mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-07 06:44:11 +00:00
Merge pull request #46 from str4d/ff-traits
Migrate to ff and group crates
This commit is contained in:
commit
c57a31e82e
368
Cargo.lock
generated
368
Cargo.lock
generated
@ -28,22 +28,6 @@ dependencies = [
|
|||||||
"stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "aho-corasick"
|
|
||||||
version = "0.6.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ansi_term"
|
|
||||||
version = "0.11.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
@ -52,27 +36,6 @@ dependencies = [
|
|||||||
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "backtrace"
|
|
||||||
version = "0.3.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "backtrace-sys"
|
|
||||||
version = "0.1.24"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bellman"
|
name = "bellman"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -80,8 +43,10 @@ dependencies = [
|
|||||||
"bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ff 0.4.0",
|
||||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"group 0.1.0",
|
||||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pairing 0.14.2",
|
"pairing 0.14.2",
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -92,11 +57,6 @@ name = "bit-vec"
|
|||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bitflags"
|
|
||||||
version = "0.9.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
@ -130,61 +90,6 @@ name = "byteorder"
|
|||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cargo_metadata"
|
|
||||||
version = "0.5.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cc"
|
|
||||||
version = "1.0.22"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clippy"
|
|
||||||
version = "0.0.200"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"clippy_lints 0.0.200 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clippy_lints"
|
|
||||||
version = "0.0.200"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "constant_time_eq"
|
name = "constant_time_eq"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
@ -204,16 +109,24 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "ff"
|
||||||
version = "1.5.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
dependencies = [
|
||||||
|
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ff_derive 0.3.0",
|
||||||
|
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "error-chain"
|
name = "ff_derive"
|
||||||
version = "0.11.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-bigint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"proc-macro2 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -270,11 +183,11 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getopts"
|
name = "group"
|
||||||
version = "0.2.18"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ff 0.4.0",
|
||||||
|
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -294,34 +207,6 @@ dependencies = [
|
|||||||
"proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "idna"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "if_chain"
|
|
||||||
version = "0.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itertools"
|
|
||||||
version = "0.7.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itoa"
|
|
||||||
version = "0.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@ -339,6 +224,7 @@ dependencies = [
|
|||||||
"bellman 0.1.0",
|
"bellman 0.1.0",
|
||||||
"blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)",
|
"blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)",
|
||||||
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ff 0.4.0",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pairing 0.14.2",
|
"pairing 0.14.2",
|
||||||
@ -348,19 +234,6 @@ dependencies = [
|
|||||||
"zip32 0.0.0",
|
"zip32 0.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "matches"
|
|
||||||
version = "0.1.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nodrop"
|
name = "nodrop"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
@ -406,15 +279,11 @@ name = "pairing"
|
|||||||
version = "0.14.2"
|
version = "0.14.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clippy 0.0.200 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ff 0.4.0",
|
||||||
|
"group 0.1.0",
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "percent-encoding"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-hack"
|
name = "proc-macro-hack"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -436,20 +305,6 @@ dependencies = [
|
|||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pulldown-cmark"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quine-mc_cluskey"
|
|
||||||
version = "0.2.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.6.8"
|
version = "0.6.8"
|
||||||
@ -483,26 +338,6 @@ name = "redox_syscall"
|
|||||||
version = "0.1.40"
|
version = "0.1.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-syntax"
|
|
||||||
version = "0.6.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-crypto"
|
name = "rust-crypto"
|
||||||
version = "0.2.36"
|
version = "0.2.36"
|
||||||
@ -515,29 +350,11 @@ dependencies = [
|
|||||||
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc-demangle"
|
|
||||||
version = "0.1.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-serialize"
|
name = "rustc-serialize"
|
||||||
version = "0.3.24"
|
version = "0.3.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc_version"
|
|
||||||
version = "0.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ryu"
|
|
||||||
version = "0.2.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sapling-crypto"
|
name = "sapling-crypto"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
@ -546,51 +363,13 @@ dependencies = [
|
|||||||
"blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)",
|
"blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)",
|
||||||
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ff 0.4.0",
|
||||||
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pairing 0.14.2",
|
"pairing 0.14.2",
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "semver"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "semver-parser"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde"
|
|
||||||
version = "1.0.75"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_derive"
|
|
||||||
version = "1.0.75"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_json"
|
|
||||||
version = "1.0.26"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stream-cipher"
|
name = "stream-cipher"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@ -609,14 +388,6 @@ dependencies = [
|
|||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thread_local"
|
|
||||||
version = "0.3.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.1.40"
|
version = "0.1.40"
|
||||||
@ -627,62 +398,16 @@ dependencies = [
|
|||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml"
|
|
||||||
version = "0.4.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ucd-util"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-bidi"
|
|
||||||
version = "0.3.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-normalization"
|
|
||||||
version = "0.1.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-width"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "url"
|
|
||||||
version = "1.7.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "utf8-ranges"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.4"
|
version = "0.3.4"
|
||||||
@ -708,6 +433,7 @@ version = "0.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)",
|
"blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)",
|
||||||
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ff 0.4.0",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pairing 0.14.2",
|
"pairing 0.14.2",
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -720,6 +446,7 @@ version = "0.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bellman 0.1.0",
|
"bellman 0.1.0",
|
||||||
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ff 0.4.0",
|
||||||
"pairing 0.14.2",
|
"pairing 0.14.2",
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"sapling-crypto 0.0.1",
|
"sapling-crypto 0.0.1",
|
||||||
@ -736,6 +463,7 @@ dependencies = [
|
|||||||
"aes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"aes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)",
|
"blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)",
|
||||||
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ff 0.4.0",
|
||||||
"fpe 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fpe 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pairing 0.14.2",
|
"pairing 0.14.2",
|
||||||
@ -746,28 +474,16 @@ dependencies = [
|
|||||||
"checksum aes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6fb1737cdc8da3db76e90ca817a194249a38fcb500c2e6ecec39b29448aa873"
|
"checksum aes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6fb1737cdc8da3db76e90ca817a194249a38fcb500c2e6ecec39b29448aa873"
|
||||||
"checksum aes-soft 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67cc03b0a090a05cb01e96998a01905d7ceedce1bc23b756c0bb7faa0682ccb1"
|
"checksum aes-soft 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67cc03b0a090a05cb01e96998a01905d7ceedce1bc23b756c0bb7faa0682ccb1"
|
||||||
"checksum aesni 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6810b7fb9f2bb4f76f05ac1c170b8dde285b6308955dc3afd89710268c958d9e"
|
"checksum aesni 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6810b7fb9f2bb4f76f05ac1c170b8dde285b6308955dc3afd89710268c958d9e"
|
||||||
"checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a"
|
|
||||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
|
||||||
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
||||||
"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
|
|
||||||
"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
|
|
||||||
"checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f"
|
"checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f"
|
||||||
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
|
||||||
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
||||||
"checksum blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)" = "<none>"
|
"checksum blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)" = "<none>"
|
||||||
"checksum block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "370424437b9459f3dfd68428ed9376ddfe03d8b70ede29cc533b3557df186ab4"
|
"checksum block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "370424437b9459f3dfd68428ed9376ddfe03d8b70ede29cc533b3557df186ab4"
|
||||||
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
|
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
|
||||||
"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87"
|
"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87"
|
||||||
"checksum cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1efca0b863ca03ed4c109fb1c55e0bc4bbeb221d3e103d86251046b06a526bd0"
|
|
||||||
"checksum cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "4a6007c146fdd28d4512a794b07ffe9d8e89e6bf86e2e0c4ddff2e1fb54a0007"
|
|
||||||
"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
|
|
||||||
"checksum clippy 0.0.200 (registry+https://github.com/rust-lang/crates.io-index)" = "927a1f79af10deb103df108347f23c6b7fa1731c953d6fb24d68be1748a0993f"
|
|
||||||
"checksum clippy_lints 0.0.200 (registry+https://github.com/rust-lang/crates.io-index)" = "d2432663f6bdb90255dcf9df5ca504f99b575bb471281591138f62f9d31f863b"
|
|
||||||
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
|
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
|
||||||
"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
|
"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
|
||||||
"checksum digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603"
|
"checksum digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603"
|
||||||
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
|
|
||||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
|
||||||
"checksum fpe 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce3371c82bfbd984f624cab093f55e7336f5a6e589f8518e1258f54f011b89ad"
|
"checksum fpe 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce3371c82bfbd984f624cab093f55e7336f5a6e589f8518e1258f54f011b89ad"
|
||||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||||
@ -775,58 +491,30 @@ dependencies = [
|
|||||||
"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
|
"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
|
||||||
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
|
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
|
||||||
"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
|
"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
|
||||||
"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797"
|
|
||||||
"checksum hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4da5f0e01bd8a71a224a4eedecaacfcabda388dbb7a80faf04d3514287572d95"
|
"checksum hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4da5f0e01bd8a71a224a4eedecaacfcabda388dbb7a80faf04d3514287572d95"
|
||||||
"checksum hex-literal-impl 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1d340b6514f232f6db1bd16db65302a5278a04fef9ce867cb932e7e5fa21130a"
|
"checksum hex-literal-impl 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1d340b6514f232f6db1bd16db65302a5278a04fef9ce867cb932e7e5fa21130a"
|
||||||
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
|
|
||||||
"checksum if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4bac95d9aa0624e7b78187d6fb8ab012b41d9f6f54b1bcb61e61c4845f8357ec"
|
|
||||||
"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
|
|
||||||
"checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606"
|
|
||||||
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
|
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
|
||||||
"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b"
|
"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b"
|
||||||
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
|
||||||
"checksum memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a3b4142ab8738a78c51896f704f83c11df047ff1bda9a92a661aa6361552d93d"
|
|
||||||
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
|
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
|
||||||
"checksum num-bigint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3eceac7784c5dc97c2d6edf30259b4e153e6e2b42b3c85e9a6e9f45d06caef6e"
|
"checksum num-bigint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3eceac7784c5dc97c2d6edf30259b4e153e6e2b42b3c85e9a6e9f45d06caef6e"
|
||||||
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
|
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
|
||||||
"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
|
"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
|
||||||
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
|
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
|
||||||
"checksum opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d620c9c26834b34f039489ac0dfdb12c7ac15ccaf818350a64c9b5334a452ad7"
|
"checksum opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d620c9c26834b34f039489ac0dfdb12c7ac15ccaf818350a64c9b5334a452ad7"
|
||||||
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
|
|
||||||
"checksum proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba8d4f9257b85eb6cdf13f055cea3190520aab1409ca2ab43493ea4820c25f0"
|
"checksum proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba8d4f9257b85eb6cdf13f055cea3190520aab1409ca2ab43493ea4820c25f0"
|
||||||
"checksum proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5cb6f960ad471404618e9817c0e5d10b1ae74cfdf01fab89ea0641fe7fb2892"
|
"checksum proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5cb6f960ad471404618e9817c0e5d10b1ae74cfdf01fab89ea0641fe7fb2892"
|
||||||
"checksum proc-macro2 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b331c6ad3411474cd55540398dc7ad89fc41488e64ec71fdecc9c9b86de96fb0"
|
"checksum proc-macro2 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b331c6ad3411474cd55540398dc7ad89fc41488e64ec71fdecc9c9b86de96fb0"
|
||||||
"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
|
|
||||||
"checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
|
|
||||||
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
|
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
|
||||||
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
|
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
|
||||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||||
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
|
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
|
||||||
"checksum regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "67d0301b0c6804eca7e3c275119d0b01ff3b7ab9258a65709e608a66312a1025"
|
|
||||||
"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d"
|
|
||||||
"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
|
"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
|
||||||
"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395"
|
|
||||||
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
||||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
|
||||||
"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7"
|
|
||||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
|
||||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
|
||||||
"checksum serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)" = "22d340507cea0b7e6632900a176101fea959c7065d93ba555072da90aaaafc87"
|
|
||||||
"checksum serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)" = "234fc8b737737b148ccd625175fc6390f5e4dacfdaa543cb93a3430d984a9119"
|
|
||||||
"checksum serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae"
|
|
||||||
"checksum stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "30dc6118470d69ce0fdcf7e6f95e95853f7f4f72f80d835d4519577c323814ab"
|
"checksum stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "30dc6118470d69ce0fdcf7e6f95e95853f7f4f72f80d835d4519577c323814ab"
|
||||||
"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
|
"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
|
||||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
|
||||||
"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
|
"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
|
||||||
"checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9"
|
|
||||||
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
||||||
"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
|
|
||||||
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
|
||||||
"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
|
|
||||||
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
|
||||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||||
"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6"
|
|
||||||
"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4"
|
|
||||||
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
|
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
|
||||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"bellman",
|
"bellman",
|
||||||
|
"ff",
|
||||||
|
"group",
|
||||||
"librustzcash",
|
"librustzcash",
|
||||||
"pairing",
|
"pairing",
|
||||||
"sapling-crypto",
|
"sapling-crypto",
|
||||||
|
@ -11,12 +11,20 @@ version = "0.1.0"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.4"
|
rand = "0.4"
|
||||||
bit-vec = "0.4.4"
|
bit-vec = "0.4.4"
|
||||||
|
ff = { path = "../ff" }
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
futures-cpupool = "0.1"
|
futures-cpupool = "0.1"
|
||||||
|
group = { path = "../group" }
|
||||||
num_cpus = "1"
|
num_cpus = "1"
|
||||||
crossbeam = "0.3"
|
crossbeam = "0.3"
|
||||||
pairing = { path = "../pairing" }
|
pairing = { path = "../pairing", optional = true }
|
||||||
byteorder = "1"
|
byteorder = "1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
groth16 = ["pairing"]
|
||||||
|
default = ["groth16"]
|
||||||
|
|
||||||
|
[[test]]
|
||||||
|
name = "mimc"
|
||||||
|
path = "tests/mimc.rs"
|
||||||
|
required-features = ["groth16"]
|
||||||
|
@ -10,12 +10,8 @@
|
|||||||
//! This allows us to perform polynomial operations in O(n)
|
//! This allows us to perform polynomial operations in O(n)
|
||||||
//! by performing an O(n log n) FFT over such a domain.
|
//! by performing an O(n log n) FFT over such a domain.
|
||||||
|
|
||||||
use pairing::{
|
use ff::{Field, PrimeField, ScalarEngine};
|
||||||
Engine,
|
use group::CurveProjective;
|
||||||
Field,
|
|
||||||
PrimeField,
|
|
||||||
CurveProjective
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
SynthesisError
|
SynthesisError
|
||||||
@ -23,7 +19,7 @@ use super::{
|
|||||||
|
|
||||||
use super::multicore::Worker;
|
use super::multicore::Worker;
|
||||||
|
|
||||||
pub struct EvaluationDomain<E: Engine, G: Group<E>> {
|
pub struct EvaluationDomain<E: ScalarEngine, G: Group<E>> {
|
||||||
coeffs: Vec<G>,
|
coeffs: Vec<G>,
|
||||||
exp: u32,
|
exp: u32,
|
||||||
omega: E::Fr,
|
omega: E::Fr,
|
||||||
@ -32,7 +28,7 @@ pub struct EvaluationDomain<E: Engine, G: Group<E>> {
|
|||||||
minv: E::Fr
|
minv: E::Fr
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine, G: Group<E>> EvaluationDomain<E, G> {
|
impl<E: ScalarEngine, G: Group<E>> EvaluationDomain<E, G> {
|
||||||
pub fn as_ref(&self) -> &[G] {
|
pub fn as_ref(&self) -> &[G] {
|
||||||
&self.coeffs
|
&self.coeffs
|
||||||
}
|
}
|
||||||
@ -189,7 +185,7 @@ impl<E: Engine, G: Group<E>> EvaluationDomain<E, G> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Group<E: Engine>: Sized + Copy + Clone + Send + Sync {
|
pub trait Group<E: ScalarEngine>: Sized + Copy + Clone + Send + Sync {
|
||||||
fn group_zero() -> Self;
|
fn group_zero() -> Self;
|
||||||
fn group_mul_assign(&mut self, by: &E::Fr);
|
fn group_mul_assign(&mut self, by: &E::Fr);
|
||||||
fn group_add_assign(&mut self, other: &Self);
|
fn group_add_assign(&mut self, other: &Self);
|
||||||
@ -227,23 +223,23 @@ impl<G: CurveProjective> Group<G::Engine> for Point<G> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Scalar<E: Engine>(pub E::Fr);
|
pub struct Scalar<E: ScalarEngine>(pub E::Fr);
|
||||||
|
|
||||||
impl<E: Engine> PartialEq for Scalar<E> {
|
impl<E: ScalarEngine> PartialEq for Scalar<E> {
|
||||||
fn eq(&self, other: &Scalar<E>) -> bool {
|
fn eq(&self, other: &Scalar<E>) -> bool {
|
||||||
self.0 == other.0
|
self.0 == other.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine> Copy for Scalar<E> { }
|
impl<E: ScalarEngine> Copy for Scalar<E> { }
|
||||||
|
|
||||||
impl<E: Engine> Clone for Scalar<E> {
|
impl<E: ScalarEngine> Clone for Scalar<E> {
|
||||||
fn clone(&self) -> Scalar<E> {
|
fn clone(&self) -> Scalar<E> {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine> Group<E> for Scalar<E> {
|
impl<E: ScalarEngine> Group<E> for Scalar<E> {
|
||||||
fn group_zero() -> Self {
|
fn group_zero() -> Self {
|
||||||
Scalar(E::Fr::zero())
|
Scalar(E::Fr::zero())
|
||||||
}
|
}
|
||||||
@ -258,7 +254,7 @@ impl<E: Engine> Group<E> for Scalar<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn best_fft<E: Engine, T: Group<E>>(a: &mut [T], worker: &Worker, omega: &E::Fr, log_n: u32)
|
fn best_fft<E: ScalarEngine, T: Group<E>>(a: &mut [T], worker: &Worker, omega: &E::Fr, log_n: u32)
|
||||||
{
|
{
|
||||||
let log_cpus = worker.log_num_cpus();
|
let log_cpus = worker.log_num_cpus();
|
||||||
|
|
||||||
@ -269,7 +265,7 @@ fn best_fft<E: Engine, T: Group<E>>(a: &mut [T], worker: &Worker, omega: &E::Fr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serial_fft<E: Engine, T: Group<E>>(a: &mut [T], omega: &E::Fr, log_n: u32)
|
fn serial_fft<E: ScalarEngine, T: Group<E>>(a: &mut [T], omega: &E::Fr, log_n: u32)
|
||||||
{
|
{
|
||||||
fn bitreverse(mut n: u32, l: u32) -> u32 {
|
fn bitreverse(mut n: u32, l: u32) -> u32 {
|
||||||
let mut r = 0;
|
let mut r = 0;
|
||||||
@ -314,7 +310,7 @@ fn serial_fft<E: Engine, T: Group<E>>(a: &mut [T], omega: &E::Fr, log_n: u32)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parallel_fft<E: Engine, T: Group<E>>(
|
fn parallel_fft<E: ScalarEngine, T: Group<E>>(
|
||||||
a: &mut [T],
|
a: &mut [T],
|
||||||
worker: &Worker,
|
worker: &Worker,
|
||||||
omega: &E::Fr,
|
omega: &E::Fr,
|
||||||
@ -375,12 +371,13 @@ fn parallel_fft<E: Engine, T: Group<E>>(
|
|||||||
|
|
||||||
// Test multiplying various (low degree) polynomials together and
|
// Test multiplying various (low degree) polynomials together and
|
||||||
// comparing with naive evaluations.
|
// comparing with naive evaluations.
|
||||||
|
#[cfg(feature = "pairing")]
|
||||||
#[test]
|
#[test]
|
||||||
fn polynomial_arith() {
|
fn polynomial_arith() {
|
||||||
use pairing::bls12_381::Bls12;
|
use pairing::bls12_381::Bls12;
|
||||||
use rand::{self, Rand};
|
use rand::{self, Rand};
|
||||||
|
|
||||||
fn test_mul<E: Engine, R: rand::Rng>(rng: &mut R)
|
fn test_mul<E: ScalarEngine, R: rand::Rng>(rng: &mut R)
|
||||||
{
|
{
|
||||||
let worker = Worker::new();
|
let worker = Worker::new();
|
||||||
|
|
||||||
@ -422,12 +419,13 @@ fn polynomial_arith() {
|
|||||||
test_mul::<Bls12, _>(rng);
|
test_mul::<Bls12, _>(rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "pairing")]
|
||||||
#[test]
|
#[test]
|
||||||
fn fft_composition() {
|
fn fft_composition() {
|
||||||
use pairing::bls12_381::Bls12;
|
use pairing::bls12_381::Bls12;
|
||||||
use rand;
|
use rand;
|
||||||
|
|
||||||
fn test_comp<E: Engine, R: rand::Rng>(rng: &mut R)
|
fn test_comp<E: ScalarEngine, R: rand::Rng>(rng: &mut R)
|
||||||
{
|
{
|
||||||
let worker = Worker::new();
|
let worker = Worker::new();
|
||||||
|
|
||||||
@ -460,13 +458,14 @@ fn fft_composition() {
|
|||||||
test_comp::<Bls12, _>(rng);
|
test_comp::<Bls12, _>(rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "pairing")]
|
||||||
#[test]
|
#[test]
|
||||||
fn parallel_fft_consistency() {
|
fn parallel_fft_consistency() {
|
||||||
use pairing::bls12_381::Bls12;
|
use pairing::bls12_381::Bls12;
|
||||||
use rand::{self, Rand};
|
use rand::{self, Rand};
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
|
|
||||||
fn test_consistency<E: Engine, R: rand::Rng>(rng: &mut R)
|
fn test_consistency<E: ScalarEngine, R: rand::Rng>(rng: &mut R)
|
||||||
{
|
{
|
||||||
let worker = Worker::new();
|
let worker = Worker::new();
|
||||||
|
|
||||||
|
@ -2,14 +2,9 @@ use rand::Rng;
|
|||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use pairing::{
|
use ff::{Field, PrimeField};
|
||||||
Engine,
|
use group::{CurveAffine, CurveProjective, Wnaf};
|
||||||
PrimeField,
|
use pairing::Engine;
|
||||||
Field,
|
|
||||||
Wnaf,
|
|
||||||
CurveProjective,
|
|
||||||
CurveAffine
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Parameters,
|
Parameters,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
use group::{CurveAffine, EncodedPoint};
|
||||||
use pairing::{
|
use pairing::{
|
||||||
Engine,
|
Engine,
|
||||||
CurveAffine,
|
PairingCurveAffine,
|
||||||
EncodedPoint
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use ::{
|
use ::{
|
||||||
@ -385,9 +385,9 @@ pub struct PreparedVerifyingKey<E: Engine> {
|
|||||||
/// Pairing result of alpha*beta
|
/// Pairing result of alpha*beta
|
||||||
alpha_g1_beta_g2: E::Fqk,
|
alpha_g1_beta_g2: E::Fqk,
|
||||||
/// -gamma in G2
|
/// -gamma in G2
|
||||||
neg_gamma_g2: <E::G2Affine as CurveAffine>::Prepared,
|
neg_gamma_g2: <E::G2Affine as PairingCurveAffine>::Prepared,
|
||||||
/// -delta in G2
|
/// -delta in G2
|
||||||
neg_delta_g2: <E::G2Affine as CurveAffine>::Prepared,
|
neg_delta_g2: <E::G2Affine as PairingCurveAffine>::Prepared,
|
||||||
/// Copy of IC from `VerifiyingKey`.
|
/// Copy of IC from `VerifiyingKey`.
|
||||||
ic: Vec<E::G1Affine>
|
ic: Vec<E::G1Affine>
|
||||||
}
|
}
|
||||||
@ -486,8 +486,8 @@ mod test_with_bls12_381 {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use {Circuit, SynthesisError, ConstraintSystem};
|
use {Circuit, SynthesisError, ConstraintSystem};
|
||||||
|
|
||||||
|
use ff::Field;
|
||||||
use rand::{Rand, thread_rng};
|
use rand::{Rand, thread_rng};
|
||||||
use pairing::{Field};
|
|
||||||
use pairing::bls12_381::{Bls12, Fr};
|
use pairing::bls12_381::{Bls12, Fr};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -4,13 +4,9 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
|
|
||||||
use pairing::{
|
use ff::{Field, PrimeField};
|
||||||
Engine,
|
use group::{CurveAffine, CurveProjective};
|
||||||
PrimeField,
|
use pairing::Engine;
|
||||||
Field,
|
|
||||||
CurveProjective,
|
|
||||||
CurveAffine
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
ParameterSource,
|
ParameterSource,
|
||||||
|
@ -1,16 +1,8 @@
|
|||||||
use pairing::{
|
use ff::{
|
||||||
Engine,
|
Field, LegendreSymbol, PrimeField, PrimeFieldDecodingError,
|
||||||
PrimeField,
|
PrimeFieldRepr, ScalarEngine, SqrtField};
|
||||||
PrimeFieldRepr,
|
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError};
|
||||||
Field,
|
use pairing::{Engine, PairingCurveAffine};
|
||||||
SqrtField,
|
|
||||||
LegendreSymbol,
|
|
||||||
CurveProjective,
|
|
||||||
CurveAffine,
|
|
||||||
PrimeFieldDecodingError,
|
|
||||||
GroupDecodingError,
|
|
||||||
EncodedPoint
|
|
||||||
};
|
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -263,8 +255,11 @@ impl PrimeField for Fr {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DummyEngine;
|
pub struct DummyEngine;
|
||||||
|
|
||||||
impl Engine for DummyEngine {
|
impl ScalarEngine for DummyEngine {
|
||||||
type Fr = Fr;
|
type Fr = Fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Engine for DummyEngine {
|
||||||
type G1 = Fr;
|
type G1 = Fr;
|
||||||
type G1Affine = Fr;
|
type G1Affine = Fr;
|
||||||
type G2 = Fr;
|
type G2 = Fr;
|
||||||
@ -277,8 +272,8 @@ impl Engine for DummyEngine {
|
|||||||
|
|
||||||
fn miller_loop<'a, I>(i: I) -> Self::Fqk
|
fn miller_loop<'a, I>(i: I) -> Self::Fqk
|
||||||
where I: IntoIterator<Item=&'a (
|
where I: IntoIterator<Item=&'a (
|
||||||
&'a <Self::G1Affine as CurveAffine>::Prepared,
|
&'a <Self::G1Affine as PairingCurveAffine>::Prepared,
|
||||||
&'a <Self::G2Affine as CurveAffine>::Prepared
|
&'a <Self::G2Affine as PairingCurveAffine>::Prepared
|
||||||
)>
|
)>
|
||||||
{
|
{
|
||||||
let mut acc = <Fr as Field>::zero();
|
let mut acc = <Fr as Field>::zero();
|
||||||
@ -401,11 +396,8 @@ impl EncodedPoint for FakePoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CurveAffine for Fr {
|
impl CurveAffine for Fr {
|
||||||
type Pair = Fr;
|
|
||||||
type PairingResult = Fr;
|
|
||||||
type Compressed = FakePoint;
|
type Compressed = FakePoint;
|
||||||
type Uncompressed = FakePoint;
|
type Uncompressed = FakePoint;
|
||||||
type Prepared = Fr;
|
|
||||||
type Projective = Fr;
|
type Projective = Fr;
|
||||||
type Base = Fr;
|
type Base = Fr;
|
||||||
type Scalar = Fr;
|
type Scalar = Fr;
|
||||||
@ -437,6 +429,16 @@ impl CurveAffine for Fr {
|
|||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn into_projective(&self) -> Self::Projective {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PairingCurveAffine for Fr {
|
||||||
|
type Prepared = Fr;
|
||||||
|
type Pair = Fr;
|
||||||
|
type PairingResult = Fr;
|
||||||
|
|
||||||
fn prepare(&self) -> Self::Prepared {
|
fn prepare(&self) -> Self::Prepared {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
@ -444,8 +446,4 @@ impl CurveAffine for Fr {
|
|||||||
fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult {
|
fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult {
|
||||||
self.mul(*other)
|
self.mul(*other)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_projective(&self) -> Self::Projective {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
use pairing::{
|
use ff::{Field, PrimeField};
|
||||||
Engine,
|
use pairing::Engine;
|
||||||
Field,
|
|
||||||
PrimeField
|
|
||||||
};
|
|
||||||
|
|
||||||
mod dummy_engine;
|
mod dummy_engine;
|
||||||
use self::dummy_engine::*;
|
use self::dummy_engine::*;
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
use pairing::{
|
use ff::PrimeField;
|
||||||
Engine,
|
use group::{CurveAffine, CurveProjective};
|
||||||
CurveProjective,
|
use pairing::{Engine, PairingCurveAffine};
|
||||||
CurveAffine,
|
|
||||||
PrimeField
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Proof,
|
Proof,
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
extern crate ff;
|
||||||
|
extern crate group;
|
||||||
|
#[cfg(feature = "pairing")]
|
||||||
extern crate pairing;
|
extern crate pairing;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate num_cpus;
|
extern crate num_cpus;
|
||||||
@ -10,9 +13,10 @@ extern crate byteorder;
|
|||||||
pub mod multicore;
|
pub mod multicore;
|
||||||
mod multiexp;
|
mod multiexp;
|
||||||
pub mod domain;
|
pub mod domain;
|
||||||
|
#[cfg(feature = "groth16")]
|
||||||
pub mod groth16;
|
pub mod groth16;
|
||||||
|
|
||||||
use pairing::{Engine, Field};
|
use ff::{Field, ScalarEngine};
|
||||||
|
|
||||||
use std::ops::{Add, Sub};
|
use std::ops::{Add, Sub};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -24,7 +28,7 @@ use std::marker::PhantomData;
|
|||||||
/// rank-1 quadratic constraint systems. The `Circuit` trait represents a
|
/// rank-1 quadratic constraint systems. The `Circuit` trait represents a
|
||||||
/// circuit that can be synthesized. The `synthesize` method is called during
|
/// circuit that can be synthesized. The `synthesize` method is called during
|
||||||
/// CRS generation and during proving.
|
/// CRS generation and during proving.
|
||||||
pub trait Circuit<E: Engine> {
|
pub trait Circuit<E: ScalarEngine> {
|
||||||
/// Synthesize the circuit into a rank-1 quadratic constraint system
|
/// Synthesize the circuit into a rank-1 quadratic constraint system
|
||||||
fn synthesize<CS: ConstraintSystem<E>>(
|
fn synthesize<CS: ConstraintSystem<E>>(
|
||||||
self,
|
self,
|
||||||
@ -61,21 +65,21 @@ pub enum Index {
|
|||||||
/// This represents a linear combination of some variables, with coefficients
|
/// This represents a linear combination of some variables, with coefficients
|
||||||
/// in the scalar field of a pairing-friendly elliptic curve group.
|
/// in the scalar field of a pairing-friendly elliptic curve group.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct LinearCombination<E: Engine>(Vec<(Variable, E::Fr)>);
|
pub struct LinearCombination<E: ScalarEngine>(Vec<(Variable, E::Fr)>);
|
||||||
|
|
||||||
impl<E: Engine> AsRef<[(Variable, E::Fr)]> for LinearCombination<E> {
|
impl<E: ScalarEngine> AsRef<[(Variable, E::Fr)]> for LinearCombination<E> {
|
||||||
fn as_ref(&self) -> &[(Variable, E::Fr)] {
|
fn as_ref(&self) -> &[(Variable, E::Fr)] {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine> LinearCombination<E> {
|
impl<E: ScalarEngine> LinearCombination<E> {
|
||||||
pub fn zero() -> LinearCombination<E> {
|
pub fn zero() -> LinearCombination<E> {
|
||||||
LinearCombination(vec![])
|
LinearCombination(vec![])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine> Add<(E::Fr, Variable)> for LinearCombination<E> {
|
impl<E: ScalarEngine> Add<(E::Fr, Variable)> for LinearCombination<E> {
|
||||||
type Output = LinearCombination<E>;
|
type Output = LinearCombination<E>;
|
||||||
|
|
||||||
fn add(mut self, (coeff, var): (E::Fr, Variable)) -> LinearCombination<E> {
|
fn add(mut self, (coeff, var): (E::Fr, Variable)) -> LinearCombination<E> {
|
||||||
@ -85,7 +89,7 @@ impl<E: Engine> Add<(E::Fr, Variable)> for LinearCombination<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine> Sub<(E::Fr, Variable)> for LinearCombination<E> {
|
impl<E: ScalarEngine> Sub<(E::Fr, Variable)> for LinearCombination<E> {
|
||||||
type Output = LinearCombination<E>;
|
type Output = LinearCombination<E>;
|
||||||
|
|
||||||
fn sub(self, (mut coeff, var): (E::Fr, Variable)) -> LinearCombination<E> {
|
fn sub(self, (mut coeff, var): (E::Fr, Variable)) -> LinearCombination<E> {
|
||||||
@ -95,7 +99,7 @@ impl<E: Engine> Sub<(E::Fr, Variable)> for LinearCombination<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine> Add<Variable> for LinearCombination<E> {
|
impl<E: ScalarEngine> Add<Variable> for LinearCombination<E> {
|
||||||
type Output = LinearCombination<E>;
|
type Output = LinearCombination<E>;
|
||||||
|
|
||||||
fn add(self, other: Variable) -> LinearCombination<E> {
|
fn add(self, other: Variable) -> LinearCombination<E> {
|
||||||
@ -103,7 +107,7 @@ impl<E: Engine> Add<Variable> for LinearCombination<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine> Sub<Variable> for LinearCombination<E> {
|
impl<E: ScalarEngine> Sub<Variable> for LinearCombination<E> {
|
||||||
type Output = LinearCombination<E>;
|
type Output = LinearCombination<E>;
|
||||||
|
|
||||||
fn sub(self, other: Variable) -> LinearCombination<E> {
|
fn sub(self, other: Variable) -> LinearCombination<E> {
|
||||||
@ -111,7 +115,7 @@ impl<E: Engine> Sub<Variable> for LinearCombination<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E: Engine> Add<&'a LinearCombination<E>> for LinearCombination<E> {
|
impl<'a, E: ScalarEngine> Add<&'a LinearCombination<E>> for LinearCombination<E> {
|
||||||
type Output = LinearCombination<E>;
|
type Output = LinearCombination<E>;
|
||||||
|
|
||||||
fn add(mut self, other: &'a LinearCombination<E>) -> LinearCombination<E> {
|
fn add(mut self, other: &'a LinearCombination<E>) -> LinearCombination<E> {
|
||||||
@ -123,7 +127,7 @@ impl<'a, E: Engine> Add<&'a LinearCombination<E>> for LinearCombination<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E: Engine> Sub<&'a LinearCombination<E>> for LinearCombination<E> {
|
impl<'a, E: ScalarEngine> Sub<&'a LinearCombination<E>> for LinearCombination<E> {
|
||||||
type Output = LinearCombination<E>;
|
type Output = LinearCombination<E>;
|
||||||
|
|
||||||
fn sub(mut self, other: &'a LinearCombination<E>) -> LinearCombination<E> {
|
fn sub(mut self, other: &'a LinearCombination<E>) -> LinearCombination<E> {
|
||||||
@ -135,7 +139,7 @@ impl<'a, E: Engine> Sub<&'a LinearCombination<E>> for LinearCombination<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E: Engine> Add<(E::Fr, &'a LinearCombination<E>)> for LinearCombination<E> {
|
impl<'a, E: ScalarEngine> Add<(E::Fr, &'a LinearCombination<E>)> for LinearCombination<E> {
|
||||||
type Output = LinearCombination<E>;
|
type Output = LinearCombination<E>;
|
||||||
|
|
||||||
fn add(mut self, (coeff, other): (E::Fr, &'a LinearCombination<E>)) -> LinearCombination<E> {
|
fn add(mut self, (coeff, other): (E::Fr, &'a LinearCombination<E>)) -> LinearCombination<E> {
|
||||||
@ -149,7 +153,7 @@ impl<'a, E: Engine> Add<(E::Fr, &'a LinearCombination<E>)> for LinearCombination
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E: Engine> Sub<(E::Fr, &'a LinearCombination<E>)> for LinearCombination<E> {
|
impl<'a, E: ScalarEngine> Sub<(E::Fr, &'a LinearCombination<E>)> for LinearCombination<E> {
|
||||||
type Output = LinearCombination<E>;
|
type Output = LinearCombination<E>;
|
||||||
|
|
||||||
fn sub(mut self, (coeff, other): (E::Fr, &'a LinearCombination<E>)) -> LinearCombination<E> {
|
fn sub(mut self, (coeff, other): (E::Fr, &'a LinearCombination<E>)) -> LinearCombination<E> {
|
||||||
@ -219,7 +223,7 @@ impl fmt::Display for SynthesisError {
|
|||||||
|
|
||||||
/// Represents a constraint system which can have new variables
|
/// Represents a constraint system which can have new variables
|
||||||
/// allocated and constrains between them formed.
|
/// allocated and constrains between them formed.
|
||||||
pub trait ConstraintSystem<E: Engine>: Sized {
|
pub trait ConstraintSystem<E: ScalarEngine>: Sized {
|
||||||
/// Represents the type of the "root" of this constraint system
|
/// Represents the type of the "root" of this constraint system
|
||||||
/// so that nested namespaces can minimize indirection.
|
/// so that nested namespaces can minimize indirection.
|
||||||
type Root: ConstraintSystem<E>;
|
type Root: ConstraintSystem<E>;
|
||||||
@ -291,9 +295,9 @@ pub trait ConstraintSystem<E: Engine>: Sized {
|
|||||||
|
|
||||||
/// This is a "namespaced" constraint system which borrows a constraint system (pushing
|
/// This is a "namespaced" constraint system which borrows a constraint system (pushing
|
||||||
/// a namespace context) and, when dropped, pops out of the namespace context.
|
/// a namespace context) and, when dropped, pops out of the namespace context.
|
||||||
pub struct Namespace<'a, E: Engine, CS: ConstraintSystem<E> + 'a>(&'a mut CS, PhantomData<E>);
|
pub struct Namespace<'a, E: ScalarEngine, CS: ConstraintSystem<E> + 'a>(&'a mut CS, PhantomData<E>);
|
||||||
|
|
||||||
impl<'cs, E: Engine, CS: ConstraintSystem<E>> ConstraintSystem<E> for Namespace<'cs, E, CS> {
|
impl<'cs, E: ScalarEngine, CS: ConstraintSystem<E>> ConstraintSystem<E> for Namespace<'cs, E, CS> {
|
||||||
type Root = CS::Root;
|
type Root = CS::Root;
|
||||||
|
|
||||||
fn one() -> Variable {
|
fn one() -> Variable {
|
||||||
@ -356,7 +360,7 @@ impl<'cs, E: Engine, CS: ConstraintSystem<E>> ConstraintSystem<E> for Namespace<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E: Engine, CS: ConstraintSystem<E>> Drop for Namespace<'a, E, CS> {
|
impl<'a, E: ScalarEngine, CS: ConstraintSystem<E>> Drop for Namespace<'a, E, CS> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.get_root().pop_namespace()
|
self.get_root().pop_namespace()
|
||||||
}
|
}
|
||||||
@ -364,7 +368,7 @@ impl<'a, E: Engine, CS: ConstraintSystem<E>> Drop for Namespace<'a, E, CS> {
|
|||||||
|
|
||||||
/// Convenience implementation of ConstraintSystem<E> for mutable references to
|
/// Convenience implementation of ConstraintSystem<E> for mutable references to
|
||||||
/// constraint systems.
|
/// constraint systems.
|
||||||
impl<'cs, E: Engine, CS: ConstraintSystem<E>> ConstraintSystem<E> for &'cs mut CS {
|
impl<'cs, E: ScalarEngine, CS: ConstraintSystem<E>> ConstraintSystem<E> for &'cs mut CS {
|
||||||
type Root = CS::Root;
|
type Root = CS::Root;
|
||||||
|
|
||||||
fn one() -> Variable {
|
fn one() -> Variable {
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
use pairing::{
|
use ff::{Field, PrimeField, PrimeFieldRepr, ScalarEngine};
|
||||||
CurveAffine,
|
use group::{CurveAffine, CurveProjective};
|
||||||
CurveProjective,
|
|
||||||
Engine,
|
|
||||||
PrimeField,
|
|
||||||
Field,
|
|
||||||
PrimeFieldRepr
|
|
||||||
};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::io;
|
use std::io;
|
||||||
use bit_vec::{self, BitVec};
|
use bit_vec::{self, BitVec};
|
||||||
@ -141,7 +135,7 @@ fn multiexp_inner<Q, D, G, S>(
|
|||||||
pool: &Worker,
|
pool: &Worker,
|
||||||
bases: S,
|
bases: S,
|
||||||
density_map: D,
|
density_map: D,
|
||||||
exponents: Arc<Vec<<<G::Engine as Engine>::Fr as PrimeField>::Repr>>,
|
exponents: Arc<Vec<<<G::Engine as ScalarEngine>::Fr as PrimeField>::Repr>>,
|
||||||
mut skip: u32,
|
mut skip: u32,
|
||||||
c: u32,
|
c: u32,
|
||||||
handle_trivial: bool
|
handle_trivial: bool
|
||||||
@ -167,8 +161,8 @@ fn multiexp_inner<Q, D, G, S>(
|
|||||||
// Create space for the buckets
|
// Create space for the buckets
|
||||||
let mut buckets = vec![<G as CurveAffine>::Projective::zero(); (1 << c) - 1];
|
let mut buckets = vec![<G as CurveAffine>::Projective::zero(); (1 << c) - 1];
|
||||||
|
|
||||||
let zero = <G::Engine as Engine>::Fr::zero().into_repr();
|
let zero = <G::Engine as ScalarEngine>::Fr::zero().into_repr();
|
||||||
let one = <G::Engine as Engine>::Fr::one().into_repr();
|
let one = <G::Engine as ScalarEngine>::Fr::one().into_repr();
|
||||||
|
|
||||||
// Sort the bases into buckets
|
// Sort the bases into buckets
|
||||||
for (&exp, density) in exponents.iter().zip(density_map.as_ref().iter()) {
|
for (&exp, density) in exponents.iter().zip(density_map.as_ref().iter()) {
|
||||||
@ -211,7 +205,7 @@ fn multiexp_inner<Q, D, G, S>(
|
|||||||
|
|
||||||
skip += c;
|
skip += c;
|
||||||
|
|
||||||
if skip >= <G::Engine as Engine>::Fr::NUM_BITS {
|
if skip >= <G::Engine as ScalarEngine>::Fr::NUM_BITS {
|
||||||
// There isn't another region.
|
// There isn't another region.
|
||||||
Box::new(this)
|
Box::new(this)
|
||||||
} else {
|
} else {
|
||||||
@ -238,7 +232,7 @@ pub fn multiexp<Q, D, G, S>(
|
|||||||
pool: &Worker,
|
pool: &Worker,
|
||||||
bases: S,
|
bases: S,
|
||||||
density_map: D,
|
density_map: D,
|
||||||
exponents: Arc<Vec<<<G::Engine as Engine>::Fr as PrimeField>::Repr>>
|
exponents: Arc<Vec<<<G::Engine as ScalarEngine>::Fr as PrimeField>::Repr>>
|
||||||
) -> Box<Future<Item=<G as CurveAffine>::Projective, Error=SynthesisError>>
|
) -> Box<Future<Item=<G as CurveAffine>::Projective, Error=SynthesisError>>
|
||||||
where for<'a> &'a Q: QueryDensity,
|
where for<'a> &'a Q: QueryDensity,
|
||||||
D: Send + Sync + 'static + Clone + AsRef<Q>,
|
D: Send + Sync + 'static + Clone + AsRef<Q>,
|
||||||
@ -261,6 +255,7 @@ pub fn multiexp<Q, D, G, S>(
|
|||||||
multiexp_inner(pool, bases, density_map, exponents, 0, c, true)
|
multiexp_inner(pool, bases, density_map, exponents, 0, c, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "pairing")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_with_bls12() {
|
fn test_with_bls12() {
|
||||||
fn naive_multiexp<G: CurveAffine>(
|
fn naive_multiexp<G: CurveAffine>(
|
||||||
@ -280,12 +275,12 @@ fn test_with_bls12() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
use rand::{self, Rand};
|
use rand::{self, Rand};
|
||||||
use pairing::bls12_381::Bls12;
|
use pairing::{bls12_381::Bls12, Engine};
|
||||||
|
|
||||||
const SAMPLES: usize = 1 << 14;
|
const SAMPLES: usize = 1 << 14;
|
||||||
|
|
||||||
let rng = &mut rand::thread_rng();
|
let rng = &mut rand::thread_rng();
|
||||||
let v = Arc::new((0..SAMPLES).map(|_| <Bls12 as Engine>::Fr::rand(rng).into_repr()).collect::<Vec<_>>());
|
let v = Arc::new((0..SAMPLES).map(|_| <Bls12 as ScalarEngine>::Fr::rand(rng).into_repr()).collect::<Vec<_>>());
|
||||||
let g = Arc::new((0..SAMPLES).map(|_| <Bls12 as Engine>::G1::rand(rng).into_affine()).collect::<Vec<_>>());
|
let g = Arc::new((0..SAMPLES).map(|_| <Bls12 as Engine>::G1::rand(rng).into_affine()).collect::<Vec<_>>());
|
||||||
|
|
||||||
let naive = naive_multiexp(g.clone(), v.clone());
|
let naive = naive_multiexp(g.clone(), v.clone());
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
extern crate bellman;
|
extern crate bellman;
|
||||||
|
extern crate ff;
|
||||||
extern crate pairing;
|
extern crate pairing;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
|
||||||
@ -9,10 +10,8 @@ use rand::{thread_rng, Rng};
|
|||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
// Bring in some tools for using pairing-friendly curves
|
// Bring in some tools for using pairing-friendly curves
|
||||||
use pairing::{
|
use ff::Field;
|
||||||
Engine,
|
use pairing::Engine;
|
||||||
Field
|
|
||||||
};
|
|
||||||
|
|
||||||
// We're going to use the BLS12-381 pairing-friendly elliptic curve.
|
// We're going to use the BLS12-381 pairing-friendly elliptic curve.
|
||||||
use pairing::bls12_381::{
|
use pairing::bls12_381::{
|
||||||
|
3
ff/.gitignore
vendored
Normal file
3
ff/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
target/
|
||||||
|
**/*.rs.bk
|
||||||
|
Cargo.lock
|
18
ff/Cargo.toml
Normal file
18
ff/Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
[package]
|
||||||
|
name = "ff"
|
||||||
|
version = "0.4.0"
|
||||||
|
authors = ["Sean Bowe <ewillbefull@gmail.com>"]
|
||||||
|
description = "Library for building and interfacing with finite fields"
|
||||||
|
documentation = "https://docs.rs/ff/"
|
||||||
|
homepage = "https://github.com/ebfull/ff"
|
||||||
|
license = "MIT/Apache-2.0"
|
||||||
|
repository = "https://github.com/ebfull/ff"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
byteorder = "1"
|
||||||
|
rand = "0.4"
|
||||||
|
ff_derive = { version = "0.3.0", path = "ff_derive", optional = true }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
derive = ["ff_derive"]
|
202
ff/LICENSE-APACHE
Normal file
202
ff/LICENSE-APACHE
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
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.
|
||||||
|
|
21
ff/LICENSE-MIT
Normal file
21
ff/LICENSE-MIT
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2017 Sean Bowe
|
||||||
|
|
||||||
|
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.
|
60
ff/README.md
Normal file
60
ff/README.md
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# ff
|
||||||
|
|
||||||
|
`ff` is a finite field library written in pure Rust, with no `unsafe{}` code.
|
||||||
|
|
||||||
|
## Disclaimers
|
||||||
|
|
||||||
|
* This library does not provide constant-time guarantees.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Add the `ff` crate to your `Cargo.toml`:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[dependencies]
|
||||||
|
ff = "0.4"
|
||||||
|
```
|
||||||
|
|
||||||
|
The `ff` crate contains `Field`, `PrimeField`, `PrimeFieldRepr` and `SqrtField` traits. See the **[documentation](https://docs.rs/ff/0.4.0/ff/)** for more.
|
||||||
|
|
||||||
|
### #![derive(PrimeField)]
|
||||||
|
|
||||||
|
If you need an implementation of a prime field, this library also provides a procedural macro that will expand into an efficient implementation of a prime field when supplied with the modulus. `PrimeFieldGenerator` must be an element of Fp of p-1 order, that is also quadratic nonresidue.
|
||||||
|
|
||||||
|
First, enable the `derive` crate feature:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[dependencies]
|
||||||
|
ff = { version = "0.4", features = ["derive"] }
|
||||||
|
```
|
||||||
|
|
||||||
|
And then use the macro like so:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
extern crate rand;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate ff;
|
||||||
|
|
||||||
|
#[derive(PrimeField)]
|
||||||
|
#[PrimeFieldModulus = "52435875175126190479447740508185965837690552500527637822603658699938581184513"]
|
||||||
|
#[PrimeFieldGenerator = "7"]
|
||||||
|
struct Fp(FpRepr);
|
||||||
|
```
|
||||||
|
|
||||||
|
And that's it! `Fp` now implements `Field` and `PrimeField`. `Fp` will also implement `SqrtField` if supported. The library implements `FpRepr` itself and derives `PrimeFieldRepr` for it.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Licensed under either of
|
||||||
|
|
||||||
|
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
at your option.
|
||||||
|
|
||||||
|
### Contribution
|
||||||
|
|
||||||
|
Unless you explicitly state otherwise, any contribution intentionally
|
||||||
|
submitted for inclusion in the work by you, as defined in the Apache-2.0
|
||||||
|
license, shall be dual licensed as above, without any additional terms or
|
||||||
|
conditions.
|
20
ff/ff_derive/Cargo.toml
Normal file
20
ff/ff_derive/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
[package]
|
||||||
|
name = "ff_derive"
|
||||||
|
version = "0.3.0"
|
||||||
|
authors = ["Sean Bowe <ewillbefull@gmail.com>"]
|
||||||
|
description = "Procedural macro library used to build custom prime field implementations"
|
||||||
|
documentation = "https://docs.rs/ff/"
|
||||||
|
homepage = "https://github.com/ebfull/ff"
|
||||||
|
license = "MIT/Apache-2.0"
|
||||||
|
repository = "https://github.com/ebfull/ff"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
num-bigint = "0.2"
|
||||||
|
num-traits = "0.2"
|
||||||
|
num-integer = "0.1"
|
||||||
|
proc-macro2 = "0.4"
|
||||||
|
quote = "0.6"
|
||||||
|
syn = "0.14"
|
1065
ff/ff_derive/src/lib.rs
Normal file
1065
ff/ff_derive/src/lib.rs
Normal file
File diff suppressed because it is too large
Load Diff
393
ff/src/lib.rs
Normal file
393
ff/src/lib.rs
Normal file
@ -0,0 +1,393 @@
|
|||||||
|
#![allow(unused_imports)]
|
||||||
|
|
||||||
|
extern crate byteorder;
|
||||||
|
extern crate rand;
|
||||||
|
|
||||||
|
#[cfg(feature = "derive")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate ff_derive;
|
||||||
|
|
||||||
|
#[cfg(feature = "derive")]
|
||||||
|
pub use ff_derive::*;
|
||||||
|
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fmt;
|
||||||
|
use std::io::{self, Read, Write};
|
||||||
|
|
||||||
|
/// This trait represents an element of a field.
|
||||||
|
pub trait Field:
|
||||||
|
Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display + 'static + rand::Rand
|
||||||
|
{
|
||||||
|
/// Returns the zero element of the field, the additive identity.
|
||||||
|
fn zero() -> Self;
|
||||||
|
|
||||||
|
/// Returns the one element of the field, the multiplicative identity.
|
||||||
|
fn one() -> Self;
|
||||||
|
|
||||||
|
/// Returns true iff this element is zero.
|
||||||
|
fn is_zero(&self) -> bool;
|
||||||
|
|
||||||
|
/// Squares this element.
|
||||||
|
fn square(&mut self);
|
||||||
|
|
||||||
|
/// Doubles this element.
|
||||||
|
fn double(&mut self);
|
||||||
|
|
||||||
|
/// Negates this element.
|
||||||
|
fn negate(&mut self);
|
||||||
|
|
||||||
|
/// Adds another element to this element.
|
||||||
|
fn add_assign(&mut self, other: &Self);
|
||||||
|
|
||||||
|
/// Subtracts another element from this element.
|
||||||
|
fn sub_assign(&mut self, other: &Self);
|
||||||
|
|
||||||
|
/// Multiplies another element by this element.
|
||||||
|
fn mul_assign(&mut self, other: &Self);
|
||||||
|
|
||||||
|
/// Computes the multiplicative inverse of this element, if nonzero.
|
||||||
|
fn inverse(&self) -> Option<Self>;
|
||||||
|
|
||||||
|
/// Exponentiates this element by a power of the base prime modulus via
|
||||||
|
/// the Frobenius automorphism.
|
||||||
|
fn frobenius_map(&mut self, power: usize);
|
||||||
|
|
||||||
|
/// Exponentiates this element by a number represented with `u64` limbs,
|
||||||
|
/// least significant digit first.
|
||||||
|
fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
|
||||||
|
let mut res = Self::one();
|
||||||
|
|
||||||
|
let mut found_one = false;
|
||||||
|
|
||||||
|
for i in BitIterator::new(exp) {
|
||||||
|
if found_one {
|
||||||
|
res.square();
|
||||||
|
} else {
|
||||||
|
found_one = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if i {
|
||||||
|
res.mul_assign(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This trait represents an element of a field that has a square root operation described for it.
|
||||||
|
pub trait SqrtField: Field {
|
||||||
|
/// Returns the Legendre symbol of the field element.
|
||||||
|
fn legendre(&self) -> LegendreSymbol;
|
||||||
|
|
||||||
|
/// Returns the square root of the field element, if it is
|
||||||
|
/// quadratic residue.
|
||||||
|
fn sqrt(&self) -> Option<Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This trait represents a wrapper around a biginteger which can encode any element of a particular
|
||||||
|
/// prime field. It is a smart wrapper around a sequence of `u64` limbs, least-significant digit
|
||||||
|
/// first.
|
||||||
|
pub trait PrimeFieldRepr:
|
||||||
|
Sized
|
||||||
|
+ Copy
|
||||||
|
+ Clone
|
||||||
|
+ Eq
|
||||||
|
+ Ord
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ Default
|
||||||
|
+ fmt::Debug
|
||||||
|
+ fmt::Display
|
||||||
|
+ 'static
|
||||||
|
+ rand::Rand
|
||||||
|
+ AsRef<[u64]>
|
||||||
|
+ AsMut<[u64]>
|
||||||
|
+ From<u64>
|
||||||
|
{
|
||||||
|
/// Subtract another represetation from this one.
|
||||||
|
fn sub_noborrow(&mut self, other: &Self);
|
||||||
|
|
||||||
|
/// Add another representation to this one.
|
||||||
|
fn add_nocarry(&mut self, other: &Self);
|
||||||
|
|
||||||
|
/// Compute the number of bits needed to encode this number. Always a
|
||||||
|
/// multiple of 64.
|
||||||
|
fn num_bits(&self) -> u32;
|
||||||
|
|
||||||
|
/// Returns true iff this number is zero.
|
||||||
|
fn is_zero(&self) -> bool;
|
||||||
|
|
||||||
|
/// Returns true iff this number is odd.
|
||||||
|
fn is_odd(&self) -> bool;
|
||||||
|
|
||||||
|
/// Returns true iff this number is even.
|
||||||
|
fn is_even(&self) -> bool;
|
||||||
|
|
||||||
|
/// Performs a rightwise bitshift of this number, effectively dividing
|
||||||
|
/// it by 2.
|
||||||
|
fn div2(&mut self);
|
||||||
|
|
||||||
|
/// Performs a rightwise bitshift of this number by some amount.
|
||||||
|
fn shr(&mut self, amt: u32);
|
||||||
|
|
||||||
|
/// Performs a leftwise bitshift of this number, effectively multiplying
|
||||||
|
/// it by 2. Overflow is ignored.
|
||||||
|
fn mul2(&mut self);
|
||||||
|
|
||||||
|
/// Performs a leftwise bitshift of this number by some amount.
|
||||||
|
fn shl(&mut self, amt: u32);
|
||||||
|
|
||||||
|
/// Writes this `PrimeFieldRepr` as a big endian integer.
|
||||||
|
fn write_be<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
||||||
|
use byteorder::{BigEndian, WriteBytesExt};
|
||||||
|
|
||||||
|
for digit in self.as_ref().iter().rev() {
|
||||||
|
writer.write_u64::<BigEndian>(*digit)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads a big endian integer into this representation.
|
||||||
|
fn read_be<R: Read>(&mut self, mut reader: R) -> io::Result<()> {
|
||||||
|
use byteorder::{BigEndian, ReadBytesExt};
|
||||||
|
|
||||||
|
for digit in self.as_mut().iter_mut().rev() {
|
||||||
|
*digit = reader.read_u64::<BigEndian>()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes this `PrimeFieldRepr` as a little endian integer.
|
||||||
|
fn write_le<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
||||||
|
use byteorder::{LittleEndian, WriteBytesExt};
|
||||||
|
|
||||||
|
for digit in self.as_ref().iter() {
|
||||||
|
writer.write_u64::<LittleEndian>(*digit)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads a little endian integer into this representation.
|
||||||
|
fn read_le<R: Read>(&mut self, mut reader: R) -> io::Result<()> {
|
||||||
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
|
|
||||||
|
for digit in self.as_mut().iter_mut() {
|
||||||
|
*digit = reader.read_u64::<LittleEndian>()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum LegendreSymbol {
|
||||||
|
Zero = 0,
|
||||||
|
QuadraticResidue = 1,
|
||||||
|
QuadraticNonResidue = -1,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An error that may occur when trying to interpret a `PrimeFieldRepr` as a
|
||||||
|
/// `PrimeField` element.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum PrimeFieldDecodingError {
|
||||||
|
/// The encoded value is not in the field
|
||||||
|
NotInField(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for PrimeFieldDecodingError {
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
match *self {
|
||||||
|
PrimeFieldDecodingError::NotInField(..) => "not an element of the field",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for PrimeFieldDecodingError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
match *self {
|
||||||
|
PrimeFieldDecodingError::NotInField(ref repr) => {
|
||||||
|
write!(f, "{} is not an element of the field", repr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This represents an element of a prime field.
|
||||||
|
pub trait PrimeField: Field {
|
||||||
|
/// The prime field can be converted back and forth into this biginteger
|
||||||
|
/// representation.
|
||||||
|
type Repr: PrimeFieldRepr + From<Self>;
|
||||||
|
|
||||||
|
/// Interpret a string of numbers as a (congruent) prime field element.
|
||||||
|
/// Does not accept unnecessary leading zeroes or a blank string.
|
||||||
|
fn from_str(s: &str) -> Option<Self> {
|
||||||
|
if s.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if s == "0" {
|
||||||
|
return Some(Self::zero());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut res = Self::zero();
|
||||||
|
|
||||||
|
let ten = Self::from_repr(Self::Repr::from(10)).unwrap();
|
||||||
|
|
||||||
|
let mut first_digit = true;
|
||||||
|
|
||||||
|
for c in s.chars() {
|
||||||
|
match c.to_digit(10) {
|
||||||
|
Some(c) => {
|
||||||
|
if first_digit {
|
||||||
|
if c == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
first_digit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.mul_assign(&ten);
|
||||||
|
res.add_assign(&Self::from_repr(Self::Repr::from(u64::from(c))).unwrap());
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert this prime field element into a biginteger representation.
|
||||||
|
fn from_repr(Self::Repr) -> Result<Self, PrimeFieldDecodingError>;
|
||||||
|
|
||||||
|
/// Convert a biginteger representation into a prime field element, if
|
||||||
|
/// the number is an element of the field.
|
||||||
|
fn into_repr(&self) -> Self::Repr;
|
||||||
|
|
||||||
|
/// Returns the field characteristic; the modulus.
|
||||||
|
fn char() -> Self::Repr;
|
||||||
|
|
||||||
|
/// How many bits are needed to represent an element of this field.
|
||||||
|
const NUM_BITS: u32;
|
||||||
|
|
||||||
|
/// How many bits of information can be reliably stored in the field element.
|
||||||
|
const CAPACITY: u32;
|
||||||
|
|
||||||
|
/// Returns the multiplicative generator of `char()` - 1 order. This element
|
||||||
|
/// must also be quadratic nonresidue.
|
||||||
|
fn multiplicative_generator() -> Self;
|
||||||
|
|
||||||
|
/// 2^s * t = `char()` - 1 with t odd.
|
||||||
|
const S: u32;
|
||||||
|
|
||||||
|
/// Returns the 2^s root of unity computed by exponentiating the `multiplicative_generator()`
|
||||||
|
/// by t.
|
||||||
|
fn root_of_unity() -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An "engine" is a collection of types (fields, elliptic curve groups, etc.)
|
||||||
|
/// with well-defined relationships. Specific relationships (for example, a
|
||||||
|
/// pairing-friendly curve) can be defined in a subtrait.
|
||||||
|
pub trait ScalarEngine: Sized + 'static + Clone {
|
||||||
|
/// This is the scalar field of the engine's groups.
|
||||||
|
type Fr: PrimeField + SqrtField;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct BitIterator<E> {
|
||||||
|
t: E,
|
||||||
|
n: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: AsRef<[u64]>> BitIterator<E> {
|
||||||
|
pub fn new(t: E) -> Self {
|
||||||
|
let n = t.as_ref().len() * 64;
|
||||||
|
|
||||||
|
BitIterator { t, n }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: AsRef<[u64]>> Iterator for BitIterator<E> {
|
||||||
|
type Item = bool;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<bool> {
|
||||||
|
if self.n == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
self.n -= 1;
|
||||||
|
let part = self.n / 64;
|
||||||
|
let bit = self.n - (64 * part);
|
||||||
|
|
||||||
|
Some(self.t.as_ref()[part] & (1 << bit) > 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bit_iterator() {
|
||||||
|
let mut a = BitIterator::new([0xa953d79b83f6ab59, 0x6dea2059e200bd39]);
|
||||||
|
let expected = "01101101111010100010000001011001111000100000000010111101001110011010100101010011110101111001101110000011111101101010101101011001";
|
||||||
|
|
||||||
|
for e in expected.chars() {
|
||||||
|
assert!(a.next().unwrap() == (e == '1'));
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(a.next().is_none());
|
||||||
|
|
||||||
|
let expected = "1010010101111110101010000101101011101000011101110101001000011001100100100011011010001011011011010001011011101100110100111011010010110001000011110100110001100110011101101000101100011100100100100100001010011101010111110011101011000011101000111011011101011001";
|
||||||
|
|
||||||
|
let mut a = BitIterator::new([
|
||||||
|
0x429d5f3ac3a3b759,
|
||||||
|
0xb10f4c66768b1c92,
|
||||||
|
0x92368b6d16ecd3b4,
|
||||||
|
0xa57ea85ae8775219,
|
||||||
|
]);
|
||||||
|
|
||||||
|
for e in expected.chars() {
|
||||||
|
assert!(a.next().unwrap() == (e == '1'));
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(a.next().is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub use self::arith_impl::*;
|
||||||
|
|
||||||
|
mod arith_impl {
|
||||||
|
/// Calculate a - b - borrow, returning the result and modifying
|
||||||
|
/// the borrow value.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn sbb(a: u64, b: u64, borrow: &mut u64) -> u64 {
|
||||||
|
let tmp = (1u128 << 64) + u128::from(a) - u128::from(b) - u128::from(*borrow);
|
||||||
|
|
||||||
|
*borrow = if tmp >> 64 == 0 { 1 } else { 0 };
|
||||||
|
|
||||||
|
tmp as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculate a + b + carry, returning the sum and modifying the
|
||||||
|
/// carry value.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn adc(a: u64, b: u64, carry: &mut u64) -> u64 {
|
||||||
|
let tmp = u128::from(a) + u128::from(b) + u128::from(*carry);
|
||||||
|
|
||||||
|
*carry = (tmp >> 64) as u64;
|
||||||
|
|
||||||
|
tmp as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculate a + (b * c) + carry, returning the least significant digit
|
||||||
|
/// and setting carry to the most significant digit.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn mac_with_carry(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
|
||||||
|
let tmp = (u128::from(a)) + u128::from(b) * u128::from(c) + u128::from(*carry);
|
||||||
|
|
||||||
|
*carry = (tmp >> 64) as u64;
|
||||||
|
|
||||||
|
tmp as u64
|
||||||
|
}
|
||||||
|
}
|
3
group/.gitignore
vendored
Normal file
3
group/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/target
|
||||||
|
**/*.rs.bk
|
||||||
|
Cargo.lock
|
14
group/COPYRIGHT
Normal file
14
group/COPYRIGHT
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
Copyrights in the "group" library are retained by their contributors. No
|
||||||
|
copyright assignment is required to contribute to the "group" library.
|
||||||
|
|
||||||
|
The "group" library is licensed under either of
|
||||||
|
|
||||||
|
* Apache License, Version 2.0, (see ./LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
* MIT license (see ./LICENSE-MIT or http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
at your option.
|
||||||
|
|
||||||
|
Unless you explicitly state otherwise, any contribution intentionally
|
||||||
|
submitted for inclusion in the work by you, as defined in the Apache-2.0
|
||||||
|
license, shall be dual licensed as above, without any additional terms or
|
||||||
|
conditions.
|
17
group/Cargo.toml
Normal file
17
group/Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
[package]
|
||||||
|
name = "group"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = [
|
||||||
|
"Sean Bowe <ewillbefull@gmail.com>",
|
||||||
|
"Jack Grigg <jack@z.cash>",
|
||||||
|
]
|
||||||
|
license = "MIT/Apache-2.0"
|
||||||
|
|
||||||
|
description = "Elliptic curve group traits and utilities"
|
||||||
|
documentation = "https://docs.rs/group/"
|
||||||
|
homepage = "https://github.com/ebfull/group"
|
||||||
|
repository = "https://github.com/ebfull/group"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ff = { path = "../ff" }
|
||||||
|
rand = "0.4"
|
201
group/LICENSE-APACHE
Normal file
201
group/LICENSE-APACHE
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
23
group/LICENSE-MIT
Normal file
23
group/LICENSE-MIT
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
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.
|
17
group/README.md
Normal file
17
group/README.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# group [![Crates.io](https://img.shields.io/crates/v/group.svg)](https://crates.io/crates/group) #
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Licensed under either of
|
||||||
|
|
||||||
|
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
at your option.
|
||||||
|
|
||||||
|
### Contribution
|
||||||
|
|
||||||
|
Unless you explicitly state otherwise, any contribution intentionally
|
||||||
|
submitted for inclusion in the work by you, as defined in the Apache-2.0
|
||||||
|
license, shall be dual licensed as above, without any additional terms or
|
||||||
|
conditions.
|
196
group/src/lib.rs
Normal file
196
group/src/lib.rs
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
extern crate ff;
|
||||||
|
extern crate rand;
|
||||||
|
|
||||||
|
use ff::{PrimeField, PrimeFieldDecodingError, ScalarEngine, SqrtField};
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
pub mod tests;
|
||||||
|
|
||||||
|
mod wnaf;
|
||||||
|
pub use self::wnaf::Wnaf;
|
||||||
|
|
||||||
|
/// Projective representation of an elliptic curve point guaranteed to be
|
||||||
|
/// in the correct prime order subgroup.
|
||||||
|
pub trait CurveProjective:
|
||||||
|
PartialEq
|
||||||
|
+ Eq
|
||||||
|
+ Sized
|
||||||
|
+ Copy
|
||||||
|
+ Clone
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ fmt::Debug
|
||||||
|
+ fmt::Display
|
||||||
|
+ rand::Rand
|
||||||
|
+ 'static
|
||||||
|
{
|
||||||
|
type Engine: ScalarEngine<Fr = Self::Scalar>;
|
||||||
|
type Scalar: PrimeField + SqrtField;
|
||||||
|
type Base: SqrtField;
|
||||||
|
type Affine: CurveAffine<Projective = Self, Scalar = Self::Scalar>;
|
||||||
|
|
||||||
|
/// Returns the additive identity.
|
||||||
|
fn zero() -> Self;
|
||||||
|
|
||||||
|
/// Returns a fixed generator of unknown exponent.
|
||||||
|
fn one() -> Self;
|
||||||
|
|
||||||
|
/// Determines if this point is the point at infinity.
|
||||||
|
fn is_zero(&self) -> bool;
|
||||||
|
|
||||||
|
/// Normalizes a slice of projective elements so that
|
||||||
|
/// conversion to affine is cheap.
|
||||||
|
fn batch_normalization(v: &mut [Self]);
|
||||||
|
|
||||||
|
/// Checks if the point is already "normalized" so that
|
||||||
|
/// cheap affine conversion is possible.
|
||||||
|
fn is_normalized(&self) -> bool;
|
||||||
|
|
||||||
|
/// Doubles this element.
|
||||||
|
fn double(&mut self);
|
||||||
|
|
||||||
|
/// Adds another element to this element.
|
||||||
|
fn add_assign(&mut self, other: &Self);
|
||||||
|
|
||||||
|
/// Subtracts another element from this element.
|
||||||
|
fn sub_assign(&mut self, other: &Self) {
|
||||||
|
let mut tmp = *other;
|
||||||
|
tmp.negate();
|
||||||
|
self.add_assign(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds an affine element to this element.
|
||||||
|
fn add_assign_mixed(&mut self, other: &Self::Affine);
|
||||||
|
|
||||||
|
/// Negates this element.
|
||||||
|
fn negate(&mut self);
|
||||||
|
|
||||||
|
/// Performs scalar multiplication of this element.
|
||||||
|
fn mul_assign<S: Into<<Self::Scalar as PrimeField>::Repr>>(&mut self, other: S);
|
||||||
|
|
||||||
|
/// Converts this element into its affine representation.
|
||||||
|
fn into_affine(&self) -> Self::Affine;
|
||||||
|
|
||||||
|
/// Recommends a wNAF window table size given a scalar. Always returns a number
|
||||||
|
/// between 2 and 22, inclusive.
|
||||||
|
fn recommended_wnaf_for_scalar(scalar: <Self::Scalar as PrimeField>::Repr) -> usize;
|
||||||
|
|
||||||
|
/// Recommends a wNAF window size given the number of scalars you intend to multiply
|
||||||
|
/// a base by. Always returns a number between 2 and 22, inclusive.
|
||||||
|
fn recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Affine representation of an elliptic curve point guaranteed to be
|
||||||
|
/// in the correct prime order subgroup.
|
||||||
|
pub trait CurveAffine:
|
||||||
|
Copy + Clone + Sized + Send + Sync + fmt::Debug + fmt::Display + PartialEq + Eq + 'static
|
||||||
|
{
|
||||||
|
type Engine: ScalarEngine<Fr = Self::Scalar>;
|
||||||
|
type Scalar: PrimeField + SqrtField;
|
||||||
|
type Base: SqrtField;
|
||||||
|
type Projective: CurveProjective<Affine = Self, Scalar = Self::Scalar>;
|
||||||
|
type Uncompressed: EncodedPoint<Affine = Self>;
|
||||||
|
type Compressed: EncodedPoint<Affine = Self>;
|
||||||
|
|
||||||
|
/// Returns the additive identity.
|
||||||
|
fn zero() -> Self;
|
||||||
|
|
||||||
|
/// Returns a fixed generator of unknown exponent.
|
||||||
|
fn one() -> Self;
|
||||||
|
|
||||||
|
/// Determines if this point represents the point at infinity; the
|
||||||
|
/// additive identity.
|
||||||
|
fn is_zero(&self) -> bool;
|
||||||
|
|
||||||
|
/// Negates this element.
|
||||||
|
fn negate(&mut self);
|
||||||
|
|
||||||
|
/// Performs scalar multiplication of this element with mixed addition.
|
||||||
|
fn mul<S: Into<<Self::Scalar as PrimeField>::Repr>>(&self, other: S) -> Self::Projective;
|
||||||
|
|
||||||
|
/// Converts this element into its affine representation.
|
||||||
|
fn into_projective(&self) -> Self::Projective;
|
||||||
|
|
||||||
|
/// Converts this element into its compressed encoding, so long as it's not
|
||||||
|
/// the point at infinity.
|
||||||
|
fn into_compressed(&self) -> Self::Compressed {
|
||||||
|
<Self::Compressed as EncodedPoint>::from_affine(*self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts this element into its uncompressed encoding, so long as it's not
|
||||||
|
/// the point at infinity.
|
||||||
|
fn into_uncompressed(&self) -> Self::Uncompressed {
|
||||||
|
<Self::Uncompressed as EncodedPoint>::from_affine(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An encoded elliptic curve point, which should essentially wrap a `[u8; N]`.
|
||||||
|
pub trait EncodedPoint:
|
||||||
|
Sized + Send + Sync + AsRef<[u8]> + AsMut<[u8]> + Clone + Copy + 'static
|
||||||
|
{
|
||||||
|
type Affine: CurveAffine;
|
||||||
|
|
||||||
|
/// Creates an empty representation.
|
||||||
|
fn empty() -> Self;
|
||||||
|
|
||||||
|
/// Returns the number of bytes consumed by this representation.
|
||||||
|
fn size() -> usize;
|
||||||
|
|
||||||
|
/// Converts an `EncodedPoint` into a `CurveAffine` element,
|
||||||
|
/// if the encoding represents a valid element.
|
||||||
|
fn into_affine(&self) -> Result<Self::Affine, GroupDecodingError>;
|
||||||
|
|
||||||
|
/// Converts an `EncodedPoint` into a `CurveAffine` element,
|
||||||
|
/// without guaranteeing that the encoding represents a valid
|
||||||
|
/// element. This is useful when the caller knows the encoding is
|
||||||
|
/// valid already.
|
||||||
|
///
|
||||||
|
/// If the encoding is invalid, this can break API invariants,
|
||||||
|
/// so caution is strongly encouraged.
|
||||||
|
fn into_affine_unchecked(&self) -> Result<Self::Affine, GroupDecodingError>;
|
||||||
|
|
||||||
|
/// Creates an `EncodedPoint` from an affine point, as long as the
|
||||||
|
/// point is not the point at infinity.
|
||||||
|
fn from_affine(affine: Self::Affine) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An error that may occur when trying to decode an `EncodedPoint`.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum GroupDecodingError {
|
||||||
|
/// The coordinate(s) do not lie on the curve.
|
||||||
|
NotOnCurve,
|
||||||
|
/// The element is not part of the r-order subgroup.
|
||||||
|
NotInSubgroup,
|
||||||
|
/// One of the coordinates could not be decoded
|
||||||
|
CoordinateDecodingError(&'static str, PrimeFieldDecodingError),
|
||||||
|
/// The compression mode of the encoded element was not as expected
|
||||||
|
UnexpectedCompressionMode,
|
||||||
|
/// The encoding contained bits that should not have been set
|
||||||
|
UnexpectedInformation,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for GroupDecodingError {
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
match *self {
|
||||||
|
GroupDecodingError::NotOnCurve => "coordinate(s) do not lie on the curve",
|
||||||
|
GroupDecodingError::NotInSubgroup => "the element is not part of an r-order subgroup",
|
||||||
|
GroupDecodingError::CoordinateDecodingError(..) => "coordinate(s) could not be decoded",
|
||||||
|
GroupDecodingError::UnexpectedCompressionMode => {
|
||||||
|
"encoding has unexpected compression mode"
|
||||||
|
}
|
||||||
|
GroupDecodingError::UnexpectedInformation => "encoding has unexpected information",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for GroupDecodingError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
match *self {
|
||||||
|
GroupDecodingError::CoordinateDecodingError(description, ref err) => {
|
||||||
|
write!(f, "{} decoding error: {}", description, err)
|
||||||
|
}
|
||||||
|
_ => write!(f, "{}", self.description()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
use rand::{Rand, Rng, SeedableRng, XorShiftRng};
|
use rand::{Rand, Rng, SeedableRng, XorShiftRng};
|
||||||
|
|
||||||
use {CurveAffine, CurveProjective, EncodedPoint, Field};
|
use {CurveAffine, CurveProjective, EncodedPoint};
|
||||||
|
|
||||||
pub fn curve_tests<G: CurveProjective>() {
|
pub fn curve_tests<G: CurveProjective>() {
|
||||||
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||||
@ -47,8 +47,7 @@ pub fn curve_tests<G: CurveProjective>() {
|
|||||||
{
|
{
|
||||||
let a = G::rand(&mut rng);
|
let a = G::rand(&mut rng);
|
||||||
let b = a.into_affine().into_projective();
|
let b = a.into_affine().into_projective();
|
||||||
let c = a
|
let c = a.into_affine()
|
||||||
.into_affine()
|
|
||||||
.into_projective()
|
.into_projective()
|
||||||
.into_affine()
|
.into_affine()
|
||||||
.into_projective();
|
.into_projective();
|
||||||
@ -66,8 +65,9 @@ pub fn curve_tests<G: CurveProjective>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn random_wnaf_tests<G: CurveProjective>() {
|
fn random_wnaf_tests<G: CurveProjective>() {
|
||||||
|
use ff::PrimeField;
|
||||||
|
|
||||||
use wnaf::*;
|
use wnaf::*;
|
||||||
use PrimeField;
|
|
||||||
|
|
||||||
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||||
|
|
||||||
@ -179,6 +179,8 @@ fn random_wnaf_tests<G: CurveProjective>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn random_negation_tests<G: CurveProjective>() {
|
fn random_negation_tests<G: CurveProjective>() {
|
||||||
|
use ff::Field;
|
||||||
|
|
||||||
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||||
|
|
||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
@ -373,8 +375,7 @@ fn random_transformation_tests<G: CurveProjective>() {
|
|||||||
v[s] = v[s].into_affine().into_projective();
|
v[s] = v[s].into_affine().into_projective();
|
||||||
}
|
}
|
||||||
|
|
||||||
let expected_v = v
|
let expected_v = v.iter()
|
||||||
.iter()
|
|
||||||
.map(|v| v.into_affine().into_projective())
|
.map(|v| v.into_affine().into_projective())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
G::batch_normalization(&mut v);
|
G::batch_normalization(&mut v);
|
@ -1,4 +1,6 @@
|
|||||||
use super::{CurveProjective, PrimeField, PrimeFieldRepr};
|
use ff::{PrimeField, PrimeFieldRepr};
|
||||||
|
|
||||||
|
use super::CurveProjective;
|
||||||
|
|
||||||
/// Replaces the contents of `table` with a w-NAF window table for the given window size.
|
/// Replaces the contents of `table` with a w-NAF window table for the given window size.
|
||||||
pub(crate) fn wnaf_table<G: CurveProjective>(table: &mut Vec<G>, mut base: G, window: usize) {
|
pub(crate) fn wnaf_table<G: CurveProjective>(table: &mut Vec<G>, mut base: G, window: usize) {
|
@ -15,6 +15,7 @@ crate-type = ["staticlib"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bellman = { path = "../bellman" }
|
bellman = { path = "../bellman" }
|
||||||
|
ff = { path = "../ff" }
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
pairing = { path = "../pairing" }
|
pairing = { path = "../pairing" }
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
extern crate bellman;
|
extern crate bellman;
|
||||||
extern crate blake2_rfc;
|
extern crate blake2_rfc;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
extern crate ff;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate pairing;
|
extern crate pairing;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
@ -13,10 +14,8 @@ mod hashreader;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
use pairing::{
|
use ff::{BitIterator, PrimeField, PrimeFieldRepr};
|
||||||
bls12_381::{Bls12, Fr, FrRepr},
|
use pairing::bls12_381::{Bls12, Fr, FrRepr};
|
||||||
BitIterator, PrimeField, PrimeFieldRepr,
|
|
||||||
};
|
|
||||||
|
|
||||||
use sapling_crypto::{
|
use sapling_crypto::{
|
||||||
circuit::multipack,
|
circuit::multipack,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
use ff::{PrimeField, PrimeFieldRepr};
|
||||||
use pairing::bls12_381::Bls12;
|
use pairing::bls12_381::Bls12;
|
||||||
use pairing::{PrimeField, PrimeFieldRepr};
|
|
||||||
use rand::{OsRng, Rng};
|
use rand::{OsRng, Rng};
|
||||||
use sapling_crypto::jubjub::{edwards, JubjubBls12};
|
use sapling_crypto::jubjub::{edwards, JubjubBls12};
|
||||||
use sapling_crypto::primitives::{Diversifier, ViewingKey};
|
use sapling_crypto::primitives::{Diversifier, ViewingKey};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use pairing::{bls12_381::Bls12, PrimeField, PrimeFieldRepr};
|
use ff::{PrimeField, PrimeFieldRepr};
|
||||||
|
use pairing::bls12_381::Bls12;
|
||||||
use sapling_crypto::{
|
use sapling_crypto::{
|
||||||
jubjub::{fs::FsRepr, FixedGenerators, JubjubEngine, JubjubParams},
|
jubjub::{fs::FsRepr, FixedGenerators, JubjubEngine, JubjubParams},
|
||||||
primitives::{Diversifier, ProofGenerationKey},
|
primitives::{Diversifier, ProofGenerationKey},
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use pairing::{bls12_381::Bls12, PrimeField, PrimeFieldRepr};
|
use ff::{PrimeField, PrimeFieldRepr};
|
||||||
|
use pairing::bls12_381::Bls12;
|
||||||
use sapling_crypto::{
|
use sapling_crypto::{
|
||||||
jubjub::{FixedGenerators, JubjubEngine},
|
jubjub::{FixedGenerators, JubjubEngine},
|
||||||
redjubjub::{PrivateKey, PublicKey, Signature},
|
redjubjub::{PrivateKey, PublicKey, Signature},
|
||||||
|
@ -3,7 +3,10 @@ name = "pairing"
|
|||||||
|
|
||||||
# Remember to change version string in README.md.
|
# Remember to change version string in README.md.
|
||||||
version = "0.14.2"
|
version = "0.14.2"
|
||||||
authors = ["Sean Bowe <ewillbefull@gmail.com>"]
|
authors = [
|
||||||
|
"Sean Bowe <ewillbefull@gmail.com>",
|
||||||
|
"Jack Grigg <jack@z.cash>",
|
||||||
|
]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
|
|
||||||
description = "Pairing-friendly elliptic curve library"
|
description = "Pairing-friendly elliptic curve library"
|
||||||
@ -14,10 +17,10 @@ repository = "https://github.com/ebfull/pairing"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.4"
|
rand = "0.4"
|
||||||
byteorder = "1"
|
byteorder = "1"
|
||||||
clippy = { version = "0.0.200", optional = true }
|
ff = { path = "../ff", features = ["derive"] }
|
||||||
|
group = { path = "../group" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
unstable-features = ["expose-arith"]
|
unstable-features = ["expose-arith"]
|
||||||
expose-arith = []
|
expose-arith = []
|
||||||
u128-support = []
|
|
||||||
default = []
|
default = []
|
||||||
|
@ -6,14 +6,6 @@ This is a Rust crate for using pairing-friendly elliptic curves. Currently, only
|
|||||||
|
|
||||||
Bring the `pairing` crate into your project just as you normally would.
|
Bring the `pairing` crate into your project just as you normally would.
|
||||||
|
|
||||||
If you're using a supported platform and the nightly Rust compiler, you can enable the `u128-support` feature for faster arithmetic.
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[dependencies.pairing]
|
|
||||||
version = "0.14"
|
|
||||||
features = ["u128-support"]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Security Warnings
|
## Security Warnings
|
||||||
|
|
||||||
This library does not make any guarantees about constant-time operations, memory access patterns, or resistance to side-channel attacks.
|
This library does not make any guarantees about constant-time operations, memory access patterns, or resistance to side-channel attacks.
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
mod g1 {
|
mod g1 {
|
||||||
use rand::{Rand, SeedableRng, XorShiftRng};
|
use rand::{Rand, SeedableRng, XorShiftRng};
|
||||||
|
|
||||||
|
use group::CurveProjective;
|
||||||
use pairing::bls12_381::*;
|
use pairing::bls12_381::*;
|
||||||
use pairing::CurveProjective;
|
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_g1_mul_assign(b: &mut ::test::Bencher) {
|
fn bench_g1_mul_assign(b: &mut ::test::Bencher) {
|
||||||
@ -65,8 +65,8 @@ mod g1 {
|
|||||||
mod g2 {
|
mod g2 {
|
||||||
use rand::{Rand, SeedableRng, XorShiftRng};
|
use rand::{Rand, SeedableRng, XorShiftRng};
|
||||||
|
|
||||||
|
use group::CurveProjective;
|
||||||
use pairing::bls12_381::*;
|
use pairing::bls12_381::*;
|
||||||
use pairing::CurveProjective;
|
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_g2_mul_assign(b: &mut ::test::Bencher) {
|
fn bench_g2_mul_assign(b: &mut ::test::Bencher) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use rand::{Rand, SeedableRng, XorShiftRng};
|
use rand::{Rand, SeedableRng, XorShiftRng};
|
||||||
|
|
||||||
|
use ff::{Field, PrimeField, PrimeFieldRepr, SqrtField};
|
||||||
use pairing::bls12_381::*;
|
use pairing::bls12_381::*;
|
||||||
use pairing::{Field, PrimeField, PrimeFieldRepr, SqrtField};
|
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_fq_repr_add_nocarry(b: &mut ::test::Bencher) {
|
fn bench_fq_repr_add_nocarry(b: &mut ::test::Bencher) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use rand::{Rand, SeedableRng, XorShiftRng};
|
use rand::{Rand, SeedableRng, XorShiftRng};
|
||||||
|
|
||||||
|
use ff::Field;
|
||||||
use pairing::bls12_381::*;
|
use pairing::bls12_381::*;
|
||||||
use pairing::Field;
|
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_fq12_add_assign(b: &mut ::test::Bencher) {
|
fn bench_fq12_add_assign(b: &mut ::test::Bencher) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use rand::{Rand, SeedableRng, XorShiftRng};
|
use rand::{Rand, SeedableRng, XorShiftRng};
|
||||||
|
|
||||||
|
use ff::{Field, SqrtField};
|
||||||
use pairing::bls12_381::*;
|
use pairing::bls12_381::*;
|
||||||
use pairing::{Field, SqrtField};
|
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_fq2_add_assign(b: &mut ::test::Bencher) {
|
fn bench_fq2_add_assign(b: &mut ::test::Bencher) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use rand::{Rand, SeedableRng, XorShiftRng};
|
use rand::{Rand, SeedableRng, XorShiftRng};
|
||||||
|
|
||||||
|
use ff::{Field, PrimeField, PrimeFieldRepr, SqrtField};
|
||||||
use pairing::bls12_381::*;
|
use pairing::bls12_381::*;
|
||||||
use pairing::{Field, PrimeField, PrimeFieldRepr, SqrtField};
|
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_fr_repr_add_nocarry(b: &mut ::test::Bencher) {
|
fn bench_fr_repr_add_nocarry(b: &mut ::test::Bencher) {
|
||||||
|
@ -7,7 +7,7 @@ mod fr;
|
|||||||
use rand::{Rand, SeedableRng, XorShiftRng};
|
use rand::{Rand, SeedableRng, XorShiftRng};
|
||||||
|
|
||||||
use pairing::bls12_381::*;
|
use pairing::bls12_381::*;
|
||||||
use pairing::{CurveAffine, Engine};
|
use pairing::{Engine, PairingCurveAffine};
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_pairing_g1_preparation(b: &mut ::test::Bencher) {
|
fn bench_pairing_g1_preparation(b: &mut ::test::Bencher) {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
|
||||||
|
extern crate ff;
|
||||||
|
extern crate group;
|
||||||
extern crate pairing;
|
extern crate pairing;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
@ -148,12 +148,9 @@ macro_rules! curve_impl {
|
|||||||
type Engine = Bls12;
|
type Engine = Bls12;
|
||||||
type Scalar = $scalarfield;
|
type Scalar = $scalarfield;
|
||||||
type Base = $basefield;
|
type Base = $basefield;
|
||||||
type Prepared = $prepared;
|
|
||||||
type Projective = $projective;
|
type Projective = $projective;
|
||||||
type Uncompressed = $uncompressed;
|
type Uncompressed = $uncompressed;
|
||||||
type Compressed = $compressed;
|
type Compressed = $compressed;
|
||||||
type Pair = $pairing;
|
|
||||||
type PairingResult = Fq12;
|
|
||||||
|
|
||||||
fn zero() -> Self {
|
fn zero() -> Self {
|
||||||
$affine {
|
$affine {
|
||||||
@ -182,6 +179,17 @@ macro_rules! curve_impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn into_projective(&self) -> $projective {
|
||||||
|
(*self).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PairingCurveAffine for $affine {
|
||||||
|
type Prepared = $prepared;
|
||||||
|
type Pair = $pairing;
|
||||||
|
type PairingResult = Fq12;
|
||||||
|
|
||||||
fn prepare(&self) -> Self::Prepared {
|
fn prepare(&self) -> Self::Prepared {
|
||||||
$prepared::from_affine(*self)
|
$prepared::from_affine(*self)
|
||||||
}
|
}
|
||||||
@ -190,10 +198,6 @@ macro_rules! curve_impl {
|
|||||||
self.perform_pairing(other)
|
self.perform_pairing(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_projective(&self) -> $projective {
|
|
||||||
(*self).into()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rand for $projective {
|
impl Rand for $projective {
|
||||||
@ -623,12 +627,11 @@ macro_rules! curve_impl {
|
|||||||
pub mod g1 {
|
pub mod g1 {
|
||||||
use super::super::{Bls12, Fq, Fq12, FqRepr, Fr, FrRepr};
|
use super::super::{Bls12, Fq, Fq12, FqRepr, Fr, FrRepr};
|
||||||
use super::g2::G2Affine;
|
use super::g2::G2Affine;
|
||||||
|
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField};
|
||||||
|
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError};
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use {
|
use {Engine, PairingCurveAffine};
|
||||||
BitIterator, CurveAffine, CurveProjective, EncodedPoint, Engine, Field, GroupDecodingError,
|
|
||||||
PrimeField, PrimeFieldRepr, SqrtField,
|
|
||||||
};
|
|
||||||
|
|
||||||
curve_impl!(
|
curve_impl!(
|
||||||
"G1",
|
"G1",
|
||||||
@ -1263,19 +1266,19 @@ pub mod g1 {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn g1_curve_tests() {
|
fn g1_curve_tests() {
|
||||||
::tests::curve::curve_tests::<G1>();
|
use group::tests::curve_tests;
|
||||||
|
curve_tests::<G1>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod g2 {
|
pub mod g2 {
|
||||||
use super::super::{Bls12, Fq, Fq12, Fq2, FqRepr, Fr, FrRepr};
|
use super::super::{Bls12, Fq, Fq12, Fq2, FqRepr, Fr, FrRepr};
|
||||||
use super::g1::G1Affine;
|
use super::g1::G1Affine;
|
||||||
|
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField};
|
||||||
|
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError};
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use {
|
use {Engine, PairingCurveAffine};
|
||||||
BitIterator, CurveAffine, CurveProjective, EncodedPoint, Engine, Field, GroupDecodingError,
|
|
||||||
PrimeField, PrimeFieldRepr, SqrtField,
|
|
||||||
};
|
|
||||||
|
|
||||||
curve_impl!(
|
curve_impl!(
|
||||||
"G2",
|
"G2",
|
||||||
@ -2018,7 +2021,8 @@ pub mod g2 {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn g2_curve_tests() {
|
fn g2_curve_tests() {
|
||||||
::tests::curve::curve_tests::<G2>();
|
use group::tests::curve_tests;
|
||||||
|
curve_tests::<G2>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,69 +1,5 @@
|
|||||||
use super::fq2::Fq2;
|
use super::fq2::Fq2;
|
||||||
use std::cmp::Ordering;
|
use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr};
|
||||||
use {Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, SqrtField};
|
|
||||||
|
|
||||||
// q = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
|
|
||||||
const MODULUS: FqRepr = FqRepr([
|
|
||||||
0xb9feffffffffaaab,
|
|
||||||
0x1eabfffeb153ffff,
|
|
||||||
0x6730d2a0f6b0f624,
|
|
||||||
0x64774b84f38512bf,
|
|
||||||
0x4b1ba7b6434bacd7,
|
|
||||||
0x1a0111ea397fe69a,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// The number of bits needed to represent the modulus.
|
|
||||||
const MODULUS_BITS: u32 = 381;
|
|
||||||
|
|
||||||
// The number of bits that must be shaved from the beginning of
|
|
||||||
// the representation when randomly sampling.
|
|
||||||
const REPR_SHAVE_BITS: u32 = 3;
|
|
||||||
|
|
||||||
// R = 2**384 % q
|
|
||||||
const R: FqRepr = FqRepr([
|
|
||||||
0x760900000002fffd,
|
|
||||||
0xebf4000bc40c0002,
|
|
||||||
0x5f48985753c758ba,
|
|
||||||
0x77ce585370525745,
|
|
||||||
0x5c071a97a256ec6d,
|
|
||||||
0x15f65ec3fa80e493,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// R2 = R^2 % q
|
|
||||||
const R2: FqRepr = FqRepr([
|
|
||||||
0xf4df1f341c341746,
|
|
||||||
0xa76e6a609d104f1,
|
|
||||||
0x8de5476c4c95b6d5,
|
|
||||||
0x67eb88a9939d83c0,
|
|
||||||
0x9a793e85b519952d,
|
|
||||||
0x11988fe592cae3aa,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// INV = -(q^{-1} mod 2^64) mod 2^64
|
|
||||||
const INV: u64 = 0x89f3fffcfffcfffd;
|
|
||||||
|
|
||||||
// GENERATOR = 2 (multiplicative generator of q-1 order, that is also quadratic nonresidue)
|
|
||||||
const GENERATOR: FqRepr = FqRepr([
|
|
||||||
0x321300000006554f,
|
|
||||||
0xb93c0018d6c40005,
|
|
||||||
0x57605e0db0ddbb51,
|
|
||||||
0x8b256521ed1f9bcb,
|
|
||||||
0x6cf28d7901622c03,
|
|
||||||
0x11ebab9dbb81e28c,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 2^s * t = MODULUS - 1 with t odd
|
|
||||||
const S: u32 = 1;
|
|
||||||
|
|
||||||
// 2^s root of unity computed by GENERATOR^t
|
|
||||||
const ROOT_OF_UNITY: FqRepr = FqRepr([
|
|
||||||
0x43f5fffffffcaaae,
|
|
||||||
0x32b7fff2ed47fffd,
|
|
||||||
0x7e83a49a2e99d69,
|
|
||||||
0xeca8f3318332bb7a,
|
|
||||||
0xef148d1ea0f4c069,
|
|
||||||
0x40ab3263eff0206,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// B coefficient of BLS12-381 curve, 4.
|
// B coefficient of BLS12-381 curve, 4.
|
||||||
pub const B_COEFF: Fq = Fq(FqRepr([
|
pub const B_COEFF: Fq = Fq(FqRepr([
|
||||||
@ -507,669 +443,11 @@ pub const NEGATIVE_ONE: Fq = Fq(FqRepr([
|
|||||||
0x40ab3263eff0206,
|
0x40ab3263eff0206,
|
||||||
]));
|
]));
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)]
|
#[derive(PrimeField)]
|
||||||
pub struct FqRepr(pub [u64; 6]);
|
#[PrimeFieldModulus = "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787"]
|
||||||
|
#[PrimeFieldGenerator = "2"]
|
||||||
impl ::rand::Rand for FqRepr {
|
|
||||||
#[inline(always)]
|
|
||||||
fn rand<R: ::rand::Rng>(rng: &mut R) -> Self {
|
|
||||||
FqRepr(rng.gen())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::fmt::Display for FqRepr {
|
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
|
||||||
try!(write!(f, "0x"));
|
|
||||||
for i in self.0.iter().rev() {
|
|
||||||
try!(write!(f, "{:016x}", *i));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsRef<[u64]> for FqRepr {
|
|
||||||
#[inline(always)]
|
|
||||||
fn as_ref(&self) -> &[u64] {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsMut<[u64]> for FqRepr {
|
|
||||||
#[inline(always)]
|
|
||||||
fn as_mut(&mut self) -> &mut [u64] {
|
|
||||||
&mut self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<u64> for FqRepr {
|
|
||||||
#[inline(always)]
|
|
||||||
fn from(val: u64) -> FqRepr {
|
|
||||||
let mut repr = Self::default();
|
|
||||||
repr.0[0] = val;
|
|
||||||
repr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Ord for FqRepr {
|
|
||||||
#[inline(always)]
|
|
||||||
fn cmp(&self, other: &FqRepr) -> Ordering {
|
|
||||||
for (a, b) in self.0.iter().rev().zip(other.0.iter().rev()) {
|
|
||||||
if a < b {
|
|
||||||
return Ordering::Less;
|
|
||||||
} else if a > b {
|
|
||||||
return Ordering::Greater;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ordering::Equal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialOrd for FqRepr {
|
|
||||||
#[inline(always)]
|
|
||||||
fn partial_cmp(&self, other: &FqRepr) -> Option<Ordering> {
|
|
||||||
Some(self.cmp(other))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PrimeFieldRepr for FqRepr {
|
|
||||||
#[inline(always)]
|
|
||||||
fn is_odd(&self) -> bool {
|
|
||||||
self.0[0] & 1 == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn is_even(&self) -> bool {
|
|
||||||
!self.is_odd()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn is_zero(&self) -> bool {
|
|
||||||
self.0.iter().all(|&e| e == 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn shr(&mut self, mut n: u32) {
|
|
||||||
if n >= 64 * 6 {
|
|
||||||
*self = Self::from(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while n >= 64 {
|
|
||||||
let mut t = 0;
|
|
||||||
for i in self.0.iter_mut().rev() {
|
|
||||||
::std::mem::swap(&mut t, i);
|
|
||||||
}
|
|
||||||
n -= 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
if n > 0 {
|
|
||||||
let mut t = 0;
|
|
||||||
for i in self.0.iter_mut().rev() {
|
|
||||||
let t2 = *i << (64 - n);
|
|
||||||
*i >>= n;
|
|
||||||
*i |= t;
|
|
||||||
t = t2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn div2(&mut self) {
|
|
||||||
let mut t = 0;
|
|
||||||
for i in self.0.iter_mut().rev() {
|
|
||||||
let t2 = *i << 63;
|
|
||||||
*i >>= 1;
|
|
||||||
*i |= t;
|
|
||||||
t = t2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn mul2(&mut self) {
|
|
||||||
let mut last = 0;
|
|
||||||
for i in &mut self.0 {
|
|
||||||
let tmp = *i >> 63;
|
|
||||||
*i <<= 1;
|
|
||||||
*i |= last;
|
|
||||||
last = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn shl(&mut self, mut n: u32) {
|
|
||||||
if n >= 64 * 6 {
|
|
||||||
*self = Self::from(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while n >= 64 {
|
|
||||||
let mut t = 0;
|
|
||||||
for i in &mut self.0 {
|
|
||||||
::std::mem::swap(&mut t, i);
|
|
||||||
}
|
|
||||||
n -= 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
if n > 0 {
|
|
||||||
let mut t = 0;
|
|
||||||
for i in &mut self.0 {
|
|
||||||
let t2 = *i >> (64 - n);
|
|
||||||
*i <<= n;
|
|
||||||
*i |= t;
|
|
||||||
t = t2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn num_bits(&self) -> u32 {
|
|
||||||
let mut ret = (6 as u32) * 64;
|
|
||||||
for i in self.0.iter().rev() {
|
|
||||||
let leading = i.leading_zeros();
|
|
||||||
ret -= leading;
|
|
||||||
if leading != 64 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn add_nocarry(&mut self, other: &FqRepr) {
|
|
||||||
let mut carry = 0;
|
|
||||||
|
|
||||||
for (a, b) in self.0.iter_mut().zip(other.0.iter()) {
|
|
||||||
*a = ::adc(*a, *b, &mut carry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn sub_noborrow(&mut self, other: &FqRepr) {
|
|
||||||
let mut borrow = 0;
|
|
||||||
|
|
||||||
for (a, b) in self.0.iter_mut().zip(other.0.iter()) {
|
|
||||||
*a = ::sbb(*a, *b, &mut borrow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
|
||||||
pub struct Fq(FqRepr);
|
pub struct Fq(FqRepr);
|
||||||
|
|
||||||
/// `Fq` elements are ordered lexicographically.
|
|
||||||
impl Ord for Fq {
|
|
||||||
#[inline(always)]
|
|
||||||
fn cmp(&self, other: &Fq) -> Ordering {
|
|
||||||
self.into_repr().cmp(&other.into_repr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialOrd for Fq {
|
|
||||||
#[inline(always)]
|
|
||||||
fn partial_cmp(&self, other: &Fq) -> Option<Ordering> {
|
|
||||||
Some(self.cmp(other))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::fmt::Display for Fq {
|
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
|
||||||
write!(f, "Fq({})", self.into_repr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::rand::Rand for Fq {
|
|
||||||
fn rand<R: ::rand::Rng>(rng: &mut R) -> Self {
|
|
||||||
loop {
|
|
||||||
let mut tmp = Fq(FqRepr::rand(rng));
|
|
||||||
|
|
||||||
// Mask away the unused bits at the beginning.
|
|
||||||
tmp.0.as_mut()[5] &= 0xffffffffffffffff >> REPR_SHAVE_BITS;
|
|
||||||
|
|
||||||
if tmp.is_valid() {
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Fq> for FqRepr {
|
|
||||||
fn from(e: Fq) -> FqRepr {
|
|
||||||
e.into_repr()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PrimeField for Fq {
|
|
||||||
type Repr = FqRepr;
|
|
||||||
|
|
||||||
fn from_repr(r: FqRepr) -> Result<Fq, PrimeFieldDecodingError> {
|
|
||||||
let mut r = Fq(r);
|
|
||||||
if r.is_valid() {
|
|
||||||
r.mul_assign(&Fq(R2));
|
|
||||||
|
|
||||||
Ok(r)
|
|
||||||
} else {
|
|
||||||
Err(PrimeFieldDecodingError::NotInField(format!("{}", r.0)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_repr(&self) -> FqRepr {
|
|
||||||
let mut r = *self;
|
|
||||||
r.mont_reduce(
|
|
||||||
(self.0).0[0],
|
|
||||||
(self.0).0[1],
|
|
||||||
(self.0).0[2],
|
|
||||||
(self.0).0[3],
|
|
||||||
(self.0).0[4],
|
|
||||||
(self.0).0[5],
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
r.0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn char() -> FqRepr {
|
|
||||||
MODULUS
|
|
||||||
}
|
|
||||||
|
|
||||||
const NUM_BITS: u32 = MODULUS_BITS;
|
|
||||||
|
|
||||||
const CAPACITY: u32 = Self::NUM_BITS - 1;
|
|
||||||
|
|
||||||
fn multiplicative_generator() -> Self {
|
|
||||||
Fq(GENERATOR)
|
|
||||||
}
|
|
||||||
|
|
||||||
const S: u32 = S;
|
|
||||||
|
|
||||||
fn root_of_unity() -> Self {
|
|
||||||
Fq(ROOT_OF_UNITY)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Field for Fq {
|
|
||||||
#[inline]
|
|
||||||
fn zero() -> Self {
|
|
||||||
Fq(FqRepr::from(0))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn one() -> Self {
|
|
||||||
Fq(R)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_zero(&self) -> bool {
|
|
||||||
self.0.is_zero()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn add_assign(&mut self, other: &Fq) {
|
|
||||||
// This cannot exceed the backing capacity.
|
|
||||||
self.0.add_nocarry(&other.0);
|
|
||||||
|
|
||||||
// However, it may need to be reduced.
|
|
||||||
self.reduce();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn double(&mut self) {
|
|
||||||
// This cannot exceed the backing capacity.
|
|
||||||
self.0.mul2();
|
|
||||||
|
|
||||||
// However, it may need to be reduced.
|
|
||||||
self.reduce();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sub_assign(&mut self, other: &Fq) {
|
|
||||||
// If `other` is larger than `self`, we'll need to add the modulus to self first.
|
|
||||||
if other.0 > self.0 {
|
|
||||||
self.0.add_nocarry(&MODULUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.0.sub_noborrow(&other.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn negate(&mut self) {
|
|
||||||
if !self.is_zero() {
|
|
||||||
let mut tmp = MODULUS;
|
|
||||||
tmp.sub_noborrow(&self.0);
|
|
||||||
self.0 = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inverse(&self) -> Option<Self> {
|
|
||||||
if self.is_zero() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
// Guajardo Kumar Paar Pelzl
|
|
||||||
// Efficient Software-Implementation of Finite Fields with Applications to Cryptography
|
|
||||||
// Algorithm 16 (BEA for Inversion in Fp)
|
|
||||||
|
|
||||||
let one = FqRepr::from(1);
|
|
||||||
|
|
||||||
let mut u = self.0;
|
|
||||||
let mut v = MODULUS;
|
|
||||||
let mut b = Fq(R2); // Avoids unnecessary reduction step.
|
|
||||||
let mut c = Self::zero();
|
|
||||||
|
|
||||||
while u != one && v != one {
|
|
||||||
while u.is_even() {
|
|
||||||
u.div2();
|
|
||||||
|
|
||||||
if b.0.is_even() {
|
|
||||||
b.0.div2();
|
|
||||||
} else {
|
|
||||||
b.0.add_nocarry(&MODULUS);
|
|
||||||
b.0.div2();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while v.is_even() {
|
|
||||||
v.div2();
|
|
||||||
|
|
||||||
if c.0.is_even() {
|
|
||||||
c.0.div2();
|
|
||||||
} else {
|
|
||||||
c.0.add_nocarry(&MODULUS);
|
|
||||||
c.0.div2();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if v < u {
|
|
||||||
u.sub_noborrow(&v);
|
|
||||||
b.sub_assign(&c);
|
|
||||||
} else {
|
|
||||||
v.sub_noborrow(&u);
|
|
||||||
c.sub_assign(&b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if u == one {
|
|
||||||
Some(b)
|
|
||||||
} else {
|
|
||||||
Some(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn frobenius_map(&mut self, _: usize) {
|
|
||||||
// This has no effect in a prime field.
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn mul_assign(&mut self, other: &Fq) {
|
|
||||||
let mut carry = 0;
|
|
||||||
let r0 = ::mac_with_carry(0, (self.0).0[0], (other.0).0[0], &mut carry);
|
|
||||||
let r1 = ::mac_with_carry(0, (self.0).0[0], (other.0).0[1], &mut carry);
|
|
||||||
let r2 = ::mac_with_carry(0, (self.0).0[0], (other.0).0[2], &mut carry);
|
|
||||||
let r3 = ::mac_with_carry(0, (self.0).0[0], (other.0).0[3], &mut carry);
|
|
||||||
let r4 = ::mac_with_carry(0, (self.0).0[0], (other.0).0[4], &mut carry);
|
|
||||||
let r5 = ::mac_with_carry(0, (self.0).0[0], (other.0).0[5], &mut carry);
|
|
||||||
let r6 = carry;
|
|
||||||
let mut carry = 0;
|
|
||||||
let r1 = ::mac_with_carry(r1, (self.0).0[1], (other.0).0[0], &mut carry);
|
|
||||||
let r2 = ::mac_with_carry(r2, (self.0).0[1], (other.0).0[1], &mut carry);
|
|
||||||
let r3 = ::mac_with_carry(r3, (self.0).0[1], (other.0).0[2], &mut carry);
|
|
||||||
let r4 = ::mac_with_carry(r4, (self.0).0[1], (other.0).0[3], &mut carry);
|
|
||||||
let r5 = ::mac_with_carry(r5, (self.0).0[1], (other.0).0[4], &mut carry);
|
|
||||||
let r6 = ::mac_with_carry(r6, (self.0).0[1], (other.0).0[5], &mut carry);
|
|
||||||
let r7 = carry;
|
|
||||||
let mut carry = 0;
|
|
||||||
let r2 = ::mac_with_carry(r2, (self.0).0[2], (other.0).0[0], &mut carry);
|
|
||||||
let r3 = ::mac_with_carry(r3, (self.0).0[2], (other.0).0[1], &mut carry);
|
|
||||||
let r4 = ::mac_with_carry(r4, (self.0).0[2], (other.0).0[2], &mut carry);
|
|
||||||
let r5 = ::mac_with_carry(r5, (self.0).0[2], (other.0).0[3], &mut carry);
|
|
||||||
let r6 = ::mac_with_carry(r6, (self.0).0[2], (other.0).0[4], &mut carry);
|
|
||||||
let r7 = ::mac_with_carry(r7, (self.0).0[2], (other.0).0[5], &mut carry);
|
|
||||||
let r8 = carry;
|
|
||||||
let mut carry = 0;
|
|
||||||
let r3 = ::mac_with_carry(r3, (self.0).0[3], (other.0).0[0], &mut carry);
|
|
||||||
let r4 = ::mac_with_carry(r4, (self.0).0[3], (other.0).0[1], &mut carry);
|
|
||||||
let r5 = ::mac_with_carry(r5, (self.0).0[3], (other.0).0[2], &mut carry);
|
|
||||||
let r6 = ::mac_with_carry(r6, (self.0).0[3], (other.0).0[3], &mut carry);
|
|
||||||
let r7 = ::mac_with_carry(r7, (self.0).0[3], (other.0).0[4], &mut carry);
|
|
||||||
let r8 = ::mac_with_carry(r8, (self.0).0[3], (other.0).0[5], &mut carry);
|
|
||||||
let r9 = carry;
|
|
||||||
let mut carry = 0;
|
|
||||||
let r4 = ::mac_with_carry(r4, (self.0).0[4], (other.0).0[0], &mut carry);
|
|
||||||
let r5 = ::mac_with_carry(r5, (self.0).0[4], (other.0).0[1], &mut carry);
|
|
||||||
let r6 = ::mac_with_carry(r6, (self.0).0[4], (other.0).0[2], &mut carry);
|
|
||||||
let r7 = ::mac_with_carry(r7, (self.0).0[4], (other.0).0[3], &mut carry);
|
|
||||||
let r8 = ::mac_with_carry(r8, (self.0).0[4], (other.0).0[4], &mut carry);
|
|
||||||
let r9 = ::mac_with_carry(r9, (self.0).0[4], (other.0).0[5], &mut carry);
|
|
||||||
let r10 = carry;
|
|
||||||
let mut carry = 0;
|
|
||||||
let r5 = ::mac_with_carry(r5, (self.0).0[5], (other.0).0[0], &mut carry);
|
|
||||||
let r6 = ::mac_with_carry(r6, (self.0).0[5], (other.0).0[1], &mut carry);
|
|
||||||
let r7 = ::mac_with_carry(r7, (self.0).0[5], (other.0).0[2], &mut carry);
|
|
||||||
let r8 = ::mac_with_carry(r8, (self.0).0[5], (other.0).0[3], &mut carry);
|
|
||||||
let r9 = ::mac_with_carry(r9, (self.0).0[5], (other.0).0[4], &mut carry);
|
|
||||||
let r10 = ::mac_with_carry(r10, (self.0).0[5], (other.0).0[5], &mut carry);
|
|
||||||
let r11 = carry;
|
|
||||||
self.mont_reduce(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn square(&mut self) {
|
|
||||||
let mut carry = 0;
|
|
||||||
let r1 = ::mac_with_carry(0, (self.0).0[0], (self.0).0[1], &mut carry);
|
|
||||||
let r2 = ::mac_with_carry(0, (self.0).0[0], (self.0).0[2], &mut carry);
|
|
||||||
let r3 = ::mac_with_carry(0, (self.0).0[0], (self.0).0[3], &mut carry);
|
|
||||||
let r4 = ::mac_with_carry(0, (self.0).0[0], (self.0).0[4], &mut carry);
|
|
||||||
let r5 = ::mac_with_carry(0, (self.0).0[0], (self.0).0[5], &mut carry);
|
|
||||||
let r6 = carry;
|
|
||||||
let mut carry = 0;
|
|
||||||
let r3 = ::mac_with_carry(r3, (self.0).0[1], (self.0).0[2], &mut carry);
|
|
||||||
let r4 = ::mac_with_carry(r4, (self.0).0[1], (self.0).0[3], &mut carry);
|
|
||||||
let r5 = ::mac_with_carry(r5, (self.0).0[1], (self.0).0[4], &mut carry);
|
|
||||||
let r6 = ::mac_with_carry(r6, (self.0).0[1], (self.0).0[5], &mut carry);
|
|
||||||
let r7 = carry;
|
|
||||||
let mut carry = 0;
|
|
||||||
let r5 = ::mac_with_carry(r5, (self.0).0[2], (self.0).0[3], &mut carry);
|
|
||||||
let r6 = ::mac_with_carry(r6, (self.0).0[2], (self.0).0[4], &mut carry);
|
|
||||||
let r7 = ::mac_with_carry(r7, (self.0).0[2], (self.0).0[5], &mut carry);
|
|
||||||
let r8 = carry;
|
|
||||||
let mut carry = 0;
|
|
||||||
let r7 = ::mac_with_carry(r7, (self.0).0[3], (self.0).0[4], &mut carry);
|
|
||||||
let r8 = ::mac_with_carry(r8, (self.0).0[3], (self.0).0[5], &mut carry);
|
|
||||||
let r9 = carry;
|
|
||||||
let mut carry = 0;
|
|
||||||
let r9 = ::mac_with_carry(r9, (self.0).0[4], (self.0).0[5], &mut carry);
|
|
||||||
let r10 = carry;
|
|
||||||
|
|
||||||
let r11 = r10 >> 63;
|
|
||||||
let r10 = (r10 << 1) | (r9 >> 63);
|
|
||||||
let r9 = (r9 << 1) | (r8 >> 63);
|
|
||||||
let r8 = (r8 << 1) | (r7 >> 63);
|
|
||||||
let r7 = (r7 << 1) | (r6 >> 63);
|
|
||||||
let r6 = (r6 << 1) | (r5 >> 63);
|
|
||||||
let r5 = (r5 << 1) | (r4 >> 63);
|
|
||||||
let r4 = (r4 << 1) | (r3 >> 63);
|
|
||||||
let r3 = (r3 << 1) | (r2 >> 63);
|
|
||||||
let r2 = (r2 << 1) | (r1 >> 63);
|
|
||||||
let r1 = r1 << 1;
|
|
||||||
|
|
||||||
let mut carry = 0;
|
|
||||||
let r0 = ::mac_with_carry(0, (self.0).0[0], (self.0).0[0], &mut carry);
|
|
||||||
let r1 = ::adc(r1, 0, &mut carry);
|
|
||||||
let r2 = ::mac_with_carry(r2, (self.0).0[1], (self.0).0[1], &mut carry);
|
|
||||||
let r3 = ::adc(r3, 0, &mut carry);
|
|
||||||
let r4 = ::mac_with_carry(r4, (self.0).0[2], (self.0).0[2], &mut carry);
|
|
||||||
let r5 = ::adc(r5, 0, &mut carry);
|
|
||||||
let r6 = ::mac_with_carry(r6, (self.0).0[3], (self.0).0[3], &mut carry);
|
|
||||||
let r7 = ::adc(r7, 0, &mut carry);
|
|
||||||
let r8 = ::mac_with_carry(r8, (self.0).0[4], (self.0).0[4], &mut carry);
|
|
||||||
let r9 = ::adc(r9, 0, &mut carry);
|
|
||||||
let r10 = ::mac_with_carry(r10, (self.0).0[5], (self.0).0[5], &mut carry);
|
|
||||||
let r11 = ::adc(r11, 0, &mut carry);
|
|
||||||
self.mont_reduce(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Fq {
|
|
||||||
/// Determines if the element is really in the field. This is only used
|
|
||||||
/// internally.
|
|
||||||
#[inline(always)]
|
|
||||||
fn is_valid(&self) -> bool {
|
|
||||||
self.0 < MODULUS
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subtracts the modulus from this element if this element is not in the
|
|
||||||
/// field. Only used internally.
|
|
||||||
#[inline(always)]
|
|
||||||
fn reduce(&mut self) {
|
|
||||||
if !self.is_valid() {
|
|
||||||
self.0.sub_noborrow(&MODULUS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn mont_reduce(
|
|
||||||
&mut self,
|
|
||||||
r0: u64,
|
|
||||||
mut r1: u64,
|
|
||||||
mut r2: u64,
|
|
||||||
mut r3: u64,
|
|
||||||
mut r4: u64,
|
|
||||||
mut r5: u64,
|
|
||||||
mut r6: u64,
|
|
||||||
mut r7: u64,
|
|
||||||
mut r8: u64,
|
|
||||||
mut r9: u64,
|
|
||||||
mut r10: u64,
|
|
||||||
mut r11: u64,
|
|
||||||
) {
|
|
||||||
// The Montgomery reduction here is based on Algorithm 14.32 in
|
|
||||||
// Handbook of Applied Cryptography
|
|
||||||
// <http://cacr.uwaterloo.ca/hac/about/chap14.pdf>.
|
|
||||||
|
|
||||||
let k = r0.wrapping_mul(INV);
|
|
||||||
let mut carry = 0;
|
|
||||||
::mac_with_carry(r0, k, MODULUS.0[0], &mut carry);
|
|
||||||
r1 = ::mac_with_carry(r1, k, MODULUS.0[1], &mut carry);
|
|
||||||
r2 = ::mac_with_carry(r2, k, MODULUS.0[2], &mut carry);
|
|
||||||
r3 = ::mac_with_carry(r3, k, MODULUS.0[3], &mut carry);
|
|
||||||
r4 = ::mac_with_carry(r4, k, MODULUS.0[4], &mut carry);
|
|
||||||
r5 = ::mac_with_carry(r5, k, MODULUS.0[5], &mut carry);
|
|
||||||
r6 = ::adc(r6, 0, &mut carry);
|
|
||||||
let carry2 = carry;
|
|
||||||
let k = r1.wrapping_mul(INV);
|
|
||||||
let mut carry = 0;
|
|
||||||
::mac_with_carry(r1, k, MODULUS.0[0], &mut carry);
|
|
||||||
r2 = ::mac_with_carry(r2, k, MODULUS.0[1], &mut carry);
|
|
||||||
r3 = ::mac_with_carry(r3, k, MODULUS.0[2], &mut carry);
|
|
||||||
r4 = ::mac_with_carry(r4, k, MODULUS.0[3], &mut carry);
|
|
||||||
r5 = ::mac_with_carry(r5, k, MODULUS.0[4], &mut carry);
|
|
||||||
r6 = ::mac_with_carry(r6, k, MODULUS.0[5], &mut carry);
|
|
||||||
r7 = ::adc(r7, carry2, &mut carry);
|
|
||||||
let carry2 = carry;
|
|
||||||
let k = r2.wrapping_mul(INV);
|
|
||||||
let mut carry = 0;
|
|
||||||
::mac_with_carry(r2, k, MODULUS.0[0], &mut carry);
|
|
||||||
r3 = ::mac_with_carry(r3, k, MODULUS.0[1], &mut carry);
|
|
||||||
r4 = ::mac_with_carry(r4, k, MODULUS.0[2], &mut carry);
|
|
||||||
r5 = ::mac_with_carry(r5, k, MODULUS.0[3], &mut carry);
|
|
||||||
r6 = ::mac_with_carry(r6, k, MODULUS.0[4], &mut carry);
|
|
||||||
r7 = ::mac_with_carry(r7, k, MODULUS.0[5], &mut carry);
|
|
||||||
r8 = ::adc(r8, carry2, &mut carry);
|
|
||||||
let carry2 = carry;
|
|
||||||
let k = r3.wrapping_mul(INV);
|
|
||||||
let mut carry = 0;
|
|
||||||
::mac_with_carry(r3, k, MODULUS.0[0], &mut carry);
|
|
||||||
r4 = ::mac_with_carry(r4, k, MODULUS.0[1], &mut carry);
|
|
||||||
r5 = ::mac_with_carry(r5, k, MODULUS.0[2], &mut carry);
|
|
||||||
r6 = ::mac_with_carry(r6, k, MODULUS.0[3], &mut carry);
|
|
||||||
r7 = ::mac_with_carry(r7, k, MODULUS.0[4], &mut carry);
|
|
||||||
r8 = ::mac_with_carry(r8, k, MODULUS.0[5], &mut carry);
|
|
||||||
r9 = ::adc(r9, carry2, &mut carry);
|
|
||||||
let carry2 = carry;
|
|
||||||
let k = r4.wrapping_mul(INV);
|
|
||||||
let mut carry = 0;
|
|
||||||
::mac_with_carry(r4, k, MODULUS.0[0], &mut carry);
|
|
||||||
r5 = ::mac_with_carry(r5, k, MODULUS.0[1], &mut carry);
|
|
||||||
r6 = ::mac_with_carry(r6, k, MODULUS.0[2], &mut carry);
|
|
||||||
r7 = ::mac_with_carry(r7, k, MODULUS.0[3], &mut carry);
|
|
||||||
r8 = ::mac_with_carry(r8, k, MODULUS.0[4], &mut carry);
|
|
||||||
r9 = ::mac_with_carry(r9, k, MODULUS.0[5], &mut carry);
|
|
||||||
r10 = ::adc(r10, carry2, &mut carry);
|
|
||||||
let carry2 = carry;
|
|
||||||
let k = r5.wrapping_mul(INV);
|
|
||||||
let mut carry = 0;
|
|
||||||
::mac_with_carry(r5, k, MODULUS.0[0], &mut carry);
|
|
||||||
r6 = ::mac_with_carry(r6, k, MODULUS.0[1], &mut carry);
|
|
||||||
r7 = ::mac_with_carry(r7, k, MODULUS.0[2], &mut carry);
|
|
||||||
r8 = ::mac_with_carry(r8, k, MODULUS.0[3], &mut carry);
|
|
||||||
r9 = ::mac_with_carry(r9, k, MODULUS.0[4], &mut carry);
|
|
||||||
r10 = ::mac_with_carry(r10, k, MODULUS.0[5], &mut carry);
|
|
||||||
r11 = ::adc(r11, carry2, &mut carry);
|
|
||||||
(self.0).0[0] = r6;
|
|
||||||
(self.0).0[1] = r7;
|
|
||||||
(self.0).0[2] = r8;
|
|
||||||
(self.0).0[3] = r9;
|
|
||||||
(self.0).0[4] = r10;
|
|
||||||
(self.0).0[5] = r11;
|
|
||||||
self.reduce();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SqrtField for Fq {
|
|
||||||
fn legendre(&self) -> ::LegendreSymbol {
|
|
||||||
use LegendreSymbol::*;
|
|
||||||
|
|
||||||
// s = self^((q - 1) // 2)
|
|
||||||
let s = self.pow([
|
|
||||||
0xdcff7fffffffd555,
|
|
||||||
0xf55ffff58a9ffff,
|
|
||||||
0xb39869507b587b12,
|
|
||||||
0xb23ba5c279c2895f,
|
|
||||||
0x258dd3db21a5d66b,
|
|
||||||
0xd0088f51cbff34d,
|
|
||||||
]);
|
|
||||||
if s == Fq::zero() {
|
|
||||||
Zero
|
|
||||||
} else if s == Fq::one() {
|
|
||||||
QuadraticResidue
|
|
||||||
} else {
|
|
||||||
QuadraticNonResidue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sqrt(&self) -> Option<Self> {
|
|
||||||
// Shank's algorithm for q mod 4 = 3
|
|
||||||
// https://eprint.iacr.org/2012/685.pdf (page 9, algorithm 2)
|
|
||||||
|
|
||||||
// a1 = self^((q - 3) // 4)
|
|
||||||
let mut a1 = self.pow([
|
|
||||||
0xee7fbfffffffeaaa,
|
|
||||||
0x7aaffffac54ffff,
|
|
||||||
0xd9cc34a83dac3d89,
|
|
||||||
0xd91dd2e13ce144af,
|
|
||||||
0x92c6e9ed90d2eb35,
|
|
||||||
0x680447a8e5ff9a6,
|
|
||||||
]);
|
|
||||||
let mut a0 = a1;
|
|
||||||
a0.square();
|
|
||||||
a0.mul_assign(self);
|
|
||||||
|
|
||||||
if a0 == NEGATIVE_ONE {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
a1.mul_assign(self);
|
|
||||||
Some(a1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_b_coeff() {
|
fn test_b_coeff() {
|
||||||
assert_eq!(Fq::from_repr(FqRepr::from(4)).unwrap(), B_COEFF);
|
assert_eq!(Fq::from_repr(FqRepr::from(4)).unwrap(), B_COEFF);
|
||||||
@ -1899,6 +1177,8 @@ use rand::{Rand, SeedableRng, XorShiftRng};
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_repr_ordering() {
|
fn test_fq_repr_ordering() {
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
fn assert_equality(a: FqRepr, b: FqRepr) {
|
fn assert_equality(a: FqRepr, b: FqRepr) {
|
||||||
assert_eq!(a, b);
|
assert_eq!(a, b);
|
||||||
assert!(a.cmp(&b) == Ordering::Equal);
|
assert!(a.cmp(&b) == Ordering::Equal);
|
||||||
@ -2304,14 +1584,16 @@ fn test_fq_is_valid() {
|
|||||||
0x17c8be1800b9f059
|
0x17c8be1800b9f059
|
||||||
])).is_valid()
|
])).is_valid()
|
||||||
);
|
);
|
||||||
assert!(!Fq(FqRepr([
|
assert!(
|
||||||
0xffffffffffffffff,
|
!Fq(FqRepr([
|
||||||
0xffffffffffffffff,
|
0xffffffffffffffff,
|
||||||
0xffffffffffffffff,
|
0xffffffffffffffff,
|
||||||
0xffffffffffffffff,
|
0xffffffffffffffff,
|
||||||
0xffffffffffffffff,
|
0xffffffffffffffff,
|
||||||
0xffffffffffffffff
|
0xffffffffffffffff,
|
||||||
])).is_valid());
|
0xffffffffffffffff
|
||||||
|
])).is_valid()
|
||||||
|
);
|
||||||
|
|
||||||
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||||
|
|
||||||
@ -2745,6 +2027,8 @@ fn test_fq_pow() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_sqrt() {
|
fn test_fq_sqrt() {
|
||||||
|
use ff::SqrtField;
|
||||||
|
|
||||||
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||||
|
|
||||||
assert_eq!(Fq::zero().sqrt().unwrap(), Fq::zero());
|
assert_eq!(Fq::zero().sqrt().unwrap(), Fq::zero());
|
||||||
@ -2878,6 +2162,8 @@ fn test_fq_num_bits() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_root_of_unity() {
|
fn test_fq_root_of_unity() {
|
||||||
|
use ff::SqrtField;
|
||||||
|
|
||||||
assert_eq!(Fq::S, 1);
|
assert_eq!(Fq::S, 1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Fq::multiplicative_generator(),
|
Fq::multiplicative_generator(),
|
||||||
@ -2924,7 +2210,8 @@ fn fq_repr_tests() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq_legendre() {
|
fn test_fq_legendre() {
|
||||||
use LegendreSymbol::*;
|
use ff::LegendreSymbol::*;
|
||||||
|
use ff::SqrtField;
|
||||||
|
|
||||||
assert_eq!(QuadraticResidue, Fq::one().legendre());
|
assert_eq!(QuadraticResidue, Fq::one().legendre());
|
||||||
assert_eq!(Zero, Fq::zero().legendre());
|
assert_eq!(Zero, Fq::zero().legendre());
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use super::fq::FROBENIUS_COEFF_FQ12_C1;
|
use super::fq::FROBENIUS_COEFF_FQ12_C1;
|
||||||
use super::fq2::Fq2;
|
use super::fq2::Fq2;
|
||||||
use super::fq6::Fq6;
|
use super::fq6::Fq6;
|
||||||
|
use ff::Field;
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
use Field;
|
|
||||||
|
|
||||||
/// An element of Fq12, represented by c0 + c1 * w.
|
/// An element of Fq12, represented by c0 + c1 * w.
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
@ -182,7 +182,7 @@ fn test_fq12_mul_by_014() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fq12_field_tests() {
|
fn fq12_field_tests() {
|
||||||
use PrimeField;
|
use ff::PrimeField;
|
||||||
|
|
||||||
::tests::field::random_field_tests::<Fq12>();
|
::tests::field::random_field_tests::<Fq12>();
|
||||||
::tests::field::random_frobenius_tests::<Fq12, _>(super::fq::Fq::char(), 13);
|
::tests::field::random_frobenius_tests::<Fq12, _>(super::fq::Fq::char(), 13);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::fq::{FROBENIUS_COEFF_FQ2_C1, Fq, NEGATIVE_ONE};
|
use super::fq::{FROBENIUS_COEFF_FQ2_C1, Fq, NEGATIVE_ONE};
|
||||||
|
use ff::{Field, SqrtField};
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
use {Field, SqrtField};
|
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ impl Field for Fq2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SqrtField for Fq2 {
|
impl SqrtField for Fq2 {
|
||||||
fn legendre(&self) -> ::LegendreSymbol {
|
fn legendre(&self) -> ::ff::LegendreSymbol {
|
||||||
self.norm().legendre()
|
self.norm().legendre()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,16 +263,18 @@ fn test_fq2_basics() {
|
|||||||
);
|
);
|
||||||
assert!(Fq2::zero().is_zero());
|
assert!(Fq2::zero().is_zero());
|
||||||
assert!(!Fq2::one().is_zero());
|
assert!(!Fq2::one().is_zero());
|
||||||
assert!(!Fq2 {
|
assert!(
|
||||||
c0: Fq::zero(),
|
!Fq2 {
|
||||||
c1: Fq::one(),
|
c0: Fq::zero(),
|
||||||
}.is_zero());
|
c1: Fq::one(),
|
||||||
|
}.is_zero()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq2_squaring() {
|
fn test_fq2_squaring() {
|
||||||
use super::fq::FqRepr;
|
use super::fq::FqRepr;
|
||||||
use PrimeField;
|
use ff::PrimeField;
|
||||||
|
|
||||||
let mut a = Fq2 {
|
let mut a = Fq2 {
|
||||||
c0: Fq::one(),
|
c0: Fq::one(),
|
||||||
@ -346,7 +348,7 @@ fn test_fq2_squaring() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_fq2_mul() {
|
fn test_fq2_mul() {
|
||||||
use super::fq::FqRepr;
|
use super::fq::FqRepr;
|
||||||
use PrimeField;
|
use ff::PrimeField;
|
||||||
|
|
||||||
let mut a = Fq2 {
|
let mut a = Fq2 {
|
||||||
c0: Fq::from_repr(FqRepr([
|
c0: Fq::from_repr(FqRepr([
|
||||||
@ -410,7 +412,7 @@ fn test_fq2_mul() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_fq2_inverse() {
|
fn test_fq2_inverse() {
|
||||||
use super::fq::FqRepr;
|
use super::fq::FqRepr;
|
||||||
use PrimeField;
|
use ff::PrimeField;
|
||||||
|
|
||||||
assert!(Fq2::zero().inverse().is_none());
|
assert!(Fq2::zero().inverse().is_none());
|
||||||
|
|
||||||
@ -459,7 +461,7 @@ fn test_fq2_inverse() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_fq2_addition() {
|
fn test_fq2_addition() {
|
||||||
use super::fq::FqRepr;
|
use super::fq::FqRepr;
|
||||||
use PrimeField;
|
use ff::PrimeField;
|
||||||
|
|
||||||
let mut a = Fq2 {
|
let mut a = Fq2 {
|
||||||
c0: Fq::from_repr(FqRepr([
|
c0: Fq::from_repr(FqRepr([
|
||||||
@ -523,7 +525,7 @@ fn test_fq2_addition() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_fq2_subtraction() {
|
fn test_fq2_subtraction() {
|
||||||
use super::fq::FqRepr;
|
use super::fq::FqRepr;
|
||||||
use PrimeField;
|
use ff::PrimeField;
|
||||||
|
|
||||||
let mut a = Fq2 {
|
let mut a = Fq2 {
|
||||||
c0: Fq::from_repr(FqRepr([
|
c0: Fq::from_repr(FqRepr([
|
||||||
@ -587,7 +589,7 @@ fn test_fq2_subtraction() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_fq2_negation() {
|
fn test_fq2_negation() {
|
||||||
use super::fq::FqRepr;
|
use super::fq::FqRepr;
|
||||||
use PrimeField;
|
use ff::PrimeField;
|
||||||
|
|
||||||
let mut a = Fq2 {
|
let mut a = Fq2 {
|
||||||
c0: Fq::from_repr(FqRepr([
|
c0: Fq::from_repr(FqRepr([
|
||||||
@ -634,7 +636,7 @@ fn test_fq2_negation() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_fq2_doubling() {
|
fn test_fq2_doubling() {
|
||||||
use super::fq::FqRepr;
|
use super::fq::FqRepr;
|
||||||
use PrimeField;
|
use ff::PrimeField;
|
||||||
|
|
||||||
let mut a = Fq2 {
|
let mut a = Fq2 {
|
||||||
c0: Fq::from_repr(FqRepr([
|
c0: Fq::from_repr(FqRepr([
|
||||||
@ -681,7 +683,7 @@ fn test_fq2_doubling() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_fq2_frobenius_map() {
|
fn test_fq2_frobenius_map() {
|
||||||
use super::fq::FqRepr;
|
use super::fq::FqRepr;
|
||||||
use PrimeField;
|
use ff::PrimeField;
|
||||||
|
|
||||||
let mut a = Fq2 {
|
let mut a = Fq2 {
|
||||||
c0: Fq::from_repr(FqRepr([
|
c0: Fq::from_repr(FqRepr([
|
||||||
@ -794,7 +796,7 @@ fn test_fq2_frobenius_map() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_fq2_sqrt() {
|
fn test_fq2_sqrt() {
|
||||||
use super::fq::FqRepr;
|
use super::fq::FqRepr;
|
||||||
use PrimeField;
|
use ff::PrimeField;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Fq2 {
|
Fq2 {
|
||||||
@ -865,7 +867,7 @@ fn test_fq2_sqrt() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq2_legendre() {
|
fn test_fq2_legendre() {
|
||||||
use LegendreSymbol::*;
|
use ff::LegendreSymbol::*;
|
||||||
|
|
||||||
assert_eq!(Zero, Fq2::zero().legendre());
|
assert_eq!(Zero, Fq2::zero().legendre());
|
||||||
// i^2 = -1
|
// i^2 = -1
|
||||||
@ -900,7 +902,7 @@ fn test_fq2_mul_nonresidue() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fq2_field_tests() {
|
fn fq2_field_tests() {
|
||||||
use PrimeField;
|
use ff::PrimeField;
|
||||||
|
|
||||||
::tests::field::random_field_tests::<Fq2>();
|
::tests::field::random_field_tests::<Fq2>();
|
||||||
::tests::field::random_sqrt_tests::<Fq2>();
|
::tests::field::random_sqrt_tests::<Fq2>();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::fq::{FROBENIUS_COEFF_FQ6_C1, FROBENIUS_COEFF_FQ6_C2};
|
use super::fq::{FROBENIUS_COEFF_FQ6_C1, FROBENIUS_COEFF_FQ6_C2};
|
||||||
use super::fq2::Fq2;
|
use super::fq2::Fq2;
|
||||||
|
use ff::Field;
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
use Field;
|
|
||||||
|
|
||||||
/// An element of Fq6, represented by c0 + c1 * v + c2 * v^(2).
|
/// An element of Fq6, represented by c0 + c1 * v + c2 * v^(2).
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
@ -367,7 +367,7 @@ fn test_fq6_mul_by_01() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fq6_field_tests() {
|
fn fq6_field_tests() {
|
||||||
use PrimeField;
|
use ff::PrimeField;
|
||||||
|
|
||||||
::tests::field::random_field_tests::<Fq6>();
|
::tests::field::random_field_tests::<Fq6>();
|
||||||
::tests::field::random_frobenius_tests::<Fq6, _>(super::fq::Fq::char(), 13);
|
::tests::field::random_frobenius_tests::<Fq6, _>(super::fq::Fq::char(), 13);
|
||||||
|
@ -1,647 +1,10 @@
|
|||||||
use LegendreSymbol::*;
|
use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr};
|
||||||
use {Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, SqrtField};
|
|
||||||
|
|
||||||
// r = 52435875175126190479447740508185965837690552500527637822603658699938581184513
|
#[derive(PrimeField)]
|
||||||
const MODULUS: FrRepr = FrRepr([
|
#[PrimeFieldModulus = "52435875175126190479447740508185965837690552500527637822603658699938581184513"]
|
||||||
0xffffffff00000001,
|
#[PrimeFieldGenerator = "7"]
|
||||||
0x53bda402fffe5bfe,
|
|
||||||
0x3339d80809a1d805,
|
|
||||||
0x73eda753299d7d48,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// The number of bits needed to represent the modulus.
|
|
||||||
const MODULUS_BITS: u32 = 255;
|
|
||||||
|
|
||||||
// The number of bits that must be shaved from the beginning of
|
|
||||||
// the representation when randomly sampling.
|
|
||||||
const REPR_SHAVE_BITS: u32 = 1;
|
|
||||||
|
|
||||||
// R = 2**256 % r
|
|
||||||
const R: FrRepr = FrRepr([
|
|
||||||
0x1fffffffe,
|
|
||||||
0x5884b7fa00034802,
|
|
||||||
0x998c4fefecbc4ff5,
|
|
||||||
0x1824b159acc5056f,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// R2 = R^2 % r
|
|
||||||
const R2: FrRepr = FrRepr([
|
|
||||||
0xc999e990f3f29c6d,
|
|
||||||
0x2b6cedcb87925c23,
|
|
||||||
0x5d314967254398f,
|
|
||||||
0x748d9d99f59ff11,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// INV = -(r^{-1} mod 2^64) mod 2^64
|
|
||||||
const INV: u64 = 0xfffffffeffffffff;
|
|
||||||
|
|
||||||
// GENERATOR = 7 (multiplicative generator of r-1 order, that is also quadratic nonresidue)
|
|
||||||
const GENERATOR: FrRepr = FrRepr([
|
|
||||||
0xefffffff1,
|
|
||||||
0x17e363d300189c0f,
|
|
||||||
0xff9c57876f8457b0,
|
|
||||||
0x351332208fc5a8c4,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 2^s * t = MODULUS - 1 with t odd
|
|
||||||
const S: u32 = 32;
|
|
||||||
|
|
||||||
// 2^s root of unity computed by GENERATOR^t
|
|
||||||
const ROOT_OF_UNITY: FrRepr = FrRepr([
|
|
||||||
0xb9b58d8c5f0e466a,
|
|
||||||
0x5b1b4c801819d7ec,
|
|
||||||
0xaf53ae352a31e64,
|
|
||||||
0x5bf3adda19e9b27b,
|
|
||||||
]);
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)]
|
|
||||||
pub struct FrRepr(pub [u64; 4]);
|
|
||||||
|
|
||||||
impl ::rand::Rand for FrRepr {
|
|
||||||
#[inline(always)]
|
|
||||||
fn rand<R: ::rand::Rng>(rng: &mut R) -> Self {
|
|
||||||
FrRepr(rng.gen())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::fmt::Display for FrRepr {
|
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
|
||||||
try!(write!(f, "0x"));
|
|
||||||
for i in self.0.iter().rev() {
|
|
||||||
try!(write!(f, "{:016x}", *i));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsRef<[u64]> for FrRepr {
|
|
||||||
#[inline(always)]
|
|
||||||
fn as_ref(&self) -> &[u64] {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsMut<[u64]> for FrRepr {
|
|
||||||
#[inline(always)]
|
|
||||||
fn as_mut(&mut self) -> &mut [u64] {
|
|
||||||
&mut self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<u64> for FrRepr {
|
|
||||||
#[inline(always)]
|
|
||||||
fn from(val: u64) -> FrRepr {
|
|
||||||
let mut repr = Self::default();
|
|
||||||
repr.0[0] = val;
|
|
||||||
repr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Ord for FrRepr {
|
|
||||||
#[inline(always)]
|
|
||||||
fn cmp(&self, other: &FrRepr) -> ::std::cmp::Ordering {
|
|
||||||
for (a, b) in self.0.iter().rev().zip(other.0.iter().rev()) {
|
|
||||||
if a < b {
|
|
||||||
return ::std::cmp::Ordering::Less;
|
|
||||||
} else if a > b {
|
|
||||||
return ::std::cmp::Ordering::Greater;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::std::cmp::Ordering::Equal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialOrd for FrRepr {
|
|
||||||
#[inline(always)]
|
|
||||||
fn partial_cmp(&self, other: &FrRepr) -> Option<::std::cmp::Ordering> {
|
|
||||||
Some(self.cmp(other))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PrimeFieldRepr for FrRepr {
|
|
||||||
#[inline(always)]
|
|
||||||
fn is_odd(&self) -> bool {
|
|
||||||
self.0[0] & 1 == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn is_even(&self) -> bool {
|
|
||||||
!self.is_odd()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn is_zero(&self) -> bool {
|
|
||||||
self.0.iter().all(|&e| e == 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn shr(&mut self, mut n: u32) {
|
|
||||||
if n >= 64 * 4 {
|
|
||||||
*self = Self::from(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while n >= 64 {
|
|
||||||
let mut t = 0;
|
|
||||||
for i in self.0.iter_mut().rev() {
|
|
||||||
::std::mem::swap(&mut t, i);
|
|
||||||
}
|
|
||||||
n -= 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
if n > 0 {
|
|
||||||
let mut t = 0;
|
|
||||||
for i in self.0.iter_mut().rev() {
|
|
||||||
let t2 = *i << (64 - n);
|
|
||||||
*i >>= n;
|
|
||||||
*i |= t;
|
|
||||||
t = t2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn div2(&mut self) {
|
|
||||||
let mut t = 0;
|
|
||||||
for i in self.0.iter_mut().rev() {
|
|
||||||
let t2 = *i << 63;
|
|
||||||
*i >>= 1;
|
|
||||||
*i |= t;
|
|
||||||
t = t2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn mul2(&mut self) {
|
|
||||||
let mut last = 0;
|
|
||||||
for i in &mut self.0 {
|
|
||||||
let tmp = *i >> 63;
|
|
||||||
*i <<= 1;
|
|
||||||
*i |= last;
|
|
||||||
last = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn shl(&mut self, mut n: u32) {
|
|
||||||
if n >= 64 * 4 {
|
|
||||||
*self = Self::from(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while n >= 64 {
|
|
||||||
let mut t = 0;
|
|
||||||
for i in &mut self.0 {
|
|
||||||
::std::mem::swap(&mut t, i);
|
|
||||||
}
|
|
||||||
n -= 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
if n > 0 {
|
|
||||||
let mut t = 0;
|
|
||||||
for i in &mut self.0 {
|
|
||||||
let t2 = *i >> (64 - n);
|
|
||||||
*i <<= n;
|
|
||||||
*i |= t;
|
|
||||||
t = t2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn num_bits(&self) -> u32 {
|
|
||||||
let mut ret = (4 as u32) * 64;
|
|
||||||
for i in self.0.iter().rev() {
|
|
||||||
let leading = i.leading_zeros();
|
|
||||||
ret -= leading;
|
|
||||||
if leading != 64 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn add_nocarry(&mut self, other: &FrRepr) {
|
|
||||||
let mut carry = 0;
|
|
||||||
|
|
||||||
for (a, b) in self.0.iter_mut().zip(other.0.iter()) {
|
|
||||||
*a = ::adc(*a, *b, &mut carry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn sub_noborrow(&mut self, other: &FrRepr) {
|
|
||||||
let mut borrow = 0;
|
|
||||||
|
|
||||||
for (a, b) in self.0.iter_mut().zip(other.0.iter()) {
|
|
||||||
*a = ::sbb(*a, *b, &mut borrow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
|
||||||
pub struct Fr(FrRepr);
|
pub struct Fr(FrRepr);
|
||||||
|
|
||||||
impl ::std::fmt::Display for Fr {
|
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
|
||||||
write!(f, "Fr({})", self.into_repr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::rand::Rand for Fr {
|
|
||||||
fn rand<R: ::rand::Rng>(rng: &mut R) -> Self {
|
|
||||||
loop {
|
|
||||||
let mut tmp = Fr(FrRepr::rand(rng));
|
|
||||||
|
|
||||||
// Mask away the unused bits at the beginning.
|
|
||||||
tmp.0.as_mut()[3] &= 0xffffffffffffffff >> REPR_SHAVE_BITS;
|
|
||||||
|
|
||||||
if tmp.is_valid() {
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Fr> for FrRepr {
|
|
||||||
fn from(e: Fr) -> FrRepr {
|
|
||||||
e.into_repr()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PrimeField for Fr {
|
|
||||||
type Repr = FrRepr;
|
|
||||||
|
|
||||||
fn from_repr(r: FrRepr) -> Result<Fr, PrimeFieldDecodingError> {
|
|
||||||
let mut r = Fr(r);
|
|
||||||
if r.is_valid() {
|
|
||||||
r.mul_assign(&Fr(R2));
|
|
||||||
|
|
||||||
Ok(r)
|
|
||||||
} else {
|
|
||||||
Err(PrimeFieldDecodingError::NotInField(format!("{}", r.0)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_repr(&self) -> FrRepr {
|
|
||||||
let mut r = *self;
|
|
||||||
r.mont_reduce(
|
|
||||||
(self.0).0[0],
|
|
||||||
(self.0).0[1],
|
|
||||||
(self.0).0[2],
|
|
||||||
(self.0).0[3],
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
r.0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn char() -> FrRepr {
|
|
||||||
MODULUS
|
|
||||||
}
|
|
||||||
|
|
||||||
const NUM_BITS: u32 = MODULUS_BITS;
|
|
||||||
|
|
||||||
const CAPACITY: u32 = Self::NUM_BITS - 1;
|
|
||||||
|
|
||||||
fn multiplicative_generator() -> Self {
|
|
||||||
Fr(GENERATOR)
|
|
||||||
}
|
|
||||||
|
|
||||||
const S: u32 = S;
|
|
||||||
|
|
||||||
fn root_of_unity() -> Self {
|
|
||||||
Fr(ROOT_OF_UNITY)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Field for Fr {
|
|
||||||
#[inline]
|
|
||||||
fn zero() -> Self {
|
|
||||||
Fr(FrRepr::from(0))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn one() -> Self {
|
|
||||||
Fr(R)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_zero(&self) -> bool {
|
|
||||||
self.0.is_zero()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn add_assign(&mut self, other: &Fr) {
|
|
||||||
// This cannot exceed the backing capacity.
|
|
||||||
self.0.add_nocarry(&other.0);
|
|
||||||
|
|
||||||
// However, it may need to be reduced.
|
|
||||||
self.reduce();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn double(&mut self) {
|
|
||||||
// This cannot exceed the backing capacity.
|
|
||||||
self.0.mul2();
|
|
||||||
|
|
||||||
// However, it may need to be reduced.
|
|
||||||
self.reduce();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sub_assign(&mut self, other: &Fr) {
|
|
||||||
// If `other` is larger than `self`, we'll need to add the modulus to self first.
|
|
||||||
if other.0 > self.0 {
|
|
||||||
self.0.add_nocarry(&MODULUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.0.sub_noborrow(&other.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn negate(&mut self) {
|
|
||||||
if !self.is_zero() {
|
|
||||||
let mut tmp = MODULUS;
|
|
||||||
tmp.sub_noborrow(&self.0);
|
|
||||||
self.0 = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inverse(&self) -> Option<Self> {
|
|
||||||
if self.is_zero() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
// Guajardo Kumar Paar Pelzl
|
|
||||||
// Efficient Software-Implementation of Finite Fields with Applications to Cryptography
|
|
||||||
// Algorithm 16 (BEA for Inversion in Fp)
|
|
||||||
|
|
||||||
let one = FrRepr::from(1);
|
|
||||||
|
|
||||||
let mut u = self.0;
|
|
||||||
let mut v = MODULUS;
|
|
||||||
let mut b = Fr(R2); // Avoids unnecessary reduction step.
|
|
||||||
let mut c = Self::zero();
|
|
||||||
|
|
||||||
while u != one && v != one {
|
|
||||||
while u.is_even() {
|
|
||||||
u.div2();
|
|
||||||
|
|
||||||
if b.0.is_even() {
|
|
||||||
b.0.div2();
|
|
||||||
} else {
|
|
||||||
b.0.add_nocarry(&MODULUS);
|
|
||||||
b.0.div2();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while v.is_even() {
|
|
||||||
v.div2();
|
|
||||||
|
|
||||||
if c.0.is_even() {
|
|
||||||
c.0.div2();
|
|
||||||
} else {
|
|
||||||
c.0.add_nocarry(&MODULUS);
|
|
||||||
c.0.div2();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if v < u {
|
|
||||||
u.sub_noborrow(&v);
|
|
||||||
b.sub_assign(&c);
|
|
||||||
} else {
|
|
||||||
v.sub_noborrow(&u);
|
|
||||||
c.sub_assign(&b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if u == one {
|
|
||||||
Some(b)
|
|
||||||
} else {
|
|
||||||
Some(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn frobenius_map(&mut self, _: usize) {
|
|
||||||
// This has no effect in a prime field.
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn mul_assign(&mut self, other: &Fr) {
|
|
||||||
let mut carry = 0;
|
|
||||||
let r0 = ::mac_with_carry(0, (self.0).0[0], (other.0).0[0], &mut carry);
|
|
||||||
let r1 = ::mac_with_carry(0, (self.0).0[0], (other.0).0[1], &mut carry);
|
|
||||||
let r2 = ::mac_with_carry(0, (self.0).0[0], (other.0).0[2], &mut carry);
|
|
||||||
let r3 = ::mac_with_carry(0, (self.0).0[0], (other.0).0[3], &mut carry);
|
|
||||||
let r4 = carry;
|
|
||||||
let mut carry = 0;
|
|
||||||
let r1 = ::mac_with_carry(r1, (self.0).0[1], (other.0).0[0], &mut carry);
|
|
||||||
let r2 = ::mac_with_carry(r2, (self.0).0[1], (other.0).0[1], &mut carry);
|
|
||||||
let r3 = ::mac_with_carry(r3, (self.0).0[1], (other.0).0[2], &mut carry);
|
|
||||||
let r4 = ::mac_with_carry(r4, (self.0).0[1], (other.0).0[3], &mut carry);
|
|
||||||
let r5 = carry;
|
|
||||||
let mut carry = 0;
|
|
||||||
let r2 = ::mac_with_carry(r2, (self.0).0[2], (other.0).0[0], &mut carry);
|
|
||||||
let r3 = ::mac_with_carry(r3, (self.0).0[2], (other.0).0[1], &mut carry);
|
|
||||||
let r4 = ::mac_with_carry(r4, (self.0).0[2], (other.0).0[2], &mut carry);
|
|
||||||
let r5 = ::mac_with_carry(r5, (self.0).0[2], (other.0).0[3], &mut carry);
|
|
||||||
let r6 = carry;
|
|
||||||
let mut carry = 0;
|
|
||||||
let r3 = ::mac_with_carry(r3, (self.0).0[3], (other.0).0[0], &mut carry);
|
|
||||||
let r4 = ::mac_with_carry(r4, (self.0).0[3], (other.0).0[1], &mut carry);
|
|
||||||
let r5 = ::mac_with_carry(r5, (self.0).0[3], (other.0).0[2], &mut carry);
|
|
||||||
let r6 = ::mac_with_carry(r6, (self.0).0[3], (other.0).0[3], &mut carry);
|
|
||||||
let r7 = carry;
|
|
||||||
self.mont_reduce(r0, r1, r2, r3, r4, r5, r6, r7);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn square(&mut self) {
|
|
||||||
let mut carry = 0;
|
|
||||||
let r1 = ::mac_with_carry(0, (self.0).0[0], (self.0).0[1], &mut carry);
|
|
||||||
let r2 = ::mac_with_carry(0, (self.0).0[0], (self.0).0[2], &mut carry);
|
|
||||||
let r3 = ::mac_with_carry(0, (self.0).0[0], (self.0).0[3], &mut carry);
|
|
||||||
let r4 = carry;
|
|
||||||
let mut carry = 0;
|
|
||||||
let r3 = ::mac_with_carry(r3, (self.0).0[1], (self.0).0[2], &mut carry);
|
|
||||||
let r4 = ::mac_with_carry(r4, (self.0).0[1], (self.0).0[3], &mut carry);
|
|
||||||
let r5 = carry;
|
|
||||||
let mut carry = 0;
|
|
||||||
let r5 = ::mac_with_carry(r5, (self.0).0[2], (self.0).0[3], &mut carry);
|
|
||||||
let r6 = carry;
|
|
||||||
|
|
||||||
let r7 = r6 >> 63;
|
|
||||||
let r6 = (r6 << 1) | (r5 >> 63);
|
|
||||||
let r5 = (r5 << 1) | (r4 >> 63);
|
|
||||||
let r4 = (r4 << 1) | (r3 >> 63);
|
|
||||||
let r3 = (r3 << 1) | (r2 >> 63);
|
|
||||||
let r2 = (r2 << 1) | (r1 >> 63);
|
|
||||||
let r1 = r1 << 1;
|
|
||||||
|
|
||||||
let mut carry = 0;
|
|
||||||
let r0 = ::mac_with_carry(0, (self.0).0[0], (self.0).0[0], &mut carry);
|
|
||||||
let r1 = ::adc(r1, 0, &mut carry);
|
|
||||||
let r2 = ::mac_with_carry(r2, (self.0).0[1], (self.0).0[1], &mut carry);
|
|
||||||
let r3 = ::adc(r3, 0, &mut carry);
|
|
||||||
let r4 = ::mac_with_carry(r4, (self.0).0[2], (self.0).0[2], &mut carry);
|
|
||||||
let r5 = ::adc(r5, 0, &mut carry);
|
|
||||||
let r6 = ::mac_with_carry(r6, (self.0).0[3], (self.0).0[3], &mut carry);
|
|
||||||
let r7 = ::adc(r7, 0, &mut carry);
|
|
||||||
self.mont_reduce(r0, r1, r2, r3, r4, r5, r6, r7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Fr {
|
|
||||||
/// Determines if the element is really in the field. This is only used
|
|
||||||
/// internally.
|
|
||||||
#[inline(always)]
|
|
||||||
fn is_valid(&self) -> bool {
|
|
||||||
self.0 < MODULUS
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subtracts the modulus from this element if this element is not in the
|
|
||||||
/// field. Only used internally.
|
|
||||||
#[inline(always)]
|
|
||||||
fn reduce(&mut self) {
|
|
||||||
if !self.is_valid() {
|
|
||||||
self.0.sub_noborrow(&MODULUS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn mont_reduce(
|
|
||||||
&mut self,
|
|
||||||
r0: u64,
|
|
||||||
mut r1: u64,
|
|
||||||
mut r2: u64,
|
|
||||||
mut r3: u64,
|
|
||||||
mut r4: u64,
|
|
||||||
mut r5: u64,
|
|
||||||
mut r6: u64,
|
|
||||||
mut r7: u64,
|
|
||||||
) {
|
|
||||||
// The Montgomery reduction here is based on Algorithm 14.32 in
|
|
||||||
// Handbook of Applied Cryptography
|
|
||||||
// <http://cacr.uwaterloo.ca/hac/about/chap14.pdf>.
|
|
||||||
|
|
||||||
let k = r0.wrapping_mul(INV);
|
|
||||||
let mut carry = 0;
|
|
||||||
::mac_with_carry(r0, k, MODULUS.0[0], &mut carry);
|
|
||||||
r1 = ::mac_with_carry(r1, k, MODULUS.0[1], &mut carry);
|
|
||||||
r2 = ::mac_with_carry(r2, k, MODULUS.0[2], &mut carry);
|
|
||||||
r3 = ::mac_with_carry(r3, k, MODULUS.0[3], &mut carry);
|
|
||||||
r4 = ::adc(r4, 0, &mut carry);
|
|
||||||
let carry2 = carry;
|
|
||||||
let k = r1.wrapping_mul(INV);
|
|
||||||
let mut carry = 0;
|
|
||||||
::mac_with_carry(r1, k, MODULUS.0[0], &mut carry);
|
|
||||||
r2 = ::mac_with_carry(r2, k, MODULUS.0[1], &mut carry);
|
|
||||||
r3 = ::mac_with_carry(r3, k, MODULUS.0[2], &mut carry);
|
|
||||||
r4 = ::mac_with_carry(r4, k, MODULUS.0[3], &mut carry);
|
|
||||||
r5 = ::adc(r5, carry2, &mut carry);
|
|
||||||
let carry2 = carry;
|
|
||||||
let k = r2.wrapping_mul(INV);
|
|
||||||
let mut carry = 0;
|
|
||||||
::mac_with_carry(r2, k, MODULUS.0[0], &mut carry);
|
|
||||||
r3 = ::mac_with_carry(r3, k, MODULUS.0[1], &mut carry);
|
|
||||||
r4 = ::mac_with_carry(r4, k, MODULUS.0[2], &mut carry);
|
|
||||||
r5 = ::mac_with_carry(r5, k, MODULUS.0[3], &mut carry);
|
|
||||||
r6 = ::adc(r6, carry2, &mut carry);
|
|
||||||
let carry2 = carry;
|
|
||||||
let k = r3.wrapping_mul(INV);
|
|
||||||
let mut carry = 0;
|
|
||||||
::mac_with_carry(r3, k, MODULUS.0[0], &mut carry);
|
|
||||||
r4 = ::mac_with_carry(r4, k, MODULUS.0[1], &mut carry);
|
|
||||||
r5 = ::mac_with_carry(r5, k, MODULUS.0[2], &mut carry);
|
|
||||||
r6 = ::mac_with_carry(r6, k, MODULUS.0[3], &mut carry);
|
|
||||||
r7 = ::adc(r7, carry2, &mut carry);
|
|
||||||
(self.0).0[0] = r4;
|
|
||||||
(self.0).0[1] = r5;
|
|
||||||
(self.0).0[2] = r6;
|
|
||||||
(self.0).0[3] = r7;
|
|
||||||
self.reduce();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SqrtField for Fr {
|
|
||||||
fn legendre(&self) -> ::LegendreSymbol {
|
|
||||||
// s = self^((r - 1) // 2)
|
|
||||||
let s = self.pow([
|
|
||||||
0x7fffffff80000000,
|
|
||||||
0xa9ded2017fff2dff,
|
|
||||||
0x199cec0404d0ec02,
|
|
||||||
0x39f6d3a994cebea4,
|
|
||||||
]);
|
|
||||||
if s == Self::zero() {
|
|
||||||
Zero
|
|
||||||
} else if s == Self::one() {
|
|
||||||
QuadraticResidue
|
|
||||||
} else {
|
|
||||||
QuadraticNonResidue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sqrt(&self) -> Option<Self> {
|
|
||||||
// Tonelli-Shank's algorithm for q mod 16 = 1
|
|
||||||
// https://eprint.iacr.org/2012/685.pdf (page 12, algorithm 5)
|
|
||||||
match self.legendre() {
|
|
||||||
Zero => Some(*self),
|
|
||||||
QuadraticNonResidue => None,
|
|
||||||
QuadraticResidue => {
|
|
||||||
let mut c = Fr(ROOT_OF_UNITY);
|
|
||||||
// r = self^((t + 1) // 2)
|
|
||||||
let mut r = self.pow([
|
|
||||||
0x7fff2dff80000000,
|
|
||||||
0x4d0ec02a9ded201,
|
|
||||||
0x94cebea4199cec04,
|
|
||||||
0x39f6d3a9,
|
|
||||||
]);
|
|
||||||
// t = self^t
|
|
||||||
let mut t = self.pow([
|
|
||||||
0xfffe5bfeffffffff,
|
|
||||||
0x9a1d80553bda402,
|
|
||||||
0x299d7d483339d808,
|
|
||||||
0x73eda753,
|
|
||||||
]);
|
|
||||||
let mut m = S;
|
|
||||||
|
|
||||||
while t != Self::one() {
|
|
||||||
let mut i = 1;
|
|
||||||
{
|
|
||||||
let mut t2i = t;
|
|
||||||
t2i.square();
|
|
||||||
loop {
|
|
||||||
if t2i == Self::one() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
t2i.square();
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _ in 0..(m - i - 1) {
|
|
||||||
c.square();
|
|
||||||
}
|
|
||||||
r.mul_assign(&c);
|
|
||||||
c.square();
|
|
||||||
t.mul_assign(&c);
|
|
||||||
m = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use rand::{Rand, SeedableRng, XorShiftRng};
|
use rand::{Rand, SeedableRng, XorShiftRng};
|
||||||
|
|
||||||
@ -909,6 +272,9 @@ fn test_fr_repr_sub_noborrow() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fr_legendre() {
|
fn test_fr_legendre() {
|
||||||
|
use ff::LegendreSymbol::*;
|
||||||
|
use ff::SqrtField;
|
||||||
|
|
||||||
assert_eq!(QuadraticResidue, Fr::one().legendre());
|
assert_eq!(QuadraticResidue, Fr::one().legendre());
|
||||||
assert_eq!(Zero, Fr::zero().legendre());
|
assert_eq!(Zero, Fr::zero().legendre());
|
||||||
|
|
||||||
@ -1022,12 +388,14 @@ fn test_fr_is_valid() {
|
|||||||
0x73eda753299d7d48
|
0x73eda753299d7d48
|
||||||
])).is_valid()
|
])).is_valid()
|
||||||
);
|
);
|
||||||
assert!(!Fr(FrRepr([
|
assert!(
|
||||||
0xffffffffffffffff,
|
!Fr(FrRepr([
|
||||||
0xffffffffffffffff,
|
0xffffffffffffffff,
|
||||||
0xffffffffffffffff,
|
0xffffffffffffffff,
|
||||||
0xffffffffffffffff
|
0xffffffffffffffff,
|
||||||
])).is_valid());
|
0xffffffffffffffff
|
||||||
|
])).is_valid()
|
||||||
|
);
|
||||||
|
|
||||||
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||||
|
|
||||||
@ -1417,6 +785,8 @@ fn test_fr_pow() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fr_sqrt() {
|
fn test_fr_sqrt() {
|
||||||
|
use ff::SqrtField;
|
||||||
|
|
||||||
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||||
|
|
||||||
assert_eq!(Fr::zero().sqrt().unwrap(), Fr::zero());
|
assert_eq!(Fr::zero().sqrt().unwrap(), Fr::zero());
|
||||||
@ -1582,6 +952,8 @@ fn test_fr_num_bits() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fr_root_of_unity() {
|
fn test_fr_root_of_unity() {
|
||||||
|
use ff::SqrtField;
|
||||||
|
|
||||||
assert_eq!(Fr::S, 32);
|
assert_eq!(Fr::S, 32);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Fr::multiplicative_generator(),
|
Fr::multiplicative_generator(),
|
||||||
|
@ -18,7 +18,10 @@ pub use self::fq2::Fq2;
|
|||||||
pub use self::fq6::Fq6;
|
pub use self::fq6::Fq6;
|
||||||
pub use self::fr::{Fr, FrRepr};
|
pub use self::fr::{Fr, FrRepr};
|
||||||
|
|
||||||
use super::{BitIterator, CurveAffine, Engine, Field};
|
use super::{Engine, PairingCurveAffine};
|
||||||
|
|
||||||
|
use ff::{BitIterator, Field, ScalarEngine};
|
||||||
|
use group::CurveAffine;
|
||||||
|
|
||||||
// The BLS parameter x for BLS12-381 is -0xd201000000010000
|
// The BLS parameter x for BLS12-381 is -0xd201000000010000
|
||||||
const BLS_X: u64 = 0xd201000000010000;
|
const BLS_X: u64 = 0xd201000000010000;
|
||||||
@ -27,8 +30,11 @@ const BLS_X_IS_NEGATIVE: bool = true;
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Bls12;
|
pub struct Bls12;
|
||||||
|
|
||||||
impl Engine for Bls12 {
|
impl ScalarEngine for Bls12 {
|
||||||
type Fr = Fr;
|
type Fr = Fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Engine for Bls12 {
|
||||||
type G1 = G1;
|
type G1 = G1;
|
||||||
type G1Affine = G1Affine;
|
type G1Affine = G1Affine;
|
||||||
type G2 = G2;
|
type G2 = G2;
|
||||||
@ -41,8 +47,8 @@ impl Engine for Bls12 {
|
|||||||
where
|
where
|
||||||
I: IntoIterator<
|
I: IntoIterator<
|
||||||
Item = &'a (
|
Item = &'a (
|
||||||
&'a <Self::G1Affine as CurveAffine>::Prepared,
|
&'a <Self::G1Affine as PairingCurveAffine>::Prepared,
|
||||||
&'a <Self::G2Affine as CurveAffine>::Prepared,
|
&'a <Self::G2Affine as PairingCurveAffine>::Prepared,
|
||||||
),
|
),
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
use ff::PrimeFieldRepr;
|
||||||
|
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use *;
|
use *;
|
||||||
|
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
// `clippy` is a code linting tool for improving code quality by catching
|
// `clippy` is a code linting tool for improving code quality by catching
|
||||||
// common mistakes or strange code patterns. If the `clippy` feature is
|
// common mistakes or strange code patterns. If the `cargo-clippy` feature
|
||||||
// provided, it is enabled and all compiler warnings are prohibited.
|
// is provided, all compiler warnings are prohibited.
|
||||||
#![cfg_attr(feature = "clippy", deny(warnings))]
|
#![cfg_attr(feature = "cargo-clippy", deny(warnings))]
|
||||||
#![cfg_attr(feature = "clippy", feature(plugin))]
|
#![cfg_attr(feature = "cargo-clippy", allow(inline_always))]
|
||||||
#![cfg_attr(feature = "clippy", plugin(clippy))]
|
#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
|
||||||
#![cfg_attr(feature = "clippy", allow(inline_always))]
|
#![cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))]
|
||||||
#![cfg_attr(feature = "clippy", allow(too_many_arguments))]
|
#![cfg_attr(feature = "cargo-clippy", allow(many_single_char_names))]
|
||||||
#![cfg_attr(feature = "clippy", allow(unreadable_literal))]
|
#![cfg_attr(feature = "cargo-clippy", allow(new_without_default_derive))]
|
||||||
#![cfg_attr(feature = "clippy", allow(many_single_char_names))]
|
#![cfg_attr(feature = "cargo-clippy", allow(write_literal))]
|
||||||
#![cfg_attr(feature = "clippy", allow(new_without_default_derive))]
|
|
||||||
#![cfg_attr(feature = "clippy", allow(write_literal))]
|
|
||||||
// Force public structures to implement Debug
|
// Force public structures to implement Debug
|
||||||
#![deny(missing_debug_implementations)]
|
#![deny(missing_debug_implementations)]
|
||||||
|
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
extern crate ff;
|
||||||
|
extern crate group;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -21,20 +21,13 @@ pub mod tests;
|
|||||||
|
|
||||||
pub mod bls12_381;
|
pub mod bls12_381;
|
||||||
|
|
||||||
mod wnaf;
|
use ff::{Field, PrimeField, ScalarEngine, SqrtField};
|
||||||
pub use self::wnaf::Wnaf;
|
use group::{CurveAffine, CurveProjective};
|
||||||
|
|
||||||
use std::error::Error;
|
|
||||||
use std::fmt;
|
|
||||||
use std::io::{self, Read, Write};
|
|
||||||
|
|
||||||
/// An "engine" is a collection of types (fields, elliptic curve groups, etc.)
|
/// An "engine" is a collection of types (fields, elliptic curve groups, etc.)
|
||||||
/// with well-defined relationships. In particular, the G1/G2 curve groups are
|
/// with well-defined relationships. In particular, the G1/G2 curve groups are
|
||||||
/// of prime order `r`, and are equipped with a bilinear pairing function.
|
/// of prime order `r`, and are equipped with a bilinear pairing function.
|
||||||
pub trait Engine: Sized + 'static + Clone {
|
pub trait Engine: ScalarEngine {
|
||||||
/// This is the scalar field of the G1/G2 groups.
|
|
||||||
type Fr: PrimeField + SqrtField;
|
|
||||||
|
|
||||||
/// The projective representation of an element in G1.
|
/// The projective representation of an element in G1.
|
||||||
type G1: CurveProjective<
|
type G1: CurveProjective<
|
||||||
Engine = Self,
|
Engine = Self,
|
||||||
@ -45,7 +38,7 @@ pub trait Engine: Sized + 'static + Clone {
|
|||||||
+ From<Self::G1Affine>;
|
+ From<Self::G1Affine>;
|
||||||
|
|
||||||
/// The affine representation of an element in G1.
|
/// The affine representation of an element in G1.
|
||||||
type G1Affine: CurveAffine<
|
type G1Affine: PairingCurveAffine<
|
||||||
Engine = Self,
|
Engine = Self,
|
||||||
Base = Self::Fq,
|
Base = Self::Fq,
|
||||||
Scalar = Self::Fr,
|
Scalar = Self::Fr,
|
||||||
@ -65,7 +58,7 @@ pub trait Engine: Sized + 'static + Clone {
|
|||||||
+ From<Self::G2Affine>;
|
+ From<Self::G2Affine>;
|
||||||
|
|
||||||
/// The affine representation of an element in G2.
|
/// The affine representation of an element in G2.
|
||||||
type G2Affine: CurveAffine<
|
type G2Affine: PairingCurveAffine<
|
||||||
Engine = Self,
|
Engine = Self,
|
||||||
Base = Self::Fqe,
|
Base = Self::Fqe,
|
||||||
Scalar = Self::Fr,
|
Scalar = Self::Fr,
|
||||||
@ -89,8 +82,8 @@ pub trait Engine: Sized + 'static + Clone {
|
|||||||
where
|
where
|
||||||
I: IntoIterator<
|
I: IntoIterator<
|
||||||
Item = &'a (
|
Item = &'a (
|
||||||
&'a <Self::G1Affine as CurveAffine>::Prepared,
|
&'a <Self::G1Affine as PairingCurveAffine>::Prepared,
|
||||||
&'a <Self::G2Affine as CurveAffine>::Prepared,
|
&'a <Self::G2Affine as PairingCurveAffine>::Prepared,
|
||||||
),
|
),
|
||||||
>;
|
>;
|
||||||
|
|
||||||
@ -109,650 +102,16 @@ pub trait Engine: Sized + 'static + Clone {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Projective representation of an elliptic curve point guaranteed to be
|
/// Affine representation of an elliptic curve point that can be used
|
||||||
/// in the correct prime order subgroup.
|
/// to perform pairings.
|
||||||
pub trait CurveProjective:
|
pub trait PairingCurveAffine: CurveAffine {
|
||||||
PartialEq
|
|
||||||
+ Eq
|
|
||||||
+ Sized
|
|
||||||
+ Copy
|
|
||||||
+ Clone
|
|
||||||
+ Send
|
|
||||||
+ Sync
|
|
||||||
+ fmt::Debug
|
|
||||||
+ fmt::Display
|
|
||||||
+ rand::Rand
|
|
||||||
+ 'static
|
|
||||||
{
|
|
||||||
type Engine: Engine<Fr = Self::Scalar>;
|
|
||||||
type Scalar: PrimeField + SqrtField;
|
|
||||||
type Base: SqrtField;
|
|
||||||
type Affine: CurveAffine<Projective = Self, Scalar = Self::Scalar>;
|
|
||||||
|
|
||||||
/// Returns the additive identity.
|
|
||||||
fn zero() -> Self;
|
|
||||||
|
|
||||||
/// Returns a fixed generator of unknown exponent.
|
|
||||||
fn one() -> Self;
|
|
||||||
|
|
||||||
/// Determines if this point is the point at infinity.
|
|
||||||
fn is_zero(&self) -> bool;
|
|
||||||
|
|
||||||
/// Normalizes a slice of projective elements so that
|
|
||||||
/// conversion to affine is cheap.
|
|
||||||
fn batch_normalization(v: &mut [Self]);
|
|
||||||
|
|
||||||
/// Checks if the point is already "normalized" so that
|
|
||||||
/// cheap affine conversion is possible.
|
|
||||||
fn is_normalized(&self) -> bool;
|
|
||||||
|
|
||||||
/// Doubles this element.
|
|
||||||
fn double(&mut self);
|
|
||||||
|
|
||||||
/// Adds another element to this element.
|
|
||||||
fn add_assign(&mut self, other: &Self);
|
|
||||||
|
|
||||||
/// Subtracts another element from this element.
|
|
||||||
fn sub_assign(&mut self, other: &Self) {
|
|
||||||
let mut tmp = *other;
|
|
||||||
tmp.negate();
|
|
||||||
self.add_assign(&tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds an affine element to this element.
|
|
||||||
fn add_assign_mixed(&mut self, other: &Self::Affine);
|
|
||||||
|
|
||||||
/// Negates this element.
|
|
||||||
fn negate(&mut self);
|
|
||||||
|
|
||||||
/// Performs scalar multiplication of this element.
|
|
||||||
fn mul_assign<S: Into<<Self::Scalar as PrimeField>::Repr>>(&mut self, other: S);
|
|
||||||
|
|
||||||
/// Converts this element into its affine representation.
|
|
||||||
fn into_affine(&self) -> Self::Affine;
|
|
||||||
|
|
||||||
/// Recommends a wNAF window table size given a scalar. Always returns a number
|
|
||||||
/// between 2 and 22, inclusive.
|
|
||||||
fn recommended_wnaf_for_scalar(scalar: <Self::Scalar as PrimeField>::Repr) -> usize;
|
|
||||||
|
|
||||||
/// Recommends a wNAF window size given the number of scalars you intend to multiply
|
|
||||||
/// a base by. Always returns a number between 2 and 22, inclusive.
|
|
||||||
fn recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Affine representation of an elliptic curve point guaranteed to be
|
|
||||||
/// in the correct prime order subgroup.
|
|
||||||
pub trait CurveAffine:
|
|
||||||
Copy + Clone + Sized + Send + Sync + fmt::Debug + fmt::Display + PartialEq + Eq + 'static
|
|
||||||
{
|
|
||||||
type Engine: Engine<Fr = Self::Scalar>;
|
|
||||||
type Scalar: PrimeField + SqrtField;
|
|
||||||
type Base: SqrtField;
|
|
||||||
type Projective: CurveProjective<Affine = Self, Scalar = Self::Scalar>;
|
|
||||||
type Prepared: Clone + Send + Sync + 'static;
|
type Prepared: Clone + Send + Sync + 'static;
|
||||||
type Uncompressed: EncodedPoint<Affine = Self>;
|
type Pair: PairingCurveAffine<Pair = Self>;
|
||||||
type Compressed: EncodedPoint<Affine = Self>;
|
|
||||||
type Pair: CurveAffine<Pair = Self>;
|
|
||||||
type PairingResult: Field;
|
type PairingResult: Field;
|
||||||
|
|
||||||
/// Returns the additive identity.
|
|
||||||
fn zero() -> Self;
|
|
||||||
|
|
||||||
/// Returns a fixed generator of unknown exponent.
|
|
||||||
fn one() -> Self;
|
|
||||||
|
|
||||||
/// Determines if this point represents the point at infinity; the
|
|
||||||
/// additive identity.
|
|
||||||
fn is_zero(&self) -> bool;
|
|
||||||
|
|
||||||
/// Negates this element.
|
|
||||||
fn negate(&mut self);
|
|
||||||
|
|
||||||
/// Performs scalar multiplication of this element with mixed addition.
|
|
||||||
fn mul<S: Into<<Self::Scalar as PrimeField>::Repr>>(&self, other: S) -> Self::Projective;
|
|
||||||
|
|
||||||
/// Prepares this element for pairing purposes.
|
/// Prepares this element for pairing purposes.
|
||||||
fn prepare(&self) -> Self::Prepared;
|
fn prepare(&self) -> Self::Prepared;
|
||||||
|
|
||||||
/// Perform a pairing
|
/// Perform a pairing
|
||||||
fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult;
|
fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult;
|
||||||
|
|
||||||
/// Converts this element into its affine representation.
|
|
||||||
fn into_projective(&self) -> Self::Projective;
|
|
||||||
|
|
||||||
/// Converts this element into its compressed encoding, so long as it's not
|
|
||||||
/// the point at infinity.
|
|
||||||
fn into_compressed(&self) -> Self::Compressed {
|
|
||||||
<Self::Compressed as EncodedPoint>::from_affine(*self)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Converts this element into its uncompressed encoding, so long as it's not
|
|
||||||
/// the point at infinity.
|
|
||||||
fn into_uncompressed(&self) -> Self::Uncompressed {
|
|
||||||
<Self::Uncompressed as EncodedPoint>::from_affine(*self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An encoded elliptic curve point, which should essentially wrap a `[u8; N]`.
|
|
||||||
pub trait EncodedPoint:
|
|
||||||
Sized + Send + Sync + AsRef<[u8]> + AsMut<[u8]> + Clone + Copy + 'static
|
|
||||||
{
|
|
||||||
type Affine: CurveAffine;
|
|
||||||
|
|
||||||
/// Creates an empty representation.
|
|
||||||
fn empty() -> Self;
|
|
||||||
|
|
||||||
/// Returns the number of bytes consumed by this representation.
|
|
||||||
fn size() -> usize;
|
|
||||||
|
|
||||||
/// Converts an `EncodedPoint` into a `CurveAffine` element,
|
|
||||||
/// if the encoding represents a valid element.
|
|
||||||
fn into_affine(&self) -> Result<Self::Affine, GroupDecodingError>;
|
|
||||||
|
|
||||||
/// Converts an `EncodedPoint` into a `CurveAffine` element,
|
|
||||||
/// without guaranteeing that the encoding represents a valid
|
|
||||||
/// element. This is useful when the caller knows the encoding is
|
|
||||||
/// valid already.
|
|
||||||
///
|
|
||||||
/// If the encoding is invalid, this can break API invariants,
|
|
||||||
/// so caution is strongly encouraged.
|
|
||||||
fn into_affine_unchecked(&self) -> Result<Self::Affine, GroupDecodingError>;
|
|
||||||
|
|
||||||
/// Creates an `EncodedPoint` from an affine point, as long as the
|
|
||||||
/// point is not the point at infinity.
|
|
||||||
fn from_affine(affine: Self::Affine) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This trait represents an element of a field.
|
|
||||||
pub trait Field:
|
|
||||||
Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display + 'static + rand::Rand
|
|
||||||
{
|
|
||||||
/// Returns the zero element of the field, the additive identity.
|
|
||||||
fn zero() -> Self;
|
|
||||||
|
|
||||||
/// Returns the one element of the field, the multiplicative identity.
|
|
||||||
fn one() -> Self;
|
|
||||||
|
|
||||||
/// Returns true iff this element is zero.
|
|
||||||
fn is_zero(&self) -> bool;
|
|
||||||
|
|
||||||
/// Squares this element.
|
|
||||||
fn square(&mut self);
|
|
||||||
|
|
||||||
/// Doubles this element.
|
|
||||||
fn double(&mut self);
|
|
||||||
|
|
||||||
/// Negates this element.
|
|
||||||
fn negate(&mut self);
|
|
||||||
|
|
||||||
/// Adds another element to this element.
|
|
||||||
fn add_assign(&mut self, other: &Self);
|
|
||||||
|
|
||||||
/// Subtracts another element from this element.
|
|
||||||
fn sub_assign(&mut self, other: &Self);
|
|
||||||
|
|
||||||
/// Multiplies another element by this element.
|
|
||||||
fn mul_assign(&mut self, other: &Self);
|
|
||||||
|
|
||||||
/// Computes the multiplicative inverse of this element, if nonzero.
|
|
||||||
fn inverse(&self) -> Option<Self>;
|
|
||||||
|
|
||||||
/// Exponentiates this element by a power of the base prime modulus via
|
|
||||||
/// the Frobenius automorphism.
|
|
||||||
fn frobenius_map(&mut self, power: usize);
|
|
||||||
|
|
||||||
/// Exponentiates this element by a number represented with `u64` limbs,
|
|
||||||
/// least significant digit first.
|
|
||||||
fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
|
|
||||||
let mut res = Self::one();
|
|
||||||
|
|
||||||
let mut found_one = false;
|
|
||||||
|
|
||||||
for i in BitIterator::new(exp) {
|
|
||||||
if found_one {
|
|
||||||
res.square();
|
|
||||||
} else {
|
|
||||||
found_one = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if i {
|
|
||||||
res.mul_assign(self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This trait represents an element of a field that has a square root operation described for it.
|
|
||||||
pub trait SqrtField: Field {
|
|
||||||
/// Returns the Legendre symbol of the field element.
|
|
||||||
fn legendre(&self) -> LegendreSymbol;
|
|
||||||
|
|
||||||
/// Returns the square root of the field element, if it is
|
|
||||||
/// quadratic residue.
|
|
||||||
fn sqrt(&self) -> Option<Self>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This trait represents a wrapper around a biginteger which can encode any element of a particular
|
|
||||||
/// prime field. It is a smart wrapper around a sequence of `u64` limbs, least-significant digit
|
|
||||||
/// first.
|
|
||||||
pub trait PrimeFieldRepr:
|
|
||||||
Sized
|
|
||||||
+ Copy
|
|
||||||
+ Clone
|
|
||||||
+ Eq
|
|
||||||
+ Ord
|
|
||||||
+ Send
|
|
||||||
+ Sync
|
|
||||||
+ Default
|
|
||||||
+ fmt::Debug
|
|
||||||
+ fmt::Display
|
|
||||||
+ 'static
|
|
||||||
+ rand::Rand
|
|
||||||
+ AsRef<[u64]>
|
|
||||||
+ AsMut<[u64]>
|
|
||||||
+ From<u64>
|
|
||||||
{
|
|
||||||
/// Subtract another represetation from this one.
|
|
||||||
fn sub_noborrow(&mut self, other: &Self);
|
|
||||||
|
|
||||||
/// Add another representation to this one.
|
|
||||||
fn add_nocarry(&mut self, other: &Self);
|
|
||||||
|
|
||||||
/// Compute the number of bits needed to encode this number. Always a
|
|
||||||
/// multiple of 64.
|
|
||||||
fn num_bits(&self) -> u32;
|
|
||||||
|
|
||||||
/// Returns true iff this number is zero.
|
|
||||||
fn is_zero(&self) -> bool;
|
|
||||||
|
|
||||||
/// Returns true iff this number is odd.
|
|
||||||
fn is_odd(&self) -> bool;
|
|
||||||
|
|
||||||
/// Returns true iff this number is even.
|
|
||||||
fn is_even(&self) -> bool;
|
|
||||||
|
|
||||||
/// Performs a rightwise bitshift of this number, effectively dividing
|
|
||||||
/// it by 2.
|
|
||||||
fn div2(&mut self);
|
|
||||||
|
|
||||||
/// Performs a rightwise bitshift of this number by some amount.
|
|
||||||
fn shr(&mut self, amt: u32);
|
|
||||||
|
|
||||||
/// Performs a leftwise bitshift of this number, effectively multiplying
|
|
||||||
/// it by 2. Overflow is ignored.
|
|
||||||
fn mul2(&mut self);
|
|
||||||
|
|
||||||
/// Performs a leftwise bitshift of this number by some amount.
|
|
||||||
fn shl(&mut self, amt: u32);
|
|
||||||
|
|
||||||
/// Writes this `PrimeFieldRepr` as a big endian integer.
|
|
||||||
fn write_be<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
|
||||||
use byteorder::{BigEndian, WriteBytesExt};
|
|
||||||
|
|
||||||
for digit in self.as_ref().iter().rev() {
|
|
||||||
writer.write_u64::<BigEndian>(*digit)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a big endian integer into this representation.
|
|
||||||
fn read_be<R: Read>(&mut self, mut reader: R) -> io::Result<()> {
|
|
||||||
use byteorder::{BigEndian, ReadBytesExt};
|
|
||||||
|
|
||||||
for digit in self.as_mut().iter_mut().rev() {
|
|
||||||
*digit = reader.read_u64::<BigEndian>()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes this `PrimeFieldRepr` as a little endian integer.
|
|
||||||
fn write_le<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
|
||||||
use byteorder::{LittleEndian, WriteBytesExt};
|
|
||||||
|
|
||||||
for digit in self.as_ref().iter() {
|
|
||||||
writer.write_u64::<LittleEndian>(*digit)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a little endian integer into this representation.
|
|
||||||
fn read_le<R: Read>(&mut self, mut reader: R) -> io::Result<()> {
|
|
||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
|
||||||
|
|
||||||
for digit in self.as_mut().iter_mut() {
|
|
||||||
*digit = reader.read_u64::<LittleEndian>()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub enum LegendreSymbol {
|
|
||||||
Zero = 0,
|
|
||||||
QuadraticResidue = 1,
|
|
||||||
QuadraticNonResidue = -1,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error that may occur when trying to interpret a `PrimeFieldRepr` as a
|
|
||||||
/// `PrimeField` element.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum PrimeFieldDecodingError {
|
|
||||||
/// The encoded value is not in the field
|
|
||||||
NotInField(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for PrimeFieldDecodingError {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
match *self {
|
|
||||||
PrimeFieldDecodingError::NotInField(..) => "not an element of the field",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for PrimeFieldDecodingError {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
||||||
match *self {
|
|
||||||
PrimeFieldDecodingError::NotInField(ref repr) => {
|
|
||||||
write!(f, "{} is not an element of the field", repr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error that may occur when trying to decode an `EncodedPoint`.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum GroupDecodingError {
|
|
||||||
/// The coordinate(s) do not lie on the curve.
|
|
||||||
NotOnCurve,
|
|
||||||
/// The element is not part of the r-order subgroup.
|
|
||||||
NotInSubgroup,
|
|
||||||
/// One of the coordinates could not be decoded
|
|
||||||
CoordinateDecodingError(&'static str, PrimeFieldDecodingError),
|
|
||||||
/// The compression mode of the encoded element was not as expected
|
|
||||||
UnexpectedCompressionMode,
|
|
||||||
/// The encoding contained bits that should not have been set
|
|
||||||
UnexpectedInformation,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for GroupDecodingError {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
match *self {
|
|
||||||
GroupDecodingError::NotOnCurve => "coordinate(s) do not lie on the curve",
|
|
||||||
GroupDecodingError::NotInSubgroup => "the element is not part of an r-order subgroup",
|
|
||||||
GroupDecodingError::CoordinateDecodingError(..) => "coordinate(s) could not be decoded",
|
|
||||||
GroupDecodingError::UnexpectedCompressionMode => {
|
|
||||||
"encoding has unexpected compression mode"
|
|
||||||
}
|
|
||||||
GroupDecodingError::UnexpectedInformation => "encoding has unexpected information",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for GroupDecodingError {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
||||||
match *self {
|
|
||||||
GroupDecodingError::CoordinateDecodingError(description, ref err) => {
|
|
||||||
write!(f, "{} decoding error: {}", description, err)
|
|
||||||
}
|
|
||||||
_ => write!(f, "{}", self.description()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This represents an element of a prime field.
|
|
||||||
pub trait PrimeField: Field {
|
|
||||||
/// The prime field can be converted back and forth into this biginteger
|
|
||||||
/// representation.
|
|
||||||
type Repr: PrimeFieldRepr + From<Self>;
|
|
||||||
|
|
||||||
/// Interpret a string of numbers as a (congruent) prime field element.
|
|
||||||
/// Does not accept unnecessary leading zeroes or a blank string.
|
|
||||||
fn from_str(s: &str) -> Option<Self> {
|
|
||||||
if s.is_empty() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
if s == "0" {
|
|
||||||
return Some(Self::zero());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut res = Self::zero();
|
|
||||||
|
|
||||||
let ten = Self::from_repr(Self::Repr::from(10)).unwrap();
|
|
||||||
|
|
||||||
let mut first_digit = true;
|
|
||||||
|
|
||||||
for c in s.chars() {
|
|
||||||
match c.to_digit(10) {
|
|
||||||
Some(c) => {
|
|
||||||
if first_digit {
|
|
||||||
if c == 0 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
first_digit = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.mul_assign(&ten);
|
|
||||||
res.add_assign(&Self::from_repr(Self::Repr::from(u64::from(c))).unwrap());
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert this prime field element into a biginteger representation.
|
|
||||||
fn from_repr(Self::Repr) -> Result<Self, PrimeFieldDecodingError>;
|
|
||||||
|
|
||||||
/// Convert a biginteger representation into a prime field element, if
|
|
||||||
/// the number is an element of the field.
|
|
||||||
fn into_repr(&self) -> Self::Repr;
|
|
||||||
|
|
||||||
/// Returns the field characteristic; the modulus.
|
|
||||||
fn char() -> Self::Repr;
|
|
||||||
|
|
||||||
/// How many bits are needed to represent an element of this field.
|
|
||||||
const NUM_BITS: u32;
|
|
||||||
|
|
||||||
/// How many bits of information can be reliably stored in the field element.
|
|
||||||
const CAPACITY: u32;
|
|
||||||
|
|
||||||
/// Returns the multiplicative generator of `char()` - 1 order. This element
|
|
||||||
/// must also be quadratic nonresidue.
|
|
||||||
fn multiplicative_generator() -> Self;
|
|
||||||
|
|
||||||
/// 2^s * t = `char()` - 1 with t odd.
|
|
||||||
const S: u32;
|
|
||||||
|
|
||||||
/// Returns the 2^s root of unity computed by exponentiating the `multiplicative_generator()`
|
|
||||||
/// by t.
|
|
||||||
fn root_of_unity() -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct BitIterator<E> {
|
|
||||||
t: E,
|
|
||||||
n: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: AsRef<[u64]>> BitIterator<E> {
|
|
||||||
pub fn new(t: E) -> Self {
|
|
||||||
let n = t.as_ref().len() * 64;
|
|
||||||
|
|
||||||
BitIterator { t, n }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: AsRef<[u64]>> Iterator for BitIterator<E> {
|
|
||||||
type Item = bool;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<bool> {
|
|
||||||
if self.n == 0 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
self.n -= 1;
|
|
||||||
let part = self.n / 64;
|
|
||||||
let bit = self.n - (64 * part);
|
|
||||||
|
|
||||||
Some(self.t.as_ref()[part] & (1 << bit) > 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_bit_iterator() {
|
|
||||||
let mut a = BitIterator::new([0xa953d79b83f6ab59, 0x6dea2059e200bd39]);
|
|
||||||
let expected = "01101101111010100010000001011001111000100000000010111101001110011010100101010011110101111001101110000011111101101010101101011001";
|
|
||||||
|
|
||||||
for e in expected.chars() {
|
|
||||||
assert!(a.next().unwrap() == (e == '1'));
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(a.next().is_none());
|
|
||||||
|
|
||||||
let expected = "1010010101111110101010000101101011101000011101110101001000011001100100100011011010001011011011010001011011101100110100111011010010110001000011110100110001100110011101101000101100011100100100100100001010011101010111110011101011000011101000111011011101011001";
|
|
||||||
|
|
||||||
let mut a = BitIterator::new([
|
|
||||||
0x429d5f3ac3a3b759,
|
|
||||||
0xb10f4c66768b1c92,
|
|
||||||
0x92368b6d16ecd3b4,
|
|
||||||
0xa57ea85ae8775219,
|
|
||||||
]);
|
|
||||||
|
|
||||||
for e in expected.chars() {
|
|
||||||
assert!(a.next().unwrap() == (e == '1'));
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(a.next().is_none());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "expose-arith"))]
|
|
||||||
use self::arith_impl::*;
|
|
||||||
|
|
||||||
#[cfg(feature = "expose-arith")]
|
|
||||||
pub use self::arith_impl::*;
|
|
||||||
|
|
||||||
#[cfg(feature = "u128-support")]
|
|
||||||
mod arith_impl {
|
|
||||||
/// Calculate a - b - borrow, returning the result and modifying
|
|
||||||
/// the borrow value.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn sbb(a: u64, b: u64, borrow: &mut u64) -> u64 {
|
|
||||||
let tmp = (1u128 << 64) + u128::from(a) - u128::from(b) - u128::from(*borrow);
|
|
||||||
|
|
||||||
*borrow = if tmp >> 64 == 0 { 1 } else { 0 };
|
|
||||||
|
|
||||||
tmp as u64
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate a + b + carry, returning the sum and modifying the
|
|
||||||
/// carry value.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn adc(a: u64, b: u64, carry: &mut u64) -> u64 {
|
|
||||||
let tmp = u128::from(a) + u128::from(b) + u128::from(*carry);
|
|
||||||
|
|
||||||
*carry = (tmp >> 64) as u64;
|
|
||||||
|
|
||||||
tmp as u64
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate a + (b * c) + carry, returning the least significant digit
|
|
||||||
/// and setting carry to the most significant digit.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn mac_with_carry(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
|
|
||||||
let tmp = (u128::from(a)) + u128::from(b) * u128::from(c) + u128::from(*carry);
|
|
||||||
|
|
||||||
*carry = (tmp >> 64) as u64;
|
|
||||||
|
|
||||||
tmp as u64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "u128-support"))]
|
|
||||||
mod arith_impl {
|
|
||||||
#[inline(always)]
|
|
||||||
fn split_u64(i: u64) -> (u64, u64) {
|
|
||||||
(i >> 32, i & 0xFFFFFFFF)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn combine_u64(hi: u64, lo: u64) -> u64 {
|
|
||||||
(hi << 32) | lo
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate a - b - borrow, returning the result and modifying
|
|
||||||
/// the borrow value.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn sbb(a: u64, b: u64, borrow: &mut u64) -> u64 {
|
|
||||||
let (a_hi, a_lo) = split_u64(a);
|
|
||||||
let (b_hi, b_lo) = split_u64(b);
|
|
||||||
let (b, r0) = split_u64((1 << 32) + a_lo - b_lo - *borrow);
|
|
||||||
let (b, r1) = split_u64((1 << 32) + a_hi - b_hi - ((b == 0) as u64));
|
|
||||||
|
|
||||||
*borrow = (b == 0) as u64;
|
|
||||||
|
|
||||||
combine_u64(r1, r0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate a + b + carry, returning the sum and modifying the
|
|
||||||
/// carry value.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn adc(a: u64, b: u64, carry: &mut u64) -> u64 {
|
|
||||||
let (a_hi, a_lo) = split_u64(a);
|
|
||||||
let (b_hi, b_lo) = split_u64(b);
|
|
||||||
let (carry_hi, carry_lo) = split_u64(*carry);
|
|
||||||
|
|
||||||
let (t, r0) = split_u64(a_lo + b_lo + carry_lo);
|
|
||||||
let (t, r1) = split_u64(t + a_hi + b_hi + carry_hi);
|
|
||||||
|
|
||||||
*carry = t;
|
|
||||||
|
|
||||||
combine_u64(r1, r0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate a + (b * c) + carry, returning the least significant digit
|
|
||||||
/// and setting carry to the most significant digit.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn mac_with_carry(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
|
|
||||||
/*
|
|
||||||
[ b_hi | b_lo ]
|
|
||||||
[ c_hi | c_lo ] *
|
|
||||||
-------------------------------------------
|
|
||||||
[ b_lo * c_lo ] <-- w
|
|
||||||
[ b_hi * c_lo ] <-- x
|
|
||||||
[ b_lo * c_hi ] <-- y
|
|
||||||
[ b_hi * c_lo ] <-- z
|
|
||||||
[ a_hi | a_lo ]
|
|
||||||
[ C_hi | C_lo ]
|
|
||||||
*/
|
|
||||||
|
|
||||||
let (a_hi, a_lo) = split_u64(a);
|
|
||||||
let (b_hi, b_lo) = split_u64(b);
|
|
||||||
let (c_hi, c_lo) = split_u64(c);
|
|
||||||
let (carry_hi, carry_lo) = split_u64(*carry);
|
|
||||||
|
|
||||||
let (w_hi, w_lo) = split_u64(b_lo * c_lo);
|
|
||||||
let (x_hi, x_lo) = split_u64(b_hi * c_lo);
|
|
||||||
let (y_hi, y_lo) = split_u64(b_lo * c_hi);
|
|
||||||
let (z_hi, z_lo) = split_u64(b_hi * c_hi);
|
|
||||||
|
|
||||||
let (t, r0) = split_u64(w_lo + a_lo + carry_lo);
|
|
||||||
let (t, r1) = split_u64(t + w_hi + x_lo + y_lo + a_hi + carry_hi);
|
|
||||||
let (t, r2) = split_u64(t + x_hi + y_hi + z_lo);
|
|
||||||
let (_, r3) = split_u64(t + z_hi);
|
|
||||||
|
|
||||||
*carry = combine_u64(r3, r2);
|
|
||||||
|
|
||||||
combine_u64(r1, r0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
use group::{CurveAffine, CurveProjective};
|
||||||
use rand::{Rand, SeedableRng, XorShiftRng};
|
use rand::{Rand, SeedableRng, XorShiftRng};
|
||||||
|
|
||||||
use {CurveAffine, CurveProjective, Engine, Field, PrimeField};
|
use {Engine, Field, PairingCurveAffine, PrimeField};
|
||||||
|
|
||||||
pub fn engine_tests<E: Engine>() {
|
pub fn engine_tests<E: Engine>() {
|
||||||
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
use ff::{Field, LegendreSymbol, PrimeField, SqrtField};
|
||||||
use rand::{Rng, SeedableRng, XorShiftRng};
|
use rand::{Rng, SeedableRng, XorShiftRng};
|
||||||
use {Field, LegendreSymbol, PrimeField, SqrtField};
|
|
||||||
|
|
||||||
pub fn random_frobenius_tests<F: Field, C: AsRef<[u64]>>(characteristic: C, maxpower: usize) {
|
pub fn random_frobenius_tests<F: Field, C: AsRef<[u64]>>(characteristic: C, maxpower: usize) {
|
||||||
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
pub mod curve;
|
|
||||||
pub mod engine;
|
pub mod engine;
|
||||||
pub mod field;
|
pub mod field;
|
||||||
pub mod repr;
|
pub mod repr;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
use ff::PrimeFieldRepr;
|
||||||
use rand::{SeedableRng, XorShiftRng};
|
use rand::{SeedableRng, XorShiftRng};
|
||||||
use PrimeFieldRepr;
|
|
||||||
|
|
||||||
pub fn random_repr_tests<R: PrimeFieldRepr>() {
|
pub fn random_repr_tests<R: PrimeFieldRepr>() {
|
||||||
random_encoding_tests::<R>();
|
random_encoding_tests::<R>();
|
||||||
|
@ -14,6 +14,7 @@ features = ["expose-arith"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bellman = { path = "../bellman" }
|
bellman = { path = "../bellman" }
|
||||||
|
ff = { path = "../ff" }
|
||||||
rand = "0.4"
|
rand = "0.4"
|
||||||
digest = "0.7"
|
digest = "0.7"
|
||||||
byteorder = "1"
|
byteorder = "1"
|
||||||
@ -25,7 +26,3 @@ rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9"
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hex-literal = "0.1"
|
hex-literal = "0.1"
|
||||||
rust-crypto = "0.2"
|
rust-crypto = "0.2"
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["u128-support"]
|
|
||||||
u128-support = ["pairing/u128-support"]
|
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
use pairing::{
|
use ff::{BitIterator, Field, PrimeField};
|
||||||
Engine,
|
use pairing::Engine;
|
||||||
Field,
|
|
||||||
PrimeField,
|
|
||||||
BitIterator
|
|
||||||
};
|
|
||||||
|
|
||||||
use bellman::{
|
use bellman::{
|
||||||
ConstraintSystem,
|
ConstraintSystem,
|
||||||
@ -806,8 +802,8 @@ impl From<AllocatedBit> for Boolean {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use bellman::{ConstraintSystem};
|
use bellman::{ConstraintSystem};
|
||||||
|
use ff::{Field, PrimeField};
|
||||||
use pairing::bls12_381::{Bls12, Fr};
|
use pairing::bls12_381::{Bls12, Fr};
|
||||||
use pairing::{Field, PrimeField};
|
|
||||||
use ::circuit::test::*;
|
use ::circuit::test::*;
|
||||||
use super::{
|
use super::{
|
||||||
AllocatedBit,
|
AllocatedBit,
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
use pairing::{
|
use ff::Field;
|
||||||
Engine,
|
use pairing::Engine;
|
||||||
Field
|
|
||||||
};
|
|
||||||
|
|
||||||
use bellman::{
|
use bellman::{
|
||||||
SynthesisError,
|
SynthesisError,
|
||||||
@ -751,8 +749,8 @@ impl<E: JubjubEngine> MontgomeryPoint<E> {
|
|||||||
mod test {
|
mod test {
|
||||||
use bellman::{ConstraintSystem};
|
use bellman::{ConstraintSystem};
|
||||||
use rand::{XorShiftRng, SeedableRng, Rand, Rng};
|
use rand::{XorShiftRng, SeedableRng, Rand, Rng};
|
||||||
|
use ff::{BitIterator, Field, PrimeField};
|
||||||
use pairing::bls12_381::{Bls12, Fr};
|
use pairing::bls12_381::{Bls12, Fr};
|
||||||
use pairing::{BitIterator, Field, PrimeField};
|
|
||||||
use ::circuit::test::*;
|
use ::circuit::test::*;
|
||||||
use ::jubjub::{
|
use ::jubjub::{
|
||||||
montgomery,
|
montgomery,
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
use pairing::{Engine, Field};
|
use ff::Field;
|
||||||
|
use pairing::Engine;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::num::{
|
use super::num::{
|
||||||
AllocatedNum,
|
AllocatedNum,
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
use pairing::{
|
use ff::{Field, PrimeField};
|
||||||
Engine,
|
use pairing::Engine;
|
||||||
Field,
|
|
||||||
PrimeField
|
|
||||||
};
|
|
||||||
|
|
||||||
use bellman::{
|
use bellman::{
|
||||||
SynthesisError,
|
SynthesisError,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use pairing::{Engine, Field, PrimeField};
|
use ff::{Field, PrimeField};
|
||||||
|
use pairing::Engine;
|
||||||
use bellman::{ConstraintSystem, SynthesisError};
|
use bellman::{ConstraintSystem, SynthesisError};
|
||||||
use super::boolean::{Boolean};
|
use super::boolean::{Boolean};
|
||||||
use super::num::Num;
|
use super::num::Num;
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
use pairing::{
|
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr};
|
||||||
Engine,
|
use pairing::Engine;
|
||||||
Field,
|
|
||||||
PrimeField,
|
|
||||||
PrimeFieldRepr,
|
|
||||||
BitIterator
|
|
||||||
};
|
|
||||||
|
|
||||||
use bellman::{
|
use bellman::{
|
||||||
SynthesisError,
|
SynthesisError,
|
||||||
@ -462,8 +457,8 @@ impl<E: Engine> Num<E> {
|
|||||||
mod test {
|
mod test {
|
||||||
use rand::{SeedableRng, Rand, Rng, XorShiftRng};
|
use rand::{SeedableRng, Rand, Rng, XorShiftRng};
|
||||||
use bellman::{ConstraintSystem};
|
use bellman::{ConstraintSystem};
|
||||||
|
use ff::{BitIterator, Field, PrimeField};
|
||||||
use pairing::bls12_381::{Bls12, Fr};
|
use pairing::bls12_381::{Bls12, Fr};
|
||||||
use pairing::{Field, PrimeField, BitIterator};
|
|
||||||
use ::circuit::test::*;
|
use ::circuit::test::*;
|
||||||
use super::{AllocatedNum, Boolean};
|
use super::{AllocatedNum, Boolean};
|
||||||
|
|
||||||
|
@ -116,8 +116,8 @@ mod test {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use ::circuit::test::*;
|
use ::circuit::test::*;
|
||||||
use ::circuit::boolean::{Boolean, AllocatedBit};
|
use ::circuit::boolean::{Boolean, AllocatedBit};
|
||||||
|
use ff::PrimeField;
|
||||||
use pairing::bls12_381::{Bls12, Fr};
|
use pairing::bls12_381::{Bls12, Fr};
|
||||||
use pairing::PrimeField;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_pedersen_hash_constraints() {
|
fn test_pedersen_hash_constraints() {
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
use pairing::{
|
use ff::{Field, PrimeField, PrimeFieldRepr};
|
||||||
PrimeField,
|
|
||||||
PrimeFieldRepr,
|
|
||||||
Field,
|
|
||||||
};
|
|
||||||
|
|
||||||
use bellman::{
|
use bellman::{
|
||||||
SynthesisError,
|
SynthesisError,
|
||||||
@ -602,7 +598,7 @@ impl<'a, E: JubjubEngine> Circuit<E> for Output<'a, E> {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_input_circuit_with_bls12_381() {
|
fn test_input_circuit_with_bls12_381() {
|
||||||
use pairing::{Field, BitIterator};
|
use ff::{BitIterator, Field};
|
||||||
use pairing::bls12_381::*;
|
use pairing::bls12_381::*;
|
||||||
use rand::{SeedableRng, Rng, XorShiftRng};
|
use rand::{SeedableRng, Rng, XorShiftRng};
|
||||||
use ::circuit::test::*;
|
use ::circuit::test::*;
|
||||||
@ -734,7 +730,7 @@ fn test_input_circuit_with_bls12_381() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_output_circuit_with_bls12_381() {
|
fn test_output_circuit_with_bls12_381() {
|
||||||
use pairing::{Field};
|
use ff::Field;
|
||||||
use pairing::bls12_381::*;
|
use pairing::bls12_381::*;
|
||||||
use rand::{SeedableRng, Rng, XorShiftRng};
|
use rand::{SeedableRng, Rng, XorShiftRng};
|
||||||
use ::circuit::test::*;
|
use ::circuit::test::*;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use pairing::{Engine, Field};
|
use ff::Field;
|
||||||
|
use pairing::Engine;
|
||||||
use bellman::{ConstraintSystem, SynthesisError, Circuit, LinearCombination};
|
use bellman::{ConstraintSystem, SynthesisError, Circuit, LinearCombination};
|
||||||
use circuit::boolean::{
|
use circuit::boolean::{
|
||||||
AllocatedBit,
|
AllocatedBit,
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
use pairing::{
|
use ff::{Field, PrimeField, PrimeFieldRepr};
|
||||||
Engine,
|
use pairing::Engine;
|
||||||
Field,
|
|
||||||
PrimeField,
|
|
||||||
PrimeFieldRepr
|
|
||||||
};
|
|
||||||
|
|
||||||
use bellman::{
|
use bellman::{
|
||||||
LinearCombination,
|
LinearCombination,
|
||||||
@ -445,8 +441,8 @@ impl<E: Engine> ConstraintSystem<E> for TestConstraintSystem<E> {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cs() {
|
fn test_cs() {
|
||||||
|
use ff::PrimeField;
|
||||||
use pairing::bls12_381::{Bls12, Fr};
|
use pairing::bls12_381::{Bls12, Fr};
|
||||||
use pairing::PrimeField;
|
|
||||||
|
|
||||||
let mut cs = TestConstraintSystem::<Bls12>::new();
|
let mut cs = TestConstraintSystem::<Bls12>::new();
|
||||||
assert!(cs.is_satisfied());
|
assert!(cs.is_satisfied());
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
use pairing::{
|
use ff::{Field, PrimeField};
|
||||||
Engine,
|
use pairing::Engine;
|
||||||
Field,
|
|
||||||
PrimeField
|
|
||||||
};
|
|
||||||
|
|
||||||
use bellman::{
|
use bellman::{
|
||||||
SynthesisError,
|
SynthesisError,
|
||||||
@ -415,8 +412,8 @@ mod test {
|
|||||||
use rand::{XorShiftRng, SeedableRng, Rng};
|
use rand::{XorShiftRng, SeedableRng, Rng};
|
||||||
use ::circuit::boolean::{Boolean};
|
use ::circuit::boolean::{Boolean};
|
||||||
use super::{UInt32};
|
use super::{UInt32};
|
||||||
|
use ff::Field;
|
||||||
use pairing::bls12_381::{Bls12};
|
use pairing::bls12_381::{Bls12};
|
||||||
use pairing::{Field};
|
|
||||||
use ::circuit::test::*;
|
use ::circuit::test::*;
|
||||||
use bellman::{ConstraintSystem};
|
use bellman::{ConstraintSystem};
|
||||||
use circuit::multieq::MultiEq;
|
use circuit::multieq::MultiEq;
|
||||||
|
@ -4,7 +4,7 @@ use jubjub::{
|
|||||||
edwards
|
edwards
|
||||||
};
|
};
|
||||||
|
|
||||||
use pairing::{
|
use ff::{
|
||||||
PrimeField
|
PrimeField
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
use pairing::{
|
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField};
|
||||||
Field,
|
|
||||||
SqrtField,
|
|
||||||
PrimeField,
|
|
||||||
PrimeFieldRepr,
|
|
||||||
BitIterator
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
JubjubEngine,
|
JubjubEngine,
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use pairing::{BitIterator, Field, PrimeField, SqrtField, PrimeFieldRepr, PrimeFieldDecodingError, LegendreSymbol};
|
use ff::{
|
||||||
use pairing::LegendreSymbol::*;
|
adc, mac_with_carry, sbb, BitIterator, Field,
|
||||||
use pairing::{adc, sbb, mac_with_carry};
|
LegendreSymbol::{self, *},
|
||||||
|
PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, SqrtField,
|
||||||
|
};
|
||||||
|
|
||||||
use super::ToUniform;
|
use super::ToUniform;
|
||||||
|
|
||||||
|
@ -17,12 +17,8 @@
|
|||||||
//! the Montgomery curve forms a group isomorphism, allowing points
|
//! the Montgomery curve forms a group isomorphism, allowing points
|
||||||
//! to be freely converted between the two forms.
|
//! to be freely converted between the two forms.
|
||||||
|
|
||||||
use pairing::{
|
use ff::{Field, PrimeField, SqrtField};
|
||||||
Engine,
|
use pairing::Engine;
|
||||||
Field,
|
|
||||||
PrimeField,
|
|
||||||
SqrtField
|
|
||||||
};
|
|
||||||
|
|
||||||
use group_hash::group_hash;
|
use group_hash::group_hash;
|
||||||
|
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
use pairing::{
|
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField};
|
||||||
Field,
|
|
||||||
SqrtField,
|
|
||||||
PrimeField,
|
|
||||||
PrimeFieldRepr,
|
|
||||||
BitIterator
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
JubjubEngine,
|
JubjubEngine,
|
||||||
|
@ -6,7 +6,7 @@ use super::{
|
|||||||
edwards
|
edwards
|
||||||
};
|
};
|
||||||
|
|
||||||
use pairing::{
|
use ff::{
|
||||||
Field,
|
Field,
|
||||||
PrimeField,
|
PrimeField,
|
||||||
PrimeFieldRepr,
|
PrimeFieldRepr,
|
||||||
|
@ -2,6 +2,7 @@ extern crate pairing;
|
|||||||
extern crate bellman;
|
extern crate bellman;
|
||||||
extern crate blake2_rfc;
|
extern crate blake2_rfc;
|
||||||
extern crate digest;
|
extern crate digest;
|
||||||
|
extern crate ff;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
use ff::{Field, PrimeField, PrimeFieldRepr};
|
||||||
use jubjub::*;
|
use jubjub::*;
|
||||||
use pairing::*;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum Personalization {
|
pub enum Personalization {
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
use pairing::{
|
use ff::{Field, PrimeField, PrimeFieldRepr};
|
||||||
Field,
|
|
||||||
PrimeField,
|
|
||||||
PrimeFieldRepr
|
|
||||||
};
|
|
||||||
|
|
||||||
use constants;
|
use constants;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Implementation of RedJubjub, a specialization of RedDSA to the Jubjub curve.
|
//! Implementation of RedJubjub, a specialization of RedDSA to the Jubjub curve.
|
||||||
//! See section 5.4.6 of the Sapling protocol specification.
|
//! See section 5.4.6 of the Sapling protocol specification.
|
||||||
|
|
||||||
use pairing::{Field, PrimeField, PrimeFieldRepr};
|
use ff::{Field, PrimeField, PrimeFieldRepr};
|
||||||
use rand::{Rng, Rand};
|
use rand::{Rng, Rand};
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ authors = [
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1"
|
byteorder = "1"
|
||||||
|
ff = { path = "../ff" }
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
pairing = { path = "../pairing" }
|
pairing = { path = "../pairing" }
|
||||||
rand = "0.4"
|
rand = "0.4"
|
||||||
|
@ -3,6 +3,7 @@ extern crate lazy_static;
|
|||||||
|
|
||||||
extern crate blake2_rfc;
|
extern crate blake2_rfc;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
extern crate ff;
|
||||||
extern crate pairing;
|
extern crate pairing;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate sapling_crypto;
|
extern crate sapling_crypto;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
use pairing::{
|
use ff::{PrimeField, PrimeFieldRepr};
|
||||||
bls12_381::{Bls12, Fr, FrRepr},
|
use pairing::bls12_381::{Bls12, Fr, FrRepr};
|
||||||
PrimeField, PrimeFieldRepr,
|
|
||||||
};
|
|
||||||
use sapling_crypto::{
|
use sapling_crypto::{
|
||||||
jubjub::{edwards, Unknown},
|
jubjub::{edwards, Unknown},
|
||||||
redjubjub::{PublicKey, Signature},
|
redjubjub::{PublicKey, Signature},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use blake2_rfc::blake2b::Blake2b;
|
use blake2_rfc::blake2b::Blake2b;
|
||||||
use byteorder::{LittleEndian, WriteBytesExt};
|
use byteorder::{LittleEndian, WriteBytesExt};
|
||||||
use pairing::{PrimeField, PrimeFieldRepr};
|
use ff::{PrimeField, PrimeFieldRepr};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
components::{Amount, Script, TxOut},
|
components::{Amount, Script, TxOut},
|
||||||
|
@ -8,6 +8,7 @@ authors = [
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
bellman = { path = "../bellman" }
|
bellman = { path = "../bellman" }
|
||||||
byteorder = "1"
|
byteorder = "1"
|
||||||
|
ff = { path = "../ff" }
|
||||||
pairing = { path = "../pairing" }
|
pairing = { path = "../pairing" }
|
||||||
rand = "0.4"
|
rand = "0.4"
|
||||||
sapling-crypto = { path = "../sapling-crypto" }
|
sapling-crypto = { path = "../sapling-crypto" }
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
extern crate bellman;
|
extern crate bellman;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
extern crate ff;
|
||||||
extern crate pairing;
|
extern crate pairing;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate sapling_crypto;
|
extern crate sapling_crypto;
|
||||||
|
@ -2,10 +2,8 @@ use bellman::groth16::{
|
|||||||
create_random_proof, verify_proof, Parameters, PreparedVerifyingKey, Proof,
|
create_random_proof, verify_proof, Parameters, PreparedVerifyingKey, Proof,
|
||||||
};
|
};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
use pairing::{
|
use ff::{Field, PrimeField, PrimeFieldRepr};
|
||||||
bls12_381::{Bls12, Fr, FrRepr},
|
use pairing::bls12_381::{Bls12, Fr, FrRepr};
|
||||||
Field, PrimeField, PrimeFieldRepr,
|
|
||||||
};
|
|
||||||
use rand::{OsRng, Rand};
|
use rand::{OsRng, Rand};
|
||||||
use sapling_crypto::{
|
use sapling_crypto::{
|
||||||
circuit::{
|
circuit::{
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
use bellman::groth16::{verify_proof, PreparedVerifyingKey, Proof};
|
use bellman::groth16::{verify_proof, PreparedVerifyingKey, Proof};
|
||||||
use pairing::{
|
use ff::Field;
|
||||||
bls12_381::{Bls12, Fr},
|
use pairing::bls12_381::{Bls12, Fr};
|
||||||
Field,
|
|
||||||
};
|
|
||||||
use sapling_crypto::{
|
use sapling_crypto::{
|
||||||
circuit::multipack,
|
circuit::multipack,
|
||||||
jubjub::{edwards, FixedGenerators, JubjubBls12, Unknown},
|
jubjub::{edwards, FixedGenerators, JubjubBls12, Unknown},
|
||||||
|
@ -14,6 +14,7 @@ repository = "https://github.com/zcash-hackworks/zip32"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
aes = "0.2"
|
aes = "0.2"
|
||||||
byteorder = "1"
|
byteorder = "1"
|
||||||
|
ff = { path = "../ff" }
|
||||||
fpe = "0.1"
|
fpe = "0.1"
|
||||||
lazy_static = "1.0"
|
lazy_static = "1.0"
|
||||||
pairing = { path = "../pairing" }
|
pairing = { path = "../pairing" }
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
extern crate aes;
|
extern crate aes;
|
||||||
extern crate blake2_rfc;
|
extern crate blake2_rfc;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
extern crate ff;
|
||||||
extern crate fpe;
|
extern crate fpe;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
@ -10,8 +11,9 @@ extern crate sapling_crypto;
|
|||||||
use aes::Aes256;
|
use aes::Aes256;
|
||||||
use blake2_rfc::blake2b::{Blake2b, Blake2bResult};
|
use blake2_rfc::blake2b::{Blake2b, Blake2bResult};
|
||||||
use byteorder::{ByteOrder, LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{ByteOrder, LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
|
use ff::{Field, PrimeField, PrimeFieldRepr};
|
||||||
use fpe::ff1::{BinaryNumeralString, FF1};
|
use fpe::ff1::{BinaryNumeralString, FF1};
|
||||||
use pairing::{bls12_381::Bls12, Field, PrimeField, PrimeFieldRepr};
|
use pairing::bls12_381::Bls12;
|
||||||
use sapling_crypto::{
|
use sapling_crypto::{
|
||||||
jubjub::{
|
jubjub::{
|
||||||
edwards, FixedGenerators, JubjubBls12, JubjubEngine, JubjubParams, ToUniform, Unknown,
|
edwards, FixedGenerators, JubjubBls12, JubjubEngine, JubjubParams, ToUniform, Unknown,
|
||||||
|
Loading…
Reference in New Issue
Block a user