Skip to content

Commit 8b8b31e

Browse files
authored
chore: cross contract call to Solidity verifier (#92)
1 parent 928dd99 commit 8b8b31e

File tree

17 files changed

+15160
-0
lines changed

17 files changed

+15160
-0
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Dependencies
2+
node_modules/
3+
npm-debug.log*
4+
yarn-debug.log*
5+
yarn-error.log*
6+
7+
# Environment variables
8+
.env
9+
.env.local
10+
.env.development.local
11+
.env.test.local
12+
.env.production.local
13+
14+
# Build outputs
15+
circuits/target/
16+
circuits/proofs/
17+
contracts/artifacts/
18+
contracts/cache/
19+
frontend/build/
20+
frontend/dist/
21+
22+
# IDE
23+
.vscode/
24+
.idea/
25+
*.swp
26+
*.swo
27+
28+
# OS
29+
.DS_Store
30+
Thumbs.db
31+
32+
# Logs
33+
*.log
34+
logs/
35+
36+
# Temporary files
37+
*.tmp
38+
*.temp
39+
40+
41+
Prover.toml
42+
Verifier.toml
43+
*.wasm
44+
*.vk
45+
*.pk
46+
*.proof
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Anonymous ZK Poll App
2+
3+
This project demonstrates an anonymous polling application leveraging Zero-Knowledge (ZK) proofs to ensure unique participation without revealing user identities. It utilizes Noir for ZK circuit development.
4+
5+
## Features (Planned)
6+
7+
- Anonymous Voting: Users can cast votes without revealing their identity.
8+
9+
- Unique Participation: ZK proofs prevent double-voting.
10+
11+
- Real-time Results: Poll results are updated in real-time.
12+
13+
- Scalable Architecture: Designed with clear separation of concerns for future expansion.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[package]
2+
name = "circuits"
3+
type = "bin"
4+
authors = [""]
5+
6+
[dependencies]
7+
8+
# Configuration for the circuit
9+
[circuit]
10+
# Maximum number of constraints (adjust based on your needs)
11+
max_constraints = 100000
12+
13+
# Backend configuration
14+
[backend]
15+
# Use Barretenberg backend (default)
16+
backend = "barretenberg"
17+
18+
# Optimization settings
19+
[optimization]
20+
# Enable optimizations for smaller proof size
21+
optimize_for_size = true
22+
23+
# Enable parallel proving (if supported)
24+
enable_parallel = true
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use dep::std;
2+
3+
global MERKLE_TREE_DEPTH: u32 = 20;
4+
5+
fn main(user_secret: Field,
6+
vote_choice: Field,
7+
merkle_path: [Field; MERKLE_TREE_DEPTH],
8+
merkle_indices: [u1; MERKLE_TREE_DEPTH],
9+
merkle_root: pub Field,
10+
nullifier: pub Field,
11+
poll_id: pub Field,
12+
max_options: pub Field
13+
) {
14+
assert((vote_choice as u32) < (max_options as u32));
15+
assert((vote_choice as u32) >= 0);
16+
17+
// verify that the nullifier is correctly computed
18+
let computed_nullifier = std::hash::pedersen_hash([user_secret, poll_id]);
19+
// std::println(f"Computed nullifier: {computed_nullifier}");
20+
assert(nullifier == computed_nullifier);
21+
22+
// Verify that the user is in the eligible voters merkle tree
23+
let leaf = std::hash::pedersen_hash([user_secret]);
24+
// std::println(f"Leaf hash: {leaf}");
25+
let is_valid_member = verify_merkle_membership(
26+
leaf,
27+
merkle_root,
28+
merkle_path,
29+
merkle_indices
30+
);
31+
assert(is_valid_member);
32+
33+
// ensure user_secret is not 0
34+
assert(user_secret != 0);
35+
36+
std::println(f"Vote verified for poll {poll_id}");
37+
}
38+
39+
fn verify_merkle_membership(
40+
leaf: Field,
41+
root: Field,
42+
path: [Field; MERKLE_TREE_DEPTH],
43+
indices: [u1; MERKLE_TREE_DEPTH]
44+
) -> bool {
45+
let mut current = leaf;
46+
47+
// std::println(f"Starting with leaf: {leaf}");
48+
for i in 0..MERKLE_TREE_DEPTH {
49+
let path_element = path[i];
50+
// std::println(f"Step {i}: current = {current}, path_element = {path_element}");
51+
let is_right = indices[i];
52+
53+
if is_right == 0 {
54+
// Current is left child
55+
current = std::hash::pedersen_hash([current, path_element]);
56+
} else {
57+
// Current is right child
58+
current = std::hash::pedersen_hash([path_element, current]);
59+
}
60+
}
61+
// std::println(f"Final computed root: {current}");
62+
current == root
63+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Ignore build artifacts from the local tests sub-crate.
2+
/target/
3+
4+
# Ignore backup files creates by cargo fmt.
5+
**/*.rs.bk
6+
7+
# Remove Cargo.lock when creating an executable, leave it for libraries
8+
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
9+
Cargo.lock
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[package]
2+
name = "contracts"
3+
version = "0.1.0"
4+
authors = ["[your_name] <[your_email]>"]
5+
edition = "2021"
6+
7+
[dependencies]
8+
const-crypto = "0.3.0"
9+
ink = { version = "6.0.0-beta", default-features = false, features = ["unstable-hostfn"] }
10+
scale-info = { version = "2.11.6", default-features = false, features = ["derive"] }
11+
12+
[dev-dependencies]
13+
ink_e2e = "6.0.0-beta"
14+
15+
[lib]
16+
path = "lib.rs"
17+
18+
[features]
19+
default = ["std"]
20+
std = [
21+
"ink/std",
22+
"scale-info/std",
23+
]
24+
ink-as-dependency = []
25+
e2e-tests = []
26+
27+
[package.metadata.ink-lang]
28+
abi = "all"
29+
30+
[lints.rust.unexpected_cfgs]
31+
level = "warn"
32+
check-cfg = [
33+
'cfg(ink_abi, values("ink", "sol", "all"))'
34+
]

0 commit comments

Comments
 (0)