Skip to content

Commit

Permalink
Merge pull request #427 from JohnLCaron/verifierErrors
Browse files Browse the repository at this point in the history
Verifier uses ErrorMessages.
  • Loading branch information
JohnLCaron authored Nov 9, 2023
2 parents 1231d17 + 33d69b4 commit 6915402
Show file tree
Hide file tree
Showing 17 changed files with 267 additions and 245 deletions.
20 changes: 9 additions & 11 deletions egklib/src/commonMain/kotlin/electionguard/ballot/Manifest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,22 @@ data class Manifest(
return styleToContestsMap[ballotStyle]
}

override fun contestLimit(contestId : String) : Int {
return contestIdToContestLimit[contestId]?: 1
override fun findContest(contestId: String): ManifestIF.Contest? {
return contestMap[contestId]
}

override fun optionLimit(contestId : String) : Int {
return contestIdToOptionLimit[contestId]?: 1
override fun contestLimit(contestId : String) : Int {
return contestMap[contestId]?.votesAllowed ?: 1
}

/** Map of contestId to contest selection limit. */
val contestIdToContestLimit : Map<String, Int> by
lazy {
contests.associate { it.contestId to it.votesAllowed }
override fun optionLimit(contestId : String) : Int {
return contestMap[contestId]?.optionSelectionLimit ?: 1
}

/** Map of contestId to contest selection limit. */
val contestIdToOptionLimit : Map<String, Int> by
/** Map of contestId to contests. */
val contestMap : Map<String, ContestDescription> by
lazy {
contests.associate { it.contestId to it.optionSelectionLimit }
contests.associateBy { it.contestId }
}

/** Map "$contestId/$selectionId" to candidateId. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ interface ManifestIF {
/** get the list of valid contests for the given ballotStyle */
fun contestsForBallotStyle(ballotStyle : String): List<Contest>?

fun findContest(contestId: String): Contest?

/** get the contest selection limit (aka votesAllowed) for the given contest id */
fun contestLimit(contestId : String): Int

Expand Down
84 changes: 56 additions & 28 deletions egklib/src/commonMain/kotlin/electionguard/verifier/Verifier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.github.michaelbull.result.*
import electionguard.ballot.*
import electionguard.core.*
import electionguard.publish.ElectionRecord
import electionguard.util.ErrorMessages
import electionguard.util.Stats

class Verifier(val record: ElectionRecord, val nthreads: Int = 11) {
Expand Down Expand Up @@ -56,45 +57,64 @@ class Verifier(val record: ElectionRecord, val nthreads: Int = 11) {
}

// encryption and vote limits
val verifyEncryptions = VerifyEncryptedBallots(group, manifest, jointPublicKey, He, config, nthreads)
// Note we are validating all ballots, not just CAST,including preencrypted
val ballotResult = verifyEncryptions.verifyBallots(record.encryptedAllBallots { true }, stats, showTime)
println(" 5,6,15,16,17,18. verifyEncryptedBallots $ballotResult")
val encryptionVerifier = VerifyEncryptedBallots(group, manifest, jointPublicKey, He, config, nthreads)
// Note we are validating all ballots, not just CAST, and including preencrypted
val eerrs = ErrorMessages("")
val ballotsOk = encryptionVerifier.verifyBallots(record.encryptedAllBallots { true }, eerrs, stats, showTime)
println(" 5,6,15,16,17,18. verifyEncryptedBallots $ballotsOk")
if (!ballotsOk) {
println(eerrs)
}

val chainResults = if (config.chainConfirmationCodes) {
val chainResult = verifyEncryptions.verifyConfirmationChain(record)
println(" 7. verifyConfirmationChain $chainResult")
chainResult
} else Ok(true)
val chainOk = if (!config.chainConfirmationCodes) true else {
val chainErrs = ErrorMessages("")
val ok = encryptionVerifier.verifyConfirmationChain(record, chainErrs)
println(" 7. verifyConfirmationChain $ok")
if (!ok) {
println(chainErrs)
}
ok
}

if (record.stage() < ElectionRecord.Stage.TALLIED) {
println("election record stage = ${record.stage()}, stopping verification now\n")
return true
}

// tally accumulation
val verifyTally = VerifyTally(group, verifyEncryptions.aggregator)
val aggResult = verifyTally.verify(record.encryptedTally()!!, showTime)
println(" 8. verifyBallotAggregation $aggResult")
val tallyVerifier = VerifyTally(group, encryptionVerifier.aggregator)
val tallyErrs = ErrorMessages("")
val tallyOk = tallyVerifier.verify(record.encryptedTally()!!, tallyErrs, showTime)
println(" 8. verifyBallotAggregation $tallyOk")
if (!tallyOk) {
println(tallyErrs)
}

if (record.stage() < ElectionRecord.Stage.DECRYPTED) {
println("election record stage = ${record.stage()}, stopping verification now\n")
return true
}

// tally decryption
val verifyDecryption = VerifyDecryption(group, manifest, jointPublicKey, He)
val tallyResult = verifyDecryption.verify(record.decryptedTally()!!, isBallot = false, stats)
println(" 9,10,11. verifyTallyDecryption $tallyResult")
val decryptionVerifier = VerifyDecryption(group, manifest, jointPublicKey, He)
val tdErrs = ErrorMessages("")
val tdOk = decryptionVerifier.verify(record.decryptedTally()!!, isBallot = false, tdErrs, stats)
println(" 9,10,11. verifyTallyDecryption $tdOk")
if (!tdOk) {
println(tdErrs)
}

// 12, 13, 14 spoiled ballots
val spoiledResult =
verifyDecryption.verifySpoiledBallotTallies(record.decryptedBallots(), nthreads, stats, showTime)
println(" 12,13,14. verifySpoiledBallotTallies $spoiledResult")
val spoiledErrs = ErrorMessages("")
val spoiledOk =
decryptionVerifier.verifySpoiledBallotTallies(record.decryptedBallots(), nthreads, spoiledErrs, stats, showTime)
println(" 12,13,14. verifySpoiledBallotTallies $spoiledOk")
if (!spoiledOk) {
println(spoiledErrs)
}

val allOk = (parametersOk is Ok) && (guardiansOk is Ok) && (publicKeyOk is Ok) && (baseHashOk is Ok) &&
(ballotResult is Ok) &&
(chainResults is Ok) && (aggResult is Ok) && (tallyResult is Ok) && (spoiledResult is Ok)
ballotsOk && chainOk && tallyOk && tdOk && spoiledOk
println("verify allOK = $allOk\n")
return allOk
}
Expand Down Expand Up @@ -192,24 +212,32 @@ class Verifier(val record: ElectionRecord, val nthreads: Int = 11) {
return errors.merge()
}

fun verifyEncryptedBallots(stats : Stats): Result<Boolean, String> {
fun verifyEncryptedBallots(stats : Stats): ErrorMessages {
val errs = ErrorMessages("verifyDecryptedTally")
val verifyBallots = VerifyEncryptedBallots(group, manifest, jointPublicKey, He, record.config(), nthreads)
return verifyBallots.verifyBallots(record.encryptedAllBallots { true }, stats)
verifyBallots.verifyBallots(record.encryptedAllBallots { true }, errs, stats)
return errs
}

fun verifyEncryptedBallots(ballots: Iterable<EncryptedBallot>, stats : Stats): Result<Boolean, String> {
fun verifyEncryptedBallots(ballots: Iterable<EncryptedBallot>, stats : Stats): ErrorMessages {
val errs = ErrorMessages("verifyDecryptedTally")
val verifyBallots = VerifyEncryptedBallots(group, manifest, jointPublicKey, He, record.config(), nthreads)
return verifyBallots.verifyBallots(ballots, stats)
verifyBallots.verifyBallots(ballots, errs, stats)
return errs
}

fun verifyDecryptedTally(tally: DecryptedTallyOrBallot, stats: Stats): Result<Boolean, String> {
fun verifyDecryptedTally(tally: DecryptedTallyOrBallot, stats: Stats): ErrorMessages {
val errs = ErrorMessages("verifyDecryptedTally")
val verifyTally = VerifyDecryption(group, manifest, jointPublicKey, He)
return verifyTally.verify(tally, false, stats)
verifyTally.verify(tally, false, errs, stats)
return errs
}

fun verifySpoiledBallotTallies(stats: Stats): Result<Boolean, String> {
fun verifySpoiledBallotTallies(stats: Stats): ErrorMessages {
val errs = ErrorMessages("verifyDecryptedTally")
val verifyTally = VerifyDecryption(group, manifest, jointPublicKey, He)
return verifyTally.verifySpoiledBallotTallies(record.decryptedBallots(), nthreads, stats, true)
verifyTally.verifySpoiledBallotTallies(record.decryptedBallots(), nthreads, errs, stats, true)
return errs
}

fun verifyTallyBallotIds(): Boolean {
Expand Down
Loading

0 comments on commit 6915402

Please sign in to comment.