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

29
bw6_761/Cargo.toml Normal file
View File

@@ -0,0 +1,29 @@
[package]
name = "ark-bw6-761"
version = "0.1.0"
authors = [ "arkworks contributors" ]
description = "The BW6-761 pairing-friendly elliptic curve"
homepage = "https://arworks.rs"
repository = "https://github.com/arkworks/algebra"
documentation = "https://docs.rs/ark-bw6-761/"
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 }
ark-bls12-377 = { path = "../bls12_377", default-features = false, features = [ "base_field" ] }
[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 = []
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std", "ark-bls12-377/std" ]

113
bw6_761/src/curves/g1.rs Normal file
View File

@@ -0,0 +1,113 @@
use crate::{Fq, Fr};
use ark_ec::{
models::{ModelParameters, SWModelParameters},
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
};
use ark_ff::{
biginteger::{BigInteger384, BigInteger768},
field_new,
};
pub type G1Affine = GroupAffine<Parameters>;
pub type G1Projective = GroupProjective<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
#[rustfmt::skip]
const COEFF_A: Fq = field_new!(Fq, BigInteger768([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]));
/// COEFF_B = -1
#[rustfmt::skip]
const COEFF_B: Fq = field_new!(Fq, BigInteger768([
0xf29a000000007ab6,
0x8c391832e000739b,
0x77738a6b6870f959,
0xbe36179047832b03,
0x84f3089e56574722,
0xc5a3614ac0b1d984,
0x5c81153f4906e9fe,
0x4d28be3a9f55c815,
0xd72c1d6f77d5f5c5,
0x73a18e069ac04458,
0xf9dfaa846595555f,
0xd0f0a60a5be58c,
]));
/// COFACTOR =
/// 26642435879335816683987677701488073867751118270052650655942102502312977592501693353047140953112195348280268661194876
#[rustfmt::skip]
const COFACTOR: &'static [u64] = &[
0x3de580000000007c,
0x832ba4061000003b,
0xc61c554757551c0c,
0xc856a0853c9db94c,
0x2c77d5ac34cb12ef,
0xad1972339049ce76,
];
/// COFACTOR^(-1) mod r =
/// 91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger384([
489703175600125849,
3883341943836920852,
1678256062427438196,
5848789333018172718,
7127967896440782320,
71512347676739162,
]));
/// 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(_elem: &Self::BaseField) -> Self::BaseField {
use ark_ff::Zero;
Self::BaseField::zero()
}
}
/// G1_GENERATOR_X =
/// 6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237
#[rustfmt::skip]
pub const G1_GENERATOR_X: Fq = field_new!(Fq, BigInteger768([
0xd6e42d7614c2d770,
0x4bb886eddbc3fc21,
0x64648b044098b4d2,
0x1a585c895a422985,
0xf1a9ac17cf8685c9,
0x352785830727aea5,
0xddf8cb12306266fe,
0x6913b4bfbc9e949a,
0x3a4b78d67ba5f6ab,
0x0f481c06a8d02a04,
0x91d4e7365c43edac,
0xf4d17cd48beca5,
]));
/// G1_GENERATOR_Y =
/// 2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099
#[rustfmt::skip]
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, BigInteger768([
0x97e805c4bd16411f,
0x870d844e1ee6dd08,
0x1eba7a37cb9eab4d,
0xd544c4df10b9889a,
0x8fe37f21a33897be,
0xe9bf99a43a0885d2,
0xd7ee0c9e273de139,
0xaa6a9ec7a38dd791,
0x8f95d3fcf765da8e,
0x42326e7db7357c99,
0xe217e407e218695f,
0x9d1eb23b7cf684,
]));

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

