I had this idea a few years ago and improved it today as I notice a hole or two. I believe I have the system down right but If there was a hole the first time there may be a hole this time. I believe the below will have a voter voting anonymously and impossible to tamper with unless the party handing out tickets give out more tickets than it should. What do you guys think?
Lets say there are many parties who track votes (simply known as party) and a verification-party who validate your identity and allows you to vote. Starting from the point the software knows you are validated it starts the verification-phase.
Connect and verify yourself to the verification-party. The voter should receive a ticket which is simply a signed GUID.
Parties will be contacted in a chain. If the order is randomize find out what the order is for the session
Generate X+1 public/private key pair where X is the number of parties. They should be unique and only to be used for this verification-phase. -edit- someone asked why. This is so if any link leaks data no other part of the chain can recognize it link since it has no matching data. Every step/link is encrypted with that party public key.
The voter send the signed ticket and 'encrypted data' to the first party. 'encrypted data' is a public key for that party + inner data which are for public keys for the next link in the chain.
Each party will check if the ticket is valid/signed by the previous party or verification-party if it is the first party. It will then decrypt the 'encrypted data' and take the voter public key which it keeps for the session.
The party will create a new ticket which is a new GUID and the remaining 'encrypted data' than and signs it. It hands it to the next party in the chain.
When the last party receives the ticket it will request a party-vote-ticket from each party (including itself). It will have two keys, one for itself one to give to each party. The party combines each of the party-vote-ticket and encrypts them with the voter public key for itself. The data is sent back up the chain
When each party receives the encrypted data it will use the public key the voter gave it before sending it up the chain.
The party-vote-ticket is simply a signed GUID which as i mention is encrypted with the voter public key.
The voter decrypts the data with each of its private keys and unlocks the vote-ticket to use in the next phase.
At a later time (minutes, hours, days) the voter may vote with the tickets. The following steps to vote are
- Connect to any party with a block of data with a GUID
- Each party will sign the GUID and send it to the next party.
- The last party sees all the others have signed the GUID and it signs than sends the data back down the chain.
- The voter now knows which party is last (even if its randomize) and been signed by each party. The voter can now trust the order since it is sign and will encrypt the vote-ticket + who the voter is voting for with the last party public key. The voter sends it through the chain.
- The last party decrypts the data and duty is to send a copy to each party.
Some possible attacks
Identify The Voter
Looking at IP address: In both phase the data goes through each party before any data can be exchange or seen. This is to hide voters ip in the voting phase and disassociate the voter ID in the verification phase.
Data being passed in the Verification phase: The information one party gives to the next is a GUID which is different at each step and encrypted data (chained encrypted public keys). If there is a leak it won't matter because the encrypted data is different at each link in the chain thus no way to associate it with data elsewhere in the chain.
Time of voting: If a party notice only 1 voter has registered this minute and votes this minute it can be assumed the person who registered is the voter who voted. It is best to randomize the time voting and would be better if many/all Voters goes through the verification phase before going through the vote phase.
Vote Tampering
- Changing votes: Because the voter has an anonymous ticket before voting all votes should be public and the voter should be able to check via GUID if the vote is correct with each party.
- Repeat votes via reusing signed tickets: Since no one but the voter can see the ticket and no one can sign it this should be impossible. If a voter tries cheating and submitting multiple times ignore it. If the voter tries voting for someone else flag all votes as 'tampered' and record date/time with any other data the party wants.
- Repeat votes with different tickets: This relies on the verification party not issuing more than one ticket to a person. Also each party should check if a ticket is correctly signed.
- Voting for someone who has been verified but hasn't voted: Because each party encrypts its party-vote-ticket with the voter's public key no one but the voter should be able to see it. Again checking if it is signed is important.
- Voting for someone who has not been verified and doesn't want to vote: This would be the issue of the verification party handing out tickets.
- Parties Ignoring Votes: If a party is the last party and sees it does not like who the voter is voting for it may attempt to cheat by ignoring it. Again this is countered by the voter simply checking but also the voter can attempt to vote again using the keys as it was ignored the first time. A voter should be able to check if the vote went through within a minute or two even if the party decides not to real who the voter has voted for until a after the election.