Skip to content

Commit

Permalink
CLI return values.
Browse files Browse the repository at this point in the history
Tests use --noexit.
  • Loading branch information
JohnLCaron committed Apr 25, 2024
1 parent 4a9a7c5 commit 61a953d
Show file tree
Hide file tree
Showing 20 changed files with 199 additions and 127 deletions.
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/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-90.8%25%20LOC%20(6930/7630)-blue)
![Coverage](https://img.shields.io/badge/coverage-90.7%25%20LOC%20(6967/7680)-blue)

# ElectionGuard-Kotlin Elliptic Curve

_last update 04/24/2024_
_last update 04/25/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 Down
14 changes: 11 additions & 3 deletions src/main/kotlin/org/cryptobiotic/eg/cli/RunAccumulateTally.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import kotlinx.cli.ArgType
import kotlinx.cli.default
import kotlinx.cli.required
import org.cryptobiotic.util.Stopwatch
import kotlin.system.exitProcess

/**
* Run tally accumulation CLI.
Expand Down Expand Up @@ -58,6 +59,12 @@ class RunAccumulateTally {
shortName = "createdBy",
description = "who created"
)
val noexit by parser.option(
ArgType.Boolean,
shortName = "noexit",
description = "Dont call System.exit"
).default(false)

parser.parse(args)

val startupInfo = "starting '$name" +
Expand All @@ -80,7 +87,7 @@ class RunAccumulateTally {

} catch (t: Throwable) {
logger.error { "Exception= ${t.message} ${t.stackTraceToString()}" }
t.printStackTrace()
if (!noexit) exitProcess(-1)
}
}

Expand All @@ -91,14 +98,14 @@ class RunAccumulateTally {
name: String,
createdBy: String,
countNumberOfBallots: Boolean = false,
) {
): Int {
val stopwatch = Stopwatch()

val consumerIn = makeConsumer(inputDir)
val initResult = consumerIn.readElectionInitialized()
if (initResult is Err) {
logger.error { "readElectionInitialized error ${initResult.error}" }
return
return 1
}
val electionInit = initResult.unwrap()
val manifest = consumerIn.makeManifest(electionInit.config.manifestBytes)
Expand Down Expand Up @@ -134,6 +141,7 @@ class RunAccumulateTally {
)

logger.debug { "processed $countOk good ballots, $countBad bad ballots, ${stopwatch.tookPer(countOk, "good ballot")}" }
return if (countBad == 0) 0 else 2
}
}
}
50 changes: 30 additions & 20 deletions src/main/kotlin/org/cryptobiotic/eg/cli/RunCreateElectionConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.cryptobiotic.eg.core.productionGroup
import org.cryptobiotic.eg.election.makeElectionConfig
import org.cryptobiotic.eg.publish.makePublisher
import org.cryptobiotic.eg.publish.readAndCheckManifest
import kotlin.system.exitProcess

/** Run Create Election Configuration CLI. */
class RunCreateElectionConfig {
Expand Down Expand Up @@ -60,6 +61,11 @@ class RunCreateElectionConfig {
shortName = "chainCodes",
description = "chain confirmation codes"
).default(false)
val noexit by parser.option(
ArgType.Boolean,
shortName = "noexit",
description = "Dont call System.exit"
).default(false)
parser.parse(args)

val startupInfo = "starting" +
Expand All @@ -73,30 +79,34 @@ class RunCreateElectionConfig {
"\n chainCodes = $chainCodes"
logger.info { startupInfo }

val group = productionGroup(groupName)
try {
val group = productionGroup(groupName)

val (_, _, manifestBytes) = readAndCheckManifest(electionManifest)
val (_, _, manifestBytes) = readAndCheckManifest(electionManifest)

// As input, either specify the election record directory,
// OR the election manifest, nguardians and quorum.
val config =
makeElectionConfig(
group.constants,
nguardians,
quorum,
manifestBytes,
chainCodes,
baux0?.encodeToByteArray() ?: ByteArray(0), // use empty ByteArray if not specified
mapOf(
Pair("CreatedBy", createdBy),
Pair("CreatedOn", getSystemDate()),
),
)
// As input, either specify the election record directory,
// OR the election manifest, nguardians and quorum.
val config =
makeElectionConfig(
group.constants,
nguardians,
quorum,
manifestBytes,
chainCodes,
baux0?.encodeToByteArray() ?: ByteArray(0), // use empty ByteArray if not specified
mapOf(
Pair("CreatedBy", createdBy),
Pair("CreatedOn", getSystemDate()),
),
)

val publisher = makePublisher(outputDir, true)
publisher.writeElectionConfig(config)
val publisher = makePublisher(outputDir, true)
publisher.writeElectionConfig(config)

logger.info { "success" }
logger.info { "success" }
} catch (t: Throwable) {
if (!noexit) exitProcess(-1)
}
}
}
}
11 changes: 9 additions & 2 deletions src/main/kotlin/org/cryptobiotic/eg/cli/RunEncryptBallot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import org.cryptobiotic.eg.encrypt.submit
import org.cryptobiotic.eg.input.ManifestInputValidation
import org.cryptobiotic.eg.publish.*
import org.cryptobiotic.util.ErrorMessages
import kotlin.system.exitProcess

