diff --git a/acvm-repo/bn254_blackbox_solver/src/generator/generators.rs b/acvm-repo/bn254_blackbox_solver/src/generator/generators.rs index 6f9c72f7eb..a4f195a722 100644 --- a/acvm-repo/bn254_blackbox_solver/src/generator/generators.rs +++ b/acvm-repo/bn254_blackbox_solver/src/generator/generators.rs @@ -1,5 +1,7 @@ // Taken from https://github.com/laudiacay/barustenberg/blob/df6bc6f095fe7f288bf6a12e7317fd8eb33d68ae/barustenberg/src/ecc/groups/affine_element.rshttps://github.com/laudiacay/barustenberg/blob/df6bc6f095fe7f288bf6a12e7317fd8eb33d68ae/barustenberg/src/ecc/groups/group.rs +use std::sync::OnceLock; + use ark_ec::short_weierstrass::Affine; use acvm_blackbox_solver::blake3; @@ -8,6 +10,17 @@ use grumpkin::GrumpkinParameters; use super::hash_to_curve::hash_to_curve; pub(crate) const DEFAULT_DOMAIN_SEPARATOR: &[u8] = "DEFAULT_DOMAIN_SEPARATOR".as_bytes(); +const NUM_DEFAULT_GENERATORS: usize = 8; + +fn default_generators() -> &'static [Affine; NUM_DEFAULT_GENERATORS] { + static INSTANCE: OnceLock<[Affine; NUM_DEFAULT_GENERATORS]> = + OnceLock::new(); + INSTANCE.get_or_init(|| { + _derive_generators(DEFAULT_DOMAIN_SEPARATOR, NUM_DEFAULT_GENERATORS as u32, 0) + .try_into() + .expect("Should generate `NUM_DEFAULT_GENERATORS`") + }) +} /// Derives generator points via [hash-to-curve][hash_to_curve]. /// @@ -27,6 +40,21 @@ pub(crate) fn derive_generators( domain_separator_bytes: &[u8], num_generators: u32, starting_index: u32, +) -> Vec> { + // We cache a small number of the default generators so we can reuse them without needing to repeatedly recalculate them. + if domain_separator_bytes == DEFAULT_DOMAIN_SEPARATOR && starting_index + num_generators <= NUM_DEFAULT_GENERATORS as u32 { + let start_index = starting_index as usize; + let end_index = (starting_index + num_generators) as usize; + default_generators()[start_index..end_index].to_vec() + } else { + _derive_generators(domain_separator_bytes, num_generators, starting_index) + } +} + +fn _derive_generators( + domain_separator_bytes: &[u8], + num_generators: u32, + starting_index: u32, ) -> Vec> { let mut generator_preimage = [0u8; 64]; let domain_hash = blake3(domain_separator_bytes).expect("hash should succeed"); diff --git a/acvm-repo/bn254_blackbox_solver/src/pedersen/hash.rs b/acvm-repo/bn254_blackbox_solver/src/pedersen/hash.rs index 7c04984974..40a1aeb3c9 100644 --- a/acvm-repo/bn254_blackbox_solver/src/pedersen/hash.rs +++ b/acvm-repo/bn254_blackbox_solver/src/pedersen/hash.rs @@ -1,5 +1,7 @@ // Taken from: https://github.com/laudiacay/barustenberg/blob/df6bc6f095fe7f288bf6a12e7317fd8eb33d68ae/barustenberg/src/crypto/pedersen/pederson_hash.rs +use std::sync::OnceLock; + use ark_ec::{short_weierstrass::Affine, CurveConfig, CurveGroup}; use grumpkin::GrumpkinParameters; @@ -23,14 +25,14 @@ pub(crate) fn hash_with_index( ) -> ::BaseField { let length_as_scalar: ::ScalarField = (inputs.len() as u64).into(); - let length_prefix = length_generator(0) * length_as_scalar; + let length_prefix = *length_generator() * length_as_scalar; let result = length_prefix + commit_native_with_index(inputs, starting_index); result.into_affine().x } -//Note: this can be abstracted to a lazy_static!() -fn length_generator(starting_index: u32) -> Affine { - derive_generators("pedersen_hash_length".as_bytes(), 1, starting_index)[0] +fn length_generator() -> &'static Affine { + static INSTANCE: OnceLock> = OnceLock::new(); + INSTANCE.get_or_init(|| derive_generators("pedersen_hash_length".as_bytes(), 1, 0)[0]) } #[cfg(test)]