use ark_crypto_primitives::sponge::Absorb; use ark_ec::{CurveGroup, Group}; use ark_ff::{Field, PrimeField}; use std::marker::PhantomData; use ark_crypto_primitives::sponge::poseidon::{PoseidonConfig, PoseidonSponge}; use ark_r1cs_std::{groups::GroupOpsBounds, prelude::CurveVar}; use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}; use crate::circuits::{AugmentedFCircuit, ConstraintF}; use crate::nifs::{FWit, Phi, NIFS, R1CS}; use crate::pedersen::{Commitment, Params as PedersenParams, Pedersen, Proof as PedersenProof}; use crate::transcript::Transcript; use ark_std::{One, Zero}; use core::ops::Deref; pub struct IVCProof { phi: Phi, // w: FWit, w: Vec, phiBig: Phi, // W: FWit, W: Vec, } pub struct IVC< C1: CurveGroup, GC1: CurveVar>, C2: CurveGroup, GC2: CurveVar>, > where C1: CurveGroup::ScalarField>, C2: CurveGroup::ScalarField>, { _c1: PhantomData, _gc1: PhantomData, _c2: PhantomData, _gc2: PhantomData, pub poseidon_config: PoseidonConfig>, pub pedersen_params_C1: PedersenParams, pub pedersen_params_C2: PedersenParams, } impl< C1: CurveGroup, GC1: CurveVar>, C2: CurveGroup, GC2: CurveVar>, > IVC where for<'a> &'a GC1: GroupOpsBounds<'a, C1, GC1>, for<'a> &'a GC2: GroupOpsBounds<'a, C2, GC2>, C1: CurveGroup::ScalarField>, C2: CurveGroup::ScalarField>, ::ScalarField: Absorb, ::BaseField: Absorb, <::BaseField as Field>::BasePrimeField: Absorb, ::BaseField: PrimeField, // 2 ::ScalarField: Absorb, ::BaseField: Absorb, <::BaseField as Field>::BasePrimeField: Absorb, ::BaseField: PrimeField, { pub fn prove( &self, cs: ConstraintSystemRef>, tr1: &mut Transcript, tr2: &mut Transcript, r1cs: &R1CS, i: C1::ScalarField, z_0: C1::ScalarField, z_i: C1::ScalarField, // phi1: &Phi, // phi2: &Phi, fw1: FWit, fw2: FWit, ) -> Result, SynthesisError> { tr1.get_challenge(); let r = tr2.get_challenge(); // TODO transcript usage is still WIP, will update with expected adds & gets // fold phi_i and phiBig_i let (fw3, phi1, phi2, _T, cmT) = NIFS::::P(tr2, &self.pedersen_params_C2, r, r1cs, fw1, fw2); let phi3 = NIFS::::V(r, &phi1, &phi2, &cmT); // TODO compute z_{i+1} let z_i1 = z_i.clone(); // WIP this will be the actual computed z_{i+1} let c = AugmentedFCircuit:: { _c: PhantomData, _gc: PhantomData, poseidon_config: self.poseidon_config.clone(), i: Some(i), z_0: Some(z_0), z_i: Some(z_i), z_i1: Some(z_i1), phi: Some(phi1), phiBig: Some(phi2), phiOut: Some(phi3.clone()), cmT: Some(cmT.0), r: Some(r), }; c.generate_constraints(cs.clone())?; // get w_{i+1} let cs1 = cs.borrow().unwrap(); let cs2 = cs1.deref(); let w_i1 = cs2.witness_assignment.clone(); let x_i1 = cs2.instance_assignment.clone(); let rW = tr1.get_challenge(); let _ = tr2.get_challenge(); // phi_{i+1} small let phi = Phi:: { cmE: Commitment::(C1::zero()), u: C1::ScalarField::one(), cmW: Pedersen::commit(&self.pedersen_params_C1, &w_i1, &rW), x: x_i1[0], // check if pos 0 is 1 }; Ok(IVCProof { phiBig: phi3, W: fw3.W, phi, // phi_{i+1} w: w_i1, // w_{i+1} }) } }