Browse Source

Add BW6-767 curve and update BW6-761 to use the new bw6 model (#156)

* Rework bw6-761 to bw6-767

use bls12-381 instead of 377 for test imports

fix the inline comments with correct name and params


Set the right base field


Equation for base curve is y2 = x3 + 1


fill in pairing params


adapt sage scripts with correct moduli


calculate the correct cubic non residue


correct the parameter B in the curve equation


remove the specialized method for mult by nonresidue

nonresidue is two, so default will be doubling

calculate more correct parameters for fq3

`TRACE_MINUS_ONE_DIV_TWO` and `QUADRATIC_NONRESIDUE_TO_T`

compute the right fq3 & fp6 frobenious coefficients


calculate the cofactor for g1


use the g1 generator from gnark's fork


use the right g2 equation


g2 cofactor is slightly smaller than g1 cofactor


get the g2 generators from gnark's fork


update g1 and g2 curve info in the comments


fill in `COFACTOR_INV` value for g1


fill in `COFACTOR_INV` value for g2

* update module description

author information
2-adicity of the scalar field

* update changelog

* remove trailing comma

* remove todo

* 2nd loop count is x^3 - x^2 - x

* Revert "2nd loop count is x^3 - x^2 - x"

This reverts commit 2b323db3ba.

* fix comment regarding non-residue

* first loop count should be X

* 1. Generic BW6 params added to BW6-761
2. Curve specific hard part of the final exp moved from algebra

* 1. Generic BW6 params added to BW6-767
2. Miller loop params changed to the "unoptimized" version

* cargo fmt

* changelog updated

* X_MINUS_1_DIV_3 added to BW6Config

* imports fixed

---------

Co-authored-by: mmagician <marcin.gorny.94@protonmail.com>
master
swasilyev 1 year ago
committed by GitHub
parent
commit
7e58260618
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 619 additions and 1 deletions
  1. +4
    -0
      CHANGELOG.md
  2. +2
    -0
      Cargo.toml
  3. +129
    -1
      bw6_761/src/curves/mod.rs
  4. +33
    -0
      bw6_767/Cargo.toml
  5. +1
    -0
      bw6_767/LICENSE-APACHE
  6. +1
    -0
      bw6_767/LICENSE-MIT
  7. +16
    -0
      bw6_767/benches/bw6_767.rs
  8. +28
    -0
      bw6_767/scripts/base_field.sage
  9. +28
    -0
      bw6_767/scripts/scalar_field.sage
  10. +59
    -0
      bw6_767/src/curves/g1.rs
  11. +60
    -0
      bw6_767/src/curves/g2.rs
  12. +80
    -0
      bw6_767/src/curves/mod.rs
  13. +8
    -0
      bw6_767/src/curves/tests.rs
  14. +7
    -0
      bw6_767/src/fields/fq.rs
  15. +79
    -0
      bw6_767/src/fields/fq3.rs
  16. +26
    -0
      bw6_767/src/fields/fq6.rs
  17. +1
    -0
      bw6_767/src/fields/fr.rs
  18. +14
    -0
      bw6_767/src/fields/mod.rs
  19. +7
    -0
      bw6_767/src/fields/tests.rs
  20. +36
    -0
      bw6_767/src/lib.rs

+ 4
- 0
CHANGELOG.md

@ -6,8 +6,12 @@
### Features
- [\#156](https://github.com/arkworks-rs/curves/pull/156) Add the bw6-767 curve.
### Improvements
- [\#156](https://github.com/arkworks-rs/curves/pull/156) The hard part of the final exponentiation for bw6-761 relocated from arkworks/algebra.
### Bugfixes
## v0.4.0

+ 2
- 0
Cargo.toml

@ -9,6 +9,8 @@ members = [
"bw6_761",
"ed_on_bw6_761",
"bw6_767",
"cp6_782",
"ed_on_cp6_782",

+ 129
- 1
bw6_761/src/curves/mod.rs

@ -2,7 +2,9 @@ use ark_ec::{
bw6,
bw6::{BW6Config, TwistType, BW6},
};
use ark_ff::{biginteger::BigInteger768 as BigInteger, BigInt};
use ark_ff::{
biginteger::BigInteger768 as BigInteger, fp6_2over3::Fp6, BigInt, CyclotomicMultSubgroup, Field,
};
use crate::*;
@ -32,6 +34,21 @@ impl BW6Config for Config {
]);
/// `x` is positive.
const X_IS_NEGATIVE: bool = false;
// (X-1)/3
const X_MINUS_1_DIV_3: BigInteger = BigInt::new([
0x2c58400000000000,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
]);
// X+1
const ATE_LOOP_COUNT_1: &'static [u64] = &[0x8508c00000000002];
const ATE_LOOP_COUNT_1_IS_NEGATIVE: bool = false;
@ -47,11 +64,122 @@ impl BW6Config for Config {
];
const ATE_LOOP_COUNT_2_IS_NEGATIVE: bool = false;
const TWIST_TYPE: TwistType = TwistType::M;
const H_T: i64 = 13;
const H_Y: i64 = 9;
const T_MOD_R_IS_ZERO: bool = false;
type Fp = Fq;
type Fp3Config = Fq3Config;
type Fp6Config = Fq6Config;
type G1Config = g1::Config;
type G2Config = g2::Config;
fn final_exponentiation_hard_part(f: &Fp6<Self::Fp6Config>) -> Fp6<Self::Fp6Config> {
// hard_part
// From https://eprint.iacr.org/2020/351.pdf, Alg.6
#[rustfmt::skip]
// R0(x) := (-103*x^7 + 70*x^6 + 269*x^5 - 197*x^4 - 314*x^3 - 73*x^2 - 263*x - 220)
// R1(x) := (103*x^9 - 276*x^8 + 77*x^7 + 492*x^6 - 445*x^5 - 65*x^4 + 452*x^3 - 181*x^2 + 34*x + 229)
// f ^ R0(u) * (f ^ q) ^ R1(u) in a 2-NAF multi-exp fashion.
// steps 1,2,3
let f0 = *f;
let mut f0p = f0;
f0p.frobenius_map_in_place(1);
let f1 = Self::exp_by_x(&f0);
let mut f1p = f1;
f1p.frobenius_map_in_place(1);
let f2 = Self::exp_by_x(&f1);
let mut f2p = f2;
f2p.frobenius_map_in_place(1);
let f3 = Self::exp_by_x(&f2);
let mut f3p = f3;
f3p.frobenius_map_in_place(1);
let f4 = Self::exp_by_x(&f3);
let mut f4p = f4;
f4p.frobenius_map_in_place(1);
let f5 = Self::exp_by_x(&f4);
let mut f5p = f5;
f5p.frobenius_map_in_place(1);
let f6 = Self::exp_by_x(&f5);
let mut f6p = f6;
f6p.frobenius_map_in_place(1);
let f7 = Self::exp_by_x(&f6);
let mut f7p = f7;
f7p.frobenius_map_in_place(1);
// step 4
let f8p = Self::exp_by_x(&f7p);
let f9p = Self::exp_by_x(&f8p);
// step 5
let mut f5p_p3 = f5p;
f5p_p3.cyclotomic_inverse_in_place();
let result1 = f3p * &f6p * &f5p_p3;
// step 6
let result2 = result1.square();
let f4_2p = f4 * &f2p;
let mut tmp1_p3 = f0 * &f1 * &f3 * &f4_2p * &f8p;
tmp1_p3.cyclotomic_inverse_in_place();
let result3 = result2 * &f5 * &f0p * &tmp1_p3;
// step 7
let result4 = result3.square();
let mut f7_p3 = f7;
f7_p3.cyclotomic_inverse_in_place();
let result5 = result4 * &f9p * &f7_p3;
// step 8
let result6 = result5.square();
let f2_4p = f2 * &f4p;
let f4_2p_5p = f4_2p * &f5p;
let mut tmp2_p3 = f2_4p * &f3 * &f3p;
tmp2_p3.cyclotomic_inverse_in_place();
let result7 = result6 * &f4_2p_5p * &f6 * &f7p * &tmp2_p3;
// step 9
let result8 = result7.square();
let mut tmp3_p3 = f0p * &f9p;
tmp3_p3.cyclotomic_inverse_in_place();
let result9 = result8 * &f0 * &f7 * &f1p * &tmp3_p3;
// step 10
let result10 = result9.square();
let f6p_8p = f6p * &f8p;
let f5_7p = f5 * &f7p;
let mut tmp4_p3 = f6p_8p;
tmp4_p3.cyclotomic_inverse_in_place();
let result11 = result10 * &f5_7p * &f2p * &tmp4_p3;
// step 11
let result12 = result11.square();
let f3_6 = f3 * &f6;
let f1_7 = f1 * &f7;
let mut tmp5_p3 = f1_7 * &f2;
tmp5_p3.cyclotomic_inverse_in_place();
let result13 = result12 * &f3_6 * &f9p * &tmp5_p3;
// step 12
let result14 = result13.square();
let mut tmp6_p3 = f4_2p * &f5_7p * &f6p_8p;
tmp6_p3.cyclotomic_inverse_in_place();
let result15 = result14 * &f0 * &f0p * &f3p * &f5p * &tmp6_p3;
// step 13
let result16 = result15.square();
let mut tmp7_p3 = f3_6;
tmp7_p3.cyclotomic_inverse_in_place();
let result17 = result16 * &f1p * &tmp7_p3;
// step 14
let result18 = result17.square();
let mut tmp8_p3 = f2_4p * &f4_2p_5p * &f9p;
tmp8_p3.cyclotomic_inverse_in_place();
let result19 = result18 * &f1_7 * &f5_7p * &f0p * &tmp8_p3;
result19
}
}
pub type BW6_761 = BW6<Config>;

+ 33
- 0
bw6_767/Cargo.toml

@ -0,0 +1,33 @@
[package]
name = "ark-bw6-767"
version = "0.4.0"
authors = [ "arkworks contributors" ]
description = "The BW6-767 pairing-friendly elliptic curve"
homepage = "https://arkworks.rs"
repository = "https://github.com/arkworks-rs/curves"
documentation = "https://docs.rs/ark-bw6-767/"
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
categories = ["cryptography"]
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
license = "MIT/Apache-2.0"
edition = "2021"
[dependencies]
ark-ff = { version= "0.4.0", default-features = false }
ark-ec = { version= "0.4.0", default-features = false }
ark-std = { version = "0.4.0", default-features = false }
ark-bls12-381 = { version = "0.4.0", path = "../bls12_381", default-features = false, features = [ "curve" ] }
[dev-dependencies]
ark-serialize = { version = "0.4.0", default-features = false }
ark-algebra-test-templates = { version = "0.4.0", default-features = false }
ark-algebra-bench-templates = { version = "0.4.0", default-features = false }
[features]
default = []
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std", "ark-bls12-381/std" ]
[[bench]]
name = "bw6_767"
path = "benches/bw6_767.rs"
harness = false

+ 1
- 0
bw6_767/LICENSE-APACHE

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

+ 1
- 0
bw6_767/LICENSE-MIT

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

+ 16
- 0
bw6_767/benches/bw6_767.rs

@ -0,0 +1,16 @@
use ark_algebra_bench_templates::*;
use ark_bw6_767::{
fq::Fq, fq3::Fq3, fq6::Fq6, fr::Fr, g1::G1Projective as G1, g2::G2Projective as G2, BW6_767,
};
bench!(
Name = "BW6_767",
Pairing = BW6_767,
G1 = G1,
G2 = G2,
ScalarField = Fr,
G1BaseField = Fq,
G2BaseField = Fq3,
TargetField = Fq6,
);

+ 28
- 0
bw6_767/scripts/base_field.sage

@ -0,0 +1,28 @@
modulus = 496597749679620867773432037469214230242402307330180853437434581099336634619713640485778675608223760166307530047354464605410050411581079376994803852937842168733702867087556948851016246640584660942486895230518034810309227309966899431
assert(modulus.is_prime())
Fp = GF(modulus)
generator = Fp(0);
for i in range(0, 20):
i = Fp(i);
neg_i = Fp(-i)
if not(i.is_primitive_root() or neg_i.is_primitive_root()):
continue
elif i.is_primitive_root():
assert(i.is_primitive_root());
print("Generator: %d" % i)
generator = i
break
else:
assert(neg_i.is_primitive_root());
print("Generator: %d" % neg_i)
generator = neg_i
break
two_adicity = valuation(modulus - 1, 2);
trace = (modulus - 1) / 2**two_adicity;
two_adic_root_of_unity = generator^trace
print("2-adic Root of Unity: %d " % two_adic_root_of_unity)

+ 28
- 0
bw6_767/scripts/scalar_field.sage

@ -0,0 +1,28 @@
modulus = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
assert(modulus.is_prime())
Fp = GF(modulus)
generator = Fp(0);
for i in range(0, 20):
i = Fp(i);
neg_i = Fp(-i)
if not(i.is_primitive_root() or neg_i.is_primitive_root()):
continue
elif i.is_primitive_root():
assert(i.is_primitive_root());
print("Generator: %d" % i)
generator = i
break
else:
assert(neg_i.is_primitive_root());
print("Generator: %d" % neg_i)
generator = neg_i
break
two_adicity = valuation(modulus - 1, 2);
trace = (modulus - 1) / 2**two_adicity;
two_adic_root_of_unity = generator^trace
print("2-adic Root of Unity: %d " % two_adic_root_of_unity)

+ 59
- 0
bw6_767/src/curves/g1.rs

@ -0,0 +1,59 @@
use ark_ec::{
models::{short_weierstrass::SWCurveConfig, CurveConfig},
short_weierstrass::{Affine, Projective},
};
use ark_ff::{AdditiveGroup, MontFp};
use crate::{Fq, Fr};
pub type G1Affine = Affine<Config>;
pub type G1Projective = Projective<Config>;
#[derive(Clone, Default, PartialEq, Eq)]
pub struct Config;
impl CurveConfig for Config {
type BaseField = Fq;
type ScalarField = Fr;
/// COFACTOR =
/// 124074696211871689196744963988542244365937182994917792082847997279938522233341057826255097957635256182243502012934844
#[rustfmt::skip]
const COFACTOR: &'static [u64] = &[
0x9fed0006fffaaabc,
0xfae29bffb34d7c0d,
0xc51e35fba8145036,
0x58c9927410ca3a62,
0x7772b64205a0bc67,
0x26212b5cf67cecaf,
0x3,
];
/// COFACTOR^(-1) mod r =
/// 1707860402533867312515920333330662452399178546610458136488910471176197226039103222144872611321997303708365553992812
const COFACTOR_INV: Fr = MontFp!("1707860402533867312515920333330662452399178546610458136488910471176197226039103222144872611321997303708365553992812");
}
impl SWCurveConfig for Config {
/// COEFF_A = 0
const COEFF_A: Fq = Fq::ZERO;
/// COEFF_B = 1
const COEFF_B: Fq = MontFp!("1");
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
const GENERATOR: G1Affine = G1Affine::new_unchecked(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 =
/// 127687253511432941835499154999732953539969793860764514205013635996439242747457934431893570832266740963864950713809357287070846939000367049554519743864924323440810949629217677483481194663331926309250818003412838087592587472550707218
pub const G1_GENERATOR_X: Fq = MontFp!("127687253511432941835499154999732953539969793860764514205013635996439242747457934431893570832266740963864950713809357287070846939000367049554519743864924323440810949629217677483481194663331926309250818003412838087592587472550707218");
/// G1_GENERATOR_Y =
/// 415570529523170147223250223671601071129165798689804006717876771297003017718159840368703823786319144396618898691682149260290217115399107531975419658973137909698922937988511368601419289861827304905241655385035120916874417442125721204
pub const G1_GENERATOR_Y: Fq = MontFp!("415570529523170147223250223671601071129165798689804006717876771297003017718159840368703823786319144396618898691682149260290217115399107531975419658973137909698922937988511368601419289861827304905241655385035120916874417442125721204");

+ 60
- 0
bw6_767/src/curves/g2.rs

@ -0,0 +1,60 @@
use ark_ec::{
models::{short_weierstrass::SWCurveConfig, CurveConfig},
short_weierstrass::{Affine, Projective},
};
use ark_ff::{AdditiveGroup, MontFp};
use crate::{Fq, Fr};
pub type G2Affine = Affine<Config>;
pub type G2Projective = Projective<Config>;
#[derive(Clone, Default, PartialEq, Eq)]
pub struct Config;
impl CurveConfig for Config {
type BaseField = Fq;
type ScalarField = Fr;
/// COFACTOR =
/// 124074696211871689196744963988542244365937182994917792082847997279938522233341057826255097957635256182243502012934833
#[rustfmt::skip]
const COFACTOR: &'static [u64] = &[
0x9fed0006fffaaab1,
0xfae29bffb34d7c0d,
0xc51e35fba8145036,
0x58c9927410ca3a62,
0x7772b64205a0bc67,
0x26212b5cf67cecaf,
0x3,
];
/// COFACTOR^(-1) mod r =
/// 1034808299677096100380606582404873291173913026971901593767142419502683535585229274705219741821274468081298550569313
const COFACTOR_INV: Fr = MontFp!("1034808299677096100380606582404873291173913026971901593767142419502683535585229274705219741821274468081298550569313");
}
impl SWCurveConfig for Config {
/// COEFF_A = 0
const COEFF_A: Fq = Fq::ZERO;
/// COEFF_B = 4
const COEFF_B: Fq = MontFp!("3");
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
const GENERATOR: G2Affine = G2Affine::new_unchecked(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 =
/// 370611171465172359348863648443534520144617072349884185652206813771489664034831143983178049920510836078361116088420840622225267322852644540540617123958979924966938307707664543525950567252218300954395355151658118858470703533448342222
pub const G2_GENERATOR_X: Fq = MontFp!("370611171465172359348863648443534520144617072349884185652206813771489664034831143983178049920510836078361116088420840622225267322852644540540617123958979924966938307707664543525950567252218300954395355151658118858470703533448342222");
/// G2_GENERATOR_Y =
/// 455144308204607096185992716699045373884508292978508084510087807751472279103896568109582325400258900176330927780121791269969939391813736974371796892558810828460226121428602798229282770695472612961143258458821149661074127679136388603
pub const G2_GENERATOR_Y: Fq = MontFp!("455144308204607096185992716699045373884508292978508084510087807751472279103896568109582325400258900176330927780121791269969939391813736974371796892558810828460226121428602798229282770695472612961143258458821149661074127679136388603");

+ 80
- 0
bw6_767/src/curves/mod.rs

@ -0,0 +1,80 @@
use ark_ec::{
bw6,
bw6::{BW6Config, TwistType, BW6},
};
use ark_ff::{biginteger::BigInteger768 as BigInteger, BigInt};
use crate::*;
pub mod g1;
pub mod g2;
#[cfg(test)]
mod tests;
#[derive(PartialEq, Eq)]
pub struct Config;
impl BW6Config for Config {
// X is the same as in bls12_381
const X: BigInteger = BigInt::new([
0xd201000000010000,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
]);
const X_IS_NEGATIVE: bool = true;
// [(-X)+1]/3, since X < 0
const X_MINUS_1_DIV_3: BigInteger = BigInt::new([
0x460055555555aaab,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
]);
// -[(-X)+1]
const ATE_LOOP_COUNT_1: &'static [u64] = &[0xd20100000000ffff];
const ATE_LOOP_COUNT_1_IS_NEGATIVE: bool = true;
// -[(-X)^3-(-X)^2-(-X)] in 2-NAF
const ATE_LOOP_COUNT_2: &'static [i8] = &[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 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, -1, 0, 0,
-1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1,
0, -1, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0,
0, 0, 0, -1, 0, 1, 0, -1, 0, 1, 0, 0, 1, 0, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0,
0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 1, 0, -1, 0, 0, 1, 0, -1, 0, 1, 0, -1, 0, 1, 0, -1, 0, 0,
1, 0, 0, 1, 0, 1, 0, 1, 0, -1, 0, 1, 0, 0, 1,
];
const ATE_LOOP_COUNT_2_IS_NEGATIVE: bool = true;
const TWIST_TYPE: TwistType = TwistType::M;
const H_T: i64 = -4;
const H_Y: i64 = -6;
const T_MOD_R_IS_ZERO: bool = true;
type Fp = Fq;
type Fp3Config = Fq3Config;
type Fp6Config = Fq6Config;
type G1Config = g1::Config;
type G2Config = g2::Config;
}
pub type BW6_767 = BW6<Config>;
pub type G1Affine = bw6::G1Affine<Config>;
pub type G1Projective = bw6::G1Projective<Config>;
pub type G2Affine = bw6::G2Affine<Config>;
pub type G2Projective = bw6::G2Projective<Config>;

+ 8
- 0
bw6_767/src/curves/tests.rs

@ -0,0 +1,8 @@
use crate::*;
use ark_algebra_test_templates::*;
use ark_ff::Field;
test_group!(g1; G1Projective; sw);
test_group!(g2; G2Projective; sw);
test_group!(pairing_output; ark_ec::pairing::PairingOutput<BW6_767>; msm);
test_pairing!(pairing; crate::BW6_767);

+ 7
- 0
bw6_767/src/fields/fq.rs

@ -0,0 +1,7 @@
use ark_ff::fields::{Fp768, MontBackend, MontConfig};
#[derive(MontConfig)]
#[modulus = "496597749679620867773432037469214230242402307330180853437434581099336634619713640485778675608223760166307530047354464605410050411581079376994803852937842168733702867087556948851016246640584660942486895230518034810309227309966899431"]
#[generator = "3"]
pub struct FqConfig;
pub type Fq = Fp768<MontBackend<FqConfig, 12>>;

+ 79
- 0
bw6_767/src/fields/fq3.rs

@ -0,0 +1,79 @@
use ark_ff::{
fields::fp3::{Fp3, Fp3Config},
AdditiveGroup, Field, MontFp,
};
use crate::Fq;
pub type Fq3 = Fp3<Fq3Config>;
pub struct Fq3Config;
impl Fp3Config for Fq3Config {
type Fp = Fq;
/// NONRESIDUE = 3
// Fq3 = Fq\[u\]/u^3-3
const NONRESIDUE: Fq = MontFp!("3");
// (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 TRACE_MINUS_ONE_DIV_TWO: &'static [u64] = &[
0x22d18a101ce54f7d,
0x354335b0e7c460e8,
0x8014efd2b7ade04d,
0x3a3c62ab52e0a2c1,
0x79ce8405b95dd2ee,
0x24f75cbd8559a2b6,
0x2519d1267e548214,
0xea0034421965f6c8,
0xbbaa92b6aca7d134,
0x9ec0892af11e70cc,
0x06e6ab40a2fd09ec,
0xd333987617c1542a,
0xdcb52167b1f0ae0f,
0xeffa098d77a86e52,
0x9fe0d744c24ed062,
0x7df249c9ef981da1,
0x01337d754cef36fa,
0xf84c4f79c259bd8b,
0x6552e19d7dc57335,
0x9f2cab11727d9c89,
0xe5cc4da17a684263,
0xaab0632027470c14,
0xb841a2fe447f48a3,
0x6e705db09cb2c6c9,
0x51d3c82bd5de018d,
0xf0bb21ffbef26bd1,
0x294ce678e6a4c0ff,
0x130ad731f57d4c85,
0xa1e367e5eb70a85b,
0xd1b2d73d567515cd,
0x0527dddbc3e9f165,
0x1d9c04e0098344e7,
0x5db616f391729475,
0xd2834b1fae1c2c1b,
0x7cf1b8c728557851,
0x218325db61d6ebd,
];
// NONRESIDUE^T % q
const QUADRATIC_NONRESIDUE_TO_T: Fq3 = Fq3::new(Fq::ONE, Fq::ZERO, Fq::ZERO);
// NQR ^ (MODULUS^i - 1)/3, i=0,1,2 with NQR = u = (0,1,0)
const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[
Fq::ONE,
MontFp!("451452499708746243421442696394275804592767119751118962106882058158528025766103643615697202253207413006991058800455542766924935899310685166148099708594514571753800103096705086912881023032622324847956780035251378028187894066092550170"),
MontFp!("45145249970874624351989341074938425649635187579061891330552522940808608853609996870081473355016347159316471246898921838485114512270394210846704144343327596979902763990851861938135223607962336094530115195266656782121333243874349260"),
];
// NQR ^ (2*MODULUS^i - 2)/3, i=0,1,2 with NQR = u = (0,1,0)
const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[
Fq::ONE,
MontFp!("45145249970874624351989341074938425649635187579061891330552522940808608853609996870081473355016347159316471246898921838485114512270394210846704144343327596979902763990851861938135223607962336094530115195266656782121333243874349260"),
MontFp!("451452499708746243421442696394275804592767119751118962106882058158528025766103643615697202253207413006991058800455542766924935899310685166148099708594514571753800103096705086912881023032622324847956780035251378028187894066092550170"),
];
}

+ 26
- 0
bw6_767/src/fields/fq6.rs

@ -0,0 +1,26 @@
use ark_ff::{
fields::fp6_2over3::{Fp6, Fp6Config},
AdditiveGroup, Field, MontFp,
};
use crate::{Fq, Fq3, Fq3Config};
pub type Fq6 = Fp6<Fq6Config>;
pub struct Fq6Config;
impl Fp6Config for Fq6Config {
type Fp3Config = Fq3Config;
/// NONRESIDUE = (0, 1, 0)
const NONRESIDUE: Fq3 = Fq3::new(Fq::ZERO, Fq::ONE, Fq::ZERO);
const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[
Fq::ONE,
MontFp!("451452499708746243421442696394275804592767119751118962106882058158528025766103643615697202253207413006991058800455542766924935899310685166148099708594514571753800103096705086912881023032622324847956780035251378028187894066092550171"),
MontFp!("451452499708746243421442696394275804592767119751118962106882058158528025766103643615697202253207413006991058800455542766924935899310685166148099708594514571753800103096705086912881023032622324847956780035251378028187894066092550170"),
MontFp!("-1"),
MontFp!("45145249970874624351989341074938425649635187579061891330552522940808608853609996870081473355016347159316471246898921838485114512270394210846704144343327596979902763990851861938135223607962336094530115195266656782121333243874349260"),
MontFp!("45145249970874624351989341074938425649635187579061891330552522940808608853609996870081473355016347159316471246898921838485114512270394210846704144343327596979902763990851861938135223607962336094530115195266656782121333243874349261"),
];
}

+ 1
- 0
bw6_767/src/fields/fr.rs

@ -0,0 +1 @@
pub use ark_bls12_381::{Fq as Fr, FqConfig as FrConfig};

+ 14
- 0
bw6_767/src/fields/mod.rs

@ -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;

+ 7
- 0
bw6_767/src/fields/tests.rs

@ -0,0 +1,7 @@
use crate::*;
use ark_algebra_test_templates::*;
test_field!(fr; Fr; mont_prime_field);
test_field!(fq; Fq; mont_prime_field);
test_field!(fq3; Fq3);
test_field!(fq6; Fq6);

+ 36
- 0
bw6_767/src/lib.rs

@ -0,0 +1,36 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(
warnings,
unused,
future_incompatible,
nonstandard_style,
rust_2018_idioms
)]
#![forbid(unsafe_code)]
//! This module implements the BW6_767 curve generated by [\[El Housni and Guillevic\]](https://hackmd.io/@gnark/bw6_bls12381),
//! using their generic approach described in [\[HG21\]](https://eprint.iacr.org/2021/1359).
//! 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_381 curve.
//!
//! Curve information:
//! * Base field: q = 496597749679620867773432037469214230242402307330180853437434581099336634619713640485778675608223760166307530047354464605410050411581079376994803852937842168733702867087556948851016246640584660942486895230518034810309227309966899431
//! * Scalar field: r = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
//! * valuation(q - 1, 2) = 1
//! * valuation(r - 1, 2) = 1
//!
//! G1 curve equation: y^2 = x^3 + Ax + B, where
//! * A = 0,
//! * B = 1
//!
//! G2 curve equation: y^2 = x^3 + Ax + B, where
//! * A = 0
//! * B = 3
mod curves;
mod fields;
pub use curves::*;
pub use fields::*;

Loading…
Cancel
Save