API Reference

This API is designed to allow clients to correctly implement an E2E Verifiable election. In designing this API, we tried to balance the following constraints and goals:

  • correct: The API must provide the necessary tools to implement a correct E2E verifiable election system.
  • communication agnostic: The client is responsible for managing communications between components. Those components may be a part of the same program and communicate via argument-passing, or they may be on entirely different servers and communicate over a network. This leads to a design in which the entities produce and consume messages that drive the election process forward and enforce an ordering on operations.
  • easy to use: API should be easy to use correctly. This means reducing the number of functions calls where possible, as well as using the types of messages to guide the user towards correct usage of the API.
  • general: We try to make no extra assumptions about the set-up of the election other than those required by the ElectionGuard E2E Verifiable specification.

There are 3 phases of an election:

  1. Key Ceremony: A group of \(n\) trustees jointly generate a joint public key such that for a predetermined threshold \(k\), any \(k\) of the trustees can decrypt a message encrypted by the public key.
  2. Voting: Voters cast their ballots at various polling locations. Their ballots are encrypted using the the joint public key.
  3. Decryption: A group of at least \(k\) of the trustees jointly decrypt the tally of all the ballots and publish sufficient information for anyone to verify that the tally and decryption was carried out correctly.

Within the API, these phases are represented by interactions between various entities:

  1. The key ceremony is carried out by \(n\) KeyCeremony_Trustee objects representing the election trustees, and a single KeyCeremony_Coordinator object that provides a central “location” to which KeyCeremony_Trustees submit pieces of information, and which then broadcasts that information to all the KeyCeremony_Trustees.
  2. Voting is carried out by groups of many Voting_Encrypters (probably located within ballot marking devices) connected to a single Voting_Coordinator. Each group represents a single polling location. The Voting_Encrypter is responsible for encrypting ballots to produce ballot_trackers and ballot_identifiers. The Voting_Coordinator is responsible for keeping track of which ballots have been registered, cast, and spoiled.
  3. Tallying is carried out by a group of at least \(k\) Decryption_Trustee objects representing the election trustees, and a single Decryption_Coordinator object in a structure very similar to that of the Key Ceremony.

We chose to separate the trustees and coordinators into KeyCeremony_Trustees/Decryption_Trustees and KeyCeremony_Coordinators/Decryption_Coordinators respectively. This is because conceptually a trustee has two distinct tasks, key generation and decryption, that are linked by a small kernel of persisted information such as the trustee’s private key and key shares. Decryption will probably happen at least a day after the key ceremony, so it is important that the information necessary for decryption can be stored for a long period of time. Making the distinction between KeyCeremony_Trustees and Decryption_Trustees and making the persisted trustee_state explicit and serializable makes the APIs of each component simpler and makes it easier to persist the trustee_state over the course of the election.