Skip to content

Commit

Permalink
Performance improvements and cleanups (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
clintfred authored and coltfred committed Feb 7, 2019
1 parent 1c01789 commit d941b5e
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 91 deletions.
94 changes: 32 additions & 62 deletions src/internal/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,6 @@ pub trait ExtensionField: Field
where
Self: Sized + From<u8>,
{
/// Xi is u + 3 which is v^3.
/// v^p == Xi^((p-1)/3) * v
fn xi() -> Fp2Elem<Self> {
Fp2Elem {
elem1: Self::one(),
elem2: Self::from(3u8),
}
}
///Precomputed xi.inv() * 9
fn xi_inv_times_9() -> Fp2Elem<Self>;

Expand All @@ -151,29 +143,24 @@ where

///v is the thing that cubes to xi
///v^3 = u+3, because by definition it is a solution to the equation y^3 - (u + 3)
#[inline]
fn v() -> Fp6Elem<Self> {
Fp6Elem {
elem1: Zero::zero(),
elem2: One::one(),
elem3: Zero::zero(),
}
}

/// 3 / (u+3)
/// pre-calculate as an optimization
/// ExtensionField::xi().inv() * 3;
fn twisted_curve_const_coeff() -> Fp2Elem<Self>;
}

impl ExtensionField for fp_256::Monty {
fn xi() -> Fp2Elem<Self> {
Fp2Elem {
elem1: fp_256::Monty::new([
1368961080, 1174866893, 1632604085, 2004383869, 1511972380, 1964912876, 1176826515,
403865604, 70,
]),
elem2: fp_256::Monty::new([
381778497, 559663760, 555210920, 1938629360, 1980684343, 291306425, 697096529,
1840680552, 66,
]),
}
}
//precalculate this since it's used in every double and add operation in the extension field.
//xi is u + 3 or Fp2Elem(1, 3)
// Fp256::xi().inv() * 9
fn xi_inv_times_9() -> Fp2Elem<Self> {
Fp2Elem {
Expand Down Expand Up @@ -236,39 +223,24 @@ impl ExtensionField for fp_256::Monty {
}
}

///v is the thing that cubes to xi
///v^3 = u+3, because by definition it is a solution to the equation y^3 - (u + 3)
fn v() -> Fp6Elem<Self> {
Fp6Elem {
elem1: Zero::zero(),
elem2: Fp2Elem {
elem1: Zero::zero(),
elem2: fp_256::Monty::new([
1368961080, 1174866893, 1632604085, 2004383869, 1511972380, 1964912876,
1176826515, 403865604, 70,
]),
},
elem3: Zero::zero(),
}
}
}

impl ExtensionField for fp_480::Monty {
fn xi() -> Fp2Elem<Self> {
#[inline]
fn twisted_curve_const_coeff() -> Fp2Elem<Self> {
Fp2Elem {
elem1: fp_480::Monty::new([
1588384315, 657481659, 1879608514, 2019977405, 241404753, 1339062904, 639566708,
740072562, 1004131918, 1560224833, 2014075, 1848411426, 1733309265, 1811487384,
799788540, 19667,
elem1: fp_256::Monty::new([
1925150376, 516250914, 1051564560, 1369812449, 731601065, 672046428, 625168271,
1952553705, 93,
]),
elem2: fp_480::Monty::new([
1562186266, 585547362, 445363961, 373107586, 235669429, 70320378, 1725584133,
1655137918, 674554062, 1273113365, 570248622, 1027777883, 144574781, 808941279,
1969907309, 26235,
elem2: fp_256::Monty::new([
1674758358, 86153800, 1235541696, 1892123501, 768178752, 600790531, 1643777575,
1474105998, 5,
]),
}
}
}

impl ExtensionField for fp_480::Monty {
// precalculate this since it's used in every double and add operation in the extension field.
// xi is u + 3 or Fp2Elem(1, 3)
// Fp480::xi().inv() * 9
fn xi_inv_times_9() -> Fp2Elem<Self> {
Fp2Elem {
Expand Down Expand Up @@ -335,21 +307,19 @@ impl ExtensionField for fp_480::Monty {
}
}

///v is the thing that cubes to xi
///v^3 = u+3, because by definition it is a solution to the equation y^3 - (u + 3)
fn v() -> Fp6Elem<Self> {
Fp6Elem {
elem1: Zero::zero(),
elem2: Fp2Elem {
elem1: Zero::zero(),
//This is 1 in monty form
elem2: fp_480::Monty::new([
1588384315, 657481659, 1879608514, 2019977405, 241404753, 1339062904,
639566708, 740072562, 1004131918, 1560224833, 2014075, 1848411426, 1733309265,
1811487384, 799788540, 19667,
]),
},
elem3: Zero::zero(),
#[inline]
fn twisted_curve_const_coeff() -> Fp2Elem<Self> {
Fp2Elem {
elem1: fp_480::Monty::new([
1976657987, 2124705180, 1103755761, 1290923474, 2085255841, 1647224075, 1270424569,
286550022, 1158572853, 451253923, 1853842034, 2007948773, 1667592921, 2116284018,
790821013, 23589,
]),
elem2: fp_480::Monty::new([
1531442428, 2081544602, 1531699218, 302801582, 1652317917, 456481830, 1063041565,
835589236, 1390322869, 278987042, 1335789303, 1086071918, 1573345690, 1085259625,
1063395545, 27530,
]),
}
}
}
49 changes: 45 additions & 4 deletions src/internal/fp2elem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,41 @@ pub struct Fp2Elem<T> {
pub elem2: T,
}

/// Xi is u + 3 which is v^3.
/// v^p == Xi^((p-1)/3) * v
/// This is an empty type which allows for Fp2 * Xi in order to multiply the fp2 element * Fp2(1, 3).
pub struct Xi;

impl<T> Mul<Fp2Elem<T>> for Xi
where
T: Mul<u32, Output = T> + Sub<Output = T> + Add<Output = T> + Copy,
{
type Output = Fp2Elem<T>;
#[inline]
fn mul(self, fp2: Fp2Elem<T>) -> Fp2Elem<T> {
fp2 * self
}
}

impl<T> Mul<Xi> for Fp2Elem<T>
where
T: Mul<u32, Output = T> + Sub<Output = T> + Add<Output = T> + Copy,
{
type Output = Fp2Elem<T>;
///This is a shorthand for multiplying times u + 3.
/// (a*u+b)*(u+3) = -a+3b + u*(3a+b)
/// In this case we expand out the additions.
#[inline]
fn mul(self, _xi: Xi) -> Self {
Fp2Elem {
//3a+b
elem1: self.elem1 + self.elem1 + self.elem1 + self.elem2,
//-a+3b
elem2: self.elem2 + self.elem2 + self.elem2 - self.elem1,
}
}
}

impl<T> fmt::Debug for Fp2Elem<T>
where
T: fmt::Debug,
Expand Down Expand Up @@ -175,14 +210,20 @@ where

impl<T> Inv for Fp2Elem<T>
where
T: Pow<u32, Output = T> + Add<Output = T> + Neg<Output = T> + Div<Output = T> + Copy,
T: Pow<u32, Output = T>
+ Add<Output = T>
+ Neg<Output = T>
+ Mul<Output = T>
+ Inv<Output = T>
+ Copy,
{
type Output = Fp2Elem<T>;
fn inv(self) -> Fp2Elem<T> {
let mag = self.elem1.pow(2) + self.elem2.pow(2);
let magnitude = self.elem1.pow(2) + self.elem2.pow(2);
let mag_inv = magnitude.inv();
Fp2Elem {
elem1: (-self.elem1 / mag),
elem2: (self.elem2 / mag),
elem1: (-self.elem1 * mag_inv),
elem2: (self.elem2 * mag_inv),
}
}
}
Expand Down
27 changes: 11 additions & 16 deletions src/internal/fp6elem.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::internal::bytedecoder::{BytesDecoder, DecodeErr};
use crate::internal::field::{ExtensionField, Field};
use crate::internal::fp2elem::Fp2Elem;
use crate::internal::fp2elem::{Fp2Elem, Xi};
use crate::internal::hashable::Hashable;
use crate::internal::ByteVector;
use crate::internal::{pow_for_square, sum_n, Square};
Expand Down Expand Up @@ -158,12 +158,11 @@ where

let elem1 = self.elem1 * other.elem3 + self.elem2 * other.elem2 + self.elem3 * other.elem1;

let elem2 = self.elem1 * other.elem1 * ExtensionField::xi()
+ self.elem2 * other.elem3
+ self.elem3 * other.elem2;
let elem2 =
self.elem1 * other.elem1 * Xi + self.elem2 * other.elem3 + self.elem3 * other.elem2;

let elem3 = (self.elem1 * other.elem2 + self.elem2 * other.elem1) * ExtensionField::xi()
+ self.elem3 * other.elem3;
let elem3 =
(self.elem1 * other.elem2 + self.elem2 * other.elem1) * Xi + self.elem3 * other.elem3;

Fp6Elem {
elem1,
Expand Down Expand Up @@ -215,8 +214,6 @@ where
{
type Output = Fp6Elem<T>;
fn inv(self) -> Fp6Elem<T> {
let xi: Fp2Elem<T> = ExtensionField::xi();

// Algorithm 5.23 from El Mrabet--Joye 2017 "Guide to Pairing-Based Cryptography."
let (c, b, a) = (self.elem1, self.elem2, self.elem3);
let v0 = a.square();
Expand All @@ -225,12 +222,12 @@ where
let v3 = a * b;
let v4 = a * c;
let v5 = b * c;
let cap_a = v0 - xi * v5;
let cap_b = xi * v2 - v3;
let cap_a = v0 - Xi * v5;
let cap_b = Xi * v2 - v3;
let cap_c = v1 - v4;
let v6 = a * cap_a;
let v61 = v6 + (xi * c * cap_b);
let v62 = v61 + (xi * b * cap_c);
let v61 = v6 + (Xi * c * cap_b);
let v62 = v61 + (Xi * b * cap_c);
let cap_f = v62.inv();
let c0 = cap_a * cap_f;
let c1 = cap_b * cap_f;
Expand Down Expand Up @@ -269,15 +266,13 @@ where
T: Clone + ExtensionField,
{
fn square(&self) -> Self {
let xi: Fp2Elem<T> = ExtensionField::xi();

let a_prime = Fp2Elem {
elem1: self.elem1.elem1 * 2,
elem2: self.elem1.elem2 * 2,
};
let a2 = a_prime * self.elem3 + self.elem2.square();
let fp22 = self.elem1.square() * xi + self.elem2 * self.elem3 * 2;
let fp32 = (a_prime * self.elem2) * xi + self.elem3.square();
let fp22 = self.elem1.square() * Xi + self.elem2 * self.elem3 * 2;
let fp32 = (a_prime * self.elem2) * Xi + self.elem3.square();
Fp6Elem {
elem1: a2,
elem2: fp22,
Expand Down
8 changes: 1 addition & 7 deletions src/internal/homogeneouspoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,16 +344,13 @@ impl<T: ExtensionField + BytesDecoder> BytesDecoder for TwistedHPoint<T> {
/// Decodes and validates that the resultant TwistedHPoint is on the curve
fn decode(bytes: ByteVector) -> Result<Self, DecodeErr> {
if bytes.len() == Self::ENCODED_SIZE_BYTES {
// 3 / (u + 3)
let twisted_curve_const_coeff: Fp2Elem<T> = ExtensionField::xi().inv() * 3;

let (x_bytes, y_bytes) = bytes.split_at(Self::ENCODED_SIZE_BYTES / 2);
let hpoint = TwistedHPoint::new(
Fp2Elem::<T>::decode(x_bytes.to_vec())?,
Fp2Elem::<T>::decode(y_bytes.to_vec())?,
);

if hpoint.y.pow(2) == (hpoint.x.pow(3) + twisted_curve_const_coeff) {
if hpoint.y.pow(2) == (hpoint.x.pow(3) + ExtensionField::twisted_curve_const_coeff()) {
Result::Ok(hpoint)
} else {
Result::Err(DecodeErr::BytesInvalid {
Expand Down Expand Up @@ -438,9 +435,6 @@ where
// "Complete addition formulas for prime order elliptic curves",
// https://eprint.iacr.org/2015/1060
// (For y^2=x^3+b, doubling formulas, page 12.)
// Mind that the main curve uses b = 3, but the twisted curve uses
// b = 3/(u+3). The code below _assumes_ that the twisted curve is used
// when the base field is FP2Elem (this is quite ugly).
fn double<T, U>(x: T, y: T, z: T, three_b: U) -> (T, T, T)
where
T: Field + Copy + Mul<U, Output = T>,
Expand Down
4 changes: 2 additions & 2 deletions src/internal/pairing.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::internal::field::ExtensionField;
use crate::internal::fp12elem::Fp12Elem;
use crate::internal::fp2elem::Fp2Elem;
use crate::internal::fp2elem::{Fp2Elem, Xi};
use crate::internal::fp6elem::Fp6Elem;
use crate::internal::homogeneouspoint::Double;
use crate::internal::homogeneouspoint::HomogeneousPoint;
Expand Down Expand Up @@ -236,7 +236,7 @@ where
elem2: y,
elem3: x,
} = b2;
let z2 = z * ExtensionField::xi() + One::one();
let z2 = z * Xi + One::one();
Fp12Elem {
elem1: a2,
elem2: Fp6Elem {
Expand Down

0 comments on commit d941b5e

Please sign in to comment.