Skip to content

Commit

Permalink
Merge pull request #401 from JohnLCaron/decryptionMods
Browse files Browse the repository at this point in the history
Modifications to EG Decryption.
  • Loading branch information
JohnLCaron authored Oct 18, 2023
2 parents 5315f94 + 811b691 commit 4085589
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ data class DecryptingTrusteeDoerre(
): List<PartialDecryption> {
val results: MutableList<PartialDecryption> = mutableListOf()
for (text: ElementModP in texts) {
if (!text.isValidResidue()) {
return emptyList()
}
val u = group.randomElementModQ(2) // random value u in Zq
val a = group.gPowP(u) // (a,b) for the proof, spec 2.0.0, eq 69
val b = text powP u
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package electionguard.decrypt

import com.github.michaelbull.result.Err
import com.github.michaelbull.result.Result
import com.github.michaelbull.result.unwrap
import electionguard.ballot.EncryptedTally
import electionguard.ballot.DecryptedTallyOrBallot
Expand All @@ -12,7 +11,7 @@ import mu.KotlinLogging

private val logger = KotlinLogging.logger("TallyDecryptor")

private const val doVerifierSelectionProof = false
private const val doVerifierSelectionProof = true

/** Turn an EncryptedTally into a DecryptedTallyOrBallot, after all the partial decryptions have been done. */
internal class TallyDecryptor(
Expand Down Expand Up @@ -130,12 +129,15 @@ internal class TallyDecryptor(

val startVerify = getSystemTimeInMillis()

// the idea here is to do the proof verification, whose cost is 4 exponents (3 powP and 1 accPowp)
// check the proof verification, whose cost is 4 exponents (3 powP and 1 accPowp)
// If it fails, then do the individual guardian verification, hopefully to pinpoint the culprit.
// If it succeeds, dont have to do the individual verification
if (doVerifierSelectionProof) {
if (!decrypytedSelection.verifySelection()) {
logger.error { "verifySelection error for $contestId and ${selection.selectionId}" }
selectionDecryptions.checkIndividualResponses()
if (!selectionDecryptions.checkIndividualResponses()) {
logger.error {"checkIndividualResponses error for $contestId and ${selection.selectionId}"}
}
}
} else { // Otherwise do the individual guardian verifications, which costs 4*n exponents
if (!selectionDecryptions.checkIndividualResponses()) {
Expand Down
43 changes: 30 additions & 13 deletions egklib/src/commonMain/kotlin/electionguard/pep/PepBlindTrust.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import mu.KotlinLogging

private val logger = KotlinLogging.logger("DistPep")

private const val doVerifierSelectionProof = true


/** Egk PEP with blinding Guardians separate from decrypting Guardians, and a trusted admin. */
class PepBlindTrust(
val group: GroupContext,
Expand Down Expand Up @@ -133,7 +136,6 @@ class PepBlindTrust(
work23.blindResponses = responsesForTrustees
}


//4. all BGj in {BGj}:
// respond to challenge with vj = uj − c * ξj
// send to admin
Expand All @@ -158,17 +160,32 @@ class PepBlindTrust(
}
require(step4invert.size == ntexts) // list(texts, nb)

// 5. admin:
// for each BGj, verify that aj = α^vj * Aj^c and bj = β^vj * Bj^c for any j // 4 * nb
work23s.zip(step4invert).forEach { (work23, step4) -> // workj23s list(texts)
work23.blindResponses!!.zip(step4).forEach { (br, bcr) ->
val ajp = (work23.ciphertextRatio.pad powP bcr.response) * (br.bigAj powP work23.c)
val bjp = (work23.ciphertextRatio.data powP bcr.response) * (br.bigBj powP work23.c)
require(ajp == br.aj)
require(bjp == br.bj)
}
// cough, cough, while were at it: 6(b) v = Sum_dj(vj)
// 5.a admin:
work23s.zip(step4invert).forEach { (work23, step4) ->
// v = Sum_dj(vj)
work23.v = with(group) { step4.map { it.response }.addQ() }

// verify if ChaumPedersenProof(c, v).verify(cons0; {cons1, K}, α, β, A, B). // 4
val proof = ChaumPedersenProof(work23.c, work23.v!!)
val verifya = proof.verify(
extendedBaseHash,
0x42.toByte(),
jointPublicKey.key,
work23.ciphertextRatio.pad, work23.ciphertextRatio.data,
work23.bigA, work23.bigB,
)
// If true, can skip 5.b
if (!verifya) {
work23s.zip(step4invert).forEach { (work23, step4) -> // workj23s list(texts)
work23.blindResponses!!.zip(step4).forEach { (br, bcr) ->
// for each BGj, verify that aj = α^vj * Aj^c and bj = β^vj * Bj^c // 4 * nb
val ajp = (work23.ciphertextRatio.pad powP bcr.response) * (br.bigAj powP work23.c)
val bjp = (work23.ciphertextRatio.data powP bcr.response) * (br.bigBj powP work23.c)
require(ajp == br.aj)
require(bjp == br.bj)
}
}
}
}

// create an EncryptedBallot with the ciphertexts = (A, B), this is what we decrypt
Expand All @@ -186,10 +203,10 @@ class PepBlindTrust(
val ballotAB = ballot1.copy(contests = contestsAB)

//6. admin:
// (a) decrypt (A, B): (T, ChaumPedersenProof(c',v')) = EGDecrypt(A, B) // 8*nd
// (a) decrypt (A, B): (T, ChaumPedersenProof(c',v')) = EGDecrypt(A, B) // 4+5*nd
val decryption: DecryptedTallyOrBallot = decryptor.decryptPep(ballotAB)

// (b) v = Sum_dj(vj), IsEq = (T == 1)
// (b) IsEq = (T == 1)
// (c) Send (IsEq, c, v, α, β, c′, v′, A, B, T) to V and publish to BB.
workIterator = work23s.iterator()
var isEq = true
Expand Down
2 changes: 1 addition & 1 deletion egklib/src/commonTest/kotlin/electionguard/pep/PepTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ class PepTest {
val nb = btrustees.size
val nd = egkPep.decryptor.ndGuardians
val nenc = 1
val expect = (8 + 8 * nd + 8 * nb) * nenc // we do run the verifier
val expect = (16 + 4 * nb + 5 * nd) * nenc // we do run the verifier
println(" after doEgkPep ${group.showAndClearCountPowP()} expect = $expect")

assertTrue(resultPep is Ok)
Expand Down

0 comments on commit 4085589

Please sign in to comment.