Skip to content

Commit 674d723

Browse files
committed
refactor: remove build.rs and integrate zkey downloading into utils
- Deleted the `build.rs` file, which previously handled downloading semaphore artifacts. - Introduced a new `download_zkey` function in `utils.rs` to manage zkey downloads. - Updated `proof.rs` to utilize the new `download_zkey` function for fetching zkeys dynamically based on tree depth. - Added a new `witness.rs` file to handle witness dispatching based on tree depth. - Updated `Cargo.toml` to remove `rust-witness` dependency and adjust `circom-prover` to use the latest version from the main branch. - Added multiple witness graph binary files for different depths.
1 parent 0d2c7e4 commit 674d723

39 files changed

+1664
-385
lines changed

Cargo.lock

Lines changed: 1452 additions & 292 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ thiserror = "2.0.12"
1111
num-traits = "0.2.19"
1212
ethers-core = "2.0.14"
1313
anyhow = "1.0.97"
14+
reqwest = { version = "0.12.15", features = ["blocking"] }
15+
openssl = { version = "0.10", features = ["vendored"] }
1416

1517
# arkworks
1618
ark-ec = { version = "=0.5.0", default-features = false }
@@ -25,16 +27,10 @@ serde = { version = "1", features = ["derive"], optional = true }
2527
serde_json = "1"
2628

2729
# circom-prover
28-
rust-witness = "0.1"
29-
circom-prover = "=0.1.1"
30+
circom-prover = { git = "https://github.com/zkmopro/mopro.git", branch = "main", features = [
31+
"circom-witnesscalc",
32+
] }
3033

3134
[features]
3235
default = []
33-
serde = [
34-
"dep:serde",
35-
"zk-kit-lean-imt/serde"
36-
]
37-
38-
[build-dependencies]
39-
rust-witness = "0.1"
40-
reqwest = { version = "0.12.15", features = ["blocking", "json"] }
36+
serde = ["dep:serde", "zk-kit-lean-imt/serde"]

build.rs

Lines changed: 0 additions & 66 deletions
This file was deleted.

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub mod group;
99
pub mod identity;
1010
pub mod proof;
1111
pub mod utils;
12+
pub mod witness;
1213

1314
pub const MIN_TREE_DEPTH: u16 = 1;
1415
pub const MAX_TREE_DEPTH: u16 = 32;

src/proof.rs

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,25 @@
11
use crate::{
2-
MAX_TREE_DEPTH, MIN_TREE_DEPTH,
3-
group::{EMPTY_ELEMENT, Element, Group, MerkleProof},
2+
group::{Element, Group, MerkleProof, EMPTY_ELEMENT},
43
identity::Identity,
5-
utils::{hash, to_big_uint, to_element},
4+
utils::{download_zkey, hash, to_big_uint, to_element},
5+
witness::dispatch_witness,
6+
MAX_TREE_DEPTH, MIN_TREE_DEPTH,
67
};
7-
use anyhow::{Ok, Result, bail};
8+
use anyhow::{bail, Ok, Result};
89
use circom_prover::{
9-
CircomProver,
1010
prover::{
11-
CircomProof, ProofLib, PublicInputs,
1211
circom::{self, CURVE_BN254, G1, G2, PROTOCOL_GROTH16},
12+
CircomProof, ProofLib, PublicInputs,
1313
},
1414
witness::WitnessFn,
15+
CircomProver,
1516
};
1617
use num_bigint::BigUint;
17-
use num_traits::{Zero, identities::One};
18-
use std::{collections::HashMap, str::FromStr};
19-
20-
// Prepare witness generator
21-
rust_witness::witness!(semaphore);
18+
use num_traits::{identities::One, Zero};
19+
use std::{collections::HashMap, str::FromStr, time::Instant};
2220

2321
pub type PackedGroth16Proof = [BigUint; 8];
2422

25-
const ZKEY_PATH: &str = "./zkey/semaphore.zkey";
26-
2723
pub enum GroupOrMerkleProof {
2824
Group(Group),
2925
MerkleProof(MerkleProof),
@@ -112,12 +108,25 @@ impl Proof {
112108
("message".to_string(), vec![hash(message_uint.clone())]),
113109
]);
114110

