diff --git a/src/circuit_builder.rs b/src/circuit_builder.rs index 431e7427..b9d6a909 100644 --- a/src/circuit_builder.rs +++ b/src/circuit_builder.rs @@ -10,11 +10,11 @@ use crate::gates::gate::{GateInstance, GateRef}; use crate::gates::noop::NoopGate; use crate::generator::{CopyGenerator, WitnessGenerator}; use crate::hash::merkle_root_bit_rev_order; +use crate::partition::get_subgroup_shift; use crate::polynomial::polynomial::PolynomialValues; use crate::target::Target; use crate::util::{log2_strict, transpose, transpose_poly_values}; use crate::wire::Wire; -use crate::partition::get_subgroup_shift; pub struct CircuitBuilder { pub(crate) config: CircuitConfig, @@ -51,12 +51,18 @@ impl CircuitBuilder { } let index = self.gate_instances.len(); + + // TODO: Not passing next constants for now. Not sure if it's really useful... + self.add_generators(gate_type.0.generators(index, &constants, &[])); + self.gate_instances.push(GateInstance { gate_type, constants }); index } fn check_gate_compatibility(&self, gate: &GateRef) { - assert!(gate.0.num_wires() <= self.config.num_wires); + assert!(gate.0.num_wires() <= self.config.num_wires, + "{:?} requires {} wires, but our GateConfig has only {}", + gate.0.id(), gate.0.num_wires(), self.config.num_wires); } /// Shorthand for `generate_copy` and `assert_equal`. @@ -74,11 +80,15 @@ impl CircuitBuilder { /// Uses Plonk's permutation argument to require that two elements be equal. /// Both elements must be routable, otherwise this method will panic. pub fn assert_equal(&mut self, x: Target, y: Target) { - assert!(x.is_routable(self.config)); - assert!(y.is_routable(self.config)); + assert!(x.is_routable(self.config), "Tried to route a wire that isn't routable"); + assert!(y.is_routable(self.config), "Tried to route a wire that isn't routable"); // TODO: Add to copy_constraints. } + pub fn add_generators(&mut self, generators: Vec>>) { + self.generators.extend(generators); + } + pub fn add_generator>(&mut self, generator: G) { self.generators.push(Box::new(generator)); } @@ -113,10 +123,6 @@ impl CircuitBuilder { constants.iter().map(|&c| self.constant(c)).collect() } - pub fn permute(&mut self, inputs: [Target; 12]) -> [Target; 12] { - todo!() - } - fn blind_and_pad(&mut self) { // TODO: Blind. @@ -125,16 +131,6 @@ impl CircuitBuilder { } } - fn get_generators(&self) -> Vec>> { - self.gate_instances.iter() - .enumerate() - .flat_map(|(gate_index, gate_inst)| gate_inst.gate_type.0.generators( - gate_index, - &gate_inst.constants, - &[])) // TODO: Not supporting next_const for now. - .collect() - } - fn constant_polys(&self) -> Vec> { let num_constants = self.gate_instances.iter() .map(|gate_inst| gate_inst.constants.len()) @@ -178,7 +174,7 @@ impl CircuitBuilder { let sigma_ldes_t = transpose_poly_values(sigma_ldes); let sigmas_root = merkle_root_bit_rev_order(sigma_ldes_t.clone()); - let generators = self.get_generators(); + let generators = self.generators; let prover_only = ProverOnlyCircuitData { generators, constant_ldes_t, sigma_ldes_t }; let verifier_only = VerifierOnlyCircuitData {}; @@ -215,14 +211,14 @@ impl CircuitBuilder { } /// Builds a "prover circuit", with data needed to generate proofs but not verify them. - pub fn build_prover(mut self) -> ProverCircuitData { + pub fn build_prover(self) -> ProverCircuitData { // TODO: Can skip parts of this. let CircuitData { prover_only, common, .. } = self.build(); ProverCircuitData { prover_only, common } } /// Builds a "verifier circuit", with data needed to verify proofs but not generate them. - pub fn build_verifier(mut self) -> VerifierCircuitData { + pub fn build_verifier(self) -> VerifierCircuitData { // TODO: Can skip parts of this. let CircuitData { verifier_only, common, .. } = self.build(); VerifierCircuitData { verifier_only, common } diff --git a/src/circuit_data.rs b/src/circuit_data.rs index 494b8660..ff837f36 100644 --- a/src/circuit_data.rs +++ b/src/circuit_data.rs @@ -21,8 +21,8 @@ pub struct CircuitConfig { impl Default for CircuitConfig { fn default() -> Self { CircuitConfig { - num_wires: 3, - num_routed_wires: 3, + num_wires: 4, + num_routed_wires: 4, security_bits: 128, rate_bits: 3, num_checks: 3, diff --git a/src/field/crandall_field.rs b/src/field/crandall_field.rs index 662a1864..1425d68e 100644 --- a/src/field/crandall_field.rs +++ b/src/field/crandall_field.rs @@ -80,18 +80,22 @@ impl Field for CrandallField { while u != 1 && v != 1 { while u.is_even() { u >>= 1; - if b.is_odd() { - b += Self::ORDER; + if b.is_even() { + b >>= 1; + } else { + // b = (b + p)/2, avoiding overflow + b = (b >> 1) + (Self::ORDER >> 1) + 1; } - b >>= 1; } while v.is_even() { v >>= 1; - if c.is_odd() { - c += Self::ORDER; + if c.is_even() { + c >>= 1; + } else { + // c = (c + p)/2, avoiding overflow + c = (c >> 1) + (Self::ORDER >> 1) + 1; } - c >>= 1; } if u < v { diff --git a/src/gadgets/arithmetic.rs b/src/gadgets/arithmetic.rs index a8991408..7c9076da 100644 --- a/src/gadgets/arithmetic.rs +++ b/src/gadgets/arithmetic.rs @@ -1,21 +1,75 @@ use crate::circuit_builder::CircuitBuilder; use crate::field::field::Field; use crate::target::Target; +use crate::gates::arithmetic::ArithmeticGate; +use crate::wire::Wire; impl CircuitBuilder { + pub fn neg(&mut self, x: Target) -> Target { + let neg_one = self.neg_one(); + self.mul(x, neg_one) + } + pub fn add(&mut self, x: Target, y: Target) -> Target { - todo!() + let zero = self.zero(); + let one = self.one(); + if x == zero { + return y; + } + if y == zero { + return x; + } + + let gate = self.add_gate(ArithmeticGate::new(), vec![F::ONE, F::ONE]); + + let wire_multiplicand_0 = Wire { gate, input: ArithmeticGate::WIRE_MULTIPLICAND_0 }; + let wire_multiplicand_1 = Wire { gate, input: ArithmeticGate::WIRE_MULTIPLICAND_1 }; + let wire_addend = Wire { gate, input: ArithmeticGate::WIRE_ADDEND }; + let wire_output = Wire { gate, input: ArithmeticGate::WIRE_OUTPUT }; + + self.route(x, Target::Wire(wire_multiplicand_0)); + self.route(one, Target::Wire(wire_multiplicand_1)); + self.route(y, Target::Wire(wire_addend)); + Target::Wire(wire_output) + } + + pub fn add_many(&mut self, terms: &[Target]) -> Target { + let mut sum = self.zero(); + for term in terms { + sum = self.add(sum, *term); + } + sum } pub fn sub(&mut self, x: Target, y: Target) -> Target { - todo!() + let zero = self.zero(); + if x == zero { + return y; + } + if y == zero { + return x; + } + + // TODO: Inefficient impl for now. + let neg_y = self.neg(y); + self.add(x, neg_y) } pub fn mul(&mut self, x: Target, y: Target) -> Target { + // TODO: Check if one operand is 0 or 1. todo!() } + pub fn mul_many(&mut self, terms: &[Target]) -> Target { + let mut product = self.one(); + for term in terms { + product = self.mul(product, *term); + } + product + } + pub fn div(&mut self, x: Target, y: Target) -> Target { + // TODO: Check if one operand is 0 or 1. todo!() } } diff --git a/src/gadgets/hash.rs b/src/gadgets/hash.rs new file mode 100644 index 00000000..8d0357a6 --- /dev/null +++ b/src/gadgets/hash.rs @@ -0,0 +1,41 @@ +use std::convert::TryInto; + +use crate::circuit_builder::CircuitBuilder; +use crate::field::field::Field; +use crate::gates::gmimc::GMiMCGate; +use crate::gates::noop::NoopGate; +use crate::hash::GMIMC_ROUNDS; +use crate::target::Target; +use crate::wire::Wire; + +impl CircuitBuilder { + pub fn permute(&mut self, inputs: [Target; 12]) -> [Target; 12] { + let zero = self.zero(); + self.permute_switched(inputs, zero) + } + + pub(crate) fn permute_switched(&mut self, inputs: [Target; 12], switch: Target) -> [Target; 12] { + let gate = self.add_gate_no_constants( + GMiMCGate::::with_automatic_constants()); + + let switch_wire = GMiMCGate::::WIRE_SWITCH; + let switch_wire = Target::Wire(Wire { gate, input: switch_wire }); + self.route(switch, switch_wire); + + for i in 0..12 { + let in_wire = GMiMCGate::::wire_output(i); + let in_wire = Target::Wire(Wire { gate, input: in_wire }); + self.route(inputs[i], in_wire); + } + + // Add a NoopGate just to receive the outputs. + let next_gate = self.add_gate_no_constants(NoopGate::get()); + + (0..12) + .map(|i| Target::Wire( + Wire { gate: next_gate, input: GMiMCGate::::wire_output(i) })) + .collect::>() + .try_into() + .unwrap() + } +} diff --git a/src/gadgets/mod.rs b/src/gadgets/mod.rs index 754bccfb..f2c22478 100644 --- a/src/gadgets/mod.rs +++ b/src/gadgets/mod.rs @@ -1,2 +1,3 @@ pub(crate) mod arithmetic; pub(crate) mod split_join; +pub(crate) mod hash; diff --git a/src/gates/arithmetic.rs b/src/gates/arithmetic.rs new file mode 100644 index 00000000..8fd2afe5 --- /dev/null +++ b/src/gates/arithmetic.rs @@ -0,0 +1,156 @@ +use crate::circuit_builder::CircuitBuilder; +use crate::constraint_polynomial::{EvaluationTargets, EvaluationVars}; +use crate::field::field::Field; +use crate::gates::gate::{Gate, GateRef}; +use crate::generator::{SimpleGenerator, WitnessGenerator}; +use crate::target::Target; +use crate::wire::Wire; +use crate::witness::PartialWitness; + +/// A gate which can be configured to perform various arithmetic. In particular, it computes +/// +/// ```text +/// output := const_0 * multiplicand_0 * multiplicand_1 + const_1 * addend +/// ``` +#[derive(Debug)] +pub struct ArithmeticGate; + +impl ArithmeticGate { + pub fn new() -> GateRef { + GateRef::new(ArithmeticGate) + } + + pub const WIRE_MULTIPLICAND_0: usize = 0; + pub const WIRE_MULTIPLICAND_1: usize = 1; + pub const WIRE_ADDEND: usize = 2; + pub const WIRE_OUTPUT: usize = 3; +} + +impl Gate for ArithmeticGate { + fn id(&self) -> String { + format!("{:?}", self) + } + + fn eval_unfiltered(&self, vars: EvaluationVars) -> Vec { + let const_0 = vars.local_constants[0]; + let const_1 = vars.local_constants[1]; + let multiplicand_0 = vars.local_wires[Self::WIRE_MULTIPLICAND_0]; + let multiplicand_1 = vars.local_wires[Self::WIRE_MULTIPLICAND_1]; + let addend = vars.local_wires[Self::WIRE_ADDEND]; + let output = vars.local_wires[Self::WIRE_OUTPUT]; + let computed_output = const_0 * multiplicand_0 * multiplicand_1 + const_1 * addend; + vec![computed_output - output] + } + + fn eval_unfiltered_recursively( + &self, + builder: &mut CircuitBuilder, + vars: EvaluationTargets, + ) -> Vec { + let const_0 = vars.local_constants[0]; + let const_1 = vars.local_constants[1]; + let multiplicand_0 = vars.local_wires[Self::WIRE_MULTIPLICAND_0]; + let multiplicand_1 = vars.local_wires[Self::WIRE_MULTIPLICAND_1]; + let addend = vars.local_wires[Self::WIRE_ADDEND]; + let output = vars.local_wires[Self::WIRE_OUTPUT]; + + let product_term = builder.mul_many(&[const_0, multiplicand_0, multiplicand_1]); + let addend_term = builder.mul(const_1, addend); + let computed_output = builder.add_many(&[product_term, addend_term]); + vec![builder.sub(computed_output, output)] + } + + fn generators( + &self, + gate_index: usize, + local_constants: &[F], + _next_constants: &[F], + ) -> Vec>> { + let gen = ArithmeticGenerator { + gate_index, + const_0: local_constants[0], + const_1: local_constants[1], + }; + vec![Box::new(gen)] + } + + fn num_wires(&self) -> usize { + 4 + } + + fn num_constants(&self) -> usize { + 2 + } + + fn degree(&self) -> usize { + 3 + } + + fn num_constraints(&self) -> usize { + 1 + } +} + +struct ArithmeticGenerator { + gate_index: usize, + const_0: F, + const_1: F, +} + +impl SimpleGenerator for ArithmeticGenerator { + fn dependencies(&self) -> Vec { + vec![ + Target::Wire(Wire { + gate: self.gate_index, + input: ArithmeticGate::WIRE_MULTIPLICAND_0, + }), + Target::Wire(Wire { + gate: self.gate_index, + input: ArithmeticGate::WIRE_MULTIPLICAND_1, + }), + Target::Wire(Wire { + gate: self.gate_index, + input: ArithmeticGate::WIRE_ADDEND, + }), + ] + } + + fn run_once(&self, witness: &PartialWitness) -> PartialWitness { + let multiplicand_0_target = Wire { + gate: self.gate_index, + input: ArithmeticGate::WIRE_MULTIPLICAND_0, + }; + let multiplicand_1_target = Wire { + gate: self.gate_index, + input: ArithmeticGate::WIRE_MULTIPLICAND_1, + }; + let addend_target = Wire { + gate: self.gate_index, + input: ArithmeticGate::WIRE_ADDEND, + }; + let output_target = Wire { + gate: self.gate_index, + input: ArithmeticGate::WIRE_OUTPUT, + }; + + let multiplicand_0 = witness.get_wire(multiplicand_0_target); + let multiplicand_1 = witness.get_wire(multiplicand_1_target); + let addend = witness.get_wire(addend_target); + + let output = self.const_0 * multiplicand_0 * multiplicand_1 + + self.const_1 * addend; + + PartialWitness::singleton_wire(output_target, output) + } +} + +// #[cfg(test)] +// mod tests { +// use crate::{test_gate_low_degree, ArithmeticGate, Tweedledum}; +// +// test_gate_low_degree!( +// low_degree_ArithmeticGate, +// Tweedledum, +// ArithmeticGate +// ); +// } diff --git a/src/gates/constant.rs b/src/gates/constant.rs index f9f373e6..ca67d105 100644 --- a/src/gates/constant.rs +++ b/src/gates/constant.rs @@ -84,6 +84,6 @@ impl SimpleGenerator for ConstantGenerator { fn run_once(&self, _witness: &PartialWitness) -> PartialWitness { let wire = Wire { gate: self.gate_index, input: ConstantGate::WIRE_OUTPUT }; - PartialWitness::singleton(Target::Wire(wire), self.constant) + PartialWitness::singleton_target(Target::Wire(wire), self.constant) } } diff --git a/src/gates/gmimc.rs b/src/gates/gmimc.rs index f9992514..23afea81 100644 --- a/src/gates/gmimc.rs +++ b/src/gates/gmimc.rs @@ -5,6 +5,7 @@ use crate::constraint_polynomial::{EvaluationTargets, EvaluationVars}; use crate::field::field::Field; use crate::gates::gate::{Gate, GateRef}; use crate::generator::{SimpleGenerator, WitnessGenerator}; +use crate::gmimc::gmimc_automatic_constants; use crate::target::Target; use crate::wire::Wire; use crate::witness::PartialWitness; @@ -26,7 +27,8 @@ impl GMiMCGate { } pub fn with_automatic_constants() -> GateRef { - todo!() + let constants = Arc::new(gmimc_automatic_constants::()); + Self::with_constants(constants) } /// If this is set to 1, the first four inputs will be swapped with the next four inputs. This diff --git a/src/gates/mod.rs b/src/gates/mod.rs index 82063dfc..5e3a7724 100644 --- a/src/gates/mod.rs +++ b/src/gates/mod.rs @@ -1,3 +1,4 @@ +pub(crate) mod arithmetic; pub(crate) mod constant; pub(crate) mod fri_consistency_gate; pub(crate) mod gate; diff --git a/src/generator.rs b/src/generator.rs index 87a9cddd..da00a595 100644 --- a/src/generator.rs +++ b/src/generator.rs @@ -1,8 +1,5 @@ use std::collections::{HashMap, HashSet}; use std::fmt::Debug; -use std::time::Instant; - -use log::trace; use crate::field::field::Field; use crate::target::Target; @@ -12,10 +9,10 @@ use crate::witness::PartialWitness; /// given set of generators. pub(crate) fn generate_partial_witness( witness: &mut PartialWitness, - mut generators: &[Box>], + generators: &[Box>], ) { // Index generator indices by their watched targets. - let mut generator_indices_by_watches: HashMap> = HashMap::new(); + let mut generator_indices_by_watches = HashMap::new(); for (i, generator) in generators.iter().enumerate() { for watch in generator.watch_list() { generator_indices_by_watches @@ -40,9 +37,7 @@ pub(crate) fn generate_partial_witness( let mut next_pending_generator_indices = HashSet::new(); for &generator_idx in &pending_generator_indices { - let start = Instant::now(); let (result, finished) = generators[generator_idx].run(&witness); - trace!("run {:?} took {}", generators[generator_idx], start.elapsed().as_secs_f32()); if finished { expired_generator_indices.insert(generator_idx); } @@ -66,7 +61,7 @@ pub(crate) fn generate_partial_witness( } /// A generator participates in the generation of the witness. -pub trait WitnessGenerator: 'static + Debug + Send + Sync { +pub trait WitnessGenerator: 'static + Send + Sync { /// Targets to be "watched" by this generator. Whenever a target in the watch list is populated, /// the generator will be queued to run. fn watch_list(&self) -> Vec; @@ -80,7 +75,7 @@ pub trait WitnessGenerator: 'static + Debug + Send + Sync { /// A generator which runs once after a list of dependencies is present in the witness. // TODO: Remove Debug. Here temporarily to debug generator issues. -pub trait SimpleGenerator: 'static + Debug + Send + Sync { +pub trait SimpleGenerator: 'static + Send + Sync { fn dependencies(&self) -> Vec; fn run_once(&self, witness: &PartialWitness) -> PartialWitness; @@ -114,6 +109,6 @@ impl SimpleGenerator for CopyGenerator { fn run_once(&self, witness: &PartialWitness) -> PartialWitness { let value = witness.get_target(self.src); - PartialWitness::singleton(self.dst, value) + PartialWitness::singleton_target(self.dst, value) } } diff --git a/src/gmimc.rs b/src/gmimc.rs index 2697acc7..547fe7b2 100644 --- a/src/gmimc.rs +++ b/src/gmimc.rs @@ -1,9 +1,20 @@ use std::sync::Arc; +use rand::SeedableRng; +use rand_chacha::ChaCha8Rng; use unroll::unroll_for_loops; use crate::field::field::Field; +pub(crate) fn gmimc_automatic_constants() -> [F; R] { + let mut rng = ChaCha8Rng::seed_from_u64(0); + let mut constants = [F::ZERO; R]; + for i in 0..R { + constants[i] = F::rand_from_rng(&mut rng); + } + constants +} + pub fn gmimc_compress(a: [F; 4], b: [F; 4], constants: Arc<[F; R]>) -> [F; 4] { // Sponge with r=8, c=4. let state_0 = [a[0], a[1], a[2], a[3], b[0], diff --git a/src/hash.rs b/src/hash.rs index 50548dcf..2f083bd1 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -13,8 +13,9 @@ pub(crate) const SPONGE_RATE: usize = 8; pub(crate) const SPONGE_CAPACITY: usize = 4; pub(crate) const SPONGE_WIDTH: usize = SPONGE_RATE + SPONGE_CAPACITY; -const GMIMC_ROUNDS: usize = 101; -const GMIMC_CONSTANTS: [u64; GMIMC_ROUNDS] = [11875528958976719239, 6107683892976199900, 7756999550758271958, 14819109722912164804, 9716579428412441110, 13627117528901194436, 16260683900833506663, 5942251937084147420, 3340009544523273897, 5103423085715007461, 17051583366444092101, 11122892258227244197, 16564300648907092407, 978667924592675864, 17676416205210517593, 1938246372790494499, 8857737698008340728, 1616088456497468086, 15961521580811621978, 17427220057097673602, 14693961562064090188, 694121596646283736, 554241305747273747, 5783347729647881086, 14933083198980931734, 2600898787591841337, 9178797321043036456, 18068112389665928586, 14493389459750307626, 1650694762687203587, 12538946551586403559, 10144328970401184255, 4215161528137084719, 17559540991336287827, 1632269449854444901, 986434918028205468, 14921385763379308253, 4345141219277982730, 2645897826751167170, 9815223670029373528, 7687983869685434132, 13956100321958014639, 519639453142393369, 15617837024229225911, 1557446238053329052, 8130006133842942201, 864716631341688017, 2860289738131495304, 16723700803638270299, 8363528906277648001, 13196016034228493087, 2514677332206134618, 15626342185220554936, 466271571343554681, 17490024028988898434, 6454235936129380878, 15187752952940298536, 18043495619660620405, 17118101079533798167, 13420382916440963101, 535472393366793763, 1071152303676936161, 6351382326603870931, 12029593435043638097, 9983185196487342247, 414304527840226604, 1578977347398530191, 13594880016528059526, 13219707576179925776, 6596253305527634647, 17708788597914990288, 7005038999589109658, 10171979740390484633, 1791376803510914239, 2405996319967739434, 12383033218117026776, 17648019043455213923, 6600216741450137683, 5359884112225925883, 1501497388400572107, 11860887439428904719, 64080876483307031, 11909038931518362287, 14166132102057826906, 14172584203466994499, 593515702472765471, 3423583343794830614, 10041710997716717966, 13434212189787960052, 9943803922749087030, 3216887087479209126, 17385898166602921353, 617799950397934255, 9245115057096506938, 13290383521064450731, 10193883853810413351, 14648839921475785656, 14635698366607946133, 9134302981480720532, 10045888297267997632, 10752096344939765738]; +pub(crate) const GMIMC_ROUNDS: usize = 101; +/// This is the result of `gmimc_automatic_constants`; i.e. it's from ChaCha20 seeded with 0. +pub(crate) const GMIMC_CONSTANTS: [u64; GMIMC_ROUNDS] = [13080132715619999810, 8594738768332784433, 12896916466795114362, 1109962092924985887, 16216730424513838303, 10137062674532189451, 15292064468290167604, 17255573296743700660, 14827154243383347999, 2846171648262623971, 16246264665335217464, 14214208089399786945, 9667108688411000080, 6470857421371427314, 14103331941574951088, 11854816474757864855, 3498097497657653643, 7947235693333396721, 11110078702363612411, 16384314114341783099, 15404405914224921002, 14077880832148466479, 9555554663682579629, 13859595359622389547, 16859897326779206643, 17685474422023725021, 17858764736437889563, 9410011023624402450, 12495243630852222748, 12416945299436348089, 5776666812952701944, 6314421663507268983, 7402742472177291738, 982536713292517255, 17321168867539521172, 2934354895304883596, 10567510599683852824, 8135543734546633309, 116353493093565855, 8029688164312877009, 9003846638141970076, 7052445133185619935, 9645665433271393194, 5446430061585660707, 16770910636054378912, 17708360573237778662, 4661556288797079635, 11977051900536351292, 4378616569536950472, 3334807503157233344, 8019184736760206441, 2395043909056213726, 6558421058999795722, 11735894061922784518, 8143540539718733269, 5991753490174091591, 12235918792748480378, 2880312033996085535, 18224748117164817283, 18070411014966027790, 8156487614951798795, 10615269511128318233, 12489426406026437595, 5055279340584943685, 7231927320516917417, 2602078848371820415, 12445944370602567717, 3978905924297801117, 16711272946032085229, 10439032362290464320, 15110119873264383151, 821141790739535246, 11073536381779174375, 4866839313593360589, 13118391690850240703, 14527674975242150843, 7612751960041028847, 6808090908507673494, 6899703780195472329, 3664666286710282218, 783179505504239941, 8990689242729919931, 9646603556395461579, 7351246026916028004, 16970959815450893036, 15735726859844361172, 10347018222946250943, 12195545879691602738, 7423314197870213963, 14908016118492485461, 5840340123122280205, 17740311464247702688, 815306422036794512, 17456357369997417977, 6982651077270605698, 11970987325834369417, 8167785009370061651, 9483259820363401119, 954550221761525285, 10339565172077536587, 8651171085167737860]; /// Controls the granularity of parallelization when building Merkle trees. I.e., we will try to /// split up the task into units of work, such that each unit involves hashing roughly this many diff --git a/src/main.rs b/src/main.rs index 0043e77f..9a2b38a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,3 @@ -use std::sync::Arc; use std::thread; use std::time::Instant; @@ -13,6 +12,7 @@ use crate::circuit_data::CircuitConfig; use crate::field::field::Field; use crate::gates::constant::ConstantGate; use crate::gates::gmimc::GMiMCGate; +use crate::hash::{GMIMC_CONSTANTS, GMIMC_ROUNDS}; use crate::polynomial::polynomial::PolynomialCoeffs; use crate::witness::PartialWitness; @@ -76,12 +76,7 @@ fn bench_field_mul() { } fn bench_prove() { - let mut gmimc_constants = [F::ZERO; GMIMC_ROUNDS]; - for i in 0..GMIMC_ROUNDS { - gmimc_constants[i] = F::from_canonical_u64(GMIMC_CONSTANTS[i]); - } - let gmimc_gate = GMiMCGate::::with_constants( - Arc::new(gmimc_constants)); + let gmimc_gate = GMiMCGate::::with_automatic_constants(); let config = CircuitConfig { num_wires: 120, @@ -110,9 +105,6 @@ fn bench_prove() { prover.prove(inputs); } -const GMIMC_ROUNDS: usize = 101; -const GMIMC_CONSTANTS: [u64; GMIMC_ROUNDS] = [11875528958976719239, 6107683892976199900, 7756999550758271958, 14819109722912164804, 9716579428412441110, 13627117528901194436, 16260683900833506663, 5942251937084147420, 3340009544523273897, 5103423085715007461, 17051583366444092101, 11122892258227244197, 16564300648907092407, 978667924592675864, 17676416205210517593, 1938246372790494499, 8857737698008340728, 1616088456497468086, 15961521580811621978, 17427220057097673602, 14693961562064090188, 694121596646283736, 554241305747273747, 5783347729647881086, 14933083198980931734, 2600898787591841337, 9178797321043036456, 18068112389665928586, 14493389459750307626, 1650694762687203587, 12538946551586403559, 10144328970401184255, 4215161528137084719, 17559540991336287827, 1632269449854444901, 986434918028205468, 14921385763379308253, 4345141219277982730, 2645897826751167170, 9815223670029373528, 7687983869685434132, 13956100321958014639, 519639453142393369, 15617837024229225911, 1557446238053329052, 8130006133842942201, 864716631341688017, 2860289738131495304, 16723700803638270299, 8363528906277648001, 13196016034228493087, 2514677332206134618, 15626342185220554936, 466271571343554681, 17490024028988898434, 6454235936129380878, 15187752952940298536, 18043495619660620405, 17118101079533798167, 13420382916440963101, 535472393366793763, 1071152303676936161, 6351382326603870931, 12029593435043638097, 9983185196487342247, 414304527840226604, 1578977347398530191, 13594880016528059526, 13219707576179925776, 6596253305527634647, 17708788597914990288, 7005038999589109658, 10171979740390484633, 1791376803510914239, 2405996319967739434, 12383033218117026776, 17648019043455213923, 6600216741450137683, 5359884112225925883, 1501497388400572107, 11860887439428904719, 64080876483307031, 11909038931518362287, 14166132102057826906, 14172584203466994499, 593515702472765471, 3423583343794830614, 10041710997716717966, 13434212189787960052, 9943803922749087030, 3216887087479209126, 17385898166602921353, 617799950397934255, 9245115057096506938, 13290383521064450731, 10193883853810413351, 14648839921475785656, 14635698366607946133, 9134302981480720532, 10045888297267997632, 10752096344939765738]; - fn bench_gmimc() { const THREADS: usize = 12; const LDE_BITS: i32 = 3; diff --git a/src/plonk_challenger.rs b/src/plonk_challenger.rs index 2bc6f3de..8dbd2813 100644 --- a/src/plonk_challenger.rs +++ b/src/plonk_challenger.rs @@ -226,7 +226,11 @@ mod tests { outputs_per_round.push(challenger.get_n_challenges(num_outputs_per_round[r])); } - let config = CircuitConfig::default(); + let config = CircuitConfig { + num_wires: 114, + num_routed_wires: 13, + ..CircuitConfig::default() + }; let mut builder = CircuitBuilder::::new(config); let mut recursive_challenger = RecursiveChallenger::new(&mut builder); let mut recursive_outputs_per_round: Vec> = diff --git a/src/witness.rs b/src/witness.rs index ebd68797..6f990aea 100644 --- a/src/witness.rs +++ b/src/witness.rs @@ -16,7 +16,11 @@ impl PartialWitness { } } - pub fn singleton(target: Target, value: F) -> Self { + pub fn singleton_wire(wire: Wire, value: F) -> Self { + Self::singleton_target(Target::Wire(wire), value) + } + + pub fn singleton_target(target: Target, value: F) -> Self { let mut witness = PartialWitness::new(); witness.set_target(target, value); witness