1use ark_ed_on_bn254::Fq;
2use ark_ff::{BigInteger, PrimeField};
3use ethers_core::utils::keccak256;
4use num_bigint::BigUint;
5use reqwest::blocking::Client;
6use std::error::Error;
7use std::fs::File;
8use std::io::copy;
9
10use crate::group::{EMPTY_ELEMENT, Element};
11
12pub fn string_to_biguint(num_str: &str) -> BigUint {
13 num_str
14 .parse()
15 .expect("Failed to parse the string into BigUint")
16}
17
18pub fn hash(message: BigUint) -> String {
19 let mut h = BigUint::from_bytes_be(&keccak256(message.to_bytes_be()));
20 h >>= 8;
21 h.to_string()
22}
23
24pub fn to_big_uint(str: &String) -> BigUint {
26 let bytes = str.as_bytes();
27 assert!(bytes.len() <= 32, "BigUint too large: exceeds 32 bytes");
28 let mut fixed_bytes = [0u8; 32];
29 fixed_bytes[0..bytes.len()].copy_from_slice(bytes);
30 BigUint::from_bytes_be(&fixed_bytes)
31}
32
33pub fn to_element(value: Fq) -> Element {
35 let mut element = EMPTY_ELEMENT;
36 let bytes = value.into_bigint().to_bytes_le();
37 element[..bytes.len()].copy_from_slice(&bytes);
38 element
39}
40
41pub fn download_zkey(depth: u16) -> Result<String, Box<dyn Error>> {
43 let version = "4.13.0";
44 let base_url = format!("https://snark-artifacts.pse.dev/semaphore/{version}/");
45 let filename = format!("semaphore-{depth}.zkey");
46 let dest_filename = format!("semaphore-{version}-{depth}.zkey");
47 let out_dir = std::env::temp_dir();
48 let dest_path = out_dir.join(dest_filename.clone());
49 if !dest_path.exists() {
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 }
56 Ok(dest_path.to_string_lossy().into_owned())
57}