python-dirbtuves/internet-voting-django#2
Model fields:
created
(datetime)title
(required)slug
(auto slug field)active
(boolean)registration_close_time
(date time, required)voting_open_time
(date time)voting_close_time
(date time)signing_close_time
(date time)primary_key
(text)public_key
(text)public_key_fingerprint
(char field)salt
(char field)
This model should be available in Django admin.
CEC person: creates voting poll
This should be done using Django admin, and voting poll form should set these initial values:
registration_close_time
- 1 day after todayvoting_close_time
- 1 day after registration_close_timesigning_close_time
- 1 day after voting_close_time
Server: generates voting poll key pair
Set
primary_key
,public_key
andpublic_key_fingerprint
fields using generated key pair data, save this to database.Key pair should be generated using
generate
function.Primary key and public key should be serialized using
dump_private_key
function. Primary key should be protected with Django secret_key and Poll salt.Public key fingerprint should be SHA-1 (use
public_key_fingerprint
).
python-dirbtuves/internet-voting-django#1
Voter model
Model fields
user_id
(foreign key)name
(char field)
Voter: fill registration form
Form fields:
name
Save form data to database.
PUT /voter/<registration id>/register/
POST data:
- registration public key (serialized with dump_public_key)
Voter poll model
voter_id
(foreign key)poll_id
(foreign key)check_code
(char key), random number, will be used to verify client appregistration_id
(UUID4)registration_number
(int)registration_date
(datetime)registration_fingerprint
(char field), SHA-1registration_public_key
(text)registration_hash
(char field)mixnet_volunteer
(boolean)
Unique fields:
voter_id
, poll_idregistration_id
Server actions:
Check given registration id.
Server should find voter poll with provided registration id and save registration public key.
If registration public key is already registered, an error should be returned, telling, that user can register only once.
Get registration hash.
Registration hash should be generated from all already registered public keys. Following data in this order should be used to generate hash:
- Registration number (starting from one).
- Registration date and time in
isoformat
. - Mix-net volunteer (0 or 1).
- Voter registration public key fingerprint.
- Voter registration public key.
All these fields should by hashed joining fields with
\t
character.Also all these fields, together with hash should be stored to database.
Server returns:
- Poll id.
- CEC public key.
- Check code.
- Registration number.
- Registration hash.
- Registration date.
- Registration close time.
- Voting open time.
- Voting close time.
- Signing close time.
First user visits list of available active voting polls. Only active polls are shown in the list.
Then user selects a voting poll.
After selecting a voting poll:
Server: generates registration id
Registration id should be UUID4. Saved this id to database.
Server: generate check code
Check code should be random number, maybe three bytes (use
get_random_bytes
).Website: show registration id, check code and CEC public key fingerprint.
Check code maybe should be shown as three numbers, converted from three radom bytes.
If same voting poll will be visited again, same registration id, check code and CEC public key should be shown and nothing should be saved to database.
Also there should be a button for Mix-net volunteers, by pressing this button,
voter agrees to become Mix-net volunteer. Before saving mixnet_volunteer
flag, confirmation page, with explanation what is mixnet_volunteer
is
should be show. Only after confirmation, data should be saved to database.
Veter registers for voting by running following command from command line client:
$ voter register <registraiton id>
Client: creates registration key pair.
Client: sends registration public key.
Uses
/voter/<registration id>/register/
Server API endpoint.Client: shows CEC public key fingerprint and check code.
User should verify check code by comparing it with what he saw after registration in CEC website.
Client: generates vote identification key pair.
Save all data to voter file.
Voter file should be encrypted using
dump_sensitive_data
. File content should look something like this:{ 'salt': dump_base64(get_random_bytes(64)), 'vote:': apply_hash_function(vote_json, salt), 'poll_id': poll_id, 'registration_id': registration_id, 'registration_number': registration_number, 'registration_date': registration_date, 'registration_hash': registration_hash, 'registration_key': dump_private_key(reg_private_key), 'identification_key': dump_private_key(id_private_key), 'registration_close_time': registration_close_time, 'voting_open_time': voting_open_time, 'voting_close_time': voting_close_time, 'signing_close_time': signing_close_time, 'choices': [ [ question_id, question_title, [ [value, title], ... ] ], ... ] }
Filename could be named
voting.proof
.A password should be asked from used, to be able to encrypt voter file.
If same command will be run again and voting.proof
file exists, then
password should be asked to decrypt file content. After validating file
content, no action should be taken.
GET /polls/<poll id>/voters.tsv GET /polls/<poll id>/voters.tsv?offset=<registration_number>
Simply returns TSV file with all registered voters. Optionally offset
can
be specified to get only newly registered voters.
TSV file includes following fields:
- Registration number (starting from one).
- Registration date and time in
isoformat
. - Mix-net volunteer (0 or 1).
- Voter registration public key fingerprint.
- Voter registration public key.
- Registration hash.
All those fields should be joined with \t
.
$ voter pull
This command checks if registration_close_time
is more than now and voting_open_time
is less than now, then voters.tsv
file will be downloaded.
voters.tsv
should be saved to internal SQLite database. SQLite database can
be called voting.db
. Downloaded voters should be stored to voters
table.
When pulling, if voters
table already has some record, then offset
should be taken from MAX(registration_number)
and only new voters should be
requested.
After pulling, hashes should be checked and confirmed.
After data integrity check, some information should be provided, how much new items where pulled, how much voters there are, laster voter hash.
When inserting many records to database, bulk inserts should be used.
For database access dataset
library should be used.
PUT /voter/<registration id>/announce-node/
PUT data:
- Host.
- Port.
Mix-net node model fields:
voter_id
host
port
last_time_seen
(datetime)online
(int), minutes online
Online time should be increased if announcement received not longer than 30
minutes ago since last time seen. If announcement receive longer than 30
minutes, then online
should be set to 0.
python-dirbtuves/internet-voting#9
$ voter start-node host[: port]
Probably it is a good idea to use aiohttp.
When daemon is started, it should announce CEC server, for it's availability,
using PUT /voter/<registration id>/announce-node/
.
These announcements should be made each 15 minutes.
GET /polls/<poll id>/nodes.tsv
TSV file includes following fields:
- Node host.
- Node port.
- Voter registration public key fingerprint.
- Voter registration public key.
- Registration hash.
- Online.
All those fields should be joined with \t
.
Each 15 minutes, mix-net nodes checks for new available mix-net nodes by using
GET /polls/<poll id>/nodes.tsv
API endpoint.
All received data is written to internal voting.db
database to nodes
table.
$ voter pull
Client outputs all available choices with number next to each choice and asks user to enter the number of his choice.
If there are more than one question, then same thing will be repeated while all questions will be answered.