Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cast as intended verification during the vote #21

Closed
3 of 4 tasks
JanisErdmanis opened this issue Jan 21, 2024 · 5 comments
Closed
3 of 4 tasks

Cast as intended verification during the vote #21

JanisErdmanis opened this issue Jan 21, 2024 · 5 comments
Labels
client Need changes to the voting client easy Something that takes comparably little effort feature

Comments

@JanisErdmanis
Copy link
Member

JanisErdmanis commented Jan 21, 2024

At present, voters can only confirm that their vote has been cast as intended and accurately counted after the vote has ended and the votes are published. As the publication of votes can be delayed as a measure against coercion, it might discourage voters' participation from verifying that their vote is indeed cast as intended and counted as cast. The key issue lies in the possibility of unnoticed malware on voting devices. If voters don't verify their votes, the likelihood of malware affecting a significant number of votes without detection increases. Thus, having a procedure that enables immediate verification of the voting process is essential to engage more voters to check their votes.

The PeaceFounder system can address this by providing voters with a token displayed on the client's screen for vote verification. This token can be used in a web browser to confirm that the vote has been cast as intended. It also indicates if the vote has been superseded by a subsequent vote or one with a higher sequence number, which may occur if the member's key is compromised. To maintain receipt-freeness, the token remains valid for only a short period, such as 15 minutes. The expiration is crucial; it allows voters to verify their votes while preventing coercion or bribery attempts. It also hinders any unsolicited checks on voters' choices.

The most straightforward method to generate a token is using the byte string of the vote. This is done by setting the token as $token={\rm{Hash}}(0|vote)$, where the vote itself is the secret to be safeguarded. To utilise this token, an HTTP request is sent to the server containing $TokenID={\rm Hash}(token)$ along with an HMAC of the request. This request is directed to:

GET /ballotbox/{proposal_index}/votes/peek/{token_id}

When the server receives a vote verification request, it first checks that the token is valid and has not expired and then returns the vote's metadata. To maintain the integrity of this response during its transmission, the reply is secured with HMAC. Additionally, encrypting this reply would be advantageous to safeguard the voter's privacy when their network is under surveillance.

However, this approach has limitations. It doesn't prevent the possibility of a network monitor storing data for future comparison with the information on the ballotbox ledger, where votes and, therefore, tokens are eventually published. To enhance security in this aspect, the token could be derived from the Diffie-Hellman key, which could remain secret indefinitely. The server would generate a key pair and incorporate the public key into the receipt, whereas locally exponentiate pseudonym to derive the key.

There's also the risk of a corrupt election authority monitoring the voter. That could trace the voter's pseudonym back to their IP address and, ultimately, their identity. The most effective way to mitigate this risk is to run these requests through a TOR browser, ensuring anonymity. An ultimate solution from a usability point of view would be if the TOR client could be embedded within web assembly to make the request, but there does not seem to be support for that.

For this issue, the following tasks thus need to be addressed:

  • Implement the HTTP endpoint;
  • Add HMAC verification for the request;
  • Add encryption of the reply;
  • Implement a static website form where the request for peeking a vote can be made.

Regarding the website interface, several technical details must be specified: the server's address, the Hash/HMAC function for request authorisation, and the encryption method for replies. However, these technicalities will be seamlessly integrated into the user experience. A custom-designed bulletin board facade will hardcode these parameters, requiring the user only to input the token.

It's crucial to highlight that while voters can verify their vote to be cast as intended through this system, there remains uncertainty. Voters cannot be assured that malware won't ultimately influence the election results by altering their votes or adding a coercion tag invalidating it (which is not disclosed). Additionally, this implementation does not guard against the possibility of the server providing misleading information about the vote being cast. In such a scenario, the worst-case recourse for voters would be to recast their vote and eventually compare it with the ballotbox ledger after the votes are published.

@JanisErdmanis
Copy link
Member Author

I've made a significant advancement in integrating the API authorisation on the Julia side, achieving compatibility with the existing JavaScript implementation right from the outset. This small milestone includes the development of fetchAuthorize in JavaScript, mirroring the functionality of the standard fetch method but with an additional feature: it accepts an authorisation key to sign the request and verify the signed response.

