mirror of
https://github.com/arnaucube/ark-curves-cherry-picked.git
synced 2026-01-27 14:13:46 +01:00
Compare commits
1 Commits
v0.4.0-alp
...
update-to-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23d97681af |
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
|
||||||
|
|||||||
@@ -8,21 +8,12 @@
|
|||||||
### Breaking changes
|
### Breaking changes
|
||||||
|
|
||||||
- [\#104](https://github.com/arkworks-rs/curves/pull/104) Remove `QUADRATIC_NONRESIDUE` parameter from implementors of `Fp2Config`.
|
- [\#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.
|
|
||||||
- [\#122](https://github.com/arkworks-rs/curves/pull/122) Add the secp256k1 and secq256k1 curves.
|
|
||||||
- [\#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
|
||||||
|
|
||||||
|
|||||||
17
Cargo.toml
17
Cargo.toml
@@ -1,6 +1,7 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
|
|
||||||
members = [
|
members = [
|
||||||
|
"curve-benches",
|
||||||
"curve-constraint-tests",
|
"curve-constraint-tests",
|
||||||
|
|
||||||
"bls12_377",
|
"bls12_377",
|
||||||
@@ -29,14 +30,7 @@ members = [
|
|||||||
|
|
||||||
"pallas",
|
"pallas",
|
||||||
"vesta",
|
"vesta",
|
||||||
|
|
||||||
"secp256k1",
|
|
||||||
"secq256k1",
|
|
||||||
|
|
||||||
"curve25519",
|
|
||||||
"ed25519",
|
|
||||||
]
|
]
|
||||||
resolver = "2"
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
@@ -62,3 +56,12 @@ 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" }
|
||||||
|
ark-algebra-test-templates = { git = "https://github.com/arkworks-rs/algebra" }
|
||||||
|
ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std" }
|
||||||
|
ark-std = { git = "https://github.com/arkworks-rs/std" }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-bls12-377"
|
name = "ark-bls12-377"
|
||||||
version = "0.4.0-alpha.2"
|
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,39 +1,45 @@
|
|||||||
use ark_ec::{bls12::Bls12Config, CurveConfig};
|
use ark_ec::{bls12::Bls12Parameters, CurveConfig};
|
||||||
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::Config;
|
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<Config>;
|
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.
|
||||||
pub type G2Var = bls12::G2Var<Config>;
|
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<
|
||||||
<Config as Bls12Config>::G1Config,
|
<Parameters as Bls12Parameters>::G1Parameters,
|
||||||
FpVar<<<Config as Bls12Config>::G1Config as CurveConfig>::BaseField>,
|
FpVar<<<Parameters as Bls12Parameters>::G1Parameters as CurveConfig>::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
|
||||||
/// which enables speeding up pairing computation.
|
/// which enables speeding up pairing computation.
|
||||||
pub type G1PreparedVar = bls12::G1PreparedVar<Config>;
|
pub type G1PreparedVar = bls12::G1PreparedVar<Parameters>;
|
||||||
/// Represents the cached precomputation that can be performed on a G2 element
|
/// Represents the cached precomputation that can be performed on a G2 element
|
||||||
/// which enables speeding up pairing computation.
|
/// which enables speeding up pairing computation.
|
||||||
pub type G2PreparedVar = bls12::G2PreparedVar<Config>;
|
pub type G2PreparedVar = bls12::G2PreparedVar<Parameters>;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
use ark_ec::models::bls12::Bls12Config;
|
use ark_ec::models::bls12::Bls12Parameters;
|
||||||
ark_curve_constraint_tests::curves::sw_test::<<Config as Bls12Config>::G1Config, G1Var>()
|
ark_curve_constraint_tests::curves::sw_test::<
|
||||||
.unwrap();
|
<Parameters as Bls12Parameters>::G1Parameters,
|
||||||
|
G1Var,
|
||||||
|
>()
|
||||||
|
.unwrap();
|
||||||
ark_curve_constraint_tests::curves::te_test::<
|
ark_curve_constraint_tests::curves::te_test::<
|
||||||
<Config as Bls12Config>::G1Config,
|
<Parameters as Bls12Parameters>::G1Parameters,
|
||||||
G1TEAffineVar,
|
G1TEAffineVar,
|
||||||
>()
|
>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
ark_curve_constraint_tests::curves::sw_test::<<Config as Bls12Config>::G2Config, G2Var>()
|
ark_curve_constraint_tests::curves::sw_test::<
|
||||||
.unwrap();
|
<Parameters as Bls12Parameters>::G2Parameters,
|
||||||
|
G2Var,
|
||||||
|
>()
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,11 @@
|
|||||||
use crate::Config;
|
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<Config>;
|
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();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ use core::ops::Neg;
|
|||||||
use crate::{Fq, Fr};
|
use crate::{Fq, Fr};
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Config;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Config {
|
impl CurveConfig for Parameters {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ impl CurveConfig for Config {
|
|||||||
const COFACTOR_INV: Fr = MontFp!("5285428838741532253824584287042945485047145357130994810877");
|
const COFACTOR_INV: Fr = MontFp!("5285428838741532253824584287042945485047145357130994810877");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Config {
|
impl SWCurveConfig for Parameters {
|
||||||
/// COEFF_A = 0
|
/// COEFF_A = 0
|
||||||
const COEFF_A: Fq = Fq::ZERO;
|
const COEFF_A: Fq = Fq::ZERO;
|
||||||
|
|
||||||
@@ -36,14 +36,14 @@ impl SWCurveConfig for Config {
|
|||||||
const GENERATOR: G1SWAffine = G1SWAffine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
const GENERATOR: G1SWAffine = G1SWAffine::new_unchecked(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<Config>;
|
pub type G1SWAffine = SWAffine<Parameters>;
|
||||||
pub type G1TEAffine = TEAffine<Config>;
|
pub type G1TEAffine = TEAffine<Parameters>;
|
||||||
pub type G1TEProjective = TEProjective<Config>;
|
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
|
||||||
@@ -92,7 +92,7 @@ pub type G1TEProjective = TEProjective<Config>;
|
|||||||
/// # b = -TE1d/TE1a
|
/// # b = -TE1d/TE1a
|
||||||
/// TE2d = Fp(122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179)
|
/// TE2d = Fp(122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179)
|
||||||
/// ```
|
/// ```
|
||||||
impl TECurveConfig for Config {
|
impl TECurveConfig for Parameters {
|
||||||
/// COEFF_A = -1
|
/// COEFF_A = -1
|
||||||
const COEFF_A: Fq = MontFp!("-1");
|
const COEFF_A: Fq = MontFp!("-1");
|
||||||
|
|
||||||
@@ -102,11 +102,11 @@ impl TECurveConfig for Config {
|
|||||||
/// 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 GENERATOR: G1TEAffine = G1TEAffine::new_unchecked(TE_GENERATOR_X, TE_GENERATOR_Y);
|
||||||
|
|
||||||
type MontCurveConfig = Config;
|
type MontCurveConfig = 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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,14 +140,14 @@ impl TECurveConfig for Config {
|
|||||||
// # MB = s
|
// # MB = s
|
||||||
// MB=Fp(10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931)
|
// MB=Fp(10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931)
|
||||||
// ```
|
// ```
|
||||||
impl MontCurveConfig for Config {
|
impl MontCurveConfig for Parameters {
|
||||||
/// COEFF_A = 228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384
|
/// COEFF_A = 228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384
|
||||||
const COEFF_A: Fq = MontFp!("228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384");
|
const COEFF_A: Fq = MontFp!("228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384");
|
||||||
|
|
||||||
/// COEFF_B = 10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931
|
/// COEFF_B = 10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931
|
||||||
const COEFF_B: Fq = MontFp!("10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931");
|
const COEFF_B: Fq = MontFp!("10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931");
|
||||||
|
|
||||||
type TECurveConfig = Config;
|
type TECurveConfig = Parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// G1_GENERATOR_X =
|
/// G1_GENERATOR_X =
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ use ark_ff::{Field, MontFp, Zero};
|
|||||||
|
|
||||||
use crate::{g1, Fq, Fq2, Fr};
|
use crate::{g1, Fq, Fq2, Fr};
|
||||||
|
|
||||||
pub type G2Affine = Affine<Config>;
|
pub type G2Affine = Affine<Parameters>;
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Config;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Config {
|
impl CurveConfig for Parameters {
|
||||||
type BaseField = Fq2;
|
type BaseField = Fq2;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -34,9 +34,9 @@ impl CurveConfig for Config {
|
|||||||
MontFp!("6764900296503390671038341982857278410319949526107311149686707033187604810669");
|
MontFp!("6764900296503390671038341982857278410319949526107311149686707033187604810669");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Config {
|
impl SWCurveConfig for Parameters {
|
||||||
/// COEFF_A = [0, 0]
|
/// COEFF_A = [0, 0]
|
||||||
const COEFF_A: Fq2 = Fq2::new(g1::Config::COEFF_A, g1::Config::COEFF_A);
|
const COEFF_A: Fq2 = Fq2::new(g1::Parameters::COEFF_A, g1::Parameters::COEFF_A);
|
||||||
|
|
||||||
// As per https://eprint.iacr.org/2012/072.pdf,
|
// As per https://eprint.iacr.org/2012/072.pdf,
|
||||||
// this curve has b' = b/i, where b is the COEFF_B of G1, and x^6 -i is
|
// this curve has b' = b/i, where b is the COEFF_B of G1, and x^6 -i is
|
||||||
@@ -53,7 +53,7 @@ impl SWCurveConfig for Config {
|
|||||||
const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
const GENERATOR: G2Affine = G2Affine::new_unchecked(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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bls12,
|
bls12,
|
||||||
bls12::{Bls12, Bls12Config, TwistType},
|
bls12::{Bls12, Bls12Parameters, TwistType},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
@@ -11,9 +11,9 @@ pub mod g2;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
pub struct Config;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl Bls12Config for Config {
|
impl Bls12Parameters for Parameters {
|
||||||
const X: &'static [u64] = &[0x8508c00000000001];
|
const X: &'static [u64] = &[0x8508c00000000001];
|
||||||
/// `x` is positive.
|
/// `x` is positive.
|
||||||
const X_IS_NEGATIVE: bool = false;
|
const X_IS_NEGATIVE: bool = false;
|
||||||
@@ -22,15 +22,15 @@ impl Bls12Config for Config {
|
|||||||
type Fp2Config = Fq2Config;
|
type Fp2Config = Fq2Config;
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Config = Fq6Config;
|
||||||
type Fp12Config = Fq12Config;
|
type Fp12Config = Fq12Config;
|
||||||
type G1Config = g1::Config;
|
type G1Parameters = g1::Parameters;
|
||||||
type G2Config = g2::Config;
|
type G2Parameters = g2::Parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Bls12_377 = Bls12<Config>;
|
pub type Bls12_377 = Bls12<Parameters>;
|
||||||
|
|
||||||
pub type G1Affine = bls12::G1Affine<Config>;
|
pub type G1Affine = bls12::G1Affine<Parameters>;
|
||||||
pub type G1Projective = bls12::G1Projective<Config>;
|
pub type G1Projective = bls12::G1Projective<Parameters>;
|
||||||
pub type G2Affine = bls12::G2Affine<Config>;
|
pub type G2Affine = bls12::G2Affine<Parameters>;
|
||||||
pub type G2Projective = bls12::G2Projective<Config>;
|
pub type G2Projective = bls12::G2Projective<Parameters>;
|
||||||
|
|
||||||
pub use g1::{G1TEAffine, G1TEProjective};
|
pub use g1::{G1TEAffine, G1TEProjective};
|
||||||
|
|||||||
@@ -1,7 +1,19 @@
|
|||||||
use crate::{Bls12_377, G1Projective, G2Projective};
|
use ark_algebra_test_templates::{
|
||||||
use ark_algebra_test_templates::*;
|
curves::{curve_tests, edwards_tests, sw_tests},
|
||||||
|
generate_bilinearity_test, generate_g1_generator_raw_test, generate_g1_test, generate_g2_test,
|
||||||
|
msm::test_var_base_msm,
|
||||||
|
};
|
||||||
|
use ark_ec::{models::short_weierstrass::SWCurveConfig, AffineCurve, PairingEngine};
|
||||||
|
use ark_ff::{
|
||||||
|
fields::{Field, PrimeField},
|
||||||
|
One, Zero,
|
||||||
|
};
|
||||||
|
use ark_std::{rand::Rng, test_rng};
|
||||||
|
use core::ops::{AddAssign, MulAssign};
|
||||||
|
|
||||||
test_group!(g1; G1Projective; sw);
|
use crate::{g1, g2, Bls12_377, Fq, Fq12, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
|
||||||
test_group!(g2; G2Projective; sw);
|
|
||||||
test_group!(pairing_output; ark_ec::pairing::PairingOutput<Bls12_377>; msm);
|
generate_g1_test!(bls12_377; curve_tests; sw_tests; edwards_tests;);
|
||||||
test_pairing!(pairing; crate::Bls12_377);
|
generate_g2_test!(bls12_377; curve_tests; sw_tests;);
|
||||||
|
generate_bilinearity_test!(Bls12_377, Fq12);
|
||||||
|
generate_g1_generator_raw_test!(bls12_377, 1);
|
||||||
|
|||||||
@@ -21,31 +21,10 @@ impl Fp2Config for Fq2Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,12 +68,10 @@ impl Fp6Config for Fq6Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[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 = Fq2Config::mul_fp_by_nonresidue(&fe.c1);
|
||||||
fe.c0 = fe.c1;
|
let c1 = fe.c0;
|
||||||
Fq2Config::mul_fp_by_nonresidue_in_place(&mut fe.c0);
|
Fq2::new(c0, c1)
|
||||||
fe.c1 = old_c0;
|
|
||||||
fe
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
use ark_algebra_test_templates::*;
|
use ark_algebra_test_templates::{
|
||||||
|
fields::*, generate_field_serialization_test, generate_field_test,
|
||||||
|
};
|
||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
biginteger::{BigInt, BigInteger, BigInteger384},
|
biginteger::{BigInt, BigInteger, BigInteger384},
|
||||||
fields::{FftField, Field, Fp6Config, PrimeField},
|
fields::{FftField, Field, Fp6Config, PrimeField},
|
||||||
Fp384, One, UniformRand, Zero,
|
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, Fq6, Fq6Config, FqConfig, Fr, FrConfig};
|
||||||
|
|
||||||
test_field!(fr; Fr; mont_prime_field);
|
generate_field_test!(bls12_377; fq2; fq6; fq12; mont(6, 4); );
|
||||||
test_field!(fq; Fq; mont_prime_field);
|
generate_field_serialization_test!(bls12_377; fq2; fq6; fq12;);
|
||||||
test_field!(fq2; Fq2);
|
|
||||||
test_field!(fq6; Fq6);
|
|
||||||
test_field!(fq12; Fq12);
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_from() {
|
fn test_fq_repr_from() {
|
||||||
@@ -85,7 +85,7 @@ 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..100u64 {
|
||||||
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 +95,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(4u64)).legendre()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
QuadraticNonResidue,
|
||||||
|
Fq::from(BigInteger384::from(5u64)).legendre()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -136,7 +142,7 @@ fn test_fq2_legendre() {
|
|||||||
// i^2 = -1
|
// i^2 = -1
|
||||||
let mut m1 = -Fq2::one();
|
let mut m1 = -Fq2::one();
|
||||||
assert_eq!(QuadraticResidue, m1.legendre());
|
assert_eq!(QuadraticResidue, m1.legendre());
|
||||||
Fq6Config::mul_fp2_by_nonresidue_in_place(&mut m1);
|
m1 = Fq6Config::mul_fp2_by_nonresidue(&m1);
|
||||||
assert_eq!(QuadraticNonResidue, m1.legendre());
|
assert_eq!(QuadraticNonResidue, m1.legendre());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-bls12-381"
|
name = "ark-bls12-381"
|
||||||
version = "0.4.0-alpha.2"
|
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,26 +1,22 @@
|
|||||||
use crate::*;
|
|
||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bls12,
|
bls12,
|
||||||
bls12::Bls12Config,
|
bls12::Bls12Parameters,
|
||||||
models::CurveConfig,
|
models::CurveConfig,
|
||||||
short_weierstrass::{Affine, SWCurveConfig},
|
short_weierstrass::{Affine, SWCurveConfig},
|
||||||
AffineRepr, Group,
|
AffineCurve, ProjectiveCurve,
|
||||||
};
|
};
|
||||||
use ark_ff::{Field, MontFp, PrimeField, Zero};
|
use ark_ff::{Field, MontFp, Zero};
|
||||||
use ark_serialize::{Compress, SerializationError};
|
use ark_std::ops::Neg;
|
||||||
use ark_std::{ops::Neg, One};
|
|
||||||
|
|
||||||
use crate::util::{
|
use crate::*;
|
||||||
read_g1_compressed, read_g1_uncompressed, serialize_fq, EncodingFlags, G1_SERIALIZED_SIZE,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub type G1Affine = bls12::G1Affine<crate::Config>;
|
pub type G1Affine = bls12::G1Affine<crate::Parameters>;
|
||||||
pub type G1Projective = bls12::G1Projective<crate::Config>;
|
pub type G1Projective = bls12::G1Projective<crate::Parameters>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Config;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Config {
|
impl CurveConfig for Parameters {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -33,7 +29,7 @@ impl CurveConfig for Config {
|
|||||||
MontFp!("52435875175126190458656871551744051925719901746859129887267498875565241663483");
|
MontFp!("52435875175126190458656871551744051925719901746859129887267498875565241663483");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Config {
|
impl SWCurveConfig for Parameters {
|
||||||
/// COEFF_A = 0
|
/// COEFF_A = 0
|
||||||
const COEFF_A: Fq = Fq::ZERO;
|
const COEFF_A: Fq = Fq::ZERO;
|
||||||
|
|
||||||
@@ -44,7 +40,7 @@ impl SWCurveConfig for Config {
|
|||||||
const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
const GENERATOR: G1Affine = G1Affine::new_unchecked(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()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,90 +53,15 @@ impl SWCurveConfig for Config {
|
|||||||
// 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_bigint(crate::Config::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::Config::X).neg();
|
let minus_x_squared_times_p = x_times_p.mul_bigint(crate::Parameters::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();
|
|
||||||
Config::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::Config::X_IS_NEGATIVE, crate::Config::X);
|
|
||||||
Fr::one() - X
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// G1_GENERATOR_X =
|
/// G1_GENERATOR_X =
|
||||||
@@ -154,7 +75,7 @@ pub const G1_GENERATOR_Y: Fq = MontFp!("1339506544944476473020471379941921221584
|
|||||||
/// 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 = MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350");
|
||||||
|
|
||||||
pub fn endomorphism(p: &Affine<Config>) -> Affine<Config> {
|
pub fn endomorphism(p: &Affine<Parameters>) -> Affine<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.
|
||||||
@@ -162,33 +83,3 @@ pub fn endomorphism(p: &Affine<Config>) -> Affine<Config> {
|
|||||||
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::Config> {
|
|
||||||
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::Config> = sample_unchecked();
|
|
||||||
let p = p.clear_cofactor();
|
|
||||||
assert!(p.is_on_curve());
|
|
||||||
assert!(p.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,28 +1,21 @@
|
|||||||
use ark_std::ops::Neg;
|
|
||||||
|
|
||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bls12,
|
bls12,
|
||||||
bls12::Bls12Config,
|
bls12::Bls12Parameters,
|
||||||
models::CurveConfig,
|
models::CurveConfig,
|
||||||
short_weierstrass::{Affine, Projective, SWCurveConfig},
|
short_weierstrass::{Affine, SWCurveConfig},
|
||||||
AffineRepr, CurveGroup, Group,
|
AffineCurve,
|
||||||
};
|
};
|
||||||
use ark_ff::{Field, MontFp, Zero};
|
use ark_ff::{Field, MontFp, Zero};
|
||||||
use ark_serialize::{Compress, SerializationError};
|
|
||||||
|
|
||||||
use super::util::{serialize_fq, EncodingFlags, G2_SERIALIZED_SIZE};
|
use crate::*;
|
||||||
use crate::{
|
|
||||||
util::{read_g2_compressed, read_g2_uncompressed},
|
|
||||||
*,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub type G2Affine = bls12::G2Affine<crate::Config>;
|
pub type G2Affine = bls12::G2Affine<crate::Parameters>;
|
||||||
pub type G2Projective = bls12::G2Projective<crate::Config>;
|
pub type G2Projective = bls12::G2Projective<crate::Parameters>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Config;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Config {
|
impl CurveConfig for Parameters {
|
||||||
type BaseField = Fq2;
|
type BaseField = Fq2;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -47,18 +40,18 @@ impl CurveConfig for Config {
|
|||||||
MontFp!("26652489039290660355457965112010883481355318854675681319708643586776743290055");
|
MontFp!("26652489039290660355457965112010883481355318854675681319708643586776743290055");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Config {
|
impl SWCurveConfig for Parameters {
|
||||||
/// COEFF_A = [0, 0]
|
/// COEFF_A = [0, 0]
|
||||||
const COEFF_A: Fq2 = Fq2::new(g1::Config::COEFF_A, g1::Config::COEFF_A);
|
const COEFF_A: Fq2 = Fq2::new(g1::Parameters::COEFF_A, g1::Parameters::COEFF_A);
|
||||||
|
|
||||||
/// COEFF_B = [4, 4]
|
/// COEFF_B = [4, 4]
|
||||||
const COEFF_B: Fq2 = Fq2::new(g1::Config::COEFF_B, g1::Config::COEFF_B);
|
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 GENERATOR: G2Affine = G2Affine::new_unchecked(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()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,8 +60,8 @@ impl SWCurveConfig for Config {
|
|||||||
//
|
//
|
||||||
// Checks that [p]P = [X]P
|
// Checks that [p]P = [X]P
|
||||||
|
|
||||||
let mut x_times_point = point.mul_bigint(crate::Config::X);
|
let mut x_times_point = point.mul_bigint(crate::Parameters::X);
|
||||||
if crate::Config::X_IS_NEGATIVE {
|
if crate::Parameters::X_IS_NEGATIVE {
|
||||||
x_times_point = -x_times_point;
|
x_times_point = -x_times_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,109 +69,6 @@ impl SWCurveConfig for Config {
|
|||||||
|
|
||||||
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::Config::X;
|
|
||||||
let p_projective = p.into_group();
|
|
||||||
|
|
||||||
// [x]P
|
|
||||||
let x_p = Config::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<Config> = 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 = Fq2::new(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
||||||
@@ -219,12 +109,7 @@ pub const P_POWER_ENDOMORPHISM_COEFF_1: Fq2 = Fq2::new(
|
|||||||
"1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257")
|
"1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257")
|
||||||
);
|
);
|
||||||
|
|
||||||
pub const DOUBLE_P_POWER_ENDOMORPHISM: Fq2 = Fq2::new(
|
pub fn p_power_endomorphism(p: &Affine<Parameters>) -> Affine<Parameters> {
|
||||||
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
|
||||||
Fq::ZERO
|
|
||||||
);
|
|
||||||
|
|
||||||
pub fn p_power_endomorphism(p: &Affine<Config>) -> Affine<Config> {
|
|
||||||
// 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,
|
||||||
@@ -240,8 +125,8 @@ pub fn p_power_endomorphism(p: &Affine<Config>) -> Affine<Config> {
|
|||||||
// as implemented in the code as follows.
|
// as implemented in the code as follows.
|
||||||
|
|
||||||
let mut res = *p;
|
let mut res = *p;
|
||||||
res.x.frobenius_map_in_place(1);
|
res.x.frobenius_map(1);
|
||||||
res.y.frobenius_map_in_place(1);
|
res.y.frobenius_map(1);
|
||||||
|
|
||||||
let tmp_x = res.x.clone();
|
let tmp_x = res.x.clone();
|
||||||
res.x.c0 = -P_POWER_ENDOMORPHISM_COEFF_0.c1 * &tmp_x.c1;
|
res.x.c0 = -P_POWER_ENDOMORPHISM_COEFF_0.c1 * &tmp_x.c1;
|
||||||
@@ -250,47 +135,3 @@ pub fn p_power_endomorphism(p: &Affine<Config>) -> Affine<Config> {
|
|||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For a p-power endomorphism psi(P), compute psi(psi(P))
|
|
||||||
pub fn double_p_power_endomorphism(p: &Projective<Config>) -> Projective<Config> {
|
|
||||||
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::Config>::rand(&mut rng);
|
|
||||||
let optimised = p.clear_cofactor().into_group();
|
|
||||||
let naive = g2::Config::mul_affine(&p, h_eff);
|
|
||||||
assert_eq!(optimised, naive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use ark_ec::bls12::{Bls12, Bls12Config, TwistType};
|
use ark_ec::bls12::{Bls12, Bls12Parameters, TwistType};
|
||||||
|
|
||||||
use crate::{Fq, Fq12Config, Fq2Config, Fq6Config};
|
use crate::{Fq, Fq12Config, Fq2Config, Fq6Config};
|
||||||
|
|
||||||
pub mod g1;
|
pub mod g1;
|
||||||
pub mod g2;
|
pub mod g2;
|
||||||
pub(crate) mod util;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
@@ -14,11 +13,11 @@ pub use self::{
|
|||||||
g2::{G2Affine, G2Projective},
|
g2::{G2Affine, G2Projective},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type Bls12_381 = Bls12<Config>;
|
pub type Bls12_381 = Bls12<Parameters>;
|
||||||
|
|
||||||
pub struct Config;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl Bls12Config for Config {
|
impl Bls12Parameters for Parameters {
|
||||||
const X: &'static [u64] = &[0xd201000000010000];
|
const X: &'static [u64] = &[0xd201000000010000];
|
||||||
const X_IS_NEGATIVE: bool = true;
|
const X_IS_NEGATIVE: bool = true;
|
||||||
const TWIST_TYPE: TwistType = TwistType::M;
|
const TWIST_TYPE: TwistType = TwistType::M;
|
||||||
@@ -26,6 +25,6 @@ impl Bls12Config for Config {
|
|||||||
type Fp2Config = Fq2Config;
|
type Fp2Config = Fq2Config;
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Config = Fq6Config;
|
||||||
type Fp12Config = Fq12Config;
|
type Fp12Config = Fq12Config;
|
||||||
type G1Config = self::g1::Config;
|
type G1Parameters = self::g1::Parameters;
|
||||||
type G2Config = self::g2::Config;
|
type G2Parameters = self::g2::Parameters;
|
||||||
}
|
}
|
||||||
|
|||||||
71
bls12_381/src/curves/tests.rs
Executable file
71
bls12_381/src/curves/tests.rs
Executable file
@@ -0,0 +1,71 @@
|
|||||||
|
use ark_algebra_test_templates::{
|
||||||
|
curves::*, generate_bilinearity_test, generate_g1_generator_raw_test, generate_g1_test,
|
||||||
|
generate_g2_test, msm::*,
|
||||||
|
};
|
||||||
|
use ark_ec::{
|
||||||
|
models::short_weierstrass::SWCurveConfig, AffineCurve, PairingEngine, ProjectiveCurve,
|
||||||
|
};
|
||||||
|
use ark_ff::{
|
||||||
|
fields::{Field, PrimeField},
|
||||||
|
One, UniformRand, Zero,
|
||||||
|
};
|
||||||
|
use ark_std::{rand::Rng, test_rng};
|
||||||
|
use core::ops::{AddAssign, MulAssign};
|
||||||
|
|
||||||
|
use crate::{g1, g2, Bls12_381, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
|
||||||
|
|
||||||
|
generate_g1_test!(bls12_381; curve_tests; sw_tests;);
|
||||||
|
generate_g2_test!(bls12_381; curve_tests; sw_tests;);
|
||||||
|
generate_bilinearity_test!(Bls12_381, Fq12);
|
||||||
|
generate_g1_generator_raw_test!(bls12_381, 4);
|
||||||
|
|
||||||
|
#[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_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(x, greatest) {
|
||||||
|
if !p.into_projective().mul_bigint(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,215 +0,0 @@
|
|||||||
use ark_ec::{short_weierstrass::Affine, AffineRepr};
|
|
||||||
use ark_ff::{BigInteger384, PrimeField};
|
|
||||||
use ark_serialize::SerializationError;
|
|
||||||
|
|
||||||
use crate::{g1::Config as G1Config, g2::Config as G2Config, 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<G1Config>, 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<G1Config>, 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<G2Config>, 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<G2Config>, 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)
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,5 @@ use ark_ff::fields::{Fp384, MontBackend, MontConfig};
|
|||||||
#[derive(MontConfig)]
|
#[derive(MontConfig)]
|
||||||
#[modulus = "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787"]
|
#[modulus = "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787"]
|
||||||
#[generator = "2"]
|
#[generator = "2"]
|
||||||
#[small_subgroup_base = "3"]
|
|
||||||
#[small_subgroup_power = "2"]
|
|
||||||
pub struct FqConfig;
|
pub struct FqConfig;
|
||||||
pub type Fq = Fp384<MontBackend<FqConfig, 6>>;
|
pub type Fq = Fp384<MontBackend<FqConfig, 6>>;
|
||||||
|
|||||||
@@ -21,22 +21,7 @@ impl Fp2Config for Fq2Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,10 +82,11 @@ impl Fp6Config for Fq6Config {
|
|||||||
|
|
||||||
/// 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,5 @@ use ark_ff::fields::{Fp256, MontBackend, MontConfig};
|
|||||||
#[derive(MontConfig)]
|
#[derive(MontConfig)]
|
||||||
#[modulus = "52435875175126190479447740508185965837690552500527637822603658699938581184513"]
|
#[modulus = "52435875175126190479447740508185965837690552500527637822603658699938581184513"]
|
||||||
#[generator = "7"]
|
#[generator = "7"]
|
||||||
#[small_subgroup_base = "3"]
|
|
||||||
#[small_subgroup_power = "1"]
|
|
||||||
pub struct FrConfig;
|
pub struct FrConfig;
|
||||||
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;
|
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
use ark_algebra_test_templates::*;
|
use ark_algebra_test_templates::{
|
||||||
|
fields::*, generate_field_serialization_test, generate_field_test,
|
||||||
|
};
|
||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
biginteger::{BigInt, BigInteger, BigInteger384},
|
biginteger::{BigInt, BigInteger, BigInteger384},
|
||||||
fields::{FftField, Field, Fp12Config, Fp2Config, Fp6Config, PrimeField},
|
fields::{FftField, Field, Fp12Config, Fp2Config, Fp6Config, PrimeField},
|
||||||
One, UniformRand, Zero,
|
One, UniformRand, Zero,
|
||||||
};
|
};
|
||||||
|
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
||||||
use ark_std::{
|
use ark_std::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
ops::{AddAssign, MulAssign, SubAssign},
|
ops::{AddAssign, MulAssign, SubAssign},
|
||||||
vec,
|
rand::Rng,
|
||||||
|
test_rng, vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Fq, Fq12, Fq12Config, Fq2, Fq2Config, Fq6, Fq6Config, Fr};
|
use crate::{Fq, Fq12, Fq12Config, Fq2, Fq2Config, Fq6, Fq6Config, FqConfig, Fr, FrConfig};
|
||||||
|
|
||||||
test_field!(fr; Fr; mont_prime_field);
|
generate_field_test!(bls12_381; fq2; fq6; fq12; mont(6, 4); );
|
||||||
test_field!(fq; Fq; mont_prime_field);
|
generate_field_serialization_test!(bls12_381; fq2; fq6; fq12;);
|
||||||
test_field!(fq2; Fq2);
|
|
||||||
test_field!(fq6; Fq6);
|
|
||||||
test_field!(fq12; Fq12);
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_negative_one() {
|
fn test_negative_one() {
|
||||||
@@ -1601,7 +1602,7 @@ fn test_fq2_doubling() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq2_frobenius_map_in_place() {
|
fn test_fq2_frobenius_map() {
|
||||||
let mut a = Fq2::new(
|
let mut a = Fq2::new(
|
||||||
Fq::from(BigInt::new([
|
Fq::from(BigInt::new([
|
||||||
0x2d0078036923ffc7,
|
0x2d0078036923ffc7,
|
||||||
@@ -1620,7 +1621,7 @@ fn test_fq2_frobenius_map_in_place() {
|
|||||||
0x12d1137b8a6a837,
|
0x12d1137b8a6a837,
|
||||||
])),
|
])),
|
||||||
);
|
);
|
||||||
a.frobenius_map_in_place(0);
|
a.frobenius_map(0);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
a,
|
a,
|
||||||
Fq2::new(
|
Fq2::new(
|
||||||
@@ -1642,7 +1643,7 @@ fn test_fq2_frobenius_map_in_place() {
|
|||||||
])),
|
])),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
a.frobenius_map_in_place(1);
|
a.frobenius_map(1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
a,
|
a,
|
||||||
Fq2::new(
|
Fq2::new(
|
||||||
@@ -1664,7 +1665,7 @@ fn test_fq2_frobenius_map_in_place() {
|
|||||||
])),
|
])),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
a.frobenius_map_in_place(1);
|
a.frobenius_map(1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
a,
|
a,
|
||||||
Fq2::new(
|
Fq2::new(
|
||||||
@@ -1686,7 +1687,7 @@ fn test_fq2_frobenius_map_in_place() {
|
|||||||
])),
|
])),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
a.frobenius_map_in_place(2);
|
a.frobenius_map(2);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
a,
|
a,
|
||||||
Fq2::new(
|
Fq2::new(
|
||||||
@@ -1718,7 +1719,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 = Fq6Config::mul_fp2_by_nonresidue(&m1);
|
||||||
assert_eq!(QuadraticNonResidue, m1.legendre());
|
assert_eq!(QuadraticNonResidue, m1.legendre());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1731,7 +1732,7 @@ fn test_fq2_mul_nonresidue() {
|
|||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
let mut a = Fq2::rand(&mut rng);
|
let mut a = Fq2::rand(&mut rng);
|
||||||
let mut b = a;
|
let mut b = a;
|
||||||
Fq6Config::mul_fp2_by_nonresidue_in_place(&mut a);
|
a = Fq6Config::mul_fp2_by_nonresidue(&a);
|
||||||
b.mul_assign(&nqr);
|
b.mul_assign(&nqr);
|
||||||
|
|
||||||
assert_eq!(a, b);
|
assert_eq!(a, b);
|
||||||
@@ -1747,7 +1748,7 @@ fn test_fq6_mul_nonresidue() {
|
|||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
let mut a = Fq6::rand(&mut rng);
|
let mut a = Fq6::rand(&mut rng);
|
||||||
let mut b = a;
|
let mut b = a;
|
||||||
Fq12Config::mul_fp6_by_nonresidue_in_place(&mut a);
|
a = Fq12Config::mul_fp6_by_nonresidue(&a);
|
||||||
b.mul_assign(&nqr);
|
b.mul_assign(&nqr);
|
||||||
|
|
||||||
assert_eq!(a, b);
|
assert_eq!(a, b);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-bn254"
|
name = "ark-bn254"
|
||||||
version = "0.4.0-alpha.2"
|
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,
|
|
||||||
);
|
|
||||||
@@ -7,11 +7,11 @@ 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 Config;
|
pub struct Parameters;
|
||||||
|
|
||||||
pub type G1Affine = Affine<Config>;
|
pub type G1Affine = Affine<Parameters>;
|
||||||
|
|
||||||
impl CurveConfig for Config {
|
impl CurveConfig for Parameters {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ impl CurveConfig for Config {
|
|||||||
const COFACTOR_INV: Fr = Fr::ONE;
|
const COFACTOR_INV: Fr = Fr::ONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Config {
|
impl SWCurveConfig for Parameters {
|
||||||
/// COEFF_A = 0
|
/// COEFF_A = 0
|
||||||
const COEFF_A: Fq = Fq::ZERO;
|
const COEFF_A: Fq = Fq::ZERO;
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ impl SWCurveConfig for Config {
|
|||||||
const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
const GENERATOR: G1Affine = G1Affine::new_unchecked(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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ use ark_ff::{Field, MontFp, Zero};
|
|||||||
|
|
||||||
use crate::{Fq, Fq2, Fr};
|
use crate::{Fq, Fq2, Fr};
|
||||||
|
|
||||||
pub type G2Affine = Affine<Config>;
|
pub type G2Affine = Affine<Parameters>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Config;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Config {
|
impl CurveConfig for Parameters {
|
||||||
type BaseField = Fq2;
|
type BaseField = Fq2;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ impl CurveConfig for Config {
|
|||||||
MontFp!("10944121435919637613327163357776759465618812564592884533313067514031822496649");
|
MontFp!("10944121435919637613327163357776759465618812564592884533313067514031822496649");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Config {
|
impl SWCurveConfig for Parameters {
|
||||||
/// COEFF_A = [0, 0]
|
/// COEFF_A = [0, 0]
|
||||||
const COEFF_A: Fq2 = Fq2::ZERO;
|
const COEFF_A: Fq2 = Fq2::ZERO;
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ impl SWCurveConfig for Config {
|
|||||||
const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
const GENERATOR: G2Affine = G2Affine::new_unchecked(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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bn,
|
bn,
|
||||||
bn::{Bn, BnConfig, TwistType},
|
bn::{Bn, BnParameters, TwistType},
|
||||||
};
|
};
|
||||||
use ark_ff::MontFp;
|
use ark_ff::MontFp;
|
||||||
|
|
||||||
@@ -12,9 +12,9 @@ pub mod g2;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
pub struct Config;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl BnConfig for Config {
|
impl BnParameters for Parameters {
|
||||||
const X: &'static [u64] = &[4965661367192848881];
|
const X: &'static [u64] = &[4965661367192848881];
|
||||||
/// `x` is positive.
|
/// `x` is positive.
|
||||||
const X_IS_NEGATIVE: bool = false;
|
const X_IS_NEGATIVE: bool = false;
|
||||||
@@ -37,13 +37,13 @@ impl BnConfig for Config {
|
|||||||
type Fp2Config = Fq2Config;
|
type Fp2Config = Fq2Config;
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Config = Fq6Config;
|
||||||
type Fp12Config = Fq12Config;
|
type Fp12Config = Fq12Config;
|
||||||
type G1Config = g1::Config;
|
type G1Parameters = g1::Parameters;
|
||||||
type G2Config = g2::Config;
|
type G2Parameters = g2::Parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Bn254 = Bn<Config>;
|
pub type Bn254 = Bn<Parameters>;
|
||||||
|
|
||||||
pub type G1Affine = bn::G1Affine<Config>;
|
pub type G1Affine = bn::G1Affine<Parameters>;
|
||||||
pub type G1Projective = bn::G1Projective<Config>;
|
pub type G1Projective = bn::G1Projective<Parameters>;
|
||||||
pub type G2Affine = bn::G2Affine<Config>;
|
pub type G2Affine = bn::G2Affine<Parameters>;
|
||||||
pub type G2Projective = bn::G2Projective<Config>;
|
pub type G2Projective = bn::G2Projective<Parameters>;
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
use ark_algebra_test_templates::*;
|
use ark_algebra_test_templates::{
|
||||||
use ark_ff::fields::Field;
|
curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, msm::*,
|
||||||
|
};
|
||||||
|
use ark_ec::{AffineCurve, PairingEngine};
|
||||||
|
use ark_ff::{
|
||||||
|
fields::{Field, PrimeField},
|
||||||
|
One,
|
||||||
|
};
|
||||||
|
use ark_std::{rand::Rng, test_rng};
|
||||||
|
use core::ops::MulAssign;
|
||||||
|
|
||||||
use crate::{Bn254, G1Projective, G2Projective};
|
use crate::{g1, g2, Bn254, Fq12, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
|
||||||
|
|
||||||
test_group!(g1; G1Projective; sw);
|
generate_g1_test!(bn254; curve_tests; sw_tests;);
|
||||||
test_group!(g2; G2Projective; sw);
|
generate_g2_test!(bn254; curve_tests; sw_tests;);
|
||||||
test_group!(pairing_output; ark_ec::pairing::PairingOutput<Bn254>; msm);
|
generate_bilinearity_test!(Bn254, Fq12);
|
||||||
test_pairing!(pairing; crate::Bn254);
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ impl Fp2Config for Fq2Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,16 +90,12 @@ impl Fp6Config for Fq6Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[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 + Fq2Config::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);
|
Fq2::new(c0, c1)
|
||||||
fe
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
use ark_algebra_test_templates::*;
|
use ark_algebra_test_templates::{
|
||||||
|
fields::*, generate_field_serialization_test, generate_field_test,
|
||||||
|
};
|
||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
biginteger::{BigInt, BigInteger, BigInteger256},
|
biginteger::{BigInt, BigInteger, BigInteger256},
|
||||||
fields::{FftField, Field, Fp6Config, PrimeField},
|
fields::{FftField, Field, Fp6Config, PrimeField},
|
||||||
One, UniformRand, Zero,
|
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},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Config, Fr};
|
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Config, FqConfig, Fr, FrConfig};
|
||||||
|
|
||||||
test_field!(fr; Fr; mont_prime_field);
|
generate_field_test!(bn254; fq2; fq6; fq12; mont(4, 4); );
|
||||||
test_field!(fq; Fq; mont_prime_field);
|
generate_field_serialization_test!(bn254; fq2; fq6; fq12;);
|
||||||
test_field!(fq2; Fq2);
|
|
||||||
test_field!(fq6; Fq6);
|
|
||||||
test_field!(fq12; Fq12);
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_from() {
|
fn test_fq_repr_from() {
|
||||||
@@ -139,7 +140,7 @@ fn test_fq2_legendre() {
|
|||||||
// i^2 = -1
|
// i^2 = -1
|
||||||
let mut m1 = -Fq2::one();
|
let mut m1 = -Fq2::one();
|
||||||
assert_eq!(QuadraticResidue, m1.legendre());
|
assert_eq!(QuadraticResidue, m1.legendre());
|
||||||
Fq6Config::mul_fp2_by_nonresidue_in_place(&mut m1);
|
m1 = Fq6Config::mul_fp2_by_nonresidue(&m1);
|
||||||
assert_eq!(QuadraticNonResidue, m1.legendre());
|
assert_eq!(QuadraticNonResidue, m1.legendre());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-bw6-761"
|
name = "ark-bw6-761"
|
||||||
version = "0.4.0-alpha.2"
|
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,
|
|
||||||
);
|
|
||||||
@@ -6,13 +6,13 @@ use ark_ff::{Field, MontFp};
|
|||||||
|
|
||||||
use crate::{Fq, Fr};
|
use crate::{Fq, Fr};
|
||||||
|
|
||||||
pub type G1Affine = Affine<Config>;
|
pub type G1Affine = Affine<Parameters>;
|
||||||
pub type G1Projective = Projective<Config>;
|
pub type G1Projective = Projective<Parameters>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Config;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Config {
|
impl CurveConfig for Parameters {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ impl CurveConfig for Config {
|
|||||||
const COFACTOR_INV: Fr = MontFp!("91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804");
|
const COFACTOR_INV: Fr = MontFp!("91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Config {
|
impl SWCurveConfig for Parameters {
|
||||||
/// COEFF_A = 0
|
/// COEFF_A = 0
|
||||||
const COEFF_A: Fq = Fq::ZERO;
|
const COEFF_A: Fq = Fq::ZERO;
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ impl SWCurveConfig for Config {
|
|||||||
/// 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 GENERATOR: G1Affine = G1Affine::new_unchecked(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()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ use ark_ff::{Field, MontFp};
|
|||||||
|
|
||||||
use crate::{Fq, Fr};
|
use crate::{Fq, Fr};
|
||||||
|
|
||||||
pub type G2Affine = Affine<Config>;
|
pub type G2Affine = Affine<Parameters>;
|
||||||
pub type G2Projective = Projective<Config>;
|
pub type G2Projective = Projective<Parameters>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Config;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Config {
|
impl CurveConfig for Parameters {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ impl CurveConfig for Config {
|
|||||||
const COFACTOR_INV: Fr = MontFp!("214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124");
|
const COFACTOR_INV: Fr = MontFp!("214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Config {
|
impl SWCurveConfig for Parameters {
|
||||||
/// COEFF_A = 0
|
/// COEFF_A = 0
|
||||||
const COEFF_A: Fq = Fq::ZERO;
|
const COEFF_A: Fq = Fq::ZERO;
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ impl SWCurveConfig for Config {
|
|||||||
const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
const GENERATOR: G2Affine = G2Affine::new_unchecked(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()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bw6,
|
bw6,
|
||||||
bw6::{BW6Config, TwistType, BW6},
|
bw6::{BW6Parameters, TwistType, BW6},
|
||||||
};
|
};
|
||||||
use ark_ff::{biginteger::BigInteger768 as BigInteger, BigInt};
|
use ark_ff::{biginteger::BigInteger768 as BigInteger, BigInt};
|
||||||
|
|
||||||
@@ -13,9 +13,9 @@ pub mod g2;
|
|||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
pub struct Config;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl BW6Config for Config {
|
impl BW6Parameters for Parameters {
|
||||||
const X: BigInteger = BigInt::new([
|
const X: BigInteger = BigInt::new([
|
||||||
0x8508c00000000001,
|
0x8508c00000000001,
|
||||||
0x0,
|
0x0,
|
||||||
@@ -50,13 +50,13 @@ impl BW6Config for Config {
|
|||||||
type Fp = Fq;
|
type Fp = Fq;
|
||||||
type Fp3Config = Fq3Config;
|
type Fp3Config = Fq3Config;
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Config = Fq6Config;
|
||||||
type G1Config = g1::Config;
|
type G1Parameters = g1::Parameters;
|
||||||
type G2Config = g2::Config;
|
type G2Parameters = g2::Parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type BW6_761 = BW6<Config>;
|
pub type BW6_761 = BW6<Parameters>;
|
||||||
|
|
||||||
pub type G1Affine = bw6::G1Affine<Config>;
|
pub type G1Affine = bw6::G1Affine<Parameters>;
|
||||||
pub type G1Projective = bw6::G1Projective<Config>;
|
pub type G1Projective = bw6::G1Projective<Parameters>;
|
||||||
pub type G2Affine = bw6::G2Affine<Config>;
|
pub type G2Affine = bw6::G2Affine<Parameters>;
|
||||||
pub type G2Projective = bw6::G2Projective<Config>;
|
pub type G2Projective = bw6::G2Projective<Parameters>;
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
use crate::*;
|
use ark_algebra_test_templates::{
|
||||||
use ark_algebra_test_templates::*;
|
curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, msm::*,
|
||||||
use ark_ff::Field;
|
};
|
||||||
|
use ark_ec::{AffineCurve, PairingEngine};
|
||||||
|
use ark_ff::{Field, One, PrimeField};
|
||||||
|
use ark_std::{rand::Rng, test_rng};
|
||||||
|
use core::ops::MulAssign;
|
||||||
|
|
||||||
test_group!(g1; G1Projective; sw);
|
use crate::*;
|
||||||
test_group!(g2; G2Projective; sw);
|
|
||||||
test_group!(pairing_output; ark_ec::pairing::PairingOutput<BW6_761>; msm);
|
generate_g1_test!(bw6_761; curve_tests; sw_tests;);
|
||||||
test_pairing!(pairing; crate::BW6_761);
|
generate_g2_test!(bw6_761; curve_tests; sw_tests;);
|
||||||
|
generate_bilinearity_test!(BW6_761, Fq6);
|
||||||
|
|||||||
@@ -82,7 +82,9 @@ impl Fp3Config for Fq3Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[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,7 +1,12 @@
|
|||||||
use crate::*;
|
use ark_algebra_test_templates::{
|
||||||
use ark_algebra_test_templates::*;
|
fields::*, generate_field_serialization_test, generate_field_test,
|
||||||
|
};
|
||||||
|
use ark_ff::{Field, One, PrimeField, UniformRand, Zero};
|
||||||
|
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
||||||
|
use ark_std::{rand::Rng, test_rng};
|
||||||
|
use core::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
test_field!(fr; Fr; mont_prime_field);
|
use crate::*;
|
||||||
test_field!(fq; Fq; mont_prime_field);
|
|
||||||
test_field!(fq3; Fq3);
|
generate_field_test!(bw6_761; fq3; fq6_2_on_3; false; mont(12, 6); );
|
||||||
test_field!(fq6; Fq6);
|
generate_field_serialization_test!(bw6_761;);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-cp6-782"
|
name = "ark-cp6-782"
|
||||||
version = "0.4.0-alpha.2"
|
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,60 +1,18 @@
|
|||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
models::{short_weierstrass::SWCurveConfig, CurveConfig},
|
models::{short_weierstrass::SWCurveConfig, CurveConfig},
|
||||||
short_weierstrass::{Affine, Projective},
|
short_weierstrass::{Affine, Projective},
|
||||||
AffineRepr, CurveGroup,
|
|
||||||
};
|
};
|
||||||
use ark_ff::MontFp;
|
use ark_ff::MontFp;
|
||||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
|
||||||
use ark_std::vec::Vec;
|
|
||||||
|
|
||||||
use crate::{Fq, Fr};
|
use crate::{Fq, Fr};
|
||||||
|
|
||||||
pub type G1Affine = Affine<Config>;
|
pub type G1Affine = Affine<Parameters>;
|
||||||
pub type G1Projective = Projective<Config>;
|
pub type G1Projective = Projective<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 Config;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Config {
|
impl CurveConfig for Parameters {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -76,7 +34,7 @@ impl CurveConfig for Config {
|
|||||||
const COFACTOR_INV: Fr = MontFp!("163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788");
|
const COFACTOR_INV: Fr = MontFp!("163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Config {
|
impl SWCurveConfig for Parameters {
|
||||||
/// COEFF_A = 5
|
/// COEFF_A = 5
|
||||||
const COEFF_A: Fq = MontFp!("5");
|
const COEFF_A: Fq = MontFp!("5");
|
||||||
|
|
||||||
|
|||||||
@@ -1,60 +1,18 @@
|
|||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
models::CurveConfig,
|
models::CurveConfig,
|
||||||
short_weierstrass::{Affine, Projective, SWCurveConfig},
|
short_weierstrass::{Affine, Projective, SWCurveConfig},
|
||||||
AffineRepr, CurveGroup,
|
|
||||||
};
|
};
|
||||||
use ark_ff::{Field, MontFp};
|
use ark_ff::{Field, MontFp};
|
||||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
|
||||||
use ark_std::vec::Vec;
|
|
||||||
|
|
||||||
use crate::{Fq, Fq3, Fr};
|
use crate::{Fq, Fq3, Fr};
|
||||||
|
|
||||||
pub type G2Affine = Affine<Config>;
|
pub type G2Affine = Affine<Parameters>;
|
||||||
pub type G2Projective = Projective<Config>;
|
pub type G2Projective = Projective<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 Config;
|
pub struct Parameters;
|
||||||
|
|
||||||
impl CurveConfig for Config {
|
impl CurveConfig for Parameters {
|
||||||
type BaseField = Fq3;
|
type BaseField = Fq3;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -100,7 +58,7 @@ impl CurveConfig for Config {
|
|||||||
const COFACTOR_INV: Fr = MontFp!("45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598");
|
const COFACTOR_INV: Fr = MontFp!("45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Config {
|
impl SWCurveConfig for Parameters {
|
||||||
/// COEFF_A = (0, 0, COEFF_A * TWIST^2) = (0, 0, 5)
|
/// COEFF_A = (0, 0, COEFF_A * TWIST^2) = (0, 0, 5)
|
||||||
const COEFF_A: Fq3 = Fq3::new(Fq::ZERO, Fq::ZERO, MontFp!("5"));
|
const COEFF_A: Fq3 = Fq3::new(Fq::ZERO, Fq::ZERO, MontFp!("5"));
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
use ark_ec::{
|
use ark_ec::{models::short_weierstrass::SWCurveConfig, PairingEngine};
|
||||||
models::short_weierstrass::SWCurveConfig,
|
|
||||||
pairing::{MillerLoopOutput, Pairing, PairingOutput},
|
|
||||||
};
|
|
||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
biginteger::BigInteger832, BigInt, BitIteratorBE, CyclotomicMultSubgroup, Field, One,
|
biginteger::BigInteger832,
|
||||||
|
fields::{BitIteratorBE, Field},
|
||||||
|
BigInt, One,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
|
||||||
|
|
||||||
use crate::{Fq, Fq3, Fq6, Fr};
|
use crate::{Fq, Fq3, Fq6, Fr};
|
||||||
|
|
||||||
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 +21,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;
|
||||||
@@ -78,7 +76,7 @@ impl CP6_782 {
|
|||||||
|
|
||||||
let old_rx_square = old_rx.square();
|
let old_rx_square = old_rx.square();
|
||||||
let old_rx_square_3 = old_rx_square.double() + &old_rx_square;
|
let old_rx_square_3 = old_rx_square.double() + &old_rx_square;
|
||||||
let old_rx_square_3_a = old_rx_square_3 + &g2::Config::COEFF_A;
|
let old_rx_square_3_a = old_rx_square_3 + &g2::Parameters::COEFF_A;
|
||||||
let old_ry_double_inverse = old_ry.double().inverse().unwrap();
|
let old_ry_double_inverse = old_ry.double().inverse().unwrap();
|
||||||
|
|
||||||
let gamma = old_rx_square_3_a * &old_ry_double_inverse;
|
let gamma = old_rx_square_3_a * &old_ry_double_inverse;
|
||||||
@@ -129,19 +127,19 @@ impl CP6_782 {
|
|||||||
|
|
||||||
// elt_q3 = elt^(q^3)
|
// elt_q3 = elt^(q^3)
|
||||||
let mut elt_q3 = elt.clone();
|
let mut elt_q3 = elt.clone();
|
||||||
elt_q3.frobenius_map_in_place(3);
|
elt_q3.frobenius_map(3);
|
||||||
// elt_q3_over_elt = elt^(q^3-1)
|
// elt_q3_over_elt = elt^(q^3-1)
|
||||||
let elt_q3_over_elt = elt_q3 * elt_inv;
|
let elt_q3_over_elt = elt_q3 * elt_inv;
|
||||||
// alpha = elt^((q^3-1) * q)
|
// alpha = elt^((q^3-1) * q)
|
||||||
let mut alpha = elt_q3_over_elt.clone();
|
let mut alpha = elt_q3_over_elt.clone();
|
||||||
alpha.frobenius_map_in_place(1);
|
alpha.frobenius_map(1);
|
||||||
// beta = elt^((q^3-1)*(q+1)
|
// beta = elt^((q^3-1)*(q+1)
|
||||||
alpha * &elt_q3_over_elt
|
alpha * &elt_q3_over_elt
|
||||||
}
|
}
|
||||||
|
|
||||||
fn final_exponentiation_last(elt: &Fq6, elt_inv: &Fq6) -> Fq6 {
|
fn final_exponentiation_last(elt: &Fq6, elt_inv: &Fq6) -> Fq6 {
|
||||||
let mut elt_q = elt.clone();
|
let mut elt_q = elt.clone();
|
||||||
elt_q.frobenius_map_in_place(1);
|
elt_q.frobenius_map(1);
|
||||||
|
|
||||||
let w1_part = elt_q.cyclotomic_exp(&FINAL_EXPONENT_LAST_CHUNK_W1);
|
let w1_part = elt_q.cyclotomic_exp(&FINAL_EXPONENT_LAST_CHUNK_W1);
|
||||||
let w0_part = if FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG {
|
let w0_part = if FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG {
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
use ark_algebra_test_templates::*;
|
use ark_algebra_test_templates::{
|
||||||
use ark_ff::Field;
|
curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, msm::*,
|
||||||
|
};
|
||||||
|
use ark_ec::{AffineCurve, PairingEngine};
|
||||||
|
use ark_ff::{Field, One, PrimeField};
|
||||||
|
use ark_std::{rand::Rng, test_rng};
|
||||||
|
use core::ops::MulAssign;
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
test_group!(g1; G1Projective; sw);
|
generate_g1_test!(cp6_782; curve_tests; sw_tests;);
|
||||||
test_group!(g2; G2Projective; sw);
|
generate_g2_test!(cp6_782; curve_tests; sw_tests;);
|
||||||
test_group!(pairing_output; ark_ec::pairing::PairingOutput<CP6_782>; msm);
|
generate_bilinearity_test!(CP6_782, Fq6);
|
||||||
test_pairing!(pairing; crate::CP6_782);
|
|
||||||
|
|||||||
@@ -77,12 +77,11 @@ impl Fp3Config for Fq3Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[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,7 +1,12 @@
|
|||||||
use crate::*;
|
use ark_algebra_test_templates::{
|
||||||
use ark_algebra_test_templates::*;
|
fields::*, generate_field_serialization_test, generate_field_test,
|
||||||
|
};
|
||||||
|
use ark_ff::{Field, One, PrimeField, UniformRand, Zero};
|
||||||
|
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
||||||
|
use ark_std::{rand::Rng, test_rng};
|
||||||
|
use core::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
test_field!(fr; Fr; mont_prime_field);
|
use crate::*;
|
||||||
test_field!(fq; Fq; mont_prime_field);
|
|
||||||
test_field!(fq3; Fq3);
|
generate_field_test!(cp6_782; fq3; fq6_2_on_3; mont(13, 6); );
|
||||||
test_field!(fq6; Fq6);
|
generate_field_serialization_test!(cp6_782;);
|
||||||
|
|||||||
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, 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, 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);
|
||||||
27
curve-benches/benches/bn254.rs
Normal file
27
curve-benches/benches/bn254.rs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
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 Repr, BigInteger, Field, PrimeField, UniformRand};
|
||||||
|
|
||||||
|
mod g1 {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G1, G1Affine);
|
||||||
|
}
|
||||||
|
mod g2 {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G2, G2Affine);
|
||||||
|
}
|
||||||
|
|
||||||
|
f_bench!(Fq, Fq, Repr, Repr, fq);
|
||||||
|
f_bench!(Fr, Fr, Repr, Repr, 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, 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, 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);
|
||||||
16
curve-benches/benches/ed_on_bls12_381.rs
Normal file
16
curve-benches/benches/ed_on_bls12_381.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
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 Repr, BigInteger, Field, PrimeField, UniformRand};
|
||||||
|
|
||||||
|
mod g {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G, GAffine);
|
||||||
|
}
|
||||||
|
|
||||||
|
f_bench!(Fq, Fq, Repr, Repr, fq);
|
||||||
|
f_bench!(Fr, Fr, Repr, Repr, fr);
|
||||||
|
|
||||||
|
bencher::benchmark_main!(fq, fr, g::group_ops);
|
||||||
26
curve-benches/benches/mnt4_298.rs
Normal file
26
curve-benches/benches/mnt4_298.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
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, 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);
|
||||||
26
curve-benches/benches/mnt4_753.rs
Normal file
26
curve-benches/benches/mnt4_753.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
use ark_curve_benches::*;
|
||||||
|
use ark_std::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
|
use ark_ec::{PairingEngine, ProjectiveCurve};
|
||||||
|
use ark_ff::{biginteger::BigInteger768 as FqRepr, BigInteger, Field, PrimeField, UniformRand};
|
||||||
|
use ark_mnt4_753::{
|
||||||
|
fq::Fq, fq2::Fq2, fr::Fr, Fq4, G1Affine, G1Projective as G1, G2Affine, G2Projective as G2,
|
||||||
|
MNT4_753,
|
||||||
|
};
|
||||||
|
|
||||||
|
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_753, Fq4);
|
||||||
|
|
||||||
|
bencher::benchmark_main!(fq, fr, fq2, fq4, g1::group_ops, g2::group_ops, pairing);
|
||||||
26
curve-benches/benches/mnt6_298.rs
Normal file
26
curve-benches/benches/mnt6_298.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
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, UniformRand};
|
||||||
|
use ark_mnt6_298::{
|
||||||
|
fq::Fq, fq3::Fq3, fr::Fr, Fq6, G1Affine, G1Projective as G1, G2Affine, G2Projective as G2,
|
||||||
|
MNT6_298,
|
||||||
|
};
|
||||||
|
|
||||||
|
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, FqRepr, FqRepr, fr);
|
||||||
|
pairing_bench!(MNT6_298, Fq6);
|
||||||
|
|
||||||
|
bencher::benchmark_main!(fq, fr, fq3, fq6, g1::group_ops, g2::group_ops, pairing);
|
||||||
26
curve-benches/benches/mnt6_753.rs
Normal file
26
curve-benches/benches/mnt6_753.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
use ark_curve_benches::*;
|
||||||
|
use ark_std::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
|
use ark_ec::{PairingEngine, ProjectiveCurve};
|
||||||
|
use ark_ff::{biginteger::BigInteger768 as FqRepr, BigInteger, Field, PrimeField, UniformRand};
|
||||||
|
use ark_mnt6_753::{
|
||||||
|
fq::Fq, fq3::Fq3, fr::Fr, Fq6, G1Affine, G1Projective as G1, G2Affine, G2Projective as G2,
|
||||||
|
MNT6_753,
|
||||||
|
};
|
||||||
|
|
||||||
|
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, FqRepr, FqRepr, fr);
|
||||||
|
pairing_bench!(MNT6_753, Fq6);
|
||||||
|
|
||||||
|
bencher::benchmark_main!(fq, fr, fq3, fq6, g1::group_ops, g2::group_ops, pairing);
|
||||||
16
curve-benches/benches/pallas.rs
Normal file
16
curve-benches/benches/pallas.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
use ark_curve_benches::*;
|
||||||
|
use ark_std::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
|
use ark_ec::ProjectiveCurve;
|
||||||
|
use ark_ff::{biginteger::BigInteger256 as Repr, BigInteger, Field, PrimeField, UniformRand};
|
||||||
|
use ark_pallas::{fq::Fq, fr::Fr, Affine as GAffine, Projective as G};
|
||||||
|
|
||||||
|
mod g {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G, GAffine);
|
||||||
|
}
|
||||||
|
|
||||||
|
f_bench!(Fq, Fq, Repr, Repr, fq);
|
||||||
|
f_bench!(Fr, Fr, Repr, Repr, fr);
|
||||||
|
|
||||||
|
bencher::benchmark_main!(fq, fr, g::group_ops);
|
||||||
16
curve-benches/benches/vesta.rs
Normal file
16
curve-benches/benches/vesta.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
use ark_curve_benches::*;
|
||||||
|
use ark_std::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
|
use ark_ec::ProjectiveCurve;
|
||||||
|
use ark_ff::{biginteger::BigInteger256 as Repr, BigInteger, Field, PrimeField, UniformRand};
|
||||||
|
use ark_vesta::{fq::Fq, fr::Fr, Affine as GAffine, Projective as G};
|
||||||
|
|
||||||
|
mod g {
|
||||||
|
use super::*;
|
||||||
|
ec_bench!(G, GAffine);
|
||||||
|
}
|
||||||
|
|
||||||
|
f_bench!(Fq, Fq, Repr, Repr, fq);
|
||||||
|
f_bench!(Fr, Fr, Repr, Repr, fr);
|
||||||
|
|
||||||
|
bencher::benchmark_main!(fq, fr, g::group_ops);
|
||||||
9
curve-benches/build.rs
Normal file
9
curve-benches/build.rs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
extern crate rustc_version;
|
||||||
|
|
||||||
|
use rustc_version::{version_meta, Channel};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
if version_meta().expect("nightly check failed").channel == Channel::Nightly {
|
||||||
|
println!("cargo:rustc-cfg=nightly");
|
||||||
|
}
|
||||||
|
}
|
||||||
8
curve-benches/src/lib.rs
Normal file
8
curve-benches/src/lib.rs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#![allow(unused_macros, unused_imports)]
|
||||||
|
#[macro_use]
|
||||||
|
pub mod macros;
|
||||||
|
pub use macros::*;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
pub extern crate bencher;
|
||||||
|
pub use bencher::*;
|
||||||
258
curve-benches/src/macros/ec.rs
Normal file
258
curve-benches/src/macros/ec.rs
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
#[macro_export]
|
||||||
|
macro_rules! ec_bench {
|
||||||
|
($projective:ty, $affine:ty) => {
|
||||||
|
fn rand(b: &mut $crate::bencher::Bencher) {
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
b.iter(|| <$projective>::rand(&mut rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mul_assign(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<($projective, Fr)> = (0..SAMPLES)
|
||||||
|
.map(|_| (<$projective>::rand(&mut rng), Fr::rand(&mut rng)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count].0;
|
||||||
|
tmp *= v[count].1;
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_assign(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<($projective, $projective)> = (0..SAMPLES)
|
||||||
|
.map(|_| (<$projective>::rand(&mut rng), <$projective>::rand(&mut rng)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count].0;
|
||||||
|
n_fold!(tmp, v, add_assign, count);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sub_assign(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<($projective, $projective)> = (0..SAMPLES)
|
||||||
|
.map(|_| (<$projective>::rand(&mut rng), <$projective>::rand(&mut rng)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count].0;
|
||||||
|
n_fold!(tmp, v, sub_assign, count);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn double(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<$projective> = (0..SAMPLES)
|
||||||
|
.map(|_| <$projective>::rand(&mut rng))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count];
|
||||||
|
n_fold!(tmp, double_in_place);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_assign_mixed(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<($projective, $affine)> = (0..SAMPLES)
|
||||||
|
.map(|_| {
|
||||||
|
(
|
||||||
|
<$projective>::rand(&mut rng),
|
||||||
|
<$projective>::rand(&mut rng).into(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count].0;
|
||||||
|
n_fold!(tmp, v, add_assign_mixed, count);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deser(b: &mut $crate::bencher::Bencher) {
|
||||||
|
use ark_ec::ProjectiveCurve;
|
||||||
|
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let mut num_bytes = 0;
|
||||||
|
let tmp = <$projective>::rand(&mut rng).into_affine();
|
||||||
|
let v: Vec<_> = (0..SAMPLES)
|
||||||
|
.flat_map(|_| {
|
||||||
|
let mut bytes = Vec::with_capacity(1000);
|
||||||
|
tmp.serialize(&mut bytes).unwrap();
|
||||||
|
num_bytes = bytes.len();
|
||||||
|
bytes
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
let index = count * num_bytes;
|
||||||
|
<$affine>::deserialize(&v[index..(index + num_bytes)]).unwrap()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ser(b: &mut $crate::bencher::Bencher) {
|
||||||
|
use ark_ec::ProjectiveCurve;
|
||||||
|
use ark_serialize::CanonicalSerialize;
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let mut v: Vec<_> = (0..SAMPLES)
|
||||||
|
.map(|_| <$projective>::rand(&mut rng))
|
||||||
|
.collect();
|
||||||
|
let v = <$projective>::batch_normalization_into_affine(v.as_mut_slice());
|
||||||
|
let mut bytes = Vec::with_capacity(1000);
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let tmp = v[count];
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
bytes.clear();
|
||||||
|
tmp.serialize(&mut bytes)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deser_unchecked(b: &mut $crate::bencher::Bencher) {
|
||||||
|
use ark_ec::ProjectiveCurve;
|
||||||
|
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let mut num_bytes = 0;
|
||||||
|
let tmp = <$projective>::rand(&mut rng).into_affine();
|
||||||
|
let v: Vec<_> = (0..SAMPLES)
|
||||||
|
.flat_map(|_| {
|
||||||
|
let mut bytes = Vec::with_capacity(1000);
|
||||||
|
tmp.serialize_unchecked(&mut bytes).unwrap();
|
||||||
|
num_bytes = bytes.len();
|
||||||
|
bytes
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
let index = count * num_bytes;
|
||||||
|
<$affine>::deserialize_unchecked(&v[index..(index + num_bytes)]).unwrap()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ser_unchecked(b: &mut $crate::bencher::Bencher) {
|
||||||
|
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let mut v: Vec<_> = (0..SAMPLES)
|
||||||
|
.map(|_| <$projective>::rand(&mut rng))
|
||||||
|
.collect();
|
||||||
|
let v = <$projective>::batch_normalization_into_affine(v.as_mut_slice());
|
||||||
|
let mut bytes = Vec::with_capacity(1000);
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let tmp = v[count];
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
bytes.clear();
|
||||||
|
tmp.serialize_unchecked(&mut bytes)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deser_uncompressed(b: &mut $crate::bencher::Bencher) {
|
||||||
|
use ark_ec::ProjectiveCurve;
|
||||||
|
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let mut num_bytes = 0;
|
||||||
|
let tmp = <$projective>::rand(&mut rng).into_affine();
|
||||||
|
let v: Vec<_> = (0..SAMPLES)
|
||||||
|
.flat_map(|_| {
|
||||||
|
let mut bytes = Vec::with_capacity(1000);
|
||||||
|
tmp.serialize_uncompressed(&mut bytes).unwrap();
|
||||||
|
num_bytes = bytes.len();
|
||||||
|
bytes
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
let index = count * num_bytes;
|
||||||
|
<$affine>::deserialize_uncompressed(&v[index..(index + num_bytes)]).unwrap()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn msm_131072(b: &mut $crate::bencher::Bencher) {
|
||||||
|
use ark_ec::msm::VariableBaseMSM;
|
||||||
|
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||||
|
const SAMPLES: usize = 131072;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let g = <$projective>::rand(&mut rng).into_affine();
|
||||||
|
let v: Vec<_> = (0..SAMPLES).map(|_| g).collect();
|
||||||
|
let scalars: Vec<_> = (0..SAMPLES)
|
||||||
|
.map(|_| Fr::rand(&mut rng).into_bigint())
|
||||||
|
.collect();
|
||||||
|
b.bench_n(1, |b| {
|
||||||
|
b.iter(|| <$projective as VariableBaseMSM>::msm_bigint(&v, &scalars));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
$crate::benchmark_group!(
|
||||||
|
group_ops,
|
||||||
|
rand,
|
||||||
|
mul_assign,
|
||||||
|
add_assign,
|
||||||
|
sub_assign,
|
||||||
|
add_assign_mixed,
|
||||||
|
double,
|
||||||
|
ser,
|
||||||
|
deser,
|
||||||
|
ser_unchecked,
|
||||||
|
deser_unchecked,
|
||||||
|
deser_uncompressed,
|
||||||
|
msm_131072,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
455
curve-benches/src/macros/field.rs
Normal file
455
curve-benches/src/macros/field.rs
Normal file
@@ -0,0 +1,455 @@
|
|||||||
|
#[macro_export]
|
||||||
|
macro_rules! f_bench {
|
||||||
|
// Use this for base fields
|
||||||
|
($f:ident, $f_type:ty, $f_repr:ident, $f_repr_type:ty, $modname:ident) => {
|
||||||
|
pub mod $modname {
|
||||||
|
use super::*;
|
||||||
|
field_common!($f, $f_type);
|
||||||
|
sqrt!($f, $f_type);
|
||||||
|
prime_field!($f, $f_type, $f_repr, $f_repr_type);
|
||||||
|
$crate::benchmark_group!(
|
||||||
|
$modname,
|
||||||
|
// common stuff
|
||||||
|
add_assign,
|
||||||
|
sub_assign,
|
||||||
|
double,
|
||||||
|
negate,
|
||||||
|
mul_assign,
|
||||||
|
square,
|
||||||
|
inverse,
|
||||||
|
ser,
|
||||||
|
deser,
|
||||||
|
ser_unchecked,
|
||||||
|
deser_unchecked,
|
||||||
|
// sqrt field stuff
|
||||||
|
sqrt,
|
||||||
|
// prime field stuff
|
||||||
|
repr_add_nocarry,
|
||||||
|
repr_sub_noborrow,
|
||||||
|
repr_num_bits,
|
||||||
|
repr_mul2,
|
||||||
|
repr_div2,
|
||||||
|
into_repr,
|
||||||
|
from_repr,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
use $modname::$modname;
|
||||||
|
};
|
||||||
|
// use this for intermediate fields
|
||||||
|
(extension, $f:ident, $f_type:ty, $modname:ident) => {
|
||||||
|
mod $modname {
|
||||||
|
use super::*;
|
||||||
|
field_common!($f, $f_type);
|
||||||
|
sqrt!($f, $f_type);
|
||||||
|
$crate::benchmark_group!(
|
||||||
|
$modname,
|
||||||
|
// common stuff
|
||||||
|
add_assign,
|
||||||
|
sub_assign,
|
||||||
|
double,
|
||||||
|
negate,
|
||||||
|
mul_assign,
|
||||||
|
square,
|
||||||
|
inverse,
|
||||||
|
ser,
|
||||||
|
deser,
|
||||||
|
ser_unchecked,
|
||||||
|
deser_unchecked,
|
||||||
|
// sqrt field stuff
|
||||||
|
sqrt,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
use $modname::$modname;
|
||||||
|
};
|
||||||
|
// Use this for the full extension field Fqk
|
||||||
|
(target, $f:ident, $f_type:ty, $modname:ident) => {
|
||||||
|
mod $modname {
|
||||||
|
use super::*;
|
||||||
|
field_common!($f, $f_type);
|
||||||
|
$crate::benchmark_group!(
|
||||||
|
$modname,
|
||||||
|
// common stuff
|
||||||
|
add_assign,
|
||||||
|
sub_assign,
|
||||||
|
double,
|
||||||
|
negate,
|
||||||
|
mul_assign,
|
||||||
|
square,
|
||||||
|
inverse,
|
||||||
|
ser,
|
||||||
|
deser,
|
||||||
|
ser_unchecked,
|
||||||
|
deser_unchecked,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
use $modname::$modname;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! field_common {
|
||||||
|
($f:ident, $f_type:ty) => {
|
||||||
|
fn add_assign(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<_> = (0..SAMPLES)
|
||||||
|
.map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count].0;
|
||||||
|
n_fold!(tmp, v, add_assign, count);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sub_assign(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<_> = (0..SAMPLES)
|
||||||
|
.map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count].0;
|
||||||
|
n_fold!(tmp, v, sub_assign, count);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn double(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count];
|
||||||
|
n_fold!(tmp, double_in_place);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn negate(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count];
|
||||||
|
tmp = -tmp;
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mul_assign(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<_> = (0..SAMPLES)
|
||||||
|
.map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count].0;
|
||||||
|
n_fold!(tmp, v, mul_assign, count);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn square(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count];
|
||||||
|
n_fold!(tmp, square_in_place);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inverse(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let tmp = v[count].inverse();
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deser(b: &mut $crate::bencher::Bencher) {
|
||||||
|
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let mut num_bytes = 0;
|
||||||
|
let v: Vec<_> = (0..SAMPLES)
|
||||||
|
.flat_map(|_| {
|
||||||
|
let mut bytes = Vec::with_capacity(1000);
|
||||||
|
let tmp = $f::rand(&mut rng);
|
||||||
|
tmp.serialize(&mut bytes).unwrap();
|
||||||
|
num_bytes = bytes.len();
|
||||||
|
bytes
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
let index = count * num_bytes;
|
||||||
|
<$f_type>::deserialize(&v[index..(index + num_bytes)]).unwrap()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ser(b: &mut $crate::bencher::Bencher) {
|
||||||
|
use ark_serialize::CanonicalSerialize;
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
||||||
|
let mut bytes = Vec::with_capacity(1000);
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let tmp = v[count];
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
bytes.clear();
|
||||||
|
tmp.serialize(&mut bytes)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deser_unchecked(b: &mut $crate::bencher::Bencher) {
|
||||||
|
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let mut num_bytes = 0;
|
||||||
|
let v: Vec<_> = (0..SAMPLES)
|
||||||
|
.flat_map(|_| {
|
||||||
|
let mut bytes = Vec::with_capacity(1000);
|
||||||
|
let tmp = $f::rand(&mut rng);
|
||||||
|
tmp.serialize_unchecked(&mut bytes).unwrap();
|
||||||
|
num_bytes = bytes.len();
|
||||||
|
bytes
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
let index = count * num_bytes;
|
||||||
|
<$f_type>::deserialize_unchecked(&v[index..(index + num_bytes)]).unwrap()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ser_unchecked(b: &mut $crate::bencher::Bencher) {
|
||||||
|
use ark_serialize::CanonicalSerialize;
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
||||||
|
let mut bytes = Vec::with_capacity(1000);
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let tmp = v[count];
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
bytes.clear();
|
||||||
|
tmp.serialize_unchecked(&mut bytes)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! sqrt {
|
||||||
|
($f:ident, $f_type:ty) => {
|
||||||
|
pub fn sqrt(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<$f_type> = (0..SAMPLES)
|
||||||
|
.map(|_| {
|
||||||
|
let mut tmp = $f::rand(&mut rng);
|
||||||
|
tmp.square_in_place();
|
||||||
|
tmp
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
v[count].sqrt()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! prime_field {
|
||||||
|
($f:ident, $f_type:ty, $f_repr:ident, $f_repr_type:ty) => {
|
||||||
|
fn repr_add_nocarry(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<_> = (0..SAMPLES)
|
||||||
|
.map(|_| {
|
||||||
|
let mut tmp1 = $f_repr::rand(&mut rng);
|
||||||
|
let mut tmp2 = $f_repr::rand(&mut rng);
|
||||||
|
// Shave a few bits off to avoid overflow.
|
||||||
|
for _ in 0..3 {
|
||||||
|
tmp1.div2();
|
||||||
|
tmp2.div2();
|
||||||
|
}
|
||||||
|
(tmp1, tmp2)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count].0;
|
||||||
|
n_fold!(tmp, v, add_with_carry, count);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn repr_sub_noborrow(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<_> = (0..SAMPLES)
|
||||||
|
.map(|_| {
|
||||||
|
let tmp1 = $f_repr::rand(&mut rng);
|
||||||
|
let mut tmp2 = tmp1;
|
||||||
|
// Ensure tmp2 is smaller than tmp1.
|
||||||
|
for _ in 0..10 {
|
||||||
|
tmp2.div2();
|
||||||
|
}
|
||||||
|
(tmp1, tmp2)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count].0;
|
||||||
|
n_fold!(tmp, v, sub_with_borrow, count);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn repr_num_bits(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let tmp = v[count].num_bits();
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn repr_mul2(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count];
|
||||||
|
n_fold!(tmp, mul2);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn repr_div2(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let mut tmp = v[count];
|
||||||
|
n_fold!(tmp, div2);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_repr(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
v[count].into_bigint();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_repr(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<$f_repr_type> = (0..SAMPLES)
|
||||||
|
.map(|_| $f::rand(&mut rng).into_bigint())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
let _ = $f::from(v[count]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
11
curve-benches/src/macros/mod.rs
Normal file
11
curve-benches/src/macros/mod.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#[macro_use]
|
||||||
|
mod utils;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
mod ec;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
mod field;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
mod pairing;
|
||||||
72
curve-benches/src/macros/pairing.rs
Normal file
72
curve-benches/src/macros/pairing.rs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#[macro_export]
|
||||||
|
macro_rules! pairing_bench {
|
||||||
|
($curve:ident, $pairing_field:ident) => {
|
||||||
|
fn miller_loop(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let g1s = (0..SAMPLES).map(|_| G1::rand(&mut rng)).collect::<Vec<_>>();
|
||||||
|
let g2s = (0..SAMPLES).map(|_| G2::rand(&mut rng)).collect::<Vec<_>>();
|
||||||
|
let g1s = G1::batch_normalization_into_affine(&g1s);
|
||||||
|
let g2s = G2::batch_normalization_into_affine(&g2s);
|
||||||
|
let prepared = g1s
|
||||||
|
.into_iter()
|
||||||
|
.zip(g2s)
|
||||||
|
.map(|(g1, g2)| (g1.into(), g2.into()))
|
||||||
|
.collect::<Vec<(
|
||||||
|
<$curve as PairingEngine>::G1Prepared,
|
||||||
|
<$curve as PairingEngine>::G2Prepared,
|
||||||
|
)>>();
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let tmp =
|
||||||
|
$curve::miller_loop(&[(prepared[count].0.clone(), prepared[count].1.clone())]);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn final_exponentiation(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<_> = (0..SAMPLES)
|
||||||
|
.map(|_| {
|
||||||
|
(
|
||||||
|
G1Affine::from(G1::rand(&mut rng)).into(),
|
||||||
|
G2Affine::from(G2::rand(&mut rng)).into(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.map(|(p, q)| $curve::miller_loop(&[(p, q)]))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let tmp = $curve::final_exponentiation(&v[count]);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn full_pairing(b: &mut $crate::bencher::Bencher) {
|
||||||
|
const SAMPLES: usize = 1000;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
|
let v: Vec<(G1, G2)> = (0..SAMPLES)
|
||||||
|
.map(|_| (G1::rand(&mut rng), G2::rand(&mut rng)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
let tmp = $curve::pairing(v[count].0, v[count].1);
|
||||||
|
count = (count + 1) % SAMPLES;
|
||||||
|
tmp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$crate::benchmark_group!(pairing, miller_loop, final_exponentiation, full_pairing,);
|
||||||
|
};
|
||||||
|
}
|
||||||
36
curve-benches/src/macros/utils.rs
Normal file
36
curve-benches/src/macros/utils.rs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#[macro_export]
|
||||||
|
macro_rules! n_fold {
|
||||||
|
($tmp:ident, $v:ident, $func:ident, $count:ident) => {
|
||||||
|
$tmp.$func(&$v[$count].1);
|
||||||
|
};
|
||||||
|
|
||||||
|
($tmp:ident, $func:ident) => {
|
||||||
|
$tmp.$func();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defines a function called `$group_name` that returns the test description
|
||||||
|
/// values for the listed functions `$function`.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! benchmark_group {
|
||||||
|
($group_name:ident, $($function:path),+) => {
|
||||||
|
pub fn $group_name() -> ::std::vec::Vec<$crate::TestDescAndFn> {
|
||||||
|
use $crate::{TestDescAndFn, TestFn, TestDesc};
|
||||||
|
use std::borrow::Cow;
|
||||||
|
let mut benches = ::std::vec::Vec::new();
|
||||||
|
$(
|
||||||
|
benches.push(TestDescAndFn {
|
||||||
|
desc: TestDesc {
|
||||||
|
name: Cow::from(module_path!().to_string() + "::" + stringify!($function)),
|
||||||
|
ignore: false,
|
||||||
|
},
|
||||||
|
testfn: TestFn::StaticBenchFn($function),
|
||||||
|
});
|
||||||
|
)+
|
||||||
|
benches
|
||||||
|
}
|
||||||
|
};
|
||||||
|
($group_name:ident, $($function:path,)+) => {
|
||||||
|
benchmark_group!($group_name, $($function),+);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-curve-constraint-tests"
|
name = "ark-curve-constraint-tests"
|
||||||
version = "0.4.0-alpha.2"
|
version = "0.3.0"
|
||||||
authors = [ "arkworks contributors" ]
|
authors = [ "arkworks contributors" ]
|
||||||
description = "A library for testing constraints for finite fields, elliptic curves, and pairings"
|
description = "A library for testing constraints for finite fields, elliptic curves, and pairings"
|
||||||
homepage = "https://arkworks.rs"
|
homepage = "https://arkworks.rs"
|
||||||
@@ -10,15 +10,15 @@ keywords = ["cryptography", "finite-fields", "elliptic-curves", "r1cs" ]
|
|||||||
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-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 }
|
ark-serialize = { version = "^0.3.0", default-features = false }
|
||||||
ark-ff = { version = "0.4.0-alpha", default-features = false }
|
ark-ff = { version = "^0.3.0", default-features = false }
|
||||||
ark-relations = { version = "0.4.0-alpha", default-features = false }
|
ark-relations = { version = "^0.3.0", default-features = false }
|
||||||
ark-r1cs-std = { version = "0.4.0-alpha", default-features = false }
|
ark-r1cs-std = { 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 }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
../LICENSE-APACHE
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../LICENSE-MIT
|
|
||||||
81
curve-constraint-tests/src/lib.rs
Normal file → Executable file
81
curve-constraint-tests/src/lib.rs
Normal file → Executable file
@@ -211,7 +211,7 @@ pub mod fields {
|
|||||||
let mut a = F::rand(&mut rng);
|
let mut a = F::rand(&mut rng);
|
||||||
let mut a_gadget = AF::new_variable(ark_relations::ns!(cs, "a"), || Ok(a), mode)?;
|
let mut a_gadget = AF::new_variable(ark_relations::ns!(cs, "a"), || Ok(a), mode)?;
|
||||||
a_gadget.frobenius_map_in_place(i)?;
|
a_gadget.frobenius_map_in_place(i)?;
|
||||||
a.frobenius_map_in_place(i);
|
a.frobenius_map(i);
|
||||||
|
|
||||||
assert_eq!(a_gadget.value()?, a);
|
assert_eq!(a_gadget.value()?, a);
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,7 @@ pub mod fields {
|
|||||||
pub mod curves {
|
pub mod curves {
|
||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
short_weierstrass::Projective as SWProjective, twisted_edwards::Projective as TEProjective,
|
short_weierstrass::Projective as SWProjective, twisted_edwards::Projective as TEProjective,
|
||||||
CurveGroup, Group,
|
ProjectiveCurve,
|
||||||
};
|
};
|
||||||
use ark_ff::{BitIteratorLE, Field, One, PrimeField};
|
use ark_ff::{BitIteratorLE, Field, One, PrimeField};
|
||||||
use ark_relations::r1cs::{ConstraintSystem, SynthesisError};
|
use ark_relations::r1cs::{ConstraintSystem, SynthesisError};
|
||||||
@@ -235,7 +235,7 @@ pub mod curves {
|
|||||||
|
|
||||||
pub fn group_test<C, ConstraintF, GG>() -> Result<(), SynthesisError>
|
pub fn group_test<C, ConstraintF, GG>() -> Result<(), SynthesisError>
|
||||||
where
|
where
|
||||||
C: CurveGroup,
|
C: ProjectiveCurve,
|
||||||
ConstraintF: Field,
|
ConstraintF: Field,
|
||||||
GG: CurveVar<C, ConstraintF>,
|
GG: CurveVar<C, ConstraintF>,
|
||||||
for<'a> &'a GG: GroupOpsBounds<'a, C, GG>,
|
for<'a> &'a GG: GroupOpsBounds<'a, C, GG>,
|
||||||
@@ -321,10 +321,8 @@ pub mod curves {
|
|||||||
*limb = u64::MAX;
|
*limb = u64::MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
let modulus_num_bits_mod_64 = <C::ScalarField as PrimeField>::MODULUS_BIT_SIZE % 64;
|
let modulus_last_limb_bits = <C::ScalarField as PrimeField>::MODULUS_BIT_SIZE % 64;
|
||||||
if modulus_num_bits_mod_64 != 0 {
|
*max.last_mut().unwrap() >>= 64 - modulus_last_limb_bits;
|
||||||
*max.last_mut().unwrap() >>= 64 - modulus_num_bits_mod_64;
|
|
||||||
}
|
|
||||||
let scalars = [
|
let scalars = [
|
||||||
C::ScalarField::rand(&mut rng)
|
C::ScalarField::rand(&mut rng)
|
||||||
.into_bigint()
|
.into_bigint()
|
||||||
@@ -342,7 +340,7 @@ pub mod curves {
|
|||||||
|
|
||||||
// Check scalar mul with edge cases
|
// Check scalar mul with edge cases
|
||||||
for scalar in scalars.iter() {
|
for scalar in scalars.iter() {
|
||||||
let native_result = a_native.mul_bigint(scalar);
|
let native_result = a_native.mul(scalar);
|
||||||
let native_result = native_result.into_affine();
|
let native_result = native_result.into_affine();
|
||||||
|
|
||||||
let scalar_bits: Vec<bool> = BitIteratorLE::new(&scalar).collect();
|
let scalar_bits: Vec<bool> = BitIteratorLE::new(&scalar).collect();
|
||||||
@@ -514,21 +512,18 @@ pub mod curves {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod pairing {
|
pub mod pairing {
|
||||||
use ark_ec::{
|
use ark_ec::{PairingEngine, ProjectiveCurve};
|
||||||
pairing::{Pairing, PairingOutput},
|
|
||||||
AffineRepr, CurveGroup,
|
|
||||||
};
|
|
||||||
use ark_ff::{BitIteratorLE, Field, PrimeField};
|
use ark_ff::{BitIteratorLE, Field, PrimeField};
|
||||||
use ark_r1cs_std::prelude::*;
|
use ark_r1cs_std::prelude::*;
|
||||||
use ark_relations::r1cs::{ConstraintSystem, SynthesisError};
|
use ark_relations::r1cs::{ConstraintSystem, SynthesisError};
|
||||||
use ark_std::{test_rng, vec::Vec, UniformRand};
|
use ark_std::{test_rng, vec::Vec, UniformRand};
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn bilinearity_test<E: Pairing, P: PairingVar<E>>() -> Result<(), SynthesisError>
|
pub fn bilinearity_test<E: PairingEngine, P: PairingVar<E>>() -> Result<(), SynthesisError>
|
||||||
where
|
where
|
||||||
for<'a> &'a P::G1Var: GroupOpsBounds<'a, E::G1, P::G1Var>,
|
for<'a> &'a P::G1Var: GroupOpsBounds<'a, E::G1Projective, P::G1Var>,
|
||||||
for<'a> &'a P::G2Var: GroupOpsBounds<'a, E::G2, P::G2Var>,
|
for<'a> &'a P::G2Var: GroupOpsBounds<'a, E::G2Projective, P::G2Var>,
|
||||||
for<'a> &'a P::GTVar: FieldOpsBounds<'a, E::TargetField, P::GTVar>,
|
for<'a> &'a P::GTVar: FieldOpsBounds<'a, E::Fqk, P::GTVar>,
|
||||||
{
|
{
|
||||||
let modes = [
|
let modes = [
|
||||||
AllocationMode::Input,
|
AllocationMode::Input,
|
||||||
@@ -536,12 +531,12 @@ pub mod pairing {
|
|||||||
AllocationMode::Constant,
|
AllocationMode::Constant,
|
||||||
];
|
];
|
||||||
for &mode in &modes {
|
for &mode in &modes {
|
||||||
let cs = ConstraintSystem::<<E::G1 as CurveGroup>::BaseField>::new_ref();
|
let cs = ConstraintSystem::<E::Fq>::new_ref();
|
||||||
|
|
||||||
let mut rng = test_rng();
|
let mut rng = test_rng();
|
||||||
let a = E::G1::rand(&mut rng);
|
let a = E::G1Projective::rand(&mut rng);
|
||||||
let b = E::G2::rand(&mut rng);
|
let b = E::G2Projective::rand(&mut rng);
|
||||||
let s = E::ScalarField::rand(&mut rng);
|
let s = E::Fr::rand(&mut rng);
|
||||||
|
|
||||||
let mut sa = a;
|
let mut sa = a;
|
||||||
sa *= s;
|
sa *= s;
|
||||||
@@ -583,7 +578,7 @@ pub mod pairing {
|
|||||||
|
|
||||||
let mut ans_g = P::pairing(a_prep_g, b_prep_g)?;
|
let mut ans_g = P::pairing(a_prep_g, b_prep_g)?;
|
||||||
let mut ans_n = E::pairing(a, b);
|
let mut ans_n = E::pairing(a, b);
|
||||||
ans_n = PairingOutput(ans_n.0.pow(s.into_bigint()));
|
ans_n = ans_n.pow(s.into_bigint());
|
||||||
ans_g = ans_g.pow_le(&s_iter)?;
|
ans_g = ans_g.pow_le(&s_iter)?;
|
||||||
|
|
||||||
(ans_g, ans_n)
|
(ans_g, ans_n)
|
||||||
@@ -592,12 +587,12 @@ pub mod pairing {
|
|||||||
ans1_g.enforce_equal(&ans2_g)?;
|
ans1_g.enforce_equal(&ans2_g)?;
|
||||||
ans2_g.enforce_equal(&ans3_g)?;
|
ans2_g.enforce_equal(&ans3_g)?;
|
||||||
|
|
||||||
assert_eq!(ans1_g.value()?, ans1_n.0, "Failed native test 1");
|
assert_eq!(ans1_g.value()?, ans1_n, "Failed native test 1");
|
||||||
assert_eq!(ans2_g.value()?, ans2_n.0, "Failed native test 2");
|
assert_eq!(ans2_g.value()?, ans2_n, "Failed native test 2");
|
||||||
assert_eq!(ans3_g.value()?, ans3_n.0, "Failed native test 3");
|
assert_eq!(ans3_g.value()?, ans3_n, "Failed native test 3");
|
||||||
|
|
||||||
assert_eq!(ans1_n.0, ans2_n.0, "Failed ans1_native == ans2_native");
|
assert_eq!(ans1_n, ans2_n, "Failed ans1_native == ans2_native");
|
||||||
assert_eq!(ans2_n.0, ans3_n.0, "Failed ans2_native == ans3_native");
|
assert_eq!(ans2_n, ans3_n, "Failed ans2_native == ans3_native");
|
||||||
assert_eq!(ans1_g.value()?, ans3_g.value()?, "Failed ans1 == ans3");
|
assert_eq!(ans1_g.value()?, ans3_g.value()?, "Failed ans1 == ans3");
|
||||||
assert_eq!(ans1_g.value()?, ans2_g.value()?, "Failed ans1 == ans2");
|
assert_eq!(ans1_g.value()?, ans2_g.value()?, "Failed ans1 == ans2");
|
||||||
assert_eq!(ans2_g.value()?, ans3_g.value()?, "Failed ans2 == ans3");
|
assert_eq!(ans2_g.value()?, ans3_g.value()?, "Failed ans2 == ans3");
|
||||||
@@ -614,38 +609,4 @@ pub mod pairing {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn g2_prepare_consistency_test<E: Pairing, P: PairingVar<E>>() -> Result<(), SynthesisError>
|
|
||||||
{
|
|
||||||
let test_g2_elem = E::G2Affine::generator();
|
|
||||||
let test_g2_prepared = E::G2Prepared::from(test_g2_elem.clone());
|
|
||||||
|
|
||||||
let modes = [
|
|
||||||
AllocationMode::Input,
|
|
||||||
AllocationMode::Witness,
|
|
||||||
AllocationMode::Constant,
|
|
||||||
];
|
|
||||||
for &mode in &modes {
|
|
||||||
let cs = ConstraintSystem::new_ref();
|
|
||||||
|
|
||||||
let test_g2_gadget =
|
|
||||||
P::G2Var::new_witness(cs.clone(), || Ok(test_g2_elem.clone())).unwrap();
|
|
||||||
|
|
||||||
let prepared_test_g2_gadget = P::prepare_g2(&test_g2_gadget).unwrap();
|
|
||||||
let allocated_test_g2_gadget =
|
|
||||||
P::G2PreparedVar::new_variable(cs.clone(), || Ok(test_g2_prepared.clone()), mode)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let prepared_test_g2_gadget_bytes = prepared_test_g2_gadget.to_bytes().unwrap();
|
|
||||||
let allocated_test_g2_gadget_bytes = allocated_test_g2_gadget.to_bytes().unwrap();
|
|
||||||
|
|
||||||
prepared_test_g2_gadget_bytes
|
|
||||||
.enforce_equal(&allocated_test_g2_gadget_bytes)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert!(cs.is_satisfied().unwrap(), "cs is not satisfied");
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "ark-curve25519"
|
|
||||||
version = "0.4.0-alpha.2"
|
|
||||||
authors = [ "arkworks contributors" ]
|
|
||||||
description = "The curve25519 Montgomery curve"
|
|
||||||
homepage = "https://arkworks.rs"
|
|
||||||
repository = "https://github.com/arkworks-rs/curves"
|
|
||||||
documentation = "https://docs.rs/ark-curve25519/"
|
|
||||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
|
||||||
categories = ["cryptography"]
|
|
||||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
|
||||||
license = "MIT/Apache-2.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
ark-ff = { version = "0.4.0-alpha", default-features = false }
|
|
||||||
ark-ec = { version = "0.4.0-alpha", default-features = false }
|
|
||||||
ark-std = { version = "0.4.0-alpha", default-features = false }
|
|
||||||
ark-r1cs-std = { version = "0.4.0-alpha", default-features = false, optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
ark-relations = { version = "0.4.0-alpha", default-features = false }
|
|
||||||
ark-serialize = { version = "0.4.0-alpha", default-features = false }
|
|
||||||
ark-algebra-test-templates = { version = "0.4.0-alpha", default-features = false }
|
|
||||||
ark-curve-constraint-tests = { path = "../curve-constraint-tests", default-features = false }
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = []
|
|
||||||
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ]
|
|
||||||
r1cs = [ "ark-r1cs-std" ]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../LICENSE-APACHE
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../LICENSE-MIT
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 1,
|
|
||||||
"id": "04264893",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"r = 7237005577332262213973186563042994240857116359379907606001950938285454250989"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 2,
|
|
||||||
"id": "1603b293",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"2^2 * 3 * 11 * 198211423230930754013084525763697 * 276602624281642239937218680557139826668747"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 2,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"factor(r - 1)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 3,
|
|
||||||
"id": "425ceac7",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"7237005577332262213973186563042994240857116359379907606001950938285454250988\n",
|
|
||||||
"1570463851528226261927580272323658009530148727742783848239914322803198255651\n",
|
|
||||||
"4908983020090465803374304318106080751443647916949975825112097080460587568629\n",
|
|
||||||
"7119675135705137915307919240607293966034195415655343409829245710729128040338\n",
|
|
||||||
"2975531125133123119648879457563281269120703404158613135195788908093573672641\n"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"gen = 2\n",
|
|
||||||
"print(pow(gen, (r - 1) / 2, r))\n",
|
|
||||||
"print(pow(gen, (r - 1) / 3, r))\n",
|
|
||||||
"print(pow(gen, (r - 1) / 11, r))\n",
|
|
||||||
"print(pow(gen, (r - 1) / 198211423230930754013084525763697, r))\n",
|
|
||||||
"print(pow(gen, (r - 1) / 276602624281642239937218680557139826668747, r))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"id": "f4c58ca4",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"kernelspec": {
|
|
||||||
"display_name": "SageMath 9.2",
|
|
||||||
"language": "sage",
|
|
||||||
"name": "sagemath"
|
|
||||||
},
|
|
||||||
"language_info": {
|
|
||||||
"codemirror_mode": {
|
|
||||||
"name": "ipython",
|
|
||||||
"version": 3
|
|
||||||
},
|
|
||||||
"file_extension": ".py",
|
|
||||||
"mimetype": "text/x-python",
|
|
||||||
"name": "python",
|
|
||||||
"nbconvert_exporter": "python",
|
|
||||||
"pygments_lexer": "ipython3",
|
|
||||||
"version": "3.9.7"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nbformat": 4,
|
|
||||||
"nbformat_minor": 5
|
|
||||||
}
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 1,
|
|
||||||
"id": "f890e69f",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"q = pow(2,255) - 19"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 2,
|
|
||||||
"id": "d90a7f0b",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"A = 486662\n",
|
|
||||||
"B = 1"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 3,
|
|
||||||
"id": "1b2aebc5",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"486664\n",
|
|
||||||
"486660\n"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"a = (A + 2) * 1\n",
|
|
||||||
"d = (A - 2) * 1\n",
|
|
||||||
"print(a)\n",
|
|
||||||
"print(d)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 4,
|
|
||||||
"id": "aae2f8bf",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"9"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 4,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"u = 9\n",
|
|
||||||
"u"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 5,
|
|
||||||
"id": "ea9a4d90",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"14781619447589544791020593568409986887264606134616475288964881837755586237401"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 5,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"v = mod(u^3 + A * u^2 + u, q).sqrt()\n",
|
|
||||||
"v"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 6,
|
|
||||||
"id": "95895004",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"38213832894368730265794714087330135568483813637251082400757400312561599933396"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 6,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"u * pow(v, -1, q) % q"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 7,
|
|
||||||
"id": "1134cf74",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"46316835694926478169428394003475163141307993866256225615783033603165251855960"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 7,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"(u - 1) * pow(u + 1, -1, q) % q"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"id": "ec089e21",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"kernelspec": {
|
|
||||||
"display_name": "SageMath 9.2",
|
|
||||||
"language": "sage",
|
|
||||||
"name": "sagemath"
|
|
||||||
},
|
|
||||||
"language_info": {
|
|
||||||
"codemirror_mode": {
|
|
||||||
"name": "ipython",
|
|
||||||
"version": 3
|
|
||||||
},
|
|
||||||
"file_extension": ".py",
|
|
||||||
"mimetype": "text/x-python",
|
|
||||||
"name": "python",
|
|
||||||
"nbconvert_exporter": "python",
|
|
||||||
"pygments_lexer": "ipython3",
|
|
||||||
"version": "3.9.7"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nbformat": 4,
|
|
||||||
"nbformat_minor": 5
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
use ark_r1cs_std::groups::curves::twisted_edwards::{AffineVar, MontgomeryAffineVar};
|
|
||||||
|
|
||||||
use crate::{constraints::FqVar, *};
|
|
||||||
|
|
||||||
/// A variable that is the R1CS equivalent of `crate::EdwardsAffine`.
|
|
||||||
pub type EdwardsVar = AffineVar<Curve25519Config, FqVar>;
|
|
||||||
|
|
||||||
/// A variable that is the R1CS equivalent of `crate::NonZeroMontgomeryAffine`.
|
|
||||||
pub type NonZeroMontgomeryVar = MontgomeryAffineVar<Curve25519Config, FqVar>;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test() {
|
|
||||||
ark_curve_constraint_tests::curves::te_test::<Curve25519Config, EdwardsVar>().unwrap();
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
use ark_r1cs_std::fields::fp::FpVar;
|
|
||||||
|
|
||||||
use crate::Fq;
|
|
||||||
|
|
||||||
/// A variable that is the R1CS equivalent of `crate::Fq`.
|
|
||||||
pub type FqVar = FpVar<Fq>;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test() {
|
|
||||||
ark_curve_constraint_tests::fields::field_test::<_, _, FqVar>().unwrap();
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
//! This module implements the R1CS equivalent of `ark_curve25519`.
|
|
||||||
//! It requires a curve that embeds curve25519.
|
|
||||||
|
|
||||||
mod curves;
|
|
||||||
mod fields;
|
|
||||||
|
|
||||||
pub use curves::*;
|
|
||||||
pub use fields::*;
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
use crate::{Fq, Fr};
|
|
||||||
use ark_ec::{
|
|
||||||
models::CurveConfig,
|
|
||||||
twisted_edwards::{Affine, MontCurveConfig, MontgomeryAffine, Projective, TECurveConfig},
|
|
||||||
};
|
|
||||||
use ark_ff::MontFp;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
pub type EdwardsAffine = Affine<Curve25519Config>;
|
|
||||||
pub type EdwardsProjective = Projective<Curve25519Config>;
|
|
||||||
pub type NonZeroMontgomeryAffine = MontgomeryAffine<Curve25519Config>;
|
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
|
||||||
pub struct Curve25519Config;
|
|
||||||
|
|
||||||
impl CurveConfig for Curve25519Config {
|
|
||||||
type BaseField = Fq;
|
|
||||||
type ScalarField = Fr;
|
|
||||||
|
|
||||||
/// COFACTOR = 8
|
|
||||||
const COFACTOR: &'static [u64] = &[8];
|
|
||||||
|
|
||||||
/// COFACTOR_INV (mod r) =
|
|
||||||
/// 2713877091499598330239944961141122840321418634767465352250731601857045344121
|
|
||||||
const COFACTOR_INV: Fr =
|
|
||||||
MontFp!("2713877091499598330239944961141122840321418634767465352250731601857045344121");
|
|
||||||
}
|
|
||||||
|
|
||||||
// We want to emphasize that this twisted Edwards curve is not ed25519.
|
|
||||||
// Ed25519 has COEFF_A = -1 and COEFF_D = -121665 / 121666.
|
|
||||||
impl TECurveConfig for Curve25519Config {
|
|
||||||
/// COEFF_A = 486664
|
|
||||||
const COEFF_A: Fq = MontFp!("486664");
|
|
||||||
|
|
||||||
/// COEFF_D = 486660
|
|
||||||
const COEFF_D: Fq = MontFp!("486660");
|
|
||||||
|
|
||||||
/// Standard generators from <https://neuromancer.sk/std/other/Curve25519>.
|
|
||||||
/// The Montgomery form is
|
|
||||||
/// x = 0x09,
|
|
||||||
/// y = 0x20ae19a1b8a086b4e01edd2c7748d14c923d4d7e6d7c61b229e9c5a27eced3d9
|
|
||||||
/// The twisted Edwards form is
|
|
||||||
/// x = 0x547c4350219f5e19dd26a3d6668b74346a8eb726eb2396e1228cfa397ffe6bd4
|
|
||||||
/// y = 0x6666666666666666666666666666666666666666666666666666666666666658
|
|
||||||
const GENERATOR: EdwardsAffine = EdwardsAffine::new_unchecked(GENERATOR_X, GENERATOR_Y);
|
|
||||||
|
|
||||||
type MontCurveConfig = Curve25519Config;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MontCurveConfig for Curve25519Config {
|
|
||||||
/// COEFF_A = 486662
|
|
||||||
const COEFF_A: Fq = MontFp!("486662");
|
|
||||||
|
|
||||||
/// COEFF_B = 1
|
|
||||||
const COEFF_B: Fq = MontFp!("1");
|
|
||||||
|
|
||||||
type TECurveConfig = Curve25519Config;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// GENERATOR_X =
|
|
||||||
/// 38213832894368730265794714087330135568483813637251082400757400312561599933396
|
|
||||||
const GENERATOR_X: Fq =
|
|
||||||
MontFp!("38213832894368730265794714087330135568483813637251082400757400312561599933396");
|
|
||||||
|
|
||||||
/// GENERATOR_Y =
|
|
||||||
/// (4/5)
|
|
||||||
/// 46316835694926478169428394003475163141307993866256225615783033603165251855960
|
|
||||||
const GENERATOR_Y: Fq =
|
|
||||||
MontFp!("46316835694926478169428394003475163141307993866256225615783033603165251855960");
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
use crate::*;
|
|
||||||
use ark_algebra_test_templates::*;
|
|
||||||
|
|
||||||
test_group!(te; EdwardsProjective; te);
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
|
|
||||||
|
|
||||||
#[derive(MontConfig)]
|
|
||||||
#[modulus = "57896044618658097711785492504343953926634992332820282019728792003956564819949"]
|
|
||||||
#[generator = "2"]
|
|
||||||
#[small_subgroup_base = "3"]
|
|
||||||
#[small_subgroup_power = "1"]
|
|
||||||
pub struct FqConfig;
|
|
||||||
pub type Fq = Fp256<MontBackend<FqConfig, 4>>;
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
|
|
||||||
|
|
||||||
#[derive(MontConfig)]
|
|
||||||
#[modulus = "7237005577332262213973186563042994240857116359379907606001950938285454250989"]
|
|
||||||
#[generator = "2"]
|
|
||||||
#[small_subgroup_base = "3"]
|
|
||||||
#[small_subgroup_power = "1"]
|
|
||||||
pub struct FrConfig;
|
|
||||||
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
mod fq;
|
|
||||||
mod fr;
|
|
||||||
|
|
||||||
pub use fq::*;
|
|
||||||
pub use fr::*;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
use crate::{Fq, Fr};
|
|
||||||
use ark_algebra_test_templates::*;
|
|
||||||
|
|
||||||
test_field!(fr; Fr; mont_prime_field);
|
|
||||||
test_field!(fq; Fq; mont_prime_field);
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
|
||||||
#![deny(
|
|
||||||
warnings,
|
|
||||||
unused,
|
|
||||||
future_incompatible,
|
|
||||||
nonstandard_style,
|
|
||||||
rust_2018_idioms
|
|
||||||
)]
|
|
||||||
#![forbid(unsafe_code)]
|
|
||||||
|
|
||||||
//! This library implements the curve25519 Montgomery curve.
|
|
||||||
//!
|
|
||||||
//! Curve information:
|
|
||||||
//! * Base field: q =
|
|
||||||
//! 57896044618658097711785492504343953926634992332820282019728792003956564819949
|
|
||||||
//! * Scalar field: r =
|
|
||||||
//! 7237005577332262213973186563042994240857116359379907606001950938285454250989
|
|
||||||
//! * Curve equation: B * y^2 = x^3 + A * x^2 + x, where
|
|
||||||
//! * A = 486662
|
|
||||||
//! * B = 1
|
|
||||||
|
|
||||||
#[cfg(feature = "r1cs")]
|
|
||||||
pub mod constraints;
|
|
||||||
mod curves;
|
|
||||||
mod fields;
|
|
||||||
|
|
||||||
pub use curves::*;
|
|
||||||
pub use fields::*;
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user