Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove zipped file from repo, as its recreated each time. #58

Merged
merged 1 commit into from
Apr 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading