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

Fixed warnings and added hash2curve for G1 #4

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
Revert "Change to use reduction via modulus"
This reverts commit 9ca2b2a.

Signed-off-by: Michael Lodder <[email protected]>
mikelodder7 committed Apr 20, 2020
commit dfd94ae2fe329246dd6a013efb88495ca94d2293
6 changes: 3 additions & 3 deletions src/constants.rs
Original file line number Diff line number Diff line change
@@ -29,19 +29,19 @@ lazy_static! {
pub static ref CURVE_ORDER_BIT_SIZE: usize = CURVE_ORDER.nbits();
pub static ref BARRETT_REDC_K: usize = MODULUS.nbits();
pub static ref BARRETT_REDC_U: BigNum = {
let k = MODULUS.nbits();
let k = CURVE_ORDER.nbits();
let mut u = DoubleBigNum::new();
u.w[0] = 1;
// `u.shl(2*k)` crashes, so perform shl(k) twice
u.shl(k);
u.shl(k);

// div returns floored value
u.div(&MODULUS)
u.div(&CURVE_ORDER)
};

pub static ref BARRETT_REDC_V: BigNum = {
let k = MODULUS.nbits();
let k = CURVE_ORDER.nbits();
let mut v = BigNum::new_int(1isize);
v.shl(k+1);
v
68 changes: 34 additions & 34 deletions src/field_elem.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use rand::{CryptoRng, RngCore};

use crate::constants::{
BARRETT_REDC_K, BARRETT_REDC_U, BARRETT_REDC_V, BIG_NUM_BITS, MODULUS, FIELD_ELEMENT_SIZE, NLEN,
MODULUS_MINUS_1_DIV_2
BARRETT_REDC_K, BARRETT_REDC_U, BARRETT_REDC_V, BIG_NUM_BITS, CURVE_ORDER, FIELD_ELEMENT_SIZE, NLEN,
CURVE_ORDER_MINUS_1_DIV_2
};
use crate::errors::{SerzDeserzError, ValueError};
use crate::signum::Sgn0;
@@ -133,7 +133,7 @@ impl FieldElement {
));
}
let mut n = BigNum::frombytes(bytes);
n.rmod(&MODULUS);
n.rmod(&CURVE_ORDER);
Ok(Self { value: n })
}

