Skip to content

Commit

Permalink
Merge pull request #58 from JohnLCaron/zipped
Browse files Browse the repository at this point in the history
Remove zipped file from repo, as its recreated each time.
  • Loading branch information
JohnLCaron authored Apr 13, 2024
2 parents 3caedd7 + 49d8f20 commit 53a3daa
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 50 deletions.
7 changes: 5 additions & 2 deletions docs/ElectionRecordJson.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# EGK Election Record JSON directory and file layout, version 2.1

draft 04/04/2024
draft 04/13/2024

## Public Election Record files

Expand All @@ -27,7 +27,8 @@ topdir/
````

The encrypted_ballots directory may optionally be divided into "device" subdirectories.
If using ballot chaining, each such subdirectory is a separate ballot chain.

If using ballot chaining, each such subdirectory is a separate ballot chain, like this:

````
topdir/
Expand Down Expand Up @@ -66,6 +67,8 @@ Files/directories may be absent, depending on the workflow stage:
* The challenged_ballots directory contain only challenged ballots that have been decrypted.
* DecryptedTallyJson and DecryptedBallotJson use the same schema (DecryptedTallyOrBallotJson)

The entire election record may be zipped; the library can read from the zip file, eg for verification.

## Private files

These files are not part of the election record, but are generated for internal use.
Expand Down
32 changes: 16 additions & 16 deletions htmlReport/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,18 @@ <h1>Overall Coverage Summary </h1>
<td class="name">all classes</td>
<td class="coverageStat">
<span class="percent">
83.2%
83.4%
</span>
<span class="absValue">
(475/571)
(476/571)
</span>
</td>
<td class="coverageStat">
<span class="percent">
87%
87.1%
</span>
<span class="absValue">
(1270/1460)
(1271/1460)
</span>
</td>
<td class="coverageStat">
Expand All @@ -71,7 +71,7 @@ <h1>Overall Coverage Summary </h1>
90.2%
</span>
<span class="absValue">
(6890/7642)
(6892/7642)
</span>
</td>
</tr>
Expand Down Expand Up @@ -106,34 +106,34 @@ <h2>Coverage Breakdown</h2>
<td class="name"><a href="ns-1/index.html">org.cryptobiotic.eg.cli</a></td>
<td class="coverageStat">
<span class="percent">
60.2%
60.9%
</span>
<span class="absValue">
(80/133)
(81/133)
</span>
</td>
<td class="coverageStat">
<span class="percent">
69%
69.5%
</span>
<span class="absValue">
(140/203)
(141/203)
</span>
</td>
<td class="coverageStat">
<span class="percent">
69%
69.3%
</span>
<span class="absValue">
(200/290)
(201/290)
</span>
</td>
<td class="coverageStat">
<span class="percent">
89.8%
90%
</span>
<span class="absValue">
(1244/1385)
(1246/1385)
</span>
</td>
</tr>
Expand Down Expand Up @@ -227,10 +227,10 @@ <h2>Coverage Breakdown</h2>
</td>
<td class="coverageStat">
<span class="percent">
61.2%
60.5%
</span>
<span class="absValue">
(93/152)
(92/152)
</span>
</td>
<td class="coverageStat">
Expand Down Expand Up @@ -649,7 +649,7 @@ <h2>Coverage Breakdown</h2>

<div class="footer">

