made directory names singular

This commit is contained in:
lunar-mining
2021-09-13 09:38:21 +02:00
parent 8ce2445879
commit e83853718f
24 changed files with 3495 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
accept_url = "127.0.0.1:7777"
rpc_url = "http://127.0.0.1:8000"
client_database_path = "cashier_client_database.db"
btc_endpoint = "tcp://electrum.blockstream.info:50001"
gateway_url = "127.0.0.1:3333"
log_path = "/tmp/cashierd.log"
cashierdb_path = "~/.config/darkfi/cashier.db"
client_walletdb_path = "~/.config/darkfi/cashier_client_walletdb.db"
password = "TEST_PASSWORD"
client_password = "TEST_PASSWORD"

View File

@@ -0,0 +1,8 @@
connect_url = "127.0.0.1:3333"
subscriber_url = "127.0.0.1:4444"
cashier_url = "127.0.0.1:7777"
rpc_url = "127.0.0.1:8000"
database_path = "~/.config/darkfi/database_client.db"
walletdb_path = "~/.config/darkfi/walletdb.db"
log_path = "/tmp/darkfid_service_daemon.log"
password = "TEST_PASSWORD"

2
example/config/drk.toml Normal file
View File

@@ -0,0 +1,2 @@
rpc_url = "http://127.0.0.1:8000"
log_path = "/tmp/drk_cli.log"

View File

@@ -0,0 +1,4 @@
connect_url = "127.0.0.1:3333"
publisher_url = "127.0.0.1:4444"
database_path = "gatewayd.db"
log_path = "/tmp/gatewayd.log"

791
example/halo2/Cargo.lock generated Normal file
View File

