Skip to content

Commit

Permalink
feat(zk-snarks): AG-32 defined voting program (#39)
Browse files Browse the repository at this point in the history
defined municipality election voting zk-snarks protocol
  • Loading branch information
g3k0 authored Apr 18, 2024
1 parent 970496f commit c166750
Show file tree
Hide file tree
Showing 18 changed files with 109 additions and 11 deletions.
7 changes: 2 additions & 5 deletions contracts/MunicipalityElection.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ contract MunicipalityElection is Election {
struct Candidate {
string name;
string candidatesFor; // major or councilor
uint256 points;
}

/// @dev the string key of the map correspond tho the party name registered in the parties mapping
Expand Down Expand Up @@ -112,8 +111,7 @@ contract MunicipalityElection is Election {

Candidate memory c = Candidate({
name: councilorCandidates[i],
candidatesFor: "councilor",
points: 0
candidatesFor: "councilor"
});

candidatesList.push(c);
Expand Down Expand Up @@ -143,8 +141,7 @@ contract MunicipalityElection is Election {

Candidate memory mcandidate = Candidate({
name: majorCandidate,
candidatesFor: "major",
points: 0
candidatesFor: "major"
});

Coalition memory newCoalition;
Expand Down
4 changes: 4 additions & 0 deletions election-scripts/__mocks__.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const MAJOR_CANDIDATE_2 = "Ugo Silenti";
export const PARTIES: Party[] = [
{
name: PARTY_NAME_A,
points: 0,
councilorCandidates: [
"Luigi Rossi",
"Maria Verdi",
Expand All @@ -50,6 +51,7 @@ export const PARTIES: Party[] = [
},
{
name: PARTY_NAME_B,
points: 0,
councilorCandidates: [
"Francesca Riti",
"Vanessa Reti",
Expand All @@ -60,6 +62,7 @@ export const PARTIES: Party[] = [
},
{
name: PARTY_NAME_C,
points: 0,
councilorCandidates: [
"Giuseppe Toni",
"Nicolò Movizzo",
Expand All @@ -70,6 +73,7 @@ export const PARTIES: Party[] = [
},
{
name: PARTY_NAME_D,
points: 0,
councilorCandidates: [
"Patrizio Pini",
"Mariagrazia Crudi",
Expand Down
3 changes: 0 additions & 3 deletions election-scripts/create-election.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ describe("Create Election Script", () => {
expect(coalitionFromContract[0][1]).to.equal(
coalition.majorCandidate.candidatesFor,
);
expect(coalitionFromContract[0][2]).to.equal(
coalition.majorCandidate.points,
);
expect(coalitionFromContract[1]).to.deep.equal(
coalition.parties.map((p) => p.name),
);
Expand Down
6 changes: 4 additions & 2 deletions election-scripts/create-election.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,15 @@ export async function main(
majorCandidate: {
name: coalition1Raw[0][0],
candidatesFor: coalition1Raw[0][1] as Candidature,
points: Number(coalition1Raw[0][2]),
points: 0,
},
parties: [],
};

for (const p of parties) {
for (const k of coalition1Raw[1]) {
if (k === p.name) {
p.points = 0;
coalition1.parties.push(p);
}
}
Expand All @@ -120,14 +121,15 @@ export async function main(
majorCandidate: {
name: coalition2Raw[0][0],
candidatesFor: coalition2Raw[0][1] as Candidature,
points: Number(coalition2Raw[0][2]),
points: 0,
},
parties: [],
};

for (const p of parties) {
for (const k of coalition2Raw[1]) {
if (k === p.name) {
p.points = 0;
coalition2.parties.push(p);
}
}
Expand Down
1 change: 1 addition & 0 deletions election-scripts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export type Candidate = {

export type Party = {
name: string;
points: number;
councilorCandidates: string[];
};

Expand Down
1 change: 0 additions & 1 deletion test/MunicipalityElection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ describe("MunicipalityElection Contract", function () {

expect(coalition[0][0]).to.be.equal(majorCandidate);
expect(coalition[0][1]).to.be.equal("major");
expect(coalition[0][2]).to.be.equal(0);
expect(coalition[1][0]).to.be.equal(partyName);
expect(coalition[1][1]).to.be.equal(partyNameB);
});
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
98 changes: 98 additions & 0 deletions zkProtocols/voting/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Municipality Election zk-SNARKS Voting proof

## About

This program implements a π-vote proof based on a municipality election smart contract deployed using the election-scripts.

The TypeScript script deploy the MunicipalityElection smart contract and registers parties and candidates using mock data.This must be done
before to generate the proof program.

In a real use case of this program, the circuit for the π-vote proof must be generated after the election
registration phase has closed, so that you know the ballot paper used by the Voter to vote.

Following the ballot paper for the municipalityElection generated by the ts script:

```json
{
"contractAddress":"0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9",
"coalitions":[
{
"majorCandidate":{
"name":"Pino Pini",
"candidatesFor":"major",
"points":0
},
"parties":[
{
"name":"Partito Democratico",
"councilorCandidates":[
"Luigi Rossi",
"Maria Verdi",
"Renato Bianchi",
"Francesco Guidi",
"Paolo Franchi"
],
"points":0
},
{
"name":"Forza Italia",
"councilorCandidates":[
"Francesca Riti",
"Vanessa Reti",
"Mario Checchi",
"Carlo Proni",
"Pierpaolo Pingitore"
],
"points":0
}
]
},
{
"majorCandidate":{
"name":"Ugo Silenti",
"candidatesFor":"major",
"points":0
},
"parties":[
{
"name":"Cinque Stelle",
"councilorCandidates":[
"Giuseppe Toni",
"Nicolò Movizzo",
"Alessandra Tonali",
"Antonella Chierici",
"Antonio Basso"
],
"points":0
},
{
"name":"Lega",
"councilorCandidates":[
"Patrizio Pini",
"Mariagrazia Crudi",
"Sabrina Giacigli",
"Marco Lioni",
"Pio Pedri"
],
"points":0
}
]
}
]
}
```

## Voting mechanism

The election is created assigning 20 voting points (see the `election-scripts/create-election.ts`).

Therefore, each voter can assign point to the major candidates and/or the parties
up to a maximum of 20 points totally.

It is possible to assign points to more that one major candidate at the same time and also to parties in different coalitions.

## What this program proofs

1. The sum of the points assigned to the candidates and the parties does not exceed 20;
2. Since a voter can assign negative points in that way that the sum is 20, the second proof verifies that the points assigned are positive integers;
3. The third proof consist to demonstrate that the voter knows for whom he/she is voting;
Empty file added zkProtocols/voting/root.zk
Empty file.

0 comments on commit c166750

Please sign in to comment.