From 6f2e52c4639ff695a642e3ab9694c036862a2148 Mon Sep 17 00:00:00 2001 From: JohnLCaron Date: Wed, 17 Apr 2024 11:18:24 -0600 Subject: [PATCH] Move TODOs into issues where appropriate. --- docs/JsonSerializationSpec1.9.md | 2 +- docs/JsonSerializationSpec2.1.md | 4 +++- .../cryptobiotic/eg/cli/RunTrustedBallotDecryption.kt | 1 - .../org/cryptobiotic/eg/election/EncryptedBallot.kt | 2 +- .../org/cryptobiotic/eg/keyceremony/KeyCeremony.kt | 6 +----- .../kotlin/org/cryptobiotic/eg/preencrypt/PreBallot.kt | 2 +- .../org/cryptobiotic/eg/preencrypt/PreEncryptor.kt | 8 ++++++-- .../kotlin/org/cryptobiotic/eg/preencrypt/Recorder.kt | 9 --------- .../org/cryptobiotic/eg/verifier/VerifyDecryption.kt | 10 ---------- .../cryptobiotic/eg/verifier/VerifyEncryptedBallots.kt | 6 +++--- .../eg/verifier/VerifyPreEncryptedBallots.kt | 4 +--- .../kotlin/org/cryptobiotic/eg/verifier/VerifyTally.kt | 7 +------ .../org/cryptobiotic/eg/preencrypt/PreEncryptorTest.kt | 2 +- src/test/kotlin/org/cryptobiotic/util/DfracTest.kt | 2 +- 14 files changed, 20 insertions(+), 45 deletions(-) diff --git a/docs/JsonSerializationSpec1.9.md b/docs/JsonSerializationSpec1.9.md index 121c5b5..d9d5c81 100644 --- a/docs/JsonSerializationSpec1.9.md +++ b/docs/JsonSerializationSpec1.9.md @@ -295,7 +295,7 @@ data class HashedElGamalCiphertextJson( val c0: ElementModPJson, // ElementModP, val c1: String, // ByteArray, val c2: UInt256Json, // UInt256, - val numBytes: Int // TODO needed? + val numBytes: Int ) @Serializable diff --git a/docs/JsonSerializationSpec2.1.md b/docs/JsonSerializationSpec2.1.md index 73bc70f..b22a95c 100644 --- a/docs/JsonSerializationSpec2.1.md +++ b/docs/JsonSerializationSpec2.1.md @@ -408,7 +408,7 @@ data class HashedElGamalCiphertextJson( val c0: ElementModPJson, // ElementModP, val c1: String, // ByteArray, val c2: UInt256Json, // UInt256, - val numBytes: Int // TODO needed? + val numBytes: Int ) @Serializable @@ -701,6 +701,8 @@ data class ContestDataJson( val status: String, ) +TODO ContestDataJson is not in any spec. + ```` Example: diff --git a/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedBallotDecryption.kt b/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedBallotDecryption.kt index e1f873e..fec9e64 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedBallotDecryption.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedBallotDecryption.kt @@ -109,7 +109,6 @@ class RunTrustedBallotDecryption { decryptingTrustees, ) - // TODO you may want to put the decryption results in the same directory, but sinks now are append-only. val publisher = makePublisher(outputDir, false) val sink: DecryptedBallotSinkIF = publisher.decryptedBallotSink() diff --git a/src/main/kotlin/org/cryptobiotic/eg/election/EncryptedBallot.kt b/src/main/kotlin/org/cryptobiotic/eg/election/EncryptedBallot.kt index af2ed1b..6a9e1c8 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/election/EncryptedBallot.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/election/EncryptedBallot.kt @@ -79,7 +79,7 @@ data class EncryptedBallot( val contestHash: UInt256, // eq 58 override val selections: List, val proof: ChaumPedersenRangeProofKnownNonce, - override val contestData: HashedElGamalCiphertext, // TODO make optional? + override val contestData: HashedElGamalCiphertext, val preEncryption: PreEncryption? = null, // pre-encrypted ballots only ) : EncryptedBallotIF.Contest { diff --git a/src/main/kotlin/org/cryptobiotic/eg/keyceremony/KeyCeremony.kt b/src/main/kotlin/org/cryptobiotic/eg/keyceremony/KeyCeremony.kt index e8e0abb..65868be 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/keyceremony/KeyCeremony.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/keyceremony/KeyCeremony.kt @@ -32,10 +32,7 @@ fun keyCeremonyExchange(trustees: List, allowEncryptedFail return Err("keyCeremonyExchange trustees have different quorums = ${trustees.map{it.coefficientCommitments().size}}") } - // TODO if the trustees are not trusted, we could do other verification tests here. - // are the public keys valid? - // are the encrypted shares valid? - // are the unencrypted shares valid? + // if the trustees are not trusted, we could do other verification tests here. // exchange PublicKeys val publicKeys: MutableList = mutableListOf() @@ -96,7 +93,6 @@ fun keyCeremonyExchange(trustees: List, allowEncryptedFail // footnote 28 It is also permissible to dismiss any guardian that makes a false claim of malfeasance. However, this is not // required as the sensitive information that is released as a result of the claim could have been released by the claimant // in any case. - // TODO KeyShare should include ξi,ℓ // Phase Two: if any secretKeyShares fail to validate, send and validate KeyShares val keyResults: MutableList> = mutableListOf() diff --git a/src/main/kotlin/org/cryptobiotic/eg/preencrypt/PreBallot.kt b/src/main/kotlin/org/cryptobiotic/eg/preencrypt/PreBallot.kt index 80c3fe5..05a8604 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/preencrypt/PreBallot.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/preencrypt/PreBallot.kt @@ -32,7 +32,7 @@ internal data class PreContest( val votedFor: List // nselections, in order by sequence_order ) { init { - require(votedFor.size == allSelectionHashes.size - selectedVectors.size) // TODO + require(votedFor.size == allSelectionHashes.size - selectedVectors.size) } fun selectedCodes() : List = selectedVectors.map { it.shortCode } fun nselections() = votedFor.size diff --git a/src/main/kotlin/org/cryptobiotic/eg/preencrypt/PreEncryptor.kt b/src/main/kotlin/org/cryptobiotic/eg/preencrypt/PreEncryptor.kt index fcb665f..0535bdb 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/preencrypt/PreEncryptor.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/preencrypt/PreEncryptor.kt @@ -3,7 +3,6 @@ package org.cryptobiotic.eg.preencrypt import org.cryptobiotic.eg.core.* import org.cryptobiotic.eg.election.ManifestIF - /** * The crypto part of the "The Ballot Encrypting Tool" * The encrypting/decrypting of the primaryNonce is done external to this. @@ -64,7 +63,7 @@ class PreEncryptor( // In a contest with a selection limit of L, an additional L null vectors are added var nextSeqNo = sortedSelections.last().sequenceOrder + 1 for (nullVectorIdx in (1..contestLimit)) { - // TODO "null labels may be in manifest", see 4.2.1. wtf? + // TODO "null labels may be in manifest", see Issue #56 preeSelections.add( preencryptSelection(primaryNonce, this.sequenceOrder, "null${nullVectorIdx}", nextSeqNo, sortedSelectionIndices)) nextSeqNo++ } @@ -114,4 +113,9 @@ class PreEncryptor( encryptionNonces, ) } + + companion object { + // TODO "hash trimming function Ω must be completely specified in the election manifest" see Issue #56 + fun sigma(hash: UInt256): String = hash.toHex().substring(0, 5) + } } \ No newline at end of file diff --git a/src/main/kotlin/org/cryptobiotic/eg/preencrypt/Recorder.kt b/src/main/kotlin/org/cryptobiotic/eg/preencrypt/Recorder.kt index 3c7079f..23e4291 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/preencrypt/Recorder.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/preencrypt/Recorder.kt @@ -8,15 +8,6 @@ import org.cryptobiotic.util.ErrorMessages /** * The crypto part of the "The Recording Tool". * The encrypting/decrypting primaryNonce is done external. - * - * TODO : uncast (implicitly or explicitly challenged) aka CHALLENGED - * "For each uncast (implicitly or explicitly challenged) ballot, the recording tool returns the primary - * nonce that enables the encryptions to be opened and checked." - * "For an uncast ballot, the wrapper computes the short codes for all possible selections and posts - * in the election record the full set of pre-encryption vectors, selection hashes, and short codes for - * each possible selection." - * "The decryptions of all pre-encryptions correspond to the plaintext values indicated in the - * election manifest." */ class Recorder( val group: GroupContext, diff --git a/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyDecryption.kt b/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyDecryption.kt index ab6d572..8cfd048 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyDecryption.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyDecryption.kt @@ -126,16 +126,6 @@ class VerifyDecryption( } - // TODO check - // Verification 11 (Correctness of decryptions of contest data) - // An election verifier must confirm the correct decryption of the contest data field for each contest by - // verifying the conditions analogous to Verification 9 for the corresponding NIZK proof with (A, B) - // replaced by (C0 , C1 , C2 ) and Mi by mi as follows. An election verifier must compute the following values. - // (11.1) a = g v · K c mod p, - // (11.2) b = C0v · β c mod p. - // An election verifier must then confirm the following. - // (11.A) The given value v is in the set Zq . - // (11.B) The challenge value c satisfies c = H(HE ; 0x31, K, C0 , C1 , C2 , a, b, β). private fun verifyContestData(decryptedContestData: DecryptedTallyOrBallot.DecryptedContestData, errs: ErrorMessages){ // (11.A,14.A) The given value v is in the set Zq. if (!decryptedContestData.proof.r.inBounds()) { diff --git a/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyEncryptedBallots.kt b/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyEncryptedBallots.kt index 7ae2e0d..5f8c632 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyEncryptedBallots.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyEncryptedBallots.kt @@ -22,6 +22,7 @@ import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.yield import org.cryptobiotic.eg.encrypt.EncryptedBallotChain import org.cryptobiotic.eg.encrypt.EncryptedBallotChain.Companion.assembleChain +import org.cryptobiotic.eg.preencrypt.PreEncryptor import org.cryptobiotic.eg.publish.Consumer import org.cryptobiotic.util.Stopwatch @@ -61,8 +62,7 @@ class VerifyEncryptedBallots( joinAll(*verifierJobs.toTypedArray()) } - // check duplicate confirmation codes (7.C): TODO what if there are multiple records for the election? - // TODO what about checking for duplicate ballot ids? + // check duplicate confirmation codes (7.C): val checkDuplicates = mutableMapOf() confirmationCodes.forEach { if (checkDuplicates[it.code] != null) { @@ -147,7 +147,7 @@ class VerifyEncryptedBallots( } if (isPreencrypt) { - verifyPreencryptionShortCodes(contest, errs) + verifyPreencryptionShortCodes(contest, errs, PreEncryptor::sigma) } } diff --git a/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyPreEncryptedBallots.kt b/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyPreEncryptedBallots.kt index 4d914a4..271b4b0 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyPreEncryptedBallots.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyPreEncryptedBallots.kt @@ -8,9 +8,6 @@ import org.cryptobiotic.util.ErrorMessages ////////////////////////////////////////////////////////////////////////////// // pre-encryption -// TODO specify sigma in manifest -private fun sigma(hash: UInt256): String = hash.toHex().substring(0, 5) - /* Every step of verification that applies to traditional ElectionGuard ballots also applies to pre- encrypted ballots – with the exception of the process for computing confirmation codes. However, @@ -53,6 +50,7 @@ record as uncast. fun VerifyEncryptedBallots.verifyPreencryptionShortCodes( contest: EncryptedBallot.Contest, errs: ErrorMessages, + sigma : (UInt256) -> String, // "hash trimming function Ω must be completely specified in the election manifest" ) { if (contest.preEncryption == null) { errs.add(" 18. Contest has no preEncryption") diff --git a/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyTally.kt b/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyTally.kt index 023cb3e..7715745 100644 --- a/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyTally.kt +++ b/src/main/kotlin/org/cryptobiotic/eg/verifier/VerifyTally.kt @@ -40,12 +40,7 @@ class VerifyTally( if (selection.encryptedVote.data != accum.data) { errs.add(" 8.B Ballot Aggregation does not match: $key") } - } /* else { - // TODO what is it? is it needed? left over from placeholders ?? - if (selection.encryptedVote.pad != group.ZERO_MOD_P || selection.encryptedVote.data != group.ZERO_MOD_P) { - errs.add(" Ballot Aggregation empty does not match $key") - } - } */ + } } } diff --git a/src/test/kotlin/org/cryptobiotic/eg/preencrypt/PreEncryptorTest.kt b/src/test/kotlin/org/cryptobiotic/eg/preencrypt/PreEncryptorTest.kt index d4e61aa..cb8bd03 100644 --- a/src/test/kotlin/org/cryptobiotic/eg/preencrypt/PreEncryptorTest.kt +++ b/src/test/kotlin/org/cryptobiotic/eg/preencrypt/PreEncryptorTest.kt @@ -295,7 +295,7 @@ internal fun runComplete( assertFalse(errs.hasErrors()) } -fun sigma(hash: UInt256): String = hash.toHex().substring(0, 5) +fun sigma(code: UInt256) : String = PreEncryptor.sigma(code) internal class ChosenBallot(val selectedIdx: Int) { diff --git a/src/test/kotlin/org/cryptobiotic/util/DfracTest.kt b/src/test/kotlin/org/cryptobiotic/util/DfracTest.kt index 34acce9..7d326a5 100644 --- a/src/test/kotlin/org/cryptobiotic/util/DfracTest.kt +++ b/src/test/kotlin/org/cryptobiotic/util/DfracTest.kt @@ -79,7 +79,7 @@ class DfracTest { fraction.append("0") } } else if (fixedDecimals < fracFigs) { - val chop = fracFigs - fixedDecimals // TODO should round !! + val chop = fracFigs - fixedDecimals // LOOK should round !! fraction.setLength(fraction.length - chop) }