Skip to content
jschejter edited this page Apr 11, 2016 · 32 revisions

The Bulletin Board

The Bulletin Board is a web-app written in Ruby using a framework called Sinatra. We use MySQL as our database, which is located on the same machine as the web-app.

Setting up the Bulletin Board

First go to the bulletinboard directory. You need a working Ruby installation. New linux distributions have one already installed. Now, from the bulletinboard directory, run

$ make

this will install lots of stuff, setup the database and make everything work.

NOTE: the make installs mysql-server, and it will ask you to set the MySQL root password. Since this is just a toy project, we use an empty password so that it will be easy to work with. So go ahead and just press ENTER when asked.

Of course, in a real project, you would want to setup a serious root password for your database.

Environment Variables

Before working with the bulletin board you must always run, from the bulletinboard directory

$ source env.sh

This sets up some environment variables that Ruby needs.

Running tests

To make sure everything is OK

$ rake test

This will run our unit tests.

Running the Web App

The app runs in two modes, secure and insecure. The difference is that in secure mode, the app will verify signatures, and in insecure mode, it will not. You may find it easier, for development purposes, to work insecurely. To run insecurely use

$ BB_INSECURE= rake run

(Votes will always be verified with a signature, even in Insecure mode)

To run in secure mode use simply

$ rake run

Either way, this will launch a webserver listening on port 4567.

Supported APIs

Publishing Commitments/Complaints/ParametersFile

Here's a small example of publishing commitments and then retrieving the data. We publish using POST and retrieve things using GET.

$ wget -q --header "Content-Type: application/json" --post-data='{"content":{"party_id":5,"t":7,"[b]-1[\b]commitment":[56,88]}}'  -O- http://localhost:4567/publishCommitment

$ wget -q --header "Content-Type: application/json" --post-data='{"content":{"party_id":8,"t":17,"commitment":[40,90]}}'  -O- http://localhost:4567/publishCommitment

$ wget -q  -O- http://localhost:4567/retrieveCommitment
[{"party_id":5,"t":7,"commitment":[56,88]},{"party_id":8,"t":17,"commitment":[40,90]}]

Publishing messages is exactly the same, just use Message instead of Commitment. The same goes for publishing Complaints.

Publishing Messages

POST to use the /publishMessage url, with JSON data in the following format:

{"party_id":10,"recepient_id":20,"message":"arbitrary-data-here","signature":"signature-here"}

you can retrieve messages for a given recepient with a GET request to /retrieveMessage?recepient_id=ID.

Sending and retrieving votes

Example of posting votes to the BB:

To send 3 votes "123456", "538495", "4562" (3 races) from ballot_box 10 and serialNumner 23456, do this:

$ wget -q --header "Content-Type: application/json" --post-data='{"ballot_box": 10, "serial_number": "23456", "votes": [ {"vote_value": "123456"}, {"vote_value": "538495"}, {"vote_value": "4562"}], "signature": "ekjfkjansfads", "qr": "sdfqwuibmvxsdf"}'  -O- http://localhost:4567/sendVote

Note that the value of signature (ekjfkjansfads) should be the result of signing the first vote in the array (execute the provided signature function on this: "123456". Note that the values of "vote_value" and the value of "signature" must all be converted to base64 format before sending to the server.

Example of retrieving the votes:

To get ALL votes in the BB, perform: 
$ wget -q  -O- http://localhost:4567/getBBVotes/-1

Response:
[{"vote_id":1,"vote_value":"123456","ballot_box":10,"serial_number":23456,"race_id":1},{"vote_id":2,"vote_value":"538495","ballot_box":10,"serial_number":23456,"race_id":2},{"vote_id":3,"vote_value":"4562","ballot_box":10,"serial_number":23456,"race_id":3}]

To get votes from a specific race (for example race_id 2), perform: 
$ wget -q  -O- http://localhost:4567/getBBVotes/2

Response:
[{"vote_id":2,"vote_value":"538495","ballot_box":4,"serial_number":23456,"race_id":2}]

Sending and retrieving ZKP (for Threshold)

ZKP process:

  1. party_id i performs:
  2. Retrieve all votes (or votes per race - TBD).
  3. Calculate zkp for a vote (vote_id x).
  4. Publish the calculated zkp of vote_id x to the BB with other relevant information (see example).

Each party repeats steps 3-4 for each vote in the BB. Make sure that the vote_id sent in publishZKP is the same vote_id as recieved from getBBVotes. This way we assure that each vote has n zkps (n parties). The signature value is the result of executing the provided Sign function on the calculated zkp value.

Example of posting ZKP to the BB:

To send zkp of vote_id 32, race_id 3 (get this info from getBBVotes response), by party_id 4, do this:

$ wget -q --header "Content-Type: application/json" --post-data='{"vote_id": 32, "race_id": 3, "party_id": 4, zkp: "this is a proof", "signature": "ekjfkjansfads"}'  -O- http://localhost:4567/publishZKP

Example of retrieving ZKP from the BB: (for decryption process)

$ wget -q  -O- http://localhost:4567/getZKP

Response:
[{"vote_id":32,"party_id":1 ,"race_id":3, "zkp":"zkp1"},{"vote_id":32,"party_id":2,"race_id":3,"zkp":"zkp2"}]

Getting the Public Key for a Given Party

Use a GET request to /getPublicKey with the party_id in the query string, e.g.:

$ wget -q --header "Content-Type: application/json"  -O- "http://localhost:4567/getPublicKey?party_id=10"

The two big integers will be returned like so:

{"party_id":10,"first":11,"second":12}

Getting the voting public key (encrypt votes with this key)

$ wget -q  -O- http://localhost:4567/retrieveVotingPublicKey

Response:
[{content: "public_key"}]

Formats to send to the BB

Represent a group member as a byte array by concatenating the x coordinate and the y coordinate, x first, nothing in between. Each number will be unsigned little endian and will be trailed by zeros such that the size of the array will be exactly (32) * 2 bytes. Representing a byte array as a string will be made by encoding the byte array to standard Base64 and encoding the base64 array to utf8:

        byte[] base64 = base64Encoder.encode(myArray);
        String utf8 = new String(base64, "UTF-8");