Skip to content
This repository has been archived by the owner on Jun 20, 2023. It is now read-only.

Commit

Permalink
Merge pull request #7 from Brechtpd/msm
Browse files Browse the repository at this point in the history
MSM optimization
  • Loading branch information
kilic authored May 3, 2022
2 parents 3721879 + c616fb2 commit 1da2920
Show file tree
Hide file tree
Showing 8 changed files with 263 additions and 20 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pairing_bn256"
version = "0.1.0"
version = "0.1.1"
authors = [
"Sean Bowe <[email protected]>",
"Jack Grigg <[email protected]>",
Expand Down Expand Up @@ -30,6 +30,7 @@ rand_core = { version = "0.6", default-features = false }
[features]
default = []
asm = []
prefetch = []

[profile.bench]
opt-level = 3
Expand Down
17 changes: 17 additions & 0 deletions src/arithmetic/curves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,23 @@ pub trait CurveAffine:

/// Returns the curve constant $b$.
fn b() -> Self::Base;

/// Obtains the endomorphism base.
fn get_endomorphism_base(base: &Self) -> Self;

/// Obtains the endomorphism scalars.
fn get_endomorphism_scalars(k: &Self::ScalarExt) -> (u128, u128);

/// Batched point addition.
/// If COMPLETE is set to false the points need to be linearly independent.
fn batch_add<const COMPLETE: bool, const LOAD_POINTS: bool>(
points: &mut [Self],
output_indices: &[u32],
num_points: usize,
offset: usize,
bases: &[Self],
base_positions: &[u32],
);
}

/// The affine coordinates of a point on an elliptic curve.
Expand Down
33 changes: 33 additions & 0 deletions src/arithmetic/fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,36 @@ pub(crate) const fn mac(a: u64, b: u64, c: u64, carry: u64) -> (u64, u64) {
let ret = (a as u128) + ((b as u128) * (c as u128)) + (carry as u128);
(ret as u64, (ret >> 64) as u64)
}

/// Compute a + (b * c), returning the result and the new carry over.
#[inline(always)]
pub(crate) const fn macx(a: u64, b: u64, c: u64) -> (u64, u64) {
let res = (a as u128) + ((b as u128) * (c as u128));
(res as u64, (res >> 64) as u64)
}

/// Compute a * b, returning the result.
#[inline(always)]
pub(crate) fn mul_512(a: [u64; 4], b: [u64; 4]) -> [u64; 8] {
let (r0, carry) = macx(0, a[0], b[0]);
let (r1, carry) = macx(carry, a[0], b[1]);
let (r2, carry) = macx(carry, a[0], b[2]);
let (r3, carry_out) = macx(carry, a[0], b[3]);

let (r1, carry) = macx(r1, a[1], b[0]);
let (r2, carry) = mac(r2, a[1], b[1], carry);
let (r3, carry) = mac(r3, a[1], b[2], carry);
let (r4, carry_out) = mac(carry_out, a[1], b[3], carry);

let (r2, carry) = macx(r2, a[2], b[0]);
let (r3, carry) = mac(r3, a[2], b[1], carry);
let (r4, carry) = mac(r4, a[2], b[2], carry);
let (r5, carry_out) = mac(carry_out, a[2], b[3], carry);

let (r3, carry) = macx(r3, a[3], b[0]);
let (r4, carry) = mac(r4, a[3], b[1], carry);
let (r5, carry) = mac(r5, a[3], b[2], carry);
let (r6, carry_out) = mac(carry_out, a[3], b[3], carry);

[r0, r1, r2, r3, r4, r5, r6, carry_out]
}
2 changes: 1 addition & 1 deletion src/bn256/assembly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ macro_rules! assembly_field {
}

#[inline(always)]
fn montgomery_reduce(a: &[u64; 8]) -> $field {
pub(crate) fn montgomery_reduce(a: &[u64; 8]) -> $field {
let mut r0: u64;
let mut r1: u64;
let mut r2: u64;
Expand Down
2 changes: 1 addition & 1 deletion src/bn256/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ macro_rules! common_field {

#[allow(clippy::too_many_arguments)]
#[inline(always)]
const fn montgomery_reduce(
pub(crate) const fn montgomery_reduce(
r0: u64,
r1: u64,
r2: u64,
Expand Down
30 changes: 29 additions & 1 deletion src/bn256/g.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::arithmetic::{BaseExt, Coordinates, CurveAffine, CurveExt, Group};
use crate::arithmetic::mul_512;
use crate::arithmetic::{BaseExt, Coordinates, CurveAffine, CurveExt, FieldExt, Group};
use crate::bn256::Fq;
use crate::bn256::Fq2;
use crate::bn256::Fr;
Expand All @@ -22,6 +23,7 @@ new_curve_impl!(
Fr,
(G1_GENERATOR_X,G1_GENERATOR_Y),
G1_B,
ENDO_G1_CUBE_ROOT,
"bn256_g1"
);

Expand All @@ -34,12 +36,38 @@ new_curve_impl!(
Fr,
(G2_GENERATOR_X, G2_GENERATOR_Y),
G2_B,
ENDO_G2_CUBE_ROOT,
"bn256_g2"
);

const G1_GENERATOR_X: Fq = Fq::one();
const G1_GENERATOR_Y: Fq = Fq::from_raw([2, 0, 0, 0]);
const G1_B: Fq = Fq::from_raw([3, 0, 0, 0]);
const ENDO_G1: [u64; 4] = [
0x7a7bd9d4391eb18du64,
0x4ccef014a773d2cfu64,
0x0000000000000002u64,
0u64,
];
const ENDO_G2: [u64; 4] = [0xd91d232ec7e0b3d7u64, 0x0000000000000002u64, 0u64, 0u64];
const ENDO_MINUS_B1: [u64; 4] = [0x8211bbeb7d4f1128u64, 0x6f4d8248eeb859fcu64, 0u64, 0u64];
const ENDO_B2: [u64; 4] = [0x89d3256894d213e3u64, 0u64, 0u64, 0u64];
const ENDO_BETA: Fr = Fr::from_raw([
0x8b17ea66b99c90ddu64,
0x5bfc41088d8daaa7u64,
0xb3c4d79d41a91758u64,
0x0u64,
]);
const ENDO_G1_CUBE_ROOT: Fq = Fq::from_raw([
0x5763473177fffffeu64,
0xd4f263f1acdb5c4fu64,
0x59e26bcea0d48bacu64,
0x0u64,
]);
const ENDO_G2_CUBE_ROOT: Fq2 = Fq2 {
c0: Fq::zero(),
c1: Fq::zero(),
};

impl group::cofactor::CofactorGroup for G1 {
type Subgroup = G1;
Expand Down
Loading

0 comments on commit 1da2920

Please sign in to comment.