From e2708af39eb872cf12a34b6d0fe187c17d25ce38 Mon Sep 17 00:00:00 2001 From: Hai Brenner Date: Sat, 19 Dec 2015 14:46:14 +0200 Subject: [PATCH] Committing so I can checkout to 'master' branch and pull and re-build Because build failed, and not necessarily becuase of my changes.... --- .../main/java/meerkat/voting/VotingBooth.java | 4 +- .../src/main/proto/meerkat/voting.proto | 27 ++++ .../java/meerkat/voting/EncryptionFake.java | 58 +++++++ .../voting/SharedEncryptedBallotMessage.java | 47 ++++++ .../voting/SharedPlaintextBallotMessage.java | 40 +++++ .../main/java/meerkat/voting/VBMessage.java | 12 +- .../java/meerkat/voting/VotingBoothToy.java | 144 ++++++++++++------ .../voting/VotingBoothToyConsoleUI.java | 8 +- .../meerkat/voting/VotingBoothToyDemoRun.java | 45 ++++++ 9 files changed, 334 insertions(+), 51 deletions(-) create mode 100644 voting-booth/src/main/java/meerkat/voting/EncryptionFake.java create mode 100644 voting-booth/src/main/java/meerkat/voting/SharedEncryptedBallotMessage.java create mode 100644 voting-booth/src/main/java/meerkat/voting/SharedPlaintextBallotMessage.java create mode 100644 voting-booth/src/main/java/meerkat/voting/VotingBoothToyDemoRun.java diff --git a/meerkat-common/src/main/java/meerkat/voting/VotingBooth.java b/meerkat-common/src/main/java/meerkat/voting/VotingBooth.java index 956921f..f0c5468 100644 --- a/meerkat-common/src/main/java/meerkat/voting/VotingBooth.java +++ b/meerkat-common/src/main/java/meerkat/voting/VotingBooth.java @@ -60,11 +60,11 @@ public interface VotingBooth { /** * UI calls this when the user cancels the voting process in the middle. */ - void cancelBallot(); + //void cancelBallot(); /** * Called by UI thread after voter made choice to cast or audit ballot. * @param castVote */ - void voterCastOrAudit(boolean castVote); + //void voterCastOrAudit(boolean castVote); } diff --git a/meerkat-common/src/main/proto/meerkat/voting.proto b/meerkat-common/src/main/proto/meerkat/voting.proto index beb4e0c..77d8051 100644 --- a/meerkat-common/src/main/proto/meerkat/voting.proto +++ b/meerkat-common/src/main/proto/meerkat/voting.proto @@ -52,6 +52,33 @@ message BallotAnswerTranslationTable { bytes data = 1; } + + +enum UIDataType { + TEXT = 0; + IMAGE = 1; + VOICE = 2; +} + +enum QuestionType { + MULTIPLE_CHOICE = 0; + MULTIPLE_SELECTION = 1; + ORDER = 2; +} + +message UIElement { + UIDataType type = 1; + bytes data = 2; +} + +message BllotQuestionNew { + bool is_mandatory = 1; + UIElement question = 2; + UIElement description = 3; + repeated UIElement answers = 4; +} + + message ElectionParams { // TODO: different sets of keys for different roles? repeated SignatureVerificationKey trusteeVerificationKeys = 1; diff --git a/voting-booth/src/main/java/meerkat/voting/EncryptionFake.java b/voting-booth/src/main/java/meerkat/voting/EncryptionFake.java new file mode 100644 index 0000000..291e786 --- /dev/null +++ b/voting-booth/src/main/java/meerkat/voting/EncryptionFake.java @@ -0,0 +1,58 @@ +package meerkat.voting; + +import java.io.IOException; +import java.util.Random; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; + +import meerkat.crypto.Encryption; +import meerkat.protobuf.Crypto.EncryptionPublicKey; +import meerkat.protobuf.Crypto.EncryptionRandomness; +import meerkat.protobuf.Crypto.RerandomizableEncryptedMessage; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +public class EncryptionFake implements Encryption { + + EncryptionPublicKey m_encryptionPublicKey; + Random m_rnd; + + public EncryptionFake (EncryptionPublicKey publicKey) { + m_encryptionPublicKey = publicKey; + } + + @Override + public RerandomizableEncryptedMessage encrypt(Message plaintext, EncryptionRandomness rnd) throws IOException { + // TODO Auto-generated method stub + assert plaintext != null; + assert rnd != null; + + byte plaintextBytes[] = plaintext.toByteArray(); + byte encryptedBytes[] = new byte[plaintextBytes.length + 1]; + encryptedBytes[0] = rnd.getData().byteAt(0); + for (int i = 0; i < plaintextBytes.length; ++i) { + encryptedBytes[i+1] = (byte)(plaintextBytes[i] ^ encryptedBytes[0]); + } + + return RerandomizableEncryptedMessage.newBuilder().setData(ByteString.copyFrom(encryptedBytes)).build(); + } + + @Override + public RerandomizableEncryptedMessage rerandomize(RerandomizableEncryptedMessage msg, EncryptionRandomness rnd) + throws InvalidProtocolBufferException { + // TODO Auto-generated method stub + System.err.println("rerandomize: not implemented!"); + throw new NotImplementedException(); + } + + @Override + public EncryptionRandomness generateRandomness(Random rand) { + assert rand != null; + byte a[] = new byte[1]; + a[0] = (byte)((rand.nextInt() % 255)+1); + ByteString val = ByteString.copyFrom(a); + return EncryptionRandomness.newBuilder().setData(val).build(); + } + +} diff --git a/voting-booth/src/main/java/meerkat/voting/SharedEncryptedBallotMessage.java b/voting-booth/src/main/java/meerkat/voting/SharedEncryptedBallotMessage.java new file mode 100644 index 0000000..52ab120 --- /dev/null +++ b/voting-booth/src/main/java/meerkat/voting/SharedEncryptedBallotMessage.java @@ -0,0 +1,47 @@ +package meerkat.voting; + +import meerkat.protobuf.Voting.EncryptedBallot; + +public class SharedEncryptedBallotMessage { + + private EncryptedBallot m_encryptedBallot; + private boolean b_writeable = true; + + synchronized void setSharedMessage (EncryptedBallot encryptedBallot) + { + while (!b_writeable) { + try + { + wait (); + } + catch (InterruptedException e) {} + } + + m_encryptedBallot = EncryptedBallot.newBuilder(encryptedBallot).build(); + b_writeable = false; + notifyAll (); + } + + synchronized EncryptedBallot getSharedMessage (int millisecTimeout) + { + do { + try { + wait (millisecTimeout); + } + catch (InterruptedException e) { } + } while (b_writeable && millisecTimeout == 0); + + EncryptedBallot retValue = null; + + if (m_encryptedBallot != null) + { + b_writeable = true; + notifyAll (); + retValue = EncryptedBallot.newBuilder(m_encryptedBallot).build(); + m_encryptedBallot = null; + } + + return retValue; + } + +} diff --git a/voting-booth/src/main/java/meerkat/voting/SharedPlaintextBallotMessage.java b/voting-booth/src/main/java/meerkat/voting/SharedPlaintextBallotMessage.java new file mode 100644 index 0000000..c076f1c --- /dev/null +++ b/voting-booth/src/main/java/meerkat/voting/SharedPlaintextBallotMessage.java @@ -0,0 +1,40 @@ +package meerkat.voting; + +import meerkat.protobuf.Voting.PlaintextBallot; + +public class SharedPlaintextBallotMessage { + + private PlaintextBallot m_plaintextBallot; + private boolean b_writeable = true; + + synchronized void setSharedMessage (PlaintextBallot plaintextBallot) + { + while (!b_writeable) { + try + { + wait (); + } + catch (InterruptedException e) {} + } + + m_plaintextBallot = PlaintextBallot.newBuilder(plaintextBallot).build(); + b_writeable = false; + notifyAll (); + } + + synchronized PlaintextBallot getSharedMessage () + { + while (b_writeable) { + try + { + wait (); + } + catch (InterruptedException e) { } + } + + b_writeable = true; + notifyAll (); + + return PlaintextBallot.newBuilder(m_plaintextBallot).build(); + } +} diff --git a/voting-booth/src/main/java/meerkat/voting/VBMessage.java b/voting-booth/src/main/java/meerkat/voting/VBMessage.java index 1aa6e00..bc5e8b4 100644 --- a/voting-booth/src/main/java/meerkat/voting/VBMessage.java +++ b/voting-booth/src/main/java/meerkat/voting/VBMessage.java @@ -24,6 +24,10 @@ public class VBMessage { return retVal; } + public VBMessageType getType () { + return m_type; + } + public static VBMessage newEncryptionQuery (PlaintextBallot plaintextBallot) { VBMessage retVal = new VBMessage(); retVal.m_type = VBMessageType.VB_ENCRYPTION_QUERY; @@ -40,21 +44,21 @@ public class VBMessage { } public EncryptedBallot getEncryptedBallot () { - assert m_type == VBMessageType.VB_CONTROLLER_RESPONSE; + assert getType() == VBMessageType.VB_CONTROLLER_RESPONSE; return m_encryptedBallot; } public BallotSecrets getSecrets () { - assert m_type == VBMessageType.VB_CONTROLLER_RESPONSE; + assert getType() == VBMessageType.VB_CONTROLLER_RESPONSE; return m_secrets; } public PlaintextBallot getPlaintextBallot () { - assert m_type == VBMessageType.VB_ENCRYPTION_QUERY; + assert getType() == VBMessageType.VB_ENCRYPTION_QUERY; return m_plaintextBallot; } public boolean isEmptyMessage () { - return (m_type == VBMessageType.VB_TICK); + return (getType() == VBMessageType.VB_TICK); } } diff --git a/voting-booth/src/main/java/meerkat/voting/VotingBoothToy.java b/voting-booth/src/main/java/meerkat/voting/VotingBoothToy.java index 5dec24c..396ebc0 100644 --- a/voting-booth/src/main/java/meerkat/voting/VotingBoothToy.java +++ b/voting-booth/src/main/java/meerkat/voting/VotingBoothToy.java @@ -1,18 +1,17 @@ package meerkat.voting; -import meerkat.protobuf.Voting.BallotAnswer; -import meerkat.protobuf.Voting.BallotAnswerTranslationTable; -import meerkat.protobuf.Voting.BallotQuestion; -import meerkat.protobuf.Voting.BallotSecrets; -import meerkat.protobuf.Voting.BoothParams; -import meerkat.protobuf.Voting.ElectionParams; -import meerkat.protobuf.Voting.PlaintextBallot; -import meerkat.protobuf.Crypto.EncryptionPublicKey; +import meerkat.protobuf.Voting.*; +import meerkat.crypto.Encryption; +import meerkat.protobuf.Crypto.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.List; +import java.util.Random; +import java.util.concurrent.ArrayBlockingQueue; + +import com.google.protobuf.ByteString; @@ -25,32 +24,24 @@ public class VotingBoothToy implements VotingBooth, Runnable { private BallotAnswer a_answers[]; private BallotAnswerTranslationTable m_answerTranslationTable; - private BoothParams m_boothParams; + private ArrayBlockingQueue a_queue; + static private int m_queueSize = 5; + private VotingBooth.UI m_ui; + //TODO: where do I use these? + SignatureVerificationKey a_signatureKeys[]; + + Encryption m_encryption; + Random m_random; + - public static void main (String[] args) - { - VotingBoothToy vbController = new VotingBoothToy (); - VotingBoothToyConsoleUI ui = new VotingBoothToyConsoleUI(); - - vbController.registerUI (ui); - ui.registerVBController(vbController); - - BoothParams boothParams = new BoothParams(); - ElectionParams electionParams = new ElectionParams(); - - vbController.init(electionParams, boothParams); - - Thread controllerThread = new Thread(new VotingBoothToy ()); - Thread uiThread = new Thread(ui); - - controllerThread.start(); - uiThread.start(); - - } public VotingBoothToy () { + a_queue = new ArrayBlockingQueue (m_queueSize, true); + + m_encryption = new EncryptionFake(m_ballotEncryptionKey); + m_random = new Random(); } public void registerUI (UI ui) { @@ -58,9 +49,66 @@ public class VotingBoothToy implements VotingBooth, Runnable { } public void run () { + System.err.println("VB controller is up and running"); + while (true) { + VBMessage msg; + try { + msg = a_queue.take(); + } + catch (InterruptedException e) { + System.err.println("VB controller interrupted!!"); + break; + } + if (msg.getType() == VBMessage.VBMessageType.VB_ENCRYPTION_QUERY) { + handleEncryptionQuery (msg); + } + else { + System.err.println("VB controller unknown type of message!!"); + break; + } + } } + + private void handleEncryptionQuery (VBMessage msg) { + assert msg.getType() == VBMessage.VBMessageType.VB_ENCRYPTION_QUERY; + PlaintextBallot ptb = msg.getPlaintextBallot(); + + // encrypt + RerandomizableEncryptedMessage encMsg; + EncryptionRandomness rnd = m_encryption.generateRandomness(m_random); + try { + // simulate taking a lot of time + Thread.sleep(30000); + encMsg = m_encryption.encrypt(ptb, rnd); + } + catch (InterruptedException e) { + System.err.println("debug: VotingBoothToy encrypt interrupted!"); + return; + } + catch (IOException e) { + System.err.println("debug: VotingBoothToy encrypt IOException!"); + return; + } + + EncryptedBallot encBallot = EncryptedBallot.newBuilder() + .setSerialNumber(ptb.getSerialNumber()) + .setData(encMsg) + .build(); + RandomnessGenerationProof proof = RandomnessGenerationProof.newBuilder() + .setData(ByteString.copyFrom(new byte[0])) + .build(); + BallotSecrets secrets = BallotSecrets.newBuilder() + .setPlaintextBallot(ptb) + .setEncryptionRandomness(rnd) + .setProof(proof) + .build(); + + m_ui.commitToEncryptedBallot(encBallot, secrets); + } + + /* (non-Javadoc) * @see meerkat.voting.VotingBooth#init(meerkat.protobuf.Voting.ElectionParams, meerkat.protobuf.Voting.BoothParams) */ @@ -72,7 +120,13 @@ public class VotingBoothToy implements VotingBooth, Runnable { this.m_answerTranslationTable = globalParams.getAnswerTranslationTable(); - this.m_boothParams = boothParams; + List l_signatureKeys = boothParams.getPscVerificationKeysList(); + a_signatureKeys = new SignatureVerificationKey[l_signatureKeys.size()]; + int i = 0; + for (SignatureVerificationKey q: l_signatureKeys) { + a_signatureKeys[i] = q; + ++i; + } } @@ -85,28 +139,32 @@ public class VotingBoothToy implements VotingBooth, Runnable { */ @Override public void submitBallot(PlaintextBallot ballot) { - System.err.println ("debug VB: submit ballot."); - // encryptBallot (PlaintextBallot) - + VBMessage msg = VBMessage.newEncryptionQuery(ballot); + try { + a_queue.put(msg); + } + catch (InterruptedException e) { + System.err.println("SubmitBallot interrupted!!"); + } } /* (non-Javadoc) * @see meerkat.voting.VotingBooth#cancelBallot() */ - @Override + /*@Override public void cancelBallot() { // TODO Auto-generated method stub - } + }*/ /* (non-Javadoc) * @see meerkat.voting.VotingBooth#voterCastOrAudit(boolean) */ - @Override + /*@Override public void voterCastOrAudit(boolean castVote) { // TODO Auto-generated method stub - } + }*/ } @@ -129,17 +187,17 @@ message BallotAnswer { repeated sint64 answer = 1 [packed=true]; } -message PlaintextBallot { - uint64 serialNumber = 1; // Ballot serial number +message EncryptedBallot { + uint64 serialNumber = 1; // Ballot serial number - repeated BallotAnswer answers = 2; + RerandomizableEncryptedMessage data = 2; } message BallotSecrets { - PlaintextBallot plaintext_ballot = 1; + PlaintextBallot plaintext_ballot = 1; - EncryptionRandomness encryption_randomness = 2; - RandomnessGenerationProof proof = 3; + EncryptionRandomness encryption_randomness = 2; + RandomnessGenerationProof proof = 3; } message BoothParams { diff --git a/voting-booth/src/main/java/meerkat/voting/VotingBoothToyConsoleUI.java b/voting-booth/src/main/java/meerkat/voting/VotingBoothToyConsoleUI.java index 8e80158..4c87bfa 100644 --- a/voting-booth/src/main/java/meerkat/voting/VotingBoothToyConsoleUI.java +++ b/voting-booth/src/main/java/meerkat/voting/VotingBoothToyConsoleUI.java @@ -31,12 +31,14 @@ public class VotingBoothToyConsoleUI implements UI, Runnable { private ArrayBlockingQueue a_queue; static private int m_queueSize = 5; private BallotQuestion a_questions[]; + private BallotQuestionNew a_questionsNew[]; private int m_serialNumber; private PlaintextBallot m_plaintextBallot; private EncryptedBallot m_encryptedBallot; private BallotSecrets m_ballotSecrets; private int m_waitForControllerMillisecTimeout = 10; - + private BallotAnswerTranslationTable m_answerTranslationTable; + public VotingBoothToyConsoleUI () { a_queue = new ArrayBlockingQueue (m_queueSize, true); @@ -44,6 +46,9 @@ public class VotingBoothToyConsoleUI implements UI, Runnable { public VotingBoothToyConsoleUI(ElectionParams globalParams) { m_serialNumber = 0; + + this.m_answerTranslationTable = globalParams.getAnswerTranslationTable(); + List l_questions = globalParams.getQuestionsList(); a_questions = new BallotQuestion[l_questions.size()]; m_in = new BufferedReader(new InputStreamReader(System.in)); @@ -65,7 +70,6 @@ public class VotingBoothToyConsoleUI implements UI, Runnable { System.err.println ("UI debug: preparing console UI for a new user."); // clear history from memory - // TODO: should we clean memory better? eraseEncryption(); erasePlaintext(); diff --git a/voting-booth/src/main/java/meerkat/voting/VotingBoothToyDemoRun.java b/voting-booth/src/main/java/meerkat/voting/VotingBoothToyDemoRun.java new file mode 100644 index 0000000..6e023bd --- /dev/null +++ b/voting-booth/src/main/java/meerkat/voting/VotingBoothToyDemoRun.java @@ -0,0 +1,45 @@ +package meerkat.voting; + +import com.google.protobuf.ByteString; + +import meerkat.protobuf.Crypto.SignatureType; +import meerkat.protobuf.Crypto.SignatureVerificationKey; +import meerkat.protobuf.Voting.BoothParams; +import meerkat.protobuf.Voting.ElectionParams; + +public class VotingBoothToyDemoRun { + + static int N_SIGNATURE_VERIFICATION_KEYS = 3; + + public static void main (String[] args) + { + VotingBoothToy vbController = new VotingBoothToy (); + VotingBoothToyConsoleUI ui = new VotingBoothToyConsoleUI(); + + vbController.registerUI (ui); + ui.registerVBController(vbController); + + BoothParams.Builder bpb = BoothParams.newBuilder(); + SignatureType signatureType = SignatureType.ECDSA; + for (int i = 0; i < N_SIGNATURE_VERIFICATION_KEYS; ++i) { + SignatureVerificationKey verifiationKey = SignatureVerificationKey.newBuilder() + .setType(signatureType) + .setData(ByteString.copyFrom(new byte[0])) + .build(); + bpb.addPscVerificationKeys(i, verifiationKey); + } + BoothParams boothParams = bpb.build(); + + ElectionParams electionParams = new ElectionParams(); + + vbController.init(electionParams, boothParams); + + Thread controllerThread = new Thread(new VotingBoothToy ()); + Thread uiThread = new Thread(ui); + + controllerThread.start(); + uiThread.start(); + + } + +}