Browse Source

Upgrade to work with latest `ark-ff` (#95)

Co-authored-by: Sun <huachuang20@gmail.com>
update-to-latest-arkworks
Pratyush Mishra 2 years ago
committed by GitHub
parent
commit
1551d6d76c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
231 changed files with 2826 additions and 4339 deletions
  1. +1
    -0
      Cargo.toml
  2. +28
    -0
      bls12_377/scripts/base_field.sage
  3. +28
    -0
      bls12_377/scripts/scalar_field.sage
  4. +3
    -3
      bls12_377/src/constraints/curves.rs
  5. +5
    -5
      bls12_377/src/constraints/fields.rs
  6. +2
    -1
      bls12_377/src/constraints/pairing.rs
  7. +16
    -24
      bls12_377/src/curves/g1.rs
  8. +14
    -23
      bls12_377/src/curves/g2.rs
  9. +5
    -4
      bls12_377/src/curves/mod.rs
  10. +9
    -15
      bls12_377/src/curves/tests.rs
  11. +8
    -119
      bls12_377/src/fields/fq.rs
  12. +31
    -31
      bls12_377/src/fields/fq12.rs
  13. +11
    -13
      bls12_377/src/fields/fq2.rs
  14. +31
    -32
      bls12_377/src/fields/fq6.rs
  15. +6
    -102
      bls12_377/src/fields/fr.rs
  16. +28
    -33
      bls12_377/src/fields/tests.rs
  17. +7
    -5
      bls12_377/src/lib.rs
  18. +28
    -0
      bls12_381/scripts/base_field.sage
  19. +28
    -0
      bls12_381/scripts/scalar_field.sage
  20. +16
    -14
      bls12_381/src/curves/g1.rs
  21. +33
    -34
      bls12_381/src/curves/g2.rs
  22. +4
    -4
      bls12_381/src/curves/mod.rs
  23. +6
    -13
      bls12_381/src/curves/tests.rs
  24. +8
    -113
      bls12_381/src/fields/fq.rs
  25. +43
    -42
      bls12_381/src/fields/fq12.rs
  26. +11
    -13
      bls12_381/src/fields/fq2.rs
  27. +43
    -47
      bls12_381/src/fields/fq6.rs
  28. +6
    -99
      bls12_381/src/fields/fr.rs
  29. +1
    -1
      bls12_381/src/fields/mod.rs
  30. +83
    -84
      bls12_381/src/fields/tests.rs
  31. +6
    -5
      bls12_381/src/lib.rs
  32. +28
    -0
      bn254/scripts/base_field.sage
  33. +28
    -0
      bn254/scripts/scalar_field.sage
  34. +6
    -6
      bn254/src/curves/g1.rs
  35. +35
    -23
      bn254/src/curves/g2.rs
  36. +13
    -13
      bn254/src/curves/mod.rs
  37. +8
    -11
      bn254/src/curves/tests.rs
  38. +8
    -98
      bn254/src/fields/fq.rs
  39. +88
    -46
      bn254/src/fields/fq12.rs
  40. +12
    -17
      bn254/src/fields/fq2.rs
  41. +91
    -50
      bn254/src/fields/fq6.rs
  42. +6
    -102
      bn254/src/fields/fr.rs
  43. +26
    -30
      bn254/src/fields/tests.rs
  44. +7
    -4
      bn254/src/lib.rs
  45. +28
    -0
      bw6_761/scripts/base_field.sage
  46. +28
    -0
      bw6_761/scripts/scalar_field.sage
  47. +8
    -13
      bw6_761/src/curves/g1.rs
  48. +9
    -13
      bw6_761/src/curves/g2.rs
  49. +4
    -3
      bw6_761/src/curves/mod.rs
  50. +4
    -6
      bw6_761/src/curves/tests.rs
  51. +8
    -173
      bw6_761/src/fields/fq.rs
  52. +13
    -17
      bw6_761/src/fields/fq3.rs
  53. +15
    -16
      bw6_761/src/fields/fq6.rs
  54. +1
    -1
      bw6_761/src/fields/fr.rs
  55. +5
    -7
      bw6_761/src/fields/tests.rs
  56. +4
    -3
      bw6_761/src/lib.rs
  57. +28
    -0
      cp6_782/scripts/base_field.sage
  58. +28
    -0
      cp6_782/scripts/scalar_field.sage
  59. +6
    -11
      cp6_782/src/curves/g1.rs
  60. +13
    -28
      cp6_782/src/curves/g2.rs
  61. +2
    -3
      cp6_782/src/curves/mod.rs
  62. +4
    -6
      cp6_782/src/curves/tests.rs
  63. +8
    -167
      cp6_782/src/fields/fq.rs
  64. +17
    -21
      cp6_782/src/fields/fq3.rs
  65. +15
    -16
      cp6_782/src/fields/fq6.rs
  66. +1
    -1
      cp6_782/src/fields/fr.rs
  67. +1
    -1
      cp6_782/src/fields/mod.rs
  68. +5
    -7
      cp6_782/src/fields/tests.rs
  69. +3
    -2
      cp6_782/src/lib.rs
  70. +2
    -2
      curve-benches/benches/bn254.rs
  71. +2
    -2
      curve-benches/benches/ed_on_bls12_381.rs
  72. +2
    -2
      curve-benches/benches/pallas.rs
  73. +2
    -2
      curve-benches/benches/vesta.rs
  74. +1
    -1
      curve-benches/src/macros/ec.rs
  75. +4
    -4
      curve-benches/src/macros/field.rs
  76. +11
    -13
      curve-constraint-tests/src/lib.rs
  77. +28
    -0
      ed_on_bls12_377/scripts/base_field.sage
  78. +28
    -0
      ed_on_bls12_377/scripts/scalar_field.sage
  79. +1
    -2
      ed_on_bls12_377/src/constraints/curves.rs
  80. +2
    -1
      ed_on_bls12_377/src/constraints/fields.rs
  81. +26
    -16
      ed_on_bls12_377/src/curves/mod.rs
  82. +2
    -4
      ed_on_bls12_377/src/curves/tests.rs
  83. +1
    -1
      ed_on_bls12_377/src/fields/fq.rs
  84. +6
    -82
      ed_on_bls12_377/src/fields/fr.rs
  85. +1
    -1
      ed_on_bls12_377/src/fields/mod.rs
  86. +15
    -24
      ed_on_bls12_377/src/fields/tests.rs
  87. +8
    -6
      ed_on_bls12_377/src/lib.rs
  88. +28
    -0
      ed_on_bls12_381/scripts/base_field.sage
  89. +28
    -0
      ed_on_bls12_381/scripts/scalar_field.sage
  90. +1
    -2
      ed_on_bls12_381/src/constraints/curves.rs
  91. +41
    -24
      ed_on_bls12_381/src/curves/mod.rs
  92. +1
    -2
      ed_on_bls12_381/src/curves/tests.rs
  93. +1
    -1
      ed_on_bls12_381/src/fields/fq.rs
  94. +6
    -80
      ed_on_bls12_381/src/fields/fr.rs
  95. +1
    -1
      ed_on_bls12_381/src/fields/mod.rs
  96. +24
    -66
      ed_on_bls12_381/src/fields/tests.rs
  97. +5
    -5
      ed_on_bls12_381_bandersnatch/Cargo.toml
  98. +28
    -0
      ed_on_bls12_381_bandersnatch/scripts/base_field.sage
  99. +28
    -0
      ed_on_bls12_381_bandersnatch/scripts/scalar_field.sage
  100. +2
    -1
      ed_on_bls12_381_bandersnatch/src/constraints/curves.rs

+ 1
- 0
Cargo.toml

@ -63,3 +63,4 @@ ark-ec = { git = "https://github.com/arkworks-rs/algebra" }
ark-ff = { git = "https://github.com/arkworks-rs/algebra" } ark-ff = { git = "https://github.com/arkworks-rs/algebra" }
ark-serialize = { git = "https://github.com/arkworks-rs/algebra" } ark-serialize = { git = "https://github.com/arkworks-rs/algebra" }
ark-algebra-test-templates = { git = "https://github.com/arkworks-rs/algebra" } ark-algebra-test-templates = { git = "https://github.com/arkworks-rs/algebra" }
ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std" }

+ 28
- 0
bls12_377/scripts/base_field.sage

@ -0,0 +1,28 @@
modulus = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
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
bls12_377/scripts/scalar_field.sage

@ -0,0 +1,28 @@
modulus = 8444461749428370424248824938781546531375899335154063827935233455917409239041
assert(modulus.is_prime())
Fp = GF(modulus)
generator = Fp(0);
for i in range(0, 30):
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)

+ 3
- 3
bls12_377/src/constraints/curves.rs

@ -1,11 +1,11 @@
use crate::Parameters;
use ark_ec::bls12::Bls12Parameters;
use ark_ec::ModelParameters;
use ark_ec::{bls12::Bls12Parameters, ModelParameters};
use ark_r1cs_std::{ use ark_r1cs_std::{
fields::fp::FpVar, fields::fp::FpVar,
groups::{bls12, curves::twisted_edwards::AffineVar as TEAffineVar}, groups::{bls12, curves::twisted_edwards::AffineVar as TEAffineVar},
}; };
use crate::Parameters;
/// An element of G1 in the BLS12-377 bilinear group. /// An element of G1 in the BLS12-377 bilinear group.
pub type G1Var = bls12::G1Var<Parameters>; pub type G1Var = bls12::G1Var<Parameters>;
/// An element of G2 in the BLS12-377 bilinear group. /// An element of G2 in the BLS12-377 bilinear group.

+ 5
- 5
bls12_377/src/constraints/fields.rs

@ -1,16 +1,16 @@
use crate::{Fq, Fq12Parameters, Fq2Parameters, Fq6Parameters};
use ark_r1cs_std::fields::{fp::FpVar, fp12::Fp12Var, fp2::Fp2Var, fp6_3over2::Fp6Var}; use ark_r1cs_std::fields::{fp::FpVar, fp12::Fp12Var, fp2::Fp2Var, fp6_3over2::Fp6Var};
use crate::{Fq, Fq12Config, Fq2Config, Fq6Config};
/// A variable that is the R1CS equivalent of `crate::Fq`. /// A variable that is the R1CS equivalent of `crate::Fq`.
pub type FqVar = FpVar<Fq>; pub type FqVar = FpVar<Fq>;
/// A variable that is the R1CS equivalent of `crate::Fq2`. /// A variable that is the R1CS equivalent of `crate::Fq2`.
pub type Fq2Var = Fp2Var<Fq2Parameters>;
pub type Fq2Var = Fp2Var<Fq2Config>;
/// A variable that is the R1CS equivalent of `crate::Fq6`. /// A variable that is the R1CS equivalent of `crate::Fq6`.
pub type Fq6Var = Fp6Var<Fq6Parameters>;
pub type Fq6Var = Fp6Var<Fq6Config>;
/// A variable that is the R1CS equivalent of `crate::Fq12`. /// A variable that is the R1CS equivalent of `crate::Fq12`.
pub type Fq12Var = Fp12Var<Fq12Parameters>;
pub type Fq12Var = Fp12Var<Fq12Config>;
#[test] #[test]
fn bls12_377_field_test() { fn bls12_377_field_test() {

+ 2
- 1
bls12_377/src/constraints/pairing.rs

@ -1,6 +1,7 @@
use crate::Parameters; use crate::Parameters;
/// Specifies the constraints for computing a pairing in the BLS12-377 bilinear group.
/// Specifies the constraints for computing a pairing in the BLS12-377 bilinear
/// group.
pub type PairingVar = ark_r1cs_std::pairing::bls12::PairingVar<Parameters>; pub type PairingVar = ark_r1cs_std::pairing::bls12::PairingVar<Parameters>;
#[test] #[test]

+ 16
- 24
bls12_377/src/curves/g1.rs

@ -4,7 +4,7 @@ use ark_ec::models::{
}, },
ModelParameters, MontgomeryModelParameters, SWModelParameters, TEModelParameters, ModelParameters, MontgomeryModelParameters, SWModelParameters, TEModelParameters,
}; };
use ark_ff::{field_new, Zero};
use ark_ff::{MontFp, Zero};
use core::ops::Neg; use core::ops::Neg;
use crate::{ use crate::{
@ -24,8 +24,10 @@ impl ModelParameters for Parameters {
/// COFACTOR_INV = COFACTOR^{-1} mod r /// COFACTOR_INV = COFACTOR^{-1} mod r
/// = 5285428838741532253824584287042945485047145357130994810877 /// = 5285428838741532253824584287042945485047145357130994810877
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, "5285428838741532253824584287042945485047145357130994810877");
const COFACTOR_INV: Fr = MontFp!(
Fr,
"5285428838741532253824584287042945485047145357130994810877"
);
} }
impl SWModelParameters for Parameters { impl SWModelParameters for Parameters {
@ -33,7 +35,6 @@ impl SWModelParameters for Parameters {
const COEFF_A: Fq = FQ_ZERO; const COEFF_A: Fq = FQ_ZERO;
/// COEFF_B = 1 /// COEFF_B = 1
#[rustfmt::skip]
const COEFF_B: Fq = FQ_ONE; const COEFF_B: Fq = FQ_ONE;
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
@ -54,7 +55,6 @@ pub type G1TEProjective = TEGroupProjective;
/// 1. SW -> Montgomery -> TE1 transformation: <https://en.wikipedia.org/wiki/Montgomery_curve> /// 1. SW -> Montgomery -> TE1 transformation: <https://en.wikipedia.org/wiki/Montgomery_curve>
/// 2. TE1 -> TE2 normalization (enforcing `a = -1`) /// 2. TE1 -> TE2 normalization (enforcing `a = -1`)
/// ``` sage /// ``` sage
///
/// # modulus /// # modulus
/// p = 0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001 /// p = 0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001
/// Fp = Zmod(p) /// Fp = Zmod(p)
@ -96,15 +96,13 @@ pub type G1TEProjective = TEGroupProjective;
/// TE2a = Fp(-1) /// TE2a = Fp(-1)
/// # b = -TE1d/TE1a /// # b = -TE1d/TE1a
/// TE2d = Fp(122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179) /// TE2d = Fp(122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179)
///
/// ``` /// ```
impl TEModelParameters for Parameters { impl TEModelParameters for Parameters {
/// COEFF_A = -1 /// COEFF_A = -1
const COEFF_A: Fq = field_new!(Fq, "-1");
const COEFF_A: Fq = MontFp!(Fq, "-1");
/// COEFF_D = 122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179 mod q /// COEFF_D = 122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179 mod q
#[rustfmt::skip]
const COEFF_D: Fq = field_new!(Fq, "122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179");
const COEFF_D: Fq = MontFp!(Fq, "122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179");
/// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y) /// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
@ -124,7 +122,6 @@ impl TEModelParameters for Parameters {
// It can be obtained via the following script, implementing // It can be obtained via the following script, implementing
// SW -> Montgomery transformation: <https://en.wikipedia.org/wiki/Montgomery_curve> // SW -> Montgomery transformation: <https://en.wikipedia.org/wiki/Montgomery_curve>
// ``` sage // ``` sage
//
// # modulus // # modulus
// p=0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001 // p=0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001
// Fp=Zmod(p) // Fp=Zmod(p)
@ -151,28 +148,25 @@ impl TEModelParameters for Parameters {
// ``` // ```
impl MontgomeryModelParameters for Parameters { impl MontgomeryModelParameters for Parameters {
/// COEFF_A = 228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384 /// COEFF_A = 228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384
#[rustfmt::skip]
const COEFF_A: Fq = field_new!(Fq, "228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384");
const COEFF_A: Fq = MontFp!(Fq, "228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384");
/// COEFF_B = 10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931 /// COEFF_B = 10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931
#[rustfmt::skip]
const COEFF_B: Fq = field_new!(Fq, "10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931");
const COEFF_B: Fq = MontFp!(Fq, "10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931");
type TEModelParameters = Parameters; type TEModelParameters = Parameters;
} }
/// G1_GENERATOR_X = /// G1_GENERATOR_X =
/// 81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695 /// 81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695
#[rustfmt::skip]
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695");
pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695");
/// G1_GENERATOR_Y = /// G1_GENERATOR_Y =
/// 241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030 /// 241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030
#[rustfmt::skip]
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030");
pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030");
// The generator for twisted Edward form is the same SW generator converted into the normalized TE form (TE2).
// ``` sage
// The generator for twisted Edward form is the same SW generator converted into
// the normalized TE form (TE2).
//``` sage
// # following scripts in previous section // # following scripts in previous section
// ##################################################### // #####################################################
// # Weierstrass curve generator // # Weierstrass curve generator
@ -216,10 +210,8 @@ pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "241266749859715473739788878240585
// ``` // ```
/// TE_GENERATOR_X = /// TE_GENERATOR_X =
/// 71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393 /// 71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393
#[rustfmt::skip]
pub const TE_GENERATOR_X: Fq = field_new!(Fq, "71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393");
pub const TE_GENERATOR_X: Fq = MontFp!(Fq, "71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393");
/// TE_GENERATOR_Y = /// TE_GENERATOR_Y =
/// 6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235 /// 6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235
#[rustfmt::skip]
pub const TE_GENERATOR_Y: Fq = field_new!(Fq, "6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235");
pub const TE_GENERATOR_Y: Fq = MontFp!(Fq, "6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235");

+ 14
- 23
bls12_377/src/curves/g2.rs

@ -1,5 +1,5 @@
use ark_ec::models::{ModelParameters, SWModelParameters}; use ark_ec::models::{ModelParameters, SWModelParameters};
use ark_ff::{field_new, Zero};
use ark_ff::{MontFp, QuadExt, Zero};
use crate::{fields::FQ_ZERO, g1, Fq, Fq2, Fr}; use crate::{fields::FQ_ZERO, g1, Fq, Fq2, Fr};
@ -26,17 +26,15 @@ impl ModelParameters for Parameters {
/// COFACTOR_INV = COFACTOR^{-1} mod r /// COFACTOR_INV = COFACTOR^{-1} mod r
/// = 6764900296503390671038341982857278410319949526107311149686707033187604810669 /// = 6764900296503390671038341982857278410319949526107311149686707033187604810669
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, "6764900296503390671038341982857278410319949526107311149686707033187604810669");
const COFACTOR_INV: Fr = MontFp!(
Fr,
"6764900296503390671038341982857278410319949526107311149686707033187604810669"
);
} }
impl SWModelParameters for Parameters { impl SWModelParameters for Parameters {
/// COEFF_A = [0, 0] /// COEFF_A = [0, 0]
#[rustfmt::skip]
const COEFF_A: Fq2 = field_new!(Fq2,
g1::Parameters::COEFF_A,
g1::Parameters::COEFF_A,
);
const COEFF_A: Fq2 = QuadExt!(g1::Parameters::COEFF_A, g1::Parameters::COEFF_A,);
// As per https://eprint.iacr.org/2012/072.pdf, // As per https://eprint.iacr.org/2012/072.pdf,
// this curve has b' = b/i, where b is the COEFF_B of G1, and x^6 -i is // this curve has b' = b/i, where b is the COEFF_B of G1, and x^6 -i is
@ -44,10 +42,9 @@ impl SWModelParameters for Parameters {
// In our case, i = u (App A.3, T_6). // In our case, i = u (App A.3, T_6).
/// COEFF_B = [0, /// COEFF_B = [0,
/// 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906] /// 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906]
#[rustfmt::skip]
const COEFF_B: Fq2 = field_new!(Fq2,
const COEFF_B: Fq2 = QuadExt!(
FQ_ZERO, FQ_ZERO,
field_new!(Fq, "155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906"),
MontFp!(Fq, "155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906"),
); );
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y) /// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
@ -60,27 +57,21 @@ impl SWModelParameters for Parameters {
} }
} }
#[rustfmt::skip]
pub const G2_GENERATOR_X: Fq2 = field_new!(Fq2, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
#[rustfmt::skip]
pub const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
pub const G2_GENERATOR_X: Fq2 = QuadExt!(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
pub const G2_GENERATOR_Y: Fq2 = QuadExt!(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
/// G2_GENERATOR_X_C0 = /// G2_GENERATOR_X_C0 =
/// 233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294 /// 233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294
#[rustfmt::skip]
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294");
pub const G2_GENERATOR_X_C0: Fq = MontFp!(Fq, "233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294");
/// G2_GENERATOR_X_C1 = /// G2_GENERATOR_X_C1 =
/// 140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118 /// 140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118
#[rustfmt::skip]
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118");
pub const G2_GENERATOR_X_C1: Fq = MontFp!(Fq, "140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118");
/// G2_GENERATOR_Y_C0 = /// G2_GENERATOR_Y_C0 =
/// 63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423 /// 63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423
#[rustfmt::skip]
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423");
pub const G2_GENERATOR_Y_C0: Fq = MontFp!(Fq, "63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423");
/// G2_GENERATOR_Y_C1 = /// G2_GENERATOR_Y_C1 =
/// 149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491 /// 149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491
#[rustfmt::skip]
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491");
pub const G2_GENERATOR_Y_C1: Fq = MontFp!(Fq, "149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491");

+ 5
- 4
bls12_377/src/curves/mod.rs

@ -1,9 +1,10 @@
use crate::*;
use ark_ec::{ use ark_ec::{
bls12, bls12,
bls12::{Bls12, Bls12Parameters, TwistType}, bls12::{Bls12, Bls12Parameters, TwistType},
}; };
use crate::*;
pub mod g1; pub mod g1;
pub mod g2; pub mod g2;
@ -18,9 +19,9 @@ impl Bls12Parameters for Parameters {
const X_IS_NEGATIVE: bool = false; const X_IS_NEGATIVE: bool = false;
const TWIST_TYPE: TwistType = TwistType::D; const TWIST_TYPE: TwistType = TwistType::D;
type Fp = Fq; type Fp = Fq;
type Fp2Params = Fq2Parameters;
type Fp6Params = Fq6Parameters;
type Fp12Params = Fq12Parameters;
type Fp2Config = Fq2Config;
type Fp6Config = Fq6Config;
type Fp12Config = Fq12Config;
type G1Parameters = g1::Parameters; type G1Parameters = g1::Parameters;
type G2Parameters = g2::Parameters; type G2Parameters = g2::Parameters;
} }

+ 9
- 15
bls12_377/src/curves/tests.rs

@ -1,25 +1,19 @@
#![allow(unused_imports)]
use crate::{
g1, g2, Bls12_377, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G1TEProjective, G2Affine,
G2Projective,
};
use ark_ec::{
models::SWModelParameters, short_weierstrass_jacobian, AffineCurve, PairingEngine,
ProjectiveCurve,
use ark_algebra_test_templates::{
curves::{curve_tests, edwards_tests, sw_tests},
generate_bilinearity_test, generate_g1_generator_raw_test, generate_g1_test, generate_g2_test,
groups::group_test,
msm::test_var_base_msm,
}; };
use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine};
use ark_ff::{ use ark_ff::{
fields::{Field, FpParameters, PrimeField, SquareRootField},
fields::{Field, PrimeField, SquareRootField},
One, Zero, One, Zero,
}; };
use ark_serialize::CanonicalSerialize;
use ark_std::{rand::Rng, test_rng}; use ark_std::{rand::Rng, test_rng};
use core::ops::{AddAssign, MulAssign}; use core::ops::{AddAssign, MulAssign};
use ark_algebra_test_templates::{
curves::{curve_tests, edwards_tests, sw_tests},
generate_bilinearity_test, generate_g1_generator_raw_test, generate_g1_test, generate_g2_test,
groups::group_test,
msm::test_var_base_msm,
use crate::{
g1, g2, Bls12_377, Fq, Fq12, Fr, G1Affine, G1Projective, G1TEProjective, G2Affine, G2Projective,
}; };
generate_g1_test!(bls12_377; curve_tests; sw_tests; edwards_tests; te_group_tests;); generate_g1_test!(bls12_377; curve_tests; sw_tests; edwards_tests; te_group_tests;);

+ 8
- 119
bls12_377/src/fields/fq.rs

@ -1,121 +1,10 @@
use ark_ff::{
biginteger::{BigInt, BigInteger384 as BigInteger},
fields::*,
};
use ark_ff::fields::{Fp384, MontBackend, MontConfig, MontFp};
pub type Fq = Fp384<FqParameters>;
#[derive(MontConfig)]
#[modulus = "258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177"]
#[generator = "15"]
pub struct FqConfig;
pub type Fq = Fp384<MontBackend<FqConfig, 6>>;
pub struct FqParameters;
impl Fp384Parameters for FqParameters {}
impl FftParameters for FqParameters {
type BigInt = BigInteger;
const TWO_ADICITY: u32 = 46u32;
#[rustfmt::skip]
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([
2022196864061697551u64,
17419102863309525423u64,
8564289679875062096u64,
17152078065055548215u64,
17966377291017729567u64,
68610905582439508u64,
]);
}
impl FpParameters for FqParameters {
/// MODULUS = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
#[rustfmt::skip]
const MODULUS: BigInteger = BigInt::new([
0x8508c00000000001,
0x170b5d4430000000,
0x1ef3622fba094800,
0x1a22d9f300f5138f,
0xc63b05c06ca1493b,
0x1ae3a4617c510ea,
]);
const MODULUS_BITS: u32 = 377;
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
const REPR_SHAVE_BITS: u32 = 7;
/// R = 85013442423176922659824578519796707547925331718418265885885478904210582549405549618995257669764901891699128663912
#[rustfmt::skip]
const R: BigInteger = BigInt::new([
202099033278250856u64,
5854854902718660529u64,
11492539364873682930u64,
8885205928937022213u64,
5545221690922665192u64,
39800542322357402u64,
]);
#[rustfmt::skip]
const R2: BigInteger = BigInt::new([
0xb786686c9400cd22,
0x329fcaab00431b1,
0x22a5f11162d6b46d,
0xbfdf7d03827dc3ac,
0x837e92f041790bf9,
0x6dfccb1e914b88,
]);
const INV: u64 = 9586122913090633727u64;
/// GENERATOR = -5
/// Encoded in Montgomery form, so the value here is
/// (-5 * R) % q = 92261639910053574722182574790803529333160366917737991650341130812388023949653897454961487930322210790384999596794
#[rustfmt::skip]
const GENERATOR: BigInteger = BigInt::new([
0xfc0b8000000002fa,
0x97d39cf6e000018b,
0x2072420fbfa05044,
0xcbbcbd50d97c3802,
0xbaf1ec35813f9eb,
0x9974a2c0945ad2,
]);
#[rustfmt::skip]
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0x4284600000000000,
0xb85aea218000000,
0x8f79b117dd04a400,
0x8d116cf9807a89c7,
0x631d82e03650a49d,
0xd71d230be28875,
]);
// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T
// For T coprime to 2
// T = (MODULUS - 1) // 2^S =
// 3675842578061421676390135839012792950148785745837396071634149488243117337281387659330802195819009059
#[rustfmt::skip]
const T: BigInteger = BigInt::new([
0x7510c00000021423,
0x88bee82520005c2d,
0x67cc03d44e3c7bcd,
0x1701b28524ec688b,
0xe9185f1443ab18ec,
0x6b8,
]);
// (T - 1) // 2 =
// 1837921289030710838195067919506396475074392872918698035817074744121558668640693829665401097909504529
#[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0xba88600000010a11,
0xc45f741290002e16,
0xb3e601ea271e3de6,
0xb80d94292763445,
0x748c2f8a21d58c76,
0x35c,
]);
}
#[allow(dead_code)]
pub const FQ_ONE: Fq = Fq::new(FqParameters::R);
#[allow(dead_code)]
pub const FQ_ZERO: Fq = Fq::new(BigInt::new([0, 0, 0, 0, 0, 0]));
pub const FQ_ONE: Fq = Fq::new(FqConfig::R);
pub const FQ_ZERO: Fq = MontFp!(Fq, "0");

+ 31
- 31
bls12_377/src/fields/fq12.rs

@ -1,73 +1,73 @@
use super::*;
use ark_ff::{field_new, fields::*};
use ark_ff::{fields::*, CubicExt, MontFp, QuadExt};
pub type Fq12 = Fp12<Fq12Parameters>;
use crate::*;
pub type Fq12 = Fp12<Fq12Config>;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Fq12Parameters;
pub struct Fq12Config;
impl Fp12Parameters for Fq12Parameters {
type Fp6Params = Fq6Parameters;
impl Fp12Config for Fq12Config {
type Fp6Config = Fq6Config;
const NONRESIDUE: Fq6 = field_new!(Fq6, FQ2_ZERO, FQ2_ONE, FQ2_ZERO);
const NONRESIDUE: Fq6 = CubicExt!(FQ2_ZERO, FQ2_ONE, FQ2_ZERO);
#[rustfmt::skip]
const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[ const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[
// Fp2::NONRESIDUE^(((q^0) - 1) / 6) // Fp2::NONRESIDUE^(((q^0) - 1) / 6)
field_new!(Fq2, FQ_ONE, FQ_ZERO),
QuadExt!(FQ_ONE, FQ_ZERO),
// Fp2::NONRESIDUE^(((q^1) - 1) / 6) // Fp2::NONRESIDUE^(((q^1) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "92949345220277864758624960506473182677953048909283248980960104381795901929519566951595905490535835115111760994353"),
QuadExt!(
MontFp!(Fq, "92949345220277864758624960506473182677953048909283248980960104381795901929519566951595905490535835115111760994353"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^(((q^2) - 1) / 6) // Fp2::NONRESIDUE^(((q^2) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"),
QuadExt!(
MontFp!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^(((q^3) - 1) / 6) // Fp2::NONRESIDUE^(((q^3) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499"),
QuadExt!(
MontFp!(Fq, "216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^(((q^4) - 1) / 6) // Fp2::NONRESIDUE^(((q^4) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
QuadExt!(
MontFp!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^(((q^5) - 1) / 6) // Fp2::NONRESIDUE^(((q^5) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "123516416119946754630746545296132064952198520638002533875843642777304321125866014634106496325844844051843001220146"),
QuadExt!(
MontFp!(Fq, "123516416119946754630746545296132064952198520638002533875843642777304321125866014634106496325844844051843001220146"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^(((q^6) - 1) / 6) // Fp2::NONRESIDUE^(((q^6) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "-1"),
QuadExt!(
MontFp!(Fq, "-1"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^(((q^7) - 1) / 6) // Fp2::NONRESIDUE^(((q^7) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "165715080792691229252027773188420350858440463845631411558924158284924566418821255823372982649037525009328560463824"),
QuadExt!(
MontFp!(Fq, "165715080792691229252027773188420350858440463845631411558924158284924566418821255823372982649037525009328560463824"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^(((q^8) - 1) / 6) // Fp2::NONRESIDUE^(((q^8) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
QuadExt!(
MontFp!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^(((q^9) - 1) / 6) // Fp2::NONRESIDUE^(((q^9) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "42198664672744474621281227892288285906241943207628877683080515507620245292955241189266486323192680957485559243678"),
QuadExt!(
MontFp!(Fq, "42198664672744474621281227892288285906241943207628877683080515507620245292955241189266486323192680957485559243678"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^(((q^10) - 1) / 6) // Fp2::NONRESIDUE^(((q^10) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"),
QuadExt!(
MontFp!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^(((q^11) - 1) / 6) // Fp2::NONRESIDUE^(((q^11) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "135148009893022339379906188398761468584194992116912126664040619889416147222474808140862391813728516072597320238031"),
QuadExt!(
MontFp!(Fq, "135148009893022339379906188398761468584194992116912126664040619889416147222474808140862391813728516072597320238031"),
FQ_ZERO, FQ_ZERO,
), ),
]; ];

+ 11
- 13
bls12_377/src/fields/fq2.rs

@ -1,28 +1,26 @@
use super::*;
use ark_ff::{field_new, fields::*};
use ark_ff::{fields::*, MontFp, QuadExt};
pub type Fq2 = Fp2<Fq2Parameters>;
use crate::*;
pub struct Fq2Parameters;
pub type Fq2 = Fp2<Fq2Config>;
impl Fp2Parameters for Fq2Parameters {
pub struct Fq2Config;
impl Fp2Config for Fq2Config {
type Fp = Fq; type Fp = Fq;
/// NONRESIDUE = -5 /// NONRESIDUE = -5
#[rustfmt::skip]
const NONRESIDUE: Fq = field_new!(Fq, "-5");
const NONRESIDUE: Fq = MontFp!(Fq, "-5");
/// QUADRATIC_NONRESIDUE = U /// QUADRATIC_NONRESIDUE = U
#[rustfmt::skip]
const QUADRATIC_NONRESIDUE: (Fq, Fq) = (FQ_ZERO, FQ_ONE);
const QUADRATIC_NONRESIDUE: Fq2 = QuadExt!(FQ_ZERO, FQ_ONE);
/// Coefficients for the Frobenius automorphism. /// Coefficients for the Frobenius automorphism.
#[rustfmt::skip]
const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[ const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[
// NONRESIDUE**(((q^0) - 1) / 2) // NONRESIDUE**(((q^0) - 1) / 2)
FQ_ONE, FQ_ONE,
// NONRESIDUE**(((q^1) - 1) / 2) // NONRESIDUE**(((q^1) - 1) / 2)
field_new!(Fq, "-1"),
MontFp!(Fq, "-1"),
]; ];
#[inline(always)] #[inline(always)]
@ -34,5 +32,5 @@ impl Fp2Parameters for Fq2Parameters {
} }
} }
pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO);
pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO);
pub const FQ2_ZERO: Fq2 = QuadExt!(FQ_ZERO, FQ_ZERO);
pub const FQ2_ONE: Fq2 = QuadExt!(FQ_ONE, FQ_ZERO);

+ 31
- 32
bls12_377/src/fields/fq6.rs

@ -1,69 +1,68 @@
use super::*;
use ark_ff::{field_new, fields::*};
use ark_ff::{fields::*, MontFp, QuadExt};
pub type Fq6 = Fp6<Fq6Parameters>;
use crate::*;
pub type Fq6 = Fp6<Fq6Config>;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Fq6Parameters;
pub struct Fq6Config;
impl Fp6Parameters for Fq6Parameters {
type Fp2Params = Fq2Parameters;
impl Fp6Config for Fq6Config {
type Fp2Config = Fq2Config;
/// NONRESIDUE = U /// NONRESIDUE = U
#[rustfmt::skip]
const NONRESIDUE: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ONE);
const NONRESIDUE: Fq2 = QuadExt!(FQ_ZERO, FQ_ONE);
#[rustfmt::skip]
const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[ const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[
// Fp2::NONRESIDUE^(((q^0) - 1) / 3) // Fp2::NONRESIDUE^(((q^0) - 1) / 3)
field_new!(Fq2, FQ_ONE, FQ_ZERO),
QuadExt!(FQ_ONE, FQ_ZERO),
// Fp2::NONRESIDUE^(((q^1) - 1) / 3) // Fp2::NONRESIDUE^(((q^1) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"),
QuadExt!(
MontFp!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^(((q^2) - 1) / 3) // Fp2::NONRESIDUE^(((q^2) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
QuadExt!(
MontFp!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^(((q^3) - 1) / 3) // Fp2::NONRESIDUE^(((q^3) - 1) / 3)
field_new!(Fq2, field_new!(Fq, "-1"), FQ_ZERO),
QuadExt!(MontFp!(Fq, "-1"), FQ_ZERO),
// Fp2::NONRESIDUE^(((q^4) - 1) / 3) // Fp2::NONRESIDUE^(((q^4) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
QuadExt!(
MontFp!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^(((q^5) - 1) / 3) // Fp2::NONRESIDUE^(((q^5) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"),
QuadExt!(
MontFp!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"),
FQ_ZERO, FQ_ZERO,
), ),
]; ];
#[rustfmt::skip]
const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[ const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[
// Fp2::NONRESIDUE^((2*(q^0) - 2) / 3) // Fp2::NONRESIDUE^((2*(q^0) - 2) / 3)
field_new!(Fq2, FQ_ONE, FQ_ZERO),
QuadExt!(FQ_ONE, FQ_ZERO),
// Fp2::NONRESIDUE^((2*(q^1) - 2) / 3) // Fp2::NONRESIDUE^((2*(q^1) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
QuadExt!(
MontFp!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
FQ_ZERO FQ_ZERO
), ),
// Fp2::NONRESIDUE^((2*(q^2) - 2) / 3) // Fp2::NONRESIDUE^((2*(q^2) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
QuadExt!(
MontFp!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^((2*(q^3) - 2) / 3) // Fp2::NONRESIDUE^((2*(q^3) - 2) / 3)
field_new!(Fq2, FQ_ONE, FQ_ZERO),
QuadExt!(FQ_ONE, FQ_ZERO),
// Fp2::NONRESIDUE^((2*(q^4) - 2) / 3) // Fp2::NONRESIDUE^((2*(q^4) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
QuadExt!(
MontFp!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
FQ_ZERO, FQ_ZERO,
), ),
// Fp2::NONRESIDUE^((2*(q^5) - 2) / 3) // Fp2::NONRESIDUE^((2*(q^5) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
QuadExt!(
MontFp!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
FQ_ZERO, FQ_ZERO,
), ),
]; ];
@ -71,8 +70,8 @@ impl Fp6Parameters for Fq6Parameters {
#[inline(always)] #[inline(always)]
fn mul_fp2_by_nonresidue(fe: &Fq2) -> Fq2 { fn mul_fp2_by_nonresidue(fe: &Fq2) -> Fq2 {
// Karatsuba multiplication with constant other = u. // Karatsuba multiplication with constant other = u.
let c0 = Fq2Parameters::mul_fp_by_nonresidue(&fe.c1);
let c0 = Fq2Config::mul_fp_by_nonresidue(&fe.c1);
let c1 = fe.c0; let c1 = fe.c0;
field_new!(Fq2, c0, c1)
QuadExt!(c0, c1)
} }
} }

+ 6
- 102
bls12_377/src/fields/fr.rs

@ -1,5 +1,4 @@
//! Bls12-377 scalar field. //! Bls12-377 scalar field.
///
/// Roots of unity computed from modulus and R using this sage code: /// Roots of unity computed from modulus and R using this sage code:
/// ///
/// ```ignore /// ```ignore
@ -19,105 +18,10 @@
/// print("Gen: ", into_chunks(g * R % q, 64, 4)) /// print("Gen: ", into_chunks(g * R % q, 64, 4))
/// print("2-adic gen: ", into_chunks(g2 * R % q, 64, 4)) /// print("2-adic gen: ", into_chunks(g2 * R % q, 64, 4))
/// ``` /// ```
use ark_ff::{
biginteger::{BigInt, BigInteger256 as BigInteger},
fields::*,
};
pub type Fr = Fp256<FrParameters>;
pub struct FrParameters;
impl Fp256Parameters for FrParameters {}
impl FftParameters for FrParameters {
type BigInt = BigInteger;
const TWO_ADICITY: u32 = 47;
#[rustfmt::skip]
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([
12646347781564978760u64,
6783048705277173164u64,
268534165941069093u64,
1121515446318641358u64,
]);
}
impl FpParameters for FrParameters {
/// MODULUS = 8444461749428370424248824938781546531375899335154063827935233455917409239041
#[rustfmt::skip]
const MODULUS: BigInteger = BigInt::new([
725501752471715841u64,
6461107452199829505u64,
6968279316240510977u64,
1345280370688173398u64,
]);
const MODULUS_BITS: u32 = 253;
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
const REPR_SHAVE_BITS: u32 = 3;
/// R = 6014086494747379908336260804527802945383293308637734276299549080986809532403
#[rustfmt::skip]
const R: BigInteger = BigInt::new([
9015221291577245683u64,
8239323489949974514u64,
1646089257421115374u64,
958099254763297437u64,
]);
#[rustfmt::skip]
const R2: BigInteger = BigInt::new([
2726216793283724667u64,
14712177743343147295u64,
12091039717619697043u64,
81024008013859129u64,
]);
const INV: u64 = 725501752471715839u64;
/// GENERATOR = 22
/// Encoded in Montgomery form, so the value is
/// (22 * R) % q =
/// 5642976643016801619665363617888466827793962762719196659561577942948671127251
#[rustfmt::skip]
const GENERATOR: BigInteger = BigInt::new([
2984901390528151251u64,
10561528701063790279u64,
5476750214495080041u64,
898978044469942640u64,
]);
/// (r - 1)/2 =
/// 4222230874714185212124412469390773265687949667577031913967616727958704619520
#[rustfmt::skip]
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0x8508c00000000000,
0xacd53b7f68000000,
0x305a268f2e1bd800,
0x955b2af4d1652ab,
]);
// T and T_MINUS_ONE_DIV_TWO, where r - 1 = 2^s * t
// For T coprime to 2
/// t = (r - 1) / 2^s =
/// 60001509534603559531609739528203892656505753216962260608619555
#[rustfmt::skip]
const T: BigInteger = BigInt::new([
0xedfda00000021423,
0x9a3cb86f6002b354,
0xcabd34594aacc168,
0x2556,
]);
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
/// (t - 1) / 2 =
/// 30000754767301779765804869764101946328252876608481130304309777
#[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0x76fed00000010a11,
0x4d1e5c37b00159aa,
0x655e9a2ca55660b4,
0x12ab,
]);
}
#[derive(MontConfig)]
#[modulus = "8444461749428370424248824938781546531375899335154063827935233455917409239041"]
#[generator = "22"]
pub struct FrConfig;
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;

+ 28
- 33
bls12_377/src/fields/tests.rs

@ -1,9 +1,9 @@
use ark_algebra_test_templates::{
fields::*, generate_field_serialization_test, generate_field_test,
};
use ark_ff::{ use ark_ff::{
biginteger::{BigInt, BigInteger, BigInteger384}, biginteger::{BigInt, BigInteger, BigInteger384},
fields::{
fp6_3over2::Fp6Parameters, FftField, FftParameters, Field, Fp2Parameters, FpParameters,
PrimeField, SquareRootField,
},
fields::{FftField, Field, Fp2Config, Fp6Config, PrimeField, SquareRootField},
One, UniformRand, Zero, One, UniformRand, Zero,
}; };
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
@ -13,13 +13,9 @@ use core::{
ops::{AddAssign, MulAssign, SubAssign}, ops::{AddAssign, MulAssign, SubAssign},
}; };
use crate::{Fq, Fq12, Fq2, Fq2Parameters, Fq6, Fq6Parameters, FqParameters, Fr};
use ark_algebra_test_templates::{
fields::*, generate_field_serialization_test, generate_field_test,
};
use crate::{Fq, Fq12, Fq2, Fq2Config, Fq6, Fq6Config, FqConfig, Fr, FrConfig};
generate_field_test!(bls12_377; fq2; fq6; fq12;);
generate_field_test!(bls12_377; fq2; fq6; fq12; mont(6, 4); );
generate_field_serialization_test!(bls12_377; fq2; fq6; fq12;); generate_field_serialization_test!(bls12_377; fq2; fq6; fq12;);
#[test] #[test]
@ -29,14 +25,14 @@ fn test_fq_repr_from() {
#[test] #[test]
fn test_fq_repr_is_odd() { fn test_fq_repr_is_odd() {
assert!(!BigInteger384::from(0).is_odd());
assert!(BigInteger384::from(0).is_even());
assert!(BigInteger384::from(1).is_odd());
assert!(!BigInteger384::from(1).is_even());
assert!(!BigInteger384::from(324834872).is_odd());
assert!(BigInteger384::from(324834872).is_even());
assert!(BigInteger384::from(324834873).is_odd());
assert!(!BigInteger384::from(324834873).is_even());
assert!(!BigInteger384::from(0u64).is_odd());
assert!(BigInteger384::from(0u64).is_even());
assert!(BigInteger384::from(1u64).is_odd());
assert!(!BigInteger384::from(1u64).is_even());
assert!(!BigInteger384::from(324834872u64).is_odd());
assert!(BigInteger384::from(324834872u64).is_even());
assert!(BigInteger384::from(324834873u64).is_odd());
assert!(!BigInteger384::from(324834873u64).is_even());
} }
#[test] #[test]
@ -48,9 +44,9 @@ fn test_fq_repr_is_zero() {
#[test] #[test]
fn test_fq_repr_num_bits() { fn test_fq_repr_num_bits() {
let mut a = BigInteger384::from(0);
let mut a = BigInteger384::from(0u64);
assert_eq!(0, a.num_bits()); assert_eq!(0, a.num_bits());
a = BigInteger384::from(1);
a = BigInteger384::from(1u64);
for i in 1..385 { for i in 1..385 {
assert_eq!(i, a.num_bits()); assert_eq!(i, a.num_bits());
a.mul2(); a.mul2();
@ -60,15 +56,14 @@ fn test_fq_repr_num_bits() {
#[test] #[test]
fn test_fq_num_bits() { fn test_fq_num_bits() {
assert_eq!(FqParameters::MODULUS_BITS, 377);
assert_eq!(FqParameters::CAPACITY, 376);
assert_eq!(Fq::MODULUS_BIT_SIZE, 377);
} }
#[test] #[test]
fn test_fq_root_of_unity() { fn test_fq_root_of_unity() {
assert_eq!(FqParameters::TWO_ADICITY, 46);
assert_eq!(Fq::TWO_ADICITY, 46);
assert_eq!( assert_eq!(
Fq::multiplicative_generator().pow([
Fq::GENERATOR.pow([
0x7510c00000021423, 0x7510c00000021423,
0x88bee82520005c2d, 0x88bee82520005c2d,
0x67cc03d44e3c7bcd, 0x67cc03d44e3c7bcd,
@ -76,20 +71,20 @@ fn test_fq_root_of_unity() {
0xe9185f1443ab18ec, 0xe9185f1443ab18ec,
0x6b8 0x6b8
]), ]),
Fq::two_adic_root_of_unity()
Fq::TWO_ADIC_ROOT_OF_UNITY
); );
assert_eq!( assert_eq!(
Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]),
Fq::TWO_ADIC_ROOT_OF_UNITY.pow([1 << Fq::TWO_ADICITY]),
Fq::one() Fq::one()
); );
assert!(Fq::multiplicative_generator().sqrt().is_none());
assert!(Fq::GENERATOR.sqrt().is_none());
} }
#[test] #[test]
fn test_fq_ordering() { fn test_fq_ordering() {
// BigInteger384's ordering is well-tested, but we still need to make sure the // BigInteger384's ordering is well-tested, but we still need to make sure the
// Fq elements aren't being compared in Montgomery form. // Fq elements aren't being compared in Montgomery form.
for i in 0..100 {
for i in 0..100u64 {
assert!(Fq::from(BigInteger384::from(i + 1)) > Fq::from(BigInteger384::from(i))); assert!(Fq::from(BigInteger384::from(i + 1)) > Fq::from(BigInteger384::from(i)));
} }
} }
@ -102,11 +97,11 @@ fn test_fq_legendre() {
assert_eq!(Zero, Fq::zero().legendre()); assert_eq!(Zero, Fq::zero().legendre());
assert_eq!( assert_eq!(
QuadraticResidue, QuadraticResidue,
Fq::from(BigInteger384::from(4)).legendre()
Fq::from(BigInteger384::from(4u64)).legendre()
); );
assert_eq!( assert_eq!(
QuadraticNonResidue, QuadraticNonResidue,
Fq::from(BigInteger384::from(5)).legendre()
Fq::from(BigInteger384::from(5u64)).legendre()
); );
} }
@ -147,7 +142,7 @@ fn test_fq2_legendre() {
// i^2 = -1 // i^2 = -1
let mut m1 = -Fq2::one(); let mut m1 = -Fq2::one();
assert_eq!(QuadraticResidue, m1.legendre()); assert_eq!(QuadraticResidue, m1.legendre());
m1 = Fq6Parameters::mul_fp2_by_nonresidue(&m1);
m1 = Fq6Config::mul_fp2_by_nonresidue(&m1);
assert_eq!(QuadraticNonResidue, m1.legendre()); assert_eq!(QuadraticNonResidue, m1.legendre());
} }
@ -158,8 +153,8 @@ fn test_fq2_mul_nonresidue() {
let nqr = Fq2::new(Fq::zero(), Fq::one()); let nqr = Fq2::new(Fq::zero(), Fq::one());
let quadratic_non_residue = Fq2::new( let quadratic_non_residue = Fq2::new(
Fq2Parameters::QUADRATIC_NONRESIDUE.0,
Fq2Parameters::QUADRATIC_NONRESIDUE.1,
Fq2Config::QUADRATIC_NONRESIDUE.c0,
Fq2Config::QUADRATIC_NONRESIDUE.c1,
); );
for _ in 0..1000 { for _ in 0..1000 {
let mut a = Fq2::rand(&mut rng); let mut a = Fq2::rand(&mut rng);

+ 7
- 5
bls12_377/src/lib.rs

@ -9,15 +9,17 @@
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
//! This library implements the BLS12_377 curve generated in [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962). //! This library implements the BLS12_377 curve generated in [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962).
//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree 12,
//! defined over a 377-bit (prime) field. The main feature of this curve is that
//! both the scalar field and the base field are highly 2-adic.
//! (This is in contrast to the BLS12_381 curve for which only the scalar field is highly 2-adic.)
//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree
//! 12, defined over a 377-bit (prime) field. The main feature of this curve is
//! that both the scalar field and the base field are highly 2-adic.
//! (This is in contrast to the BLS12_381 curve for which only the scalar field
//! is highly 2-adic.)
//! //!
//! //!
//! Curve information: //! Curve information:
//! * Base field: q = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177 //! * Base field: q = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
//! * Scalar field: r = 8444461749428370424248824938781546531375899335154063827935233455917409239041
//! * Scalar field: r =
//! 8444461749428370424248824938781546531375899335154063827935233455917409239041
//! * valuation(q - 1, 2) = 46 //! * valuation(q - 1, 2) = 46
//! * valuation(r - 1, 2) = 47 //! * valuation(r - 1, 2) = 47
//! * G1 curve equation: y^2 = x^3 + 1 //! * G1 curve equation: y^2 = x^3 + 1

+ 28
- 0
bls12_381/scripts/base_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)

+ 28
- 0
bls12_381/scripts/scalar_field.sage

@ -0,0 +1,28 @@
modulus = 52435875175126190479447740508185965837690552500527637822603658699938581184513
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)

+ 16
- 14
bls12_381/src/curves/g1.rs

@ -1,4 +1,3 @@
use crate::*;
use ark_ec::{ use ark_ec::{
bls12, bls12,
bls12::Bls12Parameters, bls12::Bls12Parameters,
@ -6,9 +5,11 @@ use ark_ec::{
short_weierstrass_jacobian::GroupAffine, short_weierstrass_jacobian::GroupAffine,
AffineCurve, ProjectiveCurve, AffineCurve, ProjectiveCurve,
}; };
use ark_ff::{biginteger::BigInteger256, field_new, Zero};
use ark_ff::{biginteger::BigInteger256, MontFp, Zero};
use ark_std::ops::Neg; use ark_std::ops::Neg;
use crate::*;
pub type G1Affine = bls12::G1Affine<crate::Parameters>; pub type G1Affine = bls12::G1Affine<crate::Parameters>;
pub type G1Projective = bls12::G1Projective<crate::Parameters>; pub type G1Projective = bls12::G1Projective<crate::Parameters>;
@ -24,17 +25,18 @@ impl ModelParameters for Parameters {
/// COFACTOR_INV = COFACTOR^{-1} mod r /// COFACTOR_INV = COFACTOR^{-1} mod r
/// = 52435875175126190458656871551744051925719901746859129887267498875565241663483 /// = 52435875175126190458656871551744051925719901746859129887267498875565241663483
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, "52435875175126190458656871551744051925719901746859129887267498875565241663483");
const COFACTOR_INV: Fr = MontFp!(
Fr,
"52435875175126190458656871551744051925719901746859129887267498875565241663483"
);
} }
impl SWModelParameters for Parameters { impl SWModelParameters for Parameters {
/// COEFF_A = 0 /// COEFF_A = 0
const COEFF_A: Fq = field_new!(Fq, "0");
const COEFF_A: Fq = MontFp!(Fq, "0");
/// COEFF_B = 4 /// COEFF_B = 4
#[rustfmt::skip]
const COEFF_B: Fq = field_new!(Fq, "4");
const COEFF_B: Fq = MontFp!(Fq, "4");
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
@ -54,7 +56,8 @@ impl SWModelParameters for Parameters {
let x = BigInteger256::new([crate::Parameters::X[0], 0, 0, 0]); let x = BigInteger256::new([crate::Parameters::X[0], 0, 0, 0]);
// An early-out optimization described in Section 6. // An early-out optimization described in Section 6.
// If uP == P but P != point of infinity, then the point is not in the right subgroup.
// If uP == P but P != point of infinity, then the point is not in the right
// subgroup.
let x_times_p = p.mul(x); let x_times_p = p.mul(x);
if x_times_p.eq(p) && !p.infinity { if x_times_p.eq(p) && !p.infinity {
return false; return false;
@ -68,20 +71,19 @@ impl SWModelParameters for Parameters {
/// G1_GENERATOR_X = /// G1_GENERATOR_X =
/// 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507 /// 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
#[rustfmt::skip]
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507");
pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507");
/// G1_GENERATOR_Y = /// G1_GENERATOR_Y =
/// 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569 /// 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
#[rustfmt::skip]
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569");
pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569");
/// BETA is a non-trivial cubic root of unity in Fq. /// BETA is a non-trivial cubic root of unity in Fq.
pub const BETA: Fq = field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350");
pub const BETA: Fq = MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350");
pub fn endomorphism(p: &GroupAffine<Parameters>) -> GroupAffine<Parameters> { pub fn endomorphism(p: &GroupAffine<Parameters>) -> GroupAffine<Parameters> {
// Endomorphism of the points on the curve. // Endomorphism of the points on the curve.
// endomorphism_p(x,y) = (BETA * x, y) where BETA is a non-trivial cubic root of unity in Fq.
// endomorphism_p(x,y) = (BETA * x, y)
// where BETA is a non-trivial cubic root of unity in Fq.
let mut res = (*p).clone(); let mut res = (*p).clone();
res.x *= BETA; res.x *= BETA;
res res

+ 33
- 34
bls12_381/src/curves/g2.rs

@ -1,12 +1,13 @@
use crate::*;
use ark_ec::bls12::Bls12Parameters;
use ark_ec::{ use ark_ec::{
bls12, bls12,
bls12::Bls12Parameters,
models::{ModelParameters, SWModelParameters}, models::{ModelParameters, SWModelParameters},
short_weierstrass_jacobian::GroupAffine, short_weierstrass_jacobian::GroupAffine,
AffineCurve, AffineCurve,
}; };
use ark_ff::{field_new, BigInt, Field, Zero};
use ark_ff::{BigInt, Field, MontFp, QuadExt, Zero};
use crate::*;
pub type G2Affine = bls12::G2Affine<crate::Parameters>; pub type G2Affine = bls12::G2Affine<crate::Parameters>;
pub type G2Projective = bls12::G2Projective<crate::Parameters>; pub type G2Projective = bls12::G2Projective<crate::Parameters>;
@ -35,16 +36,18 @@ impl ModelParameters for Parameters {
/// COFACTOR_INV = COFACTOR^{-1} mod r /// COFACTOR_INV = COFACTOR^{-1} mod r
/// 26652489039290660355457965112010883481355318854675681319708643586776743290055 /// 26652489039290660355457965112010883481355318854675681319708643586776743290055
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, "26652489039290660355457965112010883481355318854675681319708643586776743290055");
const COFACTOR_INV: Fr = MontFp!(
Fr,
"26652489039290660355457965112010883481355318854675681319708643586776743290055"
);
} }
impl SWModelParameters for Parameters { impl SWModelParameters for Parameters {
/// COEFF_A = [0, 0] /// COEFF_A = [0, 0]
const COEFF_A: Fq2 = field_new!(Fq2, g1::Parameters::COEFF_A, g1::Parameters::COEFF_A,);
const COEFF_A: Fq2 = QuadExt!(g1::Parameters::COEFF_A, g1::Parameters::COEFF_A,);
/// COEFF_B = [4, 4] /// COEFF_B = [4, 4]
const COEFF_B: Fq2 = field_new!(Fq2, g1::Parameters::COEFF_B, g1::Parameters::COEFF_B,);
const COEFF_B: Fq2 = QuadExt!(g1::Parameters::COEFF_B, g1::Parameters::COEFF_B,);
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y) /// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
@ -71,59 +74,55 @@ impl SWModelParameters for Parameters {
} }
} }
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);
pub const G2_GENERATOR_X: Fq2 = QuadExt!(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
pub const G2_GENERATOR_Y: Fq2 = QuadExt!(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
/// G2_GENERATOR_X_C0 = /// G2_GENERATOR_X_C0 =
/// 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160 /// 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160
#[rustfmt::skip]
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160");
pub const G2_GENERATOR_X_C0: Fq = MontFp!(Fq, "352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160");
/// G2_GENERATOR_X_C1 = /// G2_GENERATOR_X_C1 =
/// 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758 /// 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758
#[rustfmt::skip]
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758");
pub const G2_GENERATOR_X_C1: Fq = MontFp!(Fq, "3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758");
/// G2_GENERATOR_Y_C0 = /// G2_GENERATOR_Y_C0 =
/// 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905 /// 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905
#[rustfmt::skip]
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905");
pub const G2_GENERATOR_Y_C0: Fq = MontFp!(Fq, "1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905");
/// G2_GENERATOR_Y_C1 = /// G2_GENERATOR_Y_C1 =
/// 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582 /// 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582
#[rustfmt::skip]
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582");
pub const G2_GENERATOR_Y_C1: Fq = MontFp!(Fq, "927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582");
// psi(x,y) = (x**p * PSI_X, y**p * PSI_Y) is the Frobenius composed // psi(x,y) = (x**p * PSI_X, y**p * PSI_Y) is the Frobenius composed
// with the quadratic twist and its inverse // with the quadratic twist and its inverse
// PSI_X = 1/(u+1)^((p-1)/3) // PSI_X = 1/(u+1)^((p-1)/3)
pub const P_POWER_ENDOMORPHISM_COEFF_0 : Fq2 = field_new!(
Fq2,
pub const P_POWER_ENDOMORPHISM_COEFF_0 : Fq2 = QuadExt!(
FQ_ZERO, FQ_ZERO,
field_new!(
Fq,
"4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"
MontFp!(
Fq,
"4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"
) )
); );
// PSI_Y = 1/(u+1)^((p-1)/2) // PSI_Y = 1/(u+1)^((p-1)/2)
pub const P_POWER_ENDOMORPHISM_COEFF_1: Fq2 = field_new!(
Fq2,
field_new!(
Fq,
"2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
field_new!(
Fq,
"1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257")
pub const P_POWER_ENDOMORPHISM_COEFF_1: Fq2 = QuadExt!(
MontFp!(
Fq,
"2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
MontFp!(
Fq,
"1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257")
); );
pub fn p_power_endomorphism(p: &GroupAffine<Parameters>) -> GroupAffine<Parameters> { pub fn p_power_endomorphism(p: &GroupAffine<Parameters>) -> GroupAffine<Parameters> {
// The p-power endomorphism for G2 is defined as follows: // The p-power endomorphism for G2 is defined as follows:
// 1. Note that G2 is defined on curve E': y^2 = x^3 + 4(u+1). To map a point (x, y) in E' to (s, t) in E,
// one set s = x / ((u+1) ^ (1/3)), t = y / ((u+1) ^ (1/2)), because E: y^2 = x^3 + 4.
// 2. Apply the Frobenius endomorphism (s, t) => (s', t'), another point on curve E,
// where s' = s^p, t' = t^p.
// 1. Note that G2 is defined on curve E': y^2 = x^3 + 4(u+1).
// To map a point (x, y) in E' to (s, t) in E,
// one set s = x / ((u+1) ^ (1/3)), t = y / ((u+1) ^ (1/2)),
// because E: y^2 = x^3 + 4.
// 2. Apply the Frobenius endomorphism (s, t) => (s', t'),
// another point on curve E, where s' = s^p, t' = t^p.
// 3. Map the point from E back to E'; that is, // 3. Map the point from E back to E'; that is,
// one set x' = s' * ((u+1) ^ (1/3)), y' = t' * ((u+1) ^ (1/2)). // one set x' = s' * ((u+1) ^ (1/3)), y' = t' * ((u+1) ^ (1/2)).
// //

+ 4
- 4
bls12_381/src/curves/mod.rs

@ -1,6 +1,6 @@
use ark_ec::bls12::{Bls12, Bls12Parameters, TwistType}; use ark_ec::bls12::{Bls12, Bls12Parameters, TwistType};
use crate::{Fq, Fq12Parameters, Fq2Parameters, Fq6Parameters};
use crate::{Fq, Fq12Config, Fq2Config, Fq6Config};
pub mod g1; pub mod g1;
pub mod g2; pub mod g2;
@ -22,9 +22,9 @@ impl Bls12Parameters for Parameters {
const X_IS_NEGATIVE: bool = true; const X_IS_NEGATIVE: bool = true;
const TWIST_TYPE: TwistType = TwistType::M; const TWIST_TYPE: TwistType = TwistType::M;
type Fp = Fq; type Fp = Fq;
type Fp2Params = Fq2Parameters;
type Fp6Params = Fq6Parameters;
type Fp12Params = Fq12Parameters;
type Fp2Config = Fq2Config;
type Fp6Config = Fq6Config;
type Fp12Config = Fq12Config;
type G1Parameters = self::g1::Parameters; type G1Parameters = self::g1::Parameters;
type G2Parameters = self::g2::Parameters; type G2Parameters = self::g2::Parameters;
} }

+ 6
- 13
bls12_381/src/curves/tests.rs

@ -1,23 +1,16 @@
#![allow(unused_imports)]
use ark_ec::{
models::SWModelParameters,
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
AffineCurve, PairingEngine, ProjectiveCurve,
use ark_algebra_test_templates::{
curves::*, generate_bilinearity_test, generate_g1_generator_raw_test, generate_g1_test,
generate_g2_test, groups::*, msm::*,
}; };
use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine, ProjectiveCurve};
use ark_ff::{ use ark_ff::{
fields::{Field, FpParameters, PrimeField, SquareRootField},
BitIteratorBE, One, UniformRand, Zero,
fields::{Field, PrimeField, SquareRootField},
One, UniformRand, Zero,
}; };
use ark_serialize::CanonicalSerialize;
use ark_std::{rand::Rng, test_rng}; use ark_std::{rand::Rng, test_rng};
use core::ops::{AddAssign, MulAssign}; use core::ops::{AddAssign, MulAssign};
use crate::{g1, g2, Bls12_381, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective}; use crate::{g1, g2, Bls12_381, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
use ark_algebra_test_templates::{
curves::*, generate_bilinearity_test, generate_g1_generator_raw_test, generate_g1_test,
generate_g2_test, groups::*, msm::*,
};
use ark_ec::group::Group;
generate_g1_test!(bls12_381; curve_tests; sw_tests;); generate_g1_test!(bls12_381; curve_tests; sw_tests;);
generate_g2_test!(bls12_381; curve_tests; sw_tests;); generate_g2_test!(bls12_381; curve_tests; sw_tests;);

+ 8
- 113
bls12_381/src/fields/fq.rs

@ -1,115 +1,10 @@
use ark_ff::{
biginteger::{BigInt, BigInteger384 as BigInteger},
field_new,
fields::{FftParameters, Fp384, Fp384Parameters, FpParameters},
};
use ark_ff::fields::{Fp384, MontBackend, MontConfig, MontFp};
pub type Fq = Fp384<FqParameters>;
#[derive(MontConfig)]
#[modulus = "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787"]
#[generator = "2"]
pub struct FqConfig;
pub type Fq = Fp384<MontBackend<FqConfig, 6>>;
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 = BigInt::new([
0x43f5fffffffcaaae,
0x32b7fff2ed47fffd,
0x7e83a49a2e99d69,
0xeca8f3318332bb7a,
0xef148d1ea0f4c069,
0x40ab3263eff0206,
]);
}
impl FpParameters for FqParameters {
/// MODULUS = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
#[rustfmt::skip]
const MODULUS: BigInteger = BigInt::new([
0xb9feffffffffaaab,
0x1eabfffeb153ffff,
0x6730d2a0f6b0f624,
0x64774b84f38512bf,
0x4b1ba7b6434bacd7,
0x1a0111ea397fe69a,
]);
const MODULUS_BITS: u32 = 381;
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
const REPR_SHAVE_BITS: u32 = 3;
/// R = 3380320199399472671518931668520476396067793891014375699959770179129436917079669831430077592723774664465579537268733
#[rustfmt::skip]
const R: BigInteger = BigInt::new([
0x760900000002fffd,
0xebf4000bc40c0002,
0x5f48985753c758ba,
0x77ce585370525745,
0x5c071a97a256ec6d,
0x15f65ec3fa80e493,
]);
#[rustfmt::skip]
const R2: BigInteger = BigInt::new([
0xf4df1f341c341746,
0xa76e6a609d104f1,
0x8de5476c4c95b6d5,
0x67eb88a9939d83c0,
0x9a793e85b519952d,
0x11988fe592cae3aa,
]);
const INV: u64 = 0x89f3fffcfffcfffd;
/// GENERATOR = 2
/// Encoded in Montgomery form, so the value is
/// 2 * R % q = 2758230843577277949620073511305048635578704962089743514587482222134842183668501798417467556318533664893264801977679
#[rustfmt::skip]
const GENERATOR: BigInteger = BigInt::new([
0x321300000006554f,
0xb93c0018d6c40005,
0x57605e0db0ddbb51,
0x8b256521ed1f9bcb,
0x6cf28d7901622c03,
0x11ebab9dbb81e28c,
]);
#[rustfmt::skip]
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0xdcff7fffffffd555,
0xf55ffff58a9ffff,
0xb39869507b587b12,
0xb23ba5c279c2895f,
0x258dd3db21a5d66b,
0xd0088f51cbff34d,
]);
/// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T
/// For T coprime to 2
#[rustfmt::skip]
const T: BigInteger = BigInt::new([
0xdcff7fffffffd555,
0xf55ffff58a9ffff,
0xb39869507b587b12,
0xb23ba5c279c2895f,
0x258dd3db21a5d66b,
0xd0088f51cbff34d,
]);
#[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0xee7fbfffffffeaaa,
0x7aaffffac54ffff,
0xd9cc34a83dac3d89,
0xd91dd2e13ce144af,
0x92c6e9ed90d2eb35,
0x680447a8e5ff9a6,
]);
}
pub const FQ_ONE: Fq = field_new!(Fq, "1");
pub const FQ_ZERO: Fq = field_new!(Fq, "0");
pub const FQ_ONE: Fq = MontFp!(Fq, "1");
pub const FQ_ZERO: Fq = MontFp!(Fq, "0");

+ 43
- 42
bls12_381/src/fields/fq12.rs

@ -1,76 +1,77 @@
use ark_ff::{fields::*, CubicExt, MontFp, QuadExt};
use crate::*; use crate::*;
use ark_ff::{field_new, fields::*};
pub type Fq12 = Fp12<Fq12Parameters>;
pub type Fq12 = Fp12<Fq12Config>;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Fq12Parameters;
pub struct Fq12Config;
impl Fp12Parameters for Fq12Parameters {
type Fp6Params = Fq6Parameters;
impl Fp12Config for Fq12Config {
type Fp6Config = Fq6Config;
const NONRESIDUE: Fq6 = field_new!(Fq6, FQ2_ZERO, FQ2_ONE, FQ2_ZERO);
const NONRESIDUE: Fq6 = CubicExt!(FQ2_ZERO, FQ2_ONE, FQ2_ZERO);
const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[ const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[
// Fp2::NONRESIDUE^(((q^0) - 1) / 6) // Fp2::NONRESIDUE^(((q^0) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "1"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "1"),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^1) - 1) / 6) // Fp2::NONRESIDUE^(((q^1) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"),
field_new!(Fq, "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"),
QuadExt!(
MontFp!(Fq, "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"),
MontFp!(Fq, "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"),
), ),
// Fp2::NONRESIDUE^(((q^2) - 1) / 6) // Fp2::NONRESIDUE^(((q^2) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^3) - 1) / 6) // Fp2::NONRESIDUE^(((q^3) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
field_new!(Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"),
QuadExt!(
MontFp!(Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
MontFp!(Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"),
), ),
// Fp2::NONRESIDUE^(((q^4) - 1) / 6) // Fp2::NONRESIDUE^(((q^4) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^5) - 1) / 6) // Fp2::NONRESIDUE^(((q^5) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"),
field_new!(Fq, "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"),
QuadExt!(
MontFp!(Fq, "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"),
MontFp!(Fq, "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"),
), ),
// Fp2::NONRESIDUE^(((q^6) - 1) / 6) // Fp2::NONRESIDUE^(((q^6) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "-1"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "-1"),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^7) - 1) / 6) // Fp2::NONRESIDUE^(((q^7) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"),
field_new!(Fq, "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"),
QuadExt!(
MontFp!(Fq, "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"),
MontFp!(Fq, "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"),
), ),
// Fp2::NONRESIDUE^(((q^8) - 1) / 6) // Fp2::NONRESIDUE^(((q^8) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^9) - 1) / 6) // Fp2::NONRESIDUE^(((q^9) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"),
field_new!(Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
QuadExt!(
MontFp!(Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"),
MontFp!(Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
), ),
// Fp2::NONRESIDUE^(((q^10) - 1) / 6) // Fp2::NONRESIDUE^(((q^10) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^11) - 1) / 6) // Fp2::NONRESIDUE^(((q^11) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"),
field_new!(Fq, "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"),
QuadExt!(
MontFp!(Fq, "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"),
MontFp!(Fq, "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"),
), ),
]; ];
} }

+ 11
- 13
bls12_381/src/fields/fq2.rs

@ -1,28 +1,26 @@
use ark_ff::{fields::*, MontFp, QuadExt};
use crate::*; use crate::*;
use ark_ff::{field_new, fields::*};
pub type Fq2 = Fp2<Fq2Parameters>;
pub type Fq2 = Fp2<Fq2Config>;
pub struct Fq2Parameters;
pub struct Fq2Config;
impl Fp2Parameters for Fq2Parameters {
impl Fp2Config for Fq2Config {
type Fp = Fq; type Fp = Fq;
/// NONRESIDUE = -1 /// NONRESIDUE = -1
#[rustfmt::skip]
const NONRESIDUE: Fq = field_new!(Fq, "-1");
const NONRESIDUE: Fq = MontFp!(Fq, "-1");
/// QUADRATIC_NONRESIDUE = (U + 1) /// QUADRATIC_NONRESIDUE = (U + 1)
#[rustfmt::skip]
const QUADRATIC_NONRESIDUE: (Fq, Fq) = (FQ_ONE, FQ_ONE);
const QUADRATIC_NONRESIDUE: Fq2 = QuadExt!(FQ_ONE, FQ_ONE);
/// Coefficients for the Frobenius automorphism. /// Coefficients for the Frobenius automorphism.
#[rustfmt::skip]
const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[ const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[
// Fq(-1)**(((q^0) - 1) / 2) // Fq(-1)**(((q^0) - 1) / 2)
field_new!(Fq, "1"),
MontFp!(Fq, "1"),
// Fq(-1)**(((q^1) - 1) / 2) // Fq(-1)**(((q^1) - 1) / 2)
field_new!(Fq, "-1"),
MontFp!(Fq, "-1"),
]; ];
#[inline(always)] #[inline(always)]
@ -31,5 +29,5 @@ impl Fp2Parameters for Fq2Parameters {
} }
} }
pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO);
pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO);
pub const FQ2_ZERO: Fq2 = QuadExt!(FQ_ZERO, FQ_ZERO);
pub const FQ2_ONE: Fq2 = QuadExt!(FQ_ONE, FQ_ZERO);

+ 43
- 47
bls12_381/src/fields/fq6.rs

@ -1,86 +1,82 @@
use ark_ff::{fields::*, MontFp, QuadExt};
use crate::*; use crate::*;
use ark_ff::{field_new, fields::*};
pub type Fq6 = Fp6<Fq6Parameters>;
pub type Fq6 = Fp6<Fq6Config>;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Fq6Parameters;
pub struct Fq6Config;
impl Fp6Parameters for Fq6Parameters {
type Fp2Params = Fq2Parameters;
impl Fp6Config for Fq6Config {
type Fp2Config = Fq2Config;
/// NONRESIDUE = (U + 1) /// NONRESIDUE = (U + 1)
#[rustfmt::skip]
const NONRESIDUE: Fq2 = field_new!(Fq2,
field_new!(Fq, "1"),
field_new!(Fq, "1"),
);
const NONRESIDUE: Fq2 = QuadExt!(FQ_ONE, FQ_ONE);
#[rustfmt::skip]
const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[ const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[
// Fp2::NONRESIDUE^(((q^0) - 1) / 3) // Fp2::NONRESIDUE^(((q^0) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "1"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "1"),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^1) - 1) / 3) // Fp2::NONRESIDUE^(((q^1) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "0"),
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
QuadExt!(
MontFp!(Fq, "0"),
MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
), ),
// Fp2::NONRESIDUE^(((q^2) - 1) / 3) // Fp2::NONRESIDUE^(((q^2) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^3) - 1) / 3) // Fp2::NONRESIDUE^(((q^3) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "0"),
field_new!(Fq, "1"),
QuadExt!(
MontFp!(Fq, "0"),
MontFp!(Fq, "1"),
), ),
// Fp2::NONRESIDUE^(((q^4) - 1) / 3) // Fp2::NONRESIDUE^(((q^4) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^5) - 1) / 3) // Fp2::NONRESIDUE^(((q^5) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "0"),
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
QuadExt!(
MontFp!(Fq, "0"),
MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
), ),
]; ];
#[rustfmt::skip] #[rustfmt::skip]
const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[ const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[
// Fq2(u + 1)**(((2q^0) - 2) / 3) // Fq2(u + 1)**(((2q^0) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "1"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "1"),
MontFp!(Fq, "0"),
), ),
// Fq2(u + 1)**(((2q^1) - 2) / 3) // Fq2(u + 1)**(((2q^1) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"),
MontFp!(Fq, "0"),
), ),
// Fq2(u + 1)**(((2q^2) - 2) / 3) // Fq2(u + 1)**(((2q^2) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
MontFp!(Fq, "0"),
), ),
// Fq2(u + 1)**(((2q^3) - 2) / 3) // Fq2(u + 1)**(((2q^3) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "-1"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "-1"),
MontFp!(Fq, "0"),
), ),
// Fq2(u + 1)**(((2q^4) - 2) / 3) // Fq2(u + 1)**(((2q^4) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
MontFp!(Fq, "0"),
), ),
// Fq2(u + 1)**(((2q^5) - 2) / 3) // Fq2(u + 1)**(((2q^5) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"),
MontFp!(Fq, "0"),
), ),
]; ];

+ 6
- 99
bls12_381/src/fields/fr.rs

@ -1,100 +1,7 @@
use ark_ff::{
biginteger::{BigInt, BigInteger256 as BigInteger},
fields::{FftParameters, Fp256, Fp256Parameters, FpParameters},
};
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
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 = BigInt::new([
0xb9b58d8c5f0e466a,
0x5b1b4c801819d7ec,
0xaf53ae352a31e64,
0x5bf3adda19e9b27b,
]);
}
impl FpParameters for FrParameters {
/// MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513
#[rustfmt::skip]
const MODULUS: BigInteger = BigInt::new([
0xffffffff00000001,
0x53bda402fffe5bfe,
0x3339d80809a1d805,
0x73eda753299d7d48,
]);
const MODULUS_BITS: u32 = 255;
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
const REPR_SHAVE_BITS: u32 = 1;
/// R = 10920338887063814464675503992315976177888879664585288394250266608035967270910
#[rustfmt::skip]
const R: BigInteger = BigInt::new([
0x1fffffffe,
0x5884b7fa00034802,
0x998c4fefecbc4ff5,
0x1824b159acc5056f,
]);
#[rustfmt::skip]
const R2: BigInteger = BigInt::new([
0xc999e990f3f29c6d,
0x2b6cedcb87925c23,
0x5d314967254398f,
0x748d9d99f59ff11,
]);
const INV: u64 = 0xfffffffeffffffff;
/// GENERATOR = 7
/// Encoded in Montgomery form, so the value here is
/// 7 * R % q = 24006497034320510773280787438025867407531605151569380937148207556313189711857
#[rustfmt::skip]
const GENERATOR: BigInteger = BigInt::new([
0xefffffff1,
0x17e363d300189c0f,
0xff9c57876f8457b0,
0x351332208fc5a8c4,
]);
#[rustfmt::skip]
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0x7fffffff80000000,
0xa9ded2017fff2dff,
0x199cec0404d0ec02,
0x39f6d3a994cebea4,
]);
// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T
// For T coprime to 2
// T = (MODULUS - 1) / 2^S =
// 12208678567578594777604504606729831043093128246378069236549469339647
#[rustfmt::skip]
const T: BigInteger = BigInt::new([
0xfffe5bfeffffffff,
0x9a1d80553bda402,
0x299d7d483339d808,
0x73eda753,
]);
// (T - 1) / 2 =
// 6104339283789297388802252303364915521546564123189034618274734669823
#[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0x7fff2dff7fffffff,
0x4d0ec02a9ded201,
0x94cebea4199cec04,
0x39f6d3a9,
]);
}
#[derive(MontConfig)]
#[modulus = "52435875175126190479447740508185965837690552500527637822603658699938581184513"]
#[generator = "7"]
pub struct FrConfig;
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;

