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

Sync egk library. #31

Merged
merged 1 commit into from
May 22, 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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[![License](https://img.shields.io/github/license/JohnLCaron/egk-ec)](https://github.com/JohnLCaron/egk-ec-mixnet/blob/main/LICENSE.txt)
![GitHub branch checks state](https://img.shields.io/github/actions/workflow/status/JohnLCaron/egk-ec-mixnet/unit-tests.yml)
![Coverage](https://img.shields.io/badge/coverage-90.0%25%20LOC%20(1573/1748)-blue)
![Coverage](https://img.shields.io/badge/coverage-89.9%25%20LOC%20(1651/1836)-blue)

# Egk Elliptic Curves Mixnet

_last update 05/18/2024_
_last update 05/22/2024_

Implementation of a mixnet using the [ElectionGuard Kotlin Elliptical Curve library](https://github.com/JohnLCaron/egk-ec),
and the [Verificatum library](https://www.verificatum.org/). The mixnet uses the Terelius / Wikström (TW) mixnet
Expand Down
Binary file modified docs/mixnet-maths.zip
Binary file not shown.
Binary file modified docs/mixnet_maths.pdf
Binary file not shown.
Binary file modified libs/egk-ec-2.1-SNAPSHOT.jar
Binary file not shown.
136 changes: 136 additions & 0 deletions src/main/kotlin/org/cryptobiotic/mixnet/cli/RunMixnetTally.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package org.cryptobiotic.mixnet.cli

import com.github.michaelbull.result.Err
import com.github.michaelbull.result.unwrap
import io.github.oshai.kotlinlogging.KotlinLogging
import kotlinx.cli.ArgParser
import kotlinx.cli.ArgType
import kotlinx.cli.default
import kotlinx.cli.required
import org.cryptobiotic.eg.core.*
import org.cryptobiotic.eg.election.*
import org.cryptobiotic.eg.publish.makeConsumer
import org.cryptobiotic.eg.publish.makePublisher
import org.cryptobiotic.eg.tally.AccumulateTally
import org.cryptobiotic.mixnet.writer.MixnetConfigJson
import org.cryptobiotic.util.ErrorMessages
import org.cryptobiotic.mixnet.writer.readMixnetConfigFromFile
import org.cryptobiotic.mixnet.writer.readShuffledBallotsFromFile
import kotlin.system.exitProcess

class RunMixnetTally {

companion object {
val logger = KotlinLogging.logger("RunMixnetTally")

@JvmStatic
fun main(args: Array<String>) {
val parser = ArgParser("RunMixnetTally")
val publicDir by parser.option(
ArgType.String,
shortName = "in",
description = "egk mixnet public directory"
).required()
val mixDir by parser.option(
ArgType.String,
shortName = "mix",
description = "Mix directory"
).required()
val outputDir by parser.option(
ArgType.String,
shortName = "out",
description = "output directory"
).required()
val noexit by parser.option(
ArgType.Boolean,
shortName = "noexit",
description = "Dont call System.exit"
).default(false)

parser.parse(args)

val info = buildString {
appendLine("starting MixnetTally")
appendLine(" publicDir= $publicDir")
appendLine(" mixDir= $mixDir")
append(" outputDir= $outputDir")
}
logger.info { info }

val configFilename = "$mixDir/${RunMixnet.configFilename}"
val resultConfig = readMixnetConfigFromFile(configFilename)
if (resultConfig is Err) {
RunMixnet.logger.error { "Error reading MixnetConfig from $configFilename err = $resultConfig" }
if (!noexit) exitProcess(1) else return
}
val config = resultConfig.unwrap()

val valid = runAccumulateBallots(publicDir, config, mixDir, outputDir, noexit)
logger.info { "valid = $valid" }
}

fun runAccumulateBallots(
publicDir: String,
config: MixnetConfigJson,
mixDir: String,
outputDir: String,
noexit: Boolean
) {
val consumerIn = makeConsumer(publicDir)
val initResult = consumerIn.readElectionInitialized()
if (initResult is Err) {
logger.error { "readElectionInitialized error ${initResult.error}" }
return
}
val electionInit = initResult.unwrap()
val manifest = consumerIn.makeManifest(electionInit.config.manifestBytes)
val group = consumerIn.group

val shuffledResult = readShuffledBallotsFromFile( group, mixDir, config.width)
if (shuffledResult is Err) {
RunMixnetTable.logger.error {"Error reading shuffled ballots in $mixDir = $shuffledResult" }
if (!noexit) exitProcess(3) else return
}
val shuffled = shuffledResult.unwrap()
RunProofOfShuffleVerifier.logger.info { " Read ${shuffled.size} shuffled ballots" }

//val reader = BallotReader(group, config.width)
//val shuffled = reader.readFromFile("$mixDir/$shuffledFilename")

val accumulator = AccumulateTally(
group,
manifest,
config.mix_name,
electionInit.extendedBaseHash,
electionInit.jointPublicKey,
countNumberOfBallots = true,
)
val errs = ErrorMessages("RunAccumulateTally on Shuffled Ballots")
var nrows = 0
shuffled.forEach {
val ballotId = it.elems[0].hashCode().toString()
val eballot: EncryptedBallotIF = rehydrate(manifest, ballotId, electionInit.extendedBaseHash, 0, it)
if (!accumulator.addCastBallot(eballot, errs)) {
println(" got error $errs")
}
nrows++
}

val tally: EncryptedTally = accumulator.build()

val publisher = makePublisher(outputDir, false)
publisher.writeTallyResult(
TallyResult(
electionInit, tally, emptyList(),
mapOf(
Pair("CreatedBy", "RunMixnetTally"),
Pair("CreatedOn", getSystemDate()),
Pair("CreatedFromDir", mixDir)
)
)
)
println("writeTallyResult nrows=$nrows, width= ${config.width} per row" )
logger.info { "writeTallyResult nrows=$nrows, width= ${config.width} per row" }
}
}
}
37 changes: 37 additions & 0 deletions src/test/kotlin/org/cryptobiotic/mixnet/cli/RunMixnetTallyTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.cryptobiotic.mixnet.cli

import org.cryptobiotic.eg.core.createDirectories
import org.cryptobiotic.util.Testing
import kotlin.test.Test

class RunMixnetTallyTest {

@Test
fun testRunMixnetTally() {
val publicDir = "src/test/data/working/public"
val outputDir = "${Testing.testOutMixnet}/testRunMixnetTally"
createDirectories("$outputDir/mix1")
createDirectories("$outputDir/mix2")
createDirectories(outputDir)

RunMixnetTally.main(
arrayOf(
"--publicDir", publicDir,
"--mixDir", "$publicDir/mix1",
"--outputDir", "$outputDir/mix1",
)
)

/*
RunMixnetTally.main(
arrayOf(
"-publicDir", publicDir,
"--mixDir", "$outputDir/mix2",
"--outputDir", "$outputDir/mix2",
)
)

*/
}

}
Loading