mirror of
https://github.com/arnaucube/Nova.git
synced 2026-01-12 09:01:28 +01:00
Base case for second circuit (#60)
* output the incoming instance as the running instance in one of the circuits * Make some verifier circuit inputs optional (for base case)
This commit is contained in:
@@ -29,14 +29,19 @@ where
|
||||
Fp: PrimeField,
|
||||
{
|
||||
/// Allocates a new point on the curve using coordinates provided by `coords`.
|
||||
/// If coords = None, it allocates the default infinity point
|
||||
pub fn alloc<CS>(mut cs: CS, coords: Option<(Fp, Fp, bool)>) -> Result<Self, SynthesisError>
|
||||
where
|
||||
CS: ConstraintSystem<Fp>,
|
||||
{
|
||||
let x = AllocatedNum::alloc(cs.namespace(|| "x"), || Ok(coords.unwrap().0))?;
|
||||
let y = AllocatedNum::alloc(cs.namespace(|| "y"), || Ok(coords.unwrap().1))?;
|
||||
let x = AllocatedNum::alloc(cs.namespace(|| "x"), || {
|
||||
Ok(coords.map_or(Fp::zero(), |c| c.0))
|
||||
})?;
|
||||
let y = AllocatedNum::alloc(cs.namespace(|| "y"), || {
|
||||
Ok(coords.map_or(Fp::zero(), |c| c.0))
|
||||
})?;
|
||||
let is_infinity = AllocatedNum::alloc(cs.namespace(|| "is_infinity"), || {
|
||||
Ok(if coords.unwrap().2 {
|
||||
Ok(if coords.map_or(true, |c| c.2) {
|
||||
Fp::one()
|
||||
} else {
|
||||
Fp::zero()
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::{
|
||||
gadgets::{
|
||||
ecc::AllocatedPoint,
|
||||
utils::{
|
||||
alloc_bignat_constant, alloc_scalar_as_base, conditionally_select,
|
||||
alloc_bignat_constant, alloc_one, alloc_scalar_as_base, conditionally_select,
|
||||
conditionally_select_bignat, le_bits_to_num,
|
||||
},
|
||||
},
|
||||
@@ -114,16 +114,25 @@ where
|
||||
inst.get().map_or(None, |inst| Some(inst.u)),
|
||||
)?;
|
||||
|
||||
// Allocate X0 and X1. If the input instance is None, then allocate default values 0.
|
||||
let X0 = BigNat::alloc_from_nat(
|
||||
cs.namespace(|| "allocate X[0]"),
|
||||
|| Ok(f_to_nat(&inst.get()?.X[0])),
|
||||
|| {
|
||||
Ok(f_to_nat(
|
||||
&inst.clone().map_or(G::Scalar::zero(), |inst| inst.X[0]),
|
||||
))
|
||||
},
|
||||
limb_width,
|
||||
n_limbs,
|
||||
)?;
|
||||
|
||||
let X1 = BigNat::alloc_from_nat(
|
||||
cs.namespace(|| "allocate X[1]"),
|
||||
|| Ok(f_to_nat(&inst.get()?.X[1])),
|
||||
|| {
|
||||
Ok(f_to_nat(
|
||||
&inst.clone().map_or(G::Scalar::zero(), |inst| inst.X[1]),
|
||||
))
|
||||
},
|
||||
limb_width,
|
||||
n_limbs,
|
||||
)?;
|
||||
@@ -160,6 +169,41 @@ where
|
||||
Ok(AllocatedRelaxedR1CSInstance { W, E, u, X0, X1 })
|
||||
}
|
||||
|
||||
/// Allocates the R1CS Instance as a RelaxedR1CSInstance in the circuit.
|
||||
/// E = 0, u = 1
|
||||
pub fn from_r1cs_instance<CS: ConstraintSystem<<G as Group>::Base>>(
|
||||
mut cs: CS,
|
||||
inst: AllocatedR1CSInstance<G>,
|
||||
limb_width: usize,
|
||||
n_limbs: usize,
|
||||
) -> Result<Self, SynthesisError> {
|
||||
let E = AllocatedPoint::default(cs.namespace(|| "allocate W"))?;
|
||||
|
||||
let u = alloc_one(cs.namespace(|| "one"))?;
|
||||
|
||||
let X0 = BigNat::from_num(
|
||||
cs.namespace(|| "allocate X0 from relaxed r1cs"),
|
||||
Num::from(inst.X0.clone()),
|
||||
limb_width,
|
||||
n_limbs,
|
||||
)?;
|
||||
|
||||
let X1 = BigNat::from_num(
|
||||
cs.namespace(|| "allocate X1 from relaxed r1cs"),
|
||||
Num::from(inst.X1.clone()),
|
||||
limb_width,
|
||||
n_limbs,
|
||||
)?;
|
||||
|
||||
Ok(AllocatedRelaxedR1CSInstance {
|
||||
W: inst.W,
|
||||
E,
|
||||
u,
|
||||
X0,
|
||||
X1,
|
||||
})
|
||||
}
|
||||
|
||||
/// Absorb the provided instance in the RO
|
||||
pub fn absorb_in_ro<CS: ConstraintSystem<<G as Group>::Base>>(
|
||||
&self,
|
||||
|
||||
@@ -86,7 +86,7 @@ where
|
||||
CS: ConstraintSystem<<G as Group>::Base>,
|
||||
{
|
||||
AllocatedNum::alloc(cs.namespace(|| "allocate scalar as base"), || {
|
||||
let input_bits = input.get()?.clone().to_le_bits();
|
||||
let input_bits = input.unwrap_or_else(G::Scalar::zero).clone().to_le_bits();
|
||||
let mut mult = G::Base::one();
|
||||
let mut val = G::Base::zero();
|
||||
for bit in input_bits {
|
||||
|
||||
Reference in New Issue
Block a user