diff --git a/docs/CommandLineInterface.md b/docs/CommandLineInterface.md index cce26b35..1ad60bff 100644 --- a/docs/CommandLineInterface.md +++ b/docs/CommandLineInterface.md @@ -46,7 +46,7 @@ last update 11/22/2023 2. To run a keyceremony with remote guardians, see the webapps CLI. 4. **Create test input plaintext ballots** - 1. Create fake input ballots for testing with [_RunGenerateInputBallots_ CLI](#create-fake-input-ballots). + 1. Create fake input ballots for testing with [_RunCreateInputBallots_ CLI](#create-fake-input-ballots). 1. _electionguard.workflow.GenerateFakeBallots_ generates random test ballots. 2. Use existing fake ballots for testing in _egklib/src/commonTest/data/fakeBallots_. @@ -123,7 +123,6 @@ Example: ```` /usr/lib/jvm/jdk-19/bin/java \ - -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 \ -classpath egkliball/build/libs/egklib-all.jar \ electionguard.cli.RunCreateElectionConfig \ -manifest egklib/src/commonTest/data/startManifestJson \ @@ -193,7 +192,7 @@ Options: --inputDir, -in -> Directory containing input election record (always required) { String } --ballotDir, -ballots -> Directory to read Plaintext ballots from (always required) { String } --outputDir, -out -> Directory to write output election record { String } - --encryptDir, -encryptDir -> Write just encrypted ballots here { String } + --encryptDir, -eballots -> Write encrypted ballots here { String } --invalidDir, -invalid -> Directory to write invalid input ballots to { String } --check, -check [None] -> Check encryption { Value should be one of [none, verify, encrypttwice, decryptnonce] } --nthreads, -nthreads [11] -> Number of parallel threads to use { Int } @@ -201,7 +200,7 @@ Options: --device, -device -> voting device name (always required) { String } --cleanOutput, -clean [false] -> clean output dir --anonymize, -anon [false] -> anonymize ballot - --help, -h -> Usage info + --help, -h -> Usage info ```` You must specify outputDir or encryptDir. The former copies ElectionInit and writes encrypted ballots to standard election record. The latter writes just the encrypted ballots to the specified directory. @@ -228,6 +227,7 @@ Usage: RunAccumulateTally options_list Options: --inputDir, -in -> Directory containing input ElectionInitialized record and encrypted ballots (always required) { String } --outputDir, -out -> Directory to write output election record (always required) { String } + --encryptDir, -eballots -> Read encrypted ballots here (optional) { String } --name, -name -> Name of tally { String } --createdBy, -createdBy -> who created { String } --help, -h -> Usage info @@ -263,7 +263,7 @@ Options: --trusteeDir, -trustees -> Directory to read private trustees (always required) { String } --outputDir, -out -> Directory to write output election record (always required) { String } --createdBy, -createdBy -> who created { String } - --npresent, -npresent -> number of guardians present { Int } + --missing, -missing -> missing guardians' xcoord, comma separated, eg '2,4' { String } --help, -h -> Usage info ```` diff --git a/egklib/src/commonMain/kotlin/electionguard/keyceremony/KeyCeremonyTrustee.kt b/egklib/src/commonMain/kotlin/electionguard/keyceremony/KeyCeremonyTrustee.kt index bb1944fa..75e24bf8 100644 --- a/egklib/src/commonMain/kotlin/electionguard/keyceremony/KeyCeremonyTrustee.kt +++ b/egklib/src/commonMain/kotlin/electionguard/keyceremony/KeyCeremonyTrustee.kt @@ -283,7 +283,7 @@ open class KeyCeremonyTrustee( // Call after all myShareOfOthers has been populated with all the other trustee's. // The value P(i) == G_i’s share of the secret key s = (s1 + s2 + · · · + sn ) // == (P1 (ℓ) + P2 (ℓ) + · · · + Pn (ℓ)) mod q. spec 2.0.0, eq 65. - internal fun computeSecretKeyShare(): ElementModQ { + fun computeSecretKeyShare(): ElementModQ { if (nguardians != myShareOfOthers.size + 1) { throw RuntimeException("KeyCeremonyTrustee.computeSecretKeyShare: requires nguardians ${nguardians} but have ${myShareOfOthers.size + 1} shares") } diff --git a/egklib/src/jvmMain/kotlin/electionguard/cli/RunMakeMixnetInput.kt b/egklib/src/jvmMain/kotlin/electionguard/cli/RunMakeMixnetInput.kt index ca998f58..35fda9b4 100644 --- a/egklib/src/jvmMain/kotlin/electionguard/cli/RunMakeMixnetInput.kt +++ b/egklib/src/jvmMain/kotlin/electionguard/cli/RunMakeMixnetInput.kt @@ -12,13 +12,14 @@ import kotlinx.serialization.json.Json import kotlinx.serialization.json.encodeToStream import java.io.FileOutputStream +/** Read the EG encypted ballots and create JSON encoded file for the mixnet. */ class RunMakeMixnetInput { companion object { val jsonReader = Json { explicitNulls = false; ignoreUnknownKeys = true; prettyPrint = true } @JvmStatic - fun main(args: Array) { + fun main(args: Array): Int { val parser = ArgParser("RunMakeMixnetInput") val encryptedBallotsDir by parser.option( ArgType.String, @@ -33,7 +34,7 @@ class RunMakeMixnetInput { val isJson by parser.option( ArgType.Boolean, shortName = "json", - description = "ENcrypted ballots are JSON" + description = "Encrypted ballots are JSON" ).default(true) parser.parse(args) @@ -41,12 +42,15 @@ class RunMakeMixnetInput { val outputDir = outputFile.substringBeforeLast("/") createDirectories(outputDir) - runMakeMixnetInput(productionGroup(), encryptedBallotsDir, outputFile, isJson) + return runMakeMixnetInput(productionGroup(), encryptedBallotsDir, outputFile, isJson) } - fun runMakeMixnetInput(group: GroupContext, encryptedBallotsDir: String, outputFile: String, isJson : Boolean) { + /** return number of ciphertexts in a row. */ + fun runMakeMixnetInput(group: GroupContext, encryptedBallotsDir: String, outputFile: String, isJson : Boolean): Int { val consumer = makeConsumer(group, encryptedBallotsDir, isJson) val mixnetBallots = mutableListOf() + var first = true + var countCiphertexts = 0 consumer.iterateEncryptedBallotsFromDir(encryptedBallotsDir, null).forEach { encryptedBallot -> val ciphertexts = mutableListOf() ciphertexts.add(encryptedBallot.encryptedSn!!) // always the first one @@ -56,12 +60,14 @@ class RunMakeMixnetInput { } } mixnetBallots.add(MixnetBallot(ciphertexts)) + if (first) countCiphertexts = ciphertexts.size else require(countCiphertexts == ciphertexts.size) } val json = mixnetBallots.publishJson() FileOutputStream(outputFile).use { out -> jsonReader.encodeToStream(json, out) } + return countCiphertexts } } } \ No newline at end of file