use ark_ec::{msm::VariableBaseMSM, AffineCurve, ProjectiveCurve};
|
|
use ark_ff::{PrimeField, UniformRand, Zero};
|
|
use rand::SeedableRng;
|
|
use rand_xorshift::XorShiftRng;
|
|
|
|
fn naive_var_base_msm<G: AffineCurve>(
|
|
bases: &[G],
|
|
scalars: &[<G::ScalarField as PrimeField>::BigInt],
|
|
) -> G::Projective {
|
|
let mut acc = G::Projective::zero();
|
|
|
|
for (base, scalar) in bases.iter().zip(scalars.iter()) {
|
|
acc += &base.mul(*scalar);
|
|
}
|
|
acc
|
|
}
|
|
|
|
pub fn test_var_base_msm<G: AffineCurve>() {
|
|
const SAMPLES: usize = 1 << 10;
|
|
|
|
let mut rng = XorShiftRng::seed_from_u64(234872845u64);
|
|
|
|
let v = (0..SAMPLES - 1)
|
|
.map(|_| G::ScalarField::rand(&mut rng).into_repr())
|
|
.collect::<Vec<_>>();
|
|
let g = (0..SAMPLES)
|
|
.map(|_| G::Projective::rand(&mut rng))
|
|
.collect::<Vec<_>>();
|
|
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());
|
|
|
|
assert_eq!(naive.into_affine(), fast.into_affine());
|
|
}
|