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:
iontzialla
2022-05-14 10:56:57 -04:00
committed by GitHub
parent 3193d67bce
commit 9f7c12dbc5
4 changed files with 165 additions and 80 deletions

View File

@@ -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()

View File

@@ -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,

View File

@@ -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 {