mirror of
https://github.com/arnaucube/ark-curves-cherry-picked.git
synced 2026-01-27 22:23:48 +01:00
Compare commits
65 Commits
sjoseph/bi
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2d16a27e2 | ||
|
|
7854883b47 | ||
|
|
ccf83923f8 | ||
|
|
0a64024ebc | ||
|
|
8c0256ac9c | ||
|
|
72a18b6ecf | ||
|
|
8765798eb0 | ||
|
|
7e4b4bf027 | ||
|
|
4d1e504025 | ||
|
|
fc8379d9ed | ||
|
|
a0bd36f781 | ||
|
|
1ce1fcf70f | ||
|
|
379f23070c | ||
|
|
7e58260618 | ||
|
|
3fded1fbcc | ||
|
|
32b487e7fd | ||
|
|
5a41d7f27a | ||
|
|
4ab8ba6eb7 | ||
|
|
ab9be6d8f4 | ||
|
|
d5447dec42 | ||
|
|
3668338023 | ||
|
|
69a9c3513b | ||
|
|
bf8c488263 | ||
|
|
0d2142c001 | ||
|
|
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 | ||
|
|
e75546313a | ||
|
|
67d5a8582e | ||
|
|
93e64df895 | ||
|
|
76579d0fbb | ||
|
|
9a89ea8adc | ||
|
|
5a1e16e2b7 | ||
|
|
1551d6d76c | ||
|
|
d0dc200f22 | ||
|
|
6a5cf1d84a | ||
|
|
d1ced15cc2 | ||
|
|
677b4ae751 | ||
|
|
c5547905d0 | ||
|
|
f1e36c5bed | ||
|
|
3a0f858adb |
135
.github/workflows/ci.yml
vendored
135
.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
|
||||||
@@ -50,7 +50,7 @@ jobs:
|
|||||||
toolchain: ${{ matrix.rust }}
|
toolchain: ${{ matrix.rust }}
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
- uses: actions/cache@v2
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/registry
|
~/.cargo/registry
|
||||||
@@ -79,14 +79,13 @@ jobs:
|
|||||||
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
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
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,130 @@ jobs:
|
|||||||
exclude:
|
exclude:
|
||||||
- dir: scripts/
|
- dir: scripts/
|
||||||
- dir: curve-constraint-tests/
|
- dir: curve-constraint-tests/
|
||||||
- dir: curve-benches/
|
- dir: mnt4_753/
|
||||||
|
- dir: mnt6_753/
|
||||||
|
- dir: cp6_782/
|
||||||
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
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Check if source code updated
|
||||||
|
uses: dorny/paths-filter@v2.11.1
|
||||||
|
id: check-diff
|
||||||
|
with:
|
||||||
|
filters: |
|
||||||
|
mnt4_753_is_updated:
|
||||||
|
- 'mnt4_753/**'
|
||||||
|
|
||||||
|
- name: Generate lockfile
|
||||||
|
run: cargo generate-lockfile
|
||||||
|
|
||||||
|
- name: Check if deps updated
|
||||||
|
id: deps-updated
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/registry
|
||||||
|
~/.cargo/git
|
||||||
|
target
|
||||||
|
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
|
- name: Conditionally run the tests
|
||||||
|
# if source code updated OR dependencies updated
|
||||||
|
if: ${{ steps.check-diff.outputs.mnt4_753_is_updated == 'true' || steps.deps-updated.outputs.cache-hit != 'true' }}
|
||||||
|
run: |
|
||||||
|
cd mnt4_753/
|
||||||
|
cargo test --all-features
|
||||||
|
|
||||||
|
test-mnt6-753:
|
||||||
|
name: Test (mnt6_753/)
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Check if source code updated
|
||||||
|
uses: dorny/paths-filter@v2.11.1
|
||||||
|
id: check-diff
|
||||||
|
with:
|
||||||
|
filters: |
|
||||||
|
mnt6_753_is_updated:
|
||||||
|
- 'mnt6_753/**'
|
||||||
|
|
||||||
|
- name: Generate lockfile
|
||||||
|
run: cargo generate-lockfile
|
||||||
|
|
||||||
|
- name: Check if deps updated
|
||||||
|
id: deps-updated
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/registry
|
||||||
|
~/.cargo/git
|
||||||
|
target
|
||||||
|
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
|
- name: Conditionally run the tests
|
||||||
|
# if source code updated OR dependencies updated
|
||||||
|
if: ${{ steps.check-diff.outputs.mnt6_753_is_updated == 'true' || steps.deps-updated.outputs.cache-hit != 'true' }}
|
||||||
|
run: |
|
||||||
|
cd mnt6_753/
|
||||||
|
cargo test --all-features
|
||||||
|
|
||||||
|
test-cp6_782:
|
||||||
|
name: Test (cp6_782/)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Check if source code updated
|
||||||
|
uses: dorny/paths-filter@v2.11.1
|
||||||
|
id: check-diff
|
||||||
|
with:
|
||||||
|
filters: |
|
||||||
|
cp6_782_is_updated:
|
||||||
|
- 'cp6_782/**'
|
||||||
|
|
||||||
|
- name: Generate lockfile
|
||||||
|
run: cargo generate-lockfile
|
||||||
|
|
||||||
|
- name: Check if deps updated
|
||||||
|
id: deps-updated
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/registry
|
||||||
|
~/.cargo/git
|
||||||
|
target
|
||||||
|
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
|
- name: Conditionally run the tests
|
||||||
|
# if source code updated OR dependencies updated
|
||||||
|
if: ${{ steps.check-diff.outputs.cp6_782_is_updated == 'true' || steps.deps-updated.outputs.cache-hit != 'true' }}
|
||||||
|
run: |
|
||||||
|
cd cp6_782/
|
||||||
|
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,16 +245,16 @@ 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
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: stable
|
toolchain: stable
|
||||||
target: aarch64-unknown-none
|
target: thumbv6m-none-eabi
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
- uses: actions/cache@v2
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/registry
|
~/.cargo/registry
|
||||||
@@ -159,10 +266,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 thumbv6m-none-eabi
|
||||||
|
|
||||||
- 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 thumbv6m-none-eabi
|
||||||
|
|||||||
35
CHANGELOG.md
35
CHANGELOG.md
@@ -2,15 +2,46 @@
|
|||||||
|
|
||||||
## Pending
|
## Pending
|
||||||
|
|
||||||
- [\#76](https://github.com/arkworks-rs/curves/pull/76) twisted Edwards parameters for bls12-377
|
|
||||||
|
|
||||||
### Breaking changes
|
### Breaking changes
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
|
- [\#156](https://github.com/arkworks-rs/curves/pull/156) Add the bw6-767 curve.
|
||||||
|
- [\#174](https://github.com/arkworks-rs/curves/pull/174) Add the "grumpkin" curve.
|
||||||
|
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|
||||||
|
- [\#156](https://github.com/arkworks-rs/curves/pull/156) The hard part of the final exponentiation for bw6-761 relocated from arkworks/algebra.
|
||||||
|
- [\#158](https://github.com/arkworks-rs/curves/pull/158) Enabled GLV as the default scalar multiplication for BLS12-377, BLS12-381 and BN254.
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
- [\#176](https://github.com/arkworks-rs/curves/pull/176) Non-canonical infinity point and bad flags in BLS12-381 serialization should fail.
|
||||||
|
|
||||||
|
## v0.4.0
|
||||||
|
- [\#76](https://github.com/arkworks-rs/curves/pull/76) twisted Edwards parameters for bls12-377
|
||||||
|
- Fixed curve benches
|
||||||
|
|
||||||
|
### Breaking changes
|
||||||
|
|
||||||
|
- [\#104](https://github.com/arkworks-rs/curves/pull/104) Remove `QUADRATIC_NONRESIDUE` parameter from implementors of `Fp2Config`.
|
||||||
|
- [\#129](https://github.com/arkworks-rs/curves/pull/129) Implement custom serialization for BLS12-381 for compatibility with the [Zcash lib](https://github.com/zkcrypto/bls12_381).
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- [\#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
|
||||||
|
|
||||||
|
- [\#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.
|
||||||
|
- [\#141](https://github.com/arkworks-rs/curves/pull/103) Faster cofactor clearing for BLS12-377.
|
||||||
|
- [\#138](https://github.com/arkworks-rs/curves/pull/138) Implement WB Hash-to-Curve for bls12-381 and bls12-377
|
||||||
|
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
|
|
||||||
|
|||||||
24
Cargo.toml
24
Cargo.toml
@@ -1,7 +1,6 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
|
|
||||||
members = [
|
members = [
|
||||||
"curve-benches",
|
|
||||||
"curve-constraint-tests",
|
"curve-constraint-tests",
|
||||||
|
|
||||||
"bls12_377",
|
"bls12_377",
|
||||||
@@ -10,6 +9,8 @@ members = [
|
|||||||
"bw6_761",
|
"bw6_761",
|
||||||
"ed_on_bw6_761",
|
"ed_on_bw6_761",
|
||||||
|
|
||||||
|
"bw6_767",
|
||||||
|
|
||||||
"cp6_782",
|
"cp6_782",
|
||||||
"ed_on_cp6_782",
|
"ed_on_cp6_782",
|
||||||
|
|
||||||
@@ -19,6 +20,7 @@ members = [
|
|||||||
|
|
||||||
"bn254",
|
"bn254",
|
||||||
"ed_on_bn254",
|
"ed_on_bn254",
|
||||||
|
"grumpkin",
|
||||||
|
|
||||||
"mnt4_298",
|
"mnt4_298",
|
||||||
"mnt6_298",
|
"mnt6_298",
|
||||||
@@ -30,7 +32,16 @@ members = [
|
|||||||
|
|
||||||
"pallas",
|
"pallas",
|
||||||
"vesta",
|
"vesta",
|
||||||
|
|
||||||
|
"secp256k1",
|
||||||
|
"secp256r1",
|
||||||
|
"secp384r1",
|
||||||
|
"secq256k1",
|
||||||
|
|
||||||
|
"curve25519",
|
||||||
|
"ed25519",
|
||||||
]
|
]
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
@@ -57,8 +68,11 @@ incremental = true
|
|||||||
debug-assertions = true
|
debug-assertions = true
|
||||||
debug = true
|
debug = true
|
||||||
|
|
||||||
# To be removed in the new release.
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
ark-ec = { git = "https://github.com/arkworks-rs/algebra" }
|
ark-ff = { git = "https://github.com/arkworks-rs/algebra/" }
|
||||||
ark-ff = { git = "https://github.com/arkworks-rs/algebra" }
|
ark-ec = { git = "https://github.com/arkworks-rs/algebra/" }
|
||||||
ark-serialize = { git = "https://github.com/arkworks-rs/algebra" }
|
ark-poly = { git = "https://github.com/arkworks-rs/algebra/" }
|
||||||
|
ark-serialize = { git = "https://github.com/arkworks-rs/algebra/" }
|
||||||
|
ark-algebra-test-templates = { git = "https://github.com/arkworks-rs/algebra/" }
|
||||||
|
ark-algebra-bench-templates = { git = "https://github.com/arkworks-rs/algebra/" }
|
||||||
|
ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std/" }
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
# Curve implementations
|
# Notice
|
||||||
|
|
||||||
|
This repository is no longer maintained, and PRs to add or modify curves should instead be made against [arkworks-rs/algebra](https://github.com/arkworks-rs/algebra); all the curves implemented here have moved to the [`curves` folder](https://github.com/arkworks-rs/algebra/tree/master/curves) of that repository.
|
||||||
|
|
||||||
|
## Curve implementations
|
||||||
|
|
||||||
This repository contains implementations of some popular elliptic curves. The curve API implemented here matches the curve traits defined [here](https://github.com/arkworks-rs/algebra/blob/master/ec/src/lib.rs) in the [arkworks-rs/algebra](https://github.com/arkworks-rs/algebra) repository.
|
This repository contains implementations of some popular elliptic curves. The curve API implemented here matches the curve traits defined [here](https://github.com/arkworks-rs/algebra/blob/master/ec/src/lib.rs) in the [arkworks-rs/algebra](https://github.com/arkworks-rs/algebra) repository.
|
||||||
|
|
||||||
@@ -20,6 +24,7 @@ This repository contains implementations of some popular elliptic curves. The cu
|
|||||||
### BN254 and related curves
|
### BN254 and related curves
|
||||||
* [`ark-bn254`](bn254): Implements the BN254 pairing-friendly curve
|
* [`ark-bn254`](bn254): Implements the BN254 pairing-friendly curve
|
||||||
* [`ark-ed-on-bn254`](ed_on_bn254): Implements a Twisted Edwards curve atop the scalar field of BN254
|
* [`ark-ed-on-bn254`](ed_on_bn254): Implements a Twisted Edwards curve atop the scalar field of BN254
|
||||||
|
* [`ark-grumpkin`](grumpkin): Implements the Grumpkin curve. A curve that forms a cycle with bn254.
|
||||||
|
|
||||||
### MNT-298 cycle of curves and related curves
|
### MNT-298 cycle of curves and related curves
|
||||||
* [`ark-mnt4-298`](mnt4_298): Implements the MNT4-298 pairing-friendly curve. This curve forms a pairing-friendly cycle with MNT6-298
|
* [`ark-mnt4-298`](mnt4_298): Implements the MNT4-298 pairing-friendly curve. This curve forms a pairing-friendly cycle with MNT6-298
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-bls12-377"
|
name = "ark-bls12-377"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
authors = [ "arkworks contributors" ]
|
authors = [ "arkworks contributors" ]
|
||||||
description = "The BLS12-377 pairing-friendly elliptic curve"
|
description = "The BLS12-377 pairing-friendly elliptic curve"
|
||||||
homepage = "https://arkworks.rs"
|
homepage = "https://arkworks.rs"
|
||||||
@@ -10,19 +10,21 @@ 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", default-features = false }
|
||||||
ark-ec = { version="^0.3.0", default-features = false }
|
ark-ec = { version= "0.4.0", default-features = false }
|
||||||
ark-r1cs-std = { version="^0.3.0", default-features = false, optional = true }
|
ark-r1cs-std = { version= "0.4.0", default-features = false, optional = true }
|
||||||
ark-std = { version="^0.3.0", default-features = false }
|
ark-std = { version = "0.4.0", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ark-relations = { version="^0.3.0", default-features = false }
|
ark-relations = { version= "0.4.0", default-features = false }
|
||||||
ark-serialize = { version="^0.3.0", default-features = false }
|
ark-serialize = { version = "0.4.0", default-features = false }
|
||||||
ark-algebra-test-templates = { version="^0.3.0", default-features = false }
|
ark-algebra-test-templates = { version = "0.4.0", default-features = false }
|
||||||
|
ark-algebra-bench-templates = { version = "0.4.0", default-features = false }
|
||||||
ark-curve-constraint-tests = { path = "../curve-constraint-tests", default-features = false }
|
ark-curve-constraint-tests = { path = "../curve-constraint-tests", default-features = false }
|
||||||
|
sha2 = { version = "0.10", default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "curve" ]
|
default = [ "curve" ]
|
||||||
@@ -32,3 +34,8 @@ 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,
|
||||||
|
);
|
||||||
28
bls12_377/scripts/base_field.sage
Normal file
28
bls12_377/scripts/base_field.sage
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
modulus = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
|
||||||
|
|
||||||
|
assert(modulus.is_prime())
|
||||||
|
|
||||||
|
Fp = GF(modulus)
|
||||||
|
|
||||||
|
generator = Fp(0);
|
||||||
|
for i in range(0, 20):
|
||||||
|
i = Fp(i);
|
||||||
|
neg_i = Fp(-i)
|
||||||
|
if not(i.is_primitive_root() or neg_i.is_primitive_root()):
|
||||||
|
continue
|
||||||
|
elif i.is_primitive_root():
|
||||||
|
assert(i.is_primitive_root());
|
||||||
|
print("Generator: %d" % i)
|
||||||
|
generator = i
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
assert(neg_i.is_primitive_root());
|
||||||
|
print("Generator: %d" % neg_i)
|
||||||
|
generator = neg_i
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
two_adicity = valuation(modulus - 1, 2);
|
||||||
|
trace = (modulus - 1) / 2**two_adicity;
|
||||||
|
two_adic_root_of_unity = generator^trace
|
||||||
|
print("2-adic Root of Unity: %d " % two_adic_root_of_unity)
|
||||||
327
bls12_377/scripts/bls12_isogeny_computer.sage
Normal file
327
bls12_377/scripts/bls12_isogeny_computer.sage
Normal file
File diff suppressed because one or more lines are too long
28
bls12_377/scripts/scalar_field.sage
Normal file
28
bls12_377/scripts/scalar_field.sage
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
modulus = 8444461749428370424248824938781546531375899335154063827935233455917409239041
|
||||||
|
|
||||||
|
assert(modulus.is_prime())
|
||||||
|
|
||||||
|
Fp = GF(modulus)
|
||||||
|
|
||||||
|
generator = Fp(0);
|
||||||
|
for i in range(0, 30):
|
||||||
|
i = Fp(i);
|
||||||
|
neg_i = Fp(-i)
|
||||||
|
if not(i.is_primitive_root() or neg_i.is_primitive_root()):
|
||||||
|
continue
|
||||||
|
elif i.is_primitive_root():
|
||||||
|
assert(i.is_primitive_root());
|
||||||
|
print("Generator: %d" % i)
|
||||||
|
generator = i
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
assert(neg_i.is_primitive_root());
|
||||||
|
print("Generator: %d" % neg_i)
|
||||||
|
generator = neg_i
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
two_adicity = valuation(modulus - 1, 2);
|
||||||
|
trace = (modulus - 1) / 2**two_adicity;
|
||||||
|
two_adic_root_of_unity = generator^trace
|
||||||
|
print("2-adic Root of Unity: %d " % two_adic_root_of_unity)
|
||||||
@@ -1,45 +1,39 @@
|
|||||||
use crate::Parameters;
|
use ark_ec::{bls12::Bls12Config, CurveConfig};
|
||||||
use ark_ec::bls12::Bls12Parameters;
|
|
||||||
use ark_ec::ModelParameters;
|
|
||||||
use ark_r1cs_std::{
|
use ark_r1cs_std::{
|
||||||
fields::fp::FpVar,
|
fields::fp::FpVar,
|
||||||
groups::{bls12, curves::twisted_edwards::AffineVar as TEAffineVar},
|
groups::{bls12, curves::twisted_edwards::AffineVar as TEAffineVar},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::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 ModelParameters>::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,
|
|
||||||
G1Var,
|
|
||||||
>()
|
|
||||||
.unwrap();
|
.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,
|
|
||||||
G2Var,
|
|
||||||
>()
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
use crate::{Fq, Fq12Parameters, Fq2Parameters, Fq6Parameters};
|
|
||||||
|
|
||||||
use ark_r1cs_std::fields::{fp::FpVar, fp12::Fp12Var, fp2::Fp2Var, fp6_3over2::Fp6Var};
|
use ark_r1cs_std::fields::{fp::FpVar, fp12::Fp12Var, fp2::Fp2Var, fp6_3over2::Fp6Var};
|
||||||
|
|
||||||
|
use crate::{Fq, Fq12Config, Fq2Config, Fq6Config};
|
||||||
|
|
||||||
/// A variable that is the R1CS equivalent of `crate::Fq`.
|
/// A variable that is the R1CS equivalent of `crate::Fq`.
|
||||||
pub type FqVar = FpVar<Fq>;
|
pub type FqVar = FpVar<Fq>;
|
||||||
|
|
||||||
/// A variable that is the R1CS equivalent of `crate::Fq2`.
|
/// A variable that is the R1CS equivalent of `crate::Fq2`.
|
||||||
pub type Fq2Var = Fp2Var<Fq2Parameters>;
|
pub type Fq2Var = Fp2Var<Fq2Config>;
|
||||||
/// A variable that is the R1CS equivalent of `crate::Fq6`.
|
/// A variable that is the R1CS equivalent of `crate::Fq6`.
|
||||||
pub type Fq6Var = Fp6Var<Fq6Parameters>;
|
pub type Fq6Var = Fp6Var<Fq6Config>;
|
||||||
/// A variable that is the R1CS equivalent of `crate::Fq12`.
|
/// A variable that is the R1CS equivalent of `crate::Fq12`.
|
||||||
pub type Fq12Var = Fp12Var<Fq12Parameters>;
|
pub type Fq12Var = Fp12Var<Fq12Config>;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bls12_377_field_test() {
|
fn bls12_377_field_test() {
|
||||||
|
|||||||
@@ -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,10 +1,13 @@
|
|||||||
use crate::Parameters;
|
use crate::Config;
|
||||||
|
|
||||||
/// Specifies the constraints for computing a pairing in the BLS12-377 bilinear group.
|
/// Specifies the constraints for computing a pairing in the BLS12-377 bilinear
|
||||||
pub type PairingVar = ark_r1cs_std::pairing::bls12::PairingVar<Parameters>;
|
/// group.
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,60 +1,113 @@
|
|||||||
use ark_ec::models::{
|
use ark_ec::{
|
||||||
twisted_edwards_extended::{
|
bls12,
|
||||||
GroupAffine as TEGroupAffine, GroupProjective as TEGroupProjective,
|
bls12::Bls12Config,
|
||||||
|
hashing::curve_maps::wb::{IsogenyMap, WBConfig},
|
||||||
|
models::{
|
||||||
|
short_weierstrass::{Affine as SWAffine, Projective as SWProjective, SWCurveConfig},
|
||||||
|
twisted_edwards::{
|
||||||
|
Affine as TEAffine, MontCurveConfig, Projective as TEProjective, TECurveConfig,
|
||||||
},
|
},
|
||||||
ModelParameters, MontgomeryModelParameters, SWModelParameters, TEModelParameters,
|
},
|
||||||
|
scalar_mul::glv::GLVConfig,
|
||||||
|
CurveConfig,
|
||||||
};
|
};
|
||||||
use ark_ff::{field_new, Zero};
|
use ark_ff::{AdditiveGroup, BigInt, Field, MontFp, PrimeField, Zero};
|
||||||
use core::ops::Neg;
|
use ark_std::{ops::Neg, One};
|
||||||
|
|
||||||
use crate::{
|
use super::g1_swu_iso::{SwuIsoConfig, ISOGENY_MAP_TO_G1};
|
||||||
fields::{FQ_ONE, FQ_ZERO},
|
use crate::{Fq, Fr};
|
||||||
Fq, Fr,
|
|
||||||
};
|
pub type G1Affine = bls12::G1Affine<crate::Config>;
|
||||||
|
pub type G1Projective = bls12::G1Projective<crate::Config>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl ModelParameters for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
}
|
|
||||||
|
|
||||||
impl SWModelParameters for Parameters {
|
|
||||||
/// COEFF_A = 0
|
|
||||||
const COEFF_A: Fq = FQ_ZERO;
|
|
||||||
|
|
||||||
/// COEFF_B = 1
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const COEFF_B: Fq = FQ_ONE;
|
|
||||||
|
|
||||||
/// COFACTOR = (x - 1)^2 / 3 = 30631250834960419227450344600217059328
|
/// COFACTOR = (x - 1)^2 / 3 = 30631250834960419227450344600217059328
|
||||||
const COFACTOR: &'static [u64] = &[0x0, 0x170b5d4430000000];
|
const COFACTOR: &'static [u64] = &[0x0, 0x170b5d4430000000];
|
||||||
|
|
||||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
/// = 5285428838741532253824584287042945485047145357130994810877
|
/// = 5285428838741532253824584287042945485047145357130994810877
|
||||||
#[rustfmt::skip]
|
const COFACTOR_INV: Fr = MontFp!("5285428838741532253824584287042945485047145357130994810877");
|
||||||
const COFACTOR_INV: Fr = field_new!(Fr, "5285428838741532253824584287042945485047145357130994810877");
|
}
|
||||||
|
|
||||||
|
impl SWCurveConfig for Config {
|
||||||
|
/// COEFF_A = 0
|
||||||
|
const COEFF_A: Fq = Fq::ZERO;
|
||||||
|
|
||||||
|
/// COEFF_B = 1
|
||||||
|
const COEFF_B: Fq = Fq::ONE;
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
const GENERATOR: G1SWAffine = G1SWAffine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||||
(G1_GENERATOR_X, G1_GENERATOR_Y);
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
fn mul_by_a(_: Self::BaseField) -> Self::BaseField {
|
||||||
Self::BaseField::zero()
|
Self::BaseField::zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul_projective(p: &G1Projective, scalar: &[u64]) -> G1Projective {
|
||||||
|
let s = Self::ScalarField::from_sign_and_limbs(true, scalar);
|
||||||
|
GLVConfig::glv_mul_projective(*p, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn clear_cofactor(p: &G1SWAffine) -> G1SWAffine {
|
||||||
|
// Using the effective cofactor.
|
||||||
|
//
|
||||||
|
// It is enough to multiply by (x - 1), instead of (x - 1)^2 / 3
|
||||||
|
let h_eff = x_minus_one().into_bigint();
|
||||||
|
<Config as SWCurveConfig>::mul_affine(p, h_eff.as_ref()).into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type G1TEAffine = TEGroupAffine<Parameters>;
|
impl GLVConfig for Config {
|
||||||
pub type G1TEProjective = TEGroupProjective<Parameters>;
|
const ENDO_COEFFS: &'static[Self::BaseField] = &[
|
||||||
|
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231")
|
||||||
|
];
|
||||||
|
|
||||||
|
const LAMBDA: Self::ScalarField =
|
||||||
|
MontFp!("8444461749428370424248824938781546531284005582649182570233710176290576793600");
|
||||||
|
|
||||||
|
const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
|
||||||
|
(true, BigInt!("91893752504881257701523279626832445441")),
|
||||||
|
(true, BigInt!("1")),
|
||||||
|
(false, BigInt!("1")),
|
||||||
|
(true, BigInt!("91893752504881257701523279626832445440")),
|
||||||
|
];
|
||||||
|
|
||||||
|
fn endomorphism(p: &SWProjective<Self>) -> SWProjective<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn endomorphism_affine(p: &SWAffine<Self>) -> SWAffine<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn x_minus_one() -> Fr {
|
||||||
|
const X: Fr = Fr::from_sign_and_limbs(!crate::Config::X_IS_NEGATIVE, crate::Config::X);
|
||||||
|
X - Fr::one()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type G1SWAffine = SWAffine<Config>;
|
||||||
|
pub type G1TEAffine = TEAffine<Config>;
|
||||||
|
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
|
||||||
/// 1. SW -> Montgomery -> TE1 transformation: <https://en.wikipedia.org/wiki/Montgomery_curve>
|
/// 1. SW -> Montgomery -> TE1 transformation: <https://en.wikipedia.org/wiki/Montgomery_curve>
|
||||||
/// 2. TE1 -> TE2 normalization (enforcing `a = -1`)
|
/// 2. TE1 -> TE2 normalization (enforcing `a = -1`)
|
||||||
/// ``` sage
|
/// ``` sage
|
||||||
///
|
|
||||||
/// # modulus
|
/// # modulus
|
||||||
/// p = 0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001
|
/// p = 0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001
|
||||||
/// Fp = Zmod(p)
|
/// Fp = Zmod(p)
|
||||||
@@ -96,33 +149,22 @@ pub type G1TEProjective = TEGroupProjective<Parameters>;
|
|||||||
/// TE2a = Fp(-1)
|
/// TE2a = Fp(-1)
|
||||||
/// # b = -TE1d/TE1a
|
/// # b = -TE1d/TE1a
|
||||||
/// TE2d = Fp(122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179)
|
/// TE2d = Fp(122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179)
|
||||||
///
|
|
||||||
/// ```
|
/// ```
|
||||||
impl TEModelParameters for Parameters {
|
impl TECurveConfig for Config {
|
||||||
/// COEFF_A = -1
|
/// COEFF_A = -1
|
||||||
const COEFF_A: Fq = field_new!(Fq, "-1");
|
const COEFF_A: Fq = MontFp!("-1");
|
||||||
|
|
||||||
/// COEFF_D = 122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179 mod q
|
/// COEFF_D = 122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179 mod q
|
||||||
#[rustfmt::skip]
|
const COEFF_D: Fq = MontFp!("122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179");
|
||||||
const COEFF_D: Fq = field_new!(Fq, "122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179");
|
|
||||||
|
|
||||||
/// COFACTOR = (x - 1)^2 / 3 = 30631250834960419227450344600217059328
|
|
||||||
const COFACTOR: &'static [u64] = &[0x0, 0x170b5d4430000000];
|
|
||||||
|
|
||||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
|
||||||
/// = 5285428838741532253824584287042945485047145357130994810877
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const COFACTOR_INV: Fr = field_new!(Fr, "5285428838741532253824584287042945485047145357130994810877");
|
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
|
||||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
const GENERATOR: G1TEAffine = G1TEAffine::new_unchecked(TE_GENERATOR_X, TE_GENERATOR_Y);
|
||||||
(TE_GENERATOR_X, TE_GENERATOR_Y);
|
|
||||||
|
|
||||||
type MontgomeryModelParameters = 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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,7 +174,6 @@ impl TEModelParameters for Parameters {
|
|||||||
// It can be obtained via the following script, implementing
|
// It can be obtained via the following script, implementing
|
||||||
// SW -> Montgomery transformation: <https://en.wikipedia.org/wiki/Montgomery_curve>
|
// SW -> Montgomery transformation: <https://en.wikipedia.org/wiki/Montgomery_curve>
|
||||||
// ``` sage
|
// ``` sage
|
||||||
//
|
|
||||||
// # modulus
|
// # modulus
|
||||||
// p=0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001
|
// p=0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001
|
||||||
// Fp=Zmod(p)
|
// Fp=Zmod(p)
|
||||||
@@ -157,30 +198,33 @@ impl TEModelParameters for Parameters {
|
|||||||
// # MB = s
|
// # MB = s
|
||||||
// MB=Fp(10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931)
|
// MB=Fp(10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931)
|
||||||
// ```
|
// ```
|
||||||
impl MontgomeryModelParameters for Parameters {
|
impl MontCurveConfig for Config {
|
||||||
/// COEFF_A = 228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384
|
/// COEFF_A = 228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384
|
||||||
#[rustfmt::skip]
|
const COEFF_A: Fq = MontFp!("228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384");
|
||||||
const COEFF_A: Fq = field_new!(Fq, "228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384");
|
|
||||||
|
|
||||||
/// COEFF_B = 10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931
|
/// COEFF_B = 10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931
|
||||||
#[rustfmt::skip]
|
const COEFF_B: Fq = MontFp!("10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931");
|
||||||
const COEFF_B: Fq = field_new!(Fq, "10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931");
|
|
||||||
|
|
||||||
type TEModelParameters = Parameters;
|
type TECurveConfig = Config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// G1_GENERATOR_X =
|
/// G1_GENERATOR_X =
|
||||||
/// 81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695
|
/// 81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695
|
||||||
#[rustfmt::skip]
|
pub const G1_GENERATOR_X: Fq = MontFp!("81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695");
|
||||||
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695");
|
|
||||||
|
|
||||||
/// G1_GENERATOR_Y =
|
/// G1_GENERATOR_Y =
|
||||||
/// 241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030
|
/// 241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030
|
||||||
#[rustfmt::skip]
|
pub const G1_GENERATOR_Y: Fq = MontFp!("241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030");
|
||||||
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030");
|
|
||||||
|
|
||||||
// The generator for twisted Edward form is the same SW generator converted into the normalized TE form (TE2).
|
impl WBConfig for Config {
|
||||||
// ``` sage
|
type IsogenousCurve = SwuIsoConfig;
|
||||||
|
|
||||||
|
const ISOGENY_MAP: IsogenyMap<'static, Self::IsogenousCurve, Self> = ISOGENY_MAP_TO_G1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The generator for twisted Edward form is the same SW generator converted into
|
||||||
|
// the normalized TE form (TE2).
|
||||||
|
//``` sage
|
||||||
// # following scripts in previous section
|
// # following scripts in previous section
|
||||||
// #####################################################
|
// #####################################################
|
||||||
// # Weierstrass curve generator
|
// # Weierstrass curve generator
|
||||||
@@ -224,10 +268,39 @@ pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "241266749859715473739788878240585
|
|||||||
// ```
|
// ```
|
||||||
/// TE_GENERATOR_X =
|
/// TE_GENERATOR_X =
|
||||||
/// 71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393
|
/// 71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393
|
||||||
#[rustfmt::skip]
|
pub const TE_GENERATOR_X: Fq = MontFp!("71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393");
|
||||||
pub const TE_GENERATOR_X: Fq = field_new!(Fq, "71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393");
|
|
||||||
|
|
||||||
/// TE_GENERATOR_Y =
|
/// TE_GENERATOR_Y =
|
||||||
/// 6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235
|
/// 6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235
|
||||||
#[rustfmt::skip]
|
pub const TE_GENERATOR_Y: Fq = MontFp!("6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235");
|
||||||
pub const TE_GENERATOR_Y: Fq = field_new!(Fq, "6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235");
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use crate::g1;
|
||||||
|
use ark_std::{rand::Rng, UniformRand};
|
||||||
|
|
||||||
|
fn sample_unchecked() -> SWAffine<g1::Config> {
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
loop {
|
||||||
|
let x = Fq::rand(&mut rng);
|
||||||
|
let greatest = rng.gen();
|
||||||
|
|
||||||
|
if let Some(p) = SWAffine::get_point_from_x_unchecked(x, greatest) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cofactor_clearing() {
|
||||||
|
const SAMPLES: usize = 100;
|
||||||
|
for _ in 0..SAMPLES {
|
||||||
|
let p: SWAffine<g1::Config> = sample_unchecked();
|
||||||
|
let p = <Config as SWCurveConfig>::clear_cofactor(&p);
|
||||||
|
assert!(p.is_on_curve());
|
||||||
|
assert!(p.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
107
bls12_377/src/curves/g1_swu_iso.rs
Normal file
107
bls12_377/src/curves/g1_swu_iso.rs
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
use ark_ec::{
|
||||||
|
hashing::curve_maps::{swu::SWUConfig, wb::IsogenyMap},
|
||||||
|
models::{
|
||||||
|
short_weierstrass::{Affine, SWCurveConfig},
|
||||||
|
CurveConfig,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
use ark_ff::MontFp;
|
||||||
|
|
||||||
|
use crate::{g1, Fq, Fr};
|
||||||
|
|
||||||
|
type G1Affine = Affine<SwuIsoConfig>;
|
||||||
|
|
||||||
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
|
pub struct SwuIsoConfig;
|
||||||
|
|
||||||
|
impl CurveConfig for SwuIsoConfig {
|
||||||
|
type BaseField = Fq;
|
||||||
|
type ScalarField = Fr;
|
||||||
|
|
||||||
|
/// COFACTOR = (x - 1)^2 / 3 = iso_G1.domain().order() /
|
||||||
|
/// 8444461749428370424248824938781546531375899335154063827935233455917409239041
|
||||||
|
// 30631250834960419227450344600217059328
|
||||||
|
const COFACTOR: &'static [u64] = &[0x0, 0x170b5d4430000000];
|
||||||
|
|
||||||
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
|
/// = 5285428838741532253824584287042945485047145357130994810877
|
||||||
|
const COFACTOR_INV: Fr = MontFp!("5285428838741532253824584287042945485047145357130994810877");
|
||||||
|
}
|
||||||
|
|
||||||
|
// sage: iso_G1
|
||||||
|
// Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 +
|
||||||
|
// 258664426012969092796408009721202742408018065645352501567204841856062976176281513834280849065051431927238430294002*
|
||||||
|
// x + 22 over Finite Field of size
|
||||||
|
// 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
|
||||||
|
// to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size
|
||||||
|
// 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
|
||||||
|
|
||||||
|
impl SWCurveConfig for SwuIsoConfig {
|
||||||
|
/// COEFF_A
|
||||||
|
const COEFF_A: Fq = MontFp!("258664426012969092796408009721202742408018065645352501567204841856062976176281513834280849065051431927238430294002");
|
||||||
|
|
||||||
|
/// COEFF_B
|
||||||
|
const COEFF_B: Fq = MontFp!("22");
|
||||||
|
|
||||||
|
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||||
|
const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// sage: G1_gen = iso_G1.domain().random_point()
|
||||||
|
// sage: G1_gen = 30631250834960419227450344600217059328* G1_gen
|
||||||
|
// sage: G1_gen.order() ==
|
||||||
|
// 8444461749428370424248824938781546531375899335154063827935233455917409239041
|
||||||
|
// True
|
||||||
|
// sage: G1_gen
|
||||||
|
// (183898640136580512316530045470998831691790391453237259434516336279447756609241220664846162561503820562316877867830 : 69018534046895515891776145953191511526693172354818719412306559690461416836925400134233128432719372819569406562974 : 1)
|
||||||
|
/// G1_GENERATOR_X =
|
||||||
|
/// 183898640136580512316530045470998831691790391453237259434516336279447756609241220664846162561503820562316877867830
|
||||||
|
pub const G1_GENERATOR_X: Fq = MontFp!("183898640136580512316530045470998831691790391453237259434516336279447756609241220664846162561503820562316877867830");
|
||||||
|
|
||||||
|
/// G1_GENERATOR_Y =
|
||||||
|
/// 69018534046895515891776145953191511526693172354818719412306559690461416836925400134233128432719372819569406562974
|
||||||
|
pub const G1_GENERATOR_Y: Fq = MontFp!("69018534046895515891776145953191511526693172354818719412306559690461416836925400134233128432719372819569406562974");
|
||||||
|
|
||||||
|
impl SWUConfig for SwuIsoConfig {
|
||||||
|
const ZETA: Fq = MontFp!("-11"); // arbitatry primitive root of unity (element)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const ISOGENY_MAP_TO_G1 : IsogenyMap<'_, SwuIsoConfig, g1::Config, > = IsogenyMap {
|
||||||
|
x_map_numerator : &[
|
||||||
|
MontFp!("193998319509726820447277314072485610595876362210707887456279225959507476652652651634192264150953923683470146535424"),
|
||||||
|
MontFp!("40474824132456359704279181570318738632422647360355249739068643631356267969150730939906729705473"),
|
||||||
|
MontFp!("193998319509726820507989550271170150152295134566185995404913197000040351261255617081226666104680020093330241093633"),
|
||||||
|
],
|
||||||
|
|
||||||
|
x_map_denominator : &[
|
||||||
|
MontFp!("161899296529825438817116726281274954529690589441420998956274574525425071876602923759626918821892"),
|
||||||
|
MontFp!("1"),
|
||||||
|
],
|
||||||
|
|
||||||
|
y_map_numerator : &[
|
||||||
|
MontFp!("193998319509726820507989550271170150152295134566185995404913197000040351261255617081226666104680020093330241093631"),
|
||||||
|
MontFp!("32333053251621136903112182208573040583096119983059602439070460434672245065050016464457115901761911040205276577794"),
|
||||||
|
MontFp!("129332213006484547066038603046131306324615528732935438218576102373893108782773376834518846023512776472080255287298"),
|
||||||
|
MontFp!("226331372761347957259321141983031841844344323660550327972398729833380409804798219928097777122126690108885281275905"),
|
||||||
|
],
|
||||||
|
|
||||||
|
y_map_denominator : &[
|
||||||
|
MontFp!("258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458169"),
|
||||||
|
MontFp!("971395779178952632902700357687649727178143536648525993737647447152550431259617542557761512931340"),
|
||||||
|
MontFp!("485697889589476316451350178843824863589071768324262996868823723576275215629808771278880756465676"),
|
||||||
|
MontFp!("1"),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gen() {
|
||||||
|
let gen: G1Affine = SwuIsoConfig::GENERATOR;
|
||||||
|
assert!(gen.is_on_curve());
|
||||||
|
assert!(gen.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,35 +1,28 @@
|
|||||||
use ark_ec::models::{ModelParameters, SWModelParameters};
|
use ark_ec::{
|
||||||
use ark_ff::{field_new, Zero};
|
bls12,
|
||||||
|
bls12::Bls12Config,
|
||||||
|
hashing::curve_maps::wb::{IsogenyMap, WBConfig},
|
||||||
|
scalar_mul::glv::GLVConfig,
|
||||||
|
short_weierstrass::{Affine, Projective, SWCurveConfig},
|
||||||
|
AffineRepr, CurveConfig, CurveGroup, PrimeGroup,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{fields::FQ_ZERO, g1, Fq, Fq2, Fr};
|
use ark_ff::{AdditiveGroup, BigInt, Field, MontFp, PrimeField, Zero};
|
||||||
|
use ark_std::ops::Neg;
|
||||||
|
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
use super::g2_swu_iso::{SwuIsoConfig, ISOGENY_MAP_TO_G2};
|
||||||
|
|
||||||
|
pub type G2Affine = bls12::G2Affine<crate::Config>;
|
||||||
|
pub type G2Projective = bls12::G2Projective<crate::Config>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl ModelParameters for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq2;
|
type BaseField = Fq2;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
}
|
|
||||||
|
|
||||||
impl SWModelParameters for Parameters {
|
|
||||||
/// COEFF_A = [0, 0]
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const COEFF_A: Fq2 = field_new!(Fq2,
|
|
||||||
g1::Parameters::COEFF_A,
|
|
||||||
g1::Parameters::COEFF_A,
|
|
||||||
);
|
|
||||||
|
|
||||||
// As per https://eprint.iacr.org/2012/072.pdf,
|
|
||||||
// this curve has b' = b/i, where b is the COEFF_B of G1, and x^6 -i is
|
|
||||||
// the irreducible poly used to extend from Fp2 to Fp12.
|
|
||||||
// In our case, i = u (App A.3, T_6).
|
|
||||||
/// COEFF_B = [0,
|
|
||||||
/// 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906]
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const COEFF_B: Fq2 = field_new!(Fq2,
|
|
||||||
FQ_ZERO,
|
|
||||||
field_new!(Fq, "155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906"),
|
|
||||||
);
|
|
||||||
|
|
||||||
/// COFACTOR =
|
/// COFACTOR =
|
||||||
/// 7923214915284317143930293550643874566881017850177945424769256759165301436616933228209277966774092486467289478618404761412630691835764674559376407658497
|
/// 7923214915284317143930293550643874566881017850177945424769256759165301436616933228209277966774092486467289478618404761412630691835764674559376407658497
|
||||||
@@ -47,40 +40,230 @@ impl SWModelParameters for Parameters {
|
|||||||
|
|
||||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
/// = 6764900296503390671038341982857278410319949526107311149686707033187604810669
|
/// = 6764900296503390671038341982857278410319949526107311149686707033187604810669
|
||||||
#[rustfmt::skip]
|
const COFACTOR_INV: Fr =
|
||||||
const COFACTOR_INV: Fr = field_new!(Fr, "6764900296503390671038341982857278410319949526107311149686707033187604810669");
|
MontFp!("6764900296503390671038341982857278410319949526107311149686707033187604810669");
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWCurveConfig for Config {
|
||||||
|
/// COEFF_A = [0, 0]
|
||||||
|
const COEFF_A: Fq2 = Fq2::new(g1::Config::COEFF_A, g1::Config::COEFF_A);
|
||||||
|
|
||||||
|
// As per https://eprint.iacr.org/2012/072.pdf,
|
||||||
|
// this curve has b' = b/i, where b is the COEFF_B of G1, and x^6 -i is
|
||||||
|
// the irreducible poly used to extend from Fp2 to Fp12.
|
||||||
|
// In our case, i = u (App A.3, T_6).
|
||||||
|
/// COEFF_B = [0,
|
||||||
|
/// 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906]
|
||||||
|
const COEFF_B: Fq2 = Fq2::new(
|
||||||
|
Fq::ZERO,
|
||||||
|
MontFp!("155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906"),
|
||||||
|
);
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
||||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||||
(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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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)
|
||||||
|
|
||||||
|
let x: &'static [u64] = crate::Config::X;
|
||||||
|
let p_projective = p.into_group();
|
||||||
|
|
||||||
|
// [x]P
|
||||||
|
let x_p = Config::mul_affine(p, x);
|
||||||
|
// ψ(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;
|
||||||
|
tmp += &psi_p;
|
||||||
|
|
||||||
|
// tmp2 = [x^2]P + [x]ψ(P)
|
||||||
|
let mut tmp2: Projective<Config> = tmp;
|
||||||
|
tmp2 = tmp2.mul_bigint(x);
|
||||||
|
|
||||||
|
// add up all the terms
|
||||||
|
psi2_p2 += tmp2;
|
||||||
|
psi2_p2 -= x_p;
|
||||||
|
psi2_p2 += &-psi_p;
|
||||||
|
(psi2_p2 - p_projective).into_affine()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
impl GLVConfig for Config {
|
||||||
pub const G2_GENERATOR_X: Fq2 = field_new!(Fq2, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
const ENDO_COEFFS: &'static[Self::BaseField] = &[
|
||||||
#[rustfmt::skip]
|
Fq2::new(
|
||||||
pub const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
|
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
||||||
|
Fq::ZERO
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
const LAMBDA: Self::ScalarField = MontFp!("91893752504881257701523279626832445440");
|
||||||
|
|
||||||
|
const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
|
||||||
|
(false, BigInt!("91893752504881257701523279626832445440")),
|
||||||
|
(true, BigInt!("1")),
|
||||||
|
(false, BigInt!("1")),
|
||||||
|
(false, BigInt!("91893752504881257701523279626832445441")),
|
||||||
|
];
|
||||||
|
|
||||||
|
fn endomorphism(p: &Projective<Self>) -> Projective<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn endomorphism_affine(p: &Affine<Self>) -> Affine<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const G2_GENERATOR_X: Fq2 = Fq2::new(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
||||||
|
pub const G2_GENERATOR_Y: Fq2 = Fq2::new(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C0 =
|
/// G2_GENERATOR_X_C0 =
|
||||||
/// 233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294
|
/// 233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294
|
||||||
#[rustfmt::skip]
|
pub const G2_GENERATOR_X_C0: Fq = MontFp!("233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294");
|
||||||
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294");
|
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C1 =
|
/// G2_GENERATOR_X_C1 =
|
||||||
/// 140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118
|
/// 140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118
|
||||||
#[rustfmt::skip]
|
pub const G2_GENERATOR_X_C1: Fq = MontFp!("140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118");
|
||||||
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118");
|
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C0 =
|
/// G2_GENERATOR_Y_C0 =
|
||||||
/// 63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423
|
/// 63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423
|
||||||
#[rustfmt::skip]
|
pub const G2_GENERATOR_Y_C0: Fq = MontFp!("63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423");
|
||||||
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423");
|
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C1 =
|
/// G2_GENERATOR_Y_C1 =
|
||||||
/// 149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491
|
/// 149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491
|
||||||
#[rustfmt::skip]
|
pub const G2_GENERATOR_Y_C1: Fq = MontFp!("149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491");
|
||||||
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491");
|
|
||||||
|
// PSI_X = u^((p-1)/3)
|
||||||
|
const P_POWER_ENDOMORPHISM_COEFF_0 : Fq2 = Fq2::new(
|
||||||
|
MontFp!(
|
||||||
|
"80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"
|
||||||
|
),
|
||||||
|
Fq::ZERO,
|
||||||
|
);
|
||||||
|
|
||||||
|
// PSI_Y = u^((p-1)/2)
|
||||||
|
const P_POWER_ENDOMORPHISM_COEFF_1: Fq2 = Fq2::new(
|
||||||
|
MontFp!(
|
||||||
|
"216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499"),
|
||||||
|
Fq::ZERO,
|
||||||
|
);
|
||||||
|
|
||||||
|
// PSI_2_X = u^((p^2 - 1)/3)
|
||||||
|
const DOUBLE_P_POWER_ENDOMORPHISM_COEFF_0: Fq2 = Fq2::new(
|
||||||
|
MontFp!("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
||||||
|
Fq::ZERO
|
||||||
|
);
|
||||||
|
|
||||||
|
/// psi(x,y) is the untwist-Frobenius-twist endomorhism on E'(Fq2)
|
||||||
|
fn p_power_endomorphism(p: &Affine<Config>) -> Affine<Config> {
|
||||||
|
// The p-power endomorphism for G2 is defined as follows:
|
||||||
|
// 1. Note that G2 is defined on curve E': y^2 = x^3 + 1/u.
|
||||||
|
// To map a point (x, y) in E' to (s, t) in E,
|
||||||
|
// one set s = x * (u ^ (1/3)), t = y * (u ^ (1/2)),
|
||||||
|
// because E: y^2 = x^3 + 1.
|
||||||
|
// 2. Apply the Frobenius endomorphism (s, t) => (s', t'),
|
||||||
|
// another point on curve E, where s' = s^p, t' = t^p.
|
||||||
|
// 3. Map the point from E back to E'; that is,
|
||||||
|
// one set x' = s' / ((u) ^ (1/3)), y' = t' / ((u) ^ (1/2)).
|
||||||
|
//
|
||||||
|
// To sum up, it maps
|
||||||
|
// (x,y) -> (x^p * (u ^ ((p-1)/3)), y^p * (u ^ ((p-1)/2)))
|
||||||
|
// as implemented in the code as follows.
|
||||||
|
|
||||||
|
let mut res = *p;
|
||||||
|
res.x.frobenius_map_in_place(1);
|
||||||
|
res.y.frobenius_map_in_place(1);
|
||||||
|
|
||||||
|
res.x *= P_POWER_ENDOMORPHISM_COEFF_0;
|
||||||
|
res.y *= P_POWER_ENDOMORPHISM_COEFF_1;
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For a p-power endomorphism psi(P), compute psi(psi(P))
|
||||||
|
fn double_p_power_endomorphism(p: &Projective<Config>) -> Projective<Config> {
|
||||||
|
// p_power_endomorphism(&p_power_endomorphism(&p.into_affine())).into()
|
||||||
|
let mut res = *p;
|
||||||
|
|
||||||
|
res.x *= DOUBLE_P_POWER_ENDOMORPHISM_COEFF_0;
|
||||||
|
// u^((p^2 - 1)/2) == -1
|
||||||
|
res.y = res.y.neg();
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WBConfig for Config {
|
||||||
|
type IsogenousCurve = SwuIsoConfig;
|
||||||
|
|
||||||
|
const ISOGENY_MAP: IsogenyMap<'static, Self::IsogenousCurve, Self> = ISOGENY_MAP_TO_G2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use ark_std::{rand::Rng, UniformRand};
|
||||||
|
|
||||||
|
fn sample_unchecked() -> Affine<g2::Config> {
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
loop {
|
||||||
|
let x1 = Fq::rand(&mut rng);
|
||||||
|
let x2 = Fq::rand(&mut rng);
|
||||||
|
let greatest = rng.gen();
|
||||||
|
let x = Fq2::new(x1, x2);
|
||||||
|
|
||||||
|
if let Some(p) = Affine::get_point_from_x_unchecked(x, greatest) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_psi_2() {
|
||||||
|
let p = sample_unchecked();
|
||||||
|
let psi_p = p_power_endomorphism(&p);
|
||||||
|
let psi2_p_composed = p_power_endomorphism(&psi_p);
|
||||||
|
let psi2_p_optimised = double_p_power_endomorphism(&p.into());
|
||||||
|
|
||||||
|
assert_eq!(psi2_p_composed, psi2_p_optimised);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cofactor_clearing() {
|
||||||
|
let h_eff = &[
|
||||||
|
0x1e34800000000000,
|
||||||
|
0xcf664765b0000003,
|
||||||
|
0x8e8e73ad8a538800,
|
||||||
|
0x78ba279637388559,
|
||||||
|
0xb85860aaaad29276,
|
||||||
|
0xf7ee7c4b03103b45,
|
||||||
|
0x8f6ade35a5c7d769,
|
||||||
|
0xa951764c46f4edd2,
|
||||||
|
0x53648d3d9502abfb,
|
||||||
|
0x1f60243677e306,
|
||||||
|
];
|
||||||
|
const SAMPLES: usize = 10;
|
||||||
|
for _ in 0..SAMPLES {
|
||||||
|
let p: Affine<g2::Config> = sample_unchecked();
|
||||||
|
let optimised = p.clear_cofactor();
|
||||||
|
let naive = g2::Config::mul_affine(&p, h_eff);
|
||||||
|
assert_eq!(optimised.into_group(), naive);
|
||||||
|
assert!(optimised.is_on_curve());
|
||||||
|
assert!(optimised.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
457
bls12_377/src/curves/g2_swu_iso.rs
Normal file
457
bls12_377/src/curves/g2_swu_iso.rs
Normal file
@@ -0,0 +1,457 @@
|
|||||||
|
use ark_ec::{
|
||||||
|
hashing::curve_maps::{swu::SWUConfig, wb::IsogenyMap},
|
||||||
|
models::{
|
||||||
|
short_weierstrass::{Affine, SWCurveConfig},
|
||||||
|
CurveConfig,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use ark_ff::MontFp;
|
||||||
|
|
||||||
|
use crate::{g2, Fq2, Fr};
|
||||||
|
|
||||||
|
type G2Affine = Affine<SwuIsoConfig>;
|
||||||
|
|
||||||
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
|
pub struct SwuIsoConfig;
|
||||||
|
|
||||||
|
impl CurveConfig for SwuIsoConfig {
|
||||||
|
type BaseField = Fq2;
|
||||||
|
type ScalarField = Fr;
|
||||||
|
|
||||||
|
/// COFACTOR =
|
||||||
|
/// 7923214915284317143930293550643874566881017850177945424769256759165301436616933228209277966774092486467289478618404761412630691835764674559376407658497
|
||||||
|
/// same as the original g2 curve
|
||||||
|
/// sage: iso_G2.domain().order() == iso_G2.codomain().order()
|
||||||
|
/// True
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COFACTOR: &'static [u64] = &[
|
||||||
|
0x0000000000000001,
|
||||||
|
0x452217cc90000000,
|
||||||
|
0xa0f3622fba094800,
|
||||||
|
0xd693e8c36676bd09,
|
||||||
|
0x8c505634fae2e189,
|
||||||
|
0xfbb36b00e1dcc40c,
|
||||||
|
0xddd88d99a6f6a829,
|
||||||
|
0x26ba558ae9562a,
|
||||||
|
];
|
||||||
|
|
||||||
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
|
/// = 6764900296503390671038341982857278410319949526107311149686707033187604810669
|
||||||
|
const COFACTOR_INV: Fr =
|
||||||
|
MontFp!("6764900296503390671038341982857278410319949526107311149686707033187604810669");
|
||||||
|
}
|
||||||
|
|
||||||
|
// sage: E2p = iso_G2.domain()
|
||||||
|
// sage: r = 8444461749428370424248824938781546531375899335154063827935233455917409239041
|
||||||
|
// sage: E2p.order()/r
|
||||||
|
// 7923214915284317143930293550643874566881017850177945424769256759165301436616933228209277966774092486467289478618404761412630691835764674559376407658497
|
||||||
|
// sage: E2p
|
||||||
|
// Elliptic Curve defined by y^2 = x^3 +
|
||||||
|
// (69357795553467368835766998649443114298653120475771922004522583893765862042427351483161253261358624703462995261783*
|
||||||
|
// X2+203567575243095400658685394654545117908398249146024925306257919445062693445414588103741379252427065422417496933054)*
|
||||||
|
// x + (806998283981877041862626354975415285020485827233942100233224759047656510577433749137260740227904569833498998565*
|
||||||
|
// X2+249039961697346248294162904170316935273494032138504221215795383014884687447192317932476994472315647695087734549420)
|
||||||
|
// over Finite Field in X2 of size
|
||||||
|
// 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177^2
|
||||||
|
impl SWCurveConfig for SwuIsoConfig {
|
||||||
|
/// COEFF_A =
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COEFF_A: Fq2 = Fq2::new(
|
||||||
|
MontFp!("203567575243095400658685394654545117908398249146024925306257919445062693445414588103741379252427065422417496933054"),
|
||||||
|
MontFp!("69357795553467368835766998649443114298653120475771922004522583893765862042427351483161253261358624703462995261783"),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// COEFF_B =
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COEFF_B: Fq2 = Fq2::new(
|
||||||
|
MontFp!("249039961697346248294162904170316935273494032138504221215795383014884687447192317932476994472315647695087734549420"),
|
||||||
|
MontFp!("806998283981877041862626354975415285020485827233942100233224759047656510577433749137260740227904569833498998565"),
|
||||||
|
);
|
||||||
|
|
||||||
|
const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
const G2_GENERATOR_X: Fq2 = Fq2::new(
|
||||||
|
MontFp!("44471777796618567688228760095584248343372454885978087674329841655595593880133139294404651664057692271364857231527"),
|
||||||
|
MontFp!("152209914092745808277594956866181055187624831129109767937025242463317365117655129123148193049673425418513926319001"),
|
||||||
|
);
|
||||||
|
const G2_GENERATOR_Y: Fq2 = Fq2::new(
|
||||||
|
MontFp!("115206687171448860889110309021279060303629519187879257051215751573842462972180856243991157572371972099444077110343"),
|
||||||
|
MontFp!("191377956145194479040228903677940355038998863371661730030204479850936075480341608934735952709786495341106477933498"),
|
||||||
|
);
|
||||||
|
|
||||||
|
impl SWUConfig for SwuIsoConfig {
|
||||||
|
// sage: F2.primitive_element()
|
||||||
|
// X2 + 12
|
||||||
|
const ZETA: Fq2 = Fq2::new(MontFp!("12"), MontFp!("1")); // arbitatry primitive root of unity (element)
|
||||||
|
}
|
||||||
|
pub const ISOGENY_MAP_TO_G2 : IsogenyMap<'_, SwuIsoConfig, g2::Config> = IsogenyMap {
|
||||||
|
x_map_numerator : &[
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("165752316658948679552567650341600213993620343632797226373648182250196112194084163699689918190990441453209217107673"),
|
||||||
|
MontFp!("172182978063994664796636281648715261218877265445686511820228400278128135165425091257965367402286789184662480399420")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("49078863819486020728803126419770411403544927967564775122533948145670810135602221046611632159195633125363688522753"),
|
||||||
|
MontFp!("133330677606878026253733532636681674371349711466687180056118155523679405609126901243884039337337134962627419965345")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("88440326308038176392218244342168484162310820452393341528824316035047758188693394849605113877264996124652991932266"),
|
||||||
|
MontFp!("26460985441766134300772651139298255538590921173641559533448371120006177647448359485069994828122162245692248966113")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("240831597672798022181780196442988629902557797416422752447288392631352072879531084668083129009311685341499602842359"),
|
||||||
|
MontFp!("124795068789978952575783920730487695370136831800946532752608526840944057283524691812795315973894625798220920082767")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("231856156439094824000656216233999389240375109059054378946071472571709648546048606758615235778059505184730503731408"),
|
||||||
|
MontFp!("134026238756820071135251263743482298414233385640297868129438877114735051445009051866011097877494554014116371908672")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("161628978970526519329329822295337582413127505041035400390544637404697415598883543152357105789965717470570494458589"),
|
||||||
|
MontFp!("116602947282570158568911982642223012726308726836613908383578383334370050655181609483409110122767402070015216413338")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("231615170079008089001496386178968115998492752668752266579314749799030868007672086089822600816657899022828734321418"),
|
||||||
|
MontFp!("141639542381992520856560441410242716791591163086143661904501184306161835850893036003163803884002896297253767009574")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("96957224446676123824350918241672464825735454895610578698586352322390662445273628285471423071856275085141118045105"),
|
||||||
|
MontFp!("97587419381711441517698658129839468394457401157021696651597713140291602428957555768352336399994179660880524139808")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("18662780664429933771192510151421557554668611953190652639195940454142648933454488952361465779870877163142807899993"),
|
||||||
|
MontFp!("55517007457989983858891530398020104232682844055600438506715652841000901588962918721851719951820185832313468320365")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("188864327416940344326229259749844123042825201085435432627935318423081174922012610651352346391417830722940140585036"),
|
||||||
|
MontFp!("233542978062801907184831603532041452683131033894029390005010898310417350737942550513935694209129350870817277172583")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("33702103741469458207888758659069786556456463428431771947788685622778743201883736580054112022350187936628758294279"),
|
||||||
|
MontFp!("7531651998638745138624528632013700806848273210661661935097722938692087106885113623803921367479582718152259987647")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("129405180560592211762572081137246817341681076084973348177153469170177032429929182033872985192027066614650754524309"),
|
||||||
|
MontFp!("71494892585734577638768956295356005795556178117525317604450863442514001295461407965931789120761632296953990284809")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("121805396188033590038927712795579559087103093135515082191363074395734682090746320669474388875423586929711608364404"),
|
||||||
|
MontFp!("75932324143801627944771670190157701465835368459121478812142087933983158148741884038298732552979549182443318608554")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("205121513164720886728676669276499362266139599046368626660027529707299170205603076104821498121463983514654737906998"),
|
||||||
|
MontFp!("168051662766288660516992486993594951443897767271245608184500932350745292043277998040372769419920145370014740823389")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("224387508661509885922784938707800296916307265709615639996851552571542396031861010679067114387017955365668256976459"),
|
||||||
|
MontFp!("139097554917981907719834170888130444861465074977932740823078016609751284491153969166862091045221603146530147099779")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("142477190388553987083175296028785369398580520754966744245694134692905987471896623788336582063245356609279657681007"),
|
||||||
|
MontFp!("140302880976816076816721836344737338071783799730513599397010923016385668972882234545823525686327074617973208860421")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("205538184807792915395400814312734290381492118179294333381188081024280220461983210331268164749465891791515156713363"),
|
||||||
|
MontFp!("13030331252003455924520111292282390143014750833628314421882396445822808054003584720817672388894671968339344750750")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("139197805910452438551419010260519164074855817417063470117576949912038778696248952069759607969690314639425179841530"),
|
||||||
|
MontFp!("134745690770497208213126494241047670387239583870118646766457825646403640347226342104549240830903829682059982326727")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("46999088780962505530452862218145506822520603893157196954987630663398814970386085186714696215299498862118704356116"),
|
||||||
|
MontFp!("239220883081126775212690475926873251881459118214247205003758844846022330659109168499739536107988232402392010148915")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("137461512605659170682300574841422927080299499340556631216517745531687218204749421916211266297116812992348911035943"),
|
||||||
|
MontFp!("126932856673577834557989832150639712812952235385146245135235966945536973066700604316981524138335070494135486842267")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("57815299880375466472857931022912171296473275308202666945592250229771936329503691945881925004852905385160277065937"),
|
||||||
|
MontFp!("207900273391847649346738694548609379565855077833395139615718913929125517933139374225345876078131155102796477330196")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("182397511129719455005407008314265069548677727690813781407770284951663734172103638427690475141072553074575221965383"),
|
||||||
|
MontFp!("225121846650282460844501132545123914298308844633699320249517374760159461135641190512758348530493533776082794775238")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("42757221749971324771094873984161893488770713619971906650868412147150411626107692517374735631529074208182971223761"),
|
||||||
|
MontFp!("111424637101855455933266154646364284011426845669269128135151076357862608862363255550023430066507374024948118755170")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("257686488674545770403807165703608491821700153538449954828958424244540050698630649531963334687249831352703307010320"),
|
||||||
|
MontFp!("0")),
|
||||||
|
],
|
||||||
|
|
||||||
|
x_map_denominator : &[
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("196537929755540830130458921156910352741196129560556501635658595085779576490417628044619830744899117989899096675116"),
|
||||||
|
MontFp!("106967816747202586221026040614608875779671819314280336591550617355334247302203894951925800601923998790402234025494")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("73314120416427646620569455169905724114883313094893949291513517502168861559767103394033744003864213510722887906274"),
|
||||||
|
MontFp!("38999017135204040984255776995893429123212353273299706702441986090800506456890730978953545316903022073202240280957")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("133779461364688439286044255858523747234865723284672664672066362220940987786797573428234566651244275384657571315397"),
|
||||||
|
MontFp!("154931903368935230733381648548242132592387960818255334523314635613616976204585469590179605887364646535250639335453")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("247957910140234524214324761874381439955705875777136703199106095643204254634304448830280410483013931961038942096519"),
|
||||||
|
MontFp!("214943806307523271117409515396321303330984956986022871981067208079182219051826091487389512723678609613943324945884")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("11697862001088266121450094179739500241088837734277696824118211258364151630931186792937914301859707394679202145393"),
|
||||||
|
MontFp!("95980723944521770226526824868742386994509079773043937452565624851192578861364669763702851513923262074687274763858")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("168096269708683796856556357930292925811554548435612382636199127159818409693729567946366892866365435246772528367031"),
|
||||||
|
MontFp!("99720174640078175171062115168656883367851695095484071724968247253018133737453004325770034298778522431209097310502")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("33059404918884325948584592996172619413923041143099424466021368531149134447772287601175965141235934645074697267050"),
|
||||||
|
MontFp!("10757428905957703588038877674336794621171834192483169256644941002565404396356505770991807551250572677872221995215")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("142027935684179419855710336591935481541662612521926997142809731189880364304749483394981554800161483370077741056896"),
|
||||||
|
MontFp!("1943403947563275150997369785095274118967148389261968103605246462390957897712088493386683316483490223770940902453")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("200535851812830711305923885193456283997079838967145939474743725430895019937175928830731575175640901984178880783011"),
|
||||||
|
MontFp!("73874168720549156282270730246833500558176745413797996774310087510749148634278604002052708223696920208907646881989")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("220384543328043309613139993483671702409123249316603413540407457441864555087013622511692877380446192851630287225413"),
|
||||||
|
MontFp!("39000405073743042346296304484168728185850505353133307908773204457381817815206498660334035187329579833299098854925")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("219195224293908756855578672234544437367397890301565855376597788842679778002659222115121213889017072727428356719234"),
|
||||||
|
MontFp!("247894577734607804564008327202067464850944943412136922154651844411293409127507835027401641672218158657943826643185")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("146699001487357489560227247646638441970227213145065178169054120124066032784405371946823057532199624317631250110158"),
|
||||||
|
MontFp!("196336324454181158449524835117699225596467237400207491815838252818724619960701247377784788803043096102210425517795")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("155939253194251956164424003889230633804182501306742152137449150503013281009623802843490858570697615902305132709111"),
|
||||||
|
MontFp!("172261303485740204844677209985093962119870302741179905216184157502752680126595180139007438892219460422745105017475")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("137972103666241533333852948884443545062916813938500094392929132716673981519930321922556812217620174550912349461419"),
|
||||||
|
MontFp!("47600282095791674213992406796226738606147801920837771594412659335039656256887529097801732359033209329929517773020")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("135098057022357227608956235549944366234286127511416070373827898662879730495316177891045223676768538262860577751087"),
|
||||||
|
MontFp!("218641591773893348322227471378547165043111820723080862748702228639502320411481947789769811366015509814793754417785")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("228687493726193558146661770435566220015197012398911029567178581932152080915557441338298274247922585720118620741642"),
|
||||||
|
MontFp!("48223421552324743764826987807666420223567068651197810526658625431719723647078135623842652870214605734395702563953")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("82401683815523491481199527201592079745651015539510634295850130611233688561451492330603949648060220533354045095181"),
|
||||||
|
MontFp!("159070381032762485827712709726121404273458384870681735035622289092845201234785949112608113110663482448286550123895")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("61539107135026562717413992304341045078777699607129438878970720148394005607774781361280841945254066290447512808860"),
|
||||||
|
MontFp!("258564647705165711537697112631909171171984598885182416737094411313452565619624851452883996847677936536536427515609")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("219867891253233227579149075701158020315633373195728794672342716359369374905471205886891783929214978430681990036959"),
|
||||||
|
MontFp!("40524381030862708561992431051313657250449208728762250622105264621614810013551839533882876237430311293361821844681")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("88800087516399959501800534486349824688877578947555023348699585957763763180753947498274724426567091309571649023166"),
|
||||||
|
MontFp!("122245180850560437899129167839042992977076962956306963014567407897293197200681367630073717776421484831646532593850")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("69204740140688189359361744597982172008615446130082862488352885921056331761951244674105352971861180999345144984246"),
|
||||||
|
MontFp!("38216467720351249271557670250657907497353617320059247139049052120842234439257669911851800147147313339669901995490")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("114765242606519624982400506165904237893471895287563151339459173837887003905317760268941880935997925302483810508170"),
|
||||||
|
MontFp!("226808321937551848279625259185874129283473963677740840941191767963773773116795416044456897499248110949601850478751")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("1"),
|
||||||
|
MontFp!("0")),
|
||||||
|
],
|
||||||
|
|
||||||
|
y_map_numerator : &[
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("243169287995837894205750503657473181252400776697661357268613577074201794943537027717771587727860769419520957117060"),
|
||||||
|
MontFp!("154445371651863854130996979206021232172872232688365227537444264835087932826365764405635125797374865965304745730822")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("109149004424675517113489432756837393820953128532207867425106578478986226345054217066591849467433110788215195319750"),
|
||||||
|
MontFp!("30408441237651674477115309504276625429344634933425091999725383701660094027885762738289460271315609173544614563248")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("8414285408102090292522571401032945098403423241877066651551931468973120658567171350501434823318074450118610388181"),
|
||||||
|
MontFp!("226047422399128874433860903177676209375847937545805175562415311468986239012130226120019081492247088609694678876810")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("228308803559737454633222698485074629499383737811342884536963429506633258142551503400414163815852158951494613610809"),
|
||||||
|
MontFp!("220909287290837789818195731110558629271153823543746871132117978761339034747123501189473420274677281822601971748563")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("116623955280658732717402646061913268461869836841204913444259922610012147799771656282704605878638711580234302879520"),
|
||||||
|
MontFp!("251345693404812657374633929641944735274020119374936409701199723189056283828393555325905238148261248120379910778583")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("142632909729670553826438094523500302011158161959746397893981306350515911350319381478896794266740222044724793183031"),
|
||||||
|
MontFp!("135097007131619291616144192105571840182910366835929043414300810591005223344182310684819863256436016908585466099814")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("159262246805999098136860288248138175456624792734939305704793543040582454889431805248352849370505960249829264037333"),
|
||||||
|
MontFp!("256411146327954053251262434650444473133439725697572806395735688747939610541453396276159230618136278790246160635595")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("106675525854808944323662773997719159035717496275254424840883415090817949089664218352587480756720528552217297479523"),
|
||||||
|
MontFp!("142202207982399429498494980946602932891398916434890751210930378360132151108127041093945093575972538591541631204396")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("115853993705912938985758922127173369175321347209545356726288637524744651943071927137158115778405271676616612170666"),
|
||||||
|
MontFp!("188439202506521797668192307957766105517906171778775206324453830870041256388075168650527562921934698697140423464142")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("199891426461397900698689228549412057991574595606781836622700872746783962617889812808189413859146835266670353365164"),
|
||||||
|
MontFp!("123487321384490387195094801639396482206262484603737596281845841408384878196277195829349272799617445074531384638014")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("203453160391122297114764634999687500867096029894782931052056493086745424054313508850135956093450854351511962568248"),
|
||||||
|
MontFp!("3933321808920817665892338621688661599151270488240879901971434149901647580182088988848276352998263499828820719486")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("216229669548325266866202681779047392389311278655704899819569794547799955366773265486059541504823551138048188296915"),
|
||||||
|
MontFp!("41448968894064940344019909320065089603789758666259308674991068396259424208998703895462327945020441899649105710894")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("202678826482051686554967485240375873611017127444692775767942717540980994219310434688309713205309853725035377739266"),
|
||||||
|
MontFp!("48778316120483961415587198479185523835826749642473845435889717611018677968038563827240090688089889339896065735651")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("43364741387169348753014627410136368149262698966106150910900756728904165177527487078077667350512959263803465594111"),
|
||||||
|
MontFp!("61944739699039529393579599024212698483276675572994284564132452254474389809816373777333943401872462638231436446348")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("1902545032251691771730077590223241149624964994150687591044314892275508885163105731414463515832696686914784357054"),
|
||||||
|
MontFp!("67221897212365550931740188657735915316732820967428518278153545138481072202717711417949297443415145931349647354864")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("232464396645736057215489125286424902556417590819993013568149210848680788030572385843387291711255018198764185991688"),
|
||||||
|
MontFp!("41800154023275681622180037448850007404785328883356603798952195956734186941687720006035939799906615555216990599152")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("187038260664272653235271156369560372695631446985830424056061915935191103410794701043280599214000281588074544657045"),
|
||||||
|
MontFp!("38290302770763423573829549940707041833171456153861823771988991461936307395626028842226881832323571911777783325552")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("8193038016485856982946817225511231096542148907426451941320763511467909442967073658628847889502238964737537651732"),
|
||||||
|
MontFp!("9418692556935347898382092734571186686450013671235254851703843297990915553970523788207837029694342875454233715193")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("134073844001083825421215848942909782702386338984309026786345170296027964134133613977422644522116018820345983847098"),
|
||||||
|
MontFp!("153830492090479629579603390014414329445124716355506854714467139884353350218676155251380590350715220577136073627555")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("24894203921911934571199160858232802417038583022586807490232139245280305064770051397858560092019807972764914216208"),
|
||||||
|
MontFp!("120208242722200714489749801697072499732825359039071841003310452443348308205795253556381720202955786470886397257982")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("190392008574458975806418600277835706985376229847531539152452591238358119216217627352637258288556199770365835067627"),
|
||||||
|
MontFp!("236947842470057836630333692287445445381482585314120394670322793497639860754696181540315462907276465780536189751938")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("128014602802339573117431114877417430852771121268703430430938496966993823548956133449208721198231566864014207876438"),
|
||||||
|
MontFp!("76313913933214383311039506294052736258824720597935452573279680967713148986901401959316819572744945391130691484709")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("25945524144868616798377005434321968607597029473408456417628770501736226577600936996306306386148517051252174176056"),
|
||||||
|
MontFp!("93302878136439028547402102681387844515310157832968167882878653011659204369510932686206718073261314562836132094987")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("89345438915485267000169594163110872264018138861479961667441187849751112704236404111089533981719810422892295971197"),
|
||||||
|
MontFp!("225199447663521472758596124691205483139271667363437613911741821442536429098852529066869544898685674003162780468715")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("133226465537371725791207823007732608016851433266603356824246032571600774858733596680855277271698121233692296984412"),
|
||||||
|
MontFp!("214026235442364760645768878901893433888530027239186932434340221483611429797860448445573321733516533800376783586849")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("209865017468509971341642462085093919192185569139223034709204939485243056860760867821924437786503336074163109167043"),
|
||||||
|
MontFp!("219490420378012040044597900078465204875085141304274262719756064241884227366143829466191943246131284770521917871841")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("107794270350250727824303719264349327362253764840855494366195678657690526275364378542854833701549538802096418248084"),
|
||||||
|
MontFp!("214497132288922282410470995366492104127705853917251639956391350188219443322307620708083843529019036699996096662829")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("216436913923048926393371382639334167145590308917722616640273699755872914758105310937706004925121569777096571773501"),
|
||||||
|
MontFp!("14821532235517245029225575994881495294340097494060025842437989195232333244802578196149414170959605497405878582540")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("149340524242957423974772893433814190392014381473852786295383636551096665463613496468840974015807625484823068784839"),
|
||||||
|
MontFp!("92602205576740019970555092291786069878442230185393269119060098961688837594116147683652993589116622567477525635445")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("187289608720372854303118076618428364941868395899689208696722069999084187290922488892094161492110977423619035272649"),
|
||||||
|
MontFp!("138246251209835932037747211155451146889753321830881007441732932302281412878493276648902633332871835811473542877960")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("165653628641840315664303139225783620502451401675361521932235743336920154286645843675719999005591028855021909439672"),
|
||||||
|
MontFp!("221484407095875062109245088271905042727631591858266177514520864715688286361376419124935364810076972840743950061836")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("133980604703672698089766182661998480874540278232523164821108522954758888202993741126021280431373622479768313949356"),
|
||||||
|
MontFp!("38886256490758184304393553179653915986060051480245869194662478974097783410818598716423697164666847852998235320966")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("8411654157888762354868203383638678565276209861191964793314989111047210939710084789719415109438273538021505111510"),
|
||||||
|
MontFp!("187207294428708203829145346569036650547801585764458185253951079008883539428999915118458145884040644479498579194069")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("191144230647045707590184821948778479495825928592047153194222027257046414968351470170933284561757547536684715232224"),
|
||||||
|
MontFp!("0")),
|
||||||
|
],
|
||||||
|
|
||||||
|
y_map_denominator : &[
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("177304823246185962354212404236288831041380791662214394697399928748373114098169675564032904690251242875327747673679"),
|
||||||
|
MontFp!("234106598974619695004693596968258258794247055108931498762994964636371479098512727352039267846913406623802246782945")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("255874157960252694683645508260848371559149621054025374393554376526882940742514793344046680765937904153005134511200"),
|
||||||
|
MontFp!("19068358873460915055376626440913257473060029137260026174266944920186136734103362122730468957229595374427187617425")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("83946178094995839681455048029661822915614318352963730526672352524233381944447759416757234629624830143848209247040"),
|
||||||
|
MontFp!("36167189440196390196320129647971031300455228428629866775570898825049060037811108115927676106354625467897211624573")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("214137118009637944275213937166601531498145257806838837034827533674793291112410824873653425491233537265355337125438"),
|
||||||
|
MontFp!("75310151275642225944994533227518963961512910025529659163648069668626195571780520556481029340507362571133885889206")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("107140053800026140817203074526089346919722280052456645787788712045148531978814339001150298053597504647766497707422"),
|
||||||
|
MontFp!("114397460921328140828185121166450637136573513025702964340164304518654108540682577087979875141067314446917571826582")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("42398151340378868438123040588425908782227436520374323184618125390984068793920538080412999034838310511981244418952"),
|
||||||
|
MontFp!("82194329196840936158921467961561828669469444994699107543787160001285217807552090667641931153824104285439311091477")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("32044478312863504453978511975839237915357713065285858656377527520925624222082496835678894223326750023304346513708"),
|
||||||
|
MontFp!("224732340440722096332247540469311391766792864305974461767563394934556509366444399113606207665094042937608880394380")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("53290030879673160724264978063216325707183784347799183367929912851157629196486013218134779085284663628473135140615"),
|
||||||
|
MontFp!("42967590874964323361920860309631969474991176192252393149421408476343364383848642144439727879920981862569415477634")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("250488593850017034090300371968459931740406675270099747930030660805939980644430804509506597720682995099971419762057"),
|
||||||
|
MontFp!("131736273443849165304852712527070616520885505701320868662058330388440710419459541866884603770735894010610491333882")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("251064692215092635541196206457923985861467397867989080397969990645886126152674833092283559946890888232618697517884"),
|
||||||
|
MontFp!("171430383391121065822039978510482289343958135960126315509375831831735263180943544895493884988847947752888720502133")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("255810123836950778051032251049468471118744836441263107437005316697409810175422976454215094737538073112171964000966"),
|
||||||
|
MontFp!("78363344687446114757879143124020926645520829625790622079288990711202726499291972408305265373741655103522048633806")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("94953611600133917480746113251669332369937157892937924494319507354263981756523698288726321437604686331762128114942"),
|
||||||
|
MontFp!("224037954053161681052577381077631881138732983068288196649494577229506443999757164090758954620762136536790092765707")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("18177910449767953614338723180992575758462819793657888834925741153507922227776503487306285172452430778418239589878"),
|
||||||
|
MontFp!("55976309667093193926953058482403983650044130588205371047077237394269232758375928755579870418413040530924659710422")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("108398849957050915959578499238335172000970311919637037913625633347326921657585237193100994767528244599176367431882"),
|
||||||
|
MontFp!("204809230842263072415312635210643987712012160534293694062738501600937603588267937911969298058204043106501986725326")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("40836628940164991036725499428168139451294386215534361893839871958837737306822281294361671587764896498700322394958"),
|
||||||
|
MontFp!("119396884503349014053839666170414789560955868303656326650021743484252346209353246139311353657707899076368015332219")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("57449149099548285338146473529383255206310079371370663992648410210841833627207062160011080280732475904935527767063"),
|
||||||
|
MontFp!("53213606042373287683153647684084583002441527525177758051678463570615020765660540938870067881706148841340293404257")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("136011650568921952309089811450436645471254909718073766303847394446918967077385999380499048535832357755732371368738"),
|
||||||
|
MontFp!("167478505497067957490757520193067128323382872103395718848436244112857102765738573826312783708349214669979612036158")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("124201488690791095020042847186337439989685011854729481246272047846908500431421470344897520044190299684207452017073"),
|
||||||
|
MontFp!("206045464105062318563700338460670926332476051084269665075012377410704353049241671458557389593362582538704238377616")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("141307886851791570111930048284226290849958071383456038631306928334570275405889250568493573543543795501685612269615"),
|
||||||
|
MontFp!("33695298953151791677564491610276872092952551110021466172491397823758283921068636555353240048692541883780027233962")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("248265339860070148327157063205450906034372346050742532250909040050681913704941472496789561564874787781299103889328"),
|
||||||
|
MontFp!("246735083688655178976599901436968434779493759990448799231310864308891009496294971885106650388027197609829556319894")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("242374981274128257174433646391488180576863913259197526647513270422870835725158808599624055920155693832356361192562"),
|
||||||
|
MontFp!("228823832066259533984346839854456963456061412139464585495219844904598927917971403987214543635705786807302526573779")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("252218794556637183364789705825049189219556217519670190016584589877973440046635828866291293002549365274213665103495"),
|
||||||
|
MontFp!("246226868929550107779875102413192686259972538740042993595504829761267272514998892312681511407413880843390092913913")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("194440756770673250653849096711805826346541581797630354589253365569405779009028682866443842541588052010949210024484"),
|
||||||
|
MontFp!("75265817091612360444217709043194311507703596250641164601263089234422086318666070167810083868284770450890779266774")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("30126025128311053094362231518416999154688680759401769180563223025361877725315179695978985780460875616652938854146"),
|
||||||
|
MontFp!("53390417057360854696711134553867053334956120915983753729596602193155006833056717338565729257476036879055975910097")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("101332532133743769759178027285109552486478973958553103055307446365529747250973790438239230671819476569086244438727"),
|
||||||
|
MontFp!("148745905560783494991892238622790396213255789465409808038709750840775025617296316699696997331989504328034553213894")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("64805743514968884017432304617184871899075979363892814607985017391426869625002757534871594116135107848421987411961"),
|
||||||
|
MontFp!("6046324386958113626500748531301314307229746408846776295678625368971798823548167403538529285882066298168231669149")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("42585898388361518080924198789209195881860509830112816215046001795045034138585747974649960102171072364466234418812"),
|
||||||
|
MontFp!("132695208880203057798268960407754614753345990251279710979596670783892175104478291787481794529190706739877760089560")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("212862020601301354783026588297306531610140885387724836359356800753780855161155144746080869191538655229274242914307"),
|
||||||
|
MontFp!("157598266513011182093451150345114371606842593014102635902061162138398777778450012845089379844999350325670077782200")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("4121090928751590306336774011079865996138664888804166805010515676212588791761189056383637824656513752764121888675"),
|
||||||
|
MontFp!("183219245849642047090141657656072708461001592401873575143115550847958265143529306190408825011434780265059908079650")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("79081485025787885179619178550309706744599846607596447880706626420512740963985633088538634502003788677250834958908"),
|
||||||
|
MontFp!("183808890703436998546164599111050972902808423546263572335175957576564587842514119276068990911067829699066843757937")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("212106075999882114389916784897163150756429321557076536924307653148222968665985018997130331497354557069316538670523"),
|
||||||
|
MontFp!("6765896997590927451499527318422027932088882822980873934837948553969718709492787823596776070132570199077127482065")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("234716866510887739589745422464313597883163631119309437461957606368046054279070563732715561665778636277317684644515"),
|
||||||
|
MontFp!("97451989647642778641795555357790293895920858058713680518946629728091416392679362160653023502048556793761866531581")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("172147863909779437473600759248856356840207842931344727009188760756830505857976640403412821403996887953725715762255"),
|
||||||
|
MontFp!("210880269899843225414111521931364427157014189139153931141845520612300425501022712679200902179085486362182614989038")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("1"),
|
||||||
|
MontFp!("0")),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gen() {
|
||||||
|
let gen: G2Affine = SwuIsoConfig::GENERATOR;
|
||||||
|
assert!(gen.is_on_curve());
|
||||||
|
assert!(gen.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,35 +1,39 @@
|
|||||||
use crate::*;
|
|
||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bls12,
|
bls12,
|
||||||
bls12::{Bls12, Bls12Parameters, TwistType},
|
bls12::{Bls12, Bls12Config, TwistType},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
pub mod g1;
|
pub mod g1;
|
||||||
pub mod g2;
|
pub mod g2;
|
||||||
|
|
||||||
|
mod g1_swu_iso;
|
||||||
|
mod g2_swu_iso;
|
||||||
|
|
||||||
#[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;
|
||||||
const TWIST_TYPE: TwistType = TwistType::D;
|
const TWIST_TYPE: TwistType = TwistType::D;
|
||||||
type Fp = Fq;
|
type Fp = Fq;
|
||||||
type Fp2Params = Fq2Parameters;
|
type Fp2Config = Fq2Config;
|
||||||
type Fp6Params = Fq6Parameters;
|
type Fp6Config = Fq6Config;
|
||||||
type Fp12Params = Fq12Parameters;
|
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,130 +0,0 @@
|
|||||||
#![allow(unused_imports)]
|
|
||||||
use crate::{
|
|
||||||
g1, g2, Bls12_377, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G1TEProjective, G2Affine,
|
|
||||||
G2Projective,
|
|
||||||
};
|
|
||||||
use ark_ec::{
|
|
||||||
models::SWModelParameters, short_weierstrass_jacobian, AffineCurve, PairingEngine,
|
|
||||||
ProjectiveCurve,
|
|
||||||
};
|
|
||||||
use ark_ff::{
|
|
||||||
fields::{Field, FpParameters, PrimeField, SquareRootField},
|
|
||||||
One, Zero,
|
|
||||||
};
|
|
||||||
use ark_serialize::CanonicalSerialize;
|
|
||||||
use ark_std::{rand::Rng, test_rng};
|
|
||||||
use core::ops::{AddAssign, MulAssign};
|
|
||||||
|
|
||||||
use ark_algebra_test_templates::{
|
|
||||||
curves::{curve_tests, edwards_tests, sw_tests},
|
|
||||||
groups::group_test,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_projective_curve() {
|
|
||||||
curve_tests::<G1Projective>();
|
|
||||||
|
|
||||||
sw_tests::<g1::Parameters>();
|
|
||||||
edwards_tests::<g1::Parameters>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_projective_group() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: G1Projective = rng.gen();
|
|
||||||
let b: G1Projective = rng.gen();
|
|
||||||
group_test(a, b);
|
|
||||||
|
|
||||||
let c = rng.gen();
|
|
||||||
let d = rng.gen();
|
|
||||||
group_test::<G1TEProjective>(c, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_generator() {
|
|
||||||
let generator = G1Affine::prime_subgroup_generator();
|
|
||||||
assert!(generator.is_on_curve());
|
|
||||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_projective_curve() {
|
|
||||||
curve_tests::<G2Projective>();
|
|
||||||
|
|
||||||
sw_tests::<g2::Parameters>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_projective_group() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: G2Projective = rng.gen();
|
|
||||||
let b: G2Projective = rng.gen();
|
|
||||||
group_test(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_generator() {
|
|
||||||
let generator = G2Affine::prime_subgroup_generator();
|
|
||||||
assert!(generator.is_on_curve());
|
|
||||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_bilinearity() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: G1Projective = rng.gen();
|
|
||||||
let b: G2Projective = rng.gen();
|
|
||||||
let s: Fr = rng.gen();
|
|
||||||
|
|
||||||
let mut sa = a;
|
|
||||||
sa.mul_assign(s);
|
|
||||||
let mut sb = b;
|
|
||||||
sb.mul_assign(s);
|
|
||||||
|
|
||||||
let ans1 = Bls12_377::pairing(sa, b);
|
|
||||||
let ans2 = Bls12_377::pairing(a, sb);
|
|
||||||
let ans3 = Bls12_377::pairing(a, b).pow(s.into_repr());
|
|
||||||
|
|
||||||
assert_eq!(ans1, ans2);
|
|
||||||
assert_eq!(ans2, ans3);
|
|
||||||
|
|
||||||
assert_ne!(ans1, Fq12::one());
|
|
||||||
assert_ne!(ans2, Fq12::one());
|
|
||||||
assert_ne!(ans3, Fq12::one());
|
|
||||||
|
|
||||||
assert_eq!(ans1.pow(Fr::characteristic()), Fq12::one());
|
|
||||||
assert_eq!(ans2.pow(Fr::characteristic()), Fq12::one());
|
|
||||||
assert_eq!(ans3.pow(Fr::characteristic()), Fq12::one());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_generator_raw() {
|
|
||||||
let mut x = Fq::zero();
|
|
||||||
let mut i = 0;
|
|
||||||
loop {
|
|
||||||
// y^2 = x^3 + b
|
|
||||||
let mut rhs = x;
|
|
||||||
rhs.square_in_place();
|
|
||||||
rhs.mul_assign(&x);
|
|
||||||
rhs.add_assign(&g1::Parameters::COEFF_B);
|
|
||||||
|
|
||||||
if let Some(y) = rhs.sqrt() {
|
|
||||||
let p = G1Affine::new(x, if y < -y { y } else { -y }, false);
|
|
||||||
assert!(!p.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
|
|
||||||
let g1 = p.scale_by_cofactor();
|
|
||||||
if !g1.is_zero() {
|
|
||||||
assert_eq!(i, 1);
|
|
||||||
let g1 = G1Affine::from(g1);
|
|
||||||
|
|
||||||
assert!(g1.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
|
|
||||||
assert_eq!(g1, G1Affine::prime_subgroup_generator());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i += 1;
|
|
||||||
x.add_assign(&Fq::one());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
115
bls12_377/src/curves/tests/BLS12377G1_XMD-SHA-256_SSWU_RO_.json
Normal file
115
bls12_377/src/curves/tests/BLS12377G1_XMD-SHA-256_SSWU_RO_.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"L": "0x40",
|
||||||
|
"Z": "0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508bffffffffff6",
|
||||||
|
"ciphersuite": "BLS12377G1_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"curve": "BLS12-377 G1",
|
||||||
|
"dst": "QUUX-V01-CS02-with-BLS12377G1_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001"
|
||||||
|
},
|
||||||
|
"hash": "sha256",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": true,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x0123184bf576b5d69c00311c57eb503e3df99ab60156a2bc34228e46cd1b0c8a15304f0de63602ae32bbb08a7f44c2c9",
|
||||||
|
"y": "0x017c05a4f658399a64f5028b1c5d8a928f6a955bf28525d906592b9e6aabdad838102c6b1b4a9108898931fa42ef0cdf"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x00e10a1e6c2853d3416288652f6cda34fd2363c993f4c4fdebb38f185855fd17fdae6f8b35f6586abf39b746e14c0297",
|
||||||
|
"y": "0x0132b86c328a4c52e82db1a43257ca0cb5a8f8e2546b92a854117ab26cf6607e9d8c207854d8597426c6987ebca42d97"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x005648e0f6aa7131780c1ae8d396bdac0dc8e76426b8a2adf6b0dee3a0f80b7152343332a9c2ad5c83113b8956fe2685",
|
||||||
|
"y": "0x0196b1ffad506901d481b632f7dc9ebad6e3eed84c7d03edab2c7df0b1566c5b5d376aa2bbd4c7c169abc449f3129f9c"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x00e91c93755d4dce58b4277d109ca11cb178e160d0209f0b97c0ef0a9d03206bdb93498faaaba98969d4a50f91d8fed3",
|
||||||
|
"0x01442032ceae5c549af8f3222a0b9fafe5ef19a001ab399c2ddbb9f7dd59671150a067bd104604bc7d7fb9b909a2b276"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x015756bc7b5a8140577878f75009f8a0009bf1820719354863a52057d0758b27ff7d843e177fc618146edec267d1510f",
|
||||||
|
"y": "0x013b4be1db30d04593dc965b804044c2f92e366543f32377463a0deeddf7ddaa0e62e843d5590e948e5a0d9af2b917cd"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x01029fe43eca43ce7adca5d31a84b66b28fc00de3adcddd393c3ad1bd993e24cf70a9dd99b8233d2a657536943cc5000",
|
||||||
|
"y": "0x0011e54e8956bfbfdd17dab8b91e571a49ef5c5c7a5b3c00f9ecb045c39c6f59e3c60c3cc0d290c0e5effde15672ce8f"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x009e6c4f23e3590fb40b0a622a3cda01addda2a4ebd860ba4d87615c299f87e02c190035e593e6b80b18282d37168f3a",
|
||||||
|
"y": "0x0090c6fac6f33662a3b50631e367b087e144315a4400bbfbcea7c16366cba865893c85bfa79d82cad31954925363219b"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x00cf409921dcdce7de4b3541144bbb5c41592a95278af448bb6f6287e5a71b71c8148a03b8f98cf6e654b2a93bf89c5b",
|
||||||
|
"0x00bccdefe8cbec53dad21b03a0d1f05e1e4c401a7f20ff349043ff1afe8074ea4edb457a2181d6388a41be08445f1099"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x01a6d66a21a28362895c867fa2a65e5e54fd85171a0a8327faec0f7272dd5fbfeaafb311d7e83c85dfabbc790fb8031f",
|
||||||
|
"y": "0x01183a9c2d97c91c06cb090e69cfdf0e89e92baa780b8e3c5e1d92488d3a2422896c4ab808ab099f0b4d9203c7499147"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x017397c57e444777264e21318d6e0096779eccafd05f7a95a87acad1f8730fe7fe9e1d1dbf1ddf11539515596ad71861",
|
||||||
|
"y": "0x01660b0335de45c1d4e7edc3b1230bbedaf598cc3943ce854fc2d86d84080486c4b0f325dbcbef0212b99ee3d0994f58"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x00cfcc6e7987859db4156bd643a7ac69357f0fa86c6fec36e039b2822001c90fd852c4afa98a5dcb00e65280299520ed",
|
||||||
|
"y": "0x01823e2bce6d7769163f6646e6d80944572a6c473d7760b0b55911697437e7bedbc6674a4cf55850d03bc238128e9479"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x019061c2817582abc25c57a58f08f5239bd8d0eb1980d2b911e38131a779e0991c5a5662eb8a6aad8ce0bbc0cdfb67b8",
|
||||||
|
"0x003d673f221f321f652ad6baac32fd04ad1c06a2c03e4974f752e9b87f5fe222b120e853c7a7c767255adda229c71a49"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x009574af6ebc91ea9e337178cbd5c83ecb9d42fed22b3272c3e50b1840c5089fe5bec9808eaaba8a06ced26a30b82747",
|
||||||
|
"y": "0x00ccbad45957f1d493c1859e325c27dca3c63ac49177a1b2a9b5e22e14fd23845a638214e85506f46260db2827e2869a"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x00a4721db398949969915611e7a65cc43d167bc9c6b11fa69e871663aac40266a4a01ae64ac380dcce313f9975fe8f2b",
|
||||||
|
"y": "0x002123e943b9a1943d7a57e69e30c84c9bcebc96905b920365f2fc5a4af2f9c42bc1c7c5660d3b10de8c8b1381b8163c"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x00860490ade9e09cbf22a1f32cfe14bd1e82721b73a244d1e3e03a38ea45b0332dca194a5f43bbc8e9bc6319399a0a13",
|
||||||
|
"y": "0x00279ad50592f1a5b92430020566b2bca7837bef7fe0f8e08d456962b7ff6a25b4839863baa4a9659bee69af343d8ed9"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x000ec0c5ca9fd63019bd1f989f8b054b29a0a1833a0e3078031da7bb6446de321ddd6ba40a7cb9dfc70afca8bac538ff",
|
||||||
|
"0x000e110ff18deec2d60a2dfc92642fdebd6d70712114a6310e1f3eadf56e608a05058d378413fdb819c8274437f0d440"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x00c54bd72909539ce2c7558b081a7ab7cf8643cb5c02e87d233f6458c69c1a9270ebb0a6c42083ba38835a2698a57cde",
|
||||||
|
"y": "0x01a9529726f7d9994634d1d02c1ab474e2b9c20f2cb0cfec7e566ea033f40438548e737c43d4e7d1cb2fb75bf7686533"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x003ca77f5b09d595550a258c0480381569c8ed1caf4bf69e3c8a530d1d910d3ee941a53f6abc452219aa79f22734e61c",
|
||||||
|
"y": "0x004d376f45eb23e03be43ea5c1e00f9290d800d01ff0141c8faa8d1b0bd88c2ee8f3bb8c7ce17ddfe21633ec2b223780"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x011f325cc402afd10b3b92a6ea9f52440d9fda541cd2fe6bf58040bf803f23a22c59c3dd494c1392f911ffec1a283b98",
|
||||||
|
"y": "0x00346cb1d6116a329e755b913f5d2d9c7f5405b21e8e400853791ffaefc18a1b1aa8610bbbd4961fe112aa78d1859a40"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x00d5ca54c4622a2f8ec71843ce327959689ae7ff37e7509a88212b3b852e213cbef248471eac50bfdbca3c9ce733d8e8",
|
||||||
|
"0x00b91b02d867e03924593529ae87f35a2adf317a87209bed9c91d5c886e801191676a272422454c7d9692b8368b02e21"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
bls12_377/src/curves/tests/BLS12377G2_XMD-SHA-256_SSWU_RO_.json
Normal file
115
bls12_377/src/curves/tests/BLS12377G2_XMD-SHA-256_SSWU_RO_.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"L": "0x40",
|
||||||
|
"Z": "0xc,0x1",
|
||||||
|
"ciphersuite": "BLS12377G2_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"curve": "BLS12-377 G2",
|
||||||
|
"dst": "QUUX-V01-CS02-with-BLS12377G2_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x2",
|
||||||
|
"p": "0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001"
|
||||||
|
},
|
||||||
|
"hash": "sha256",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": true,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x012988d49df0158335f268551a0121a3fd5509580e675ed2e26f66ffb8ec1089b9db4a69bd19db25f7cae34619b8542a,0x0060eecba902692a7f95900c6501ea3f6e6f52b2e951586f60c9f31585c4fb63cb5486d155df4bc394a872f6e0bc3eea",
|
||||||
|
"y": "0x00e07c09af8c992a920bdfcdba4db43b542c5799258f2a01897d5a0c621db77c29f02ca2afa99d78dad2abdd4e180d89,0x00020a02b4d45959b67af782b737915298c203dada50f9d4941ada19ea7e986e91a83cb33d01af449dc540244b418561"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x0040618d422085e035e06f0333349c4630b7e47d96c45b803db208243cfe176cc9b89710c0ac9b6c25387772b0253de9,0x016e1c02056c1c0d179c0225b37845f1ea7fdeede136d731b2365248003829bee421b65f64b43c579ad9b30469d6cdd1",
|
||||||
|
"y": "0x0011e6e3019b9c453e3b930a091fb514b082e0353dbd58185d8e9211ec33d036c7c1d535ba020ad2b5cf584aab23fcf0,0x014063792b5a789670e1f75fd996a22fa9174888dd315fdb8b4597bdd7572edbb145817b933a0f79c467dabf473ed98c"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x00d0ec3127b58d178301f9f63be6932d2bf84a71fc79e50004efe7d13ab9ebd80cb7a958a369a1061e5aeb5365d657d2,0x00a69c72d1855528334e08529d9d304d39326e5670943f2fa3d57f32b4e1ce215a7df744bff01574e5ef35826e61cdef",
|
||||||
|
"y": "0x0158d9d3ea783058becfbde70cf6215c53a9afd702308c551c5d8b02e00240e20ff93d2d4515d3033b92d44b76f063fa,0x0111257e46569bdb27e1c54c51b57a0aef5c5b287e28205b6b08bb585087774993895c2886dcc500c98fc3af92f114dd"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x00bad459056ed98adf92ddc87a4b9970b8ce50e5c1d811f72a5631f0ee41eeba11bdc1fcbf135ab259f7be9dbf44c3f4,0x018d496adfe469a57596f015eebd869b7bed74083c573bb4b9d40a471e082517e5b744dac07eb67dac975bb8411766c6",
|
||||||
|
"0x0022395aab1038ade247f4b17deb81f4b00cabc04ad532fd3ac580ddbfcb44b3cb9d1d1976b09de603a0a228e713ae7d,0x01a366c20f9c2c1bc6b766e25856a85967a104d616680f4a79d97745c224fdadff08940f11ae0b26ea96f656f28b5e78"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x001346f07170e2ed45d08def787101795af173163239e7a1ee3297fd4e2b4fb6d76380058612e745a62a6fa6186744b7,0x00977c6b055e2b80e68afb986a05870294628464393619a2d92a698abcbc8927fe9729b4b72daac63e7f0c76ef711992",
|
||||||
|
"y": "0x016896c5571627fb322a371c57528f98131c51b1dc4ceb2be384610dc3f1a224236febd2c501bcea4d387a3c0c7b4e1c,0x007a86495cf20600a5d066b91a726df0b7d67f8758d7ed3fedb797d8772805c52eba9a7bd4661d37932f855b05f19892"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x00af89668bbc75ea1818bde76c0d126f516356b5b4da3f06603a0c4af5c68e44e8984ce185b756287b9aead31fc54c4c,0x0013b1d55b0cf613f54d056541daea78edc693750cb992564a9a7861e66f26b3cd4da71a30295dea0e40f0809847a030",
|
||||||
|
"y": "0x0127448b51269ac893ef00a585646b14371c0af69cafafaf3176e663f4e033b29a85e332116d8d9a3bfc8d1873730866,0x009a3aad06b68199b2e66fc1dafe20dcc5af8dd740be98fe7db529b424f098ae27759d7613f1942e9b1602664868c17b"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x009fc985f056445b2f6156a8021faff087f9b8d4690653346ca74b4420589fdbe511491fec0c535b52d521c1bb4be400,0x00f920679bd77a0d50d624513cf2296e4565f57dc3d7a578ddb19bfa60f05de1d5954ce247979fbc6501af72cd62e334",
|
||||||
|
"y": "0x0164c6cd007aba3e295df8310a2da71ef40022cec7a2e51dcab9f3850795ac823c7bb65082a88199d7c378b0ac4e9257,0x0028633591401d7da706fcb4a4da6f8999a7aff7b167bb96fd92511dca61f62f4b4e0be3213f0d68841a110b39c5a685"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x014a48b15756981016043ea1be11e30a728877c090f3beb8bd56cdadeb98792c0f47246c99c92c6a6d9b4f2ccef6d09f,0x01445002d867fb15a2d50311d23ace363b27befbe88d5feecababd66082e6b056d306f7f9dec8d3f4dfb1b2314963cec",
|
||||||
|
"0x001559a97f7639b2b5122e90b51a35c6714903b15cdab56bbe16eac4f8a0bd1514b412867f46f6948362c6f29d88c9fb,0x015556fa42d21cb9c6af6de63f6fbfcd6cae7c788e1b74c978f9c2ad1aae724912ff47bd4bab7d77c2af68b9c45b8c49"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x00dceaed928808d01aff4fc8c762d8cda12cc7ba1f6e721887606ee40ed0df1186f8cde71550636425de7b5ec0137fca,0x0166a7280c74d1bb3f0fd8c48aae30b855ba1a59a1dc309fb743f44b958ee721f1c273ee9ccc17e5ae931d566cf93671",
|
||||||
|
"y": "0x003125c58959ccbbca6e456a531833720d87dd039068ec1c4dbeab97230db643c71fb47e6be54eda3a470f452f3d6b1c,0x00d070fa5ebd18f6af02f65102b74cc379af99ab9d2b797a316c736bda39fb209bdaee9b59877cd0925c9d0949d91b0a"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x013c8c7d3aa93cb082f1b83edfd76a44a17aba8253a4b0a183b679b9e4d85e1e9653145b4947320187e99825d1846149,0x014e9afc495733168d15ebddd8d5177563e2b33a584a9993cef5536a1bba557590f37fc79651825cdf7bb6516ab54a88",
|
||||||
|
"y": "0x008a53b0d7d5a96b9fb7a15c60374028f1ab06c6545c69cfbb6ad7320e3933c64bb13b5139009ae7fb4dc0d29a1eacbd,0x0081a61008d4e7204c4a0268c1b4a369d142f4cfbfc8ee794d9653d89dc42d9b27e208ae0f11167d7eadfb56c7d4d1da"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x0062e543539c61cbfeb512fd1ec5f58bedec3ecc8bfec05de8043bfa92fec6fd7a671c9d3c9b0f86278ec6fbf4ae02a6,0x00f9402ce08a6d603d17d45dbaeda0babc9188a7837dba10c4aaad3e4dba9b5208b8df01d0635c30cb913ab16d9d23dc",
|
||||||
|
"y": "0x001c23bb7a1789b4afb3d896e497e8c9d5d4018721ac1303836265bd3d54e7eaa5f63ba45fa8e3776642fa27f049d792,0x00cd3bf5161c9ac44a3a490beb0e12c91de09706c4c86b369da263ee63560e84c30ba0ebd72536fa7f874539f2d590b1"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x014058fb0e66728eb352ca096e0ff6534512d1b8da4391b192da08e1d45d86064c92f01568889b13318cc3ad8144190a,0x004f706e3d9a2a46f32f2953cb7a305d092ffb332f085d6ff4ec063d24686c8917a9036e0699c7dcf48f884f1e47ab2e",
|
||||||
|
"0x00cf38b24a429230e04edbaf3b759aacfd37dc8dcc9b297b65b1b9705858f4d3bffee8b10324be05d7e4a18bcc4cd863,0x00c478b8e924194155ae97dd29ed2374cf8e207049e32bfb1519ead43702d49f22208ce12b058e7ff31ae7866f05959e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x00cdb3038598c178025dbaf99dcd440d99c2b38d5b8041893d67002e7c6bab93beaff51439845d06c63f6ddd7c5c401e,0x011d2a48f51437628dd6508f6bbb306da621acadf14fbe9e8f47ddf1915beea1e4e3286319c172a32742d7faa45a5b7f",
|
||||||
|
"y": "0x00cac5a0278869557095a63c6a7203468a71d58ad123aaa82f72381cd94250c01479ea8cbe643a8341678679305bc01d,0x01a91041b5c1406e643b44d4564babe6f2bdf5fa3c1620419fb6cdb4ba294f1494a33fc829784cc14cbc8066c5310a87"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x012f22361e00eb23ffe9082f1b4bf4822553cd42c8367588e5329fa166efdcf09c53e0e0b5f06e2a610f42c6b278050c,0x01aade240952b9e4db24fd88e0b0552904b3cb8bab3e4cfbaf2a5c35da48127ef75d1348d76225e8fb896c62766902b5",
|
||||||
|
"y": "0x00f205ed12fd5bdeac9a95349e8383ab854dd59690992b6240357652246388e3224ddfa5ce06de195dfe4e9dc2c5a901,0x01203782b3fa65de7ab229eafae08b4ea9bae437e195491b03fab30ddce83881a0b940b33f0f3e7bd7feca2c76e139d6"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x0171cca78371628178ecc12072e263eda9725524b5de48e340ccc8514897834b81cf36466ef7e2473f88aca8830fd0c7,0x017273b33c0259339fac166bf927a66da0a6b40b751048a0093bb4e5d37c35f2a7318e393d4aaef61435ad4471603662",
|
||||||
|
"y": "0x008fe7352facf00e07a74b1315db5b308827577c53a950607fe25974039598f017ed7cc054c1d279dd4957a19435d16d,0x0083382ba5e521808254bf1e058dd663336bf591c564d15a0df71791c4124c2ab38baee90d1d4435f4d6c3967df0f9ef"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x017afe7f987942b49e66831d61b785992f3172b2387f55e97863062e81734b0001bd64ed508d6721956741688dc9af0b,0x00631bcf5d854071890838210f50dfa1359da5ff4694255b7cd6ed630e4c6dfca746c69a9c5f3d76ee3cceae20bb355b",
|
||||||
|
"0x00b1fc859bd156b84a8b95d503db388a604c7a05ead79f8cd08cb21b677f3bd77143d8334ff51ddbc77ebf670b7839fa,0x00df8ed5ad61dced6490d9b58585fa3803f04f0b7d4efee366296339e634201c6f8924c8c3794c45685f49c6f974cf7e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x00bc60ec05a3e54f000d07e4ef4d86c9f5bbc8d17aae021f547615a1c89a374bb47fdd25aa488ce8ad6e4b45483cf70f,0x00dac74d2a7d021f868b1ba53075fbb5d8b44fa709ba1b94d904d18cd79373bf23e277ca808bc70b64bd47fa877e81aa",
|
||||||
|
"y": "0x010dc70c8b009d9013768bef31ebf18db9ae405fbbdebf7cb8ced20d10ef633e66e3c2301e233e375e75c972f9dc11f1,0x0040e8b8abcd97f7bb841fb35655830456be9b0e931db9dbd40307ce7380b53351d22557ca29204b55eb7298cc3b1e0a"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x01891e447beb5b70294a6f5f7e0230faed4b3119353bf55ad2afa86cc266359350c07d1eb974389a67533c07f15d506b,0x0164482864c5fabe4716cc80bfd8776a8037d87dd141058737c5cf407aa39ec76b78564621637edb6c2ef6b8921d72c9",
|
||||||
|
"y": "0x003b6cffeb0e47c6bd294263d38fb8908707502415d850d06b524a61e1de100d8a768996c6cb8c8d67b8e88cd3dcb4d7,0x008ac2f1ea197c81aab704952b808f0cb418d63df22b39d5b88c000c40890200934e8695aac7345e3da11493d76c4231"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x00f507c2c5090a0e1d5c8e8db72e168c461cb99cbab2f9672934a3a2d92b81501553fce7bc3da3d53fc487dfe7512dd0,0x004d70e612013e7b66829a9d3e7d0f8a865fa3cddb794ce30e3b145d4287e4eca91977889f0a6a3837089c34c4ca035e",
|
||||||
|
"y": "0x0055eb01ee257e72fc09d0cb36162af8d98bbb9cad244715cfd63dc30e66ff452d6f4519c418654b4110eabcdf701f76,0x00a20ce3bdb4d1da6b8047caf4b7c2285265021dff3b1c1a760badef8d5b108aff67a13d964218711613330b3f0c3344"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x011c761e1ea0285445d16b6982d2c58b8ac14ac32dcecd59a76d652c86adacb8643fabc49f6340a9bbb85220ae3272db,0x00a340146d9af76164b2aac1026bb445b0f4a9d8d65725c2b26051c905b40146548056e0828590573efb151312ed97de",
|
||||||
|
"0x000edd1a63bc707aef87eed2bd7bf933247a697404d4ed1abebf8db4670cf14c9ebf6b138c642be96bc7fa9616284e7a,0x00521fae4b02b3a025c08bbeb2c4783786f82816b7f4c8d496f4715906a3b1085cd48d9d2b58588c138ae4757e220a91"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
59
bls12_377/src/curves/tests/mod.rs
Executable file
59
bls12_377/src/curves/tests/mod.rs
Executable file
@@ -0,0 +1,59 @@
|
|||||||
|
use crate::{Bls12_377, G1Projective, G2Projective};
|
||||||
|
use ark_algebra_test_templates::*;
|
||||||
|
|
||||||
|
test_group!(g1; G1Projective; sw);
|
||||||
|
test_group!(g2; G2Projective; sw);
|
||||||
|
test_group!(pairing_output; ark_ec::pairing::PairingOutput<Bls12_377>; msm);
|
||||||
|
test_pairing!(pairing; crate::Bls12_377);
|
||||||
|
test_group!(g1_glv; G1Projective; glv);
|
||||||
|
test_group!(g2_glv; G2Projective; glv);
|
||||||
|
test_h2c!(g1_h2c; "./src/curves/tests"; "BLS12377G1"; crate::g1::Config; crate::Fq; crate::Fq; 1);
|
||||||
|
test_h2c!(g2_hc2; "./src/curves/tests"; "BLS12377G2"; crate::g2::Config; crate::Fq2; crate::Fq; 2);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use ark_ec::{
|
||||||
|
hashing::{
|
||||||
|
curve_maps::wb::{WBConfig, WBMap},
|
||||||
|
map_to_curve_hasher::MapToCurveBasedHasher,
|
||||||
|
HashToCurve,
|
||||||
|
},
|
||||||
|
short_weierstrass::Projective,
|
||||||
|
};
|
||||||
|
use ark_ff::field_hashers::DefaultFieldHasher;
|
||||||
|
use ark_std::Zero;
|
||||||
|
|
||||||
|
/// make a simple hash
|
||||||
|
fn wb_hash_arbitrary_string_to_curve<WBCurve: WBConfig>() {
|
||||||
|
use sha2::Sha256;
|
||||||
|
let test_wb_to_curve_hasher = MapToCurveBasedHasher::<
|
||||||
|
Projective<WBCurve>,
|
||||||
|
DefaultFieldHasher<Sha256, 128>,
|
||||||
|
WBMap<WBCurve>,
|
||||||
|
>::new(&[1])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let hash_result = test_wb_to_curve_hasher.hash(b"if you stick a Babel fish in your ear you can instantly understand anything said to you in any form of language.").expect("fail to hash the string to curve");
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
hash_result.x != WBCurve::BaseField::zero()
|
||||||
|
&& hash_result.y != WBCurve::BaseField::zero(),
|
||||||
|
"we assume that not both a and b coefficienst are zero for the test curve"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
hash_result.is_on_curve(),
|
||||||
|
"hash results into a point off the curve"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn wb_hash_arbitrary_string_to_g1() {
|
||||||
|
wb_hash_arbitrary_string_to_curve::<crate::g1::Config>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn wb_hash_arbitrary_string_to_g2() {
|
||||||
|
wb_hash_arbitrary_string_to_curve::<crate::g2::Config>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,118 +1,7 @@
|
|||||||
use ark_ff::{biginteger::BigInteger384 as BigInteger, fields::*};
|
use ark_ff::fields::{Fp384, MontBackend, MontConfig};
|
||||||
|
|
||||||
pub type Fq = Fp384<FqParameters>;
|
#[derive(MontConfig)]
|
||||||
|
#[modulus = "258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177"]
|
||||||
pub struct FqParameters;
|
#[generator = "15"]
|
||||||
|
pub struct FqConfig;
|
||||||
impl Fp384Parameters for FqParameters {}
|
pub type Fq = Fp384<MontBackend<FqConfig, 6>>;
|
||||||
impl FftParameters for FqParameters {
|
|
||||||
type BigInt = BigInteger;
|
|
||||||
|
|
||||||
const TWO_ADICITY: u32 = 46u32;
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
|
||||||
2022196864061697551u64,
|
|
||||||
17419102863309525423u64,
|
|
||||||
8564289679875062096u64,
|
|
||||||
17152078065055548215u64,
|
|
||||||
17966377291017729567u64,
|
|
||||||
68610905582439508u64,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
impl FpParameters for FqParameters {
|
|
||||||
/// MODULUS = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const MODULUS: BigInteger = BigInteger([
|
|
||||||
0x8508c00000000001,
|
|
||||||
0x170b5d4430000000,
|
|
||||||
0x1ef3622fba094800,
|
|
||||||
0x1a22d9f300f5138f,
|
|
||||||
0xc63b05c06ca1493b,
|
|
||||||
0x1ae3a4617c510ea,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const MODULUS_BITS: u32 = 377;
|
|
||||||
|
|
||||||
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
|
|
||||||
|
|
||||||
const REPR_SHAVE_BITS: u32 = 7;
|
|
||||||
|
|
||||||
/// R = 85013442423176922659824578519796707547925331718418265885885478904210582549405549618995257669764901891699128663912
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const R: BigInteger = BigInteger([
|
|
||||||
202099033278250856u64,
|
|
||||||
5854854902718660529u64,
|
|
||||||
11492539364873682930u64,
|
|
||||||
8885205928937022213u64,
|
|
||||||
5545221690922665192u64,
|
|
||||||
39800542322357402u64,
|
|
||||||
]);
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const R2: BigInteger = BigInteger([
|
|
||||||
0xb786686c9400cd22,
|
|
||||||
0x329fcaab00431b1,
|
|
||||||
0x22a5f11162d6b46d,
|
|
||||||
0xbfdf7d03827dc3ac,
|
|
||||||
0x837e92f041790bf9,
|
|
||||||
0x6dfccb1e914b88,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const INV: u64 = 9586122913090633727u64;
|
|
||||||
|
|
||||||
/// GENERATOR = -5
|
|
||||||
/// Encoded in Montgomery form, so the value here is
|
|
||||||
/// (-5 * R) % q = 92261639910053574722182574790803529333160366917737991650341130812388023949653897454961487930322210790384999596794
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const GENERATOR: BigInteger = BigInteger([
|
|
||||||
0xfc0b8000000002fa,
|
|
||||||
0x97d39cf6e000018b,
|
|
||||||
0x2072420fbfa05044,
|
|
||||||
0xcbbcbd50d97c3802,
|
|
||||||
0xbaf1ec35813f9eb,
|
|
||||||
0x9974a2c0945ad2,
|
|
||||||
]);
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
|
||||||
0x4284600000000000,
|
|
||||||
0xb85aea218000000,
|
|
||||||
0x8f79b117dd04a400,
|
|
||||||
0x8d116cf9807a89c7,
|
|
||||||
0x631d82e03650a49d,
|
|
||||||
0xd71d230be28875,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T
|
|
||||||
// For T coprime to 2
|
|
||||||
|
|
||||||
// T = (MODULUS - 1) // 2^S =
|
|
||||||
// 3675842578061421676390135839012792950148785745837396071634149488243117337281387659330802195819009059
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const T: BigInteger = BigInteger([
|
|
||||||
0x7510c00000021423,
|
|
||||||
0x88bee82520005c2d,
|
|
||||||
0x67cc03d44e3c7bcd,
|
|
||||||
0x1701b28524ec688b,
|
|
||||||
0xe9185f1443ab18ec,
|
|
||||||
0x6b8,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// (T - 1) // 2 =
|
|
||||||
// 1837921289030710838195067919506396475074392872918698035817074744121558668640693829665401097909504529
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
|
||||||
0xba88600000010a11,
|
|
||||||
0xc45f741290002e16,
|
|
||||||
0xb3e601ea271e3de6,
|
|
||||||
0xb80d94292763445,
|
|
||||||
0x748c2f8a21d58c76,
|
|
||||||
0x35c,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub const FQ_ONE: Fq = Fq::new(FqParameters::R);
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub const FQ_ZERO: Fq = Fq::new(BigInteger([0, 0, 0, 0, 0, 0]));
|
|
||||||
|
|||||||
@@ -1,74 +1,74 @@
|
|||||||
use super::*;
|
use ark_ff::{fields::*, MontFp};
|
||||||
use ark_ff::{field_new, fields::*};
|
|
||||||
|
|
||||||
pub type Fq12 = Fp12<Fq12Parameters>;
|
use crate::*;
|
||||||
|
|
||||||
|
pub type Fq12 = Fp12<Fq12Config>;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Fq12Parameters;
|
pub struct Fq12Config;
|
||||||
|
|
||||||
impl Fp12Parameters for Fq12Parameters {
|
impl Fp12Config for Fq12Config {
|
||||||
type Fp6Params = Fq6Parameters;
|
type Fp6Config = Fq6Config;
|
||||||
|
|
||||||
const NONRESIDUE: Fq6 = field_new!(Fq6, FQ2_ZERO, FQ2_ONE, FQ2_ZERO);
|
const NONRESIDUE: Fq6 = Fq6::new(Fq2::ZERO, Fq2::ONE, Fq2::ZERO);
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[
|
const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[
|
||||||
// Fp2::NONRESIDUE^(((q^0) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^0) - 1) / 6)
|
||||||
field_new!(Fq2, FQ_ONE, FQ_ZERO),
|
Fq2::new(Fq::ONE, Fq::ZERO),
|
||||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^1) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "92949345220277864758624960506473182677953048909283248980960104381795901929519566951595905490535835115111760994353"),
|
MontFp!("92949345220277864758624960506473182677953048909283248980960104381795901929519566951595905490535835115111760994353"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^2) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"),
|
MontFp!("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^3) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499"),
|
MontFp!("216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^4) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
MontFp!("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^5) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "123516416119946754630746545296132064952198520638002533875843642777304321125866014634106496325844844051843001220146"),
|
MontFp!("123516416119946754630746545296132064952198520638002533875843642777304321125866014634106496325844844051843001220146"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^6) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^6) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "-1"),
|
MontFp!("-1"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^7) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^7) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "165715080792691229252027773188420350858440463845631411558924158284924566418821255823372982649037525009328560463824"),
|
MontFp!("165715080792691229252027773188420350858440463845631411558924158284924566418821255823372982649037525009328560463824"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^8) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^8) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^9) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^9) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "42198664672744474621281227892288285906241943207628877683080515507620245292955241189266486323192680957485559243678"),
|
MontFp!("42198664672744474621281227892288285906241943207628877683080515507620245292955241189266486323192680957485559243678"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^10) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^10) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"),
|
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^11) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^11) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "135148009893022339379906188398761468584194992116912126664040619889416147222474808140862391813728516072597320238031"),
|
MontFp!("135148009893022339379906188398761468584194992116912126664040619889416147222474808140862391813728516072597320238031"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,51 @@
|
|||||||
use super::*;
|
use ark_ff::{fields::*, MontFp};
|
||||||
use ark_ff::{field_new, fields::*};
|
|
||||||
|
|
||||||
pub type Fq2 = Fp2<Fq2Parameters>;
|
use crate::*;
|
||||||
|
|
||||||
pub struct Fq2Parameters;
|
pub type Fq2 = Fp2<Fq2Config>;
|
||||||
|
|
||||||
impl Fp2Parameters for Fq2Parameters {
|
pub struct Fq2Config;
|
||||||
|
|
||||||
|
impl Fp2Config for Fq2Config {
|
||||||
type Fp = Fq;
|
type Fp = Fq;
|
||||||
|
|
||||||
/// NONRESIDUE = -5
|
/// NONRESIDUE = -5
|
||||||
#[rustfmt::skip]
|
const NONRESIDUE: Fq = MontFp!("-5");
|
||||||
const NONRESIDUE: Fq = field_new!(Fq, "-5");
|
|
||||||
|
|
||||||
/// QUADRATIC_NONRESIDUE = U
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const QUADRATIC_NONRESIDUE: (Fq, Fq) = (FQ_ZERO, FQ_ONE);
|
|
||||||
|
|
||||||
/// Coefficients for the Frobenius automorphism.
|
/// Coefficients for the Frobenius automorphism.
|
||||||
#[rustfmt::skip]
|
|
||||||
const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[
|
const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[
|
||||||
// NONRESIDUE**(((q^0) - 1) / 2)
|
// NONRESIDUE**(((q^0) - 1) / 2)
|
||||||
FQ_ONE,
|
Fq::ONE,
|
||||||
// NONRESIDUE**(((q^1) - 1) / 2)
|
// NONRESIDUE**(((q^1) - 1) / 2)
|
||||||
field_new!(Fq, "-1"),
|
MontFp!("-1"),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO);
|
|
||||||
pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO);
|
|
||||||
|
|||||||
@@ -1,78 +1,79 @@
|
|||||||
use super::*;
|
use ark_ff::{fields::*, MontFp};
|
||||||
use ark_ff::{field_new, fields::*};
|
|
||||||
|
|
||||||
pub type Fq6 = Fp6<Fq6Parameters>;
|
use crate::*;
|
||||||
|
|
||||||
|
pub type Fq6 = Fp6<Fq6Config>;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Fq6Parameters;
|
pub struct Fq6Config;
|
||||||
|
|
||||||
impl Fp6Parameters for Fq6Parameters {
|
impl Fp6Config for Fq6Config {
|
||||||
type Fp2Params = Fq2Parameters;
|
type Fp2Config = Fq2Config;
|
||||||
|
|
||||||
/// NONRESIDUE = U
|
/// NONRESIDUE = U
|
||||||
#[rustfmt::skip]
|
const NONRESIDUE: Fq2 = Fq2::new(Fq::ZERO, Fq::ONE);
|
||||||
const NONRESIDUE: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ONE);
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[
|
const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[
|
||||||
// Fp2::NONRESIDUE^(((q^0) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^0) - 1) / 3)
|
||||||
field_new!(Fq2, FQ_ONE, FQ_ZERO),
|
Fq2::new(Fq::ONE, Fq::ZERO),
|
||||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^1) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"),
|
MontFp!("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^2) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
MontFp!("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^3) - 1) / 3)
|
||||||
field_new!(Fq2, field_new!(Fq, "-1"), FQ_ZERO),
|
Fq2::new(MontFp!("-1"), Fq::ZERO),
|
||||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^4) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^5) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"),
|
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
#[rustfmt::skip]
|
|
||||||
const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[
|
const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[
|
||||||
// Fp2::NONRESIDUE^((2*(q^0) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^0) - 2) / 3)
|
||||||
field_new!(Fq2, FQ_ONE, FQ_ZERO),
|
Fq2::new(Fq::ONE, Fq::ZERO),
|
||||||
// Fp2::NONRESIDUE^((2*(q^1) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^1) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
MontFp!("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
||||||
FQ_ZERO
|
Fq::ZERO
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^2) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^2) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^3) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^3) - 2) / 3)
|
||||||
field_new!(Fq2, FQ_ONE, FQ_ZERO),
|
Fq2::new(Fq::ONE, Fq::ZERO),
|
||||||
// Fp2::NONRESIDUE^((2*(q^4) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^4) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
MontFp!("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^5) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^5) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[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 = Fq2Parameters::mul_fp_by_nonresidue(&fe.c1);
|
let old_c0 = fe.c0;
|
||||||
let c1 = fe.c0;
|
fe.c0 = fe.c1;
|
||||||
field_new!(Fq2, c0, c1)
|
Fq2Config::mul_fp_by_nonresidue_in_place(&mut fe.c0);
|
||||||
|
fe.c1 = old_c0;
|
||||||
|
fe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
//! Bls12-377 scalar field.
|
//! Bls12-377 scalar field.
|
||||||
///
|
|
||||||
/// Roots of unity computed from modulus and R using this sage code:
|
/// Roots of unity computed from modulus and R using this sage code:
|
||||||
///
|
///
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
@@ -19,103 +18,10 @@
|
|||||||
/// print("Gen: ", into_chunks(g * R % q, 64, 4))
|
/// print("Gen: ", into_chunks(g * R % q, 64, 4))
|
||||||
/// print("2-adic gen: ", into_chunks(g2 * R % q, 64, 4))
|
/// print("2-adic gen: ", into_chunks(g2 * R % q, 64, 4))
|
||||||
/// ```
|
/// ```
|
||||||
use ark_ff::{biginteger::BigInteger256 as BigInteger, fields::*};
|
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
|
||||||
|
|
||||||
pub type Fr = Fp256<FrParameters>;
|
#[derive(MontConfig)]
|
||||||
|
#[modulus = "8444461749428370424248824938781546531375899335154063827935233455917409239041"]
|
||||||
pub struct FrParameters;
|
#[generator = "22"]
|
||||||
|
pub struct FrConfig;
|
||||||
impl Fp256Parameters for FrParameters {}
|
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;
|
||||||
impl FftParameters for FrParameters {
|
|
||||||
type BigInt = BigInteger;
|
|
||||||
|
|
||||||
const TWO_ADICITY: u32 = 47;
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
|
||||||
12646347781564978760u64,
|
|
||||||
6783048705277173164u64,
|
|
||||||
268534165941069093u64,
|
|
||||||
1121515446318641358u64,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
impl FpParameters for FrParameters {
|
|
||||||
/// MODULUS = 8444461749428370424248824938781546531375899335154063827935233455917409239041
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const MODULUS: BigInteger = BigInteger([
|
|
||||||
725501752471715841u64,
|
|
||||||
6461107452199829505u64,
|
|
||||||
6968279316240510977u64,
|
|
||||||
1345280370688173398u64,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const MODULUS_BITS: u32 = 253;
|
|
||||||
|
|
||||||
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
|
|
||||||
|
|
||||||
const REPR_SHAVE_BITS: u32 = 3;
|
|
||||||
|
|
||||||
/// R = 6014086494747379908336260804527802945383293308637734276299549080986809532403
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const R: BigInteger = BigInteger([
|
|
||||||
9015221291577245683u64,
|
|
||||||
8239323489949974514u64,
|
|
||||||
1646089257421115374u64,
|
|
||||||
958099254763297437u64,
|
|
||||||
]);
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const R2: BigInteger = BigInteger([
|
|
||||||
2726216793283724667u64,
|
|
||||||
14712177743343147295u64,
|
|
||||||
12091039717619697043u64,
|
|
||||||
81024008013859129u64,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const INV: u64 = 725501752471715839u64;
|
|
||||||
|
|
||||||
/// GENERATOR = 22
|
|
||||||
/// Encoded in Montgomery form, so the value is
|
|
||||||
/// (22 * R) % q =
|
|
||||||
/// 5642976643016801619665363617888466827793962762719196659561577942948671127251
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const GENERATOR: BigInteger = BigInteger([
|
|
||||||
2984901390528151251u64,
|
|
||||||
10561528701063790279u64,
|
|
||||||
5476750214495080041u64,
|
|
||||||
898978044469942640u64,
|
|
||||||
]);
|
|
||||||
|
|
||||||
/// (r - 1)/2 =
|
|
||||||
/// 4222230874714185212124412469390773265687949667577031913967616727958704619520
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
|
||||||
0x8508c00000000000,
|
|
||||||
0xacd53b7f68000000,
|
|
||||||
0x305a268f2e1bd800,
|
|
||||||
0x955b2af4d1652ab,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// T and T_MINUS_ONE_DIV_TWO, where r - 1 = 2^s * t
|
|
||||||
// For T coprime to 2
|
|
||||||
|
|
||||||
/// t = (r - 1) / 2^s =
|
|
||||||
/// 60001509534603559531609739528203892656505753216962260608619555
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const T: BigInteger = BigInteger([
|
|
||||||
0xedfda00000021423,
|
|
||||||
0x9a3cb86f6002b354,
|
|
||||||
0xcabd34594aacc168,
|
|
||||||
0x2556,
|
|
||||||
]);
|
|
||||||
|
|
||||||
/// (t - 1) / 2 =
|
|
||||||
/// 30000754767301779765804869764101946328252876608481130304309777
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
|
||||||
0x76fed00000010a11,
|
|
||||||
0x4d1e5c37b00159aa,
|
|
||||||
0x655e9a2ca55660b4,
|
|
||||||
0x12ab,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,127 +1,52 @@
|
|||||||
|
use ark_algebra_test_templates::*;
|
||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
biginteger::{BigInteger, BigInteger384},
|
biginteger::{BigInt, BigInteger, BigInteger384},
|
||||||
fields::{
|
fields::{FftField, Field, Fp6Config, PrimeField},
|
||||||
fp6_3over2::Fp6Parameters, FftField, FftParameters, Field, Fp2Parameters, FpParameters,
|
Fp384, One, UniformRand, Zero,
|
||||||
PrimeField, SquareRootField,
|
|
||||||
},
|
|
||||||
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, Fq2Parameters, Fq6, Fq6Parameters, FqParameters, Fr};
|
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Config, Fr};
|
||||||
|
|
||||||
use ark_algebra_test_templates::fields::*;
|
test_field!(fr; Fr; mont_prime_field);
|
||||||
|
test_field!(fq; Fq; mont_prime_field);
|
||||||
pub(crate) const ITERATIONS: usize = 5;
|
test_field!(fq2; Fq2);
|
||||||
|
test_field!(fq6; Fq6);
|
||||||
#[test]
|
test_field!(fq12; Fq12);
|
||||||
fn test_fr() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
for _ in 0..ITERATIONS {
|
|
||||||
let a: Fr = rng.gen();
|
|
||||||
let b: Fr = rng.gen();
|
|
||||||
field_test(a, b);
|
|
||||||
primefield_test::<Fr>();
|
|
||||||
sqrt_field_test(b);
|
|
||||||
let byte_size = a.serialized_size();
|
|
||||||
field_serialization_test::<Fr>(byte_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
for _ in 0..ITERATIONS {
|
|
||||||
let a: Fq = rng.gen();
|
|
||||||
let b: Fq = rng.gen();
|
|
||||||
field_test(a, b);
|
|
||||||
primefield_test::<Fq>();
|
|
||||||
sqrt_field_test(a);
|
|
||||||
let byte_size = a.serialized_size();
|
|
||||||
let (_, buffer_size) = buffer_bit_byte_size(Fq::size_in_bits());
|
|
||||||
assert_eq!(byte_size, buffer_size);
|
|
||||||
field_serialization_test::<Fq>(byte_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq2() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
for _ in 0..ITERATIONS {
|
|
||||||
let a: Fq2 = rng.gen();
|
|
||||||
let b: Fq2 = rng.gen();
|
|
||||||
field_test(a, b);
|
|
||||||
sqrt_field_test(a);
|
|
||||||
}
|
|
||||||
frobenius_test::<Fq2, _>(Fq::characteristic(), 13);
|
|
||||||
let byte_size = Fq2::zero().serialized_size();
|
|
||||||
field_serialization_test::<Fq2>(byte_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq6() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
for _ in 0..ITERATIONS {
|
|
||||||
let g: Fq6 = rng.gen();
|
|
||||||
let h: Fq6 = rng.gen();
|
|
||||||
field_test(g, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
frobenius_test::<Fq6, _>(Fq::characteristic(), 13);
|
|
||||||
let byte_size = Fq6::zero().serialized_size();
|
|
||||||
field_serialization_test::<Fq6>(byte_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq12() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
for _ in 0..ITERATIONS {
|
|
||||||
let g: Fq12 = rng.gen();
|
|
||||||
let h: Fq12 = rng.gen();
|
|
||||||
field_test(g, h);
|
|
||||||
}
|
|
||||||
frobenius_test::<Fq12, _>(Fq::characteristic(), 13);
|
|
||||||
let byte_size = Fq12::zero().serialized_size();
|
|
||||||
field_serialization_test::<Fq12>(byte_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_from() {
|
fn test_fq_repr_from() {
|
||||||
assert_eq!(
|
assert_eq!(BigInt::from(100u64), BigInt::new([100, 0, 0, 0, 0, 0]));
|
||||||
BigInteger384::from(100),
|
|
||||||
BigInteger384([100, 0, 0, 0, 0, 0])
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_is_odd() {
|
fn test_fq_repr_is_odd() {
|
||||||
assert!(!BigInteger384::from(0).is_odd());
|
assert!(!BigInteger384::from(0u64).is_odd());
|
||||||
assert!(BigInteger384::from(0).is_even());
|
assert!(BigInteger384::from(0u64).is_even());
|
||||||
assert!(BigInteger384::from(1).is_odd());
|
assert!(BigInteger384::from(1u64).is_odd());
|
||||||
assert!(!BigInteger384::from(1).is_even());
|
assert!(!BigInteger384::from(1u64).is_even());
|
||||||
assert!(!BigInteger384::from(324834872).is_odd());
|
assert!(!BigInteger384::from(324834872u64).is_odd());
|
||||||
assert!(BigInteger384::from(324834872).is_even());
|
assert!(BigInteger384::from(324834872u64).is_even());
|
||||||
assert!(BigInteger384::from(324834873).is_odd());
|
assert!(BigInteger384::from(324834873u64).is_odd());
|
||||||
assert!(!BigInteger384::from(324834873).is_even());
|
assert!(!BigInteger384::from(324834873u64).is_even());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_is_zero() {
|
fn test_fq_repr_is_zero() {
|
||||||
assert!(BigInteger384::from(0).is_zero());
|
assert!(BigInteger384::from(0u64).is_zero());
|
||||||
assert!(!BigInteger384::from(1).is_zero());
|
assert!(!BigInteger384::from(1u64).is_zero());
|
||||||
assert!(!BigInteger384([0, 0, 0, 0, 1, 0]).is_zero());
|
assert!(!BigInt::new([0, 0, 0, 0, 1, 0]).is_zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_num_bits() {
|
fn test_fq_repr_num_bits() {
|
||||||
let mut a = BigInteger384::from(0);
|
let mut a = BigInteger384::from(0u64);
|
||||||
assert_eq!(0, a.num_bits());
|
assert_eq!(0, a.num_bits());
|
||||||
a = BigInteger384::from(1);
|
a = BigInteger384::from(1u64);
|
||||||
for i in 1..385 {
|
for i in 1..385 {
|
||||||
assert_eq!(i, a.num_bits());
|
assert_eq!(i, a.num_bits());
|
||||||
a.mul2();
|
a.mul2();
|
||||||
@@ -129,229 +54,16 @@ fn test_fq_repr_num_bits() {
|
|||||||
assert_eq!(0, a.num_bits());
|
assert_eq!(0, a.num_bits());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_add_assign() {
|
|
||||||
// Test associativity
|
|
||||||
|
|
||||||
let mut rng = test_rng();
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Generate a, b, c and ensure (a + b) + c == a + (b + c).
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
let b = Fq::rand(&mut rng);
|
|
||||||
let c = Fq::rand(&mut rng);
|
|
||||||
|
|
||||||
let mut tmp1 = a;
|
|
||||||
tmp1.add_assign(&b);
|
|
||||||
tmp1.add_assign(&c);
|
|
||||||
|
|
||||||
let mut tmp2 = b;
|
|
||||||
tmp2.add_assign(&c);
|
|
||||||
tmp2.add_assign(&a);
|
|
||||||
|
|
||||||
assert_eq!(tmp1, tmp2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_sub_assign() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Ensure that (a - b) + (b - a) = 0.
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
let b = Fq::rand(&mut rng);
|
|
||||||
|
|
||||||
let mut tmp1 = a;
|
|
||||||
tmp1.sub_assign(&b);
|
|
||||||
|
|
||||||
let mut tmp2 = b;
|
|
||||||
tmp2.sub_assign(&a);
|
|
||||||
|
|
||||||
tmp1.add_assign(&tmp2);
|
|
||||||
assert!(tmp1.is_zero());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_mul_assign() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
|
|
||||||
for _ in 0..1000000 {
|
|
||||||
// Ensure that (a * b) * c = a * (b * c)
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
let b = Fq::rand(&mut rng);
|
|
||||||
let c = Fq::rand(&mut rng);
|
|
||||||
|
|
||||||
let mut tmp1 = a;
|
|
||||||
tmp1.mul_assign(&b);
|
|
||||||
tmp1.mul_assign(&c);
|
|
||||||
|
|
||||||
let mut tmp2 = b;
|
|
||||||
tmp2.mul_assign(&c);
|
|
||||||
tmp2.mul_assign(&a);
|
|
||||||
|
|
||||||
assert_eq!(tmp1, tmp2);
|
|
||||||
}
|
|
||||||
|
|
||||||
for _ in 0..1000000 {
|
|
||||||
// Ensure that r * (a + b + c) = r*a + r*b + r*c
|
|
||||||
|
|
||||||
let r = Fq::rand(&mut rng);
|
|
||||||
let mut a = Fq::rand(&mut rng);
|
|
||||||
let mut b = Fq::rand(&mut rng);
|
|
||||||
let mut c = Fq::rand(&mut rng);
|
|
||||||
|
|
||||||
let mut tmp1 = a;
|
|
||||||
tmp1.add_assign(&b);
|
|
||||||
tmp1.add_assign(&c);
|
|
||||||
tmp1.mul_assign(&r);
|
|
||||||
|
|
||||||
a.mul_assign(&r);
|
|
||||||
b.mul_assign(&r);
|
|
||||||
c.mul_assign(&r);
|
|
||||||
|
|
||||||
a.add_assign(&b);
|
|
||||||
a.add_assign(&c);
|
|
||||||
|
|
||||||
assert_eq!(tmp1, a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_squaring() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
|
|
||||||
for _ in 0..1000000 {
|
|
||||||
// Ensure that (a * a) = a^2
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
|
|
||||||
let mut tmp = a;
|
|
||||||
tmp.square_in_place();
|
|
||||||
|
|
||||||
let mut tmp2 = a;
|
|
||||||
tmp2.mul_assign(&a);
|
|
||||||
|
|
||||||
assert_eq!(tmp, tmp2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_inverse() {
|
|
||||||
assert!(Fq::zero().inverse().is_none());
|
|
||||||
|
|
||||||
let mut rng = test_rng();
|
|
||||||
|
|
||||||
let one = Fq::one();
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Ensure that a * a^-1 = 1
|
|
||||||
let mut a = Fq::rand(&mut rng);
|
|
||||||
let ainv = a.inverse().unwrap();
|
|
||||||
a.mul_assign(&ainv);
|
|
||||||
assert_eq!(a, one);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_double_in_place() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Ensure doubling a is equivalent to adding a to itself.
|
|
||||||
let mut a = Fq::rand(&mut rng);
|
|
||||||
let mut b = a;
|
|
||||||
b.add_assign(&a);
|
|
||||||
a.double_in_place();
|
|
||||||
assert_eq!(a, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_negate() {
|
|
||||||
{
|
|
||||||
let a = -Fq::zero();
|
|
||||||
|
|
||||||
assert!(a.is_zero());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut rng = test_rng();
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Ensure (a - (-a)) = 0.
|
|
||||||
let mut a = Fq::rand(&mut rng);
|
|
||||||
let b = -a;
|
|
||||||
a.add_assign(&b);
|
|
||||||
|
|
||||||
assert!(a.is_zero());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_pow() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
|
|
||||||
for i in 0..1000 {
|
|
||||||
// Exponentiate by various small numbers and ensure it consists with repeated
|
|
||||||
// multiplication.
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
let target = a.pow(&[i]);
|
|
||||||
let mut c = Fq::one();
|
|
||||||
for _ in 0..i {
|
|
||||||
c.mul_assign(&a);
|
|
||||||
}
|
|
||||||
assert_eq!(c, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Exponentiating by the modulus should have no effect in a prime field.
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
|
|
||||||
assert_eq!(a, a.pow(Fq::characteristic()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_sqrt() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
|
|
||||||
assert_eq!(Fq::zero().sqrt().unwrap(), Fq::zero());
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Ensure sqrt(a^2) = a or -a
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
let nega = -a;
|
|
||||||
let mut b = a;
|
|
||||||
b.square_in_place();
|
|
||||||
|
|
||||||
let b = b.sqrt().unwrap();
|
|
||||||
|
|
||||||
assert!(a == b || nega == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Ensure sqrt(a)^2 = a for random a
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
|
|
||||||
if let Some(mut tmp) = a.sqrt() {
|
|
||||||
tmp.square_in_place();
|
|
||||||
|
|
||||||
assert_eq!(a, tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_num_bits() {
|
fn test_fq_num_bits() {
|
||||||
assert_eq!(FqParameters::MODULUS_BITS, 377);
|
assert_eq!(Fq::MODULUS_BIT_SIZE, 377);
|
||||||
assert_eq!(FqParameters::CAPACITY, 376);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_root_of_unity() {
|
fn test_fq_root_of_unity() {
|
||||||
assert_eq!(FqParameters::TWO_ADICITY, 46);
|
assert_eq!(Fq::TWO_ADICITY, 46);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Fq::multiplicative_generator().pow([
|
Fq::GENERATOR.pow([
|
||||||
0x7510c00000021423,
|
0x7510c00000021423,
|
||||||
0x88bee82520005c2d,
|
0x88bee82520005c2d,
|
||||||
0x67cc03d44e3c7bcd,
|
0x67cc03d44e3c7bcd,
|
||||||
@@ -359,21 +71,21 @@ fn test_fq_root_of_unity() {
|
|||||||
0xe9185f1443ab18ec,
|
0xe9185f1443ab18ec,
|
||||||
0x6b8
|
0x6b8
|
||||||
]),
|
]),
|
||||||
Fq::two_adic_root_of_unity()
|
Fq::TWO_ADIC_ROOT_OF_UNITY
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]),
|
Fq::TWO_ADIC_ROOT_OF_UNITY.pow([1 << Fq::TWO_ADICITY]),
|
||||||
Fq::one()
|
Fq::one()
|
||||||
);
|
);
|
||||||
assert!(Fq::multiplicative_generator().sqrt().is_none());
|
assert!(Fq::GENERATOR.sqrt().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_ordering() {
|
fn test_fq_ordering() {
|
||||||
// BigInteger384's ordering is well-tested, but we still need to make sure the
|
// BigInteger384's ordering is well-tested, but we still need to make sure the
|
||||||
// Fq elements aren't being compared in Montgomery form.
|
// Fq elements aren't being compared in Montgomery form.
|
||||||
for i in 0..100 {
|
for i in 0..100u64 {
|
||||||
assert!(Fq::from(BigInteger384::from(i + 1)) > Fq::from(BigInteger384::from(i)));
|
assert!(Fq::from(Fp384::from(i + 1)) > Fq::from(Fp384::from(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,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(4)).legendre()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
QuadraticNonResidue,
|
|
||||||
Fq::from(BigInteger384::from(5)).legendre()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -430,30 +136,10 @@ fn test_fq2_legendre() {
|
|||||||
// i^2 = -1
|
// i^2 = -1
|
||||||
let mut m1 = -Fq2::one();
|
let mut m1 = -Fq2::one();
|
||||||
assert_eq!(QuadraticResidue, m1.legendre());
|
assert_eq!(QuadraticResidue, m1.legendre());
|
||||||
m1 = Fq6Parameters::mul_fp2_by_nonresidue(&m1);
|
Fq6Config::mul_fp2_by_nonresidue_in_place(&mut m1);
|
||||||
assert_eq!(QuadraticNonResidue, m1.legendre());
|
assert_eq!(QuadraticNonResidue, m1.legendre());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq2_mul_nonresidue() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
|
|
||||||
let nqr = Fq2::new(Fq::zero(), Fq::one());
|
|
||||||
|
|
||||||
let quadratic_non_residue = Fq2::new(
|
|
||||||
Fq2Parameters::QUADRATIC_NONRESIDUE.0,
|
|
||||||
Fq2Parameters::QUADRATIC_NONRESIDUE.1,
|
|
||||||
);
|
|
||||||
for _ in 0..1000 {
|
|
||||||
let mut a = Fq2::rand(&mut rng);
|
|
||||||
let mut b = a;
|
|
||||||
a = quadratic_non_residue * &a;
|
|
||||||
b.mul_assign(&nqr);
|
|
||||||
|
|
||||||
assert_eq!(a, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq6_mul_by_1() {
|
fn test_fq6_mul_by_1() {
|
||||||
let mut rng = test_rng();
|
let mut rng = test_rng();
|
||||||
|
|||||||
12
bls12_377/src/lib.rs
Normal file → Executable file
12
bls12_377/src/lib.rs
Normal file → Executable file
@@ -9,15 +9,17 @@
|
|||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
|
|
||||||
//! This library implements the BLS12_377 curve generated in [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962).
|
//! This library implements the BLS12_377 curve generated in [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962).
|
||||||
//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree 12,
|
//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree
|
||||||
//! defined over a 377-bit (prime) field. The main feature of this curve is that
|
//! 12, defined over a 377-bit (prime) field. The main feature of this curve is
|
||||||
//! both the scalar field and the base field are highly 2-adic.
|
//! that both the scalar field and the base field are highly 2-adic.
|
||||||
//! (This is in contrast to the BLS12_381 curve for which only the scalar field is highly 2-adic.)
|
//! (This is in contrast to the BLS12_381 curve for which only the scalar field
|
||||||
|
//! is highly 2-adic.)
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//! Curve information:
|
//! Curve information:
|
||||||
//! * Base field: q = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
|
//! * Base field: q = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
|
||||||
//! * Scalar field: r = 8444461749428370424248824938781546531375899335154063827935233455917409239041
|
//! * Scalar field: r =
|
||||||
|
//! 8444461749428370424248824938781546531375899335154063827935233455917409239041
|
||||||
//! * valuation(q - 1, 2) = 46
|
//! * valuation(q - 1, 2) = 46
|
||||||
//! * valuation(r - 1, 2) = 47
|
//! * valuation(r - 1, 2) = 47
|
||||||
//! * G1 curve equation: y^2 = x^3 + 1
|
//! * G1 curve equation: y^2 = x^3 + 1
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-bls12-381"
|
name = "ark-bls12-381"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
authors = [ "arkworks contributors" ]
|
authors = [ "arkworks contributors" ]
|
||||||
description = "The BLS12-381 pairing-friendly elliptic curve"
|
description = "The BLS12-381 pairing-friendly elliptic curve"
|
||||||
homepage = "https://arkworks.rs"
|
homepage = "https://arkworks.rs"
|
||||||
@@ -10,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", default-features = false }
|
||||||
ark-ec = { version="^0.3.0", default-features = false }
|
ark-ec = { version= "0.4.0" }
|
||||||
ark-std = { version="^0.3.0", default-features = false }
|
ark-std = { version = "0.4.0", default-features = false }
|
||||||
|
ark-serialize = { version = "0.4.0", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ark-serialize = { version="^0.3.0", default-features = false }
|
ark-algebra-test-templates = { version = "0.4.0", default-features = false }
|
||||||
ark-algebra-test-templates = { version="^0.3.0", default-features = false }
|
ark-algebra-bench-templates = { version = "0.4.0", 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
|
||||||
|
|||||||
15
bls12_381/benches/bls12_381.rs
Normal file
15
bls12_381/benches/bls12_381.rs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
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,
|
||||||
|
);
|
||||||
28
bls12_381/scripts/base_field.sage
Normal file
28
bls12_381/scripts/base_field.sage
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
modulus = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
|
||||||
|
|
||||||
|
assert(modulus.is_prime())
|
||||||
|
|
||||||
|
Fp = GF(modulus)
|
||||||
|
|
||||||
|
generator = Fp(0);
|
||||||
|
for i in range(0, 20):
|
||||||
|
i = Fp(i);
|
||||||
|
neg_i = Fp(-i)
|
||||||
|
if not(i.is_primitive_root() or neg_i.is_primitive_root()):
|
||||||
|
continue
|
||||||
|
elif i.is_primitive_root():
|
||||||
|
assert(i.is_primitive_root());
|
||||||
|
print("Generator: %d" % i)
|
||||||
|
generator = i
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
assert(neg_i.is_primitive_root());
|
||||||
|
print("Generator: %d" % neg_i)
|
||||||
|
generator = neg_i
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
two_adicity = valuation(modulus - 1, 2);
|
||||||
|
trace = (modulus - 1) / 2**two_adicity;
|
||||||
|
two_adic_root_of_unity = generator^trace
|
||||||
|
print("2-adic Root of Unity: %d " % two_adic_root_of_unity)
|
||||||
28
bls12_381/scripts/scalar_field.sage
Normal file
28
bls12_381/scripts/scalar_field.sage
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
modulus = 52435875175126190479447740508185965837690552500527637822603658699938581184513
|
||||||
|
|
||||||
|
assert(modulus.is_prime())
|
||||||
|
|
||||||
|
Fp = GF(modulus)
|
||||||
|
|
||||||
|
generator = Fp(0);
|
||||||
|
for i in range(0, 20):
|
||||||
|
i = Fp(i);
|
||||||
|
neg_i = Fp(-i)
|
||||||
|
if not(i.is_primitive_root() or neg_i.is_primitive_root()):
|
||||||
|
continue
|
||||||
|
elif i.is_primitive_root():
|
||||||
|
assert(i.is_primitive_root());
|
||||||
|
print("Generator: %d" % i)
|
||||||
|
generator = i
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
assert(neg_i.is_primitive_root());
|
||||||
|
print("Generator: %d" % neg_i)
|
||||||
|
generator = neg_i
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
two_adicity = valuation(modulus - 1, 2);
|
||||||
|
trace = (modulus - 1) / 2**two_adicity;
|
||||||
|
two_adic_root_of_unity = generator^trace
|
||||||
|
print("2-adic Root of Unity: %d " % two_adic_root_of_unity)
|
||||||
@@ -1,87 +1,294 @@
|
|||||||
use crate::*;
|
|
||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bls12,
|
bls12,
|
||||||
bls12::Bls12Parameters,
|
bls12::Bls12Config,
|
||||||
models::{ModelParameters, SWModelParameters},
|
hashing::curve_maps::wb::{IsogenyMap, WBConfig},
|
||||||
short_weierstrass_jacobian::GroupAffine,
|
models::CurveConfig,
|
||||||
AffineCurve, ProjectiveCurve,
|
scalar_mul::glv::GLVConfig,
|
||||||
|
short_weierstrass::{Affine, SWCurveConfig},
|
||||||
|
AffineRepr, PrimeGroup,
|
||||||
};
|
};
|
||||||
use ark_ff::{biginteger::BigInteger256, field_new, Zero};
|
use ark_ff::{AdditiveGroup, BigInt, MontFp, PrimeField, Zero};
|
||||||
use ark_std::ops::Neg;
|
use ark_serialize::{Compress, SerializationError};
|
||||||
|
use ark_std::{ops::Neg, One};
|
||||||
|
|
||||||
pub type G1Affine = bls12::G1Affine<crate::Parameters>;
|
use super::g1_swu_iso;
|
||||||
pub type G1Projective = bls12::G1Projective<crate::Parameters>;
|
use crate::{
|
||||||
|
util::{
|
||||||
|
read_g1_compressed, read_g1_uncompressed, serialize_fq, EncodingFlags, G1_SERIALIZED_SIZE,
|
||||||
|
},
|
||||||
|
Fq, Fr,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub type G1Affine = bls12::G1Affine<crate::Config>;
|
||||||
|
pub type G1Projective = bls12::G1Projective<crate::Config>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl ModelParameters for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
}
|
|
||||||
|
|
||||||
impl SWModelParameters for Parameters {
|
|
||||||
/// COEFF_A = 0
|
|
||||||
const COEFF_A: Fq = field_new!(Fq, "0");
|
|
||||||
|
|
||||||
/// COEFF_B = 4
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const COEFF_B: Fq = field_new!(Fq, "4");
|
|
||||||
|
|
||||||
/// COFACTOR = (x - 1)^2 / 3 = 76329603384216526031706109802092473003
|
/// COFACTOR = (x - 1)^2 / 3 = 76329603384216526031706109802092473003
|
||||||
const COFACTOR: &'static [u64] = &[0x8c00aaab0000aaab, 0x396c8c005555e156];
|
const COFACTOR: &'static [u64] = &[0x8c00aaab0000aaab, 0x396c8c005555e156];
|
||||||
|
|
||||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
/// = 52435875175126190458656871551744051925719901746859129887267498875565241663483
|
/// = 52435875175126190458656871551744051925719901746859129887267498875565241663483
|
||||||
#[rustfmt::skip]
|
const COFACTOR_INV: Fr =
|
||||||
const COFACTOR_INV: Fr = field_new!(Fr, "52435875175126190458656871551744051925719901746859129887267498875565241663483");
|
MontFp!("52435875175126190458656871551744051925719901746859129887267498875565241663483");
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWCurveConfig for Config {
|
||||||
|
/// COEFF_A = 0
|
||||||
|
const COEFF_A: Fq = Fq::ZERO;
|
||||||
|
|
||||||
|
/// COEFF_B = 4
|
||||||
|
const COEFF_B: Fq = MontFp!("4");
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||||
(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()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_in_correct_subgroup_assuming_on_curve(p: &GroupAffine<Parameters>) -> bool {
|
#[inline]
|
||||||
|
fn mul_projective(p: &G1Projective, scalar: &[u64]) -> G1Projective {
|
||||||
|
let s = Self::ScalarField::from_sign_and_limbs(true, scalar);
|
||||||
|
GLVConfig::glv_mul_projective(*p, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_in_correct_subgroup_assuming_on_curve(p: &G1Affine) -> bool {
|
||||||
// Algorithm from Section 6 of https://eprint.iacr.org/2021/1130.
|
// Algorithm from Section 6 of https://eprint.iacr.org/2021/1130.
|
||||||
//
|
//
|
||||||
// Check that endomorphism_p(P) == -[X^2]P
|
// Check that endomorphism_p(P) == -[X^2]P
|
||||||
|
|
||||||
let x = BigInteger256::new([crate::Parameters::X[0], 0, 0, 0]);
|
|
||||||
|
|
||||||
// An early-out optimization described in Section 6.
|
// An early-out optimization described in Section 6.
|
||||||
// If uP == P but P != point of infinity, then the point is not in the right subgroup.
|
// If uP == P but P != point of infinity, then the point is not in the right
|
||||||
let x_times_p = p.mul(x);
|
// subgroup.
|
||||||
|
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(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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GLVConfig for Config {
|
||||||
|
const ENDO_COEFFS: &'static[Self::BaseField] = &[
|
||||||
|
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350")
|
||||||
|
];
|
||||||
|
|
||||||
|
const LAMBDA: Self::ScalarField =
|
||||||
|
MontFp!("52435875175126190479447740508185965837461563690374988244538805122978187051009");
|
||||||
|
|
||||||
|
const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
|
||||||
|
(true, BigInt!("228988810152649578064853576960394133504")),
|
||||||
|
(true, BigInt!("1")),
|
||||||
|
(false, BigInt!("1")),
|
||||||
|
(true, BigInt!("228988810152649578064853576960394133503")),
|
||||||
|
];
|
||||||
|
|
||||||
|
fn endomorphism(p: &G1Projective) -> G1Projective {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn endomorphism_affine(p: &Affine<Self>) -> Affine<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn one_minus_x() -> Fr {
|
||||||
|
const X: Fr = Fr::from_sign_and_limbs(!crate::Config::X_IS_NEGATIVE, crate::Config::X);
|
||||||
|
Fr::one() - X
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameters from the [IETF draft v16, section E.2](https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-11-isogeny-map-for-bls12-381).
|
||||||
|
impl WBConfig for Config {
|
||||||
|
type IsogenousCurve = g1_swu_iso::SwuIsoConfig;
|
||||||
|
|
||||||
|
const ISOGENY_MAP: IsogenyMap<'static, Self::IsogenousCurve, Self> =
|
||||||
|
g1_swu_iso::ISOGENY_MAP_TO_G1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// G1_GENERATOR_X =
|
/// G1_GENERATOR_X =
|
||||||
/// 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
|
/// 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
|
||||||
#[rustfmt::skip]
|
pub const G1_GENERATOR_X: Fq = MontFp!("3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507");
|
||||||
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507");
|
|
||||||
|
|
||||||
/// G1_GENERATOR_Y =
|
/// G1_GENERATOR_Y =
|
||||||
/// 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
|
/// 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
|
||||||
#[rustfmt::skip]
|
pub const G1_GENERATOR_Y: Fq = MontFp!("1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569");
|
||||||
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569");
|
|
||||||
|
|
||||||
/// BETA is a non-trivial cubic root of unity in Fq.
|
/// BETA is a non-trivial cubic root of unity in Fq.
|
||||||
pub const BETA: Fq = field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350");
|
pub const BETA: Fq = MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350");
|
||||||
|
|
||||||
pub fn endomorphism(p: &GroupAffine<Parameters>) -> GroupAffine<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) where BETA is a non-trivial cubic root of unity in Fq.
|
// endomorphism_p(x,y) = (BETA * x, y)
|
||||||
|
// where BETA is a non-trivial cubic root of unity in Fq.
|
||||||
let mut res = (*p).clone();
|
let mut res = (*p).clone();
|
||||||
res.x *= BETA;
|
res.x *= BETA;
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use crate::g1;
|
||||||
|
use ark_serialize::CanonicalDeserialize;
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn non_canonical_identity_point() {
|
||||||
|
let non_canonical_hex = "c01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
|
||||||
|
let non_canonical_bytes = hex::decode(non_canonical_hex).unwrap();
|
||||||
|
assert_eq!(non_canonical_bytes.len(), 48);
|
||||||
|
|
||||||
|
let maybe_affine_point: Result<G1Affine, ark_serialize::SerializationError> =
|
||||||
|
CanonicalDeserialize::deserialize_compressed(&non_canonical_bytes[..]);
|
||||||
|
|
||||||
|
assert!(maybe_affine_point.is_err());
|
||||||
|
|
||||||
|
let non_canonical_hex_uncompressed = "c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001";
|
||||||
|
let non_canonical_bytes = hex::decode(non_canonical_hex_uncompressed).unwrap();
|
||||||
|
assert_eq!(non_canonical_bytes.len(), 96);
|
||||||
|
|
||||||
|
let maybe_affine_point: Result<G1Affine, ark_serialize::SerializationError> =
|
||||||
|
CanonicalDeserialize::deserialize_uncompressed(&non_canonical_bytes[..]);
|
||||||
|
|
||||||
|
assert!(maybe_affine_point.is_err())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bad_flag_combination() {
|
||||||
|
// See https://github.com/zkcrypto/pairing/tree/fa8103764a07bd273927447d434de18aace252d3/src/bls12_381#serialization
|
||||||
|
// - Bit 1 is compressed/uncompressed
|
||||||
|
// - Bit 2 is infinity
|
||||||
|
// - Bit 3 is lexicographical order for compressed point deserialization
|
||||||
|
// Hence `0b1110` ("e" in hex) or `0b0110` ("6" in hex") are both nonsensical.
|
||||||
|
|
||||||
|
// uncompressed, but lexicographically largest flag is set
|
||||||
|
let non_canonical_hex = "600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
|
||||||
|
let non_canonical_bytes = hex::decode(non_canonical_hex).unwrap();
|
||||||
|
assert_eq!(non_canonical_bytes.len(), 48);
|
||||||
|
|
||||||
|
let maybe_affine_point: Result<G1Affine, ark_serialize::SerializationError> =
|
||||||
|
CanonicalDeserialize::deserialize_compressed(&non_canonical_bytes[..]);
|
||||||
|
|
||||||
|
assert!(maybe_affine_point.is_err());
|
||||||
|
|
||||||
|
// compressed, but infinity flag is set and lexicographically largest flag is
|
||||||
|
// set
|
||||||
|
let non_canonical_hex_2 = "e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
|
||||||
|
|
||||||
|
let non_canonical_bytes = hex::decode(non_canonical_hex_2).unwrap();
|
||||||
|
assert_eq!(non_canonical_bytes.len(), 48);
|
||||||
|
|
||||||
|
let maybe_affine_point: Result<G1Affine, ark_serialize::SerializationError> =
|
||||||
|
CanonicalDeserialize::deserialize_compressed(&non_canonical_bytes[..]);
|
||||||
|
assert!(maybe_affine_point.is_err());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
140
bls12_381/src/curves/g1_swu_iso.rs
Normal file
140
bls12_381/src/curves/g1_swu_iso.rs
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
use crate::{g1, Fq, Fr};
|
||||||
|
use ark_ec::{
|
||||||
|
hashing::curve_maps::{swu::SWUConfig, wb::IsogenyMap},
|
||||||
|
models::{
|
||||||
|
short_weierstrass::{Affine, SWCurveConfig},
|
||||||
|
CurveConfig,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use ark_ff::MontFp;
|
||||||
|
|
||||||
|
type G1Affine = Affine<SwuIsoConfig>;
|
||||||
|
|
||||||
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
|
pub struct SwuIsoConfig;
|
||||||
|
|
||||||
|
impl CurveConfig for SwuIsoConfig {
|
||||||
|
type BaseField = Fq;
|
||||||
|
type ScalarField = Fr;
|
||||||
|
|
||||||
|
/// COFACTOR = (x - 1)^2 / 3 = 76329603384216526031706109802092473003
|
||||||
|
const COFACTOR: &'static [u64] = &[0x8c00aaab0000aaab, 0x396c8c005555e156];
|
||||||
|
|
||||||
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
|
/// = 52435875175126190458656871551744051925719901746859129887267498875565241663483
|
||||||
|
const COFACTOR_INV: Fr =
|
||||||
|
MontFp!("52435875175126190458656871551744051925719901746859129887267498875565241663483");
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/
|
||||||
|
// Hashing to Elliptic Curves
|
||||||
|
// 8.8.1. BLS12-381 G1
|
||||||
|
// BLS12381G1_XMD:SHA-256_SSWU_RO_ is defined as follows:
|
||||||
|
// * E': y'^2 = x'^3 + A' * x' + B', where
|
||||||
|
// - A' = 0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d
|
||||||
|
// - B' = 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0
|
||||||
|
// - A' = 12190336318893619529228877361869031420615612348429846051986726275283378313155663745811710833465465981901188123677
|
||||||
|
// - B' = 2906670324641927570491258158026293881577086121416628140204402091718288198173574630967936031029026176254968826637280
|
||||||
|
// * Z: 11
|
||||||
|
impl SWCurveConfig for SwuIsoConfig {
|
||||||
|
const COEFF_A: Fq = MontFp!("12190336318893619529228877361869031420615612348429846051986726275283378313155663745811710833465465981901188123677");
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COEFF_B: Fq = MontFp!("2906670324641927570491258158026293881577086121416628140204402091718288198173574630967936031029026176254968826637280");
|
||||||
|
|
||||||
|
const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Lexicographically smallest, valid x-coordinate of a point P on the curve
|
||||||
|
/// (with its corresponding y) multiplied by the cofactor. P_x = 2
|
||||||
|
/// P_y = 658522096176515125667361255350269797307718222519385801637008089782287711363858559738763090642304321670226247205569
|
||||||
|
/// P = E(P_x, P_y)
|
||||||
|
/// G = P * COFACTOR
|
||||||
|
const G1_GENERATOR_X: Fq = MontFp!("1677416608493238977774703213729589714082762656433187746258164626835771660734158898989765932111853529350617333597651");
|
||||||
|
const G1_GENERATOR_Y: Fq = MontFp!("1405098061573104639413728190240719229571583960971553962991897960445246185035342568402755187331334546673157015627211");
|
||||||
|
|
||||||
|
impl SWUConfig for SwuIsoConfig {
|
||||||
|
// ZETA = 0xb as per the IETF draft.
|
||||||
|
const ZETA: Fq = MontFp!("11");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const ISOGENY_MAP_TO_G1 : IsogenyMap<'_, SwuIsoConfig, g1::Config, > = IsogenyMap {
|
||||||
|
x_map_numerator : &[
|
||||||
|
MontFp!("2712959285290305970661081772124144179193819192423276218370281158706191519995889425075952244140278856085036081760695"),
|
||||||
|
MontFp!("3564859427549639835253027846704205725951033235539816243131874237388832081954622352624080767121604606753339903542203"),
|
||||||
|
MontFp!("2051387046688339481714726479723076305756384619135044672831882917686431912682625619320120082313093891743187631791280"),
|
||||||
|
MontFp!("3612713941521031012780325893181011392520079402153354595775735142359240110423346445050803899623018402874731133626465"),
|
||||||
|
MontFp!("2247053637822768981792833880270996398470828564809439728372634811976089874056583714987807553397615562273407692740057"),
|
||||||
|
MontFp!("3415427104483187489859740871640064348492611444552862448295571438270821994900526625562705192993481400731539293415811"),
|
||||||
|
MontFp!("2067521456483432583860405634125513059912765526223015704616050604591207046392807563217109432457129564962571408764292"),
|
||||||
|
MontFp!("3650721292069012982822225637849018828271936405382082649291891245623305084633066170122780668657208923883092359301262"),
|
||||||
|
MontFp!("1239271775787030039269460763652455868148971086016832054354147730155061349388626624328773377658494412538595239256855"),
|
||||||
|
MontFp!("3479374185711034293956731583912244564891370843071137483962415222733470401948838363051960066766720884717833231600798"),
|
||||||
|
MontFp!("2492756312273161536685660027440158956721981129429869601638362407515627529461742974364729223659746272460004902959995"),
|
||||||
|
MontFp!("1058488477413994682556770863004536636444795456512795473806825292198091015005841418695586811009326456605062948114985"),
|
||||||
|
],
|
||||||
|
|
||||||
|
x_map_denominator : &[
|
||||||
|
MontFp!("1353092447850172218905095041059784486169131709710991428415161466575141675351394082965234118340787683181925558786844"),
|
||||||
|
MontFp!("2822220997908397120956501031591772354860004534930174057793539372552395729721474912921980407622851861692773516917759"),
|
||||||
|
MontFp!("1717937747208385987946072944131378949849282930538642983149296304709633281382731764122371874602115081850953846504985"),
|
||||||
|
MontFp!("501624051089734157816582944025690868317536915684467868346388760435016044027032505306995281054569109955275640941784"),
|
||||||
|
MontFp!("3025903087998593826923738290305187197829899948335370692927241015584233559365859980023579293766193297662657497834014"),
|
||||||
|
MontFp!("2224140216975189437834161136818943039444741035168992629437640302964164227138031844090123490881551522278632040105125"),
|
||||||
|
MontFp!("1146414465848284837484508420047674663876992808692209238763293935905506532411661921697047880549716175045414621825594"),
|
||||||
|
MontFp!("3179090966864399634396993677377903383656908036827452986467581478509513058347781039562481806409014718357094150199902"),
|
||||||
|
MontFp!("1549317016540628014674302140786462938410429359529923207442151939696344988707002602944342203885692366490121021806145"),
|
||||||
|
MontFp!("1442797143427491432630626390066422021593505165588630398337491100088557278058060064930663878153124164818522816175370"),
|
||||||
|
MontFp!("1"),
|
||||||
|
],
|
||||||
|
|
||||||
|
y_map_numerator : &[
|
||||||
|
MontFp!("1393399195776646641963150658816615410692049723305861307490980409834842911816308830479576739332720113414154429643571"),
|
||||||
|
MontFp!("2968610969752762946134106091152102846225411740689724909058016729455736597929366401532929068084731548131227395540630"),
|
||||||
|
MontFp!("122933100683284845219599644396874530871261396084070222155796123161881094323788483360414289333111221370374027338230"),
|
||||||
|
MontFp!("303251954782077855462083823228569901064301365507057490567314302006681283228886645653148231378803311079384246777035"),
|
||||||
|
MontFp!("1353972356724735644398279028378555627591260676383150667237975415318226973994509601413730187583692624416197017403099"),
|
||||||
|
MontFp!("3443977503653895028417260979421240655844034880950251104724609885224259484262346958661845148165419691583810082940400"),
|
||||||
|
MontFp!("718493410301850496156792713845282235942975872282052335612908458061560958159410402177452633054233549648465863759602"),
|
||||||
|
MontFp!("1466864076415884313141727877156167508644960317046160398342634861648153052436926062434809922037623519108138661903145"),
|
||||||
|
MontFp!("1536886493137106337339531461344158973554574987550750910027365237255347020572858445054025958480906372033954157667719"),
|
||||||
|
MontFp!("2171468288973248519912068884667133903101171670397991979582205855298465414047741472281361964966463442016062407908400"),
|
||||||
|
MontFp!("3915937073730221072189646057898966011292434045388986394373682715266664498392389619761133407846638689998746172899634"),
|
||||||
|
MontFp!("3802409194827407598156407709510350851173404795262202653149767739163117554648574333789388883640862266596657730112910"),
|
||||||
|
MontFp!("1707589313757812493102695021134258021969283151093981498394095062397393499601961942449581422761005023512037430861560"),
|
||||||
|
MontFp!("349697005987545415860583335313370109325490073856352967581197273584891698473628451945217286148025358795756956811571"),
|
||||||
|
MontFp!("885704436476567581377743161796735879083481447641210566405057346859953524538988296201011389016649354976986251207243"),
|
||||||
|
MontFp!("3370924952219000111210625390420697640496067348723987858345031683392215988129398381698161406651860675722373763741188"),
|
||||||
|
],
|
||||||
|
|
||||||
|
y_map_denominator : &[
|
||||||
|
MontFp!("3396434800020507717552209507749485772788165484415495716688989613875369612529138640646200921379825018840894888371137"),
|
||||||
|
MontFp!("3907278185868397906991868466757978732688957419873771881240086730384895060595583602347317992689443299391009456758845"),
|
||||||
|
MontFp!("854914566454823955479427412036002165304466268547334760894270240966182605542146252771872707010378658178126128834546"),
|
||||||
|
MontFp!("3496628876382137961119423566187258795236027183112131017519536056628828830323846696121917502443333849318934945158166"),
|
||||||
|
MontFp!("1828256966233331991927609917644344011503610008134915752990581590799656305331275863706710232159635159092657073225757"),
|
||||||
|
MontFp!("1362317127649143894542621413133849052553333099883364300946623208643344298804722863920546222860227051989127113848748"),
|
||||||
|
MontFp!("3443845896188810583748698342858554856823966611538932245284665132724280883115455093457486044009395063504744802318172"),
|
||||||
|
MontFp!("3484671274283470572728732863557945897902920439975203610275006103818288159899345245633896492713412187296754791689945"),
|
||||||
|
MontFp!("3755735109429418587065437067067640634211015783636675372165599470771975919172394156249639331555277748466603540045130"),
|
||||||
|
MontFp!("3459661102222301807083870307127272890283709299202626530836335779816726101522661683404130556379097384249447658110805"),
|
||||||
|
MontFp!("742483168411032072323733249644347333168432665415341249073150659015707795549260947228694495111018381111866512337576"),
|
||||||
|
MontFp!("1662231279858095762833829698537304807741442669992646287950513237989158777254081548205552083108208170765474149568658"),
|
||||||
|
MontFp!("1668238650112823419388205992952852912407572045257706138925379268508860023191233729074751042562151098884528280913356"),
|
||||||
|
MontFp!("369162719928976119195087327055926326601627748362769544198813069133429557026740823593067700396825489145575282378487"),
|
||||||
|
MontFp!("2164195715141237148945939585099633032390257748382945597506236650132835917087090097395995817229686247227784224263055"),
|
||||||
|
MontFp!("1"),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gen() {
|
||||||
|
let gen: G1Affine = SwuIsoConfig::GENERATOR;
|
||||||
|
assert!(gen.is_on_curve());
|
||||||
|
assert!(gen.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,30 +1,35 @@
|
|||||||
use crate::*;
|
use ark_std::ops::Neg;
|
||||||
use ark_ec::bls12::Bls12Parameters;
|
|
||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bls12,
|
bls12,
|
||||||
models::{ModelParameters, SWModelParameters},
|
bls12::Bls12Config,
|
||||||
short_weierstrass_jacobian::GroupAffine,
|
hashing::curve_maps::wb::{IsogenyMap, WBConfig},
|
||||||
AffineCurve,
|
models::CurveConfig,
|
||||||
|
scalar_mul::glv::GLVConfig,
|
||||||
|
short_weierstrass::{Affine, Projective, SWCurveConfig},
|
||||||
|
AffineRepr, CurveGroup, PrimeGroup,
|
||||||
};
|
};
|
||||||
use ark_ff::{biginteger::BigInteger256, field_new, Field, Zero};
|
use ark_ff::{AdditiveGroup, BigInt, Field, MontFp, PrimeField, Zero};
|
||||||
|
use ark_serialize::{Compress, SerializationError};
|
||||||
|
|
||||||
pub type G2Affine = bls12::G2Affine<crate::Parameters>;
|
use super::{
|
||||||
pub type G2Projective = bls12::G2Projective<crate::Parameters>;
|
g2_swu_iso,
|
||||||
|
util::{serialize_fq, EncodingFlags, G2_SERIALIZED_SIZE},
|
||||||
|
};
|
||||||
|
use crate::{
|
||||||
|
util::{read_g2_compressed, read_g2_uncompressed},
|
||||||
|
*,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub type G2Affine = bls12::G2Affine<crate::Config>;
|
||||||
|
pub type G2Projective = bls12::G2Projective<crate::Config>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl ModelParameters for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq2;
|
type BaseField = Fq2;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
}
|
|
||||||
|
|
||||||
impl SWModelParameters for Parameters {
|
|
||||||
/// COEFF_A = [0, 0]
|
|
||||||
const COEFF_A: Fq2 = field_new!(Fq2, g1::Parameters::COEFF_A, g1::Parameters::COEFF_A,);
|
|
||||||
|
|
||||||
/// COEFF_B = [4, 4]
|
|
||||||
const COEFF_B: Fq2 = field_new!(Fq2, g1::Parameters::COEFF_B, g1::Parameters::COEFF_B,);
|
|
||||||
|
|
||||||
/// COFACTOR = (x^8 - 4 x^7 + 5 x^6) - (4 x^4 + 6 x^3 - 4 x^2 - 4 x + 13) //
|
/// COFACTOR = (x^8 - 4 x^7 + 5 x^6) - (4 x^4 + 6 x^3 - 4 x^2 - 4 x + 13) //
|
||||||
/// 9
|
/// 9
|
||||||
@@ -43,25 +48,32 @@ impl SWModelParameters for Parameters {
|
|||||||
|
|
||||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
/// 26652489039290660355457965112010883481355318854675681319708643586776743290055
|
/// 26652489039290660355457965112010883481355318854675681319708643586776743290055
|
||||||
#[rustfmt::skip]
|
const COFACTOR_INV: Fr =
|
||||||
const COFACTOR_INV: Fr = field_new!(Fr, "26652489039290660355457965112010883481355318854675681319708643586776743290055");
|
MontFp!("26652489039290660355457965112010883481355318854675681319708643586776743290055");
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWCurveConfig for Config {
|
||||||
|
/// COEFF_A = [0, 0]
|
||||||
|
const COEFF_A: Fq2 = Fq2::new(g1::Config::COEFF_A, g1::Config::COEFF_A);
|
||||||
|
|
||||||
|
/// COEFF_B = [4, 4]
|
||||||
|
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 AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||||
(G2_GENERATOR_X, G2_GENERATOR_Y);
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
fn mul_by_a(_: Self::BaseField) -> Self::BaseField {
|
||||||
Self::BaseField::zero()
|
Self::BaseField::zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_in_correct_subgroup_assuming_on_curve(point: &GroupAffine<Parameters>) -> bool {
|
fn is_in_correct_subgroup_assuming_on_curve(point: &G2Affine) -> bool {
|
||||||
// Algorithm from Section 4 of https://eprint.iacr.org/2021/1130.
|
// Algorithm from Section 4 of https://eprint.iacr.org/2021/1130.
|
||||||
//
|
//
|
||||||
// Checks that [p]P = [X]P
|
// Checks that [p]P = [X]P
|
||||||
|
|
||||||
let mut x_times_point = point.mul(BigInteger256([crate::Parameters::X[0], 0, 0, 0]));
|
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,71 +81,201 @@ impl SWModelParameters 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 = field_new!(Fq2, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
impl GLVConfig for Config {
|
||||||
pub const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
|
const ENDO_COEFFS: &'static[Self::BaseField] = &[
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
||||||
|
Fq::ZERO
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
const LAMBDA: Self::ScalarField = MontFp!("228988810152649578064853576960394133503");
|
||||||
|
|
||||||
|
const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
|
||||||
|
(false, BigInt!("228988810152649578064853576960394133503")),
|
||||||
|
(true, BigInt!("1")),
|
||||||
|
(false, BigInt!("1")),
|
||||||
|
(false, BigInt!("228988810152649578064853576960394133504")),
|
||||||
|
];
|
||||||
|
|
||||||
|
fn endomorphism(p: &Projective<Self>) -> Projective<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn endomorphism_affine(p: &Affine<Self>) -> Affine<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const G2_GENERATOR_X: Fq2 = Fq2::new(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
||||||
|
pub const G2_GENERATOR_Y: Fq2 = Fq2::new(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C0 =
|
/// G2_GENERATOR_X_C0 =
|
||||||
/// 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160
|
/// 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160
|
||||||
#[rustfmt::skip]
|
pub const G2_GENERATOR_X_C0: Fq = MontFp!("352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160");
|
||||||
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160");
|
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C1 =
|
/// G2_GENERATOR_X_C1 =
|
||||||
/// 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758
|
/// 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758
|
||||||
#[rustfmt::skip]
|
pub const G2_GENERATOR_X_C1: Fq = MontFp!("3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758");
|
||||||
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758");
|
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C0 =
|
/// G2_GENERATOR_Y_C0 =
|
||||||
/// 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905
|
/// 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905
|
||||||
#[rustfmt::skip]
|
pub const G2_GENERATOR_Y_C0: Fq = MontFp!("1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905");
|
||||||
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905");
|
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C1 =
|
/// G2_GENERATOR_Y_C1 =
|
||||||
/// 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582
|
/// 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582
|
||||||
#[rustfmt::skip]
|
pub const G2_GENERATOR_Y_C1: Fq = MontFp!("927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582");
|
||||||
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582");
|
|
||||||
|
|
||||||
// psi(x,y) = (x**p * PSI_X, y**p * PSI_Y) is the Frobenius composed
|
|
||||||
// with the quadratic twist and its inverse
|
|
||||||
|
|
||||||
// PSI_X = 1/(u+1)^((p-1)/3)
|
// PSI_X = 1/(u+1)^((p-1)/3)
|
||||||
pub const P_POWER_ENDOMORPHISM_COEFF_0 : Fq2 = field_new!(
|
const P_POWER_ENDOMORPHISM_COEFF_0 : Fq2 = Fq2::new(
|
||||||
Fq2,
|
Fq::ZERO,
|
||||||
FQ_ZERO,
|
MontFp!(
|
||||||
field_new!(
|
|
||||||
Fq,
|
|
||||||
"4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"
|
"4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// PSI_Y = 1/(u+1)^((p-1)/2)
|
// PSI_Y = 1/(u+1)^((p-1)/2)
|
||||||
pub const P_POWER_ENDOMORPHISM_COEFF_1: Fq2 = field_new!(
|
const P_POWER_ENDOMORPHISM_COEFF_1: Fq2 = Fq2::new(
|
||||||
Fq2,
|
MontFp!(
|
||||||
field_new!(
|
|
||||||
Fq,
|
|
||||||
"2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
|
"2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
|
||||||
field_new!(
|
MontFp!(
|
||||||
Fq,
|
|
||||||
"1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257")
|
"1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257")
|
||||||
);
|
);
|
||||||
|
|
||||||
pub fn p_power_endomorphism(p: &GroupAffine<Parameters>) -> GroupAffine<Parameters> {
|
// PSI_2_X = (u+1)^((1-p^2)/3)
|
||||||
|
const DOUBLE_P_POWER_ENDOMORPHISM_COEFF_0: Fq2 = Fq2::new(
|
||||||
|
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
||||||
|
Fq::ZERO
|
||||||
|
);
|
||||||
|
|
||||||
|
/// psi(P) is the untwist-Frobenius-twist endomorhism on E'(Fq2)
|
||||||
|
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). To map a point (x, y) in E' to (s, t) in E,
|
// 1. Note that G2 is defined on curve E': y^2 = x^3 + 4(u+1).
|
||||||
// one set s = x / ((u+1) ^ (1/3)), t = y / ((u+1) ^ (1/2)), because E: y^2 = x^3 + 4.
|
// To map a point (x, y) in E' to (s, t) in E,
|
||||||
// 2. Apply the Frobenius endomorphism (s, t) => (s', t'), another point on curve E,
|
// set s = x / ((u+1) ^ (1/3)), t = y / ((u+1) ^ (1/2)),
|
||||||
// where s' = s^p, t' = t^p.
|
// because E: y^2 = x^3 + 4.
|
||||||
|
// 2. Apply the Frobenius endomorphism (s, t) => (s', t'),
|
||||||
|
// another point on curve E, where s' = s^p, t' = t^p.
|
||||||
// 3. Map the point from E back to E'; that is,
|
// 3. Map the point from E back to E'; that is,
|
||||||
// one set x' = s' * ((u+1) ^ (1/3)), y' = t' * ((u+1) ^ (1/2)).
|
// set x' = s' * ((u+1) ^ (1/3)), y' = t' * ((u+1) ^ (1/2)).
|
||||||
//
|
//
|
||||||
// To sum up, it maps
|
// To sum up, it maps
|
||||||
// (x,y) -> (x^p / ((u+1)^((p-1)/3)), y^p / ((u+1)^((p-1)/2)))
|
// (x,y) -> (x^p / ((u+1)^((p-1)/3)), y^p / ((u+1)^((p-1)/2)))
|
||||||
// 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;
|
||||||
@@ -142,3 +284,80 @@ pub fn p_power_endomorphism(p: &GroupAffine<Parameters>) -> GroupAffine<Paramete
|
|||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For a p-power endomorphism psi(P), compute psi(psi(P))
|
||||||
|
fn double_p_power_endomorphism(p: &Projective<Config>) -> Projective<Config> {
|
||||||
|
let mut res = *p;
|
||||||
|
|
||||||
|
res.x *= DOUBLE_P_POWER_ENDOMORPHISM_COEFF_0;
|
||||||
|
res.y = res.y.neg();
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parametres from the [IETF draft v16, section E.3](https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-3-isogeny-map-for-bls12-381).
|
||||||
|
impl WBConfig for Config {
|
||||||
|
type IsogenousCurve = g2_swu_iso::SwuIsoConfig;
|
||||||
|
|
||||||
|
const ISOGENY_MAP: IsogenyMap<'static, Self::IsogenousCurve, Self> =
|
||||||
|
g2_swu_iso::ISOGENY_MAP_TO_G2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use ark_std::{rand::Rng, UniformRand};
|
||||||
|
|
||||||
|
fn sample_unchecked() -> Affine<g2::Config> {
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
loop {
|
||||||
|
let x1 = Fq::rand(&mut rng);
|
||||||
|
let x2 = Fq::rand(&mut rng);
|
||||||
|
let greatest = rng.gen();
|
||||||
|
let x = Fq2::new(x1, x2);
|
||||||
|
|
||||||
|
if let Some(p) = Affine::get_point_from_x_unchecked(x, greatest) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_psi_2() {
|
||||||
|
let p = sample_unchecked();
|
||||||
|
let psi_p = p_power_endomorphism(&p);
|
||||||
|
let psi2_p_composed = p_power_endomorphism(&psi_p);
|
||||||
|
let psi2_p_optimised = double_p_power_endomorphism(&p.into());
|
||||||
|
|
||||||
|
assert_eq!(psi2_p_composed, psi2_p_optimised);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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,
|
||||||
|
];
|
||||||
|
|
||||||
|
const SAMPLES: usize = 10;
|
||||||
|
for _ in 0..SAMPLES {
|
||||||
|
let p: Affine<g2::Config> = sample_unchecked();
|
||||||
|
let optimised = p.clear_cofactor();
|
||||||
|
let naive = g2::Config::mul_affine(&p, h_eff);
|
||||||
|
assert_eq!(optimised.into_group(), naive);
|
||||||
|
assert!(optimised.is_on_curve());
|
||||||
|
assert!(optimised.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
151
bls12_381/src/curves/g2_swu_iso.rs
Normal file
151
bls12_381/src/curves/g2_swu_iso.rs
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
use crate::*;
|
||||||
|
|
||||||
|
use ark_ec::{
|
||||||
|
hashing::curve_maps::{swu::SWUConfig, wb::IsogenyMap},
|
||||||
|
models::{
|
||||||
|
short_weierstrass::{Affine, SWCurveConfig},
|
||||||
|
CurveConfig,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use ark_ff::MontFp;
|
||||||
|
|
||||||
|
type G2Affine = Affine<SwuIsoConfig>;
|
||||||
|
|
||||||
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
|
pub struct SwuIsoConfig;
|
||||||
|
|
||||||
|
impl CurveConfig for SwuIsoConfig {
|
||||||
|
type BaseField = Fq2;
|
||||||
|
type ScalarField = Fr;
|
||||||
|
|
||||||
|
/// Cofactors of g2_iso and g2 are the same.
|
||||||
|
/// COFACTOR = (x^8 - 4 x^7 + 5 x^6) - (4 x^4 + 6 x^3 - 4 x^2 - 4 x + 13) //
|
||||||
|
/// 9
|
||||||
|
/// = 3055023339312683442009997531931215042144660192541881426676640329822676041829718840265074273592599778478322728390416166612858038233783720963550777062779109
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COFACTOR: &'static [u64] = &[
|
||||||
|
0xcf1c38e31c7238e5,
|
||||||
|
0x1616ec6e786f0c70,
|
||||||
|
0x21537e293a6691ae,
|
||||||
|
0xa628f1cb4d9e82ef,
|
||||||
|
0xa68a205b2e5a7ddf,
|
||||||
|
0xcd91de4547085aba,
|
||||||
|
0x91d50792876a202,
|
||||||
|
0x5d543a95414e7f1,
|
||||||
|
];
|
||||||
|
|
||||||
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
|
/// 26652489039290660355457965112010883481355318854675681319708643586776743290055
|
||||||
|
const COFACTOR_INV: Fr =
|
||||||
|
MontFp!("26652489039290660355457965112010883481355318854675681319708643586776743290055");
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/
|
||||||
|
// Hashing to Elliptic Curves
|
||||||
|
// 8.8.2. BLS12-381 G2
|
||||||
|
// * E': y'^2 = x'^3 + A' * x' + B', where
|
||||||
|
//
|
||||||
|
// - A' = 240 * I
|
||||||
|
//
|
||||||
|
// - B' = 1012 * (1 + I)
|
||||||
|
//
|
||||||
|
// * Z: -(2 + I)
|
||||||
|
impl SWCurveConfig for SwuIsoConfig {
|
||||||
|
/// COEFF_A = 240 * I
|
||||||
|
const COEFF_A: Fq2 = Fq2::new(MontFp!("0"), MontFp!("240"));
|
||||||
|
|
||||||
|
/// COEFF_B = 1012 + 1012 * I
|
||||||
|
const COEFF_B: Fq2 = Fq2::new(MontFp!("1012"), MontFp!("1012"));
|
||||||
|
|
||||||
|
const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Lexicographically smallest, valid x-coordinate of a point P on the curve
|
||||||
|
/// (with its corresponding y) multiplied by the cofactor. P_x = 1
|
||||||
|
/// P_y = 1199519624119946820355795551601605892701128025883245860600494152840508171012839086684258857614063467038089173303263 + 2721622435888802346851223931977585460571674503470326381323808470905804676865417627238564067834747838523978879375704 * I
|
||||||
|
/// P = E(P_x, P_y)
|
||||||
|
/// G = P * COFACTOR
|
||||||
|
const G2_GENERATOR_X: Fq2 = Fq2::new(
|
||||||
|
MontFp!("2595569946714414516067015540153643524656442638788025933727967960306287756885400469291119095920626560658971252184199"),
|
||||||
|
MontFp!("1037079738597573406765355774006601850633656296583542639082316151670128374872040593053087014315526494961765370307992")
|
||||||
|
);
|
||||||
|
const G2_GENERATOR_Y: Fq2 = Fq2::new(
|
||||||
|
MontFp!("3927929472994661655038722055497331445175131868678630546921475383290711810401295661250673209427965906654429357114487"),
|
||||||
|
MontFp!("3300326318345570015758639333209189167876318321385223785506096497597561910823001330832964776707374262378602791224889")
|
||||||
|
);
|
||||||
|
|
||||||
|
impl SWUConfig for SwuIsoConfig {
|
||||||
|
// ZETA = -(2 + u) as per IETF draft.
|
||||||
|
const ZETA: Fq2 = Fq2::new(MontFp!("-2"), MontFp!("-1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const ISOGENY_MAP_TO_G2 : IsogenyMap<'_, SwuIsoConfig, g2::Config> = IsogenyMap {
|
||||||
|
x_map_numerator: &[
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542"),
|
||||||
|
MontFp!("889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("0"),
|
||||||
|
MontFp!("2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706522")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706526"),
|
||||||
|
MontFp!("1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853261")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("3557697382419259905260257622876359250272784728834673675850718343221361467102966990615722337003569479144794908942033"),
|
||||||
|
MontFp!("0")),
|
||||||
|
],
|
||||||
|
|
||||||
|
x_map_denominator: &[
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("0"),
|
||||||
|
MontFp!("4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559715")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("12"),
|
||||||
|
MontFp!("4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559775")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("1"),
|
||||||
|
MontFp!("0")),
|
||||||
|
],
|
||||||
|
|
||||||
|
y_map_numerator: &[
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558"),
|
||||||
|
MontFp!("3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("0"),
|
||||||
|
MontFp!("889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235518")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706524"),
|
||||||
|
MontFp!("1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853263")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("2816510427748580758331037284777117739799287910327449993381818688383577828123182200904113516794492504322962636245776"),
|
||||||
|
MontFp!("0")),
|
||||||
|
],
|
||||||
|
|
||||||
|
y_map_denominator: &[
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355"),
|
||||||
|
MontFp!("4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("0"),
|
||||||
|
MontFp!("4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559571")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("18"),
|
||||||
|
MontFp!("4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559769")),
|
||||||
|
Fq2::new(
|
||||||
|
MontFp!("1"),
|
||||||
|
MontFp!("0")),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gen() {
|
||||||
|
let gen: G2Affine = curves::g2_swu_iso::SwuIsoConfig::GENERATOR;
|
||||||
|
assert!(gen.is_on_curve());
|
||||||
|
assert!(gen.is_in_correct_subgroup_assuming_on_curve());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,13 @@
|
|||||||
use ark_ec::bls12::{Bls12, Bls12Parameters, TwistType};
|
use ark_ec::bls12::{Bls12, Bls12Config, TwistType};
|
||||||
|
|
||||||
use crate::{Fq, Fq12Parameters, Fq2Parameters, Fq6Parameters};
|
use crate::{Fq, Fq12Config, Fq2Config, Fq6Config};
|
||||||
|
|
||||||
pub mod g1;
|
pub mod g1;
|
||||||
pub mod g2;
|
pub mod g2;
|
||||||
|
pub(crate) mod util;
|
||||||
|
|
||||||
|
mod g1_swu_iso;
|
||||||
|
mod g2_swu_iso;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
@@ -13,18 +17,18 @@ 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;
|
||||||
type Fp = Fq;
|
type Fp = Fq;
|
||||||
type Fp2Params = Fq2Parameters;
|
type Fp2Config = Fq2Config;
|
||||||
type Fp6Params = Fq6Parameters;
|
type Fp6Config = Fq6Config;
|
||||||
type Fp12Params = Fq12Parameters;
|
type Fp12Config = Fq12Config;
|
||||||
type G1Parameters = self::g1::Parameters;
|
type G1Config = self::g1::Config;
|
||||||
type G2Parameters = self::g2::Parameters;
|
type G2Config = self::g2::Config;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,173 +0,0 @@
|
|||||||
#![allow(unused_imports)]
|
|
||||||
use ark_ec::{
|
|
||||||
models::SWModelParameters,
|
|
||||||
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
|
|
||||||
AffineCurve, PairingEngine, ProjectiveCurve,
|
|
||||||
};
|
|
||||||
use ark_ff::{
|
|
||||||
fields::{Field, FpParameters, PrimeField, SquareRootField},
|
|
||||||
BitIteratorBE, One, UniformRand, Zero,
|
|
||||||
};
|
|
||||||
use ark_serialize::CanonicalSerialize;
|
|
||||||
use ark_std::rand::Rng;
|
|
||||||
use ark_std::test_rng;
|
|
||||||
use core::ops::{AddAssign, MulAssign};
|
|
||||||
|
|
||||||
use crate::{g1, g2, Bls12_381, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
|
|
||||||
use ark_algebra_test_templates::{curves::*, groups::*};
|
|
||||||
use ark_ec::group::Group;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_projective_curve() {
|
|
||||||
curve_tests::<G1Projective>();
|
|
||||||
|
|
||||||
sw_tests::<g1::Parameters>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_projective_group() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: G1Projective = rng.gen();
|
|
||||||
let b: G1Projective = rng.gen();
|
|
||||||
group_test(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_generator() {
|
|
||||||
let generator = G1Affine::prime_subgroup_generator();
|
|
||||||
assert!(generator.is_on_curve());
|
|
||||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_projective_curve() {
|
|
||||||
curve_tests::<G2Projective>();
|
|
||||||
|
|
||||||
sw_tests::<g2::Parameters>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_projective_group() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: G2Projective = rng.gen();
|
|
||||||
let b: G2Projective = rng.gen();
|
|
||||||
group_test(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_generator() {
|
|
||||||
let generator = G2Affine::prime_subgroup_generator();
|
|
||||||
assert!(generator.is_on_curve());
|
|
||||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_bilinearity() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: G1Projective = rng.gen();
|
|
||||||
let b: G2Projective = rng.gen();
|
|
||||||
let s: Fr = rng.gen();
|
|
||||||
|
|
||||||
let mut sa = a;
|
|
||||||
sa.mul_assign(s);
|
|
||||||
let mut sb = b;
|
|
||||||
sb.mul_assign(s);
|
|
||||||
|
|
||||||
let ans1 = Bls12_381::pairing(sa, b);
|
|
||||||
let ans2 = Bls12_381::pairing(a, sb);
|
|
||||||
let ans3 = Bls12_381::pairing(a, b).pow(s.into_repr());
|
|
||||||
|
|
||||||
assert_eq!(ans1, ans2);
|
|
||||||
assert_eq!(ans2, ans3);
|
|
||||||
|
|
||||||
assert_ne!(ans1, Fq12::one());
|
|
||||||
assert_ne!(ans2, Fq12::one());
|
|
||||||
assert_ne!(ans3, Fq12::one());
|
|
||||||
|
|
||||||
assert_eq!(ans1.pow(Fr::characteristic()), Fq12::one());
|
|
||||||
assert_eq!(ans2.pow(Fr::characteristic()), Fq12::one());
|
|
||||||
assert_eq!(ans3.pow(Fr::characteristic()), Fq12::one());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_generator_raw() {
|
|
||||||
let mut x = Fq::zero();
|
|
||||||
let mut i = 0;
|
|
||||||
loop {
|
|
||||||
// y^2 = x^3 + b
|
|
||||||
let mut rhs = x;
|
|
||||||
rhs.square_in_place();
|
|
||||||
rhs.mul_assign(&x);
|
|
||||||
rhs.add_assign(&g1::Parameters::COEFF_B);
|
|
||||||
|
|
||||||
if let Some(y) = rhs.sqrt() {
|
|
||||||
let p = G1Affine::new(x, if y < -y { y } else { -y }, false);
|
|
||||||
assert!(!p.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
|
|
||||||
let g1 = p.scale_by_cofactor();
|
|
||||||
if !g1.is_zero() {
|
|
||||||
assert_eq!(i, 4);
|
|
||||||
let g1 = G1Affine::from(g1);
|
|
||||||
|
|
||||||
assert!(g1.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
|
|
||||||
assert_eq!(g1, G1Affine::prime_subgroup_generator());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i += 1;
|
|
||||||
x.add_assign(&Fq::one());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_endomorphism_beta() {
|
|
||||||
assert!(g1::BETA.pow(&[3u64]).is_one());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_subgroup_membership_via_endomorphism() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let generator = G1Projective::rand(&mut rng).into_affine();
|
|
||||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_subgroup_non_membership_via_endomorphism() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
loop {
|
|
||||||
let x = Fq::rand(&mut rng);
|
|
||||||
let greatest = rng.gen();
|
|
||||||
|
|
||||||
if let Some(p) = G1Affine::get_point_from_x(x, greatest) {
|
|
||||||
if !p.into_projective().mul(Fr::characteristic()).is_zero() {
|
|
||||||
assert!(!p.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_subgroup_membership_via_endomorphism() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let generator = G2Projective::rand(&mut rng).into_affine();
|
|
||||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_subgroup_non_membership_via_endomorphism() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
loop {
|
|
||||||
let x = Fq2::rand(&mut rng);
|
|
||||||
let greatest = rng.gen();
|
|
||||||
|
|
||||||
if let Some(p) = G2Affine::get_point_from_x(x, greatest) {
|
|
||||||
if !p.into_projective().mul(Fr::characteristic()).is_zero() {
|
|
||||||
assert!(!p.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
115
bls12_381/src/curves/tests/BLS12381G1_XMD-SHA-256_SSWU_RO_.json
Normal file
115
bls12_381/src/curves/tests/BLS12381G1_XMD-SHA-256_SSWU_RO_.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"L": "0x40",
|
||||||
|
"Z": "0xb",
|
||||||
|
"ciphersuite": "BLS12381G1_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"curve": "BLS12-381 G1",
|
||||||
|
"dst": "QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
|
||||||
|
},
|
||||||
|
"hash": "sha256",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": true,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x052926add2207b76ca4fa57a8734416c8dc95e24501772c814278700eed6d1e4e8cf62d9c09db0fac349612b759e79a1",
|
||||||
|
"y": "0x08ba738453bfed09cb546dbb0783dbb3a5f1f566ed67bb6be0e8c67e2e81a4cc68ee29813bb7994998f3eae0c9c6a265"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x11a3cce7e1d90975990066b2f2643b9540fa40d6137780df4e753a8054d07580db3b7f1f03396333d4a359d1fe3766fe",
|
||||||
|
"y": "0x0eeaf6d794e479e270da10fdaf768db4c96b650a74518fc67b04b03927754bac66f3ac720404f339ecdcc028afa091b7"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x160003aaf1632b13396dbad518effa00fff532f604de1a7fc2082ff4cb0afa2d63b2c32da1bef2bf6c5ca62dc6b72f9c",
|
||||||
|
"y": "0x0d8bb2d14e20cf9f6036152ed386d79189415b6d015a20133acb4e019139b94e9c146aaad5817f866c95d609a361735e"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x0ba14bd907ad64a016293ee7c2d276b8eae71f25a4b941eece7b0d89f17f75cb3ae5438a614fb61d6835ad59f29c564f",
|
||||||
|
"0x019b9bd7979f12657976de2884c7cce192b82c177c80e0ec604436a7f538d231552f0d96d9f7babe5fa3b19b3ff25ac9"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x03567bc5ef9c690c2ab2ecdf6a96ef1c139cc0b2f284dca0a9a7943388a49a3aee664ba5379a7655d3c68900be2f6903",
|
||||||
|
"y": "0x0b9c15f3fe6e5cf4211f346271d7b01c8f3b28be689c8429c85b67af215533311f0b8dfaaa154fa6b88176c229f2885d"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x125435adce8e1cbd1c803e7123f45392dc6e326d292499c2c45c5865985fd74fe8f042ecdeeec5ecac80680d04317d80",
|
||||||
|
"y": "0x0e8828948c989126595ee30e4f7c931cbd6f4570735624fd25aef2fa41d3f79cfb4b4ee7b7e55a8ce013af2a5ba20bf2"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x11def93719829ecda3b46aa8c31fc3ac9c34b428982b898369608e4f042babee6c77ab9218aad5c87ba785481eff8ae4",
|
||||||
|
"y": "0x0007c9cef122ccf2efd233d6eb9bfc680aa276652b0661f4f820a653cec1db7ff69899f8e52b8e92b025a12c822a6ce6"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x0d921c33f2bad966478a03ca35d05719bdf92d347557ea166e5bba579eea9b83e9afa5c088573c2281410369fbd32951",
|
||||||
|
"0x003574a00b109ada2f26a37a91f9d1e740dffd8d69ec0c35e1e9f4652c7dba61123e9dd2e76c655d956e2b3462611139"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x11e0b079dea29a68f0383ee94fed1b940995272407e3bb916bbf268c263ddd57a6a27200a784cbc248e84f357ce82d98",
|
||||||
|
"y": "0x03a87ae2caf14e8ee52e51fa2ed8eefe80f02457004ba4d486d6aa1f517c0889501dc7413753f9599b099ebcbbd2d709"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x08834484878c217682f6d09a4b51444802fdba3d7f2df9903a0ddadb92130ebbfa807fffa0eabf257d7b48272410afff",
|
||||||
|
"y": "0x0b318f7ecf77f45a0f038e62d7098221d2dbbca2a394164e2e3fe953dc714ac2cde412d8f2d7f0c03b259e6795a2508e"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x158418ed6b27e2549f05531a8281b5822b31c3bf3144277fbb977f8d6e2694fedceb7011b3c2b192f23e2a44b2bd106e",
|
||||||
|
"y": "0x1879074f344471fac5f839e2b4920789643c075792bec5af4282c73f7941cda5aa77b00085eb10e206171b9787c4169f"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x062d1865eb80ebfa73dcfc45db1ad4266b9f3a93219976a3790ab8d52d3e5f1e62f3b01795e36834b17b70e7b76246d4",
|
||||||
|
"0x0cdc3e2f271f29c4ff75020857ce6c5d36008c9b48385ea2f2bf6f96f428a3deb798aa033cd482d1cdc8b30178b08e3a"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x15f68eaa693b95ccb85215dc65fa81038d69629f70aeee0d0f677cf22285e7bf58d7cb86eefe8f2e9bc3f8cb84fac488",
|
||||||
|
"y": "0x1807a1d50c29f430b8cafc4f8638dfeeadf51211e1602a5f184443076715f91bb90a48ba1e370edce6ae1062f5e6dd38"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x0cbd7f84ad2c99643fea7a7ac8f52d63d66cefa06d9a56148e58b984b3dd25e1f41ff47154543343949c64f88d48a710",
|
||||||
|
"y": "0x052c00e4ed52d000d94881a5638ae9274d3efc8bc77bc0e5c650de04a000b2c334a9e80b85282a00f3148dfdface0865"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x06493fb68f0d513af08be0372f849436a787e7b701ae31cb964d968021d6ba6bd7d26a38aaa5a68e8c21a6b17dc8b579",
|
||||||
|
"y": "0x02e98f2ccf5802b05ffaac7c20018bc0c0b2fd580216c4aa2275d2909dc0c92d0d0bdc979226adeb57a29933536b6bb4"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x010476f6a060453c0b1ad0b628f3e57c23039ee16eea5e71bb87c3b5419b1255dc0e5883322e563b84a29543823c0e86",
|
||||||
|
"0x0b1a912064fb0554b180e07af7e787f1f883a0470759c03c1b6509eb8ce980d1670305ae7b928226bb58fdc0a419f46e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x082aabae8b7dedb0e78aeb619ad3bfd9277a2f77ba7fad20ef6aabdc6c31d19ba5a6d12283553294c1825c4b3ca2dcfe",
|
||||||
|
"y": "0x05b84ae5a942248eea39e1d91030458c40153f3b654ab7872d779ad1e942856a20c438e8d99bc8abfbf74729ce1f7ac8"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x0cf97e6dbd0947857f3e578231d07b309c622ade08f2c08b32ff372bd90db19467b2563cc997d4407968d4ac80e154f8",
|
||||||
|
"y": "0x127f0cddf2613058101a5701f4cb9d0861fd6c2a1b8e0afe194fccf586a3201a53874a2761a9ab6d7220c68661a35ab3"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x092f1acfa62b05f95884c6791fba989bbe58044ee6355d100973bf9553ade52b47929264e6ae770fb264582d8dce512a",
|
||||||
|
"y": "0x028e6d0169a72cfedb737be45db6c401d3adfb12c58c619c82b93a5dfcccef12290de530b0480575ddc8397cda0bbebf"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x0a8ffa7447f6be1c5a2ea4b959c9454b431e29ccc0802bc052413a9c5b4f9aac67a93431bd480d15be1e057c8a08e8c6",
|
||||||
|
"0x05d487032f602c90fa7625dbafe0f4a49ef4a6b0b33d7bb349ff4cf5410d297fd6241876e3e77b651cfc8191e40a68b7"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
bls12_381/src/curves/tests/BLS12381G2_XMD-SHA-256_SSWU_RO_.json
Normal file
115
bls12_381/src/curves/tests/BLS12381G2_XMD-SHA-256_SSWU_RO_.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"L": "0x40",
|
||||||
|
"Z": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaa9,0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa",
|
||||||
|
"ciphersuite": "BLS12381G2_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"curve": "BLS12-381 G2",
|
||||||
|
"dst": "QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x2",
|
||||||
|
"p": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
|
||||||
|
},
|
||||||
|
"hash": "sha256",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": true,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x0141ebfbdca40eb85b87142e130ab689c673cf60f1a3e98d69335266f30d9b8d4ac44c1038e9dcdd5393faf5c41fb78a,0x05cb8437535e20ecffaef7752baddf98034139c38452458baeefab379ba13dff5bf5dd71b72418717047f5b0f37da03d",
|
||||||
|
"y": "0x0503921d7f6a12805e72940b963c0cf3471c7b2a524950ca195d11062ee75ec076daf2d4bc358c4b190c0c98064fdd92,0x12424ac32561493f3fe3c260708a12b7c620e7be00099a974e259ddc7d1f6395c3c811cdd19f1e8dbf3e9ecfdcbab8d6"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x019ad3fc9c72425a998d7ab1ea0e646a1f6093444fc6965f1cad5a3195a7b1e099c050d57f45e3fa191cc6d75ed7458c,0x171c88b0b0efb5eb2b88913a9e74fe111a4f68867b59db252ce5868af4d1254bfab77ebde5d61cd1a86fb2fe4a5a1c1d",
|
||||||
|
"y": "0x0ba10604e62bdd9eeeb4156652066167b72c8d743b050fb4c1016c31b505129374f76e03fa127d6a156213576910fef3,0x0eb22c7a543d3d376e9716a49b72e79a89c9bfe9feee8533ed931cbb5373dde1fbcd7411d8052e02693654f71e15410a"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x113d2b9cd4bd98aee53470b27abc658d91b47a78a51584f3d4b950677cfb8a3e99c24222c406128c91296ef6b45608be,0x13855912321c5cb793e9d1e88f6f8d342d49c0b0dbac613ee9e17e3c0b3c97dfbb5a49cc3fb45102fdbaf65e0efe2632",
|
||||||
|
"y": "0x0fd3def0b7574a1d801be44fde617162aa2e89da47f464317d9bb5abc3a7071763ce74180883ad7ad9a723a9afafcdca,0x056f617902b3c0d0f78a9a8cbda43a26b65f602f8786540b9469b060db7b38417915b413ca65f875c130bebfaa59790c"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x03dbc2cce174e91ba93cbb08f26b917f98194a2ea08d1cce75b2b9cc9f21689d80bd79b594a613d0a68eb807dfdc1cf8,0x05a2acec64114845711a54199ea339abd125ba38253b70a92c876df10598bd1986b739cad67961eb94f7076511b3b39a",
|
||||||
|
"0x02f99798e8a5acdeed60d7e18e9120521ba1f47ec090984662846bc825de191b5b7641148c0dbc237726a334473eee94,0x145a81e418d4010cc027a68f14391b30074e89e60ee7a22f87217b2f6eb0c4b94c9115b436e6fa4607e95a98de30a435"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x02c2d18e033b960562aae3cab37a27ce00d80ccd5ba4b7fe0e7a210245129dbec7780ccc7954725f4168aff2787776e6,0x139cddbccdc5e91b9623efd38c49f81a6f83f175e80b06fc374de9eb4b41dfe4ca3a230ed250fbe3a2acf73a41177fd8",
|
||||||
|
"y": "0x1787327b68159716a37440985269cf584bcb1e621d3a7202be6ea05c4cfe244aeb197642555a0645fb87bf7466b2ba48,0x00aa65dae3c8d732d10ecd2c50f8a1baf3001578f71c694e03866e9f3d49ac1e1ce70dd94a733534f106d4cec0eddd16"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x12b2e525281b5f4d2276954e84ac4f42cf4e13b6ac4228624e17760faf94ce5706d53f0ca1952f1c5ef75239aeed55ad,0x05d8a724db78e570e34100c0bc4a5fa84ad5839359b40398151f37cff5a51de945c563463c9efbdda569850ee5a53e77",
|
||||||
|
"y": "0x02eacdc556d0bdb5d18d22f23dcb086dd106cad713777c7e6407943edbe0b3d1efe391eedf11e977fac55f9b94f2489c,0x04bbe48bfd5814648d0b9e30f0717b34015d45a861425fabc1ee06fdfce36384ae2c808185e693ae97dcde118f34de41"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x19f18cc5ec0c2f055e47c802acc3b0e40c337256a208001dde14b25afced146f37ea3d3ce16834c78175b3ed61f3c537,0x15b0dadc256a258b4c68ea43605dffa6d312eef215c19e6474b3e101d33b661dfee43b51abbf96fee68fc6043ac56a58",
|
||||||
|
"y": "0x05e47c1781286e61c7ade887512bd9c2cb9f640d3be9cf87ea0bad24bd0ebfe946497b48a581ab6c7d4ca74b5147287f,0x19f98db2f4a1fcdf56a9ced7b320ea9deecf57c8e59236b0dc21f6ee7229aa9705ce9ac7fe7a31c72edca0d92370c096"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x15f7c0aa8f6b296ab5ff9c2c7581ade64f4ee6f1bf18f55179ff44a2cf355fa53dd2a2158c5ecb17d7c52f63e7195771,0x01c8067bf4c0ba709aa8b9abc3d1cef589a4758e09ef53732d670fd8739a7274e111ba2fcaa71b3d33df2a3a0c8529dd",
|
||||||
|
"0x187111d5e088b6b9acfdfad078c4dacf72dcd17ca17c82be35e79f8c372a693f60a033b461d81b025864a0ad051a06e4,0x08b852331c96ed983e497ebc6dee9b75e373d923b729194af8e72a051ea586f3538a6ebb1e80881a082fa2b24df9f566"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x121982811d2491fde9ba7ed31ef9ca474f0e1501297f68c298e9f4c0028add35aea8bb83d53c08cfc007c1e005723cd0,0x190d119345b94fbd15497bcba94ecf7db2cbfd1e1fe7da034d26cbba169fb3968288b3fafb265f9ebd380512a71c3f2c",
|
||||||
|
"y": "0x05571a0f8d3c08d094576981f4a3b8eda0a8e771fcdcc8ecceaf1356a6acf17574518acb506e435b639353c2e14827c8,0x0bb5e7572275c567462d91807de765611490205a941a5a6af3b1691bfe596c31225d3aabdf15faff860cb4ef17c7c3be"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x0f48f1ea1318ddb713697708f7327781fb39718971d72a9245b9731faaca4dbaa7cca433d6c434a820c28b18e20ea208,0x06051467c8f85da5ba2540974758f7a1e0239a5981de441fdd87680a995649c211054869c50edbac1f3a86c561ba3162",
|
||||||
|
"y": "0x168b3d6df80069dbbedb714d41b32961ad064c227355e1ce5fac8e105de5e49d77f0c64867f3834848f152497eb76333,0x134e0e8331cee8cb12f9c2d0742714ed9eee78a84d634c9a95f6a7391b37125ed48bfc6e90bf3546e99930ff67cc97bc"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x004fd03968cd1c99a0dd84551f44c206c84dcbdb78076c5bfee24e89a92c8508b52b88b68a92258403cbe1ea2da3495f,0x1674338ea298281b636b2eb0fe593008d03171195fd6dcd4531e8a1ed1f02a72da238a17a635de307d7d24aa2d969a47",
|
||||||
|
"y": "0x0dc7fa13fff6b12558419e0a1e94bfc3cfaf67238009991c5f24ee94b632c3d09e27eca329989aee348a67b50d5e236c,0x169585e164c131103d85324f2d7747b23b91d66ae5d947c449c8194a347969fc6bbd967729768da485ba71868df8aed2"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x0313d9325081b415bfd4e5364efaef392ecf69b087496973b229303e1816d2080971470f7da112c4eb43053130b785e1,0x062f84cb21ed89406890c051a0e8b9cf6c575cf6e8e18ecf63ba86826b0ae02548d83b483b79e48512b82a6c0686df8f",
|
||||||
|
"0x1739123845406baa7be5c5dc74492051b6d42504de008c635f3535bb831d478a341420e67dcc7b46b2e8cba5379cca97,0x01897665d9cb5db16a27657760bbea7951f67ad68f8d55f7113f24ba6ddd82caef240a9bfa627972279974894701d975"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x19a84dd7248a1066f737cc34502ee5555bd3c19f2ecdb3c7d9e24dc65d4e25e50d83f0f77105e955d78f4762d33c17da,0x0934aba516a52d8ae479939a91998299c76d39cc0c035cd18813bec433f587e2d7a4fef038260eef0cef4d02aae3eb91",
|
||||||
|
"y": "0x14f81cd421617428bc3b9fe25afbb751d934a00493524bc4e065635b0555084dd54679df1536101b2c979c0152d09192,0x09bcccfa036b4847c9950780733633f13619994394c23ff0b32fa6b795844f4a0673e20282d07bc69641cee04f5e5662"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x09eccbc53df677f0e5814e3f86e41e146422834854a224bf5a83a50e4cc0a77bfc56718e8166ad180f53526ea9194b57,0x0c3633943f91daee715277bd644fba585168a72f96ded64fc5a384cce4ec884a4c3c30f08e09cd2129335dc8f67840ec",
|
||||||
|
"y": "0x0eb6186a0457d5b12d132902d4468bfeb7315d83320b6c32f1c875f344efcba979952b4aa418589cb01af712f98cc555,0x119e3cf167e69eb16c1c7830e8df88856d48be12e3ff0a40791a5cd2f7221311d4bf13b1847f371f467357b3f3c0b4c7"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x0eb3aabc1ddfce17ff18455fcc7167d15ce6b60ddc9eb9b59f8d40ab49420d35558686293d046fc1e42f864b7f60e381,0x198bdfb19d7441ebcca61e8ff774b29d17da16547d2c10c273227a635cacea3f16826322ae85717630f0867539b5ed8b",
|
||||||
|
"y": "0x0aaf1dee3adf3ed4c80e481c09b57ea4c705e1b8d25b897f0ceeec3990748716575f92abff22a1c8f4582aff7b872d52,0x0d058d9061ed27d4259848a06c96c5ca68921a5d269b078650c882cb3c2bd424a8702b7a6ee4e0ead9982baf6843e924"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x025820cefc7d06fd38de7d8e370e0da8a52498be9b53cba9927b2ef5c6de1e12e12f188bbc7bc923864883c57e49e253,0x034147b77ce337a52e5948f66db0bab47a8d038e712123bb381899b6ab5ad20f02805601e6104c29df18c254b8618c7b",
|
||||||
|
"0x0930315cae1f9a6017c3f0c8f2314baa130e1cf13f6532bff0a8a1790cd70af918088c3db94bda214e896e1543629795,0x10c4df2cacf67ea3cb3108b00d4cbd0b3968031ebc8eac4b1ebcefe84d6b715fde66bef0219951ece29d1facc8a520ef"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x01a6ba2f9a11fa5598b2d8ace0fbe0a0eacb65deceb476fbbcb64fd24557c2f4b18ecfc5663e54ae16a84f5ab7f62534,0x11fca2ff525572795a801eed17eb12785887c7b63fb77a42be46ce4a34131d71f7a73e95fee3f812aea3de78b4d01569",
|
||||||
|
"y": "0x0b6798718c8aed24bc19cb27f866f1c9effcdbf92397ad6448b5c9db90d2b9da6cbabf48adc1adf59a1a28344e79d57e,0x03a47f8e6d1763ba0cad63d6114c0accbef65707825a511b251a660a9b3994249ae4e63fac38b23da0c398689ee2ab52"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x17cadf8d04a1a170f8347d42856526a24cc466cb2ddfd506cff01191666b7f944e31244d662c904de5440516a2b09004,0x0d13ba91f2a8b0051cf3279ea0ee63a9f19bc9cb8bfcc7d78b3cbd8cc4fc43ba726774b28038213acf2b0095391c523e",
|
||||||
|
"y": "0x17ef19497d6d9246fa94d35575c0f8d06ee02f21a284dbeaa78768cb1e25abd564e3381de87bda26acd04f41181610c5,0x12c3c913ba4ed03c24f0721a81a6be7430f2971ffca8fd1729aafe496bb725807531b44b34b59b3ae5495e5a2dcbd5c8"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x16ec57b7fe04c71dfe34fb5ad84dbce5a2dbbd6ee085f1d8cd17f45e8868976fc3c51ad9eeda682c7869024d24579bfd,0x13103f7aace1ae1420d208a537f7d3a9679c287208026e4e3439ab8cd534c12856284d95e27f5e1f33eec2ce656533b0",
|
||||||
|
"y": "0x0958b2c4c2c10fcef5a6c59b9e92c4a67b0fae3e2e0f1b6b5edad9c940b8f3524ba9ebbc3f2ceb3cfe377655b3163bd7,0x0ccb594ed8bd14ca64ed9cb4e0aba221be540f25dd0d6ba15a4a4be5d67bcf35df7853b2d8dad3ba245f1ea3697f66aa"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x190b513da3e66fc9a3587b78c76d1d132b1152174d0b83e3c1114066392579a45824c5fa17649ab89299ddd4bda54935,0x12ab625b0fe0ebd1367fe9fac57bb1168891846039b4216b9d94007b674de2d79126870e88aeef54b2ec717a887dcf39",
|
||||||
|
"0x0e6a42010cf435fb5bacc156a585e1ea3294cc81d0ceb81924d95040298380b164f702275892cedd81b62de3aba3f6b5,0x117d9a0defc57a33ed208428cb84e54c85a6840e7648480ae428838989d25d97a0af8e3255be62b25c2a85630d2dddd8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
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.
123
bls12_381/src/curves/tests/mod.rs
Executable file
123
bls12_381/src/curves/tests/mod.rs
Executable file
@@ -0,0 +1,123 @@
|
|||||||
|
use ark_algebra_test_templates::*;
|
||||||
|
use ark_ec::{AffineRepr, CurveGroup, PrimeGroup};
|
||||||
|
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!(g1_glv; G1Projective; glv);
|
||||||
|
test_group!(g2_glv; G2Projective; glv);
|
||||||
|
test_group!(pairing_output; ark_ec::pairing::PairingOutput<Bls12_381>; msm);
|
||||||
|
test_pairing!(pairing; crate::Bls12_381);
|
||||||
|
test_h2c!(g1_h2c; "./src/curves/tests"; "BLS12381G1"; crate::g1::Config; crate::Fq; crate::Fq; 1);
|
||||||
|
test_h2c!(g2_hc2; "./src/curves/tests"; "BLS12381G2"; crate::g2::Config; crate::Fq2; crate::Fq; 2);
|
||||||
|
|
||||||
|
#[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);
|
||||||
|
}
|
||||||
258
bls12_381/src/curves/util.rs
Normal file
258
bls12_381/src/curves/util.rs
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
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 {
|
||||||
|
/// Fetches the flags from the byte-string
|
||||||
|
pub fn get_flags(bytes: &[u8]) -> Result<Self, SerializationError> {
|
||||||
|
let compression_flag_set = (bytes[0] >> 7) & 1;
|
||||||
|
let infinity_flag_set = (bytes[0] >> 6) & 1;
|
||||||
|
let sort_flag_set = (bytes[0] >> 5) & 1;
|
||||||
|
|
||||||
|
let is_compressed = compression_flag_set == 1;
|
||||||
|
let is_infinity = infinity_flag_set == 1;
|
||||||
|
let is_lexographically_largest = sort_flag_set == 1;
|
||||||
|
|
||||||
|
if is_lexographically_largest && (!is_compressed || is_infinity) {
|
||||||
|
return Err(SerializationError::InvalidData);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
is_compressed,
|
||||||
|
is_infinity,
|
||||||
|
is_lexographically_largest,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encodes the flags into the byte-string
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Removes the flags from the byte-string.
|
||||||
|
///
|
||||||
|
/// This reverses the effects of `encode_flags`.
|
||||||
|
pub fn remove_flags(bytes: &mut [u8]) {
|
||||||
|
bytes[0] &= 0b0001_1111;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_bytes_with_offset(bytes: &[u8], offset: usize, mask: bool) -> [u8; G1_SERIALIZED_SIZE] {
|
||||||
|
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 {
|
||||||
|
EncodingFlags::remove_flags(&mut tmp);
|
||||||
|
}
|
||||||
|
tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to obtain the x-coordinate
|
||||||
|
let x_bytes = read_bytes_with_offset(&bytes, 0, true);
|
||||||
|
|
||||||
|
if flags.is_infinity {
|
||||||
|
// Check that the `x` co-ordinate was `0`
|
||||||
|
if x_bytes != [0u8; 48] {
|
||||||
|
return Err(SerializationError::InvalidData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(G1Affine::zero());
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = deserialize_fq(x_bytes).ok_or(SerializationError::InvalidData)?;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
let x_bytes = read_bytes_with_offset(&bytes, 0, true);
|
||||||
|
let y_bytes = read_bytes_with_offset(&bytes, 1, false);
|
||||||
|
|
||||||
|
if flags.is_infinity {
|
||||||
|
if x_bytes != [0u8; 48] || y_bytes != [0u8; 48] {
|
||||||
|
return Err(SerializationError::InvalidData);
|
||||||
|
}
|
||||||
|
return Ok(G1Affine::zero());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to obtain the x-coordinate
|
||||||
|
let x = deserialize_fq(x_bytes).ok_or(SerializationError::InvalidData)?;
|
||||||
|
// Attempt to obtain the y-coordinate
|
||||||
|
let y = deserialize_fq(y_bytes).ok_or(SerializationError::InvalidData)?;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
let xc1_bytes = read_bytes_with_offset(&bytes, 0, true);
|
||||||
|
let xc0_bytes = read_bytes_with_offset(&bytes, 1, false);
|
||||||
|
|
||||||
|
if flags.is_infinity {
|
||||||
|
if xc1_bytes != [0u8; 48] || xc0_bytes != [0u8; 48] {
|
||||||
|
return Err(SerializationError::InvalidData);
|
||||||
|
}
|
||||||
|
return Ok(G2Affine::zero());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to obtain the x-coordinate
|
||||||
|
let xc1 = deserialize_fq(xc1_bytes).ok_or(SerializationError::InvalidData)?;
|
||||||
|
let xc0 = deserialize_fq(xc0_bytes).ok_or(SerializationError::InvalidData)?;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
let xc1_bytes = read_bytes_with_offset(&bytes, 0, true);
|
||||||
|
let xc0_bytes = read_bytes_with_offset(&bytes, 1, false);
|
||||||
|
|
||||||
|
let yc1_bytes = read_bytes_with_offset(&bytes, 2, false);
|
||||||
|
let yc0_bytes = read_bytes_with_offset(&bytes, 3, false);
|
||||||
|
|
||||||
|
if flags.is_infinity {
|
||||||
|
if xc1_bytes != [0u8; 48]
|
||||||
|
|| xc0_bytes != [0u8; 48]
|
||||||
|
|| yc1_bytes != [0u8; 48]
|
||||||
|
|| yc0_bytes != [0u8; 48]
|
||||||
|
{
|
||||||
|
return Err(SerializationError::InvalidData);
|
||||||
|
}
|
||||||
|
return Ok(G2Affine::zero());
|
||||||
|
}
|
||||||
|
|
||||||
|
let xc1 = deserialize_fq(xc1_bytes).ok_or(SerializationError::InvalidData)?;
|
||||||
|
let xc0 = deserialize_fq(xc0_bytes).ok_or(SerializationError::InvalidData)?;
|
||||||
|
let yc1 = deserialize_fq(yc1_bytes).ok_or(SerializationError::InvalidData)?;
|
||||||
|
let yc0 = deserialize_fq(yc0_bytes).ok_or(SerializationError::InvalidData)?;
|
||||||
|
|
||||||
|
// Attempt to obtain the x-coordinate
|
||||||
|
let x = Fq2::new(xc0, xc1);
|
||||||
|
|
||||||
|
// Attempt to obtain the y-coordinate
|
||||||
|
let y = Fq2::new(yc0, yc1);
|
||||||
|
|
||||||
|
let p = G2Affine::new_unchecked(x, y);
|
||||||
|
|
||||||
|
Ok(p)
|
||||||
|
}
|
||||||
@@ -1,115 +1,12 @@
|
|||||||
use ark_ff::{
|
use ark_ff::fields::{Fp384, MontBackend, MontConfig};
|
||||||
biginteger::BigInteger384 as BigInteger,
|
|
||||||
field_new,
|
|
||||||
fields::{FftParameters, Fp384, Fp384Parameters, FpParameters},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub type Fq = Fp384<FqParameters>;
|
#[derive(MontConfig)]
|
||||||
|
#[modulus = "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787"]
|
||||||
|
#[generator = "2"]
|
||||||
|
#[small_subgroup_base = "3"]
|
||||||
|
#[small_subgroup_power = "2"]
|
||||||
|
pub struct FqConfig;
|
||||||
|
pub type Fq = Fp384<MontBackend<FqConfig, 6>>;
|
||||||
|
|
||||||
pub struct FqParameters;
|
pub const FQ_ONE: Fq = ark_ff::MontFp!("1");
|
||||||
|
pub const FQ_ZERO: Fq = ark_ff::MontFp!("0");
|
||||||
impl Fp384Parameters for FqParameters {}
|
|
||||||
impl FftParameters for FqParameters {
|
|
||||||
type BigInt = BigInteger;
|
|
||||||
|
|
||||||
const TWO_ADICITY: u32 = 1;
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
|
||||||
0x43f5fffffffcaaae,
|
|
||||||
0x32b7fff2ed47fffd,
|
|
||||||
0x7e83a49a2e99d69,
|
|
||||||
0xeca8f3318332bb7a,
|
|
||||||
0xef148d1ea0f4c069,
|
|
||||||
0x40ab3263eff0206,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
impl FpParameters for FqParameters {
|
|
||||||
/// MODULUS = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const MODULUS: BigInteger = BigInteger([
|
|
||||||
0xb9feffffffffaaab,
|
|
||||||
0x1eabfffeb153ffff,
|
|
||||||
0x6730d2a0f6b0f624,
|
|
||||||
0x64774b84f38512bf,
|
|
||||||
0x4b1ba7b6434bacd7,
|
|
||||||
0x1a0111ea397fe69a,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const MODULUS_BITS: u32 = 381;
|
|
||||||
|
|
||||||
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
|
|
||||||
|
|
||||||
const REPR_SHAVE_BITS: u32 = 3;
|
|
||||||
|
|
||||||
/// R = 3380320199399472671518931668520476396067793891014375699959770179129436917079669831430077592723774664465579537268733
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const R: BigInteger = BigInteger([
|
|
||||||
0x760900000002fffd,
|
|
||||||
0xebf4000bc40c0002,
|
|
||||||
0x5f48985753c758ba,
|
|
||||||
0x77ce585370525745,
|
|
||||||
0x5c071a97a256ec6d,
|
|
||||||
0x15f65ec3fa80e493,
|
|
||||||
]);
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const R2: BigInteger = BigInteger([
|
|
||||||
0xf4df1f341c341746,
|
|
||||||
0xa76e6a609d104f1,
|
|
||||||
0x8de5476c4c95b6d5,
|
|
||||||
0x67eb88a9939d83c0,
|
|
||||||
0x9a793e85b519952d,
|
|
||||||
0x11988fe592cae3aa,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const INV: u64 = 0x89f3fffcfffcfffd;
|
|
||||||
|
|
||||||
/// GENERATOR = 2
|
|
||||||
/// Encoded in Montgomery form, so the value is
|
|
||||||
/// 2 * R % q = 2758230843577277949620073511305048635578704962089743514587482222134842183668501798417467556318533664893264801977679
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const GENERATOR: BigInteger = BigInteger([
|
|
||||||
0x321300000006554f,
|
|
||||||
0xb93c0018d6c40005,
|
|
||||||
0x57605e0db0ddbb51,
|
|
||||||
0x8b256521ed1f9bcb,
|
|
||||||
0x6cf28d7901622c03,
|
|
||||||
0x11ebab9dbb81e28c,
|
|
||||||
]);
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
|
||||||
0xdcff7fffffffd555,
|
|
||||||
0xf55ffff58a9ffff,
|
|
||||||
0xb39869507b587b12,
|
|
||||||
0xb23ba5c279c2895f,
|
|
||||||
0x258dd3db21a5d66b,
|
|
||||||
0xd0088f51cbff34d,
|
|
||||||
]);
|
|
||||||
|
|
||||||
/// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T
|
|
||||||
/// For T coprime to 2
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const T: BigInteger = BigInteger([
|
|
||||||
0xdcff7fffffffd555,
|
|
||||||
0xf55ffff58a9ffff,
|
|
||||||
0xb39869507b587b12,
|
|
||||||
0xb23ba5c279c2895f,
|
|
||||||
0x258dd3db21a5d66b,
|
|
||||||
0xd0088f51cbff34d,
|
|
||||||
]);
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
|
||||||
0xee7fbfffffffeaaa,
|
|
||||||
0x7aaffffac54ffff,
|
|
||||||
0xd9cc34a83dac3d89,
|
|
||||||
0xd91dd2e13ce144af,
|
|
||||||
0x92c6e9ed90d2eb35,
|
|
||||||
0x680447a8e5ff9a6,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const FQ_ONE: Fq = field_new!(Fq, "1");
|
|
||||||
pub const FQ_ZERO: Fq = field_new!(Fq, "0");
|
|
||||||
|
|||||||
@@ -1,76 +1,77 @@
|
|||||||
use crate::*;
|
use ark_ff::{fields::*, MontFp};
|
||||||
use ark_ff::{field_new, fields::*};
|
|
||||||
|
|
||||||
pub type Fq12 = Fp12<Fq12Parameters>;
|
use crate::*;
|
||||||
|
|
||||||
|
pub type Fq12 = Fp12<Fq12Config>;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Fq12Parameters;
|
pub struct Fq12Config;
|
||||||
|
|
||||||
impl Fp12Parameters for Fq12Parameters {
|
impl Fp12Config for Fq12Config {
|
||||||
type Fp6Params = Fq6Parameters;
|
type Fp6Config = Fq6Config;
|
||||||
|
|
||||||
const NONRESIDUE: Fq6 = field_new!(Fq6, FQ2_ZERO, FQ2_ONE, FQ2_ZERO);
|
const NONRESIDUE: Fq6 = Fq6::new(Fq2::ZERO, Fq2::ONE, Fq2::ZERO);
|
||||||
|
|
||||||
const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[
|
const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[
|
||||||
// Fp2::NONRESIDUE^(((q^0) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^0) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "1"),
|
Fq::ONE,
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^1) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"),
|
MontFp!("3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"),
|
||||||
field_new!(Fq, "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"),
|
MontFp!("151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^2) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"),
|
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^3) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
|
MontFp!("2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
|
||||||
field_new!(Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"),
|
MontFp!("1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^4) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^5) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"),
|
MontFp!("3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"),
|
||||||
field_new!(Fq, "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"),
|
MontFp!("877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^6) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^6) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "-1"),
|
MontFp!("-1"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^7) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^7) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"),
|
MontFp!("151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"),
|
||||||
field_new!(Fq, "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"),
|
MontFp!("3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^8) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^8) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^9) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^9) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"),
|
MontFp!("1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"),
|
||||||
field_new!(Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
|
MontFp!("2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^10) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^10) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"),
|
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^11) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^11) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"),
|
MontFp!("877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"),
|
||||||
field_new!(Fq, "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"),
|
MontFp!("3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,42 @@
|
|||||||
|
use ark_ff::{fields::*, MontFp};
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use ark_ff::{field_new, fields::*};
|
|
||||||
|
|
||||||
pub type Fq2 = Fp2<Fq2Parameters>;
|
pub type Fq2 = Fp2<Fq2Config>;
|
||||||
|
|
||||||
pub struct Fq2Parameters;
|
pub struct Fq2Config;
|
||||||
|
|
||||||
impl Fp2Parameters for Fq2Parameters {
|
impl Fp2Config for Fq2Config {
|
||||||
type Fp = Fq;
|
type Fp = Fq;
|
||||||
|
|
||||||
/// NONRESIDUE = -1
|
/// NONRESIDUE = -1
|
||||||
#[rustfmt::skip]
|
const NONRESIDUE: Fq = MontFp!("-1");
|
||||||
const NONRESIDUE: Fq = field_new!(Fq, "-1");
|
|
||||||
|
|
||||||
/// QUADRATIC_NONRESIDUE = (U + 1)
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const QUADRATIC_NONRESIDUE: (Fq, Fq) = (FQ_ONE, FQ_ONE);
|
|
||||||
|
|
||||||
/// Coefficients for the Frobenius automorphism.
|
/// Coefficients for the Frobenius automorphism.
|
||||||
#[rustfmt::skip]
|
|
||||||
const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[
|
const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[
|
||||||
// Fq(-1)**(((q^0) - 1) / 2)
|
// Fq(-1)**(((q^0) - 1) / 2)
|
||||||
field_new!(Fq, "1"),
|
Fq::ONE,
|
||||||
// Fq(-1)**(((q^1) - 1) / 2)
|
// Fq(-1)**(((q^1) - 1) / 2)
|
||||||
field_new!(Fq, "-1"),
|
MontFp!("-1"),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO);
|
|
||||||
pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO);
|
|
||||||
|
|||||||
@@ -1,96 +1,91 @@
|
|||||||
use crate::*;
|
use ark_ff::{fields::*, MontFp};
|
||||||
use ark_ff::{field_new, fields::*};
|
|
||||||
|
|
||||||
pub type Fq6 = Fp6<Fq6Parameters>;
|
use crate::*;
|
||||||
|
|
||||||
|
pub type Fq6 = Fp6<Fq6Config>;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Fq6Parameters;
|
pub struct Fq6Config;
|
||||||
|
|
||||||
impl Fp6Parameters for Fq6Parameters {
|
impl Fp6Config for Fq6Config {
|
||||||
type Fp2Params = Fq2Parameters;
|
type Fp2Config = Fq2Config;
|
||||||
|
|
||||||
/// NONRESIDUE = (U + 1)
|
/// NONRESIDUE = (U + 1)
|
||||||
#[rustfmt::skip]
|
const NONRESIDUE: Fq2 = Fq2::new(Fq::ONE, Fq::ONE);
|
||||||
const NONRESIDUE: Fq2 = field_new!(Fq2,
|
|
||||||
field_new!(Fq, "1"),
|
|
||||||
field_new!(Fq, "1"),
|
|
||||||
);
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[
|
const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[
|
||||||
// Fp2::NONRESIDUE^(((q^0) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^0) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "1"),
|
Fq::ONE,
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^1) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^2) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^3) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
field_new!(Fq, "1"),
|
Fq::ONE,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^4) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^5) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[
|
const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[
|
||||||
// Fq2(u + 1)**(((2q^0) - 2) / 3)
|
// Fq2(u + 1)**(((2q^0) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "1"),
|
Fq::ONE,
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fq2(u + 1)**(((2q^1) - 2) / 3)
|
// Fq2(u + 1)**(((2q^1) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"),
|
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fq2(u + 1)**(((2q^2) - 2) / 3)
|
// Fq2(u + 1)**(((2q^2) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fq2(u + 1)**(((2q^3) - 2) / 3)
|
// Fq2(u + 1)**(((2q^3) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "-1"),
|
MontFp!("-1"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fq2(u + 1)**(((2q^4) - 2) / 3)
|
// Fq2(u + 1)**(((2q^4) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fq2(u + 1)**(((2q^5) - 2) / 3)
|
// Fq2(u + 1)**(((2q^5) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"),
|
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
/// 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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,100 +1,9 @@
|
|||||||
use ark_ff::{
|
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
|
||||||
biginteger::BigInteger256 as BigInteger,
|
|
||||||
fields::{FftParameters, Fp256, Fp256Parameters, FpParameters},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub type Fr = Fp256<FrParameters>;
|
#[derive(MontConfig)]
|
||||||
|
#[modulus = "52435875175126190479447740508185965837690552500527637822603658699938581184513"]
|
||||||
pub struct FrParameters;
|
#[generator = "7"]
|
||||||
|
#[small_subgroup_base = "3"]
|
||||||
impl Fp256Parameters for FrParameters {}
|
#[small_subgroup_power = "1"]
|
||||||
impl FftParameters for FrParameters {
|
pub struct FrConfig;
|
||||||
type BigInt = BigInteger;
|
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;
|
||||||
|
|
||||||
const TWO_ADICITY: u32 = 32;
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
|
||||||
0xb9b58d8c5f0e466a,
|
|
||||||
0x5b1b4c801819d7ec,
|
|
||||||
0xaf53ae352a31e64,
|
|
||||||
0x5bf3adda19e9b27b,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
impl FpParameters for FrParameters {
|
|
||||||
/// MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const MODULUS: BigInteger = BigInteger([
|
|
||||||
0xffffffff00000001,
|
|
||||||
0x53bda402fffe5bfe,
|
|
||||||
0x3339d80809a1d805,
|
|
||||||
0x73eda753299d7d48,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const MODULUS_BITS: u32 = 255;
|
|
||||||
|
|
||||||
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
|
|
||||||
|
|
||||||
const REPR_SHAVE_BITS: u32 = 1;
|
|
||||||
|
|
||||||
/// R = 10920338887063814464675503992315976177888879664585288394250266608035967270910
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const R: BigInteger = BigInteger([
|
|
||||||
0x1fffffffe,
|
|
||||||
0x5884b7fa00034802,
|
|
||||||
0x998c4fefecbc4ff5,
|
|
||||||
0x1824b159acc5056f,
|
|
||||||
]);
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const R2: BigInteger = BigInteger([
|
|
||||||
0xc999e990f3f29c6d,
|
|
||||||
0x2b6cedcb87925c23,
|
|
||||||
0x5d314967254398f,
|
|
||||||
0x748d9d99f59ff11,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const INV: u64 = 0xfffffffeffffffff;
|
|
||||||
|
|
||||||
/// GENERATOR = 7
|
|
||||||
/// Encoded in Montgomery form, so the value here is
|
|
||||||
/// 7 * R % q = 24006497034320510773280787438025867407531605151569380937148207556313189711857
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const GENERATOR: BigInteger = BigInteger([
|
|
||||||
0xefffffff1,
|
|
||||||
0x17e363d300189c0f,
|
|
||||||
0xff9c57876f8457b0,
|
|
||||||
0x351332208fc5a8c4,
|
|
||||||
]);
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
|
||||||
0x7fffffff80000000,
|
|
||||||
0xa9ded2017fff2dff,
|
|
||||||
0x199cec0404d0ec02,
|
|
||||||
0x39f6d3a994cebea4,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T
|
|
||||||
// For T coprime to 2
|
|
||||||
|
|
||||||
// T = (MODULUS - 1) / 2^S =
|
|
||||||
// 12208678567578594777604504606729831043093128246378069236549469339647
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const T: BigInteger = BigInteger([
|
|
||||||
0xfffe5bfeffffffff,
|
|
||||||
0x9a1d80553bda402,
|
|
||||||
0x299d7d483339d808,
|
|
||||||
0x73eda753,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// (T - 1) / 2 =
|
|
||||||
// 6104339283789297388802252303364915521546564123189034618274734669823
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
|
||||||
0x7fff2dff7fffffff,
|
|
||||||
0x4d0ec02a9ded201,
|
|
||||||
0x94cebea4199cec04,
|
|
||||||
0x39f6d3a9,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -23,5 +23,5 @@ pub mod fq12;
|
|||||||
#[cfg(feature = "curve")]
|
#[cfg(feature = "curve")]
|
||||||
pub use self::fq12::*;
|
pub use self::fq12::*;
|
||||||
|
|
||||||
#[cfg(all(feature = "curve", feature = "std", test))]
|
#[cfg(all(feature = "curve", test))]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
11
bls12_381/src/lib.rs
Normal file → Executable file
11
bls12_381/src/lib.rs
Normal file → Executable file
@@ -9,15 +9,16 @@
|
|||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
|
|
||||||
//! This library implements the BLS12_381 curve generated by [Sean Bowe](https://electriccoin.co/blog/new-snark-curve/).
|
//! This library implements the BLS12_381 curve generated by [Sean Bowe](https://electriccoin.co/blog/new-snark-curve/).
|
||||||
//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree 12,
|
//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree
|
||||||
//! defined over a 381-bit (prime) field.
|
//! 12, defined over a 381-bit (prime) field.
|
||||||
//! This curve was intended to replace the BN254 curve to provide a higher security
|
//! This curve was intended to replace the BN254 curve to provide a higher
|
||||||
//! level without incurring a large performance overhead.
|
//! security level without incurring a large performance overhead.
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//! Curve information:
|
//! Curve information:
|
||||||
//! * Base field: q = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
|
//! * Base field: q = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
|
||||||
//! * Scalar field: r = 52435875175126190479447740508185965837690552500527637822603658699938581184513
|
//! * Scalar field: r =
|
||||||
|
//! 52435875175126190479447740508185965837690552500527637822603658699938581184513
|
||||||
//! * valuation(q - 1, 2) = 1
|
//! * valuation(q - 1, 2) = 1
|
||||||
//! * valuation(r - 1, 2) = 32
|
//! * valuation(r - 1, 2) = 32
|
||||||
//! * G1 curve equation: y^2 = x^3 + 4
|
//! * G1 curve equation: y^2 = x^3 + 4
|
||||||
|
|||||||
@@ -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,16 +10,17 @@ 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", default-features = false }
|
||||||
ark-ec = { version="^0.3.0", default-features = false }
|
ark-ec = { version= "0.4.0", default-features = false }
|
||||||
ark-std = { version="^0.3.0", default-features = false }
|
ark-std = { version = "0.4.0", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ark-serialize = { version="^0.3.0", default-features = false }
|
ark-serialize = { version = "0.4.0", default-features = false }
|
||||||
ark-algebra-test-templates = { version="^0.3.0", default-features = false }
|
ark-algebra-test-templates = { version = "0.4.0", default-features = false }
|
||||||
|
ark-algebra-bench-templates = { version = "0.4.0", default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "curve" ]
|
default = [ "curve" ]
|
||||||
@@ -27,3 +28,8 @@ std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ]
|
|||||||
|
|
||||||
curve = [ "scalar_field" ]
|
curve = [ "scalar_field" ]
|
||||||
scalar_field = []
|
scalar_field = []
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "bn254"
|
||||||
|
path = "benches/bn254.rs"
|
||||||
|
harness = false
|
||||||
|
|||||||
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,
|
||||||
|
);
|
||||||
28
bn254/scripts/base_field.sage
Normal file
28
bn254/scripts/base_field.sage
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
modulus = 21888242871839275222246405745257275088696311157297823662689037894645226208583
|
||||||
|
|
||||||
|
assert(modulus.is_prime())
|
||||||
|
|
||||||
|
Fp = GF(modulus)
|
||||||
|
|
||||||
|
generator = Fp(0);
|
||||||
|
for i in range(0, 20):
|
||||||
|
i = Fp(i);
|
||||||
|
neg_i = Fp(-i)
|
||||||
|
if not(i.is_primitive_root() or neg_i.is_primitive_root()):
|
||||||
|
continue
|
||||||
|
elif i.is_primitive_root():
|
||||||
|
assert(i.is_primitive_root());
|
||||||
|
print("Generator: %d" % i)
|
||||||
|
generator = i
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
assert(neg_i.is_primitive_root());
|
||||||
|
print("Generator: %d" % neg_i)
|
||||||
|
generator = neg_i
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
two_adicity = valuation(modulus - 1, 2);
|
||||||
|
trace = (modulus - 1) / 2**two_adicity;
|
||||||
|
two_adic_root_of_unity = generator^trace
|
||||||
|
print("2-adic Root of Unity: %d " % two_adic_root_of_unity)
|
||||||
28
bn254/scripts/scalar_field.sage
Normal file
28
bn254/scripts/scalar_field.sage
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
modulus = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||||
|
|
||||||
|
assert(modulus.is_prime())
|
||||||
|
|
||||||
|
Fp = GF(modulus)
|
||||||
|
|
||||||
|
generator = Fp(0);
|
||||||
|
for i in range(0, 20):
|
||||||
|
i = Fp(i);
|
||||||
|
neg_i = Fp(-i)
|
||||||
|
if not(i.is_primitive_root() or neg_i.is_primitive_root()):
|
||||||
|
continue
|
||||||
|
elif i.is_primitive_root():
|
||||||
|
assert(i.is_primitive_root());
|
||||||
|
print("Generator: %d" % i)
|
||||||
|
generator = i
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
assert(neg_i.is_primitive_root());
|
||||||
|
print("Generator: %d" % neg_i)
|
||||||
|
generator = neg_i
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
two_adicity = valuation(modulus - 1, 2);
|
||||||
|
trace = (modulus - 1) / 2**two_adicity;
|
||||||
|
two_adic_root_of_unity = generator^trace
|
||||||
|
print("2-adic Root of Unity: %d " % two_adic_root_of_unity)
|
||||||
@@ -1,41 +1,83 @@
|
|||||||
use ark_ec::models::{ModelParameters, SWModelParameters};
|
use ark_ec::{
|
||||||
use ark_ff::{field_new, Zero};
|
bn,
|
||||||
|
models::{short_weierstrass::SWCurveConfig, CurveConfig},
|
||||||
|
scalar_mul::glv::GLVConfig,
|
||||||
|
short_weierstrass::{Affine, Projective},
|
||||||
|
};
|
||||||
|
use ark_ff::{AdditiveGroup, BigInt, Field, MontFp, PrimeField, 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;
|
||||||
|
|
||||||
impl ModelParameters for Parameters {
|
pub type G1Affine = Affine<Config>;
|
||||||
|
|
||||||
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
}
|
|
||||||
|
|
||||||
impl SWModelParameters for Parameters {
|
|
||||||
/// COEFF_A = 0
|
|
||||||
const COEFF_A: Fq = field_new!(Fq, "0");
|
|
||||||
|
|
||||||
/// COEFF_B = 3
|
|
||||||
const COEFF_B: Fq = field_new!(Fq, "3");
|
|
||||||
|
|
||||||
/// COFACTOR = 1
|
/// COFACTOR = 1
|
||||||
const COFACTOR: &'static [u64] = &[0x1];
|
const COFACTOR: &'static [u64] = &[0x1];
|
||||||
|
|
||||||
/// COFACTOR_INV = COFACTOR^{-1} mod r = 1
|
/// COFACTOR_INV = COFACTOR^{-1} mod r = 1
|
||||||
const COFACTOR_INV: Fr = field_new!(Fr, "1");
|
const COFACTOR_INV: Fr = Fr::ONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWCurveConfig for Config {
|
||||||
|
/// COEFF_A = 0
|
||||||
|
const COEFF_A: Fq = Fq::ZERO;
|
||||||
|
|
||||||
|
/// COEFF_B = 3
|
||||||
|
const COEFF_B: Fq = MontFp!("3");
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||||
(G1_GENERATOR_X, G1_GENERATOR_Y);
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
fn mul_by_a(_: Self::BaseField) -> Self::BaseField {
|
||||||
Self::BaseField::zero()
|
Self::BaseField::zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul_projective(
|
||||||
|
p: &bn::G1Projective<crate::Config>,
|
||||||
|
scalar: &[u64],
|
||||||
|
) -> bn::G1Projective<crate::Config> {
|
||||||
|
let s = Self::ScalarField::from_sign_and_limbs(true, scalar);
|
||||||
|
GLVConfig::glv_mul_projective(*p, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GLVConfig for Config {
|
||||||
|
const ENDO_COEFFS: &'static [Self::BaseField] = &[MontFp!(
|
||||||
|
"21888242871839275220042445260109153167277707414472061641714758635765020556616"
|
||||||
|
)];
|
||||||
|
|
||||||
|
const LAMBDA: Self::ScalarField =
|
||||||
|
MontFp!("21888242871839275217838484774961031246154997185409878258781734729429964517155");
|
||||||
|
|
||||||
|
const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
|
||||||
|
(false, BigInt!("147946756881789319000765030803803410728")),
|
||||||
|
(true, BigInt!("9931322734385697763")),
|
||||||
|
(false, BigInt!("9931322734385697763")),
|
||||||
|
(false, BigInt!("147946756881789319010696353538189108491")),
|
||||||
|
];
|
||||||
|
|
||||||
|
fn endomorphism(p: &Projective<Self>) -> Projective<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
fn endomorphism_affine(p: &Affine<Self>) -> Affine<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// G1_GENERATOR_X = 1
|
/// G1_GENERATOR_X = 1
|
||||||
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "1");
|
pub const G1_GENERATOR_X: Fq = Fq::ONE;
|
||||||
|
|
||||||
/// G1_GENERATOR_Y = 2
|
/// G1_GENERATOR_Y = 2
|
||||||
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "2");
|
pub const G1_GENERATOR_Y: Fq = MontFp!("2");
|
||||||
|
|||||||
@@ -1,31 +1,23 @@
|
|||||||
use ark_ec::models::{ModelParameters, SWModelParameters};
|
use ark_ec::{
|
||||||
use ark_ff::{field_new, Zero};
|
models::{short_weierstrass::SWCurveConfig, CurveConfig},
|
||||||
|
scalar_mul::glv::GLVConfig,
|
||||||
|
short_weierstrass::{Affine, Projective},
|
||||||
|
};
|
||||||
|
use ark_ff::{AdditiveGroup, BigInt, MontFp, PrimeField, Zero};
|
||||||
|
|
||||||
use crate::{Fq, Fq2, Fr};
|
use crate::{Fq, Fq2, Fr};
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
pub type G2Affine = Affine<Config>;
|
||||||
pub struct Parameters;
|
|
||||||
|
|
||||||
impl ModelParameters for Parameters {
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
|
pub struct Config;
|
||||||
|
|
||||||
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq2;
|
type BaseField = Fq2;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
}
|
|
||||||
|
|
||||||
impl SWModelParameters for Parameters {
|
|
||||||
/// COEFF_A = [0, 0]
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const COEFF_A: Fq2 = field_new!(Fq2, field_new!(Fq, "0"), field_new!(Fq, "0"));
|
|
||||||
|
|
||||||
/// COEFF_B = 3/(u+9)
|
|
||||||
/// = (19485874751759354771024239261021720505790618469301721065564631296452457478373, 266929791119991161246907387137283842545076965332900288569378510910307636690)
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const COEFF_B: Fq2 = field_new!(Fq2,
|
|
||||||
field_new!(Fq, "19485874751759354771024239261021720505790618469301721065564631296452457478373"),
|
|
||||||
field_new!(Fq, "266929791119991161246907387137283842545076965332900288569378510910307636690"),
|
|
||||||
);
|
|
||||||
|
|
||||||
/// COFACTOR = (36 * X^4) + (36 * X^3) + (30 * X^2) + 6*X + 1
|
/// COFACTOR = (36 * X^4) + (36 * X^3) + (30 * X^2) + 6*X + 1
|
||||||
/// = 21888242871839275222246405745257275088844257914179612981679871602714643921549
|
/// 21888242871839275222246405745257275088844257914179612981679871602714643921549
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
const COFACTOR: &'static [u64] = &[
|
const COFACTOR: &'static [u64] = &[
|
||||||
0x345f2299c0f9fa8d,
|
0x345f2299c0f9fa8d,
|
||||||
@@ -35,40 +27,78 @@ impl SWModelParameters for Parameters {
|
|||||||
];
|
];
|
||||||
|
|
||||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||||
#[rustfmt::skip]
|
const COFACTOR_INV: Fr =
|
||||||
const COFACTOR_INV: Fr = field_new!(Fr, "10944121435919637613327163357776759465618812564592884533313067514031822496649");
|
MontFp!("10944121435919637613327163357776759465618812564592884533313067514031822496649");
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWCurveConfig for Config {
|
||||||
|
/// COEFF_A = [0, 0]
|
||||||
|
const COEFF_A: Fq2 = Fq2::ZERO;
|
||||||
|
|
||||||
|
/// COEFF_B = 3/(u+9)
|
||||||
|
/// (19485874751759354771024239261021720505790618469301721065564631296452457478373, 266929791119991161246907387137283842545076965332900288569378510910307636690)
|
||||||
|
const COEFF_B: Fq2 = Fq2::new(
|
||||||
|
MontFp!("19485874751759354771024239261021720505790618469301721065564631296452457478373"),
|
||||||
|
MontFp!("266929791119991161246907387137283842545076965332900288569378510910307636690"),
|
||||||
|
);
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
||||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||||
(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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
impl GLVConfig for Config {
|
||||||
pub const G2_GENERATOR_X: Fq2 = field_new!(Fq2, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
const ENDO_COEFFS: &'static [Self::BaseField] = &[Fq2::new(
|
||||||
#[rustfmt::skip]
|
MontFp!("21888242871839275220042445260109153167277707414472061641714758635765020556616"),
|
||||||
pub const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
|
Fq::ZERO,
|
||||||
|
)];
|
||||||
|
|
||||||
|
const LAMBDA: Self::ScalarField =
|
||||||
|
MontFp!("4407920970296243842393367215006156084916469457145843978461");
|
||||||
|
|
||||||
|
const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
|
||||||
|
(false, BigInt!("147946756881789319010696353538189108491")),
|
||||||
|
(false, BigInt!("9931322734385697763")),
|
||||||
|
(true, BigInt!("9931322734385697763")),
|
||||||
|
(false, BigInt!("147946756881789319000765030803803410728")),
|
||||||
|
];
|
||||||
|
|
||||||
|
fn endomorphism(p: &Projective<Self>) -> Projective<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn endomorphism_affine(p: &Affine<Self>) -> Affine<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const G2_GENERATOR_X: Fq2 = Fq2::new(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
||||||
|
pub const G2_GENERATOR_Y: Fq2 = Fq2::new(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C0 =
|
/// G2_GENERATOR_X_C0 =
|
||||||
/// 10857046999023057135944570762232829481370756359578518086990519993285655852781
|
/// 10857046999023057135944570762232829481370756359578518086990519993285655852781
|
||||||
#[rustfmt::skip]
|
pub const G2_GENERATOR_X_C0: Fq =
|
||||||
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "10857046999023057135944570762232829481370756359578518086990519993285655852781");
|
MontFp!("10857046999023057135944570762232829481370756359578518086990519993285655852781");
|
||||||
|
|
||||||
/// G2_GENERATOR_X_C1 =
|
/// G2_GENERATOR_X_C1 =
|
||||||
/// 11559732032986387107991004021392285783925812861821192530917403151452391805634
|
/// 11559732032986387107991004021392285783925812861821192530917403151452391805634
|
||||||
#[rustfmt::skip]
|
pub const G2_GENERATOR_X_C1: Fq =
|
||||||
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "11559732032986387107991004021392285783925812861821192530917403151452391805634");
|
MontFp!("11559732032986387107991004021392285783925812861821192530917403151452391805634");
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C0 =
|
/// G2_GENERATOR_Y_C0 =
|
||||||
/// 8495653923123431417604973247489272438418190587263600148770280649306958101930
|
/// 8495653923123431417604973247489272438418190587263600148770280649306958101930
|
||||||
#[rustfmt::skip]
|
pub const G2_GENERATOR_Y_C0: Fq =
|
||||||
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "8495653923123431417604973247489272438418190587263600148770280649306958101930");
|
MontFp!("8495653923123431417604973247489272438418190587263600148770280649306958101930");
|
||||||
|
|
||||||
/// G2_GENERATOR_Y_C1 =
|
/// G2_GENERATOR_Y_C1 =
|
||||||
/// 4082367875863433681332203403145435568316851327593401208105741076214120093531
|
/// 4082367875863433681332203403145435568316851327593401208105741076214120093531
|
||||||
#[rustfmt::skip]
|
pub const G2_GENERATOR_Y_C1: Fq =
|
||||||
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "4082367875863433681332203403145435568316851327593401208105741076214120093531");
|
MontFp!("4082367875863433681332203403145435568316851327593401208105741076214120093531");
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
use crate::*;
|
|
||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bn,
|
bn,
|
||||||
bn::{Bn, BnParameters, TwistType},
|
bn::{Bn, BnConfig, TwistType},
|
||||||
};
|
};
|
||||||
use ark_ff::field_new;
|
use ark_ff::MontFp;
|
||||||
|
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
pub mod g1;
|
pub mod g1;
|
||||||
pub mod g2;
|
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;
|
||||||
@@ -22,40 +24,26 @@ impl BnParameters for Parameters {
|
|||||||
-1, 0, 0, 1, 0, 1, 1,
|
-1, 0, 0, 1, 0, 1, 1,
|
||||||
];
|
];
|
||||||
|
|
||||||
const TWIST_MUL_BY_Q_X: Fq2 = field_new!(
|
const TWIST_MUL_BY_Q_X: Fq2 = Fq2::new(
|
||||||
Fq2,
|
MontFp!("21575463638280843010398324269430826099269044274347216827212613867836435027261"),
|
||||||
field_new!(
|
MontFp!("10307601595873709700152284273816112264069230130616436755625194854815875713954"),
|
||||||
Fq,
|
|
||||||
"21575463638280843010398324269430826099269044274347216827212613867836435027261"
|
|
||||||
),
|
|
||||||
field_new!(
|
|
||||||
Fq,
|
|
||||||
"10307601595873709700152284273816112264069230130616436755625194854815875713954"
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
const TWIST_MUL_BY_Q_Y: Fq2 = field_new!(
|
const TWIST_MUL_BY_Q_Y: Fq2 = Fq2::new(
|
||||||
Fq2,
|
MontFp!("2821565182194536844548159561693502659359617185244120367078079554186484126554"),
|
||||||
field_new!(
|
MontFp!("3505843767911556378687030309984248845540243509899259641013678093033130930403"),
|
||||||
Fq,
|
|
||||||
"2821565182194536844548159561693502659359617185244120367078079554186484126554"
|
|
||||||
),
|
|
||||||
field_new!(
|
|
||||||
Fq,
|
|
||||||
"3505843767911556378687030309984248845540243509899259641013678093033130930403"
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
const TWIST_TYPE: TwistType = TwistType::D;
|
const TWIST_TYPE: TwistType = TwistType::D;
|
||||||
type Fp = Fq;
|
type Fp = Fq;
|
||||||
type Fp2Params = Fq2Parameters;
|
type Fp2Config = Fq2Config;
|
||||||
type Fp6Params = Fq6Parameters;
|
type Fp6Config = Fq6Config;
|
||||||
type Fp12Params = Fq12Parameters;
|
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>;
|
||||||
|
|||||||
93
bn254/src/curves/tests.rs
Normal file → Executable file
93
bn254/src/curves/tests.rs
Normal file → Executable file
@@ -1,86 +1,11 @@
|
|||||||
#![allow(unused_imports)]
|
use ark_algebra_test_templates::*;
|
||||||
use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine, ProjectiveCurve};
|
use ark_ff::fields::Field;
|
||||||
use ark_ff::{
|
|
||||||
fields::{Field, FpParameters, PrimeField, SquareRootField},
|
|
||||||
One, Zero,
|
|
||||||
};
|
|
||||||
use ark_serialize::CanonicalSerialize;
|
|
||||||
use ark_std::rand::Rng;
|
|
||||||
use ark_std::test_rng;
|
|
||||||
use core::ops::{AddAssign, MulAssign};
|
|
||||||
|
|
||||||
use crate::{g1, g2, Bn254, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
|
use crate::{Bn254, G1Projective, G2Projective};
|
||||||
|
|
||||||
use ark_algebra_test_templates::{curves::*, groups::*};
|
test_group!(g1; G1Projective; sw);
|
||||||
|
test_group!(g2; G2Projective; sw);
|
||||||
#[test]
|
test_group!(pairing_output; ark_ec::pairing::PairingOutput<Bn254>; msm);
|
||||||
fn test_g1_projective_curve() {
|
test_pairing!(pairing; crate::Bn254);
|
||||||
curve_tests::<G1Projective>();
|
test_group!(g1_glv; G1Projective; glv);
|
||||||
|
test_group!(g2_glv; G2Projective; glv);
|
||||||
sw_tests::<g1::Parameters>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_projective_group() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: G1Projective = rng.gen();
|
|
||||||
let b: G1Projective = rng.gen();
|
|
||||||
group_test(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_generator() {
|
|
||||||
let generator = G1Affine::prime_subgroup_generator();
|
|
||||||
assert!(generator.is_on_curve());
|
|
||||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_projective_curve() {
|
|
||||||
curve_tests::<G2Projective>();
|
|
||||||
|
|
||||||
sw_tests::<g2::Parameters>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_projective_group() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: G2Projective = rng.gen();
|
|
||||||
let b: G2Projective = rng.gen();
|
|
||||||
group_test(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_generator() {
|
|
||||||
let generator = G2Affine::prime_subgroup_generator();
|
|
||||||
assert!(generator.is_on_curve());
|
|
||||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_bilinearity() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: G1Projective = rng.gen();
|
|
||||||
let b: G2Projective = rng.gen();
|
|
||||||
let s: Fr = rng.gen();
|
|
||||||
|
|
||||||
let mut sa = a;
|
|
||||||
sa.mul_assign(s);
|
|
||||||
let mut sb = b;
|
|
||||||
sb.mul_assign(s);
|
|
||||||
|
|
||||||
let ans1 = Bn254::pairing(sa, b);
|
|
||||||
let ans2 = Bn254::pairing(a, sb);
|
|
||||||
let ans3 = Bn254::pairing(a, b).pow(s.into_repr());
|
|
||||||
|
|
||||||
assert_eq!(ans1, ans2);
|
|
||||||
assert_eq!(ans2, ans3);
|
|
||||||
|
|
||||||
assert_ne!(ans1, Fq12::one());
|
|
||||||
assert_ne!(ans2, Fq12::one());
|
|
||||||
assert_ne!(ans3, Fq12::one());
|
|
||||||
|
|
||||||
assert_eq!(ans1.pow(Fr::characteristic()), Fq12::one());
|
|
||||||
assert_eq!(ans2.pow(Fr::characteristic()), Fq12::one());
|
|
||||||
assert_eq!(ans3.pow(Fr::characteristic()), Fq12::one());
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,96 +1,7 @@
|
|||||||
use ark_ff::{biginteger::BigInteger256 as BigInteger, field_new, fields::*};
|
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
|
||||||
|
|
||||||
pub type Fq = Fp256<FqParameters>;
|
#[derive(MontConfig)]
|
||||||
|
#[modulus = "21888242871839275222246405745257275088696311157297823662689037894645226208583"]
|
||||||
pub struct FqParameters;
|
#[generator = "3"]
|
||||||
|
pub struct FqConfig;
|
||||||
impl Fp256Parameters for FqParameters {}
|
pub type Fq = Fp256<MontBackend<FqConfig, 4>>;
|
||||||
impl FftParameters for FqParameters {
|
|
||||||
type BigInt = BigInteger;
|
|
||||||
|
|
||||||
const TWO_ADICITY: u32 = 1;
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
|
||||||
0x68c3488912edefaa,
|
|
||||||
0x8d087f6872aabf4f,
|
|
||||||
0x51e1a24709081231,
|
|
||||||
0x2259d6b14729c0fa,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
impl FpParameters for FqParameters {
|
|
||||||
/// MODULUS = 21888242871839275222246405745257275088696311157297823662689037894645226208583
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const MODULUS: BigInteger = BigInteger([
|
|
||||||
0x3c208c16d87cfd47,
|
|
||||||
0x97816a916871ca8d,
|
|
||||||
0xb85045b68181585d,
|
|
||||||
0x30644e72e131a029,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const MODULUS_BITS: u32 = 254;
|
|
||||||
|
|
||||||
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
|
|
||||||
|
|
||||||
const REPR_SHAVE_BITS: u32 = 2;
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const R: BigInteger = BigInteger([
|
|
||||||
0xd35d438dc58f0d9d,
|
|
||||||
0x0a78eb28f5c70b3d,
|
|
||||||
0x666ea36f7879462c,
|
|
||||||
0xe0a77c19a07df2f,
|
|
||||||
]);
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const R2: BigInteger = BigInteger([
|
|
||||||
0xf32cfc5b538afa89,
|
|
||||||
0xb5e71911d44501fb,
|
|
||||||
0x47ab1eff0a417ff6,
|
|
||||||
0x6d89f71cab8351f,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const INV: u64 = 9786893198990664585u64;
|
|
||||||
|
|
||||||
// GENERATOR = 3
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const GENERATOR: BigInteger = BigInteger([
|
|
||||||
0x7a17caa950ad28d7,
|
|
||||||
0x1f6ac17ae15521b9,
|
|
||||||
0x334bea4e696bd284,
|
|
||||||
0x2a1f6744ce179d8e,
|
|
||||||
]);
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
|
||||||
0x9e10460b6c3e7ea3,
|
|
||||||
0xcbc0b548b438e546,
|
|
||||||
0xdc2822db40c0ac2e,
|
|
||||||
0x183227397098d014,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T
|
|
||||||
|
|
||||||
// T = (MODULUS - 1) // 2^S =
|
|
||||||
// 10944121435919637611123202872628637544348155578648911831344518947322613104291
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const T: BigInteger = BigInteger([
|
|
||||||
0x9e10460b6c3e7ea3,
|
|
||||||
0xcbc0b548b438e546,
|
|
||||||
0xdc2822db40c0ac2e,
|
|
||||||
0x183227397098d014,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// (T - 1) // 2 =
|
|
||||||
// 5472060717959818805561601436314318772174077789324455915672259473661306552145
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
|
||||||
0x4f082305b61f3f51,
|
|
||||||
0x65e05aa45a1c72a3,
|
|
||||||
0x6e14116da0605617,
|
|
||||||
0xc19139cb84c680a,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const FQ_ONE: Fq = field_new!(Fq, "1");
|
|
||||||
pub const FQ_ZERO: Fq = field_new!(Fq, "0");
|
|
||||||
|
|||||||
@@ -1,77 +1,89 @@
|
|||||||
use super::*;
|
use ark_ff::{fields::*, MontFp};
|
||||||
use ark_ff::{field_new, fields::*};
|
|
||||||
|
|
||||||
pub type Fq12 = Fp12<Fq12Parameters>;
|
use crate::*;
|
||||||
|
|
||||||
|
pub type Fq12 = Fp12<Fq12Config>;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Fq12Parameters;
|
pub struct Fq12Config;
|
||||||
|
|
||||||
impl Fp12Parameters for Fq12Parameters {
|
impl Fp12Config for Fq12Config {
|
||||||
type Fp6Params = Fq6Parameters;
|
type Fp6Config = Fq6Config;
|
||||||
|
|
||||||
const NONRESIDUE: Fq6 = field_new!(Fq6, FQ2_ZERO, FQ2_ONE, FQ2_ZERO);
|
const NONRESIDUE: Fq6 = Fq6::new(Fq2::ZERO, Fq2::ONE, Fq2::ZERO);
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[
|
const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[
|
||||||
// Fp2::NONRESIDUE^(((q^0) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^0) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(Fq::ONE, Fq::ZERO),
|
||||||
field_new!(Fq, "1"),
|
|
||||||
field_new!(Fq, "0"),
|
|
||||||
),
|
|
||||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^1) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "8376118865763821496583973867626364092589906065868298776909617916018768340080"),
|
MontFp!("8376118865763821496583973867626364092589906065868298776909617916018768340080"),
|
||||||
field_new!(Fq, "16469823323077808223889137241176536799009286646108169935659301613961712198316"),
|
MontFp!(
|
||||||
|
"16469823323077808223889137241176536799009286646108169935659301613961712198316"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^2) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556617"),
|
MontFp!(
|
||||||
field_new!(Fq, "0"),
|
"21888242871839275220042445260109153167277707414472061641714758635765020556617"
|
||||||
|
),
|
||||||
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^3) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "11697423496358154304825782922584725312912383441159505038794027105778954184319"),
|
MontFp!(
|
||||||
field_new!(Fq, "303847389135065887422783454877609941456349188919719272345083954437860409601"),
|
"11697423496358154304825782922584725312912383441159505038794027105778954184319"
|
||||||
|
),
|
||||||
|
MontFp!("303847389135065887422783454877609941456349188919719272345083954437860409601"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^4) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556616"),
|
MontFp!(
|
||||||
field_new!(Fq, "0"),
|
"21888242871839275220042445260109153167277707414472061641714758635765020556616"
|
||||||
|
),
|
||||||
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^5) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "3321304630594332808241809054958361220322477375291206261884409189760185844239"),
|
MontFp!("3321304630594332808241809054958361220322477375291206261884409189760185844239"),
|
||||||
field_new!(Fq, "5722266937896532885780051958958348231143373700109372999374820235121374419868"),
|
MontFp!("5722266937896532885780051958958348231143373700109372999374820235121374419868"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^6) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^6) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(MontFp!("-1"), Fq::ZERO),
|
||||||
field_new!(Fq, "-1"),
|
|
||||||
field_new!(Fq, "0"),
|
|
||||||
),
|
|
||||||
// Fp2::NONRESIDUE^(((q^7) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^7) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "13512124006075453725662431877630910996106405091429524885779419978626457868503"),
|
MontFp!(
|
||||||
field_new!(Fq, "5418419548761466998357268504080738289687024511189653727029736280683514010267"),
|
"13512124006075453725662431877630910996106405091429524885779419978626457868503"
|
||||||
|
),
|
||||||
|
MontFp!("5418419548761466998357268504080738289687024511189653727029736280683514010267"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^8) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^8) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "2203960485148121921418603742825762020974279258880205651966"),
|
MontFp!("2203960485148121921418603742825762020974279258880205651966"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^9) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^9) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "10190819375481120917420622822672549775783927716138318623895010788866272024264"),
|
MontFp!(
|
||||||
field_new!(Fq, "21584395482704209334823622290379665147239961968378104390343953940207365798982"),
|
"10190819375481120917420622822672549775783927716138318623895010788866272024264"
|
||||||
|
),
|
||||||
|
MontFp!(
|
||||||
|
"21584395482704209334823622290379665147239961968378104390343953940207365798982"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^10) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^10) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "2203960485148121921418603742825762020974279258880205651967"),
|
MontFp!("2203960485148121921418603742825762020974279258880205651967"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^11) - 1) / 6)
|
// Fp2::NONRESIDUE^(((q^11) - 1) / 6)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "18566938241244942414004596690298913868373833782006617400804628704885040364344"),
|
MontFp!(
|
||||||
field_new!(Fq, "16165975933942742336466353786298926857552937457188450663314217659523851788715"),
|
"18566938241244942414004596690298913868373833782006617400804628704885040364344"
|
||||||
|
),
|
||||||
|
MontFp!(
|
||||||
|
"16165975933942742336466353786298926857552937457188450663314217659523851788715"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,27 @@
|
|||||||
use super::*;
|
use ark_ff::{fields::*, MontFp};
|
||||||
use ark_ff::{field_new, fields::*};
|
|
||||||
|
|
||||||
pub type Fq2 = Fp2<Fq2Parameters>;
|
use crate::*;
|
||||||
|
|
||||||
pub struct Fq2Parameters;
|
pub type Fq2 = Fp2<Fq2Config>;
|
||||||
|
|
||||||
impl Fp2Parameters for Fq2Parameters {
|
pub struct Fq2Config;
|
||||||
|
|
||||||
|
impl Fp2Config for Fq2Config {
|
||||||
type Fp = Fq;
|
type Fp = Fq;
|
||||||
|
|
||||||
/// NONRESIDUE = -1
|
/// NONRESIDUE = -1
|
||||||
#[rustfmt::skip]
|
const NONRESIDUE: Fq = MontFp!("-1");
|
||||||
const NONRESIDUE: Fq = field_new!(Fq, "-1");
|
|
||||||
|
|
||||||
/// QUADRATIC_NONRESIDUE = U+2
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const QUADRATIC_NONRESIDUE: (Fq, Fq) = (
|
|
||||||
field_new!(Fq, "2"),
|
|
||||||
field_new!(Fq, "1"),
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Coefficients for the Frobenius automorphism.
|
/// Coefficients for the Frobenius automorphism.
|
||||||
#[rustfmt::skip]
|
|
||||||
const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[
|
const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[
|
||||||
// NONRESIDUE**(((q^0) - 1) / 2)
|
// NONRESIDUE**(((q^0) - 1) / 2)
|
||||||
field_new!(Fq, "1"),
|
Fq::ONE,
|
||||||
// NONRESIDUE**(((q^1) - 1) / 2)
|
// NONRESIDUE**(((q^1) - 1) / 2)
|
||||||
field_new!(Fq, "-1"),
|
MontFp!("-1"),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO);
|
|
||||||
pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO);
|
|
||||||
|
|||||||
@@ -1,92 +1,105 @@
|
|||||||
use super::*;
|
use ark_ff::{fields::*, MontFp};
|
||||||
use ark_ff::{field_new, fields::*};
|
|
||||||
|
|
||||||
pub type Fq6 = Fp6<Fq6Parameters>;
|
use crate::*;
|
||||||
|
|
||||||
|
pub type Fq6 = Fp6<Fq6Config>;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Fq6Parameters;
|
pub struct Fq6Config;
|
||||||
|
|
||||||
impl Fp6Parameters for Fq6Parameters {
|
impl Fp6Config for Fq6Config {
|
||||||
type Fp2Params = Fq2Parameters;
|
type Fp2Config = Fq2Config;
|
||||||
|
|
||||||
/// NONRESIDUE = U+9
|
/// NONRESIDUE = U+9
|
||||||
#[rustfmt::skip]
|
const NONRESIDUE: Fq2 = Fq2::new(MontFp!("9"), Fq::ONE);
|
||||||
const NONRESIDUE: Fq2 = field_new!(Fq2, field_new!(Fq, "9"), field_new!(Fq, "1"));
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[
|
const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[
|
||||||
// Fp2::NONRESIDUE^(((q^0) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^0) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(Fq::ONE, Fq::ZERO),
|
||||||
field_new!(Fq, "1"),
|
|
||||||
field_new!(Fq, "0"),
|
|
||||||
),
|
|
||||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^1) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "21575463638280843010398324269430826099269044274347216827212613867836435027261"),
|
MontFp!(
|
||||||
field_new!(Fq, "10307601595873709700152284273816112264069230130616436755625194854815875713954"),
|
"21575463638280843010398324269430826099269044274347216827212613867836435027261"
|
||||||
|
),
|
||||||
|
MontFp!(
|
||||||
|
"10307601595873709700152284273816112264069230130616436755625194854815875713954"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^2) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556616"),
|
MontFp!(
|
||||||
field_new!(Fq, "0"),
|
"21888242871839275220042445260109153167277707414472061641714758635765020556616"
|
||||||
|
),
|
||||||
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^3) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "3772000881919853776433695186713858239009073593817195771773381919316419345261"),
|
MontFp!("3772000881919853776433695186713858239009073593817195771773381919316419345261"),
|
||||||
field_new!(Fq, "2236595495967245188281701248203181795121068902605861227855261137820944008926"),
|
MontFp!("2236595495967245188281701248203181795121068902605861227855261137820944008926"),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^4) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "2203960485148121921418603742825762020974279258880205651966"),
|
MontFp!("2203960485148121921418603742825762020974279258880205651966"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 3)
|
// Fp2::NONRESIDUE^(((q^5) - 1) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "18429021223477853657660792034369865839114504446431234726392080002137598044644"),
|
MontFp!(
|
||||||
field_new!(Fq, "9344045779998320333812420223237981029506012124075525679208581902008406485703"),
|
"18429021223477853657660792034369865839114504446431234726392080002137598044644"
|
||||||
|
),
|
||||||
|
MontFp!("9344045779998320333812420223237981029506012124075525679208581902008406485703"),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
#[rustfmt::skip]
|
|
||||||
const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[
|
const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[
|
||||||
// Fp2::NONRESIDUE^((2*(q^0) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^0) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(Fq::ONE, Fq::ZERO),
|
||||||
field_new!(Fq, "1"),
|
|
||||||
field_new!(Fq, "0"),
|
|
||||||
),
|
|
||||||
// Fp2::NONRESIDUE^((2*(q^1) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^1) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "2581911344467009335267311115468803099551665605076196740867805258568234346338"),
|
MontFp!("2581911344467009335267311115468803099551665605076196740867805258568234346338"),
|
||||||
field_new!(Fq, "19937756971775647987995932169929341994314640652964949448313374472400716661030"),
|
MontFp!(
|
||||||
|
"19937756971775647987995932169929341994314640652964949448313374472400716661030"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^2) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^2) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "2203960485148121921418603742825762020974279258880205651966"),
|
MontFp!("2203960485148121921418603742825762020974279258880205651966"),
|
||||||
field_new!(Fq, "0"),
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^3) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^3) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "5324479202449903542726783395506214481928257762400643279780343368557297135718"),
|
MontFp!("5324479202449903542726783395506214481928257762400643279780343368557297135718"),
|
||||||
field_new!(Fq, "16208900380737693084919495127334387981393726419856888799917914180988844123039"),
|
MontFp!(
|
||||||
|
"16208900380737693084919495127334387981393726419856888799917914180988844123039"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^4) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^4) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556616"),
|
MontFp!(
|
||||||
field_new!(Fq, "0"),
|
"21888242871839275220042445260109153167277707414472061641714758635765020556616"
|
||||||
|
),
|
||||||
|
Fq::ZERO,
|
||||||
),
|
),
|
||||||
// Fp2::NONRESIDUE^((2*(q^5) - 2) / 3)
|
// Fp2::NONRESIDUE^((2*(q^5) - 2) / 3)
|
||||||
field_new!(Fq2,
|
Fq2::new(
|
||||||
field_new!(Fq, "13981852324922362344252311234282257507216387789820983642040889267519694726527"),
|
MontFp!(
|
||||||
field_new!(Fq, "7629828391165209371577384193250820201684255241773809077146787135900891633097"),
|
"13981852324922362344252311234282257507216387789820983642040889267519694726527"
|
||||||
|
),
|
||||||
|
MontFp!("7629828391165209371577384193250820201684255241773809077146787135900891633097"),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[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 + Fq2Parameters::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;
|
||||||
field_new!(Fq2, c0, c1)
|
*fe = Fq2::new(c0, c1);
|
||||||
|
fe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,100 +1,9 @@
|
|||||||
use ark_ff::{biginteger::BigInteger256 as BigInteger, fields::*};
|
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
|
||||||
|
|
||||||
pub type Fr = Fp256<FrParameters>;
|
#[derive(MontConfig)]
|
||||||
|
#[modulus = "21888242871839275222246405745257275088548364400416034343698204186575808495617"]
|
||||||
pub struct FrParameters;
|
#[generator = "5"]
|
||||||
|
#[small_subgroup_base = "3"]
|
||||||
impl Fp256Parameters for FrParameters {}
|
#[small_subgroup_power = "2"]
|
||||||
impl FftParameters for FrParameters {
|
pub struct FrConfig;
|
||||||
type BigInt = BigInteger;
|
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;
|
||||||
|
|
||||||
const TWO_ADICITY: u32 = 28;
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
|
||||||
7164790868263648668u64,
|
|
||||||
11685701338293206998u64,
|
|
||||||
6216421865291908056u64,
|
|
||||||
1756667274303109607u64,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
impl FpParameters for FrParameters {
|
|
||||||
/// MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const MODULUS: BigInteger = BigInteger([
|
|
||||||
4891460686036598785u64,
|
|
||||||
2896914383306846353u64,
|
|
||||||
13281191951274694749u64,
|
|
||||||
3486998266802970665u64,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const MODULUS_BITS: u32 = 254;
|
|
||||||
|
|
||||||
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
|
|
||||||
|
|
||||||
const REPR_SHAVE_BITS: u32 = 2;
|
|
||||||
|
|
||||||
/// R = pow(2, 320) % MODULUS
|
|
||||||
/// = 6350874878119819312338956282401532410528162663560392320966563075034087161851
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const R: BigInteger = BigInteger([
|
|
||||||
12436184717236109307u64,
|
|
||||||
3962172157175319849u64,
|
|
||||||
7381016538464732718u64,
|
|
||||||
1011752739694698287u64,
|
|
||||||
]);
|
|
||||||
|
|
||||||
/// R2 = R * R % MODULUS
|
|
||||||
/// = 944936681149208446651664254269745548490766851729442924617792859073125903783
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const R2: BigInteger = BigInteger([
|
|
||||||
1997599621687373223u64,
|
|
||||||
6052339484930628067u64,
|
|
||||||
10108755138030829701u64,
|
|
||||||
150537098327114917u64,
|
|
||||||
]);
|
|
||||||
|
|
||||||
/// INV = (-MODULUS) ^ {-1} % pow(2, 64) = 14042775128853446655
|
|
||||||
const INV: u64 = 14042775128853446655u64;
|
|
||||||
|
|
||||||
/// GENERATOR = 5
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const GENERATOR: BigInteger = BigInteger([
|
|
||||||
1949230679015292902u64,
|
|
||||||
16913946402569752895u64,
|
|
||||||
5177146667339417225u64,
|
|
||||||
1571765431670520771u64,
|
|
||||||
]);
|
|
||||||
|
|
||||||
/// (MODULUS - 1)/2 =
|
|
||||||
/// 10944121435919637611123202872628637544274182200208017171849102093287904247808
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
|
||||||
0xa1f0fac9f8000000,
|
|
||||||
0x9419f4243cdcb848,
|
|
||||||
0xdc2822db40c0ac2e,
|
|
||||||
0x183227397098d014,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// T and T_MINUS_ONE_DIV_TWO, where r - 1 = 2^s * t
|
|
||||||
|
|
||||||
/// T = (MODULUS - 1) / 2^s =
|
|
||||||
/// 81540058820840996586704275553141814055101440848469862132140264610111
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const T: BigInteger = BigInteger([
|
|
||||||
0x9b9709143e1f593f,
|
|
||||||
0x181585d2833e8487,
|
|
||||||
0x131a029b85045b68,
|
|
||||||
0x30644e72e,
|
|
||||||
]);
|
|
||||||
|
|
||||||
/// (T - 1) / 2 =
|
|
||||||
/// 40770029410420498293352137776570907027550720424234931066070132305055
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
|
||||||
0xcdcb848a1f0fac9f,
|
|
||||||
0x0c0ac2e9419f4243,
|
|
||||||
0x098d014dc2822db4,
|
|
||||||
0x183227397,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,123 +1,51 @@
|
|||||||
|
use ark_algebra_test_templates::*;
|
||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
biginteger::{BigInteger, BigInteger256},
|
biginteger::{BigInt, BigInteger, BigInteger256},
|
||||||
fields::{
|
fields::{FftField, Field, Fp6Config, PrimeField},
|
||||||
fp6_3over2::Fp6Parameters, FftField, FftParameters, Field, FpParameters, PrimeField,
|
|
||||||
SquareRootField,
|
|
||||||
},
|
|
||||||
One, UniformRand, Zero,
|
One, UniformRand, Zero,
|
||||||
};
|
};
|
||||||
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
use ark_std::{
|
||||||
use ark_std::rand::Rng;
|
|
||||||
use ark_std::test_rng;
|
|
||||||
use core::{
|
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
ops::{AddAssign, MulAssign, SubAssign},
|
ops::{AddAssign, MulAssign},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Parameters, FqParameters, Fr};
|
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Config, Fr};
|
||||||
use ark_algebra_test_templates::fields::*;
|
|
||||||
|
|
||||||
pub(crate) const ITERATIONS: usize = 5;
|
test_field!(fr; Fr; mont_prime_field);
|
||||||
|
test_field!(fq; Fq; mont_prime_field);
|
||||||
#[test]
|
test_field!(fq2; Fq2);
|
||||||
fn test_fr() {
|
test_field!(fq6; Fq6);
|
||||||
let mut rng = test_rng();
|
test_field!(fq12; Fq12);
|
||||||
for _ in 0..ITERATIONS {
|
|
||||||
let a: Fr = rng.gen();
|
|
||||||
let b: Fr = rng.gen();
|
|
||||||
field_test(a, b);
|
|
||||||
primefield_test::<Fr>();
|
|
||||||
sqrt_field_test(b);
|
|
||||||
let byte_size = a.serialized_size();
|
|
||||||
field_serialization_test::<Fr>(byte_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
for _ in 0..ITERATIONS {
|
|
||||||
let a: Fq = rng.gen();
|
|
||||||
let b: Fq = rng.gen();
|
|
||||||
field_test(a, b);
|
|
||||||
primefield_test::<Fq>();
|
|
||||||
sqrt_field_test(a);
|
|
||||||
let byte_size = a.serialized_size();
|
|
||||||
let (_, buffer_size) = buffer_bit_byte_size(Fq::size_in_bits());
|
|
||||||
assert_eq!(byte_size, buffer_size);
|
|
||||||
field_serialization_test::<Fq>(byte_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq2() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
for _ in 0..ITERATIONS {
|
|
||||||
let a: Fq2 = rng.gen();
|
|
||||||
let b: Fq2 = rng.gen();
|
|
||||||
field_test(a, b);
|
|
||||||
sqrt_field_test(a);
|
|
||||||
}
|
|
||||||
frobenius_test::<Fq2, _>(Fq::characteristic(), 13);
|
|
||||||
let byte_size = Fq2::zero().serialized_size();
|
|
||||||
field_serialization_test::<Fq2>(byte_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq6() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
for _ in 0..ITERATIONS {
|
|
||||||
let g: Fq6 = rng.gen();
|
|
||||||
let h: Fq6 = rng.gen();
|
|
||||||
field_test(g, h);
|
|
||||||
}
|
|
||||||
frobenius_test::<Fq6, _>(Fq::characteristic(), 13);
|
|
||||||
let byte_size = Fq6::zero().serialized_size();
|
|
||||||
field_serialization_test::<Fq6>(byte_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq12() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
for _ in 0..ITERATIONS {
|
|
||||||
let g: Fq12 = rng.gen();
|
|
||||||
let h: Fq12 = rng.gen();
|
|
||||||
field_test(g, h);
|
|
||||||
}
|
|
||||||
frobenius_test::<Fq12, _>(Fq::characteristic(), 13);
|
|
||||||
let byte_size = Fq12::zero().serialized_size();
|
|
||||||
field_serialization_test::<Fq12>(byte_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_from() {
|
fn test_fq_repr_from() {
|
||||||
assert_eq!(BigInteger256::from(100), BigInteger256([100, 0, 0, 0]));
|
assert_eq!(BigInteger256::from(100u64), BigInt::new([100, 0, 0, 0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_is_odd() {
|
fn test_fq_repr_is_odd() {
|
||||||
assert!(!BigInteger256::from(0).is_odd());
|
assert!(!BigInteger256::from(0u64).is_odd());
|
||||||
assert!(BigInteger256::from(0).is_even());
|
assert!(BigInteger256::from(0u64).is_even());
|
||||||
assert!(BigInteger256::from(1).is_odd());
|
assert!(BigInteger256::from(1u64).is_odd());
|
||||||
assert!(!BigInteger256::from(1).is_even());
|
assert!(!BigInteger256::from(1u64).is_even());
|
||||||
assert!(!BigInteger256::from(324834872).is_odd());
|
assert!(!BigInteger256::from(324834872u64).is_odd());
|
||||||
assert!(BigInteger256::from(324834872).is_even());
|
assert!(BigInteger256::from(324834872u64).is_even());
|
||||||
assert!(BigInteger256::from(324834873).is_odd());
|
assert!(BigInteger256::from(324834873u64).is_odd());
|
||||||
assert!(!BigInteger256::from(324834873).is_even());
|
assert!(!BigInteger256::from(324834873u64).is_even());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_is_zero() {
|
fn test_fq_repr_is_zero() {
|
||||||
assert!(BigInteger256::from(0).is_zero());
|
assert!(BigInteger256::from(0u64).is_zero());
|
||||||
assert!(!BigInteger256::from(1).is_zero());
|
assert!(!BigInteger256::from(1u64).is_zero());
|
||||||
assert!(!BigInteger256([0, 0, 1, 0]).is_zero());
|
assert!(!BigInt::new([0, 0, 1, 0]).is_zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_num_bits() {
|
fn test_fq_repr_num_bits() {
|
||||||
let mut a = BigInteger256::from(0);
|
let mut a = BigInteger256::from(0u64);
|
||||||
assert_eq!(0, a.num_bits());
|
assert_eq!(0, a.num_bits());
|
||||||
a = BigInteger256::from(1);
|
a = BigInteger256::from(1u64);
|
||||||
for i in 1..257 {
|
for i in 1..257 {
|
||||||
assert_eq!(i, a.num_bits());
|
assert_eq!(i, a.num_bits());
|
||||||
a.mul2();
|
a.mul2();
|
||||||
@@ -125,248 +53,35 @@ fn test_fq_repr_num_bits() {
|
|||||||
assert_eq!(0, a.num_bits());
|
assert_eq!(0, a.num_bits());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_add_assign() {
|
|
||||||
// Test associativity
|
|
||||||
|
|
||||||
let mut rng = ark_std::test_rng();
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Generate a, b, c and ensure (a + b) + c == a + (b + c).
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
let b = Fq::rand(&mut rng);
|
|
||||||
let c = Fq::rand(&mut rng);
|
|
||||||
|
|
||||||
let mut tmp1 = a;
|
|
||||||
tmp1.add_assign(&b);
|
|
||||||
tmp1.add_assign(&c);
|
|
||||||
|
|
||||||
let mut tmp2 = b;
|
|
||||||
tmp2.add_assign(&c);
|
|
||||||
tmp2.add_assign(&a);
|
|
||||||
|
|
||||||
assert_eq!(tmp1, tmp2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_sub_assign() {
|
|
||||||
let mut rng = ark_std::test_rng();
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Ensure that (a - b) + (b - a) = 0.
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
let b = Fq::rand(&mut rng);
|
|
||||||
|
|
||||||
let mut tmp1 = a;
|
|
||||||
tmp1.sub_assign(&b);
|
|
||||||
|
|
||||||
let mut tmp2 = b;
|
|
||||||
tmp2.sub_assign(&a);
|
|
||||||
|
|
||||||
tmp1.add_assign(&tmp2);
|
|
||||||
assert!(tmp1.is_zero());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_mul_assign() {
|
|
||||||
let mut rng = ark_std::test_rng();
|
|
||||||
|
|
||||||
for _ in 0..1000000 {
|
|
||||||
// Ensure that (a * b) * c = a * (b * c)
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
let b = Fq::rand(&mut rng);
|
|
||||||
let c = Fq::rand(&mut rng);
|
|
||||||
|
|
||||||
let mut tmp1 = a;
|
|
||||||
tmp1.mul_assign(&b);
|
|
||||||
tmp1.mul_assign(&c);
|
|
||||||
|
|
||||||
let mut tmp2 = b;
|
|
||||||
tmp2.mul_assign(&c);
|
|
||||||
tmp2.mul_assign(&a);
|
|
||||||
|
|
||||||
assert_eq!(tmp1, tmp2);
|
|
||||||
}
|
|
||||||
|
|
||||||
for _ in 0..1000000 {
|
|
||||||
// Ensure that r * (a + b + c) = r*a + r*b + r*c
|
|
||||||
|
|
||||||
let r = Fq::rand(&mut rng);
|
|
||||||
let mut a = Fq::rand(&mut rng);
|
|
||||||
let mut b = Fq::rand(&mut rng);
|
|
||||||
let mut c = Fq::rand(&mut rng);
|
|
||||||
|
|
||||||
let mut tmp1 = a;
|
|
||||||
tmp1.add_assign(&b);
|
|
||||||
tmp1.add_assign(&c);
|
|
||||||
tmp1.mul_assign(&r);
|
|
||||||
|
|
||||||
a.mul_assign(&r);
|
|
||||||
b.mul_assign(&r);
|
|
||||||
c.mul_assign(&r);
|
|
||||||
|
|
||||||
a.add_assign(&b);
|
|
||||||
a.add_assign(&c);
|
|
||||||
|
|
||||||
assert_eq!(tmp1, a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_squaring() {
|
|
||||||
let mut rng = ark_std::test_rng();
|
|
||||||
|
|
||||||
for _ in 0..1000000 {
|
|
||||||
// Ensure that (a * a) = a^2
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
|
|
||||||
let mut tmp = a;
|
|
||||||
tmp.square_in_place();
|
|
||||||
|
|
||||||
let mut tmp2 = a;
|
|
||||||
tmp2.mul_assign(&a);
|
|
||||||
|
|
||||||
assert_eq!(tmp, tmp2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_inverse() {
|
|
||||||
assert!(Fq::zero().inverse().is_none());
|
|
||||||
|
|
||||||
let mut rng = ark_std::test_rng();
|
|
||||||
|
|
||||||
let one = Fq::one();
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Ensure that a * a^-1 = 1
|
|
||||||
let mut a = Fq::rand(&mut rng);
|
|
||||||
let ainv = a.inverse().unwrap();
|
|
||||||
a.mul_assign(&ainv);
|
|
||||||
assert_eq!(a, one);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_double_in_place() {
|
|
||||||
let mut rng = ark_std::test_rng();
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Ensure doubling a is equivalent to adding a to itself.
|
|
||||||
let mut a = Fq::rand(&mut rng);
|
|
||||||
let mut b = a;
|
|
||||||
b.add_assign(&a);
|
|
||||||
a.double_in_place();
|
|
||||||
assert_eq!(a, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_negate() {
|
|
||||||
{
|
|
||||||
let a = -Fq::zero();
|
|
||||||
|
|
||||||
assert!(a.is_zero());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut rng = ark_std::test_rng();
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Ensure (a - (-a)) = 0.
|
|
||||||
let mut a = Fq::rand(&mut rng);
|
|
||||||
let b = -a;
|
|
||||||
a.add_assign(&b);
|
|
||||||
|
|
||||||
assert!(a.is_zero());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_pow() {
|
|
||||||
let mut rng = ark_std::test_rng();
|
|
||||||
|
|
||||||
for i in 0..1000 {
|
|
||||||
// Exponentiate by various small numbers and ensure it consists with repeated
|
|
||||||
// multiplication.
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
let target = a.pow(&[i]);
|
|
||||||
let mut c = Fq::one();
|
|
||||||
for _ in 0..i {
|
|
||||||
c.mul_assign(&a);
|
|
||||||
}
|
|
||||||
assert_eq!(c, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Exponentiating by the modulus should have no effect in a prime field.
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
|
|
||||||
assert_eq!(a, a.pow(Fq::characteristic()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq_sqrt() {
|
|
||||||
let mut rng = ark_std::test_rng();
|
|
||||||
|
|
||||||
assert_eq!(Fq::zero().sqrt().unwrap(), Fq::zero());
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Ensure sqrt(a^2) = a or -a
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
let nega = -a;
|
|
||||||
let mut b = a;
|
|
||||||
b.square_in_place();
|
|
||||||
|
|
||||||
let b = b.sqrt().unwrap();
|
|
||||||
|
|
||||||
assert!(a == b || nega == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
for _ in 0..1000 {
|
|
||||||
// Ensure sqrt(a)^2 = a for random a
|
|
||||||
let a = Fq::rand(&mut rng);
|
|
||||||
|
|
||||||
if let Some(mut tmp) = a.sqrt() {
|
|
||||||
tmp.square_in_place();
|
|
||||||
|
|
||||||
assert_eq!(a, tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_num_bits() {
|
fn test_fq_num_bits() {
|
||||||
assert_eq!(FqParameters::MODULUS_BITS, 254);
|
assert_eq!(Fq::MODULUS_BIT_SIZE, 254);
|
||||||
assert_eq!(FqParameters::CAPACITY, 253);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_root_of_unity() {
|
fn test_fq_root_of_unity() {
|
||||||
assert_eq!(FqParameters::TWO_ADICITY, 1);
|
assert_eq!(Fq::TWO_ADICITY, 1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Fq::multiplicative_generator().pow([
|
Fq::GENERATOR.pow([
|
||||||
0x9e10460b6c3e7ea3,
|
0x9e10460b6c3e7ea3,
|
||||||
0xcbc0b548b438e546,
|
0xcbc0b548b438e546,
|
||||||
0xdc2822db40c0ac2e,
|
0xdc2822db40c0ac2e,
|
||||||
0x183227397098d014,
|
0x183227397098d014,
|
||||||
]),
|
]),
|
||||||
Fq::two_adic_root_of_unity()
|
Fq::TWO_ADIC_ROOT_OF_UNITY
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]),
|
Fq::TWO_ADIC_ROOT_OF_UNITY.pow([1 << Fq::TWO_ADICITY]),
|
||||||
Fq::one()
|
Fq::one()
|
||||||
);
|
);
|
||||||
assert!(Fq::multiplicative_generator().sqrt().is_none());
|
assert!(Fq::GENERATOR.sqrt().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_ordering() {
|
fn test_fq_ordering() {
|
||||||
// BigInteger256's ordering is well-tested, but we still need to make sure the
|
// BigInteger256's ordering is well-tested, but we still need to make sure the
|
||||||
// Fq elements aren't being compared in Montgomery form.
|
// Fq elements aren't being compared in Montgomery form.
|
||||||
for i in 0..100 {
|
for i in 0..100u64 {
|
||||||
assert!(Fq::from(BigInteger256::from(i + 1)) > Fq::from(BigInteger256::from(i)));
|
assert!(Fq::from(BigInteger256::from(i + 1)) > Fq::from(BigInteger256::from(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,11 +94,11 @@ fn test_fq_legendre() {
|
|||||||
assert_eq!(Zero, Fq::zero().legendre());
|
assert_eq!(Zero, Fq::zero().legendre());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
QuadraticResidue,
|
QuadraticResidue,
|
||||||
Fq::from(BigInteger256::from(4)).legendre()
|
Fq::from(BigInteger256::from(4u64)).legendre()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
QuadraticNonResidue,
|
QuadraticNonResidue,
|
||||||
Fq::from(BigInteger256::from(5)).legendre()
|
Fq::from(BigInteger256::from(5u64)).legendre()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,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 = Fq6Parameters::mul_fp2_by_nonresidue(&m1);
|
Fq6Config::mul_fp2_by_nonresidue_in_place(&mut m1);
|
||||||
assert_eq!(QuadraticNonResidue, m1.legendre());
|
assert_eq!(QuadraticNonResidue, m1.legendre());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
bn254/src/lib.rs
Normal file → Executable file
11
bn254/src/lib.rs
Normal file → Executable file
@@ -20,14 +20,17 @@
|
|||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//! Curve information:
|
//! Curve information:
|
||||||
//! * Base field: q = 21888242871839275222246405745257275088696311157297823662689037894645226208583
|
//! * Base field: q =
|
||||||
//! * Scalar field: r = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
//! 21888242871839275222246405745257275088696311157297823662689037894645226208583
|
||||||
|
//! * Scalar field: r =
|
||||||
|
//! 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||||
//! * valuation(q - 1, 2) = 1
|
//! * valuation(q - 1, 2) = 1
|
||||||
//! * valuation(r - 1, 2) = 28
|
//! * valuation(r - 1, 2) = 28
|
||||||
//! * G1 curve equation: y^2 = x^3 + 3
|
//! * G1 curve equation: y^2 = x^3 + 3
|
||||||
//! * G2 curve equation: y^2 = x^3 + B, where
|
//! * G2 curve equation: y^2 = x^3 + B, where
|
||||||
//! * B = 3/(u+9) where Fq2 is represented as Fq\[u\]/(u^2+1)
|
//! * B = 3/(u+9) where Fq2 is represented as Fq\[u\]/(u^2+1) =
|
||||||
//! = Fq2(19485874751759354771024239261021720505790618469301721065564631296452457478373, 266929791119991161246907387137283842545076965332900288569378510910307636690)
|
//! Fq2(19485874751759354771024239261021720505790618469301721065564631296452457478373,
|
||||||
|
//! 266929791119991161246907387137283842545076965332900288569378510910307636690)
|
||||||
|
|
||||||
#[cfg(feature = "curve")]
|
#[cfg(feature = "curve")]
|
||||||
mod curves;
|
mod curves;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ark-bw6-761"
|
name = "ark-bw6-761"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
authors = [ "arkworks contributors" ]
|
authors = [ "arkworks contributors" ]
|
||||||
description = "The BW6-761 pairing-friendly elliptic curve"
|
description = "The BW6-761 pairing-friendly elliptic curve"
|
||||||
homepage = "https://arkworks.rs"
|
homepage = "https://arkworks.rs"
|
||||||
@@ -10,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", default-features = false }
|
||||||
ark-ec = { version="^0.3.0", default-features = false }
|
ark-ec = { version= "0.4.0", default-features = false }
|
||||||
ark-std = { version="^0.3.0", default-features = false }
|
ark-std = { version = "0.4.0", 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", 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", default-features = false }
|
||||||
ark-algebra-test-templates = { version="^0.3.0", default-features = false }
|
ark-algebra-test-templates = { version = "0.4.0", default-features = false }
|
||||||
|
ark-algebra-bench-templates = { version = "0.4.0", default-features = false }
|
||||||
|
|
||||||
[features]
|
[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,
|
||||||
|
);
|
||||||
28
bw6_761/scripts/base_field.sage
Normal file
28
bw6_761/scripts/base_field.sage
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
modulus = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299
|
||||||
|
|
||||||
|
assert(modulus.is_prime())
|
||||||
|
|
||||||
|
Fp = GF(modulus)
|
||||||
|
|
||||||
|
generator = Fp(0);
|
||||||
|
for i in range(0, 20):
|
||||||
|
i = Fp(i);
|
||||||
|
neg_i = Fp(-i)
|
||||||
|
if not(i.is_primitive_root() or neg_i.is_primitive_root()):
|
||||||
|
continue
|
||||||
|
elif i.is_primitive_root():
|
||||||
|
assert(i.is_primitive_root());
|
||||||
|
print("Generator: %d" % i)
|
||||||
|
generator = i
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
assert(neg_i.is_primitive_root());
|
||||||
|
print("Generator: %d" % neg_i)
|
||||||
|
generator = neg_i
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
two_adicity = valuation(modulus - 1, 2);
|
||||||
|
trace = (modulus - 1) / 2**two_adicity;
|
||||||
|
two_adic_root_of_unity = generator^trace
|
||||||
|
print("2-adic Root of Unity: %d " % two_adic_root_of_unity)
|
||||||
28
bw6_761/scripts/scalar_field.sage
Normal file
28
bw6_761/scripts/scalar_field.sage
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
modulus = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
|
||||||
|
|
||||||
|
assert(modulus.is_prime())
|
||||||
|
|
||||||
|
Fp = GF(modulus)
|
||||||
|
|
||||||
|
generator = Fp(0);
|
||||||
|
for i in range(0, 20):
|
||||||
|
i = Fp(i);
|
||||||
|
neg_i = Fp(-i)
|
||||||
|
if not(i.is_primitive_root() or neg_i.is_primitive_root()):
|
||||||
|
continue
|
||||||
|
elif i.is_primitive_root():
|
||||||
|
assert(i.is_primitive_root());
|
||||||
|
print("Generator: %d" % i)
|
||||||
|
generator = i
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
assert(neg_i.is_primitive_root());
|
||||||
|
print("Generator: %d" % neg_i)
|
||||||
|
generator = neg_i
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
two_adicity = valuation(modulus - 1, 2);
|
||||||
|
trace = (modulus - 1) / 2**two_adicity;
|
||||||
|
two_adic_root_of_unity = generator^trace
|
||||||
|
print("2-adic Root of Unity: %d " % two_adic_root_of_unity)
|
||||||
@@ -1,30 +1,21 @@
|
|||||||
use crate::{Fq, Fr};
|
|
||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
models::{ModelParameters, SWModelParameters},
|
models::{short_weierstrass::SWCurveConfig, CurveConfig},
|
||||||
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
|
scalar_mul::glv::GLVConfig,
|
||||||
|
short_weierstrass::{Affine, Projective},
|
||||||
};
|
};
|
||||||
use ark_ff::field_new;
|
use ark_ff::{AdditiveGroup, BigInt, MontFp, PrimeField};
|
||||||
|
|
||||||
pub type G1Affine = GroupAffine<Parameters>;
|
use crate::{Fq, Fr};
|
||||||
pub type G1Projective = GroupProjective<Parameters>;
|
|
||||||
|
pub type G1Affine = Affine<Config>;
|
||||||
|
pub type G1Projective = Projective<Config>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl ModelParameters for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
}
|
|
||||||
|
|
||||||
impl SWModelParameters for Parameters {
|
|
||||||
/// COEFF_A = 0
|
|
||||||
#[rustfmt::skip]
|
|
||||||
|
|
||||||
const COEFF_A: Fq = field_new!(Fq, "0");
|
|
||||||
|
|
||||||
/// COEFF_B = -1
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const COEFF_B: Fq = field_new!(Fq, "-1");
|
|
||||||
|
|
||||||
/// COFACTOR =
|
/// COFACTOR =
|
||||||
/// 26642435879335816683987677701488073867751118270052650655942102502312977592501693353047140953112195348280268661194876
|
/// 26642435879335816683987677701488073867751118270052650655942102502312977592501693353047140953112195348280268661194876
|
||||||
@@ -40,25 +31,69 @@ impl SWModelParameters for Parameters {
|
|||||||
|
|
||||||
/// COFACTOR^(-1) mod r =
|
/// COFACTOR^(-1) mod r =
|
||||||
/// 91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804
|
/// 91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804
|
||||||
#[rustfmt::skip]
|
const COFACTOR_INV: Fr = MontFp!("91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804");
|
||||||
const COFACTOR_INV: Fr = field_new!(Fr, "91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804");
|
}
|
||||||
|
|
||||||
|
impl SWCurveConfig for Config {
|
||||||
|
/// COEFF_A = 0
|
||||||
|
const COEFF_A: Fq = Fq::ZERO;
|
||||||
|
|
||||||
|
/// COEFF_B = -1
|
||||||
|
const COEFF_B: Fq = MontFp!("-1");
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||||
(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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GLVConfig for Config {
|
||||||
|
const ENDO_COEFFS: &'static [Self::BaseField] = &[MontFp!(
|
||||||
|
"4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"
|
||||||
|
)];
|
||||||
|
|
||||||
|
const LAMBDA: Self::ScalarField =
|
||||||
|
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231");
|
||||||
|
|
||||||
|
const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
|
||||||
|
(
|
||||||
|
true,
|
||||||
|
BigInt!("293634935485640680722085584138834120324914961969255022593"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
false,
|
||||||
|
BigInt!("293634935485640680722085584138834120315328839056164388863"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
true,
|
||||||
|
BigInt!("293634935485640680722085584138834120315328839056164388863"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
true,
|
||||||
|
BigInt!("587269870971281361444171168277668240640243801025419411456"),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
fn endomorphism(p: &Projective<Self>) -> Projective<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn endomorphism_affine(p: &Affine<Self>) -> Affine<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// G1_GENERATOR_X =
|
/// G1_GENERATOR_X =
|
||||||
/// 6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237
|
/// 6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237
|
||||||
#[rustfmt::skip]
|
pub const G1_GENERATOR_X: Fq = MontFp!("6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237");
|
||||||
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237");
|
|
||||||
|
|
||||||
/// G1_GENERATOR_Y =
|
/// G1_GENERATOR_Y =
|
||||||
/// 2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099
|
/// 2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099
|
||||||
#[rustfmt::skip]
|
pub const G1_GENERATOR_Y: Fq = MontFp!("2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099");
|
||||||
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099");
|
|
||||||
|
|||||||
@@ -1,30 +1,21 @@
|
|||||||
use crate::{Fq, Fr};
|
|
||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
models::{ModelParameters, SWModelParameters},
|
models::{short_weierstrass::SWCurveConfig, CurveConfig},
|
||||||
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
|
scalar_mul::glv::GLVConfig,
|
||||||
|
short_weierstrass::{Affine, Projective},
|
||||||
};
|
};
|
||||||
use ark_ff::field_new;
|
use ark_ff::{AdditiveGroup, BigInt, MontFp, PrimeField};
|
||||||
|
|
||||||
pub type G2Affine = GroupAffine<Parameters>;
|
use crate::{Fq, Fr};
|
||||||
pub type G2Projective = GroupProjective<Parameters>;
|
|
||||||
|
pub type G2Affine = Affine<Config>;
|
||||||
|
pub type G2Projective = Projective<Config>;
|
||||||
|
|
||||||
#[derive(Clone, Default, PartialEq, Eq)]
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Parameters;
|
pub struct Config;
|
||||||
|
|
||||||
impl ModelParameters for Parameters {
|
impl CurveConfig for Config {
|
||||||
type BaseField = Fq;
|
type BaseField = Fq;
|
||||||
type ScalarField = Fr;
|
type ScalarField = Fr;
|
||||||
}
|
|
||||||
|
|
||||||
impl SWModelParameters for Parameters {
|
|
||||||
/// COEFF_A = 0
|
|
||||||
#[rustfmt::skip]
|
|
||||||
|
|
||||||
const COEFF_A: Fq = field_new!(Fq, "0");
|
|
||||||
|
|
||||||
/// COEFF_B = 4
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const COEFF_B: Fq = field_new!(Fq, "4");
|
|
||||||
|
|
||||||
/// COFACTOR =
|
/// COFACTOR =
|
||||||
/// 26642435879335816683987677701488073867751118270052650655942102502312977592501693353047140953112195348280268661194869
|
/// 26642435879335816683987677701488073867751118270052650655942102502312977592501693353047140953112195348280268661194869
|
||||||
@@ -40,25 +31,70 @@ impl SWModelParameters for Parameters {
|
|||||||
|
|
||||||
/// COFACTOR^(-1) mod r =
|
/// COFACTOR^(-1) mod r =
|
||||||
/// 214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124
|
/// 214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124
|
||||||
#[rustfmt::skip]
|
const COFACTOR_INV: Fr = MontFp!("214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124");
|
||||||
const COFACTOR_INV: Fr = field_new!(Fr, "214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124");
|
}
|
||||||
|
|
||||||
|
impl SWCurveConfig for Config {
|
||||||
|
/// COEFF_A = 0
|
||||||
|
const COEFF_A: Fq = Fq::ZERO;
|
||||||
|
|
||||||
|
/// COEFF_B = 4
|
||||||
|
const COEFF_B: Fq = MontFp!("4");
|
||||||
|
|
||||||
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
||||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||||
(G2_GENERATOR_X, G2_GENERATOR_Y);
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_by_a(_elem: &Self::BaseField) -> Self::BaseField {
|
fn mul_by_a(_elem: Self::BaseField) -> Self::BaseField {
|
||||||
use ark_ff::Zero;
|
use ark_ff::Zero;
|
||||||
Self::BaseField::zero()
|
Self::BaseField::zero()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GLVConfig for Config {
|
||||||
|
const ENDO_COEFFS: &'static [Self::BaseField] = &[
|
||||||
|
MontFp!("4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
|
||||||
|
];
|
||||||
|
|
||||||
|
const LAMBDA: Self::ScalarField =
|
||||||
|
MontFp!("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945");
|
||||||
|
|
||||||
|
const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
|
||||||
|
(
|
||||||
|
true,
|
||||||
|
BigInt!("293634935485640680722085584138834120315328839056164388863"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
false,
|
||||||
|
BigInt!("293634935485640680722085584138834120324914961969255022593"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
true,
|
||||||
|
BigInt!("293634935485640680722085584138834120324914961969255022593"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
true,
|
||||||
|
BigInt!("587269870971281361444171168277668240640243801025419411456"),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
fn endomorphism(p: &Projective<Self>) -> Projective<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn endomorphism_affine(p: &Affine<Self>) -> Affine<Self> {
|
||||||
|
let mut res = (*p).clone();
|
||||||
|
res.x *= Self::ENDO_COEFFS[0];
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// G2_GENERATOR_X =
|
/// G2_GENERATOR_X =
|
||||||
/// 6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428
|
/// 6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428
|
||||||
#[rustfmt::skip]
|
pub const G2_GENERATOR_X: Fq = MontFp!("6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428");
|
||||||
pub const G2_GENERATOR_X: Fq = field_new!(Fq, "6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428");
|
|
||||||
|
|
||||||
/// G2_GENERATOR_Y =
|
/// G2_GENERATOR_Y =
|
||||||
/// 562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041
|
/// 562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041
|
||||||
#[rustfmt::skip]
|
pub const G2_GENERATOR_Y: Fq = MontFp!("562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041");
|
||||||
pub const G2_GENERATOR_Y: Fq = field_new!(Fq, "562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041");
|
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
use crate::*;
|
|
||||||
use ark_ec::{
|
use ark_ec::{
|
||||||
bw6,
|
bw6,
|
||||||
bw6::{BW6Parameters, TwistType, BW6},
|
bw6::{BW6Config, TwistType, BW6},
|
||||||
};
|
};
|
||||||
use ark_ff::biginteger::BigInteger768 as BigInteger;
|
use ark_ff::{
|
||||||
|
biginteger::BigInteger768 as BigInteger, fp6_2over3::Fp6, BigInt, CyclotomicMultSubgroup, Field,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
pub mod g1;
|
pub mod g1;
|
||||||
pub mod g2;
|
pub mod g2;
|
||||||
@@ -12,50 +15,149 @@ 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 = BigInteger([
|
const X: BigInteger = BigInt!("0x8508c00000000001");
|
||||||
0x8508c00000000001,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
0x0,
|
|
||||||
]);
|
|
||||||
/// `x` is positive.
|
/// `x` is positive.
|
||||||
const X_IS_NEGATIVE: bool = false;
|
const X_IS_NEGATIVE: bool = false;
|
||||||
|
// X
|
||||||
|
const ATE_LOOP_COUNT_1: &'static [u64] = &[0x8508c00000000001];
|
||||||
|
// (X-1)/3
|
||||||
|
const X_MINUS_1_DIV_3: BigInteger = BigInt!("0x2c58400000000000");
|
||||||
// X+1
|
// X+1
|
||||||
const ATE_LOOP_COUNT_1: &'static [u64] = &[0x8508c00000000002];
|
|
||||||
const ATE_LOOP_COUNT_1_IS_NEGATIVE: bool = false;
|
const ATE_LOOP_COUNT_1_IS_NEGATIVE: bool = false;
|
||||||
// X^3-X^2-X
|
// X^2-X-1
|
||||||
const ATE_LOOP_COUNT_2: &'static [i8] = &[
|
const ATE_LOOP_COUNT_2: &'static [i8] = &[
|
||||||
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
|
0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0,
|
||||||
0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, 0,
|
0, 1, 0, 1, 0, 0, 0, 1,
|
||||||
1, 0, 0, 0, -1, 0, 0, -1, 0, 1, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, -1, 0, 1, 0, 1, 0, 0, 0, 1,
|
|
||||||
0, -1, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 1,
|
|
||||||
];
|
];
|
||||||
const ATE_LOOP_COUNT_2_IS_NEGATIVE: bool = false;
|
const ATE_LOOP_COUNT_2_IS_NEGATIVE: bool = false;
|
||||||
const TWIST_TYPE: TwistType = TwistType::M;
|
const TWIST_TYPE: TwistType = TwistType::M;
|
||||||
|
const H_T: i64 = 13;
|
||||||
|
const H_Y: i64 = 9;
|
||||||
|
const T_MOD_R_IS_ZERO: bool = false;
|
||||||
type Fp = Fq;
|
type Fp = Fq;
|
||||||
type Fp3Params = Fq3Parameters;
|
type Fp3Config = Fq3Config;
|
||||||
type Fp6Params = Fq6Parameters;
|
type Fp6Config = Fq6Config;
|
||||||
type G1Parameters = g1::Parameters;
|
type G1Config = g1::Config;
|
||||||
type G2Parameters = g2::Parameters;
|
type G2Config = g2::Config;
|
||||||
|
|
||||||
|
fn final_exponentiation_hard_part(f: &Fp6<Self::Fp6Config>) -> Fp6<Self::Fp6Config> {
|
||||||
|
// hard_part
|
||||||
|
// From https://eprint.iacr.org/2020/351.pdf, Alg.6
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
// R0(x) := (-103*x^7 + 70*x^6 + 269*x^5 - 197*x^4 - 314*x^3 - 73*x^2 - 263*x - 220)
|
||||||
|
// R1(x) := (103*x^9 - 276*x^8 + 77*x^7 + 492*x^6 - 445*x^5 - 65*x^4 + 452*x^3 - 181*x^2 + 34*x + 229)
|
||||||
|
// f ^ R0(u) * (f ^ q) ^ R1(u) in a 2-NAF multi-exp fashion.
|
||||||
|
|
||||||
|
// steps 1,2,3
|
||||||
|
let f0 = *f;
|
||||||
|
let mut f0p = f0;
|
||||||
|
f0p.frobenius_map_in_place(1);
|
||||||
|
let f1 = Self::exp_by_x(&f0);
|
||||||
|
let mut f1p = f1;
|
||||||
|
f1p.frobenius_map_in_place(1);
|
||||||
|
let f2 = Self::exp_by_x(&f1);
|
||||||
|
let mut f2p = f2;
|
||||||
|
f2p.frobenius_map_in_place(1);
|
||||||
|
let f3 = Self::exp_by_x(&f2);
|
||||||
|
let mut f3p = f3;
|
||||||
|
f3p.frobenius_map_in_place(1);
|
||||||
|
let f4 = Self::exp_by_x(&f3);
|
||||||
|
let mut f4p = f4;
|
||||||
|
f4p.frobenius_map_in_place(1);
|
||||||
|
let f5 = Self::exp_by_x(&f4);
|
||||||
|
let mut f5p = f5;
|
||||||
|
f5p.frobenius_map_in_place(1);
|
||||||
|
let f6 = Self::exp_by_x(&f5);
|
||||||
|
let mut f6p = f6;
|
||||||
|
f6p.frobenius_map_in_place(1);
|
||||||
|
let f7 = Self::exp_by_x(&f6);
|
||||||
|
let mut f7p = f7;
|
||||||
|
f7p.frobenius_map_in_place(1);
|
||||||
|
|
||||||
|
// step 4
|
||||||
|
let f8p = Self::exp_by_x(&f7p);
|
||||||
|
let f9p = Self::exp_by_x(&f8p);
|
||||||
|
|
||||||
|
// step 5
|
||||||
|
let mut f5p_p3 = f5p;
|
||||||
|
f5p_p3.cyclotomic_inverse_in_place();
|
||||||
|
let result1 = f3p * &f6p * &f5p_p3;
|
||||||
|
|
||||||
|
// step 6
|
||||||
|
let result2 = result1.square();
|
||||||
|
let f4_2p = f4 * &f2p;
|
||||||
|
let mut tmp1_p3 = f0 * &f1 * &f3 * &f4_2p * &f8p;
|
||||||
|
tmp1_p3.cyclotomic_inverse_in_place();
|
||||||
|
let result3 = result2 * &f5 * &f0p * &tmp1_p3;
|
||||||
|
|
||||||
|
// step 7
|
||||||
|
let result4 = result3.square();
|
||||||
|
let mut f7_p3 = f7;
|
||||||
|
f7_p3.cyclotomic_inverse_in_place();
|
||||||
|
let result5 = result4 * &f9p * &f7_p3;
|
||||||
|
|
||||||
|
// step 8
|
||||||
|
let result6 = result5.square();
|
||||||
|
let f2_4p = f2 * &f4p;
|
||||||
|
let f4_2p_5p = f4_2p * &f5p;
|
||||||
|
let mut tmp2_p3 = f2_4p * &f3 * &f3p;
|
||||||
|
tmp2_p3.cyclotomic_inverse_in_place();
|
||||||
|
let result7 = result6 * &f4_2p_5p * &f6 * &f7p * &tmp2_p3;
|
||||||
|
|
||||||
|
// step 9
|
||||||
|
let result8 = result7.square();
|
||||||
|
let mut tmp3_p3 = f0p * &f9p;
|
||||||
|
tmp3_p3.cyclotomic_inverse_in_place();
|
||||||
|
let result9 = result8 * &f0 * &f7 * &f1p * &tmp3_p3;
|
||||||
|
|
||||||
|
// step 10
|
||||||
|
let result10 = result9.square();
|
||||||
|
let f6p_8p = f6p * &f8p;
|
||||||
|
let f5_7p = f5 * &f7p;
|
||||||
|
let mut tmp4_p3 = f6p_8p;
|
||||||
|
tmp4_p3.cyclotomic_inverse_in_place();
|
||||||
|
let result11 = result10 * &f5_7p * &f2p * &tmp4_p3;
|
||||||
|
|
||||||
|
// step 11
|
||||||
|
let result12 = result11.square();
|
||||||
|
let f3_6 = f3 * &f6;
|
||||||
|
let f1_7 = f1 * &f7;
|
||||||
|
let mut tmp5_p3 = f1_7 * &f2;
|
||||||
|
tmp5_p3.cyclotomic_inverse_in_place();
|
||||||
|
let result13 = result12 * &f3_6 * &f9p * &tmp5_p3;
|
||||||
|
|
||||||
|
// step 12
|
||||||
|
let result14 = result13.square();
|
||||||
|
let mut tmp6_p3 = f4_2p * &f5_7p * &f6p_8p;
|
||||||
|
tmp6_p3.cyclotomic_inverse_in_place();
|
||||||
|
let result15 = result14 * &f0 * &f0p * &f3p * &f5p * &tmp6_p3;
|
||||||
|
|
||||||
|
// step 13
|
||||||
|
let result16 = result15.square();
|
||||||
|
let mut tmp7_p3 = f3_6;
|
||||||
|
tmp7_p3.cyclotomic_inverse_in_place();
|
||||||
|
let result17 = result16 * &f1p * &tmp7_p3;
|
||||||
|
|
||||||
|
// step 14
|
||||||
|
let result18 = result17.square();
|
||||||
|
let mut tmp8_p3 = f2_4p * &f4_2p_5p * &f9p;
|
||||||
|
tmp8_p3.cyclotomic_inverse_in_place();
|
||||||
|
let result19 = result18 * &f1_7 * &f5_7p * &f0p * &tmp8_p3;
|
||||||
|
|
||||||
|
result19
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type BW6_761 = BW6<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,78 +1,10 @@
|
|||||||
use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve};
|
|
||||||
use ark_ff::{Field, One, PrimeField};
|
|
||||||
use ark_std::rand::Rng;
|
|
||||||
use ark_std::test_rng;
|
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use ark_algebra_test_templates::*;
|
||||||
|
use ark_ff::Field;
|
||||||
|
|
||||||
use ark_algebra_test_templates::{curves::*, groups::*};
|
test_group!(g1; G1Projective; sw);
|
||||||
|
test_group!(g2; G2Projective; sw);
|
||||||
#[test]
|
test_group!(pairing_output; ark_ec::pairing::PairingOutput<BW6_761>; msm);
|
||||||
fn test_g1_projective_curve() {
|
test_pairing!(pairing; crate::BW6_761);
|
||||||
curve_tests::<G1Projective>();
|
test_group!(g1_glv; G1Projective; glv);
|
||||||
|
test_group!(g2_glv; G2Projective; glv);
|
||||||
sw_tests::<g1::Parameters>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_projective_group() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: G1Projective = rng.gen();
|
|
||||||
let b: G1Projective = rng.gen();
|
|
||||||
group_test(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g1_generator() {
|
|
||||||
let generator = G1Affine::prime_subgroup_generator();
|
|
||||||
assert!(generator.is_on_curve());
|
|
||||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_projective_curve() {
|
|
||||||
curve_tests::<G2Projective>();
|
|
||||||
|
|
||||||
sw_tests::<g2::Parameters>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_projective_group() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: G2Projective = rng.gen();
|
|
||||||
let b: G2Projective = rng.gen();
|
|
||||||
group_test(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_g2_generator() {
|
|
||||||
let generator = G2Affine::prime_subgroup_generator();
|
|
||||||
assert!(generator.is_on_curve());
|
|
||||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_bilinearity() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: G1Projective = rng.gen();
|
|
||||||
let b: G2Projective = rng.gen();
|
|
||||||
let s: Fr = rng.gen();
|
|
||||||
|
|
||||||
let sa = a.mul(s.into_repr());
|
|
||||||
let sb = b.mul(s.into_repr());
|
|
||||||
|
|
||||||
let ans1 = BW6_761::pairing(sa, b);
|
|
||||||
let ans2 = BW6_761::pairing(a, sb);
|
|
||||||
let ans3 = BW6_761::pairing(a, b).pow(s.into_repr());
|
|
||||||
|
|
||||||
assert_eq!(ans1, ans2);
|
|
||||||
assert_eq!(ans2, ans3);
|
|
||||||
|
|
||||||
assert_ne!(ans1, Fq6::one());
|
|
||||||
assert_ne!(ans2, Fq6::one());
|
|
||||||
assert_ne!(ans3, Fq6::one());
|
|
||||||
|
|
||||||
assert_eq!(ans1.pow(Fr::characteristic()), Fq6::one());
|
|
||||||
assert_eq!(ans2.pow(Fr::characteristic()), Fq6::one());
|
|
||||||
assert_eq!(ans3.pow(Fr::characteristic()), Fq6::one());
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,175 +1,7 @@
|
|||||||
use ark_ff::{
|
use ark_ff::fields::{Fp768, MontBackend, MontConfig};
|
||||||
biginteger::BigInteger768 as BigInteger,
|
|
||||||
field_new,
|
|
||||||
fields::{FftParameters, Fp768, Fp768Parameters, FpParameters},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub type Fq = Fp768<FqParameters>;
|
#[derive(MontConfig)]
|
||||||
|
#[modulus = "6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299"]
|
||||||
pub struct FqParameters;
|
#[generator = "2"]
|
||||||
|
pub struct FqConfig;
|
||||||
pub const FQ_ONE: Fq = field_new!(Fq, "1");
|
pub type Fq = Fp768<MontBackend<FqConfig, 12>>;
|
||||||
pub const FQ_ZERO: Fq = field_new!(Fq, "0");
|
|
||||||
|
|
||||||
impl Fp768Parameters for FqParameters {}
|
|
||||||
impl FftParameters for FqParameters {
|
|
||||||
type BigInt = BigInteger;
|
|
||||||
|
|
||||||
// The internal representation of this type is six 64-bit unsigned
|
|
||||||
// integers in little-endian order. Values are always in
|
|
||||||
// Montgomery form; i.e., Scalar(a) = aR mod p, with R=2^768.
|
|
||||||
|
|
||||||
// (MODULUS - 1) % 2^TWO_ADICITY == 0
|
|
||||||
const TWO_ADICITY: u32 = 1;
|
|
||||||
|
|
||||||
// least_quadratic_nonresidue(MODULUS) in Sage.
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
|
||||||
17481284903592032950u64,
|
|
||||||
10104133845767975835u64,
|
|
||||||
8607375506753517913u64,
|
|
||||||
13706168424391191299u64,
|
|
||||||
9580010308493592354u64,
|
|
||||||
14241333420363995524u64,
|
|
||||||
6665632285037357566u64,
|
|
||||||
5559902898979457045u64,
|
|
||||||
15504799981718861253u64,
|
|
||||||
8332096944629367896u64,
|
|
||||||
18005297320867222879u64,
|
|
||||||
58811391084848524u64,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
impl FpParameters for FqParameters {
|
|
||||||
/// MODULUS = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const MODULUS: BigInteger = BigInteger([
|
|
||||||
0xf49d00000000008b,
|
|
||||||
0xe6913e6870000082,
|
|
||||||
0x160cf8aeeaf0a437,
|
|
||||||
0x98a116c25667a8f8,
|
|
||||||
0x71dcd3dc73ebff2e,
|
|
||||||
0x8689c8ed12f9fd90,
|
|
||||||
0x03cebaff25b42304,
|
|
||||||
0x707ba638e584e919,
|
|
||||||
0x528275ef8087be41,
|
|
||||||
0xb926186a81d14688,
|
|
||||||
0xd187c94004faff3e,
|
|
||||||
0x122e824fb83ce0a
|
|
||||||
]);
|
|
||||||
|
|
||||||
const MODULUS_BITS: u32 = 761;
|
|
||||||
|
|
||||||
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
|
|
||||||
|
|
||||||
// gap to 64-bit machine word
|
|
||||||
const REPR_SHAVE_BITS: u32 = 7;
|
|
||||||
|
|
||||||
// 2^768 % MODULUS
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const R: BigInteger = BigInteger([
|
|
||||||
144959613005956565u64,
|
|
||||||
6509995272855063783u64,
|
|
||||||
11428286765660613342u64,
|
|
||||||
15738672438262922740u64,
|
|
||||||
17071399330169272331u64,
|
|
||||||
13899911246788437003u64,
|
|
||||||
12055474021000362245u64,
|
|
||||||
2545351818702954755u64,
|
|
||||||
8887388221587179644u64,
|
|
||||||
5009280847225881135u64,
|
|
||||||
15539704305423854047u64,
|
|
||||||
23071597697427581u64,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// R^2
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const R2: BigInteger = BigInteger([
|
|
||||||
14305184132582319705u64,
|
|
||||||
8868935336694416555u64,
|
|
||||||
9196887162930508889u64,
|
|
||||||
15486798265448570248u64,
|
|
||||||
5402985275949444416u64,
|
|
||||||
10893197322525159598u64,
|
|
||||||
3204916688966998390u64,
|
|
||||||
12417238192559061753u64,
|
|
||||||
12426306557607898622u64,
|
|
||||||
1305582522441154384u64,
|
|
||||||
10311846026977660324u64,
|
|
||||||
48736111365249031u64,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// (-1/MODULUS) % 2^64
|
|
||||||
const INV: u64 = 744663313386281181u64;
|
|
||||||
|
|
||||||
/// GENERATOR = 2
|
|
||||||
// primitive_root(MODULUS)
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const GENERATOR: BigInteger = BigInteger([
|
|
||||||
289919226011913130u64,
|
|
||||||
13019990545710127566u64,
|
|
||||||
4409829457611675068u64,
|
|
||||||
13030600802816293865u64,
|
|
||||||
15696054586628993047u64,
|
|
||||||
9353078419867322391u64,
|
|
||||||
5664203968291172875u64,
|
|
||||||
5090703637405909511u64,
|
|
||||||
17774776443174359288u64,
|
|
||||||
10018561694451762270u64,
|
|
||||||
12632664537138156478u64,
|
|
||||||
46143195394855163u64,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// (MODULUS - 1) / 2
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
|
||||||
0x7a4e800000000045,
|
|
||||||
0xf3489f3438000041,
|
|
||||||
0x0b067c577578521b,
|
|
||||||
0x4c508b612b33d47c,
|
|
||||||
0x38ee69ee39f5ff97,
|
|
||||||
0x4344e476897cfec8,
|
|
||||||
0x81e75d7f92da1182,
|
|
||||||
0xb83dd31c72c2748c,
|
|
||||||
0x29413af7c043df20,
|
|
||||||
0x5c930c3540e8a344,
|
|
||||||
0x68c3e4a0027d7f9f,
|
|
||||||
0x9174127dc1e705,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// T =
|
|
||||||
// 3445725192157866269698394841137828771239834456268075054756895080104811711121745868043841591644705843820432283876893306725580879560277123879674755849562650799475802549689254425186271815711798397975949850214984556421382456559534149
|
|
||||||
// (MODULUS - 1) / 2 ^ TWO_ADICITY
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const T: BigInteger = BigInteger([
|
|
||||||
0x7a4e800000000045,
|
|
||||||
0xf3489f3438000041,
|
|
||||||
0x0b067c577578521b,
|
|
||||||
0x4c508b612b33d47c,
|
|
||||||
0x38ee69ee39f5ff97,
|
|
||||||
0x4344e476897cfec8,
|
|
||||||
0x81e75d7f92da1182,
|
|
||||||
0xb83dd31c72c2748c,
|
|
||||||
0x29413af7c043df20,
|
|
||||||
0x5c930c3540e8a344,
|
|
||||||
0x68c3e4a0027d7f9f,
|
|
||||||
0x9174127dc1e705,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// (T - 1)/2 =
|
|
||||||
// 1722862596078933134849197420568914385619917228134037527378447540052405855560872934021920795822352921910216141938446653362790439780138561939837377924781325399737901274844627212593135907855899198987974925107492278210691228279767074
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
|
||||||
0xbd27400000000022,
|
|
||||||
0xf9a44f9a1c000020,
|
|
||||||
0x05833e2bbabc290d,
|
|
||||||
0xa62845b09599ea3e,
|
|
||||||
0x1c7734f71cfaffcb,
|
|
||||||
0x21a2723b44be7f64,
|
|
||||||
0x40f3aebfc96d08c1,
|
|
||||||
0x5c1ee98e39613a46,
|
|
||||||
0x14a09d7be021ef90,
|
|
||||||
0xae49861aa07451a2,
|
|
||||||
0xb461f250013ebfcf,
|
|
||||||
0x48ba093ee0f382,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,31 +1,27 @@
|
|||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
field_new,
|
fields::fp3::{Fp3, Fp3Config},
|
||||||
fields::fp3::{Fp3, Fp3Parameters},
|
AdditiveGroup, Field, MontFp,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::Fq;
|
||||||
fields::{FQ_ONE, FQ_ZERO},
|
|
||||||
Fq,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub type Fq3 = Fp3<Fq3Parameters>;
|
pub type Fq3 = Fp3<Fq3Config>;
|
||||||
|
|
||||||
pub struct Fq3Parameters;
|
pub struct Fq3Config;
|
||||||
|
|
||||||
impl Fp3Parameters for Fq3Parameters {
|
impl Fp3Config for Fq3Config {
|
||||||
type Fp = Fq;
|
type Fp = Fq;
|
||||||
|
|
||||||
/// NONRESIDUE = -4
|
/// NONRESIDUE = -4
|
||||||
// Fq3 = Fq\[u\]/u^3+4
|
// Fq3 = Fq\[u\]/u^3+4
|
||||||
#[rustfmt::skip]
|
const NONRESIDUE: Fq = MontFp!("-4");
|
||||||
const NONRESIDUE: Fq = field_new!(Fq, "-4");
|
|
||||||
|
|
||||||
// (MODULUS^3 - 1) % 2^TWO_ADICITY == 0
|
// (MODULUS^3 - 1) % 2^TWO_ADICITY == 0
|
||||||
const TWO_ADICITY: u32 = 1;
|
const TWO_ADICITY: u32 = 1;
|
||||||
|
|
||||||
// (T-1)/2 with T = (MODULUS^3-1) / 2^TWO_ADICITY
|
// (T-1)/2 with T = (MODULUS^3-1) / 2^TWO_ADICITY
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
const T_MINUS_ONE_DIV_TWO: &'static [u64] = &[
|
const TRACE_MINUS_ONE_DIV_TWO: &'static [u64] = &[
|
||||||
0xb5e7c000000a3eac,
|
0xb5e7c000000a3eac,
|
||||||
0xf79b99dbf41cf4ab,
|
0xf79b99dbf41cf4ab,
|
||||||
0xe9372b1919e55ee5,
|
0xe9372b1919e55ee5,
|
||||||
@@ -65,33 +61,28 @@ impl Fp3Parameters for Fq3Parameters {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// NONRESIDUE^T % q
|
// NONRESIDUE^T % q
|
||||||
#[rustfmt::skip]
|
const QUADRATIC_NONRESIDUE_TO_T: Fq3 = Fq3::new(
|
||||||
const QUADRATIC_NONRESIDUE_TO_T: (Fq, Fq, Fq) = (
|
MontFp!("6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068298"),
|
||||||
field_new!(Fq, "6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068298"),
|
Fq::ZERO,
|
||||||
FQ_ZERO,
|
Fq::ZERO,
|
||||||
FQ_ZERO,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// NQR ^ (MODULUS^i - 1)/3, i=0,1,2 with NQR = u = (0,1,0)
|
// NQR ^ (MODULUS^i - 1)/3, i=0,1,2 with NQR = u = (0,1,0)
|
||||||
#[rustfmt::skip]
|
|
||||||
const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[
|
const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[
|
||||||
FQ_ONE,
|
Fq::ONE,
|
||||||
field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
|
MontFp!("4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
|
||||||
field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
|
MontFp!("1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
|
||||||
];
|
];
|
||||||
|
|
||||||
// NQR ^ (2*MODULUS^i - 2)/3, i=0,1,2 with NQR = u = (0,1,0)
|
// NQR ^ (2*MODULUS^i - 2)/3, i=0,1,2 with NQR = u = (0,1,0)
|
||||||
#[rustfmt::skip]
|
|
||||||
const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[
|
const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[
|
||||||
FQ_ONE,
|
Fq::ONE,
|
||||||
field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
|
MontFp!("1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
|
||||||
field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
|
MontFp!("4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[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,27 +1,26 @@
|
|||||||
use crate::{Fq, Fq3, Fq3Parameters, FQ_ONE, FQ_ZERO};
|
|
||||||
use ark_ff::{
|
use ark_ff::{
|
||||||
field_new,
|
fields::fp6_2over3::{Fp6, Fp6Config},
|
||||||
fields::fp6_2over3::{Fp6, Fp6Parameters},
|
AdditiveGroup, Field, MontFp,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type Fq6 = Fp6<Fq6Parameters>;
|
use crate::{Fq, Fq3, Fq3Config};
|
||||||
|
|
||||||
pub struct Fq6Parameters;
|
pub type Fq6 = Fp6<Fq6Config>;
|
||||||
|
|
||||||
impl Fp6Parameters for Fq6Parameters {
|
pub struct Fq6Config;
|
||||||
type Fp3Params = Fq3Parameters;
|
|
||||||
|
impl Fp6Config for Fq6Config {
|
||||||
|
type Fp3Config = Fq3Config;
|
||||||
|
|
||||||
/// NONRESIDUE = (0, 1, 0)
|
/// NONRESIDUE = (0, 1, 0)
|
||||||
#[rustfmt::skip]
|
const NONRESIDUE: Fq3 = Fq3::new(Fq::ZERO, Fq::ONE, Fq::ZERO);
|
||||||
const NONRESIDUE: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO);
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[
|
const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[
|
||||||
field_new!(Fq, "1"),
|
Fq::ONE,
|
||||||
field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775649"),
|
MontFp!("4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775649"),
|
||||||
field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
|
MontFp!("4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"),
|
||||||
field_new!(Fq, "-1"),
|
MontFp!("-1"),
|
||||||
field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
|
MontFp!("1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"),
|
||||||
field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292651"),
|
MontFp!("1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292651"),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
pub use ark_bls12_377::{Fq as Fr, FqParameters as FrParameters};
|
pub use ark_bls12_377::{Fq as Fr, FqConfig as FrConfig};
|
||||||
|
|||||||
@@ -1,52 +1,7 @@
|
|||||||
use ark_ff::{Field, PrimeField};
|
|
||||||
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
|
||||||
use ark_std::rand::Rng;
|
|
||||||
use ark_std::test_rng;
|
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use ark_algebra_test_templates::*;
|
||||||
|
|
||||||
use ark_algebra_test_templates::fields::*;
|
test_field!(fr; Fr; mont_prime_field);
|
||||||
|
test_field!(fq; Fq; mont_prime_field);
|
||||||
#[test]
|
test_field!(fq3; Fq3);
|
||||||
fn test_fr() {
|
test_field!(fq6; Fq6);
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: Fr = rng.gen();
|
|
||||||
let b: Fr = rng.gen();
|
|
||||||
field_test(a, b);
|
|
||||||
sqrt_field_test(a);
|
|
||||||
primefield_test::<Fr>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: Fq = rng.gen();
|
|
||||||
let b: Fq = rng.gen();
|
|
||||||
field_test(a, b);
|
|
||||||
primefield_test::<Fq>();
|
|
||||||
sqrt_field_test(a);
|
|
||||||
|
|
||||||
let byte_size = a.serialized_size();
|
|
||||||
let (_, buffer_size) = buffer_bit_byte_size(Fq::size_in_bits());
|
|
||||||
assert_eq!(byte_size, buffer_size);
|
|
||||||
field_serialization_test::<Fq>(byte_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq3() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: Fq3 = rng.gen();
|
|
||||||
let b: Fq3 = rng.gen();
|
|
||||||
field_test(a, b);
|
|
||||||
sqrt_field_test(a);
|
|
||||||
frobenius_test::<Fq3, _>(Fq::characteristic(), 13);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fq6() {
|
|
||||||
let mut rng = test_rng();
|
|
||||||
let a: Fq6 = rng.gen();
|
|
||||||
let b: Fq6 = rng.gen();
|
|
||||||
field_test(a, b);
|
|
||||||
frobenius_test::<Fq6, _>(Fq::characteristic(), 13);
|
|
||||||
}
|
|
||||||
|
|||||||
7
bw6_761/src/lib.rs
Normal file → Executable file
7
bw6_761/src/lib.rs
Normal file → Executable file
@@ -9,9 +9,10 @@
|
|||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
|
|
||||||
//! This library implements the BW6_761 curve generated in [\[EG20\]](https://eprint.iacr.org/2020/351).
|
//! This library implements the BW6_761 curve generated in [\[EG20\]](https://eprint.iacr.org/2020/351).
|
||||||
//! The name denotes that it is a curve generated using the Brezing--Weng method, and that
|
//! The name denotes that it is a curve generated using the Brezing--Weng
|
||||||
//! its embedding degree is 6.
|
//! method, and that its embedding degree is 6.
|
||||||
//! The main feature of this curve is that the scalar field equals the base field of the BLS12_377 curve.
|
//! The main feature of this curve is that the scalar field equals the base
|
||||||
|
//! field of the BLS12_377 curve.
|
||||||
//!
|
//!
|
||||||
//! Curve information:
|
//! Curve information:
|
||||||
//! * Base field: q = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299
|
//! * Base field: q = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299
|
||||||
|
|||||||
33
bw6_767/Cargo.toml
Normal file
33
bw6_767/Cargo.toml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
[package]
|
||||||
|
name = "ark-bw6-767"
|
||||||
|
version = "0.4.0"
|
||||||
|
authors = [ "arkworks contributors" ]
|
||||||
|
description = "The BW6-767 pairing-friendly elliptic curve"
|
||||||
|
homepage = "https://arkworks.rs"
|
||||||
|
repository = "https://github.com/arkworks-rs/curves"
|
||||||
|
documentation = "https://docs.rs/ark-bw6-767/"
|
||||||
|
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||||
|
categories = ["cryptography"]
|
||||||
|
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||||
|
license = "MIT/Apache-2.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ark-ff = { version= "0.4.0", default-features = false }
|
||||||
|
ark-ec = { version= "0.4.0", default-features = false }
|
||||||
|
ark-std = { version = "0.4.0", default-features = false }
|
||||||
|
ark-bls12-381 = { version = "0.4.0", path = "../bls12_381", default-features = false, features = [ "curve" ] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
ark-serialize = { version = "0.4.0", default-features = false }
|
||||||
|
ark-algebra-test-templates = { version = "0.4.0", default-features = false }
|
||||||
|
ark-algebra-bench-templates = { version = "0.4.0", default-features = false }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std", "ark-bls12-381/std" ]
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "bw6_767"
|
||||||
|
path = "benches/bw6_767.rs"
|
||||||
|
harness = false
|
||||||
1
bw6_767/LICENSE-APACHE
Symbolic link
1
bw6_767/LICENSE-APACHE
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../LICENSE-APACHE
|
||||||
1
bw6_767/LICENSE-MIT
Symbolic link
1
bw6_767/LICENSE-MIT
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../LICENSE-MIT
|
||||||
16
bw6_767/benches/bw6_767.rs
Normal file
16
bw6_767/benches/bw6_767.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
use ark_algebra_bench_templates::*;
|
||||||
|
|
||||||
|
use ark_bw6_767::{
|
||||||
|
fq::Fq, fq3::Fq3, fq6::Fq6, fr::Fr, g1::G1Projective as G1, g2::G2Projective as G2, BW6_767,
|
||||||
|
};
|
||||||
|
|
||||||
|
bench!(
|
||||||
|
Name = "BW6_767",
|
||||||
|
Pairing = BW6_767,
|
||||||
|
G1 = G1,
|
||||||
|
G2 = G2,
|
||||||
|
ScalarField = Fr,
|
||||||
|
G1BaseField = Fq,
|
||||||
|
G2BaseField = Fq3,
|
||||||
|
TargetField = Fq6,
|
||||||
|
);
|
||||||
28
bw6_767/scripts/base_field.sage
Normal file
28
bw6_767/scripts/base_field.sage
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
modulus = 496597749679620867773432037469214230242402307330180853437434581099336634619713640485778675608223760166307530047354464605410050411581079376994803852937842168733702867087556948851016246640584660942486895230518034810309227309966899431
|
||||||
|
|
||||||
|
assert(modulus.is_prime())
|
||||||
|
|
||||||
|
Fp = GF(modulus)
|
||||||
|
|
||||||
|
generator = Fp(0);
|
||||||
|
for i in range(0, 20):
|
||||||
|
i = Fp(i);
|
||||||
|
neg_i = Fp(-i)
|
||||||
|
if not(i.is_primitive_root() or neg_i.is_primitive_root()):
|
||||||
|
continue
|
||||||
|
elif i.is_primitive_root():
|
||||||
|
assert(i.is_primitive_root());
|
||||||
|
print("Generator: %d" % i)
|
||||||
|
generator = i
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
assert(neg_i.is_primitive_root());
|
||||||
|
print("Generator: %d" % neg_i)
|
||||||
|
generator = neg_i
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
two_adicity = valuation(modulus - 1, 2);
|
||||||
|
trace = (modulus - 1) / 2**two_adicity;
|
||||||
|
two_adic_root_of_unity = generator^trace
|
||||||
|
print("2-adic Root of Unity: %d " % two_adic_root_of_unity)
|
||||||
28
bw6_767/scripts/scalar_field.sage
Normal file
28
bw6_767/scripts/scalar_field.sage
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
modulus = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
|
||||||
|
|
||||||
|
assert(modulus.is_prime())
|
||||||
|
|
||||||
|
Fp = GF(modulus)
|
||||||
|
|
||||||
|
generator = Fp(0);
|
||||||
|
for i in range(0, 20):
|
||||||
|
i = Fp(i);
|
||||||
|
neg_i = Fp(-i)
|
||||||
|
if not(i.is_primitive_root() or neg_i.is_primitive_root()):
|
||||||
|
continue
|
||||||
|
elif i.is_primitive_root():
|
||||||
|
assert(i.is_primitive_root());
|
||||||
|
print("Generator: %d" % i)
|
||||||
|
generator = i
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
assert(neg_i.is_primitive_root());
|
||||||
|
print("Generator: %d" % neg_i)
|
||||||
|
generator = neg_i
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
two_adicity = valuation(modulus - 1, 2);
|
||||||
|
trace = (modulus - 1) / 2**two_adicity;
|
||||||
|
two_adic_root_of_unity = generator^trace
|
||||||
|
print("2-adic Root of Unity: %d " % two_adic_root_of_unity)
|
||||||
59
bw6_767/src/curves/g1.rs
Normal file
59
bw6_767/src/curves/g1.rs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
use ark_ec::{
|
||||||
|
models::{short_weierstrass::SWCurveConfig, CurveConfig},
|
||||||
|
short_weierstrass::{Affine, Projective},
|
||||||
|
};
|
||||||
|
use ark_ff::{AdditiveGroup, MontFp};
|
||||||
|
|
||||||
|
use crate::{Fq, Fr};
|
||||||
|
|
||||||
|
pub type G1Affine = Affine<Config>;
|
||||||
|
pub type G1Projective = Projective<Config>;
|
||||||
|
|
||||||
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
|
pub struct Config;
|
||||||
|
|
||||||
|
impl CurveConfig for Config {
|
||||||
|
type BaseField = Fq;
|
||||||
|
type ScalarField = Fr;
|
||||||
|
|
||||||
|
/// COFACTOR =
|
||||||
|
/// 124074696211871689196744963988542244365937182994917792082847997279938522233341057826255097957635256182243502012934844
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COFACTOR: &'static [u64] = &[
|
||||||
|
0x9fed0006fffaaabc,
|
||||||
|
0xfae29bffb34d7c0d,
|
||||||
|
0xc51e35fba8145036,
|
||||||
|
0x58c9927410ca3a62,
|
||||||
|
0x7772b64205a0bc67,
|
||||||
|
0x26212b5cf67cecaf,
|
||||||
|
0x3,
|
||||||
|
];
|
||||||
|
|
||||||
|
/// COFACTOR^(-1) mod r =
|
||||||
|
/// 1707860402533867312515920333330662452399178546610458136488910471176197226039103222144872611321997303708365553992812
|
||||||
|
const COFACTOR_INV: Fr = MontFp!("1707860402533867312515920333330662452399178546610458136488910471176197226039103222144872611321997303708365553992812");
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWCurveConfig for Config {
|
||||||
|
/// COEFF_A = 0
|
||||||
|
const COEFF_A: Fq = Fq::ZERO;
|
||||||
|
|
||||||
|
/// COEFF_B = 1
|
||||||
|
const COEFF_B: Fq = MontFp!("1");
|
||||||
|
|
||||||
|
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||||
|
const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||||
|
#[inline(always)]
|
||||||
|
fn mul_by_a(_elem: Self::BaseField) -> Self::BaseField {
|
||||||
|
use ark_ff::Zero;
|
||||||
|
Self::BaseField::zero()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// G1_GENERATOR_X =
|
||||||
|
/// 127687253511432941835499154999732953539969793860764514205013635996439242747457934431893570832266740963864950713809357287070846939000367049554519743864924323440810949629217677483481194663331926309250818003412838087592587472550707218
|
||||||
|
pub const G1_GENERATOR_X: Fq = MontFp!("127687253511432941835499154999732953539969793860764514205013635996439242747457934431893570832266740963864950713809357287070846939000367049554519743864924323440810949629217677483481194663331926309250818003412838087592587472550707218");
|
||||||
|
|
||||||
|
/// G1_GENERATOR_Y =
|
||||||
|
/// 415570529523170147223250223671601071129165798689804006717876771297003017718159840368703823786319144396618898691682149260290217115399107531975419658973137909698922937988511368601419289861827304905241655385035120916874417442125721204
|
||||||
|
pub const G1_GENERATOR_Y: Fq = MontFp!("415570529523170147223250223671601071129165798689804006717876771297003017718159840368703823786319144396618898691682149260290217115399107531975419658973137909698922937988511368601419289861827304905241655385035120916874417442125721204");
|
||||||
60
bw6_767/src/curves/g2.rs
Normal file
60
bw6_767/src/curves/g2.rs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
use ark_ec::{
|
||||||
|
models::{short_weierstrass::SWCurveConfig, CurveConfig},
|
||||||
|
short_weierstrass::{Affine, Projective},
|
||||||
|
};
|
||||||
|
use ark_ff::{AdditiveGroup, MontFp};
|
||||||
|
|
||||||
|
use crate::{Fq, Fr};
|
||||||
|
|
||||||
|
pub type G2Affine = Affine<Config>;
|
||||||
|
pub type G2Projective = Projective<Config>;
|
||||||
|
|
||||||
|
#[derive(Clone, Default, PartialEq, Eq)]
|
||||||
|
pub struct Config;
|
||||||
|
|
||||||
|
impl CurveConfig for Config {
|
||||||
|
type BaseField = Fq;
|
||||||
|
type ScalarField = Fr;
|
||||||
|
|
||||||
|
/// COFACTOR =
|
||||||
|
/// 124074696211871689196744963988542244365937182994917792082847997279938522233341057826255097957635256182243502012934833
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const COFACTOR: &'static [u64] = &[
|
||||||
|
0x9fed0006fffaaab1,
|
||||||
|
0xfae29bffb34d7c0d,
|
||||||
|
0xc51e35fba8145036,
|
||||||
|
0x58c9927410ca3a62,
|
||||||
|
0x7772b64205a0bc67,
|
||||||
|
0x26212b5cf67cecaf,
|
||||||
|
0x3,
|
||||||
|
];
|
||||||
|
|
||||||
|
/// COFACTOR^(-1) mod r =
|
||||||
|
/// 1034808299677096100380606582404873291173913026971901593767142419502683535585229274705219741821274468081298550569313
|
||||||
|
const COFACTOR_INV: Fr = MontFp!("1034808299677096100380606582404873291173913026971901593767142419502683535585229274705219741821274468081298550569313");
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SWCurveConfig for Config {
|
||||||
|
/// COEFF_A = 0
|
||||||
|
const COEFF_A: Fq = Fq::ZERO;
|
||||||
|
|
||||||
|
/// COEFF_B = 4
|
||||||
|
const COEFF_B: Fq = MontFp!("3");
|
||||||
|
|
||||||
|
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
||||||
|
const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn mul_by_a(_elem: Self::BaseField) -> Self::BaseField {
|
||||||
|
use ark_ff::Zero;
|
||||||
|
Self::BaseField::zero()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// G2_GENERATOR_X =
|
||||||
|
/// 370611171465172359348863648443534520144617072349884185652206813771489664034831143983178049920510836078361116088420840622225267322852644540540617123958979924966938307707664543525950567252218300954395355151658118858470703533448342222
|
||||||
|
pub const G2_GENERATOR_X: Fq = MontFp!("370611171465172359348863648443534520144617072349884185652206813771489664034831143983178049920510836078361116088420840622225267322852644540540617123958979924966938307707664543525950567252218300954395355151658118858470703533448342222");
|
||||||
|
|
||||||
|
/// G2_GENERATOR_Y =
|
||||||
|
/// 455144308204607096185992716699045373884508292978508084510087807751472279103896568109582325400258900176330927780121791269969939391813736974371796892558810828460226121428602798229282770695472612961143258458821149661074127679136388603
|
||||||
|
pub const G2_GENERATOR_Y: Fq = MontFp!("455144308204607096185992716699045373884508292978508084510087807751472279103896568109582325400258900176330927780121791269969939391813736974371796892558810828460226121428602798229282770695472612961143258458821149661074127679136388603");
|
||||||
51
bw6_767/src/curves/mod.rs
Normal file
51
bw6_767/src/curves/mod.rs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
use ark_ec::{
|
||||||
|
bw6,
|
||||||
|
bw6::{BW6Config, TwistType, BW6},
|
||||||
|
};
|
||||||
|
use ark_ff::{biginteger::BigInteger768 as BigInteger, BigInt};
|
||||||
|
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
pub mod g1;
|
||||||
|
pub mod g2;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
|
pub struct Config;
|
||||||
|
|
||||||
|
impl BW6Config for Config {
|
||||||
|
// X is the same as in bls12_381
|
||||||
|
const X: BigInteger = BigInt!("0xd201000000010000");
|
||||||
|
const X_IS_NEGATIVE: bool = true;
|
||||||
|
// X
|
||||||
|
const ATE_LOOP_COUNT_1: &'static [u64] = &[0xd201000000010000];
|
||||||
|
const X_MINUS_1_DIV_3: BigInteger = BigInt!("0x460055555555aaab");
|
||||||
|
const ATE_LOOP_COUNT_1_IS_NEGATIVE: bool = true;
|
||||||
|
// X^2-X-1
|
||||||
|
const ATE_LOOP_COUNT_2: &'static [i8] = &[
|
||||||
|
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
|
||||||
|
1, 0, -1, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, -1, 0, -1, 0, 1, 0, 0, 1,
|
||||||
|
0, 0, 0, -1, 0, -1, 0, -1, 0, 1,
|
||||||
|
];
|
||||||
|
const ATE_LOOP_COUNT_2_IS_NEGATIVE: bool = false;
|
||||||
|
const TWIST_TYPE: TwistType = TwistType::M;
|
||||||
|
const H_T: i64 = -4;
|
||||||
|
const H_Y: i64 = -6;
|
||||||
|
const T_MOD_R_IS_ZERO: bool = true;
|
||||||
|
type Fp = Fq;
|
||||||
|
type Fp3Config = Fq3Config;
|
||||||
|
type Fp6Config = Fq6Config;
|
||||||
|
type G1Config = g1::Config;
|
||||||
|
type G2Config = g2::Config;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type BW6_767 = BW6<Config>;
|
||||||
|
|
||||||
|
pub type G1Affine = bw6::G1Affine<Config>;
|
||||||
|
pub type G1Projective = bw6::G1Projective<Config>;
|
||||||
|
pub type G2Affine = bw6::G2Affine<Config>;
|
||||||
|
pub type G2Projective = bw6::G2Projective<Config>;
|
||||||
8
bw6_767/src/curves/tests.rs
Normal file
8
bw6_767/src/curves/tests.rs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
use crate::*;
|
||||||
|
use ark_algebra_test_templates::*;
|
||||||
|
use ark_ff::Field;
|
||||||
|
|
||||||
|
test_group!(g1; G1Projective; sw);
|
||||||
|
test_group!(g2; G2Projective; sw);
|
||||||
|
test_group!(pairing_output; ark_ec::pairing::PairingOutput<BW6_767>; msm);
|
||||||
|
test_pairing!(pairing; crate::BW6_767);
|
||||||
7
bw6_767/src/fields/fq.rs
Normal file
7
bw6_767/src/fields/fq.rs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
use ark_ff::fields::{Fp768, MontBackend, MontConfig};
|
||||||
|
|
||||||
|
#[derive(MontConfig)]
|
||||||
|
#[modulus = "496597749679620867773432037469214230242402307330180853437434581099336634619713640485778675608223760166307530047354464605410050411581079376994803852937842168733702867087556948851016246640584660942486895230518034810309227309966899431"]
|
||||||
|
#[generator = "3"]
|
||||||
|
pub struct FqConfig;
|
||||||
|
pub type Fq = Fp768<MontBackend<FqConfig, 12>>;
|
||||||
79
bw6_767/src/fields/fq3.rs
Normal file
79
bw6_767/src/fields/fq3.rs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
use ark_ff::{
|
||||||
|
fields::fp3::{Fp3, Fp3Config},
|
||||||
|
AdditiveGroup, Field, MontFp,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::Fq;
|
||||||
|
|
||||||
|
pub type Fq3 = Fp3<Fq3Config>;
|
||||||
|
|
||||||
|
pub struct Fq3Config;
|
||||||
|
|
||||||
|
impl Fp3Config for Fq3Config {
|
||||||
|
type Fp = Fq;
|
||||||
|
|
||||||
|
/// NONRESIDUE = 3
|
||||||
|
// Fq3 = Fq\[u\]/u^3-3
|
||||||
|
const NONRESIDUE: Fq = MontFp!("3");
|
||||||
|
|
||||||
|
// (MODULUS^3 - 1) % 2^TWO_ADICITY == 0
|
||||||
|
const TWO_ADICITY: u32 = 1;
|
||||||
|
|
||||||
|
// (T-1)/2 with T = (MODULUS^3-1) / 2^TWO_ADICITY
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const TRACE_MINUS_ONE_DIV_TWO: &'static [u64] = &[
|
||||||
|
0x22d18a101ce54f7d,
|
||||||
|
0x354335b0e7c460e8,
|
||||||
|
0x8014efd2b7ade04d,
|
||||||
|
0x3a3c62ab52e0a2c1,
|
||||||
|
0x79ce8405b95dd2ee,
|
||||||
|
0x24f75cbd8559a2b6,
|
||||||
|
0x2519d1267e548214,
|
||||||
|
0xea0034421965f6c8,
|
||||||
|
0xbbaa92b6aca7d134,
|
||||||
|
0x9ec0892af11e70cc,
|
||||||
|
0x06e6ab40a2fd09ec,
|
||||||
|
0xd333987617c1542a,
|
||||||
|
0xdcb52167b1f0ae0f,
|
||||||
|
0xeffa098d77a86e52,
|
||||||
|
0x9fe0d744c24ed062,
|
||||||
|
0x7df249c9ef981da1,
|
||||||
|
0x01337d754cef36fa,
|
||||||
|
0xf84c4f79c259bd8b,
|
||||||
|
0x6552e19d7dc57335,
|
||||||
|
0x9f2cab11727d9c89,
|
||||||
|
0xe5cc4da17a684263,
|
||||||
|
0xaab0632027470c14,
|
||||||
|
0xb841a2fe447f48a3,
|
||||||
|
0x6e705db09cb2c6c9,
|
||||||
|
0x51d3c82bd5de018d,
|
||||||
|
0xf0bb21ffbef26bd1,
|
||||||
|
0x294ce678e6a4c0ff,
|
||||||
|
0x130ad731f57d4c85,
|
||||||
|
0xa1e367e5eb70a85b,
|
||||||
|
0xd1b2d73d567515cd,
|
||||||
|
0x0527dddbc3e9f165,
|
||||||
|
0x1d9c04e0098344e7,
|
||||||
|
0x5db616f391729475,
|
||||||
|
0xd2834b1fae1c2c1b,
|
||||||
|
0x7cf1b8c728557851,
|
||||||
|
0x218325db61d6ebd,
|
||||||
|
];
|
||||||
|
|
||||||
|
// NONRESIDUE^T % q
|
||||||
|
const QUADRATIC_NONRESIDUE_TO_T: Fq3 = Fq3::new(Fq::ONE, Fq::ZERO, Fq::ZERO);
|
||||||
|
|
||||||
|
// NQR ^ (MODULUS^i - 1)/3, i=0,1,2 with NQR = u = (0,1,0)
|
||||||
|
const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[
|
||||||
|
Fq::ONE,
|
||||||
|
MontFp!("451452499708746243421442696394275804592767119751118962106882058158528025766103643615697202253207413006991058800455542766924935899310685166148099708594514571753800103096705086912881023032622324847956780035251378028187894066092550170"),
|
||||||
|
MontFp!("45145249970874624351989341074938425649635187579061891330552522940808608853609996870081473355016347159316471246898921838485114512270394210846704144343327596979902763990851861938135223607962336094530115195266656782121333243874349260"),
|
||||||
|
];
|
||||||
|
|
||||||
|
// NQR ^ (2*MODULUS^i - 2)/3, i=0,1,2 with NQR = u = (0,1,0)
|
||||||
|
const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[
|
||||||
|
Fq::ONE,
|
||||||
|
MontFp!("45145249970874624351989341074938425649635187579061891330552522940808608853609996870081473355016347159316471246898921838485114512270394210846704144343327596979902763990851861938135223607962336094530115195266656782121333243874349260"),
|
||||||
|
MontFp!("451452499708746243421442696394275804592767119751118962106882058158528025766103643615697202253207413006991058800455542766924935899310685166148099708594514571753800103096705086912881023032622324847956780035251378028187894066092550170"),
|
||||||
|
];
|
||||||
|
}
|
||||||
26
bw6_767/src/fields/fq6.rs
Normal file
26
bw6_767/src/fields/fq6.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
use ark_ff::{
|
||||||
|
fields::fp6_2over3::{Fp6, Fp6Config},
|
||||||
|
AdditiveGroup, Field, MontFp,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{Fq, Fq3, Fq3Config};
|
||||||
|
|
||||||
|
pub type Fq6 = Fp6<Fq6Config>;
|
||||||
|
|
||||||
|
pub struct Fq6Config;
|
||||||
|
|
||||||
|
impl Fp6Config for Fq6Config {
|
||||||
|
type Fp3Config = Fq3Config;
|
||||||
|
|
||||||
|
/// NONRESIDUE = (0, 1, 0)
|
||||||
|
const NONRESIDUE: Fq3 = Fq3::new(Fq::ZERO, Fq::ONE, Fq::ZERO);
|
||||||
|
|
||||||
|
const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[
|
||||||
|
Fq::ONE,
|
||||||
|
MontFp!("451452499708746243421442696394275804592767119751118962106882058158528025766103643615697202253207413006991058800455542766924935899310685166148099708594514571753800103096705086912881023032622324847956780035251378028187894066092550171"),
|
||||||
|
MontFp!("451452499708746243421442696394275804592767119751118962106882058158528025766103643615697202253207413006991058800455542766924935899310685166148099708594514571753800103096705086912881023032622324847956780035251378028187894066092550170"),
|
||||||
|
MontFp!("-1"),
|
||||||
|
MontFp!("45145249970874624351989341074938425649635187579061891330552522940808608853609996870081473355016347159316471246898921838485114512270394210846704144343327596979902763990851861938135223607962336094530115195266656782121333243874349260"),
|
||||||
|
MontFp!("45145249970874624351989341074938425649635187579061891330552522940808608853609996870081473355016347159316471246898921838485114512270394210846704144343327596979902763990851861938135223607962336094530115195266656782121333243874349261"),
|
||||||
|
];
|
||||||
|
}
|
||||||
1
bw6_767/src/fields/fr.rs
Normal file
1
bw6_767/src/fields/fr.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub use ark_bls12_381::{Fq as Fr, FqConfig as FrConfig};
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user