<div style="float:right;">generated on 2024-04-10 12:12</div>
<div style="float:right;">generated on 2024-04-12 14:46</div>
</div>
</body>
</html>
Expand Down
2 changes: 0 additions & 2 deletions src/main/kotlin/org/cryptobiotic/eg/cli/RunEncryptBallot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,11 @@ class RunEncryptBallot {
)
if (retval != 0) {
logger.info { "encryptBallot retval=$retval" }
// exitProcess(retval)
}
}

} catch (t: Throwable) {
logger.error(t) { "failed ${t.message}" }
// exitProcess(10)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import org.cryptobiotic.eg.input.RandomBallotProvider
import org.cryptobiotic.eg.publish.makeConsumer
import org.cryptobiotic.eg.publish.makePublisher
import kotlin.random.Random
import kotlin.system.exitProcess

/**
* Simulates using RunEncryptBallot one ballot at a time.
* Note that chaining is controlled by config.chainConfirmationCodes, and handled by RunEncryptBallot.
* Note that this does not allow for benolah challenge, ie voter submits a ballot, gets a confirmation code
* (with or without ballot chaining), then decide to challenge or cast. So all ballots are cast. */
* (with or without ballot chaining), then decide to challenge or cast. So all ballots are cast.
*/
class RunExampleEncryption {

companion object {
Expand Down Expand Up @@ -112,7 +112,6 @@ class RunExampleEncryption {
logger.info { "success" }
} else {
logger.error { "failure" }
exitProcess(10)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ data class ElectionConfig(
val manifestHash : UInt256, // Hm
val electionBaseHash : UInt256, // Hb
// the raw bytes of the manifest. You must regenerate the manifest from this.
val manifestBytes: ByteArray, // TODO may need to specify serialization form, or detect it.
val manifestBytes: ByteArray,

val chainConfirmationCodes: Boolean = false,
val configBaux0: ByteArray, // B_aux,0 from eq 59,60 may be empty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import java.io.Closeable
private val logger = KotlinLogging.logger("AddEncryptedBallot")

/**
* Encrypt a ballot and add to election record. TODO Single threaded only?.
* Encrypt a ballot and add to election record. Single threaded or thread confined only.
* Note that chaining is controlled by config.chainConfirmationCodes, and handled here.
* Note that this allows for benolah challenge, ie voter submits a ballot, gets a confirmation code
* (with or without ballot chaining), then decide to challenge or cast.
Expand Down Expand Up @@ -132,7 +132,7 @@ class AddEncryptedBallot(
sink.writeEncryptedBallot(eballot)
Ok(eballot)
} catch (t: Throwable) {
logger.throwing(t) // TODO
logger.throwing(t)
Err("Tried to submit Ciphertext ballot state=$state ccode=$ccode error = ${t.message}")
}
}
Expand Down Expand Up @@ -164,7 +164,7 @@ class AddEncryptedBallot(
}
}
} catch (t: Throwable) {
logger.throwing(t) // TODO
logger.throwing(t)
return Err("Tried to challenge Ciphertext ballot ccode=$ccode error = ${t.message}")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,13 @@ import org.cryptobiotic.util.ErrorMessages
// TODO error if ballotChain is already closed ??

// Let Baux,0 = "Baux,0 must contain at least a unique voting device identifier and possibly other voting device
// information as described above and as specified in the election manifest file.
// information as described above and as specified in the election manifest file." p 36.
//
// Then:
//
// H0 = H(HE ; 0x24, Baux,0) (59)
//
// Baux,1 = H0 ∥ Baux,0
//
// H(B1) = H(HE ; 0x24, χ1 , χ2 , . . . , χmB , Baux,1 ).
//
// Baux,j = Hj−1 ∥ Baux,0 (60)
//
// H(Bj) = H(HE ; 0x24, χ1 , χ2 , . . . , χmB , Baux,j ).

data class EncryptedBallotChain(
Expand Down
6 changes: 3 additions & 3 deletions src/main/kotlin/org/cryptobiotic/eg/encrypt/Encryptor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import org.cryptobiotic.eg.election.*
import org.cryptobiotic.util.ErrorMessages

/**
* Encrypt Plaintext Ballots into Ciphertext Ballots.
* Encrypt Plaintext Ballots into PendingEncryptedBallot.
* The manifest is expected to have passed manifest validation (see ManifestInputValidation).
* The input ballots are expected to have passed ballot validation [TODO missing contests added? overvotes checked?]
* See RunBatchEncryption and BallotInputValidation to validate ballots before passing them to this class.
* The input ballots are expected to have passed ballot validation
* See RunExampleEncryption and BallotInputValidation to validate ballots before passing them to this class.
*/
class Encryptor(
val group: GroupContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ open class KeyCeremonyTrustee(
// (αi,ℓ , βi,ℓ ) = (g^ξi,ℓ mod p, K^ξi,ℓ mod p), ξi,ℓ = nonce
// (α_i,ℓ , β_i,ℓ ) = (g^nonce mod p, Kℓ^nonce mod p) ; spec 2.0.0, eq 14
// by encrypting a zero, we achieve exactly this
val K_l = ElGamalPublicKey(other.publicKey) // TODO is it worth turning this into an accelerated elementP?
val K_l = ElGamalPublicKey(other.publicKey)
val (alpha, beta) = 0.encrypt(K_l, nonce)
// ki,ℓ = H(HP ; 0x11, i, ℓ, Kℓ , αi,ℓ , βi,ℓ ) ; eq 15 "secret key"
val kil = hashFunction(hp, 0x11.toByte(), i, l, other.publicKey, alpha, beta).bytes
Expand Down
Binary file removed src/test/data/workflow/allAvailableEc.zip
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ import org.cryptobiotic.util.Testing

class AddEncryptedBallotTest {
val input = "src/test/data/workflow/allAvailableEc"
val outputDir = "${Testing.testOut}/encrypt/addEncryptedBallot/Plain"
val testDir = "${Testing.testOut}/encrypt/addEncryptedBallot/Plain"
val nballots = 4

@Test
fun testJustOne() {
val outputDir = "$outputDir/testJustOne"
val outputDir = "$testDir/testJustOne"
val device = "device0"

val electionRecord = readElectionRecord(input)
Expand Down Expand Up @@ -57,7 +57,7 @@ class AddEncryptedBallotTest {

@Test
fun testEncryptAndCast() {
val outputDir = "$outputDir/testEncryptAndCast"
val outputDir = "$testDir/testEncryptAndCast"
val device = "device0"

val electionRecord = readElectionRecord(input)
Expand All @@ -82,7 +82,10 @@ class AddEncryptedBallotTest {
val ballot = ballotProvider.makeBallot()
val result = encryptor.encryptAndCast(ballot, ErrorMessages("testEncryptAndCast"))
assertNotNull(result)
assertTrue(encryptor.submit(result.confirmationCode, EncryptedBallot.BallotState.CAST) is Err)
// expect submitting again to fail
val submitAgain = encryptor.submit(result.confirmationCode, EncryptedBallot.BallotState.CAST)
assertTrue(submitAgain is Err)
assertTrue(submitAgain.error.contains("unknown ballot ccode"))
}
encryptor.close()

Expand All @@ -91,7 +94,7 @@ class AddEncryptedBallotTest {

@Test
fun testEncryptAndCastNoWrite() {
val outputDir = "$outputDir/testEncryptAndCastNoWrite"
val outputDir = "$testDir/testEncryptAndCastNoWrite"
val device = "device0"

val electionRecord = readElectionRecord(input)
Expand All @@ -116,16 +119,21 @@ class AddEncryptedBallotTest {
val ballot = ballotProvider.makeBallot()
val result = encryptor.encryptAndCast(ballot, ErrorMessages("testEncryptAndCastNoWrite"), false)
assertNotNull(result)
assertTrue(encryptor.submit(result.confirmationCode, EncryptedBallot.BallotState.CAST) is Err)
// expect submitting again to fail
val submitAgain = encryptor.submit(result.confirmationCode, EncryptedBallot.BallotState.CAST)
assertTrue(submitAgain is Err)
assertTrue(submitAgain.error.contains("unknown ballot ccode"))
}
encryptor.close()

// TODO make sure no ballots were written
// make sure no ballots were written
val consumer = makeConsumer(outputDir)
assertFalse(consumer.hasEncryptedBallots())
}

@Test
fun testCallMultipleTimes() {
val outputDir = "$outputDir/testCallMultipleTimes"
val outputDir = "$testDir/testCallMultipleTimes"
val device = "device1"

val electionRecord = readElectionRecord(input)
Expand Down Expand Up @@ -161,7 +169,7 @@ class AddEncryptedBallotTest {

@Test
fun testMultipleDevices() {
val outputDir = "$outputDir/testMultipleDevices"
val outputDir = "$testDir/testMultipleDevices"

val electionRecord = readElectionRecord(input)
val electionInit = electionRecord.electionInit()!!
Expand Down Expand Up @@ -196,7 +204,7 @@ class AddEncryptedBallotTest {

@Test
fun testOneWithChain() {
val outputDir = "$outputDir/testOneWithChain"
val outputDir = "$testDir/testOneWithChain"
val device = "device0"

val electionRecord = readElectionRecord(input)
Expand Down Expand Up @@ -232,7 +240,7 @@ class AddEncryptedBallotTest {

@Test
fun testCallMultipleTimesChaining() {
val outputDir = "$outputDir/testCallMultipleTimesChaining"
val outputDir = "$testDir/testCallMultipleTimesChaining"
val device = "device1"

val electionRecord = readElectionRecord(input)
Expand Down Expand Up @@ -270,7 +278,7 @@ class AddEncryptedBallotTest {

@Test
fun testMultipleDevicesChaining() {
val outputDir = "$outputDir/testMultipleDevicesChaining"
val outputDir = "$testDir/testMultipleDevicesChaining"

val electionRecord = readElectionRecord( input)
val configWithChaining = electionRecord.config().copy(chainConfirmationCodes = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import org.cryptobiotic.eg.cli.RunVerifier
import org.cryptobiotic.eg.core.createDirectories
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
Expand All @@ -19,6 +20,7 @@ import kotlin.test.assertNotNull

import org.cryptobiotic.eg.publish.json.*
import org.cryptobiotic.util.ErrorMessages
import org.cryptobiotic.util.Testing


// run verifier on zipped JSON record
Expand All @@ -27,11 +29,12 @@ class TestZippedJson {
val jsonReader = Json { explicitNulls = false; ignoreUnknownKeys = true; prettyPrint = true }

val inputDir = "src/test/data/workflow/allAvailableEc"
val zippedJson = "src/test/data/workflow/allAvailableEc.zip"
val zippedJson = "${Testing.testOut}/zip/allAvailableEc.zip"
val fs: FileSystem
val fsp: FileSystemProvider

init {
createDirectories("${Testing.testOut}/zip/")
zipFolder(File(inputDir), File(zippedJson))
fs = FileSystems.newFileSystem(Path.of(zippedJson), mutableMapOf<String, String>())
fsp = fs.provider()
Expand Down Expand Up @@ -60,6 +63,7 @@ class TestZippedJson {
fun testVerifyEncryptedBallots() {
RunVerifier.verifyEncryptedBallots(zippedJson, 11)
RunVerifier.verifyChallengedBallots(zippedJson)
RunVerifier.runVerifier(zippedJson, 11)
}
}

Expand Down

0 comments on commit 53a3daa

Please sign in to comment.