mirror of
https://github.com/arnaucube/ark-curves-cherry-picked.git
synced 2026-01-07 06:21:31 +01:00
Initial commit
This commit is contained in:
128
.github/workflows/ci.yml
vendored
Normal file
128
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
name: CI
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
jobs:
|
||||
style:
|
||||
name: Check Style
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: rustfmt
|
||||
|
||||
- name: cargo fmt --check
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --all -- --check
|
||||
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RUSTFLAGS: -Dwarnings
|
||||
strategy:
|
||||
matrix:
|
||||
rust:
|
||||
- stable
|
||||
- nightly
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Rust (${{ matrix.rust }})
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: ${{ matrix.rust }}
|
||||
override: true
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: Check examples
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
args: --examples --all
|
||||
|
||||
- name: Check examples with all features on stable
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
args: --examples --all-features --all
|
||||
if: matrix.rust == 'stable'
|
||||
|
||||
- name: Check benchmarks on nightly
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
args: --all-features --examples --workspace --benches
|
||||
if: matrix.rust == 'nightly'
|
||||
|
||||
- name: Test
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
args: "--workspace \
|
||||
--all-features \
|
||||
--exclude curve-benches"
|
||||
|
||||
check_no_std:
|
||||
name: Check no_std
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Rust (${{ matrix.rust }})
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
target: thumbv6m-none-eabi
|
||||
override: true
|
||||
|
||||
- name: Install Rust ARM64 (${{ matrix.rust }})
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
target: aarch64-unknown-none
|
||||
override: true
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: check
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
args: --examples --workspace --exclude ark-curve-tests --exclude ark-curve-benches --target thumbv6m-none-eabi
|
||||
|
||||
- name: build
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --workspace --exclude ark-curve-tests --exclude ark-curve-benches --target thumbv6m-none-eabi
|
||||
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
target
|
||||
Cargo.lock
|
||||
.DS_Store
|
||||
.idea
|
||||
*.iml
|
||||
*.ipynb_checkpoints
|
||||
*.pyc
|
||||
*.sage.py
|
||||
params
|
||||
*.swp
|
||||
*.swo
|
||||
458
Cargo.lock
generated
Normal file
458
Cargo.lock
generated
Normal file
@@ -0,0 +1,458 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "ark-bls12-377"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-curve-tests",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-bls12-381"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-curve-tests",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-bn254"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-curve-tests",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-bw6-761"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-bls12-377",
|
||||
"ark-curve-tests",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-cp6-782"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-bls12-377",
|
||||
"ark-curve-tests",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-curve-benches"
|
||||
version = "0.1.1-alpha.0"
|
||||
dependencies = [
|
||||
"ark-bls12-377",
|
||||
"ark-bls12-381",
|
||||
"ark-bn254",
|
||||
"ark-bw6-761",
|
||||
"ark-cp6-782",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-mnt4-298",
|
||||
"ark-mnt4-753",
|
||||
"ark-mnt6-298",
|
||||
"ark-mnt6-753",
|
||||
"ark-serialize",
|
||||
"paste",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-curve-tests"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-ec"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/arkworks-rs/algebra#d5202f896ca9700c5c22d7a1266ada600f913dc4"
|
||||
dependencies = [
|
||||
"ark-ff",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"derivative",
|
||||
"num-traits",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-ed-on-bls12-377"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-bls12-377",
|
||||
"ark-curve-tests",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-ed-on-bls12-381"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-bls12-381",
|
||||
"ark-curve-tests",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-ed-on-bn254"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-bn254",
|
||||
"ark-curve-tests",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-ed-on-bw6-761"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-ed-on-cp6-782",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-ed-on-cp6-782"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-bls12-377",
|
||||
"ark-curve-tests",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-ed-on-mnt4-298"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-curve-tests",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-mnt4-298",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-ff"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/arkworks-rs/algebra#d5202f896ca9700c5c22d7a1266ada600f913dc4"
|
||||
dependencies = [
|
||||
"ark-ff-asm",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"derivative",
|
||||
"num-traits",
|
||||
"rand",
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-ff-asm"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/arkworks-rs/algebra#d5202f896ca9700c5c22d7a1266ada600f913dc4"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-mnt4-298"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-curve-tests",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-mnt4-753"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-curve-tests",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-mnt6-298"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-curve-tests",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-mnt4-298",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-mnt6-753"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-curve-tests",
|
||||
"ark-ec",
|
||||
"ark-ff",
|
||||
"ark-mnt4-753",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-serialize"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/arkworks-rs/algebra#d5202f896ca9700c5c22d7a1266ada600f913dc4"
|
||||
dependencies = [
|
||||
"ark-std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-std"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/arkworks-rs/utils#7bde3ab01799da8429b8fa9c3f152201415cdfe7"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0520af26d4cf99643dbbe093a61507922b57232d9978d8491fdc8f7b44573c8c"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e03e57e4fcbfe7749842d53e24ccb9aa12b7252dbe5e91d2acad31834c8b8fdd"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
52
Cargo.toml
Normal file
52
Cargo.toml
Normal file
@@ -0,0 +1,52 @@
|
||||
[workspace]
|
||||
|
||||
members = [
|
||||
"curve-benches",
|
||||
"curve-tests",
|
||||
|
||||
"bls12_377",
|
||||
"ed_on_bls12_377",
|
||||
|
||||
"bw6_761",
|
||||
"ed_on_bw6_761",
|
||||
|
||||
"cp6_782",
|
||||
"ed_on_cp6_782",
|
||||
|
||||
"bls12_381",
|
||||
"ed_on_bls12_381",
|
||||
|
||||
"bn254",
|
||||
"ed_on_bn254",
|
||||
|
||||
"mnt4_298",
|
||||
"mnt6_298",
|
||||
"ed_on_mnt4_298",
|
||||
|
||||
"mnt4_753",
|
||||
"mnt6_753",
|
||||
"ed_on_mnt4_298",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
lto = "thin"
|
||||
incremental = true
|
||||
|
||||
[profile.bench]
|
||||
opt-level = 3
|
||||
debug = false
|
||||
rpath = false
|
||||
lto = "thin"
|
||||
incremental = true
|
||||
debug-assertions = false
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 0
|
||||
|
||||
[profile.test]
|
||||
opt-level = 3
|
||||
lto = "thin"
|
||||
incremental = true
|
||||
debug-assertions = true
|
||||
debug = true
|
||||
201
LICENSE-APACHE
Normal file
201
LICENSE-APACHE
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
19
LICENSE-MIT
Normal file
19
LICENSE-MIT
Normal file
@@ -0,0 +1,19 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
31
README.md
Normal file
31
README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Curve implementations
|
||||
|
||||
This directory contains implementations of some popular elliptic curves.
|
||||
|
||||
### BLS12-381 and embedded curves
|
||||
* [`ark-bls12-381`](bls12-381): Implements the BLS12-381 pairing-friendly curve
|
||||
* [`ark-ed-on-bls12-381`](ed-on-bls12-381): Implements a Twisted Edwards curve atop the scalar field of BLS12-381
|
||||
|
||||
### BLS12-377 and related curves
|
||||
* [`ark-bls12-377`](bls12-377): Implements the BLS12-377 pairing-friendly curve
|
||||
* [`ark-ed-on-bls12-377`](ed-on-bls12-377): Implements a Twisted Edwards curve atop the scalar field of BLS12-377
|
||||
|
||||
* [`ark-bw6-761`](bw6-761): Implements the BW6-761 pairing-friendly curve, which is a curve whose scalar field equals the base field of BLS12-377
|
||||
* [`ark-ed-on-bw6-761`](ed-on-bw6-761): Implements a Twisted Edwards curve atop the scalar field of BW6-761
|
||||
|
||||
* [`ark-cp6-782`](cp6-782): Implements the CP6-782 pairing-friendly curve, which is a curve whose scalar field equals the base field of BLS12-377
|
||||
* [`ark-ed-on-cp6-782`](ed-on-cp6-782): Implements a Twisted Edwards curve atop the scalar field of CP6-782. This is the same curve as in `ark-ed-on-bw6-761`
|
||||
|
||||
### BN254 and related curves
|
||||
* [`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
|
||||
|
||||
### 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-mnt6-298`](mnt6-298): Implements the MNT6-298 pairing-friendly curve. This curve forms a pairing-friendly cycle with MNT4-298
|
||||
* [`ark-ed-on-mnt4-298`](ed-on-mnt4-298): Implements a Twisted Edwards curve atop the scalar field of MNT4-298
|
||||
|
||||
### MNT-753 cycle of curves and related curves
|
||||
* [`ark-mnt4-753`](mnt4-753): Implements the MNT4-753 pairing-friendly curve. This curve forms a pairing-friendly cycle with MNT6-753
|
||||
* [`ark-mnt6-753`](mnt6-753): Implements the MNT6-753 pairing-friendly curve. This curve forms a pairing-friendly cycle with MNT4-753
|
||||
* [`ark-ed-on-mnt4-753`](ed-on-mnt4-753): Implements a Twisted Edwards curve atop the scalar field of MNT4-753
|
||||
32
bls12_377/Cargo.toml
Normal file
32
bls12_377/Cargo.toml
Normal file
@@ -0,0 +1,32 @@
|
||||
[package]
|
||||
name = "ark-bls12-377"
|
||||
version = "0.1.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The BLS12-377 pairing-friendly elliptic curve"
|
||||
homepage = "https://arworks.rs"
|
||||
repository = "https://github.com/arkworks/algebra"
|
||||
documentation = "https://docs.rs/ark-bls12-377/"
|
||||
keywords = ["cryptography", "finite fields", "elliptic curves" ]
|
||||
categories = ["cryptography"]
|
||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
license = "MIT/Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
ark-ff = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-ec = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
ark-serialize = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-curve-tests = { path = "../curve-tests", default-features = false }
|
||||
rand = { version = "0.7", default-features = false }
|
||||
rand_xorshift = "0.2"
|
||||
|
||||
[features]
|
||||
default = [ "curve" ]
|
||||
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ]
|
||||
|
||||
curve = [ "scalar_field", "base_field" ]
|
||||
scalar_field = []
|
||||
base_field = []
|
||||
1
bls12_377/LICENSE-APACHE
Symbolic link
1
bls12_377/LICENSE-APACHE
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE-APACHE
|
||||
1
bls12_377/LICENSE-MIT
Symbolic link
1
bls12_377/LICENSE-MIT
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE-MIT
|
||||
77
bls12_377/src/curves/g1.rs
Normal file
77
bls12_377/src/curves/g1.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use ark_ec::models::{ModelParameters, SWModelParameters};
|
||||
use ark_ff::{
|
||||
biginteger::{BigInteger256, BigInteger384},
|
||||
field_new, Zero,
|
||||
};
|
||||
|
||||
use crate::{Fq, Fr};
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct Parameters;
|
||||
|
||||
impl ModelParameters for Parameters {
|
||||
type BaseField = Fq;
|
||||
type ScalarField = Fr;
|
||||
}
|
||||
|
||||
impl SWModelParameters for Parameters {
|
||||
/// COEFF_A = 0
|
||||
const COEFF_A: Fq = field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0]));
|
||||
|
||||
/// COEFF_B = 1
|
||||
#[rustfmt::skip]
|
||||
const COEFF_B: Fq = field_new!(Fq, BigInteger384([
|
||||
0x2cdffffffffff68,
|
||||
0x51409f837fffffb1,
|
||||
0x9f7db3a98a7d3ff2,
|
||||
0x7b4e97b76e7c6305,
|
||||
0x4cf495bf803c84e8,
|
||||
0x8d6661e2fdf49a,
|
||||
]));
|
||||
|
||||
/// 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, BigInteger256([
|
||||
2013239619100046060,
|
||||
4201184776506987597,
|
||||
2526766393982337036,
|
||||
1114629510922847535,
|
||||
]));
|
||||
|
||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||
(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
||||
Self::BaseField::zero()
|
||||
}
|
||||
}
|
||||
|
||||
/// G1_GENERATOR_X =
|
||||
/// 81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695
|
||||
#[rustfmt::skip]
|
||||
pub const G1_GENERATOR_X: Fq = field_new!(Fq, BigInteger384([
|
||||
0x260f33b9772451f4,
|
||||
0xc54dd773169d5658,
|
||||
0x5c1551c469a510dd,
|
||||
0x761662e4425e1698,
|
||||
0xc97d78cc6f065272,
|
||||
0xa41206b361fd4d,
|
||||
]));
|
||||
|
||||
/// G1_GENERATOR_Y =
|
||||
/// 241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030
|
||||
#[rustfmt::skip]
|
||||
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, BigInteger384([
|
||||
0x8193961fb8cb81f3,
|
||||
0x638d4c5f44adb8,
|
||||
0xfafaf3dad4daf54a,
|
||||
0xc27849e2d655cd18,
|
||||
0x2ec3ddb401d52814,
|
||||
0x7da93326303c71,
|
||||
]));
|
||||
129
bls12_377/src/curves/g2.rs
Normal file
129
bls12_377/src/curves/g2.rs
Normal file
@@ -0,0 +1,129 @@
|
||||
use ark_ec::models::{ModelParameters, SWModelParameters};
|
||||
use ark_ff::{
|
||||
biginteger::{BigInteger256, BigInteger384},
|
||||
field_new, Zero,
|
||||
};
|
||||
|
||||
use crate::{g1, Fq, Fq2, Fr};
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct Parameters;
|
||||
|
||||
impl ModelParameters for Parameters {
|
||||
type BaseField = Fq2;
|
||||
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,
|
||||
field_new!(Fq, BigInteger384([0, 0, 0, 0, 0, 0])),
|
||||
field_new!(Fq, BigInteger384([
|
||||
9255502405446297221,
|
||||
10229180150694123945,
|
||||
9215585410771530959,
|
||||
13357015519562362907,
|
||||
5437107869987383107,
|
||||
16259554076827459,
|
||||
])),
|
||||
);
|
||||
|
||||
/// COFACTOR =
|
||||
/// 7923214915284317143930293550643874566881017850177945424769256759165301436616933228209277966774092486467289478618404761412630691835764674559376407658497
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR: &'static [u64] = &[
|
||||
0x0000000000000001,
|
||||
0x452217cc90000000,
|
||||
0xa0f3622fba094800,
|
||||
0xd693e8c36676bd09,
|
||||
0x8c505634fae2e189,
|
||||
0xfbb36b00e1dcc40c,
|
||||
0xddd88d99a6f6a829,
|
||||
0x26ba558ae9562a,
|
||||
];
|
||||
|
||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||
/// = 6764900296503390671038341982857278410319949526107311149686707033187604810669
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger256([
|
||||
15499857013495546999,
|
||||
4613531467548868169,
|
||||
14546778081091178013,
|
||||
549402535258503313,
|
||||
]));
|
||||
|
||||
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||
(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
||||
Self::BaseField::zero()
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_X: Fq2 = field_new!(Fq2, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
|
||||
|
||||
/// G2_GENERATOR_X_C0 =
|
||||
/// 233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, BigInteger384([
|
||||
0x68904082f268725b,
|
||||
0x668f2ea74f45328b,
|
||||
0xebca7a65802be84f,
|
||||
0x1e1850f4c1ada3e6,
|
||||
0x830dc22d588ef1e9,
|
||||
0x1862a81767c0982,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_X_C1 =
|
||||
/// 140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, BigInteger384([
|
||||
0x5f02a915c91c7f39,
|
||||
0xf8c553ba388da2a7,
|
||||
0xd51a416dbd198850,
|
||||
0xe943c6f38ae3073a,
|
||||
0xffe24aa8259a4981,
|
||||
0x11853391e73dfdd,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_Y_C0 =
|
||||
/// 63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, BigInteger384([
|
||||
0xd5b19b897881430f,
|
||||
0x5be9118a5b371ed,
|
||||
0x6063f91f86c131ee,
|
||||
0x3244a61be8f4ec19,
|
||||
0xa02e425b9f9a3a12,
|
||||
0x18af8c04f3360d2,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_Y_C1 =
|
||||
/// 149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, BigInteger384([
|
||||
0x57601ac71a5b96f5,
|
||||
0xe99acc1714f2440e,
|
||||
0x2339612f10118ea9,
|
||||
0x8321e68a3b1cd722,
|
||||
0x2b543b050cc74917,
|
||||
0x590182b396c112,
|
||||
]));
|
||||
33
bls12_377/src/curves/mod.rs
Normal file
33
bls12_377/src/curves/mod.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
use crate::*;
|
||||
use ark_ec::{
|
||||
bls12,
|
||||
bls12::{Bls12, Bls12Parameters, TwistType},
|
||||
};
|
||||
|
||||
pub mod g1;
|
||||
pub mod g2;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub struct Parameters;
|
||||
|
||||
impl Bls12Parameters for Parameters {
|
||||
const X: &'static [u64] = &[0x8508c00000000001];
|
||||
/// `x` is positive.
|
||||
const X_IS_NEGATIVE: bool = false;
|
||||
const TWIST_TYPE: TwistType = TwistType::D;
|
||||
type Fp = Fq;
|
||||
type Fp2Params = Fq2Parameters;
|
||||
type Fp6Params = Fq6Parameters;
|
||||
type Fp12Params = Fq12Parameters;
|
||||
type G1Parameters = g1::Parameters;
|
||||
type G2Parameters = g2::Parameters;
|
||||
}
|
||||
|
||||
pub type Bls12_377 = Bls12<Parameters>;
|
||||
|
||||
pub type G1Affine = bls12::G1Affine<Parameters>;
|
||||
pub type G1Projective = bls12::G1Projective<Parameters>;
|
||||
pub type G2Affine = bls12::G2Affine<Parameters>;
|
||||
pub type G2Projective = bls12::G2Projective<Parameters>;
|
||||
121
bls12_377/src/curves/tests.rs
Normal file
121
bls12_377/src/curves/tests.rs
Normal file
@@ -0,0 +1,121 @@
|
||||
#![allow(unused_imports)]
|
||||
use ark_ff::{
|
||||
fields::{Field, FpParameters, PrimeField, SquareRootField},
|
||||
test_rng, One, Zero,
|
||||
};
|
||||
use ark_serialize::CanonicalSerialize;
|
||||
|
||||
use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine, ProjectiveCurve};
|
||||
use core::ops::{AddAssign, MulAssign};
|
||||
use rand::Rng;
|
||||
|
||||
use crate::{g1, g2, Bls12_377, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
|
||||
|
||||
use ark_curve_tests::{
|
||||
curves::{curve_tests, sw_tests},
|
||||
groups::group_test,
|
||||
};
|
||||
|
||||
#[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_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());
|
||||
}
|
||||
}
|
||||
114
bls12_377/src/fields/fq.rs
Normal file
114
bls12_377/src/fields/fq.rs
Normal file
@@ -0,0 +1,114 @@
|
||||
use ark_ff::{biginteger::BigInteger384 as BigInteger, field_new, fields::*};
|
||||
|
||||
pub type Fq = Fp384<FqParameters>;
|
||||
|
||||
pub struct FqParameters;
|
||||
|
||||
impl Fp384Parameters for FqParameters {}
|
||||
impl FftParameters for FqParameters {
|
||||
type BigInt = BigInteger;
|
||||
|
||||
const TWO_ADICITY: u32 = 46u32;
|
||||
|
||||
#[rustfmt::skip]
|
||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = 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;
|
||||
|
||||
#[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
|
||||
#[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
|
||||
|
||||
// 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 = field_new!(Fq, FqParameters::R);
|
||||
#[allow(dead_code)]
|
||||
pub const FQ_ZERO: Fq = field_new!(Fq, BigInteger([0, 0, 0, 0, 0, 0]));
|
||||
161
bls12_377/src/fields/fq12.rs
Normal file
161
bls12_377/src/fields/fq12.rs
Normal file
@@ -0,0 +1,161 @@
|
||||
use super::*;
|
||||
use ark_ff::{biginteger::BigInteger384, field_new, fields::*};
|
||||
|
||||
pub type Fq12 = Fp12<Fq12Parameters>;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Fq12Parameters;
|
||||
|
||||
impl Fp12Parameters for Fq12Parameters {
|
||||
type Fp6Params = Fq6Parameters;
|
||||
|
||||
const NONRESIDUE: Fq6 = field_new!(Fq6, FQ2_ZERO, FQ2_ONE, FQ2_ZERO);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[
|
||||
// Fp2::NONRESIDUE^(((q^0) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x2cdffffffffff68,
|
||||
0x51409f837fffffb1,
|
||||
0x9f7db3a98a7d3ff2,
|
||||
0x7b4e97b76e7c6305,
|
||||
0x4cf495bf803c84e8,
|
||||
0x8d6661e2fdf49a,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x6ec47a04a3f7ca9e,
|
||||
0xa42e0cb968c1fa44,
|
||||
0x578d5187fbd2bd23,
|
||||
0x930eeb0ac79dd4bd,
|
||||
0xa24883de1e09a9ee,
|
||||
0xdaa7058067d46f,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x5892506da58478da,
|
||||
0x133366940ac2a74b,
|
||||
0x9b64a150cdf726cf,
|
||||
0x5cc426090a9c587e,
|
||||
0x5cf848adfdcd640c,
|
||||
0x4702bf3ac02380,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x982c13d9d084771f,
|
||||
0xfd49de0c6da34a32,
|
||||
0x61a530d183ab0e53,
|
||||
0xdf8fe44106dd9879,
|
||||
0x40f29b58d88472bc,
|
||||
0x158723199046d5d,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xdacd106da5847973,
|
||||
0xd8fe2454bac2a79a,
|
||||
0x1ada4fd6fd832edc,
|
||||
0xfb9868449d150908,
|
||||
0xd63eb8aeea32285e,
|
||||
0x167d6a36f873fd0,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x296799d52c8cac81,
|
||||
0x591bd15304e14fee,
|
||||
0xa17df4987d85130,
|
||||
0x4c80f9363f3fc3bc,
|
||||
0x9eaa177aba7ac8ce,
|
||||
0x7dcb2c189c98ed,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^6) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x823ac00000000099,
|
||||
0xc5cabdc0b000004f,
|
||||
0x7f75ae862f8c080d,
|
||||
0x9ed4423b9278b089,
|
||||
0x79467000ec64c452,
|
||||
0x120d3e434c71c50,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^7) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x164445fb5c083563,
|
||||
0x72dd508ac73e05bc,
|
||||
0xc76610a7be368adc,
|
||||
0x8713eee839573ed1,
|
||||
0x23f281e24e979f4c,
|
||||
0xd39340975d3c7b,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^8) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x2c766f925a7b8727,
|
||||
0x3d7f6b0253d58b5,
|
||||
0x838ec0deec122131,
|
||||
0xbd5eb3e9f658bb10,
|
||||
0x6942bd126ed3e52e,
|
||||
0x1673786dd04ed6a,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^9) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xecdcac262f7b88e2,
|
||||
0x19c17f37c25cb5cd,
|
||||
0xbd4e315e365e39ac,
|
||||
0x3a92f5b1fa177b15,
|
||||
0x85486a67941cd67e,
|
||||
0x55c8147ec0a38d,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^10) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xaa3baf925a7b868e,
|
||||
0x3e0d38ef753d5865,
|
||||
0x4191258bc861923,
|
||||
0x1e8a71ae63e00a87,
|
||||
0xeffc4d11826f20dc,
|
||||
0x4663a2a83dd119,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^11) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x5ba1262ad3735380,
|
||||
0xbdef8bf12b1eb012,
|
||||
0x14db82e63230f6cf,
|
||||
0xcda1e0bcc1b54fd3,
|
||||
0x2790ee45b226806c,
|
||||
0x1306f19ff2877fd,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
];
|
||||
}
|
||||
69
bls12_377/src/fields/fq2.rs
Normal file
69
bls12_377/src/fields/fq2.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
use super::*;
|
||||
use ark_ff::{biginteger::BigInteger384 as BigInteger, field_new, fields::*};
|
||||
|
||||
pub type Fq2 = Fp2<Fq2Parameters>;
|
||||
|
||||
pub struct Fq2Parameters;
|
||||
|
||||
impl Fp2Parameters for Fq2Parameters {
|
||||
type Fp = Fq;
|
||||
|
||||
/// NONRESIDUE = -5
|
||||
#[rustfmt::skip]
|
||||
const NONRESIDUE: Fq = field_new!(Fq, BigInteger([
|
||||
0xfc0b8000000002fa,
|
||||
0x97d39cf6e000018b,
|
||||
0x2072420fbfa05044,
|
||||
0xcbbcbd50d97c3802,
|
||||
0xbaf1ec35813f9eb,
|
||||
0x9974a2c0945ad2,
|
||||
]));
|
||||
|
||||
/// QUADRATIC_NONRESIDUE = U
|
||||
#[rustfmt::skip]
|
||||
const QUADRATIC_NONRESIDUE: (Fq, Fq) = (
|
||||
field_new!(Fq, BigInteger([0, 0, 0, 0, 0, 0])),
|
||||
field_new!(Fq, BigInteger([
|
||||
202099033278250856u64,
|
||||
5854854902718660529u64,
|
||||
11492539364873682930u64,
|
||||
8885205928937022213u64,
|
||||
5545221690922665192u64,
|
||||
39800542322357402u64,
|
||||
])),
|
||||
);
|
||||
|
||||
/// Coefficients for the Frobenius automorphism.
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[
|
||||
// NONRESIDUE**(((q^0) - 1) / 2)
|
||||
field_new!(Fq, BigInteger([
|
||||
0x2cdffffffffff68,
|
||||
0x51409f837fffffb1,
|
||||
0x9f7db3a98a7d3ff2,
|
||||
0x7b4e97b76e7c6305,
|
||||
0x4cf495bf803c84e8,
|
||||
0x8d6661e2fdf49a,
|
||||
])),
|
||||
// NONRESIDUE**(((q^1) - 1) / 2)
|
||||
field_new!(Fq, BigInteger([
|
||||
0x823ac00000000099,
|
||||
0xc5cabdc0b000004f,
|
||||
0x7f75ae862f8c080d,
|
||||
0x9ed4423b9278b089,
|
||||
0x79467000ec64c452,
|
||||
0x120d3e434c71c50,
|
||||
])),
|
||||
];
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_fp_by_nonresidue(fe: &Self::Fp) -> Self::Fp {
|
||||
let original = fe;
|
||||
let mut fe = -fe.double();
|
||||
fe.double_in_place();
|
||||
fe - 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);
|
||||
184
bls12_377/src/fields/fq6.rs
Normal file
184
bls12_377/src/fields/fq6.rs
Normal file
@@ -0,0 +1,184 @@
|
||||
use super::*;
|
||||
use ark_ff::{biginteger::BigInteger384, field_new, fields::*};
|
||||
|
||||
pub type Fq6 = Fp6<Fq6Parameters>;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Fq6Parameters;
|
||||
|
||||
impl Fp6Parameters for Fq6Parameters {
|
||||
type Fp2Params = Fq2Parameters;
|
||||
|
||||
/// NONRESIDUE = U
|
||||
#[rustfmt::skip]
|
||||
const NONRESIDUE: Fq2 = field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([0, 0, 0, 0, 0, 0])),
|
||||
field_new!(Fq, BigInteger384([
|
||||
202099033278250856u64,
|
||||
5854854902718660529u64,
|
||||
11492539364873682930u64,
|
||||
8885205928937022213u64,
|
||||
5545221690922665192u64,
|
||||
39800542322357402u64,
|
||||
])),
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[
|
||||
// Fp2::NONRESIDUE^(((q^0) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x2cdffffffffff68,
|
||||
0x51409f837fffffb1,
|
||||
0x9f7db3a98a7d3ff2,
|
||||
0x7b4e97b76e7c6305,
|
||||
0x4cf495bf803c84e8,
|
||||
0x8d6661e2fdf49a,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x5892506da58478da,
|
||||
0x133366940ac2a74b,
|
||||
0x9b64a150cdf726cf,
|
||||
0x5cc426090a9c587e,
|
||||
0x5cf848adfdcd640c,
|
||||
0x4702bf3ac02380,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xdacd106da5847973,
|
||||
0xd8fe2454bac2a79a,
|
||||
0x1ada4fd6fd832edc,
|
||||
0xfb9868449d150908,
|
||||
0xd63eb8aeea32285e,
|
||||
0x167d6a36f873fd0,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x823ac00000000099,
|
||||
0xc5cabdc0b000004f,
|
||||
0x7f75ae862f8c080d,
|
||||
0x9ed4423b9278b089,
|
||||
0x79467000ec64c452,
|
||||
0x120d3e434c71c50,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x2c766f925a7b8727,
|
||||
0x3d7f6b0253d58b5,
|
||||
0x838ec0deec122131,
|
||||
0xbd5eb3e9f658bb10,
|
||||
0x6942bd126ed3e52e,
|
||||
0x1673786dd04ed6a,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xaa3baf925a7b868e,
|
||||
0x3e0d38ef753d5865,
|
||||
0x4191258bc861923,
|
||||
0x1e8a71ae63e00a87,
|
||||
0xeffc4d11826f20dc,
|
||||
0x4663a2a83dd119,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
];
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[
|
||||
// Fp2::NONRESIDUE^((2*(q^0) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x2cdffffffffff68,
|
||||
0x51409f837fffffb1,
|
||||
0x9f7db3a98a7d3ff2,
|
||||
0x7b4e97b76e7c6305,
|
||||
0x4cf495bf803c84e8,
|
||||
0x8d6661e2fdf49a,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^((2*(q^1) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xdacd106da5847973,
|
||||
0xd8fe2454bac2a79a,
|
||||
0x1ada4fd6fd832edc,
|
||||
0xfb9868449d150908,
|
||||
0xd63eb8aeea32285e,
|
||||
0x167d6a36f873fd0,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^((2*(q^2) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x2c766f925a7b8727,
|
||||
0x3d7f6b0253d58b5,
|
||||
0x838ec0deec122131,
|
||||
0xbd5eb3e9f658bb10,
|
||||
0x6942bd126ed3e52e,
|
||||
0x1673786dd04ed6a,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^((2*(q^3) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x2cdffffffffff68,
|
||||
0x51409f837fffffb1,
|
||||
0x9f7db3a98a7d3ff2,
|
||||
0x7b4e97b76e7c6305,
|
||||
0x4cf495bf803c84e8,
|
||||
0x8d6661e2fdf49a,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^((2*(q^4) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xdacd106da5847973,
|
||||
0xd8fe2454bac2a79a,
|
||||
0x1ada4fd6fd832edc,
|
||||
0xfb9868449d150908,
|
||||
0xd63eb8aeea32285e,
|
||||
0x167d6a36f873fd0,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^((2*(q^5) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x2c766f925a7b8727,
|
||||
0x3d7f6b0253d58b5,
|
||||
0x838ec0deec122131,
|
||||
0xbd5eb3e9f658bb10,
|
||||
0x6942bd126ed3e52e,
|
||||
0x1673786dd04ed6a,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
];
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_fp2_by_nonresidue(fe: &Fq2) -> Fq2 {
|
||||
// Karatsuba multiplication with constant other = u.
|
||||
let c0 = Fq2Parameters::mul_fp_by_nonresidue(&fe.c1);
|
||||
let c1 = fe.c0;
|
||||
field_new!(Fq2, c0, c1)
|
||||
}
|
||||
}
|
||||
95
bls12_377/src/fields/fr.rs
Normal file
95
bls12_377/src/fields/fr.rs
Normal file
@@ -0,0 +1,95 @@
|
||||
use ark_ff::{biginteger::BigInteger256 as BigInteger, fields::*};
|
||||
|
||||
pub type Fr = Fp256<FrParameters>;
|
||||
|
||||
pub struct FrParameters;
|
||||
|
||||
impl Fp256Parameters for FrParameters {}
|
||||
impl FftParameters for FrParameters {
|
||||
type BigInt = BigInteger;
|
||||
|
||||
const TWO_ADICITY: u32 = 47;
|
||||
|
||||
#[rustfmt::skip]
|
||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
||||
0x3c3d3ca739381fb2,
|
||||
0x9a14cda3ec99772b,
|
||||
0xd7aacc7c59724826,
|
||||
0xd1ba211c5cc349c,
|
||||
]);
|
||||
}
|
||||
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;
|
||||
|
||||
#[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 = 11
|
||||
#[rustfmt::skip]
|
||||
const GENERATOR: BigInteger = BigInteger([
|
||||
1855201571499933546u64,
|
||||
8511318076631809892u64,
|
||||
6222514765367795509u64,
|
||||
1122129207579058019u64,
|
||||
]);
|
||||
|
||||
/// (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
|
||||
|
||||
/// 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,
|
||||
]);
|
||||
}
|
||||
27
bls12_377/src/fields/mod.rs
Normal file
27
bls12_377/src/fields/mod.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
#[cfg(feature = "scalar_field")]
|
||||
pub mod fr;
|
||||
#[cfg(feature = "scalar_field")]
|
||||
pub use self::fr::*;
|
||||
|
||||
#[cfg(feature = "base_field")]
|
||||
pub mod fq;
|
||||
#[cfg(feature = "base_field")]
|
||||
pub use self::fq::*;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub mod fq2;
|
||||
#[cfg(feature = "curve")]
|
||||
pub use self::fq2::*;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub mod fq6;
|
||||
#[cfg(feature = "curve")]
|
||||
pub use self::fq6::*;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub mod fq12;
|
||||
#[cfg(feature = "curve")]
|
||||
pub use self::fq12::*;
|
||||
|
||||
#[cfg(all(feature = "curve", test))]
|
||||
mod tests;
|
||||
530
bls12_377/src/fields/tests.rs
Normal file
530
bls12_377/src/fields/tests.rs
Normal file
@@ -0,0 +1,530 @@
|
||||
use ark_ff::{
|
||||
biginteger::{BigInteger, BigInteger384},
|
||||
fields::{
|
||||
fp6_3over2::Fp6Parameters, FftField, FftParameters, Field, Fp2Parameters, FpParameters,
|
||||
PrimeField, SquareRootField,
|
||||
},
|
||||
test_rng, One, UniformRand, Zero,
|
||||
};
|
||||
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
||||
use core::{
|
||||
cmp::Ordering,
|
||||
ops::{AddAssign, MulAssign, SubAssign},
|
||||
};
|
||||
use rand::{Rng, SeedableRng};
|
||||
use rand_xorshift::XorShiftRng;
|
||||
|
||||
use crate::{Fq, Fq12, Fq2, Fq2Parameters, Fq6, Fq6Parameters, FqParameters, Fr};
|
||||
|
||||
use ark_curve_tests::fields::*;
|
||||
|
||||
pub(crate) const ITERATIONS: usize = 5;
|
||||
|
||||
#[test]
|
||||
fn test_fr() {
|
||||
let mut rng = test_rng();
|
||||
for _ in 0..ITERATIONS {
|
||||
let a: Fr = rng.gen();
|
||||
let b: Fr = rng.gen();
|
||||
field_test(a, b);
|
||||
primefield_test::<Fr>();
|
||||
sqrt_field_test(b);
|
||||
let byte_size = a.serialized_size();
|
||||
field_serialization_test::<Fr>(byte_size);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq() {
|
||||
let mut rng = test_rng();
|
||||
for _ in 0..ITERATIONS {
|
||||
let a: Fq = rng.gen();
|
||||
let b: Fq = rng.gen();
|
||||
field_test(a, b);
|
||||
primefield_test::<Fq>();
|
||||
sqrt_field_test(a);
|
||||
let byte_size = a.serialized_size();
|
||||
let (_, buffer_size) = buffer_bit_byte_size(Fq::size_in_bits());
|
||||
assert_eq!(byte_size, buffer_size);
|
||||
field_serialization_test::<Fq>(byte_size);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq2() {
|
||||
let mut rng = test_rng();
|
||||
for _ in 0..ITERATIONS {
|
||||
let a: Fq2 = rng.gen();
|
||||
let b: Fq2 = rng.gen();
|
||||
field_test(a, b);
|
||||
sqrt_field_test(a);
|
||||
}
|
||||
frobenius_test::<Fq2, _>(Fq::characteristic(), 13);
|
||||
let byte_size = Fq2::zero().serialized_size();
|
||||
field_serialization_test::<Fq2>(byte_size);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq6() {
|
||||
let mut rng = test_rng();
|
||||
for _ in 0..ITERATIONS {
|
||||
let g: Fq6 = rng.gen();
|
||||
let h: Fq6 = rng.gen();
|
||||
field_test(g, h);
|
||||
}
|
||||
frobenius_test::<Fq6, _>(Fq::characteristic(), 13);
|
||||
let byte_size = Fq6::zero().serialized_size();
|
||||
field_serialization_test::<Fq6>(byte_size);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq12() {
|
||||
let mut rng = test_rng();
|
||||
for _ in 0..ITERATIONS {
|
||||
let g: Fq12 = rng.gen();
|
||||
let h: Fq12 = rng.gen();
|
||||
field_test(g, h);
|
||||
}
|
||||
frobenius_test::<Fq12, _>(Fq::characteristic(), 13);
|
||||
let byte_size = Fq12::zero().serialized_size();
|
||||
field_serialization_test::<Fq12>(byte_size);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_repr_from() {
|
||||
assert_eq!(
|
||||
BigInteger384::from(100),
|
||||
BigInteger384([100, 0, 0, 0, 0, 0])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_repr_is_odd() {
|
||||
assert!(!BigInteger384::from(0).is_odd());
|
||||
assert!(BigInteger384::from(0).is_even());
|
||||
assert!(BigInteger384::from(1).is_odd());
|
||||
assert!(!BigInteger384::from(1).is_even());
|
||||
assert!(!BigInteger384::from(324834872).is_odd());
|
||||
assert!(BigInteger384::from(324834872).is_even());
|
||||
assert!(BigInteger384::from(324834873).is_odd());
|
||||
assert!(!BigInteger384::from(324834873).is_even());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_repr_is_zero() {
|
||||
assert!(BigInteger384::from(0).is_zero());
|
||||
assert!(!BigInteger384::from(1).is_zero());
|
||||
assert!(!BigInteger384([0, 0, 0, 0, 1, 0]).is_zero());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_repr_num_bits() {
|
||||
let mut a = BigInteger384::from(0);
|
||||
assert_eq!(0, a.num_bits());
|
||||
a = BigInteger384::from(1);
|
||||
for i in 1..385 {
|
||||
assert_eq!(i, a.num_bits());
|
||||
a.mul2();
|
||||
}
|
||||
assert_eq!(0, a.num_bits());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_add_assign() {
|
||||
// Test associativity
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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]
|
||||
fn test_fq_num_bits() {
|
||||
assert_eq!(FqParameters::MODULUS_BITS, 377);
|
||||
assert_eq!(FqParameters::CAPACITY, 376);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_root_of_unity() {
|
||||
assert_eq!(FqParameters::TWO_ADICITY, 46);
|
||||
assert_eq!(
|
||||
Fq::multiplicative_generator().pow([
|
||||
0x7510c00000021423,
|
||||
0x88bee82520005c2d,
|
||||
0x67cc03d44e3c7bcd,
|
||||
0x1701b28524ec688b,
|
||||
0xe9185f1443ab18ec,
|
||||
0x6b8
|
||||
]),
|
||||
Fq::two_adic_root_of_unity()
|
||||
);
|
||||
assert_eq!(
|
||||
Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]),
|
||||
Fq::one()
|
||||
);
|
||||
assert!(Fq::multiplicative_generator().sqrt().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_ordering() {
|
||||
// BigInteger384's ordering is well-tested, but we still need to make sure the
|
||||
// Fq elements aren't being compared in Montgomery form.
|
||||
for i in 0..100 {
|
||||
assert!(Fq::from(BigInteger384::from(i + 1)) > Fq::from(BigInteger384::from(i)));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_legendre() {
|
||||
use ark_ff::fields::LegendreSymbol::*;
|
||||
|
||||
assert_eq!(QuadraticResidue, Fq::one().legendre());
|
||||
assert_eq!(Zero, Fq::zero().legendre());
|
||||
assert_eq!(
|
||||
QuadraticResidue,
|
||||
Fq::from(BigInteger384::from(4)).legendre()
|
||||
);
|
||||
assert_eq!(
|
||||
QuadraticNonResidue,
|
||||
Fq::from(BigInteger384::from(5)).legendre()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq2_ordering() {
|
||||
let mut a = Fq2::new(Fq::zero(), Fq::zero());
|
||||
let mut b = a.clone();
|
||||
|
||||
assert!(a.cmp(&b) == Ordering::Equal);
|
||||
b.c0.add_assign(&Fq::one());
|
||||
assert!(a.cmp(&b) == Ordering::Less);
|
||||
a.c0.add_assign(&Fq::one());
|
||||
assert!(a.cmp(&b) == Ordering::Equal);
|
||||
b.c1.add_assign(&Fq::one());
|
||||
assert!(a.cmp(&b) == Ordering::Less);
|
||||
a.c0.add_assign(&Fq::one());
|
||||
assert!(a.cmp(&b) == Ordering::Less);
|
||||
a.c1.add_assign(&Fq::one());
|
||||
assert!(a.cmp(&b) == Ordering::Greater);
|
||||
b.c0.add_assign(&Fq::one());
|
||||
assert!(a.cmp(&b) == Ordering::Equal);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq2_basics() {
|
||||
assert_eq!(Fq2::new(Fq::zero(), Fq::zero(),), Fq2::zero());
|
||||
assert_eq!(Fq2::new(Fq::one(), Fq::zero(),), Fq2::one());
|
||||
assert!(Fq2::zero().is_zero());
|
||||
assert!(!Fq2::one().is_zero());
|
||||
assert!(!Fq2::new(Fq::zero(), Fq::one(),).is_zero());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq2_legendre() {
|
||||
use ark_ff::fields::LegendreSymbol::*;
|
||||
|
||||
assert_eq!(Zero, Fq2::zero().legendre());
|
||||
// i^2 = -1
|
||||
let mut m1 = -Fq2::one();
|
||||
assert_eq!(QuadraticResidue, m1.legendre());
|
||||
m1 = Fq6Parameters::mul_fp2_by_nonresidue(&m1);
|
||||
assert_eq!(QuadraticNonResidue, m1.legendre());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq2_mul_nonresidue() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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]
|
||||
fn test_fq6_mul_by_1() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..1000 {
|
||||
let c1 = Fq2::rand(&mut rng);
|
||||
let mut a = Fq6::rand(&mut rng);
|
||||
let mut b = a;
|
||||
|
||||
a.mul_by_1(&c1);
|
||||
b.mul_assign(&Fq6::new(Fq2::zero(), c1, Fq2::zero()));
|
||||
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq6_mul_by_01() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..1000 {
|
||||
let c0 = Fq2::rand(&mut rng);
|
||||
let c1 = Fq2::rand(&mut rng);
|
||||
let mut a = Fq6::rand(&mut rng);
|
||||
let mut b = a;
|
||||
|
||||
a.mul_by_01(&c0, &c1);
|
||||
b.mul_assign(&Fq6::new(c0, c1, Fq2::zero()));
|
||||
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq12_mul_by_014() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..1000 {
|
||||
let c0 = Fq2::rand(&mut rng);
|
||||
let c1 = Fq2::rand(&mut rng);
|
||||
let c5 = Fq2::rand(&mut rng);
|
||||
let mut a = Fq12::rand(&mut rng);
|
||||
let mut b = a;
|
||||
|
||||
a.mul_by_014(&c0, &c1, &c5);
|
||||
b.mul_assign(&Fq12::new(
|
||||
Fq6::new(c0, c1, Fq2::zero()),
|
||||
Fq6::new(Fq2::zero(), c5, Fq2::zero()),
|
||||
));
|
||||
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq12_mul_by_034() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..1000 {
|
||||
let c0 = Fq2::rand(&mut rng);
|
||||
let c3 = Fq2::rand(&mut rng);
|
||||
let c4 = Fq2::rand(&mut rng);
|
||||
let mut a = Fq12::rand(&mut rng);
|
||||
let mut b = a;
|
||||
|
||||
a.mul_by_034(&c0, &c3, &c4);
|
||||
b.mul_assign(&Fq12::new(
|
||||
Fq6::new(c0, Fq2::zero(), Fq2::zero()),
|
||||
Fq6::new(c3, c4, Fq2::zero()),
|
||||
));
|
||||
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
}
|
||||
35
bls12_377/src/lib.rs
Normal file
35
bls12_377/src/lib.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![deny(
|
||||
warnings,
|
||||
unused,
|
||||
future_incompatible,
|
||||
nonstandard_style,
|
||||
rust_2018_idioms
|
||||
)]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
//! This library implements the BLS12_377 curve generated in [[BCGMMW20, “Zexe”]](https://eprint.iacr.org/2018/962).
|
||||
//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree 12,
|
||||
//! defined over a 377-bit (prime) field. The main feature of this curve is that
|
||||
//! both the scalar field and the base field are highly 2-adic.
|
||||
//! (This is in contrast to the BLS12_381 curve for which only the scalar field is highly 2-adic.)
|
||||
//!
|
||||
//!
|
||||
//! Curve information:
|
||||
//! * Base field: q = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
|
||||
//! * Scalar field: r = 8444461749428370424248824938781546531375899335154063827935233455917409239041
|
||||
//! * valuation(q - 1, 2) = 46
|
||||
//! * valuation(r - 1, 2) = 47
|
||||
//! * G1 curve equation: y^2 = x^3 + 1
|
||||
//! * G2 curve equation: y^2 = x^3 + B, where
|
||||
//! * B = Fq2(0, 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906)
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
mod curves;
|
||||
|
||||
mod fields;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub use curves::*;
|
||||
|
||||
pub use fields::*;
|
||||
31
bls12_381/Cargo.toml
Normal file
31
bls12_381/Cargo.toml
Normal file
@@ -0,0 +1,31 @@
|
||||
[package]
|
||||
name = "ark-bls12-381"
|
||||
version = "0.1.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The BLS12-381 pairing-friendly elliptic curve"
|
||||
homepage = "https://arworks.rs"
|
||||
repository = "https://github.com/arkworks/algebra"
|
||||
documentation = "https://docs.rs/ark-bls12-381/"
|
||||
keywords = ["cryptography", "finite fields", "elliptic curves" ]
|
||||
categories = ["cryptography"]
|
||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
license = "MIT/Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
ark-ff = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-ec = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
ark-serialize = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-curve-tests = { path = "../curve-tests", default-features = false }
|
||||
rand = { version = "0.7", default-features = false }
|
||||
rand_xorshift = "0.2"
|
||||
|
||||
[features]
|
||||
default = [ "curve" ]
|
||||
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ]
|
||||
|
||||
curve = [ "scalar_field" ]
|
||||
scalar_field = []
|
||||
1
bls12_381/LICENSE-APACHE
Symbolic link
1
bls12_381/LICENSE-APACHE
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE-APACHE
|
||||
1
bls12_381/LICENSE-MIT
Symbolic link
1
bls12_381/LICENSE-MIT
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE-MIT
|
||||
82
bls12_381/src/curves/g1.rs
Normal file
82
bls12_381/src/curves/g1.rs
Normal file
@@ -0,0 +1,82 @@
|
||||
use crate::*;
|
||||
use ark_ec::{
|
||||
bls12,
|
||||
models::{ModelParameters, SWModelParameters},
|
||||
};
|
||||
use ark_ff::{
|
||||
biginteger::{BigInteger256, BigInteger384},
|
||||
field_new, Zero,
|
||||
};
|
||||
|
||||
pub type G1Affine = bls12::G1Affine<crate::Parameters>;
|
||||
pub type G1Projective = bls12::G1Projective<crate::Parameters>;
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct Parameters;
|
||||
|
||||
impl ModelParameters for Parameters {
|
||||
type BaseField = Fq;
|
||||
type ScalarField = Fr;
|
||||
}
|
||||
|
||||
impl SWModelParameters for Parameters {
|
||||
/// COEFF_A = 0
|
||||
const COEFF_A: Fq = field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0]));
|
||||
|
||||
/// COEFF_B = 4
|
||||
#[rustfmt::skip]
|
||||
const COEFF_B: Fq = field_new!(Fq, BigInteger384([
|
||||
0xaa270000000cfff3,
|
||||
0x53cc0032fc34000a,
|
||||
0x478fe97a6b0a807f,
|
||||
0xb1d37ebee6ba24d7,
|
||||
0x8ec9733bbf78ab2f,
|
||||
0x9d645513d83de7e,
|
||||
]));
|
||||
|
||||
/// COFACTOR = (x - 1)^2 / 3 = 76329603384216526031706109802092473003
|
||||
const COFACTOR: &'static [u64] = &[0x8c00aaab0000aaab, 0x396c8c005555e156];
|
||||
|
||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||
/// = 52435875175126190458656871551744051925719901746859129887267498875565241663483
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger256([
|
||||
288839107172787499,
|
||||
1152722415086798946,
|
||||
2612889808468387987,
|
||||
5124657601728438008,
|
||||
]));
|
||||
|
||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||
(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
||||
Self::BaseField::zero()
|
||||
}
|
||||
}
|
||||
|
||||
/// G1_GENERATOR_X =
|
||||
/// 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
|
||||
#[rustfmt::skip]
|
||||
pub const G1_GENERATOR_X: Fq = field_new!(Fq, BigInteger384([
|
||||
0x5cb38790fd530c16,
|
||||
0x7817fc679976fff5,
|
||||
0x154f95c7143ba1c1,
|
||||
0xf0ae6acdf3d0e747,
|
||||
0xedce6ecc21dbf440,
|
||||
0x120177419e0bfb75,
|
||||
]));
|
||||
|
||||
/// G1_GENERATOR_Y =
|
||||
/// 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
|
||||
#[rustfmt::skip]
|
||||
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, BigInteger384([
|
||||
0xbaac93d50ce72271,
|
||||
0x8c22631a7918fd8e,
|
||||
0xdd595f13570725ce,
|
||||
0x51ac582950405194,
|
||||
0xe1c8c3fad0059c0,
|
||||
0xbbc3efc5008a26a,
|
||||
]));
|
||||
113
bls12_381/src/curves/g2.rs
Normal file
113
bls12_381/src/curves/g2.rs
Normal file
@@ -0,0 +1,113 @@
|
||||
use crate::*;
|
||||
use ark_ec::{
|
||||
bls12,
|
||||
models::{ModelParameters, SWModelParameters},
|
||||
};
|
||||
use ark_ff::{
|
||||
biginteger::{BigInteger256, BigInteger384},
|
||||
field_new, Zero,
|
||||
};
|
||||
|
||||
pub type G2Affine = bls12::G2Affine<crate::Parameters>;
|
||||
pub type G2Projective = bls12::G2Projective<crate::Parameters>;
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct Parameters;
|
||||
|
||||
impl ModelParameters for Parameters {
|
||||
type BaseField = Fq2;
|
||||
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) //
|
||||
/// 9
|
||||
/// = 305502333931268344200999753193121504214466019254188142667664032982267604182971884026507427359259977847832272839041616661285803823378372096355777062779109
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR: &'static [u64] = &[
|
||||
0xcf1c38e31c7238e5,
|
||||
0x1616ec6e786f0c70,
|
||||
0x21537e293a6691ae,
|
||||
0xa628f1cb4d9e82ef,
|
||||
0xa68a205b2e5a7ddf,
|
||||
0xcd91de4547085aba,
|
||||
0x91d50792876a202,
|
||||
0x5d543a95414e7f1,
|
||||
];
|
||||
|
||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||
/// 26652489039290660355457965112010883481355318854675681319708643586776743290055
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger256([
|
||||
6746407649509787816,
|
||||
1304054119431494378,
|
||||
2461312685643913071,
|
||||
5956596749362435284,
|
||||
]));
|
||||
|
||||
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||
(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
||||
Self::BaseField::zero()
|
||||
}
|
||||
}
|
||||
|
||||
pub const G2_GENERATOR_X: Fq2 = field_new!(Fq2, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
||||
pub const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
|
||||
|
||||
/// G2_GENERATOR_X_C0 =
|
||||
/// 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, BigInteger384([
|
||||
0xf5f28fa202940a10,
|
||||
0xb3f5fb2687b4961a,
|
||||
0xa1a893b53e2ae580,
|
||||
0x9894999d1a3caee9,
|
||||
0x6f67b7631863366b,
|
||||
0x58191924350bcd7,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_X_C1 =
|
||||
/// 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, BigInteger384([
|
||||
0xa5a9c0759e23f606,
|
||||
0xaaa0c59dbccd60c3,
|
||||
0x3bb17e18e2867806,
|
||||
0x1b1ab6cc8541b367,
|
||||
0xc2b6ed0ef2158547,
|
||||
0x11922a097360edf3,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_Y_C0 =
|
||||
/// 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, BigInteger384([
|
||||
0x4c730af860494c4a,
|
||||
0x597cfa1f5e369c5a,
|
||||
0xe7e6856caa0a635a,
|
||||
0xbbefb5e96e0d495f,
|
||||
0x7d3a975f0ef25a2,
|
||||
0x83fd8e7e80dae5,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_Y_C1 =
|
||||
/// 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, BigInteger384([
|
||||
0xadc0fc92df64b05d,
|
||||
0x18aa270a2b1461dc,
|
||||
0x86adac6a3be4eba0,
|
||||
0x79495c4ec93da33a,
|
||||
0xe7175850a43ccaed,
|
||||
0xb2bc2a163de1bf2,
|
||||
]));
|
||||
30
bls12_381/src/curves/mod.rs
Normal file
30
bls12_381/src/curves/mod.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use ark_ec::bls12::{Bls12, Bls12Parameters, TwistType};
|
||||
|
||||
use crate::{Fq, Fq12Parameters, Fq2Parameters, Fq6Parameters};
|
||||
|
||||
pub mod g1;
|
||||
pub mod g2;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use self::{
|
||||
g1::{G1Affine, G1Projective},
|
||||
g2::{G2Affine, G2Projective},
|
||||
};
|
||||
|
||||
pub type Bls12_381 = Bls12<Parameters>;
|
||||
|
||||
pub struct Parameters;
|
||||
|
||||
impl Bls12Parameters for Parameters {
|
||||
const X: &'static [u64] = &[0xd201000000010000];
|
||||
const X_IS_NEGATIVE: bool = true;
|
||||
const TWIST_TYPE: TwistType = TwistType::M;
|
||||
type Fp = Fq;
|
||||
type Fp2Params = Fq2Parameters;
|
||||
type Fp6Params = Fq6Parameters;
|
||||
type Fp12Params = Fq12Parameters;
|
||||
type G1Parameters = self::g1::Parameters;
|
||||
type G2Parameters = self::g2::Parameters;
|
||||
}
|
||||
116
bls12_381/src/curves/tests.rs
Normal file
116
bls12_381/src/curves/tests.rs
Normal file
@@ -0,0 +1,116 @@
|
||||
#![allow(unused_imports)]
|
||||
use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine, ProjectiveCurve};
|
||||
use ark_ff::{
|
||||
fields::{Field, FpParameters, PrimeField, SquareRootField},
|
||||
test_rng, One, Zero,
|
||||
};
|
||||
use ark_serialize::CanonicalSerialize;
|
||||
use core::ops::{AddAssign, MulAssign};
|
||||
use rand::Rng;
|
||||
|
||||
use crate::{g1, g2, Bls12_381, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
|
||||
use ark_curve_tests::{curves::*, groups::*};
|
||||
|
||||
#[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());
|
||||
}
|
||||
}
|
||||
112
bls12_381/src/fields/fq.rs
Normal file
112
bls12_381/src/fields/fq.rs
Normal file
@@ -0,0 +1,112 @@
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger384 as BigInteger,
|
||||
field_new,
|
||||
fields::{FftParameters, Fp384, Fp384Parameters, FpParameters},
|
||||
};
|
||||
|
||||
pub type Fq = Fp384<FqParameters>;
|
||||
|
||||
pub struct FqParameters;
|
||||
|
||||
impl Fp384Parameters for FqParameters {}
|
||||
impl FftParameters for FqParameters {
|
||||
type BigInt = BigInteger;
|
||||
|
||||
const TWO_ADICITY: u32 = 1;
|
||||
|
||||
#[rustfmt::skip]
|
||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = 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;
|
||||
|
||||
#[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
|
||||
#[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
|
||||
|
||||
#[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, FqParameters::R);
|
||||
pub const FQ_ZERO: Fq = field_new!(Fq, BigInteger([0, 0, 0, 0, 0, 0]));
|
||||
193
bls12_381/src/fields/fq12.rs
Normal file
193
bls12_381/src/fields/fq12.rs
Normal file
@@ -0,0 +1,193 @@
|
||||
use crate::*;
|
||||
use ark_ff::{biginteger::BigInteger384, field_new, fields::*};
|
||||
|
||||
pub type Fq12 = Fp12<Fq12Parameters>;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Fq12Parameters;
|
||||
|
||||
impl Fp12Parameters for Fq12Parameters {
|
||||
type Fp6Params = Fq6Parameters;
|
||||
|
||||
const NONRESIDUE: Fq6 = field_new!(Fq6, FQ2_ZERO, FQ2_ONE, FQ2_ZERO);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[
|
||||
// Fq2(u + 1)**(((q^0) - 1) / 6)
|
||||
FQ2_ONE,
|
||||
// Fq2(u + 1)**(((q^1) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x7089552b319d465,
|
||||
0xc6695f92b50a8313,
|
||||
0x97e83cccd117228f,
|
||||
0xa35baecab2dc29ee,
|
||||
0x1ce393ea5daace4d,
|
||||
0x8f2220fb0fb66eb,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xb2f66aad4ce5d646,
|
||||
0x5842a06bfc497cec,
|
||||
0xcf4895d42599d394,
|
||||
0xc11b9cba40a8e8d0,
|
||||
0x2e3813cbe5a0de89,
|
||||
0x110eefda88847faf,
|
||||
])),
|
||||
),
|
||||
// Fq2(u + 1)**(((q^2) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xecfb361b798dba3a,
|
||||
0xc100ddb891865a2c,
|
||||
0xec08ff1232bda8e,
|
||||
0xd5c13cc6f1ca4721,
|
||||
0x47222a47bf7b5c04,
|
||||
0x110f184e51c5f59,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fq2(u + 1)**(((q^3) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x3e2f585da55c9ad1,
|
||||
0x4294213d86c18183,
|
||||
0x382844c88b623732,
|
||||
0x92ad2afd19103e18,
|
||||
0x1d794e4fac7cf0b9,
|
||||
0xbd592fc7d825ec8,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x7bcfa7a25aa30fda,
|
||||
0xdc17dec12a927e7c,
|
||||
0x2f088dd86b4ebef1,
|
||||
0xd1ca2087da74d4a7,
|
||||
0x2da2596696cebc1d,
|
||||
0xe2b7eedbbfd87d2,
|
||||
])),
|
||||
),
|
||||
// Fq2(u + 1)**(((q^4) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x30f1361b798a64e8,
|
||||
0xf3b8ddab7ece5a2a,
|
||||
0x16a8ca3ac61577f7,
|
||||
0xc26a2ff874fd029b,
|
||||
0x3636b76660701c6e,
|
||||
0x51ba4ab241b6160,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fq2(u + 1)**(((q^5) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x3726c30af242c66c,
|
||||
0x7c2ac1aad1b6fe70,
|
||||
0xa04007fbba4b14a2,
|
||||
0xef517c3266341429,
|
||||
0x95ba654ed2226b,
|
||||
0x2e370eccc86f7dd,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x82d83cf50dbce43f,
|
||||
0xa2813e53df9d018f,
|
||||
0xc6f0caa53c65e181,
|
||||
0x7525cf528d50fe95,
|
||||
0x4a85ed50f4798a6b,
|
||||
0x171da0fd6cf8eebd,
|
||||
])),
|
||||
),
|
||||
// Fq2(u + 1)**(((q^6) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x43f5fffffffcaaae,
|
||||
0x32b7fff2ed47fffd,
|
||||
0x7e83a49a2e99d69,
|
||||
0xeca8f3318332bb7a,
|
||||
0xef148d1ea0f4c069,
|
||||
0x40ab3263eff0206,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fq2(u + 1)**(((q^7) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xb2f66aad4ce5d646,
|
||||
0x5842a06bfc497cec,
|
||||
0xcf4895d42599d394,
|
||||
0xc11b9cba40a8e8d0,
|
||||
0x2e3813cbe5a0de89,
|
||||
0x110eefda88847faf,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x7089552b319d465,
|
||||
0xc6695f92b50a8313,
|
||||
0x97e83cccd117228f,
|
||||
0xa35baecab2dc29ee,
|
||||
0x1ce393ea5daace4d,
|
||||
0x8f2220fb0fb66eb,
|
||||
])),
|
||||
),
|
||||
// Fq2(u + 1)**(((q^8) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xcd03c9e48671f071,
|
||||
0x5dab22461fcda5d2,
|
||||
0x587042afd3851b95,
|
||||
0x8eb60ebe01bacb9e,
|
||||
0x3f97d6e83d050d2,
|
||||
0x18f0206554638741,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fq2(u + 1)**(((q^9) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x7bcfa7a25aa30fda,
|
||||
0xdc17dec12a927e7c,
|
||||
0x2f088dd86b4ebef1,
|
||||
0xd1ca2087da74d4a7,
|
||||
0x2da2596696cebc1d,
|
||||
0xe2b7eedbbfd87d2,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x3e2f585da55c9ad1,
|
||||
0x4294213d86c18183,
|
||||
0x382844c88b623732,
|
||||
0x92ad2afd19103e18,
|
||||
0x1d794e4fac7cf0b9,
|
||||
0xbd592fc7d825ec8,
|
||||
])),
|
||||
),
|
||||
// Fq2(u + 1)**(((q^10) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x890dc9e4867545c3,
|
||||
0x2af322533285a5d5,
|
||||
0x50880866309b7e2c,
|
||||
0xa20d1b8c7e881024,
|
||||
0x14e4f04fe2db9068,
|
||||
0x14e56d3f1564853a,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fq2(u + 1)**(((q^11) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x82d83cf50dbce43f,
|
||||
0xa2813e53df9d018f,
|
||||
0xc6f0caa53c65e181,
|
||||
0x7525cf528d50fe95,
|
||||
0x4a85ed50f4798a6b,
|
||||
0x171da0fd6cf8eebd,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x3726c30af242c66c,
|
||||
0x7c2ac1aad1b6fe70,
|
||||
0xa04007fbba4b14a2,
|
||||
0xef517c3266341429,
|
||||
0x95ba654ed2226b,
|
||||
0x2e370eccc86f7dd,
|
||||
])),
|
||||
),
|
||||
];
|
||||
}
|
||||
73
bls12_381/src/fields/fq2.rs
Normal file
73
bls12_381/src/fields/fq2.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
use crate::*;
|
||||
use ark_ff::{biginteger::BigInteger384 as BigInteger, field_new, fields::*};
|
||||
|
||||
pub type Fq2 = Fp2<Fq2Parameters>;
|
||||
|
||||
pub struct Fq2Parameters;
|
||||
|
||||
impl Fp2Parameters for Fq2Parameters {
|
||||
type Fp = Fq;
|
||||
|
||||
/// NONRESIDUE = -1
|
||||
#[rustfmt::skip]
|
||||
const NONRESIDUE: Fq = field_new!(Fq, BigInteger([
|
||||
0x43f5fffffffcaaae,
|
||||
0x32b7fff2ed47fffd,
|
||||
0x7e83a49a2e99d69,
|
||||
0xeca8f3318332bb7a,
|
||||
0xef148d1ea0f4c069,
|
||||
0x40ab3263eff0206,
|
||||
]));
|
||||
|
||||
/// QUADRATIC_NONRESIDUE = (U + 1)
|
||||
#[rustfmt::skip]
|
||||
const QUADRATIC_NONRESIDUE: (Fq, Fq) = (
|
||||
field_new!(Fq, BigInteger([
|
||||
0x760900000002fffd,
|
||||
0xebf4000bc40c0002,
|
||||
0x5f48985753c758ba,
|
||||
0x77ce585370525745,
|
||||
0x5c071a97a256ec6d,
|
||||
0x15f65ec3fa80e493,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0x760900000002fffd,
|
||||
0xebf4000bc40c0002,
|
||||
0x5f48985753c758ba,
|
||||
0x77ce585370525745,
|
||||
0x5c071a97a256ec6d,
|
||||
0x15f65ec3fa80e493,
|
||||
])),
|
||||
);
|
||||
|
||||
/// Coefficients for the Frobenius automorphism.
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[
|
||||
// Fq(-1)**(((q^0) - 1) / 2)
|
||||
field_new!(Fq, BigInteger([
|
||||
0x760900000002fffd,
|
||||
0xebf4000bc40c0002,
|
||||
0x5f48985753c758ba,
|
||||
0x77ce585370525745,
|
||||
0x5c071a97a256ec6d,
|
||||
0x15f65ec3fa80e493,
|
||||
])),
|
||||
// Fq(-1)**(((q^1) - 1) / 2)
|
||||
field_new!(Fq, BigInteger([
|
||||
0x43f5fffffffcaaae,
|
||||
0x32b7fff2ed47fffd,
|
||||
0x7e83a49a2e99d69,
|
||||
0xeca8f3318332bb7a,
|
||||
0xef148d1ea0f4c069,
|
||||
0x40ab3263eff0206,
|
||||
])),
|
||||
];
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_fp_by_nonresidue(fp: &Self::Fp) -> Self::Fp {
|
||||
-(*fp)
|
||||
}
|
||||
}
|
||||
|
||||
pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO);
|
||||
pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO);
|
||||
194
bls12_381/src/fields/fq6.rs
Normal file
194
bls12_381/src/fields/fq6.rs
Normal file
@@ -0,0 +1,194 @@
|
||||
use crate::*;
|
||||
use ark_ff::{biginteger::BigInteger384, field_new, fields::*};
|
||||
|
||||
pub type Fq6 = Fp6<Fq6Parameters>;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Fq6Parameters;
|
||||
|
||||
impl Fp6Parameters for Fq6Parameters {
|
||||
type Fp2Params = Fq2Parameters;
|
||||
|
||||
/// NONRESIDUE = (U + 1)
|
||||
#[rustfmt::skip]
|
||||
const NONRESIDUE: Fq2 = field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x760900000002fffd,
|
||||
0xebf4000bc40c0002,
|
||||
0x5f48985753c758ba,
|
||||
0x77ce585370525745,
|
||||
0x5c071a97a256ec6d,
|
||||
0x15f65ec3fa80e493,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x760900000002fffd,
|
||||
0xebf4000bc40c0002,
|
||||
0x5f48985753c758ba,
|
||||
0x77ce585370525745,
|
||||
0x5c071a97a256ec6d,
|
||||
0x15f65ec3fa80e493,
|
||||
])),
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[
|
||||
// Fq2(u + 1)**(((q^0) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x760900000002fffd,
|
||||
0xebf4000bc40c0002,
|
||||
0x5f48985753c758ba,
|
||||
0x77ce585370525745,
|
||||
0x5c071a97a256ec6d,
|
||||
0x15f65ec3fa80e493,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fq2(u + 1)**(((q^1) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xcd03c9e48671f071,
|
||||
0x5dab22461fcda5d2,
|
||||
0x587042afd3851b95,
|
||||
0x8eb60ebe01bacb9e,
|
||||
0x3f97d6e83d050d2,
|
||||
0x18f0206554638741,
|
||||
])),
|
||||
),
|
||||
// Fq2(u + 1)**(((q^2) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x30f1361b798a64e8,
|
||||
0xf3b8ddab7ece5a2a,
|
||||
0x16a8ca3ac61577f7,
|
||||
0xc26a2ff874fd029b,
|
||||
0x3636b76660701c6e,
|
||||
0x51ba4ab241b6160,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fq2(u + 1)**(((q^3) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x760900000002fffd,
|
||||
0xebf4000bc40c0002,
|
||||
0x5f48985753c758ba,
|
||||
0x77ce585370525745,
|
||||
0x5c071a97a256ec6d,
|
||||
0x15f65ec3fa80e493,
|
||||
])),
|
||||
),
|
||||
// Fq2(u + 1)**(((q^4) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xcd03c9e48671f071,
|
||||
0x5dab22461fcda5d2,
|
||||
0x587042afd3851b95,
|
||||
0x8eb60ebe01bacb9e,
|
||||
0x3f97d6e83d050d2,
|
||||
0x18f0206554638741,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fq2(u + 1)**(((q^5) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x30f1361b798a64e8,
|
||||
0xf3b8ddab7ece5a2a,
|
||||
0x16a8ca3ac61577f7,
|
||||
0xc26a2ff874fd029b,
|
||||
0x3636b76660701c6e,
|
||||
0x51ba4ab241b6160,
|
||||
])),
|
||||
),
|
||||
];
|
||||
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[
|
||||
// Fq2(u + 1)**(((2q^0) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x760900000002fffd,
|
||||
0xebf4000bc40c0002,
|
||||
0x5f48985753c758ba,
|
||||
0x77ce585370525745,
|
||||
0x5c071a97a256ec6d,
|
||||
0x15f65ec3fa80e493,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fq2(u + 1)**(((2q^1) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x890dc9e4867545c3,
|
||||
0x2af322533285a5d5,
|
||||
0x50880866309b7e2c,
|
||||
0xa20d1b8c7e881024,
|
||||
0x14e4f04fe2db9068,
|
||||
0x14e56d3f1564853a,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fq2(u + 1)**(((2q^2) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xcd03c9e48671f071,
|
||||
0x5dab22461fcda5d2,
|
||||
0x587042afd3851b95,
|
||||
0x8eb60ebe01bacb9e,
|
||||
0x3f97d6e83d050d2,
|
||||
0x18f0206554638741,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fq2(u + 1)**(((2q^3) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x43f5fffffffcaaae,
|
||||
0x32b7fff2ed47fffd,
|
||||
0x7e83a49a2e99d69,
|
||||
0xeca8f3318332bb7a,
|
||||
0xef148d1ea0f4c069,
|
||||
0x40ab3263eff0206,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fq2(u + 1)**(((2q^4) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0x30f1361b798a64e8,
|
||||
0xf3b8ddab7ece5a2a,
|
||||
0x16a8ca3ac61577f7,
|
||||
0xc26a2ff874fd029b,
|
||||
0x3636b76660701c6e,
|
||||
0x51ba4ab241b6160,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fq2(u + 1)**(((2q^5) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger384([
|
||||
0xecfb361b798dba3a,
|
||||
0xc100ddb891865a2c,
|
||||
0xec08ff1232bda8e,
|
||||
0xd5c13cc6f1ca4721,
|
||||
0x47222a47bf7b5c04,
|
||||
0x110f184e51c5f59,
|
||||
])),
|
||||
field_new!(Fq, BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
];
|
||||
|
||||
/// Multiply this element by the quadratic nonresidue 1 + u.
|
||||
/// Make this generic.
|
||||
fn mul_fp2_by_nonresidue(fe: &Fq2) -> Fq2 {
|
||||
let mut copy = *fe;
|
||||
let t0 = copy.c0;
|
||||
copy.c0 -= &fe.c1;
|
||||
copy.c1 += &t0;
|
||||
copy
|
||||
}
|
||||
}
|
||||
96
bls12_381/src/fields/fr.rs
Normal file
96
bls12_381/src/fields/fr.rs
Normal file
@@ -0,0 +1,96 @@
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger256 as BigInteger,
|
||||
fields::{FftParameters, Fp256, Fp256Parameters, FpParameters},
|
||||
};
|
||||
|
||||
pub type Fr = Fp256<FrParameters>;
|
||||
|
||||
pub struct FrParameters;
|
||||
|
||||
impl Fp256Parameters for FrParameters {}
|
||||
impl FftParameters for FrParameters {
|
||||
type BigInt = BigInteger;
|
||||
|
||||
const TWO_ADICITY: u32 = 32;
|
||||
|
||||
#[rustfmt::skip]
|
||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = 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;
|
||||
|
||||
#[rustfmt::skip]
|
||||
const R: BigInteger = BigInteger([
|
||||
0x1fffffffe,
|
||||
0x5884b7fa00034802,
|
||||
0x998c4fefecbc4ff5,
|
||||
0x1824b159acc5056f,
|
||||
]);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const R2: BigInteger = BigInteger([
|
||||
0xc999e990f3f29c6d,
|
||||
0x2b6cedcb87925c23,
|
||||
0x5d314967254398f,
|
||||
0x748d9d99f59ff11,
|
||||
]);
|
||||
|
||||
const INV: u64 = 0xfffffffeffffffff;
|
||||
|
||||
//
|
||||
#[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
|
||||
|
||||
// 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,
|
||||
]);
|
||||
}
|
||||
27
bls12_381/src/fields/mod.rs
Normal file
27
bls12_381/src/fields/mod.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
#[cfg(feature = "scalar_field")]
|
||||
pub mod fr;
|
||||
#[cfg(feature = "scalar_field")]
|
||||
pub use self::fr::*;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub mod fq;
|
||||
#[cfg(feature = "curve")]
|
||||
pub use self::fq::*;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub mod fq2;
|
||||
#[cfg(feature = "curve")]
|
||||
pub use self::fq2::*;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub mod fq6;
|
||||
#[cfg(feature = "curve")]
|
||||
pub use self::fq6::*;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub mod fq12;
|
||||
#[cfg(feature = "curve")]
|
||||
pub use self::fq12::*;
|
||||
|
||||
#[cfg(all(feature = "curve", feature = "std", test))]
|
||||
mod tests;
|
||||
2322
bls12_381/src/fields/tests.rs
Normal file
2322
bls12_381/src/fields/tests.rs
Normal file
File diff suppressed because it is too large
Load Diff
32
bls12_381/src/lib.rs
Normal file
32
bls12_381/src/lib.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![deny(
|
||||
warnings,
|
||||
unused,
|
||||
future_incompatible,
|
||||
nonstandard_style,
|
||||
rust_2018_idioms
|
||||
)]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
//! This library implements the BLS12_381 curve generated by [Sean Bowe](https://electriccoin.co/blog/new-snark-curve/).
|
||||
//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree 12,
|
||||
//! defined over a 381-bit (prime) field.
|
||||
//! This curve was intended to replace the BN254 curve to provide a higher security
|
||||
//! level without incurring a large performance overhead.
|
||||
//!
|
||||
//!
|
||||
//! Curve information:
|
||||
//! * Base field: q = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
|
||||
//! * Scalar field: r = 52435875175126190479447740508185965837690552500527637822603658699938581184513
|
||||
//! * valuation(q - 1, 2) = 1
|
||||
//! * valuation(r - 1, 2) = 32
|
||||
//! * G1 curve equation: y^2 = x^3 + 4
|
||||
//! * G2 curve equation: y^2 = x^3 + Fq2(4, 4)
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
mod curves;
|
||||
mod fields;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub use curves::*;
|
||||
pub use fields::*;
|
||||
31
bn254/Cargo.toml
Normal file
31
bn254/Cargo.toml
Normal file
@@ -0,0 +1,31 @@
|
||||
[package]
|
||||
name = "ark-bn254"
|
||||
version = "0.1.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The BN254 pairing-friendly elliptic curve"
|
||||
homepage = "https://arworks.rs"
|
||||
repository = "https://github.com/arkworks/algebra"
|
||||
documentation = "https://docs.rs/ark-bn254/"
|
||||
keywords = ["cryptography", "finite fields", "elliptic curves" ]
|
||||
categories = ["cryptography"]
|
||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
license = "MIT/Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
ark-ff = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-ec = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
ark-serialize = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-curve-tests = { path = "../curve-tests", default-features = false }
|
||||
rand = { version = "0.7", default-features = false }
|
||||
rand_xorshift = "0.2"
|
||||
|
||||
[features]
|
||||
default = [ "curve" ]
|
||||
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ]
|
||||
|
||||
curve = [ "scalar_field" ]
|
||||
scalar_field = []
|
||||
1
bn254/LICENSE-APACHE
Symbolic link
1
bn254/LICENSE-APACHE
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE-APACHE
|
||||
1
bn254/LICENSE-MIT
Symbolic link
1
bn254/LICENSE-MIT
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE-MIT
|
||||
67
bn254/src/curves/g1.rs
Normal file
67
bn254/src/curves/g1.rs
Normal file
@@ -0,0 +1,67 @@
|
||||
use ark_ec::models::{ModelParameters, SWModelParameters};
|
||||
use ark_ff::{biginteger::BigInteger256, field_new, Zero};
|
||||
|
||||
use crate::{Fq, Fr};
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct Parameters;
|
||||
|
||||
impl ModelParameters for Parameters {
|
||||
type BaseField = Fq;
|
||||
type ScalarField = Fr;
|
||||
}
|
||||
|
||||
impl SWModelParameters for Parameters {
|
||||
/// COEFF_A = 0
|
||||
const COEFF_A: Fq = field_new!(Fq, BigInteger256([0x0, 0x0, 0x0, 0x0]));
|
||||
|
||||
/// COEFF_B = 3
|
||||
#[rustfmt::skip]
|
||||
const COEFF_B: Fq = field_new!(Fq, BigInteger256([
|
||||
0x7a17caa950ad28d7,
|
||||
0x1f6ac17ae15521b9,
|
||||
0x334bea4e696bd284,
|
||||
0x2a1f6744ce179d8e,
|
||||
]));
|
||||
|
||||
/// COFACTOR = 1
|
||||
const COFACTOR: &'static [u64] = &[0x1];
|
||||
|
||||
/// COFACTOR_INV = COFACTOR^{-1} mod r = 1
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger256([
|
||||
0xac96341c4ffffffb,
|
||||
0x36fc76959f60cd29,
|
||||
0x666ea36f7879462e,
|
||||
0xe0a77c19a07df2f,
|
||||
]));
|
||||
|
||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||
(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
||||
Self::BaseField::zero()
|
||||
}
|
||||
}
|
||||
|
||||
/// G1_GENERATOR_X =
|
||||
/// 1
|
||||
#[rustfmt::skip]
|
||||
pub const G1_GENERATOR_X: Fq = field_new!(Fq, BigInteger256([
|
||||
0xd35d438dc58f0d9d,
|
||||
0x0a78eb28f5c70b3d,
|
||||
0x666ea36f7879462c,
|
||||
0x0e0a77c19a07df2f,
|
||||
]));
|
||||
|
||||
/// G1_GENERATOR_Y =
|
||||
/// 2
|
||||
#[rustfmt::skip]
|
||||
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, BigInteger256([
|
||||
0xa6ba871b8b1e1b3a,
|
||||
0x14f1d651eb8e167b,
|
||||
0xccdd46def0f28c58,
|
||||
0x1c14ef83340fbe5e,
|
||||
]));
|
||||
112
bn254/src/curves/g2.rs
Normal file
112
bn254/src/curves/g2.rs
Normal file
@@ -0,0 +1,112 @@
|
||||
use ark_ec::models::{ModelParameters, SWModelParameters};
|
||||
use ark_ff::{biginteger::BigInteger256, field_new, Zero};
|
||||
|
||||
use crate::{g1, Fq, Fq2, Fr};
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct Parameters;
|
||||
|
||||
impl ModelParameters for Parameters {
|
||||
type BaseField = Fq2;
|
||||
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,
|
||||
);
|
||||
|
||||
/// COEFF_B = 3/(u+9)
|
||||
/// = (19485874751759354771024239261021720505790618469301721065564631296452457478373, 266929791119991161246907387137283842545076965332900288569378510910307636690)
|
||||
#[rustfmt::skip]
|
||||
const COEFF_B: Fq2 = field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x3bf938e377b802a8,
|
||||
0x020b1b273633535d,
|
||||
0x26b7edf049755260,
|
||||
0x2514c6324384a86d,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x38e7ecccd1dcff67,
|
||||
0x65f0b37d93ce0d3e,
|
||||
0xd749d0dd22ac00aa,
|
||||
0x0141b9ce4a688d4d,
|
||||
])),
|
||||
);
|
||||
|
||||
/// COFACTOR = (36 * X^4) + (36 * X^3) + (30 * X^2) + 6*X + 1
|
||||
/// = 21888242871839275222246405745257275088844257914179612981679871602714643921549
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR: &'static [u64] = &[
|
||||
0x345f2299c0f9fa8d,
|
||||
0x06ceecda572a2489,
|
||||
0xb85045b68181585e,
|
||||
0x30644e72e131a029,
|
||||
];
|
||||
|
||||
/// COFACTOR_INV = COFACTOR^{-1} mod r
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger256([
|
||||
0x7fff17d53ff2895e,
|
||||
0xd0617390cf7919e5,
|
||||
0xb9af426b22d0eb61,
|
||||
0x270485e31bd72a4d,
|
||||
]));
|
||||
|
||||
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||
(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
|
||||
Self::BaseField::zero()
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_X: Fq2 = field_new!(Fq2, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
|
||||
|
||||
/// G2_GENERATOR_X_C0 =
|
||||
/// 10857046999023057135944570762232829481370756359578518086990519993285655852781
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, BigInteger256([
|
||||
0x8e83b5d102bc2026,
|
||||
0xdceb1935497b0172,
|
||||
0xfbb8264797811adf,
|
||||
0x19573841af96503b,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_X_C1 =
|
||||
/// 11559732032986387107991004021392285783925812861821192530917403151452391805634
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, BigInteger256([
|
||||
0xafb4737da84c6140,
|
||||
0x6043dd5a5802d8c4,
|
||||
0x09e950fc52a02f86,
|
||||
0x14fef0833aea7b6b,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_Y_C0 =
|
||||
/// 8495653923123431417604973247489272438418190587263600148770280649306958101930
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, BigInteger256([
|
||||
0x619dfa9d886be9f6,
|
||||
0xfe7fd297f59e9b78,
|
||||
0xff9e1a62231b7dfe,
|
||||
0x28fd7eebae9e4206,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_Y_C1 =
|
||||
/// 4082367875863433681332203403145435568316851327593401208105741076214120093531
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, BigInteger256([
|
||||
0x64095b56c71856ee,
|
||||
0xdc57f922327d3cbb,
|
||||
0x55f935be33351076,
|
||||
0x0da4a0e693fd6482,
|
||||
]));
|
||||
82
bn254/src/curves/mod.rs
Normal file
82
bn254/src/curves/mod.rs
Normal file
@@ -0,0 +1,82 @@
|
||||
use crate::*;
|
||||
use ark_ec::{
|
||||
bn,
|
||||
bn::{Bn, BnParameters, TwistType},
|
||||
};
|
||||
use ark_ff::{biginteger::BigInteger256, field_new};
|
||||
pub mod g1;
|
||||
pub mod g2;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub struct Parameters;
|
||||
|
||||
impl BnParameters for Parameters {
|
||||
const X: &'static [u64] = &[4965661367192848881];
|
||||
/// `x` is positive.
|
||||
const X_IS_NEGATIVE: bool = false;
|
||||
const ATE_LOOP_COUNT: &'static [i8] = &[
|
||||
0, 0, 0, 1, 0, 1, 0, -1, 0, 0, 1, -1, 0, 0, 1, 0, 0, 1, 1, 0, -1, 0, 0, 1, 0, -1, 0, 0, 0,
|
||||
0, 1, 1, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, 0, 0, 1, 1, 0,
|
||||
-1, 0, 0, 1, 0, 1, 1,
|
||||
];
|
||||
/// `ate_loop_count` is positive.
|
||||
const ATE_LOOP_COUNT_IS_NEGATIVE: bool = false;
|
||||
const TWIST_MUL_BY_Q_X: Fq2 = field_new!(
|
||||
Fq2,
|
||||
field_new!(
|
||||
Fq,
|
||||
BigInteger256([
|
||||
0xb5773b104563ab30,
|
||||
0x347f91c8a9aa6454,
|
||||
0x7a007127242e0991,
|
||||
0x1956bcd8118214ec,
|
||||
])
|
||||
),
|
||||
field_new!(
|
||||
Fq,
|
||||
BigInteger256([
|
||||
0x6e849f1ea0aa4757,
|
||||
0xaa1c7b6d89f89141,
|
||||
0xb6e713cdfae0ca3a,
|
||||
0x26694fbb4e82ebc3,
|
||||
])
|
||||
),
|
||||
);
|
||||
const TWIST_MUL_BY_Q_Y: Fq2 = field_new!(
|
||||
Fq2,
|
||||
field_new!(
|
||||
Fq,
|
||||
BigInteger256([
|
||||
0xe4bbdd0c2936b629,
|
||||
0xbb30f162e133bacb,
|
||||
0x31a9d1b6f9645366,
|
||||
0x253570bea500f8dd,
|
||||
])
|
||||
),
|
||||
field_new!(
|
||||
Fq,
|
||||
BigInteger256([
|
||||
0xa1d77ce45ffe77c7,
|
||||
0x07affd117826d1db,
|
||||
0x6d16bd27bb7edc6b,
|
||||
0x2c87200285defecc,
|
||||
])
|
||||
),
|
||||
);
|
||||
const TWIST_TYPE: TwistType = TwistType::D;
|
||||
type Fp = Fq;
|
||||
type Fp2Params = Fq2Parameters;
|
||||
type Fp6Params = Fq6Parameters;
|
||||
type Fp12Params = Fq12Parameters;
|
||||
type G1Parameters = g1::Parameters;
|
||||
type G2Parameters = g2::Parameters;
|
||||
}
|
||||
|
||||
pub type Bn254 = Bn<Parameters>;
|
||||
|
||||
pub type G1Affine = bn::G1Affine<Parameters>;
|
||||
pub type G1Projective = bn::G1Projective<Parameters>;
|
||||
pub type G2Affine = bn::G2Affine<Parameters>;
|
||||
pub type G2Projective = bn::G2Projective<Parameters>;
|
||||
85
bn254/src/curves/tests.rs
Normal file
85
bn254/src/curves/tests.rs
Normal file
@@ -0,0 +1,85 @@
|
||||
#![allow(unused_imports)]
|
||||
use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine, ProjectiveCurve};
|
||||
use ark_ff::{
|
||||
fields::{Field, FpParameters, PrimeField, SquareRootField},
|
||||
test_rng, One, Zero,
|
||||
};
|
||||
use ark_serialize::CanonicalSerialize;
|
||||
use core::ops::{AddAssign, MulAssign};
|
||||
use rand::Rng;
|
||||
|
||||
use crate::{g1, g2, Bn254, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
|
||||
|
||||
use ark_curve_tests::{curves::*, groups::*};
|
||||
|
||||
#[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 = 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());
|
||||
}
|
||||
96
bn254/src/fields/fq.rs
Normal file
96
bn254/src/fields/fq.rs
Normal file
@@ -0,0 +1,96 @@
|
||||
use ark_ff::{biginteger::BigInteger256 as BigInteger, field_new, fields::*};
|
||||
|
||||
pub type Fq = Fp256<FqParameters>;
|
||||
|
||||
pub struct FqParameters;
|
||||
|
||||
impl Fp256Parameters for FqParameters {}
|
||||
impl FftParameters for FqParameters {
|
||||
type BigInt = BigInteger;
|
||||
|
||||
const TWO_ADICITY: u32 = 1;
|
||||
|
||||
#[rustfmt::skip]
|
||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
||||
0x68c3488912edefaa,
|
||||
0x8d087f6872aabf4f,
|
||||
0x51e1a24709081231,
|
||||
0x2259d6b14729c0fa,
|
||||
]);
|
||||
}
|
||||
impl FpParameters for FqParameters {
|
||||
/// MODULUS = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
|
||||
#[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 =
|
||||
// 1837921289030710838195067919506396475074392872918698035817074744121558668640693829665401097909504529
|
||||
#[rustfmt::skip]
|
||||
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||
0x4f082305b61f3f51,
|
||||
0x65e05aa45a1c72a3,
|
||||
0x6e14116da0605617,
|
||||
0xc19139cb84c680a,
|
||||
]);
|
||||
}
|
||||
|
||||
pub const FQ_ONE: Fq = field_new!(Fq, FqParameters::R);
|
||||
pub const FQ_ZERO: Fq = field_new!(Fq, BigInteger([0, 0, 0, 0]));
|
||||
159
bn254/src/fields/fq12.rs
Normal file
159
bn254/src/fields/fq12.rs
Normal file
@@ -0,0 +1,159 @@
|
||||
use super::*;
|
||||
use ark_ff::{biginteger::BigInteger256, field_new, fields::*};
|
||||
|
||||
pub type Fq12 = Fp12<Fq12Parameters>;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Fq12Parameters;
|
||||
|
||||
impl Fp12Parameters for Fq12Parameters {
|
||||
type Fp6Params = Fq6Parameters;
|
||||
|
||||
const NONRESIDUE: Fq6 = field_new!(Fq6, FQ2_ZERO, FQ2_ONE, FQ2_ZERO);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[
|
||||
// Fp2::NONRESIDUE^(((q^0) - 1) / 6)
|
||||
FQ2_ONE,
|
||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0xaf9ba69633144907,
|
||||
0xca6b1d7387afb78a,
|
||||
0x11bded5ef08a2087,
|
||||
0x02f34d751a1f3a7c,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([
|
||||
0xa222ae234c492d72,
|
||||
0xd00f02a4565de15b,
|
||||
0xdc2ff3a253dfc926,
|
||||
0x10a75716b3899551,
|
||||
])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0xca8d800500fa1bf2,
|
||||
0xf0c5d61468b39769,
|
||||
0x0e201271ad0d4418,
|
||||
0x04290f65bad856e6,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x365316184e46d97d,
|
||||
0x0af7129ed4c96d9f,
|
||||
0x659da72fca1009b5,
|
||||
0x08116d8983a20d23,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([
|
||||
0xb1df4af7c39c1939,
|
||||
0x3d9f02878a73bf7f,
|
||||
0x9b2220928caf0ae0,
|
||||
0x26684515eff054a6,
|
||||
])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x3350c88e13e80b9c,
|
||||
0x7dce557cdb5e56b9,
|
||||
0x6001b4b8b615564a,
|
||||
0x2682e617020217e0,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x86b76f821b329076,
|
||||
0x408bf52b4d19b614,
|
||||
0x53dfb9d0d985e92d,
|
||||
0x051e20146982d2a7,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x0fbc9cd47752ebc7,
|
||||
0x6d8fffe33415de24,
|
||||
0xbef22cf038cf41b9,
|
||||
0x15c0edff3c66bf54,
|
||||
])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^6) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x68c3488912edefaa,
|
||||
0x8d087f6872aabf4f,
|
||||
0x51e1a24709081231,
|
||||
0x2259d6b14729c0fa,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^7) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x8c84e580a568b440,
|
||||
0xcd164d1de0c21302,
|
||||
0xa692585790f737d5,
|
||||
0x2d7100fdc71265ad,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x99fdddf38c33cfd5,
|
||||
0xc77267ed1213e931,
|
||||
0xdc2052142da18f36,
|
||||
0x1fbcf75c2da80ad7,
|
||||
])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^8) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x71930c11d782e155,
|
||||
0xa6bb947cffbe3323,
|
||||
0xaa303344d4741444,
|
||||
0x2c3b3f0d26594943,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^9) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x05cd75fe8a3623ca,
|
||||
0x8c8a57f293a85cee,
|
||||
0x52b29e86b7714ea8,
|
||||
0x2852e0e95d8f9306,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x8a41411f14e0e40e,
|
||||
0x59e26809ddfe0b0d,
|
||||
0x1d2e2523f4d24d7d,
|
||||
0x09fc095cf1414b83,
|
||||
])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^10) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x08cfc388c494f1ab,
|
||||
0x19b315148d1373d4,
|
||||
0x584e90fdcb6c0213,
|
||||
0x09e1685bdf2f8849,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^11) - 1) / 6)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0xb5691c94bd4a6cd1,
|
||||
0x56f575661b581478,
|
||||
0x64708be5a7fb6f30,
|
||||
0x2b462e5e77aecd82,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x2c63ef42612a1180,
|
||||
0x29f16aae345bec69,
|
||||
0xf95e18c648b216a4,
|
||||
0x1aa36073a4cae0d4,
|
||||
])),
|
||||
),
|
||||
];
|
||||
}
|
||||
63
bn254/src/fields/fq2.rs
Normal file
63
bn254/src/fields/fq2.rs
Normal file
@@ -0,0 +1,63 @@
|
||||
use super::*;
|
||||
use ark_ff::{biginteger::BigInteger256 as BigInteger, field_new, fields::*};
|
||||
|
||||
pub type Fq2 = Fp2<Fq2Parameters>;
|
||||
|
||||
pub struct Fq2Parameters;
|
||||
|
||||
impl Fp2Parameters for Fq2Parameters {
|
||||
type Fp = Fq;
|
||||
|
||||
/// NONRESIDUE = -1
|
||||
#[rustfmt::skip]
|
||||
const NONRESIDUE: Fq = field_new!(Fq, BigInteger([
|
||||
0x68c3488912edefaa,
|
||||
0x8d087f6872aabf4f,
|
||||
0x51e1a24709081231,
|
||||
0x2259d6b14729c0fa,
|
||||
]));
|
||||
|
||||
/// QUADRATIC_NONRESIDUE = U+2
|
||||
#[rustfmt::skip]
|
||||
const QUADRATIC_NONRESIDUE: (Fq, Fq) = (
|
||||
field_new!(Fq, BigInteger([
|
||||
12014063508332092218u64,
|
||||
1509222997478479483u64,
|
||||
14762033076929465432u64,
|
||||
2023505479389396574u64,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
202099033278250856u64,
|
||||
8885205928937022213u64,
|
||||
5545221690922665192u64,
|
||||
39800542322357402u64,
|
||||
])),
|
||||
);
|
||||
|
||||
/// Coefficients for the Frobenius automorphism.
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[
|
||||
// NONRESIDUE**(((q^0) - 1) / 2)
|
||||
field_new!(Fq, BigInteger([
|
||||
0xd35d438dc58f0d9d,
|
||||
0x0a78eb28f5c70b3d,
|
||||
0x666ea36f7879462c,
|
||||
0xe0a77c19a07df2f,
|
||||
])),
|
||||
// NONRESIDUE**(((q^1) - 1) / 2)
|
||||
field_new!(Fq, BigInteger([
|
||||
0x68c3488912edefaa,
|
||||
0x8d087f6872aabf4f,
|
||||
0x51e1a24709081231,
|
||||
0x2259d6b14729c0fa,
|
||||
])),
|
||||
];
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_fp_by_nonresidue(fe: &Self::Fp) -> Self::Fp {
|
||||
-(*fe)
|
||||
}
|
||||
}
|
||||
|
||||
pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO);
|
||||
pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO);
|
||||
195
bn254/src/fields/fq6.rs
Normal file
195
bn254/src/fields/fq6.rs
Normal file
@@ -0,0 +1,195 @@
|
||||
use super::*;
|
||||
use ark_ff::{biginteger::BigInteger256, field_new, fields::*};
|
||||
|
||||
pub type Fq6 = Fp6<Fq6Parameters>;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Fq6Parameters;
|
||||
|
||||
impl Fp6Parameters for Fq6Parameters {
|
||||
type Fp2Params = Fq2Parameters;
|
||||
|
||||
/// NONRESIDUE = U+9
|
||||
#[rustfmt::skip]
|
||||
const NONRESIDUE: Fq2 = field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0xf60647ce410d7ff7,
|
||||
0x2f3d6f4dd31bd011,
|
||||
0x2943337e3940c6d1,
|
||||
0x1d9598e8a7e39857,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([
|
||||
202099033278250856u64,
|
||||
8885205928937022213u64,
|
||||
5545221690922665192u64,
|
||||
39800542322357402u64,
|
||||
])),
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[
|
||||
// Fp2::NONRESIDUE^(((q^0) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0xd35d438dc58f0d9d,
|
||||
0x0a78eb28f5c70b3d,
|
||||
0x666ea36f7879462c,
|
||||
0xe0a77c19a07df2f,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^1) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0xb5773b104563ab30,
|
||||
0x347f91c8a9aa6454,
|
||||
0x7a007127242e0991,
|
||||
0x1956bcd8118214ec,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x6e849f1ea0aa4757,
|
||||
0xaa1c7b6d89f89141,
|
||||
0xb6e713cdfae0ca3a,
|
||||
0x26694fbb4e82ebc3,
|
||||
])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^2) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x3350c88e13e80b9c,
|
||||
0x7dce557cdb5e56b9,
|
||||
0x6001b4b8b615564a,
|
||||
0x2682e617020217e0,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^3) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0xc9af22f716ad6bad,
|
||||
0xb311782a4aa662b2,
|
||||
0x19eeaf64e248c7f4,
|
||||
0x20273e77e3439f82,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([
|
||||
0xacc02860f7ce93ac,
|
||||
0x3933d5817ba76b4c,
|
||||
0x69e6188b446c8467,
|
||||
0xa46036d4417cc55,
|
||||
])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^4) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x71930c11d782e155,
|
||||
0xa6bb947cffbe3323,
|
||||
0xaa303344d4741444,
|
||||
0x2c3b3f0d26594943,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^(((q^5) - 1) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0xf91aba2654e8e3b1,
|
||||
0x4771cb2fdc92ce12,
|
||||
0xdcb16ae0fc8bdf35,
|
||||
0x274aa195cd9d8be4,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x5cfc50ae18811f8b,
|
||||
0x4bb28433cb43988c,
|
||||
0x4fd35f13c3b56219,
|
||||
0x301949bd2fc8883a,
|
||||
])),
|
||||
),
|
||||
];
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[
|
||||
// Fp2::NONRESIDUE^((2*(q^0) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0xd35d438dc58f0d9d,
|
||||
0x0a78eb28f5c70b3d,
|
||||
0x666ea36f7879462c,
|
||||
0xe0a77c19a07df2f,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^((2*(q^1) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x7361d77f843abe92,
|
||||
0xa5bb2bd3273411fb,
|
||||
0x9c941f314b3e2399,
|
||||
0x15df9cddbb9fd3ec,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x5dddfd154bd8c949,
|
||||
0x62cb29a5a4445b60,
|
||||
0x37bc870a0c7dd2b9,
|
||||
0x24830a9d3171f0fd,
|
||||
])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^((2*(q^2) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x71930c11d782e155,
|
||||
0xa6bb947cffbe3323,
|
||||
0xaa303344d4741444,
|
||||
0x2c3b3f0d26594943,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^((2*(q^3) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x448a93a57b6762df,
|
||||
0xbfd62df528fdeadf,
|
||||
0xd858f5d00e9bd47a,
|
||||
0x6b03d4d3476ec58,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x2b19daf4bcc936d1,
|
||||
0xa1a54e7a56f4299f,
|
||||
0xb533eee05adeaef1,
|
||||
0x170c812b84dda0b2,
|
||||
])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^((2*(q^4) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x3350c88e13e80b9c,
|
||||
0x7dce557cdb5e56b9,
|
||||
0x6001b4b8b615564a,
|
||||
0x2682e617020217e0,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([0x0, 0x0, 0x0, 0x0])),
|
||||
),
|
||||
// Fp2::NONRESIDUE^((2*(q^5) - 2) / 3)
|
||||
field_new!(Fq2,
|
||||
field_new!(Fq, BigInteger256([
|
||||
0x843420f1d8dadbd6,
|
||||
0x31f010c9183fcdb2,
|
||||
0x436330b527a76049,
|
||||
0x13d47447f11adfe4,
|
||||
])),
|
||||
field_new!(Fq, BigInteger256([
|
||||
0xef494023a857fa74,
|
||||
0x2a925d02d5ab101a,
|
||||
0x83b015829ba62f10,
|
||||
0x2539111d0c13aea3,
|
||||
])),
|
||||
),
|
||||
];
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_fp2_by_nonresidue(fe: &Fq2) -> Fq2 {
|
||||
// (c0+u*c1)*(9+u) = (9*c0-c1)+u*(9*c1+c0)
|
||||
let mut f = *fe;
|
||||
f.double_in_place().double_in_place().double_in_place();
|
||||
let c0 = f.c0 + fe.c0 + Fq2Parameters::mul_fp_by_nonresidue(&fe.c1);
|
||||
let c1 = f.c1 + fe.c1 + fe.c0;
|
||||
field_new!(Fq2, c0, c1)
|
||||
}
|
||||
}
|
||||
95
bn254/src/fields/fr.rs
Normal file
95
bn254/src/fields/fr.rs
Normal file
@@ -0,0 +1,95 @@
|
||||
use ark_ff::{biginteger::BigInteger256 as BigInteger, fields::*};
|
||||
|
||||
pub type Fr = Fp256<FrParameters>;
|
||||
|
||||
pub struct FrParameters;
|
||||
|
||||
impl Fp256Parameters for FrParameters {}
|
||||
impl FftParameters for FrParameters {
|
||||
type BigInt = BigInteger;
|
||||
|
||||
const TWO_ADICITY: u32 = 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;
|
||||
|
||||
#[rustfmt::skip]
|
||||
const R: BigInteger = BigInteger([
|
||||
12436184717236109307u64,
|
||||
3962172157175319849u64,
|
||||
7381016538464732718u64,
|
||||
1011752739694698287u64,
|
||||
]);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const R2: BigInteger = BigInteger([
|
||||
1997599621687373223u64,
|
||||
6052339484930628067u64,
|
||||
10108755138030829701u64,
|
||||
150537098327114917u64,
|
||||
]);
|
||||
|
||||
const INV: u64 = 14042775128853446655u64;
|
||||
|
||||
// GENERATOR = 5
|
||||
#[rustfmt::skip]
|
||||
const GENERATOR: BigInteger = BigInteger([
|
||||
1949230679015292902u64,
|
||||
16913946402569752895u64,
|
||||
5177146667339417225u64,
|
||||
1571765431670520771u64,
|
||||
]);
|
||||
|
||||
/// (r - 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 = (r - 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,
|
||||
]);
|
||||
}
|
||||
27
bn254/src/fields/mod.rs
Normal file
27
bn254/src/fields/mod.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
#[cfg(feature = "scalar_field")]
|
||||
pub mod fr;
|
||||
#[cfg(feature = "scalar_field")]
|
||||
pub use self::fr::*;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub mod fq;
|
||||
#[cfg(feature = "curve")]
|
||||
pub use self::fq::*;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub mod fq2;
|
||||
#[cfg(feature = "curve")]
|
||||
pub use self::fq2::*;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub mod fq6;
|
||||
#[cfg(feature = "curve")]
|
||||
pub use self::fq6::*;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub mod fq12;
|
||||
#[cfg(feature = "curve")]
|
||||
pub use self::fq12::*;
|
||||
|
||||
#[cfg(all(feature = "curve", test))]
|
||||
mod tests;
|
||||
504
bn254/src/fields/tests.rs
Normal file
504
bn254/src/fields/tests.rs
Normal file
@@ -0,0 +1,504 @@
|
||||
use ark_ff::{
|
||||
biginteger::{BigInteger, BigInteger256},
|
||||
fields::{
|
||||
fp6_3over2::Fp6Parameters, FftField, FftParameters, Field, FpParameters, PrimeField,
|
||||
SquareRootField,
|
||||
},
|
||||
test_rng, One, UniformRand, Zero,
|
||||
};
|
||||
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
||||
use core::{
|
||||
cmp::Ordering,
|
||||
ops::{AddAssign, MulAssign, SubAssign},
|
||||
};
|
||||
use rand::{Rng, SeedableRng};
|
||||
use rand_xorshift::XorShiftRng;
|
||||
|
||||
use crate::{Fq, Fq12, Fq2, Fq6, Fq6Parameters, FqParameters, Fr};
|
||||
use ark_curve_tests::fields::*;
|
||||
|
||||
pub(crate) const ITERATIONS: usize = 5;
|
||||
|
||||
#[test]
|
||||
fn test_fr() {
|
||||
let mut rng = test_rng();
|
||||
for _ in 0..ITERATIONS {
|
||||
let a: Fr = rng.gen();
|
||||
let b: Fr = rng.gen();
|
||||
field_test(a, b);
|
||||
primefield_test::<Fr>();
|
||||
sqrt_field_test(b);
|
||||
let byte_size = a.serialized_size();
|
||||
field_serialization_test::<Fr>(byte_size);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq() {
|
||||
let mut rng = test_rng();
|
||||
for _ in 0..ITERATIONS {
|
||||
let a: Fq = rng.gen();
|
||||
let b: Fq = rng.gen();
|
||||
field_test(a, b);
|
||||
primefield_test::<Fq>();
|
||||
sqrt_field_test(a);
|
||||
let byte_size = a.serialized_size();
|
||||
let (_, buffer_size) = buffer_bit_byte_size(Fq::size_in_bits());
|
||||
assert_eq!(byte_size, buffer_size);
|
||||
field_serialization_test::<Fq>(byte_size);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq2() {
|
||||
let mut rng = test_rng();
|
||||
for _ in 0..ITERATIONS {
|
||||
let a: Fq2 = rng.gen();
|
||||
let b: Fq2 = rng.gen();
|
||||
field_test(a, b);
|
||||
sqrt_field_test(a);
|
||||
}
|
||||
frobenius_test::<Fq2, _>(Fq::characteristic(), 13);
|
||||
let byte_size = Fq2::zero().serialized_size();
|
||||
field_serialization_test::<Fq2>(byte_size);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq6() {
|
||||
let mut rng = test_rng();
|
||||
for _ in 0..ITERATIONS {
|
||||
let g: Fq6 = rng.gen();
|
||||
let h: Fq6 = rng.gen();
|
||||
field_test(g, h);
|
||||
}
|
||||
frobenius_test::<Fq6, _>(Fq::characteristic(), 13);
|
||||
let byte_size = Fq6::zero().serialized_size();
|
||||
field_serialization_test::<Fq6>(byte_size);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq12() {
|
||||
let mut rng = test_rng();
|
||||
for _ in 0..ITERATIONS {
|
||||
let g: Fq12 = rng.gen();
|
||||
let h: Fq12 = rng.gen();
|
||||
field_test(g, h);
|
||||
}
|
||||
frobenius_test::<Fq12, _>(Fq::characteristic(), 13);
|
||||
let byte_size = Fq12::zero().serialized_size();
|
||||
field_serialization_test::<Fq12>(byte_size);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_repr_from() {
|
||||
assert_eq!(BigInteger256::from(100), BigInteger256([100, 0, 0, 0]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_repr_is_odd() {
|
||||
assert!(!BigInteger256::from(0).is_odd());
|
||||
assert!(BigInteger256::from(0).is_even());
|
||||
assert!(BigInteger256::from(1).is_odd());
|
||||
assert!(!BigInteger256::from(1).is_even());
|
||||
assert!(!BigInteger256::from(324834872).is_odd());
|
||||
assert!(BigInteger256::from(324834872).is_even());
|
||||
assert!(BigInteger256::from(324834873).is_odd());
|
||||
assert!(!BigInteger256::from(324834873).is_even());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_repr_is_zero() {
|
||||
assert!(BigInteger256::from(0).is_zero());
|
||||
assert!(!BigInteger256::from(1).is_zero());
|
||||
assert!(!BigInteger256([0, 0, 1, 0]).is_zero());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_repr_num_bits() {
|
||||
let mut a = BigInteger256::from(0);
|
||||
assert_eq!(0, a.num_bits());
|
||||
a = BigInteger256::from(1);
|
||||
for i in 1..257 {
|
||||
assert_eq!(i, a.num_bits());
|
||||
a.mul2();
|
||||
}
|
||||
assert_eq!(0, a.num_bits());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_add_assign() {
|
||||
// Test associativity
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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 = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
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]
|
||||
fn test_fq_num_bits() {
|
||||
assert_eq!(FqParameters::MODULUS_BITS, 254);
|
||||
assert_eq!(FqParameters::CAPACITY, 253);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_root_of_unity() {
|
||||
assert_eq!(FqParameters::TWO_ADICITY, 1);
|
||||
assert_eq!(
|
||||
Fq::multiplicative_generator().pow([
|
||||
0x9e10460b6c3e7ea3,
|
||||
0xcbc0b548b438e546,
|
||||
0xdc2822db40c0ac2e,
|
||||
0x183227397098d014,
|
||||
]),
|
||||
Fq::two_adic_root_of_unity()
|
||||
);
|
||||
assert_eq!(
|
||||
Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]),
|
||||
Fq::one()
|
||||
);
|
||||
assert!(Fq::multiplicative_generator().sqrt().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_ordering() {
|
||||
// BigInteger256's ordering is well-tested, but we still need to make sure the
|
||||
// Fq elements aren't being compared in Montgomery form.
|
||||
for i in 0..100 {
|
||||
assert!(Fq::from(BigInteger256::from(i + 1)) > Fq::from(BigInteger256::from(i)));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_legendre() {
|
||||
use ark_ff::fields::LegendreSymbol::*;
|
||||
|
||||
assert_eq!(QuadraticResidue, Fq::one().legendre());
|
||||
assert_eq!(Zero, Fq::zero().legendre());
|
||||
assert_eq!(
|
||||
QuadraticResidue,
|
||||
Fq::from(BigInteger256::from(4)).legendre()
|
||||
);
|
||||
assert_eq!(
|
||||
QuadraticNonResidue,
|
||||
Fq::from(BigInteger256::from(5)).legendre()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq2_ordering() {
|
||||
let mut a = Fq2::new(Fq::zero(), Fq::zero());
|
||||
let mut b = a.clone();
|
||||
|
||||
assert!(a.cmp(&b) == Ordering::Equal);
|
||||
b.c0.add_assign(&Fq::one());
|
||||
assert!(a.cmp(&b) == Ordering::Less);
|
||||
a.c0.add_assign(&Fq::one());
|
||||
assert!(a.cmp(&b) == Ordering::Equal);
|
||||
b.c1.add_assign(&Fq::one());
|
||||
assert!(a.cmp(&b) == Ordering::Less);
|
||||
a.c0.add_assign(&Fq::one());
|
||||
assert!(a.cmp(&b) == Ordering::Less);
|
||||
a.c1.add_assign(&Fq::one());
|
||||
assert!(a.cmp(&b) == Ordering::Greater);
|
||||
b.c0.add_assign(&Fq::one());
|
||||
assert!(a.cmp(&b) == Ordering::Equal);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq2_basics() {
|
||||
assert_eq!(Fq2::new(Fq::zero(), Fq::zero(),), Fq2::zero());
|
||||
assert_eq!(Fq2::new(Fq::one(), Fq::zero(),), Fq2::one());
|
||||
assert!(Fq2::zero().is_zero());
|
||||
assert!(!Fq2::one().is_zero());
|
||||
assert!(!Fq2::new(Fq::zero(), Fq::one(),).is_zero());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq2_legendre() {
|
||||
use ark_ff::fields::LegendreSymbol::*;
|
||||
|
||||
assert_eq!(Zero, Fq2::zero().legendre());
|
||||
// i^2 = -1
|
||||
let mut m1 = -Fq2::one();
|
||||
assert_eq!(QuadraticResidue, m1.legendre());
|
||||
m1 = Fq6Parameters::mul_fp2_by_nonresidue(&m1);
|
||||
assert_eq!(QuadraticNonResidue, m1.legendre());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq6_mul_by_1() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..1000 {
|
||||
let c1 = Fq2::rand(&mut rng);
|
||||
let mut a = Fq6::rand(&mut rng);
|
||||
let mut b = a;
|
||||
|
||||
a.mul_by_1(&c1);
|
||||
b.mul_assign(&Fq6::new(Fq2::zero(), c1, Fq2::zero()));
|
||||
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq6_mul_by_01() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..1000 {
|
||||
let c0 = Fq2::rand(&mut rng);
|
||||
let c1 = Fq2::rand(&mut rng);
|
||||
let mut a = Fq6::rand(&mut rng);
|
||||
let mut b = a;
|
||||
|
||||
a.mul_by_01(&c0, &c1);
|
||||
b.mul_assign(&Fq6::new(c0, c1, Fq2::zero()));
|
||||
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq12_mul_by_014() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..1000 {
|
||||
let c0 = Fq2::rand(&mut rng);
|
||||
let c1 = Fq2::rand(&mut rng);
|
||||
let c5 = Fq2::rand(&mut rng);
|
||||
let mut a = Fq12::rand(&mut rng);
|
||||
let mut b = a;
|
||||
|
||||
a.mul_by_014(&c0, &c1, &c5);
|
||||
b.mul_assign(&Fq12::new(
|
||||
Fq6::new(c0, c1, Fq2::zero()),
|
||||
Fq6::new(Fq2::zero(), c5, Fq2::zero()),
|
||||
));
|
||||
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq12_mul_by_034() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..1000 {
|
||||
let c0 = Fq2::rand(&mut rng);
|
||||
let c3 = Fq2::rand(&mut rng);
|
||||
let c4 = Fq2::rand(&mut rng);
|
||||
let mut a = Fq12::rand(&mut rng);
|
||||
let mut b = a;
|
||||
|
||||
a.mul_by_034(&c0, &c3, &c4);
|
||||
b.mul_assign(&Fq12::new(
|
||||
Fq6::new(c0, Fq2::zero(), Fq2::zero()),
|
||||
Fq6::new(c3, c4, Fq2::zero()),
|
||||
));
|
||||
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
}
|
||||
40
bn254/src/lib.rs
Normal file
40
bn254/src/lib.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![deny(
|
||||
warnings,
|
||||
unused,
|
||||
future_incompatible,
|
||||
nonstandard_style,
|
||||
rust_2018_idioms
|
||||
)]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
//! This library implements the BN254 curve that was sampled as part of the [[BCTV14]][https://eprint.iacr.org/2013/879.pdf] paper .
|
||||
//! The name denotes that it is a Barreto--Naehrig curve of embedding degree 12,
|
||||
//! defined over a 254-bit (prime) field. The scalar field is highly 2-adic.
|
||||
//!
|
||||
//! This curve is also implemented in [libff](https://github.com/scipr-lab/libff/tree/master/libff/algebra/curves/alt_bn128) under the name `bn128`.
|
||||
//! It is the same as the `bn256` curve used in Ethereum (eg: [go-ethereum](https://github.com/ethereum/go-ethereum/tree/master/crypto/bn254/cloudflare)).
|
||||
//!
|
||||
//! #CAUTION
|
||||
//! **This curve does not satisfy the 128-bit security level anymore.**
|
||||
//!
|
||||
//!
|
||||
//! Curve information:
|
||||
//! * Base field: q = 21888242871839275222246405745257275088696311157297823662689037894645226208583
|
||||
//! * Scalar field: r = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||
//! * valuation(q - 1, 2) = 1
|
||||
//! * valuation(r - 1, 2) = 28
|
||||
//! * G1 curve equation: y^2 = x^3 + 3
|
||||
//! * G2 curve equation: y^2 = x^3 + B, where
|
||||
//! * B = 3/(u+9) where Fq2[u]=Fq/u+1
|
||||
//! = Fq2(19485874751759354771024239261021720505790618469301721065564631296452457478373, 266929791119991161246907387137283842545076965332900288569378510910307636690)
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
mod curves;
|
||||
|
||||
mod fields;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub use curves::*;
|
||||
|
||||
pub use fields::*;
|
||||
29
bw6_761/Cargo.toml
Normal file
29
bw6_761/Cargo.toml
Normal file
@@ -0,0 +1,29 @@
|
||||
[package]
|
||||
name = "ark-bw6-761"
|
||||
version = "0.1.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The BW6-761 pairing-friendly elliptic curve"
|
||||
homepage = "https://arworks.rs"
|
||||
repository = "https://github.com/arkworks/algebra"
|
||||
documentation = "https://docs.rs/ark-bw6-761/"
|
||||
keywords = ["cryptography", "finite fields", "elliptic curves" ]
|
||||
categories = ["cryptography"]
|
||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
license = "MIT/Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
ark-ff = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-ec = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false }
|
||||
ark-bls12-377 = { path = "../bls12_377", default-features = false, features = [ "base_field" ] }
|
||||
|
||||
[dev-dependencies]
|
||||
ark-serialize = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-curve-tests = { path = "../curve-tests", default-features = false }
|
||||
rand = { version = "0.7", default-features = false }
|
||||
rand_xorshift = "0.2"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std", "ark-bls12-377/std" ]
|
||||
113
bw6_761/src/curves/g1.rs
Normal file
113
bw6_761/src/curves/g1.rs
Normal file
@@ -0,0 +1,113 @@
|
||||
use crate::{Fq, Fr};
|
||||
use ark_ec::{
|
||||
models::{ModelParameters, SWModelParameters},
|
||||
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
|
||||
};
|
||||
use ark_ff::{
|
||||
biginteger::{BigInteger384, BigInteger768},
|
||||
field_new,
|
||||
};
|
||||
|
||||
pub type G1Affine = GroupAffine<Parameters>;
|
||||
pub type G1Projective = GroupProjective<Parameters>;
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct Parameters;
|
||||
|
||||
impl ModelParameters for Parameters {
|
||||
type BaseField = Fq;
|
||||
type ScalarField = Fr;
|
||||
}
|
||||
|
||||
impl SWModelParameters for Parameters {
|
||||
/// COEFF_A = 0
|
||||
#[rustfmt::skip]
|
||||
|
||||
const COEFF_A: Fq = field_new!(Fq, BigInteger768([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]));
|
||||
|
||||
/// COEFF_B = -1
|
||||
#[rustfmt::skip]
|
||||
const COEFF_B: Fq = field_new!(Fq, BigInteger768([
|
||||
0xf29a000000007ab6,
|
||||
0x8c391832e000739b,
|
||||
0x77738a6b6870f959,
|
||||
0xbe36179047832b03,
|
||||
0x84f3089e56574722,
|
||||
0xc5a3614ac0b1d984,
|
||||
0x5c81153f4906e9fe,
|
||||
0x4d28be3a9f55c815,
|
||||
0xd72c1d6f77d5f5c5,
|
||||
0x73a18e069ac04458,
|
||||
0xf9dfaa846595555f,
|
||||
0xd0f0a60a5be58c,
|
||||
]));
|
||||
|
||||
/// COFACTOR =
|
||||
/// 26642435879335816683987677701488073867751118270052650655942102502312977592501693353047140953112195348280268661194876
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR: &'static [u64] = &[
|
||||
0x3de580000000007c,
|
||||
0x832ba4061000003b,
|
||||
0xc61c554757551c0c,
|
||||
0xc856a0853c9db94c,
|
||||
0x2c77d5ac34cb12ef,
|
||||
0xad1972339049ce76,
|
||||
];
|
||||
|
||||
/// COFACTOR^(-1) mod r =
|
||||
/// 91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger384([
|
||||
489703175600125849,
|
||||
3883341943836920852,
|
||||
1678256062427438196,
|
||||
5848789333018172718,
|
||||
7127967896440782320,
|
||||
71512347676739162,
|
||||
]));
|
||||
|
||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||
(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 =
|
||||
/// 6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237
|
||||
#[rustfmt::skip]
|
||||
pub const G1_GENERATOR_X: Fq = field_new!(Fq, BigInteger768([
|
||||
0xd6e42d7614c2d770,
|
||||
0x4bb886eddbc3fc21,
|
||||
0x64648b044098b4d2,
|
||||
0x1a585c895a422985,
|
||||
0xf1a9ac17cf8685c9,
|
||||
0x352785830727aea5,
|
||||
0xddf8cb12306266fe,
|
||||
0x6913b4bfbc9e949a,
|
||||
0x3a4b78d67ba5f6ab,
|
||||
0x0f481c06a8d02a04,
|
||||
0x91d4e7365c43edac,
|
||||
0xf4d17cd48beca5,
|
||||
]));
|
||||
|
||||
/// G1_GENERATOR_Y =
|
||||
/// 2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099
|
||||
#[rustfmt::skip]
|
||||
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, BigInteger768([
|
||||
0x97e805c4bd16411f,
|
||||
0x870d844e1ee6dd08,
|
||||
0x1eba7a37cb9eab4d,
|
||||
0xd544c4df10b9889a,
|
||||
0x8fe37f21a33897be,
|
||||
0xe9bf99a43a0885d2,
|
||||
0xd7ee0c9e273de139,
|
||||
0xaa6a9ec7a38dd791,
|
||||
0x8f95d3fcf765da8e,
|
||||
0x42326e7db7357c99,
|
||||
0xe217e407e218695f,
|
||||
0x9d1eb23b7cf684,
|
||||
]));
|
||||
113
bw6_761/src/curves/g2.rs
Normal file
113
bw6_761/src/curves/g2.rs
Normal file
@@ -0,0 +1,113 @@
|
||||
use crate::{Fq, Fr};
|
||||
use ark_ec::{
|
||||
models::{ModelParameters, SWModelParameters},
|
||||
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
|
||||
};
|
||||
use ark_ff::{
|
||||
biginteger::{BigInteger384, BigInteger768},
|
||||
field_new,
|
||||
};
|
||||
|
||||
pub type G2Affine = GroupAffine<Parameters>;
|
||||
pub type G2Projective = GroupProjective<Parameters>;
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct Parameters;
|
||||
|
||||
impl ModelParameters for Parameters {
|
||||
type BaseField = Fq;
|
||||
type ScalarField = Fr;
|
||||
}
|
||||
|
||||
impl SWModelParameters for Parameters {
|
||||
/// COEFF_A = 0
|
||||
#[rustfmt::skip]
|
||||
|
||||
const COEFF_A: Fq = field_new!(Fq, BigInteger768([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]));
|
||||
|
||||
/// COEFF_B = 4
|
||||
#[rustfmt::skip]
|
||||
const COEFF_B: Fq = field_new!(Fq, BigInteger768([
|
||||
0x136efffffffe16c9,
|
||||
0x82cf5a6dcffe3319,
|
||||
0x6458c05f1f0e0741,
|
||||
0xd10ae605e52a4eda,
|
||||
0x41ca591c0266e100,
|
||||
0x7d0fd59c3626929f,
|
||||
0x9967dc004d00c112,
|
||||
0x1ccff9c033379af5,
|
||||
0x9ad6ec10a23f63af,
|
||||
0x5cec11251a72c235,
|
||||
0x8d18b1ae789ba83e,
|
||||
10403402007434220,
|
||||
]));
|
||||
|
||||
/// COFACTOR =
|
||||
/// 26642435879335816683987677701488073867751118270052650655942102502312977592501693353047140953112195348280268661194869
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR: &'static [u64] = &[
|
||||
0x3de5800000000075,
|
||||
0x832ba4061000003b,
|
||||
0xc61c554757551c0c,
|
||||
0xc856a0853c9db94c,
|
||||
0x2c77d5ac34cb12ef,
|
||||
0xad1972339049ce76,
|
||||
];
|
||||
|
||||
/// COFACTOR^(-1) mod r =
|
||||
/// 214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger384([
|
||||
14378295991815829998,
|
||||
14586153992421458638,
|
||||
9788477762582722914,
|
||||
12654821707953664524,
|
||||
15185631607604703397,
|
||||
26723985783783076,
|
||||
]));
|
||||
|
||||
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||
(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 =
|
||||
/// 6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_X: Fq = field_new!(Fq, BigInteger768([
|
||||
0x3d902a84cd9f4f78,
|
||||
0x864e451b8a9c05dd,
|
||||
0xc2b3c0d6646c5673,
|
||||
0x17a7682def1ecb9d,
|
||||
0xbe31a1e0fb768fe3,
|
||||
0x4df125e09b92d1a6,
|
||||
0x0943fce635b02ee9,
|
||||
0xffc8e7ad0605e780,
|
||||
0x8165c00a39341e95,
|
||||
0x8ccc2ae90a0f094f,
|
||||
0x73a8b8cc0ad09e0c,
|
||||
0x11027e203edd9f4,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_Y =
|
||||
/// 562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_Y: Fq = field_new!(Fq, BigInteger768([
|
||||
0x9a159be4e773f67c,
|
||||
0x6b957244aa8f4e6b,
|
||||
0xa27b70c9c945a38c,
|
||||
0xacb6a09fda11d0ab,
|
||||
0x3abbdaa9bb6b1291,
|
||||
0xdbdf642af5694c36,
|
||||
0xb6360bb9560b369f,
|
||||
0xac0bd1e822b8d6da,
|
||||
0xfa355d17afe6945f,
|
||||
0x8d6a0fc1fbcad35e,
|
||||
0x72a63c7874409840,
|
||||
0x114976e5b0db280,
|
||||
]));
|
||||
61
bw6_761/src/curves/mod.rs
Normal file
61
bw6_761/src/curves/mod.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use crate::*;
|
||||
use ark_ec::{
|
||||
bw6,
|
||||
bw6::{BW6Parameters, TwistType, BW6},
|
||||
};
|
||||
use ark_ff::biginteger::BigInteger768 as BigInteger;
|
||||
|
||||
pub mod g1;
|
||||
pub mod g2;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct Parameters;
|
||||
|
||||
impl BW6Parameters for Parameters {
|
||||
const X: BigInteger = BigInteger([
|
||||
0x8508c00000000001,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
]);
|
||||
/// `x` is positive.
|
||||
const X_IS_NEGATIVE: bool = false;
|
||||
// X+1
|
||||
const ATE_LOOP_COUNT_1: &'static [u64] = &[0x8508c00000000002];
|
||||
const ATE_LOOP_COUNT_1_IS_NEGATIVE: bool = false;
|
||||
// X^3-X^2-X
|
||||
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,
|
||||
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, 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, 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,
|
||||
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 TWIST_TYPE: TwistType = TwistType::M;
|
||||
type Fp = Fq;
|
||||
type Fp3Params = Fq3Parameters;
|
||||
type Fp6Params = Fq6Parameters;
|
||||
type G1Parameters = g1::Parameters;
|
||||
type G2Parameters = g2::Parameters;
|
||||
}
|
||||
|
||||
pub type BW6_761 = BW6<Parameters>;
|
||||
|
||||
pub type G1Affine = bw6::G1Affine<Parameters>;
|
||||
pub type G1Projective = bw6::G1Projective<Parameters>;
|
||||
pub type G2Affine = bw6::G2Affine<Parameters>;
|
||||
pub type G2Projective = bw6::G2Projective<Parameters>;
|
||||
77
bw6_761/src/curves/tests.rs
Normal file
77
bw6_761/src/curves/tests.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve};
|
||||
use ark_ff::{test_rng, Field, One, PrimeField};
|
||||
use rand::Rng;
|
||||
|
||||
use crate::*;
|
||||
|
||||
use ark_curve_tests::{curves::*, groups::*};
|
||||
|
||||
#[test]
|
||||
fn test_g1_projective_curve() {
|
||||
curve_tests::<G1Projective>();
|
||||
|
||||
sw_tests::<g1::Parameters>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g1_projective_group() {
|
||||
let mut rng = test_rng();
|
||||
let a: G1Projective = rng.gen();
|
||||
let b: G1Projective = rng.gen();
|
||||
group_test(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g1_generator() {
|
||||
let generator = G1Affine::prime_subgroup_generator();
|
||||
assert!(generator.is_on_curve());
|
||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g2_projective_curve() {
|
||||
curve_tests::<G2Projective>();
|
||||
|
||||
sw_tests::<g2::Parameters>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g2_projective_group() {
|
||||
let mut rng = test_rng();
|
||||
let a: G2Projective = rng.gen();
|
||||
let b: G2Projective = rng.gen();
|
||||
group_test(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g2_generator() {
|
||||
let generator = G2Affine::prime_subgroup_generator();
|
||||
assert!(generator.is_on_curve());
|
||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bilinearity() {
|
||||
let mut rng = test_rng();
|
||||
let a: G1Projective = rng.gen();
|
||||
let b: G2Projective = rng.gen();
|
||||
let s: Fr = rng.gen();
|
||||
|
||||
let sa = a.mul(s);
|
||||
let sb = b.mul(s);
|
||||
|
||||
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());
|
||||
}
|
||||
175
bw6_761/src/fields/fq.rs
Normal file
175
bw6_761/src/fields/fq.rs
Normal file
@@ -0,0 +1,175 @@
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger768 as BigInteger,
|
||||
field_new,
|
||||
fields::{FftParameters, Fp768, Fp768Parameters, FpParameters},
|
||||
};
|
||||
|
||||
pub type Fq = Fp768<FqParameters>;
|
||||
|
||||
pub struct FqParameters;
|
||||
|
||||
pub const FQ_ONE: Fq = field_new!(Fq, FqParameters::R);
|
||||
pub const FQ_ZERO: Fq = field_new!(Fq, BigInteger([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,
|
||||
]);
|
||||
}
|
||||
200
bw6_761/src/fields/fq3.rs
Normal file
200
bw6_761/src/fields/fq3.rs
Normal file
@@ -0,0 +1,200 @@
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger768 as BigInteger,
|
||||
field_new,
|
||||
fields::fp3::{Fp3, Fp3Parameters},
|
||||
};
|
||||
|
||||
use crate::Fq;
|
||||
|
||||
pub type Fq3 = Fp3<Fq3Parameters>;
|
||||
|
||||
pub struct Fq3Parameters;
|
||||
|
||||
impl Fp3Parameters for Fq3Parameters {
|
||||
type Fp = Fq;
|
||||
|
||||
/// NONRESIDUE = -4
|
||||
// Fq3 = Fq[u]/u^3+4
|
||||
#[rustfmt::skip]
|
||||
const NONRESIDUE: Fq = field_new!(Fq, BigInteger([
|
||||
0xe12e00000001e9c2,
|
||||
0x63c1e3faa001cd69,
|
||||
0xb1b4384fcbe29cf6,
|
||||
0xc79630bc713d5a1d,
|
||||
0x30127ac071851e2d,
|
||||
0x0979f350dcd36af1,
|
||||
0x6a66defed8b361f2,
|
||||
0x53abac78b24d4e23,
|
||||
0xb7ab89dede485a92,
|
||||
0x5c3a0745675e8452,
|
||||
0x446f17918c5f5700,
|
||||
0xfdf24e3267fa1e,
|
||||
]));
|
||||
|
||||
// (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 T_MINUS_ONE_DIV_TWO: &'static [u64] = &[
|
||||
0xb5e7c000000a3eac,
|
||||
0xf79b99dbf41cf4ab,
|
||||
0xe9372b1919e55ee5,
|
||||
0xbb7bbc4936c1980b,
|
||||
0x7c0cb9d4399b36e1,
|
||||
0x73304a5507bb1ae0,
|
||||
0x92f639be8963936f,
|
||||
0x4f574ac2439ba816,
|
||||
0x670d9bd389dd29ef,
|
||||
0x606ddf900d2124f1,
|
||||
0x928fb14985ec3270,
|
||||
0x6b2f2428c5f420f3,
|
||||
0xac9ade29d5ab5fbe,
|
||||
0xec0d0434c4005822,
|
||||
0x973f10d7f3c5c108,
|
||||
0x6d5e83fc81095979,
|
||||
0xdac3e6e4e1647752,
|
||||
0x227febf93994603e,
|
||||
0x4ab8755d894167d1,
|
||||
0x4fd2d3f67d8b537a,
|
||||
0x33e196a4d5f4030a,
|
||||
0x88b51fb72092df1a,
|
||||
0xa67e5b1e8fc48316,
|
||||
0xb0855eb2a00d7dab,
|
||||
0xe875dd2da6751442,
|
||||
0x777594a243e25676,
|
||||
0x294e0f70376a85a8,
|
||||
0x83f431c7988e4f18,
|
||||
0x8e8fb6af3ca2f5f1,
|
||||
0x7297896b4b9e90f1,
|
||||
0xff38f54664d66123,
|
||||
0xb5ecf80bfff41e13,
|
||||
0x1662a3666bb8392a,
|
||||
0x07a0968e8742d3e1,
|
||||
0xf12927e564bcdfdc,
|
||||
0x5de9825a0e,
|
||||
];
|
||||
|
||||
// NONRESIDUE^T % q
|
||||
#[rustfmt::skip]
|
||||
const QUADRATIC_NONRESIDUE_TO_T: (Fq, Fq, Fq) = (
|
||||
field_new!(Fq, BigInteger([
|
||||
0xf29a000000007ab6,
|
||||
0x8c391832e000739b,
|
||||
0x77738a6b6870f959,
|
||||
0xbe36179047832b03,
|
||||
0x84f3089e56574722,
|
||||
0xc5a3614ac0b1d984,
|
||||
0x5c81153f4906e9fe,
|
||||
0x4d28be3a9f55c815,
|
||||
0xd72c1d6f77d5f5c5,
|
||||
0x73a18e069ac04458,
|
||||
0xf9dfaa846595555f,
|
||||
0xd0f0a60a5be58c,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])),
|
||||
field_new!(Fq, BigInteger([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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] = &[
|
||||
field_new!(Fq, BigInteger([
|
||||
0x0202ffffffff85d5,
|
||||
0x5a5826358fff8ce7,
|
||||
0x9e996e43827faade,
|
||||
0xda6aff320ee47df4,
|
||||
0xece9cb3e1d94b80b,
|
||||
0xc0e667a25248240b,
|
||||
0xa74da5bfdcad3905,
|
||||
0x2352e7fe462f2103,
|
||||
0x7b56588008b1c87c,
|
||||
0x45848a63e711022f,
|
||||
0xd7a81ebb9f65a9df,
|
||||
0x51f77ef127e87d,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0x7f96b51bd840c549,
|
||||
0xd59782096496171f,
|
||||
0x49b046fd9ce14bbc,
|
||||
0x4b6163bba7527a56,
|
||||
0xef6c92fb771d59f1,
|
||||
0x0425bedbac1dfdc7,
|
||||
0xd3ac39de759c0ffd,
|
||||
0x9f43ed0e063a81d0,
|
||||
0x5bd7d20b4f9a3ce2,
|
||||
0x0411f03c36cf5c3c,
|
||||
0x2d658fd49661c472,
|
||||
0x1100249ae760b93,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0x67a04ae427bfb5f8,
|
||||
0x9d32d491eb6a5cff,
|
||||
0x43d03c1cb68051d4,
|
||||
0x0b75ca96f69859a5,
|
||||
0x0763497f5325ec60,
|
||||
0x48076b5c278dd94d,
|
||||
0x8ca3965ff91efd06,
|
||||
0x1e6077657ea02f5d,
|
||||
0xcdd6c153a8c37724,
|
||||
0x28b5b634e5c22ea4,
|
||||
0x9e01e3efd42e902c,
|
||||
0xe3d6815769a804,
|
||||
|
||||
])),
|
||||
];
|
||||
|
||||
// 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] = &[
|
||||
field_new!(Fq, BigInteger([
|
||||
0x0202ffffffff85d5,
|
||||
0x5a5826358fff8ce7,
|
||||
0x9e996e43827faade,
|
||||
0xda6aff320ee47df4,
|
||||
0xece9cb3e1d94b80b,
|
||||
0xc0e667a25248240b,
|
||||
0xa74da5bfdcad3905,
|
||||
0x2352e7fe462f2103,
|
||||
0x7b56588008b1c87c,
|
||||
0x45848a63e711022f,
|
||||
0xd7a81ebb9f65a9df,
|
||||
0x51f77ef127e87d,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0x67a04ae427bfb5f8,
|
||||
0x9d32d491eb6a5cff,
|
||||
0x43d03c1cb68051d4,
|
||||
0x0b75ca96f69859a5,
|
||||
0x0763497f5325ec60,
|
||||
0x48076b5c278dd94d,
|
||||
0x8ca3965ff91efd06,
|
||||
0x1e6077657ea02f5d,
|
||||
0xcdd6c153a8c37724,
|
||||
0x28b5b634e5c22ea4,
|
||||
0x9e01e3efd42e902c,
|
||||
0xe3d6815769a804,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0x7f96b51bd840c549,
|
||||
0xd59782096496171f,
|
||||
0x49b046fd9ce14bbc,
|
||||
0x4b6163bba7527a56,
|
||||
0xef6c92fb771d59f1,
|
||||
0x0425bedbac1dfdc7,
|
||||
0xd3ac39de759c0ffd,
|
||||
0x9f43ed0e063a81d0,
|
||||
0x5bd7d20b4f9a3ce2,
|
||||
0x0411f03c36cf5c3c,
|
||||
0x2d658fd49661c472,
|
||||
0x1100249ae760b93,
|
||||
])),
|
||||
];
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_fp_by_nonresidue(fe: &Self::Fp) -> Self::Fp {
|
||||
let original = -(*fe);
|
||||
let double = original + &original;
|
||||
double + &double
|
||||
}
|
||||
}
|
||||
106
bw6_761/src/fields/fq6.rs
Normal file
106
bw6_761/src/fields/fq6.rs
Normal file
@@ -0,0 +1,106 @@
|
||||
use crate::{Fq, Fq3, Fq3Parameters, FQ_ONE, FQ_ZERO};
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger768 as BigInteger,
|
||||
field_new,
|
||||
fields::fp6_2over3::{Fp6, Fp6Parameters},
|
||||
};
|
||||
|
||||
pub type Fq6 = Fp6<Fq6Parameters>;
|
||||
|
||||
pub struct Fq6Parameters;
|
||||
|
||||
impl Fp6Parameters for Fq6Parameters {
|
||||
type Fp3Params = Fq3Parameters;
|
||||
|
||||
/// NONRESIDUE = (0, 1, 0)
|
||||
#[rustfmt::skip]
|
||||
const NONRESIDUE: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[
|
||||
field_new!(Fq, BigInteger([
|
||||
0x0202ffffffff85d5,
|
||||
0x5a5826358fff8ce7,
|
||||
0x9e996e43827faade,
|
||||
0xda6aff320ee47df4,
|
||||
0xece9cb3e1d94b80b,
|
||||
0xc0e667a25248240b,
|
||||
0xa74da5bfdcad3905,
|
||||
0x2352e7fe462f2103,
|
||||
0x7b56588008b1c87c,
|
||||
0x45848a63e711022f,
|
||||
0xd7a81ebb9f65a9df,
|
||||
0x51f77ef127e87d,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0x8cfcb51bd8404a93,
|
||||
0x495e69d68495a383,
|
||||
0xd23cbc9234705263,
|
||||
0x8d2b4c2b5fcf4f52,
|
||||
0x6a798a5d20c612ce,
|
||||
0x3e825d90eb6c2443,
|
||||
0x772b249f2c9525fe,
|
||||
0x521b2ed366e4b9bb,
|
||||
0x84abb49bd7c4471d,
|
||||
0x907062359c0f17e3,
|
||||
0x3385e55030cc6f12,
|
||||
0x3f11a3a41a2606,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0x7f96b51bd840c549,
|
||||
0xd59782096496171f,
|
||||
0x49b046fd9ce14bbc,
|
||||
0x4b6163bba7527a56,
|
||||
0xef6c92fb771d59f1,
|
||||
0x0425bedbac1dfdc7,
|
||||
0xd3ac39de759c0ffd,
|
||||
0x9f43ed0e063a81d0,
|
||||
0x5bd7d20b4f9a3ce2,
|
||||
0x0411f03c36cf5c3c,
|
||||
0x2d658fd49661c472,
|
||||
0x1100249ae760b93,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0xf29a000000007ab6,
|
||||
0x8c391832e000739b,
|
||||
0x77738a6b6870f959,
|
||||
0xbe36179047832b03,
|
||||
0x84f3089e56574722,
|
||||
0xc5a3614ac0b1d984,
|
||||
0x5c81153f4906e9fe,
|
||||
0x4d28be3a9f55c815,
|
||||
0xd72c1d6f77d5f5c5,
|
||||
0x73a18e069ac04458,
|
||||
0xf9dfaa846595555f,
|
||||
0xd0f0a60a5be58c,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0x67a04ae427bfb5f8,
|
||||
0x9d32d491eb6a5cff,
|
||||
0x43d03c1cb68051d4,
|
||||
0x0b75ca96f69859a5,
|
||||
0x0763497f5325ec60,
|
||||
0x48076b5c278dd94d,
|
||||
0x8ca3965ff91efd06,
|
||||
0x1e6077657ea02f5d,
|
||||
0xcdd6c153a8c37724,
|
||||
0x28b5b634e5c22ea4,
|
||||
0x9e01e3efd42e902c,
|
||||
0xe3d6815769a804,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0x75064ae427bf3b42,
|
||||
0x10f9bc5f0b69e963,
|
||||
0xcc5cb1b14e0f587b,
|
||||
0x4d3fb306af152ea1,
|
||||
0x827040e0fccea53d,
|
||||
0x82640a1166dbffc8,
|
||||
0x30228120b0181307,
|
||||
0xd137b92adf4a6748,
|
||||
0xf6aaa3e430ed815e,
|
||||
0xb514282e4b01ea4b,
|
||||
0xa422396b6e993acc,
|
||||
0x12e5db4d0dc277,
|
||||
])),
|
||||
];
|
||||
}
|
||||
1
bw6_761/src/fields/fr.rs
Normal file
1
bw6_761/src/fields/fr.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub use ark_bls12_377::{Fq as Fr, FqParameters as FrParameters};
|
||||
14
bw6_761/src/fields/mod.rs
Normal file
14
bw6_761/src/fields/mod.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
pub mod fr;
|
||||
pub use self::fr::*;
|
||||
|
||||
pub mod fq;
|
||||
pub use self::fq::*;
|
||||
|
||||
pub mod fq3;
|
||||
pub use self::fq3::*;
|
||||
|
||||
pub mod fq6;
|
||||
pub use self::fq6::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
51
bw6_761/src/fields/tests.rs
Normal file
51
bw6_761/src/fields/tests.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
use ark_ff::{test_rng, Field, PrimeField};
|
||||
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
||||
use rand::Rng;
|
||||
|
||||
use crate::*;
|
||||
|
||||
use ark_curve_tests::fields::*;
|
||||
|
||||
#[test]
|
||||
fn test_fr() {
|
||||
let mut rng = test_rng();
|
||||
let a: Fr = rng.gen();
|
||||
let b: Fr = rng.gen();
|
||||
field_test(a, b);
|
||||
sqrt_field_test(a);
|
||||
primefield_test::<Fr>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq() {
|
||||
let mut rng = test_rng();
|
||||
let a: Fq = rng.gen();
|
||||
let b: Fq = rng.gen();
|
||||
field_test(a, b);
|
||||
primefield_test::<Fq>();
|
||||
sqrt_field_test(a);
|
||||
|
||||
let byte_size = a.serialized_size();
|
||||
let (_, buffer_size) = buffer_bit_byte_size(Fq::size_in_bits());
|
||||
assert_eq!(byte_size, buffer_size);
|
||||
field_serialization_test::<Fq>(byte_size);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq3() {
|
||||
let mut rng = test_rng();
|
||||
let a: Fq3 = rng.gen();
|
||||
let b: Fq3 = rng.gen();
|
||||
field_test(a, b);
|
||||
sqrt_field_test(a);
|
||||
frobenius_test::<Fq3, _>(Fq::characteristic(), 13);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq6() {
|
||||
let mut rng = test_rng();
|
||||
let a: Fq6 = rng.gen();
|
||||
let b: Fq6 = rng.gen();
|
||||
field_test(a, b);
|
||||
frobenius_test::<Fq6, _>(Fq::characteristic(), 13);
|
||||
}
|
||||
34
bw6_761/src/lib.rs
Normal file
34
bw6_761/src/lib.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![deny(
|
||||
warnings,
|
||||
unused,
|
||||
future_incompatible,
|
||||
nonstandard_style,
|
||||
rust_2018_idioms
|
||||
)]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
//! This library implements the BW6_761 curve generated in [[EG20]](https://eprint.iacr.org/2020/351).
|
||||
//! The name denotes that it is a curve generated using the Brezing--Weng method, and that
|
||||
//! its embedding degree is 6.
|
||||
//! The main feature of this curve is that the scalar field equals the base field of the BLS12_377 curve.
|
||||
//!
|
||||
//! Curve information:
|
||||
//! * Base field: q = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299
|
||||
//! * Scalar field: r = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
|
||||
//! * valuation(q - 1, 2) = 1
|
||||
//! * valuation(r - 1, 2) = 46
|
||||
//!
|
||||
//! G1 curve equation: y^2 = x^3 + ax + b, where
|
||||
//! * a = 0,
|
||||
//! * b = -1,
|
||||
//!
|
||||
//! G2 curve equation: y^2 = x^3 + Ax + B
|
||||
//! * A = 0
|
||||
//! * B = 4
|
||||
|
||||
mod curves;
|
||||
mod fields;
|
||||
|
||||
pub use curves::*;
|
||||
pub use fields::*;
|
||||
29
cp6_782/Cargo.toml
Normal file
29
cp6_782/Cargo.toml
Normal file
@@ -0,0 +1,29 @@
|
||||
[package]
|
||||
name = "ark-cp6-782"
|
||||
version = "0.1.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The CP6-782 pairing-friendly elliptic curve"
|
||||
homepage = "https://arworks.rs"
|
||||
repository = "https://github.com/arkworks/algebra"
|
||||
documentation = "https://docs.rs/ark-cp6-782/"
|
||||
keywords = ["cryptography", "finite fields", "elliptic curves" ]
|
||||
categories = ["cryptography"]
|
||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
license = "MIT/Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
ark-ff = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-ec = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false }
|
||||
ark-bls12-377 = { path = "../bls12_377", default-features = false, features = [ "base_field" ] }
|
||||
|
||||
[dev-dependencies]
|
||||
ark-serialize = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-curve-tests = { path = "../curve-tests", default-features = false }
|
||||
rand = { version = "0.7", default-features = false }
|
||||
rand_xorshift = "0.2"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std", "ark-bls12-377/std" ]
|
||||
126
cp6_782/src/curves/g1.rs
Normal file
126
cp6_782/src/curves/g1.rs
Normal file
@@ -0,0 +1,126 @@
|
||||
use ark_ec::{
|
||||
models::{ModelParameters, SWModelParameters},
|
||||
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
|
||||
};
|
||||
use ark_ff::{
|
||||
biginteger::{BigInteger384, BigInteger832},
|
||||
field_new,
|
||||
};
|
||||
|
||||
use crate::{Fq, Fr};
|
||||
|
||||
pub type G1Affine = GroupAffine<Parameters>;
|
||||
pub type G1Projective = GroupProjective<Parameters>;
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct Parameters;
|
||||
|
||||
impl ModelParameters for Parameters {
|
||||
type BaseField = Fq;
|
||||
type ScalarField = Fr;
|
||||
}
|
||||
|
||||
impl SWModelParameters for Parameters {
|
||||
/// COEFF_A = 5
|
||||
#[rustfmt::skip]
|
||||
const COEFF_A: Fq = field_new!(Fq, BigInteger832([
|
||||
0x781c76643018bd7a,
|
||||
0x64f3a5a4f1d1ad48,
|
||||
0xd2f8a1eb4f72692d,
|
||||
0xc35eb123c6ed72ca,
|
||||
0xb58d6bcfd32de058,
|
||||
0x841eab13b02a492c,
|
||||
0x4b70dc5a54c487e7,
|
||||
0x2f231a8808a74c59,
|
||||
0x5e2915154d70b050,
|
||||
0x8a40fa16f37a6b37,
|
||||
0xd01980093a72c54b,
|
||||
0xef6845c25398004c,
|
||||
0x48,
|
||||
]));
|
||||
|
||||
/// COEFF_B = 17764315118651679038286329069295091506801468118146712649886336045535808055361274148466772191243305528312843236347777260247138934336850548243151534538734724191505953341403463040067571652261229308333392040104884438208594329793895206056414
|
||||
#[rustfmt::skip]
|
||||
const COEFF_B: Fq = field_new!(Fq, BigInteger832([
|
||||
0xec5bd271ad37429,
|
||||
0x9db8ac843ecca28a,
|
||||
0x94f29bcb7e01bc74,
|
||||
0x1b0bebb77bb5af0,
|
||||
0x75b8cef4aa27ee17,
|
||||
0xb5767ae80812cf6b,
|
||||
0x592fa41e377a0d8c,
|
||||
0xb6c6deedbb52df3e,
|
||||
0xcb1343e488737fd4,
|
||||
0x878020734d05b5a9,
|
||||
0x2f51354eddfa069a,
|
||||
0x498e2ecdc545243e,
|
||||
0x2c2,
|
||||
]));
|
||||
|
||||
/// COFACTOR =
|
||||
/// 86482221941698704497288378992285180119495364068003923046442785886272123124361700722982503222189455144364945735564951561028
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR: &'static [u64] = &[
|
||||
0x5657b9b57b942344,
|
||||
0x84f9a65f3bd54eaf,
|
||||
0x5ea4214e35cd127,
|
||||
0xe3cbcbc14ec1501d,
|
||||
0xf196cb845a3092ab,
|
||||
0x7e14627ad0e19017,
|
||||
0x217db4,
|
||||
];
|
||||
|
||||
/// COFACTOR^(-1) mod r =
|
||||
/// 163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger384([
|
||||
4179837108212676264,
|
||||
15545810469293120493,
|
||||
13202863094424182470,
|
||||
9506285060796071546,
|
||||
9248558385029790142,
|
||||
87030208545296111,
|
||||
]));
|
||||
|
||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||
(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||
}
|
||||
|
||||
/// G1_GENERATOR_X =
|
||||
/// 5511163824921585887915590525772884263960974614921003940645351443740084257508990841338974915037175497689287870585840954231884082785026301437744745393958283053278991955159266640440849940136976927372133743626748847559939620888818486853646
|
||||
#[rustfmt::skip]
|
||||
pub const G1_GENERATOR_X: Fq = field_new!(Fq, BigInteger832([
|
||||
0x5901480e5bc22290,
|
||||
0x20024afcdb9bd3a9,
|
||||
0x12dc18ff416e8138,
|
||||
0x28c69aa0ea223e18,
|
||||
0xafb1524a1eb7efe6,
|
||||
0x3d5c34edc3764ca2,
|
||||
0x736c2230c8466ce9,
|
||||
0xacfaa04e051014f1,
|
||||
0x5d5ff82f00ff2964,
|
||||
0x64c13ba270a26eaf,
|
||||
0x50e9864b56ab172e,
|
||||
0xd8370826a322499e,
|
||||
0x00000000000006f1,
|
||||
]));
|
||||
|
||||
/// G1_GENERATOR_Y =
|
||||
/// 7913123550914612057135582061699117755797758113868200992327595317370485234417808273674357776714522052694559358668442301647906991623400754234679697332299689255516547752391831738454121261248793568285885897998257357202903170202349380518443
|
||||
#[rustfmt::skip]
|
||||
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, BigInteger832([
|
||||
0x8af8b64b402e1953,
|
||||
0xd1bbceb3a258ea51,
|
||||
0xdca9efa3140aaa0d,
|
||||
0x807a610058ddedb2,
|
||||
0xeb898562fe88076c,
|
||||
0x0e4342ca56dd8ce2,
|
||||
0x4f5528d29f1bde9a,
|
||||
0xf18b0c6c19feb372,
|
||||
0x94503ac2fac9199c,
|
||||
0xffc86a8aff08ea34,
|
||||
0xf7b1295214735d8c,
|
||||
0x44eda9e0f55edd10,
|
||||
0x0000000000000ef3,
|
||||
]));
|
||||
241
cp6_782/src/curves/g2.rs
Normal file
241
cp6_782/src/curves/g2.rs
Normal file
@@ -0,0 +1,241 @@
|
||||
use ark_ec::{
|
||||
models::{ModelParameters, SWModelParameters},
|
||||
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
|
||||
};
|
||||
use ark_ff::{
|
||||
biginteger::{BigInteger384, BigInteger832},
|
||||
field_new,
|
||||
};
|
||||
|
||||
use crate::{Fq, Fq3, Fr, FQ_ZERO};
|
||||
|
||||
pub type G2Affine = GroupAffine<Parameters>;
|
||||
pub type G2Projective = GroupProjective<Parameters>;
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct Parameters;
|
||||
|
||||
impl ModelParameters for Parameters {
|
||||
type BaseField = Fq3;
|
||||
type ScalarField = Fr;
|
||||
}
|
||||
|
||||
impl SWModelParameters for Parameters {
|
||||
/// COEFF_A = (0, 0, COEFF_A * TWIST^2) = (0, 0, 5)
|
||||
#[rustfmt::skip]
|
||||
const COEFF_A: Fq3 = field_new!(Fq3,
|
||||
FQ_ZERO,
|
||||
FQ_ZERO,
|
||||
field_new!(Fq, BigInteger832([
|
||||
0x781c76643018bd7a,
|
||||
0x64f3a5a4f1d1ad48,
|
||||
0xd2f8a1eb4f72692d,
|
||||
0xc35eb123c6ed72ca,
|
||||
0xb58d6bcfd32de058,
|
||||
0x841eab13b02a492c,
|
||||
0x4b70dc5a54c487e7,
|
||||
0x2f231a8808a74c59,
|
||||
0x5e2915154d70b050,
|
||||
0x8a40fa16f37a6b37,
|
||||
0xd01980093a72c54b,
|
||||
0xef6845c25398004c,
|
||||
0x48,
|
||||
])),
|
||||
);
|
||||
|
||||
/// COEFF_B = (G1::COEFF_B * TWIST^3, 0, 0) =
|
||||
/// (7237353553714858194254855835825640240663090882935418626687402315497764195116318527743248304684159666286416318482685337633828994152723793439622384740540789612754127688659139509552568164770448654259255628317166934203899992395064470477612,
|
||||
/// 0, 0)
|
||||
#[rustfmt::skip]
|
||||
const COEFF_B: Fq3 = field_new!(Fq3,
|
||||
field_new!(Fq, BigInteger832([
|
||||
0xc00a9afc5cbce615,
|
||||
0x0260c2b730644102,
|
||||
0x9051e955661691ec,
|
||||
0x15f9af8514839e37,
|
||||
0xfa62826ca407172b,
|
||||
0x37043dc868f48874,
|
||||
0x876b5588d132b025,
|
||||
0x481952128335562a,
|
||||
0x4ffa729aeddd7dcd,
|
||||
0xe181a5dae94a399f,
|
||||
0x671fb50145b255d8,
|
||||
0xbc3860730482d728,
|
||||
0x00000000000023dd,
|
||||
])),
|
||||
FQ_ZERO,
|
||||
FQ_ZERO,
|
||||
);
|
||||
|
||||
/// COFACTOR =
|
||||
/// 43276679045916726782882096851503554444292580777869919574700824986947162516693702667493938255647666346010819253090121562084993205202476199057555142869892665220155573207800985012241638987472334344174208389303164492698303448192856551557283997344470334833850065978668184377503856699635686872344035470027430053642178229054516302338812152178131995800255516474185251732445975837621097393375441662426280154371264547168198834382681059556891327702516519955053315674076980350109237328216856859758931256208439575383786363605925879337208599843910819433766160937121108797819223653884174994325142959644019600
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR: &'static [u64] = &[
|
||||
0x4b77fca151d50b90,
|
||||
0x8c98a12bd486d2fb,
|
||||
0x1f0c9a51593693f8,
|
||||
0x1d6f388069c063c1,
|
||||
0x556e918748f06793,
|
||||
0x2cea7dc01aae2140,
|
||||
0x4216f0595cee44d0,
|
||||
0x7a5e400154f633cf,
|
||||
0xbb74eb9b6630846b,
|
||||
0x8eb48c92998f3358,
|
||||
0xbedd37f629e8e634,
|
||||
0xc541018fe4d10cc7,
|
||||
0x574956a099ace2c3,
|
||||
0xa597504275948226,
|
||||
0x7ecaaf050acb91f3,
|
||||
0x0f25b044f4e9c932,
|
||||
0xf8c39cbf0df97780,
|
||||
0xd8f9eda95d6abf3e,
|
||||
0xd1d80da227dd39c1,
|
||||
0x8b589c61531dbce7,
|
||||
0xfee4439281455474,
|
||||
0x9eea59baa2aeb4a1,
|
||||
0xa3b8a42c4e1e6f5a,
|
||||
0xc4b99b0d9b077d21,
|
||||
0xd09033887d09b4d2,
|
||||
0x4a86d8ebb7fdf52a,
|
||||
0xbe7ce44dd084e05d,
|
||||
0x4ed25f7ebe6c44b3,
|
||||
0xd7f8e3ef00255961,
|
||||
0xa1ad2ad61580ef78,
|
||||
0x19e70d3618ca3,
|
||||
];
|
||||
|
||||
/// COFACTOR^(-1) mod r =
|
||||
/// 45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger384([
|
||||
7373687189387546408,
|
||||
11284009518041539892,
|
||||
301575489693670883,
|
||||
13203058298476577559,
|
||||
18441611830097862156,
|
||||
4115759498196698,
|
||||
]));
|
||||
|
||||
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||
(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||
}
|
||||
|
||||
const G2_GENERATOR_X: Fq3 =
|
||||
field_new!(Fq3, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1, G2_GENERATOR_X_C2);
|
||||
const G2_GENERATOR_Y: Fq3 =
|
||||
field_new!(Fq3, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1, G2_GENERATOR_Y_C2);
|
||||
|
||||
/// G2_GENERATOR_X_C0 =
|
||||
/// 13426761183630949215425595811885033211332897733228446437546263564078445562454176776915160094418980045665397361295624472103734543457352048745726512354895954850428989867542989474136256025045975283415690491751906307188562464175510373683338
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, BigInteger832([
|
||||
0x03b3fe4c8d4ecac7,
|
||||
0x9568212677524d1e,
|
||||
0xf5de3f2228d187c1,
|
||||
0x7bac772e31a420ef,
|
||||
0x0255cf59968a612b,
|
||||
0x991d4676f6b5d605,
|
||||
0x02dd2ae4831d29ea,
|
||||
0xbeca7c9a62e392c2,
|
||||
0xfc1d0633d48d2fc5,
|
||||
0x7867813be5f7d2a1,
|
||||
0x6f567b6617030028,
|
||||
0xf08c9fa6ca6809df,
|
||||
0x0000000000000de9,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_X_C1 =
|
||||
/// 20471601555918880743198170952645906008198510944268658573129351735028343217532386920456705632337352161031960990613816401042894531220068552819818037605513359562118363589199569321421558696125646867661360498323171027455638052943806292028610
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, BigInteger832([
|
||||
0xefd1b506e5fbe05f,
|
||||
0xad27d47a4975140c,
|
||||
0xfa11540132dbc27a,
|
||||
0x8dca42b6da7c4717,
|
||||
0x66d30fd7fd76207a,
|
||||
0xb8e4f65c68932b1d,
|
||||
0x3b7f971e93ad14be,
|
||||
0xf860a89f4e582f9f,
|
||||
0x7d438aaa3986f73b,
|
||||
0xa37ec0c18c6e106a,
|
||||
0x9f2dfb98b5185b54,
|
||||
0x19995e421ca939bc,
|
||||
0x0000000000002f4f,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_X_C2 =
|
||||
/// 3905053196875761830053608605277158152930144841844497593936739534395003062685449846381431331169369910535935138116320442345524758217411779027270883193856999691582831339845600938304719916501940381093815781408183227875600753651697934495980
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_X_C2: Fq = field_new!(Fq, BigInteger832([
|
||||
0xc081ed832bdf911e,
|
||||
0xb85ff7aeebdfe7b3,
|
||||
0x96dce6bb307b14eb,
|
||||
0x578f7ded84bd824c,
|
||||
0xb799305a9971d184,
|
||||
0x0116ad33c2874b90,
|
||||
0x862dce68efdca245,
|
||||
0x4190947c70534c1d,
|
||||
0x1b1aa80334248d03,
|
||||
0xb13b07aff63fcf27,
|
||||
0x5727687b73ab4fff,
|
||||
0xf559a7f4eb8d180a,
|
||||
0x0000000000002d37,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_Y_C0 =
|
||||
/// 8567517639523571619872938228644013584947463594196306323477160496987712111576624702939472765993995586889532559039169098780892505598589581147768095093536988446010255611523736706017580686335404469207486594272103717837888228343074699140243
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, BigInteger832([
|
||||
0x3f680b59e26b33d1,
|
||||
0x720fdf65b9e15b17,
|
||||
0x0f0b56def11247b1,
|
||||
0x5ea05417c8a4a52c,
|
||||
0x4ad59dc4f7c47a09,
|
||||
0xf393e0db62107115,
|
||||
0xde3b16404a53d2bb,
|
||||
0xeaa74961636280e0,
|
||||
0x2d16ccd14cf5a88c,
|
||||
0x5667565a06187d0e,
|
||||
0xb446fdc7565d0261,
|
||||
0xd3ad395d6fd0faab,
|
||||
0x0000000000000655,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_Y_C1 =
|
||||
/// 3890537069205870914984502594450293167889863914413852788876350245583932846980126025043974070704295857226211547108005650399870458089721518559480870503159804530091559886149680718531004778697982910253701559194337987238111062202037698927752
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, BigInteger832([
|
||||
0x9e86cc63207679dd,
|
||||
0x4e16d9a9d87c3e47,
|
||||
0xdbee3524db80627d,
|
||||
0x137322b87d93befc,
|
||||
0x24a7ca2f9aae90a0,
|
||||
0x44abea538df3e854,
|
||||
0xc01d176c6e042eee,
|
||||
0xf5fcc4caabc75699,
|
||||
0x1f99972699a38960,
|
||||
0x30d4cc8256bf963d,
|
||||
0xa3634826edcfefff,
|
||||
0x34f3bd0c8e5a4b38,
|
||||
0x0000000000001d28,
|
||||
]));
|
||||
|
||||
/// G2_GENERATOR_Y_C2 =
|
||||
/// 10936269922612615564271188303104593362724754284143779051599749016735041389483971486958818324356025479751246744831831158558101688599198721653921723013062333636402617118847009085485166284126970598561393411916461254016145116183331671450721
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_Y_C2: Fq = field_new!(Fq, BigInteger832([
|
||||
0xfc478105dedf3654,
|
||||
0xa6fcfcfdd2710d6a,
|
||||
0x05a68c283d5d4c65,
|
||||
0x9fab8d94c667a679,
|
||||
0x009b0a616ea54ff9,
|
||||
0xf0df517bc7bc6382,
|
||||
0xdb44338e7491f5b7,
|
||||
0xcd192a7e53453f45,
|
||||
0xa041a7a60982d92c,
|
||||
0x4dd01c62bae4c7ff,
|
||||
0x79a69a54e6b66178,
|
||||
0xd47b0bfe832b05f8,
|
||||
0x00000000000000ef,
|
||||
]));
|
||||
223
cp6_782/src/curves/mod.rs
Normal file
223
cp6_782/src/curves/mod.rs
Normal file
@@ -0,0 +1,223 @@
|
||||
use ark_ec::{models::SWModelParameters, PairingEngine};
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger832,
|
||||
field_new,
|
||||
fields::{BitIteratorBE, Field, FpParameters},
|
||||
One,
|
||||
};
|
||||
|
||||
use crate::{Fq, Fq3, Fq6, FqParameters, Fr};
|
||||
|
||||
pub mod g1;
|
||||
pub use self::g1::{G1Affine, G1Projective};
|
||||
|
||||
pub mod g2;
|
||||
pub use self::g2::{G2Affine, G2Projective};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub type GT = Fq6;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct CP6_782;
|
||||
|
||||
impl PairingEngine for CP6_782 {
|
||||
type Fr = Fr;
|
||||
type G1Projective = G1Projective;
|
||||
type G1Affine = G1Affine;
|
||||
type G1Prepared = G1Affine;
|
||||
type G2Projective = G2Projective;
|
||||
type G2Affine = G2Affine;
|
||||
type G2Prepared = G2Affine;
|
||||
type Fq = Fq;
|
||||
type Fqe = Fq3;
|
||||
type Fqk = Fq6;
|
||||
|
||||
fn miller_loop<'a, I>(i: I) -> Self::Fqk
|
||||
where
|
||||
I: IntoIterator<Item = &'a (Self::G1Prepared, Self::G2Prepared)>,
|
||||
{
|
||||
let mut result = Self::Fqk::one();
|
||||
for &(ref p, ref q) in i {
|
||||
result *= &CP6_782::ate_miller_loop(p, q);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn final_exponentiation(r: &Self::Fqk) -> Option<Self::Fqk> {
|
||||
Some(CP6_782::final_exponentiation(r))
|
||||
}
|
||||
}
|
||||
|
||||
impl CP6_782 {
|
||||
pub fn ate_pairing(p: &G1Affine, q: &G2Affine) -> GT {
|
||||
CP6_782::final_exponentiation(&CP6_782::ate_miller_loop(p, q))
|
||||
}
|
||||
|
||||
fn ate_miller_loop(p: &G1Affine, q: &G2Affine) -> Fq6 {
|
||||
let px = p.x;
|
||||
let py = p.y;
|
||||
let qx = q.x;
|
||||
let qy = q.y;
|
||||
let mut py_twist_squared = TWIST.square();
|
||||
py_twist_squared.mul_assign_by_fp(&py);
|
||||
|
||||
let mut old_rx;
|
||||
let mut old_ry;
|
||||
let mut rx = qx;
|
||||
let mut ry = qy;
|
||||
let mut f = Fq6::one();
|
||||
|
||||
// The for loop is executed for all bits (EXCEPT the MSB itself) of
|
||||
// cp6_782_param_p (skipping leading zeros) in MSB to LSB order
|
||||
for bit in BitIteratorBE::without_leading_zeros(ATE_LOOP_COUNT).skip(1) {
|
||||
old_rx = rx;
|
||||
old_ry = ry;
|
||||
|
||||
let old_rx_square = old_rx.square();
|
||||
let old_rx_square_3 = old_rx_square.double() + &old_rx_square;
|
||||
let old_rx_square_3_a = old_rx_square_3 + &g2::Parameters::COEFF_A;
|
||||
let old_ry_double_inverse = old_ry.double().inverse().unwrap();
|
||||
|
||||
let gamma = old_rx_square_3_a * &old_ry_double_inverse;
|
||||
let gamma_twist = gamma * &TWIST;
|
||||
let gamma_old_rx = gamma * &old_rx;
|
||||
let mut gamma_twist_px = gamma_twist;
|
||||
gamma_twist_px.mul_assign_by_fp(&px);
|
||||
|
||||
let x = py_twist_squared;
|
||||
let y = gamma_old_rx - &old_ry - &gamma_twist_px;
|
||||
let ell_rr_at_p = Fq6::new(x, y);
|
||||
|
||||
rx = gamma.square() - &old_rx.double();
|
||||
ry = gamma * &(old_rx - &rx) - &old_ry;
|
||||
f = f.square() * &ell_rr_at_p;
|
||||
|
||||
if bit {
|
||||
old_rx = rx;
|
||||
old_ry = ry;
|
||||
|
||||
let gamma = (old_ry - &qy) * &((old_rx - &qx).inverse().unwrap());
|
||||
let gamma_twist = gamma * &TWIST;
|
||||
let gamma_qx = gamma * &qx;
|
||||
let mut gamma_twist_px = gamma_twist;
|
||||
gamma_twist_px.mul_assign_by_fp(&px);
|
||||
|
||||
let x = py_twist_squared;
|
||||
let y = gamma_qx - &qy - &gamma_twist_px;
|
||||
let ell_rq_at_p = Fq6::new(x, y);
|
||||
|
||||
rx = gamma.square() - &old_rx - &qx;
|
||||
ry = gamma * &(old_rx - &rx) - &old_ry;
|
||||
f = f * &ell_rq_at_p;
|
||||
}
|
||||
}
|
||||
f
|
||||
}
|
||||
|
||||
fn final_exponentiation(value: &Fq6) -> GT {
|
||||
let value_inv = value.inverse().unwrap();
|
||||
let value_to_first_chunk = CP6_782::final_exponentiation_first(value, &value_inv);
|
||||
let value_inv_to_first_chunk = CP6_782::final_exponentiation_first(&value_inv, value);
|
||||
CP6_782::final_exponentiation_last(&value_to_first_chunk, &value_inv_to_first_chunk)
|
||||
}
|
||||
|
||||
fn final_exponentiation_first(elt: &Fq6, elt_inv: &Fq6) -> Fq6 {
|
||||
// (q^3-1)*(q+1)
|
||||
|
||||
// elt_q3 = elt^(q^3)
|
||||
let mut elt_q3 = elt.clone();
|
||||
elt_q3.frobenius_map(3);
|
||||
// elt_q3_over_elt = elt^(q^3-1)
|
||||
let elt_q3_over_elt = elt_q3 * elt_inv;
|
||||
// alpha = elt^((q^3-1) * q)
|
||||
let mut alpha = elt_q3_over_elt.clone();
|
||||
alpha.frobenius_map(1);
|
||||
// beta = elt^((q^3-1)*(q+1)
|
||||
alpha * &elt_q3_over_elt
|
||||
}
|
||||
|
||||
fn final_exponentiation_last(elt: &Fq6, elt_inv: &Fq6) -> Fq6 {
|
||||
let mut elt_q = elt.clone();
|
||||
elt_q.frobenius_map(1);
|
||||
|
||||
let w1_part = elt_q.cyclotomic_exp(&FINAL_EXPONENT_LAST_CHUNK_W1);
|
||||
let w0_part = if FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG {
|
||||
elt_inv.cyclotomic_exp(&FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0)
|
||||
} else {
|
||||
elt.cyclotomic_exp(&FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0)
|
||||
};
|
||||
|
||||
w1_part * &w0_part
|
||||
}
|
||||
}
|
||||
|
||||
/// FQ_ZERO = 0
|
||||
pub const FQ_ZERO: Fq = field_new!(Fq, BigInteger832([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]));
|
||||
|
||||
/// FQ_ONE = 1
|
||||
pub const FQ_ONE: Fq = field_new!(Fq, FqParameters::R);
|
||||
|
||||
/// TWIST = (0, 1, 0)
|
||||
pub const TWIST: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO);
|
||||
|
||||
/// ATE_IS_LOOP_COUNT_NEG = false
|
||||
pub const ATE_IS_LOOP_COUNT_NEG: bool = false;
|
||||
|
||||
/// ATE_LOOP_COUNT =
|
||||
/// 506464946133393486072777102926336625944849939610982267859828541006717966526573193706126370441346337661774335955699621
|
||||
pub const ATE_LOOP_COUNT: [u64; 13] = [
|
||||
0x55c5b9b57b942ae8,
|
||||
0x3d52287d3dfd424a,
|
||||
0xcf1ff9d6a543deb7,
|
||||
0x820c9c5711ceeebc,
|
||||
0x549a2d44305d20fe,
|
||||
0x50f5c131afd70235,
|
||||
0xab3596c8617c5792,
|
||||
0x830c728d80f9d78b,
|
||||
0x6a7223ee72023d07,
|
||||
0xbc5d176b746af026,
|
||||
0xe959283d8f526663,
|
||||
0xc4d2263babf8941f,
|
||||
0x3848,
|
||||
];
|
||||
|
||||
/// FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG = true
|
||||
pub const FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG: bool = true;
|
||||
|
||||
/// FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0 =
|
||||
/// 7000705447348627246181409558336018323010329260726930841638672011287206690002601216854775649561085256265269640040570922609783227469279331691880282815325569032149343779036142830666859805506518426649197067288711084398033
|
||||
pub const FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0: BigInteger832 = BigInteger832([
|
||||
0xb62ef36af72855d1,
|
||||
0x676b5cef49d290fa,
|
||||
0xd17fcf3c60947427,
|
||||
0x5b93d992bc1b2849,
|
||||
0x2171887cecd072cb,
|
||||
0x879a2873f1516f4a,
|
||||
0x8cc6856bd2cdf24e,
|
||||
0xbff4fb6644d01993,
|
||||
0x5dcbeea3e31ea667,
|
||||
0x5f256f47681649f3,
|
||||
0x2355a2b0839967fe,
|
||||
0x144ed,
|
||||
0x0,
|
||||
]);
|
||||
|
||||
/// FINAL_EXPONENT_LAST_CHUNK_W1 =
|
||||
/// 86482221941698704497288378992285180119495364068003923046442785886272123124361700722982503222189455144364945735564951562986
|
||||
pub const FINAL_EXPONENT_LAST_CHUNK_W1: BigInteger832 = BigInteger832([
|
||||
0x5657b9b57b942aea,
|
||||
0x84f9a65f3bd54eaf,
|
||||
0x5ea4214e35cd127,
|
||||
0xe3cbcbc14ec1501d,
|
||||
0xf196cb845a3092ab,
|
||||
0x7e14627ad0e19017,
|
||||
0x217db4,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
]);
|
||||
77
cp6_782/src/curves/tests.rs
Normal file
77
cp6_782/src/curves/tests.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve};
|
||||
use ark_ff::{test_rng, Field, One, PrimeField};
|
||||
use rand::Rng;
|
||||
|
||||
use crate::*;
|
||||
|
||||
use ark_curve_tests::{curves::*, groups::*};
|
||||
|
||||
#[test]
|
||||
fn test_g1_projective_curve() {
|
||||
curve_tests::<G1Projective>();
|
||||
|
||||
sw_tests::<g1::Parameters>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g1_projective_group() {
|
||||
let mut rng = test_rng();
|
||||
let a: G1Projective = rng.gen();
|
||||
let b: G1Projective = rng.gen();
|
||||
group_test(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g1_generator() {
|
||||
let generator = G1Affine::prime_subgroup_generator();
|
||||
assert!(generator.is_on_curve());
|
||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g2_projective_curve() {
|
||||
curve_tests::<G2Projective>();
|
||||
|
||||
sw_tests::<g2::Parameters>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g2_projective_group() {
|
||||
let mut rng = test_rng();
|
||||
let a: G2Projective = rng.gen();
|
||||
let b: G2Projective = rng.gen();
|
||||
group_test(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g2_generator() {
|
||||
let generator = G2Affine::prime_subgroup_generator();
|
||||
assert!(generator.is_on_curve());
|
||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bilinearity() {
|
||||
let mut rng = test_rng();
|
||||
let a: G1Projective = rng.gen();
|
||||
let b: G2Projective = rng.gen();
|
||||
let s: Fr = rng.gen();
|
||||
|
||||
let sa = a.mul(s);
|
||||
let sb = b.mul(s);
|
||||
|
||||
let ans1 = CP6_782::pairing(sa, b);
|
||||
let ans2 = CP6_782::pairing(a, sb);
|
||||
let ans3 = CP6_782::pairing(a, b).pow(s.into_repr());
|
||||
|
||||
assert_eq!(ans1, ans2);
|
||||
assert_eq!(ans2, ans3);
|
||||
|
||||
assert_ne!(ans1, Fq6::one());
|
||||
assert_ne!(ans2, Fq6::one());
|
||||
assert_ne!(ans3, Fq6::one());
|
||||
|
||||
assert_eq!(ans1.pow(Fr::characteristic()), Fq6::one());
|
||||
assert_eq!(ans2.pow(Fr::characteristic()), Fq6::one());
|
||||
assert_eq!(ans3.pow(Fr::characteristic()), Fq6::one());
|
||||
}
|
||||
166
cp6_782/src/fields/fq.rs
Normal file
166
cp6_782/src/fields/fq.rs
Normal file
@@ -0,0 +1,166 @@
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger832 as BigInteger,
|
||||
fields::{FftParameters, Fp832, Fp832Parameters, FpParameters},
|
||||
};
|
||||
|
||||
pub type Fq = Fp832<FqParameters>;
|
||||
|
||||
pub struct FqParameters;
|
||||
|
||||
impl Fp832Parameters for FqParameters {}
|
||||
impl FftParameters for FqParameters {
|
||||
type BigInt = BigInteger;
|
||||
|
||||
const TWO_ADICITY: u32 = 3;
|
||||
|
||||
#[rustfmt::skip]
|
||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
||||
18044746167194862600u64,
|
||||
63590321303744709u64,
|
||||
5009346151370959890u64,
|
||||
2859114157767503991u64,
|
||||
8301813204852325413u64,
|
||||
5629414263664332594u64,
|
||||
2637340888701394641u64,
|
||||
17433538052687852753u64,
|
||||
2230763098934759248u64,
|
||||
3785382115983092023u64,
|
||||
8895511354022222370u64,
|
||||
15792083141709071785u64,
|
||||
1328u64,
|
||||
]);
|
||||
}
|
||||
impl FpParameters for FqParameters {
|
||||
/// MODULUS = 22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577
|
||||
#[rustfmt::skip]
|
||||
const MODULUS: BigInteger = BigInteger([
|
||||
0xdace79b57b942ae9,
|
||||
0x545d85c16dfd424a,
|
||||
0xee135c065f4d26b7,
|
||||
0x9c2f764a12c4024b,
|
||||
0x1ad533049cfe6a39,
|
||||
0x52a3fb77c79c1320,
|
||||
0xab3596c8617c5792,
|
||||
0x830c728d80f9d78b,
|
||||
0x6a7223ee72023d07,
|
||||
0xbc5d176b746af026,
|
||||
0xe959283d8f526663,
|
||||
0xc4d2263babf8941f,
|
||||
0x3848,
|
||||
]);
|
||||
|
||||
const MODULUS_BITS: u32 = 782;
|
||||
|
||||
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
|
||||
|
||||
const REPR_SHAVE_BITS: u32 = 50;
|
||||
|
||||
#[rustfmt::skip]
|
||||
const R: BigInteger = BigInteger([
|
||||
11190988450819017841u64,
|
||||
16170411717126802030u64,
|
||||
2265463223430229059u64,
|
||||
16946880912571045974u64,
|
||||
11155248462028513229u64,
|
||||
12855672356664541314u64,
|
||||
8489376931127408159u64,
|
||||
2655797810825538098u64,
|
||||
9648483887143916718u64,
|
||||
17514963461276738952u64,
|
||||
16777089214204267338u64,
|
||||
15649035958020076168u64,
|
||||
8659u64,
|
||||
]);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const R2: BigInteger = BigInteger([
|
||||
13983406830510863714u64,
|
||||
17863856572171232656u64,
|
||||
1698388424046564526u64,
|
||||
1773634430448388392u64,
|
||||
8684647957094413275u64,
|
||||
3992637317298078843u64,
|
||||
18420879196616862245u64,
|
||||
3238482510270583127u64,
|
||||
7928200707794018216u64,
|
||||
10024831010452223910u64,
|
||||
9613847725664942650u64,
|
||||
15361265984156787358u64,
|
||||
7833u64,
|
||||
]);
|
||||
|
||||
const INV: u64 = 14469047335842394791u64;
|
||||
|
||||
/// GENERATOR = 13
|
||||
#[rustfmt::skip]
|
||||
const GENERATOR: BigInteger = BigInteger([
|
||||
16669393626057438558u64,
|
||||
1640520694378723217u64,
|
||||
1598646156981121135u64,
|
||||
12401834967100173388u64,
|
||||
2356467520877704673u64,
|
||||
14759118825104212161u64,
|
||||
5556628239575210651u64,
|
||||
5317520392768798654u64,
|
||||
16398429955031064995u64,
|
||||
3556102264904210145u64,
|
||||
8166834915717907988u64,
|
||||
11926665585800594452u64,
|
||||
11716u64,
|
||||
]);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||
0x6d673cdabdca1574,
|
||||
0xaa2ec2e0b6fea125,
|
||||
0xf709ae032fa6935b,
|
||||
0xce17bb2509620125,
|
||||
0xd6a99824e7f351c,
|
||||
0x2951fdbbe3ce0990,
|
||||
0xd59acb6430be2bc9,
|
||||
0xc1863946c07cebc5,
|
||||
0x353911f739011e83,
|
||||
0xde2e8bb5ba357813,
|
||||
0xf4ac941ec7a93331,
|
||||
0x6269131dd5fc4a0f,
|
||||
0x1c24,
|
||||
]);
|
||||
|
||||
// (T - 1)/2 =
|
||||
// 1398117143679731058146671387906315933423474966581074036386468539227923378278626533764529938634242576261128410962740119034868607201414583335758422276643816405480145410934911750070786645716409577212967755581539567265673914343284832551598
|
||||
#[rustfmt::skip]
|
||||
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||
0xadace79b57b942ae,
|
||||
0x7545d85c16dfd424,
|
||||
0xbee135c065f4d26b,
|
||||
0x99c2f764a12c4024,
|
||||
0x1ad533049cfe6a3,
|
||||
0x252a3fb77c79c132,
|
||||
0xbab3596c8617c579,
|
||||
0x7830c728d80f9d78,
|
||||
0x66a7223ee72023d0,
|
||||
0x3bc5d176b746af02,
|
||||
0xfe959283d8f52666,
|
||||
0x8c4d2263babf8941,
|
||||
0x384,
|
||||
]);
|
||||
|
||||
// T =
|
||||
// 2796234287359462116293342775812631866846949933162148072772937078455846756557253067529059877268485152522256821925480238069737214402829166671516844553287632810960290821869823500141573291432819154425935511163079134531347828686569665103197
|
||||
#[rustfmt::skip]
|
||||
const T: BigInteger = BigInteger([
|
||||
0x5b59cf36af72855d,
|
||||
0xea8bb0b82dbfa849,
|
||||
0x7dc26b80cbe9a4d6,
|
||||
0x3385eec942588049,
|
||||
0x35aa660939fcd47,
|
||||
0x4a547f6ef8f38264,
|
||||
0x7566b2d90c2f8af2,
|
||||
0xf0618e51b01f3af1,
|
||||
0xcd4e447dce4047a0,
|
||||
0x778ba2ed6e8d5e04,
|
||||
0xfd2b2507b1ea4ccc,
|
||||
0x189a44c7757f1283,
|
||||
0x709,
|
||||
]);
|
||||
}
|
||||
204
cp6_782/src/fields/fq3.rs
Normal file
204
cp6_782/src/fields/fq3.rs
Normal file
@@ -0,0 +1,204 @@
|
||||
use crate::Fq;
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger832 as BigInteger,
|
||||
field_new,
|
||||
fields::fp3::{Fp3, Fp3Parameters},
|
||||
Field,
|
||||
};
|
||||
|
||||
pub type Fq3 = Fp3<Fq3Parameters>;
|
||||
|
||||
pub struct Fq3Parameters;
|
||||
|
||||
impl Fp3Parameters for Fq3Parameters {
|
||||
type Fp = Fq;
|
||||
|
||||
/// NONRESIDUE = 13
|
||||
#[rustfmt::skip]
|
||||
const NONRESIDUE: Fq = field_new!(Fq, BigInteger([
|
||||
0xe755952f4650755e,
|
||||
0x16c44ce1331ef791,
|
||||
0x162f8835b467306f,
|
||||
0xac1c2b31e1062c4c,
|
||||
0x20b3dab9a2a935e1,
|
||||
0xccd2ec5fd01e00c1,
|
||||
0x4d1d1bf190c8da9b,
|
||||
0x49cba09fb0e13fbe,
|
||||
0xe392ed2957c061a3,
|
||||
0x3159d02b3c93d6e1,
|
||||
0x71566d160a9f8614,
|
||||
0xa5840728fc854414,
|
||||
0x2dc4,
|
||||
]));
|
||||
|
||||
const TWO_ADICITY: u32 = 3;
|
||||
|
||||
#[rustfmt::skip]
|
||||
const T_MINUS_ONE_DIV_TWO: &'static [u64] = &[
|
||||
0x62730e2cd2029617,
|
||||
0x660647f735cb88cf,
|
||||
0x274359d60784f69d,
|
||||
0x83067194eb102629,
|
||||
0x54ea4a12a9381160,
|
||||
0xade0b24e398dac25,
|
||||
0xb476ae9f927e81cb,
|
||||
0x220fd4a9178adc3b,
|
||||
0x57e0cb9b0569745b,
|
||||
0xba15024addc8f52e,
|
||||
0x145b9bc116144ab6,
|
||||
0x6bc2260726e88b15,
|
||||
0x51da6bf151066474,
|
||||
0x9fd1b3190f6320cf,
|
||||
0x2097bfb7bf4167b0,
|
||||
0x27c35b1e7e628e09,
|
||||
0x94f80c9d623dd9bb,
|
||||
0x20bfa6d5bf31e7d3,
|
||||
0x19fb862c049d3a8,
|
||||
0xdf4c5efe04c0cec1,
|
||||
0x32c9a8abe9b50297,
|
||||
0x268d5c2076b44f0a,
|
||||
0x76027ec67b23ca21,
|
||||
0x248d61e0c45d270,
|
||||
0x419cd0d1d6be027e,
|
||||
0xbcd8dc3b1986ef18,
|
||||
0x73093d8719c862c2,
|
||||
0x651d60f8f9f6fcd9,
|
||||
0x8dabebe38a09b261,
|
||||
0xfa85b5a9e180cd3f,
|
||||
0x6a97fc618f319fb7,
|
||||
0xce08b93a5652a8e1,
|
||||
0x37525cbc4ba24cf9,
|
||||
0xb104c580df9d2150,
|
||||
0x1407c1bfe240a89d,
|
||||
0x34c96a73372daf9a,
|
||||
0x2b87fda171,
|
||||
];
|
||||
|
||||
#[rustfmt::skip]
|
||||
const QUADRATIC_NONRESIDUE_TO_T: (Fq, Fq, Fq) = (
|
||||
field_new!(Fq, BigInteger([
|
||||
0x59987c0ef8e31739,
|
||||
0x59578d750d6f57dd,
|
||||
0x9672547570dddab8,
|
||||
0x1a1f630e1d6dbdd5,
|
||||
0xde15f46e52d7613e,
|
||||
0x6a1b6e4f80179926,
|
||||
0x461ad119d93123b,
|
||||
0x12054e3654907ed9,
|
||||
0x85ea06b12bf811a0,
|
||||
0xc01d53d07347f9ec,
|
||||
0x70c424eb666c3922,
|
||||
0x1796ce4ed605d49e,
|
||||
0x68b,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])),
|
||||
field_new!(Fq, BigInteger([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])),
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[
|
||||
field_new!(Fq, BigInteger([
|
||||
0x9b4e60b420910c71,
|
||||
0xe068d7c83f284a6e,
|
||||
0x1f708acc7c452c43,
|
||||
0xeb2f6a66cca51856,
|
||||
0x9acf675f886e9fcd,
|
||||
0xb26885e567cc8082,
|
||||
0x75d05357183eb61f,
|
||||
0x24db4a09b5842a32,
|
||||
0x85e64cf9ba4b14ae,
|
||||
0xf311a6784358a588,
|
||||
0xe8d431c061aecb4a,
|
||||
0xd92c8b4aab19f288,
|
||||
0x21d3,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0xe793e750fc0c0fdc,
|
||||
0x28cd75f5634a867e,
|
||||
0xde5e9b1261eb3c33,
|
||||
0x68a0fb1c17595903,
|
||||
0x19626d2c9f392e46,
|
||||
0xc4d95794cb378b83,
|
||||
0x54870f1f582d67c9,
|
||||
0xf3f1a0ac4aceb56d,
|
||||
0x811361215ea4fd47,
|
||||
0x32cd6ee17d95bd00,
|
||||
0x725f9881049a9c52,
|
||||
0x5acb70be0613a307,
|
||||
0x11bb,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0x57ec31b05ef70e9c,
|
||||
0x4b273803cb8a715d,
|
||||
0xf0443627811cbe40,
|
||||
0x485f10c72ec590f1,
|
||||
0x66a35e7875569c25,
|
||||
0xdb621dfd9498071a,
|
||||
0xe0de3451f11039a8,
|
||||
0x6a3f87d780a6f7eb,
|
||||
0x637875d359122b11,
|
||||
0x967e0211b37c8d9d,
|
||||
0x8e255dfc2908fec6,
|
||||
0x90da2a32facafe8f,
|
||||
0x4b9,
|
||||
])),
|
||||
];
|
||||
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[
|
||||
field_new!(Fq, BigInteger([
|
||||
0x9b4e60b420910c71,
|
||||
0xe068d7c83f284a6e,
|
||||
0x1f708acc7c452c43,
|
||||
0xeb2f6a66cca51856,
|
||||
0x9acf675f886e9fcd,
|
||||
0xb26885e567cc8082,
|
||||
0x75d05357183eb61f,
|
||||
0x24db4a09b5842a32,
|
||||
0x85e64cf9ba4b14ae,
|
||||
0xf311a6784358a588,
|
||||
0xe8d431c061aecb4a,
|
||||
0xd92c8b4aab19f288,
|
||||
0x21d3,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0x57ec31b05ef70e9c,
|
||||
0x4b273803cb8a715d,
|
||||
0xf0443627811cbe40,
|
||||
0x485f10c72ec590f1,
|
||||
0x66a35e7875569c25,
|
||||
0xdb621dfd9498071a,
|
||||
0xe0de3451f11039a8,
|
||||
0x6a3f87d780a6f7eb,
|
||||
0x637875d359122b11,
|
||||
0x967e0211b37c8d9d,
|
||||
0x8e255dfc2908fec6,
|
||||
0x90da2a32facafe8f,
|
||||
0x4b9,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0xe793e750fc0c0fdc,
|
||||
0x28cd75f5634a867e,
|
||||
0xde5e9b1261eb3c33,
|
||||
0x68a0fb1c17595903,
|
||||
0x19626d2c9f392e46,
|
||||
0xc4d95794cb378b83,
|
||||
0x54870f1f582d67c9,
|
||||
0xf3f1a0ac4aceb56d,
|
||||
0x811361215ea4fd47,
|
||||
0x32cd6ee17d95bd00,
|
||||
0x725f9881049a9c52,
|
||||
0x5acb70be0613a307,
|
||||
0x11bb,
|
||||
])),
|
||||
];
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_fp_by_nonresidue(fe: &Self::Fp) -> Self::Fp {
|
||||
let original = *fe;
|
||||
let mut four_fe = fe.double();
|
||||
four_fe.double_in_place();
|
||||
let eight_fe = four_fe.double();
|
||||
eight_fe + &four_fe + &original
|
||||
}
|
||||
}
|
||||
112
cp6_782/src/fields/fq6.rs
Normal file
112
cp6_782/src/fields/fq6.rs
Normal file
@@ -0,0 +1,112 @@
|
||||
use crate::{Fq, Fq3, Fq3Parameters, FQ_ONE, FQ_ZERO};
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger832 as BigInteger,
|
||||
field_new,
|
||||
fields::fp6_2over3::{Fp6, Fp6Parameters},
|
||||
};
|
||||
|
||||
pub type Fq6 = Fp6<Fq6Parameters>;
|
||||
|
||||
pub struct Fq6Parameters;
|
||||
|
||||
impl Fp6Parameters for Fq6Parameters {
|
||||
type Fp3Params = Fq3Parameters;
|
||||
|
||||
/// NONRESIDUE = (0, 1, 0).
|
||||
#[rustfmt::skip]
|
||||
const NONRESIDUE: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[
|
||||
field_new!(Fq, BigInteger([
|
||||
0x9b4e60b420910c71,
|
||||
0xe068d7c83f284a6e,
|
||||
0x1f708acc7c452c43,
|
||||
0xeb2f6a66cca51856,
|
||||
0x9acf675f886e9fcd,
|
||||
0xb26885e567cc8082,
|
||||
0x75d05357183eb61f,
|
||||
0x24db4a09b5842a32,
|
||||
0x85e64cf9ba4b14ae,
|
||||
0xf311a6784358a588,
|
||||
0xe8d431c061aecb4a,
|
||||
0xd92c8b4aab19f288,
|
||||
0x21d3,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0x82e248051c9d1c4d,
|
||||
0x9364dbda272d0ed,
|
||||
0xfdcf25dede306877,
|
||||
0x53d06582e3fe7159,
|
||||
0xb431d48c27a7ce14,
|
||||
0x7741dd7a33040c05,
|
||||
0xca576276706c1de9,
|
||||
0x18cceab60052df9f,
|
||||
0x6f9ae1b18f011f6,
|
||||
0x25df1559c0ee6289,
|
||||
0x5b33ca416649679d,
|
||||
0x33f7fc08b12d9590,
|
||||
0x338f,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0xe793e750fc0c0fdc,
|
||||
0x28cd75f5634a867e,
|
||||
0xde5e9b1261eb3c33,
|
||||
0x68a0fb1c17595903,
|
||||
0x19626d2c9f392e46,
|
||||
0xc4d95794cb378b83,
|
||||
0x54870f1f582d67c9,
|
||||
0xf3f1a0ac4aceb56d,
|
||||
0x811361215ea4fd47,
|
||||
0x32cd6ee17d95bd00,
|
||||
0x725f9881049a9c52,
|
||||
0x5acb70be0613a307,
|
||||
0x11bb,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0x3f8019015b031e78,
|
||||
0x73f4adf92ed4f7dc,
|
||||
0xcea2d139e307fa73,
|
||||
0xb1000be3461ee9f5,
|
||||
0x8005cba5148fca6b,
|
||||
0xa03b75925fcf929d,
|
||||
0x35654371493da172,
|
||||
0x5e312883cb75ad59,
|
||||
0xe48bd6f4b7b72859,
|
||||
0xc94b70f331124a9d,
|
||||
0x84f67d2da39b18,
|
||||
0xeba59af100dea197,
|
||||
0x1674,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0x57ec31b05ef70e9c,
|
||||
0x4b273803cb8a715d,
|
||||
0xf0443627811cbe40,
|
||||
0x485f10c72ec590f1,
|
||||
0x66a35e7875569c25,
|
||||
0xdb621dfd9498071a,
|
||||
0xe0de3451f11039a8,
|
||||
0x6a3f87d780a6f7eb,
|
||||
0x637875d359122b11,
|
||||
0x967e0211b37c8d9d,
|
||||
0x8e255dfc2908fec6,
|
||||
0x90da2a32facafe8f,
|
||||
0x4b9,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
0xf33a92647f881b0d,
|
||||
0x2b900fcc0ab2bbcb,
|
||||
0xfb4c0f3fd61ea84,
|
||||
0x338e7b2dfb6aa948,
|
||||
0x172c5d7fdc53bf3,
|
||||
0x8dcaa3e2fc64879d,
|
||||
0x56ae87a9094eefc8,
|
||||
0x8f1ad1e1362b221e,
|
||||
0xe95ec2cd135d3fbf,
|
||||
0x898fa889f6d53325,
|
||||
0x76f98fbc8ab7ca11,
|
||||
0x6a06b57da5e4f118,
|
||||
0x268d,
|
||||
])),
|
||||
];
|
||||
}
|
||||
1
cp6_782/src/fields/fr.rs
Normal file
1
cp6_782/src/fields/fr.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub use ark_bls12_377::{Fq as Fr, FqParameters as FrParameters};
|
||||
14
cp6_782/src/fields/mod.rs
Normal file
14
cp6_782/src/fields/mod.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
pub mod fr;
|
||||
pub use self::fr::*;
|
||||
|
||||
pub mod fq;
|
||||
pub use self::fq::*;
|
||||
|
||||
pub mod fq3;
|
||||
pub use self::fq3::*;
|
||||
|
||||
pub mod fq6;
|
||||
pub use self::fq6::*;
|
||||
|
||||
#[cfg(all(feature = "cp6_782", test))]
|
||||
mod tests;
|
||||
51
cp6_782/src/fields/tests.rs
Normal file
51
cp6_782/src/fields/tests.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
use ark_ff::{test_rng, Field, PrimeField};
|
||||
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
|
||||
use rand::Rng;
|
||||
|
||||
use crate::*;
|
||||
|
||||
use ark_curve_tests::fields::*;
|
||||
|
||||
#[test]
|
||||
fn test_fr() {
|
||||
let mut rng = test_rng();
|
||||
let a: Fr = rng.gen();
|
||||
let b: Fr = rng.gen();
|
||||
field_test(a, b);
|
||||
sqrt_field_test(a);
|
||||
primefield_test::<Fr>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq() {
|
||||
let mut rng = test_rng();
|
||||
let a: Fq = rng.gen();
|
||||
let b: Fq = rng.gen();
|
||||
field_test(a, b);
|
||||
primefield_test::<Fq>();
|
||||
sqrt_field_test(a);
|
||||
|
||||
let byte_size = a.serialized_size();
|
||||
let (_, buffer_size) = buffer_bit_byte_size(Fq::size_in_bits());
|
||||
assert_eq!(byte_size, buffer_size);
|
||||
field_serialization_test::<Fq>(byte_size);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq3() {
|
||||
let mut rng = test_rng();
|
||||
let a: Fq3 = rng.gen();
|
||||
let b: Fq3 = rng.gen();
|
||||
field_test(a, b);
|
||||
sqrt_field_test(a);
|
||||
frobenius_test::<Fq3, _>(Fq::characteristic(), 13);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq6() {
|
||||
let mut rng = test_rng();
|
||||
let a: Fq6 = rng.gen();
|
||||
let b: Fq6 = rng.gen();
|
||||
field_test(a, b);
|
||||
frobenius_test::<Fq6, _>(Fq::characteristic(), 13);
|
||||
}
|
||||
33
cp6_782/src/lib.rs
Normal file
33
cp6_782/src/lib.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![deny(
|
||||
warnings,
|
||||
unused,
|
||||
future_incompatible,
|
||||
nonstandard_style,
|
||||
rust_2018_idioms
|
||||
)]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
//! This library implements the CP6_782 curve generated in [[BCGMMW20, “Zexe”]](https://eprint.iacr.org/2018/962).
|
||||
//! The name denotes that it was generated using the Cocks--Pinch method for the embedding degree 6.
|
||||
//! The main feature of this curve is that the scalar field equals the base field of the BLS12_377 curve.
|
||||
//!
|
||||
//! Curve information:
|
||||
//! * Base field: q = 22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577
|
||||
//! * Scalar field: r = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
|
||||
//! * valuation(q - 1, 2) = 3
|
||||
//! * valuation(r - 1, 2) = 46
|
||||
//!
|
||||
//! G1 curve equation: y^2 = x^3 + ax + b, where
|
||||
//! * a = 5,
|
||||
//! * b = 17764315118651679038286329069295091506801468118146712649886336045535808055361274148466772191243305528312843236347777260247138934336850548243151534538734724191505953341403463040067571652261229308333392040104884438208594329793895206056414,
|
||||
//!
|
||||
//! G2 curve equation: y^2 = x^3 + Ax + B
|
||||
//! * A = Fq3(0, 0, 5)
|
||||
//! * B = Fq3(7237353553714858194254855835825640240663090882935418626687402315497764195116318527743248304684159666286416318482685337633828994152723793439622384740540789612754127688659139509552568164770448654259255628317166934203899992395064470477612, 0, 0)
|
||||
|
||||
mod curves;
|
||||
mod fields;
|
||||
|
||||
pub use curves::*;
|
||||
pub use fields::*;
|
||||
50
curve-benches/Cargo.toml
Normal file
50
curve-benches/Cargo.toml
Normal file
@@ -0,0 +1,50 @@
|
||||
[package]
|
||||
name = "ark-curve-benches"
|
||||
version = "0.1.1-alpha.0"
|
||||
authors = [
|
||||
"Sean Bowe",
|
||||
"Alessandro Chiesa",
|
||||
"Matthew Green",
|
||||
"Ian Miers",
|
||||
"Pratyush Mishra",
|
||||
"Howard Wu"
|
||||
]
|
||||
description = "A benchmark library for finite fields and elliptic curves"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
documentation = "https://docs.rs/algebra/"
|
||||
keywords = ["cryptography", "finite fields", "elliptic curves", "pairing"]
|
||||
categories = ["cryptography"]
|
||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
license = "MIT/Apache-2.0"
|
||||
edition = "2018"
|
||||
publish = false
|
||||
build = "build.rs"
|
||||
|
||||
################################# Dependencies ################################
|
||||
|
||||
[dependencies]
|
||||
ark-ec = { git = "https://github.com/arkworks-rs/algebra" }
|
||||
ark-ff = { git = "https://github.com/arkworks-rs/algebra" }
|
||||
ark-serialize = { git = "https://github.com/arkworks-rs/algebra" }
|
||||
|
||||
ark-mnt4-298 = { path = "../mnt4_298", optional = true }
|
||||
ark-mnt6-298 = { path = "../mnt6_298", optional = true }
|
||||
ark-mnt4-753 = { path = "../mnt4_753", optional = true }
|
||||
ark-mnt6-753 = { path = "../mnt6_753", optional = true }
|
||||
ark-bn254 = { path = "../bn254", default-features = false, optional = true }
|
||||
ark-bls12-377 = { path = "../bls12_377", optional = true }
|
||||
ark-bls12-381 = { path = "../bls12_381", optional = true }
|
||||
ark-bw6-761 = { path = "../bw6_761", optional = true }
|
||||
ark-cp6-782 = { path = "../cp6_782", optional = true }
|
||||
|
||||
rand = "0.7"
|
||||
rand_xorshift = { version = "0.2" }
|
||||
paste = "1.0"
|
||||
|
||||
[features]
|
||||
asm = [ "ark-ff/asm"]
|
||||
n_fold = []
|
||||
|
||||
[build-dependencies]
|
||||
rustc_version = "0.2"
|
||||
1
curve-benches/LICENSE-APACHE
Symbolic link
1
curve-benches/LICENSE-APACHE
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE-APACHE
|
||||
1
curve-benches/LICENSE-MIT
Symbolic link
1
curve-benches/LICENSE-MIT
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE-MIT
|
||||
9
curve-benches/build.rs
Normal file
9
curve-benches/build.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
extern crate rustc_version;
|
||||
|
||||
use rustc_version::{version_meta, Channel};
|
||||
|
||||
fn main() {
|
||||
if version_meta().expect("nightly check failed").channel == Channel::Nightly {
|
||||
println!("cargo:rustc-cfg=nightly");
|
||||
}
|
||||
}
|
||||
23
curve-benches/src/curves/bls12_377.rs
Normal file
23
curve-benches/src/curves/bls12_377.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use rand::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::ops::{AddAssign, MulAssign, SubAssign};
|
||||
|
||||
use ark_bls12_377::bls12_377::{
|
||||
fq::Fq, fq2::Fq2, fr::Fr, Bls12_377, Fq12, G1Affine, G1Projective as G1, G2Affine,
|
||||
G2Projective as G2, Parameters,
|
||||
};
|
||||
use ark_ec::{
|
||||
bls12::{G1Prepared, G2Prepared},
|
||||
PairingEngine, ProjectiveCurve,
|
||||
};
|
||||
use ark_ff::{
|
||||
biginteger::{BigInteger256 as FrRepr, BigInteger384 as FqRepr},
|
||||
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
|
||||
};
|
||||
|
||||
ec_bench!();
|
||||
f_bench!(1, Fq2, Fq2, fq2);
|
||||
f_bench!(2, Fq12, Fq12, fq12);
|
||||
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);
|
||||
pairing_bench!(Bls12_377, Fq12, prepared_v);
|
||||
23
curve-benches/src/curves/bls12_381.rs
Normal file
23
curve-benches/src/curves/bls12_381.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use rand::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::ops::{AddAssign, MulAssign, SubAssign};
|
||||
|
||||
use ark_bls12_381::bls12_381::{
|
||||
fq::Fq, fq2::Fq2, fr::Fr, Bls12_381, Fq12, G1Affine, G1Projective as G1, G2Affine,
|
||||
G2Projective as G2, Parameters,
|
||||
};
|
||||
use ark_ec::{
|
||||
bls12::{G1Prepared, G2Prepared},
|
||||
PairingEngine, ProjectiveCurve,
|
||||
};
|
||||
use ark_ff::{
|
||||
biginteger::{BigInteger256 as FrRepr, BigInteger384 as FqRepr},
|
||||
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
|
||||
};
|
||||
|
||||
ec_bench!();
|
||||
f_bench!(1, Fq2, Fq2, fq2);
|
||||
f_bench!(2, Fq12, Fq12, fq12);
|
||||
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);
|
||||
pairing_bench!(Bls12_381, Fq12, prepared_v);
|
||||
23
curve-benches/src/curves/bn254.rs
Normal file
23
curve-benches/src/curves/bn254.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use rand::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::ops::{AddAssign, MulAssign, SubAssign};
|
||||
|
||||
use ark_ec::{
|
||||
bn::{G1Prepared, G2Prepared},
|
||||
PairingEngine, ProjectiveCurve,
|
||||
};
|
||||
use ark_ef::{
|
||||
biginteger::{BigInteger256 as FrRepr, BigInteger256 as FqRepr},
|
||||
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
|
||||
};
|
||||
use ark_en254::bn254::{
|
||||
fq::Fq, fq2::Fq2, fr::Fr, Bls12_381, Fq12, G1Affine, G1Projective as G1, G2Affine,
|
||||
G2Projective as G2, Parameters,
|
||||
};
|
||||
|
||||
ec_bench!();
|
||||
f_bench!(1, Fq2, Fq2, fq2);
|
||||
f_bench!(2, Fq12, Fq12, fq12);
|
||||
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);
|
||||
pairing_bench!(Bn254, Fq12, prepared_v);
|
||||
23
curve-benches/src/curves/bw6_761.rs
Normal file
23
curve-benches/src/curves/bw6_761.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use rand::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::ops::{AddAssign, MulAssign, SubAssign};
|
||||
|
||||
use ark_bls12_377::bw6_761::{
|
||||
fq::Fq, fq3::Fq3, fr::Fr, Fq6, G1Affine, G1Projective as G1, G2Affine, G2Projective as G2,
|
||||
Parameters, BW6_761,
|
||||
};
|
||||
use ark_ec::{
|
||||
bw6::{G1Prepared, G2Prepared},
|
||||
PairingEngine, ProjectiveCurve,
|
||||
};
|
||||
use ark_ff::{
|
||||
biginteger::{BigInteger384 as FrRepr, BigInteger768 as FqRepr},
|
||||
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
|
||||
};
|
||||
|
||||
ec_bench!();
|
||||
f_bench!(1, Fq3, Fq3, fq3);
|
||||
f_bench!(2, Fq6, Fq6, fq6);
|
||||
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);
|
||||
pairing_bench!(BW6_761, Fq6, prepared_v);
|
||||
20
curve-benches/src/curves/cp6_782.rs
Normal file
20
curve-benches/src/curves/cp6_782.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use rand::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::ops::{AddAssign, MulAssign, SubAssign};
|
||||
|
||||
use ark_bls12_377::cp6_782::{
|
||||
fq::Fq, fq3::Fq3, fr::Fr, Fq6, G1Affine, G1Projective as G1, G2Affine, G2Projective as G2,
|
||||
CP6_782,
|
||||
};
|
||||
use ark_ec::{PairingEngine, ProjectiveCurve};
|
||||
use ark_ff::{
|
||||
biginteger::{BigInteger384 as FrRepr, BigInteger832 as FqRepr},
|
||||
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
|
||||
};
|
||||
|
||||
ec_bench!();
|
||||
f_bench!(1, Fq3, Fq3, fq3);
|
||||
f_bench!(2, Fq6, Fq6, fq6);
|
||||
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);
|
||||
pairing_bench!(CP6_782, Fq6, affine_v);
|
||||
22
curve-benches/src/curves/mnt4_298.rs
Normal file
22
curve-benches/src/curves/mnt4_298.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use rand::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::ops::{AddAssign, MulAssign, SubAssign};
|
||||
|
||||
use ark_ec::{
|
||||
mnt4::{G1Prepared, G2Prepared},
|
||||
PairingEngine, ProjectiveCurve,
|
||||
};
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger320 as FqRepr, BigInteger, Field, PrimeField, SquareRootField,
|
||||
UniformRand,
|
||||
};
|
||||
use ark_mnt_298::mnt4_298::{
|
||||
fq::Fq, fq2::Fq2, fr::Fr, Fq4, G1Affine, G1Projective as G1, G2Affine, G2Projective as G2,
|
||||
Parameters, MNT4_298,
|
||||
};
|
||||
|
||||
ec_bench!();
|
||||
f_bench!(1, Fq2, Fq2, fq2);
|
||||
f_bench!(2, Fq4, Fq4, fq4);
|
||||
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||
pairing_bench!(MNT4_298, Fq4, prepared_v);
|
||||
22
curve-benches/src/curves/mnt4_753.rs
Normal file
22
curve-benches/src/curves/mnt4_753.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use rand::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::ops::{AddAssign, MulAssign, SubAssign};
|
||||
|
||||
use ark_ec::{
|
||||
mnt4::{G1Prepared, G2Prepared},
|
||||
PairingEngine, ProjectiveCurve,
|
||||
};
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger768 as FqRepr, BigInteger, Field, PrimeField, SquareRootField,
|
||||
UniformRand,
|
||||
};
|
||||
use ark_mnt_753::mnt4_753::{
|
||||
fq::Fq, fq2::Fq2, fr::Fr, Fq4, G1Affine, G1Projective as G1, G2Affine, G2Projective as G2,
|
||||
Parameters, MNT4_753,
|
||||
};
|
||||
|
||||
ec_bench!();
|
||||
f_bench!(1, Fq2, Fq2, fq2);
|
||||
f_bench!(2, Fq4, Fq4, fq4);
|
||||
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||
pairing_bench!(MNT4_753, Fq4, prepared_v);
|
||||
22
curve-benches/src/curves/mnt6_298.rs
Normal file
22
curve-benches/src/curves/mnt6_298.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use rand::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::ops::{AddAssign, MulAssign, SubAssign};
|
||||
|
||||
use ark_ec::{
|
||||
mnt6::{G1Prepared, G2Prepared},
|
||||
PairingEngine, ProjectiveCurve,
|
||||
};
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger320 as FqRepr, BigInteger, Field, PrimeField, SquareRootField,
|
||||
UniformRand,
|
||||
};
|
||||
use ark_mnt_298::mnt6_298::{
|
||||
fq::Fq, fq3::Fq3, fr::Fr, Fq6, G1Affine, G1Projective as G1, G2Affine, G2Projective as G2,
|
||||
Parameters, MNT6_298,
|
||||
};
|
||||
|
||||
ec_bench!();
|
||||
f_bench!(1, Fq3, Fq3, fq3);
|
||||
f_bench!(2, Fq6, Fq6, fq6);
|
||||
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||
pairing_bench!(MNT6_298, Fq6, prepared_v);
|
||||
22
curve-benches/src/curves/mnt6_753.rs
Normal file
22
curve-benches/src/curves/mnt6_753.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use rand::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::ops::{AddAssign, MulAssign, SubAssign};
|
||||
|
||||
use ark_ec::{
|
||||
mnt6::{G1Prepared, G2Prepared},
|
||||
PairingEngine, ProjectiveCurve,
|
||||
};
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger768 as FqRepr, BigInteger, Field, PrimeField, SquareRootField,
|
||||
UniformRand,
|
||||
};
|
||||
use ark_mnt_753::mnt6_753::{
|
||||
fq::Fq, fq3::Fq3, fr::Fr, Fq6, G1Affine, G1Projective as G1, G2Affine, G2Projective as G2,
|
||||
Parameters, MNT6_753,
|
||||
};
|
||||
|
||||
ec_bench!();
|
||||
f_bench!(1, Fq3, Fq3, fq3);
|
||||
f_bench!(2, Fq6, Fq6, fq6);
|
||||
f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
|
||||
pairing_bench!(MNT6_753, Fq6, prepared_v);
|
||||
18
curve-benches/src/curves/mod.rs
Normal file
18
curve-benches/src/curves/mod.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
#[cfg(feature = "bls12_377")]
|
||||
mod bls12_377;
|
||||
#[cfg(feature = "bls12_381")]
|
||||
mod bls12_381;
|
||||
#[cfg(feature = "bn254")]
|
||||
mod bn254;
|
||||
#[cfg(feature = "bw6_761")]
|
||||
mod bw6_761;
|
||||
#[cfg(feature = "cp6_782")]
|
||||
mod cp6_782;
|
||||
#[cfg(feature = "mnt4_298")]
|
||||
mod mnt4_298;
|
||||
#[cfg(feature = "mnt4_753")]
|
||||
mod mnt4_753;
|
||||
#[cfg(feature = "mnt6_298")]
|
||||
mod mnt6_298;
|
||||
#[cfg(feature = "mnt6_753")]
|
||||
mod mnt6_753;
|
||||
12
curve-benches/src/lib.rs
Normal file
12
curve-benches/src/lib.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
#![cfg_attr(nightly, feature(test))]
|
||||
#![allow(unused_macros, unused_imports)]
|
||||
|
||||
#[cfg(nightly)]
|
||||
extern crate test;
|
||||
|
||||
#[cfg(all(nightly, test))]
|
||||
#[macro_use]
|
||||
pub mod macros;
|
||||
|
||||
#[cfg(all(nightly, test))]
|
||||
mod curves;
|
||||
357
curve-benches/src/macros/ec.rs
Normal file
357
curve-benches/src/macros/ec.rs
Normal file
@@ -0,0 +1,357 @@
|
||||
macro_rules! ec_bench {
|
||||
() => {
|
||||
#[bench]
|
||||
fn bench_g1_rand(b: &mut ::test::Bencher) {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
b.iter(|| G1::rand(&mut rng));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g1_mul_assign(b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<(G1, Fr)> = (0..SAMPLES)
|
||||
.map(|_| (G1::rand(&mut rng), Fr::rand(&mut rng)))
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
tmp *= v[count].1;
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g1_add_assign(b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<(G1, G1)> = (0..SAMPLES)
|
||||
.map(|_| (G1::rand(&mut rng), G1::rand(&mut rng)))
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
n_fold!(tmp, v, add_assign, count);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g1_add_assign_mixed(b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<(G1, G1Affine)> = (0..SAMPLES)
|
||||
.map(|_| (G1::rand(&mut rng), G1::rand(&mut rng).into()))
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
n_fold!(tmp, v, add_assign_mixed, count);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g1_double(b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<(G1, G1)> = (0..SAMPLES)
|
||||
.map(|_| (G1::rand(&mut rng), G1::rand(&mut rng)))
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
n_fold!(tmp, double_in_place);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g1_deser(b: &mut ::test::Bencher) {
|
||||
use ark_ec::ProjectiveCurve;
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let mut num_bytes = 0;
|
||||
let tmp = G1::rand(&mut rng).into_affine();
|
||||
let v: Vec<_> = (0..SAMPLES)
|
||||
.flat_map(|_| {
|
||||
let mut bytes = Vec::with_capacity(1000);
|
||||
tmp.serialize(&mut bytes).unwrap();
|
||||
num_bytes = bytes.len();
|
||||
bytes
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
count = (count + 1) % SAMPLES;
|
||||
let index = count * num_bytes;
|
||||
G1Affine::deserialize(&v[index..(index + num_bytes)]).unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g1_ser(b: &mut ::test::Bencher) {
|
||||
use ark_ec::ProjectiveCurve;
|
||||
use ark_serialize::CanonicalSerialize;
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let mut v: Vec<_> = (0..SAMPLES).map(|_| G1::rand(&mut rng)).collect();
|
||||
let v = G1::batch_normalization_into_affine(v.as_mut_slice());
|
||||
let mut bytes = Vec::with_capacity(1000);
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let tmp = v[count];
|
||||
count = (count + 1) % SAMPLES;
|
||||
bytes.clear();
|
||||
tmp.serialize(&mut bytes)
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g1_deser_unchecked(b: &mut ::test::Bencher) {
|
||||
use ark_ec::ProjectiveCurve;
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let mut num_bytes = 0;
|
||||
let tmp = G1::rand(&mut rng).into_affine();
|
||||
let v: Vec<_> = (0..SAMPLES)
|
||||
.flat_map(|_| {
|
||||
let mut bytes = Vec::with_capacity(1000);
|
||||
tmp.serialize_unchecked(&mut bytes).unwrap();
|
||||
num_bytes = bytes.len();
|
||||
bytes
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
count = (count + 1) % SAMPLES;
|
||||
let index = count * num_bytes;
|
||||
G1Affine::deserialize_unchecked(&v[index..(index + num_bytes)]).unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g1_ser_unchecked(b: &mut ::test::Bencher) {
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let mut v: Vec<_> = (0..SAMPLES).map(|_| G1::rand(&mut rng)).collect();
|
||||
let v = G1::batch_normalization_into_affine(v.as_mut_slice());
|
||||
let mut bytes = Vec::with_capacity(1000);
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let tmp = v[count];
|
||||
count = (count + 1) % SAMPLES;
|
||||
bytes.clear();
|
||||
tmp.serialize_unchecked(&mut bytes)
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g2_rand(b: &mut ::test::Bencher) {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
b.iter(|| G2::rand(&mut rng));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g2_mul_assign(b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<(G2, Fr)> = (0..SAMPLES)
|
||||
.map(|_| (G2::rand(&mut rng), Fr::rand(&mut rng)))
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
tmp *= v[count].1;
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g2_add_assign(b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<(G2, G2)> = (0..SAMPLES)
|
||||
.map(|_| (G2::rand(&mut rng), G2::rand(&mut rng)))
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
tmp.add_assign(&v[count].1);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g2_add_assign_mixed(b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<(G2, G2Affine)> = (0..SAMPLES)
|
||||
.map(|_| (G2::rand(&mut rng), G2::rand(&mut rng).into()))
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
tmp.add_assign_mixed(&v[count].1);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g2_double(b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<(G2, G2)> = (0..SAMPLES)
|
||||
.map(|_| (G2::rand(&mut rng), G2::rand(&mut rng)))
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
tmp.double_in_place();
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g2_deser(b: &mut ::test::Bencher) {
|
||||
use ark_ec::ProjectiveCurve;
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let mut num_bytes = 0;
|
||||
let tmp = G2::rand(&mut rng).into_affine();
|
||||
let v: Vec<_> = (0..SAMPLES)
|
||||
.flat_map(|_| {
|
||||
let mut bytes = Vec::with_capacity(1000);
|
||||
tmp.serialize(&mut bytes).unwrap();
|
||||
num_bytes = bytes.len();
|
||||
bytes
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
count = (count + 1) % SAMPLES;
|
||||
let index = count * num_bytes;
|
||||
G2Affine::deserialize(&v[index..(index + num_bytes)]).unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g2_ser(b: &mut ::test::Bencher) {
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let mut v: Vec<_> = (0..SAMPLES).map(|_| G2::rand(&mut rng)).collect();
|
||||
let v = G2::batch_normalization_into_affine(v.as_mut_slice());
|
||||
let mut bytes = Vec::with_capacity(1000);
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let tmp = v[count];
|
||||
count = (count + 1) % SAMPLES;
|
||||
bytes.clear();
|
||||
tmp.serialize(&mut bytes)
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g2_deser_unchecked(b: &mut ::test::Bencher) {
|
||||
use ark_ec::ProjectiveCurve;
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let mut num_bytes = 0;
|
||||
let tmp = G2::rand(&mut rng).into_affine();
|
||||
let v: Vec<_> = (0..SAMPLES)
|
||||
.flat_map(|_| {
|
||||
let mut bytes = Vec::with_capacity(1000);
|
||||
tmp.serialize_unchecked(&mut bytes).unwrap();
|
||||
num_bytes = bytes.len();
|
||||
bytes
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
count = (count + 1) % SAMPLES;
|
||||
let index = count * num_bytes;
|
||||
G2Affine::deserialize_unchecked(&v[index..(index + num_bytes)]).unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_g2_ser_unchecked(b: &mut ::test::Bencher) {
|
||||
use ark_ec::ProjectiveCurve;
|
||||
use ark_serialize::CanonicalSerialize;
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let mut v: Vec<_> = (0..SAMPLES).map(|_| G2::rand(&mut rng)).collect();
|
||||
let v = G2::batch_normalization_into_affine(v.as_mut_slice());
|
||||
let mut bytes = Vec::with_capacity(1000);
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let tmp = v[count];
|
||||
count = (count + 1) % SAMPLES;
|
||||
bytes.clear();
|
||||
tmp.serialize_unchecked(&mut bytes)
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
405
curve-benches/src/macros/field.rs
Normal file
405
curve-benches/src/macros/field.rs
Normal file
@@ -0,0 +1,405 @@
|
||||
macro_rules! f_bench {
|
||||
// Use this for base fields
|
||||
($f:ident, $f_type:ty, $f_repr:ident, $f_repr_type:ty, $field_ident:ident) => {
|
||||
field_common!($f, $f_type, $field_ident);
|
||||
sqrt!($f, $f_type, $field_ident);
|
||||
field_base!($f, $f_type, $f_repr, $f_repr_type, $field_ident);
|
||||
};
|
||||
// use this for intermediate fields
|
||||
(1, $f:ident, $f_type:ty, $field_ident:ident) => {
|
||||
field_common!($f, $f_type, $field_ident);
|
||||
sqrt!($f, $f_type, $field_ident);
|
||||
};
|
||||
// Use this for the full extension field Fqk
|
||||
(2, $f:ident, $f_type:ty, $field_ident:ident) => {
|
||||
field_common!($f, $f_type, $field_ident);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! field_common {
|
||||
($f:ident, $f_type:ty, $field_ident:ident) => {
|
||||
paste::item! {
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _add_assign>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<_> = (0..SAMPLES)
|
||||
.map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
n_fold!(tmp, v, add_assign, count);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _sub_assign>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<_> = (0..SAMPLES)
|
||||
.map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
n_fold!(tmp, v, sub_assign, count);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _mul_assign>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<_> = (0..SAMPLES)
|
||||
.map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
n_fold!(tmp, v, mul_assign, count);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _double>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count];
|
||||
n_fold!(tmp, double_in_place);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _square>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count];
|
||||
n_fold!(tmp, square_in_place);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _inverse>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let tmp = v[count].inverse();
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _deser>](b: &mut ::test::Bencher) {
|
||||
use ark_serialize::{CanonicalSerialize, CanonicalDeserialize};
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let mut num_bytes = 0;
|
||||
let v: Vec<_> = (0..SAMPLES).flat_map(|_| {
|
||||
let mut bytes = Vec::with_capacity(1000);
|
||||
let tmp = $f::rand(&mut rng);
|
||||
tmp.serialize(&mut bytes).unwrap();
|
||||
num_bytes = bytes.len();
|
||||
bytes
|
||||
}).collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
count = (count + 1) % SAMPLES;
|
||||
let index = count * num_bytes;
|
||||
$f_type::deserialize(&v[index..(index + num_bytes)]).unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _ser>](b: &mut ::test::Bencher) {
|
||||
use ark_serialize::CanonicalSerialize;
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
||||
let mut bytes = Vec::with_capacity(1000);
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let tmp = v[count];
|
||||
count = (count + 1) % SAMPLES;
|
||||
bytes.clear();
|
||||
tmp.serialize(&mut bytes)
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _deser_unchecked>](b: &mut ::test::Bencher) {
|
||||
use ark_serialize::{CanonicalSerialize, CanonicalDeserialize};
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let mut num_bytes = 0;
|
||||
let v: Vec<_> = (0..SAMPLES).flat_map(|_| {
|
||||
let mut bytes = Vec::with_capacity(1000);
|
||||
let tmp = $f::rand(&mut rng);
|
||||
tmp.serialize_unchecked(&mut bytes).unwrap();
|
||||
num_bytes = bytes.len();
|
||||
bytes
|
||||
}).collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
count = (count + 1) % SAMPLES;
|
||||
let index = count * num_bytes;
|
||||
$f_type::deserialize_unchecked(&v[index..(index + num_bytes)]).unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _ser_unchecked>](b: &mut ::test::Bencher) {
|
||||
use ark_serialize::CanonicalSerialize;
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
||||
let mut bytes = Vec::with_capacity(1000);
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let tmp = v[count];
|
||||
count = (count + 1) % SAMPLES;
|
||||
bytes.clear();
|
||||
tmp.serialize_unchecked(&mut bytes)
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! sqrt {
|
||||
($f:ident, $f_type:ty, $field_ident:ident) => {
|
||||
paste::item! {
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _sqrt>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<$f_type> = (0..SAMPLES)
|
||||
.map(|_| {
|
||||
let mut tmp = $f::rand(&mut rng);
|
||||
tmp.square_in_place();
|
||||
tmp
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
count = (count + 1) % SAMPLES;
|
||||
v[count].sqrt()
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! field_base {
|
||||
($f:ident, $f_type:ty, $f_repr:ident, $f_repr_type:ty, $field_ident:ident) => {
|
||||
paste::item! {
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _repr_add_nocarry>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<_> = (0..SAMPLES)
|
||||
.map(|_| {
|
||||
let mut tmp1 = $f_repr::rand(&mut rng);
|
||||
let mut tmp2 = $f_repr::rand(&mut rng);
|
||||
// Shave a few bits off to avoid overflow.
|
||||
for _ in 0..3 {
|
||||
tmp1.div2();
|
||||
tmp2.div2();
|
||||
}
|
||||
(tmp1, tmp2)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
n_fold!(tmp, v, add_nocarry, count);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _repr_sub_noborrow>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<_> = (0..SAMPLES)
|
||||
.map(|_| {
|
||||
let tmp1 = $f_repr::rand(&mut rng);
|
||||
let mut tmp2 = tmp1;
|
||||
// Ensure tmp2 is smaller than tmp1.
|
||||
for _ in 0..10 {
|
||||
tmp2.div2();
|
||||
}
|
||||
(tmp1, tmp2)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
n_fold!(tmp, v, sub_noborrow, count);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _repr_num_bits>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let tmp = v[count].num_bits();
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _repr_mul2>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count];
|
||||
n_fold!(tmp, mul2);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _repr_div2>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count];
|
||||
n_fold!(tmp, div2);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _negate>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count];
|
||||
tmp = -tmp;
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _into_repr>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
count = (count + 1) % SAMPLES;
|
||||
v[count].into_repr()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn [<bench_ $field_ident _from_repr>](b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<$f_repr_type> = (0..SAMPLES)
|
||||
.map(|_| $f::rand(&mut rng).into_repr())
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
count = (count + 1) % SAMPLES;
|
||||
$f::from(v[count])
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
11
curve-benches/src/macros/mod.rs
Normal file
11
curve-benches/src/macros/mod.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
#[macro_use]
|
||||
mod ec;
|
||||
|
||||
#[macro_use]
|
||||
mod field;
|
||||
|
||||
#[macro_use]
|
||||
mod pairing;
|
||||
|
||||
#[macro_use]
|
||||
mod utils;
|
||||
61
curve-benches/src/macros/pairing.rs
Normal file
61
curve-benches/src/macros/pairing.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
macro_rules! pairing_bench {
|
||||
($curve:ident, $pairing_field:ident, $pairing_type:ident) => {
|
||||
#[bench]
|
||||
fn bench_pairing_miller_loop(b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
$pairing_type!(v, rng);
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let tmp = $curve::miller_loop(&[(v[count].0.clone(), v[count].1.clone())]);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_pairing_final_exponentiation(b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<$pairing_field> = (0..SAMPLES)
|
||||
.map(|_| {
|
||||
(
|
||||
G1Affine::from(G1::rand(&mut rng)).into(),
|
||||
G2Affine::from(G2::rand(&mut rng)).into(),
|
||||
)
|
||||
})
|
||||
.map(|(p, q)| $curve::miller_loop(&[(p, q)]))
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let tmp = $curve::final_exponentiation(&v[count]);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_pairing_full(b: &mut ::test::Bencher) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
let v: Vec<(G1, G2)> = (0..SAMPLES)
|
||||
.map(|_| (G1::rand(&mut rng), G2::rand(&mut rng)))
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
b.iter(|| {
|
||||
let tmp = $curve::pairing(v[count].0, v[count].1);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
49
curve-benches/src/macros/utils.rs
Normal file
49
curve-benches/src/macros/utils.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
macro_rules! n_fold {
|
||||
($tmp:ident, $v:ident, $func:ident, $count:ident) => {
|
||||
const ITERS: usize = 1000;
|
||||
|
||||
#[cfg(not(feature = "n_fold"))]
|
||||
$tmp.$func(&$v[$count].1);
|
||||
#[cfg(feature = "n_fold")]
|
||||
for _ in 0..ITERS {
|
||||
$tmp.$func(&$v[$count].1);
|
||||
}
|
||||
};
|
||||
|
||||
($tmp:ident, $func:ident) => {
|
||||
const ITERS: usize = 1000;
|
||||
|
||||
#[cfg(not(feature = "n_fold"))]
|
||||
$tmp.$func();
|
||||
#[cfg(feature = "n_fold")]
|
||||
for _ in 0..ITERS {
|
||||
$tmp.$func();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! prepared_v {
|
||||
($v:ident, $rng:ident) => {
|
||||
let $v: Vec<(G1Prepared<Parameters>, G2Prepared<Parameters>)> = (0..SAMPLES)
|
||||
.map(|_| {
|
||||
(
|
||||
G1Affine::from(G1::rand(&mut $rng)).into(),
|
||||
G2Affine::from(G2::rand(&mut $rng)).into(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! affine_v {
|
||||
($v:ident, $rng:ident) => {
|
||||
let $v: Vec<(G1Affine, G2Affine)> = (0..SAMPLES)
|
||||
.map(|_| {
|
||||
(
|
||||
G1Affine::from(G1::rand(&mut $rng)).into(),
|
||||
G2Affine::from(G2::rand(&mut $rng)).into(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
};
|
||||
}
|
||||
33
curve-tests/Cargo.toml
Normal file
33
curve-tests/Cargo.toml
Normal file
@@ -0,0 +1,33 @@
|
||||
[package]
|
||||
name = "ark-curve-tests"
|
||||
version = "0.1.0"
|
||||
authors = [
|
||||
"Sean Bowe",
|
||||
"Alessandro Chiesa",
|
||||
"Matthew Green",
|
||||
"Ian Miers",
|
||||
"Pratyush Mishra",
|
||||
"Howard Wu",
|
||||
"arkworks contributors"
|
||||
]
|
||||
description = "A library for tests for finite fields, elliptic curves, and pairings"
|
||||
homepage = "https://arworks.rs"
|
||||
repository = "https://github.com/arkworks/algebra"
|
||||
documentation = "https://docs.rs/ark-curve-tests/"
|
||||
keywords = ["cryptography", "finite fields", "elliptic curves" ]
|
||||
categories = ["cryptography"]
|
||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
license = "MIT/Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false }
|
||||
ark-serialize = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-ff = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
ark-ec = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
rand = { version = "0.7", default-features = false}
|
||||
rand_xorshift = { version = "0.2", default-features = false}
|
||||
|
||||
[features]
|
||||
default = []
|
||||
std = [ "ark-std/std", "ark-ff/std", "ark-serialize/std", "ark-ec/std" ]
|
||||
1
curve-tests/LICENSE-APACHE
Symbolic link
1
curve-tests/LICENSE-APACHE
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE-APACHE
|
||||
1
curve-tests/LICENSE-MIT
Symbolic link
1
curve-tests/LICENSE-MIT
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE-MIT
|
||||
531
curve-tests/src/curves.rs
Normal file
531
curve-tests/src/curves.rs
Normal file
@@ -0,0 +1,531 @@
|
||||
#![allow(unused)]
|
||||
use ark_ec::{
|
||||
AffineCurve, MontgomeryModelParameters, ProjectiveCurve, SWModelParameters, TEModelParameters,
|
||||
};
|
||||
use ark_ff::{Field, One, PrimeField, UniformRand, Zero};
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SWFlags, SerializationError};
|
||||
use ark_std::{io::Cursor, vec::Vec};
|
||||
use rand::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
|
||||
pub const ITERATIONS: usize = 10;
|
||||
|
||||
fn random_addition_test<G: ProjectiveCurve>() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..ITERATIONS {
|
||||
let a = G::rand(&mut rng);
|
||||
let b = G::rand(&mut rng);
|
||||
let c = G::rand(&mut rng);
|
||||
let a_affine = a.into_affine();
|
||||
let b_affine = b.into_affine();
|
||||
let c_affine = c.into_affine();
|
||||
|
||||
// a + a should equal the doubling
|
||||
{
|
||||
let mut aplusa = a;
|
||||
aplusa.add_assign(&a);
|
||||
|
||||
let mut aplusamixed = a;
|
||||
aplusamixed.add_assign_mixed(&a.into_affine());
|
||||
|
||||
let mut adouble = a;
|
||||
adouble.double_in_place();
|
||||
|
||||
assert_eq!(aplusa, adouble);
|
||||
assert_eq!(aplusa, aplusamixed);
|
||||
}
|
||||
|
||||
let mut tmp = vec![G::zero(); 6];
|
||||
|
||||
// (a + b) + c
|
||||
tmp[0] = (a + &b) + &c;
|
||||
|
||||
// a + (b + c)
|
||||
tmp[1] = a + &(b + &c);
|
||||
|
||||
// (a + c) + b
|
||||
tmp[2] = (a + &c) + &b;
|
||||
|
||||
// Mixed addition
|
||||
|
||||
// (a + b) + c
|
||||
tmp[3] = a_affine.into_projective();
|
||||
tmp[3].add_assign_mixed(&b_affine);
|
||||
tmp[3].add_assign_mixed(&c_affine);
|
||||
|
||||
// a + (b + c)
|
||||
tmp[4] = b_affine.into_projective();
|
||||
tmp[4].add_assign_mixed(&c_affine);
|
||||
tmp[4].add_assign_mixed(&a_affine);
|
||||
|
||||
// (a + c) + b
|
||||
tmp[5] = a_affine.into_projective();
|
||||
tmp[5].add_assign_mixed(&c_affine);
|
||||
tmp[5].add_assign_mixed(&b_affine);
|
||||
|
||||
// Comparisons
|
||||
for i in 0..6 {
|
||||
for j in 0..6 {
|
||||
if tmp[i] != tmp[j] {
|
||||
println!("{} \n{}", tmp[i], tmp[j]);
|
||||
}
|
||||
assert_eq!(tmp[i], tmp[j], "Associativity failed {} {}", i, j);
|
||||
assert_eq!(
|
||||
tmp[i].into_affine(),
|
||||
tmp[j].into_affine(),
|
||||
"Associativity failed"
|
||||
);
|
||||
}
|
||||
|
||||
assert!(tmp[i] != a);
|
||||
assert!(tmp[i] != b);
|
||||
assert!(tmp[i] != c);
|
||||
|
||||
assert!(a != tmp[i]);
|
||||
assert!(b != tmp[i]);
|
||||
assert!(c != tmp[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn random_multiplication_test<G: ProjectiveCurve>() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..ITERATIONS {
|
||||
let mut a = G::rand(&mut rng);
|
||||
let mut b = G::rand(&mut rng);
|
||||
let a_affine = a.into_affine();
|
||||
let b_affine = b.into_affine();
|
||||
|
||||
let s = G::ScalarField::rand(&mut rng);
|
||||
|
||||
// s ( a + b )
|
||||
let mut tmp1 = a;
|
||||
tmp1.add_assign(&b);
|
||||
tmp1.mul_assign(s);
|
||||
|
||||
// sa + sb
|
||||
a.mul_assign(s);
|
||||
b.mul_assign(s);
|
||||
|
||||
let mut tmp2 = a;
|
||||
tmp2.add_assign(&b);
|
||||
|
||||
// Affine multiplication
|
||||
let mut tmp3 = a_affine.mul(s.into_repr());
|
||||
tmp3.add_assign(&b_affine.mul(s.into_repr()));
|
||||
|
||||
assert_eq!(tmp1, tmp2);
|
||||
assert_eq!(tmp1, tmp3);
|
||||
}
|
||||
}
|
||||
|
||||
fn random_doubling_test<G: ProjectiveCurve>() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..ITERATIONS {
|
||||
let mut a = G::rand(&mut rng);
|
||||
let mut b = G::rand(&mut rng);
|
||||
|
||||
// 2(a + b)
|
||||
let mut tmp1 = a;
|
||||
tmp1.add_assign(&b);
|
||||
tmp1.double_in_place();
|
||||
|
||||
// 2a + 2b
|
||||
a.double_in_place();
|
||||
b.double_in_place();
|
||||
|
||||
let mut tmp2 = a;
|
||||
tmp2.add_assign(&b);
|
||||
|
||||
let mut tmp3 = a;
|
||||
tmp3.add_assign_mixed(&b.into_affine());
|
||||
|
||||
assert_eq!(tmp1, tmp2);
|
||||
assert_eq!(tmp1, tmp3);
|
||||
}
|
||||
}
|
||||
|
||||
fn random_negation_test<G: ProjectiveCurve>() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..ITERATIONS {
|
||||
let r = G::rand(&mut rng);
|
||||
|
||||
let s = G::ScalarField::rand(&mut rng);
|
||||
let sneg = -s;
|
||||
assert!((s + &sneg).is_zero());
|
||||
|
||||
let mut t1 = r;
|
||||
t1.mul_assign(s);
|
||||
|
||||
let mut t2 = r;
|
||||
t2.mul_assign(sneg);
|
||||
|
||||
let mut t3 = t1;
|
||||
t3.add_assign(&t2);
|
||||
assert!(t3.is_zero());
|
||||
|
||||
let mut t4 = t1;
|
||||
t4.add_assign_mixed(&t2.into_affine());
|
||||
assert!(t4.is_zero());
|
||||
|
||||
t1 = -t1;
|
||||
assert_eq!(t1, t2);
|
||||
}
|
||||
}
|
||||
|
||||
fn random_transformation_test<G: ProjectiveCurve>() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..ITERATIONS {
|
||||
let g = G::rand(&mut rng);
|
||||
let g_affine = g.into_affine();
|
||||
let g_projective = g_affine.into_projective();
|
||||
assert_eq!(g, g_projective);
|
||||
}
|
||||
|
||||
// Batch normalization
|
||||
for _ in 0..10 {
|
||||
let mut v = (0..ITERATIONS)
|
||||
.map(|_| G::rand(&mut rng))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for i in &v {
|
||||
assert!(!i.is_normalized());
|
||||
}
|
||||
|
||||
use rand::distributions::{Distribution, Uniform};
|
||||
let between = Uniform::from(0..ITERATIONS);
|
||||
// Sprinkle in some normalized points
|
||||
for _ in 0..5 {
|
||||
v[between.sample(&mut rng)] = G::zero();
|
||||
}
|
||||
for _ in 0..5 {
|
||||
let s = between.sample(&mut rng);
|
||||
v[s] = v[s].into_affine().into_projective();
|
||||
}
|
||||
|
||||
let expected_v = v
|
||||
.iter()
|
||||
.map(|v| v.into_affine().into_projective())
|
||||
.collect::<Vec<_>>();
|
||||
G::batch_normalization(&mut v);
|
||||
|
||||
for i in &v {
|
||||
assert!(i.is_normalized());
|
||||
}
|
||||
|
||||
assert_eq!(v, expected_v);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn curve_tests<G: ProjectiveCurve>() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
// Negation edge case with zero.
|
||||
{
|
||||
let z = -G::zero();
|
||||
assert!(z.is_zero());
|
||||
}
|
||||
|
||||
// Doubling edge case with zero.
|
||||
{
|
||||
let mut z = -G::zero();
|
||||
z.double_in_place();
|
||||
assert!(z.is_zero());
|
||||
}
|
||||
|
||||
// Addition edge cases with zero
|
||||
{
|
||||
let mut r = G::rand(&mut rng);
|
||||
let rcopy = r;
|
||||
r.add_assign(&G::zero());
|
||||
assert_eq!(r, rcopy);
|
||||
r.add_assign_mixed(&G::Affine::zero());
|
||||
assert_eq!(r, rcopy);
|
||||
|
||||
let mut z = G::zero();
|
||||
z.add_assign(&G::zero());
|
||||
assert!(z.is_zero());
|
||||
z.add_assign_mixed(&G::Affine::zero());
|
||||
assert!(z.is_zero());
|
||||
|
||||
let mut z2 = z;
|
||||
z2.add_assign(&r);
|
||||
|
||||
z.add_assign_mixed(&r.into_affine());
|
||||
|
||||
assert_eq!(z, z2);
|
||||
assert_eq!(z, r);
|
||||
}
|
||||
|
||||
// Transformations
|
||||
{
|
||||
let a = G::rand(&mut rng);
|
||||
let b = a.into_affine().into_projective();
|
||||
let c = a
|
||||
.into_affine()
|
||||
.into_projective()
|
||||
.into_affine()
|
||||
.into_projective();
|
||||
assert_eq!(a, b);
|
||||
assert_eq!(b, c);
|
||||
}
|
||||
|
||||
// Test COFACTOR and COFACTOR_INV
|
||||
{
|
||||
let a = G::rand(&mut rng);
|
||||
let b = a.into_affine();
|
||||
let c = b.mul_by_cofactor_inv().mul_by_cofactor();
|
||||
assert_eq!(b, c);
|
||||
}
|
||||
|
||||
random_addition_test::<G>();
|
||||
random_multiplication_test::<G>();
|
||||
random_doubling_test::<G>();
|
||||
random_negation_test::<G>();
|
||||
random_transformation_test::<G>();
|
||||
}
|
||||
|
||||
pub fn sw_tests<P: SWModelParameters>() {
|
||||
sw_curve_serialization_test::<P>();
|
||||
sw_from_random_bytes::<P>();
|
||||
}
|
||||
|
||||
pub fn sw_from_random_bytes<P: SWModelParameters>() {
|
||||
use ark_ec::models::short_weierstrass_jacobian::{GroupAffine, GroupProjective};
|
||||
|
||||
let buf_size = GroupAffine::<P>::zero().serialized_size();
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..ITERATIONS {
|
||||
let a = GroupProjective::<P>::rand(&mut rng);
|
||||
let mut a = a.into_affine();
|
||||
{
|
||||
let mut serialized = vec![0; buf_size];
|
||||
let mut cursor = Cursor::new(&mut serialized[..]);
|
||||
a.serialize(&mut cursor).unwrap();
|
||||
|
||||
let mut cursor = Cursor::new(&serialized[..]);
|
||||
let p1 = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
|
||||
let p2 = GroupAffine::<P>::from_random_bytes(&serialized).unwrap();
|
||||
assert_eq!(p1, p2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sw_curve_serialization_test<P: SWModelParameters>() {
|
||||
use ark_ec::models::short_weierstrass_jacobian::{GroupAffine, GroupProjective};
|
||||
|
||||
let buf_size = GroupAffine::<P>::zero().serialized_size();
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..ITERATIONS {
|
||||
let a = GroupProjective::<P>::rand(&mut rng);
|
||||
let mut a = a.into_affine();
|
||||
{
|
||||
let mut serialized = vec![0; buf_size];
|
||||
let mut cursor = Cursor::new(&mut serialized[..]);
|
||||
a.serialize(&mut cursor).unwrap();
|
||||
|
||||
let mut cursor = Cursor::new(&serialized[..]);
|
||||
let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
{
|
||||
a.y = -a.y;
|
||||
let mut serialized = vec![0; buf_size];
|
||||
let mut cursor = Cursor::new(&mut serialized[..]);
|
||||
a.serialize(&mut cursor).unwrap();
|
||||
let mut cursor = Cursor::new(&serialized[..]);
|
||||
let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
{
|
||||
let a = GroupAffine::<P>::zero();
|
||||
let mut serialized = vec![0; buf_size];
|
||||
let mut cursor = Cursor::new(&mut serialized[..]);
|
||||
a.serialize(&mut cursor).unwrap();
|
||||
let mut cursor = Cursor::new(&serialized[..]);
|
||||
let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
{
|
||||
let a = GroupAffine::<P>::zero();
|
||||
let mut serialized = vec![0; buf_size - 1];
|
||||
let mut cursor = Cursor::new(&mut serialized[..]);
|
||||
a.serialize(&mut cursor).unwrap_err();
|
||||
}
|
||||
|
||||
{
|
||||
let serialized = vec![0; buf_size - 1];
|
||||
let mut cursor = Cursor::new(&serialized[..]);
|
||||
GroupAffine::<P>::deserialize(&mut cursor).unwrap_err();
|
||||
}
|
||||
|
||||
{
|
||||
let mut serialized = vec![0; a.uncompressed_size()];
|
||||
let mut cursor = Cursor::new(&mut serialized[..]);
|
||||
a.serialize_uncompressed(&mut cursor).unwrap();
|
||||
|
||||
let mut cursor = Cursor::new(&serialized[..]);
|
||||
let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
{
|
||||
a.y = -a.y;
|
||||
let mut serialized = vec![0; a.uncompressed_size()];
|
||||
let mut cursor = Cursor::new(&mut serialized[..]);
|
||||
a.serialize_uncompressed(&mut cursor).unwrap();
|
||||
let mut cursor = Cursor::new(&serialized[..]);
|
||||
let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
{
|
||||
let a = GroupAffine::<P>::zero();
|
||||
let mut serialized = vec![0; a.uncompressed_size()];
|
||||
let mut cursor = Cursor::new(&mut serialized[..]);
|
||||
a.serialize_uncompressed(&mut cursor).unwrap();
|
||||
let mut cursor = Cursor::new(&serialized[..]);
|
||||
let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn montgomery_conversion_test<P>()
|
||||
where
|
||||
P: TEModelParameters,
|
||||
{
|
||||
// A = 2 * (a + d) / (a - d)
|
||||
let a = P::BaseField::one().double()
|
||||
* &(P::COEFF_A + &P::COEFF_D)
|
||||
* &(P::COEFF_A - &P::COEFF_D).inverse().unwrap();
|
||||
// B = 4 / (a - d)
|
||||
let b = P::BaseField::one().double().double() * &(P::COEFF_A - &P::COEFF_D).inverse().unwrap();
|
||||
|
||||
assert_eq!(a, P::MontgomeryModelParameters::COEFF_A);
|
||||
assert_eq!(b, P::MontgomeryModelParameters::COEFF_B);
|
||||
}
|
||||
|
||||
pub fn edwards_tests<P: TEModelParameters>()
|
||||
where
|
||||
P::BaseField: PrimeField,
|
||||
{
|
||||
edwards_curve_serialization_test::<P>();
|
||||
edwards_from_random_bytes::<P>();
|
||||
}
|
||||
|
||||
pub fn edwards_from_random_bytes<P: TEModelParameters>()
|
||||
where
|
||||
P::BaseField: PrimeField,
|
||||
{
|
||||
use ark_ec::models::twisted_edwards_extended::{GroupAffine, GroupProjective};
|
||||
use ark_ff::{to_bytes, ToBytes};
|
||||
|
||||
let buf_size = GroupAffine::<P>::zero().serialized_size();
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..ITERATIONS {
|
||||
let a = GroupProjective::<P>::rand(&mut rng);
|
||||
let mut a = a.into_affine();
|
||||
{
|
||||
let mut serialized = vec![0; buf_size];
|
||||
let mut cursor = Cursor::new(&mut serialized[..]);
|
||||
a.serialize(&mut cursor).unwrap();
|
||||
|
||||
let mut cursor = Cursor::new(&serialized[..]);
|
||||
let p1 = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
|
||||
let p2 = GroupAffine::<P>::from_random_bytes(&serialized).unwrap();
|
||||
assert_eq!(p1, p2);
|
||||
}
|
||||
}
|
||||
|
||||
for _ in 0..ITERATIONS {
|
||||
let mut biginteger =
|
||||
<<GroupAffine<P> as AffineCurve>::BaseField as PrimeField>::BigInt::rand(&mut rng);
|
||||
let mut bytes = to_bytes![biginteger].unwrap();
|
||||
let mut g = GroupAffine::<P>::from_random_bytes(&bytes);
|
||||
while g.is_none() {
|
||||
bytes.iter_mut().for_each(|i| *i = i.wrapping_sub(1));
|
||||
g = GroupAffine::<P>::from_random_bytes(&bytes);
|
||||
}
|
||||
let _g = g.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn edwards_curve_serialization_test<P: TEModelParameters>() {
|
||||
use ark_ec::models::twisted_edwards_extended::{GroupAffine, GroupProjective};
|
||||
|
||||
let buf_size = GroupAffine::<P>::zero().serialized_size();
|
||||
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..ITERATIONS {
|
||||
let a = GroupProjective::<P>::rand(&mut rng);
|
||||
let a = a.into_affine();
|
||||
{
|
||||
let mut serialized = vec![0; buf_size];
|
||||
let mut cursor = Cursor::new(&mut serialized[..]);
|
||||
a.serialize(&mut cursor).unwrap();
|
||||
|
||||
let mut cursor = Cursor::new(&serialized[..]);
|
||||
let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
{
|
||||
let a = GroupAffine::<P>::zero();
|
||||
let mut serialized = vec![0; buf_size];
|
||||
let mut cursor = Cursor::new(&mut serialized[..]);
|
||||
a.serialize(&mut cursor).unwrap();
|
||||
let mut cursor = Cursor::new(&serialized[..]);
|
||||
let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
{
|
||||
let a = GroupAffine::<P>::zero();
|
||||
let mut serialized = vec![0; buf_size - 1];
|
||||
let mut cursor = Cursor::new(&mut serialized[..]);
|
||||
a.serialize(&mut cursor).unwrap_err();
|
||||
}
|
||||
|
||||
{
|
||||
let serialized = vec![0; buf_size - 1];
|
||||
let mut cursor = Cursor::new(&serialized[..]);
|
||||
GroupAffine::<P>::deserialize(&mut cursor).unwrap_err();
|
||||
}
|
||||
|
||||
{
|
||||
let mut serialized = vec![0; a.uncompressed_size()];
|
||||
let mut cursor = Cursor::new(&mut serialized[..]);
|
||||
a.serialize_uncompressed(&mut cursor).unwrap();
|
||||
|
||||
let mut cursor = Cursor::new(&serialized[..]);
|
||||
let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
{
|
||||
let a = GroupAffine::<P>::zero();
|
||||
let mut serialized = vec![0; a.uncompressed_size()];
|
||||
let mut cursor = Cursor::new(&mut serialized[..]);
|
||||
a.serialize_uncompressed(&mut cursor).unwrap();
|
||||
let mut cursor = Cursor::new(&serialized[..]);
|
||||
let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user