diff --git a/kzg/Cargo.toml b/kzg/Cargo.toml index 6359cbc..1cd4bd0 100644 --- a/kzg/Cargo.toml +++ b/kzg/Cargo.toml @@ -4,6 +4,10 @@ version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[example]] +name = "kzg-example" +path = "examples/example.rs" + [dependencies] ark-ff = "0.4.2" diff --git a/kzg/examples/example.rs b/kzg/examples/example.rs new file mode 100644 index 0000000..db91daa --- /dev/null +++ b/kzg/examples/example.rs @@ -0,0 +1,26 @@ +use ark_bls12_381::Fr; +use ark_poly::univariate::DensePolynomial; +use ark_poly::{DenseUVPolynomial, Polynomial}; +use kzg::scheme::KzgScheme; +use kzg::srs::Srs; + +fn main() { + // trusted setup + let srs = Srs::new(10); + let scheme = KzgScheme::new(srs); + + // polynomial x^3 + 3x + 5 + + let coeff = vec![Fr::from(5), Fr::from(3), Fr::from(0), Fr::from(1)]; + let poly = DensePolynomial::from_coefficients_vec(coeff); + let v = poly.evaluate(&Fr::from(1)); + assert_eq!(v, Fr::from(9)); + + // commit poly + let commitment = scheme.commit(&poly); + // opening point at p = 4. + let opening_pos = Fr::from(4); + let opening = scheme.open(&poly, opening_pos); + + assert!(scheme.verify(&commitment, &opening, opening_pos)); +} diff --git a/kzg/src/commitment.rs b/kzg/src/commitment.rs index 93663e1..021c78c 100644 --- a/kzg/src/commitment.rs +++ b/kzg/src/commitment.rs @@ -49,7 +49,7 @@ mod tests { .mul(poly.evaluate(&secret)) .into_affine() ); - let opening = scheme.open(poly, d); + let opening = scheme.open(&poly, d); assert!(scheme.verify(&commitment, &opening, d)); } @@ -111,7 +111,7 @@ mod tests { let openings: Vec = f .iter() .zip(z) - .map(|(f_i, z_i)| scheme.open(f_i.clone(), z_i)) + .map(|(f_i, z_i)| scheme.open(f_i, z_i)) .collect(); let c: Vec = f.iter().map(|f_i| scheme.commit(f_i)).collect(); let mut rng = StdRng::from_entropy(); diff --git a/kzg/src/opening.rs b/kzg/src/opening.rs index 49c4991..4f93531 100644 --- a/kzg/src/opening.rs +++ b/kzg/src/opening.rs @@ -6,7 +6,8 @@ use crate::types::G1Point; /// Represents an opening at a point with its corresponding evaluation. /// -/// `KzgOpening` encapsulates a `G1Point` representing the point and an `Fr` representing the evaluation. +/// `KzgOpening` encapsulates a `G1Point` representing the corresponding point +/// of quotient polynomial and an `Fr` representing the evaluation. #[derive(Debug, Clone)] pub struct KzgOpening(pub G1Point, pub Fr); diff --git a/kzg/src/scheme.rs b/kzg/src/scheme.rs index 11218a7..252cfa0 100644 --- a/kzg/src/scheme.rs +++ b/kzg/src/scheme.rs @@ -89,14 +89,16 @@ impl KzgScheme { /// # Returns /// /// The opening at the specified point. - pub fn open(&self, mut polynomial: Poly, z: impl Into) -> KzgOpening { + pub fn open(&self, polynomial: &Poly, z: impl Into) -> KzgOpening { let z = z.into(); let evaluation_at_z = polynomial.evaluate(&z); - let first = polynomial.coeffs.first_mut().expect("at least 1"); + let mut new_poly = polynomial.clone(); + let first = new_poly.coeffs.first_mut().expect("at least 1"); *first -= evaluation_at_z; let root = Poly::from_coefficients_slice(&[-z, 1.into()]); - let new_poly = &polynomial / &root; - let opening = self.evaluate_in_s(&new_poly); + // quotient polynomial + let quotient_poly = &new_poly / &root; + let opening = self.evaluate_in_s("ient_poly); KzgOpening(opening, evaluation_at_z) } @@ -123,7 +125,9 @@ impl KzgScheme { let g2 = self.0.g2(); let a = g2s.sub(g2.mul(z.into()).into_affine()); let b = commitment.0.sub(G1Point::generator().mul(y).into_affine()); + // e([Q]_1, [x]_2 - G_2 ⋅ z) let pairing1 = Bls12_381::pairing(opening.0, a); + // e([P]_1 - G_1 ⋅ P(x), G_2) let pairing2 = Bls12_381::pairing(b, g2); pairing1 == pairing2 }