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

Commit

Permalink
Fixed timings script
Browse files Browse the repository at this point in the history
  • Loading branch information
ruescasd committed Mar 14, 2016
1 parent 7af1035 commit 9d940aa
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 128 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ pdfs/
.project
.cache-main
.classpath
.settings/
.settings/
/bin/
66 changes: 32 additions & 34 deletions src/main/scala/Demo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ object ElectionTestSerial extends App {
val m1 = new MixerTrustee("mixer one")
val m2 = new MixerTrustee("mixer two")

// create the election,
// 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)
Expand Down Expand Up @@ -359,7 +359,7 @@ object ElectionTestSerial extends App {

// we are only timing the mixing phase
val mixingStart = System.currentTimeMillis()
MPBridge.total = 0;
MPBridge.total = 0;
// wait for keystroke, this allows us to attach a profiler at the right time
// println("Hit return to start")
// Console.in.read()
Expand Down Expand Up @@ -531,38 +531,36 @@ object GeneratorTest extends App {

object Issue4 extends App with ProofSettings {
import ch.bfh.unicrypt.crypto.keygenerator.interfaces.KeyPairGenerator
import ch.bfh.unicrypt.crypto.proofsystem.challengegenerator.classes.FiatShamirSigmaChallengeGenerator
import ch.bfh.unicrypt.crypto.proofsystem.challengegenerator.interfaces.ChallengeGenerator
import ch.bfh.unicrypt.crypto.proofsystem.challengegenerator.interfaces.SigmaChallengeGenerator
import ch.bfh.unicrypt.crypto.proofsystem.classes.EqualityPreimageProofSystem
import ch.bfh.unicrypt.crypto.proofsystem.classes.PermutationCommitmentProofSystem
import ch.bfh.unicrypt.crypto.proofsystem.classes.PlainPreimageProofSystem
import ch.bfh.unicrypt.crypto.proofsystem.classes.ReEncryptionShuffleProofSystem
import ch.bfh.unicrypt.crypto.schemes.commitment.classes.PermutationCommitmentScheme
import ch.bfh.unicrypt.crypto.schemes.encryption.classes.ElGamalEncryptionScheme
import ch.bfh.unicrypt.helper.converter.classes.ConvertMethod
import ch.bfh.unicrypt.helper.converter.classes.biginteger.ByteArrayToBigInteger
import ch.bfh.unicrypt.helper.converter.classes.bytearray.BigIntegerToByteArray
import ch.bfh.unicrypt.helper.converter.classes.bytearray.StringToByteArray
import ch.bfh.unicrypt.helper.hash.HashAlgorithm
import ch.bfh.unicrypt.helper.hash.HashMethod
import ch.bfh.unicrypt.helper.math.Alphabet
import ch.bfh.unicrypt.math.algebra.concatenative.classes.StringElement
import ch.bfh.unicrypt.math.algebra.concatenative.classes.StringMonoid
import ch.bfh.unicrypt.math.algebra.general.classes.Pair
import ch.bfh.unicrypt.math.algebra.general.classes.Triple
import ch.bfh.unicrypt.math.algebra.general.classes.Tuple
import ch.bfh.unicrypt.math.algebra.general.interfaces.Element
import ch.bfh.unicrypt.math.function.classes.CompositeFunction
import ch.bfh.unicrypt.math.function.classes.GeneratorFunction
import ch.bfh.unicrypt.math.function.classes.InvertFunction
import ch.bfh.unicrypt.math.function.classes.MultiIdentityFunction
import ch.bfh.unicrypt.math.function.classes.ProductFunction
import ch.bfh.unicrypt.math.function.interfaces.Function
import mpservice.MPBridgeS
import mpservice.MPBridge


import ch.bfh.unicrypt.crypto.proofsystem.challengegenerator.classes.FiatShamirSigmaChallengeGenerator
import ch.bfh.unicrypt.crypto.proofsystem.challengegenerator.interfaces.ChallengeGenerator
import ch.bfh.unicrypt.crypto.proofsystem.challengegenerator.interfaces.SigmaChallengeGenerator
import ch.bfh.unicrypt.crypto.proofsystem.classes.EqualityPreimageProofSystem
import ch.bfh.unicrypt.crypto.proofsystem.classes.PermutationCommitmentProofSystem
import ch.bfh.unicrypt.crypto.proofsystem.classes.PlainPreimageProofSystem
import ch.bfh.unicrypt.crypto.proofsystem.classes.ReEncryptionShuffleProofSystem
import ch.bfh.unicrypt.crypto.schemes.commitment.classes.PermutationCommitmentScheme
import ch.bfh.unicrypt.crypto.schemes.encryption.classes.ElGamalEncryptionScheme
import ch.bfh.unicrypt.helper.converter.classes.ConvertMethod
import ch.bfh.unicrypt.helper.converter.classes.biginteger.ByteArrayToBigInteger
import ch.bfh.unicrypt.helper.converter.classes.bytearray.BigIntegerToByteArray
import ch.bfh.unicrypt.helper.converter.classes.bytearray.StringToByteArray
import ch.bfh.unicrypt.helper.hash.HashAlgorithm
import ch.bfh.unicrypt.helper.hash.HashMethod
import ch.bfh.unicrypt.helper.math.Alphabet
import ch.bfh.unicrypt.math.algebra.concatenative.classes.StringElement
import ch.bfh.unicrypt.math.algebra.concatenative.classes.StringMonoid
import ch.bfh.unicrypt.math.algebra.general.classes.Pair
import ch.bfh.unicrypt.math.algebra.general.classes.Triple
import ch.bfh.unicrypt.math.algebra.general.classes.Tuple
import ch.bfh.unicrypt.math.algebra.general.interfaces.Element
import ch.bfh.unicrypt.math.function.classes.CompositeFunction
import ch.bfh.unicrypt.math.function.classes.GeneratorFunction
import ch.bfh.unicrypt.math.function.classes.InvertFunction
import ch.bfh.unicrypt.math.function.classes.MultiIdentityFunction
import ch.bfh.unicrypt.math.function.classes.ProductFunction
import ch.bfh.unicrypt.math.function.interfaces.Function
import mpservice.MPBridgeS
import mpservice.MPBridge

val group = GStarModSafePrime.getFirstInstance(2048)
val generator = group.getDefaultGenerator()
Expand Down
191 changes: 105 additions & 86 deletions src/main/scala/mpservice/MPService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,32 @@ import scala.util.Try
import scala.util.Success
import com.squareup.jnagmp.Gmp

// public api
/******************** PUBLIC API ********************/

/**
* Represents a modular exponentiation operation
*/
case class ModPow(base: BigInteger, pow: BigInteger, mod: BigInteger)

/**
* Represents a modular exponentiation operation with common modulus (see below)
*/
case class ModPow2(base: BigInteger, pow: BigInteger)

/**
* The mpservice public api
*/
trait ModPowService {
// compute modular exponentiation for a list of inputs
def compute(work: Array[ModPow]): Array[BigInteger]
// compute modular exponentiation for a list of inputs with common modulus
def compute(work: Array[ModPow2], mod: BigInteger): Array[BigInteger]
}

// implementation
case class Work(requestId: Int, workId: Int, work: Array[ModPow])
case class Work2(requestId: Int, workId: Int, work: Array[ModPow2], mod: BigInteger)
case class WorkReply(requestId: Int, workId: Int, result: Array[BigInteger])
case class ModPowArray(modpows: Array[ModPow])
case class ModPowArray2(modpows: Array[ModPow2], mod: BigInteger)
case class ModPowArrayResult(result: Array[BigInteger])
case class RequestData(client: ActorRef, length: Int, results: mutable.ArrayBuffer[WorkReply], sent: Long = System.currentTimeMillis)
/******************** IMPLEMENTATION ********************/

object MPService extends ModPowService {
// FIXME should be configurable
val service = AkkaModPowService

def compute(work: Array[ModPow]): Array[BigInteger] = service.compute(work)
Expand All @@ -38,6 +46,81 @@ object MPService extends ModPowService {
override def toString = service.getClass.toString
}

object MPBridgeS {
// FIXME move to Util
val generatorParallelism = ConfigFactory.load().getInt("generators-parallelism-level")

def ex[T](f: => T, v: String) = {
MPBridge.a()
MPBridge.startRecord(v)
val now = System.currentTimeMillis
var ret = f
val r = System.currentTimeMillis - now
println(s"R: [$r ms]")
val requests = MPBridge.stopRecord()
MPBridge.b(3)
if(requests.length > 0) {
val now2 = System.currentTimeMillis
val answers = MPService.compute(requests, MPBridge.getModulus);
val c = System.currentTimeMillis - now2
MPBridge.startReplay(answers)
ret = f
val t = System.currentTimeMillis - now
println(s"\nC: [$c ms] T: [$t ms] R+C: [${r+c} ms]")
MPBridge.stopReplay()
}
MPBridge.reset()

ret
}

def init(useGmp: Boolean, useExtractor: Boolean) = MPBridge.init(useGmp, useExtractor)
def shutdown = MPBridge.shutdown

import ch.bfh.unicrypt.math.algebra.general.abstracts.AbstractCyclicGroup
import ch.bfh.unicrypt.helper.random.deterministic.DeterministicRandomByteSequence
import ch.bfh.unicrypt.helper.random.deterministic.CTR_DRBG
import scala.collection.JavaConversions._
import ch.bfh.unicrypt.helper.converter.classes.biginteger.ByteArrayToBigInteger
import ch.bfh.unicrypt.helper.math.MathUtil
import ch.bfh.unicrypt.helper.array.classes.DenseArray
import ch.bfh.unicrypt.helper.sequence.Sequence
import ch.bfh.unicrypt.math.algebra.general.interfaces.Element
import scala.collection.JavaConversions._

// FIXME move to Util
def getIndependentGenerators[E <: Element[_]](group: AbstractCyclicGroup[E, _], skip: Int, size: Int): java.util.List[E] = {

val split = generatorParallelism
val total = size + skip

val a = Array.fill(total % split)((total / split) + 1)
val b = Array.fill(split - (total % split))(total / split)
val c = a ++ b

val seedLength = CTR_DRBG.getFactory().getSeedByteLength()
val converter = ByteArrayToBigInteger.getInstance(seedLength)

val rds = c.zipWithIndex.map{ case (value, index) =>
// 10000: we want to leave ample room for generators not to overlap
val seed = java.math.BigInteger.valueOf(index * (total / split) * 10000).mod(MathUtil.powerOfTwo(CTR_DRBG.getFactory().getSeedByteLength()))
// println("*** index " + index + " seed " + seed + " value " + value)
val r = DeterministicRandomByteSequence.getInstance(CTR_DRBG.getFactory(), converter.reconvert(seed))
(r, value)
}
// rds.foreach(println)

val items = rds.par.flatMap { case (d, i) =>
val sequence = group.getIndependentGenerators(d).limit(i)
sequence.toList
}
println("getIndependentGenerators " + total + " " + items.size)

// DenseArray.getInstance(items.drop(skip).toList.toArray)
items.drop(skip).toList
}
}

object SequentialModPowService extends ModPowService {
def compute(work: Array[ModPow]): Array[BigInteger] = work.map(x => x.base.modPow(x.pow, x.mod))
def compute(work: Array[ModPow2], mod: BigInteger): Array[BigInteger] = work.map(x => x.base.modPow(x.pow, mod))
Expand All @@ -55,6 +138,16 @@ object ParallelModPowService extends ModPowService {
def compute(work: Array[ModPow2], mod: BigInteger): Array[BigInteger] = work.par.map(x => x.base.modPow(x.pow, mod)).seq.toArray
}

/******************** AKKA ********************/

// messaging classes
case class Work(requestId: Int, workId: Int, work: Array[ModPow])
case class Work2(requestId: Int, workId: Int, work: Array[ModPow2], mod: BigInteger)
case class WorkReply(requestId: Int, workId: Int, result: Array[BigInteger])
case class ModPowArray(modpows: Array[ModPow])
case class ModPowArray2(modpows: Array[ModPow2], mod: BigInteger)
case class ModPowArrayResult(result: Array[BigInteger])

class AkkaModPowService(system: ActorSystem, modPowService: ActorRef) extends ModPowService {

def compute(work: Array[ModPow]): Array[BigInteger] = {
Expand Down Expand Up @@ -98,6 +191,7 @@ object AkkaModPowService extends ModPowService {
}

class ModPowServiceActor(val minChunks: Int, val maxChunkSize: Int, val sendDelay: Int, val useGmp: Boolean) extends Actor with ActorLogging {
case class RequestData(client: ActorRef, length: Int, results: mutable.ArrayBuffer[WorkReply], sent: Long = System.currentTimeMillis)

val workerRouter = context.actorOf(WorkerActor.props(useGmp).withRouter(FromConfig()), name = "workerRouter")

Expand Down Expand Up @@ -193,6 +287,8 @@ object ModPowServiceActor {
def props(minChunks: Int, maxChunkSize: Int, sendDelay: Int, useGmp: Boolean): Props = Props(new ModPowServiceActor(minChunks, maxChunkSize, sendDelay, useGmp))
}

/******************** LAUNCHER ********************/

object WorkerApp {

def main(args: Array[String]): Unit = {
Expand Down Expand Up @@ -247,81 +343,4 @@ object TestApp {
def rndBigInt = {
BigInt(1024, new scala.util.Random)
}
}

import ch.bfh.unicrypt.helper.sequence.Sequence
import ch.bfh.unicrypt.math.algebra.general.interfaces.Element
import scala.collection.JavaConversions._
import scala.collection.JavaConverters._

object MPBridgeS {
// move to Util
val generatorParallelism = ConfigFactory.load().getInt("generators-parallelism-level")

def ex[T](f: => T, v: String) = {
MPBridge.a()
MPBridge.startRecord(v)
val now = System.currentTimeMillis
var ret = f
val r = System.currentTimeMillis - now
println(s"R: [$r ms]")
val requests = MPBridge.stopRecord()
MPBridge.b(3)
if(requests.length > 0) {
val now2 = System.currentTimeMillis
val answers = MPService.compute(requests, MPBridge.getModulus);
val c = System.currentTimeMillis - now2
MPBridge.startReplay(answers)
ret = f
val t = System.currentTimeMillis - now
println(s"\nC: [$c ms] T: [$t ms] R+C: [${r+c} ms]")
MPBridge.stopReplay()
}
MPBridge.reset()

ret
}

def init(useGmp: Boolean, useExtractor: Boolean) = MPBridge.init(useGmp, useExtractor)
def shutdown = MPBridge.shutdown

import ch.bfh.unicrypt.math.algebra.general.abstracts.AbstractCyclicGroup
import ch.bfh.unicrypt.helper.random.deterministic.DeterministicRandomByteSequence
import ch.bfh.unicrypt.helper.random.deterministic.CTR_DRBG
import scala.collection.JavaConversions._
import ch.bfh.unicrypt.helper.converter.classes.biginteger.ByteArrayToBigInteger
import ch.bfh.unicrypt.helper.math.MathUtil
import ch.bfh.unicrypt.helper.array.classes.DenseArray

// FIXME move to Util
def getIndependentGenerators[E <: Element[_]](group: AbstractCyclicGroup[E, _], skip: Int, size: Int): java.util.List[E] = {

val split = generatorParallelism
val total = size + skip

val a = Array.fill(total % split)((total / split) + 1)
val b = Array.fill(split - (total % split))(total / split)
val c = a ++ b

val seedLength = CTR_DRBG.getFactory().getSeedByteLength()
val converter = ByteArrayToBigInteger.getInstance(seedLength)

val rds = c.zipWithIndex.map{ case (value, index) =>
// 10000: we want to leave ample room for generators not to overlap
val seed = java.math.BigInteger.valueOf(index * (total / split) * 10000).mod(MathUtil.powerOfTwo(CTR_DRBG.getFactory().getSeedByteLength()))
// println("*** index " + index + " seed " + seed + " value " + value)
val r = DeterministicRandomByteSequence.getInstance(CTR_DRBG.getFactory(), converter.reconvert(seed))
(r, value)
}
// rds.foreach(println)

val items = rds.par.flatMap { case (d, i) =>
val sequence = group.getIndependentGenerators(d).limit(i)
sequence.toList
}
println("getIndependentGenerators " + total + " " + items.size)

// DenseArray.getInstance(items.drop(skip).toList.toArray)
items.drop(skip).toList
}
}
29 changes: 22 additions & 7 deletions timings/run.sh
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
#!/bin/bash

# you must have run the assembly command from sbt for this to work
CLASSPATH=../target/scala-2.11/sandbox-assembly-0.1-SNAPSHOT.jar
# RUNS="10 20 50 100 200 400"
RUNS="100 200 400 800 2000 5000"

# leave this if you dont want to test clustering
CLUSTER_SEED=localhost:2555

# the first options to test
OPTIONS_ONE="-Dmpservice.use-gmp=true -Dmpservice.use-extractor=true -Dbypass-membership-check=true -Duse-generators-parallel=true -Dakka.cluster.seed-nodes.0=akka.tcp://ClusterSystem@$CLUSTER_SEED"

# the second options to test
OPTIONS_TWO="-Dmpservice.use-gmp=false -Dmpservice.use-extractor=true -Dbypass-membership-check=true -Duse-generators-parallel=true -Dakka.cluster.seed-nodes.0=akka.tcp://ClusterSystem@$CLUSTER_SEED"

# space sperated list of vote counts to run
RUNS="100 200"

# note that previous runs are not deleted, this allows incrementally adding data to the file
# but you must manually delete it if you want to overwrite
cp ./times.dat ./times.dat.bak 2>/dev/null || :

# run it
for votes in $RUNS
do
echo running votes = $votes
# time=`java -classpath $CLASSPATH ElectionTest $votes | grep -Po '(?<=mixTime: )[^\] ]*'`
time_gmp=`java -classpath $CLASSPATH ElectionTest $votes gmp | grep -Po '(?<=mixTime: )[^\] ]*'`
echo $votes $time_gmp
echo $votes $time_gmp >> times.dat
done
time1=`java $OPTIONS_ONE -classpath $CLASSPATH ElectionTest $votes | grep -Po '(?<=mixTime: )[^\] ]*'`
time2=`java $OPTIONS_TWO -classpath $CLASSPATH ElectionTest $votes | grep -Po '(?<=mixTime: )[^\] ]*'`
echo $votes $time1 $time2
echo $votes $time1 $time2 >> times.dat
done

0 comments on commit 9d940aa

Please sign in to comment.