mirror of
https://github.com/arnaucube/ark-curves-cherry-picked.git
synced 2026-01-27 22:23:48 +01:00
Compare commits
1 Commits
v0.4.0-alp
...
sjoseph/bi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60b6e5d63b |
44
.github/workflows/ci.yml
vendored
44
.github/workflows/ci.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v1
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
@@ -41,7 +41,7 @@ jobs:
|
|||||||
- nightly
|
- nightly
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Install Rust (${{ matrix.rust }})
|
- name: Install Rust (${{ matrix.rust }})
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -78,6 +78,7 @@ jobs:
|
|||||||
args: --all-features --examples --workspace --benches
|
args: --all-features --examples --workspace --benches
|
||||||
if: matrix.rust == 'nightly'
|
if: matrix.rust == 'nightly'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
directories: # Job that list subdirectories
|
directories: # Job that list subdirectories
|
||||||
name: List directories for parallelizing tests
|
name: List directories for parallelizing tests
|
||||||
@@ -85,7 +86,7 @@ jobs:
|
|||||||
outputs:
|
outputs:
|
||||||
dir: ${{ steps.set-dirs.outputs.dir }} # generate output name dir by using inner step output
|
dir: ${{ steps.set-dirs.outputs.dir }} # generate output name dir by using inner step output
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
- id: set-dirs # Give it an id to handle to get step outputs in the outputs key above
|
- id: set-dirs # Give it an id to handle to get step outputs in the outputs key above
|
||||||
run: echo "::set-output name=dir::$(ls -d */ | jq -R -s -c 'split("\n")[:-1]')"
|
run: echo "::set-output name=dir::$(ls -d */ | jq -R -s -c 'split("\n")[:-1]')"
|
||||||
# Define step output named dir base on ls command transformed to JSON thanks to jq
|
# Define step output named dir base on ls command transformed to JSON thanks to jq
|
||||||
@@ -102,47 +103,22 @@ jobs:
|
|||||||
exclude:
|
exclude:
|
||||||
- dir: scripts/
|
- dir: scripts/
|
||||||
- dir: curve-constraint-tests/
|
- dir: curve-constraint-tests/
|
||||||
- dir: mnt4_753/
|
- dir: curve-benches/
|
||||||
- dir: mnt6_753/
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v2
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: |
|
run: |
|
||||||
cd ${{matrix.dir}}
|
cd ${{matrix.dir}}
|
||||||
cargo test --all-features
|
cargo test --all-features
|
||||||
|
|
||||||
test-mnt4-753:
|
|
||||||
name: Test (mnt4_753/)
|
|
||||||
runs-on: macos-latest
|
|
||||||
needs: [directories] # Waits for the directory listing job
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Run tests
|
|
||||||
run: |
|
|
||||||
cd mnt4_753/
|
|
||||||
cargo test --all-features
|
|
||||||
|
|
||||||
test-mnt6-753:
|
|
||||||
name: Test (mnt6_753/)
|
|
||||||
runs-on: macos-latest
|
|
||||||
needs: [directories] # Waits for the directory listing job
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Run tests
|
|
||||||
run: |
|
|
||||||
cd mnt6_753/
|
|
||||||
cargo test --all-features
|
|
||||||
|
|
||||||
docs:
|
docs:
|
||||||
name: Check Documentation
|
name: Check Documentation
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v1
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
@@ -162,7 +138,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Install Rust (${{ matrix.rust }})
|
- name: Install Rust (${{ matrix.rust }})
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -183,10 +159,10 @@ jobs:
|
|||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: check
|
command: check
|
||||||
args: --examples --workspace --exclude ark-curve-constraint-tests --target aarch64-unknown-none
|
args: --examples --workspace --exclude ark-curve-constraint-tests --exclude ark-curve-benches --target aarch64-unknown-none
|
||||||
|
|
||||||
- name: build
|
- name: build
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: build
|
command: build
|
||||||
args: --workspace --exclude ark-curve-constraint-tests --target aarch64-unknown-none
|
args: --workspace --exclude ark-curve-constraint-tests --exclude ark-curve-benches --target aarch64-unknown-none
|
||||||
|
|||||||
11
CHANGELOG.md
11
CHANGELOG.md
@@ -3,25 +3,14 @@
|
|||||||
## Pending
|
## Pending
|
||||||
|
|
||||||
- [\#76](https://github.com/arkworks-rs/curves/pull/76) twisted Edwards parameters for bls12-377
|
- [\#76](https://github.com/arkworks-rs/curves/pull/76) twisted Edwards parameters for bls12-377
|
||||||
- Fixed curve benches
|
|
||||||
|
|
||||||
### Breaking changes
|
### Breaking changes
|
||||||
|
|
||||||
- [\#104](https://github.com/arkworks-rs/curves/pull/104) Remove `QUADRATIC_NONRESIDUE` parameter from implementors of `Fp2Config`.
|
|
||||||
- [\#129](https://github.com/arkworks-rs/curves/pull/129) Implement custom serialization for BLS12-381 for compatibility with the [Zcash lib](https://github.com/zkcrypto/bls12_381).
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
- [\#121](https://github.com/arkworks-rs/curves/pull/121) Add the ed25519 curve.
|
|
||||||
- [\#124](https://github.com/arkworks-rs/curves/pull/124) Add the curve25519 curve.
|
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|
||||||
- [\#70](https://github.com/arkworks-rs/curves/pull/70) Add prepared G2 pairing consistency test.
|
|
||||||
- [\#74](https://github.com/arkworks-rs/curves/pull/74) Use Scott's subgroup membership tests for `G1` and `G2` of BLS12-381.
|
- [\#74](https://github.com/arkworks-rs/curves/pull/74) Use Scott's subgroup membership tests for `G1` and `G2` of BLS12-381.
|
||||||
- [\#103](https://github.com/arkworks-rs/curves/pull/103) Faster cofactor clearing for BLS12-381.
|
|
||||||
- [\#107](https://github.com/arkworks-rs/curves/pull/107/) Use 2-NAF of `ATE_LOOP_COUNT` to speed up the Miller loop in MNT curves.
|
|
||||||
|
|
||||||
|
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
|
|
||||||
|
|||||||
11
Cargo.toml
11
Cargo.toml
@@ -1,6 +1,7 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
|
|
||||||
members = [
|
members = [
|
||||||
|
"curve-benches",
|
||||||
"curve-constraint-tests",
|
"curve-constraint-tests",
|
||||||
|
|
||||||
"bls12_377",
|
"bls12_377",
|
||||||
@@ -29,11 +30,7 @@ members = [
|
|||||||
|
|
||||||
"pallas",
|
"pallas",
|
||||||
"vesta",
|
"vesta",
|
||||||
|
|
||||||
"curve25519",
|
|
||||||
"ed25519",
|
|
||||||
]
|
]
|
||||||
resolver = "2"
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
@@ -59,3 +56,9 @@ lto = "thin"
|
|||||||
incremental = true
|
incremental = true
|
||||||
debug-assertions = true
|
debug-assertions = true
|
||||||
debug = true
|
debug = true
|
||||||
|
|
||||||
|
# To be removed in the new release.
|
||||||
|
[patch.crates-io]
|
||||||
|
ark-ec = { 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" }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-bls12-377"
|
name = "ark-bls12-377"
|
||||||
version = "0.4.0-alpha.1"
|
version = "0.3.0"
|
||||||
authors = [ "arkworks contributors" ]
|
authors = [ "arkworks contributors" ]
|
||||||
description = "The BLS12-377 pairing-friendly elliptic curve"
|
description = "The BLS12-377 pairing-friendly elliptic curve"
|
||||||
homepage = "https://arkworks.rs"
|
homepage = "https://arkworks.rs"
|
||||||
@@ -10,19 +10,18 @@ keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
|||||||
categories = ["cryptography"]
|
categories = ["cryptography"]
|
||||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
edition = "2021"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ark-ff = { version="0.4.0-alpha", default-features = false }
|
ark-ff = { version="^0.3.0", default-features = false }
|
||||||
ark-ec = { version="0.4.0-alpha", default-features = false }
|
ark-ec = { version="^0.3.0", default-features = false }
|
||||||
ark-r1cs-std = { version="0.4.0-alpha", default-features = false, optional = true }
|
ark-r1cs-std = { version="^0.3.0", default-features = false, optional = true }
|
||||||
ark-std = { version = "0.4.0-alpha", default-features = false }
|
ark-std = { version="^0.3.0", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ark-relations = { version="0.4.0-alpha", default-features = false }
|
ark-relations = { version="^0.3.0", default-features = false }
|
||||||
ark-serialize = { version = "0.4.0-alpha", default-features = false }
|
ark-serialize = { version="^0.3.0", default-features = false }
|
||||||
ark-algebra-test-templates = { version = "0.4.0-alpha", default-features = false }
|
ark-algebra-test-templates = { version="^0.3.0", default-features = false }
|
||||||
ark-algebra-bench-templates = { version = "0.4.0-alpha", default-features = false }
|
|
||||||
ark-curve-constraint-tests = { path = "../curve-constraint-tests", default-features = false }
|
ark-curve-constraint-tests = { path = "../curve-constraint-tests", default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
@@ -32,9 +31,4 @@ std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ]
|
|||||||
curve = [ "scalar_field", "base_field" ]
|
curve = [ "scalar_field", "base_field" ]
|
||||||
scalar_field = []
|
scalar_field = []
|
||||||
base_field = []
|
base_field = []
|
||||||
r1cs = [ "base_field", "ark-r1cs-std" ]
|
r1cs = [ "base_field", "ark-r1cs-std" ]
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "bls12_377"
|
|
||||||
path = "benches/bls12_377.rs"
|
|
||||||
harness = false
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
use ark_algebra_bench_templates::*;
|
|
||||||
|
|
||||||
use ark_bls12_377::{
|
|
||||||
fq::Fq, fq2::Fq2, fr::Fr, Bls12_377, Fq12, G1Projective as G1, G2Projective as G2,
|
|
||||||
};
|
|
||||||
|
|
||||||
bench!(
|
|
||||||
Name = "Bls12_377",
|
|
||||||
Pairing = Bls12_377,
|
|
||||||
G1 = G1,
|
|
||||||
G2 = G2,
|
|
||||||
ScalarField = Fr,
|
|
||||||
G1BaseField = Fq,
|
|
||||||
G2BaseField = Fq2,
|
|
||||||
TargetField = Fq12,
|
|
||||||
);
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
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)
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
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)
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
use ark_ec::{bls12::Bls12Parameters, CurveConfig};
|
use crate::Parameters;
|
||||||
|
use ark_ec::bls12::Bls12Parameters;
|
||||||
|
use ark_ec::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.
|
||||||
@@ -14,7 +14,7 @@ pub type G2Var = bls12::G2Var<Parameters>;
|
|||||||
/// An element of G1 (in TE Affine form) in the BLS12-377 bilinear group.
|
/// An element of G1 (in TE Affine form) in the BLS12-377 bilinear group.
|
||||||
pub type G1TEAffineVar = TEAffineVar<
|
pub type G1TEAffineVar = TEAffineVar<
|
||||||
<Parameters as Bls12Parameters>::G1Parameters,
|
<Parameters as Bls12Parameters>::G1Parameters,
|
||||||
FpVar<<<Parameters as Bls12Parameters>::G1Parameters as CurveConfig>::BaseField>,
|
FpVar<<<Parameters as Bls12Parameters>::G1Parameters as ModelParameters>::BaseField>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/// Represents the cached precomputation that can be performed on a G1 element
|
/// Represents the cached precomputation that can be performed on a G1 element
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
use ark_r1cs_std::fields::{fp::FpVar, fp12::Fp12Var, fp2::Fp2Var, fp6_3over2::Fp6Var};
|
use crate::{Fq, Fq12Parameters, Fq2Parameters, Fq6Parameters};
|
||||||
|
|
||||||
use crate::{Fq, Fq12Config, Fq2Config, Fq6Config};
|
use ark_r1cs_std::fields::{fp::FpVar, fp12::Fp12Var, fp2::Fp2Var, fp6_3over2::Fp6Var};
|
||||||
|
|
||||||
/// 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<Fq2Config>;
|
pub type Fq2Var = Fp2Var<Fq2Parameters>;
|
||||||
/// A variable that is the R1CS equivalent of `crate::Fq6`.
|
/// A variable that is the R1CS equivalent of `crate::Fq6`.
|
||||||
pub type Fq6Var = Fp6Var<Fq6Config>;
|
pub type Fq6Var = Fp6Var<Fq6Parameters>;
|
||||||
/// A variable that is the R1CS equivalent of `crate::Fq12`.
|
/// A variable that is the R1CS equivalent of `crate::Fq12`.
|
||||||
pub type Fq12Var = Fp12Var<Fq12Config>;
|
pub type Fq12Var = Fp12Var<Fq12Parameters>;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bls12_377_field_test() {
|
fn bls12_377_field_test() {
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
//! ```
|
//! ```
|
||||||
//! # fn main() -> Result<(), ark_relations::r1cs::SynthesisError> {
|
//! # fn main() -> Result<(), ark_relations::r1cs::SynthesisError> {
|
||||||
//! # use ark_std::UniformRand;
|
//! # use ark_std::UniformRand;
|
||||||
//! # use ark_ec::pairing::Pairing;
|
//! # use ark_ec::PairingEngine;
|
||||||
//! # use ark_relations::r1cs::*;
|
//! # use ark_relations::r1cs::*;
|
||||||
//! # use ark_r1cs_std::prelude::*;
|
//! # use ark_r1cs_std::prelude::*;
|
||||||
//! # use ark_bls12_377::{*, constraints::*};
|
//! # use ark_bls12_377::{*, constraints::*};
|
||||||
@@ -135,7 +135,7 @@
|
|||||||
//! let pairing_result = constraints::PairingVar::pairing(a_prep, b_prep)?;
|
//! let pairing_result = constraints::PairingVar::pairing(a_prep, b_prep)?;
|
||||||
//!
|
//!
|
||||||
//! // Check that the value of &a + &b is correct.
|
//! // Check that the value of &a + &b is correct.
|
||||||
//! assert_eq!(pairing_result.value()?, pairing_result_native.0);
|
//! assert_eq!(pairing_result.value()?, pairing_result_native);
|
||||||
//!
|
//!
|
||||||
//! // Check that operations on variables and constants are equivalent.
|
//! // Check that operations on variables and constants are equivalent.
|
||||||
//! let a_prep_const = constraints::PairingVar::prepare_g1(&a_const)?;
|
//! let a_prep_const = constraints::PairingVar::prepare_g1(&a_const)?;
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
use crate::Parameters;
|
use crate::Parameters;
|
||||||
|
|
||||||
/// Specifies the constraints for computing a pairing in the BLS12-377 bilinear
|
/// Specifies the constraints for computing a pairing in the BLS12-377 bilinear group.
|
||||||
/// group.
|
|
||||||
pub type PairingVar = ark_r1cs_std::pairing::bls12::PairingVar<Parameters>;
|
pub type PairingVar = ark_r1cs_std::pairing::bls12::PairingVar<Parameters>;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
use crate::Bls12_377;
|
use crate::Bls12_377;
|
||||||
ark_curve_constraint_tests::pairing::bilinearity_test::<Bls12_377, PairingVar>().unwrap();
|
ark_curve_constraint_tests::pairing::bilinearity_test::<Bls12_377, PairingVar>().unwrap()
|
||||||
ark_curve_constraint_tests::pairing::g2_prepare_consistency_test::<Bls12_377, PairingVar>()
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,55 +1,60 @@
|
|||||||
use ark_ec::models::{
|
use ark_ec::models::{
|
||||||
short_weierstrass::{Affine as SWAffine, SWCurveConfig},
|
twisted_edwards_extended::{
|
||||||
twisted_edwards::{
|
GroupAffine as TEGroupAffine, GroupProjective as TEGroupProjective,
|
||||||
Affine as TEAffine, MontCurveConfig, Projective as TEProjective, TECurveConfig,
|
|
||||||
},
|
},
|
||||||
CurveConfig,
|
ModelParameters, MontgomeryModelParameters, SWModelParameters, TEModelParameters,
|
||||||
};
|
};
|
||||||
use ark_ff::{Field, MontFp, Zero};
|
use ark_ff::{field_new, Zero};
|
||||||
use core::ops::Neg;
|
use core::ops::Neg;
|
||||||
|
|
||||||
use crate::{Fq, Fr};
|
use crate::{
|
||||||
|
fields::{FQ_ONE, FQ_ZERO},
|
||||||
|
Fq, Fr,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl ModelParameters for Parameters {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWModelParameters for Parameters {
|
||||||
|
/// COEFF_A = 0
|
||||||
|
const COEFF_A: Fq = FQ_ZERO;
|
||||||
|
|
||||||
|
/// COEFF_B = 1
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COEFF_B: Fq = FQ_ONE;
|
||||||
|
|
||||||
/// COFACTOR = (x - 1)^2 / 3 = 30631250834960419227450344600217059328
|
/// COFACTOR = (x - 1)^2 / 3 = 30631250834960419227450344600217059328
|
||||||
const COFACTOR: &'static [u64] = &[0x0, 0x170b5d4430000000];
|
const COFACTOR: &'static [u64] = &[0x0, 0x170b5d4430000000];
|
||||||
|
|
||||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
/// = 5285428838741532253824584287042945485047145357130994810877
|
/// = 5285428838741532253824584287042945485047145357130994810877
|
||||||
const COFACTOR_INV: Fr = MontFp!("5285428838741532253824584287042945485047145357130994810877");
|
#[rustfmt::skip]
|
||||||
}
|
const COFACTOR_INV: Fr = field_new!(Fr, "5285428838741532253824584287042945485047145357130994810877");
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
|
||||||
/// COEFF_A = 0
|
|
||||||
const COEFF_A: Fq = Fq::ZERO;
|
|
||||||
|
|
||||||
/// COEFF_B = 1
|
|
||||||
const COEFF_B: Fq = Fq::ONE;
|
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||||
const GENERATOR: G1SWAffine = G1SWAffine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||||
|
(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_by_a(_: Self::BaseField) -> Self::BaseField {
|
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
||||||
Self::BaseField::zero()
|
Self::BaseField::zero()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type G1SWAffine = SWAffine<Parameters>;
|
pub type G1TEAffine = TEGroupAffine<Parameters>;
|
||||||
pub type G1TEAffine = TEAffine<Parameters>;
|
pub type G1TEProjective = TEGroupProjective<Parameters>;
|
||||||
pub type G1TEProjective = TEProjective<Parameters>;
|
|
||||||
|
|
||||||
/// Bls12_377::G1 also has a twisted Edwards form.
|
/// Bls12_377::G1 also has a twisted Edwards form.
|
||||||
/// It can be obtained via the following script, implementing
|
/// It can be obtained via the following script, implementing
|
||||||
/// 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)
|
||||||
@@ -91,22 +96,33 @@ pub type G1TEProjective = TEProjective<Parameters>;
|
|||||||
/// TE2a = Fp(-1)
|
/// TE2a = Fp(-1)
|
||||||
/// # b = -TE1d/TE1a
|
/// # b = -TE1d/TE1a
|
||||||
/// TE2d = Fp(122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179)
|
/// TE2d = Fp(122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179)
|
||||||
|
///
|
||||||
/// ```
|
/// ```
|
||||||
impl TECurveConfig for Parameters {
|
impl TEModelParameters for Parameters {
|
||||||
/// COEFF_A = -1
|
/// COEFF_A = -1
|
||||||
const COEFF_A: Fq = MontFp!("-1");
|
const COEFF_A: Fq = field_new!(Fq, "-1");
|
||||||
|
|
||||||
/// COEFF_D = 122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179 mod q
|
/// COEFF_D = 122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179 mod q
|
||||||
const COEFF_D: Fq = MontFp!("122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179");
|
#[rustfmt::skip]
|
||||||
|
const COEFF_D: Fq = field_new!(Fq, "122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179");
|
||||||
|
|
||||||
|
/// COFACTOR = (x - 1)^2 / 3 = 30631250834960419227450344600217059328
|
||||||
|
const COFACTOR: &'static [u64] = &[0x0, 0x170b5d4430000000];
|
||||||
|
|
||||||
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
|
/// = 5285428838741532253824584287042945485047145357130994810877
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COFACTOR_INV: Fr = field_new!(Fr, "5285428838741532253824584287042945485047145357130994810877");
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
|
||||||
const GENERATOR: G1TEAffine = G1TEAffine::new_unchecked(TE_GENERATOR_X, TE_GENERATOR_Y);
|
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||||
|
(TE_GENERATOR_X, TE_GENERATOR_Y);
|
||||||
|
|
||||||
type MontCurveConfig = Parameters;
|
type MontgomeryModelParameters = Parameters;
|
||||||
|
|
||||||
/// Multiplication by `a` is multiply by `-1`.
|
/// Multiplication by `a` is multiply by `-1`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_by_a(elem: Self::BaseField) -> Self::BaseField {
|
fn mul_by_a(elem: &Self::BaseField) -> Self::BaseField {
|
||||||
elem.neg()
|
elem.neg()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,6 +132,7 @@ impl TECurveConfig 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)
|
||||||
@@ -140,27 +157,30 @@ impl TECurveConfig for Parameters {
|
|||||||
// # MB = s
|
// # MB = s
|
||||||
// MB=Fp(10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931)
|
// MB=Fp(10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931)
|
||||||
// ```
|
// ```
|
||||||
impl MontCurveConfig for Parameters {
|
impl MontgomeryModelParameters for Parameters {
|
||||||
/// COEFF_A = 228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384
|
/// COEFF_A = 228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384
|
||||||
const COEFF_A: Fq = MontFp!("228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384");
|
#[rustfmt::skip]
|
||||||
|
const COEFF_A: Fq = field_new!(Fq, "228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384");
|
||||||
|
|
||||||
/// COEFF_B = 10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931
|
/// COEFF_B = 10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931
|
||||||
const COEFF_B: Fq = MontFp!("10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931");
|
#[rustfmt::skip]
|
||||||
|
const COEFF_B: Fq = field_new!(Fq, "10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931");
|
||||||
|
|
||||||
type TECurveConfig = Parameters;
|
type TEModelParameters = Parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// G1_GENERATOR_X =
|
/// G1_GENERATOR_X =
|
||||||
/// 81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695
|
/// 81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695
|
||||||
pub const G1_GENERATOR_X: Fq = MontFp!("81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695");
|
#[rustfmt::skip]
|
||||||
|
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695");
|
||||||
|
|
||||||
/// G1_GENERATOR_Y =
|
/// G1_GENERATOR_Y =
|
||||||
/// 241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030
|
/// 241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030
|
||||||
pub const G1_GENERATOR_Y: Fq = MontFp!("241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030");
|
#[rustfmt::skip]
|
||||||
|
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030");
|
||||||
|
|
||||||
// The generator for twisted Edward form is the same SW generator converted into
|
// The generator for twisted Edward form is the same SW generator converted into the normalized TE form (TE2).
|
||||||
// the normalized TE form (TE2).
|
// ``` sage
|
||||||
//``` sage
|
|
||||||
// # following scripts in previous section
|
// # following scripts in previous section
|
||||||
// #####################################################
|
// #####################################################
|
||||||
// # Weierstrass curve generator
|
// # Weierstrass curve generator
|
||||||
@@ -204,8 +224,10 @@ pub const G1_GENERATOR_Y: Fq = MontFp!("2412667498597154737397888782405856817339
|
|||||||
// ```
|
// ```
|
||||||
/// TE_GENERATOR_X =
|
/// TE_GENERATOR_X =
|
||||||
/// 71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393
|
/// 71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393
|
||||||
pub const TE_GENERATOR_X: Fq = MontFp!("71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393");
|
#[rustfmt::skip]
|
||||||
|
pub const TE_GENERATOR_X: Fq = field_new!(Fq, "71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393");
|
||||||
|
|
||||||
/// TE_GENERATOR_Y =
|
/// TE_GENERATOR_Y =
|
||||||
/// 6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235
|
/// 6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235
|
||||||
pub const TE_GENERATOR_Y: Fq = MontFp!("6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235");
|
#[rustfmt::skip]
|
||||||
|
pub const TE_GENERATOR_Y: Fq = field_new!(Fq, "6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235");
|
||||||
|
|||||||
@@ -1,18 +1,35 @@
|
|||||||
use ark_ec::{
|
use ark_ec::models::{ModelParameters, SWModelParameters};
|
||||||
models::{short_weierstrass::SWCurveConfig, CurveConfig},
|
use ark_ff::{field_new, Zero};
|
||||||
short_weierstrass::Affine,
|
|
||||||
};
|
|
||||||
use ark_ff::{Field, MontFp, Zero};
|
|
||||||
|
|
||||||
use crate::{g1, Fq, Fq2, Fr};
|
use crate::{fields::FQ_ZERO, g1, Fq, Fq2, Fr};
|
||||||
|
|
||||||
pub type G2Affine = Affine<Parameters>;
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl ModelParameters for Parameters {
|
||||||
type BaseField = Fq2;
|
type BaseField = Fq2;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWModelParameters for Parameters {
|
||||||
|
/// COEFF_A = [0, 0]
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COEFF_A: Fq2 = field_new!(Fq2,
|
||||||
|
g1::Parameters::COEFF_A,
|
||||||
|
g1::Parameters::COEFF_A,
|
||||||
|
);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// the irreducible poly used to extend from Fp2 to Fp12.
|
||||||
|
// In our case, i = u (App A.3, T_6).
|
||||||
|
/// COEFF_B = [0,
|
||||||
|
/// 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906]
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COEFF_B: Fq2 = field_new!(Fq2,
|
||||||
|
FQ_ZERO,
|
||||||
|
field_new!(Fq, "155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906"),
|
||||||
|
);
|
||||||
|
|
||||||
/// COFACTOR =
|
/// COFACTOR =
|
||||||
/// 7923214915284317143930293550643874566881017850177945424769256759165301436616933228209277966774092486467289478618404761412630691835764674559376407658497
|
/// 7923214915284317143930293550643874566881017850177945424769256759165301436616933228209277966774092486467289478618404761412630691835764674559376407658497
|
||||||
@@ -30,49 +47,40 @@ impl CurveConfig for Parameters {
|
|||||||
|
|
||||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
/// = 6764900296503390671038341982857278410319949526107311149686707033187604810669
|
/// = 6764900296503390671038341982857278410319949526107311149686707033187604810669
|
||||||
const COFACTOR_INV: Fr =
|
#[rustfmt::skip]
|
||||||
MontFp!("6764900296503390671038341982857278410319949526107311149686707033187604810669");
|
const COFACTOR_INV: Fr = field_new!(Fr, "6764900296503390671038341982857278410319949526107311149686707033187604810669");
|
||||||
}
|
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
|
||||||
/// COEFF_A = [0, 0]
|
|
||||||
const COEFF_A: Fq2 = Fq2::new(g1::Parameters::COEFF_A, g1::Parameters::COEFF_A);
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// the irreducible poly used to extend from Fp2 to Fp12.
|
|
||||||
// In our case, i = u (App A.3, T_6).
|
|
||||||
/// COEFF_B = [0,
|
|
||||||
/// 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906]
|
|
||||||
const COEFF_B: Fq2 = Fq2::new(
|
|
||||||
Fq::ZERO,
|
|
||||||
MontFp!("155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906"),
|
|
||||||
);
|
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
||||||
const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||||
|
(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_by_a(_: Self::BaseField) -> Self::BaseField {
|
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
||||||
Self::BaseField::zero()
|
Self::BaseField::zero()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const G2_GENERATOR_X: Fq2 = Fq2::new(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
#[rustfmt::skip]
|
||||||
pub const G2_GENERATOR_Y: Fq2 = Fq2::new(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
|
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);
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C0 =
|
/// G2_GENERATOR_X_C0 =
|
||||||
/// 233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294
|
/// 233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294
|
||||||
pub const G2_GENERATOR_X_C0: Fq = MontFp!("233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294");
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C1 =
|
/// G2_GENERATOR_X_C1 =
|
||||||
/// 140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118
|
/// 140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118
|
||||||
pub const G2_GENERATOR_X_C1: Fq = MontFp!("140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118");
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C0 =
|
/// G2_GENERATOR_Y_C0 =
|
||||||
/// 63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423
|
/// 63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423
|
||||||
pub const G2_GENERATOR_Y_C0: Fq = MontFp!("63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423");
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C1 =
|
/// G2_GENERATOR_Y_C1 =
|
||||||
/// 149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491
|
/// 149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491
|
||||||
pub const G2_GENERATOR_Y_C1: Fq = MontFp!("149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491");
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
@@ -19,9 +18,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 Fp2Config = Fq2Config;
|
type Fp2Params = Fq2Parameters;
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Params = Fq6Parameters;
|
||||||
type Fp12Config = Fq12Config;
|
type Fp12Params = Fq12Parameters;
|
||||||
type G1Parameters = g1::Parameters;
|
type G1Parameters = g1::Parameters;
|
||||||
type G2Parameters = g2::Parameters;
|
type G2Parameters = g2::Parameters;
|
||||||
}
|
}
|
||||||
|
|||||||
135
bls12_377/src/curves/tests.rs
Executable file → Normal file
135
bls12_377/src/curves/tests.rs
Executable file → Normal file
@@ -1,7 +1,130 @@
|
|||||||
use crate::{Bls12_377, G1Projective, G2Projective};
|
#![allow(unused_imports)]
|
||||||
use ark_algebra_test_templates::*;
|
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_ff::{
|
||||||
|
fields::{Field, FpParameters, PrimeField, SquareRootField},
|
||||||
|
One, Zero,
|
||||||
|
};
|
||||||
|
use ark_serialize::CanonicalSerialize;
|
||||||
|
use ark_std::{rand::Rng, test_rng};
|
||||||
|
use core::ops::{AddAssign, MulAssign};
|
||||||
|
|
||||||
test_group!(g1; G1Projective; sw);
|
use ark_algebra_test_templates::{
|
||||||
test_group!(g2; G2Projective; sw);
|
curves::{curve_tests, edwards_tests, sw_tests},
|
||||||
test_group!(pairing_output; ark_ec::pairing::PairingOutput<Bls12_377>; msm);
|
groups::group_test,
|
||||||
test_pairing!(pairing; crate::Bls12_377);
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_projective_curve() {
|
||||||
|
curve_tests::<G1Projective>();
|
||||||
|
|
||||||
|
sw_tests::<g1::Parameters>();
|
||||||
|
edwards_tests::<g1::Parameters>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_projective_group() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G1Projective = rng.gen();
|
||||||
|
let b: G1Projective = rng.gen();
|
||||||
|
group_test(a, b);
|
||||||
|
|
||||||
|
let c = rng.gen();
|
||||||
|
let d = rng.gen();
|
||||||
|
group_test::<G1TEProjective>(c, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_generator() {
|
||||||
|
let generator = G1Affine::prime_subgroup_generator();
|
||||||
|
assert!(generator.is_on_curve());
|
||||||
|
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_projective_curve() {
|
||||||
|
curve_tests::<G2Projective>();
|
||||||
|
|
||||||
|
sw_tests::<g2::Parameters>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_projective_group() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G2Projective = rng.gen();
|
||||||
|
let b: G2Projective = rng.gen();
|
||||||
|
group_test(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_generator() {
|
||||||
|
let generator = G2Affine::prime_subgroup_generator();
|
||||||
|
assert!(generator.is_on_curve());
|
||||||
|
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bilinearity() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G1Projective = rng.gen();
|
||||||
|
let b: G2Projective = rng.gen();
|
||||||
|
let s: Fr = rng.gen();
|
||||||
|
|
||||||
|
let mut sa = a;
|
||||||
|
sa.mul_assign(s);
|
||||||
|
let mut sb = b;
|
||||||
|
sb.mul_assign(s);
|
||||||
|
|
||||||
|
let ans1 = Bls12_377::pairing(sa, b);
|
||||||
|
let ans2 = Bls12_377::pairing(a, sb);
|
||||||
|
let ans3 = Bls12_377::pairing(a, b).pow(s.into_repr());
|
||||||
|
|
||||||
|
assert_eq!(ans1, ans2);
|
||||||
|
assert_eq!(ans2, ans3);
|
||||||
|
|
||||||
|
assert_ne!(ans1, Fq12::one());
|
||||||
|
assert_ne!(ans2, Fq12::one());
|
||||||
|
assert_ne!(ans3, Fq12::one());
|
||||||
|
|
||||||
|
assert_eq!(ans1.pow(Fr::characteristic()), Fq12::one());
|
||||||
|
assert_eq!(ans2.pow(Fr::characteristic()), Fq12::one());
|
||||||
|
assert_eq!(ans3.pow(Fr::characteristic()), Fq12::one());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_generator_raw() {
|
||||||
|
let mut x = Fq::zero();
|
||||||
|
let mut i = 0;
|
||||||
|
loop {
|
||||||
|
// y^2 = x^3 + b
|
||||||
|
let mut rhs = x;
|
||||||
|
rhs.square_in_place();
|
||||||
|
rhs.mul_assign(&x);
|
||||||
|
rhs.add_assign(&g1::Parameters::COEFF_B);
|
||||||
|
|
||||||
|
if let Some(y) = rhs.sqrt() {
|
||||||
|
let p = G1Affine::new(x, if y < -y { y } else { -y }, false);
|
||||||
|
assert!(!p.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
|
||||||
|
let g1 = p.scale_by_cofactor();
|
||||||
|
if !g1.is_zero() {
|
||||||
|
assert_eq!(i, 1);
|
||||||
|
let g1 = G1Affine::from(g1);
|
||||||
|
|
||||||
|
assert!(g1.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
|
||||||
|
assert_eq!(g1, G1Affine::prime_subgroup_generator());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 1;
|
||||||
|
x.add_assign(&Fq::one());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,118 @@
|
|||||||
use ark_ff::fields::{Fp384, MontBackend, MontConfig};
|
use ark_ff::{biginteger::BigInteger384 as BigInteger, fields::*};
|
||||||
|
|
||||||
#[derive(MontConfig)]
|
pub type Fq = Fp384<FqParameters>;
|
||||||
#[modulus = "258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177"]
|
|
||||||
#[generator = "15"]
|
pub struct FqParameters;
|
||||||
pub struct FqConfig;
|
|
||||||
pub type Fq = Fp384<MontBackend<FqConfig, 6>>;
|
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 = BigInteger([
|
||||||
|
2022196864061697551u64,
|
||||||
|
17419102863309525423u64,
|
||||||
|
8564289679875062096u64,
|
||||||
|
17152078065055548215u64,
|
||||||
|
17966377291017729567u64,
|
||||||
|
68610905582439508u64,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
impl FpParameters for FqParameters {
|
||||||
|
/// MODULUS = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS: BigInteger = BigInteger([
|
||||||
|
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 = BigInteger([
|
||||||
|
202099033278250856u64,
|
||||||
|
5854854902718660529u64,
|
||||||
|
11492539364873682930u64,
|
||||||
|
8885205928937022213u64,
|
||||||
|
5545221690922665192u64,
|
||||||
|
39800542322357402u64,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const R2: BigInteger = BigInteger([
|
||||||
|
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 = BigInteger([
|
||||||
|
0xfc0b8000000002fa,
|
||||||
|
0x97d39cf6e000018b,
|
||||||
|
0x2072420fbfa05044,
|
||||||
|
0xcbbcbd50d97c3802,
|
||||||
|
0xbaf1ec35813f9eb,
|
||||||
|
0x9974a2c0945ad2,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
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 = BigInteger([
|
||||||
|
0x7510c00000021423,
|
||||||
|
0x88bee82520005c2d,
|
||||||
|
0x67cc03d44e3c7bcd,
|
||||||
|
0x1701b28524ec688b,
|
||||||
|
0xe9185f1443ab18ec,
|
||||||
|
0x6b8,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// (T - 1) // 2 =
|
||||||
|
// 1837921289030710838195067919506396475074392872918698035817074744121558668640693829665401097909504529
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
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(BigInteger([0, 0, 0, 0, 0, 0]));
|
||||||
|
|||||||
@@ -1,74 +1,74 @@
|
|||||||
use ark_ff::{fields::*, MontFp};
|
use super::*;
|
||||||
|
use ark_ff::{field_new, fields::*};
|
||||||
|
|
||||||
use crate::*;
|
pub type Fq12 = Fp12<Fq12Parameters>;
|
||||||
|
|
||||||
pub type Fq12 = Fp12<Fq12Config>;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Fq12Config;
|
pub struct Fq12Parameters;
|
||||||
|
|
||||||
impl Fp12Config for Fq12Config {
|
impl Fp12Parameters for Fq12Parameters {
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Params = Fq6Parameters;
|
||||||
|
|
||||||
const NONRESIDUE: Fq6 = Fq6::new(Fq2::ZERO, Fq2::ONE, Fq2::ZERO);
|
const NONRESIDUE: Fq6 = field_new!(Fq6, 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)
|
||||||
Fq2::new(Fq::ONE, Fq::ZERO),
|
field_new!(Fq2, FQ_ONE, FQ_ZERO),
|
||||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^1) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("92949345220277864758624960506473182677953048909283248980960104381795901929519566951595905490535835115111760994353"),
|
field_new!(Fq, "92949345220277864758624960506473182677953048909283248980960104381795901929519566951595905490535835115111760994353"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^2) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"),
|
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^3) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499"),
|
field_new!(Fq, "216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^4) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^5) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("123516416119946754630746545296132064952198520638002533875843642777304321125866014634106496325844844051843001220146"),
|
field_new!(Fq, "123516416119946754630746545296132064952198520638002533875843642777304321125866014634106496325844844051843001220146"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^6) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^6) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("-1"),
|
field_new!(Fq, "-1"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^7) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^7) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("165715080792691229252027773188420350858440463845631411558924158284924566418821255823372982649037525009328560463824"),
|
field_new!(Fq, "165715080792691229252027773188420350858440463845631411558924158284924566418821255823372982649037525009328560463824"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^8) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^8) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^9) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^9) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("42198664672744474621281227892288285906241943207628877683080515507620245292955241189266486323192680957485559243678"),
|
field_new!(Fq, "42198664672744474621281227892288285906241943207628877683080515507620245292955241189266486323192680957485559243678"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^10) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^10) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"),
|
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^11) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^11) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("135148009893022339379906188398761468584194992116912126664040619889416147222474808140862391813728516072597320238031"),
|
field_new!(Fq, "135148009893022339379906188398761468584194992116912126664040619889416147222474808140862391813728516072597320238031"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +1,38 @@
|
|||||||
use ark_ff::{fields::*, MontFp};
|
use super::*;
|
||||||
|
use ark_ff::{field_new, fields::*};
|
||||||
|
|
||||||
use crate::*;
|
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 = -5
|
/// NONRESIDUE = -5
|
||||||
const NONRESIDUE: Fq = MontFp!("-5");
|
#[rustfmt::skip]
|
||||||
|
const NONRESIDUE: Fq = field_new!(Fq, "-5");
|
||||||
|
|
||||||
|
/// QUADRATIC_NONRESIDUE = U
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const QUADRATIC_NONRESIDUE: (Fq, Fq) = (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)
|
||||||
MontFp!("-1"),
|
field_new!(Fq, "-1"),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_fp_by_nonresidue_in_place(fe: &mut Self::Fp) -> &mut Self::Fp {
|
fn mul_fp_by_nonresidue(fe: &Self::Fp) -> Self::Fp {
|
||||||
fe.neg_in_place();
|
let original = fe;
|
||||||
*fe = *fe + fe.double_in_place().double_in_place();
|
let mut fe = -fe.double();
|
||||||
fe
|
fe.double_in_place();
|
||||||
}
|
fe - original
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn sub_and_mul_fp_by_nonresidue(y: &mut Self::Fp, x: &Self::Fp) {
|
|
||||||
let mut original = *y;
|
|
||||||
original += x;
|
|
||||||
y.double_in_place().double_in_place();
|
|
||||||
*y += original;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn mul_fp_by_nonresidue_plus_one_and_add(y: &mut Self::Fp, x: &Self::Fp) {
|
|
||||||
y.double_in_place().double_in_place().neg_in_place();
|
|
||||||
*y += x;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mul_fp_by_nonresidue_and_add(y: &mut Self::Fp, x: &Self::Fp) {
|
|
||||||
let mut original = *y;
|
|
||||||
original.double_in_place().double_in_place();
|
|
||||||
original += &*y;
|
|
||||||
*y = *x;
|
|
||||||
*y -= original;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO);
|
||||||
|
pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO);
|
||||||
|
|||||||
@@ -1,79 +1,78 @@
|
|||||||
use ark_ff::{fields::*, MontFp};
|
use super::*;
|
||||||
|
use ark_ff::{field_new, fields::*};
|
||||||
|
|
||||||
use crate::*;
|
pub type Fq6 = Fp6<Fq6Parameters>;
|
||||||
|
|
||||||
pub type Fq6 = Fp6<Fq6Config>;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Fq6Config;
|
pub struct Fq6Parameters;
|
||||||
|
|
||||||
impl Fp6Config for Fq6Config {
|
impl Fp6Parameters for Fq6Parameters {
|
||||||
type Fp2Config = Fq2Config;
|
type Fp2Params = Fq2Parameters;
|
||||||
|
|
||||||
/// NONRESIDUE = U
|
/// NONRESIDUE = U
|
||||||
const NONRESIDUE: Fq2 = Fq2::new(Fq::ZERO, Fq::ONE);
|
#[rustfmt::skip]
|
||||||
|
const NONRESIDUE: Fq2 = field_new!(Fq2, 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)
|
||||||
Fq2::new(Fq::ONE, Fq::ZERO),
|
field_new!(Fq2, FQ_ONE, FQ_ZERO),
|
||||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^1) - 1) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"),
|
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^2) - 1) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^3) - 1) / 3)
|
||||||
Fq2::new(MontFp!("-1"), Fq::ZERO),
|
field_new!(Fq2, field_new!(Fq, "-1"), FQ_ZERO),
|
||||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^4) - 1) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^5) - 1) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"),
|
field_new!(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)
|
||||||
Fq2::new(Fq::ONE, Fq::ZERO),
|
field_new!(Fq2, FQ_ONE, FQ_ZERO),
|
||||||
// Fp2::NONRESIDUE^((2*(q^1) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^1) - 2) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
||||||
Fq::ZERO
|
FQ_ZERO
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^2) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^2) - 2) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^3) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^3) - 2) / 3)
|
||||||
Fq2::new(Fq::ONE, Fq::ZERO),
|
field_new!(Fq2, FQ_ONE, FQ_ZERO),
|
||||||
// Fp2::NONRESIDUE^((2*(q^4) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^4) - 2) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^5) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^5) - 2) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_fp2_by_nonresidue_in_place(fe: &mut Fq2) -> &mut Fq2 {
|
fn mul_fp2_by_nonresidue(fe: &Fq2) -> Fq2 {
|
||||||
// Karatsuba multiplication with constant other = u.
|
// Karatsuba multiplication with constant other = u.
|
||||||
let old_c0 = fe.c0;
|
let c0 = Fq2Parameters::mul_fp_by_nonresidue(&fe.c1);
|
||||||
fe.c0 = fe.c1;
|
let c1 = fe.c0;
|
||||||
Fq2Config::mul_fp_by_nonresidue_in_place(&mut fe.c0);
|
field_new!(Fq2, c0, c1)
|
||||||
fe.c1 = old_c0;
|
|
||||||
fe
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//! 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
|
||||||
@@ -18,10 +19,103 @@
|
|||||||
/// 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::fields::{Fp256, MontBackend, MontConfig};
|
use ark_ff::{biginteger::BigInteger256 as BigInteger, fields::*};
|
||||||
|
|
||||||
#[derive(MontConfig)]
|
pub type Fr = Fp256<FrParameters>;
|
||||||
#[modulus = "8444461749428370424248824938781546531375899335154063827935233455917409239041"]
|
|
||||||
#[generator = "22"]
|
pub struct FrParameters;
|
||||||
pub struct FrConfig;
|
|
||||||
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;
|
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 = BigInteger([
|
||||||
|
12646347781564978760u64,
|
||||||
|
6783048705277173164u64,
|
||||||
|
268534165941069093u64,
|
||||||
|
1121515446318641358u64,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
impl FpParameters for FrParameters {
|
||||||
|
/// MODULUS = 8444461749428370424248824938781546531375899335154063827935233455917409239041
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS: BigInteger = BigInteger([
|
||||||
|
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 = BigInteger([
|
||||||
|
9015221291577245683u64,
|
||||||
|
8239323489949974514u64,
|
||||||
|
1646089257421115374u64,
|
||||||
|
958099254763297437u64,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const R2: BigInteger = BigInteger([
|
||||||
|
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 = BigInteger([
|
||||||
|
2984901390528151251u64,
|
||||||
|
10561528701063790279u64,
|
||||||
|
5476750214495080041u64,
|
||||||
|
898978044469942640u64,
|
||||||
|
]);
|
||||||
|
|
||||||
|
/// (r - 1)/2 =
|
||||||
|
/// 4222230874714185212124412469390773265687949667577031913967616727958704619520
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
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 = BigInteger([
|
||||||
|
0xedfda00000021423,
|
||||||
|
0x9a3cb86f6002b354,
|
||||||
|
0xcabd34594aacc168,
|
||||||
|
0x2556,
|
||||||
|
]);
|
||||||
|
|
||||||
|
/// (t - 1) / 2 =
|
||||||
|
/// 30000754767301779765804869764101946328252876608481130304309777
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
0x76fed00000010a11,
|
||||||
|
0x4d1e5c37b00159aa,
|
||||||
|
0x655e9a2ca55660b4,
|
||||||
|
0x12ab,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,52 +1,127 @@
|
|||||||
use ark_algebra_test_templates::*;
|
|
||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
biginteger::{BigInt, BigInteger, BigInteger384},
|
biginteger::{BigInteger, BigInteger384},
|
||||||
fields::{FftField, Field, Fp6Config, PrimeField},
|
fields::{
|
||||||
Fp384, One, UniformRand, Zero,
|
fp6_3over2::Fp6Parameters, FftField, FftParameters, Field, Fp2Parameters, FpParameters,
|
||||||
|
PrimeField, SquareRootField,
|
||||||
|
},
|
||||||
|
One, UniformRand, Zero,
|
||||||
};
|
};
|
||||||
use ark_std::{
|
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
||||||
|
use ark_std::{rand::Rng, test_rng};
|
||||||
|
use core::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
ops::{AddAssign, MulAssign},
|
ops::{AddAssign, MulAssign, SubAssign},
|
||||||
test_rng,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Config, Fr};
|
use crate::{Fq, Fq12, Fq2, Fq2Parameters, Fq6, Fq6Parameters, FqParameters, Fr};
|
||||||
|
|
||||||
test_field!(fr; Fr; mont_prime_field);
|
use ark_algebra_test_templates::fields::*;
|
||||||
test_field!(fq; Fq; mont_prime_field);
|
|
||||||
test_field!(fq2; Fq2);
|
pub(crate) const ITERATIONS: usize = 5;
|
||||||
test_field!(fq6; Fq6);
|
|
||||||
test_field!(fq12; Fq12);
|
#[test]
|
||||||
|
fn test_fr() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
for _ in 0..ITERATIONS {
|
||||||
|
let a: Fr = rng.gen();
|
||||||
|
let b: Fr = rng.gen();
|
||||||
|
field_test(a, b);
|
||||||
|
primefield_test::<Fr>();
|
||||||
|
sqrt_field_test(b);
|
||||||
|
let byte_size = a.serialized_size();
|
||||||
|
field_serialization_test::<Fr>(byte_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
for _ in 0..ITERATIONS {
|
||||||
|
let a: Fq = rng.gen();
|
||||||
|
let b: Fq = rng.gen();
|
||||||
|
field_test(a, b);
|
||||||
|
primefield_test::<Fq>();
|
||||||
|
sqrt_field_test(a);
|
||||||
|
let byte_size = a.serialized_size();
|
||||||
|
let (_, buffer_size) = buffer_bit_byte_size(Fq::size_in_bits());
|
||||||
|
assert_eq!(byte_size, buffer_size);
|
||||||
|
field_serialization_test::<Fq>(byte_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq2() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
for _ in 0..ITERATIONS {
|
||||||
|
let a: Fq2 = rng.gen();
|
||||||
|
let b: Fq2 = rng.gen();
|
||||||
|
field_test(a, b);
|
||||||
|
sqrt_field_test(a);
|
||||||
|
}
|
||||||
|
frobenius_test::<Fq2, _>(Fq::characteristic(), 13);
|
||||||
|
let byte_size = Fq2::zero().serialized_size();
|
||||||
|
field_serialization_test::<Fq2>(byte_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq6() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
for _ in 0..ITERATIONS {
|
||||||
|
let g: Fq6 = rng.gen();
|
||||||
|
let h: Fq6 = rng.gen();
|
||||||
|
field_test(g, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
frobenius_test::<Fq6, _>(Fq::characteristic(), 13);
|
||||||
|
let byte_size = Fq6::zero().serialized_size();
|
||||||
|
field_serialization_test::<Fq6>(byte_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq12() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
for _ in 0..ITERATIONS {
|
||||||
|
let g: Fq12 = rng.gen();
|
||||||
|
let h: Fq12 = rng.gen();
|
||||||
|
field_test(g, h);
|
||||||
|
}
|
||||||
|
frobenius_test::<Fq12, _>(Fq::characteristic(), 13);
|
||||||
|
let byte_size = Fq12::zero().serialized_size();
|
||||||
|
field_serialization_test::<Fq12>(byte_size);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_from() {
|
fn test_fq_repr_from() {
|
||||||
assert_eq!(BigInt::from(100u64), BigInt::new([100, 0, 0, 0, 0, 0]));
|
assert_eq!(
|
||||||
|
BigInteger384::from(100),
|
||||||
|
BigInteger384([100, 0, 0, 0, 0, 0])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_is_odd() {
|
fn test_fq_repr_is_odd() {
|
||||||
assert!(!BigInteger384::from(0u64).is_odd());
|
assert!(!BigInteger384::from(0).is_odd());
|
||||||
assert!(BigInteger384::from(0u64).is_even());
|
assert!(BigInteger384::from(0).is_even());
|
||||||
assert!(BigInteger384::from(1u64).is_odd());
|
assert!(BigInteger384::from(1).is_odd());
|
||||||
assert!(!BigInteger384::from(1u64).is_even());
|
assert!(!BigInteger384::from(1).is_even());
|
||||||
assert!(!BigInteger384::from(324834872u64).is_odd());
|
assert!(!BigInteger384::from(324834872).is_odd());
|
||||||
assert!(BigInteger384::from(324834872u64).is_even());
|
assert!(BigInteger384::from(324834872).is_even());
|
||||||
assert!(BigInteger384::from(324834873u64).is_odd());
|
assert!(BigInteger384::from(324834873).is_odd());
|
||||||
assert!(!BigInteger384::from(324834873u64).is_even());
|
assert!(!BigInteger384::from(324834873).is_even());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_is_zero() {
|
fn test_fq_repr_is_zero() {
|
||||||
assert!(BigInteger384::from(0u64).is_zero());
|
assert!(BigInteger384::from(0).is_zero());
|
||||||
assert!(!BigInteger384::from(1u64).is_zero());
|
assert!(!BigInteger384::from(1).is_zero());
|
||||||
assert!(!BigInt::new([0, 0, 0, 0, 1, 0]).is_zero());
|
assert!(!BigInteger384([0, 0, 0, 0, 1, 0]).is_zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_num_bits() {
|
fn test_fq_repr_num_bits() {
|
||||||
let mut a = BigInteger384::from(0u64);
|
let mut a = BigInteger384::from(0);
|
||||||
assert_eq!(0, a.num_bits());
|
assert_eq!(0, a.num_bits());
|
||||||
a = BigInteger384::from(1u64);
|
a = BigInteger384::from(1);
|
||||||
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();
|
||||||
@@ -54,16 +129,229 @@ fn test_fq_repr_num_bits() {
|
|||||||
assert_eq!(0, a.num_bits());
|
assert_eq!(0, a.num_bits());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_add_assign() {
|
||||||
|
// Test associativity
|
||||||
|
|
||||||
|
let mut rng = test_rng();
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Generate a, b, c and ensure (a + b) + c == a + (b + c).
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
let b = Fq::rand(&mut rng);
|
||||||
|
let c = Fq::rand(&mut rng);
|
||||||
|
|
||||||
|
let mut tmp1 = a;
|
||||||
|
tmp1.add_assign(&b);
|
||||||
|
tmp1.add_assign(&c);
|
||||||
|
|
||||||
|
let mut tmp2 = b;
|
||||||
|
tmp2.add_assign(&c);
|
||||||
|
tmp2.add_assign(&a);
|
||||||
|
|
||||||
|
assert_eq!(tmp1, tmp2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_sub_assign() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Ensure that (a - b) + (b - a) = 0.
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
let b = Fq::rand(&mut rng);
|
||||||
|
|
||||||
|
let mut tmp1 = a;
|
||||||
|
tmp1.sub_assign(&b);
|
||||||
|
|
||||||
|
let mut tmp2 = b;
|
||||||
|
tmp2.sub_assign(&a);
|
||||||
|
|
||||||
|
tmp1.add_assign(&tmp2);
|
||||||
|
assert!(tmp1.is_zero());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_mul_assign() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
|
||||||
|
for _ in 0..1000000 {
|
||||||
|
// Ensure that (a * b) * c = a * (b * c)
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
let b = Fq::rand(&mut rng);
|
||||||
|
let c = Fq::rand(&mut rng);
|
||||||
|
|
||||||
|
let mut tmp1 = a;
|
||||||
|
tmp1.mul_assign(&b);
|
||||||
|
tmp1.mul_assign(&c);
|
||||||
|
|
||||||
|
let mut tmp2 = b;
|
||||||
|
tmp2.mul_assign(&c);
|
||||||
|
tmp2.mul_assign(&a);
|
||||||
|
|
||||||
|
assert_eq!(tmp1, tmp2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..1000000 {
|
||||||
|
// Ensure that r * (a + b + c) = r*a + r*b + r*c
|
||||||
|
|
||||||
|
let r = Fq::rand(&mut rng);
|
||||||
|
let mut a = Fq::rand(&mut rng);
|
||||||
|
let mut b = Fq::rand(&mut rng);
|
||||||
|
let mut c = Fq::rand(&mut rng);
|
||||||
|
|
||||||
|
let mut tmp1 = a;
|
||||||
|
tmp1.add_assign(&b);
|
||||||
|
tmp1.add_assign(&c);
|
||||||
|
tmp1.mul_assign(&r);
|
||||||
|
|
||||||
|
a.mul_assign(&r);
|
||||||
|
b.mul_assign(&r);
|
||||||
|
c.mul_assign(&r);
|
||||||
|
|
||||||
|
a.add_assign(&b);
|
||||||
|
a.add_assign(&c);
|
||||||
|
|
||||||
|
assert_eq!(tmp1, a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_squaring() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
|
||||||
|
for _ in 0..1000000 {
|
||||||
|
// Ensure that (a * a) = a^2
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
|
||||||
|
let mut tmp = a;
|
||||||
|
tmp.square_in_place();
|
||||||
|
|
||||||
|
let mut tmp2 = a;
|
||||||
|
tmp2.mul_assign(&a);
|
||||||
|
|
||||||
|
assert_eq!(tmp, tmp2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_inverse() {
|
||||||
|
assert!(Fq::zero().inverse().is_none());
|
||||||
|
|
||||||
|
let mut rng = test_rng();
|
||||||
|
|
||||||
|
let one = Fq::one();
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Ensure that a * a^-1 = 1
|
||||||
|
let mut a = Fq::rand(&mut rng);
|
||||||
|
let ainv = a.inverse().unwrap();
|
||||||
|
a.mul_assign(&ainv);
|
||||||
|
assert_eq!(a, one);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_double_in_place() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Ensure doubling a is equivalent to adding a to itself.
|
||||||
|
let mut a = Fq::rand(&mut rng);
|
||||||
|
let mut b = a;
|
||||||
|
b.add_assign(&a);
|
||||||
|
a.double_in_place();
|
||||||
|
assert_eq!(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_negate() {
|
||||||
|
{
|
||||||
|
let a = -Fq::zero();
|
||||||
|
|
||||||
|
assert!(a.is_zero());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut rng = test_rng();
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Ensure (a - (-a)) = 0.
|
||||||
|
let mut a = Fq::rand(&mut rng);
|
||||||
|
let b = -a;
|
||||||
|
a.add_assign(&b);
|
||||||
|
|
||||||
|
assert!(a.is_zero());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_pow() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
|
||||||
|
for i in 0..1000 {
|
||||||
|
// Exponentiate by various small numbers and ensure it consists with repeated
|
||||||
|
// multiplication.
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
let target = a.pow(&[i]);
|
||||||
|
let mut c = Fq::one();
|
||||||
|
for _ in 0..i {
|
||||||
|
c.mul_assign(&a);
|
||||||
|
}
|
||||||
|
assert_eq!(c, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Exponentiating by the modulus should have no effect in a prime field.
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
|
||||||
|
assert_eq!(a, a.pow(Fq::characteristic()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_sqrt() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
|
||||||
|
assert_eq!(Fq::zero().sqrt().unwrap(), Fq::zero());
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Ensure sqrt(a^2) = a or -a
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
let nega = -a;
|
||||||
|
let mut b = a;
|
||||||
|
b.square_in_place();
|
||||||
|
|
||||||
|
let b = b.sqrt().unwrap();
|
||||||
|
|
||||||
|
assert!(a == b || nega == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Ensure sqrt(a)^2 = a for random a
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
|
||||||
|
if let Some(mut tmp) = a.sqrt() {
|
||||||
|
tmp.square_in_place();
|
||||||
|
|
||||||
|
assert_eq!(a, tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_num_bits() {
|
fn test_fq_num_bits() {
|
||||||
assert_eq!(Fq::MODULUS_BIT_SIZE, 377);
|
assert_eq!(FqParameters::MODULUS_BITS, 377);
|
||||||
|
assert_eq!(FqParameters::CAPACITY, 376);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_root_of_unity() {
|
fn test_fq_root_of_unity() {
|
||||||
assert_eq!(Fq::TWO_ADICITY, 46);
|
assert_eq!(FqParameters::TWO_ADICITY, 46);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Fq::GENERATOR.pow([
|
Fq::multiplicative_generator().pow([
|
||||||
0x7510c00000021423,
|
0x7510c00000021423,
|
||||||
0x88bee82520005c2d,
|
0x88bee82520005c2d,
|
||||||
0x67cc03d44e3c7bcd,
|
0x67cc03d44e3c7bcd,
|
||||||
@@ -71,21 +359,21 @@ 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 << Fq::TWO_ADICITY]),
|
Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]),
|
||||||
Fq::one()
|
Fq::one()
|
||||||
);
|
);
|
||||||
assert!(Fq::GENERATOR.sqrt().is_none());
|
assert!(Fq::multiplicative_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..100u64 {
|
for i in 0..100 {
|
||||||
assert!(Fq::from(Fp384::from(i + 1)) > Fq::from(Fp384::from(i)));
|
assert!(Fq::from(BigInteger384::from(i + 1)) > Fq::from(BigInteger384::from(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,8 +383,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());
|
||||||
assert_eq!(QuadraticResidue, Fq::from(Fp384::from(4u64)).legendre());
|
assert_eq!(
|
||||||
assert_eq!(QuadraticNonResidue, Fq::from(Fp384::from(5u64)).legendre());
|
QuadraticResidue,
|
||||||
|
Fq::from(BigInteger384::from(4)).legendre()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
QuadraticNonResidue,
|
||||||
|
Fq::from(BigInteger384::from(5)).legendre()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -136,10 +430,30 @@ 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());
|
||||||
Fq6Config::mul_fp2_by_nonresidue_in_place(&mut m1);
|
m1 = Fq6Parameters::mul_fp2_by_nonresidue(&m1);
|
||||||
assert_eq!(QuadraticNonResidue, m1.legendre());
|
assert_eq!(QuadraticNonResidue, m1.legendre());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq2_mul_nonresidue() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
|
||||||
|
let nqr = Fq2::new(Fq::zero(), Fq::one());
|
||||||
|
|
||||||
|
let quadratic_non_residue = Fq2::new(
|
||||||
|
Fq2Parameters::QUADRATIC_NONRESIDUE.0,
|
||||||
|
Fq2Parameters::QUADRATIC_NONRESIDUE.1,
|
||||||
|
);
|
||||||
|
for _ in 0..1000 {
|
||||||
|
let mut a = Fq2::rand(&mut rng);
|
||||||
|
let mut b = a;
|
||||||
|
a = quadratic_non_residue * &a;
|
||||||
|
b.mul_assign(&nqr);
|
||||||
|
|
||||||
|
assert_eq!(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq6_mul_by_1() {
|
fn test_fq6_mul_by_1() {
|
||||||
let mut rng = test_rng();
|
let mut rng = test_rng();
|
||||||
|
|||||||
12
bls12_377/src/lib.rs
Executable file → Normal file
12
bls12_377/src/lib.rs
Executable file → Normal file
@@ -9,17 +9,15 @@
|
|||||||
#![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
|
//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree 12,
|
||||||
//! 12, defined over a 377-bit (prime) field. The main feature of this curve is
|
//! defined over a 377-bit (prime) field. The main feature of this curve is that
|
||||||
//! that both the scalar field and the base field are highly 2-adic.
|
//! 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
|
//! (This is in contrast to the BLS12_381 curve for which only the scalar field is highly 2-adic.)
|
||||||
//! is highly 2-adic.)
|
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//! Curve information:
|
//! Curve information:
|
||||||
//! * Base field: q = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
|
//! * Base field: q = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
|
||||||
//! * Scalar field: r =
|
//! * Scalar field: r = 8444461749428370424248824938781546531375899335154063827935233455917409239041
|
||||||
//! 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-bls12-381"
|
name = "ark-bls12-381"
|
||||||
version = "0.4.0-alpha.1"
|
version = "0.3.0"
|
||||||
authors = [ "arkworks contributors" ]
|
authors = [ "arkworks contributors" ]
|
||||||
description = "The BLS12-381 pairing-friendly elliptic curve"
|
description = "The BLS12-381 pairing-friendly elliptic curve"
|
||||||
homepage = "https://arkworks.rs"
|
homepage = "https://arkworks.rs"
|
||||||
@@ -10,18 +10,16 @@ keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
|||||||
categories = ["cryptography"]
|
categories = ["cryptography"]
|
||||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
edition = "2021"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ark-ff = { version="0.4.0-alpha", default-features = false }
|
ark-ff = { version="^0.3.0", default-features = false }
|
||||||
ark-ec = { version="0.4.0-alpha", default-features = false }
|
ark-ec = { version="^0.3.0", default-features = false }
|
||||||
ark-std = { version = "0.4.0-alpha", default-features = false }
|
ark-std = { version="^0.3.0", default-features = false }
|
||||||
ark-serialize = { version = "0.4.0-alpha", default-features = false }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ark-algebra-test-templates = { version = "0.4.0-alpha", default-features = false }
|
ark-serialize = { version="^0.3.0", default-features = false }
|
||||||
ark-algebra-bench-templates = { version = "0.4.0-alpha", default-features = false }
|
ark-algebra-test-templates = { version="^0.3.0", default-features = false }
|
||||||
hex = "^0.4.0"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "curve" ]
|
default = [ "curve" ]
|
||||||
@@ -29,8 +27,3 @@ std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ]
|
|||||||
|
|
||||||
curve = [ "scalar_field" ]
|
curve = [ "scalar_field" ]
|
||||||
scalar_field = []
|
scalar_field = []
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "bls12_381"
|
|
||||||
path = "benches/bls12_381.rs"
|
|
||||||
harness = false
|
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
use ark_algebra_bench_templates::*;
|
|
||||||
|
|
||||||
use ark_bls12_381::{
|
|
||||||
fq::Fq, fq2::Fq2, fr::Fr, Bls12_381, Fq12, G1Projective as G1, G2Projective as G2,
|
|
||||||
};
|
|
||||||
|
|
||||||
bench!(
|
|
||||||
Name = "Bls12_381",
|
|
||||||
Pairing = Bls12_381,
|
|
||||||
G1 = G1,
|
|
||||||
G2 = G2,
|
|
||||||
ScalarField = Fr,
|
|
||||||
G1BaseField = Fq,
|
|
||||||
G2BaseField = Fq2,
|
|
||||||
TargetField = Fq12,
|
|
||||||
);
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
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)
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
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)
|
|
||||||
@@ -2,17 +2,12 @@ use crate::*;
|
|||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bls12,
|
bls12,
|
||||||
bls12::Bls12Parameters,
|
bls12::Bls12Parameters,
|
||||||
models::CurveConfig,
|
models::{ModelParameters, SWModelParameters},
|
||||||
short_weierstrass::{Affine, SWCurveConfig},
|
short_weierstrass_jacobian::GroupAffine,
|
||||||
AffineRepr, Group,
|
AffineCurve, ProjectiveCurve,
|
||||||
};
|
|
||||||
use ark_ff::{Field, MontFp, PrimeField, Zero};
|
|
||||||
use ark_serialize::{Compress, SerializationError};
|
|
||||||
use ark_std::{ops::Neg, One};
|
|
||||||
|
|
||||||
use crate::util::{
|
|
||||||
read_g1_compressed, read_g1_uncompressed, serialize_fq, EncodingFlags, G1_SERIALIZED_SIZE,
|
|
||||||
};
|
};
|
||||||
|
use ark_ff::{biginteger::BigInteger256, field_new, Zero};
|
||||||
|
use ark_std::ops::Neg;
|
||||||
|
|
||||||
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>;
|
||||||
@@ -20,175 +15,73 @@ pub type G1Projective = bls12::G1Projective<crate::Parameters>;
|
|||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl ModelParameters for Parameters {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWModelParameters for Parameters {
|
||||||
|
/// COEFF_A = 0
|
||||||
|
const COEFF_A: Fq = field_new!(Fq, "0");
|
||||||
|
|
||||||
|
/// COEFF_B = 4
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COEFF_B: Fq = field_new!(Fq, "4");
|
||||||
|
|
||||||
/// COFACTOR = (x - 1)^2 / 3 = 76329603384216526031706109802092473003
|
/// COFACTOR = (x - 1)^2 / 3 = 76329603384216526031706109802092473003
|
||||||
const COFACTOR: &'static [u64] = &[0x8c00aaab0000aaab, 0x396c8c005555e156];
|
const COFACTOR: &'static [u64] = &[0x8c00aaab0000aaab, 0x396c8c005555e156];
|
||||||
|
|
||||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
/// = 52435875175126190458656871551744051925719901746859129887267498875565241663483
|
/// = 52435875175126190458656871551744051925719901746859129887267498875565241663483
|
||||||
const COFACTOR_INV: Fr =
|
#[rustfmt::skip]
|
||||||
MontFp!("52435875175126190458656871551744051925719901746859129887267498875565241663483");
|
const COFACTOR_INV: Fr = field_new!(Fr, "52435875175126190458656871551744051925719901746859129887267498875565241663483");
|
||||||
}
|
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
|
||||||
/// COEFF_A = 0
|
|
||||||
const COEFF_A: Fq = Fq::ZERO;
|
|
||||||
|
|
||||||
/// COEFF_B = 4
|
|
||||||
const COEFF_B: Fq = MontFp!("4");
|
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||||
const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||||
|
(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_by_a(_: Self::BaseField) -> Self::BaseField {
|
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
||||||
Self::BaseField::zero()
|
Self::BaseField::zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn is_in_correct_subgroup_assuming_on_curve(p: &GroupAffine<Parameters>) -> bool {
|
||||||
fn is_in_correct_subgroup_assuming_on_curve(p: &G1Affine) -> bool {
|
|
||||||
// Algorithm from Section 6 of https://eprint.iacr.org/2021/1130.
|
// Algorithm from Section 6 of https://eprint.iacr.org/2021/1130.
|
||||||
//
|
//
|
||||||
// Check that endomorphism_p(P) == -[X^2]P
|
// Check that endomorphism_p(P) == -[X^2]P
|
||||||
|
|
||||||
|
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
|
// If uP == P but P != point of infinity, then the point is not in the right subgroup.
|
||||||
// subgroup.
|
let x_times_p = p.mul(x);
|
||||||
let x_times_p = p.mul_bigint(crate::Parameters::X);
|
|
||||||
if x_times_p.eq(p) && !p.infinity {
|
if x_times_p.eq(p) && !p.infinity {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let minus_x_squared_times_p = x_times_p.mul_bigint(crate::Parameters::X).neg();
|
let minus_x_squared_times_p = x_times_p.mul(x).neg();
|
||||||
let endomorphism_p = endomorphism(p);
|
let endomorphism_p = endomorphism(p);
|
||||||
minus_x_squared_times_p.eq(&endomorphism_p)
|
minus_x_squared_times_p.eq(&endomorphism_p)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn clear_cofactor(p: &G1Affine) -> G1Affine {
|
|
||||||
// Using the effective cofactor, as explained in
|
|
||||||
// Section 5 of https://eprint.iacr.org/2019/403.pdf.
|
|
||||||
//
|
|
||||||
// It is enough to multiply by (1 - x), instead of (x - 1)^2 / 3
|
|
||||||
let h_eff = one_minus_x().into_bigint();
|
|
||||||
Parameters::mul_affine(&p, h_eff.as_ref()).into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_with_mode<R: ark_serialize::Read>(
|
|
||||||
mut reader: R,
|
|
||||||
compress: ark_serialize::Compress,
|
|
||||||
validate: ark_serialize::Validate,
|
|
||||||
) -> Result<Affine<Self>, ark_serialize::SerializationError> {
|
|
||||||
let p = if compress == ark_serialize::Compress::Yes {
|
|
||||||
read_g1_compressed(&mut reader)?
|
|
||||||
} else {
|
|
||||||
read_g1_uncompressed(&mut reader)?
|
|
||||||
};
|
|
||||||
|
|
||||||
if validate == ark_serialize::Validate::Yes && !p.is_in_correct_subgroup_assuming_on_curve()
|
|
||||||
{
|
|
||||||
return Err(SerializationError::InvalidData);
|
|
||||||
}
|
|
||||||
Ok(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_with_mode<W: ark_serialize::Write>(
|
|
||||||
item: &Affine<Self>,
|
|
||||||
mut writer: W,
|
|
||||||
compress: ark_serialize::Compress,
|
|
||||||
) -> Result<(), SerializationError> {
|
|
||||||
let encoding = EncodingFlags {
|
|
||||||
is_compressed: compress == ark_serialize::Compress::Yes,
|
|
||||||
is_infinity: item.is_zero(),
|
|
||||||
is_lexographically_largest: item.y > -item.y,
|
|
||||||
};
|
|
||||||
let mut p = *item;
|
|
||||||
if encoding.is_infinity {
|
|
||||||
p = G1Affine::zero();
|
|
||||||
}
|
|
||||||
// need to access the field struct `x` directly, otherwise we get None from xy()
|
|
||||||
// method
|
|
||||||
let x_bytes = serialize_fq(p.x);
|
|
||||||
if encoding.is_compressed {
|
|
||||||
let mut bytes: [u8; G1_SERIALIZED_SIZE] = x_bytes;
|
|
||||||
|
|
||||||
encoding.encode_flags(&mut bytes);
|
|
||||||
writer.write_all(&bytes)?;
|
|
||||||
} else {
|
|
||||||
let mut bytes = [0u8; 2 * G1_SERIALIZED_SIZE];
|
|
||||||
bytes[0..G1_SERIALIZED_SIZE].copy_from_slice(&x_bytes[..]);
|
|
||||||
bytes[G1_SERIALIZED_SIZE..].copy_from_slice(&serialize_fq(p.y)[..]);
|
|
||||||
|
|
||||||
encoding.encode_flags(&mut bytes);
|
|
||||||
writer.write_all(&bytes)?;
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialized_size(compress: Compress) -> usize {
|
|
||||||
if compress == Compress::Yes {
|
|
||||||
G1_SERIALIZED_SIZE
|
|
||||||
} else {
|
|
||||||
G1_SERIALIZED_SIZE * 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn one_minus_x() -> Fr {
|
|
||||||
const X: Fr = Fr::from_sign_and_limbs(!crate::Parameters::X_IS_NEGATIVE, crate::Parameters::X);
|
|
||||||
Fr::one() - X
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// G1_GENERATOR_X =
|
/// G1_GENERATOR_X =
|
||||||
/// 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
|
/// 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
|
||||||
pub const G1_GENERATOR_X: Fq = MontFp!("3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507");
|
#[rustfmt::skip]
|
||||||
|
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507");
|
||||||
|
|
||||||
/// G1_GENERATOR_Y =
|
/// G1_GENERATOR_Y =
|
||||||
/// 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
|
/// 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
|
||||||
pub const G1_GENERATOR_Y: Fq = MontFp!("1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569");
|
#[rustfmt::skip]
|
||||||
|
pub const G1_GENERATOR_Y: Fq = field_new!(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 = MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350");
|
pub const BETA: Fq = field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350");
|
||||||
|
|
||||||
pub fn endomorphism(p: &Affine<Parameters>) -> Affine<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)
|
// endomorphism_p(x,y) = (BETA * x, y) where BETA is a non-trivial cubic root of unity in Fq.
|
||||||
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
use ark_std::{rand::Rng, UniformRand};
|
|
||||||
|
|
||||||
fn sample_unchecked() -> Affine<g1::Parameters> {
|
|
||||||
let mut rng = ark_std::test_rng();
|
|
||||||
loop {
|
|
||||||
let x = Fq::rand(&mut rng);
|
|
||||||
let greatest = rng.gen();
|
|
||||||
|
|
||||||
if let Some(p) = Affine::get_point_from_x_unchecked(x, greatest) {
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_cofactor_clearing() {
|
|
||||||
const SAMPLES: usize = 100;
|
|
||||||
for _ in 0..SAMPLES {
|
|
||||||
let p: Affine<g1::Parameters> = sample_unchecked();
|
|
||||||
let p = p.clear_cofactor();
|
|
||||||
assert!(p.is_on_curve());
|
|
||||||
assert!(p.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,20 +1,12 @@
|
|||||||
use ark_std::ops::Neg;
|
use crate::*;
|
||||||
|
use ark_ec::bls12::Bls12Parameters;
|
||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bls12,
|
bls12,
|
||||||
bls12::Bls12Parameters,
|
models::{ModelParameters, SWModelParameters},
|
||||||
models::CurveConfig,
|
short_weierstrass_jacobian::GroupAffine,
|
||||||
short_weierstrass::{Affine, Projective, SWCurveConfig},
|
AffineCurve,
|
||||||
AffineRepr, CurveGroup, Group,
|
|
||||||
};
|
|
||||||
use ark_ff::{Field, MontFp, Zero};
|
|
||||||
use ark_serialize::{Compress, SerializationError};
|
|
||||||
|
|
||||||
use super::util::{serialize_fq, EncodingFlags, G2_SERIALIZED_SIZE};
|
|
||||||
use crate::{
|
|
||||||
util::{read_g2_compressed, read_g2_uncompressed},
|
|
||||||
*,
|
|
||||||
};
|
};
|
||||||
|
use ark_ff::{biginteger::BigInteger256, field_new, Field, Zero};
|
||||||
|
|
||||||
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>;
|
||||||
@@ -22,9 +14,17 @@ pub type G2Projective = bls12::G2Projective<crate::Parameters>;
|
|||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl ModelParameters for Parameters {
|
||||||
type BaseField = Fq2;
|
type BaseField = Fq2;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWModelParameters for Parameters {
|
||||||
|
/// COEFF_A = [0, 0]
|
||||||
|
const COEFF_A: Fq2 = field_new!(Fq2, g1::Parameters::COEFF_A, g1::Parameters::COEFF_A,);
|
||||||
|
|
||||||
|
/// COEFF_B = [4, 4]
|
||||||
|
const COEFF_B: Fq2 = field_new!(Fq2, g1::Parameters::COEFF_B, g1::Parameters::COEFF_B,);
|
||||||
|
|
||||||
/// COFACTOR = (x^8 - 4 x^7 + 5 x^6) - (4 x^4 + 6 x^3 - 4 x^2 - 4 x + 13) //
|
/// COFACTOR = (x^8 - 4 x^7 + 5 x^6) - (4 x^4 + 6 x^3 - 4 x^2 - 4 x + 13) //
|
||||||
/// 9
|
/// 9
|
||||||
@@ -43,31 +43,24 @@ impl CurveConfig for Parameters {
|
|||||||
|
|
||||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
/// 26652489039290660355457965112010883481355318854675681319708643586776743290055
|
/// 26652489039290660355457965112010883481355318854675681319708643586776743290055
|
||||||
const COFACTOR_INV: Fr =
|
#[rustfmt::skip]
|
||||||
MontFp!("26652489039290660355457965112010883481355318854675681319708643586776743290055");
|
const COFACTOR_INV: Fr = field_new!(Fr, "26652489039290660355457965112010883481355318854675681319708643586776743290055");
|
||||||
}
|
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
|
||||||
/// COEFF_A = [0, 0]
|
|
||||||
const COEFF_A: Fq2 = Fq2::new(g1::Parameters::COEFF_A, g1::Parameters::COEFF_A);
|
|
||||||
|
|
||||||
/// COEFF_B = [4, 4]
|
|
||||||
const COEFF_B: Fq2 = Fq2::new(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 GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||||
|
(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_by_a(_: Self::BaseField) -> Self::BaseField {
|
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
||||||
Self::BaseField::zero()
|
Self::BaseField::zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_in_correct_subgroup_assuming_on_curve(point: &G2Affine) -> bool {
|
fn is_in_correct_subgroup_assuming_on_curve(point: &GroupAffine<Parameters>) -> bool {
|
||||||
// Algorithm from Section 4 of https://eprint.iacr.org/2021/1130.
|
// Algorithm from Section 4 of https://eprint.iacr.org/2021/1130.
|
||||||
//
|
//
|
||||||
// Checks that [p]P = [X]P
|
// Checks that [p]P = [X]P
|
||||||
|
|
||||||
let mut x_times_point = point.mul_bigint(crate::Parameters::X);
|
let mut x_times_point = point.mul(BigInteger256([crate::Parameters::X[0], 0, 0, 0]));
|
||||||
if crate::Parameters::X_IS_NEGATIVE {
|
if crate::Parameters::X_IS_NEGATIVE {
|
||||||
x_times_point = -x_times_point;
|
x_times_point = -x_times_point;
|
||||||
}
|
}
|
||||||
@@ -76,162 +69,61 @@ impl SWCurveConfig for Parameters {
|
|||||||
|
|
||||||
x_times_point.eq(&p_times_point)
|
x_times_point.eq(&p_times_point)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn clear_cofactor(p: &G2Affine) -> G2Affine {
|
|
||||||
// Based on Section 4.1 of https://eprint.iacr.org/2017/419.pdf
|
|
||||||
// [h(ψ)]P = [x^2 − x − 1]P + [x − 1]ψ(P) + (ψ^2)(2P)
|
|
||||||
|
|
||||||
// x = -15132376222941642752
|
|
||||||
// When multiplying, use -c1 instead, and then negate the result. That's much
|
|
||||||
// more efficient, since the scalar -c1 has less limbs and a much lower Hamming
|
|
||||||
// weight.
|
|
||||||
let x: &'static [u64] = crate::Parameters::X;
|
|
||||||
let p_projective = p.into_group();
|
|
||||||
|
|
||||||
// [x]P
|
|
||||||
let x_p = Parameters::mul_affine(p, &x).neg();
|
|
||||||
// ψ(P)
|
|
||||||
let psi_p = p_power_endomorphism(&p);
|
|
||||||
// (ψ^2)(2P)
|
|
||||||
let mut psi2_p2 = double_p_power_endomorphism(&p_projective.double());
|
|
||||||
|
|
||||||
// tmp = [x]P + ψ(P)
|
|
||||||
let mut tmp = x_p.clone();
|
|
||||||
tmp += &psi_p;
|
|
||||||
|
|
||||||
// tmp2 = [x^2]P + [x]ψ(P)
|
|
||||||
let mut tmp2: Projective<Parameters> = tmp;
|
|
||||||
tmp2 = tmp2.mul_bigint(x).neg();
|
|
||||||
|
|
||||||
// add up all the terms
|
|
||||||
psi2_p2 += tmp2;
|
|
||||||
psi2_p2 -= x_p;
|
|
||||||
psi2_p2 += &-psi_p;
|
|
||||||
(psi2_p2 - p_projective).into_affine()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_with_mode<R: ark_serialize::Read>(
|
|
||||||
mut reader: R,
|
|
||||||
compress: ark_serialize::Compress,
|
|
||||||
validate: ark_serialize::Validate,
|
|
||||||
) -> Result<Affine<Self>, ark_serialize::SerializationError> {
|
|
||||||
let p = if compress == ark_serialize::Compress::Yes {
|
|
||||||
read_g2_compressed(&mut reader)?
|
|
||||||
} else {
|
|
||||||
read_g2_uncompressed(&mut reader)?
|
|
||||||
};
|
|
||||||
|
|
||||||
if validate == ark_serialize::Validate::Yes && !p.is_in_correct_subgroup_assuming_on_curve()
|
|
||||||
{
|
|
||||||
return Err(SerializationError::InvalidData);
|
|
||||||
}
|
|
||||||
Ok(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_with_mode<W: ark_serialize::Write>(
|
|
||||||
item: &Affine<Self>,
|
|
||||||
mut writer: W,
|
|
||||||
compress: ark_serialize::Compress,
|
|
||||||
) -> Result<(), SerializationError> {
|
|
||||||
let encoding = EncodingFlags {
|
|
||||||
is_compressed: compress == ark_serialize::Compress::Yes,
|
|
||||||
is_infinity: item.is_zero(),
|
|
||||||
is_lexographically_largest: item.y > -item.y,
|
|
||||||
};
|
|
||||||
let mut p = *item;
|
|
||||||
if encoding.is_infinity {
|
|
||||||
p = G2Affine::zero();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut x_bytes = [0u8; G2_SERIALIZED_SIZE];
|
|
||||||
let c1_bytes = serialize_fq(p.x.c1);
|
|
||||||
let c0_bytes = serialize_fq(p.x.c0);
|
|
||||||
x_bytes[0..48].copy_from_slice(&c1_bytes[..]);
|
|
||||||
x_bytes[48..96].copy_from_slice(&c0_bytes[..]);
|
|
||||||
if encoding.is_compressed {
|
|
||||||
let mut bytes: [u8; G2_SERIALIZED_SIZE] = x_bytes;
|
|
||||||
|
|
||||||
encoding.encode_flags(&mut bytes);
|
|
||||||
writer.write_all(&bytes)?;
|
|
||||||
} else {
|
|
||||||
let mut bytes = [0u8; 2 * G2_SERIALIZED_SIZE];
|
|
||||||
|
|
||||||
let mut y_bytes = [0u8; G2_SERIALIZED_SIZE];
|
|
||||||
let c1_bytes = serialize_fq(p.y.c1);
|
|
||||||
let c0_bytes = serialize_fq(p.y.c0);
|
|
||||||
y_bytes[0..48].copy_from_slice(&c1_bytes[..]);
|
|
||||||
y_bytes[48..96].copy_from_slice(&c0_bytes[..]);
|
|
||||||
bytes[0..G2_SERIALIZED_SIZE].copy_from_slice(&x_bytes);
|
|
||||||
bytes[G2_SERIALIZED_SIZE..].copy_from_slice(&y_bytes);
|
|
||||||
|
|
||||||
encoding.encode_flags(&mut bytes);
|
|
||||||
writer.write_all(&bytes)?;
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialized_size(compress: ark_serialize::Compress) -> usize {
|
|
||||||
if compress == Compress::Yes {
|
|
||||||
G2_SERIALIZED_SIZE
|
|
||||||
} else {
|
|
||||||
2 * G2_SERIALIZED_SIZE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const G2_GENERATOR_X: Fq2 = Fq2::new(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
pub const G2_GENERATOR_X: Fq2 = field_new!(Fq2, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
||||||
pub const G2_GENERATOR_Y: Fq2 = Fq2::new(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
|
pub const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C0 =
|
/// G2_GENERATOR_X_C0 =
|
||||||
/// 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160
|
/// 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160
|
||||||
pub const G2_GENERATOR_X_C0: Fq = MontFp!("352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160");
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C1 =
|
/// G2_GENERATOR_X_C1 =
|
||||||
/// 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758
|
/// 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758
|
||||||
pub const G2_GENERATOR_X_C1: Fq = MontFp!("3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758");
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C0 =
|
/// G2_GENERATOR_Y_C0 =
|
||||||
/// 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905
|
/// 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905
|
||||||
pub const G2_GENERATOR_Y_C0: Fq = MontFp!("1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905");
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C1 =
|
/// G2_GENERATOR_Y_C1 =
|
||||||
/// 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582
|
/// 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582
|
||||||
pub const G2_GENERATOR_Y_C1: Fq = MontFp!("927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_Y_C1: Fq = field_new!(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 = Fq2::new(
|
pub const P_POWER_ENDOMORPHISM_COEFF_0 : Fq2 = field_new!(
|
||||||
Fq::ZERO,
|
Fq2,
|
||||||
MontFp!(
|
FQ_ZERO,
|
||||||
"4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"
|
field_new!(
|
||||||
|
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 = Fq2::new(
|
pub const P_POWER_ENDOMORPHISM_COEFF_1: Fq2 = field_new!(
|
||||||
MontFp!(
|
Fq2,
|
||||||
"2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
|
field_new!(
|
||||||
MontFp!(
|
Fq,
|
||||||
"1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257")
|
"2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
|
||||||
|
field_new!(
|
||||||
|
Fq,
|
||||||
|
"1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257")
|
||||||
);
|
);
|
||||||
|
|
||||||
pub const DOUBLE_P_POWER_ENDOMORPHISM: Fq2 = Fq2::new(
|
pub fn p_power_endomorphism(p: &GroupAffine<Parameters>) -> GroupAffine<Parameters> {
|
||||||
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
|
||||||
Fq::ZERO
|
|
||||||
);
|
|
||||||
|
|
||||||
pub fn p_power_endomorphism(p: &Affine<Parameters>) -> Affine<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).
|
// 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,
|
||||||
// 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.
|
||||||
// one set s = x / ((u+1) ^ (1/3)), t = y / ((u+1) ^ (1/2)),
|
// 2. Apply the Frobenius endomorphism (s, t) => (s', t'), another point on curve E,
|
||||||
// because E: y^2 = x^3 + 4.
|
// where s' = s^p, t' = t^p.
|
||||||
// 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)).
|
||||||
//
|
//
|
||||||
@@ -250,47 +142,3 @@ pub fn p_power_endomorphism(p: &Affine<Parameters>) -> Affine<Parameters> {
|
|||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For a p-power endomorphism psi(P), compute psi(psi(P))
|
|
||||||
pub fn double_p_power_endomorphism(p: &Projective<Parameters>) -> Projective<Parameters> {
|
|
||||||
let mut res = *p;
|
|
||||||
|
|
||||||
res.x *= DOUBLE_P_POWER_ENDOMORPHISM;
|
|
||||||
res.y = res.y.neg();
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
use ark_std::UniformRand;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_cofactor_clearing() {
|
|
||||||
// multiplying by h_eff and clearing the cofactor by the efficient
|
|
||||||
// endomorphism-based method should yield the same result.
|
|
||||||
let h_eff: &'static [u64] = &[
|
|
||||||
0xe8020005aaa95551,
|
|
||||||
0x59894c0adebbf6b4,
|
|
||||||
0xe954cbc06689f6a3,
|
|
||||||
0x2ec0ec69d7477c1a,
|
|
||||||
0x6d82bf015d1212b0,
|
|
||||||
0x329c2f178731db95,
|
|
||||||
0x9986ff031508ffe1,
|
|
||||||
0x88e2a8e9145ad768,
|
|
||||||
0x584c6a0ea91b3528,
|
|
||||||
0xbc69f08f2ee75b3,
|
|
||||||
];
|
|
||||||
|
|
||||||
let mut rng = ark_std::test_rng();
|
|
||||||
const SAMPLES: usize = 10;
|
|
||||||
for _ in 0..SAMPLES {
|
|
||||||
let p = Affine::<g2::Parameters>::rand(&mut rng);
|
|
||||||
let optimised = p.clear_cofactor().into_group();
|
|
||||||
let naive = g2::Parameters::mul_affine(&p, h_eff);
|
|
||||||
assert_eq!(optimised, naive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use ark_ec::bls12::{Bls12, Bls12Parameters, TwistType};
|
use ark_ec::bls12::{Bls12, Bls12Parameters, TwistType};
|
||||||
|
|
||||||
use crate::{Fq, Fq12Config, Fq2Config, Fq6Config};
|
use crate::{Fq, Fq12Parameters, Fq2Parameters, Fq6Parameters};
|
||||||
|
|
||||||
pub mod g1;
|
pub mod g1;
|
||||||
pub mod g2;
|
pub mod g2;
|
||||||
pub(crate) mod util;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
@@ -23,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 Fp2Config = Fq2Config;
|
type Fp2Params = Fq2Parameters;
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Params = Fq6Parameters;
|
||||||
type Fp12Config = Fq12Config;
|
type Fp12Params = Fq12Parameters;
|
||||||
type G1Parameters = self::g1::Parameters;
|
type G1Parameters = self::g1::Parameters;
|
||||||
type G2Parameters = self::g2::Parameters;
|
type G2Parameters = self::g2::Parameters;
|
||||||
}
|
}
|
||||||
|
|||||||
173
bls12_381/src/curves/tests.rs
Normal file
173
bls12_381/src/curves/tests.rs
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
#![allow(unused_imports)]
|
||||||
|
use ark_ec::{
|
||||||
|
models::SWModelParameters,
|
||||||
|
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
|
||||||
|
AffineCurve, PairingEngine, ProjectiveCurve,
|
||||||
|
};
|
||||||
|
use ark_ff::{
|
||||||
|
fields::{Field, FpParameters, PrimeField, SquareRootField},
|
||||||
|
BitIteratorBE, One, UniformRand, Zero,
|
||||||
|
};
|
||||||
|
use ark_serialize::CanonicalSerialize;
|
||||||
|
use ark_std::rand::Rng;
|
||||||
|
use ark_std::test_rng;
|
||||||
|
use core::ops::{AddAssign, MulAssign};
|
||||||
|
|
||||||
|
use crate::{g1, g2, Bls12_381, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
|
||||||
|
use ark_algebra_test_templates::{curves::*, groups::*};
|
||||||
|
use ark_ec::group::Group;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_projective_curve() {
|
||||||
|
curve_tests::<G1Projective>();
|
||||||
|
|
||||||
|
sw_tests::<g1::Parameters>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_projective_group() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G1Projective = rng.gen();
|
||||||
|
let b: G1Projective = rng.gen();
|
||||||
|
group_test(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_generator() {
|
||||||
|
let generator = G1Affine::prime_subgroup_generator();
|
||||||
|
assert!(generator.is_on_curve());
|
||||||
|
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_projective_curve() {
|
||||||
|
curve_tests::<G2Projective>();
|
||||||
|
|
||||||
|
sw_tests::<g2::Parameters>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_projective_group() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G2Projective = rng.gen();
|
||||||
|
let b: G2Projective = rng.gen();
|
||||||
|
group_test(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_generator() {
|
||||||
|
let generator = G2Affine::prime_subgroup_generator();
|
||||||
|
assert!(generator.is_on_curve());
|
||||||
|
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bilinearity() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G1Projective = rng.gen();
|
||||||
|
let b: G2Projective = rng.gen();
|
||||||
|
let s: Fr = rng.gen();
|
||||||
|
|
||||||
|
let mut sa = a;
|
||||||
|
sa.mul_assign(s);
|
||||||
|
let mut sb = b;
|
||||||
|
sb.mul_assign(s);
|
||||||
|
|
||||||
|
let ans1 = Bls12_381::pairing(sa, b);
|
||||||
|
let ans2 = Bls12_381::pairing(a, sb);
|
||||||
|
let ans3 = Bls12_381::pairing(a, b).pow(s.into_repr());
|
||||||
|
|
||||||
|
assert_eq!(ans1, ans2);
|
||||||
|
assert_eq!(ans2, ans3);
|
||||||
|
|
||||||
|
assert_ne!(ans1, Fq12::one());
|
||||||
|
assert_ne!(ans2, Fq12::one());
|
||||||
|
assert_ne!(ans3, Fq12::one());
|
||||||
|
|
||||||
|
assert_eq!(ans1.pow(Fr::characteristic()), Fq12::one());
|
||||||
|
assert_eq!(ans2.pow(Fr::characteristic()), Fq12::one());
|
||||||
|
assert_eq!(ans3.pow(Fr::characteristic()), Fq12::one());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_generator_raw() {
|
||||||
|
let mut x = Fq::zero();
|
||||||
|
let mut i = 0;
|
||||||
|
loop {
|
||||||
|
// y^2 = x^3 + b
|
||||||
|
let mut rhs = x;
|
||||||
|
rhs.square_in_place();
|
||||||
|
rhs.mul_assign(&x);
|
||||||
|
rhs.add_assign(&g1::Parameters::COEFF_B);
|
||||||
|
|
||||||
|
if let Some(y) = rhs.sqrt() {
|
||||||
|
let p = G1Affine::new(x, if y < -y { y } else { -y }, false);
|
||||||
|
assert!(!p.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
|
||||||
|
let g1 = p.scale_by_cofactor();
|
||||||
|
if !g1.is_zero() {
|
||||||
|
assert_eq!(i, 4);
|
||||||
|
let g1 = G1Affine::from(g1);
|
||||||
|
|
||||||
|
assert!(g1.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
|
||||||
|
assert_eq!(g1, G1Affine::prime_subgroup_generator());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 1;
|
||||||
|
x.add_assign(&Fq::one());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_endomorphism_beta() {
|
||||||
|
assert!(g1::BETA.pow(&[3u64]).is_one());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_subgroup_membership_via_endomorphism() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let generator = G1Projective::rand(&mut rng).into_affine();
|
||||||
|
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_subgroup_non_membership_via_endomorphism() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
loop {
|
||||||
|
let x = Fq::rand(&mut rng);
|
||||||
|
let greatest = rng.gen();
|
||||||
|
|
||||||
|
if let Some(p) = G1Affine::get_point_from_x(x, greatest) {
|
||||||
|
if !p.into_projective().mul(Fr::characteristic()).is_zero() {
|
||||||
|
assert!(!p.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_subgroup_membership_via_endomorphism() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let generator = G2Projective::rand(&mut rng).into_affine();
|
||||||
|
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_subgroup_non_membership_via_endomorphism() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
loop {
|
||||||
|
let x = Fq2::rand(&mut rng);
|
||||||
|
let greatest = rng.gen();
|
||||||
|
|
||||||
|
if let Some(p) = G2Affine::get_point_from_x(x, greatest) {
|
||||||
|
if !p.into_projective().mul(Fr::characteristic()).is_zero() {
|
||||||
|
assert!(!p.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,119 +0,0 @@
|
|||||||
use ark_algebra_test_templates::*;
|
|
||||||
use ark_ec::{AffineRepr, CurveGroup, Group};
|
|
||||||
use ark_ff::{fields::Field, One, UniformRand, Zero};
|
|
||||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, Validate};
|
|
||||||
use ark_std::{rand::Rng, test_rng, vec};
|
|
||||||
|
|
||||||
use crate::{Bls12_381, Fq, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
|
|
||||||
|
|
||||||
test_group!(g1; G1Projective; sw);
|
|
||||||
test_group!(g2; G2Projective; sw);
|
|
||||||
test_group!(pairing_output; ark_ec::pairing::PairingOutput<Bls12_381>; msm);
|
|
||||||
test_pairing!(pairing; crate::Bls12_381);
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_endomorphism_beta() {
|
|
||||||
assert!(crate::g1::BETA.pow(&[3u64]).is_one());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_subgroup_membership_via_endomorphism() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let generator = G1Projective::rand(&mut rng).into_affine();
|
|
||||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_subgroup_non_membership_via_endomorphism() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
loop {
|
|
||||||
let x = Fq::rand(&mut rng);
|
|
||||||
let greatest = rng.gen();
|
|
||||||
|
|
||||||
if let Some(p) = G1Affine::get_point_from_x_unchecked(x, greatest) {
|
|
||||||
if !p.mul_bigint(Fr::characteristic()).is_zero() {
|
|
||||||
assert!(!p.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_subgroup_membership_via_endomorphism() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let generator = G2Projective::rand(&mut rng).into_affine();
|
|
||||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_subgroup_non_membership_via_endomorphism() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
loop {
|
|
||||||
let x = Fq2::rand(&mut rng);
|
|
||||||
let greatest = rng.gen();
|
|
||||||
|
|
||||||
if let Some(p) = G2Affine::get_point_from_x_unchecked(x, greatest) {
|
|
||||||
if !p.mul_bigint(Fr::characteristic()).is_zero() {
|
|
||||||
assert!(!p.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test vectors and macro adapted from https://github.com/zkcrypto/bls12_381/blob/e224ad4ea1babfc582ccd751c2bf128611d10936/src/tests/mod.rs
|
|
||||||
macro_rules! test_vectors {
|
|
||||||
($projective:ident, $affine:ident, $compress:expr, $expected:ident) => {
|
|
||||||
let mut e = $projective::zero();
|
|
||||||
|
|
||||||
let mut v = vec![];
|
|
||||||
{
|
|
||||||
let mut expected = $expected;
|
|
||||||
for _ in 0..1000 {
|
|
||||||
let e_affine = $affine::from(e);
|
|
||||||
let mut serialized = vec![0u8; e.serialized_size($compress)];
|
|
||||||
e_affine
|
|
||||||
.serialize_with_mode(serialized.as_mut_slice(), $compress)
|
|
||||||
.unwrap();
|
|
||||||
v.extend_from_slice(&serialized[..]);
|
|
||||||
|
|
||||||
let mut decoded = serialized;
|
|
||||||
let len_of_encoding = decoded.len();
|
|
||||||
(&mut decoded[..]).copy_from_slice(&expected[0..len_of_encoding]);
|
|
||||||
expected = &expected[len_of_encoding..];
|
|
||||||
let decoded =
|
|
||||||
$affine::deserialize_with_mode(&decoded[..], $compress, Validate::Yes).unwrap();
|
|
||||||
assert_eq!(e_affine, decoded);
|
|
||||||
|
|
||||||
e += &$projective::generator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_eq!(&v[..], $expected);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn g1_compressed_valid_test_vectors() {
|
|
||||||
let bytes: &'static [u8] = include_bytes!("g1_compressed_valid_test_vectors.dat");
|
|
||||||
test_vectors!(G1Projective, G1Affine, Compress::Yes, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn g1_uncompressed_valid_test_vectors() {
|
|
||||||
let bytes: &'static [u8] = include_bytes!("g1_uncompressed_valid_test_vectors.dat");
|
|
||||||
test_vectors!(G1Projective, G1Affine, Compress::No, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn g2_compressed_valid_test_vectors() {
|
|
||||||
let bytes: &'static [u8] = include_bytes!("g2_compressed_valid_test_vectors.dat");
|
|
||||||
test_vectors!(G2Projective, G2Affine, Compress::Yes, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn g2_uncompressed_valid_test_vectors() {
|
|
||||||
let bytes: &'static [u8] = include_bytes!("g2_uncompressed_valid_test_vectors.dat");
|
|
||||||
test_vectors!(G2Projective, G2Affine, Compress::No, bytes);
|
|
||||||
}
|
|
||||||
@@ -1,217 +0,0 @@
|
|||||||
use ark_ec::{short_weierstrass::Affine, AffineRepr};
|
|
||||||
use ark_ff::{BigInteger384, PrimeField};
|
|
||||||
use ark_serialize::SerializationError;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
g1::Parameters as G1Parameters, g2::Parameters as G2Parameters, Fq, Fq2, G1Affine, G2Affine,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const G1_SERIALIZED_SIZE: usize = 48;
|
|
||||||
pub const G2_SERIALIZED_SIZE: usize = 96;
|
|
||||||
|
|
||||||
pub struct EncodingFlags {
|
|
||||||
pub is_compressed: bool,
|
|
||||||
pub is_infinity: bool,
|
|
||||||
pub is_lexographically_largest: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EncodingFlags {
|
|
||||||
pub fn get_flags(bytes: &[u8]) -> Self {
|
|
||||||
let compression_flag_set = (bytes[0] >> 7) & 1;
|
|
||||||
let infinity_flag_set = (bytes[0] >> 6) & 1;
|
|
||||||
let sort_flag_set = (bytes[0] >> 5) & 1;
|
|
||||||
|
|
||||||
Self {
|
|
||||||
is_compressed: compression_flag_set == 1,
|
|
||||||
is_infinity: infinity_flag_set == 1,
|
|
||||||
is_lexographically_largest: sort_flag_set == 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn encode_flags(&self, bytes: &mut [u8]) {
|
|
||||||
if self.is_compressed {
|
|
||||||
bytes[0] |= 1 << 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.is_infinity {
|
|
||||||
bytes[0] |= 1 << 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.is_compressed && !self.is_infinity && self.is_lexographically_largest {
|
|
||||||
bytes[0] |= 1 << 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn deserialize_fq(bytes: [u8; 48]) -> Option<Fq> {
|
|
||||||
let mut tmp = BigInteger384::new([0, 0, 0, 0, 0, 0]);
|
|
||||||
|
|
||||||
// Note: The following unwraps are if the compiler cannot convert
|
|
||||||
// the byte slice into [u8;8], we know this is infallible since we
|
|
||||||
// are providing the indices at compile time and bytes has a fixed size
|
|
||||||
tmp.0[5] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[0..8]).unwrap());
|
|
||||||
tmp.0[4] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[8..16]).unwrap());
|
|
||||||
tmp.0[3] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[16..24]).unwrap());
|
|
||||||
tmp.0[2] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[24..32]).unwrap());
|
|
||||||
tmp.0[1] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[32..40]).unwrap());
|
|
||||||
tmp.0[0] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[40..48]).unwrap());
|
|
||||||
|
|
||||||
Fq::from_bigint(tmp)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn serialize_fq(field: Fq) -> [u8; 48] {
|
|
||||||
let mut result = [0u8; 48];
|
|
||||||
|
|
||||||
let rep = field.into_bigint();
|
|
||||||
|
|
||||||
result[0..8].copy_from_slice(&rep.0[5].to_be_bytes());
|
|
||||||
result[8..16].copy_from_slice(&rep.0[4].to_be_bytes());
|
|
||||||
result[16..24].copy_from_slice(&rep.0[3].to_be_bytes());
|
|
||||||
result[24..32].copy_from_slice(&rep.0[2].to_be_bytes());
|
|
||||||
result[32..40].copy_from_slice(&rep.0[1].to_be_bytes());
|
|
||||||
result[40..48].copy_from_slice(&rep.0[0].to_be_bytes());
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn read_fq_with_offset(
|
|
||||||
bytes: &[u8],
|
|
||||||
offset: usize,
|
|
||||||
mask: bool,
|
|
||||||
) -> Result<Fq, ark_serialize::SerializationError> {
|
|
||||||
let mut tmp = [0; G1_SERIALIZED_SIZE];
|
|
||||||
// read `G1_SERIALIZED_SIZE` bytes
|
|
||||||
tmp.copy_from_slice(&bytes[offset * G1_SERIALIZED_SIZE..G1_SERIALIZED_SIZE * (offset + 1)]);
|
|
||||||
|
|
||||||
if mask {
|
|
||||||
// Mask away the flag bits
|
|
||||||
tmp[0] &= 0b0001_1111;
|
|
||||||
}
|
|
||||||
deserialize_fq(tmp).ok_or(SerializationError::InvalidData)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn read_g1_compressed<R: ark_serialize::Read>(
|
|
||||||
mut reader: R,
|
|
||||||
) -> Result<Affine<G1Parameters>, ark_serialize::SerializationError> {
|
|
||||||
let mut bytes = [0u8; G1_SERIALIZED_SIZE];
|
|
||||||
reader
|
|
||||||
.read_exact(&mut bytes)
|
|
||||||
.ok()
|
|
||||||
.ok_or(SerializationError::InvalidData)?;
|
|
||||||
|
|
||||||
// Obtain the three flags from the start of the byte sequence
|
|
||||||
let flags = EncodingFlags::get_flags(&bytes[..]);
|
|
||||||
|
|
||||||
// we expect to be deserializing a compressed point
|
|
||||||
if !flags.is_compressed {
|
|
||||||
return Err(SerializationError::UnexpectedFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.is_infinity {
|
|
||||||
return Ok(G1Affine::zero());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to obtain the x-coordinate
|
|
||||||
let x = read_fq_with_offset(&bytes, 0, true)?;
|
|
||||||
|
|
||||||
let p = G1Affine::get_point_from_x_unchecked(x, flags.is_lexographically_largest)
|
|
||||||
.ok_or(SerializationError::InvalidData)?;
|
|
||||||
|
|
||||||
Ok(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn read_g1_uncompressed<R: ark_serialize::Read>(
|
|
||||||
mut reader: R,
|
|
||||||
) -> Result<Affine<G1Parameters>, ark_serialize::SerializationError> {
|
|
||||||
let mut bytes = [0u8; 2 * G1_SERIALIZED_SIZE];
|
|
||||||
reader
|
|
||||||
.read_exact(&mut bytes)
|
|
||||||
.map_err(|_| SerializationError::InvalidData)?;
|
|
||||||
|
|
||||||
// Obtain the three flags from the start of the byte sequence
|
|
||||||
let flags = EncodingFlags::get_flags(&bytes[..]);
|
|
||||||
|
|
||||||
// we expect to be deserializing an uncompressed point
|
|
||||||
if flags.is_compressed {
|
|
||||||
return Err(SerializationError::UnexpectedFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.is_infinity {
|
|
||||||
return Ok(G1Affine::zero());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to obtain the x-coordinate
|
|
||||||
let x = read_fq_with_offset(&bytes, 0, true)?;
|
|
||||||
// Attempt to obtain the y-coordinate
|
|
||||||
let y = read_fq_with_offset(&bytes, 1, false)?;
|
|
||||||
|
|
||||||
let p = G1Affine::new_unchecked(x, y);
|
|
||||||
|
|
||||||
Ok(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn read_g2_compressed<R: ark_serialize::Read>(
|
|
||||||
mut reader: R,
|
|
||||||
) -> Result<Affine<G2Parameters>, ark_serialize::SerializationError> {
|
|
||||||
let mut bytes = [0u8; G2_SERIALIZED_SIZE];
|
|
||||||
reader
|
|
||||||
.read_exact(&mut bytes)
|
|
||||||
.map_err(|_| SerializationError::InvalidData)?;
|
|
||||||
|
|
||||||
// Obtain the three flags from the start of the byte sequence
|
|
||||||
let flags = EncodingFlags::get_flags(&bytes);
|
|
||||||
|
|
||||||
// we expect to be deserializing a compressed point
|
|
||||||
if !flags.is_compressed {
|
|
||||||
return Err(SerializationError::UnexpectedFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.is_infinity {
|
|
||||||
return Ok(G2Affine::zero());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to obtain the x-coordinate
|
|
||||||
let xc1 = read_fq_with_offset(&bytes, 0, true)?;
|
|
||||||
let xc0 = read_fq_with_offset(&bytes, 1, false)?;
|
|
||||||
|
|
||||||
let x = Fq2::new(xc0, xc1);
|
|
||||||
|
|
||||||
let p = G2Affine::get_point_from_x_unchecked(x, flags.is_lexographically_largest)
|
|
||||||
.ok_or(SerializationError::InvalidData)?;
|
|
||||||
|
|
||||||
Ok(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn read_g2_uncompressed<R: ark_serialize::Read>(
|
|
||||||
mut reader: R,
|
|
||||||
) -> Result<Affine<G2Parameters>, ark_serialize::SerializationError> {
|
|
||||||
let mut bytes = [0u8; 2 * G2_SERIALIZED_SIZE];
|
|
||||||
reader
|
|
||||||
.read_exact(&mut bytes)
|
|
||||||
.map_err(|_| SerializationError::InvalidData)?;
|
|
||||||
|
|
||||||
// Obtain the three flags from the start of the byte sequence
|
|
||||||
let flags = EncodingFlags::get_flags(&bytes);
|
|
||||||
|
|
||||||
// we expect to be deserializing an uncompressed point
|
|
||||||
if flags.is_compressed {
|
|
||||||
return Err(SerializationError::UnexpectedFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.is_infinity {
|
|
||||||
return Ok(G2Affine::zero());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to obtain the x-coordinate
|
|
||||||
let xc1 = read_fq_with_offset(&bytes, 0, true)?;
|
|
||||||
let xc0 = read_fq_with_offset(&bytes, 1, false)?;
|
|
||||||
let x = Fq2::new(xc0, xc1);
|
|
||||||
|
|
||||||
// Attempt to obtain the y-coordinate
|
|
||||||
let yc1 = read_fq_with_offset(&bytes, 2, false)?;
|
|
||||||
let yc0 = read_fq_with_offset(&bytes, 3, false)?;
|
|
||||||
let y = Fq2::new(yc0, yc1);
|
|
||||||
|
|
||||||
let p = G2Affine::new_unchecked(x, y);
|
|
||||||
|
|
||||||
Ok(p)
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,115 @@
|
|||||||
use ark_ff::fields::{Fp384, MontBackend, MontConfig};
|
use ark_ff::{
|
||||||
|
biginteger::BigInteger384 as BigInteger,
|
||||||
|
field_new,
|
||||||
|
fields::{FftParameters, Fp384, Fp384Parameters, FpParameters},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(MontConfig)]
|
pub type Fq = Fp384<FqParameters>;
|
||||||
#[modulus = "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787"]
|
|
||||||
#[generator = "2"]
|
pub struct FqParameters;
|
||||||
pub struct FqConfig;
|
|
||||||
pub type Fq = Fp384<MontBackend<FqConfig, 6>>;
|
impl Fp384Parameters for FqParameters {}
|
||||||
|
impl FftParameters for FqParameters {
|
||||||
|
type BigInt = BigInteger;
|
||||||
|
|
||||||
|
const TWO_ADICITY: u32 = 1;
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
||||||
|
0x43f5fffffffcaaae,
|
||||||
|
0x32b7fff2ed47fffd,
|
||||||
|
0x7e83a49a2e99d69,
|
||||||
|
0xeca8f3318332bb7a,
|
||||||
|
0xef148d1ea0f4c069,
|
||||||
|
0x40ab3263eff0206,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
impl FpParameters for FqParameters {
|
||||||
|
/// MODULUS = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS: BigInteger = BigInteger([
|
||||||
|
0xb9feffffffffaaab,
|
||||||
|
0x1eabfffeb153ffff,
|
||||||
|
0x6730d2a0f6b0f624,
|
||||||
|
0x64774b84f38512bf,
|
||||||
|
0x4b1ba7b6434bacd7,
|
||||||
|
0x1a0111ea397fe69a,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const MODULUS_BITS: u32 = 381;
|
||||||
|
|
||||||
|
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
|
||||||
|
|
||||||
|
const REPR_SHAVE_BITS: u32 = 3;
|
||||||
|
|
||||||
|
/// R = 3380320199399472671518931668520476396067793891014375699959770179129436917079669831430077592723774664465579537268733
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const R: BigInteger = BigInteger([
|
||||||
|
0x760900000002fffd,
|
||||||
|
0xebf4000bc40c0002,
|
||||||
|
0x5f48985753c758ba,
|
||||||
|
0x77ce585370525745,
|
||||||
|
0x5c071a97a256ec6d,
|
||||||
|
0x15f65ec3fa80e493,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const R2: BigInteger = BigInteger([
|
||||||
|
0xf4df1f341c341746,
|
||||||
|
0xa76e6a609d104f1,
|
||||||
|
0x8de5476c4c95b6d5,
|
||||||
|
0x67eb88a9939d83c0,
|
||||||
|
0x9a793e85b519952d,
|
||||||
|
0x11988fe592cae3aa,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const INV: u64 = 0x89f3fffcfffcfffd;
|
||||||
|
|
||||||
|
/// GENERATOR = 2
|
||||||
|
/// Encoded in Montgomery form, so the value is
|
||||||
|
/// 2 * R % q = 2758230843577277949620073511305048635578704962089743514587482222134842183668501798417467556318533664893264801977679
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const GENERATOR: BigInteger = BigInteger([
|
||||||
|
0x321300000006554f,
|
||||||
|
0xb93c0018d6c40005,
|
||||||
|
0x57605e0db0ddbb51,
|
||||||
|
0x8b256521ed1f9bcb,
|
||||||
|
0x6cf28d7901622c03,
|
||||||
|
0x11ebab9dbb81e28c,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
0xdcff7fffffffd555,
|
||||||
|
0xf55ffff58a9ffff,
|
||||||
|
0xb39869507b587b12,
|
||||||
|
0xb23ba5c279c2895f,
|
||||||
|
0x258dd3db21a5d66b,
|
||||||
|
0xd0088f51cbff34d,
|
||||||
|
]);
|
||||||
|
|
||||||
|
/// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T
|
||||||
|
/// For T coprime to 2
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const T: BigInteger = BigInteger([
|
||||||
|
0xdcff7fffffffd555,
|
||||||
|
0xf55ffff58a9ffff,
|
||||||
|
0xb39869507b587b12,
|
||||||
|
0xb23ba5c279c2895f,
|
||||||
|
0x258dd3db21a5d66b,
|
||||||
|
0xd0088f51cbff34d,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
0xee7fbfffffffeaaa,
|
||||||
|
0x7aaffffac54ffff,
|
||||||
|
0xd9cc34a83dac3d89,
|
||||||
|
0xd91dd2e13ce144af,
|
||||||
|
0x92c6e9ed90d2eb35,
|
||||||
|
0x680447a8e5ff9a6,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const FQ_ONE: Fq = field_new!(Fq, "1");
|
||||||
|
pub const FQ_ZERO: Fq = field_new!(Fq, "0");
|
||||||
|
|||||||
@@ -1,77 +1,76 @@
|
|||||||
use ark_ff::{fields::*, MontFp};
|
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use ark_ff::{field_new, fields::*};
|
||||||
|
|
||||||
pub type Fq12 = Fp12<Fq12Config>;
|
pub type Fq12 = Fp12<Fq12Parameters>;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Fq12Config;
|
pub struct Fq12Parameters;
|
||||||
|
|
||||||
impl Fp12Config for Fq12Config {
|
impl Fp12Parameters for Fq12Parameters {
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Params = Fq6Parameters;
|
||||||
|
|
||||||
const NONRESIDUE: Fq6 = Fq6::new(Fq2::ZERO, Fq2::ONE, Fq2::ZERO);
|
const NONRESIDUE: Fq6 = field_new!(Fq6, 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)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
Fq::ONE,
|
field_new!(Fq, "1"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^1) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"),
|
field_new!(Fq, "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"),
|
||||||
MontFp!("151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"),
|
field_new!(Fq, "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^2) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"),
|
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^3) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
|
field_new!(Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
|
||||||
MontFp!("1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"),
|
field_new!(Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^4) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^5) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"),
|
field_new!(Fq, "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"),
|
||||||
MontFp!("877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"),
|
field_new!(Fq, "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^6) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^6) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("-1"),
|
field_new!(Fq, "-1"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^7) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^7) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"),
|
field_new!(Fq, "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"),
|
||||||
MontFp!("3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"),
|
field_new!(Fq, "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^8) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^8) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^9) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^9) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"),
|
field_new!(Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"),
|
||||||
MontFp!("2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
|
field_new!(Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^10) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^10) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"),
|
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^11) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^11) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"),
|
field_new!(Fq, "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"),
|
||||||
MontFp!("3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"),
|
field_new!(Fq, "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,35 @@
|
|||||||
use ark_ff::{fields::*, MontFp};
|
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use ark_ff::{field_new, fields::*};
|
||||||
|
|
||||||
pub type Fq2 = Fp2<Fq2Config>;
|
pub type Fq2 = Fp2<Fq2Parameters>;
|
||||||
|
|
||||||
pub struct Fq2Config;
|
pub struct Fq2Parameters;
|
||||||
|
|
||||||
impl Fp2Config for Fq2Config {
|
impl Fp2Parameters for Fq2Parameters {
|
||||||
type Fp = Fq;
|
type Fp = Fq;
|
||||||
|
|
||||||
/// NONRESIDUE = -1
|
/// NONRESIDUE = -1
|
||||||
const NONRESIDUE: Fq = MontFp!("-1");
|
#[rustfmt::skip]
|
||||||
|
const NONRESIDUE: Fq = field_new!(Fq, "-1");
|
||||||
|
|
||||||
|
/// QUADRATIC_NONRESIDUE = (U + 1)
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const QUADRATIC_NONRESIDUE: (Fq, Fq) = (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)
|
||||||
Fq::ONE,
|
field_new!(Fq, "1"),
|
||||||
// Fq(-1)**(((q^1) - 1) / 2)
|
// Fq(-1)**(((q^1) - 1) / 2)
|
||||||
MontFp!("-1"),
|
field_new!(Fq, "-1"),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_fp_by_nonresidue_in_place(fp: &mut Self::Fp) -> &mut Self::Fp {
|
fn mul_fp_by_nonresidue(fp: &Self::Fp) -> Self::Fp {
|
||||||
fp.neg_in_place()
|
-(*fp)
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn sub_and_mul_fp_by_nonresidue(y: &mut Self::Fp, x: &Self::Fp) {
|
|
||||||
*y += x;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn mul_fp_by_nonresidue_plus_one_and_add(y: &mut Self::Fp, x: &Self::Fp) {
|
|
||||||
*y = *x;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mul_fp_by_nonresidue_and_add(y: &mut Self::Fp, x: &Self::Fp) {
|
|
||||||
y.neg_in_place();
|
|
||||||
*y += x;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO);
|
||||||
|
pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO);
|
||||||
|
|||||||
@@ -1,91 +1,96 @@
|
|||||||
use ark_ff::{fields::*, MontFp};
|
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use ark_ff::{field_new, fields::*};
|
||||||
|
|
||||||
pub type Fq6 = Fp6<Fq6Config>;
|
pub type Fq6 = Fp6<Fq6Parameters>;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Fq6Config;
|
pub struct Fq6Parameters;
|
||||||
|
|
||||||
impl Fp6Config for Fq6Config {
|
impl Fp6Parameters for Fq6Parameters {
|
||||||
type Fp2Config = Fq2Config;
|
type Fp2Params = Fq2Parameters;
|
||||||
|
|
||||||
/// NONRESIDUE = (U + 1)
|
/// NONRESIDUE = (U + 1)
|
||||||
const NONRESIDUE: Fq2 = Fq2::new(Fq::ONE, Fq::ONE);
|
#[rustfmt::skip]
|
||||||
|
const NONRESIDUE: Fq2 = field_new!(Fq2,
|
||||||
|
field_new!(Fq, "1"),
|
||||||
|
field_new!(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)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
Fq::ONE,
|
field_new!(Fq, "1"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^1) - 1) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^2) - 1) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^3) - 1) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
Fq::ONE,
|
field_new!(Fq, "1"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^4) - 1) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^5) - 1) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
field_new!(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)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
Fq::ONE,
|
field_new!(Fq, "1"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fq2(u + 1)**(((2q^1) - 2) / 3)
|
// Fq2(u + 1)**(((2q^1) - 2) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"),
|
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fq2(u + 1)**(((2q^2) - 2) / 3)
|
// Fq2(u + 1)**(((2q^2) - 2) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fq2(u + 1)**(((2q^3) - 2) / 3)
|
// Fq2(u + 1)**(((2q^3) - 2) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("-1"),
|
field_new!(Fq, "-1"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fq2(u + 1)**(((2q^4) - 2) / 3)
|
// Fq2(u + 1)**(((2q^4) - 2) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fq2(u + 1)**(((2q^5) - 2) / 3)
|
// Fq2(u + 1)**(((2q^5) - 2) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"),
|
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
/// Multiply this element by the quadratic nonresidue 1 + u.
|
/// Multiply this element by the quadratic nonresidue 1 + u.
|
||||||
/// Make this generic.
|
/// Make this generic.
|
||||||
fn mul_fp2_by_nonresidue_in_place(fe: &mut Fq2) -> &mut Fq2 {
|
fn mul_fp2_by_nonresidue(fe: &Fq2) -> Fq2 {
|
||||||
let t0 = fe.c0;
|
let mut copy = *fe;
|
||||||
fe.c0 -= &fe.c1;
|
let t0 = copy.c0;
|
||||||
fe.c1 += &t0;
|
copy.c0 -= &fe.c1;
|
||||||
fe
|
copy.c1 += &t0;
|
||||||
|
copy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,100 @@
|
|||||||
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
|
use ark_ff::{
|
||||||
|
biginteger::BigInteger256 as BigInteger,
|
||||||
|
fields::{FftParameters, Fp256, Fp256Parameters, FpParameters},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(MontConfig)]
|
pub type Fr = Fp256<FrParameters>;
|
||||||
#[modulus = "52435875175126190479447740508185965837690552500527637822603658699938581184513"]
|
|
||||||
#[generator = "7"]
|
pub struct FrParameters;
|
||||||
pub struct FrConfig;
|
|
||||||
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;
|
impl Fp256Parameters for FrParameters {}
|
||||||
|
impl FftParameters for FrParameters {
|
||||||
|
type BigInt = BigInteger;
|
||||||
|
|
||||||
|
const TWO_ADICITY: u32 = 32;
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
||||||
|
0xb9b58d8c5f0e466a,
|
||||||
|
0x5b1b4c801819d7ec,
|
||||||
|
0xaf53ae352a31e64,
|
||||||
|
0x5bf3adda19e9b27b,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
impl FpParameters for FrParameters {
|
||||||
|
/// MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS: BigInteger = BigInteger([
|
||||||
|
0xffffffff00000001,
|
||||||
|
0x53bda402fffe5bfe,
|
||||||
|
0x3339d80809a1d805,
|
||||||
|
0x73eda753299d7d48,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const MODULUS_BITS: u32 = 255;
|
||||||
|
|
||||||
|
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
|
||||||
|
|
||||||
|
const REPR_SHAVE_BITS: u32 = 1;
|
||||||
|
|
||||||
|
/// R = 10920338887063814464675503992315976177888879664585288394250266608035967270910
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const R: BigInteger = BigInteger([
|
||||||
|
0x1fffffffe,
|
||||||
|
0x5884b7fa00034802,
|
||||||
|
0x998c4fefecbc4ff5,
|
||||||
|
0x1824b159acc5056f,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const R2: BigInteger = BigInteger([
|
||||||
|
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 = BigInteger([
|
||||||
|
0xefffffff1,
|
||||||
|
0x17e363d300189c0f,
|
||||||
|
0xff9c57876f8457b0,
|
||||||
|
0x351332208fc5a8c4,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
0x7fffffff80000000,
|
||||||
|
0xa9ded2017fff2dff,
|
||||||
|
0x199cec0404d0ec02,
|
||||||
|
0x39f6d3a994cebea4,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T
|
||||||
|
// For T coprime to 2
|
||||||
|
|
||||||
|
// T = (MODULUS - 1) / 2^S =
|
||||||
|
// 12208678567578594777604504606729831043093128246378069236549469339647
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const T: BigInteger = BigInteger([
|
||||||
|
0xfffe5bfeffffffff,
|
||||||
|
0x9a1d80553bda402,
|
||||||
|
0x299d7d483339d808,
|
||||||
|
0x73eda753,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// (T - 1) / 2 =
|
||||||
|
// 6104339283789297388802252303364915521546564123189034618274734669823
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
0x7fff2dff7fffffff,
|
||||||
|
0x4d0ec02a9ded201,
|
||||||
|
0x94cebea4199cec04,
|
||||||
|
0x39f6d3a9,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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", test))]
|
#[cfg(all(feature = "curve", feature = "std", test))]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
11
bls12_381/src/lib.rs
Executable file → Normal file
11
bls12_381/src/lib.rs
Executable file → Normal file
@@ -9,16 +9,15 @@
|
|||||||
#![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
|
//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree 12,
|
||||||
//! 12, defined over a 381-bit (prime) field.
|
//! defined over a 381-bit (prime) field.
|
||||||
//! This curve was intended to replace the BN254 curve to provide a higher
|
//! This curve was intended to replace the BN254 curve to provide a higher security
|
||||||
//! security level without incurring a large performance overhead.
|
//! level without incurring a large performance overhead.
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//! Curve information:
|
//! Curve information:
|
||||||
//! * Base field: q = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
|
//! * Base field: q = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
|
||||||
//! * Scalar field: r =
|
//! * Scalar field: r = 52435875175126190479447740508185965837690552500527637822603658699938581184513
|
||||||
//! 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-bn254"
|
name = "ark-bn254"
|
||||||
version = "0.4.0-alpha.1"
|
version = "0.3.0"
|
||||||
authors = [ "arkworks contributors" ]
|
authors = [ "arkworks contributors" ]
|
||||||
description = "The BN254 pairing-friendly elliptic curve"
|
description = "The BN254 pairing-friendly elliptic curve"
|
||||||
homepage = "https://arkworks.rs"
|
homepage = "https://arkworks.rs"
|
||||||
@@ -10,17 +10,16 @@ keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
|||||||
categories = ["cryptography"]
|
categories = ["cryptography"]
|
||||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
edition = "2021"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ark-ff = { version="0.4.0-alpha", default-features = false }
|
ark-ff = { version="^0.3.0", default-features = false }
|
||||||
ark-ec = { version="0.4.0-alpha", default-features = false }
|
ark-ec = { version="^0.3.0", default-features = false }
|
||||||
ark-std = { version = "0.4.0-alpha", default-features = false }
|
ark-std = { version="^0.3.0", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ark-serialize = { version = "0.4.0-alpha", default-features = false }
|
ark-serialize = { version="^0.3.0", default-features = false }
|
||||||
ark-algebra-test-templates = { version = "0.4.0-alpha", default-features = false }
|
ark-algebra-test-templates = { version="^0.3.0", default-features = false }
|
||||||
ark-algebra-bench-templates = { version = "0.4.0-alpha", default-features = false }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "curve" ]
|
default = [ "curve" ]
|
||||||
@@ -28,8 +27,3 @@ std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ]
|
|||||||
|
|
||||||
curve = [ "scalar_field" ]
|
curve = [ "scalar_field" ]
|
||||||
scalar_field = []
|
scalar_field = []
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "bn254"
|
|
||||||
path = "benches/bn254.rs"
|
|
||||||
harness = false
|
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
use ark_algebra_bench_templates::*;
|
|
||||||
use ark_bn254::{fq::Fq, fq2::Fq2, fr::Fr, Bn254, Fq12, G1Projective as G1, G2Projective as G2};
|
|
||||||
|
|
||||||
bench!(
|
|
||||||
Name = "BN254",
|
|
||||||
Pairing = Bn254,
|
|
||||||
G1 = G1,
|
|
||||||
G2 = G2,
|
|
||||||
ScalarField = Fr,
|
|
||||||
G1BaseField = Fq,
|
|
||||||
G2BaseField = Fq2,
|
|
||||||
TargetField = Fq12,
|
|
||||||
);
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
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)
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
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)
|
|
||||||
@@ -1,45 +1,41 @@
|
|||||||
use ark_ec::{
|
use ark_ec::models::{ModelParameters, SWModelParameters};
|
||||||
models::{short_weierstrass::SWCurveConfig, CurveConfig},
|
use ark_ff::{field_new, Zero};
|
||||||
short_weierstrass::Affine,
|
|
||||||
};
|
|
||||||
use ark_ff::{Field, MontFp, Zero};
|
|
||||||
|
|
||||||
use crate::{Fq, Fr};
|
use crate::{Fq, Fr};
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Parameters;
|
||||||
|
|
||||||
pub type G1Affine = Affine<Parameters>;
|
impl ModelParameters for Parameters {
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWModelParameters for Parameters {
|
||||||
|
/// COEFF_A = 0
|
||||||
|
const COEFF_A: Fq = field_new!(Fq, "0");
|
||||||
|
|
||||||
|
/// COEFF_B = 3
|
||||||
|
const COEFF_B: Fq = field_new!(Fq, "3");
|
||||||
|
|
||||||
/// COFACTOR = 1
|
/// COFACTOR = 1
|
||||||
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 = Fr::ONE;
|
const COFACTOR_INV: Fr = field_new!(Fr, "1");
|
||||||
}
|
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
|
||||||
/// COEFF_A = 0
|
|
||||||
const COEFF_A: Fq = Fq::ZERO;
|
|
||||||
|
|
||||||
/// COEFF_B = 3
|
|
||||||
const COEFF_B: Fq = MontFp!("3");
|
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||||
const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||||
|
(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_by_a(_: Self::BaseField) -> Self::BaseField {
|
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
||||||
Self::BaseField::zero()
|
Self::BaseField::zero()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// G1_GENERATOR_X = 1
|
/// G1_GENERATOR_X = 1
|
||||||
pub const G1_GENERATOR_X: Fq = Fq::ONE;
|
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "1");
|
||||||
|
|
||||||
/// G1_GENERATOR_Y = 2
|
/// G1_GENERATOR_Y = 2
|
||||||
pub const G1_GENERATOR_Y: Fq = MontFp!("2");
|
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "2");
|
||||||
|
|||||||
@@ -1,22 +1,31 @@
|
|||||||
use ark_ec::{
|
use ark_ec::models::{ModelParameters, SWModelParameters};
|
||||||
models::{short_weierstrass::SWCurveConfig, CurveConfig},
|
use ark_ff::{field_new, Zero};
|
||||||
short_weierstrass::Affine,
|
|
||||||
};
|
|
||||||
use ark_ff::{Field, MontFp, Zero};
|
|
||||||
|
|
||||||
use crate::{Fq, Fq2, Fr};
|
use crate::{Fq, Fq2, Fr};
|
||||||
|
|
||||||
pub type G2Affine = Affine<Parameters>;
|
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl ModelParameters for Parameters {
|
||||||
type BaseField = Fq2;
|
type BaseField = Fq2;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWModelParameters for Parameters {
|
||||||
|
/// COEFF_A = [0, 0]
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COEFF_A: Fq2 = field_new!(Fq2, field_new!(Fq, "0"), field_new!(Fq, "0"));
|
||||||
|
|
||||||
|
/// COEFF_B = 3/(u+9)
|
||||||
|
/// = (19485874751759354771024239261021720505790618469301721065564631296452457478373, 266929791119991161246907387137283842545076965332900288569378510910307636690)
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COEFF_B: Fq2 = field_new!(Fq2,
|
||||||
|
field_new!(Fq, "19485874751759354771024239261021720505790618469301721065564631296452457478373"),
|
||||||
|
field_new!(Fq, "266929791119991161246907387137283842545076965332900288569378510910307636690"),
|
||||||
|
);
|
||||||
|
|
||||||
/// 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,
|
||||||
@@ -26,49 +35,40 @@ impl CurveConfig for Parameters {
|
|||||||
];
|
];
|
||||||
|
|
||||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
const COFACTOR_INV: Fr =
|
#[rustfmt::skip]
|
||||||
MontFp!("10944121435919637613327163357776759465618812564592884533313067514031822496649");
|
const COFACTOR_INV: Fr = field_new!(Fr, "10944121435919637613327163357776759465618812564592884533313067514031822496649");
|
||||||
}
|
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
|
||||||
/// COEFF_A = [0, 0]
|
|
||||||
const COEFF_A: Fq2 = Fq2::ZERO;
|
|
||||||
|
|
||||||
/// COEFF_B = 3/(u+9)
|
|
||||||
/// (19485874751759354771024239261021720505790618469301721065564631296452457478373, 266929791119991161246907387137283842545076965332900288569378510910307636690)
|
|
||||||
const COEFF_B: Fq2 = Fq2::new(
|
|
||||||
MontFp!("19485874751759354771024239261021720505790618469301721065564631296452457478373"),
|
|
||||||
MontFp!("266929791119991161246907387137283842545076965332900288569378510910307636690"),
|
|
||||||
);
|
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
||||||
const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||||
|
(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_by_a(_: Self::BaseField) -> Self::BaseField {
|
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
||||||
Self::BaseField::zero()
|
Self::BaseField::zero()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const G2_GENERATOR_X: Fq2 = Fq2::new(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
#[rustfmt::skip]
|
||||||
pub const G2_GENERATOR_Y: Fq2 = Fq2::new(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
|
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);
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C0 =
|
/// G2_GENERATOR_X_C0 =
|
||||||
/// 10857046999023057135944570762232829481370756359578518086990519993285655852781
|
/// 10857046999023057135944570762232829481370756359578518086990519993285655852781
|
||||||
pub const G2_GENERATOR_X_C0: Fq =
|
#[rustfmt::skip]
|
||||||
MontFp!("10857046999023057135944570762232829481370756359578518086990519993285655852781");
|
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "10857046999023057135944570762232829481370756359578518086990519993285655852781");
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C1 =
|
/// G2_GENERATOR_X_C1 =
|
||||||
/// 11559732032986387107991004021392285783925812861821192530917403151452391805634
|
/// 11559732032986387107991004021392285783925812861821192530917403151452391805634
|
||||||
pub const G2_GENERATOR_X_C1: Fq =
|
#[rustfmt::skip]
|
||||||
MontFp!("11559732032986387107991004021392285783925812861821192530917403151452391805634");
|
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "11559732032986387107991004021392285783925812861821192530917403151452391805634");
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C0 =
|
/// G2_GENERATOR_Y_C0 =
|
||||||
/// 8495653923123431417604973247489272438418190587263600148770280649306958101930
|
/// 8495653923123431417604973247489272438418190587263600148770280649306958101930
|
||||||
pub const G2_GENERATOR_Y_C0: Fq =
|
#[rustfmt::skip]
|
||||||
MontFp!("8495653923123431417604973247489272438418190587263600148770280649306958101930");
|
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "8495653923123431417604973247489272438418190587263600148770280649306958101930");
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C1 =
|
/// G2_GENERATOR_Y_C1 =
|
||||||
/// 4082367875863433681332203403145435568316851327593401208105741076214120093531
|
/// 4082367875863433681332203403145435568316851327593401208105741076214120093531
|
||||||
pub const G2_GENERATOR_Y_C1: Fq =
|
#[rustfmt::skip]
|
||||||
MontFp!("4082367875863433681332203403145435568316851327593401208105741076214120093531");
|
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "4082367875863433681332203403145435568316851327593401208105741076214120093531");
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
|
use crate::*;
|
||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bn,
|
bn,
|
||||||
bn::{Bn, BnParameters, TwistType},
|
bn::{Bn, BnParameters, TwistType},
|
||||||
};
|
};
|
||||||
use ark_ff::MontFp;
|
use ark_ff::field_new;
|
||||||
|
|
||||||
use crate::*;
|
|
||||||
|
|
||||||
pub mod g1;
|
pub mod g1;
|
||||||
pub mod g2;
|
pub mod g2;
|
||||||
|
|
||||||
@@ -24,19 +22,33 @@ 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 = Fq2::new(
|
const TWIST_MUL_BY_Q_X: Fq2 = field_new!(
|
||||||
MontFp!("21575463638280843010398324269430826099269044274347216827212613867836435027261"),
|
Fq2,
|
||||||
MontFp!("10307601595873709700152284273816112264069230130616436755625194854815875713954"),
|
field_new!(
|
||||||
|
Fq,
|
||||||
|
"21575463638280843010398324269430826099269044274347216827212613867836435027261"
|
||||||
|
),
|
||||||
|
field_new!(
|
||||||
|
Fq,
|
||||||
|
"10307601595873709700152284273816112264069230130616436755625194854815875713954"
|
||||||
|
),
|
||||||
);
|
);
|
||||||
const TWIST_MUL_BY_Q_Y: Fq2 = Fq2::new(
|
const TWIST_MUL_BY_Q_Y: Fq2 = field_new!(
|
||||||
MontFp!("2821565182194536844548159561693502659359617185244120367078079554186484126554"),
|
Fq2,
|
||||||
MontFp!("3505843767911556378687030309984248845540243509899259641013678093033130930403"),
|
field_new!(
|
||||||
|
Fq,
|
||||||
|
"2821565182194536844548159561693502659359617185244120367078079554186484126554"
|
||||||
|
),
|
||||||
|
field_new!(
|
||||||
|
Fq,
|
||||||
|
"3505843767911556378687030309984248845540243509899259641013678093033130930403"
|
||||||
|
),
|
||||||
);
|
);
|
||||||
const TWIST_TYPE: TwistType = TwistType::D;
|
const TWIST_TYPE: TwistType = TwistType::D;
|
||||||
type Fp = Fq;
|
type Fp = Fq;
|
||||||
type Fp2Config = Fq2Config;
|
type Fp2Params = Fq2Parameters;
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Params = Fq6Parameters;
|
||||||
type Fp12Config = Fq12Config;
|
type Fp12Params = Fq12Parameters;
|
||||||
type G1Parameters = g1::Parameters;
|
type G1Parameters = g1::Parameters;
|
||||||
type G2Parameters = g2::Parameters;
|
type G2Parameters = g2::Parameters;
|
||||||
}
|
}
|
||||||
|
|||||||
91
bn254/src/curves/tests.rs
Executable file → Normal file
91
bn254/src/curves/tests.rs
Executable file → Normal file
@@ -1,9 +1,86 @@
|
|||||||
use ark_algebra_test_templates::*;
|
#![allow(unused_imports)]
|
||||||
use ark_ff::fields::Field;
|
use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine, ProjectiveCurve};
|
||||||
|
use ark_ff::{
|
||||||
|
fields::{Field, FpParameters, PrimeField, SquareRootField},
|
||||||
|
One, Zero,
|
||||||
|
};
|
||||||
|
use ark_serialize::CanonicalSerialize;
|
||||||
|
use ark_std::rand::Rng;
|
||||||
|
use ark_std::test_rng;
|
||||||
|
use core::ops::{AddAssign, MulAssign};
|
||||||
|
|
||||||
use crate::{Bn254, G1Projective, G2Projective};
|
use crate::{g1, g2, Bn254, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
|
||||||
|
|
||||||
test_group!(g1; G1Projective; sw);
|
use ark_algebra_test_templates::{curves::*, groups::*};
|
||||||
test_group!(g2; G2Projective; sw);
|
|
||||||
test_group!(pairing_output; ark_ec::pairing::PairingOutput<Bn254>; msm);
|
#[test]
|
||||||
test_pairing!(pairing; crate::Bn254);
|
fn test_g1_projective_curve() {
|
||||||
|
curve_tests::<G1Projective>();
|
||||||
|
|
||||||
|
sw_tests::<g1::Parameters>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_projective_group() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G1Projective = rng.gen();
|
||||||
|
let b: G1Projective = rng.gen();
|
||||||
|
group_test(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_generator() {
|
||||||
|
let generator = G1Affine::prime_subgroup_generator();
|
||||||
|
assert!(generator.is_on_curve());
|
||||||
|
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_projective_curve() {
|
||||||
|
curve_tests::<G2Projective>();
|
||||||
|
|
||||||
|
sw_tests::<g2::Parameters>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_projective_group() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G2Projective = rng.gen();
|
||||||
|
let b: G2Projective = rng.gen();
|
||||||
|
group_test(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_generator() {
|
||||||
|
let generator = G2Affine::prime_subgroup_generator();
|
||||||
|
assert!(generator.is_on_curve());
|
||||||
|
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bilinearity() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G1Projective = rng.gen();
|
||||||
|
let b: G2Projective = rng.gen();
|
||||||
|
let s: Fr = rng.gen();
|
||||||
|
|
||||||
|
let mut sa = a;
|
||||||
|
sa.mul_assign(s);
|
||||||
|
let mut sb = b;
|
||||||
|
sb.mul_assign(s);
|
||||||
|
|
||||||
|
let ans1 = Bn254::pairing(sa, b);
|
||||||
|
let ans2 = Bn254::pairing(a, sb);
|
||||||
|
let ans3 = Bn254::pairing(a, b).pow(s.into_repr());
|
||||||
|
|
||||||
|
assert_eq!(ans1, ans2);
|
||||||
|
assert_eq!(ans2, ans3);
|
||||||
|
|
||||||
|
assert_ne!(ans1, Fq12::one());
|
||||||
|
assert_ne!(ans2, Fq12::one());
|
||||||
|
assert_ne!(ans3, Fq12::one());
|
||||||
|
|
||||||
|
assert_eq!(ans1.pow(Fr::characteristic()), Fq12::one());
|
||||||
|
assert_eq!(ans2.pow(Fr::characteristic()), Fq12::one());
|
||||||
|
assert_eq!(ans3.pow(Fr::characteristic()), Fq12::one());
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,96 @@
|
|||||||
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
|
use ark_ff::{biginteger::BigInteger256 as BigInteger, field_new, fields::*};
|
||||||
|
|
||||||
#[derive(MontConfig)]
|
pub type Fq = Fp256<FqParameters>;
|
||||||
#[modulus = "21888242871839275222246405745257275088696311157297823662689037894645226208583"]
|
|
||||||
#[generator = "3"]
|
pub struct FqParameters;
|
||||||
pub struct FqConfig;
|
|
||||||
pub type Fq = Fp256<MontBackend<FqConfig, 4>>;
|
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 = BigInteger([
|
||||||
|
0x68c3488912edefaa,
|
||||||
|
0x8d087f6872aabf4f,
|
||||||
|
0x51e1a24709081231,
|
||||||
|
0x2259d6b14729c0fa,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
impl FpParameters for FqParameters {
|
||||||
|
/// MODULUS = 21888242871839275222246405745257275088696311157297823662689037894645226208583
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS: BigInteger = BigInteger([
|
||||||
|
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 = BigInteger([
|
||||||
|
0xd35d438dc58f0d9d,
|
||||||
|
0x0a78eb28f5c70b3d,
|
||||||
|
0x666ea36f7879462c,
|
||||||
|
0xe0a77c19a07df2f,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const R2: BigInteger = BigInteger([
|
||||||
|
0xf32cfc5b538afa89,
|
||||||
|
0xb5e71911d44501fb,
|
||||||
|
0x47ab1eff0a417ff6,
|
||||||
|
0x6d89f71cab8351f,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const INV: u64 = 9786893198990664585u64;
|
||||||
|
|
||||||
|
// GENERATOR = 3
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const GENERATOR: BigInteger = BigInteger([
|
||||||
|
0x7a17caa950ad28d7,
|
||||||
|
0x1f6ac17ae15521b9,
|
||||||
|
0x334bea4e696bd284,
|
||||||
|
0x2a1f6744ce179d8e,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
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 = BigInteger([
|
||||||
|
0x9e10460b6c3e7ea3,
|
||||||
|
0xcbc0b548b438e546,
|
||||||
|
0xdc2822db40c0ac2e,
|
||||||
|
0x183227397098d014,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// (T - 1) // 2 =
|
||||||
|
// 5472060717959818805561601436314318772174077789324455915672259473661306552145
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
0x4f082305b61f3f51,
|
||||||
|
0x65e05aa45a1c72a3,
|
||||||
|
0x6e14116da0605617,
|
||||||
|
0xc19139cb84c680a,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const FQ_ONE: Fq = field_new!(Fq, "1");
|
||||||
|
pub const FQ_ZERO: Fq = field_new!(Fq, "0");
|
||||||
|
|||||||
@@ -1,89 +1,77 @@
|
|||||||
use ark_ff::{fields::*, MontFp};
|
use super::*;
|
||||||
|
use ark_ff::{field_new, fields::*};
|
||||||
|
|
||||||
use crate::*;
|
pub type Fq12 = Fp12<Fq12Parameters>;
|
||||||
|
|
||||||
pub type Fq12 = Fp12<Fq12Config>;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Fq12Config;
|
pub struct Fq12Parameters;
|
||||||
|
|
||||||
impl Fp12Config for Fq12Config {
|
impl Fp12Parameters for Fq12Parameters {
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Params = Fq6Parameters;
|
||||||
|
|
||||||
const NONRESIDUE: Fq6 = Fq6::new(Fq2::ZERO, Fq2::ONE, Fq2::ZERO);
|
const NONRESIDUE: Fq6 = field_new!(Fq6, 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)
|
||||||
Fq2::new(Fq::ONE, Fq::ZERO),
|
field_new!(Fq2,
|
||||||
|
field_new!(Fq, "1"),
|
||||||
|
field_new!(Fq, "0"),
|
||||||
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^1) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("8376118865763821496583973867626364092589906065868298776909617916018768340080"),
|
field_new!(Fq, "8376118865763821496583973867626364092589906065868298776909617916018768340080"),
|
||||||
MontFp!(
|
field_new!(Fq, "16469823323077808223889137241176536799009286646108169935659301613961712198316"),
|
||||||
"16469823323077808223889137241176536799009286646108169935659301613961712198316"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^2) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!(
|
field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556617"),
|
||||||
"21888242871839275220042445260109153167277707414472061641714758635765020556617"
|
field_new!(Fq, "0"),
|
||||||
),
|
|
||||||
Fq::ZERO,
|
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^3) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!(
|
field_new!(Fq, "11697423496358154304825782922584725312912383441159505038794027105778954184319"),
|
||||||
"11697423496358154304825782922584725312912383441159505038794027105778954184319"
|
field_new!(Fq, "303847389135065887422783454877609941456349188919719272345083954437860409601"),
|
||||||
),
|
|
||||||
MontFp!("303847389135065887422783454877609941456349188919719272345083954437860409601"),
|
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^4) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!(
|
field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556616"),
|
||||||
"21888242871839275220042445260109153167277707414472061641714758635765020556616"
|
field_new!(Fq, "0"),
|
||||||
),
|
|
||||||
Fq::ZERO,
|
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^5) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("3321304630594332808241809054958361220322477375291206261884409189760185844239"),
|
field_new!(Fq, "3321304630594332808241809054958361220322477375291206261884409189760185844239"),
|
||||||
MontFp!("5722266937896532885780051958958348231143373700109372999374820235121374419868"),
|
field_new!(Fq, "5722266937896532885780051958958348231143373700109372999374820235121374419868"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^6) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^6) - 1) / 6)
|
||||||
Fq2::new(MontFp!("-1"), Fq::ZERO),
|
field_new!(Fq2,
|
||||||
|
field_new!(Fq, "-1"),
|
||||||
|
field_new!(Fq, "0"),
|
||||||
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^7) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^7) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!(
|
field_new!(Fq, "13512124006075453725662431877630910996106405091429524885779419978626457868503"),
|
||||||
"13512124006075453725662431877630910996106405091429524885779419978626457868503"
|
field_new!(Fq, "5418419548761466998357268504080738289687024511189653727029736280683514010267"),
|
||||||
),
|
|
||||||
MontFp!("5418419548761466998357268504080738289687024511189653727029736280683514010267"),
|
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^8) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^8) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("2203960485148121921418603742825762020974279258880205651966"),
|
field_new!(Fq, "2203960485148121921418603742825762020974279258880205651966"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^9) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^9) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!(
|
field_new!(Fq, "10190819375481120917420622822672549775783927716138318623895010788866272024264"),
|
||||||
"10190819375481120917420622822672549775783927716138318623895010788866272024264"
|
field_new!(Fq, "21584395482704209334823622290379665147239961968378104390343953940207365798982"),
|
||||||
),
|
|
||||||
MontFp!(
|
|
||||||
"21584395482704209334823622290379665147239961968378104390343953940207365798982"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^10) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^10) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("2203960485148121921418603742825762020974279258880205651967"),
|
field_new!(Fq, "2203960485148121921418603742825762020974279258880205651967"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^11) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^11) - 1) / 6)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!(
|
field_new!(Fq, "18566938241244942414004596690298913868373833782006617400804628704885040364344"),
|
||||||
"18566938241244942414004596690298913868373833782006617400804628704885040364344"
|
field_new!(Fq, "16165975933942742336466353786298926857552937457188450663314217659523851788715"),
|
||||||
),
|
|
||||||
MontFp!(
|
|
||||||
"16165975933942742336466353786298926857552937457188450663314217659523851788715"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,38 @@
|
|||||||
use ark_ff::{fields::*, MontFp};
|
use super::*;
|
||||||
|
use ark_ff::{field_new, fields::*};
|
||||||
|
|
||||||
use crate::*;
|
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
|
||||||
const NONRESIDUE: Fq = MontFp!("-1");
|
#[rustfmt::skip]
|
||||||
|
const NONRESIDUE: Fq = field_new!(Fq, "-1");
|
||||||
|
|
||||||
|
/// QUADRATIC_NONRESIDUE = U+2
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const QUADRATIC_NONRESIDUE: (Fq, Fq) = (
|
||||||
|
field_new!(Fq, "2"),
|
||||||
|
field_new!(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)
|
||||||
Fq::ONE,
|
field_new!(Fq, "1"),
|
||||||
// NONRESIDUE**(((q^1) - 1) / 2)
|
// NONRESIDUE**(((q^1) - 1) / 2)
|
||||||
MontFp!("-1"),
|
field_new!(Fq, "-1"),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_fp_by_nonresidue_in_place(fe: &mut Self::Fp) -> &mut Self::Fp {
|
fn mul_fp_by_nonresidue(fe: &Self::Fp) -> Self::Fp {
|
||||||
fe.neg_in_place()
|
-(*fe)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO);
|
||||||
|
pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO);
|
||||||
|
|||||||
@@ -1,105 +1,92 @@
|
|||||||
use ark_ff::{fields::*, MontFp};
|
use super::*;
|
||||||
|
use ark_ff::{field_new, fields::*};
|
||||||
|
|
||||||
use crate::*;
|
pub type Fq6 = Fp6<Fq6Parameters>;
|
||||||
|
|
||||||
pub type Fq6 = Fp6<Fq6Config>;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Fq6Config;
|
pub struct Fq6Parameters;
|
||||||
|
|
||||||
impl Fp6Config for Fq6Config {
|
impl Fp6Parameters for Fq6Parameters {
|
||||||
type Fp2Config = Fq2Config;
|
type Fp2Params = Fq2Parameters;
|
||||||
|
|
||||||
/// NONRESIDUE = U+9
|
/// NONRESIDUE = U+9
|
||||||
const NONRESIDUE: Fq2 = Fq2::new(MontFp!("9"), Fq::ONE);
|
#[rustfmt::skip]
|
||||||
|
const NONRESIDUE: Fq2 = field_new!(Fq2, field_new!(Fq, "9"), field_new!(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)
|
||||||
Fq2::new(Fq::ONE, Fq::ZERO),
|
field_new!(Fq2,
|
||||||
|
field_new!(Fq, "1"),
|
||||||
|
field_new!(Fq, "0"),
|
||||||
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^1) - 1) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!(
|
field_new!(Fq, "21575463638280843010398324269430826099269044274347216827212613867836435027261"),
|
||||||
"21575463638280843010398324269430826099269044274347216827212613867836435027261"
|
field_new!(Fq, "10307601595873709700152284273816112264069230130616436755625194854815875713954"),
|
||||||
),
|
|
||||||
MontFp!(
|
|
||||||
"10307601595873709700152284273816112264069230130616436755625194854815875713954"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^2) - 1) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!(
|
field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556616"),
|
||||||
"21888242871839275220042445260109153167277707414472061641714758635765020556616"
|
field_new!(Fq, "0"),
|
||||||
),
|
|
||||||
Fq::ZERO,
|
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^3) - 1) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("3772000881919853776433695186713858239009073593817195771773381919316419345261"),
|
field_new!(Fq, "3772000881919853776433695186713858239009073593817195771773381919316419345261"),
|
||||||
MontFp!("2236595495967245188281701248203181795121068902605861227855261137820944008926"),
|
field_new!(Fq, "2236595495967245188281701248203181795121068902605861227855261137820944008926"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^4) - 1) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("2203960485148121921418603742825762020974279258880205651966"),
|
field_new!(Fq, "2203960485148121921418603742825762020974279258880205651966"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^5) - 1) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!(
|
field_new!(Fq, "18429021223477853657660792034369865839114504446431234726392080002137598044644"),
|
||||||
"18429021223477853657660792034369865839114504446431234726392080002137598044644"
|
field_new!(Fq, "9344045779998320333812420223237981029506012124075525679208581902008406485703"),
|
||||||
),
|
|
||||||
MontFp!("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)
|
||||||
Fq2::new(Fq::ONE, Fq::ZERO),
|
field_new!(Fq2,
|
||||||
|
field_new!(Fq, "1"),
|
||||||
|
field_new!(Fq, "0"),
|
||||||
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^1) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^1) - 2) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("2581911344467009335267311115468803099551665605076196740867805258568234346338"),
|
field_new!(Fq, "2581911344467009335267311115468803099551665605076196740867805258568234346338"),
|
||||||
MontFp!(
|
field_new!(Fq, "19937756971775647987995932169929341994314640652964949448313374472400716661030"),
|
||||||
"19937756971775647987995932169929341994314640652964949448313374472400716661030"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^2) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^2) - 2) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("2203960485148121921418603742825762020974279258880205651966"),
|
field_new!(Fq, "2203960485148121921418603742825762020974279258880205651966"),
|
||||||
Fq::ZERO,
|
field_new!(Fq, "0"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^3) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^3) - 2) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!("5324479202449903542726783395506214481928257762400643279780343368557297135718"),
|
field_new!(Fq, "5324479202449903542726783395506214481928257762400643279780343368557297135718"),
|
||||||
MontFp!(
|
field_new!(Fq, "16208900380737693084919495127334387981393726419856888799917914180988844123039"),
|
||||||
"16208900380737693084919495127334387981393726419856888799917914180988844123039"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^4) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^4) - 2) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!(
|
field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556616"),
|
||||||
"21888242871839275220042445260109153167277707414472061641714758635765020556616"
|
field_new!(Fq, "0"),
|
||||||
),
|
|
||||||
Fq::ZERO,
|
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^5) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^5) - 2) / 3)
|
||||||
Fq2::new(
|
field_new!(Fq2,
|
||||||
MontFp!(
|
field_new!(Fq, "13981852324922362344252311234282257507216387789820983642040889267519694726527"),
|
||||||
"13981852324922362344252311234282257507216387789820983642040889267519694726527"
|
field_new!(Fq, "7629828391165209371577384193250820201684255241773809077146787135900891633097"),
|
||||||
),
|
|
||||||
MontFp!("7629828391165209371577384193250820201684255241773809077146787135900891633097"),
|
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_fp2_by_nonresidue_in_place(fe: &mut Fq2) -> &mut Fq2 {
|
fn mul_fp2_by_nonresidue(fe: &Fq2) -> Fq2 {
|
||||||
// (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 mut c0 = fe.c1;
|
let c0 = f.c0 + fe.c0 + Fq2Parameters::mul_fp_by_nonresidue(&fe.c1);
|
||||||
Fq2Config::mul_fp_by_nonresidue_in_place(&mut c0);
|
|
||||||
c0 += &f.c0;
|
|
||||||
c0 += &fe.c0;
|
|
||||||
let c1 = f.c1 + fe.c1 + fe.c0;
|
let c1 = f.c1 + fe.c1 + fe.c0;
|
||||||
*fe = Fq2::new(c0, c1);
|
field_new!(Fq2, c0, c1)
|
||||||
fe
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,100 @@
|
|||||||
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
|
use ark_ff::{biginteger::BigInteger256 as BigInteger, fields::*};
|
||||||
|
|
||||||
#[derive(MontConfig)]
|
pub type Fr = Fp256<FrParameters>;
|
||||||
#[modulus = "21888242871839275222246405745257275088548364400416034343698204186575808495617"]
|
|
||||||
#[generator = "5"]
|
pub struct FrParameters;
|
||||||
pub struct FrConfig;
|
|
||||||
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;
|
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 = BigInteger([
|
||||||
|
7164790868263648668u64,
|
||||||
|
11685701338293206998u64,
|
||||||
|
6216421865291908056u64,
|
||||||
|
1756667274303109607u64,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
impl FpParameters for FrParameters {
|
||||||
|
/// MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS: BigInteger = BigInteger([
|
||||||
|
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, 320) % MODULUS
|
||||||
|
/// = 6350874878119819312338956282401532410528162663560392320966563075034087161851
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const R: BigInteger = BigInteger([
|
||||||
|
12436184717236109307u64,
|
||||||
|
3962172157175319849u64,
|
||||||
|
7381016538464732718u64,
|
||||||
|
1011752739694698287u64,
|
||||||
|
]);
|
||||||
|
|
||||||
|
/// R2 = R * R % MODULUS
|
||||||
|
/// = 944936681149208446651664254269745548490766851729442924617792859073125903783
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const R2: BigInteger = BigInteger([
|
||||||
|
1997599621687373223u64,
|
||||||
|
6052339484930628067u64,
|
||||||
|
10108755138030829701u64,
|
||||||
|
150537098327114917u64,
|
||||||
|
]);
|
||||||
|
|
||||||
|
/// INV = (-MODULUS) ^ {-1} % pow(2, 64) = 14042775128853446655
|
||||||
|
const INV: u64 = 14042775128853446655u64;
|
||||||
|
|
||||||
|
/// GENERATOR = 5
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const GENERATOR: BigInteger = BigInteger([
|
||||||
|
1949230679015292902u64,
|
||||||
|
16913946402569752895u64,
|
||||||
|
5177146667339417225u64,
|
||||||
|
1571765431670520771u64,
|
||||||
|
]);
|
||||||
|
|
||||||
|
/// (MODULUS - 1)/2 =
|
||||||
|
/// 10944121435919637611123202872628637544274182200208017171849102093287904247808
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
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 = BigInteger([
|
||||||
|
0x9b9709143e1f593f,
|
||||||
|
0x181585d2833e8487,
|
||||||
|
0x131a029b85045b68,
|
||||||
|
0x30644e72e,
|
||||||
|
]);
|
||||||
|
|
||||||
|
/// (T - 1) / 2 =
|
||||||
|
/// 40770029410420498293352137776570907027550720424234931066070132305055
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
0xcdcb848a1f0fac9f,
|
||||||
|
0x0c0ac2e9419f4243,
|
||||||
|
0x098d014dc2822db4,
|
||||||
|
0x183227397,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,51 +1,123 @@
|
|||||||
use ark_algebra_test_templates::*;
|
|
||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
biginteger::{BigInt, BigInteger, BigInteger256},
|
biginteger::{BigInteger, BigInteger256},
|
||||||
fields::{FftField, Field, Fp6Config, PrimeField},
|
fields::{
|
||||||
|
fp6_3over2::Fp6Parameters, FftField, FftParameters, Field, FpParameters, PrimeField,
|
||||||
|
SquareRootField,
|
||||||
|
},
|
||||||
One, UniformRand, Zero,
|
One, UniformRand, Zero,
|
||||||
};
|
};
|
||||||
use ark_std::{
|
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
||||||
|
use ark_std::rand::Rng;
|
||||||
|
use ark_std::test_rng;
|
||||||
|
use core::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
ops::{AddAssign, MulAssign},
|
ops::{AddAssign, MulAssign, SubAssign},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Config, Fr};
|
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Parameters, FqParameters, Fr};
|
||||||
|
use ark_algebra_test_templates::fields::*;
|
||||||
|
|
||||||
test_field!(fr; Fr; mont_prime_field);
|
pub(crate) const ITERATIONS: usize = 5;
|
||||||
test_field!(fq; Fq; mont_prime_field);
|
|
||||||
test_field!(fq2; Fq2);
|
#[test]
|
||||||
test_field!(fq6; Fq6);
|
fn test_fr() {
|
||||||
test_field!(fq12; Fq12);
|
let mut rng = test_rng();
|
||||||
|
for _ in 0..ITERATIONS {
|
||||||
|
let a: Fr = rng.gen();
|
||||||
|
let b: Fr = rng.gen();
|
||||||
|
field_test(a, b);
|
||||||
|
primefield_test::<Fr>();
|
||||||
|
sqrt_field_test(b);
|
||||||
|
let byte_size = a.serialized_size();
|
||||||
|
field_serialization_test::<Fr>(byte_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
for _ in 0..ITERATIONS {
|
||||||
|
let a: Fq = rng.gen();
|
||||||
|
let b: Fq = rng.gen();
|
||||||
|
field_test(a, b);
|
||||||
|
primefield_test::<Fq>();
|
||||||
|
sqrt_field_test(a);
|
||||||
|
let byte_size = a.serialized_size();
|
||||||
|
let (_, buffer_size) = buffer_bit_byte_size(Fq::size_in_bits());
|
||||||
|
assert_eq!(byte_size, buffer_size);
|
||||||
|
field_serialization_test::<Fq>(byte_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq2() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
for _ in 0..ITERATIONS {
|
||||||
|
let a: Fq2 = rng.gen();
|
||||||
|
let b: Fq2 = rng.gen();
|
||||||
|
field_test(a, b);
|
||||||
|
sqrt_field_test(a);
|
||||||
|
}
|
||||||
|
frobenius_test::<Fq2, _>(Fq::characteristic(), 13);
|
||||||
|
let byte_size = Fq2::zero().serialized_size();
|
||||||
|
field_serialization_test::<Fq2>(byte_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq6() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
for _ in 0..ITERATIONS {
|
||||||
|
let g: Fq6 = rng.gen();
|
||||||
|
let h: Fq6 = rng.gen();
|
||||||
|
field_test(g, h);
|
||||||
|
}
|
||||||
|
frobenius_test::<Fq6, _>(Fq::characteristic(), 13);
|
||||||
|
let byte_size = Fq6::zero().serialized_size();
|
||||||
|
field_serialization_test::<Fq6>(byte_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq12() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
for _ in 0..ITERATIONS {
|
||||||
|
let g: Fq12 = rng.gen();
|
||||||
|
let h: Fq12 = rng.gen();
|
||||||
|
field_test(g, h);
|
||||||
|
}
|
||||||
|
frobenius_test::<Fq12, _>(Fq::characteristic(), 13);
|
||||||
|
let byte_size = Fq12::zero().serialized_size();
|
||||||
|
field_serialization_test::<Fq12>(byte_size);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_from() {
|
fn test_fq_repr_from() {
|
||||||
assert_eq!(BigInteger256::from(100u64), BigInt::new([100, 0, 0, 0]));
|
assert_eq!(BigInteger256::from(100), BigInteger256([100, 0, 0, 0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_is_odd() {
|
fn test_fq_repr_is_odd() {
|
||||||
assert!(!BigInteger256::from(0u64).is_odd());
|
assert!(!BigInteger256::from(0).is_odd());
|
||||||
assert!(BigInteger256::from(0u64).is_even());
|
assert!(BigInteger256::from(0).is_even());
|
||||||
assert!(BigInteger256::from(1u64).is_odd());
|
assert!(BigInteger256::from(1).is_odd());
|
||||||
assert!(!BigInteger256::from(1u64).is_even());
|
assert!(!BigInteger256::from(1).is_even());
|
||||||
assert!(!BigInteger256::from(324834872u64).is_odd());
|
assert!(!BigInteger256::from(324834872).is_odd());
|
||||||
assert!(BigInteger256::from(324834872u64).is_even());
|
assert!(BigInteger256::from(324834872).is_even());
|
||||||
assert!(BigInteger256::from(324834873u64).is_odd());
|
assert!(BigInteger256::from(324834873).is_odd());
|
||||||
assert!(!BigInteger256::from(324834873u64).is_even());
|
assert!(!BigInteger256::from(324834873).is_even());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_is_zero() {
|
fn test_fq_repr_is_zero() {
|
||||||
assert!(BigInteger256::from(0u64).is_zero());
|
assert!(BigInteger256::from(0).is_zero());
|
||||||
assert!(!BigInteger256::from(1u64).is_zero());
|
assert!(!BigInteger256::from(1).is_zero());
|
||||||
assert!(!BigInt::new([0, 0, 1, 0]).is_zero());
|
assert!(!BigInteger256([0, 0, 1, 0]).is_zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_num_bits() {
|
fn test_fq_repr_num_bits() {
|
||||||
let mut a = BigInteger256::from(0u64);
|
let mut a = BigInteger256::from(0);
|
||||||
assert_eq!(0, a.num_bits());
|
assert_eq!(0, a.num_bits());
|
||||||
a = BigInteger256::from(1u64);
|
a = BigInteger256::from(1);
|
||||||
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();
|
||||||
@@ -53,35 +125,248 @@ fn test_fq_repr_num_bits() {
|
|||||||
assert_eq!(0, a.num_bits());
|
assert_eq!(0, a.num_bits());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_add_assign() {
|
||||||
|
// Test associativity
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Generate a, b, c and ensure (a + b) + c == a + (b + c).
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
let b = Fq::rand(&mut rng);
|
||||||
|
let c = Fq::rand(&mut rng);
|
||||||
|
|
||||||
|
let mut tmp1 = a;
|
||||||
|
tmp1.add_assign(&b);
|
||||||
|
tmp1.add_assign(&c);
|
||||||
|
|
||||||
|
let mut tmp2 = b;
|
||||||
|
tmp2.add_assign(&c);
|
||||||
|
tmp2.add_assign(&a);
|
||||||
|
|
||||||
|
assert_eq!(tmp1, tmp2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_sub_assign() {
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Ensure that (a - b) + (b - a) = 0.
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
let b = Fq::rand(&mut rng);
|
||||||
|
|
||||||
|
let mut tmp1 = a;
|
||||||
|
tmp1.sub_assign(&b);
|
||||||
|
|
||||||
|
let mut tmp2 = b;
|
||||||
|
tmp2.sub_assign(&a);
|
||||||
|
|
||||||
|
tmp1.add_assign(&tmp2);
|
||||||
|
assert!(tmp1.is_zero());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_mul_assign() {
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
for _ in 0..1000000 {
|
||||||
|
// Ensure that (a * b) * c = a * (b * c)
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
let b = Fq::rand(&mut rng);
|
||||||
|
let c = Fq::rand(&mut rng);
|
||||||
|
|
||||||
|
let mut tmp1 = a;
|
||||||
|
tmp1.mul_assign(&b);
|
||||||
|
tmp1.mul_assign(&c);
|
||||||
|
|
||||||
|
let mut tmp2 = b;
|
||||||
|
tmp2.mul_assign(&c);
|
||||||
|
tmp2.mul_assign(&a);
|
||||||
|
|
||||||
|
assert_eq!(tmp1, tmp2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..1000000 {
|
||||||
|
// Ensure that r * (a + b + c) = r*a + r*b + r*c
|
||||||
|
|
||||||
|
let r = Fq::rand(&mut rng);
|
||||||
|
let mut a = Fq::rand(&mut rng);
|
||||||
|
let mut b = Fq::rand(&mut rng);
|
||||||
|
let mut c = Fq::rand(&mut rng);
|
||||||
|
|
||||||
|
let mut tmp1 = a;
|
||||||
|
tmp1.add_assign(&b);
|
||||||
|
tmp1.add_assign(&c);
|
||||||
|
tmp1.mul_assign(&r);
|
||||||
|
|
||||||
|
a.mul_assign(&r);
|
||||||
|
b.mul_assign(&r);
|
||||||
|
c.mul_assign(&r);
|
||||||
|
|
||||||
|
a.add_assign(&b);
|
||||||
|
a.add_assign(&c);
|
||||||
|
|
||||||
|
assert_eq!(tmp1, a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_squaring() {
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
for _ in 0..1000000 {
|
||||||
|
// Ensure that (a * a) = a^2
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
|
||||||
|
let mut tmp = a;
|
||||||
|
tmp.square_in_place();
|
||||||
|
|
||||||
|
let mut tmp2 = a;
|
||||||
|
tmp2.mul_assign(&a);
|
||||||
|
|
||||||
|
assert_eq!(tmp, tmp2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_inverse() {
|
||||||
|
assert!(Fq::zero().inverse().is_none());
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let one = Fq::one();
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Ensure that a * a^-1 = 1
|
||||||
|
let mut a = Fq::rand(&mut rng);
|
||||||
|
let ainv = a.inverse().unwrap();
|
||||||
|
a.mul_assign(&ainv);
|
||||||
|
assert_eq!(a, one);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_double_in_place() {
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Ensure doubling a is equivalent to adding a to itself.
|
||||||
|
let mut a = Fq::rand(&mut rng);
|
||||||
|
let mut b = a;
|
||||||
|
b.add_assign(&a);
|
||||||
|
a.double_in_place();
|
||||||
|
assert_eq!(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_negate() {
|
||||||
|
{
|
||||||
|
let a = -Fq::zero();
|
||||||
|
|
||||||
|
assert!(a.is_zero());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Ensure (a - (-a)) = 0.
|
||||||
|
let mut a = Fq::rand(&mut rng);
|
||||||
|
let b = -a;
|
||||||
|
a.add_assign(&b);
|
||||||
|
|
||||||
|
assert!(a.is_zero());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_pow() {
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
for i in 0..1000 {
|
||||||
|
// Exponentiate by various small numbers and ensure it consists with repeated
|
||||||
|
// multiplication.
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
let target = a.pow(&[i]);
|
||||||
|
let mut c = Fq::one();
|
||||||
|
for _ in 0..i {
|
||||||
|
c.mul_assign(&a);
|
||||||
|
}
|
||||||
|
assert_eq!(c, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Exponentiating by the modulus should have no effect in a prime field.
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
|
||||||
|
assert_eq!(a, a.pow(Fq::characteristic()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_sqrt() {
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
assert_eq!(Fq::zero().sqrt().unwrap(), Fq::zero());
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Ensure sqrt(a^2) = a or -a
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
let nega = -a;
|
||||||
|
let mut b = a;
|
||||||
|
b.square_in_place();
|
||||||
|
|
||||||
|
let b = b.sqrt().unwrap();
|
||||||
|
|
||||||
|
assert!(a == b || nega == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
|
// Ensure sqrt(a)^2 = a for random a
|
||||||
|
let a = Fq::rand(&mut rng);
|
||||||
|
|
||||||
|
if let Some(mut tmp) = a.sqrt() {
|
||||||
|
tmp.square_in_place();
|
||||||
|
|
||||||
|
assert_eq!(a, tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_num_bits() {
|
fn test_fq_num_bits() {
|
||||||
assert_eq!(Fq::MODULUS_BIT_SIZE, 254);
|
assert_eq!(FqParameters::MODULUS_BITS, 254);
|
||||||
|
assert_eq!(FqParameters::CAPACITY, 253);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_root_of_unity() {
|
fn test_fq_root_of_unity() {
|
||||||
assert_eq!(Fq::TWO_ADICITY, 1);
|
assert_eq!(FqParameters::TWO_ADICITY, 1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Fq::GENERATOR.pow([
|
Fq::multiplicative_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 << Fq::TWO_ADICITY]),
|
Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]),
|
||||||
Fq::one()
|
Fq::one()
|
||||||
);
|
);
|
||||||
assert!(Fq::GENERATOR.sqrt().is_none());
|
assert!(Fq::multiplicative_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..100u64 {
|
for i in 0..100 {
|
||||||
assert!(Fq::from(BigInteger256::from(i + 1)) > Fq::from(BigInteger256::from(i)));
|
assert!(Fq::from(BigInteger256::from(i + 1)) > Fq::from(BigInteger256::from(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,11 +379,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(4u64)).legendre()
|
Fq::from(BigInteger256::from(4)).legendre()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
QuadraticNonResidue,
|
QuadraticNonResidue,
|
||||||
Fq::from(BigInteger256::from(5u64)).legendre()
|
Fq::from(BigInteger256::from(5)).legendre()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +424,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());
|
||||||
Fq6Config::mul_fp2_by_nonresidue_in_place(&mut m1);
|
m1 = Fq6Parameters::mul_fp2_by_nonresidue(&m1);
|
||||||
assert_eq!(QuadraticNonResidue, m1.legendre());
|
assert_eq!(QuadraticNonResidue, m1.legendre());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
bn254/src/lib.rs
Executable file → Normal file
11
bn254/src/lib.rs
Executable file → Normal file
@@ -20,17 +20,14 @@
|
|||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//! Curve information:
|
//! Curve information:
|
||||||
//! * Base field: q =
|
//! * Base field: q = 21888242871839275222246405745257275088696311157297823662689037894645226208583
|
||||||
//! 21888242871839275222246405745257275088696311157297823662689037894645226208583
|
//! * Scalar field: r = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||||
//! * 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) =
|
//! * B = 3/(u+9) where Fq2 is represented as Fq\[u\]/(u^2+1)
|
||||||
//! Fq2(19485874751759354771024239261021720505790618469301721065564631296452457478373,
|
//! = Fq2(19485874751759354771024239261021720505790618469301721065564631296452457478373, 266929791119991161246907387137283842545076965332900288569378510910307636690)
|
||||||
//! 266929791119991161246907387137283842545076965332900288569378510910307636690)
|
|
||||||
|
|
||||||
#[cfg(feature = "curve")]
|
#[cfg(feature = "curve")]
|
||||||
mod curves;
|
mod curves;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-bw6-761"
|
name = "ark-bw6-761"
|
||||||
version = "0.4.0-alpha.1"
|
version = "0.3.0"
|
||||||
authors = [ "arkworks contributors" ]
|
authors = [ "arkworks contributors" ]
|
||||||
description = "The BW6-761 pairing-friendly elliptic curve"
|
description = "The BW6-761 pairing-friendly elliptic curve"
|
||||||
homepage = "https://arkworks.rs"
|
homepage = "https://arkworks.rs"
|
||||||
@@ -10,24 +10,18 @@ keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
|||||||
categories = ["cryptography"]
|
categories = ["cryptography"]
|
||||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
edition = "2021"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ark-ff = { version="0.4.0-alpha", default-features = false }
|
ark-ff = { version="^0.3.0", default-features = false }
|
||||||
ark-ec = { version="0.4.0-alpha", default-features = false }
|
ark-ec = { version="^0.3.0", default-features = false }
|
||||||
ark-std = { version = "0.4.0-alpha", default-features = false }
|
ark-std = { version="^0.3.0", default-features = false }
|
||||||
ark-bls12-377 = { version = "0.4.0-alpha", path = "../bls12_377", default-features = false, features = [ "base_field" ] }
|
ark-bls12-377 = { version="^0.3.0", path = "../bls12_377", default-features = false, features = [ "base_field" ] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ark-serialize = { version = "0.4.0-alpha", default-features = false }
|
ark-serialize = { version="^0.3.0", default-features = false }
|
||||||
ark-algebra-test-templates = { version = "0.4.0-alpha", default-features = false }
|
ark-algebra-test-templates = { version="^0.3.0", default-features = false }
|
||||||
ark-algebra-bench-templates = { version = "0.4.0-alpha", default-features = false }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std", "ark-bls12-377/std" ]
|
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std", "ark-bls12-377/std" ]
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "bw6_761"
|
|
||||||
path = "benches/bw6_761.rs"
|
|
||||||
harness = false
|
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
use ark_algebra_bench_templates::*;
|
|
||||||
|
|
||||||
use ark_bw6_761::{
|
|
||||||
fq::Fq, fq3::Fq3, fq6::Fq6, fr::Fr, g1::G1Projective as G1, g2::G2Projective as G2, BW6_761,
|
|
||||||
};
|
|
||||||
|
|
||||||
bench!(
|
|
||||||
Name = "BW6_761",
|
|
||||||
Pairing = BW6_761,
|
|
||||||
G1 = G1,
|
|
||||||
G2 = G2,
|
|
||||||
ScalarField = Fr,
|
|
||||||
G1BaseField = Fq,
|
|
||||||
G2BaseField = Fq3,
|
|
||||||
TargetField = Fq6,
|
|
||||||
);
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
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)
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
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)
|
|
||||||
@@ -1,20 +1,30 @@
|
|||||||
use ark_ec::{
|
|
||||||
models::{short_weierstrass::SWCurveConfig, CurveConfig},
|
|
||||||
short_weierstrass::{Affine, Projective},
|
|
||||||
};
|
|
||||||
use ark_ff::{Field, MontFp};
|
|
||||||
|
|
||||||
use crate::{Fq, Fr};
|
use crate::{Fq, Fr};
|
||||||
|
use ark_ec::{
|
||||||
|
models::{ModelParameters, SWModelParameters},
|
||||||
|
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
|
||||||
|
};
|
||||||
|
use ark_ff::field_new;
|
||||||
|
|
||||||
pub type G1Affine = Affine<Parameters>;
|
pub type G1Affine = GroupAffine<Parameters>;
|
||||||
pub type G1Projective = Projective<Parameters>;
|
pub type G1Projective = GroupProjective<Parameters>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl ModelParameters for Parameters {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWModelParameters for Parameters {
|
||||||
|
/// COEFF_A = 0
|
||||||
|
#[rustfmt::skip]
|
||||||
|
|
||||||
|
const COEFF_A: Fq = field_new!(Fq, "0");
|
||||||
|
|
||||||
|
/// COEFF_B = -1
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COEFF_B: Fq = field_new!(Fq, "-1");
|
||||||
|
|
||||||
/// COFACTOR =
|
/// COFACTOR =
|
||||||
/// 26642435879335816683987677701488073867751118270052650655942102502312977592501693353047140953112195348280268661194876
|
/// 26642435879335816683987677701488073867751118270052650655942102502312977592501693353047140953112195348280268661194876
|
||||||
@@ -30,20 +40,14 @@ impl CurveConfig for Parameters {
|
|||||||
|
|
||||||
/// COFACTOR^(-1) mod r =
|
/// COFACTOR^(-1) mod r =
|
||||||
/// 91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804
|
/// 91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804
|
||||||
const COFACTOR_INV: Fr = MontFp!("91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804");
|
#[rustfmt::skip]
|
||||||
}
|
const COFACTOR_INV: Fr = field_new!(Fr, "91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804");
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
|
||||||
/// COEFF_A = 0
|
|
||||||
const COEFF_A: Fq = Fq::ZERO;
|
|
||||||
|
|
||||||
/// COEFF_B = -1
|
|
||||||
const COEFF_B: Fq = MontFp!("-1");
|
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||||
const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||||
|
(G1_GENERATOR_X, G1_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;
|
||||||
Self::BaseField::zero()
|
Self::BaseField::zero()
|
||||||
}
|
}
|
||||||
@@ -51,8 +55,10 @@ impl SWCurveConfig for Parameters {
|
|||||||
|
|
||||||
/// G1_GENERATOR_X =
|
/// G1_GENERATOR_X =
|
||||||
/// 6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237
|
/// 6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237
|
||||||
pub const G1_GENERATOR_X: Fq = MontFp!("6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237");
|
#[rustfmt::skip]
|
||||||
|
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237");
|
||||||
|
|
||||||
/// G1_GENERATOR_Y =
|
/// G1_GENERATOR_Y =
|
||||||
/// 2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099
|
/// 2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099
|
||||||
pub const G1_GENERATOR_Y: Fq = MontFp!("2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099");
|
#[rustfmt::skip]
|
||||||
|
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099");
|
||||||
|
|||||||
@@ -1,20 +1,30 @@
|
|||||||
use ark_ec::{
|
|
||||||
models::{short_weierstrass::SWCurveConfig, CurveConfig},
|
|
||||||
short_weierstrass::{Affine, Projective},
|
|
||||||
};
|
|
||||||
use ark_ff::{Field, MontFp};
|
|
||||||
|
|
||||||
use crate::{Fq, Fr};
|
use crate::{Fq, Fr};
|
||||||
|
use ark_ec::{
|
||||||
|
models::{ModelParameters, SWModelParameters},
|
||||||
|
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
|
||||||
|
};
|
||||||
|
use ark_ff::field_new;
|
||||||
|
|
||||||
pub type G2Affine = Affine<Parameters>;
|
pub type G2Affine = GroupAffine<Parameters>;
|
||||||
pub type G2Projective = Projective<Parameters>;
|
pub type G2Projective = GroupProjective<Parameters>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl ModelParameters for Parameters {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWModelParameters for Parameters {
|
||||||
|
/// COEFF_A = 0
|
||||||
|
#[rustfmt::skip]
|
||||||
|
|
||||||
|
const COEFF_A: Fq = field_new!(Fq, "0");
|
||||||
|
|
||||||
|
/// COEFF_B = 4
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COEFF_B: Fq = field_new!(Fq, "4");
|
||||||
|
|
||||||
/// COFACTOR =
|
/// COFACTOR =
|
||||||
/// 26642435879335816683987677701488073867751118270052650655942102502312977592501693353047140953112195348280268661194869
|
/// 26642435879335816683987677701488073867751118270052650655942102502312977592501693353047140953112195348280268661194869
|
||||||
@@ -30,21 +40,14 @@ impl CurveConfig for Parameters {
|
|||||||
|
|
||||||
/// COFACTOR^(-1) mod r =
|
/// COFACTOR^(-1) mod r =
|
||||||
/// 214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124
|
/// 214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124
|
||||||
const COFACTOR_INV: Fr = MontFp!("214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124");
|
#[rustfmt::skip]
|
||||||
}
|
const COFACTOR_INV: Fr = field_new!(Fr, "214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124");
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
|
||||||
/// COEFF_A = 0
|
|
||||||
const COEFF_A: Fq = Fq::ZERO;
|
|
||||||
|
|
||||||
/// COEFF_B = 4
|
|
||||||
const COEFF_B: Fq = MontFp!("4");
|
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
||||||
const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||||
|
(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;
|
||||||
Self::BaseField::zero()
|
Self::BaseField::zero()
|
||||||
}
|
}
|
||||||
@@ -52,8 +55,10 @@ impl SWCurveConfig for Parameters {
|
|||||||
|
|
||||||
/// G2_GENERATOR_X =
|
/// G2_GENERATOR_X =
|
||||||
/// 6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428
|
/// 6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428
|
||||||
pub const G2_GENERATOR_X: Fq = MontFp!("6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_X: Fq = field_new!(Fq, "6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428");
|
||||||
|
|
||||||
/// G2_GENERATOR_Y =
|
/// G2_GENERATOR_Y =
|
||||||
/// 562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041
|
/// 562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041
|
||||||
pub const G2_GENERATOR_Y: Fq = MontFp!("562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_Y: Fq = field_new!(Fq, "562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041");
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
use crate::*;
|
|
||||||
|
|
||||||
pub mod g1;
|
pub mod g1;
|
||||||
pub mod g2;
|
pub mod g2;
|
||||||
@@ -16,7 +15,7 @@ mod tests;
|
|||||||
pub struct Parameters;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl BW6Parameters for Parameters {
|
impl BW6Parameters for Parameters {
|
||||||
const X: BigInteger = BigInt::new([
|
const X: BigInteger = BigInteger([
|
||||||
0x8508c00000000001,
|
0x8508c00000000001,
|
||||||
0x0,
|
0x0,
|
||||||
0x0,
|
0x0,
|
||||||
@@ -48,8 +47,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 Fp3Config = Fq3Config;
|
type Fp3Params = Fq3Parameters;
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Params = Fq6Parameters;
|
||||||
type G1Parameters = g1::Parameters;
|
type G1Parameters = g1::Parameters;
|
||||||
type G2Parameters = g2::Parameters;
|
type G2Parameters = g2::Parameters;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,78 @@
|
|||||||
use crate::*;
|
use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve};
|
||||||
use ark_algebra_test_templates::*;
|
use ark_ff::{Field, One, PrimeField};
|
||||||
use ark_ff::Field;
|
use ark_std::rand::Rng;
|
||||||
|
use ark_std::test_rng;
|
||||||
|
|
||||||
test_group!(g1; G1Projective; sw);
|
use crate::*;
|
||||||
test_group!(g2; G2Projective; sw);
|
|
||||||
test_group!(pairing_output; ark_ec::pairing::PairingOutput<BW6_761>; msm);
|
use ark_algebra_test_templates::{curves::*, groups::*};
|
||||||
test_pairing!(pairing; crate::BW6_761);
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_projective_curve() {
|
||||||
|
curve_tests::<G1Projective>();
|
||||||
|
|
||||||
|
sw_tests::<g1::Parameters>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_projective_group() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G1Projective = rng.gen();
|
||||||
|
let b: G1Projective = rng.gen();
|
||||||
|
group_test(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_generator() {
|
||||||
|
let generator = G1Affine::prime_subgroup_generator();
|
||||||
|
assert!(generator.is_on_curve());
|
||||||
|
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_projective_curve() {
|
||||||
|
curve_tests::<G2Projective>();
|
||||||
|
|
||||||
|
sw_tests::<g2::Parameters>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_projective_group() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G2Projective = rng.gen();
|
||||||
|
let b: G2Projective = rng.gen();
|
||||||
|
group_test(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_generator() {
|
||||||
|
let generator = G2Affine::prime_subgroup_generator();
|
||||||
|
assert!(generator.is_on_curve());
|
||||||
|
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bilinearity() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G1Projective = rng.gen();
|
||||||
|
let b: G2Projective = rng.gen();
|
||||||
|
let s: Fr = rng.gen();
|
||||||
|
|
||||||
|
let sa = a.mul(s.into_repr());
|
||||||
|
let sb = b.mul(s.into_repr());
|
||||||
|
|
||||||
|
let ans1 = BW6_761::pairing(sa, b);
|
||||||
|
let ans2 = BW6_761::pairing(a, sb);
|
||||||
|
let ans3 = BW6_761::pairing(a, b).pow(s.into_repr());
|
||||||
|
|
||||||
|
assert_eq!(ans1, ans2);
|
||||||
|
assert_eq!(ans2, ans3);
|
||||||
|
|
||||||
|
assert_ne!(ans1, Fq6::one());
|
||||||
|
assert_ne!(ans2, Fq6::one());
|
||||||
|
assert_ne!(ans3, Fq6::one());
|
||||||
|
|
||||||
|
assert_eq!(ans1.pow(Fr::characteristic()), Fq6::one());
|
||||||
|
assert_eq!(ans2.pow(Fr::characteristic()), Fq6::one());
|
||||||
|
assert_eq!(ans3.pow(Fr::characteristic()), Fq6::one());
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,175 @@
|
|||||||
use ark_ff::fields::{Fp768, MontBackend, MontConfig};
|
use ark_ff::{
|
||||||
|
biginteger::BigInteger768 as BigInteger,
|
||||||
|
field_new,
|
||||||
|
fields::{FftParameters, Fp768, Fp768Parameters, FpParameters},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(MontConfig)]
|
pub type Fq = Fp768<FqParameters>;
|
||||||
#[modulus = "6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299"]
|
|
||||||
#[generator = "2"]
|
pub struct FqParameters;
|
||||||
pub struct FqConfig;
|
|
||||||
pub type Fq = Fp768<MontBackend<FqConfig, 12>>;
|
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 = BigInteger([
|
||||||
|
17481284903592032950u64,
|
||||||
|
10104133845767975835u64,
|
||||||
|
8607375506753517913u64,
|
||||||
|
13706168424391191299u64,
|
||||||
|
9580010308493592354u64,
|
||||||
|
14241333420363995524u64,
|
||||||
|
6665632285037357566u64,
|
||||||
|
5559902898979457045u64,
|
||||||
|
15504799981718861253u64,
|
||||||
|
8332096944629367896u64,
|
||||||
|
18005297320867222879u64,
|
||||||
|
58811391084848524u64,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
impl FpParameters for FqParameters {
|
||||||
|
/// MODULUS = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS: BigInteger = BigInteger([
|
||||||
|
0xf49d00000000008b,
|
||||||
|
0xe6913e6870000082,
|
||||||
|
0x160cf8aeeaf0a437,
|
||||||
|
0x98a116c25667a8f8,
|
||||||
|
0x71dcd3dc73ebff2e,
|
||||||
|
0x8689c8ed12f9fd90,
|
||||||
|
0x03cebaff25b42304,
|
||||||
|
0x707ba638e584e919,
|
||||||
|
0x528275ef8087be41,
|
||||||
|
0xb926186a81d14688,
|
||||||
|
0xd187c94004faff3e,
|
||||||
|
0x122e824fb83ce0a
|
||||||
|
]);
|
||||||
|
|
||||||
|
const MODULUS_BITS: u32 = 761;
|
||||||
|
|
||||||
|
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
|
||||||
|
|
||||||
|
// gap to 64-bit machine word
|
||||||
|
const REPR_SHAVE_BITS: u32 = 7;
|
||||||
|
|
||||||
|
// 2^768 % MODULUS
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const R: BigInteger = BigInteger([
|
||||||
|
144959613005956565u64,
|
||||||
|
6509995272855063783u64,
|
||||||
|
11428286765660613342u64,
|
||||||
|
15738672438262922740u64,
|
||||||
|
17071399330169272331u64,
|
||||||
|
13899911246788437003u64,
|
||||||
|
12055474021000362245u64,
|
||||||
|
2545351818702954755u64,
|
||||||
|
8887388221587179644u64,
|
||||||
|
5009280847225881135u64,
|
||||||
|
15539704305423854047u64,
|
||||||
|
23071597697427581u64,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// R^2
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const R2: BigInteger = BigInteger([
|
||||||
|
14305184132582319705u64,
|
||||||
|
8868935336694416555u64,
|
||||||
|
9196887162930508889u64,
|
||||||
|
15486798265448570248u64,
|
||||||
|
5402985275949444416u64,
|
||||||
|
10893197322525159598u64,
|
||||||
|
3204916688966998390u64,
|
||||||
|
12417238192559061753u64,
|
||||||
|
12426306557607898622u64,
|
||||||
|
1305582522441154384u64,
|
||||||
|
10311846026977660324u64,
|
||||||
|
48736111365249031u64,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// (-1/MODULUS) % 2^64
|
||||||
|
const INV: u64 = 744663313386281181u64;
|
||||||
|
|
||||||
|
/// GENERATOR = 2
|
||||||
|
// primitive_root(MODULUS)
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const GENERATOR: BigInteger = BigInteger([
|
||||||
|
289919226011913130u64,
|
||||||
|
13019990545710127566u64,
|
||||||
|
4409829457611675068u64,
|
||||||
|
13030600802816293865u64,
|
||||||
|
15696054586628993047u64,
|
||||||
|
9353078419867322391u64,
|
||||||
|
5664203968291172875u64,
|
||||||
|
5090703637405909511u64,
|
||||||
|
17774776443174359288u64,
|
||||||
|
10018561694451762270u64,
|
||||||
|
12632664537138156478u64,
|
||||||
|
46143195394855163u64,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// (MODULUS - 1) / 2
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
0x7a4e800000000045,
|
||||||
|
0xf3489f3438000041,
|
||||||
|
0x0b067c577578521b,
|
||||||
|
0x4c508b612b33d47c,
|
||||||
|
0x38ee69ee39f5ff97,
|
||||||
|
0x4344e476897cfec8,
|
||||||
|
0x81e75d7f92da1182,
|
||||||
|
0xb83dd31c72c2748c,
|
||||||
|
0x29413af7c043df20,
|
||||||
|
0x5c930c3540e8a344,
|
||||||
|
0x68c3e4a0027d7f9f,
|
||||||
|
0x9174127dc1e705,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// T =
|
||||||
|
// 3445725192157866269698394841137828771239834456268075054756895080104811711121745868043841591644705843820432283876893306725580879560277123879674755849562650799475802549689254425186271815711798397975949850214984556421382456559534149
|
||||||
|
// (MODULUS - 1) / 2 ^ TWO_ADICITY
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const T: BigInteger = BigInteger([
|
||||||
|
0x7a4e800000000045,
|
||||||
|
0xf3489f3438000041,
|
||||||
|
0x0b067c577578521b,
|
||||||
|
0x4c508b612b33d47c,
|
||||||
|
0x38ee69ee39f5ff97,
|
||||||
|
0x4344e476897cfec8,
|
||||||
|
0x81e75d7f92da1182,
|
||||||
|
0xb83dd31c72c2748c,
|
||||||
|
0x29413af7c043df20,
|
||||||
|
0x5c930c3540e8a344,
|
||||||
|
0x68c3e4a0027d7f9f,
|
||||||
|
0x9174127dc1e705,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// (T - 1)/2 =
|
||||||
|
// 1722862596078933134849197420568914385619917228134037527378447540052405855560872934021920795822352921910216141938446653362790439780138561939837377924781325399737901274844627212593135907855899198987974925107492278210691228279767074
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
0xbd27400000000022,
|
||||||
|
0xf9a44f9a1c000020,
|
||||||
|
0x05833e2bbabc290d,
|
||||||
|
0xa62845b09599ea3e,
|
||||||
|
0x1c7734f71cfaffcb,
|
||||||
|
0x21a2723b44be7f64,
|
||||||
|
0x40f3aebfc96d08c1,
|
||||||
|
0x5c1ee98e39613a46,
|
||||||
|
0x14a09d7be021ef90,
|
||||||
|
0xae49861aa07451a2,
|
||||||
|
0xb461f250013ebfcf,
|
||||||
|
0x48ba093ee0f382,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,27 +1,31 @@
|
|||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
fields::fp3::{Fp3, Fp3Config},
|
field_new,
|
||||||
Field, MontFp,
|
fields::fp3::{Fp3, Fp3Parameters},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::Fq;
|
use crate::{
|
||||||
|
fields::{FQ_ONE, FQ_ZERO},
|
||||||
|
Fq,
|
||||||
|
};
|
||||||
|
|
||||||
pub type Fq3 = Fp3<Fq3Config>;
|
pub type Fq3 = Fp3<Fq3Parameters>;
|
||||||
|
|
||||||
pub struct Fq3Config;
|
pub struct Fq3Parameters;
|
||||||
|
|
||||||
impl Fp3Config for Fq3Config {
|
impl Fp3Parameters for Fq3Parameters {
|
||||||
type Fp = Fq;
|
type Fp = Fq;
|
||||||
|
|
||||||
/// NONRESIDUE = -4
|
/// NONRESIDUE = -4
|
||||||
// Fq3 = Fq\[u\]/u^3+4
|
// Fq3 = Fq\[u\]/u^3+4
|
||||||
const NONRESIDUE: Fq = MontFp!("-4");
|
#[rustfmt::skip]
|
||||||
|
const NONRESIDUE: Fq = field_new!(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 TRACE_MINUS_ONE_DIV_TWO: &'static [u64] = &[
|
const T_MINUS_ONE_DIV_TWO: &'static [u64] = &[
|
||||||
0xb5e7c000000a3eac,
|
0xb5e7c000000a3eac,
|
||||||
0xf79b99dbf41cf4ab,
|
0xf79b99dbf41cf4ab,
|
||||||
0xe9372b1919e55ee5,
|
0xe9372b1919e55ee5,
|
||||||
@@ -61,28 +65,33 @@ impl Fp3Config for Fq3Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// NONRESIDUE^T % q
|
// NONRESIDUE^T % q
|
||||||
const QUADRATIC_NONRESIDUE_TO_T: Fq3 = Fq3::new(
|
#[rustfmt::skip]
|
||||||
MontFp!("6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068298"),
|
const QUADRATIC_NONRESIDUE_TO_T: (Fq, Fq, Fq) = (
|
||||||
Fq::ZERO,
|
field_new!(Fq, "6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068298"),
|
||||||
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,
|
||||||
MontFp!("4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
|
field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
|
||||||
MontFp!("1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
|
field_new!(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,
|
||||||
MontFp!("1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
|
field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
|
||||||
MontFp!("4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
|
field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_fp_by_nonresidue_in_place(fe: &mut Self::Fp) -> &mut Self::Fp {
|
fn mul_fp_by_nonresidue(fe: &Self::Fp) -> Self::Fp {
|
||||||
fe.double_in_place().double_in_place().neg_in_place()
|
let original = -(*fe);
|
||||||
|
let double = original + &original;
|
||||||
|
double + &double
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,27 @@
|
|||||||
|
use crate::{Fq, Fq3, Fq3Parameters, FQ_ONE, FQ_ZERO};
|
||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
fields::fp6_2over3::{Fp6, Fp6Config},
|
field_new,
|
||||||
Field, MontFp,
|
fields::fp6_2over3::{Fp6, Fp6Parameters},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Fq, Fq3, Fq3Config};
|
pub type Fq6 = Fp6<Fq6Parameters>;
|
||||||
|
|
||||||
pub type Fq6 = Fp6<Fq6Config>;
|
pub struct Fq6Parameters;
|
||||||
|
|
||||||
pub struct Fq6Config;
|
impl Fp6Parameters for Fq6Parameters {
|
||||||
|
type Fp3Params = Fq3Parameters;
|
||||||
impl Fp6Config for Fq6Config {
|
|
||||||
type Fp3Config = Fq3Config;
|
|
||||||
|
|
||||||
/// NONRESIDUE = (0, 1, 0)
|
/// NONRESIDUE = (0, 1, 0)
|
||||||
const NONRESIDUE: Fq3 = Fq3::new(Fq::ZERO, Fq::ONE, Fq::ZERO);
|
#[rustfmt::skip]
|
||||||
|
const NONRESIDUE: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[
|
const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[
|
||||||
Fq::ONE,
|
field_new!(Fq, "1"),
|
||||||
MontFp!("4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775649"),
|
field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775649"),
|
||||||
MontFp!("4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
|
field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
|
||||||
MontFp!("-1"),
|
field_new!(Fq, "-1"),
|
||||||
MontFp!("1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
|
field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
|
||||||
MontFp!("1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292651"),
|
field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292651"),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
pub use ark_bls12_377::{Fq as Fr, FqConfig as FrConfig};
|
pub use ark_bls12_377::{Fq as Fr, FqParameters as FrParameters};
|
||||||
|
|||||||
@@ -1,7 +1,52 @@
|
|||||||
use crate::*;
|
use ark_ff::{Field, PrimeField};
|
||||||
use ark_algebra_test_templates::*;
|
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
||||||
|
use ark_std::rand::Rng;
|
||||||
|
use ark_std::test_rng;
|
||||||
|
|
||||||
test_field!(fr; Fr; mont_prime_field);
|
use crate::*;
|
||||||
test_field!(fq; Fq; mont_prime_field);
|
|
||||||
test_field!(fq3; Fq3);
|
use ark_algebra_test_templates::fields::*;
|
||||||
test_field!(fq6; Fq6);
|
|
||||||
|
#[test]
|
||||||
|
fn test_fr() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: Fr = rng.gen();
|
||||||
|
let b: Fr = rng.gen();
|
||||||
|
field_test(a, b);
|
||||||
|
sqrt_field_test(a);
|
||||||
|
primefield_test::<Fr>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: Fq = rng.gen();
|
||||||
|
let b: Fq = rng.gen();
|
||||||
|
field_test(a, b);
|
||||||
|
primefield_test::<Fq>();
|
||||||
|
sqrt_field_test(a);
|
||||||
|
|
||||||
|
let byte_size = a.serialized_size();
|
||||||
|
let (_, buffer_size) = buffer_bit_byte_size(Fq::size_in_bits());
|
||||||
|
assert_eq!(byte_size, buffer_size);
|
||||||
|
field_serialization_test::<Fq>(byte_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq3() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: Fq3 = rng.gen();
|
||||||
|
let b: Fq3 = rng.gen();
|
||||||
|
field_test(a, b);
|
||||||
|
sqrt_field_test(a);
|
||||||
|
frobenius_test::<Fq3, _>(Fq::characteristic(), 13);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq6() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: Fq6 = rng.gen();
|
||||||
|
let b: Fq6 = rng.gen();
|
||||||
|
field_test(a, b);
|
||||||
|
frobenius_test::<Fq6, _>(Fq::characteristic(), 13);
|
||||||
|
}
|
||||||
|
|||||||
7
bw6_761/src/lib.rs
Executable file → Normal file
7
bw6_761/src/lib.rs
Executable file → Normal file
@@ -9,10 +9,9 @@
|
|||||||
#![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
|
//! The name denotes that it is a curve generated using the Brezing--Weng method, and that
|
||||||
//! method, and that its embedding degree is 6.
|
//! its embedding degree is 6.
|
||||||
//! The main feature of this curve is that the scalar field equals the base
|
//! The main feature of this curve is that the scalar field equals the base field of the BLS12_377 curve.
|
||||||
//! field of the BLS12_377 curve.
|
|
||||||
//!
|
//!
|
||||||
//! Curve information:
|
//! Curve information:
|
||||||
//! * Base field: q = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299
|
//! * Base field: q = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-cp6-782"
|
name = "ark-cp6-782"
|
||||||
version = "0.4.0-alpha.1"
|
version = "0.3.0"
|
||||||
authors = [ "arkworks contributors" ]
|
authors = [ "arkworks contributors" ]
|
||||||
description = "The CP6-782 pairing-friendly elliptic curve"
|
description = "The CP6-782 pairing-friendly elliptic curve"
|
||||||
homepage = "https://arkworks.rs"
|
homepage = "https://arkworks.rs"
|
||||||
@@ -10,25 +10,18 @@ keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
|||||||
categories = ["cryptography"]
|
categories = ["cryptography"]
|
||||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
edition = "2021"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ark-ff = { version = "0.4.0-alpha", default-features = false }
|
ark-ff = { version = "^0.3.0", default-features = false }
|
||||||
ark-ec = { version = "0.4.0-alpha", default-features = false }
|
ark-ec = { version = "^0.3.0", default-features = false }
|
||||||
ark-std = { version = "0.4.0-alpha", default-features = false }
|
ark-std = { version = "^0.3.0", default-features = false }
|
||||||
ark-bls12-377 = { version = "0.4.0-alpha", path = "../bls12_377", default-features = false, features = [ "base_field" ] }
|
ark-bls12-377 = { version = "^0.3.0", path = "../bls12_377", default-features = false, features = [ "base_field" ] }
|
||||||
itertools = { version = "0.10", default-features = false }
|
|
||||||
ark-serialize = { version = "0.4.0-alpha", default-features = false }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ark-algebra-test-templates = { version = "0.4.0-alpha", default-features = false }
|
ark-serialize = { version = "^0.3.0", default-features = false }
|
||||||
ark-algebra-bench-templates = { version = "0.4.0-alpha", default-features = false }
|
ark-algebra-test-templates = { version = "^0.3.0", default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std", "ark-bls12-377/std" ]
|
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std", "ark-bls12-377/std" ]
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "cp6_782"
|
|
||||||
path = "benches/cp6_782.rs"
|
|
||||||
harness = false
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
../LICENSE-APACHE
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../LICENSE-MIT
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
use ark_algebra_bench_templates::*;
|
|
||||||
use ark_cp6_782::{
|
|
||||||
fq::Fq, fq3::Fq3, fq6::Fq6, fr::Fr, g1::G1Projective as G1, g2::G2Projective as G2, CP6_782,
|
|
||||||
};
|
|
||||||
|
|
||||||
bench!(
|
|
||||||
Name = "CP6_782",
|
|
||||||
Pairing = CP6_782,
|
|
||||||
G1 = G1,
|
|
||||||
G2 = G2,
|
|
||||||
ScalarField = Fr,
|
|
||||||
G1BaseField = Fq,
|
|
||||||
G2BaseField = Fq3,
|
|
||||||
TargetField = Fq6,
|
|
||||||
);
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
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)
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
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)
|
|
||||||
@@ -1,62 +1,30 @@
|
|||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
models::{short_weierstrass::SWCurveConfig, CurveConfig},
|
models::{ModelParameters, SWModelParameters},
|
||||||
short_weierstrass::{Affine, Projective},
|
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
|
||||||
AffineRepr, CurveGroup,
|
|
||||||
};
|
};
|
||||||
use ark_ff::MontFp;
|
use ark_ff::field_new;
|
||||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
|
||||||
use ark_std::vec::Vec;
|
|
||||||
|
|
||||||
use crate::{Fq, Fr};
|
use crate::{Fq, Fr};
|
||||||
|
|
||||||
pub type G1Affine = Affine<Parameters>;
|
pub type G1Affine = GroupAffine<Parameters>;
|
||||||
pub type G1Projective = Projective<Parameters>;
|
pub type G1Projective = GroupProjective<Parameters>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize)]
|
|
||||||
pub struct G1Prepared(pub G1Affine);
|
|
||||||
|
|
||||||
impl From<G1Affine> for G1Prepared {
|
|
||||||
fn from(other: G1Affine) -> Self {
|
|
||||||
G1Prepared(other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<G1Projective> for G1Prepared {
|
|
||||||
fn from(q: G1Projective) -> Self {
|
|
||||||
q.into_affine().into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a G1Affine> for G1Prepared {
|
|
||||||
fn from(other: &'a G1Affine) -> Self {
|
|
||||||
G1Prepared(*other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a G1Projective> for G1Prepared {
|
|
||||||
fn from(q: &'a G1Projective) -> Self {
|
|
||||||
q.into_affine().into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl G1Prepared {
|
|
||||||
pub fn is_zero(&self) -> bool {
|
|
||||||
self.0.is_zero()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for G1Prepared {
|
|
||||||
fn default() -> Self {
|
|
||||||
G1Prepared(G1Affine::generator())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl ModelParameters for Parameters {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWModelParameters for Parameters {
|
||||||
|
/// COEFF_A = 5
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COEFF_A: Fq = field_new!(Fq, "5");
|
||||||
|
|
||||||
|
/// COEFF_B = 17764315118651679038286329069295091506801468118146712649886336045535808055361274148466772191243305528312843236347777260247138934336850548243151534538734724191505953341403463040067571652261229308333392040104884438208594329793895206056414
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COEFF_B: Fq = field_new!(Fq, "17764315118651679038286329069295091506801468118146712649886336045535808055361274148466772191243305528312843236347777260247138934336850548243151534538734724191505953341403463040067571652261229308333392040104884438208594329793895206056414");
|
||||||
|
|
||||||
/// COFACTOR =
|
/// COFACTOR =
|
||||||
/// 86482221941698704497288378992285180119495364068003923046442785886272123124361700722982503222189455144364945735564951561028
|
/// 86482221941698704497288378992285180119495364068003923046442785886272123124361700722982503222189455144364945735564951561028
|
||||||
@@ -73,24 +41,20 @@ impl CurveConfig for Parameters {
|
|||||||
|
|
||||||
/// COFACTOR^(-1) mod r =
|
/// COFACTOR^(-1) mod r =
|
||||||
/// 163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788
|
/// 163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788
|
||||||
const COFACTOR_INV: Fr = MontFp!("163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788");
|
#[rustfmt::skip]
|
||||||
}
|
const COFACTOR_INV: Fr = field_new!(Fr, "163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788");
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
|
||||||
/// COEFF_A = 5
|
|
||||||
const COEFF_A: Fq = MontFp!("5");
|
|
||||||
|
|
||||||
/// COEFF_B = 17764315118651679038286329069295091506801468118146712649886336045535808055361274148466772191243305528312843236347777260247138934336850548243151534538734724191505953341403463040067571652261229308333392040104884438208594329793895206056414
|
|
||||||
const COEFF_B: Fq = MontFp!("17764315118651679038286329069295091506801468118146712649886336045535808055361274148466772191243305528312843236347777260247138934336850548243151534538734724191505953341403463040067571652261229308333392040104884438208594329793895206056414");
|
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||||
const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||||
|
(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// G1_GENERATOR_X =
|
/// G1_GENERATOR_X =
|
||||||
/// 5511163824921585887915590525772884263960974614921003940645351443740084257508990841338974915037175497689287870585840954231884082785026301437744745393958283053278991955159266640440849940136976927372133743626748847559939620888818486853646
|
/// 5511163824921585887915590525772884263960974614921003940645351443740084257508990841338974915037175497689287870585840954231884082785026301437744745393958283053278991955159266640440849940136976927372133743626748847559939620888818486853646
|
||||||
pub const G1_GENERATOR_X: Fq = MontFp!("5511163824921585887915590525772884263960974614921003940645351443740084257508990841338974915037175497689287870585840954231884082785026301437744745393958283053278991955159266640440849940136976927372133743626748847559939620888818486853646");
|
#[rustfmt::skip]
|
||||||
|
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "5511163824921585887915590525772884263960974614921003940645351443740084257508990841338974915037175497689287870585840954231884082785026301437744745393958283053278991955159266640440849940136976927372133743626748847559939620888818486853646");
|
||||||
|
|
||||||
/// G1_GENERATOR_Y =
|
/// G1_GENERATOR_Y =
|
||||||
/// 7913123550914612057135582061699117755797758113868200992327595317370485234417808273674357776714522052694559358668442301647906991623400754234679697332299689255516547752391831738454121261248793568285885897998257357202903170202349380518443
|
/// 7913123550914612057135582061699117755797758113868200992327595317370485234417808273674357776714522052694559358668442301647906991623400754234679697332299689255516547752391831738454121261248793568285885897998257357202903170202349380518443
|
||||||
pub const G1_GENERATOR_Y: Fq = MontFp!("7913123550914612057135582061699117755797758113868200992327595317370485234417808273674357776714522052694559358668442301647906991623400754234679697332299689255516547752391831738454121261248793568285885897998257357202903170202349380518443");
|
#[rustfmt::skip]
|
||||||
|
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "7913123550914612057135582061699117755797758113868200992327595317370485234417808273674357776714522052694559358668442301647906991623400754234679697332299689255516547752391831738454121261248793568285885897998257357202903170202349380518443");
|
||||||
|
|||||||
@@ -1,62 +1,40 @@
|
|||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
models::CurveConfig,
|
models::{ModelParameters, SWModelParameters},
|
||||||
short_weierstrass::{Affine, Projective, SWCurveConfig},
|
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
|
||||||
AffineRepr, CurveGroup,
|
|
||||||
};
|
};
|
||||||
use ark_ff::{Field, MontFp};
|
use ark_ff::field_new;
|
||||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
|
||||||
use ark_std::vec::Vec;
|
|
||||||
|
|
||||||
use crate::{Fq, Fq3, Fr};
|
use crate::{Fq, Fq3, Fr, FQ_ZERO};
|
||||||
|
|
||||||
pub type G2Affine = Affine<Parameters>;
|
pub type G2Affine = GroupAffine<Parameters>;
|
||||||
pub type G2Projective = Projective<Parameters>;
|
pub type G2Projective = GroupProjective<Parameters>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize)]
|
|
||||||
pub struct G2Prepared(pub G2Affine);
|
|
||||||
|
|
||||||
impl From<G2Affine> for G2Prepared {
|
|
||||||
fn from(other: G2Affine) -> Self {
|
|
||||||
G2Prepared(other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<G2Projective> for G2Prepared {
|
|
||||||
fn from(q: G2Projective) -> Self {
|
|
||||||
q.into_affine().into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a G2Affine> for G2Prepared {
|
|
||||||
fn from(other: &'a G2Affine) -> Self {
|
|
||||||
G2Prepared(*other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a G2Projective> for G2Prepared {
|
|
||||||
fn from(q: &'a G2Projective) -> Self {
|
|
||||||
q.into_affine().into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl G2Prepared {
|
|
||||||
pub fn is_zero(&self) -> bool {
|
|
||||||
self.0.is_zero()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for G2Prepared {
|
|
||||||
fn default() -> Self {
|
|
||||||
G2Prepared(G2Affine::generator())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl ModelParameters for Parameters {
|
||||||
type BaseField = Fq3;
|
type BaseField = Fq3;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWModelParameters for Parameters {
|
||||||
|
/// 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"),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// COEFF_B = (G1::COEFF_B * TWIST^3, 0, 0) =
|
||||||
|
/// (7237353553714858194254855835825640240663090882935418626687402315497764195116318527743248304684159666286416318482685337633828994152723793439622384740540789612754127688659139509552568164770448654259255628317166934203899992395064470477612,
|
||||||
|
/// 0, 0)
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COEFF_B: Fq3 = field_new!(Fq3,
|
||||||
|
field_new!(Fq, "7237353553714858194254855835825640240663090882935418626687402315497764195116318527743248304684159666286416318482685337633828994152723793439622384740540789612754127688659139509552568164770448654259255628317166934203899992395064470477612"),
|
||||||
|
FQ_ZERO,
|
||||||
|
FQ_ZERO,
|
||||||
|
);
|
||||||
|
|
||||||
/// COFACTOR =
|
/// COFACTOR =
|
||||||
/// 43276679045916726782882096851503554444292580777869919574700824986947162516693702667493938255647666346010819253090121562084993205202476199057555142869892665220155573207800985012241638987472334344174208389303164492698303448192856551557283997344470334833850065978668184377503856699635686872344035470027430053642178229054516302338812152178131995800255516474185251732445975837621097393375441662426280154371264547168198834382681059556891327702516519955053315674076980350109237328216856859758931256208439575383786363605925879337208599843910819433766160937121108797819223653884174994325142959644019600
|
/// 43276679045916726782882096851503554444292580777869919574700824986947162516693702667493938255647666346010819253090121562084993205202476199057555142869892665220155573207800985012241638987472334344174208389303164492698303448192856551557283997344470334833850065978668184377503856699635686872344035470027430053642178229054516302338812152178131995800255516474185251732445975837621097393375441662426280154371264547168198834382681059556891327702516519955053315674076980350109237328216856859758931256208439575383786363605925879337208599843910819433766160937121108797819223653884174994325142959644019600
|
||||||
@@ -97,49 +75,45 @@ impl CurveConfig for Parameters {
|
|||||||
|
|
||||||
/// COFACTOR^(-1) mod r =
|
/// COFACTOR^(-1) mod r =
|
||||||
/// 45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598
|
/// 45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598
|
||||||
const COFACTOR_INV: Fr = MontFp!("45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598");
|
#[rustfmt::skip]
|
||||||
}
|
const COFACTOR_INV: Fr = field_new!(Fr, "45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598");
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
|
||||||
/// COEFF_A = (0, 0, COEFF_A * TWIST^2) = (0, 0, 5)
|
|
||||||
const COEFF_A: Fq3 = Fq3::new(Fq::ZERO, Fq::ZERO, MontFp!("5"));
|
|
||||||
|
|
||||||
/// COEFF_B = (G1::COEFF_B * TWIST^3, 0, 0) =
|
|
||||||
/// (7237353553714858194254855835825640240663090882935418626687402315497764195116318527743248304684159666286416318482685337633828994152723793439622384740540789612754127688659139509552568164770448654259255628317166934203899992395064470477612,
|
|
||||||
/// 0, 0)
|
|
||||||
const COEFF_B: Fq3 = Fq3::new(
|
|
||||||
MontFp!("7237353553714858194254855835825640240663090882935418626687402315497764195116318527743248304684159666286416318482685337633828994152723793439622384740540789612754127688659139509552568164770448654259255628317166934203899992395064470477612"),
|
|
||||||
Fq::ZERO,
|
|
||||||
Fq::ZERO,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
||||||
const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||||
|
(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
const G2_GENERATOR_X: Fq3 = Fq3::new(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1, G2_GENERATOR_X_C2);
|
const G2_GENERATOR_X: Fq3 =
|
||||||
const G2_GENERATOR_Y: Fq3 = Fq3::new(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1, G2_GENERATOR_Y_C2);
|
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);
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C0 =
|
/// G2_GENERATOR_X_C0 =
|
||||||
/// 13426761183630949215425595811885033211332897733228446437546263564078445562454176776915160094418980045665397361295624472103734543457352048745726512354895954850428989867542989474136256025045975283415690491751906307188562464175510373683338
|
/// 13426761183630949215425595811885033211332897733228446437546263564078445562454176776915160094418980045665397361295624472103734543457352048745726512354895954850428989867542989474136256025045975283415690491751906307188562464175510373683338
|
||||||
pub const G2_GENERATOR_X_C0: Fq = MontFp!("13426761183630949215425595811885033211332897733228446437546263564078445562454176776915160094418980045665397361295624472103734543457352048745726512354895954850428989867542989474136256025045975283415690491751906307188562464175510373683338");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "13426761183630949215425595811885033211332897733228446437546263564078445562454176776915160094418980045665397361295624472103734543457352048745726512354895954850428989867542989474136256025045975283415690491751906307188562464175510373683338");
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C1 =
|
/// G2_GENERATOR_X_C1 =
|
||||||
/// 20471601555918880743198170952645906008198510944268658573129351735028343217532386920456705632337352161031960990613816401042894531220068552819818037605513359562118363589199569321421558696125646867661360498323171027455638052943806292028610
|
/// 20471601555918880743198170952645906008198510944268658573129351735028343217532386920456705632337352161031960990613816401042894531220068552819818037605513359562118363589199569321421558696125646867661360498323171027455638052943806292028610
|
||||||
pub const G2_GENERATOR_X_C1: Fq = MontFp!("20471601555918880743198170952645906008198510944268658573129351735028343217532386920456705632337352161031960990613816401042894531220068552819818037605513359562118363589199569321421558696125646867661360498323171027455638052943806292028610");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "20471601555918880743198170952645906008198510944268658573129351735028343217532386920456705632337352161031960990613816401042894531220068552819818037605513359562118363589199569321421558696125646867661360498323171027455638052943806292028610");
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C2 =
|
/// G2_GENERATOR_X_C2 =
|
||||||
/// 3905053196875761830053608605277158152930144841844497593936739534395003062685449846381431331169369910535935138116320442345524758217411779027270883193856999691582831339845600938304719916501940381093815781408183227875600753651697934495980
|
/// 3905053196875761830053608605277158152930144841844497593936739534395003062685449846381431331169369910535935138116320442345524758217411779027270883193856999691582831339845600938304719916501940381093815781408183227875600753651697934495980
|
||||||
pub const G2_GENERATOR_X_C2: Fq = MontFp!("3905053196875761830053608605277158152930144841844497593936739534395003062685449846381431331169369910535935138116320442345524758217411779027270883193856999691582831339845600938304719916501940381093815781408183227875600753651697934495980");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_X_C2: Fq = field_new!(Fq, "3905053196875761830053608605277158152930144841844497593936739534395003062685449846381431331169369910535935138116320442345524758217411779027270883193856999691582831339845600938304719916501940381093815781408183227875600753651697934495980");
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C0 =
|
/// G2_GENERATOR_Y_C0 =
|
||||||
/// 8567517639523571619872938228644013584947463594196306323477160496987712111576624702939472765993995586889532559039169098780892505598589581147768095093536988446010255611523736706017580686335404469207486594272103717837888228343074699140243
|
/// 8567517639523571619872938228644013584947463594196306323477160496987712111576624702939472765993995586889532559039169098780892505598589581147768095093536988446010255611523736706017580686335404469207486594272103717837888228343074699140243
|
||||||
pub const G2_GENERATOR_Y_C0: Fq = MontFp!("8567517639523571619872938228644013584947463594196306323477160496987712111576624702939472765993995586889532559039169098780892505598589581147768095093536988446010255611523736706017580686335404469207486594272103717837888228343074699140243");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "8567517639523571619872938228644013584947463594196306323477160496987712111576624702939472765993995586889532559039169098780892505598589581147768095093536988446010255611523736706017580686335404469207486594272103717837888228343074699140243");
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C1 =
|
/// G2_GENERATOR_Y_C1 =
|
||||||
/// 3890537069205870914984502594450293167889863914413852788876350245583932846980126025043974070704295857226211547108005650399870458089721518559480870503159804530091559886149680718531004778697982910253701559194337987238111062202037698927752
|
/// 3890537069205870914984502594450293167889863914413852788876350245583932846980126025043974070704295857226211547108005650399870458089721518559480870503159804530091559886149680718531004778697982910253701559194337987238111062202037698927752
|
||||||
pub const G2_GENERATOR_Y_C1: Fq = MontFp!("3890537069205870914984502594450293167889863914413852788876350245583932846980126025043974070704295857226211547108005650399870458089721518559480870503159804530091559886149680718531004778697982910253701559194337987238111062202037698927752");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "3890537069205870914984502594450293167889863914413852788876350245583932846980126025043974070704295857226211547108005650399870458089721518559480870503159804530091559886149680718531004778697982910253701559194337987238111062202037698927752");
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C2 =
|
/// G2_GENERATOR_Y_C2 =
|
||||||
/// 10936269922612615564271188303104593362724754284143779051599749016735041389483971486958818324356025479751246744831831158558101688599198721653921723013062333636402617118847009085485166284126970598561393411916461254016145116183331671450721
|
/// 10936269922612615564271188303104593362724754284143779051599749016735041389483971486958818324356025479751246744831831158558101688599198721653921723013062333636402617118847009085485166284126970598561393411916461254016145116183331671450721
|
||||||
pub const G2_GENERATOR_Y_C2: Fq = MontFp!("10936269922612615564271188303104593362724754284143779051599749016735041389483971486958818324356025479751246744831831158558101688599198721653921723013062333636402617118847009085485166284126970598561393411916461254016145116183331671450721");
|
#[rustfmt::skip]
|
||||||
|
pub const G2_GENERATOR_Y_C2: Fq = field_new!(Fq, "10936269922612615564271188303104593362724754284143779051599749016735041389483971486958818324356025479751246744831831158558101688599198721653921723013062333636402617118847009085485166284126970598561393411916461254016145116183331671450721");
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
use ark_ec::{
|
use ark_ec::{models::SWModelParameters, PairingEngine};
|
||||||
models::short_weierstrass::SWCurveConfig,
|
|
||||||
pairing::{MillerLoopOutput, Pairing, PairingOutput},
|
|
||||||
};
|
|
||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
biginteger::BigInteger832, BigInt, BitIteratorBE, CyclotomicMultSubgroup, Field, One,
|
biginteger::BigInteger832,
|
||||||
|
field_new,
|
||||||
|
fields::{BitIteratorBE, Field},
|
||||||
|
One,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
|
||||||
|
|
||||||
use crate::{Fq, Fq3, Fq6, Fr};
|
use crate::{Fq, Fq3, Fq6, Fr, FQ_ONE, FQ_ZERO};
|
||||||
|
|
||||||
pub mod g1;
|
pub mod g1;
|
||||||
pub use self::g1::{G1Affine, G1Prepared, G1Projective};
|
pub use self::g1::{G1Affine, G1Projective};
|
||||||
|
|
||||||
pub mod g2;
|
pub mod g2;
|
||||||
pub use self::g2::{G2Affine, G2Prepared, G2Projective};
|
pub use self::g2::{G2Affine, G2Projective};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
@@ -23,40 +22,40 @@ pub type GT = Fq6;
|
|||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct CP6_782;
|
pub struct CP6_782;
|
||||||
|
|
||||||
impl Pairing for CP6_782 {
|
impl PairingEngine for CP6_782 {
|
||||||
type ScalarField = Fr;
|
type Fr = Fr;
|
||||||
type BaseField = Fq;
|
type G1Projective = G1Projective;
|
||||||
type G1 = G1Projective;
|
|
||||||
type G1Affine = G1Affine;
|
type G1Affine = G1Affine;
|
||||||
type G1Prepared = G1Prepared;
|
type G1Prepared = G1Affine;
|
||||||
type G2 = G2Projective;
|
type G2Projective = G2Projective;
|
||||||
type G2Affine = G2Affine;
|
type G2Affine = G2Affine;
|
||||||
type G2Prepared = G2Prepared;
|
type G2Prepared = G2Affine;
|
||||||
type TargetField = Fq6;
|
type Fq = Fq;
|
||||||
|
type Fqe = Fq3;
|
||||||
|
type Fqk = Fq6;
|
||||||
|
|
||||||
fn multi_miller_loop(
|
fn miller_loop<'a, I>(i: I) -> Self::Fqk
|
||||||
a: impl IntoIterator<Item = impl Into<Self::G1Prepared>>,
|
where
|
||||||
b: impl IntoIterator<Item = impl Into<Self::G2Prepared>>,
|
I: IntoIterator<Item = &'a (Self::G1Prepared, Self::G2Prepared)>,
|
||||||
) -> MillerLoopOutput<Self> {
|
{
|
||||||
let mut result = Self::TargetField::one();
|
let mut result = Self::Fqk::one();
|
||||||
a.into_iter().zip_eq(b).for_each(|(p, q)| {
|
for &(ref p, ref q) in i {
|
||||||
let (p, q) = (p.into(), q.into());
|
result *= &CP6_782::ate_miller_loop(p, q);
|
||||||
result *= &CP6_782::ate_miller_loop(&p, &q);
|
}
|
||||||
});
|
result
|
||||||
|
|
||||||
MillerLoopOutput(result)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn final_exponentiation(r: MillerLoopOutput<Self>) -> Option<PairingOutput<Self>> {
|
fn final_exponentiation(r: &Self::Fqk) -> Option<Self::Fqk> {
|
||||||
Some(PairingOutput(CP6_782::final_exponentiation(&r.0)))
|
Some(CP6_782::final_exponentiation(r))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CP6_782 {
|
impl CP6_782 {
|
||||||
fn ate_miller_loop(p: &G1Prepared, q: &G2Prepared) -> Fq6 {
|
pub fn ate_pairing(p: &G1Affine, q: &G2Affine) -> GT {
|
||||||
let p = p.0;
|
CP6_782::final_exponentiation(&CP6_782::ate_miller_loop(p, q))
|
||||||
let q = q.0;
|
}
|
||||||
|
|
||||||
|
fn ate_miller_loop(p: &G1Affine, q: &G2Affine) -> Fq6 {
|
||||||
let px = p.x;
|
let px = p.x;
|
||||||
let py = p.y;
|
let py = p.y;
|
||||||
let qx = q.x;
|
let qx = q.x;
|
||||||
@@ -89,7 +88,7 @@ impl CP6_782 {
|
|||||||
|
|
||||||
let x = py_twist_squared;
|
let x = py_twist_squared;
|
||||||
let y = gamma_old_rx - &old_ry - &gamma_twist_px;
|
let y = gamma_old_rx - &old_ry - &gamma_twist_px;
|
||||||
let ell_rr_at_p: Fq6 = Fq6::new(x, y);
|
let ell_rr_at_p = Fq6::new(x, y);
|
||||||
|
|
||||||
rx = gamma.square() - &old_rx.double();
|
rx = gamma.square() - &old_rx.double();
|
||||||
ry = gamma * &(old_rx - &rx) - &old_ry;
|
ry = gamma * &(old_rx - &rx) - &old_ry;
|
||||||
@@ -107,7 +106,7 @@ impl CP6_782 {
|
|||||||
|
|
||||||
let x = py_twist_squared;
|
let x = py_twist_squared;
|
||||||
let y = gamma_qx - &qy - &gamma_twist_px;
|
let y = gamma_qx - &qy - &gamma_twist_px;
|
||||||
let ell_rq_at_p: Fq6 = Fq6::new(x, y);
|
let ell_rq_at_p = Fq6::new(x, y);
|
||||||
|
|
||||||
rx = gamma.square() - &old_rx - &qx;
|
rx = gamma.square() - &old_rx - &qx;
|
||||||
ry = gamma * &(old_rx - &rx) - &old_ry;
|
ry = gamma * &(old_rx - &rx) - &old_ry;
|
||||||
@@ -155,7 +154,7 @@ impl CP6_782 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// TWIST = (0, 1, 0)
|
/// TWIST = (0, 1, 0)
|
||||||
pub const TWIST: Fq3 = Fq3::new(Fq::ZERO, Fq::ONE, Fq::ZERO);
|
pub const TWIST: Fq3 = field_new!(Fq3, 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;
|
||||||
@@ -183,7 +182,7 @@ pub const FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG: bool = true;
|
|||||||
|
|
||||||
/// FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0 =
|
/// FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0 =
|
||||||
/// 7000705447348627246181409558336018323010329260726930841638672011287206690002601216854775649561085256265269640040570922609783227469279331691880282815325569032149343779036142830666859805506518426649197067288711084398033
|
/// 7000705447348627246181409558336018323010329260726930841638672011287206690002601216854775649561085256265269640040570922609783227469279331691880282815325569032149343779036142830666859805506518426649197067288711084398033
|
||||||
pub const FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0: BigInteger832 = BigInt::new([
|
pub const FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0: BigInteger832 = BigInteger832([
|
||||||
0xb62ef36af72855d1,
|
0xb62ef36af72855d1,
|
||||||
0x676b5cef49d290fa,
|
0x676b5cef49d290fa,
|
||||||
0xd17fcf3c60947427,
|
0xd17fcf3c60947427,
|
||||||
@@ -201,7 +200,7 @@ pub const FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0: BigInteger832 = BigInt::new([
|
|||||||
|
|
||||||
/// FINAL_EXPONENT_LAST_CHUNK_W1 =
|
/// FINAL_EXPONENT_LAST_CHUNK_W1 =
|
||||||
/// 86482221941698704497288378992285180119495364068003923046442785886272123124361700722982503222189455144364945735564951562986
|
/// 86482221941698704497288378992285180119495364068003923046442785886272123124361700722982503222189455144364945735564951562986
|
||||||
pub const FINAL_EXPONENT_LAST_CHUNK_W1: BigInteger832 = BigInt::new([
|
pub const FINAL_EXPONENT_LAST_CHUNK_W1: BigInteger832 = BigInteger832([
|
||||||
0x5657b9b57b942aea,
|
0x5657b9b57b942aea,
|
||||||
0x84f9a65f3bd54eaf,
|
0x84f9a65f3bd54eaf,
|
||||||
0x5ea4214e35cd127,
|
0x5ea4214e35cd127,
|
||||||
|
|||||||
@@ -1,9 +1,78 @@
|
|||||||
use ark_algebra_test_templates::*;
|
use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve};
|
||||||
use ark_ff::Field;
|
use ark_ff::{Field, One, PrimeField};
|
||||||
|
use ark_std::rand::Rng;
|
||||||
|
use ark_std::test_rng;
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
test_group!(g1; G1Projective; sw);
|
use ark_algebra_test_templates::{curves::*, groups::*};
|
||||||
test_group!(g2; G2Projective; sw);
|
|
||||||
test_group!(pairing_output; ark_ec::pairing::PairingOutput<CP6_782>; msm);
|
#[test]
|
||||||
test_pairing!(pairing; crate::CP6_782);
|
fn test_g1_projective_curve() {
|
||||||
|
curve_tests::<G1Projective>();
|
||||||
|
|
||||||
|
sw_tests::<g1::Parameters>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_projective_group() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G1Projective = rng.gen();
|
||||||
|
let b: G1Projective = rng.gen();
|
||||||
|
group_test(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1_generator() {
|
||||||
|
let generator = G1Affine::prime_subgroup_generator();
|
||||||
|
assert!(generator.is_on_curve());
|
||||||
|
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_projective_curve() {
|
||||||
|
curve_tests::<G2Projective>();
|
||||||
|
|
||||||
|
sw_tests::<g2::Parameters>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_projective_group() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G2Projective = rng.gen();
|
||||||
|
let b: G2Projective = rng.gen();
|
||||||
|
group_test(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g2_generator() {
|
||||||
|
let generator = G2Affine::prime_subgroup_generator();
|
||||||
|
assert!(generator.is_on_curve());
|
||||||
|
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bilinearity() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: G1Projective = rng.gen();
|
||||||
|
let b: G2Projective = rng.gen();
|
||||||
|
let s: Fr = rng.gen();
|
||||||
|
|
||||||
|
let sa = a.mul(s.into_repr());
|
||||||
|
let sb = b.mul(s.into_repr());
|
||||||
|
|
||||||
|
let ans1 = CP6_782::pairing(sa, b);
|
||||||
|
let ans2 = CP6_782::pairing(a, sb);
|
||||||
|
let ans3 = CP6_782::pairing(a, b).pow(s.into_repr());
|
||||||
|
|
||||||
|
assert_eq!(ans1, ans2);
|
||||||
|
assert_eq!(ans2, ans3);
|
||||||
|
|
||||||
|
assert_ne!(ans1, Fq6::one());
|
||||||
|
assert_ne!(ans2, Fq6::one());
|
||||||
|
assert_ne!(ans3, Fq6::one());
|
||||||
|
|
||||||
|
assert_eq!(ans1.pow(Fr::characteristic()), Fq6::one());
|
||||||
|
assert_eq!(ans2.pow(Fr::characteristic()), Fq6::one());
|
||||||
|
assert_eq!(ans3.pow(Fr::characteristic()), Fq6::one());
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,169 @@
|
|||||||
use ark_ff::fields::{Fp832, MontBackend, MontConfig};
|
use ark_ff::{
|
||||||
|
biginteger::BigInteger832 as BigInteger,
|
||||||
|
fields::{FftParameters, Fp832, Fp832Parameters, FpParameters},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(MontConfig)]
|
pub type Fq = Fp832<FqParameters>;
|
||||||
#[modulus = "22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577"]
|
|
||||||
#[generator = "13"]
|
pub struct FqParameters;
|
||||||
pub struct FqConfig;
|
|
||||||
pub type Fq = Fp832<MontBackend<FqConfig, 13>>;
|
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 = BigInteger([
|
||||||
|
18044746167194862600u64,
|
||||||
|
63590321303744709u64,
|
||||||
|
5009346151370959890u64,
|
||||||
|
2859114157767503991u64,
|
||||||
|
8301813204852325413u64,
|
||||||
|
5629414263664332594u64,
|
||||||
|
2637340888701394641u64,
|
||||||
|
17433538052687852753u64,
|
||||||
|
2230763098934759248u64,
|
||||||
|
3785382115983092023u64,
|
||||||
|
8895511354022222370u64,
|
||||||
|
15792083141709071785u64,
|
||||||
|
1328u64,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
impl FpParameters for FqParameters {
|
||||||
|
/// MODULUS = 22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS: BigInteger = BigInteger([
|
||||||
|
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 = BigInteger([
|
||||||
|
11190988450819017841u64,
|
||||||
|
16170411717126802030u64,
|
||||||
|
2265463223430229059u64,
|
||||||
|
16946880912571045974u64,
|
||||||
|
11155248462028513229u64,
|
||||||
|
12855672356664541314u64,
|
||||||
|
8489376931127408159u64,
|
||||||
|
2655797810825538098u64,
|
||||||
|
9648483887143916718u64,
|
||||||
|
17514963461276738952u64,
|
||||||
|
16777089214204267338u64,
|
||||||
|
15649035958020076168u64,
|
||||||
|
8659u64,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const R2: BigInteger = BigInteger([
|
||||||
|
13983406830510863714u64,
|
||||||
|
17863856572171232656u64,
|
||||||
|
1698388424046564526u64,
|
||||||
|
1773634430448388392u64,
|
||||||
|
8684647957094413275u64,
|
||||||
|
3992637317298078843u64,
|
||||||
|
18420879196616862245u64,
|
||||||
|
3238482510270583127u64,
|
||||||
|
7928200707794018216u64,
|
||||||
|
10024831010452223910u64,
|
||||||
|
9613847725664942650u64,
|
||||||
|
15361265984156787358u64,
|
||||||
|
7833u64,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const INV: u64 = 14469047335842394791u64;
|
||||||
|
|
||||||
|
/// GENERATOR = 13
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const GENERATOR: BigInteger = BigInteger([
|
||||||
|
16669393626057438558u64,
|
||||||
|
1640520694378723217u64,
|
||||||
|
1598646156981121135u64,
|
||||||
|
12401834967100173388u64,
|
||||||
|
2356467520877704673u64,
|
||||||
|
14759118825104212161u64,
|
||||||
|
5556628239575210651u64,
|
||||||
|
5317520392768798654u64,
|
||||||
|
16398429955031064995u64,
|
||||||
|
3556102264904210145u64,
|
||||||
|
8166834915717907988u64,
|
||||||
|
11926665585800594452u64,
|
||||||
|
11716u64,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||||
|
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 = BigInteger([
|
||||||
|
0xadace79b57b942ae,
|
||||||
|
0x7545d85c16dfd424,
|
||||||
|
0xbee135c065f4d26b,
|
||||||
|
0x99c2f764a12c4024,
|
||||||
|
0x1ad533049cfe6a3,
|
||||||
|
0x252a3fb77c79c132,
|
||||||
|
0xbab3596c8617c579,
|
||||||
|
0x7830c728d80f9d78,
|
||||||
|
0x66a7223ee72023d0,
|
||||||
|
0x3bc5d176b746af02,
|
||||||
|
0xfe959283d8f52666,
|
||||||
|
0x8c4d2263babf8941,
|
||||||
|
0x384,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// T =
|
||||||
|
// 2796234287359462116293342775812631866846949933162148072772937078455846756557253067529059877268485152522256821925480238069737214402829166671516844553287632810960290821869823500141573291432819154425935511163079134531347828686569665103197
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const T: BigInteger = BigInteger([
|
||||||
|
0x5b59cf36af72855d,
|
||||||
|
0xea8bb0b82dbfa849,
|
||||||
|
0x7dc26b80cbe9a4d6,
|
||||||
|
0x3385eec942588049,
|
||||||
|
0x35aa660939fcd47,
|
||||||
|
0x4a547f6ef8f38264,
|
||||||
|
0x7566b2d90c2f8af2,
|
||||||
|
0xf0618e51b01f3af1,
|
||||||
|
0xcd4e447dce4047a0,
|
||||||
|
0x778ba2ed6e8d5e04,
|
||||||
|
0xfd2b2507b1ea4ccc,
|
||||||
|
0x189a44c7757f1283,
|
||||||
|
0x709,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,24 +1,25 @@
|
|||||||
|
use crate::{fields::FQ_ZERO, Fq};
|
||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
fields::fp3::{Fp3, Fp3Config},
|
field_new,
|
||||||
Field, MontFp,
|
fields::fp3::{Fp3, Fp3Parameters},
|
||||||
|
Field,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::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 = 13
|
/// NONRESIDUE = 13
|
||||||
const NONRESIDUE: Fq = MontFp!("13");
|
#[rustfmt::skip]
|
||||||
|
const NONRESIDUE: Fq = field_new!(Fq, "13");
|
||||||
|
|
||||||
const TWO_ADICITY: u32 = 3;
|
const TWO_ADICITY: u32 = 3;
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
const TRACE_MINUS_ONE_DIV_TWO: &'static [u64] = &[
|
const T_MINUS_ONE_DIV_TWO: &'static [u64] = &[
|
||||||
0x62730e2cd2029617,
|
0x62730e2cd2029617,
|
||||||
0x660647f735cb88cf,
|
0x660647f735cb88cf,
|
||||||
0x274359d60784f69d,
|
0x274359d60784f69d,
|
||||||
@@ -58,31 +59,33 @@ impl Fp3Config for Fq3Config {
|
|||||||
0x2b87fda171,
|
0x2b87fda171,
|
||||||
];
|
];
|
||||||
|
|
||||||
const QUADRATIC_NONRESIDUE_TO_T: Fq3 = Fq3::new(
|
#[rustfmt::skip]
|
||||||
MontFp!("5759691735434357221228070840130186543101559976323700017469395641639510585333061695996665166662748527158637897523704071820491869715512532675375604262649010727161924084052120196921150869218319839231115277876207074651754402338718419191428"),
|
const QUADRATIC_NONRESIDUE_TO_T: (Fq, Fq, Fq) = (
|
||||||
Fq::ZERO,
|
field_new!(Fq, "5759691735434357221228070840130186543101559976323700017469395641639510585333061695996665166662748527158637897523704071820491869715512532675375604262649010727161924084052120196921150869218319839231115277876207074651754402338718419191428"),
|
||||||
Fq::ZERO,
|
FQ_ZERO,
|
||||||
|
FQ_ZERO,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[
|
const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[
|
||||||
Fq::ONE,
|
field_new!(Fq, "1"),
|
||||||
MontFp!("2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"),
|
field_new!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"),
|
||||||
MontFp!("19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"),
|
field_new!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[
|
const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[
|
||||||
Fq::ONE,
|
field_new!(Fq, "1"),
|
||||||
MontFp!("19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"),
|
field_new!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"),
|
||||||
MontFp!("2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"),
|
field_new!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_fp_by_nonresidue_in_place(fe: &mut Self::Fp) -> &mut Self::Fp {
|
fn mul_fp_by_nonresidue(fe: &Self::Fp) -> Self::Fp {
|
||||||
let original = *fe;
|
let original = *fe;
|
||||||
fe.double_in_place();
|
let mut four_fe = fe.double();
|
||||||
*fe += original;
|
four_fe.double_in_place();
|
||||||
fe.double_in_place().double_in_place();
|
let eight_fe = four_fe.double();
|
||||||
*fe += original;
|
eight_fe + &four_fe + &original
|
||||||
fe
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,27 @@
|
|||||||
|
use crate::{Fq, Fq3, Fq3Parameters, FQ_ONE, FQ_ZERO};
|
||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
fields::fp6_2over3::{Fp6, Fp6Config},
|
field_new,
|
||||||
Field, MontFp,
|
fields::fp6_2over3::{Fp6, Fp6Parameters},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Fq, Fq3, Fq3Config};
|
pub type Fq6 = Fp6<Fq6Parameters>;
|
||||||
|
|
||||||
pub type Fq6 = Fp6<Fq6Config>;
|
pub struct Fq6Parameters;
|
||||||
|
|
||||||
pub struct Fq6Config;
|
impl Fp6Parameters for Fq6Parameters {
|
||||||
|
type Fp3Params = Fq3Parameters;
|
||||||
impl Fp6Config for Fq6Config {
|
|
||||||
type Fp3Config = Fq3Config;
|
|
||||||
|
|
||||||
/// NONRESIDUE = (0, 1, 0).
|
/// NONRESIDUE = (0, 1, 0).
|
||||||
const NONRESIDUE: Fq3 = Fq3::new(Fq::ZERO, Fq::ONE, Fq::ZERO);
|
#[rustfmt::skip]
|
||||||
|
const NONRESIDUE: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[
|
const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[
|
||||||
Fq::ONE,
|
field_new!(Fq, "1"),
|
||||||
MontFp!("2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756862"),
|
field_new!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756862"),
|
||||||
MontFp!("2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"),
|
field_new!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"),
|
||||||
MontFp!("22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825576"),
|
field_new!(Fq, "22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825576"),
|
||||||
MontFp!("19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"),
|
field_new!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"),
|
||||||
MontFp!("19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068716"),
|
field_new!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068716"),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
pub use ark_bls12_377::{Fq as Fr, FqConfig as FrConfig};
|
pub use ark_bls12_377::{Fq as Fr, FqParameters as FrParameters};
|
||||||
|
|||||||
@@ -10,5 +10,5 @@ pub use self::fq3::*;
|
|||||||
pub mod fq6;
|
pub mod fq6;
|
||||||
pub use self::fq6::*;
|
pub use self::fq6::*;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(all(feature = "cp6_782", test))]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
@@ -1,7 +1,52 @@
|
|||||||
use crate::*;
|
use ark_ff::{Field, PrimeField};
|
||||||
use ark_algebra_test_templates::*;
|
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
||||||
|
use ark_std::rand::Rng;
|
||||||
|
use ark_std::test_rng;
|
||||||
|
|
||||||
test_field!(fr; Fr; mont_prime_field);
|
use crate::*;
|
||||||
test_field!(fq; Fq; mont_prime_field);
|
|
||||||
test_field!(fq3; Fq3);
|
use ark_algebra_test_templates::fields::*;
|
||||||
test_field!(fq6; Fq6);
|
|
||||||
|
#[test]
|
||||||
|
fn test_fr() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: Fr = rng.gen();
|
||||||
|
let b: Fr = rng.gen();
|
||||||
|
field_test(a, b);
|
||||||
|
sqrt_field_test(a);
|
||||||
|
primefield_test::<Fr>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: Fq = rng.gen();
|
||||||
|
let b: Fq = rng.gen();
|
||||||
|
field_test(a, b);
|
||||||
|
primefield_test::<Fq>();
|
||||||
|
sqrt_field_test(a);
|
||||||
|
|
||||||
|
let byte_size = a.serialized_size();
|
||||||
|
let (_, buffer_size) = buffer_bit_byte_size(Fq::size_in_bits());
|
||||||
|
assert_eq!(byte_size, buffer_size);
|
||||||
|
field_serialization_test::<Fq>(byte_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq3() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: Fq3 = rng.gen();
|
||||||
|
let b: Fq3 = rng.gen();
|
||||||
|
field_test(a, b);
|
||||||
|
sqrt_field_test(a);
|
||||||
|
frobenius_test::<Fq3, _>(Fq::characteristic(), 13);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq6() {
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let a: Fq6 = rng.gen();
|
||||||
|
let b: Fq6 = rng.gen();
|
||||||
|
field_test(a, b);
|
||||||
|
frobenius_test::<Fq6, _>(Fq::characteristic(), 13);
|
||||||
|
}
|
||||||
|
|||||||
5
cp6_782/src/lib.rs
Executable file → Normal file
5
cp6_782/src/lib.rs
Executable file → Normal file
@@ -9,9 +9,8 @@
|
|||||||
#![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
|
//! The name denotes that it was generated using the Cocks--Pinch method for the embedding degree 6.
|
||||||
//! embedding degree 6. The main feature of this curve is that the scalar field
|
//! The main feature of this curve is that the scalar field equals the base field of the BLS12_377 curve.
|
||||||
//! equals the base field of the BLS12_377 curve.
|
|
||||||
//!
|
//!
|
||||||
//! Curve information:
|
//! Curve information:
|
||||||
//! * Base field: q = 22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577
|
//! * Base field: q = 22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577
|
||||||
|
|||||||
115
curve-benches/Cargo.toml
Normal file
115
curve-benches/Cargo.toml
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
[package]
|
||||||
|
name = "ark-curve-benches"
|
||||||
|
version = "0.3.0"
|
||||||
|
authors = [
|
||||||
|
"Sean Bowe",
|
||||||
|
"Alessandro Chiesa",
|
||||||
|
"Matthew Green",
|
||||||
|
"Ian Miers",
|
||||||
|
"Pratyush Mishra",
|
||||||
|
"Howard Wu",
|
||||||
|
"Daira Hopwood"
|
||||||
|
]
|
||||||
|
description = "A benchmark library for finite fields and elliptic curves"
|
||||||
|
homepage = "https://arkworks.rs"
|
||||||
|
repository = "https://github.com/arkworks-rs/curves"
|
||||||
|
documentation = "https://docs.rs/algebra/"
|
||||||
|
keywords = ["cryptography", "finite-fields", "elliptic-curves", "pairing"]
|
||||||
|
categories = ["cryptography"]
|
||||||
|
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||||
|
license = "MIT/Apache-2.0"
|
||||||
|
edition = "2018"
|
||||||
|
publish = false
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
|
################################# Dependencies ################################
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bencher = { version = "0.1.5" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
ark-std = { version = "^0.3.0", default-features = false }
|
||||||
|
ark-ec = { version = "^0.3.0", default-features = false }
|
||||||
|
ark-ff = { version = "^0.3.0", default-features = false }
|
||||||
|
ark-serialize = { version = "^0.3.0", default-features = false }
|
||||||
|
|
||||||
|
ark-mnt4-298 = { path = "../mnt4_298" }
|
||||||
|
ark-mnt6-298 = { path = "../mnt6_298" }
|
||||||
|
ark-mnt4-753 = { path = "../mnt4_753" }
|
||||||
|
ark-mnt6-753 = { path = "../mnt6_753" }
|
||||||
|
ark-bn254 = { path = "../bn254" }
|
||||||
|
ark-bls12-377 = { path = "../bls12_377" }
|
||||||
|
ark-bls12-381 = { path = "../bls12_381" }
|
||||||
|
ark-ed-on-bls12-381 = { path = "../ed_on_bls12_381" }
|
||||||
|
ark-bw6-761 = { path = "../bw6_761" }
|
||||||
|
ark-cp6-782 = { path = "../cp6_782" }
|
||||||
|
ark-pallas = { path = "../pallas" }
|
||||||
|
ark-vesta = { path = "../vesta" }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
asm = [ "ark-ff/asm"]
|
||||||
|
parallel = [ "ark-ff/parallel", "ark-ec/parallel", ]
|
||||||
|
n_fold = []
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
rustc_version = "0.2"
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "bls12_377"
|
||||||
|
path = "benches/bls12_377.rs"
|
||||||
|
harness = false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "bls12_381"
|
||||||
|
path = "benches/bls12_381.rs"
|
||||||
|
harness = false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "bn254"
|
||||||
|
path = "benches/bn254.rs"
|
||||||
|
harness = false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "bw6_761"
|
||||||
|
path = "benches/bw6_761.rs"
|
||||||
|
harness = false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "cp6_782"
|
||||||
|
path = "benches/cp6_782.rs"
|
||||||
|
harness = false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "ed_on_bls12_381"
|
||||||
|
path = "benches/ed_on_bls12_381.rs"
|
||||||
|
harness = false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "mnt4_298"
|
||||||
|
path = "benches/mnt4_298.rs"
|
||||||
|
harness = false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "mnt6_298"
|
||||||
|
path = "benches/mnt6_298.rs"
|
||||||
|
harness = false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "mnt4_753"
|
||||||
|
path = "benches/mnt4_753.rs"
|
||||||
|
harness = false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "mnt6_753"
|
||||||
|
path = "benches/mnt6_753.rs"
|
||||||
|
harness = false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "pallas"
|
||||||
|
path = "benches/pallas.rs"
|
||||||
|
harness = false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "vesta"
|
||||||
|
path = "benches/vesta.rs"
|
||||||
|
harness = false
|
||||||
30
curve-benches/benches/bls12_377.rs
Normal file
30
curve-benches/benches/bls12_377.rs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
use ark_curve_benches::*;
|
||||||
|
use ark_std::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
|
use ark_bls12_377::{
|
||||||
|
fq::Fq, fq2::Fq2, fr::Fr, Bls12_377, Fq12, G1Affine, G1Projective as G1, G2Affine,
|
||||||
|
G2Projective as G2,
|
||||||
|
};
|
||||||
|
use ark_ec::{PairingEngine, ProjectiveCurve};
|
||||||
|
use ark_ff::{
|
||||||
|
biginteger::{BigInteger256 as FrRepr, BigInteger384 as FqRepr},
|
||||||
|
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
|
||||||
|
};
|
||||||
|
|
||||||
|
mod g1 {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G1, G1Affine);
|
||||||
|
}
|
||||||
|
mod g2 {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G2, G2Affine);
|
||||||
|
}
|
||||||
|
|
||||||
|
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||||
|
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);
|
||||||
|
f_bench!(extension, Fq2, Fq2, fq2);
|
||||||
|
f_bench!(target, Fq12, Fq12, fq12);
|
||||||
|
|
||||||
|
pairing_bench!(Bls12_377, Fq12);
|
||||||
|
|
||||||
|
bencher::benchmark_main!(fq, fr, fq2, fq12, g1::group_ops, g2::group_ops, pairing);
|
||||||
30
curve-benches/benches/bls12_381.rs
Normal file
30
curve-benches/benches/bls12_381.rs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
use ark_curve_benches::*;
|
||||||
|
use ark_std::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
|
use ark_bls12_381::{
|
||||||
|
fq::Fq, fq2::Fq2, fr::Fr, Bls12_381, Fq12, G1Affine, G1Projective as G1, G2Affine,
|
||||||
|
G2Projective as G2,
|
||||||
|
};
|
||||||
|
use ark_ec::{PairingEngine, ProjectiveCurve};
|
||||||
|
use ark_ff::{
|
||||||
|
biginteger::{BigInteger256 as FrRepr, BigInteger384 as FqRepr},
|
||||||
|
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
|
||||||
|
};
|
||||||
|
|
||||||
|
mod g1 {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G1, G1Affine);
|
||||||
|
}
|
||||||
|
mod g2 {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G2, G2Affine);
|
||||||
|
}
|
||||||
|
|
||||||
|
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||||
|
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);
|
||||||
|
f_bench!(extension, Fq2, Fq2, fq2);
|
||||||
|
f_bench!(target, Fq12, Fq12, fq12);
|
||||||
|
|
||||||
|
pairing_bench!(Bls12_381, Fq12);
|
||||||
|
|
||||||
|
bencher::benchmark_main!(fq, fr, fq2, fq12, g1::group_ops, g2::group_ops, pairing);
|
||||||
30
curve-benches/benches/bn254.rs
Normal file
30
curve-benches/benches/bn254.rs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
use ark_curve_benches::*;
|
||||||
|
use ark_std::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
|
use ark_bn254::{
|
||||||
|
fq::Fq, fq2::Fq2, fr::Fr, Bn254, Fq12, G1Affine, G1Projective as G1, G2Affine,
|
||||||
|
G2Projective as G2,
|
||||||
|
};
|
||||||
|
use ark_ec::{PairingEngine, ProjectiveCurve};
|
||||||
|
use ark_ff::{
|
||||||
|
biginteger::{BigInteger256 as FrRepr, BigInteger256 as FqRepr},
|
||||||
|
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
|
||||||
|
};
|
||||||
|
|
||||||
|
mod g1 {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G1, G1Affine);
|
||||||
|
}
|
||||||
|
mod g2 {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G2, G2Affine);
|
||||||
|
}
|
||||||
|
|
||||||
|
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||||
|
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);
|
||||||
|
f_bench!(extension, Fq2, Fq2, fq2);
|
||||||
|
f_bench!(target, Fq12, Fq12, fq12);
|
||||||
|
|
||||||
|
pairing_bench!(Bn254, Fq12);
|
||||||
|
|
||||||
|
bencher::benchmark_main!(fq, fr, fq2, fq12, g1::group_ops, g2::group_ops, pairing);
|
||||||
29
curve-benches/benches/bw6_761.rs
Normal file
29
curve-benches/benches/bw6_761.rs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
use ark_curve_benches::*;
|
||||||
|
use ark_std::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
|
use ark_bw6_761::{
|
||||||
|
fq::Fq, fq3::Fq3, fr::Fr, Fq6, G1Affine, G1Projective as G1, G2Affine, G2Projective as G2,
|
||||||
|
BW6_761,
|
||||||
|
};
|
||||||
|
use ark_ec::{PairingEngine, ProjectiveCurve};
|
||||||
|
use ark_ff::{
|
||||||
|
biginteger::{BigInteger384 as FrRepr, BigInteger768 as FqRepr},
|
||||||
|
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
|
||||||
|
};
|
||||||
|
|
||||||
|
mod g1 {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G1, G1Affine);
|
||||||
|
}
|
||||||
|
mod g2 {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G2, G2Affine);
|
||||||
|
}
|
||||||
|
|
||||||
|
f_bench!(extension, Fq3, Fq3, fq3);
|
||||||
|
f_bench!(target, Fq6, Fq6, fq6);
|
||||||
|
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||||
|
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);
|
||||||
|
pairing_bench!(BW6_761, Fq6);
|
||||||
|
|
||||||
|
bencher::benchmark_main!(fq, fr, fq3, fq6, g1::group_ops, g2::group_ops, pairing);
|
||||||
29
curve-benches/benches/cp6_782.rs
Normal file
29
curve-benches/benches/cp6_782.rs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
use ark_curve_benches::*;
|
||||||
|
use ark_std::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
|
use ark_cp6_782::{
|
||||||
|
fq::Fq, fq3::Fq3, fr::Fr, Fq6, G1Affine, G1Projective as G1, G2Affine, G2Projective as G2,
|
||||||
|
CP6_782,
|
||||||
|
};
|
||||||
|
use ark_ec::{PairingEngine, ProjectiveCurve};
|
||||||
|
use ark_ff::{
|
||||||
|
biginteger::{BigInteger384 as FrRepr, BigInteger832 as FqRepr},
|
||||||
|
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
|
||||||
|
};
|
||||||
|
|
||||||
|
mod g1 {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G1, G1Affine);
|
||||||
|
}
|
||||||
|
mod g2 {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G2, G2Affine);
|
||||||
|
}
|
||||||
|
|
||||||
|
f_bench!(extension, Fq3, Fq3, fq3);
|
||||||
|
f_bench!(target, Fq6, Fq6, fq6);
|
||||||
|
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||||
|
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);
|
||||||
|
pairing_bench!(CP6_782, Fq6);
|
||||||
|
|
||||||
|
bencher::benchmark_main!(fq, fr, fq3, fq6, g1::group_ops, g2::group_ops, pairing);
|
||||||
19
curve-benches/benches/ed_on_bls12_381.rs
Normal file
19
curve-benches/benches/ed_on_bls12_381.rs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
use ark_curve_benches::*;
|
||||||
|
use ark_std::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
|
use ark_ec::ProjectiveCurve;
|
||||||
|
use ark_ed_on_bls12_381::{fq::Fq, fr::Fr, EdwardsAffine as GAffine, EdwardsProjective as G};
|
||||||
|
use ark_ff::{
|
||||||
|
biginteger::{BigInteger256 as FrRepr, BigInteger256 as FqRepr},
|
||||||
|
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
|
||||||
|
};
|
||||||
|
|
||||||
|
mod g {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G, GAffine);
|
||||||
|
}
|
||||||
|
|
||||||
|
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||||
|
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);
|
||||||
|
|
||||||
|
bencher::benchmark_main!(fq, fr, g::group_ops);
|
||||||
29
curve-benches/benches/mnt4_298.rs
Normal file
29
curve-benches/benches/mnt4_298.rs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
use ark_curve_benches::*;
|
||||||
|
use ark_std::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
|
use ark_ec::{PairingEngine, ProjectiveCurve};
|
||||||
|
use ark_ff::{
|
||||||
|
biginteger::BigInteger320 as FqRepr, BigInteger, Field, PrimeField, SquareRootField,
|
||||||
|
UniformRand,
|
||||||
|
};
|
||||||
|
use ark_mnt4_298::{
|
||||||
|
fq::Fq, fq2::Fq2, fr::Fr, Fq4, G1Affine, G1Projective as G1, G2Affine, G2Projective as G2,
|
||||||
|
MNT4_298,
|
||||||
|
};
|
||||||
|
|
||||||
|
mod g1 {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G1, G1Affine);
|
||||||
|
}
|
||||||
|
mod g2 {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G2, G2Affine);
|
||||||
|
}
|
||||||
|
|
||||||
|
f_bench!(extension, Fq2, Fq2, fq2);
|
||||||
|
f_bench!(target, Fq4, Fq4, fq4);
|
||||||
|
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||||
|
f_bench!(Fr, Fr, FqRepr, FqRepr, fr);
|
||||||
|
pairing_bench!(MNT4_298, Fq4);
|
||||||
|
|
||||||
|
bencher::benchmark_main!(fq, fr, fq2, fq4, g1::group_ops, g2::group_ops, pairing);
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user