diff --git a/Cargo.toml b/Cargo.toml index e6cafed4..e07a9b89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nova-snark" -version = "0.72.0" +version = "0.73.0" authors = ["Srinath Setty "] edition = "2021" description = "High-speed recursive arguments from folding schemes" diff --git a/src/provider/hyperkzg.rs b/src/provider/hyperkzg.rs index 8a2517b8..406ab58d 100644 --- a/src/provider/hyperkzg.rs +++ b/src/provider/hyperkzg.rs @@ -236,7 +236,8 @@ where { fn to_transcript_bytes(&self) -> Vec { let (x, y, is_infinity) = self.comm.to_coordinates(); - let is_infinity_byte = (!is_infinity).into(); + // Encode the infinity flag as 1 = infinity, matching the RO and in-circuit conventions. + let is_infinity_byte = is_infinity.into(); [ x.to_transcript_bytes(), y.to_transcript_bytes(), @@ -813,10 +814,8 @@ pub struct EvaluationArgument where E::GE: PairingGroup, { - #[serde_as(as = "Vec")] - com: Vec>, - #[serde_as(as = "[EvmCompatSerde; 3]")] - w: [G1Affine; 3], + com: Vec>, + w: [Commitment; 3], #[serde_as(as = "Vec<[EvmCompatSerde; 3]>")] v: Vec<[E::Scalar; 3]>, } @@ -826,15 +825,15 @@ where E::GE: PairingGroup, { /// Create a new evaluation argument - pub fn new(com: Vec>, w: [G1Affine; 3], v: Vec<[E::Scalar; 3]>) -> Self { + pub fn new(com: Vec>, w: [Commitment; 3], v: Vec<[E::Scalar; 3]>) -> Self { Self { com, w, v } } /// The KZG commitments to intermediate polynomials - pub fn com(&self) -> &[G1Affine] { + pub fn com(&self) -> &[Commitment] { &self.com } /// The KZG witnesses for batch openings - pub fn w(&self) -> &[G1Affine] { + pub fn w(&self) -> &[Commitment] { &self.w } /// The evaluations of the polynomials at challenge points @@ -855,7 +854,7 @@ where { // This impl block defines helper functions that are not a part of // EvaluationEngineTrait, but that we will use to implement the trait methods. - fn compute_challenge(com: &[G1Affine], transcript: &mut ::TE) -> E::Scalar { + fn compute_challenge(com: &[Commitment], transcript: &mut ::TE) -> E::Scalar { transcript.absorb(b"c", &com.to_vec().as_slice()); transcript.squeeze(b"c").unwrap() @@ -885,7 +884,10 @@ where q_powers } - fn verifier_second_challenge(W: &[G1Affine], transcript: &mut ::TE) -> E::Scalar { + fn verifier_second_challenge( + W: &[Commitment], + transcript: &mut ::TE, + ) -> E::Scalar { transcript.absorb(b"W", &W.to_vec().as_slice()); transcript.squeeze(b"d").unwrap() @@ -929,7 +931,7 @@ where let x: Vec = point.to_vec(); //////////////// begin helper closures ////////// - let kzg_open = |f: &[E::Scalar], u: E::Scalar| -> G1Affine { + let kzg_open = |f: &[E::Scalar], u: E::Scalar| -> Commitment { // Divides polynomial f(x) by (x - u) to obtain the witness polynomial h(x) = f(x)/(x - u) // for KZG opening. // @@ -995,13 +997,13 @@ where let target_chunks = DEFAULT_TARGET_CHUNKS; let h = &div_by_monomial(f, u, target_chunks); - E::CE::commit(ck, h, &E::Scalar::ZERO).comm.affine() + E::CE::commit(ck, h, &E::Scalar::ZERO) }; let kzg_open_batch = |f: &[Vec], u: &[E::Scalar; 3], transcript: &mut ::TE| - -> (Vec>, Vec<[E::Scalar; 3]>) { + -> (Vec>, Vec<[E::Scalar; 3]>) { let poly_eval = |f: &[E::Scalar], u: E::Scalar| -> E::Scalar { // Horner's method let mut acc = E::Scalar::ZERO; @@ -1056,7 +1058,7 @@ where let w = u .into_par_iter() .map(|ui| kzg_open(&B, *ui)) - .collect::>>(); + .collect::>>(); // The prover computes the challenge to keep the transcript in the same // state as that of the verifier @@ -1091,10 +1093,7 @@ where // We do not need to commit to the first polynomial as it is already committed. // Compute commitments in parallel let r = vec![E::Scalar::ZERO; ell - 1]; - let com: Vec> = E::CE::batch_commit(ck, &polys[1..], r.as_slice()) - .par_iter() - .map(|i| i.comm.affine()) - .collect(); + let com: Vec> = E::CE::batch_commit(ck, &polys[1..], r.as_slice()); // Phase 2 // We do not need to add x to the transcript, because in our context x was obtained from the transcript. @@ -1198,6 +1197,9 @@ where }) .collect::>(); + let com_affine: Vec> = pi.com.iter().map(|c| c.into_inner().affine()).collect(); + let w_affine: Vec> = pi.w.iter().map(|c| c.into_inner().affine()).collect(); + let L = E::GE::vartime_multiscalar_mul( &[ &q_powers_multiplied[..], @@ -1211,16 +1213,16 @@ where .concat(), &[ &[C.comm.affine()][..], - &pi.com, - &pi.w, + &com_affine, + &w_affine, slice::from_ref(&vk.G), ] .concat(), ); - let R0 = E::GE::group(&pi.w[0]); - let R1 = E::GE::group(&pi.w[1]); - let R2 = E::GE::group(&pi.w[2]); + let R0 = pi.w[0].into_inner(); + let R1 = pi.w[1].into_inner(); + let R2 = pi.w[2].into_inner(); let R = R0 + R1 * d_0 + R2 * d_1; // Check that e(L, vk.H) == e(R, vk.tau_H) diff --git a/src/provider/pedersen.rs b/src/provider/pedersen.rs index 45ebda97..9eba020a 100644 --- a/src/provider/pedersen.rs +++ b/src/provider/pedersen.rs @@ -106,7 +106,8 @@ where { fn to_transcript_bytes(&self) -> Vec { let (x, y, is_infinity) = self.comm.to_coordinates(); - let is_infinity_byte = (!is_infinity).into(); + // Encode the infinity flag as 1 = infinity, matching the RO and in-circuit conventions. + let is_infinity_byte = is_infinity.into(); [ x.to_transcript_bytes(), y.to_transcript_bytes(),