@@ -0,0 +1,113 @@
use crate::{Fq, Fr};
use ark_ec::{
models::{ModelParameters, SWModelParameters},
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
};
use ark_ff::{
biginteger::{BigInteger384, BigInteger768},
field_new,
};
pub type G2Affine = GroupAffine<Parameters>;
pub type G2Projective = GroupProjective<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
#[rustfmt::skip]
const COEFF_A: Fq = field_new!(Fq, BigInteger768([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]));
/// COEFF_B = 4
#[rustfmt::skip]
const COEFF_B: Fq = field_new!(Fq, BigInteger768([
0x136efffffffe16c9,
0x82cf5a6dcffe3319,
0x6458c05f1f0e0741,
0xd10ae605e52a4eda,
0x41ca591c0266e100,
0x7d0fd59c3626929f,
0x9967dc004d00c112,
0x1ccff9c033379af5,
0x9ad6ec10a23f63af,
0x5cec11251a72c235,
0x8d18b1ae789ba83e,
10403402007434220,
]));
/// COFACTOR =
/// 26642435879335816683987677701488073867751118270052650655942102502312977592501693353047140953112195348280268661194869
#[rustfmt::skip]
const COFACTOR: &'static [u64] = &[
0x3de5800000000075,
0x832ba4061000003b,
0xc61c554757551c0c,
0xc856a0853c9db94c,
0x2c77d5ac34cb12ef,
0xad1972339049ce76,
];
/// COFACTOR^(-1) mod r =
/// 214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger384([
14378295991815829998,
14586153992421458638,
9788477762582722914,
12654821707953664524,
15185631607604703397,
26723985783783076,
]));
/// 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(_elem: &Self::BaseField) -> Self::BaseField {
use ark_ff::Zero;
Self::BaseField::zero()
}
}
/// G2_GENERATOR_X =
/// 6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428
#[rustfmt::skip]
pub const G2_GENERATOR_X: Fq = field_new!(Fq, BigInteger768([
0x3d902a84cd9f4f78,
0x864e451b8a9c05dd,
0xc2b3c0d6646c5673,
0x17a7682def1ecb9d,
0xbe31a1e0fb768fe3,
0x4df125e09b92d1a6,
0x0943fce635b02ee9,
0xffc8e7ad0605e780,
0x8165c00a39341e95,
0x8ccc2ae90a0f094f,
0x73a8b8cc0ad09e0c,
0x11027e203edd9f4,
]));
/// G2_GENERATOR_Y =
/// 562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041
#[rustfmt::skip]
pub const G2_GENERATOR_Y: Fq = field_new!(Fq, BigInteger768([
0x9a159be4e773f67c,
0x6b957244aa8f4e6b,
0xa27b70c9c945a38c,
0xacb6a09fda11d0ab,
0x3abbdaa9bb6b1291,
0xdbdf642af5694c36,
0xb6360bb9560b369f,
0xac0bd1e822b8d6da,
0xfa355d17afe6945f,
0x8d6a0fc1fbcad35e,
0x72a63c7874409840,
0x114976e5b0db280,
]));

61
bw6_761/src/curves/mod.rs Normal file
View File

@@ -0,0 +1,61 @@
use crate::*;
use ark_ec::{
bw6,
bw6::{BW6Parameters, TwistType, BW6},
};
use ark_ff::biginteger::BigInteger768 as BigInteger;
pub mod g1;
pub mod g2;
#[cfg(test)]
mod tests;
#[derive(PartialEq, Eq)]
pub struct Parameters;
impl BW6Parameters for Parameters {
const X: BigInteger = BigInteger([
0x8508c00000000001,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
]);
/// `x` is positive.
const X_IS_NEGATIVE: bool = false;
// X+1
const ATE_LOOP_COUNT_1: &'static [u64] = &[0x8508c00000000002];
const ATE_LOOP_COUNT_1_IS_NEGATIVE: bool = false;
// X^3-X^2-X
const ATE_LOOP_COUNT_2: &'static [i8] = &[
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, 0,
1, 0, 0, 0, -1, 0, 0, -1, 0, 1, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, -1, 0, 1, 0, 1, 0, 0, 0, 1,
0, -1, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 1,
];
const ATE_LOOP_COUNT_2_IS_NEGATIVE: bool = false;
const TWIST_TYPE: TwistType = TwistType::M;
type Fp = Fq;
type Fp3Params = Fq3Parameters;
type Fp6Params = Fq6Parameters;
type G1Parameters = g1::Parameters;
type G2Parameters = g2::Parameters;
}
pub type BW6_761 = BW6<Parameters>;
pub type G1Affine = bw6::G1Affine<Parameters>;
pub type G1Projective = bw6::G1Projective<Parameters>;
pub type G2Affine = bw6::G2Affine<Parameters>;
pub type G2Projective = bw6::G2Projective<Parameters>;

