This commit is contained in:
Vurich
2018-03-26 15:14:16 +02:00
parent 964b48fad5
commit 7638ee60a5
11 changed files with 954 additions and 427 deletions
+53 -13
View File
@@ -1,11 +1,11 @@
use rand::Rng;
use std::ops::{Add, Sub, Mul, Neg};
use std::ops::{Add, Mul, Neg, Sub};
use super::FieldElement;
#[cfg(feature = "rustc-serialize")]
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use arith::{U512, U256};
use arith::{U256, U512};
macro_rules! field_impl {
($name:ident, $modulus:expr, $rsquared:expr, $rcubed:expr, $one:expr, $inv:expr) => {
@@ -17,7 +17,7 @@ macro_rules! field_impl {
#[inline]
fn from(mut a: $name) -> Self {
a.0.mul(&U256::one(), &U256($modulus), $inv);
a.0
}
}
@@ -114,7 +114,7 @@ macro_rules! field_impl {
fn one() -> Self {
$name(U256($one))
}
fn random<R: Rng>(rng: &mut R) -> Self {
$name(U256::random(rng, &U256($modulus)))
}
@@ -184,19 +184,59 @@ macro_rules! field_impl {
field_impl!(
Fr,
[0x43e1f593f0000001, 0x2833e84879b97091, 0xb85045b68181585d, 0x30644e72e131a029],
[0x1bb8e645ae216da7, 0x53fe3ab1e35c59e3, 0x8c49833d53bb8085, 0x0216d0b17f4e44a5],
[0x5e94d8e1b4bf0040, 0x2a489cbe1cfbb6b8, 0x893cc664a19fcfed, 0x0cf8594b7fcc657c],
[0xac96341c4ffffffb, 0x36fc76959f60cd29, 0x666ea36f7879462e, 0xe0a77c19a07df2f],
[
0x43e1f593f0000001,
0x2833e84879b97091,
0xb85045b68181585d,
0x30644e72e131a029
],
[
0x1bb8e645ae216da7,
0x53fe3ab1e35c59e3,
0x8c49833d53bb8085,
0x0216d0b17f4e44a5
],
[
0x5e94d8e1b4bf0040,
0x2a489cbe1cfbb6b8,
0x893cc664a19fcfed,
0x0cf8594b7fcc657c
],
[
0xac96341c4ffffffb,
0x36fc76959f60cd29,
0x666ea36f7879462e,
0xe0a77c19a07df2f
],
0xc2e1f593efffffff
);
field_impl!(
Fq,
[0x3c208c16d87cfd47, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029],
[0xf32cfc5b538afa89, 0xb5e71911d44501fb, 0x47ab1eff0a417ff6, 0x06d89f71cab8351f],
[0xb1cd6dafda1530df, 0x62f210e6a7283db6, 0xef7f0b0c0ada0afb, 0x20fd6e902d592544],
[0xd35d438dc58f0d9d, 0xa78eb28f5c70b3d, 0x666ea36f7879462c, 0xe0a77c19a07df2f],
[
0x3c208c16d87cfd47,
0x97816a916871ca8d,
0xb85045b68181585d,
0x30644e72e131a029
],
[
0xf32cfc5b538afa89,
0xb5e71911d44501fb,
0x47ab1eff0a417ff6,
0x06d89f71cab8351f
],
[
0xb1cd6dafda1530df,
0x62f210e6a7283db6,
0xef7f0b0c0ada0afb,
0x20fd6e902d592544
],
[
0xd35d438dc58f0d9d,
0xa78eb28f5c70b3d,
0x666ea36f7879462c,
0xe0a77c19a07df2f
],
0x87d20782e4866389
);
+61 -39
View File
@@ -1,5 +1,5 @@
use fields::{FieldElement, Fq2, Fq, Fq6, const_fq};
use std::ops::{Add, Sub, Mul, Neg};
use fields::{const_fq, FieldElement, Fq, Fq2, Fq6};
use std::ops::{Add, Mul, Neg, Sub};
use rand::Rng;
use arith::U256;
@@ -8,18 +8,43 @@ fn frobenius_coeffs_c1(power: usize) -> Fq2 {
match power % 12 {
0 => Fq2::one(),
1 => Fq2::new(
const_fq([12653890742059813127, 14585784200204367754, 1278438861261381767, 212598772761311868]),
const_fq([11683091849979440498, 14992204589386555739, 15866167890766973222, 1200023580730561873])
const_fq([
12653890742059813127,
14585784200204367754,
1278438861261381767,
212598772761311868,
]),
const_fq([
11683091849979440498,
14992204589386555739,
15866167890766973222,
1200023580730561873,
]),
),
2 => Fq2::new(
const_fq([14595462726357228530, 17349508522658994025, 1017833795229664280, 299787779797702374]),
Fq::zero()
const_fq([
14595462726357228530,
17349508522658994025,
1017833795229664280,
299787779797702374,
]),
Fq::zero(),
),
3 => Fq2::new(
const_fq([3914496794763385213, 790120733010914719, 7322192392869644725, 581366264293887267]),
const_fq([12817045492518885689, 4440270538777280383, 11178533038884588256, 2767537931541304486])
const_fq([
3914496794763385213,
790120733010914719,
7322192392869644725,
581366264293887267,
]),
const_fq([
12817045492518885689,
4440270538777280383,
11178533038884588256,
2767537931541304486,
]),
),
_ => unimplemented!()
_ => unimplemented!(),
}
}
@@ -27,15 +52,12 @@ fn frobenius_coeffs_c1(power: usize) -> Fq2 {
#[repr(C)]
pub struct Fq12 {
c0: Fq6,
c1: Fq6
c1: Fq6,
}
impl Fq12 {
pub fn new(c0: Fq6, c1: Fq6) -> Self {
Fq12 {
c0: c0,
c1: c1
}
Fq12 { c0: c0, c1: c1 }
}
fn final_exponentiation_first_chunk(&self) -> Option<Fq12> {
@@ -46,8 +68,8 @@ impl Fq12 {
let d = c.frobenius_map(2);
Some(d * c)
},
None => None
}
None => None,
}
}
@@ -84,30 +106,29 @@ impl Fq12 {
}
pub fn final_exponentiation(&self) -> Option<Fq12> {
self.final_exponentiation_first_chunk().map(|a| a.final_exponentiation_last_chunk())
self.final_exponentiation_first_chunk()
.map(|a| a.final_exponentiation_last_chunk())
}
pub fn frobenius_map(&self, power: usize) -> Self {
Fq12 {
c0: self.c0.frobenius_map(power),
c1: self.c1.frobenius_map(power).scale(frobenius_coeffs_c1(power))
c1: self.c1
.frobenius_map(power)
.scale(frobenius_coeffs_c1(power)),
}
}
pub fn exp_by_neg_z(&self) -> Fq12 {
self.cyclotomic_pow(
U256([4965661367192848881, 0, 0, 0])
).unitary_inverse()
self.cyclotomic_pow(U256([4965661367192848881, 0, 0, 0]))
.unitary_inverse()
}
pub fn unitary_inverse(&self) -> Fq12 {
Fq12::new(self.c0, -self.c1)
}
pub fn mul_by_024(&self,
ell_0: Fq2,
ell_vw: Fq2,
ell_vv: Fq2) -> Fq12 {
pub fn mul_by_024(&self, ell_0: Fq2, ell_vw: Fq2, ell_vv: Fq2) -> Fq12 {
let z0 = self.c0.c0;
let z1 = self.c0.c1;
let z2 = self.c0.c2;
@@ -171,7 +192,7 @@ impl Fq12 {
Fq12 {
c0: Fq6::new(z0, z1, z2),
c1: Fq6::new(z3, z4, z5)
c1: Fq6::new(z3, z4, z5),
}
}
@@ -222,7 +243,7 @@ impl Fq12 {
Fq12 {
c0: Fq6::new(z0, z4, z3),
c1: Fq6::new(z2, z1, z5)
c1: Fq6::new(z2, z1, z5),
}
}
@@ -250,21 +271,21 @@ impl FieldElement for Fq12 {
fn zero() -> Self {
Fq12 {
c0: Fq6::zero(),
c1: Fq6::zero()
c1: Fq6::zero(),
}
}
fn one() -> Self {
Fq12 {
c0: Fq6::one(),
c1: Fq6::zero()
c1: Fq6::zero(),
}
}
fn random<R: Rng>(rng: &mut R) -> Self {
Fq12 {
c0: Fq6::random(rng),
c1: Fq6::random(rng)
c1: Fq6::random(rng),
}
}
@@ -276,8 +297,9 @@ impl FieldElement for Fq12 {
let ab = self.c0 * self.c1;
Fq12 {
c0: (self.c1.mul_by_nonresidue() + self.c0) * (self.c0 + self.c1) - ab - ab.mul_by_nonresidue(),
c1: ab + ab
c0: (self.c1.mul_by_nonresidue() + self.c0) * (self.c0 + self.c1) - ab
- ab.mul_by_nonresidue(),
c1: ab + ab,
}
}
@@ -285,9 +307,9 @@ impl FieldElement for Fq12 {
match (self.c0.squared() - (self.c1.squared().mul_by_nonresidue())).inverse() {
Some(t) => Some(Fq12 {
c0: self.c0 * t,
c1: -(self.c1 * t)
c1: -(self.c1 * t),
}),
None => None
None => None,
}
}
}
@@ -301,7 +323,7 @@ impl Mul for Fq12 {
Fq12 {
c0: bb.mul_by_nonresidue() + aa,
c1: (self.c0 + self.c1) * (other.c0 + other.c1) - aa - bb
c1: (self.c0 + self.c1) * (other.c0 + other.c1) - aa - bb,
}
}
}
@@ -312,7 +334,7 @@ impl Sub for Fq12 {
fn sub(self, other: Fq12) -> Fq12 {
Fq12 {
c0: self.c0 - other.c0,
c1: self.c1 - other.c1
c1: self.c1 - other.c1,
}
}
}
@@ -323,7 +345,7 @@ impl Add for Fq12 {
fn add(self, other: Fq12) -> Fq12 {
Fq12 {
c0: self.c0 + other.c0,
c1: self.c1 + other.c1
c1: self.c1 + other.c1,
}
}
}
@@ -334,7 +356,7 @@ impl Neg for Fq12 {
fn neg(self) -> Fq12 {
Fq12 {
c0: -self.c0,
c1: -self.c1
c1: -self.c1,
}
}
}
+40 -31
View File
@@ -1,24 +1,39 @@
use fields::{FieldElement, const_fq, Fq};
use std::ops::{Add, Sub, Mul, Neg};
use fields::{const_fq, FieldElement, Fq};
use std::ops::{Add, Mul, Neg, Sub};
use rand::Rng;
use arith::{U256, U512};
#[cfg(feature = "rustc-serialize")]
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
#[inline]
fn fq_non_residue() -> Fq {
// (q - 1) is a quadratic nonresidue in Fq
// 21888242871839275222246405745257275088696311157297823662689037894645226208582
const_fq([0x68c3488912edefaa, 0x8d087f6872aabf4f, 0x51e1a24709081231, 0x2259d6b14729c0fa])
const_fq([
0x68c3488912edefaa,
0x8d087f6872aabf4f,
0x51e1a24709081231,
0x2259d6b14729c0fa,
])
}
#[inline]
pub fn fq2_nonresidue() -> Fq2 {
Fq2::new(
const_fq([0xf60647ce410d7ff7, 0x2f3d6f4dd31bd011, 0x2943337e3940c6d1, 0x1d9598e8a7e39857]),
const_fq([0xd35d438dc58f0d9d, 0x0a78eb28f5c70b3d, 0x666ea36f7879462c, 0x0e0a77c19a07df2f])
const_fq([
0xf60647ce410d7ff7,
0x2f3d6f4dd31bd011,
0x2943337e3940c6d1,
0x1d9598e8a7e39857,
]),
const_fq([
0xd35d438dc58f0d9d,
0x0a78eb28f5c70b3d,
0x666ea36f7879462c,
0x0e0a77c19a07df2f,
]),
)
}
@@ -26,7 +41,7 @@ pub fn fq2_nonresidue() -> Fq2 {
#[repr(C)]
pub struct Fq2 {
c0: Fq,
c1: Fq
c1: Fq,
}
#[cfg(feature = "rustc-serialize")]
@@ -45,28 +60,21 @@ impl Decodable for Fq2 {
let combined = try!(U512::decode(s));
match combined.divrem(&Fq::modulus()) {
(Some(c1), c0) => {
Ok(Fq2::new(Fq::new(c0).unwrap(), Fq::new(c1).unwrap()))
},
_ => {
Err(s.error("integer not less than modulus squared"))
}
(Some(c1), c0) => Ok(Fq2::new(Fq::new(c0).unwrap(), Fq::new(c1).unwrap())),
_ => Err(s.error("integer not less than modulus squared")),
}
}
}
impl Fq2 {
pub fn new(c0: Fq, c1: Fq) -> Self {
Fq2 {
c0: c0,
c1: c1
}
Fq2 { c0: c0, c1: c1 }
}
pub fn scale(&self, by: Fq) -> Self {
Fq2 {
c0: self.c0 * by,
c1: self.c1 * by
c1: self.c1 * by,
}
}
@@ -80,7 +88,7 @@ impl Fq2 {
} else {
Fq2 {
c0: self.c0,
c1: self.c1 * fq_non_residue()
c1: self.c1 * fq_non_residue(),
}
}
}
@@ -90,21 +98,21 @@ impl FieldElement for Fq2 {
fn zero() -> Self {
Fq2 {
c0: Fq::zero(),
c1: Fq::zero()
c1: Fq::zero(),
}
}
fn one() -> Self {
Fq2 {
c0: Fq::one(),
c1: Fq::zero()
c1: Fq::zero(),
}
}
fn random<R: Rng>(rng: &mut R) -> Self {
Fq2 {
c0: Fq::random(rng),
c1: Fq::random(rng)
c1: Fq::random(rng),
}
}
@@ -120,8 +128,9 @@ impl FieldElement for Fq2 {
let ab = self.c0 * self.c1;
Fq2 {
c0: (self.c1 * fq_non_residue() + self.c0) * (self.c0 + self.c1) - ab - ab * fq_non_residue(),
c1: ab + ab
c0: (self.c1 * fq_non_residue() + self.c0) * (self.c0 + self.c1) - ab
- ab * fq_non_residue(),
c1: ab + ab,
}
}
@@ -132,9 +141,9 @@ impl FieldElement for Fq2 {
match (self.c0.squared() - (self.c1.squared() * fq_non_residue())).inverse() {
Some(t) => Some(Fq2 {
c0: self.c0 * t,
c1: -(self.c1 * t)
c1: -(self.c1 * t),
}),
None => None
None => None,
}
}
}
@@ -152,7 +161,7 @@ impl Mul for Fq2 {
Fq2 {
c0: bb * fq_non_residue() + aa,
c1: (self.c0 + self.c1) * (other.c0 + other.c1) - aa - bb
c1: (self.c0 + self.c1) * (other.c0 + other.c1) - aa - bb,
}
}
}
@@ -163,7 +172,7 @@ impl Sub for Fq2 {
fn sub(self, other: Fq2) -> Fq2 {
Fq2 {
c0: self.c0 - other.c0,
c1: self.c1 - other.c1
c1: self.c1 - other.c1,
}
}
}
@@ -174,7 +183,7 @@ impl Add for Fq2 {
fn add(self, other: Fq2) -> Fq2 {
Fq2 {
c0: self.c0 + other.c0,
c1: self.c1 + other.c1
c1: self.c1 + other.c1,
}
}
}
@@ -185,7 +194,7 @@ impl Neg for Fq2 {
fn neg(self) -> Fq2 {
Fq2 {
c0: -self.c0,
c1: -self.c1
c1: -self.c1,
}
}
}
+82 -32
View File
@@ -1,41 +1,91 @@
use fields::{FieldElement, Fq, Fq2, const_fq};
use std::ops::{Add, Sub, Mul, Neg};
use fields::{const_fq, FieldElement, Fq, Fq2};
use std::ops::{Add, Mul, Neg, Sub};
use rand::Rng;
fn frobenius_coeffs_c1(n: usize) -> Fq2 {
match n % 6 {
0 => Fq2::one(),
1 => Fq2::new(
const_fq([13075984984163199792, 3782902503040509012, 8791150885551868305, 1825854335138010348]),
const_fq([7963664994991228759, 12257807996192067905, 13179524609921305146, 2767831111890561987])
const_fq([
13075984984163199792,
3782902503040509012,
8791150885551868305,
1825854335138010348,
]),
const_fq([
7963664994991228759,
12257807996192067905,
13179524609921305146,
2767831111890561987,
]),
),
2 => Fq2::new(
const_fq([3697675806616062876, 9065277094688085689, 6918009208039626314, 2775033306905974752]),
Fq::zero()
const_fq([
3697675806616062876,
9065277094688085689,
6918009208039626314,
2775033306905974752,
]),
Fq::zero(),
),
3 => Fq2::new(
const_fq([14532872967180610477, 12903226530429559474, 1868623743233345524, 2316889217940299650]),
const_fq([12447993766991532972, 4121872836076202828, 7630813605053367399, 740282956577754197])
const_fq([
14532872967180610477,
12903226530429559474,
1868623743233345524,
2316889217940299650,
]),
const_fq([
12447993766991532972,
4121872836076202828,
7630813605053367399,
740282956577754197,
]),
),
_ => unimplemented!()
_ => unimplemented!(),
}
}
fn frobenius_coeffs_c2(n: usize) -> Fq2 {
match n % 6 {
0 => Fq2::one(),
1 => Fq2::new(
const_fq([8314163329781907090, 11942187022798819835, 11282677263046157209, 1576150870752482284]),
const_fq([6763840483288992073, 7118829427391486816, 4016233444936635065, 2630958277570195709])
const_fq([
8314163329781907090,
11942187022798819835,
11282677263046157209,
1576150870752482284,
]),
const_fq([
6763840483288992073,
7118829427391486816,
4016233444936635065,
2630958277570195709,
]),
),
2 => Fq2::new(
const_fq([8183898218631979349, 12014359695528440611, 12263358156045030468, 3187210487005268291]),
Fq::zero()
const_fq([
8183898218631979349,
12014359695528440611,
12263358156045030468,
3187210487005268291,
]),
Fq::zero(),
),
3 => Fq2::new(
const_fq([4938922280314430175, 13823286637238282975, 15589480384090068090, 481952561930628184]),
const_fq([3105754162722846417, 11647802298615474591, 13057042392041828081, 1660844386505564338])
const_fq([
4938922280314430175,
13823286637238282975,
15589480384090068090,
481952561930628184,
]),
const_fq([
3105754162722846417,
11647802298615474591,
13057042392041828081,
1660844386505564338,
]),
),
_ => unimplemented!()
_ => unimplemented!(),
}
}
@@ -44,7 +94,7 @@ fn frobenius_coeffs_c2(n: usize) -> Fq2 {
pub struct Fq6 {
pub c0: Fq2,
pub c1: Fq2,
pub c2: Fq2
pub c2: Fq2,
}
impl Fq6 {
@@ -52,7 +102,7 @@ impl Fq6 {
Fq6 {
c0: c0,
c1: c1,
c2: c2
c2: c2,
}
}
@@ -60,7 +110,7 @@ impl Fq6 {
Fq6 {
c0: self.c2.mul_by_nonresidue(),
c1: self.c0,
c2: self.c1
c2: self.c1,
}
}
@@ -68,7 +118,7 @@ impl Fq6 {
Fq6 {
c0: self.c0 * by,
c1: self.c1 * by,
c2: self.c2 * by
c2: self.c2 * by,
}
}
@@ -76,7 +126,7 @@ impl Fq6 {
Fq6 {
c0: self.c0.frobenius_map(power),
c1: self.c1.frobenius_map(power) * frobenius_coeffs_c1(power),
c2: self.c2.frobenius_map(power) * frobenius_coeffs_c2(power)
c2: self.c2.frobenius_map(power) * frobenius_coeffs_c2(power),
}
}
}
@@ -86,7 +136,7 @@ impl FieldElement for Fq6 {
Fq6 {
c0: Fq2::zero(),
c1: Fq2::zero(),
c2: Fq2::zero()
c2: Fq2::zero(),
}
}
@@ -94,15 +144,15 @@ impl FieldElement for Fq6 {
Fq6 {
c0: Fq2::one(),
c1: Fq2::zero(),
c2: Fq2::zero()
c2: Fq2::zero(),
}
}
fn random<R: Rng>(rng: &mut R) -> Self {
Fq6 {
c0: Fq2::random(rng),
c1: Fq2::random(rng),
c2: Fq2::random(rng)
c2: Fq2::random(rng),
}
}
@@ -122,7 +172,7 @@ impl FieldElement for Fq6 {
Fq6 {
c0: s0 + s3.mul_by_nonresidue(),
c1: s1 + s4.mul_by_nonresidue(),
c2: s1 + s2 + s3 - s0 - s4
c2: s1 + s2 + s3 - s0 - s4,
}
}
@@ -134,9 +184,9 @@ impl FieldElement for Fq6 {
Some(t) => Some(Fq6 {
c0: t * c0,
c1: t * c1,
c2: t * c2
c2: t * c2,
}),
None => None
None => None,
}
}
}
@@ -152,7 +202,7 @@ impl Mul for Fq6 {
Fq6 {
c0: ((self.c1 + self.c2) * (other.c1 + other.c2) - b_b - c_c).mul_by_nonresidue() + a_a,
c1: (self.c0 + self.c1) * (other.c0 + other.c1) - a_a - b_b + c_c.mul_by_nonresidue(),
c2: (self.c0 + self.c2) * (other.c0 + other.c2) - a_a + b_b - c_c
c2: (self.c0 + self.c2) * (other.c0 + other.c2) - a_a + b_b - c_c,
}
}
}
@@ -164,7 +214,7 @@ impl Sub for Fq6 {
Fq6 {
c0: self.c0 - other.c0,
c1: self.c1 - other.c1,
c2: self.c2 - other.c2
c2: self.c2 - other.c2,
}
}
}
@@ -176,7 +226,7 @@ impl Add for Fq6 {
Fq6 {
c0: self.c0 + other.c0,
c1: self.c1 + other.c1,
c2: self.c2 + other.c2
c2: self.c2 + other.c2,
}
}
}
@@ -188,7 +238,7 @@ impl Neg for Fq6 {
Fq6 {
c0: -self.c0,
c1: -self.c1,
c2: -self.c2
c2: -self.c2,
}
}
}
+202 -59
View File
@@ -5,25 +5,25 @@ mod fq12;
use arith::U256;
use rand::Rng;
use std::ops::{Add, Sub, Mul, Neg};
use std::ops::{Add, Mul, Neg, Sub};
use std::fmt::Debug;
pub use self::fp::{Fq, Fr, const_fq};
pub use self::fp::{const_fq, Fq, Fr};
pub use self::fq2::{Fq2, fq2_nonresidue};
pub use self::fq6::Fq6;
pub use self::fq12::Fq12;
pub trait FieldElement: Sized
+ Copy
+ Clone
+ Add<Output=Self>
+ Sub<Output=Self>
+ Mul<Output=Self>
+ Neg<Output=Self>
+ PartialEq
+ Eq
+ Debug
{
pub trait FieldElement
: Sized
+ Copy
+ Clone
+ Add<Output = Self>
+ Sub<Output = Self>
+ Mul<Output = Self>
+ Neg<Output = Self>
+ PartialEq
+ Eq
+ Debug {
fn zero() -> Self;
fn one() -> Self;
fn random<R: Rng>(&mut R) -> Self;
@@ -66,8 +66,18 @@ fn test_fq2() {
#[test]
fn test_str() {
assert_eq!(-Fr::one(), Fr::from_str("21888242871839275222246405745257275088548364400416034343698204186575808495616").unwrap());
assert_eq!(-Fq::one(), Fq::from_str("21888242871839275222246405745257275088696311157297823662689037894645226208582").unwrap());
assert_eq!(
-Fr::one(),
Fr::from_str(
"21888242871839275222246405745257275088548364400416034343698204186575808495616"
).unwrap()
);
assert_eq!(
-Fq::one(),
Fq::from_str(
"21888242871839275222246405745257275088696311157297823662689037894645226208582"
).unwrap()
);
}
#[test]
@@ -85,32 +95,56 @@ fn fq12_test_vector() {
let start = Fq12::new(
Fq6::new(
Fq2::new(
Fq::from_str("19797905000333868150253315089095386158892526856493194078073564469188852136946").unwrap(),
Fq::from_str("10509658143212501778222314067134547632307419253211327938344904628569123178733").unwrap()
Fq::from_str(
"19797905000333868150253315089095386158892526856493194078073564469188852136946",
).unwrap(),
Fq::from_str(
"10509658143212501778222314067134547632307419253211327938344904628569123178733",
).unwrap(),
),
Fq2::new(
Fq::from_str("208316612133170645758860571704540129781090973693601051684061348604461399206").unwrap(),
Fq::from_str("12617661120538088237397060591907161689901553895660355849494983891299803248390").unwrap()
Fq::from_str(
"208316612133170645758860571704540129781090973693601051684061348604461399206",
).unwrap(),
Fq::from_str(
"12617661120538088237397060591907161689901553895660355849494983891299803248390",
).unwrap(),
),
Fq2::new(
Fq::from_str("2897490589776053688661991433341220818937967872052418196321943489809183508515").unwrap(),
Fq::from_str("2730506433347642574983433139433778984782882168213690554721050571242082865799").unwrap()
)
Fq::from_str(
"2897490589776053688661991433341220818937967872052418196321943489809183508515",
).unwrap(),
Fq::from_str(
"2730506433347642574983433139433778984782882168213690554721050571242082865799",
).unwrap(),
),
),
Fq6::new(
Fq2::new(
Fq::from_str("17870056122431653936196746815433147921488990391314067765563891966783088591110").unwrap(),
Fq::from_str("14314041658607615069703576372547568077123863812415914883625850585470406221594").unwrap()
Fq::from_str(
"17870056122431653936196746815433147921488990391314067765563891966783088591110",
).unwrap(),
Fq::from_str(
"14314041658607615069703576372547568077123863812415914883625850585470406221594",
).unwrap(),
),
Fq2::new(
Fq::from_str("10123533891707846623287020000407963680629966110211808794181173248765209982878").unwrap(),
Fq::from_str("5062091880848845693514855272640141851746424235009114332841857306926659567101").unwrap()
Fq::from_str(
"10123533891707846623287020000407963680629966110211808794181173248765209982878",
).unwrap(),
Fq::from_str(
"5062091880848845693514855272640141851746424235009114332841857306926659567101",
).unwrap(),
),
Fq2::new(
Fq::from_str("9839781502639936537333620974973645053542086898304697594692219798017709586567").unwrap(),
Fq::from_str("1583892292110602864638265389721494775152090720173641072176370350017825640703").unwrap()
)
)
Fq::from_str(
"9839781502639936537333620974973645053542086898304697594692219798017709586567",
).unwrap(),
Fq::from_str(
"1583892292110602864638265389721494775152090720173641072176370350017825640703",
).unwrap(),
),
),
);
// Do a bunch of arbitrary stuff to the element
@@ -137,32 +171,56 @@ fn fq12_test_vector() {
let finally = Fq12::new(
Fq6::new(
Fq2::new(
Fq::from_str("18388750939593263065521177085001223024106699964957029146547831509155008229833").unwrap(),
Fq::from_str("18370529854582635460997127698388761779167953912610241447912705473964014492243").unwrap()
Fq::from_str(
"18388750939593263065521177085001223024106699964957029146547831509155008229833",
).unwrap(),
Fq::from_str(
"18370529854582635460997127698388761779167953912610241447912705473964014492243",
).unwrap(),
),
Fq2::new(
Fq::from_str("3691824277096717481466579496401243638295254271265821828017111951446539785268").unwrap(),
Fq::from_str("20513494218085713799072115076991457239411567892860153903443302793553884247235").unwrap()
Fq::from_str(
"3691824277096717481466579496401243638295254271265821828017111951446539785268",
).unwrap(),
Fq::from_str(
"20513494218085713799072115076991457239411567892860153903443302793553884247235",
).unwrap(),
),
Fq2::new(
Fq::from_str("12214155472433286415803224222551966441740960297013786627326456052558698216399").unwrap(),
Fq::from_str("10987494248070743195602580056085773610850106455323751205990078881956262496575").unwrap()
)
Fq::from_str(
"12214155472433286415803224222551966441740960297013786627326456052558698216399",
).unwrap(),
Fq::from_str(
"10987494248070743195602580056085773610850106455323751205990078881956262496575",
).unwrap(),
),
),
Fq6::new(
Fq2::new(
Fq::from_str("5134522153456102954632718911439874984161223687865160221119284322136466794876").unwrap(),
Fq::from_str("20119236909927036376726859192821071338930785378711977469360149362002019539920").unwrap()
Fq::from_str(
"5134522153456102954632718911439874984161223687865160221119284322136466794876",
).unwrap(),
Fq::from_str(
"20119236909927036376726859192821071338930785378711977469360149362002019539920",
).unwrap(),
),
Fq2::new(
Fq::from_str("8839766648621210419302228913265679710586991805716981851373026244791934012854").unwrap(),
Fq::from_str("9103032146464138788288547957401673544458789595252696070370942789051858719203").unwrap()
Fq::from_str(
"8839766648621210419302228913265679710586991805716981851373026244791934012854",
).unwrap(),
Fq::from_str(
"9103032146464138788288547957401673544458789595252696070370942789051858719203",
).unwrap(),
),
Fq2::new(
Fq::from_str("10378379548636866240502412547812481928323945124508039853766409196375806029865").unwrap(),
Fq::from_str("9021627154807648093720460686924074684389554332435186899318369174351765754041").unwrap()
)
)
Fq::from_str(
"10378379548636866240502412547812481928323945124508039853766409196375806029865",
).unwrap(),
Fq::from_str(
"9021627154807648093720460686924074684389554332435186899318369174351765754041",
).unwrap(),
),
),
);
assert_eq!(finally, next);
@@ -172,27 +230,112 @@ fn fq12_test_vector() {
fn test_cyclotomic_exp() {
let orig = Fq12::new(
Fq6::new(
Fq2::new(Fq::from_str("2259924035228092997691937637688451143058635253053054071159756458902878894295").unwrap(), Fq::from_str("13145690032701362144460254305183927872683620413225364127064863863535255135244").unwrap()),
Fq2::new(Fq::from_str("9910063591662383599552477067956819406417086889312288278252482503717089428441").unwrap(), Fq::from_str("537414042055419261990282459138081732565514913399498746664966841152381183961").unwrap()),
Fq2::new(Fq::from_str("15311812409497308894370893420777496684951030254049554818293571309705780605004").unwrap(), Fq::from_str("13657107176064455789881282546557276003626320193974643644160350907227082365810").unwrap())
Fq2::new(
Fq::from_str(
"2259924035228092997691937637688451143058635253053054071159756458902878894295",
).unwrap(),
Fq::from_str(
"13145690032701362144460254305183927872683620413225364127064863863535255135244",
).unwrap(),
),
Fq2::new(
Fq::from_str(
"9910063591662383599552477067956819406417086889312288278252482503717089428441",
).unwrap(),
Fq::from_str(
"537414042055419261990282459138081732565514913399498746664966841152381183961",
).unwrap(),
),
Fq2::new(
Fq::from_str(
"15311812409497308894370893420777496684951030254049554818293571309705780605004",
).unwrap(),
Fq::from_str(
"13657107176064455789881282546557276003626320193974643644160350907227082365810",
).unwrap(),
),
),
Fq6::new(
Fq2::new(
Fq::from_str(
"4913017949003742946864670837361832856526234260447029873580022776602534856819",
).unwrap(),
Fq::from_str(
"7834351480852267338070670220119081676575418514182895774094743209915633114041",
).unwrap(),
),
Fq2::new(
Fq::from_str(
"12837298223308203788092748646758194441270207338661891973231184407371206766993",
).unwrap(),
Fq::from_str(
"12756474445699147370503225379431475413909971718057034061593007812727141391799",
).unwrap(),
),
Fq2::new(
Fq::from_str(
"9473802207170192255373153510655867502408045964296373712891954747252332944018",
).unwrap(),
Fq::from_str(
"4583089109360519374075173304035813179013579459429335467869926761027310749713",
).unwrap(),
),
),
Fq6::new(Fq2::new(Fq::from_str("4913017949003742946864670837361832856526234260447029873580022776602534856819").unwrap(), Fq::from_str("7834351480852267338070670220119081676575418514182895774094743209915633114041").unwrap()),
Fq2::new(Fq::from_str("12837298223308203788092748646758194441270207338661891973231184407371206766993").unwrap(), Fq::from_str("12756474445699147370503225379431475413909971718057034061593007812727141391799").unwrap()),
Fq2::new(Fq::from_str("9473802207170192255373153510655867502408045964296373712891954747252332944018").unwrap(), Fq::from_str("4583089109360519374075173304035813179013579459429335467869926761027310749713").unwrap())
)
);
let expected = Fq12::new(
Fq6::new(
Fq2::new(Fq::from_str("14722956046055152398903846391223329501345567382234608299399030576415080188350").unwrap(), Fq::from_str("14280703280777926697010730619606819467080027543707671882210769811674790473417").unwrap()),
Fq2::new(Fq::from_str("19969875076083990244184003223190771301761436396530543002586073549972410735411").unwrap(), Fq::from_str("10717335566913889643303549252432531178405520196706173198634734518494041323243").unwrap()),
Fq2::new(Fq::from_str("6063612626166484870786832843320782567259894784043383626084549455432890717937").unwrap(), Fq::from_str("17089783040131779205038789608891431427943860868115199598200376195935079808729").unwrap())
Fq2::new(
Fq::from_str(
"14722956046055152398903846391223329501345567382234608299399030576415080188350",
).unwrap(),
Fq::from_str(
"14280703280777926697010730619606819467080027543707671882210769811674790473417",
).unwrap(),
),
Fq2::new(
Fq::from_str(
"19969875076083990244184003223190771301761436396530543002586073549972410735411",
).unwrap(),
Fq::from_str(
"10717335566913889643303549252432531178405520196706173198634734518494041323243",
).unwrap(),
),
Fq2::new(
Fq::from_str(
"6063612626166484870786832843320782567259894784043383626084549455432890717937",
).unwrap(),
Fq::from_str(
"17089783040131779205038789608891431427943860868115199598200376195935079808729",
).unwrap(),
),
),
Fq6::new(
Fq2::new(Fq::from_str("10029863438921507421569931792104023129735006154272482043027653425575205672906").unwrap(), Fq::from_str("6406252222753462799887280578845937185621081001436094637606245493619821542775").unwrap()),
Fq2::new(Fq::from_str("1048245462913506652602966692378792381004227332967846949234978073448561848050").unwrap(), Fq::from_str("1444281375189053827455518242624554285012408033699861764136810522738182087554").unwrap()),
Fq2::new(Fq::from_str("8839610992666735109106629514135300820412539620261852250193684883379364789120").unwrap(), Fq::from_str("11347360242067273846784836674906058940820632082713814508736182487171407730718").unwrap())
)
Fq2::new(
Fq::from_str(
"10029863438921507421569931792104023129735006154272482043027653425575205672906",
).unwrap(),
Fq::from_str(
"6406252222753462799887280578845937185621081001436094637606245493619821542775",
).unwrap(),
),
Fq2::new(
Fq::from_str(
"1048245462913506652602966692378792381004227332967846949234978073448561848050",
).unwrap(),
Fq::from_str(
"1444281375189053827455518242624554285012408033699861764136810522738182087554",
).unwrap(),
),
Fq2::new(
Fq::from_str(
"8839610992666735109106629514135300820412539620261852250193684883379364789120",
).unwrap(),
Fq::from_str(
"11347360242067273846784836674906058940820632082713814508736182487171407730718",
).unwrap(),
),
),
);
let e = orig.exp_by_neg_z();
+2 -5
View File
@@ -1,4 +1,4 @@
use rand::{Rng,SeedableRng,StdRng};
use rand::{Rng, SeedableRng, StdRng};
use super::FieldElement;
fn can_invert<F: FieldElement>() {
@@ -27,10 +27,7 @@ fn rand_element_eval<F: FieldElement, R: Rng>(rng: &mut R) {
let c = F::random(rng);
let d = F::random(rng);
assert_eq!(
(a + b) * (c + d),
(a * c) + (b * c) + (a * d) + (b * d)
);
assert_eq!((a + b) * (c + d), (a * c) + (b * c) + (a * d) + (b * d));
}
}