Just a small test for my git-gui.

Files pushed to 'vbdev' branch.
The files cannot run yet. They still need quite a lot of work.
vbdev
Hai Brenner 2015-11-25 20:55:27 +02:00
parent cbe3b5c765
commit 6e64c57431
3 changed files with 518 additions and 0 deletions

View File

@ -0,0 +1,52 @@
package meerkat.voting;
import meerkat.protobuf.Voting.EncryptedBallot;
import meerkat.protobuf.Voting.PlaintextBallot;
public class VBMessage {
public enum VBMessageType
{
VB_TICK,
VB_CONTROLLER_RESPONSE,
VB_ENCRYPTION_QUERY
}
private VBMessageType m_type;
private EncryptedBallot m_encryptedBallot;
private PlaintextBallot m_plaintextBallot;
public static VBMessage newTick () {
VBMessage retVal = new VBMessage();
retVal.m_type = VBMessageType.VB_TICK;
return retVal;
}
public static VBMessage newEncryptionQuery (PlaintextBallot plaintextBallot) {
VBMessage retVal = new VBMessage();
retVal.m_type = VBMessageType.VB_ENCRYPTION_QUERY;
retVal.m_plaintextBallot = plaintextBallot;
return retVal;
}
public static VBMessage newControllerResponse (EncryptedBallot encryptedBallot) {
VBMessage retVal = new VBMessage();
retVal.m_type = VBMessageType.VB_CONTROLLER_RESPONSE;
retVal.m_encryptedBallot = encryptedBallot;
return retVal;
}
public EncryptedBallot getEncryptedBallot () {
assert m_type == VBMessageType.VB_CONTROLLER_RESPONSE;
return m_encryptedBallot;
}
public PlaintextBallot getPlaintextBallot () {
assert m_type == VBMessageType.VB_ENCRYPTION_QUERY;
return m_plaintextBallot;
}
public boolean isEmptyMessage () {
return (m_type == VBMessageType.VB_TICK);
}
}

View File

