From e9f64f518d0ae64cb4f9a8c7c544e3ff0ef82584 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Tue, 12 Mar 2019 14:44:46 +0300 Subject: [PATCH 01/11] add some initializers --- src/arith.rs | 6 ++++++ src/lib.rs | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/arith.rs b/src/arith.rs index 2d816b7..28873f7 100644 --- a/src/arith.rs +++ b/src/arith.rs @@ -20,6 +20,12 @@ impl From<[u64; 4]> for U256 { } } +impl From for U256 { + fn from(d: u64) -> Self { + U256::from([d, 0, 0, 0]) + } +} + /// 512-bit, stack allocated biginteger for use in extension /// field serialization and scalar interpretation. #[derive(Copy, Clone, Debug, PartialEq, Eq)] diff --git a/src/lib.rs b/src/lib.rs index 8ce0d4f..d48a544 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -146,6 +146,9 @@ impl Fq { a.to_big_endian(slice) .map_err(|_| FieldError::InvalidSliceLength) } + pub fn from_u256(u256: arith::U256) -> Result { + Ok(Fq(fields::Fq::new(u256).ok_or(FieldError::NotMember)?)) + } } impl Add for Fq { @@ -199,6 +202,9 @@ impl Fq2 { pub fn is_zero(&self) -> bool { self.0.is_zero() } + pub fn pow(&self, exp: Fq) -> Self { + Fq2(self.0.pow(exp.0)) + } } pub trait Group From 8eac5b8a104e771d2d963f63deceecb3e73db6c1 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Tue, 12 Mar 2019 15:50:15 +0300 Subject: [PATCH 02/11] remove duplicated inline --- src/arith.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/arith.rs b/src/arith.rs index 28873f7..1bd9079 100644 --- a/src/arith.rs +++ b/src/arith.rs @@ -429,7 +429,6 @@ fn div2(a: &mut [u128; 2]) { /// Multiply by two #[inline] -#[inline] fn mul2(a: &mut [u128; 2]) { let tmp = a[0] >> 127; a[0] <<= 1; From 4470c2ecfc8b8d16a96483baf0d973edbf2e0870 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 13 Mar 2019 12:27:07 +0300 Subject: [PATCH 03/11] more api --- src/groups/mod.rs | 16 ++++++++-------- src/lib.rs | 9 +++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/groups/mod.rs b/src/groups/mod.rs index fc247a8..9d911c4 100644 --- a/src/groups/mod.rs +++ b/src/groups/mod.rs @@ -689,13 +689,13 @@ fn test_miller_loop() { assert_eq!(gt, Fq12::new(Fq6::new( - Fq2::new(Fq::from_str("14551901853310307118181117653102171756020286507151693083446930124375536995872").unwrap(), Fq::from_str("9312135802322424742640599513015426415694425842442244572104764725304978020017").unwrap()), - Fq2::new(Fq::from_str("2008578374540014049115224515107136454624926345291695498760935593377832328658").unwrap(), Fq::from_str("19401931167387470703307774451905975977586101231060812348184567722817888018105").unwrap()), + Fq2::new(Fq::from_str("14551901853310307118181117653102171756020286507151693083446930124375536995872").unwrap(), Fq::from_str("9312135802322424742640599513015426415694425842442244572104764725304978020017").unwrap()), + Fq2::new(Fq::from_str("2008578374540014049115224515107136454624926345291695498760935593377832328658").unwrap(), Fq::from_str("19401931167387470703307774451905975977586101231060812348184567722817888018105").unwrap()), Fq2::new(Fq::from_str("15835061253582829097893482726334173316772697321004871665993836763948321578465").unwrap(), Fq::from_str("2434436628082562384254182545550914004674636606111293955202388712261962820365").unwrap()) ), Fq6::new( - Fq2::new(Fq::from_str("2874440054453559166574356420729655370224872280550180463983603224123901706537").unwrap(), Fq::from_str("21199736323249863378180814900160978651989782296293186487853700340281870105680").unwrap()), - Fq2::new(Fq::from_str("19165582755854282767090326095669835261356341739532443976394958023142879015770").unwrap(), Fq::from_str("1381947898997178910398427566832118260186305708991760706544743699683050330259").unwrap()), + Fq2::new(Fq::from_str("2874440054453559166574356420729655370224872280550180463983603224123901706537").unwrap(), Fq::from_str("21199736323249863378180814900160978651989782296293186487853700340281870105680").unwrap()), + Fq2::new(Fq::from_str("19165582755854282767090326095669835261356341739532443976394958023142879015770").unwrap(), Fq::from_str("1381947898997178910398427566832118260186305708991760706544743699683050330259").unwrap()), Fq2::new(Fq::from_str("282285618133171001983721596014922591835675934808772882476123488581876545578").unwrap(), Fq::from_str("9533292755262567365755835323107174518472361243562718718917822947506880920117").unwrap()) ) ) @@ -1017,15 +1017,15 @@ fn predefined_pair() { let g2 = AffineG2::new( Fq2::new( Fq::from_str("10857046999023057135944570762232829481370756359578518086990519993285655852781") - .expect("a-coeff of g2 x generator is of the right order"), + .expect("a-coeff of g2 x generator is of the right order"), Fq::from_str("11559732032986387107991004021392285783925812861821192530917403151452391805634") - .expect("b-coeff of g2 x generator is of the right order"), + .expect("b-coeff of g2 x generator is of the right order"), ), Fq2::new( Fq::from_str("8495653923123431417604973247489272438418190587263600148770280649306958101930") - .expect("a-coeff of g2 y generator is of the right order"), + .expect("a-coeff of g2 y generator is of the right order"), Fq::from_str("4082367875863433681332203403145435568316851327593401208105741076214120093531") - .expect("b-coeff of g2 y generator is of the right order"), + .expect("b-coeff of g2 y generator is of the right order"), ), ).expect("Point(11559732032986387107991004021392285783925812861821192530917403151452391805634 * i + 10857046999023057135944570762232829481370756359578518086990519993285655852781, 4082367875863433681332203403145435568316851327593401208105741076214120093531 * i + 8495653923123431417604973247489272438418190587263600148770280649306958101930) is a valid generator for G2") .to_jacobian(); diff --git a/src/lib.rs b/src/lib.rs index d48a544..43d8b81 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -190,6 +190,10 @@ impl Fq2 { Fq2(fields::Fq2::one()) } + pub fn i() -> Fq2 { + Fq2::new(Fq::zero(), Fq::one()) + } + pub fn zero() -> Fq2 { Fq2(fields::Fq2::zero()) } @@ -202,9 +206,14 @@ impl Fq2 { pub fn is_zero(&self) -> bool { self.0.is_zero() } + pub fn pow(&self, exp: Fq) -> Self { Fq2(self.0.pow(exp.0)) } + + pub fn neg(&self) -> Self { + Fq2(self.0.neg()) + } } pub trait Group From 568746fcf26c431d6650fa222c053816983288e9 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 13 Mar 2019 12:33:07 +0300 Subject: [PATCH 04/11] impl operations for fq2 --- src/lib.rs | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 43d8b81..3134263 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -210,9 +210,38 @@ impl Fq2 { pub fn pow(&self, exp: Fq) -> Self { Fq2(self.0.pow(exp.0)) } +} - pub fn neg(&self) -> Self { - Fq2(self.0.neg()) + +impl Add for Fq2 { + type Output = Self; + + fn add(self, other: Self) -> Self { + Fq2(self.0 + other.0) + } +} + +impl Sub for Fq2 { + type Output = Self; + + fn sub(self, other: Self) -> Self { + Fq2(self.0 - other.0) + } +} + +impl Neg for Fq2 { + type Output = Self; + + fn neg(self) -> Self { + Fq2(-self.0) + } +} + +impl Mul for Fq2 { + type Output = Self; + + fn mul(self, other: Self) -> Self { + Fq2(self.0 * other.0) } } From e8390af8a69e2db8fa4ab039c69e79bf7e39c132 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 13 Mar 2019 12:35:21 +0300 Subject: [PATCH 05/11] add derives --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 3134263..c9cbe29 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -183,6 +183,8 @@ impl Mul for Fq { } } +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[repr(C)] pub struct Fq2(fields::Fq2); impl Fq2 { From 187a608dbb06f5fa360611ef37e35eac39117e01 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 13 Mar 2019 12:40:25 +0300 Subject: [PATCH 06/11] change pow func --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c9cbe29..886c10a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -209,8 +209,8 @@ impl Fq2 { self.0.is_zero() } - pub fn pow(&self, exp: Fq) -> Self { - Fq2(self.0.pow(exp.0)) + pub fn pow(&self, exp: arith::U256) -> Self { + Fq2(self.0.pow(exp)) } } From 7395ad6d1db7119a4a27e51f88f02686b41d462d Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 13 Mar 2019 12:43:05 +0300 Subject: [PATCH 07/11] add into u256 --- src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 886c10a..e55ab2e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -149,6 +149,9 @@ impl Fq { pub fn from_u256(u256: arith::U256) -> Result { Ok(Fq(fields::Fq::new(u256).ok_or(FieldError::NotMember)?)) } + pub fn into_u256(self) -> arith::U256 { + (self.0).into() + } } impl Add for Fq { From 76c1296cfe62875524affb295bc067e42a202b0d Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 13 Mar 2019 12:46:56 +0300 Subject: [PATCH 08/11] real/imagianry part exposure --- src/fields/fq2.rs | 8 ++++++++ src/lib.rs | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/fields/fq2.rs b/src/fields/fq2.rs index 8f64016..df96d40 100644 --- a/src/fields/fq2.rs +++ b/src/fields/fq2.rs @@ -92,6 +92,14 @@ impl Fq2 { } } } + + pub fn real(&self) -> &Fq { + &self.c0 + } + + pub fn imaginary(&self) -> &Fq { + &self.c1 + } } impl FieldElement for Fq2 { diff --git a/src/lib.rs b/src/lib.rs index e55ab2e..be492e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -215,6 +215,14 @@ impl Fq2 { pub fn pow(&self, exp: arith::U256) -> Self { Fq2(self.0.pow(exp)) } + + pub fn real(&self) -> Fq { + Fq(*self.0.real()) + } + + pub fn imaginary(&self) -> Fq { + Fq(*self.0.imaginary()) + } } From 68d901f0d128e961153a731dcd0d06134b4b80e6 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 13 Mar 2019 16:13:00 +0300 Subject: [PATCH 09/11] some more api exposure --- src/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index be492e5..14c4b02 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,7 @@ mod fields; mod groups; use fields::FieldElement; -use groups::GroupElement; +use groups::{GroupElement, G1Params, G2Params, GroupParams}; use std::ops::{Add, Mul, Neg, Sub}; use rand::Rng; @@ -310,6 +310,10 @@ impl G1 { pub fn set_z(&mut self, z: Fq) { *self.0.z_mut() = z.0 } + + pub fn b() -> Fq { + Fq(G1Params::coeff_b()) + } } impl Group for G1 { @@ -437,6 +441,10 @@ impl G2 { pub fn set_z(&mut self, z: Fq2) { *self.0.z_mut() = z.0 } + + pub fn b() -> Fq2 { + Fq2(G2Params::coeff_b()) + } } impl Group for G2 { From 39aef57c2f879fdb87ec67be0be761add7c33d4b Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 13 Mar 2019 16:34:48 +0300 Subject: [PATCH 10/11] modulus --- src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 14c4b02..e64e391 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -152,6 +152,9 @@ impl Fq { pub fn into_u256(self) -> arith::U256 { (self.0).into() } + pub fn modulus() -> arith::U256 { + fields::Fq::modulus() + } } impl Add for Fq { From 563ec0db3cb184ec31cf37663fe0ba4fa0d0f837 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 13 Mar 2019 17:22:25 +0300 Subject: [PATCH 11/11] from_slice for u512 --- src/arith.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/arith.rs b/src/arith.rs index 1bd9079..7c09437 100644 --- a/src/arith.rs +++ b/src/arith.rs @@ -80,6 +80,22 @@ impl U512 { U512(res) } + pub fn from_slice(s: &[u8]) -> Result { + if s.len() != 64 { + return Err(Error::InvalidLength { + expected: 32, + actual: s.len(), + }); + } + + let mut n = [0; 4]; + for (l, i) in (0..4).rev().zip((0..4).map(|i| i * 16)) { + n[l] = BigEndian::read_u128(&s[i..]); + } + + Ok(U512(n)) + } + /// Get a random U512 pub fn random(rng: &mut R) -> U512 { U512(rng.gen())