Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement ecc point compression of the PCD secondary curve #19

Merged
merged 1 commit into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/gadgets/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,24 @@ where
.inputize(cs.namespace(|| "Input point.is_infinity"))?;
Ok(())
}

/// Make the point to compressed io
pub fn compressed_inputize<CS: ConstraintSystem<G::Base>>(
&self,
mut cs: CS,
ecc_parity_manager: &mut Vec<Boolean>,
) -> Result<(), SynthesisError> {
self.x.inputize(cs.namespace(|| "Input point.x"))?;
ecc_parity_manager.push(
self
.y
.to_bits_le_strict(cs.namespace(|| "calc bits"))?
.first()
.unwrap()
.clone(),
);
Ok(())
}
}

#[derive(Clone)]
Expand Down
32 changes: 32 additions & 0 deletions src/gadgets/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,38 @@ where
Ok(num)
}

pub fn from_le_bits_to_num<Scalar, CS>(
mut cs: CS,
bits: &[Boolean],
) -> Result<AllocatedNum<Scalar>, SynthesisError>
where
Scalar: PrimeField + PrimeFieldBits,
CS: ConstraintSystem<Scalar>,
{
// We loop over the input bits and construct the constraint
// and the field element that corresponds to the result
let mut lc = LinearCombination::zero();
let mut coeff = Scalar::ONE;
let mut fe = Some(Scalar::ZERO);
for bit in bits.iter() {
lc = lc + &bit.lc(CS::one(), coeff);
fe = bit.get_value().map(|val| {
if val {
fe.unwrap() + coeff
} else {
fe.unwrap()
}
});
coeff = coeff.double();
}
let num = AllocatedNum::alloc(cs.namespace(|| "Field element"), || {
fe.ok_or(SynthesisError::AssignmentMissing)
})?;
lc = lc - num.get_variable();
cs.enforce(|| "compute number from bits", |lc| lc, |lc| lc, |_| lc);
Ok(num)
}

/// Allocate a variable that is set to zero
pub fn alloc_zero<F: PrimeField, CS: ConstraintSystem<F>>(
mut cs: CS,
Expand Down
1 change: 0 additions & 1 deletion src/nimfs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ pub mod ccs;
pub mod multifolding;
pub mod pcd_aux_circuit;
pub mod pcd_circuit;
pub mod pcd_proof;

pub mod espresso;
pub mod util;
2 changes: 0 additions & 2 deletions src/nimfs/multifolding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,6 @@ impl<C: Group> MultiFolding<C> {
new_instances: &[CCCS<C>],
proof: Proof<C>,
) -> LCCCS<C> {
// TODO appends to transcript

assert!(!running_instances.is_empty());
assert!(!new_instances.is_empty());

Expand Down
23 changes: 19 additions & 4 deletions src/nimfs/pcd_aux_circuit.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::compute_digest;
use crate::gadgets::cccs::{AllocatedCCCSSecondPart, AllocatedLCCCSSecondPart};
use crate::gadgets::utils::from_le_bits_to_num;
use crate::nimfs::ccs::cccs::CCCS;
use crate::nimfs::ccs::lcccs::LCCCS;
use crate::r1cs::R1CSShape;
Expand Down Expand Up @@ -133,16 +134,30 @@ impl<G: Group> NovaAuxiliarySecondCircuit<G> {
&rho,
)?;

// TODO: compress ecc point to x0, x1, x2, ... , ys_parity(the bit that expresses the parity of all y encode to element)
// public input
let mut ecc_parity_container = Vec::new();
rho.inputize(cs.namespace(|| "pub rho"))?;
for (i, x) in lcccs.into_iter().enumerate() {
x.C.inputize(cs.namespace(|| format!("{i}th lcccs")))?;
let mut cs = cs.namespace(|| format!("{i}th lcccs"));
x.C.check_on_curve(cs.namespace(|| "check C on curve"))?;
x.C
.compressed_inputize(cs.namespace(|| "input C"), &mut ecc_parity_container)?;
}
for (i, x) in cccs.into_iter().enumerate() {
x.C.inputize(cs.namespace(|| format!("{i}th cccs")))?;
let mut cs = cs.namespace(|| format!("{i}th cccs"));
x.C.check_on_curve(cs.namespace(|| "check C on curve"))?;
x.C
.compressed_inputize(cs.namespace(|| "input C"), &mut ecc_parity_container)?;
}
new_lcccs.C.inputize(cs.namespace(|| "pub new lcccs"))?;
new_lcccs
.C
.compressed_inputize(cs.namespace(|| "pub new lcccs"), &mut ecc_parity_container)?;

let ecc_compression_num = from_le_bits_to_num(
cs.namespace(|| "alloc ecc_compression_num"),
&ecc_parity_container,
)?;
ecc_compression_num.inputize(cs.namespace(|| "pub ecc_compression_num"))?;

Ok(())
}
Expand Down
1 change: 0 additions & 1 deletion src/nimfs/pcd_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,6 @@ where
) -> Result<AllocatedRelaxedR1CSInstance<G>, SynthesisError> {
assert!(!U.is_empty());
// Compute r
let _num_for_ro = 1 + 2 * (3 + 3 + 1 + 2 * self.params.n_limbs);
let mut ro = G::ROCircuit::new(self.ro_consts.clone(), 0);
ro.absorb(params);
for (i, U) in U.iter().enumerate() {
Expand Down
19 changes: 0 additions & 19 deletions src/nimfs/pcd_proof.rs

This file was deleted.

12 changes: 6 additions & 6 deletions src/pcd_compressed_snark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ where
pub(crate) ck_secondary: CommitmentKey<G2>,
pub(crate) primary_circuit_params: PCDUnitParams<G1, ARITY, R>,
pub(crate) secondary_circuit_params: NovaAuxiliaryParams<G2>,
// digest: G1::Scalar, // digest of everything else with this field set to G1::Scalar::ZERO
pub(crate) _p_c: PhantomData<SC>,
}

Expand All @@ -59,7 +58,7 @@ where
let _ = aux_circuit_setup.synthesize(&mut cs_aux_helper);
let (aux_r1cs_shape, ck_secondary) = cs_aux_helper.r1cs_shape();

let secondary_circuit_params = NovaAuxiliaryParams::new(aux_r1cs_shape, 6 * R + 4);
let secondary_circuit_params = NovaAuxiliaryParams::new(aux_r1cs_shape, R * 2 + 3);

// find eligible s and s_prime for satisfy PCD primary circuit
let (mut s, mut s_prime) = (16, 16);
Expand Down Expand Up @@ -180,6 +179,7 @@ where
digest: G1::Scalar,
vk_primary: S1::VerifierKey,
vk_secondary: S2::VerifierKey,
secondary_io_num: usize,
}

