From 880ecd77df727b2bed7936b4a2fa942098d50b4e Mon Sep 17 00:00:00 2001 From: mmagician Date: Thu, 11 Jan 2024 00:10:18 +0100 Subject: [PATCH 01/11] Document the msm method, and simplify the interface a little --- ec/src/scalar_mul/fixed_base.rs | 45 +++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/ec/src/scalar_mul/fixed_base.rs b/ec/src/scalar_mul/fixed_base.rs index ce8001ccd..6d5a46031 100644 --- a/ec/src/scalar_mul/fixed_base.rs +++ b/ec/src/scalar_mul/fixed_base.rs @@ -17,11 +17,8 @@ impl FixedBase { } } - pub fn get_window_table( - scalar_size: usize, - window: usize, - g: T, - ) -> Vec> { + pub fn get_window_table(window: usize, g: T) -> Vec> { + let scalar_size = T::ScalarField::MODULUS_BIT_SIZE as usize; let in_window = 1 << window; let outerc = (scalar_size + window - 1) / window; let last_in_window = 1 << (scalar_size - (outerc - 1) * window); @@ -61,7 +58,7 @@ impl FixedBase { pub fn windowed_mul( outerc: usize, window: usize, - multiples_of_g: &[Vec<::MulBase>], + multiples_of_g: &[Vec], scalar: &T::ScalarField, ) -> T { let modulus_size = T::ScalarField::MODULUS_BIT_SIZE as usize; @@ -80,14 +77,42 @@ impl FixedBase { res } - // TODO use const-generics for the scalar size and window - // TODO use iterators of iterators of T::Affine instead of taking owned Vec + /// Compute the vector v[0].G, v[1].G, ..., v[n-1].G given + /// - a window size `window` + /// - a pre-computed table from from `get_window_table` on G + /// - a vector of scalars `v` + /// using fixed-base multiplication + /// # Example + /// ``` + /// use ark_std::{One, UniformRand}; + /// use ark_ec::pairing::Pairing; + /// use ark_test_curves::bls12_381::G1Projective as G; + /// use ark_test_curves::bls12_381::Fr; + /// use ark_ec::scalar_mul::fixed_base::FixedBase; + /// + /// // Compute G, s.G, s^2.G, ..., s^9.G + /// let mut rng = ark_std::test_rng(); + /// let max_degree = 10; + /// let s = Fr::rand(&mut rng); + /// let g = G::rand(&mut rng); + /// let mut powers_of_s = vec![Fr::one()]; + /// let mut cur = s; + /// for _ in 0..max_degree { + /// powers_of_s.push(cur); + /// cur *= &s; + /// } + /// let window_size = FixedBase::get_mul_window_size(max_degree + 1); + /// let g_table = FixedBase::get_window_table(window_size, g); + /// let powers_of_g: Vec = FixedBase::msm(window_size, &g_table, &powers_of_s); + /// let naive_powers_of_g: Vec = powers_of_s.iter().map(|e| g * e).collect(); + /// assert_eq!(powers_of_g, naive_powers_of_g); + /// ``` pub fn msm( - scalar_size: usize, window: usize, - table: &[Vec<::MulBase>], + table: &[Vec], v: &[T::ScalarField], ) -> Vec { + let scalar_size = T::ScalarField::MODULUS_BIT_SIZE as usize; let outerc = (scalar_size + window - 1) / window; assert!(outerc <= table.len()); From 1974901ae8f906890b6ea0d23407c4144bacc011 Mon Sep 17 00:00:00 2001 From: mmagician Date: Thu, 11 Jan 2024 00:17:23 +0100 Subject: [PATCH 02/11] simplify the interface further; only the msm should remain public --- ec/src/scalar_mul/fixed_base.rs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/ec/src/scalar_mul/fixed_base.rs b/ec/src/scalar_mul/fixed_base.rs index 6d5a46031..22b0b6c70 100644 --- a/ec/src/scalar_mul/fixed_base.rs +++ b/ec/src/scalar_mul/fixed_base.rs @@ -9,7 +9,7 @@ use super::ScalarMul; pub struct FixedBase; impl FixedBase { - pub fn get_mul_window_size(num_scalars: usize) -> usize { + fn get_mul_window_size(num_scalars: usize) -> usize { if num_scalars < 32 { 3 } else { @@ -17,7 +17,7 @@ impl FixedBase { } } - pub fn get_window_table(window: usize, g: T) -> Vec> { + fn get_window_table(window: usize, g: T) -> Vec> { let scalar_size = T::ScalarField::MODULUS_BIT_SIZE as usize; let in_window = 1 << window; let outerc = (scalar_size + window - 1) / window; @@ -55,7 +55,7 @@ impl FixedBase { .collect() } - pub fn windowed_mul( + fn windowed_mul( outerc: usize, window: usize, multiples_of_g: &[Vec], @@ -101,23 +101,19 @@ impl FixedBase { /// powers_of_s.push(cur); /// cur *= &s; /// } - /// let window_size = FixedBase::get_mul_window_size(max_degree + 1); - /// let g_table = FixedBase::get_window_table(window_size, g); - /// let powers_of_g: Vec = FixedBase::msm(window_size, &g_table, &powers_of_s); + /// let powers_of_g: Vec = FixedBase::msm(g, &powers_of_s); /// let naive_powers_of_g: Vec = powers_of_s.iter().map(|e| g * e).collect(); /// assert_eq!(powers_of_g, naive_powers_of_g); /// ``` - pub fn msm( - window: usize, - table: &[Vec], - v: &[T::ScalarField], - ) -> Vec { + pub fn msm(g: T, v: &[T::ScalarField]) -> Vec { + let window_size = Self::get_mul_window_size(v.len()); + let table = Self::get_window_table::(window_size, g.clone()); let scalar_size = T::ScalarField::MODULUS_BIT_SIZE as usize; - let outerc = (scalar_size + window - 1) / window; + let outerc = (scalar_size + window_size - 1) / window_size; assert!(outerc <= table.len()); cfg_iter!(v) - .map(|e| Self::windowed_mul::(outerc, window, table, e)) + .map(|e| Self::windowed_mul::(outerc, window_size, &table, e)) .collect::>() } } From 162e1fa6fd726949f6476bd2dd8942952134ce1f Mon Sep 17 00:00:00 2001 From: mmagician Date: Thu, 11 Jan 2024 00:19:17 +0100 Subject: [PATCH 03/11] rename `msm` -> `mul` to avoid confusion with VariableBaseMSM --- ec/src/scalar_mul/fixed_base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ec/src/scalar_mul/fixed_base.rs b/ec/src/scalar_mul/fixed_base.rs index 22b0b6c70..9285407de 100644 --- a/ec/src/scalar_mul/fixed_base.rs +++ b/ec/src/scalar_mul/fixed_base.rs @@ -105,7 +105,7 @@ impl FixedBase { /// let naive_powers_of_g: Vec = powers_of_s.iter().map(|e| g * e).collect(); /// assert_eq!(powers_of_g, naive_powers_of_g); /// ``` - pub fn msm(g: T, v: &[T::ScalarField]) -> Vec { + pub fn mul(g: T, v: &[T::ScalarField]) -> Vec { let window_size = Self::get_mul_window_size(v.len()); let table = Self::get_window_table::(window_size, g.clone()); let scalar_size = T::ScalarField::MODULUS_BIT_SIZE as usize; From 18e7f7d938be2b9a5b27461680590e631f1f5a25 Mon Sep 17 00:00:00 2001 From: mmagician Date: Thu, 11 Jan 2024 00:32:59 +0100 Subject: [PATCH 04/11] fix doctest --- ec/src/scalar_mul/fixed_base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ec/src/scalar_mul/fixed_base.rs b/ec/src/scalar_mul/fixed_base.rs index 9285407de..7f53fc414 100644 --- a/ec/src/scalar_mul/fixed_base.rs +++ b/ec/src/scalar_mul/fixed_base.rs @@ -101,7 +101,7 @@ impl FixedBase { /// powers_of_s.push(cur); /// cur *= &s; /// } - /// let powers_of_g: Vec = FixedBase::msm(g, &powers_of_s); + /// let powers_of_g: Vec = FixedBase::mul(g, &powers_of_s); /// let naive_powers_of_g: Vec = powers_of_s.iter().map(|e| g * e).collect(); /// assert_eq!(powers_of_g, naive_powers_of_g); /// ``` From 7e5b4f29f1bf42f1983b6e7c8ef90e2f4db048c3 Mon Sep 17 00:00:00 2001 From: mmagician Date: Thu, 11 Jan 2024 00:33:14 +0100 Subject: [PATCH 05/11] bring back `get_window_table` as public --- ec/src/scalar_mul/fixed_base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ec/src/scalar_mul/fixed_base.rs b/ec/src/scalar_mul/fixed_base.rs index 7f53fc414..fd7b20269 100644 --- a/ec/src/scalar_mul/fixed_base.rs +++ b/ec/src/scalar_mul/fixed_base.rs @@ -17,7 +17,7 @@ impl FixedBase { } } - fn get_window_table(window: usize, g: T) -> Vec> { + pub fn get_window_table(window: usize, g: T) -> Vec> { let scalar_size = T::ScalarField::MODULUS_BIT_SIZE as usize; let in_window = 1 << window; let outerc = (scalar_size + window - 1) / window; From 27430b104a965fedf4a4a3690856c4227b89103e Mon Sep 17 00:00:00 2001 From: mmagician Date: Thu, 11 Jan 2024 00:43:29 +0100 Subject: [PATCH 06/11] adapt description to fit new simplified interface --- ec/src/scalar_mul/fixed_base.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ec/src/scalar_mul/fixed_base.rs b/ec/src/scalar_mul/fixed_base.rs index fd7b20269..40337a7f0 100644 --- a/ec/src/scalar_mul/fixed_base.rs +++ b/ec/src/scalar_mul/fixed_base.rs @@ -77,11 +77,10 @@ impl FixedBase { res } - /// Compute the vector v[0].G, v[1].G, ..., v[n-1].G given - /// - a window size `window` - /// - a pre-computed table from from `get_window_table` on G - /// - a vector of scalars `v` - /// using fixed-base multiplication + /// Compute the vector v[0].G, v[1].G, ..., v[n-1].G, given: + /// - an element `g` + /// - a list `v` of n scalars + /// /// # Example /// ``` /// use ark_std::{One, UniformRand}; From 963bab989da13cd999fb09d83c1fcd74343fc293 Mon Sep 17 00:00:00 2001 From: mmagician Date: Thu, 11 Jan 2024 00:49:42 +0100 Subject: [PATCH 07/11] Add a changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d637f5c57..2cb3d0afd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - [\#577](https://github.com/arkworks-rs/algebra/pull/577) (`ark-ff`, `ark-ec`) Add `AdditiveGroup`, a trait for additive groups (equipped with scalar field). - [\#593](https://github.com/arkworks-rs/algebra/pull/593) (`ark-ec`) Change `AffineRepr::xy()` to return owned values. - [\#633](https://github.com/arkworks-rs/algebra/pull/633) (`ark-ec`) Generic pairing implementation for the curves from the BW6 family. +- [\#746](https://github.com/arkworks-rs/algebra/pull/746) (`ark-ec`) Refactor `FixedBase`: rename method `msm` → `mul`, remove its arguments `scalar_size`, `window` and change `table: &[Vec]` → `g: T`; make methods `windowed_mul` and `get_mul_window_size` private. ### Features From 9b1655d998c6b21caf82c9bff5632b8bcb3b7fd5 Mon Sep 17 00:00:00 2001 From: Pratyush Mishra Date: Sun, 14 Jan 2024 16:19:01 -0500 Subject: [PATCH 08/11] Cleaner API --- ec/src/scalar_mul/fixed_base.rs | 118 -------------------------- ec/src/scalar_mul/mod.rs | 141 +++++++++++++++++++++++++++++++- 2 files changed, 138 insertions(+), 121 deletions(-) delete mode 100644 ec/src/scalar_mul/fixed_base.rs diff --git a/ec/src/scalar_mul/fixed_base.rs b/ec/src/scalar_mul/fixed_base.rs deleted file mode 100644 index 40337a7f0..000000000 --- a/ec/src/scalar_mul/fixed_base.rs +++ /dev/null @@ -1,118 +0,0 @@ -use ark_ff::{BigInteger, PrimeField}; -use ark_std::{cfg_iter, cfg_iter_mut, vec::Vec}; - -#[cfg(feature = "parallel")] -use rayon::prelude::*; - -use super::ScalarMul; - -pub struct FixedBase; - -impl FixedBase { - fn get_mul_window_size(num_scalars: usize) -> usize { - if num_scalars < 32 { - 3 - } else { - super::ln_without_floats(num_scalars) - } - } - - pub fn get_window_table(window: usize, g: T) -> Vec> { - let scalar_size = T::ScalarField::MODULUS_BIT_SIZE as usize; - let in_window = 1 << window; - let outerc = (scalar_size + window - 1) / window; - let last_in_window = 1 << (scalar_size - (outerc - 1) * window); - - let mut multiples_of_g = vec![vec![T::zero(); in_window]; outerc]; - - let mut g_outer = g; - let mut g_outers = Vec::with_capacity(outerc); - for _ in 0..outerc { - g_outers.push(g_outer); - for _ in 0..window { - g_outer.double_in_place(); - } - } - cfg_iter_mut!(multiples_of_g) - .enumerate() - .take(outerc) - .zip(g_outers) - .for_each(|((outer, multiples_of_g), g_outer)| { - let cur_in_window = if outer == outerc - 1 { - last_in_window - } else { - in_window - }; - - let mut g_inner = T::zero(); - for inner in multiples_of_g.iter_mut().take(cur_in_window) { - *inner = g_inner; - g_inner += &g_outer; - } - }); - cfg_iter!(multiples_of_g) - .map(|s| T::batch_convert_to_mul_base(s)) - .collect() - } - - fn windowed_mul( - outerc: usize, - window: usize, - multiples_of_g: &[Vec], - scalar: &T::ScalarField, - ) -> T { - let modulus_size = T::ScalarField::MODULUS_BIT_SIZE as usize; - let scalar_val = scalar.into_bigint().to_bits_le(); - - let mut res = T::from(multiples_of_g[0][0]); - for outer in 0..outerc { - let mut inner = 0usize; - for i in 0..window { - if outer * window + i < modulus_size && scalar_val[outer * window + i] { - inner |= 1 << i; - } - } - res += &multiples_of_g[outer][inner]; - } - res - } - - /// Compute the vector v[0].G, v[1].G, ..., v[n-1].G, given: - /// - an element `g` - /// - a list `v` of n scalars - /// - /// # Example - /// ``` - /// use ark_std::{One, UniformRand}; - /// use ark_ec::pairing::Pairing; - /// use ark_test_curves::bls12_381::G1Projective as G; - /// use ark_test_curves::bls12_381::Fr; - /// use ark_ec::scalar_mul::fixed_base::FixedBase; - /// - /// // Compute G, s.G, s^2.G, ..., s^9.G - /// let mut rng = ark_std::test_rng(); - /// let max_degree = 10; - /// let s = Fr::rand(&mut rng); - /// let g = G::rand(&mut rng); - /// let mut powers_of_s = vec![Fr::one()]; - /// let mut cur = s; - /// for _ in 0..max_degree { - /// powers_of_s.push(cur); - /// cur *= &s; - /// } - /// let powers_of_g: Vec = FixedBase::mul(g, &powers_of_s); - /// let naive_powers_of_g: Vec = powers_of_s.iter().map(|e| g * e).collect(); - /// assert_eq!(powers_of_g, naive_powers_of_g); - /// ``` - pub fn mul(g: T, v: &[T::ScalarField]) -> Vec { - let window_size = Self::get_mul_window_size(v.len()); - let table = Self::get_window_table::(window_size, g.clone()); - let scalar_size = T::ScalarField::MODULUS_BIT_SIZE as usize; - let outerc = (scalar_size + window_size - 1) / window_size; - assert!(outerc <= table.len()); - - cfg_iter!(v) - .map(|e| Self::windowed_mul::(outerc, window_size, &table, e)) - .collect::>() - } -} diff --git a/ec/src/scalar_mul/mod.rs b/ec/src/scalar_mul/mod.rs index 295597576..33645150e 100644 --- a/ec/src/scalar_mul/mod.rs +++ b/ec/src/scalar_mul/mod.rs @@ -1,17 +1,20 @@ pub mod glv; pub mod wnaf; -pub mod fixed_base; pub mod variable_base; use crate::short_weierstrass::{Affine, Projective, SWCurveConfig}; use crate::PrimeGroup; -use ark_ff::{AdditiveGroup, Zero}; +use ark_ff::{AdditiveGroup, Zero, PrimeField, BigInteger}; use ark_std::{ + cfg_iter, cfg_iter_mut, ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign}, vec::Vec, }; +#[cfg(feature = "parallel")] +use rayon::prelude::*; + /// The result of this function is only approximately `ln(a)` /// [`Explanation of usage`] /// @@ -74,9 +77,141 @@ pub trait ScalarMul: + core::hash::Hash + Mul + for<'a> Mul<&'a Self::ScalarField, Output = Self> - + Neg; + + Neg + + From; const NEGATION_IS_CHEAP: bool; fn batch_convert_to_mul_base(bases: &[Self]) -> Vec; + + /// Compute the vector v[0].G, v[1].G, ..., v[n-1].G, given: + /// - an element `g` + /// - a list `v` of n scalars + /// + /// # Example + /// ``` + /// use ark_std::{One, UniformRand}; + /// use ark_ec::pairing::Pairing; + /// use ark_test_curves::bls12_381::G1Projective as G; + /// use ark_test_curves::bls12_381::Fr; + /// use ark_ec::scalar_mul::fixed_base::FixedBase; + /// + /// // Compute G, s.G, s^2.G, ..., s^9.G + /// let mut rng = ark_std::test_rng(); + /// let max_degree = 10; + /// let s = Fr::rand(&mut rng); + /// let g = G::rand(&mut rng); + /// let mut powers_of_s = vec![Fr::one()]; + /// let mut cur = s; + /// for _ in 0..max_degree { + /// powers_of_s.push(cur); + /// cur *= &s; + /// } + /// let powers_of_g: Vec = g.batch_mul(&powers_of_s); + /// let naive_powers_of_g: Vec = powers_of_s.iter().map(|e| g * e).collect(); + /// assert_eq!(powers_of_g, naive_powers_of_g); + /// ``` + fn batch_mul(self, v: &[Self::ScalarField]) -> Vec { + let table = BatchMulPreprocessing::new(self, v.len()); + self.batch_mul_with_preprocessing(v, &table) + } + + fn batch_mul_with_preprocessing( + self, + v: &[Self::ScalarField], + preprocessing: &BatchMulPreprocessing, + ) -> Vec { + let result = cfg_iter!(v).map(|e| preprocessing.windowed_mul(e)).collect::>(); + Self::batch_convert_to_mul_base(&result) + } +} + +/// Preprocessing used internally for batch scalar multiplication via [`ScalarMul::batch_mul`]. +/// - `window` is the window size used for the precomputation +/// - `max_scalar_size` is the maximum size of the scalars that will be multiplied +/// - `table` is the precomputed table of multiples of `base` +pub struct BatchMulPreprocessing { + pub window: usize, + pub max_scalar_size: usize, + pub table: Vec>, +} + +impl BatchMulPreprocessing { + pub fn new(base: T, num_scalars: usize) -> Self { + let window = Self::window_size(num_scalars); + let scalar_size = T::ScalarField::MODULUS_BIT_SIZE as usize; + Self::with_window_and_scalar_size(base, window, scalar_size) + } + + fn window_size(num_scalars: usize) -> usize { + if num_scalars < 32 { + 3 + } else { + ln_without_floats(num_scalars) + } + } + + pub fn with_window_and_scalar_size( + base: T, + window: usize, + max_scalar_size: usize, + ) -> Self { + let in_window = 1 << window; + let outerc = (max_scalar_size + window - 1) / window; + let last_in_window = 1 << (max_scalar_size - (outerc - 1) * window); + + let mut multiples_of_g = vec![vec![T::zero(); in_window]; outerc]; + + let mut g_outer = base; + let mut g_outers = Vec::with_capacity(outerc); + for _ in 0..outerc { + g_outers.push(g_outer); + for _ in 0..window { + g_outer.double_in_place(); + } + } + cfg_iter_mut!(multiples_of_g) + .enumerate() + .take(outerc) + .zip(g_outers) + .for_each(|((outer, multiples_of_g), g_outer)| { + let cur_in_window = if outer == outerc - 1 { + last_in_window + } else { + in_window + }; + + let mut g_inner = T::zero(); + for inner in multiples_of_g.iter_mut().take(cur_in_window) { + *inner = g_inner; + g_inner += &g_outer; + } + }); + let table = cfg_iter!(multiples_of_g) + .map(|s| T::batch_convert_to_mul_base(s)) + .collect(); + Self { + window, + max_scalar_size, + table, + } + } + + fn windowed_mul(&self, scalar: &T::ScalarField) -> T { + let outerc = (self.max_scalar_size + self.window - 1) / self.window; + let modulus_size = T::ScalarField::MODULUS_BIT_SIZE as usize; + let scalar_val = scalar.into_bigint().to_bits_le(); + + let mut res = T::from(self.table[0][0]); + for outer in 0..outerc { + let mut inner = 0usize; + for i in 0..self.window { + if outer * self.window + i < modulus_size && scalar_val[outer * self.window + i] { + inner |= 1 << i; + } + } + res += &self.table[outer][inner]; + } + res + } } From b95fada74946dd360d72b919b6c1815319395739 Mon Sep 17 00:00:00 2001 From: Pratyush Mishra Date: Sun, 14 Jan 2024 16:33:17 -0500 Subject: [PATCH 09/11] Tweak --- ec/src/scalar_mul/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ec/src/scalar_mul/mod.rs b/ec/src/scalar_mul/mod.rs index 33645150e..7000e5119 100644 --- a/ec/src/scalar_mul/mod.rs +++ b/ec/src/scalar_mul/mod.rs @@ -138,12 +138,12 @@ pub struct BatchMulPreprocessing { impl BatchMulPreprocessing { pub fn new(base: T, num_scalars: usize) -> Self { - let window = Self::window_size(num_scalars); + let window = Self::compute_window_size(num_scalars); let scalar_size = T::ScalarField::MODULUS_BIT_SIZE as usize; Self::with_window_and_scalar_size(base, window, scalar_size) } - fn window_size(num_scalars: usize) -> usize { + fn compute_window_size(num_scalars: usize) -> usize { if num_scalars < 32 { 3 } else { From 1365f715deb909b93ce88dbc166ebfabb1ee1208 Mon Sep 17 00:00:00 2001 From: Pratyush Mishra Date: Sun, 14 Jan 2024 16:56:15 -0500 Subject: [PATCH 10/11] Format --- ec/src/scalar_mul/mod.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/ec/src/scalar_mul/mod.rs b/ec/src/scalar_mul/mod.rs index 12baf6869..2701e9454 100644 --- a/ec/src/scalar_mul/mod.rs +++ b/ec/src/scalar_mul/mod.rs @@ -7,7 +7,7 @@ use crate::{ short_weierstrass::{Affine, Projective, SWCurveConfig}, PrimeGroup, }; -use ark_ff::{AdditiveGroup, Zero, PrimeField, BigInteger}; +use ark_ff::{AdditiveGroup, BigInteger, PrimeField, Zero}; use ark_std::{ cfg_iter, cfg_iter_mut, ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign}, @@ -123,7 +123,9 @@ pub trait ScalarMul: v: &[Self::ScalarField], preprocessing: &BatchMulPreprocessing, ) -> Vec { - let result = cfg_iter!(v).map(|e| preprocessing.windowed_mul(e)).collect::>(); + let result = cfg_iter!(v) + .map(|e| preprocessing.windowed_mul(e)) + .collect::>(); Self::batch_convert_to_mul_base(&result) } } @@ -153,11 +155,7 @@ impl BatchMulPreprocessing { } } - pub fn with_window_and_scalar_size( - base: T, - window: usize, - max_scalar_size: usize, - ) -> Self { + pub fn with_window_and_scalar_size(base: T, window: usize, max_scalar_size: usize) -> Self { let in_window = 1 << window; let outerc = (max_scalar_size + window - 1) / window; let last_in_window = 1 << (max_scalar_size - (outerc - 1) * window); From b98babb84aaf3c9116fdd1b345a06bea59c3269d Mon Sep 17 00:00:00 2001 From: Pratyush Mishra Date: Sun, 14 Jan 2024 16:59:21 -0500 Subject: [PATCH 11/11] Fix doc test --- ec/src/scalar_mul/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ec/src/scalar_mul/mod.rs b/ec/src/scalar_mul/mod.rs index 2701e9454..bcf17843b 100644 --- a/ec/src/scalar_mul/mod.rs +++ b/ec/src/scalar_mul/mod.rs @@ -96,7 +96,7 @@ pub trait ScalarMul: /// use ark_ec::pairing::Pairing; /// use ark_test_curves::bls12_381::G1Projective as G; /// use ark_test_curves::bls12_381::Fr; - /// use ark_ec::scalar_mul::fixed_base::FixedBase; + /// use ark_ec::scalar_mul::ScalarMul; /// /// // Compute G, s.G, s^2.G, ..., s^9.G /// let mut rng = ark_std::test_rng(); @@ -109,7 +109,7 @@ pub trait ScalarMul: /// powers_of_s.push(cur); /// cur *= &s; /// } - /// let powers_of_g: Vec = g.batch_mul(&powers_of_s); + /// let powers_of_g = g.batch_mul(&powers_of_s); /// let naive_powers_of_g: Vec = powers_of_s.iter().map(|e| g * e).collect(); /// assert_eq!(powers_of_g, naive_powers_of_g); /// ```