From 0b4ad440695732a4d2c0c4805fa4545edbca4546 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:47:01 +0700 Subject: [PATCH 01/24] Add some helper functions --- zkmemory/src/lib.rs | 2 + zkmemory/src/nova/gadgets.rs | 103 +++++++++++++++++++++++++++++++++++ zkmemory/src/nova/mod.rs | 2 + 3 files changed, 107 insertions(+) create mode 100644 zkmemory/src/nova/gadgets.rs create mode 100644 zkmemory/src/nova/mod.rs diff --git a/zkmemory/src/lib.rs b/zkmemory/src/lib.rs index 946aaa0..fe92914 100644 --- a/zkmemory/src/lib.rs +++ b/zkmemory/src/lib.rs @@ -25,6 +25,8 @@ pub mod constraints; pub mod error; /// Definition of abstract machine (instruction, trace and context) pub mod machine; +/// +pub mod nova; /// The module of Poseidon hash function pub mod poseidon; #[cfg(test)] diff --git a/zkmemory/src/nova/gadgets.rs b/zkmemory/src/nova/gadgets.rs new file mode 100644 index 0000000..b2cfcde --- /dev/null +++ b/zkmemory/src/nova/gadgets.rs @@ -0,0 +1,103 @@ +use alloc::vec::Vec; +use alloc::{format, vec}; +use core::marker::PhantomData; +use ff::{Field, PrimeField}; + +pub struct IVCStep { + pub(crate) instance: F, + pub(crate) witness: Vec, +} + +#[derive(Clone, Copy, Debug)] +pub struct Table { + col: Column, +} + +impl Table { + /// Construct the lookup Table. + pub fn construct(meta: &mut ConstraintSystem) -> Self { + Self { + col: meta.fixed_column(), + } + } + + /// Load the `Table` for range check + pub fn load(&self, region: &mut Region<'_, F>) -> Result<(), Error> { + for i in 0..N { + region.assign_fixed( + || format!("assign {} in fixed column of size {}", i, N), + self.col, + i, + || Value::known(F::from(i as u64)), + )?; + } + Ok(()) + } + + /// Return the list of expressions used to define the table + pub fn table_exprs(&self, meta: &mut VirtualCells<'_, F>) -> Vec> { + vec![meta.query_fixed(self.col, Rotation::cur())] + } + + /// Perform the range check + pub fn range_check( + &self, + meta: &mut ConstraintSystem, + msg: &'static str, + exp_fn: impl FnOnce(&mut VirtualCells<'_, F>) -> Expression, + ) { + meta.lookup_any(msg, |meta| { + let exp = exp_fn(meta); + vec![exp] + .into_iter() + .zip_eq(self.table_exprs(meta)) + .collect() + }); + } +} + + + +[derive(Clone, Copy, Debug)] +/// Config for binary number +pub struct BinaryConfig { + /// the list of bit representation + pub bits: [Column; N], + _marker: PhantomData, +} +impl BinaryConfig { + /// Requires that each bit is zero or one + pub fn configure(meta: &mut ConstraintSystem, selector: Column) -> Self { + let bits = [0; N].map(|_| meta.advice_column()); + let one = Expression::Constant(F::ONE); + bits.map(|bit| { + meta.create_gate("bit column is 0 or 1", |meta| { + let selector = meta.query_fixed(selector, Rotation::cur()); + let bit = meta.query_advice(bit, Rotation::cur()); + vec![selector * bit.clone() * (one.clone() - bit)] + }) + }); + BinaryConfig { + bits, + _marker: PhantomData, + } + } + + /// Map a value to its corresponding binary witness for the config + pub fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + value: u8, + ) -> Result<(), Error> { + for (&bit, &column) in as_bits::(value).iter().zip(&self.bits) { + region.assign_advice( + || format!("binary number {:?}", column), + column, + offset, + || Value::known(F::from(bit as u64)), + )?; + } + Ok(()) + } +} \ No newline at end of file diff --git a/zkmemory/src/nova/mod.rs b/zkmemory/src/nova/mod.rs new file mode 100644 index 0000000..455ac50 --- /dev/null +++ b/zkmemory/src/nova/mod.rs @@ -0,0 +1,2 @@ +/// +pub mod gadgets; From 230741364c47b8e3fef4b0ecd7edbfb4c81844c4 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Fri, 14 Jun 2024 17:27:59 +0700 Subject: [PATCH 02/24] Add more helper functions --- zkmemory/src/nova/gadgets.rs | 107 ++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/zkmemory/src/nova/gadgets.rs b/zkmemory/src/nova/gadgets.rs index b2cfcde..1016431 100644 --- a/zkmemory/src/nova/gadgets.rs +++ b/zkmemory/src/nova/gadgets.rs @@ -100,4 +100,109 @@ impl BinaryConfig { } Ok(()) } -} \ No newline at end of file +} + + +// convert a value into an binary array of size N +fn as_bits(value: u8) -> [u8; N] { + let mut value = value; + let mut bits = [0; N]; + for i in 0..N { + bits[N - 1 - i] = value % 2; + value /= 2; + } + bits +} + +/// return 1 if lhs=rhs as bits and 0 otherwise +pub fn equal_value( + lhs: [Expression; N], + rhs: u8, +) -> Expression { + let mut acc = Expression::Constant(F::ONE); + let one = Expression::Constant(F::ONE); + let rhs = as_bits::(rhs); + for (r, l) in rhs.iter().zip(lhs) { + let rr = Expression::Constant(F::from(*r as u64)); + acc = acc * (one.clone() - (l.clone() - rr.clone()) * (l - rr)); + } + acc +} + +/// Trace record struct for Lexicographic ordering circuit +/// We need every element to be of an array of type F, where each +#[derive(Debug, Clone)] +pub(crate) struct ConvertedTraceRecord { + pub(crate) address: [F; 32], // 256 bits + pub(crate) time_log: [F; 8], // 256 bits + pub(crate) instruction: F, // 0 or 1 + pub(crate) value: [F; 32], // 256 bit +} + +impl ConvertedTraceRecord { + /// Get the trace record fields in tuple + pub fn get_tuple(&self) -> ([F; 32], [F; 8], F, [F; 32]) { + (self.address, self.time_log, self.instruction, self.value) + } +} +// convert the original trace record into a converted trace record +// for serving as the witness of the ciruits +impl From> for ConvertedTraceRecord { + fn from(value: TraceRecord) -> Self { + Self { + address: value + .get_tuple() + .3 + .fixed_be_bytes() + .into_iter() + .map(|b| F::from(u64::from(b))) + .collect::>() + .try_into() + .expect("Cannot convert address to [F; 32]"), + time_log: value + .get_tuple() + .0 + .to_be_bytes() + .into_iter() + .map(|b| F::from(u64::from(b))) + .collect::>() + .try_into() + .expect("Cannot convert time_log to [F; 8]"), + instruction: match value.get_tuple().2 { + MemoryInstruction::Write => F::ONE, + MemoryInstruction::Read => F::ZERO, + }, + value: value + .get_tuple() + .4 + .fixed_be_bytes() + .into_iter() + .map(|b| F::from(u64::from(b))) + .collect::>() + .try_into() + .expect("Cannot convert value to [F; 32]"), + } + } +} + +/// The witness table consisting of the elements of the trace records +#[derive(Clone, Copy, Debug)] +pub(crate) struct TraceRecordWitnessTable { + pub(crate) address: [Column; 32], + pub(crate) time_log: [Column; 8], + pub(crate) instruction: Column, + pub(crate) value: [Column; 32], + pub(crate) _marker: PhantomData, +} +impl TraceRecordWitnessTable { + /// New Witness table + pub fn new(meta: &mut ConstraintSystem) -> Self { + TraceRecordWitnessTable { + address: [0; 32].map(|_| meta.advice_column()), + time_log: [0; 8].map(|_| meta.advice_column()), + instruction: meta.advice_column(), + value: [0; 32].map(|_| meta.advice_column()), + _marker: PhantomData, + } + } +} From 16a33c3fe7ffbeb594223d56f8bff95f5f0c68a2 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 Date: Wed, 19 Jun 2024 17:15:37 +0700 Subject: [PATCH 03/24] Add the configuration of each memory commitment step --- zkmemory/src/nova/memory_commitment.rs | 69 ++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 zkmemory/src/nova/memory_commitment.rs diff --git a/zkmemory/src/nova/memory_commitment.rs b/zkmemory/src/nova/memory_commitment.rs new file mode 100644 index 0000000..b7ded2f --- /dev/null +++ b/zkmemory/src/nova/memory_commitment.rs @@ -0,0 +1,69 @@ + + +pub struct MemoryCommitmentConfig { + + memory: [Column; M], + indices: Column, + pub merkle_root: Column, + /// the selectors + selector: Column, + selector_zero: Selector, + _marker0: PhantomData, +} + +impl MerkleTreeConfig { + fn configure(meta: &mut ConstraintSystem, merkle_root: Column) -> Self { + let memory = [0; 3].map(|_| meta.advice_column()); + let indices = meta.advice_column(); + let selector = meta.fixed_column(); + let selector_zero = meta.selector(); + for i in memory { + meta.enable_equality(i); + } + + let one = Expression::Constant(F::ONE); + + // for i=0 indices[i] is equal to zero or one + // we handle i=0 seperately with selector_zero, since we are using + // a common selector for the other gates. + meta.create_gate("indices must be 0 or 1", |meta| { + let selector_zero = meta.query_selector(selector_zero); + let indices = meta.query_advice(indices, Rotation::cur()); + vec![selector_zero * indices.clone() * (one.clone() - indices)] + }); + + // for all i>=1 indices[i] is equal to zero or one + meta.create_gate("indices must be 0 or 1", |meta| { + let indices = meta.query_advice(indices, Rotation::cur()); + let selector = meta.query_fixed(selector, Rotation::cur()); + vec![selector * indices.clone() * (one.clone() - indices)] + }); + + // if indices[i]=0 then advice_cur[i][0]=advice_cur[i-1][2] + // otherwise advice_cur[i][1]=advice_cur[i-1][2] + meta.create_gate( + "output of the current layer is equal to the left or right input of the next layer", + |meta| { + let advice_cur = advice.map(|x| meta.query_advice(x, Rotation::cur())); + let advice_prev = advice.map(|x| meta.query_advice(x, Rotation::prev())); + let indices = meta.query_advice(indices, Rotation::cur()); + let selector = meta.query_fixed(selector, Rotation::cur()); + vec![ + selector + * ((one - indices.clone()) + * (advice_cur[0].clone() - advice_prev[2].clone()) + + indices * (advice_cur[1].clone() - advice_prev[2].clone())), + ] + }, + ); + + MerkleTreeConfig { + memory, + indices, + merkle_root, + selector, + selector_zero, + _marker0: PhantomData, + } + } +} \ No newline at end of file From f3cdc8bb782cba82a4fc4582f5d3fc1345ca6124 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Fri, 21 Jun 2024 18:55:45 +0700 Subject: [PATCH 04/24] Add additional helper methods for instace-witness computation step --- zkmemory/src/nova/gadgets.rs | 3 + zkmemory/src/nova/memory_commitment.rs | 96 +++++++++++++++++++++++++- zkmemory/src/nova/mod.rs | 4 +- 3 files changed, 101 insertions(+), 2 deletions(-) diff --git a/zkmemory/src/nova/gadgets.rs b/zkmemory/src/nova/gadgets.rs index 1016431..481faa6 100644 --- a/zkmemory/src/nova/gadgets.rs +++ b/zkmemory/src/nova/gadgets.rs @@ -206,3 +206,6 @@ impl TraceRecordWitnessTable { } } } + + + diff --git a/zkmemory/src/nova/memory_commitment.rs b/zkmemory/src/nova/memory_commitment.rs index b7ded2f..ba26dd2 100644 --- a/zkmemory/src/nova/memory_commitment.rs +++ b/zkmemory/src/nova/memory_commitment.rs @@ -1,3 +1,5 @@ +use core::marker::PhantomData; + pub struct MemoryCommitmentConfig { @@ -5,6 +7,7 @@ pub struct MemoryCommitmentConfig { memory: [Column; M], indices: Column, pub merkle_root: Column, + path: MerkleTreeConfig, /// the selectors selector: Column, selector_zero: Selector, @@ -57,13 +60,104 @@ impl MerkleTreeConfig { }, ); + let path=MerkleTreeConfig::::config(merkle_root); + MerkleTreeConfig { memory, indices, merkle_root, + path, selector, selector_zero, _marker0: PhantomData, } } -} \ No newline at end of file +} + +#[derive(Default)] +/// Merkle tree circuit +pub(crate) struct MemoryTreeCircuit< + S: Spec, + F: Field + PrimeField, + const W: usize, + const R: usize, +> { + /// the leaf node we would like to open + pub(crate) leaf: F, + /// the values of the sibling nodes in the path + pub(crate) elements: Vec, + /// the index of the path from the leaf to the merkle root + pub(crate) indices: Vec, + _marker: PhantomData, +} + + +impl + Clone, F: Field + PrimeField, const W: usize, const R: usize, const M: usize> Circuit + for MemoryTreeCircuit +{ + type Config = MerkleTreeConfig; + type FloorPlanner = SimpleFloorPlanner; + + fn without_witnesses(&self) -> Self { + Self { + leaf: F::ZERO, + elements: vec![F::ZERO], + indices: vec![F::ZERO], + _marker: PhantomData, + } + } + + fn configure(meta: &mut ConstraintSystem) -> Self::Config { + let instance = meta.instance_column(); + meta.enable_equality(instance); + MerkleTreeConfig::::configure(meta, instance) + } + + fn synthesize( + &self, + config: Self::Config, + mut layouter: impl Layouter, + ) -> Result<(), Error> { + assert_eq!(self.indices.len(), self.elements.len()); + let mut v = vec![self.leaf]; + + layouter.assign_region( + || "Merkle proof", + |mut region| { + for i in 0..self.indices.len() { + let digest = self.assign(v[i], &mut region, config, i); + v.push(digest.expect("cannot get digest")); + } + Ok(()) + }, + )?; + + let leaf_cell = layouter.assign_region( + || "assign leaf", + |mut region| { + region.assign_advice( + || "assign leaf", + config.advice[0], + 0, + || Value::known(self.leaf), + ) + }, + )?; + + let digest = layouter.assign_region( + || "assign root", + |mut region| { + region.assign_advice( + || "assign root", + config.advice[0], + 0, + || Value::known(v[self.indices.len()]), + ) + }, + )?; + + layouter.constrain_instance(leaf_cell.cell(), config.instance, 0)?; + layouter.constrain_instance(digest.cell(), config.instance, 1)?; + Ok(()) + } +} diff --git a/zkmemory/src/nova/mod.rs b/zkmemory/src/nova/mod.rs index 455ac50..e914f75 100644 --- a/zkmemory/src/nova/mod.rs +++ b/zkmemory/src/nova/mod.rs @@ -1,2 +1,4 @@ -/// +/// this module consists of helper functions pub mod gadgets; +/// this module consists of the instance-witness pairs in each step +pub mod memory_commitment; \ No newline at end of file From 90bb9e54b01ffa440aa6e6a550afd20a2c6927b9 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 24 Jun 2024 18:49:29 +0700 Subject: [PATCH 05/24] Reconfigure the instance-witness config --- zkmemory/src/nova/memory_commitment.rs | 131 +++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/zkmemory/src/nova/memory_commitment.rs b/zkmemory/src/nova/memory_commitment.rs index ba26dd2..668a2bc 100644 --- a/zkmemory/src/nova/memory_commitment.rs +++ b/zkmemory/src/nova/memory_commitment.rs @@ -161,3 +161,134 @@ impl + Clone, F: Field + PrimeField, const W: usize, const R: u Ok(()) } } + + +pub struct NovaAugmentedCircuitInputs { + params: E::Scalar, + i: E::Base, + z0: Vec, + zi: Option>, + U: Option>, + u: Option>, + T: Option>, +} + +impl NovaAugmentedCircuitInputs { + /// Create new inputs/witness for the verification circuit + pub fn new( + params: E::Scalar, + i: E::Base, + z0: Vec, + zi: Option>, + U: Option>, + u: Option>, + T: Option>, + ) -> Self { + Self { + params, + i, + z0, + zi, + U, + u, + T, + } + } +} + +/// The augmented circuit F' in Nova that includes a step circuit F +/// and the circuit for the verifier in Nova's non-interactive folding scheme +pub struct NovaAugmentedCircuit<'a, E: Engine, SC: StepCircuit> { + params: &'a NovaAugmentedCircuitParams, + ro_consts: ROConstantsCircuit, + inputs: Option>, + step_circuit: &'a SC, // The function that is applied for each step +} + +impl<'a, E: Engine, SC: StepCircuit> NovaAugmentedCircuit<'a, E, SC> { + /// Create a new verification circuit for the input relaxed r1cs instances + pub const fn new( + params: &'a NovaAugmentedCircuitParams, + inputs: Option>, + step_circuit: &'a SC, + ro_consts: ROConstantsCircuit, + ) -> Self { + Self { + params, + inputs, + step_circuit, + ro_consts, + } + } + + /// Allocate all witnesses and return + fn alloc_witness::Base>>( + &self, + mut cs: CS, + arity: usize, + ) -> Result< + ( + AllocatedNum, + AllocatedNum, + Vec>, + Vec>, + AllocatedRelaxedR1CSInstance, + AllocatedR1CSInstance, + AllocatedPoint, + ), + SynthesisError, + > { + // Allocate the params + let params = alloc_scalar_as_base::( + cs.namespace(|| "params"), + self.inputs.as_ref().map(|inputs| inputs.params), + )?; + + // Allocate i + let i = AllocatedNum::alloc(cs.namespace(|| "i"), || Ok(self.inputs.get()?.i))?; + + // Allocate z0 + let z_0 = (0..arity) + .map(|i| { + AllocatedNum::alloc(cs.namespace(|| format!("z0_{i}")), || { + Ok(self.inputs.get()?.z0[i]) + }) + }) + .collect::>, _>>()?; + + // Allocate zi. If inputs.zi is not provided (base case) allocate default value 0 + let zero = vec![E::Base::ZERO; arity]; + let z_i = (0..arity) + .map(|i| { + AllocatedNum::alloc(cs.namespace(|| format!("zi_{i}")), || { + Ok(self.inputs.get()?.zi.as_ref().unwrap_or(&zero)[i]) + }) + }) + .collect::>, _>>()?; + + // Allocate the running instance + let U: AllocatedRelaxedR1CSInstance = AllocatedRelaxedR1CSInstance::alloc( + cs.namespace(|| "Allocate U"), + self.inputs.as_ref().and_then(|inputs| inputs.U.as_ref()), + self.params.limb_width, + self.params.n_limbs, + )?; + + // Allocate the instance to be folded in + let u = AllocatedR1CSInstance::alloc( + cs.namespace(|| "allocate instance u to fold"), + self.inputs.as_ref().and_then(|inputs| inputs.u.as_ref()), + )?; + + // Allocate T + let T = AllocatedPoint::alloc( + cs.namespace(|| "allocate T"), + self + .inputs + .as_ref() + .and_then(|inputs| inputs.T.map(|T| T.to_coordinates())), + )?; + T.check_on_curve(cs.namespace(|| "check T on curve"))?; + + Ok((params, i, z_0, z_i, U, u, T)) + } \ No newline at end of file From cb696105ea70d60bfccf3f1eff85bdfd963c7902 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Wed, 26 Jun 2024 17:55:34 +0700 Subject: [PATCH 06/24] Add circuit constraints --- zkmemory/src/nova/memory_commitment.rs | 159 ++++++++++++++++++++++++- 1 file changed, 158 insertions(+), 1 deletion(-) diff --git a/zkmemory/src/nova/memory_commitment.rs b/zkmemory/src/nova/memory_commitment.rs index 668a2bc..0b818f0 100644 --- a/zkmemory/src/nova/memory_commitment.rs +++ b/zkmemory/src/nova/memory_commitment.rs @@ -291,4 +291,161 @@ impl<'a, E: Engine, SC: StepCircuit> NovaAugmentedCircuit<'a, E, SC> { T.check_on_curve(cs.namespace(|| "check T on curve"))?; Ok((params, i, z_0, z_i, U, u, T)) - } \ No newline at end of file + } + + /// Synthesizes non base case and returns the new relaxed `R1CSInstance` + /// And a boolean indicating if all checks pass + fn synthesize_non_base_case::Base>>( + &self, + mut cs: CS, + params: &AllocatedNum, + i: &AllocatedNum, + z_0: &[AllocatedNum], + z_i: &[AllocatedNum], + U: &AllocatedRelaxedR1CSInstance, + u: &AllocatedR1CSInstance, + T: &AllocatedPoint, + arity: usize, + ) -> Result<(AllocatedRelaxedR1CSInstance, AllocatedBit), SynthesisError> { + // Check that u.x[0] = Hash(params, U, i, z0, zi) + let mut ro = E::ROCircuit::new( + self.ro_consts.clone(), + NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * arity, + ); + ro.absorb(params); + ro.absorb(i); + for e in z_0 { + ro.absorb(e); + } + for e in z_i { + ro.absorb(e); + } + U.absorb_in_ro(cs.namespace(|| "absorb U"), &mut ro)?; + + let hash_bits = ro.squeeze(cs.namespace(|| "Input hash"), NUM_HASH_BITS)?; + let hash = le_bits_to_num(cs.namespace(|| "bits to hash"), &hash_bits)?; + let check_pass = alloc_num_equals( + cs.namespace(|| "check consistency of u.X[0] with H(params, U, i, z0, zi)"), + &u.X0, + &hash, + )?; + + // Run NIFS Verifier + let U_fold = U.fold_with_r1cs( + cs.namespace(|| "compute fold of U and u"), + params, + u, + T, + self.ro_consts.clone(), + self.params.limb_width, + self.params.n_limbs, + )?; + + Ok((U_fold, check_pass)) + } +} + +impl<'a, E: Engine, SC: StepCircuit> NovaAugmentedCircuit<'a, E, SC> { + /// synthesize circuit giving constraint system + pub fn synthesize::Base>>( + self, + cs: &mut CS, + ) -> Result>, SynthesisError> { + let arity = self.step_circuit.arity(); + + // Allocate all witnesses + let (params, i, z_0, z_i, U, u, T) = + self.alloc_witness(cs.namespace(|| "allocate the circuit witness"), arity)?; + + // Compute variable indicating if this is the base case + let zero = alloc_zero(cs.namespace(|| "zero")); + let is_base_case = alloc_num_equals(cs.namespace(|| "Check if base case"), &i.clone(), &zero)?; + + // Synthesize the circuit for the base case and get the new running instance + let Unew_base = self.synthesize_base_case(cs.namespace(|| "base case"), u.clone())?; + + // Synthesize the circuit for the non-base case and get the new running + // instance along with a boolean indicating if all checks have passed + let (Unew_non_base, check_non_base_pass) = self.synthesize_non_base_case( + cs.namespace(|| "synthesize non base case"), + ¶ms, + &i, + &z_0, + &z_i, + &U, + &u, + &T, + arity, + )?; + + // Either check_non_base_pass=true or we are in the base case + let should_be_false = AllocatedBit::nor( + cs.namespace(|| "check_non_base_pass nor base_case"), + &check_non_base_pass, + &is_base_case, + )?; + cs.enforce( + || "check_non_base_pass nor base_case = false", + |lc| lc + should_be_false.get_variable(), + |lc| lc + CS::one(), + |lc| lc, + ); + + // Compute the U_new + let Unew = Unew_base.conditionally_select( + cs.namespace(|| "compute U_new"), + &Unew_non_base, + &Boolean::from(is_base_case.clone()), + )?; + + // Compute i + 1 + let i_new = AllocatedNum::alloc(cs.namespace(|| "i + 1"), || { + Ok(*i.get_value().get()? + E::Base::ONE) + })?; + cs.enforce( + || "check i + 1", + |lc| lc, + |lc| lc, + |lc| lc + i_new.get_variable() - CS::one() - i.get_variable(), + ); + + // Compute z_{i+1} + let z_input = conditionally_select_vec( + cs.namespace(|| "select input to F"), + &z_0, + &z_i, + &Boolean::from(is_base_case), + )?; + + let z_next = self + .step_circuit + .synthesize(&mut cs.namespace(|| "F"), &z_input)?; + + if z_next.len() != arity { + return Err(SynthesisError::IncompatibleLengthVector( + "z_next".to_string(), + )); + } + + // Compute the new hash H(params, Unew, i+1, z0, z_{i+1}) + let mut ro = E::ROCircuit::new(self.ro_consts, NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * arity); + ro.absorb(¶ms); + ro.absorb(&i_new); + for e in &z_0 { + ro.absorb(e); + } + for e in &z_next { + ro.absorb(e); + } + Unew.absorb_in_ro(cs.namespace(|| "absorb U_new"), &mut ro)?; + let hash_bits = ro.squeeze(cs.namespace(|| "output hash bits"), NUM_HASH_BITS)?; + let hash = le_bits_to_num(cs.namespace(|| "convert hash to num"), &hash_bits)?; + + // Outputs the computed hash and u.X[1] that corresponds to the hash of the other circuit + u.X1 + .inputize(cs.namespace(|| "Output unmodified hash of the other circuit"))?; + hash.inputize(cs.namespace(|| "output new hash of this circuit"))?; + + Ok(z_next) + } +} \ No newline at end of file From cbd554bed7f1d49466b293a3f400812180a2ed90 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 1 Jul 2024 18:26:23 +0700 Subject: [PATCH 07/24] Fix some bugs in the circuit supporting Nova and add missing imports. --- zkmemory/src/nova/memory_commitment.rs | 104 ++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/zkmemory/src/nova/memory_commitment.rs b/zkmemory/src/nova/memory_commitment.rs index 0b818f0..ce45c46 100644 --- a/zkmemory/src/nova/memory_commitment.rs +++ b/zkmemory/src/nova/memory_commitment.rs @@ -1,6 +1,20 @@ use core::marker::PhantomData; - +use crate::{ + constants::{NUM_FE_WITHOUT_IO_FOR_CRHF, NUM_HASH_BITS}, + gadgets::{ + ecc::AllocatedPoint, + r1cs::{AllocatedR1CSInstance, AllocatedRelaxedR1CSInstance}, + utils::{ + alloc_num_equals, alloc_scalar_as_base, alloc_zero, conditionally_select_vec, le_bits_to_num, + }, + }, + r1cs::{R1CSInstance, RelaxedR1CSInstance}, + traits::{ + circuit::StepCircuit, commitment::CommitmentTrait, Engine, ROCircuitTrait, ROConstantsCircuit, + }, + Commitment, +}; pub struct MemoryCommitmentConfig { @@ -448,4 +462,92 @@ impl<'a, E: Engine, SC: StepCircuit> NovaAugmentedCircuit<'a, E, SC> { Ok(z_next) } +} + + +pub struct SparseMatrix { + /// all non-zero values in the matrix + pub data: Vec, + /// column indices + pub indices: Vec, + /// row information + pub indptr: Vec, + /// number of columns + pub cols: usize, +} + +impl SparseMatrix { + /// 0x0 empty matrix + pub fn empty() -> Self { + SparseMatrix { + data: vec![], + indices: vec![], + indptr: vec![0], + cols: 0, + } + } + + /// Construct from the COO representation; Vec. + /// We assume that the rows are sorted during construction. + pub fn new(matrix: &[(usize, usize, F)], rows: usize, cols: usize) -> Self { + let mut new_matrix = vec![vec![]; rows]; + for (row, col, val) in matrix { + new_matrix[*row].push((*col, *val)); + } + + for row in new_matrix.iter() { + assert!(row.windows(2).all(|w| w[0].0 < w[1].0)); + } + + let mut indptr = vec![0; rows + 1]; + for (i, col) in new_matrix.iter().enumerate() { + indptr[i + 1] = indptr[i] + col.len(); + } + + let mut indices = vec![]; + let mut data = vec![]; + for col in new_matrix { + let (idx, val): (Vec<_>, Vec<_>) = col.into_iter().unzip(); + indices.extend(idx); + data.extend(val); + } + + SparseMatrix { + data, + indices, + indptr, + cols, + } + } + + /// Retrieves the data for row slice [i..j] from `ptrs`. + /// We assume that `ptrs` is indexed from `indptrs` and do not check if the + /// returned slice is actually a valid row. + pub fn get_row_unchecked(&self, ptrs: &[usize; 2]) -> impl Iterator { + self.data[ptrs[0]..ptrs[1]] + .iter() + .zip(&self.indices[ptrs[0]..ptrs[1]]) + } + + /// Multiply by a dense vector; uses rayon/gpu. + pub fn multiply_vec(&self, vector: &[F]) -> Vec { + assert_eq!(self.cols, vector.len(), "invalid shape"); + + self.multiply_vec_unchecked(vector) + } + + /// Multiply by a dense vector; uses rayon/gpu. + /// This does not check that the shape of the matrix/vector are compatible. + pub fn multiply_vec_unchecked(&self, vector: &[F]) -> Vec { + self + .indptr + .par_windows(2) + .map(|ptrs| { + self + .get_row_unchecked(ptrs.try_into().unwrap()) + .map(|(val, col_idx)| *val * vector[*col_idx]) + .sum() + }) + .collect() + } } \ No newline at end of file From 6202d7983a66d14c7b1393b32c3848c8502db75d Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Thu, 4 Jul 2024 17:42:16 +0700 Subject: [PATCH 08/24] Update synthesize function and addd NIFS functions This PR tries to fix the synthesize function and implement some components of the NIFS Prove and Verify function based on Nova. --- Cargo.toml | 3 +- zkmemory/src/nova/memory_commitment.rs | 385 +++++++++++++++---------- 2 files changed, 227 insertions(+), 161 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 41ff0a8..98e02c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,4 +37,5 @@ group = "0.13.0" rand_core = "0.6.4" rand = "0.8.5" serde_json = "1.0.87" -serde = "1.0.147" \ No newline at end of file +serde = "1.0.147" +Nova = { git = "https://github.com/microsoft/Nova" } \ No newline at end of file diff --git a/zkmemory/src/nova/memory_commitment.rs b/zkmemory/src/nova/memory_commitment.rs index ce45c46..9cd25fe 100644 --- a/zkmemory/src/nova/memory_commitment.rs +++ b/zkmemory/src/nova/memory_commitment.rs @@ -1,6 +1,6 @@ use core::marker::PhantomData; - -use crate::{ +/// Reference to be added later. +use Nova::{ constants::{NUM_FE_WITHOUT_IO_FOR_CRHF, NUM_HASH_BITS}, gadgets::{ ecc::AllocatedPoint, @@ -16,165 +16,7 @@ use crate::{ Commitment, }; -pub struct MemoryCommitmentConfig { - - memory: [Column; M], - indices: Column, - pub merkle_root: Column, - path: MerkleTreeConfig, - /// the selectors - selector: Column, - selector_zero: Selector, - _marker0: PhantomData, -} - -impl MerkleTreeConfig { - fn configure(meta: &mut ConstraintSystem, merkle_root: Column) -> Self { - let memory = [0; 3].map(|_| meta.advice_column()); - let indices = meta.advice_column(); - let selector = meta.fixed_column(); - let selector_zero = meta.selector(); - for i in memory { - meta.enable_equality(i); - } - - let one = Expression::Constant(F::ONE); - - // for i=0 indices[i] is equal to zero or one - // we handle i=0 seperately with selector_zero, since we are using - // a common selector for the other gates. - meta.create_gate("indices must be 0 or 1", |meta| { - let selector_zero = meta.query_selector(selector_zero); - let indices = meta.query_advice(indices, Rotation::cur()); - vec![selector_zero * indices.clone() * (one.clone() - indices)] - }); - - // for all i>=1 indices[i] is equal to zero or one - meta.create_gate("indices must be 0 or 1", |meta| { - let indices = meta.query_advice(indices, Rotation::cur()); - let selector = meta.query_fixed(selector, Rotation::cur()); - vec![selector * indices.clone() * (one.clone() - indices)] - }); - - // if indices[i]=0 then advice_cur[i][0]=advice_cur[i-1][2] - // otherwise advice_cur[i][1]=advice_cur[i-1][2] - meta.create_gate( - "output of the current layer is equal to the left or right input of the next layer", - |meta| { - let advice_cur = advice.map(|x| meta.query_advice(x, Rotation::cur())); - let advice_prev = advice.map(|x| meta.query_advice(x, Rotation::prev())); - let indices = meta.query_advice(indices, Rotation::cur()); - let selector = meta.query_fixed(selector, Rotation::cur()); - vec![ - selector - * ((one - indices.clone()) - * (advice_cur[0].clone() - advice_prev[2].clone()) - + indices * (advice_cur[1].clone() - advice_prev[2].clone())), - ] - }, - ); - - let path=MerkleTreeConfig::::config(merkle_root); - - MerkleTreeConfig { - memory, - indices, - merkle_root, - path, - selector, - selector_zero, - _marker0: PhantomData, - } - } -} -#[derive(Default)] -/// Merkle tree circuit -pub(crate) struct MemoryTreeCircuit< - S: Spec, - F: Field + PrimeField, - const W: usize, - const R: usize, -> { - /// the leaf node we would like to open - pub(crate) leaf: F, - /// the values of the sibling nodes in the path - pub(crate) elements: Vec, - /// the index of the path from the leaf to the merkle root - pub(crate) indices: Vec, - _marker: PhantomData, -} - - -impl + Clone, F: Field + PrimeField, const W: usize, const R: usize, const M: usize> Circuit - for MemoryTreeCircuit -{ - type Config = MerkleTreeConfig; - type FloorPlanner = SimpleFloorPlanner; - - fn without_witnesses(&self) -> Self { - Self { - leaf: F::ZERO, - elements: vec![F::ZERO], - indices: vec![F::ZERO], - _marker: PhantomData, - } - } - - fn configure(meta: &mut ConstraintSystem) -> Self::Config { - let instance = meta.instance_column(); - meta.enable_equality(instance); - MerkleTreeConfig::::configure(meta, instance) - } - - fn synthesize( - &self, - config: Self::Config, - mut layouter: impl Layouter, - ) -> Result<(), Error> { - assert_eq!(self.indices.len(), self.elements.len()); - let mut v = vec![self.leaf]; - - layouter.assign_region( - || "Merkle proof", - |mut region| { - for i in 0..self.indices.len() { - let digest = self.assign(v[i], &mut region, config, i); - v.push(digest.expect("cannot get digest")); - } - Ok(()) - }, - )?; - - let leaf_cell = layouter.assign_region( - || "assign leaf", - |mut region| { - region.assign_advice( - || "assign leaf", - config.advice[0], - 0, - || Value::known(self.leaf), - ) - }, - )?; - - let digest = layouter.assign_region( - || "assign root", - |mut region| { - region.assign_advice( - || "assign root", - config.advice[0], - 0, - || Value::known(v[self.indices.len()]), - ) - }, - )?; - - layouter.constrain_instance(leaf_cell.cell(), config.instance, 0)?; - layouter.constrain_instance(digest.cell(), config.instance, 1)?; - Ok(()) - } -} pub struct NovaAugmentedCircuitInputs { @@ -359,6 +201,8 @@ impl<'a, E: Engine, SC: StepCircuit> NovaAugmentedCircuit<'a, E, SC> { } } + +/// Todo: Check Nova and try to understand how this work later. impl<'a, E: Engine, SC: StepCircuit> NovaAugmentedCircuit<'a, E, SC> { /// synthesize circuit giving constraint system pub fn synthesize::Base>>( @@ -550,4 +394,225 @@ impl SparseMatrix { }) .collect() } +} + +/// Iterator for sparse matrix +pub struct Iter<'a, F: PrimeField> { + matrix: &'a SparseMatrix, + row: usize, + i: usize, + nnz: usize, +} + +impl<'a, F: PrimeField> Iterator for Iter<'a, F> { + type Item = (usize, usize, F); + + fn next(&mut self) -> Option { + // are we at the end? + if self.i == self.nnz { + return None; + } + + // compute current item + let curr_item = ( + self.row, + self.matrix.indices[self.i], + self.matrix.data[self.i], + ); + + // advance the iterator + self.i += 1; + // edge case at the end + if self.i == self.nnz { + return Some(curr_item); + } + // if `i` has moved to next row + while self.i >= self.matrix.indptr[self.row + 1] { + self.row += 1; + } + + Some(curr_item) + } +} + + + + +/// NIFS Prove and Verify +/// TODO: Check the RO Trait Nova and implement it +pub struct NIFS { + pub(crate) comm_T: Commitment, +} + +type ROConstants = + <::RO as ROTrait<::Base, ::Scalar>>::Constants; + +impl NIFS { + + + pub fn prove( + ck: &CommitmentKey, + ro_consts: &ROConstants, + pp_digest: &E::Scalar, + S: &R1CSShape, + U1: &RelaxedR1CSInstance, + W1: &RelaxedR1CSWitness, + U2: &R1CSInstance, + W2: &R1CSWitness, + ) -> Result<(NIFS, (RelaxedR1CSInstance, RelaxedR1CSWitness)), NovaError> { + // initialize a new RO + let mut ro = E::RO::new(ro_consts.clone(), NUM_FE_FOR_RO); + + // append the digest of pp to the transcript + ro.absorb(scalar_as_base::(*pp_digest)); + + // append U2 to transcript, U1 does not need to absorbed since U2.X[0] = Hash(params, U1, i, z0, zi) + U2.absorb_in_ro(&mut ro); + + // compute a commitment to the cross-term + let (T, comm_T) = S.commit_T(ck, U1, W1, U2, W2)?; + + // append `comm_T` to the transcript and obtain a challenge + comm_T.absorb_in_ro(&mut ro); + + // compute a challenge from the RO + let r = ro.squeeze(NUM_CHALLENGE_BITS); + + // fold the instance using `r` and `comm_T` + let U = U1.fold(U2, &comm_T, &r); + + // fold the witness using `r` and `T` + let W = W1.fold(W2, &T, &r)?; + + // return the folded instance and witness + Ok((Self { comm_T }, (U, W))) + } + + /// Takes as input a relaxed R1CS instance `U1` and R1CS instance `U2` + /// with the same shape and defined with respect to the same parameters, + /// and outputs a folded instance `U` with the same shape, + /// with the guarantee that the folded instance `U` + /// if and only if `U1` and `U2` are satisfiable. + pub fn verify( + &self, + ro_consts: &ROConstants, + pp_digest: &E::Scalar, + U1: &RelaxedR1CSInstance, + U2: &R1CSInstance, + ) -> Result, NovaError> { + // initialize a new RO + let mut ro = E::RO::new(ro_consts.clone(), NUM_FE_FOR_RO); + + // append the digest of pp to the transcript + ro.absorb(scalar_as_base::(*pp_digest)); + + // append U2 to transcript, U1 does not need to absorbed since U2.X[0] = Hash(params, U1, i, z0, zi) + U2.absorb_in_ro(&mut ro); + + // append `comm_T` to the transcript and obtain a challenge + self.comm_T.absorb_in_ro(&mut ro); + + // compute a challenge from the RO + let r = ro.squeeze(NUM_CHALLENGE_BITS); + + // fold the instance using `r` and `comm_T` + let U = U1.fold(U2, &self.comm_T, &r); + + // return the folded instance + Ok(U) + } +} + + + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + provider::PallasEngine, + traits::{Engine, Group}, + }; + use ff::PrimeField; + use proptest::{ + prelude::*, + strategy::{BoxedStrategy, Just, Strategy}, + }; + + type G = ::GE; + type Fr = ::Scalar; + + /// Wrapper struct around a field element that implements additional traits + #[derive(Clone, Debug, PartialEq, Eq)] + pub struct FWrap(pub F); + + impl Copy for FWrap {} + + #[cfg(not(target_arch = "wasm32"))] + /// Trait implementation for generating `FWrap` instances with proptest + impl Arbitrary for FWrap { + type Parameters = (); + type Strategy = BoxedStrategy; + + fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { + use rand::rngs::StdRng; + use rand_core::SeedableRng; + + let strategy = any::<[u8; 32]>() + .prop_map(|seed| FWrap(F::random(StdRng::from_seed(seed)))) + .no_shrink(); + strategy.boxed() + } + } + + #[test] + fn test_matrix_creation() { + let matrix_data = vec![ + (0, 1, Fr::from(2)), + (1, 2, Fr::from(3)), + (2, 0, Fr::from(4)), + ]; + let sparse_matrix = SparseMatrix::::new(&matrix_data, 3, 3); + + assert_eq!( + sparse_matrix.data, + vec![Fr::from(2), Fr::from(3), Fr::from(4)] + ); + assert_eq!(sparse_matrix.indices, vec![1, 2, 0]); + assert_eq!(sparse_matrix.indptr, vec![0, 1, 2, 3]); + } + + #[test] + fn test_matrix_vector_multiplication() { + let matrix_data = vec![ + (0, 1, Fr::from(2)), + (0, 2, Fr::from(7)), + (1, 2, Fr::from(3)), + (2, 0, Fr::from(4)), + ]; + let sparse_matrix = SparseMatrix::::new(&matrix_data, 3, 3); + let vector = vec![Fr::from(1), Fr::from(2), Fr::from(3)]; + + let result = sparse_matrix.multiply_vec(&vector); + + assert_eq!(result, vec![Fr::from(25), Fr::from(9), Fr::from(4)]); + } + + fn coo_strategy() -> BoxedStrategy)>> { + let coo_strategy = any::>().prop_flat_map(|f| (0usize..100, 0usize..100, Just(f))); + proptest::collection::vec(coo_strategy, 10).boxed() + } + + proptest! { + #[test] + fn test_matrix_iter(mut coo_matrix in coo_strategy()) { + // process the randomly generated coo matrix + coo_matrix.sort_by_key(|(row, col, _val)| (*row, *col)); + coo_matrix.dedup_by_key(|(row, col, _val)| (*row, *col)); + let coo_matrix = coo_matrix.into_iter().map(|(row, col, val)| { (row, col, val.0) }).collect::>(); + + let matrix = SparseMatrix::new(&coo_matrix, 100, 100); + + prop_assert_eq!(coo_matrix, matrix.iter().collect::>()); + } + } } \ No newline at end of file From 56b1b34ca22d75b130665fe2960c6e4b5b77d3e2 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Thu, 4 Jul 2024 18:11:07 +0700 Subject: [PATCH 09/24] Remove unnecessary helper methods in gadget.rs --- Cargo.lock | 316 +++++++++++++++++++++++-- Cargo.toml | 2 +- zkmemory/Cargo.toml | 1 + zkmemory/src/nova/gadgets.rs | 105 +------- zkmemory/src/nova/memory_commitment.rs | 10 +- 5 files changed, 301 insertions(+), 133 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0d00176..c8694fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,17 @@ version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +[[package]] +name = "addchain" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2e69442aa5628ea6951fa33e24efe8313f4321a91bd729fc2f75bdfc858570" +dependencies = [ + "num-bigint 0.3.3", + "num-integer", + "num-traits", +] + [[package]] name = "addr2line" version = "0.21.0" @@ -180,7 +191,7 @@ dependencies = [ "ark-serialize 0.3.0", "ark-std 0.3.0", "derivative", - "num-bigint", + "num-bigint 0.4.4", "num-traits", "paste", "rustc_version 0.3.3", @@ -200,7 +211,7 @@ dependencies = [ "derivative", "digest 0.10.7", "itertools 0.10.5", - "num-bigint", + "num-bigint 0.4.4", "num-traits", "paste", "rustc_version 0.4.0", @@ -233,7 +244,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" dependencies = [ - "num-bigint", + "num-bigint 0.4.4", "num-traits", "quote", "syn 1.0.109", @@ -245,7 +256,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "num-bigint", + "num-bigint 0.4.4", "num-traits", "proc-macro2", "quote", @@ -270,7 +281,7 @@ checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ "ark-std 0.4.0", "digest 0.10.7", - "num-bigint", + "num-bigint 0.4.4", ] [[package]] @@ -628,17 +639,50 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bellpepper" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae286c2cb403324ab644c7cc68dceb25fe52ca9429908a726d7ed272c1edf7b" +dependencies = [ + "bellpepper-core", + "byteorder", + "ff", +] + +[[package]] +name = "bellpepper-core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d8abb418570756396d722841b19edfec21d4e89e1cf8990610663040ecb1aea" +dependencies = [ + "blake2s_simd", + "byteorder", + "ff", + "serde", + "thiserror", +] + [[package]] name = "bigdecimal" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" dependencies = [ - "num-bigint", + "num-bigint 0.4.4", "num-integer", "num-traits", ] +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bindgen" version = "0.66.1" @@ -715,6 +759,17 @@ dependencies = [ "constant_time_eq", ] +[[package]] +name = "blake2s_simd" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -722,7 +777,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ "block-padding", - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -731,7 +786,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -768,6 +823,22 @@ dependencies = [ "zeroize", ] +[[package]] +name = "blstrs" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a8a8ed6fefbeef4a8c7b460e4110e12c5e22a5b7cf32621aae6ad650c4dcf29" +dependencies = [ + "blst", + "byte-slice-cast", + "ff", + "group", + "pairing", + "rand_core", + "serde", + "subtle", +] + [[package]] name = "borsh" version = "1.3.1" @@ -1151,7 +1222,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ - "generic-array", + "generic-array 0.14.7", "rand_core", "subtle", "zeroize", @@ -1163,7 +1234,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array", + "generic-array 0.14.7", "typenum", ] @@ -1173,7 +1244,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ - "generic-array", + "generic-array 0.14.7", "subtle", ] @@ -1228,7 +1299,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -1320,7 +1391,7 @@ dependencies = [ "crypto-bigint", "digest 0.10.7", "ff", - "generic-array", + "generic-array 0.14.7", "group", "pkcs8", "rand_core", @@ -1446,10 +1517,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "bitvec", + "byteorder", + "ff_derive", "rand_core", "subtle", ] +[[package]] +name = "ff_derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f54704be45ed286151c5e11531316eaef5b8f5af7d597b806fdb8af108d84a" +dependencies = [ + "addchain", + "cfg-if", + "num-bigint 0.3.3", + "num-integer", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "finl_unicode" version = "1.2.0" @@ -1659,6 +1748,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "generic-array" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "152dd546e5bdac80844ce6befabb9af5784ce375cb6cea554aed99fe2d1fb169" +dependencies = [ + "typenum", +] + [[package]] name = "getrandom" version = "0.2.12" @@ -1666,8 +1764,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1701,7 +1801,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", + "rand", "rand_core", + "rand_xorshift", "subtle", ] @@ -1736,7 +1838,7 @@ dependencies = [ "maybe-rayon", "rand_chacha", "rand_core", - "sha3", + "sha3 0.9.1", "tracing", ] @@ -1750,7 +1852,7 @@ dependencies = [ "ff", "group", "lazy_static", - "num-bigint", + "num-bigint 0.4.4", "num-traits", "pasta_curves", "paste", @@ -1768,7 +1870,7 @@ dependencies = [ "ff", "group", "lazy_static", - "num-bigint", + "num-bigint 0.4.4", "num-traits", "pasta_curves", "paste", @@ -1778,6 +1880,31 @@ dependencies = [ "subtle", ] +[[package]] +name = "halo2curves" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db81d01d0bbfec9f624d7590fc6929ee2537a64ec1e080d8f8c9e2d2da291405" +dependencies = [ + "blake2b_simd", + "ff", + "group", + "hex", + "lazy_static", + "num-bigint 0.4.4", + "num-traits", + "pairing", + "pasta_curves", + "paste", + "rand", + "rand_core", + "rayon", + "serde", + "serde_arrays", + "static_assertions", + "subtle", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1844,6 +1971,9 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] [[package]] name = "hex-literal" @@ -1886,7 +2016,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" dependencies = [ "digest 0.9.0", - "generic-array", + "generic-array 0.14.7", "hmac 0.8.1", ] @@ -2423,6 +2553,25 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "neptune" +version = "13.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06626c9ac04c894e9a23d061ba1309f28506cdc5fe64156d28a15fb57fc8e438" +dependencies = [ + "bellpepper", + "bellpepper-core", + "blake2s_simd", + "blstrs", + "byteorder", + "ff", + "generic-array 0.14.7", + "log", + "pasta_curves", + "serde", + "trait-set", +] + [[package]] name = "nix" version = "0.27.1" @@ -2480,6 +2629,39 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "nova-snark" +version = "0.37.0" +source = "git+https://github.com/microsoft/Nova#d2c52bd73e6a91c20f23ae4971f24ad70a9d0395" +dependencies = [ + "bellpepper", + "bellpepper-core", + "bincode", + "bitvec", + "byteorder", + "digest 0.10.7", + "ff", + "generic-array 1.0.1", + "getrandom", + "group", + "halo2curves 0.6.1", + "itertools 0.12.1", + "neptune", + "num-bigint 0.4.4", + "num-integer", + "num-traits", + "once_cell", + "pasta-msm", + "pasta_curves", + "rand_chacha", + "rand_core", + "rayon", + "serde", + "sha3 0.10.8", + "subtle", + "thiserror", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -2496,7 +2678,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" dependencies = [ - "num-bigint", + "num-bigint 0.4.4", "num-complex", "num-integer", "num-iter", @@ -2504,6 +2686,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.4.4" @@ -2513,6 +2706,8 @@ dependencies = [ "autocfg", "num-integer", "num-traits", + "rand", + "serde", ] [[package]] @@ -2569,7 +2764,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ "autocfg", - "num-bigint", + "num-bigint 0.4.4", "num-integer", "num-traits", ] @@ -2704,6 +2899,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "pairing" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" +dependencies = [ + "group", +] + [[package]] name = "parity-scale-codec" version = "3.6.9" @@ -2784,6 +2988,19 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "pasta-msm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e85d75eba3e7e9ee3bd11342b669185e194dadda3557934bc1000d9b87159d3" +dependencies = [ + "cc", + "pasta_curves", + "semolina", + "sppark", + "which", +] + [[package]] name = "pasta_curves" version = "0.5.1" @@ -2793,8 +3010,10 @@ dependencies = [ "blake2b_simd", "ff", "group", + "hex", "lazy_static", "rand", + "serde", "static_assertions", "subtle", ] @@ -3387,7 +3606,7 @@ dependencies = [ "ark-ff 0.4.2", "bytes", "fastrlp", - "num-bigint", + "num-bigint 0.4.4", "num-traits", "parity-scale-codec", "primitive-types", @@ -3823,7 +4042,7 @@ checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", - "generic-array", + "generic-array 0.14.7", "pkcs8", "subtle", "zeroize", @@ -3847,6 +4066,16 @@ dependencies = [ "cc", ] +[[package]] +name = "semolina" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b0111fd4fa831becb0606b9a2285ef3bee3c6a70d690209b8ae9514e9befe23" +dependencies = [ + "cc", + "glob", +] + [[package]] name = "semver" version = "0.11.0" @@ -3880,6 +4109,15 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde_arrays" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38636132857f68ec3d5f3eb121166d2af33cb55174c4d5ff645db6165cbef0fd" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" version = "1.0.195" @@ -3958,6 +4196,16 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + [[package]] name = "sha3-asm" version = "0.1.0" @@ -4084,6 +4332,16 @@ dependencies = [ "der", ] +[[package]] +name = "sppark" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb266b15daead53670d477d7e136b8fc92d46e31bb9007ac46d304df23689a4b" +dependencies = [ + "cc", + "which", +] + [[package]] name = "sqlformat" version = "0.2.3" @@ -4299,7 +4557,7 @@ dependencies = [ "futures-core", "futures-io", "futures-util", - "generic-array", + "generic-array 0.14.7", "hex", "hkdf", "hmac 0.12.1", @@ -4352,7 +4610,7 @@ dependencies = [ "log", "md-5", "memchr", - "num-bigint", + "num-bigint 0.4.4", "once_cell", "rand", "rust_decimal", @@ -4787,6 +5045,17 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "trait-set" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b79e2e9c9ab44c6d7c20d5976961b47e8f49ac199154daa514b77cd1ab536625" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "try-lock" version = "0.2.5" @@ -5364,6 +5633,7 @@ dependencies = [ "halo2curves 0.3.2", "hex", "itertools 0.12.1", + "nova-snark", "rand", "rand_core", "rbtree", diff --git a/Cargo.toml b/Cargo.toml index 98e02c9..5894ac1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,4 +38,4 @@ rand_core = "0.6.4" rand = "0.8.5" serde_json = "1.0.87" serde = "1.0.147" -Nova = { git = "https://github.com/microsoft/Nova" } \ No newline at end of file +nova-snark = { git = "https://github.com/microsoft/Nova" } \ No newline at end of file diff --git a/zkmemory/Cargo.toml b/zkmemory/Cargo.toml index 233e47a..00860f1 100644 --- a/zkmemory/Cargo.toml +++ b/zkmemory/Cargo.toml @@ -28,3 +28,4 @@ ethnum = { workspace = true } hex = { workspace = true } rbtree = { workspace = true } itertools = "0.12.1" +nova-snark = { workspace = true } diff --git a/zkmemory/src/nova/gadgets.rs b/zkmemory/src/nova/gadgets.rs index 481faa6..f4d7f22 100644 --- a/zkmemory/src/nova/gadgets.rs +++ b/zkmemory/src/nova/gadgets.rs @@ -1,3 +1,4 @@ + use alloc::vec::Vec; use alloc::{format, vec}; use core::marker::PhantomData; @@ -8,111 +9,10 @@ pub struct IVCStep { pub(crate) witness: Vec, } -#[derive(Clone, Copy, Debug)] -pub struct Table { - col: Column, -} - -impl Table { - /// Construct the lookup Table. - pub fn construct(meta: &mut ConstraintSystem) -> Self { - Self { - col: meta.fixed_column(), - } - } - - /// Load the `Table` for range check - pub fn load(&self, region: &mut Region<'_, F>) -> Result<(), Error> { - for i in 0..N { - region.assign_fixed( - || format!("assign {} in fixed column of size {}", i, N), - self.col, - i, - || Value::known(F::from(i as u64)), - )?; - } - Ok(()) - } - - /// Return the list of expressions used to define the table - pub fn table_exprs(&self, meta: &mut VirtualCells<'_, F>) -> Vec> { - vec![meta.query_fixed(self.col, Rotation::cur())] - } - - /// Perform the range check - pub fn range_check( - &self, - meta: &mut ConstraintSystem, - msg: &'static str, - exp_fn: impl FnOnce(&mut VirtualCells<'_, F>) -> Expression, - ) { - meta.lookup_any(msg, |meta| { - let exp = exp_fn(meta); - vec![exp] - .into_iter() - .zip_eq(self.table_exprs(meta)) - .collect() - }); - } -} - -[derive(Clone, Copy, Debug)] -/// Config for binary number -pub struct BinaryConfig { - /// the list of bit representation - pub bits: [Column; N], - _marker: PhantomData, -} -impl BinaryConfig { - /// Requires that each bit is zero or one - pub fn configure(meta: &mut ConstraintSystem, selector: Column) -> Self { - let bits = [0; N].map(|_| meta.advice_column()); - let one = Expression::Constant(F::ONE); - bits.map(|bit| { - meta.create_gate("bit column is 0 or 1", |meta| { - let selector = meta.query_fixed(selector, Rotation::cur()); - let bit = meta.query_advice(bit, Rotation::cur()); - vec![selector * bit.clone() * (one.clone() - bit)] - }) - }); - BinaryConfig { - bits, - _marker: PhantomData, - } - } - - /// Map a value to its corresponding binary witness for the config - pub fn assign( - &self, - region: &mut Region<'_, F>, - offset: usize, - value: u8, - ) -> Result<(), Error> { - for (&bit, &column) in as_bits::(value).iter().zip(&self.bits) { - region.assign_advice( - || format!("binary number {:?}", column), - column, - offset, - || Value::known(F::from(bit as u64)), - )?; - } - Ok(()) - } -} -// convert a value into an binary array of size N -fn as_bits(value: u8) -> [u8; N] { - let mut value = value; - let mut bits = [0; N]; - for i in 0..N { - bits[N - 1 - i] = value % 2; - value /= 2; - } - bits -} /// return 1 if lhs=rhs as bits and 0 otherwise pub fn equal_value( @@ -206,6 +106,3 @@ impl TraceRecordWitnessTable { } } } - - - diff --git a/zkmemory/src/nova/memory_commitment.rs b/zkmemory/src/nova/memory_commitment.rs index 9cd25fe..07b8d5a 100644 --- a/zkmemory/src/nova/memory_commitment.rs +++ b/zkmemory/src/nova/memory_commitment.rs @@ -1,6 +1,6 @@ -use core::marker::PhantomData; + /// Reference to be added later. -use Nova::{ +use nova_snark::{ constants::{NUM_FE_WITHOUT_IO_FOR_CRHF, NUM_HASH_BITS}, gadgets::{ ecc::AllocatedPoint, @@ -18,7 +18,7 @@ use Nova::{ - +/// The section of circuit. Will Move to a seperate file later. pub struct NovaAugmentedCircuitInputs { params: E::Scalar, i: E::Base, @@ -308,7 +308,7 @@ impl<'a, E: Engine, SC: StepCircuit> NovaAugmentedCircuit<'a, E, SC> { } } - +// The section of R1CS Matrix. Will Move to a seperate file later. pub struct SparseMatrix { /// all non-zero values in the matrix pub data: Vec, @@ -436,7 +436,7 @@ impl<'a, F: PrimeField> Iterator for Iter<'a, F> { } - +// The section of NIFS. Will Move to the seperate file later. /// NIFS Prove and Verify /// TODO: Check the RO Trait Nova and implement it From 064eab1fa892fe839ef7781de8a9ea540fc60e8e Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Fri, 9 Aug 2024 18:37:48 +0700 Subject: [PATCH 10/24] Reconfigure and fix existing bugs This PR reorganize the circuits, fix existing bugs and create some testcases. --- Cargo.lock | 1313 ++++++++--------- Cargo.toml | 3 +- rust-toolchain | 2 +- zkmemory/Cargo.toml | 1 + zkmemory/src/lib.rs | 4 +- zkmemory/src/nova/gadgets.rs | 108 -- zkmemory/src/nova/memory_commitment.rs | 618 -------- .../src/nova/memory_consistency_circuit.rs | 189 +++ zkmemory/src/nova/mod.rs | 9 +- zkmemory/src/nova/testcases.rs | 135 ++ zkmemory/src/poseidon/poseidon_hash.rs | 7 +- 11 files changed, 957 insertions(+), 1432 deletions(-) delete mode 100644 zkmemory/src/nova/gadgets.rs delete mode 100644 zkmemory/src/nova/memory_commitment.rs create mode 100644 zkmemory/src/nova/memory_consistency_circuit.rs create mode 100644 zkmemory/src/nova/testcases.rs diff --git a/Cargo.lock b/Cargo.lock index c8694fa..9757228 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,9 +21,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -47,9 +47,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.9" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d713b3834d76b85304d4d525563c1276e2e30dc97cc67bfb4585a4a29fc2c89f" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "getrandom", @@ -60,9 +60,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -75,15 +75,15 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alloy-primitives" -version = "0.6.0" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3729132072f369bc4e8e6e070f9cf4deb3490fc9b9eea6f71f75ec19406df811" +checksum = "600d34d8de81e23b6d909c094e23b3d357e01ca36b78a8c5424c501eedbe86f0" dependencies = [ "alloy-rlp", "bytes", @@ -103,9 +103,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.4" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" +checksum = "26154390b1d205a4a7ac7352aa2eb4f81f391399d4e2f546fb81a2f8bb383f62" dependencies = [ "arrayvec", "bytes", @@ -128,47 +128,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.7" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd2405b3ac1faab2990b74d728624cd9fd115651fcecc7c2d8daf01376275ba" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -176,9 +177,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "ark-ff" @@ -191,7 +192,7 @@ dependencies = [ "ark-serialize 0.3.0", "ark-std 0.3.0", "derivative", - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-traits", "paste", "rustc_version 0.3.3", @@ -211,7 +212,7 @@ dependencies = [ "derivative", "digest 0.10.7", "itertools 0.10.5", - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-traits", "paste", "rustc_version 0.4.0", @@ -244,7 +245,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" dependencies = [ - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-traits", "quote", "syn 1.0.109", @@ -256,7 +257,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-traits", "proc-macro2", "quote", @@ -281,7 +282,7 @@ checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ "ark-std 0.4.0", "digest 0.10.7", - "num-bigint 0.4.4", + "num-bigint 0.4.6", ] [[package]] @@ -306,9 +307,9 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" [[package]] name = "arrayvec" @@ -339,12 +340,11 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.1.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ "concurrent-queue", - "event-listener 4.0.3", "event-listener-strategy", "futures-core", "pin-project-lite", @@ -352,15 +352,14 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.8.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" dependencies = [ - "async-lock 3.3.0", "async-task", "concurrent-queue", - "fastrand 2.0.1", - "futures-lite 2.2.0", + "fastrand 2.1.0", + "futures-lite 2.3.0", "slab", ] @@ -370,12 +369,12 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel 2.1.1", + "async-channel 2.3.1", "async-executor", - "async-io 2.2.2", - "async-lock 3.3.0", + "async-io 2.3.3", + "async-lock 3.4.0", "blocking", - "futures-lite 2.2.0", + "futures-lite 2.3.0", "once_cell", "tokio", ] @@ -402,18 +401,18 @@ dependencies = [ [[package]] name = "async-io" -version = "2.2.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" dependencies = [ - "async-lock 3.3.0", + "async-lock 3.4.0", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.2.0", + "futures-lite 2.3.0", "parking", - "polling 3.3.2", - "rustix 0.38.30", + "polling 3.7.2", + "rustix 0.38.34", "slab", "tracing", "windows-sys 0.52.0", @@ -430,11 +429,11 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener 4.0.3", + "event-listener 5.3.1", "event-listener-strategy", "pin-project-lite", ] @@ -485,24 +484,24 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "async-task" -version = "4.7.0" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -529,16 +528,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -[[package]] -name = "atomic-write-file" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" -dependencies = [ - "nix", - "rand", -] - [[package]] name = "atty" version = "0.2.14" @@ -552,9 +541,9 @@ dependencies = [ [[package]] name = "aurora-engine-modexp" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfacad86e9e138fca0670949eb8ed4ffdf73a55bded8887efe0863cd1a3a6f70" +checksum = "0aef7712851e524f35fbbb74fa6599c5cd8692056a1c36f9ca0d2001b670e7e5" dependencies = [ "hex", "num", @@ -562,27 +551,26 @@ dependencies = [ [[package]] name = "auto_impl" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -669,7 +657,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" dependencies = [ - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-integer", "num-traits", ] @@ -683,29 +671,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bindgen" -version = "0.66.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7" -dependencies = [ - "bitflags 2.4.1", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.48", - "which", -] - [[package]] name = "bit-set" version = "0.5.3" @@ -729,9 +694,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" dependencies = [ "serde", ] @@ -797,25 +762,22 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] name = "blocking" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ - "async-channel 2.1.1", - "async-lock 3.3.0", + "async-channel 2.3.1", "async-task", - "fastrand 2.0.1", "futures-io", - "futures-lite 2.2.0", + "futures-lite 2.3.0", "piper", - "tracing", ] [[package]] name = "blst" -version = "0.3.11" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +checksum = "4378725facc195f1a538864863f6de233b500a8862747e7f165078a419d5e874" dependencies = [ "cc", "glob", @@ -841,9 +803,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f58b559fd6448c6e2fd0adb5720cd98a2506594cafa4737ff98c396f3e82f667" +checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" dependencies = [ "borsh-derive", "cfg_aliases", @@ -851,34 +813,34 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aadb5b6ccbd078890f6d7003694e33816e6b784358f18e15e7e6d9f065a57cd" +checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" dependencies = [ "once_cell", - "proc-macro-crate 3.0.0", + "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "syn_derive", ] [[package]] name = "bstr" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", - "regex-automata 0.4.3", + "regex-automata 0.4.7", "serde", ] [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-slice-cast" @@ -888,9 +850,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytecheck" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" dependencies = [ "bytecheck_derive", "ptr_meta", @@ -899,9 +861,9 @@ dependencies = [ [[package]] name = "bytecheck_derive" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" dependencies = [ "proc-macro2", "quote", @@ -916,17 +878,16 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "c-kzg" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32700dc7904064bb64e857d38a1766607372928e2466ee5f02a869829b3297d7" +checksum = "94a4bc5367b6284358d2a6a6a1dc2d92ec4b86034561c3b9d3341909752fd848" dependencies = [ - "bindgen", "blst", "cc", "glob", @@ -937,20 +898,20 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" [[package]] name = "cargo-config2" -version = "0.1.19" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a7fb69d74d76f8c254afd1c0e76aca40c305707b28aebe3c5a0fd2ee62aeeeb" +checksum = "d83ce0be8bd1479e5de6202def660e6c7e27e4e0599bffa4fed05bd380ec2ede" dependencies = [ "home", "serde", "serde_derive", - "toml_edit 0.22.7", + "toml_edit 0.22.20", ] [[package]] @@ -982,21 +943,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] +checksum = "504bdec147f2cc13c8b57ed9401fd8a147cc66b67ad5cb241394244f2c947549" [[package]] name = "cfg-if" @@ -1006,32 +955,21 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cfg_aliases" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "serde", - "windows-targets 0.48.5", -] - -[[package]] -name = "clang-sys" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" -dependencies = [ - "glob", - "libc", - "libloading", + "windows-targets 0.52.6", ] [[package]] @@ -1046,30 +984,30 @@ dependencies = [ "clap_lex 0.2.4", "indexmap 1.9.3", "once_cell", - "strsim", + "strsim 0.10.0", "termcolor", "textwrap", ] [[package]] name = "clap" -version = "4.4.16" +version = "4.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e54881c004cec7895b0068a0a954cd5d62da01aef83fa35b1e594497bf5445" +checksum = "c937d4061031a6d0c8da4b9a4f98a172fc2976dfb1c19213a9cf7d0d3c837e36" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.4.16" +version = "4.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59cb82d7f531603d2fd1f507441cdd35184fa81beff7bd489570de7f773460bb" +checksum = "85379ba512b21a328adf887e85f7742d12e96eb31f3ef077df4ffc26b506ffed" dependencies = [ "anstream", "anstyle", - "clap_lex 0.6.0", - "strsim", + "clap_lex 0.7.2", + "strsim 0.11.1", ] [[package]] @@ -1096,30 +1034,30 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "concurrent-queue" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] [[package]] name = "const-hex" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" +checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" dependencies = [ "cfg-if", "cpufeatures", @@ -1163,9 +1101,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.0.1" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" dependencies = [ "crc-catalog", ] @@ -1206,9 +1144,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -1250,9 +1188,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "pem-rfc7468", @@ -1282,15 +1220,15 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version 0.4.0", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] @@ -1374,9 +1312,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" dependencies = [ "serde", ] @@ -1402,20 +1340,20 @@ dependencies = [ [[package]] name = "enumn" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" +checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "env_logger" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -1432,9 +1370,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1465,9 +1403,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "4.0.3" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", @@ -1476,11 +1414,11 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ - "event-listener 4.0.3", + "event-listener 5.3.1", "pin-project-lite", ] @@ -1495,9 +1433,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fastrlp" @@ -1539,12 +1477,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "finl_unicode" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" - [[package]] name = "fixed-hash" version = "0.8.0" @@ -1659,7 +1591,7 @@ checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" dependencies = [ "futures-core", "lock_api", - "parking_lot 0.12.1", + "parking_lot 0.12.3", ] [[package]] @@ -1685,11 +1617,11 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand 2.0.1", + "fastrand 2.1.0", "futures-core", "futures-io", "parking", @@ -1704,7 +1636,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -1750,18 +1682,18 @@ dependencies = [ [[package]] name = "generic-array" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "152dd546e5bdac80844ce6befabb9af5784ce375cb6cea554aed99fe2d1fb169" +checksum = "96512db27971c2c3eece70a1e106fbe6c87760234e31e8f7e5634912fe52794a" dependencies = [ "typenum", ] [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -1772,9 +1704,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glob" @@ -1809,17 +1741,17 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.1" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "991910e35c615d8cab86b5ab04be67e6ad24d2bf5f4f11fdbbed26da999bbeab" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", "http", - "indexmap 2.1.0", + "indexmap 2.3.0", "slab", "tokio", "tokio-util", @@ -1852,7 +1784,7 @@ dependencies = [ "ff", "group", "lazy_static", - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-traits", "pasta_curves", "paste", @@ -1870,7 +1802,7 @@ dependencies = [ "ff", "group", "lazy_static", - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-traits", "pasta_curves", "paste", @@ -1891,7 +1823,7 @@ dependencies = [ "group", "hex", "lazy_static", - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-traits", "pairing", "pasta_curves", @@ -1916,11 +1848,11 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash 0.8.9", + "ahash 0.8.11", "allocator-api2", ] @@ -1930,7 +1862,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -1962,9 +1894,15 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "hex" @@ -2031,9 +1969,9 @@ dependencies = [ [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -2042,9 +1980,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http", @@ -2052,9 +1990,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", @@ -2065,9 +2003,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -2083,9 +2021,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "1.1.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", @@ -2097,6 +2035,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", + "smallvec", "tokio", "want", ] @@ -2113,16 +2052,16 @@ dependencies = [ "http-body", "hyper", "pin-project-lite", - "socket2 0.5.5", + "socket2 0.5.7", "tokio", "tracing", ] [[package]] name = "iana-time-zone" -version = "0.1.59" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2183,12 +2122,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -2199,14 +2138,14 @@ checksum = "0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -2217,19 +2156,19 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.9", "libc", "windows-sys 0.48.0", ] [[package]] name = "is-terminal" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi 0.3.3", - "rustix 0.38.30", + "hermit-abi 0.3.9", + "libc", "windows-sys 0.52.0", ] @@ -2242,6 +2181,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.10.5" @@ -2262,15 +2207,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -2300,9 +2245,9 @@ dependencies = [ [[package]] name = "keccak-asm" -version = "0.1.0" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb8515fff80ed850aea4a1595f2e519c003e2a00a82fe168ebf5269196caf444" +checksum = "422fbc7ff2f2f5bdffeb07718e5a5324dca72b0c9293d50df4026652385e3314" dependencies = [ "digest 0.10.7", "sha3-asm", @@ -2319,24 +2264,18 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.5.2", + "spin 0.9.8", ] -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "lcov2cobertura" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dbf995693421c277b440a71144e33246d8a76808418f7430329e44b2e95c03" +checksum = "3059082d010970e36c402fd43c12114f52f32b15641c7bc45071564ca7af89f3" dependencies = [ "anyhow", "quick-xml", @@ -2352,9 +2291,9 @@ checksum = "baff4b617f7df3d896f97fe922b64817f6cd9a756bb81d40f8883f2f66dcb401" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libecvrf" @@ -2366,16 +2305,6 @@ dependencies = [ "tiny-keccak", ] -[[package]] -name = "libloading" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "libm" version = "0.2.8" @@ -2384,13 +2313,12 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "libc", - "redox_syscall 0.4.1", ] [[package]] @@ -2460,15 +2388,15 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2476,9 +2404,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" dependencies = [ "value-bag", ] @@ -2514,9 +2442,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "migration" @@ -2535,22 +2463,23 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.10" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2572,24 +2501,13 @@ dependencies = [ "trait-set", ] -[[package]] -name = "nix" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" -dependencies = [ - "bitflags 2.4.1", - "cfg-if", - "libc", -] - [[package]] name = "node" version = "1.0.0" dependencies = [ "base64-url", "bytes", - "clap 4.4.16", + "clap 4.5.14", "dotenv", "env_logger", "hex", @@ -2601,7 +2519,7 @@ dependencies = [ "log", "regex", "revm", - "sea-orm 0.12.14", + "sea-orm 0.12.15", "serde", "serde_json", "sha2 0.10.8", @@ -2622,11 +2540,11 @@ dependencies = [ [[package]] name = "normpath" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5831952a9476f2fed74b77d74182fa5ddc4d21c72ec45a333b250e3ed0272804" +checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2641,13 +2559,13 @@ dependencies = [ "byteorder", "digest 0.10.7", "ff", - "generic-array 1.0.1", + "generic-array 1.1.0", "getrandom", "group", "halo2curves 0.6.1", "itertools 0.12.1", "neptune", - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-integer", "num-traits", "once_cell", @@ -2674,11 +2592,11 @@ dependencies = [ [[package]] name = "num" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-complex", "num-integer", "num-iter", @@ -2699,11 +2617,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", "rand", @@ -2729,28 +2646,33 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -2759,21 +2681,20 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-integer", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -2785,15 +2706,15 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.9", "libc", ] [[package]] name = "object" -version = "0.32.2" +version = "0.36.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" dependencies = [ "memchr", ] @@ -2806,9 +2727,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "opener" @@ -2832,12 +2753,12 @@ dependencies = [ [[package]] name = "os_pipe" -version = "1.1.5" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9" +checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2890,7 +2811,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -2910,9 +2831,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec", "bitvec", @@ -2924,11 +2845,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 2.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -2953,12 +2874,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.9", + "parking_lot_core 0.9.10", ] [[package]] @@ -2977,15 +2898,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", + "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -3020,15 +2941,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pem-rfc7468" @@ -3047,9 +2962,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.6" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ "memchr", "thiserror", @@ -3058,9 +2973,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -3070,12 +2985,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" dependencies = [ "atomic-waker", - "fastrand 2.0.1", + "fastrand 2.1.0", "futures-io", ] @@ -3102,9 +3017,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "polling" @@ -3124,14 +3039,15 @@ dependencies = [ [[package]] name = "polling" -version = "3.3.2" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545c980a3880efd47b2e262f6a4bb6daad6555cf3367aa9c4e52895f69537a41" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" dependencies = [ "cfg-if", "concurrent-queue", + "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.30", + "rustix 0.38.34", "tracing", "windows-sys 0.52.0", ] @@ -3144,18 +3060,11 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "prettyplease" -version = "0.2.16" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ - "proc-macro2", - "syn 2.0.48", + "zerocopy", ] [[package]] @@ -3171,20 +3080,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" -dependencies = [ - "toml_edit 0.20.7", -] - -[[package]] -name = "proc-macro-crate" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b2685dd208a3771337d8d386a89840f0f43cd68be8dae90a5f8c2384effc9cd" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_edit 0.21.0", + "toml_edit 0.21.1", ] [[package]] @@ -3213,28 +3113,28 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.4.1", + "bitflags 2.6.0", "lazy_static", "num-traits", "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.8.2", + "regex-syntax 0.8.4", "rusty-fork", "tempfile", "unarray", @@ -3277,9 +3177,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -3331,9 +3231,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -3341,9 +3241,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3373,11 +3273,20 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", "libredox", @@ -3386,14 +3295,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", - "regex-syntax 0.8.2", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -3407,13 +3316,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.4", ] [[package]] @@ -3424,15 +3333,15 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "rend" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" dependencies = [ "bytecheck", ] @@ -3478,12 +3387,12 @@ source = "git+https://github.com/bluealloy/revm.git?rev=5e6546e#5e6546e2a57bbc76 dependencies = [ "alloy-primitives", "auto_impl", - "bitflags 2.4.1", + "bitflags 2.6.0", "bitvec", "c-kzg", "derive_more", "enumn", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "once_cell", ] @@ -3515,16 +3424,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3538,9 +3448,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.43" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527a97cdfef66f65998b5f3b637c26f5a5ec09cc52a3f9932313ac645f4190f5" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" dependencies = [ "bitvec", "bytecheck", @@ -3556,9 +3466,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.43" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5c462a1328c8e67e4d6dbad1eb0355dd43e8ab432c6e227a43657f16ade5033" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" dependencies = [ "proc-macro2", "quote", @@ -3597,16 +3507,16 @@ dependencies = [ [[package]] name = "ruint" -version = "1.11.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" +checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", "ark-ff 0.4.2", "bytes", "fastrlp", - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-traits", "parity-scale-codec", "primitive-types", @@ -3621,15 +3531,15 @@ dependencies = [ [[package]] name = "ruint-macro" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rust_decimal" -version = "1.33.1" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06676aec5ccb8fc1da723cc8c0f9a46549f21ebb8753d3915c6c41db1e7f1dc4" +checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" dependencies = [ "arrayvec", "borsh", @@ -3643,15 +3553,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hex" @@ -3674,7 +3578,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.21", + "semver 1.0.23", ] [[package]] @@ -3693,14 +3597,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys 0.4.12", + "linux-raw-sys 0.4.14", "windows-sys 0.52.0", ] @@ -3718,11 +3622,11 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "rustls-webpki", "sct", ] @@ -3742,15 +3646,15 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rusty-fork" @@ -3766,9 +3670,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -3791,7 +3695,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -3805,7 +3709,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -3833,9 +3737,9 @@ dependencies = [ [[package]] name = "sea-orm" -version = "0.12.14" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6632f499b80cc6aaa781b302e4c9fae663e0e3dcf2640e9d80034d5b10731efe" +checksum = "c8814e37dc25de54398ee62228323657520b7f29713b8e238649385dbe473ee0" dependencies = [ "async-stream", "async-trait", @@ -3845,12 +3749,12 @@ dependencies = [ "log", "ouroboros 0.17.2", "rust_decimal", - "sea-orm-macros 0.12.14", + "sea-orm-macros 0.12.15", "sea-query 0.30.7", "sea-query-binder 0.5.0", "serde", "serde_json", - "sqlx 0.7.3", + "sqlx 0.7.4", "strum", "thiserror", "time", @@ -3890,15 +3794,15 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "0.12.14" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec13bfb4c4aef208f68dbea970dd40d13830c868aa8dcb4e106b956e6bb4f2fa" +checksum = "5e115c6b078e013aa963cc2d38c196c2c40b05f03d0ac872fe06b6e0d5265603" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", "sea-bae", - "syn 2.0.48", + "syn 2.0.72", "unicode-ident", ] @@ -3965,7 +3869,7 @@ dependencies = [ "rust_decimal", "sea-query 0.30.7", "serde_json", - "sqlx 0.7.3", + "sqlx 0.7.4", "time", "uuid", ] @@ -4050,9 +3954,9 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.28.1" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f622567e3b4b38154fb8190bcf6b160d7a4301d70595a49195b48c116007a27" +checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" dependencies = [ "secp256k1-sys", ] @@ -4087,9 +3991,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "semver-parser" @@ -4102,9 +4006,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.195" +version = "1.0.205" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150" dependencies = [ "serde_derive", ] @@ -4120,31 +4024,32 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.205" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -4208,9 +4113,9 @@ dependencies = [ [[package]] name = "sha3-asm" -version = "0.1.0" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac61da6b35ad76b195eb4771210f947734321a8d81d7738e1580d953bc7a15e" +checksum = "57d79b758b7cb2085612b11a235055e485605a5103faccdd633f35bd7aee69dd" dependencies = [ "cc", "cfg-if", @@ -4227,12 +4132,12 @@ dependencies = [ [[package]] name = "shared_child" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" +checksum = "09fa9338aed9a1df411814a5b2252f7cd206c55ae9bf2fa763f8de84603aa60c" dependencies = [ "libc", - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -4241,17 +4146,11 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" -[[package]] -name = "shlex" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" - [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -4283,9 +4182,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" @@ -4299,12 +4198,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -4334,9 +4233,9 @@ dependencies = [ [[package]] name = "sppark" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb266b15daead53670d477d7e136b8fc92d46e31bb9007ac46d304df23689a4b" +checksum = "c55f3833d30846a26110dccb1d5366314c2c52516a9173b74238c16b24b1a9f9" dependencies = [ "cc", "which", @@ -4344,11 +4243,10 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" +checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f" dependencies = [ - "itertools 0.12.1", "nom", "unicode_categories", ] @@ -4365,12 +4263,12 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" +checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa" dependencies = [ - "sqlx-core 0.7.3", - "sqlx-macros 0.7.3", + "sqlx-core 0.7.4", + "sqlx-macros 0.7.4", "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", @@ -4431,11 +4329,11 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" +checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" dependencies = [ - "ahash 0.8.9", + "ahash 0.8.11", "atoi 2.0.0", "bigdecimal", "byteorder", @@ -4443,7 +4341,6 @@ dependencies = [ "chrono", "crc", "crossbeam-queue", - "dotenvy", "either", "event-listener 2.5.3", "futures-channel", @@ -4453,14 +4350,14 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.1.0", + "indexmap 2.3.0", "log", "memchr", "once_cell", "paste", "percent-encoding", "rust_decimal", - "rustls 0.21.10", + "rustls 0.21.12", "rustls-pemfile", "serde", "serde_json", @@ -4474,7 +4371,7 @@ dependencies = [ "tracing", "url", "uuid", - "webpki-roots 0.25.3", + "webpki-roots 0.25.4", ] [[package]] @@ -4498,24 +4395,23 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" +checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127" dependencies = [ "proc-macro2", "quote", - "sqlx-core 0.7.3", + "sqlx-core 0.7.4", "sqlx-macros-core", "syn 1.0.109", ] [[package]] name = "sqlx-macros-core" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" +checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8" dependencies = [ - "atomic-write-file", "dotenvy", "either", "heck 0.4.1", @@ -4526,7 +4422,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.8", - "sqlx-core 0.7.3", + "sqlx-core 0.7.4", "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", @@ -4538,14 +4434,14 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" +checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" dependencies = [ "atoi 2.0.0", "base64 0.21.7", "bigdecimal", - "bitflags 2.4.1", + "bitflags 2.6.0", "byteorder", "bytes", "chrono", @@ -4574,7 +4470,7 @@ dependencies = [ "sha1", "sha2 0.10.8", "smallvec", - "sqlx-core 0.7.3", + "sqlx-core 0.7.4", "stringprep", "thiserror", "time", @@ -4585,14 +4481,14 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" +checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" dependencies = [ "atoi 2.0.0", "base64 0.21.7", "bigdecimal", - "bitflags 2.4.1", + "bitflags 2.6.0", "byteorder", "chrono", "crc", @@ -4610,16 +4506,15 @@ dependencies = [ "log", "md-5", "memchr", - "num-bigint 0.4.4", + "num-bigint 0.4.6", "once_cell", "rand", "rust_decimal", "serde", "serde_json", - "sha1", "sha2 0.10.8", "smallvec", - "sqlx-core 0.7.3", + "sqlx-core 0.7.4", "stringprep", "thiserror", "time", @@ -4641,9 +4536,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" +checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" dependencies = [ "atoi 2.0.0", "chrono", @@ -4657,7 +4552,7 @@ dependencies = [ "log", "percent-encoding", "serde", - "sqlx-core 0.7.3", + "sqlx-core 0.7.4", "time", "tracing", "url", @@ -4673,13 +4568,13 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stringprep" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" dependencies = [ - "finl_unicode", "unicode-bidi", "unicode-normalization", + "unicode-properties", ] [[package]] @@ -4688,6 +4583,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "strum" version = "0.25.0" @@ -4709,9 +4610,9 @@ dependencies = [ [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -4726,9 +4627,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -4744,7 +4645,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -4755,15 +4656,15 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.9.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", - "fastrand 2.0.1", - "redox_syscall 0.4.1", - "rustix 0.38.30", - "windows-sys 0.52.0", + "fastrand 2.1.0", + "once_cell", + "rustix 0.38.34", + "windows-sys 0.59.0", ] [[package]] @@ -4777,35 +4678,35 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -4822,12 +4723,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -4842,10 +4744,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -4860,9 +4763,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -4875,32 +4778,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2 0.5.7", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -4916,9 +4818,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite", @@ -4927,60 +4829,48 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.20.7" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.3.0", "toml_datetime", - "winnow 0.5.34", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.21.0" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.1.0", - "toml_datetime", - "winnow 0.5.34", -] - -[[package]] -name = "toml_edit" -version = "0.22.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18769cd1cec395d70860ceb4d932812a0b4d06b1a4bb336745a4d21b9496e992" -dependencies = [ - "indexmap 2.1.0", + "indexmap 2.3.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.5", + "winnow 0.6.18", ] [[package]] @@ -5003,7 +4893,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -5094,9 +4984,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -5106,18 +4996,24 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-properties" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" + [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode_categories" @@ -5139,9 +5035,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -5156,15 +5052,15 @@ checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.6.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "getrandom", "rand", @@ -5174,13 +5070,13 @@ dependencies = [ [[package]] name = "uuid-macro-internal" -version = "1.6.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49e7f3f3db8040a100710a11932239fd30697115e2ba4107080d8252939845e" +checksum = "ee1cd046f83ea2c4e920d6ee9f7c3537ef928d75dce5d84a87c2c5d6b3999a3a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -5191,9 +5087,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "value-bag" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cdbaf5e132e593e9fc1de6a15bbec912395b11fb9719e061cf64f804524c503" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" [[package]] name = "vcpkg" @@ -5207,9 +5103,9 @@ version = "0.1.1" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wait-timeout" @@ -5222,9 +5118,9 @@ dependencies = [ [[package]] name = "waker-fn" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" [[package]] name = "walkdir" @@ -5255,11 +5151,17 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -5267,24 +5169,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -5294,9 +5196,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5304,28 +5206,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -5337,7 +5239,7 @@ version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -5352,9 +5254,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.3" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "which" @@ -5365,16 +5267,17 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.30", + "rustix 0.38.34", ] [[package]] name = "whoami" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" dependencies = [ - "wasm-bindgen", + "redox_syscall 0.4.1", + "wasite", "web-sys", ] @@ -5396,11 +5299,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -5415,7 +5318,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -5433,7 +5336,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -5453,17 +5365,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -5474,9 +5387,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -5486,9 +5399,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -5498,9 +5411,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -5510,9 +5429,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -5522,9 +5441,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -5534,9 +5453,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -5546,24 +5465,24 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.34" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] [[package]] name = "winnow" -version = "0.6.5" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] @@ -5579,29 +5498,30 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -5614,7 +5534,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -5625,6 +5545,7 @@ version = "0.1.0" name = "zkmemory" version = "0.1.1" dependencies = [ + "bellpepper-core", "cargo-llvm-cov", "ethnum", "ff", diff --git a/Cargo.toml b/Cargo.toml index 5894ac1..ab1fbe2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,4 +38,5 @@ rand_core = "0.6.4" rand = "0.8.5" serde_json = "1.0.87" serde = "1.0.147" -nova-snark = { git = "https://github.com/microsoft/Nova" } \ No newline at end of file +nova-snark = { git = "https://github.com/microsoft/Nova" } +bellpepper-core = { version="0.4.0", default-features = false } \ No newline at end of file diff --git a/rust-toolchain b/rust-toolchain index dc87e8a..97e9852 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.74.0 +1.80.1 diff --git a/zkmemory/Cargo.toml b/zkmemory/Cargo.toml index 00860f1..fbe8956 100644 --- a/zkmemory/Cargo.toml +++ b/zkmemory/Cargo.toml @@ -29,3 +29,4 @@ hex = { workspace = true } rbtree = { workspace = true } itertools = "0.12.1" nova-snark = { workspace = true } +bellpepper-core = { workspace = true } \ No newline at end of file diff --git a/zkmemory/src/lib.rs b/zkmemory/src/lib.rs index fe92914..a715ccc 100644 --- a/zkmemory/src/lib.rs +++ b/zkmemory/src/lib.rs @@ -1,7 +1,7 @@ //! This crate provides a simple RAM machine for use in the zkVM #![recursion_limit = "256"] #![cfg_attr(not(feature = "std"), no_std)] -#![deny( +/*#![deny( unused, warnings, future_incompatible, @@ -9,7 +9,7 @@ rust_2018_idioms, missing_docs, unused_imports -)] +)]*/ #![forbid(unsafe_code)] /// Base trait for generic type diff --git a/zkmemory/src/nova/gadgets.rs b/zkmemory/src/nova/gadgets.rs deleted file mode 100644 index f4d7f22..0000000 --- a/zkmemory/src/nova/gadgets.rs +++ /dev/null @@ -1,108 +0,0 @@ - -use alloc::vec::Vec; -use alloc::{format, vec}; -use core::marker::PhantomData; -use ff::{Field, PrimeField}; - -pub struct IVCStep { - pub(crate) instance: F, - pub(crate) witness: Vec, -} - - - - - - -/// return 1 if lhs=rhs as bits and 0 otherwise -pub fn equal_value( - lhs: [Expression; N], - rhs: u8, -) -> Expression { - let mut acc = Expression::Constant(F::ONE); - let one = Expression::Constant(F::ONE); - let rhs = as_bits::(rhs); - for (r, l) in rhs.iter().zip(lhs) { - let rr = Expression::Constant(F::from(*r as u64)); - acc = acc * (one.clone() - (l.clone() - rr.clone()) * (l - rr)); - } - acc -} - -/// Trace record struct for Lexicographic ordering circuit -/// We need every element to be of an array of type F, where each -#[derive(Debug, Clone)] -pub(crate) struct ConvertedTraceRecord { - pub(crate) address: [F; 32], // 256 bits - pub(crate) time_log: [F; 8], // 256 bits - pub(crate) instruction: F, // 0 or 1 - pub(crate) value: [F; 32], // 256 bit -} - -impl ConvertedTraceRecord { - /// Get the trace record fields in tuple - pub fn get_tuple(&self) -> ([F; 32], [F; 8], F, [F; 32]) { - (self.address, self.time_log, self.instruction, self.value) - } -} -// convert the original trace record into a converted trace record -// for serving as the witness of the ciruits -impl From> for ConvertedTraceRecord { - fn from(value: TraceRecord) -> Self { - Self { - address: value - .get_tuple() - .3 - .fixed_be_bytes() - .into_iter() - .map(|b| F::from(u64::from(b))) - .collect::>() - .try_into() - .expect("Cannot convert address to [F; 32]"), - time_log: value - .get_tuple() - .0 - .to_be_bytes() - .into_iter() - .map(|b| F::from(u64::from(b))) - .collect::>() - .try_into() - .expect("Cannot convert time_log to [F; 8]"), - instruction: match value.get_tuple().2 { - MemoryInstruction::Write => F::ONE, - MemoryInstruction::Read => F::ZERO, - }, - value: value - .get_tuple() - .4 - .fixed_be_bytes() - .into_iter() - .map(|b| F::from(u64::from(b))) - .collect::>() - .try_into() - .expect("Cannot convert value to [F; 32]"), - } - } -} - -/// The witness table consisting of the elements of the trace records -#[derive(Clone, Copy, Debug)] -pub(crate) struct TraceRecordWitnessTable { - pub(crate) address: [Column; 32], - pub(crate) time_log: [Column; 8], - pub(crate) instruction: Column, - pub(crate) value: [Column; 32], - pub(crate) _marker: PhantomData, -} -impl TraceRecordWitnessTable { - /// New Witness table - pub fn new(meta: &mut ConstraintSystem) -> Self { - TraceRecordWitnessTable { - address: [0; 32].map(|_| meta.advice_column()), - time_log: [0; 8].map(|_| meta.advice_column()), - instruction: meta.advice_column(), - value: [0; 32].map(|_| meta.advice_column()), - _marker: PhantomData, - } - } -} diff --git a/zkmemory/src/nova/memory_commitment.rs b/zkmemory/src/nova/memory_commitment.rs deleted file mode 100644 index 07b8d5a..0000000 --- a/zkmemory/src/nova/memory_commitment.rs +++ /dev/null @@ -1,618 +0,0 @@ - -/// Reference to be added later. -use nova_snark::{ - constants::{NUM_FE_WITHOUT_IO_FOR_CRHF, NUM_HASH_BITS}, - gadgets::{ - ecc::AllocatedPoint, - r1cs::{AllocatedR1CSInstance, AllocatedRelaxedR1CSInstance}, - utils::{ - alloc_num_equals, alloc_scalar_as_base, alloc_zero, conditionally_select_vec, le_bits_to_num, - }, - }, - r1cs::{R1CSInstance, RelaxedR1CSInstance}, - traits::{ - circuit::StepCircuit, commitment::CommitmentTrait, Engine, ROCircuitTrait, ROConstantsCircuit, - }, - Commitment, -}; - - - -/// The section of circuit. Will Move to a seperate file later. -pub struct NovaAugmentedCircuitInputs { - params: E::Scalar, - i: E::Base, - z0: Vec, - zi: Option>, - U: Option>, - u: Option>, - T: Option>, -} - -impl NovaAugmentedCircuitInputs { - /// Create new inputs/witness for the verification circuit - pub fn new( - params: E::Scalar, - i: E::Base, - z0: Vec, - zi: Option>, - U: Option>, - u: Option>, - T: Option>, - ) -> Self { - Self { - params, - i, - z0, - zi, - U, - u, - T, - } - } -} - -/// The augmented circuit F' in Nova that includes a step circuit F -/// and the circuit for the verifier in Nova's non-interactive folding scheme -pub struct NovaAugmentedCircuit<'a, E: Engine, SC: StepCircuit> { - params: &'a NovaAugmentedCircuitParams, - ro_consts: ROConstantsCircuit, - inputs: Option>, - step_circuit: &'a SC, // The function that is applied for each step -} - -impl<'a, E: Engine, SC: StepCircuit> NovaAugmentedCircuit<'a, E, SC> { - /// Create a new verification circuit for the input relaxed r1cs instances - pub const fn new( - params: &'a NovaAugmentedCircuitParams, - inputs: Option>, - step_circuit: &'a SC, - ro_consts: ROConstantsCircuit, - ) -> Self { - Self { - params, - inputs, - step_circuit, - ro_consts, - } - } - - /// Allocate all witnesses and return - fn alloc_witness::Base>>( - &self, - mut cs: CS, - arity: usize, - ) -> Result< - ( - AllocatedNum, - AllocatedNum, - Vec>, - Vec>, - AllocatedRelaxedR1CSInstance, - AllocatedR1CSInstance, - AllocatedPoint, - ), - SynthesisError, - > { - // Allocate the params - let params = alloc_scalar_as_base::( - cs.namespace(|| "params"), - self.inputs.as_ref().map(|inputs| inputs.params), - )?; - - // Allocate i - let i = AllocatedNum::alloc(cs.namespace(|| "i"), || Ok(self.inputs.get()?.i))?; - - // Allocate z0 - let z_0 = (0..arity) - .map(|i| { - AllocatedNum::alloc(cs.namespace(|| format!("z0_{i}")), || { - Ok(self.inputs.get()?.z0[i]) - }) - }) - .collect::>, _>>()?; - - // Allocate zi. If inputs.zi is not provided (base case) allocate default value 0 - let zero = vec![E::Base::ZERO; arity]; - let z_i = (0..arity) - .map(|i| { - AllocatedNum::alloc(cs.namespace(|| format!("zi_{i}")), || { - Ok(self.inputs.get()?.zi.as_ref().unwrap_or(&zero)[i]) - }) - }) - .collect::>, _>>()?; - - // Allocate the running instance - let U: AllocatedRelaxedR1CSInstance = AllocatedRelaxedR1CSInstance::alloc( - cs.namespace(|| "Allocate U"), - self.inputs.as_ref().and_then(|inputs| inputs.U.as_ref()), - self.params.limb_width, - self.params.n_limbs, - )?; - - // Allocate the instance to be folded in - let u = AllocatedR1CSInstance::alloc( - cs.namespace(|| "allocate instance u to fold"), - self.inputs.as_ref().and_then(|inputs| inputs.u.as_ref()), - )?; - - // Allocate T - let T = AllocatedPoint::alloc( - cs.namespace(|| "allocate T"), - self - .inputs - .as_ref() - .and_then(|inputs| inputs.T.map(|T| T.to_coordinates())), - )?; - T.check_on_curve(cs.namespace(|| "check T on curve"))?; - - Ok((params, i, z_0, z_i, U, u, T)) - } - - /// Synthesizes non base case and returns the new relaxed `R1CSInstance` - /// And a boolean indicating if all checks pass - fn synthesize_non_base_case::Base>>( - &self, - mut cs: CS, - params: &AllocatedNum, - i: &AllocatedNum, - z_0: &[AllocatedNum], - z_i: &[AllocatedNum], - U: &AllocatedRelaxedR1CSInstance, - u: &AllocatedR1CSInstance, - T: &AllocatedPoint, - arity: usize, - ) -> Result<(AllocatedRelaxedR1CSInstance, AllocatedBit), SynthesisError> { - // Check that u.x[0] = Hash(params, U, i, z0, zi) - let mut ro = E::ROCircuit::new( - self.ro_consts.clone(), - NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * arity, - ); - ro.absorb(params); - ro.absorb(i); - for e in z_0 { - ro.absorb(e); - } - for e in z_i { - ro.absorb(e); - } - U.absorb_in_ro(cs.namespace(|| "absorb U"), &mut ro)?; - - let hash_bits = ro.squeeze(cs.namespace(|| "Input hash"), NUM_HASH_BITS)?; - let hash = le_bits_to_num(cs.namespace(|| "bits to hash"), &hash_bits)?; - let check_pass = alloc_num_equals( - cs.namespace(|| "check consistency of u.X[0] with H(params, U, i, z0, zi)"), - &u.X0, - &hash, - )?; - - // Run NIFS Verifier - let U_fold = U.fold_with_r1cs( - cs.namespace(|| "compute fold of U and u"), - params, - u, - T, - self.ro_consts.clone(), - self.params.limb_width, - self.params.n_limbs, - )?; - - Ok((U_fold, check_pass)) - } -} - - -/// Todo: Check Nova and try to understand how this work later. -impl<'a, E: Engine, SC: StepCircuit> NovaAugmentedCircuit<'a, E, SC> { - /// synthesize circuit giving constraint system - pub fn synthesize::Base>>( - self, - cs: &mut CS, - ) -> Result>, SynthesisError> { - let arity = self.step_circuit.arity(); - - // Allocate all witnesses - let (params, i, z_0, z_i, U, u, T) = - self.alloc_witness(cs.namespace(|| "allocate the circuit witness"), arity)?; - - // Compute variable indicating if this is the base case - let zero = alloc_zero(cs.namespace(|| "zero")); - let is_base_case = alloc_num_equals(cs.namespace(|| "Check if base case"), &i.clone(), &zero)?; - - // Synthesize the circuit for the base case and get the new running instance - let Unew_base = self.synthesize_base_case(cs.namespace(|| "base case"), u.clone())?; - - // Synthesize the circuit for the non-base case and get the new running - // instance along with a boolean indicating if all checks have passed - let (Unew_non_base, check_non_base_pass) = self.synthesize_non_base_case( - cs.namespace(|| "synthesize non base case"), - ¶ms, - &i, - &z_0, - &z_i, - &U, - &u, - &T, - arity, - )?; - - // Either check_non_base_pass=true or we are in the base case - let should_be_false = AllocatedBit::nor( - cs.namespace(|| "check_non_base_pass nor base_case"), - &check_non_base_pass, - &is_base_case, - )?; - cs.enforce( - || "check_non_base_pass nor base_case = false", - |lc| lc + should_be_false.get_variable(), - |lc| lc + CS::one(), - |lc| lc, - ); - - // Compute the U_new - let Unew = Unew_base.conditionally_select( - cs.namespace(|| "compute U_new"), - &Unew_non_base, - &Boolean::from(is_base_case.clone()), - )?; - - // Compute i + 1 - let i_new = AllocatedNum::alloc(cs.namespace(|| "i + 1"), || { - Ok(*i.get_value().get()? + E::Base::ONE) - })?; - cs.enforce( - || "check i + 1", - |lc| lc, - |lc| lc, - |lc| lc + i_new.get_variable() - CS::one() - i.get_variable(), - ); - - // Compute z_{i+1} - let z_input = conditionally_select_vec( - cs.namespace(|| "select input to F"), - &z_0, - &z_i, - &Boolean::from(is_base_case), - )?; - - let z_next = self - .step_circuit - .synthesize(&mut cs.namespace(|| "F"), &z_input)?; - - if z_next.len() != arity { - return Err(SynthesisError::IncompatibleLengthVector( - "z_next".to_string(), - )); - } - - // Compute the new hash H(params, Unew, i+1, z0, z_{i+1}) - let mut ro = E::ROCircuit::new(self.ro_consts, NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * arity); - ro.absorb(¶ms); - ro.absorb(&i_new); - for e in &z_0 { - ro.absorb(e); - } - for e in &z_next { - ro.absorb(e); - } - Unew.absorb_in_ro(cs.namespace(|| "absorb U_new"), &mut ro)?; - let hash_bits = ro.squeeze(cs.namespace(|| "output hash bits"), NUM_HASH_BITS)?; - let hash = le_bits_to_num(cs.namespace(|| "convert hash to num"), &hash_bits)?; - - // Outputs the computed hash and u.X[1] that corresponds to the hash of the other circuit - u.X1 - .inputize(cs.namespace(|| "Output unmodified hash of the other circuit"))?; - hash.inputize(cs.namespace(|| "output new hash of this circuit"))?; - - Ok(z_next) - } -} - -// The section of R1CS Matrix. Will Move to a seperate file later. -pub struct SparseMatrix { - /// all non-zero values in the matrix - pub data: Vec, - /// column indices - pub indices: Vec, - /// row information - pub indptr: Vec, - /// number of columns - pub cols: usize, -} - -impl SparseMatrix { - /// 0x0 empty matrix - pub fn empty() -> Self { - SparseMatrix { - data: vec![], - indices: vec![], - indptr: vec![0], - cols: 0, - } - } - - /// Construct from the COO representation; Vec. - /// We assume that the rows are sorted during construction. - pub fn new(matrix: &[(usize, usize, F)], rows: usize, cols: usize) -> Self { - let mut new_matrix = vec![vec![]; rows]; - for (row, col, val) in matrix { - new_matrix[*row].push((*col, *val)); - } - - for row in new_matrix.iter() { - assert!(row.windows(2).all(|w| w[0].0 < w[1].0)); - } - - let mut indptr = vec![0; rows + 1]; - for (i, col) in new_matrix.iter().enumerate() { - indptr[i + 1] = indptr[i] + col.len(); - } - - let mut indices = vec![]; - let mut data = vec![]; - for col in new_matrix { - let (idx, val): (Vec<_>, Vec<_>) = col.into_iter().unzip(); - indices.extend(idx); - data.extend(val); - } - - SparseMatrix { - data, - indices, - indptr, - cols, - } - } - - /// Retrieves the data for row slice [i..j] from `ptrs`. - /// We assume that `ptrs` is indexed from `indptrs` and do not check if the - /// returned slice is actually a valid row. - pub fn get_row_unchecked(&self, ptrs: &[usize; 2]) -> impl Iterator { - self.data[ptrs[0]..ptrs[1]] - .iter() - .zip(&self.indices[ptrs[0]..ptrs[1]]) - } - - /// Multiply by a dense vector; uses rayon/gpu. - pub fn multiply_vec(&self, vector: &[F]) -> Vec { - assert_eq!(self.cols, vector.len(), "invalid shape"); - - self.multiply_vec_unchecked(vector) - } - - /// Multiply by a dense vector; uses rayon/gpu. - /// This does not check that the shape of the matrix/vector are compatible. - pub fn multiply_vec_unchecked(&self, vector: &[F]) -> Vec { - self - .indptr - .par_windows(2) - .map(|ptrs| { - self - .get_row_unchecked(ptrs.try_into().unwrap()) - .map(|(val, col_idx)| *val * vector[*col_idx]) - .sum() - }) - .collect() - } -} - -/// Iterator for sparse matrix -pub struct Iter<'a, F: PrimeField> { - matrix: &'a SparseMatrix, - row: usize, - i: usize, - nnz: usize, -} - -impl<'a, F: PrimeField> Iterator for Iter<'a, F> { - type Item = (usize, usize, F); - - fn next(&mut self) -> Option { - // are we at the end? - if self.i == self.nnz { - return None; - } - - // compute current item - let curr_item = ( - self.row, - self.matrix.indices[self.i], - self.matrix.data[self.i], - ); - - // advance the iterator - self.i += 1; - // edge case at the end - if self.i == self.nnz { - return Some(curr_item); - } - // if `i` has moved to next row - while self.i >= self.matrix.indptr[self.row + 1] { - self.row += 1; - } - - Some(curr_item) - } -} - - -// The section of NIFS. Will Move to the seperate file later. - -/// NIFS Prove and Verify -/// TODO: Check the RO Trait Nova and implement it -pub struct NIFS { - pub(crate) comm_T: Commitment, -} - -type ROConstants = - <::RO as ROTrait<::Base, ::Scalar>>::Constants; - -impl NIFS { - - - pub fn prove( - ck: &CommitmentKey, - ro_consts: &ROConstants, - pp_digest: &E::Scalar, - S: &R1CSShape, - U1: &RelaxedR1CSInstance, - W1: &RelaxedR1CSWitness, - U2: &R1CSInstance, - W2: &R1CSWitness, - ) -> Result<(NIFS, (RelaxedR1CSInstance, RelaxedR1CSWitness)), NovaError> { - // initialize a new RO - let mut ro = E::RO::new(ro_consts.clone(), NUM_FE_FOR_RO); - - // append the digest of pp to the transcript - ro.absorb(scalar_as_base::(*pp_digest)); - - // append U2 to transcript, U1 does not need to absorbed since U2.X[0] = Hash(params, U1, i, z0, zi) - U2.absorb_in_ro(&mut ro); - - // compute a commitment to the cross-term - let (T, comm_T) = S.commit_T(ck, U1, W1, U2, W2)?; - - // append `comm_T` to the transcript and obtain a challenge - comm_T.absorb_in_ro(&mut ro); - - // compute a challenge from the RO - let r = ro.squeeze(NUM_CHALLENGE_BITS); - - // fold the instance using `r` and `comm_T` - let U = U1.fold(U2, &comm_T, &r); - - // fold the witness using `r` and `T` - let W = W1.fold(W2, &T, &r)?; - - // return the folded instance and witness - Ok((Self { comm_T }, (U, W))) - } - - /// Takes as input a relaxed R1CS instance `U1` and R1CS instance `U2` - /// with the same shape and defined with respect to the same parameters, - /// and outputs a folded instance `U` with the same shape, - /// with the guarantee that the folded instance `U` - /// if and only if `U1` and `U2` are satisfiable. - pub fn verify( - &self, - ro_consts: &ROConstants, - pp_digest: &E::Scalar, - U1: &RelaxedR1CSInstance, - U2: &R1CSInstance, - ) -> Result, NovaError> { - // initialize a new RO - let mut ro = E::RO::new(ro_consts.clone(), NUM_FE_FOR_RO); - - // append the digest of pp to the transcript - ro.absorb(scalar_as_base::(*pp_digest)); - - // append U2 to transcript, U1 does not need to absorbed since U2.X[0] = Hash(params, U1, i, z0, zi) - U2.absorb_in_ro(&mut ro); - - // append `comm_T` to the transcript and obtain a challenge - self.comm_T.absorb_in_ro(&mut ro); - - // compute a challenge from the RO - let r = ro.squeeze(NUM_CHALLENGE_BITS); - - // fold the instance using `r` and `comm_T` - let U = U1.fold(U2, &self.comm_T, &r); - - // return the folded instance - Ok(U) - } -} - - - -#[cfg(test)] -mod tests { - use super::*; - use crate::{ - provider::PallasEngine, - traits::{Engine, Group}, - }; - use ff::PrimeField; - use proptest::{ - prelude::*, - strategy::{BoxedStrategy, Just, Strategy}, - }; - - type G = ::GE; - type Fr = ::Scalar; - - /// Wrapper struct around a field element that implements additional traits - #[derive(Clone, Debug, PartialEq, Eq)] - pub struct FWrap(pub F); - - impl Copy for FWrap {} - - #[cfg(not(target_arch = "wasm32"))] - /// Trait implementation for generating `FWrap` instances with proptest - impl Arbitrary for FWrap { - type Parameters = (); - type Strategy = BoxedStrategy; - - fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { - use rand::rngs::StdRng; - use rand_core::SeedableRng; - - let strategy = any::<[u8; 32]>() - .prop_map(|seed| FWrap(F::random(StdRng::from_seed(seed)))) - .no_shrink(); - strategy.boxed() - } - } - - #[test] - fn test_matrix_creation() { - let matrix_data = vec![ - (0, 1, Fr::from(2)), - (1, 2, Fr::from(3)), - (2, 0, Fr::from(4)), - ]; - let sparse_matrix = SparseMatrix::::new(&matrix_data, 3, 3); - - assert_eq!( - sparse_matrix.data, - vec![Fr::from(2), Fr::from(3), Fr::from(4)] - ); - assert_eq!(sparse_matrix.indices, vec![1, 2, 0]); - assert_eq!(sparse_matrix.indptr, vec![0, 1, 2, 3]); - } - - #[test] - fn test_matrix_vector_multiplication() { - let matrix_data = vec![ - (0, 1, Fr::from(2)), - (0, 2, Fr::from(7)), - (1, 2, Fr::from(3)), - (2, 0, Fr::from(4)), - ]; - let sparse_matrix = SparseMatrix::::new(&matrix_data, 3, 3); - let vector = vec![Fr::from(1), Fr::from(2), Fr::from(3)]; - - let result = sparse_matrix.multiply_vec(&vector); - - assert_eq!(result, vec![Fr::from(25), Fr::from(9), Fr::from(4)]); - } - - fn coo_strategy() -> BoxedStrategy)>> { - let coo_strategy = any::>().prop_flat_map(|f| (0usize..100, 0usize..100, Just(f))); - proptest::collection::vec(coo_strategy, 10).boxed() - } - - proptest! { - #[test] - fn test_matrix_iter(mut coo_matrix in coo_strategy()) { - // process the randomly generated coo matrix - coo_matrix.sort_by_key(|(row, col, _val)| (*row, *col)); - coo_matrix.dedup_by_key(|(row, col, _val)| (*row, *col)); - let coo_matrix = coo_matrix.into_iter().map(|(row, col, val)| { (row, col, val.0) }).collect::>(); - - let matrix = SparseMatrix::new(&coo_matrix, 100, 100); - - prop_assert_eq!(coo_matrix, matrix.iter().collect::>()); - } - } -} \ No newline at end of file diff --git a/zkmemory/src/nova/memory_consistency_circuit.rs b/zkmemory/src/nova/memory_consistency_circuit.rs new file mode 100644 index 0000000..4a9019a --- /dev/null +++ b/zkmemory/src/nova/memory_consistency_circuit.rs @@ -0,0 +1,189 @@ +extern crate alloc; +use alloc::format; +use alloc::vec::{Vec}; +use alloc::vec; +/// Reference to be added later. +use nova_snark::{traits::{Group, circuit::StepCircuit} +}; +use bellpepper_core::{ConstraintSystem, num::AllocatedNum, SynthesisError}; +use ff::Field; + + +#[derive(Copy, Clone)] +/// the trace record struct +pub struct TraceRecord { + address: G::Scalar, + instruction: G::Scalar, + value: G::Scalar, +} + +#[derive(Copy, Clone)] +/// memory consistency circuit +pub struct NovaMemoryConsistencyCircuit { + memory_len: usize, + trace_record: TraceRecord, +} + +impl StepCircuit for NovaMemoryConsistencyCircuit { + fn arity(&self) -> usize { + self.memory_len + 1 + } + /// commitment at the top + /// the next is the changed index + fn synthesize>( + &self, + cs: &mut CS, + z_in: &[AllocatedNum], + ) -> Result>, SynthesisError> { + assert!(z_in.len() == self.memory_len + 1); + // z_i is the i-th state of memory: The first memory_len elements are the memory cells. + // the final element of z_i is the Merkle root of the cells. + // trace_record is the execution trace from z_i to z_{i+1} + // meaning that if instruction=0 then the value of trace_record must be equal to + // z_i[address]. Also we need the merkle root in z_i + + let mut memory: Vec> = vec![]; + for i in 0..self.memory_len { + memory.push(z_in[i].clone()) + } + + // The value variable + let value = AllocatedNum::alloc(cs.namespace(|| format!("value")), || { + Ok(self.trace_record.value) + }) + .expect("unable to get value") + .get_variable(); + + // The instruction variable + let instruction = AllocatedNum::alloc(cs.namespace(|| format!("instruction")), || { + Ok(self.trace_record.instruction) + }) + .expect("unable to get instruction") + .get_variable(); + + let instruction_minus_one = + AllocatedNum::alloc(cs.namespace(|| format!("instruction minus one")), || { + Ok(self.trace_record.instruction - G::Scalar::ONE) + }) + .expect("unable to get instruction_minus_one") + .get_variable(); + + // The ZERO variable + let zero = AllocatedNum::alloc(cs.namespace(|| format!("zero")), || Ok(G::Scalar::ZERO)) + .expect("unable to get zero") + .get_variable(); + + // The ONE variable + let one = AllocatedNum::alloc(cs.namespace(|| format!("zero")), || Ok(G::Scalar::ONE)) + .expect("unable to get one") + .get_variable(); + + let mut tmp = zero; + for i in 0..self.memory_len { + if G::Scalar::from(i as u64) == self.trace_record.address { + tmp = memory[i].get_variable(); + } + } + + let tmp2 = AllocatedNum::alloc(cs.namespace(|| format!("value")), || { + Ok(self.trace_record.value) + }) + .expect("unable to get tmp2"); + + // create the output, which includes the memory and the Merkle + // tree commitment of the memory + let mut z_out = vec![]; + for i in 0..self.memory_len { + if G::Scalar::from(i as u64) != self.trace_record.address { + z_out.push(memory[i].clone()); + } else { + z_out.push(tmp2.clone()); + } + } + + // create the Merkle commitment of the tree + let commitment = AllocatedNum::alloc(cs.namespace(|| format!("merkle root")), || { + Ok(self.merkle_tree_commit(memory.clone())) + }) + .expect("unable to get commitment") + .get_variable(); + + // commitment to the new updated memory + let new_commitment = AllocatedNum::alloc(cs.namespace(|| format!("merkle root")), || { + Ok(self.merkle_tree_commit(z_out.clone())) + }) + .expect("unable to get new commitment"); + + z_out.push(new_commitment); + assert!(z_out.len() == self.memory_len + 1); + + // commitment to the memory must be valid + cs.enforce( + || format!("commitment to the memory must be valid"), + |lc| lc + commitment, + |lc| lc + one, + |lc| lc + z_in[self.memory_len].get_variable(), + ); + + // if instruction = 0 then memory[address]=value + cs.enforce( + || format!("memory[address] = value"), + |lc| lc + instruction_minus_one, + |lc| lc + tmp - value, + |lc| lc + zero, + ); + + // instruction must be read or write + cs.enforce( + || format!("operation is read or write"), + |lc| lc + instruction, + |lc| lc + instruction_minus_one, + |lc| lc + zero, + ); + + Ok(z_out) + } +} + +impl NovaMemoryConsistencyCircuit { + /// Create a new trace_record + pub fn new(memory_len: usize, address: u64, instruction: u64, value: u64) -> Self { + Self { + memory_len, + trace_record: TraceRecord:: { + address: G::Scalar::from(address), + instruction: G::Scalar::from(instruction), + value: G::Scalar::from(value), + }, + } + } + + /// compute the merkle root of the memory + pub fn merkle_tree_commit + (self, memory: Vec>) -> G::Scalar { + let mut tmp: Vec = memory + .into_iter() + .map(|x| x.get_value().expect("unable to get memory values")) + .collect(); + let mut size = tmp.len(); + while size > 1 { + let mut tmp2 = size; + while tmp2 > 1 { + let left = tmp.pop().expect("unable to get left"); + let right = tmp.pop().expect("unable to get right"); + // TODO: replace "out" with a hash function + let out = left + right + G::Scalar::ONE; + // End TODO + tmp.push(out); + tmp2 = tmp2 - 2; + } + size = tmp.len(); + } + tmp[0] + } +} + + + + + diff --git a/zkmemory/src/nova/mod.rs b/zkmemory/src/nova/mod.rs index e914f75..512a007 100644 --- a/zkmemory/src/nova/mod.rs +++ b/zkmemory/src/nova/mod.rs @@ -1,4 +1,5 @@ -/// this module consists of helper functions -pub mod gadgets; -/// this module consists of the instance-witness pairs in each step -pub mod memory_commitment; \ No newline at end of file + +/// the memory consitency circuit using Nova proof system +pub mod memory_consistency_circuit; +/// the testcases of memory consistency circuit +pub mod testcases; \ No newline at end of file diff --git a/zkmemory/src/nova/testcases.rs b/zkmemory/src/nova/testcases.rs new file mode 100644 index 0000000..871cbc3 --- /dev/null +++ b/zkmemory/src/nova/testcases.rs @@ -0,0 +1,135 @@ + +#[cfg(test)] +mod test { + use ff::{Field}; + use nova_snark::{traits::{Engine, circuit::TrivialCircuit, snark::RelaxedR1CSSNARKTrait}, provider::{GrumpkinEngine, Bn256EngineKZG}, RecursiveSNARK, PublicParams}; + + use crate::nova::memory_consistency_circuit::NovaMemoryConsistencyCircuit; +type E1 = Bn256EngineKZG; +type E2 = GrumpkinEngine; +type EE1 = nova_snark::provider::hyperkzg::EvaluationEngine; +type EE2 = nova_snark::provider::ipa_pc::EvaluationEngine; +type S1 = nova_snark::spartan::snark::RelaxedR1CSSNARK; // non-preprocessing SNARK +type S2 = nova_snark::spartan::snark::RelaxedR1CSSNARK; // non-preprocessing SNARK + #[test] + // test correct memory consistency in one step + fn test_memory_consistency_in_one_step() { + let address = 0 as u64; + let instruction = 1 as u64; + let value = 1292001 as u64; + // let num_steps = 10; + let circuit_primary = + NovaMemoryConsistencyCircuit::<::GE>::new(4, address, instruction, value); + let circuit_secondary = TrivialCircuit::<::Scalar>::default(); + + type C1 = NovaMemoryConsistencyCircuit<::GE>; + type C2 = TrivialCircuit<::Scalar>; + + let pp = PublicParams::< + E1, + E2, + NovaMemoryConsistencyCircuit<::GE>, + TrivialCircuit<::Scalar>, + >::setup( + &circuit_primary, + &circuit_secondary, + &*S1::ck_floor(), + &*S2::ck_floor(), + ) + .expect("unable to setup"); + + let mut recursive_snark = RecursiveSNARK::::new( + &pp, + &circuit_primary, + &circuit_secondary, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::from(3 as u64), + ], + &[::Scalar::zero()], + ) + .expect("unable to prove"); + + let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); + //assert!(res.is_ok()); + // println!("{:?}", res); + + let res = recursive_snark.verify( + &pp, + 1, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::from(3 as u64), + ], + &[::Scalar::ZERO], + ); + assert_eq!(res.is_ok(),true); + } + + #[test] + // test invalid instruction in trace record + fn test_invalid_instruction_in_one_step() { + let address = 0 as u64; + let instruction = 2 as u64; + let value = 1292001 as u64; + // let num_steps = 10; + let circuit_primary = + NovaMemoryConsistencyCircuit::<::GE>::new(4, address, instruction, value); + let circuit_secondary = TrivialCircuit::<::Scalar>::default(); + + type C1 = NovaMemoryConsistencyCircuit<::GE>; + type C2 = TrivialCircuit<::Scalar>; + + let pp = PublicParams::< + E1, + E2, + NovaMemoryConsistencyCircuit<::GE>, + TrivialCircuit<::Scalar>, + >::setup( + &circuit_primary, + &circuit_secondary, + &*S1::ck_floor(), + &*S2::ck_floor(), + ) + .expect("unable to setup"); + + let mut recursive_snark = RecursiveSNARK::::new( + &pp, + &circuit_primary, + &circuit_secondary, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::from(3 as u64), + ], + &[::Scalar::zero()], + ) + .expect("unable to prove"); + + let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); + //assert!(res.is_ok()); + // println!("{:?}", res); + + let res = recursive_snark.verify( + &pp, + 1, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::from(3 as u64), + ], + &[::Scalar::ZERO], + ); + assert_ne!(res.is_ok(),true); + } +} diff --git a/zkmemory/src/poseidon/poseidon_hash.rs b/zkmemory/src/poseidon/poseidon_hash.rs index 4661df5..4ef5fc2 100644 --- a/zkmemory/src/poseidon/poseidon_hash.rs +++ b/zkmemory/src/poseidon/poseidon_hash.rs @@ -42,6 +42,7 @@ pub trait Domain { fn padding(input_len: usize) -> Self::Padding; } +#[derive(Clone)] /// The number of messages to be hashed pub struct ConstantLength; @@ -77,16 +78,17 @@ impl Absorbing { } /// The absorbing state of the `Sponge`. -#[derive(Debug)] +#[derive(Clone,Debug)] pub struct Absorbing(pub(crate) [Option; R]); /// The squeezing state of the `Sponge`. -#[derive(Debug)] +#[derive(Clone,Debug)] pub struct Squeezing(pub(crate) [Option; R]); /// The type used to hold permutation state. pub(crate) type State = [F; T]; +#[derive(Clone)] /// A Poseidon sponge. pub(crate) struct Sponge< F: Field + PrimeField, @@ -261,6 +263,7 @@ impl, const T: usize, const R: usize> } } +#[derive(Clone)] /// A Poseidon hash function, built around a sponge. pub struct Hash< F: Field + PrimeField, From fd94ee0312019601bc960118633ddd2990a8a79b Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Sun, 11 Aug 2024 21:24:08 +0700 Subject: [PATCH 11/24] Add more testcases and generalize the memory consistency circuit This PR add more testcases and generalize the circuit so that it can handle multiple steps at a time. --- .../src/nova/memory_consistency_circuit.rs | 329 ++++++------ zkmemory/src/nova/mod.rs | 3 +- zkmemory/src/nova/testcases.rs | 473 +++++++++++++----- zkmemory/src/poseidon/poseidon_hash.rs | 4 +- 4 files changed, 509 insertions(+), 300 deletions(-) diff --git a/zkmemory/src/nova/memory_consistency_circuit.rs b/zkmemory/src/nova/memory_consistency_circuit.rs index 4a9019a..6f10c60 100644 --- a/zkmemory/src/nova/memory_consistency_circuit.rs +++ b/zkmemory/src/nova/memory_consistency_circuit.rs @@ -1,189 +1,186 @@ extern crate alloc; use alloc::format; -use alloc::vec::{Vec}; use alloc::vec; -/// Reference to be added later. -use nova_snark::{traits::{Group, circuit::StepCircuit} -}; -use bellpepper_core::{ConstraintSystem, num::AllocatedNum, SynthesisError}; +use alloc::vec::Vec; +use bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError}; use ff::Field; - +/// Reference to be added later. +use nova_snark::traits::{circuit::StepCircuit, Group}; #[derive(Copy, Clone)] /// the trace record struct pub struct TraceRecord { - address: G::Scalar, - instruction: G::Scalar, - value: G::Scalar, + address: G::Scalar, + instruction: G::Scalar, + value: G::Scalar, } -#[derive(Copy, Clone)] -/// memory consistency circuit +#[derive(Clone)] +/// memory consistency circuit in one step pub struct NovaMemoryConsistencyCircuit { - memory_len: usize, - trace_record: TraceRecord, + memory_len: usize, + num_iters_per_step: usize, + trace_record: Vec>, } impl StepCircuit for NovaMemoryConsistencyCircuit { - fn arity(&self) -> usize { - self.memory_len + 1 - } - /// commitment at the top - /// the next is the changed index - fn synthesize>( - &self, - cs: &mut CS, - z_in: &[AllocatedNum], - ) -> Result>, SynthesisError> { - assert!(z_in.len() == self.memory_len + 1); - // z_i is the i-th state of memory: The first memory_len elements are the memory cells. - // the final element of z_i is the Merkle root of the cells. - // trace_record is the execution trace from z_i to z_{i+1} - // meaning that if instruction=0 then the value of trace_record must be equal to - // z_i[address]. Also we need the merkle root in z_i - - let mut memory: Vec> = vec![]; - for i in 0..self.memory_len { - memory.push(z_in[i].clone()) + fn arity(&self) -> usize { + self.memory_len + 1 } - // The value variable - let value = AllocatedNum::alloc(cs.namespace(|| format!("value")), || { - Ok(self.trace_record.value) - }) - .expect("unable to get value") - .get_variable(); - - // The instruction variable - let instruction = AllocatedNum::alloc(cs.namespace(|| format!("instruction")), || { - Ok(self.trace_record.instruction) - }) - .expect("unable to get instruction") - .get_variable(); - - let instruction_minus_one = - AllocatedNum::alloc(cs.namespace(|| format!("instruction minus one")), || { - Ok(self.trace_record.instruction - G::Scalar::ONE) - }) - .expect("unable to get instruction_minus_one") - .get_variable(); - - // The ZERO variable - let zero = AllocatedNum::alloc(cs.namespace(|| format!("zero")), || Ok(G::Scalar::ZERO)) - .expect("unable to get zero") - .get_variable(); - - // The ONE variable - let one = AllocatedNum::alloc(cs.namespace(|| format!("zero")), || Ok(G::Scalar::ONE)) - .expect("unable to get one") - .get_variable(); - - let mut tmp = zero; - for i in 0..self.memory_len { - if G::Scalar::from(i as u64) == self.trace_record.address { - tmp = memory[i].get_variable(); - } + fn synthesize>( + &self, + cs: &mut CS, + z_in: &[AllocatedNum], + ) -> Result>, SynthesisError> { + assert!(z_in.len() == self.memory_len + 1); + // z_i is the i-th state of memory: The first memory_len elements are the memory cells. + // the final element of z_i is the Merkle root of the cells. + // trace_record is the execution trace from z_i to z_{i+1} + // meaning that if instruction=0 then the value of trace_record must be equal to + // z_i[address]. Also we need the merkle root in z_i + + // The ZERO variable + let zero = AllocatedNum::alloc(cs.namespace(|| format!("zero")), || Ok(G::Scalar::ZERO)) + .expect("unable to get ZERO value"); + + // The ONE variable + let one = AllocatedNum::alloc(cs.namespace(|| format!("one")), || Ok(G::Scalar::ONE)) + .expect("unable to get ONE value"); + + let mut z_out = z_in.to_vec(); + + // Get the current state of the memory + for j in 0..self.num_iters_per_step { + let mut memory: Vec> = vec![]; + for i in 0..self.memory_len { + memory.push(z_out[i].clone()) + } + + // The value variable + let value = AllocatedNum::alloc(cs.namespace(|| format!("value")), || { + Ok(self.trace_record[j].value) + }) + .expect("unable to get value"); + + // The instruction variable + let instruction = AllocatedNum::alloc(cs.namespace(|| format!("instruction")), || { + Ok(self.trace_record[j].instruction) + }) + .expect("unable to get instruction"); + + let instruction_minus_one = + AllocatedNum::alloc(cs.namespace(|| format!("instruction minus one")), || { + Ok(self.trace_record[j].instruction - G::Scalar::ONE) + }) + .expect("unable to get instruction_minus_one"); + + // Get memory[address] + let mut memory_address = zero.clone(); + for i in 0..self.memory_len { + if G::Scalar::from(i as u64) == self.trace_record[j].address { + memory_address = memory[i].clone(); + } + } + // create the Merkle commitment of the tree + let commitment = AllocatedNum::alloc(cs.namespace(|| format!("merkle root")), || { + Ok(self.clone().merkle_tree_commit(memory.clone())) + }) + .expect("unable to get commitment"); + + // commitment to the memory must be valid + cs.enforce( + || format!("commitment to the memory must be valid"), + |lc| lc + commitment.get_variable(), + |lc| lc + one.get_variable(), + |lc| lc + z_out[self.memory_len].get_variable(), + ); + + // if instruction = 0 then memory[address]=value + cs.enforce( + || format!("if instruction=0 then memory[address] = value"), + |lc| lc + instruction_minus_one.get_variable(), + |lc| lc + memory_address.get_variable() - value.get_variable(), + |lc| lc + zero.get_variable(), + ); + + // instruction must be read or write + cs.enforce( + || format!("operation is read or write"), + |lc| lc + instruction.get_variable(), + |lc| lc + instruction_minus_one.get_variable(), + |lc| lc + zero.get_variable(), + ); + + // create the output, which includes the memory and the Merkle + // tree commitment of the memory + z_out.clear(); + for i in 0..self.memory_len { + if G::Scalar::from(i as u64) != self.trace_record[j].address { + z_out.push(memory[i].clone()); + } else { + z_out.push(value.clone()); + } + } + // commitment to the new updated memory + let new_commitment = + AllocatedNum::alloc(cs.namespace(|| format!("merkle root")), || { + Ok(self.clone().merkle_tree_commit(z_out.clone())) + }) + .expect("unable to get new commitment"); + + z_out.push(new_commitment); + assert!(z_out.len() == self.memory_len + 1); + } + + Ok(z_out) } - - let tmp2 = AllocatedNum::alloc(cs.namespace(|| format!("value")), || { - Ok(self.trace_record.value) - }) - .expect("unable to get tmp2"); - - // create the output, which includes the memory and the Merkle - // tree commitment of the memory - let mut z_out = vec![]; - for i in 0..self.memory_len { - if G::Scalar::from(i as u64) != self.trace_record.address { - z_out.push(memory[i].clone()); - } else { - z_out.push(tmp2.clone()); - } - } - - // create the Merkle commitment of the tree - let commitment = AllocatedNum::alloc(cs.namespace(|| format!("merkle root")), || { - Ok(self.merkle_tree_commit(memory.clone())) - }) - .expect("unable to get commitment") - .get_variable(); - - // commitment to the new updated memory - let new_commitment = AllocatedNum::alloc(cs.namespace(|| format!("merkle root")), || { - Ok(self.merkle_tree_commit(z_out.clone())) - }) - .expect("unable to get new commitment"); - - z_out.push(new_commitment); - assert!(z_out.len() == self.memory_len + 1); - - // commitment to the memory must be valid - cs.enforce( - || format!("commitment to the memory must be valid"), - |lc| lc + commitment, - |lc| lc + one, - |lc| lc + z_in[self.memory_len].get_variable(), - ); - - // if instruction = 0 then memory[address]=value - cs.enforce( - || format!("memory[address] = value"), - |lc| lc + instruction_minus_one, - |lc| lc + tmp - value, - |lc| lc + zero, - ); - - // instruction must be read or write - cs.enforce( - || format!("operation is read or write"), - |lc| lc + instruction, - |lc| lc + instruction_minus_one, - |lc| lc + zero, - ); - - Ok(z_out) - } } impl NovaMemoryConsistencyCircuit { - /// Create a new trace_record - pub fn new(memory_len: usize, address: u64, instruction: u64, value: u64) -> Self { - Self { - memory_len, - trace_record: TraceRecord:: { - address: G::Scalar::from(address), - instruction: G::Scalar::from(instruction), - value: G::Scalar::from(value), - }, + /// Create a new trace_record + pub fn new( + memory_len: usize, + num_iters_per_step: usize, + address: Vec, + instruction: Vec, + value: Vec, + ) -> Self { + let mut trace_record = vec![]; + for i in 0..num_iters_per_step { + trace_record.push(TraceRecord:: { + address: G::Scalar::from(address[i]), + instruction: G::Scalar::from(instruction[i]), + value: G::Scalar::from(value[i]), + }) + } + Self { + memory_len, + num_iters_per_step, + trace_record, + } } - } - - /// compute the merkle root of the memory - pub fn merkle_tree_commit - (self, memory: Vec>) -> G::Scalar { - let mut tmp: Vec = memory - .into_iter() - .map(|x| x.get_value().expect("unable to get memory values")) - .collect(); - let mut size = tmp.len(); - while size > 1 { - let mut tmp2 = size; - while tmp2 > 1 { - let left = tmp.pop().expect("unable to get left"); - let right = tmp.pop().expect("unable to get right"); - // TODO: replace "out" with a hash function - let out = left + right + G::Scalar::ONE; - // End TODO - tmp.push(out); - tmp2 = tmp2 - 2; - } - size = tmp.len(); + + /// compute the merkle root of the memory + pub fn merkle_tree_commit(self, memory: Vec>) -> G::Scalar { + let mut tmp: Vec = memory + .into_iter() + .map(|x| x.get_value().expect("unable to get memory values")) + .collect(); + let mut size = tmp.len(); + while size > 1 { + let mut tmp2 = size; + while tmp2 > 1 { + let left = tmp.pop().expect("unable to get left"); + let right = tmp.pop().expect("unable to get right"); + // TODO: replace "out" with a hash function + let out = left + right + G::Scalar::ONE; + // End TODO + tmp.push(out); + tmp2 = tmp2 - 2; + } + size = tmp.len(); + } + tmp[0] } - tmp[0] - } } - - - - - diff --git a/zkmemory/src/nova/mod.rs b/zkmemory/src/nova/mod.rs index 512a007..e291d68 100644 --- a/zkmemory/src/nova/mod.rs +++ b/zkmemory/src/nova/mod.rs @@ -1,5 +1,4 @@ - /// the memory consitency circuit using Nova proof system pub mod memory_consistency_circuit; /// the testcases of memory consistency circuit -pub mod testcases; \ No newline at end of file +pub mod testcases; diff --git a/zkmemory/src/nova/testcases.rs b/zkmemory/src/nova/testcases.rs index 871cbc3..38c47aa 100644 --- a/zkmemory/src/nova/testcases.rs +++ b/zkmemory/src/nova/testcases.rs @@ -1,135 +1,348 @@ - #[cfg(test)] mod test { - use ff::{Field}; - use nova_snark::{traits::{Engine, circuit::TrivialCircuit, snark::RelaxedR1CSSNARKTrait}, provider::{GrumpkinEngine, Bn256EngineKZG}, RecursiveSNARK, PublicParams}; + + use ff::Field; + use nova_snark::{ + provider::{Bn256EngineKZG, GrumpkinEngine}, + traits::{circuit::TrivialCircuit, snark::RelaxedR1CSSNARKTrait, Engine}, + PublicParams, RecursiveSNARK, + }; use crate::nova::memory_consistency_circuit::NovaMemoryConsistencyCircuit; -type E1 = Bn256EngineKZG; -type E2 = GrumpkinEngine; -type EE1 = nova_snark::provider::hyperkzg::EvaluationEngine; -type EE2 = nova_snark::provider::ipa_pc::EvaluationEngine; -type S1 = nova_snark::spartan::snark::RelaxedR1CSSNARK; // non-preprocessing SNARK -type S2 = nova_snark::spartan::snark::RelaxedR1CSSNARK; // non-preprocessing SNARK - #[test] - // test correct memory consistency in one step - fn test_memory_consistency_in_one_step() { - let address = 0 as u64; - let instruction = 1 as u64; - let value = 1292001 as u64; - // let num_steps = 10; - let circuit_primary = - NovaMemoryConsistencyCircuit::<::GE>::new(4, address, instruction, value); - let circuit_secondary = TrivialCircuit::<::Scalar>::default(); - - type C1 = NovaMemoryConsistencyCircuit<::GE>; - type C2 = TrivialCircuit<::Scalar>; - - let pp = PublicParams::< - E1, - E2, - NovaMemoryConsistencyCircuit<::GE>, - TrivialCircuit<::Scalar>, - >::setup( - &circuit_primary, - &circuit_secondary, - &*S1::ck_floor(), - &*S2::ck_floor(), - ) - .expect("unable to setup"); - - let mut recursive_snark = RecursiveSNARK::::new( - &pp, - &circuit_primary, - &circuit_secondary, - &[ - ::Scalar::zero(), - ::Scalar::zero(), - ::Scalar::zero(), - ::Scalar::zero(), - ::Scalar::from(3 as u64), - ], - &[::Scalar::zero()], - ) - .expect("unable to prove"); - - let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); - //assert!(res.is_ok()); - // println!("{:?}", res); - - let res = recursive_snark.verify( - &pp, - 1, - &[ - ::Scalar::zero(), - ::Scalar::zero(), - ::Scalar::zero(), - ::Scalar::zero(), - ::Scalar::from(3 as u64), - ], - &[::Scalar::ZERO], - ); - assert_eq!(res.is_ok(),true); - } - - #[test] - // test invalid instruction in trace record - fn test_invalid_instruction_in_one_step() { - let address = 0 as u64; - let instruction = 2 as u64; - let value = 1292001 as u64; - // let num_steps = 10; - let circuit_primary = - NovaMemoryConsistencyCircuit::<::GE>::new(4, address, instruction, value); - let circuit_secondary = TrivialCircuit::<::Scalar>::default(); - - type C1 = NovaMemoryConsistencyCircuit<::GE>; - type C2 = TrivialCircuit<::Scalar>; - - let pp = PublicParams::< - E1, - E2, - NovaMemoryConsistencyCircuit<::GE>, - TrivialCircuit<::Scalar>, - >::setup( - &circuit_primary, - &circuit_secondary, - &*S1::ck_floor(), - &*S2::ck_floor(), - ) - .expect("unable to setup"); - - let mut recursive_snark = RecursiveSNARK::::new( - &pp, - &circuit_primary, - &circuit_secondary, - &[ - ::Scalar::zero(), - ::Scalar::zero(), - ::Scalar::zero(), - ::Scalar::zero(), - ::Scalar::from(3 as u64), - ], - &[::Scalar::zero()], - ) - .expect("unable to prove"); - - let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); - //assert!(res.is_ok()); - // println!("{:?}", res); - - let res = recursive_snark.verify( - &pp, - 1, - &[ - ::Scalar::zero(), - ::Scalar::zero(), - ::Scalar::zero(), - ::Scalar::zero(), - ::Scalar::from(3 as u64), - ], - &[::Scalar::ZERO], - ); - assert_ne!(res.is_ok(),true); - } + type E1 = Bn256EngineKZG; + type E2 = GrumpkinEngine; + type EE1 = nova_snark::provider::hyperkzg::EvaluationEngine; + type EE2 = nova_snark::provider::ipa_pc::EvaluationEngine; + type S1 = nova_snark::spartan::snark::RelaxedR1CSSNARK; // non-preprocessing SNARK + type S2 = nova_snark::spartan::snark::RelaxedR1CSSNARK; // non-preprocessing SNARK + #[test] + // test correct memory consistency in one step + fn test_memory_consistency_in_one_step() { + let address = [0 as u64].to_vec(); + let instruction = [1 as u64].to_vec(); + let value = [1292001 as u64].to_vec(); + // let num_steps = 10; + let circuit_primary = NovaMemoryConsistencyCircuit::<::GE>::new( + 4, + 1, + address, + instruction, + value, + ); + let circuit_secondary = TrivialCircuit::<::Scalar>::default(); + + type C1 = NovaMemoryConsistencyCircuit<::GE>; + type C2 = TrivialCircuit<::Scalar>; + + let pp = PublicParams::< + E1, + E2, + NovaMemoryConsistencyCircuit<::GE>, + TrivialCircuit<::Scalar>, + >::setup( + &circuit_primary, + &circuit_secondary, + &*S1::ck_floor(), + &*S2::ck_floor(), + ) + .expect("unable to setup"); + + let mut recursive_snark = RecursiveSNARK::::new( + &pp, + &circuit_primary, + &circuit_secondary, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::from(3 as u64), + ], + &[::Scalar::zero()], + ) + .expect("unable to prove"); + + let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); + // assert!(res.is_ok()); + // println!("{:?}", res); + + let res = recursive_snark.verify( + &pp, + 1, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::from(3 as u64), + ], + &[::Scalar::ZERO], + ); + assert_eq!(res.is_ok(), true); + } + + // for simolicity we experiment with a memory of size 4 + // test memory consistency in two steps + #[test] + fn test_memory_consistency_in_two_steps() { + let address = [0 as u64, 0 as u64].to_vec(); + let instruction = [1 as u64, 0 as u64].to_vec(); + let value = [1292001 as u64, 1292001 as u64].to_vec(); + // let num_steps = 10; + let circuit_primary = NovaMemoryConsistencyCircuit::<::GE>::new( + 4, + 2, + address, + instruction, + value, + ); + let circuit_secondary = TrivialCircuit::<::Scalar>::default(); + + type C1 = NovaMemoryConsistencyCircuit<::GE>; + type C2 = TrivialCircuit<::Scalar>; + + let pp = PublicParams::< + E1, + E2, + NovaMemoryConsistencyCircuit<::GE>, + TrivialCircuit<::Scalar>, + >::setup( + &circuit_primary, + &circuit_secondary, + &*S1::ck_floor(), + &*S2::ck_floor(), + ) + .expect("unable to setup"); + + let mut recursive_snark = RecursiveSNARK::::new( + &pp, + &circuit_primary, + &circuit_secondary, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::from(3 as u64), + ], + &[::Scalar::zero()], + ) + .expect("unable to prove"); + + let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); + // assert!(res.is_ok()); + // println!("{:?}", res); + + let res = recursive_snark.verify( + &pp, + 1, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::from(3 as u64), + ], + &[::Scalar::ZERO], + ); + assert_eq!(res.is_ok(), true); + } + + #[test] + // test invalid instruction in trace record + fn test_invalid_instruction() { + let address = [0 as u64].to_vec(); + let instruction = [2 as u64].to_vec(); + let value = [1292001 as u64].to_vec(); + // let num_steps = 10; + let circuit_primary = NovaMemoryConsistencyCircuit::<::GE>::new( + 4, + 1, + address, + instruction, + value, + ); + let circuit_secondary = TrivialCircuit::<::Scalar>::default(); + + type C1 = NovaMemoryConsistencyCircuit<::GE>; + type C2 = TrivialCircuit<::Scalar>; + + let pp = PublicParams::< + E1, + E2, + NovaMemoryConsistencyCircuit<::GE>, + TrivialCircuit<::Scalar>, + >::setup( + &circuit_primary, + &circuit_secondary, + &*S1::ck_floor(), + &*S2::ck_floor(), + ) + .expect("unable to setup"); + + let mut recursive_snark = RecursiveSNARK::::new( + &pp, + &circuit_primary, + &circuit_secondary, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::from(3 as u64), + ], + &[::Scalar::zero()], + ) + .expect("unable to prove"); + + let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); + //assert!(res.is_ok()); + // println!("{:?}", res); + + let res = recursive_snark.verify( + &pp, + 1, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::from(3 as u64), + ], + &[::Scalar::ZERO], + ); + assert_ne!(res.is_ok(), true); + } + + #[test] + // test invalid read + fn test_invalid_read() { + let address = [0 as u64].to_vec(); + let instruction = [0 as u64].to_vec(); + let value = [1292001 as u64].to_vec(); + // let num_steps = 10; + let circuit_primary = NovaMemoryConsistencyCircuit::<::GE>::new( + 4, + 1, + address, + instruction, + value, + ); + let circuit_secondary = TrivialCircuit::<::Scalar>::default(); + + type C1 = NovaMemoryConsistencyCircuit<::GE>; + type C2 = TrivialCircuit<::Scalar>; + + let pp = PublicParams::< + E1, + E2, + NovaMemoryConsistencyCircuit<::GE>, + TrivialCircuit<::Scalar>, + >::setup( + &circuit_primary, + &circuit_secondary, + &*S1::ck_floor(), + &*S2::ck_floor(), + ) + .expect("unable to setup"); + + let mut recursive_snark = RecursiveSNARK::::new( + &pp, + &circuit_primary, + &circuit_secondary, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::from(3 as u64), + ], + &[::Scalar::zero()], + ) + .expect("unable to prove"); + + let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); + //assert!(res.is_ok()); + // println!("{:?}", res); + + let res = recursive_snark.verify( + &pp, + 1, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::from(3 as u64), + ], + &[::Scalar::ZERO], + ); + assert_ne!(res.is_ok(), true); + } + + #[test] + // test invalid commitment + fn test_invalid_commitment() { + let address = [0 as u64].to_vec(); + let instruction = [0 as u64].to_vec(); + let value = [1292001 as u64].to_vec(); + // let num_steps = 10; + let circuit_primary = NovaMemoryConsistencyCircuit::<::GE>::new( + 4, + 1, + address, + instruction, + value, + ); + let circuit_secondary = TrivialCircuit::<::Scalar>::default(); + + type C1 = NovaMemoryConsistencyCircuit<::GE>; + type C2 = TrivialCircuit<::Scalar>; + + let pp = PublicParams::< + E1, + E2, + NovaMemoryConsistencyCircuit<::GE>, + TrivialCircuit<::Scalar>, + >::setup( + &circuit_primary, + &circuit_secondary, + &*S1::ck_floor(), + &*S2::ck_floor(), + ) + .expect("unable to setup"); + + let mut recursive_snark = RecursiveSNARK::::new( + &pp, + &circuit_primary, + &circuit_secondary, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::from(99 as u64), + ], + &[::Scalar::zero()], + ) + .expect("unable to prove"); + + let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); + //assert!(res.is_ok()); + // println!("{:?}", res); + + let res = recursive_snark.verify( + &pp, + 1, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::from(99 as u64), + ], + &[::Scalar::ZERO], + ); + assert_ne!(res.is_ok(), true); + } } diff --git a/zkmemory/src/poseidon/poseidon_hash.rs b/zkmemory/src/poseidon/poseidon_hash.rs index 4ef5fc2..e033ccd 100644 --- a/zkmemory/src/poseidon/poseidon_hash.rs +++ b/zkmemory/src/poseidon/poseidon_hash.rs @@ -78,11 +78,11 @@ impl Absorbing { } /// The absorbing state of the `Sponge`. -#[derive(Clone,Debug)] +#[derive(Clone, Debug)] pub struct Absorbing(pub(crate) [Option; R]); /// The squeezing state of the `Sponge`. -#[derive(Clone,Debug)] +#[derive(Clone, Debug)] pub struct Squeezing(pub(crate) [Option; R]); /// The type used to hold permutation state. From d2ee371f1fe31412b59a99eb1a586b68c3d1f553 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Sun, 11 Aug 2024 23:23:49 +0700 Subject: [PATCH 12/24] Update poseidon parameters for memory consistency circuit of Nova --- zkmemory/src/lib.rs | 2 +- .../src/nova/memory_consistency_circuit.rs | 116 +- zkmemory/src/nova/mod.rs | 2 + zkmemory/src/nova/poseidon_parameters.rs | 1442 +++++++++++++++++ zkmemory/src/nova/testcases.rs | 133 +- 5 files changed, 1596 insertions(+), 99 deletions(-) create mode 100644 zkmemory/src/nova/poseidon_parameters.rs diff --git a/zkmemory/src/lib.rs b/zkmemory/src/lib.rs index a715ccc..dbca760 100644 --- a/zkmemory/src/lib.rs +++ b/zkmemory/src/lib.rs @@ -25,7 +25,7 @@ pub mod constraints; pub mod error; /// Definition of abstract machine (instruction, trace and context) pub mod machine; -/// +/// Memory consistency circuit using Nova proof system pub mod nova; /// The module of Poseidon hash function pub mod poseidon; diff --git a/zkmemory/src/nova/memory_consistency_circuit.rs b/zkmemory/src/nova/memory_consistency_circuit.rs index 6f10c60..a9d5b2d 100644 --- a/zkmemory/src/nova/memory_consistency_circuit.rs +++ b/zkmemory/src/nova/memory_consistency_circuit.rs @@ -1,4 +1,6 @@ extern crate alloc; +use core::marker::PhantomData; + use alloc::format; use alloc::vec; use alloc::vec::Vec; @@ -7,6 +9,10 @@ use ff::Field; /// Reference to be added later. use nova_snark::traits::{circuit::StepCircuit, Group}; +use crate::poseidon::poseidon_hash::ConstantLength; +use crate::poseidon::poseidon_hash::Hash; +use crate::poseidon::poseidon_hash::Spec; + #[derive(Copy, Clone)] /// the trace record struct pub struct TraceRecord { @@ -17,13 +23,25 @@ pub struct TraceRecord { #[derive(Clone)] /// memory consistency circuit in one step -pub struct NovaMemoryConsistencyCircuit { +pub struct NovaMemoryConsistencyCircuit< + G: Group, + S: Spec + Clone + core::marker::Sync + core::marker::Send, + const W: usize, + const R: usize, +> { memory_len: usize, num_iters_per_step: usize, trace_record: Vec>, + _marker: PhantomData, } -impl StepCircuit for NovaMemoryConsistencyCircuit { +impl< + G: Group, + S: Spec + Clone + core::marker::Sync + core::marker::Send, + const W: usize, + const R: usize, + > StepCircuit for NovaMemoryConsistencyCircuit +{ fn arity(&self) -> usize { self.memory_len + 1 } @@ -41,11 +59,11 @@ impl StepCircuit for NovaMemoryConsistencyCircuit { // z_i[address]. Also we need the merkle root in z_i // The ZERO variable - let zero = AllocatedNum::alloc(cs.namespace(|| format!("zero")), || Ok(G::Scalar::ZERO)) + let zero = AllocatedNum::alloc(cs.namespace(|| "zero"), || Ok(G::Scalar::ZERO)) .expect("unable to get ZERO value"); // The ONE variable - let one = AllocatedNum::alloc(cs.namespace(|| format!("one")), || Ok(G::Scalar::ONE)) + let one = AllocatedNum::alloc(cs.namespace(|| "one"), || Ok(G::Scalar::ONE)) .expect("unable to get ONE value"); let mut z_out = z_in.to_vec(); @@ -53,44 +71,46 @@ impl StepCircuit for NovaMemoryConsistencyCircuit { // Get the current state of the memory for j in 0..self.num_iters_per_step { let mut memory: Vec> = vec![]; - for i in 0..self.memory_len { - memory.push(z_out[i].clone()) + for i in z_out.iter().take(self.memory_len) { + memory.push(i.clone()) } // The value variable - let value = AllocatedNum::alloc(cs.namespace(|| format!("value")), || { + let value = AllocatedNum::alloc(cs.namespace(|| format!("value {j}")), || { Ok(self.trace_record[j].value) }) .expect("unable to get value"); // The instruction variable - let instruction = AllocatedNum::alloc(cs.namespace(|| format!("instruction")), || { - Ok(self.trace_record[j].instruction) - }) - .expect("unable to get instruction"); - - let instruction_minus_one = - AllocatedNum::alloc(cs.namespace(|| format!("instruction minus one")), || { - Ok(self.trace_record[j].instruction - G::Scalar::ONE) + let instruction = + AllocatedNum::alloc(cs.namespace(|| format!("instruction {j}")), || { + Ok(self.trace_record[j].instruction) }) - .expect("unable to get instruction_minus_one"); + .expect("unable to get instruction"); + + let instruction_minus_one = AllocatedNum::alloc( + cs.namespace(|| format!("instruction {j} minus one")), + || Ok(self.trace_record[j].instruction - G::Scalar::ONE), + ) + .expect("unable to get instruction_minus_one"); // Get memory[address] let mut memory_address = zero.clone(); - for i in 0..self.memory_len { + for (i, item) in memory.iter().enumerate().take(self.memory_len) { if G::Scalar::from(i as u64) == self.trace_record[j].address { - memory_address = memory[i].clone(); + memory_address = item.clone(); } } // create the Merkle commitment of the tree - let commitment = AllocatedNum::alloc(cs.namespace(|| format!("merkle root")), || { - Ok(self.clone().merkle_tree_commit(memory.clone())) - }) - .expect("unable to get commitment"); + let commitment = + AllocatedNum::alloc(cs.namespace(|| format!("merkle root {j}")), || { + Ok(self.clone().merkle_tree_commit(memory.clone())) + }) + .expect("unable to get commitment"); // commitment to the memory must be valid cs.enforce( - || format!("commitment to the memory must be valid"), + || "commitment to the memory must be valid", |lc| lc + commitment.get_variable(), |lc| lc + one.get_variable(), |lc| lc + z_out[self.memory_len].get_variable(), @@ -98,7 +118,7 @@ impl StepCircuit for NovaMemoryConsistencyCircuit { // if instruction = 0 then memory[address]=value cs.enforce( - || format!("if instruction=0 then memory[address] = value"), + || "if instruction=0 then memory[address] = value", |lc| lc + instruction_minus_one.get_variable(), |lc| lc + memory_address.get_variable() - value.get_variable(), |lc| lc + zero.get_variable(), @@ -106,7 +126,7 @@ impl StepCircuit for NovaMemoryConsistencyCircuit { // instruction must be read or write cs.enforce( - || format!("operation is read or write"), + || "operation is read or write", |lc| lc + instruction.get_variable(), |lc| lc + instruction_minus_one.get_variable(), |lc| lc + zero.get_variable(), @@ -115,19 +135,19 @@ impl StepCircuit for NovaMemoryConsistencyCircuit { // create the output, which includes the memory and the Merkle // tree commitment of the memory z_out.clear(); - for i in 0..self.memory_len { + for (i, item) in memory.iter().enumerate().take(self.memory_len) { if G::Scalar::from(i as u64) != self.trace_record[j].address { - z_out.push(memory[i].clone()); + z_out.push(item.clone()); } else { z_out.push(value.clone()); } } // commitment to the new updated memory - let new_commitment = - AllocatedNum::alloc(cs.namespace(|| format!("merkle root")), || { - Ok(self.clone().merkle_tree_commit(z_out.clone())) - }) - .expect("unable to get new commitment"); + let new_commitment = AllocatedNum::alloc( + cs.namespace(|| format!("merkle root in iteration {j}")), + || Ok(self.clone().merkle_tree_commit(z_out.clone())), + ) + .expect("unable to get new commitment"); z_out.push(new_commitment); assert!(z_out.len() == self.memory_len + 1); @@ -137,7 +157,13 @@ impl StepCircuit for NovaMemoryConsistencyCircuit { } } -impl NovaMemoryConsistencyCircuit { +impl< + G: Group, + S: Spec + Clone + core::marker::Sync + core::marker::Send, + const W: usize, + const R: usize, + > NovaMemoryConsistencyCircuit +{ /// Create a new trace_record pub fn new( memory_len: usize, @@ -158,29 +184,31 @@ impl NovaMemoryConsistencyCircuit { memory_len, num_iters_per_step, trace_record, + _marker: PhantomData, } } /// compute the merkle root of the memory pub fn merkle_tree_commit(self, memory: Vec>) -> G::Scalar { - let mut tmp: Vec = memory + let mut root: Vec = memory .into_iter() .map(|x| x.get_value().expect("unable to get memory values")) .collect(); - let mut size = tmp.len(); + let hash = Hash::, W, R>::init(); + let mut size = root.len(); while size > 1 { - let mut tmp2 = size; - while tmp2 > 1 { - let left = tmp.pop().expect("unable to get left"); - let right = tmp.pop().expect("unable to get right"); + let mut root_size = size; + while root_size > 1 { + let left = root.pop().expect("unable to get left"); + let right = root.pop().expect("unable to get right"); // TODO: replace "out" with a hash function - let out = left + right + G::Scalar::ONE; + let out = hash.clone().hash([left, right]); // End TODO - tmp.push(out); - tmp2 = tmp2 - 2; + root.push(out); + root_size -= 2; } - size = tmp.len(); + size = root.len(); } - tmp[0] + root[0] } } diff --git a/zkmemory/src/nova/mod.rs b/zkmemory/src/nova/mod.rs index e291d68..f65fa29 100644 --- a/zkmemory/src/nova/mod.rs +++ b/zkmemory/src/nova/mod.rs @@ -1,4 +1,6 @@ /// the memory consitency circuit using Nova proof system pub mod memory_consistency_circuit; +/// parameters of Poseidon hash +pub mod poseidon_parameters; /// the testcases of memory consistency circuit pub mod testcases; diff --git a/zkmemory/src/nova/poseidon_parameters.rs b/zkmemory/src/nova/poseidon_parameters.rs new file mode 100644 index 0000000..e04cd11 --- /dev/null +++ b/zkmemory/src/nova/poseidon_parameters.rs @@ -0,0 +1,1442 @@ +extern crate alloc; +use alloc::vec::Vec; +use ff::Field; +use nova_snark::provider::Bn256EngineKZG; + +use crate::poseidon::poseidon_hash::{Mtrx, Spec}; +type E1 = Bn256EngineKZG; +type FF = ::Scalar; +/// Generate specific constants for testing the poseidon hash +#[derive(Clone, Debug)] +pub struct OrchardNullifierScalar; + +impl Spec for OrchardNullifierScalar { + fn full_rounds() -> usize { + 8 + } + + fn partial_rounds() -> usize { + 56 + } + + fn sbox(val: FF) -> FF { + val.pow_vartime([5]) + } + + fn constants() -> (Vec<[FF; 3]>, Mtrx, Mtrx) { + ( + ROUND_CONSTANTS_SCALAR[..].to_vec(), + MDS_SCALAR, + MDS_INV_SCALAR, + ) + } +} + +pub(crate) const MDS_SCALAR: [[FF; 3]; 3] = [ + [ + FF::from_raw([ + 0x323f_2486_d7e1_1b63, + 0x97d7_a0ab_2385_0b56, + 0xb3d5_9fbd_c8c9_ead4, + 0x0ab5_e5b8_74a6_8de7, + ]), + FF::from_raw([ + 0x8eca_5596_e996_ab5e, + 0x240d_4a7c_bf73_5736, + 0x293f_0f0d_886c_7954, + 0x3191_6628_e58a_5abb, + ]), + FF::from_raw([ + 0x19d1_cf25_d8e8_345d, + 0xa0a3_b71a_5fb1_5735, + 0xd803_952b_bb36_4fdf, + 0x07c0_45d5_f5e9_e5a6, + ]), + ], + [ + FF::from_raw([ + 0xd049_cdc8_d085_167c, + 0x3a0a_4640_48bd_770a, + 0xf8e2_4f66_822c_2d9f, + 0x2331_6263_0ebf_9ed7, + ]), + FF::from_raw([ + 0x4022_7011_3e04_7a2e, + 0x78f8_365c_85bb_ab07, + 0xb366_6454_8d60_957d, + 0x25ca_e259_9892_a8b0, + ]), + FF::from_raw([ + 0xf84d_806f_685f_747a, + 0x9aad_3d82_62ef_d83f, + 0x7493_8717_989a_1957, + 0x22f5_b5e1_e608_1c97, + ]), + ], + [ + FF::from_raw([ + 0xfee7_a994_4f84_dbe4, + 0x2168_0eab_c56b_c15d, + 0xf333_aa91_c383_3464, + 0x2e29_dd59_c64b_1037, + ]), + FF::from_raw([ + 0xc771_effa_4326_3664, + 0xcbea_f48b_3a06_24c3, + 0x92d1_5e7d_ceef_1665, + 0x1d1a_ab4e_c1cd_6788, + ]), + FF::from_raw([ + 0x1563_9415_f6e8_5ef1, + 0x7587_2c39_b59a_31f6, + 0x51e0_cbea_d655_16b9, + 0x3bf7_6308_6a18_9364, + ]), + ], +]; + +pub(crate) const MDS_INV_SCALAR: [[FF; 3]; 3] = [ + [ + FF::from_raw([ + 0xc6de_463c_d140_4e6b, + 0x4543_705f_35e9_8ab5, + 0xcc59_ffd0_0de8_6443, + 0x2cc0_57f3_fa14_687a, + ]), + FF::from_raw([ + 0x1718_4041_7cab_7576, + 0xfadb_f8ae_7ae2_4796, + 0x5fd7_2b55_df20_8385, + 0x32e7_c439_f2f9_67e5, + ]), + FF::from_raw([ + 0x9426_45bd_7d44_64e0, + 0x1403_db6f_5030_2040, + 0xf461_778a_bf6c_91fa, + 0x2eae_5df8_c311_5969, + ]), + ], + [ + FF::from_raw([ + 0xa1ca_1516_a4a1_a6a0, + 0x13f0_74fd_e9a1_8b29, + 0xdb18_b4ae_fe68_d26d, + 0x07bf_3684_8106_7199, + ]), + FF::from_raw([ + 0xe824_25bc_1b23_a059, + 0xbb1d_6504_0c85_c1bf, + 0x018a_918b_9dac_5dad, + 0x2aec_6906_c63f_3cf1, + ]), + FF::from_raw([ + 0xe054_1adf_238e_0781, + 0x76b2_a713_9db7_1b36, + 0x1215_944a_64a2_46b2, + 0x0952_e024_3aec_2af0, + ]), + ], + [ + FF::from_raw([ + 0x2a41_8d8d_73a7_c908, + 0xaef9_112e_952f_dbb5, + 0x723a_63a0_c09d_ab26, + 0x2fcb_ba6f_9159_a219, + ]), + FF::from_raw([ + 0x76ef_ab42_d4fb_a90b, + 0xc5e4_960d_7424_cd37, + 0xb4dd_d4b4_d645_2256, + 0x1ec7_3725_74f3_851b, + ]), + FF::from_raw([ + 0xadc8_933c_6f3c_72ee, + 0x87a7_435d_30f8_be81, + 0x3c26_fa4b_7d25_b1e4, + 0x0d0c_2efd_6472_f12a, + ]), + ], +]; + +pub(crate) const ROUND_CONSTANTS_SCALAR: [[FF; 3]; 64] = [ + [ + FF::from_raw([ + 0x5753_8c25_9642_6303, + 0x4e71_162f_3100_3b70, + 0x353f_628f_76d1_10f3, + 0x360d_7470_611e_473d, + ]), + FF::from_raw([ + 0xbdb7_4213_bf63_188b, + 0x4908_ac2f_12eb_e06f, + 0x5dc3_c6c5_febf_aa31, + 0x2bab_94d7_ae22_2d13, + ]), + FF::from_raw([ + 0x0939_d927_53cc_5dc8, + 0xef77_e7d7_3676_6c5d, + 0x2bf0_3e1a_29aa_871f, + 0x150c_93fe_f652_fb1c, + ]), + ], + [ + FF::from_raw([ + 0x1425_9dce_5377_82b2, + 0x03cc_0a60_141e_894e, + 0x955d_55db_56dc_57c1, + 0x3270_661e_6892_8b3a, + ]), + FF::from_raw([ + 0xce9f_b9ff_c345_afb3, + 0xb407_c370_f2b5_a1cc, + 0xa0b7_afe4_e205_7299, + 0x073f_116f_0412_2e25, + ]), + FF::from_raw([ + 0x8eba_d76f_c715_54d8, + 0x55c9_cd20_61ae_93ca, + 0x7aff_d09c_1f53_f5fd, + 0x2a32_ec5c_4ee5_b183, + ]), + ], + [ + FF::from_raw([ + 0x2d8c_cbe2_92ef_eead, + 0x634d_24fc_6e25_59f2, + 0x651e_2cfc_7406_28ca, + 0x2703_26ee_039d_f19e, + ]), + FF::from_raw([ + 0xa068_fc37_c182_e274, + 0x8af8_95bc_e012_f182, + 0xdc10_0fe7_fcfa_5491, + 0x27c6_642a_c633_bc66, + ]), + FF::from_raw([ + 0x9ca1_8682_e26d_7ff9, + 0x710e_1fb6_ab97_6a45, + 0xd27f_5739_6989_129d, + 0x1bdf_d8b0_1401_c70a, + ]), + ], + [ + FF::from_raw([ + 0xc832_d824_261a_35ea, + 0xf4f6_fb3f_9054_d373, + 0x14b9_d6a9_c84d_d678, + 0x162a_14c6_2f9a_89b8, + ]), + FF::from_raw([ + 0xf798_2466_7b5b_6bec, + 0xac0a_1fc7_1e2c_f0c0, + 0x2af6_f79e_3127_feea, + 0x2d19_3e0f_76de_586b, + ]), + FF::from_raw([ + 0x5d0b_f58d_c8a4_aa94, + 0x4fef_f829_8499_0ff8, + 0x8169_6ef1_104e_674f, + 0x044c_a3cc_4a85_d73b, + ]), + ], + [ + FF::from_raw([ + 0x6198_785f_0cd6_b9af, + 0xb8d9_e2d4_f314_f46f, + 0x1d04_5341_6d3e_235c, + 0x1cba_f2b3_71da_c6a8, + ]), + FF::from_raw([ + 0x343e_0761_0f3f_ede5, + 0x293c_4ab0_38fd_bbdc, + 0x0e6c_49d0_61b6_b5f4, + 0x1d5b_2777_692c_205b, + ]), + FF::from_raw([ + 0xf60e_971b_8d73_b04f, + 0x06a9_adb0_c1e6_f962, + 0xaa30_535b_dd74_9a7e, + 0x2e9b_dbba_3dd3_4bff, + ]), + ], + [ + FF::from_raw([ + 0x035a_1366_1f22_418b, + 0xde40_fbe2_6d04_7b05, + 0x8bd5_bae3_6969_299f, + 0x2de1_1886_b180_11ca, + ]), + FF::from_raw([ + 0xbc99_8884_ba96_a721, + 0x2ab9_395c_449b_e947, + 0x0d5b_4a3f_1841_dcd8, + 0x2e07_de17_80b8_a70d, + ]), + FF::from_raw([ + 0x825e_4c2b_b749_25ca, + 0x2504_40a9_9d6b_8af3, + 0xbbdb_63db_d52d_ad16, + 0x0f69_f185_4d20_ca0c, + ]), + ], + [ + FF::from_raw([ + 0x816c_0594_22dc_705e, + 0x6ce5_1135_07f9_6de9, + 0x0d13_5dc6_39fb_09a4, + 0x2eb1_b254_17fe_1767, + ]), + FF::from_raw([ + 0xb8b1_bdf4_953b_d82c, + 0xff36_c661_d26c_c42d, + 0x8c24_cb44_c3fa_b48a, + 0x115c_d0a0_643c_fb98, + ]), + FF::from_raw([ + 0xde80_1612_311d_04cd, + 0xbb57_ddf1_4e0f_958a, + 0x066d_7378_b999_868b, + 0x26ca_293f_7b2c_462d, + ]), + ], + [ + FF::from_raw([ + 0xf520_9d14_b248_20ca, + 0x0f16_0bf9_f71e_967f, + 0x2a83_0aa1_6241_2cd9, + 0x17bf_1b93_c4c7_e01a, + ]), + FF::from_raw([ + 0x05c8_6f2e_7dc2_93c5, + 0xe03c_0354_bd8c_fd38, + 0xa24f_8456_369c_85df, + 0x35b4_1a7a_c4f3_c571, + ]), + FF::from_raw([ + 0x72ac_156a_f435_d09e, + 0x64e1_4d3b_eb2d_ddde, + 0x4359_2799_4849_bea9, + 0x3b14_8008_0523_c439, + ]), + ], + [ + FF::from_raw([ + 0x2716_18d8_74b1_4c6d, + 0x08e2_8644_2a2d_3eb2, + 0x4950_856d_c907_d575, + 0x2cc6_8100_31dc_1b0d, + ]), + FF::from_raw([ + 0x91f3_18c0_9f0c_b566, + 0x9e51_7aa9_3b78_341d, + 0x0596_18e2_afd2_ef99, + 0x25bd_bbed_a1bd_e8c1, + ]), + FF::from_raw([ + 0xc631_3487_073f_7f7b, + 0x2a5e_d0a2_7b61_926c, + 0xb95f_33c2_5dde_8ac0, + 0x392a_4a87_58e0_6ee8, + ]), + ], + [ + FF::from_raw([ + 0xe7bb_cef0_2eb5_866c, + 0x5e6a_6fd1_5db8_9365, + 0x9aa6_111f_4de0_0948, + 0x272a_5587_8a08_442b, + ]), + FF::from_raw([ + 0x9b92_5b3c_5b21_e0e2, + 0xa6eb_ba01_1694_dd12, + 0xefa1_3c4e_60e2_6239, + 0x2d5b_308b_0cf0_2cdf, + ]), + FF::from_raw([ + 0xef38_c57c_3116_73ac, + 0x44df_f42f_18b4_6c56, + 0xdd5d_293d_72e2_e5f2, + 0x1654_9fc6_af2f_3b72, + ]), + ], + [ + FF::from_raw([ + 0x9b71_26d9_b468_60df, + 0x7639_8265_3442_0311, + 0xfa69_c3a2_ad52_f76d, + 0x1b10_bb7a_82af_ce39, + ]), + FF::from_raw([ + 0x90d2_7f6a_00b7_dfc8, + 0xd1b3_6968_ba04_05c0, + 0xc79c_2df7_dc98_a3be, + 0x0f1e_7505_ebd9_1d2f, + ]), + FF::from_raw([ + 0xff45_7756_b819_bb20, + 0x797f_d6e3_f18e_b1ca, + 0x537a_7497_a3b4_3f46, + 0x2f31_3faf_0d3f_6187, + ]), + ], + [ + FF::from_raw([ + 0xf0bc_3e73_2ecb_26f6, + 0x5cad_11eb_f0f7_ceb8, + 0xfa3c_a61c_0ed1_5bc5, + 0x3a5c_bb6d_e450_b481, + ]), + FF::from_raw([ + 0x8655_27cb_ca91_5982, + 0x51ba_a6e2_0f89_2b62, + 0xd920_86e2_53b4_39d6, + 0x3dab_54bc_9bef_688d, + ]), + FF::from_raw([ + 0x3680_45ac_f2b7_1ae3, + 0x4c24_b33b_410f_efd4, + 0xe280_d316_7012_3f74, + 0x06db_fb42_b979_884d, + ]), + ], + [ + FF::from_raw([ + 0xa7fc_32d2_2f18_b9d3, + 0xb8d2_de72_e3d2_c9ec, + 0xc6f0_39ea_1973_a63e, + 0x068d_6b46_08aa_e810, + ]), + FF::from_raw([ + 0x2b5d_fcc5_5725_55df, + 0xb868_a7d7_e1f1_f69a, + 0x0ee2_58c9_b8fd_fccd, + 0x366e_bfaf_a3ad_381c, + ]), + FF::from_raw([ + 0xe6bc_229e_95bc_76b1, + 0x7ef6_6d89_d044_d022, + 0x04db_3024_f41d_3f56, + 0x3967_8f65_512f_1ee4, + ]), + ], + [ + FF::from_raw([ + 0xe534_c88f_e53d_85fe, + 0xcf82_c25f_99dc_01a4, + 0xd58b_7750_a3bc_2fe1, + 0x2166_8f01_6a80_63c0, + ]), + FF::from_raw([ + 0x4bef_429b_c533_1608, + 0xe34d_ea56_439f_e195, + 0x1bc7_4936_3e98_a768, + 0x39d0_0994_a8a5_046a, + ]), + FF::from_raw([ + 0x770c_956f_60d8_81b3, + 0xb163_d416_05d3_9f99, + 0x6b20_3bbe_12fb_3425, + 0x1f9d_bdc3_f843_1263, + ]), + ], + [ + FF::from_raw([ + 0x9794_a9f7_c336_eab2, + 0xbe0b_c829_fe5e_66c6, + 0xe5f1_7b9e_0ee0_cab6, + 0x0277_45a9_cddf_ad95, + ]), + FF::from_raw([ + 0x5202_5657_abd8_aee0, + 0x2fa4_3fe2_0a45_c78d, + 0x788d_695c_61e9_3212, + 0x1cec_0803_c504_b635, + ]), + FF::from_raw([ + 0xd387_2a95_59a0_3a73, + 0xed50_82c8_dbf3_1365, + 0x7207_7448_ef87_cc6e, + 0x1235_23d7_5e9f_abc1, + ]), + ], + [ + FF::from_raw([ + 0x0017_79e3_a1d3_57f4, + 0x27fe_ba35_975e_e7e5, + 0xf419_b848_e5d6_94bf, + 0x1723_d145_2c9c_f02d, + ]), + FF::from_raw([ + 0x9dab_1ee4_dcf9_6622, + 0x21c3_f776_f572_836d, + 0xfcc0_573d_7e61_3694, + 0x1739_d180_a160_10bd, + ]), + FF::from_raw([ + 0x7029_0452_042d_048d, + 0xfafa_96fb_eb0a_b893, + 0xacce_3239_1794_b627, + 0x2d4e_6354_da9c_c554, + ]), + ], + [ + FF::from_raw([ + 0x670b_cf6f_8b48_5dcd, + 0x8f3b_d43f_9926_0621, + 0x4a86_9553_c9d0_07f8, + 0x153e_e614_2e53_5e33, + ]), + FF::from_raw([ + 0xd258_d2e2_b778_2172, + 0x968a_d442_4af8_3700, + 0x635e_f7e7_a430_b486, + 0x0c45_bfd3_a69a_aa65, + ]), + FF::from_raw([ + 0x0e56_33d2_51f7_3307, + 0x6897_ac0a_8ffa_5ff1, + 0xf2d5_6aec_8314_4600, + 0x0adf_d53b_256a_6957, + ]), + ], + [ + FF::from_raw([ + 0xac9d_36a8_b751_6d63, + 0x3f87_b28f_1c1b_e4bd, + 0x8cd1_726b_7cba_b8ee, + 0x315d_2ac8_ebdb_ac3c, + ]), + FF::from_raw([ + 0x299c_e44e_a423_d8e1, + 0xc9bb_60d1_f695_9879, + 0xcfae_c23d_2b16_883f, + 0x1b84_7271_2d02_eef4, + ]), + FF::from_raw([ + 0xc4a5_4041_98ad_f70c, + 0x367d_2c54_e369_28c9, + 0xbd0b_70fa_2255_eb6f, + 0x3c1c_d07e_fda6_ff24, + ]), + ], + [ + FF::from_raw([ + 0xbbe5_23ae_f9ab_107a, + 0x4a16_073f_738f_7e0c, + 0x687f_4e51_b2e1_dcd3, + 0x1360_52d2_6bb3_d373, + ]), + FF::from_raw([ + 0x676c_36c2_4ef9_67dd, + 0x7b3c_fbb8_7303_2681, + 0xc1bd_d859_a123_2a1d, + 0x16c9_6bee_f6a0_a848, + ]), + FF::from_raw([ + 0x067e_ec7f_2d63_40c4, + 0x0123_87ba_b4f1_662d, + 0x2ab7_fed8_f499_a9fb, + 0x284b_38c5_7ff6_5c26, + ]), + ], + [ + FF::from_raw([ + 0xaf1d_ff20_4c92_2f86, + 0xfc06_772c_1c04_11a6, + 0x39e2_4219_8897_d17c, + 0x0c59_93d1_75e8_1f66, + ]), + FF::from_raw([ + 0xbbf5_3f67_b1f8_7b15, + 0xf248_87ad_48e1_7759, + 0xfcda_655d_1ba9_c8f9, + 0x03bf_7a3f_7bd0_43da, + ]), + FF::from_raw([ + 0x9b5c_d09e_36d8_be62, + 0x4c8f_9cbe_69f0_e827, + 0xb0cf_9995_67f0_0e73, + 0x3188_fe4e_e9f9_fafb, + ]), + ], + [ + FF::from_raw([ + 0xafea_99a2_ec6c_595a, + 0x3af5_bf77_c1c4_2652, + 0x5a39_768c_480d_61e1, + 0x171f_528c_cf65_8437, + ]), + FF::from_raw([ + 0x5a05_63b9_b8e9_f1d5, + 0x812c_3286_ee70_0067, + 0x196e_4185_9b35_ef88, + 0x12f4_175c_4ab4_5afc, + ]), + FF::from_raw([ + 0x0e74_d4d3_6911_8b79, + 0x7e23_e1aa_be96_cfab, + 0x8f8f_dcf8_00a9_ac69, + 0x3a50_9e15_5cb7_ebfd, + ]), + ], + [ + FF::from_raw([ + 0x9871_2c65_678c_fd30, + 0x984b_c8f2_e4c1_b69e, + 0x1a89_920e_2504_c3b3, + 0x10f2_a685_df4a_27c8, + ]), + FF::from_raw([ + 0xe8a1_6728_cc9d_4918, + 0x5457_3c93_33c5_6321, + 0x1d8d_93d5_4ab9_1a0e, + 0x09e5_f497_90c8_a0e2, + ]), + FF::from_raw([ + 0x609a_7403_47cf_5fea, + 0x42d1_7ed6_ee0f_ab7e, + 0x2bf3_5705_d9f8_4a34, + 0x352d_69be_d80e_e3e5, + ]), + ], + [ + FF::from_raw([ + 0x3a75_8af6_fa84_e0e8, + 0xc634_debd_281b_76a6, + 0x4915_62fa_f2b1_90d3, + 0x058e_e73b_a9f3_f293, + ]), + FF::from_raw([ + 0x621a_1325_10a4_3904, + 0x092c_b921_19bc_76be, + 0xcd0f_1fc5_5b1a_3250, + 0x232f_99cc_911e_ddd9, + ]), + FF::from_raw([ + 0xc3b9_7c1e_301b_c213, + 0xf9ef_d52c_a6bc_2961, + 0x86c2_2c6c_5d48_69f0, + 0x201b_eed7_b8f3_ab81, + ]), + ], + [ + FF::from_raw([ + 0xbf6b_3431_ba94_e9bc, + 0x2938_8842_744a_1210, + 0xa1c9_291d_5860_2f51, + 0x1376_dce6_5800_30c6, + ]), + FF::from_raw([ + 0x6454_843c_5486_d7b3, + 0x072b_a8b0_2d92_e722, + 0x2b33_56c3_8238_f761, + 0x1793_199e_6fd6_ba34, + ]), + FF::from_raw([ + 0x06a3_f1d3_b433_311b, + 0x3c66_160d_c62a_acac, + 0x9fee_9c20_c87a_67df, + 0x22de_7a74_88dc_c735, + ]), + ], + [ + FF::from_raw([ + 0x30d6_e3fd_516b_47a8, + 0xdbe0_b77f_ae77_e1d0, + 0xdf8f_f37f_e2d8_edf8, + 0x3514_d5e9_066b_b160, + ]), + FF::from_raw([ + 0x1937_7427_137a_81c7, + 0xff45_3d6f_900f_144a, + 0xf919_a00d_abbf_5fa5, + 0x30cd_3006_931a_d636, + ]), + FF::from_raw([ + 0x5b6a_7422_0692_b506, + 0x8f9e_4b2c_ae2e_bb51, + 0x41f8_1a5c_f613_c8df, + 0x253d_1a5c_5293_4127, + ]), + ], + [ + FF::from_raw([ + 0x73f6_66cb_86a4_8e8e, + 0x851b_3a59_c990_fafc, + 0xa35e_9613_e7f5_fe92, + 0x035b_461c_02d7_9d19, + ]), + FF::from_raw([ + 0x7cfb_f86a_3aa0_4780, + 0x92b1_283c_2d5f_ccde, + 0x5bc0_0eed_d56b_93e0, + 0x23a9_9280_79d1_75bd, + ]), + FF::from_raw([ + 0xf1e4_ccd7_3fa0_0a82, + 0xb5e2_ea34_36ee_f957, + 0xf159_4a07_63c6_11ab, + 0x13a7_785a_e134_ea92, + ]), + ], + [ + FF::from_raw([ + 0xbbf0_4f52_52de_4279, + 0x3889_c578_6344_6d88, + 0x4962_ae3c_0da1_7e31, + 0x39fc_e308_b7d4_3c57, + ]), + FF::from_raw([ + 0x3b57_e344_89b5_3fad, + 0xbef0_0a08_c6ed_38d2, + 0xc0fd_f016_62f6_0d22, + 0x1aae_1883_3f8e_1d3a, + ]), + FF::from_raw([ + 0x5551_3e03_3398_513f, + 0x27c1_b3fd_8f85_d8a8, + 0x8b2e_80c0_64fd_83ed, + 0x1a76_1ce8_2400_af01, + ]), + ], + [ + FF::from_raw([ + 0x5244_ca74_9b73_e481, + 0xdcf6_af28_30a5_0287, + 0x16dd_1a87_ca22_e1cc, + 0x275a_03e4_5add_a7c3, + ]), + FF::from_raw([ + 0x58a2_53cf_b6a9_5786, + 0x07e5_6145_3fc5_648b, + 0xeb08_e47e_5fea_bcf8, + 0x2e5a_10f0_8b5a_b8bb, + ]), + FF::from_raw([ + 0xe033_d82c_efe7_8ce3, + 0xc141_a5b6_d594_bec4, + 0xb84e_9c33_3b29_32f1, + 0x1459_cb85_8720_8473, + ]), + ], + [ + FF::from_raw([ + 0x5cec_7e7b_338f_be1b, + 0x52f9_332f_bffc_fbbd, + 0x7b92_ce81_0e14_a400, + 0x193a_e592_1d78_b5de, + ]), + FF::from_raw([ + 0x6022_4be6_7248_e82c, + 0x3743_84f4_a072_8205, + 0x8911_1fb2_c466_0281, + 0x3097_898a_5d00_11a4, + ]), + FF::from_raw([ + 0x5499_80de_8629_30f5, + 0x1979_b2d1_c465_b4d9, + 0x5717_82fd_96ce_54b4, + 0x378d_97bf_8c86_4ae7, + ]), + ], + [ + FF::from_raw([ + 0x37ea_32a9_71d1_7884, + 0xdbc7_f5cb_4609_3421, + 0x8813_6287_ce37_6b08, + 0x2eb0_4ea7_c01d_97ec, + ]), + FF::from_raw([ + 0xead3_726f_1af2_e7b0, + 0x861c_bda4_7680_4e6c, + 0x2302_a1c2_2e49_baec, + 0x3642_5347_ea03_f641, + ]), + FF::from_raw([ + 0xecd6_27e5_9590_d09e, + 0x3f5b_5ca5_a19a_9701, + 0xcc99_6cd8_5c98_a1d8, + 0x26b7_2df4_7408_ad42, + ]), + ], + [ + FF::from_raw([ + 0x59be_ce31_f0a3_1e95, + 0xde01_212e_e458_8f89, + 0x1f05_636c_610b_89aa, + 0x1301_80e4_4e29_24db, + ]), + FF::from_raw([ + 0x9ea8_e7bc_7926_3550, + 0xdf77_93cc_89e5_b52f, + 0x7327_5aca_ed5f_579c, + 0x219e_9773_7d39_79ba, + ]), + FF::from_raw([ + 0x9c12_635d_f251_d153, + 0x3b06_72dd_7d42_cbb4, + 0x3461_363f_81c4_89a2, + 0x3cdb_9359_8a5c_a528, + ]), + ], + [ + FF::from_raw([ + 0x2861_ce16_f219_d5a9, + 0x4ad0_4470_45a7_c5aa, + 0x2072_4b92_7a0c_a81c, + 0x0e59_e6f3_32d7_ed37, + ]), + FF::from_raw([ + 0x43b0_a3fc_ff20_36bd, + 0x172c_c07b_9d33_fbf9, + 0x3d73_6946_7222_697a, + 0x1b06_4342_d51a_4275, + ]), + FF::from_raw([ + 0x3eb3_1022_8a0e_5f6c, + 0x78fa_9fb9_1712_21b7, + 0x2f36_3c55_b288_2e0b, + 0x30b8_2a99_8cbd_8e8a, + ]), + ], + [ + FF::from_raw([ + 0xe46f_6d42_9874_0107, + 0x8ad7_1ea7_15be_0573, + 0x63df_7a76_e858_a4aa, + 0x23e4_ab37_183a_cba4, + ]), + FF::from_raw([ + 0xfca9_95e2_b599_14a1, + 0xacfe_1464_0de0_44f2, + 0x5d33_094e_0bed_a75b, + 0x2795_d5c5_fa42_8022, + ]), + FF::from_raw([ + 0xc26d_909d_ee8b_53c0, + 0xa668_7c3d_f16c_8fe4, + 0xd765_f26d_d03f_4c45, + 0x3001_ca40_1e89_601c, + ]), + ], + [ + FF::from_raw([ + 0xe7fe_a6bd_f347_1380, + 0xe84b_5beb_ae4e_501d, + 0xf7bf_86e8_9280_827f, + 0x0072_e45c_c676_b08e, + ]), + FF::from_raw([ + 0xd0c5_4dde_b26b_86c0, + 0xb648_29e2_d40e_41bd, + 0xe2ab_e4c5_18ce_599e, + 0x13de_7054_8487_4bb5, + ]), + FF::from_raw([ + 0x3891_5b43_2a99_59a5, + 0x82bb_18e5_af1b_05bb, + 0x3159_50f1_211d_efe8, + 0x0408_a9fc_f9d6_1abf, + ]), + ], + [ + FF::from_raw([ + 0x3407_0cbe_e268_86a0, + 0xae4d_23b0_b41b_e9a8, + 0xbb4e_4a14_00cc_d2c4, + 0x2780_b9e7_5b55_676e, + ]), + FF::from_raw([ + 0x9405_5920_98b4_056f, + 0xdc4d_8fbe_fe24_405a, + 0xf803_33ec_8563_4ac9, + 0x3a57_0d4d_7c4e_7ac3, + ]), + FF::from_raw([ + 0x78d2_b247_8995_20b4, + 0xe2cc_1507_bebd_cc62, + 0xf347_c247_fcf0_9294, + 0x0c13_cca7_cb1f_9d2c, + ]), + ], + [ + FF::from_raw([ + 0x2e8c_88f7_7074_70e0, + 0x0b50_bb2e_b82d_f74d, + 0xd261_4a19_7c6b_794b, + 0x14f5_9baa_03cd_0ca4, + ]), + FF::from_raw([ + 0xbe52_476e_0a16_f3be, + 0xa51d_54ed_e661_67f5, + 0x6f54_6e17_04c3_9c60, + 0x307d_efee_925d_fb43, + ]), + FF::from_raw([ + 0x380b_67d8_0473_dce3, + 0x6611_0683_6adf_e5e7, + 0x7a07_e767_4b5a_2621, + 0x1960_cd51_1a91_e060, + ]), + ], + [ + FF::from_raw([ + 0x15aa_f1f7_7125_89dd, + 0xb8ee_335d_8828_4cbe, + 0xca2a_d0fb_5667_2500, + 0x2301_ef9c_63ea_84c5, + ]), + FF::from_raw([ + 0x5e68_478c_4d60_27a9, + 0xc861_82d1_b424_6b58, + 0xd10f_4cd5_2be9_7f6b, + 0x029a_5a47_da79_a488, + ]), + FF::from_raw([ + 0x2cc4_f962_eaae_2260, + 0xf97f_e46b_6a92_5428, + 0x2360_d17d_890e_55cb, + 0x32d7_b16a_7f11_cc96, + ]), + ], + [ + FF::from_raw([ + 0xc0ca_b915_d536_3d9f, + 0xa5f2_404c_d7b3_5eb0, + 0x18e8_57a9_8d49_8cf7, + 0x2670_3e48_c03b_81ca, + ]), + FF::from_raw([ + 0xf691_123a_e112_b928, + 0xf443_88bd_6b89_221e, + 0x88ac_8d25_a246_03f1, + 0x0486_82a3_5b32_65bc, + ]), + FF::from_raw([ + 0x3ab7_defc_b8d8_03e2, + 0x91d6_e171_5164_775e, + 0xd72c_ddc6_cf06_b507, + 0x06b1_3904_41fa_7030, + ]), + ], + [ + FF::from_raw([ + 0xbcd7_9541_4a6e_2e86, + 0x43b3_60f6_386a_86d7, + 0x1689_426d_ce05_fcd8, + 0x31aa_0eeb_868c_626d, + ]), + FF::from_raw([ + 0xed77_f5d5_76b9_9cc3, + 0x90ef_d8f4_1b20_78b2, + 0x057a_bad3_764c_104b, + 0x2394_64f7_5bf7_b6af, + ]), + FF::from_raw([ + 0xb2cb_4873_07c1_cecf, + 0xa5cc_47c5_9654_b2a7, + 0xa45e_19ed_813a_54ab, + 0x0a64_d4c0_4fd4_26bd, + ]), + ], + [ + FF::from_raw([ + 0x1f73_1532_2f65_8735, + 0x777c_7a92_1a06_2e9d, + 0x576a_4ad2_5986_0fb1, + 0x21fb_bdbb_7367_0734, + ]), + FF::from_raw([ + 0x6743_2400_3fc5_2146, + 0x5b86_d294_63d3_1564, + 0xd937_1ca2_eb95_acf3, + 0x31b8_6f3c_f017_05d4, + ]), + FF::from_raw([ + 0x7045_f48a_a4eb_4f6f, + 0x1354_1d65_157e_e1ce, + 0x05ef_1736_d090_56f6, + 0x2bfd_e533_5437_7c91, + ]), + ], + [ + FF::from_raw([ + 0x5a13_a58d_2001_1e2f, + 0xf4d5_239c_11d0_eafa, + 0xd558_f36e_65f8_eca7, + 0x1233_ca93_6ec2_4671, + ]), + FF::from_raw([ + 0x6e70_af0a_7a92_4b3a, + 0x8780_58d0_234a_576f, + 0xc437_846d_8e0b_2b30, + 0x27d4_52a4_3ac7_dea2, + ]), + FF::from_raw([ + 0xa025_76b9_4392_f980, + 0x6a30_641a_1c3d_87b2, + 0xe816_ea8d_a493_e0fa, + 0x2699_dba8_2184_e413, + ]), + ], + [ + FF::from_raw([ + 0x608c_6f7a_61b5_6e55, + 0xf185_8466_4f8c_ab49, + 0xc398_8bae_e42e_4b10, + 0x36c7_22f0_efcc_8803, + ]), + FF::from_raw([ + 0x6e49_ac17_0dbb_7fcd, + 0x85c3_8899_a7b5_a833, + 0x08b0_f2ec_89cc_aa37, + 0x02b3_ff48_861e_339b, + ]), + FF::from_raw([ + 0xa8c5_ae03_ad98_e405, + 0x6fc3_ff4c_49eb_59ad, + 0x6016_2f44_27bc_657b, + 0x0b70_d061_d58d_8a7f, + ]), + ], + [ + FF::from_raw([ + 0x2e06_cc4a_f33b_0a06, + 0xad3d_e8be_46ed_9693, + 0xf875_3ade_b9d7_cee2, + 0x3fc2_a13f_127f_96a4, + ]), + FF::from_raw([ + 0xc120_80ac_117e_e15f, + 0x00cb_3d62_1e17_1d80, + 0x1bd6_3434_ac8c_419f, + 0x0c41_a6e4_8dd2_3a51, + ]), + FF::from_raw([ + 0x9685_213e_9692_f5e1, + 0x72aa_ad7e_4e75_339d, + 0xed44_7653_7169_084e, + 0x2de8_072a_6bd8_6884, + ]), + ], + [ + FF::from_raw([ + 0x0ad0_1184_567b_027c, + 0xb81c_f735_cc9c_39c0, + 0x9d34_96a3_d9fe_05ec, + 0x0355_7a8f_7b38_a17f, + ]), + FF::from_raw([ + 0x45bc_b5ac_0082_6abc, + 0x060f_4336_3d81_8e54, + 0xee97_6d34_282f_1a37, + 0x0b5f_5955_2f49_8735, + ]), + FF::from_raw([ + 0x2f29_09e1_7e22_b0df, + 0xf5d6_46e5_7507_e548, + 0xfedb_b185_70dc_7300, + 0x0e29_23a5_fee7_b878, + ]), + ], + [ + FF::from_raw([ + 0xf71e_ed73_f15b_3326, + 0xcf1c_b37c_3b03_2af6, + 0xc787_be97_020a_7fdd, + 0x1d78_5005_a7a0_0592, + ]), + FF::from_raw([ + 0x0acf_bfb2_23f8_f00d, + 0xa590_b88a_3b06_0294, + 0x0ba5_fedc_b8f2_5bd2, + 0x1ad7_72c2_73d9_c6df, + ]), + FF::from_raw([ + 0xc1ce_13d6_0f2f_5031, + 0x8105_10eb_61f0_672d, + 0xa78f_3275_c278_234b, + 0x027b_d647_85fc_bd2a, + ]), + ], + [ + FF::from_raw([ + 0x8337_f5e0_7923_a853, + 0xe224_3134_6945_7b8e, + 0xce6f_8ffe_a103_1b6d, + 0x2080_0f44_1b4a_0526, + ]), + FF::from_raw([ + 0xa33d_7bed_89a4_408a, + 0x36cd_c8ee_d662_ad37, + 0x6eea_2cd4_9f43_12b4, + 0x3d5a_d61d_7b65_f938, + ]), + FF::from_raw([ + 0x3bbb_ae94_cc19_5284, + 0x1df9_6cc0_3ea4_b26d, + 0x02c5_f91b_e4dd_8e3d, + 0x1333_8bc3_51fc_46dd, + ]), + ], + [ + FF::from_raw([ + 0xc527_1c29_7852_819e, + 0x646c_49f9_b46c_bf19, + 0xb87d_b1e2_af3e_a923, + 0x25e5_2be5_07c9_2760, + ]), + FF::from_raw([ + 0x5c38_0ab7_01b5_2ea9, + 0xa34c_83a3_485c_6b2d, + 0x7109_6d8b_1b98_3c98, + 0x1c49_2d64_c157_aaa4, + ]), + FF::from_raw([ + 0xa20c_0b3d_a0da_4ca3, + 0xd434_87bc_288d_f682, + 0xf4e6_c5e7_a573_f592, + 0x0c5b_8015_7999_2718, + ]), + ], + [ + FF::from_raw([ + 0x7ea3_3c93_e408_33cf, + 0x584e_9e62_a7f9_554e, + 0x6869_5c0c_d7cb_f43d, + 0x1090_b1b4_d2be_be7a, + ]), + FF::from_raw([ + 0xe383_e1ec_3baa_8d69, + 0x1b21_8e35_ecf2_328e, + 0x68f5_ce5c_bed1_9cad, + 0x33e3_8018_a801_387a, + ]), + FF::from_raw([ + 0xb76b_0b3d_787e_e953, + 0x5f4a_02d2_8729_e3ae, + 0xeef8_d83d_0e87_6bac, + 0x1654_af18_772b_2da5, + ]), + ], + [ + FF::from_raw([ + 0xef7c_e6a0_1326_5477, + 0xbb08_9387_0367_ec6c, + 0x4474_2de8_8c5a_b0d5, + 0x1678_be3c_c9c6_7993, + ]), + FF::from_raw([ + 0xaf5d_4789_3348_f766, + 0xdaf1_8183_55b1_3b4f, + 0x7ff9_c6be_546e_928a, + 0x3780_bd1e_01f3_4c22, + ]), + FF::from_raw([ + 0xa123_8032_0d7c_c1de, + 0x5d11_e69a_a6c0_b98c, + 0x0786_018e_7cb7_7267, + 0x1e83_d631_5c9f_125b, + ]), + ], + [ + FF::from_raw([ + 0x1799_603e_855c_e731, + 0xc486_894d_76e0_c33b, + 0x160b_4155_2f29_31c8, + 0x354a_fd0a_2f9d_0b26, + ]), + FF::from_raw([ + 0x8b99_7ee0_6be1_bff3, + 0x60b0_0dbe_1fac_ed07, + 0x2d8a_ffa6_2905_c5a5, + 0x00cd_6d29_f166_eadc, + ]), + FF::from_raw([ + 0x08d0_6419_1708_2f2c, + 0xc60d_0197_3f18_3057, + 0xdbe0_e3d7_cdbc_66ef, + 0x1d62_1935_2768_e3ae, + ]), + ], + [ + FF::from_raw([ + 0xfa08_dd98_0638_7577, + 0xafe3_ca1d_b8d4_f529, + 0xe48d_2370_d7d1_a142, + 0x1463_36e2_5db5_181d, + ]), + FF::from_raw([ + 0xa901_d3ce_84de_0ad4, + 0x022e_54b4_9c13_d907, + 0x997a_2116_3e2e_43df, + 0x0005_d8e0_85fd_72ee, + ]), + FF::from_raw([ + 0x1c36_f313_4196_4484, + 0x6f8e_bc1d_2296_021a, + 0x0dd5_e61c_8a4e_8642, + 0x364e_97c7_a389_3227, + ]), + ], + [ + FF::from_raw([ + 0xd7a0_0c03_d2e0_baaa, + 0xfa97_ec80_ad30_7a52, + 0x561c_6fff_1534_6878, + 0x0118_9910_671b_c16b, + ]), + FF::from_raw([ + 0x63fd_8ac5_7a95_ca8c, + 0x4c0f_7e00_1df4_90aa, + 0x5229_dfaa_0123_1a45, + 0x162a_7c80_f4d2_d12e, + ]), + FF::from_raw([ + 0x32e6_9efb_22f4_0b96, + 0xcaff_31b4_fda3_2124, + 0x2604_e4af_b09f_8603, + 0x2a0d_6c09_5766_66bb, + ]), + ], + [ + FF::from_raw([ + 0xc0a0_180f_8cbf_c0d2, + 0xf444_d10d_63a7_4e2c, + 0xe16a_4d60_3d5a_808e, + 0x0978_e5c5_1e1e_5649, + ]), + FF::from_raw([ + 0x03f4_460e_bc35_1b6e, + 0x0508_7d90_3bda_cfd1, + 0xebe1_9bbd_ce25_1011, + 0x1bdc_ee3a_aca9_cd25, + ]), + FF::from_raw([ + 0xf619_64bf_3ade_7670, + 0x0c94_7321_e007_5e3f, + 0xe494_7914_0b19_44fd, + 0x1862_cccb_70b5_b885, + ]), + ], + [ + FF::from_raw([ + 0xc326_7da6_e94a_dc50, + 0x39ee_99c1_cc6e_5dda, + 0xbc26_cc88_3a19_87e1, + 0x1f3e_91d8_63c1_6922, + ]), + FF::from_raw([ + 0x0f85_b4ac_2c36_7406, + 0xfa66_1465_c656_ad99, + 0xef5c_08f8_478f_663a, + 0x1af4_7a48_a601_6a49, + ]), + FF::from_raw([ + 0x0eab_cd87_e7d0_1b15, + 0x1c36_98b0_a2e3_da10, + 0x009d_5733_8c69_3505, + 0x3c8e_e901_956e_3d3f, + ]), + ], + [ + FF::from_raw([ + 0x8b94_7721_8967_3476, + 0xe10c_e2b7_069f_4dbd, + 0x68d0_b024_f591_b520, + 0x1660_a8cd_e7fe_c553, + ]), + FF::from_raw([ + 0x9d8d_0f67_fdaa_79d5, + 0x3963_c2c1_f558_6e2f, + 0x1303_9363_34dd_1132, + 0x0f6d_9919_29d5_e4e7, + ]), + FF::from_raw([ + 0x7a43_3091_e1ce_2d3a, + 0x4e7f_da77_0712_f343, + 0xcc62_5eaa_ab52_b4dc, + 0x02b9_cea1_921c_d9f6, + ]), + ], + [ + FF::from_raw([ + 0x3797_b2d8_3760_43b3, + 0xd8ca_f468_976f_0472, + 0x214f_7c67_84ac_b565, + 0x14a3_23b9_9b90_0331, + ]), + FF::from_raw([ + 0x347f_ef2c_00f0_953a, + 0x718b_7fbc_7788_af78, + 0xec01_ea79_642d_5760, + 0x1904_76b5_80cb_9277, + ]), + FF::from_raw([ + 0xff4e_7e6f_b268_dfd7, + 0x9660_902b_6008_7651, + 0xa424_63d3_0b44_2b6f, + 0x090a_3a9d_869d_2eef, + ]), + ], + [ + FF::from_raw([ + 0xf983_387e_a045_6203, + 0xe365_0013_04f9_a11e, + 0x0dbe_8fd2_270a_6795, + 0x3877_a955_8636_7567, + ]), + FF::from_raw([ + 0x39c0_af0f_e01f_4a06, + 0x6011_8c53_a218_1352, + 0x5df3_9a2c_c63d_dc0a, + 0x2d89_4691_240f_e953, + ]), + FF::from_raw([ + 0x1aca_9eaf_9bba_9850, + 0x5914_e855_eeb4_4aa1, + 0x7ef7_1780_2016_6189, + 0x21b9_c182_92bd_bc59, + ]), + ], + [ + FF::from_raw([ + 0x33f5_09a7_4ad9_d39b, + 0x272e_1cc6_c36a_2968, + 0x505a_05f2_a6ae_834c, + 0x2fe7_6be7_cff7_23e2, + ]), + FF::from_raw([ + 0x0df9_fa97_277f_a8b4, + 0xd15b_ff84_0dda_e8a5, + 0x9299_81d7_cfce_253b, + 0x187a_a448_f391_e3ca, + ]), + FF::from_raw([ + 0xf0c6_6af5_ffc7_3736, + 0x663c_cf7b_2ffe_4b5e, + 0x007a_b3aa_3617_f422, + 0x0b70_83ad_7517_07bf, + ]), + ], + [ + FF::from_raw([ + 0x2f9b_20f1_fbd4_9791, + 0x1975_b962_f6cb_8e0b, + 0x3bc4_ca99_02c5_2acb, + 0x030d_dbb4_7049_3f16, + ]), + FF::from_raw([ + 0x3a1c_62ca_8fbf_2525, + 0x8fb8_ab9d_60ea_17b2, + 0x950b_0ab1_8d35_46df, + 0x3130_fbaf_fb5a_a82a, + ]), + FF::from_raw([ + 0x43a8_7618_0dc3_82e0, + 0x15ce_2ead_2fcd_051e, + 0x4f74_d74b_ac2e_e457, + 0x337f_5447_07c4_30f0, + ]), + ], + [ + FF::from_raw([ + 0x26de_98a8_736d_1d11, + 0x7d8e_471a_9fb9_5fef, + 0xac9d_91b0_930d_ac75, + 0x3499_7991_9015_394f, + ]), + FF::from_raw([ + 0xccfc_b618_31d5_c775, + 0x3bf9_3da6_fff3_1d95, + 0x2305_cd7a_921e_c5f1, + 0x027c_c4ef_e3fb_35dd, + ]), + FF::from_raw([ + 0xc3fa_2629_635d_27de, + 0x67f1_c6b7_3147_64af, + 0x61b7_1a36_9868_2ad2, + 0x037f_9f23_6595_4c5b, + ]), + ], + [ + FF::from_raw([ + 0x77c5_b024_8483_71ae, + 0x6041_4abe_362d_01c9, + 0x10f1_cc6d_f8b4_bcd7, + 0x1f69_7cac_4d07_feb7, + ]), + FF::from_raw([ + 0x786a_dd24_4aa0_ef29, + 0x3145_c478_0631_09d6, + 0x26e6_c851_fbd5_72a6, + 0x267a_750f_e5d7_cfbc, + ]), + FF::from_raw([ + 0x180e_2b4d_3e75_6f65, + 0xaf28_5fa8_2ce4_fae5, + 0x678c_9996_d9a4_72c8, + 0x0c91_feab_4a43_193a, + ]), + ], + [ + FF::from_raw([ + 0x79c4_7c57_3ac4_10f7, + 0x7e3b_83af_4a4b_a3ba, + 0x2186_c303_8ea0_5e69, + 0x1745_569a_0a3e_3014, + ]), + FF::from_raw([ + 0x1e03_8852_2696_191f, + 0xfdff_66c6_f3b5_ffe1, + 0xeca5_1207_78a5_6711, + 0x2986_3d54_6e7e_7c0d, + ]), + FF::from_raw([ + 0x2f22_5e63_66bf_e390, + 0xa79a_03df_8339_94c6, + 0xbf06_bae4_9ef8_53f6, + 0x1148_d6ab_2bd0_0192, + ]), + ], + [ + FF::from_raw([ + 0xf4f6_331a_8b26_5d15, + 0xf745_f45d_350d_41d4, + 0xe18b_1499_060d_a366, + 0x02e0_e121_b0f3_dfef, + ]), + FF::from_raw([ + 0x078a_e6aa_1510_54b7, + 0x6904_0173_6d44_a653, + 0xb89e_f73a_40a2_b274, + 0x0d0a_a46e_76a6_a278, + ]), + FF::from_raw([ + 0x9a4d_532c_7b6e_0958, + 0x392d_de71_0f1f_06db, + 0xeee5_45f3_fa6d_3d08, + 0x1394_3675_b04a_a986, + ]), + ], + [ + FF::from_raw([ + 0x961f_c818_dcbb_66b5, + 0xc9f2_b325_7530_dafe, + 0xd97a_11d6_3088_f5d9, + 0x2901_ec61_942d_34aa, + ]), + FF::from_raw([ + 0xfdf5_44b9_63d1_fdc7, + 0x22ff_a2a2_af9f_a3e3, + 0xf431_d544_34a3_e0cf, + 0x2020_4a21_05d2_2e7e, + ]), + FF::from_raw([ + 0x1211_b9e2_190d_6852, + 0xa004_abe8_e015_28c4, + 0x5c1e_3e9e_27a5_71c3, + 0x3a8a_6282_9512_1d5c, + ]), + ], +]; diff --git a/zkmemory/src/nova/testcases.rs b/zkmemory/src/nova/testcases.rs index 38c47aa..e0049db 100644 --- a/zkmemory/src/nova/testcases.rs +++ b/zkmemory/src/nova/testcases.rs @@ -1,6 +1,7 @@ #[cfg(test)] mod test { - + extern crate alloc; + use alloc::vec::Vec; use ff::Field; use nova_snark::{ provider::{Bn256EngineKZG, GrumpkinEngine}, @@ -8,13 +9,42 @@ mod test { PublicParams, RecursiveSNARK, }; - use crate::nova::memory_consistency_circuit::NovaMemoryConsistencyCircuit; + use crate::{ + nova::{ + memory_consistency_circuit::NovaMemoryConsistencyCircuit, + poseidon_parameters::OrchardNullifierScalar, + }, + poseidon::poseidon_hash::{ConstantLength, Hash}, + }; type E1 = Bn256EngineKZG; type E2 = GrumpkinEngine; type EE1 = nova_snark::provider::hyperkzg::EvaluationEngine; type EE2 = nova_snark::provider::ipa_pc::EvaluationEngine; type S1 = nova_snark::spartan::snark::RelaxedR1CSSNARK; // non-preprocessing SNARK type S2 = nova_snark::spartan::snark::RelaxedR1CSSNARK; // non-preprocessing SNARK + type FF = ::Scalar; + + fn merkle_tree_commit(memory: Vec) -> FF { + let mut root: Vec = memory; + + let hash = Hash::, 3, 2>::init(); + let mut size = root.len(); + while size > 1 { + let mut root_size = size; + while root_size > 1 { + let left = root.pop().expect("unable to get left"); + let right = root.pop().expect("unable to get right"); + // TODO: replace "out" with a hash function + let out = hash.clone().hash([left, right]); + // End TODO + root.push(out); + root_size -= 2; + } + size = root.len(); + } + root[0] + } + #[test] // test correct memory consistency in one step fn test_memory_consistency_in_one_step() { @@ -22,22 +52,21 @@ mod test { let instruction = [1 as u64].to_vec(); let value = [1292001 as u64].to_vec(); // let num_steps = 10; - let circuit_primary = NovaMemoryConsistencyCircuit::<::GE>::new( - 4, - 1, - address, - instruction, - value, - ); + let circuit_primary = NovaMemoryConsistencyCircuit::< + ::GE, + OrchardNullifierScalar, + 3, + 2, + >::new(4, 1, address, instruction, value); let circuit_secondary = TrivialCircuit::<::Scalar>::default(); - type C1 = NovaMemoryConsistencyCircuit<::GE>; + type C1 = NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>; type C2 = TrivialCircuit<::Scalar>; let pp = PublicParams::< E1, E2, - NovaMemoryConsistencyCircuit<::GE>, + NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>, TrivialCircuit<::Scalar>, >::setup( &circuit_primary, @@ -56,7 +85,7 @@ mod test { ::Scalar::zero(), ::Scalar::zero(), ::Scalar::zero(), - ::Scalar::from(3 as u64), + merkle_tree_commit([::Scalar::zero(); 4].to_vec()), ], &[::Scalar::zero()], ) @@ -74,7 +103,7 @@ mod test { ::Scalar::zero(), ::Scalar::zero(), ::Scalar::zero(), - ::Scalar::from(3 as u64), + merkle_tree_commit([::Scalar::zero(); 4].to_vec()), ], &[::Scalar::ZERO], ); @@ -89,22 +118,21 @@ mod test { let instruction = [1 as u64, 0 as u64].to_vec(); let value = [1292001 as u64, 1292001 as u64].to_vec(); // let num_steps = 10; - let circuit_primary = NovaMemoryConsistencyCircuit::<::GE>::new( - 4, + let circuit_primary = NovaMemoryConsistencyCircuit::< + ::GE, + OrchardNullifierScalar, + 3, 2, - address, - instruction, - value, - ); + >::new(4, 2, address, instruction, value); let circuit_secondary = TrivialCircuit::<::Scalar>::default(); - type C1 = NovaMemoryConsistencyCircuit<::GE>; + type C1 = NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>; type C2 = TrivialCircuit<::Scalar>; let pp = PublicParams::< E1, E2, - NovaMemoryConsistencyCircuit<::GE>, + NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>, TrivialCircuit<::Scalar>, >::setup( &circuit_primary, @@ -123,7 +151,7 @@ mod test { ::Scalar::zero(), ::Scalar::zero(), ::Scalar::zero(), - ::Scalar::from(3 as u64), + merkle_tree_commit([::Scalar::zero(); 4].to_vec()), ], &[::Scalar::zero()], ) @@ -141,7 +169,7 @@ mod test { ::Scalar::zero(), ::Scalar::zero(), ::Scalar::zero(), - ::Scalar::from(3 as u64), + merkle_tree_commit([::Scalar::zero(); 4].to_vec()), ], &[::Scalar::ZERO], ); @@ -155,22 +183,21 @@ mod test { let instruction = [2 as u64].to_vec(); let value = [1292001 as u64].to_vec(); // let num_steps = 10; - let circuit_primary = NovaMemoryConsistencyCircuit::<::GE>::new( - 4, - 1, - address, - instruction, - value, - ); + let circuit_primary = NovaMemoryConsistencyCircuit::< + ::GE, + OrchardNullifierScalar, + 3, + 2, + >::new(4, 1, address, instruction, value); let circuit_secondary = TrivialCircuit::<::Scalar>::default(); - type C1 = NovaMemoryConsistencyCircuit<::GE>; + type C1 = NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>; type C2 = TrivialCircuit<::Scalar>; let pp = PublicParams::< E1, E2, - NovaMemoryConsistencyCircuit<::GE>, + NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>, TrivialCircuit<::Scalar>, >::setup( &circuit_primary, @@ -189,7 +216,7 @@ mod test { ::Scalar::zero(), ::Scalar::zero(), ::Scalar::zero(), - ::Scalar::from(3 as u64), + merkle_tree_commit([::Scalar::zero(); 4].to_vec()), ], &[::Scalar::zero()], ) @@ -207,7 +234,7 @@ mod test { ::Scalar::zero(), ::Scalar::zero(), ::Scalar::zero(), - ::Scalar::from(3 as u64), + merkle_tree_commit([::Scalar::zero(); 4].to_vec()), ], &[::Scalar::ZERO], ); @@ -221,22 +248,21 @@ mod test { let instruction = [0 as u64].to_vec(); let value = [1292001 as u64].to_vec(); // let num_steps = 10; - let circuit_primary = NovaMemoryConsistencyCircuit::<::GE>::new( - 4, - 1, - address, - instruction, - value, - ); + let circuit_primary = NovaMemoryConsistencyCircuit::< + ::GE, + OrchardNullifierScalar, + 3, + 2, + >::new(4, 1, address, instruction, value); let circuit_secondary = TrivialCircuit::<::Scalar>::default(); - type C1 = NovaMemoryConsistencyCircuit<::GE>; + type C1 = NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>; type C2 = TrivialCircuit<::Scalar>; let pp = PublicParams::< E1, E2, - NovaMemoryConsistencyCircuit<::GE>, + NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>, TrivialCircuit<::Scalar>, >::setup( &circuit_primary, @@ -255,7 +281,7 @@ mod test { ::Scalar::zero(), ::Scalar::zero(), ::Scalar::zero(), - ::Scalar::from(3 as u64), + merkle_tree_commit([::Scalar::zero(); 4].to_vec()), ], &[::Scalar::zero()], ) @@ -273,7 +299,7 @@ mod test { ::Scalar::zero(), ::Scalar::zero(), ::Scalar::zero(), - ::Scalar::from(3 as u64), + merkle_tree_commit([::Scalar::zero(); 4].to_vec()), ], &[::Scalar::ZERO], ); @@ -287,22 +313,21 @@ mod test { let instruction = [0 as u64].to_vec(); let value = [1292001 as u64].to_vec(); // let num_steps = 10; - let circuit_primary = NovaMemoryConsistencyCircuit::<::GE>::new( - 4, - 1, - address, - instruction, - value, - ); + let circuit_primary = NovaMemoryConsistencyCircuit::< + ::GE, + OrchardNullifierScalar, + 3, + 2, + >::new(4, 1, address, instruction, value); let circuit_secondary = TrivialCircuit::<::Scalar>::default(); - type C1 = NovaMemoryConsistencyCircuit<::GE>; + type C1 = NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>; type C2 = TrivialCircuit<::Scalar>; let pp = PublicParams::< E1, E2, - NovaMemoryConsistencyCircuit<::GE>, + NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>, TrivialCircuit<::Scalar>, >::setup( &circuit_primary, From c8ba62a0ba0aece7440f5775d25e03625cc313c5 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 12 Aug 2024 02:53:45 +0700 Subject: [PATCH 13/24] Fix all testcase errors --- .../src/nova/memory_consistency_circuit.rs | 58 +++++++++++--- zkmemory/src/nova/testcases.rs | 79 ++++++++++++++++++- 2 files changed, 124 insertions(+), 13 deletions(-) diff --git a/zkmemory/src/nova/memory_consistency_circuit.rs b/zkmemory/src/nova/memory_consistency_circuit.rs index a9d5b2d..3103b6c 100644 --- a/zkmemory/src/nova/memory_consistency_circuit.rs +++ b/zkmemory/src/nova/memory_consistency_circuit.rs @@ -95,12 +95,14 @@ impl< .expect("unable to get instruction_minus_one"); // Get memory[address] - let mut memory_address = zero.clone(); - for (i, item) in memory.iter().enumerate().take(self.memory_len) { - if G::Scalar::from(i as u64) == self.trace_record[j].address { - memory_address = item.clone(); - } - } + let memory_address = + AllocatedNum::alloc(cs.namespace(|| "get memory[address]"), || { + Ok(self + .clone() + .get_memory_address(memory.clone(), self.trace_record[j].address)) + }) + .expect("unable to get memory[address]"); + // create the Merkle commitment of the tree let commitment = AllocatedNum::alloc(cs.namespace(|| format!("merkle root {j}")), || { @@ -134,13 +136,18 @@ impl< // create the output, which includes the memory and the Merkle // tree commitment of the memory - z_out.clear(); + z_out = (0..self.memory_len).map(|_| zero.clone()).collect(); for (i, item) in memory.iter().enumerate().take(self.memory_len) { - if G::Scalar::from(i as u64) != self.trace_record[j].address { - z_out.push(item.clone()); - } else { - z_out.push(value.clone()); - } + let tmp = AllocatedNum::alloc(cs.namespace(|| "get new memory state"), || { + Ok(self.clone().get_new_memory_cell( + item.clone(), + value.clone(), + G::Scalar::from(i as u64), + self.trace_record[j].address, + )) + }) + .expect("unable to get new memory cells"); + z_out[i] = tmp; } // commitment to the new updated memory let new_commitment = AllocatedNum::alloc( @@ -211,4 +218,31 @@ impl< } root[0] } + + fn get_new_memory_cell( + self, + item: AllocatedNum, + value: AllocatedNum, + i: G::Scalar, + address: G::Scalar, + ) -> G::Scalar { + let item = item.get_value().expect("unable to get tmp1"); + let value = value.get_value().expect("unable to get value"); + let d = (i - address).is_zero().unwrap_u8(); + G::Scalar::from((1 - d) as u64) * item + G::Scalar::from(d as u64) * value + } + + fn get_memory_address( + self, + memory: Vec>, + address: G::Scalar, + ) -> G::Scalar { + let mut tmp = G::Scalar::ZERO; + let mut tmp2: u8; + for (i, item) in memory.iter().enumerate() { + tmp2 = (G::Scalar::from(i as u64) - address).is_zero().unwrap_u8(); + tmp += G::Scalar::from(tmp2 as u64) * item.get_value().unwrap(); + } + tmp + } } diff --git a/zkmemory/src/nova/testcases.rs b/zkmemory/src/nova/testcases.rs index e0049db..d92d8e0 100644 --- a/zkmemory/src/nova/testcases.rs +++ b/zkmemory/src/nova/testcases.rs @@ -1,6 +1,7 @@ #[cfg(test)] mod test { extern crate alloc; + use alloc::vec; use alloc::vec::Vec; use ff::Field; use nova_snark::{ @@ -8,6 +9,8 @@ mod test { traits::{circuit::TrivialCircuit, snark::RelaxedR1CSSNARKTrait, Engine}, PublicParams, RecursiveSNARK, }; + extern crate std; + use std::println; use crate::{ nova::{ @@ -47,6 +50,7 @@ mod test { #[test] // test correct memory consistency in one step + // for simolicity we experiment with a memory of size 4 fn test_memory_consistency_in_one_step() { let address = [0 as u64].to_vec(); let instruction = [1 as u64].to_vec(); @@ -110,7 +114,6 @@ mod test { assert_eq!(res.is_ok(), true); } - // for simolicity we experiment with a memory of size 4 // test memory consistency in two steps #[test] fn test_memory_consistency_in_two_steps() { @@ -370,4 +373,78 @@ mod test { ); assert_ne!(res.is_ok(), true); } + + #[test] + // test correct memory consistency in four step + fn test_memory_consistency_in_four_step() { + let address = [0 as u64, 1 as u64, 2 as u64, 3 as u64].to_vec(); + let instruction = [1 as u64, 0 as u64, 1 as u64, 0 as u64].to_vec(); + let value = [1292001 as u64, 0 as u64, 1292001 as u64, 0 as u64].to_vec(); + let mut circuit_primary = vec![]; + for i in 0..2 { + circuit_primary.push(NovaMemoryConsistencyCircuit::< + ::GE, + OrchardNullifierScalar, + 3, + 2, + >::new( + 4, + 2, + (2 * i..2 * i + 2).map(|i| address[i]).collect(), + (2 * i..2 * i + 2).map(|i| instruction[i]).collect(), + (2 * i..2 * i + 2).map(|i| value[i]).collect(), + )); + } + + let circuit_secondary = TrivialCircuit::default(); + let pp = PublicParams::< + E1, + E2, + NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>, + TrivialCircuit<::Scalar>, + >::setup( + &circuit_primary[0], + &circuit_secondary, + &*S1::ck_floor(), + &*S2::ck_floor(), + ) + .expect("unable to setup"); + + type C1 = NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>; + type C2 = TrivialCircuit<::Scalar>; + + let mut recursive_snark: RecursiveSNARK = + RecursiveSNARK::::new( + &pp, + &circuit_primary[0], + &circuit_secondary, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + merkle_tree_commit([::Scalar::zero(); 4].to_vec()), + ], + &[::Scalar::zero()], + ) + .expect("unable to prove"); + + for circuits in circuit_primary { + let res = recursive_snark.prove_step(&pp, &circuits, &circuit_secondary); + assert!(res.is_ok()); + } + let res = recursive_snark.verify( + &pp, + 2, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + merkle_tree_commit([::Scalar::zero(); 4].to_vec()), + ], + &[::Scalar::zero()], + ); + println!("{:?}", res); + } } From e9a0f2715faf31c50e07a96f425060aac6f5d2b2 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 12 Aug 2024 09:41:11 +0700 Subject: [PATCH 14/24] Fix code to increase function coverage --- node/src/error.rs | 2 +- .../src/nova/memory_consistency_circuit.rs | 29 +++++-------------- zkmemory/src/nova/testcases.rs | 7 ++--- 3 files changed, 11 insertions(+), 27 deletions(-) diff --git a/node/src/error.rs b/node/src/error.rs index 1876d99..04124db 100644 --- a/node/src/error.rs +++ b/node/src/error.rs @@ -22,7 +22,7 @@ impl Error { } } -#[cfg(feature = "std")] +//#[cfg(feature = "std")] impl std::error::Error for Error {} impl core::fmt::Display for Error { diff --git a/zkmemory/src/nova/memory_consistency_circuit.rs b/zkmemory/src/nova/memory_consistency_circuit.rs index 3103b6c..dd57f84 100644 --- a/zkmemory/src/nova/memory_consistency_circuit.rs +++ b/zkmemory/src/nova/memory_consistency_circuit.rs @@ -1,3 +1,5 @@ +//! Circuit for memory consistency check using [Nova](https://github.com/microsoft/Nova) +//! extern crate alloc; use core::marker::PhantomData; @@ -6,7 +8,6 @@ use alloc::vec; use alloc::vec::Vec; use bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError}; use ff::Field; -/// Reference to be added later. use nova_snark::traits::{circuit::StepCircuit, Group}; use crate::poseidon::poseidon_hash::ConstantLength; @@ -58,14 +59,6 @@ impl< // meaning that if instruction=0 then the value of trace_record must be equal to // z_i[address]. Also we need the merkle root in z_i - // The ZERO variable - let zero = AllocatedNum::alloc(cs.namespace(|| "zero"), || Ok(G::Scalar::ZERO)) - .expect("unable to get ZERO value"); - - // The ONE variable - let one = AllocatedNum::alloc(cs.namespace(|| "one"), || Ok(G::Scalar::ONE)) - .expect("unable to get ONE value"); - let mut z_out = z_in.to_vec(); // Get the current state of the memory @@ -88,12 +81,6 @@ impl< }) .expect("unable to get instruction"); - let instruction_minus_one = AllocatedNum::alloc( - cs.namespace(|| format!("instruction {j} minus one")), - || Ok(self.trace_record[j].instruction - G::Scalar::ONE), - ) - .expect("unable to get instruction_minus_one"); - // Get memory[address] let memory_address = AllocatedNum::alloc(cs.namespace(|| "get memory[address]"), || { @@ -114,29 +101,29 @@ impl< cs.enforce( || "commitment to the memory must be valid", |lc| lc + commitment.get_variable(), - |lc| lc + one.get_variable(), + |lc| lc + CS::one(), |lc| lc + z_out[self.memory_len].get_variable(), ); // if instruction = 0 then memory[address]=value cs.enforce( || "if instruction=0 then memory[address] = value", - |lc| lc + instruction_minus_one.get_variable(), + |lc| lc + instruction.get_variable(), + |lc| lc + memory_address.get_variable() - value.get_variable(), |lc| lc + memory_address.get_variable() - value.get_variable(), - |lc| lc + zero.get_variable(), ); // instruction must be read or write cs.enforce( || "operation is read or write", |lc| lc + instruction.get_variable(), - |lc| lc + instruction_minus_one.get_variable(), - |lc| lc + zero.get_variable(), + |lc| lc + instruction.get_variable(), + |lc| lc + instruction.get_variable(), ); // create the output, which includes the memory and the Merkle // tree commitment of the memory - z_out = (0..self.memory_len).map(|_| zero.clone()).collect(); + z_out = (0..self.memory_len).map(|i| memory[i].clone()).collect(); for (i, item) in memory.iter().enumerate().take(self.memory_len) { let tmp = AllocatedNum::alloc(cs.namespace(|| "get new memory state"), || { Ok(self.clone().get_new_memory_cell( diff --git a/zkmemory/src/nova/testcases.rs b/zkmemory/src/nova/testcases.rs index d92d8e0..68aeb4c 100644 --- a/zkmemory/src/nova/testcases.rs +++ b/zkmemory/src/nova/testcases.rs @@ -9,8 +9,6 @@ mod test { traits::{circuit::TrivialCircuit, snark::RelaxedR1CSSNARKTrait, Engine}, PublicParams, RecursiveSNARK, }; - extern crate std; - use std::println; use crate::{ nova::{ @@ -430,8 +428,7 @@ mod test { .expect("unable to prove"); for circuits in circuit_primary { - let res = recursive_snark.prove_step(&pp, &circuits, &circuit_secondary); - assert!(res.is_ok()); + let _ = recursive_snark.prove_step(&pp, &circuits, &circuit_secondary); } let res = recursive_snark.verify( &pp, @@ -445,6 +442,6 @@ mod test { ], &[::Scalar::zero()], ); - println!("{:?}", res); + assert_eq!(res.is_ok(), true); } } From 48a30aa12660948cba4e72e773b2921edf13b310 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 12 Aug 2024 10:07:04 +0700 Subject: [PATCH 15/24] Change unwrap() to expect() --- zkmemory/src/nova/memory_consistency_circuit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zkmemory/src/nova/memory_consistency_circuit.rs b/zkmemory/src/nova/memory_consistency_circuit.rs index dd57f84..4aa8cbd 100644 --- a/zkmemory/src/nova/memory_consistency_circuit.rs +++ b/zkmemory/src/nova/memory_consistency_circuit.rs @@ -228,7 +228,7 @@ impl< let mut tmp2: u8; for (i, item) in memory.iter().enumerate() { tmp2 = (G::Scalar::from(i as u64) - address).is_zero().unwrap_u8(); - tmp += G::Scalar::from(tmp2 as u64) * item.get_value().unwrap(); + tmp += G::Scalar::from(tmp2 as u64) * item.get_value().expect("unable to get result"); } tmp } From 55186c192489d0fa0ab2f0ec64e15a448873c95d Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 12 Aug 2024 10:16:39 +0700 Subject: [PATCH 16/24] Add one more testcase --- zkmemory/src/nova/testcases.rs | 65 ++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/zkmemory/src/nova/testcases.rs b/zkmemory/src/nova/testcases.rs index 68aeb4c..4e41362 100644 --- a/zkmemory/src/nova/testcases.rs +++ b/zkmemory/src/nova/testcases.rs @@ -307,6 +307,71 @@ mod test { assert_ne!(res.is_ok(), true); } + // test memory consistency in two steps + #[test] + fn test_invalid_read_part_two() { + let address = [0 as u64, 0 as u64].to_vec(); + let instruction = [1 as u64, 0 as u64].to_vec(); + let value = [1292001 as u64, 0 as u64].to_vec(); + // let num_steps = 10; + let circuit_primary = NovaMemoryConsistencyCircuit::< + ::GE, + OrchardNullifierScalar, + 3, + 2, + >::new(4, 2, address, instruction, value); + let circuit_secondary = TrivialCircuit::<::Scalar>::default(); + + type C1 = NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>; + type C2 = TrivialCircuit<::Scalar>; + + let pp = PublicParams::< + E1, + E2, + NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>, + TrivialCircuit<::Scalar>, + >::setup( + &circuit_primary, + &circuit_secondary, + &*S1::ck_floor(), + &*S2::ck_floor(), + ) + .expect("unable to setup"); + + let mut recursive_snark = RecursiveSNARK::::new( + &pp, + &circuit_primary, + &circuit_secondary, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + merkle_tree_commit([::Scalar::zero(); 4].to_vec()), + ], + &[::Scalar::zero()], + ) + .expect("unable to prove"); + + let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); + // assert!(res.is_ok()); + // println!("{:?}", res); + + let res = recursive_snark.verify( + &pp, + 1, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + merkle_tree_commit([::Scalar::zero(); 4].to_vec()), + ], + &[::Scalar::ZERO], + ); + assert_ne!(res.is_ok(), true); + } + #[test] // test invalid commitment fn test_invalid_commitment() { From eda5abcc0496b646b3af565c60c4b47b240acf2d Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:14:18 +0700 Subject: [PATCH 17/24] Change rust version to 1.79.0 and add testcases in machine.rs --- rust-toolchain | 2 +- zkmemory/src/base.rs | 1 - zkmemory/src/lib.rs | 4 +-- zkmemory/src/machine.rs | 29 +++++++++++++++++ .../src/nova/memory_consistency_circuit.rs | 16 ++++++---- zkmemory/src/nova/testcases.rs | 32 +++++++------------ 6 files changed, 52 insertions(+), 32 deletions(-) diff --git a/rust-toolchain b/rust-toolchain index 97e9852..b3a8c61 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.80.1 +1.79.0 diff --git a/zkmemory/src/base.rs b/zkmemory/src/base.rs index 04cbb36..30a6372 100644 --- a/zkmemory/src/base.rs +++ b/zkmemory/src/base.rs @@ -1,6 +1,5 @@ use core::fmt::{Debug, Display}; use core::ops::{Add, Div, Mul, Rem, Sub}; -use core::usize; use ethnum::U256; /// Base trait for memory address and value diff --git a/zkmemory/src/lib.rs b/zkmemory/src/lib.rs index dbca760..87eef06 100644 --- a/zkmemory/src/lib.rs +++ b/zkmemory/src/lib.rs @@ -1,7 +1,7 @@ //! This crate provides a simple RAM machine for use in the zkVM #![recursion_limit = "256"] #![cfg_attr(not(feature = "std"), no_std)] -/*#![deny( +#![deny( unused, warnings, future_incompatible, @@ -9,7 +9,7 @@ rust_2018_idioms, missing_docs, unused_imports -)]*/ +)] #![forbid(unsafe_code)] /// Base trait for generic type diff --git a/zkmemory/src/machine.rs b/zkmemory/src/machine.rs index b97e65f..85c4f90 100644 --- a/zkmemory/src/machine.rs +++ b/zkmemory/src/machine.rs @@ -1017,6 +1017,35 @@ mod tests { assert_eq!(sm.dummy_read(base + B256::from(192)), B256::from(170)); } + #[test] + fn test_stack_machine_part_two() { + let mut sm = StateMachine::::new(DefaultConfig::default_config()); + + assert_eq!(sm.stack_allocated.low(), B256::zero()); + let base = sm.base_address(); + let program = vec![ + Instruction::Push(B256::from(1000)), + Instruction::Push(B256::from(170)), + Instruction::Swap(sm.r0), + Instruction::Pop(), + Instruction::Swap(sm.r1), + Instruction::Pop(), + Instruction::Mov(sm.r3, sm.r0), + Instruction::Save(base + B256::from(128), sm.r0), + Instruction::Save(base + B256::from(160), sm.r1), + Instruction::Save(base + B256::from(192), sm.r3), + Instruction::Mov(sm.r3, sm.r4), + ]; + // Execute program1 + for instruction in program { + sm.exec(&instruction); + } + + assert_eq!(sm.dummy_read(base + B256::from(128)), B256::from(170)); + assert_eq!(sm.dummy_read(base + B256::from(160)), B256::from(1000)); + assert_eq!(sm.dummy_read(base + B256::from(192)), B256::from(170)); + } + #[test] #[should_panic] fn test_invalid_instruction() { diff --git a/zkmemory/src/nova/memory_consistency_circuit.rs b/zkmemory/src/nova/memory_consistency_circuit.rs index 4aa8cbd..fa27e0d 100644 --- a/zkmemory/src/nova/memory_consistency_circuit.rs +++ b/zkmemory/src/nova/memory_consistency_circuit.rs @@ -1,19 +1,18 @@ //! Circuit for memory consistency check using [Nova](https://github.com/microsoft/Nova) -//! +//! We referenced [Nova's example](https://github.com/microsoft/Nova/tree/main/examples) to create the memory consistency circuit +//! This circuit is only usable for memory of size which is a power of two. extern crate alloc; -use core::marker::PhantomData; - +use crate::poseidon::poseidon_hash::ConstantLength; +use crate::poseidon::poseidon_hash::Hash; +use crate::poseidon::poseidon_hash::Spec; use alloc::format; use alloc::vec; use alloc::vec::Vec; use bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError}; +use core::marker::PhantomData; use ff::Field; use nova_snark::traits::{circuit::StepCircuit, Group}; -use crate::poseidon::poseidon_hash::ConstantLength; -use crate::poseidon::poseidon_hash::Hash; -use crate::poseidon::poseidon_hash::Spec; - #[derive(Copy, Clone)] /// the trace record struct pub struct TraceRecord { @@ -47,6 +46,9 @@ impl< self.memory_len + 1 } + // based on the idea in page 6 of https://eprint.iacr.org/2022/1758.pdf, where + // z_in consists of the memory states and the commitment. In each step, + // the function update z_in into z_out based on the trace_record fn synthesize>( &self, cs: &mut CS, diff --git a/zkmemory/src/nova/testcases.rs b/zkmemory/src/nova/testcases.rs index 4e41362..dd0d7eb 100644 --- a/zkmemory/src/nova/testcases.rs +++ b/zkmemory/src/nova/testcases.rs @@ -1,6 +1,13 @@ #[cfg(test)] mod test { extern crate alloc; + use crate::{ + nova::{ + memory_consistency_circuit::NovaMemoryConsistencyCircuit, + poseidon_parameters::OrchardNullifierScalar, + }, + poseidon::poseidon_hash::{ConstantLength, Hash}, + }; use alloc::vec; use alloc::vec::Vec; use ff::Field; @@ -9,14 +16,6 @@ mod test { traits::{circuit::TrivialCircuit, snark::RelaxedR1CSSNARKTrait, Engine}, PublicParams, RecursiveSNARK, }; - - use crate::{ - nova::{ - memory_consistency_circuit::NovaMemoryConsistencyCircuit, - poseidon_parameters::OrchardNullifierScalar, - }, - poseidon::poseidon_hash::{ConstantLength, Hash}, - }; type E1 = Bn256EngineKZG; type E2 = GrumpkinEngine; type EE1 = nova_snark::provider::hyperkzg::EvaluationEngine; @@ -48,7 +47,7 @@ mod test { #[test] // test correct memory consistency in one step - // for simolicity we experiment with a memory of size 4 + // for simplicity we experiment with a memory of size 4 only fn test_memory_consistency_in_one_step() { let address = [0 as u64].to_vec(); let instruction = [1 as u64].to_vec(); @@ -78,6 +77,9 @@ mod test { ) .expect("unable to setup"); + // The first four elements of z0_primary are the memory cells + // of a memory of size 4. The final element is the commitment + // of the memory. let mut recursive_snark = RecursiveSNARK::::new( &pp, &circuit_primary, @@ -94,8 +96,6 @@ mod test { .expect("unable to prove"); let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); - // assert!(res.is_ok()); - // println!("{:?}", res); let res = recursive_snark.verify( &pp, @@ -159,8 +159,6 @@ mod test { .expect("unable to prove"); let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); - // assert!(res.is_ok()); - // println!("{:?}", res); let res = recursive_snark.verify( &pp, @@ -224,8 +222,6 @@ mod test { .expect("unable to prove"); let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); - //assert!(res.is_ok()); - // println!("{:?}", res); let res = recursive_snark.verify( &pp, @@ -289,8 +285,6 @@ mod test { .expect("unable to prove"); let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); - //assert!(res.is_ok()); - // println!("{:?}", res); let res = recursive_snark.verify( &pp, @@ -354,8 +348,6 @@ mod test { .expect("unable to prove"); let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); - // assert!(res.is_ok()); - // println!("{:?}", res); let res = recursive_snark.verify( &pp, @@ -419,8 +411,6 @@ mod test { .expect("unable to prove"); let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); - //assert!(res.is_ok()); - // println!("{:?}", res); let res = recursive_snark.verify( &pp, From 052328de428b981153309f7f187a582b5784d40b Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:17:23 +0700 Subject: [PATCH 18/24] Resolve conflict --- zkmemory/src/poseidon/poseidon_hash.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/zkmemory/src/poseidon/poseidon_hash.rs b/zkmemory/src/poseidon/poseidon_hash.rs index e033ccd..eab3d42 100644 --- a/zkmemory/src/poseidon/poseidon_hash.rs +++ b/zkmemory/src/poseidon/poseidon_hash.rs @@ -8,7 +8,7 @@ //! Merkle tree and Verkle tree opening proofs. extern crate alloc; -use alloc::{fmt, vec::Vec}; +use alloc::vec::Vec; use core::{fmt::Debug, iter, marker::PhantomData}; use ff::{Field, PrimeField}; @@ -16,7 +16,7 @@ use ff::{Field, PrimeField}; pub(crate) type Mtrx = [[F; T]; T]; /// The trait for specifying the hash parameters -pub trait Spec: fmt::Debug { +pub trait Spec { /// The number of full rounds for Poseidon hash. fn full_rounds() -> usize; @@ -32,7 +32,7 @@ pub trait Spec: fmt::Debu /// The trait for specifying the domain of messages pub trait Domain { - /// Iterator that outputs padding field elements. + /// Iterator that outputs padding Field+PrimeField elements. type Padding: IntoIterator; /// The initial capacity element, encoding this domain. @@ -42,11 +42,11 @@ pub trait Domain { fn padding(input_len: usize) -> Self::Padding; } -#[derive(Clone)] /// The number of messages to be hashed +#[derive(Clone)] pub struct ConstantLength; -impl Domain for ConstantLength { +impl Domain for ConstantLength { type Padding = iter::Take>; fn initial_capacity_element() -> F { @@ -62,10 +62,11 @@ impl Domain for ConstantLen /// The state of the `Sponge`. pub trait SpongeMode {} + impl SpongeMode for Absorbing {} impl SpongeMode for Squeezing {} -impl Absorbing { +impl Absorbing { pub(crate) fn init_with(val: F) -> Self { Self( iter::once(Some(val)) @@ -78,17 +79,14 @@ impl Absorbing { } /// The absorbing state of the `Sponge`. -#[derive(Clone, Debug)] pub struct Absorbing(pub(crate) [Option; R]); /// The squeezing state of the `Sponge`. -#[derive(Clone, Debug)] pub struct Squeezing(pub(crate) [Option; R]); /// The type used to hold permutation state. pub(crate) type State = [F; T]; -#[derive(Clone)] /// A Poseidon sponge. pub(crate) struct Sponge< F: Field + PrimeField, @@ -263,7 +261,6 @@ impl, const T: usize, const R: usize> } } -#[derive(Clone)] /// A Poseidon hash function, built around a sponge. pub struct Hash< F: Field + PrimeField, @@ -306,7 +303,7 @@ impl, const T: usize, const R: usize, co use crate::poseidon::poseidon_constants::{MDS, MDS_INV, ROUND_CONSTANTS}; use halo2curves::pasta::Fp; /// Generate specific constants for testing the poseidon hash -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct OrchardNullifier; impl Spec for OrchardNullifier { @@ -329,6 +326,7 @@ impl Spec for OrchardNullifier { #[cfg(test)] mod tests { + use super::*; use halo2curves::pasta::pallas::Base; #[test] From b6fe64375fdd9ad6c14d90ba4a8c66835a076ce2 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:23:21 +0700 Subject: [PATCH 19/24] Fix all errors after resolving conflict --- zkmemory/src/poseidon/poseidon_hash.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/zkmemory/src/poseidon/poseidon_hash.rs b/zkmemory/src/poseidon/poseidon_hash.rs index eab3d42..c5d1a38 100644 --- a/zkmemory/src/poseidon/poseidon_hash.rs +++ b/zkmemory/src/poseidon/poseidon_hash.rs @@ -78,6 +78,7 @@ impl Absorbing { } } +#[derive(Clone)] /// The absorbing state of the `Sponge`. pub struct Absorbing(pub(crate) [Option; R]); @@ -87,6 +88,7 @@ pub struct Squeezing(pub(crate) [Option; R]); /// The type used to hold permutation state. pub(crate) type State = [F; T]; +#[derive(Clone)] /// A Poseidon sponge. pub(crate) struct Sponge< F: Field + PrimeField, @@ -261,6 +263,7 @@ impl, const T: usize, const R: usize> } } +#[derive(Clone)] /// A Poseidon hash function, built around a sponge. pub struct Hash< F: Field + PrimeField, From c9e7f6bb16e027c8b714c479e3130c80aff2ba4b Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:14:20 +0700 Subject: [PATCH 20/24] Fix clippy issues --- zkmemory/src/lib.rs | 12 +- zkmemory/src/nova/testcases.rs | 52 ++-- zkmemory/src/poseidon/circuit.rs | 481 +++++++++++++++++++++++++++++++ zkmemory/src/poseidon/gadgets.rs | 374 ++++++++++++++++++++++++ zkmemory/src/poseidon/mod.rs | 4 + 5 files changed, 889 insertions(+), 34 deletions(-) create mode 100644 zkmemory/src/poseidon/circuit.rs create mode 100644 zkmemory/src/poseidon/gadgets.rs diff --git a/zkmemory/src/lib.rs b/zkmemory/src/lib.rs index 87eef06..138351a 100644 --- a/zkmemory/src/lib.rs +++ b/zkmemory/src/lib.rs @@ -41,9 +41,7 @@ mod tests { let chunk_zero = B256::zero(); let bytes1 = [9u8; 32]; let chunk1 = B256::from(bytes1); - let bytes_convert: [u8; 32] = chunk1 - .try_into() - .expect("Cannot convert from B256 to bytes"); + let bytes_convert: [u8; 32] = chunk1.into(); assert_eq!(bytes_convert, bytes1); assert!(chunk_zero.is_zero()); assert!(!chunk1.is_zero()); @@ -52,9 +50,7 @@ mod tests { let chunk_zero = B128::zero(); let bytes1 = [9u8; 16]; let chunk1 = B128::from(bytes1); - let bytes_convert: [u8; 16] = chunk1 - .try_into() - .expect("Cannot convert from B128 to bytes"); + let bytes_convert: [u8; 16] = chunk1.into(); assert_eq!(bytes_convert, bytes1); assert!(chunk_zero.is_zero()); assert!(!chunk1.is_zero()); @@ -63,7 +59,7 @@ mod tests { let chunk_zero = B64::zero(); let bytes1 = [1u8; 8]; let chunk1 = B64::from(bytes1); - let bytes_convert: [u8; 8] = chunk1.try_into().expect("Cannot convert from B64 to bytes"); + let bytes_convert: [u8; 8] = chunk1.into(); assert_eq!(bytes_convert, bytes1); assert!(chunk_zero.is_zero()); assert!(!chunk1.is_zero()); @@ -72,7 +68,7 @@ mod tests { let chunk_zero = B64::zero(); let bytes1 = [59u8; 8]; let chunk1 = B64::from(bytes1); - let bytes_convert: [u8; 8] = chunk1.try_into().expect("Cannot convert from B64 to bytes"); + let bytes_convert: [u8; 8] = chunk1.into(); assert_eq!(bytes_convert, bytes1); assert!(chunk_zero.is_zero()); assert!(!chunk1.is_zero()); diff --git a/zkmemory/src/nova/testcases.rs b/zkmemory/src/nova/testcases.rs index dd0d7eb..931cbe2 100644 --- a/zkmemory/src/nova/testcases.rs +++ b/zkmemory/src/nova/testcases.rs @@ -49,9 +49,9 @@ mod test { // test correct memory consistency in one step // for simplicity we experiment with a memory of size 4 only fn test_memory_consistency_in_one_step() { - let address = [0 as u64].to_vec(); - let instruction = [1 as u64].to_vec(); - let value = [1292001 as u64].to_vec(); + let address = [0_u64].to_vec(); + let instruction = [1_u64].to_vec(); + let value = [1292001_u64].to_vec(); // let num_steps = 10; let circuit_primary = NovaMemoryConsistencyCircuit::< ::GE, @@ -109,15 +109,15 @@ mod test { ], &[::Scalar::ZERO], ); - assert_eq!(res.is_ok(), true); + assert!(res.is_ok()); } // test memory consistency in two steps #[test] fn test_memory_consistency_in_two_steps() { - let address = [0 as u64, 0 as u64].to_vec(); - let instruction = [1 as u64, 0 as u64].to_vec(); - let value = [1292001 as u64, 1292001 as u64].to_vec(); + let address = [0_u64, 0_u64].to_vec(); + let instruction = [1_u64, 0_u64].to_vec(); + let value = [1292001_u64, 1292001_u64].to_vec(); // let num_steps = 10; let circuit_primary = NovaMemoryConsistencyCircuit::< ::GE, @@ -172,15 +172,15 @@ mod test { ], &[::Scalar::ZERO], ); - assert_eq!(res.is_ok(), true); + assert!(res.is_ok()); } #[test] // test invalid instruction in trace record fn test_invalid_instruction() { - let address = [0 as u64].to_vec(); - let instruction = [2 as u64].to_vec(); - let value = [1292001 as u64].to_vec(); + let address = [0_u64].to_vec(); + let instruction = [2_u64].to_vec(); + let value = [1292001_u64].to_vec(); // let num_steps = 10; let circuit_primary = NovaMemoryConsistencyCircuit::< ::GE, @@ -241,9 +241,9 @@ mod test { #[test] // test invalid read fn test_invalid_read() { - let address = [0 as u64].to_vec(); - let instruction = [0 as u64].to_vec(); - let value = [1292001 as u64].to_vec(); + let address = [0_u64].to_vec(); + let instruction = [0_u64].to_vec(); + let value = [1292001_u64].to_vec(); // let num_steps = 10; let circuit_primary = NovaMemoryConsistencyCircuit::< ::GE, @@ -304,9 +304,9 @@ mod test { // test memory consistency in two steps #[test] fn test_invalid_read_part_two() { - let address = [0 as u64, 0 as u64].to_vec(); - let instruction = [1 as u64, 0 as u64].to_vec(); - let value = [1292001 as u64, 0 as u64].to_vec(); + let address = [0_u64, 0_u64].to_vec(); + let instruction = [1_u64, 0_u64].to_vec(); + let value = [1292001_u64, 0_u64].to_vec(); // let num_steps = 10; let circuit_primary = NovaMemoryConsistencyCircuit::< ::GE, @@ -367,9 +367,9 @@ mod test { #[test] // test invalid commitment fn test_invalid_commitment() { - let address = [0 as u64].to_vec(); - let instruction = [0 as u64].to_vec(); - let value = [1292001 as u64].to_vec(); + let address = [0_u64].to_vec(); + let instruction = [0_u64].to_vec(); + let value = [1292001_u64].to_vec(); // let num_steps = 10; let circuit_primary = NovaMemoryConsistencyCircuit::< ::GE, @@ -404,7 +404,7 @@ mod test { ::Scalar::zero(), ::Scalar::zero(), ::Scalar::zero(), - ::Scalar::from(99 as u64), + ::Scalar::from(99_u64), ], &[::Scalar::zero()], ) @@ -420,7 +420,7 @@ mod test { ::Scalar::zero(), ::Scalar::zero(), ::Scalar::zero(), - ::Scalar::from(99 as u64), + ::Scalar::from(99_u64), ], &[::Scalar::ZERO], ); @@ -430,9 +430,9 @@ mod test { #[test] // test correct memory consistency in four step fn test_memory_consistency_in_four_step() { - let address = [0 as u64, 1 as u64, 2 as u64, 3 as u64].to_vec(); - let instruction = [1 as u64, 0 as u64, 1 as u64, 0 as u64].to_vec(); - let value = [1292001 as u64, 0 as u64, 1292001 as u64, 0 as u64].to_vec(); + let address = [0_u64, 1_u64, 2_u64, 3_u64].to_vec(); + let instruction = [1_u64, 0_u64, 1_u64, 0_u64].to_vec(); + let value = [1292001_u64, 0_u64, 1292001_u64, 0_u64].to_vec(); let mut circuit_primary = vec![]; for i in 0..2 { circuit_primary.push(NovaMemoryConsistencyCircuit::< @@ -497,6 +497,6 @@ mod test { ], &[::Scalar::zero()], ); - assert_eq!(res.is_ok(), true); + assert!(res.is_ok()); } } diff --git a/zkmemory/src/poseidon/circuit.rs b/zkmemory/src/poseidon/circuit.rs new file mode 100644 index 0000000..43534a9 --- /dev/null +++ b/zkmemory/src/poseidon/circuit.rs @@ -0,0 +1,481 @@ +//! The poseidon circuit, with most details based from +//! [Zcash implementation](https://github.com/summa-dev/halo2/blob/main/halo2_gadgets/src/poseidon/pow5.rs). +//! We originally wanted to import the implementation from Zcash's library directly. +//! However, since we are using the Halo2 version from PSE, we need to +//! clone many functions and fix some details so that the implementation +//! will be compatible with our implementation. +extern crate alloc; +use core::marker::PhantomData; + +use alloc::string::ToString; +use alloc::{format, vec::Vec}; +use ff::PrimeField; +use halo2_proofs::circuit::{SimpleFloorPlanner, Value}; +use halo2_proofs::plonk::{Any, Constraints}; +use halo2_proofs::{ + circuit::Layouter, + plonk::{ + Advice, Circuit, Column, ConstraintSystem, Error, Expression, Fixed, Selector, VirtualCells, + }, + poly::Rotation, +}; + +use super::gadgets::{Hash, PaddedWord, PoseidonState, StateWord}; +use super::poseidon_hash::{Absorbing, ConstantLength, Domain, Mtrx, Spec, Squeezing, State}; + +/// The poseidon config +#[derive(Clone, Debug)] +pub struct PoseidonConfig { + pub(crate) state: [Column; T], + pub(crate) partial_sbox: Column, + pub(crate) sel_full_round: Selector, + pub(crate) sel_partial_round: Selector, + pub(crate) sel_pad_and_add: Selector, + half_full_rounds: usize, + half_partial_rounds: usize, + pub(crate) rc_a: [Column; T], + pub(crate) rc_b: [Column; T], + pub(crate) round_constants: Vec<[F; T]>, + pub(crate) alpha: [u64; 4], + pub(crate) m_reg: Mtrx, +} + +impl PoseidonConfig { + /// Create the gates of Poseidon + pub fn configure>( + meta: &mut ConstraintSystem, + state: [Column; T], + partial_sbox: Column, + rc_a: [Column; T], + rc_b: [Column; T], + ) -> Self { + assert_eq!(R, T - 1); + // Generate constants for the Poseidon permutation. + // This gadget requires R_F and R_P to be even. + assert!(S::full_rounds() & 1 == 0); + assert!(S::partial_rounds() & 1 == 0); + let half_full_rounds = S::full_rounds() / 2; + let half_partial_rounds = S::partial_rounds() / 2; + let (round_constants, m_reg, m_inv) = S::constants(); + + // This allows state words to be initialized (by constraining them equal to fixed + // values), and used in a permutation from an arbitrary region. rc_a is used in + // every permutation round, while rc_b is empty in the initial and final full + // rounds, so we use rc_b as "scratch space" for fixed values (enabling potential + // layouter optimisations). + for column in core::iter::empty() + .chain(state.iter().cloned().map(Column::::from)) + .chain(rc_b.iter().cloned().map(Column::::from)) + { + meta.enable_equality(column); + } + + let sel_full_round = meta.selector(); + let sel_partial_round = meta.selector(); + let sel_pad_and_add = meta.selector(); + + let alpha = [5, 0, 0, 0]; + let pow_5 = |v: Expression| { + let v2 = v.clone() * v.clone(); + v2.clone() * v2 * v + }; + + meta.create_gate("full round", |meta| { + let s_full = meta.query_selector(sel_full_round); + + Constraints::with_selector( + s_full, + (0..T) + .map(|next_idx| { + let state_next = meta.query_advice(state[next_idx], Rotation::next()); + let expr = (0..T) + .map(|idx| { + let state_cur = meta.query_advice(state[idx], Rotation::cur()); + let rc_a = meta.query_fixed(rc_a[idx], Rotation::cur()); + pow_5(state_cur + rc_a) * m_reg[next_idx][idx] + }) + .reduce(|acc, term| acc + term) + .expect("T > 0"); + expr - state_next + }) + .collect::>(), + ) + }); + + meta.create_gate("partial rounds", |meta| { + let cur_0 = meta.query_advice(state[0], Rotation::cur()); + let mid_0 = meta.query_advice(partial_sbox, Rotation::cur()); + + let rc_a0 = meta.query_fixed(rc_a[0], Rotation::cur()); + let rc_b0 = meta.query_fixed(rc_b[0], Rotation::cur()); + + let s_partial = meta.query_selector(sel_partial_round); + + let mid = |idx: usize, meta: &mut VirtualCells<'_, F>| { + let mid = mid_0.clone() * m_reg[idx][0]; + (1..T).fold(mid, |acc, cur_idx| { + let cur = meta.query_advice(state[cur_idx], Rotation::cur()); + let rc_a = meta.query_fixed(rc_a[cur_idx], Rotation::cur()); + acc + (cur + rc_a) * m_reg[idx][cur_idx] + }) + }; + + let next = |idx: usize, meta: &mut VirtualCells<'_, F>| { + (0..T) + .map(|next_idx| { + let next = meta.query_advice(state[next_idx], Rotation::next()); + next * m_inv[idx][next_idx] + }) + .reduce(|acc, next| acc + next) + .expect("T > 0") + }; + + let partial_round_linear = |idx: usize, meta: &mut VirtualCells<'_, F>| { + let rc_b = meta.query_fixed(rc_b[idx], Rotation::cur()); + mid(idx, meta) + rc_b - next(idx, meta) + }; + + Constraints::with_selector( + s_partial, + core::iter::empty() + // state[0] round a + .chain(Some(pow_5(cur_0 + rc_a0) - mid_0.clone())) + // state[0] round b + .chain(Some(pow_5(mid(0, meta) + rc_b0) - next(0, meta))) + .chain((1..T).map(|idx| partial_round_linear(idx, meta))) + .collect::>(), + ) + }); + + meta.create_gate("pad-and-add", |meta| { + let initial_state_rate = meta.query_advice(state[R], Rotation::prev()); + let output_state_rate = meta.query_advice(state[R], Rotation::next()); + + let s_pad_and_add = meta.query_selector(sel_pad_and_add); + + let pad_and_add = |idx: usize| { + let initial_state = meta.query_advice(state[idx], Rotation::prev()); + let input = meta.query_advice(state[idx], Rotation::cur()); + let output_state = meta.query_advice(state[idx], Rotation::next()); + + // We pad the input by storing the required padding in fixed columns and + // then constraining the corresponding input columns to be equal to it. + initial_state + input - output_state + }; + + Constraints::with_selector( + s_pad_and_add, + (0..R) + .map(pad_and_add) + // The capacity element is never altered by the input. + .chain(Some(initial_state_rate - output_state_rate)) + .collect::>(), + ) + }); + + PoseidonConfig { + state, + partial_sbox, + sel_full_round, + sel_partial_round, + sel_pad_and_add, + half_full_rounds, + half_partial_rounds, + rc_a, + rc_b, + round_constants, + alpha, + m_reg, + } + } + + /// Get the initial state + pub fn initial_state>( + &self, + layouter: &mut impl Layouter, + ) -> Result, T>, Error> { + let state = layouter.assign_region( + || "initial state for domain".to_string(), + |mut region| { + let mut state = Vec::with_capacity(T); + let mut load_state_word = |i: usize, value: F| -> Result<_, Error> { + let var = region.assign_advice_from_constant( + || format!("state_{}", i), + self.state[i], + 0, + value, + )?; + state.push(StateWord(var)); + + Ok(()) + }; + for i in 0..R { + load_state_word(i, F::ZERO)?; + } + load_state_word(R, D::initial_capacity_element())?; + Ok(state) + }, + )?; + + Ok(state.try_into().expect("unable to get state")) + } + + /// Add the input + pub fn add_input( + &self, + layouter: &mut impl Layouter, + initial_state: &State, T>, + input: &Absorbing, R>, + ) -> Result, T>, Error> { + layouter.assign_region( + || "add input for domain".to_string(), + |mut region| { + self.sel_pad_and_add.enable(&mut region, 1)?; + + // Load the initial state into this region. + let load_state_word = |i: usize| { + initial_state[i] + .0 + .copy_advice( + || format!("load state_{}", i), + &mut region, + self.state[i], + 0, + ) + .map(StateWord) + }; + let initial_state: Result, Error> = (0..T).map(load_state_word).collect(); + let initial_state = initial_state?; + + // Load the input into this region. + let load_input_word = |i: usize| { + let (cell, value) = match input.0[i].clone() { + Some(PaddedWord::Message(word)) => (word.cell(), word.value().copied()), + Some(PaddedWord::Padding(padding_value)) => { + let cell = region + .assign_fixed( + || format!("load pad_{}", i), + self.rc_b[i], + 1, + || Value::known(padding_value), + )? + .cell(); + (cell, Value::known(padding_value)) + } + _ => panic!("Input is not padded"), + }; + let var = region.assign_advice( + || format!("load input_{}", i), + self.state[i], + 1, + || value, + )?; + region.constrain_equal(cell, var.cell())?; + + Ok(StateWord(var)) + }; + let input: Result, Error> = (0..R).map(load_input_word).collect(); + let input = input?; + + // Constrain the output. + let constrain_output_word = |i: usize| { + let value = initial_state[i].0.value().copied() + + input + .get(i) + .map(|word| word.0.value().cloned()) + // The capacity element is never altered by the input. + .unwrap_or_else(|| Value::known(F::ZERO)); + region + .assign_advice(|| format!("load output_{}", i), self.state[i], 2, || value) + .map(StateWord) + }; + let output: Result, Error> = (0..T).map(constrain_output_word).collect(); + output.map(|output| output.try_into().expect("cannot get output")) + }, + ) + } + + /// Runs the Poseidon permutation on the given state. Given inputs a state, + /// a MDS matrix and a list of round_constants, this function transform the + /// state into a new state. + pub fn permute>( + &self, + layouter: &mut impl Layouter, + initial_state: &State, T>, + ) -> Result, T>, Error> { + layouter.assign_region( + || "permute state", + |mut region| { + // Load the initial state into this region. + let state = PoseidonState::load::(&mut region, self, initial_state)?; + + let state = (0..self.half_full_rounds).try_fold(state, |state, r| { + state.full_round::(&mut region, self, r, r) + })?; + + let state = (0..self.half_partial_rounds).try_fold(state, |state, r| { + state.partial_round::( + &mut region, + self, + self.half_full_rounds + 2 * r, + self.half_full_rounds + r, + ) + })?; + + let state = (0..self.half_full_rounds).try_fold(state, |state, r| { + state.full_round::( + &mut region, + self, + self.half_full_rounds + 2 * self.half_partial_rounds + r, + self.half_full_rounds + self.half_partial_rounds + r, + ) + })?; + + Ok(state.0) + }, + ) + } + + /// Get the output of the hash + pub fn get_output(state: &State, T>) -> Squeezing, R> { + Squeezing( + state[..R] + .iter() + .map(|word| Some(word.clone())) + .collect::>>>() + .try_into() + .expect("cannot get state"), + ) + } +} + +#[derive(Debug)] +/// The poseidon circuit +pub struct PoseidonCircuit< + S: Spec, + F: PrimeField, + D: Domain, + const T: usize, + const R: usize, + const L: usize, +> { + message: [F; L], + // For the purpose of this test, witness the result. + // TODO: Move this into an instance column. + output: F, + _marker: PhantomData, + _marker2: PhantomData, +} +impl< + S: Spec, + F: PrimeField, + D: Domain + Clone, + const T: usize, + const R: usize, + const L: usize, + > Circuit for PoseidonCircuit +{ + type Config = PoseidonConfig; + type FloorPlanner = SimpleFloorPlanner; + + fn without_witnesses(&self) -> Self { + Self { + message: [F::ZERO; L], + output: F::ZERO, + _marker: PhantomData, + _marker2: PhantomData, + } + } + + fn configure(meta: &mut ConstraintSystem) -> PoseidonConfig { + let state = (0..T) + .map(|_| meta.advice_column()) + .collect::>>(); + let partial_sbox = meta.advice_column(); + let rc_a = (0..T) + .map(|_| meta.fixed_column()) + .collect::>>(); + let rc_b = (0..T) + .map(|_| meta.fixed_column()) + .collect::>>(); + meta.enable_constant(rc_b[0]); + PoseidonConfig::configure::( + meta, + state.try_into().expect("could not load state"), + partial_sbox, + rc_a.try_into().expect("could not load rc_a"), + rc_b.try_into().expect("could not load rc_b"), + ) + } + fn synthesize( + &self, + config: PoseidonConfig, + mut layouter: impl Layouter, + ) -> Result<(), Error> { + let message = layouter.assign_region( + || "load message", + |mut region| { + let message_word = |i: usize| { + let value = Value::known(self.message[i]); + region.assign_advice( + || format!("load message_{}", i), + config.state[i], + 0, + || value, + ) + }; + let message: Result, Error> = (0..L).map(message_word).collect(); + Ok(message?.try_into().expect("cannot unwrap message")) + }, + )?; + + let hasher = Hash::, T, R>::init( + config.clone(), + layouter.namespace(|| "init"), + )?; + let output = hasher.hash(layouter.namespace(|| "hash"), message)?; + + layouter.assign_region( + || "constrain output", + |mut region| { + let expected_var = region.assign_advice( + || "load output", + config.state[0], + 0, + || Value::known(self.output), + )?; + region.constrain_equal(output.cell(), expected_var.cell()) + }, + ) + } +} + +#[cfg(test)] +mod tests { + use super::PoseidonCircuit; + use super::*; + use crate::poseidon::poseidon_hash::{Hash, OrchardNullifier}; + use alloc::vec; + use ff::Field; + use halo2_proofs::dev::MockProver; + use halo2curves::pasta::Fp; + use rand::rngs::OsRng; + + #[test] + fn poseidon_hash() { + let rng = OsRng; + + let message = [Fp::random(rng), Fp::random(rng)]; + let output = Hash::, 3, 2>::init().hash(message); + + let k = 6; + let circuit = PoseidonCircuit::, 3, 2, 2> { + message, + output, + _marker: PhantomData, + _marker2: PhantomData, + }; + let prover = MockProver::run(k, &circuit, vec![]).expect("cannot prove"); + assert_eq!(prover.verify(), Ok(())) + } +} diff --git a/zkmemory/src/poseidon/gadgets.rs b/zkmemory/src/poseidon/gadgets.rs new file mode 100644 index 0000000..508c5df --- /dev/null +++ b/zkmemory/src/poseidon/gadgets.rs @@ -0,0 +1,374 @@ +extern crate alloc; +use core::marker::PhantomData; + +use alloc::format; +use alloc::vec::Vec; +use ff::PrimeField; +use halo2_proofs::circuit::{AssignedCell, Region, Value}; +use halo2_proofs::plonk::Selector; +use halo2_proofs::{circuit::Layouter, plonk::Error}; + +use super::circuit::PoseidonConfig; +use super::poseidon_hash::{Absorbing, ConstantLength, Domain, Spec, SpongeMode, Squeezing, State}; + +#[derive(Clone, Debug)] +/// A word from the padded input to a Poseidon sponge. +pub enum PaddedWord { + /// A message word provided by the prover. + Message(AssignedCell), + /// A padding word, that will be fixed in the circuit parameters. + Padding(F), +} + +/// Simplified type to pass cargo check +pub type Sqz = Squeezing, R>; + +/// Poseidon hash struct, used in verification circuit +pub struct Hash, D: Domain, const T: usize, const R: usize> { + sponge: Sponge, R>, D, T, R>, +} + +impl, D: Domain, const T: usize, const R: usize> + Hash +{ + /// Initializes a new hasher. + pub fn init( + config: PoseidonConfig, + layouter: impl Layouter, + ) -> Result { + Sponge::new(config, layouter).map(|sponge| Hash { sponge }) + } +} + +impl, const T: usize, const R: usize, const L: usize> + Hash, T, R> +{ + /// Hashes the given input. + pub fn hash( + mut self, + mut layouter: impl Layouter, + message: [AssignedCell; L], + ) -> Result, Error> { + for (i, value) in message + .into_iter() + .map(PaddedWord::Message) + .chain( as Domain>::padding(L).map(PaddedWord::Padding)) + .enumerate() + { + self.sponge + .absorb(layouter.namespace(|| format!("absorb_{}", i)), value)?; + } + self.sponge + .finish_absorbing(layouter.namespace(|| "finish absorbing"))? + .squeeze(layouter.namespace(|| "squeeze")) + } +} + +/// A Poseidon sponge. +#[derive(Debug)] +pub struct Sponge< + F: PrimeField, + S: Spec, + M: SpongeMode, + D: Domain, + const T: usize, + const R: usize, +> { + config: PoseidonConfig, + mode: M, + state: State, T>, + _marker: PhantomData, + _marker2: PhantomData, +} + +impl, D: Domain, const T: usize, const R: usize> + Sponge, R>, D, T, R> +{ + /// Constructs a new duplex sponge for the given Poseidon specification. + pub fn new( + config: PoseidonConfig, + mut layouter: impl Layouter, + ) -> Result { + config + .initial_state::(&mut layouter) + .map(|state| Sponge { + config, + mode: Absorbing( + (0..R) + .map(|_| None) + .collect::>() + .try_into() + .expect("unable to get mode"), + ), + state, + _marker: PhantomData, + _marker2: PhantomData, + }) + } + + /// Absorbs an element into the sponge. + pub fn absorb( + &mut self, + mut layouter: impl Layouter, + value: PaddedWord, + ) -> Result<(), Error> { + for entry in self.mode.0.iter_mut() { + if entry.is_none() { + *entry = Some(value); + return Ok(()); + } + } + + // We've already absorbed as many elements as we can + let _ = poseidon_sponge::( + &self.config, + layouter.namespace(|| "PoseidonSponge"), + &mut self.state, + Some(&self.mode), + )?; + self.mode = Absorbing::init_with(value); + Ok(()) + } + + /// Transitions the sponge into its squeezing state. + pub fn finish_absorbing( + mut self, + mut layouter: impl Layouter, + ) -> Result, D, T, R>, Error> { + let mode = poseidon_sponge::( + &self.config, + layouter.namespace(|| "PoseidonSponge"), + &mut self.state, + Some(&self.mode), + )?; + + Ok(Sponge { + config: self.config, + mode, + state: self.state, + _marker: PhantomData, + _marker2: PhantomData, + }) + } +} +impl, D: Domain, const T: usize, const R: usize> + Sponge, R>, D, T, R> +{ + /// Squeezes an element from the sponge. + pub fn squeeze(&mut self, mut layouter: impl Layouter) -> Result, Error> { + loop { + for entry in self.mode.0.iter_mut() { + if let Some(inner) = entry.take() { + return Ok(inner.into()); + } + } + // We've already squeezed out all available elements + self.mode = poseidon_sponge::( + &self.config, + layouter.namespace(|| "PoseidonSponge"), + &mut self.state, + None, + )?; + } + } +} + +fn poseidon_sponge, const T: usize, const R: usize>( + config: &PoseidonConfig, + mut layouter: impl Layouter, + state: &mut State, T>, + input: Option<&Absorbing, R>>, +) -> Result, R>, Error> { + if let Some(input) = input { + *state = config.add_input(&mut layouter, state, input)?; + } + *state = config.permute::(&mut layouter, state)?; + Ok(PoseidonConfig::::get_output(state)) +} + +#[derive(Clone, Debug)] +/// The Stateword +pub struct StateWord(pub AssignedCell); + +impl From> for AssignedCell { + fn from(state_word: StateWord) -> AssignedCell { + state_word.0 + } +} + +/// The current state of Poseidon +pub struct PoseidonState(pub [StateWord; T]); + +impl PoseidonState { + /// Load the initial state + pub fn load, const R: usize>( + region: &mut Region<'_, F>, + config: &PoseidonConfig, + initial_state: &State, T>, + ) -> Result { + let load_state_word = |i: usize| { + initial_state[i] + .0 + .copy_advice(|| format!("load state_{}", i), region, config.state[i], 0) + .map(StateWord) + }; + + let state: Result>, Error> = (0..T).map(load_state_word).collect(); + state.map(|state| PoseidonState(state.try_into().expect("unable to get state"))) + } + + fn round( + region: &mut Region<'_, F>, + config: &PoseidonConfig, + round: usize, + offset: usize, + round_gate: Selector, + round_fn: impl FnOnce(&mut Region<'_, F>) -> Result<(usize, [Value; T]), Error>, + ) -> Result { + // Enable the required gate. + round_gate.enable(region, offset)?; + + // Load the round constants. + let mut load_round_constant = |i: usize| { + region.assign_fixed( + || format!("round_{} rc_{}", round, i), + config.rc_a[i], + offset, + || Value::known(config.round_constants[round][i]), + ) + }; + for i in 0..T { + load_round_constant(i)?; + } + + // Compute the next round's state. + let (next_round, next_state) = round_fn(region)?; + + let next_state_word = |i: usize| { + let value = next_state[i]; + let var = region.assign_advice( + || format!("round_{} state_{}", next_round, i), + config.state[i], + offset + 1, + || value, + )?; + Ok(StateWord(var)) + }; + + let next_state: Result>, Error> = (0..T).map(next_state_word).collect(); + next_state.map(|next_state| { + PoseidonState(next_state.try_into().expect("unable to get next_state")) + }) + } + + /// update the state via a full round + pub fn full_round, const R: usize>( + self, + region: &mut Region<'_, F>, + config: &PoseidonConfig, + round: usize, + offset: usize, + ) -> Result { + Self::round::(region, config, round, offset, config.sel_full_round, |_| { + let q = self.0.iter().enumerate().map(|(idx, word)| { + word.0 + .value() + .map(|v| *v + config.round_constants[round][idx]) + }); + let r: Value> = q.map(|q| q.map(|q| q.pow(config.alpha))).collect(); + let m = &config.m_reg; + let state = m.iter().map(|m_i| { + r.as_ref().map(|r| { + r.iter() + .enumerate() + .fold(F::ZERO, |acc, (j, r_j)| acc + m_i[j] * r_j) + }) + }); + Ok(( + round + 1, + state.collect::>>().try_into().unwrap(), + )) + }) + } + + /// update a state via a half round + pub fn partial_round, const R: usize>( + self, + region: &mut Region<'_, F>, + config: &PoseidonConfig, + round: usize, + offset: usize, + ) -> Result { + Self::round::( + region, + config, + round, + offset, + config.sel_partial_round, + |region| { + let m = &config.m_reg; + let p: Value> = self.0.iter().map(|word| word.0.value().cloned()).collect(); + let r: Value> = p.map(|p| { + let r_0 = (p[0] + config.round_constants[round][0]).pow(config.alpha); + let r_i = p[1..] + .iter() + .enumerate() + .map(|(i, p_i)| *p_i + config.round_constants[round][i + 1]); + core::iter::empty().chain(Some(r_0)).chain(r_i).collect() + }); + + region.assign_advice( + || format!("round_{} partial_sbox", round), + config.partial_sbox, + offset, + || r.as_ref().map(|r| r[0]), + )?; + + let p_mid: Value> = m + .iter() + .map(|m_i| { + r.as_ref().map(|r| { + m_i.iter() + .zip(r.iter()) + .fold(F::ZERO, |acc, (m_ij, r_j)| acc + *m_ij * r_j) + }) + }) + .collect(); + + // Load the second round constants. + let mut load_round_constant = |i: usize| { + region.assign_fixed( + || format!("round_{} rc_{}", round + 1, i), + config.rc_b[i], + offset, + || Value::known(config.round_constants[round + 1][i]), + ) + }; + for i in 0..T { + load_round_constant(i)?; + } + let r_mid: Value> = p_mid.map(|p| { + let r_0 = (p[0] + config.round_constants[round + 1][0]).pow(config.alpha); + let r_i = p[1..] + .iter() + .enumerate() + .map(|(i, p_i)| *p_i + config.round_constants[round + 1][i + 1]); + core::iter::empty().chain(Some(r_0)).chain(r_i).collect() + }); + + let state: Vec> = m + .iter() + .map(|m_i| { + r_mid.as_ref().map(|r| { + m_i.iter() + .zip(r.iter()) + .fold(F::ZERO, |acc, (m_ij, r_j)| acc + *m_ij * r_j) + }) + }) + .collect(); + + Ok((round + 2, state.try_into().unwrap())) + }, + ) + } +} diff --git a/zkmemory/src/poseidon/mod.rs b/zkmemory/src/poseidon/mod.rs index e3c5587..2ded91c 100644 --- a/zkmemory/src/poseidon/mod.rs +++ b/zkmemory/src/poseidon/mod.rs @@ -1,3 +1,7 @@ +/// The Poseidon hash circuit +pub mod circuit; +/// The gadget functions +pub mod gadgets; /// The public constants for the Poseidon hash pub mod poseidon_constants; /// The implelentation of Poseidon hash From 096a9e525c6eed6980a9ded7aeac7f90bb67bd64 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:25:59 +0700 Subject: [PATCH 21/24] Fix rustfmt issue --- zkmemory/src/poseidon/circuit.rs | 2 +- zkmemory/src/poseidon/gadgets.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/zkmemory/src/poseidon/circuit.rs b/zkmemory/src/poseidon/circuit.rs index e34247f..43534a9 100644 --- a/zkmemory/src/poseidon/circuit.rs +++ b/zkmemory/src/poseidon/circuit.rs @@ -460,7 +460,7 @@ mod tests { use halo2_proofs::dev::MockProver; use halo2curves::pasta::Fp; use rand::rngs::OsRng; - + #[test] fn poseidon_hash() { let rng = OsRng; diff --git a/zkmemory/src/poseidon/gadgets.rs b/zkmemory/src/poseidon/gadgets.rs index 266db3b..508c5df 100644 --- a/zkmemory/src/poseidon/gadgets.rs +++ b/zkmemory/src/poseidon/gadgets.rs @@ -64,7 +64,6 @@ impl, const T: usize, const R: usize, const L: u } } - /// A Poseidon sponge. #[derive(Debug)] pub struct Sponge< From 0dd76bc555c10ff2e5424955cbb69a3d32b7c63a Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:30:13 +0700 Subject: [PATCH 22/24] Fix additional clippy issues --- zkmemory/src/commitment/kzg.rs | 2 +- zkmemory/src/nova/testcases.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/zkmemory/src/commitment/kzg.rs b/zkmemory/src/commitment/kzg.rs index cfe0e58..038e292 100644 --- a/zkmemory/src/commitment/kzg.rs +++ b/zkmemory/src/commitment/kzg.rs @@ -367,7 +367,7 @@ mod test { let fr = Fr::from_bytes(&chunk).expect("Unable to convert to Fr"); // Convert back from Fr to bytes - let chunk_fr: [u8; 32] = fr.try_into().expect("Cannot convert from Fr to bytes"); + let chunk_fr: [u8; 32] = fr.into(); assert_eq!(chunk_fr, chunk); } diff --git a/zkmemory/src/nova/testcases.rs b/zkmemory/src/nova/testcases.rs index 931cbe2..4c55de0 100644 --- a/zkmemory/src/nova/testcases.rs +++ b/zkmemory/src/nova/testcases.rs @@ -235,7 +235,7 @@ mod test { ], &[::Scalar::ZERO], ); - assert_ne!(res.is_ok(), true); + assert!(!res.is_ok()); } #[test] @@ -298,7 +298,7 @@ mod test { ], &[::Scalar::ZERO], ); - assert_ne!(res.is_ok(), true); + assert!(!res.is_ok()); } // test memory consistency in two steps @@ -361,7 +361,7 @@ mod test { ], &[::Scalar::ZERO], ); - assert_ne!(res.is_ok(), true); + assert!(!res.is_ok()); } #[test] @@ -424,7 +424,7 @@ mod test { ], &[::Scalar::ZERO], ); - assert_ne!(res.is_ok(), true); + assert!(!res.is_ok()); } #[test] From 450af3506bd0baa7548f217173d64f6c2da7d679 Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:34:11 +0700 Subject: [PATCH 23/24] Change !res.is_ok() into res.is_err() in Nova testcases --- zkmemory/src/nova/testcases.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zkmemory/src/nova/testcases.rs b/zkmemory/src/nova/testcases.rs index 4c55de0..e27c6dd 100644 --- a/zkmemory/src/nova/testcases.rs +++ b/zkmemory/src/nova/testcases.rs @@ -235,7 +235,7 @@ mod test { ], &[::Scalar::ZERO], ); - assert!(!res.is_ok()); + assert!(res.is_err()); } #[test] @@ -298,7 +298,7 @@ mod test { ], &[::Scalar::ZERO], ); - assert!(!res.is_ok()); + assert!(res.is_err()); } // test memory consistency in two steps @@ -361,7 +361,7 @@ mod test { ], &[::Scalar::ZERO], ); - assert!(!res.is_ok()); + assert!(res.is_err()); } #[test] @@ -424,7 +424,7 @@ mod test { ], &[::Scalar::ZERO], ); - assert!(!res.is_ok()); + assert!(res.is_err()); } #[test] From 647f5eab4ba23146ed1954d2203d138d1d30b76a Mon Sep 17 00:00:00 2001 From: phamnhatminh1292001 <66765903+phamnhatminh1292001@users.noreply.github.com> Date: Mon, 12 Aug 2024 22:07:40 +0700 Subject: [PATCH 24/24] Add address lookup constraint --- .../src/nova/memory_consistency_circuit.rs | 20 ++++++ zkmemory/src/nova/testcases.rs | 63 +++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/zkmemory/src/nova/memory_consistency_circuit.rs b/zkmemory/src/nova/memory_consistency_circuit.rs index fa27e0d..b4281f1 100644 --- a/zkmemory/src/nova/memory_consistency_circuit.rs +++ b/zkmemory/src/nova/memory_consistency_circuit.rs @@ -99,6 +99,26 @@ impl< }) .expect("unable to get commitment"); + // get lookup result to check whether address in 0..memory_len + let mut lookup_res = 0; + for i in 0..self.memory_len { + lookup_res += (G::Scalar::from(i as u64) - self.trace_record[j].address) + .is_zero() + .unwrap_u8(); + } + let lookup_res_alloc = AllocatedNum::alloc(cs.namespace(|| "lookup result"), || { + Ok(G::Scalar::from(lookup_res as u64)) + }) + .expect("unable to get lookup result"); + + // address must be in 0..memory_len + cs.enforce( + || "address must be in 0..memory_len", + |lc| lc + lookup_res_alloc.get_variable(), + |lc| lc + CS::one(), + |lc| lc + CS::one(), + ); + // commitment to the memory must be valid cs.enforce( || "commitment to the memory must be valid", diff --git a/zkmemory/src/nova/testcases.rs b/zkmemory/src/nova/testcases.rs index e27c6dd..591a614 100644 --- a/zkmemory/src/nova/testcases.rs +++ b/zkmemory/src/nova/testcases.rs @@ -238,6 +238,69 @@ mod test { assert!(res.is_err()); } + #[test] + // test invalid instruction in trace record + fn test_invalid_address() { + let address = [5_u64].to_vec(); + let instruction = [2_u64].to_vec(); + let value = [1292001_u64].to_vec(); + // let num_steps = 10; + let circuit_primary = NovaMemoryConsistencyCircuit::< + ::GE, + OrchardNullifierScalar, + 3, + 2, + >::new(4, 1, address, instruction, value); + let circuit_secondary = TrivialCircuit::<::Scalar>::default(); + + type C1 = NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>; + type C2 = TrivialCircuit<::Scalar>; + + let pp = PublicParams::< + E1, + E2, + NovaMemoryConsistencyCircuit<::GE, OrchardNullifierScalar, 3, 2>, + TrivialCircuit<::Scalar>, + >::setup( + &circuit_primary, + &circuit_secondary, + &*S1::ck_floor(), + &*S2::ck_floor(), + ) + .expect("unable to setup"); + + let mut recursive_snark = RecursiveSNARK::::new( + &pp, + &circuit_primary, + &circuit_secondary, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + merkle_tree_commit([::Scalar::zero(); 4].to_vec()), + ], + &[::Scalar::zero()], + ) + .expect("unable to prove"); + + let _ = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary); + + let res = recursive_snark.verify( + &pp, + 1, + &[ + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + ::Scalar::zero(), + merkle_tree_commit([::Scalar::zero(); 4].to_vec()), + ], + &[::Scalar::ZERO], + ); + assert!(res.is_err()); + } + #[test] // test invalid read fn test_invalid_read() {