Skip to content

Commit

Permalink
Integrate with solidity implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
georgwiese committed Dec 29, 2022
1 parent 5b9dba5 commit db2c83d
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 34 deletions.
54 changes: 29 additions & 25 deletions contracts/Ballot.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

pragma solidity >=0.7.0 <0.9.0;

import "hardhat/console.sol";

contract Ballot {
struct Voter {
bool hasRightToVote;
Expand All @@ -24,6 +26,7 @@ contract Ballot {
uint256 public yesCount;
uint256 public voteCount;
address public verifierContractAddress;
uint256 public merkleRoot;

constructor(address _verifierContractAddress) {
chairperson = msg.sender;
Expand Down Expand Up @@ -52,15 +55,27 @@ contract Ballot {
commitList.push(commit);
}

function setMerkleRoot(uint256 newMerkleRoot) public {
require(
msg.sender == chairperson,
"Only chairperson can set the merkle root!"
);
merkleRoot = newMerkleRoot;
}

function revealVote(
bool _vote,
bytes32 serialNumber,
bytes32[10] memory commitsForProof,
Verifier.Proof memory proof
) public {
require(
merkleRoot != 0,
"Merkle root has not been set by the chairperson!"
);

// validate proof
// call sokrates
uint256[85] memory proof_inputs;
uint256[13] memory proof_inputs;
uint256 j = 0;
if (_vote) {
proof_inputs[j] = 1;
Expand All @@ -77,28 +92,22 @@ contract Ballot {
break;
}
}
for (uint256 c_index = 0; c_index < 10; c_index++) {
bytes32 commit = commitsForProof[c_index];
for (uint256 i = 7; i >= 0; i--) {
proof_inputs[j] = uint256(commit >> (i * 32)) & 0xffffffff;
j += 1;
if (i == 0) {
break;
}
for (uint256 i = 7; i >= 0; --i) {
proof_inputs[j] = uint256(merkleRoot >> (i * 32)) & 0xffffffff;
j += 1;
if (i == 0) {
break;
}
}

Verifier v = Verifier(verifierContractAddress);
require(v.verifyTx(proof, proof_inputs));

// is commitsForProof subset of commits
for (uint256 i = 0; i < commitsForProof.length; ++i) {
bytes32 commitInProof = commitsForProof[i];
if (commitInProof != 0) {
require(commits[commitInProof]);
}
console.log("Inputs:");
for (uint256 i = 0; i < 13; i++) {
console.log(proof_inputs[i]);
}

Verifier v = Verifier(verifierContractAddress);
require(v.verifyTx(proof, proof_inputs), "Proof does not verify!");

require(!seenSerialNumbers[serialNumber], "Already revealed!");
seenSerialNumbers[serialNumber] = true;

Expand Down Expand Up @@ -126,12 +135,7 @@ interface Verifier {
G1Point c;
}

function verifyTx(Proof memory proof, uint256[85] memory input)
external
view
returns (bool r);

function testVerifyTx(Proof memory proof, uint256[85] memory input)
function verifyTx(Proof memory proof, uint256[13] memory input)
external
view
returns (bool r);
Expand Down
11 changes: 5 additions & 6 deletions src/provers.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from abc import ABC, abstractmethod
import hashlib
import shutil
import os
from pathlib import Path
import json
import math
from typing import List, Tuple
import os
import shutil
from abc import ABC, abstractmethod
from pathlib import Path
from tempfile import TemporaryDirectory
import time
from typing import List, Tuple

from zokrates_pycrypto.gadgets.pedersenHasher import PedersenHasher

Expand Down
32 changes: 29 additions & 3 deletions src/vote_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from Crypto.Signature import PKCS1_v1_5
from web3 import Web3

from provers import ZokratesProver
from provers import MERKLE_TREE_DEPTH, ZokratesProver, calculate_merkle_tree

VOTE_SERVER = "http://0.0.0.0:5000"
PROVER = ZokratesProver(Path("."))
Expand Down Expand Up @@ -131,6 +131,27 @@ def eth_give_right_to_vote(address: str):
voting_contract = get_voting_contract(voting_contract_address, w3)
send_transaction(w3, voting_contract.functions.giveRightToVote(address).build_transaction())

@app.command()
def eth_set_merkle_root():
w3 = Web3(Web3.HTTPProvider(HTTP_ENDPOINT_URL))
voting_contract_address = get_deployed_contract_address()
voting_contract = get_voting_contract(voting_contract_address, w3)

num_commits = voting_contract.functions.numCommits().call()
known_hashes = []
for i in range(num_commits):
known_hashes.append(voting_contract.functions.commitList(i).call())

# This actually computes the Merkle proof for the first commit, but we're only interested in the merkle root
print("Computing Merkle root...")
merkle_root, _, _ = calculate_merkle_tree(known_hashes, 2 ** MERKLE_TREE_DEPTH, known_hashes[0])

print(f"Merkle root is: {merkle_root.hex()}")
send_transaction(w3, voting_contract.functions.setMerkleRoot(int(merkle_root.hex(), 16)).build_transaction({
# Gas estimation fails for some reason, so set limit manually
"gas": 2000000
}))

@app.command()
def eth_vote(vote: bool):

Expand Down Expand Up @@ -185,13 +206,18 @@ def eth_reveal():
for i in range(num_commits):
known_hashes.append(voting_contract.functions.commitList(i).call())

proof, known_hashes = PROVER.compute_proof(serial_number, secret, vote, known_hashes)
proof, merkle_root = PROVER.compute_proof(serial_number, secret, vote, known_hashes)
print(f"Merkle root is: {merkle_root.hex()}")
merkle_root_int = int(merkle_root.hex(), 16)
stored_merkle_root = voting_contract.functions.merkleRoot().call()
assert stored_merkle_root != 0, "The chairperson has not set the Merkle root yet!"
assert stored_merkle_root == merkle_root_int, "Merkle Root is different from what was set by the chairperson!"

def to_ints(hex_str):
return (int(hex_str[0], 16), int(hex_str[1], 16))

proof_abc = (to_ints(proof["proof"]["a"]), (to_ints(proof["proof"]["b"][0]), to_ints(proof["proof"]["b"][1])), to_ints(proof["proof"]["c"]))
tx = voting_contract.functions.revealVote(vote, serial_number, known_hashes, proof_abc).build_transaction()
tx = voting_contract.functions.revealVote(vote, serial_number, proof_abc).build_transaction()
send_transaction(w3, tx)


Expand Down
1 change: 1 addition & 0 deletions test_eth.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ python src/vote_cli.py eth-deploy-voting-contract
# Right to vote for second hardhat account
#python src/vote_cli.py eth-give-right-to-vote 0x70997970C51812dc3A010C7d01b50e0d17dc79C8
python src/vote_cli.py eth-vote yes
python src/vote_cli.py eth-set-merkle-root
python src/vote_cli.py eth-reveal
python src/vote_cli.py eth-get-results

0 comments on commit db2c83d

Please sign in to comment.