Initial commit

This commit is contained in:
Pratyush Mishra
2020-10-11 19:50:41 -07:00
commit 43ca2132fd
209 changed files with 18825 additions and 0 deletions

31
bls12_381/Cargo.toml Normal file
View File

@@ -0,0 +1,31 @@
[package]
name = "ark-bls12-381"
version = "0.1.0"
authors = [ "arkworks contributors" ]
description = "The BLS12-381 pairing-friendly elliptic curve"
homepage = "https://arworks.rs"
repository = "https://github.com/arkworks/algebra"
documentation = "https://docs.rs/ark-bls12-381/"
keywords = ["cryptography", "finite fields", "elliptic curves" ]
categories = ["cryptography"]
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
license = "MIT/Apache-2.0"
edition = "2018"
[dependencies]
ark-ff = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
ark-ec = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false }
[dev-dependencies]
ark-serialize = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
ark-curve-tests = { path = "../curve-tests", default-features = false }
rand = { version = "0.7", default-features = false }
rand_xorshift = "0.2"
[features]
default = [ "curve" ]
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ]
curve = [ "scalar_field" ]
scalar_field = []

1
bls12_381/LICENSE-APACHE Symbolic link
View File

@@ -0,0 +1 @@
../LICENSE-APACHE

1
bls12_381/LICENSE-MIT Symbolic link
View File

@@ -0,0 +1 @@
../LICENSE-MIT

View File

@@ -0,0 +1,82 @@
use crate::*;
use ark_ec::{
bls12,
models::{ModelParameters, SWModelParameters},
};
use ark_ff::{
biginteger::{BigInteger256, BigInteger384},
field_new, Zero,
};
pub type G1Affine = bls12::G1Affine<crate::Parameters>;
pub type G1Projective = bls12::G1Projective<crate::Parameters>;
#[derive(Clone, Default, PartialEq, Eq)]
pub struct Parameters;
impl ModelParameters for Parameters {
type BaseField = Fq;
type ScalarField = Fr;
}
impl SWModelParameters for Parameters {
/// COEFF_A = 0
const COEFF_A: Fq = field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0]));
/// COEFF_B = 4
#[rustfmt::skip]
const COEFF_B: Fq = field_new!(Fq, BigInteger384([
0xaa270000000cfff3,
0x53cc0032fc34000a,
0x478fe97a6b0a807f,
0xb1d37ebee6ba24d7,
0x8ec9733bbf78ab2f,
0x9d645513d83de7e,
]));
/// COFACTOR = (x - 1)^2 / 3 = 76329603384216526031706109802092473003
const COFACTOR: &'static [u64] = &[0x8c00aaab0000aaab, 0x396c8c005555e156];
/// COFACTOR_INV = COFACTOR^{-1} mod r
/// = 52435875175126190458656871551744051925719901746859129887267498875565241663483
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger256([
288839107172787499,
1152722415086798946,
2612889808468387987,
5124657601728438008,
]));
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
(G1_GENERATOR_X, G1_GENERATOR_Y);
#[inline(always)]
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
Self::BaseField::zero()
}
}
/// G1_GENERATOR_X =
/// 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
#[rustfmt::skip]
pub const G1_GENERATOR_X: Fq = field_new!(Fq, BigInteger384([
0x5cb38790fd530c16,
0x7817fc679976fff5,
0x154f95c7143ba1c1,
0xf0ae6acdf3d0e747,
0xedce6ecc21dbf440,
0x120177419e0bfb75,
]));
/// G1_GENERATOR_Y =
/// 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
#[rustfmt::skip]
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, BigInteger384([
0xbaac93d50ce72271,
0x8c22631a7918fd8e,
0xdd595f13570725ce,
0x51ac582950405194,
0xe1c8c3fad0059c0,
0xbbc3efc5008a26a,
]));

113
bls12_381/src/curves/g2.rs Normal file
View File

@@ -0,0 +1,113 @@
use crate::*;
use ark_ec::{
bls12,
models::{ModelParameters, SWModelParameters},
};
use ark_ff::{
biginteger::{BigInteger256, BigInteger384},
field_new, Zero,
};
pub type G2Affine = bls12::G2Affine<crate::Parameters>;
pub type G2Projective = bls12::G2Projective<crate::Parameters>;
#[derive(Clone, Default, PartialEq, Eq)]
pub struct Parameters;
impl ModelParameters for Parameters {
type BaseField = Fq2;
type ScalarField = Fr;
}
impl SWModelParameters for Parameters {
/// COEFF_A = [0, 0]
const COEFF_A: Fq2 = field_new!(Fq2, g1::Parameters::COEFF_A, g1::Parameters::COEFF_A,);
/// COEFF_B = [4, 4]
const COEFF_B: Fq2 = field_new!(Fq2, g1::Parameters::COEFF_B, g1::Parameters::COEFF_B,);
/// COFACTOR = (x^8 - 4 x^7 + 5 x^6) - (4 x^4 + 6 x^3 - 4 x^2 - 4 x + 13) //
/// 9
/// = 305502333931268344200999753193121504214466019254188142667664032982267604182971884026507427359259977847832272839041616661285803823378372096355777062779109
#[rustfmt::skip]
const COFACTOR: &'static [u64] = &[
0xcf1c38e31c7238e5,
0x1616ec6e786f0c70,
0x21537e293a6691ae,
0xa628f1cb4d9e82ef,
0xa68a205b2e5a7ddf,
0xcd91de4547085aba,
0x91d50792876a202,
0x5d543a95414e7f1,
];
/// COFACTOR_INV = COFACTOR^{-1} mod r
/// 26652489039290660355457965112010883481355318854675681319708643586776743290055
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger256([
6746407649509787816,
1304054119431494378,
2461312685643913071,
5956596749362435284,
]));
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
(G2_GENERATOR_X, G2_GENERATOR_Y);
#[inline(always)]
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
Self::BaseField::zero()
}
}
pub const G2_GENERATOR_X: Fq2 = field_new!(Fq2, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
pub const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
/// G2_GENERATOR_X_C0 =
/// 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160
#[rustfmt::skip]
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, BigInteger384([
0xf5f28fa202940a10,
0xb3f5fb2687b4961a,
0xa1a893b53e2ae580,
0x9894999d1a3caee9,
0x6f67b7631863366b,
0x58191924350bcd7,
]));
/// G2_GENERATOR_X_C1 =
/// 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758
#[rustfmt::skip]
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, BigInteger384([
0xa5a9c0759e23f606,
0xaaa0c59dbccd60c3,
0x3bb17e18e2867806,
0x1b1ab6cc8541b367,
0xc2b6ed0ef2158547,
0x11922a097360edf3,
]));
/// G2_GENERATOR_Y_C0 =
/// 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905
#[rustfmt::skip]
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, BigInteger384([
0x4c730af860494c4a,
0x597cfa1f5e369c5a,
0xe7e6856caa0a635a,
0xbbefb5e96e0d495f,
0x7d3a975f0ef25a2,
0x83fd8e7e80dae5,
]));
/// G2_GENERATOR_Y_C1 =
/// 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582
#[rustfmt::skip]
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, BigInteger384([
0xadc0fc92df64b05d,
0x18aa270a2b1461dc,
0x86adac6a3be4eba0,
0x79495c4ec93da33a,
0xe7175850a43ccaed,
0xb2bc2a163de1bf2,
]));

View File

@@ -0,0 +1,30 @@
use ark_ec::bls12::{Bls12, Bls12Parameters, TwistType};
use crate::{Fq, Fq12Parameters, Fq2Parameters, Fq6Parameters};
pub mod g1;
pub mod g2;
#[cfg(test)]
mod tests;
pub use self::{
g1::{G1Affine, G1Projective},
g2::{G2Affine, G2Projective},
};
pub type Bls12_381 = Bls12<Parameters>;
pub struct Parameters;
impl Bls12Parameters for Parameters {
const X: &'static [u64] = &[0xd201000000010000];
const X_IS_NEGATIVE: bool = true;
const TWIST_TYPE: TwistType = TwistType::M;
type Fp = Fq;
type Fp2Params = Fq2Parameters;
type Fp6Params = Fq6Parameters;
type Fp12Params = Fq12Parameters;
type G1Parameters = self::g1::Parameters;
type G2Parameters = self::g2::Parameters;
}

View File

@@ -0,0 +1,116 @@
#![allow(unused_imports)]
use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine, ProjectiveCurve};
use ark_ff::{
fields::{Field, FpParameters, PrimeField, SquareRootField},
test_rng, One, Zero,
};
use ark_serialize::CanonicalSerialize;
use core::ops::{AddAssign, MulAssign};
use rand::Rng;
use crate::{g1, g2, Bls12_381, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
use ark_curve_tests::{curves::*, groups::*};
#[test]
fn test_g1_projective_curve() {
curve_tests::<G1Projective>();
sw_tests::<g1::Parameters>();
}
#[test]
fn test_g1_projective_group() {
let mut rng = test_rng();
let a: G1Projective = rng.gen();
let b: G1Projective = rng.gen();
group_test(a, b);
}
#[test]
fn test_g1_generator() {
let generator = G1Affine::prime_subgroup_generator();
assert!(generator.is_on_curve());
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
}
#[test]
fn test_g2_projective_curve() {
curve_tests::<G2Projective>();
sw_tests::<g2::Parameters>();
}
#[test]
fn test_g2_projective_group() {
let mut rng = test_rng();
let a: G2Projective = rng.gen();
let b: G2Projective = rng.gen();
group_test(a, b);
}
#[test]
fn test_g2_generator() {
let generator = G2Affine::prime_subgroup_generator();
assert!(generator.is_on_curve());
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
}
#[test]
fn test_bilinearity() {
let mut rng = test_rng();
let a: G1Projective = rng.gen();
let b: G2Projective = rng.gen();
let s: Fr = rng.gen();
let mut sa = a;
sa.mul_assign(s);
let mut sb = b;
sb.mul_assign(s);
let ans1 = Bls12_381::pairing(sa, b);
let ans2 = Bls12_381::pairing(a, sb);
let ans3 = Bls12_381::pairing(a, b).pow(s.into_repr());
assert_eq!(ans1, ans2);
assert_eq!(ans2, ans3);
assert_ne!(ans1, Fq12::one());
assert_ne!(ans2, Fq12::one());
assert_ne!(ans3, Fq12::one());
assert_eq!(ans1.pow(Fr::characteristic()), Fq12::one());
assert_eq!(ans2.pow(Fr::characteristic()), Fq12::one());
assert_eq!(ans3.pow(Fr::characteristic()), Fq12::one());
}
#[test]
fn test_g1_generator_raw() {
let mut x = Fq::zero();
let mut i = 0;
loop {
// y^2 = x^3 + b
let mut rhs = x;
rhs.square_in_place();
rhs.mul_assign(&x);
rhs.add_assign(&g1::Parameters::COEFF_B);
if let Some(y) = rhs.sqrt() {
let p = G1Affine::new(x, if y < -y { y } else { -y }, false);
assert!(!p.is_in_correct_subgroup_assuming_on_curve());
let g1 = p.scale_by_cofactor();
if !g1.is_zero() {
assert_eq!(i, 4);
let g1 = G1Affine::from(g1);
assert!(g1.is_in_correct_subgroup_assuming_on_curve());
assert_eq!(g1, G1Affine::prime_subgroup_generator());
break;
}
}
i += 1;
x.add_assign(&Fq::one());
}
}

112
bls12_381/src/fields/fq.rs Normal file
View File

@@ -0,0 +1,112 @@
use ark_ff::{
biginteger::BigInteger384 as BigInteger,
field_new,
fields::{FftParameters, Fp384, Fp384Parameters, FpParameters},
};
pub type Fq = Fp384<FqParameters>;
pub struct FqParameters;
impl Fp384Parameters for FqParameters {}
impl FftParameters for FqParameters {
type BigInt = BigInteger;
const TWO_ADICITY: u32 = 1;
#[rustfmt::skip]
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
0x43f5fffffffcaaae,
0x32b7fff2ed47fffd,
0x7e83a49a2e99d69,
0xeca8f3318332bb7a,
0xef148d1ea0f4c069,
0x40ab3263eff0206,
]);
}
impl FpParameters for FqParameters {
/// MODULUS = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
#[rustfmt::skip]
const MODULUS: BigInteger = BigInteger([
0xb9feffffffffaaab,
0x1eabfffeb153ffff,
0x6730d2a0f6b0f624,
0x64774b84f38512bf,
0x4b1ba7b6434bacd7,
0x1a0111ea397fe69a,
]);
const MODULUS_BITS: u32 = 381;
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
const REPR_SHAVE_BITS: u32 = 3;
#[rustfmt::skip]
const R: BigInteger = BigInteger([
0x760900000002fffd,
0xebf4000bc40c0002,
0x5f48985753c758ba,
0x77ce585370525745,
0x5c071a97a256ec6d,
0x15f65ec3fa80e493,
]);
#[rustfmt::skip]
const R2: BigInteger = BigInteger([
0xf4df1f341c341746,
0xa76e6a609d104f1,
0x8de5476c4c95b6d5,
0x67eb88a9939d83c0,
0x9a793e85b519952d,
0x11988fe592cae3aa,
]);
const INV: u64 = 0x89f3fffcfffcfffd;
// GENERATOR = 2
#[rustfmt::skip]
const GENERATOR: BigInteger = BigInteger([
0x321300000006554f,
0xb93c0018d6c40005,
0x57605e0db0ddbb51,
0x8b256521ed1f9bcb,
0x6cf28d7901622c03,
0x11ebab9dbb81e28c,
]);
#[rustfmt::skip]
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
0xdcff7fffffffd555,
0xf55ffff58a9ffff,
0xb39869507b587b12,
0xb23ba5c279c2895f,
0x258dd3db21a5d66b,
0xd0088f51cbff34d,
]);
// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T
#[rustfmt::skip]
const T: BigInteger = BigInteger([
0xdcff7fffffffd555,
0xf55ffff58a9ffff,
0xb39869507b587b12,
0xb23ba5c279c2895f,
0x258dd3db21a5d66b,
0xd0088f51cbff34d,
]);
#[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
0xee7fbfffffffeaaa,
0x7aaffffac54ffff,
0xd9cc34a83dac3d89,
0xd91dd2e13ce144af,
0x92c6e9ed90d2eb35,
0x680447a8e5ff9a6,
]);
}
pub const FQ_ONE: Fq = field_new!(Fq, FqParameters::R);
pub const FQ_ZERO: Fq = field_new!(Fq, BigInteger([0, 0, 0, 0, 0, 0]));

View File

@@ -0,0 +1,193 @@
use crate::*;
use ark_ff::{biginteger::BigInteger384, field_new, fields::*};
pub type Fq12 = Fp12<Fq12Parameters>;
#[derive(Clone, Copy)]
pub struct Fq12Parameters;
impl Fp12Parameters for Fq12Parameters {
type Fp6Params = Fq6Parameters;
const NONRESIDUE: Fq6 = field_new!(Fq6, FQ2_ZERO, FQ2_ONE, FQ2_ZERO);
#[rustfmt::skip]
const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[
// Fq2(u + 1)**(((q^0) - 1) / 6)
FQ2_ONE,
// Fq2(u + 1)**(((q^1) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x7089552b319d465,
0xc6695f92b50a8313,
0x97e83cccd117228f,
0xa35baecab2dc29ee,
0x1ce393ea5daace4d,
0x8f2220fb0fb66eb,
])),
field_new!(Fq, BigInteger384([
0xb2f66aad4ce5d646,
0x5842a06bfc497cec,
0xcf4895d42599d394,
0xc11b9cba40a8e8d0,
0x2e3813cbe5a0de89,
0x110eefda88847faf,
])),
),
// Fq2(u + 1)**(((q^2) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0xecfb361b798dba3a,
0xc100ddb891865a2c,
0xec08ff1232bda8e,
0xd5c13cc6f1ca4721,
0x47222a47bf7b5c04,
0x110f184e51c5f59,
])),
FQ_ZERO,
),
// Fq2(u + 1)**(((q^3) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x3e2f585da55c9ad1,
0x4294213d86c18183,
0x382844c88b623732,
0x92ad2afd19103e18,
0x1d794e4fac7cf0b9,
0xbd592fc7d825ec8,
])),
field_new!(Fq, BigInteger384([
0x7bcfa7a25aa30fda,
0xdc17dec12a927e7c,
0x2f088dd86b4ebef1,
0xd1ca2087da74d4a7,
0x2da2596696cebc1d,
0xe2b7eedbbfd87d2,
])),
),
// Fq2(u + 1)**(((q^4) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x30f1361b798a64e8,
0xf3b8ddab7ece5a2a,
0x16a8ca3ac61577f7,
0xc26a2ff874fd029b,
0x3636b76660701c6e,
0x51ba4ab241b6160,
])),
FQ_ZERO,
),
// Fq2(u + 1)**(((q^5) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x3726c30af242c66c,
0x7c2ac1aad1b6fe70,
0xa04007fbba4b14a2,
0xef517c3266341429,
0x95ba654ed2226b,
0x2e370eccc86f7dd,
])),
field_new!(Fq, BigInteger384([
0x82d83cf50dbce43f,
0xa2813e53df9d018f,
0xc6f0caa53c65e181,
0x7525cf528d50fe95,
0x4a85ed50f4798a6b,
0x171da0fd6cf8eebd,
])),
),
// Fq2(u + 1)**(((q^6) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x43f5fffffffcaaae,
0x32b7fff2ed47fffd,
0x7e83a49a2e99d69,
0xeca8f3318332bb7a,
0xef148d1ea0f4c069,
0x40ab3263eff0206,
])),
FQ_ZERO,
),
// Fq2(u + 1)**(((q^7) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0xb2f66aad4ce5d646,
0x5842a06bfc497cec,
0xcf4895d42599d394,
0xc11b9cba40a8e8d0,
0x2e3813cbe5a0de89,
0x110eefda88847faf,
])),
field_new!(Fq, BigInteger384([
0x7089552b319d465,
0xc6695f92b50a8313,
0x97e83cccd117228f,
0xa35baecab2dc29ee,
0x1ce393ea5daace4d,
0x8f2220fb0fb66eb,
])),
),
// Fq2(u + 1)**(((q^8) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0xcd03c9e48671f071,
0x5dab22461fcda5d2,
0x587042afd3851b95,
0x8eb60ebe01bacb9e,
0x3f97d6e83d050d2,
0x18f0206554638741,
])),
FQ_ZERO,
),
// Fq2(u + 1)**(((q^9) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x7bcfa7a25aa30fda,
0xdc17dec12a927e7c,
0x2f088dd86b4ebef1,
0xd1ca2087da74d4a7,
0x2da2596696cebc1d,
0xe2b7eedbbfd87d2,
])),
field_new!(Fq, BigInteger384([
0x3e2f585da55c9ad1,
0x4294213d86c18183,
0x382844c88b623732,
0x92ad2afd19103e18,
0x1d794e4fac7cf0b9,
0xbd592fc7d825ec8,
])),
),
// Fq2(u + 1)**(((q^10) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x890dc9e4867545c3,
0x2af322533285a5d5,
0x50880866309b7e2c,
0xa20d1b8c7e881024,
0x14e4f04fe2db9068,
0x14e56d3f1564853a,
])),
FQ_ZERO,
),
// Fq2(u + 1)**(((q^11) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x82d83cf50dbce43f,
0xa2813e53df9d018f,
0xc6f0caa53c65e181,
0x7525cf528d50fe95,
0x4a85ed50f4798a6b,
0x171da0fd6cf8eebd,
])),
field_new!(Fq, BigInteger384([
0x3726c30af242c66c,
0x7c2ac1aad1b6fe70,
0xa04007fbba4b14a2,
0xef517c3266341429,
0x95ba654ed2226b,
0x2e370eccc86f7dd,
])),
),
];
}

