arnaucube
arnaucube/NovaPublic Self-hosted repository
take ro_constants as a parameter (#58)

Srinath Setty srinath@microsoft.com
Sat, 14 May 2022 10:50:10 +0530
commit

36d4be2145a3ba9e9c2425bd0209c596e68f7f94

parent

6ac9c7706dceb7fa37d9fc606acd3d35b452c940

2 files changed, 29 insertions(+), 17 deletions(-)

jump to
M src/lib.rs → src/lib.rs

@@ -20,7 +20,7 @@ use r1cs::{

R1CSGens, R1CSInstance, R1CSShape, R1CSWitness, RelaxedR1CSInstance, RelaxedR1CSWitness, }; use std::marker::PhantomData; -use traits::{AbsorbInROTrait, Group, HashFuncConstantsTrait, HashFuncTrait}; +use traits::{AbsorbInROTrait, Group, HashFuncTrait}; /// A SNARK that holds the proof of a step of an incremental computation pub struct StepSNARK<G: Group> {

@@ -28,6 +28,9 @@ comm_T: CompressedCommitment<G::CompressedGroupElement>,

_p: PhantomData<G>, } +type ROConstants<G> = + <<G as Group>::HashFunc as HashFuncTrait<<G as Group>::Base, <G as Group>::Scalar>>::Constants; + impl<G: Group> StepSNARK<G> { /// Takes as input a Relaxed R1CS instance-witness tuple `(U1, W1)` and /// an R1CS instance-witness tuple `(U2, W2)` with the same structure `shape`

@@ -37,6 +40,7 @@ /// with the guarantee that the folded witness `W` satisfies the folded instance `U`

/// if and only if `W1` satisfies `U1` and `W2` satisfies `U2`. pub fn prove( gens: &R1CSGens<G>, + ro_consts: &ROConstants<G>, S: &R1CSShape<G>, U1: &RelaxedR1CSInstance<G>, W1: &RelaxedR1CSWitness<G>,

@@ -50,10 +54,7 @@ ),

NovaError, > { // initialize a new RO - let mut ro = G::HashFunc::new(<<G as traits::Group>::HashFunc as HashFuncTrait< - G::Base, - G::Scalar, - >>::Constants::new()); + let mut ro = G::HashFunc::new(ro_consts.clone()); // append S to the transcript S.absorb_in_ro(&mut ro);

@@ -94,15 +95,13 @@ /// with the guarantee that the folded instance `U`

/// if and only if `U1` and `U2` are satisfiable. pub fn verify( &self, + ro_consts: &ROConstants<G>, S: &R1CSShape<G>, U1: &RelaxedR1CSInstance<G>, U2: &R1CSInstance<G>, ) -> Result<RelaxedR1CSInstance<G>, NovaError> { // initialize a new RO - let mut ro = G::HashFunc::new(<<G as traits::Group>::HashFunc as HashFuncTrait< - G::Base, - G::Scalar, - >>::Constants::new()); + let mut ro = G::HashFunc::new(ro_consts.clone()); // append S to the transcript S.absorb_in_ro(&mut ro);

@@ -152,6 +151,7 @@

#[cfg(test)] mod tests { use super::*; + use crate::traits::HashFuncConstantsTrait; use ::bellperson::{gadgets::num::AllocatedNum, ConstraintSystem, SynthesisError}; use ff::{Field, PrimeField}; use rand::rngs::OsRng;

@@ -205,6 +205,10 @@ let mut cs: ShapeCS<G> = ShapeCS::new();

let _ = synthesize_tiny_r1cs_bellperson(&mut cs, None); let shape = cs.r1cs_shape(); let gens = cs.r1cs_gens(); + let ro_consts = <<G as Group>::HashFunc as HashFuncTrait< + <G as Group>::Base, + <G as Group>::Scalar, + >>::Constants::new(); // Now get the instance and assignment for one instance let mut cs: SatisfyingAssignment<G> = SatisfyingAssignment::new();

@@ -223,11 +227,15 @@ // Make sure that the second instance is satisfiable

assert!(shape.is_sat(&gens, &U2, &W2).is_ok()); // execute a sequence of folds - execute_sequence(&gens, &shape, &U1, &W1, &U2, &W2); + execute_sequence(&gens, &ro_consts, &shape, &U1, &W1, &U2, &W2); } fn execute_sequence( gens: &R1CSGens<G>, + ro_consts: &<<G as traits::Group>::HashFunc as HashFuncTrait< + <G as traits::Group>::Base, + <G as traits::Group>::Scalar, + >>::Constants, shape: &R1CSShape<G>, U1: &R1CSInstance<G>, W1: &R1CSWitness<G>,

@@ -239,12 +247,12 @@ let mut r_W = RelaxedR1CSWitness::default(shape);

let mut r_U = RelaxedR1CSInstance::default(gens, shape); // produce a step SNARK with (W1, U1) as the first incoming witness-instance pair - let res = StepSNARK::prove(gens, shape, &r_U, &r_W, U1, W1); + let res = StepSNARK::prove(gens, ro_consts, shape, &r_U, &r_W, U1, W1); assert!(res.is_ok()); let (step_snark, (_U, W)) = res.unwrap(); // verify the step SNARK with U1 as the first incoming instance - let res = step_snark.verify(shape, &r_U, U1); + let res = step_snark.verify(ro_consts, shape, &r_U, U1); assert!(res.is_ok()); let U = res.unwrap();

@@ -255,12 +263,12 @@ r_W = W;

r_U = U; // produce a step SNARK with (W2, U2) as the second incoming witness-instance pair - let res = StepSNARK::prove(gens, shape, &r_U, &r_W, U2, W2); + let res = StepSNARK::prove(gens, ro_consts, shape, &r_U, &r_W, U2, W2); assert!(res.is_ok()); let (step_snark, (_U, W)) = res.unwrap(); // verify the step SNARK with U1 as the first incoming instance - let res = step_snark.verify(shape, &r_U, U2); + let res = step_snark.verify(ro_consts, shape, &r_U, U2); assert!(res.is_ok()); let U = res.unwrap();

@@ -338,8 +346,12 @@ assert!(res.is_ok());

res.unwrap() }; - // generate generators + // generate generators and ro constants let gens = R1CSGens::new(num_cons, num_vars); + let ro_consts = <<G as Group>::HashFunc as HashFuncTrait< + <G as Group>::Base, + <G as Group>::Scalar, + >>::Constants::new(); let rand_inst_witness_generator = |gens: &R1CSGens<G>, I: &S| -> (S, R1CSInstance<G>, R1CSWitness<G>) {

@@ -382,6 +394,6 @@ let (O, U1, W1) = rand_inst_witness_generator(&gens, &I);

let (_O, U2, W2) = rand_inst_witness_generator(&gens, &O); // execute a sequence of folds - execute_sequence(&gens, &S, &U1, &W1, &U2, &W2); + execute_sequence(&gens, &ro_consts, &S, &U1, &W1, &U2, &W2); } }
M src/traits.rs → src/traits.rs

@@ -89,7 +89,7 @@

/// A helper trait that defines the behavior of a hash function that we use as an RO pub trait HashFuncTrait<Base, Scalar> { /// A type representing constants/parameters associated with the hash function - type Constants: HashFuncConstantsTrait<Base>; + type Constants: HashFuncConstantsTrait<Base> + Clone; /// Initializes the hash function fn new(constants: Self::Constants) -> Self;