On the Julia side, I've introduced AuthorizationMiddleware, which is designed to simplify adaptation to various requirements. This middleware facilitates the seamless integration of authorisation mechanisms into our existing infrastructure. Also, CORS issues have been resolved so that the requests can be made from a random static page without issues.

I have put proof of concept in this gist. This implementation freezes Julia and JavaScript for endpoint authorisation APIs for #14, so work can continue on the refactor.

@JanisErdmanis
Copy link
Member Author

One of the setbacks for anonymity looks like it is going to be the User-Agent header, which puts rather specific information in combination with an IP address, making tracking for a corrupt server easy. Thus, the use of TOR is recommended when making such requests.

From a UX standpoint, it would be great if the verification of the vote could be performed only if the user opens the webpage with TOR. This, however, seems impossible to do as TOR has put an effort to make it indistinguishable from an ordinary browser.

@JanisErdmanis JanisErdmanis added client Need changes to the voting client feature easy Something that takes comparably little effort and removed easy Something that takes comparably little effort labels Mar 24, 2024
@JanisErdmanis
Copy link
Member Author

The webiste interface will be cosidered seperatelly. For this issue it is only important that the voter's client shows a token after casting the vote and that it can be used to query the vote from terminal making a coresponding HTTP request.

@JanisErdmanis JanisErdmanis added the easy Something that takes comparably little effort label Mar 24, 2024
JanisErdmanis pushed a commit that referenced this issue Apr 22, 2024
@JanisErdmanis
Copy link
Member Author

JanisErdmanis commented Apr 23, 2024

Screenshot 2024-04-23 at 02 36 33 Screenshot 2024-04-23 at 02 35 58

The access codes have been implemented. On the left, it is shown how it is displayed to the voter, put in brackets next to the cast record. This approach was chosen in contrast to placing the access code in a new line because:

  • another line decreased approachability and made the receipt more overwhelming
  • the cast record uniquely identifies the vote in the ballotbox, and thus, there is a one-to-one mapping between access codes and this identifier

The access code is kept short at 4 bytes. This is, however, a bit too small as an adversary can make a credential -> key mapping table, which only takes 16GB. The key size could be increased to 5 bytes to increase the strength, which would make the table take around 16TB. There are two user-friendly options to increase the key size:

  • Use a 5bit alphanumeric encoding
  • Increase the chunk size from 4 to 5 characters

The first option would be nicer from the users' point of view. However, there is no standard way to do so. A base32 encoding like outlined here would be suitable. The second option is dead simple for developing.

Another factor that can strengthen the key is making the adversary invalidate the table frequently:

  • by adding proposal UUID to the key
  • adding a timestamp for the derivation of the credential
  • using a server challenge
    Note that neither of these options would improve security for a particular voter as an adversary knowing how the credential is derived would need to compute 16GB (or 5 TB) of data and determine how the voter voted.

The next aspect is the encryption of the response. This aspect is dropped because it takes significant effort to make compatible encryption between CryptoJS in Javascript and Nettle in Julia. A padding issue is involved, so the adversary could not know how the voter voted, depending on the response length.

For access codes, it does look like a much better option to strengthen them is either on the voter side:

  • The request is routed through a TOR network; thus, a passive adversary who knows the link between IP addresses and voters' identities would be unable to learn how voters voted when they use the access codes;
  • Routing tracking requests through TLS on the server side;

For the first option, a node-TOR project looks relevant, which could allow to make requests through a static web page without voter needing to run the TOR browser on their own. The second option is a more pragmatic approach and can be easily implemented, but it would not help to maintain untraceability from the server itself.

@JanisErdmanis
Copy link
Member Author

JanisErdmanis commented Apr 23, 2024

Crockford base32 encoding has now been implemented, thus increasing the tracking code size to 5 bytes and, as a result, increasing the decoding table to 5TB (5 * 256^5 / 1024^4).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
client Need changes to the voting client easy Something that takes comparably little effort feature
Projects
None yet
Development

No branches or pull requests

1 participant