@@ -0,0 +1,791 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aes"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561"
dependencies = [
"aes-soft",
"aesni",
"cipher",
]
[[package]]
name = "aes-soft"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072"
dependencies = [
"cipher",
"opaque-debug",
]
[[package]]
name = "aesni"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce"
dependencies = [
"cipher",
"opaque-debug",
]
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "arrayvec"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd"
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bigint"
version = "4.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0e8c8a600052b52482eff2cf4d810e462fdff1f656ac1ecb6232132a1ed7def"
dependencies = [
"byteorder",
"crunchy",
]
[[package]]
name = "bitvec"
version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527"
dependencies = [
"funty",
"radium",
"tap",
"wyz",
]
[[package]]
name = "blake2b_simd"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
dependencies = [
"arrayref",
"arrayvec 0.5.2",
"constant_time_eq",
]
[[package]]
name = "block-modes"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0"
dependencies = [
"block-padding",
"cipher",
]
[[package]]
name = "block-padding"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
[[package]]
name = "bls12_381"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54757888b09a69be70b5ec303e382a74227392086ba808cb01eeca29233a2397"
dependencies = [
"ff",
"rand_core",
"subtle",
]
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cipher"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801"
dependencies = [
"generic-array",
]
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "crossbeam-channel"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
dependencies = [
"cfg-if",
"crossbeam-utils",
"lazy_static",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
dependencies = [
"cfg-if",
"lazy_static",
]
[[package]]
name = "crunchy"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
[[package]]
name = "crypto_api"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f855e87e75a4799e18b8529178adcde6fd4f97c1449ff4821e747ff728bb102"
[[package]]
name = "crypto_api_chachapoly"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d930b6a026ce9d358a17f9c9046c55d90b14bb847f36b6ebb6b19365d4feffb8"
dependencies = [
"crypto_api",
]
[[package]]
name = "digest"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "ff"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f"
dependencies = [
"bitvec",
"rand_core",
"subtle",
]
[[package]]
name = "fpe"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a25080721bbcd2cd4d765b7d607ea350425fa087ce53cd3e31afcacdab850352"
dependencies = [
"aes",
"block-modes",
"num-bigint",
"num-integer",
"num-traits",
]
[[package]]
name = "funty"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e"
[[package]]
name = "generic-array"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "group"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912"
dependencies = [
"byteorder",
"ff",
"rand_core",
"subtle",
]
[[package]]
name = "halo2"
version = "0.0.1"
source = "git+https://github.com/zcash/halo2.git?rev=27c4187673a9c6ade13fbdbd4f20955530c22d7f#27c4187673a9c6ade13fbdbd4f20955530c22d7f"
dependencies = [
"blake2b_simd",
"ff",
"group",
"pasta_curves",
"rand",
"rayon",
]
[[package]]
name = "halo2_ecc"
version = "0.0.0"
source = "git+https://github.com/parazyd/orchard.git?rev=f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9#f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9"
dependencies = [
"arrayvec 0.7.1",
"bigint",
"ff",
"group",
"halo2",
"halo2_utilities",
"lazy_static",
"pasta_curves",
"rand",
]
[[package]]
name = "halo2_examples"
version = "0.1.0"
dependencies = [
"arrayvec 0.7.1",
"bigint",
"bitvec",
"ff",
"group",
"halo2",
"halo2_ecc",
"halo2_poseidon",
"halo2_utilities",
"lazy_static",
"orchard",
"pasta_curves",
"rand",
"sinsemilla",
"subtle",
]
[[package]]
name = "halo2_poseidon"
version = "0.0.0"
source = "git+https://github.com/parazyd/orchard.git?rev=f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9#f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9"
dependencies = [
"bitvec",
"ff",
"halo2",
"halo2_utilities",
"pasta_curves",
]
[[package]]
name = "halo2_utilities"
version = "0.0.0"
source = "git+https://github.com/parazyd/orchard.git?rev=f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9#f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9"
dependencies = [
"bigint",
"ff",
"halo2",
"pasta_curves",
"rand",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "incrementalmerkletree"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16d75fb342984cc8cea665a9ef5607b4956569839ca098172082fa1b19bdaf02"
dependencies = [
"serde",
]
[[package]]
name = "jubjub"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "593fc4726ca80edb47ee18ab4d826719e25c2096991a79308b44fb915c6014ef"
dependencies = [
"bitvec",
"bls12_381",
"ff",
"group",
"rand_core",
"subtle",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5"
[[package]]
name = "memoffset"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
dependencies = [
"autocfg",
]
[[package]]
name = "nonempty"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7"
[[package]]
name = "num-bigint"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d0a3d5e207573f948a9e5376662aa743a2ea13f7c50a554d7af443a73fbfeba"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "orchard"
version = "0.0.0"
source = "git+https://github.com/parazyd/orchard.git?rev=f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9#f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9"
dependencies = [
"aes",
"arrayvec 0.7.1",
"bigint",
"bitvec",
"blake2b_simd",
"ff",
"fpe",
"group",
"halo2",
"halo2_ecc",
"halo2_poseidon",
"halo2_utilities",
"incrementalmerkletree",
"lazy_static",
"nonempty",
"pasta_curves",
"rand",
"reddsa",
"serde",
"sinsemilla",
"subtle",
"zcash_note_encryption",
]
[[package]]
name = "pasta_curves"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a21914ddc589b74e7638091c8e91a4e8b083ee5e1d0066d64407131b7570799"
dependencies = [
"blake2b_simd",
"ff",
"group",
"lazy_static",
"rand",
"static_assertions",
"subtle",
]
[[package]]
name = "ppv-lite86"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "proc-macro2"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "radium"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb"
[[package]]
name = "rand"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
"rand_core",
]
[[package]]
name = "rayon"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
dependencies = [
"autocfg",
"crossbeam-deque",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"lazy_static",
"num_cpus",
]
[[package]]
name = "reddsa"
version = "0.0.0"
source = "git+https://github.com/str4d/redjubjub.git?rev=d5d8c5f3bb704bad8ae88fe4a29ae1f744774cb2#d5d8c5f3bb704bad8ae88fe4a29ae1f744774cb2"
dependencies = [
"blake2b_simd",
"byteorder",
"digest",
"group",
"jubjub",
"pasta_curves",
"rand_core",
"serde",
"thiserror",
"zeroize",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.128"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1056a0db1978e9dbf0f6e4fca677f6f9143dc1c19de346f22cac23e422196834"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.128"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13af2fbb8b60a8950d6c72a56d2095c28870367cc8e10c55e9745bac4995a2c4"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "sinsemilla"
version = "0.0.0"
source = "git+https://github.com/parazyd/orchard.git?rev=f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9#f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9"
dependencies = [
"ff",
"group",
"halo2",
"halo2_ecc",
"halo2_utilities",
"pasta_curves",
"rand",
"subtle",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "subtle"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "syn"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "synstructure"
version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "474aaa926faa1603c40b7885a9eaea29b444d1cb2850cb7c0e37bb1a4182f4fa"
dependencies = [
"proc-macro2",
"quote",
"syn",
"unicode-xid",
]
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "thiserror"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "typenum"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "version_check"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "wyz"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188"
dependencies = [
"tap",
]
[[package]]
name = "zcash_note_encryption"
version = "0.0.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=13b023387bafdc7b5712c933dc0e16ee94b96a6a#13b023387bafdc7b5712c933dc0e16ee94b96a6a"
dependencies = [
"blake2b_simd",
"byteorder",
"crypto_api_chachapoly",
"ff",
"group",
"rand_core",
"subtle",
]
[[package]]
name = "zeroize"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd"
dependencies = [
"zeroize_derive",
]
[[package]]
name = "zeroize_derive"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1"
dependencies = [
"proc-macro2",
"quote",
"syn",
"synstructure",
]

47
example/halo2/Cargo.toml Normal file
View File

@@ -0,0 +1,47 @@
[package]
name = "halo2_examples"
version = "0.1.0"
authors = ["narodnik <x@x.org>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
ff = "0.10"
group = "0.10"
pasta_curves = "0.1.2"
bitvec = "0.22"
rand = "0.8.4"
arrayvec = "0.7.0"
lazy_static = "1"
bigint = "4"
subtle = "2.3"
halo2 = "0.0"
[patch.crates-io]
halo2 = { git = "https://github.com/zcash/halo2.git", rev = "27c4187673a9c6ade13fbdbd4f20955530c22d7f" }
[dependencies.halo2_poseidon]
git = "https://github.com/parazyd/orchard.git"
#rev = "0d14f2390734e4710fc24a976f037dae3a6e7ac8"
rev = "f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9"
features = ["halo2"]
[dependencies.halo2_utilities]
git = "https://github.com/parazyd/orchard.git"
#rev = "0d14f2390734e4710fc24a976f037dae3a6e7ac8"
rev = "f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9"
[dependencies.halo2_ecc]
git = "https://github.com/parazyd/orchard.git"
#rev = "0d14f2390734e4710fc24a976f037dae3a6e7ac8"
rev = "f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9"
[dependencies.sinsemilla]
git = "https://github.com/parazyd/orchard.git"
#rev = "0d14f2390734e4710fc24a976f037dae3a6e7ac8"
rev = "f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9"
[dependencies.orchard]
git = "https://github.com/parazyd/orchard.git"
rev = "f9cc01c21010b31988129f9cbc2ca8c0bdbf2ee9"

6
example/halo2/README.md Normal file
View File

@@ -0,0 +1,6 @@
Always use the --release flag otherwise it's too slow:
```
cargo run --release --bin simple3
```

View File

@@ -0,0 +1,73 @@
use std::iter;
use group::{ff::PrimeFieldBits, Curve};
use halo2::{
arithmetic::{CurveAffine, Field, FieldExt},
pasta::{Fp, Fq},
};
use halo2_ecc::gadget::FixedPoints;
use halo2_poseidon::primitive::{ConstantLength, Hash, P128Pow5T3 as OrchardNullifier};
use orchard::constants::{fixed_bases::OrchardFixedBases, sinsemilla::MERKLE_CRH_PERSONALIZATION};
use rand::rngs::OsRng;
use sinsemilla::primitive::{CommitDomain, HashDomain};
use halo2_examples::pedersen_commitment;
fn main() {
let secret_key = Fq::random(&mut OsRng);
let serial = Fp::random(&mut OsRng);
// Sinsemilla hash
let domain = HashDomain::new(MERKLE_CRH_PERSONALIZATION);
let nullifier = domain
.hash(
iter::empty()
.chain(secret_key.to_le_bits().iter().by_val())
.chain(serial.to_le_bits().iter().by_val()),
)
.unwrap();
let public_key = OrchardFixedBases::SpendAuthG.generator() * secret_key;
let coords = public_key.to_affine().coordinates().unwrap();
let value = 110;
let asset = 1;
let value_blind = Fq::random(&mut OsRng);
let asset_blind = Fq::random(&mut OsRng);
let coin_blind = Fp::random(&mut OsRng);
// FIXME:
let messages = [
[*coords.x(), *coords.y()],
[Fp::from(value), Fp::from(asset)],
[serial, coin_blind],
];
let mut coin = Fp::zero();
for msg in messages.iter() {
coin += Hash::init(OrchardNullifier, ConstantLength::<2>).hash(*msg);
}
// TODO: Merkle
let value_commit = pedersen_commitment(value, value_blind);
let asset_commit = pedersen_commitment(asset, asset_blind);
let value_coords = value_commit.to_affine().coordinates().unwrap();
let asset_coords = value_commit.to_affine().coordinates().unwrap();
let sig_secret = Fq::random(&mut OsRng);
let sig_pubkey = OrchardFixedBases::SpendAuthG.generator() * sig_secret;
let sig_pk_coords = sig_pubkey.to_affine().coordinates().unwrap();
let mut public_inputs = vec![
nullifier,
*value_coords.x(),
*value_coords.y(),
*asset_coords.x(),
*asset_coords.y(),
// merkle_root,
*sig_pk_coords.x(),
*sig_pk_coords.y(),
];
}

View File

@@ -0,0 +1,439 @@
use std::{convert::TryInto, time::Instant};
use group::{ff::Field, Curve, Group};
use halo2::{
arithmetic::CurveAffine,
circuit::{floor_planner, Layouter},
dev::MockProver,
pasta::{vesta, Ep, Fp, Fq},
plonk,
plonk::{Circuit, ConstraintSystem, Error},
poly::commitment,
transcript::{Blake2bRead, Blake2bWrite},
};
use halo2_ecc::{chip::EccChip, gadget::FixedPoint};
use halo2_poseidon::{
gadget::{Hash as PoseidonHash, Word},
pow5t3::{Pow5T3Chip as PoseidonChip, StateWord},
primitive::{ConstantLength, Hash, P128Pow5T3 as OrchardNullifier},
};
use halo2_utilities::{
lookup_range_check::LookupRangeCheckConfig, CellValue, UtilitiesInstructions, Var,
};
use orchard::constants::fixed_bases::OrchardFixedBases;
use rand::rngs::OsRng;
use halo2_examples::{circuit::Config, pedersen_commitment};
const K: u32 = 9;
#[derive(Default, Debug)]
struct MintCircuit {
pub_x: Option<Fp>, // x coordinate for pubkey
pub_y: Option<Fp>, // y coordinate for pubkey
value: Option<Fp>, // The value of this coin
asset: Option<Fp>, // The asset ID
serial: Option<Fp>, // Unique serial number corresponding to this coin
coin_blind: Option<Fp>, // Random blinding factor for coin
value_blind: Option<Fq>, // Random blinding factor for value commitment
asset_blind: Option<Fq>, // Random blinding factor for the asset ID
}
impl UtilitiesInstructions<Fp> for MintCircuit {
type Var = CellValue<Fp>;
}
impl Circuit<Fp> for MintCircuit {
type Config = Config;
type FloorPlanner = floor_planner::V1;
//type FloorPlanner = SimpleFloorPlanner;
fn without_witnesses(&self) -> Self {
Self::default()
}
fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
let advices = [
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
];
let q_add = meta.selector();
let table_idx = meta.lookup_table_column();
// let lookup = (
// table_idx,
// meta.lookup_table_column(),
// meta.lookup_table_column(),
// );
let primary = meta.instance_column();
meta.enable_equality(primary.into());
for advice in advices.iter() {
meta.enable_equality((*advice).into());
}
let lagrange_coeffs = [
meta.fixed_column(),
meta.fixed_column(),
meta.fixed_column(),
meta.fixed_column(),
meta.fixed_column(),
meta.fixed_column(),
meta.fixed_column(),
meta.fixed_column(),
];
let rc_a = lagrange_coeffs[2..5].try_into().unwrap();
let rc_b = lagrange_coeffs[5..8].try_into().unwrap();
meta.enable_constant(lagrange_coeffs[0]);
let range_check = LookupRangeCheckConfig::configure(meta, advices[9], table_idx);
let ecc_config = EccChip::<OrchardFixedBases>::configure(
meta,
advices,
lagrange_coeffs,
range_check.clone(),
);
let poseidon_config = PoseidonChip::configure(
meta,
OrchardNullifier,
advices[6..9].try_into().unwrap(),
advices[5],
rc_a,
rc_b,
);
Config {
primary,
q_add,
advices,
ecc_config,
poseidon_config,
}
}
fn synthesize(
&self,
config: Self::Config,
mut layouter: impl Layouter<Fp>,
) -> Result<(), Error> {
// Construct the ECC chip.
let ecc_chip = EccChip::construct(config.ecc_config.clone());
let pub_x = self.load_private(
layouter.namespace(|| "load pubkey x"),
config.advices[0],
self.pub_x,
)?;
let pub_y = self.load_private(
layouter.namespace(|| "load pubkey y"),
config.advices[0],
self.pub_y,
)?;
let value = self.load_private(
layouter.namespace(|| "load value"),
config.advices[0],
self.value,
)?;
let asset = self.load_private(
layouter.namespace(|| "load asset"),
config.advices[0],
self.asset,
)?;
let serial = self.load_private(
layouter.namespace(|| "load serial"),
config.advices[0],
self.serial,
)?;
let coin_blind = self.load_private(
layouter.namespace(|| "load coin_blind"),
config.advices[0],
self.coin_blind,
)?;
// =============
// = Coin hash =
// =============
// TODO: This is a hack until issue is resolved in poseidon gadget
let mut coin = Fp::zero();
let messages = [[pub_x, pub_y], [value, asset], [serial, coin_blind]];
//let messages = [[pub_x, pub_y], [value, asset]];
//let messages = [[pub_x, pub_y]];
for msg in messages.iter() {
let poseidon_message = layouter.assign_region(
|| "load message",
|mut region| {
let mut message_word = |i: usize| {
let val = msg[i].value();
let var = region.assign_advice(
|| format!("load message_{}", i),
config.poseidon_config.state()[i],
0,
|| val.ok_or(Error::SynthesisError),
)?;
region.constrain_equal(var, msg[i].cell())?;
Ok(Word::<_, _, OrchardNullifier, 3, 2>::from_inner(
StateWord::new(var, val),
))
};
Ok([message_word(0)?, message_word(1)?])
},
)?;
let poseidon_hasher = PoseidonHash::init(
PoseidonChip::construct(config.poseidon_config.clone()),
layouter.namespace(|| "Poseidon init"),
ConstantLength::<2>,
)?;
let poseidon_output =
poseidon_hasher.hash(layouter.namespace(|| "Poseidon hash"), poseidon_message)?;
let poseidon_output: CellValue<Fp> = poseidon_output.inner().into();
if !poseidon_output.value().is_none() {
coin += poseidon_output.value().unwrap();
}
}
// if coin != Fp::zero() {
// println!("circuit hash: {:?}", coin);
// }
let hash = self.load_private(
layouter.namespace(|| "load hash"),
config.advices[0],
Some(coin),
)?;
// Constrain the coin C; index in public values is 0
layouter.constrain_instance(hash.cell(), config.primary, 0)?;
// ====================
// = Value commitment =
// ====================
// This constant one is used for multiplication
let one = self.load_constant(
layouter.namespace(|| "constant one"),
config.advices[0],
Fp::one(),
)?;
// v*G_1
let (commitment, _) = {
let value_commit_v = OrchardFixedBases::ValueCommitV;
let value_commit_v = FixedPoint::from_inner(ecc_chip.clone(), value_commit_v);
value_commit_v.mul_short(layouter.namespace(|| "[value] ValueCommitV"), (value, one))?
};
// r_V*G_2
let (blind, _rcv) = {
let rcv = self.value_blind;
let value_commit_r = OrchardFixedBases::ValueCommitR;
let value_commit_r = FixedPoint::from_inner(ecc_chip.clone(), value_commit_r);
value_commit_r.mul(layouter.namespace(|| "[value_blind] ValueCommitR"), rcv)?
};
// Constrain the x and y; indexes in public values are 1 and 2
let value_commit = commitment.add(layouter.namespace(|| "valuecommit"), &blind)?;
layouter.constrain_instance(value_commit.inner().x().cell(), config.primary, 1)?;
layouter.constrain_instance(value_commit.inner().y().cell(), config.primary, 2)?;
// ====================
// = Asset commitment =
// ====================
// a*G_1
let (commitment, _) = {
let asset_commit_v = OrchardFixedBases::ValueCommitV;
let asset_commit_v = FixedPoint::from_inner(ecc_chip.clone(), asset_commit_v);
asset_commit_v.mul_short(layouter.namespace(|| "[asset] ValueCommitV"), (asset, one))?
};
// r_A*G_2
let (blind, _rca) = {
let rca = self.asset_blind;
let asset_commit_r = OrchardFixedBases::ValueCommitR;
let asset_commit_r = FixedPoint::from_inner(ecc_chip.clone(), asset_commit_r);
asset_commit_r.mul(layouter.namespace(|| "[asset_blind] ValueCommitR"), rca)?
};
// Constrain the x and y; indexes in public values are 3 and 4
let asset_commit = commitment.add(layouter.namespace(|| "assetcommit"), &blind)?;
layouter.constrain_instance(asset_commit.inner().x().cell(), config.primary, 3)?;
layouter.constrain_instance(asset_commit.inner().y().cell(), config.primary, 4)?;
Ok(())
}
}
#[derive(Debug)]
struct VerifyingKey {
params: commitment::Params<vesta::Affine>,
vk: plonk::VerifyingKey<vesta::Affine>,
}
impl VerifyingKey {
fn build() -> Self {
let params = commitment::Params::new(K);
let circuit: MintCircuit = Default::default();
let vk = plonk::keygen_vk(&params, &circuit).unwrap();
VerifyingKey { params, vk }
}
}
#[derive(Debug)]
struct ProvingKey {
params: commitment::Params<vesta::Affine>,
pk: plonk::ProvingKey<vesta::Affine>,
}
impl ProvingKey {
fn build() -> Self {
let params = commitment::Params::new(K);
let circuit: MintCircuit = Default::default();
let vk = plonk::keygen_vk(&params, &circuit).unwrap();
let pk = plonk::keygen_pk(&params, vk, &circuit).unwrap();
ProvingKey { params, pk }
}
}
#[derive(Clone, Debug)]
struct Proof(Vec<u8>);
impl AsRef<[u8]> for Proof {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl Proof {
fn create(pk: &ProvingKey, circuits: &[MintCircuit], pubinputs: &[Fp]) -> Result<Self, Error> {
let mut transcript = Blake2bWrite::<_, vesta::Affine, _>::init(vec![]);
plonk::create_proof(
&pk.params,
&pk.pk,
circuits,
&[&[pubinputs]],
&mut transcript,
)?;
Ok(Proof(transcript.finalize()))
}
fn verify(&self, vk: &VerifyingKey, pubinputs: &[Fp]) -> Result<(), plonk::Error> {
let msm = vk.params.empty_msm();
let mut transcript = Blake2bRead::init(&self.0[..]);
let guard = plonk::verify_proof(&vk.params, &vk.vk, msm, &[&[pubinputs]], &mut transcript)?;
let msm = guard.clone().use_challenges();
if msm.eval() {
Ok(())
} else {
Err(Error::ConstraintSystemFailure)
}
}
// fn new(bytes: Vec<u8>) -> Self {
// Proof(bytes)
// }
}
fn main() {
let pubkey = Ep::random(&mut OsRng);
let coords = pubkey.to_affine().coordinates().unwrap();
let value = 110;
let asset = 1;
let value_blind = Fq::random(&mut OsRng);
let asset_blind = Fq::random(&mut OsRng);
let serial = Fp::random(&mut OsRng);
let coin_blind = Fp::random(&mut OsRng);
let mut coin = Fp::zero();
let messages = [
[*coords.x(), *coords.y()],
[Fp::from(value), Fp::from(asset)],
[serial, coin_blind],
];
// TODO: This is a hack until issue is fixed in poseidon gadget
for msg in messages.iter() {
coin += Hash::init(OrchardNullifier, ConstantLength::<2>).hash(*msg);
}
let value_commit = pedersen_commitment(value, value_blind);
let value_coords = value_commit.to_affine().coordinates().unwrap();
let asset_commit = pedersen_commitment(asset, asset_blind);
let asset_coords = asset_commit.to_affine().coordinates().unwrap();
let mut public_inputs = vec![
coin,
*value_coords.x(),
*value_coords.y(),
*asset_coords.x(),
*asset_coords.y(),
];
let circuit = MintCircuit {
pub_x: Some(*coords.x()),
pub_y: Some(*coords.y()),
value: Some(vesta::Scalar::from(value)),
asset: Some(vesta::Scalar::from(asset)),
serial: Some(serial),
coin_blind: Some(coin_blind),
value_blind: Some(value_blind),
asset_blind: Some(asset_blind),
};
// Valid MockProver
let prover = MockProver::run(K, &circuit, vec![public_inputs.clone()]).unwrap();
assert_eq!(prover.verify(), Ok(()));
// Add 1 to break the public inputs
public_inputs[0] += Fp::from(0xdeadbeef);
// Invalid MockProver
let prover = MockProver::run(K, &circuit, vec![public_inputs.clone()]).unwrap();
assert!(prover.verify().is_err());
// Remove 1 to make the public inputs valid again
public_inputs[0] -= Fp::from(0xdeadbeef);
// Actual ZK proof
let start = Instant::now();
let vk = VerifyingKey::build();
let pk = ProvingKey::build();
println!("\nSetup: [{:?}]", start.elapsed());
let start = Instant::now();
let proof = Proof::create(&pk, &[circuit], &public_inputs).unwrap();
println!("Prove: [{:?}]", start.elapsed());
let start = Instant::now();
assert!(proof.verify(&vk, &public_inputs).is_ok());
println!("Verify: [{:?}]", start.elapsed());
}

View File

@@ -0,0 +1,298 @@
use std::convert::TryInto;
use std::time::Instant;
use halo2::{
circuit::{floor_planner, Layouter},
pasta::{vesta, Fp},
plonk,
plonk::{
Advice, Circuit, Column, ConstraintSystem, Error, Instance as InstanceColumn, Selector,
},
poly::{commitment, Rotation},
transcript::{Blake2bRead, Blake2bWrite},
};
use halo2_poseidon::{
gadget::{Hash as PoseidonHash, Word},
pow5t3::{Pow5T3Chip as PoseidonChip, Pow5T3Config as PoseidonConfig, StateWord},
primitive::{ConstantLength, Hash, P128Pow5T3 as OrchardNullifier},
};
use halo2_utilities::{copy, CellValue, UtilitiesInstructions, Var};
const K: u32 = 6;
#[derive(Clone, Debug)]
struct Config {
primary: Column<InstanceColumn>,
q_add: Selector,
advices: [Column<Advice>; 10],
poseidon_config: PoseidonConfig<Fp>,
}
#[derive(Default, Debug)]
struct HashCircuit {
a: Option<Fp>, // First input for hash
b: Option<Fp>, // Second input for hash
c: Option<Fp>, // c is summed with hash
}
impl UtilitiesInstructions<Fp> for HashCircuit {
type Var = CellValue<Fp>;
}
impl Circuit<Fp> for HashCircuit {
type Config = Config;
type FloorPlanner = floor_planner::V1;
fn without_witnesses(&self) -> Self {
Self::default()
}
fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
// 10 advice columns
let advices = [
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
meta.advice_column(),
];
// Addition of two field elements: poseidon_hash(a, b) + c
let q_add = meta.selector();
meta.create_gate("poseidon_hash(a, b) + c", |meta| {
let q_add = meta.query_selector(q_add);
let sum = meta.query_advice(advices[6], Rotation::cur());
let hash = meta.query_advice(advices[7], Rotation::cur());
let c = meta.query_advice(advices[8], Rotation::cur());
vec![q_add * (hash + c - sum)]
});
let primary = meta.instance_column();
meta.enable_equality(primary.into());
for advice in advices.iter() {
meta.enable_equality((*advice).into());
}
let lagrange_coeffs = [
meta.fixed_column(),
meta.fixed_column(),
meta.fixed_column(),
meta.fixed_column(),
meta.fixed_column(),
meta.fixed_column(),
meta.fixed_column(),
meta.fixed_column(),
];
let rc_a = lagrange_coeffs[2..5].try_into().unwrap();
let rc_b = lagrange_coeffs[5..8].try_into().unwrap();
meta.enable_constant(lagrange_coeffs[0]);
let poseidon_config = PoseidonChip::configure(
meta,
OrchardNullifier,
advices[6..9].try_into().unwrap(),
advices[5],
rc_a,
rc_b,
);
Config {
primary,
q_add,
advices,
poseidon_config,
}
}
fn synthesize(
&self,
config: Self::Config,
mut layouter: impl Layouter<Fp>,
) -> Result<(), Error> {
let a = self.load_private(layouter.namespace(|| "load a"), config.advices[0], self.a)?;
let b = self.load_private(layouter.namespace(|| "load b"), config.advices[0], self.b)?;
let c = self.load_private(layouter.namespace(|| "load c"), config.advices[0], self.c)?;
let hash = {
let message = [a, b];
let poseidon_message = layouter.assign_region(
|| "load message",
|mut region| {
let mut message_word = |i: usize| {
let value = message[i].value();
let var = region.assign_advice(
|| format!("load message_{}", i),
config.poseidon_config.state()[i],
0,
|| value.ok_or(Error::SynthesisError),
)?;
region.constrain_equal(var, message[i].cell())?;
Ok(Word::<_, _, OrchardNullifier, 3, 2>::from_inner(
StateWord::new(var, value),
))
};
Ok([message_word(0)?, message_word(1)?])
},
)?;
let poseidon_hasher = PoseidonHash::init(
//config.poseidon_chip(),
PoseidonChip::construct(config.poseidon_config.clone()),
layouter.namespace(|| "Poseidon init"),
ConstantLength::<2>,
)?;
let poseidon_output = poseidon_hasher.hash(
layouter.namespace(|| "Poseidon hash (a, b)"),
poseidon_message,
)?;
let poseidon_output: CellValue<Fp> = poseidon_output.inner().into();
poseidon_output
};
// Add hash output to c
let scalar = layouter.assign_region(
|| " `scalar` = poseidon_hash(a, b) + c",
|mut region| {
config.q_add.enable(&mut region, 0)?;
copy(&mut region, || "copy hash", config.advices[7], 0, &hash)?;
copy(&mut region, || "copy c", config.advices[8], 0, &c)?;
let scalar_val = hash.value().zip(c.value()).map(|(hash, c)| hash + c);
let cell = region.assign_advice(
|| "poseidon_hash(a, b) + c",
config.advices[6],
0,
|| scalar_val.ok_or(Error::SynthesisError),
)?;
Ok(CellValue::new(cell, scalar_val))
},
)?;
layouter.constrain_instance(scalar.cell(), config.primary, 0)
}
}
#[derive(Debug)]
struct VerifyingKey {
params: commitment::Params<vesta::Affine>,
vk: plonk::VerifyingKey<vesta::Affine>,
}
impl VerifyingKey {
fn build() -> Self {
let params = commitment::Params::new(K);
let circuit: HashCircuit = Default::default();
let vk = plonk::keygen_vk(&params, &circuit).unwrap();
VerifyingKey { params, vk }
}
}
#[derive(Debug)]
struct ProvingKey {
params: commitment::Params<vesta::Affine>,
pk: plonk::ProvingKey<vesta::Affine>,
}
impl ProvingKey {
fn build() -> Self {
let params = commitment::Params::new(K);
let circuit: HashCircuit = Default::default();
let vk = plonk::keygen_vk(&params, &circuit).unwrap();
let pk = plonk::keygen_pk(&params, vk, &circuit).unwrap();
ProvingKey { params, pk }
}
}
#[derive(Clone, Debug)]
struct Proof(Vec<u8>);
impl AsRef<[u8]> for Proof {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl Proof {
fn create(pk: &ProvingKey, circuits: &[HashCircuit], pubinputs: &[Fp]) -> Result<Self, Error> {
let mut transcript = Blake2bWrite::<_, vesta::Affine, _>::init(vec![]);
plonk::create_proof(
&pk.params,
&pk.pk,
circuits,
&[&[pubinputs]],
&mut transcript,
)?;
Ok(Proof(transcript.finalize()))
}
fn verify(&self, vk: &VerifyingKey, pubinputs: &[Fp]) -> Result<(), plonk::Error> {
let msm = vk.params.empty_msm();
let mut transcript = Blake2bRead::init(&self.0[..]);
let guard = plonk::verify_proof(&vk.params, &vk.vk, msm, &[&[pubinputs]], &mut transcript)?;
let msm = guard.clone().use_challenges();
if msm.eval() {
Ok(())
} else {
Err(Error::ConstraintSystemFailure)
}
}
// fn new(bytes: Vec<u8>) -> Self {
// Proof(bytes)
// }
}
fn main() {
let a = Fp::from(13);
let b = Fp::from(69);
let c = Fp::from(42);
let message = [a, b];
let output = Hash::init(OrchardNullifier, ConstantLength::<2>).hash(message);
let circuit = HashCircuit {
a: Some(a),
b: Some(b),
c: Some(c),
};
let sum = output + c;
// Correct:
let public_inputs = vec![sum];
// Incorrect:
// let public_inputs = vec![sum + Fp::one()];
let start = Instant::now();
let vk = VerifyingKey::build();
let pk = ProvingKey::build();
println!("Setup: [{:?}]", start.elapsed());
let start = Instant::now();
let proof = Proof::create(&pk, &[circuit], &public_inputs).unwrap();
println!("Prove: [{:?}]", start.elapsed());
let start = Instant::now();
assert!(proof.verify(&vk, &public_inputs).is_ok());
println!("Verify: [{:?}]", start.elapsed());
}

View File

@@ -0,0 +1,130 @@
use halo2::{
circuit::{SimpleFloorPlanner, Chip, Layouter},
pasta::{EqAffine, Fp},
plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Expression, Selector, create_proof, verify_proof, keygen_vk, keygen_pk},
poly::{commitment::Params, Rotation},
transcript::{Blake2bRead, Blake2bWrite, Challenge255},
};
use std::time::Instant;
#[derive(Clone, Debug)]
struct CoolConfig {
a_col: Column<Advice>,
s_range: Selector,
}
struct CoolChip {
config: CoolConfig
}
impl Chip<Fp> for CoolChip {
type Config = CoolConfig;
type Loaded = ();
fn config(&self) -> &Self::Config {
&self.config
}
fn loaded(&self) -> &Self::Loaded {
&()
}
}
impl CoolChip {
fn construct(config: CoolConfig) -> Self {
Self { config }
}
fn configure(cs: &mut ConstraintSystem<Fp>) -> CoolConfig {
let a_col = cs.advice_column();
let s_range = cs.selector();
cs.create_gate("check", |cs| {
let a = cs.query_advice(a_col, Rotation::cur());
let s_range = cs.query_selector(s_range);
vec![s_range * (a - Expression::Constant(Fp::from(2)))]
});
CoolConfig { a_col, s_range }
}
fn alloc_and_check(
&self,
layouter: &mut impl Layouter<Fp>,
a: Option<Fp>,
) -> Result<(), Error> {
layouter.assign_region(
|| "load private inputs",
|mut region| {
let row_offset = 0;
self.config.s_range.enable(&mut region, row_offset)?;
region.assign_advice(
|| "private input 'a'",
self.config.a_col,
row_offset,
|| a.ok_or(Error::SynthesisError),
)?;
Ok(())
},
)
}
}
#[derive(Clone)]
struct CoolCircuit {
// Private input.
a: Option<Fp>,
}
impl Circuit<Fp> for CoolCircuit {
type Config = CoolConfig;
type FloorPlanner = SimpleFloorPlanner;
fn without_witnesses(&self) -> Self {
Self { a: None }
}
fn configure(cs: &mut ConstraintSystem<Fp>) -> Self::Config {
CoolChip::configure(cs)
}
fn synthesize(&self, config: Self::Config, mut layouter: impl Layouter<Fp>) -> Result<(), Error> {
let chip = CoolChip::construct(config);
chip.alloc_and_check(&mut layouter, self.a)
}
}
fn main() {
let start = Instant::now();
let params: Params<EqAffine> = Params::new(4);
let empty_circuit = CoolCircuit { a: None };
let vk = keygen_vk(&params, &empty_circuit).expect("keygen_vk should not fail");
let pk = keygen_pk(&params, vk, &empty_circuit).expect("keygen_pk should not fail");
println!("Setup: [{:?}]", start.elapsed());
let start = Instant::now();
let circuit = CoolCircuit {
a: Some(Fp::from(2)),
};
// Create a proof
let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);
create_proof(&params, &pk, &[circuit], &[&[]], &mut transcript)
.expect("proof generation should not fail");
let proof = transcript.finalize();
println!("Prove: [{:?}]", start.elapsed());
let start = Instant::now();
let msm = params.empty_msm();
let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
let verification = verify_proof(&params, pk.get_vk(), msm, &[&[]], &mut transcript);
if let Err(err) = verification {
panic!("error {:?}", err);
}
let guard = verification.unwrap();
let msm = guard.clone().use_challenges();
assert!(msm.eval());
println!("Verify: [{:?}]", start.elapsed());
}

View File

@@ -0,0 +1,267 @@
use halo2::{
circuit::{SimpleFloorPlanner, Cell, Chip, Layouter},
pasta::{EqAffine, Fp},
plonk::{Advice, Any, Circuit, Column, ConstraintSystem, Error, Expression, Selector, create_proof, verify_proof, keygen_vk, keygen_pk, Permutation},
poly::{commitment::{Blind, Params}, Rotation},
transcript::{Blake2bRead, Blake2bWrite, Challenge255},
};
use group::Curve;
use std::time::Instant;
#[derive(Clone, Debug)]
struct CoolConfig {
a_col: Column<Advice>,
b_col: Column<Advice>,
permute: Permutation,
s_range: Selector,
s_mul: Selector,
s_pub: Selector,
}
struct CoolChip {
config: CoolConfig
}
impl Chip<Fp> for CoolChip {
type Config = CoolConfig;
type Loaded = ();
fn config(&self) -> &Self::Config {
&self.config
}
fn loaded(&self) -> &Self::Loaded {
&()
}
}
#[derive(Clone, Debug)]
struct Number {
cell: Cell,
value: Option<Fp>,
}
impl CoolChip {
fn construct(config: CoolConfig) -> Self {
Self { config }
}
fn configure(cs: &mut ConstraintSystem<Fp>) -> CoolConfig {
let a_col = cs.advice_column();
let b_col = cs.advice_column();
let instance = cs.instance_column();
let permute = {
// Convert advice columns into an "any" columns.
let cols: [Column<Any>; 2] = [a_col.into(), b_col.into()];
Permutation::new(cs, &cols)
};
let s_range = cs.selector();
let s_mul = cs.selector();
let s_pub = cs.selector();
cs.create_gate("check", |cs| {
let a = cs.query_advice(a_col, Rotation::cur());
let s_range = cs.query_selector(s_range);
vec![s_range * (a - Expression::Constant(Fp::from(2)))]
});
cs.create_gate("mul", |cs| {
let lhs = cs.query_advice(a_col, Rotation::cur());
let rhs = cs.query_advice(b_col, Rotation::cur());
let out = cs.query_advice(a_col, Rotation::next());
let s_mul = cs.query_selector(s_mul);
vec![s_mul * (lhs * rhs + out * -Fp::one())]
});
cs.create_gate("public input", |cs| {
let a = cs.query_advice(b_col, Rotation::cur());
let p = cs.query_instance(instance, Rotation::cur());
let s = cs.query_selector(s_pub);
vec![s * (p + a * -Fp::one())]
});
CoolConfig { a_col, b_col, permute, s_range, s_mul, s_pub }
}
fn alloc_left(
&self,
layouter: &mut impl Layouter<Fp>,
value: Option<Fp>
) -> Result<Number, Error> {
layouter.assign_region(
|| "load left private input",
|mut region| {
let cell = region.assign_advice(
|| "private input 'a'",
self.config.a_col,
0,
|| value.ok_or(Error::SynthesisError),
)?;
Ok(Number { cell, value })
}
)
}
fn check(
&self,
layouter: &mut impl Layouter<Fp>,
number: Number
) -> Result<(), Error> {
layouter.assign_region(
|| "load private inputs",
|mut region| {
self.config.s_range.enable(&mut region, 0)?;
let a = region.assign_advice(
|| "lhs",
self.config.a_col,
0,
|| number.value.ok_or(Error::SynthesisError),
)?;
region.constrain_equal(&self.config.permute, number.cell, a)?;
Ok(())
},
)
}
fn mul(
&self,
layouter: &mut impl Layouter<Fp>,
a: Number,
b: Number
) -> Result<Number, Error> {
let mut out = None;
layouter.assign_region(
|| "mul",
|mut region| {
self.config.s_mul.enable(&mut region, 0)?;
let lhs = region.assign_advice(
|| "lhs",
self.config.a_col,
0,
|| a.value.ok_or(Error::SynthesisError),
)?;
let rhs = region.assign_advice(
|| "rhs",
self.config.b_col,
0,
|| b.value.ok_or(Error::SynthesisError),
)?;
region.constrain_equal(&self.config.permute, a.cell, lhs)?;
region.constrain_equal(&self.config.permute, b.cell, rhs)?;
let value = a.value.and_then(|a| b.value.map(|b| a * b));
let cell = region.assign_advice(
|| "lhs * rhs",
self.config.a_col,
1,
|| value.ok_or(Error::SynthesisError),
)?;
out = Some(Number { cell, value });
Ok(())
},
)?;
Ok(out.unwrap())
}
fn expose_public(&self, layouter: &mut impl Layouter<Fp>, num: Number) -> Result<(), Error> {
layouter.assign_region(
|| "expose public",
|mut region| {
self.config.s_pub.enable(&mut region, 0)?;
let out = region.assign_advice(
|| "public advice",
self.config.b_col,
0,
|| num.value.ok_or(Error::SynthesisError),
)?;
region.constrain_equal(&self.config.permute, num.cell, out)?;
Ok(())
},
)
}
}
#[derive(Clone)]
struct CoolCircuit {
// Private input.
a: Option<Fp>,
}
impl Circuit<Fp> for CoolCircuit {
type Config = CoolConfig;
type FloorPlanner = SimpleFloorPlanner;
fn without_witnesses(&self) -> Self {
Self { a: None }
}
fn configure(cs: &mut ConstraintSystem<Fp>) -> Self::Config {
CoolChip::configure(cs)
}
fn synthesize(&self, config: Self::Config, mut layouter: impl Layouter<Fp>) -> Result<(), Error> {
let chip = CoolChip::construct(config);
let a = chip.alloc_left(&mut layouter, self.a)?;
chip.check(&mut layouter, a.clone())?;
let a2 = chip.mul(&mut layouter, a.clone(), a)?;
chip.expose_public(&mut layouter, a2)?;
Ok(())
}
}
fn main() {
let k = 6;
let start = Instant::now();
let params: Params<EqAffine> = Params::new(k);
let empty_circuit = CoolCircuit { a: None };
let vk = keygen_vk(&params, &empty_circuit).expect("keygen_vk should not fail");
let pk = keygen_pk(&params, vk, &empty_circuit).expect("keygen_pk should not fail");
println!("Setup: [{:?}]", start.elapsed());
let start = Instant::now();
let circuit = CoolCircuit {
a: Some(Fp::from(2)),
};
let mut public_inputs = pk.get_vk().get_domain().empty_lagrange();
public_inputs[4] = Fp::from(4);
// Create a proof
let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);
create_proof(&params, &pk, &[circuit], &[&[public_inputs.clone()]], &mut transcript)
.expect("proof generation should not fail");
let proof = transcript.finalize();
println!("Prove: [{:?}]", start.elapsed());
let pubinput = params
.commit_lagrange(&public_inputs, Blind::default())
.to_affine();
let pubinput_slice = &[pubinput];
let start = Instant::now();
let msm = params.empty_msm();
let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
let verification = verify_proof(&params, pk.get_vk(), msm, &[pubinput_slice], &mut transcript);
if let Err(err) = verification {
panic!("error {:?}", err);
}
let guard = verification.unwrap();
let msm = guard.clone().use_challenges();
assert!(msm.eval());
println!("Verify: [{:?}]", start.elapsed());
}

View File

@@ -0,0 +1,16 @@
use halo2::{
pasta::pallas,
plonk::{Advice, Column, Instance as InstanceColumn, Selector},
};
use halo2_ecc::chip::EccConfig;
use halo2_poseidon::pow5t3::Pow5T3Config as PoseidonConfig;
#[derive(Clone, Debug)]
pub struct Config {
pub primary: Column<InstanceColumn>,
pub q_add: Selector,
pub advices: [Column<Advice>; 10],
pub ecc_config: EccConfig,
pub poseidon_config: PoseidonConfig<pallas::Base>,
}

19
example/halo2/src/lib.rs Normal file
View File

@@ -0,0 +1,19 @@
pub mod circuit;
use halo2::{
arithmetic::{CurveExt, FieldExt},
pasta::{Ep, Fq},
};
use orchard::constants::fixed_bases::{
VALUE_COMMITMENT_PERSONALIZATION, VALUE_COMMITMENT_R_BYTES, VALUE_COMMITMENT_V_BYTES,
};
#[allow(non_snake_case)]
pub fn pedersen_commitment(value: u64, blind: Fq) -> Ep {
let hasher = Ep::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
let V = hasher(&VALUE_COMMITMENT_V_BYTES);
let R = hasher(&VALUE_COMMITMENT_R_BYTES);
let value = Fq::from_u64(value);
V * value + R * blind
}

460
old/compile.py Normal file
View File

@@ -0,0 +1,460 @@
import argparse
import sys
from enum import Enum
alloc_commands = {
"param": 1,
"private": 1,
"public": 1,
}
op_commands = {
"set": 2,
"mul": 2,
"add": 2,
"sub": 2,
"divide": 2,
"double": 1,
"square": 1,
"invert": 1,
"unpack_bits": 3,
"load": 2,
"local": 1,
"debug": 1,
"dump_alloc": 0,
"dump_local": 0,
}
constraint_commands = {
"lc0_add": 1,
"lc1_add": 1,
"lc2_add": 1,
"lc0_sub": 1,
"lc1_sub": 1,
"lc2_sub": 1,
"lc0_add_one": 0,
"lc1_add_one": 0,
"lc2_add_one": 0,
"lc0_sub_one": 0,
"lc1_sub_one": 0,
"lc2_sub_one": 0,
"lc0_add_coeff": 2,
"lc1_add_coeff": 2,
"lc2_add_coeff": 2,
"lc0_add_constant": 1,
"lc1_add_constant": 1,
"lc2_add_constant": 1,
"enforce": 0,
"lc_coeff_reset": 0,
"lc_coeff_double": 0,
}
def eprint(*args):
print(*args, file=sys.stderr)
class Line:
def __init__(self, text, line_number):
self.text = text
self.orig = text
self.lineno = line_number
self.clean()
def clean(self):
# Remove the comments
self.text = self.text.split("#", 1)[0]
# Remove whitespace
self.text = self.text.strip()
def is_empty(self):
return bool(self.text)
def __repr__(self):
return "Line %s: %s" % (self.lineno, self.orig.lstrip())
def command(self):
if not self.is_empty():
return None
return self.text.split(" ")[0]
def args(self):
if not self.is_empty():
return None
return self.text.split()[1:]
def clean(contents):
# Split input into lines
contents = contents.split("\n")
contents = [Line(line, i + 1) for i, line in enumerate(contents)]
# Remove empty blank lines
contents = [line for line in contents if line.is_empty()]
return contents
def divide_sections(contents):
state = "NOSCOPE"
segments = {}
current_segment = []
contract_name = None
for line in contents:
if line.command() == "contract":
if len(line.args()) != 1:
eprint("error: missing contract name")
eprint(line)
return None
contract_name = line.args()[0]
if state == "NOSCOPE":
assert not current_segment
state = "INSCOPE"
continue
else:
assert state == "INSCOPE"
eprint("error: double contract entry violation")
eprint(line)
return None
elif line.command() == "end":
if len(line.args()) != 0:
eprint("error: end takes no args")
eprint(line)
return None
if state == "NOSCOPE":
eprint("error: missing contract start for end")
eprint(line)
return None
else:
assert state == "INSCOPE"
state = "NOSCOPE"
segments[contract_name] = current_segment
current_segment = []
continue
elif state == "NOSCOPE":
# Ignore lines outside any contract
continue
current_segment.append(line)
if state != "NOSCOPE":
eprint("error: reached end of file with unclosed scope")
return None
return segments
def extract_relevant_lines(contract, commands_table):
relevant_lines = []
for line in contract:
command = line.command()
if command not in commands_table.keys():
continue
define = commands_table[command]
if len(line.args()) != define:
eprint("error: wrong number of args")
return None
relevant_lines.append(line)
return relevant_lines
class VariableType(Enum):
PUBLIC = 1
PRIVATE = 2
class Variable:
def __init__(self, symbol, index, type, is_param):
self.symbol = symbol
self.index = index
self.type = type
self.is_param = is_param
def __repr__(self):
return "<Variable %s:%s>" % (self.symbol, self.index)
def generate_alloc_table(contract):
relevant_lines = extract_relevant_lines(contract, alloc_commands)
alloc_table = {}
for i, line in enumerate(relevant_lines):
assert len(line.args()) == 1
symbol = line.args()[0]
command = line.command()
if command == "param":
type = VariableType.PRIVATE
is_param = True
elif command == "private":
type = VariableType.PRIVATE
is_param = False
elif command == "public":
type = VariableType.PUBLIC
is_param = False
else:
assert False
if symbol in alloc_table:
eprint("error: duplicate symbol '%s'" % symbol)
eprint(line)
return None
alloc_table[symbol] = Variable(symbol, i, type, is_param)
return alloc_table
class Operation:
def __init__(self, line, indexes):
self.command = line.command()
self.args = indexes
self.line = line
class VariableRefType(Enum):
AUX = 1
LOCAL = 2
CONST = 3
class VariableRef:
def __init__(self, type, index):
self.type = type
self.index = index
def __repr__(self):
return "%s(%s)" % (self.type.name, self.index)
def symbols_list_to_refs(line, alloc, local_vars, constants):
indexes = []
for symbol in line.args():
if symbol in alloc:
# Lookup variable index
index = alloc[symbol].index
index = VariableRef(VariableRefType.AUX, index)
elif symbol in local_vars:
index = local_vars[symbol]
index = VariableRef(VariableRefType.LOCAL, index)
elif symbol in constants:
index = constants[symbol][0]
index = VariableRef(VariableRefType.CONST, index)
else:
eprint("error: missing unallocated symbol '%s'" % symbol)
eprint(line)
return None
indexes.append(index)
return indexes
def generate_ops_table(contract, alloc, constants):
relevant_lines = extract_relevant_lines(contract, op_commands)
ops = []
local_vars = {}
for line in relevant_lines:
# This is a special case which creates a new local stack value
if line.command() == "local":
assert len(line.args()) == 1
symbol = line.args()[0]
local_vars[symbol] = len(local_vars)
indexes = []
else:
if (indexes := symbols_list_to_refs(line, alloc,
local_vars, constants)) is None:
return None
# Handle this here directly since only the
# load command deals with constants
if line.command() == "load":
assert len(indexes) == 2
# This is the only command which uses consts
if indexes[1].type != VariableRefType.CONST:
eprint("error: load command takes a const argument")
eprint(line)
return None
elif any(index.type == VariableRefType.CONST for index in indexes):
eprint("error: invalid const arg")
eprint(line)
return None
ops.append(Operation(line, indexes))
return ops
class Constraint:
def __init__(self, line, lcargs):
self.command = line.command()
self.args = lcargs
self.line = line
def args_comment(self):
return ", ".join("%s" % symbol for symbol in self.line.args())
def symbols_list_to_lcargs(line, alloc, constants):
lcargs = []
for symbol in line.args():
if symbol in alloc:
# Lookup variable index
index = alloc[symbol].index
lcargs.append(index)
elif symbol in constants:
value = constants[symbol]
lcargs.append(value)
else:
eprint("error: missing unallocated symbol '%s'" % symbol)
eprint(line)
return None
return lcargs
def generate_constraints_table(contract, alloc, constants):
relevant_lines = extract_relevant_lines(contract, constraint_commands)
constraints = []
for line in relevant_lines:
if (lcargs := symbols_list_to_lcargs(line, alloc, constants)) is None:
return None
constraints.append(Constraint(line, lcargs))
return constraints
class Contract:
def __init__(self, constants, alloc, ops, constraints):
self.constants = constants
self.alloc = alloc
self.ops = ops
self.constraints = constraints
def __repr__(self):
repr_str = ""
repr_str += "Constants:\n"
for symbol, value in self.constants.items():
repr_str += " // %s\n" % symbol
repr_str += " %s: %s\n" % value
repr_str += "Alloc table:\n"
for symbol, variable in self.alloc.items():
repr_str += " // %s\n" % symbol
repr_str += " %s %s\n" % (variable.type, variable.index)
repr_str += "Operations:\n"
for op in self.ops:
repr_str += " // %s\n" % op.line
repr_str += " %s %s\n" % (op.command, op.args)
repr_str += "Constraints:\n"
for constraint in self.constraints:
if constraint.args:
repr_str += " // %s\n" % constraint.args_comment()
repr_str += " %s %s\n" % (constraint.command, constraint.args)
repr_str += "Stats:\n"
repr_str += " Constants: %s\n" % len(self.constants)
repr_str += " Alloc: %s\n" % len(self.alloc)
repr_str += " Operations: %s\n" % len(self.ops)
repr_str += " Constraint Instructions: %s\n" % len(self.constraints)
return repr_str
def compile(contract, constants):
# Allocation table
# symbol: Private/Public, is_param, index
if (alloc := generate_alloc_table(contract)) is None:
return None
# Operations lines list
if (ops := generate_ops_table(contract, alloc, constants)) is None:
return None
# Constraint commands
if (constraints := generate_constraints_table(
contract, alloc, constants)) is None:
return None
return Contract(constants, alloc, ops, constraints)
def parse_constants(contents):
relevant_lines = [line for line in contents if line.command() == "constant"]
constants = {}
for line in relevant_lines:
assert line.command() == "constant"
if len(line.args()) != 2:
eprint("error: wrong number of args for constant")
eprint(line)
return None
symbol, value = line.args()
try:
int(value, 16)
except ValueError:
eprint("error: invalid constant value for '%s'" % symbol)
eprint(line)
return None
if len(value) != 32*2 + 2 or value[:2] != "0x":
eprint("error: invalid hex value for constant")
eprint(line)
return None
# Remove 0x prefix
value = value[2:]
constants[symbol] = (len(constants), value)
return constants
def process(contents):
# Remove left whitespace
contents = clean(contents)
# Parse all constants
if (constants := parse_constants(contents)) is None:
return None
# Divide into contract sections
if (pre_contracts := divide_sections(contents)) is None:
return None
# Process each contract
contracts = {}
for contract_name, pre_contract in pre_contracts.items():
if (contract := compile(pre_contract, constants)) is None:
return None
contracts[contract_name] = contract
return contracts
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument("filename", help="VM PISM file: proofs/vm.pism")
parser.add_argument("--output", type=argparse.FileType('wb', 0),
default=sys.stdout.buffer, help="Output file")
group = parser.add_mutually_exclusive_group()
group.add_argument('--display', action='store_true',
help="show the compiled code in human readable format")
group.add_argument('--rust', action='store_true',
help="output compiled code to rust for testing")
group.add_argument('--supervisor', action='store_true',
help="output compiled code to zkvm supervisor")
args = parser.parse_args()
src_filename = args.filename
contents = open(src_filename).read()
if (contracts := process(contents)) is None:
return -2
def default_display():
for contract_name, contract in contracts.items():
print("Contract:", contract_name)
print(contract)
if args.display:
default_display()
elif args.rust:
import compile_export_rust
for contract_name, contract in contracts.items():
compile_export_rust.display(contract)
elif args.supervisor:
import compile_export_supervisor
for contract_name, contract in contracts.items():
compile_export_supervisor.export(args.output, contract_name,
contract)
else:
default_display()
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))

