Skip to content

Commit

Permalink
Refine code & Add comments.
Browse files Browse the repository at this point in the history
Signed-off-by: VanhGer <vietanhpg2003@gmail.com>
  • Loading branch information
VanhGer committed Apr 20, 2024
1 parent f85f362 commit 102f5a6
Show file tree
Hide file tree
Showing 13 changed files with 272 additions and 35 deletions.
9 changes: 9 additions & 0 deletions kzg/src/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::types::G1Point;
pub struct KzgCommitment(pub G1Point);

impl KzgCommitment {
/// A reference to the inner `G1Point` contained within the commitment.
pub fn inner(&self) -> &G1Point {
&self.0
}
Expand All @@ -24,6 +25,10 @@ mod tests {
use crate::types::{G1Point, Poly};

#[test]
/// Tests the commitment functionality in the KZG scheme.
///
/// This test verifies the correctness of committing to a polynomial,
/// opening the commitment, and verifying the opening.
fn commit() {
let secret = Fr::from(2);
let srs = Srs::new_from_secret(secret, 10);
Expand All @@ -45,6 +50,10 @@ mod tests {
}

#[test]
/// Tests the scalar multiplication of commitments.
///
/// This test validates the correctness of scalar multiplying a commitment
/// by a factor in the KZG scheme.
fn scalar_mul() {
let srs = Srs::new(5);
let scheme = KzgScheme::new(srs);
Expand Down
21 changes: 20 additions & 1 deletion kzg/src/opening.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@ use ark_bls12_381::Fr;

use crate::types::G1Point;

/// Opening at (point, evaluation)
/// Represents an opening at a point with its corresponding evaluation.
///
/// `KzgOpening` encapsulates a `G1Point` representing the point and an `Fr` representing the evaluation.
#[derive(Debug, Clone)]
pub struct KzgOpening(pub G1Point, pub Fr);

impl KzgOpening {
/// Retrieves the evaluation associated with the opening.
///
/// # Returns
///
/// The evaluation (`Fr`) of the opening.
pub fn eval(self) -> Fr {
self.1
}
Expand All @@ -17,8 +24,20 @@ impl KzgOpening {
impl Add for KzgOpening {
type Output = Self;

/// Combines two openings by adding their evaluations and doubling the witness point.
///
/// # Parameters
///
/// - `self`: The first `KzgOpening` instance.
/// - `rhs`: The second `KzgOpening` instance to be added.
///
/// # Returns
///
/// A new `KzgOpening` instance representing the combined opening.
fn add(self, rhs: Self) -> Self::Output {
// Add evaluations
let eval = self.1 + rhs.1;
// Double the witness point
let witness = self.0 + self.0;
Self(witness.into(), eval)
}
Expand Down
53 changes: 52 additions & 1 deletion kzg/src/scheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,51 @@ use crate::opening::KzgOpening;
use crate::srs::Srs;
use crate::types::{G1Point, Poly};

/// KzgScheme, Srs: structured reference string
/// Implements the KZG polynomial commitment scheme.
///
/// The `KzgScheme` struct provides methods for committing to polynomials, opening commitments,
/// and verifying openings.
pub struct KzgScheme(Srs);

impl KzgScheme {
/// Creates a new instance of `KzgScheme` with the given structured reference string (SRS).
///
/// # Parameters
///
/// - `srs`: The structured reference string (SRS) used in the scheme.
///
/// # Returns
///
/// A new instance of `KzgScheme`.
pub fn new(srs: Srs) -> Self {
Self(srs)
}
}

impl KzgScheme {
/// Commits to a polynomial using the KZG scheme.
///
/// # Parameters
///
/// - `polynomial`: The polynomial to be committed to.
///
/// # Returns
///
/// The commitment to the polynomial.
pub fn commit(&self, polynomial: &Poly) -> KzgCommitment {
let commitment = self.evaluate_in_s(polynomial);
KzgCommitment(commitment)
}

/// Commits to a parameter using the KZG scheme.
///
/// # Parameters
///
/// - `para`: The parameter to be committed to.
///
/// # Returns
///
/// The commitment to the parameter.
pub fn commit_para(&self, para: Fr) -> KzgCommitment {
let g1_0 = *self.0.g1_points().first().unwrap();
let commitment = g1_0.mul(para).into();
Expand All @@ -46,6 +76,16 @@ impl KzgScheme {
point
}

/// Opens a commitment at a specified point.
///
/// # Parameters
///
/// - `polynomial`: The polynomial to be opened.
/// - `z`: The point at which the polynomial is opened.
///
/// # Returns
///
/// The opening at the specified point.
pub fn open(&self, mut polynomial: Poly, z: impl Into<Fr>) -> KzgOpening {
let z = z.into();
let evaluation_at_z = polynomial.evaluate(&z);
Expand All @@ -58,6 +98,17 @@ impl KzgScheme {
KzgOpening(opening, evaluation_at_z)
}

/// Verifies the correctness of an opening.
///
/// # Parameters
///
/// - `commitment`: The commitment to be verified.
/// - `opening`: The opening to be verified.
/// - `z`: The point at which the polynomial was opened.
///
/// # Returns
///
/// `true` if the opening is valid, otherwise `false`.
pub fn verify(
&self,
commitment: &KzgCommitment,
Expand Down
50 changes: 42 additions & 8 deletions kzg/src/srs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,49 @@ use std::ops::Mul;

use ark_bls12_381::Fr;
use ark_ec::{AffineRepr, CurveGroup};
use ark_ff::One;
use ark_ff::UniformRand;
use ark_ff::{One, UniformRand};

use crate::types::{G1Point, G2Point};

/// Structured reference string
/// Structured Reference String (SRS) used in the KZG scheme.
///
/// The `Srs` struct represents the structured reference string used in the KZG scheme,
/// containing precomputed values necessary for commitment and verification.
#[derive(Debug, Clone)]
pub struct Srs {
/// G1 times the secret's powers
/// Points in G1, each equals to generator point multiplied by the secret's powers.
g1_points: Vec<G1Point>,
/// generator on G2
/// Generator point in G2.
g2: G2Point,
/// generator on G2 times the secret
/// Generator point in G2 multiplied by the secret.
g2s_point: G2Point,
}

impl Srs {
/// generate
/// Generates a new SRS with a random secret and the specified circuit size.
///
/// # Parameters
///
/// - `circuit_size`: The size of the circuit.
///
/// # Returns
///
/// A new `Srs` instance.
pub fn new(circuit_size: usize) -> Self {
let s = Fr::rand(&mut rand::thread_rng());
Self::new_from_secret(s, circuit_size)
}

/// only use it for testing purposes
/// Generates a new SRS with the provided secret and the specified circuit size.
///
/// # Parameters
///
/// - `secret`: The secret used for generating the SRS.
/// - `circuit_size`: The size of the circuit.
///
/// # Returns
///
/// A new `Srs` instance.
pub fn new_from_secret(secret: Fr, circuit_size: usize) -> Self {
let g1 = G1Point::generator();

Expand All @@ -51,14 +70,29 @@ impl Srs {
}

impl Srs {
/// Returns the precomputed points in G1.
///
/// # Returns
///
/// A vector containing points in G1.
pub fn g1_points(&self) -> Vec<G1Point> {
self.g1_points.clone()
}

/// Returns the generator point in G2.
///
/// # Returns
///
/// The generator point in G2.
pub fn g2(&self) -> G2Point {
self.g2
}

/// Returns the generator point in G2 multiplied by the secret.
///
/// # Returns
///
/// The generator point in G2 multiplied by the secret.
pub fn g2s(&self) -> G2Point {
self.g2s_point
}
Expand Down
44 changes: 34 additions & 10 deletions plonk/src/challenge.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::marker::PhantomData;

use ark_bls12_381::Fr;
use ark_ff::UniformRand;
use ark_serialize::{CanonicalSerialize, Write};
Expand All @@ -7,55 +9,77 @@ use sha2::Digest;

use kzg::commitment::KzgCommitment;

/// Generates Fiat-Shamir challenges for the KZG scheme.
///
/// The `ChallengeGenerator` struct is responsible for generating challenges used in the KZG scheme.
#[derive(Clone, Default)]
pub struct ChallengeGenerator<T: Digest + Default> {
data: Option<Vec<u8>>,
generated: bool,

#[allow(dead_code)]
/// this is just for annotation purposes
_hasher: T,
/// Phantom data for annotation purposes.
_phantom_data: PhantomData<T>,
}

impl<T: Digest + Default> ChallengeGenerator<T> {
/// Creates a new `ChallengeGenerator` instance from a list of commitments.
///
/// # Parameters
///
/// - `kzg_commitment`: A slice containing the commitments.
///
/// # Returns
///
/// A new `ChallengeGenerator` instance.
pub fn from_commitment(kzg_commitment: &[KzgCommitment]) -> Self {
let mut challenge_parse = Self::default();
for commitment in kzg_commitment {
challenge_parse.feed(commitment);
}

challenge_parse
}
}

impl<T: Digest + Default> ChallengeGenerator<T> {
/// Feeds a commitment to the challenge generator.
///
/// # Parameters
///
/// - `kzg_commitment`: The commitment to feed to the generator.
pub fn feed(&mut self, kzg_commitment: &KzgCommitment) {
let mut hasher = T::default();
hasher.update(self.data.take().unwrap_or(Vec::default()));

Check warning

Code scanning / clippy

use of unwrap_or to construct default value Warning

use of unwrap\_or to construct default value
kzg_commitment
.inner()
.serialize_uncompressed(HashMarshaller(&mut hasher))
.expect("HashMarshaller::flush should be infallible!");
self.data = Option::from(hasher.finalize().to_vec());
self.generated = false
self.data = Some(hasher.finalize().to_vec());
self.generated = false;
}

fn generate_rng_with_seed(&mut self) -> StdRng {
if self.generated {
panic!("I'm hungry! Feed me something first")
panic!("I'm hungry! Feed me something first");
}

self.generated = true;
let mut seed: [u8; 8] = Default::default();
seed.copy_from_slice(&self.data.clone().unwrap_or(vec![])[0..8]);
seed.copy_from_slice(&self.data.clone().unwrap_or_default()[0..8]);
let seed = u64::from_le_bytes(seed);

StdRng::seed_from_u64(seed)
}

/// Generates challenges of a specified length.
///
/// # Parameters
///
/// - `N`: The length of the challenges to generate.
///
/// # Returns
///
/// An array of generated challenges.
pub fn generate_challenges<const N: usize>(&mut self) -> [Fr; N] {
let mut rng = self.generate_rng_with_seed();

let points = [0; N];
points.map(|_| Fr::rand(&mut rng))
}
Expand Down
Loading

0 comments on commit 102f5a6

Please sign in to comment.