@ -0,0 +1,161 @@
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 java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
public class VotingBoothToy implements VotingBooth, Runnable {
//private ElectionParams m_electionParams;
private EncryptionPublicKey m_ballotEncryptionKey;
private List<BallotQuestion> l_questions;
private BallotQuestion a_questions[];
private BallotAnswer a_answers[];
private BallotAnswerTranslationTable m_answerTranslationTable;
private BoothParams m_boothParams;
private VotingBooth.UI m_ui;
public VotingBoothToy () {
}
public void registerUI (UI ui) {
m_ui = ui;
}
public void run () {
}
/* (non-Javadoc)
* @see meerkat.voting.VotingBooth#init(meerkat.protobuf.Voting.ElectionParams, meerkat.protobuf.Voting.BoothParams)
*/
@Override
public void init(ElectionParams globalParams, BoothParams boothParams) {
System.err.println ("debug VB: init.");
//this.m_electionParams = globalParams;
this.m_ballotEncryptionKey = globalParams.getBallotEncryptionKey();
this.l_questions = globalParams.getQuestionsList();
this.m_answerTranslationTable = globalParams.getAnswerTranslationTable();
this.m_boothParams = boothParams;
}
public void registerVBUI (VotingBooth.UI ui)
{
m_ui = ui;
}
/* (non-Javadoc)
* @see meerkat.voting.VotingBooth#submitBallot(meerkat.protobuf.Voting.PlaintextBallot)
*/
@Override
public void submitBallot(PlaintextBallot ballot) {
System.err.println ("debug VB: submit ballot.");
// encryptBallot (PlaintextBallot)
}
/* (non-Javadoc)
* @see meerkat.voting.VotingBooth#cancelBallot()
*/
@Override
public void cancelBallot() {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see meerkat.voting.VotingBooth#voterCastOrAudit(boolean)
*/
@Override
public void voterCastOrAudit(boolean castVote) {
// TODO Auto-generated method stub
}
}
/*
//A ballot question. This is an opaque
//data type that is parsed by the UI to display
//the question.
message BallotQuestion {
bytes data = 1;
}
//An answer to a specific ballot question.
//The answer is a vector of signed integers,
//to encompass voting schemes such as ranked voting
//and STV.
message BallotAnswer {
repeated sint64 answer = 1 [packed=true];
}
message PlaintextBallot {
uint64 serialNumber = 1; // Ballot serial number
repeated BallotAnswer answers = 2;
}
message BallotSecrets {
PlaintextBallot plaintext_ballot = 1;
EncryptionRandomness encryption_randomness = 2;
RandomnessGenerationProof proof = 3;
}
message BoothParams {
repeated SignatureVerificationKey pscVerificationKeys = 1;
}
//A table to translate to and from compactly encoded answers
//and their human-understandable counterparts.
//This should be parsable by the UI
message BallotAnswerTranslationTable {
bytes data = 1;
}
message ElectionParams {
// TODO: different sets of keys for different roles?
//repeated SignatureVerificationKey trusteeVerificationKeys = 1;
// How many trustees must participate in a signature for it to be considered valid.
//uint32 trusteeSignatureThreshold = 2;
// The key used to encrypt ballots. The corresponding private key
// is shared between the trustees.
EncryptionPublicKey ballotEncryptionKey = 3;
// Verification keys for valid mixers.
//repeated SignatureVerificationKey mixerVerificationKeys = 4;
// How many mixers must participate for the mixing to be considered valid
//uint32 mixerThreshold = 5;
// Candidate list (or other question format)
repeated BallotQuestion questions = 6;
// Translation table between answers and plaintext encoding
BallotAnswerTranslationTable answerTranslationTable = 7;
}
*/

View File

@ -0,0 +1,305 @@
/**
*
*/
package meerkat.voting;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ArrayBlockingQueue;
import com.google.protobuf.ByteString;
import meerkat.protobuf.Voting.*;
import meerkat.voting.VotingBooth.UI;
/**
* @author hai
*
*/
public class VotingBoothToyConsoleUI implements UI, Runnable {
private BufferedReader m_in;
private VotingBooth m_vbController;
//private SharedPlaintextBallotMessage m_sharedPlaintext;
//private SharedEncryptedBallotMessage m_sharedEncrypted;
private ArrayBlockingQueue<VBMessage> a_queue;
static private int m_queueSize = 5;
private BallotQuestion a_questions[];
private int m_serialNumber;
private PlaintextBallot m_plaintextBallot;
private EncryptedBallot m_encryptedBallot;
private int m_waitForControllerMillisecTimeout = 10;
public VotingBoothToyConsoleUI () {
a_queue = new ArrayBlockingQueue<VBMessage> (m_queueSize, true);
}
public VotingBoothToyConsoleUI(ElectionParams globalParams) {
m_serialNumber = 0;
List<BallotQuestion> l_questions = globalParams.getQuestionsList();
a_questions = new BallotQuestion[l_questions.size()];
m_in = new BufferedReader(new InputStreamReader(System.in));
int i = 0;
for (BallotQuestion q: l_questions) {
a_questions[i] = q;
++i;
}
}
/* (non-Javadoc)
* @see meerkat.voting.VotingBooth.UI#votingBegin()
*/
@Override
public void votingBegin() {
System.err.println ("UI debug: preparing console UI for a new user.");
System.out.println ("UI screen: Welcome. Press to start");
readInputLine();
++ m_serialNumber;
boolean votingOccured = listQuestionsToUserAndGetAnswers ();
if (! votingOccured)
{
// cancel vote;
return;
}
else {
sendBallotToControllerForEncryptionAndWaitForResponse ();
}
}
/* (non-Javadoc)
* @see meerkat.voting.VotingBooth.UI#commitToEncryptedBallot(meerkat.voting.EncryptedBallot)
*/
@Override
public void commitToEncryptedBallot(EncryptedBallot encryptedBallot) {
try {
a_queue.put (VBMessage.newControllerResponse(encryptedBallot));
}
catch (InterruptedException e) {
System.err.println ("Interrupted in VotingBoothToyConsoleUI.commitToEncryptedBallot");
}
}
/* (non-Javadoc)
* @see meerkat.voting.VotingBooth.UI#castVote()
*/
@Override
public void castVote() {
System.err.println ("UI debug: voter decided to cast vote.");
System.out.println ("UI printer: print empty space until end of page");
}
/* (non-Javadoc)
* @see meerkat.voting.VotingBooth.UI#auditVote(meerkat.protobuf.Voting.BallotSecrets)
*/
@Override
public void auditVote(BallotSecrets ballotSecrets) {
// audit = calcAudit (ballotSecrets)
// sendToPrinter (audit)
System.err.println ("UI debug: voter decided to audit vote.");
System.out.println ("UI printer: here we should print audit of ballot");
}
public void run () {
System.out.println("UI screen: Initializing the magic");
System.out.println("UI screen: press something to start the system");
readInputLine();
while (true) {
votingBegin();
if (m_encryptedBallot != null) {
printBallot();
castOrAudit ();
}
}
}
private void castOrAudit () {
// fix the flow here!!
// keeping the same vote should return for a new encryption
System.out.println("UI screen: printing ended. Do you want to (c)ast the ballot or (a)udit?");
boolean keepThisVote = true;
String s = readInputLine();
if (s.equals("c") || s.equals("cancel") || s.equals("cast")) {
castVote();
keepThisVote = false;
}
else if (s.equals("a") || s.equals("audit")) {
auditVote();
System.out.println("Do you still want to keep this vote? Type 'y' for casting/auditing the same vote. Type 'n' tp start from scratch");
if (s.equals("y") || s.equals("yes")) {
//
}
else if (s.equals("n") || s.equals("no")) {
keepThisVote = false;
}
else {
throw new IOException();
}
}
else {
throw new IOException();
}
}
public void registerVBController (VotingBooth vb)
{
m_vbController = vb;
//m_sharedPlaintext = sharedPlaintext;
//m_sharedEncrypted = sharedEncrypted;
}
/*
* returns true if voting finished successfully
* false if cancelled in the middle
*/
private boolean listQuestionsToUserAndGetAnswers()
{
PlaintextBallot.Builder ptbb = PlaintextBallot.newBuilder();
ptbb.setSerialNumber(m_serialNumber);
int index = 0;
while (index < a_questions.length) {
BallotQuestion q = a_questions[index];
printQuestion(index, q);
System.out.println("UI screen: Enter your answer. You can also type 'back' or 'cancel'");
String s = readInputLine();
if (s.equals("cancel") || (index == 0 && s.equals("back"))) {
m_plaintextBallot = null;
return false;
}
if (s.equals("back")) {
--index;
continue;
}
BallotAnswer answer = translateStringAnswerToProtoBufMessageAnswer (s);
ptbb.setAnswers(index, answer);
}
m_plaintextBallot = ptbb.build();
return true;
}
private String readInputLine () {
String s;
try {
s = this.m_in.readLine();
}
catch (IOException e) {
System.err.println("UI debug: VotingBegin(): some error with reading input. " + e);
return null;
}
return s;
}
private String getHexData (ByteString data) {
String s = "";
for (Byte b : data) {
s += "0123456789ABCDEF".charAt((int)b / 16);
s += "0123456789ABCDEF".charAt((int)b % 16);
}
return s;
}
private void printHexData (ByteString data) {
String s = getHexData(data);
System.out.println(s);
}
private void printQuestion (int i, BallotQuestion q) {
System.out.println("UI screen: question number " + i);
System.out.println(q.getData());
printHexData (q.getData());
}
private BallotAnswer translateStringAnswerToProtoBufMessageAnswer (String s) {
BallotAnswer.Builder bab = BallotAnswer.newBuilder();
StringTokenizer st = new StringTokenizer(s);
int index = 0;
while (st.hasMoreTokens()) {
++index;
bab.setAnswer(index, Integer.parseInt(st.nextToken()));
}
BallotAnswer ba = bab.build();
return ba;
}
public void tick () {
// adds a 'tick'. If queue is full, do nothing
a_queue.add (VBMessage.newTick());
}
private void sendBallotToControllerForEncryptionAndWaitForResponse () {
class TickerTask extends TimerTask {
private VotingBoothToyConsoleUI m_ui;
public TickerTask (VotingBoothToyConsoleUI ui) {
m_ui = ui;
}
@Override
public void run() {
m_ui.tick();
}
}
System.out.println("UI screen: Please wait for encryption");
m_vbController.submitBallot(m_plaintextBallot);
m_encryptedBallot = null;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TickerTask(this), new Date(), m_waitForControllerMillisecTimeout);
while (m_encryptedBallot == null)
{
VBMessage msg = null;
try {
msg = a_queue.take();
}
catch (InterruptedException e) {
System.err.println("VotingBoothToyConsoleUI.sendBallotToControllerForEncryptionAndWaitForResponse interrupted!");
return;
}
if (msg.isEmptyMessage()) {
System.out.print(".");
}
else {
m_encryptedBallot = msg.getEncryptedBallot();
if (m_encryptedBallot.getSerialNumber() != m_plaintextBallot.getSerialNumber())
{
m_encryptedBallot = null;
}
}
}
System.out.println("\nUI debug: Received EncryptedBallot");
timer.cancel();
timer.purge();
}
}