View File

@@ -0,0 +1,77 @@
use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve};
use ark_ff::{test_rng, Field, One, PrimeField};
use rand::Rng;
use crate::*;
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 sa = a.mul(s);
let sb = b.mul(s);
let ans1 = BW6_761::pairing(sa, b);
let ans2 = BW6_761::pairing(a, sb);
let ans3 = BW6_761::pairing(a, b).pow(s.into_repr());
assert_eq!(ans1, ans2);
assert_eq!(ans2, ans3);
assert_ne!(ans1, Fq6::one());
assert_ne!(ans2, Fq6::one());
assert_ne!(ans3, Fq6::one());
assert_eq!(ans1.pow(Fr::characteristic()), Fq6::one());
assert_eq!(ans2.pow(Fr::characteristic()), Fq6::one());
assert_eq!(ans3.pow(Fr::characteristic()), Fq6::one());
}

175
bw6_761/src/fields/fq.rs Normal file
View File

@@ -0,0 +1,175 @@
use ark_ff::{
biginteger::BigInteger768 as BigInteger,
field_new,
fields::{FftParameters, Fp768, Fp768Parameters, FpParameters},
};
pub type Fq = Fp768<FqParameters>;
pub struct FqParameters;
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, 0, 0, 0, 0, 0, 0]));
impl Fp768Parameters for FqParameters {}
impl FftParameters for FqParameters {
type BigInt = BigInteger;
// The internal representation of this type is six 64-bit unsigned
// integers in little-endian order. Values are always in
// Montgomery form; i.e., Scalar(a) = aR mod p, with R=2^768.
// (MODULUS - 1) % 2^TWO_ADICITY == 0
const TWO_ADICITY: u32 = 1;
// least_quadratic_nonresidue(MODULUS) in Sage.
#[rustfmt::skip]
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
17481284903592032950u64,
10104133845767975835u64,
8607375506753517913u64,
13706168424391191299u64,
9580010308493592354u64,
14241333420363995524u64,
6665632285037357566u64,
5559902898979457045u64,
15504799981718861253u64,
8332096944629367896u64,
18005297320867222879u64,
58811391084848524u64,
]);
}
impl FpParameters for FqParameters {
/// MODULUS = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299
#[rustfmt::skip]
const MODULUS: BigInteger = BigInteger([
0xf49d00000000008b,
0xe6913e6870000082,
0x160cf8aeeaf0a437,
0x98a116c25667a8f8,
0x71dcd3dc73ebff2e,
0x8689c8ed12f9fd90,
0x03cebaff25b42304,
0x707ba638e584e919,
0x528275ef8087be41,
0xb926186a81d14688,
0xd187c94004faff3e,
0x122e824fb83ce0a
]);
const MODULUS_BITS: u32 = 761;
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
// gap to 64-bit machine word
const REPR_SHAVE_BITS: u32 = 7;
// 2^768 % MODULUS
#[rustfmt::skip]
const R: BigInteger = BigInteger([
144959613005956565u64,
6509995272855063783u64,
11428286765660613342u64,
15738672438262922740u64,
17071399330169272331u64,
13899911246788437003u64,
12055474021000362245u64,
2545351818702954755u64,
8887388221587179644u64,
5009280847225881135u64,
15539704305423854047u64,
23071597697427581u64,
]);
// R^2
#[rustfmt::skip]
const R2: BigInteger = BigInteger([
14305184132582319705u64,
8868935336694416555u64,
9196887162930508889u64,
15486798265448570248u64,
5402985275949444416u64,
10893197322525159598u64,
3204916688966998390u64,
12417238192559061753u64,
12426306557607898622u64,
1305582522441154384u64,
10311846026977660324u64,
48736111365249031u64,
]);
// (-1/MODULUS) % 2^64
const INV: u64 = 744663313386281181u64;
/// GENERATOR = 2
// primitive_root(MODULUS)
#[rustfmt::skip]
const GENERATOR: BigInteger = BigInteger([
289919226011913130u64,
13019990545710127566u64,
4409829457611675068u64,
13030600802816293865u64,
15696054586628993047u64,
9353078419867322391u64,
5664203968291172875u64,
5090703637405909511u64,
17774776443174359288u64,
10018561694451762270u64,
12632664537138156478u64,
46143195394855163u64,
]);
// (MODULUS - 1) / 2
#[rustfmt::skip]
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
0x7a4e800000000045,
0xf3489f3438000041,
0x0b067c577578521b,
0x4c508b612b33d47c,
0x38ee69ee39f5ff97,
0x4344e476897cfec8,
0x81e75d7f92da1182,
0xb83dd31c72c2748c,
0x29413af7c043df20,
0x5c930c3540e8a344,
0x68c3e4a0027d7f9f,
0x9174127dc1e705,
]);
// T =
// 3445725192157866269698394841137828771239834456268075054756895080104811711121745868043841591644705843820432283876893306725580879560277123879674755849562650799475802549689254425186271815711798397975949850214984556421382456559534149
// (MODULUS - 1) / 2 ^ TWO_ADICITY
#[rustfmt::skip]
const T: BigInteger = BigInteger([
0x7a4e800000000045,
0xf3489f3438000041,
0x0b067c577578521b,
0x4c508b612b33d47c,
0x38ee69ee39f5ff97,
0x4344e476897cfec8,
0x81e75d7f92da1182,
0xb83dd31c72c2748c,
0x29413af7c043df20,
0x5c930c3540e8a344,
0x68c3e4a0027d7f9f,
0x9174127dc1e705,
]);
// (T - 1)/2 =
// 1722862596078933134849197420568914385619917228134037527378447540052405855560872934021920795822352921910216141938446653362790439780138561939837377924781325399737901274844627212593135907855899198987974925107492278210691228279767074
#[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
0xbd27400000000022,
0xf9a44f9a1c000020,
0x05833e2bbabc290d,
0xa62845b09599ea3e,
0x1c7734f71cfaffcb,
0x21a2723b44be7f64,
0x40f3aebfc96d08c1,
0x5c1ee98e39613a46,
0x14a09d7be021ef90,
0xae49861aa07451a2,
0xb461f250013ebfcf,
0x48ba093ee0f382,
]);
}

