Skip to content

Commit

Permalink
Merge branch 'main' into feat/msm
Browse files Browse the repository at this point in the history
  • Loading branch information
lonerapier committed Nov 12, 2023
2 parents 089ced6 + df6bc6f commit 7003856
Show file tree
Hide file tree
Showing 27 changed files with 1,544 additions and 823 deletions.
147 changes: 66 additions & 81 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ ark-grumpkin = { git = "https://github.com/arkworks-rs/curves/" }
ark-ff = { git = "https://github.com/arkworks-rs/algebra/" }
ark-ec = { git = "https://github.com/arkworks-rs/algebra/" }
ark-serialize = { git = "https://github.com/arkworks-rs/algebra/" }
ark-poly = { git = "https://github.com/arkworks-rs/algebra/" }
ark-poly = { git = "https://github.com/arkworks-rs/algebra/" }
2 changes: 2 additions & 0 deletions barustenberg/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ path = "src/lib.rs"

[dependencies]
anyhow = "1.0"
ark-std = "0.4.0"
ark-bn254 = "0.4.0"
ark-ec = "0.4.2"
ark-ff = "0.4.2"
Expand All @@ -43,6 +44,7 @@ typenum = "1.13"
ff = { version = "0.13.0", features = ["alloc"] }
either = "1.8.1"
num-bigint = "0.4.3"
blake3 = "1.5.0"

[dev-dependencies]
proptest = "1.1"
Expand Down
116 changes: 116 additions & 0 deletions barustenberg/src/crypto/generator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
use grumpkin::GrumpkinConfig;
use lazy_static::lazy_static;

use std::{collections::HashMap, fmt::Debug, sync::Mutex};

use ark_ec::{
short_weierstrass::{Affine, SWCurveConfig},
AffineRepr,
};

use crate::ecc::groups::group::derive_generators;

pub(crate) const DEFAULT_NUM_GENERATORS: usize = 8;
pub(crate) const DEFAULT_DOMAIN_SEPARATOR: &str = "DEFAULT_DOMAIN_SEPARATOR";

//Ref that can be imported to access pre-computed generators
lazy_static! {
pub(crate) static ref GENERATOR_CONTEXT: Mutex<GeneratorContext<GrumpkinConfig>> =
Mutex::new(GeneratorContext::default());
}

#[derive(Debug, Clone)]
pub(crate) struct GeneratorList<E: SWCurveConfig>(Vec<Affine<E>>);

// In barustenberg there exists a shared ladder storing cached precomputed values.
#[derive(Clone, Debug)]
pub(crate) struct GeneratorData<E: SWCurveConfig> {
pub(crate) precomputed_generators: [Affine<E>; DEFAULT_NUM_GENERATORS],
pub(crate) generator_map: HashMap<String, GeneratorList<E>>,
}

impl<E: SWCurveConfig> Default for GeneratorData<E> {
fn default() -> Self {
Self {
precomputed_generators: Self::make_precomputed_generators(),
generator_map: HashMap::new(),
}
}
}

impl<E: SWCurveConfig> GeneratorData<E> {
fn make_precomputed_generators() -> [Affine<E>; DEFAULT_NUM_GENERATORS] {
let mut output: [Affine<E>; DEFAULT_NUM_GENERATORS] =
[Affine::zero(); DEFAULT_NUM_GENERATORS];
let res: Vec<Affine<E>> = derive_generators(
DEFAULT_DOMAIN_SEPARATOR.as_bytes(),
DEFAULT_NUM_GENERATORS,
0,
);
output.copy_from_slice(&res[..DEFAULT_NUM_GENERATORS]);
output
}

//NOTE: can add default arguments by wrapping function parameters with options
pub(crate) fn get(
&mut self,
num_generators: usize,
generator_offset: usize,
domain_separator: &str,
) -> Vec<Affine<E>> {
let is_default_domain = domain_separator == DEFAULT_DOMAIN_SEPARATOR;
if is_default_domain && (num_generators + generator_offset) < DEFAULT_NUM_GENERATORS {
return self.precomputed_generators.to_vec();
}

// Case 2: we want default generators, but more than we precomputed at compile time. If we have not yet copied
// the default generators into the map, do so.
if is_default_domain && !self.generator_map.is_empty() {
let _ = self
.generator_map
.insert(
DEFAULT_DOMAIN_SEPARATOR.to_string(),
GeneratorList(self.precomputed_generators.to_vec()),
)
.unwrap();
}

//TODO: open to suggestions for this
let mut generators = self
.generator_map
.get(DEFAULT_DOMAIN_SEPARATOR)
.unwrap()
.0
.clone();

if num_generators + generator_offset > generators.len() {
let num_extra_generators = num_generators + generator_offset - generators.len();
let extended_generators = derive_generators(
domain_separator.as_bytes(),
num_extra_generators,
generators.len(),
);

generators.extend_from_slice(&extended_generators);
}

generators
}
}

