Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding wNAF multiplication functionality #230

Merged
merged 24 commits into from
Mar 25, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ The main features of this release are:
- #140 (ark-poly) Add support for multilinear extensions in dense and sparse evaluation form.
- #164 (ark-ff) Add methods `from_{be, le}_bytes_mod_order` to the `PrimeField` trait.
- #197 (ark-test-curves) Add a BN384 curve with low two-arity for mixed-radix testing.
- #230 (ark-ec) Add `wnaf_mul` implementation for `ProjectiveCurve`.

### Improvements
- #22 (ark-ec) Speedup fixed-base MSMs
Expand Down
2 changes: 2 additions & 0 deletions ec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ pub mod group;

pub mod msm;

pub mod wnaf;

pub trait PairingEngine: Sized + 'static + Copy + Debug + Sync + Send + Eq + PartialEq {
/// This is the scalar field of the G1/G2 groups.
type Fr: PrimeField + SquareRootField;
Expand Down
42 changes: 42 additions & 0 deletions ec/src/wnaf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
extern crate alloc;
use crate::ProjectiveCurve;
use alloc::vec::Vec;
ggkitsas marked this conversation as resolved.
Show resolved Hide resolved

// Computes scalar multiplication of a preprocessed group element by a scalar in windowed non-adjacent form (wNAF).
// `scalar_wnaf` is expected in its NAF form which can be obtained by using `find_wnaf` on the underlying BigInt.
// `table` holds pre-computed multiples of the group element; it can be calculated using `wnaf_table`.
pub fn wnaf_mul<G: ProjectiveCurve>(table: &[G], scalar_wnaf: &[i64]) -> G {
Pratyush marked this conversation as resolved.
Show resolved Hide resolved
let mut result = G::zero();

let mut found_non_zero = false;

for n in scalar_wnaf.iter().rev() {
if found_one {
ggkitsas marked this conversation as resolved.
Show resolved Hide resolved
result.double_in_place();
}

if *n != 0 {
found_non_zero = true;

if *n > 0 {
result += &table[(n / 2) as usize];
Pratyush marked this conversation as resolved.
Show resolved Hide resolved
} else {
result -= &table[((-n) / 2) as usize];
}
}
}

result
}

pub fn wnaf_table<G: ProjectiveCurve>(mut base: G, window: usize) -> Vec<G> {
let mut table = Vec::with_capacity(1 << (window - 1));

let dbl = base.double();

for _ in 0..(1 << (window - 1)) {
table.push(base);
base += &dbl;
}
table
}
13 changes: 13 additions & 0 deletions test-templates/src/curves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ use ark_ec::{
AffineCurve, MontgomeryModelParameters, ProjectiveCurve, SWModelParameters, TEModelParameters,
};
use ark_ff::{Field, One, PrimeField, UniformRand, Zero};
use ark_ff::BigInteger;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SWFlags, SerializationError};
use ark_std::{io::Cursor, vec::Vec};
use ark_ec::wnaf::{wnaf_mul, wnaf_table};

pub const ITERATIONS: usize = 10;

Expand Down Expand Up @@ -103,6 +105,17 @@ fn random_multiplication_test<G: ProjectiveCurve>() {
tmp1.add_assign(&b);
tmp1.mul_assign(s);

// s ( a + b) using wNAF for several window values in [2,5]
for w in 2..=5 {
let mut tmp4 = a;
tmp4.add_assign(&b);

let scalar_wnaf = s.into_repr().find_wnaf();
let wnaf_lut = wnaf_table(tmp4, w);

assert_eq!(tmp1, wnaf_mul(&wnaf_lut, &scalar_wnaf));
}

// sa + sb
a.mul_assign(s);
b.mul_assign(s);
Expand Down
2 changes: 2 additions & 0 deletions test-templates/src/groups.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![allow(unused)]
use ark_ec::group::Group;
use ark_ff::fields::PrimeField;
use ark_ff::{One, UniformRand, Zero};

pub fn group_test<G: Group>(a: G, mut b: G) {
Expand All @@ -8,6 +9,7 @@ pub fn group_test<G: Group>(a: G, mut b: G) {
let fr_zero = G::ScalarField::zero();
let fr_one = G::ScalarField::one();
let fr_two = fr_one + &fr_one;

assert_eq!(zero, zero);
assert_eq!(zero.is_zero(), true);
assert_eq!(a.mul(&fr_one), a);
Expand Down