200
bw6_761/src/fields/fq3.rs Normal file
View File

@@ -0,0 +1,200 @@
use ark_ff::{
biginteger::BigInteger768 as BigInteger,
field_new,
fields::fp3::{Fp3, Fp3Parameters},
};
use crate::Fq;
pub type Fq3 = Fp3<Fq3Parameters>;
pub struct Fq3Parameters;
impl Fp3Parameters for Fq3Parameters {
type Fp = Fq;
/// NONRESIDUE = -4
// Fq3 = Fq[u]/u^3+4
#[rustfmt::skip]
const NONRESIDUE: Fq = field_new!(Fq, BigInteger([
0xe12e00000001e9c2,
0x63c1e3faa001cd69,
0xb1b4384fcbe29cf6,
0xc79630bc713d5a1d,
0x30127ac071851e2d,
0x0979f350dcd36af1,
0x6a66defed8b361f2,
0x53abac78b24d4e23,
0xb7ab89dede485a92,
0x5c3a0745675e8452,
0x446f17918c5f5700,
0xfdf24e3267fa1e,
]));
// (MODULUS^3 - 1) % 2^TWO_ADICITY == 0
const TWO_ADICITY: u32 = 1;
// (T-1)/2 with T = (MODULUS^3-1) / 2^TWO_ADICITY
#[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: &'static [u64] = &[
0xb5e7c000000a3eac,
0xf79b99dbf41cf4ab,
0xe9372b1919e55ee5,
0xbb7bbc4936c1980b,
0x7c0cb9d4399b36e1,
0x73304a5507bb1ae0,
0x92f639be8963936f,
0x4f574ac2439ba816,
0x670d9bd389dd29ef,
0x606ddf900d2124f1,
0x928fb14985ec3270,
0x6b2f2428c5f420f3,
0xac9ade29d5ab5fbe,
0xec0d0434c4005822,
0x973f10d7f3c5c108,
0x6d5e83fc81095979,
0xdac3e6e4e1647752,
0x227febf93994603e,
0x4ab8755d894167d1,
0x4fd2d3f67d8b537a,
0x33e196a4d5f4030a,
0x88b51fb72092df1a,
0xa67e5b1e8fc48316,
0xb0855eb2a00d7dab,
0xe875dd2da6751442,
0x777594a243e25676,
0x294e0f70376a85a8,
0x83f431c7988e4f18,
0x8e8fb6af3ca2f5f1,
0x7297896b4b9e90f1,
0xff38f54664d66123,
0xb5ecf80bfff41e13,
0x1662a3666bb8392a,
0x07a0968e8742d3e1,
0xf12927e564bcdfdc,
0x5de9825a0e,
];
// NONRESIDUE^T % q
#[rustfmt::skip]
const QUADRATIC_NONRESIDUE_TO_T: (Fq, Fq, Fq) = (
field_new!(Fq, BigInteger([
0xf29a000000007ab6,
0x8c391832e000739b,
0x77738a6b6870f959,
0xbe36179047832b03,
0x84f3089e56574722,
0xc5a3614ac0b1d984,
0x5c81153f4906e9fe,
0x4d28be3a9f55c815,
0xd72c1d6f77d5f5c5,
0x73a18e069ac04458,
0xf9dfaa846595555f,
0xd0f0a60a5be58c,
])),
field_new!(Fq, BigInteger([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])),
field_new!(Fq, BigInteger([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])),
);
// NQR ^ (MODULUS^i - 1)/3, i=0,1,2 with NQR = u = (0,1,0)
#[rustfmt::skip]
const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[
field_new!(Fq, BigInteger([
0x0202ffffffff85d5,
0x5a5826358fff8ce7,
0x9e996e43827faade,
0xda6aff320ee47df4,
0xece9cb3e1d94b80b,
0xc0e667a25248240b,
0xa74da5bfdcad3905,
0x2352e7fe462f2103,
0x7b56588008b1c87c,
0x45848a63e711022f,
0xd7a81ebb9f65a9df,
0x51f77ef127e87d,
])),
field_new!(Fq, BigInteger([
0x7f96b51bd840c549,
0xd59782096496171f,
0x49b046fd9ce14bbc,
0x4b6163bba7527a56,
0xef6c92fb771d59f1,
0x0425bedbac1dfdc7,
0xd3ac39de759c0ffd,
0x9f43ed0e063a81d0,
0x5bd7d20b4f9a3ce2,
0x0411f03c36cf5c3c,
0x2d658fd49661c472,
0x1100249ae760b93,
])),
field_new!(Fq, BigInteger([
0x67a04ae427bfb5f8,
0x9d32d491eb6a5cff,
0x43d03c1cb68051d4,
0x0b75ca96f69859a5,
0x0763497f5325ec60,
0x48076b5c278dd94d,
0x8ca3965ff91efd06,
0x1e6077657ea02f5d,
0xcdd6c153a8c37724,
0x28b5b634e5c22ea4,
0x9e01e3efd42e902c,
0xe3d6815769a804,
])),
];
// NQR ^ (2*MODULUS^i - 2)/3, i=0,1,2 with NQR = u = (0,1,0)
#[rustfmt::skip]
const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[
field_new!(Fq, BigInteger([
0x0202ffffffff85d5,
0x5a5826358fff8ce7,
0x9e996e43827faade,
0xda6aff320ee47df4,
0xece9cb3e1d94b80b,
0xc0e667a25248240b,
0xa74da5bfdcad3905,
0x2352e7fe462f2103,
0x7b56588008b1c87c,
0x45848a63e711022f,
0xd7a81ebb9f65a9df,
0x51f77ef127e87d,
])),
field_new!(Fq, BigInteger([
0x67a04ae427bfb5f8,
0x9d32d491eb6a5cff,
0x43d03c1cb68051d4,
0x0b75ca96f69859a5,
0x0763497f5325ec60,
0x48076b5c278dd94d,
0x8ca3965ff91efd06,
0x1e6077657ea02f5d,
0xcdd6c153a8c37724,
0x28b5b634e5c22ea4,
0x9e01e3efd42e902c,
0xe3d6815769a804,
])),
field_new!(Fq, BigInteger([
0x7f96b51bd840c549,
0xd59782096496171f,
0x49b046fd9ce14bbc,
0x4b6163bba7527a56,
0xef6c92fb771d59f1,
0x0425bedbac1dfdc7,
0xd3ac39de759c0ffd,
0x9f43ed0e063a81d0,
0x5bd7d20b4f9a3ce2,
0x0411f03c36cf5c3c,
0x2d658fd49661c472,
0x1100249ae760b93,
])),
];
#[inline(always)]
fn mul_fp_by_nonresidue(fe: &Self::Fp) -> Self::Fp {
let original = -(*fe);
let double = original + &original;
double + &double
}
}