40
old/mint.aux Normal file
View File

@@ -0,0 +1,40 @@
{
"constants": {
"G_SPEND": {
"maps_to": "zcash_proofs::constants::SPENDING_KEY_GENERATOR"
},
"G_PROOF": {
"maps_to": "zcash_proofs::constants::PROOF_GENERATION_KEY_GENERATOR"
},
"CRH_IVK": {
"maps_to": "zcash_primitives::constants::CRH_IVK_PERSONALIZATION"
},
"PRF_NF": {
"maps_to": "zcash_primitives::constants::PRF_NF_PERSONALIZATION"
},
"G_VCV": {
"maps_to": "zcash_proofs::constants::VALUE_COMMITMENT_VALUE_GENERATOR"
},
"G_VCR": {
"maps_to": "zcash_proofs::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR"
},
"JUBJUB_FR_CAPACITY": {
"maps_to": "jubjub::Fr::CAPACITY as usize"
},
"NOTE_COMMIT": {
"maps_to": "pedersen_hash::Personalization::NoteCommitment"
},
"MERKLE_0": {
"maps_to": "pedersen_hash::Personalization::MerkleTree(0)"
},
"MERKLE_1": {
"maps_to": "pedersen_hash::Personalization::MerkleTree(1)"
},
"MERKLE_2": {
"maps_to": "pedersen_hash::Personalization::MerkleTree(2)"
},
"MERKLE_3": {
"maps_to": "pedersen_hash::Personalization::MerkleTree(3)"
}
}
}

