Browse Source

take ro_constants as a parameter (#58)

main
Srinath Setty 2 years ago
committed by GitHub
parent
commit
36d4be2145
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 17 deletions
  1. +28
    -16
      src/lib.rs
  2. +1
    -1
      src/traits.rs

+ 28
- 16
src/lib.rs

@ -20,7 +20,7 @@ use r1cs::{
R1CSGens, R1CSInstance, R1CSShape, R1CSWitness, RelaxedR1CSInstance, RelaxedR1CSWitness, R1CSGens, R1CSInstance, R1CSShape, R1CSWitness, RelaxedR1CSInstance, RelaxedR1CSWitness,
}; };
use std::marker::PhantomData; 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 /// A SNARK that holds the proof of a step of an incremental computation
pub struct StepSNARK<G: Group> { pub struct StepSNARK<G: Group> {
@ -28,6 +28,9 @@ pub struct StepSNARK {
_p: PhantomData<G>, _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> { impl<G: Group> StepSNARK<G> {
/// Takes as input a Relaxed R1CS instance-witness tuple `(U1, W1)` and /// Takes as input a Relaxed R1CS instance-witness tuple `(U1, W1)` and
/// an R1CS instance-witness tuple `(U2, W2)` with the same structure `shape` /// an R1CS instance-witness tuple `(U2, W2)` with the same structure `shape`
@ -37,6 +40,7 @@ impl StepSNARK {
/// if and only if `W1` satisfies `U1` and `W2` satisfies `U2`. /// if and only if `W1` satisfies `U1` and `W2` satisfies `U2`.
pub fn prove( pub fn prove(
gens: &R1CSGens<G>, gens: &R1CSGens<G>,
ro_consts: &ROConstants<G>,
S: &R1CSShape<G>, S: &R1CSShape<G>,
U1: &RelaxedR1CSInstance<G>, U1: &RelaxedR1CSInstance<G>,
W1: &RelaxedR1CSWitness<G>, W1: &RelaxedR1CSWitness<G>,
@ -50,10 +54,7 @@ impl StepSNARK {
NovaError, NovaError,
> { > {
// initialize a new RO // 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 // append S to the transcript
S.absorb_in_ro(&mut ro); S.absorb_in_ro(&mut ro);
@ -94,15 +95,13 @@ impl StepSNARK {
/// if and only if `U1` and `U2` are satisfiable. /// if and only if `U1` and `U2` are satisfiable.
pub fn verify( pub fn verify(
&self, &self,
ro_consts: &ROConstants<G>,
S: &R1CSShape<G>, S: &R1CSShape<G>,
U1: &RelaxedR1CSInstance<G>, U1: &RelaxedR1CSInstance<G>,
U2: &R1CSInstance<G>, U2: &R1CSInstance<G>,
) -> Result<RelaxedR1CSInstance<G>, NovaError> { ) -> Result<RelaxedR1CSInstance<G>, NovaError> {
// initialize a new RO // 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 // append S to the transcript
S.absorb_in_ro(&mut ro); S.absorb_in_ro(&mut ro);
@ -152,6 +151,7 @@ impl FinalSNARK {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::traits::HashFuncConstantsTrait;
use ::bellperson::{gadgets::num::AllocatedNum, ConstraintSystem, SynthesisError}; use ::bellperson::{gadgets::num::AllocatedNum, ConstraintSystem, SynthesisError};
use ff::{Field, PrimeField}; use ff::{Field, PrimeField};
use rand::rngs::OsRng; use rand::rngs::OsRng;
@ -205,6 +205,10 @@ mod tests {
let _ = synthesize_tiny_r1cs_bellperson(&mut cs, None); let _ = synthesize_tiny_r1cs_bellperson(&mut cs, None);
let shape = cs.r1cs_shape(); let shape = cs.r1cs_shape();
let gens = cs.r1cs_gens(); 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 // Now get the instance and assignment for one instance
let mut cs: SatisfyingAssignment<G> = SatisfyingAssignment::new(); let mut cs: SatisfyingAssignment<G> = SatisfyingAssignment::new();
@ -223,11 +227,15 @@ mod tests {
assert!(shape.is_sat(&gens, &U2, &W2).is_ok()); assert!(shape.is_sat(&gens, &U2, &W2).is_ok());
// execute a sequence of folds // 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( fn execute_sequence(
gens: &R1CSGens<G>, 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>, shape: &R1CSShape<G>,
U1: &R1CSInstance<G>, U1: &R1CSInstance<G>,
W1: &R1CSWitness<G>, W1: &R1CSWitness<G>,
@ -239,12 +247,12 @@ mod tests {
let mut r_U = RelaxedR1CSInstance::default(gens, shape); let mut r_U = RelaxedR1CSInstance::default(gens, shape);
// produce a step SNARK with (W1, U1) as the first incoming witness-instance pair // 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()); assert!(res.is_ok());
let (step_snark, (_U, W)) = res.unwrap(); let (step_snark, (_U, W)) = res.unwrap();
// verify the step SNARK with U1 as the first incoming instance // 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()); assert!(res.is_ok());
let U = res.unwrap(); let U = res.unwrap();
@ -255,12 +263,12 @@ mod tests {
r_U = U; r_U = U;
// produce a step SNARK with (W2, U2) as the second incoming witness-instance pair // 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()); assert!(res.is_ok());
let (step_snark, (_U, W)) = res.unwrap(); let (step_snark, (_U, W)) = res.unwrap();
// verify the step SNARK with U1 as the first incoming instance // 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()); assert!(res.is_ok());
let U = res.unwrap(); let U = res.unwrap();
@ -338,8 +346,12 @@ mod tests {
res.unwrap() res.unwrap()
}; };
// generate generators
// generate generators and ro constants
let gens = R1CSGens::new(num_cons, num_vars); 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 = let rand_inst_witness_generator =
|gens: &R1CSGens<G>, I: &S| -> (S, R1CSInstance<G>, R1CSWitness<G>) { |gens: &R1CSGens<G>, I: &S| -> (S, R1CSInstance<G>, R1CSWitness<G>) {
@ -382,6 +394,6 @@ mod tests {
let (_O, U2, W2) = rand_inst_witness_generator(&gens, &O); let (_O, U2, W2) = rand_inst_witness_generator(&gens, &O);
// execute a sequence of folds // execute a sequence of folds
execute_sequence(&gens, &S, &U1, &W1, &U2, &W2);
execute_sequence(&gens, &ro_consts, &S, &U1, &W1, &U2, &W2);
} }
} }

+ 1
- 1
src/traits.rs

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

Loading…
Cancel
Save