Skip to content
This repository has been archived by the owner on Jun 13, 2022. It is now read-only.

Commit

Permalink
Now targeting unicrypt-2.2
Browse files Browse the repository at this point in the history
  • Loading branch information
ruescasd committed Feb 4, 2016
1 parent 40a5c80 commit 43cb90e
Show file tree
Hide file tree
Showing 13 changed files with 753 additions and 193 deletions.
167 changes: 9 additions & 158 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
Minimal voting demo using [unicrypt](https://github.com/bfh-evg/univote2) plus code/design from [univote](https://github.com/bfh-evg/univote2). Copied from [Election.scala](https://github.com/agoravoting/sandbox/blob/master/src/main/scala/Election.scala):
ElectionTest demo
=================

Minimal voting demo using [unicrypt](https://github.com/bfh-evg/univote2) plus code/design from [univote](https://github.com/bfh-evg/univote2). Below is the header to the ElectionTest App object found in [Election.scala](https://github.com/agoravoting/sandbox/blob/master/src/main/scala/Election.scala):

/**
* An election process DEMO
Expand Down Expand Up @@ -43,162 +46,10 @@ Minimal voting demo using [unicrypt](https://github.com/bfh-evg/univote2) plus c
*
* This demo uses two trustees, ElectionTest3 below shows how number of trustees generalizes
*/
object ElectionTest extends App {

// create the keymakers
// these are responsible for distributed key generation and joint decryption
val k1 = new KeyMakerTrustee("keymaker one")
val k2 = new KeyMakerTrustee("keymaker two")

// create the mixers
// these are responsible for shuffling the votes
val m1 = new MixerTrustee("mixer one")
val m2 = new MixerTrustee("mixer two")

// create the election,
// we are using privacy level 2, two trustees of each kind
// we are 2048 bits for the size of the group modulus
val start = Election.create[_2]("my election", 2048)

// the election is now ready to receive key shares
val readyForShares = Election.startShares(start)

// each keymaker creates the shares and their proofs, these are added to the election
val oneShare = Election.addShare(readyForShares, k1.createKeyShare(readyForShares), k1.id)
val twoShares = Election.addShare(oneShare, k2.createKeyShare(readyForShares), k2.id)

// combine the shares from the keymaker trustees, this produces the election public key
val combined = Election.combineShares(twoShares)

// since we are storing information in election as if it were a bulletin board, all
// the information is stored in a wire-compatible format, that is strings/jsons whatever
// we reconstruct the public key as if it had been read from such a format
val publicKey = Util.getPublicKeyFromString(combined.state.publicKey, combined.state.cSettings.generator)

// open the election period
val startVotes = Election.startVotes(combined)

// generate dummy votes
val plaintexts = Seq.fill(10)(scala.util.Random.nextInt(10))

// encrypt the votes with the public key of the election
val votes = Util.encryptVotes(plaintexts, combined.state.cSettings, publicKey)

// add the votes to the election
var electionGettingVotes = startVotes
votes.foreach { v =>
electionGettingVotes = Election.addVotes(electionGettingVotes, v.convertToString)
}

// stop the voting period
val stopVotes = Election.stopVotes(electionGettingVotes)

// prepare for mixing
val startMix = Election.startMixing(stopVotes)

// each mixing trustee extracts the needed information from the election
// and performs the shuffle and proofs
val shuffle1 = m1.shuffleVotes(startMix)

// the proof is verified and the shuffle is then added to the election, advancing its state
val mixOne = Election.addMix(startMix, shuffle1, m1.id)

// again for the second trustee..
val shuffle2 = m2.shuffleVotes(mixOne)
val mixTwo = Election.addMix(mixOne, shuffle2, m2.id)

// we are done mixing
val stopMix = Election.stopMixing(mixTwo)

// start the partial decryptions
// if we tried to do this before the mixing was completed, the compiler would protest
val startDecryptions = Election.startDecryptions(stopMix)

// each keymaker trustee extracts the votes from the last shuffle from the election and
// uses their private keys to do the partial decryption and create proofs
val pd1 = k1.partialDecryption(startDecryptions)
val pd2 = k2.partialDecryption(startDecryptions)

// the proofs are verified and the partial decryptions are added to the election,
val partialOne = Election.addDecryption(startDecryptions, pd1, k1.id)
val partialTwo = Election.addDecryption(partialOne, pd2, k2.id)

// the partial decryptions are combined, yielding the plaintexts
val electionDone = Election.combineDecryptions(partialTwo)

// lets check that everything went well
println(s"Plaintexts $plaintexts")
println(s"Decrypted ${electionDone.state.decrypted}")
println("ok: " + (plaintexts.sorted == electionDone.state.decrypted.map(_.toInt).sorted))
}

/**
* Same as above but with three trustees
*
* Note that everything is done the same way except the type parameter _3 and
* the number of trustee operations
*
*/
object ElectionTest3 extends App {

val k1 = new KeyMakerTrustee("keymaker one")
val k2 = new KeyMakerTrustee("keymaker two")
val k3 = new KeyMakerTrustee("keymaker three")

val m1 = new MixerTrustee("mixer one")
val m2 = new MixerTrustee("mixer two")
val m3 = new MixerTrustee("mixer three")

// privacy level 3, three trustees of each kind, 512 bits for the size of the group modulus
val start = Election.create[_3]("my election", 512)

val readyForShares = Election.startShares(start)

val oneShare = Election.addShare(readyForShares, k1.createKeyShare(readyForShares), k1.id)
val twoShares = Election.addShare(oneShare, k2.createKeyShare(readyForShares), k2.id)
val threeShares = Election.addShare(twoShares, k3.createKeyShare(readyForShares), k3.id)

val combined = Election.combineShares(threeShares)

val publicKey = Util.getPublicKeyFromString(combined.state.publicKey, combined.state.cSettings.generator)

val startVotes = Election.startVotes(combined)

val plaintexts = Seq.fill(100)(scala.util.Random.nextInt(10))

val votes = Util.encryptVotes(plaintexts, combined.state.cSettings, publicKey)

var electionGettingVotes = startVotes
votes.foreach { v =>
electionGettingVotes = Election.addVotes(electionGettingVotes, v.convertToString)
}

val stopVotes = Election.stopVotes(electionGettingVotes)

val startMix = Election.startMixing(stopVotes)

val shuffle1 = m1.shuffleVotes(startMix)
val mixOne = Election.addMix(startMix, shuffle1, m1.id)
val shuffle2 = m2.shuffleVotes(mixOne)
val mixTwo = Election.addMix(mixOne, shuffle2, m2.id)
val shuffle3 = m3.shuffleVotes(mixTwo)
val mixThree = Election.addMix(mixTwo, shuffle3, m3.id)

val stopMix = Election.stopMixing(mixThree)

val startDecryptions = Election.startDecryptions(stopMix)

val pd1 = k1.partialDecryption(startDecryptions)
val pd2 = k2.partialDecryption(startDecryptions)
val pd3 = k3.partialDecryption(startDecryptions)

val partialOne = Election.addDecryption(startDecryptions, pd1, k1.id)
val partialTwo = Election.addDecryption(partialOne, pd2, k2.id)
val partialThree = Election.addDecryption(partialTwo, pd3, k3.id)

Running it
----------

val electionDone = Election.combineDecryptions(partialThree)
git clone

println(s"Plaintexts $plaintexts")
println(s"Decrypted ${electionDone.state.decrypted}")
println("ok: " + (plaintexts.sorted == electionDone.state.decrypted.map(_.toInt).sorted))
}
rng-tools
9 changes: 7 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
scalaVersion := "2.11.7"

lazy val akkaVersion = "2.4.0"
// fork in run := true

resolvers ++= Seq(
Resolver.sonatypeRepo("releases"),
Expand All @@ -12,12 +13,16 @@ libraryDependencies ++= Seq(
"com.github.nscala-time" %% "nscala-time" % "2.6.0",
"com.chuusai" %% "shapeless" % "2.2.5",
"com.typesafe.akka" %% "akka-actor" % akkaVersion,
"com.typesafe.akka" %% "akka-testkit" % akkaVersion
"com.typesafe.akka" %% "akka-testkit" % akkaVersion,
"org.consensusresearch" %% "scrypto" % "1.0.4",
"org.apache.commons" % "commons-collections4" % "4.0"
)

assemblyMergeStrategy in assembly := {
case PathList("ch", "bfh", xs @ _*) => MergeStrategy.first
case x =>
val oldStrategy = (assemblyMergeStrategy in assembly).value
oldStrategy(x)
}
}

scalacOptions ++= Seq("-feature", "-language:existentials")
Binary file added lib/jna-4.2.1.jar
Binary file not shown.
Binary file added lib/jna-platform-4.2.1.jar
Binary file not shown.
Binary file added lib/jnagmp-1.0.2-SNAPSHOT.jar
Binary file not shown.
Binary file added lib/unicrypt-2.2-SNAPSHOT.jar
Binary file not shown.
Loading

0 comments on commit 43cb90e

Please sign in to comment.