106
bw6_761/src/fields/fq6.rs Normal file
View File

@@ -0,0 +1,106 @@
use crate::{Fq, Fq3, Fq3Parameters, FQ_ONE, FQ_ZERO};
use ark_ff::{
biginteger::BigInteger768 as BigInteger,
field_new,
fields::fp6_2over3::{Fp6, Fp6Parameters},
};
pub type Fq6 = Fp6<Fq6Parameters>;
pub struct Fq6Parameters;
impl Fp6Parameters for Fq6Parameters {
type Fp3Params = Fq3Parameters;
/// NONRESIDUE = (0, 1, 0)
#[rustfmt::skip]
const NONRESIDUE: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO);
#[rustfmt::skip]
const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[
field_new!(Fq, BigInteger([
0x0202ffffffff85d5,
0x5a5826358fff8ce7,
0x9e996e43827faade,
0xda6aff320ee47df4,
0xece9cb3e1d94b80b,
0xc0e667a25248240b,
0xa74da5bfdcad3905,
0x2352e7fe462f2103,
0x7b56588008b1c87c,
0x45848a63e711022f,
0xd7a81ebb9f65a9df,
0x51f77ef127e87d,
])),
field_new!(Fq, BigInteger([
0x8cfcb51bd8404a93,
0x495e69d68495a383,
0xd23cbc9234705263,
0x8d2b4c2b5fcf4f52,
0x6a798a5d20c612ce,
0x3e825d90eb6c2443,
0x772b249f2c9525fe,
0x521b2ed366e4b9bb,
0x84abb49bd7c4471d,
0x907062359c0f17e3,
0x3385e55030cc6f12,
0x3f11a3a41a2606,
])),
field_new!(Fq, BigInteger([
0x7f96b51bd840c549,
0xd59782096496171f,
0x49b046fd9ce14bbc,
0x4b6163bba7527a56,
0xef6c92fb771d59f1,
0x0425bedbac1dfdc7,
0xd3ac39de759c0ffd,
0x9f43ed0e063a81d0,
0x5bd7d20b4f9a3ce2,
0x0411f03c36cf5c3c,
0x2d658fd49661c472,
0x1100249ae760b93,
])),
field_new!(Fq, BigInteger([
0xf29a000000007ab6,
0x8c391832e000739b,
0x77738a6b6870f959,
0xbe36179047832b03,
0x84f3089e56574722,
0xc5a3614ac0b1d984,
0x5c81153f4906e9fe,
0x4d28be3a9f55c815,
0xd72c1d6f77d5f5c5,
0x73a18e069ac04458,
0xf9dfaa846595555f,
0xd0f0a60a5be58c,
])),
field_new!(Fq, BigInteger([
0x67a04ae427bfb5f8,
0x9d32d491eb6a5cff,
0x43d03c1cb68051d4,
0x0b75ca96f69859a5,
0x0763497f5325ec60,
0x48076b5c278dd94d,
0x8ca3965ff91efd06,
0x1e6077657ea02f5d,
0xcdd6c153a8c37724,
0x28b5b634e5c22ea4,
0x9e01e3efd42e902c,
0xe3d6815769a804,
])),
field_new!(Fq, BigInteger([
0x75064ae427bf3b42,
0x10f9bc5f0b69e963,
0xcc5cb1b14e0f587b,
0x4d3fb306af152ea1,
0x827040e0fccea53d,
0x82640a1166dbffc8,
0x30228120b0181307,
0xd137b92adf4a6748,
0xf6aaa3e430ed815e,
0xb514282e4b01ea4b,
0xa422396b6e993acc,
0x12e5db4d0dc277,
])),
];
}

