mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-07 22:04:03 -05:00
made directory names singular
This commit is contained in:
10
example/config/cashierd.toml
Normal file
10
example/config/cashierd.toml
Normal 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"
|
||||
8
example/config/darkfid.toml
Normal file
8
example/config/darkfid.toml
Normal 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
2
example/config/drk.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
rpc_url = "http://127.0.0.1:8000"
|
||||
log_path = "/tmp/drk_cli.log"
|
||||
4
example/config/gatewayd.toml
Normal file
4
example/config/gatewayd.toml
Normal 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
791
example/halo2/Cargo.lock
generated
Normal 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
47
example/halo2/Cargo.toml
Normal 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
6
example/halo2/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Always use the --release flag otherwise it's too slow:
|
||||
|
||||
```
|
||||
cargo run --release --bin simple3
|
||||
```
|
||||
|
||||
73
example/halo2/src/bin/burn.rs
Normal file
73
example/halo2/src/bin/burn.rs
Normal 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(),
|
||||
];
|
||||
}
|
||||
439
example/halo2/src/bin/mint.rs
Normal file
439
example/halo2/src/bin/mint.rs
Normal 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(¶ms, &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(¶ms, &circuit).unwrap();
|
||||
let pk = plonk::keygen_pk(¶ms, 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());
|
||||
}
|
||||
298
example/halo2/src/bin/poseidon.rs
Normal file
298
example/halo2/src/bin/poseidon.rs
Normal 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(¶ms, &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(¶ms, &circuit).unwrap();
|
||||
let pk = plonk::keygen_pk(¶ms, 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());
|
||||
}
|
||||
130
example/halo2/src/bin/simple3.rs
Normal file
130
example/halo2/src/bin/simple3.rs
Normal 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(¶ms, &empty_circuit).expect("keygen_vk should not fail");
|
||||
let pk = keygen_pk(¶ms, 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(¶ms, &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(¶ms, 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());
|
||||
}
|
||||
|
||||
267
example/halo2/src/bin/simple4.rs
Normal file
267
example/halo2/src/bin/simple4.rs
Normal 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(¶ms, &empty_circuit).expect("keygen_vk should not fail");
|
||||
let pk = keygen_pk(¶ms, 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(¶ms, &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(¶ms, 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());
|
||||
}
|
||||
|
||||
16
example/halo2/src/circuit.rs
Normal file
16
example/halo2/src/circuit.rs
Normal 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
19
example/halo2/src/lib.rs
Normal 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
460
old/compile.py
Normal 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
40
old/mint.aux
Normal 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
528
old/pism.py
Normal 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
20
old/preprocess.py
Normal 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
5
old/run_mint.sh
Executable 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
4
old/run_mint_contract.sh
Executable 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
4
old/run_spend_contract.sh
Executable 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
92
proof/mint.pism
Normal 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
158
proof/spend.pism
Normal 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
74
script/run_demo.sh
Executable 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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user