-
Notifications
You must be signed in to change notification settings - Fork 0
/
ballot_proof.circom
58 lines (56 loc) · 2.42 KB
/
ballot_proof.circom
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
pragma circom 2.1.0;
include "poseidon.circom";
include "./ballot_checker.circom";
include "./ballot_cipher.circom";
// BallotProof is the circuit to prove a valid vote in the Vocdoni scheme. The
// vote is valid if it meets the Ballot Protocol requirements, but also if the
// encrypted vote provided matches with the raw vote encrypted in this circuit.
// The circuit checks the the vote over the params provided using the
// BallotProtocol template, encodes the vote using the BallotEncoder template
// and compares the result with the encrypted vote.
template BallotProof(n_fields) {
// Ballot inputs
signal input fields[n_fields]; // private
signal input max_count; // public
signal input force_uniqueness; // public
signal input max_value; // public
signal input min_value; // public
signal input max_total_cost; // public
signal input min_total_cost; // public
signal input cost_exp; // public
signal input cost_from_weight; // public
signal input weight; // public
// ElGamal inputs
signal input pk[2]; // public
signal input k; // private
signal input cipherfields[n_fields][2][2]; // public
// Nullifier inputs
signal input nullifier; // public
signal input commitment; // private
signal input secret; // private
// 1. Check the vote meets the ballot requirements
component ballotProtocol = BallotChecker(n_fields);
ballotProtocol.fields <== fields;
ballotProtocol.max_count <== max_count;
ballotProtocol.force_uniqueness <== force_uniqueness;
ballotProtocol.max_value <== max_value;
ballotProtocol.min_value <== min_value;
ballotProtocol.max_total_cost <== max_total_cost;
ballotProtocol.min_total_cost <== min_total_cost;
ballotProtocol.cost_exp <== cost_exp;
ballotProtocol.cost_from_weight <== cost_from_weight;
ballotProtocol.weight <== weight;
// 2. Check the encrypted vote
component ballotCipher = BallotCipher(n_fields);
ballotCipher.pk <== pk;
ballotCipher.k <== k;
ballotCipher.fields <== fields;
ballotCipher.mask <== ballotProtocol.mask;
ballotCipher.cipherfields <== cipherfields;
ballotCipher.valid_fields === max_count;
// 3. Check the nullifier
component hash = Poseidon(2);
hash.inputs[0] <== commitment;
hash.inputs[1] <== secret;
hash.out === nullifier;
}