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

Polynomial commitment scheme based on IPA #743

Open
wants to merge 30 commits into
base: main
Choose a base branch
from

Conversation

cliraa
Copy link
Contributor

@cliraa cliraa commented Jan 4, 2024

Polynomial commitment scheme based on IPA

Description

A folder was created within 'commitments' where everything related to the new polynomial commitment scheme is located.

Type of change

  • New feature

Checklist

  • Linked to Github Issue

@cliraa cliraa requested a review from a team as a code owner January 4, 2024 14:45
@unbalancedparentheses
Copy link
Member

@diegokingston have you checked this?

@MauroToscano
Copy link
Collaborator

This is not ready for merging, I'm moving it to a draft

@MauroToscano MauroToscano marked this pull request as draft January 29, 2024 16:25
@@ -14,6 +14,9 @@ sha2 = "0.10"
thiserror = "1.0.38"
serde = { version = "1.0", features = ["derive"] }
rayon = { version = "1.8.0", optional = true }
num-bigint = { version = "0.4", features = ["rand"] }
num-traits = "0.2"
rand = { version = "0.8", features = [ "std", "std_rng" ] }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to import these libraries

pub type FrElement = FE;
pub type FrField = FrF;

#[allow(non_snake_case)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try using names according to rust practices

pub fn new(d: u32) -> IPA<BLS12381Curve> {

let mut gs: Vec<ShortWeierstrassProjectivePoint<BLS12381Curve>> = Vec::new();
for _ in 0..d {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be imported from some SRS

let m = a.len() / 2;
let a_lo = a[..m].to_vec();
let a_hi = a[m..].to_vec();
let b_lo = b[..m].to_vec();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can avoid this to_vec

let G_lo = G[..m].to_vec();
let G_hi = G[m..].to_vec();

l[j] = generate_random_element();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Random elements should be obtained from the verifier


pub fn identity_point<E: lambdaworks_math::elliptic_curve::traits::IsEllipticCurve<BaseField = MontgomeryBackendPrimeField<BLS12381FieldModulus, 6>> + lambdaworks_math::elliptic_curve::short_weierstrass::traits::IsShortWeierstrass>() -> ShortWeierstrassProjectivePoint<E> {
let point = ShortWeierstrassProjectivePoint::new([
FieldElement::<BaseField>::new_base("0"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is neutral element

let vc_c = vc_a.operate_with(&vc_b);
assert_eq!(vc_c, expected_vc_c);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need some more tests

@cliraa
Copy link
Contributor Author

cliraa commented Feb 4, 2024

Hello! I just updated the files. Among the changes made, we can find:

  • The change in the name from 'identity_point' to 'neutral_element'.

  • Use of Fiat-Shamir for challenges construction.

  • Removal of some imported libraries.

  • Proper naming according to Rust practices.

  • SRS (Structured Reference String) was added for the creation of some values.

  • And more tests were added (using 2 elliptic curves, BLS12381 and BN254).

This is a Polynomial Commitment Scheme described in the Halo paper.

Usage examples can be found in the tests 'test_inner_product_argument_proof_bn254_curve' and 'test_inner_product_argument_proof_bls12381_curve' in the ipa.rs file.

Here is an example:

// Initial values.

// M: will be a constant used to establish the amount of limbs later on.
// gen: the generator used.
// d: the number of terms that the polynomial has.

// With this we create the variable 'ipa'.

const M: usize = 4;
let gen = BN254Curve::generator();
let d = 8;
let mut ipa = IPA::new(d, gen.clone());

//Polynomial to use.
let a = Polynomial::new(&[
    FE_2::from(1 as u64),
    FE_2::from(2 as u64),
    FE_2::from(3 as u64),
    FE_2::from(4 as u64),
    FE_2::from(5 as u64),
    FE_2::from(6 as u64),
    FE_2::from(7 as u64),
    FE_2::from(8 as u64),
]);

// Its coefficients.
let coef_a = a.clone().coefficients;

// Blinding factor used in the commitment:
let r = generate_random_element();

// The commitment is calculated as follows:
// P = 〈a, G〉 + [r]H
// where H is a point on the elliptic curve
// and G is a vector of points on the elliptic curve. These values are calculated in the SRS.
let _p = ipa
    .commit(&a, r.clone(), neutral_element_bn254_curve())
    .unwrap();

// Generation of challenges (_u and u) using Fiat-Shamir.

// - In the case of _u:

// Initially, we generate a vector (Vec<u8>) using randomness.
// Then, this vector is used together with the generator to create a point on an elliptic curve using 'build_group_challenge'.

// - And regarding u:

// We generate another vector (Vec<u8>) using randomness, 
// which is used in 'build_field_challenge' to create a Field Element.

let mut rng = rand::thread_rng();
let vector: Vec<u8> = (0..32).map(|_| rng.gen::<u8>()).collect();
let _u = build_group_challenge::<Fr_2, M, BN254Curve>(vector, gen);

// Calculation of k.
let k = (f64::from(ipa.d as u32).log2()) as usize;

let mut u: Vec<FE_2> = vec![FE_2::zero(); k];
for j in 0..k {
    let mut rng = rand::thread_rng();
    let vector: Vec<u8> = (0..32).map(|_| rng.gen::<u8>()).collect();
    u[j] = build_field_challenge(vector);
}

// x will be used to construct vector b.
let x = FE_2::from(3 as u64);
let b = powers_of(&x.clone(), ipa.d.try_into().unwrap());

// Calculation of v using inner product.
let v = inner_product_field(&coef_a, &b).unwrap();

// Open the challenges.
let proof = ipa
    .open(&coef_a, &b, &u, &_u, neutral_element_bn254_curve())
    .unwrap();

// Verification.
let verif = ipa
    .verify_open(
        &x,
        &v,
        &_p,
        &proof,
        &r,
        &u,
        &_u,
        neutral_element_bn254_curve(),
    )
    .unwrap();
assert!(verif);

I believe the README.md would look quite nice by including a usage example as described above. The README.md is not included yet, but if there is no problem, I can create it soon.

@diegokingston diegokingston marked this pull request as ready for review February 5, 2024 13:59
@codecov-commenter
Copy link

codecov-commenter commented Feb 6, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (601ab67) 94.55% compared to head (c8856c6) 94.53%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #743      +/-   ##
==========================================
- Coverage   94.55%   94.53%   -0.03%     
==========================================
  Files         154      154              
  Lines       34587    34587              
==========================================
- Hits        32705    32696       -9     
- Misses       1882     1891       +9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants