Merge pull request #1 from matter-labs/playground

Edition 2018 + expose Montgommery forms
This commit is contained in:
Alexander 2019-07-13 21:58:58 +03:00 committed by GitHub
commit e93d939ae0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 225 additions and 107 deletions

@ -2,7 +2,7 @@
name = "pairing_ce"
# Remember to change version string in README.md.
version = "0.17.0"
version = "0.18.0"
authors = [
"Sean Bowe <ewillbefull@gmail.com>",
"Jack Grigg <jack@z.cash>",
@ -15,18 +15,14 @@ description = "Pairing-friendly elliptic curve library"
documentation = "https://docs.rs/pairing/"
homepage = "https://github.com/matter-labs/pairing"
repository = "https://github.com/matter-labs/pairing"
edition = "2018"
[dependencies]
rand = "0.4"
byteorder = "1"
ff_ce = {version = "0.6", features = ["derive"] }
#ff = { git = 'https://github.com/matterinc/ff', features = ["derive"], tag = "0.5"}
serde = "1.0.80"
serde_derive = "1.0.80"
serde_json = "1.0.33"
hex = "0.3.2"
ff = {package = "ff_ce", version = "0.7", features = ["derive"]}
#ff = { path = '../ff', package = "ff_ce", features = ["derive"]}
[features]
unstable-features = ["expose-arith"]
expose-arith = []
default = []

@ -1,7 +1,7 @@
#![feature(test)]
extern crate ff;
extern crate pairing;
extern crate pairing_ce;
extern crate rand;
extern crate test;

@ -626,7 +626,7 @@ pub mod g1 {
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField};
use rand::{Rand, Rng};
use std::fmt;
use {CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError};
use crate::{RawEncodable, CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError};
curve_impl!(
"G1",
@ -750,6 +750,59 @@ pub mod g1 {
}
}
impl RawEncodable for G1Affine {
fn into_raw_uncompressed_le(&self) -> Self::Uncompressed {
let mut res = Self::Uncompressed::empty();
{
let mut writer = &mut res.0[..];
self.x.into_raw_repr().write_le(&mut writer).unwrap();
self.y.into_raw_repr().write_le(&mut writer).unwrap();
}
res
}
fn from_raw_uncompressed_le_unchecked(
encoded: &Self::Uncompressed,
_infinity: bool
) -> Result<Self, GroupDecodingError> {
let copy = encoded.0;
if copy.iter().all(|b| *b == 0) {
return Ok(Self::zero());
}
let mut x = FqRepr([0; 6]);
let mut y = FqRepr([0; 6]);
{
let mut reader = &copy[..];
x.read_le(&mut reader).unwrap();
y.read_le(&mut reader).unwrap();
}
Ok(G1Affine {
x: Fq::from_raw_repr(x).map_err(|e| {
GroupDecodingError::CoordinateDecodingError("x coordinate", e)
})?,
y: Fq::from_raw_repr(y).map_err(|e| {
GroupDecodingError::CoordinateDecodingError("y coordinate", e)
})?,
infinity: false,
})
}
fn from_raw_uncompressed_le(encoded: &Self::Uncompressed, _infinity: bool) -> Result<Self, GroupDecodingError> {
let affine = Self::from_raw_uncompressed_le_unchecked(&encoded, _infinity)?;
if !affine.is_on_curve() {
Err(GroupDecodingError::NotOnCurve)
} else {
Ok(affine)
}
}
}
#[derive(Copy, Clone)]
pub struct G1Compressed([u8; 48]);
@ -1261,8 +1314,8 @@ pub mod g1 {
#[test]
fn g1_curve_tests() {
::tests::curve::curve_tests::<G1>();
::tests::curve::random_transformation_tests_with_cofactor::<G1>();
crate::tests::curve::curve_tests::<G1>();
crate::tests::curve::random_transformation_tests_with_cofactor::<G1>();
}
}
@ -1272,7 +1325,7 @@ pub mod g2 {
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField};
use rand::{Rand, Rng};
use std::fmt;
use {CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError};
use crate::{CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError};
curve_impl!(
"G2",
@ -2015,8 +2068,8 @@ pub mod g2 {
#[test]
fn g2_curve_tests() {
::tests::curve::curve_tests::<G2>();
::tests::curve::random_transformation_tests_with_cofactor::<G2>();
crate::tests::curve::curve_tests::<G2>();
crate::tests::curve::random_transformation_tests_with_cofactor::<G2>();
}
}

@ -1,5 +1,5 @@
use super::fq2::Fq2;
use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr};
use ff::{Field, PrimeField, PrimeFieldRepr};
// B coefficient of BLS12-381 curve, 4.
pub const B_COEFF: Fq = Fq(FqRepr([
@ -2186,10 +2186,10 @@ fn test_fq_root_of_unity() {
#[test]
fn fq_field_tests() {
::tests::field::random_field_tests::<Fq>();
::tests::field::random_sqrt_tests::<Fq>();
::tests::field::random_frobenius_tests::<Fq, _>(Fq::char(), 13);
::tests::field::from_str_tests::<Fq>();
crate::tests::field::random_field_tests::<Fq>();
crate::tests::field::random_sqrt_tests::<Fq>();
crate::tests::field::random_frobenius_tests::<Fq, _>(Fq::char(), 13);
crate::tests::field::from_str_tests::<Fq>();
}
#[test]
@ -2205,7 +2205,7 @@ fn test_fq_ordering() {
#[test]
fn fq_repr_tests() {
::tests::repr::random_repr_tests::<FqRepr>();
crate::tests::repr::random_repr_tests::<FqRepr>();
}
#[test]

@ -184,6 +184,6 @@ fn test_fq12_mul_by_014() {
fn fq12_field_tests() {
use ff::PrimeField;
::tests::field::random_field_tests::<Fq12>();
::tests::field::random_frobenius_tests::<Fq12, _>(super::fq::Fq::char(), 13);
crate::tests::field::random_field_tests::<Fq12>();
crate::tests::field::random_frobenius_tests::<Fq12, _>(super::fq::Fq::char(), 13);
}

@ -904,7 +904,7 @@ fn test_fq2_mul_nonresidue() {
fn fq2_field_tests() {
use ff::PrimeField;
::tests::field::random_field_tests::<Fq2>();
::tests::field::random_sqrt_tests::<Fq2>();
::tests::field::random_frobenius_tests::<Fq2, _>(super::fq::Fq::char(), 13);
crate::tests::field::random_field_tests::<Fq2>();
crate::tests::field::random_sqrt_tests::<Fq2>();
crate::tests::field::random_frobenius_tests::<Fq2, _>(super::fq::Fq::char(), 13);
}

@ -369,6 +369,6 @@ fn test_fq6_mul_by_01() {
fn fq6_field_tests() {
use ff::PrimeField;
::tests::field::random_field_tests::<Fq6>();
::tests::field::random_frobenius_tests::<Fq6, _>(super::fq::Fq::char(), 13);
crate::tests::field::random_field_tests::<Fq6>();
crate::tests::field::random_frobenius_tests::<Fq6, _>(super::fq::Fq::char(), 13);
}

@ -1,4 +1,4 @@
use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr};
use ff::{Field, PrimeField, PrimeFieldRepr};
#[derive(PrimeField)]
#[PrimeFieldModulus = "52435875175126190479447740508185965837690552500527637822603658699938581184513"]
@ -974,13 +974,13 @@ fn test_fr_root_of_unity() {
#[test]
fn fr_field_tests() {
::tests::field::random_field_tests::<Fr>();
::tests::field::random_sqrt_tests::<Fr>();
::tests::field::random_frobenius_tests::<Fr, _>(Fr::char(), 13);
::tests::field::from_str_tests::<Fr>();
crate::tests::field::random_field_tests::<Fr>();
crate::tests::field::random_sqrt_tests::<Fr>();
crate::tests::field::random_frobenius_tests::<Fr, _>(Fr::char(), 13);
crate::tests::field::from_str_tests::<Fr>();
}
#[test]
fn fr_repr_tests() {
::tests::repr::random_repr_tests::<FrRepr>();
crate::tests::repr::random_repr_tests::<FrRepr>();
}

@ -365,5 +365,5 @@ impl G2Prepared {
#[test]
fn bls12_engine_tests() {
::tests::engine::engine_tests::<Bls12>();
crate::tests::engine::engine_tests::<Bls12>();
}

@ -1,5 +1,5 @@
use super::*;
use *;
use crate::*;
#[test]
fn test_pairing_result_against_relic() {

@ -190,9 +190,7 @@ macro_rules! curve_impl {
fn into_projective(&self) -> $projective {
(*self).into()
}
}
// impl Rand for $projective {
// fn rand<R: Rng>(rng: &mut R) -> Self {
// loop {
@ -630,7 +628,7 @@ pub mod g1 {
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField};
use rand::{Rand, Rng};
use std::fmt;
use {CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError};
use crate::{RawEncodable, CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError};
curve_impl!(
"G1",
@ -644,6 +642,61 @@ pub mod g1 {
G2Affine
);
impl RawEncodable for G1Affine {
fn into_raw_uncompressed_le(&self) -> Self::Uncompressed {
let mut res = Self::Uncompressed::empty();
{
let mut writer = &mut res.0[..];
self.x.into_raw_repr().write_le(&mut writer).unwrap();
self.y.into_raw_repr().write_le(&mut writer).unwrap();
}
res
}
/// Creates a point from raw encoded coordinates without checking on curve
fn from_raw_uncompressed_le_unchecked(
encoded: &Self::Uncompressed,
_infinity: bool
) -> Result<Self, GroupDecodingError> {
let copy = encoded.0;
if copy.iter().all(|b| *b == 0) {
return Ok(Self::zero());
}
let mut x = FqRepr([0; 4]);
let mut y = FqRepr([0; 4]);
{
let mut reader = &copy[..];
x.read_le(&mut reader).unwrap();
y.read_le(&mut reader).unwrap();
}
Ok(G1Affine {
x: Fq::from_raw_repr(x).map_err(|e| {
GroupDecodingError::CoordinateDecodingError("x coordinate", e)
})?,
y: Fq::from_raw_repr(y).map_err(|e| {
GroupDecodingError::CoordinateDecodingError("y coordinate", e)
})?,
infinity: false,
})
}
fn from_raw_uncompressed_le(encoded: &Self::Uncompressed, _infinity: bool) -> Result<Self, GroupDecodingError> {
let affine = Self::from_raw_uncompressed_le_unchecked(&encoded, _infinity)?;
if !affine.is_on_curve() {
Err(GroupDecodingError::NotOnCurve)
} else {
Ok(affine)
}
}
}
#[derive(Copy, Clone)]
pub struct G1Uncompressed([u8; 64]);
@ -1002,8 +1055,8 @@ pub mod g1 {
#[test]
fn g1_curve_tests() {
::tests::curve::curve_tests::<G1>();
::tests::curve::random_transformation_tests::<G1>();
crate::tests::curve::curve_tests::<G1>();
crate::tests::curve::random_transformation_tests::<G1>();
}
}
@ -1013,7 +1066,7 @@ pub mod g2 {
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField};
use rand::{Rand, Rng};
use std::fmt;
use {CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError};
use crate::{CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError};
curve_impl!(
"G2",
@ -1027,25 +1080,6 @@ pub mod g2 {
G1Affine
);
// impl Rand for G2 {
// fn rand<R: Rng>(rng: &mut R) -> Self {
// let mut r = G2::one();
// let k = Fr::rand(rng);
// r.mul_assign(k);
// return r;
// }
// }
// impl Rand for G2Affine {
// fn rand<R: Rng>(rng: &mut R) -> Self {
// let mut r = G2::one();
// let k = Fr::rand(rng);
// r.mul_assign(k);
// return r.into_affine();
// }
// }
impl Rand for G2 {
fn rand<R: Rng>(rng: &mut R) -> Self {
loop {
@ -1420,6 +1454,50 @@ pub mod g2 {
}
}
#[test]
fn test_generate_g2_in_subgroup() {
use SqrtField;
let mut x = Fq2::zero();
loop {
// y^2 = x^3 + b
let mut rhs = x;
rhs.square();
rhs.mul_assign(&x);
rhs.add_assign(&G2Affine::get_coeff_b());
if let Some(y) = rhs.sqrt() {
let mut negy = y;
negy.negate();
let p = G2Affine {
x: x,
y: if y < negy { y } else { negy },
infinity: false,
};
let g2 = p.into_projective();
let mut minus_one = Fr::one();
minus_one.negate();
let mut expected_zero = p.mul(minus_one);
expected_zero.add_assign(&g2);
if !expected_zero.is_zero() {
let p = expected_zero.into_affine();
let scaled_by_cofactor = p.scale_by_cofactor();
if scaled_by_cofactor.is_zero() {
let g2 = G2Affine::from(expected_zero);
println!("Invalid subgroup point = {}", g2);
return;
}
}
}
x.add_assign(&Fq2::one());
}
}
#[cfg(test)]
use rand::{SeedableRng, XorShiftRng};
@ -1454,8 +1532,8 @@ pub mod g2 {
#[test]
fn g2_curve_tests() {
::tests::curve::curve_tests::<G2>();
::tests::curve::random_transformation_tests::<G2>();
crate::tests::curve::curve_tests::<G2>();
crate::tests::curve::random_transformation_tests::<G2>();
}
#[test]

@ -1,5 +1,5 @@
use super::fq2::Fq2;
use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr};
use ff::{Field, PrimeField, PrimeFieldRepr};
#[derive(PrimeField)]
#[PrimeFieldModulus = "21888242871839275222246405745257275088696311157297823662689037894645226208583"]
@ -572,8 +572,8 @@ fn test_fq_sqrt_2() {
#[test]
fn fq_field_tests() {
::tests::field::random_field_tests::<Fq>();
::tests::field::random_sqrt_tests::<Fq>();
::tests::field::random_frobenius_tests::<Fq, _>(Fq::char(), 13);
::tests::field::from_str_tests::<Fq>();
crate::tests::field::random_field_tests::<Fq>();
crate::tests::field::random_sqrt_tests::<Fq>();
crate::tests::field::random_frobenius_tests::<Fq, _>(Fq::char(), 13);
crate::tests::field::from_str_tests::<Fq>();
}

@ -216,6 +216,6 @@ fn test_squaring() {
fn fq12_field_tests() {
use ff::PrimeField;
::tests::field::random_field_tests::<Fq12>();
::tests::field::random_frobenius_tests::<Fq12, _>(super::fq::Fq::char(), 13);
crate::tests::field::random_field_tests::<Fq12>();
crate::tests::field::random_frobenius_tests::<Fq12, _>(super::fq::Fq::char(), 13);
}

@ -960,7 +960,7 @@ fn test_fq2_mul_nonresidue() {
fn fq2_field_tests() {
use ff::PrimeField;
::tests::field::random_field_tests::<Fq2>();
::tests::field::random_sqrt_tests::<Fq2>();
::tests::field::random_frobenius_tests::<Fq2, _>(super::fq::Fq::char(), 13);
crate::tests::field::random_field_tests::<Fq2>();
crate::tests::field::random_sqrt_tests::<Fq2>();
crate::tests::field::random_frobenius_tests::<Fq2, _>(super::fq::Fq::char(), 13);
}

@ -395,6 +395,6 @@ fn test_fq6_mul_by_01() {
fn fq6_field_tests() {
use ff::PrimeField;
::tests::field::random_field_tests::<Fq6>();
::tests::field::random_frobenius_tests::<Fq6, _>(super::fq::Fq::char(), 13);
crate::tests::field::random_field_tests::<Fq6>();
crate::tests::field::random_frobenius_tests::<Fq6, _>(super::fq::Fq::char(), 13);
}

@ -1,4 +1,4 @@
use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr};
use ff::{Field, PrimeField, PrimeFieldRepr};
#[derive(PrimeField)]
#[PrimeFieldModulus = "21888242871839275222246405745257275088548364400416034343698204186575808495617"]
@ -28,20 +28,6 @@ fn test_fr_from_hex() {
assert_eq!(fr, Fr::zero());
}
#[test]
fn test_fr_serialize() {
assert_eq!(
serde_json::to_string(&Fr::one()).unwrap(),
r#""0x0000000000000000000000000000000000000000000000000000000000000001""#);
}
#[test]
fn test_fr_deserialize() {
let json = r#""0x0000000000000000000000000000000000000000000000000000000000000001""#;
let fr: Fr = serde_json::from_str(json).unwrap();
assert_eq!(fr, Fr::one());
}
#[test]
fn test_roots_of_unity() {
assert_eq!(Fr::S, 28);

@ -473,7 +473,7 @@ use rand::{Rand, SeedableRng, XorShiftRng};
#[test]
fn test_pairing() {
use {CurveProjective};
use crate::{CurveProjective};
let mut g1 = G1::one();
let mut g2 = G2::one();
@ -557,7 +557,7 @@ fn test_pairing() {
#[test]
fn random_bilinearity_tests() {
use {CurveProjective};
use crate::{CurveProjective};
use ff::PrimeField;
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
@ -600,5 +600,5 @@ fn random_bilinearity_tests() {
#[test]
fn bn256_engine_tests() {
::tests::engine::engine_tests::<Bn256>();
crate::tests::engine::engine_tests::<Bn256>();
}

@ -14,19 +14,12 @@
extern crate byteorder;
extern crate rand;
extern crate hex;
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[cfg(test)]
pub mod tests;
extern crate ff_ce as imported_ff;
pub extern crate ff;
pub mod ff {
pub use imported_ff::*;
}
pub use ff::*;
pub mod bls12_381;
pub mod bn256;
@ -60,7 +53,7 @@ pub trait Engine: ScalarEngine {
Pair = Self::G2Affine,
PairingResult = Self::Fqk,
>
+ From<Self::G1>;
+ From<Self::G1> + RawEncodable;
/// The projective representation of an element in G2.
type G2: CurveProjective<
@ -102,7 +95,7 @@ pub trait Engine: ScalarEngine {
>;
/// Perform final exponentiation of the result of a miller loop.
fn final_exponentiation(&Self::Fqk) -> Option<Self::Fqk>;
fn final_exponentiation(r: &Self::Fqk) -> Option<Self::Fqk>;
/// Performs a complete pairing operation `(p, q)`.
fn pairing<G1, G2>(p: G1, q: G2) -> Self::Fqk
@ -240,6 +233,18 @@ pub trait CurveAffine:
}
}
pub trait RawEncodable: CurveAffine {
/// Converts this element into its uncompressed encoding, so long as it's not
/// the point at infinity. Leaves coordinates in Montgommery form
fn into_raw_uncompressed_le(&self) -> Self::Uncompressed;
/// Creates a point from raw encoded coordinates without checking on curve
fn from_raw_uncompressed_le_unchecked(encoded: &Self::Uncompressed, infinity: bool) -> Result<Self, GroupDecodingError>;
/// Creates a point from raw encoded coordinates
fn from_raw_uncompressed_le(encoded: &Self::Uncompressed, infinity: bool) -> Result<Self, GroupDecodingError>;
}
/// An encoded elliptic curve point, which should essentially wrap a `[u8; N]`.
pub trait EncodedPoint:
Sized + Send + Sync + AsRef<[u8]> + AsMut<[u8]> + Clone + Copy + 'static

@ -1,7 +1,7 @@
use ff::Field;
use rand::{Rand, Rng, SeedableRng, XorShiftRng};
use {CurveAffine, CurveProjective, EncodedPoint};
use crate::{CurveAffine, CurveProjective, EncodedPoint};
pub fn curve_tests<G: CurveProjective>() {
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
@ -67,7 +67,7 @@ pub fn curve_tests<G: CurveProjective>() {
fn random_wnaf_tests<G: CurveProjective>() {
use ff::PrimeField;
use wnaf::*;
use crate::wnaf::*;
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);

@ -1,6 +1,6 @@
use rand::{Rand, SeedableRng, XorShiftRng};
use {CurveAffine, CurveProjective, Engine, Field, PrimeField};
use crate::{CurveAffine, CurveProjective, Engine, Field, PrimeField};
pub fn engine_tests<E: Engine>() {
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);