1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00

fix conflicts

This commit is contained in:
schaeff 2021-07-08 10:53:28 +02:00
commit cbb6e4ff97
46 changed files with 3983 additions and 565 deletions

View file

@ -106,7 +106,7 @@ jobs:
- v4-cargo-cache-{{ arch }}-{{ checksum "Cargo.lock" }}
- run:
name: Run integration tests
command: WITH_LIBSNARK=1 RUSTFLAGS="-D warnings" ./full_test.sh
command: WITH_LIBSNARK=1 RUSTFLAGS="-D warnings" ./integration_test.sh
deploy:
docker:
- image: circleci/python:latest-node

373
Cargo.lock generated
View file

@ -4,9 +4,9 @@ version = 3
[[package]]
name = "addr2line"
version = "0.14.1"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7"
checksum = "e7a2e47a1fbe209ee101dd6d61285226744c6c8d3c21c8dc878ba6cb9f467f3a"
dependencies = [
"gimli",
]
@ -19,11 +19,11 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
version = "0.7.2"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f200cbb1e856866d9eade941cf3aa0c5d7dd36f74311c4273b494f4ef036957"
checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98"
dependencies = [
"getrandom 0.2.2",
"getrandom 0.2.3",
"once_cell",
"version_check",
]
@ -54,6 +54,7 @@ checksum = "eb89b97424403ec9cc22a1df0db748dd7396c9ba5fb5c71a6f0e10ae1d1a7449"
dependencies = [
"ark-ec",
"ark-ff",
"ark-r1cs-std",
"ark-std",
]
@ -88,12 +89,15 @@ checksum = "74b83a7e125e5c611e4a997123effb2f02e3fbc66531dd77751d3016ee920741"
dependencies = [
"ark-ec",
"ark-ff",
"ark-nonnative-field",
"ark-r1cs-std",
"ark-relations",
"ark-snark",
"ark-std",
"blake2",
"derivative",
"digest 0.9.0",
"tracing",
]
[[package]]
@ -133,7 +137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e8cb28c2137af1ef058aa59616db3f7df67dbb70bf2be4ee6920008cc30d98c"
dependencies = [
"quote 1.0.9",
"syn 1.0.71",
"syn 1.0.73",
]
[[package]]
@ -145,7 +149,7 @@ dependencies = [
"num-bigint 0.4.0",
"num-traits 0.2.14",
"quote 1.0.9",
"syn 1.0.71",
"syn 1.0.73",
]
[[package]]
@ -158,9 +162,12 @@ dependencies = [
"ark-ec",
"ark-ff",
"ark-poly",
"ark-r1cs-std",
"ark-relations",
"ark-serialize",
"ark-std",
"derivative",
"tracing",
]
[[package]]
@ -180,6 +187,24 @@ dependencies = [
"rand_chacha 0.2.2",
]
[[package]]
name = "ark-nonnative-field"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17887af156e9911d1dba5b30d49256d508f82f6a4f765a6fad8b5c637b700353"
dependencies = [
"ark-ec",
"ark-ff",
"ark-r1cs-std",
"ark-relations",
"ark-std",
"derivative",
"num-bigint 0.4.0",
"num-integer",
"num-traits 0.2.14",
"tracing",
]
[[package]]
name = "ark-poly"
version = "0.2.0"
@ -209,6 +234,22 @@ dependencies = [
"tracing",
]
[[package]]
name = "ark-r1cs-std"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a90fea2b84ae4443983d56540360ea004cab952292b7a6535798b6b9dcb7f41"
dependencies = [
"ark-ec",
"ark-ff",
"ark-relations",
"ark-std",
"derivative",
"num-bigint 0.4.0",
"num-traits 0.2.14",
"tracing",
]
[[package]]
name = "ark-relations"
version = "0.2.0"
@ -236,9 +277,9 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ac3d78c750b01f5df5b2e76d106ed31487a93b3868f14a7f0eb3a74f45e1d8a"
dependencies = [
"proc-macro2 1.0.26",
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.71",
"syn 1.0.73",
]
[[package]]
@ -304,9 +345,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "backtrace"
version = "0.3.58"
version = "0.3.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88fb5a785d6b44fd9d6700935608639af1b8356de1e55d5f7c2740f4faa15d82"
checksum = "b7815ea54e4d821e791162e078acbebfd6d8c8939cd559c9335dceb1c8ca7282"
dependencies = [
"addr2line",
"cc",
@ -411,9 +452,9 @@ dependencies = [
[[package]]
name = "bstr"
version = "0.2.15"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d"
checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279"
dependencies = [
"lazy_static",
"memchr",
@ -423,9 +464,9 @@ dependencies = [
[[package]]
name = "bumpalo"
version = "3.6.1"
version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
[[package]]
name = "byte-tools"
@ -469,9 +510,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.67"
version = "1.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
dependencies = [
"jobserver",
]
@ -540,10 +581,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "cpuid-bool"
version = "0.1.2"
name = "cpufeatures"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef"
dependencies = [
"libc",
]
[[package]]
name = "crossbeam"
@ -662,7 +706,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d"
dependencies = [
"quote 1.0.9",
"syn 1.0.71",
"syn 1.0.73",
]
[[package]]
@ -671,9 +715,9 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
"proc-macro2 1.0.26",
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.71",
"syn 1.0.73",
]
[[package]]
@ -772,9 +816,9 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
dependencies = [
"proc-macro2 1.0.26",
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.71",
"syn 1.0.73",
"synstructure",
]
@ -816,9 +860,9 @@ dependencies = [
"num-bigint 0.2.6",
"num-integer",
"num-traits 0.2.14",
"proc-macro2 1.0.26",
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.71",
"syn 1.0.73",
]
[[package]]
@ -855,9 +899,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "futures"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253"
checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27"
dependencies = [
"futures-channel",
"futures-core",
@ -870,9 +914,9 @@ dependencies = [
[[package]]
name = "futures-channel"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25"
checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
dependencies = [
"futures-core",
"futures-sink",
@ -880,15 +924,15 @@ dependencies = [
[[package]]
name = "futures-core"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815"
checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
[[package]]
name = "futures-executor"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d"
checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79"
dependencies = [
"futures-core",
"futures-task",
@ -898,28 +942,29 @@ dependencies = [
[[package]]
name = "futures-io"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04"
checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"
[[package]]
name = "futures-sink"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23"
checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282"
[[package]]
name = "futures-task"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc"
checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"
[[package]]
name = "futures-util"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025"
checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
dependencies = [
"autocfg",
"futures-channel",
"futures-core",
"futures-io",
@ -963,9 +1008,9 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if 1.0.0",
"js-sys",
@ -976,15 +1021,15 @@ dependencies = [
[[package]]
name = "gimli"
version = "0.23.0"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189"
[[package]]
name = "git2"
version = "0.13.18"
version = "0.13.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b483c6c2145421099df1b4efd50e0f6205479a072199460eff852fa15e5603c7"
checksum = "d9831e983241f8c5591ed53f17d874833e2fa82cac2625f3888c50cbfe136cba"
dependencies = [
"bitflags",
"libc",
@ -1018,9 +1063,9 @@ dependencies = [
[[package]]
name = "hermit-abi"
version = "0.1.18"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
@ -1068,9 +1113,9 @@ dependencies = [
[[package]]
name = "js-sys"
version = "0.3.50"
version = "0.3.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c"
checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
dependencies = [
"wasm-bindgen",
]
@ -1083,15 +1128,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.94"
version = "0.2.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
[[package]]
name = "libgit2-sys"
version = "0.12.19+1.1.0"
version = "0.12.21+1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f322155d574c8b9ebe991a04f6908bb49e68a79463338d24a43d6274cb6443e6"
checksum = "86271bacd72b2b9e854c3dcfb82efd538f15f870e4c11af66900effb462f6825"
dependencies = [
"cc",
"libc",
@ -1117,9 +1162,9 @@ dependencies = [
[[package]]
name = "libz-sys"
version = "1.1.2"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655"
checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66"
dependencies = [
"cc",
"libc",
@ -1156,9 +1201,9 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
[[package]]
name = "memchr"
version = "2.3.4"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
[[package]]
name = "memoffset"
@ -1270,15 +1315,18 @@ dependencies = [
[[package]]
name = "object"
version = "0.23.0"
version = "0.25.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
checksum = "a38f2be3697a57b4060074ff41b44c16870d916ad7877c17696e063257482bc7"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.7.2"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]]
name = "opaque-debug"
@ -1294,15 +1342,15 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "openssl-probe"
version = "0.1.2"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
[[package]]
name = "openssl-sys"
version = "0.9.62"
version = "0.9.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa52160d45fa2e7608d504b7c3a3355afed615e6d8b627a74458634ba21b69bd"
checksum = "7a7907e3bfa08bb85105209cdfcb6c63d109f8f6c1ed6ca318fff5c1853fbc1d"
dependencies = [
"autocfg",
"cc",
@ -1377,9 +1425,9 @@ checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
dependencies = [
"pest",
"pest_meta",
"proc-macro2 1.0.26",
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.71",
"syn 1.0.73",
]
[[package]]
@ -1395,9 +1443,9 @@ dependencies = [
[[package]]
name = "pin-project-lite"
version = "0.2.6"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
[[package]]
name = "pin-utils"
@ -1440,11 +1488,11 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.26"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
dependencies = [
"unicode-xid 0.2.1",
"unicode-xid 0.2.2",
]
[[package]]
@ -1473,7 +1521,7 @@ version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2 1.0.26",
"proc-macro2 1.0.27",
]
[[package]]
@ -1504,14 +1552,14 @@ dependencies = [
[[package]]
name = "rand"
version = "0.8.3"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha 0.3.0",
"rand_core 0.6.2",
"rand_hc 0.3.0",
"rand_chacha 0.3.1",
"rand_core 0.6.3",
"rand_hc 0.3.1",
]
[[package]]
@ -1526,12 +1574,12 @@ dependencies = [
[[package]]
name = "rand_chacha"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core 0.6.2",
"rand_core 0.6.3",
]
[[package]]
@ -1560,11 +1608,11 @@ dependencies = [
[[package]]
name = "rand_core"
version = "0.6.2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom 0.2.2",
"getrandom 0.2.3",
]
[[package]]
@ -1578,11 +1626,11 @@ dependencies = [
[[package]]
name = "rand_hc"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
"rand_core 0.6.2",
"rand_core 0.6.3",
]
[[package]]
@ -1605,9 +1653,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.2.7"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85dd92e586f7355c633911e11f77f3d12f04b1b1bd76a198bd34ae3af8341ef2"
checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee"
dependencies = [
"bitflags",
]
@ -1618,7 +1666,7 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
dependencies = [
"getrandom 0.2.2",
"getrandom 0.2.3",
"redox_syscall",
]
@ -1643,12 +1691,9 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.1.9"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
dependencies = [
"byteorder",
]
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
[[package]]
name = "regex-syntax"
@ -1670,9 +1715,9 @@ dependencies = [
[[package]]
name = "rustc-demangle"
version = "0.1.18"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49"
[[package]]
name = "rustc_version"
@ -1748,22 +1793,22 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.125"
version = "1.0.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.125"
version = "1.0.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
dependencies = [
"proc-macro2 1.0.26",
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.71",
"syn 1.0.73",
]
[[package]]
@ -1803,13 +1848,13 @@ dependencies = [
[[package]]
name = "sha2"
version = "0.9.3"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de"
checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12"
dependencies = [
"block-buffer 0.9.0",
"cfg-if 1.0.0",
"cpuid-bool",
"cpufeatures",
"digest 0.9.0",
"opaque-debug 0.3.0",
]
@ -1869,13 +1914,13 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.71"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373"
checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
dependencies = [
"proc-macro2 1.0.26",
"proc-macro2 1.0.27",
"quote 1.0.9",
"unicode-xid 0.2.1",
"unicode-xid 0.2.2",
]
[[package]]
@ -1884,10 +1929,10 @@ version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
dependencies = [
"proc-macro2 1.0.26",
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.71",
"unicode-xid 0.2.1",
"syn 1.0.73",
"unicode-xid 0.2.2",
]
[[package]]
@ -1908,7 +1953,7 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
dependencies = [
"cfg-if 1.0.0",
"libc",
"rand 0.8.3",
"rand 0.8.4",
"redox_syscall",
"remove_dir_all",
"winapi",
@ -1958,9 +2003,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tracing"
version = "0.1.25"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f"
checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d"
dependencies = [
"cfg-if 1.0.0",
"pin-project-lite",
@ -1974,16 +2019,16 @@ version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2"
dependencies = [
"proc-macro2 1.0.26",
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.71",
"syn 1.0.73",
]
[[package]]
name = "tracing-core"
version = "0.1.17"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f"
checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052"
[[package]]
name = "typed-arena"
@ -2029,9 +2074,9 @@ dependencies = [
[[package]]
name = "unicode-normalization"
version = "0.1.17"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef"
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
dependencies = [
"tinyvec",
]
@ -2050,15 +2095,15 @@ checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
[[package]]
name = "unicode-xid"
version = "0.2.1"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "url"
version = "2.2.1"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b"
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
dependencies = [
"form_urlencoded",
"idna",
@ -2074,9 +2119,9 @@ checksum = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba"
[[package]]
name = "vcpkg"
version = "0.2.12"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbdbff6266a24120518560b5dc983096efb98462e51d0d68169895b237be3e5d"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "vec_map"
@ -2121,9 +2166,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "wasm-bindgen"
version = "0.2.73"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9"
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
dependencies = [
"cfg-if 1.0.0",
"wasm-bindgen-macro",
@ -2131,24 +2176,24 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.73"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae"
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
dependencies = [
"bumpalo",
"lazy_static",
"log",
"proc-macro2 1.0.26",
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.71",
"syn 1.0.73",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.23"
version = "0.4.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81b8b767af23de6ac18bf2168b690bed2902743ddf0fb39252e36f9e2bfc63ea"
checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1"
dependencies = [
"cfg-if 1.0.0",
"js-sys",
@ -2158,9 +2203,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.73"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f"
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
dependencies = [
"quote 1.0.9",
"wasm-bindgen-macro-support",
@ -2168,28 +2213,28 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.73"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c"
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
dependencies = [
"proc-macro2 1.0.26",
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.71",
"syn 1.0.73",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.73"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489"
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
[[package]]
name = "wasm-bindgen-test"
version = "0.3.23"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e972e914de63aa53bd84865e54f5c761bd274d48e5be3a6329a662c0386aa67a"
checksum = "8cab416a9b970464c2882ed92d55b0c33046b08e0bdc9d59b3b718acd4e1bae8"
dependencies = [
"console_error_panic_hook",
"js-sys",
@ -2201,19 +2246,19 @@ dependencies = [
[[package]]
name = "wasm-bindgen-test-macro"
version = "0.3.23"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6153a8f9bf24588e9f25c87223414fff124049f68d3a442a0f0eab4768a8b6"
checksum = "dd4543fc6cf3541ef0d98bf720104cc6bd856d7eba449fd2aa365ef4fed0e782"
dependencies = [
"proc-macro2 1.0.26",
"proc-macro2 1.0.27",
"quote 1.0.9",
]
[[package]]
name = "web-sys"
version = "0.3.50"
version = "0.3.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be"
checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
dependencies = [
"js-sys",
"wasm-bindgen",
@ -2265,9 +2310,9 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1"
dependencies = [
"proc-macro2 1.0.26",
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.71",
"syn 1.0.73",
"synstructure",
]
@ -2329,7 +2374,7 @@ dependencies = [
"cmake",
"csv",
"ff_ce 0.9.0",
"getrandom 0.2.2",
"getrandom 0.2.3",
"git2",
"hex",
"lazy_static",
@ -2343,7 +2388,7 @@ dependencies = [
"regex",
"serde",
"serde_json",
"sha2 0.9.3",
"sha2 0.9.5",
"typed-arena",
"wasm-bindgen-test",
"zokrates_common",
@ -2364,8 +2409,18 @@ dependencies = [
name = "zokrates_embed"
version = "0.1.3"
dependencies = [
"ark-bls12-377",
"ark-bw6-761",
"ark-crypto-primitives",
"ark-ec",
"ark-ff",
"ark-gm17",
"ark-r1cs-std",
"ark-relations",
"ark-std",
"bellman_ce",
"sapling-crypto_ce",
"zokrates_field",
]
[[package]]

View file

@ -6,5 +6,5 @@ set -e
if [ -n "$WITH_LIBSNARK" ]; then
cargo build --package zokrates_cli --features="libsnark"
else
cargo build
cargo build --package zokrates_cli
fi

View file

@ -6,5 +6,5 @@ set -e
if [ -n "$WITH_LIBSNARK" ]; then
cargo build --release --package zokrates_cli --features="libsnark"
else
cargo build --release
cargo build --release --package zokrates_cli
fi

View file

@ -0,0 +1 @@
Introduce the `snark_verify_bls12_377` embed for one-layer composition of SNARK proofs (over `BLS12-377`/`BW6-761` pair of curves where `BW6-761` is used as an outer curve to `BLS12-377`)

View file

@ -0,0 +1 @@
Add a CLI option `generate-smtlib2` to output the compiled IR as an SMT formula.

View file

@ -6,5 +6,5 @@ set -e
if [ -n "$WITH_LIBSNARK" ]; then
cargo test --release --package zokrates_cli --features="libsnark" -- --ignored
else
cargo test --release -- --ignored
cargo test --release --package zokrates_cli -- --ignored
fi

View file

@ -4,7 +4,9 @@
set -e
if [ -n "$WITH_LIBSNARK" ]; then
cargo test --release --package zokrates_cli --features="libsnark"
else
cargo test --release
# run specifically the libsnark tests inside zokrates_core
cargo test --release --package zokrates_core --features="libsnark" libsnark -- --test-threads=1
fi
# run all tests without libsnark on
cargo test --release

View file

@ -50,6 +50,7 @@ fn cli() -> Result<(), String> {
export_verifier::subcommand(),
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
generate_proof::subcommand(),
generate_smtlib2::subcommand(),
print_proof::subcommand(),
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
verify::subcommand()])
@ -66,6 +67,7 @@ fn cli() -> Result<(), String> {
("export-verifier", Some(sub_matches)) => export_verifier::exec(sub_matches),
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
("generate-proof", Some(sub_matches)) => generate_proof::exec(sub_matches),
("generate-smtlib2", Some(sub_matches)) => generate_smtlib2::exec(sub_matches),
("print-proof", Some(sub_matches)) => print_proof::exec(sub_matches),
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
("verify", Some(sub_matches)) => verify::exec(sub_matches),

View file

@ -7,6 +7,7 @@ pub const WITNESS_DEFAULT_PATH: &str = "witness";
pub const JSON_PROOF_PATH: &str = "proof.json";
pub const UNIVERSAL_SETUP_DEFAULT_PATH: &str = "universal_setup.dat";
pub const UNIVERSAL_SETUP_DEFAULT_SIZE: &str = "10";
pub const SMTLIB2_DEFAULT_PATH: &str = "out.smt2";
pub const BELLMAN: &str = "bellman";
pub const LIBSNARK: &str = "libsnark";

View file

@ -0,0 +1,64 @@
use crate::constants::{FLATTENED_CODE_DEFAULT_PATH, SMTLIB2_DEFAULT_PATH};
use clap::{App, Arg, ArgMatches, SubCommand};
use std::fs::File;
use std::io::{BufReader, Write};
use std::path::Path;
use zokrates_core::ir;
use zokrates_core::ir::smtlib2::SMTLib2Display;
use zokrates_core::ir::ProgEnum;
use zokrates_field::Field;
pub fn subcommand() -> App<'static, 'static> {
SubCommand::with_name("generate-smtlib2")
.about("Outputs the constraint system in the SMTLib2 format")
.arg(
Arg::with_name("input")
.short("i")
.long("input")
.help("Path of the binary")
.value_name("FILE")
.takes_value(true)
.required(false)
.default_value(FLATTENED_CODE_DEFAULT_PATH),
)
.arg(
Arg::with_name("output")
.short("o")
.long("output")
.help("Path of the output file")
.value_name("FILE")
.takes_value(true)
.required(false)
.default_value(SMTLIB2_DEFAULT_PATH),
)
}
pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> {
// read compiled program
let path = Path::new(sub_matches.value_of("input").unwrap());
let file =
File::open(&path).map_err(|why| format!("Could not open {}: {}", path.display(), why))?;
let mut reader = BufReader::new(file);
match ProgEnum::deserialize(&mut reader)? {
ProgEnum::Bn128Program(p) => cli_smtlib2(p, sub_matches),
ProgEnum::Bls12_377Program(p) => cli_smtlib2(p, sub_matches),
ProgEnum::Bls12_381Program(p) => cli_smtlib2(p, sub_matches),
ProgEnum::Bw6_761Program(p) => cli_smtlib2(p, sub_matches),
}
}
fn cli_smtlib2<T: Field>(ir_prog: ir::Prog<T>, sub_matches: &ArgMatches) -> Result<(), String> {
println!("Generating SMTLib2...");
let output_path = Path::new(sub_matches.value_of("output").unwrap());
let mut output_file = File::create(output_path).unwrap();
output_file
.write(format!("{}", SMTLib2Display(&ir_prog)).as_bytes())
.map_err(|why| format!("Could not save smtlib2: {:?}", why))?;
println!("SMTLib2 file written to '{}'", output_path.display());
Ok(())
}

View file

@ -4,6 +4,7 @@ pub mod compute_witness;
pub mod export_verifier;
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
pub mod generate_proof;
pub mod generate_smtlib2;
pub mod print_proof;
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
pub mod setup;

View file

@ -0,0 +1,15 @@
; Auto generated by ZoKrates
; Number of circuit variables: 5
; Number of equalities: 2
(declare-const |~prime| Int)
(declare-const |~out_0| Int)
(declare-const |~one| Int)
(declare-const |_0| Int)
(declare-const |_1| Int)
(declare-const |_2| Int)
(assert (and
(= |~prime| 21888242871839275222246405745257275088548364400416034343698204186575808495617)
(= |~one| 1)
(= (mod (* (+ (* |_0| 1) (* |_1| 1)) (+ (* |_0| 1) (* |_1| 1))) |~prime|) (mod (* |_2| 1) |~prime|))
(= (mod (* (* |~one| 1) (+ (* |_0| 3) (* |_2| 1))) |~prime|) (mod (* |~out_0| 1) |~prime|))
))

View file

@ -0,0 +1,17 @@
; Auto generated by ZoKrates
; Number of circuit variables: 5
; Number of equalities: 4
(declare-const |~prime| Int)
(declare-const |~out_0| Int)
(declare-const |~one| Int)
(declare-const |_0| Int)
(declare-const |_2| Int)
(declare-const |_3| Int)
(assert (and
(= |~prime| 21888242871839275222246405745257275088548364400416034343698204186575808495617)
(= |~one| 1)
(= (mod (* (+ (* |~one| 21888242871839275222246405745257275088548364400416034343698204186575808495616) (* |_0| 1)) (* |_3| 1)) |~prime|) (mod (* |_2| 1) |~prime|))
(= (mod (* (+ (* |~one| 1) (* |_2| 21888242871839275222246405745257275088548364400416034343698204186575808495616)) (+ (* |~one| 21888242871839275222246405745257275088548364400416034343698204186575808495616) (* |_0| 1))) |~prime|) (mod 0 |~prime|))
(= (mod (* (* |~one| 1) (+ (* |~one| 1) (* |_2| 21888242871839275222246405745257275088548364400416034343698204186575808495616))) |~prime|) (mod (* |~out_0| 1) |~prime|))
))

View file

@ -0,0 +1,17 @@
; Auto generated by ZoKrates
; Number of circuit variables: 5
; Number of equalities: 4
(declare-const |~prime| Int)
(declare-const |~out_0| Int)
(declare-const |~one| Int)
(declare-const |_0| Int)
(declare-const |_2| Int)
(declare-const |_3| Int)
(assert (and
(= |~prime| 21888242871839275222246405745257275088548364400416034343698204186575808495617)
(= |~one| 1)
(= (mod (* (+ (* |~one| 21888242871839275222246405745257275088548364400416034343698204186575808495616) (* |_0| 1)) (* |_3| 1)) |~prime|) (mod (* |_2| 1) |~prime|))
(= (mod (* (+ (* |~one| 1) (* |_2| 21888242871839275222246405745257275088548364400416034343698204186575808495616)) (+ (* |~one| 21888242871839275222246405745257275088548364400416034343698204186575808495616) (* |_0| 1))) |~prime|) (mod 0 |~prime|))
(= (mod (* (* |~one| 1) (+ (* |~one| 1) (* |_2| 21888242871839275222246405745257275088548364400416034343698204186575808495616))) |~prime|) (mod (* |~out_0| 1) |~prime|))
))

View file

@ -0,0 +1,21 @@
; Auto generated by ZoKrates
; Number of circuit variables: 9
; Number of equalities: 4
(declare-const |~prime| Int)
(declare-const |~out_3| Int)
(declare-const |~out_2| Int)
(declare-const |~out_1| Int)
(declare-const |~out_0| Int)
(declare-const |~one| Int)
(declare-const |_0| Int)
(declare-const |_1| Int)
(declare-const |_2| Int)
(declare-const |_3| Int)
(assert (and
(= |~prime| 21888242871839275222246405745257275088548364400416034343698204186575808495617)
(= |~one| 1)
(= (mod (* (* |~one| 1) (* |_0| 1)) |~prime|) (mod (* |~out_0| 1) |~prime|))
(= (mod (* (* |~one| 1) (* |_1| 1)) |~prime|) (mod (* |~out_1| 1) |~prime|))
(= (mod (* (* |~one| 1) (* |_2| 1)) |~prime|) (mod (* |~out_2| 1) |~prime|))
(= (mod (* (* |~one| 1) (* |~one| 42)) |~prime|) (mod (* |~out_3| 1) |~prime|))
))

View file

@ -0,0 +1,12 @@
; Auto generated by ZoKrates
; Number of circuit variables: 3
; Number of equalities: 1
(declare-const |~prime| Int)
(declare-const |~one| Int)
(declare-const |_0| Int)
(declare-const |_1| Int)
(assert (and
(= |~prime| 21888242871839275222246405745257275088548364400416034343698204186575808495617)
(= |~one| 1)
(= (mod (* (* |~one| 1) (* |_0| 1)) |~prime|) (mod (* |_1| 1) |~prime|))
))

View file

@ -0,0 +1,33 @@
; Auto generated by ZoKrates
; Number of circuit variables: 17
; Number of equalities: 8
(declare-const |~prime| Int)
(declare-const |~out_7| Int)
(declare-const |~out_6| Int)
(declare-const |~out_5| Int)
(declare-const |~out_4| Int)
(declare-const |~out_3| Int)
(declare-const |~out_2| Int)
(declare-const |~out_1| Int)
(declare-const |~out_0| Int)
(declare-const |~one| Int)
(declare-const |_0| Int)
(declare-const |_1| Int)
(declare-const |_2| Int)
(declare-const |_3| Int)
(declare-const |_4| Int)
(declare-const |_5| Int)
(declare-const |_6| Int)
(declare-const |_7| Int)
(assert (and
(= |~prime| 21888242871839275222246405745257275088548364400416034343698204186575808495617)
(= |~one| 1)
(= (mod (* (* |~one| 1) (* |_3| 1)) |~prime|) (mod (* |~out_0| 1) |~prime|))
(= (mod (* (* |~one| 1) (* |_0| 1)) |~prime|) (mod (* |~out_1| 1) |~prime|))
(= (mod (* (* |~one| 1) (* |_1| 1)) |~prime|) (mod (* |~out_2| 1) |~prime|))
(= (mod (* (* |~one| 1) (* |_2| 1)) |~prime|) (mod (* |~out_3| 1) |~prime|))
(= (mod (* (* |~one| 1) (* |_4| 1)) |~prime|) (mod (* |~out_4| 1) |~prime|))
(= (mod (* (* |~one| 1) (* |_5| 1)) |~prime|) (mod (* |~out_5| 1) |~prime|))
(= (mod (* (* |~one| 1) (* |_6| 1)) |~prime|) (mod (* |~out_6| 1) |~prime|))
(= (mod (* (* |~one| 1) (* |_7| 1)) |~prime|) (mod (* |~out_7| 1) |~prime|))
))

View file

@ -0,0 +1,13 @@
; Auto generated by ZoKrates
; Number of circuit variables: 4
; Number of equalities: 1
(declare-const |~prime| Int)
(declare-const |~out_0| Int)
(declare-const |~one| Int)
(declare-const |_0| Int)
(declare-const |_1| Int)
(assert (and
(= |~prime| 21888242871839275222246405745257275088548364400416034343698204186575808495617)
(= |~one| 1)
(= (mod (* (* |~one| 1) (+ (* |_0| 1) (* |_1| 1))) |~prime|) (mod (* |~out_0| 1) |~prime|))
))

View file

@ -0,0 +1,16 @@
; Auto generated by ZoKrates
; Number of circuit variables: 6
; Number of equalities: 2
(declare-const |~prime| Int)
(declare-const |~out_0| Int)
(declare-const |~one| Int)
(declare-const |_0| Int)
(declare-const |_1| Int)
(declare-const |_2| Int)
(declare-const |_3| Int)
(assert (and
(= |~prime| 21888242871839275222246405745257275088548364400416034343698204186575808495617)
(= |~one| 1)
(= (mod (* (* |_0| 1) (* |_1| 1)) |~prime|) (mod (* |_3| 1) |~prime|))
(= (mod (* (* |_3| 1) (* |_2| 1)) |~prime|) (mod (* |~out_0| 1) |~prime|))
))

File diff suppressed because one or more lines are too long

View file

@ -330,4 +330,78 @@ mod integration {
}
}
}
fn test_compile_and_smtlib2(
program_name: &str,
program_path: &Path,
expected_smtlib2_path: &Path,
) {
let tmp_dir = TempDir::new(".tmp").unwrap();
let tmp_base = tmp_dir.path();
let test_case_path = tmp_base.join(program_name);
let flattened_path = tmp_base.join(program_name).join("out");
let smtlib2_path = tmp_base.join(program_name).join("out.smt2");
// create a tmp folder to store artifacts
fs::create_dir(test_case_path).unwrap();
let stdlib = std::fs::canonicalize("../zokrates_stdlib/stdlib").unwrap();
// prepare compile arguments
let compile = vec![
"../target/release/zokrates",
"compile",
"-i",
program_path.to_str().unwrap(),
"--stdlib-path",
stdlib.to_str().unwrap(),
"-o",
flattened_path.to_str().unwrap(),
];
// compile
assert_cli::Assert::command(&compile).succeeds().unwrap();
// prepare generate-smtlib2 arguments
let gen = vec![
"../target/release/zokrates",
"generate-smtlib2",
"-i",
flattened_path.to_str().unwrap(),
"-o",
smtlib2_path.to_str().unwrap(),
];
// generate-smtlib2
assert_cli::Assert::command(&gen).succeeds().unwrap();
// load the expected smtlib2
let mut expected_smtlib2_file = File::open(&expected_smtlib2_path).unwrap();
let mut expected_smtlib2 = String::new();
expected_smtlib2_file
.read_to_string(&mut expected_smtlib2)
.unwrap();
// load the actual smtlib2
let mut smtlib2_file = File::open(&smtlib2_path).unwrap();
let mut smtlib2 = String::new();
smtlib2_file.read_to_string(&mut smtlib2).unwrap();
assert_eq!(expected_smtlib2, smtlib2);
}
#[test]
fn test_compile_and_smtlib2_dir() {
let dir = Path::new("./tests/code");
assert!(dir.is_dir());
for entry in fs::read_dir(dir).unwrap() {
let entry = entry.unwrap();
let path = entry.path();
if path.extension().unwrap() == "smt2" {
let program_name = Path::new(path.file_stem().unwrap());
let prog = dir.join(program_name).with_extension("zok");
test_compile_and_smtlib2(program_name.to_str().unwrap(), &prog, &path);
}
}
}
}

View file

@ -1,6 +1,6 @@
#include "ffi.hpp"
void __free(uint8_t* ptr)
void c_free(uint8_t* ptr)
{
free(ptr);
}

View file

@ -30,7 +30,7 @@ struct proof_result_t {
}
};
void __free(uint8_t* ptr);
void c_free(uint8_t* ptr);
#ifdef __cplusplus
} // extern "C"

View file

@ -8,14 +8,19 @@ use crate::typed_absy::types::{
GenericIdentifier,
};
use std::collections::HashMap;
use zokrates_field::{Bn128Field, Field};
use zokrates_field::Field;
cfg_if::cfg_if! {
if #[cfg(feature = "bellman")] {
use pairing_ce::bn256::Bn256;
use pairing_ce::ff::{PrimeField, PrimeFieldRepr};
use pairing_ce::Engine;
use zokrates_embed::{generate_sha256_round_constraints, BellmanConstraint};
use zokrates_embed::{bellman::{from_bellman, generate_sha256_round_constraints}};
}
}
cfg_if::cfg_if! {
if #[cfg(feature = "ark")] {
use ark_bls12_377::Bls12_377;
use zokrates_embed::ark::{from_ark, generate_verify_constraints};
}
}
@ -24,8 +29,6 @@ cfg_if::cfg_if! {
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
pub enum FlatEmbed {
U32ToField,
#[cfg(feature = "bellman")]
Sha256Round,
Unpack,
U8ToBits,
U16ToBits,
@ -35,6 +38,10 @@ pub enum FlatEmbed {
U16FromBits,
U32FromBits,
U64FromBits,
#[cfg(feature = "bellman")]
Sha256Round,
#[cfg(feature = "ark")]
SnarkVerifyBls12377,
}
impl FlatEmbed {
@ -116,6 +123,36 @@ impl FlatEmbed {
DeclarationType::Boolean,
256usize,
))]),
#[cfg(feature = "ark")]
FlatEmbed::SnarkVerifyBls12377 => DeclarationSignature::new()
.generics(vec![
Some(DeclarationConstant::Generic(GenericIdentifier {
name: "N",
index: 0,
})),
Some(DeclarationConstant::Generic(GenericIdentifier {
name: "V",
index: 1,
})),
])
.inputs(vec![
DeclarationType::array((
DeclarationType::FieldElement,
GenericIdentifier {
name: "N",
index: 0,
},
)), // inputs
DeclarationType::array((DeclarationType::FieldElement, 8usize)), // proof
DeclarationType::array((
DeclarationType::FieldElement,
GenericIdentifier {
name: "V",
index: 1,
},
)), // 18 + (2 * n) // vk
])
.outputs(vec![DeclarationType::Boolean]),
}
}
@ -136,8 +173,6 @@ impl FlatEmbed {
pub fn id(&self) -> &'static str {
match self {
FlatEmbed::U32ToField => "_U32_TO_FIELD",
#[cfg(feature = "bellman")]
FlatEmbed::Sha256Round => "_SHA256_ROUND",
FlatEmbed::Unpack => "_UNPACK",
FlatEmbed::U8ToBits => "_U8_TO_BITS",
FlatEmbed::U16ToBits => "_U16_TO_BITS",
@ -147,15 +182,21 @@ impl FlatEmbed {
FlatEmbed::U16FromBits => "_U16_FROM_BITS",
FlatEmbed::U32FromBits => "_U32_FROM_BITS",
FlatEmbed::U64FromBits => "_U64_FROM_BITS",
#[cfg(feature = "bellman")]
FlatEmbed::Sha256Round => "_SHA256_ROUND",
#[cfg(feature = "ark")]
FlatEmbed::SnarkVerifyBls12377 => "_SNARK_VERIFY_BLS12_377",
}
}
/// Actually get the `FlatFunction` that this `FlatEmbed` represents
pub fn synthetize<T: Field>(&self, generics: &[u32]) -> FlatFunction<T> {
match self {
FlatEmbed::Unpack => unpack_to_bitwidth(generics[0] as usize),
#[cfg(feature = "bellman")]
FlatEmbed::Sha256Round => sha256_round(),
FlatEmbed::Unpack => unpack_to_bitwidth(generics[0] as usize),
#[cfg(feature = "ark")]
FlatEmbed::SnarkVerifyBls12377 => snark_verify_bls12_377(generics[0] as usize),
_ => unreachable!(),
}
}
@ -163,40 +204,26 @@ impl FlatEmbed {
// util to convert a vector of `(variable_id, coefficient)` to a flat_expression
// we build a binary tree of additions by splitting the vector recursively
#[cfg(feature = "bellman")]
fn flat_expression_from_vec<T: Field, E: Engine>(v: &[(usize, E::Fr)]) -> FlatExpression<T> {
fn flat_expression_from_vec<T: Field>(v: &[(usize, T)]) -> FlatExpression<T> {
match v.len() {
0 => FlatExpression::Number(T::zero()),
1 => {
let (key, val) = v[0];
let mut res: Vec<u8> = vec![];
val.into_repr().write_le(&mut res).unwrap();
let (key, val) = v[0].clone();
FlatExpression::Mult(
box FlatExpression::Number(T::from_byte_vector(res)),
box FlatExpression::Number(val),
box FlatExpression::Identifier(FlatVariable::new(key)),
)
}
n => {
let (u, v) = v.split_at(n / 2);
FlatExpression::Add(
box flat_expression_from_vec::<T, E>(u),
box flat_expression_from_vec::<T, E>(v),
box flat_expression_from_vec::<T>(u),
box flat_expression_from_vec::<T>(v),
)
}
}
}
#[cfg(feature = "bellman")]
impl<T: Field, E: Engine> From<BellmanConstraint<E>> for FlatStatement<T> {
fn from(c: BellmanConstraint<E>) -> FlatStatement<T> {
let rhs_a = flat_expression_from_vec::<T, E>(&c.a);
let rhs_b = flat_expression_from_vec::<T, E>(&c.b);
let lhs = flat_expression_from_vec::<T, E>(&c.c);
FlatStatement::Condition(lhs, FlatExpression::Mult(box rhs_a, box rhs_b))
}
}
/// Returns a flat function which computes a sha256 round
///
/// # Remarks
@ -206,6 +233,7 @@ impl<T: Field, E: Engine> From<BellmanConstraint<E>> for FlatStatement<T> {
/// - arguments
#[cfg(feature = "bellman")]
pub fn sha256_round<T: Field>() -> FlatFunction<T> {
use zokrates_field::Bn128Field;
assert_eq!(T::id(), Bn128Field::id());
// Define iterators for all indices at hand
@ -254,7 +282,15 @@ pub fn sha256_round<T: Field>() -> FlatFunction<T> {
)
});
// insert flattened statements to represent constraints
let constraint_statements = r1cs.constraints.into_iter().map(|c| c.into());
let constraint_statements = r1cs.constraints.into_iter().map(|c| {
let c = from_bellman::<T, Bn256>(c);
let rhs_a = flat_expression_from_vec::<T>(c.a.as_slice());
let rhs_b = flat_expression_from_vec::<T>(c.b.as_slice());
let lhs = flat_expression_from_vec::<T>(c.c.as_slice());
FlatStatement::Condition(lhs, FlatExpression::Mult(box rhs_a, box rhs_b))
});
// define which subset of the witness is returned
let outputs: Vec<FlatExpression<T>> = output_indices
.map(|o| FlatExpression::Identifier(FlatVariable::new(o)))
@ -284,6 +320,105 @@ pub fn sha256_round<T: Field>() -> FlatFunction<T> {
}
}
#[cfg(feature = "ark")]
pub fn snark_verify_bls12_377<T: Field>(n: usize) -> FlatFunction<T> {
use zokrates_field::Bw6_761Field;
assert_eq!(T::id(), Bw6_761Field::id());
let (out_index, input_indices, proof_indices, vk_indices, constraints, variable_count) =
generate_verify_constraints(n);
let cs_indices = 0..variable_count;
let input_indices = input_indices.into_iter();
let proof_indices = proof_indices.into_iter();
let vk_indices = vk_indices.into_iter();
// indices of the arguments to the function
let input_argument_indices = input_indices.clone().map(|i| i + variable_count);
let proof_argument_indices = proof_indices.clone().map(|i| i + variable_count);
let vk_argument_indices = vk_indices.clone().map(|i| i + variable_count);
let input_arguments = input_argument_indices
.clone()
.map(|i| FlatParameter::private(FlatVariable::new(i)));
let proof_arguments = proof_argument_indices
.clone()
.map(|i| FlatParameter::private(FlatVariable::new(i)));
let vk_arguments = vk_argument_indices
.clone()
.map(|i| FlatParameter::private(FlatVariable::new(i)));
let arguments = input_arguments
.chain(proof_arguments)
.chain(vk_arguments)
.collect();
let one_binding_statement = FlatStatement::Condition(
FlatExpression::Identifier(FlatVariable::new(0)),
FlatExpression::Number(T::from(1)),
);
let input_binding_statements: Vec<_> = input_indices
.chain(proof_indices)
.chain(vk_indices)
.zip(
input_argument_indices
.clone()
.chain(proof_argument_indices.clone())
.chain(vk_argument_indices.clone()),
)
.map(|(cs_index, argument_index)| {
FlatStatement::Condition(
FlatVariable::new(cs_index).into(),
FlatVariable::new(argument_index).into(),
)
})
.collect();
let constraint_statements: Vec<FlatStatement<T>> = constraints
.into_iter()
.map(|c| {
let c = from_ark::<T, Bls12_377>(c);
let rhs_a = flat_expression_from_vec::<T>(c.a.as_slice());
let rhs_b = flat_expression_from_vec::<T>(c.b.as_slice());
let lhs = flat_expression_from_vec::<T>(c.c.as_slice());
FlatStatement::Condition(lhs, FlatExpression::Mult(box rhs_a, box rhs_b))
})
.collect();
let return_statement = FlatStatement::Return(FlatExpressionList {
expressions: vec![FlatExpression::Identifier(FlatVariable::new(out_index))],
});
// insert a directive to set the witness
let directive_statement = FlatStatement::Directive(FlatDirective {
outputs: cs_indices.map(FlatVariable::new).collect(),
inputs: input_argument_indices
.chain(proof_argument_indices)
.chain(vk_argument_indices)
.map(|i| FlatVariable::new(i).into())
.collect(),
solver: Solver::SnarkVerifyBls12377(n),
});
let statements: Vec<_> = std::iter::once(directive_statement)
.chain(std::iter::once(one_binding_statement))
.chain(input_binding_statements)
.chain(constraint_statements)
.chain(std::iter::once(return_statement))
.collect();
FlatFunction {
arguments,
statements,
}
}
fn use_variable(
layout: &mut HashMap<String, FlatVariable>,
name: String,

View file

@ -17,7 +17,7 @@ use std::path::{Path, PathBuf};
use crate::absy::types::UnresolvedType;
use typed_arena::Arena;
use zokrates_common::Resolver;
use zokrates_field::{Bn128Field, Field};
use zokrates_field::{Bn128Field, Bw6_761Field, Field};
#[derive(PartialEq, Debug)]
pub struct Error {
@ -107,7 +107,8 @@ impl Importer {
if T::id() != Bn128Field::id() {
return Err(CompileErrorInner::ImportError(
Error::new(format!(
"Embed sha256round cannot be used with curve {}",
"`sha256round` is expected to be compiled over `{}` curve, but found `{}`",
Bn128Field::name(),
T::name()
))
.with_pos(Some(pos)),
@ -121,6 +122,26 @@ impl Importer {
}
}
}
#[cfg(feature = "ark")]
"snark_verify_bls12_377" => {
if T::id() != Bw6_761Field::id() {
return Err(CompileErrorInner::ImportError(
Error::new(format!(
"`snark_verify_bls12_377` is expected to be compiled over `{}` curve, but found `{}`",
Bw6_761Field::name(),
T::name()
))
.with_pos(Some(pos)),
)
.in_file(location)
.into());
} else {
SymbolDeclaration {
id: symbol.get_alias(),
symbol: Symbol::Flat(FlatEmbed::SnarkVerifyBls12377),
}
}
}
"unpack" => SymbolDeclaration {
id: symbol.get_alias(),
symbol: Symbol::Flat(FlatEmbed::Unpack),

View file

@ -6,8 +6,9 @@ use pairing_ce::bn256::Bn256;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::fmt;
use zokrates_embed::ark::generate_verify_witness;
#[cfg(feature = "bellman")]
use zokrates_embed::generate_sha256_round_witness;
use zokrates_embed::bellman::generate_sha256_round_witness;
use zokrates_field::Field;
pub type ExecutionResult<T> = Result<Witness<T>, Error>;
@ -144,7 +145,7 @@ impl Interpreter {
inputs: &[T],
) -> Result<Vec<T>, String> {
let (expected_input_count, expected_output_count) = solver.get_signature();
assert!(inputs.len() == expected_input_count);
assert_eq!(inputs.len(), expected_input_count);
let res = match solver {
Solver::ConditionEq => match inputs[0].is_zero() {
@ -233,6 +234,17 @@ impl Interpreter {
})
.collect()
}
#[cfg(feature = "ark")]
Solver::SnarkVerifyBls12377(n) => {
use zokrates_field::Bw6_761Field;
assert_eq!(T::id(), Bw6_761Field::id());
generate_verify_witness(
&inputs[..*n],
&inputs[*n..*n + 8usize],
&inputs[*n + 8usize..],
)
}
};
assert_eq!(res.len(), expected_output_count);

View file

@ -11,6 +11,8 @@ pub mod folder;
mod from_flat;
mod interpreter;
mod serialize;
pub mod smtlib2;
pub mod visitor;
mod witness;
pub use self::expression::QuadComb;

View file

@ -0,0 +1,141 @@
use num_bigint::BigUint;
use std::collections::BTreeSet;
use super::*;
use zokrates_field::Field;
use super::expression::LinComb;
use super::expression::QuadComb;
use super::visitor::*;
pub trait SMTLib2 {
fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result;
}
impl<T: Field> SMTLib2 for Prog<T> {
fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.main.to_smtlib2(f)
}
}
pub struct SMTLib2Display<'a, T>(pub &'a Prog<T>);
impl<T: Field> fmt::Display for SMTLib2Display<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.to_smtlib2(f)
}
}
struct FlatVariableCollector {
variables: BTreeSet<FlatVariable>,
}
impl<T: Field> Visitor<T> for FlatVariableCollector {
fn visit_variable(&mut self, v: &FlatVariable) {
self.variables.insert(*v);
}
}
impl<T: Field> SMTLib2 for Function<T> {
fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut collector = FlatVariableCollector {
variables: BTreeSet::<FlatVariable>::new(),
};
collector.visit_function(self);
collector.variables.insert(FlatVariable::one());
writeln!(f, "; Auto generated by ZoKrates")?;
writeln!(
f,
"; Number of circuit variables: {}",
collector.variables.len()
)?;
writeln!(f, "; Number of equalities: {}", self.statements.len())?;
writeln!(f, "(declare-const |~prime| Int)")?;
for v in collector.variables.iter() {
writeln!(f, "(declare-const |{}| Int)", v)?;
}
writeln!(f, "(assert (and")?;
writeln!(f, "(= |~prime| {})", T::max_value().to_biguint() + 1usize)?;
writeln!(f, "(= |~one| 1)")?;
for s in &self.statements {
s.to_smtlib2(f)?;
writeln!(f)?;
}
write!(f, "))")
}
}
fn format_prefix_op_smtlib2<T: SMTLib2, Ts: SMTLib2>(
f: &mut fmt::Formatter,
op: &str,
a: &T,
b: &Ts,
) -> fmt::Result {
write!(f, "({} ", op)?;
a.to_smtlib2(f)?;
write!(f, " ")?;
b.to_smtlib2(f)?;
write!(f, ")")
}
impl<T: Field> SMTLib2 for Statement<T> {
fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Statement::Constraint(ref quad, ref lin) => {
write!(f, "(= (mod ")?;
quad.to_smtlib2(f)?;
write!(f, " |~prime|) (mod ")?;
lin.to_smtlib2(f)?;
write!(f, " |~prime|))")
}
Statement::Directive(ref s) => s.to_smtlib2(f),
}
}
}
impl<T: Field> SMTLib2 for Directive<T> {
fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "")
}
}
impl<T: Field> SMTLib2 for QuadComb<T> {
fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result {
format_prefix_op_smtlib2(f, "*", &self.left, &self.right)
}
}
impl<T: Field> SMTLib2 for LinComb<T> {
fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.is_zero() {
true => write!(f, "0"),
false => {
if self.0.len() > 1 {
write!(f, "(+")?;
for expr in self.0.iter() {
write!(f, " ")?;
format_prefix_op_smtlib2(f, "*", &expr.0, &expr.1.to_biguint())?;
}
write!(f, ")")
} else {
format_prefix_op_smtlib2(f, "*", &self.0[0].0, &self.0[0].1.to_biguint())
}
}
}
}
}
impl SMTLib2 for FlatVariable {
fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "|{}|", self)
}
}
impl SMTLib2 for BigUint {
fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self)
}
}

View file

@ -0,0 +1,98 @@
// Generic walk through an IR AST. Not mutating in place
use crate::flat_absy::flat_variable::FlatVariable;
use crate::ir::*;
use zokrates_field::Field;
pub trait Visitor<T: Field>: Sized {
fn visit_module(&mut self, p: &Prog<T>) {
visit_module(self, p)
}
fn visit_function(&mut self, f: &Function<T>) {
visit_function(self, f)
}
fn visit_argument(&mut self, p: &FlatVariable) {
visit_argument(self, p)
}
fn visit_variable(&mut self, v: &FlatVariable) {
visit_variable(self, v)
}
fn visit_value(&mut self, v: &T) {
visit_value(self, v)
}
fn visit_statement(&mut self, s: &Statement<T>) {
visit_statement(self, s)
}
fn visit_linear_combination(&mut self, e: &LinComb<T>) {
visit_linear_combination(self, e)
}
fn visit_quadratic_combination(&mut self, es: &QuadComb<T>) {
visit_quadratic_combination(self, es)
}
fn visit_directive(&mut self, d: &Directive<T>) {
visit_directive(self, d)
}
}
pub fn visit_module<T: Field, F: Visitor<T>>(f: &mut F, p: &Prog<T>) {
f.visit_function(&p.main)
}
pub fn visit_statement<T: Field, F: Visitor<T>>(f: &mut F, s: &Statement<T>) {
match s {
Statement::Constraint(quad, lin) => {
f.visit_quadratic_combination(quad);
f.visit_linear_combination(lin);
}
Statement::Directive(dir) => f.visit_directive(dir),
}
}
pub fn visit_linear_combination<T: Field, F: Visitor<T>>(f: &mut F, e: &LinComb<T>) {
for expr in e.0.iter() {
f.visit_variable(&expr.0);
f.visit_value(&expr.1);
}
}
pub fn visit_quadratic_combination<T: Field, F: Visitor<T>>(f: &mut F, e: &QuadComb<T>) {
f.visit_linear_combination(&e.left);
f.visit_linear_combination(&e.right);
}
pub fn visit_directive<T: Field, F: Visitor<T>>(f: &mut F, ds: &Directive<T>) {
for expr in ds.inputs.iter() {
f.visit_quadratic_combination(expr);
}
for expr in ds.outputs.iter() {
f.visit_variable(expr);
}
}
pub fn visit_function<T: Field, F: Visitor<T>>(f: &mut F, fun: &Function<T>) {
for expr in fun.arguments.iter() {
f.visit_argument(expr);
}
for expr in fun.statements.iter() {
f.visit_statement(expr);
}
for expr in fun.returns.iter() {
f.visit_variable(expr);
}
}
pub fn visit_argument<T: Field, F: Visitor<T>>(f: &mut F, a: &FlatVariable) {
f.visit_variable(a)
}
pub fn visit_variable<T: Field, F: Visitor<T>>(_f: &mut F, _v: &FlatVariable) {}
pub fn visit_value<T: Field, F: Visitor<T>>(_f: &mut F, _v: &T) {}

View file

@ -1,6 +1,6 @@
#[repr(C)]
pub struct Buffer {
pub data: *mut u8,
pub data: *const u8,
pub length: i32,
}
@ -16,33 +16,17 @@ pub struct ProofResult {
}
extern "C" {
fn __free(ptr: *mut u8);
pub fn c_free(ptr: *const u8);
}
impl Buffer {
pub fn from_vec(v: &Vec<u8>) -> Buffer {
let mut buf = vec![0; v.len()].into_boxed_slice();
buf.copy_from_slice(v.as_slice());
let data = buf.as_mut_ptr();
let len = buf.len();
std::mem::forget(buf);
let data = v.as_ptr();
let len = v.len();
Buffer {
data,
length: len as i32,
}
}
pub unsafe fn drop(&self) {
let s = std::slice::from_raw_parts_mut(self.data, self.length as usize);
let s = s.as_mut_ptr();
Box::from_raw(s);
}
/// The purpose of this function is to free memory allocated by C. Do not use otherwise.
pub fn free(self) {
unsafe { __free(self.data) };
}
}

View file

@ -1,6 +1,6 @@
use crate::ir::{Prog, Witness};
use crate::proof_system::gm17::{ProofPoints, VerificationKey, GM17};
use crate::proof_system::libsnark::ffi::{Buffer, ProofResult, SetupResult};
use crate::proof_system::libsnark::ffi::{c_free, Buffer, ProofResult, SetupResult};
use crate::proof_system::libsnark::{
prepare_generate_proof, prepare_public_inputs, prepare_setup, serialization::*, Libsnark,
};
@ -47,9 +47,9 @@ impl Backend<Bn128Field, GM17> for Libsnark {
let (public_inputs_arr, public_inputs_length, private_inputs_arr, private_inputs_length) =
prepare_generate_proof(program.clone(), witness.clone());
let proof = unsafe {
let mut pk_buffer = Buffer::from_vec(&proving_key);
let mut pk_buffer = Buffer::from_vec(&proving_key);
let proof = unsafe {
let result = gm17_bn128_generate_proof(
&mut pk_buffer as *mut _,
public_inputs_arr[0].as_ptr(),
@ -58,14 +58,11 @@ impl Backend<Bn128Field, GM17> for Libsnark {
private_inputs_length as i32,
);
pk_buffer.drop(); // drop the buffer manually
let proof: Vec<u8> =
std::slice::from_raw_parts(result.proof.data, result.proof.length as usize)
.to_vec();
let proof = std::slice::from_raw_parts(result.proof.data, result.proof.length as usize)
.to_vec();
// free c allocated buffer
result.proof.free();
c_free(result.proof.data);
proof
};
@ -118,21 +115,16 @@ impl Backend<Bn128Field, GM17> for Libsnark {
let (public_inputs_arr, public_inputs_length) = prepare_public_inputs(public_inputs);
unsafe {
let mut vk_buffer = Buffer::from_vec(vk_writer.get_ref());
let mut proof_buffer = Buffer::from_vec(proof_writer.get_ref());
let mut vk_buffer = Buffer::from_vec(vk_writer.get_ref());
let mut proof_buffer = Buffer::from_vec(proof_writer.get_ref());
let ans = gm17_bn128_verify(
unsafe {
gm17_bn128_verify(
&mut vk_buffer as *mut _,
&mut proof_buffer as *mut _,
public_inputs_arr[0].as_ptr(),
public_inputs_length as i32,
);
vk_buffer.drop();
proof_buffer.drop();
ans
)
}
}
}
@ -163,8 +155,8 @@ impl NonUniversalBackend<Bn128Field, GM17> for Libsnark {
std::slice::from_raw_parts(result.pk.data, result.pk.length as usize).to_vec();
// free c allocated buffers
result.vk.free();
result.pk.free();
c_free(result.vk.data);
c_free(result.pk.data);
(vk, pk)
};

View file

@ -1,4 +1,4 @@
use crate::proof_system::libsnark::ffi::{Buffer, ProofResult, SetupResult};
use crate::proof_system::libsnark::ffi::{c_free, Buffer, ProofResult, SetupResult};
use crate::proof_system::libsnark::{
prepare_generate_proof, prepare_public_inputs, prepare_setup, Libsnark,
};
@ -50,9 +50,9 @@ impl Backend<Bn128Field, PGHR13> for Libsnark {
let (public_inputs_arr, public_inputs_length, private_inputs_arr, private_inputs_length) =
prepare_generate_proof(program.clone(), witness.clone());
let proof = unsafe {
let mut pk_buffer = Buffer::from_vec(&proving_key);
let mut pk_buffer = Buffer::from_vec(&proving_key);
let proof = unsafe {
let result = pghr13_bn128_generate_proof(
&mut pk_buffer as *mut _,
public_inputs_arr[0].as_ptr(),
@ -61,14 +61,11 @@ impl Backend<Bn128Field, PGHR13> for Libsnark {
private_inputs_length as i32,
);
pk_buffer.drop(); // drop the buffer manually
let proof: Vec<u8> =
std::slice::from_raw_parts(result.proof.data, result.proof.length as usize)
.to_vec();
let proof = std::slice::from_raw_parts(result.proof.data, result.proof.length as usize)
.to_vec();
// free c allocated buffer
result.proof.free();
c_free(result.proof.data);
proof
};
@ -144,21 +141,16 @@ impl Backend<Bn128Field, PGHR13> for Libsnark {
let (public_inputs_arr, public_inputs_length) = prepare_public_inputs(public_inputs);
unsafe {
let mut vk_buffer = Buffer::from_vec(vk_writer.get_ref());
let mut proof_buffer = Buffer::from_vec(proof_writer.get_ref());
let mut vk_buffer = Buffer::from_vec(vk_writer.get_ref());
let mut proof_buffer = Buffer::from_vec(proof_writer.get_ref());
let ans = pghr13_bn128_verify(
unsafe {
pghr13_bn128_verify(
&mut vk_buffer as *mut _,
&mut proof_buffer as *mut _,
public_inputs_arr[0].as_ptr(),
public_inputs_length as i32,
);
vk_buffer.drop();
proof_buffer.drop();
ans
)
}
}
}
@ -189,8 +181,8 @@ impl NonUniversalBackend<Bn128Field, PGHR13> for Libsnark {
std::slice::from_raw_parts(result.pk.data, result.pk.length as usize).to_vec();
// free c allocated buffers
result.vk.free();
result.pk.free();
c_free(result.vk.data);
c_free(result.pk.data);
(vk, pk)
};

View file

@ -13,6 +13,8 @@ pub enum Solver {
EuclideanDiv,
#[cfg(feature = "bellman")]
Sha256Round,
#[cfg(feature = "ark")]
SnarkVerifyBls12377(usize),
}
impl fmt::Display for Solver {
@ -34,6 +36,8 @@ impl Solver {
Solver::EuclideanDiv => (2, 2),
#[cfg(feature = "bellman")]
Solver::Sha256Round => (768, 26935),
#[cfg(feature = "ark")]
Solver::SnarkVerifyBls12377(n) => (26 + 3 * n, 41991 + 4972 * n),
}
}
}

View file

@ -542,7 +542,7 @@ mod tests {
let constants: TypedConstantSymbols<_> = vec![(
CanonicalConstantIdentifier::new(const_id, "main".into()),
TypedConstantSymbol::Here(TypedConstant::new(
GType::FieldElement,
GType::array(GArrayType::new(GType::FieldElement, 2usize)),
TypedExpression::Array(
ArrayExpressionInner::Value(
vec![

View file

@ -582,7 +582,10 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
_ => unreachable!("should be a field value"),
}
}
#[cfg(feature = "bellman")]
FlatEmbed::Sha256Round => None,
#[cfg(feature = "ark")]
FlatEmbed::SnarkVerifyBls12377 => None,
};
match r {

View file

@ -0,0 +1,46 @@
{
"entry_point": "./tests/tests/snark/snark_verify_bls12_377_1.zok",
"curves": ["Bw6_761"],
"tests": [
{
"input": {
"values": [
"14854361253166356985827940126714566475275412573126716429346293669288261212877767002588736768495892518280555332082",
"213732210873464696846782550184555137228225514409080200587629835423679101735680889388490505365220726936653232900722",
"87538607630632344401950048588801759619324114043687193925268161368645768079512372989046887060116208844098222887523",
"5657143080315521889991799092902512094315245718355471372723437558193333983953910948320586493950523700874011063560",
"57443068623489368358651325326719858590550354409074784986003051193396111859230778144944186401073595967957696940521",
"239017299818740889416561988179003000999440599788233589838386981563280711497257601212385904595560069610856834048609",
"210817940648895568697680255986492415724502544301527123629003695092329489846191300997148203752109923795482648905049",
"104796720182429147963427519368170838521257629224027565408974396362211239635140389257768036297199752289691646178885",
"1",
"237849156256827398282019388933972533154056715710612980343582379691235964002811111531637163291964836316287473866944",
"121324456153144638357885760921484124420296650752569739652599982435599667566663818850130137668154167962818124679946",
"73600332144130508132510040050892177274732799381796146541825372722030832659283233558443467575385522990242420388929",
"44732797483932307692113794160403754043679743522093845554740681666841720206796756514002159097899004452746371432672",
"11133333007786916806537653763736510041397904969121754556887982143919681840159919608974969747422557814633960596319",
"90561577672782365102721874737156537447800052875073945376839636447536979602099666234669817779872333362600029687267",
"5450223346768511418345330845468131514992561567665451102957435878264997759483533580796977034429945593412389724558",
"235853237950439075722577332685219091953664185148611937130324227335365792837509030624805785387473218289296335533890",
"89396333230537847366322364436342481695658547414236326093675863540417141298105682739791578537835191912089484203681",
"115830385654423364502343021113073028365721746246232924567075277636234346135515984504152518055968175024342452068593",
"11263613907940703510226043272578077114062568830909561875804816268614922948545123959608046723806484765856945366386",
"85099371298035679603247495321780481321948685394995318303952199333118698031562067002765732094949837892213467834453",
"237849156256827398282019388933972533154056715710612980343582379691235964002811111531637163291964836316287473866944",
"121324456153144638357885760921484124420296650752569739652599982435599667566663818850130137668154167962818124679946",
"73600332144130508132510040050892177274732799381796146541825372722030832659283233558443467575385522990242420388929",
"44732797483932307692113794160403754043679743522093845554740681666841720206796756514002159097899004452746371432672",
"147751075268067473595930126919015490789314687953476809410426208666203744311411068892162888393693647317357680788622",
"253223744369647051774471619931702227054534749249995484100066505466186263584769989160049762529720081850824722544795",
"226753899873357669326157359116609350824063726018578587491538482132599227769745752321252816012800490263881222618536",
"176875521207730154886136120529839690202784860066517231969835480145708453592054364059780266900035568058186799176840"
]
},
"output": {
"Ok": {
"values": ["1"]
}
}
}
]
}

View file

@ -0,0 +1,35 @@
from "EMBED" import snark_verify_bls12_377
// Verifies a proof with 1 public input (0 inputs + 1 output)
// Circuit used in this test:
//
// def main() -> field:
// return 1
//
// Save the circuit as "circuit.zok" and run the following commands (in order):
// $ zokrates compile -i ./circuit.zok -c bls12_377
// $ zokrates compute-witness
// $ zokrates setup -b ark -s gm17
// $ zokrates generate-proof -b ark -s gm17
//
// To get flattened inputs needed for this test, use the following script:
// #!/usr/bin/env node
//
// const path = require("path");
// const fs = require("fs");
//
// let output = []
// for (let i = 2; i < process.argv.length; i++) {
// const source = fs.readFileSync(path.resolve(process.argv[i]), 'utf8')
// const flat = [...source.matchAll(/0x[a-z0-9]+/gm)].map(n => BigInt(n).toString(10));
// output.push(...flat)
// }
//
// console.log(JSON.stringify(output));
//
// Save this script as "flatten.js" and run the following command:
// $ node flatten.js proof.json verification.key
def main(private field[8] proof, private field[1] inputs, private field[20] vk) -> bool:
bool result = snark_verify_bls12_377(inputs, proof, vk)
return result

View file

@ -0,0 +1,49 @@
{
"entry_point": "./tests/tests/snark/snark_verify_bls12_377_2.zok",
"curves": ["Bw6_761"],
"tests": [
{
"input": {
"values": [
"30886639936493049016175318852868223421962513695924799011862965798142544864756272917016480650319179059444391880142",
"210714472424410627451557273311118253425679108293022860127144278352441005505195339659420709617036779682326673533186",
"101969549978420613687361685686211943788361418391955806064423246725556175258043096446227634997412743489772585976407",
"225606981549539274850150853435430709464645103097569777238240148161962808333007149588258118157237589076622092111900",
"94477902787810056005140833707514971680416163466937669331638397632516292559333058429168736236263588445181668773613",
"156965166665593649649919836247487186182263277589020558979047044043456286367751723077006781061358137877318135673282",
"137741518433065408317198878994358008499493756319076293122811213051853618947340414216838530582726247267590705502194",
"126547036337175013106414910386451161000910611736141896590177615068467376299665795605927145787930213987505973766731",
"2",
"4",
"26150522755032959261786285436959898551137848025504557005325333189168466417284586793885098543725273736029879389211",
"169754513648720531797744265077389392707096818238531464510797707592538650668826008029773773893361012602508598834793",
"172926009578431040673671475398833553033375949638930965254433842547261096474109828672139964685904707258254717562981",
"190737508410333459842769941580905855813961948279753848892816073188168697419955701512184037596994386514528425558736",
"1619785665530270858283718034422422029553639813181597813279549759777153426792287594479505827096186872882300711765",
"63694115876363306907024906479487765094262979049817897093877772048737865300854356915611214233650510384715733840309",
"138256625715993632167333368395637908886726696039897946710436000177289042559378071109224721507617736881530800812544",
"107857276706363405428900669135705736327281608718185524590709570009027542794964888233568166787710632979062032163927",
"117681951719142414345371029336876269027160875021843115377112400246872843732924494507290756295050251515524804614493",
"16932482238351125436073535332269385696327441869886865463514408400096260901383164481505901002564992831623879258663",
"46308513493241827384377341904914105301671994851198058483103383539450400464257917932036866988024757095122827891763",
"12774065758179916688827174319525442607170697024774973507481660009802587305759263737719583503498828398179974682702",
"26150522755032959261786285436959898551137848025504557005325333189168466417284586793885098543725273736029879389211",
"169754513648720531797744265077389392707096818238531464510797707592538650668826008029773773893361012602508598834793",
"172926009578431040673671475398833553033375949638930965254433842547261096474109828672139964685904707258254717562981",
"190737508410333459842769941580905855813961948279753848892816073188168697419955701512184037596994386514528425558736",
"187872074241198211214687054253180244660204447307195753216396863454451962530721491538379804696965671145239859590846",
"172889367615248592096001816975404506869611319851954669628812891122278364377518978073247194031011246327549860771430",
"227539811502856876734690781228675876891342950061206768786526280217867721882979938383152839106086209430522325241347",
"33214331578997688306993838825659395665609935174693430136691944882187065031251282996759071511854109007793069549563",
"231745969633345194328768544928321593376710672347115907704852838281813505601170157293937606734791368236398411854640",
"47237328152391646101146711114931457284784793248831449686265996627039097119070481703804420386021717476164037563466"
]
},
"output": {
"Ok": {
"values": ["1"]
}
}
}
]
}

View file

@ -0,0 +1,35 @@
from "EMBED" import snark_verify_bls12_377
// Verifies a proof with 2 public inputs (1 input + 1 output)
// Circuit used in this test:
//
// def main(field a) -> field:
// return a * a
//
// Save the circuit as "circuit.zok" and run the following commands (in order):
// $ zokrates compile -i ./circuit.zok -c bls12_377
// $ zokrates compute-witness -a 2
// $ zokrates setup -b ark -s gm17
// $ zokrates generate-proof -b ark -s gm17
//
// To get flattened inputs needed for this test, use the following script:
// #!/usr/bin/env node
//
// const path = require("path");
// const fs = require("fs");
//
// let output = []
// for (let i = 2; i < process.argv.length; i++) {
// const source = fs.readFileSync(path.resolve(process.argv[i]), 'utf8')
// const flat = [...source.matchAll(/0x[a-z0-9]+/gm)].map(n => BigInt(n).toString(10));
// output.push(...flat)
// }
//
// console.log(JSON.stringify(output));
//
// Save this script as "flatten.js" and run the following command:
// $ node flatten.js proof.json verification.key
def main(private field[8] proof, private field[2] inputs, private field[22] vk) -> bool:
bool result = snark_verify_bls12_377(inputs, proof, vk)
return result

View file

@ -0,0 +1,58 @@
{
"entry_point": "./tests/tests/snark/snark_verify_bls12_377_5.zok",
"curves": ["Bw6_761"],
"tests": [
{
"input": {
"values": [
"60457684924193218954780799695448128402450659922819148866042534731462934804174889585425668379894806827192129355035",
"30692976080216123852486339295726836787768525847434467843252380267593056117653493955651719058012291818530914713503",
"125357500613234885873309304302314409734224357144836572740733227274842238671614205545693580811504410323545780196986",
"247651569074486453849718457544382537302063316144666696072138162914150063434773021124866593709430271032906775848230",
"205925817697152648573187530836257591106879527302418969217282393297385329815356611501846344314549412686571096624542",
"52408210490520029867007596145203947635265945726032430791270964404506413872638222587937059680769423104224418341783",
"245391920863498220927838330312555206148254951255756591670548373412908886220063896460749603543488483619267089689381",
"78589112605630898410537770266153128219408270888620016803188045523021815277982064356841045190284469829851165791293",
"2",
"2",
"2",
"2",
"8",
"177010185638377511324501604520563739739317808509681430951164029757345810095174696221494505373089763385490312116358",
"153053794329278051178743982884522858761476481700312111393093980133181276780354993379856934110282786295862092443919",
"119352601414532465114802089751399530705471140760948692288569726825270783170792459863146836606243083937386903791326",
"154395739702801688661668736325735092854144372763349598896957725187031688340840056329057020108410010039817499025290",
"219300867221825583189537695275783744511701200221265601874271468574900788700976161865886103325397401233680596662586",
"6184162650897786738969218350774078215930829358700672611442020481749290685465136203052430712512726892174302053960",
"223615432567648858214064557325028920329759681028000034077399269834838357009569712943919669143358231307616009815434",
"175981229674044997402551815995123920812483064905277870260193130162059294237262155034620065210131116619520563506519",
"149763821034046861511733819294494872607002147076380551480035933618221202037885306159876853613449195409389418630899",
"63613896436066139625271941484202721828670668029032907443649108037543119043920396499152980372905932782160074585332",
"83664647128245200609718804963435898883339854035469313658046832013326011731523365594256699720796643575140884572905",
"144568623182910160643612162930255558274463299944237682869943691750723939109705466332836308875557772911097578331002",
"177010185638377511324501604520563739739317808509681430951164029757345810095174696221494505373089763385490312116358",
"153053794329278051178743982884522858761476481700312111393093980133181276780354993379856934110282786295862092443919",
"119352601414532465114802089751399530705471140760948692288569726825270783170792459863146836606243083937386903791326",
"154395739702801688661668736325735092854144372763349598896957725187031688340840056329057020108410010039817499025290",
"149057616125424973478283591473814309565673764317022249169395023211664620308712452144732942791215282170059517214134",
"41780114592407788188439225711342125468082786659527520800331438243958377257657588645284569742745602805176661321513",
"221720891820590314635918157317325200201212159883016241641294528146177946855934688201173659819769674033460232363042",
"50797017918692117248188277962054664678983362179572320962314605303222488912037808946253081883636411158993624881368",
"45015881196637283857089803245084152220024891684216432418680197321055655838083895789012460620698622411348666936603",
"6614931577154387449192604140382084380965299734550787093003728565193454839715263838958636766466130999302518638149",
"245269024464910939632469903406535269950072210280644644046910525955649284275684019199442256400616717695144071175450",
"43420687027898212877864397162744483839228857355048382441491263977288496076621257227893835793326940537504242772685",
"83272518748948630820579332810320118472860479700707035306680609335770289292207880205558249065217561951629308682324",
"6938552589263177251253935997174459628120498877543020100980702178088439767196046212767463370826879237199769600513",
"170649759404749298159628447642105098367401676132263627894428382159110486377464596992614660456131317719055604455895",
"52917028619173381482821776446008133295138882162362339762583394451153359715914188291769779536313083815565710768404"
]
},
"output": {
"Ok": {
"values": ["1"]
}
}
}
]
}

View file

@ -0,0 +1,39 @@
from "EMBED" import snark_verify_bls12_377
// Verifies a proof with 5 public inputs (4 inputs + 1 output)
// Circuit used in this test:
//
// def main(field[4] a) -> field:
// field out = 0
// for u32 i in 0..4 do
// out = out + a[i]
// endfor
// return out
//
// Save the circuit as "circuit.zok" and run the following commands (in order):
// $ zokrates compile -i ./circuit.zok -c bls12_377
// $ zokrates compute-witness -a 2 2 2 2
// $ zokrates setup -b ark -s gm17
// $ zokrates generate-proof -b ark -s gm17
//
// To get flattened inputs needed for this test, use the following script:
// #!/usr/bin/env node
//
// const path = require("path");
// const fs = require("fs");
//
// let output = []
// for (let i = 2; i < process.argv.length; i++) {
// const source = fs.readFileSync(path.resolve(process.argv[i]), 'utf8')
// const flat = [...source.matchAll(/0x[a-z0-9]+/gm)].map(n => BigInt(n).toString(10));
// output.push(...flat)
// }
//
// console.log(JSON.stringify(output));
//
// Save this script as "flatten.js" and run the following command:
// $ node flatten.js proof.json verification.key
def main(private field[8] proof, private field[5] inputs, private field[28] vk) -> bool:
bool result = snark_verify_bls12_377(inputs, proof, vk)
return result

View file

@ -10,5 +10,15 @@ wasm = ["bellman_ce/wasm", "sapling-crypto_ce/wasm"]
multicore = ["bellman_ce/multicore", "sapling-crypto_ce/multicore"]
[dependencies]
zokrates_field = { version = "0.4.0", path = "../zokrates_field", default-features = false }
bellman_ce = { version = "^0.3", default-features = false }
sapling-crypto_ce = { version = "^0.1", default-features = false }
sapling-crypto_ce = { version = "^0.1", default-features = false }
ark-bls12-377 = { version = "^0.2.0", features = ["curve", "r1cs"], default-features = false }
ark-bw6-761 = { version = "^0.2.0", default-features = false }
ark-gm17 = { version = "^0.2.0", default-features = false, features = ["r1cs"] }
ark-relations = { version = "^0.2.0", default-features = false }
ark-crypto-primitives = { version = "^0.2.0", default-features = false, features = ["r1cs"] }
ark-r1cs-std = { version = "^0.2.0", default-features = false }
ark-std = { version = "^0.2.0", default-features = false }
ark-ec = { version = "^0.2.0", default-features = false }
ark-ff = { version = "^0.2.0", default-features = false}

340
zokrates_embed/src/ark.rs Normal file
View file

@ -0,0 +1,340 @@
use ark_bls12_377::{
constraints::PairingVar as BLS12PairingVar, Bls12_377 as BLS12PairingEngine, Fq as BLS12Fq,
Fq2 as BLS12Fq2,
};
use ark_bw6_761::Fr as BW6Fr;
use ark_ec::PairingEngine;
use ark_ff::{BigInteger, One, PrimeField};
use ark_r1cs_std::bits::boolean::Boolean;
use ark_relations::{
ns,
r1cs::{ConstraintSystem, ConstraintSystemRef},
};
use ark_crypto_primitives::snark::constraints::SNARKGadget;
use ark_gm17::{constraints::GM17VerifierGadget, Proof, VerifyingKey, GM17};
use ark_r1cs_std::alloc::{AllocVar, AllocationMode};
use crate::Constraint;
use ark_crypto_primitives::SNARK;
use ark_r1cs_std::fields::fp::FpVar;
use ark_r1cs_std::ToBitsGadget;
use ark_relations::r1cs::{ConstraintSynthesizer, SynthesisError};
use ark_std::test_rng;
use std::str::FromStr;
use zokrates_field::Field;
type GM17Snark = GM17<BLS12PairingEngine>;
type VerifierGadget = GM17VerifierGadget<BLS12PairingEngine, BLS12PairingVar>;
type G1 = <ark_ec::bls12::Bls12<ark_bls12_377::Parameters> as PairingEngine>::G1Affine;
type G2 = <ark_ec::bls12::Bls12<ark_bls12_377::Parameters> as PairingEngine>::G2Affine;
#[derive(Copy, Clone)]
struct DefaultCircuit {
pub public_input_size: usize,
}
impl<F: PrimeField> ConstraintSynthesizer<F> for DefaultCircuit {
fn generate_constraints(self, cs: ConstraintSystemRef<F>) -> Result<(), SynthesisError> {
for _ in 0..self.public_input_size {
let _ = FpVar::<F>::new_input(ns!(cs, "alloc_input"), || Ok(F::one()))?;
}
Ok(())
}
}
#[allow(clippy::type_complexity)]
pub fn generate_verify_constraints(
public_input_size: usize,
) -> (
usize,
Vec<usize>,
Vec<usize>,
Vec<usize>,
Vec<Constraint<BW6Fr>>,
usize,
) {
let cs_sys = ConstraintSystem::<BW6Fr>::new();
let cs = ConstraintSystemRef::new(cs_sys);
let mut rng = test_rng(); // has a fixed seed
let circuit = DefaultCircuit { public_input_size };
let (pk, vk) = GM17Snark::circuit_specific_setup(circuit, &mut rng).unwrap();
let proof = GM17Snark::prove(&pk, circuit, &mut rng).unwrap();
let mut fp_vars = Vec::new();
for _ in 0..public_input_size {
let fp = FpVar::new_input(ns!(cs, "alloc_input"), || Ok(BLS12Fq::one())).unwrap();
fp_vars.push(fp);
}
let input_booleans: Vec<Vec<Boolean<_>>> =
fp_vars.iter().map(|i| i.to_bits_le().unwrap()).collect();
let inputs = <VerifierGadget as SNARKGadget<
<BLS12PairingEngine as PairingEngine>::Fr,
<BLS12PairingEngine as PairingEngine>::Fq,
GM17Snark,
>>::InputVar::new(input_booleans);
let proof = <VerifierGadget as SNARKGadget<
<BLS12PairingEngine as PairingEngine>::Fr,
<BLS12PairingEngine as PairingEngine>::Fq,
GM17Snark,
>>::new_proof_unchecked(
ns!(cs, "alloc_proof"),
|| Ok(proof),
AllocationMode::Witness,
)
.unwrap();
let vk = <VerifierGadget as SNARKGadget<
<BLS12PairingEngine as PairingEngine>::Fr,
<BLS12PairingEngine as PairingEngine>::Fq,
GM17Snark,
>>::new_verification_key_unchecked(
ns!(cs, "alloc_vk"), || Ok(vk), AllocationMode::Witness
)
.unwrap();
let res = <VerifierGadget as SNARKGadget<
<BLS12PairingEngine as PairingEngine>::Fr,
<BLS12PairingEngine as PairingEngine>::Fq,
GM17Snark,
>>::verify(&vk, &inputs, &proof)
.unwrap();
cs.finalize();
let num_instance_variables = cs.num_instance_variables();
let input_indices = fp_vars
.iter()
.map(|f| var_to_index(&f, 0))
.collect::<Vec<usize>>();
let proof_indices: Vec<usize> = vec![
var_to_index(&proof.a.x, num_instance_variables),
var_to_index(&proof.a.y, num_instance_variables),
var_to_index(&proof.b.x.c0, num_instance_variables),
var_to_index(&proof.b.x.c1, num_instance_variables),
var_to_index(&proof.b.y.c0, num_instance_variables),
var_to_index(&proof.b.y.c1, num_instance_variables),
var_to_index(&proof.c.x, num_instance_variables),
var_to_index(&proof.c.y, num_instance_variables),
];
let mut vk_indices: Vec<usize> = vec![
var_to_index(&vk.h_g2.x.c0, num_instance_variables),
var_to_index(&vk.h_g2.x.c1, num_instance_variables),
var_to_index(&vk.h_g2.y.c0, num_instance_variables),
var_to_index(&vk.h_g2.y.c1, num_instance_variables),
var_to_index(&vk.g_alpha_g1.x, num_instance_variables),
var_to_index(&vk.g_alpha_g1.y, num_instance_variables),
var_to_index(&vk.h_beta_g2.x.c0, num_instance_variables),
var_to_index(&vk.h_beta_g2.x.c1, num_instance_variables),
var_to_index(&vk.h_beta_g2.y.c0, num_instance_variables),
var_to_index(&vk.h_beta_g2.y.c1, num_instance_variables),
var_to_index(&vk.g_gamma_g1.x, num_instance_variables),
var_to_index(&vk.g_gamma_g1.y, num_instance_variables),
var_to_index(&vk.h_gamma_g2.x.c0, num_instance_variables),
var_to_index(&vk.h_gamma_g2.x.c1, num_instance_variables),
var_to_index(&vk.h_gamma_g2.y.c0, num_instance_variables),
var_to_index(&vk.h_gamma_g2.y.c1, num_instance_variables),
];
vk_indices.extend(
vk.query
.iter()
.map(|q| {
vec![
var_to_index(&q.x, num_instance_variables),
var_to_index(&q.y, num_instance_variables),
]
})
.flatten(),
);
let out_index = match &res {
Boolean::Is(x) => x
.variable()
.get_index_unchecked(num_instance_variables)
.unwrap(),
_ => unreachable!(),
};
let matrices = cs.to_matrices().unwrap();
let constraints: Vec<Constraint<_>> = matrices
.a
.into_iter()
.zip(matrices.b.into_iter())
.zip(matrices.c.into_iter())
.map(|((a, b), c)| Constraint {
a: a.into_iter().map(|(f, index)| (index, f)).collect(),
b: b.into_iter().map(|(f, index)| (index, f)).collect(),
c: c.into_iter().map(|(f, index)| (index, f)).collect(),
})
.collect();
(
out_index,
input_indices,
proof_indices,
vk_indices,
constraints,
cs.num_witness_variables() + cs.num_instance_variables(),
)
}
pub fn generate_verify_witness<T: Field>(inputs: &[T], proof: &[T], vk: &[T]) -> Vec<T> {
assert_eq!(proof.len(), 8);
assert_eq!(vk.len(), 18 + (2 * inputs.len()));
let cs_sys = ConstraintSystem::<BW6Fr>::new();
let cs = ConstraintSystemRef::new(cs_sys);
let mut fp_vars = Vec::new();
for input in inputs {
let input_field: BLS12Fq = BLS12Fq::from_str(input.to_dec_string().as_str()).unwrap();
let fp = FpVar::new_input(ns!(cs, "alloc_input"), || Ok(input_field)).unwrap();
fp_vars.push(fp);
}
let input_booleans: Vec<Vec<Boolean<_>>> = fp_vars
.into_iter()
.map(|i| i.to_bits_le().unwrap())
.collect();
let inputs = <VerifierGadget as SNARKGadget<
<BLS12PairingEngine as PairingEngine>::Fr,
<BLS12PairingEngine as PairingEngine>::Fq,
GM17Snark,
>>::InputVar::new(input_booleans);
let proof = <VerifierGadget as SNARKGadget<
<BLS12PairingEngine as PairingEngine>::Fr,
<BLS12PairingEngine as PairingEngine>::Fq,
GM17Snark,
>>::new_proof_unchecked(
ns!(cs, "alloc_proof"),
|| {
Ok(Proof {
a: new_g1(&proof[0..2]),
b: new_g2(&proof[2..6]),
c: new_g1(&proof[6..8]),
})
},
AllocationMode::Witness,
)
.unwrap();
let vk = <VerifierGadget as SNARKGadget<
<BLS12PairingEngine as PairingEngine>::Fr,
<BLS12PairingEngine as PairingEngine>::Fq,
GM17Snark,
>>::new_verification_key_unchecked(
ns!(cs, "alloc_vk"),
|| {
Ok(VerifyingKey {
h_g2: new_g2(&vk[0..4]),
g_alpha_g1: new_g1(&vk[4..6]),
h_beta_g2: new_g2(&vk[6..10]),
g_gamma_g1: new_g1(&vk[10..12]),
h_gamma_g2: new_g2(&vk[12..16]),
query: (16..vk.len())
.collect::<Vec<_>>()
.chunks(2)
.map(|c| new_g1(&vk[c[0]..c[1] + 1]))
.collect(),
})
},
AllocationMode::Witness,
)
.unwrap();
let _ = <VerifierGadget as SNARKGadget<
<BLS12PairingEngine as PairingEngine>::Fr,
<BLS12PairingEngine as PairingEngine>::Fq,
GM17Snark,
>>::verify(&vk, &inputs, &proof)
.unwrap();
cs.finalize();
let cs = cs.borrow().unwrap();
let witness_variables: Vec<BLS12Fq> = cs.witness_assignment.clone();
cs.instance_assignment
.clone()
.into_iter()
.chain(witness_variables)
.map(|fq| T::from_byte_vector(fq.into_repr().to_bytes_le()))
.collect()
}
#[inline]
fn var_to_index<F: ark_ff::PrimeField>(var: &FpVar<F>, offset: usize) -> usize {
match var {
FpVar::Var(ref fp) => {
let var = &fp.variable;
var.get_index_unchecked(offset).unwrap()
}
_ => unreachable!("expected variable, but found a constant"),
}
}
#[inline]
fn new_g1<T: Field>(flat: &[T]) -> G1 {
assert_eq!(flat.len(), 2);
G1::new(
BLS12Fq::from_str(&*flat[0].to_dec_string()).unwrap(),
BLS12Fq::from_str(&*flat[1].to_dec_string()).unwrap(),
false,
)
}
#[inline]
fn new_g2<T: Field>(flat: &[T]) -> G2 {
assert_eq!(flat.len(), 4);
G2::new(
BLS12Fq2::new(
BLS12Fq::from_str(&*flat[0].to_dec_string()).unwrap(),
BLS12Fq::from_str(&*flat[1].to_dec_string()).unwrap(),
),
BLS12Fq2::new(
BLS12Fq::from_str(&*flat[2].to_dec_string()).unwrap(),
BLS12Fq::from_str(&*flat[3].to_dec_string()).unwrap(),
),
false,
)
}
pub fn from_ark<T: zokrates_field::Field, E: PairingEngine>(c: Constraint<E::Fq>) -> Constraint<T> {
Constraint {
a: c.a
.into_iter()
.map(|(index, fq)| {
let mut res: Vec<u8> = vec![];
fq.into_repr().write_le(&mut res).unwrap();
(index, T::from_byte_vector(res))
})
.collect(),
b: c.b
.into_iter()
.map(|(index, fq)| {
let mut res: Vec<u8> = vec![];
fq.into_repr().write_le(&mut res).unwrap();
(index, T::from_byte_vector(res))
})
.collect(),
c: c.c
.into_iter()
.map(|(index, fq)| {
let mut res: Vec<u8> = vec![];
fq.into_repr().write_le(&mut res).unwrap();
(index, T::from_byte_vector(res))
})
.collect(),
}
}

View file

@ -0,0 +1,319 @@
extern crate sapling_crypto_ce as sapling_crypto;
use sapling_crypto::bellman;
use crate::{Constraint, Witness, R1CS};
use bellman::{
pairing::{ff::Field, Engine},
ConstraintSystem, Index, LinearCombination, SynthesisError, Variable,
};
use sapling_crypto::bellman::pairing::ff::{PrimeField, PrimeFieldRepr};
use sapling_crypto::circuit::{
boolean::{AllocatedBit, Boolean},
sha256::sha256_compression_function,
uint32::UInt32,
};
fn sha256_round<E: Engine, CS: ConstraintSystem<E>>(
mut cs: CS,
input: &[Option<E::Fr>],
current_hash: &[Option<E::Fr>],
) -> (Vec<usize>, Vec<usize>, Vec<usize>) {
// Allocate bits for `input`
let input_bits = input
.iter()
.enumerate()
.map(|(index, i)| {
AllocatedBit::alloc::<E, _>(
&mut cs.namespace(|| format!("input_{}", index)),
Some(*i == Some(<E::Fr as Field>::one())),
)
.unwrap()
})
.collect::<Vec<_>>();
// Define Booleans whose values are the defined bits
let input = input_bits
.iter()
.map(|i| Boolean::Is(i.clone()))
.collect::<Vec<_>>();
// Allocate bits for `current_hash`
let current_hash_bits = current_hash
.iter()
.enumerate()
.map(|(index, i)| {
AllocatedBit::alloc::<E, _>(
&mut cs.namespace(|| format!("current_hash_{}", index)),
Some(*i == Some(<E::Fr as Field>::one())),
)
.unwrap()
})
.collect::<Vec<_>>();
// Define Booleans whose values are the defined bits
let current_hash = current_hash_bits
.chunks(32)
.map(|chunk| {
UInt32::from_bits_be(
&chunk
.iter()
.map(|i| Boolean::Is(i.clone()))
.collect::<Vec<_>>(),
)
})
.collect::<Vec<_>>();
// Apply the compression function, returning the 8 bytes of outputs
let res = sha256_compression_function::<E, _>(&mut cs, &input, &current_hash).unwrap();
// Extract the 256 bits of output out of the 8 bytes
let output_bits = res
.into_iter()
.flat_map(|u| u.into_bits_be())
.map(|b| b.get_variable().unwrap().clone());
// Return indices of `input`, `current_hash` and `output` in the CS
(
input_bits
.into_iter()
.map(|b| var_to_index(b.get_variable()))
.collect(),
current_hash_bits
.into_iter()
.map(|b| var_to_index(b.get_variable()))
.collect(),
output_bits
.map(|b| var_to_index(b.get_variable()))
.collect(),
)
}
impl<E: Engine> ConstraintSystem<E> for Witness<E::Fr> {
type Root = Self;
fn alloc<F, A, AR>(&mut self, _: A, f: F) -> Result<Variable, SynthesisError>
where
F: FnOnce() -> Result<E::Fr, SynthesisError>,
A: FnOnce() -> AR,
AR: Into<String>,
{
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, _: A, _: 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, _: A, _: LA, _: LB, _: 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, _: 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 R1CS<E::Fr> {
type Root = Self;
fn alloc<F, A, AR>(&mut self, _: A, _: 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 generating 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, _: A, _: 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, _: 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()
.iter()
.map(|(variable, coefficient)| (var_to_index(*variable), *coefficient))
.collect();
let b = b
.as_ref()
.iter()
.map(|(variable, coefficient)| (var_to_index(*variable), *coefficient))
.collect();
let c = c
.as_ref()
.iter()
.map(|(variable, coefficient)| (var_to_index(*variable), *coefficient))
.collect();
self.constraints.push(Constraint { a, b, c });
}
fn push_namespace<NR, N>(&mut self, _: 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_sha256_round_constraints<E: Engine>(
) -> (R1CS<E::Fr>, Vec<usize>, Vec<usize>, Vec<usize>) {
let mut cs = R1CS::default();
let (input_bits, current_hash_bits, output_bits) =
sha256_round::<E, _>(&mut cs, &[None; 512], &[None; 256]);
// res is now the allocated bits for `input`, `current_hash` and `sha256_output`
(cs, input_bits, current_hash_bits, output_bits)
}
pub fn generate_sha256_round_witness<E: Engine>(
input: &[E::Fr],
current_hash: &[E::Fr],
) -> Vec<E::Fr> {
assert_eq!(input.len(), 512);
assert_eq!(current_hash.len(), 256);
let mut cs: Witness<E::Fr> = Witness {
values: vec![<E::Fr as Field>::one()],
};
sha256_round::<E, _>(
&mut cs,
&input.iter().map(|x| Some(*x)).collect::<Vec<_>>(),
&current_hash.iter().map(|x| Some(*x)).collect::<Vec<_>>(),
);
cs.values
}
fn var_to_index(v: Variable) -> usize {
match v.get_unchecked() {
Index::Aux(i) => i + 1,
Index::Input(0) => 0,
_ => unreachable!("No public variables should have been allocated"),
}
}
pub fn from_bellman<T: zokrates_field::Field, E: Engine>(c: Constraint<E::Fr>) -> Constraint<T> {
Constraint {
a: c.a
.into_iter()
.map(|(index, fq)| {
let mut res: Vec<u8> = vec![];
fq.into_repr().write_le(&mut res).unwrap();
(index, T::from_byte_vector(res))
})
.collect(),
b: c.b
.into_iter()
.map(|(index, fq)| {
let mut res: Vec<u8> = vec![];
fq.into_repr().write_le(&mut res).unwrap();
(index, T::from_byte_vector(res))
})
.collect(),
c: c.c
.into_iter()
.map(|(index, fq)| {
let mut res: Vec<u8> = vec![];
fq.into_repr().write_le(&mut res).unwrap();
(index, T::from_byte_vector(res))
})
.collect(),
}
}
#[cfg(test)]
mod tests {
use super::*;
use bellman::pairing::bn256::{Bn256, Fr};
#[test]
fn generate_constraints() {
let (_c, input, current_hash, output) = generate_sha256_round_constraints::<Bn256>();
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::<Bn256>(&vec![Fr::one(); 512], &vec![Fr::zero(); 256]);
assert_eq!(witness.len(), 26935);
}
#[test]
fn test_cs() {
use sapling_crypto::circuit::test::TestConstraintSystem;
let mut cs: TestConstraintSystem<Bn256> = TestConstraintSystem::new();
let _ = sha256_round(
&mut cs,
&vec![Some(Fr::zero()); 512],
&vec![Some(Fr::one()); 256],
);
assert!(cs.is_satisfied());
}
}

View file

@ -1,26 +1,16 @@
extern crate sapling_crypto_ce as sapling_crypto;
use sapling_crypto::bellman;
pub mod ark;
pub mod bellman;
use bellman::{
pairing::{ff::Field, Engine},
ConstraintSystem, Index, LinearCombination, SynthesisError, Variable,
};
use sapling_crypto::circuit::{
boolean::{AllocatedBit, Boolean},
sha256::sha256_compression_function,
uint32::UInt32,
};
#[derive(Debug)]
#[derive(Debug, Clone)]
#[allow(clippy::upper_case_acronyms)]
pub struct BellmanR1CS<E: Engine> {
pub struct R1CS<T> {
pub aux_count: usize,
pub constraints: Vec<BellmanConstraint<E>>,
pub constraints: Vec<Constraint<T>>,
}
impl<E: Engine> Default for BellmanR1CS<E> {
impl<T> Default for R1CS<T> {
fn default() -> Self {
BellmanR1CS {
Self {
aux_count: 0,
constraints: vec![],
}
@ -28,289 +18,13 @@ impl<E: Engine> Default for BellmanR1CS<E> {
}
#[derive(Debug)]
pub struct BellmanWitness<E: Engine> {
pub values: Vec<E::Fr>,
pub struct Witness<T> {
pub values: Vec<T>,
}
#[derive(Debug, PartialEq)]
pub struct BellmanConstraint<E: Engine> {
pub a: Vec<(usize, E::Fr)>,
pub b: Vec<(usize, E::Fr)>,
pub c: Vec<(usize, E::Fr)>,
}
fn sha256_round<E: Engine, CS: ConstraintSystem<E>>(
mut cs: CS,
input: &[Option<E::Fr>],
current_hash: &[Option<E::Fr>],
) -> (Vec<usize>, Vec<usize>, Vec<usize>) {
// Allocate bits for `input`
let input_bits = input
.iter()
.enumerate()
.map(|(index, i)| {
AllocatedBit::alloc::<E, _>(
&mut cs.namespace(|| format!("input_{}", index)),
Some(*i == Some(<E::Fr as Field>::one())),
)
.unwrap()
})
.collect::<Vec<_>>();
// Define Booleans whose values are the defined bits
let input = input_bits
.iter()
.map(|i| Boolean::Is(i.clone()))
.collect::<Vec<_>>();
// Allocate bits for `current_hash`
let current_hash_bits = current_hash
.iter()
.enumerate()
.map(|(index, i)| {
AllocatedBit::alloc::<E, _>(
&mut cs.namespace(|| format!("current_hash_{}", index)),
Some(*i == Some(<E::Fr as Field>::one())),
)
.unwrap()
})
.collect::<Vec<_>>();
// Define Booleans whose values are the defined bits
let current_hash = current_hash_bits
.chunks(32)
.map(|chunk| {
UInt32::from_bits_be(
&chunk
.iter()
.map(|i| Boolean::Is(i.clone()))
.collect::<Vec<_>>(),
)
})
.collect::<Vec<_>>();
// Apply the compression function, returning the 8 bytes of outputs
let res = sha256_compression_function::<E, _>(&mut cs, &input, &current_hash).unwrap();
// Extract the 256 bits of output out of the 8 bytes
let output_bits = res
.into_iter()
.flat_map(|u| u.into_bits_be())
.map(|b| b.get_variable().unwrap().clone());
// Return indices of `input`, `current_hash` and `output` in the CS
(
input_bits
.into_iter()
.map(|b| var_to_index(b.get_variable()))
.collect(),
current_hash_bits
.into_iter()
.map(|b| var_to_index(b.get_variable()))
.collect(),
output_bits
.map(|b| var_to_index(b.get_variable()))
.collect(),
)
}
impl<E: Engine> ConstraintSystem<E> for BellmanWitness<E> {
type Root = Self;
fn alloc<F, A, AR>(&mut self, _: A, f: F) -> Result<Variable, SynthesisError>
where
F: FnOnce() -> Result<E::Fr, SynthesisError>,
A: FnOnce() -> AR,
AR: Into<String>,
{
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, _: A, _: 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, _: A, _: LA, _: LB, _: 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, _: 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, _: A, _: 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 generating 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, _: A, _: 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, _: 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()
.iter()
.map(|(variable, coefficient)| (var_to_index(*variable), *coefficient))
.collect();
let b = b
.as_ref()
.iter()
.map(|(variable, coefficient)| (var_to_index(*variable), *coefficient))
.collect();
let c = c
.as_ref()
.iter()
.map(|(variable, coefficient)| (var_to_index(*variable), *coefficient))
.collect();
self.constraints.push(BellmanConstraint { a, b, c });
}
fn push_namespace<NR, N>(&mut self, _: 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_sha256_round_constraints<E: Engine>(
) -> (BellmanR1CS<E>, Vec<usize>, Vec<usize>, Vec<usize>) {
let mut cs = BellmanR1CS::default();
let (input_bits, current_hash_bits, output_bits) =
sha256_round(&mut cs, &[None; 512], &[None; 256]);
// res is now the allocated bits for `input`, `current_hash` and `sha256_output`
(cs, input_bits, current_hash_bits, output_bits)
}
pub fn generate_sha256_round_witness<E: Engine>(
input: &[E::Fr],
current_hash: &[E::Fr],
) -> Vec<E::Fr> {
assert_eq!(input.len(), 512);
assert_eq!(current_hash.len(), 256);
let mut cs: BellmanWitness<E> = BellmanWitness {
values: vec![<E::Fr as Field>::one()],
};
sha256_round(
&mut cs,
&input.iter().map(|x| Some(*x)).collect::<Vec<_>>(),
&current_hash.iter().map(|x| Some(*x)).collect::<Vec<_>>(),
);
cs.values
}
fn var_to_index(v: Variable) -> usize {
match v.get_unchecked() {
Index::Aux(i) => i + 1,
Index::Input(0) => 0,
_ => unreachable!("No public variables should have been allocated"),
}
}
#[cfg(test)]
mod tests {
use super::*;
use bellman::pairing::bn256::{Bn256, Fr};
#[test]
fn generate_constraints() {
let (_c, input, current_hash, output) = generate_sha256_round_constraints::<Bn256>();
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::<Bn256>(&vec![Fr::one(); 512], &vec![Fr::zero(); 256]);
assert_eq!(witness.len(), 26935);
}
#[test]
fn test_cs() {
use sapling_crypto::circuit::test::TestConstraintSystem;
let mut cs: TestConstraintSystem<Bn256> = TestConstraintSystem::new();
let _ = sha256_round(
&mut cs,
&vec![Some(Fr::zero()); 512],
&vec![Some(Fr::one()); 256],
);
assert!(cs.is_satisfied());
}
#[derive(Default, Debug, PartialEq, Clone)]
pub struct Constraint<T> {
pub a: Vec<(usize, T)>,
pub b: Vec<(usize, T)>,
pub c: Vec<(usize, T)>,
}