View File

@@ -0,0 +1,73 @@
use crate::*;
use ark_ff::{biginteger::BigInteger384 as BigInteger, field_new, fields::*};
pub type Fq2 = Fp2<Fq2Parameters>;
pub struct Fq2Parameters;
impl Fp2Parameters for Fq2Parameters {
type Fp = Fq;
/// NONRESIDUE = -1
#[rustfmt::skip]
const NONRESIDUE: Fq = field_new!(Fq, BigInteger([
0x43f5fffffffcaaae,
0x32b7fff2ed47fffd,
0x7e83a49a2e99d69,
0xeca8f3318332bb7a,
0xef148d1ea0f4c069,
0x40ab3263eff0206,
]));
/// QUADRATIC_NONRESIDUE = (U + 1)
#[rustfmt::skip]
const QUADRATIC_NONRESIDUE: (Fq, Fq) = (
field_new!(Fq, BigInteger([
0x760900000002fffd,
0xebf4000bc40c0002,
0x5f48985753c758ba,
0x77ce585370525745,
0x5c071a97a256ec6d,
0x15f65ec3fa80e493,
])),
field_new!(Fq, BigInteger([
0x760900000002fffd,
0xebf4000bc40c0002,
0x5f48985753c758ba,
0x77ce585370525745,
0x5c071a97a256ec6d,
0x15f65ec3fa80e493,
])),
);
/// Coefficients for the Frobenius automorphism.
#[rustfmt::skip]
const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[
// Fq(-1)**(((q^0) - 1) / 2)
field_new!(Fq, BigInteger([
0x760900000002fffd,
0xebf4000bc40c0002,
0x5f48985753c758ba,
0x77ce585370525745,
0x5c071a97a256ec6d,
0x15f65ec3fa80e493,
])),
// Fq(-1)**(((q^1) - 1) / 2)
field_new!(Fq, BigInteger([
0x43f5fffffffcaaae,
0x32b7fff2ed47fffd,
0x7e83a49a2e99d69,
0xeca8f3318332bb7a,
0xef148d1ea0f4c069,
0x40ab3263eff0206,
])),
];
#[inline(always)]
fn mul_fp_by_nonresidue(fp: &Self::Fp) -> Self::Fp {
-(*fp)
}
}
pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO);
pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO);

