mirror of
https://github.com/arnaucube/ark-curves-cherry-picked.git
synced 2026-01-08 23:11:29 +01:00
Initial commit
This commit is contained in:
29
bw6_761/Cargo.toml
Normal file
29
bw6_761/Cargo.toml
Normal 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
113
bw6_761/src/curves/g1.rs
Normal 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
113
bw6_761/src/curves/g2.rs
Normal 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
61
bw6_761/src/curves/mod.rs
Normal 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>;
|
||||
77
bw6_761/src/curves/tests.rs
Normal file
77
bw6_761/src/curves/tests.rs
Normal 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
175
bw6_761/src/fields/fq.rs
Normal 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
200
bw6_761/src/fields/fq3.rs
Normal 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
106
bw6_761/src/fields/fq6.rs
Normal 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
1
bw6_761/src/fields/fr.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub use ark_bls12_377::{Fq as Fr, FqParameters as FrParameters};
|
||||
14
bw6_761/src/fields/mod.rs
Normal file
14
bw6_761/src/fields/mod.rs
Normal 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;
|
||||
51
bw6_761/src/fields/tests.rs
Normal file
51
bw6_761/src/fields/tests.rs
Normal 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
34
bw6_761/src/lib.rs
Normal 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::*;
|
||||
Reference in New Issue
Block a user