Skip to content

Commit

Permalink
Add ec:msm:{Fixed,Variable}Base:msm_checked_len
Browse files Browse the repository at this point in the history
Add the new methods for checked fixed and variable base multi-scalar
multiplication. They will return `None` if the arguments don't have the
same length.

This way, the users may confidently call this function without having to
check the length themselves.

Also, `ec:msm:{Fixed,Variable}BaseMSM` was renamed to
`ec:msm::{Fixed,Variable}Base` to avoid redundancy. The import path
contained `msm` several times, and now it contains only one incidence
for the type resolution and one for the function call.

Closes #319
  • Loading branch information
vlopes11 committed Nov 16, 2021
1 parent 15f48e3 commit aa8540c
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 10 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
- [\#338](https://github.com/arkworks-rs/algebra/pull/338) (ark-ec) Add missing `UniformRand` trait bound to `GroupAffine`.
- [\#338](https://github.com/arkworks-rs/algebra/pull/338) (workspace) Change to Rust 2021 edition.
- [\#345](https://github.com/arkworks-rs/algebra/pull/345) (arc-ec, ark-serialize) Change the serialization format for Twisted Edwards Curves. We now encode the Y coordinate and take the sign bit of the X co-ordinate, the default flag is also now the Positive X value. The old methods for backwards compatibility are located [here](https://github.com/arkworks-rs/algebra/pull/345/files#diff-3621a48bb33f469144044d8d5fc663f767e103132a764812cda6be6c25877494R860)
- [\#348](https://github.com/arkworks-rs/algebra/pull/348) (arc-ec) Rename `msm:{Fixed,Variable}BaseMSM:multi_scalar_mul` to `msm:{Fixed,Variable}:msm` to avoid redundancy.

### Features

- [\#321](https://github.com/arkworks-rs/algebra/pull/321) (ark-ff) Change bigint conversions to impl `From` instead of `Into`.
- [\#301](https://github.com/arkworks-rs/algebra/pull/301) (ark-ec) Add `GLVParameters` trait definition.
- [\#312](https://github.com/arkworks-rs/algebra/pull/312) (ark-ec) Add `is_in_correct_subgroup_assuming_on_curve` for all `SWModelParameters`.
- [\#348](https://github.com/arkworks-rs/algebra/pull/348) (ark-ec) Add `msm:{Fixed,Variable}Base:msm_checked_len`.

### Improvements

Expand Down
8 changes: 5 additions & 3 deletions ec/src/msm/fixed_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use ark_std::{cfg_iter, cfg_iter_mut, vec::Vec};
#[cfg(feature = "parallel")]
use rayon::prelude::*;

pub struct FixedBaseMSM;
pub struct FixedBase;

impl FixedBaseMSM {
impl FixedBase {
pub fn get_mul_window_size(num_scalars: usize) -> usize {
if num_scalars < 32 {
3
Expand Down Expand Up @@ -79,7 +79,9 @@ impl FixedBaseMSM {
res
}

pub fn multi_scalar_mul<T: ProjectiveCurve>(
// TODO use const-generics for the scalar size and window
// TODO use iterators of iterators of T::Affine instead of taking owned Vec
pub fn msm<T: ProjectiveCurve>(
scalar_size: usize,
window: usize,
table: &[Vec<T::Affine>],
Expand Down
26 changes: 23 additions & 3 deletions ec/src/msm/variable_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,30 @@ use crate::{AffineCurve, ProjectiveCurve};
#[cfg(feature = "parallel")]
use rayon::prelude::*;

pub struct VariableBaseMSM;
pub struct VariableBase;

impl VariableBaseMSM {
pub fn multi_scalar_mul<G: AffineCurve>(
impl VariableBase {
/// Optimized implementation of multi-scalar multiplication.
///
/// Will return `None` if `bases` and `scalar` have different lengths.
///
/// Reference: [`VariableBase::msm`]
pub fn msm_checked_len<G: AffineCurve>(
bases: &[G],
scalars: &[<G::ScalarField as PrimeField>::BigInt],
) -> Option<G::Projective> {
(bases.len() == scalars.len()).then(|| Self::msm(bases, scalars))
}

/// Optimized implementation of multi-scalar multiplication.
///
/// Will multiply the tuples of the diagonal product of `bases × scalars`
/// and sum the resulting set. Will iterate only for the elements of the
/// smallest of the two sets, ignoring the remaining elements of the biggest
/// set.
///
/// ∑i (Bi · Si)
pub fn msm<G: AffineCurve>(
bases: &[G],
scalars: &[<G::ScalarField as PrimeField>::BigInt],
) -> G::Projective {
Expand Down
7 changes: 6 additions & 1 deletion test-curves/src/bls12_381/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine, ProjectiveCu
use ark_ff::{Field, One, UniformRand, Zero};

use crate::bls12_381::{g1, Fq, Fq2, Fq6, FqParameters, Fr, G1Affine, G1Projective};
use ark_algebra_test_templates::{curves::*, fields::*, groups::*};
use ark_algebra_test_templates::{curves::*, fields::*, groups::*, msm::*};
use ark_std::rand::Rng;

pub(crate) const ITERATIONS: usize = 5;
Expand Down Expand Up @@ -55,6 +55,11 @@ fn test_fq6() {
frobenius_test::<Fq6, _>(Fq::characteristic(), 13);
}

#[test]
fn test_g1_affine_curve() {
test_var_base_msm::<G1Affine>();
}

#[test]
fn test_g1_projective_curve() {
curve_tests::<G1Projective>();
Expand Down
7 changes: 6 additions & 1 deletion test-curves/src/bn384_small_two_adicity/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ark_ff::{One, UniformRand, Zero};
use ark_std::rand::Rng;

use crate::bn384_small_two_adicity::{g1, Fq, FqParameters, Fr, G1Affine, G1Projective};
use ark_algebra_test_templates::{curves::*, fields::*, groups::*};
use ark_algebra_test_templates::{curves::*, fields::*, groups::*, msm::*};

pub(crate) const ITERATIONS: usize = 5;

Expand Down Expand Up @@ -32,6 +32,11 @@ fn test_fq() {
}
}

#[test]
fn test_g1_affine_curve() {
test_var_base_msm::<G1Affine>();
}

#[test]
fn test_g1_projective_curve() {
curve_tests::<G1Projective>();
Expand Down
4 changes: 2 additions & 2 deletions test-templates/src/msm.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use ark_ec::{msm::VariableBaseMSM, AffineCurve, ProjectiveCurve};
use ark_ec::{msm::VariableBase, AffineCurve, ProjectiveCurve};
use ark_ff::{PrimeField, UniformRand, Zero};

fn naive_var_base_msm<G: AffineCurve>(
Expand Down Expand Up @@ -27,7 +27,7 @@ pub fn test_var_base_msm<G: AffineCurve>() {
let g = <G::Projective as ProjectiveCurve>::batch_normalization_into_affine(&g);

let naive = naive_var_base_msm(g.as_slice(), v.as_slice());
let fast = VariableBaseMSM::multi_scalar_mul(g.as_slice(), v.as_slice());
let fast = VariableBase::msm(g.as_slice(), v.as_slice());

assert_eq!(naive.into_affine(), fast.into_affine());
}

0 comments on commit aa8540c

Please sign in to comment.