@@ -159,7 +159,7 @@ impl FieldElement {

pub fn to_bignum(&self) -> BigNum {
let mut v = self.value.clone();
v.rmod(&MODULUS);
v.rmod(&CURVE_ORDER);
v
}

@@ -178,51 +178,51 @@ impl FieldElement {
pub fn add_assign_(&mut self, b: &Self) {
// Not using `self.plus` to avoid cloning. Breaking the abstraction a bit for performance.
self.value.add(&b.value);
self.value.rmod(&MODULUS);
self.value.rmod(&CURVE_ORDER);
}

/// Subtract a field element from itself. `self = self - b`
pub fn sub_assign_(&mut self, b: &Self) {
// Not using `self.minus` to avoid cloning. Breaking the abstraction a bit for performance.
let neg_b = BigNum::modneg(&b.value, &MODULUS);
let neg_b = BigNum::modneg(&b.value, &CURVE_ORDER);
self.value.add(&neg_b);
self.value.rmod(&MODULUS);
self.value.rmod(&CURVE_ORDER);
}

/// Return sum of a field element and itself. `self + b`
pub fn plus(&self, b: &Self) -> Self {
let mut sum = self.value.clone();
sum.add(&b.value);
sum.rmod(&MODULUS);
sum.rmod(&CURVE_ORDER);
sum.into()
}

/// Return difference of a field element and itself. `self - b`
pub fn minus(&self, b: &Self) -> Self {
let mut sum = self.value.clone();
let neg_b = BigNum::modneg(&b.value, &MODULUS);
let neg_b = BigNum::modneg(&b.value, &CURVE_ORDER);
sum.add(&neg_b);
sum.rmod(&MODULUS);
sum.rmod(&CURVE_ORDER);
sum.into()
}

/// Multiply 2 field elements modulus the order of the curve.
/// (field_element_a * field_element_b) % modulus
/// (field_element_a * field_element_b) % curve_order
pub fn multiply(&self, b: &Self) -> Self {
let d = BigNum::mul(&self.value, &b.value);
Self::reduce_dmod_curve_order(&d).into()
}

/// Calculate square of a field element modulo the curve order, i.e `a^2 % MODULUS`
/// Calculate square of a field element modulo the curve order, i.e `a^2 % curve_order`
pub fn square(&self) -> Self {
let d = BigNum::sqr(&self.value);
Self::reduce_dmod_curve_order(&d).into()
}

/// Exponentiation modulo curve order, i.e. self^exp % MODULUS
/// Exponentiation modulo curve order, i.e. self^exp % CURVE_ORDER
pub fn pow(&self, exp: &Self) -> Self {
let mut base = self.value.clone();
let res = base.powmod(&exp.value, &MODULUS);
let res = base.powmod(&exp.value, &CURVE_ORDER);
res.into()
}

@@ -237,14 +237,14 @@ impl FieldElement {
self.value = zero.minus(&self).value;
}

/// Calculate inverse of a field element modulo the curve order, i.e `a^-1 % MODULUS`
/// Calculate inverse of a field element modulo the curve order, i.e `a^-1 % curve_order`
pub fn inverse(&self) -> Self {
// Violating constant time guarantee until bug fixed in amcl
if self.is_zero() {
return Self::zero();
}
let mut inv = self.value.clone();
inv.invmodp(&MODULUS);
inv.invmodp(&CURVE_ORDER);
inv.into()
}

@@ -253,7 +253,7 @@ impl FieldElement {
if self.is_zero() {
self.value = BigNum::new();
} else {
self.value.invmodp(&MODULUS);
self.value.invmodp(&CURVE_ORDER);
}
}

@@ -333,9 +333,9 @@ impl FieldElement {
}

fn get_big_num_from_rand(r: &mut RAND) -> BigNum {
let mut n = BigNum::randomnum(&BigNum::new_big(&MODULUS), r);
let mut n = BigNum::randomnum(&BigNum::new_big(&CURVE_ORDER), r);
while n.iszilch() {
n = BigNum::randomnum(&BigNum::new_big(&MODULUS), r);
n = BigNum::randomnum(&BigNum::new_big(&CURVE_ORDER), r);
}
n
}
@@ -466,14 +466,14 @@ impl FieldElement {
/// Create big number from hex string in big endian
pub fn from_hex(s: String) -> Result<Self, SerzDeserzError> {
let mut f = Self::parse_hex_as_bignum(s)?;
f.rmod(&MODULUS);
f.rmod(&CURVE_ORDER);
Ok(f.into())
}

/// Useful for reducing product of BigNums. Uses Barrett reduction
pub fn reduce_dmod_curve_order(x: &DoubleBigNum) -> BigNum {
let (k, u, v) = (*BARRETT_REDC_K, *BARRETT_REDC_U, *BARRETT_REDC_V);
barrett_reduction(&x, &MODULUS, k, &u, &v)
barrett_reduction(&x, &CURVE_ORDER, k, &u, &v)
}

/// Parse given hex string as BigNum in constant time.
@@ -522,7 +522,7 @@ impl FieldElement {
/// "sign" of x, where sgn0(x) == -1 just when x is "negative". In
/// other words, this function always considers 0 to be positive.
pub fn sgn0(&self) -> Sgn0 {
if self.value > *MODULUS_MINUS_1_DIV_2 {
if self.value > *CURVE_ORDER_MINUS_1_DIV_2 {
Sgn0::Negative
} else {
Sgn0::NonNegative
@@ -618,7 +618,7 @@ impl From<BigNum> for FieldElement {
impl From<&[u8; FIELD_ELEMENT_SIZE]> for FieldElement {
fn from(x: &[u8; FIELD_ELEMENT_SIZE]) -> Self {
let mut n = BigNum::frombytes(x);
n.rmod(&MODULUS);
n.rmod(&CURVE_ORDER);
Self { value: n }
}
}
@@ -915,7 +915,7 @@ impl FieldElementVector {
}

/// Computes inner product of 2 vectors of field elements
/// [a1, a2, a3, ...field elements].[b1, b2, b3, ...field elements] = (a1*b1 + a2*b2 + a3*b3) % MODULUS
/// [a1, a2, a3, ...field elements].[b1, b2, b3, ...field elements] = (a1*b1 + a2*b2 + a3*b3) % curve_order
pub fn inner_product(&self, b: &FieldElementVector) -> Result<FieldElement, ValueError> {
check_vector_size_for_equality!(self, b)?;
let r = (0..b.len()).into_par_iter().map(|i| (&self[i] * &b[i])).reduce(|| FieldElement::new(), |a, b| a + b);
@@ -1524,11 +1524,11 @@ mod test {
let mut start = Instant::now();
for i in 0..count {
let mut a = l[i].clone();
a.rmod(&MODULUS);
a.rmod(&CURVE_ORDER);
let mut b = r[i].clone();
b.rmod(&MODULUS);
b.rmod(&CURVE_ORDER);
let d = BigNum::mul(&a, &b);
o1.push(barrett_reduction(&d, &MODULUS, k, &u, &v));
o1.push(barrett_reduction(&d, &CURVE_ORDER, k, &u, &v));
}
println!("Mul1 for {} elems = {:?}", count, start.elapsed());

@@ -1537,7 +1537,7 @@ mod test {
let a = l[i].clone();
let b = r[i].clone();
let d = BigNum::mul(&a, &b);
o2.push(barrett_reduction(&d, &MODULUS, k, &u, &v));
o2.push(barrett_reduction(&d, &CURVE_ORDER, k, &u, &v));
}
println!("Mul2 for {} elems = {:?}", count, start.elapsed());

@@ -1548,11 +1548,11 @@ mod test {
let mut x = BigNum::new_int(1isize);
start = Instant::now();
for i in 0..count {
x.rmod(&MODULUS);
x.rmod(&CURVE_ORDER);
let mut b = o1[i].clone();
b.rmod(&MODULUS);
b.rmod(&CURVE_ORDER);
let d = BigNum::mul(&x, &b);
x = barrett_reduction(&d, &MODULUS, k, &u, &v);
x = barrett_reduction(&d, &CURVE_ORDER, k, &u, &v);
}
println!("Mul1 all for {} elems = {:?}", count, start.elapsed());

@@ -1561,7 +1561,7 @@ mod test {
for i in 0..count {
let b = o2[i].clone();
let d = BigNum::mul(&y, &b);
y = barrett_reduction(&d, &MODULUS, k, &u, &v);
y = barrett_reduction(&d, &CURVE_ORDER, k, &u, &v);
}
println!("Mul2 all for {} elems = {:?}", count, start.elapsed());

@@ -1593,13 +1593,13 @@ mod test {

let start = Instant::now();
for i in 0..count {
BigNum::modmul(&nums[i], &nums[i], &MODULUS);
BigNum::modmul(&nums[i], &nums[i], &CURVE_ORDER);
}
println!("Mul time for {} big nums = {:?}", count, start.elapsed());

let start = Instant::now();
for i in 0..count {
BigNum::modsqr(&nums[i], &MODULUS);
BigNum::modsqr(&nums[i], &CURVE_ORDER);
}
println!("Sqr time for {} big nums = {:?}", count, start.elapsed());
}
4 changes: 2 additions & 2 deletions src/group_elem_g1.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::constants::{MODULUS, GROUP_G1_SIZE};
use crate::constants::{CURVE_ORDER, GROUP_G1_SIZE};
use crate::errors::{SerzDeserzError, ValueError};
use crate::field_elem::{FieldElement, FieldElementVector};
use crate::group_elem::{GroupElement, GroupElementVector};
@@ -155,7 +155,7 @@ impl GroupElement for G1 {
}

fn has_correct_order(&self) -> bool {
return self.value.mul(&MODULUS).is_infinity();
return self.value.mul(&CURVE_ORDER).is_infinity();
}
}

4 changes: 2 additions & 2 deletions src/group_elem_g2.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::constants::{MODULUS, GROUP_G2_SIZE};
use crate::constants::{CURVE_ORDER, GROUP_G2_SIZE};
use crate::errors::{SerzDeserzError, ValueError};
use crate::field_elem::{FieldElement, FieldElementVector};
use crate::group_elem::{GroupElement, GroupElementVector};
@@ -153,7 +153,7 @@ impl GroupElement for G2 {
}

fn has_correct_order(&self) -> bool {
return self.value.mul(&MODULUS).is_infinity();
return self.value.mul(&CURVE_ORDER).is_infinity();
}
}

26 changes: 13 additions & 13 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ extern crate sha3;

use rand::{CryptoRng, RngCore};

use crate::constants::{MODULUS, FIELD_ELEMENT_SIZE};
use crate::constants::{CURVE_ORDER, FIELD_ELEMENT_SIZE};
use crate::types::{BigNum, DoubleBigNum};
use amcl::rand::RAND;

@@ -140,14 +140,14 @@ fn __barrett_reduction__(x: &BigNum, modulus: &BigNum, k: usize, u: &BigNum, v:
pub fn barrett_reduction_params(modulus: &BigNum) -> (usize, BigNum, BigNum) {
let k = modulus.nbits();

// u = floor(2^2k/MODULUS)
// u = floor(2^2k/CURVE_ORDER)
let mut u = DoubleBigNum::new();
u.w[0] = 1;
// `u.shl(2*k)` crashes, so perform shl(k) twice
u.shl(k);
u.shl(k);
// div returns floored value
let u = u.div(&MODULUS);
let u = u.div(&CURVE_ORDER);

// v = 2^(k+1)
let mut v = BigNum::new_int(1isize);
@@ -179,7 +179,7 @@ mod test {
let mut res_mul = BIG::new_int(1 as isize);
let mut start = Instant::now();
for b in &bigs {
res_mul = BigNum::modmul(&res_mul, &b, &MODULUS);
res_mul = BigNum::modmul(&res_mul, &b, &CURVE_ORDER);
}
println!(
"Multiplication time for {} BIGs = {:?}",
@@ -215,12 +215,12 @@ mod test {
start = Instant::now();
for b in &bigs {
let mut i = b.clone();
i.invmodp(&MODULUS);
i.invmodp(&CURVE_ORDER);
inverses_b.push(i);
}
println!("Inverse time for {} BIGs = {:?}", count, start.elapsed());
for i in 0..count {
let r = BigNum::modmul(&inverses_b[i], &bigs[i], &MODULUS);
let r = BigNum::modmul(&inverses_b[i], &bigs[i], &CURVE_ORDER);
assert_eq!(BigNum::comp(&r, &BigNum::new_int(1 as isize)), 0);
}

@@ -243,7 +243,7 @@ mod test {
let mut r = bigs[0];
for i in 0..c {
r.add(&bigs[i]);
r.rmod(&MODULUS);
r.rmod(&CURVE_ORDER);
}
println!("Addition time for {} BIGs = {:?}", c, start.elapsed());

@@ -296,7 +296,7 @@ mod test {

#[test]
fn timing_barrett_reduction() {
//let (k, u, v) = barrett_reduction_params(&MODULUS);
//let (k, u, v) = barrett_reduction_params(&CURVE_ORDER);
let (k, u, v) = (
*constants::BARRETT_REDC_K,
*constants::BARRETT_REDC_U,
@@ -310,21 +310,21 @@ mod test {
for _ in 0..count {
let a: u32 = rng.gen();
let s = BigNum::new_int(a as isize);
let _x = MODULUS.minus(&s);
let _x = CURVE_ORDER.minus(&s);
xs.push(BigNum::mul(&_x, &_x));
}

let mut start = Instant::now();
for x in &xs {
let r = barrett_reduction(&x, &MODULUS, k, &u, &v);
let r = barrett_reduction(&x, &CURVE_ORDER, k, &u, &v);
reduced1.push(r);
}
println!("Barrett time = {:?}", start.elapsed());

start = Instant::now();
for x in &xs {
let mut y = x.clone();
let z = y.dmod(&MODULUS);
let z = y.dmod(&CURVE_ORDER);
reduced2.push(z);
}
println!("Normal time = {:?}", start.elapsed());
@@ -349,15 +349,15 @@ mod test {
let mut start = Instant::now();
for i in 0..count {
sum = BigNum::plus(&sum, &bigs[i]);
sum.rmod(&MODULUS)
sum.rmod(&CURVE_ORDER)
}
println!("rmod time = {:?}", start.elapsed());

let mut sum_b = bigs[0].clone();
start = Instant::now();
for i in 0..count {
sum_b = BigNum::plus(&sum_b, &bigs[i]);
sum_b = __barrett_reduction__(&sum_b, &MODULUS, k, &u, &v)
sum_b = __barrett_reduction__(&sum_b, &CURVE_ORDER, k, &u, &v)
}
println!("Barrett time = {:?}", start.elapsed());