528
old/pism.py Normal file
View File

@@ -0,0 +1,528 @@
import json
import os
import sys
import codegen
symbol_table = {
"contract": 1,
"param": 2,
"start": 0,
"end": 0,
}
types_map = {
"U64": "u64",
"Fr": "jubjub::Fr",
"Point": "jubjub::SubgroupPoint",
"Scalar": "bls12_381::Scalar",
"Bool": "bool"
}
feature_includes = {"G_SPEND": "use crate::crypto::merkle_node::SAPLING_COMMITMENT_TREE_DEPTH;\n"}
command_desc = {
"witness": (
("EdwardsPoint", True),
("Point", False)
),
"assert_not_small_order": (
("EdwardsPoint", False),
),
"u64_as_binary_le": (
("Vec<Boolean>", True),
("U64", False),
),
"fr_as_binary_le": (
("Vec<Boolean>", True),
("Fr", False)
),
"ec_mul_const": (
("EdwardsPoint", True),
("Vec<Boolean>", False),
("FixedGenerator", False)
),
"ec_mul": (
("EdwardsPoint", True),
("Vec<Boolean>", False),
("EdwardsPoint", False),
),
"ec_add": (
("EdwardsPoint", True),
("EdwardsPoint", False),
("EdwardsPoint", False),
),
"ec_repr": (
("Vec<Boolean>", True),
("EdwardsPoint", False),
),
"ec_get_u": (
("ScalarNum", True),
("EdwardsPoint", False),
),
"emit_ec": (
("EdwardsPoint", False),
),
"alloc_binary": (
("Vec<Boolean>", True),
),
"binary_clone": (
("Vec<Boolean>", True),
("Vec<Boolean>", False),
),
"binary_extend": (
("Vec<Boolean>", False),
("Vec<Boolean>", False),
),
"binary_push": (
("Vec<Boolean>", False),
("Boolean", False),
),
"binary_truncate": (
("Vec<Boolean>", False),
("BinarySize", False),
),
"static_assert_binary_size": (
("Vec<Boolean>", False),
("INTEGER", False),
),
"blake2s": (
("Vec<Boolean>", True),
("Vec<Boolean>", False),
("BlakePersonalization", False),
),
"pedersen_hash": (
("EdwardsPoint", True),
("Vec<Boolean>", False),
("PedersenPersonalization", False),
),
"emit_binary": (
("Vec<Boolean>", False),
),
"alloc_bit": (
("Boolean", True),
("Bool", False),
),
"alloc_const_bit": (
("Boolean", True),
("BOOL_CONST", False),
),
"clone_bit": (
("Boolean", True),
("Boolean", False),
),
"alloc_scalar": (
("ScalarNum", True),
("Scalar", False),
),
"scalar_as_binary": (
("Vec<Boolean>", True),
("ScalarNum", False),
),
"emit_scalar": (
("ScalarNum", False),
),
"scalar_enforce_equal": (
("ScalarNum", False),
("ScalarNum", False),
),
"conditionally_reverse": (
("ScalarNum", True),
("ScalarNum", True),
("ScalarNum", False),
("ScalarNum", False),
("Boolean", False),
),
}
def eprint(*args):
print(*args, file=sys.stderr)
class Line:
def __init__(self, text, line_number):
self.text = text
self.orig = text
self.lineno = line_number
self.clean()
def clean(self):
# Remove the comments
self.text = self.text.split("#", 1)[0]
# Remove whitespace
self.text = self.text.strip()
def is_empty(self):
return bool(self.text)
def __repr__(self):
return "Line %s: %s" % (self.lineno, self.orig.lstrip())
def command(self):
if not self.is_empty():
return None
return self.text.split(" ")[0]
def args(self):
if not self.is_empty():
return None
return self.text.split(" ")[1:]
def clean(contents):
# Split input into lines
contents = contents.split("\n")
contents = [Line(line, i) for i, line in enumerate(contents)]
# Remove empty blank lines
contents = [line for line in contents if line.is_empty()]
return contents
def make_segments(contents):
constants = [line for line in contents if line.command() == "constant"]
segments = []
current_segment = []
for line in contents:
if line.command() == "contract":
current_segment = []
current_segment.append(line)
if line.command() == "end":
segments.append(current_segment)
current_segment = []
return constants, segments
def build_constants_table(constants):
table = {}
for line in constants:
args = line.args()
if len(args) != 2:
eprint("error: wrong number of args")
eprint(line)
return None
name, type = args
table[name] = type
return table
def extract(segment):
assert segment
# Does it have a declaration?
if not segment[0].command() == "contract":
eprint("error: missing contract declaration")
eprint(segment[0])
return None
# Does it have an end?
if not segment[-1].command() == "end":
eprint("error: missing contract end")
eprint(segment[-1])
return None
# Does it have a start?
if not [line for line in segment if line.command() == "start"]:
eprint("error: missing contract start")
eprint(segment[0])
return None
for line in segment:
command, args = line.command(), line.args()
if command in symbol_table:
if symbol_table[command] != len(args):
eprint("error: wrong number of args for command '%s'" % command)
eprint(line)
return None
elif command in command_desc:
if len(command_desc[command]) != len(args):
eprint("error: wrong number of args for command '%s'" % command)
eprint(line)
return None
else:
eprint("error: missing symbol for command '%s'" % command)
eprint(line)
return None
contract_name = segment[0].args()[0]
start_index = [index for index, line in enumerate(segment)
if line.command() == "start"]
if len(start_index) > 1:
eprint("error: multiple start statements in contract '%s'" %
contract_name)
for index in start_index:
eprint(segment[index])
eprint("Aborting.")
return None
assert len(start_index) == 1
start_index = start_index[0]
header = segment[1:start_index]
code = segment[start_index + 1:-1]
params = {}
for param_decl in header:
args = param_decl.args()
assert len(args) == 2
name, type = args
params[name] = type
program = []
for line in code:
command, args = line.command(), line.args()
program.append((command, args, line))
return Contract(contract_name, params, program)
def to_initial_caps(snake_str):
components = snake_str.split("_")
return "".join(x.title() for x in components)
class Contract:
def __init__(self, name, params, program):
self.name = name
self.params = params
self.program = program
def _includes(self):
return \
r"""#![allow(unused_imports)]
#![allow(unused_mut)]
use bellman::{
gadgets::{
boolean,
boolean::{AllocatedBit, Boolean},
multipack,
blake2s,
num,
Assignment,
},
groth16, Circuit, ConstraintSystem, SynthesisError,
};
use bls12_381::Bls12;
use ff::{PrimeField, Field};
use group::Curve;
use zcash_proofs::circuit::{ecc, pedersen_hash};
"""
def _compile_header(self):
code = "pub struct %s {\n" % to_initial_caps(self.name)
for param_name, param_type in self.params.items():
try:
mapped_type = types_map[param_type]
except KeyError:
return None
code += " pub %s: Option<%s>,\n" % (param_name, mapped_type)
code += "}\n"
return code
def _compile_body(self):
self.stack = {}
code = "\n"
#indent = " " * 8
for command, args, line in self.program:
if (code_text := self._compile_line(command, args, line)) is None:
return None
code += "// %s\n" % str(line)
code += code_text + "\n\n"
return code
def _preprocess_args(self, args, line):
nargs = []
for arg in args:
if not arg.startswith("param:"):
nargs.append((arg, False))
continue
_, argname = arg.split(":", 1)
if argname not in self.params:
eprint("error: non-existant param referenced")
eprint(line)
return None
nargs.append((argname, True))
return nargs
def type_checking(self, command, args, line):
assert command in command_desc
type_list = command_desc[command]
if len(type_list) != len(args):
eprint("error: wrong number of arguments!")
eprint(line)
return False
for (expected_type, new_val), (argname, is_param) in \
zip(type_list, args):
# Only type check input arguments, not output values
if new_val:
continue
if expected_type == "INTEGER" or expected_type == "BOOL_CONST":
continue
if is_param:
actual_type = self.params[argname]
elif argname in self.constants:
actual_type = self.constants[argname]
else:
# Check the stack here
if argname not in self.stack:
eprint("error: cannot find value '%s' on the stack!" %
argname)
eprint(line)
return False
actual_type = self.stack[argname]
if expected_type != actual_type:
eprint("error: wrong type for arg '%s'!" % argname)
eprint(line)
return False
return True
def _check_args(self, command, args, line):
assert command in command_desc
type_list = command_desc[command]
assert len(type_list) == len(args)
for (expected_type, is_new_val), (arg, is_param) in zip(type_list, args):
if is_param:
continue
if is_new_val:
continue
if arg in self.stack:
continue
if arg in self.constants:
continue
if expected_type == "INTEGER" or expected_type == "BOOL_CONST":
continue
eprint("error: cannot find '%s' in the stack" % arg)
eprint(line)
return False
return True
def _compile_line(self, command, args, line):
if (args := self._preprocess_args(args, line)) is None:
return None
if not self.type_checking(command, args, line):
return None
if not self._check_args(command, args, line):
return None
self.modify_stack(command, args)
args = [self.carg(arg) for arg in args]
try:
codegen_method = getattr(codegen, command)
except AttributeError:
eprint("error: missing command '%s' does not exist" % command)
eprint(line)
return None
return codegen_method(line, *args)
def carg(self, arg):
argname, is_param = arg
if is_param:
return "self.%s" % argname
if argname in self.rename_consts:
return self.rename_consts[argname]
return argname
def modify_stack(self, command, args):
type_list = command_desc[command]
assert len(type_list) == len(args)
for (expected_type, new_val), (argname, is_param) in \
zip(type_list, args):
if is_param:
assert not new_val
continue
# Now apply the new values to the stack
if new_val:
self.stack[argname] = expected_type
def compile(self, constants, aux):
self.constants = constants
code = ""
code += self._includes()
self.rename_consts = {}
if "constants" in aux:
for const_name, value in aux["constants"].items():
if "maps_to" not in value:
eprint("error: bad aux config '%s', missing maps_to" %
const_name)
return None
if const_name in feature_includes:
code += feature_includes[const_name]
mapped_type = value["maps_to"]
self.rename_consts[const_name] = mapped_type
code += "\n"
if (header := self._compile_header()) is None:
return None
code += header
code += \
r"""impl Circuit<bls12_381::Scalar> for %s {
fn synthesize<CS: ConstraintSystem<bls12_381::Scalar>>(
self,
cs: &mut CS,
) -> Result<(), SynthesisError> {
""" % to_initial_caps(self.name)
if (body := self._compile_body()) is None:
return None
code += body
code += "Ok(())\n"
code += " }\n"
code += "}\n"
return code
def process(contents, aux):
contents = clean(contents)
constants, segments = make_segments(contents)
if (constants := build_constants_table(constants)) is None:
return False
codes = []
for segment in segments:
if (contract := extract(segment)) is None:
return False
if (code := contract.compile(constants, aux)) is None:
return False
codes.append(code)
# Success! Output finished product.
[print(code) for code in codes]
return True
def main(argv):
if len(argv) != 3:
eprint("pism FILENAME AUX_FILENAME")
return -1
aux_filename = argv[2]
aux = json.loads(open(aux_filename).read())
src_filename = argv[1]
contents = open(src_filename).read()
if not process(contents, aux):
return -2
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))

20
old/preprocess.py Normal file
View File

@@ -0,0 +1,20 @@
import os.path
import sys
from jinja2 import Environment, FileSystemLoader, Template
def main(argv):
if len(argv) != 2:
print("error: missing arg", file=sys.stderr)
return -1
path = argv[1]
dirname, filename = os.path.dirname(path), os.path.basename(path)
env = Environment(loader = FileSystemLoader([dirname]))
template = env.get_template(filename)
print(template.render())
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))

5
old/run_mint.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash -x
python3 scripts/preprocess.py proofs/mint2.psm > /tmp/mint2.psm || exit $?
python3 scripts/compile.py --supervisor /tmp/mint2.psm --output mint.zcd || exit $?
cargo run --release --bin mint

4
old/run_mint_contract.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/bash -x
python scripts/preprocess.py proofs/mint.pism > /tmp/mint.pism
python scripts/pism.py /tmp/mint.pism proofs/mint.aux | rustfmt > src/mint_contract.rs
cargo run --release --bin mint

4
old/run_spend_contract.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/bash -x
python scripts/preprocess.py proofs/spend.pism > /tmp/spend.pism
python scripts/pism.py /tmp/spend.pism proofs/mint.aux | rustfmt > src/spend_contract.rs
cargo run --release --bin spend