/// A SNARK that proves the knowledge of a valid `RecursiveSNARK`
Expand Down Expand Up @@ -235,6 +235,7 @@ where
digest: pp.primary_circuit_params.digest,
vk_primary,
vk_secondary,
secondary_io_num: pp.secondary_circuit_params.io_num,
};

Ok((pk, vk))
Expand Down Expand Up @@ -292,9 +293,9 @@ where
z0_primary: Vec<G1::Scalar>,
) -> Result<Vec<G1::Scalar>, NovaError> {
// check if the instances have two public outputs
if self.r_u_primary.x.len() != 1
|| self.r_U_primary.x.len() != 1
|| self.r_U_secondary.X.len() != 6 * R + 4
if self.r_u_primary.x.len() != ARITY
|| self.r_U_primary.x.len() != ARITY
|| self.r_U_secondary.X.len() != vk.secondary_io_num
{
return Err(NovaError::InvalidInputLength);
}
Expand Down Expand Up @@ -393,7 +394,6 @@ mod test {
let default_relaxed_r1cs_witness =
RelaxedR1CSWitness::<G2>::default(&pp.secondary_circuit_params.r1cs_shape);

println!("Creating PCD node1");
let node_1 = PCDNode::<G1, G2, IO_NUM, R>::new(
vec![default_lcccs.clone(), default_lcccs],
vec![default_cccs.clone(), default_cccs],
Expand Down
5 changes: 4 additions & 1 deletion src/pcd_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,10 @@ where
W: &RelaxedR1CSWitness<G2>,
) -> Result<Vec<G1::Scalar>, NovaError> {
println!("================================PCD verify===================================");
if U.X.len() != 6 * R + 4 && lcccs.x.len() != 1 && cccs.x.len() != 1 {
if U.X.len() != pp.secondary_circuit_params.io_num
|| lcccs.x.len() != ARITY
|| cccs.x.len() != ARITY
{
return Err(NovaError::ProofVerifyError);
}

Expand Down
7 changes: 1 addition & 6 deletions src/r1cs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use crate::{
use core::{cmp::max, marker::PhantomData};
use ff::Field;

use crate::nimfs::ccs::ccs::CCS;
use rayon::prelude::*;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -152,7 +151,7 @@ impl<G: Group> R1CSShape<G> {
pub(crate) fn check_regular_shape(&self) {
assert_eq!(self.num_cons.next_power_of_two(), self.num_cons);
assert_eq!(self.num_vars.next_power_of_two(), self.num_vars);
assert_eq!(self.num_io.next_power_of_two(), self.num_io);
// assert_eq!(self.num_io.next_power_of_two(), self.num_io);
assert!(self.num_io < self.num_vars);
}

Expand Down Expand Up @@ -422,10 +421,6 @@ impl<G: Group> R1CSShape<G> {
C: C_padded,
}
}

pub fn to_cccs(&self) -> CCS<G> {
todo!()
}
}

impl<G: Group> R1CSWitness<G> {
Expand Down
Loading