From a56ef361de3dd59222c1824e44ecf90014377343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adria=CC=80=20Torralba=20Agell?= <0xAdriaTorralba@gmail.com> Date: Sat, 14 Sep 2024 20:04:35 +0200 Subject: [PATCH 1/3] Add constant MAX_POLYNOMIAL_DEGREE, add explicit deletion of toxic_waste once SRS is generated --- crypto/src/commitments/kzg.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crypto/src/commitments/kzg.rs b/crypto/src/commitments/kzg.rs index 2ecbb483c..1f93de1d5 100644 --- a/crypto/src/commitments/kzg.rs +++ b/crypto/src/commitments/kzg.rs @@ -283,6 +283,8 @@ mod tests { #[allow(clippy::upper_case_acronyms)] type KZG = KateZaveruchaGoldberg; + const MAX_POLYNOMIAL_DEGREE: usize = 100; + fn create_srs() -> StructuredReferenceString< ::G1Point, ::G2Point, @@ -298,7 +300,7 @@ mod tests { }); let g1 = BLS12381Curve::generator(); let g2 = BLS12381TwistCurve::generator(); - let powers_main_group: Vec = (0..100) + let powers_main_group: Vec = (0..MAX_POLYNOMIAL_DEGREE) .map(|exponent| { g1.operate_with_self(toxic_waste.pow(exponent as u128).representative()) }) @@ -307,6 +309,7 @@ mod tests { g2.clone(), g2.operate_with_self(toxic_waste.representative()), ]; + std::mem::drop(toxic_waste); StructuredReferenceString::new(&powers_main_group, &powers_secondary_group) } From 8f6422546d2988083d8496c16e24cf08cd952980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adria=CC=80=20Torralba=20Agell?= <0xAdriaTorralba@gmail.com> Date: Sat, 14 Sep 2024 20:14:09 +0200 Subject: [PATCH 2/3] Add tests --- crypto/src/commitments/kzg.rs | 76 +++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/crypto/src/commitments/kzg.rs b/crypto/src/commitments/kzg.rs index 1f93de1d5..9d9fecc39 100644 --- a/crypto/src/commitments/kzg.rs +++ b/crypto/src/commitments/kzg.rs @@ -313,6 +313,82 @@ mod tests { StructuredReferenceString::new(&powers_main_group, &powers_secondary_group) } + #[test] + fn e2e_kzg_single_polynomial() { + // Setup phase: create the SRS + let kzg = KZG::new(create_srs()); + + // Commit phase: create the desired polynomial, and commit that polyonmial + let p = Polynomial::::new(&[ + FieldElement::from(7), + FieldElement::from(5), + FieldElement::from(3), + ]); + // ASSERT: the polynomial is not too large + assert!(p.degree() <= MAX_POLYNOMIAL_DEGREE); + let p_commitment: ::G1Point = kzg.commit(&p); + + // Open phase: evaluate the polynomial at the desired point i, and create the proof for that opening + let i = FieldElement::from(1); // Challenge from the verifier + let y = p.evaluate(&i); // Evaluation of the polynomial at challenge + // ASSERT: the evaluation is correct + assert_eq!(y, FieldElement::from(15)); + let proof = kzg.open(&i, &y, &p); + + // Verify phase: the proof should verify + // ASSERT: the proof verifies + assert!(kzg.verify(&i, &y, &p_commitment, &proof)); + } + + #[test] + fn e2e_kzg_batched_polynomials() { + // Setup phase: create the SRS + let kzg = KZG::new(create_srs()); + + // Commit phase: create the polynomials, and compute the commitments. + let p0 = Polynomial::::new(&[ + FieldElement::from(5), + FieldElement::from(4), + -FieldElement::from(7), + ]); + // ASSERT: deg(p0) < MAX_POLYNOMIAL_DEGREE + assert!(p0.degree() < MAX_POLYNOMIAL_DEGREE); + let p0_commitment: ::G1Point = kzg.commit(&p0); + + let p1 = Polynomial::::new(&[ + FieldElement::from(1), + FieldElement::from(2), + -FieldElement::from(1), + ]); + // ASSERT: deg(p1) < MAX_POLYNOMIAL_DEGREE + assert!(p1.degree() < MAX_POLYNOMIAL_DEGREE); + let p1_commitment: ::G1Point = kzg.commit(&p1); + + // Open phase: open the polynomials at point i, and compute the proof for the batch. + let i = FieldElement::from(3); + + let y0 = p0.evaluate(&i); + // ASSERT: evaluation on p0 is correct + assert_eq!(y0, -FieldElement::from(46)); + + // ASSERT: evaluation on p1 is correct + let y1 = p1.evaluate(&i); + assert_eq!(y1, -FieldElement::from(2)); + + let upsilon = &FieldElement::from(1); + + let proof = kzg.open_batch(&i, &[y0.clone(), y1.clone()], &[p0, p1], upsilon); + + assert!(kzg.verify_batch( + &i, + &[y0, y1], + &[p0_commitment, p1_commitment], + &proof, + upsilon + )); + } + + #[test] fn kzg_1() { let kzg = KZG::new(create_srs()); From 6d09863043914568145a42bd67a3c62dd3b271cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adria=CC=80=20Torralba=20Agell?= <0xAdriaTorralba@gmail.com> Date: Mon, 2 Dec 2024 15:35:49 +0100 Subject: [PATCH 3/3] Remove toxic_waste once its used Removed the toxic waste once its used. Added assert to make sure the deletion. --- crypto/src/commitments/kzg.rs | 43 +++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/crypto/src/commitments/kzg.rs b/crypto/src/commitments/kzg.rs index 9d9fecc39..467812fd7 100644 --- a/crypto/src/commitments/kzg.rs +++ b/crypto/src/commitments/kzg.rs @@ -1,3 +1,4 @@ +#![deny(clippy::all)] use super::traits::IsCommitmentScheme; use alloc::{borrow::ToOwned, vec::Vec}; use core::{marker::PhantomData, mem}; @@ -290,26 +291,40 @@ mod tests { ::G2Point, > { let mut rng = rand::thread_rng(); - let toxic_waste = FrElement::new(U256 { + let mut toxic_waste = Some(FrElement::new(U256 { limbs: [ rng.gen::(), rng.gen::(), rng.gen::(), rng.gen::(), ], - }); - let g1 = BLS12381Curve::generator(); - let g2 = BLS12381TwistCurve::generator(); - let powers_main_group: Vec = (0..MAX_POLYNOMIAL_DEGREE) - .map(|exponent| { - g1.operate_with_self(toxic_waste.pow(exponent as u128).representative()) - }) - .collect(); - let powers_secondary_group = [ - g2.clone(), - g2.operate_with_self(toxic_waste.representative()), - ]; - std::mem::drop(toxic_waste); + })); + + let powers_main_group: Vec = { + let g1 = BLS12381Curve::generator(); + (0..MAX_POLYNOMIAL_DEGREE) + .map(|exponent| { + let tw = toxic_waste.as_ref().expect("toxic_waste should be available"); + g1.operate_with_self(tw.pow(exponent as u128).representative()) + }) + .collect() + }; + + let powers_secondary_group = { + let g2 = BLS12381TwistCurve::generator(); + [ + g2.clone(), + g2.operate_with_self( + toxic_waste + .as_ref() + .expect("toxic_waste should be available") + .representative(), + ), + ] + }; + + toxic_waste = None; + assert!(toxic_waste.is_none(), "toxic_waste should be poisoned"); StructuredReferenceString::new(&powers_main_group, &powers_secondary_group) }