#[derive(Debug, Clone)]
pub(crate) struct GeneratorContext<E: SWCurveConfig> {
pub(crate) offset: usize,
pub(crate) domain_separator: &'static str,
pub(crate) generators: GeneratorData<E>,
}

impl<E: SWCurveConfig> Default for GeneratorContext<E> {
fn default() -> Self {
Self {
offset: 0,
domain_separator: DEFAULT_DOMAIN_SEPARATOR,
generators: GeneratorData::default(),
}
}
}
1 change: 1 addition & 0 deletions barustenberg/src/crypto/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub(crate) mod generator;
pub(crate) mod pedersen;
2 changes: 1 addition & 1 deletion barustenberg/src/crypto/pedersen/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub(crate) fn compress_native_with_multiple_indices(
todo!("compress_native with multiple hash indices")
}

pub(crate) fn compress_native(_input: &[u8]) -> Vec<u8> {
pub(crate) fn compress_native(input: &[grumpkin::Fq]) -> Vec<u8> {
// TODO: Implement this function
todo!("compress_native")
}
Expand Down
55 changes: 3 additions & 52 deletions barustenberg/src/crypto/pedersen/mod.rs
Original file line number Diff line number Diff line change
@@ -1,52 +1,3 @@
pub(crate) mod lookup;
use std::vec::Vec;

pub(crate) type GeneratorIndexT = usize;

pub(crate) fn commit_single(_in_value: ark_bn254::Fr, _index: GeneratorIndexT) -> grumpkin::Affine {
// TODO: Implement this function
todo!("commit_single")
}

pub(crate) fn commit_native(
_inputs: Vec<grumpkin::Fq>,
hash_index: Option<usize>,
) -> grumpkin::Affine {
let _hash_index = hash_index.unwrap_or(0);

// TODO: Implement this function
todo!("commit_native")
}

pub(crate) fn commit_native_with_pairs(
_input_pairs: Vec<(grumpkin::Fq, GeneratorIndexT)>,
) -> grumpkin::Affine {
// TODO: Implement this function
todo!("commit_native_with_pairs")
}

pub(crate) fn compress_native_with_index(
_inputs: Vec<grumpkin::Fq>,
hash_index: Option<usize>,
) -> grumpkin::Fq {
let _hash_index = hash_index.unwrap_or(0);
// TODO: Implement this function
todo!("compress_native")
}

pub(crate) fn compress_native_array<const T: usize>(_inputs: [grumpkin::Fq; T]) -> grumpkin::Fq {
// TODO: Implement this function
todo!("compress_native_array")
}

pub(crate) fn compress_native(_input: &[u8]) -> grumpkin::Fq {
// TODO: Implement this function
todo!("compress_native")
}

pub(crate) fn compress_native_with_pairs(
_input_pairs: Vec<(grumpkin::Fq, GeneratorIndexT)>,
) -> grumpkin::Fq {
// TODO: Implement this function
todo!("compress_native_with_pairs")
}
//pub(crate) mod lookup;
pub(crate) mod pederson;
pub(crate) mod pederson_hash;
69 changes: 69 additions & 0 deletions barustenberg/src/crypto/pedersen/pederson.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use ark_ec::{
short_weierstrass::{Affine, SWCurveConfig},
AffineRepr, CurveGroup,
};
use ark_ff::{Field, Fp, PrimeField};
use grumpkin::{Fq, Fr, GrumpkinConfig};

use crate::crypto::generator::GeneratorContext;

/**
* @brief Given a vector of fields, generate a pedersen commitment using the indexed generators.
*
* @details This method uses `Curve::BaseField` members as inputs. This aligns with what we expect when creating
* grumpkin commitments to field elements inside a BN254 SNARK circuit.
* @param inputs
* @param context
* @return Curve::AffineElement
*/
// NOTE: this could be generalized using SWCurveConfig but since we perform the operation over grumpkin its explicit
pub(crate) fn commit_native(
inputs: &[Fq],
context: &mut GeneratorContext<GrumpkinConfig>,
) -> Affine<GrumpkinConfig> {
let generators = context
.generators
.get(inputs.len(), context.offset, context.domain_separator);

inputs
.iter()
.enumerate()
.fold(Affine::zero(), |mut acc, (i, input)| {
//TODO: this is a sketch conversion do better
acc = (acc
+ (generators[i] * Fr::from_bigint(input.into_bigint()).unwrap()).into_affine())
.into_affine();
acc
})
}

#[cfg(test)]
pub(crate) mod test {
use crate::crypto::generator::GENERATOR_CONTEXT;

use super::*;

use ark_ff::MontFp;
use ark_std::One;
use grumpkin::Fq;

//TODO: double check that the generators are the same. They could be slightly different due to the way we canonically
// decide how to invert y which was done to prevent a headache of having to deseialize an Fq element... Long story.
#[test]
fn commitment() {
let res = commit_native(
&[Fq::one(), Fq::one()],
&mut GENERATOR_CONTEXT.lock().unwrap(),
);
let expected = Affine::new(
// 2f7a8f9a6c96926682205fb73ee43215bf13523c19d7afe36f12760266cdfe15
MontFp!(
"21475250338311530111088781112432132511855209292730670949974692984887182229013"
),
// 01916b316adbbf0e10e39b18c1d24b33ec84b46daddf72f43878bcc92b6057e6
MontFp!("709245492126126701709902506217603794644991322680146492508959813283461748710"),
);

assert_eq!(res, expected);
}
}
95 changes: 95 additions & 0 deletions barustenberg/src/crypto/pedersen/pederson_hash.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use ark_ec::{
short_weierstrass::{Affine, Projective, SWCurveConfig},
CurveConfig, CurveGroup,
};
use grumpkin::GrumpkinConfig;

use crate::{crypto::generator::GeneratorContext, ecc::groups::group::derive_generators};

use super::pederson::commit_native;

/**
* @brief Given a vector of fields, generate a pedersen commitment using the indexed generators.
*
* @details This method uses `Curve::BaseField` members as inputs. This aligns with what we expect when creating
* grumpkin commitments to field elements inside a BN254 SNARK circuit.
* @param inputs
* @param context
* @return Curve::AffineElement
*/
//TODO: confirm we can do this with scalar field
pub(crate) fn hash(
inputs: &[grumpkin::Fq],
context: &mut GeneratorContext<GrumpkinConfig>,
) -> <GrumpkinConfig as CurveConfig>::BaseField {
let res: Affine<GrumpkinConfig> = (length_generator(0)
* <GrumpkinConfig as CurveConfig>::ScalarField::from(inputs.len() as u64))
.into_affine();
(res + commit_native(inputs, context)).x
}

pub(crate) fn hash_with_index(
inputs: &[grumpkin::Fq],
starting_index: usize,
context: &mut GeneratorContext<GrumpkinConfig>,
) -> <GrumpkinConfig as CurveConfig>::BaseField {
let res: Affine<GrumpkinConfig> = (length_generator(starting_index)
* <GrumpkinConfig as CurveConfig>::ScalarField::from(inputs.len() as u64))
.into_affine();
(res + commit_native(inputs, context)).x
}

//Note: this can be abstracted to a lazy_static!()
fn length_generator<E: SWCurveConfig>(starting_index: usize) -> Affine<E> {
derive_generators::<E>("pedersen_hash_length".as_bytes(), 1, starting_index)[0]
}

pub(crate) fn hash_buffer<E: SWCurveConfig>(
input: &[u8],
context: &mut GeneratorContext<E>,
) -> E::BaseField {
todo!()
}

#[cfg(test)]
pub(crate) mod test {
use crate::crypto::generator::GENERATOR_CONTEXT;

use super::*;

use ark_ff::{AdditiveGroup, BigInteger, MontFp, PrimeField, Zero};
use ark_serialize::CanonicalSerialize;
use ark_std::{One, UniformRand};
use grumpkin::{Fq, Fr};

//reference: https://github.com/AztecProtocol/barretenberg/blob/master/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.test.cpp
#[test]
fn hash_one() {
let res = hash(
&[Fq::one(), Fq::one()],
&mut GENERATOR_CONTEXT.lock().unwrap(),
);
//TODO: double check that the generators are the same. They could be slightly different due to the way we canonically invert y
//TODO: compute correct value from generators
// 07ebfbf4df29888c6cd6dca13d4bb9d1a923013ddbbcbdc3378ab8845463297b
assert_eq!(
res,
MontFp!("3583137940367543141169889198758850326673923325182598243450662697654714313083")
);
}

#[test]
fn hash_with_index() {
let res = hash(
&[Fq::one(), Fq::one()],
&mut GENERATOR_CONTEXT.lock().unwrap(),
);
//TODO: double check that the generators are the same. They could be slightly different due to the way we canonically invert y
//TODO: compute correct value from generators
// 07ebfbf4df29888c6cd6dca13d4bb9d1a923013ddbbcbdc3378ab8845463297b
assert_eq!(
res,
MontFp!("3583137940367543141169889198758850326673923325182598243450662697654714313083")
);
}
}
2 changes: 1 addition & 1 deletion barustenberg/src/ecc/curves/bn254_scalar_multiplication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::srs::io::read_transcript_g1;
use anyhow::Result;

#[inline]
fn cube_root_of_unity<F: ark_ff::Field>() -> F {
pub(crate) fn cube_root_of_unity<F: ark_ff::Field>() -> F {
// // endomorphism i.e. lambda * [P] = (beta * x, y)
// if constexpr (Params::cube_root_0 != 0) {
// constexpr field result{
Expand Down
Loading

0 comments on commit 7003856

Please sign in to comment.