92
proof/mint.pism Normal file
View File

@@ -0,0 +1,92 @@
# :set syntax=pism
# :source ../scripts/pism.vim
constant G_VCV FixedGenerator
constant G_VCR FixedGenerator
constant CRH_IVK BlakePersonalization
#constant JUBJUB_FR_CAPACITY BinarySize
#constant NOTE_COMMIT PedersenPersonalization
contract mint_contract
# Value commitment
param value U64
param asset_id Fr
param randomness_value Fr
param randomness_asset Fr
param serial Fr
param randomness_coin Fr
param public Point
start
# Witness input values
u64_as_binary_le value param:value
fr_as_binary_le asset_id param:asset_id
fr_as_binary_le randomness_value param:randomness_value
fr_as_binary_le randomness_asset param:randomness_asset
fr_as_binary_le serial param:serial
fr_as_binary_le randomness_coin param:randomness_coin
witness public param:public
assert_not_small_order public
# Make value commitment
# V = v * G_VCV + r * G_VCR
ec_mul_const vcv value G_VCV
ec_mul_const rcv randomness_value G_VCR
ec_add cv vcv rcv
# emit cv
emit_ec cv
# Make asset_id commitment
# A = a * G_VCV + r_a * G_VCR
ec_mul_const vca asset_id G_VCV
ec_mul_const rca randomness_asset G_VCR
ec_add ca vca rca
# emit ca
emit_ec ca
# Make the coin
# C = Hash(public_key, value, asset_id, serial, randomness_coin)
# Build the preimage to hash
alloc_binary preimage
# public_key
ec_repr repr_public public
binary_extend preimage repr_public
# value
binary_extend preimage value
# Fr values are 252 bits so we need to pad it with extra 0s
# to match the Rust values which are 256 bits
{% macro binary_put_fr(binary, var) -%}
binary_extend {{ binary }} {{ var }}
{% for n in range(4) %}
alloc_const_bit zero_bit false
binary_push {{ binary }} zero_bit
{% endfor %}
{%- endmacro %}
# serial
{{ binary_put_fr("preimage", "serial") }}
# randomness_coin
{{ binary_put_fr("preimage", "randomness_coin") }}
# asset_id
{{ binary_put_fr("preimage", "asset_id") }}
# Public key: SubgroupPoint = 256 bits
# Value: u64 = 64 bits
# AssetID: Fr = 252 + 4 bits padding
# Serial: Fr = 252 + 4 bits padding
# Randomness coin Fr = 252 + 4 bits padding
# TOTAL: 1088 bits for preimage
static_assert_binary_size preimage 1088
blake2s coin preimage CRH_IVK
emit_binary coin
end

158
proof/spend.pism Normal file
View File

@@ -0,0 +1,158 @@
constant G_VCV FixedGenerator
constant G_VCR FixedGenerator
constant G_SPEND FixedGenerator
constant PRF_NF BlakePersonalization
constant CRH_IVK BlakePersonalization
constant NOTE_COMMIT PedersenPersonalization
{% for i in range(32) %}
constant MERKLE_{{ i }} PedersenPersonalization
{% endfor %}
contract spend_contract
# Value commitment
param value U64
param asset_id Fr
param randomness_value Fr
param randomness_asset Fr
param serial Fr
param randomness_coin Fr
param secret Fr
param signature_secret Fr
{% for i in range(32) %}
param branch_{{ i }} Scalar
param is_right_{{ i }} Bool
{% endfor %}
start
# Witness input values
u64_as_binary_le value param:value
fr_as_binary_le asset_id param:asset_id
fr_as_binary_le randomness_value param:randomness_value
fr_as_binary_le randomness_asset param:randomness_asset
# Make value commitment
# V = v * G_VCV + r * G_VCR
ec_mul_const vcv value G_VCV
ec_mul_const rcv randomness_value G_VCR
ec_add cv vcv rcv
# emit cv
emit_ec cv
# Make asset_id commitment
# A = a * G_VCV + r * G_VCR
ec_mul_const vca asset_id G_VCV
ec_mul_const rca randomness_asset G_VCR
ec_add ca vca rca
# emit ca
emit_ec ca
# Make the nullifier
# N = Hash(secret, serial)
fr_as_binary_le serial param:serial
fr_as_binary_le secret param:secret
alloc_binary nf_preimage
# Fr values are 252 bits so we need to pad it with extra 0s
# to match the Rust values which are 256 bits
{% macro binary_put_fr(binary, var) -%}
binary_extend {{ binary }} {{ var }}
{% for n in range(4) %}
alloc_const_bit zero_bit false
binary_push {{ binary }} zero_bit
{% endfor %}
{%- endmacro %}
# secret
binary_clone secret2 secret
{{ binary_put_fr("nf_preimage", "secret2") }}
# serial
binary_clone serial2 serial
{{ binary_put_fr("nf_preimage", "serial2") }}
# Secret: Fr = 252 + 4 bits padding
# Serial: Fr = 252 + 4 bits padding
# TOTAL: 512 bits for preimage
static_assert_binary_size nf_preimage 512
blake2s nf nf_preimage PRF_NF
emit_binary nf
# Derive the public key
# P = secret * G
ec_mul_const public secret G_SPEND
# Make the coin (same as mint contract)
# C = Hash(public_key, value, asset_id, serial, randomness_coin)
fr_as_binary_le randomness_coin param:randomness_coin
# Build the preimage to hash
alloc_binary preimage
# public_key
ec_repr repr_public public
binary_extend preimage repr_public
# value
binary_extend preimage value
# serial
{{ binary_put_fr("preimage", "serial") }}
# randomness_coin
{{ binary_put_fr("preimage", "randomness_coin") }}
# asset_id
{{ binary_put_fr("preimage", "asset_id") }}
# Public key: SubgroupPoint = 256 bits
# Value: u64 = 64 bits
# AssetID: Fr = 252 + 4 bits padding
# Serial: Fr = 252 + 4 bits padding
# Randomness coin Fr = 252 + 4 bits padding
# TOTAL: 1088 bits for preimage
static_assert_binary_size preimage 1088
blake2s coin preimage CRH_IVK
# Debug stuff. Normally we don't reveal the coin in the spend proof.
#binary_clone coin2 coin
#emit_binary coin2
# coin_commit = PedersenHash(coin)
pedersen_hash cm coin NOTE_COMMIT
# left = coin_commit.u
ec_get_u current cm
# Our merkle tree has a height of 32
{% for i in range(32) %}
# left = current
# right = branch[{{ i }}]
alloc_scalar branch param:branch_{{ i }}
# is_right = is_right[{{ i }}]
alloc_bit is_right param:is_right_{{ i }}
# reverse(a, b, condition) = if condition (b, a) else (a, b)
conditionally_reverse left right current branch is_right
# coin_commit = PedersenHash(left || right)
scalar_as_binary left left
scalar_as_binary right right
alloc_binary preimage
binary_extend preimage left
binary_extend preimage right
pedersen_hash cm preimage MERKLE_{{ i }}
# current = coin_commit.u
ec_get_u current cm
{% endfor %}
# Reveal the merkle root
emit_scalar current
# Emit the signature public key
fr_as_binary_le signature_secret param:signature_secret
ec_mul_const signature_public signature_secret G_SPEND
emit_ec signature_public
end

