This page documents tweaks to the Helios v3 Verification Specs that will make data types forward-compatible and able to evolve over time to support other types of elections, in particular other types of homomorphic tallying, mixnet tallying, etc... NOT FINAL. THIS DOCUMENT IS IN PROGRESS AS OF August 9th 2011. ALSO worth looking at: Adding Mixnet Support. Raw DatatypesRaw, unlabeled datatypes in Helios v4 are only used to represent integers and strings. Integers are base64-encoded.Adding Type to Data StructuresIn order to distinguish between election types, in particular different encryption mechanisms, tallying approaches, etc., data structures will declare types. If they do not declare a type, the default type value assumed is that of Helios v3.0. We use JSON-LD (JSON Linked Data) to add types. JSON-LD is based on the W3C's RDF for extensible linked data.Public Keys and CiphertextsIn Helios v3.0, public keys are always ElGamal public keys, as follows:<ELGAMAL_PUBLIC_KEY_v3>
{"g": "Hbb3mx34sd", "p": "mN3xc34","q": "J3sRtxcwqlert", "y": "U8cnsvn45234wsdf"} With v3.1+, a public key should be typed, using the RDF/JSON-LD "a" field name. The value of this field is a URL relative to http://heliosvoting.org/vocab/. <PUBLIC_KEY_v3.1>
{"a": "<pkc/elgamal/pk>","g": "Hbb3mx34sd", "p": "mN3xc34", "q": "J3sRtxcwqlert", "y": "U8cnsvn45234wsdf"} This approach, using _type, is the way we'll do things generally in Helios v3.1+. Similarly, ciphertexts should be typed. <CIPHERTEXT> {"a": "<pkc/elgamal/ciphertext>", "alpha": "234r8sdfvn4t3402Df", "beta": "zxc09v245nsfsdf" } ElectionsElections in Helios v3.0 do not include type information, but they include a list of questions, and each question does include some type information:
Encrypted Answer and VoteIn Helios v3.0, an encrypted vote is a list of encrypted answers. This can remain the same in v3.1+, as there will always be an ordered list of independent questions.Similarly, a cast vote, which included an encrypted vote, its hash, the hash of the voter, and a date, can remain the same for all election types: these are just the bundling of answers to multiple questions. However, a single encrypted answer should contain some type information as to how it should be tallied. <ENCRYPTED_ANSWER>
{"a": "<ballot/homomorphic/encrypted-answer>", "choices": [<ELGAMAL_CIPHERTEXT>, <ELGAMAL_CIPHERTEXT>, ...], "individual_proofs": [<ZK_PROOF_0..1>, <ZK_PROOF_0..1>, ...], "overall_proof": <ZK_PROOF_0..max>} The fields within an encrypted answer may, of course, vary depending on _type. An encrypted answer for a mixnet-based system may be: <ENCRYPTED_ANSWER>
{"a": "<ballot/mixnet/encrypted-answer>",
"choice": <CIPHERTEXT>} Complete Datatype SpecificationGiven the above additions, we now specify the datatypes completely.Basic Cryptographic DatatypesAll large integers are represented in decimal form as strings, rather than integers. The reason is that some languages do not support big integers natively, and thus cannot properly parse large integers in JSON integer form. An El-Gamal public-key thus includes the prime p, the primer-order q of its intended subgroup, the generator g, and the public-key value y (with keys in alphabetical order): <ELGAMAL_PUBLIC_KEY>
{"a" : "pkc/elgamal/pk","g": "6811145128679259384514506369165", "p": "16998971978194099593503959", "q": "8499485989097049796751", "y": "7464668703479877164253720373259704"} An El-Gamal ciphertext is a JSON structure containing properties alpha and beta, the two components modulo p. <ELGAMAL_CIPHERTEXT>
{"a" : "pkc/elgamal/ciphertext","alpha": "72348234202340223423", "beta": "123498235234234234324" } In Helios, all ciphertexts are Exponential ElGamal, so alpha = g^r mod p, and beta = g^m y^r mod p. In Helios, all hash values are base-64 encoded, with the hashing algorithm specified, e.g: Hash value example
{"election_hash": {"a": "hash/sha256/output", "value" : "c0D1TVR7vcIvQxuwfLXJHa5EtTHZGHpDKdulKdE1oxw"}}VoterA single voter in Helios is represented using a few fields that identify the voter. <VOTER>
{"a":"voter","name": "Ben Adida", "uuid": "60435862-65e3-11de-8c90-001b63948875", "voter_id": "benadida@gmail.com", "voter_type": "email"}
NOTE: should we use a subtype of "voter" here instead of voter_type? TBD. Together, the type and id identify the voter via some external authentication mechanism. In the example above, this is a user whose email address is benadida@gmail.com. Another example might be: <VOTER>
{"a": "voter","name": "Ben Adida", "uuid": "4e8674e2-65e3-11de-8c90-001b63948875", "voter_id": "ben@adida.net", "voter_type": "email"} where this is a voter identified by the email address ben@adida.net. The uuid field is used as a reference key within Helios. Voters may be identified by OpenID URL rather than email address, in which case their JSON representation is: <VOTER>
{"a": "voter","name": "Ben Adida", "uuid": "4e8674e2-65e3-11de-8c90-001b63948875", "voter_id": "http://benadida.myopenid.com", "voter_type": "openid"} Other fields may be present in a <VOTER> data structure, e.g. category. These do not affect the cryptographic processing, but if present, they become part of the hash of the voter list. Protecting Voter PrivacyIn
order to protect voter privacy, Helios can obfuscate the voter_id,
especially when that voter_id is an email address. This protection is
not meant to resist a powerful attacker with other knowledge about the
voter, but mostly to prevent email-address crawling and spamming. In this case, a voter can be represented
with the field voter_id_hash replacing voter_id. The hash is SHA256 by
default, or specified as a typical hash data structure<VOTER>
{"a": "voter","name": "Ben Adida", "uuid": "60435862-65e3-11de-8c90-001b63948875", "voter_id_hash": {"a": "hash/sha256/value", "value": "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU"}, "voter_type": "email"} Voter AliasesIn some elections, it may be preferable to never reveal the identity of the voters. This is particularly applicable when organizers are worried about votes being decryptable in 20-30 years, when cryptographic advances make today's algorithms weaker. An election may thus publish only an ALIASED_VOTER:<ALIASED_VOTER>
{"a": "aliased-voter", "alias": "voter_123",
"uuid": "b7dbd90a-65e3-11de-8c90-001b63948875"}
An aliased voter still has a UUID, so it can still be referred appropriately in the rest of the system. Casting a VoteOnce a voter has cast a ballot, the encrypted vote representation is then: <CAST_VOTE>
{"a": "cast-vote","cast_at": "2009-07-15 12:23:46", "vote": <VOTE>, "vote_hash": {"a": "hash/sha256/value", "value": "8bncn23nsfsdk234234"}, "voter_hash": {"a": "hash/sha256/value", "value": "2bxksdlkxnsdf"}, "voter_uuid": "b7dbd90a-65e3-11de-8c90-001b63948875"} cast_at is the timestamp of the cast vote in UTC. We describe the details of the <VOTE> data structure later in this document, once we have described all of the required components. vote_hash is available to enable a shorter version of this data structure: <SHORT_CAST_VOTE>
{"a": "short-cast-vote","cast_at": "2009-07-15 12:23:46", "vote_hash": {"a": "hash/sha256/value", "value": "8bncn23nsfsdk234234"}, "voter_hash": {"a": "hash/sha256/value", "value": "2bxksdlkxnsdf"}, "voter_uuid": "b7dbd90a-65e3-11de-8c90-001b63948875"} where only the hash and not the full vote is listed. ElectionAn election is represented as: <ELECTION>
{"a": "election","cast_url": "<https://heliosvoting.org/cast/>", "description": "... blah blah blah ... info about the election", "frozen_at": null, "name": "Student President Election at Foo University 2010", "openreg": false, "public_key": <ELGAMAL_PUBLIC_KEY>, "private_p": false, "questions": <QUESTION_LIST>, "short_name": "fooprez2010", "use_advanced_auditing_p": true, "use_voter_aliases": false, "uuid": "1882f79c-65e5-11de-8c90-001b63948875", "voters_hash": {"a": "hash/sha256/value", "value": "G6yS/dAZm5hKnCn5cRgBGdw3yGo"}, "voting_ends_at": <TIMESTAMP>, "voting_starts_at": <TIMESTAMP>} short_name, name, and description
describe the election. The short name must be a few characters without a
space (almost like a database key), the name can be a long string, and
the description is an even longer description of the election. frozen_at indicates the timestamp at which this election was frozen. It remains null until the election is frozen. openreg indicates whether voters can be added to the list after the election has started. use_voter_aliases indicates whether this election aliases its voters.uuid is a unique identifier for the election, and name is the election's name. <ELGAMAL_PUBLIC_KEY> is, as detailed earlier, the JSON data structure that represents an El-Gamal public key. voters_hash is the hash of the list of voters for the election. The list of voters is a JSON array of <VOTER> or <ALIASED_VOTER> data structures. <QUESTION_LIST> is a data structure that represents the list of questions and available answers to those questions. <QUESTION_LIST>
[<QUESTION>, <QUESTION>, ...]and a single question is: <QUESTION>
{"a": "ballot/question/approval-absolute","answers": [<ANSWER>, <ANSWER>, ...], "max": 1, "min": 0, "question": "Who Should be President?", "randomize_answer_order": false, "short_name": "President", "tally_type": "homomorphic"} The parameter max indicates the maximum number of options that a voter can select, most often 1. The parameter min indicates the minimum number of options that a voter must select, most often 0. Note how, given that max and min should be small integers, they are in fact serialized as integers, not as strings. choice_type indicates the kind of question, for now just approval (possibly with a maximum number of choices). If max is null, then it's approval voting for as many candidates as desired. tally_type indicates how the question is tallied, e.g. homomorphic or mixnet. In some cases, certain question types are not compatible with homomorphic tallying. The different types of questions are:
A single answer is then: <ANSWER>
{"a": "ballot/answer","value": "Alice", "url": "<http://alice.com>", "details": "Alice is a wonderful person who..."} Open Registration Helios supports "open registration elections", when the election
administrator so desires. In those elections, the voter list is not set
ahead of time. In that case, an election data structure contains a null voters_hash, and sets openreg to true. Election Fingerprint
Once an election is ready to be used for voting, the administrator freezes
the election, at which point Helios prevents changing any of the
question parameters and voter registration settings: an open election
remains an open election, and a closed election remains closed with a
fixed voter list. The frozen_at field then indicates the timestamp at which the election was frozen. Such a frozen election can be designated by its Helios Election Fingerprint, which is the base-64-string-encoded SHA256 of the election data structure serialized as JSON (with properly alphabetized field names). Note how this fingerprint depends on the list of voters if the election registration status is closed, but not if it is open. In any case, this fingerprint does not depend on any cast vote or cast-vote hash. VoteA vote contains a list of encrypted answers, and a reference to the election, both by ID (for convenience) and by hash (for integrity.) The hash is the election fingerprint just described. <VOTE>
{"a": "encrypted-vote","answers": [<ENCRYPTED_ANSWER>, <ENCRYPTED_ANSWER>, ...], "election_hash": {"a": "hash/sha256/value", "value": "Nz1fWLvVLH3eY3Ox7u5hxfLZPdw"}, "election_uuid": "1882f79c-65e5-11de-8c90-001b63948875"} Each "encrypted answer" corresponds to one election question. The specifics of the encrypted answer depend, of course, on the type of encryption used for that question. The only type of encrypted answer in v3.0 and earlier is the homomorphic approval answer. it contains a list of ciphertexts (one for each possible choice for that question), a list of corresponding proofs that the ciphertext is correctly formed, and an overall proof that all of the ciphertexts for that election question, taken together, are correctly formed. <ENCRYPTED_ANSWER>
{"a": "encrypted-answer/approval/homomorphic","choices": [<ELGAMAL_CIPHERTEXT>, <ELGAMAL_CIPHERTEXT>, ...], "individual_proofs": [<ZK_PROOF_0..1>, <ZK_PROOF_0..1>, ...], "overall_proof": <ZK_PROOF_0..max>} The value of max in overall_proof matches the value of max in the election's question definition. For approval voting questions, the overall_proof is absent. When a voter generates a ballot, Helios provides the ballot fingerprint, which is the base64-encoding of the SHA256 hash of the <VOTE> data structure defined above. ProofsA zero-knowledge proof, denoted <ZK_PROOF_0..max>, is a transcript of a non-interactive proof that the corresponding ciphertext encodes an integer value between 0 and max. For the overall proof, the ciphertext whose value is being proven to be between 0 and max is the homomorphic sum (element-wise product) of the choices ciphertexts. In Helios, all 0..max proofs are disjunctive proofs (CDS & CP), meaning that the transcript includes max+1 proofs, one for each possible value of the plaintext, 0 through max. The max+1 individual challenges must sum up to the single actual protocol challenge, which ensures that one of the proofs is real (while the others are simulated.) <ZK_PROOF_0..max>
{"a": "proofs/range/disjunctive","proofs": [<ZK_PROOF(0)>, <ZK_PROOF(1)>, ..., <ZK_PROOF(max)>]} A single ZK proof is then composed of three messages: the commitment, the challenge, and the response. Since the proof is a Chaum-Pedersen proof of a DDH tuple, the commitment is composed of two values, A and B. Thus, a ZK proof is: <ZK_PROOF(plaintext)>
{"a": "proofs/chaum-pedersen","challenge": "2342342", "commitment": {"A": "28838", "B": "9823723"}, "response": "970234234"} Ballot Audit TrailWhen a voter chooses to audit their ballot, each encrypted answer contains additional information concerning the actual selected choice and the randomness used to encrypt each choice's ciphertext. Specifically, the JSON structure for <VOTE_WITH_PLAINTEXTS> is as follows. <VOTE_WITH_PLAINTEXTS>
{"a": "encrypted-vote", "answers": [<ENCRYPTED_ANSWER_WITH_PLAINTEXT>, <ENCRYPTED_ANSWER_WITH_PLAINTEXT>, ...], "election_hash": {"a": "hash/sha256/value", "value": <B64_HASH>}, "election_uuid": <ELECTION_UUID>} And the contained <ENCRYPTED_ANSWER_WITH_PLAINTEXT> is as follows. <ENCRYPTED_ANSWER_WITH_PLAINTEXT>
{"a": "encrypted-answer/approval/homomorphic","choices": [<ELGAMAL_CIPHERTEXT>, <ELGAMAL_CIPHERTEXT>, ...], "individual_proofs": [<ZK_PROOF_0..1>, <ZK_PROOF_0..1>, ...], "overall_proof": <ZK_PROOF_0..max>, "plaintexts": [<PLAINTEXT>, <PLAINTEXT>, <PLAINTEXT>, ...], "randomness": [<BIGINT>, <BIGINT>, <BIGINT>]} ResultThe result of an election is represented using the <RESULT> data structure. The proofs of the decryption are done at the Trustee level. The result simply displays the count of votes for each candidate within each question, in an array of arrays format. <RESULT>
{"a": "result","counts": [[<QUESTION_1_CANDIDATE_1_COUNT>, <QUESTION_1_CANDIDATE_2_COUNT>, <QUESTION_1_CANDIDATE_3_COUNT>], [<QUESTION_2_CANDIDATE_1_COUNT>, <QUESTION_2_CANDIDATE_2_COUNT>]} TrusteeEven if there is only one keypair in the case of a simple election, Helios v3 (in a departure from previous versions), represents every election as having trustees. If there is only one trustee, that's fine, but the data structure remains the same: <TRUSTEE>
{"a": "trustee","decryption_factors": <LIST_OF_LISTS_OF_DEC_FACTORS>, "decryption_proofs": <LIST_OF_LISTS_OF_DEC_PROOFS>, "pok": <POK_OF_SECRET_KEY>, "public_key": <PUBLIC_KEY>, "public_key_hash": <PUBLIC_KEY_HASH>, "uuid": <UUID_OF_TRUSTEE>} |