194
bls12_381/src/fields/fq6.rs Normal file
View File

@@ -0,0 +1,194 @@
use crate::*;
use ark_ff::{biginteger::BigInteger384, field_new, fields::*};
pub type Fq6 = Fp6<Fq6Parameters>;
#[derive(Clone, Copy)]
pub struct Fq6Parameters;
impl Fp6Parameters for Fq6Parameters {
type Fp2Params = Fq2Parameters;
/// NONRESIDUE = (U + 1)
#[rustfmt::skip]
const NONRESIDUE: Fq2 = field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x760900000002fffd,
0xebf4000bc40c0002,
0x5f48985753c758ba,
0x77ce585370525745,
0x5c071a97a256ec6d,
0x15f65ec3fa80e493,
])),
field_new!(Fq, BigInteger384([
0x760900000002fffd,
0xebf4000bc40c0002,
0x5f48985753c758ba,
0x77ce585370525745,
0x5c071a97a256ec6d,
0x15f65ec3fa80e493,
])),
);
#[rustfmt::skip]
const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[
// Fq2(u + 1)**(((q^0) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x760900000002fffd,
0xebf4000bc40c0002,
0x5f48985753c758ba,
0x77ce585370525745,
0x5c071a97a256ec6d,
0x15f65ec3fa80e493,
])),
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
),
// Fq2(u + 1)**(((q^1) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
field_new!(Fq, BigInteger384([
0xcd03c9e48671f071,
0x5dab22461fcda5d2,
0x587042afd3851b95,
0x8eb60ebe01bacb9e,
0x3f97d6e83d050d2,
0x18f0206554638741,
])),
),
// Fq2(u + 1)**(((q^2) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x30f1361b798a64e8,
0xf3b8ddab7ece5a2a,
0x16a8ca3ac61577f7,
0xc26a2ff874fd029b,
0x3636b76660701c6e,
0x51ba4ab241b6160,
])),
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
),
// Fq2(u + 1)**(((q^3) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
field_new!(Fq, BigInteger384([
0x760900000002fffd,
0xebf4000bc40c0002,
0x5f48985753c758ba,
0x77ce585370525745,
0x5c071a97a256ec6d,
0x15f65ec3fa80e493,
])),
),
// Fq2(u + 1)**(((q^4) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0xcd03c9e48671f071,
0x5dab22461fcda5d2,
0x587042afd3851b95,
0x8eb60ebe01bacb9e,
0x3f97d6e83d050d2,
0x18f0206554638741,
])),
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
),
// Fq2(u + 1)**(((q^5) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
field_new!(Fq, BigInteger384([
0x30f1361b798a64e8,
0xf3b8ddab7ece5a2a,
0x16a8ca3ac61577f7,
0xc26a2ff874fd029b,
0x3636b76660701c6e,
0x51ba4ab241b6160,
])),
),
];
#[rustfmt::skip]
const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[
// Fq2(u + 1)**(((2q^0) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x760900000002fffd,
0xebf4000bc40c0002,
0x5f48985753c758ba,
0x77ce585370525745,
0x5c071a97a256ec6d,
0x15f65ec3fa80e493,
])),
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
),
// Fq2(u + 1)**(((2q^1) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x890dc9e4867545c3,
0x2af322533285a5d5,
0x50880866309b7e2c,
0xa20d1b8c7e881024,
0x14e4f04fe2db9068,
0x14e56d3f1564853a,
])),
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
),
// Fq2(u + 1)**(((2q^2) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0xcd03c9e48671f071,
0x5dab22461fcda5d2,
0x587042afd3851b95,
0x8eb60ebe01bacb9e,
0x3f97d6e83d050d2,
0x18f0206554638741,
])),
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
),
// Fq2(u + 1)**(((2q^3) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x43f5fffffffcaaae,
0x32b7fff2ed47fffd,
0x7e83a49a2e99d69,
0xeca8f3318332bb7a,
0xef148d1ea0f4c069,
0x40ab3263eff0206,
])),
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
),
// Fq2(u + 1)**(((2q^4) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0x30f1361b798a64e8,
0xf3b8ddab7ece5a2a,
0x16a8ca3ac61577f7,
0xc26a2ff874fd029b,
0x3636b76660701c6e,
0x51ba4ab241b6160,
])),
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
),
// Fq2(u + 1)**(((2q^5) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, BigInteger384([
0xecfb361b798dba3a,
0xc100ddb891865a2c,
0xec08ff1232bda8e,
0xd5c13cc6f1ca4721,
0x47222a47bf7b5c04,
0x110f184e51c5f59,
])),
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
),
];
/// Multiply this element by the quadratic nonresidue 1 + u.
/// Make this generic.
fn mul_fp2_by_nonresidue(fe: &Fq2) -> Fq2 {
let mut copy = *fe;
let t0 = copy.c0;
copy.c0 -= &fe.c1;
copy.c1 += &t0;
copy
}
}