74
script/run_demo.sh Executable file
View File

@@ -0,0 +1,74 @@
#!/bin/bash
arg=$1
gatewayd_path="./target/release/gatewayd"
cashierd_path="./target/release/cashierd"
darkfid_path="./target/release/darkfid"
drk_path="./target/release/drk"
echo Running demo...
if [ "$arg" = "-d" ]; then
echo DEBUG MODE
gatewayd_path="./target/debug/gatewayd"
cashierd_path="./target/debug/cashierd"
darkfid_path="./target/debug/darkfid"
drk_path="./target/debug/drk"
fi
echo Open new tab and run:
echo " $ " $drk_path --help
trap cleanup SIGINT
function cleanup()
{
screen -X -S "gatewayd" quit
screen -X -S "cashierd" quit
screen -X -S "darkfid" quit
echo Exit demo...
}
# Start gateway daemon
screen -S "gatewayd" -dm "$gatewayd_path" -v
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start gateway daemon: $status"
exit $status
fi
# Start cashier daemon
screen -S "cashierd" -dm "$cashierd_path" -v
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start cashier daemon: $status"
exit $status
fi
# Start darkfi daemon
screen -S "darkfid" -dm "$darkfid_path" -v
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start darkfi daemon: $status"
exit $status
fi
# Exit with an error if it detects that either of the processes has exited.
# Otherwise it loops forever, waking up every 60 seconds
while sleep 60; do
ps aux |grep "gatewayd" |grep -q -v grep
PROCESS_1_STATUS=$?
ps aux |grep "cashierd" |grep -q -v grep
PROCESS_2_STATUS=$?
ps aux |grep "darkfid" |grep -q -v grep
PROCESS_3_STATUS=$?
if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 -o $PROCESS_3_STATUS -ne 0 ]; then
echo "One of the processes has already exited."
cleanup
exit 1
fi
done