mirror of
https://github.com/pezkuwichain/bizinikiwi-bn.git
synced 2026-07-21 15:05:42 +00:00
rustfmt
This commit is contained in:
+4
-4
@@ -1,12 +1,12 @@
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
extern crate rand;
|
||||
extern crate bn;
|
||||
extern crate bincode;
|
||||
extern crate bn;
|
||||
extern crate rand;
|
||||
extern crate test;
|
||||
|
||||
use bn::*;
|
||||
use bincode::SizeLimit::Infinite;
|
||||
use bincode::rustc_serialize::{encode, decode};
|
||||
use bincode::rustc_serialize::{decode, encode};
|
||||
|
||||
const SAMPLES: usize = 30;
|
||||
|
||||
|
||||
+99
-57
@@ -2,8 +2,8 @@ use std::cmp::Ordering;
|
||||
use rand::Rng;
|
||||
|
||||
#[cfg(feature = "rustc-serialize")]
|
||||
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
|
||||
use byteorder::{ByteOrder, BigEndian};
|
||||
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
|
||||
/// 256-bit, stack allocated biginteger for use in prime field
|
||||
/// arithmetic.
|
||||
@@ -45,8 +45,7 @@ impl U512 {
|
||||
}
|
||||
|
||||
/// Get a random U512
|
||||
pub fn random<R: Rng>(rng: &mut R) -> U512
|
||||
{
|
||||
pub fn random<R: Rng>(rng: &mut R) -> U512 {
|
||||
U512(rng.gen())
|
||||
}
|
||||
|
||||
@@ -63,8 +62,7 @@ impl U512 {
|
||||
|
||||
/// Divides self by modulo, returning remainder and, if
|
||||
/// possible, a quotient smaller than the modulus.
|
||||
pub fn divrem(&self, modulo: &U256) -> (Option<U256>, U256)
|
||||
{
|
||||
pub fn divrem(&self, modulo: &U256) -> (Option<U256>, U256) {
|
||||
let mut q = Some(U256::zero());
|
||||
let mut r = U256::zero();
|
||||
|
||||
@@ -154,7 +152,7 @@ impl Decodable for U256 {
|
||||
buf[i] = try!(s.read_u8());
|
||||
}
|
||||
|
||||
U256::from_slice(&buf).map_err(|_| s.error("Invalid input length; Also unreachable;"))
|
||||
U256::from_slice(&buf).map_err(|_| s.error("Invalid input length; Also unreachable;"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,10 +185,14 @@ pub enum Error {
|
||||
}
|
||||
|
||||
impl U256 {
|
||||
|
||||
/// Initialize U256 from slice of bytes (big endian)
|
||||
pub fn from_slice(s: &[u8]) -> Result<U256, Error> {
|
||||
if s.len() != 32 { return Err(Error::InvalidLength { expected: 32, actual: s.len() }); }
|
||||
if s.len() != 32 {
|
||||
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 * 8)) {
|
||||
@@ -201,11 +203,16 @@ impl U256 {
|
||||
}
|
||||
|
||||
pub fn to_big_endian(&self, s: &mut [u8]) -> Result<(), Error> {
|
||||
if s.len() != 32 { return Err(Error::InvalidLength { expected: 32, actual: s.len() }); }
|
||||
if s.len() != 32 {
|
||||
return Err(Error::InvalidLength {
|
||||
expected: 32,
|
||||
actual: s.len(),
|
||||
});
|
||||
}
|
||||
|
||||
for (l, i) in (0..4).rev().zip((0..4).map(|i| i * 8)) {
|
||||
BigEndian::write_u64(&mut s[i..], self.0[l]);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -221,20 +228,15 @@ impl U256 {
|
||||
}
|
||||
|
||||
/// Produce a random number (mod `modulo`)
|
||||
pub fn random<R: Rng>(rng: &mut R, modulo: &U256) -> U256
|
||||
{
|
||||
pub fn random<R: Rng>(rng: &mut R, modulo: &U256) -> U256 {
|
||||
U512::random(rng).divrem(modulo).1
|
||||
}
|
||||
|
||||
pub fn is_zero(&self) -> bool {
|
||||
self.0[0] == 0 &&
|
||||
self.0[1] == 0 &&
|
||||
self.0[2] == 0 &&
|
||||
self.0[3] == 0
|
||||
self.0[0] == 0 && self.0[1] == 0 && self.0[2] == 0 && self.0[3] == 0
|
||||
}
|
||||
|
||||
pub fn set_bit(&mut self, n: usize, to: bool) -> bool
|
||||
{
|
||||
pub fn set_bit(&mut self, n: usize, to: bool) -> bool {
|
||||
if n >= 256 {
|
||||
false
|
||||
} else {
|
||||
@@ -251,8 +253,7 @@ impl U256 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_bit(&self, n: usize) -> Option<bool>
|
||||
{
|
||||
pub fn get_bit(&self, n: usize) -> Option<bool> {
|
||||
if n >= 256 {
|
||||
None
|
||||
} else {
|
||||
@@ -296,7 +297,7 @@ impl U256 {
|
||||
if *self > Self::zero() {
|
||||
let mut tmp = modulo.0;
|
||||
sub_noborrow(&mut tmp, &self.0);
|
||||
|
||||
|
||||
self.0 = tmp;
|
||||
}
|
||||
}
|
||||
@@ -358,16 +359,13 @@ impl U256 {
|
||||
/// Return an Iterator<Item=bool> over all bits from
|
||||
/// MSB to LSB.
|
||||
pub fn bits(&self) -> BitIterator {
|
||||
BitIterator {
|
||||
int: &self,
|
||||
n: 256
|
||||
}
|
||||
BitIterator { int: &self, n: 256 }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BitIterator<'a> {
|
||||
int: &'a U256,
|
||||
n: usize
|
||||
n: usize,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for BitIterator<'a> {
|
||||
@@ -376,8 +374,7 @@ impl<'a> Iterator for BitIterator<'a> {
|
||||
fn next(&mut self) -> Option<bool> {
|
||||
if self.n == 0 {
|
||||
None
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
self.n -= 1;
|
||||
|
||||
self.int.get_bit(self.n)
|
||||
@@ -467,8 +464,7 @@ fn sub_noborrow(a: &mut [u64; 4], b: &[u64; 4]) {
|
||||
debug_assert!(0 == borrow);
|
||||
}
|
||||
|
||||
fn mac_digit(acc: &mut [u64], b: &[u64], c: u64)
|
||||
{
|
||||
fn mac_digit(acc: &mut [u64], b: &[u64], c: u64) {
|
||||
#[inline]
|
||||
fn mac_with_carry(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
|
||||
let (b_hi, b_lo) = split_u64(b);
|
||||
@@ -507,18 +503,12 @@ fn mac_digit(acc: &mut [u64], b: &[u64], c: u64)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn mul_reduce(
|
||||
this: &mut [u64; 4],
|
||||
by: &[u64; 4],
|
||||
modulus: &[u64; 4],
|
||||
inv: u64
|
||||
)
|
||||
{
|
||||
fn mul_reduce(this: &mut [u64; 4], by: &[u64; 4], modulus: &[u64; 4], inv: u64) {
|
||||
// The Montgomery reduction here is based on Algorithm 14.32 in
|
||||
// Handbook of Applied Cryptography
|
||||
// <http://cacr.uwaterloo.ca/hac/about/chap14.pdf>.
|
||||
|
||||
let mut res = [0; 2*4];
|
||||
let mut res = [0; 2 * 4];
|
||||
for (i, xi) in this.iter().enumerate() {
|
||||
mac_digit(&mut res[i..], by, *xi);
|
||||
}
|
||||
@@ -551,7 +541,8 @@ fn from_slice() {
|
||||
let mut s = [0u8; 32];
|
||||
s[31] = 1;
|
||||
|
||||
let num = U256::from_slice(&s).expect("U256 should initialize ok from slice in `from_slice` test");
|
||||
let num =
|
||||
U256::from_slice(&s).expect("U256 should initialize ok from slice in `from_slice` test");
|
||||
assert_eq!(num, tst);
|
||||
}
|
||||
|
||||
@@ -560,12 +551,13 @@ fn to_big_endian() {
|
||||
let num = U256::one();
|
||||
let mut s = [0u8; 32];
|
||||
|
||||
num.to_big_endian(&mut s).expect("U256 should convert to bytes ok in `to_big_endian` test");
|
||||
num.to_big_endian(&mut s)
|
||||
.expect("U256 should convert to bytes ok in `to_big_endian` test");
|
||||
assert_eq!(
|
||||
s,
|
||||
[
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -574,7 +566,12 @@ fn to_big_endian() {
|
||||
fn testing_divrem() {
|
||||
let rng = &mut ::rand::thread_rng();
|
||||
|
||||
let modulo = U256([0x3c208c16d87cfd47, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029]);
|
||||
let modulo = U256([
|
||||
0x3c208c16d87cfd47,
|
||||
0x97816a916871ca8d,
|
||||
0xb85045b68181585d,
|
||||
0x30644e72e131a029,
|
||||
]);
|
||||
|
||||
for _ in 0..100 {
|
||||
let c0 = U256::random(rng, &modulo);
|
||||
@@ -598,7 +595,7 @@ fn testing_divrem() {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
0,
|
||||
]);
|
||||
|
||||
let (c1, c0) = a.divrem(&modulo);
|
||||
@@ -616,12 +613,28 @@ fn testing_divrem() {
|
||||
0x26edfa5c34c6b38d,
|
||||
0xb00b855116375606,
|
||||
0x599a6f7c0348d21c,
|
||||
0x0925c4b8763cbf9c
|
||||
0x0925c4b8763cbf9c,
|
||||
]);
|
||||
|
||||
let (c1, c0) = a.divrem(&modulo);
|
||||
assert_eq!(c1.unwrap(), U256([0x3c208c16d87cfd46, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029]));
|
||||
assert_eq!(c0, U256([0x3c208c16d87cfd46, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029]));
|
||||
assert_eq!(
|
||||
c1.unwrap(),
|
||||
U256([
|
||||
0x3c208c16d87cfd46,
|
||||
0x97816a916871ca8d,
|
||||
0xb85045b68181585d,
|
||||
0x30644e72e131a029
|
||||
])
|
||||
);
|
||||
assert_eq!(
|
||||
c0,
|
||||
U256([
|
||||
0x3c208c16d87cfd46,
|
||||
0x97816a916871ca8d,
|
||||
0xb85045b68181585d,
|
||||
0x30644e72e131a029
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -634,13 +647,29 @@ fn testing_divrem() {
|
||||
0x26edfa5c34c6b38d,
|
||||
0xb00b855116375606,
|
||||
0x599a6f7c0348d21c,
|
||||
0x0925c4b8763cbf9c
|
||||
0x0925c4b8763cbf9c,
|
||||
]);
|
||||
|
||||
let (c1, c0) = a.divrem(&modulo);
|
||||
|
||||
assert_eq!(c1.unwrap(), U256([0x3c208c16d87cfd46, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029]));
|
||||
assert_eq!(c0, U256([0x3c208c16d87cfd45, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029]));
|
||||
assert_eq!(
|
||||
c1.unwrap(),
|
||||
U256([
|
||||
0x3c208c16d87cfd46,
|
||||
0x97816a916871ca8d,
|
||||
0xb85045b68181585d,
|
||||
0x30644e72e131a029
|
||||
])
|
||||
);
|
||||
assert_eq!(
|
||||
c0,
|
||||
U256([
|
||||
0x3c208c16d87cfd45,
|
||||
0x97816a916871ca8d,
|
||||
0xb85045b68181585d,
|
||||
0x30644e72e131a029
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -653,12 +682,20 @@ fn testing_divrem() {
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff
|
||||
0xffffffffffffffff,
|
||||
]);
|
||||
|
||||
let (c1, c0) = a.divrem(&modulo);
|
||||
assert!(c1.is_none());
|
||||
assert_eq!(c0, U256([0xf32cfc5b538afa88, 0xb5e71911d44501fb, 0x47ab1eff0a417ff6, 0x06d89f71cab8351f]));
|
||||
assert_eq!(
|
||||
c0,
|
||||
U256([
|
||||
0xf32cfc5b538afa88,
|
||||
0xb5e71911d44501fb,
|
||||
0x47ab1eff0a417ff6,
|
||||
0x06d89f71cab8351f
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -671,7 +708,7 @@ fn testing_divrem() {
|
||||
0x26edfa5c34c6b38d,
|
||||
0xb00b855116375606,
|
||||
0x599a6f7c0348d21c,
|
||||
0x0925c4b8763cbf9c
|
||||
0x0925c4b8763cbf9c,
|
||||
]);
|
||||
|
||||
let (c1, c0) = a.divrem(&modulo);
|
||||
@@ -689,7 +726,7 @@ fn testing_divrem() {
|
||||
0x26edfa5c34c6b38d,
|
||||
0xb00b855116375606,
|
||||
0x599a6f7c0348d21c,
|
||||
0x0925c4b8763cbf9c
|
||||
0x0925c4b8763cbf9c,
|
||||
]);
|
||||
|
||||
let (c1, c0) = a.divrem(&modulo);
|
||||
@@ -698,7 +735,12 @@ fn testing_divrem() {
|
||||
}
|
||||
|
||||
{
|
||||
let modulo = U256([0x43e1f593f0000001, 0x2833e84879b97091, 0xb85045b68181585d, 0x30644e72e131a029]);
|
||||
let modulo = U256([
|
||||
0x43e1f593f0000001,
|
||||
0x2833e84879b97091,
|
||||
0xb85045b68181585d,
|
||||
0x30644e72e131a029,
|
||||
]);
|
||||
|
||||
// Fr modulus masked off is valid
|
||||
let a = U512([
|
||||
@@ -709,7 +751,7 @@ fn testing_divrem() {
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0x07ffffffffffffff
|
||||
0x07ffffffffffffff,
|
||||
]);
|
||||
|
||||
let (c1, c0) = a.divrem(&modulo);
|
||||
|
||||
+53
-13
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+236
-101
@@ -1,23 +1,23 @@
|
||||
use std::ops::{Add,Sub,Neg,Mul};
|
||||
use fields::{FieldElement, Fq, Fq2, Fq12, Fr, const_fq, fq2_nonresidue};
|
||||
use std::ops::{Add, Mul, Neg, Sub};
|
||||
use fields::{const_fq, FieldElement, Fq, Fq12, Fq2, Fr, fq2_nonresidue};
|
||||
use arith::U256;
|
||||
use std::fmt;
|
||||
use rand::Rng;
|
||||
|
||||
#[cfg(feature = "rustc-serialize")]
|
||||
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
|
||||
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
||||
|
||||
pub trait GroupElement: Sized +
|
||||
Copy +
|
||||
Clone +
|
||||
PartialEq +
|
||||
Eq +
|
||||
fmt::Debug +
|
||||
Add<Output=Self> +
|
||||
Sub<Output=Self> +
|
||||
Neg<Output=Self> +
|
||||
Mul<Fr, Output=Self>
|
||||
{
|
||||
pub trait GroupElement
|
||||
: Sized
|
||||
+ Copy
|
||||
+ Clone
|
||||
+ PartialEq
|
||||
+ Eq
|
||||
+ fmt::Debug
|
||||
+ Add<Output = Self>
|
||||
+ Sub<Output = Self>
|
||||
+ Neg<Output = Self>
|
||||
+ Mul<Fr, Output = Self> {
|
||||
fn zero() -> Self;
|
||||
fn one() -> Self;
|
||||
fn random<R: Rng>(rng: &mut R) -> Self;
|
||||
@@ -34,23 +34,21 @@ pub trait GroupParams: Sized {
|
||||
fn name() -> &'static str;
|
||||
fn one() -> G<Self>;
|
||||
fn coeff_b() -> Self::Base;
|
||||
fn check_order() -> bool { false }
|
||||
fn check_order() -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct G<P: GroupParams> {
|
||||
x: P::Base,
|
||||
y: P::Base,
|
||||
z: P::Base
|
||||
z: P::Base,
|
||||
}
|
||||
|
||||
impl<P: GroupParams> G<P> {
|
||||
pub fn new(x: P::Base, y: P::Base, z: P::Base) -> Self {
|
||||
G {
|
||||
x: x,
|
||||
y: y,
|
||||
z: z,
|
||||
}
|
||||
G { x: x, y: y, z: z }
|
||||
}
|
||||
|
||||
pub fn x(&self) -> &P::Base {
|
||||
@@ -67,7 +65,7 @@ impl<P: GroupParams> G<P> {
|
||||
|
||||
pub fn y_mut(&mut self) -> &mut P::Base {
|
||||
&mut self.y
|
||||
}
|
||||
}
|
||||
|
||||
pub fn z(&self) -> &P::Base {
|
||||
&self.z
|
||||
@@ -75,12 +73,12 @@ impl<P: GroupParams> G<P> {
|
||||
|
||||
pub fn z_mut(&mut self) -> &mut P::Base {
|
||||
&mut self.z
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AffineG<P: GroupParams> {
|
||||
x: P::Base,
|
||||
y: P::Base
|
||||
y: P::Base,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -96,18 +94,15 @@ impl<P: GroupParams> AffineG<P> {
|
||||
let p: G<P> = G {
|
||||
x: x,
|
||||
y: y,
|
||||
z: P::Base::one()
|
||||
z: P::Base::one(),
|
||||
};
|
||||
|
||||
if (p * (-Fr::one())) + p != G::zero() {
|
||||
return Err(Error::NotInSubgroup)
|
||||
return Err(Error::NotInSubgroup);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(AffineG {
|
||||
x: x,
|
||||
y: y
|
||||
})
|
||||
Ok(AffineG { x: x, y: y })
|
||||
} else {
|
||||
Err(Error::NotOnCurve)
|
||||
}
|
||||
@@ -136,7 +131,7 @@ impl<P: GroupParams> PartialEq for AffineG<P> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: GroupParams> Eq for AffineG<P> { }
|
||||
impl<P: GroupParams> Eq for AffineG<P> {}
|
||||
|
||||
impl<P: GroupParams> fmt::Debug for G<P> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
@@ -149,7 +144,7 @@ impl<P: GroupParams> Clone for G<P> {
|
||||
G {
|
||||
x: self.x,
|
||||
y: self.y,
|
||||
z: self.z
|
||||
z: self.z,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,7 +155,7 @@ impl<P: GroupParams> Clone for AffineG<P> {
|
||||
fn clone(&self) -> Self {
|
||||
AffineG {
|
||||
x: self.x,
|
||||
y: self.y
|
||||
y: self.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,7 +165,7 @@ impl<P: GroupParams> Copy for AffineG<P> {}
|
||||
impl<P: GroupParams> PartialEq for G<P> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
if self.is_zero() {
|
||||
return other.is_zero()
|
||||
return other.is_zero();
|
||||
}
|
||||
|
||||
if other.is_zero() {
|
||||
@@ -194,7 +189,7 @@ impl<P: GroupParams> PartialEq for G<P> {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
impl<P: GroupParams> Eq for G<P> { }
|
||||
impl<P: GroupParams> Eq for G<P> {}
|
||||
|
||||
impl<P: GroupParams> G<P> {
|
||||
pub fn to_affine(&self) -> Option<AffineG<P>> {
|
||||
@@ -203,7 +198,7 @@ impl<P: GroupParams> G<P> {
|
||||
} else if self.z == P::Base::one() {
|
||||
Some(AffineG {
|
||||
x: self.x,
|
||||
y: self.y
|
||||
y: self.y,
|
||||
})
|
||||
} else {
|
||||
let zinv = self.z.inverse().unwrap();
|
||||
@@ -211,7 +206,7 @@ impl<P: GroupParams> G<P> {
|
||||
|
||||
Some(AffineG {
|
||||
x: self.x * zinv_squared,
|
||||
y: self.y * (zinv_squared * zinv)
|
||||
y: self.y * (zinv_squared * zinv),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -222,7 +217,7 @@ impl<P: GroupParams> AffineG<P> {
|
||||
G {
|
||||
x: self.x,
|
||||
y: self.y,
|
||||
z: P::Base::one()
|
||||
z: P::Base::one(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,11 +266,9 @@ impl<P: GroupParams> Decodable for AffineG<P> {
|
||||
let x = try!(P::Base::decode(s));
|
||||
let y = try!(P::Base::decode(s));
|
||||
|
||||
Self::new(x, y).map_err(|e| {
|
||||
match e {
|
||||
Error::NotOnCurve => s.error("point is not on the curve"),
|
||||
Error::NotInSubgroup => s.error("point is not in the subgroup"),
|
||||
}
|
||||
Self::new(x, y).map_err(|e| match e {
|
||||
Error::NotOnCurve => s.error("point is not on the curve"),
|
||||
Error::NotInSubgroup => s.error("point is not in the subgroup"),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -285,7 +278,7 @@ impl<P: GroupParams> GroupElement for G<P> {
|
||||
G {
|
||||
x: P::Base::zero(),
|
||||
y: P::Base::one(),
|
||||
z: P::Base::zero()
|
||||
z: P::Base::zero(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,7 +311,7 @@ impl<P: GroupParams> GroupElement for G<P> {
|
||||
G {
|
||||
x: x3,
|
||||
y: e * (d - x3) - eight_c,
|
||||
z: y1z1 + y1z1
|
||||
z: y1z1 + y1z1,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -381,7 +374,7 @@ impl<P: GroupParams> Add<G<P>> for G<P> {
|
||||
G {
|
||||
x: x3,
|
||||
y: r * (v - x3) - (s1_j + s1_j),
|
||||
z: ((self.z + other.z).squared() - z1_squared - z2_squared) * h
|
||||
z: ((self.z + other.z).squared() - z1_squared - z2_squared) * h,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -397,7 +390,7 @@ impl<P: GroupParams> Neg for G<P> {
|
||||
G {
|
||||
x: self.x,
|
||||
y: -self.y,
|
||||
z: self.z
|
||||
z: self.z,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -409,7 +402,7 @@ impl<P: GroupParams> Neg for AffineG<P> {
|
||||
fn neg(self) -> AffineG<P> {
|
||||
AffineG {
|
||||
x: self.x,
|
||||
y: -self.y
|
||||
y: -self.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -427,18 +420,30 @@ pub struct G1Params;
|
||||
impl GroupParams for G1Params {
|
||||
type Base = Fq;
|
||||
|
||||
fn name() -> &'static str { "G1" }
|
||||
fn name() -> &'static str {
|
||||
"G1"
|
||||
}
|
||||
|
||||
fn one() -> G<Self> {
|
||||
G {
|
||||
x: Fq::one(),
|
||||
y: const_fq([0xa6ba871b8b1e1b3a, 0x14f1d651eb8e167b, 0xccdd46def0f28c58, 0x1c14ef83340fbe5e]),
|
||||
z: Fq::one()
|
||||
y: const_fq([
|
||||
0xa6ba871b8b1e1b3a,
|
||||
0x14f1d651eb8e167b,
|
||||
0xccdd46def0f28c58,
|
||||
0x1c14ef83340fbe5e,
|
||||
]),
|
||||
z: Fq::one(),
|
||||
}
|
||||
}
|
||||
|
||||
fn coeff_b() -> Fq {
|
||||
const_fq([0x7a17caa950ad28d7, 0x1f6ac17ae15521b9, 0x334bea4e696bd284, 0x2a1f6744ce179d8e])
|
||||
const_fq([
|
||||
0x7a17caa950ad28d7,
|
||||
0x1f6ac17ae15521b9,
|
||||
0x334bea4e696bd284,
|
||||
0x2a1f6744ce179d8e,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,30 +456,64 @@ pub struct G2Params;
|
||||
impl GroupParams for G2Params {
|
||||
type Base = Fq2;
|
||||
|
||||
fn name() -> &'static str { "G2" }
|
||||
fn name() -> &'static str {
|
||||
"G2"
|
||||
}
|
||||
|
||||
fn one() -> G<Self> {
|
||||
G {
|
||||
x: Fq2::new(
|
||||
const_fq([0x8e83b5d102bc2026, 0xdceb1935497b0172, 0xfbb8264797811adf, 0x19573841af96503b]),
|
||||
const_fq([0xafb4737da84c6140, 0x6043dd5a5802d8c4, 0x09e950fc52a02f86, 0x14fef0833aea7b6b])
|
||||
const_fq([
|
||||
0x8e83b5d102bc2026,
|
||||
0xdceb1935497b0172,
|
||||
0xfbb8264797811adf,
|
||||
0x19573841af96503b,
|
||||
]),
|
||||
const_fq([
|
||||
0xafb4737da84c6140,
|
||||
0x6043dd5a5802d8c4,
|
||||
0x09e950fc52a02f86,
|
||||
0x14fef0833aea7b6b,
|
||||
]),
|
||||
),
|
||||
y: Fq2::new(
|
||||
const_fq([0x619dfa9d886be9f6, 0xfe7fd297f59e9b78, 0xff9e1a62231b7dfe, 0x28fd7eebae9e4206]),
|
||||
const_fq([0x64095b56c71856ee, 0xdc57f922327d3cbb, 0x55f935be33351076, 0x0da4a0e693fd6482])
|
||||
const_fq([
|
||||
0x619dfa9d886be9f6,
|
||||
0xfe7fd297f59e9b78,
|
||||
0xff9e1a62231b7dfe,
|
||||
0x28fd7eebae9e4206,
|
||||
]),
|
||||
const_fq([
|
||||
0x64095b56c71856ee,
|
||||
0xdc57f922327d3cbb,
|
||||
0x55f935be33351076,
|
||||
0x0da4a0e693fd6482,
|
||||
]),
|
||||
),
|
||||
z: Fq2::one()
|
||||
z: Fq2::one(),
|
||||
}
|
||||
}
|
||||
|
||||
fn coeff_b() -> Fq2 {
|
||||
Fq2::new(
|
||||
const_fq([0x3bf938e377b802a8, 0x020b1b273633535d, 0x26b7edf049755260, 0x2514c6324384a86d]),
|
||||
const_fq([0x38e7ecccd1dcff67, 0x65f0b37d93ce0d3e, 0xd749d0dd22ac00aa, 0x0141b9ce4a688d4d])
|
||||
const_fq([
|
||||
0x3bf938e377b802a8,
|
||||
0x020b1b273633535d,
|
||||
0x26b7edf049755260,
|
||||
0x2514c6324384a86d,
|
||||
]),
|
||||
const_fq([
|
||||
0x38e7ecccd1dcff67,
|
||||
0x65f0b37d93ce0d3e,
|
||||
0xd749d0dd22ac00aa,
|
||||
0x0141b9ce4a688d4d,
|
||||
]),
|
||||
)
|
||||
}
|
||||
|
||||
fn check_order() -> bool { true }
|
||||
fn check_order() -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub type G2 = G<G2Params>;
|
||||
@@ -525,27 +564,57 @@ fn twist() -> Fq2 {
|
||||
|
||||
#[inline]
|
||||
fn two_inv() -> Fq {
|
||||
const_fq([9781510331150239090, 15059239858463337189, 10331104244869713732, 2249375503248834476])
|
||||
const_fq([
|
||||
9781510331150239090,
|
||||
15059239858463337189,
|
||||
10331104244869713732,
|
||||
2249375503248834476,
|
||||
])
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ate_loop_count() -> U256 {
|
||||
U256([0x9d797039be763ba8, 0x0000000000000001, 0x0000000000000000, 0x0000000000000000])
|
||||
U256([
|
||||
0x9d797039be763ba8,
|
||||
0x0000000000000001,
|
||||
0x0000000000000000,
|
||||
0x0000000000000000,
|
||||
])
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn twist_mul_by_q_x() -> Fq2 {
|
||||
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,
|
||||
]),
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn twist_mul_by_q_y() -> Fq2 {
|
||||
Fq2::new(
|
||||
const_fq([16482010305593259561, 13488546290961988299, 3578621962720924518, 2681173117283399901]),
|
||||
const_fq([11661927080404088775, 553939530661941723, 7860678177968807019, 3208568454732775116])
|
||||
const_fq([
|
||||
16482010305593259561,
|
||||
13488546290961988299,
|
||||
3578621962720924518,
|
||||
2681173117283399901,
|
||||
]),
|
||||
const_fq([
|
||||
11661927080404088775,
|
||||
553939530661941723,
|
||||
7860678177968807019,
|
||||
3208568454732775116,
|
||||
]),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -553,13 +622,13 @@ fn twist_mul_by_q_y() -> Fq2 {
|
||||
pub struct EllCoeffs {
|
||||
pub ell_0: Fq2,
|
||||
pub ell_vw: Fq2,
|
||||
pub ell_vv: Fq2
|
||||
pub ell_vv: Fq2,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct G2Precomp {
|
||||
pub q: AffineG<G2Params>,
|
||||
pub coeffs: Vec<EllCoeffs>
|
||||
pub coeffs: Vec<EllCoeffs>,
|
||||
}
|
||||
|
||||
impl G2Precomp {
|
||||
@@ -579,7 +648,8 @@ impl G2Precomp {
|
||||
|
||||
let c = &self.coeffs[idx];
|
||||
idx += 1;
|
||||
f = f.squared().mul_by_024(c.ell_0, c.ell_vw.scale(g1.y), c.ell_vv.scale(g1.x));
|
||||
f = f.squared()
|
||||
.mul_by_024(c.ell_0, c.ell_vw.scale(g1.y), c.ell_vv.scale(g1.x));
|
||||
|
||||
if i {
|
||||
let c = &self.coeffs[idx];
|
||||
@@ -603,8 +673,14 @@ impl G2Precomp {
|
||||
fn test_miller_loop() {
|
||||
use fields::Fq6;
|
||||
|
||||
let g1 = G1::one() * Fr::from_str("18097487326282793650237947474982649264364522469319914492172746413872781676").unwrap();
|
||||
let g2 = G2::one() * Fr::from_str("20390255904278144451778773028944684152769293537511418234311120800877067946").unwrap();
|
||||
let g1 = G1::one()
|
||||
* Fr::from_str(
|
||||
"18097487326282793650237947474982649264364522469319914492172746413872781676",
|
||||
).unwrap();
|
||||
let g2 = G2::one()
|
||||
* Fr::from_str(
|
||||
"20390255904278144451778773028944684152769293537511418234311120800877067946",
|
||||
).unwrap();
|
||||
|
||||
let g1_pre = g1.to_affine().unwrap();
|
||||
let g2_pre = g2.to_affine().unwrap().precompute();
|
||||
@@ -630,7 +706,7 @@ impl AffineG<G2Params> {
|
||||
fn mul_by_q(&self) -> Self {
|
||||
AffineG {
|
||||
x: twist_mul_by_q_x() * self.x.frobenius_map(1),
|
||||
y: twist_mul_by_q_y() * self.y.frobenius_map(1)
|
||||
y: twist_mul_by_q_y() * self.y.frobenius_map(1),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -663,13 +739,16 @@ impl AffineG<G2Params> {
|
||||
|
||||
G2Precomp {
|
||||
q: *self,
|
||||
coeffs: coeffs
|
||||
coeffs: coeffs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl G2 {
|
||||
fn mixed_addition_step_for_flipped_miller_loop(&mut self, base: &AffineG<G2Params>) -> EllCoeffs {
|
||||
fn mixed_addition_step_for_flipped_miller_loop(
|
||||
&mut self,
|
||||
base: &AffineG<G2Params>,
|
||||
) -> EllCoeffs {
|
||||
let d = self.x - self.z * base.x;
|
||||
let e = self.y - self.z * base.y;
|
||||
let f = d.squared();
|
||||
@@ -685,7 +764,7 @@ impl G2 {
|
||||
EllCoeffs {
|
||||
ell_0: twist() * (e * base.x - d * base.y),
|
||||
ell_vv: e.neg(),
|
||||
ell_vw: d
|
||||
ell_vw: d,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -709,14 +788,17 @@ impl G2 {
|
||||
EllCoeffs {
|
||||
ell_0: twist() * i,
|
||||
ell_vw: h.neg(),
|
||||
ell_vv: j + j + j
|
||||
ell_vv: j + j + j,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_prepared_g2() {
|
||||
let g2 = G2::one() * Fr::from_str("20390255904278144451778773028944684152769293537511418234311120800877067946").unwrap();
|
||||
let g2 = G2::one()
|
||||
* Fr::from_str(
|
||||
"20390255904278144451778773028944684152769293537511418234311120800877067946",
|
||||
).unwrap();
|
||||
|
||||
let g2_p = g2.to_affine().unwrap().precompute();
|
||||
|
||||
@@ -844,9 +926,10 @@ fn test_prepared_g2() {
|
||||
pub fn pairing(p: &G1, q: &G2) -> Fq12 {
|
||||
match (p.to_affine(), q.to_affine()) {
|
||||
(None, _) | (_, None) => Fq12::one(),
|
||||
(Some(p), Some(q)) => {
|
||||
q.precompute().miller_loop(&p).final_exponentiation().expect("miller loop cannot produce zero")
|
||||
}
|
||||
(Some(p), Some(q)) => q.precompute()
|
||||
.miller_loop(&p)
|
||||
.final_exponentiation()
|
||||
.expect("miller loop cannot produce zero"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -854,22 +937,70 @@ pub fn pairing(p: &G1, q: &G2) -> Fq12 {
|
||||
fn test_reduced_pairing() {
|
||||
use fields::Fq6;
|
||||
|
||||
let g1 = G1::one() * Fr::from_str("18097487326282793650237947474982649264364522469319914492172746413872781676").unwrap();
|
||||
let g2 = G2::one() * Fr::from_str("20390255904278144451778773028944684152769293537511418234311120800877067946").unwrap();
|
||||
let g1 = G1::one()
|
||||
* Fr::from_str(
|
||||
"18097487326282793650237947474982649264364522469319914492172746413872781676",
|
||||
).unwrap();
|
||||
let g2 = G2::one()
|
||||
* Fr::from_str(
|
||||
"20390255904278144451778773028944684152769293537511418234311120800877067946",
|
||||
).unwrap();
|
||||
|
||||
let gt = pairing(&g1, &g2);
|
||||
|
||||
let expected = Fq12::new(
|
||||
Fq6::new(
|
||||
Fq2::new(Fq::from_str("7520311483001723614143802378045727372643587653754534704390832890681688842501").unwrap(), Fq::from_str("20265650864814324826731498061022229653175757397078253377158157137251452249882").unwrap()),
|
||||
Fq2::new(Fq::from_str("11942254371042183455193243679791334797733902728447312943687767053513298221130").unwrap(), Fq::from_str("759657045325139626991751731924144629256296901790485373000297868065176843620").unwrap()),
|
||||
Fq2::new(Fq::from_str("16045761475400271697821392803010234478356356448940805056528536884493606035236").unwrap(), Fq::from_str("4715626119252431692316067698189337228571577552724976915822652894333558784086").unwrap())
|
||||
Fq2::new(
|
||||
Fq::from_str(
|
||||
"7520311483001723614143802378045727372643587653754534704390832890681688842501",
|
||||
).unwrap(),
|
||||
Fq::from_str(
|
||||
"20265650864814324826731498061022229653175757397078253377158157137251452249882",
|
||||
).unwrap(),
|
||||
),
|
||||
Fq2::new(
|
||||
Fq::from_str(
|
||||
"11942254371042183455193243679791334797733902728447312943687767053513298221130",
|
||||
).unwrap(),
|
||||
Fq::from_str(
|
||||
"759657045325139626991751731924144629256296901790485373000297868065176843620",
|
||||
).unwrap(),
|
||||
),
|
||||
Fq2::new(
|
||||
Fq::from_str(
|
||||
"16045761475400271697821392803010234478356356448940805056528536884493606035236",
|
||||
).unwrap(),
|
||||
Fq::from_str(
|
||||
"4715626119252431692316067698189337228571577552724976915822652894333558784086",
|
||||
).unwrap(),
|
||||
),
|
||||
),
|
||||
Fq6::new(
|
||||
Fq2::new(Fq::from_str("14901948363362882981706797068611719724999331551064314004234728272909570402962").unwrap(), Fq::from_str("11093203747077241090565767003969726435272313921345853819385060670210834379103").unwrap()),
|
||||
Fq2::new(Fq::from_str("17897835398184801202802503586172351707502775171934235751219763553166796820753").unwrap(), Fq::from_str("1344517825169318161285758374052722008806261739116142912817807653057880346554").unwrap()),
|
||||
Fq2::new(Fq::from_str("11123896897251094532909582772961906225000817992624500900708432321664085800838").unwrap(), Fq::from_str("17453370448280081813275586256976217762629631160552329276585874071364454854650").unwrap())
|
||||
)
|
||||
Fq2::new(
|
||||
Fq::from_str(
|
||||
"14901948363362882981706797068611719724999331551064314004234728272909570402962",
|
||||
).unwrap(),
|
||||
Fq::from_str(
|
||||
"11093203747077241090565767003969726435272313921345853819385060670210834379103",
|
||||
).unwrap(),
|
||||
),
|
||||
Fq2::new(
|
||||
Fq::from_str(
|
||||
"17897835398184801202802503586172351707502775171934235751219763553166796820753",
|
||||
).unwrap(),
|
||||
Fq::from_str(
|
||||
"1344517825169318161285758374052722008806261739116142912817807653057880346554",
|
||||
).unwrap(),
|
||||
),
|
||||
Fq2::new(
|
||||
Fq::from_str(
|
||||
"11123896897251094532909582772961906225000817992624500900708432321664085800838",
|
||||
).unwrap(),
|
||||
Fq::from_str(
|
||||
"17453370448280081813275586256976217762629631160552329276585874071364454854650",
|
||||
).unwrap(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
assert_eq!(expected, gt);
|
||||
@@ -878,9 +1009,10 @@ fn test_reduced_pairing() {
|
||||
#[test]
|
||||
fn predefined_pair() {
|
||||
let g1 = AffineG1::new(
|
||||
Fq::from_str("1").expect("Fq(1) should exist"),
|
||||
Fq::from_str("1").expect("Fq(1) should exist"),
|
||||
Fq::from_str("2").expect("Fq(2) should exist"),
|
||||
).expect("Point (1,2) should exist in G1").to_jacobian();
|
||||
).expect("Point (1,2) should exist in G1")
|
||||
.to_jacobian();
|
||||
|
||||
let g2 = AffineG2::new(
|
||||
Fq2::new(
|
||||
@@ -905,7 +1037,7 @@ fn predefined_pair() {
|
||||
|
||||
#[test]
|
||||
fn test_binlinearity() {
|
||||
use rand::{SeedableRng,StdRng};
|
||||
use rand::{SeedableRng, StdRng};
|
||||
let seed: [usize; 4] = [103245, 191922, 1293, 192103];
|
||||
let mut rng = StdRng::from_seed(&seed);
|
||||
|
||||
@@ -934,13 +1066,10 @@ fn test_binlinearity() {
|
||||
fn internals() {
|
||||
let test_p = G1::one();
|
||||
|
||||
let val = G1::new(
|
||||
test_p.x().clone(),
|
||||
test_p.y().clone(),
|
||||
test_p.z().clone(),
|
||||
);
|
||||
let val = G1::new(test_p.x().clone(), test_p.y().clone(), test_p.z().clone());
|
||||
|
||||
let affine = val.to_affine().expect("There should be affine coords for (0, 0)");
|
||||
let affine = val.to_affine()
|
||||
.expect("There should be affine coords for (0, 0)");
|
||||
|
||||
assert_eq!(affine.x(), &Fq::one());
|
||||
}
|
||||
@@ -948,13 +1077,19 @@ fn internals() {
|
||||
#[test]
|
||||
fn affine_fail() {
|
||||
let res = AffineG1::new(Fq::one(), Fq::one());
|
||||
assert!(res.is_err(), "Affine initialization should fail because the point is not on curve");
|
||||
assert!(
|
||||
res.is_err(),
|
||||
"Affine initialization should fail because the point is not on curve"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn affine_ok() {
|
||||
let res = AffineG1::new(Fq::one(), G1Params::coeff_b());
|
||||
assert!(res.is_err(), "Affine initialization should be ok because the point is on the curve");
|
||||
assert!(
|
||||
res.is_err(),
|
||||
"Affine initialization should be ok because the point is on the curve"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
+1
-2
@@ -90,7 +90,7 @@ pub fn group_trials<G: GroupElement>() {
|
||||
|
||||
assert!((G::one() * (-Fr::one()) + G::one()).is_zero());
|
||||
|
||||
use rand::{SeedableRng,StdRng};
|
||||
use rand::{SeedableRng, StdRng};
|
||||
let seed: [usize; 4] = [103245, 191922, 1293, 192103];
|
||||
let mut rng = StdRng::from_seed(&seed);
|
||||
|
||||
@@ -99,4 +99,3 @@ pub fn group_trials<G: GroupElement>() {
|
||||
random_test_dh::<G, _>(&mut rng);
|
||||
random_test_equality::<G, _>(&mut rng);
|
||||
}
|
||||
|
||||
|
||||
+174
-84
@@ -1,7 +1,7 @@
|
||||
extern crate byteorder;
|
||||
extern crate rand;
|
||||
#[cfg(feature = "rustc-serialize")]
|
||||
extern crate rustc_serialize;
|
||||
extern crate byteorder;
|
||||
|
||||
pub mod arith;
|
||||
mod fields;
|
||||
@@ -10,7 +10,7 @@ mod groups;
|
||||
use fields::FieldElement;
|
||||
use groups::GroupElement;
|
||||
|
||||
use std::ops::{Add, Sub, Mul, Neg};
|
||||
use std::ops::{Add, Mul, Neg, Sub};
|
||||
use rand::Rng;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
@@ -19,13 +19,27 @@ use rand::Rng;
|
||||
pub struct Fr(fields::Fr);
|
||||
|
||||
impl Fr {
|
||||
pub fn zero() -> Self { Fr(fields::Fr::zero()) }
|
||||
pub fn one() -> Self { Fr(fields::Fr::one()) }
|
||||
pub fn random<R: Rng>(rng: &mut R) -> Self { Fr(fields::Fr::random(rng)) }
|
||||
pub fn pow(&self, exp: Fr) -> Self { Fr(self.0.pow(exp.0)) }
|
||||
pub fn from_str(s: &str) -> Option<Self> { fields::Fr::from_str(s).map(|e| Fr(e)) }
|
||||
pub fn inverse(&self) -> Option<Self> { self.0.inverse().map(|e| Fr(e)) }
|
||||
pub fn is_zero(&self) -> bool { self.0.is_zero() }
|
||||
pub fn zero() -> Self {
|
||||
Fr(fields::Fr::zero())
|
||||
}
|
||||
pub fn one() -> Self {
|
||||
Fr(fields::Fr::one())
|
||||
}
|
||||
pub fn random<R: Rng>(rng: &mut R) -> Self {
|
||||
Fr(fields::Fr::random(rng))
|
||||
}
|
||||
pub fn pow(&self, exp: Fr) -> Self {
|
||||
Fr(self.0.pow(exp.0))
|
||||
}
|
||||
pub fn from_str(s: &str) -> Option<Self> {
|
||||
fields::Fr::from_str(s).map(|e| Fr(e))
|
||||
}
|
||||
pub fn inverse(&self) -> Option<Self> {
|
||||
self.0.inverse().map(|e| Fr(e))
|
||||
}
|
||||
pub fn is_zero(&self) -> bool {
|
||||
self.0.is_zero()
|
||||
}
|
||||
pub fn interpret(buf: &[u8; 64]) -> Fr {
|
||||
Fr(fields::Fr::interpret(buf))
|
||||
}
|
||||
@@ -36,32 +50,43 @@ impl Fr {
|
||||
.map(|x| Fr(x))
|
||||
}
|
||||
pub fn to_big_endian(&self, slice: &mut [u8]) -> Result<(), FieldError> {
|
||||
self.0.raw().to_big_endian(slice).map_err(|_| FieldError::InvalidSliceLength)
|
||||
self.0
|
||||
.raw()
|
||||
.to_big_endian(slice)
|
||||
.map_err(|_| FieldError::InvalidSliceLength)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Fr> for Fr {
|
||||
type Output = Fr;
|
||||
|
||||
fn add(self, other: Fr) -> Fr { Fr(self.0 + other.0) }
|
||||
fn add(self, other: Fr) -> Fr {
|
||||
Fr(self.0 + other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<Fr> for Fr {
|
||||
type Output = Fr;
|
||||
|
||||
fn sub(self, other: Fr) -> Fr { Fr(self.0 - other.0) }
|
||||
fn sub(self, other: Fr) -> Fr {
|
||||
Fr(self.0 - other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for Fr {
|
||||
type Output = Fr;
|
||||
|
||||
fn neg(self) -> Fr { Fr(-self.0) }
|
||||
fn neg(self) -> Fr {
|
||||
Fr(-self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul for Fr {
|
||||
type Output = Fr;
|
||||
|
||||
fn mul(self, other: Fr) -> Fr { Fr(self.0 * other.0) }
|
||||
fn mul(self, other: Fr) -> Fr {
|
||||
Fr(self.0 * other.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -78,13 +103,27 @@ pub use groups::Error as GroupError;
|
||||
pub struct Fq(fields::Fq);
|
||||
|
||||
impl Fq {
|
||||
pub fn zero() -> Self { Fq(fields::Fq::zero()) }
|
||||
pub fn one() -> Self { Fq(fields::Fq::one()) }
|
||||
pub fn random<R: Rng>(rng: &mut R) -> Self { Fq(fields::Fq::random(rng)) }
|
||||
pub fn pow(&self, exp: Fq) -> Self { Fq(self.0.pow(exp.0)) }
|
||||
pub fn from_str(s: &str) -> Option<Self> { fields::Fq::from_str(s).map(|e| Fq(e)) }
|
||||
pub fn inverse(&self) -> Option<Self> { self.0.inverse().map(|e| Fq(e)) }
|
||||
pub fn is_zero(&self) -> bool { self.0.is_zero() }
|
||||
pub fn zero() -> Self {
|
||||
Fq(fields::Fq::zero())
|
||||
}
|
||||
pub fn one() -> Self {
|
||||
Fq(fields::Fq::one())
|
||||
}
|
||||
pub fn random<R: Rng>(rng: &mut R) -> Self {
|
||||
Fq(fields::Fq::random(rng))
|
||||
}
|
||||
pub fn pow(&self, exp: Fq) -> Self {
|
||||
Fq(self.0.pow(exp.0))
|
||||
}
|
||||
pub fn from_str(s: &str) -> Option<Self> {
|
||||
fields::Fq::from_str(s).map(|e| Fq(e))
|
||||
}
|
||||
pub fn inverse(&self) -> Option<Self> {
|
||||
self.0.inverse().map(|e| Fq(e))
|
||||
}
|
||||
pub fn is_zero(&self) -> bool {
|
||||
self.0.is_zero()
|
||||
}
|
||||
pub fn interpret(buf: &[u8; 64]) -> Fq {
|
||||
Fq(fields::Fq::interpret(buf))
|
||||
}
|
||||
@@ -97,33 +136,46 @@ impl Fq {
|
||||
pub fn to_big_endian(&self, slice: &mut [u8]) -> Result<(), FieldError> {
|
||||
let mut a: arith::U256 = self.0.into();
|
||||
// convert from Montgomery representation
|
||||
a.mul(&fields::Fq::one().raw(), &fields::Fq::modulus(), self.0.inv());
|
||||
a.to_big_endian(slice).map_err(|_| FieldError::InvalidSliceLength)
|
||||
a.mul(
|
||||
&fields::Fq::one().raw(),
|
||||
&fields::Fq::modulus(),
|
||||
self.0.inv(),
|
||||
);
|
||||
a.to_big_endian(slice)
|
||||
.map_err(|_| FieldError::InvalidSliceLength)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Fq> for Fq {
|
||||
type Output = Fq;
|
||||
|
||||
fn add(self, other: Fq) -> Fq { Fq(self.0 + other.0) }
|
||||
fn add(self, other: Fq) -> Fq {
|
||||
Fq(self.0 + other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<Fq> for Fq {
|
||||
type Output = Fq;
|
||||
|
||||
fn sub(self, other: Fq) -> Fq { Fq(self.0 - other.0) }
|
||||
fn sub(self, other: Fq) -> Fq {
|
||||
Fq(self.0 - other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for Fq {
|
||||
type Output = Fq;
|
||||
|
||||
fn neg(self) -> Fq { Fq(-self.0) }
|
||||
fn neg(self) -> Fq {
|
||||
Fq(-self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul for Fq {
|
||||
type Output = Fq;
|
||||
|
||||
fn mul(self, other: Fq) -> Fq { Fq(self.0 * other.0) }
|
||||
fn mul(self, other: Fq) -> Fq {
|
||||
Fq(self.0 * other.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Fq2(fields::Fq2);
|
||||
@@ -135,7 +187,7 @@ impl Fq2 {
|
||||
|
||||
pub fn zero() -> Fq2 {
|
||||
Fq2(fields::Fq2::zero())
|
||||
}
|
||||
}
|
||||
|
||||
/// Initalizes new F_q2(a + bi, a is real coeff, b is imaginary)
|
||||
pub fn new(a: Fq, b: Fq) -> Fq2 {
|
||||
@@ -148,21 +200,20 @@ impl Fq2 {
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustc-serialize")]
|
||||
pub trait Group:
|
||||
rustc_serialize::Encodable +
|
||||
rustc_serialize::Decodable +
|
||||
Send +
|
||||
Sync +
|
||||
Copy +
|
||||
Clone +
|
||||
PartialEq +
|
||||
Eq +
|
||||
Sized +
|
||||
Add<Self, Output=Self> +
|
||||
Sub<Self, Output=Self> +
|
||||
Neg<Output=Self> +
|
||||
Mul<Fr, Output=Self>
|
||||
{
|
||||
pub trait Group
|
||||
: rustc_serialize::Encodable
|
||||
+ rustc_serialize::Decodable
|
||||
+ Send
|
||||
+ Sync
|
||||
+ Copy
|
||||
+ Clone
|
||||
+ PartialEq
|
||||
+ Eq
|
||||
+ Sized
|
||||
+ Add<Self, Output = Self>
|
||||
+ Sub<Self, Output = Self>
|
||||
+ Neg<Output = Self>
|
||||
+ Mul<Fr, Output = Self> {
|
||||
fn zero() -> Self;
|
||||
fn one() -> Self;
|
||||
fn random<R: Rng>(rng: &mut R) -> Self;
|
||||
@@ -171,19 +222,18 @@ pub trait Group:
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "rustc-serialize"))]
|
||||
pub trait Group:
|
||||
Send +
|
||||
Sync +
|
||||
Copy +
|
||||
Clone +
|
||||
PartialEq +
|
||||
Eq +
|
||||
Sized +
|
||||
Add<Self, Output=Self> +
|
||||
Sub<Self, Output=Self> +
|
||||
Neg<Output=Self> +
|
||||
Mul<Fr, Output=Self>
|
||||
{
|
||||
pub trait Group
|
||||
: Send
|
||||
+ Sync
|
||||
+ Copy
|
||||
+ Clone
|
||||
+ PartialEq
|
||||
+ Eq
|
||||
+ Sized
|
||||
+ Add<Self, Output = Self>
|
||||
+ Sub<Self, Output = Self>
|
||||
+ Neg<Output = Self>
|
||||
+ Mul<Fr, Output = Self> {
|
||||
fn zero() -> Self;
|
||||
fn one() -> Self;
|
||||
fn random<R: Rng>(rng: &mut R) -> Self;
|
||||
@@ -215,7 +265,7 @@ impl G1 {
|
||||
|
||||
pub fn set_y(&mut self, y: Fq) {
|
||||
*self.0.y_mut() = y.0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn z(&self) -> Fq {
|
||||
Fq(self.0.z().clone())
|
||||
@@ -223,18 +273,26 @@ impl G1 {
|
||||
|
||||
pub fn set_z(&mut self, z: Fq) {
|
||||
*self.0.z_mut() = z.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Group for G1 {
|
||||
fn zero() -> Self { G1(groups::G1::zero()) }
|
||||
fn one() -> Self { G1(groups::G1::one()) }
|
||||
fn random<R: Rng>(rng: &mut R) -> Self { G1(groups::G1::random(rng)) }
|
||||
fn is_zero(&self) -> bool { self.0.is_zero() }
|
||||
fn zero() -> Self {
|
||||
G1(groups::G1::zero())
|
||||
}
|
||||
fn one() -> Self {
|
||||
G1(groups::G1::one())
|
||||
}
|
||||
fn random<R: Rng>(rng: &mut R) -> Self {
|
||||
G1(groups::G1::random(rng))
|
||||
}
|
||||
fn is_zero(&self) -> bool {
|
||||
self.0.is_zero()
|
||||
}
|
||||
fn normalize(&mut self) {
|
||||
let new = match self.0.to_affine() {
|
||||
Some(a) => a,
|
||||
None => return
|
||||
None => return,
|
||||
};
|
||||
|
||||
self.0 = new.to_jacobian();
|
||||
@@ -244,25 +302,33 @@ impl Group for G1 {
|
||||
impl Add<G1> for G1 {
|
||||
type Output = G1;
|
||||
|
||||
fn add(self, other: G1) -> G1 { G1(self.0 + other.0) }
|
||||
fn add(self, other: G1) -> G1 {
|
||||
G1(self.0 + other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<G1> for G1 {
|
||||
type Output = G1;
|
||||
|
||||
fn sub(self, other: G1) -> G1 { G1(self.0 - other.0) }
|
||||
fn sub(self, other: G1) -> G1 {
|
||||
G1(self.0 - other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for G1 {
|
||||
type Output = G1;
|
||||
|
||||
fn neg(self) -> G1 { G1(-self.0) }
|
||||
fn neg(self) -> G1 {
|
||||
G1(-self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Fr> for G1 {
|
||||
type Output = G1;
|
||||
|
||||
fn mul(self, other: Fr) -> G1 { G1(self.0 * other.0) }
|
||||
fn mul(self, other: Fr) -> G1 {
|
||||
G1(self.0 * other.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
@@ -289,7 +355,7 @@ impl AffineG1 {
|
||||
|
||||
pub fn set_y(&mut self, y: Fq) {
|
||||
*self.0.y_mut() = y.0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_jacobian(g1: G1) -> Option<Self> {
|
||||
g1.0.to_affine().map(|x| AffineG1(x))
|
||||
@@ -326,7 +392,7 @@ impl G2 {
|
||||
|
||||
pub fn set_y(&mut self, y: Fq2) {
|
||||
*self.0.y_mut() = y.0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn z(&self) -> Fq2 {
|
||||
Fq2(self.0.z().clone())
|
||||
@@ -334,18 +400,26 @@ impl G2 {
|
||||
|
||||
pub fn set_z(&mut self, z: Fq2) {
|
||||
*self.0.z_mut() = z.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Group for G2 {
|
||||
fn zero() -> Self { G2(groups::G2::zero()) }
|
||||
fn one() -> Self { G2(groups::G2::one()) }
|
||||
fn random<R: Rng>(rng: &mut R) -> Self { G2(groups::G2::random(rng)) }
|
||||
fn is_zero(&self) -> bool { self.0.is_zero() }
|
||||
fn zero() -> Self {
|
||||
G2(groups::G2::zero())
|
||||
}
|
||||
fn one() -> Self {
|
||||
G2(groups::G2::one())
|
||||
}
|
||||
fn random<R: Rng>(rng: &mut R) -> Self {
|
||||
G2(groups::G2::random(rng))
|
||||
}
|
||||
fn is_zero(&self) -> bool {
|
||||
self.0.is_zero()
|
||||
}
|
||||
fn normalize(&mut self) {
|
||||
let new = match self.0.to_affine() {
|
||||
Some(a) => a,
|
||||
None => return
|
||||
None => return,
|
||||
};
|
||||
|
||||
self.0 = new.to_jacobian();
|
||||
@@ -355,25 +429,33 @@ impl Group for G2 {
|
||||
impl Add<G2> for G2 {
|
||||
type Output = G2;
|
||||
|
||||
fn add(self, other: G2) -> G2 { G2(self.0 + other.0) }
|
||||
fn add(self, other: G2) -> G2 {
|
||||
G2(self.0 + other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<G2> for G2 {
|
||||
type Output = G2;
|
||||
|
||||
fn sub(self, other: G2) -> G2 { G2(self.0 - other.0) }
|
||||
fn sub(self, other: G2) -> G2 {
|
||||
G2(self.0 - other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for G2 {
|
||||
type Output = G2;
|
||||
|
||||
fn neg(self) -> G2 { G2(-self.0) }
|
||||
fn neg(self) -> G2 {
|
||||
G2(-self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Fr> for G2 {
|
||||
type Output = G2;
|
||||
|
||||
fn mul(self, other: Fr) -> G2 { G2(self.0 * other.0) }
|
||||
fn mul(self, other: Fr) -> G2 {
|
||||
G2(self.0 * other.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
@@ -381,15 +463,23 @@ impl Mul<Fr> for G2 {
|
||||
pub struct Gt(fields::Fq12);
|
||||
|
||||
impl Gt {
|
||||
pub fn one() -> Self { Gt(fields::Fq12::one()) }
|
||||
pub fn pow(&self, exp: Fr) -> Self { Gt(self.0.pow(exp.0)) }
|
||||
pub fn inverse(&self) -> Self { Gt(self.0.inverse().unwrap()) }
|
||||
pub fn one() -> Self {
|
||||
Gt(fields::Fq12::one())
|
||||
}
|
||||
pub fn pow(&self, exp: Fr) -> Self {
|
||||
Gt(self.0.pow(exp.0))
|
||||
}
|
||||
pub fn inverse(&self) -> Self {
|
||||
Gt(self.0.inverse().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Gt> for Gt {
|
||||
type Output = Gt;
|
||||
|
||||
fn mul(self, other: Gt) -> Gt { Gt(self.0 * other.0) }
|
||||
fn mul(self, other: Gt) -> Gt {
|
||||
Gt(self.0 * other.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pairing(p: G1, q: G2) -> Gt {
|
||||
@@ -420,7 +510,7 @@ impl AffineG2 {
|
||||
|
||||
pub fn set_y(&mut self, y: Fq2) {
|
||||
*self.0.y_mut() = y.0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_jacobian(g2: G2) -> Option<Self> {
|
||||
g2.0.to_affine().map(|x| AffineG2(x))
|
||||
|
||||
Reference in New Issue
Block a user