/**
* Reads a plaintext ballot from disk and writes its encryption to disk.
Expand Down Expand Up @@ -56,6 +57,11 @@ class RunEncryptBallot {
shortName = "deviceDir",
description = "Dont add device name to encrypted ballots directory"
).default(false)
val noexit by parser.option(
ArgType.Boolean,
shortName = "noexit",
description = "Dont call System.exit"
).default(false)
parser.parse(args)

logger.info {
Expand All @@ -73,10 +79,12 @@ class RunEncryptBallot {
)
if (retval != 0) {
logger.error { "failed retval=$retval" }
if (!noexit) exitProcess(retval)
}

} catch (t: Throwable) {
logger.error(t) { "failed ${t.message}" }
if (!noexit) exitProcess(-1)
}
}

Expand Down Expand Up @@ -104,8 +112,7 @@ class RunEncryptBallot {
val sink: EncryptedBallotSinkIF = publisher.encryptedBallotSink( if (noDeviceNameInDir) null else device)

if (ballotFilepath == "CLOSE") {
close(makeConsumer(encryptBallotDir, consumerIn.group), device, publisher)
return 0
return close(makeConsumer(encryptBallotDir, consumerIn.group), device, publisher)
}

val configBaux0 = electionInit.config.configBaux0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.yield
import io.github.oshai.kotlinlogging.KotlinLogging
import kotlinx.cli.default
import org.cryptobiotic.eg.cli.RunTrustedTallyDecryption.Companion.readDecryptingTrustees

import org.cryptobiotic.eg.core.*
Expand All @@ -27,6 +28,7 @@ import org.cryptobiotic.eg.election.*
import org.cryptobiotic.eg.publish.*
import org.cryptobiotic.util.ErrorMessages
import org.cryptobiotic.util.Stopwatch
import kotlin.system.exitProcess

/**
* Decrypt challenged ballots with local trustees CLI.
Expand Down Expand Up @@ -68,18 +70,28 @@ class RunTrustedBallotDecryption {
shortName = "nthreads",
description = "Number of parallel threads to use"
)
val noexit by parser.option(
ArgType.Boolean,
shortName = "noexit",
description = "Dont call System.exit"
).default(false)

parser.parse(args)

val startupInfo = "RunTrustedBallotDecryption starting input= $inputDir trustees= $trusteeDir" +
" decryptChallenged = $decryptChallenged output = $outputDir"
logger.info { startupInfo }

try {
runDecryptBallots(
val (retval, _) = runDecryptBallots(
inputDir, outputDir, readDecryptingTrustees(inputDir, trusteeDir),
decryptChallenged, nthreads ?: 11
)
if (!noexit && retval != 0) exitProcess(retval)

} catch (t : Throwable) {
logger.error{"Exception= ${t.message} ${t.stackTraceToString()}"}
if (!noexit) exitProcess(-1)
}
}

Expand All @@ -89,14 +101,14 @@ class RunTrustedBallotDecryption {
decryptingTrustees: List<DecryptingTrusteeIF>,
decryptChallenged: String?, // comma delimited, no spaces
nthreads: Int,
): Int {
): Pair<Int,Int> {
val stopwatch = Stopwatch() // start timing here

val consumerIn = makeConsumer(inputDir)
val result: Result<TallyResult, ErrorMessages> = consumerIn.readTallyResult()
if (result is Err) {
logger.error { result.error.toString() }
return 0
return Pair(1,0)
}
val tallyResult = result.unwrap()
val guardians = Guardians(consumerIn.group, tallyResult.electionInitialized.guardians)
Expand Down Expand Up @@ -170,7 +182,7 @@ class RunTrustedBallotDecryption {

logger.info {" decrypt ballots ${stopwatch.tookPer(count, "ballots")}" }

return count
return Pair(0, count)
}

// parallelize over ballots
Expand Down
26 changes: 17 additions & 9 deletions src/main/kotlin/org/cryptobiotic/eg/cli/RunTrustedKeyCeremony.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import org.cryptobiotic.eg.keyceremony.KeyCeremonyTrustee
import org.cryptobiotic.eg.keyceremony.keyCeremonyExchange
import org.cryptobiotic.eg.publish.*
import org.cryptobiotic.util.Stopwatch
import kotlin.system.exitProcess

/**
* Run KeyCeremony CLI.
Expand Down Expand Up @@ -50,20 +51,26 @@ class RunTrustedKeyCeremony {
shortName = "createdBy",
description = "who created"
).default("RunTrustedKeyCeremony")
val noexit by parser.option(
ArgType.Boolean,
shortName = "noexit",
description = "Dont call System.exit"
).default(false)

parser.parse(args)

val startupInfo = "starting\n input= $inputDir\n trustees= $trusteeDir\n output = $outputDir"
logger.info { startupInfo }

val consumerIn = makeConsumer(inputDir)
val configResult = consumerIn.readElectionConfig()
if (configResult is Err) {
logger.error {"readElectionConfig error ${configResult.error}"}
return
}
val config = configResult.unwrap()

try {
val consumerIn = makeConsumer(inputDir)
val configResult = consumerIn.readElectionConfig()
if (configResult is Err) {
logger.error {"readElectionConfig error ${configResult.error}"}
if (!noexit) exitProcess(1)
}
val config = configResult.unwrap()

val result = runKeyCeremony(
consumerIn.group,
inputDir,
Expand All @@ -74,10 +81,11 @@ class RunTrustedKeyCeremony {
createdBy
)
logger.info {"result = $result"}
require(result is Ok)
if (!noexit && result !is Ok) exitProcess(2)

} catch (t: Throwable) {
logger.error{ "Exception= ${t.message} ${t.stackTraceToString()}" }
if (!noexit) exitProcess(-1)
}
}

Expand Down
Loading

0 comments on commit 61a953d

Please sign in to comment.