Skip to content

Instantly share code, notes, and snippets.

@sirex
Last active August 29, 2015 14:25
Show Gist options
  • Save sirex/4e281f75687a5cf24f97 to your computer and use it in GitHub Desktop.
Save sirex/4e281f75687a5cf24f97 to your computer and use it in GitHub Desktop.
Internet voting project tasks

Library: Crypto helpers

Website: Creating new voting poll

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 today
    • voting_close_time - 1 day after registration_close_time
    • signing_close_time - 1 day after voting_close_time
  • Server: generates voting poll key pair

    Set primary_key, public_key and public_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).

Website: Voter authentication

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.

Server API: Voter registration

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 app
  • registration_id (UUID4)
  • registration_number (int)
  • registration_date (datetime)
  • registration_fingerprint (char field), SHA-1
  • registration_public_key (text)
  • registration_hash (char field)
  • mixnet_volunteer (boolean)

Unique fields:

  • voter_id, poll_id
  • registration_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.

    See: python-dirbtuves/internet-voting#7

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.

Website: selecting voting poll

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.

Client: register for voting

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.

Server API: Get registered voters

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.

Client: Get registered voters

$ 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.

Server API: Accept node announcements

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.

Client: Running mix-net node daemon

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.

Server API: Get available mix-net nodes

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.

Node: Get available mix-net nodes

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.

Client: Vote

$ 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment