diff --git a/kzg10/rust_implementation/.gitignore b/kzg10/rust_implementation/.gitignore new file mode 100644 index 0000000..f2f9e58 --- /dev/null +++ b/kzg10/rust_implementation/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock \ No newline at end of file diff --git a/kzg10/rust_implementation/Cargo.toml b/kzg10/rust_implementation/Cargo.toml new file mode 100644 index 0000000..c1f862c --- /dev/null +++ b/kzg10/rust_implementation/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "kzg10" +version = "0.1.0" +edition = "2021" + +[dependencies] +ark-std = "0.4" +ark-bls12-381 = "0.4" +ark-ec = "0.4" +ark-ff = "0.4" +# ark-poly = { version = "0.3.0", features = ["bls12_381"] } +rand = "0.8" diff --git a/kzg10/rust_implementation/src/lib.rs b/kzg10/rust_implementation/src/lib.rs new file mode 100644 index 0000000..e0af053 --- /dev/null +++ b/kzg10/rust_implementation/src/lib.rs @@ -0,0 +1,118 @@ +use ark_bls12_381::{Fr, G1Projective as G1, G2Projective as G2}; +use ark_ec::Group; +use ark_ff::{Field, One, UniformRand}; +use ark_std::rand::RngCore; +use ark_std::vec::Vec; +use std::ops::Mul; + +pub struct KZG10Commitment { + pub debug: bool, +} + +pub struct SetupParams { + pub powers_of_g: Vec, + pub powers_of_gamma_g: Vec, + pub h: G2, + pub beta_h: G2, + pub neg_powers_of_h: Vec, +} + +impl KZG10Commitment { + pub fn new(debug: bool) -> Self { + Self { debug } + } + + pub fn setup( + &self, + max_degree: usize, + produce_g2_powers: bool, + secret_symbol: Option, + g1_generator: Option, + g2_generator: Option, + rng: &mut R, + ) -> SetupParams { + // Default generators + let default_g = G1::generator(); + let default_h = G2::generator(); + + // Derive g and h from provided scalars or use default generators + let g = if let Some(gen) = g1_generator { + default_g.mul(gen) + } else { + default_g + }; + + let h = if let Some(gen) = g2_generator { + default_h.mul(gen) + } else { + default_h + }; + + // Beta (the secret symbol) + let beta = secret_symbol.unwrap_or_else(|| Fr::rand(rng)); + + // gamma_g is another field element chosen at random + let gamma_g = Fr::rand(rng); + + // Compute powers_of_s = [ 1, beta, beta^2,...., beta^(max_degree+1)] + let mut powers_of_s = Vec::with_capacity(max_degree + 2); + { + let mut current = Fr::one(); + for _ in 0..(max_degree + 2) { + powers_of_s.push(current); + current *= beta; + } + } + + // powers_of_g[i] = g^{beta^i} + let powers_of_g: Vec = powers_of_s[..=max_degree] + .iter() + .map(|exp| g.mul(*exp)) + .collect(); + + let powers_of_gamma_g: Vec = powers_of_s + .iter() + .map(|exp| g.mul(gamma_g * (*exp))) + .collect(); + + let beta_h = h.mul(beta); + + let mut neg_powers_of_h = Vec::new(); + if produce_g2_powers { + let beta_inv = beta.inverse().expect("beta must be invertible"); + let mut current_inv = Fr::one(); + neg_powers_of_h.push(h); + + for _ in 1..=max_degree { + current_inv *= beta_inv; + neg_powers_of_h.push(h.mul(current_inv)); + } + } + SetupParams { + powers_of_g, + powers_of_gamma_g, + h, + beta_h, + neg_powers_of_h, + } + } +} + + + +#[cfg(test)] +mod tests { + use super::*; + use ark_std::test_rng; + + #[test] + fn test_setup() { + let mut rng = test_rng(); + let kzg = KZG10Commitment::new(false); + + let params = kzg.setup(10, true, None, None, None, &mut rng); + assert_eq!(params.powers_of_g.len(), 11); // max_degree + 1 + assert_eq!(params.powers_of_gamma_g.len(), 12); // max_degree + 2 + assert_eq!(params.neg_powers_of_h.len(), 11); // max_degree + 1 + } +} diff --git a/kzg10/rust_implementation/src/main.rs b/kzg10/rust_implementation/src/main.rs new file mode 100644 index 0000000..e0b5e27 --- /dev/null +++ b/kzg10/rust_implementation/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello world!"); +}