+ 1
- 1
bls12_381/src/fields/mod.rs

@ -23,5 +23,5 @@ pub mod fq12;
#[cfg(feature = "curve")] #[cfg(feature = "curve")]
pub use self::fq12::*; pub use self::fq12::*;
#[cfg(all(feature = "curve", feature = "std", test))]
#[cfg(all(feature = "curve", test))]
mod tests; mod tests;

+ 83
- 84
bls12_381/src/fields/tests.rs

@ -1,22 +1,23 @@
use ark_algebra_test_templates::{
fields::*, generate_field_serialization_test, generate_field_test,
};
use ark_ff::{ use ark_ff::{
biginteger::{BigInt, BigInteger, BigInteger384}, biginteger::{BigInt, BigInteger, BigInteger384},
fields::{
FftField, FftParameters, Field, Fp12Parameters, Fp2Parameters, Fp6Parameters, FpParameters,
SquareRootField,
},
fields::{FftField, Field, Fp12Config, Fp2Config, Fp6Config, PrimeField, SquareRootField},
One, UniformRand, Zero, One, UniformRand, Zero,
}; };
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
use ark_std::{ use ark_std::{
cmp::Ordering, cmp::Ordering,
ops::{AddAssign, MulAssign, SubAssign}, ops::{AddAssign, MulAssign, SubAssign},
rand::Rng, rand::Rng,
test_rng,
test_rng, vec,
}; };
use crate::{Fq, Fq12, Fq12Parameters, Fq2, Fq2Parameters, Fq6, Fq6Parameters, FqParameters, Fr};
use ark_algebra_test_templates::{fields::*, generate_field_test};
use crate::{Fq, Fq12, Fq12Config, Fq2, Fq2Config, Fq6, Fq6Config, FqConfig, Fr, FrConfig};
generate_field_test!(bls12_381; fq2; fq6; fq12;);
generate_field_test!(bls12_381; fq2; fq6; fq12; mont(6, 4); );
generate_field_serialization_test!(bls12_381; fq2; fq6; fq12;);
#[test] #[test]
fn test_negative_one() { fn test_negative_one() {
@ -35,9 +36,9 @@ fn test_negative_one() {
fn test_frob_coeffs() { fn test_frob_coeffs() {
let nqr = -Fq::one(); let nqr = -Fq::one();
assert_eq!(Fq2Parameters::FROBENIUS_COEFF_FP2_C1[0], Fq::one());
assert_eq!(Fq2Config::FROBENIUS_COEFF_FP2_C1[0], Fq::one());
assert_eq!( assert_eq!(
Fq2Parameters::FROBENIUS_COEFF_FP2_C1[1],
Fq2Config::FROBENIUS_COEFF_FP2_C1[1],
nqr.pow([ nqr.pow([
0xdcff7fffffffd555, 0xdcff7fffffffd555,
0xf55ffff58a9ffff, 0xf55ffff58a9ffff,
@ -50,9 +51,9 @@ fn test_frob_coeffs() {
let nqr = Fq2::new(Fq::one(), Fq::one()); let nqr = Fq2::new(Fq::one(), Fq::one());
assert_eq!(Fq6Parameters::FROBENIUS_COEFF_FP6_C1[0], Fq2::one());
assert_eq!(Fq6Config::FROBENIUS_COEFF_FP6_C1[0], Fq2::one());
assert_eq!( assert_eq!(
Fq6Parameters::FROBENIUS_COEFF_FP6_C1[1],
Fq6Config::FROBENIUS_COEFF_FP6_C1[1],
nqr.pow([ nqr.pow([
0x9354ffffffffe38e, 0x9354ffffffffe38e,
0xa395554e5c6aaaa, 0xa395554e5c6aaaa,
@ -63,7 +64,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq6Parameters::FROBENIUS_COEFF_FP6_C1[2],
Fq6Config::FROBENIUS_COEFF_FP6_C1[2],
nqr.pow([ nqr.pow([
0xb78e0000097b2f68, 0xb78e0000097b2f68,
0xd44f23b47cbd64e3, 0xd44f23b47cbd64e3,
@ -80,7 +81,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq6Parameters::FROBENIUS_COEFF_FP6_C1[3],
Fq6Config::FROBENIUS_COEFF_FP6_C1[3],
nqr.pow([ nqr.pow([
0xdbc6fcd6f35b9e06, 0xdbc6fcd6f35b9e06,
0x997dead10becd6aa, 0x997dead10becd6aa,
@ -103,7 +104,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq6Parameters::FROBENIUS_COEFF_FP6_C1[4],
Fq6Config::FROBENIUS_COEFF_FP6_C1[4],
nqr.pow([ nqr.pow([
0x4649add3c71c6d90, 0x4649add3c71c6d90,
0x43caa6528972a865, 0x43caa6528972a865,
@ -132,7 +133,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq6Parameters::FROBENIUS_COEFF_FP6_C1[5],
Fq6Config::FROBENIUS_COEFF_FP6_C1[5],
nqr.pow([ nqr.pow([
0xf896f792732eb2be, 0xf896f792732eb2be,
0x49c86a6d1dc593a1, 0x49c86a6d1dc593a1,
@ -167,9 +168,9 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!(Fq6Parameters::FROBENIUS_COEFF_FP6_C2[0], Fq2::one());
assert_eq!(Fq6Config::FROBENIUS_COEFF_FP6_C2[0], Fq2::one());
assert_eq!( assert_eq!(
Fq6Parameters::FROBENIUS_COEFF_FP6_C2[1],
Fq6Config::FROBENIUS_COEFF_FP6_C2[1],
nqr.pow([ nqr.pow([
0x26a9ffffffffc71c, 0x26a9ffffffffc71c,
0x1472aaa9cb8d5555, 0x1472aaa9cb8d5555,
@ -180,7 +181,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq6Parameters::FROBENIUS_COEFF_FP6_C2[2],
Fq6Config::FROBENIUS_COEFF_FP6_C2[2],
nqr.pow([ nqr.pow([
0x6f1c000012f65ed0, 0x6f1c000012f65ed0,
0xa89e4768f97ac9c7, 0xa89e4768f97ac9c7,
@ -197,7 +198,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq6Parameters::FROBENIUS_COEFF_FP6_C2[3],
Fq6Config::FROBENIUS_COEFF_FP6_C2[3],
nqr.pow([ nqr.pow([
0xb78df9ade6b73c0c, 0xb78df9ade6b73c0c,
0x32fbd5a217d9ad55, 0x32fbd5a217d9ad55,
@ -220,7 +221,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq6Parameters::FROBENIUS_COEFF_FP6_C2[4],
Fq6Config::FROBENIUS_COEFF_FP6_C2[4],
nqr.pow([ nqr.pow([
0x8c935ba78e38db20, 0x8c935ba78e38db20,
0x87954ca512e550ca, 0x87954ca512e550ca,
@ -249,7 +250,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq6Parameters::FROBENIUS_COEFF_FP6_C2[5],
Fq6Config::FROBENIUS_COEFF_FP6_C2[5],
nqr.pow([ nqr.pow([
0xf12def24e65d657c, 0xf12def24e65d657c,
0x9390d4da3b8b2743, 0x9390d4da3b8b2743,
@ -284,9 +285,9 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!(Fq12Parameters::FROBENIUS_COEFF_FP12_C1[0], Fq2::one());
assert_eq!(Fq12Config::FROBENIUS_COEFF_FP12_C1[0], Fq2::one());
assert_eq!( assert_eq!(
Fq12Parameters::FROBENIUS_COEFF_FP12_C1[1],
Fq12Config::FROBENIUS_COEFF_FP12_C1[1],
nqr.pow([ nqr.pow([
0x49aa7ffffffff1c7, 0x49aa7ffffffff1c7,
0x51caaaa72e35555, 0x51caaaa72e35555,
@ -297,7 +298,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq12Parameters::FROBENIUS_COEFF_FP12_C1[2],
Fq12Config::FROBENIUS_COEFF_FP12_C1[2],
nqr.pow([ nqr.pow([
0xdbc7000004bd97b4, 0xdbc7000004bd97b4,
0xea2791da3e5eb271, 0xea2791da3e5eb271,
@ -314,7 +315,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq12Parameters::FROBENIUS_COEFF_FP12_C1[3],
Fq12Config::FROBENIUS_COEFF_FP12_C1[3],
nqr.pow(vec![ nqr.pow(vec![
0x6de37e6b79adcf03, 0x6de37e6b79adcf03,
0x4cbef56885f66b55, 0x4cbef56885f66b55,
@ -337,7 +338,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq12Parameters::FROBENIUS_COEFF_FP12_C1[4],
Fq12Config::FROBENIUS_COEFF_FP12_C1[4],
nqr.pow(vec![ nqr.pow(vec![
0xa324d6e9e38e36c8, 0xa324d6e9e38e36c8,
0xa1e5532944b95432, 0xa1e5532944b95432,
@ -366,7 +367,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq12Parameters::FROBENIUS_COEFF_FP12_C1[5],
Fq12Config::FROBENIUS_COEFF_FP12_C1[5],
nqr.pow(vec![ nqr.pow(vec![
0xfc4b7bc93997595f, 0xfc4b7bc93997595f,
0xa4e435368ee2c9d0, 0xa4e435368ee2c9d0,
@ -401,7 +402,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq12Parameters::FROBENIUS_COEFF_FP12_C1[6],
Fq12Config::FROBENIUS_COEFF_FP12_C1[6],
nqr.pow(vec![ nqr.pow(vec![
0x21219610a012ba3c, 0x21219610a012ba3c,
0xa5c19ad35375325, 0xa5c19ad35375325,
@ -442,7 +443,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq12Parameters::FROBENIUS_COEFF_FP12_C1[7],
Fq12Config::FROBENIUS_COEFF_FP12_C1[7],
nqr.pow(vec![ nqr.pow(vec![
0x742754a1f22fdb, 0x742754a1f22fdb,
0x2a1955c2dec3a702, 0x2a1955c2dec3a702,
@ -489,7 +490,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq12Parameters::FROBENIUS_COEFF_FP12_C1[8],
Fq12Config::FROBENIUS_COEFF_FP12_C1[8],
nqr.pow(vec![ nqr.pow(vec![
0x802f5720d0b25710, 0x802f5720d0b25710,
0x6714f0a258b85c7c, 0x6714f0a258b85c7c,
@ -542,7 +543,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq12Parameters::FROBENIUS_COEFF_FP12_C1[9],
Fq12Config::FROBENIUS_COEFF_FP12_C1[9],
nqr.pow(vec![ nqr.pow(vec![
0x4af4accf7de0b977, 0x4af4accf7de0b977,
0x742485e21805b4ee, 0x742485e21805b4ee,
@ -601,7 +602,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq12Parameters::FROBENIUS_COEFF_FP12_C1[10],
Fq12Config::FROBENIUS_COEFF_FP12_C1[10],
nqr.pow(vec![ nqr.pow(vec![
0xe5953a4f96cdda44, 0xe5953a4f96cdda44,
0x336b2d734cbc32bb, 0x336b2d734cbc32bb,
@ -666,7 +667,7 @@ fn test_frob_coeffs() {
]) ])
); );
assert_eq!( assert_eq!(
Fq12Parameters::FROBENIUS_COEFF_FP12_C1[11],
Fq12Config::FROBENIUS_COEFF_FP12_C1[11],
nqr.pow(vec![ nqr.pow(vec![
0x107db680942de533, 0x107db680942de533,
0x6262b24d2052393b, 0x6262b24d2052393b,
@ -750,7 +751,6 @@ fn test_neg_one() {
0xef148d1ea0f4c069, 0xef148d1ea0f4c069,
0x40ab3263eff0206, 0x40ab3263eff0206,
]; ];
println!("{:?}", thing);
let negative_one = Fq::new(BigInt::new(thing)); let negative_one = Fq::new(BigInt::new(thing));
assert_eq!(negative_one, o); assert_eq!(negative_one, o);
@ -763,14 +763,14 @@ fn test_fq_repr_from() {
#[test] #[test]
fn test_fq_repr_is_odd() { fn test_fq_repr_is_odd() {
assert!(!BigInteger384::from(0).is_odd());
assert!(BigInteger384::from(0).is_even());
assert!(BigInteger384::from(1).is_odd());
assert!(!BigInteger384::from(1).is_even());
assert!(!BigInteger384::from(324834872).is_odd());
assert!(BigInteger384::from(324834872).is_even());
assert!(BigInteger384::from(324834873).is_odd());
assert!(!BigInteger384::from(324834873).is_even());
assert!(!BigInteger384::from(0u64).is_odd());
assert!(BigInteger384::from(0u64).is_even());
assert!(BigInteger384::from(1u64).is_odd());
assert!(!BigInteger384::from(1u64).is_even());
assert!(!BigInteger384::from(324834872u64).is_odd());
assert!(BigInteger384::from(324834872u64).is_even());
assert!(BigInteger384::from(324834873u64).is_odd());
assert!(!BigInteger384::from(324834873u64).is_even());
} }
#[test] #[test]
@ -902,7 +902,7 @@ fn test_fq_repr_divn() {
#[test] #[test]
fn test_fq_repr_mul2() { fn test_fq_repr_mul2() {
let mut a = BigInteger384::from(23712937547);
let mut a = BigInteger384::from(23712937547u64);
a.mul2(); a.mul2();
assert_eq!(a, BigInt::new([0xb0acd6c96, 0x0, 0x0, 0x0, 0x0, 0x0])); assert_eq!(a, BigInt::new([0xb0acd6c96, 0x0, 0x0, 0x0, 0x0, 0x0]));
for _ in 0..60 { for _ in 0..60 {
@ -934,9 +934,9 @@ fn test_fq_repr_mul2() {
#[test] #[test]
fn test_fq_repr_num_bits() { fn test_fq_repr_num_bits() {
let mut a = BigInteger384::from(0);
let mut a = BigInteger384::from(0u64);
assert_eq!(0, a.num_bits()); assert_eq!(0, a.num_bits());
a = BigInteger384::from(1);
a = BigInteger384::from(1u64);
for i in 1..385 { for i in 1..385 {
assert_eq!(i, a.num_bits()); assert_eq!(i, a.num_bits());
a.mul2(); a.mul2();
@ -956,7 +956,7 @@ fn test_fq_repr_sub_noborrow() {
0xad0eb3948a5c34fd, 0xad0eb3948a5c34fd,
0xd56f7b5ab8b5ce8, 0xd56f7b5ab8b5ce8,
]); ]);
t.sub_noborrow(&BigInt::new([
t.sub_with_borrow(&BigInt::new([
0xc7867917187ca02b, 0xc7867917187ca02b,
0x5d75679d4911ffef, 0x5d75679d4911ffef,
0x8c5b3e48b1a71c15, 0x8c5b3e48b1a71c15,
@ -991,12 +991,12 @@ fn test_fq_repr_sub_noborrow() {
assert!(b < c); assert!(b < c);
let mut csub_ba = c; let mut csub_ba = c;
csub_ba.sub_noborrow(&b);
csub_ba.sub_noborrow(&a);
csub_ba.sub_with_borrow(&b);
csub_ba.sub_with_borrow(&a);
let mut csub_ab = c; let mut csub_ab = c;
csub_ab.sub_noborrow(&a);
csub_ab.sub_noborrow(&b);
csub_ab.sub_with_borrow(&a);
csub_ab.sub_with_borrow(&b);
assert_eq!(csub_ab, csub_ba); assert_eq!(csub_ab, csub_ba);
} }
@ -1010,7 +1010,7 @@ fn test_fq_repr_sub_noborrow() {
0x4b1ba7b6434bacd7, 0x4b1ba7b6434bacd7,
0x1a0111ea397fe69a, 0x1a0111ea397fe69a,
]); ]);
qplusone.sub_noborrow(&BigInt::new([
qplusone.sub_with_borrow(&BigInt::new([
0xb9feffffffffaaac, 0xb9feffffffffaaac,
0x1eabfffeb153ffff, 0x1eabfffeb153ffff,
0x6730d2a0f6b0f624, 0x6730d2a0f6b0f624,
@ -1043,7 +1043,7 @@ fn test_fq_repr_add_nocarry() {
0xad0eb3948a5c34fd, 0xad0eb3948a5c34fd,
0xd56f7b5ab8b5ce8, 0xd56f7b5ab8b5ce8,
]); ]);
t.add_nocarry(&BigInt::new([
t.add_with_carry(&BigInt::new([
0xc7867917187ca02b, 0xc7867917187ca02b,
0x5d75679d4911ffef, 0x5d75679d4911ffef,
0x8c5b3e48b1a71c15, 0x8c5b3e48b1a71c15,
@ -1074,28 +1074,28 @@ fn test_fq_repr_add_nocarry() {
c.0[5] >>= 3; c.0[5] >>= 3;
let mut abc = a; let mut abc = a;
abc.add_nocarry(&b);
abc.add_nocarry(&c);
abc.add_with_carry(&b);
abc.add_with_carry(&c);
let mut acb = a; let mut acb = a;
acb.add_nocarry(&c);
acb.add_nocarry(&b);
acb.add_with_carry(&c);
acb.add_with_carry(&b);
let mut bac = b; let mut bac = b;
bac.add_nocarry(&a);
bac.add_nocarry(&c);
bac.add_with_carry(&a);
bac.add_with_carry(&c);
let mut bca = b; let mut bca = b;
bca.add_nocarry(&c);
bca.add_nocarry(&a);
bca.add_with_carry(&c);
bca.add_with_carry(&a);
let mut cab = c; let mut cab = c;
cab.add_nocarry(&a);
cab.add_nocarry(&b);
cab.add_with_carry(&a);
cab.add_with_carry(&b);
let mut cba = c; let mut cba = c;
cba.add_nocarry(&b);
cba.add_nocarry(&a);
cba.add_with_carry(&b);
cba.add_with_carry(&a);
assert_eq!(abc, acb); assert_eq!(abc, acb);
assert_eq!(abc, bac); assert_eq!(abc, bac);
@ -1113,7 +1113,7 @@ fn test_fq_repr_add_nocarry() {
0xffffffffffffffff, 0xffffffffffffffff,
0xffffffffffffffff, 0xffffffffffffffff,
]); ]);
x.add_nocarry(&BigInteger384::from(1));
x.add_with_carry(&BigInteger384::from(1u64));
assert!(x.is_zero()); assert!(x.is_zero());
} }
@ -1132,19 +1132,15 @@ fn test_fq2_sqrt() {
#[test] #[test]
fn test_fq_num_bits() { fn test_fq_num_bits() {
assert_eq!(FqParameters::MODULUS_BITS, 381);
assert_eq!(FqParameters::CAPACITY, 380);
assert_eq!(Fq::MODULUS_BIT_SIZE, 381);
} }
#[test] #[test]
fn test_fq_root_of_unity() { fn test_fq_root_of_unity() {
assert_eq!(FqParameters::TWO_ADICITY, 1);
assert_eq!(
Fq::multiplicative_generator(),
Fq::from(BigInteger384::from(2))
);
assert_eq!(Fq::TWO_ADICITY, 1);
assert_eq!(Fq::GENERATOR, Fq::from(BigInteger384::from(2u64)));
assert_eq!( assert_eq!(
Fq::multiplicative_generator().pow([
Fq::GENERATOR.pow([
0xdcff7fffffffd555, 0xdcff7fffffffd555,
0xf55ffff58a9ffff, 0xf55ffff58a9ffff,
0xb39869507b587b12, 0xb39869507b587b12,
@ -1152,13 +1148,13 @@ fn test_fq_root_of_unity() {
0x258dd3db21a5d66b, 0x258dd3db21a5d66b,
0xd0088f51cbff34d, 0xd0088f51cbff34d,
]), ]),
Fq::two_adic_root_of_unity()
Fq::TWO_ADIC_ROOT_OF_UNITY
); );
assert_eq!( assert_eq!(
Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]),
Fq::TWO_ADIC_ROOT_OF_UNITY.pow([1 << Fq::TWO_ADICITY]),
Fq::one() Fq::one()
); );
assert!(Fq::multiplicative_generator().sqrt().is_none());
assert!(Fq::GENERATOR.sqrt().is_none());
} }
// #[test] // #[test]
@ -1173,7 +1169,7 @@ fn test_fq_root_of_unity() {
fn test_fq_ordering() { fn test_fq_ordering() {
// BigInteger384's ordering is well-tested, but we still need to make sure the // BigInteger384's ordering is well-tested, but we still need to make sure the
// Fq elements aren't being compared in Montgomery form. // Fq elements aren't being compared in Montgomery form.
for i in 0..100 {
for i in 0..100u64 {
assert!(Fq::from(BigInteger384::from(i + 1)) > Fq::from(BigInteger384::from(i))); assert!(Fq::from(BigInteger384::from(i + 1)) > Fq::from(BigInteger384::from(i)));
} }
} }
@ -1192,11 +1188,11 @@ fn test_fq_legendre() {
assert_eq!( assert_eq!(
QuadraticNonResidue, QuadraticNonResidue,
Fq::from(BigInteger384::from(2)).legendre()
Fq::from(BigInteger384::from(2u64)).legendre()
); );
assert_eq!( assert_eq!(
QuadraticResidue, QuadraticResidue,
Fq::from(BigInteger384::from(4)).legendre()
Fq::from(BigInteger384::from(4u64)).legendre()
); );
let e = BigInt::new([ let e = BigInt::new([
@ -1252,7 +1248,10 @@ fn test_fq2_basics() {
#[test] #[test]
fn test_fq2_squaring() { fn test_fq2_squaring() {
let a = Fq2::new(Fq::one(), Fq::one()).square(); // u + 1 let a = Fq2::new(Fq::one(), Fq::one()).square(); // u + 1
assert_eq!(a, Fq2::new(Fq::zero(), Fq::from(BigInteger384::from(2)),)); // 2u
assert_eq!(
a,
Fq2::new(Fq::zero(), Fq::from(BigInteger384::from(2u64)),)
); // 2u
let a = Fq2::new(Fq::zero(), Fq::one()).square(); // u let a = Fq2::new(Fq::zero(), Fq::one()).square(); // u
assert_eq!(a, { assert_eq!(a, {
@ -1737,7 +1736,7 @@ fn test_fq2_legendre() {
// i^2 = -1 // i^2 = -1
let mut m1 = -Fq2::one(); let mut m1 = -Fq2::one();
assert_eq!(QuadraticResidue, m1.legendre()); assert_eq!(QuadraticResidue, m1.legendre());
m1 = Fq6Parameters::mul_fp2_by_nonresidue(&m1);
m1 = Fq6Config::mul_fp2_by_nonresidue(&m1);
assert_eq!(QuadraticNonResidue, m1.legendre()); assert_eq!(QuadraticNonResidue, m1.legendre());
} }
@ -1750,7 +1749,7 @@ fn test_fq2_mul_nonresidue() {
for _ in 0..1000 { for _ in 0..1000 {
let mut a = Fq2::rand(&mut rng); let mut a = Fq2::rand(&mut rng);
let mut b = a; let mut b = a;
a = Fq6Parameters::mul_fp2_by_nonresidue(&a);
a = Fq6Config::mul_fp2_by_nonresidue(&a);
b.mul_assign(&nqr); b.mul_assign(&nqr);
assert_eq!(a, b); assert_eq!(a, b);
@ -1766,7 +1765,7 @@ fn test_fq6_mul_nonresidue() {
for _ in 0..1000 { for _ in 0..1000 {
let mut a = Fq6::rand(&mut rng); let mut a = Fq6::rand(&mut rng);
let mut b = a; let mut b = a;
a = Fq12Parameters::mul_fp6_by_nonresidue(&a);
a = Fq12Config::mul_fp6_by_nonresidue(&a);
b.mul_assign(&nqr); b.mul_assign(&nqr);
assert_eq!(a, b); assert_eq!(a, b);

+ 6
- 5
bls12_381/src/lib.rs

@ -9,15 +9,16 @@
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
//! This library implements the BLS12_381 curve generated by [Sean Bowe](https://electriccoin.co/blog/new-snark-curve/). //! 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.
//! 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: //! Curve information:
//! * Base field: q = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787 //! * Base field: q = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
//! * Scalar field: r = 52435875175126190479447740508185965837690552500527637822603658699938581184513
//! * Scalar field: r =
//! 52435875175126190479447740508185965837690552500527637822603658699938581184513
//! * valuation(q - 1, 2) = 1 //! * valuation(q - 1, 2) = 1
//! * valuation(r - 1, 2) = 32 //! * valuation(r - 1, 2) = 32
//! * G1 curve equation: y^2 = x^3 + 4 //! * G1 curve equation: y^2 = x^3 + 4

+ 28
- 0
bn254/scripts/base_field.sage

@ -0,0 +1,28 @@
modulus = 21888242871839275222246405745257275088696311157297823662689037894645226208583
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
bn254/scripts/scalar_field.sage

@ -0,0 +1,28 @@
modulus = 21888242871839275222246405745257275088548364400416034343698204186575808495617
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)

+ 6
- 6
bn254/src/curves/g1.rs

@ -1,5 +1,5 @@
use ark_ec::models::{ModelParameters, SWModelParameters}; use ark_ec::models::{ModelParameters, SWModelParameters};
use ark_ff::{field_new, Zero};
use ark_ff::{MontFp, Zero};
use crate::{Fq, Fr}; use crate::{Fq, Fr};
@ -14,15 +14,15 @@ impl ModelParameters for Parameters {
const COFACTOR: &'static [u64] = &[0x1]; const COFACTOR: &'static [u64] = &[0x1];
/// COFACTOR_INV = COFACTOR^{-1} mod r = 1 /// COFACTOR_INV = COFACTOR^{-1} mod r = 1
const COFACTOR_INV: Fr = field_new!(Fr, "1");
const COFACTOR_INV: Fr = MontFp!(Fr, "1");
} }
impl SWModelParameters for Parameters { impl SWModelParameters for Parameters {
/// COEFF_A = 0 /// COEFF_A = 0
const COEFF_A: Fq = field_new!(Fq, "0");
const COEFF_A: Fq = MontFp!(Fq, "0");
/// COEFF_B = 3 /// COEFF_B = 3
const COEFF_B: Fq = field_new!(Fq, "3");
const COEFF_B: Fq = MontFp!(Fq, "3");
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
@ -35,7 +35,7 @@ impl SWModelParameters for Parameters {
} }
/// G1_GENERATOR_X = 1 /// G1_GENERATOR_X = 1
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "1");
pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "1");
/// G1_GENERATOR_Y = 2 /// G1_GENERATOR_Y = 2
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "2");
pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "2");

+ 35
- 23
bn254/src/curves/g2.rs

@ -1,5 +1,5 @@
use ark_ec::models::{ModelParameters, SWModelParameters}; use ark_ec::models::{ModelParameters, SWModelParameters};
use ark_ff::{field_new, Zero};
use ark_ff::{MontFp, QuadExt, Zero};
use crate::{Fq, Fq2, Fr}; use crate::{Fq, Fq2, Fr};
@ -11,7 +11,7 @@ impl ModelParameters for Parameters {
type ScalarField = Fr; type ScalarField = Fr;
/// COFACTOR = (36 * X^4) + (36 * X^3) + (30 * X^2) + 6*X + 1 /// COFACTOR = (36 * X^4) + (36 * X^3) + (30 * X^2) + 6*X + 1
/// = 21888242871839275222246405745257275088844257914179612981679871602714643921549
/// 21888242871839275222246405745257275088844257914179612981679871602714643921549
#[rustfmt::skip] #[rustfmt::skip]
const COFACTOR: &'static [u64] = &[ const COFACTOR: &'static [u64] = &[
0x345f2299c0f9fa8d, 0x345f2299c0f9fa8d,
@ -21,21 +21,27 @@ impl ModelParameters for Parameters {
]; ];
/// COFACTOR_INV = COFACTOR^{-1} mod r /// COFACTOR_INV = COFACTOR^{-1} mod r
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, "10944121435919637613327163357776759465618812564592884533313067514031822496649");
const COFACTOR_INV: Fr = MontFp!(
Fr,
"10944121435919637613327163357776759465618812564592884533313067514031822496649"
);
} }
impl SWModelParameters for Parameters { impl SWModelParameters for Parameters {
/// COEFF_A = [0, 0] /// COEFF_A = [0, 0]
#[rustfmt::skip]
const COEFF_A: Fq2 = field_new!(Fq2, field_new!(Fq, "0"), field_new!(Fq, "0"));
const COEFF_A: Fq2 = QuadExt!(MontFp!(Fq, "0"), MontFp!(Fq, "0"));
/// COEFF_B = 3/(u+9) /// COEFF_B = 3/(u+9)
/// = (19485874751759354771024239261021720505790618469301721065564631296452457478373, 266929791119991161246907387137283842545076965332900288569378510910307636690)
#[rustfmt::skip]
const COEFF_B: Fq2 = field_new!(Fq2,
field_new!(Fq, "19485874751759354771024239261021720505790618469301721065564631296452457478373"),
field_new!(Fq, "266929791119991161246907387137283842545076965332900288569378510910307636690"),
/// (19485874751759354771024239261021720505790618469301721065564631296452457478373, 266929791119991161246907387137283842545076965332900288569378510910307636690)
const COEFF_B: Fq2 = QuadExt!(
MontFp!(
Fq,
"19485874751759354771024239261021720505790618469301721065564631296452457478373"
),
MontFp!(
Fq,
"266929791119991161246907387137283842545076965332900288569378510910307636690"
),
); );
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y) /// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
@ -48,27 +54,33 @@ impl SWModelParameters for Parameters {
} }
} }
#[rustfmt::skip]
pub const G2_GENERATOR_X: Fq2 = field_new!(Fq2, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
#[rustfmt::skip]
pub const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
pub const G2_GENERATOR_X: Fq2 = QuadExt!(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
pub const G2_GENERATOR_Y: Fq2 = QuadExt!(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
/// G2_GENERATOR_X_C0 = /// G2_GENERATOR_X_C0 =
/// 10857046999023057135944570762232829481370756359578518086990519993285655852781 /// 10857046999023057135944570762232829481370756359578518086990519993285655852781
#[rustfmt::skip]
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "10857046999023057135944570762232829481370756359578518086990519993285655852781");
pub const G2_GENERATOR_X_C0: Fq = MontFp!(
Fq,
"10857046999023057135944570762232829481370756359578518086990519993285655852781"
);
/// G2_GENERATOR_X_C1 = /// G2_GENERATOR_X_C1 =
/// 11559732032986387107991004021392285783925812861821192530917403151452391805634 /// 11559732032986387107991004021392285783925812861821192530917403151452391805634
#[rustfmt::skip]
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "11559732032986387107991004021392285783925812861821192530917403151452391805634");
pub const G2_GENERATOR_X_C1: Fq = MontFp!(
Fq,
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
);
/// G2_GENERATOR_Y_C0 = /// G2_GENERATOR_Y_C0 =
/// 8495653923123431417604973247489272438418190587263600148770280649306958101930 /// 8495653923123431417604973247489272438418190587263600148770280649306958101930
#[rustfmt::skip]
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "8495653923123431417604973247489272438418190587263600148770280649306958101930");
pub const G2_GENERATOR_Y_C0: Fq = MontFp!(
Fq,
"8495653923123431417604973247489272438418190587263600148770280649306958101930"
);
/// G2_GENERATOR_Y_C1 = /// G2_GENERATOR_Y_C1 =
/// 4082367875863433681332203403145435568316851327593401208105741076214120093531 /// 4082367875863433681332203403145435568316851327593401208105741076214120093531
#[rustfmt::skip]
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "4082367875863433681332203403145435568316851327593401208105741076214120093531");
pub const G2_GENERATOR_Y_C1: Fq = MontFp!(
Fq,
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
);

+ 13
- 13
bn254/src/curves/mod.rs

@ -1,9 +1,11 @@
use crate::*;
use ark_ec::{ use ark_ec::{
bn, bn,
bn::{Bn, BnParameters, TwistType}, bn::{Bn, BnParameters, TwistType},
}; };
use ark_ff::field_new;
use ark_ff::{MontFp, QuadExt};
use crate::*;
pub mod g1; pub mod g1;
pub mod g2; pub mod g2;
@ -22,33 +24,31 @@ impl BnParameters for Parameters {
-1, 0, 0, 1, 0, 1, 1, -1, 0, 0, 1, 0, 1, 1,
]; ];
const TWIST_MUL_BY_Q_X: Fq2 = field_new!(
Fq2,
field_new!(
const TWIST_MUL_BY_Q_X: Fq2 = QuadExt!(
MontFp!(
Fq, Fq,
"21575463638280843010398324269430826099269044274347216827212613867836435027261" "21575463638280843010398324269430826099269044274347216827212613867836435027261"
), ),
field_new!(
MontFp!(
Fq, Fq,
"10307601595873709700152284273816112264069230130616436755625194854815875713954" "10307601595873709700152284273816112264069230130616436755625194854815875713954"
), ),
); );
const TWIST_MUL_BY_Q_Y: Fq2 = field_new!(
Fq2,
field_new!(
const TWIST_MUL_BY_Q_Y: Fq2 = QuadExt!(
MontFp!(
Fq, Fq,
"2821565182194536844548159561693502659359617185244120367078079554186484126554" "2821565182194536844548159561693502659359617185244120367078079554186484126554"
), ),
field_new!(
MontFp!(
Fq, Fq,
"3505843767911556378687030309984248845540243509899259641013678093033130930403" "3505843767911556378687030309984248845540243509899259641013678093033130930403"
), ),
); );
const TWIST_TYPE: TwistType = TwistType::D; const TWIST_TYPE: TwistType = TwistType::D;
type Fp = Fq; type Fp = Fq;
type Fp2Params = Fq2Parameters;
type Fp6Params = Fq6Parameters;
type Fp12Params = Fq12Parameters;
type Fp2Config = Fq2Config;
type Fp6Config = Fq6Config;
type Fp12Config = Fq12Config;
type G1Parameters = g1::Parameters; type G1Parameters = g1::Parameters;
type G2Parameters = g2::Parameters; type G2Parameters = g2::Parameters;
} }

+ 8
- 11
bn254/src/curves/tests.rs

@ -1,18 +1,15 @@
#![allow(unused_imports)]
use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine, ProjectiveCurve};
use ark_algebra_test_templates::{
curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, groups::*, msm::*,
};
use ark_ec::{AffineCurve, PairingEngine};
use ark_ff::{ use ark_ff::{
fields::{Field, FpParameters, PrimeField, SquareRootField},
One, Zero,
fields::{Field, PrimeField},
One,
}; };
use ark_serialize::CanonicalSerialize;
use ark_std::{rand::Rng, test_rng}; use ark_std::{rand::Rng, test_rng};
use core::ops::{AddAssign, MulAssign};
use crate::{g1, g2, Bn254, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
use core::ops::MulAssign;
use ark_algebra_test_templates::{
curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, groups::*, msm::*,
};
use crate::{g1, g2, Bn254, Fq12, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
generate_g1_test!(bn254; curve_tests; sw_tests;); generate_g1_test!(bn254; curve_tests; sw_tests;);
generate_g2_test!(bn254; curve_tests; sw_tests;); generate_g2_test!(bn254; curve_tests; sw_tests;);

+ 8
- 98
bn254/src/fields/fq.rs

@ -1,100 +1,10 @@
use ark_ff::{
biginteger::{BigInt, BigInteger256 as BigInteger},
field_new,
fields::*,
};
use ark_ff::fields::{Fp256, MontBackend, MontConfig, MontFp};
pub type Fq = Fp256<FqParameters>;
#[derive(MontConfig)]
#[modulus = "21888242871839275222246405745257275088696311157297823662689037894645226208583"]
#[generator = "3"]
pub struct FqConfig;
pub type Fq = Fp256<MontBackend<FqConfig, 4>>;
pub struct FqParameters;
impl Fp256Parameters for FqParameters {}
impl FftParameters for FqParameters {
type BigInt = BigInteger;
const TWO_ADICITY: u32 = 1;
#[rustfmt::skip]
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([
0x68c3488912edefaa,
0x8d087f6872aabf4f,
0x51e1a24709081231,
0x2259d6b14729c0fa,
]);
}
impl FpParameters for FqParameters {
/// MODULUS = 21888242871839275222246405745257275088696311157297823662689037894645226208583
#[rustfmt::skip]
const MODULUS: BigInteger = BigInt::new([
0x3c208c16d87cfd47,
0x97816a916871ca8d,
0xb85045b68181585d,
0x30644e72e131a029,
]);
const MODULUS_BITS: u32 = 254;
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
const REPR_SHAVE_BITS: u32 = 2;
#[rustfmt::skip]
const R: BigInteger = BigInt::new([
0xd35d438dc58f0d9d,
0x0a78eb28f5c70b3d,
0x666ea36f7879462c,
0xe0a77c19a07df2f,
]);
#[rustfmt::skip]
const R2: BigInteger = BigInt::new([
0xf32cfc5b538afa89,
0xb5e71911d44501fb,
0x47ab1eff0a417ff6,
0x6d89f71cab8351f,
]);
const INV: u64 = 9786893198990664585u64;
// GENERATOR = 3
#[rustfmt::skip]
const GENERATOR: BigInteger = BigInt::new([
0x7a17caa950ad28d7,
0x1f6ac17ae15521b9,
0x334bea4e696bd284,
0x2a1f6744ce179d8e,
]);
#[rustfmt::skip]
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0x9e10460b6c3e7ea3,
0xcbc0b548b438e546,
0xdc2822db40c0ac2e,
0x183227397098d014,
]);
// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T
// T = (MODULUS - 1) // 2^S =
// 10944121435919637611123202872628637544348155578648911831344518947322613104291
#[rustfmt::skip]
const T: BigInteger = BigInt::new([
0x9e10460b6c3e7ea3,
0xcbc0b548b438e546,
0xdc2822db40c0ac2e,
0x183227397098d014,
]);
// (T - 1) // 2 =
// 5472060717959818805561601436314318772174077789324455915672259473661306552145
#[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0x4f082305b61f3f51,
0x65e05aa45a1c72a3,
0x6e14116da0605617,
0xc19139cb84c680a,
]);
}
pub const FQ_ONE: Fq = field_new!(Fq, "1");
pub const FQ_ZERO: Fq = field_new!(Fq, "0");
pub const FQ_ONE: Fq = MontFp!(Fq, "1");
pub const FQ_ZERO: Fq = MontFp!(Fq, "0");

+ 88
- 46
bn254/src/fields/fq12.rs

@ -1,77 +1,119 @@
use super::*;
use ark_ff::{field_new, fields::*};
use ark_ff::{fields::*, CubicExt, MontFp, QuadExt};
pub type Fq12 = Fp12<Fq12Parameters>;
use crate::*;
pub type Fq12 = Fp12<Fq12Config>;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Fq12Parameters;
pub struct Fq12Config;
impl Fp12Parameters for Fq12Parameters {
type Fp6Params = Fq6Parameters;
impl Fp12Config for Fq12Config {
type Fp6Config = Fq6Config;
const NONRESIDUE: Fq6 = field_new!(Fq6, FQ2_ZERO, FQ2_ONE, FQ2_ZERO);
const NONRESIDUE: Fq6 = CubicExt!(FQ2_ZERO, FQ2_ONE, FQ2_ZERO);
#[rustfmt::skip]
const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[ const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[
// Fp2::NONRESIDUE^(((q^0) - 1) / 6) // Fp2::NONRESIDUE^(((q^0) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "1"),
field_new!(Fq, "0"),
),
QuadExt!(MontFp!(Fq, "1"), MontFp!(Fq, "0"),),
// Fp2::NONRESIDUE^(((q^1) - 1) / 6) // Fp2::NONRESIDUE^(((q^1) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "8376118865763821496583973867626364092589906065868298776909617916018768340080"),
field_new!(Fq, "16469823323077808223889137241176536799009286646108169935659301613961712198316"),
QuadExt!(
MontFp!(
Fq,
"8376118865763821496583973867626364092589906065868298776909617916018768340080"
),
MontFp!(
Fq,
"16469823323077808223889137241176536799009286646108169935659301613961712198316"
),
), ),
// Fp2::NONRESIDUE^(((q^2) - 1) / 6) // Fp2::NONRESIDUE^(((q^2) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556617"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(
Fq,
"21888242871839275220042445260109153167277707414472061641714758635765020556617"
),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^3) - 1) / 6) // Fp2::NONRESIDUE^(((q^3) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "11697423496358154304825782922584725312912383441159505038794027105778954184319"),
field_new!(Fq, "303847389135065887422783454877609941456349188919719272345083954437860409601"),
QuadExt!(
MontFp!(
Fq,
"11697423496358154304825782922584725312912383441159505038794027105778954184319"
),
MontFp!(
Fq,
"303847389135065887422783454877609941456349188919719272345083954437860409601"
),
), ),
// Fp2::NONRESIDUE^(((q^4) - 1) / 6) // Fp2::NONRESIDUE^(((q^4) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556616"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(
Fq,
"21888242871839275220042445260109153167277707414472061641714758635765020556616"
),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^5) - 1) / 6) // Fp2::NONRESIDUE^(((q^5) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "3321304630594332808241809054958361220322477375291206261884409189760185844239"),
field_new!(Fq, "5722266937896532885780051958958348231143373700109372999374820235121374419868"),
QuadExt!(
MontFp!(
Fq,
"3321304630594332808241809054958361220322477375291206261884409189760185844239"
),
MontFp!(
Fq,
"5722266937896532885780051958958348231143373700109372999374820235121374419868"
),
), ),
// Fp2::NONRESIDUE^(((q^6) - 1) / 6) // Fp2::NONRESIDUE^(((q^6) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "-1"),
field_new!(Fq, "0"),
),
QuadExt!(MontFp!(Fq, "-1"), MontFp!(Fq, "0"),),
// Fp2::NONRESIDUE^(((q^7) - 1) / 6) // Fp2::NONRESIDUE^(((q^7) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "13512124006075453725662431877630910996106405091429524885779419978626457868503"),
field_new!(Fq, "5418419548761466998357268504080738289687024511189653727029736280683514010267"),
QuadExt!(
MontFp!(
Fq,
"13512124006075453725662431877630910996106405091429524885779419978626457868503"
),
MontFp!(
Fq,
"5418419548761466998357268504080738289687024511189653727029736280683514010267"
),
), ),
// Fp2::NONRESIDUE^(((q^8) - 1) / 6) // Fp2::NONRESIDUE^(((q^8) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "2203960485148121921418603742825762020974279258880205651966"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(
Fq,
"2203960485148121921418603742825762020974279258880205651966"
),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^9) - 1) / 6) // Fp2::NONRESIDUE^(((q^9) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "10190819375481120917420622822672549775783927716138318623895010788866272024264"),
field_new!(Fq, "21584395482704209334823622290379665147239961968378104390343953940207365798982"),
QuadExt!(
MontFp!(
Fq,
"10190819375481120917420622822672549775783927716138318623895010788866272024264"
),
MontFp!(
Fq,
"21584395482704209334823622290379665147239961968378104390343953940207365798982"
),
), ),
// Fp2::NONRESIDUE^(((q^10) - 1) / 6) // Fp2::NONRESIDUE^(((q^10) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "2203960485148121921418603742825762020974279258880205651967"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(
Fq,
"2203960485148121921418603742825762020974279258880205651967"
),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^11) - 1) / 6) // Fp2::NONRESIDUE^(((q^11) - 1) / 6)
field_new!(Fq2,
field_new!(Fq, "18566938241244942414004596690298913868373833782006617400804628704885040364344"),
field_new!(Fq, "16165975933942742336466353786298926857552937457188450663314217659523851788715"),
QuadExt!(
MontFp!(
Fq,
"18566938241244942414004596690298913868373833782006617400804628704885040364344"
),
MontFp!(
Fq,
"16165975933942742336466353786298926857552937457188450663314217659523851788715"
),
), ),
]; ];
} }

+ 12
- 17
bn254/src/fields/fq2.rs

@ -1,31 +1,26 @@
use super::*;
use ark_ff::{field_new, fields::*};
use ark_ff::{fields::*, MontFp, QuadExt};
pub type Fq2 = Fp2<Fq2Parameters>;
use crate::*;
pub struct Fq2Parameters;
pub type Fq2 = Fp2<Fq2Config>;
impl Fp2Parameters for Fq2Parameters {
pub struct Fq2Config;
impl Fp2Config for Fq2Config {
type Fp = Fq; type Fp = Fq;
/// NONRESIDUE = -1 /// NONRESIDUE = -1
#[rustfmt::skip]
const NONRESIDUE: Fq = field_new!(Fq, "-1");
const NONRESIDUE: Fq = MontFp!(Fq, "-1");
/// QUADRATIC_NONRESIDUE = U+2 /// QUADRATIC_NONRESIDUE = U+2
#[rustfmt::skip]
const QUADRATIC_NONRESIDUE: (Fq, Fq) = (
field_new!(Fq, "2"),
field_new!(Fq, "1"),
);
const QUADRATIC_NONRESIDUE: Fq2 = QuadExt!(MontFp!(Fq, "2"), MontFp!(Fq, "1"));
/// Coefficients for the Frobenius automorphism. /// Coefficients for the Frobenius automorphism.
#[rustfmt::skip]
const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[ const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[
// NONRESIDUE**(((q^0) - 1) / 2) // NONRESIDUE**(((q^0) - 1) / 2)
field_new!(Fq, "1"),
MontFp!(Fq, "1"),
// NONRESIDUE**(((q^1) - 1) / 2) // NONRESIDUE**(((q^1) - 1) / 2)
field_new!(Fq, "-1"),
MontFp!(Fq, "-1"),
]; ];
#[inline(always)] #[inline(always)]
@ -34,5 +29,5 @@ impl Fp2Parameters for Fq2Parameters {
} }
} }
pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO);
pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO);
pub const FQ2_ZERO: Fq2 = QuadExt!(FQ_ZERO, FQ_ZERO);
pub const FQ2_ONE: Fq2 = QuadExt!(FQ_ONE, FQ_ZERO);

+ 91
- 50
bn254/src/fields/fq6.rs

@ -1,82 +1,123 @@
use super::*;
use ark_ff::{field_new, fields::*};
use ark_ff::{fields::*, MontFp, QuadExt};
pub type Fq6 = Fp6<Fq6Parameters>;
use crate::*;
pub type Fq6 = Fp6<Fq6Config>;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Fq6Parameters;
pub struct Fq6Config;
impl Fp6Parameters for Fq6Parameters {
type Fp2Params = Fq2Parameters;
impl Fp6Config for Fq6Config {
type Fp2Config = Fq2Config;
/// NONRESIDUE = U+9 /// NONRESIDUE = U+9
#[rustfmt::skip]
const NONRESIDUE: Fq2 = field_new!(Fq2, field_new!(Fq, "9"), field_new!(Fq, "1"));
const NONRESIDUE: Fq2 = QuadExt!(MontFp!(Fq, "9"), MontFp!(Fq, "1"));
#[rustfmt::skip]
const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[ const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[
// Fp2::NONRESIDUE^(((q^0) - 1) / 3) // Fp2::NONRESIDUE^(((q^0) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "1"),
field_new!(Fq, "0"),
),
QuadExt!(MontFp!(Fq, "1"), MontFp!(Fq, "0"),),
// Fp2::NONRESIDUE^(((q^1) - 1) / 3) // Fp2::NONRESIDUE^(((q^1) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "21575463638280843010398324269430826099269044274347216827212613867836435027261"),
field_new!(Fq, "10307601595873709700152284273816112264069230130616436755625194854815875713954"),
QuadExt!(
MontFp!(
Fq,
"21575463638280843010398324269430826099269044274347216827212613867836435027261"
),
MontFp!(
Fq,
"10307601595873709700152284273816112264069230130616436755625194854815875713954"
),
), ),
// Fp2::NONRESIDUE^(((q^2) - 1) / 3) // Fp2::NONRESIDUE^(((q^2) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556616"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(
Fq,
"21888242871839275220042445260109153167277707414472061641714758635765020556616"
),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^3) - 1) / 3) // Fp2::NONRESIDUE^(((q^3) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "3772000881919853776433695186713858239009073593817195771773381919316419345261"),
field_new!(Fq, "2236595495967245188281701248203181795121068902605861227855261137820944008926"),
QuadExt!(
MontFp!(
Fq,
"3772000881919853776433695186713858239009073593817195771773381919316419345261"
),
MontFp!(
Fq,
"2236595495967245188281701248203181795121068902605861227855261137820944008926"
),
), ),
// Fp2::NONRESIDUE^(((q^4) - 1) / 3) // Fp2::NONRESIDUE^(((q^4) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "2203960485148121921418603742825762020974279258880205651966"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(
Fq,
"2203960485148121921418603742825762020974279258880205651966"
),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^(((q^5) - 1) / 3) // Fp2::NONRESIDUE^(((q^5) - 1) / 3)
field_new!(Fq2,
field_new!(Fq, "18429021223477853657660792034369865839114504446431234726392080002137598044644"),
field_new!(Fq, "9344045779998320333812420223237981029506012124075525679208581902008406485703"),
QuadExt!(
MontFp!(
Fq,
"18429021223477853657660792034369865839114504446431234726392080002137598044644"
),
MontFp!(
Fq,
"9344045779998320333812420223237981029506012124075525679208581902008406485703"
),
), ),
]; ];
#[rustfmt::skip]
const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[ const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[
// Fp2::NONRESIDUE^((2*(q^0) - 2) / 3) // Fp2::NONRESIDUE^((2*(q^0) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "1"),
field_new!(Fq, "0"),
),
QuadExt!(MontFp!(Fq, "1"), MontFp!(Fq, "0"),),
// Fp2::NONRESIDUE^((2*(q^1) - 2) / 3) // Fp2::NONRESIDUE^((2*(q^1) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "2581911344467009335267311115468803099551665605076196740867805258568234346338"),
field_new!(Fq, "19937756971775647987995932169929341994314640652964949448313374472400716661030"),
QuadExt!(
MontFp!(
Fq,
"2581911344467009335267311115468803099551665605076196740867805258568234346338"
),
MontFp!(
Fq,
"19937756971775647987995932169929341994314640652964949448313374472400716661030"
),
), ),
// Fp2::NONRESIDUE^((2*(q^2) - 2) / 3) // Fp2::NONRESIDUE^((2*(q^2) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "2203960485148121921418603742825762020974279258880205651966"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(
Fq,
"2203960485148121921418603742825762020974279258880205651966"
),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^((2*(q^3) - 2) / 3) // Fp2::NONRESIDUE^((2*(q^3) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "5324479202449903542726783395506214481928257762400643279780343368557297135718"),
field_new!(Fq, "16208900380737693084919495127334387981393726419856888799917914180988844123039"),
QuadExt!(
MontFp!(
Fq,
"5324479202449903542726783395506214481928257762400643279780343368557297135718"
),
MontFp!(
Fq,
"16208900380737693084919495127334387981393726419856888799917914180988844123039"
),
), ),
// Fp2::NONRESIDUE^((2*(q^4) - 2) / 3) // Fp2::NONRESIDUE^((2*(q^4) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556616"),
field_new!(Fq, "0"),
QuadExt!(
MontFp!(
Fq,
"21888242871839275220042445260109153167277707414472061641714758635765020556616"
),
MontFp!(Fq, "0"),
), ),
// Fp2::NONRESIDUE^((2*(q^5) - 2) / 3) // Fp2::NONRESIDUE^((2*(q^5) - 2) / 3)
field_new!(Fq2,
field_new!(Fq, "13981852324922362344252311234282257507216387789820983642040889267519694726527"),
field_new!(Fq, "7629828391165209371577384193250820201684255241773809077146787135900891633097"),
QuadExt!(
MontFp!(
Fq,
"13981852324922362344252311234282257507216387789820983642040889267519694726527"
),
MontFp!(
Fq,
"7629828391165209371577384193250820201684255241773809077146787135900891633097"
),
), ),
]; ];
@ -85,8 +126,8 @@ impl Fp6Parameters for Fq6Parameters {
// (c0+u*c1)*(9+u) = (9*c0-c1)+u*(9*c1+c0) // (c0+u*c1)*(9+u) = (9*c0-c1)+u*(9*c1+c0)
let mut f = *fe; let mut f = *fe;
f.double_in_place().double_in_place().double_in_place(); f.double_in_place().double_in_place().double_in_place();
let c0 = f.c0 + fe.c0 + Fq2Parameters::mul_fp_by_nonresidue(&fe.c1);
let c0 = f.c0 + fe.c0 + Fq2Config::mul_fp_by_nonresidue(&fe.c1);
let c1 = f.c1 + fe.c1 + fe.c0; let c1 = f.c1 + fe.c1 + fe.c0;
field_new!(Fq2, c0, c1)
QuadExt!(c0, c1)
} }
} }

+ 6
- 102
bn254/src/fields/fr.rs

@ -1,103 +1,7 @@
use ark_ff::{
biginteger::{BigInt, BigInteger256 as BigInteger},
fields::*,
};
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
pub type Fr = Fp256<FrParameters>;
pub struct FrParameters;
impl Fp256Parameters for FrParameters {}
impl FftParameters for FrParameters {
type BigInt = BigInteger;
const TWO_ADICITY: u32 = 28;
#[rustfmt::skip]
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([
7164790868263648668u64,
11685701338293206998u64,
6216421865291908056u64,
1756667274303109607u64,
]);
}
impl FpParameters for FrParameters {
/// MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617
#[rustfmt::skip]
const MODULUS: BigInteger = BigInt::new([
4891460686036598785u64,
2896914383306846353u64,
13281191951274694749u64,
3486998266802970665u64,
]);
const MODULUS_BITS: u32 = 254;
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
const REPR_SHAVE_BITS: u32 = 2;
/// R = pow(2, 256) % MODULUS
/// = 6350874878119819312338956282401532410528162663560392320966563075034087161851
#[rustfmt::skip]
const R: BigInteger = BigInt::new([
12436184717236109307u64,
3962172157175319849u64,
7381016538464732718u64,
1011752739694698287u64,
]);
/// R2 = R * R % MODULUS
/// = 944936681149208446651664254269745548490766851729442924617792859073125903783
#[rustfmt::skip]
const R2: BigInteger = BigInt::new([
1997599621687373223u64,
6052339484930628067u64,
10108755138030829701u64,
150537098327114917u64,
]);
/// INV = (-MODULUS) ^ {-1} % pow(2, 64) = 14042775128853446655
const INV: u64 = 14042775128853446655u64;
/// GENERATOR = 5
#[rustfmt::skip]
const GENERATOR: BigInteger = BigInt::new([
1949230679015292902u64,
16913946402569752895u64,
5177146667339417225u64,
1571765431670520771u64,
]);
/// (MODULUS - 1)/2 =
/// 10944121435919637611123202872628637544274182200208017171849102093287904247808
#[rustfmt::skip]
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0xa1f0fac9f8000000,
0x9419f4243cdcb848,
0xdc2822db40c0ac2e,
0x183227397098d014,
]);
// T and T_MINUS_ONE_DIV_TWO, where r - 1 = 2^s * t
/// T = (MODULUS - 1) / 2^s =
/// 81540058820840996586704275553141814055101440848469862132140264610111
#[rustfmt::skip]
const T: BigInteger = BigInt::new([
0x9b9709143e1f593f,
0x181585d2833e8487,
0x131a029b85045b68,
0x30644e72e,
]);
/// (T - 1) / 2 =
/// 40770029410420498293352137776570907027550720424234931066070132305055
#[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0xcdcb848a1f0fac9f,
0x0c0ac2e9419f4243,
0x098d014dc2822db4,
0x183227397,
]);
}
#[derive(MontConfig)]
#[modulus = "21888242871839275222246405745257275088548364400416034343698204186575808495617"]
#[generator = "5"]
pub struct FrConfig;
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;

+ 26
- 30
bn254/src/fields/tests.rs

@ -1,9 +1,9 @@
use ark_algebra_test_templates::{
fields::*, generate_field_serialization_test, generate_field_test,
};
use ark_ff::{ use ark_ff::{
biginteger::{BigInt, BigInteger, BigInteger256}, biginteger::{BigInt, BigInteger, BigInteger256},
fields::{
fp6_3over2::Fp6Parameters, FftField, FftParameters, Field, FpParameters, PrimeField,
SquareRootField,
},
fields::{FftField, Field, Fp6Config, PrimeField, SquareRootField},
One, UniformRand, Zero, One, UniformRand, Zero,
}; };
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
@ -13,12 +13,9 @@ use core::{
ops::{AddAssign, MulAssign, SubAssign}, ops::{AddAssign, MulAssign, SubAssign},
}; };
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Parameters, FqParameters, Fr};
use ark_algebra_test_templates::{
fields::*, generate_field_serialization_test, generate_field_test,
};
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Config, FqConfig, Fr, FrConfig};
generate_field_test!(bn254; fq2; fq6; fq12;);
generate_field_test!(bn254; fq2; fq6; fq12; mont(4, 4); );
generate_field_serialization_test!(bn254; fq2; fq6; fq12;); generate_field_serialization_test!(bn254; fq2; fq6; fq12;);
#[test] #[test]
@ -28,14 +25,14 @@ fn test_fq_repr_from() {
#[test] #[test]
fn test_fq_repr_is_odd() { fn test_fq_repr_is_odd() {
assert!(!BigInteger256::from(0).is_odd());
assert!(BigInteger256::from(0).is_even());
assert!(BigInteger256::from(1).is_odd());
assert!(!BigInteger256::from(1).is_even());
assert!(!BigInteger256::from(324834872).is_odd());
assert!(BigInteger256::from(324834872).is_even());
assert!(BigInteger256::from(324834873).is_odd());
assert!(!BigInteger256::from(324834873).is_even());
assert!(!BigInteger256::from(0u64).is_odd());
assert!(BigInteger256::from(0u64).is_even());
assert!(BigInteger256::from(1u64).is_odd());
assert!(!BigInteger256::from(1u64).is_even());
assert!(!BigInteger256::from(324834872u64).is_odd());
assert!(BigInteger256::from(324834872u64).is_even());
assert!(BigInteger256::from(324834873u64).is_odd());
assert!(!BigInteger256::from(324834873u64).is_even());
} }
#[test] #[test]
@ -47,9 +44,9 @@ fn test_fq_repr_is_zero() {
#[test] #[test]
fn test_fq_repr_num_bits() { fn test_fq_repr_num_bits() {
let mut a = BigInteger256::from(0);
let mut a = BigInteger256::from(0u64);
assert_eq!(0, a.num_bits()); assert_eq!(0, a.num_bits());
a = BigInteger256::from(1);
a = BigInteger256::from(1u64);
for i in 1..257 { for i in 1..257 {
assert_eq!(i, a.num_bits()); assert_eq!(i, a.num_bits());
a.mul2(); a.mul2();
@ -59,34 +56,33 @@ fn test_fq_repr_num_bits() {
#[test] #[test]
fn test_fq_num_bits() { fn test_fq_num_bits() {
assert_eq!(FqParameters::MODULUS_BITS, 254);
assert_eq!(FqParameters::CAPACITY, 253);
assert_eq!(Fq::MODULUS_BIT_SIZE, 254);
} }
#[test] #[test]
fn test_fq_root_of_unity() { fn test_fq_root_of_unity() {
assert_eq!(FqParameters::TWO_ADICITY, 1);
assert_eq!(Fq::TWO_ADICITY, 1);
assert_eq!( assert_eq!(
Fq::multiplicative_generator().pow([
Fq::GENERATOR.pow([
0x9e10460b6c3e7ea3, 0x9e10460b6c3e7ea3,
0xcbc0b548b438e546, 0xcbc0b548b438e546,
0xdc2822db40c0ac2e, 0xdc2822db40c0ac2e,
0x183227397098d014, 0x183227397098d014,
]), ]),
Fq::two_adic_root_of_unity()
Fq::TWO_ADIC_ROOT_OF_UNITY
); );
assert_eq!( assert_eq!(
Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]),
Fq::TWO_ADIC_ROOT_OF_UNITY.pow([1 << Fq::TWO_ADICITY]),
Fq::one() Fq::one()
); );
assert!(Fq::multiplicative_generator().sqrt().is_none());
assert!(Fq::GENERATOR.sqrt().is_none());
} }
#[test] #[test]
fn test_fq_ordering() { fn test_fq_ordering() {
// BigInteger256's ordering is well-tested, but we still need to make sure the // BigInteger256's ordering is well-tested, but we still need to make sure the
// Fq elements aren't being compared in Montgomery form. // Fq elements aren't being compared in Montgomery form.
for i in 0..100 {
for i in 0..100u64 {
assert!(Fq::from(BigInteger256::from(i + 1)) > Fq::from(BigInteger256::from(i))); assert!(Fq::from(BigInteger256::from(i + 1)) > Fq::from(BigInteger256::from(i)));
} }
} }
@ -99,11 +95,11 @@ fn test_fq_legendre() {
assert_eq!(Zero, Fq::zero().legendre()); assert_eq!(Zero, Fq::zero().legendre());
assert_eq!( assert_eq!(
QuadraticResidue, QuadraticResidue,
Fq::from(BigInteger256::from(4)).legendre()
Fq::from(BigInteger256::from(4u64)).legendre()
); );
assert_eq!( assert_eq!(
QuadraticNonResidue, QuadraticNonResidue,
Fq::from(BigInteger256::from(5)).legendre()
Fq::from(BigInteger256::from(5u64)).legendre()
); );
} }
@ -144,7 +140,7 @@ fn test_fq2_legendre() {
// i^2 = -1 // i^2 = -1
let mut m1 = -Fq2::one(); let mut m1 = -Fq2::one();
assert_eq!(QuadraticResidue, m1.legendre()); assert_eq!(QuadraticResidue, m1.legendre());
m1 = Fq6Parameters::mul_fp2_by_nonresidue(&m1);
m1 = Fq6Config::mul_fp2_by_nonresidue(&m1);
assert_eq!(QuadraticNonResidue, m1.legendre()); assert_eq!(QuadraticNonResidue, m1.legendre());
} }

+ 7
- 4
bn254/src/lib.rs

@ -20,14 +20,17 @@
//! //!
//! //!
//! Curve information: //! Curve information:
//! * Base field: q = 21888242871839275222246405745257275088696311157297823662689037894645226208583
//! * Scalar field: r = 21888242871839275222246405745257275088548364400416034343698204186575808495617
//! * Base field: q =
//! 21888242871839275222246405745257275088696311157297823662689037894645226208583
//! * Scalar field: r =
//! 21888242871839275222246405745257275088548364400416034343698204186575808495617
//! * valuation(q - 1, 2) = 1 //! * valuation(q - 1, 2) = 1
//! * valuation(r - 1, 2) = 28 //! * valuation(r - 1, 2) = 28
//! * G1 curve equation: y^2 = x^3 + 3 //! * G1 curve equation: y^2 = x^3 + 3
//! * G2 curve equation: y^2 = x^3 + B, where //! * G2 curve equation: y^2 = x^3 + B, where
//! * B = 3/(u+9) where Fq2 is represented as Fq\[u\]/(u^2+1)
//! = Fq2(19485874751759354771024239261021720505790618469301721065564631296452457478373, 266929791119991161246907387137283842545076965332900288569378510910307636690)
//! * B = 3/(u+9) where Fq2 is represented as Fq\[u\]/(u^2+1) =
//! Fq2(19485874751759354771024239261021720505790618469301721065564631296452457478373,
//! 266929791119991161246907387137283842545076965332900288569378510910307636690)
#[cfg(feature = "curve")] #[cfg(feature = "curve")]
mod curves; mod curves;

+ 28
- 0
bw6_761/scripts/base_field.sage

@ -0,0 +1,28 @@
modulus = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299
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_761/scripts/scalar_field.sage

@ -0,0 +1,28 @@
modulus = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
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)

+ 8
- 13
bw6_761/src/curves/g1.rs

@ -1,9 +1,10 @@
use crate::{Fq, Fr};
use ark_ec::{ use ark_ec::{
models::{ModelParameters, SWModelParameters}, models::{ModelParameters, SWModelParameters},
short_weierstrass_jacobian::{GroupAffine, GroupProjective}, short_weierstrass_jacobian::{GroupAffine, GroupProjective},
}; };
use ark_ff::field_new;
use ark_ff::MontFp;
use crate::{Fq, Fr};
pub type G1Affine = GroupAffine<Parameters>; pub type G1Affine = GroupAffine<Parameters>;
pub type G1Projective = GroupProjective<Parameters>; pub type G1Projective = GroupProjective<Parameters>;
@ -29,19 +30,15 @@ impl ModelParameters for Parameters {
/// COFACTOR^(-1) mod r = /// COFACTOR^(-1) mod r =
/// 91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804 /// 91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, "91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804");
const COFACTOR_INV: Fr = MontFp!(Fr, "91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804");
} }
impl SWModelParameters for Parameters { impl SWModelParameters for Parameters {
/// COEFF_A = 0 /// COEFF_A = 0
#[rustfmt::skip]
const COEFF_A: Fq = field_new!(Fq, "0");
const COEFF_A: Fq = MontFp!(Fq, "0");
/// COEFF_B = -1 /// COEFF_B = -1
#[rustfmt::skip]
const COEFF_B: Fq = field_new!(Fq, "-1");
const COEFF_B: Fq = MontFp!(Fq, "-1");
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
@ -55,10 +52,8 @@ impl SWModelParameters for Parameters {
/// G1_GENERATOR_X = /// G1_GENERATOR_X =
/// 6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237 /// 6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237
#[rustfmt::skip]
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237");
pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237");
/// G1_GENERATOR_Y = /// G1_GENERATOR_Y =
/// 2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099 /// 2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099
#[rustfmt::skip]
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099");
pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099");

+ 9
- 13
bw6_761/src/curves/g2.rs

@ -1,9 +1,10 @@
use crate::{Fq, Fr};
use ark_ec::{ use ark_ec::{
models::{ModelParameters, SWModelParameters}, models::{ModelParameters, SWModelParameters},
short_weierstrass_jacobian::{GroupAffine, GroupProjective}, short_weierstrass_jacobian::{GroupAffine, GroupProjective},
}; };
use ark_ff::field_new;
use ark_ff::MontFp;
use crate::{Fq, Fr};
pub type G2Affine = GroupAffine<Parameters>; pub type G2Affine = GroupAffine<Parameters>;
pub type G2Projective = GroupProjective<Parameters>; pub type G2Projective = GroupProjective<Parameters>;
@ -29,23 +30,20 @@ impl ModelParameters for Parameters {
/// COFACTOR^(-1) mod r = /// COFACTOR^(-1) mod r =
/// 214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124 /// 214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, "214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124");
const COFACTOR_INV: Fr = MontFp!(Fr, "214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124");
} }
impl SWModelParameters for Parameters { impl SWModelParameters for Parameters {
/// COEFF_A = 0 /// COEFF_A = 0
#[rustfmt::skip]
const COEFF_A: Fq = field_new!(Fq, "0");
const COEFF_A: Fq = MontFp!(Fq, "0");
/// COEFF_B = 4 /// COEFF_B = 4
#[rustfmt::skip]
const COEFF_B: Fq = field_new!(Fq, "4");
const COEFF_B: Fq = MontFp!(Fq, "4");
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y) /// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
(G2_GENERATOR_X, G2_GENERATOR_Y); (G2_GENERATOR_X, G2_GENERATOR_Y);
#[inline(always)] #[inline(always)]
fn mul_by_a(_elem: &Self::BaseField) -> Self::BaseField { fn mul_by_a(_elem: &Self::BaseField) -> Self::BaseField {
use ark_ff::Zero; use ark_ff::Zero;
@ -55,10 +53,8 @@ impl SWModelParameters for Parameters {
/// G2_GENERATOR_X = /// G2_GENERATOR_X =
/// 6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428 /// 6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428
#[rustfmt::skip]
pub const G2_GENERATOR_X: Fq = field_new!(Fq, "6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428");
pub const G2_GENERATOR_X: Fq = MontFp!(Fq, "6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428");
/// G2_GENERATOR_Y = /// G2_GENERATOR_Y =
/// 562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041 /// 562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041
#[rustfmt::skip]
pub const G2_GENERATOR_Y: Fq = field_new!(Fq, "562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041");
pub const G2_GENERATOR_Y: Fq = MontFp!(Fq, "562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041");

+ 4
- 3
bw6_761/src/curves/mod.rs

@ -1,10 +1,11 @@
use crate::*;
use ark_ec::{ use ark_ec::{
bw6, bw6,
bw6::{BW6Parameters, TwistType, BW6}, bw6::{BW6Parameters, TwistType, BW6},
}; };
use ark_ff::{biginteger::BigInteger768 as BigInteger, BigInt}; use ark_ff::{biginteger::BigInteger768 as BigInteger, BigInt};
use crate::*;
pub mod g1; pub mod g1;
pub mod g2; pub mod g2;
@ -47,8 +48,8 @@ impl BW6Parameters for Parameters {
const ATE_LOOP_COUNT_2_IS_NEGATIVE: bool = false; const ATE_LOOP_COUNT_2_IS_NEGATIVE: bool = false;
const TWIST_TYPE: TwistType = TwistType::M; const TWIST_TYPE: TwistType = TwistType::M;
type Fp = Fq; type Fp = Fq;
type Fp3Params = Fq3Parameters;
type Fp6Params = Fq6Parameters;
type Fp3Config = Fq3Config;
type Fp6Config = Fq6Config;
type G1Parameters = g1::Parameters; type G1Parameters = g1::Parameters;
type G2Parameters = g2::Parameters; type G2Parameters = g2::Parameters;
} }

+ 4
- 6
bw6_761/src/curves/tests.rs

@ -1,15 +1,13 @@
use ark_algebra_test_templates::{
curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, groups::*, msm::*,
};
use ark_ec::{AffineCurve, PairingEngine}; use ark_ec::{AffineCurve, PairingEngine};
use ark_ff::{Field, One, PrimeField}; use ark_ff::{Field, One, PrimeField};
use ark_std::{rand::Rng, test_rng}; use ark_std::{rand::Rng, test_rng};
use core::ops::MulAssign;
use crate::*; use crate::*;
use ark_algebra_test_templates::{
curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, groups::*, msm::*,
};
use core::ops::MulAssign;
generate_g1_test!(bw6_761; curve_tests; sw_tests;); generate_g1_test!(bw6_761; curve_tests; sw_tests;);
generate_g2_test!(bw6_761; curve_tests; sw_tests;); generate_g2_test!(bw6_761; curve_tests; sw_tests;);
generate_bilinearity_test!(BW6_761, Fq6); generate_bilinearity_test!(BW6_761, Fq6);

+ 8
- 173
bw6_761/src/fields/fq.rs

@ -1,175 +1,10 @@
use ark_ff::{
biginteger::{BigInt, BigInteger768 as BigInteger},
field_new,
fields::{FftParameters, Fp768, Fp768Parameters, FpParameters},
};
use ark_ff::fields::{Fp768, MontBackend, MontConfig, MontFp};
pub type Fq = Fp768<FqParameters>;
#[derive(MontConfig)]
#[modulus = "6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299"]
#[generator = "2"]
pub struct FqConfig;
pub type Fq = Fp768<MontBackend<FqConfig, 12>>;
pub struct FqParameters;
pub const FQ_ONE: Fq = field_new!(Fq, "1");
pub const FQ_ZERO: Fq = field_new!(Fq, "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 = BigInt::new([
17481284903592032950u64,
10104133845767975835u64,
8607375506753517913u64,
13706168424391191299u64,
9580010308493592354u64,
14241333420363995524u64,
6665632285037357566u64,
5559902898979457045u64,
15504799981718861253u64,
8332096944629367896u64,
18005297320867222879u64,
58811391084848524u64,
]);
}
impl FpParameters for FqParameters {
/// MODULUS = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299
#[rustfmt::skip]
const MODULUS: BigInteger = BigInt::new([
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 = BigInt::new([
144959613005956565u64,
6509995272855063783u64,
11428286765660613342u64,
15738672438262922740u64,
17071399330169272331u64,
13899911246788437003u64,
12055474021000362245u64,
2545351818702954755u64,
8887388221587179644u64,
5009280847225881135u64,
15539704305423854047u64,
23071597697427581u64,
]);
// R^2
#[rustfmt::skip]
const R2: BigInteger = BigInt::new([
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 = BigInt::new([
289919226011913130u64,
13019990545710127566u64,
4409829457611675068u64,
13030600802816293865u64,
15696054586628993047u64,
9353078419867322391u64,
5664203968291172875u64,
5090703637405909511u64,
17774776443174359288u64,
10018561694451762270u64,
12632664537138156478u64,
46143195394855163u64,
]);
// (MODULUS - 1) / 2
#[rustfmt::skip]
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0x7a4e800000000045,
0xf3489f3438000041,
0x0b067c577578521b,
0x4c508b612b33d47c,
0x38ee69ee39f5ff97,
0x4344e476897cfec8,
0x81e75d7f92da1182,
0xb83dd31c72c2748c,
0x29413af7c043df20,
0x5c930c3540e8a344,
0x68c3e4a0027d7f9f,
0x9174127dc1e705,
]);
// T =
// 3445725192157866269698394841137828771239834456268075054756895080104811711121745868043841591644705843820432283876893306725580879560277123879674755849562650799475802549689254425186271815711798397975949850214984556421382456559534149
// (MODULUS - 1) / 2 ^ TWO_ADICITY
#[rustfmt::skip]
const T: BigInteger = BigInt::new([
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 = BigInt::new([
0xbd27400000000022,
0xf9a44f9a1c000020,
0x05833e2bbabc290d,
0xa62845b09599ea3e,
0x1c7734f71cfaffcb,
0x21a2723b44be7f64,
0x40f3aebfc96d08c1,
0x5c1ee98e39613a46,
0x14a09d7be021ef90,
0xae49861aa07451a2,
0xb461f250013ebfcf,
0x48ba093ee0f382,
]);
}
pub const FQ_ONE: Fq = MontFp!(Fq, "1");
pub const FQ_ZERO: Fq = MontFp!(Fq, "0");

+ 13
- 17
bw6_761/src/fields/fq3.rs

@ -1,6 +1,6 @@
use ark_ff::{ use ark_ff::{
field_new,
fields::fp3::{Fp3, Fp3Parameters},
fields::fp3::{Fp3, Fp3Config},
CubicExt, MontFp,
}; };
use crate::{ use crate::{
@ -8,24 +8,23 @@ use crate::{
Fq, Fq,
}; };
pub type Fq3 = Fp3<Fq3Parameters>;
pub type Fq3 = Fp3<Fq3Config>;
pub struct Fq3Parameters;
pub struct Fq3Config;
impl Fp3Parameters for Fq3Parameters {
impl Fp3Config for Fq3Config {
type Fp = Fq; type Fp = Fq;
/// NONRESIDUE = -4 /// NONRESIDUE = -4
// Fq3 = Fq\[u\]/u^3+4 // Fq3 = Fq\[u\]/u^3+4
#[rustfmt::skip]
const NONRESIDUE: Fq = field_new!(Fq, "-4");
const NONRESIDUE: Fq = MontFp!(Fq, "-4");
// (MODULUS^3 - 1) % 2^TWO_ADICITY == 0 // (MODULUS^3 - 1) % 2^TWO_ADICITY == 0
const TWO_ADICITY: u32 = 1; const TWO_ADICITY: u32 = 1;
// (T-1)/2 with T = (MODULUS^3-1) / 2^TWO_ADICITY // (T-1)/2 with T = (MODULUS^3-1) / 2^TWO_ADICITY
#[rustfmt::skip] #[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: &'static [u64] = &[
const TRACE_MINUS_ONE_DIV_TWO: &'static [u64] = &[
0xb5e7c000000a3eac, 0xb5e7c000000a3eac,
0xf79b99dbf41cf4ab, 0xf79b99dbf41cf4ab,
0xe9372b1919e55ee5, 0xe9372b1919e55ee5,
@ -65,27 +64,24 @@ impl Fp3Parameters for Fq3Parameters {
]; ];
// NONRESIDUE^T % q // NONRESIDUE^T % q
#[rustfmt::skip]
const QUADRATIC_NONRESIDUE_TO_T: (Fq, Fq, Fq) = (
field_new!(Fq, "6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068298"),
const QUADRATIC_NONRESIDUE_TO_T: Fq3 = CubicExt!(
MontFp!(Fq, "6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068298"),
FQ_ZERO, FQ_ZERO,
FQ_ZERO, FQ_ZERO,
); );
// NQR ^ (MODULUS^i - 1)/3, i=0,1,2 with NQR = u = (0,1,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] = &[ const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[
FQ_ONE, FQ_ONE,
field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
MontFp!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
MontFp!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
]; ];
// NQR ^ (2*MODULUS^i - 2)/3, i=0,1,2 with NQR = u = (0,1,0) // 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] = &[ const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[
FQ_ONE, FQ_ONE,
field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
MontFp!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
MontFp!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
]; ];
#[inline(always)] #[inline(always)]

+ 15
- 16
bw6_761/src/fields/fq6.rs

@ -1,27 +1,26 @@
use crate::{Fq, Fq3, Fq3Parameters, FQ_ONE, FQ_ZERO};
use ark_ff::{ use ark_ff::{
field_new,
fields::fp6_2over3::{Fp6, Fp6Parameters},
fields::fp6_2over3::{Fp6, Fp6Config},
CubicExt, MontFp,
}; };
pub type Fq6 = Fp6<Fq6Parameters>;
use crate::{Fq, Fq3, Fq3Config, FQ_ONE, FQ_ZERO};
pub struct Fq6Parameters;
pub type Fq6 = Fp6<Fq6Config>;
impl Fp6Parameters for Fq6Parameters {
type Fp3Params = Fq3Parameters;
pub struct Fq6Config;
impl Fp6Config for Fq6Config {
type Fp3Config = Fq3Config;
/// NONRESIDUE = (0, 1, 0) /// NONRESIDUE = (0, 1, 0)
#[rustfmt::skip]
const NONRESIDUE: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO);
const NONRESIDUE: Fq3 = CubicExt!(FQ_ZERO, FQ_ONE, FQ_ZERO);
#[rustfmt::skip]
const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[ const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[
field_new!(Fq, "1"),
field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775649"),
field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
field_new!(Fq, "-1"),
field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292651"),
MontFp!(Fq, "1"),
MontFp!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775649"),
MontFp!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
MontFp!(Fq, "-1"),
MontFp!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
MontFp!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292651"),
]; ];
} }

+ 1
- 1
bw6_761/src/fields/fr.rs

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

+ 5
- 7
bw6_761/src/fields/tests.rs

@ -1,14 +1,12 @@
use ark_algebra_test_templates::{
fields::*, generate_field_serialization_test, generate_field_test,
};
use ark_ff::{Field, One, PrimeField, SquareRootField, UniformRand, Zero}; use ark_ff::{Field, One, PrimeField, SquareRootField, UniformRand, Zero};
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
use ark_std::{rand::Rng, test_rng}; use ark_std::{rand::Rng, test_rng};
use core::ops::{AddAssign, MulAssign, SubAssign};
use crate::*; use crate::*;
use ark_algebra_test_templates::{
fields::*, generate_field_serialization_test, generate_field_test,
};
use core::ops::{AddAssign, MulAssign, SubAssign};
generate_field_test!(bw6_761; fq3; fq6;);
generate_field_test!(bw6_761; fq3; fq6; mont(12, 6); );
generate_field_serialization_test!(bw6_761;); generate_field_serialization_test!(bw6_761;);

+ 4
- 3
bw6_761/src/lib.rs

@ -9,9 +9,10 @@
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
//! This library implements the BW6_761 curve generated in [\[EG20\]](https://eprint.iacr.org/2020/351). //! 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.
//! 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: //! Curve information:
//! * Base field: q = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299 //! * Base field: q = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299

+ 28
- 0
cp6_782/scripts/base_field.sage

@ -0,0 +1,28 @@
modulus = 22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577
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
cp6_782/scripts/scalar_field.sage

@ -0,0 +1,28 @@
modulus = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
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)

+ 6
- 11
cp6_782/src/curves/g1.rs

@ -2,7 +2,7 @@ use ark_ec::{
models::{ModelParameters, SWModelParameters}, models::{ModelParameters, SWModelParameters},
short_weierstrass_jacobian::{GroupAffine, GroupProjective}, short_weierstrass_jacobian::{GroupAffine, GroupProjective},
}; };
use ark_ff::field_new;
use ark_ff::MontFp;
use crate::{Fq, Fr}; use crate::{Fq, Fr};
@ -31,18 +31,15 @@ impl ModelParameters for Parameters {
/// COFACTOR^(-1) mod r = /// COFACTOR^(-1) mod r =
/// 163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788 /// 163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, "163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788");
const COFACTOR_INV: Fr = MontFp!(Fr, "163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788");
} }
impl SWModelParameters for Parameters { impl SWModelParameters for Parameters {
/// COEFF_A = 5 /// COEFF_A = 5
#[rustfmt::skip]
const COEFF_A: Fq = field_new!(Fq, "5");
const COEFF_A: Fq = MontFp!(Fq, "5");
/// COEFF_B = 17764315118651679038286329069295091506801468118146712649886336045535808055361274148466772191243305528312843236347777260247138934336850548243151534538734724191505953341403463040067571652261229308333392040104884438208594329793895206056414 /// COEFF_B = 17764315118651679038286329069295091506801468118146712649886336045535808055361274148466772191243305528312843236347777260247138934336850548243151534538734724191505953341403463040067571652261229308333392040104884438208594329793895206056414
#[rustfmt::skip]
const COEFF_B: Fq = field_new!(Fq, "17764315118651679038286329069295091506801468118146712649886336045535808055361274148466772191243305528312843236347777260247138934336850548243151534538734724191505953341403463040067571652261229308333392040104884438208594329793895206056414");
const COEFF_B: Fq = MontFp!(Fq, "17764315118651679038286329069295091506801468118146712649886336045535808055361274148466772191243305528312843236347777260247138934336850548243151534538734724191505953341403463040067571652261229308333392040104884438208594329793895206056414");
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
@ -51,10 +48,8 @@ impl SWModelParameters for Parameters {
/// G1_GENERATOR_X = /// G1_GENERATOR_X =
/// 5511163824921585887915590525772884263960974614921003940645351443740084257508990841338974915037175497689287870585840954231884082785026301437744745393958283053278991955159266640440849940136976927372133743626748847559939620888818486853646 /// 5511163824921585887915590525772884263960974614921003940645351443740084257508990841338974915037175497689287870585840954231884082785026301437744745393958283053278991955159266640440849940136976927372133743626748847559939620888818486853646
#[rustfmt::skip]
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "5511163824921585887915590525772884263960974614921003940645351443740084257508990841338974915037175497689287870585840954231884082785026301437744745393958283053278991955159266640440849940136976927372133743626748847559939620888818486853646");
pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "5511163824921585887915590525772884263960974614921003940645351443740084257508990841338974915037175497689287870585840954231884082785026301437744745393958283053278991955159266640440849940136976927372133743626748847559939620888818486853646");
/// G1_GENERATOR_Y = /// G1_GENERATOR_Y =
/// 7913123550914612057135582061699117755797758113868200992327595317370485234417808273674357776714522052694559358668442301647906991623400754234679697332299689255516547752391831738454121261248793568285885897998257357202903170202349380518443 /// 7913123550914612057135582061699117755797758113868200992327595317370485234417808273674357776714522052694559358668442301647906991623400754234679697332299689255516547752391831738454121261248793568285885897998257357202903170202349380518443
#[rustfmt::skip]
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "7913123550914612057135582061699117755797758113868200992327595317370485234417808273674357776714522052694559358668442301647906991623400754234679697332299689255516547752391831738454121261248793568285885897998257357202903170202349380518443");
pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "7913123550914612057135582061699117755797758113868200992327595317370485234417808273674357776714522052694559358668442301647906991623400754234679697332299689255516547752391831738454121261248793568285885897998257357202903170202349380518443");

+ 13
- 28
cp6_782/src/curves/g2.rs

@ -2,7 +2,7 @@ use ark_ec::{
models::{ModelParameters, SWModelParameters}, models::{ModelParameters, SWModelParameters},
short_weierstrass_jacobian::{GroupAffine, GroupProjective}, short_weierstrass_jacobian::{GroupAffine, GroupProjective},
}; };
use ark_ff::field_new;
use ark_ff::{CubicExt, MontFp};
use crate::{Fq, Fq3, Fr, FQ_ZERO}; use crate::{Fq, Fq3, Fr, FQ_ZERO};
@ -55,25 +55,18 @@ impl ModelParameters for Parameters {
/// COFACTOR^(-1) mod r = /// COFACTOR^(-1) mod r =
/// 45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598 /// 45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, "45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598");
const COFACTOR_INV: Fr = MontFp!(Fr, "45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598");
} }
impl SWModelParameters for Parameters { impl SWModelParameters for Parameters {
/// COEFF_A = (0, 0, COEFF_A * TWIST^2) = (0, 0, 5) /// COEFF_A = (0, 0, COEFF_A * TWIST^2) = (0, 0, 5)
#[rustfmt::skip]
const COEFF_A: Fq3 = field_new!(Fq3,
FQ_ZERO,
FQ_ZERO,
field_new!(Fq, "5"),
);
const COEFF_A: Fq3 = CubicExt!(FQ_ZERO, FQ_ZERO, MontFp!(Fq, "5"),);
/// COEFF_B = (G1::COEFF_B * TWIST^3, 0, 0) = /// COEFF_B = (G1::COEFF_B * TWIST^3, 0, 0) =
/// (7237353553714858194254855835825640240663090882935418626687402315497764195116318527743248304684159666286416318482685337633828994152723793439622384740540789612754127688659139509552568164770448654259255628317166934203899992395064470477612, /// (7237353553714858194254855835825640240663090882935418626687402315497764195116318527743248304684159666286416318482685337633828994152723793439622384740540789612754127688659139509552568164770448654259255628317166934203899992395064470477612,
/// 0, 0) /// 0, 0)
#[rustfmt::skip]
const COEFF_B: Fq3 = field_new!(Fq3,
field_new!(Fq, "7237353553714858194254855835825640240663090882935418626687402315497764195116318527743248304684159666286416318482685337633828994152723793439622384740540789612754127688659139509552568164770448654259255628317166934203899992395064470477612"),
const COEFF_B: Fq3 = CubicExt!(
MontFp!(Fq, "7237353553714858194254855835825640240663090882935418626687402315497764195116318527743248304684159666286416318482685337633828994152723793439622384740540789612754127688659139509552568164770448654259255628317166934203899992395064470477612"),
FQ_ZERO, FQ_ZERO,
FQ_ZERO, FQ_ZERO,
); );
@ -83,37 +76,29 @@ impl SWModelParameters for Parameters {
(G2_GENERATOR_X, G2_GENERATOR_Y); (G2_GENERATOR_X, G2_GENERATOR_Y);
} }
const G2_GENERATOR_X: Fq3 =
field_new!(Fq3, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1, G2_GENERATOR_X_C2);
const G2_GENERATOR_Y: Fq3 =
field_new!(Fq3, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1, G2_GENERATOR_Y_C2);
const G2_GENERATOR_X: Fq3 = CubicExt!(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1, G2_GENERATOR_X_C2);
const G2_GENERATOR_Y: Fq3 = CubicExt!(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1, G2_GENERATOR_Y_C2);
/// G2_GENERATOR_X_C0 = /// G2_GENERATOR_X_C0 =
/// 13426761183630949215425595811885033211332897733228446437546263564078445562454176776915160094418980045665397361295624472103734543457352048745726512354895954850428989867542989474136256025045975283415690491751906307188562464175510373683338 /// 13426761183630949215425595811885033211332897733228446437546263564078445562454176776915160094418980045665397361295624472103734543457352048745726512354895954850428989867542989474136256025045975283415690491751906307188562464175510373683338
#[rustfmt::skip]
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "13426761183630949215425595811885033211332897733228446437546263564078445562454176776915160094418980045665397361295624472103734543457352048745726512354895954850428989867542989474136256025045975283415690491751906307188562464175510373683338");
pub const G2_GENERATOR_X_C0: Fq = MontFp!(Fq, "13426761183630949215425595811885033211332897733228446437546263564078445562454176776915160094418980045665397361295624472103734543457352048745726512354895954850428989867542989474136256025045975283415690491751906307188562464175510373683338");
/// G2_GENERATOR_X_C1 = /// G2_GENERATOR_X_C1 =
/// 20471601555918880743198170952645906008198510944268658573129351735028343217532386920456705632337352161031960990613816401042894531220068552819818037605513359562118363589199569321421558696125646867661360498323171027455638052943806292028610 /// 20471601555918880743198170952645906008198510944268658573129351735028343217532386920456705632337352161031960990613816401042894531220068552819818037605513359562118363589199569321421558696125646867661360498323171027455638052943806292028610
#[rustfmt::skip]
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "20471601555918880743198170952645906008198510944268658573129351735028343217532386920456705632337352161031960990613816401042894531220068552819818037605513359562118363589199569321421558696125646867661360498323171027455638052943806292028610");
pub const G2_GENERATOR_X_C1: Fq = MontFp!(Fq, "20471601555918880743198170952645906008198510944268658573129351735028343217532386920456705632337352161031960990613816401042894531220068552819818037605513359562118363589199569321421558696125646867661360498323171027455638052943806292028610");
/// G2_GENERATOR_X_C2 = /// G2_GENERATOR_X_C2 =
/// 3905053196875761830053608605277158152930144841844497593936739534395003062685449846381431331169369910535935138116320442345524758217411779027270883193856999691582831339845600938304719916501940381093815781408183227875600753651697934495980 /// 3905053196875761830053608605277158152930144841844497593936739534395003062685449846381431331169369910535935138116320442345524758217411779027270883193856999691582831339845600938304719916501940381093815781408183227875600753651697934495980
#[rustfmt::skip]
pub const G2_GENERATOR_X_C2: Fq = field_new!(Fq, "3905053196875761830053608605277158152930144841844497593936739534395003062685449846381431331169369910535935138116320442345524758217411779027270883193856999691582831339845600938304719916501940381093815781408183227875600753651697934495980");
pub const G2_GENERATOR_X_C2: Fq = MontFp!(Fq, "3905053196875761830053608605277158152930144841844497593936739534395003062685449846381431331169369910535935138116320442345524758217411779027270883193856999691582831339845600938304719916501940381093815781408183227875600753651697934495980");
/// G2_GENERATOR_Y_C0 = /// G2_GENERATOR_Y_C0 =
/// 8567517639523571619872938228644013584947463594196306323477160496987712111576624702939472765993995586889532559039169098780892505598589581147768095093536988446010255611523736706017580686335404469207486594272103717837888228343074699140243 /// 8567517639523571619872938228644013584947463594196306323477160496987712111576624702939472765993995586889532559039169098780892505598589581147768095093536988446010255611523736706017580686335404469207486594272103717837888228343074699140243
#[rustfmt::skip]
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "8567517639523571619872938228644013584947463594196306323477160496987712111576624702939472765993995586889532559039169098780892505598589581147768095093536988446010255611523736706017580686335404469207486594272103717837888228343074699140243");
pub const G2_GENERATOR_Y_C0: Fq = MontFp!(Fq, "8567517639523571619872938228644013584947463594196306323477160496987712111576624702939472765993995586889532559039169098780892505598589581147768095093536988446010255611523736706017580686335404469207486594272103717837888228343074699140243");
/// G2_GENERATOR_Y_C1 = /// G2_GENERATOR_Y_C1 =
/// 3890537069205870914984502594450293167889863914413852788876350245583932846980126025043974070704295857226211547108005650399870458089721518559480870503159804530091559886149680718531004778697982910253701559194337987238111062202037698927752 /// 3890537069205870914984502594450293167889863914413852788876350245583932846980126025043974070704295857226211547108005650399870458089721518559480870503159804530091559886149680718531004778697982910253701559194337987238111062202037698927752
#[rustfmt::skip]
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "3890537069205870914984502594450293167889863914413852788876350245583932846980126025043974070704295857226211547108005650399870458089721518559480870503159804530091559886149680718531004778697982910253701559194337987238111062202037698927752");
pub const G2_GENERATOR_Y_C1: Fq = MontFp!(Fq, "3890537069205870914984502594450293167889863914413852788876350245583932846980126025043974070704295857226211547108005650399870458089721518559480870503159804530091559886149680718531004778697982910253701559194337987238111062202037698927752");
/// G2_GENERATOR_Y_C2 = /// G2_GENERATOR_Y_C2 =
/// 10936269922612615564271188303104593362724754284143779051599749016735041389483971486958818324356025479751246744831831158558101688599198721653921723013062333636402617118847009085485166284126970598561393411916461254016145116183331671450721 /// 10936269922612615564271188303104593362724754284143779051599749016735041389483971486958818324356025479751246744831831158558101688599198721653921723013062333636402617118847009085485166284126970598561393411916461254016145116183331671450721
#[rustfmt::skip]
pub const G2_GENERATOR_Y_C2: Fq = field_new!(Fq, "10936269922612615564271188303104593362724754284143779051599749016735041389483971486958818324356025479751246744831831158558101688599198721653921723013062333636402617118847009085485166284126970598561393411916461254016145116183331671450721");
pub const G2_GENERATOR_Y_C2: Fq = MontFp!(Fq, "10936269922612615564271188303104593362724754284143779051599749016735041389483971486958818324356025479751246744831831158558101688599198721653921723013062333636402617118847009085485166284126970598561393411916461254016145116183331671450721");

+ 2
- 3
cp6_782/src/curves/mod.rs

@ -1,9 +1,8 @@
use ark_ec::{models::SWModelParameters, PairingEngine}; use ark_ec::{models::SWModelParameters, PairingEngine};
use ark_ff::{ use ark_ff::{
biginteger::BigInteger832, biginteger::BigInteger832,
field_new,
fields::{BitIteratorBE, Field}, fields::{BitIteratorBE, Field},
BigInt, One,
BigInt, CubicExt, One,
}; };
use crate::{Fq, Fq3, Fq6, Fr, FQ_ONE, FQ_ZERO}; use crate::{Fq, Fq3, Fq6, Fr, FQ_ONE, FQ_ZERO};
@ -154,7 +153,7 @@ impl CP6_782 {
} }
/// TWIST = (0, 1, 0) /// TWIST = (0, 1, 0)
pub const TWIST: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO);
pub const TWIST: Fq3 = CubicExt!(FQ_ZERO, FQ_ONE, FQ_ZERO);
/// ATE_IS_LOOP_COUNT_NEG = false /// ATE_IS_LOOP_COUNT_NEG = false
pub const ATE_IS_LOOP_COUNT_NEG: bool = false; pub const ATE_IS_LOOP_COUNT_NEG: bool = false;

+ 4
- 6
cp6_782/src/curves/tests.rs

@ -1,15 +1,13 @@
use ark_algebra_test_templates::{
curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, groups::*, msm::*,
};
use ark_ec::{AffineCurve, PairingEngine}; use ark_ec::{AffineCurve, PairingEngine};
use ark_ff::{Field, One, PrimeField}; use ark_ff::{Field, One, PrimeField};
use ark_std::{rand::Rng, test_rng}; use ark_std::{rand::Rng, test_rng};
use core::ops::MulAssign;
use crate::*; use crate::*;
use ark_algebra_test_templates::{
curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, groups::*, msm::*,
};
use core::ops::MulAssign;
generate_g1_test!(cp6_782; curve_tests; sw_tests;); generate_g1_test!(cp6_782; curve_tests; sw_tests;);
generate_g2_test!(cp6_782; curve_tests; sw_tests;); generate_g2_test!(cp6_782; curve_tests; sw_tests;);
generate_bilinearity_test!(CP6_782, Fq6); generate_bilinearity_test!(CP6_782, Fq6);

+ 8
- 167
cp6_782/src/fields/fq.rs

@ -1,169 +1,10 @@
use ark_ff::{
biginteger::{BigInt, BigInteger832 as BigInteger},
fields::{FftParameters, Fp832, Fp832Parameters, FpParameters},
};
use ark_ff::fields::{Fp832, MontBackend, MontConfig, MontFp};
pub type Fq = Fp832<FqParameters>;
#[derive(MontConfig)]
#[modulus = "22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577"]
#[generator = "13"]
pub struct FqConfig;
pub type Fq = Fp832<MontBackend<FqConfig, 13>>;
pub struct FqParameters;
pub const FQ_ONE: Fq = ark_ff::field_new!(Fq, "1");
pub const FQ_ZERO: Fq = ark_ff::field_new!(Fq, "0");
impl Fp832Parameters for FqParameters {}
impl FftParameters for FqParameters {
type BigInt = BigInteger;
const TWO_ADICITY: u32 = 3;
#[rustfmt::skip]
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([
18044746167194862600u64,
63590321303744709u64,
5009346151370959890u64,
2859114157767503991u64,
8301813204852325413u64,
5629414263664332594u64,
2637340888701394641u64,
17433538052687852753u64,
2230763098934759248u64,
3785382115983092023u64,
8895511354022222370u64,
15792083141709071785u64,
1328u64,
]);
}
impl FpParameters for FqParameters {
/// MODULUS = 22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577
#[rustfmt::skip]
const MODULUS: BigInteger = BigInt::new([
0xdace79b57b942ae9,
0x545d85c16dfd424a,
0xee135c065f4d26b7,
0x9c2f764a12c4024b,
0x1ad533049cfe6a39,
0x52a3fb77c79c1320,
0xab3596c8617c5792,
0x830c728d80f9d78b,
0x6a7223ee72023d07,
0xbc5d176b746af026,
0xe959283d8f526663,
0xc4d2263babf8941f,
0x3848,
]);
const MODULUS_BITS: u32 = 782;
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
const REPR_SHAVE_BITS: u32 = 50;
#[rustfmt::skip]
const R: BigInteger = BigInt::new([
11190988450819017841u64,
16170411717126802030u64,
2265463223430229059u64,
16946880912571045974u64,
11155248462028513229u64,
12855672356664541314u64,
8489376931127408159u64,
2655797810825538098u64,
9648483887143916718u64,
17514963461276738952u64,
16777089214204267338u64,
15649035958020076168u64,
8659u64,
]);
#[rustfmt::skip]
const R2: BigInteger = BigInt::new([
13983406830510863714u64,
17863856572171232656u64,
1698388424046564526u64,
1773634430448388392u64,
8684647957094413275u64,
3992637317298078843u64,
18420879196616862245u64,
3238482510270583127u64,
7928200707794018216u64,
10024831010452223910u64,
9613847725664942650u64,
15361265984156787358u64,
7833u64,
]);
const INV: u64 = 14469047335842394791u64;
/// GENERATOR = 13
#[rustfmt::skip]
const GENERATOR: BigInteger = BigInt::new([
16669393626057438558u64,
1640520694378723217u64,
1598646156981121135u64,
12401834967100173388u64,
2356467520877704673u64,
14759118825104212161u64,
5556628239575210651u64,
5317520392768798654u64,
16398429955031064995u64,
3556102264904210145u64,
8166834915717907988u64,
11926665585800594452u64,
11716u64,
]);
#[rustfmt::skip]
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0x6d673cdabdca1574,
0xaa2ec2e0b6fea125,
0xf709ae032fa6935b,
0xce17bb2509620125,
0xd6a99824e7f351c,
0x2951fdbbe3ce0990,
0xd59acb6430be2bc9,
0xc1863946c07cebc5,
0x353911f739011e83,
0xde2e8bb5ba357813,
0xf4ac941ec7a93331,
0x6269131dd5fc4a0f,
0x1c24,
]);
// (T - 1)/2 =
// 1398117143679731058146671387906315933423474966581074036386468539227923378278626533764529938634242576261128410962740119034868607201414583335758422276643816405480145410934911750070786645716409577212967755581539567265673914343284832551598
#[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0xadace79b57b942ae,
0x7545d85c16dfd424,
0xbee135c065f4d26b,
0x99c2f764a12c4024,
0x1ad533049cfe6a3,
0x252a3fb77c79c132,
0xbab3596c8617c579,
0x7830c728d80f9d78,
0x66a7223ee72023d0,
0x3bc5d176b746af02,
0xfe959283d8f52666,
0x8c4d2263babf8941,
0x384,
]);
// T =
// 2796234287359462116293342775812631866846949933162148072772937078455846756557253067529059877268485152522256821925480238069737214402829166671516844553287632810960290821869823500141573291432819154425935511163079134531347828686569665103197
#[rustfmt::skip]
const T: BigInteger = BigInt::new([
0x5b59cf36af72855d,
0xea8bb0b82dbfa849,
0x7dc26b80cbe9a4d6,
0x3385eec942588049,
0x35aa660939fcd47,
0x4a547f6ef8f38264,
0x7566b2d90c2f8af2,
0xf0618e51b01f3af1,
0xcd4e447dce4047a0,
0x778ba2ed6e8d5e04,
0xfd2b2507b1ea4ccc,
0x189a44c7757f1283,
0x709,
]);
}
pub const FQ_ONE: Fq = MontFp!(Fq, "1");
pub const FQ_ZERO: Fq = MontFp!(Fq, "0");

+ 17
- 21
cp6_782/src/fields/fq3.rs

@ -1,25 +1,24 @@
use crate::{fields::FQ_ZERO, Fq};
use ark_ff::{ use ark_ff::{
field_new,
fields::fp3::{Fp3, Fp3Parameters},
Field,
fields::fp3::{Fp3, Fp3Config},
CubicExt, Field, MontFp,
}; };
pub type Fq3 = Fp3<Fq3Parameters>;
use crate::{fields::FQ_ZERO, Fq};
pub type Fq3 = Fp3<Fq3Config>;
pub struct Fq3Parameters;
pub struct Fq3Config;
impl Fp3Parameters for Fq3Parameters {
impl Fp3Config for Fq3Config {
type Fp = Fq; type Fp = Fq;
/// NONRESIDUE = 13 /// NONRESIDUE = 13
#[rustfmt::skip]
const NONRESIDUE: Fq = field_new!(Fq, "13");
const NONRESIDUE: Fq = MontFp!(Fq, "13");
const TWO_ADICITY: u32 = 3; const TWO_ADICITY: u32 = 3;
#[rustfmt::skip] #[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: &'static [u64] = &[
const TRACE_MINUS_ONE_DIV_TWO: &'static [u64] = &[
0x62730e2cd2029617, 0x62730e2cd2029617,
0x660647f735cb88cf, 0x660647f735cb88cf,
0x274359d60784f69d, 0x274359d60784f69d,
@ -59,25 +58,22 @@ impl Fp3Parameters for Fq3Parameters {
0x2b87fda171, 0x2b87fda171,
]; ];
#[rustfmt::skip]
const QUADRATIC_NONRESIDUE_TO_T: (Fq, Fq, Fq) = (
field_new!(Fq, "5759691735434357221228070840130186543101559976323700017469395641639510585333061695996665166662748527158637897523704071820491869715512532675375604262649010727161924084052120196921150869218319839231115277876207074651754402338718419191428"),
const QUADRATIC_NONRESIDUE_TO_T: Fq3 = CubicExt!(
MontFp!(Fq, "5759691735434357221228070840130186543101559976323700017469395641639510585333061695996665166662748527158637897523704071820491869715512532675375604262649010727161924084052120196921150869218319839231115277876207074651754402338718419191428"),
FQ_ZERO, FQ_ZERO,
FQ_ZERO, FQ_ZERO,
); );
#[rustfmt::skip]
const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[ const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[
field_new!(Fq, "1"),
field_new!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"),
field_new!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"),
MontFp!(Fq, "1"),
MontFp!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"),
MontFp!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"),
]; ];
#[rustfmt::skip]
const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[ const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[
field_new!(Fq, "1"),
field_new!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"),
field_new!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"),
MontFp!(Fq, "1"),
MontFp!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"),
MontFp!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"),
]; ];
#[inline(always)] #[inline(always)]

+ 15
- 16
cp6_782/src/fields/fq6.rs

@ -1,27 +1,26 @@
use crate::{Fq, Fq3, Fq3Parameters, FQ_ONE, FQ_ZERO};
use ark_ff::{ use ark_ff::{
field_new,
fields::fp6_2over3::{Fp6, Fp6Parameters},
fields::fp6_2over3::{Fp6, Fp6Config},
CubicExt, MontFp,
}; };
pub type Fq6 = Fp6<Fq6Parameters>;
use crate::{Fq, Fq3, Fq3Config, FQ_ONE, FQ_ZERO};
pub struct Fq6Parameters;
pub type Fq6 = Fp6<Fq6Config>;
impl Fp6Parameters for Fq6Parameters {
type Fp3Params = Fq3Parameters;
pub struct Fq6Config;
impl Fp6Config for Fq6Config {
type Fp3Config = Fq3Config;
/// NONRESIDUE = (0, 1, 0). /// NONRESIDUE = (0, 1, 0).
#[rustfmt::skip]
const NONRESIDUE: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO);
const NONRESIDUE: Fq3 = CubicExt!(FQ_ZERO, FQ_ONE, FQ_ZERO);
#[rustfmt::skip]
const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[ const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[
field_new!(Fq, "1"),
field_new!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756862"),
field_new!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"),
field_new!(Fq, "22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825576"),
field_new!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"),
field_new!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068716"),
MontFp!(Fq, "1"),
MontFp!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756862"),
MontFp!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"),
MontFp!(Fq, "22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825576"),
MontFp!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"),
MontFp!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068716"),
]; ];
} }

+ 1
- 1
cp6_782/src/fields/fr.rs

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

+ 1
- 1
cp6_782/src/fields/mod.rs

@ -10,5 +10,5 @@ pub use self::fq3::*;
pub mod fq6; pub mod fq6;
pub use self::fq6::*; pub use self::fq6::*;
#[cfg(all(feature = "cp6_782", test))]
#[cfg(test)]
mod tests; mod tests;

+ 5
- 7
cp6_782/src/fields/tests.rs

@ -1,14 +1,12 @@
use ark_algebra_test_templates::{
fields::*, generate_field_serialization_test, generate_field_test,
};
use ark_ff::{Field, One, PrimeField, SquareRootField, UniformRand, Zero}; use ark_ff::{Field, One, PrimeField, SquareRootField, UniformRand, Zero};
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
use ark_std::{rand::Rng, test_rng}; use ark_std::{rand::Rng, test_rng};
use core::ops::{AddAssign, MulAssign, SubAssign};
use crate::*; use crate::*;
use ark_algebra_test_templates::{
fields::*, generate_field_serialization_test, generate_field_test,
};
use core::ops::{AddAssign, MulAssign, SubAssign};
generate_field_test!(cp6_782; fq3; fq6;);
generate_field_test!(cp6_782; fq3; fq6; mont(13, 6); );
generate_field_serialization_test!(cp6_782;); generate_field_serialization_test!(cp6_782;);

+ 3
- 2
cp6_782/src/lib.rs

@ -9,8 +9,9 @@
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
//! This library implements the CP6_782 curve generated in [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962). //! This library implements the CP6_782 curve generated in [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962).
//! The name denotes that it was generated using the Cocks--Pinch method for the embedding degree 6.
//! The main feature of this curve is that the scalar field equals the base field of the BLS12_377 curve.
//! The name denotes that it was generated using the Cocks--Pinch method for the
//! embedding degree 6. The main feature of this curve is that the scalar field
//! equals the base field of the BLS12_377 curve.
//! //!
//! Curve information: //! Curve information:
//! * Base field: q = 22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577 //! * Base field: q = 22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577

+ 2
- 2
curve-benches/benches/bn254.rs

@ -7,8 +7,8 @@ use ark_bn254::{
}; };
use ark_ec::{PairingEngine, ProjectiveCurve}; use ark_ec::{PairingEngine, ProjectiveCurve};
use ark_ff::{ use ark_ff::{
biginteger::{BigInteger256 as FrRepr, BigInteger256 as FqRepr},
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
biginteger::BigInteger256 as FrRepr, BigInteger, Field, PrimeField, SquareRootField,
UniformRand,
}; };
mod g1 { mod g1 {

+ 2
- 2
curve-benches/benches/ed_on_bls12_381.rs

@ -4,8 +4,8 @@ use ark_std::ops::{AddAssign, MulAssign, SubAssign};
use ark_ec::ProjectiveCurve; use ark_ec::ProjectiveCurve;
use ark_ed_on_bls12_381::{fq::Fq, fr::Fr, EdwardsAffine as GAffine, EdwardsProjective as G}; use ark_ed_on_bls12_381::{fq::Fq, fr::Fr, EdwardsAffine as GAffine, EdwardsProjective as G};
use ark_ff::{ use ark_ff::{
biginteger::{BigInteger256 as FrRepr, BigInteger256 as FqRepr},
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
biginteger::BigInteger256 as FrRepr, BigInteger, Field, PrimeField, SquareRootField,
UniformRand,
}; };
mod g { mod g {

+ 2
- 2
curve-benches/benches/pallas.rs

@ -3,8 +3,8 @@ use ark_std::ops::{AddAssign, MulAssign, SubAssign};
use ark_ec::ProjectiveCurve; use ark_ec::ProjectiveCurve;
use ark_ff::{ use ark_ff::{
biginteger::{BigInteger256 as FrRepr, BigInteger256 as FqRepr},
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
biginteger::BigInteger256 as FrRepr, BigInteger, Field, PrimeField, SquareRootField,
UniformRand,
}; };
use ark_pallas::{fq::Fq, fr::Fr, Affine as GAffine, Projective as G}; use ark_pallas::{fq::Fq, fr::Fr, Affine as GAffine, Projective as G};

+ 2
- 2
curve-benches/benches/vesta.rs

@ -3,8 +3,8 @@ use ark_std::ops::{AddAssign, MulAssign, SubAssign};
use ark_ec::ProjectiveCurve; use ark_ec::ProjectiveCurve;
use ark_ff::{ use ark_ff::{
biginteger::{BigInteger256 as FrRepr, BigInteger256 as FqRepr},
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
biginteger::BigInteger256 as FrRepr, BigInteger, Field, PrimeField, SquareRootField,
UniformRand,
}; };
use ark_vesta::{fq::Fq, fr::Fr, Affine as GAffine, Projective as G}; use ark_vesta::{fq::Fq, fr::Fr, Affine as GAffine, Projective as G};

+ 1
- 1
curve-benches/src/macros/ec.rs

@ -231,7 +231,7 @@ macro_rules! ec_bench {
let g = <$projective>::rand(&mut rng).into_affine(); let g = <$projective>::rand(&mut rng).into_affine();
let v: Vec<_> = (0..SAMPLES).map(|_| g).collect(); let v: Vec<_> = (0..SAMPLES).map(|_| g).collect();
let scalars: Vec<_> = (0..SAMPLES) let scalars: Vec<_> = (0..SAMPLES)
.map(|_| Fr::rand(&mut rng).into_repr())
.map(|_| Fr::rand(&mut rng).into_bigint())
.collect(); .collect();
b.bench_n(1, |b| { b.bench_n(1, |b| {
b.iter(|| ark_ec::msm::VariableBase::msm(&v, &scalars)); b.iter(|| ark_ec::msm::VariableBase::msm(&v, &scalars));

+ 4
- 4
curve-benches/src/macros/field.rs

@ -343,7 +343,7 @@ macro_rules! prime_field {
let mut count = 0; let mut count = 0;
b.iter(|| { b.iter(|| {
let mut tmp = v[count].0; let mut tmp = v[count].0;
n_fold!(tmp, v, add_nocarry, count);
n_fold!(tmp, v, add_with_carry, count);
count = (count + 1) % SAMPLES; count = (count + 1) % SAMPLES;
tmp tmp
}); });
@ -369,7 +369,7 @@ macro_rules! prime_field {
let mut count = 0; let mut count = 0;
b.iter(|| { b.iter(|| {
let mut tmp = v[count].0; let mut tmp = v[count].0;
n_fold!(tmp, v, sub_noborrow, count);
n_fold!(tmp, v, sub_with_borrow, count);
count = (count + 1) % SAMPLES; count = (count + 1) % SAMPLES;
tmp; tmp;
}); });
@ -432,7 +432,7 @@ macro_rules! prime_field {
let mut count = 0; let mut count = 0;
b.iter(|| { b.iter(|| {
count = (count + 1) % SAMPLES; count = (count + 1) % SAMPLES;
v[count].into_repr();
v[count].into_bigint();
}); });
} }
@ -442,7 +442,7 @@ macro_rules! prime_field {
let mut rng = ark_std::test_rng(); let mut rng = ark_std::test_rng();
let v: Vec<$f_repr_type> = (0..SAMPLES) let v: Vec<$f_repr_type> = (0..SAMPLES)
.map(|_| $f::rand(&mut rng).into_repr())
.map(|_| $f::rand(&mut rng).into_bigint())
.collect(); .collect();
let mut count = 0; let mut count = 0;

+ 11
- 13
curve-constraint-tests/src/lib.rs

@ -5,8 +5,7 @@ pub mod fields {
use ark_ff::{BitIteratorLE, Field, UniformRand}; use ark_ff::{BitIteratorLE, Field, UniformRand};
use ark_r1cs_std::prelude::*; use ark_r1cs_std::prelude::*;
use ark_relations::r1cs::{ConstraintSystem, SynthesisError}; use ark_relations::r1cs::{ConstraintSystem, SynthesisError};
use ark_std::test_rng;
use ark_std::vec::Vec;
use ark_std::{test_rng, vec::Vec};
pub fn field_test<F, ConstraintF, AF>() -> Result<(), SynthesisError> pub fn field_test<F, ConstraintF, AF>() -> Result<(), SynthesisError>
where where
@ -235,7 +234,7 @@ pub mod curves {
short_weierstrass_jacobian::GroupProjective as SWProjective, short_weierstrass_jacobian::GroupProjective as SWProjective,
twisted_edwards_extended::GroupProjective as TEProjective, ProjectiveCurve, twisted_edwards_extended::GroupProjective as TEProjective, ProjectiveCurve,
}; };
use ark_ff::{BitIteratorLE, Field, FpParameters, One, PrimeField};
use ark_ff::{BitIteratorLE, Field, One, PrimeField};
use ark_relations::r1cs::{ConstraintSystem, SynthesisError}; use ark_relations::r1cs::{ConstraintSystem, SynthesisError};
use ark_std::{test_rng, vec::Vec, UniformRand}; use ark_std::{test_rng, vec::Vec, UniformRand};
@ -323,23 +322,22 @@ pub mod curves {
} }
assert!(cs.is_satisfied().unwrap()); assert!(cs.is_satisfied().unwrap());
let modulus = <C::ScalarField as PrimeField>::Params::MODULUS
.as_ref()
.to_vec();
let modulus = <C::ScalarField as PrimeField>::MODULUS.as_ref().to_vec();
let mut max = modulus.clone(); let mut max = modulus.clone();
for limb in &mut max { for limb in &mut max {
*limb = u64::MAX; *limb = u64::MAX;
} }
let modulus_last_limb_bits = <C::ScalarField as PrimeField>::Params::MODULUS_BITS % 64;
let modulus_last_limb_bits = <C::ScalarField as PrimeField>::MODULUS_BIT_SIZE % 64;
*max.last_mut().unwrap() >>= 64 - modulus_last_limb_bits; *max.last_mut().unwrap() >>= 64 - modulus_last_limb_bits;
let scalars = [ let scalars = [
C::ScalarField::rand(&mut rng).into_repr().as_ref().to_vec(),
vec![u64::rand(&mut rng)],
(-C::ScalarField::one()).into_repr().as_ref().to_vec(),
<C::ScalarField as PrimeField>::Params::MODULUS
C::ScalarField::rand(&mut rng)
.into_bigint()
.as_ref() .as_ref()
.to_vec(), .to_vec(),
vec![u64::rand(&mut rng)],
(-C::ScalarField::one()).into_bigint().as_ref().to_vec(),
<C::ScalarField as PrimeField>::MODULUS.as_ref().to_vec(),
max, max,
vec![0; 50], vec![0; 50],
vec![1000012341233u64; 36], vec![1000012341233u64; 36],
@ -585,13 +583,13 @@ pub mod pairing {
}; };
let (ans3_g, ans3_n) = { let (ans3_g, ans3_n) = {
let s_iter = BitIteratorLE::without_trailing_zeros(s.into_repr())
let s_iter = BitIteratorLE::without_trailing_zeros(s.into_bigint())
.map(Boolean::constant) .map(Boolean::constant)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let mut ans_g = P::pairing(a_prep_g, b_prep_g)?; let mut ans_g = P::pairing(a_prep_g, b_prep_g)?;
let mut ans_n = E::pairing(a, b); let mut ans_n = E::pairing(a, b);
ans_n = ans_n.pow(s.into_repr());
ans_n = ans_n.pow(s.into_bigint());
ans_g = ans_g.pow_le(&s_iter)?; ans_g = ans_g.pow_le(&s_iter)?;
(ans_g, ans_n) (ans_g, ans_n)

+ 28
- 0
ed_on_bls12_377/scripts/base_field.sage

@ -0,0 +1,28 @@
modulus = 8444461749428370424248824938781546531375899335154063827935233455917409239041
assert(modulus.is_prime())
Fp = GF(modulus)
generator = Fp(0);
for i in range(0, 30):
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
ed_on_bls12_377/scripts/scalar_field.sage

@ -0,0 +1,28 @@
modulus = 2111115437357092606062206234695386632838870926408408195193685246394721360383
assert(modulus.is_prime())
Fp = GF(modulus)
generator = Fp(0);
for i in range(0, 30):
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)

+ 1
- 2
ed_on_bls12_377/src/constraints/curves.rs

@ -1,7 +1,6 @@
use crate::*;
use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar; use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar;
use crate::constraints::FqVar;
use crate::{constraints::FqVar, *};
/// A variable that is the R1CS equivalent of `crate::EdwardsAffine`. /// A variable that is the R1CS equivalent of `crate::EdwardsAffine`.
pub type EdwardsVar = AffineVar<EdwardsParameters, FqVar>; pub type EdwardsVar = AffineVar<EdwardsParameters, FqVar>;

+ 2
- 1
ed_on_bls12_377/src/constraints/fields.rs

@ -1,6 +1,7 @@
use crate::fq::Fq;
use ark_r1cs_std::fields::fp::FpVar; use ark_r1cs_std::fields::fp::FpVar;
use crate::fq::Fq;
/// A variable that is the R1CS equivalent of `crate::Fq`. /// A variable that is the R1CS equivalent of `crate::Fq`.
pub type FqVar = FpVar<Fq>; pub type FqVar = FpVar<Fq>;

+ 26
- 16
ed_on_bls12_377/src/curves/mod.rs

@ -1,9 +1,10 @@
use crate::{fq::Fq, fr::Fr};
use ark_ec::{ use ark_ec::{
models::{ModelParameters, MontgomeryModelParameters, TEModelParameters}, models::{ModelParameters, MontgomeryModelParameters, TEModelParameters},
twisted_edwards_extended::{GroupAffine, GroupProjective}, twisted_edwards_extended::{GroupAffine, GroupProjective},
}; };
use ark_ff::field_new;
use ark_ff::MontFp;
use crate::{fq::Fq, fr::Fr};
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
@ -23,18 +24,18 @@ impl ModelParameters for EdwardsParameters {
/// COFACTOR_INV = /// COFACTOR_INV =
/// 527778859339273151515551558673846658209717731602102048798421311598680340096 /// 527778859339273151515551558673846658209717731602102048798421311598680340096
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, "527778859339273151515551558673846658209717731602102048798421311598680340096");
const COFACTOR_INV: Fr = MontFp!(
Fr,
"527778859339273151515551558673846658209717731602102048798421311598680340096"
);
} }
impl TEModelParameters for EdwardsParameters { impl TEModelParameters for EdwardsParameters {
/// COEFF_A = -1 /// COEFF_A = -1
#[rustfmt::skip]
const COEFF_A: Fq = field_new!(Fq, "-1");
const COEFF_A: Fq = MontFp!(Fq, "-1");
/// COEFF_D = 3021 /// COEFF_D = 3021
#[rustfmt::skip]
const COEFF_D: Fq = field_new!(Fq, "3021");
const COEFF_D: Fq = MontFp!(Fq, "3021");
/// Generated randomly /// Generated randomly
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y); const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y);
@ -52,22 +53,31 @@ impl TEModelParameters for EdwardsParameters {
impl MontgomeryModelParameters for EdwardsParameters { impl MontgomeryModelParameters for EdwardsParameters {
/// COEFF_A = 0x8D26E3FADA9010A26949031ECE3971B93952AD84D4753DDEDB748DA37E8F552 /// COEFF_A = 0x8D26E3FADA9010A26949031ECE3971B93952AD84D4753DDEDB748DA37E8F552
/// = 3990301581132929505568273333084066329187552697088022219156688740916631500114 /// = 3990301581132929505568273333084066329187552697088022219156688740916631500114
#[rustfmt::skip]
const COEFF_A: Fq = field_new!(Fq, "3990301581132929505568273333084066329187552697088022219156688740916631500114");
const COEFF_A: Fq = MontFp!(
Fq,
"3990301581132929505568273333084066329187552697088022219156688740916631500114"
);
/// COEFF_B = 0x9D8F71EEC83A44C3A1FBCEC6F5418E5C6154C2682B8AC231C5A3725C8170AAD /// COEFF_B = 0x9D8F71EEC83A44C3A1FBCEC6F5418E5C6154C2682B8AC231C5A3725C8170AAD
/// = 4454160168295440918680551605697480202188346638066041608778544715000777738925 /// = 4454160168295440918680551605697480202188346638066041608778544715000777738925
#[rustfmt::skip]
const COEFF_B: Fq = field_new!(Fq, "4454160168295440918680551605697480202188346638066041608778544715000777738925");
const COEFF_B: Fq = MontFp!(
Fq,
"4454160168295440918680551605697480202188346638066041608778544715000777738925"
);
type TEModelParameters = EdwardsParameters; type TEModelParameters = EdwardsParameters;
} }
/// GENERATOR_X = /// GENERATOR_X =
/// 4497879464030519973909970603271755437257548612157028181994697785683032656389, /// 4497879464030519973909970603271755437257548612157028181994697785683032656389,
#[rustfmt::skip]
const GENERATOR_X: Fq = field_new!(Fq, "4497879464030519973909970603271755437257548612157028181994697785683032656389");
const GENERATOR_X: Fq = MontFp!(
Fq,
"4497879464030519973909970603271755437257548612157028181994697785683032656389"
);
/// GENERATOR_Y = /// GENERATOR_Y =
/// 4357141146396347889246900916607623952598927460421559113092863576544024487809 /// 4357141146396347889246900916607623952598927460421559113092863576544024487809
#[rustfmt::skip]
const GENERATOR_Y: Fq = field_new!(Fq, "4357141146396347889246900916607623952598927460421559113092863576544024487809");
const GENERATOR_Y: Fq = MontFp!(
Fq,
"4357141146396347889246900916607623952598927460421559113092863576544024487809"
);

+ 2
- 4
ed_on_bls12_377/src/curves/tests.rs

@ -1,11 +1,9 @@
use ark_algebra_test_templates::{curves::*, groups::*};
use ark_ec::{AffineCurve, ProjectiveCurve}; use ark_ec::{AffineCurve, ProjectiveCurve};
use ark_std::rand::Rng;
use ark_std::test_rng;
use ark_std::{rand::Rng, test_rng};
use crate::*; use crate::*;
use ark_algebra_test_templates::{curves::*, groups::*};
#[test] #[test]
fn test_projective_curve() { fn test_projective_curve() {
curve_tests::<EdwardsProjective>(); curve_tests::<EdwardsProjective>();

+ 1
- 1
ed_on_bls12_377/src/fields/fq.rs

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

+ 6
- 82
ed_on_bls12_377/src/fields/fr.rs

@ -1,83 +1,7 @@
use ark_ff::{
biginteger::{BigInt, BigInteger256 as BigInteger},
fields::{FftParameters, Fp256, Fp256Parameters, FpParameters},
};
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
pub type Fr = Fp256<FrParameters>;
pub struct FrParameters;
impl Fp256Parameters for FrParameters {}
impl FftParameters for FrParameters {
type BigInt = BigInteger;
const TWO_ADICITY: u32 = 1;
#[rustfmt::skip]
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([
15170730761708361161u64,
13670723686578117817u64,
12803492266614043665u64,
50861023252832611u64,
]);
}
impl FpParameters for FrParameters {
/// MODULUS = 2111115437357092606062206234695386632838870926408408195193685246394721360383
#[rustfmt::skip]
const MODULUS: BigInteger = BigInt::new([
13356249993388743167u64,
5950279507993463550u64,
10965441865914903552u64,
336320092672043349u64,
]);
const MODULUS_BITS: u32 = 251;
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
const REPR_SHAVE_BITS: u32 = 5;
#[rustfmt::skip]
const R: BigInteger = BigInt::new([
16632263305389933622u64,
10726299895124897348u64,
16608693673010411502u64,
285459069419210737u64,
]);
#[rustfmt::skip]
const R2: BigInteger = BigInt::new([
3987543627614508126u64,
17742427666091596403u64,
14557327917022607905u64,
322810149704226881u64,
]);
const INV: u64 = 9659935179256617473u64;
// 70865795004005329077606947863872807680085016823885970091001235374859923341923
#[rustfmt::skip]
const GENERATOR: BigInteger = BigInt::new([
11289572479685143826u64,
11383637369941080925u64,
2288212753973340071u64,
82014976407880291u64,
]);
#[rustfmt::skip]
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
6678124996694371583u64,
2975139753996731775u64,
14706092969812227584u64,
168160046336021674u64,
]);
const T: BigInteger = Self::MODULUS_MINUS_ONE_DIV_TWO;
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
0xae56bba6b0cff67f,
0x14a4e8ebf10f22bf,
0x660b44d1e5c37b00,
0x12ab655e9a2ca55,
]);
}
#[derive(MontConfig)]
#[modulus = "2111115437357092606062206234695386632838870926408408195193685246394721360383"]
#[generator = "5"]
pub struct FrConfig;
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;

+ 1
- 1
ed_on_bls12_377/src/fields/mod.rs

@ -4,5 +4,5 @@ pub mod fr;
pub use fq::*; pub use fq::*;
pub use fr::*; pub use fr::*;
#[cfg(all(feature = "ed_on_bls12_377", test))]
#[cfg(test)]
mod tests; mod tests;

+ 15
- 24
ed_on_bls12_377/src/fields/tests.rs

@ -1,24 +1,15 @@
use ark_std::rand::Rng;
use ark_std::test_rng;
use crate::{Fq, Fr};
use ark_algebra_test_templates::fields::*;
#[test]
fn test_fr() {
let mut rng = test_rng();
let a: Fr = rng.gen();
let b: Fr = rng.gen();
field_test(a, b);
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>();
}
use ark_algebra_test_templates::{
fields::*, generate_field_serialization_test, generate_field_test,
};
use ark_ff::{
fields::{Field, PrimeField, SquareRootField},
One, UniformRand, Zero,
};
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
use ark_std::{rand::Rng, test_rng};
use core::ops::{AddAssign, MulAssign, SubAssign};
use crate::{Fq, FqConfig, Fr, FrConfig};
generate_field_test!(ed_on_bls12_377; mont(4, 4); );
generate_field_serialization_test!(ed_on_bls12_377;);

+ 8
- 6
ed_on_bls12_377/src/lib.rs

@ -8,14 +8,16 @@
)] )]
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
//! This library implements a twisted Edwards curve whose base field is the scalar field of the
//! curve BLS12-377. This allows defining cryptographic primitives that use elliptic curves over
//! the scalar field of the latter curve. This curve was generated as part of the paper
//! [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962).
//! This library implements a twisted Edwards curve whose base field is the
//! scalar field of the curve BLS12-377. This allows defining cryptographic
//! primitives that use elliptic curves over the scalar field of the latter
//! curve. This curve was generated as part of the paper [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962).
//! //!
//! Curve information: //! Curve information:
//! * Base field: q = 8444461749428370424248824938781546531375899335154063827935233455917409239041
//! * Scalar field: r = 2111115437357092606062206234695386632838870926408408195193685246394721360383
//! * Base field: q =
//! 8444461749428370424248824938781546531375899335154063827935233455917409239041
//! * Scalar field: r =
//! 2111115437357092606062206234695386632838870926408408195193685246394721360383
//! * Valuation(q - 1, 2) = 47 //! * Valuation(q - 1, 2) = 47
//! * Valuation(r - 1, 2) = 1 //! * Valuation(r - 1, 2) = 1
//! * Curve equation: ax^2 + y^2 =1 + dx^2y^2, where //! * Curve equation: ax^2 + y^2 =1 + dx^2y^2, where

+ 28
- 0
ed_on_bls12_381/scripts/base_field.sage

@ -0,0 +1,28 @@
modulus = 52435875175126190479447740508185965837690552500527637822603658699938581184513
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
ed_on_bls12_381/scripts/scalar_field.sage

@ -0,0 +1,28 @@
modulus = 6554484396890773809930967563523245729705921265872317281365359162392183254199
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)

+ 1
- 2
ed_on_bls12_381/src/constraints/curves.rs

@ -1,7 +1,6 @@
use crate::*;
use ark_r1cs_std::groups::curves::{short_weierstrass::ProjectiveVar, twisted_edwards::AffineVar}; use ark_r1cs_std::groups::curves::{short_weierstrass::ProjectiveVar, twisted_edwards::AffineVar};
use crate::constraints::FqVar;
use crate::{constraints::FqVar, *};
/// A variable that is the R1CS equivalent of `crate::EdwardsAffine`. /// A variable that is the R1CS equivalent of `crate::EdwardsAffine`.
pub type EdwardsVar = AffineVar<JubjubParameters, FqVar>; pub type EdwardsVar = AffineVar<JubjubParameters, FqVar>;

+ 41
- 24
ed_on_bls12_381/src/curves/mod.rs

@ -1,4 +1,3 @@
use crate::{Fq, Fr};
use ark_ec::{ use ark_ec::{
models::{ModelParameters, MontgomeryModelParameters, TEModelParameters}, models::{ModelParameters, MontgomeryModelParameters, TEModelParameters},
short_weierstrass_jacobian::{ short_weierstrass_jacobian::{
@ -7,7 +6,9 @@ use ark_ec::{
twisted_edwards_extended::{GroupAffine, GroupProjective}, twisted_edwards_extended::{GroupAffine, GroupProjective},
SWModelParameters, SWModelParameters,
}; };
use ark_ff::field_new;
use ark_ff::MontFp;
use crate::{Fq, Fr};
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
@ -64,18 +65,21 @@ impl ModelParameters for JubjubParameters {
/// COFACTOR^(-1) mod r = /// COFACTOR^(-1) mod r =
/// 819310549611346726241370945440405716213240158234039660170669895299022906775 /// 819310549611346726241370945440405716213240158234039660170669895299022906775
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, "819310549611346726241370945440405716213240158234039660170669895299022906775");
const COFACTOR_INV: Fr = MontFp!(
Fr,
"819310549611346726241370945440405716213240158234039660170669895299022906775"
);
} }
impl TEModelParameters for JubjubParameters { impl TEModelParameters for JubjubParameters {
/// COEFF_A = -1 /// COEFF_A = -1
#[rustfmt::skip]
const COEFF_A: Fq = field_new!(Fq, "-1");
const COEFF_A: Fq = MontFp!(Fq, "-1");
/// COEFF_D = (10240/10241) mod q /// COEFF_D = (10240/10241) mod q
#[rustfmt::skip]
const COEFF_D: Fq = field_new!(Fq, "19257038036680949359750312669786877991949435402254120286184196891950884077233");
const COEFF_D: Fq = MontFp!(
Fq,
"19257038036680949359750312669786877991949435402254120286184196891950884077233"
);
/// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y) /// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y); const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y);
@ -91,28 +95,36 @@ impl TEModelParameters for JubjubParameters {
impl MontgomeryModelParameters for JubjubParameters { impl MontgomeryModelParameters for JubjubParameters {
/// COEFF_A = 40962 /// COEFF_A = 40962
#[rustfmt::skip]
const COEFF_A: Fq = field_new!(Fq, "40962");
const COEFF_A: Fq = MontFp!(Fq, "40962");
/// COEFF_B = -40964 /// COEFF_B = -40964
#[rustfmt::skip]
const COEFF_B: Fq = field_new!(Fq, "-40964");
const COEFF_B: Fq = MontFp!(Fq, "-40964");
type TEModelParameters = JubjubParameters; type TEModelParameters = JubjubParameters;
} }
#[rustfmt::skip]
const GENERATOR_X: Fq = field_new!(Fq, "8076246640662884909881801758704306714034609987455869804520522091855516602923");
#[rustfmt::skip]
const GENERATOR_Y: Fq = field_new!(Fq, "13262374693698910701929044844600465831413122818447359594527400194675274060458");
const GENERATOR_X: Fq = MontFp!(
Fq,
"8076246640662884909881801758704306714034609987455869804520522091855516602923"
);
const GENERATOR_Y: Fq = MontFp!(
Fq,
"13262374693698910701929044844600465831413122818447359594527400194675274060458"
);
impl SWModelParameters for JubjubParameters { impl SWModelParameters for JubjubParameters {
/// COEFF_A = 52296097456646850916096512823759002727550416093741407922227928430486925478210 /// COEFF_A = 52296097456646850916096512823759002727550416093741407922227928430486925478210
#[rustfmt::skip]
const COEFF_A: Self::BaseField = field_new!(Fq, "52296097456646850916096512823759002727550416093741407922227928430486925478210");
const COEFF_A: Self::BaseField = MontFp!(
Fq,
"52296097456646850916096512823759002727550416093741407922227928430486925478210"
);
/// COEFF_B = 48351165704696163914533707656614864561753505123260775585269522553028192119009 /// COEFF_B = 48351165704696163914533707656614864561753505123260775585269522553028192119009
#[rustfmt::skip]
const COEFF_B: Self::BaseField = field_new!(Fq, "48351165704696163914533707656614864561753505123260775585269522553028192119009");
const COEFF_B: Self::BaseField = MontFp!(
Fq,
"48351165704696163914533707656614864561753505123260775585269522553028192119009"
);
/// generators /// generators
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
@ -120,8 +132,13 @@ impl SWModelParameters for JubjubParameters {
} }
/// x coordinate for SW curve generator /// x coordinate for SW curve generator
#[rustfmt::skip]
const SW_GENERATOR_X: Fq = field_new!(Fq, "33835869156188682335217394949746694649676633840125476177319971163079011318731");
const SW_GENERATOR_X: Fq = MontFp!(
Fq,
"33835869156188682335217394949746694649676633840125476177319971163079011318731"
);
/// y coordinate for SW curve generator /// y coordinate for SW curve generator
#[rustfmt::skip]
const SW_GENERATOR_Y: Fq = field_new!(Fq, "43777270878440091394432848052353307184915192688165709016756678962558652055320");
const SW_GENERATOR_Y: Fq = MontFp!(
Fq,
"43777270878440091394432848052353307184915192688165709016756678962558652055320"
);

+ 1
- 2
ed_on_bls12_381/src/curves/tests.rs

@ -1,11 +1,10 @@
use ark_algebra_test_templates::{curves::*, groups::*};
use ark_ec::{AffineCurve, ProjectiveCurve}; use ark_ec::{AffineCurve, ProjectiveCurve};
use ark_ff::{bytes::FromBytes, Zero}; use ark_ff::{bytes::FromBytes, Zero};
use ark_std::{rand::Rng, str::FromStr, test_rng}; use ark_std::{rand::Rng, str::FromStr, test_rng};
use crate::*; use crate::*;
use ark_algebra_test_templates::{curves::*, groups::*};
#[test] #[test]
fn test_projective_curve() { fn test_projective_curve() {
curve_tests::<EdwardsProjective>(); curve_tests::<EdwardsProjective>();

+ 1
- 1
ed_on_bls12_381/src/fields/fq.rs

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

+ 6
- 80
ed_on_bls12_381/src/fields/fr.rs

@ -1,81 +1,7 @@
use ark_ff::{
biginteger::{BigInt, BigInteger256 as BigInteger},
fields::{FftParameters, Fp256, Fp256Parameters, FpParameters},
};
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
pub type Fr = Fp256<FrParameters>;
pub struct FrParameters;
impl Fp256Parameters for FrParameters {}
impl FftParameters for FrParameters {
type BigInt = BigInteger;
const TWO_ADICITY: u32 = 1;
#[rustfmt::skip]
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([
0xaa9f02ab1d6124de,
0xb3524a6466112932,
0x7342261215ac260b,
0x4d6b87b1da259e2,
]);
}
impl FpParameters for FrParameters {
/// MODULUS = 6554484396890773809930967563523245729705921265872317281365359162392183254199.
#[rustfmt::skip]
const MODULUS: BigInteger = BigInt::new([
0xd0970e5ed6f72cb7,
0xa6682093ccc81082,
0x6673b0101343b00,
0xe7db4ea6533afa9,
]);
const MODULUS_BITS: u32 = 252;
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
const REPR_SHAVE_BITS: u32 = 4;
#[rustfmt::skip]
const R: BigInteger = BigInt::new([
0x25f80bb3b99607d9,
0xf315d62f66b6e750,
0x932514eeeb8814f4,
0x9a6fc6f479155c6,
]);
#[rustfmt::skip]
const R2: BigInteger = BigInt::new([
0x67719aa495e57731,
0x51b0cef09ce3fc26,
0x69dab7fac026e9a5,
0x4f6547b8d127688,
]);
const INV: u64 = 0x1ba3a358ef788ef9;
#[rustfmt::skip]
const GENERATOR: BigInteger = BigInt::new([
0x720b1b19d49ea8f1,
0xbf4aa36101f13a58,
0x5fa8cc968193ccbb,
0xe70cbdc7dccf3ac,
]);
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
7515249040934278747,
5995434913520945217,
9454073218019761536,
522094803716528084,
]);
const T: BigInteger = Self::MODULUS_MINUS_ONE_DIV_TWO;
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([
12980996557321915181,
2997717456760472608,
4727036609009880768,
261047401858264042,
]);
}
#[derive(MontConfig)]
#[modulus = "6554484396890773809930967563523245729705921265872317281365359162392183254199"]
#[generator = "6"]
pub struct FrConfig;
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;

+ 1
- 1
ed_on_bls12_381/src/fields/mod.rs

@ -4,5 +4,5 @@ pub mod fr;
pub use fq::*; pub use fq::*;
pub use fr::*; pub use fr::*;
#[cfg(all(feature = "ed_on_bls12_381", test))]
#[cfg(test)]
mod tests; mod tests;

+ 24
- 66
ed_on_bls12_381/src/fields/tests.rs

@ -1,33 +1,20 @@
use crate::{Fq, Fr};
use ark_algebra_test_templates::{
fields::*, generate_field_serialization_test, generate_field_test,
};
use ark_ff::{ use ark_ff::{
biginteger::BigInteger256 as BigInteger, biginteger::BigInteger256 as BigInteger,
bytes::{FromBytes, ToBytes}, bytes::{FromBytes, ToBytes},
fields::{Field, LegendreSymbol::*, SquareRootField},
One, Zero,
fields::{Field, LegendreSymbol::*, PrimeField, SquareRootField},
One, UniformRand, Zero,
}; };
use ark_std::test_rng;
use ark_algebra_test_templates::fields::*;
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
use ark_std::{rand::Rng, str::FromStr, test_rng};
use core::ops::{AddAssign, MulAssign, SubAssign};
use ark_std::{rand::Rng, str::FromStr};
#[test]
fn test_fr() {
let mut rng = test_rng();
let a: Fr = rng.gen();
let b: Fr = rng.gen();
field_test(a, b);
primefield_test::<Fr>();
}
use crate::{Fq, FqConfig, Fr, FrConfig};
#[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>();
}
generate_field_test!(ed_on_bls12_381; mont(4, 4); );
generate_field_serialization_test!(ed_on_bls12_381;);
#[test] #[test]
fn test_fq_add() { fn test_fq_add() {
@ -148,22 +135,6 @@ fn test_fq_sub() {
assert_eq!(f1 - &f2, f3); assert_eq!(f1 - &f2, f3);
} }
#[test]
fn test_fq_double_in_place() {
let mut f1 = Fq::from_str(
"29729289787452206300641229002276778748586801323231253291984198106063944136114",
)
.unwrap();
let f3 = Fq::from_str(
"7022704399778222121834717496367591659483050145934868761364737512189307087715",
)
.unwrap();
assert!(!f1.is_zero());
assert!(!f3.is_zero());
f1.double_in_place();
assert_eq!(f1, f3);
}
#[test] #[test]
fn test_fq_double_in_place_thrice() { fn test_fq_double_in_place_thrice() {
let mut f1 = Fq::from_str( let mut f1 = Fq::from_str(
@ -280,22 +251,9 @@ fn test_fq_square_in_place() {
assert_eq!(f1, f3); assert_eq!(f1, f3);
} }
#[test]
fn test_fq_sqrt() {
let f1 = Fq::from_str(
"10875927553327821418567659853801220899541454800710193788767706167237535308235",
)
.unwrap();
let f3 = Fq::from_str(
"10816221372957505053219354782681292880545918527618367765651802809826238616708",
)
.unwrap();
assert_eq!(f1.sqrt().unwrap(), f3);
}
#[test] #[test]
fn test_fq_from_str() { fn test_fq_from_str() {
let f1_from_repr = Fq::from(BigInteger([
let f1_from_repr = Fq::from(BigInteger::new([
0xab8a2535947d1a77, 0xab8a2535947d1a77,
0x9ba74cbfda0bbcda, 0x9ba74cbfda0bbcda,
0xe928b59724d60baf, 0xe928b59724d60baf,
@ -305,7 +263,7 @@ fn test_fq_from_str() {
"13026376210409056429264774981357153555336288129100724591327877625017068755575", "13026376210409056429264774981357153555336288129100724591327877625017068755575",
) )
.unwrap(); .unwrap();
let f2_from_repr = Fq::from(BigInteger([
let f2_from_repr = Fq::from(BigInteger::new([
0x97e9103775d2f35c, 0x97e9103775d2f35c,
0xbe6756b6c587544b, 0xbe6756b6c587544b,
0x6ee38c3afd88ef4b, 0x6ee38c3afd88ef4b,
@ -324,14 +282,14 @@ fn test_fq_legendre() {
assert_eq!(QuadraticResidue, Fq::one().legendre()); assert_eq!(QuadraticResidue, Fq::one().legendre());
assert_eq!(Zero, Fq::zero().legendre()); assert_eq!(Zero, Fq::zero().legendre());
let e = BigInteger([
let e = BigInteger::new([
0x0dbc5349cd5664da, 0x0dbc5349cd5664da,
0x8ac5b6296e3ae29d, 0x8ac5b6296e3ae29d,
0x127cb819feceaa3b, 0x127cb819feceaa3b,
0x3a6b21fb03867191, 0x3a6b21fb03867191,
]); ]);
assert_eq!(QuadraticResidue, Fq::from(e).legendre()); assert_eq!(QuadraticResidue, Fq::from(e).legendre());
let e = BigInteger([
let e = BigInteger::new([
0x96341aefd047c045, 0x96341aefd047c045,
0x9b5f4254500a4d65, 0x9b5f4254500a4d65,
0x1ee08223b68ac240, 0x1ee08223b68ac240,
@ -342,7 +300,7 @@ fn test_fq_legendre() {
#[test] #[test]
fn test_fq_bytes() { fn test_fq_bytes() {
let f1_from_repr = Fq::from(BigInteger([
let f1_from_repr = Fq::from(BigInteger::new([
0xab8a2535947d1a77, 0xab8a2535947d1a77,
0x9ba74cbfda0bbcda, 0x9ba74cbfda0bbcda,
0xe928b59724d60baf, 0xe928b59724d60baf,
@ -358,19 +316,19 @@ fn test_fq_bytes() {
#[test] #[test]
fn test_fr_add() { fn test_fr_add() {
let f1 = Fr::from(BigInteger([
let f1 = Fr::from(BigInteger::new([
0xc81265fb4130fe0c, 0xc81265fb4130fe0c,
0xb308836c14e22279, 0xb308836c14e22279,
0x699e887f96bff372, 0x699e887f96bff372,
0x84ecc7e76c11ad, 0x84ecc7e76c11ad,
])); ]));
let f2 = Fr::from(BigInteger([
let f2 = Fr::from(BigInteger::new([
0x71875719b422efb8, 0x71875719b422efb8,
0x43658e68a93612, 0x43658e68a93612,
0x9fa756be2011e833, 0x9fa756be2011e833,
0xaa2b2cb08dac497, 0xaa2b2cb08dac497,
])); ]));
let f3 = Fr::from(BigInteger([
let f3 = Fr::from(BigInteger::new([
0x3999bd14f553edc4, 0x3999bd14f553edc4,
0xb34be8fa7d8b588c, 0xb34be8fa7d8b588c,
0x945df3db6d1dba5, 0x945df3db6d1dba5,
@ -381,19 +339,19 @@ fn test_fr_add() {
#[test] #[test]
fn test_fr_mul() { fn test_fr_mul() {
let f1 = Fr::from(BigInteger([
let f1 = Fr::from(BigInteger::new([
0xc81265fb4130fe0c, 0xc81265fb4130fe0c,
0xb308836c14e22279, 0xb308836c14e22279,
0x699e887f96bff372, 0x699e887f96bff372,
0x84ecc7e76c11ad, 0x84ecc7e76c11ad,
])); ]));
let f2 = Fr::from(BigInteger([
let f2 = Fr::from(BigInteger::new([
0x71875719b422efb8, 0x71875719b422efb8,
0x43658e68a93612, 0x43658e68a93612,
0x9fa756be2011e833, 0x9fa756be2011e833,
0xaa2b2cb08dac497, 0xaa2b2cb08dac497,
])); ]));
let f3 = Fr::from(BigInteger([
let f3 = Fr::from(BigInteger::new([
0x6d6618ac6b4a8381, 0x6d6618ac6b4a8381,
0x5b9eb35d711ee1da, 0x5b9eb35d711ee1da,
0xce83310e6ac4105d, 0xce83310e6ac4105d,
@ -404,7 +362,7 @@ fn test_fr_mul() {
#[test] #[test]
fn test_fr_bytes() { fn test_fr_bytes() {
let f1_from_repr = Fr::from(BigInteger([
let f1_from_repr = Fr::from(BigInteger::new([
0xc81265fb4130fe0c, 0xc81265fb4130fe0c,
0xb308836c14e22279, 0xb308836c14e22279,
0x699e887f96bff372, 0x699e887f96bff372,
@ -420,7 +378,7 @@ fn test_fr_bytes() {
#[test] #[test]
fn test_fr_from_str() { fn test_fr_from_str() {
let f100_from_repr = Fr::from(BigInteger([0x64, 0, 0, 0]));
let f100_from_repr = Fr::from(BigInteger::new([0x64, 0, 0, 0]));
let f100 = Fr::from_str("100").unwrap(); let f100 = Fr::from_str("100").unwrap();
assert_eq!(f100_from_repr, f100); assert_eq!(f100_from_repr, f100);
} }

+ 5
- 5
ed_on_bls12_381_bandersnatch/Cargo.toml

@ -25,10 +25,10 @@ ark-curve-constraint-tests = { path = "../curve-constraint-tests", default-featu
[features] [features]
default = [] default = []
std = [
"ark-std/std",
"ark-ff/std",
"ark-ec/std",
"ark-bls12-381/std"
std = [
"ark-std/std",
"ark-ff/std",
"ark-ec/std",
"ark-bls12-381/std"
] ]
r1cs = ["ark-r1cs-std"] r1cs = ["ark-r1cs-std"]

+ 28
- 0
ed_on_bls12_381_bandersnatch/scripts/base_field.sage

@ -0,0 +1,28 @@
modulus = 52435875175126190479447740508185965837690552500527637822603658699938581184513
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
ed_on_bls12_381_bandersnatch/scripts/scalar_field.sage

@ -0,0 +1,28 @@
modulus = 13108968793781547619861935127046491459309155893440570251786403306729687672801
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)

+ 2
- 1
ed_on_bls12_381_bandersnatch/src/constraints/curves.rs

@ -1,6 +1,7 @@
use crate::{constraints::FqVar, *};
use ark_r1cs_std::groups::curves::{short_weierstrass::ProjectiveVar, twisted_edwards::AffineVar}; use ark_r1cs_std::groups::curves::{short_weierstrass::ProjectiveVar, twisted_edwards::AffineVar};
use crate::{constraints::FqVar, *};
/// A variable that is the R1CS equivalent of `crate::BandersnatchParameters`. /// A variable that is the R1CS equivalent of `crate::BandersnatchParameters`.
pub type EdwardsVar = AffineVar<BandersnatchParameters, FqVar>; pub type EdwardsVar = AffineVar<BandersnatchParameters, FqVar>;

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save