diff --git a/bellman/src/groth16/mod.rs b/bellman/src/groth16/mod.rs index 8e70cc3..681bf7e 100644 --- a/bellman/src/groth16/mod.rs +++ b/bellman/src/groth16/mod.rs @@ -301,7 +301,7 @@ impl Parameters { .into_affine_unchecked() } .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { + .and_then(|e| if /*e.is_zero()*/false { Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) } else { Ok(e) @@ -320,7 +320,7 @@ impl Parameters { .into_affine_unchecked() } .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { + .and_then(|e| if /*e.is_zero()*/false { Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) } else { Ok(e) diff --git a/phase2/Cargo.toml b/phase2/Cargo.toml index d55bdce..9feda86 100644 --- a/phase2/Cargo.toml +++ b/phase2/Cargo.toml @@ -12,11 +12,16 @@ repository = "https://github.com/ebfull/phase2" rand = "0.4" bellman_ce = { path = "../bellman" } byteorder = "1" +exitcode = "1.1.2" num_cpus = "1" crossbeam = "0.3" blake2-rfc = "0.2" +blake2 = "0.6.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" memmap = "0.7" num-bigint = "0.2.3" num-traits = "0.2.8" +itertools = "0.8.1" +rust-crypto = "0.2" +hex-literal = "0.1" diff --git a/phase2/src/bin/beacon.rs b/phase2/src/bin/beacon.rs new file mode 100644 index 0000000..547362c --- /dev/null +++ b/phase2/src/bin/beacon.rs @@ -0,0 +1,92 @@ +extern crate rand; +extern crate phase2; +extern crate memmap; +extern crate num_bigint; +extern crate num_traits; +extern crate blake2; +extern crate byteorder; +extern crate exitcode; +extern crate itertools; +extern crate crypto; + +use itertools::Itertools; + +use std::fs::File; +use std::fs::OpenOptions; + +#[macro_use] +extern crate hex_literal; + +fn main() { + let args: Vec = std::env::args().collect(); + if args.len() != 3 { + println!("Usage: \n "); + std::process::exit(exitcode::USAGE); + } + let in_params_filename = &args[1]; + let out_params_filename = &args[2]; + + // Create an RNG based on the outcome of the random beacon + let mut rng = { + use byteorder::{ReadBytesExt, BigEndian}; + use rand::{SeedableRng}; + use rand::chacha::ChaChaRng; + use crypto::sha2::Sha256; + use crypto::digest::Digest; + + // Place block hash here (block number #564321) + let mut cur_hash: [u8; 32] = hex!("0000000000000000000a558a61ddc8ee4e488d647a747fe4dcc362fe2026c620"); + + // Performs 2^n hash iterations over it + const N: usize = 10; + + for i in 0..(1u64<().expect("digest is large enough for this to work"); + } + + ChaChaRng::from_seed(&seed) + }; + + println!("Done creating a beacon RNG"); + + let reader = OpenOptions::new() + .read(true) + .open(in_params_filename) + .expect("unable to open."); + let mut params = phase2::MPCParameters::read(reader, true).expect("unable to read params"); + + println!("Contributing to {}...", in_params_filename); + let hash = params.contribute(&mut rng); + println!("Contribution hash: 0x{:02x}", hash.iter().format("")); + + println!("Writing parameters to {}.", out_params_filename); + let mut f = File::create(out_params_filename).unwrap(); + params.write(&mut f).expect("failed to write updated parameters"); +} diff --git a/phase2/src/bin/contribute.rs b/phase2/src/bin/contribute.rs new file mode 100644 index 0000000..3a9087b --- /dev/null +++ b/phase2/src/bin/contribute.rs @@ -0,0 +1,72 @@ +extern crate rand; +extern crate phase2; +extern crate memmap; +extern crate num_bigint; +extern crate num_traits; +extern crate blake2; +extern crate byteorder; +extern crate exitcode; +extern crate itertools; + +use itertools::Itertools; + +use std::fs::File; +use std::fs::OpenOptions; + +fn main() { + let args: Vec = std::env::args().collect(); + if args.len() != 4 { + println!("Usage: \n "); + std::process::exit(exitcode::USAGE); + } + let in_params_filename = &args[1]; + let entropy = &args[2]; + let out_params_filename = &args[3]; + + // Create an RNG based on a mixture of system randomness and user provided randomness + let mut rng = { + use byteorder::{ReadBytesExt, BigEndian}; + use blake2::{Blake2b, Digest}; + use rand::{SeedableRng, Rng, OsRng}; + use rand::chacha::ChaChaRng; + + let h = { + let mut system_rng = OsRng::new().unwrap(); + let mut h = Blake2b::default(); + + // Gather 1024 bytes of entropy from the system + for _ in 0..1024 { + let r: u8 = system_rng.gen(); + h.input(&[r]); + } + + // Hash it all up to make a seed + h.input(&entropy.as_bytes()); + h.result() + }; + + let mut digest = &h[..]; + + // Interpret the first 32 bytes of the digest as 8 32-bit words + let mut seed = [0u32; 8]; + for i in 0..8 { + seed[i] = digest.read_u32::().expect("digest is large enough for this to work"); + } + + ChaChaRng::from_seed(&seed) + }; + + let reader = OpenOptions::new() + .read(true) + .open(in_params_filename) + .expect("unable to open."); + let mut params = phase2::MPCParameters::read(reader, true).expect("unable to read params"); + + println!("Contributing to {}...", in_params_filename); + let hash = params.contribute(&mut rng); + println!("Contribution hash: 0x{:02x}", hash.iter().format("")); + + println!("Writing parameters to {}.", out_params_filename); + let mut f = File::create(out_params_filename).unwrap(); + params.write(&mut f).expect("failed to write updated parameters"); +} diff --git a/phase2/src/bin/export_keys.rs b/phase2/src/bin/export_keys.rs new file mode 100644 index 0000000..0934127 --- /dev/null +++ b/phase2/src/bin/export_keys.rs @@ -0,0 +1,217 @@ +extern crate bellman_ce; +extern crate rand; +extern crate phase2; +extern crate memmap; +extern crate num_bigint; +extern crate num_traits; +extern crate exitcode; + +extern crate serde; +extern crate serde_json; + +use serde::{Deserialize, Serialize}; +use num_bigint::BigUint; +use num_traits::Num; + +use std::fs::OpenOptions; +use std::io::Write; +use std::ops::DerefMut; + +#[derive(Serialize, Deserialize)] +struct ProvingKeyJson { + #[serde(rename = "A")] + pub a: Vec>, + #[serde(rename = "B1")] + pub b1: Vec>, + #[serde(rename = "B2")] + pub b2: Vec>>, + #[serde(rename = "C")] + pub c: Vec>>, + pub vk_alfa_1: Vec, + pub vk_beta_1: Vec, + pub vk_delta_1: Vec, + pub vk_beta_2: Vec>, + pub vk_delta_2: Vec>, + #[serde(rename = "hExps")] + pub h: Vec>, +} + +#[derive(Serialize, Deserialize)] +struct VerifyingKeyJson { + #[serde(rename = "IC")] + pub ic: Vec>, + pub vk_alfa_1: Vec, + pub vk_beta_2: Vec>, + pub vk_gamma_2: Vec>, + pub vk_delta_2: Vec>, +} + +// Bring in some tools for using pairing-friendly curves +use bellman_ce::pairing::{ + Engine, + CurveAffine, + ff::PrimeField, +}; + +// We're going to use the BLS12-381 pairing-friendly elliptic curve. +use bellman_ce::pairing::bn256::{ + Bn256, +}; + +use std::collections::BTreeMap; + +#[derive(Serialize, Deserialize)] +struct CircuitJson { + pub constraints: Vec>>, + #[serde(rename = "nPubInputs")] + pub num_inputs: usize, + #[serde(rename = "nOutputs")] + pub num_outputs: usize, + #[serde(rename = "nVars")] + pub num_variables: usize, +} + +fn main() { + let args: Vec = std::env::args().collect(); + if args.len() != 4 { + println!("Usage: \n "); + std::process::exit(exitcode::USAGE); + } + let params_filename = &args[1]; + let vk_filename = &args[2]; + let pk_filename = &args[3]; + + println!("Exporting {}...", params_filename); + + let reader = OpenOptions::new() + .read(true) + .open(params_filename) + .expect("unable to open."); + let params = phase2::MPCParameters::read(reader, true).expect("unable to read params"); + let params = params.get_params(); + + let mut proving_key = ProvingKeyJson { + a: vec![], + b1: vec![], + b2: vec![], + c: vec![], + vk_alfa_1: vec![], + vk_beta_1: vec![], + vk_delta_1: vec![], + vk_beta_2: vec![], + vk_delta_2: vec![], + h: vec![], + }; + let repr_to_big = |r| { + BigUint::from_str_radix(&format!("{}", r)[2..], 16).unwrap().to_str_radix(10) + }; + + let p1_to_vec = |p : &::G1Affine| { + let mut v = vec![]; + //println!("test: {}", p.get_x().into_repr()); + let x = repr_to_big(p.get_x().into_repr()); + v.push(x); + let y = repr_to_big(p.get_y().into_repr()); + v.push(y); + if p.is_zero() { + v.push("0".to_string()); + } else { + v.push("1".to_string()); + } + v + }; + let p2_to_vec = |p : &::G2Affine| { + let mut v = vec![]; + let x = p.get_x(); + let mut x_v = vec![]; + x_v.push(repr_to_big(x.c0.into_repr())); + x_v.push(repr_to_big(x.c1.into_repr())); + v.push(x_v); + + let y = p.get_y(); + let mut y_v = vec![]; + y_v.push(repr_to_big(y.c0.into_repr())); + y_v.push(repr_to_big(y.c1.into_repr())); + v.push(y_v); + + if p.is_zero() { + v.push(["0".to_string(), "0".to_string()].to_vec()); + } else { + v.push(["1".to_string(), "0".to_string()].to_vec()); + } + + v + }; + let a = params.a.clone(); + for e in a.iter() { + proving_key.a.push(p1_to_vec(e)); + } + let b1 = params.b_g1.clone(); + for e in b1.iter() { + proving_key.b1.push(p1_to_vec(e)); + } + let b2 = params.b_g2.clone(); + for e in b2.iter() { + proving_key.b2.push(p2_to_vec(e)); + } + let c = params.l.clone(); + for _ in 0..params.vk.ic.len() { + proving_key.c.push(None); + } + for e in c.iter() { + proving_key.c.push(Some(p1_to_vec(e))); + } + + let vk_alfa_1 = params.vk.alpha_g1.clone(); + proving_key.vk_alfa_1 = p1_to_vec(&vk_alfa_1); + + let vk_beta_1 = params.vk.beta_g1.clone(); + proving_key.vk_beta_1 = p1_to_vec(&vk_beta_1); + + let vk_delta_1 = params.vk.delta_g1.clone(); + proving_key.vk_delta_1 = p1_to_vec(&vk_delta_1); + + let vk_beta_2 = params.vk.beta_g2.clone(); + proving_key.vk_beta_2 = p2_to_vec(&vk_beta_2); + + let vk_delta_2 = params.vk.delta_g2.clone(); + proving_key.vk_delta_2 = p2_to_vec(&vk_delta_2); + + let h = params.h.clone(); + for e in h.iter() { + proving_key.h.push(p1_to_vec(e)); + } + + let mut verification_key = VerifyingKeyJson { + ic: vec![], + vk_alfa_1: vec![], + vk_beta_2: vec![], + vk_gamma_2: vec![], + vk_delta_2: vec![], + }; + + let ic = params.vk.ic.clone(); + for e in ic.iter() { + verification_key.ic.push(p1_to_vec(e)); + } + + verification_key.vk_alfa_1 = p1_to_vec(&vk_alfa_1); + verification_key.vk_beta_2 = p2_to_vec(&vk_beta_2); + let vk_gamma_2 = params.vk.gamma_g2.clone(); + verification_key.vk_gamma_2 = p2_to_vec(&vk_gamma_2); + verification_key.vk_delta_2 = p2_to_vec(&vk_delta_2); + + let pk_file = OpenOptions::new().read(true).write(true).create_new(true).open(pk_filename).unwrap(); + let pk_json = serde_json::to_string(&proving_key).unwrap(); + pk_file.set_len(pk_json.len() as u64).expect("unable to write pk file"); + let mut mmap = unsafe { memmap::Mmap::map(&pk_file) }.unwrap().make_mut().unwrap(); + mmap.deref_mut().write_all(pk_json.as_bytes()).unwrap(); + + let vk_file = OpenOptions::new().read(true).write(true).create_new(true).open(vk_filename).unwrap(); + let vk_json = serde_json::to_string(&verification_key).unwrap(); + vk_file.set_len(vk_json.len() as u64).expect("unable to write vk file"); + let mut mmap = unsafe { memmap::Mmap::map(&vk_file) }.unwrap().make_mut().unwrap(); + mmap.deref_mut().write_all(vk_json.as_bytes()).unwrap(); + + println!("Created {} and {}.", pk_filename, vk_filename); +} diff --git a/phase2/src/bin/new.rs b/phase2/src/bin/new.rs new file mode 100644 index 0000000..d8b17a0 --- /dev/null +++ b/phase2/src/bin/new.rs @@ -0,0 +1,29 @@ +extern crate rand; +extern crate phase2; +extern crate exitcode; + +use std::fs::File; + +fn main() { + let args: Vec = std::env::args().collect(); + if args.len() != 3 { + println!("Usage: \n "); + std::process::exit(exitcode::USAGE); + } + let circuit_filename = &args[1]; + let params_filename = &args[2]; + + // Import the circuit and create the initial parameters using phase 1 + println!("Creating initial parameters for {}...", circuit_filename); + let should_filter_points_at_infinity = false; + let params = { + let c = phase2::CircomCircuit { + file_name: &circuit_filename, + }; + phase2::MPCParameters::new(c, should_filter_points_at_infinity).unwrap() + }; + + println!("Writing initial parameters to {}.", params_filename); + let mut f = File::create(params_filename).unwrap(); + params.write(&mut f).expect("unable to write params"); +} diff --git a/phase2/src/bin/verify_contribution.rs b/phase2/src/bin/verify_contribution.rs new file mode 100644 index 0000000..1b96fee --- /dev/null +++ b/phase2/src/bin/verify_contribution.rs @@ -0,0 +1,37 @@ +extern crate phase2; +extern crate exitcode; + +use std::fs::OpenOptions; + +fn main() { + let args: Vec = std::env::args().collect(); + if args.len() != 4 { + println!("Usage: \n "); + std::process::exit(exitcode::USAGE); + } + let circuit_filename = &args[1]; + let old_params_filename = &args[2]; + let new_params_filename = &args[3]; + + let old_reader = OpenOptions::new() + .read(true) + .open(old_params_filename) + .expect("unable to open old params"); + let old_params = phase2::MPCParameters::read(old_reader, true).expect("unable to read old params"); + + let new_reader = OpenOptions::new() + .read(true) + .open(new_params_filename) + .expect("unable to open new params"); + let new_params = phase2::MPCParameters::read(new_reader, true).expect("unable to read new params"); + + println!("Checking contribution {}...", new_params_filename); + let contribution = phase2::verify_contribution(&old_params, &new_params).expect("should verify"); + + let should_filter_points_at_infinity = false; + let verification_result = new_params.verify(phase2::CircomCircuit { + file_name: &circuit_filename, + }, should_filter_points_at_infinity).unwrap(); + assert!(phase2::contains_contribution(&verification_result, &contribution)); + println!("Contribution {} verified.", new_params_filename); +} diff --git a/phase2/src/lib.rs b/phase2/src/lib.rs index 6b9ac52..51fe3bf 100644 --- a/phase2/src/lib.rs +++ b/phase2/src/lib.rs @@ -269,6 +269,14 @@ use rand::{ SeedableRng }; +use std::collections::BTreeMap; + +use std::str; + +#[macro_use] +extern crate serde; +extern crate serde_json; + /// This is our assembly structure that we'll use to synthesize the /// circuit into a QAP. struct KeypairAssembly { @@ -438,8 +446,8 @@ impl MPCParameters { m *= 2; exp += 1; - // Powers of Tau ceremony can't support more than 2^21 - if exp > 21 { + // Powers of Tau ceremony can't support more than 2^28 + if exp > 28 { return Err(SynthesisError::PolynomialDegreeTooLarge) } } @@ -511,8 +519,8 @@ impl MPCParameters { let alpha_coeffs_g1 = Arc::new(alpha_coeffs_g1); let beta_coeffs_g1 = Arc::new(beta_coeffs_g1); - let mut h = Vec::with_capacity(m); - for i in 0..m { + let mut h = Vec::with_capacity(m-1); + for _ in 0..m-1 { h.push(read_g1(f)?); } @@ -1399,3 +1407,88 @@ pub fn contains_contribution( return false } + +#[derive(Serialize, Deserialize)] +struct CircuitJson { + pub constraints: Vec>>, + #[serde(rename = "nPubInputs")] + pub num_inputs: usize, + #[serde(rename = "nOutputs")] + pub num_outputs: usize, + #[serde(rename = "nVars")] + pub num_variables: usize, +} + +pub struct CircomCircuit<'a> { + pub file_name: &'a str, +} + +/// Our demo circuit implements this `Circuit` trait which +/// is used during paramgen and proving in order to +/// synthesize the constraint system. +impl<'a, E: Engine> Circuit for CircomCircuit<'a> { + fn synthesize>( + self, + cs: &mut CS + ) -> Result<(), SynthesisError> + { + let mmap = unsafe { memmap::Mmap::map(&File::open(self.file_name)?) }?; + let content = str::from_utf8(&mmap).unwrap(); + let circuit_json: CircuitJson = serde_json::from_str(&content).unwrap(); + let num_public_inputs = circuit_json.num_inputs + circuit_json.num_outputs + 1; + //println!("num public inputs: {}", num_public_inputs); + for i in 1..circuit_json.num_variables { + if i < num_public_inputs { + //println!("allocating public input {}", i); + cs.alloc_input(|| format!("variable {}", i), || { + //println!("variable {}: {}", i, &self.witness[i]); + Ok(E::Fr::from_str("1").unwrap()) + }); + } else { + //println!("allocating private input {}", i); + cs.alloc(|| format!("variable {}", i), || { + //println!("variable {}: {}", i, &self.witness[i]); + Ok(E::Fr::from_str("1").unwrap()) + }); + } + } + let mut constrained: BTreeMap = BTreeMap::new(); + let mut constraint_num = 0; + for (i, constraint) in circuit_json.constraints.iter().enumerate() { + let mut lcs = vec![]; + for lc_description in constraint { + let mut lc = LinearCombination::::zero(); + //println!("lc_description: {:?}, i: {}, len: {}", lc_description, i, constraint.len()); + for (var_index_str, coefficient_str) in lc_description { + //println!("var_index_str: {}, coefficient_str: {}", var_index_str, coefficient_str); + let var_index_num: usize = var_index_str.parse().unwrap(); + let var_index = if var_index_num < num_public_inputs { + Index::Input(var_index_num) + } else { + Index::Aux(var_index_num - num_public_inputs) + }; + constrained.insert(var_index_num, true); + if i == 2 { + lc = lc + (E::Fr::from_str(coefficient_str).unwrap(), Variable::new_unchecked(var_index)); + } else { + lc = lc + (E::Fr::from_str(coefficient_str).unwrap(), Variable::new_unchecked(var_index)); + } + } + lcs.push(lc); + } + cs.enforce(|| format!("constraint {}", constraint_num), |_| lcs[0].clone(), |_| lcs[1].clone(), |_| lcs[2].clone()); + constraint_num += 1; + } + println!("constraints: {}", circuit_json.constraints.len()); + let mut unconstrained: BTreeMap = BTreeMap::new(); + for i in 0..circuit_json.num_variables { + if !constrained.contains_key(&i) { + unconstrained.insert(i, true); + } + } + for (i, _) in unconstrained { + println!("variable {} is unconstrained", i); + } + Ok(()) + } +} \ No newline at end of file diff --git a/phase2/tools/vk2ethsnarks.py b/phase2/tools/vk2ethsnarks.py new file mode 100644 index 0000000..7e4a40e --- /dev/null +++ b/phase2/tools/vk2ethsnarks.py @@ -0,0 +1,48 @@ +import sys +import json + +def to_hex(d): + return hex(int(d)).rstrip('L') + return d + +class vk_ethsnarks(object): + def to_json(self): + return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) + +if len(sys.argv) != 3: + print("Usage: ") + print(" ") + +f = json.load(open(sys.argv[1])) + +vk = vk_ethsnarks() +# alpha +vk.alpha = [] +for i in range(2): + vk.alpha.append(to_hex(f["vk_alfa_1"][i])) +# beta +vk.beta = [[], []] +for i in range(2): + for j in range(2): + vk.beta[i].append(to_hex(f["vk_beta_2"][i][1-j])) +# gamma +vk.gamma = [[], []] +for i in range(2): + for j in range(2): + vk.gamma[i].append(to_hex(f["vk_gamma_2"][i][1-j])) +# delta +vk.delta = [[], []] +for i in range(2): + for j in range(2): + vk.delta[i].append(to_hex(f["vk_delta_2"][i][1-j])) +# gammaABC +vk.gammaABC = [[], []] +for i in range(2): + for j in range(2): + vk.gammaABC[i].append(to_hex(f["IC"][i][j])) + +f3 = open(sys.argv[2], 'w') +f3.write(vk.to_json()) +f3.close() + +print("vk file created: " + str(sys.argv[2])) diff --git a/powersoftau/Cargo.lock b/powersoftau/Cargo.lock index 807f1eb..59d43bd 100644 --- a/powersoftau/Cargo.lock +++ b/powersoftau/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pairing_ce 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pairing_ce 0.18.0", "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -296,7 +296,6 @@ dependencies = [ [[package]] name = "pairing_ce" version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "ff_ce 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -511,7 +510,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba" -"checksum pairing_ce 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f075a9c570e2026111cb6dddf6a320e5163c42aa32500b315ec34acbcf7c9b36" "checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8" "checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a" "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" diff --git a/powersoftau/src/bin/prepare_phase2.rs b/powersoftau/src/bin/prepare_phase2.rs index ec71991..c910a9a 100644 --- a/powersoftau/src/bin/prepare_phase2.rs +++ b/powersoftau/src/bin/prepare_phase2.rs @@ -29,7 +29,7 @@ fn log_2(x: u64) -> u32 { } fn main() { - // Try to load `./transcript` from disk. + // Try to load `./response` from disk. let reader = OpenOptions::new() .read(true) .open("response") @@ -47,7 +47,7 @@ fn main() { // Create the parameters for various 2^m circuit depths. let max_degree = log_2(current_accumulator.tau_powers_g2.len() as u64); - for m in 0..max_degree { + for m in 0..max_degree+1 { let paramname = format!("phase1radix2m{}", m); println!("Creating {}", paramname); diff --git a/powersoftau/src/bin/verify.rs b/powersoftau/src/bin/verify.rs index 73dbd24..e1016d3 100644 --- a/powersoftau/src/bin/verify.rs +++ b/powersoftau/src/bin/verify.rs @@ -25,6 +25,13 @@ use std::io::{self, Read, BufWriter, Write}; use memmap::*; +const fn num_bits() -> usize { std::mem::size_of::() * 8 } + +fn log_2(x: u64) -> u32 { + assert!(x > 0); + num_bits::() as u32 - x.leading_zeros() - 1 +} + // Computes the hash of the challenge file for the player, // given the current state of the accumulator and the last // response file hash. @@ -268,7 +275,8 @@ fn main() { let worker = &Worker::new(); // Create the parameters for various 2^m circuit depths. - for m in 0..22 { + let max_degree = log_2(current_accumulator.tau_powers_g2.len() as u64); + for m in 0..max_degree+1 { let paramname = format!("phase1radix2m{}", m); println!("Creating {}", paramname); diff --git a/powersoftau/src/small_bn256/mod.rs b/powersoftau/src/small_bn256/mod.rs index d7cf89d..17565e6 100644 --- a/powersoftau/src/small_bn256/mod.rs +++ b/powersoftau/src/small_bn256/mod.rs @@ -30,7 +30,7 @@ pub struct Bn256CeremonyParameters { } impl PowersOfTauParameters for Bn256CeremonyParameters { - const REQUIRED_POWER: usize = 12; // generate to have roughly 2 million constraints + const REQUIRED_POWER: usize = 28; // This ceremony is based on the BN256 elliptic curve construction. const G1_UNCOMPRESSED_BYTE_SIZE: usize = 64;