1
bw6_761/src/fields/fr.rs Normal file
View File

@@ -0,0 +1 @@
pub use ark_bls12_377::{Fq as Fr, FqParameters as FrParameters};

14
bw6_761/src/fields/mod.rs Normal file
View File

@@ -0,0 +1,14 @@
pub mod fr;
pub use self::fr::*;
pub mod fq;
pub use self::fq::*;
pub mod fq3;
pub use self::fq3::*;
pub mod fq6;
pub use self::fq6::*;
#[cfg(test)]
mod tests;

View File

@@ -0,0 +1,51 @@
use ark_ff::{test_rng, Field, PrimeField};
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
use rand::Rng;
use crate::*;
use ark_curve_tests::fields::*;
#[test]
fn test_fr() {
let mut rng = test_rng();
let a: Fr = rng.gen();
let b: Fr = rng.gen();
field_test(a, b);
sqrt_field_test(a);
primefield_test::<Fr>();
}
#[test]
fn test_fq() {
let mut rng = test_rng();
let a: Fq = rng.gen();
let b: Fq = rng.gen();
field_test(a, b);
primefield_test::<Fq>();
sqrt_field_test(a);
let byte_size = a.serialized_size();
let (_, buffer_size) = buffer_bit_byte_size(Fq::size_in_bits());
assert_eq!(byte_size, buffer_size);
field_serialization_test::<Fq>(byte_size);
}
#[test]
fn test_fq3() {
let mut rng = test_rng();
let a: Fq3 = rng.gen();
let b: Fq3 = rng.gen();
field_test(a, b);
sqrt_field_test(a);
frobenius_test::<Fq3, _>(Fq::characteristic(), 13);
}
#[test]
fn test_fq6() {
let mut rng = test_rng();
let a: Fq6 = rng.gen();
let b: Fq6 = rng.gen();
field_test(a, b);
frobenius_test::<Fq6, _>(Fq::characteristic(), 13);
}

34
bw6_761/src/lib.rs Normal file
View File

@@ -0,0 +1,34 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(
warnings,
unused,
future_incompatible,
nonstandard_style,
rust_2018_idioms
)]
#![forbid(unsafe_code)]
//! This library implements the BW6_761 curve generated in [[EG20]](https://eprint.iacr.org/2020/351).
//! The name denotes that it is a curve generated using the Brezing--Weng method, and that
//! its embedding degree is 6.
//! The main feature of this curve is that the scalar field equals the base field of the BLS12_377 curve.
//!
//! Curve information:
//! * Base field: q = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299
//! * Scalar field: r = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
//! * valuation(q - 1, 2) = 1
//! * valuation(r - 1, 2) = 46
//!
//! G1 curve equation: y^2 = x^3 + ax + b, where
//! * a = 0,
//! * b = -1,
//!
//! G2 curve equation: y^2 = x^3 + Ax + B
//! * A = 0
//! * B = 4
mod curves;
mod fields;
pub use curves::*;
pub use fields::*;