Skip to content

Commit

Permalink
Merge pull request #52 from JohnLCaron/coverage4
Browse files Browse the repository at this point in the history
Add tests to increase coverage.
  • Loading branch information
JohnLCaron authored Apr 9, 2024
2 parents d535f0d + 4507d8d commit c972e6e
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 163 deletions.
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
[![License](https://img.shields.io/github/license/JohnLCaron/egk-ec)](https://github.com/JohnLCaron/egk-ec/main/LICENSE.txt)
[![License](https://img.shields.io/github/license/JohnLCaron/egk-ec)](https://github.com/JohnLCaron/egk-ec/blob/main/LICENSE.txt)
![GitHub branch checks state](https://img.shields.io/github/actions/workflow/status/JohnLCaron/egk-ec/unit-tests.yml)
![Coverage](https://img.shields.io/badge/Coverage-89.1%25%20(6819/7649)-blue)
[![Coverage](https://img.shields.io/badge/coverage-90.2%25%20LOC%20(6875/7623)-blue)](https://github.com/JohnLCaron/egk-ec/blob/main/htmlReport/index.html)

# ElectionGuard-Kotlin Elliptic Curve


_last update 04/08/2024_
_last update 04/09/2024_

EGK Elliptic Curve (egk-ec) is an experimental implementation of [ElectionGuard](https://github.com/microsoft/electionguard),
[version 2.0](https://github.com/microsoft/electionguard/releases/download/v2.0/EG_Spec_2_0.pdf),
Expand All @@ -26,8 +25,6 @@ See [EGK EC mixnet](https://github.com/JohnLCaron/egk-ec-mixnet) for an implemen

See [EGK webapps](https://github.com/JohnLCaron/egk-webapps) for HTTP client/server applications that use this library to allow remote workflows.

Currently we have 89.1% (6819/7649) LOC test coverage.

## Documentation
* [Getting Started](docs/GettingStarted.md)
* [Workflow and Command Line Programs](docs/CommandLineInterface.md)
Expand Down
50 changes: 25 additions & 25 deletions htmlReport/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,34 +44,34 @@ <h1>Overall Coverage Summary </h1>
<td class="name">all classes</td>
<td class="coverageStat">
<span class="percent">
81.4%
83.1%
</span>
<span class="absValue">
(464/570)
(473/569)
</span>
</td>
<td class="coverageStat">
<span class="percent">
85.7%
87.1%
</span>
<span class="absValue">
(1249/1458)
(1266/1454)
</span>
</td>
<td class="coverageStat">
<span class="percent">
65.9%
66.5%
</span>
<span class="absValue">
(1787/2710)
(1794/2696)
</span>
</td>
<td class="coverageStat">
<span class="percent">
89.2%
90.2%
</span>
<span class="absValue">
(6826/7655)
(6875/7623)
</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.9%
60.2%
</span>
<span class="absValue">
(81/133)
(80/133)
</span>
</td>
<td class="coverageStat">
<span class="percent">
69.5%
69%
</span>
<span class="absValue">
(141/203)
(140/203)
</span>
</td>
<td class="coverageStat">
<span class="percent">
69.3%
69%
</span>
<span class="absValue">
(201/290)
(200/290)
</span>
</td>
<td class="coverageStat">
<span class="percent">
90%
89.8%
</span>
<span class="absValue">
(1246/1385)
(1244/1385)
</span>
</td>
</tr>
Expand Down Expand Up @@ -491,34 +491,34 @@ <h2>Coverage Breakdown</h2>
<td class="name"><a href="ns-c/index.html">org.cryptobiotic.eg.publish.json</a></td>
<td class="coverageStat">
<span class="percent">
86.4%
93.8%
</span>
<span class="absValue">
(127/147)
(137/146)
</span>
</td>
<td class="coverageStat">
<span class="percent">
87.3%
94.4%
</span>
<span class="absValue">
(268/307)
(286/303)
</span>
</td>
<td class="coverageStat">
<span class="percent">
55.7%
59.3%
</span>
<span class="absValue">
(246/442)
(254/428)
</span>
</td>
<td class="coverageStat">
<span class="percent">
87.7%
93.9%
</span>
<span class="absValue">
(1157/1319)
(1208/1287)
</span>
</td>
</tr>
Expand Down Expand Up @@ -649,7 +649,7 @@ <h2>Coverage Breakdown</h2>

<div class="footer">

<div style="float:right;">generated on 2024-04-09 11:54</div>
<div style="float:right;">generated on 2024-04-09 15:46</div>
</div>
</body>
</html>
Expand Down
4 changes: 0 additions & 4 deletions src/main/kotlin/org/cryptobiotic/eg/publish/Consumer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ interface Consumer {
fun readTallyResult(): Result<TallyResult, ErrorMessages>
fun readEncryptedTallyFromFile(filename: String): Result<EncryptedTally, ErrorMessages>
fun readDecryptionResult(): Result<DecryptionResult, ErrorMessages>
fun readDecryptedTallyFromFile(filename: String): Result<DecryptedTallyOrBallot, ErrorMessages>

/** Are there any encrypted ballots? */
fun hasEncryptedBallots() : Boolean
Expand All @@ -53,9 +52,6 @@ interface Consumer {
fun iterateDecryptedBallots(ballotOverrideDir: String? = null): Iterable<DecryptedTallyOrBallot>

//// may be outside the election record
/** read encrypted ballots in given directory. */
@Deprecated("to be removed")
fun iterateEncryptedBallotsFromDir(ballotDir: String, filter : Predicate<EncryptedBallot>? ): Iterable<EncryptedBallot> // TODO remove?
/** read plaintext ballots in given directory, private data. */
fun iteratePlaintextBallots(ballotDir: String, filter : ((PlaintextBallot) -> Boolean)? ): Iterable<PlaintextBallot>
/** read trustee in given directory for given guardianId, private data. */
Expand Down
27 changes: 0 additions & 27 deletions src/main/kotlin/org/cryptobiotic/eg/publish/json/ConsumerJson.kt
Original file line number Diff line number Diff line change
Expand Up @@ -136,23 +136,6 @@ class ConsumerJson(val topDir: String, usegroup: GroupContext? = null) : Consume
)
}

override fun readDecryptedTallyFromFile(filename: String): Result<DecryptedTallyOrBallot, ErrorMessages> {
val errs = ErrorMessages("DecryptedTallyFromFile '$filename'")
val decryptedTallyPath = Path.of(filename)
if (!Files.exists(decryptedTallyPath)) {
return errs.add("file does not exist ")
}
return try {
fileSystemProvider.newInputStream(decryptedTallyPath, StandardOpenOption.READ).use { inp ->
val json = jsonReader.decodeFromStream<DecryptedTallyOrBallotJson>(inp)
val tally = json.import(group, errs)
if (errs.hasErrors()) Err(errs) else Ok(tally!!)
}
} catch (t: Throwable) {
errs.add("Exception= ${t.message} ${t.stackTraceToString()}")
}
}

//////////////////////////////////////////////////////////////////////////////////////////////////

override fun hasEncryptedBallots(): Boolean {
Expand All @@ -179,16 +162,6 @@ class ConsumerJson(val topDir: String, usegroup: GroupContext? = null) : Consume
return Iterable { DeviceIterator(devices.iterator(), filter) }
}

// TODO

override fun iterateEncryptedBallotsFromDir(ballotDir: String, filter: Predicate<EncryptedBallot>? ): Iterable<EncryptedBallot> {
val path = fileSystem.getPath(ballotDir)
if (!Files.exists(path)) {
return emptyList()
}
return Iterable { EncryptedBallotFileIterator(path, filter) }
}

/////////////////////////////////////////////////////////////////////////////////////

override fun encryptingDevices(): List<String> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ data class DecryptRequestJson(
val texts: List<ElementModPJson>
)

fun DecryptRequest.publishJson() = DecryptRequestJson( this.texts.map { it.publishJson() } )
fun DecryptRequest.publishJson() = DecryptRequestJson( this.texts.map { it.publishJson() } )

fun DecryptRequestJson.import(group: GroupContext): Result< List<ElementModP>, String> {
fun DecryptRequestJson.import(group: GroupContext): Result<List<ElementModP>, String> {
val responses = this.texts.map { it.import(group) }
val allgood = responses.map { it != null }.reduce { a, b -> a && b }

Expand Down
Binary file modified src/test/data/workflow/allAvailableEc.zip
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package org.cryptobiotic.eg.publish.json

import org.cryptobiotic.eg.core.*
import org.cryptobiotic.util.ErrorMessages
import org.cryptobiotic.eg.core.productionGroup

import io.kotest.property.Arb
import io.kotest.property.arbitrary.int
import io.kotest.property.arbitrary.single
import io.kotest.property.arbitrary.string
import io.kotest.property.checkAll
import org.cryptobiotic.eg.core.ecgroup.EcGroupContext
import org.cryptobiotic.eg.core.intgroup.tinyGroup
import org.cryptobiotic.eg.keyceremony.EncryptedKeyShare
import org.cryptobiotic.eg.keyceremony.KeyShare
import org.cryptobiotic.eg.keyceremony.PublicKeys
import kotlin.test.*

class KeyCeremonyJsonTest {
val groups = listOf(
tinyGroup(),
productionGroup("Integer3072"),
productionGroup("Integer4096"),
EcGroupContext("P-256")
)

@Test
fun testPublicKeysRoundtrip() {
groups.forEach { testPublicKeysRoundtrip(it) }
}

fun testPublicKeysRoundtrip(group: GroupContext) {
runTest {
checkAll(
iterations = 33,
Arb.string(minSize = 3),
Arb.int(min = 1, max = 10),
Arb.int(min = 1, max = 10),
) { id, xcoord, quota, ->

val proofs = mutableListOf<SchnorrProof>()
repeat(quota) {
val kp = elGamalKeypairs(group).single()
val nonce = elementsModQ(group).single()
proofs.add(kp.schnorrProof(xcoord, it, nonce))
}
val publicKey = PublicKeys(id, xcoord, proofs)
assertEquals(publicKey, publicKey.publishJson().import(group, ErrorMessages("round")))
assertEquals(publicKey, jsonRoundTrip(publicKey.publishJson()).import(group, ErrorMessages("trip")))
}
}
}

@Test
fun testKeyShareJsonRoundtrip() {
groups.forEach { testKeyShareJsonRoundtrip(it) }
}

fun testKeyShareJsonRoundtrip(group: GroupContext) {
runTest {
checkAll(
iterations = 33,
Arb.int(min = 1, max = 10),
Arb.string(minSize = 3),
Arb.string(minSize = 3),
) { id, owner, secretShareFor, ->
val kshare = KeyShare(id, owner, secretShareFor, group.randomElementModQ(2))
assertEquals(kshare, kshare.publishJson().import(group))
}
}
}

@Test
fun testKeyEncryptedShareJsonRoundtrip() {
groups.forEach { testEncryptedKeyShareJsonRoundtrip(it) }
}

fun testEncryptedKeyShareJsonRoundtrip(group: GroupContext) {
runTest {
checkAll(
iterations = 33,
Arb.int(min = 1, max = 10),
Arb.string(minSize = 3),
Arb.string(minSize = 3),
) { id, owner, secretShareFor, ->
// val ownerXcoord: Int, // guardian i (owns the polynomial Pi) xCoordinate
// val polynomialOwner: String, // guardian i (owns the polynomial Pi)
// val secretShareFor: String, // guardian l with coordinate ℓ
// val encryptedCoordinate: HashedElGamalCiphertext, // El(Pi_(ℓ)), spec 2.0, eq 18
val eshare = EncryptedKeyShare(id, owner, secretShareFor, generateHashedCiphertext(group))
assertEquals(eshare, eshare.publishJson().import(group))
}
}
}
}
52 changes: 0 additions & 52 deletions src/test/kotlin/org/cryptobiotic/eg/publish/json/PublicKeysTest.kt

This file was deleted.

Loading

0 comments on commit c972e6e

Please sign in to comment.