View File

@@ -0,0 +1,96 @@
use ark_ff::{
biginteger::BigInteger256 as BigInteger,
fields::{FftParameters, Fp256, Fp256Parameters, FpParameters},
};
pub type Fr = Fp256<FrParameters>;
pub struct FrParameters;
impl Fp256Parameters for FrParameters {}
impl FftParameters for FrParameters {
type BigInt = BigInteger;
const TWO_ADICITY: u32 = 32;
#[rustfmt::skip]
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
0xb9b58d8c5f0e466a,
0x5b1b4c801819d7ec,
0xaf53ae352a31e64,
0x5bf3adda19e9b27b,
]);
}
impl FpParameters for FrParameters {
/// MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513
#[rustfmt::skip]
const MODULUS: BigInteger = BigInteger([
0xffffffff00000001,
0x53bda402fffe5bfe,
0x3339d80809a1d805,
0x73eda753299d7d48,
]);
const MODULUS_BITS: u32 = 255;
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
const REPR_SHAVE_BITS: u32 = 1;
#[rustfmt::skip]
const R: BigInteger = BigInteger([
0x1fffffffe,
0x5884b7fa00034802,
0x998c4fefecbc4ff5,
0x1824b159acc5056f,
]);
#[rustfmt::skip]
const R2: BigInteger = BigInteger([
0xc999e990f3f29c6d,
0x2b6cedcb87925c23,
0x5d314967254398f,
0x748d9d99f59ff11,
]);
const INV: u64 = 0xfffffffeffffffff;
//
#[rustfmt::skip]
const GENERATOR: BigInteger = BigInteger([
0xefffffff1,
0x17e363d300189c0f,
0xff9c57876f8457b0,
0x351332208fc5a8c4,
]);
#[rustfmt::skip]
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
0x7fffffff80000000,
0xa9ded2017fff2dff,
0x199cec0404d0ec02,
0x39f6d3a994cebea4,
]);
// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T
// T = (MODULUS - 1) / 2^S =
// 12208678567578594777604504606729831043093128246378069236549469339647
#[rustfmt::skip]
const T: BigInteger = BigInteger([
0xfffe5bfeffffffff,
0x9a1d80553bda402,
0x299d7d483339d808,
0x73eda753,
]);
// (T - 1) / 2 =
// 6104339283789297388802252303364915521546564123189034618274734669823
#[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
0x7fff2dff7fffffff,
0x4d0ec02a9ded201,
0x94cebea4199cec04,
0x39f6d3a9,
]);
}

