Skip to content

Commit

Permalink
✨ weighted voting support (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
Findeton authored Apr 2, 2024
2 parents 52b4a0f + 96e5e84 commit 598fe2a
Show file tree
Hide file tree
Showing 19 changed files with 178 additions and 96 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/unittests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Install internal dependencies
run: |
export INTERNAL_GIT_VERSION="master"
export INTERNAL_GIT_VERSION="10.2.0"
git clone https://github.com/sequentech/tally-methods.git
cd tally-methods && git checkout "${INTERNAL_GIT_VERSION}" && cd ..
mv tally-methods/tally_methods .
Expand Down
33 changes: 18 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# election-verifier

https://user-images.githubusercontent.com/81968/164185978-953b72b6-3faa-4cad-a93b-879fe191e9b6.mov

`election-verifier` performs universal verification of an election tally in
[Sequent] platform.

Expand All @@ -9,11 +11,12 @@ The verifications performed are:
2. `counted-as-recorded`: Allows anyone to verify that with the given set of
encrypted ballots, the calculated election results are correct. This
includes:
- The usage of [mixnet] library to verify the `Zero Knowledge Proofs` of:
- Key Generation
- Shuffling
- Joint-decryption of the encrypted ballots
- The calculation of election results from the plaintext ballots verified in
1. The usage of [mixnet] library to verify the `Zero Knowledge Proofs` of:
1. Key Generation
1. Ballot Shuffling
1. Ballot Re-encryption
1. Joint-decryption of the encrypted ballots
1. The calculation of election results from the plaintext ballots verified in
the previous Joint-decryption verification step, using the [tally-pipes]
and [tally-methods] libraries.

Expand All @@ -28,14 +31,14 @@ can find an example of some tallies to verify in `testdata/` directory in this
repository. Note that you need to use a matching software version of
`election-verifier` and this tally to make it work.

In the `testdata/` directory, the file `12.tar` is a valid election tally, and
In the `testdata/` directory, the file `8.tar` is a valid election tally, and
all the other tallies contain different kind of invalid errors that would make
the verifier fail, showing some red color output and returning a non-zero value
as result.

Finally, to perform recorded-as-cast verification in this testdata, note that a
valid ballot tracker is
`09684d8abd01c2227432bc6302e669fac4e4b3e7251f24c4a9c938683fa44705`.
`ae38e56fd663c142387ad9f69d710e9afd1e8c28da3f0ba93facdaae65d273e6`.

### Performing `counted-as-recorded` verification

Expand All @@ -45,8 +48,8 @@ command:

```bash
chmod +x election-verifier
# Execute by using ./election-verifier <path-to-tally.tar>
./election-verifier testdata/12.tar
# Execute by using bash ./election-verifier <path-to-tally.tar>
bash ./election-verifier testdata/8.tar
```

**Tip:** You can use one of the invalid testdata tallies and see how
Expand All @@ -58,14 +61,14 @@ You can also verify the inclusion of a ballot tracker with `election-verifier` i
the list of encrypted ballots of the election tally. This is the so-called
`recorded-as-cast` verification. Note that the ballot tracker is just a hash of
the ballot. If the ballot tracker is
`09684d8abd01c2227432bc6302e669fac4e4b3e7251f24c4a9c938683fa44705`, then to
`ae38e56fd663c142387ad9f69d710e9afd1e8c28da3f0ba93facdaae65d273e6`, then to
perform this verification on the tally `tally.tar` you would run the
following command:

```bash
chmod +x election-verifier
# Execute by using ./election-verifier <path-to-tally.tar> <ballot-tracker>
./election-verifier testdata/12.tar 09684d8abd01c2227432bc6302e669fac4e4b3e7251f24c4a9c938683fa44705
# Execute by using bash ./election-verifier <path-to-tally.tar> <ballot-tracker>
bash ./election-verifier testdata/8.tar ae38e56fd663c142387ad9f69d710e9afd1e8c28da3f0ba93facdaae65d273e6
```

**Tip:** You can try to make up an invalid ballot-tracker to see that
Expand Down Expand Up @@ -119,11 +122,11 @@ appropiate version to use in your case.

> :warning: **Note** You need to change the `INTERNAL_GIT_VERSION` you should be
using depending on the version of [Sequent] platform used to run the election you
want to verify. In this example, we're using version `5.0.0` of [Sequent]
want to verify. In this example, we're using version `10.2.0` of [Sequent]
platform.

```bash
export INTERNAL_GIT_VERSION="5.0.0"
export INTERNAL_GIT_VERSION="10.2.0"
git clone https://github.com/sequentech/election-verifier.git
cd election-verifier
git checkout "${INTERNAL_GIT_VERSION}"
Expand Down Expand Up @@ -152,7 +155,7 @@ This will generate the `election-verifier` executable in the current working
directory. You can see it's working by running:

```bash
./election-verifier testdata/12.tar
bash ./election-verifier testdata/8.tar
```

**4. Notes on `lib/mixnet.jar`**
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

name := "election-verifier"

version := "master"
version := "10.2.0"

scalaVersion := "2.10.3"

Expand Down
Binary file modified lib/mixnet.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ rm -r -f dist
mkdir dist
cp -r tally_methods dist
cp -r tally_pipes dist
cp target/scala-2.10/proguard/election-verifier_2.10-master.jar dist
cp target/scala-2.10/proguard/election-verifier_2.10-10.2.0.jar dist
cp pverify.sh dist
cp vmnc.sh dist
cp verify.py dist
Expand Down
6 changes: 3 additions & 3 deletions project.spdx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ creationInfo:
- "Organization: Sequent Tech Inc."
- "Person: Eduardo Robles"
licenseListVersion: "3.9"
name: "election-verifier-master"
name: "election-verifier-10.2.0"
dataLicense: "CC0-1.0"
documentNamespace: "http://sequentech.io/spdxdocs/spdx-document-election-verifier-0d6261e7-2d52-4eb7-9d3d-2091a35978ab"
documentDescribes:
Expand All @@ -15,13 +15,13 @@ packages:
- SPDXID: "SPDXRef-Package-election-verifier"
summary: "election-verifier performs tally and cryptographic verification of the election process, including key generation, shuffling and joint-decryption."
copyrightText: "Copyright 2015-2021 Sequent Tech Inc and others"
downloadLocation: "git+https://github.com/sequentech/election-verifier.git@master"
downloadLocation: "git+https://github.com/sequentech/election-verifier.git@10.2.0"
filesAnalyzed: false
homepage: "https://github.com/sequentech/election-verifier"
licenseConcluded: "NOASSERTION"
licenseDeclared: "AGPL-3.0-only"
name: "election-verifier"
versionInfo: "master"
versionInfo: "10.2.0"
- SPDXID: "SPDXRef-Package-tally-methods"
description: "sequent base tallying system."
copyrightText: "Copyright 2014 - 2021 Sequent Tech Inc and others"
Expand Down
2 changes: 1 addition & 1 deletion pverify.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ fi

command -v java >/dev/null 2>&1 || { echo >&2 "* I require java but it's not installed. Aborting."; exit 1; }

java -Djava.security.egd=file:/dev/./urandom -classpath election-verifier_2.10-master.jar org.sequent.sequent.Verifier $1 $2
java -Djava.security.egd=file:/dev/./urandom -classpath election-verifier_2.10-10.2.0.jar org.sequent.sequent.Verifier $1 $2
exit $?
Binary file removed testdata/12.tar
Binary file not shown.
Binary file removed testdata/12_wrong_ballots.tar
Binary file not shown.
Binary file removed testdata/12_wrong_proof_of_shuffle.tar
Binary file not shown.
Binary file removed testdata/12_wrong_results.tar
Binary file not shown.
Binary file added testdata/8.tar
Binary file not shown.
Binary file added testdata/8_vote_weight.tar
Binary file not shown.
Binary file added testdata/8_wrong_ballots.tar
Binary file not shown.
Binary file added testdata/8_wrong_proof_of_shuffle.tar
Binary file not shown.
Binary file added testdata/8_wrong_results.tar
Binary file not shown.
71 changes: 47 additions & 24 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import unittest
import subprocess

def run_command(command, return_code=None, **kwargs):
def run_command(command, return_code=None, stdout_contains_text=None, **kwargs):
'''
Utility to run a command.
timeout is in seconds.
Expand All @@ -28,20 +28,29 @@ def run_command(command, return_code=None, **kwargs):
process = subprocess.run(
command,
check=True,
stdout=subprocess.PIPE,
**kwargs
)
return process
except subprocess.CalledProcessError as error:
if return_code == None or error.returncode != return_code:
raise error
finally:
if stdout_contains_text:
if not process.stdout:
raise Exception(f"`{stdout_contains_text}` not in stdout")
process_stdout = process.stdout.decode('utf-8')
for check_text in stdout_contains_text:
if check_text not in process_stdout:
raise Exception(f"`{check_text}` not in process_stdout")

class TestStringMethods(unittest.TestCase):
def test_election_12(self):
def test_election_8(self):
'''
Validates the example proofs for election 12.tar
Validates the example proofs for election 8.tar
'''
run_command(
command=["./election-verifier", "./testdata/12.tar"],
command=["./election-verifier", "./testdata/8.tar"],
)

def test_election_invalid_file(self):
Expand All @@ -53,44 +62,44 @@ def test_election_invalid_file(self):
return_code=1
)

def test_election_12_wrong_ballots(self):
def test_election_8_wrong_ballots(self):
'''
The election proofs fail because the ballots.json file
is wrong
'''
run_command(
command=["./election-verifier", "./testdata/12_wrong_ballots.tar"],
command=["./election-verifier", "./testdata/8_wrong_ballots.tar"],
return_code=1
)

def test_election_12_wrong_proof_of_shuffle(self):
def test_election_8_wrong_proof_of_shuffle(self):
'''
The election proofs fail because the proofs of shuffle (file
0-78172fa2-42f5-4854-bd2e-5e3015e7e23e/proofs/CCPoSCommitment01.bt)
0-78b10d61-d525-4aca-998f-cad2f200a1bf/proofs/CCPoSCommitment01.bt)
have been tampered with.
'''
run_command(
command=[
"./election-verifier",
"./testdata/12_wrong_proof_of_shuffle.tar"
"./testdata/8_wrong_proof_of_shuffle.tar"
],
return_code=1
)

def test_election_12_wrong_proof_of_shuffle_existing_ballot(self):
def test_election_8_wrong_proof_of_shuffle_existing_ballot(self):
'''
The ballot hash locator finds the ballot, because although the
proof of shuffle was tampered with, the ballots.json file was not.
'''
run_command(
command=[
"./election-verifier",
"./testdata/12_wrong_proof_of_shuffle.tar",
"09684d8abd01c2227432bc6302e669fac4e4b3e7251f24c4a9c938683fa44705"
"./testdata/8_wrong_proof_of_shuffle.tar",
"ae38e56fd663c142387ad9f69d710e9afd1e8c28da3f0ba93facdaae65d273e6"
]
)

def test_election_12_wrong_proof_of_shuffle_nonexisting_ballot(self):
def test_election_8_wrong_proof_of_shuffle_nonexisting_ballot(self):
'''
The ballot hash locator cannot find the ballot. The proof of shuffle was
tampered with, the ballots.json file was not. The tampering does not
Expand All @@ -100,61 +109,75 @@ def test_election_12_wrong_proof_of_shuffle_nonexisting_ballot(self):
run_command(
command=[
"./election-verifier",
"./testdata/12_wrong_proof_of_shuffle.tar",
"09684d8abd01c2227432bc6302e669fac4e4b3e7251f24c4a9c938683fa44701"
"./testdata/8_wrong_proof_of_shuffle.tar",
"ae38e56fd663c142387ad9f69d710e9afd1e8c28da3f0ba93facdaae65d273e5"
],
return_code=1
)

def test_election_12_wrong_results(self):
def test_election_8_wrong_results(self):
'''
The election proofs fail because the results have been tampered with.
'''
run_command(
command=[
"./election-verifier",
"./testdata/12_wrong_results.tar"
"./testdata/8_wrong_results.tar"
],
return_code=1
)

def test_election_12_existing_ballot(self):
def test_election_8_existing_ballot(self):
'''
The ballot is located in the ballots.json file.
'''
run_command(
command=[
"./election-verifier",
"./testdata/12.tar",
"09684d8abd01c2227432bc6302e669fac4e4b3e7251f24c4a9c938683fa44705"
"./testdata/8.tar",
"ae38e56fd663c142387ad9f69d710e9afd1e8c28da3f0ba93facdaae65d273e6"
],
stdout_contains_text=["weight=1"]
)

def test_election_12_nonexisting_ballots(self):
def test_election_8_existing_ballot_vote_weight(self):
'''
The ballot is located in the ballots.json file.
'''
run_command(
command=[
"./election-verifier",
"./testdata/8_vote_weight.tar",
"ae38e56fd663c142387ad9f69d710e9afd1e8c28da3f0ba93facdaae65d273e6"
],
stdout_contains_text=["weight=2"]
)

def test_election_8_nonexisting_ballots(self):
'''
The ballot is not located in the ballots.json file, because it's not
there.
'''
run_command(
command=[
"./election-verifier",
"./testdata/12.tar",
"./testdata/8.tar",
"09684d8abd01c2227432bc6302e669fac4e4b3e7251f24c4a9c938683fa44704"
],
return_code=1
)
run_command(
command=[
"./election-verifier",
"./testdata/12.tar",
"./testdata/8.tar",
"deadbeef"
],
return_code=1
)
run_command(
command=[
"./election-verifier",
"./testdata/12.tar",
"./testdata/8.tar",
"whatever"
],
return_code=1
Expand Down
Loading

0 comments on commit 598fe2a

Please sign in to comment.