mirror of
https://github.com/arnaucube/Nova.git
synced 2026-01-11 16:41:28 +01:00
Abstract the RO used in the circuit with traits (#84)
* cleanup RO usage inside the circuit: use traits * Add a note * rename types for clarity
This commit is contained in:
@@ -15,9 +15,8 @@ use super::{
|
||||
alloc_num_equals, alloc_scalar_as_base, alloc_zero, conditionally_select, le_bits_to_num,
|
||||
},
|
||||
},
|
||||
poseidon::{PoseidonROGadget, ROConstantsCircuit},
|
||||
r1cs::{R1CSInstance, RelaxedR1CSInstance},
|
||||
traits::{Group, StepCircuit},
|
||||
traits::{Group, HashFuncCircuitTrait, HashFuncConstantsCircuit, StepCircuit},
|
||||
};
|
||||
use bellperson::{
|
||||
gadgets::{
|
||||
@@ -91,7 +90,7 @@ where
|
||||
SC: StepCircuit<G::Base>,
|
||||
{
|
||||
params: NIFSVerifierCircuitParams,
|
||||
ro_consts: ROConstantsCircuit<G::Base>,
|
||||
ro_consts: HashFuncConstantsCircuit<G>,
|
||||
inputs: Option<NIFSVerifierCircuitInputs<G>>,
|
||||
step_circuit: SC, // The function that is applied for each step
|
||||
}
|
||||
@@ -106,7 +105,7 @@ where
|
||||
params: NIFSVerifierCircuitParams,
|
||||
inputs: Option<NIFSVerifierCircuitInputs<G>>,
|
||||
step_circuit: SC,
|
||||
ro_consts: ROConstantsCircuit<G::Base>,
|
||||
ro_consts: HashFuncConstantsCircuit<G>,
|
||||
) -> Self {
|
||||
Self {
|
||||
params,
|
||||
@@ -221,7 +220,7 @@ where
|
||||
T: AllocatedPoint<G::Base>,
|
||||
) -> Result<(AllocatedRelaxedR1CSInstance<G>, AllocatedBit), SynthesisError> {
|
||||
// Check that u.x[0] = Hash(params, U, i, z0, zi)
|
||||
let mut ro: PoseidonROGadget<G::Base> = PoseidonROGadget::new(self.ro_consts.clone());
|
||||
let mut ro = G::HashFuncCircuit::new(self.ro_consts.clone());
|
||||
ro.absorb(params.clone());
|
||||
ro.absorb(i);
|
||||
ro.absorb(z_0);
|
||||
@@ -328,7 +327,7 @@ where
|
||||
.synthesize(&mut cs.namespace(|| "F"), z_input)?;
|
||||
|
||||
// Compute the new hash H(params, Unew, i+1, z0, z_{i+1})
|
||||
let mut ro: PoseidonROGadget<G::Base> = PoseidonROGadget::new(self.ro_consts);
|
||||
let mut ro = G::HashFuncCircuit::new(self.ro_consts);
|
||||
ro.absorb(params);
|
||||
ro.absorb(i_new.clone());
|
||||
ro.absorb(z_0);
|
||||
@@ -356,6 +355,7 @@ mod tests {
|
||||
use crate::constants::{BN_LIMB_WIDTH, BN_N_LIMBS};
|
||||
use crate::{
|
||||
bellperson::r1cs::{NovaShape, NovaWitness},
|
||||
poseidon::PoseidonConstantsCircuit,
|
||||
traits::HashFuncConstantsTrait,
|
||||
};
|
||||
use ff::PrimeField;
|
||||
@@ -388,8 +388,8 @@ mod tests {
|
||||
// In the following we use 1 to refer to the primary, and 2 to refer to the secondary circuit
|
||||
let params1 = NIFSVerifierCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true);
|
||||
let params2 = NIFSVerifierCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false);
|
||||
let ro_consts1: ROConstantsCircuit<<G2 as Group>::Base> = ROConstantsCircuit::new();
|
||||
let ro_consts2: ROConstantsCircuit<<G1 as Group>::Base> = ROConstantsCircuit::new();
|
||||
let ro_consts1: HashFuncConstantsCircuit<G2> = PoseidonConstantsCircuit::new();
|
||||
let ro_consts2: HashFuncConstantsCircuit<G1> = PoseidonConstantsCircuit::new();
|
||||
|
||||
// Initialize the shape and gens for the primary
|
||||
let circuit1: NIFSVerifierCircuit<G2, TestCircuit<<G2 as Group>::Base>> =
|
||||
|
||||
@@ -7,9 +7,8 @@ use crate::{
|
||||
conditionally_select_bignat, le_bits_to_num,
|
||||
},
|
||||
},
|
||||
poseidon::{PoseidonROGadget, ROConstantsCircuit},
|
||||
r1cs::{R1CSInstance, RelaxedR1CSInstance},
|
||||
traits::Group,
|
||||
traits::{Group, HashFuncCircuitTrait, HashFuncConstantsCircuit},
|
||||
};
|
||||
use bellperson::{
|
||||
gadgets::{boolean::Boolean, num::AllocatedNum, Assignment},
|
||||
@@ -61,7 +60,7 @@ where
|
||||
}
|
||||
|
||||
/// Absorb the provided instance in the RO
|
||||
pub fn absorb_in_ro(&self, ro: &mut PoseidonROGadget<G::Base>) {
|
||||
pub fn absorb_in_ro(&self, ro: &mut G::HashFuncCircuit) {
|
||||
ro.absorb(self.W.x.clone());
|
||||
ro.absorb(self.W.y.clone());
|
||||
ro.absorb(self.W.is_infinity.clone());
|
||||
@@ -208,7 +207,7 @@ where
|
||||
pub fn absorb_in_ro<CS: ConstraintSystem<<G as Group>::Base>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
ro: &mut PoseidonROGadget<G::Base>,
|
||||
ro: &mut G::HashFuncCircuit,
|
||||
) -> Result<(), SynthesisError> {
|
||||
ro.absorb(self.W.x.clone());
|
||||
ro.absorb(self.W.y.clone());
|
||||
@@ -263,12 +262,12 @@ where
|
||||
params: AllocatedNum<G::Base>, // hash of R1CSShape of F'
|
||||
u: AllocatedR1CSInstance<G>,
|
||||
T: AllocatedPoint<G::Base>,
|
||||
ro_consts: ROConstantsCircuit<G::Base>,
|
||||
ro_consts: HashFuncConstantsCircuit<G>,
|
||||
limb_width: usize,
|
||||
n_limbs: usize,
|
||||
) -> Result<AllocatedRelaxedR1CSInstance<G>, SynthesisError> {
|
||||
// Compute r:
|
||||
let mut ro: PoseidonROGadget<G::Base> = PoseidonROGadget::new(ro_consts);
|
||||
let mut ro = G::HashFuncCircuit::new(ro_consts);
|
||||
ro.absorb(params);
|
||||
self.absorb_in_ro(cs.namespace(|| "absorb running instance"), &mut ro)?;
|
||||
u.absorb_in_ro(&mut ro);
|
||||
|
||||
46
src/lib.rs
46
src/lib.rs
@@ -33,31 +33,30 @@ use errors::NovaError;
|
||||
use ff::Field;
|
||||
use gadgets::utils::scalar_as_base;
|
||||
use nifs::NIFS;
|
||||
use poseidon::ROConstantsCircuit; // TODO: make this a trait so we can use it without the concrete implementation
|
||||
use r1cs::{
|
||||
R1CSGens, R1CSInstance, R1CSShape, R1CSWitness, RelaxedR1CSInstance, RelaxedR1CSWitness,
|
||||
};
|
||||
use snark::RelaxedR1CSSNARKTrait;
|
||||
use traits::{AbsorbInROTrait, Group, HashFuncConstantsTrait, HashFuncTrait, StepCircuit};
|
||||
|
||||
type ROConstants<G> =
|
||||
<<G as Group>::HashFunc as HashFuncTrait<<G as Group>::Base, <G as Group>::Scalar>>::Constants;
|
||||
use traits::{
|
||||
AbsorbInROTrait, Group, HashFuncConstants, HashFuncConstantsCircuit, HashFuncConstantsTrait,
|
||||
HashFuncTrait, StepCircuit,
|
||||
};
|
||||
|
||||
/// A type that holds public parameters of Nova
|
||||
pub struct PublicParams<G1, G2, C1, C2>
|
||||
where
|
||||
G1: Group<Base = <G2 as Group>::Scalar>,
|
||||
G2: Group<Base = <G1 as Group>::Scalar>,
|
||||
C1: StepCircuit<G1::Scalar> + Clone,
|
||||
C2: StepCircuit<G2::Scalar> + Clone,
|
||||
C1: StepCircuit<G1::Scalar>,
|
||||
C2: StepCircuit<G2::Scalar>,
|
||||
{
|
||||
ro_consts_primary: ROConstants<G1>,
|
||||
ro_consts_circuit_primary: ROConstantsCircuit<<G2 as Group>::Base>,
|
||||
ro_consts_primary: HashFuncConstants<G1>,
|
||||
ro_consts_circuit_primary: HashFuncConstantsCircuit<G2>,
|
||||
r1cs_gens_primary: R1CSGens<G1>,
|
||||
r1cs_shape_primary: R1CSShape<G1>,
|
||||
r1cs_shape_padded_primary: R1CSShape<G1>,
|
||||
ro_consts_secondary: ROConstants<G2>,
|
||||
ro_consts_circuit_secondary: ROConstantsCircuit<<G1 as Group>::Base>,
|
||||
ro_consts_secondary: HashFuncConstants<G2>,
|
||||
ro_consts_circuit_secondary: HashFuncConstantsCircuit<G1>,
|
||||
r1cs_gens_secondary: R1CSGens<G2>,
|
||||
r1cs_shape_secondary: R1CSShape<G2>,
|
||||
r1cs_shape_padded_secondary: R1CSShape<G2>,
|
||||
@@ -71,21 +70,22 @@ impl<G1, G2, C1, C2> PublicParams<G1, G2, C1, C2>
|
||||
where
|
||||
G1: Group<Base = <G2 as Group>::Scalar>,
|
||||
G2: Group<Base = <G1 as Group>::Scalar>,
|
||||
C1: StepCircuit<G1::Scalar> + Clone,
|
||||
C2: StepCircuit<G2::Scalar> + Clone,
|
||||
C1: StepCircuit<G1::Scalar>,
|
||||
C2: StepCircuit<G2::Scalar>,
|
||||
{
|
||||
/// Create a new `PublicParams`
|
||||
pub fn setup(c_primary: C1, c_secondary: C2) -> Self {
|
||||
let params_primary = NIFSVerifierCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true);
|
||||
let params_secondary = NIFSVerifierCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false);
|
||||
|
||||
let ro_consts_primary: ROConstants<G1> = ROConstants::<G1>::new();
|
||||
let ro_consts_secondary: ROConstants<G2> = ROConstants::<G2>::new();
|
||||
let ro_consts_primary: HashFuncConstants<G1> = HashFuncConstants::<G1>::new();
|
||||
let ro_consts_secondary: HashFuncConstants<G2> = HashFuncConstants::<G2>::new();
|
||||
|
||||
let ro_consts_circuit_primary: ROConstantsCircuit<<G2 as Group>::Base> =
|
||||
ROConstantsCircuit::new();
|
||||
let ro_consts_circuit_secondary: ROConstantsCircuit<<G1 as Group>::Base> =
|
||||
ROConstantsCircuit::new();
|
||||
// ro_consts_circuit_primart are parameterized by G2 because the type alias uses G2::Base = G1::Scalar
|
||||
let ro_consts_circuit_primary: HashFuncConstantsCircuit<G2> =
|
||||
HashFuncConstantsCircuit::<G2>::new();
|
||||
let ro_consts_circuit_secondary: HashFuncConstantsCircuit<G1> =
|
||||
HashFuncConstantsCircuit::<G1>::new();
|
||||
|
||||
// Initialize gens for the primary
|
||||
let circuit_primary: NIFSVerifierCircuit<G2, C1> = NIFSVerifierCircuit::new(
|
||||
@@ -135,8 +135,8 @@ pub struct RecursiveSNARK<G1, G2, C1, C2>
|
||||
where
|
||||
G1: Group<Base = <G2 as Group>::Scalar>,
|
||||
G2: Group<Base = <G1 as Group>::Scalar>,
|
||||
C1: StepCircuit<G1::Scalar> + Clone,
|
||||
C2: StepCircuit<G2::Scalar> + Clone,
|
||||
C1: StepCircuit<G1::Scalar>,
|
||||
C2: StepCircuit<G2::Scalar>,
|
||||
{
|
||||
r_W_primary: RelaxedR1CSWitness<G1>,
|
||||
r_U_primary: RelaxedR1CSInstance<G1>,
|
||||
@@ -156,8 +156,8 @@ impl<G1, G2, C1, C2> RecursiveSNARK<G1, G2, C1, C2>
|
||||
where
|
||||
G1: Group<Base = <G2 as Group>::Scalar>,
|
||||
G2: Group<Base = <G1 as Group>::Scalar>,
|
||||
C1: StepCircuit<G1::Scalar> + Clone,
|
||||
C2: StepCircuit<G2::Scalar> + Clone,
|
||||
C1: StepCircuit<G1::Scalar>,
|
||||
C2: StepCircuit<G2::Scalar>,
|
||||
{
|
||||
/// Create a new `RecursiveSNARK`
|
||||
pub fn prove(
|
||||
|
||||
@@ -17,7 +17,7 @@ pub struct NIFS<G: Group> {
|
||||
_p: PhantomData<G>,
|
||||
}
|
||||
|
||||
type ROConstants<G> =
|
||||
type HashFuncConstants<G> =
|
||||
<<G as Group>::HashFunc as HashFuncTrait<<G as Group>::Base, <G as Group>::Scalar>>::Constants;
|
||||
|
||||
impl<G: Group> NIFS<G> {
|
||||
@@ -29,7 +29,7 @@ impl<G: Group> NIFS<G> {
|
||||
/// if and only if `W1` satisfies `U1` and `W2` satisfies `U2`.
|
||||
pub fn prove(
|
||||
gens: &R1CSGens<G>,
|
||||
ro_consts: &ROConstants<G>,
|
||||
ro_consts: &HashFuncConstants<G>,
|
||||
S: &R1CSShape<G>,
|
||||
U1: &RelaxedR1CSInstance<G>,
|
||||
W1: &RelaxedR1CSWitness<G>,
|
||||
@@ -78,7 +78,7 @@ impl<G: Group> NIFS<G> {
|
||||
/// if and only if `U1` and `U2` are satisfiable.
|
||||
pub fn verify(
|
||||
&self,
|
||||
ro_consts: &ROConstants<G>,
|
||||
ro_consts: &HashFuncConstants<G>,
|
||||
S: &R1CSShape<G>,
|
||||
U1: &RelaxedR1CSInstance<G>,
|
||||
U2: &R1CSInstance<G>,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! This module implements the Nova traits for pallas::Point, pallas::Scalar, vesta::Point, vesta::Scalar.
|
||||
use crate::{
|
||||
poseidon::PoseidonRO,
|
||||
poseidon::{PoseidonHashFunc, PoseidonHashFuncCircuit},
|
||||
traits::{ChallengeTrait, CompressedGroup, Group},
|
||||
};
|
||||
use digest::{ExtendableOutput, Input};
|
||||
@@ -40,7 +40,8 @@ impl Group for pallas::Point {
|
||||
type Scalar = pallas::Scalar;
|
||||
type CompressedGroupElement = PallasCompressedElementWrapper;
|
||||
type PreprocessedGroupElement = pallas::Affine;
|
||||
type HashFunc = PoseidonRO<Self::Base, Self::Scalar>;
|
||||
type HashFunc = PoseidonHashFunc<Self::Base, Self::Scalar>;
|
||||
type HashFuncCircuit = PoseidonHashFuncCircuit<Self::Base>;
|
||||
|
||||
fn vartime_multiscalar_mul(
|
||||
scalars: &[Self::Scalar],
|
||||
@@ -137,7 +138,8 @@ impl Group for vesta::Point {
|
||||
type Scalar = vesta::Scalar;
|
||||
type CompressedGroupElement = VestaCompressedElementWrapper;
|
||||
type PreprocessedGroupElement = vesta::Affine;
|
||||
type HashFunc = PoseidonRO<Self::Base, Self::Scalar>;
|
||||
type HashFunc = PoseidonHashFunc<Self::Base, Self::Scalar>;
|
||||
type HashFuncCircuit = PoseidonHashFuncCircuit<Self::Base>;
|
||||
|
||||
fn vartime_multiscalar_mul(
|
||||
scalars: &[Self::Scalar],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Poseidon Constants and Poseidon-based RO used in Nova
|
||||
use super::{
|
||||
constants::{NUM_CHALLENGE_BITS, NUM_HASH_BITS},
|
||||
traits::{HashFuncConstantsTrait, HashFuncTrait},
|
||||
traits::{HashFuncCircuitTrait, HashFuncConstantsTrait, HashFuncTrait},
|
||||
};
|
||||
use bellperson::{
|
||||
gadgets::{
|
||||
@@ -21,7 +21,7 @@ use neptune::{
|
||||
|
||||
/// All Poseidon Constants that are used in Nova
|
||||
#[derive(Clone)]
|
||||
pub struct ROConstantsCircuit<Scalar>
|
||||
pub struct PoseidonConstantsCircuit<Scalar>
|
||||
where
|
||||
Scalar: PrimeField,
|
||||
{
|
||||
@@ -29,7 +29,7 @@ where
|
||||
constants32: PoseidonConstants<Scalar, U32>,
|
||||
}
|
||||
|
||||
impl<Scalar> HashFuncConstantsTrait<Scalar> for ROConstantsCircuit<Scalar>
|
||||
impl<Scalar> HashFuncConstantsTrait<Scalar> for PoseidonConstantsCircuit<Scalar>
|
||||
where
|
||||
Scalar: PrimeField + PrimeFieldBits,
|
||||
{
|
||||
@@ -46,7 +46,7 @@ where
|
||||
}
|
||||
|
||||
/// A Poseidon-based RO to use outside circuits
|
||||
pub struct PoseidonRO<Base, Scalar>
|
||||
pub struct PoseidonHashFunc<Base, Scalar>
|
||||
where
|
||||
Base: PrimeField + PrimeFieldBits,
|
||||
Scalar: PrimeField + PrimeFieldBits,
|
||||
@@ -54,11 +54,11 @@ where
|
||||
// Internal State
|
||||
state: Vec<Base>,
|
||||
// Constants for Poseidon
|
||||
constants: ROConstantsCircuit<Base>,
|
||||
constants: PoseidonConstantsCircuit<Base>,
|
||||
_p: PhantomData<Scalar>,
|
||||
}
|
||||
|
||||
impl<Base, Scalar> PoseidonRO<Base, Scalar>
|
||||
impl<Base, Scalar> PoseidonHashFunc<Base, Scalar>
|
||||
where
|
||||
Base: PrimeField + PrimeFieldBits,
|
||||
Scalar: PrimeField + PrimeFieldBits,
|
||||
@@ -81,14 +81,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Base, Scalar> HashFuncTrait<Base, Scalar> for PoseidonRO<Base, Scalar>
|
||||
impl<Base, Scalar> HashFuncTrait<Base, Scalar> for PoseidonHashFunc<Base, Scalar>
|
||||
where
|
||||
Base: PrimeField + PrimeFieldBits,
|
||||
Scalar: PrimeField + PrimeFieldBits,
|
||||
{
|
||||
type Constants = ROConstantsCircuit<Base>;
|
||||
type Constants = PoseidonConstantsCircuit<Base>;
|
||||
|
||||
fn new(constants: ROConstantsCircuit<Base>) -> Self {
|
||||
fn new(constants: PoseidonConstantsCircuit<Base>) -> Self {
|
||||
Self {
|
||||
state: Vec::new(),
|
||||
constants,
|
||||
@@ -134,32 +134,19 @@ where
|
||||
}
|
||||
|
||||
/// A Poseidon-based RO gadget to use inside the verifier circuit.
|
||||
pub struct PoseidonROGadget<Scalar>
|
||||
pub struct PoseidonHashFuncCircuit<Scalar>
|
||||
where
|
||||
Scalar: PrimeField + PrimeFieldBits,
|
||||
{
|
||||
// Internal state
|
||||
state: Vec<AllocatedNum<Scalar>>,
|
||||
constants: ROConstantsCircuit<Scalar>,
|
||||
constants: PoseidonConstantsCircuit<Scalar>,
|
||||
}
|
||||
|
||||
impl<Scalar> PoseidonROGadget<Scalar>
|
||||
impl<Scalar> PoseidonHashFuncCircuit<Scalar>
|
||||
where
|
||||
Scalar: PrimeField + PrimeFieldBits,
|
||||
{
|
||||
/// Initialize the internal state and set the poseidon constants
|
||||
pub fn new(constants: ROConstantsCircuit<Scalar>) -> Self {
|
||||
Self {
|
||||
state: Vec::new(),
|
||||
constants,
|
||||
}
|
||||
}
|
||||
|
||||
/// Absorb a new number into the state of the oracle
|
||||
pub fn absorb(&mut self, e: AllocatedNum<Scalar>) {
|
||||
self.state.push(e);
|
||||
}
|
||||
|
||||
fn hash_inner<CS>(&mut self, mut cs: CS) -> Result<Vec<AllocatedBit>, SynthesisError>
|
||||
where
|
||||
CS: ConstraintSystem<Scalar>,
|
||||
@@ -195,9 +182,29 @@ where
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Scalar> HashFuncCircuitTrait<Scalar> for PoseidonHashFuncCircuit<Scalar>
|
||||
where
|
||||
Scalar: PrimeField + PrimeFieldBits,
|
||||
{
|
||||
type Constants = PoseidonConstantsCircuit<Scalar>;
|
||||
|
||||
/// Initialize the internal state and set the poseidon constants
|
||||
fn new(constants: PoseidonConstantsCircuit<Scalar>) -> Self {
|
||||
Self {
|
||||
state: Vec::new(),
|
||||
constants,
|
||||
}
|
||||
}
|
||||
|
||||
/// Absorb a new number into the state of the oracle
|
||||
fn absorb(&mut self, e: AllocatedNum<Scalar>) {
|
||||
self.state.push(e);
|
||||
}
|
||||
|
||||
/// Compute a challenge by hashing the current state
|
||||
pub fn get_challenge<CS>(&mut self, mut cs: CS) -> Result<Vec<AllocatedBit>, SynthesisError>
|
||||
fn get_challenge<CS>(&mut self, mut cs: CS) -> Result<Vec<AllocatedBit>, SynthesisError>
|
||||
where
|
||||
CS: ConstraintSystem<Scalar>,
|
||||
{
|
||||
@@ -205,7 +212,7 @@ where
|
||||
Ok(bits[..NUM_CHALLENGE_BITS].into())
|
||||
}
|
||||
|
||||
pub fn get_hash<CS>(&mut self, mut cs: CS) -> Result<Vec<AllocatedBit>, SynthesisError>
|
||||
fn get_hash<CS>(&mut self, mut cs: CS) -> Result<Vec<AllocatedBit>, SynthesisError>
|
||||
where
|
||||
CS: ConstraintSystem<Scalar>,
|
||||
{
|
||||
@@ -228,9 +235,9 @@ mod tests {
|
||||
fn test_poseidon_ro() {
|
||||
// Check that the number computed inside the circuit is equal to the number computed outside the circuit
|
||||
let mut csprng: OsRng = OsRng;
|
||||
let constants = ROConstantsCircuit::new();
|
||||
let mut ro: PoseidonRO<S, B> = PoseidonRO::new(constants.clone());
|
||||
let mut ro_gadget: PoseidonROGadget<S> = PoseidonROGadget::new(constants);
|
||||
let constants = PoseidonConstantsCircuit::new();
|
||||
let mut ro: PoseidonHashFunc<S, B> = PoseidonHashFunc::new(constants.clone());
|
||||
let mut ro_gadget: PoseidonHashFuncCircuit<S> = PoseidonHashFuncCircuit::new(constants);
|
||||
let mut cs: SatisfyingAssignment<G> = SatisfyingAssignment::new();
|
||||
for i in 0..27 {
|
||||
let num = S::random(&mut csprng);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
//! This module defines various traits required by the users of the library to implement.
|
||||
use bellperson::{gadgets::num::AllocatedNum, ConstraintSystem, SynthesisError};
|
||||
use bellperson::{
|
||||
gadgets::{boolean::AllocatedBit, num::AllocatedNum},
|
||||
ConstraintSystem, SynthesisError,
|
||||
};
|
||||
use core::{
|
||||
fmt::Debug,
|
||||
ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign},
|
||||
@@ -38,6 +41,9 @@ pub trait Group:
|
||||
/// from the base field and squeezes out elements of the scalar field
|
||||
type HashFunc: HashFuncTrait<Self::Base, Self::Scalar>;
|
||||
|
||||
/// An alternate implementation of Self::HashFunc in the circuit model
|
||||
type HashFuncCircuit: HashFuncCircuitTrait<Self::Base>;
|
||||
|
||||
/// A method to compute a multiexponentation
|
||||
fn vartime_multiscalar_mul(
|
||||
scalars: &[Self::Scalar],
|
||||
@@ -108,12 +114,42 @@ pub trait HashFuncTrait<Base, Scalar> {
|
||||
fn get_hash(&self) -> Scalar;
|
||||
}
|
||||
|
||||
/// A helper trait that defines the behavior of a hash function that we use as an RO in the circuit model
|
||||
pub trait HashFuncCircuitTrait<Base: PrimeField> {
|
||||
/// A type representing constants/parameters associated with the hash function
|
||||
type Constants: HashFuncConstantsTrait<Base> + Clone + Send + Sync;
|
||||
|
||||
/// Initializes the hash function
|
||||
fn new(constants: Self::Constants) -> Self;
|
||||
|
||||
/// Adds a scalar to the internal state
|
||||
fn absorb(&mut self, e: AllocatedNum<Base>);
|
||||
|
||||
/// Returns a random challenge by hashing the internal state
|
||||
fn get_challenge<CS>(&mut self, cs: CS) -> Result<Vec<AllocatedBit>, SynthesisError>
|
||||
where
|
||||
CS: ConstraintSystem<Base>;
|
||||
|
||||
/// Returns a hash of the internal state
|
||||
fn get_hash<CS>(&mut self, cs: CS) -> Result<Vec<AllocatedBit>, SynthesisError>
|
||||
where
|
||||
CS: ConstraintSystem<Base>;
|
||||
}
|
||||
|
||||
/// A helper trait that defines the constants associated with a hash function
|
||||
pub trait HashFuncConstantsTrait<Base> {
|
||||
/// produces constants/parameters associated with the hash function
|
||||
fn new() -> Self;
|
||||
}
|
||||
|
||||
/// An alias for constants associated with G::HashFunc
|
||||
pub type HashFuncConstants<G> =
|
||||
<<G as Group>::HashFunc as HashFuncTrait<<G as Group>::Base, <G as Group>::Scalar>>::Constants;
|
||||
|
||||
/// An alias for constants associated with G::HashFuncCircuit
|
||||
pub type HashFuncConstantsCircuit<G> =
|
||||
<<G as Group>::HashFuncCircuit as HashFuncCircuitTrait<<G as Group>::Base>>::Constants;
|
||||
|
||||
/// A helper trait for types with a group operation.
|
||||
pub trait GroupOps<Rhs = Self, Output = Self>:
|
||||
Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
|
||||
|
||||
Reference in New Issue
Block a user