Skip to content

Commit

Permalink
Feature/nova ivc (#36)
Browse files Browse the repository at this point in the history
* Implement Nova IVC's new & prove_step methods

Implement Nova IVC's new & prove_step methods (without CycleFold part yet)

* transcript.absorb_point err handling, and update C.xy() usage

* add transcript usage to IVC prove, add NovaTranscript trait extending Transcript trait, refactor NIFS.P to allow absorbing in transcript inbetween

* Implement Nova's IVC.V method (without CycleFold part yet)

* clippy lints

* move challenge r computation in-circuit

* reuse computed points with coordinates over CF (non-native) to save constraints in AugmentedFCircuit

(constraint count went down ~6k)

* rm 128 bit constant

* add params to Errors

* Updates from review suggestions. Additionally refactored nova/nifs fold, and rm transcript from nova/IVC.

- Updates from PR suggestions
- Additionally updated:
  - in nova/nifs.rs: reuse folded_committed_instance for verify_folded_instance, computationally is the same, but reusing the same code so avoiding duplication and having an error on one of the two versions.
  - in nova/ivc.rs: remove transcript from IVC (not needed, it uses the RO)
  • Loading branch information
arnaucube authored Nov 24, 2023
1 parent 6d919d7 commit 905ba44
Show file tree
Hide file tree
Showing 15 changed files with 663 additions and 174 deletions.
2 changes: 1 addition & 1 deletion rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.71.1
1.73.0
4 changes: 3 additions & 1 deletion src/constants.rs
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
pub const N_BITS_CHALLENGE: usize = 250;
// used for committed instances hash, so when going to the other curve of the cycle it does not
// overflow the scalar field
pub const N_BITS_HASH: usize = 250;
4 changes: 2 additions & 2 deletions src/decider/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub fn vec_add<F: PrimeField>(
b: &Vec<FpVar<F>>,
) -> Result<Vec<FpVar<F>>, Error> {
if a.len() != b.len() {
return Err(Error::NotSameLength);
return Err(Error::NotSameLength(a.len(), b.len()));
}
let mut r: Vec<FpVar<F>> = vec![FpVar::<F>::zero(); a.len()];
for i in 0..a.len() {
Expand All @@ -68,7 +68,7 @@ pub fn hadamard<F: PrimeField>(
b: &Vec<FpVar<F>>,
) -> Result<Vec<FpVar<F>>, Error> {
if a.len() != b.len() {
return Err(Error::NotSameLength);
return Err(Error::NotSameLength(a.len(), b.len()));
}
let mut r: Vec<FpVar<F>> = vec![FpVar::<F>::zero(); a.len()];
for i in 0..a.len() {
Expand Down
42 changes: 18 additions & 24 deletions src/folding/circuits/nonnative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@ use ark_ff::PrimeField;
use ark_r1cs_std::fields::nonnative::{params::OptimizationType, AllocatedNonNativeFieldVar};
use ark_r1cs_std::{
alloc::{AllocVar, AllocationMode},
fields::nonnative::NonNativeFieldVar,
fields::{fp::FpVar, nonnative::NonNativeFieldVar},
ToConstraintFieldGadget,
};
use ark_relations::r1cs::{Namespace, SynthesisError};
use ark_std::{One, Zero};
use core::borrow::Borrow;

/// NonNativeAffineVar represents an elliptic curve point in Affine represenation in the non-native
/// field. It is not intended to perform operations, but just to contain the affine coordinates in
/// order to perform hash operations of the point.
/// field, over the constraint field. It is not intended to perform operations, but just to contain
/// the affine coordinates in order to perform hash operations of the point.
#[derive(Debug, Clone)]
pub struct NonNativeAffineVar<F: PrimeField, CF: PrimeField> {
pub x: NonNativeFieldVar<F, CF>,
pub y: NonNativeFieldVar<F, CF>,
pub struct NonNativeAffineVar<F: PrimeField> {
pub x: Vec<FpVar<F>>,
pub y: Vec<FpVar<F>>,
}

impl<C> AllocVar<C, C::ScalarField> for NonNativeAffineVar<C::BaseField, C::ScalarField>
impl<C> AllocVar<C, C::ScalarField> for NonNativeAffineVar<C::ScalarField>
where
C: CurveGroup,
<C as ark_ec::CurveGroup>::BaseField: ark_ff::PrimeField,
Expand All @@ -32,30 +33,23 @@ where
let cs = cs.into();

let affine = val.borrow().into_affine();
if affine.is_zero() {
let x = NonNativeFieldVar::<C::BaseField, C::ScalarField>::new_variable(
cs.clone(),
|| Ok(C::BaseField::zero()),
mode,
)?;
let y = NonNativeFieldVar::<C::BaseField, C::ScalarField>::new_variable(
cs.clone(),
|| Ok(C::BaseField::one()),
mode,
)?;
return Ok(Self { x, y });
let xy_obj = &affine.xy();
let mut xy = (&C::BaseField::zero(), &C::BaseField::one());
if xy_obj.is_some() {
xy = xy_obj.unwrap();
}
let xy = affine.xy().unwrap();
let x = NonNativeFieldVar::<C::BaseField, C::ScalarField>::new_variable(
cs.clone(),
|| Ok(xy.0),
mode,
)?;
)?
.to_constraint_field()?;
let y = NonNativeFieldVar::<C::BaseField, C::ScalarField>::new_variable(
cs.clone(),
|| Ok(xy.1),
mode,
)?;
)?
.to_constraint_field()?;

Ok(Self { x, y })
})
Expand Down Expand Up @@ -101,7 +95,7 @@ where
#[cfg(test)]
mod tests {
use super::*;
use ark_pallas::{Fq, Fr, Projective};
use ark_pallas::{Fr, Projective};
use ark_r1cs_std::alloc::AllocVar;
use ark_relations::r1cs::ConstraintSystem;
use ark_std::Zero;
Expand All @@ -112,6 +106,6 @@ mod tests {

// dealing with the 'zero' point should not panic when doing the unwrap
let p = Projective::zero();
NonNativeAffineVar::<Fq, Fr>::new_witness(cs.clone(), || Ok(p)).unwrap();
NonNativeAffineVar::<Fr>::new_witness(cs.clone(), || Ok(p)).unwrap();
}
}
Loading

0 comments on commit 905ba44

Please sign in to comment.