diff --git a/README.md b/README.md index 31998f0..c908d6d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ [![License](https://img.shields.io/github/license/JohnLCaron/egk-ec)](https://github.com/JohnLCaron/egk-ec/blob/main/LICENSE.txt) ![GitHub branch checks state](https://img.shields.io/github/actions/workflow/status/JohnLCaron/egk-ec/unit-tests.yml) -![Coverage](https://img.shields.io/badge/coverage-90.8%25%20LOC%20(6930/7630)-blue) +![Coverage](https://img.shields.io/badge/coverage-90.7%25%20LOC%20(6967/7680)-blue) # ElectionGuard-Kotlin Elliptic Curve -_last update 04/24/2024_ +_last update 04/25/2024_ EGK Elliptic Curve (egk-ec) is an experimental implementation of [ElectionGuard](https://github.com/microsoft/electionguard), [version 2.0](https://github.com/microsoft/electionguard/releases/download/v2.0/EG_Spec_2_0.pdf), diff --git a/src/main/kotlin/org/cryptobiotic/eg/cli/RunAccumulateTally.kt b/src/main/kotlin/org/cryptobiotic/eg/cli/RunAccumulateTally.kt index 0f68d00..a01343a 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/cli/RunAccumulateTally.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/cli/RunAccumulateTally.kt @@ -15,6 +15,7 @@ import kotlinx.cli.ArgType import kotlinx.cli.default import kotlinx.cli.required import org.cryptobiotic.util.Stopwatch +import kotlin.system.exitProcess /** * Run tally accumulation CLI. @@ -58,6 +59,12 @@ class RunAccumulateTally { shortName = "createdBy", description = "who created" ) + val noexit by parser.option( + ArgType.Boolean, + shortName = "noexit", + description = "Dont call System.exit" + ).default(false) + parser.parse(args) val startupInfo = "starting '$name" + @@ -80,7 +87,7 @@ class RunAccumulateTally { } catch (t: Throwable) { logger.error { "Exception= ${t.message} ${t.stackTraceToString()}" } - t.printStackTrace() + if (!noexit) exitProcess(-1) } } @@ -91,14 +98,14 @@ class RunAccumulateTally { name: String, createdBy: String, countNumberOfBallots: Boolean = false, - ) { + ): Int { val stopwatch = Stopwatch() val consumerIn = makeConsumer(inputDir) val initResult = consumerIn.readElectionInitialized() if (initResult is Err) { logger.error { "readElectionInitialized error ${initResult.error}" } - return + return 1 } val electionInit = initResult.unwrap() val manifest = consumerIn.makeManifest(electionInit.config.manifestBytes) @@ -134,6 +141,7 @@ class RunAccumulateTally { ) logger.debug { "processed $countOk good ballots, $countBad bad ballots, ${stopwatch.tookPer(countOk, "good ballot")}" } + return if (countBad == 0) 0 else 2 } } } diff --git a/src/main/kotlin/org/cryptobiotic/eg/cli/RunCreateElectionConfig.kt b/src/main/kotlin/org/cryptobiotic/eg/cli/RunCreateElectionConfig.kt index fcb57b0..df12688 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/cli/RunCreateElectionConfig.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/cli/RunCreateElectionConfig.kt @@ -10,6 +10,7 @@ import org.cryptobiotic.eg.core.productionGroup import org.cryptobiotic.eg.election.makeElectionConfig import org.cryptobiotic.eg.publish.makePublisher import org.cryptobiotic.eg.publish.readAndCheckManifest +import kotlin.system.exitProcess /** Run Create Election Configuration CLI. */ class RunCreateElectionConfig { @@ -60,6 +61,11 @@ class RunCreateElectionConfig { shortName = "chainCodes", description = "chain confirmation codes" ).default(false) + val noexit by parser.option( + ArgType.Boolean, + shortName = "noexit", + description = "Dont call System.exit" + ).default(false) parser.parse(args) val startupInfo = "starting" + @@ -73,30 +79,34 @@ class RunCreateElectionConfig { "\n chainCodes = $chainCodes" logger.info { startupInfo } - val group = productionGroup(groupName) + try { + val group = productionGroup(groupName) - val (_, _, manifestBytes) = readAndCheckManifest(electionManifest) + val (_, _, manifestBytes) = readAndCheckManifest(electionManifest) - // As input, either specify the election record directory, - // OR the election manifest, nguardians and quorum. - val config = - makeElectionConfig( - group.constants, - nguardians, - quorum, - manifestBytes, - chainCodes, - baux0?.encodeToByteArray() ?: ByteArray(0), // use empty ByteArray if not specified - mapOf( - Pair("CreatedBy", createdBy), - Pair("CreatedOn", getSystemDate()), - ), - ) + // As input, either specify the election record directory, + // OR the election manifest, nguardians and quorum. + val config = + makeElectionConfig( + group.constants, + nguardians, + quorum, + manifestBytes, + chainCodes, + baux0?.encodeToByteArray() ?: ByteArray(0), // use empty ByteArray if not specified + mapOf( + Pair("CreatedBy", createdBy), + Pair("CreatedOn", getSystemDate()), + ), + ) - val publisher = makePublisher(outputDir, true) - publisher.writeElectionConfig(config) + val publisher = makePublisher(outputDir, true) + publisher.writeElectionConfig(config) - logger.info { "success" } + logger.info { "success" } + } catch (t: Throwable) { + if (!noexit) exitProcess(-1) + } } } } diff --git a/src/main/kotlin/org/cryptobiotic/eg/cli/RunEncryptBallot.kt b/src/main/kotlin/org/cryptobiotic/eg/cli/RunEncryptBallot.kt index d44311c..641c882 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/cli/RunEncryptBallot.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/cli/RunEncryptBallot.kt @@ -16,6 +16,7 @@ import org.cryptobiotic.eg.encrypt.submit import org.cryptobiotic.eg.input.ManifestInputValidation import org.cryptobiotic.eg.publish.* import org.cryptobiotic.util.ErrorMessages +import kotlin.system.exitProcess /** * Reads a plaintext ballot from disk and writes its encryption to disk. @@ -56,6 +57,11 @@ class RunEncryptBallot { shortName = "deviceDir", description = "Dont add device name to encrypted ballots directory" ).default(false) + val noexit by parser.option( + ArgType.Boolean, + shortName = "noexit", + description = "Dont call System.exit" + ).default(false) parser.parse(args) logger.info { @@ -73,10 +79,12 @@ class RunEncryptBallot { ) if (retval != 0) { logger.error { "failed retval=$retval" } + if (!noexit) exitProcess(retval) } } catch (t: Throwable) { logger.error(t) { "failed ${t.message}" } + if (!noexit) exitProcess(-1) } } @@ -104,8 +112,7 @@ class RunEncryptBallot { val sink: EncryptedBallotSinkIF = publisher.encryptedBallotSink( if (noDeviceNameInDir) null else device) if (ballotFilepath == "CLOSE") { - close(makeConsumer(encryptBallotDir, consumerIn.group), device, publisher) - return 0 + return close(makeConsumer(encryptBallotDir, consumerIn.group), device, publisher) } val configBaux0 = electionInit.config.configBaux0 diff --git a/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedBallotDecryption.kt b/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedBallotDecryption.kt index fec9e64..2ab8545 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedBallotDecryption.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedBallotDecryption.kt @@ -19,6 +19,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.yield import io.github.oshai.kotlinlogging.KotlinLogging +import kotlinx.cli.default import org.cryptobiotic.eg.cli.RunTrustedTallyDecryption.Companion.readDecryptingTrustees import org.cryptobiotic.eg.core.* @@ -27,6 +28,7 @@ import org.cryptobiotic.eg.election.* import org.cryptobiotic.eg.publish.* import org.cryptobiotic.util.ErrorMessages import org.cryptobiotic.util.Stopwatch +import kotlin.system.exitProcess /** * Decrypt challenged ballots with local trustees CLI. @@ -68,18 +70,28 @@ class RunTrustedBallotDecryption { shortName = "nthreads", description = "Number of parallel threads to use" ) + val noexit by parser.option( + ArgType.Boolean, + shortName = "noexit", + description = "Dont call System.exit" + ).default(false) + parser.parse(args) + val startupInfo = "RunTrustedBallotDecryption starting input= $inputDir trustees= $trusteeDir" + " decryptChallenged = $decryptChallenged output = $outputDir" logger.info { startupInfo } try { - runDecryptBallots( + val (retval, _) = runDecryptBallots( inputDir, outputDir, readDecryptingTrustees(inputDir, trusteeDir), decryptChallenged, nthreads ?: 11 ) + if (!noexit && retval != 0) exitProcess(retval) + } catch (t : Throwable) { logger.error{"Exception= ${t.message} ${t.stackTraceToString()}"} + if (!noexit) exitProcess(-1) } } @@ -89,14 +101,14 @@ class RunTrustedBallotDecryption { decryptingTrustees: List, decryptChallenged: String?, // comma delimited, no spaces nthreads: Int, - ): Int { + ): Pair { val stopwatch = Stopwatch() // start timing here val consumerIn = makeConsumer(inputDir) val result: Result = consumerIn.readTallyResult() if (result is Err) { logger.error { result.error.toString() } - return 0 + return Pair(1,0) } val tallyResult = result.unwrap() val guardians = Guardians(consumerIn.group, tallyResult.electionInitialized.guardians) @@ -170,7 +182,7 @@ class RunTrustedBallotDecryption { logger.info {" decrypt ballots ${stopwatch.tookPer(count, "ballots")}" } - return count + return Pair(0, count) } // parallelize over ballots diff --git a/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedKeyCeremony.kt b/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedKeyCeremony.kt index 551e41a..890852c 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedKeyCeremony.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedKeyCeremony.kt @@ -16,6 +16,7 @@ import org.cryptobiotic.eg.keyceremony.KeyCeremonyTrustee import org.cryptobiotic.eg.keyceremony.keyCeremonyExchange import org.cryptobiotic.eg.publish.* import org.cryptobiotic.util.Stopwatch +import kotlin.system.exitProcess /** * Run KeyCeremony CLI. @@ -50,20 +51,26 @@ class RunTrustedKeyCeremony { shortName = "createdBy", description = "who created" ).default("RunTrustedKeyCeremony") + val noexit by parser.option( + ArgType.Boolean, + shortName = "noexit", + description = "Dont call System.exit" + ).default(false) + parser.parse(args) val startupInfo = "starting\n input= $inputDir\n trustees= $trusteeDir\n output = $outputDir" logger.info { startupInfo } - val consumerIn = makeConsumer(inputDir) - val configResult = consumerIn.readElectionConfig() - if (configResult is Err) { - logger.error {"readElectionConfig error ${configResult.error}"} - return - } - val config = configResult.unwrap() - try { + val consumerIn = makeConsumer(inputDir) + val configResult = consumerIn.readElectionConfig() + if (configResult is Err) { + logger.error {"readElectionConfig error ${configResult.error}"} + if (!noexit) exitProcess(1) + } + val config = configResult.unwrap() + val result = runKeyCeremony( consumerIn.group, inputDir, @@ -74,10 +81,11 @@ class RunTrustedKeyCeremony { createdBy ) logger.info {"result = $result"} - require(result is Ok) + if (!noexit && result !is Ok) exitProcess(2) } catch (t: Throwable) { logger.error{ "Exception= ${t.message} ${t.stackTraceToString()}" } + if (!noexit) exitProcess(-1) } } diff --git a/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedTallyDecryption.kt b/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedTallyDecryption.kt index 59bcdde..5ec6311 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedTallyDecryption.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedTallyDecryption.kt @@ -7,6 +7,7 @@ import com.github.michaelbull.result.unwrap import io.github.oshai.kotlinlogging.KotlinLogging import kotlinx.cli.ArgParser import kotlinx.cli.ArgType +import kotlinx.cli.default import kotlinx.cli.required import org.cryptobiotic.eg.core.* @@ -17,6 +18,7 @@ import org.cryptobiotic.eg.election.* import org.cryptobiotic.eg.publish.* import org.cryptobiotic.util.ErrorMessages import org.cryptobiotic.util.mergeErrorMessages +import kotlin.system.exitProcess /** * Run Trusted Tally Decryption CLI. @@ -62,21 +64,30 @@ class RunTrustedTallyDecryption { shortName = "missing", description = "missing guardians' xcoord, comma separated, eg '2,4'" ) + val noexit by parser.option( + ArgType.Boolean, + shortName = "noexit", + description = "Dont call System.exit" + ).default(false) + parser.parse(args) + val startupInfo = "starting\n input= $inputDir\n trustees= $trusteeDir\n output = $outputDir" val extraInfo = if (encryptedTallyFile != null) "\n encryptedTallyFile = $encryptedTallyFile" else "" logger.info { startupInfo + extraInfo} try { - runDecryptTally( + val retval = runDecryptTally( inputDir, outputDir, readDecryptingTrustees(inputDir, trusteeDir, missing), createdBy, encryptedTallyFile, ) + if (!noexit && retval != 0) exitProcess(retval) } catch (t: Throwable) { logger.error { "Exception= ${t.message} ${t.stackTraceToString()}" } + if (!noexit) exitProcess(-1) } } @@ -112,12 +123,12 @@ class RunTrustedTallyDecryption { decryptingTrustees: List, createdBy: String? = null, encryptedTallyFile: String? = null, - ) { + ): Int { val consumerIn = makeConsumer(inputDir) val resultInit = consumerIn.readElectionInitialized() if (resultInit is Err) { logger.error { "readElectionInitialized error ${resultInit.error}" } - return + return 1 } val electionInit = resultInit.unwrap() @@ -128,7 +139,7 @@ class RunTrustedTallyDecryption { val quorum = electionInit.config.quorum if (decryptingTrustees.size < quorum) { logger.error { " encryptedTally.decrypt $inputDir does not have a quorum=${quorum}, only ${electionInit.config.quorum} guardians" } - return + return 2 } val guardians = Guardians(consumerIn.group, electionInit.guardians) @@ -145,7 +156,7 @@ class RunTrustedTallyDecryption { val result = consumerIn.readTallyResult() if (result is Err) { logger.error { "readTallyResult error ${result.error}" } - return + return 3 } tallyResult = result.unwrap() tallyResult.encryptedTally @@ -153,42 +164,37 @@ class RunTrustedTallyDecryption { val result = consumerIn.readEncryptedTallyFromFile(encryptedTallyFile) if (result is Err) { logger.error { " Cant read readEncryptedTallyFromFile $encryptedTallyFile err = $result" } - return + return 4 } result.unwrap() } val errs = ErrorMessages("RunTrustedTallyDecryption") - try { - val decryptedTally = decryptor.decrypt(encryptedTally, errs) - if (decryptedTally == null) { - logger.error { " encryptedTally.decrypt $inputDir has error=${errs}" } - return - } - val publisher = makePublisher(outputDir, false) - if (tallyResult != null) { - publisher.writeDecryptionResult( - DecryptionResult( - tallyResult, - decryptedTally, - mapOf( - Pair("CreatedBy", createdBy ?: "RunTrustedTallyDecryption"), - Pair("CreatedOn", getSystemDate()), - Pair("CreatedFromDir", inputDir), - ), + val decryptedTally = decryptor.decrypt(encryptedTally, errs) + if (decryptedTally == null) { + logger.error { " encryptedTally.decrypt $inputDir has error=${errs}" } + return 5 + } + val publisher = makePublisher(outputDir, false) + if (tallyResult != null) { + publisher.writeDecryptionResult( + DecryptionResult( + tallyResult, + decryptedTally, + mapOf( + Pair("CreatedBy", createdBy ?: "RunTrustedTallyDecryption"), + Pair("CreatedOn", getSystemDate()), + Pair("CreatedFromDir", inputDir), ), - ) - logger.info{ "writeDecryptionResult to output directory $outputDir "} - } else { - publisher.writeDecryptedTally(decryptedTally) - logger.info{ "writeDecryptedTally to output directory $outputDir "} - } - logger.info { "success" } - } catch (t: Throwable) { - errs.add("Exception= ${t.message} ${t.stackTraceToString()}") - logger.error { errs } + ), + ) + logger.info{ "writeDecryptionResult to output directory $outputDir "} + } else { + publisher.writeDecryptedTally(decryptedTally) + logger.info{ "writeDecryptedTally to output directory $outputDir "} } - + logger.info { "success" } + return 0 } } } diff --git a/src/main/kotlin/org/cryptobiotic/eg/cli/RunVerifier.kt b/src/main/kotlin/org/cryptobiotic/eg/cli/RunVerifier.kt index b647d92..7015715 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/cli/RunVerifier.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/cli/RunVerifier.kt @@ -5,15 +5,15 @@ import kotlinx.cli.ArgParser import kotlinx.cli.ArgType import kotlinx.cli.default import kotlinx.cli.required +import org.cryptobiotic.eg.cli.RunTrustedTallyDecryption.Companion import org.cryptobiotic.eg.publish.Consumer import org.cryptobiotic.eg.publish.readElectionRecord import org.cryptobiotic.eg.verifier.Verifier import org.cryptobiotic.util.Stats import org.cryptobiotic.util.Stopwatch +import kotlin.system.exitProcess -/** - * Run election record verification CLI. - */ +/** Run election record verification CLI. */ class RunVerifier { companion object { @@ -37,13 +37,26 @@ class RunVerifier { shortName = "time", description = "Show timing" ).default(false) + val noexit by parser.option( + ArgType.Boolean, + shortName = "noexit", + description = "Dont call System.exit" + ).default(false) + parser.parse(args) + logger.info { "RunVerifier input= $inputDir" } - runVerifier(inputDir, nthreads, showTime) + try { + val retval = runVerifier(inputDir, nthreads, showTime) + if (!noexit && retval != 0) exitProcess(retval) + } catch (t: Throwable) { + logger.error { "Exception= ${t.message} ${t.stackTraceToString()}" } + if (!noexit) exitProcess(-1) + } } - fun runVerifier(inputDir: String, nthreads: Int, showTime: Boolean = false): Boolean { + fun runVerifier(inputDir: String, nthreads: Int, showTime: Boolean = false): Int { val stopwatch = Stopwatch() // start timing here val electionRecord = readElectionRecord(inputDir) @@ -56,7 +69,7 @@ class RunVerifier { logger.debug { "${stopwatch.took()}" } logger.info { "$inputDir verified = ${allOk}" } - return allOk + return if (allOk) 0 else 1 } fun verifyEncryptedBallots(inputDir: String, nthreads: Int) { @@ -104,7 +117,7 @@ class RunVerifier { fun verifyTallyBallotIds(inputDir: String) { val electionRecord = readElectionRecord(inputDir) - println("$inputDir stage=${electionRecord.stage()} ncast_ballots=${electionRecord.encryptedTally()!!.castBallotIds.size}") + // println("$inputDir stage=${electionRecord.stage()} ncast_ballots=${electionRecord.encryptedTally()!!.castBallotIds.size}") val verifier = Verifier(electionRecord, 1) val errs = verifier.verifyTallyBallotIds() diff --git a/src/main/kotlin/org/cryptobiotic/eg/core/intgroup/IntGroup.kt b/src/main/kotlin/org/cryptobiotic/eg/core/intgroup/IntGroup.kt index 242f12f..83541e7 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/core/intgroup/IntGroup.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/core/intgroup/IntGroup.kt @@ -98,6 +98,18 @@ class ProductionGroupContext( return (ctx is ProductionGroupContext) && productionMode == ctx.productionMode } + /** + * Returns a random number in [2, P). Promises to use a + * "secure" random number generator, such that the results are suitable for use as cryptographic keys. + * @throws IllegalArgumentException if the minimum is negative + */ + override fun randomElementModP(): ElementModP { + val b = randomBytes(MAX_BYTES_P) + val tmp = b.toBigInteger().mod(p) + val tmp2 = if (tmp < BigInteger.TWO) tmp + BigInteger.TWO else tmp + return ProductionElementModP(tmp2, this) + } + override fun binaryToElementModP(b: ByteArray): ElementModP? = try { val tmp = b.toBigInteger() @@ -146,24 +158,6 @@ class ProductionGroupContext( override fun dLogG(p: ElementModP, maxResult: Int): Int? = dlogger.dLog(p, maxResult) - /** - * Returns a random number in [2, P). Promises to use a - * "secure" random number generator, such that the results are suitable for use as cryptographic keys. - * @throws IllegalArgumentException if the minimum is negative - */ - override fun randomElementModP() = binaryToElementModPsafe(randomBytes(MAX_BYTES_P), 2) - - - fun binaryToElementModPsafe(b: ByteArray, minimum: Int): ElementModP { - if (minimum < 0) { - throw IllegalArgumentException("minimum $minimum may not be negative") - } - val tmp = b.toBigInteger().mod(p) - val mv = minimum.toBigInteger() - val tmp2 = if (tmp < mv) tmp + mv else tmp - return ProductionElementModP(tmp2, this) - } - var opCounts: HashMap = HashMap() override fun getAndClearOpCounts(): Map { val result = HashMap() diff --git a/src/main/kotlin/org/cryptobiotic/eg/encrypt/EncryptedBallotChain.kt b/src/main/kotlin/org/cryptobiotic/eg/encrypt/EncryptedBallotChain.kt index 0485143..f8531d8 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/encrypt/EncryptedBallotChain.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/encrypt/EncryptedBallotChain.kt @@ -112,7 +112,7 @@ data class EncryptedBallotChain( publisher.writeEncryptedBallotChain(ballotChain) } catch (t: Throwable) { logger.error(t) { "error writing chain ${t.message}" } - return 6 + return 10 } return 0 } diff --git a/src/test/kotlin/org/cryptobiotic/eg/cli/RunCreateConfigTest.kt b/src/test/kotlin/org/cryptobiotic/eg/cli/RunCreateConfigTest.kt index 74b1761..3753163 100644 --- a/src/test/kotlin/org/cryptobiotic/eg/cli/RunCreateConfigTest.kt +++ b/src/test/kotlin/org/cryptobiotic/eg/cli/RunCreateConfigTest.kt @@ -34,6 +34,7 @@ class RunCreateConfigTest { "${Testing.testOut}/config/startConfigJson", "-device", "device information", + "-noexit" ) ) } @@ -51,6 +52,7 @@ class RunCreateConfigTest { "${Testing.testOut}/config/testCreateConfigDirectoryJson", "-device", "device information", + "-noexit" ) ) } diff --git a/src/test/kotlin/org/cryptobiotic/eg/cli/RunEncryptBallotTest.kt b/src/test/kotlin/org/cryptobiotic/eg/cli/RunEncryptBallotTest.kt index 2531021..1e504e9 100644 --- a/src/test/kotlin/org/cryptobiotic/eg/cli/RunEncryptBallotTest.kt +++ b/src/test/kotlin/org/cryptobiotic/eg/cli/RunEncryptBallotTest.kt @@ -79,6 +79,7 @@ class RunEncryptBallotTest { "--ballotFilepath", "$outputDir/pballot-$ballotId.json", "--outputDir", outputDir, "-device", "device42", + "--noexit", ) ) @@ -116,7 +117,8 @@ class RunEncryptBallotTest { "--ballotFilepath", ballotFilename, "--outputDir", outputDir, "-device", device, - "--noDeviceNameInDir" + "--noDeviceNameInDir", + "--noexit", ) ) @@ -159,6 +161,7 @@ class RunEncryptBallotTest { "--ballotFilepath", ballotFilename, "--outputDir", outputDir, "-device", device, + "--noexit", ) ) @@ -175,6 +178,7 @@ class RunEncryptBallotTest { "--ballotFilepath", "CLOSE", "--outputDir", outputDir, "-device", device, + "--noexit", ) ) @@ -209,6 +213,7 @@ class RunEncryptBallotTest { "--ballotFilepath", ballotFilename, "--outputDir", outputDir, "-device", device, + "--noexit", ) ) diff --git a/src/test/kotlin/org/cryptobiotic/eg/cli/RunTrustedKeyCeremonyTest.kt b/src/test/kotlin/org/cryptobiotic/eg/cli/RunTrustedKeyCeremonyTest.kt index dfd34f4..19d8366 100644 --- a/src/test/kotlin/org/cryptobiotic/eg/cli/RunTrustedKeyCeremonyTest.kt +++ b/src/test/kotlin/org/cryptobiotic/eg/cli/RunTrustedKeyCeremonyTest.kt @@ -11,6 +11,7 @@ class RunTrustedKeyCeremonyTest { "-in", "src/test/data/startConfigEc", "-trustees", "${Testing.testOut}/cliWorkflow/keyceremonyEc/trustees", "-out", "${Testing.testOut}/cliWorkflow/keyceremonyEc", + "--noexit" ) ) } diff --git a/src/test/kotlin/org/cryptobiotic/eg/decrypt/RunDecryptBallotsJsonTest.kt b/src/test/kotlin/org/cryptobiotic/eg/decrypt/RunDecryptBallotsJsonTest.kt index 34c2e34..607df05 100644 --- a/src/test/kotlin/org/cryptobiotic/eg/decrypt/RunDecryptBallotsJsonTest.kt +++ b/src/test/kotlin/org/cryptobiotic/eg/decrypt/RunDecryptBallotsJsonTest.kt @@ -24,13 +24,14 @@ class RunDecryptBallotsJsonTest { val trusteeDir = "$inputDir/private_data/trustees" val outputDir = "${Testing.testOut}/decrypt/testDecryptBallotsAllJson" println("\ntestDecryptBallotsAll") - val n = runDecryptBallots( + val (retval, n) = runDecryptBallots( inputDir, outputDir, readDecryptingTrustees(inputDir, trusteeDir), "ALL", nthreads, ) + assertEquals(0, retval) assertEquals(42, n) } @@ -40,13 +41,14 @@ class RunDecryptBallotsJsonTest { val trusteeDir = "$inputDir/private_data/trustees" val outputDir = "${Testing.testOut}/decrypt/testDecryptBallotsSomeJson" println("\ntestDecryptBallotsAll") - val n = runDecryptBallots( + val (retval, n) = runDecryptBallots( inputDir, outputDir, readDecryptingTrustees(inputDir, trusteeDir), "ALL", nthreads, ) + assertEquals(0, retval) assertEquals(42, n) } @@ -56,7 +58,7 @@ class RunDecryptBallotsJsonTest { val trusteeDir = "$inputDir/private_data/trustees" val outputDir = "${Testing.testOut}/decrypt/testDecryptBallotsSomeFromListJson" println("\ntestDecryptBallotsSomeFromList") - val n = runDecryptBallots( + val (retval, n) = runDecryptBallots( inputDir, outputDir, readDecryptingTrustees(inputDir, trusteeDir, "5"), "id-6," + "id-7," + @@ -64,6 +66,7 @@ class RunDecryptBallotsJsonTest { "id-1,", 3, ) + assertEquals(0, retval) assertEquals(4, n) } diff --git a/src/test/kotlin/org/cryptobiotic/eg/decrypt/RunDecryptBallotsTest.kt b/src/test/kotlin/org/cryptobiotic/eg/decrypt/RunDecryptBallotsTest.kt index 3f8ef16..14297ec 100644 --- a/src/test/kotlin/org/cryptobiotic/eg/decrypt/RunDecryptBallotsTest.kt +++ b/src/test/kotlin/org/cryptobiotic/eg/decrypt/RunDecryptBallotsTest.kt @@ -25,13 +25,14 @@ class RunDecryptBallotsTest { val trusteeDir = "$inputDir/private_data/trustees" val outputDir = "${Testing.testOut}/decrypt/testDecryptBallotsAll" println("\ntestDecryptBallotsAll") - val n = runDecryptBallots( + val (retval, n) = runDecryptBallots( inputDir, outputDir, readDecryptingTrustees(inputDir, trusteeDir), "ALL", nthreads, ) + assertEquals(0, retval) assertEquals(42, n) } @@ -41,13 +42,14 @@ class RunDecryptBallotsTest { val trusteeDir = "$inputDir/private_data/trustees" val outputDir = "${Testing.testOut}/decrypt/testDecryptBallotsSomeFromList" println("\ntestDecryptBallotsSomeFromList") - val n = runDecryptBallots( + val (retval, n) = runDecryptBallots( inputDir, outputDir, readDecryptingTrustees(inputDir, trusteeDir, "5"), "id-1," + "id-3," + "id-2", 3, ) + assertEquals(0, retval) assertEquals(3, n) } @@ -58,11 +60,12 @@ class RunDecryptBallotsTest { val wantBallots = "$inputDir/private_data/wantedBallots.txt" val outputDir = "${Testing.testOut}/decrypt/testDecryptBallotsSomeFromFile" println("\ntestDecryptBallotsSomeFromFile") - val n = runDecryptBallots( + val (retval, n) = runDecryptBallots( inputDir, outputDir, readDecryptingTrustees(inputDir, trusteeDir, "4,5"), wantBallots, 2, ) + assertEquals(0, retval) assertEquals(2, n) } @@ -72,16 +75,12 @@ class RunDecryptBallotsTest { println("\ntestDecryptBallotsMainMultiThreaded") RunTrustedBallotDecryption.main( arrayOf( - "-in", - "src/test/data/workflow/someAvailableEc", - "-trustees", - "src/test/data/workflow/someAvailableEc/private_data/trustees", - "-out", - "${Testing.testOut}/decrypt/testDecryptBallotsMainMultiThreaded", - "-challenged", - "all", - "-nthreads", - "$nthreads" + "-in", "src/test/data/workflow/someAvailableEc", + "-trustees", "src/test/data/workflow/someAvailableEc/private_data/trustees", + "-out", "${Testing.testOut}/decrypt/testDecryptBallotsMainMultiThreaded", + "-challenged", "all", + "-nthreads", "$nthreads", + "--noexit", ) ) } @@ -92,14 +91,11 @@ class RunDecryptBallotsTest { println("\ntestDecryptBallotsMarkedChallenged") RunTrustedBallotDecryption.main( arrayOf( - "-in", - "src/test/data/workflow/someAvailableEc", - "-trustees", - "src/test/data/workflow/someAvailableEc/private_data/trustees", - "-out", - "${Testing.testOut}/decrypt/testDecryptBallotsMarkedChallenged", - "-nthreads", - "1" + "-in", "src/test/data/workflow/someAvailableEc", + "-trustees", "src/test/data/workflow/someAvailableEc/private_data/trustees", + "-out", "${Testing.testOut}/decrypt/testDecryptBallotsMarkedChallenged", + "-nthreads", "1", + "--noexit" ) ) } diff --git a/src/test/kotlin/org/cryptobiotic/eg/tally/RunTallyAccumulationTest.kt b/src/test/kotlin/org/cryptobiotic/eg/tally/RunTallyAccumulationTest.kt index 0453f55..434fa86 100644 --- a/src/test/kotlin/org/cryptobiotic/eg/tally/RunTallyAccumulationTest.kt +++ b/src/test/kotlin/org/cryptobiotic/eg/tally/RunTallyAccumulationTest.kt @@ -30,6 +30,7 @@ class RunTallyAccumulationTest { "src/test/data/workflow/someAvailableEc", "-out", "${Testing.testOut}/tally/testRunBatchEncryptionJson", + "--noexit" ) ) } diff --git a/src/test/kotlin/org/cryptobiotic/eg/verifier/VerifierTest.kt b/src/test/kotlin/org/cryptobiotic/eg/verifier/VerifierTest.kt index a8b8828..2c8627f 100644 --- a/src/test/kotlin/org/cryptobiotic/eg/verifier/VerifierTest.kt +++ b/src/test/kotlin/org/cryptobiotic/eg/verifier/VerifierTest.kt @@ -48,6 +48,7 @@ class VerifierTest { "-nthreads", "11", "--showTime", + "--noexit" ) ) } diff --git a/src/test/kotlin/org/cryptobiotic/eg/workflow/CreateElectionConfig.kt b/src/test/kotlin/org/cryptobiotic/eg/workflow/CreateElectionConfig.kt index cc79b6e..d57bb00 100644 --- a/src/test/kotlin/org/cryptobiotic/eg/workflow/CreateElectionConfig.kt +++ b/src/test/kotlin/org/cryptobiotic/eg/workflow/CreateElectionConfig.kt @@ -17,6 +17,7 @@ class CreateElectionConfig { "-quorum", "3", "-out", "${Testing.testOut}/config/startConfig", "-device", "device information", + "-noexit" ) ) } @@ -30,6 +31,7 @@ class CreateElectionConfig { "-nguardians", "3", "-quorum", "3", "-out", "${Testing.testOut}/config/startConfigEc", + "-noexit" ) ) } diff --git a/src/test/kotlin/org/cryptobiotic/eg/workflow/TestNumGuardiansPresent.kt b/src/test/kotlin/org/cryptobiotic/eg/workflow/TestNumGuardiansPresent.kt index cecd266..647d170 100644 --- a/src/test/kotlin/org/cryptobiotic/eg/workflow/TestNumGuardiansPresent.kt +++ b/src/test/kotlin/org/cryptobiotic/eg/workflow/TestNumGuardiansPresent.kt @@ -70,6 +70,7 @@ class TestNumGuardiansPresent { "-out", workingDir, "-device", "device11", "-createdBy", name1, + "-noexit" ) ) @@ -98,7 +99,8 @@ class TestNumGuardiansPresent { "-trustees", trusteeDir, "-out", workingDir, "-challenged", "all", - "-nthreads", nthreads.toString() + "-nthreads", nthreads.toString(), + "--noexit" ) ) println(group.showOpCountResults("----------- after decrypt ballots")) diff --git a/src/test/kotlin/org/cryptobiotic/eg/workflow/TestWorkflow.kt b/src/test/kotlin/org/cryptobiotic/eg/workflow/TestWorkflow.kt index daf8c8d..1b3138c 100644 --- a/src/test/kotlin/org/cryptobiotic/eg/workflow/TestWorkflow.kt +++ b/src/test/kotlin/org/cryptobiotic/eg/workflow/TestWorkflow.kt @@ -102,13 +102,14 @@ class TestWorkflow { ) // decrypt challenged ballots - val ndecrypted = runDecryptBallots( + val (retval, ndecrypted) = runDecryptBallots( inputDir = workingDir, outputDir = workingDir, trustees, "challenged", 11 ) + assertEquals(0, retval) assertEquals(nchallenged, ndecrypted) // verify