Belenios is a verifiable voting system that partially implements the Helios-C protocol described here, which is itself derived from Helios.
It consists of a command-line tool used to perform administrative tasks related to elections, as well as verifications, and a web server used to collect ballots from voters. Voters can vote directly from their web browser.
A specification is provided in specification.pdf.
Compilation instructions are provided in INSTALL.
During an election, you should have access to the following files:
election.json: election parameters
public_keys.jsons: trustees' public keys
public_creds.txt: the public keys associated to valid credentials
ballots.jsons: accepted ballots
Note that the last two are dynamic, and evolve during the election. At
the end of the election, they are frozen and a
result.json file will
If you put these files in a directory
/path/to/election, the following
command will perform all possible verifications, depending on existing
belenios-tool election --dir /path/to/election verify
For example, during the election, you can check if some candidate
ballot is acceptable by putting it alone in
running the command above.
If you put your secret credential in a file
your choices in a file
/path/to/choices.json (as an array of arrays
of 0/1 in JSON format), the following command will output a ballot
that can be directly submitted:
belenios-tool election --dir /path/to/election --privkey /path/to/credential vote /path/to/choices.json
To generate a keypair, run:
It will generate two files,
containing respectively the public and the private key. Send the
public key file to the server administrator, and keep the private key
with extreme care.
To compute your decryption share, set
/path/to/election up as
described in the Voter's guide section above, and run:
belenios-tool election --dir /path/to/election --privkey /path/to/privkey decrypt > partial_decryption.json
partial_decryption.json to the election
Note: be sure to authenticate all your input files when you use your private key!
To generate the credentials, run:
belenios-tool credgen --uuid XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX --count N
XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX is the UUID of the
election given by the administrator, and
N the number of credentials
to generate. It will generate two files,
TTTTTTTTTT is a timestamp), each with
N lines. Send the public file as a whole to the administator, and
each line of the private file to each voter.
You can optionally add a
--dir option to specify the directory where
these files will be written.
Note that, if you are honest, you must not keep the private file, nor to whom you sent each individual private credential.
If you have a list of identities in a file
lines, one identity per line, you can also run:
belenios-tool credgen --uuid XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX --file F
It will create the same
TTTTTTTTTT.public file as above, with
lines. It will also generate
N lines, each
one containing a private credential and the identity of whom to send
it to. Additionally, it will create
lines, each one containing the hash of a public credential and the
corresponding identity. Only the hashed file is needed to disactivate
the credential of a specific identify; the private file must still be
forgotten once it is used.
Note that, as a safety measure, all output files are written sorted so that there is no matching between them based on line numbers.
To get the public key derived from a private credential, run:
belenios-tool credgen --uuid XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX --derive YYYYYYYYYYYYYYY
Once the server is up and running (see next section), anyone who can log into the server can create an election, with the help of the command-line tool. The interface is very rudimentary at the moment, and it is not possible to edit or destroy an election once it has been accepted by the server.
uuidgencommand. Let it be
$DIRthe full path to this directory and by
$BELENIOSthe full path to the Belenios source tree.
$UUIDis needed for that. Save the file with public credentials into
belenios-tool mkelection --uuid $UUID --group $BELENIOS/demo/groups/default.json --template $BELENIOS/demo/templates/election.json. It should generate
election.jsonin the current directory.
$DIR/metadata.jsonfile. Its format is currently undocumented and subject to future evolution, but you can get inspiration from
Each election has its own administration page and authentication configuration. An election owner has to log in from the site administration page (accessible from the link at the bottom of pages) to be able to access the administration page specific to the election.
ballots.jsonsmust be downloaded from the running webserver, as well as
public_creds.txtif some credentials were changed during the election.
partial_decryption.jsonreceived from each trustee into a
partial_decryptions.jsons, in the same order as in
belenios-tool election finalize. It will create
result.json. Publish this file, along with the files listed in the first step above. The whole set will enable universal verifiability.
partial_decryptions.jsons is a temporary file whose contents
is embedded in
result.json, so there is no need to keep it.
A sample web server can be run with the
from the compiled source tree.
Here is an excerpt of the sample configuration file:
<eliom module="_build/src/web/server.cma"> <auth name="demo"><dummy/></auth> <auth name="local"><password db="demo/password_db.csv"/></auth> <source file="../belenios.tar.gz"/> <log file="_RUNDIR_/log/security.log"/> <import dir="demo/data"/> <spool dir="_RUNDIR_/spool"/> </eliom>
<auth> elements configure authentication for the whole
site. Available authentication methods:
<dummy>: just asks for a name. No security is intended. This is useful for debugging or demonstration purposes but obviously not suitable for production
<password>: password-based authentication. It takes as parameter
a file, in CSV format, where each line consists of:
Additional fields are ignored. In the sample
file, a fourth field with the plaintext password is included. The
sample file has been generated with the following shell command:
for u in $(seq 1 5); do SALT=$(pwgen); PASS=$(pwgen); echo "user$u,$SALT,$(echo -n "$SALT$PASS" | sha256sum | read a b; echo $a),$PASS"; done
<cas>: authenticate with a CAS
server. For example:
<auth name="example"><cas server="https://cas.example.com/cas"/></auth>
If the web server is behind a reverse-proxy, it might be needed to rewrite URLs passed to the CAS server. This can be done with the following directive:
<rewrite-prefix src="https://backend-server" dst="https://frontend-server/belenios"/>
<source>element gives the path to the source tarball. Note that this is a path on the local filesystem and not a URL. If you made local changes, an easy way to comply with the AGPL license is to commit them in a local git checkout, and put in the
sourceelement the path to the tarball generated by
<main-election> element is present, the home page will be a
redirection to the referenced election, and not a mere listing of
featured elections. This is useful if there is a single
election. Others elections (if any) are still accessible, though.
<log> element indicates a file where some security-sentive
events will be logged. It is optional.
<spool> element indicates a directory with election data. This
directory should be empty when the server is launched for the first
time, and will be populated with election data. A typical location
<import> element indicates a directory from where elections will
be imported when the server is launched for the first time. The
directory referenced here must contain an
index.json file. Each
election subdirectory must contain the following files:
election.json: election parameters
metadata.json: additional parameters that are not published
public_keys.jsons: public keys of the trustees, one per line
public_creds.txt: anonymous public credentials, one per line
The election fingerprint, which is shown on the election page and in
the booth, is the compact Base64 encoding of the SHA256 of
election.json. It can be computed from a POSIX shell by piping it
sha256sum | xxd -r -p | base64
By "internal code", we mean everything that is not in the
Copyright © 2012-2014 Inria
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version, with the additional exemption that compiling, linking, and/or using OpenSSL is allowed.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
The booth (web-based voting client) has been imported from Helios and adapted for our needs. It uses code from many origins; please refer to each file for accurate copyright and licensing information.