@ -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 |
@ -0,0 +1,11 @@ |
|||||
|
target |
||||
|
Cargo.lock |
||||
|
.DS_Store |
||||
|
.idea |
||||
|
*.iml |
||||
|
*.ipynb_checkpoints |
||||
|
*.pyc |
||||
|
*.sage.py |
||||
|
params |
||||
|
*.swp |
||||
|
*.swo |
@ -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" |
@ -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 |
@ -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. |
@ -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. |
@ -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 |
@ -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 = [] |
@ -0,0 +1 @@ |
|||||
|
../LICENSE-APACHE |
@ -0,0 +1 @@ |
|||||
|
../LICENSE-MIT |
@ -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,
|
||||
|
]));
|
@ -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,
|
||||
|
]));
|
@ -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>;
|
@ -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());
|
||||
|
}
|
||||
|
}
|
@ -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]));
|
@ -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,
|
||||
|
),
|
||||
|
];
|
||||
|
}
|
@ -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);
|
@ -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)
|
||||
|
}
|
||||
|
}
|
@ -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,
|
||||
|
]);
|
||||
|
}
|
@ -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;
|
@ -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);
|
||||
|
}
|
||||
|
}
|
@ -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::*;
|
@ -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 = [] |
@ -0,0 +1 @@ |
|||||
|
../LICENSE-APACHE |
@ -0,0 +1 @@ |
|||||
|
../LICENSE-MIT |
@ -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,
|
||||
|
]));
|
@ -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,
|
||||
|
]));
|
@ -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;
|
||||
|
}
|
@ -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());
|
||||
|
}
|
||||
|
}
|
@ -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]));
|
@ -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,
|
||||
|
])),
|
||||
|
),
|
||||
|
];
|
||||
|
}
|
@ -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);
|
@ -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
|
||||
|
}
|
||||
|
}
|
@ -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,
|
||||
|
]);
|
||||
|
}
|
@ -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;
|
@ -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::*;
|
@ -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 = [] |
@ -0,0 +1 @@ |
|||||
|
../LICENSE-APACHE |
@ -0,0 +1 @@ |
|||||
|
../LICENSE-MIT |
@ -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,
|
||||
|
]));
|
@ -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,
|
||||
|
]));
|
@ -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>;
|
@ -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());
|
||||
|
}
|
@ -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]));
|
@ -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,
|
||||
|
])),
|
||||
|
),
|
||||
|
];
|
||||
|
}
|
@ -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);
|
@ -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)
|
||||
|
}
|
||||
|
}
|
@ -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,
|
||||
|
]);
|
||||
|
}
|
@ -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;
|
@ -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);
|
||||
|
}
|
||||
|
}
|
@ -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::*;
|
@ -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" ] |
@ -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,
|
||||
|
]));
|
@ -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,
|
||||
|
]));
|
@ -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>;
|
@ -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());
|
||||
|
}
|
@ -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,
|
||||
|
]);
|
||||
|
}
|
@ -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
|
||||
|
}
|
||||
|
}
|
@ -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,
|
||||
|
])),
|
||||
|
];
|
||||
|
}
|
@ -0,0 +1 @@ |
|||||
|
pub use ark_bls12_377::{Fq as Fr, FqParameters as FrParameters};
|
@ -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;
|
@ -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);
|
||||
|
}
|
@ -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::*;
|
@ -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" ] |
@ -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,
|
||||
|
]));
|
@ -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,
|
||||
|
]));
|
@ -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,
|
||||
|
]);
|
@ -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());
|
||||
|
}
|
@ -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,
|
||||
|
]);
|
||||
|
}
|
@ -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
|
||||
|
}
|
||||
|
}
|
@ -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,
|
||||
|
])),
|
||||
|
];
|
||||
|
}
|
@ -0,0 +1 @@ |
|||||
|
pub use ark_bls12_377::{Fq as Fr, FqParameters as FrParameters};
|
@ -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;
|
@ -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);
|
||||
|
}
|
@ -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::*;
|
@ -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" |
@ -0,0 +1 @@ |
|||||
|
../LICENSE-APACHE |
@ -0,0 +1 @@ |
|||||
|
../LICENSE-MIT |
@ -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");
|
||||
|
}
|
||||
|
}
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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;
|
@ -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;
|
@ -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)
|
||||
|
});
|
||||
|
}
|
||||
|
};
|
||||
|
}
|
@ -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])
|
||||
|
});
|
||||
|
}
|
||||
|
}
|
||||
|
};
|
||||
|
}
|
@ -0,0 +1,11 @@ |
|||||
|
#[macro_use]
|
||||
|
mod ec;
|
||||
|
|
||||
|
#[macro_use]
|
||||
|
mod field;
|
||||
|
|
||||
|
#[macro_use]
|
||||
|
mod pairing;
|
||||
|
|
||||
|
#[macro_use]
|
||||
|
mod utils;
|
@ -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
|
||||
|
});
|
||||
|
}
|
||||
|
};
|
||||
|
}
|
@ -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();
|
||||
|
};
|
||||
|
}
|
@ -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" ] |
@ -0,0 +1 @@ |
|||||
|
../LICENSE-APACHE |
@ -0,0 +1 @@ |
|||||
|
../LICENSE-MIT |
@ -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);
|
||||
|
}
|
||||
|
}
|
||||
|
}
|