View File

@@ -0,0 +1,27 @@
#[cfg(feature = "scalar_field")]
pub mod fr;
#[cfg(feature = "scalar_field")]
pub use self::fr::*;
#[cfg(feature = "curve")]
pub mod fq;
#[cfg(feature = "curve")]
pub use self::fq::*;
#[cfg(feature = "curve")]
pub mod fq2;
#[cfg(feature = "curve")]
pub use self::fq2::*;
#[cfg(feature = "curve")]
pub mod fq6;
#[cfg(feature = "curve")]
pub use self::fq6::*;
#[cfg(feature = "curve")]
pub mod fq12;
#[cfg(feature = "curve")]
pub use self::fq12::*;
#[cfg(all(feature = "curve", feature = "std", test))]
mod tests;

File diff suppressed because it is too large Load Diff

32
bls12_381/src/lib.rs Normal file
View File

@@ -0,0 +1,32 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(
warnings,
unused,
future_incompatible,
nonstandard_style,
rust_2018_idioms
)]
#![forbid(unsafe_code)]
//! This library implements the BLS12_381 curve generated by [Sean Bowe](https://electriccoin.co/blog/new-snark-curve/).
//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree 12,
//! defined over a 381-bit (prime) field.
//! This curve was intended to replace the BN254 curve to provide a higher security
//! level without incurring a large performance overhead.
//!
//!
//! Curve information:
//! * Base field: q = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
//! * Scalar field: r = 52435875175126190479447740508185965837690552500527637822603658699938581184513
//! * valuation(q - 1, 2) = 1
//! * valuation(r - 1, 2) = 32
//! * G1 curve equation: y^2 = x^3 + 4
//! * G2 curve equation: y^2 = x^3 + Fq2(4, 4)
#[cfg(feature = "curve")]
mod curves;
mod fields;
#[cfg(feature = "curve")]
pub use curves::*;
pub use fields::*;