implement sha256 on bellman, remove libsnark version
This commit is contained in:
parent
b3c432ae2f
commit
f8fa3efccf
18 changed files with 777 additions and 706 deletions
103
Cargo.lock
generated
103
Cargo.lock
generated
|
@ -70,7 +70,7 @@ name = "backtrace-sys"
|
|||
version = "0.1.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -149,7 +149,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.31"
|
||||
version = "1.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -184,10 +184,10 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.35"
|
||||
version = "0.1.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -295,6 +295,11 @@ dependencies = [
|
|||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.0.5"
|
||||
|
@ -317,10 +322,10 @@ name = "curl-sys"
|
|||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -331,6 +336,14 @@ name = "difference"
|
|||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.5.1"
|
||||
|
@ -400,6 +413,14 @@ dependencies = [
|
|||
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.8.0"
|
||||
|
@ -410,7 +431,7 @@ dependencies = [
|
|||
"libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -464,12 +485,12 @@ name = "libgit2-sys"
|
|||
version = "0.7.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"curl-sys 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -478,10 +499,10 @@ name = "libssh2-sys"
|
|||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -491,7 +512,7 @@ name = "libz-sys"
|
|||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -607,10 +628,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.42"
|
||||
version = "0.9.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -895,6 +916,21 @@ dependencies = [
|
|||
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sapling-crypto"
|
||||
version = "0.0.4"
|
||||
source = "git+https://github.com/matterinc/sapling-crypto?tag=0.0.4#6ac48e2f920bd54358b7a4cca0a96f87753009e4"
|
||||
dependencies = [
|
||||
"bellman 0.2.0 (git+https://github.com/matterinc/bellman?tag=0.2.0)",
|
||||
"blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)",
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "0.3.3"
|
||||
|
@ -1040,6 +1076,19 @@ dependencies = [
|
|||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-keccak"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-util"
|
||||
version = "0.1.3"
|
||||
|
@ -1167,8 +1216,8 @@ dependencies = [
|
|||
"bellman 0.2.0 (git+https://github.com/matterinc/bellman?tag=0.2.0)",
|
||||
"bimap 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cmake 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ff 0.5.0 (git+https://github.com/matterinc/ff?tag=0.5)",
|
||||
"git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1187,6 +1236,16 @@ dependencies = [
|
|||
"serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmi 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zokrates_embed 0.1.0",
|
||||
"zokrates_field 0.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zokrates_embed"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bellman 0.2.0 (git+https://github.com/matterinc/bellman?tag=0.2.0)",
|
||||
"sapling-crypto 0.0.4 (git+https://github.com/matterinc/sapling-crypto?tag=0.0.4)",
|
||||
"zokrates_field 0.3.2",
|
||||
]
|
||||
|
||||
|
@ -1245,11 +1304,11 @@ dependencies = [
|
|||
"checksum bytecount 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b92204551573580e078dc80017f36a213eb77a0450e4ddd8cfa0f3f2d1f0178f"
|
||||
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
|
||||
"checksum cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1b4d380e1bab994591a24c2bdd1b054f64b60bef483a8c598c7c345bc3bbe"
|
||||
"checksum cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d"
|
||||
"checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2"
|
||||
"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
|
||||
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
"checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a"
|
||||
"checksum cmake 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "c11b79fbf026d6ec02704f7248c6da99be02068bf57f624bb08af72ad29f2c06"
|
||||
"checksum colored 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e9a455e156a4271e12fd0246238c380b1e223e3736663c7a18ed8b6362028a9"
|
||||
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
|
||||
"checksum crossbeam 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b14492071ca110999a20bf90e3833406d5d66bfd93b4e52ec9539025ff43fe0d"
|
||||
|
@ -1261,10 +1320,12 @@ dependencies = [
|
|||
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
|
||||
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
|
||||
"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c"
|
||||
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
|
||||
"checksum csv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd1c44c58078cfbeaf11fbb3eac9ae5534c23004ed770cc4bfb48e658ae4f04"
|
||||
"checksum csv-core 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5cdef62f37e6ffe7d1f07a381bc0db32b7a3ff1cac0de56cb0d81e71f53d65"
|
||||
"checksum curl-sys 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)" = "7b8d8e51964f58c8053337fcef48e1c4608c7ee70c6f2e457674a97dda5a5828"
|
||||
"checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
|
||||
"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
|
||||
"checksum either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c67353c641dc847124ea1902d69bd753dee9bb3beff9aa3662ecf86c971d1fac"
|
||||
"checksum environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4b14e20978669064c33b4c1e0fb4083412e40fe56cbea2eae80fd7591503ee"
|
||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||
|
@ -1274,6 +1335,7 @@ dependencies = [
|
|||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b"
|
||||
"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
|
||||
"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
|
||||
"checksum git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7339329bfa14a00223244311560d11f8f489b453fb90092af97f267a6090ab0"
|
||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
@ -1301,7 +1363,7 @@ dependencies = [
|
|||
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
|
||||
"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
|
||||
"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
||||
"checksum openssl-sys 0.9.42 (registry+https://github.com/rust-lang/crates.io-index)" = "cb534d752bf98cf363b473950659ac2546517f9c6be9723771614ab3f03bbc9e"
|
||||
"checksum openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)" = "33c86834957dd5b915623e94f2f4ab2c70dd8f6b70679824155d5ae21dbd495d"
|
||||
"checksum pairing 0.16.2 (git+https://github.com/matterinc/pairing?tag=0.16.2)" = "<none>"
|
||||
"checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc"
|
||||
"checksum parity-wasm 0.35.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3e1e076c4e01399b6cd0793a8df42f90bba3ae424671ef421d1608a943155d93"
|
||||
|
@ -1335,6 +1397,7 @@ dependencies = [
|
|||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
|
||||
"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
|
||||
"checksum sapling-crypto 0.0.4 (git+https://github.com/matterinc/sapling-crypto?tag=0.0.4)" = "<none>"
|
||||
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||
"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"
|
||||
|
@ -1352,6 +1415,8 @@ dependencies = [
|
|||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
|
||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||
"checksum tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e9175261fbdb60781fcd388a4d6cc7e14764a2b629a7ad94abb439aed223a44f"
|
||||
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
||||
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
|
||||
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
||||
"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426"
|
||||
|
|
|
@ -5,4 +5,5 @@ members = [
|
|||
"zokrates_cli",
|
||||
"zokrates_fs_resolver",
|
||||
"zokrates_stdlib",
|
||||
"zokrates_embed",
|
||||
]
|
|
@ -29,6 +29,7 @@ bellman = { git = "https://github.com/matterinc/bellman", tag = "0.2.0" }
|
|||
pairing = { git = "https://github.com/matterinc/pairing", tag = "0.16.2" }
|
||||
ff = { git = 'https://github.com/matterinc/ff', features = ["derive"], tag = "0.5" }
|
||||
zokrates_field = { version = "0.3.0", path = "../zokrates_field" }
|
||||
zokrates_embed = { path = "../zokrates_embed" }
|
||||
rand = "0.4"
|
||||
wasmi = "0.4.2"
|
||||
parity-wasm = "0.35.3"
|
||||
|
|
|
@ -57,18 +57,6 @@ fn main() {
|
|||
.file("lib/pghr13.cpp")
|
||||
.compile("libwraplibsnark.a");
|
||||
|
||||
// build gadgets
|
||||
|
||||
cc::Build::new()
|
||||
.cpp(true)
|
||||
.flag("-std=c++11")
|
||||
.include(libsnark_source_path)
|
||||
.include(libsnark_source_path.join("depends/libff"))
|
||||
.include(libsnark_source_path.join("depends/libfqfft"))
|
||||
.define("CURVE_ALT_BN128", None)
|
||||
.file("lib/wraplibsnarkgadgets.cpp")
|
||||
.compile("libwraplibsnarkgadgets.a");
|
||||
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
libsnark.join("lib").display()
|
||||
|
|
|
@ -1,237 +0,0 @@
|
|||
//https://gist.github.com/kobigurk/24c25e68219df87c348f1a78db51bb52
|
||||
#include <iostream>
|
||||
|
||||
#include "wraplibsnarkgadgets.hpp"
|
||||
|
||||
#include "libsnark/gadgetlib1/gadget.hpp"
|
||||
#include "libsnark/gadgetlib1/protoboard.hpp"
|
||||
#include "libff/common/default_types/ec_pp.hpp"
|
||||
#include "libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.hpp"
|
||||
#include "libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp"
|
||||
|
||||
using namespace libsnark;
|
||||
using namespace libff;
|
||||
using std::vector;
|
||||
|
||||
|
||||
typedef libff::Fr<alt_bn128_pp> FieldT;
|
||||
|
||||
pb_variable_array<FieldT> from_bits(std::vector<bool> bits, pb_variable<FieldT>& ZERO)
|
||||
{
|
||||
pb_variable_array<FieldT> acc;
|
||||
|
||||
for (size_t i = 0; i < bits.size(); i++) {
|
||||
bool bit = bits[i];
|
||||
acc.emplace_back(bit ? ONE : ZERO);
|
||||
}
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
vector<unsigned long> bit_list_to_ints(vector<bool> bit_list, const size_t wordsize)
|
||||
{
|
||||
vector<unsigned long> res;
|
||||
size_t iterations = bit_list.size()/wordsize+1;
|
||||
for (size_t i = 0; i < iterations; ++i) {
|
||||
unsigned long current = 0;
|
||||
for (size_t j = 0; j < wordsize; ++j) {
|
||||
if (bit_list.size() == (i*wordsize+j)) break;
|
||||
current += (bit_list[i*wordsize+j] * (1ul<<(wordsize-1-j)));
|
||||
}
|
||||
res.push_back(current);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
// conversion byte[32] <-> libsnark bigint.
|
||||
libff::bigint<libff::alt_bn128_r_limbs> libsnarkBigintFromBytesAux(const uint8_t* _x)
|
||||
{
|
||||
libff::bigint<libff::alt_bn128_r_limbs> x;
|
||||
|
||||
for (unsigned i = 0; i < 4; i++) {
|
||||
for (unsigned j = 0; j < 8; j++) {
|
||||
x.data[3 - i] |= uint64_t(_x[i * 8 + j]) << (8 * (7-j));
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
void constraint_to_json(linear_combination<FieldT> constraints, std::stringstream &ss)
|
||||
{
|
||||
ss << "{";
|
||||
uint count = 0;
|
||||
for (const linear_term<FieldT>& lt : constraints.terms)
|
||||
{
|
||||
if (count != 0) {
|
||||
ss << ",";
|
||||
}
|
||||
|
||||
ss << '"' << lt.index << '"' << ":" << '"' << lt.coeff << '"';
|
||||
count++;
|
||||
}
|
||||
ss << "}";
|
||||
}
|
||||
|
||||
|
||||
std::string r1cs_to_json(protoboard<FieldT> pb)
|
||||
{
|
||||
r1cs_constraint_system<FieldT> constraints = pb.get_constraint_system();
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "{\"variable_count\":";
|
||||
ss << pb.num_variables() + 1; // ~one is not counted in pb.num_variables()
|
||||
ss << ",\"inputs\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768], \"outputs\":[769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024],\"constraints\":[";
|
||||
|
||||
for (size_t c = 0; c < constraints.num_constraints(); ++c)
|
||||
{
|
||||
ss << "[";// << "\"A\"=";
|
||||
constraint_to_json(constraints.constraints[c].a, ss);
|
||||
ss << ",";// << "\"B\"=";
|
||||
constraint_to_json(constraints.constraints[c].b, ss);
|
||||
ss << ",";// << "\"C\"=";;
|
||||
constraint_to_json(constraints.constraints[c].c, ss);
|
||||
if (c == constraints.num_constraints()-1 ) {
|
||||
ss << "]\n";
|
||||
} else {
|
||||
ss << "],\n";
|
||||
}
|
||||
}
|
||||
ss << "]}";
|
||||
ss.rdbuf()->pubseekpos(0, std::ios_base::out);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string array_to_json(protoboard<FieldT> pb)
|
||||
{
|
||||
std::stringstream ss;
|
||||
r1cs_variable_assignment<FieldT> values = pb.full_variable_assignment();
|
||||
ss << "{\"variables\":[";
|
||||
|
||||
ss << 1 << ","; // the variable zero to the one constant
|
||||
|
||||
for (size_t i = 0; i < values.size(); ++i)
|
||||
{
|
||||
ss << values[i].as_bigint();
|
||||
if (i < values.size() - 1) { ss << ",";}
|
||||
}
|
||||
|
||||
ss << "]}";
|
||||
|
||||
// std::cout << ss.rdbuf();
|
||||
|
||||
ss.rdbuf()->pubseekpos(0, std::ios_base::out);
|
||||
|
||||
return(ss.str());
|
||||
}
|
||||
|
||||
class sha256round: gadget<FieldT>
|
||||
{
|
||||
private:
|
||||
std::shared_ptr<block_variable<FieldT>> block;
|
||||
|
||||
public:
|
||||
std::shared_ptr<sha256_compression_function_gadget<FieldT>> hasher;
|
||||
sha256round(
|
||||
protoboard<FieldT> &pb,
|
||||
pb_variable_array<FieldT>& myIV,
|
||||
pb_variable_array<FieldT>& a,
|
||||
pb_variable_array<FieldT>& b,
|
||||
digest_variable<FieldT> &result
|
||||
) : gadget<FieldT>(pb, "sha256round") {
|
||||
|
||||
block.reset(new block_variable<FieldT>(pb, {
|
||||
a,
|
||||
b
|
||||
}, "block"));
|
||||
|
||||
hasher.reset(new sha256_compression_function_gadget<FieldT>(
|
||||
pb,
|
||||
myIV,
|
||||
block->bits,
|
||||
result,
|
||||
"hasher"));
|
||||
}
|
||||
|
||||
void generate_r1cs_constraints() {
|
||||
hasher->generate_r1cs_constraints();
|
||||
}
|
||||
|
||||
void generate_r1cs_witness() {
|
||||
hasher->generate_r1cs_witness();
|
||||
}
|
||||
};
|
||||
|
||||
char* _sha256RoundConstraints()
|
||||
{
|
||||
libff::alt_bn128_pp::init_public_params();
|
||||
protoboard<FieldT> pb;
|
||||
pb_variable_array<FieldT> left;
|
||||
|
||||
left.allocate(pb, 256, "left");
|
||||
pb_variable_array<FieldT> right;
|
||||
right.allocate(pb, 256, "right");
|
||||
|
||||
digest_variable<FieldT> IV(pb, 256, "IV");
|
||||
|
||||
digest_variable<FieldT> output(pb, 256, "output");
|
||||
|
||||
IV.generate_r1cs_constraints(); //binary check for IV vector
|
||||
output.generate_r1cs_constraints(); //binary check for output vector
|
||||
|
||||
sha256round g(pb, IV.bits, left, right, output);
|
||||
g.generate_r1cs_constraints();
|
||||
|
||||
auto json = r1cs_to_json(pb);
|
||||
|
||||
auto result = new char[json.size() + 1];
|
||||
memcpy(result, json.c_str(), json.size() + 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
char* _sha256RoundWitness(const uint8_t* inputs, int inputs_length)
|
||||
{
|
||||
assert(inputs_length==768);
|
||||
|
||||
libff::alt_bn128_pp::init_public_params();
|
||||
protoboard<FieldT> pb;
|
||||
|
||||
pb_variable_array<FieldT> left;
|
||||
left.allocate(pb, 256, "left");
|
||||
pb_variable_array<FieldT> right;
|
||||
right.allocate(pb, 256, "right");
|
||||
|
||||
digest_variable<FieldT> IV(pb, 256, "IV");
|
||||
|
||||
digest_variable<FieldT> output(pb, 256, "output");
|
||||
|
||||
libff::bit_vector left_bv;
|
||||
libff::bit_vector right_bv;
|
||||
libff::bit_vector IV_bv;
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
left_bv.push_back(libsnarkBigintFromBytesAux(inputs + i*32) == 1);
|
||||
}
|
||||
|
||||
for (int i = 256; i < 512; i++) {
|
||||
right_bv.push_back(libsnarkBigintFromBytesAux(inputs + i*32) == 1);
|
||||
}
|
||||
|
||||
for (int i = 512; i < 768; i++) {
|
||||
IV_bv.push_back(libsnarkBigintFromBytesAux(inputs + i*32) == 1);
|
||||
}
|
||||
|
||||
left.fill_with_bits(pb, left_bv);
|
||||
right.fill_with_bits(pb, right_bv);
|
||||
|
||||
IV.generate_r1cs_witness(IV_bv);
|
||||
|
||||
sha256round g(pb, IV.bits, left, right, output);
|
||||
g.generate_r1cs_witness();
|
||||
|
||||
assert(pb.is_satisfied());
|
||||
|
||||
auto json = array_to_json(pb);
|
||||
|
||||
auto result = new char[json.size() + 1];
|
||||
memcpy(result, json.c_str(), json.size() + 1);
|
||||
return result;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/**
|
||||
* @file wraplibsnark.hpp
|
||||
* @author Jacob Eberhardt <jacob.eberhardt@tu-berlin.de
|
||||
* @author Dennis Kuhnert <dennis.kuhnert@campus.tu-berlin.de>
|
||||
* @date 2017
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
char* _sha256RoundConstraints();
|
||||
char* _sha256RoundWitness(const uint8_t* input, int input_length);
|
||||
|
||||
// External interface to free memory
|
||||
void _free_string(char const *str) {
|
||||
delete[] str;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
|
@ -1,5 +1,6 @@
|
|||
use helpers::{Executable, Signed};
|
||||
use std::fmt;
|
||||
use zokrates_embed::generate_sha256_round_witness;
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
|
||||
|
@ -8,16 +9,12 @@ pub enum RustHelper {
|
|||
ConditionEq,
|
||||
Bits,
|
||||
Div,
|
||||
Sha256Round,
|
||||
}
|
||||
|
||||
impl fmt::Display for RustHelper {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
RustHelper::Identity => write!(f, "Identity"),
|
||||
RustHelper::ConditionEq => write!(f, "ConditionEq"),
|
||||
RustHelper::Bits => write!(f, "Bits"),
|
||||
RustHelper::Div => write!(f, "Div"),
|
||||
}
|
||||
write!(f, "{:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +25,7 @@ impl Signed for RustHelper {
|
|||
RustHelper::ConditionEq => (1, 2),
|
||||
RustHelper::Bits => (1, 254),
|
||||
RustHelper::Div => (2, 1),
|
||||
RustHelper::Sha256Round => (768, 26935),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +54,12 @@ impl<T: Field> Executable<T> for RustHelper {
|
|||
Ok(res)
|
||||
}
|
||||
RustHelper::Div => Ok(vec![inputs[0].clone() / inputs[1].clone()]),
|
||||
RustHelper::Sha256Round => {
|
||||
let i = &inputs[0..512];
|
||||
let h = &inputs[512..];
|
||||
assert!(h.len() == 256);
|
||||
Ok(generate_sha256_round_witness(i, h))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,26 +139,20 @@ impl Importer {
|
|||
let pos = import.pos();
|
||||
let import = &import.value;
|
||||
// handle the case of special libsnark and packing imports
|
||||
if import.source.starts_with("LIBSNARK") {
|
||||
#[cfg(feature = "libsnark")]
|
||||
{
|
||||
use helpers::LibsnarkGadgetHelper;
|
||||
use libsnark::get_sha256round_constraints;
|
||||
use serde_json::from_str;
|
||||
use standard::{DirectiveR1CS, R1CS};
|
||||
|
||||
if import.source.starts_with("BELLMAN") {
|
||||
match import.source.as_ref() {
|
||||
"LIBSNARK/sha256round" => {
|
||||
let r1cs: R1CS = from_str(&get_sha256round_constraints()).unwrap();
|
||||
let dr1cs: DirectiveR1CS = DirectiveR1CS {
|
||||
r1cs,
|
||||
directive: LibsnarkGadgetHelper::Sha256Round,
|
||||
"BELLMAN/sha256round" => {
|
||||
use standard::sha_round;
|
||||
|
||||
let compiled = FlatProg {
|
||||
functions: vec![sha_round()],
|
||||
};
|
||||
let compiled = FlatProg::from(dr1cs);
|
||||
|
||||
let alias = match import.alias {
|
||||
Some(ref alias) => alias.clone(),
|
||||
None => String::from("sha256round"),
|
||||
};
|
||||
|
||||
origins.push(CompiledImport::new(compiled, alias));
|
||||
}
|
||||
s => {
|
||||
|
@ -169,11 +163,6 @@ impl Importer {
|
|||
.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "libsnark"))]
|
||||
{
|
||||
panic!("libsnark is not enabled, cannot access {}", import.source)
|
||||
}
|
||||
} else if import.source.starts_with("PACKING") {
|
||||
use types::conversions::split;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ extern crate rustc_hex;
|
|||
extern crate serde_bytes;
|
||||
#[cfg(feature = "wasm")]
|
||||
extern crate wasmi;
|
||||
extern crate zokrates_embed;
|
||||
extern crate zokrates_field;
|
||||
|
||||
mod flatten;
|
||||
|
@ -29,7 +30,6 @@ mod imports;
|
|||
mod optimizer;
|
||||
mod parser;
|
||||
mod semantics;
|
||||
#[cfg(feature = "libsnark")]
|
||||
mod standard;
|
||||
mod static_analysis;
|
||||
mod typed_absy;
|
||||
|
@ -39,7 +39,4 @@ pub mod absy;
|
|||
pub mod compile;
|
||||
pub mod flat_absy;
|
||||
pub mod ir;
|
||||
#[cfg(feature = "libsnark")]
|
||||
pub mod libsnark;
|
||||
// #[cfg(feature = "libsnark")]
|
||||
pub mod proof_system;
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
//
|
||||
// @file libsnark.rs
|
||||
// @author Jacob Eberhardt <jacob.eberhardt@tu-berlin.de
|
||||
// @author Dennis Kuhnert <dennis.kuhnert@campus.tu-berlin.de>
|
||||
// @date 2017
|
||||
|
||||
extern crate libc;
|
||||
|
||||
use self::libc::{c_char, c_int, uint8_t};
|
||||
use std::ffi::CStr;
|
||||
use std::string::String;
|
||||
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
extern "C" {
|
||||
fn _sha256RoundConstraints() -> *mut c_char;
|
||||
fn _sha256RoundWitness(inputs: *const uint8_t, inputs_length: c_int) -> *mut c_char;
|
||||
fn _free_string(str: *const c_char);
|
||||
}
|
||||
|
||||
pub fn get_sha256round_constraints() -> String {
|
||||
let c_buf: *const c_char = unsafe { _sha256RoundConstraints() };
|
||||
let c_str: &CStr = unsafe { CStr::from_ptr(c_buf) };
|
||||
let str_slice: &str = c_str.to_str().unwrap();
|
||||
let str_buf: String = str_slice.to_owned(); //memory allocated in Rust
|
||||
unsafe { _free_string(c_buf) }; //memory deallocated in Cpp
|
||||
str_buf
|
||||
}
|
||||
|
||||
pub fn get_sha256round_witness<T: Field>(inputs: &Vec<T>) -> String {
|
||||
let mut inputs_arr: Vec<[u8; 32]> = vec![[0u8; 32]; inputs.len()];
|
||||
for (index, value) in inputs.into_iter().enumerate() {
|
||||
inputs_arr[index] = vec_as_u8_32_array(&value.into_byte_vector());
|
||||
}
|
||||
let c_buf: *const c_char =
|
||||
unsafe { _sha256RoundWitness(inputs_arr[0].as_ptr(), inputs.len() as i32) };
|
||||
let c_str: &CStr = unsafe { CStr::from_ptr(c_buf) };
|
||||
let str_slice: &str = c_str.to_str().unwrap();
|
||||
let str_buf: String = str_slice.to_owned();
|
||||
unsafe { _free_string(c_buf) };
|
||||
str_buf
|
||||
}
|
||||
|
||||
// utility function. Converts a Fields vector-based byte representation to fixed size array.
|
||||
fn vec_as_u8_32_array(vec: &Vec<u8>) -> [u8; 32] {
|
||||
assert!(vec.len() <= 32);
|
||||
let mut array = [0u8; 32];
|
||||
for (index, byte) in vec.iter().enumerate() {
|
||||
array[31 - index] = *byte;
|
||||
}
|
||||
array
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use flat_absy::*;
|
||||
use helpers;
|
||||
use num_bigint::BigUint;
|
||||
use serde_json;
|
||||
use standard;
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
#[cfg(test)]
|
||||
mod sha256_gadget {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn can_get_sha256_constraints() {
|
||||
let _a = get_sha256round_constraints();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_generate_sha_256_witness_null() {
|
||||
let inputs = vec![FieldPrime::from(0); 768];
|
||||
let _b = get_sha256round_witness(&inputs);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_generate_flattened_code() {
|
||||
let constraints = get_sha256round_constraints();
|
||||
let r1cs: standard::R1CS = serde_json::from_str(&constraints).unwrap();
|
||||
let _prog: FlatProg<FieldPrime> = FlatProg::from(standard::DirectiveR1CS {
|
||||
r1cs,
|
||||
directive: helpers::LibsnarkGadgetHelper::Sha256Round,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod libsnark_integration {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn serialization_dec() {
|
||||
assert_eq!(
|
||||
BigUint::parse_bytes(
|
||||
b"5472060717959818805561601436314318772174077789324455915672259473661306552146",
|
||||
10
|
||||
)
|
||||
.unwrap()
|
||||
.to_bytes_le(),
|
||||
FieldPrime::try_from_str(
|
||||
"5472060717959818805561601436314318772174077789324455915672259473661306552146"
|
||||
)
|
||||
.unwrap()
|
||||
.into_byte_vector()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialization_bin() {
|
||||
assert_eq!(
|
||||
BigUint::parse_bytes(b"110000011001000100111001110010111000010011000110100000001010011011100001010000010001011011011010000001100000010101100001011101100101111000000101101010100100010110100001110001110010101000110100111100001000001000110000010110110110000111110011111101010010",2).unwrap().to_bytes_le(),
|
||||
FieldPrime::try_from_str("5472060717959818805561601436314318772174077789324455915672259473661306552146").unwrap().into_byte_vector()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vec_to_array() {
|
||||
let byte_vector: Vec<u8> = FieldPrime::try_from_str(
|
||||
"5472060717959818805561601436314318772174077789324455915672259473661306552146",
|
||||
)
|
||||
.unwrap()
|
||||
.into_byte_vector();
|
||||
let array: [u8; 32] = vec_as_u8_32_array(&byte_vector);
|
||||
for (index, value) in byte_vector.iter().enumerate() {
|
||||
assert_eq!(*value, array[31 - index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -45,7 +45,7 @@ fn bellman_combination<CS: ConstraintSystem<Bn256>>(
|
|||
l.0.into_iter()
|
||||
.map(|(k, v)| {
|
||||
(
|
||||
Fr::from(v),
|
||||
v.into_bellman(),
|
||||
symbols
|
||||
.entry(k)
|
||||
.or_insert_with(|| {
|
||||
|
@ -57,7 +57,7 @@ fn bellman_combination<CS: ConstraintSystem<Bn256>>(
|
|||
.0
|
||||
.remove(&k)
|
||||
.ok_or(SynthesisError::AssignmentMissing)?
|
||||
.into())
|
||||
.into_bellman())
|
||||
},
|
||||
),
|
||||
false => cs.alloc(
|
||||
|
@ -67,7 +67,7 @@ fn bellman_combination<CS: ConstraintSystem<Bn256>>(
|
|||
.0
|
||||
.remove(&k)
|
||||
.ok_or(SynthesisError::AssignmentMissing)?
|
||||
.into())
|
||||
.into_bellman())
|
||||
},
|
||||
),
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ impl Prog<FieldPrime> {
|
|||
.0
|
||||
.remove(&var)
|
||||
.ok_or(SynthesisError::AssignmentMissing)?
|
||||
.into())
|
||||
.into_bellman())
|
||||
},
|
||||
),
|
||||
false => cs.alloc_input(
|
||||
|
@ -117,7 +117,7 @@ impl Prog<FieldPrime> {
|
|||
.0
|
||||
.remove(&var)
|
||||
.ok_or(SynthesisError::AssignmentMissing)?
|
||||
.into())
|
||||
.into_bellman())
|
||||
},
|
||||
),
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ impl Computation<FieldPrime> {
|
|||
.map(|(a, _)| a)
|
||||
.map(|v| self.witness.clone().unwrap().0.get(v).unwrap().clone())
|
||||
.chain(self.witness.clone().unwrap().return_values())
|
||||
.map(|v| Fr::from(v.clone()))
|
||||
.map(|v| v.clone().into_bellman())
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,57 +1,18 @@
|
|||
use flat_absy::{FlatExpression, FlatExpressionList, FlatFunction, FlatStatement};
|
||||
use flat_absy::{FlatParameter, FlatVariable};
|
||||
use helpers::{DirectiveStatement, Helper, LibsnarkGadgetHelper};
|
||||
use helpers::{DirectiveStatement, Helper, RustHelper};
|
||||
use reduce::Reduce;
|
||||
use std::collections::BTreeMap;
|
||||
use types::{Signature, Type};
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
// for r1cs import, can be moved.
|
||||
// r1cs data structure reflecting JSON standard format:
|
||||
// {
|
||||
// variable_count: 435,
|
||||
// inputs: [offset_1, offset_33], // # of inputs to pass
|
||||
// outputs: [offset_42, offset_63, offset_55], // indices of the outputs in the witness
|
||||
// constraints: [ // constraints verified by the witness
|
||||
// [
|
||||
// {offset_1: value_a1, offset_2: value_a2, ...},
|
||||
// {offset_1: value_b1, offset_2: value_b2, ...},
|
||||
// {offset_1: value_c1, offset_2: value_c2, ...}
|
||||
// ]
|
||||
// }
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct R1CS {
|
||||
pub inputs: Vec<usize>,
|
||||
pub outputs: Vec<usize>,
|
||||
pub variable_count: usize,
|
||||
pub constraints: Vec<Constraint>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Witness {
|
||||
pub variables: Vec<usize>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||
pub struct Constraint {
|
||||
a: BTreeMap<usize, String>,
|
||||
b: BTreeMap<usize, String>,
|
||||
c: BTreeMap<usize, String>,
|
||||
}
|
||||
|
||||
pub struct DirectiveR1CS {
|
||||
pub r1cs: R1CS,
|
||||
pub directive: LibsnarkGadgetHelper,
|
||||
}
|
||||
|
||||
impl<T: Field> Into<FlatStatement<T>> for Constraint {
|
||||
fn into(self: Constraint) -> FlatStatement<T> {
|
||||
let rhs_a = match self
|
||||
impl<T: Field> From<zokrates_embed::Constraint<T>> for FlatStatement<T> {
|
||||
fn from(c: zokrates_embed::Constraint<T>) -> FlatStatement<T> {
|
||||
let rhs_a = match c
|
||||
.a
|
||||
.into_iter()
|
||||
.map(|(key, val)| {
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Number(T::from_dec_string(val.to_string())),
|
||||
box FlatExpression::Number(val),
|
||||
box FlatExpression::Identifier(FlatVariable::new(key)),
|
||||
)
|
||||
})
|
||||
|
@ -64,12 +25,12 @@ impl<T: Field> Into<FlatStatement<T>> for Constraint {
|
|||
None => FlatExpression::Number(T::zero()),
|
||||
};
|
||||
|
||||
let rhs_b = match self
|
||||
let rhs_b = match c
|
||||
.b
|
||||
.into_iter()
|
||||
.map(|(key, val)| {
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Number(T::from_dec_string(val.to_string())),
|
||||
box FlatExpression::Number(val),
|
||||
box FlatExpression::Identifier(FlatVariable::new(key)),
|
||||
)
|
||||
})
|
||||
|
@ -82,12 +43,12 @@ impl<T: Field> Into<FlatStatement<T>> for Constraint {
|
|||
None => FlatExpression::Number(T::zero()),
|
||||
};
|
||||
|
||||
let lhs = match self
|
||||
let lhs = match c
|
||||
.c
|
||||
.into_iter()
|
||||
.map(|(key, val)| {
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Number(T::from_dec_string(val.to_string())),
|
||||
box FlatExpression::Number(val),
|
||||
box FlatExpression::Identifier(FlatVariable::new(key)),
|
||||
)
|
||||
})
|
||||
|
@ -104,35 +65,15 @@ impl<T: Field> Into<FlatStatement<T>> for Constraint {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Field> Into<FlatFunction<T>> for DirectiveR1CS {
|
||||
fn into(self: DirectiveR1CS) -> FlatFunction<T> {
|
||||
let r1cs = self.r1cs;
|
||||
pub fn sha_round<T: Field>() -> FlatFunction<T> {
|
||||
let (r1cs, input, current_hash, output) = zokrates_embed::generate_sha256_round_constraints();
|
||||
|
||||
let variable_count = r1cs.variable_count;
|
||||
|
||||
let input_binding_statements = std::iter::once(FlatStatement::Condition(
|
||||
FlatVariable::new(0).into(),
|
||||
FlatExpression::Number(T::from(1)),
|
||||
))
|
||||
.chain(r1cs.inputs.iter().enumerate().map(|(index, i)| {
|
||||
FlatStatement::Condition(
|
||||
FlatVariable::new(*i).into(),
|
||||
FlatVariable::new(index + variable_count).into(),
|
||||
)
|
||||
}));
|
||||
|
||||
// insert flattened statements to represent constraints
|
||||
let constraint_statements = r1cs.constraints.into_iter().map(|c| c.into());
|
||||
|
||||
// define the entire witness
|
||||
let variables = vec![0; variable_count]
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, _)| FlatVariable::new(i))
|
||||
.collect();
|
||||
let variable_count = r1cs.aux_count + 1; // auxiliary and ONE
|
||||
|
||||
// define the inputs with dummy variables: arguments to the function and to the directive
|
||||
let input_variables: Vec<FlatVariable> = (0..r1cs.inputs.len())
|
||||
let input_variables: Vec<FlatVariable> = input
|
||||
.iter()
|
||||
.chain(current_hash.iter())
|
||||
.map(|i| FlatVariable::new(i + variable_count))
|
||||
.collect();
|
||||
let arguments = input_variables
|
||||
|
@ -147,9 +88,27 @@ impl<T: Field> Into<FlatFunction<T>> for DirectiveR1CS {
|
|||
.map(|i| FlatExpression::Identifier(i))
|
||||
.collect();
|
||||
|
||||
let input_binding_statements = // bind first variable to ~one
|
||||
std::iter::once(FlatStatement::Condition(
|
||||
FlatVariable::new(0).into(),
|
||||
FlatExpression::Number(T::from(1)),
|
||||
))
|
||||
// bind input and current_hash to inputs
|
||||
.chain(input.iter().chain(current_hash.iter()).map(|i| {
|
||||
FlatStatement::Condition(
|
||||
FlatVariable::new(*i).into(),
|
||||
FlatVariable::new(i + variable_count).into(),
|
||||
)
|
||||
}));
|
||||
|
||||
// insert flattened statements to represent constraints
|
||||
let constraint_statements = r1cs.constraints.into_iter().map(|c| c.into());
|
||||
|
||||
// define the entire witness
|
||||
let variables = (0..variable_count).map(|i| FlatVariable::new(i)).collect();
|
||||
|
||||
// define which subset of the witness is returned
|
||||
let outputs: Vec<FlatExpression<T>> = r1cs
|
||||
.outputs
|
||||
let outputs: Vec<FlatExpression<T>> = output
|
||||
.into_iter()
|
||||
.map(|o| FlatExpression::Identifier(FlatVariable::new(o)))
|
||||
.collect();
|
||||
|
@ -160,13 +119,11 @@ impl<T: Field> Into<FlatFunction<T>> for DirectiveR1CS {
|
|||
};
|
||||
|
||||
// insert a directive to set the witness based on the libsnark gadget and inputs
|
||||
let directive_statement = match self.directive {
|
||||
LibsnarkGadgetHelper::Sha256Round => FlatStatement::Directive(DirectiveStatement {
|
||||
let directive_statement = FlatStatement::Directive(DirectiveStatement {
|
||||
outputs: variables,
|
||||
inputs: inputs,
|
||||
helper: Helper::LibsnarkGadget(LibsnarkGadgetHelper::Sha256Round),
|
||||
}),
|
||||
};
|
||||
helper: Helper::Rust(RustHelper::Sha256Round),
|
||||
});
|
||||
|
||||
// insert a statement to return the subset of the witness
|
||||
let return_statement = FlatStatement::Return(FlatExpressionList {
|
||||
|
@ -186,43 +143,64 @@ impl<T: Field> Into<FlatFunction<T>> for DirectiveR1CS {
|
|||
signature,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json;
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
#[test]
|
||||
fn deserialize_constraint() {
|
||||
let constraint = r#"[{"2026": "1"}, {"0": "1", "2026": "1751751751751751751751751751751751751751751"}, {"0": "0"}]"#;
|
||||
let _c: Constraint = serde_json::from_str(constraint).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn constraint_into_flat_statement() {
|
||||
let constraint = r#"[{"2026": "1"}, {"0": "1", "2026": "1751751751751751751751751751751751751751751"}, {"0": "0"}]"#;
|
||||
let c: Constraint = serde_json::from_str(constraint).unwrap();
|
||||
let _statement: FlatStatement<FieldPrime> = c.into();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generate_sha256_constraints() {
|
||||
use flat_absy::FlatProg;
|
||||
use libsnark::get_sha256round_constraints;
|
||||
let r1cs: R1CS = serde_json::from_str(&get_sha256round_constraints()).unwrap();
|
||||
let v_count = r1cs.variable_count;
|
||||
let compiled = sha_round();
|
||||
|
||||
let dr1cs: DirectiveR1CS = DirectiveR1CS {
|
||||
r1cs,
|
||||
directive: LibsnarkGadgetHelper::Sha256Round,
|
||||
};
|
||||
let compiled: FlatProg<FieldPrime> = FlatProg::from(dr1cs);
|
||||
// function should have a signature of 768 inputs and 256 outputs
|
||||
assert_eq!(
|
||||
compiled.signature,
|
||||
Signature::new()
|
||||
.inputs(vec![Type::FieldElement; 768])
|
||||
.outputs(vec![Type::FieldElement; 256])
|
||||
);
|
||||
|
||||
// function should have 768 inputs
|
||||
assert_eq!(compiled.arguments.len(), 768,);
|
||||
|
||||
// function should return 256 values
|
||||
assert_eq!(
|
||||
compiled
|
||||
.statements
|
||||
.iter()
|
||||
.filter_map(|s| match s {
|
||||
FlatStatement::Return(v) => Some(v),
|
||||
_ => None,
|
||||
})
|
||||
.next()
|
||||
.unwrap()
|
||||
.expressions
|
||||
.len(),
|
||||
256,
|
||||
);
|
||||
|
||||
// directive should take 768 inputs and return n_var outputs
|
||||
let directive = compiled
|
||||
.statements
|
||||
.iter()
|
||||
.filter_map(|s| match s {
|
||||
FlatStatement::Directive(d) => Some(d.clone()),
|
||||
_ => None,
|
||||
})
|
||||
.next()
|
||||
.unwrap();
|
||||
assert_eq!(directive.inputs.len(), 768);
|
||||
assert_eq!(directive.outputs.len(), 26935);
|
||||
// function input should be offset by variable_count
|
||||
assert_eq!(
|
||||
compiled.arguments[0].id,
|
||||
FlatVariable::new(directive.outputs.len() + 1)
|
||||
);
|
||||
|
||||
// libsnark variable #0: index 0 should equal 1
|
||||
assert_eq!(
|
||||
compiled.functions[0].statements[1],
|
||||
compiled.statements[1],
|
||||
FlatStatement::Condition(
|
||||
FlatVariable::new(0).into(),
|
||||
FlatExpression::Number(FieldPrime::from(1))
|
||||
|
@ -231,11 +209,25 @@ mod tests {
|
|||
|
||||
// libsnark input #0: index 1 should equal zokrates input #0: index v_count
|
||||
assert_eq!(
|
||||
compiled.functions[0].statements[2],
|
||||
FlatStatement::Condition(
|
||||
FlatVariable::new(1).into(),
|
||||
FlatVariable::new(v_count).into()
|
||||
)
|
||||
compiled.statements[2],
|
||||
FlatStatement::Condition(FlatVariable::new(1).into(), FlatVariable::new(26936).into())
|
||||
);
|
||||
|
||||
let f = ::ir::Function::from(compiled);
|
||||
let prog = ::ir::Prog {
|
||||
main: f,
|
||||
private: vec![true; 768],
|
||||
};
|
||||
|
||||
//use rand::Rng;
|
||||
|
||||
// let mut rng = rand::thread_rng();
|
||||
// let input: Vec<_> = (0..768).map(|_| {
|
||||
// rng.gen_range(0, 2)
|
||||
// }).collect();
|
||||
|
||||
let input = (0..512).map(|_| 0).chain((0..256).map(|_| 1)).collect();
|
||||
|
||||
prog.execute(&input).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
10
zokrates_embed/Cargo.toml
Normal file
10
zokrates_embed/Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "zokrates_embed"
|
||||
version = "0.1.0"
|
||||
authors = ["schaeff <thibaut@schaeff.fr>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
sapling-crypto = { git = 'https://github.com/matterinc/sapling-crypto', tag = "0.0.4" }
|
||||
bellman = { git = 'https://github.com/matterinc/bellman', tag = "0.2.0" }
|
||||
zokrates_field = { path = "../zokrates_field" }
|
412
zokrates_embed/src/lib.rs
Normal file
412
zokrates_embed/src/lib.rs
Normal file
|
@ -0,0 +1,412 @@
|
|||
use bellman::pairing::Engine;
|
||||
use bellman::ConstraintSystem;
|
||||
use bellman::{Index, LinearCombination, SynthesisError, Variable};
|
||||
use sapling_crypto::circuit::boolean::{AllocatedBit, Boolean};
|
||||
use sapling_crypto::circuit::sha256::sha256_compression_function;
|
||||
use sapling_crypto::circuit::uint32::UInt32;
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct BellmanR1CS<E: Engine> {
|
||||
aux_count: usize,
|
||||
constraints: Vec<BellmanConstraint<E>>,
|
||||
}
|
||||
|
||||
impl<E: Engine> BellmanR1CS<E> {
|
||||
pub fn new() -> Self {
|
||||
BellmanR1CS {
|
||||
aux_count: 0,
|
||||
constraints: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct BellmanWitness<E: Engine> {
|
||||
pub values: Vec<E::Fr>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct BellmanConstraint<E: Engine> {
|
||||
pub a: Vec<(usize, E::Fr)>,
|
||||
pub b: Vec<(usize, E::Fr)>,
|
||||
pub c: Vec<(usize, E::Fr)>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Constraint<T: Field> {
|
||||
pub a: Vec<(usize, T)>,
|
||||
pub b: Vec<(usize, T)>,
|
||||
pub c: Vec<(usize, T)>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct R1CS<T: Field> {
|
||||
pub aux_count: usize,
|
||||
pub constraints: Vec<Constraint<T>>,
|
||||
}
|
||||
|
||||
fn sha256_round<T: Field, CS: ConstraintSystem<T::BellmanEngine>>(
|
||||
mut cs: CS,
|
||||
input: Option<&Vec<T>>,
|
||||
current_hash: Option<&Vec<T>>,
|
||||
) -> Result<(Vec<usize>, Vec<usize>, Vec<usize>), SynthesisError> {
|
||||
let input_bits = (0..512)
|
||||
.map(|i| {
|
||||
AllocatedBit::alloc::<T::BellmanEngine, _>(
|
||||
&mut cs.namespace(|| format!("input_{}", i)),
|
||||
Some(input.as_ref().unwrap()[i] == T::from(1)),
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let input = input_bits
|
||||
.iter()
|
||||
.map(|i| Boolean::Is(i.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let current_hash_bits = (0..256)
|
||||
.map(|i| {
|
||||
AllocatedBit::alloc::<T::BellmanEngine, _>(
|
||||
&mut cs.namespace(|| format!("current_hash_{}", i)),
|
||||
Some(current_hash.as_ref().unwrap()[i] == T::from(1)),
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let current_hash = current_hash_bits
|
||||
.chunks(32)
|
||||
.map(|chunk| {
|
||||
UInt32::from_bits_be(
|
||||
&chunk
|
||||
.into_iter()
|
||||
.map(|i| Boolean::Is(i.clone()))
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let res =
|
||||
sha256_compression_function::<T::BellmanEngine, _>(&mut cs, &input, ¤t_hash).unwrap();
|
||||
|
||||
let output_bits = res
|
||||
.into_iter()
|
||||
.flat_map(|u| u.into_bits_be())
|
||||
.map(|b| b.get_variable().unwrap().clone())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Ok((
|
||||
input_bits
|
||||
.into_iter()
|
||||
.map(|b| BellmanR1CS::<T::BellmanEngine>::var_to_index(b.get_variable()))
|
||||
.collect(),
|
||||
current_hash_bits
|
||||
.into_iter()
|
||||
.map(|b| BellmanR1CS::<T::BellmanEngine>::var_to_index(b.get_variable()))
|
||||
.collect(),
|
||||
output_bits
|
||||
.into_iter()
|
||||
.map(|b| BellmanR1CS::<T::BellmanEngine>::var_to_index(b.get_variable()))
|
||||
.collect(),
|
||||
))
|
||||
}
|
||||
|
||||
impl<T: Field> R1CS<T> {
|
||||
fn from_bellman(cs: BellmanR1CS<T::BellmanEngine>) -> Self {
|
||||
R1CS {
|
||||
aux_count: cs.aux_count,
|
||||
constraints: cs
|
||||
.constraints
|
||||
.into_iter()
|
||||
.map(|c| Constraint::from_bellman(c))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field> Constraint<T> {
|
||||
fn from_bellman(cs: BellmanConstraint<T::BellmanEngine>) -> Self {
|
||||
let res = Constraint {
|
||||
a: cs
|
||||
.a
|
||||
.into_iter()
|
||||
.map(|(variable, coefficient)| (variable, T::from_bellman(coefficient)))
|
||||
.collect(),
|
||||
b: cs
|
||||
.b
|
||||
.into_iter()
|
||||
.map(|(variable, coefficient)| (variable, T::from_bellman(coefficient)))
|
||||
.collect(),
|
||||
c: cs
|
||||
.c
|
||||
.into_iter()
|
||||
.map(|(variable, coefficient)| (variable, T::from_bellman(coefficient)))
|
||||
.collect(),
|
||||
};
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine> ConstraintSystem<E> for BellmanWitness<E> {
|
||||
type Root = Self;
|
||||
|
||||
fn alloc<F, A, AR>(&mut self, _annotation: A, f: F) -> Result<Variable, SynthesisError>
|
||||
where
|
||||
F: FnOnce() -> Result<E::Fr, SynthesisError>,
|
||||
A: FnOnce() -> AR,
|
||||
AR: Into<String>,
|
||||
{
|
||||
// we only care about the value
|
||||
let index = self.values.len();
|
||||
let var = Variable::new_unchecked(Index::Aux(index));
|
||||
self.values.push(f().unwrap());
|
||||
Ok(var)
|
||||
}
|
||||
|
||||
fn alloc_input<F, A, AR>(&mut self, _annotation: A, _f: F) -> Result<Variable, SynthesisError>
|
||||
where
|
||||
F: FnOnce() -> Result<E::Fr, SynthesisError>,
|
||||
A: FnOnce() -> AR,
|
||||
AR: Into<String>,
|
||||
{
|
||||
unreachable!("Bellman helpers are not allowed to allocate public variables")
|
||||
}
|
||||
|
||||
fn enforce<A, AR, LA, LB, LC>(&mut self, _annotation: A, _a: LA, _b: LB, _c: LC)
|
||||
where
|
||||
A: FnOnce() -> AR,
|
||||
AR: Into<String>,
|
||||
LA: FnOnce(LinearCombination<E>) -> LinearCombination<E>,
|
||||
LB: FnOnce(LinearCombination<E>) -> LinearCombination<E>,
|
||||
LC: FnOnce(LinearCombination<E>) -> LinearCombination<E>,
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
fn push_namespace<NR, N>(&mut self, _name_fn: N)
|
||||
where
|
||||
NR: Into<String>,
|
||||
N: FnOnce() -> NR,
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
fn pop_namespace(&mut self) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
fn get_root(&mut self) -> &mut Self::Root {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine> ConstraintSystem<E> for BellmanR1CS<E> {
|
||||
type Root = Self;
|
||||
|
||||
fn alloc<F, A, AR>(&mut self, _annotation: A, _f: F) -> Result<Variable, SynthesisError>
|
||||
where
|
||||
F: FnOnce() -> Result<E::Fr, SynthesisError>,
|
||||
A: FnOnce() -> AR,
|
||||
AR: Into<String>,
|
||||
{
|
||||
// we don't care about the value as we're only getting the CS
|
||||
let index = self.aux_count;
|
||||
let var = Variable::new_unchecked(Index::Aux(index));
|
||||
self.aux_count += 1;
|
||||
Ok(var)
|
||||
}
|
||||
|
||||
fn alloc_input<F, A, AR>(&mut self, _annotation: A, _f: F) -> Result<Variable, SynthesisError>
|
||||
where
|
||||
F: FnOnce() -> Result<E::Fr, SynthesisError>,
|
||||
A: FnOnce() -> AR,
|
||||
AR: Into<String>,
|
||||
{
|
||||
unreachable!("Bellman helpers are not allowed to allocate public variables")
|
||||
}
|
||||
|
||||
fn enforce<A, AR, LA, LB, LC>(&mut self, _annotation: A, a: LA, b: LB, c: LC)
|
||||
where
|
||||
A: FnOnce() -> AR,
|
||||
AR: Into<String>,
|
||||
LA: FnOnce(LinearCombination<E>) -> LinearCombination<E>,
|
||||
LB: FnOnce(LinearCombination<E>) -> LinearCombination<E>,
|
||||
LC: FnOnce(LinearCombination<E>) -> LinearCombination<E>,
|
||||
{
|
||||
let a = a(LinearCombination::zero());
|
||||
let b = b(LinearCombination::zero());
|
||||
let c = c(LinearCombination::zero());
|
||||
|
||||
let a = a
|
||||
.as_ref()
|
||||
.into_iter()
|
||||
.map(|(variable, coefficient)| {
|
||||
(BellmanR1CS::<E>::var_to_index(*variable), *coefficient)
|
||||
})
|
||||
.collect();
|
||||
let b = b
|
||||
.as_ref()
|
||||
.into_iter()
|
||||
.map(|(variable, coefficient)| {
|
||||
(BellmanR1CS::<E>::var_to_index(*variable), *coefficient)
|
||||
})
|
||||
.collect();
|
||||
let c = c
|
||||
.as_ref()
|
||||
.into_iter()
|
||||
.map(|(variable, coefficient)| {
|
||||
(BellmanR1CS::<E>::var_to_index(*variable), *coefficient)
|
||||
})
|
||||
.collect();
|
||||
|
||||
self.constraints.push(BellmanConstraint { a, b, c });
|
||||
}
|
||||
|
||||
fn push_namespace<NR, N>(&mut self, _name_fn: N)
|
||||
where
|
||||
NR: Into<String>,
|
||||
N: FnOnce() -> NR,
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
fn pop_namespace(&mut self) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
fn get_root(&mut self) -> &mut Self::Root {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_xor_constraints<T: Field>() -> (R1CS<T>, usize) {
|
||||
let mut cs = BellmanR1CS::new();
|
||||
|
||||
let i0 = Boolean::Is(AllocatedBit::alloc::<T::BellmanEngine, _>(&mut cs, None).unwrap());
|
||||
let i1 = Boolean::Is(AllocatedBit::alloc::<T::BellmanEngine, _>(&mut cs, None).unwrap());
|
||||
|
||||
let res = Boolean::xor(&mut cs, &i0, &i1).unwrap();
|
||||
let res =
|
||||
BellmanR1CS::<T::BellmanEngine>::var_to_index(res.get_variable().unwrap().get_variable());
|
||||
|
||||
let cs = R1CS::from_bellman(cs);
|
||||
|
||||
(cs, res)
|
||||
}
|
||||
|
||||
pub fn generate_xor_witness<T: Field>(i1: bool, i2: bool) -> Vec<T> {
|
||||
let mut cs = BellmanWitness {
|
||||
values: vec![T::from(1).into_bellman()],
|
||||
};
|
||||
|
||||
let i0 = Boolean::Is(AllocatedBit::alloc::<T::BellmanEngine, _>(&mut cs, Some(i1)).unwrap());
|
||||
let i1 = Boolean::Is(AllocatedBit::alloc::<T::BellmanEngine, _>(&mut cs, Some(i2)).unwrap());
|
||||
|
||||
Boolean::xor(&mut cs, &i0, &i1).unwrap();
|
||||
|
||||
cs.values.into_iter().map(|v| T::from_bellman(v)).collect()
|
||||
}
|
||||
|
||||
pub fn generate_sha256_round_constraints<T: Field>() -> (R1CS<T>, Vec<usize>, Vec<usize>, Vec<usize>)
|
||||
{
|
||||
let mut cs = BellmanR1CS::new();
|
||||
|
||||
let (input_bits, current_hash_bits, output_bits) = sha256_round::<T, _>(
|
||||
&mut cs,
|
||||
Some(&vec![T::from(0); 512]),
|
||||
Some(&vec![T::from(0); 256]),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// res is now the allocated bits for input, current_hash and sha256_output
|
||||
|
||||
let cs = R1CS::<T>::from_bellman(cs);
|
||||
|
||||
(cs, input_bits, current_hash_bits, output_bits)
|
||||
}
|
||||
|
||||
pub fn generate_sha256_round_witness<T: Field>(input: &[T], current_hash: &[T]) -> Vec<T> {
|
||||
assert_eq!(input.len(), 512);
|
||||
assert_eq!(current_hash.len(), 256);
|
||||
|
||||
let mut cs = BellmanWitness {
|
||||
values: vec![T::from(1).into_bellman()],
|
||||
};
|
||||
|
||||
sha256_round(&mut cs, Some(&input.to_vec()), Some(¤t_hash.to_vec())).unwrap();
|
||||
|
||||
cs.values.into_iter().map(|v| T::from_bellman(v)).collect()
|
||||
}
|
||||
|
||||
impl<E: Engine> BellmanR1CS<E> {
|
||||
fn var_to_index(v: Variable) -> usize {
|
||||
match v.get_unchecked() {
|
||||
Index::Aux(i) => i + 1,
|
||||
Index::Input(0) => 0,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
#[test]
|
||||
fn generate_constraints() {
|
||||
let (_c, input, current_hash, output) = generate_sha256_round_constraints::<FieldPrime>();
|
||||
assert_eq!(input.len(), 512);
|
||||
assert_eq!(current_hash.len(), 256);
|
||||
assert_eq!(output.len(), 256);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generate_witness() {
|
||||
let witness = generate_sha256_round_witness(
|
||||
&vec![FieldPrime::from(0); 512],
|
||||
&vec![FieldPrime::from(0); 256],
|
||||
);
|
||||
assert_eq!(witness.len(), 26935);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn xor() {
|
||||
let (_, indice) = generate_xor_constraints::<FieldPrime>();
|
||||
|
||||
assert_eq!(
|
||||
FieldPrime::from(0),
|
||||
generate_xor_witness::<FieldPrime>(true, true)[indice]
|
||||
);
|
||||
assert_eq!(
|
||||
FieldPrime::from(1),
|
||||
generate_xor_witness::<FieldPrime>(true, false)[indice]
|
||||
);
|
||||
assert_eq!(
|
||||
FieldPrime::from(1),
|
||||
generate_xor_witness::<FieldPrime>(false, true)[indice]
|
||||
);
|
||||
assert_eq!(
|
||||
FieldPrime::from(0),
|
||||
generate_xor_witness::<FieldPrime>(false, false)[indice]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cs() {
|
||||
use sapling_crypto::circuit::test::TestConstraintSystem;
|
||||
|
||||
let mut cs = TestConstraintSystem::new();
|
||||
|
||||
let _ = sha256_round::<FieldPrime, _>(
|
||||
&mut cs,
|
||||
Some(&vec![FieldPrime::from(0); 512]),
|
||||
Some(&vec![FieldPrime::from(1); 256]),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(cs.is_satisfied());
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
use crate::field::{Field, FieldPrime};
|
||||
use ff::{PrimeField, PrimeFieldRepr};
|
||||
use pairing::bn256::Fr;
|
||||
|
||||
impl From<FieldPrime> for Fr {
|
||||
fn from(e: FieldPrime) -> Fr {
|
||||
let s = e.to_dec_string();
|
||||
Fr::from_str(&s).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Fr> for FieldPrime {
|
||||
fn from(e: Fr) -> FieldPrime {
|
||||
let mut res: Vec<u8> = vec![];
|
||||
e.into_repr().write_le(&mut res).unwrap();
|
||||
FieldPrime::from_byte_vector(res)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ff::Field;
|
||||
|
||||
extern crate rand;
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
#[test]
|
||||
fn fr_to_field_to_fr() {
|
||||
let rng = &mut thread_rng();
|
||||
let a: Fr = rng.gen();
|
||||
|
||||
assert_eq!(Fr::from(FieldPrime::from(a)), a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn field_to_fr_to_field() {
|
||||
// use Fr to get a random element
|
||||
let rng = &mut thread_rng();
|
||||
let a: Fr = rng.gen();
|
||||
|
||||
// now test idempotence
|
||||
let a = FieldPrime::from(a);
|
||||
|
||||
assert_eq!(FieldPrime::from(Fr::from(a.clone())), a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn one() {
|
||||
let a = FieldPrime::from(1);
|
||||
|
||||
assert_eq!(Fr::from(a), Fr::one());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zero() {
|
||||
let a = FieldPrime::from(0);
|
||||
|
||||
assert_eq!(Fr::from(a), Fr::zero());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn minus_one() {
|
||||
let mut a: Fr = Fr::one();
|
||||
a.negate();
|
||||
assert_eq!(FieldPrime::from(a), FieldPrime::from(-1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add() {
|
||||
let rng = &mut thread_rng();
|
||||
|
||||
let mut a: Fr = rng.gen();
|
||||
let b: Fr = rng.gen();
|
||||
|
||||
let aa = FieldPrime::from(a);
|
||||
let bb = FieldPrime::from(b);
|
||||
let cc = aa + bb;
|
||||
|
||||
a.add_assign(&b);
|
||||
|
||||
assert_eq!(FieldPrime::from(a), cc);
|
||||
}
|
||||
}
|
|
@ -8,6 +8,9 @@ use lazy_static::lazy_static;
|
|||
use num_bigint::{BigInt, BigUint, Sign, ToBigInt};
|
||||
use num_integer::Integer;
|
||||
use num_traits::{Num, One, Zero};
|
||||
use pairing::bn256::Bn256;
|
||||
use pairing::ff::ScalarEngine;
|
||||
use pairing::Engine;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::convert::From;
|
||||
use std::fmt;
|
||||
|
@ -53,6 +56,22 @@ pub trait Field:
|
|||
+ Pow<Self, Output = Self>
|
||||
+ for<'a> Pow<&'a Self, Output = Self>
|
||||
{
|
||||
/// An associated type to be able to operate with Bellman ff traits
|
||||
type BellmanEngine: Engine;
|
||||
|
||||
fn from_bellman(e: <Self::BellmanEngine as ScalarEngine>::Fr) -> Self {
|
||||
use ff::{PrimeField, PrimeFieldRepr};
|
||||
let mut res: Vec<u8> = vec![];
|
||||
e.into_repr().write_le(&mut res).unwrap();
|
||||
Self::from_byte_vector(res)
|
||||
}
|
||||
|
||||
fn into_bellman(self) -> <Self::BellmanEngine as ScalarEngine>::Fr {
|
||||
use ff::PrimeField;
|
||||
let s = self.to_dec_string();
|
||||
<Self::BellmanEngine as ScalarEngine>::Fr::from_str(&s).unwrap()
|
||||
}
|
||||
|
||||
/// Returns this `Field`'s contents as little-endian byte vector
|
||||
fn into_byte_vector(&self) -> Vec<u8>;
|
||||
/// Returns an element of this `Field` from a little-endian byte vector
|
||||
|
@ -82,6 +101,8 @@ pub struct FieldPrime {
|
|||
}
|
||||
|
||||
impl Field for FieldPrime {
|
||||
type BellmanEngine = Bn256;
|
||||
|
||||
fn into_byte_vector(&self) -> Vec<u8> {
|
||||
match self.value.to_biguint() {
|
||||
Option::Some(val) => val.to_bytes_le(),
|
||||
|
@ -716,4 +737,74 @@ mod tests {
|
|||
s_field
|
||||
);
|
||||
}
|
||||
|
||||
mod bellman {
|
||||
use super::*;
|
||||
|
||||
use ff::Field as FField;
|
||||
|
||||
extern crate rand;
|
||||
use pairing::bn256::Fr;
|
||||
use rand::{thread_rng, Rng};
|
||||
use Field;
|
||||
|
||||
#[test]
|
||||
fn fr_to_field_to_fr() {
|
||||
let rng = &mut thread_rng();
|
||||
for _ in 0..1000 {
|
||||
let a: Fr = rng.gen();
|
||||
assert_eq!(FieldPrime::from_bellman(a).into_bellman(), a);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn field_to_fr_to_field() {
|
||||
// use Fr to get a random element
|
||||
let rng = &mut thread_rng();
|
||||
for _ in 0..1000 {
|
||||
let a: Fr = rng.gen();
|
||||
// now test idempotence
|
||||
let a = FieldPrime::from_bellman(a);
|
||||
assert_eq!(FieldPrime::from_bellman(a.clone().into_bellman()), a);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn one() {
|
||||
let a = FieldPrime::from(1);
|
||||
|
||||
assert_eq!(a.into_bellman(), Fr::one());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zero() {
|
||||
let a = FieldPrime::from(0);
|
||||
|
||||
assert_eq!(a.into_bellman(), Fr::zero());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn minus_one() {
|
||||
let mut a: Fr = Fr::one();
|
||||
a.negate();
|
||||
assert_eq!(FieldPrime::from_bellman(a), FieldPrime::from(-1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add() {
|
||||
let rng = &mut thread_rng();
|
||||
|
||||
let mut a: Fr = rng.gen();
|
||||
let b: Fr = rng.gen();
|
||||
|
||||
let aa = FieldPrime::from_bellman(a);
|
||||
let bb = FieldPrime::from_bellman(b);
|
||||
let cc = aa + bb;
|
||||
|
||||
a.add_assign(&b);
|
||||
|
||||
assert_eq!(FieldPrime::from_bellman(a), cc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
mod conversion;
|
||||
pub mod field;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import "LIBSNARK/sha256round" as sha256
|
||||
import "BELLMAN/sha256round" as sha256
|
||||
// a and b is NOT checked to be of type bool
|
||||
// IV vector is checked to be of type bool
|
||||
def main(field[256] a, field[256] b, field[256] IV) -> (field[256]):
|
||||
|
|
Loading…
Reference in a new issue