111+
let start = Instant::now();
112+
let zkey_path = download_zkey(merkle_tree_depth).expect("Failed to download zkey");
113+
let duration = start.elapsed();
114+
println!("download zkey time: {:?}", duration.as_micros());
115+
116+
let start = Instant::now();
117+
let witness_fn = dispatch_witness(merkle_tree_depth);
118+
let duration = start.elapsed();
119+
println!("dispatch witness time: {:?}", duration.as_micros());
120+
121+
let start = Instant::now();
115122
let circom_proof = CircomProver::prove(
116123
ProofLib::Arkworks,
117-
WitnessFn::RustWitness(semaphore_witness),
124+
WitnessFn::CircomWitnessCalc(witness_fn),
118125
serde_json::to_string(&inputs).unwrap(),
119-
ZKEY_PATH.to_string(),
126+
zkey_path,
120127
)?;
128+
let duration = start.elapsed();
129+
println!("semaphore proof time: {:?}", duration.as_micros());
121130

122131
Ok(SemaphoreProof {
123132
merkle_tree_depth,
@@ -148,7 +157,8 @@ impl Proof {
148157
pub_inputs,
149158
};
150159

151-
CircomProver::verify(ProofLib::Arkworks, p, ZKEY_PATH.to_string()).unwrap()
160+
let zkey_path = download_zkey(proof.merkle_tree_depth).expect("Failed to download zkey");
161+
CircomProver::verify(ProofLib::Arkworks, p, zkey_path).unwrap()
152162
}
153163

154164
pub fn pack_groth16_proof(p: circom::Proof) -> PackedGroth16Proof {
@@ -390,6 +400,27 @@ mod tests {
390400
assert!(Proof::verify_proof(proof))
391401
}
392402

403+
#[test]
404+
fn test_verify_proof_with_different_depth() {
405+
for depth in MIN_TREE_DEPTH..=MAX_TREE_DEPTH {
406+
println!("Testing depth: {}", depth);
407+
let identity = Identity::new("secret".as_bytes());
408+
let group =
409+
Group::new(&[MEMBER1, MEMBER2, to_element(*identity.commitment())]).unwrap();
410+
411+
let proof = Proof::generate_proof(
412+
identity,
413+
GroupOrMerkleProof::Group(group),
414+
MESSAGE.to_string(),
415+
SCOPE.to_string(),
416+
depth as u16,
417+
)
418+
.unwrap();
419+
420+
assert!(Proof::verify_proof(proof));
421+
}
422+
}
423+
393424
#[test]
394425
fn test_panic_verify_invalid_tree_depth() {
395426
let identity = Identity::new("secret".as_bytes());

src/utils.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ use ark_ed_on_bn254::Fq;
22
use ark_ff::{BigInteger, PrimeField};
33
use ethers_core::utils::keccak256;
44
use num_bigint::BigUint;
5+
use reqwest::blocking::Client;
6+
use std::error::Error;
7+
use std::fs::File;
8+
use std::io::copy;
59

6-
use crate::group::{EMPTY_ELEMENT, Element};
10+
use crate::group::{Element, EMPTY_ELEMENT};
711

812
pub fn string_to_biguint(num_str: &str) -> BigUint {
913
num_str
@@ -33,3 +37,21 @@ pub fn to_element(value: Fq) -> Element {
3337
element[..bytes.len()].copy_from_slice(&bytes);
3438
element
3539
}
40+
41+
/// Download zkey from artifacts: https://snark-artifacts.pse.dev/
42+
pub fn download_zkey(depth: u16) -> Result<String, Box<dyn Error>> {
43+
let base_url = "https://snark-artifacts.pse.dev/semaphore/latest/";
44+
let filename = format!("semaphore-{}.zkey", depth);
45+
let out_dir = std::env::temp_dir();
46+
let dest_path = out_dir.join(filename.clone());
47+
if dest_path.exists() {
48+
return Ok(dest_path.to_string_lossy().into_owned());
49+
}
50+
let url = format!("{}{}", base_url, filename);
51+
let client = Client::new();
52+
let mut resp = client.get(&url).send()?.error_for_status()?;
53+
let mut out = File::create(&dest_path)?;
54+
copy(&mut resp, &mut out)?;
55+
eprintln!("Saved as {}", dest_path.display());
56+
Ok(dest_path.to_string_lossy().into_owned())
57+
}

src/witness.rs

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
use circom_prover::graph;
2+
3+
pub fn dispatch_witness(depth: u16) -> fn(&str) -> anyhow::Result<Vec<u8>> {
4+
match depth {
5+
1_u16 => {
6+
graph!(semaphore1, "../witness_graph/semaphore-1.bin");
7+
semaphore1_witness
8+
}
9+
2_u16 => {
10+
graph!(semaphore2, "../witness_graph/semaphore-2.bin");
11+
semaphore2_witness
12+
}
13+
3_u16 => {
14+
graph!(semaphore3, "../witness_graph/semaphore-3.bin");
15+
semaphore3_witness
16+
}
17+
4_u16 => {
18+
graph!(semaphore4, "../witness_graph/semaphore-4.bin");
19+
semaphore4_witness
20+
}
21+
5_u16 => {
22+
graph!(semaphore5, "../witness_graph/semaphore-5.bin");
23+
semaphore5_witness
24+
}
25+
6_u16 => {
26+
graph!(semaphore6, "../witness_graph/semaphore-6.bin");
27+
semaphore6_witness
28+
}
29+
7_u16 => {
30+
graph!(semaphore7, "../witness_graph/semaphore-7.bin");
31+
semaphore7_witness
32+
}
33+
8_u16 => {
34+
graph!(semaphore8, "../witness_graph/semaphore-8.bin");
35+
semaphore8_witness
36+
}
37+
9_u16 => {
38+
graph!(semaphore9, "../witness_graph/semaphore-9.bin");
39+
semaphore9_witness
40+
}
41+
10_u16 => {
42+
graph!(semaphore10, "../witness_graph/semaphore-10.bin");
43+
semaphore10_witness
44+
}
45+
11_u16 => {
46+
graph!(semaphore11, "../witness_graph/semaphore-11.bin");
47+
semaphore11_witness
48+
}
49+
12_u16 => {
50+
graph!(semaphore12, "../witness_graph/semaphore-12.bin");
51+
semaphore12_witness
52+
}
53+
13_u16 => {
54+
graph!(semaphore13, "../witness_graph/semaphore-13.bin");
55+
semaphore13_witness
56+
}
57+
14_u16 => {
58+
graph!(semaphore14, "../witness_graph/semaphore-14.bin");
59+
semaphore14_witness
60+
}
61+
15_u16 => {
62+
graph!(semaphore15, "../witness_graph/semaphore-15.bin");
63+
semaphore15_witness
64+
}
65+
16_u16 => {
66+
graph!(semaphore16, "../witness_graph/semaphore-16.bin");
67+
semaphore16_witness
68+
}
69+
17_u16 => {
70+
graph!(semaphore17, "../witness_graph/semaphore-17.bin");
71+
semaphore17_witness
72+
}
73+
18_u16 => {
74+
graph!(semaphore18, "../witness_graph/semaphore-18.bin");
75+
semaphore18_witness
76+
}
77+
19_u16 => {
78+
graph!(semaphore19, "../witness_graph/semaphore-19.bin");
79+
semaphore19_witness
80+
}
81+
20_u16 => {
82+
graph!(semaphore20, "../witness_graph/semaphore-20.bin");
83+
semaphore20_witness
84+
}
85+
21_u16 => {
86+
graph!(semaphore21, "../witness_graph/semaphore-21.bin");
87+
semaphore21_witness
88+
}
89+
22_u16 => {
90+
graph!(semaphore22, "../witness_graph/semaphore-22.bin");
91+
semaphore22_witness
92+
}
93+
23_u16 => {
94+
graph!(semaphore23, "../witness_graph/semaphore-23.bin");
95+
semaphore23_witness
96+
}
97+
24_u16 => {
98+
graph!(semaphore24, "../witness_graph/semaphore-24.bin");
99+
semaphore24_witness
100+
}
101+
25_u16 => {
102+
graph!(semaphore25, "../witness_graph/semaphore-25.bin");
103+
semaphore25_witness
104+
}
105+
26_u16 => {
106+
graph!(semaphore26, "../witness_graph/semaphore-26.bin");
107+
semaphore26_witness
108+
}
109+
27_u16 => {
110+
graph!(semaphore27, "../witness_graph/semaphore-27.bin");
111+
semaphore27_witness
112+
}
113+
28_u16 => {
114+
graph!(semaphore28, "../witness_graph/semaphore-28.bin");
115+
semaphore28_witness
116+
}
117+
29_u16 => {
118+
graph!(semaphore29, "../witness_graph/semaphore-29.bin");
119+
semaphore29_witness
120+
}
121+
30_u16 => {
122+
graph!(semaphore30, "../witness_graph/semaphore-30.bin");
123+
semaphore30_witness
124+
}
125+
31_u16 => {
126+
graph!(semaphore31, "../witness_graph/semaphore-31.bin");
127+
semaphore31_witness
128+
}
129+
32_u16 => {
130+
graph!(semaphore32, "../witness_graph/semaphore-32.bin");
131+
semaphore32_witness
132+
}
133+
_ => panic!("Unsupported depth"),
134+
}
135+
}

witness_graph/semaphore-1.bin

147 KB
Binary file not shown.

witness_graph/semaphore-10.bin

234 KB
Binary file not shown.

witness_graph/semaphore-11.bin

245 KB
Binary file not shown.

0 commit comments

Comments
 (0)