mirror of
https://github.com/arnaucube/ark-curves-cherry-picked.git
synced 2026-01-27 14:13:46 +01:00
Compare commits
31 Commits
update-to-
...
cherry-pic
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d56cc2630 | ||
|
|
5a0b8eca0b | ||
|
|
a986e08ce4 | ||
|
|
5831ddbfe7 | ||
|
|
cba0c7ef0d | ||
|
|
a82486db1d | ||
|
|
febd7635fb | ||
|
|
f8a6a4050e | ||
|
|
cdf4d182a6 | ||
|
|
99831650f8 | ||
|
|
db03d405b5 | ||
|
|
a7d266f73d | ||
|
|
5d6d31d213 | ||
|
|
df39c78a5b | ||
|
|
138b23f2fa | ||
|
|
4bcf87de22 | ||
|
|
efefa209d6 | ||
|
|
1833cbfb29 | ||
|
|
f43d59c958 | ||
|
|
68f500da01 | ||
|
|
363426c1d4 | ||
|
|
55a092a6c7 | ||
|
|
f74378c017 | ||
|
|
3af6ec17d6 | ||
|
|
dc555882cd | ||
|
|
3c4c67f114 | ||
|
|
42289245a6 | ||
|
|
b433045f4d | ||
|
|
52577f93ba | ||
|
|
6d94362894 | ||
|
|
435de9fc36 |
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@v1
|
uses: actions/checkout@v3
|
||||||
- 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@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install Rust (${{ matrix.rust }})
|
- name: Install Rust (${{ matrix.rust }})
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -78,7 +78,6 @@ 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
|
||||||
@@ -86,7 +85,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@v2
|
- uses: actions/checkout@v3
|
||||||
- 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
|
||||||
@@ -103,22 +102,47 @@ jobs:
|
|||||||
exclude:
|
exclude:
|
||||||
- dir: scripts/
|
- dir: scripts/
|
||||||
- dir: curve-constraint-tests/
|
- dir: curve-constraint-tests/
|
||||||
- dir: curve-benches/
|
- dir: mnt4_753/
|
||||||
|
- dir: mnt6_753/
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
- 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@v1
|
uses: actions/checkout@v3
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
@@ -138,7 +162,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install Rust (${{ matrix.rust }})
|
- name: Install Rust (${{ matrix.rust }})
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -159,10 +183,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 --exclude ark-curve-benches --target aarch64-unknown-none
|
args: --examples --workspace --exclude ark-curve-constraint-tests --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 --exclude ark-curve-benches --target aarch64-unknown-none
|
args: --workspace --exclude ark-curve-constraint-tests --target aarch64-unknown-none
|
||||||
|
|||||||
@@ -8,12 +8,21 @@
|
|||||||
### 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
|
||||||
|
|
||||||
|
|||||||
22
Cargo.toml
22
Cargo.toml
@@ -1,7 +1,6 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
|
|
||||||
members = [
|
members = [
|
||||||
"curve-benches",
|
|
||||||
"curve-constraint-tests",
|
"curve-constraint-tests",
|
||||||
|
|
||||||
"bls12_377",
|
"bls12_377",
|
||||||
@@ -19,6 +18,7 @@ members = [
|
|||||||
|
|
||||||
"bn254",
|
"bn254",
|
||||||
"ed_on_bn254",
|
"ed_on_bn254",
|
||||||
|
"grumpkin",
|
||||||
|
|
||||||
"mnt4_298",
|
"mnt4_298",
|
||||||
"mnt6_298",
|
"mnt6_298",
|
||||||
@@ -30,7 +30,14 @@ members = [
|
|||||||
|
|
||||||
"pallas",
|
"pallas",
|
||||||
"vesta",
|
"vesta",
|
||||||
|
|
||||||
|
"secp256k1",
|
||||||
|
"secq256k1",
|
||||||
|
|
||||||
|
"curve25519",
|
||||||
|
"ed25519",
|
||||||
]
|
]
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
@@ -57,11 +64,10 @@ incremental = true
|
|||||||
debug-assertions = true
|
debug-assertions = true
|
||||||
debug = true
|
debug = true
|
||||||
|
|
||||||
# To be removed in the new release.
|
# The following patch is to use a version of ark-r1cs-std compatible with
|
||||||
|
# v0.4.0 but that includes a cherry-picked commit from after v0.4.0 which fixes
|
||||||
|
# the in-circuit scalar multiplication of the zero point. The commit is from
|
||||||
|
# https://github.com/arkworks-rs/r1cs-std/pull/124, without including other
|
||||||
|
# changes done between v0.4.0 and this fix which would break compatibility.
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
ark-ec = { git = "https://github.com/arkworks-rs/algebra" }
|
ark-r1cs-std = { git = "https://github.com/arnaucube/ark-r1cs-std-cherry-picked/" }
|
||||||
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.3.0"
|
version = "0.4.0-alpha.2"
|
||||||
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,18 +10,19 @@ 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 = "2018"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ark-ff = { version="^0.3.0", default-features = false }
|
ark-ff = { version="0.4.0-alpha", default-features = false }
|
||||||
ark-ec = { version="^0.3.0", default-features = false }
|
ark-ec = { version="0.4.0-alpha", default-features = false }
|
||||||
ark-r1cs-std = { version="^0.3.0", default-features = false, optional = true }
|
ark-r1cs-std = { version="0.4.0-alpha", default-features = false, optional = true }
|
||||||
ark-std = { version="^0.3.0", default-features = false }
|
ark-std = { version = "0.4.0-alpha", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ark-relations = { version="^0.3.0", default-features = false }
|
ark-relations = { version="0.4.0-alpha", default-features = false }
|
||||||
ark-serialize = { version="^0.3.0", default-features = false }
|
ark-serialize = { version = "0.4.0-alpha", default-features = false }
|
||||||
ark-algebra-test-templates = { version="^0.3.0", default-features = false }
|
ark-algebra-test-templates = { version = "0.4.0-alpha", 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]
|
||||||
@@ -31,4 +32,9 @@ 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
|
||||||
|
|||||||
16
bls12_377/benches/bls12_377.rs
Normal file
16
bls12_377/benches/bls12_377.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
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,45 +1,39 @@
|
|||||||
use ark_ec::{bls12::Bls12Parameters, CurveConfig};
|
use ark_ec::{bls12::Bls12Config, 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::Parameters;
|
use crate::Config;
|
||||||
|
|
||||||
/// An element of G1 in the BLS12-377 bilinear group.
|
/// An element of G1 in the BLS12-377 bilinear group.
|
||||||
pub type G1Var = bls12::G1Var<Parameters>;
|
pub type G1Var = bls12::G1Var<Config>;
|
||||||
/// 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<Parameters>;
|
pub type G2Var = bls12::G2Var<Config>;
|
||||||
|
|
||||||
/// An element of G1 (in TE Affine form) in the BLS12-377 bilinear group.
|
/// An element of G1 (in TE Affine form) in the BLS12-377 bilinear group.
|
||||||
pub type G1TEAffineVar = TEAffineVar<
|
pub type G1TEAffineVar = TEAffineVar<
|
||||||
<Parameters as Bls12Parameters>::G1Parameters,
|
<Config as Bls12Config>::G1Config,
|
||||||
FpVar<<<Parameters as Bls12Parameters>::G1Parameters as CurveConfig>::BaseField>,
|
FpVar<<<Config as Bls12Config>::G1Config 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<Parameters>;
|
pub type G1PreparedVar = bls12::G1PreparedVar<Config>;
|
||||||
/// 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<Parameters>;
|
pub type G2PreparedVar = bls12::G2PreparedVar<Config>;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
use ark_ec::models::bls12::Bls12Parameters;
|
use ark_ec::models::bls12::Bls12Config;
|
||||||
ark_curve_constraint_tests::curves::sw_test::<
|
ark_curve_constraint_tests::curves::sw_test::<<Config as Bls12Config>::G1Config, G1Var>()
|
||||||
<Parameters as Bls12Parameters>::G1Parameters,
|
.unwrap();
|
||||||
G1Var,
|
|
||||||
>()
|
|
||||||
.unwrap();
|
|
||||||
ark_curve_constraint_tests::curves::te_test::<
|
ark_curve_constraint_tests::curves::te_test::<
|
||||||
<Parameters as Bls12Parameters>::G1Parameters,
|
<Config as Bls12Config>::G1Config,
|
||||||
G1TEAffineVar,
|
G1TEAffineVar,
|
||||||
>()
|
>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
ark_curve_constraint_tests::curves::sw_test::<
|
ark_curve_constraint_tests::curves::sw_test::<<Config as Bls12Config>::G2Config, G2Var>()
|
||||||
<Parameters as Bls12Parameters>::G2Parameters,
|
.unwrap();
|
||||||
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::PairingEngine;
|
//! # use ark_ec::pairing::Pairing;
|
||||||
//! # 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);
|
//! assert_eq!(pairing_result.value()?, pairing_result_native.0);
|
||||||
//!
|
//!
|
||||||
//! // 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,11 +1,13 @@
|
|||||||
use crate::Parameters;
|
use crate::Config;
|
||||||
|
|
||||||
/// Specifies the constraints for computing a pairing in the BLS12-377 bilinear
|
/// Specifies the constraints for computing a pairing in the BLS12-377 bilinear
|
||||||
/// group.
|
/// group.
|
||||||
pub type PairingVar = ark_r1cs_std::pairing::bls12::PairingVar<Parameters>;
|
pub type PairingVar = ark_r1cs_std::pairing::bls12::PairingVar<Config>;
|
||||||
|
|
||||||
#[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 Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ impl CurveConfig for Parameters {
|
|||||||
const COFACTOR_INV: Fr = MontFp!("5285428838741532253824584287042945485047145357130994810877");
|
const COFACTOR_INV: Fr = MontFp!("5285428838741532253824584287042945485047145357130994810877");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
impl SWCurveConfig for Config {
|
||||||
/// 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 Parameters {
|
|||||||
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<Parameters>;
|
pub type G1SWAffine = SWAffine<Config>;
|
||||||
pub type G1TEAffine = TEAffine<Parameters>;
|
pub type G1TEAffine = TEAffine<Config>;
|
||||||
pub type G1TEProjective = TEProjective<Parameters>;
|
pub type G1TEProjective = TEProjective<Config>;
|
||||||
|
|
||||||
/// 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<Parameters>;
|
|||||||
/// # b = -TE1d/TE1a
|
/// # b = -TE1d/TE1a
|
||||||
/// TE2d = Fp(122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179)
|
/// TE2d = Fp(122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179)
|
||||||
/// ```
|
/// ```
|
||||||
impl TECurveConfig for Parameters {
|
impl TECurveConfig for Config {
|
||||||
/// 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 Parameters {
|
|||||||
/// 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 = Parameters;
|
type MontCurveConfig = Config;
|
||||||
|
|
||||||
/// 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 Parameters {
|
|||||||
// # MB = s
|
// # MB = s
|
||||||
// MB=Fp(10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931)
|
// MB=Fp(10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931)
|
||||||
// ```
|
// ```
|
||||||
impl MontCurveConfig for Parameters {
|
impl MontCurveConfig for Config {
|
||||||
/// 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 = Parameters;
|
type TECurveConfig = Config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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<Parameters>;
|
pub type G2Affine = Affine<Config>;
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq2;
|
type BaseField = Fq2;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -34,9 +34,9 @@ impl CurveConfig for Parameters {
|
|||||||
MontFp!("6764900296503390671038341982857278410319949526107311149686707033187604810669");
|
MontFp!("6764900296503390671038341982857278410319949526107311149686707033187604810669");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
impl SWCurveConfig for Config {
|
||||||
/// COEFF_A = [0, 0]
|
/// COEFF_A = [0, 0]
|
||||||
const COEFF_A: Fq2 = Fq2::new(g1::Parameters::COEFF_A, g1::Parameters::COEFF_A);
|
const COEFF_A: Fq2 = Fq2::new(g1::Config::COEFF_A, g1::Config::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 Parameters {
|
|||||||
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, Bls12Parameters, TwistType},
|
bls12::{Bls12, Bls12Config, TwistType},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
@@ -11,9 +11,9 @@ pub mod g2;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl Bls12Parameters for Parameters {
|
impl Bls12Config for Config {
|
||||||
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 Bls12Parameters for Parameters {
|
|||||||
type Fp2Config = Fq2Config;
|
type Fp2Config = Fq2Config;
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Config = Fq6Config;
|
||||||
type Fp12Config = Fq12Config;
|
type Fp12Config = Fq12Config;
|
||||||
type G1Parameters = g1::Parameters;
|
type G1Config = g1::Config;
|
||||||
type G2Parameters = g2::Parameters;
|
type G2Config = g2::Config;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Bls12_377 = Bls12<Parameters>;
|
pub type Bls12_377 = Bls12<Config>;
|
||||||
|
|
||||||
pub type G1Affine = bls12::G1Affine<Parameters>;
|
pub type G1Affine = bls12::G1Affine<Config>;
|
||||||
pub type G1Projective = bls12::G1Projective<Parameters>;
|
pub type G1Projective = bls12::G1Projective<Config>;
|
||||||
pub type G2Affine = bls12::G2Affine<Parameters>;
|
pub type G2Affine = bls12::G2Affine<Config>;
|
||||||
pub type G2Projective = bls12::G2Projective<Parameters>;
|
pub type G2Projective = bls12::G2Projective<Config>;
|
||||||
|
|
||||||
pub use g1::{G1TEAffine, G1TEProjective};
|
pub use g1::{G1TEAffine, G1TEProjective};
|
||||||
|
|||||||
@@ -1,19 +1,7 @@
|
|||||||
use ark_algebra_test_templates::{
|
use crate::{Bls12_377, G1Projective, G2Projective};
|
||||||
curves::{curve_tests, edwards_tests, sw_tests},
|
use ark_algebra_test_templates::*;
|
||||||
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};
|
|
||||||
|
|
||||||
use crate::{g1, g2, Bls12_377, Fq, Fq12, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
|
test_group!(g1; G1Projective; sw);
|
||||||
|
test_group!(g2; G2Projective; sw);
|
||||||
generate_g1_test!(bls12_377; curve_tests; sw_tests; edwards_tests;);
|
test_group!(pairing_output; ark_ec::pairing::PairingOutput<Bls12_377>; msm);
|
||||||
generate_g2_test!(bls12_377; curve_tests; sw_tests;);
|
test_pairing!(pairing; crate::Bls12_377);
|
||||||
generate_bilinearity_test!(Bls12_377, Fq12);
|
|
||||||
generate_g1_generator_raw_test!(bls12_377, 1);
|
|
||||||
|
|||||||
@@ -21,10 +21,31 @@ impl Fp2Config for Fq2Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_fp_by_nonresidue(fe: &Self::Fp) -> Self::Fp {
|
fn mul_fp_by_nonresidue_in_place(fe: &mut Self::Fp) -> &mut Self::Fp {
|
||||||
let original = fe;
|
fe.neg_in_place();
|
||||||
let mut fe = -fe.double();
|
*fe = *fe + fe.double_in_place().double_in_place();
|
||||||
fe.double_in_place();
|
fe
|
||||||
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,10 +68,12 @@ impl Fp6Config for Fq6Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_fp2_by_nonresidue(fe: &Fq2) -> Fq2 {
|
fn mul_fp2_by_nonresidue_in_place(fe: &mut Fq2) -> &mut Fq2 {
|
||||||
// Karatsuba multiplication with constant other = u.
|
// Karatsuba multiplication with constant other = u.
|
||||||
let c0 = Fq2Config::mul_fp_by_nonresidue(&fe.c1);
|
let old_c0 = fe.c0;
|
||||||
let c1 = fe.c0;
|
fe.c0 = fe.c1;
|
||||||
Fq2::new(c0, c1)
|
Fq2Config::mul_fp_by_nonresidue_in_place(&mut fe.c0);
|
||||||
|
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},
|
||||||
One, UniformRand, Zero,
|
Fp384, One, UniformRand, Zero,
|
||||||
};
|
};
|
||||||
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
use ark_std::{
|
||||||
use ark_std::{rand::Rng, test_rng};
|
|
||||||
use core::{
|
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
ops::{AddAssign, MulAssign, SubAssign},
|
ops::{AddAssign, MulAssign},
|
||||||
|
test_rng,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Config, FqConfig, Fr, FrConfig};
|
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Config, Fr};
|
||||||
|
|
||||||
generate_field_test!(bls12_377; fq2; fq6; fq12; mont(6, 4); );
|
test_field!(fr; Fr; mont_prime_field);
|
||||||
generate_field_serialization_test!(bls12_377; fq2; fq6; fq12;);
|
test_field!(fq; Fq; mont_prime_field);
|
||||||
|
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(BigInteger384::from(i + 1)) > Fq::from(BigInteger384::from(i)));
|
assert!(Fq::from(Fp384::from(i + 1)) > Fq::from(Fp384::from(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,14 +95,8 @@ 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!(
|
assert_eq!(QuadraticResidue, Fq::from(Fp384::from(4u64)).legendre());
|
||||||
QuadraticResidue,
|
assert_eq!(QuadraticNonResidue, Fq::from(Fp384::from(5u64)).legendre());
|
||||||
Fq::from(BigInteger384::from(4u64)).legendre()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
QuadraticNonResidue,
|
|
||||||
Fq::from(BigInteger384::from(5u64)).legendre()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -142,7 +136,7 @@ fn test_fq2_legendre() {
|
|||||||
// i^2 = -1
|
// i^2 = -1
|
||||||
let mut m1 = -Fq2::one();
|
let mut m1 = -Fq2::one();
|
||||||
assert_eq!(QuadraticResidue, m1.legendre());
|
assert_eq!(QuadraticResidue, m1.legendre());
|
||||||
m1 = Fq6Config::mul_fp2_by_nonresidue(&m1);
|
Fq6Config::mul_fp2_by_nonresidue_in_place(&mut 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.3.0"
|
version = "0.4.0-alpha.2"
|
||||||
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,16 +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 = "2018"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ark-ff = { version="^0.3.0", default-features = false }
|
ark-ff = { version="0.4.0-alpha", default-features = false }
|
||||||
ark-ec = { version="^0.3.0", default-features = false }
|
ark-ec = { version="0.4.0-alpha", default-features = false }
|
||||||
ark-std = { version="^0.3.0", default-features = false }
|
ark-std = { version = "0.4.0-alpha", default-features = false }
|
||||||
|
ark-serialize = { version = "0.4.0-alpha", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
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 }
|
||||||
|
hex = "^0.4.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "curve" ]
|
default = [ "curve" ]
|
||||||
@@ -27,3 +29,8 @@ 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
|
||||||
|
|||||||
16
bls12_381/benches/bls12_381.rs
Normal file
16
bls12_381/benches/bls12_381.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
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,22 +1,26 @@
|
|||||||
|
use crate::*;
|
||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bls12,
|
bls12,
|
||||||
bls12::Bls12Parameters,
|
bls12::Bls12Config,
|
||||||
models::CurveConfig,
|
models::CurveConfig,
|
||||||
short_weierstrass::{Affine, SWCurveConfig},
|
short_weierstrass::{Affine, SWCurveConfig},
|
||||||
AffineCurve, ProjectiveCurve,
|
AffineRepr, Group,
|
||||||
};
|
};
|
||||||
use ark_ff::{Field, MontFp, Zero};
|
use ark_ff::{Field, MontFp, PrimeField, Zero};
|
||||||
use ark_std::ops::Neg;
|
use ark_serialize::{Compress, SerializationError};
|
||||||
|
use ark_std::{ops::Neg, One};
|
||||||
|
|
||||||
use crate::*;
|
use crate::util::{
|
||||||
|
read_g1_compressed, read_g1_uncompressed, serialize_fq, EncodingFlags, G1_SERIALIZED_SIZE,
|
||||||
|
};
|
||||||
|
|
||||||
pub type G1Affine = bls12::G1Affine<crate::Parameters>;
|
pub type G1Affine = bls12::G1Affine<crate::Config>;
|
||||||
pub type G1Projective = bls12::G1Projective<crate::Parameters>;
|
pub type G1Projective = bls12::G1Projective<crate::Config>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -29,7 +33,7 @@ impl CurveConfig for Parameters {
|
|||||||
MontFp!("52435875175126190458656871551744051925719901746859129887267498875565241663483");
|
MontFp!("52435875175126190458656871551744051925719901746859129887267498875565241663483");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
impl SWCurveConfig for Config {
|
||||||
/// COEFF_A = 0
|
/// COEFF_A = 0
|
||||||
const COEFF_A: Fq = Fq::ZERO;
|
const COEFF_A: Fq = Fq::ZERO;
|
||||||
|
|
||||||
@@ -40,7 +44,7 @@ impl SWCurveConfig for Parameters {
|
|||||||
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,15 +57,90 @@ impl SWCurveConfig for Parameters {
|
|||||||
// 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::Parameters::X);
|
let x_times_p = p.mul_bigint(crate::Config::X);
|
||||||
if x_times_p.eq(p) && !p.infinity {
|
if x_times_p.eq(p) && !p.infinity {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let minus_x_squared_times_p = x_times_p.mul_bigint(crate::Parameters::X).neg();
|
let minus_x_squared_times_p = x_times_p.mul_bigint(crate::Config::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 =
|
||||||
@@ -75,7 +154,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<Parameters>) -> Affine<Parameters> {
|
pub fn endomorphism(p: &Affine<Config>) -> Affine<Config> {
|
||||||
// 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.
|
||||||
@@ -83,3 +162,33 @@ pub fn endomorphism(p: &Affine<Parameters>) -> Affine<Parameters> {
|
|||||||
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,21 +1,28 @@
|
|||||||
|
use ark_std::ops::Neg;
|
||||||
|
|
||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bls12,
|
bls12,
|
||||||
bls12::Bls12Parameters,
|
bls12::Bls12Config,
|
||||||
models::CurveConfig,
|
models::CurveConfig,
|
||||||
short_weierstrass::{Affine, SWCurveConfig},
|
short_weierstrass::{Affine, Projective, SWCurveConfig},
|
||||||
AffineCurve,
|
AffineRepr, CurveGroup, Group,
|
||||||
};
|
};
|
||||||
use ark_ff::{Field, MontFp, Zero};
|
use ark_ff::{Field, MontFp, Zero};
|
||||||
|
use ark_serialize::{Compress, SerializationError};
|
||||||
|
|
||||||
use crate::*;
|
use super::util::{serialize_fq, EncodingFlags, G2_SERIALIZED_SIZE};
|
||||||
|
use crate::{
|
||||||
|
util::{read_g2_compressed, read_g2_uncompressed},
|
||||||
|
*,
|
||||||
|
};
|
||||||
|
|
||||||
pub type G2Affine = bls12::G2Affine<crate::Parameters>;
|
pub type G2Affine = bls12::G2Affine<crate::Config>;
|
||||||
pub type G2Projective = bls12::G2Projective<crate::Parameters>;
|
pub type G2Projective = bls12::G2Projective<crate::Config>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq2;
|
type BaseField = Fq2;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -40,18 +47,18 @@ impl CurveConfig for Parameters {
|
|||||||
MontFp!("26652489039290660355457965112010883481355318854675681319708643586776743290055");
|
MontFp!("26652489039290660355457965112010883481355318854675681319708643586776743290055");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
impl SWCurveConfig for Config {
|
||||||
/// COEFF_A = [0, 0]
|
/// COEFF_A = [0, 0]
|
||||||
const COEFF_A: Fq2 = Fq2::new(g1::Parameters::COEFF_A, g1::Parameters::COEFF_A);
|
const COEFF_A: Fq2 = Fq2::new(g1::Config::COEFF_A, g1::Config::COEFF_A);
|
||||||
|
|
||||||
/// COEFF_B = [4, 4]
|
/// COEFF_B = [4, 4]
|
||||||
const COEFF_B: Fq2 = Fq2::new(g1::Parameters::COEFF_B, g1::Parameters::COEFF_B);
|
const COEFF_B: Fq2 = Fq2::new(g1::Config::COEFF_B, g1::Config::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()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,8 +67,8 @@ impl SWCurveConfig for Parameters {
|
|||||||
//
|
//
|
||||||
// Checks that [p]P = [X]P
|
// Checks that [p]P = [X]P
|
||||||
|
|
||||||
let mut x_times_point = point.mul_bigint(crate::Parameters::X);
|
let mut x_times_point = point.mul_bigint(crate::Config::X);
|
||||||
if crate::Parameters::X_IS_NEGATIVE {
|
if crate::Config::X_IS_NEGATIVE {
|
||||||
x_times_point = -x_times_point;
|
x_times_point = -x_times_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +76,109 @@ impl SWCurveConfig for Parameters {
|
|||||||
|
|
||||||
x_times_point.eq(&p_times_point)
|
x_times_point.eq(&p_times_point)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn clear_cofactor(p: &G2Affine) -> G2Affine {
|
||||||
|
// Based on Section 4.1 of https://eprint.iacr.org/2017/419.pdf
|
||||||
|
// [h(ψ)]P = [x^2 − x − 1]P + [x − 1]ψ(P) + (ψ^2)(2P)
|
||||||
|
|
||||||
|
// x = -15132376222941642752
|
||||||
|
// When multiplying, use -c1 instead, and then negate the result. That's much
|
||||||
|
// more efficient, since the scalar -c1 has less limbs and a much lower Hamming
|
||||||
|
// weight.
|
||||||
|
let x: &'static [u64] = crate::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);
|
||||||
@@ -109,7 +219,12 @@ pub const P_POWER_ENDOMORPHISM_COEFF_1: Fq2 = Fq2::new(
|
|||||||
"1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257")
|
"1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257")
|
||||||
);
|
);
|
||||||
|
|
||||||
pub fn p_power_endomorphism(p: &Affine<Parameters>) -> Affine<Parameters> {
|
pub const DOUBLE_P_POWER_ENDOMORPHISM: Fq2 = Fq2::new(
|
||||||
|
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,
|
||||||
@@ -125,8 +240,8 @@ pub fn p_power_endomorphism(p: &Affine<Parameters>) -> Affine<Parameters> {
|
|||||||
// 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(1);
|
res.x.frobenius_map_in_place(1);
|
||||||
res.y.frobenius_map(1);
|
res.y.frobenius_map_in_place(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;
|
||||||
@@ -135,3 +250,47 @@ pub fn p_power_endomorphism(p: &Affine<Parameters>) -> Affine<Parameters> {
|
|||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For a p-power endomorphism psi(P), compute psi(psi(P))
|
||||||
|
pub fn double_p_power_endomorphism(p: &Projective<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,9 +1,10 @@
|
|||||||
use ark_ec::bls12::{Bls12, Bls12Parameters, TwistType};
|
use ark_ec::bls12::{Bls12, Bls12Config, 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;
|
||||||
@@ -13,11 +14,11 @@ pub use self::{
|
|||||||
g2::{G2Affine, G2Projective},
|
g2::{G2Affine, G2Projective},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type Bls12_381 = Bls12<Parameters>;
|
pub type Bls12_381 = Bls12<Config>;
|
||||||
|
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl Bls12Parameters for Parameters {
|
impl Bls12Config for Config {
|
||||||
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;
|
||||||
@@ -25,6 +26,6 @@ impl Bls12Parameters for Parameters {
|
|||||||
type Fp2Config = Fq2Config;
|
type Fp2Config = Fq2Config;
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Config = Fq6Config;
|
||||||
type Fp12Config = Fq12Config;
|
type Fp12Config = Fq12Config;
|
||||||
type G1Parameters = self::g1::Parameters;
|
type G1Config = self::g1::Config;
|
||||||
type G2Parameters = self::g2::Parameters;
|
type G2Config = self::g2::Config;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BIN
bls12_381/src/curves/tests/g1_compressed_valid_test_vectors.dat
Normal file
BIN
bls12_381/src/curves/tests/g1_compressed_valid_test_vectors.dat
Normal file
Binary file not shown.
Binary file not shown.
BIN
bls12_381/src/curves/tests/g2_compressed_valid_test_vectors.dat
Normal file
BIN
bls12_381/src/curves/tests/g2_compressed_valid_test_vectors.dat
Normal file
Binary file not shown.
Binary file not shown.
119
bls12_381/src/curves/tests/mod.rs
Executable file
119
bls12_381/src/curves/tests/mod.rs
Executable file
@@ -0,0 +1,119 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
215
bls12_381/src/curves/util.rs
Normal file
215
bls12_381/src/curves/util.rs
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
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,5 +3,7 @@ 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,7 +21,22 @@ impl Fp2Config for Fq2Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_fp_by_nonresidue(fp: &Self::Fp) -> Self::Fp {
|
fn mul_fp_by_nonresidue_in_place(fp: &mut Self::Fp) -> &mut Self::Fp {
|
||||||
-(*fp)
|
fp.neg_in_place()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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,11 +82,10 @@ 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(fe: &Fq2) -> Fq2 {
|
fn mul_fp2_by_nonresidue_in_place(fe: &mut Fq2) -> &mut Fq2 {
|
||||||
let mut copy = *fe;
|
let t0 = fe.c0;
|
||||||
let t0 = copy.c0;
|
fe.c0 -= &fe.c1;
|
||||||
copy.c0 -= &fe.c1;
|
fe.c1 += &t0;
|
||||||
copy.c1 += &t0;
|
fe
|
||||||
copy
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,5 +3,7 @@ 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,23 +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, 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},
|
||||||
rand::Rng,
|
vec,
|
||||||
test_rng, vec,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Fq, Fq12, Fq12Config, Fq2, Fq2Config, Fq6, Fq6Config, FqConfig, Fr, FrConfig};
|
use crate::{Fq, Fq12, Fq12Config, Fq2, Fq2Config, Fq6, Fq6Config, Fr};
|
||||||
|
|
||||||
generate_field_test!(bls12_381; fq2; fq6; fq12; mont(6, 4); );
|
test_field!(fr; Fr; mont_prime_field);
|
||||||
generate_field_serialization_test!(bls12_381; fq2; fq6; fq12;);
|
test_field!(fq; Fq; mont_prime_field);
|
||||||
|
test_field!(fq2; Fq2);
|
||||||
|
test_field!(fq6; Fq6);
|
||||||
|
test_field!(fq12; Fq12);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_negative_one() {
|
fn test_negative_one() {
|
||||||
@@ -1602,7 +1601,7 @@ fn test_fq2_doubling() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq2_frobenius_map() {
|
fn test_fq2_frobenius_map_in_place() {
|
||||||
let mut a = Fq2::new(
|
let mut a = Fq2::new(
|
||||||
Fq::from(BigInt::new([
|
Fq::from(BigInt::new([
|
||||||
0x2d0078036923ffc7,
|
0x2d0078036923ffc7,
|
||||||
@@ -1621,7 +1620,7 @@ fn test_fq2_frobenius_map() {
|
|||||||
0x12d1137b8a6a837,
|
0x12d1137b8a6a837,
|
||||||
])),
|
])),
|
||||||
);
|
);
|
||||||
a.frobenius_map(0);
|
a.frobenius_map_in_place(0);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
a,
|
a,
|
||||||
Fq2::new(
|
Fq2::new(
|
||||||
@@ -1643,7 +1642,7 @@ fn test_fq2_frobenius_map() {
|
|||||||
])),
|
])),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
a.frobenius_map(1);
|
a.frobenius_map_in_place(1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
a,
|
a,
|
||||||
Fq2::new(
|
Fq2::new(
|
||||||
@@ -1665,7 +1664,7 @@ fn test_fq2_frobenius_map() {
|
|||||||
])),
|
])),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
a.frobenius_map(1);
|
a.frobenius_map_in_place(1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
a,
|
a,
|
||||||
Fq2::new(
|
Fq2::new(
|
||||||
@@ -1687,7 +1686,7 @@ fn test_fq2_frobenius_map() {
|
|||||||
])),
|
])),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
a.frobenius_map(2);
|
a.frobenius_map_in_place(2);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
a,
|
a,
|
||||||
Fq2::new(
|
Fq2::new(
|
||||||
@@ -1719,7 +1718,7 @@ fn test_fq2_legendre() {
|
|||||||
// i^2 = -1
|
// i^2 = -1
|
||||||
let mut m1 = -Fq2::one();
|
let mut m1 = -Fq2::one();
|
||||||
assert_eq!(QuadraticResidue, m1.legendre());
|
assert_eq!(QuadraticResidue, m1.legendre());
|
||||||
m1 = Fq6Config::mul_fp2_by_nonresidue(&m1);
|
Fq6Config::mul_fp2_by_nonresidue_in_place(&mut m1);
|
||||||
assert_eq!(QuadraticNonResidue, m1.legendre());
|
assert_eq!(QuadraticNonResidue, m1.legendre());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1732,7 +1731,7 @@ fn test_fq2_mul_nonresidue() {
|
|||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
let mut a = Fq2::rand(&mut rng);
|
let mut a = Fq2::rand(&mut rng);
|
||||||
let mut b = a;
|
let mut b = a;
|
||||||
a = Fq6Config::mul_fp2_by_nonresidue(&a);
|
Fq6Config::mul_fp2_by_nonresidue_in_place(&mut a);
|
||||||
b.mul_assign(&nqr);
|
b.mul_assign(&nqr);
|
||||||
|
|
||||||
assert_eq!(a, b);
|
assert_eq!(a, b);
|
||||||
@@ -1748,7 +1747,7 @@ fn test_fq6_mul_nonresidue() {
|
|||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
let mut a = Fq6::rand(&mut rng);
|
let mut a = Fq6::rand(&mut rng);
|
||||||
let mut b = a;
|
let mut b = a;
|
||||||
a = Fq12Config::mul_fp6_by_nonresidue(&a);
|
Fq12Config::mul_fp6_by_nonresidue_in_place(&mut 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.3.0"
|
version = "0.4.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,20 +10,28 @@ 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 = "2018"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ark-ff = { version="^0.3.0", default-features = false }
|
ark-ff = { version="0.4.0-alpha", default-features = false }
|
||||||
ark-ec = { version="^0.3.0", default-features = false }
|
ark-ec = { version="0.4.0-alpha", default-features = false }
|
||||||
ark-std = { version="^0.3.0", 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]
|
[dev-dependencies]
|
||||||
ark-serialize = { version="^0.3.0", default-features = false }
|
ark-serialize = { version = "0.4.0-alpha", default-features = false }
|
||||||
ark-algebra-test-templates = { version="^0.3.0", default-features = false }
|
ark-algebra-test-templates = { version = "0.4.0-alpha", default-features = false }
|
||||||
|
ark-algebra-bench-templates = { version = "0.4.0-alpha", default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "curve" ]
|
default = [ "curve" ]
|
||||||
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ]
|
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ]
|
||||||
|
r1cs = [ "ark-r1cs-std" ]
|
||||||
|
|
||||||
curve = [ "scalar_field" ]
|
curve = [ "scalar_field" ]
|
||||||
scalar_field = []
|
scalar_field = []
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "bn254"
|
||||||
|
path = "benches/bn254.rs"
|
||||||
|
harness = false
|
||||||
|
|||||||
13
bn254/benches/bn254.rs
Normal file
13
bn254/benches/bn254.rs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
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,
|
||||||
|
);
|
||||||
11
bn254/src/constraints/curves.rs
Normal file
11
bn254/src/constraints/curves.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use ark_r1cs_std::groups::curves::short_weierstrass::ProjectiveVar;
|
||||||
|
|
||||||
|
use crate::{constraints::FBaseVar, g1::Config};
|
||||||
|
|
||||||
|
/// A group element in the Bn254 prime-order group.
|
||||||
|
pub type GVar = ProjectiveVar<Config, FBaseVar>;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
ark_curve_constraint_tests::curves::sw_test::<Config, GVar>().unwrap();
|
||||||
|
}
|
||||||
11
bn254/src/constraints/fields.rs
Normal file
11
bn254/src/constraints/fields.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use ark_r1cs_std::fields::fp::FpVar;
|
||||||
|
|
||||||
|
use crate::fq::Fq;
|
||||||
|
|
||||||
|
/// A variable that is the R1CS equivalent of `crate::Fq`.
|
||||||
|
pub type FBaseVar = FpVar<Fq>;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
ark_curve_constraint_tests::fields::field_test::<_, _, FBaseVar>().unwrap();
|
||||||
|
}
|
||||||
107
bn254/src/constraints/mod.rs
Normal file
107
bn254/src/constraints/mod.rs
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
//! This module implements the R1CS equivalent of `ark_bn254`.
|
||||||
|
//!
|
||||||
|
//! It implements field variables for `crate::Fq`,
|
||||||
|
//! and group variables for `crate::G1Projective`.
|
||||||
|
//!
|
||||||
|
//! The field underlying these constraints is `crate::Fq`.
|
||||||
|
//!
|
||||||
|
//! # Examples
|
||||||
|
//!
|
||||||
|
//! One can perform standard algebraic operations on `FBaseVar`:
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! # fn main() -> Result<(), ark_relations::r1cs::SynthesisError> {
|
||||||
|
//! use ark_std::UniformRand;
|
||||||
|
//! use ark_relations::r1cs::*;
|
||||||
|
//! use ark_r1cs_std::prelude::*;
|
||||||
|
//! use ark_bn254::{*, constraints::*};
|
||||||
|
//!
|
||||||
|
//! let cs = ConstraintSystem::<Fq>::new_ref();
|
||||||
|
//! // This rng is just for test purposes; do not use it
|
||||||
|
//! // in real applications.
|
||||||
|
//! let mut rng = ark_std::test_rng();
|
||||||
|
//!
|
||||||
|
//! // Generate some random `Fq` elements.
|
||||||
|
//! let a_native = Fq::rand(&mut rng);
|
||||||
|
//! let b_native = Fq::rand(&mut rng);
|
||||||
|
//!
|
||||||
|
//! // Allocate `a_native` and `b_native` as witness variables in `cs`.
|
||||||
|
//! let a = FBaseVar::new_witness(ark_relations::ns!(cs, "generate_a"), || Ok(a_native))?;
|
||||||
|
//! let b = FBaseVar::new_witness(ark_relations::ns!(cs, "generate_b"), || Ok(b_native))?;
|
||||||
|
//!
|
||||||
|
//! // Allocate `a_native` and `b_native` as constants in `cs`. This does not add any
|
||||||
|
//! // constraints or variables.
|
||||||
|
//! let a_const = FBaseVar::new_constant(ark_relations::ns!(cs, "a_as_constant"), a_native)?;
|
||||||
|
//! let b_const = FBaseVar::new_constant(ark_relations::ns!(cs, "b_as_constant"), b_native)?;
|
||||||
|
//!
|
||||||
|
//! let one = FBaseVar::one();
|
||||||
|
//! let zero = FBaseVar::zero();
|
||||||
|
//!
|
||||||
|
//! // Sanity check one + one = two
|
||||||
|
//! let two = &one + &one + &zero;
|
||||||
|
//! two.enforce_equal(&one.double()?)?;
|
||||||
|
//!
|
||||||
|
//! assert!(cs.is_satisfied()?);
|
||||||
|
//!
|
||||||
|
//! // Check that the value of &a + &b is correct.
|
||||||
|
//! assert_eq!((&a + &b).value()?, a_native + &b_native);
|
||||||
|
//!
|
||||||
|
//! // Check that the value of &a * &b is correct.
|
||||||
|
//! assert_eq!((&a * &b).value()?, a_native * &b_native);
|
||||||
|
//!
|
||||||
|
//! // Check that operations on variables and constants are equivalent.
|
||||||
|
//! (&a + &b).enforce_equal(&(&a_const + &b_const))?;
|
||||||
|
//! assert!(cs.is_satisfied()?);
|
||||||
|
//! # Ok(())
|
||||||
|
//! # }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! One can also perform standard algebraic operations on `GVar`:
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! # fn main() -> Result<(), ark_relations::r1cs::SynthesisError> {
|
||||||
|
//! # use ark_std::UniformRand;
|
||||||
|
//! # use ark_relations::r1cs::*;
|
||||||
|
//! # use ark_r1cs_std::prelude::*;
|
||||||
|
//! # use ark_bn254::{*, constraints::*};
|
||||||
|
//!
|
||||||
|
//! # let cs = ConstraintSystem::<Fq>::new_ref();
|
||||||
|
//! # let mut rng = ark_std::test_rng();
|
||||||
|
//!
|
||||||
|
//! // Generate some random `G1Projective` elements.
|
||||||
|
//! let a_native = G1Projective::rand(&mut rng);
|
||||||
|
//! let b_native = G1Projective::rand(&mut rng);
|
||||||
|
//!
|
||||||
|
//! // Allocate `a_native` and `b_native` as witness variables in `cs`.
|
||||||
|
//! let a = GVar::new_witness(ark_relations::ns!(cs, "a"), || Ok(a_native))?;
|
||||||
|
//! let b = GVar::new_witness(ark_relations::ns!(cs, "b"), || Ok(b_native))?;
|
||||||
|
//!
|
||||||
|
//! // Allocate `a_native` and `b_native` as constants in `cs`. This does not add any
|
||||||
|
//! // constraints or variables.
|
||||||
|
//! let a_const = GVar::new_constant(ark_relations::ns!(cs, "a_as_constant"), a_native)?;
|
||||||
|
//! let b_const = GVar::new_constant(ark_relations::ns!(cs, "b_as_constant"), b_native)?;
|
||||||
|
//!
|
||||||
|
//! // This returns the identity.
|
||||||
|
//! let zero = GVar::zero();
|
||||||
|
//!
|
||||||
|
//! // Sanity check one + one = two
|
||||||
|
//! let two_a = &a + &a + &zero;
|
||||||
|
//! two_a.enforce_equal(&a.double()?)?;
|
||||||
|
//!
|
||||||
|
//! assert!(cs.is_satisfied()?);
|
||||||
|
//!
|
||||||
|
//! // Check that the value of &a + &b is correct.
|
||||||
|
//! assert_eq!((&a + &b).value()?, a_native + &b_native);
|
||||||
|
//!
|
||||||
|
//! // Check that operations on variables and constants are equivalent.
|
||||||
|
//! (&a + &b).enforce_equal(&(&a_const + &b_const))?;
|
||||||
|
//! assert!(cs.is_satisfied()?);
|
||||||
|
//! # Ok(())
|
||||||
|
//! # }
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
mod curves;
|
||||||
|
mod fields;
|
||||||
|
|
||||||
|
pub use curves::*;
|
||||||
|
pub use fields::*;
|
||||||
@@ -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 Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
pub type G1Affine = Affine<Parameters>;
|
pub type G1Affine = Affine<Config>;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ impl CurveConfig for Parameters {
|
|||||||
const COFACTOR_INV: Fr = Fr::ONE;
|
const COFACTOR_INV: Fr = Fr::ONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
impl SWCurveConfig for Config {
|
||||||
/// 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 Parameters {
|
|||||||
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<Parameters>;
|
pub type G2Affine = Affine<Config>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq2;
|
type BaseField = Fq2;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ impl CurveConfig for Parameters {
|
|||||||
MontFp!("10944121435919637613327163357776759465618812564592884533313067514031822496649");
|
MontFp!("10944121435919637613327163357776759465618812564592884533313067514031822496649");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
impl SWCurveConfig for Config {
|
||||||
/// 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 Parameters {
|
|||||||
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, BnParameters, TwistType},
|
bn::{Bn, BnConfig, 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 Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl BnParameters for Parameters {
|
impl BnConfig for Config {
|
||||||
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 BnParameters for Parameters {
|
|||||||
type Fp2Config = Fq2Config;
|
type Fp2Config = Fq2Config;
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Config = Fq6Config;
|
||||||
type Fp12Config = Fq12Config;
|
type Fp12Config = Fq12Config;
|
||||||
type G1Parameters = g1::Parameters;
|
type G1Config = g1::Config;
|
||||||
type G2Parameters = g2::Parameters;
|
type G2Config = g2::Config;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Bn254 = Bn<Parameters>;
|
pub type Bn254 = Bn<Config>;
|
||||||
|
|
||||||
pub type G1Affine = bn::G1Affine<Parameters>;
|
pub type G1Affine = bn::G1Affine<Config>;
|
||||||
pub type G1Projective = bn::G1Projective<Parameters>;
|
pub type G1Projective = bn::G1Projective<Config>;
|
||||||
pub type G2Affine = bn::G2Affine<Parameters>;
|
pub type G2Affine = bn::G2Affine<Config>;
|
||||||
pub type G2Projective = bn::G2Projective<Parameters>;
|
pub type G2Projective = bn::G2Projective<Config>;
|
||||||
|
|||||||
@@ -1,16 +1,9 @@
|
|||||||
use ark_algebra_test_templates::{
|
use ark_algebra_test_templates::*;
|
||||||
curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, msm::*,
|
use ark_ff::fields::Field;
|
||||||
};
|
|
||||||
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::{g1, g2, Bn254, Fq12, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
|
use crate::{Bn254, G1Projective, G2Projective};
|
||||||
|
|
||||||
generate_g1_test!(bn254; curve_tests; sw_tests;);
|
test_group!(g1; G1Projective; sw);
|
||||||
generate_g2_test!(bn254; curve_tests; sw_tests;);
|
test_group!(g2; G2Projective; sw);
|
||||||
generate_bilinearity_test!(Bn254, Fq12);
|
test_group!(pairing_output; ark_ec::pairing::PairingOutput<Bn254>; msm);
|
||||||
|
test_pairing!(pairing; crate::Bn254);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ impl Fp2Config for Fq2Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_fp_by_nonresidue(fe: &Self::Fp) -> Self::Fp {
|
fn mul_fp_by_nonresidue_in_place(fe: &mut Self::Fp) -> &mut Self::Fp {
|
||||||
-(*fe)
|
fe.neg_in_place()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,12 +90,16 @@ impl Fp6Config for Fq6Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_fp2_by_nonresidue(fe: &Fq2) -> Fq2 {
|
fn mul_fp2_by_nonresidue_in_place(fe: &mut Fq2) -> &mut 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 c0 = f.c0 + fe.c0 + Fq2Config::mul_fp_by_nonresidue(&fe.c1);
|
let mut c0 = 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;
|
||||||
Fq2::new(c0, c1)
|
*fe = Fq2::new(c0, c1);
|
||||||
|
fe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,21 @@
|
|||||||
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_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
use ark_std::{
|
||||||
use ark_std::{rand::Rng, test_rng};
|
|
||||||
use core::{
|
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
ops::{AddAssign, MulAssign, SubAssign},
|
ops::{AddAssign, MulAssign},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Config, FqConfig, Fr, FrConfig};
|
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Config, Fr};
|
||||||
|
|
||||||
generate_field_test!(bn254; fq2; fq6; fq12; mont(4, 4); );
|
test_field!(fr; Fr; mont_prime_field);
|
||||||
generate_field_serialization_test!(bn254; fq2; fq6; fq12;);
|
test_field!(fq; Fq; mont_prime_field);
|
||||||
|
test_field!(fq2; Fq2);
|
||||||
|
test_field!(fq6; Fq6);
|
||||||
|
test_field!(fq12; Fq12);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_from() {
|
fn test_fq_repr_from() {
|
||||||
@@ -140,7 +139,7 @@ fn test_fq2_legendre() {
|
|||||||
// i^2 = -1
|
// i^2 = -1
|
||||||
let mut m1 = -Fq2::one();
|
let mut m1 = -Fq2::one();
|
||||||
assert_eq!(QuadraticResidue, m1.legendre());
|
assert_eq!(QuadraticResidue, m1.legendre());
|
||||||
m1 = Fq6Config::mul_fp2_by_nonresidue(&m1);
|
Fq6Config::mul_fp2_by_nonresidue_in_place(&mut m1);
|
||||||
assert_eq!(QuadraticNonResidue, m1.legendre());
|
assert_eq!(QuadraticNonResidue, m1.legendre());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,3 +41,6 @@ mod fields;
|
|||||||
pub use curves::*;
|
pub use curves::*;
|
||||||
|
|
||||||
pub use fields::*;
|
pub use fields::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "r1cs")]
|
||||||
|
pub mod constraints;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-bw6-761"
|
name = "ark-bw6-761"
|
||||||
version = "0.3.0"
|
version = "0.4.0-alpha.2"
|
||||||
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,18 +10,24 @@ 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 = "2018"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ark-ff = { version="^0.3.0", default-features = false }
|
ark-ff = { version="0.4.0-alpha", default-features = false }
|
||||||
ark-ec = { version="^0.3.0", default-features = false }
|
ark-ec = { version="0.4.0-alpha", default-features = false }
|
||||||
ark-std = { version="^0.3.0", default-features = false }
|
ark-std = { version = "0.4.0-alpha", default-features = false }
|
||||||
ark-bls12-377 = { version="^0.3.0", path = "../bls12_377", default-features = false, features = [ "base_field" ] }
|
ark-bls12-377 = { version = "0.4.0-alpha", path = "../bls12_377", default-features = false, features = [ "base_field" ] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ark-serialize = { version="^0.3.0", default-features = false }
|
ark-serialize = { version = "0.4.0-alpha", default-features = false }
|
||||||
ark-algebra-test-templates = { version="^0.3.0", default-features = false }
|
ark-algebra-test-templates = { version = "0.4.0-alpha", 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
|
||||||
|
|||||||
16
bw6_761/benches/bw6_761.rs
Normal file
16
bw6_761/benches/bw6_761.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
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<Parameters>;
|
pub type G1Affine = Affine<Config>;
|
||||||
pub type G1Projective = Projective<Parameters>;
|
pub type G1Projective = Projective<Config>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ impl CurveConfig for Parameters {
|
|||||||
const COFACTOR_INV: Fr = MontFp!("91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804");
|
const COFACTOR_INV: Fr = MontFp!("91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
impl SWCurveConfig for Config {
|
||||||
/// 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 Parameters {
|
|||||||
/// 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<Parameters>;
|
pub type G2Affine = Affine<Config>;
|
||||||
pub type G2Projective = Projective<Parameters>;
|
pub type G2Projective = Projective<Config>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ impl CurveConfig for Parameters {
|
|||||||
const COFACTOR_INV: Fr = MontFp!("214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124");
|
const COFACTOR_INV: Fr = MontFp!("214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
impl SWCurveConfig for Config {
|
||||||
/// 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 Parameters {
|
|||||||
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::{BW6Parameters, TwistType, BW6},
|
bw6::{BW6Config, 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 Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl BW6Parameters for Parameters {
|
impl BW6Config for Config {
|
||||||
const X: BigInteger = BigInt::new([
|
const X: BigInteger = BigInt::new([
|
||||||
0x8508c00000000001,
|
0x8508c00000000001,
|
||||||
0x0,
|
0x0,
|
||||||
@@ -50,13 +50,13 @@ impl BW6Parameters for Parameters {
|
|||||||
type Fp = Fq;
|
type Fp = Fq;
|
||||||
type Fp3Config = Fq3Config;
|
type Fp3Config = Fq3Config;
|
||||||
type Fp6Config = Fq6Config;
|
type Fp6Config = Fq6Config;
|
||||||
type G1Parameters = g1::Parameters;
|
type G1Config = g1::Config;
|
||||||
type G2Parameters = g2::Parameters;
|
type G2Config = g2::Config;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type BW6_761 = BW6<Parameters>;
|
pub type BW6_761 = BW6<Config>;
|
||||||
|
|
||||||
pub type G1Affine = bw6::G1Affine<Parameters>;
|
pub type G1Affine = bw6::G1Affine<Config>;
|
||||||
pub type G1Projective = bw6::G1Projective<Parameters>;
|
pub type G1Projective = bw6::G1Projective<Config>;
|
||||||
pub type G2Affine = bw6::G2Affine<Parameters>;
|
pub type G2Affine = bw6::G2Affine<Config>;
|
||||||
pub type G2Projective = bw6::G2Projective<Parameters>;
|
pub type G2Projective = bw6::G2Projective<Config>;
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
use ark_algebra_test_templates::{
|
|
||||||
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::*;
|
||||||
|
use ark_algebra_test_templates::*;
|
||||||
|
use ark_ff::Field;
|
||||||
|
|
||||||
generate_g1_test!(bw6_761; curve_tests; sw_tests;);
|
test_group!(g1; G1Projective; sw);
|
||||||
generate_g2_test!(bw6_761; curve_tests; sw_tests;);
|
test_group!(g2; G2Projective; sw);
|
||||||
generate_bilinearity_test!(BW6_761, Fq6);
|
test_group!(pairing_output; ark_ec::pairing::PairingOutput<BW6_761>; msm);
|
||||||
|
test_pairing!(pairing; crate::BW6_761);
|
||||||
|
|||||||
@@ -82,9 +82,7 @@ impl Fp3Config for Fq3Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_fp_by_nonresidue(fe: &Self::Fp) -> Self::Fp {
|
fn mul_fp_by_nonresidue_in_place(fe: &mut Self::Fp) -> &mut Self::Fp {
|
||||||
let original = -(*fe);
|
fe.double_in_place().double_in_place().neg_in_place()
|
||||||
let double = original + &original;
|
|
||||||
double + &double
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
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};
|
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use ark_algebra_test_templates::*;
|
||||||
|
|
||||||
generate_field_test!(bw6_761; fq3; fq6_2_on_3; false; mont(12, 6); );
|
test_field!(fr; Fr; mont_prime_field);
|
||||||
generate_field_serialization_test!(bw6_761;);
|
test_field!(fq; Fq; mont_prime_field);
|
||||||
|
test_field!(fq3; Fq3);
|
||||||
|
test_field!(fq6; Fq6);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-cp6-782"
|
name = "ark-cp6-782"
|
||||||
version = "0.3.0"
|
version = "0.4.0-alpha.2"
|
||||||
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,18 +10,25 @@ 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 = "2018"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ark-ff = { version = "^0.3.0", default-features = false }
|
ark-ff = { version = "0.4.0-alpha", default-features = false }
|
||||||
ark-ec = { version = "^0.3.0", default-features = false }
|
ark-ec = { version = "0.4.0-alpha", default-features = false }
|
||||||
ark-std = { version = "^0.3.0", default-features = false }
|
ark-std = { version = "0.4.0-alpha", default-features = false }
|
||||||
ark-bls12-377 = { version = "^0.3.0", path = "../bls12_377", default-features = false, features = [ "base_field" ] }
|
ark-bls12-377 = { version = "0.4.0-alpha", 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-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 = "cp6_782"
|
||||||
|
path = "benches/cp6_782.rs"
|
||||||
|
harness = false
|
||||||
|
|||||||
1
cp6_782/LICENSE-APACHE
Symbolic link
1
cp6_782/LICENSE-APACHE
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../LICENSE-APACHE
|
||||||
1
cp6_782/LICENSE-MIT
Symbolic link
1
cp6_782/LICENSE-MIT
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../LICENSE-MIT
|
||||||
15
cp6_782/benches/cp6_782.rs
Normal file
15
cp6_782/benches/cp6_782.rs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
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,18 +1,60 @@
|
|||||||
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<Parameters>;
|
pub type G1Affine = Affine<Config>;
|
||||||
pub type G1Projective = Projective<Parameters>;
|
pub type G1Projective = Projective<Config>;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize)]
|
||||||
|
pub struct G1Prepared(pub G1Affine);
|
||||||
|
|
||||||
|
impl From<G1Affine> for G1Prepared {
|
||||||
|
fn from(other: G1Affine) -> Self {
|
||||||
|
G1Prepared(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<G1Projective> for G1Prepared {
|
||||||
|
fn from(q: G1Projective) -> Self {
|
||||||
|
q.into_affine().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a G1Affine> for G1Prepared {
|
||||||
|
fn from(other: &'a G1Affine) -> Self {
|
||||||
|
G1Prepared(*other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a G1Projective> for G1Prepared {
|
||||||
|
fn from(q: &'a G1Projective) -> Self {
|
||||||
|
q.into_affine().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl G1Prepared {
|
||||||
|
pub fn is_zero(&self) -> bool {
|
||||||
|
self.0.is_zero()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for G1Prepared {
|
||||||
|
fn default() -> Self {
|
||||||
|
G1Prepared(G1Affine::generator())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -34,7 +76,7 @@ impl CurveConfig for Parameters {
|
|||||||
const COFACTOR_INV: Fr = MontFp!("163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788");
|
const COFACTOR_INV: Fr = MontFp!("163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
impl SWCurveConfig for Config {
|
||||||
/// COEFF_A = 5
|
/// COEFF_A = 5
|
||||||
const COEFF_A: Fq = MontFp!("5");
|
const COEFF_A: Fq = MontFp!("5");
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,60 @@
|
|||||||
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<Parameters>;
|
pub type G2Affine = Affine<Config>;
|
||||||
pub type G2Projective = Projective<Parameters>;
|
pub type G2Projective = Projective<Config>;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize)]
|
||||||
|
pub struct G2Prepared(pub G2Affine);
|
||||||
|
|
||||||
|
impl From<G2Affine> for G2Prepared {
|
||||||
|
fn from(other: G2Affine) -> Self {
|
||||||
|
G2Prepared(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<G2Projective> for G2Prepared {
|
||||||
|
fn from(q: G2Projective) -> Self {
|
||||||
|
q.into_affine().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a G2Affine> for G2Prepared {
|
||||||
|
fn from(other: &'a G2Affine) -> Self {
|
||||||
|
G2Prepared(*other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a G2Projective> for G2Prepared {
|
||||||
|
fn from(q: &'a G2Projective) -> Self {
|
||||||
|
q.into_affine().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl G2Prepared {
|
||||||
|
pub fn is_zero(&self) -> bool {
|
||||||
|
self.0.is_zero()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for G2Prepared {
|
||||||
|
fn default() -> Self {
|
||||||
|
G2Prepared(G2Affine::generator())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl CurveConfig for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq3;
|
type BaseField = Fq3;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
|
|
||||||
@@ -58,7 +100,7 @@ impl CurveConfig for Parameters {
|
|||||||
const COFACTOR_INV: Fr = MontFp!("45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598");
|
const COFACTOR_INV: Fr = MontFp!("45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SWCurveConfig for Parameters {
|
impl SWCurveConfig for Config {
|
||||||
/// 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,17 +1,19 @@
|
|||||||
use ark_ec::{models::short_weierstrass::SWCurveConfig, PairingEngine};
|
use ark_ec::{
|
||||||
use ark_ff::{
|
models::short_weierstrass::SWCurveConfig,
|
||||||
biginteger::BigInteger832,
|
pairing::{MillerLoopOutput, Pairing, PairingOutput},
|
||||||
fields::{BitIteratorBE, Field},
|
|
||||||
BigInt, One,
|
|
||||||
};
|
};
|
||||||
|
use ark_ff::{
|
||||||
|
biginteger::BigInteger832, BigInt, BitIteratorBE, CyclotomicMultSubgroup, Field, 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, G1Projective};
|
pub use self::g1::{G1Affine, G1Prepared, G1Projective};
|
||||||
|
|
||||||
pub mod g2;
|
pub mod g2;
|
||||||
pub use self::g2::{G2Affine, G2Projective};
|
pub use self::g2::{G2Affine, G2Prepared, G2Projective};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
@@ -21,40 +23,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 PairingEngine for CP6_782 {
|
impl Pairing for CP6_782 {
|
||||||
type Fr = Fr;
|
type ScalarField = Fr;
|
||||||
type G1Projective = G1Projective;
|
type BaseField = Fq;
|
||||||
|
type G1 = G1Projective;
|
||||||
type G1Affine = G1Affine;
|
type G1Affine = G1Affine;
|
||||||
type G1Prepared = G1Affine;
|
type G1Prepared = G1Prepared;
|
||||||
type G2Projective = G2Projective;
|
type G2 = G2Projective;
|
||||||
type G2Affine = G2Affine;
|
type G2Affine = G2Affine;
|
||||||
type G2Prepared = G2Affine;
|
type G2Prepared = G2Prepared;
|
||||||
type Fq = Fq;
|
type TargetField = Fq6;
|
||||||
type Fqe = Fq3;
|
|
||||||
type Fqk = Fq6;
|
|
||||||
|
|
||||||
fn miller_loop<'a, I>(i: I) -> Self::Fqk
|
fn multi_miller_loop(
|
||||||
where
|
a: impl IntoIterator<Item = impl Into<Self::G1Prepared>>,
|
||||||
I: IntoIterator<Item = &'a (Self::G1Prepared, Self::G2Prepared)>,
|
b: impl IntoIterator<Item = impl Into<Self::G2Prepared>>,
|
||||||
{
|
) -> MillerLoopOutput<Self> {
|
||||||
let mut result = Self::Fqk::one();
|
let mut result = Self::TargetField::one();
|
||||||
for &(ref p, ref q) in i {
|
a.into_iter().zip_eq(b).for_each(|(p, q)| {
|
||||||
result *= &CP6_782::ate_miller_loop(p, q);
|
let (p, q) = (p.into(), q.into());
|
||||||
}
|
result *= &CP6_782::ate_miller_loop(&p, &q);
|
||||||
result
|
});
|
||||||
|
|
||||||
|
MillerLoopOutput(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn final_exponentiation(r: &Self::Fqk) -> Option<Self::Fqk> {
|
fn final_exponentiation(r: MillerLoopOutput<Self>) -> Option<PairingOutput<Self>> {
|
||||||
Some(CP6_782::final_exponentiation(r))
|
Some(PairingOutput(CP6_782::final_exponentiation(&r.0)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CP6_782 {
|
impl CP6_782 {
|
||||||
pub fn ate_pairing(p: &G1Affine, q: &G2Affine) -> GT {
|
fn ate_miller_loop(p: &G1Prepared, q: &G2Prepared) -> Fq6 {
|
||||||
CP6_782::final_exponentiation(&CP6_782::ate_miller_loop(p, q))
|
let p = p.0;
|
||||||
}
|
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;
|
||||||
@@ -76,7 +78,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::Parameters::COEFF_A;
|
let old_rx_square_3_a = old_rx_square_3 + &g2::Config::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;
|
||||||
@@ -127,19 +129,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(3);
|
elt_q3.frobenius_map_in_place(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(1);
|
alpha.frobenius_map_in_place(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(1);
|
elt_q.frobenius_map_in_place(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,13 +1,9 @@
|
|||||||
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;
|
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
generate_g1_test!(cp6_782; curve_tests; sw_tests;);
|
test_group!(g1; G1Projective; sw);
|
||||||
generate_g2_test!(cp6_782; curve_tests; sw_tests;);
|
test_group!(g2; G2Projective; sw);
|
||||||
generate_bilinearity_test!(CP6_782, Fq6);
|
test_group!(pairing_output; ark_ec::pairing::PairingOutput<CP6_782>; msm);
|
||||||
|
test_pairing!(pairing; crate::CP6_782);
|
||||||
|
|||||||
@@ -77,11 +77,12 @@ impl Fp3Config for Fq3Config {
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_fp_by_nonresidue(fe: &Self::Fp) -> Self::Fp {
|
fn mul_fp_by_nonresidue_in_place(fe: &mut Self::Fp) -> &mut Self::Fp {
|
||||||
let original = *fe;
|
let original = *fe;
|
||||||
let mut four_fe = fe.double();
|
fe.double_in_place();
|
||||||
four_fe.double_in_place();
|
*fe += original;
|
||||||
let eight_fe = four_fe.double();
|
fe.double_in_place().double_in_place();
|
||||||
eight_fe + &four_fe + &original
|
*fe += original;
|
||||||
|
fe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
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};
|
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use ark_algebra_test_templates::*;
|
||||||
|
|
||||||
generate_field_test!(cp6_782; fq3; fq6_2_on_3; mont(13, 6); );
|
test_field!(fr; Fr; mont_prime_field);
|
||||||
generate_field_serialization_test!(cp6_782;);
|
test_field!(fq; Fq; mont_prime_field);
|
||||||
|
test_field!(fq3; Fq3);
|
||||||
|
test_field!(fq6; Fq6);
|
||||||
|
|||||||
@@ -1,115 +0,0 @@
|
|||||||
[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
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
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);
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
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);
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
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);
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
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);
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
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);
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
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);
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
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);
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
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);
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
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);
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
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);
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
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);
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
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);
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#![allow(unused_macros, unused_imports)]
|
|
||||||
#[macro_use]
|
|
||||||
pub mod macros;
|
|
||||||
pub use macros::*;
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
pub extern crate bencher;
|
|
||||||
pub use bencher::*;
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
#[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,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,455 +0,0 @@
|
|||||||
#[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]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#[macro_use]
|
|
||||||
mod utils;
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
mod ec;
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
mod field;
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
mod pairing;
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
#[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,);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#[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.3.0"
|
version = "0.4.0-alpha.2"
|
||||||
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 = "2018"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ark-std = { version = "^0.3.0", default-features = false }
|
ark-std = { version = "0.4.0-alpha", default-features = false }
|
||||||
ark-serialize = { version = "^0.3.0", default-features = false }
|
ark-serialize = { version = "0.4.0-alpha", default-features = false }
|
||||||
ark-ff = { version = "^0.3.0", default-features = false }
|
ark-ff = { version = "0.4.0-alpha", default-features = false }
|
||||||
ark-relations = { version = "^0.3.0", default-features = false }
|
ark-relations = { version = "0.4.0-alpha", default-features = false }
|
||||||
ark-r1cs-std = { version = "^0.3.0", default-features = false }
|
ark-r1cs-std = { version = "0.4.0-alpha", default-features = false }
|
||||||
ark-ec = { version = "^0.3.0", default-features = false }
|
ark-ec = { version = "0.4.0-alpha", default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
|||||||
1
curve-constraint-tests/LICENSE-APACHE
Symbolic link
1
curve-constraint-tests/LICENSE-APACHE
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../LICENSE-APACHE
|
||||||
1
curve-constraint-tests/LICENSE-MIT
Symbolic link
1
curve-constraint-tests/LICENSE-MIT
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../LICENSE-MIT
|
||||||
81
curve-constraint-tests/src/lib.rs
Executable file → Normal file
81
curve-constraint-tests/src/lib.rs
Executable file → Normal 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(i);
|
a.frobenius_map_in_place(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,
|
||||||
ProjectiveCurve,
|
CurveGroup, Group,
|
||||||
};
|
};
|
||||||
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: ProjectiveCurve,
|
C: CurveGroup,
|
||||||
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,8 +321,10 @@ pub mod curves {
|
|||||||
*limb = u64::MAX;
|
*limb = u64::MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
let modulus_last_limb_bits = <C::ScalarField as PrimeField>::MODULUS_BIT_SIZE % 64;
|
let modulus_num_bits_mod_64 = <C::ScalarField as PrimeField>::MODULUS_BIT_SIZE % 64;
|
||||||
*max.last_mut().unwrap() >>= 64 - modulus_last_limb_bits;
|
if modulus_num_bits_mod_64 != 0 {
|
||||||
|
*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()
|
||||||
@@ -340,7 +342,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(scalar);
|
let native_result = a_native.mul_bigint(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();
|
||||||
@@ -512,18 +514,21 @@ pub mod curves {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod pairing {
|
pub mod pairing {
|
||||||
use ark_ec::{PairingEngine, ProjectiveCurve};
|
use ark_ec::{
|
||||||
|
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: PairingEngine, P: PairingVar<E>>() -> Result<(), SynthesisError>
|
pub fn bilinearity_test<E: Pairing, P: PairingVar<E>>() -> Result<(), SynthesisError>
|
||||||
where
|
where
|
||||||
for<'a> &'a P::G1Var: GroupOpsBounds<'a, E::G1Projective, P::G1Var>,
|
for<'a> &'a P::G1Var: GroupOpsBounds<'a, E::G1, P::G1Var>,
|
||||||
for<'a> &'a P::G2Var: GroupOpsBounds<'a, E::G2Projective, P::G2Var>,
|
for<'a> &'a P::G2Var: GroupOpsBounds<'a, E::G2, P::G2Var>,
|
||||||
for<'a> &'a P::GTVar: FieldOpsBounds<'a, E::Fqk, P::GTVar>,
|
for<'a> &'a P::GTVar: FieldOpsBounds<'a, E::TargetField, P::GTVar>,
|
||||||
{
|
{
|
||||||
let modes = [
|
let modes = [
|
||||||
AllocationMode::Input,
|
AllocationMode::Input,
|
||||||
@@ -531,12 +536,12 @@ pub mod pairing {
|
|||||||
AllocationMode::Constant,
|
AllocationMode::Constant,
|
||||||
];
|
];
|
||||||
for &mode in &modes {
|
for &mode in &modes {
|
||||||
let cs = ConstraintSystem::<E::Fq>::new_ref();
|
let cs = ConstraintSystem::<<E::G1 as CurveGroup>::BaseField>::new_ref();
|
||||||
|
|
||||||
let mut rng = test_rng();
|
let mut rng = test_rng();
|
||||||
let a = E::G1Projective::rand(&mut rng);
|
let a = E::G1::rand(&mut rng);
|
||||||
let b = E::G2Projective::rand(&mut rng);
|
let b = E::G2::rand(&mut rng);
|
||||||
let s = E::Fr::rand(&mut rng);
|
let s = E::ScalarField::rand(&mut rng);
|
||||||
|
|
||||||
let mut sa = a;
|
let mut sa = a;
|
||||||
sa *= s;
|
sa *= s;
|
||||||
@@ -578,7 +583,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 = ans_n.pow(s.into_bigint());
|
ans_n = PairingOutput(ans_n.0.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)
|
||||||
@@ -587,12 +592,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, "Failed native test 1");
|
assert_eq!(ans1_g.value()?, ans1_n.0, "Failed native test 1");
|
||||||
assert_eq!(ans2_g.value()?, ans2_n, "Failed native test 2");
|
assert_eq!(ans2_g.value()?, ans2_n.0, "Failed native test 2");
|
||||||
assert_eq!(ans3_g.value()?, ans3_n, "Failed native test 3");
|
assert_eq!(ans3_g.value()?, ans3_n.0, "Failed native test 3");
|
||||||
|
|
||||||
assert_eq!(ans1_n, ans2_n, "Failed ans1_native == ans2_native");
|
assert_eq!(ans1_n.0, ans2_n.0, "Failed ans1_native == ans2_native");
|
||||||
assert_eq!(ans2_n, ans3_n, "Failed ans2_native == ans3_native");
|
assert_eq!(ans2_n.0, ans3_n.0, "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");
|
||||||
@@ -609,4 +614,38 @@ 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(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
30
curve25519/Cargo.toml
Normal file
30
curve25519/Cargo.toml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
[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
curve25519/LICENSE-APACHE
Symbolic link
1
curve25519/LICENSE-APACHE
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../LICENSE-APACHE
|
||||||
1
curve25519/LICENSE-MIT
Symbolic link
1
curve25519/LICENSE-MIT
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../LICENSE-MIT
|
||||||
91
curve25519/scripts/fr.ipynb
Normal file
91
curve25519/scripts/fr.ipynb
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
{
|
||||||
|
"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
|
||||||
|
}
|
||||||
162
curve25519/scripts/g1.ipynb
Normal file
162
curve25519/scripts/g1.ipynb
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
{
|
||||||
|
"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
|
||||||
|
}
|
||||||
14
curve25519/src/constraints/curves.rs
Normal file
14
curve25519/src/constraints/curves.rs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
11
curve25519/src/constraints/fields.rs
Normal file
11
curve25519/src/constraints/fields.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
8
curve25519/src/constraints/mod.rs
Normal file
8
curve25519/src/constraints/mod.rs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
//! 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::*;
|
||||||
71
curve25519/src/curves/mod.rs
Normal file
71
curve25519/src/curves/mod.rs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
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");
|
||||||
4
curve25519/src/curves/tests.rs
Normal file
4
curve25519/src/curves/tests.rs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
use crate::*;
|
||||||
|
use ark_algebra_test_templates::*;
|
||||||
|
|
||||||
|
test_group!(te; EdwardsProjective; te);
|
||||||
9
curve25519/src/fields/fq.rs
Normal file
9
curve25519/src/fields/fq.rs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
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>>;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user