@ -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);
|
|||
}
|
|||
}
|
|||
}
|