This is an automated email from the ASF dual-hosted git repository.
kmccusker pushed a commit to branch develop
in repository
https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git
The following commit(s) were added to refs/heads/develop by this push:
new f308968 Inline operations with large return values
new 8b99137 Merge pull request #42 from sigp/inline
f308968 is described below
commit f30896868944d6b7cb93a78ae7c5172b328050c0
Author: Kirk Baird <[email protected]>
AuthorDate: Tue Jul 28 12:36:03 2020 +1000
Inline operations with large return values
Signed-off-by: Kirk Baird <[email protected]>
---
src/big.rs | 21 ++++++-
src/dbig.rs | 16 +++++-
src/ecp.rs | 175 +++++++++++++++++++++++++++++++++++++++++++++------------
src/ecp2.rs | 70 +++++++++++++++++++----
src/ecp4.rs | 48 +++++++++++++---
src/ecp8.rs | 54 +++++++++++++++---
src/ff.rs | 6 ++
src/fp.rs | 37 ++++++++++--
src/fp12.rs | 14 +++++
src/fp16.rs | 10 ++++
src/fp2.rs | 32 +++++++++++
src/fp24.rs | 12 ++++
src/fp4.rs | 56 +++++++++++++++---
src/fp48.rs | 12 ++++
src/fp8.rs | 59 +++++++++++++++----
src/pair.rs | 24 ++++++--
src/pair192.rs | 24 ++++++--
src/pair256.rs | 24 ++++++--
18 files changed, 587 insertions(+), 107 deletions(-)
diff --git a/src/big.rs b/src/big.rs
index 1ebbd13..52eb21e 100644
--- a/src/big.rs
+++ b/src/big.rs
@@ -80,11 +80,13 @@ impl PartialOrd for Big {
}
impl Big {
+ #[inline(always)]
pub fn new() -> Big {
Big { w: [0; NLEN] }
}
/// Convert a integer to a Big
+ #[inline(always)]
pub fn new_int(x: isize) -> Big {
let mut s = Big::new();
s.w[0] = x as Chunk;
@@ -92,6 +94,7 @@ impl Big {
}
/// Takes an array of integers and converts to a Big
+ #[inline(always)]
pub fn new_ints(a: &[Chunk]) -> Big {
let mut s = Big::new();
for i in 0..NLEN {
@@ -100,6 +103,7 @@ impl Big {
s
}
+ #[inline(always)]
pub fn new_dcopy(y: &DBig) -> Big {
let mut s = Big::new();
for i in 0..NLEN {
@@ -306,6 +310,7 @@ impl Big {
}
/// From Hex String
+ #[inline(always)]
pub fn fromstring(val: String) -> Big {
let mut res = Big::new();
let len = val.len();
@@ -343,6 +348,7 @@ impl Big {
}
/// Return self + x
+ #[inline(always)]
pub fn plus(&self, x: &Big) -> Big {
let mut s = Big::new();
for i in 0..NLEN {
@@ -358,6 +364,7 @@ impl Big {
}
/// Return self - x
+ #[inline(always)]
pub fn minus(&self, x: &Big) -> Big {
let mut d = Big::new();
for i in 0..NLEN {
@@ -409,6 +416,7 @@ impl Big {
/// From Byte Array
///
/// Convert from byte array starting at index `n` to Big
+ #[inline(always)]
pub fn frombytearray(b: &[u8], n: usize) -> Big {
let mut m = Big::new();
@@ -437,6 +445,8 @@ impl Big {
/// From bytes
///
/// Convert from bytes from index 0
+ /// Panics if input bytes length is less than required.
+ #[inline(always)]
pub fn frombytes(b: &[u8]) -> Big {
Big::frombytearray(b, 0)
}
@@ -453,7 +463,8 @@ impl Big {
carry
}
- /// self*=c and catch overflow in DBig
+ /// self *= c and catch overflow in DBig
+ #[inline(always)]
pub fn pxmul(&self, c: isize) -> DBig {
let mut m = DBig::new();
let mut carry = 0 as Chunk;
@@ -480,6 +491,7 @@ impl Big {
}
/// return a*b where result fits in a Big
+ #[inline(always)]
pub fn smul(a: &Big, b: &Big) -> Big {
let mut c = Big::new();
for i in 0..NLEN {
@@ -686,6 +698,7 @@ impl Big {
/// Random
///
/// Get 8*MODBYTES size random number
+ #[inline(always)]
pub fn random(rng: &mut RAND) -> Big {
let mut m = Big::new();
let mut j = 0;
@@ -711,6 +724,7 @@ impl Big {
/// Random Number
///
/// Create random Big in portable way, one bit at a time
+ #[inline(always)]
pub fn randomnum(q: &Big, rng: &mut RAND) -> Big {
let mut d = DBig::new();
let mut j = 0;
@@ -947,6 +961,7 @@ impl Big {
/// Montegomery Reduction
///
/// https://eprint.iacr.org/2015/1247.pdf
+ #[inline(always)]
pub fn monty(md: &Big, mc: Chunk, d: &mut DBig) -> Big {
let mut b = Big::new();
let rm = BMASK as DChunk;
@@ -1011,6 +1026,7 @@ impl Big {
/// Modular Multiplication
///
/// return a*b mod m
+ #[inline(always)]
pub fn modmul(a1: &Big, b1: &Big, m: &Big) -> Big {
let mut a = a1.clone();
let mut b = b1.clone();
@@ -1021,6 +1037,7 @@ impl Big {
}
/// return a^2 mod m
+ #[inline(always)]
pub fn modsqr(a1: &Big, m: &Big) -> Big {
let mut a = a1.clone();
a.rmod(m);
@@ -1031,6 +1048,7 @@ impl Big {
/// Modular Negation
///
/// return -a mod m
+ #[inline(always)]
pub fn modneg(a1: &Big, m: &Big) -> Big {
let mut a = a1.clone();
a.rmod(m);
@@ -1040,6 +1058,7 @@ impl Big {
/// Raise to Power with Modulus
///
/// return this^e mod m
+ #[inline(always)]
pub fn powmod(&mut self, e1: &Big, m: &Big) -> Big {
self.norm();
let mut e = e1.clone();
diff --git a/src/dbig.rs b/src/dbig.rs
index b4b48c1..9e003da 100644
--- a/src/dbig.rs
+++ b/src/dbig.rs
@@ -28,12 +28,20 @@ pub struct DBig {
}
impl DBig {
+
+ /// Creates new DBig as 0.
+ #[inline(always)]
pub fn new() -> DBig {
DBig {
w: [0; big::DNLEN as usize],
}
}
+ /// New Small Copy
+ ///
+ /// Creates a new DBig from a Big
+ /// Most significant bits are set to zero.
+ #[inline(always)]
pub fn new_scopy(x: &Big) -> DBig {
let mut b = DBig::new();
for i in 0..big::NLEN {
@@ -48,7 +56,10 @@ impl DBig {
b
}
- /// split DBig at position n, return higher half, keep lower half
+ /// Split DBig
+ ///
+ /// Splits the DBig at position n, return higher half, keep lower half
+ #[inline(always)]
pub fn split(&mut self, n: usize) -> Big {
let mut t = Big::new();
let m = n % big::BASEBITS;
@@ -159,6 +170,7 @@ impl DBig {
}
/// Reduces self DBig mod a Big, and returns the Big
+ #[inline(always)]
pub fn dmod(&mut self, c: &Big) -> Big {
let mut k = 0;
self.norm();
@@ -193,6 +205,7 @@ impl DBig {
}
/// return self / c
+ #[inline(always)]
pub fn div(&mut self, c: &Big) -> Big {
let mut k = 0;
let mut m = DBig::new_scopy(c);
@@ -277,6 +290,7 @@ impl DBig {
}
// convert from byte array to DBig
+ #[inline(always)]
pub fn frombytes(b: &[u8]) -> DBig {
let mut m = DBig::new();
diff --git a/src/ecp.rs b/src/ecp.rs
index b10f408..bed0f1b 100644
--- a/src/ecp.rs
+++ b/src/ecp.rs
@@ -57,6 +57,10 @@ impl fmt::Debug for ECP {
#[allow(non_snake_case)]
impl ECP {
+ /// Projective New
+ ///
+ /// Creates a new projective elliptic curve point at infinity (0, 1, 0).
+ #[inline(always)]
pub fn pnew() -> ECP {
ECP {
x: FP::new(),
@@ -65,6 +69,10 @@ impl ECP {
}
}
+ /// New
+ ///
+ /// Creates a new ECP at infinity
+ #[inline(always)]
pub fn new() -> ECP {
let mut E = ECP::pnew();
if CURVETYPE == CurveType::Edwards {
@@ -73,7 +81,11 @@ impl ECP {
return E;
}
- /* set (x,y) from two Bigs */
+ /// New Bigs
+ ///
+ /// Set (x,y) from two Bigs
+ /// Set to infinity if not on curve.
+ #[inline(always)]
pub fn new_bigs(ix: &Big, iy: &Big) -> ECP {
let mut E = ECP::new();
E.x.bcopy(ix);
@@ -95,7 +107,11 @@ impl ECP {
return E;
}
- /* set (x,y) from Big and a bit */
+ /// New BigInt
+ ///
+ /// Set (x, y) from x and sign of y.
+ /// Set to infinity if not on curve.
+ #[inline(always)]
pub fn new_bigint(ix: &Big, s: isize) -> ECP {
let mut E = ECP::new();
E.x.bcopy(ix);
@@ -116,8 +132,12 @@ impl ECP {
E
}
+ /// New Big
+ ///
+ /// Create point from x, calculates y from curve equation
+ /// Set to infinity if not on curve.
+ #[inline(always)]
#[allow(non_snake_case)]
- /* set from x - calculate y from curve equation */
pub fn new_big(ix: &Big) -> ECP {
let mut E = ECP::new();
E.x.bcopy(ix);
@@ -134,7 +154,11 @@ impl ECP {
return E;
}
- // construct this from (x,y), set to 0 if not on curve
+ /// New Fp's
+ ///
+ /// Constructs from (x,y).
+ /// Set to infinity if not on curve.
+ #[inline(always)]
pub fn new_fps(x: FP, y: FP) -> ECP {
let mut point = ECP {
x,
@@ -151,13 +175,18 @@ impl ECP {
point
}
- // Create new point from (x, y, z)
- // Assumes coordinates are valid
+ /// New Projective
+ ///
+ /// Create new point from (X, Y, Z).
+ /// Assumes coordinates are valid.
+ #[inline(always)]
pub fn new_projective(x: FP, y: FP, z: FP) -> ECP {
ECP { x, y, z }
}
- /* set this=O */
+ /// Infinity
+ ///
+ /// Set self to infinity.
pub fn inf(&mut self) {
self.x.zero();
if CURVETYPE != CurveType::Montgomery {
@@ -170,7 +199,9 @@ impl ECP {
}
}
- /* Calculate RHS of curve equation */
+ /// Right Hand Side
+ ///
+ /// Calculate RHS of curve equation.
fn rhs(x: &FP) -> FP {
let mut r = x.clone();
r.sqr();
@@ -215,7 +246,9 @@ impl ECP {
return r;
}
- /* test for O point-at-infinity */
+ /// Is Infinity
+ ///
+ /// self == infinity
pub fn is_infinity(&self) -> bool {
match CURVETYPE {
CurveType::Edwards => self.x.iszilch() && self.y.equals(&self.z),
@@ -224,7 +257,9 @@ impl ECP {
}
}
- /* Conditional swap of P and Q dependant on d */
+ /// Conditional Swap
+ ///
+ /// Conditional swap of self and Q dependant on d
pub fn cswap(&mut self, Q: &mut ECP, d: isize) {
self.x.cswap(&mut Q.x, d);
if CURVETYPE != CurveType::Montgomery {
@@ -233,7 +268,9 @@ impl ECP {
self.z.cswap(&mut Q.z, d);
}
- /* Conditional move of Q to P dependant on d */
+ /// Conditional Move
+ ///
+ /// Conditional move of Q to self dependant on d
pub fn cmove(&mut self, Q: &ECP, d: isize) {
self.x.cmove(&Q.x, d);
if CURVETYPE != CurveType::Montgomery {
@@ -242,14 +279,18 @@ impl ECP {
self.z.cmove(&Q.z, d);
}
- /* return 1 if b==c, no branching */
+ /// ConstantTime Equals
+ ///
+ /// Return 1 if b == c, no branching
fn teq(b: i32, c: i32) -> isize {
let mut x = b ^ c;
x -= 1; // if x=0, x now -1
return ((x >> 31) & 1) as isize;
}
- /* this=-this */
+ /// Negation
+ ///
+ /// self = -self
pub fn neg(&mut self) {
if CURVETYPE == CurveType::Weierstrass {
self.y.neg();
@@ -261,12 +302,17 @@ impl ECP {
}
return;
}
- /* multiply x coordinate */
+
+ /// Multiply X
+ ///
+ /// Multiplies the X coordinate
pub fn mulx(&mut self, c: &mut FP) {
self.x.mul(c);
}
- /* Constant time select from pre-computed table */
+ /// Selector
+ ///
+ /// Constant time select from pre-computed table.
fn selector(&mut self, W: &[ECP], b: i32) {
let m = b >> 31;
let mut babs = (b ^ m) - m;
@@ -287,7 +333,9 @@ impl ECP {
self.cmove(&MP, (m & 1) as isize);
}
- /* Test P == Q */
+ /// Equals
+ ///
+ /// self == Q
pub fn equals(&self, Q: &ECP) -> bool {
let mut a = self.getpx();
a.mul(&Q.z);
@@ -308,7 +356,9 @@ impl ECP {
return true;
}
- /* set to affine - from (x,y,z) to (x,y) */
+ /// Affine
+ ///
+ /// Set to affine, from (X, Y, Z) to (x, y).
pub fn affine(&mut self) {
if self.is_infinity() {
return;
@@ -328,41 +378,57 @@ impl ECP {
self.z = one;
}
- /* extract x as a Big */
+ /// Get X
+ ///
+ /// Extract affine x as a Big.
pub fn getx(&self) -> Big {
let mut W = self.clone();
W.affine();
return W.x.redc();
}
- /* extract y as a Big */
+ /// Get Y
+ ///
+ /// Extract affine y as a Big.
pub fn gety(&self) -> Big {
let mut W = self.clone();
W.affine();
return W.y.redc();
}
- /* get sign of Y */
+ /// Get Sign Y
+ ///
+ /// Returns the sign of Y.
pub fn gets(&self) -> isize {
let y = self.gety();
return y.parity();
}
- /* extract x as an FP */
+ /// Get Proejctive X
+ ///
+ /// Extract X as an FP.
pub fn getpx(&self) -> FP {
self.x.clone()
}
- /* extract y as an FP */
+
+ /// Get Projective Y
+ ///
+ /// Extract Y as an FP.
pub fn getpy(&self) -> FP {
self.y.clone()
}
- /* extract z as an FP */
+ /// Get Porjective Z
+ ///
+ /// Extract Z as an FP.
pub fn getpz(&self) -> FP {
self.z.clone()
}
- /* convert to byte array */
+ /// To Bytes
+ ///
+ /// Convert to byte array
+ /// Panics if byte array is insufficient length.
pub fn tobytes(&self, b: &mut [u8], compress: bool) {
let mb = big::MODBYTES as usize;
let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
@@ -395,7 +461,11 @@ impl ECP {
}
}
- /* convert from byte array to point */
+ /// From Bytes
+ ///
+ /// Convert from byte array to point
+ /// Panics if input bytes are less than required bytes.
+ #[inline(always)]
pub fn frombytes(b: &[u8]) -> ECP {
let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
let mb = big::MODBYTES as usize;
@@ -431,7 +501,9 @@ impl ECP {
return ECP::new();
}
- /* convert to hex string */
+ /// To String
+ ///
+ /// Convert to hex string
pub fn tostring(&self) -> String {
let mut W = self.clone();
W.affine();
@@ -445,6 +517,9 @@ impl ECP {
};
}
+ /// To Hex
+ ///
+ /// Converts the projectives to a hex string separated by a space.
pub fn to_hex(&self) -> String {
format!(
"{} {} {}",
@@ -454,6 +529,8 @@ impl ECP {
)
}
+ /// From Hex Iterator
+ #[inline(always)]
pub fn from_hex_iter(iter: &mut SplitWhitespace) -> ECP {
ECP {
x: FP::from_hex_iter(iter),
@@ -462,12 +539,16 @@ impl ECP {
}
}
+ /// From Hex
+ #[inline(always)]
pub fn from_hex(val: String) -> ECP {
let mut iter = val.split_whitespace();
return ECP::from_hex_iter(&mut iter);
}
- /* this*=2 */
+ /// Double
+ ///
+ /// self *= 2
pub fn dbl(&mut self) {
if CURVETYPE == CurveType::Weierstrass {
if rom::CURVE_A == 0 {
@@ -656,7 +737,9 @@ impl ECP {
}
}
- /* self+=Q */
+ /// Addition
+ ///
+ /// self += Q
pub fn add(&mut self, Q: &ECP) {
if CURVETYPE == CurveType::Weierstrass {
if rom::CURVE_A == 0 {
@@ -907,7 +990,10 @@ impl ECP {
return;
}
- /* Differential Add for Montgomery curves. this+=Q where W is this-Q and
is affine. */
+ /// Differential Add for Montgomery curves.
+ ///
+ /// self += Q
+ /// where W is (self - Q) and is affine
pub fn dadd(&mut self, Q: &ECP, W: &ECP) {
let mut a = self.x.clone();
let mut b = self.x.clone();
@@ -946,14 +1032,19 @@ impl ECP {
self.z.mul(&b);
}
- /// self-=Q
+ /// Subtraction
+ ///
+ /// self -= Q
pub fn sub(&mut self, Q: &ECP) {
let mut NQ = Q.clone();
NQ.neg();
self.add(&NQ);
}
- // Constant time multiply by small integer of length bts - use ladder
+ /// Pin Multiplication
+ ///
+ /// Constant time multiply by small integer of length bts - use ladder
+ #[inline(always)]
pub fn pinmul(&self, e: i32, bts: i32) -> ECP {
if CURVETYPE == CurveType::Montgomery {
return self.mul(&mut Big::new_int(e as isize));
@@ -976,7 +1067,10 @@ impl ECP {
}
}
- /// Return e.self
+ /// Multiplication
+ ///
+ /// Return e * self
+ #[inline(always)]
pub fn mul(&self, e: &Big) -> ECP {
if e.iszilch() || self.is_infinity() {
return ECP::new();
@@ -1065,8 +1159,10 @@ impl ECP {
T
}
- /* Return e.this+f.Q */
-
+ /// Multiply two points by scalars
+ ///
+ /// Return e * self + f * Q
+ #[inline(always)]
pub fn mul2(&self, e: &Big, Q: &ECP, f: &Big) -> ECP {
let mut W: [ECP; 8] = [
ECP::new(),
@@ -1191,8 +1287,13 @@ impl ECP {
*self = P.clone();
}
- // Map a given byte slice to a point on the curve. The byte slice should
be atleast the size of the modulus
+
+ /// Map It
+ ///
+ /// Maps bytes to a curve point using hash and test.
+ /// Not conformant to hash-to-curve standards.
#[allow(non_snake_case)]
+ #[inline(always)]
pub fn mapit(h: &[u8]) -> ECP {
let q = Big::new_ints(&rom::MODULUS);
let mut x = Big::frombytes(h);
@@ -1221,6 +1322,10 @@ impl ECP {
return P;
}
+ /// Generator
+ ///
+ /// Returns the generator of the group.
+ #[inline(always)]
pub fn generator() -> ECP {
let G: ECP;
diff --git a/src/ecp2.rs b/src/ecp2.rs
index e0e2073..af9eeff 100644
--- a/src/ecp2.rs
+++ b/src/ecp2.rs
@@ -27,6 +27,10 @@ use crate::types::{CurvePairingType, SexticTwist, SignOfX};
use std::fmt;
use std::str::SplitWhitespace;
+/// Elliptic Curve Point over Fp2
+///
+/// A projective elliptic curve point defined over Fp2.
+/// (X, Y, Z)
#[derive(Clone)]
pub struct ECP2 {
x: FP2,
@@ -56,6 +60,10 @@ impl fmt::Debug for ECP2 {
#[allow(non_snake_case)]
impl ECP2 {
+ /// New
+ ///
+ /// Creates a new elliptic curve point at infinity: (0, 1, 0).
+ #[inline(always)]
pub fn new() -> ECP2 {
ECP2 {
x: FP2::new(),
@@ -63,8 +71,13 @@ impl ECP2 {
z: FP2::new(),
}
}
+
+ /// New Fp2's
+ ///
+ /// Constructs from (x,y).
+ /// Set to infinity if not on curve.
#[allow(non_snake_case)]
- /* construct this from (x,y) - but set to O if not on curve */
+ #[inline(always)]
pub fn new_fp2s(x: FP2, y: FP2) -> ECP2 {
let mut E = ECP2 {
x,
@@ -82,7 +95,11 @@ impl ECP2 {
E
}
- /* construct this from x - but set to O if not on curve */
+ /// New Fp2
+ ///
+ /// Constructs point from x, by calculating y.
+ /// Set to infinity if not on curve.
+ #[inline(always)]
pub fn new_fp2(ix: &FP2) -> ECP2 {
let mut E = ECP2::new();
E.x = ix.clone();
@@ -98,7 +115,11 @@ impl ECP2 {
return E;
}
- // Construct from (X, Y, Z) with no gaurentee of correctness.
+ /// New Porjective
+ ///
+ /// Constructs point from (X, Y, Z) with no gaurentee of correctness.
+ /// Do not use this on untrusted input!
+ #[inline(always)]
pub fn new_projective(x: FP2, y: FP2, z: FP2) -> ECP2 {
ECP2 { x, y, z }
}
@@ -249,7 +270,11 @@ impl ECP2 {
}
}
- /* convert from byte array to point */
+ /// From Bytes
+ ///
+ /// Converts byte array to point.
+ /// Pancis if insufficient bytes are given.
+ #[inline(always)]
pub fn frombytes(b: &[u8]) -> ECP2 {
let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
let mb = big::MODBYTES as usize;
@@ -287,6 +312,9 @@ impl ECP2 {
return format!("({},{})", W.x.tostring(), W.y.tostring());
}
+ /// To Hex
+ ///
+ /// Converts each projective (X, Y, Z) to a hex string, separated by
spaces.
pub fn to_hex(&self) -> String {
format!(
"{} {} {}",
@@ -296,6 +324,8 @@ impl ECP2 {
)
}
+ /// From Hex Iterator
+ #[inline(always)]
pub fn from_hex_iter(iter: &mut SplitWhitespace) -> ECP2 {
ECP2 {
x: FP2::from_hex_iter(iter),
@@ -304,6 +334,8 @@ impl ECP2 {
}
}
+ /// From Hex
+ #[inline(always)]
pub fn from_hex(val: String) -> ECP2 {
let mut iter = val.split_whitespace();
return ECP2::from_hex_iter(&mut iter);
@@ -513,7 +545,10 @@ impl ECP2 {
self.y.mul(x);
}
- /* self*=e */
+ /// Multiplication
+ ///
+ /// Return e * self
+ #[inline(always)]
pub fn mul(&self, e: &Big) -> ECP2 {
if self.is_infinity() {
return ECP2::new();
@@ -582,11 +617,15 @@ impl ECP2 {
P
}
- /* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
- // Bos & Costello https://eprint.iacr.org/2013/458.pdf
- // Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf
- // Side channel attack secure
-
+ /// Multiply 4 Points
+ ///
+ /// P = u0 * Q0 + u1 * Q1 + u2 * Q2 + u3 * Q3
+ /// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+ /// Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf
+ /// Side channel attack secure
+ ///
+ /// Panics if 4 points and 4 scalars are not given.
+ #[inline(always)]
pub fn mul4(Q: &mut [ECP2], u: &[Big]) -> ECP2 {
let mut P = ECP2::new();
@@ -686,8 +725,13 @@ impl ECP2 {
return P;
}
-
+
+ /// Map It
+ ///
+ /// Maps bytes to a curve point using hash and test.
+ /// Not conformant to hash-to-curve standards.
#[allow(non_snake_case)]
+ #[inline(always)]
pub fn mapit(h: &[u8]) -> ECP2 {
let q = Big::new_ints(&rom::MODULUS);
let mut x = Big::frombytes(h);
@@ -759,6 +803,10 @@ impl ECP2 {
self.affine();
}
+ /// Generator
+ ///
+ /// Returns the generator of the group.
+ #[inline(always)]
pub fn generator() -> ECP2 {
return ECP2::new_fp2s(
FP2::new_bigs(
diff --git a/src/ecp4.rs b/src/ecp4.rs
index c988ee9..d593fea 100644
--- a/src/ecp4.rs
+++ b/src/ecp4.rs
@@ -34,6 +34,8 @@ pub struct ECP4 {
#[allow(non_snake_case)]
impl ECP4 {
+ /// New
+ #[inline(always)]
pub fn new() -> ECP4 {
ECP4 {
x: FP4::new(),
@@ -41,8 +43,13 @@ impl ECP4 {
z: FP4::new(),
}
}
+
+ /// New Fp4's
+ ///
+ /// Constructs from (x,y)
+ /// Set to infinity if not on curve
+ #[inline(always)]
#[allow(non_snake_case)]
- /* construct this from (x,y) - but set to O if not on curve */
pub fn new_fp4s(ix: &FP4, iy: &FP4) -> ECP4 {
let mut E = ECP4::new();
E.x = ix.clone();
@@ -59,7 +66,11 @@ impl ECP4 {
return E;
}
- /* construct this from x - but set to O if not on curve */
+ /// New Fp4
+ ///
+ /// Construct this from x, calulating y.
+ /// Set to infinity if not on curve.
+ #[inline(always)]
pub fn new_fp4(ix: &FP4) -> ECP4 {
let mut E = ECP4::new();
E.x = ix.clone();
@@ -244,7 +255,11 @@ impl ECP4 {
}
}
- /* convert from byte array to point */
+ /// From Bytes
+ ///
+ /// Convert from byte array to point
+ /// Panics if insufficient bytes are given.
+ #[inline(always)]
pub fn frombytes(b: &[u8]) -> ECP4 {
let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
let mb = big::MODBYTES as usize;
@@ -531,7 +546,10 @@ impl ECP4 {
}
}
- /* self*=e */
+ /// Multiplication
+ ///
+ /// Return self * e
+ #[inline(always)]
pub fn mul(&self, e: &Big) -> ECP4 {
/* fixed size windows */
if self.is_infinity() {
@@ -601,11 +619,14 @@ impl ECP4 {
P
}
- /* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3.. */
- // Bos & Costello https://eprint.iacr.org/2013/458.pdf
- // Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf
- // Side channel attack secure
-
+ /// Multiplication 8
+ ///
+ /// P = u0 * Q0 + u1 * Q1 + u2 * Q2 + u3 * Q3 ..
+ /// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+ /// Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf
+ /// Side channel attack secure
+ /// Panics if 8 points and 8 scalars are not given.
+ #[inline(always)]
pub fn mul8(Q: &mut [ECP4], u: &[Big]) -> ECP4 {
let mut P = ECP4::new();
@@ -762,6 +783,10 @@ impl ECP4 {
return P;
}
+ /// Generator
+ ///
+ /// Returns the generator of the group.
+ #[inline(always)]
pub fn generator() -> ECP4 {
return ECP4::new_fp4s(
&FP4::new_fp2s(
@@ -787,7 +812,12 @@ impl ECP4 {
);
}
+ /// Map It
+ ///
+ /// Maps bytes to a curve point using hash and test.
+ /// Not conformant to hash-to-curve standards.
#[allow(non_snake_case)]
+ #[inline(always)]
pub fn mapit(h: &[u8]) -> ECP4 {
let mut q = Big::new_ints(&rom::MODULUS);
let mut x = Big::frombytes(h);
diff --git a/src/ecp8.rs b/src/ecp8.rs
index 7625fc1..a597249 100644
--- a/src/ecp8.rs
+++ b/src/ecp8.rs
@@ -26,6 +26,10 @@ use super::fp8::FP8;
use super::rom;
use crate::types::{SexticTwist, SignOfX};
+/// Elliptic Curve Point over Fp8
+///
+/// An eliptic curve point defined over the extension field Fp8
+/// (X, Y , Z)
#[derive(Clone)]
pub struct ECP8 {
x: FP8,
@@ -35,6 +39,10 @@ pub struct ECP8 {
#[allow(non_snake_case)]
impl ECP8 {
+ /// New
+ ///
+ /// Creates a new projective point at infinity: (0, 1, 0)
+ #[inline(always)]
pub fn new() -> ECP8 {
ECP8 {
x: FP8::new(),
@@ -42,8 +50,13 @@ impl ECP8 {
z: FP8::new(),
}
}
+
+ /// New Fp8's
+ ///
+ /// Construct this from (x,y).
+ /// Set to infinity if not on curve.
#[allow(non_snake_case)]
- /* construct this from (x,y) - but set to O if not on curve */
+ #[inline(always)]
pub fn new_fp8s(ix: &FP8, iy: &FP8) -> ECP8 {
let mut E = ECP8::new();
E.x = ix.clone();
@@ -60,7 +73,11 @@ impl ECP8 {
return E;
}
- /* construct this from x - but set to O if not on curve */
+ /// New Fp8
+ ///
+ /// Constructs from x, calculating y.
+ /// Set to infinity if not on curve.
+ #[inline(always)]
pub fn new_fp8(ix: &FP8) -> ECP8 {
let mut E = ECP8::new();
E.x = ix.clone();
@@ -282,7 +299,11 @@ impl ECP8 {
}
}
- /* convert from byte array to point */
+ /// From Bytes
+ ///
+ /// Convert from byte array to point
+ /// Panics if insufficient bytes are given.
+ #[inline(always)]
pub fn frombytes(b: &[u8]) -> ECP8 {
let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
let mb = big::MODBYTES as usize;
@@ -637,7 +658,10 @@ impl ECP8 {
}
}
- /* self*=e */
+ /// Multiplication
+ ///
+ /// Returns self * e
+ #[inline(always)]
pub fn mul(&self, e: &Big) -> ECP8 {
/* fixed size windows */
let mut P = ECP8::new();
@@ -709,11 +733,14 @@ impl ECP8 {
return P;
}
- /* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3.. */
- // Bos & Costello https://eprint.iacr.org/2013/458.pdf
- // Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf
- // Side channel attack secure
-
+ /// Multiplication 16
+ ///
+ /// P = u0 * Q0 + u1 * Q1 + u2 * Q2 + u3 * Q3 ...
+ /// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+ /// Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf
+ /// Side channel attack secure
+ /// Panics if less than 8 points and 8 scalars are given.
+ #[inline(always)]
pub fn mul16(Q: &mut [ECP8], u: &[Big]) -> ECP8 {
let mut P = ECP8::new();
@@ -1010,6 +1037,10 @@ impl ECP8 {
return P;
}
+ /// Generator
+ ///
+ /// Returns the generator of the group.
+ #[inline(always)]
pub fn generator() -> ECP8 {
return ECP8::new_fp8s(
&FP8::new_fp4s(
@@ -1059,7 +1090,12 @@ impl ECP8 {
);
}
+ /// Map It
+ ///
+ /// Maps bytes to a curve point using hash and test.
+ /// Not conformant to hash-to-curve standards.
#[allow(non_snake_case)]
+ #[inline(always)]
pub fn mapit(h: &[u8]) -> ECP8 {
let mut q = Big::new_ints(&rom::MODULUS);
let mut x = Big::frombytes(h);
diff --git a/src/ff.rs b/src/ff.rs
index 47324c6..e460517 100644
--- a/src/ff.rs
+++ b/src/ff.rs
@@ -64,6 +64,7 @@ impl FF {
}
/* Constructors */
+ #[inline(always)]
pub fn new_int(n: usize) -> FF {
let mut f = FF {
v: Vec::new(),
@@ -454,6 +455,7 @@ impl FF {
}
/* z=x*y. Assumes x and y are of same length. */
+ #[inline(always)]
pub fn mul(x: &FF, y: &FF) -> FF {
let n = x.length;
let mut z = FF::new_int(2 * n);
@@ -500,6 +502,7 @@ impl FF {
}
/* z=x^2 */
+ #[inline(always)]
pub fn sqr(x: &FF) -> FF {
let n = x.length;
let mut z = FF::new_int(2 * n);
@@ -509,6 +512,7 @@ impl FF {
}
/* return This mod modulus, ms is modulus, md is Montgomery Constant */
+ #[inline(always)]
pub fn reduce(&mut self, ms: &FF, md: &FF) -> FF {
/* fast karatsuba Montgomery reduction */
let n = ms.length;
@@ -531,6 +535,7 @@ impl FF {
/* Set r=this mod b */
/* this is of length - 2*n */
/* r,b is of length - n */
+ #[inline(always)]
pub fn dmod(&mut self, b: &FF) -> FF {
let n = b.length;
let mut m = FF::new_int(2 * n);
@@ -668,6 +673,7 @@ impl FF {
}
/* U=1/a mod 2^m - Arazi & Qi */
+ #[inline(always)]
pub fn invmod2m(&self) -> FF {
let n = self.length;
diff --git a/src/fp.rs b/src/fp.rs
index a3e1776..4e345d3 100644
--- a/src/fp.rs
+++ b/src/fp.rs
@@ -62,7 +62,10 @@ pub const TBITS: usize = MODBITS % big::BASEBITS; // Number
of active bits in to
pub const TMASK: Chunk = (1 << TBITS) - 1;
impl FP {
- // Constructors
+ /// New
+ ///
+ /// Creates a new Fp at 0.
+ #[inline(always)]
pub fn new() -> FP {
FP {
x: Big::new(),
@@ -70,7 +73,10 @@ impl FP {
}
}
- /// Creates a FP from an int
+ /// New Int
+ ///
+ /// Creates a FP from an int.
+ #[inline(always)]
pub fn new_int(a: isize) -> FP {
let mut f = FP::new();
f.x.inc(a);
@@ -78,11 +84,18 @@ impl FP {
return f;
}
- /// Creates a FP from a slice of raw ints in Big from
+ /// New Ints
+ ///
+ /// Creates a Fp from a slice of raw ints in Big form.
+ #[inline(always)]
pub fn new_ints(w: &[Chunk]) -> FP {
Self::new_big(Big::new_ints(w))
}
+ /// New Big
+ ///
+ /// Creates a Fp from a Big.
+ #[inline(always)]
pub fn new_big(x: Big) -> FP {
let mut f = FP { x, xes: 1 };
f.nres();
@@ -100,6 +113,8 @@ impl FP {
}
}
+ /// From Hex Iterator
+ #[inline(always)]
pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP {
let xes = i32::from_str(iter.next().unwrap()).unwrap();
let x = iter.next().unwrap();
@@ -109,6 +124,10 @@ impl FP {
}
}
+ /// From Hex
+ ///
+ /// Converts to Fp from a hex string.
+ #[inline(always)]
pub fn from_hex(val: String) -> FP {
let mut s = val.split_whitespace();
FP::from_hex_iter(&mut s)
@@ -414,9 +433,11 @@ impl FP {
}
}
- /// Return this^(p-3)/4 or this^(p-5)/8
+ /// Modular Inverse for pseudo-Mersenne primes
///
+ /// Return self ^ (p - 3) / 4 or self ^ (p - 5) / 8
/// https://eprint.iacr.org/2018/1038
+ #[inline(always)]
pub fn fpow(&self) -> FP {
let ac: [isize; 11] = [1, 2, 3, 6, 12, 15, 30, 60, 120, 240, 255];
let mut xp: [FP; 11] = [
@@ -600,7 +621,10 @@ impl FP {
return false;
}
- /// return self^e mod Modulus
+ /// Power
+ ///
+ /// return self ^ e mod Modulus
+ #[inline(always)]
pub fn pow(&mut self, e: &mut Big) -> FP {
let mut tb: [FP; 16] = [
FP::new(),
@@ -654,7 +678,10 @@ impl FP {
return r;
}
+ /// Square Root
+ ///
/// return sqrt(this) mod Modulus
+ #[inline(always)]
pub fn sqrt(&mut self) -> FP {
self.reduce();
diff --git a/src/fp12.rs b/src/fp12.rs
index 8952ada..2a96020 100644
--- a/src/fp12.rs
+++ b/src/fp12.rs
@@ -50,6 +50,7 @@ impl PartialEq for FP12 {
impl Eq for FP12 {}
impl FP12 {
+ #[inline(always)]
pub fn new() -> FP12 {
FP12 {
a: FP4::new(),
@@ -67,6 +68,7 @@ impl FP12 {
self.stype
}
+ #[inline(always)]
pub fn new_int(a: isize) -> FP12 {
let stype = if a == 1 { ONE } else { SPARSER };
@@ -78,6 +80,7 @@ impl FP12 {
}
}
+ #[inline(always)]
pub fn new_fp4s(a: FP4, b: FP4, c: FP4) -> FP12 {
FP12 {
a,
@@ -87,6 +90,7 @@ impl FP12 {
}
}
+ #[inline(always)]
pub fn new_fp4(a: FP4) -> FP12 {
FP12 {
a,
@@ -165,14 +169,17 @@ impl FP12 {
self.a.equals(&x.a) && self.b.equals(&x.b) && self.c.equals(&x.c)
}
+ #[inline(always)]
pub fn geta(&self) -> FP4 {
self.a.clone()
}
+ #[inline(always)]
pub fn getb(&self) -> FP4 {
self.b.clone()
}
+ #[inline(always)]
pub fn getc(&mut self) -> FP4 {
self.c.clone()
}
@@ -764,6 +771,7 @@ impl FP12 {
}
/* trace function */
+ #[inline(always)]
pub fn trace(&mut self) -> FP4 {
let mut t = self.geta();
t.imul(3);
@@ -772,6 +780,7 @@ impl FP12 {
}
/* convert from byte array to FP12 */
+ #[inline(always)]
pub fn frombytes(w: &[u8]) -> FP12 {
let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
let mb = big::MODBYTES as usize;
@@ -922,6 +931,7 @@ impl FP12 {
)
}
+ #[inline(always)]
pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP12 {
FP12 {
a: FP4::from_hex_iter(iter),
@@ -931,12 +941,14 @@ impl FP12 {
}
}
+ #[inline(always)]
pub fn from_hex(val: String) -> FP12 {
let mut iter = val.split_whitespace();
return FP12::from_hex_iter(&mut iter);
}
/* self=self^e */
+ #[inline(always)]
pub fn pow(&self, e: &Big) -> FP12 {
let mut r = self.clone();
r.norm();
@@ -978,6 +990,7 @@ impl FP12 {
*self = r[0].clone();
}
+ #[inline(always)]
pub fn compow(&mut self, e: &Big, r: &Big) -> FP4 {
let f = FP2::new_bigs(Big::new_ints(&rom::FRA),
Big::new_ints(&rom::FRB));
let q = Big::new_ints(&rom::MODULUS);
@@ -1018,6 +1031,7 @@ impl FP12 {
// Bos & Costello https://eprint.iacr.org/2013/458.pdf
// Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf
// Side channel attack secure
+ #[inline(always)]
pub fn pow4(q: &[FP12], u: &[Big]) -> FP12 {
let mut g: [FP12; 8] = [
FP12::new(),
diff --git a/src/fp16.rs b/src/fp16.rs
index 124e7df..cd71567 100644
--- a/src/fp16.rs
+++ b/src/fp16.rs
@@ -28,6 +28,7 @@ pub struct FP16 {
}
impl FP16 {
+ #[inline(always)]
pub fn new() -> FP16 {
FP16 {
a: FP8::new(),
@@ -35,6 +36,7 @@ impl FP16 {
}
}
+ #[inline(always)]
pub fn new_int(a: isize) -> FP16 {
FP16 {
a: FP8::new_int(a),
@@ -42,10 +44,12 @@ impl FP16 {
}
}
+ #[inline(always)]
pub fn new_fp8s(a: FP8, b: FP8) -> FP16 {
FP16 { a, b }
}
+ #[inline(always)]
pub fn new_fp8(a: FP8) -> FP16 {
FP16 { a, b: FP8::new() }
}
@@ -99,15 +103,18 @@ impl FP16 {
}
/// Extract real part a
+ #[inline(always)]
pub fn real(&self) -> FP8 {
self.geta()
}
+ #[inline(always)]
pub fn geta(&self) -> FP8 {
self.a.clone()
}
/// Extract imaginary part b
+ #[inline(always)]
pub fn getb(&self) -> FP8 {
self.b.clone()
}
@@ -325,6 +332,7 @@ impl FP16 {
}
/* self=self^e */
+ #[inline(always)]
pub fn pow(&self, e: &Big) -> FP16 {
let mut w = self.clone();
w.norm();
@@ -377,6 +385,7 @@ impl FP16 {
}
/* r=x^n using XTR method on traces of FP24s */
+ #[inline(always)]
pub fn xtr_pow(&self, n: &Big) -> FP16 {
let mut sf = self.clone();
sf.norm();
@@ -420,6 +429,7 @@ impl FP16 {
}
/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s.
See Stam thesis. */
+ #[inline(always)]
pub fn xtr_pow2(&mut self, ck: &FP16, ckml: &FP16, ckm2l: &FP16, a: &Big,
b: &Big) -> FP16 {
let mut e = a.clone();
let mut d = b.clone();
diff --git a/src/fp2.rs b/src/fp2.rs
index 0b9927a..b449ef3 100644
--- a/src/fp2.rs
+++ b/src/fp2.rs
@@ -53,6 +53,10 @@ impl fmt::Debug for FP2 {
}
impl FP2 {
+ /// New
+ ///
+ /// Create a Fp2 set to 0.
+ #[inline(always)]
pub fn new() -> FP2 {
FP2 {
a: FP::new(),
@@ -60,6 +64,10 @@ impl FP2 {
}
}
+ /// New Int
+ ///
+ /// Create a Fp2 setting `a` as an int, `b` to 0.
+ #[inline(always)]
pub fn new_int(a: isize) -> FP2 {
FP2 {
a: FP::new_int(a),
@@ -67,6 +75,10 @@ impl FP2 {
}
}
+ /// New Ints
+ ///
+ /// Creates a Fp2 setting `a` and `b` as ints.
+ #[inline(always)]
pub fn new_ints(a: isize, b: isize) -> FP2 {
FP2 {
a: FP::new_int(a),
@@ -74,10 +86,18 @@ impl FP2 {
}
}
+ /// New Fp's
+ ///
+ /// Create a new Fp2 from two Fp's.
+ #[inline(always)]
pub fn new_fps(a: FP, b: FP) -> FP2 {
FP2 { a, b }
}
+ /// New Bigs
+ ///
+ /// Create a new Fp2 from two Bigs.
+ #[inline(always)]
pub fn new_bigs(c: Big, d: Big) -> FP2 {
FP2 {
a: FP::new_big(c),
@@ -85,10 +105,18 @@ impl FP2 {
}
}
+ /// New Fp
+ ///
+ /// Creates a Fp2 setting `a` from a Fp.
+ #[inline(always)]
pub fn new_fp(a: FP) -> FP2 {
FP2 { a, b: FP::new() }
}
+ /// New Big
+ ///
+ /// Creates a new Fp2 setting `a` from a Big.
+ #[inline(always)]
pub fn new_big(c: Big) -> FP2 {
FP2 {
a: FP::new_big(c),
@@ -319,6 +347,8 @@ impl FP2 {
format!("{} {}", self.a.to_hex(), self.b.to_hex())
}
+ /// From Hex Iterator
+ #[inline(always)]
pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP2 {
FP2 {
a: FP::from_hex_iter(iter),
@@ -326,6 +356,8 @@ impl FP2 {
}
}
+ /// From Hex
+ #[inline(always)]
pub fn from_hex(val: String) -> FP2 {
let mut iter = val.split_whitespace();
return FP2::from_hex_iter(&mut iter);
diff --git a/src/fp24.rs b/src/fp24.rs
index db0b7da..dcca5af 100644
--- a/src/fp24.rs
+++ b/src/fp24.rs
@@ -41,6 +41,7 @@ pub struct FP24 {
}
impl FP24 {
+ #[inline(always)]
pub fn new() -> FP24 {
FP24 {
a: FP8::new(),
@@ -58,6 +59,7 @@ impl FP24 {
return self.stype;
}
+ #[inline(always)]
pub fn new_int(a: isize) -> FP24 {
let stype = if a == 1 { ONE } else { SPARSER };
@@ -69,6 +71,7 @@ impl FP24 {
}
}
+ #[inline(always)]
pub fn new_fp8s(a: FP8, b: FP8, c: FP8) -> FP24 {
FP24 {
a,
@@ -78,6 +81,7 @@ impl FP24 {
}
}
+ #[inline(always)]
pub fn new_fp8(a: FP8) -> FP24 {
FP24 {
a,
@@ -155,14 +159,17 @@ impl FP24 {
return self.a.equals(&x.a) && self.b.equals(&x.b) &&
self.c.equals(&x.c);
}
+ #[inline(always)]
pub fn geta(&self) -> FP8 {
self.a.clone()
}
+ #[inline(always)]
pub fn getb(&self) -> FP8 {
self.b.clone()
}
+ #[inline(always)]
pub fn getc(&self) -> FP8 {
self.c.clone()
}
@@ -761,6 +768,7 @@ impl FP24 {
}
/* trace function */
+ #[inline(always)]
pub fn trace(&mut self) -> FP8 {
let mut t = self.geta();
t.imul(3);
@@ -769,6 +777,7 @@ impl FP24 {
}
/* convert from byte array to FP24 */
+ #[inline(always)]
pub fn frombytes(w: &[u8]) -> FP24 {
let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
let mb = big::MODBYTES as usize;
@@ -1035,6 +1044,7 @@ impl FP24 {
}
/* self=self^e */
+ #[inline(always)]
pub fn pow(&self, e: &Big) -> FP24 {
let mut r = self.clone();
r.norm();
@@ -1076,6 +1086,7 @@ impl FP24 {
*self = r[0].clone();
}
+ #[inline(always)]
pub fn compow(&mut self, e: &Big, r: &Big) -> FP8 {
let f = FP2::new_bigs(Big::new_ints(&rom::FRA),
Big::new_ints(&rom::FRB));
let q = Big::new_ints(&rom::MODULUS);
@@ -1116,6 +1127,7 @@ impl FP24 {
// Bos & Costello https://eprint.iacr.org/2013/458.pdf
// Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf
// Side channel attack secure
+ #[inline(always)]
pub fn pow8(q: &[FP24], u: &[Big]) -> FP24 {
let mut g1: [FP24; 8] = [
FP24::new(),
diff --git a/src/fp4.rs b/src/fp4.rs
index 6bd18b3..652452c 100644
--- a/src/fp4.rs
+++ b/src/fp4.rs
@@ -38,6 +38,10 @@ impl PartialEq for FP4 {
impl Eq for FP4 {}
impl FP4 {
+ /// New Fp4
+ ///
+ /// Create a new Fp4 set to 0.
+ #[inline(always)]
pub fn new() -> FP4 {
FP4 {
a: FP2::new(),
@@ -45,6 +49,8 @@ impl FP4 {
}
}
+ /// New Int
+ #[inline(always)]
pub fn new_int(a: isize) -> FP4 {
FP4 {
a: FP2::new_int(a),
@@ -52,10 +58,18 @@ impl FP4 {
}
}
+ /// New Fp2's
+ ///
+ /// Create a Fp4 from two Fp2's
+ #[inline(always)]
pub fn new_fp2s(a: FP2, b: FP2) -> FP4 {
FP4 { a, b }
}
+ /// New Fp2
+ ///
+ /// Create a Fp4 setting `a` from an Fp and `b` to 0.
+ #[inline(always)]
pub fn new_fp2(a: FP2) -> FP4 {
FP4 { a, b: FP2::new() }
}
@@ -108,21 +122,33 @@ impl FP4 {
self.b.iszilch()
}
- /* extract real part a */
+ /// Real
+ ///
+ /// Extract real part (`a`).
+ #[inline(always)]
pub fn real(&self) -> FP2 {
self.geta()
}
+ /// Get A
+ ///
+ /// Returns `a`
+ #[inline(always)]
pub fn geta(&self) -> FP2 {
self.a.clone()
}
- /* extract imaginary part b */
+ /// Get B
+ ///
+ /// Extract imaginary part (`b`).
+ #[inline(always)]
pub fn getb(&self) -> FP2 {
self.b.clone()
}
- /* test self=x */
+ /// Equals
+ ///
+ /// self == x
pub fn equals(&self, x: &FP4) -> bool {
return self.a.equals(&x.a) && self.b.equals(&x.b);
}
@@ -290,6 +316,8 @@ impl FP4 {
format!("{} {}", self.a.to_hex(), self.b.to_hex())
}
+ /// From Hex Iterator
+ #[inline(always)]
pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP4 {
FP4 {
a: FP2::from_hex_iter(iter),
@@ -297,12 +325,16 @@ impl FP4 {
}
}
+ /// From Hex
+ #[inline(always)]
pub fn from_hex(val: String) -> FP4 {
let mut iter = val.split_whitespace();
return FP4::from_hex_iter(&mut iter);
}
- /* self=1/self */
+ /// Inverse
+ ///
+ /// self = 1 / self
pub fn inverse(&mut self) {
//self.norm();
@@ -339,7 +371,10 @@ impl FP4 {
self.b.mul(f);
}
- /* self=self^e */
+ /// Power
+ ///
+ /// Return self ^ e
+ #[inline(always)]
pub fn pow(&self, e: &Big) -> FP4 {
let mut w = self.clone();
w.norm();
@@ -391,7 +426,10 @@ impl FP4 {
self.reduce();
}
- /* r=x^n using XTR method on traces of FP12s */
+ /// XTR Power
+ ///
+ /// r = x^n using XTR method on traces of FP12s
+ #[inline(always)]
pub fn xtr_pow(&self, n: &Big) -> FP4 {
let mut sf = self.clone();
sf.norm();
@@ -434,7 +472,11 @@ impl FP4 {
r
}
- /* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s.
See Stam thesis. */
+ /// XTR Power 2
+ ///
+ /// Return ck ^ a * cl ^ n
+ /// Using XTR double exponentiation method on traces of FP12s. See Stam
thesis.
+ #[inline(always)]
pub fn xtr_pow2(&mut self, ck: &FP4, ckml: &FP4, ckm2l: &FP4, a: &Big, b:
&Big) -> FP4 {
let mut e = a.clone();
let mut d = b.clone();
diff --git a/src/fp48.rs b/src/fp48.rs
index 134f63a..74ce7d9 100644
--- a/src/fp48.rs
+++ b/src/fp48.rs
@@ -42,6 +42,7 @@ pub struct FP48 {
}
impl FP48 {
+ #[inline(always)]
pub fn new() -> FP48 {
FP48 {
a: FP16::new(),
@@ -59,6 +60,7 @@ impl FP48 {
return self.stype;
}
+ #[inline(always)]
pub fn new_int(a: isize) -> FP48 {
let mut f = FP48::new();
f.a = FP16::new_int(a);
@@ -72,6 +74,7 @@ impl FP48 {
return f;
}
+ #[inline(always)]
pub fn new_fp16s(a: FP16, b: FP16, c: FP16) -> FP48 {
FP48 {
a,
@@ -81,6 +84,7 @@ impl FP48 {
}
}
+ #[inline(always)]
pub fn new_fp16(a: FP16) -> FP48 {
FP48 {
a,
@@ -158,14 +162,17 @@ impl FP48 {
return self.a.equals(&x.a) && self.b.equals(&x.b) &&
self.c.equals(&x.c);
}
+ #[inline(always)]
pub fn geta(&self) -> FP16 {
self.a.clone()
}
+ #[inline(always)]
pub fn getb(&self) -> FP16 {
self.b.clone()
}
+ #[inline(always)]
pub fn getc(&self) -> FP16 {
self.c.clone()
}
@@ -767,6 +774,7 @@ impl FP48 {
}
/// Trace function
+ #[inline(always)]
pub fn trace(&mut self) -> FP16 {
let mut t = self.geta();
t.imul(3);
@@ -775,6 +783,7 @@ impl FP48 {
}
/// Convert from byte array to FP48
+ #[inline(always)]
pub fn frombytes(w: &[u8]) -> FP48 {
let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
let mb = big::MODBYTES as usize;
@@ -1287,6 +1296,7 @@ impl FP48 {
}
/* self=self^e */
+ #[inline(always)]
pub fn pow(&self, e: &Big) -> FP48 {
let mut r = self.clone();
r.norm();
@@ -1328,6 +1338,7 @@ impl FP48 {
*self = r[0].clone();
}
+ #[inline(always)]
pub fn compow(&mut self, e: &Big, r: &Big) -> FP16 {
let f = FP2::new_bigs(Big::new_ints(&rom::FRA),
Big::new_ints(&rom::FRB));
let q = Big::new_ints(&rom::MODULUS);
@@ -1368,6 +1379,7 @@ impl FP48 {
// Bos & Costello https://eprint.iacr.org/2013/458.pdf
// Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf
// Side channel attack secure
+ #[inline(always)]
pub fn pow16(q: &[FP48], u: &[Big]) -> FP48 {
let mut g1: [FP48; 8] = [
FP48::new(),
diff --git a/src/fp8.rs b/src/fp8.rs
index ada4a01..2349898 100644
--- a/src/fp8.rs
+++ b/src/fp8.rs
@@ -29,6 +29,8 @@ pub struct FP8 {
}
impl FP8 {
+ /// New
+ #[inline(always)]
pub fn new() -> FP8 {
FP8 {
a: FP4::new(),
@@ -36,6 +38,8 @@ impl FP8 {
}
}
+ /// New Int
+ #[inline(always)]
pub fn new_int(a: isize) -> FP8 {
FP8 {
a: FP4::new_int(a),
@@ -43,10 +47,14 @@ impl FP8 {
}
}
+ /// New Fp4's
+ #[inline(always)]
pub fn new_fp4s(a: FP4, b: FP4) -> FP8 {
FP8 { a, b }
}
+ /// New Fp4
+ #[inline(always)]
pub fn new_fp4(a: FP4) -> FP8 {
FP8 { a, b: FP4::new() }
}
@@ -98,38 +106,53 @@ impl FP8 {
pub fn isreal(&self) -> bool {
return self.b.iszilch();
}
- /* extract real part a */
+
+ /// Real
+ ///
+ /// Extract real part (`a`)
+ #[inline(always)]
pub fn real(&self) -> FP4 {
self.geta()
}
+ /// Get A
pub fn geta(&self) -> FP4 {
self.a.clone()
}
- /* extract imaginary part b */
+ /// Get B
+ ///
+ /// Extract imaginary part `(b)`
pub fn getb(&self) -> FP4 {
self.b.clone()
}
- /* test self=x */
+ /// Equals
+ ///
+ /// self == x
pub fn equals(&self, x: &FP8) -> bool {
return self.a.equals(&x.a) && self.b.equals(&x.b);
}
- /* set self=0 */
+ /// Zero
+ ///
+ /// Set self = 0
pub fn zero(&mut self) {
self.a.zero();
self.b.zero();
}
- /* set self=1 */
+ /// One
+ ///
+ // Set self = 1
pub fn one(&mut self) {
self.a.one();
self.b.zero();
}
- /* negate self mod Modulus */
+ /// Negation
+ ///
+ /// Negate self mod Modulus.
pub fn neg(&mut self) {
self.norm();
let mut m = self.geta();
@@ -319,7 +342,9 @@ impl FP8 {
self.b.times_i();
}
- /* self=self^p using Frobenius */
+ /// Frobenius
+ ///
+ /// self = self ^ p using Frobenius.
pub fn frob(&mut self, f: &FP2) {
let mut ff = f.clone();
ff.sqr();
@@ -331,7 +356,10 @@ impl FP8 {
self.b.times_i();
}
- /* self=self^e */
+ /// Power
+ ///
+ /// self ^ e
+ #[inline(always)]
pub fn pow(&self, e: &Big) -> FP8 {
let mut w = self.clone();
w.norm();
@@ -353,7 +381,9 @@ impl FP8 {
return r;
}
- /* XTR xtr_a function */
+ /// XTR A
+ ///
+ /// XTR xtr_a function.
pub fn xtr_a(&mut self, w: &FP8, y: &FP8, z: &FP8) {
let mut r = w.clone();
let mut t = w.clone();
@@ -384,7 +414,10 @@ impl FP8 {
self.reduce();
}
- /* r=x^n using XTR method on traces of FP24s */
+ /// XTR Power
+ ///
+ /// r = x^n using XTR method on traces of FP24s
+ #[inline(always)]
pub fn xtr_pow(&self, n: &Big) -> FP8 {
let mut sf = self.clone();
sf.norm();
@@ -427,7 +460,11 @@ impl FP8 {
r
}
- /* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s.
See Stam thesis. */
+ /// XTR Power 2
+ ///
+ /// r = ck ^ a * cl ^ n
+ /// using XTR double exponentiation method on traces of FP12s. See Stam
thesis.
+ #[inline(always)]
pub fn xtr_pow2(&mut self, ck: &FP8, ckml: &FP8, ckm2l: &FP8, a: &Big, b:
&Big) -> FP8 {
let mut e = a.clone();
let mut d = b.clone();
diff --git a/src/pair.rs b/src/pair.rs
index 59610c5..d63abc7 100644
--- a/src/pair.rs
+++ b/src/pair.rs
@@ -31,6 +31,7 @@ use super::rom;
use crate::types::{CurvePairingType, SexticTwist, SignOfX};
#[allow(non_snake_case)]
+#[inline(always)]
fn linedbl(A: &mut ECP2, qx: &FP, qy: &FP) -> FP12 {
let mut xx = A.getpx(); //X
let mut yy = A.getpy(); //Y
@@ -83,6 +84,7 @@ fn linedbl(A: &mut ECP2, qx: &FP, qy: &FP) -> FP12 {
}
#[allow(non_snake_case)]
+#[inline(always)]
fn lineadd(A: &mut ECP2, B: &ECP2, qx: &FP, qy: &FP) -> FP12 {
let mut x1 = A.getpx(); // X1
let mut y1 = A.getpy(); // Y1
@@ -150,6 +152,7 @@ fn lbits(n3: &mut Big, n: &mut Big) -> usize {
}
/* prepare for multi-pairing */
+#[inline(always)]
pub fn initmp() -> Vec<FP12> {
let mut r: Vec<FP12> = Vec::with_capacity(rom::ATE_BITS);
for _ in 0..rom::ATE_BITS {
@@ -159,6 +162,7 @@ pub fn initmp() -> Vec<FP12> {
}
/* basic Miller loop */
+#[inline(always)]
pub fn miller(r: &[FP12]) -> FP12 {
let mut res = FP12::new_int(1);
for i in (1..rom::ATE_BITS).rev() {
@@ -233,8 +237,9 @@ pub fn another(r: &mut [FP12], P1: &ECP2, Q1: &ECP) {
}
}
-#[allow(non_snake_case)]
/* Optimal R-ate pairing */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn ate(P1: &ECP2, Q1: &ECP) -> FP12 {
let mut f = FP2::new_bigs(Big::new_ints(&rom::FRA),
Big::new_ints(&rom::FRB));
let mut n = Big::new();
@@ -302,8 +307,9 @@ pub fn ate(P1: &ECP2, Q1: &ECP) -> FP12 {
return r;
}
-#[allow(non_snake_case)]
/* Optimal R-ate double pairing e(P,Q).e(R,S) */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn ate2(P1: &ECP2, Q1: &ECP, R1: &ECP2, S1: &ECP) -> FP12 {
let mut f = FP2::new_bigs(Big::new_ints(&rom::FRA),
Big::new_ints(&rom::FRB));
let mut n = Big::new();
@@ -399,6 +405,7 @@ pub fn ate2(P1: &ECP2, Q1: &ECP, R1: &ECP2, S1: &ECP) ->
FP12 {
}
// final exponentiation - keep separate for multi-pairings and to avoid
thrashing stack
+#[inline(always)]
pub fn fexp(m: &FP12) -> FP12 {
let f = FP2::new_bigs(Big::new_ints(&rom::FRA), Big::new_ints(&rom::FRB));
let mut x = Big::new_ints(&rom::CURVE_BNX);
@@ -533,8 +540,9 @@ pub fn fexp(m: &FP12) -> FP12 {
return r;
}
-#[allow(non_snake_case)]
/* GLV method */
+#[allow(non_snake_case)]
+#[inline(always)]
fn glv(e: &Big) -> [Big; 2] {
let mut u: [Big; 2] = [Big::new(), Big::new()];
if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
@@ -569,8 +577,9 @@ fn glv(e: &Big) -> [Big; 2] {
return u;
}
-#[allow(non_snake_case)]
/* Galbraith & Scott Method */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn gs(e: &Big) -> [Big; 4] {
let mut u: [Big; 4] = [Big::new(), Big::new(), Big::new(), Big::new()];
if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
@@ -610,8 +619,9 @@ pub fn gs(e: &Big) -> [Big; 4] {
return u;
}
-#[allow(non_snake_case)]
/* Multiply P by e in group G1 */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn g1mul(P: &ECP, e: &Big) -> ECP {
if rom::USE_GLV {
let mut R = P.clone();
@@ -645,8 +655,9 @@ pub fn g1mul(P: &ECP, e: &Big) -> ECP {
}
}
-#[allow(non_snake_case)]
/* Multiply P by e in group G2 */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn g2mul(P: &ECP2, e: &Big) -> ECP2 {
if rom::USE_GS_G2 {
let mut Q: [ECP2; 4] = [ECP2::new(), ECP2::new(), ECP2::new(),
ECP2::new()];
@@ -683,6 +694,7 @@ pub fn g2mul(P: &ECP2, e: &Big) -> ECP2 {
/* f=f^e */
/* Note that this method requires a lot of RAM! Better to use compressed XTR
method, see FP4.java */
+#[inline(always)]
pub fn gtpow(d: &FP12, e: &Big) -> FP12 {
if rom::USE_GS_GT {
let mut g: [FP12; 4] = [FP12::new(), FP12::new(), FP12::new(),
FP12::new()];
diff --git a/src/pair192.rs b/src/pair192.rs
index 37b9297..733b322 100644
--- a/src/pair192.rs
+++ b/src/pair192.rs
@@ -30,6 +30,7 @@ use super::rom;
use crate::types::{SexticTwist, SignOfX};
#[allow(non_snake_case)]
+#[inline(always)]
fn linedbl(A: &mut ECP4, qx: &FP, qy: &FP) -> FP24 {
let mut xx = A.getpx(); //X
let mut yy = A.getpy(); //Y
@@ -81,6 +82,7 @@ fn linedbl(A: &mut ECP4, qx: &FP, qy: &FP) -> FP24 {
}
#[allow(non_snake_case)]
+#[inline(always)]
fn lineadd(A: &mut ECP4, B: &ECP4, qx: &FP, qy: &FP) -> FP24 {
let mut x1 = A.getpx(); // X1
let mut y1 = A.getpy(); // Y1
@@ -138,6 +140,7 @@ fn lbits(n3: &mut Big, n: &mut Big) -> usize {
}
/* prepare for multi-pairing */
+#[inline(always)]
pub fn initmp() -> Vec<FP24> {
let mut r: Vec<FP24> = Vec::with_capacity(rom::ATE_BITS);
for _ in 0..rom::ATE_BITS {
@@ -147,6 +150,7 @@ pub fn initmp() -> Vec<FP24> {
}
/* basic Miller loop */
+#[inline(always)]
pub fn miller(r: &[FP24]) -> FP24 {
let mut res = FP24::new_int(1);
for i in (1..rom::ATE_BITS).rev() {
@@ -198,8 +202,9 @@ pub fn another(r: &mut [FP24], P1: &ECP4, Q1: &ECP) {
}
}
-#[allow(non_snake_case)]
/* Optimal R-ate pairing */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn ate(P1: &ECP4, Q1: &ECP) -> FP24 {
let mut n = Big::new();
let mut n3 = Big::new();
@@ -243,8 +248,9 @@ pub fn ate(P1: &ECP4, Q1: &ECP) -> FP24 {
return r;
}
-#[allow(non_snake_case)]
/* Optimal R-ate double pairing e(P,Q).e(R,S) */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn ate2(P1: &ECP4, Q1: &ECP, R1: &ECP4, S1: &ECP) -> FP24 {
let mut n = Big::new();
let mut n3 = Big::new();
@@ -304,6 +310,7 @@ pub fn ate2(P1: &ECP4, Q1: &ECP, R1: &ECP4, S1: &ECP) ->
FP24 {
}
/* final exponentiation - keep separate for multi-pairings and to avoid
thrashing stack */
+#[inline(always)]
pub fn fexp(m: &FP24) -> FP24 {
let f = FP2::new_bigs(Big::new_ints(&rom::FRA), Big::new_ints(&rom::FRB));
let mut x = Big::new_ints(&rom::CURVE_BNX);
@@ -401,8 +408,9 @@ pub fn fexp(m: &FP24) -> FP24 {
return r;
}
-#[allow(non_snake_case)]
/* GLV method */
+#[allow(non_snake_case)]
+#[inline(always)]
fn glv(e: &Big) -> [Big; 2] {
let mut u: [Big; 2] = [Big::new(), Big::new()];
let q = Big::new_ints(&rom::CURVE_ORDER);
@@ -418,8 +426,9 @@ fn glv(e: &Big) -> [Big; 2] {
return u;
}
-#[allow(non_snake_case)]
/* Galbraith & Scott Method */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn gs(e: &Big) -> [Big; 8] {
let mut u: [Big; 8] = [
Big::new(),
@@ -449,8 +458,9 @@ pub fn gs(e: &Big) -> [Big; 8] {
u
}
-#[allow(non_snake_case)]
/* Multiply P by e in group G1 */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn g1mul(P: &ECP, e: &mut Big) -> ECP {
if rom::USE_GLV {
let mut R = P.clone();
@@ -484,8 +494,9 @@ pub fn g1mul(P: &ECP, e: &mut Big) -> ECP {
}
}
-#[allow(non_snake_case)]
/* Multiply P by e in group G2 */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn g2mul(P: &ECP4, e: &Big) -> ECP4 {
if rom::USE_GS_G2 {
let mut Q: [ECP4; 8] = [
@@ -527,6 +538,7 @@ pub fn g2mul(P: &ECP4, e: &Big) -> ECP4 {
/* f=f^e */
/* Note that this method requires a lot of RAM! Better to use compressed XTR
method, see FP4.java */
+#[inline(always)]
pub fn gtpow(d: &FP24, e: &Big) -> FP24 {
if rom::USE_GS_GT {
let mut g: [FP24; 8] = [
diff --git a/src/pair256.rs b/src/pair256.rs
index e442be7..fd68011 100644
--- a/src/pair256.rs
+++ b/src/pair256.rs
@@ -30,6 +30,7 @@ use super::rom;
use crate::types::{SexticTwist, SignOfX};
#[allow(non_snake_case)]
+#[inline(always)]
fn linedbl(A: &mut ECP8, qx: &FP, qy: &FP) -> FP48 {
let mut xx = A.getpx(); //X
let mut yy = A.getpy(); //Y
@@ -81,6 +82,7 @@ fn linedbl(A: &mut ECP8, qx: &FP, qy: &FP) -> FP48 {
}
#[allow(non_snake_case)]
+#[inline(always)]
fn lineadd(A: &mut ECP8, B: &ECP8, qx: &FP, qy: &FP) -> FP48 {
let mut x1 = A.getpx(); // X1
let mut y1 = A.getpy(); // Y1
@@ -138,6 +140,7 @@ fn lbits(n3: &mut Big, n: &mut Big) -> usize {
}
/* prepare for multi-pairing */
+#[inline(always)]
pub fn initmp() -> Vec<FP48> {
let mut r: Vec<FP48> = Vec::with_capacity(rom::ATE_BITS);
for _ in 0..rom::ATE_BITS {
@@ -147,6 +150,7 @@ pub fn initmp() -> Vec<FP48> {
}
/* basic Miller loop */
+#[inline(always)]
pub fn miller(r: &[FP48]) -> FP48 {
let mut res = FP48::new_int(1);
for i in (1..rom::ATE_BITS).rev() {
@@ -198,8 +202,9 @@ pub fn another(r: &mut [FP48], P1: &ECP8, Q1: &ECP) {
}
}
-#[allow(non_snake_case)]
/* Optimal R-ate pairing */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn ate(P1: &ECP8, Q1: &ECP) -> FP48 {
let mut n = Big::new();
let mut n3 = Big::new();
@@ -241,8 +246,9 @@ pub fn ate(P1: &ECP8, Q1: &ECP) -> FP48 {
return r;
}
-#[allow(non_snake_case)]
/* Optimal R-ate double pairing e(P,Q).e(R,S) */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn ate2(P1: &ECP8, Q1: &ECP, R1: &ECP8, S1: &ECP) -> FP48 {
let mut n = Big::new();
let mut n3 = Big::new();
@@ -302,6 +308,7 @@ pub fn ate2(P1: &ECP8, Q1: &ECP, R1: &ECP8, S1: &ECP) ->
FP48 {
}
/* final exponentiation - keep separate for multi-pairings and to avoid
thrashing stack */
+#[inline(always)]
pub fn fexp(m: &FP48) -> FP48 {
let f = FP2::new_bigs(Big::new_ints(&rom::FRA), Big::new_ints(&rom::FRB));
let mut x = Big::new_ints(&rom::CURVE_BNX);
@@ -470,8 +477,9 @@ pub fn fexp(m: &FP48) -> FP48 {
return r;
}
-#[allow(non_snake_case)]
/* GLV method */
+#[allow(non_snake_case)]
+#[inline(always)]
fn glv(e: &Big) -> [Big; 2] {
let mut u: [Big; 2] = [Big::new(), Big::new()];
let q = Big::new_ints(&rom::CURVE_ORDER);
@@ -488,8 +496,9 @@ fn glv(e: &Big) -> [Big; 2] {
return u;
}
-#[allow(non_snake_case)]
/* Galbraith & Scott Method */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn gs(e: &Big) -> [Big; 16] {
let mut u: [Big; 16] = [
Big::new(),
@@ -531,8 +540,9 @@ pub fn gs(e: &Big) -> [Big; 16] {
u
}
-#[allow(non_snake_case)]
/* Multiply P by e in group G1 */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn g1mul(P: &ECP, e: &mut Big) -> ECP {
if rom::USE_GLV {
let mut R = P.clone();
@@ -566,8 +576,9 @@ pub fn g1mul(P: &ECP, e: &mut Big) -> ECP {
}
}
-#[allow(non_snake_case)]
/* Multiply P by e in group G2 */
+#[allow(non_snake_case)]
+#[inline(always)]
pub fn g2mul(P: &ECP8, e: &Big) -> ECP8 {
if rom::USE_GS_G2 {
let mut Q: [ECP8; 16] = [
@@ -617,6 +628,7 @@ pub fn g2mul(P: &ECP8, e: &Big) -> ECP8 {
/* f=f^e */
/* Note that this method requires a lot of RAM! Better to use compressed XTR
method, see FP4.java */
+#[inline(always)]
pub fn gtpow(d: &FP48, e: &Big) -> FP48 {
if rom::USE_GS_GT {
let mut g: [FP48; 16] = [