Commit 4bf5547c authored by mdj33's avatar mdj33 Committed by vipwzw

update circuits

parent 45ec8646
...@@ -295,10 +295,11 @@ txFee=100000000 ...@@ -295,10 +295,11 @@ txFee=100000000
#私对私token转账,花费token(true)还是BTY(false), #私对私token转账,花费token(true)还是BTY(false),
tokenFee=false tokenFee=false
#curve H point #curve H point
pointHX="10190477835300927557649934238820360529458681672073866116232821892325659279502" pointHX="9252662952969393856711468743327022054484546162727338092576697495684140272191"
pointHY="7969140283216448215269095418467361784159407896899334866715345504515077887397" pointHY="8220002160263982499510761441032261960817037857915665984040705585999508400744"
#电路最大支持1024个叶子hash,10 level, 配置可以小于1024,但不能大于 #电路最大支持1024个叶子hash,10 level, 配置可以小于1024,但不能大于
maxTreeLeaves=1024 maxTreeLeaves=1024
hashSeed="seed"
[metrics] [metrics]
#是否使能发送metrics数据的发送 #是否使能发送metrics数据的发送
......
...@@ -12,6 +12,8 @@ require ( ...@@ -12,6 +12,8 @@ require (
github.com/bitly/go-simplejson v0.5.0 github.com/bitly/go-simplejson v0.5.0
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/btcsuite/btcd v0.22.0-beta github.com/btcsuite/btcd v0.22.0-beta
github.com/consensys/gnark v0.5.0
github.com/consensys/gnark-crypto v0.5.0
github.com/coreos/etcd v3.3.15+incompatible github.com/coreos/etcd v3.3.15+incompatible
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect
github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew v1.1.1
......
...@@ -9,7 +9,7 @@ OUT_DIR="${1}/$strapp" ...@@ -9,7 +9,7 @@ OUT_DIR="${1}/$strapp"
mkdir -p "${OUT_DIR}"/gnark mkdir -p "${OUT_DIR}"/gnark
# shellcheck disable=SC2086 # shellcheck disable=SC2086
cp ./build/* "${OUT_DIR}" cp ./build/* "${OUT_DIR}"
cp -r ./gnark/circuit "${OUT_DIR}"/gnark cp -r ./gnark/* "${OUT_DIR}"/gnark
OUT_TESTDIR="${1}/dapptest/$strapp" OUT_TESTDIR="${1}/dapptest/$strapp"
mkdir -p "${OUT_TESTDIR}" mkdir -p "${OUT_TESTDIR}"
......
#!/usr/bin/env bash #!/usr/bin/env bash
#1ks returner chain31 #1ks returner chain31
MIX_CLI1="docker exec ${NODE1} /root/chain33-cli " MIX_CLI31="docker exec ${NODE1} /root/chain33-cli "
#1jr authorize chain32 #1jr authorize chain32
MIX_CLI2="docker exec ${NODE2} /root/chain33-cli " MIX_CLI32="docker exec ${NODE2} /root/chain33-cli "
#1nl receiver chain30 #1nl receiver chain30
MIX_CLI3="docker exec ${NODE4} /root/chain33-cli " MIX_CLI30="docker exec ${NODE4} /root/chain33-cli "
xsedfix="" xsedfix=""
if [ "$(uname)" == "Darwin" ]; then if [ "$(uname)" == "Darwin" ]; then
...@@ -18,13 +18,13 @@ fi ...@@ -18,13 +18,13 @@ fi
function mix_set_wallet() { function mix_set_wallet() {
echo "=========== # mix set wallet =============" echo "=========== # mix set wallet ============="
#1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 #1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
mix_import_wallet "${MIX_CLI1}" "0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" "returner" mix_import_wallet "${MIX_CLI31}" "0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" "returner"
#1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR #1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR
mix_import_wallet "${MIX_CLI2}" "0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4" "authorizer" mix_import_wallet "${MIX_CLI32}" "0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4" "authorizer"
#1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k #1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k
mix_import_wallet "${MIX_CLI3}" "0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115" "receiver1" mix_import_wallet "${MIX_CLI30}" "0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115" "receiver1"
#1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs #1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs
mix_import_key "${MIX_CLI3}" "0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71" "receiver2" mix_import_key "${MIX_CLI30}" "0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71" "receiver2"
mix_enable_privacy mix_enable_privacy
...@@ -67,9 +67,9 @@ function mix_import_key() { ...@@ -67,9 +67,9 @@ function mix_import_key() {
} }
function mix_enable_privacy() { function mix_enable_privacy() {
${MIX_CLI1} mix wallet enable -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 ${MIX_CLI31} mix wallet enable -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
${MIX_CLI2} mix wallet enable -a 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR ${MIX_CLI32} mix wallet enable -a 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR
${MIX_CLI3} mix wallet enable -a "1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k,1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs" ${MIX_CLI30} mix wallet enable -a "1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k,1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
} }
function mix_transfer() { function mix_transfer() {
...@@ -87,66 +87,76 @@ function mix_transfer() { ...@@ -87,66 +87,76 @@ function mix_transfer() {
#receiver key config #receiver key config
#12q #12q
${CLI} send mix config register -r 6828502228622121242962846647254323777568535293334252387427096385571037136275 -e fd1383f79872c41d9af716e64f4a72653faff01858a58122d6a8480ae1eafb04 -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01 ${CLI} send mix config register -r 14248533008859289736671040497097112376729713980306862599828676705210740679404 -e fd1383f79872c41d9af716e64f4a72653faff01858a58122d6a8480ae1eafb04 -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01
#14k #14k
${CLI} send mix config register -r 19618555102674542426188842632653510836841656859537346801180550073357423415124 -e 001a01b0e39a4e06a6a0470a8436be3d6107ce7312d7c56d41fccb91ffa2031c -a 14KEKbYtKKQm4wMthSK9J4La4nAiidGozt -k CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944 ${CLI} send mix config register -r 15542837613302913931804198235633080071021890362349316969360913659116440971972 -e 001a01b0e39a4e06a6a0470a8436be3d6107ce7312d7c56d41fccb91ffa2031c -a 14KEKbYtKKQm4wMthSK9J4La4nAiidGozt -k CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944
##1ks ##1ks
${CLI} send mix config register -r 7922952968605110993699808851901993086405084846049488287958179300126299607225 -e 78e2dd2c33f9cd7a94b69962a164da935e91c3c7fef8cfbf810491a128ef396b -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b ${CLI} send mix config register -r 6803726063008093410366112941811416911449216219005125852762197815950128434240 -e 78e2dd2c33f9cd7a94b69962a164da935e91c3c7fef8cfbf810491a128ef396b -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b
#1jr #1jr
${CLI} send mix config register -r 15841547877266309152336489543198284578462047449743379483021378876113912204480 -e e5362c31a903cd5522c4b84c324f90e96851292194fdfb33a8a1244bf1bb9f13 -a 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR -k 0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4 ${CLI} send mix config register -r 11499201522891581270391851171638982479327681756562559547094861564688053581237 -e e5362c31a903cd5522c4b84c324f90e96851292194fdfb33a8a1244bf1bb9f13 -a 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR -k 0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4
#1nl #1nl
${CLI} send mix config register -r 1499328046806813717988379826525346013601394010052157072491414645500411978017 -e 0abaa15456580365b90f84f22186f99250f4198f8df7319bcced1606085a1e01 -a 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -k 0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115 ${CLI} send mix config register -r 20573898766049640519279377248992057483378639946007599793634981932019201439513 -e 0abaa15456580365b90f84f22186f99250f4198f8df7319bcced1606085a1e01 -a 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -k 0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115
#1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs
${CLI} send mix config register -r 7166643181671374870524536201432214798965258692016821447324045928745450625215 -e a97592e700eb0f87c5738b35c8d460ce33a4a59bde6128081ddd042c3c262f76 -a 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs -k 0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71 ${CLI} send mix config register -r 16664447758440542061402448540177654829488285379043162144052840929545481936061 -e a97592e700eb0f87c5738b35c8d460ce33a4a59bde6128081ddd042c3c262f76 -a 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs -k 0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71
##config deposit circuit vk ##config deposit circuit vk
${CLI} send mix config vk -c 0 -z 1f8b08000000000000ff6c51795053eb15ff4e7281e0f086f5098ff7221114509692581441b4611111c160559055960b449280240842adb22b8bb2094a0551912aa853d08a452bd2a9a0b6022e55c74e519246a86804b57a04f47612c4ce74fad76fbeb3fc96efb0f509db97c96303186da533c449bbc5b2e4207a3730f90428007f600a09b00204c0946b910f4c2501235166bc449c10284bcf54c881a923842c640ad8006c9a2f98dd0096af1b30c50458be7c2d12e2c814b10158f4725d990d2c1f3760f61360f9f0bfa2408b84f09812dda060b60c2ca11b30a5045842be1609b1640e008081bf8496d23285aea70f1c4268a68c0de025576464262878b9bc8038a9342e844ee6c5cb04eecb5d0304c2a424b18cf6e2f9d112c5ff69f0f6cca604cedc2630070970e6c6b52f421631156c00cedc926e840510ae730bdb66330898436c00ee372b41bcc8e8af62fcff8a5512008020606a0921364c0d0bc0e47fe7b44d60aab5ba553add6ff5ea39ddd2595dedd7cc670eb3003891d17245865896acbd0d1811f285b261f2b55a141e0cb7b2cb5650edb824f244cad4c47a677cb79d9f3af5278f179fceaa06a59e13a140a1e16052f395a5279fe3dd5daf4b7c827f27c3965a8db9c42a568956cd1569b6966b34444bd656dd347cc6e1d5396c7655c9f5e679b762a85bf4d63b6dc6e3683e154f697e9d900d14662bd4cea71f769860daaf9e29ad7e5f4630708c2ffca3dbeb22341067b4bee93adfaa63fbebd588fb6b3f0812b1d1f042e1b5d6e66348d78f979ab3252a5cb8e831a97d193108149aced4bdfbe866f102b3cb9c573f3cd583b8c0a37d6fe391ad13e8c0bd292de84bc9224417f556fb83f4bb9ad17eec513f393a62b7f11e5e0d77e106e7d4cbd1f17ec1314596e21250382a6ee82e81db3cac1cbc6c5a6716f21794e839af0f2e6fb1409e1337356a91c24ce76e68ec3d377d7fad06472a2e5dfce870d1057d068523aedce275e812c95bb7e2674da78142faec8cc3631bcb30dc6cd9dd417ff75a0f9b2637ab0d0a6346d15594f45e31fac3351d5b8da5bd5cffb6d20377da08e61936c4b6a1cf1249596e8c4883662182ebde669272a030e7173762854fcda3d1652235ae6fbbe9306a869e4e9e3c7a60086d565c7137aec997135d58a030f183e9b0d71beb1cecf922d967b7ab780d3a58efda1059ff3210ad8397b9de342fb5060a6704ab948eaa497d0c88c813559e18106268cdcec20df6515de894f1a863ba6b8385cedf49ae6f9b5e627704ae2e6f5c5d3becf80a237f7c78e08972b0131dbb970ac63a0b95406191c86ba86ce6ed760c1f8ebfdc1013b516190ff5a6b0c6f43cfcf1d6b9e9c8a74577bfdec23fe2efe53e71337fc347ead1fec495ce6a9ceaeb332eff94db8c40e7b6557f1fa7010a8befddf68f3d7e5c8d92dc54e9ab8190f14ff9675c3ae6cb5468ec6eb0addbfe70b3cedc33bf7962cde26732c4d223e951c6b41c43db1bc2e78ff45aa1f9be36eaf829f942a0d07695fab9881e2358909fd56568726112853baa944dde45ada8d7f253dbb48745b6eef3d840e1991ddd4e752bfb3568edf95b16e768423dfee374f89e9ea43f44a3b5eb0d5159c9f81aa0f09893af2ad33d7b0be6d8d92efba567340f6d9a0ff5f23a1d2b70e96f060aa5fd7f5611a03086ebfc990afcc11e1f74da5e36ce085a8e575b8cab07bd5bab90ea0a335ac0242502856f72345b64de03121c7bffd387fb862987f19fcec985574e4def442b2b7dffe755c9095ab225bd597eff3a58a1c4c5df63a8a9e7f528d43f62ee961a96e887862396df755c3b6f0714f2df0e0cfb35f956a388256ffdf9b0751ef6ee55e9494d3e37a1e59de97fc38bde294280cd094953d0ebe2e429fa42695aa64cc1d918e21f1b16b8c99ffc270000ffff603a413108060000 -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01 ${CLI} send mix config vk -c 0 -z 11d72c948d3d6b88a49d99b55ac035875fbecc3654a0e275bb731b2da3acb94610bdc3e5aea2738b230cac2988e1290cd711f9170808e1c8eee0b4d1682c663825c8f7d853ca655f502524091ce0a48e7229f05df8e40bd31839ba19ef9ea3b81d5d15428b59e5c1b523917a989c189a2b9ed799cb18318160b47829868138cb2b49730f693a497e022a14344374410004ed29ab3333a2c4ff5a63d486d841210969ea406d44fc0af8f5a3ded0fe76f9a90c6c42c518e3725d07f91c0bcda1330982f9732d7a542b11ef8c90c2bb39d9f85f8bc240c2bea852d4dda3961be1e22a33bf4a7120e37df97c58aa10ac88fc365f156bffad5f0709615a0389b6542401689987d98818e7c0c55ca092ae21dd9895a5baba579a68bac5807e4f37677e128265980bf81da9622334495acd490d986068d12a148ec26f6b16d74e22f19d2ac20e521154c443fe93dba26c2b1cb6c8fa2533b8029ba28c168b80398b2a980268c89af9b92ed851e5cb18f1a688ce8d654b7db547c6753516776e6a16662c14ef921c2f016514a09a2265112b8f24da3267828793c9e37a5fa156dd3f5e8b279ac92cb2f35e64e2620def2c45b51503ee4552a1da0cfb055711efc08d89fe0e3a407989f7b14a8b0353a5ca8907be1d2551b2c085b2104e3afba15e30ad0d0527b06bd267ab6dffdc80b5ba6ff86adfb8c3f87e48a4ab3ba46de238e400ca1c7f4a396c30d31b20c756a1789213657c0fff66d7e7f8b1a3ec9728a1aada9622b0c732c615c9c78322da5da67ab6861ee30eaba4b0103c956265310e743f65000000031b3e8a8ac3b0ff4f009474b7dfb2e99e8c1368440219b8418351d2de4ec193c61b8fad37c1d5028da1e6a6b67e2c6858868710598175f4c6c07850d5e8ab53c120380af328d225d79a6ad6a716b7421de1b6f26793683fb83fae14ab6858486d062af23453da53472221872353ae3ac2900f711ab285de1cd9562eed856333c425767d1fb4797b1a64836d343541193cbfcc0e748fbb8a8b2f315505927c20fe1a87bc97b5f5d4e61216b061f2daa0703510a9813d253f710d73ad862c916603 -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01
##config withdraw vk ##config withdraw vk
${CLI} send mix config vk -c 1 -z 1f8b08000000000000ff6c51795093671a7f9fe4230d1a15224705c508b845442520ba8a42498c8051ea8180656345fc20c190484850504428208756a11e8834d80d663d285854c6455d0705d68a2e5a0b54915a8ecaacb25e94f5316abf9d2f48776667fffacdfb1cbfe37db83cc29532d95c004114ad5325a4ab3489723a1d981c0214800c985c029c503f60f6b02806663f01c14ac346b52a3e5cb3c5a04f05e61021641af33917804b8bfd46368023f505269f00472a6691102f268f0bc0a1e759cb5ce0487c812920c09188dfa31f8b848898ddd641bf913270427c812922c00911b34888335308001fc8d47432add15b7b3ce0134233c55c80c054bdce10af176d1785c62527c745d089a28d1abf8079b343fd421212541a3a50b48456ebff4f4394399212f8a39bc07c41803f3acebe08f164f67201f8a34bd6110e408cd52dac1bc9e0c7ece3024cf9dd8a5c14ab782f26feafd87e02002007e60021642af32507c0ee7fe7d82630a5ac6e8955f7f77ae9a86ed1882efb354ecc410e003f5691aad7a93489ec6d4040c86fd44f4c0eab45e12187da976e973aabd1609719e9bd7e7e3d862b266ccefdb2d88cfc6de6575b87172c060ac34f788ea76ebcedc42237fb17e3e70e34a278d1bf1fdbbb19fa519074fc68439a5d1661d9d28f4df0ba1a552cc54f7f21394be53307f06ceef449bb1206f720e772e3b46a557713507876f79a28a540198ccf85fab4825f2c4d981677fd9213d40a10247f9d27b3bd61b4b2694f9676c6ce9afa161d25f2e3073687ea50d6973fe540a47e2c728dd75fb6bdae3c0714ba24a698e65d72e8c4ccaf5fa65efea7b01ee70cb62462c87205daad9924fb3ee0761c21d6ac70abac3f68da15231e98fb8af9a02ce52b6c444515efeefa4014c6dd7c9066bce00d143eb333276f2bfabc0a677a78fd1679adfa28ba1b5f4b2ddf9fea43f76f331774a9fc5badeedcae79d5dc0af639843faa4b9eb53ff97339da563de9d1b41e7b8393d3164dfe35d04309140e2b3cebb76524987068e87a073743f402a34abe49bc27a91122372b5aeb5f3cff9d956da7474f53cd3a37172c684f1faea14d6d98a48a5c1814ebf00edd9cb5a6e045d93380c287cbd5bb453b3e2c45bed3706d94a3d20605ce6dd2b1376c2ea27df4acd28e6bfb7389352c50e871bf3da95aba54820de3a06d7b952909a7381dc1757fea35a1f041c599b13d55dd40e1969b8e3197fed1558bd5852edc85e27d0c1e3978b5f2c7ae9f3538ee62d8daa91794df8ca4ed79d46cd8d94e630bf793def696d077d81db9a94c360414baca2abd7c6c6eca81c2ee7ee17c5e5653d2eb8d2dde0ecbb29bf13196c2b0c7e06514cc0ce63fb5ef5efafe14eee54b66c2ed53c518b48a1fb3baf3b010b38e7ee178e77a4a310a9f0c99ff55b8b50428347977f9da3fec50e2e0ca079399882b9e287e53985ef807d88b3e675f1dd605ae1bb29ab33c13edd207ac7d81d3eb6225b6b5eeade86df9587238758c33dafa9bfd1a88e318a05013b03eafa2313319d396f795df3b33e482cb368d3fd6d27bad1f79572ed43f4affa1cefa79364061c8dc5d374c4f7136fec55c10b63d6222852736c4d9449b3df27186d673d58c0fd36380c2f3f93d2b94ab3e6d47c71503b67b8dcdcdf89d7c41fc361551e19c57cfa77f3b58ee4180c28a8b6a1f4d59c30614a5c406145df13e81cb02b79e74ceddf8314e38b628eaa974ee65a0509193974bf6fdfd34bafb6484259794203eef73b50bf85b5617f2440e5bca3c17b4b0643ba3e7f7d59f32f2b06671ac4b6f6b228d3fc4db6cb8630a32be1e0abb5fd7f2f82e5018e3ab769a762e7c32f29ad6dece769e65c2ca239b732c735a0770a2daa971c9cae1cf582ef9f99f024e3f6d4841b3ff8a3da136a78370383bbfeeeeb984669c7ae6966bc67dea3950b87052de573513f30ee2d8f57f7cd46e5155e28e3bf11f7df7ab220067b7f576081a62642c595271d29c299d05fe7877cf47e1272dd96538e6ade55447c5bd12e49bfb5de5c7f75d050a076e693216ef1808c52eb7a28775c1272a5053effab25c7efe6be4bf7998f1b3cfde0984800d2f24596bd0e8f99f44c83e8b0e5f2d1344ea687ab556ab0f8b4b550a430c7aa556a7caa0d76ca1359bd8d2b808835aad4a50d13af645fe130000ffff37a667a7c7060000 -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01 ${CLI} send mix config vk -c 1 -z 17497f382733020c2441ee2179d468e4a871353ecf52e7bc7f57600703e6cd0417c8a91b86c1e6e55316bd1ba88db8c817b646add9c5289497faf705e2e0a50510a31a9fbbcbec3399e15f1caea1e372a51827e08335606f7f1a9428539e4a3025ea43142772f0300fcb6e2e03057be5deebbc7e00cad1019da0452c2ab90d582caa5e4c22103eadf15f5ded717187934e4e9a44997766d6a770c42ff520e00d1d5a65abd94ac973cfb60d07499505d4db9584ccb428041336610d422a6d203007171dc5d586c536b3f49c2daf4d3b0a095a67ea759b49f182c87b41ac03848722b838c495beb5537c43fa7175bc5346743a2eb620856d0daa92614f283027ae2aff76e2a53c74648f52d9bd65ccf3064f2b9d9230e45bdaaa2214aa593d90180e85e2e045eac57a2b2b86d3eb23215bdc6b8b0ecb80e37374d41e1f7101acb502a75d203e2e058258f53f8c58192c8f0849a67a5ab5c7d26d782e4e1a10669c03285a2eae35d76a09c20841c49e72e7d7896da7a788d146836d5ba60bd2981b0eeabf8ee62fd2406056b556db292d18cbda9bcbe008791cb96fcb17ca6a33b0090652012ee82cce78f6ba28fe807cd3f668ba1fbdf795002d5ca1335a5de65307936b649d057637f8ff815d86aef66fc49960d02a8244cbd64658bc5758ee2a271e7a651fd9ef47bd7683c5457c724365c4a49e5e4ab88c980e33292ca1467c1e4b36114f7ed29b48bc2cf422be5c8ca374647971eb7daa1016348546190a762cc190a0d413e00c81f098a84e880bb53024be29917ebba4a55d59c40a606c0d0000000519dd32ea5a02431cbd4c38143012542385d9085b4c5d0b4f176285feae96d232061ed041ec53ee1897dc1eb82f1456bcb939b7512fe60548c97873bc602606c91f1d2dea1819016ef4bf1f1f3a6e074f04f04117d0628375f15779bc612078a302aa853d4d2e348cf05422efffd585fea5826ae63770b35be4ba8087092cf5150560d8d5e21d5b60413658c69f52d0ab2b399490f7e572ad8612a08472721ceb107ffe99a3a4de489fa4849a63eb5a574ddac2ccf7afe89c06c77c43a94e4d4b1c1250247c5352bd7b34dcd075f52cb31c5f4c96ba3120355a3dc010d330c4e02707c707d9cc3772ce61f7ff8bbd50d2633453a21d10edf821ceea93ba205bee2955c296632546fffbbdfdeea2f1aa67a9b1a90903ea12a3818d5e44f9964a6109afe1cbce7b5bccdf71718f22a3d57f6afd1a7976a75c093410520cf79bebf8 -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01
#transferInput #transferInput
${CLI} send mix config vk -c 2 -z 1f8b08000000000000ff6c51795094f719febddf7ee062b8e4f640562428f7ee1a560a465960478e46b985414281fdc0b5bb0bc26ee5d288241c2208180e2347b6296245a64504ac442523a0099682065302040c686c4982e3487c41c3d7d945d369277f3df35ecff3bcefcbd1271c7f369f036018cd64c852b265cad410261bd8e304680009b0ef13a0760b813da94501b015040c43d54972597290325dadca04b68610b2892de000701881706502287f3eb08504287f811609d9ca7ec001a018912ecd01ca8f0f6c3101ca4ff00a855a2484c716e91a852b69a0c47c604f10a0c4022d1262cd9600c02a899c51304a95aea60f5c4218b69403e093a9ca5027ab78b9bcdd890a45e21e269597a4147a8adc770bc529293225e3c30b60e4aa5f29f08eac6c09dcd793c09613e0be6ed7468438b0651c00eeeb215d0b0510a3730bb12b3b08d9531c00db5fac84f0e2e25f8909fe2b564100004280fd901062c79ea6004cffbf4f5b04b64aab5ba9d3fd255ff55af7c48aaef634566c3505c08d8bcf5465c894a9dadf802121cb7a62f6b8568bc6cac84e72d8d7c1100bfe309c2ee8cbe94597e6f5c3e7caae25a39e32f0eea4f95c0ed09816ece275ade05613debbb9ef54988f9f27faadda35bcaefd6fb1e83aedeca0e96cd844b46cf571d7e9c8fb75df61dd4e1127d83bcb14f916f94349cd9b846816cd17142f58bf0d34e696ad4d5faa94001ed5dc37b9df965a86d529e78a3fbcfc532752ecaaa68d4cf8bc8ead5d3269492eb63dc586cc99566e5b8b0053138b4ea917251de8a609490cb09d6d001a373ca63aff92e7648be6f6eeb6c5212a1106bf1c0c9bc936f7c6ad0e751f6b465c3611a2dbf52d4944686bd0800ddaff66bcb1fb8864022f5e32e96f3bf6b610ad0d367b3e7bee5606347e1569ac3ef30f511eeeb6886ebc3f505b8b8207a331f94d776671cb0475f2d865fb429d3b7e7790666de0d7755812fef3fa86e59e5bf8385aa22a7f366f836b7bff9eaefa486c05347eacf9f1bd1fde31f0c1aefded337bf3a20bb1e1d9a453c56c54079aeb7dd1fa3272728b8e4ddaf2469165666d15362d5d22d2bfce2e6342cebaed1bf517a6d1defb9122a0a6d418683c7f63cdadae3c173d9ca97b5eec51eee1825bbc7071b6a360075aba7ec41f979d6f22ba65814683a100f34f9f04f071aed5d3e4d09f2cabd122fd7c5d99db9326745724d84b34c41068ec1c9bf824bdbba719377e5e98f3a6dde40c565ebfc6bbf47cd40b3788120cb2bf3d5eaff3b7c1ef0dcde3de417d745f476647f44ac7f0c08dc3ad67be3f1a83a68315366eb6cfe781c69a2e876db969a54fd1542fb8e8ca255725064f1fea6b8c588e42d758a387ff1a8a3bf1ea1709fca5b36bbc3fa170f44a7bf2a091340b574dee28352c178fa3435b63ffbf576fcf021a372f4e8d1d546d35462fe1d4f0f268e075742e1c387f74756809ba4962c6db2f58b9e9dc39bbfdde4c11181a8ed641b519c71f2a9df19f7da3dfdc89347642ab2f4ef531bc933f038dcbd44de983390583e88c094355dd11c8ebc95699543d152fda4bdfd30c247da73b9e3ed02809bb7076ff8b7777608fcdd5a6b8dcac293cfce54fd1738ee7a4689a75c378a444d405346eeba8f15ef8e6c513c42de50aabe435bea8f0ffb4aa6e61fa07740c6fbd6bddf8e202d1fef6ec1133618bef34b2ef7efdd03dde7a1fcebe1c0eedff716d041a4decb01dddd9a6061a9b0f7e7efb50dcf745e82c3710bf53536d8905328f9cab1b175bd02c28d2dbf1ca114f2dd9e9c22b8525b96388be0e6dc551f2450a635dfd3d8e2eff3913dfccdadc9cd41f2e071a7d77e10839abf900172e48fdb685ea01aee9bbbccb8e6ffc00cd8cc20e77357e36a625f38d5126877c16df87dbefd5fb3e9ddf1f8f7315ebc3c6a8b776a2e5c52e6e4efecd28a071e08e53f5d6f75336a3d18407f9ed6d5530762ea7bde8f569ff1dda3aeeed9f0a989768c92af3ef74b46696e461ccb586afba3841625cba77d5d6f76eef335c6f213ebded61f53da0d1875d34aa1eb4fc2376a688ef0acce4223c936623da3fbfaf1e9df463d8c85d5ffa6bc91c9a1ccbea6b8fbd4461d041de54d4a312dca9b1700b6ca9bf8d56715eab279c045e4063ecb9785e614f97230e8ddb3c3ad6e7bc84b78ab98b76d3d5ddb8dacea434ece4b7238480be616406c384a7a5a90213330f70f7ee9124ec0b0a979889d5aa036919b21c26229d514ab535a33d6ab95c962263327451c4011923978a15696aa52ae67fa258f29f000000ffff7fdd3e0e2a070000 -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01 ${CLI} send mix config vk -c 2 -z 153cd9b6c5bd77f41c63012def12cfa719cedbbb7c376353ada8865bd9d386a22ebdbbd1da14114ff44d1ffd49d3a1f108a6affd4614c9c519fc84425bec6293145cb2f2e7c8945ed7e9a7a7ef02c1555bb0886e7c15a8be254cbab1adbbe33919b40f19c82819808f1f87ac6ae96657a60ff37557ec55e73043f51a3ae17ade00973ce23495e3dc7941b468ff0e9b9b0ae73d722fc5401983a8def9f48ab76020b317cf6ccbc216c4a20210c34e061b2d3f74e8a1645b8be4b7ff073abdb22923d6b82003695d70bf025442860d9979f4b547569d1c79bcb36bd85498d66969304a7edfa12d4ef559b07b93834024f424cc73d115e231d31c0489d22a19403321583c42261bb161b3566c574c42bfc80ef00bb5890e40b90ef3361eadb38f181144271f45c753afda2f81bdd2868e1adb7b2519d2f75ddb05e7fe7250a2bfc00beb6540deba4e021b1edc5d0c5e08015674d5db33c591714297acf1f02c35af1069621ead725fc0527099915ea5de69282cb9850de96495e86b61670f9146b411a9ea9a4df35af15a333495475ddd34df53692471d09e7fbc337471829f64d203a199091300223531a0298b17ad923c29f8982b32862b1c091d970f9b5cc9ef23a7761a669a5dd9d631424ea8879b89b22afcee997fc6ab95cdf9dc9baac6461c1bc5f5736b339568767e9ccab43e63dbfbd3f3a94f1100f566fa5f72029b701fda13678ff8db802156bce08bcc2ededa2914ac45d4be6d459abd612fbdd77718874dcb119724bcd71c8de5e10f7c79f4b66434f8b9a1e2a174d92cb10b1ca70000000628e6eaab99088247e8106f52f47b5940f3c5294d2283006bf3c29532c59a4c5a0e931758722334e0299af3b6cb36e9457fcac0bcd5440d80355babd3c05e88211e1e7f5bcdc4863afa2d49c743652305f971c92920c0bb61e76a1bb51f08156303ac2e2f58c0a6f2627b820ff08f0cedbbbfd99fa840b79de57e0f6ebf5969ce2efddfb68b6c57535a6be061335009ea879087b15def360546c5f1a4b0f737bf0d785f07ada66b23c6a037ce372994fd072a97c16d74c513f63e987217ec8dc210cbcb5c6dd8ffe745a63e88470fc09cade0ef877c4f107c08070fa19674618813e5be4d5db40af84bd83db80fccadee83af1549c92f4c935256bd5dd68b97f32e8dff5346fb5fa554c9ce617774c2a43cd7b6c5d5edbc9cd0dce0ba74b5ec87043b59f5b19c20057780c99db499d2565bc9f90c252f27cc37b2f5c9c69f504c13357153d572be7823f67ca794ca52088e20396eb7bef837109f542041fdd56310c5bd398cbfa8e588fd8342cbd103f58249481f5af3eac33f15add8fe4a64e4 -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01
#transferOutput #transferOutput
${CLI} send mix config vk -c 3 -z 1f8b08000000000000ff6c53795454e715ffeecc0b8e040988a23058864a5482b53328102521308088a3ac1621c836f818a61d1ecb0c844541a7b2045904a284260a078f444243596493838c1288a2294903270d614969122ab40a81948b82afe70d929ef6e4afdf79f7bbf7b77cf77b7c03c2f760cff2018c82e964656cba9251c8e87460b50428002f60cf11e0793b005bc8a104d80b048cfc53e42a658c0f9398a251037b891062c3fe9e0fc0a7250eab13c0f310039b4b80e721e190905d6c0e1f80473be9cb7ce049c5c0e613e04925cfd1814342446c9ebed161b50c3c7731b0050478ee120e09d9c2be0d00ebbc54743ccd68f4670620208466cff3015cd49ae494188d2853e41d1d1f1fed4b2b4472c6c1d1698fb7837b6cac92a15d449eb44af33307a2d3ab2941b036096c3101c15a3bf745882d5bc40710ac0de95b7800217ab710ba9ac1812de1036cfbc98a4c1416fe5c4cf25fb10b04004006ec3b84106bb69c0760f2ff7ddc21b0659c6ea95ef7a77ad99a6ec1aa2e7735e6ec451e80202c5cad4956320a6e376044c833ea0cabe5b428cc1e32e9931d731bc1e8f69a3783852f4830e0d0b7bd864f978651b829585b5e3a970a147a4a07cf7e6db2f9d852d50b01994fbc5ad0283c5f7da275d74eb45eceed1d3dfa592ce1c80eb95eeef1fd68b005cfda66a5557db5f5204eb1b333c5eb3227d1a4cf79792afbc309a0f06ad7878bd7b5fc52d4dcaa341ccb7d7300ed5f0c7f6db0738f155a1fb9ffb7f3ae9e7c3d5bb733e3d77e7bab25ee91876e9835a8e842d9b714c3741ae6e146435327c946e90ea070cb97effdd163c2428ba637e79bcf141933b86f8f0b8ed9642ce03a4bc3bf4c1b4b5d09d147cd799dae8cf9ad360dab4ac2824e279c13e3173702986ab92a02ed6607747707dda780c2b611d76ee77d651fe0a507858af428c3719cb9af3b597d25418be656d2b9297e4795de1d3db1b2f489e30f5578bd2bd5398bd73e83a3a75c859fbf78b97a4935ad7b634bc04ea0f0ada39587beac693d85c6b5dec5af375fdb81eb3a7c73827f74bf8a42d9a2e88969b3a59eecdef62097818583a36855f7e7c6bd23bd973073a8492812bb45a2ddc31ebb8fe71aa380c2a6c3db4a22695b5b6477fbed10ffc26f04b50714babf3f7bd6b754712af495f503dc7fb5ba569f10cfc11941c16da42c99a9deac923b387981c4d6cb22929012decd9bd444ff06289c6a895c7ef9c4f84d6c4b69d6ceb7cd6f43a7b73bdb82c6ef4ad126a62bb1a9eda9a3de9e7d71cc6c606c9e19aecf49fef40d92cde2e2d4fbdf0cf61137848ea8df0972e728a050e1b92c504b5712b1fe56f3f6f3bb4b1dd1d03c57346eb5e93b14d6ce9d58aadf9cf87c13ce1989d6dfef77aac58be6f7884503dae0ca62a197b67f7d160a0b6f46c4fcdbfd63a0b0a7d65ef6d75f8319be97f528f6465d6214bafe68ffea44f9fb0b28e6ef7a6d20df40a477f781d9156974ead14034ae78e99decb4cf55e82f4dd8eed29cdc8d3b3514ed7df85a2550281e6d1b8ea971fa149ddefa83ddbfba775ec4efbf0e78a594b54dc7ad8e9bf66ed3768cea6f8f4b127278e19b3b293231be7be3001d3813dc827f6234f50ab7e3fe68feb872ce63afc12250f874e687be80e53b23f840e77940fe51ad31de9657e5adefb9178194e255fbe4e96133c2858d1aeadb600ad358f0a4b4a2bcb1fc1c1ec146d3c756712648edcef1696c481ae49eb1e53f7ed520955d47f13138d21ad51982d92bf2ab8f5fda2745934ff2d3268b0e0a38b2afc67cbe535d69fd0c8bc693fce3bb8eef4756b962735f571d861665a2eae18e876aeea1300ae3d4c6f964746cada93b5d7726035fde5d7e3963a4ff018ac5ed6e8c7af95d8eec9624d07a7e8ba80be9cea2450bbbb87e4c78d42f67473bcbd0dcf461eac6cd5f3c020a278dcc06c61449bd38d4f04ff1c952b9057685ebaef935a995f8cb9ac8fdbdba8c01428012f8f97a451ef709f4da1014a7a45527dde31352184d88c03741431f8a56c7fd4f3994fc270000ffff89296a6769060000 -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01 ${CLI} send mix config vk -c 3 -z 13934cfcc6ff87d92bd9bf14fc22abdda42ecfd544a0dd8b5b38d8936cb91f7d2ab93a5f2e54a2b09ae0f822be44bb304d2e8a3a9a2590e134cef4de7ca61e6222f85e2b09a87301942fa12d8755467ce88b30679f703b48a3ed973b526648c614058f734069dc99be9312b0f64b46dbfe8b5a1c7a7b2abd301417abe61cd7580f07fb23e6b6e998dbc16fa3f5e9d0489ec2867f496f79364628731c8a81159d26ba7de29f451d5b6128224f398ad7797a605b022f5a6de1b59276a339d88921218971e393ea6027f758ddffe692b11269b5ab17f72266661cc452b83f83a70818d7a37dabff75b1995952a63c45ef51695e18ce1b9b6bf0da5dbe3c9625ad090dd507dc37e610ea95e32f2109bd7ae0783484675a445cf396ca0653d4e3c71b27c0b8d2d3239ce11da02406913fbec4d973bb1ff1922a6d5d295581f635afc22cc1379afb9f5158d88baed9020b8d393f1c7157b30a36724d6efcf162fad84e20cd61fa92f99ef48a4ab4a0d93f91f06204addb1686344476605f2089defb561c4b0f8502b3dbe27395b86e8535fc4ca14c25c071880f8153e931194473b2d809dae5160125311328f69840cc36c0d68e3b135827f79076ec6cde7c94b607792485812b35437227068c0122eaa92ab9e181a7b6776b681d3c6d58d3a2d7e8462537bc06071d29fc3ec2e789d343359fd2adb5aa1e343033b6456cd9f9c9859120c39266d6032c2e4cd703c2ebaf1ed66edeaa95b8e9363190cb2e33b7c430ad2e7d9a9587ed281bf44e2305aa20c3e031ede1cfc40cfc600b09b45b0647cf1100000004269eb69c9017e0e3e8f2fefae3d2bf072ce5a9369b9dc4a949863a096b8c2fe70e53a7aaf51d02342549315f63b45527dbc1fc8b640b471337ea89ab78179c6305ba8d54c55ef56feb4623a09629f70164572993ac8ff3472753d643f325622220f4e4183a52903095d6989f5f3aaa18da0693d815e18eacab419e1306a492d42b1a34104b599e2c91e697969f4e47fb2305f5e0e587b1616c2cf53d4ac5ebba004710a9c23bfd6dfe3b0b4ce9b934fc6a6b2304640d56fc2ecdc20d37dbe352048691666bb7323b37f75cb2a3c078e05ee3d38ba666f33ee3c9cf9cbe2e1a901fcfbf411bdbf8b3e671579c29fe2da9b29cc1e99ab30801d8b9a1bd87c5cd8c -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01
#auth #auth
${CLI} send mix config vk -c 4 -z 1f8b08000000000000ff6c517b5493e7197f9fe403a2244a89c14b0563a5e014038905d6c2985c82040aa21525440a09fd80b41069122617071228144cc7451438a0a5038695035527a52d475bb9163a540e058a041d7a86b6bb7070b43e22f8ed24883b67677ffdce73fb5dde976d4dd8814c1e1b807b88d6aa1333d59aa4303a131803010a400a4c0101d65e093046338a812923c08d4c57a5a813649ab474bd0e98338490ad4c3e1b804d8b25cb17c00af400a690002b506c4642b6331fb00158b497a5cd06568007301f126005889fa3c48c84089922cba264b90d2c7f0f604a08b0fcc56624643d530c0036d2143a95d6e82d336be010423327d9003e3abd363d412fcc16ee55a6a62a23e824a14a23f1f412ed95f82726aa35b48f30884ed1ff9f81f0f7cb2981b37209cc1f087056d6cd1521cecc476c00ceca91658505106d710bf2e50c12a6940de0f8c24a985011fb5c4cfc5fb132020010064c2521640b738a0560f7bf7be621301566dd728bee8b7ec58a6ec9b2aef9691c98d32c008e2256a7d7aa3549e6bf012e21cf282363306b5118fb679b70c65eb006efb5ec7a6974d5e4437c1297e8a7fec06a003746482f1a868cb5402137f2f6dcdfbc459fa3a05738683a55398c395b68b746db81dfe1b6f315aaa95fadca2466b63f5dea8e709705b7e398527cf17a505701cef86528ae66707fc2d5f762a90dc73aff0a1446554fe78d1e79f019ce04c4bf54f686751b86a4c7e617ebfb3dd1a9f88bc1463baf1c0b5bc30f616e63cefd3b51b4fb84d27d47ef26bcb5b150b42dc1251c9d4d8f96ee44178e01858ced46e6b45ed58b4c42ab5b50c3d231d40e70e4df45bdd68cbcfe62df94bb5f9f25c49255e9e7f115dcec13e0ccf0b3ace18e605f8c979d130ae6eab2d12935f4ec178ff9ae40e1c87b335622bfbe494c9edb961b3fbb781c3b568dcf1d715c47a395cef434c406ab2cee40341a2ff07b7301f97b0c9ddffa38aec3beede24cf8542b44a1c2747891e7c0070a5f6db3af1b7f1c33886bd639f27ed42aa5989bbbfbead933dddd08edfb474e464a7658d81cd67b7b8eb95251a8735e78ddb7f2181f8d8dce7db32f3ff91cb9b19d3155139e52a0b07fa75c7b0ba01303c603123e5c25edc656438bb0e13da72728c8f9aae469505632b184050a559afb4e891e833fe342fe081e9a14cc62c5eaf56151c5a79ee206eb7d2dbe46d525a0f0daab293e25312379d874f11f3fa97efee33738f17ebda9c6e43087ceffba7fc28be3df65f1576e54d72daeb59bc0f2b23d45f3c36bf93814b7f64cb04ea846d748aaa85c96310714264cb754c75c2efd357a15253797650f75e177792107bd3f698ec2cdaf7fefb6e1e1c7d9cfffc2295e21ae6fd26fc7da78d9a8e8b35db7f1df87834b9a7daf10dcc16efae54068da23a030c9aa612afc6a413de6fdd6d028dff04d16ceff5dee68eccdaa439e9b7da8c0b7966d71f7b2cb5d4dfec9f5ad989adc546d15a309c54db5edaec777f730b8e617dbe145d5e34ca0d0601b0a6bc2d2687c67a6a4a370e1c2252cf0fea72eeaae0720af27ffcb736e824396d7a380426dd6c0ce0677661ef7dd7cffa3d4a567720c1f9c3454664ef5a0b5c1d1e6c175f770a0b0be9fc9589db3b30d5f2b4b87894f67af63c638cfe85a937502d9d5a7fb5ca6276e10a070da46596ebdfffb3bf86eeb95e4a9c24d6bd121f42fbf91f9bcd2846e76fca984523a1828bc5daa38f8b6a2cb154bf7a5bc7bfee3a4b7f1789ef79dcd3d7b6f20e7c1919bbee73debcc64eeafd86ebd1c7dad035d3e71bc2ff48aa23174f78f6fd484b4c4a0dd46d3b74bf6f90e40e11679f38d1a7957048aee756cbe35f1e665346d2d75e7ebeb8690dd32aab810b62bd54c1677ae86efb43d7a1e9302d3f4171eb669b17d8f8b3da31a8bc6cd8955bcafdb3bae01854185dc7581c16f65e2123720e34bc9fe2bf8a8e307595b6f6e155a456eaa2fe7e74a08018ae79fae4f3eaa5567d1214a5db2fd8beaad345af38eb9c53da8a5e903478feacd05675f8434eeb0ec8094fc270000ffff6794568075060000 -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01 ${CLI} send mix config vk -c 4 -z 1473ab4328616752c00ea248309e10bce4b92e3fd4e3047e30747512821e24741a59bb2115d794d53e8a123b284f59acfccfe5fd76c87a4ee5cf72a24e415d52049eddd126746ca46f1a6b5151354844fba1cc136f56dc8d52ee087e77ee545a24793c266c6760371f66e3ddcbd2f50fdb40ebcd63327d0daeccace522636aa42525af4490cdbcba010d5d60b17b899a5d4ce32a4f028153d18ccb9b54108e35215fc55fa11835b75755f4b2e71af4787c7d8424c8fcde9b59d0283fa1a6596c287a8695a5c4fbe45979ba25930455fddeec304c1e0fe1d980730a262bd3c15a097ed012586cc746756ff350ba08c0f7e97b1e3368ad99d4b413419544a5ceea09b9dbb381264e8a786e9875c7fc9989ad119aa3a8e1b07f170dfc29b6603ac1245629f9260508d08747a7b8ddc2502be73cdc16e467d47df69aa71575d39119197ce70dbe1e1f1d8f1b45a3dddc63e6e236794fe08b42080e6746e8e22628f70d436597422407240ed94d46b32d0914451225dfeb64124f7215476148092e190010e75b4d11104f80c5259fda8778d6886fcbf789c48a13e21d7357eafd8a8308b0ae3dfcc341e715bdab7de49fb699330025da6060eb91b5a79cbe25e1cb3705f350c2d348ef3df4a6cccb11e68874fc8e75d617b3934a7c654c8c854f3752091291b80aa18de8fbd41b0ec39ebbd96ca685e6386da6cc204ae13a9184d18b044f26507b4b443e60e02162492364452a83246e9643adbd42e87316dc04382b29c76acfba7614956b9d9aed7e49be9258268e22adbba0aee818a3f8bc1c3bf40000000411f40834f563e79b2ffabc45c24797299ee34346888f34802b784b62427bd5d429f5117115d7162353b65557850a4a2f99e9834ca8ad95830ede631d897048521fabfd0dd4246c4d8e98062daf771ded13921619e76df0ae190ed0200757684e02ef7e138bf53134af024817312c725cc8a6617c8ecdd66d65e90576f59596c90358b4ce57d7b4832639096c4fc814fa067b3d4b11a4ba8626c543b26b68bac505c2ac761fb39a0b160010b4085dbe7ab2f4c940b96fa75fbcd0fefa6fbf12811e86674dd28531b9b264e6f098b91344df5755dd28a41696d1ffa878f5dd9ada0be976bdfcb9f5538df6dc9eee17babeeecaf3c93b4f317d189bb82cb0b7c264 -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01
} }
function mix_deposit() { function mix_deposit() {
proof="0e420e0a8963195ab7fc4a610d8cd758a04be4950317c1c0cdfff701e207d03c0f72b5c669058434b3db24ef57f9a0d9e443d78a3b661e1cd2a1f6c1cdbdb855081c95f92a68286a0aa4d17615f9e61ed073ecb9aa4cbb86feaf4007dc86de8f139e1ff01ff5a6ff5e46db1ede026243c47755cfc33c3dbe4f8871fc62322a3a230ffd865b7b5bfc0e99677877517f562245cdda012e28941b4bad8a25d5edb427152ca0948940a12f489aa259377b0eb0cd1f084faf4dd9ae08c43aba780a6a0245a3a5d13253523272bc7b82ed16ecbcfa94fce8f3033fcf863240134265b70e2ff0b31a35ce0c5d0cba7efb7a4ede29e884da05ee3ede095433c9bfd6fea5"
hash=$(${CLI} send mix deposit -m 1000000000 -p ./gnark/circuit/deposit/ -r 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -a 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR -f 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -e coins -s bty -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01) hash=$(${CLI} send mix deposit -m 1000000000 -p ./gnark/ -w "" -v true -t 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -a 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR -r 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -e coins -s bty -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01)
echo "${hash}" echo "${hash}"
query_tx "${CLI}" "${hash}" query_tx "${CLI}" "${hash}"
query_note "${MIX_CLI1}" 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 3 query_note "${MIX_CLI31}" 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 3
query_note "${MIX_CLI2}" 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR 3 query_note "${MIX_CLI32}" 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR 3
query_note "${MIX_CLI3}" 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k 3 query_note "${MIX_CLI30}" 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k 3
echo "auth" echo "auth"
authHash=$(${MIX_CLI2} mix wallet notes -a 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR -s 3 | jq -r ".notes[0].noteHash") authHash=$(${MIX_CLI32} mix wallet notes -a 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR -s 3 | jq -r ".notes[0].noteHash")
authKey=$(${MIX_CLI2} mix wallet notes -a 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR -s 3 | jq -r ".notes[0].secret.returnKey") authKey=$(${MIX_CLI32} mix wallet notes -a 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR -s 3 | jq -r ".notes[0].secret.returnKey")
echo "authHash=$authHash,authKey=$authKey" echo "authHash=$authHash,authKey=$authKey"
hash=$(${MIX_CLI2} send mix auth -n "$authHash" -a "$authKey" -p ./gnark/circuit/authorize/ -e coins -s bty -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01) proof="1c33f86a705d387a191d598cdf5a4d97d839e49013ec8b73fb265a62bafc03fc17e9b34a36c6f015f49d1e944c945ff16bc3c7b4886591578c780fa829f140560fea4be7ddf3a98a5a620010f7a210456158e3f20b88a5a120980c8b960d15fb1c50a4d93b78c3cb3bc729152e1cd0b1574b3cc63a4ce6fb5f8e51828320df861d70f529eab34712c213a605dda2f05eda7fc4b0aefc99adb2817eb10548489d12591f64709a5ad3dd32a1ebfcdb70c50288af1185b4fa3e9a25636b9cc9df0c22880ab3541018fa25a9fb232ed4dd47e0aa92de0c4ee2f0fab57fe95df096fc01fc054d1331088bb57efd36df79ab36686df37dcb9284943d2047df96bd7635"
rawData=$(${MIX_CLI32} mix auth -n "$authHash" -a "$authKey" -p ./gnark/ -w "" -v true -e coins -s bty)
signData=$(${CLI} wallet sign -d $rawData -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01)
hash=$(${CLI} wallet send -d "$signData")
echo "${hash}" echo "${hash}"
query_tx "${MIX_CLI2}" "${hash}" query_tx "${CLI}" "${hash}"
query_note "${MIX_CLI1}" 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 1 query_note "${MIX_CLI31}" 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 1
echo "transfer to 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k" echo "transfer to 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
transHash=$(${MIX_CLI1} mix wallet notes -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -s 1 | jq -r ".notes[0].noteHash") transHash=$(${MIX_CLI31} mix wallet notes -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -s 1 | jq -r ".notes[0].noteHash")
hash=$(${MIX_CLI1} send mix transfer -m 600000000 -n "$transHash" -t 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -i ./gnark/circuit/transfer/input/ -o ./gnark/circuit/transfer/output/ -e coins -s bty -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01) proof="1c33f86a705d387a191d598cdf5a4d97d839e49013ec8b73fb265a62bafc03fc17e9b34a36c6f015f49d1e944c945ff16bc3c7b4886591578c780fa829f140560fea4be7ddf3a98a5a620010f7a210456158e3f20b88a5a120980c8b960d15fb1c50a4d93b78c3cb3bc729152e1cd0b1574b3cc63a4ce6fb5f8e51828320df861d70f529eab34712c213a605dda2f05eda7fc4b0aefc99adb2817eb10548489d12591f64709a5ad3dd32a1ebfcdb70c50288af1185b4fa3e9a25636b9cc9df0c22880ab3541018fa25a9fb232ed4dd47e0aa92de0c4ee2f0fab57fe95df096fc01fc054d1331088bb57efd36df79ab36686df37dcb9284943d2047df96bd7635-172b267f5d1d1a629b364388c803405485aee2d5a86c4438dddba011c5ce77b42d7e5f12179642372f325af5d6fca46d169a2437e732461c4f4993a4ac3938a92c89038d4ba4434dacf7113c59e7be32a1952e0a452bd23621fa7159af74eb351a5ca048e591be47db5d45d54505c8924c7c1c5ec3d4df8e5b7c6e7f3ccf563d1acf12ad74b6985d9ba676a3db5abb69f0d4b687f8f11d019479ef22671b1cc90511e3fa819ad60f07d20329af3bfc0344f1a96b61e3f77c50885c5701be8e480482a58a06b3469b2d5821fca30e8d283c2e8e26c2106604709280e00c3df77f2ea8d9b4263ddedeab056d206c4665ed2caa28d4af67f09f32922239e1e5e572-1b66ecc95b8caf448d3bd235662c24a218a5c75ab42d41a8def3310424ac2d4515dfe9c9c77ad041e76ca2175d7e91de608cd39dea0194dc4eed7304d3126b230041306b465e74397b104db0303d87e0b02d052f6c7486d249a4dd5635f268ed1cd9180c6603351d1d74ed3f64283b0bfb75736d391892818f037b2549cb7e6d0b139b88edbf530fc3711e5c9235fa0e5b10af2fd03ac5993a6936d52ed51f250cfc84d3a379b9caa41ce9bf911259c1d7da73f8551032af8e3939c4d03e9cb125d0871b2e7a4ed474b87376188fd2fc463d0807d9bd701a6339c82489b523e022151dc964977616cc1d12176aad27d596b3e5caa4538d8716f93bfcaa2f2588"
rawData=$(${MIX_CLI31} mix transfer -m 600000000 -n "$transHash" -t 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -p ./gnark/ -w "" -v true -e coins -s bty)
signData=$(${CLI} wallet sign -d $rawData -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01)
hash=$(${CLI} wallet send -d "$signData")
echo "${hash}" echo "${hash}"
query_tx "${CLI}" "${hash}" query_tx "${CLI}" "${hash}"
query_note "${MIX_CLI3}" 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k 1 query_note "${MIX_CLI30}" 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k 1
echo "withdraw" echo "withdraw"
withdrawHash=$(${MIX_CLI3} mix wallet notes -a 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -s 1 | jq -r ".notes[0].noteHash") withdrawHash=$(${MIX_CLI30} mix wallet notes -a 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -s 1 | jq -r ".notes[0].noteHash")
hash=$(${MIX_CLI3} send mix withdraw -m 600000000 -n "$withdrawHash" -p ./gnark/circuit/withdraw/ -e coins -s bty -k 0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115) proof="152d166b3cbf1863f9da7ebb478a99d170544653d870a48533a48da8c484f2590fc795d9db67816b39a3dec2562dccfc5920b88236b766b8c3879e1d991121aa1b28801f92fac0597d397dc605b1e479742dbc3354bd1f33c8b52fac95cf047c29302a139eef9c948d148641e91d8b122785570d4a6c753c289e61bba96860c719fad87bb0954fc6ed3616f32af3f978aa26aeb03d123d312f569be901057c64123a2fed3890d5c0e59b3cff0e527dfe23b3f069227fd975a11c41133772cd311aa1b7ab4ff4849e01d7475c99e6e5fbc3fb0c1817e5f0a3ae98a7dc513af1e011aadc35e47b0359e39d89a50ff585b436fd27f5bc0bc973047c5b2fd52cd606"
rawData=$(${MIX_CLI30} mix withdraw -m 600000000 -n "$withdrawHash" -p ./gnark/ -w "" -v true -e coins -s bty)
signData=$(${CLI} wallet sign -d $rawData -k 0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115)
hash=$(${CLI} wallet send -d "$signData")
echo "${hash}" echo "${hash}"
query_tx "${CLI}" "${hash}" query_tx "${CLI}" "${hash}"
query_note "${MIX_CLI3}" 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k 2 query_note "${MIX_CLI30}" 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k 2
${CLI} account balance -a 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -e mix ${CLI} account balance -a 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -e mix
balance=$(${CLI} account balance -a 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -e mix | jq -r ".balance") balance=$(${CLI} account balance -a 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -e mix | jq -r ".balance")
...@@ -188,26 +198,33 @@ function mix_token_test() { ...@@ -188,26 +198,33 @@ function mix_token_test() {
query_tx "${CLI}" "${hash}" query_tx "${CLI}" "${hash}"
echo "mix deposit" echo "mix deposit"
hash=$(${CLI} send mix deposit -m 1000000000 -p ./gnark/circuit/deposit/ -r 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -e token -s GD -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01) proof="12c840fed692d2f38e6d227e6b4dfe46f0107075035adbb035c652f9e00a662b2ce53546477aff0fc320dd8c505cab2861d494a173be2fdfb6ddb033542a8bb10826dce453a6aa7c728e821b67a7c0dac14dd76135c04d71985e6682a4a4e0ca033be19ce61562235ae9d62cb8409599331da4b11718169fdddde4b6e4642f60031f64e90a2c37f627059af4db30e92ce9d3f45a7f4683088f048ed2e34d331a0966758a7849abfe4a15d2f7df52a1be3270bd13b2c87d559cfd85c3e12aed911627413fb9e99be990e0b4ea9c61ef68ba655bf003cbc050d92febfc337c32b52e7c30942536885d0b62ea3b44261f557d12ef4c24cc3728d4ea91d39b19ebf5"
hash=$(${CLI} send mix deposit -m 1000000000 -p ./gnark/ -w "" -v true -t 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -e token -s GD -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01)
echo "${hash}" echo "${hash}"
query_tx "${CLI}" "${hash}" query_tx "${CLI}" "${hash}"
query_note "${MIX_CLI3}" 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k 1 query_note "${MIX_CLI30}" 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k 1
echo "transfer to 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs" echo "transfer to 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
transHash=$(${MIX_CLI3} mix wallet notes -a 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -s 1 | jq -r ".notes[0].noteHash") transHash=$(${MIX_CLI30} mix wallet notes -a 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k -s 1 | jq -r ".notes[0].noteHash")
hash=$(${MIX_CLI3} send mix transfer -m 600000000 -n "$transHash" -t 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs -i ./gnark/circuit/transfer/input/ -o ./gnark/circuit/transfer/output/ -e token -s GD -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01) proof="19af0372674c7a4b2ab9126abe97862a75c0359998c02846fc9e43c6a75ef93d100b12a6f0caefb55d45407b8fee49271a20be3fe1615ca535635cf58a20625922cb46d5f9c41054f6d85b4c7df1ac5d308d3c0187f2b787befe5fcf80f790351a200124cdde88299fa3b6bdf9e88969607ea4816066f51f05d77b2034b5676817a8ece901f5df1993b242d1cf2bfd0f91d4478b33ff0994d6ea70830feaecf40d12f855ccd1cf73e2c7e27f5cf1df357c25293decc91d8cc252bbb5e19cd3741a90834263874d77ca79e6e69e6711cc4d73f1045942448eb3600dd58a1e084b1960fe8bf0dbfcb54dfdbed79f3c3c9b5a22469a7aa4e195b247bfd26f1fca73-17b4593758ceed61ac96cba435d5bfe6b7cdcdc8e2e4deab88aeadf433e37542131a1c2f4f5383a57387b2de3b5767e91d301b9e42da4858513bf897c8441ce205284b694309a57dc8dcdea27922742c446c94413054de7451f6f21d0425fecb1ce6b7a52d044fdbf52f842cd8fb2c4539a0cfa7973293fa78b0c5e656df40650ad4d041ecc9f50c72c4de2db6f917a5e08dff6f59e7a48bdd9f74667193fa7218ec30659bc1409354f58ae3fc98be3b0810dc83a39a4ee84e586487747b62e61e5f07914c2e94bd86128944106239ba523377d87216cb2c91191e1ac3c1a7382a3e9ee7868da53d20fdef596008c4641b48ca2b052a3c569ff5a2364aab5aa5-234cd13277ef10f2ffe28cd56964411b70040e2bec022e00ac068c9a5c94ed510b2f04e1a4377efd2e83f543cdfdfae0b1bd70595b5b6ea0db15b6c161354dd90e0028c5ae061cb46e10cbdd58d7558798350956777981178a3a08ad4f8513af06fb315045f3f438358206e543ad7b5caa93e9b9d82f7452a7d57dbf48ebd4c42f8583c62a050bd2b143340bdcbeb641679a49a607ee13e7fde5d1eba0217a1b0384ff474d6d5f041b1eba24b70b8f807b4bc45a4751a7cba10d806fef6ba6f122fa1928ba8328e89f82c2281330460931a69324e14fe584e0a9ab851b069a6304e0178f04a0bc89ffb50e7755328ba8ef84ca830424bed6ef3a8142c567ff2b"
rawData=$(${MIX_CLI30} mix transfer -m 600000000 -n "$transHash" -t 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs -p ./gnark/ -w "" -v true -e token -s GD)
signData=$(${CLI} wallet sign -d $rawData -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01)
hash=$(${CLI} wallet send -d "$signData")
echo "${hash}" echo "${hash}"
query_tx "${CLI}" "${hash}" query_tx "${CLI}" "${hash}"
query_note "${MIX_CLI3}" 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs 1 query_note "${MIX_CLI30}" 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs 1
echo "withdraw token GD" echo "withdraw token GD"
withdrawHash=$(${MIX_CLI3} mix wallet notes -a 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs -s 1 | jq -r ".notes[0].noteHash") withdrawHash=$(${MIX_CLI30} mix wallet notes -a 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs -s 1 | jq -r ".notes[0].noteHash")
hash=$(${MIX_CLI3} send mix withdraw -m 600000000 -n "$withdrawHash" -p ./gnark/circuit/withdraw/ -e token -s GD -k 0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71) proof="2ae76d20889a6be8c9173bd7fa93883a4d3f018b01d083f80809e363b954fab626327fc97e34d830a8101fa6c6fce2fcbc613a8794776488a9acad7983af189f225e1b7284f40ab265092524c20219da32ccf4ac6dc2a8b2de924e43e8763c421bf55d90f6615e15aa228549b09f48f7072af6f768528da8a7b13611950b8e611513ec503c0ea0a0782106eb85dc0493a117f699465cff63d44beec2668ab368207bab40cf1867e11fbc947408339f04cd991eda2b1a250fb181080f575cfe650cc4e1144a6f02e997d49269c0406a373913bc2530fd96fa2856c459de596da71d12b0e8aef76d33d4e862879636c9f9d21ff49789d93f9f671013c9e0489774"
rawData=$(${MIX_CLI30} mix withdraw -m 600000000 -n "$withdrawHash" -p ./gnark/ -w "" -v true -e token -s GD)
signData=$(${CLI} wallet sign -d $rawData -k 0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71)
hash=$(${CLI} wallet send -d "$signData")
echo "${hash}" echo "${hash}"
query_tx "${CLI}" "${hash}" query_tx "${CLI}" "${hash}"
query_note "${MIX_CLI3}" 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs 2 query_note "${MIX_CLI30}" 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs 2
${CLI} account balance -a 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs -e mix ${CLI} account balance -a 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs -e mix
balance=$(${CLI} asset balance -a 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs -e mix --asset_exec token --asset_symbol GD | jq -r ".balance") balance=$(${CLI} asset balance -a 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs -e mix --asset_exec token --asset_symbol GD | jq -r ".balance")
......
package main
import (
util "github.com/33cn/plugin/plugin/dapp/mix/cmd/gnark/circuit"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/gadgets/hash/mimc"
"github.com/consensys/gurvy"
)
func main() {
circuit := NewAuth()
gob.Write("circuit_auth.r1cs", circuit, gurvy.BN256)
}
//spend commit hash the circuit implementing
/*
public:
treeRootHash
authorizeHash(=hash(authpubkey+noterandom))
authorizeSpendHash(=hash(spendpub+value+noterandom))
private:
amount
receiverPubKey
returnPubKey
authorizePubKey
authorizePriKey
spendFlag
noteRandom
noteHash
path...
helper...
valid...
*/
func NewAuth() *frontend.R1CS {
// create root constraint system
circuit := frontend.New()
amount := circuit.SECRET_INPUT("Amount")
//spend pubkey
receiverPubKey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubKey := circuit.SECRET_INPUT("ReturnPubKey")
authorizePriKey := circuit.SECRET_INPUT("AuthorizePriKey")
noteRandom := circuit.SECRET_INPUT("NoteRandom")
authPubKey := circuit.SECRET_INPUT("AuthorizePubKey")
authorizeHash := circuit.PUBLIC_INPUT("AuthorizeHash")
// hash function
mimc, _ := mimc.NewMiMCGadget("seed", gurvy.BN256)
calcAuthPubKey := mimc.Hash(&circuit, authorizePriKey)
circuit.MUSTBE_EQ(authPubKey, calcAuthPubKey)
circuit.MUSTBE_EQ(authorizeHash, mimc.Hash(&circuit, authPubKey, noteRandom))
//note hash random
authSpendHash := circuit.PUBLIC_INPUT("AuthorizeSpendHash")
//spend_flag 0:return_pubkey, 1: spend_pubkey
spendFlag := circuit.SECRET_INPUT("SpendFlag")
circuit.MUSTBE_BOOLEAN(spendFlag)
targetPubHash := circuit.SELECT(spendFlag, receiverPubKey, returnPubKey)
calcAuthSpendHash := mimc.Hash(&circuit, targetPubHash, amount, noteRandom)
circuit.MUSTBE_EQ(authSpendHash, calcAuthSpendHash)
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
// specify note hash constraint
preImage := mimc.Hash(&circuit, receiverPubKey, returnPubKey, authPubKey, amount, noteRandom)
noteHash := circuit.SECRET_INPUT("NoteHash")
circuit.MUSTBE_EQ(noteHash, preImage)
util.MerkelPathPart(&circuit, mimc, preImage)
r1cs := circuit.ToR1CS()
return r1cs
}
package main
import (
"testing"
backend_bn256 "github.com/consensys/gnark/backend/bn256"
"github.com/consensys/gnark/backend"
"github.com/consensys/gnark/backend/bn256/groth16"
)
/*
public:
treeRootHash
authorizePubKey
authorizeHash(=hash(authpubkey+noterandom))
authorizeSpendHash(=hash(spendpub+value+noterandom))
private:
amount
receiverPubKey
returnPubKey
authorizePriKey
spendFlag
noteRandom
path...
helper...
valid...
*/
func TestAuthorizeSpend(t *testing.T) {
assert := groth16.NewAssert(t)
r1cs := NewAuth()
r1csBN256 := backend_bn256.Cast(r1cs)
{
good := backend.NewAssignment()
good.Assign(backend.Public, "TreeRootHash", "10531321614990797034921282585661869614556487056951485265320464926630499341310")
good.Assign(backend.Public, "AuthorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583")
good.Assign(backend.Public, "AuthorizeHash", "1267825436937766239630340333349685320927256968591056373125946583184548355070")
good.Assign(backend.Public, "AuthorizeSpendHash", "14468512365438613046028281588661351435476168610934165547900473609197783547663")
good.Assign(backend.Secret, "Amount", "28242048")
good.Assign(backend.Secret, "ReceiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705")
good.Assign(backend.Secret, "ReturnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497")
good.Assign(backend.Secret, "AuthorizePriKey", "17822967620457187568904804290291537271142779717280482398091401115827760898835")
good.Assign(backend.Secret, "SpendFlag", "1")
good.Assign(backend.Secret, "NoteRandom", "2824204835")
good.Assign(backend.Secret, "NoteHash", "16308793397024662832064523892418908145900866571524124093537199035808550255649")
good.Assign(backend.Secret, "Path0", "19561523370160677851616596032513161448778901506614020103852017946679781620105")
good.Assign(backend.Secret, "Path1", "13898857070666440684265042188056372750257678232709763835292910585848522658637")
good.Assign(backend.Secret, "Path2", "15019169196974879571470243100379529757970866395477207575033769902587972032431")
good.Assign(backend.Secret, "Path3", "0")
good.Assign(backend.Secret, "Path4", "0")
good.Assign(backend.Secret, "Path5", "0")
good.Assign(backend.Secret, "Path6", "0")
good.Assign(backend.Secret, "Path7", "0")
good.Assign(backend.Secret, "Path8", "0")
good.Assign(backend.Secret, "Path9", "0")
good.Assign(backend.Secret, "Helper0", "1")
good.Assign(backend.Secret, "Helper1", "1")
good.Assign(backend.Secret, "Helper2", "1")
good.Assign(backend.Secret, "Helper3", "0")
good.Assign(backend.Secret, "Helper4", "0")
good.Assign(backend.Secret, "Helper5", "0")
good.Assign(backend.Secret, "Helper6", "0")
good.Assign(backend.Secret, "Helper7", "0")
good.Assign(backend.Secret, "Helper8", "0")
good.Assign(backend.Secret, "Helper9", "0")
good.Assign(backend.Secret, "Valid0", "1")
good.Assign(backend.Secret, "Valid1", "1")
good.Assign(backend.Secret, "Valid2", "1")
good.Assign(backend.Secret, "Valid3", "0")
good.Assign(backend.Secret, "Valid4", "0")
good.Assign(backend.Secret, "Valid5", "0")
good.Assign(backend.Secret, "Valid6", "0")
good.Assign(backend.Secret, "Valid7", "0")
good.Assign(backend.Secret, "Valid8", "0")
good.Assign(backend.Secret, "Valid9", "0")
assert.Solved(&r1csBN256, good, nil)
}
}
public, TreeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310
public, AuthorizeHash,1267825436937766239630340333349685320927256968591056373125946583184548355070
public, AuthorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663
secret, Amount,28242048
secret, ReceiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, ReturnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
public, AuthorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
secret, AuthorizePriKey,17822967620457187568904804290291537271142779717280482398091401115827760898835
secret, SpendFlag,1
secret, NoteRandom,2824204835
secret, NoteHash,3649361563603415612447884923592927672484439983354650489908367088830561161361
secret, Path0,19561523370160677851616596032513161448778901506614020103852017946679781620105
secret, Path1,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, Path2,15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, Path3,0
secret, Path4,0
secret, Path5,0
secret, Path6,0
secret, Path7,0
secret, Path8,0
secret, Path9,0
secret, Helper0,1
secret, Helper1,1
secret, Helper2,1
secret, Helper3,1
secret, Helper4,1
secret, Helper5,1
secret, Helper6,1
secret, Helper7,1
secret, Helper8,1
secret, Helper9,1
secret, Valid0,1
secret, Valid1,1
secret, Valid2,1
secret, Valid3,0
secret, Valid4,0
secret, Valid5,0
secret, Valid6,0
secret, Valid7,0
secret, Valid8,0
secret, Valid9,0
package main
import (
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/gadgets/hash/mimc"
"github.com/consensys/gurvy"
)
func main() {
circuit := NewDeposit()
gob.Write("circuit_deposit.r1cs", circuit, gurvy.BN256)
}
//spend commit hash the circuit implementing
/*
public:
NoteHash
Amount
private:
ReceiverPubKey
ReturnPubKey
AuthorizePubKey
NoteRandom
*/
func NewDeposit() *frontend.R1CS {
// create root constraint system
circuit := frontend.New()
//公共输入以验证
amount := circuit.PUBLIC_INPUT("Amount")
//spend pubkey
receiverPubKey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubkey := circuit.SECRET_INPUT("ReturnPubKey")
authPubkey := circuit.SECRET_INPUT("AuthorizePubKey")
// hash function
mimc, _ := mimc.NewMiMCGadget("seed", gurvy.BN256)
//note hash random
noteRandom := circuit.SECRET_INPUT("NoteRandom")
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
//preImage=hash(spendPubkey, returnPubkey,AuthPubkey,spendValue,noteRandom)
noteHash := circuit.PUBLIC_INPUT("NoteHash")
// specify note hash constraint
preImage := mimc.Hash(&circuit, receiverPubKey, returnPubkey, authPubkey, amount, noteRandom)
circuit.MUSTBE_EQ(noteHash, preImage)
r1cs := circuit.ToR1CS()
return r1cs
}
package main
import (
"testing"
backend_bn256 "github.com/consensys/gnark/backend/bn256"
"github.com/consensys/gnark/backend"
"github.com/consensys/gnark/backend/bn256/groth16"
)
/*
public:
nodeHash
amount
private:
receiverPubKey
returnPubkey
authorizePubkey
noteRandom
*/
func TestDeposit(t *testing.T) {
assert := groth16.NewAssert(t)
//spend prikey="10190477835300927557649934238820360529458681672073866116232821892325659279502"
//spend pubkey="13735985067536865723202617343666111332145536963656464451727087263423649028705"
//return prikey="7969140283216448215269095418467361784159407896899334866715345504515077887397"
//return pubkey="16067249407809359746114321133992130903102335882983385972747813693681808870497"
//authorize prikey="17822967620457187568904804290291537271142779717280482398091401115827760898835"
//authorize pubkey="13519883267141251871527102103999205179714486518503885909948192364772977661583"
//spend prikey="10407830929890509544473717262275616077696950294748419792758056545898949331744"
//spend pubkey="12419942056983622012214804185935674735538011812395392042541464417352183370586"
r1cs := NewDeposit()
r1csBN256 := backend_bn256.Cast(r1cs)
{
good := backend.NewAssignment()
good.Assign(backend.Public, "noteHash", "16308793397024662832064523892418908145900866571524124093537199035808550255649")
good.Assign(backend.Public, "amount", "28242048")
good.Assign(backend.Secret, "receiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705")
good.Assign(backend.Secret, "returnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497")
good.Assign(backend.Secret, "authorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583")
good.Assign(backend.Secret, "noteRandom", "2824204835")
assert.Solved(&r1csBN256, good, nil)
}
}
public, NoteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649
public, Amount,28242048
secret, ReceiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, ReturnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, AuthorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
secret, NoteRandom,2824204835
public, TreeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310
public, ShieldAmountX,14087975867275911077371231345227824611951436822132762463787130558957838320348
public, ShieldAmountY,15113519960384204624879642069520481336224311978035289236693658603675385299879
public, AuthorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663
public, NullifierHash,6747518781649068310795677405858353007442326529625450860668944156162052335195
secret, Amount,28242048
secret, AmountRandom,35
secret, ReceiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, ReturnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, AuthorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
secret, SpendPriKey,10190477835300927557649934238820360529458681672073866116232821892325659279502
secret, SpendFlag,1
secret, AuthorizeFlag,1
secret, NoteRandom,2824204835
secret, NoteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649
secret, Path0,19561523370160677851616596032513161448778901506614020103852017946679781620105
secret, Path1,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, Path2,15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, Path3,0
secret, Path4,0
secret, Path5,0
secret, Path6,0
secret, Path7,0
secret, Path8,0
secret, Path9,0
secret, Helper0,1
secret, Helper1,1
secret, Helper2,1
secret, Helper3,1
secret, Helper4,1
secret, Helper5,1
secret, Helper6,1
secret, Helper7,1
secret, Helper8,1
secret, Helper9,1
secret, Valid0,1
secret, Valid1,1
secret, Valid2,1
secret, Valid3,0
secret, Valid4,0
secret, Valid5,0
secret, Valid6,0
secret, Valid7,0
secret, Valid8,0
secret, Valid9,0
package main
import (
util "github.com/33cn/plugin/plugin/dapp/mix/cmd/gnark/circuit"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/gadgets/hash/mimc"
"github.com/consensys/gurvy"
)
func main() {
circuit := NewTransferInput()
gob.Write("circuit_transfer_input.r1cs", circuit, gurvy.BN256)
}
//spend commit hash the circuit implementing
/*
public:
treeRootHash
shieldAmountX
shieldAmountY
authorizeSpendHash
nullifierHash
private:
amount
amountRandom
receiverPubKey
returnPubKey
authorizePubKey
spendPriKey
spendFlag
authorizeFlag
noteRandom
path...
helper...
valid...
*/
func NewTransferInput() *frontend.R1CS {
// create root constraint system
circuit := frontend.New()
spendValue := circuit.SECRET_INPUT("Amount")
//spend pubkey
spendPubkey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubkey := circuit.SECRET_INPUT("ReturnPubKey")
authPubkey := circuit.SECRET_INPUT("AuthorizePubKey")
spendPrikey := circuit.SECRET_INPUT("SpendPriKey")
//spend_flag 0:return_pubkey, 1: spend_pubkey
spendFlag := circuit.SECRET_INPUT("SpendFlag")
circuit.MUSTBE_BOOLEAN(spendFlag)
//auth_check 0: not need auth check, 1:need check
authFlag := circuit.SECRET_INPUT("AuthorizeFlag")
circuit.MUSTBE_BOOLEAN(authFlag)
// hash function
mimc, _ := mimc.NewMiMCGadget("seed", gurvy.BN256)
calcPubHash := mimc.Hash(&circuit, spendPrikey)
targetPubHash := circuit.SELECT(spendFlag, spendPubkey, returnPubkey)
circuit.MUSTBE_EQ(targetPubHash, calcPubHash)
//note hash random
noteRandom := circuit.SECRET_INPUT("NoteRandom")
//need check in database if not null
authHash := circuit.PUBLIC_INPUT("AuthorizeSpendHash")
nullValue := circuit.ALLOCATE(0)
//// specify auth hash constraint
calcAuthSpendHash := mimc.Hash(&circuit, targetPubHash, spendValue, noteRandom)
targetAuthHash := circuit.SELECT(authFlag, calcAuthSpendHash, nullValue)
circuit.MUSTBE_EQ(authHash, targetAuthHash)
//need check in database if not null
nullifierHash := circuit.PUBLIC_INPUT("NullifierHash")
calcNullifierHash := mimc.Hash(&circuit, noteRandom)
circuit.MUSTBE_EQ(nullifierHash, calcNullifierHash)
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
noteHash := circuit.SECRET_INPUT("NoteHash")
calcReturnPubkey := circuit.SELECT(authFlag, returnPubkey, nullValue)
calcAuthPubkey := circuit.SELECT(authFlag, authPubkey, nullValue)
// specify note hash constraint
preImage := mimc.Hash(&circuit, spendPubkey, calcReturnPubkey, calcAuthPubkey, spendValue, noteRandom)
circuit.MUSTBE_EQ(noteHash, preImage)
util.CommitValuePart(&circuit, spendValue)
util.MerkelPathPart(&circuit, mimc, preImage)
r1cs := circuit.ToR1CS()
return r1cs
}
package main
import (
"testing"
backend_bn256 "github.com/consensys/gnark/backend/bn256"
"github.com/consensys/gnark/backend"
"github.com/consensys/gnark/backend/bn256/groth16"
)
/*
public:
treeRootHash
shieldAmountX
shieldAmountY
authorizeHash
nullifierHash
private:
amount
amountRandom
receiverPubKey
returnPubKey
authorizePubKey
spendPriKey
spendFlag
authorizeFlag
noteRandom
path...
helper...
valid...
*/
func TestTransferInputAuth(t *testing.T) {
assert := groth16.NewAssert(t)
r1cs := NewTransferInput()
r1csBN256 := backend_bn256.Cast(r1cs)
{
good := backend.NewAssignment()
good.Assign(backend.Public, "treeRootHash", "10531321614990797034921282585661869614556487056951485265320464926630499341310")
good.Assign(backend.Public, "shieldAmountX", "14087975867275911077371231345227824611951436822132762463787130558957838320348")
good.Assign(backend.Public, "shieldAmountY", "15113519960384204624879642069520481336224311978035289236693658603675385299879")
good.Assign(backend.Public, "authorizeSpendHash", "14468512365438613046028281588661351435476168610934165547900473609197783547663")
good.Assign(backend.Public, "nullifierHash", "6747518781649068310795677405858353007442326529625450860668944156162052335195")
good.Assign(backend.Secret, "amount", "28242048")
good.Assign(backend.Secret, "amountRandom", "35")
good.Assign(backend.Secret, "receiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705")
good.Assign(backend.Secret, "returnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497")
good.Assign(backend.Secret, "authorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583")
good.Assign(backend.Secret, "spendPriKey", "10190477835300927557649934238820360529458681672073866116232821892325659279502")
good.Assign(backend.Secret, "spendFlag", "1")
good.Assign(backend.Secret, "authorizeFlag", "1")
good.Assign(backend.Secret, "noteRandom", "2824204835")
good.Assign(backend.Secret, "noteHash", "16308793397024662832064523892418908145900866571524124093537199035808550255649")
//nodehash="16308793397024662832064523892418908145900866571524124093537199035808550255649"
good.Assign(backend.Secret, "path1", "19561523370160677851616596032513161448778901506614020103852017946679781620105")
good.Assign(backend.Secret, "path2", "13898857070666440684265042188056372750257678232709763835292910585848522658637")
good.Assign(backend.Secret, "path3", "15019169196974879571470243100379529757970866395477207575033769902587972032431")
good.Assign(backend.Secret, "path4", "0")
good.Assign(backend.Secret, "path5", "0")
good.Assign(backend.Secret, "path6", "0")
good.Assign(backend.Secret, "path7", "0")
good.Assign(backend.Secret, "path8", "0")
good.Assign(backend.Secret, "path9", "0")
good.Assign(backend.Secret, "helper1", "1")
good.Assign(backend.Secret, "helper2", "1")
good.Assign(backend.Secret, "helper3", "1")
good.Assign(backend.Secret, "helper4", "0")
good.Assign(backend.Secret, "helper5", "0")
good.Assign(backend.Secret, "helper6", "0")
good.Assign(backend.Secret, "helper7", "0")
good.Assign(backend.Secret, "helper8", "0")
good.Assign(backend.Secret, "helper9", "0")
good.Assign(backend.Secret, "valid1", "1")
good.Assign(backend.Secret, "valid2", "1")
good.Assign(backend.Secret, "valid3", "1")
good.Assign(backend.Secret, "valid4", "0")
good.Assign(backend.Secret, "valid5", "0")
good.Assign(backend.Secret, "valid6", "0")
good.Assign(backend.Secret, "valid7", "0")
good.Assign(backend.Secret, "valid8", "0")
good.Assign(backend.Secret, "valid9", "0")
assert.Solved(&r1csBN256, good, nil)
}
}
func TestTransferInputReturnKey(t *testing.T) {
assert := groth16.NewAssert(t)
r1cs := NewTransferInput()
r1csBN256 := backend_bn256.Cast(r1cs)
{
good := backend.NewAssignment()
good.Assign(backend.Public, "treeRootHash", "10531321614990797034921282585661869614556487056951485265320464926630499341310")
good.Assign(backend.Public, "shieldAmountX", "14087975867275911077371231345227824611951436822132762463787130558957838320348")
good.Assign(backend.Public, "shieldAmountY", "15113519960384204624879642069520481336224311978035289236693658603675385299879")
good.Assign(backend.Public, "authorizeSpendHash", "6026163592877030954825395224309219861774131411806846860652261047183070579370")
good.Assign(backend.Public, "nullifierHash", "6747518781649068310795677405858353007442326529625450860668944156162052335195")
good.Assign(backend.Secret, "amount", "28242048")
good.Assign(backend.Secret, "amountRandom", "35")
good.Assign(backend.Secret, "receiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705")
good.Assign(backend.Secret, "returnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497")
good.Assign(backend.Secret, "authorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583")
good.Assign(backend.Secret, "spendPriKey", "7969140283216448215269095418467361784159407896899334866715345504515077887397")
//returnkey spend notehash
good.Assign(backend.Secret, "spendFlag", "0")
good.Assign(backend.Secret, "authorizeFlag", "1")
good.Assign(backend.Secret, "noteRandom", "2824204835")
good.Assign(backend.Secret, "noteHash", "16308793397024662832064523892418908145900866571524124093537199035808550255649")
//nodehash="16308793397024662832064523892418908145900866571524124093537199035808550255649"
good.Assign(backend.Secret, "path1", "19561523370160677851616596032513161448778901506614020103852017946679781620105")
good.Assign(backend.Secret, "path2", "13898857070666440684265042188056372750257678232709763835292910585848522658637")
good.Assign(backend.Secret, "path3", "15019169196974879571470243100379529757970866395477207575033769902587972032431")
good.Assign(backend.Secret, "path4", "0")
good.Assign(backend.Secret, "path5", "0")
good.Assign(backend.Secret, "path6", "0")
good.Assign(backend.Secret, "path7", "0")
good.Assign(backend.Secret, "path8", "0")
good.Assign(backend.Secret, "path9", "0")
good.Assign(backend.Secret, "helper1", "1")
good.Assign(backend.Secret, "helper2", "1")
good.Assign(backend.Secret, "helper3", "1")
good.Assign(backend.Secret, "helper4", "0")
good.Assign(backend.Secret, "helper5", "0")
good.Assign(backend.Secret, "helper6", "0")
good.Assign(backend.Secret, "helper7", "0")
good.Assign(backend.Secret, "helper8", "0")
good.Assign(backend.Secret, "helper9", "0")
good.Assign(backend.Secret, "valid1", "1")
good.Assign(backend.Secret, "valid2", "1")
good.Assign(backend.Secret, "valid3", "1")
good.Assign(backend.Secret, "valid4", "0")
good.Assign(backend.Secret, "valid5", "0")
good.Assign(backend.Secret, "valid6", "0")
good.Assign(backend.Secret, "valid7", "0")
good.Assign(backend.Secret, "valid8", "0")
good.Assign(backend.Secret, "valid9", "0")
assert.Solved(&r1csBN256, good, nil)
}
}
func TestTransferInputNoAuthorize(t *testing.T) {
assert := groth16.NewAssert(t)
r1cs := NewTransferInput()
r1csBN256 := backend_bn256.Cast(r1cs)
{
good := backend.NewAssignment()
good.Assign(backend.Public, "treeRootHash", "8924377726623516198388981994706612588174229761660626844219523809311621081152")
good.Assign(backend.Public, "shieldAmountX", "20026900249169569699397829614948056401416692452575929785554743563301443795984")
good.Assign(backend.Public, "shieldAmountY", "11443294504840468048882645872852838384649876010412151915870299030068051779303")
good.Assign(backend.Public, "authorizeSpendHash", "0")
good.Assign(backend.Public, "nullifierHash", "4493238794492517147695618716694376637191823831910850819304582851540887491471")
good.Assign(backend.Secret, "amount", "500000000")
good.Assign(backend.Secret, "amountRandom", "103649245823269378598256096359743803233")
good.Assign(backend.Secret, "receiverPubKey", "7244551457692363731356498279463138379576484998878425864678733206990733443457")
good.Assign(backend.Secret, "returnPubKey", "0")
good.Assign(backend.Secret, "authorizePubKey", "0")
good.Assign(backend.Secret, "spendPriKey", "19115616183616714814727844928908633989028519974595353009754871398745087846141")
good.Assign(backend.Secret, "spendFlag", "1")
//not need authorize
good.Assign(backend.Secret, "authorizeFlag", "0")
good.Assign(backend.Secret, "noteRandom", "16855817802811010832998322637530013398737002960466904173163094025121554818471")
good.Assign(backend.Secret, "noteHash", "4757455985754753449547885621755931629265767091930770913671501411452663313694")
good.Assign(backend.Secret, "path1", "21609869341494920403470153054548069228540665950349313465330160010270609674984")
good.Assign(backend.Secret, "path2", "0")
good.Assign(backend.Secret, "path3", "0")
good.Assign(backend.Secret, "path4", "0")
good.Assign(backend.Secret, "path5", "0")
good.Assign(backend.Secret, "path6", "0")
good.Assign(backend.Secret, "path7", "0")
good.Assign(backend.Secret, "path8", "0")
good.Assign(backend.Secret, "path9", "0")
good.Assign(backend.Secret, "helper1", "0")
good.Assign(backend.Secret, "helper2", "1")
good.Assign(backend.Secret, "helper3", "1")
good.Assign(backend.Secret, "helper4", "0")
good.Assign(backend.Secret, "helper5", "0")
good.Assign(backend.Secret, "helper6", "0")
good.Assign(backend.Secret, "helper7", "0")
good.Assign(backend.Secret, "helper8", "0")
good.Assign(backend.Secret, "helper9", "0")
good.Assign(backend.Secret, "valid1", "1")
good.Assign(backend.Secret, "valid2", "0")
good.Assign(backend.Secret, "valid3", "0")
good.Assign(backend.Secret, "valid4", "0")
good.Assign(backend.Secret, "valid5", "0")
good.Assign(backend.Secret, "valid6", "0")
good.Assign(backend.Secret, "valid7", "0")
good.Assign(backend.Secret, "valid8", "0")
good.Assign(backend.Secret, "valid9", "0")
assert.Solved(&r1csBN256, good, nil)
}
}
public, shieldAmountX,14087975867275911077371231345227824611951436822132762463787130558957838320348
public, shieldAmountY,15113519960384204624879642069520481336224311978035289236693658603675385299879
public, noteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649
secret, amount,28242048
secret, amountRandom,35
secret, receiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, returnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, authorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
secret, noteRandom,2824204835
package main
import (
util "github.com/33cn/plugin/plugin/dapp/mix/cmd/gnark/circuit"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/gadgets/hash/mimc"
"github.com/consensys/gurvy"
)
func main() {
circuit := NewTransferOutput()
gob.Write("circuit_transfer_output.r1cs", circuit, gurvy.BN256)
}
//spend commit hash the circuit implementing
/*
public:
shieldAmountX
shieldAmountY
noteHash
private:
amount
amountRandom
receiverPubKey
returnPubKey
authorizePubKey
noteRandom
*/
func NewTransferOutput() *frontend.R1CS {
// create root constraint system
circuit := frontend.New()
spendValue := circuit.SECRET_INPUT("Amount")
//spend pubkey
spendPubkey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubkey := circuit.SECRET_INPUT("ReturnPubKey")
authPubkey := circuit.SECRET_INPUT("AuthorizePubKey")
// hash function
mimc, _ := mimc.NewMiMCGadget("seed", gurvy.BN256)
//note hash random
noteRandom := circuit.SECRET_INPUT("NoteRandom")
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
//preImage=hash(spendPubkey, returnPubkey,AuthPubkey,spendValue,noteRandom)
noteHash := circuit.PUBLIC_INPUT("NoteHash")
// specify note hash constraint
preImage := mimc.Hash(&circuit, spendPubkey, returnPubkey, authPubkey, spendValue, noteRandom)
circuit.MUSTBE_EQ(noteHash, preImage)
util.CommitValuePart(&circuit, spendValue)
r1cs := circuit.ToR1CS()
return r1cs
}
package main
import (
"testing"
backend_bn256 "github.com/consensys/gnark/backend/bn256"
"github.com/consensys/gnark/backend"
"github.com/consensys/gnark/backend/bn256/groth16"
)
/*
public:
shieldAmountX
shieldAmountY
noteHash
private:
amount
amountRandom
receiverPubKey
returnPubKey
authorizePubKey
noteRandom
*/
func TestTransferOutput(t *testing.T) {
assert := groth16.NewAssert(t)
r1cs := NewTransferOutput()
r1csBN256 := backend_bn256.Cast(r1cs)
{
good := backend.NewAssignment()
good.Assign(backend.Public, "shieldAmountX", "14087975867275911077371231345227824611951436822132762463787130558957838320348")
good.Assign(backend.Public, "shieldAmountY", "15113519960384204624879642069520481336224311978035289236693658603675385299879")
good.Assign(backend.Public, "noteHash", "16308793397024662832064523892418908145900866571524124093537199035808550255649")
good.Assign(backend.Secret, "amount", "28242048")
good.Assign(backend.Secret, "amountRandom", "35")
good.Assign(backend.Secret, "receiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705")
good.Assign(backend.Secret, "returnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497")
good.Assign(backend.Secret, "authorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583")
good.Assign(backend.Secret, "noteRandom", "2824204835")
assert.Solved(&r1csBN256, good, nil)
}
}
func TestTransferOutputTemp(t *testing.T) {
assert := groth16.NewAssert(t)
r1cs := NewTransferOutput()
r1csBN256 := backend_bn256.Cast(r1cs)
{
good := backend.NewAssignment()
good.Assign(backend.Public, "shieldAmountX", "3403754862862244121869403834818720211897208891381676574399662060838495940078")
good.Assign(backend.Public, "shieldAmountY", "21401902064308935591303802598664246616585474010691469717860664156067228175223")
good.Assign(backend.Public, "noteHash", "13610259753835165822431524149670478281864477297016371975012414049080268826331")
good.Assign(backend.Secret, "amount", "300000000")
good.Assign(backend.Secret, "amountRandom", "17199160520698273243343882915453578587")
good.Assign(backend.Secret, "receiverPubKey", "18829345085195922012068709111582461121107908772422825655963168999800303848486")
good.Assign(backend.Secret, "returnPubKey", "0")
good.Assign(backend.Secret, "authorizePubKey", "0")
good.Assign(backend.Secret, "noteRandom", "5029847585956946251661044349066579681630691396824473307862642244158835326399")
assert.Solved(&r1csBN256, good, nil)
}
}
func TestTransferOutputChange(t *testing.T) {
assert := groth16.NewAssert(t)
r1cs := NewTransferOutput()
r1csBN256 := backend_bn256.Cast(r1cs)
{
good := backend.NewAssignment()
good.Assign(backend.Public, "shieldAmountX", "10703086269439751873106176219875739041896146845566831131812760688039385779519")
good.Assign(backend.Public, "shieldAmountY", "19139103177181062461420753508628290808191900352948606822559796252948653071734")
good.Assign(backend.Public, "noteHash", "13134546856103113099750783399130805737503059294172727906371169345876474249458")
good.Assign(backend.Secret, "amount", "199900000")
good.Assign(backend.Secret, "amountRandom", "86450085302571105354912213444290224646")
good.Assign(backend.Secret, "receiverPubKey", "7244551457692363731356498279463138379576484998878425864678733206990733443457")
good.Assign(backend.Secret, "returnPubKey", "0")
good.Assign(backend.Secret, "authorizePubKey", "0")
good.Assign(backend.Secret, "noteRandom", "7266395330102686861165120582739238575545854195882356283931287331463151808870")
assert.Solved(&r1csBN256, good, nil)
}
}
package circuit
import (
"strconv"
"github.com/consensys/gnark/frontend"
twistededwards_gadget "github.com/consensys/gnark/gadgets/algebra/twistededwards"
"github.com/consensys/gnark/gadgets/hash/mimc"
"github.com/consensys/gurvy"
fr_bn256 "github.com/consensys/gurvy/bn256/fr"
)
func MerkelPathPart(circuit *frontend.CS, mimc mimc.MiMCGadget, noteHash *frontend.Constraint) {
var proofSet, helper, valid []*frontend.Constraint
merkleRoot := circuit.PUBLIC_INPUT("TreeRootHash")
proofSet = append(proofSet, noteHash)
//helper[0],valid[0]占位, 方便接口只设置有效值
helper = append(helper, circuit.ALLOCATE("1"))
valid = append(valid, circuit.ALLOCATE("1"))
//depth:10, path num need be 9
for i := 0; i < 10; i++ {
proofSet = append(proofSet, circuit.SECRET_INPUT("Path"+strconv.Itoa(i)))
helper = append(helper, circuit.SECRET_INPUT("Helper"+strconv.Itoa(i)))
valid = append(valid, circuit.SECRET_INPUT("Valid"+strconv.Itoa(i)))
}
VerifyMerkleProof(circuit, mimc, merkleRoot, proofSet, helper, valid)
}
func VerifyMerkleProof(circuit *frontend.CS, h mimc.MiMCGadget, merkleRoot *frontend.Constraint, proofSet, helper, valid []*frontend.Constraint) {
sum := leafSum(circuit, h, proofSet[0])
for i := 1; i < len(proofSet); i++ {
circuit.MUSTBE_BOOLEAN(helper[i])
d1 := circuit.SELECT(helper[i], sum, proofSet[i])
d2 := circuit.SELECT(helper[i], proofSet[i], sum)
rst := nodeSum(circuit, h, d1, d2)
sum = circuit.SELECT(valid[i], rst, sum)
}
// Compare our calculated Merkle root to the desired Merkle root.
circuit.MUSTBE_EQ(sum, merkleRoot)
}
// nodeSum returns the hash created from data inserted to form a leaf.
// Without domain separation.
func nodeSum(circuit *frontend.CS, h mimc.MiMCGadget, a, b *frontend.Constraint) *frontend.Constraint {
res := h.Hash(circuit, a, b)
return res
}
// leafSum returns the hash created from data inserted to form a leaf.
// Without domain separation.
func leafSum(circuit *frontend.CS, h mimc.MiMCGadget, data *frontend.Constraint) *frontend.Constraint {
res := h.Hash(circuit, data)
return res
}
func CommitValuePart(circuit *frontend.CS, spendValue *frontend.Constraint) {
//cmt=transfer_value*G + random_value*H
cmtvalueX := circuit.PUBLIC_INPUT("ShieldAmountX")
cmtvalueY := circuit.PUBLIC_INPUT("ShieldAmountY")
// set curve parameters
edgadget, _ := twistededwards_gadget.NewEdCurveGadget(gurvy.BN256)
// set point G in the circuit
pointGSnark := twistededwards_gadget.NewPointGadget(circuit, nil, nil)
//to avoid <0 values input
//negOne := circuit.ALLOCATE("-1")
//negSpendVal := circuit.MUL(spendValue,negOne)
//circuit.MUSTBE_LESS_OR_EQ(negSpendVal, 0, 256)
circuit.MUSTBE_LESS_OR_EQ(spendValue, 1000000000000000000, 256)
// set point G in the circuit
pointGSnark.ScalarMulFixedBase(circuit, edgadget.BaseX, edgadget.BaseY, spendValue, edgadget)
pointGSnark.X.Tag("xg")
pointGSnark.Y.Tag("yg")
transfer_random := circuit.SECRET_INPUT("AmountRandom")
//circuit.MUSTBE_LESS_OR_EQ(random_value,10000000000,256)
//H is not G, H should be a point that no one know the prikey
var baseX_H, baseY_H fr_bn256.Element
baseX_H.SetString("10190477835300927557649934238820360529458681672073866116232821892325659279502")
baseY_H.SetString("7969140283216448215269095418467361784159407896899334866715345504515077887397")
pointHSnark := twistededwards_gadget.NewPointGadget(circuit, nil, nil)
// add points in circuit (the method updates the underlying plain points as well)
pointHSnark.ScalarMulFixedBase(circuit, baseX_H, baseY_H, transfer_random, edgadget)
pointHSnark.X.Tag("xh")
pointHSnark.Y.Tag("yh")
pointSumSnark := twistededwards_gadget.NewPointGadget(circuit, nil, nil)
pointSumSnark.AddGeneric(circuit, &pointGSnark, &pointHSnark, edgadget)
//cmtvalue=transfer_value*G + random_value*H
circuit.MUSTBE_EQ(cmtvalueX, pointSumSnark.X)
circuit.MUSTBE_EQ(cmtvalueY, pointSumSnark.Y)
}
public, TreeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310
public, AuthorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663
public, NullifierHash,6747518781649068310795677405858353007442326529625450860668944156162052335195
public, Amount,28242048
secret, ReceiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, ReturnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, AuthorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
secret, SpendPriKey,10190477835300927557649934238820360529458681672073866116232821892325659279502
secret, SpendFlag,1
secret, AuthorizeFlag,1
secret, NoteRandom,2824204835
secret, NoteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649
secret, Path0,19561523370160677851616596032513161448778901506614020103852017946679781620105
secret, Path1,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, Path2,15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, Path3,0
secret, Path4,0
secret, Path5,0
secret, Path6,0
secret, Path7,0
secret, Path8,0
secret, Path9,0
secret, Helper0,1
secret, Helper1,1
secret, Helper2,1
secret, Helper3,1
secret, Helper4,1
secret, Helper5,1
secret, Helper6,1
secret, Helper7,1
secret, Helper8,1
secret, Helper9,1
secret, Valid0,1
secret, Valid1,1
secret, Valid2,1
secret, Valid3,0
secret, Valid4,0
secret, Valid5,0
secret, Valid6,0
secret, Valid7,0
secret, Valid8,0
secret, Valid9,0
package main
import (
util "github.com/33cn/plugin/plugin/dapp/mix/cmd/gnark/circuit"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/gadgets/hash/mimc"
"github.com/consensys/gurvy"
)
func main() {
circuit := NewWithdraw()
gob.Write("circuit_withdraw.r1cs", circuit, gurvy.BN256)
}
//withdraw commit hash the circuit implementing
/*
public:
treeRootHash
authorizeSpendHash
nullifierHash
amount
private:
receiverPubKey
returnPubKey
authorizePubKey
spendPriKey
spendFlag
authorizeFlag
noteRandom
noteHash
path...
helper...
valid...
*/
func NewWithdraw() *frontend.R1CS {
// create root constraint system
circuit := frontend.New()
spendValue := circuit.PUBLIC_INPUT("Amount")
//spend pubkey
receiverPubKey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubkey := circuit.SECRET_INPUT("ReturnPubKey")
authPubkey := circuit.SECRET_INPUT("AuthorizePubKey")
spendPrikey := circuit.SECRET_INPUT("SpendPriKey")
//spend_flag 0:return_pubkey, 1: spend_pubkey
spendFlag := circuit.SECRET_INPUT("SpendFlag")
circuit.MUSTBE_BOOLEAN(spendFlag)
//auth_check 0: not need auth check, 1:need check
authFlag := circuit.SECRET_INPUT("AuthorizeFlag")
circuit.MUSTBE_BOOLEAN(authFlag)
// hash function
mimc, _ := mimc.NewMiMCGadget("seed", gurvy.BN256)
calcPubHash := mimc.Hash(&circuit, spendPrikey)
targetPubHash := circuit.SELECT(spendFlag, receiverPubKey, returnPubkey)
circuit.MUSTBE_EQ(targetPubHash, calcPubHash)
//note hash random
noteRandom := circuit.SECRET_INPUT("NoteRandom")
//need check in database if not null
authHash := circuit.PUBLIC_INPUT("AuthorizeSpendHash")
nullValue := circuit.ALLOCATE(0)
// specify auth hash constraint
calcAuthHash := mimc.Hash(&circuit, targetPubHash, spendValue, noteRandom)
targetAuthHash := circuit.SELECT(authFlag, calcAuthHash, nullValue)
circuit.MUSTBE_EQ(authHash, targetAuthHash)
//need check in database if not null
nullifierHash := circuit.PUBLIC_INPUT("NullifierHash")
calcNullifierHash := mimc.Hash(&circuit, noteRandom)
circuit.MUSTBE_EQ(nullifierHash, calcNullifierHash)
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
//preImage=hash(spendPubkey, returnPubkey,AuthPubkey,spendValue,noteRandom)
noteHash := circuit.SECRET_INPUT("NoteHash")
calcReturnPubkey := circuit.SELECT(authFlag, returnPubkey, nullValue)
calcAuthPubkey := circuit.SELECT(authFlag, authPubkey, nullValue)
// specify note hash constraint
preImage := mimc.Hash(&circuit, receiverPubKey, calcReturnPubkey, calcAuthPubkey, spendValue, noteRandom)
circuit.MUSTBE_EQ(noteHash, preImage)
util.MerkelPathPart(&circuit, mimc, preImage)
r1cs := circuit.ToR1CS()
return r1cs
}
package main
import (
"testing"
backend_bn256 "github.com/consensys/gnark/backend/bn256"
"github.com/consensys/gnark/backend"
"github.com/consensys/gnark/backend/bn256/groth16"
)
/*
public:
treeRootHash
authorizeHash
nullifierHash
amount
private:
receiverPubKey
returnPubKey
authorizePubKey
spendPriKey
spendFlag
authorizeFlag
noteRandom
path...
helper...
valid...
*/
func TestWithdraw(t *testing.T) {
assert := groth16.NewAssert(t)
r1cs := NewWithdraw()
r1csBN256 := backend_bn256.Cast(r1cs)
{
good := backend.NewAssignment()
good.Assign(backend.Public, "TreeRootHash", "10531321614990797034921282585661869614556487056951485265320464926630499341310")
good.Assign(backend.Public, "AuthorizeSpendHash", "14468512365438613046028281588661351435476168610934165547900473609197783547663")
good.Assign(backend.Public, "NullifierHash", "6747518781649068310795677405858353007442326529625450860668944156162052335195")
good.Assign(backend.Public, "Amount", "28242048")
good.Assign(backend.Secret, "ReceiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705")
good.Assign(backend.Secret, "ReturnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497")
good.Assign(backend.Secret, "AuthorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583")
good.Assign(backend.Secret, "SpendPriKey", "10190477835300927557649934238820360529458681672073866116232821892325659279502")
good.Assign(backend.Secret, "SpendFlag", "1")
good.Assign(backend.Secret, "AuthorizeFlag", "1")
good.Assign(backend.Secret, "NoteRandom", "2824204835")
good.Assign(backend.Secret, "NoteHash", "16308793397024662832064523892418908145900866571524124093537199035808550255649")
//nodehash="16308793397024662832064523892418908145900866571524124093537199035808550255649"
good.Assign(backend.Secret, "Path0", "19561523370160677851616596032513161448778901506614020103852017946679781620105")
good.Assign(backend.Secret, "Path1", "13898857070666440684265042188056372750257678232709763835292910585848522658637")
good.Assign(backend.Secret, "Path2", "15019169196974879571470243100379529757970866395477207575033769902587972032431")
good.Assign(backend.Secret, "Path3", "0")
good.Assign(backend.Secret, "Path4", "0")
good.Assign(backend.Secret, "Path5", "0")
good.Assign(backend.Secret, "Path6", "0")
good.Assign(backend.Secret, "Path7", "0")
good.Assign(backend.Secret, "Path8", "0")
good.Assign(backend.Secret, "Path9", "0")
good.Assign(backend.Secret, "Helper0", "1")
good.Assign(backend.Secret, "Helper1", "1")
good.Assign(backend.Secret, "Helper2", "1")
good.Assign(backend.Secret, "Helper3", "0")
good.Assign(backend.Secret, "Helper4", "0")
good.Assign(backend.Secret, "Helper5", "0")
good.Assign(backend.Secret, "Helper6", "0")
good.Assign(backend.Secret, "Helper7", "0")
good.Assign(backend.Secret, "Helper8", "0")
good.Assign(backend.Secret, "Helper9", "0")
good.Assign(backend.Secret, "Valid0", "1")
good.Assign(backend.Secret, "Valid1", "1")
good.Assign(backend.Secret, "Valid2", "1")
good.Assign(backend.Secret, "Valid3", "0")
good.Assign(backend.Secret, "Valid4", "0")
good.Assign(backend.Secret, "Valid5", "0")
good.Assign(backend.Secret, "Valid6", "0")
good.Assign(backend.Secret, "Valid7", "0")
good.Assign(backend.Secret, "Valid8", "0")
good.Assign(backend.Secret, "Valid9", "0")
assert.Solved(&r1csBN256, good, nil)
}
}
func TestWithdraw2(t *testing.T) {
assert := groth16.NewAssert(t)
r1cs := NewWithdraw()
r1csBN256 := backend_bn256.Cast(r1cs)
{
good := backend.NewAssignment()
good.Assign(backend.Public, "TreeRootHash", "7407373673604276152801354004851383461539317977307945198624806503955302548700")
good.Assign(backend.Public, "AuthorizeSpendHash", "0")
good.Assign(backend.Public, "NullifierHash", "3911774040567972872956008387141175001419649692949203140089059098956773329188")
good.Assign(backend.Public, "Amount", "500000000")
good.Assign(backend.Secret, "ReceiverPubKey", "7244551457692363731356498279463138379576484998878425864678733206990733443457")
good.Assign(backend.Secret, "ReturnPubKey", "0")
good.Assign(backend.Secret, "AuthorizePubKey", "0")
good.Assign(backend.Secret, "SpendPriKey", "19115616183616714814727844928908633989028519974595353009754871398745087846141")
good.Assign(backend.Secret, "SpendFlag", "1")
good.Assign(backend.Secret, "AuthorizeFlag", "0")
good.Assign(backend.Secret, "NoteRandom", "13093524699504167542220418896875211339267114119238016501132859435646426190390")
good.Assign(backend.Secret, "NoteHash", "6441981280327245191543878922302235060888201984279829017462503030039593719666")
//nodehash="16308793397024662832064523892418908145900866571524124093537199035808550255649"
good.Assign(backend.Secret, "Path0", "16592081253758169453601069427813166612800474003570537799829885686701266956141")
good.Assign(backend.Secret, "Path1", "0")
good.Assign(backend.Secret, "Path2", "0")
good.Assign(backend.Secret, "Path3", "0")
good.Assign(backend.Secret, "Path4", "0")
good.Assign(backend.Secret, "Path5", "0")
good.Assign(backend.Secret, "Path6", "0")
good.Assign(backend.Secret, "Path7", "0")
good.Assign(backend.Secret, "Path8", "0")
good.Assign(backend.Secret, "Path9", "0")
good.Assign(backend.Secret, "Helper0", "0")
good.Assign(backend.Secret, "Helper1", "0")
good.Assign(backend.Secret, "Helper2", "0")
good.Assign(backend.Secret, "Helper3", "0")
good.Assign(backend.Secret, "Helper4", "0")
good.Assign(backend.Secret, "Helper5", "0")
good.Assign(backend.Secret, "Helper6", "0")
good.Assign(backend.Secret, "Helper7", "0")
good.Assign(backend.Secret, "Helper8", "0")
good.Assign(backend.Secret, "Helper9", "0")
good.Assign(backend.Secret, "Valid0", "1")
good.Assign(backend.Secret, "Valid1", "0")
good.Assign(backend.Secret, "Valid2", "0")
good.Assign(backend.Secret, "Valid3", "0")
good.Assign(backend.Secret, "Valid4", "0")
good.Assign(backend.Secret, "Valid5", "0")
good.Assign(backend.Secret, "Valid6", "0")
good.Assign(backend.Secret, "Valid7", "0")
good.Assign(backend.Secret, "Valid8", "0")
good.Assign(backend.Secret, "Valid9", "0")
assert.Solved(&r1csBN256, good, nil)
}
}
/*
Copyright © 2020 ConsenSys
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"github.com/spf13/cobra"
"os"
mimcbn256 "github.com/consensys/gnark/crypto/hash/mimc/bn256"
fr_bn256 "github.com/consensys/gurvy/bn256/fr"
"github.com/consensys/gurvy/bn256/twistededwards"
)
// verifyCmd represents the verify command
var calcCmd = &cobra.Command{
Use: "calc",
Short: "calc",
Version: Version,
}
var (
fCommit string
fRandom string
)
func init() {
calcCmd.AddCommand(hashCmd)
calcCmd.AddCommand(commitCmd)
rootCmd.AddCommand(calcCmd)
commitCmd.PersistentFlags().StringVar(&fCommit, "value", "", "specifies commit value")
commitCmd.PersistentFlags().StringVar(&fRandom, "random", "", "specifies random value")
_ = commitCmd.MarkPersistentFlagRequired("value")
_ = commitCmd.MarkPersistentFlagRequired("random")
}
var hashCmd = &cobra.Command{
Use: "hash ...",
Short: "read strings to calc hash",
Run: hash,
Version: Version,
}
func hash(cmd *cobra.Command, args []string) {
if len(args) < 1 {
fmt.Println("missing input strings")
os.Exit(-1)
}
var sum []byte
for _, k := range args {
fmt.Println("input:", k)
sum = append(sum, getByte(k)...)
}
hash := mimcbn256.Sum("seed", sum)
fmt.Println("hash=", getFrString(hash))
}
func getByte(v string) []byte {
var fr fr_bn256.Element
fr.SetString(v)
return fr.Bytes()
}
func getFrString(v []byte) string {
var f fr_bn256.Element
f.SetBytes(v)
return f.String()
}
var commitCmd = &cobra.Command{
Use: "commit",
Short: "commit value",
Run: commit,
Version: Version,
}
func commit(cmd *cobra.Command, args []string) {
//if len(args) < 1 {
// fmt.Println("missing input strings")
// os.Exit(-1)
//}
var basex, basey, baseHx, baseHy fr_bn256.Element
basex.SetString("5299619240641551281634865583518297030282874472190772894086521144482721001553")
basey.SetString("16950150798460657717958625567821834550301663161624707787222815936182638968203")
baseHx.SetString("10190477835300927557649934238820360529458681672073866116232821892325659279502")
baseHy.SetString("7969140283216448215269095418467361784159407896899334866715345504515077887397")
basePoint := twistededwards.NewPoint(basex, basey)
baseHPoint := twistededwards.NewPoint(baseHx, baseHy)
var frCommit, frRandom fr_bn256.Element
frCommit.SetString(fCommit).FromMont()
frRandom.SetString(fRandom).FromMont()
fmt.Println("commit", fCommit, "random", fRandom)
var commitPoint, randomPoint, finalPoint twistededwards.Point
commitPoint.ScalarMul(&basePoint, frCommit)
randomPoint.ScalarMul(&baseHPoint, frRandom)
finalPoint.Add(&commitPoint, &randomPoint)
fmt.Println("finalPoint X:", finalPoint.X.String())
fmt.Println("finalPoint Y:", finalPoint.Y.String())
//
//fmt.Println("commitX:",commitPoint.X.String())
//fmt.Println("commitY:",commitPoint.Y.String())
//
//fmt.Println("randomX:",randomPoint.X.String())
//fmt.Println("randomY:",randomPoint.Y.String())
}
/*
Copyright © 2020 ConsenSys
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import "errors"
var (
errNotFound = errors.New("file not found")
errUnknownCurve = errors.New("unknown curve id")
)
/*
Copyright © 2020 ConsenSys
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"os"
"path/filepath"
"time"
"github.com/consensys/gnark/backend"
backend_bls377 "github.com/consensys/gnark/backend/bls377"
groth16_bls377 "github.com/consensys/gnark/backend/bls377/groth16"
backend_bls381 "github.com/consensys/gnark/backend/bls381"
groth16_bls381 "github.com/consensys/gnark/backend/bls381/groth16"
backend_bn256 "github.com/consensys/gnark/backend/bn256"
groth16_bn256 "github.com/consensys/gnark/backend/bn256/groth16"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gurvy"
"github.com/spf13/cobra"
)
// proveCmd represents the prove command
var proveCmd = &cobra.Command{
Use: "prove [circuit.r1cs]",
Short: "creates a (zk)proof for provided circuit and solution",
Run: cmdProve,
Version: Version,
}
var (
fProofPath string
fInputPath string
fCount uint
)
func init() {
rootCmd.AddCommand(proveCmd)
proveCmd.PersistentFlags().StringVar(&fProofPath, "proof", "", "specifies full path for proof -- default is ./[circuit].proof")
proveCmd.PersistentFlags().StringVar(&fPkPath, "pk", "", "specifies full path for proving key")
proveCmd.PersistentFlags().StringVar(&fInputPath, "input", "", "specifies full path for input file")
proveCmd.PersistentFlags().UintVar(&fCount, "count", 1, "specifies number of times the prover algorithm is ran (benchmarking purposes)")
_ = proveCmd.MarkPersistentFlagRequired("pk")
_ = proveCmd.MarkPersistentFlagRequired("input")
}
func cmdProve(cmd *cobra.Command, args []string) {
if len(args) < 1 {
fmt.Println("missing circuit path -- gnark prove -h for help")
os.Exit(-1)
}
circuitPath := filepath.Clean(args[0])
circuitName := filepath.Base(circuitPath)
circuitExt := filepath.Ext(circuitName)
circuitName = circuitName[0 : len(circuitName)-len(circuitExt)]
// ensure pk and input flags are set and valid
if fPkPath == "" {
fmt.Println("please specify proving key path")
_ = cmd.Usage()
os.Exit(-1)
}
if fInputPath == "" {
fmt.Println("please specify input file path")
_ = cmd.Usage()
os.Exit(-1)
}
fPkPath = filepath.Clean(fPkPath)
if !fileExists(fPkPath) {
fmt.Println(fPkPath, errNotFound)
os.Exit(-1)
}
fInputPath = filepath.Clean(fInputPath)
if !fileExists(fInputPath) {
fmt.Println(fInputPath, errNotFound)
os.Exit(-1)
}
// load circuit
if !fileExists(circuitPath) {
fmt.Println("error:", errNotFound)
os.Exit(-1)
}
// check curve ID
curveID, err := gob.PeekCurveID(circuitPath)
if err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
// TODO clean that up with interfaces and type casts
var bigIntR1cs frontend.R1CS
switch curveID {
case gurvy.BLS377:
if err := gob.Read(circuitPath, &bigIntR1cs, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
r1cs := backend_bls377.Cast(&bigIntR1cs)
fmt.Printf("%-30s %-30s %-d constraints\n", "loaded circuit", circuitPath, r1cs.NbConstraints)
// run setup
var pk groth16_bls377.ProvingKey
if err := gob.Read(fPkPath, &pk, curveID); err != nil {
fmt.Println("can't load proving key")
fmt.Println(err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s\n", "loaded proving key", fPkPath)
// parse input file
r1csInput := backend.NewAssignment()
err = r1csInput.ReadFile(fInputPath)
if err != nil {
fmt.Println("can't parse input", err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s %-d inputs\n", "loaded input", fInputPath, len(r1csInput))
// compute proof
start := time.Now()
proof, err := groth16_bls377.Prove(&r1cs, &pk, r1csInput)
if err != nil {
fmt.Println("Error proof generation", err)
os.Exit(-1)
}
for i := uint(1); i < fCount; i++ {
_, _ = groth16_bls377.Prove(&r1cs, &pk, r1csInput)
}
duration := time.Since(start)
if fCount > 1 {
duration = time.Duration(int64(duration) / int64(fCount))
}
// default proof path
proofPath := filepath.Join(".", circuitName+".proof")
if fProofPath != "" {
proofPath = fProofPath
}
if err := gob.Write(proofPath, proof, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s %-30s\n", "generated proof", proofPath, duration)
case gurvy.BLS381:
if err := gob.Read(circuitPath, &bigIntR1cs, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
r1cs := backend_bls381.Cast(&bigIntR1cs)
fmt.Printf("%-30s %-30s %-d constraints\n", "loaded circuit", circuitPath, r1cs.NbConstraints)
// run setup
var pk groth16_bls381.ProvingKey
if err := gob.Read(fPkPath, &pk, curveID); err != nil {
fmt.Println("can't load proving key")
fmt.Println(err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s\n", "loaded proving key", fPkPath)
// parse input file
r1csInput := backend.NewAssignment()
err = r1csInput.ReadFile(fInputPath)
if err != nil {
fmt.Println("can't parse input", err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s %-d inputs\n", "loaded input", fInputPath, len(r1csInput))
// compute proof
start := time.Now()
proof, err := groth16_bls381.Prove(&r1cs, &pk, r1csInput)
if err != nil {
fmt.Println("Error proof generation", err)
os.Exit(-1)
}
for i := uint(1); i < fCount; i++ {
_, _ = groth16_bls381.Prove(&r1cs, &pk, r1csInput)
}
duration := time.Since(start)
if fCount > 1 {
duration = time.Duration(int64(duration) / int64(fCount))
}
// default proof path
proofPath := filepath.Join(".", circuitName+".proof")
if fProofPath != "" {
proofPath = fProofPath
}
if err := gob.Write(proofPath, proof, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s %-30s\n", "generated proof", proofPath, duration)
case gurvy.BN256:
if err := gob.Read(circuitPath, &bigIntR1cs, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
r1cs := backend_bn256.Cast(&bigIntR1cs)
fmt.Printf("%-30s %-30s %-d constraints\n", "loaded circuit", circuitPath, r1cs.NbConstraints)
// run setup
var pk groth16_bn256.ProvingKey
if err := gob.Read(fPkPath, &pk, curveID); err != nil {
fmt.Println("can't load proving key")
fmt.Println(err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s\n", "loaded proving key", fPkPath)
// parse input file
r1csInput := backend.NewAssignment()
err = r1csInput.ReadFile(fInputPath)
if err != nil {
fmt.Println("can't parse input", err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s %-d inputs\n", "loaded input", fInputPath, len(r1csInput))
// compute proof
start := time.Now()
proof, err := groth16_bn256.Prove(&r1cs, &pk, r1csInput)
if err != nil {
fmt.Println("Error proof generation", err)
os.Exit(-1)
}
for i := uint(1); i < fCount; i++ {
_, _ = groth16_bn256.Prove(&r1cs, &pk, r1csInput)
}
duration := time.Since(start)
if fCount > 1 {
duration = time.Duration(int64(duration) / int64(fCount))
}
// default proof path
proofPath := filepath.Join(".", circuitName+".proof")
if fProofPath != "" {
proofPath = fProofPath
}
if err := gob.Write(proofPath, proof, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s %-30s\n", "generated proof", proofPath, duration)
default:
fmt.Println("error:", errUnknownCurve)
os.Exit(-1)
}
}
/*
Copyright © 2020 ConsenSys
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"bufio"
"bytes"
"encoding/csv"
"errors"
"encoding/hex"
"encoding/json"
"github.com/consensys/gnark/backend"
"strings"
"fmt"
"io"
"github.com/spf13/cobra"
"os"
"path/filepath"
)
// verifyCmd represents the verify command
var readCmd = &cobra.Command{
Use: "read [file] --flags",
Short: "read a file and show to hex string",
Run: cmdRead,
Version: Version,
}
var (
fType int32
)
func init() {
rootCmd.AddCommand(readCmd)
readCmd.PersistentFlags().Int32VarP(&fType, "type", "t", 0, "0: proof or vk file, 1: input file, default 0")
}
func cmdRead(cmd *cobra.Command, args []string) {
if len(args) < 1 {
fmt.Println("missing read file path -- gnark read -h for help")
os.Exit(-1)
}
filePath := filepath.Clean(args[0])
if fType == 1 {
readInput2(filePath)
return
}
readProof(filePath)
}
func readProof(file string) {
// open file
f, err := os.Open(file)
if err != nil {
fmt.Println("err", err)
}
defer f.Close()
var buff bytes.Buffer
buff.ReadFrom(f)
fmt.Println("proof", hex.EncodeToString(buff.Bytes()))
}
func readInput2(fInputPath string) {
// parse input file
csvFile, err := os.Open(fInputPath)
if err != nil {
fmt.Println("open", err)
return
}
defer csvFile.Close()
toRead, err := readPublic(csvFile)
if err != nil {
fmt.Println("read", err)
return
}
fmt.Println("json code =", toRead)
}
func readPublic(r io.Reader) (string, error) {
toRead := make(map[string]interface{})
reader := csv.NewReader(bufio.NewReader(r))
for {
line, err := reader.Read()
if err == io.EOF {
break
} else if err != nil {
return "", err
} else if len(line) != 3 {
return "", errors.New("ErrInvalidInputFormat")
}
visibility := strings.ToLower(strings.TrimSpace(line[0]))
name := strings.TrimSpace(line[1])
value := strings.TrimSpace(line[2])
if backend.Visibility(visibility) == backend.Public {
if strings.HasPrefix(value, "0x") {
bytes, err := hex.DecodeString(value[2:])
if err != nil {
return "", err
}
toRead[name] = bytes
}
toRead[name] = value
}
}
//marshal 可以被unmarshal 和json.decode同时解析
out, err := json.Marshal(toRead)
if err != nil {
return "", err
}
return hex.EncodeToString(out), nil
}
/*
Copyright © 2020 ConsenSys
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
)
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "gnark",
Short: "gnark is a framework to execute (and verify) algorithms in zero-knowledge",
Version: Version,
}
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
if Version == "" {
fmt.Println("/!\\ running gnark in DEV mode /!\\")
}
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func init() {
cobra.OnInitialize(initConfig)
}
// initConfig reads in config file and ENV variables if set.
func initConfig() {
// config file business, if needed.
}
func fileExists(filePath string) bool {
fInfo, err := os.Stat(filePath)
return !os.IsNotExist(err) && !fInfo.IsDir()
}
/*
Copyright © 2020 ConsenSys
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"os"
"path/filepath"
"time"
backend_bls377 "github.com/consensys/gnark/backend/bls377"
groth16_bls377 "github.com/consensys/gnark/backend/bls377/groth16"
backend_bls381 "github.com/consensys/gnark/backend/bls381"
groth16_bls381 "github.com/consensys/gnark/backend/bls381/groth16"
backend_bn256 "github.com/consensys/gnark/backend/bn256"
groth16_bn256 "github.com/consensys/gnark/backend/bn256/groth16"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gurvy"
"github.com/spf13/cobra"
)
// setupCmd represents the setup command
var setupCmd = &cobra.Command{
Use: "setup [circuit.r1cs]",
Short: "outputs proving and verifying keys for a given circuit",
Run: cmdSetup,
Version: Version,
}
var (
fVkPath, fPkPath string
)
func init() {
rootCmd.AddCommand(setupCmd)
setupCmd.PersistentFlags().StringVar(&fVkPath, "vk", "", "specifies full path for verifying key -- default is ./[circuit].vk")
setupCmd.PersistentFlags().StringVar(&fPkPath, "pk", "", "specifies full path for proving key -- default is ./[circuit].pk")
}
func cmdSetup(cmd *cobra.Command, args []string) {
if len(args) < 1 {
fmt.Println("missing circuit path -- gnark setup -h for help")
os.Exit(-1)
}
circuitPath := filepath.Clean(args[0])
circuitName := filepath.Base(circuitPath)
circuitExt := filepath.Ext(circuitName)
circuitName = circuitName[0 : len(circuitName)-len(circuitExt)]
vkPath := filepath.Join(".", circuitName+".vk")
pkPath := filepath.Join(".", circuitName+".pk")
if fVkPath != "" {
vkPath = fVkPath
}
if fPkPath != "" {
pkPath = fPkPath
}
// load circuit
if !fileExists(circuitPath) {
fmt.Println("error:", errNotFound)
os.Exit(-1)
}
// check curve ID (TODO is curve.ID necessary now? Because the circuits are serialized with big.Int, here the curve.ID is "unknown")
curveID, err := gob.PeekCurveID(circuitPath)
fmt.Println("test-----" + curveID.String())
if err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
// TODO clean that up with interfaces and type casts
var bigIntR1cs frontend.R1CS
switch curveID {
case gurvy.BLS377:
if err := gob.Read(circuitPath, &bigIntR1cs, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
r1cs := backend_bls377.Cast(&bigIntR1cs)
fmt.Printf("%-30s %-30s %-d constraints\n", "loaded circuit", circuitPath, r1cs.NbConstraints)
// run setup
var pk groth16_bls377.ProvingKey
var vk groth16_bls377.VerifyingKey
start := time.Now()
groth16_bls377.Setup(&r1cs, &pk, &vk)
duration := time.Since(start)
fmt.Printf("%-30s %-30s %-30s\n", "setup completed", "", duration)
if err := gob.Write(vkPath, &vk, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
fmt.Printf("%-30s %s\n", "generated verifying key", vkPath)
if err := gob.Write(pkPath, &pk, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
fmt.Printf("%-30s %s\n", "generated proving key", pkPath)
case gurvy.BLS381:
if err := gob.Read(circuitPath, &bigIntR1cs, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
r1cs := backend_bls381.Cast(&bigIntR1cs)
fmt.Printf("%-30s %-30s %-d constraints\n", "loaded circuit", circuitPath, r1cs.NbConstraints)
// run setup
var pk groth16_bls381.ProvingKey
var vk groth16_bls381.VerifyingKey
start := time.Now()
groth16_bls381.Setup(&r1cs, &pk, &vk)
duration := time.Since(start)
fmt.Printf("%-30s %-30s %-30s\n", "setup completed", "", duration)
if err := gob.Write(vkPath, &vk, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
fmt.Printf("%-30s %s\n", "generated verifying key", vkPath)
if err := gob.Write(pkPath, &pk, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
fmt.Printf("%-30s %s\n", "generated proving key", pkPath)
case gurvy.BN256:
if err := gob.Read(circuitPath, &bigIntR1cs, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
r1cs := backend_bn256.Cast(&bigIntR1cs)
fmt.Printf("%-30s %-30s %-d constraints\n", "loaded circuit", circuitPath, r1cs.NbConstraints)
// run setup
var pk groth16_bn256.ProvingKey
var vk groth16_bn256.VerifyingKey
start := time.Now()
groth16_bn256.Setup(&r1cs, &pk, &vk)
duration := time.Since(start)
fmt.Printf("%-30s %-30s %-30s\n", "setup completed", "", duration)
if err := gob.Write(vkPath, &vk, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
fmt.Printf("%-30s %s\n", "generated verifying key", vkPath)
if err := gob.Write(pkPath, &pk, curveID); err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
fmt.Printf("%-30s %s\n", "generated proving key", pkPath)
default:
fmt.Println("error:", errUnknownCurve)
os.Exit(-1)
}
}
/*
Copyright © 2020 ConsenSys
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"os"
"path/filepath"
"time"
"github.com/consensys/gnark/backend"
groth16_bls377 "github.com/consensys/gnark/backend/bls377/groth16"
groth16_bls381 "github.com/consensys/gnark/backend/bls381/groth16"
groth16_bn256 "github.com/consensys/gnark/backend/bn256/groth16"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gurvy"
"github.com/spf13/cobra"
)
// verifyCmd represents the verify command
var verifyCmd = &cobra.Command{
Use: "verify [proof]",
Short: "verifies a proof against a verifying key and a partial / public solution",
Run: cmdVerify,
Version: Version,
}
func init() {
rootCmd.AddCommand(verifyCmd)
verifyCmd.PersistentFlags().StringVar(&fVkPath, "vk", "", "specifies full path for verifying key")
verifyCmd.PersistentFlags().StringVar(&fInputPath, "input", "", "specifies full path for input file")
_ = verifyCmd.MarkPersistentFlagRequired("vk")
_ = verifyCmd.MarkPersistentFlagRequired("input")
}
func cmdVerify(cmd *cobra.Command, args []string) {
if len(args) < 1 {
fmt.Println("missing proof path -- gnark verify -h for help")
os.Exit(-1)
}
proofPath := filepath.Clean(args[0])
// ensure vk and input flags are set and valid
if fVkPath == "" {
fmt.Println("please specify verifying key path")
_ = cmd.Usage()
os.Exit(-1)
}
if fInputPath == "" {
fmt.Println("please specify input file path")
_ = cmd.Usage()
os.Exit(-1)
}
fVkPath = filepath.Clean(fVkPath)
if !fileExists(fVkPath) {
fmt.Println(fVkPath, errNotFound)
os.Exit(-1)
}
fInputPath = filepath.Clean(fInputPath)
if !fileExists(fInputPath) {
fmt.Println(fInputPath, errNotFound)
os.Exit(-1)
}
// parse verifying key
if !fileExists(fVkPath) {
fmt.Println("error:", errNotFound)
os.Exit(-1)
}
// check curve ID
curveID, err := gob.PeekCurveID(fVkPath)
if err != nil {
fmt.Println("error:", err)
os.Exit(-1)
}
// TODO clean that up with interfaces and type casts
switch curveID {
case gurvy.BLS377:
var vk groth16_bls377.VerifyingKey
if err := gob.Read(fVkPath, &vk, curveID); err != nil {
fmt.Println("can't load verifying key")
fmt.Println(err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s\n", "loaded verifying key", fVkPath)
// parse input file
r1csInput := backend.NewAssignment()
err := r1csInput.ReadFile(fInputPath)
if err != nil {
fmt.Println("can't parse input", err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s %-d inputs\n", "loaded input", fInputPath, len(r1csInput))
// load proof
var proof groth16_bls377.Proof
if err := gob.Read(proofPath, &proof, curveID); err != nil {
fmt.Println("can't parse proof", err)
os.Exit(-1)
}
// verify proof
start := time.Now()
result, err := groth16_bls377.Verify(&proof, &vk, r1csInput)
if err != nil || !result {
fmt.Printf("%-30s %-30s %-30s\n", "proof is invalid", proofPath, time.Since(start))
if err != nil {
fmt.Println(err)
}
os.Exit(-1)
}
fmt.Printf("%-30s %-30s %-30s\n", "proof is valid", proofPath, time.Since(start))
case gurvy.BLS381:
var vk groth16_bls381.VerifyingKey
if err := gob.Read(fVkPath, &vk, curveID); err != nil {
fmt.Println("can't load verifying key")
fmt.Println(err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s\n", "loaded verifying key", fVkPath)
// parse input file
r1csInput := backend.NewAssignment()
err := r1csInput.ReadFile(fInputPath)
if err != nil {
fmt.Println("can't parse input", err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s %-d inputs\n", "loaded input", fInputPath, len(r1csInput))
// load proof
var proof groth16_bls381.Proof
if err := gob.Read(proofPath, &proof, curveID); err != nil {
fmt.Println("can't parse proof", err)
os.Exit(-1)
}
// verify proof
start := time.Now()
result, err := groth16_bls381.Verify(&proof, &vk, r1csInput)
if err != nil || !result {
fmt.Printf("%-30s %-30s %-30s\n", "proof is invalid", proofPath, time.Since(start))
if err != nil {
fmt.Println(err)
}
os.Exit(-1)
}
fmt.Printf("%-30s %-30s %-30s\n", "proof is valid", proofPath, time.Since(start))
case gurvy.BN256:
var vk groth16_bn256.VerifyingKey
if err := gob.Read(fVkPath, &vk, curveID); err != nil {
fmt.Println("can't load verifying key")
fmt.Println(err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s\n", "loaded verifying key", fVkPath)
// parse input file
r1csInput := backend.NewAssignment()
err := r1csInput.ReadFile(fInputPath)
if err != nil {
fmt.Println("can't parse input", err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s %-d inputs\n", "loaded input", fInputPath, len(r1csInput))
// load proof
var proof groth16_bn256.Proof
if err := gob.Read(proofPath, &proof, curveID); err != nil {
fmt.Println("can't parse proof", err)
os.Exit(-1)
}
// verify proof
start := time.Now()
result, err := groth16_bn256.Verify(&proof, &vk, r1csInput)
if err != nil || !result {
fmt.Printf("%-30s %-30s %-30s\n", "proof is invalid", proofPath, time.Since(start))
if err != nil {
fmt.Println(err)
}
os.Exit(-1)
}
fmt.Printf("%-30s %-30s %-30s\n", "proof is valid", proofPath, time.Since(start))
default:
fmt.Println("error:", errUnknownCurve)
os.Exit(-1)
}
}
/*
Copyright © 2020 ConsenSys
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"bytes"
"encoding/hex"
"encoding/json"
"fmt"
"log"
"os"
"time"
"github.com/consensys/gnark/backend"
groth16_bn256 "github.com/consensys/gnark/backend/bn256/groth16"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gurvy"
"github.com/spf13/cobra"
)
// verifyCmd represents the verify command
var verifyInputCmd = &cobra.Command{
Use: "verifystr",
Short: "verifies a proof against a verifying key and a partial / public solution",
Run: cmdVerifyStr,
Version: Version,
}
var (
fProofStr, fInputStr, fVerifyStr string
)
func init() {
rootCmd.AddCommand(verifyInputCmd)
verifyInputCmd.PersistentFlags().StringVar(&fVerifyStr, "vk", "", "specifies full path for verifying key")
verifyInputCmd.PersistentFlags().StringVar(&fInputStr, "input", "", "specifies full path for input file")
verifyInputCmd.PersistentFlags().StringVar(&fProofStr, "proof", "", "specifies full path for input file")
_ = verifyInputCmd.MarkPersistentFlagRequired("vk")
_ = verifyInputCmd.MarkPersistentFlagRequired("input")
_ = verifyInputCmd.MarkPersistentFlagRequired("proof")
}
func cmdVerifyStr(cmd *cobra.Command, args []string) {
curveID := gurvy.BN256
//verify key
var buffVk bytes.Buffer
res, err := hex.DecodeString(fVerifyStr)
if err != nil {
log.Fatal(err)
}
buffVk.Write(res)
var vk groth16_bn256.VerifyingKey
if err := gob.Deserialize(&buffVk, &vk, curveID); err != nil {
fmt.Println("can't load verifying key")
fmt.Println(err)
os.Exit(-1)
}
fmt.Printf("%-30s %-30s\n", "loaded verifying key", fVkPath)
//public input
rst, err := deserializeInput(fInputStr)
if err != nil {
log.Fatal(err)
}
r1csInput := backend.NewAssignment()
for k, v := range rst {
r1csInput.Assign(backend.Public, k, v)
}
// load proof
var proof groth16_bn256.Proof
var buffProof bytes.Buffer
res, err = hex.DecodeString(fProofStr)
if err != nil {
log.Fatal(err)
}
buffProof.Write(res)
if err := gob.Deserialize(&buffProof, &proof, curveID); err != nil {
fmt.Println("can't parse proof", err)
os.Exit(-1)
}
// verify proof
start := time.Now()
result, err := groth16_bn256.Verify(&proof, &vk, r1csInput)
if err != nil || !result {
fmt.Printf("%-30s %-30s %-30s\n", "proof is invalid", "proofPath", time.Since(start))
if err != nil {
fmt.Println(err)
}
os.Exit(-1)
}
fmt.Printf("%-30s %-30s %-30s\n", "proof is valid", "proofPath", time.Since(start))
}
func deserializeInput(input string) (map[string]interface{}, error) {
var buffInput bytes.Buffer
res, err := hex.DecodeString(input)
if err != nil {
log.Fatal(err)
}
buffInput.Write(res)
decoder := json.NewDecoder(&buffInput)
toRead := make(map[string]interface{})
if err := decoder.Decode(&toRead); err != nil {
return nil, err
}
return toRead, nil
}
// Copyright 2020 ConsenSys AG
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by gnark/internal/generators/version DO NOT EDIT
package cmd
const Version = "v0.2.0-alpha"
package cmd
import (
"os/exec"
"strings"
"testing"
)
func TestVersionIsGenerated(t *testing.T) {
// goal of this test is to ensure version.go contains up to date Version string
// that is: if a new SemVer tag is pushed, go generate should run to re-generate version.go
v, err := exec.Command("git", "describe", "--abbrev=0").CombinedOutput()
if err != nil {
panic(err)
}
version := strings.TrimSpace(string(v))
if version != Version {
t.Fatal("version was not generated, need to run go generate ./... at root of repo", "got", Version, "expected", version)
}
}
/*
Copyright © 2020 ConsenSys
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package gnark is a framework to execute (and verify) algorithms in zero-knowledge
package main
import "github.com/33cn/plugin/plugin/dapp/mix/cmd/gnark/cmd"
func main() {
cmd.Execute()
}
...@@ -34,6 +34,7 @@ func MixCmd() *cobra.Command { ...@@ -34,6 +34,7 @@ func MixCmd() *cobra.Command {
CreateAuthRawTxCmd(), CreateAuthRawTxCmd(),
CreateConfigCmd(), CreateConfigCmd(),
CreateParamsCmd(),
QueryCmd(), QueryCmd(),
WalletCmd(), WalletCmd(),
...@@ -106,6 +107,52 @@ func createConfigVerify(cmd *cobra.Command, args []string) { ...@@ -106,6 +107,52 @@ func createConfigVerify(cmd *cobra.Command, args []string) {
} }
// CreateParamsCmd create raw asset transfer tx
func CreateParamsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create",
Short: "create parameters",
}
cmd.AddCommand(mixCreateZkKeyCmd())
return cmd
}
func mixCreateZkKeyCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "keys",
Short: "create pk and vk for circuit",
Run: createZkKeys,
}
addCreateKeyFlags(cmd)
return cmd
}
func addCreateKeyFlags(cmd *cobra.Command) {
cmd.Flags().Int32P("circuit", "t", 0, "mix circuit type,0:deposit,1:withdraw,2:tansferinput,3:transferoutput,4:authorize")
cmd.MarkFlagRequired("circuit")
cmd.Flags().StringP("path", "p", "", "key save path")
cmd.MarkFlagRequired("path")
}
func createZkKeys(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
circuit, _ := cmd.Flags().GetInt32("circuit")
path, _ := cmd.Flags().GetString("path")
var params mixTy.CreateZkKeyFileReq
params.Ty = circuit
params.SavePath = path
var req types.ReplyString
ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.CreateZkKeyFile", &params, &req)
ctx.Run()
}
func mixConfigAuthPubKeyParaCmd() *cobra.Command { func mixConfigAuthPubKeyParaCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "auth", Use: "auth",
...@@ -161,14 +208,14 @@ func mixConfigPaymentPubKeyParaCmd() *cobra.Command { ...@@ -161,14 +208,14 @@ func mixConfigPaymentPubKeyParaCmd() *cobra.Command {
} }
func addPayPubKeyConfigFlags(cmd *cobra.Command) { func addPayPubKeyConfigFlags(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "a", "", "register for addr ") cmd.Flags().StringP("addr", "a", "", "chain addr ")
cmd.MarkFlagRequired("addr") cmd.MarkFlagRequired("addr")
cmd.Flags().StringP("receiver", "r", "", "receiver key") cmd.Flags().StringP("receiver", "r", "", "note receiver addr")
cmd.MarkFlagRequired("receiver") cmd.MarkFlagRequired("receiver")
cmd.Flags().StringP("encryptKey", "e", "", "encrypt key for secret") cmd.Flags().StringP("secretKey", "e", "", "key for note secret info")
cmd.MarkFlagRequired("encryptKey") cmd.MarkFlagRequired("secretKey")
} }
...@@ -176,12 +223,12 @@ func createConfigPayPubKey(cmd *cobra.Command, args []string) { ...@@ -176,12 +223,12 @@ func createConfigPayPubKey(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName") paraName, _ := cmd.Flags().GetString("paraName")
addr, _ := cmd.Flags().GetString("addr") addr, _ := cmd.Flags().GetString("addr")
receiver, _ := cmd.Flags().GetString("receiver") receiver, _ := cmd.Flags().GetString("receiver")
encryptKey, _ := cmd.Flags().GetString("encryptKey") secretKey, _ := cmd.Flags().GetString("secretKey")
payload := &mixTy.MixConfigAction{} payload := &mixTy.MixConfigAction{}
payload.Ty = mixTy.MixConfigType_Payment payload.Ty = mixTy.MixConfigType_Payment
payload.Value = &mixTy.MixConfigAction_PaymentKey{PaymentKey: &mixTy.PaymentKey{Addr: addr, ReceiverKey: receiver, EncryptKey: encryptKey}} payload.Value = &mixTy.MixConfigAction_NoteAccountKey{NoteAccountKey: &mixTy.NoteAccountKey{Addr: addr, NoteReceiveAddr: receiver, SecretReceiveKey: secretKey}}
params := &rpctypes.CreateTxIn{ params := &rpctypes.CreateTxIn{
Execer: getRealExecName(paraName, mixTy.MixX), Execer: getRealExecName(paraName, mixTy.MixX),
...@@ -473,7 +520,7 @@ func showMixTxs(cmd *cobra.Command, args []string) { ...@@ -473,7 +520,7 @@ func showMixTxs(cmd *cobra.Command, args []string) {
ctx.Run() ctx.Run()
} }
// ShowProposalBoardCmd 显示提案查询信息 // ShowPaymentPubKeyCmd 显示
func ShowPaymentPubKeyCmd() *cobra.Command { func ShowPaymentPubKeyCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "peer", Use: "peer",
...@@ -501,7 +548,7 @@ func showPayment(cmd *cobra.Command, args []string) { ...@@ -501,7 +548,7 @@ func showPayment(cmd *cobra.Command, args []string) {
params.FuncName = "PaymentPubKey" params.FuncName = "PaymentPubKey"
params.Payload = types.MustPBToJSON(&types.ReqString{Data: addr}) params.Payload = types.MustPBToJSON(&types.ReqString{Data: addr})
var resp mixTy.PaymentKey var resp mixTy.NoteAccountKey
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &resp) ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &resp)
ctx.Run() ctx.Run()
} }
...@@ -699,49 +746,49 @@ func SecretCmd() *cobra.Command { ...@@ -699,49 +746,49 @@ func SecretCmd() *cobra.Command {
cmd.AddCommand(DecodeSecretDataCmd()) cmd.AddCommand(DecodeSecretDataCmd())
cmd.AddCommand(EncryptSecretDataCmd()) cmd.AddCommand(EncryptSecretDataCmd())
cmd.AddCommand(DecryptSecretDataCmd()) cmd.AddCommand(DecryptSecretDataCmd())
cmd.AddCommand(DecodePubInputDataCmd()) //cmd.AddCommand(DecodePubInputDataCmd())
return cmd return cmd
} }
// DecodePublicInputDataCmd decode zk public data // DecodePublicInputDataCmd decode zk public data
func DecodePubInputDataCmd() *cobra.Command { //func DecodePubInputDataCmd() *cobra.Command {
cmd := &cobra.Command{ // cmd := &cobra.Command{
Use: "parse", // Use: "parse",
Short: "parse zk public input data", // Short: "parse zk public input data",
Run: decodePubInput, // Run: decodePubInput,
} // }
decodePubInputCmdFlags(cmd) // decodePubInputCmdFlags(cmd)
return cmd // return cmd
} //}
//
func decodePubInputCmdFlags(cmd *cobra.Command) { //func decodePubInputCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("data", "d", "", "public input data") // cmd.Flags().StringP("data", "d", "", "public input data")
cmd.MarkFlagRequired("data") // cmd.MarkFlagRequired("data")
//
cmd.Flags().Int32P("type", "t", 0, "type 0:deposit,1:withdraw,2:transIn,3:transOut,4:auth") // cmd.Flags().Int32P("type", "t", 0, "type 0:deposit,1:withdraw,2:transIn,3:transOut,4:auth")
cmd.MarkFlagRequired("type") // cmd.MarkFlagRequired("type")
//
} //}
//
func decodePubInput(cmd *cobra.Command, args []string) { //func decodePubInput(cmd *cobra.Command, args []string) {
//rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") // //rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
data, _ := cmd.Flags().GetString("data") // data, _ := cmd.Flags().GetString("data")
ty, _ := cmd.Flags().GetInt32("type") // ty, _ := cmd.Flags().GetInt32("type")
//
v, err := mixTy.DecodePubInput(mixTy.VerifyType(ty), data) // v, err := mixTy.DecodePubInput(mixTy.VerifyType(ty), data)
if err != nil { // if err != nil {
fmt.Fprintln(os.Stderr, err) // fmt.Fprintln(os.Stderr, err)
return // return
} // }
//
rst, err := json.MarshalIndent(v, "", " ") // rst, err := json.MarshalIndent(v, "", " ")
if err != nil { // if err != nil {
fmt.Fprintln(os.Stderr, err) // fmt.Fprintln(os.Stderr, err)
return // return
} // }
fmt.Println(string(rst)) // fmt.Println(string(rst))
} //}
// EncodeSecretDataCmd get para chain status by height // EncodeSecretDataCmd get para chain status by height
func DecodeSecretDataCmd() *cobra.Command { func DecodeSecretDataCmd() *cobra.Command {
...@@ -886,10 +933,10 @@ func CreateDepositRawTxCmd() *cobra.Command { ...@@ -886,10 +933,10 @@ func CreateDepositRawTxCmd() *cobra.Command {
} }
func depositSecretCmdFlags(cmd *cobra.Command) { func depositSecretCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("receiver", "r", "", "receiver addrs,seperated by ','") cmd.Flags().StringP("receiver", "t", "", "receiver addrs,seperated by ','")
cmd.MarkFlagRequired("receiver") cmd.MarkFlagRequired("receiver")
cmd.Flags().StringP("return", "f", "", "return addr,optional") cmd.Flags().StringP("return", "r", "", "return addr,optional")
cmd.Flags().StringP("authorize", "a", "", "authorize addr,optional") cmd.Flags().StringP("authorize", "a", "", "authorize addr,optional")
...@@ -904,8 +951,8 @@ func depositSecretCmdFlags(cmd *cobra.Command) { ...@@ -904,8 +951,8 @@ func depositSecretCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("path", "p", "", "deposit circuit path") cmd.Flags().StringP("path", "p", "", "deposit circuit path")
cmd.MarkFlagRequired("path") cmd.MarkFlagRequired("path")
cmd.Flags().Int32P("privacy", "w", 0, "get zk privacy data print, 1:print, default not") cmd.Flags().StringP("proof", "w", "", "proof string to test")
cmd.Flags().Int32P("verify", "v", 0, "verify on chain:0 on local:1, default 0 ") cmd.Flags().BoolP("verify", "v", false, "verify on chain:true on local:false ")
} }
...@@ -920,8 +967,8 @@ func depositSecret(cmd *cobra.Command, args []string) { ...@@ -920,8 +967,8 @@ func depositSecret(cmd *cobra.Command, args []string) {
symbol, _ := cmd.Flags().GetString("symbol") symbol, _ := cmd.Flags().GetString("symbol")
path, _ := cmd.Flags().GetString("path") path, _ := cmd.Flags().GetString("path")
privacy, _ := cmd.Flags().GetInt32("privacy") proof, _ := cmd.Flags().GetString("proof")
verify, _ := cmd.Flags().GetInt32("verify") verify, _ := cmd.Flags().GetBool("verify")
deposit := &mixTy.DepositInfo{ deposit := &mixTy.DepositInfo{
ReceiverAddrs: receiver, ReceiverAddrs: receiver,
...@@ -936,13 +983,13 @@ func depositSecret(cmd *cobra.Command, args []string) { ...@@ -936,13 +983,13 @@ func depositSecret(cmd *cobra.Command, args []string) {
} }
params := &mixTy.CreateRawTxReq{ params := &mixTy.CreateRawTxReq{
ActionTy: mixTy.MixActionDeposit, ActionTy: mixTy.MixActionDeposit,
Data: types.Encode(tx), Data: types.Encode(tx),
AssetExec: assetExec, AssetExec: assetExec,
AssetSymbol: symbol, AssetSymbol: symbol,
Title: paraName, Title: paraName,
Privacy: privacy, ZkProof: proof,
Verify: verify, VerifyOnChain: verify,
} }
ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.CreateRawTransaction", params, nil) ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.CreateRawTransaction", params, nil)
...@@ -979,13 +1026,11 @@ func transferSecretCmdFlags(cmd *cobra.Command) { ...@@ -979,13 +1026,11 @@ func transferSecretCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("exec", "e", "coins", "asset executor(coins, token)") cmd.Flags().StringP("exec", "e", "coins", "asset executor(coins, token)")
cmd.MarkFlagRequired("exec") cmd.MarkFlagRequired("exec")
cmd.Flags().StringP("inpath", "i", "", "input path ") cmd.Flags().StringP("path", "p", "", "input path ")
cmd.MarkFlagRequired("inpath") cmd.MarkFlagRequired("path")
cmd.Flags().StringP("outpath", "o", "", "output pk file ") cmd.Flags().StringP("proof", "w", "", "proof string to test")
cmd.MarkFlagRequired("outpath") cmd.Flags().BoolP("verify", "v", false, "verify on chain:true on local:false, default false ")
cmd.Flags().Int32P("privacy", "w", 0, "get zk privacy data print, 1:print, default not")
cmd.Flags().Int32P("verify", "v", 0, "verify on chain:0 on local:1, default 0 ")
} }
...@@ -998,18 +1043,16 @@ func transferSecret(cmd *cobra.Command, args []string) { ...@@ -998,18 +1043,16 @@ func transferSecret(cmd *cobra.Command, args []string) {
returner, _ := cmd.Flags().GetString("returner") returner, _ := cmd.Flags().GetString("returner")
amount, _ := cmd.Flags().GetString("amount") amount, _ := cmd.Flags().GetString("amount")
inpath, _ := cmd.Flags().GetString("inpath") path, _ := cmd.Flags().GetString("path")
outpath, _ := cmd.Flags().GetString("outpath")
assetExec, _ := cmd.Flags().GetString("exec") assetExec, _ := cmd.Flags().GetString("exec")
symbol, _ := cmd.Flags().GetString("symbol") symbol, _ := cmd.Flags().GetString("symbol")
privacy, _ := cmd.Flags().GetInt32("privacy") proof, _ := cmd.Flags().GetString("proof")
verify, _ := cmd.Flags().GetInt32("verify") verify, _ := cmd.Flags().GetBool("verify")
input := &mixTy.TransferInputTxReq{ input := &mixTy.TransferInputTxReq{
NoteHashs: noteHash, NoteHashs: noteHash,
ZkPath: inpath,
} }
deposit := &mixTy.DepositInfo{ deposit := &mixTy.DepositInfo{
...@@ -1021,22 +1064,22 @@ func transferSecret(cmd *cobra.Command, args []string) { ...@@ -1021,22 +1064,22 @@ func transferSecret(cmd *cobra.Command, args []string) {
output := &mixTy.TransferOutputTxReq{ output := &mixTy.TransferOutputTxReq{
Deposit: deposit, Deposit: deposit,
ZkPath: outpath,
} }
req := &mixTy.TransferTxReq{ req := &mixTy.TransferTxReq{
Input: input, Input: input,
Output: output, Output: output,
ZkPath: path,
} }
params := &mixTy.CreateRawTxReq{ params := &mixTy.CreateRawTxReq{
ActionTy: mixTy.MixActionTransfer, ActionTy: mixTy.MixActionTransfer,
Data: types.Encode(req), Data: types.Encode(req),
AssetExec: assetExec, AssetExec: assetExec,
AssetSymbol: symbol, AssetSymbol: symbol,
Title: paraName, Title: paraName,
Privacy: privacy, ZkProof: proof,
Verify: verify, VerifyOnChain: verify,
} }
ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.CreateRawTransaction", params, nil) ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.CreateRawTransaction", params, nil)
...@@ -1069,8 +1112,8 @@ func withdrawSecretCmdFlags(cmd *cobra.Command) { ...@@ -1069,8 +1112,8 @@ func withdrawSecretCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("path", "p", "", "withdraw pk file ") cmd.Flags().StringP("path", "p", "", "withdraw pk file ")
cmd.MarkFlagRequired("path") cmd.MarkFlagRequired("path")
cmd.Flags().Int32P("privacy", "w", 0, "get zk privacy data print, 1:print, default not") cmd.Flags().StringP("proof", "w", "", "proof string to test")
cmd.Flags().Int32P("verify", "v", 0, "verify on chain:0 on local:1, default 0 ") cmd.Flags().BoolP("verify", "v", false, "verify on chain:true on local:false, default false ")
} }
...@@ -1084,8 +1127,8 @@ func withdrawSecret(cmd *cobra.Command, args []string) { ...@@ -1084,8 +1127,8 @@ func withdrawSecret(cmd *cobra.Command, args []string) {
symbol, _ := cmd.Flags().GetString("symbol") symbol, _ := cmd.Flags().GetString("symbol")
path, _ := cmd.Flags().GetString("path") path, _ := cmd.Flags().GetString("path")
privacy, _ := cmd.Flags().GetInt32("privacy") proof, _ := cmd.Flags().GetString("proof")
verify, _ := cmd.Flags().GetInt32("verify") verify, _ := cmd.Flags().GetBool("verify")
req := &mixTy.WithdrawTxReq{ req := &mixTy.WithdrawTxReq{
TotalAmount: amount, TotalAmount: amount,
...@@ -1094,13 +1137,13 @@ func withdrawSecret(cmd *cobra.Command, args []string) { ...@@ -1094,13 +1137,13 @@ func withdrawSecret(cmd *cobra.Command, args []string) {
} }
params := &mixTy.CreateRawTxReq{ params := &mixTy.CreateRawTxReq{
ActionTy: mixTy.MixActionWithdraw, ActionTy: mixTy.MixActionWithdraw,
Data: types.Encode(req), Data: types.Encode(req),
AssetExec: assetExec, AssetExec: assetExec,
AssetSymbol: symbol, AssetSymbol: symbol,
Title: paraName, Title: paraName,
Privacy: privacy, ZkProof: proof,
Verify: verify, VerifyOnChain: verify,
} }
ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.CreateRawTransaction", params, nil) ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.CreateRawTransaction", params, nil)
...@@ -1133,8 +1176,8 @@ func authSecretCmdFlags(cmd *cobra.Command) { ...@@ -1133,8 +1176,8 @@ func authSecretCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("path", "p", "", "auth path file ") cmd.Flags().StringP("path", "p", "", "auth path file ")
cmd.MarkFlagRequired("path") cmd.MarkFlagRequired("path")
cmd.Flags().Int32P("privacy", "w", 0, "get zk privacy data print, 1:print, default not") cmd.Flags().StringP("proof", "w", "", "proof string to test")
cmd.Flags().Int32P("verify", "v", 0, "verify on chain:0 on local:1, default 0 ") cmd.Flags().BoolP("verify", "v", false, "verify on chain:true on local:false, default false ")
} }
...@@ -1149,8 +1192,8 @@ func authSecret(cmd *cobra.Command, args []string) { ...@@ -1149,8 +1192,8 @@ func authSecret(cmd *cobra.Command, args []string) {
path, _ := cmd.Flags().GetString("path") path, _ := cmd.Flags().GetString("path")
privacy, _ := cmd.Flags().GetInt32("privacy") proof, _ := cmd.Flags().GetString("proof")
verify, _ := cmd.Flags().GetInt32("verify") verify, _ := cmd.Flags().GetBool("verify")
req := &mixTy.AuthTxReq{ req := &mixTy.AuthTxReq{
AuthorizeToAddr: toKey, AuthorizeToAddr: toKey,
...@@ -1159,13 +1202,13 @@ func authSecret(cmd *cobra.Command, args []string) { ...@@ -1159,13 +1202,13 @@ func authSecret(cmd *cobra.Command, args []string) {
} }
params := &mixTy.CreateRawTxReq{ params := &mixTy.CreateRawTxReq{
ActionTy: mixTy.MixActionAuth, ActionTy: mixTy.MixActionAuth,
Data: types.Encode(req), Data: types.Encode(req),
AssetExec: assetExec, AssetExec: assetExec,
AssetSymbol: symbol, AssetSymbol: symbol,
Title: paraName, Title: paraName,
Privacy: privacy, ZkProof: proof,
Verify: verify, VerifyOnChain: verify,
} }
ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.CreateRawTransaction", params, nil) ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.CreateRawTransaction", params, nil)
......
...@@ -5,8 +5,7 @@ ...@@ -5,8 +5,7 @@
package executor package executor
import ( import (
"encoding/hex" "github.com/consensys/gnark/frontend"
"encoding/json"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
...@@ -15,54 +14,36 @@ import ( ...@@ -15,54 +14,36 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
func (a *action) authParamCheck(exec, symbol string, input *mixTy.AuthorizePublicInput) error { func (a *action) authParamCheck(exec, symbol string, input *mixTy.AuthorizeCircuit) error {
//check tree rootHash exist //check tree rootHash exist
exist, err := checkTreeRootHashExist(a.db, exec, symbol, mixTy.Str2Byte(input.TreeRootHash)) treeRootHash := frontend.FromInterface(frontend.GetAssignedValue(input.TreeRootHash))
exist, err := checkTreeRootHashExist(a.db, exec, symbol, mixTy.Str2Byte(treeRootHash.String()))
if err != nil { if err != nil {
return errors.Wrapf(err, "roothash=%s not found,exec=%s,symbol=%s", input.TreeRootHash, exec, symbol) return errors.Wrapf(err, "roothash=%s not found,exec=%s,symbol=%s", treeRootHash.String(), exec, symbol)
} }
if !exist { if !exist {
return errors.Wrapf(mixTy.ErrTreeRootHashNotFound, "roothash=%s", input.TreeRootHash) return errors.Wrapf(mixTy.ErrTreeRootHashNotFound, "roothash=%s", treeRootHash.String())
} }
//authorize key should not exist //authorize key should not exist
authKey := calcAuthorizeHashKey(input.AuthorizeHash) authHash := frontend.FromInterface(frontend.GetAssignedValue(input.AuthorizeHash))
authKey := calcAuthorizeHashKey(authHash.String())
_, err = a.db.Get(authKey) _, err = a.db.Get(authKey)
if err == nil { if err == nil {
return errors.Wrapf(mixTy.ErrAuthorizeHashExist, "auth=%s", input.AuthorizeHash) return errors.Wrapf(mixTy.ErrAuthorizeHashExist, "auth=%s", authHash.String())
} }
if !isNotFound(err) { if !isNotFound(err) {
return errors.Wrapf(err, "get auth=%s", input.AuthorizeHash) return errors.Wrapf(err, "get auth=%s", authHash.String())
} }
//authPubKeys, err := a.getAuthKeys()
//if err != nil {
// return errors.Wrap(err, "get AuthPubkey")
//}
//
////authorize pubkey hash should be configured already
//var found bool
//for _, k := range authPubKeys.Keys {
// if input.AuthorizePubKey == k {
// found = true
// break
// }
//}
//if !found {
// return errors.Wrapf(types.ErrNotFound, "authPubkey=%s", input.AuthorizePubKey)
//}
return nil return nil
} }
func (a *action) authorizeVerify(exec, symbol string, proof *mixTy.ZkProofInfo) (*mixTy.AuthorizePublicInput, error) { func (a *action) authorizePubInputs(exec, symbol string, proof *mixTy.ZkProofInfo) (*mixTy.AuthorizeCircuit, error) {
var input mixTy.AuthorizePublicInput var input mixTy.AuthorizeCircuit
data, err := hex.DecodeString(proof.PublicInput) err := mixTy.ConstructCircuitPubInput(proof.PublicInput, &input)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "decode string=%s", proof.PublicInput) return nil, errors.Wrapf(err, "setCircuitPubInput")
}
err = json.Unmarshal(data, &input)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal string=%s", proof.PublicInput)
} }
err = a.authParamCheck(exec, symbol, &input) err = a.authParamCheck(exec, symbol, &input)
...@@ -70,12 +51,6 @@ func (a *action) authorizeVerify(exec, symbol string, proof *mixTy.ZkProofInfo) ...@@ -70,12 +51,6 @@ func (a *action) authorizeVerify(exec, symbol string, proof *mixTy.ZkProofInfo)
return nil, err return nil, err
} }
//zk-proof校验
err = zkProofVerify(a.db, proof, mixTy.VerifyType_AUTHORIZE)
if err != nil {
return nil, err
}
return &input, nil return &input, nil
} }
...@@ -88,26 +63,27 @@ func (a *action) authorizeVerify(exec, symbol string, proof *mixTy.ZkProofInfo) ...@@ -88,26 +63,27 @@ func (a *action) authorizeVerify(exec, symbol string, proof *mixTy.ZkProofInfo)
5. set authorize hash and authorize_spend hash 5. set authorize hash and authorize_spend hash
*/ */
func (a *action) Authorize(authorize *mixTy.MixAuthorizeAction) (*types.Receipt, error) { func (a *action) Authorize(authorize *mixTy.MixAuthorizeAction) (*types.Receipt, error) {
var inputs []*mixTy.AuthorizePublicInput
execer, symbol := mixTy.GetAssetExecSymbol(a.api.GetConfig(), authorize.AssetExec, authorize.AssetSymbol) execer, symbol := mixTy.GetAssetExecSymbol(a.api.GetConfig(), authorize.AssetExec, authorize.AssetSymbol)
in, err := a.authorizeVerify(execer, symbol, authorize.Proof) input, err := a.authorizePubInputs(execer, symbol, authorize.ProofInfo)
if err != nil { if err != nil {
return nil, err return nil, err
} }
inputs = append(inputs, in)
receipt := &types.Receipt{Ty: types.ExecOk} //zk-proof校验
var auths, authSpends []string err = zkProofVerify(a.db, authorize.ProofInfo, mixTy.VerifyType_AUTHORIZE)
for _, in := range inputs { if err != nil {
r := makeReceipt(calcAuthorizeHashKey(in.AuthorizeHash), mixTy.TyLogAuthorizeSet, &mixTy.ExistValue{Nullifier: in.AuthorizeHash, Exist: true}) return nil, err
mergeReceipt(receipt, r)
r = makeReceipt(calcAuthorizeSpendHashKey(in.AuthorizeSpendHash), mixTy.TyLogAuthorizeSpendSet, &mixTy.ExistValue{Nullifier: in.AuthorizeSpendHash, Exist: true})
mergeReceipt(receipt, r)
auths = append(auths, in.AuthorizeHash)
authSpends = append(authSpends, in.AuthorizeSpendHash)
} }
receipt := &types.Receipt{Ty: types.ExecOk}
authNullHash := frontend.FromInterface(frontend.GetAssignedValue(input.AuthorizeHash))
r := makeReceipt(calcAuthorizeHashKey(authNullHash.String()), mixTy.TyLogAuthorizeSet, &mixTy.ExistValue{Nullifier: authNullHash.String(), Exist: true})
mergeReceipt(receipt, r)
authSpendHash := frontend.FromInterface(frontend.GetAssignedValue(input.AuthorizeSpendHash))
r = makeReceipt(calcAuthorizeSpendHashKey(authSpendHash.String()), mixTy.TyLogAuthorizeSpendSet, &mixTy.ExistValue{Nullifier: authSpendHash.String(), Exist: true})
mergeReceipt(receipt, r)
return receipt, nil return receipt, nil
} }
...@@ -12,7 +12,7 @@ import ( ...@@ -12,7 +12,7 @@ import (
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/mix/executor/merkletree" "github.com/33cn/plugin/plugin/dapp/mix/executor/merkletree"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gnark/crypto/hash/mimc/bn256" "github.com/consensys/gnark-crypto/ecc/bn254/fr/mimc"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
...@@ -95,7 +95,7 @@ func getArchiveRoots(db dbm.KV, exec, symbol string, seq uint64) (*mixTy.CommitT ...@@ -95,7 +95,7 @@ func getArchiveRoots(db dbm.KV, exec, symbol string, seq uint64) (*mixTy.CommitT
//TODO seed config //TODO seed config
func getNewTree() *merkletree.Tree { func getNewTree() *merkletree.Tree {
return merkletree.New(bn256.NewMiMC("seed")) return merkletree.New(mimc.NewMiMC("seed"))
} }
func calcTreeRoot(leaves *mixTy.CommitTreeLeaves) []byte { func calcTreeRoot(leaves *mixTy.CommitTreeLeaves) []byte {
......
...@@ -7,24 +7,25 @@ package executor ...@@ -7,24 +7,25 @@ package executor
import ( import (
"testing" "testing"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
/* /*
leaf0 = "16308793397024662832064523892418908145900866571524124093537199035808550255649" leaf0 = "16308793397024662832064523892418908145900866571524124093537199035808550255649"
hexstr 240e732fc90c3a88a11f3f60bbbe412f6b4b56d007cf34fdb2500195071c7c21 hash 4010939160279929375357088561050093294975728828994381439611270589357856115894
leaf1 = 21467822781369104390668289189963532506973289112396605437823854946060028754354 leaf1 = 21467822781369104390668289189963532506973289112396605437823854946060028754354
leaf hash 17799daf83d82530d70343bc44578bdabafcb134332d4949883695a1ec9d1ba9 leaf hash 19846868408490658463513283235031798083935100648624648285566873440653365397815
leaf2= 4178471437305290899835614805415999986197321812505352791035422725360758750328 leaf2= 4178471437305290899835614805415999986197321812505352791035422725360758750328
leaf hash 29ded1ba9ed45d829f458ce511e013a8d11058db9d6f03fea14267082087b151 leaf hash 4062509694129705639089082212179777344962624935939361647381392834235969534831
leaf3= 10407830929890509544473717262275616077696950294748419792758056545898949331744 leaf3= 10407830929890509544473717262275616077696950294748419792758056545898949331744
leaf hash 1b757026b07fd17150c5d23081bddd52e77dc26b0c7c46b4e0150ca7ccfed35a leaf hash 3656010751855274388516368747583374746848682779395325737100877017850943546836
leaf4= 11032604436245646157001636966356016502073301224837385665550497706958264582086 leaf4= 11032604436245646157001636966356016502073301224837385665550497706958264582086
leaf hash 24a8d61af8e16abaf9ccb1051c882799121c6ece1094655b5b93f837aead2f30 leaf hash 5949485921924623528448830799540295699445001672535082168235329176256394356669
merkleroot= 6988991286454436061784929049510388415076132311642532433013500389938249229356 merkleroot= 6988991286454436061784929049510388415076132311642532433013500389938249229356
0 proof str= 21467822781369104390668289189963532506973289112396605437823854946060028754354 0 proof str= 21467822781369104390668289189963532506973289112396605437823854946060028754354
...@@ -44,25 +45,25 @@ func TestGetProveData(t *testing.T) { ...@@ -44,25 +45,25 @@ func TestGetProveData(t *testing.T) {
proves := []string{ proves := []string{
"21467822781369104390668289189963532506973289112396605437823854946060028754354", "21467822781369104390668289189963532506973289112396605437823854946060028754354",
"12096317366724227951683802305909172775715878134489527031786909074403605889217", "4010939160279929375357088561050093294975728828994381439611270589357856115894",
"14541527209424185878803689752018034974129079647509824805270353433359922459228", "19203142125680456902129919467753534834062383756119332074615431762320316227830",
"16581570556767364549626991605903512613557832602774591000372759906303762837296", "5949485921924623528448830799540295699445001672535082168235329176256394356669",
} }
var leave [][]byte var leave [][]byte
for _, l := range leaves { for _, l := range leaves {
leave = append(leave, transferFr2Bytes(l)) leave = append(leave, mixTy.Str2Byte(l))
} }
ret, err := getProveData(leave[1], leave) ret, err := getProveData(leave[1], leave)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, uint32(5), ret.NumLeaves) assert.Equal(t, uint32(5), ret.NumLeaves)
assert.Equal(t, uint32(1), ret.ProofIndex) assert.Equal(t, uint32(1), ret.ProofIndex)
assert.Equal(t, "6988991286454436061784929049510388415076132311642532433013500389938249229356", ret.RootHash) assert.Equal(t, "12154966389094759868987627011400429400046999538507894392248611367616715657246", ret.RootHash)
assert.Equal(t, len(proves), len(ret.ProofSet)) assert.Equal(t, len(proves), len(ret.ProofSet))
for i, k := range proves { for i, k := range proves {
assert.Equal(t, k, ret.ProofSet[i]) assert.Equal(t, k, ret.ProofSet[i])
} }
assert.Equal(t, "0,1,1", ret.Helpers) assert.Equal(t, []uint32([]uint32{0, 1, 1}), ret.Helpers)
} }
...@@ -45,7 +45,7 @@ func (a *action) Config(config *mixTy.MixConfigAction) (*types.Receipt, error) { ...@@ -45,7 +45,7 @@ func (a *action) Config(config *mixTy.MixConfigAction) (*types.Receipt, error) {
} }
case mixTy.MixConfigType_Payment: case mixTy.MixConfigType_Payment:
//个人配置,个人负责,可重配 //个人配置,个人负责,可重配
return a.ConfigPaymentPubKey(config.GetPaymentKey()) return a.ConfigPaymentPubKey(config.GetNoteAccountKey())
} }
return nil, errors.Wrapf(types.ErrNotFound, "ty=%d", config.Ty) return nil, errors.Wrapf(types.ErrNotFound, "ty=%d", config.Ty)
...@@ -157,7 +157,7 @@ func (a *action) ConfigDeleteAuthPubKey(key string) (*types.Receipt, error) { ...@@ -157,7 +157,7 @@ func (a *action) ConfigDeleteAuthPubKey(key string) (*types.Receipt, error) {
return makeConfigAuthKeyReceipt(&newKeys), nil return makeConfigAuthKeyReceipt(&newKeys), nil
} }
func makeConfigPaymentKeyReceipt(data *mixTy.PaymentKey) *types.Receipt { func makeConfigPaymentKeyReceipt(data *mixTy.NoteAccountKey) *types.Receipt {
key := calcReceivingKey(data.Addr) key := calcReceivingKey(data.Addr)
return &types.Receipt{ return &types.Receipt{
Ty: types.ExecOk, Ty: types.ExecOk,
...@@ -171,13 +171,13 @@ func makeConfigPaymentKeyReceipt(data *mixTy.PaymentKey) *types.Receipt { ...@@ -171,13 +171,13 @@ func makeConfigPaymentKeyReceipt(data *mixTy.PaymentKey) *types.Receipt {
} }
func GetPaymentPubKey(db dbm.KV, addr string) (*mixTy.PaymentKey, error) { func GetPaymentPubKey(db dbm.KV, addr string) (*mixTy.NoteAccountKey, error) {
key := calcReceivingKey(addr) key := calcReceivingKey(addr)
v, err := db.Get(key) v, err := db.Get(key)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "get db") return nil, errors.Wrapf(err, "get db")
} }
var keys mixTy.PaymentKey var keys mixTy.NoteAccountKey
err = types.Decode(v, &keys) err = types.Decode(v, &keys)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "decode db key") return nil, errors.Wrapf(err, "decode db key")
...@@ -186,8 +186,8 @@ func GetPaymentPubKey(db dbm.KV, addr string) (*mixTy.PaymentKey, error) { ...@@ -186,8 +186,8 @@ func GetPaymentPubKey(db dbm.KV, addr string) (*mixTy.PaymentKey, error) {
return &keys, nil return &keys, nil
} }
func (a *action) ConfigPaymentPubKey(paykey *mixTy.PaymentKey) (*types.Receipt, error) { func (a *action) ConfigPaymentPubKey(paykey *mixTy.NoteAccountKey) (*types.Receipt, error) {
if paykey == nil || len(paykey.ReceiverKey) == 0 || len(paykey.EncryptKey) == 0 || len(paykey.Addr) == 0 { if paykey == nil || len(paykey.NoteReceiveAddr) == 0 || len(paykey.SecretReceiveKey) == 0 || len(paykey.Addr) == 0 {
return nil, errors.Wrapf(types.ErrInvalidParam, "pubkey=%v", paykey) return nil, errors.Wrapf(types.ErrInvalidParam, "pubkey=%v", paykey)
} }
//检查用户使用对应的addr的key,但不能确保key就是对应addr //检查用户使用对应的addr的key,但不能确保key就是对应addr
...@@ -195,9 +195,9 @@ func (a *action) ConfigPaymentPubKey(paykey *mixTy.PaymentKey) (*types.Receipt, ...@@ -195,9 +195,9 @@ func (a *action) ConfigPaymentPubKey(paykey *mixTy.PaymentKey) (*types.Receipt,
return nil, errors.Wrapf(types.ErrInvalidParam, "register addr=%s not match with sign=%s", paykey.Addr, a.fromaddr) return nil, errors.Wrapf(types.ErrInvalidParam, "register addr=%s not match with sign=%s", paykey.Addr, a.fromaddr)
} }
//直接覆盖 //直接覆盖
return makeConfigPaymentKeyReceipt(&mixTy.PaymentKey{ return makeConfigPaymentKeyReceipt(&mixTy.NoteAccountKey{
Addr: a.fromaddr, Addr: a.fromaddr,
ReceiverKey: paykey.ReceiverKey, NoteReceiveAddr: paykey.NoteReceiveAddr,
EncryptKey: paykey.EncryptKey}), nil SecretReceiveKey: paykey.SecretReceiveKey}), nil
} }
...@@ -5,15 +5,10 @@ ...@@ -5,15 +5,10 @@
package executor package executor
import ( import (
"encoding/hex"
"encoding/json"
"strconv"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/mix/executor/zksnark"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gnark/frontend"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"github.com/pkg/errors" "github.com/pkg/errors"
...@@ -24,55 +19,20 @@ func makeNullifierSetReceipt(hash string, data proto.Message) *types.Receipt { ...@@ -24,55 +19,20 @@ func makeNullifierSetReceipt(hash string, data proto.Message) *types.Receipt {
} }
func zkProofVerify(db dbm.KV, proof *mixTy.ZkProofInfo, ty mixTy.VerifyType) error { func (a *action) depositVerify(proof *mixTy.ZkProofInfo) (*mixTy.DepositCircuit, error) {
keys, err := getVerifyKeys(db, int32(ty)) var input mixTy.DepositCircuit
if err != nil {
return err
}
var pass bool
for _, verifyKey := range keys.Data {
ok, err := zksnark.Verify(verifyKey.Value, proof.Proof, proof.PublicInput)
if err != nil {
return err
}
if !ok {
continue
}
pass = true
break
}
if !pass {
return errors.Wrap(mixTy.ErrZkVerifyFail, "verify")
}
return nil
}
func (a *action) depositVerify(proof *mixTy.ZkProofInfo) (string, uint64, error) { err := mixTy.ConstructCircuitPubInput(proof.PublicInput, &input)
var input mixTy.DepositPublicInput
data, err := hex.DecodeString(proof.PublicInput)
if err != nil {
return "", 0, errors.Wrapf(err, "decode string=%s", proof.PublicInput)
}
err = json.Unmarshal(data, &input)
if err != nil {
return "", 0, errors.Wrapf(err, "unmarshal string=%s", proof.PublicInput)
}
val, err := strconv.ParseUint(input.Amount, 10, 64)
if err != nil { if err != nil {
return "", 0, errors.Wrapf(err, "parseUint=%s", input.Amount) return nil, errors.Wrapf(err, "setCircuitPubInput")
}
if val <= 0 {
return "", 0, errors.Wrapf(err, "amount=%d should >0", val)
} }
err = zkProofVerify(a.db, proof, mixTy.VerifyType_DEPOSIT) err = zkProofVerify(a.db, proof, mixTy.VerifyType_DEPOSIT)
if err != nil { if err != nil {
return "", 0, err return nil, errors.Wrapf(err, "verify fail for input=%s", proof.PublicInput)
} }
return input.NoteHash, val, nil return &input, nil
} }
...@@ -87,12 +47,14 @@ func (a *action) Deposit(deposit *mixTy.MixDepositAction) (*types.Receipt, error ...@@ -87,12 +47,14 @@ func (a *action) Deposit(deposit *mixTy.MixDepositAction) (*types.Receipt, error
var sum uint64 var sum uint64
//1. zk-proof校验 //1. zk-proof校验
for _, p := range deposit.Proofs { for _, p := range deposit.Proofs {
noteHash, amount, err := a.depositVerify(p) input, err := a.depositVerify(p)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "verify fail for input=%s", p.PublicInput) return nil, errors.Wrap(err, "get pub input")
} }
sum += amount v := frontend.FromInterface(frontend.GetAssignedValue(input.Amount))
notes = append(notes, noteHash) sum += v.Uint64()
noteHash := frontend.FromInterface(frontend.GetAssignedValue(input.NoteHash))
notes = append(notes, noteHash.String())
} }
//存款 //存款
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
package merkletree package merkletree
import ( import (
"encoding/hex"
"errors" "errors"
"fmt" "fmt"
"hash" "hash"
...@@ -198,7 +197,7 @@ func (t *Tree) Push(data []byte) { ...@@ -198,7 +197,7 @@ func (t *Tree) Push(data []byte) {
t.head.sum = data t.head.sum = data
} else { } else {
t.head.sum = leafSum(t.hash, data) t.head.sum = leafSum(t.hash, data)
fmt.Println("leaf hash", hex.EncodeToString(t.head.sum)) //fmt.Println("leaf hash", mixTy.Byte2Str(t.head.sum))
} }
// Join subTrees if possible. // Join subTrees if possible.
......
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package merkletree
import (
"fmt"
"github.com/stretchr/testify/assert"
"testing"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gnark-crypto/ecc/bn254/fr/mimc"
)
func TestLeafHash(t *testing.T) {
leaves := []string{
"16308793397024662832064523892418908145900866571524124093537199035808550255649",
}
h := mimc.NewMiMC("seed")
s := leafSum(h, mixTy.Str2Byte(leaves[0]))
assert.Equal(t, "4010939160279929375357088561050093294975728828994381439611270589357856115894", mixTy.Byte2Str(s))
leaves = []string{
"4062509694129705639089082212179777344962624935939361647381392834235969534831",
"3656010751855274388516368747583374746848682779395325737100877017850943546836",
}
h.Reset()
s = nodeSum(h, mixTy.Str2Byte(leaves[0]), mixTy.Str2Byte(leaves[1]))
assert.Equal(t, "19203142125680456902129919467753534834062383756119332074615431762320316227830", mixTy.Byte2Str(s))
proves := []string{
"21467822781369104390668289189963532506973289112396605437823854946060028754354",
"4010939160279929375357088561050093294975728828994381439611270589357856115894",
"19203142125680456902129919467753534834062383756119332074615431762320316227830",
"5949485921924623528448830799540295699445001672535082168235329176256394356669",
}
var sum []byte
for i, l := range proves {
if len(sum) == 0 {
sum = leafSum(h, mixTy.Str2Byte(l))
continue
}
//第0个leaf在第一个leaf的右侧,需要调整顺序
if i < 2 {
sum = nodeSum(h, mixTy.Str2Byte(l), sum)
continue
}
sum = nodeSum(h, sum, mixTy.Str2Byte(l))
}
fmt.Println("sum", mixTy.Byte2Str(sum))
}
...@@ -5,14 +5,13 @@ ...@@ -5,14 +5,13 @@
package executor package executor
import ( import (
"encoding/hex" "github.com/consensys/gnark/frontend"
"encoding/json"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gurvy/bn256/twistededwards" "github.com/consensys/gnark-crypto/ecc/bn254/twistededwards"
dbm "github.com/33cn/chain33/common/db" dbm "github.com/33cn/chain33/common/db"
"github.com/pkg/errors" "github.com/pkg/errors"
...@@ -23,18 +22,17 @@ import ( ...@@ -23,18 +22,17 @@ import (
2. check if exist in authorize pool and nullifier pool 2. check if exist in authorize pool and nullifier pool
*/ */
func transferInputVerify(db dbm.KV, execer, symbol string, proof *mixTy.ZkProofInfo) (*mixTy.TransferInputPublicInput, error) { func transferInput(db dbm.KV, execer, symbol string, proof *mixTy.ZkProofInfo) (*mixTy.TransferInputCircuit, error) {
var input mixTy.TransferInputPublicInput var input mixTy.TransferInputCircuit
data, err := hex.DecodeString(proof.PublicInput) err := mixTy.ConstructCircuitPubInput(proof.PublicInput, &input)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "transferInput verify decode string=%s", proof.PublicInput) return nil, errors.Wrapf(err, "decode string=%s", proof.PublicInput)
}
err = json.Unmarshal(data, &input)
if err != nil {
return nil, errors.Wrapf(err, "transferInput verify unmarshal string=%s", proof.PublicInput)
} }
err = spendVerify(db, execer, symbol, input.TreeRootHash, input.NullifierHash, input.AuthorizeSpendHash) treeRootHash := frontend.FromInterface(frontend.GetAssignedValue(input.TreeRootHash))
nullifierHash := frontend.FromInterface(frontend.GetAssignedValue(input.NullifierHash))
authSpendHash := frontend.FromInterface(frontend.GetAssignedValue(input.AuthorizeSpendHash))
err = spendVerify(db, execer, symbol, treeRootHash.String(), nullifierHash.String(), authSpendHash.String())
if err != nil { if err != nil {
return nil, errors.Wrap(err, "transferInput verify spendVerify") return nil, errors.Wrap(err, "transferInput verify spendVerify")
} }
...@@ -53,17 +51,12 @@ func transferInputVerify(db dbm.KV, execer, symbol string, proof *mixTy.ZkProofI ...@@ -53,17 +51,12 @@ func transferInputVerify(db dbm.KV, execer, symbol string, proof *mixTy.ZkProofI
2. check if exist in authorize pool and nullifier pool 2. check if exist in authorize pool and nullifier pool
*/ */
func transferOutputVerify(db dbm.KV, proof *mixTy.ZkProofInfo) (*mixTy.TransferOutputPublicInput, error) { func transferOutputVerify(db dbm.KV, proof *mixTy.ZkProofInfo) (*mixTy.TransferOutputCircuit, error) {
var input mixTy.TransferOutputPublicInput var input mixTy.TransferOutputCircuit
data, err := hex.DecodeString(proof.PublicInput) err := mixTy.ConstructCircuitPubInput(proof.PublicInput, &input)
if err != nil {
return nil, errors.Wrapf(err, "Output verify decode string=%s", proof.PublicInput)
}
err = json.Unmarshal(data, &input)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "Output verify unmarshal string=%s", proof.PublicInput) return nil, errors.Wrapf(err, "decode string=%s", proof.PublicInput)
} }
err = zkProofVerify(db, proof, mixTy.VerifyType_TRANSFEROUTPUT) err = zkProofVerify(db, proof, mixTy.VerifyType_TRANSFEROUTPUT)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "Output verify proof verify") return nil, errors.Wrap(err, "Output verify proof verify")
...@@ -73,19 +66,19 @@ func transferOutputVerify(db dbm.KV, proof *mixTy.ZkProofInfo) (*mixTy.TransferO ...@@ -73,19 +66,19 @@ func transferOutputVerify(db dbm.KV, proof *mixTy.ZkProofInfo) (*mixTy.TransferO
} }
func VerifyCommitValues(inputs []*mixTy.TransferInputPublicInput, outputs []*mixTy.TransferOutputPublicInput, txFee uint64) bool { func VerifyCommitValues(inputs []*mixTy.TransferInputCircuit, outputs []*mixTy.TransferOutputCircuit, txFee uint64) bool {
var inputPoints, outputPoints []*twistededwards.Point var inputPoints, outputPoints []*twistededwards.PointAffine
for _, in := range inputs { for _, in := range inputs {
var p twistededwards.Point var p twistededwards.PointAffine
p.X.SetString(in.ShieldAmountX) p.X.SetInterface(frontend.GetAssignedValue(in.ShieldAmountX))
p.Y.SetString(in.ShieldAmountY) p.Y.SetInterface(frontend.GetAssignedValue(in.ShieldAmountY))
inputPoints = append(inputPoints, &p) inputPoints = append(inputPoints, &p)
} }
for _, out := range outputs { for _, out := range outputs {
var p twistededwards.Point var p twistededwards.PointAffine
p.X.SetString(out.ShieldAmountX) p.X.SetInterface(frontend.GetAssignedValue(out.ShieldAmountX))
p.Y.SetString(out.ShieldAmountY) p.Y.SetInterface(frontend.GetAssignedValue(out.ShieldAmountY))
outputPoints = append(outputPoints, &p) outputPoints = append(outputPoints, &p)
} }
//out value add fee //out value add fee
...@@ -109,19 +102,20 @@ func VerifyCommitValues(inputs []*mixTy.TransferInputPublicInput, outputs []*mix ...@@ -109,19 +102,20 @@ func VerifyCommitValues(inputs []*mixTy.TransferInputPublicInput, outputs []*mix
return false return false
} }
func MixTransferInfoVerify(cfg *types.Chain33Config, db dbm.KV, transfer *mixTy.MixTransferAction) ([]*mixTy.TransferInputPublicInput, []*mixTy.TransferOutputPublicInput, error) { func MixTransferInfoVerify(cfg *types.Chain33Config, db dbm.KV, transfer *mixTy.MixTransferAction) ([]*mixTy.TransferInputCircuit, []*mixTy.TransferOutputCircuit, error) {
var inputs []*mixTy.TransferInputPublicInput var inputs []*mixTy.TransferInputCircuit
var outputs []*mixTy.TransferOutputPublicInput var outputs []*mixTy.TransferOutputCircuit
execer, symbol := mixTy.GetAssetExecSymbol(cfg, transfer.AssetExec, transfer.AssetSymbol) execer, symbol := mixTy.GetAssetExecSymbol(cfg, transfer.AssetExec, transfer.AssetSymbol)
txFee := mixTy.GetTransferTxFee(cfg, execer) txFee := mixTy.GetTransferTxFee(cfg, execer)
//inputs //inputs
for _, i := range transfer.Inputs { for _, i := range transfer.Inputs {
in, err := transferInputVerify(db, execer, symbol, i) in, err := transferInput(db, execer, symbol, i)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
inputs = append(inputs, in) inputs = append(inputs, in)
} }
//output //output
...@@ -196,14 +190,16 @@ func (a *action) Transfer(transfer *mixTy.MixTransferAction) (*types.Receipt, er ...@@ -196,14 +190,16 @@ func (a *action) Transfer(transfer *mixTy.MixTransferAction) (*types.Receipt, er
mergeReceipt(receipt, rTxFee) mergeReceipt(receipt, rTxFee)
for _, k := range inputs { for _, k := range inputs {
r := makeNullifierSetReceipt(k.NullifierHash, &mixTy.ExistValue{Nullifier: k.NullifierHash, Exist: true}) nullHash := frontend.FromInterface(frontend.GetAssignedValue(k.NullifierHash))
r := makeNullifierSetReceipt(nullHash.String(), &mixTy.ExistValue{Nullifier: nullHash.String(), Exist: true})
mergeReceipt(receipt, r) mergeReceipt(receipt, r)
} }
//push new commit to merkle tree //push new commit to merkle tree
var leaves [][]byte var leaves [][]byte
for _, h := range outputs { for _, h := range outputs {
leaves = append(leaves, mixTy.Str2Byte(h.NoteHash)) noteHash := frontend.FromInterface(frontend.GetAssignedValue(h.NoteHash))
leaves = append(leaves, mixTy.Str2Byte(noteHash.String()))
} }
conf := types.ConfSub(a.api.GetConfig(), mixTy.MixX) conf := types.ConfSub(a.api.GetConfig(), mixTy.MixX)
......
...@@ -5,130 +5,112 @@ ...@@ -5,130 +5,112 @@
package executor package executor
import ( import (
"math/big"
"testing" "testing"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gurvy/bn256/fr" "github.com/consensys/gnark-crypto/ecc/bn254/twistededwards"
bn256 "github.com/consensys/gurvy/bn256/twistededwards"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
const ( const (
baseHX = "10190477835300927557649934238820360529458681672073866116232821892325659279502" baseHX = "9252662952969393856711468743327022054484546162727338092576697495684140272191"
baseHY = "7969140283216448215269095418467361784159407896899334866715345504515077887397" baseHY = "8220002160263982499510761441032261960817037857915665984040705585999508400744"
fee = 100000 fee = 100000
) )
func TestVerifyCommitValuesBasePoint(t *testing.T) { func TestVerifyCommitValuesBasePoint(t *testing.T) {
var in44, out10, out34, rIn100, rOut40, rOut60 fr.Element var in44, out10, out34 big.Int
//calc p1=44*G+100*G, p2=10*G+30*G,p3=34*G+70*G, p1=p2+p3+fee //calc p1=44*G+100*G, p2=10*G+30*G,p3=34*G+70*G, p1=p2+p3+fee
in44.SetUint64(4400000).FromMont() in44.SetUint64(4400000)
out10.SetUint64(1000000).FromMont() out10.SetUint64(1000000)
out34.SetUint64(3400000 - fee).FromMont() out34.SetUint64(3400000 - fee)
rIn100.SetUint64(10000000).FromMont() ed := twistededwards.GetEdwardsCurve()
rOut40.SetUint64(3000000).FromMont() var p1, p2, p3 twistededwards.PointAffine
rOut60.SetUint64(7000000).FromMont() p1.ScalarMul(&ed.Base, &in44)
p2.ScalarMul(&ed.Base, &out10)
ed := bn256.GetEdwardsCurve() p3.ScalarMul(&ed.Base, &out34)
var p1, p2, p3, r1, r2, r3 bn256.Point
p1.ScalarMul(&ed.Base, in44) //t.Log("p1.x", p1.X.String())
p2.ScalarMul(&ed.Base, out10) //t.Log("p1.y", p1.Y.String())
p3.ScalarMul(&ed.Base, out34) //t.Log("p2.x", p2.X.String())
r1.ScalarMul(&ed.Base, rIn100) //t.Log("p2.y", p2.Y.String())
r2.ScalarMul(&ed.Base, rOut40) //t.Log("p3.x", p3.X.String())
r3.ScalarMul(&ed.Base, rOut60) //t.Log("p3.y", p3.Y.String())
//p1.Add(&p1,&r1) var input1 mixTy.TransferInputCircuit
//p2.Add(&p2,&r2) input1.ShieldAmountX.Assign(p1.X.String())
//p3.Add(&p3,&r3) input1.ShieldAmountY.Assign(p1.Y.String())
t.Log("p1.x", p1.X.String()) var inputs []*mixTy.TransferInputCircuit
t.Log("p1.y", p1.Y.String()) inputs = append(inputs, &input1)
t.Log("p2.x", p2.X.String())
t.Log("p2.y", p2.Y.String()) var output1, output2 mixTy.TransferOutputCircuit
t.Log("p3.x", p3.X.String()) output1.ShieldAmountX.Assign(p2.X.String())
t.Log("p3.y", p3.Y.String()) output1.ShieldAmountY.Assign(p2.Y.String())
input1 := &mixTy.TransferInputPublicInput{
ShieldAmountX: p1.X.String(), output2.ShieldAmountX.Assign(p3.X.String())
ShieldAmountY: p1.Y.String(), output2.ShieldAmountY.Assign(p3.Y.String())
}
var outputs []*mixTy.TransferOutputCircuit
var inputs []*mixTy.TransferInputPublicInput outputs = append(outputs, &output1)
inputs = append(inputs, input1) outputs = append(outputs, &output2)
output1 := &mixTy.TransferOutputPublicInput{ ret := VerifyCommitValues(inputs, outputs, fee)
ShieldAmountX: p2.X.String(),
ShieldAmountY: p2.Y.String(),
}
output2 := &mixTy.TransferOutputPublicInput{
ShieldAmountX: p3.X.String(),
ShieldAmountY: p3.Y.String(),
}
var outputs []*mixTy.TransferOutputPublicInput
outputs = append(outputs, output1)
outputs = append(outputs, output2)
ret := VerifyCommitValues(inputs, outputs)
assert.Equal(t, true, ret) assert.Equal(t, true, ret)
} }
func TestVerifyCommitValuesBaseAddHPoint(t *testing.T) { func TestVerifyCommitValuesBaseAddHPoint(t *testing.T) {
var in44, out10, out34 fr.Element var in44, out10, out34 big.Int
in44.SetUint64(4400000).FromMont() in44.SetUint64(4400000)
out10.SetUint64(1000000).FromMont() out10.SetUint64(1000000)
out34.SetUint64(3400000 - fee).FromMont() out34.SetUint64(3400000 - fee)
//random value //random value
var rIn100, rOut40, rOut60 fr.Element var rIn100, rOut40, rOut60 big.Int
rIn100.SetUint64(10000000).FromMont() rIn100.SetUint64(10000000)
rOut40.SetUint64(3000000).FromMont() rOut40.SetUint64(3000000)
rOut60.SetUint64(7000000).FromMont() rOut60.SetUint64(7000000)
var baseH bn256.Point var baseH twistededwards.PointAffine
baseH.X.SetString(baseHX) baseH.X.SetString(baseHX)
baseH.Y.SetString(baseHY) baseH.Y.SetString(baseHY)
ed := bn256.GetEdwardsCurve() ed := twistededwards.GetEdwardsCurve()
var p1, p2, p3, r1, r2, r3 bn256.Point var p1, p2, p3, r1, r2, r3 twistededwards.PointAffine
p1.ScalarMul(&ed.Base, in44) p1.ScalarMul(&ed.Base, &in44)
p2.ScalarMul(&ed.Base, out10) p2.ScalarMul(&ed.Base, &out10)
p3.ScalarMul(&ed.Base, out34) p3.ScalarMul(&ed.Base, &out34)
r1.ScalarMul(&baseH, rIn100) r1.ScalarMul(&baseH, &rIn100)
r2.ScalarMul(&baseH, rOut40) r2.ScalarMul(&baseH, &rOut40)
r3.ScalarMul(&baseH, rOut60) r3.ScalarMul(&baseH, &rOut60)
p1.Add(&p1, &r1) p1.Add(&p1, &r1)
p2.Add(&p2, &r2) p2.Add(&p2, &r2)
p3.Add(&p3, &r3) p3.Add(&p3, &r3)
input1 := &mixTy.TransferInputPublicInput{ var input1 mixTy.TransferInputCircuit
ShieldAmountX: p1.X.String(), input1.ShieldAmountX.Assign(p1.X.String())
ShieldAmountY: p1.Y.String(), input1.ShieldAmountY.Assign(p1.Y.String())
}
var inputs []*mixTy.TransferInputPublicInput var inputs []*mixTy.TransferInputCircuit
inputs = append(inputs, input1) inputs = append(inputs, &input1)
output1 := &mixTy.TransferOutputPublicInput{ var output1, output2 mixTy.TransferOutputCircuit
ShieldAmountX: p2.X.String(), output1.ShieldAmountX.Assign(p2.X.String())
ShieldAmountY: p2.Y.String(), output1.ShieldAmountY.Assign(p2.Y.String())
}
output2 := &mixTy.TransferOutputPublicInput{ output2.ShieldAmountX.Assign(p3.X.String())
ShieldAmountX: p3.X.String(), output2.ShieldAmountY.Assign(p3.Y.String())
ShieldAmountY: p3.Y.String(),
}
var outputs []*mixTy.TransferOutputPublicInput var outputs []*mixTy.TransferOutputCircuit
outputs = append(outputs, output1) outputs = append(outputs, &output1)
outputs = append(outputs, output2) outputs = append(outputs, &output2)
ret := VerifyCommitValues(inputs, outputs) ret := VerifyCommitValues(inputs, outputs, fee)
assert.Equal(t, true, ret) assert.Equal(t, true, ret)
} }
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/plugin/plugin/dapp/mix/executor/zksnark"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/pkg/errors"
)
func zkProofVerify(db dbm.KV, proof *mixTy.ZkProofInfo, ty mixTy.VerifyType) error {
keys, err := getVerifyKeys(db, int32(ty))
if err != nil {
return err
}
var pass bool
for _, verifyKey := range keys.Data {
ok, err := zksnark.Verify(verifyKey.Value, proof.Proof, proof.PublicInput)
if err != nil {
return err
}
if !ok {
continue
}
pass = true
break
}
if !pass {
return errors.Wrap(mixTy.ErrZkVerifyFail, "verify")
}
return nil
}
...@@ -5,14 +5,11 @@ ...@@ -5,14 +5,11 @@
package executor package executor
import ( import (
"encoding/hex"
"encoding/json"
"strconv"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
dbm "github.com/33cn/chain33/common/db" dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gnark/frontend"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
...@@ -50,32 +47,28 @@ func spendVerify(db dbm.KV, exec, symbol string, treeRootHash, nulliferHash, aut ...@@ -50,32 +47,28 @@ func spendVerify(db dbm.KV, exec, symbol string, treeRootHash, nulliferHash, aut
} }
func (a *action) withdrawVerify(exec, symbol string, proof *mixTy.ZkProofInfo) (string, uint64, error) { func (a *action) withdrawVerify(exec, symbol string, proof *mixTy.ZkProofInfo) (*mixTy.WithdrawCircuit, error) {
var input mixTy.WithdrawPublicInput var input mixTy.WithdrawCircuit
data, err := hex.DecodeString(proof.PublicInput) err := mixTy.ConstructCircuitPubInput(proof.PublicInput, &input)
if err != nil {
return "", 0, errors.Wrapf(err, "decode string=%s", proof.PublicInput)
}
err = json.Unmarshal(data, &input)
if err != nil {
return "", 0, errors.Wrapf(err, "unmarshal string=%s", proof.PublicInput)
}
val, err := strconv.ParseUint(input.Amount, 10, 64)
if err != nil { if err != nil {
return "", 0, errors.Wrapf(err, "parseUint=%s", input.Amount) return nil, errors.Wrapf(err, "setCircuitPubInput")
} }
err = spendVerify(a.db, exec, symbol, input.TreeRootHash, input.NullifierHash, input.AuthorizeSpendHash) treeRootHash := frontend.FromInterface(frontend.GetAssignedValue(input.TreeRootHash))
nullifierHash := frontend.FromInterface(frontend.GetAssignedValue(input.NullifierHash))
authSpendHash := frontend.FromInterface(frontend.GetAssignedValue(input.AuthorizeSpendHash))
err = spendVerify(a.db, exec, symbol, treeRootHash.String(), nullifierHash.String(), authSpendHash.String())
if err != nil { if err != nil {
return "", 0, err return nil, err
} }
err = zkProofVerify(a.db, proof, mixTy.VerifyType_WITHDRAW) err = zkProofVerify(a.db, proof, mixTy.VerifyType_WITHDRAW)
if err != nil { if err != nil {
return "", 0, err return nil, err
} }
return input.NullifierHash, val, nil return &input, nil
} }
...@@ -90,12 +83,14 @@ func (a *action) Withdraw(withdraw *mixTy.MixWithdrawAction) (*types.Receipt, er ...@@ -90,12 +83,14 @@ func (a *action) Withdraw(withdraw *mixTy.MixWithdrawAction) (*types.Receipt, er
var nulliferSet []string var nulliferSet []string
var sumValue uint64 var sumValue uint64
for _, k := range withdraw.Proofs { for _, k := range withdraw.Proofs {
nulfier, v, err := a.withdrawVerify(exec, symbol, k) input, err := a.withdrawVerify(exec, symbol, k)
if err != nil { if err != nil {
return nil, err return nil, err
} }
sumValue += v v := frontend.FromInterface(frontend.GetAssignedValue(input.Amount))
nulliferSet = append(nulliferSet, nulfier) sumValue += v.Uint64()
nullHash := frontend.FromInterface(frontend.GetAssignedValue(input.NullifierHash))
nulliferSet = append(nulliferSet, nullHash.String())
} }
if sumValue != withdraw.Amount { if sumValue != withdraw.Amount {
......
...@@ -18,11 +18,8 @@ package zksnark ...@@ -18,11 +18,8 @@ package zksnark
import ( import (
"encoding/json" "encoding/json"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/backend" "github.com/consensys/gnark/backend/groth16"
groth16_bn256 "github.com/consensys/gnark/backend/bn256/groth16"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gurvy"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/pkg/errors" "github.com/pkg/errors"
...@@ -44,42 +41,78 @@ func deserializeInput(input string) (map[string]interface{}, error) { ...@@ -44,42 +41,78 @@ func deserializeInput(input string) (map[string]interface{}, error) {
} }
func Verify(verifyKeyStr, proofStr, pubInputStr string) (bool, error) { func Verify(verifyKeyStr, proofStr, pubInputStr string) (bool, error) {
curveID := gurvy.BN256 vkBuf, err := mixTy.GetByteBuff(verifyKeyStr)
output, err := mixTy.GetByteBuff(verifyKeyStr)
if err != nil { if err != nil {
return false, errors.Wrapf(err, "zkVerify.GetByteBuff") return false, errors.Wrapf(err, "zkVerify.vk.GetByteBuff")
} }
var vk groth16_bn256.VerifyingKey vk := groth16.NewVerifyingKey(ecc.BN254)
if err := gob.Deserialize(output, &vk, curveID); err != nil { if _, err := vk.ReadFrom(vkBuf); err != nil {
return false, errors.Wrapf(err, "zkVerify.Deserize.VK=%s", verifyKeyStr[:10]) return false, errors.Wrapf(err, "zkVerify.read.vk=%s", verifyKeyStr[:10])
} }
// parse input file // load proof
assigns, err := deserializeInput(pubInputStr) proofBuf, err := mixTy.GetByteBuff(proofStr)
if err != nil { if err != nil {
return false, err return false, errors.Wrapf(err, "zkVerify.get.proof")
} }
r1csInput := backend.NewAssignment() proof := groth16.NewProof(ecc.BN254)
for k, v := range assigns { if _, err = proof.ReadFrom(proofBuf); err != nil {
r1csInput.Assign(backend.Public, k, v) return false, errors.Wrapf(err, "zkVerify.read.proof=%s", proofStr[:10])
} }
// load proof // decode pub input hex string
output, err = mixTy.GetByteBuff(proofStr) pubBuf, err := mixTy.GetByteBuff(pubInputStr)
if err != nil { if err != nil {
return false, errors.Wrapf(err, "zkVerify.proof") return false, errors.Wrapf(err, "zkVerify.pub.GetByteBuff")
}
var proof groth16_bn256.Proof
if err := gob.Deserialize(output, &proof, curveID); err != nil {
return false, errors.Wrapf(err, "zkVerify.deserial.proof=%s", proofStr[:10])
} }
// verify proof // verify proof
//start := time.Now() //start := time.Now()
result, err := groth16_bn256.Verify(&proof, &vk, r1csInput) err = groth16.ReadAndVerify(proof, vk, pubBuf)
if err != nil { if err != nil {
return false, errors.Wrapf(err, "zkVerify.verify") return false, errors.Wrapf(err, "zkVerify.verify")
} }
return result, nil return true, nil
} }
//
//func Verify(verifyKeyStr, proofStr, pubInputStr string) (bool, error) {
// curveID := gurvy.BN256
//
// output, err := mixTy.GetByteBuff(verifyKeyStr)
// if err != nil {
// return false, errors.Wrapf(err, "zkVerify.GetByteBuff")
// }
// var vk groth16_bn256.VerifyingKey
// if err := gob.Deserialize(output, &vk, curveID); err != nil {
// return false, errors.Wrapf(err, "zkVerify.Deserize.VK=%s", verifyKeyStr[:10])
// }
//
// // parse input file
// assigns, err := deserializeInput(pubInputStr)
// if err != nil {
// return false, err
// }
// r1csInput := backend.NewAssignment()
// for k, v := range assigns {
// r1csInput.Assign(backend.Public, k, v)
// }
//
// // load proof
// output, err = mixTy.GetByteBuff(proofStr)
// if err != nil {
// return false, errors.Wrapf(err, "zkVerify.proof")
// }
// var proof groth16_bn256.Proof
// if err := gob.Deserialize(output, &proof, curveID); err != nil {
// return false, errors.Wrapf(err, "zkVerify.deserial.proof=%s", proofStr[:10])
// }
//
// // verify proof
// //start := time.Now()
// result, err := groth16_bn256.Verify(&proof, &vk, r1csInput)
// if err != nil {
// return false, errors.Wrapf(err, "zkVerify.verify")
// }
// return result, nil
//}
...@@ -5,185 +5,18 @@ ...@@ -5,185 +5,18 @@
package zksnark package zksnark
import ( import (
"bytes"
"encoding/hex"
"encoding/json"
"fmt"
"testing" "testing"
"github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestVerify(t *testing.T) {
verifyKey := "1f8b08000000000000ff6c517b4c937714fdddf6536116149022a8a3bc9c1544a84a1086c8a3b85a278ac1c7b0bc6ba90386b41511910928e5fdb43a3543610c5164109c5a37314689c4218e1158650a5b47c4884e05991714bea51fe292657f9dfc7ef7dc7bceb9973d93b003e8436c00ce5669b27c57aa3c512696a6029d49800210029d4d80b54e00748101dd812e21c0d9a48a8e97c7881293544a05d01a42881d9dc506604bdd05531dc00a7003fa08015680bb010959421f6603b0a41ecc371b58fe6e40ab09b0fcdddfa1c08084f0e81c862898fa06969f1bd07904587eee0624c48ace058059c27869823451c9d466821121523a9f0de0ad5026ab6294bc34debaa88484a88d52192f3a51b0cac3759dc06fd72e79a2d49b17288d57fe4f81973e95128ca63b812e2260344d37bc0871a40bd90046d34d0c8505b09d710b3ba63208e86236c0a2f756c4bc30c93b31f77fc54a08008018e80a42882d5dce0298fb5f9ea108749941b794d17dff5f36ad9b37a56b580d973eca02300a932894c9f24499e136c0216492dd4a671ab4286c53bcacf11bbf7402b5c8b1bf38b157895983a14badf436e9c8d56dc9dfe3dad50814a6d7465af46d1d6b46fd8f631e51dd8a6eb475a914b4da44f4e0acc7cd8e23034b55c4308d2babfdeb79a64316aa3afbefa83fffec28b6b9253b4ddcb694e3f23f4bbe7f312af1040a858bf5837e5b9e05a1282d29b377c53e37bcdddfbda2ddab2d16cd35f10feecf7bb29999569bab1f14cb1a8250f1ddf15e9de3ad37b87afdd5868ad50331b85055de2adb861140a1f596a37d73bcc79d715fc3b5039dbf695c50af9eedefebba488d0b9d87d7ea0fdeb22184c99a127c5912ee59c147a37dc4f711e78c1faa95675b3571bbbdd0aee297932e21c72e00858f46474da21b440118776a81e92585731c66151c08af3a625f8f1f5856342a0e167833ee62ed33124b7d9bae628d71dcf84513761e0ee51e5e3522d18ee1525d7fd34a21270b282c7ec9bd32af3af62966fadc0968896d7f831da27a0f9c61721a3979e79dd76ed85dcb4c8b793b5278236d38199f8d17a55766478e608ac7b9a61b55430a9cbb725b7647df09c31d2e3717efecfd4317832b1af4c1d5b2949ff1a979a5981f91148a663ec3f9658157761026ac617b7dfc21e31f469e63ca3703ed3983ca5ff1edf916cfbfcd343bd03498fbed3dd18510a0f06e58754fd7ecb4e5c8ad5bbfeac927ea022c4f900f08db8aacd179a2382092bb7f82f1b75db24cad0d71f0c20f87261cc336a51aa36bf3ab84cc25cd34f2e77c35daf8f6740350d885d228301eeec19b35053e2b2d861ad1f361e30bfe0d311f4dc7b5f7be36b33ff4ee167517ebfcc54109f7b163f9c2f98bae0b63519dbdc6f59497d923345fd3e1131aedd70214d2faf0979ffaabcab0c3a92ff4ead90336585d3e1974f96cc831b4a56d23afb53d2c63dcd5db25f10ba1528fbd5d15ca8e415e2796f0ac449a1289095a65e8acf78449cf0185339b1c6c3c4c1d6c5113d9fe65a05a721c4fd66ff5dfe9fdc065cce3f8e6ebc67539ccf2584061a9aea78aeff97b2796b6cdcfe8945adc43575fdd82bb65af65386372e7fec843a79d80c2d541813f6d0a1bbf8939cbae770657a92cf1c45e4e8b57ef17f968fdf1f90bb1c9dc3b04288cef1739693ff2a731f3f5e35ccbf4c200bcbbf95542c46bef545cbc41606773b3520b1456172936a64cca2dd06e8e437dcb68773876d5f4cfc88834f34273f119b714edc33442806514bc5118b14d14228454f24f000000ffffd7ca51e5ae050000"
pubInput := "7b2279223a223335227d0a"
proof := "1f8b08000000000000ff62666360d6f9dfc8ccc8c81a50949f9fc6f8bf8981919991c9b188f17f0b0323b377513198c1e454ccf8bf83818141e57f3333232387bba1635a5a665e2a4492913182f17f1b0323632488626010ffdfcac8c8c8ee9a939a9b9a5702966263e400696e076b368269ee8069ee8268ee62606050f8dfc9ccc8c8946a04166562647234009bc0e4680831fd1fa3edff264646961ff2dac6726f5e0770fdd87d50ae413cc4a0fe87884ade7de7bfdd0b7eb0cdb27dd07755c99691e5879fb6c43f4b39a7a93fda32c5ae1c3d3cf5d28f79f35d4d3e955999fee099f6694e45d40e65069069468dd1b6cb04f3847ffc4ff8e2753ff3a2e48f77f24b59ff96d69df921b371399fffd5f5bf19597e249ebdf6e77fd444f71f079466ad774ef3abfe71a07bdd077ed695e13fe46ebe9e6ba4bb51888111645cd4abcfee7d2a26277fdc0a3d533b695a8bcc0faffdbcb71c4d3fb8fd50ac280dd7b253bbc2c8f26375a28ed446a98fb77f1cf8735e594cfbefff1feebdbbd25317759ef9211221d33433eb7c33d87147ef898b06a44ebffaa3227cdd5fddedaf56ff5860397f86c0559f673f647be744dc5fa6f49891e5475335e7a317d32df87e1c2f3f7352ef5339cb8f2dd11ffeff09ebbcf7437ff6e6873f8fa96c64606000040000ffff023acbaff4010000"
rst, err := Verify(verifyKey, proof, pubInput)
assert.Nil(t, err)
assert.Equal(t, true, rst)
}
func TestDeposit(t *testing.T) { func TestDeposit(t *testing.T) {
verifyKey := "1f8b08000000000000ff6c517d34d47b1efe7ee6f7c35ccdb5dcbde18a8cb7dd417b9941e38eba1bc2e25cee76dd625dad89c1d4cc2466dc1c160945de95e965cb59b2c7944a75923a3615dae294262c6de985517adfa87c52faed9991f69c3df7afe77c3f2fcff379be0f654ca840660b05c0592d499326654a15c9e1924c60f209d00041c014106085088029d5231f984a029cef55eb64d2845045aa4a990e4c2d21c481d94a015012be606e0358819ec014116005f2f548088f29a4005892a5863205ac004f60b6136005f03fa2408f8470996d8641c15c1958fe9ec0941060f9f3f5488815530c00264132895ca2501a7ac6c02644c2eca000fcd29569aa0425378b1b2296cbc5119264ee3a85c067e9d72102ffa424a942e2c75d2991297fa1c1fdcb9c4b60cf6f02534e803d3fae7f11e2cc945100ecf925c3080b20da702dc4cc791030151480dda753c2b9b1711fc5f8ff13ab240000e1c0ec2484d833352c00f3ff9fd33781a9d6eb5619743fd5abe7754be674f55f63c9ec6201b063e3d295695245b23e1be010f281e632f97a2d1ad3c03f3da2f46d17169fb22d9fea68ba8f75f195897745d4185a9c297399e8715e0534be6d4996699f0ff6e088139a1909a7aab17d5f7b996679712eba059ded7a1063ed45f46cd75aad7eb7e9e9a3dbe81998b6d63e7398416560618250f38519da7032f277be9cce061acf560f468de78c6b30c9f2c66dc1f9f119ec160e3f3df10fbb52e49c883325cace21031bfd61e554f2e5e976bcdf4bed4cd40832d0abb6312ccf66b315c2af374878da4b8f81c682d23ddb467beaed30eb492fe6fc14528effdecd5fe8b54dd98156d7ffee15f0e0d9578418bc8e99ccae9f6db9f4012fddc97532af5921c53e5b9b7dfd4f223390fbf902381499de0b340e05fcd521d147148de6a5233029e7d9a0769c37f32e3eeb32dadd97731b2f46ce79b512b9ebfa52dbf858618f5322edcd0aec8d78d6601473611c7f23905e7858d06a0134b6df685eb46cafe94bb434ea0efcd7e0678b3165ff1bd3d4f257416f4dd5b7fe16d23c6920130be927392e65228cd05dddff65a4ff0c76ae5547d057a607d055d53a3030dc6f0b34bedf6527dbe119e980df0cae92a6a39020631b75bbbead448dac3e971a595e858a18bc028d1ab578f0ace6a91c3d2658a5e73ac2697c67c5733c1e9cdb8fb613acc3a35fb8ca80c689510b9277ddf121baa67554769ff3a847773757379163d36eb4d6960bb6e72dfa6a2e58f5fb5f79d5de1160fbf500e36c75e66bf4ac4ba3fbb4b273685d95bbc2d72dae10681cd95bb65c3d63d78b192d939f9b305b7af1e754f72529de2fcc90b791d7a0733ee3f7318a49d5c91fffb420271a2baadf38e83cfa8fe2a1850b527f3f921285bc1a6ffb7b4e17478146e1e203d6d5c6c7aa90fa63dd6707c25e68708833db2db6187f8eb6dbabbe195c16e363b86eaa257c83f99ed55b51dd9709be9c3b0ec8715cffdb0197ab42b415999cfaaee05103d018a67b10e234b1c11f83c7629ba71b6cf6a2c2a72c3969b3ae14174e67c72ac23c36197e8f021ac3f9fbda4e666d3e885ea7357dbbc7a62af15e3ebb2bec4ded4b74097eb54c788ffd03d0b8b6af68f1a354b5007d971ed659d5dd1dc4e1fa75514bfabd8fa06570e8ea235f0efd4cf45144b71d9fb9e52dc5c6a6c84db35d2543a83de8ddbcfceb6b1968b9c2c99d75a6c91d685cfff8bb42d3d1e2839864326dbf48ac15e1cd1ffd4ace17294ea34782597d66e7ec313dd99503df7e5fd9f63a0a7f8851173defd1e460e3acb1aa92d34aa17be712e1d1672bd7008d71bed3ba3a2f6706c3d784c627fd33fe14d698cb85d951908836ff09a47fba69f42d2140b1232382febc26745590b158be51a550b2151b95923f88d353c87f030000ffffeebab67209060000" verifyKey := "814df619a71aed3315c9cfb740269ca277bec78f1826006a3f3c2ddd4624e733d06840bc329a6efbe2ebba79972c545c85dfe6c40e58617fbe81c5960a46ff399d8e32486e9a1c91fa82ff7a2dfd40ad1cc8af0b4d4d5685430e4acea7108e952b10a13e8fdb3acca1b75c57f6ad9a3bb7b3180f8459cb4622b2fb536e521023da1b8c3424572ab9406f760a4659debd0629e7716ebf250ca801497bd7827cf92c64b21a72a98e84f615a3d6327bcf781771c7a9fd3715003223ea6367643de7e85a80e7e501cca7ddfcc5fd8aed61853f0ed76780c9a969eabfb90625c5dce88146b6f2cffbfde53105b8f1fc799896d31ae909a05f8d5cff04575f52ce916f2468648da7a3a81bf9b143b06eb56e92c2fab2ff63405ff47b695e727171bb7800000003e972123c96876df8e11b5980d29361a6eff03ca3e3b1a057cc34a738a735b542ac4c82ae834f7e31b7e79beadcdabed431f0074a7984a390f35d8a96282ed1cf813da0a5f45ae4a2a8eb2074adaaa85fc617bbdf97193ff9214f7a4693c77214"
pubInput := "7b22616d6f756e74223a223238323432303438222c226e6f746548617368223a223136333038373933333937303234363632383332303634353233383932343138393038313435393030383636353731353234313234303933353337313939303335383038353530323535363439227d" pubInput := "0000000218b9b448bd793dab9075f70ce404a87497b3a2d0d0b5d177441d6cada1e9b2d20000000000000000000000000000000000000000000000000000000001aef080"
proof := "1f8b08000000000000ff62666360d6f9dfc8ccc8c81a50949f9fc6f8bf8981919991c9b188f17f0b0323b377513198c1e454ccf8bf83818141e57f3333232387bba1635a5a665e2a4492913182f17f1b0323632488626010ffdfcac8c8c8ee9a939a9b9a5702966263e400696e076b368269ee8069ee8268ee62606050f8dfc9ccc8c8946a04166562647234009bc0e4680831fd1fa3edff264646961f8a8b3aa3e4d764fcfab1ab72fab48e09b6453f9a26ac8b173a73ecd40fa5c6268bdb3bafdc6464f971ab2a30fb6bcec3693f5efef5ea5a9139efe30fce6bb53e4b6fdcbbf943a4f06b5a93dd2c79069069be4297b6f331096cfc31ad6b41d186058bd6fee0eaaedd71adf247d30fc1eb66fdb7a4441733b2fc98d1bc75ae44eb1f831fbba76505182ef894f2e3dd9189b16e8ca25b7fc86e7bbae1e6c2a5120c8c20e366589fec28d4f3daf8e398fdd176ad7d56393f7c1dd6ce9ed93451ef078f0f43d28e29160e8c2c3fa6274c177839df4ce7c7cf1fd354bbee08bfff319f3ffacdfe97461b7f2836c69e4ad15262013bcefb0e7b69dd8dad353fbceecf379d9eb477d18fe0ab2f1e25722b7dfd2175a22ea14a38da8291e5c7969baa8d1eeb369afeb0f2cd168ac899b7f107df7989c2d4d7cb797e485c71bed89e71888b818101100000ffff7c81eeadf4010000" proof := "ae58e1c78542ab2329332e6eb1d80fbd6eccef6558786ef90df8dec90127e1e6a84e86a457c70fd2e1064b1c43c8d967e4a6b7f5e9b71876c3897be336817ac8056660d2d877609aff716da9fd2facb4bdd7cc8a5b3003c393293bd0fa7ff67bd342ba43e14a87dc509fd83453aa09a7e5d82e77eee7e7c96d4f37fcb402280f"
rst, err := Verify(verifyKey, proof, pubInput)
assert.Nil(t, err)
assert.Equal(t, true, rst)
}
func TestAuthorize(t *testing.T) {
verifyKey := "1f8b08000000000000ff6c527b5493e7197f9f2f1f907211b52da88004a5520b38881005842306449688119058016dc40f890782cba531b371155141299030db5a2fb00896138ebaaed551f10647451c502f5b8528322f2005e7c28cf4d13abe9d2fa83b67677f3de7b9fd2ecffbf25c094fcc6ee7017866316a65be41a9da28610cc09610a00192812d2540a50881ade06224b0d5043c65baf585cabc54d5669d5603ece784902076070f80c7440a273680124700bb8b00258ee42221efb33b79001423729679402d8900b68c00b524f2551472911001bbdb39289c2803951801ec1e025462241709f165cb01c02db9902962545a67cf15f88430ec5e1e409c46abd6e569055b05298aa222451ab351b05e258c16cd4b1126e6e72b554c9c208929d4fe9f86c038e112f8af3781ad24c07f3dce658404b39ff100f8af979c2314c06aa75af870c28390ade20104bc91221164e7be228bfc2f593501009000fb7b4248205b43014cfedf39ae09ac99e3353979dfd4cdaf79f74cf072a7f161f75100fcec5c8d56ad546de4de063c0919a71fb1251c178dfa9d496b17f85422feea9f2f87a423d78ee0131cada950e856e32cdbe0899ba43b1b68dc2ed0777e50d168c3ea9ebcf5d316673cc60737121a0f7d622fc7b7fd36978b6cb763088796a2dcb622d7127e1a130b1766192b43fbb038b0e55c60e7cc0c14c47f11e558eb770e687c70fdfef4294cbc2b3e3a643a26fde9c20ebc77f8f89d63252d85e872f140cb8b539fa639d12272b26f9fcf84f3d814ee75bda920211b57e66def6e1c1e5987f342b242e69e765d06347e79326257666054077a94edfaca7269bc1e3bdf7d7c5754734186fc7b77add4d8f1a38438bdee35cb67278acfe4a12867eccacdaa2d7614c42d1ab81bd73b86ef247dfc83ebf002ceeba98bf57ef3670aba31b6cad15cf08773e1385a7f2333738f84f73c8cd41b668d7ce714b7eaada76db3a9e487f889696756e505aa0b459eb63b1efe9521f8bebbc85a26cf8a061a0f1cbedcd471cad28eb732665fea8125bfc1291a7bfba276ef4e9c91e86835e71ccc77a2f56e6c99f77371ff4a3cef6fbd79ea454f2bbe285efec7e21f8c160cd595382e8febfb81c6f0a943a962993400175a83bb46725d82b1a9779c9f93b4b6093d53676d98dc70f85be2f40a347e6f92a50dd448d7e2e57befc6fcf551a01c4fd6cf3adb31c36cc549a505ad0f97597381c6c72d065bc8826fe2f11dbb7ca14bd89c2eb42a1c5b64d7c73230587ac0ad30be7995531f4f6d4ce8f5dd4a63decae82c59db357f3cfbe3f461f99abffc0367b89fd937685ffe21d058b7dcf8a4bbb361182b6f04d9c99f9b776287bbe24fefa5f55ec1a0a26f4ea45f75bbf8ea29145dd33d1e565f52e2ee9325b21493ef5114596f0ffb746cbf8ae14679dfc269095381c68fff3e3e2762519b1d379d751c0fd81df1111eee130fea431c2538a9c2d72cb9ed93ea54b76f798f79ffad9c7e8c9e13877356ef388baaab43dac1c5fac7e8712bd8bbfa8a3e0468dc90ee7524aa94adc3a5eadf5d3fe635b71c1ff499032d096fdfc1b9512f2b92c66adb9cd773e1ae3734ee62e93fe3863da5f79ffefc9de43e1e4a88d9375a579689ae457b3b3a7d1a1440637677fb8dbf79493d9e37162b6bd5750f51d2b22db55c3c3080bcd2ea5d312bae7c4db80feafe6868748db706db5b12f67bffb2ea38baf83ea968adf59a86be4be5dbdcd28f9880465310f3eb07678c7de811363f11198b0afb0e289bbd03361dc2c94c1a6f77d7cc180e2ce958bc7bd8d218094efd9effe397d44f4da83404fa2db5515af4f874bf4f0d1ddb0334a66fea0af50bd46dc1f34fa56deccaa849b83f6acd36fdd69113e81ffdcbf3a7b66b991c58c8ec3ab1dcddff053e118a8c2f6d124017293520b4181c181a64fb5a186df80c68d4b8d99f3d93d736e0564633c5a7222c0a2fafb96628d3cd5f87a1fa291f7db0baee280736bf2a3f6bf3e20d295895dcf09eebe703528c8d9dfe6dffbf5be391cafcead6a4dac13aa0513cbaa3fa5f734d04edcf624f37bfe5db885fc8b22e894ff72930e0e041db90b1d09f1070e1af484b5e274f4d4ff652e8b405c56ae56f99650a4d81f79b4ca65b2f610c53dfe4199b19d5066ec453ab6698f4e2622d9790ff040000ffff593c5ebfd0060000"
pubInput := "7b22617574686f72697a6548617368223a2231323637383235343336393337373636323339363330333430333333333439363835333230393237323536393638353931303536333733313235393436353833313834353438333535303730222c22617574686f72697a655075624b6579223a223133353139383833323637313431323531383731353237313032313033393939323035313739373134343836353138353033383835393039393438313932333634373732393737363631353833222c22617574686f72697a655370656e6448617368223a223134343638353132333635343338363133303436303238323831353838363631333531343335343736313638363130393334313635353437393030343733363039313937373833353437363633222c2274726565526f6f7448617368223a223130353331333231363134393930373937303334393231323832353835363631383639363134353536343837303536393531343835323635333230343634393236363330343939333431333130227d"
proof := "1f8b08000000000000ff62666360d6f9dfc8ccc8c81a50949f9fc6f8bf8981919991c9b188f17f0b0323b377513198c1e454ccf8bf83818141e57f3333232387bba1635a5a665e2a4492913182f17f1b0323632488626010ffdfcac8c8c8ee9a939a9b9a5702966263e400696e076b368269ee8069ee8268ee62606050f8dfc9ccc8c8946a04166562647234009bc0e4680831fd1fa3edff264646961fdef959ec5357f7bbfdd82211cf3b3dd643e287baa480fcbdece6833f38bcb63aff76590d52f526c657a7e69dd2d91ffe356b42446f9d2eff51c8d1a7685d6f74e207cbeee7fe270dbd7b1840ea44be4c4bceae5dbeefc7777e17b9ed51f6963faa7e6c37b8d331ebe30fdeb29cbefd22e5a98c2c3f725f6c539c20d12af42364d39683712fe6b9fdf8b35f2b523ba82de007bfd0bf438e6d7f53191841c6fd9cc796ff25ce7ff98fc4c486339b7ce4e6fc70b35feab79973d19f1fbc938d224bcd9e5a30b2fc58773e3f4169da6d811fe758c396efaf950dfeb1e46de244b132862d3f44cfcdd4dbbf62d16fb0e38e4e5d9653ef1fcaf363dea3b01d8d7d6f96fd98bc7d83353beba9f41ffcdb9e4edd32fb813c23cb8fcf87debc5956e8c6fe631f9bfdb7509fbe2d3f762c327b9c60e97fff87ee7e17e6537cd9af19181800010000ffffc892b7eff4010000"
rst, err := Verify(verifyKey, proof, pubInput)
assert.Nil(t, err)
assert.Equal(t, true, rst)
}
func TestTransferInput(t *testing.T) {
verifyKey := "1f8b08000000000000ff6c517b50937716fddde433044c512c0645a2a1c511110422a0426193208d54090c6e2c50740df801614362432205f109a2d0e521b0209465b174c5062bd6078b150505953a822bcb5b8b60712ba0b558d4abddf2ed246877c6e95f677ef79e7bceb9bfcbe6107620b3970dc0db48eb5471a92a4dfc3a3a15987d04288020603209b0642260fe62424f600a08f0c20c316a556cb0669b419f0c4c0921c491c96003b0694fd1f404b0023d80c922c00af4342121cecc7e36008bf63197d9c0927a007390004beaf90a45262444c81c301345d36560493c80c921c092789a90103b261b002c82d47412add19b7b1ce01242339fb201fc92f53a43ac5eb8432853262529e574bc304623f2f6592e1349e2e2541ada4fb88656eb7fa721dc39bd25705f4f02934780fb9a6e7a11e2c4e4b201b8af87cc14164084392d444eef2062f2d90082dfa2ac137eb4e99599e7ffcd0a0800c03a608a09218b982216c0ec3779a626308526df4366dfdfea85af7d73a67d4d5fc367feca02e07eb42959af5369e24db7011e215333c4cc3e931785b7169c4948f3cb6a47ca782e40d071ed3bfce5acf6e6b6726281c20b55be56de6f2f040a837b0abf51334f3ec7e81fb8fb4f2dbcfd3e6a7b63eb9724e04c5c263eaf2af3bffb1331a959c8df39f8b8fa9bc3e893fda3c26a4da602ef14fe337f68e4328dd69b6128f1b86a2e5028ec3ff0aebaead3010c3ef973db6151cb0dccd591b29e9800192ebaffc1ad6a87f600b35ab647c5171de31d0ee89a613d73f927bc593858d67ceba2ddae0c744890055b77c7e880c26687c9e8a2f97951f8d07ef98daefa43b9d8b3a5d2caada25b814eb87bcb9d0ab74242ccbb3e336edb9d1bdb7a1ffff047ead7f40767a538a48a5edd6e252f41574be3bfc7fdf35a81c217faacaf3e9f61770bdb6a576c48ffa1d912672d73b79df78f90ed68977df8fd63173a7dcde99c72aa643f1a32a7f08e7dd49c8a2bad1ccc1ab8f9d0de4b9689b645aaa79b4bbbfd80c2f03d7ebc55de8e2df8ee9c40754ba2ed7bb84977d1ddf28482838ed743359d8e799366b5c775612b3b17dbff1d8bbe3e73b7afadc1038f2a8ee7ba56baee429b6f5d7b3f18f82c0e282cd9f1507e2d25742e3a288bf8713cdb1ab458fbedf9a7069b429c3d5c9f1a70c97d949897050aaf8d1d89b8bec73b1ae50dc3820b47f7c5a2a35778444dfb090172bdde3976ce8e160285df19ef9d3d6318d6a2b83faf31b97a8714fbf887cb1d3c6539386f38f845832032c79cafd2d7e9ca3a55a3069b2c8676ad38f9ac0bdb1a64474abcb3f7a34dc7d1f5d5ba9a34a0f0a0cf53fad2b3cb93981a16b6a03afaf965ecf6e53cec8f193a88dcba2659a5d7a9de57b7e813cbd3234ae9462c908e0def6f9bd7880bf5e9b53b7f7215a35032759b67943403852e92915ceb409f1cac79501014ecda5780c58ac19b7dad8fc468b752d1fbf851949b395dd6de557ad6fc15ebb1b2d83215cfaede8e290fc2537dcb036bd02e6009b5840ab90d146a43fdd7688fde8947273f234abfccfd1803bf14090649f74bb44e96eb33c6461bcdbfc7010a236d260e49baf1676cec7951903df9962d864c38e66b473cf371d6a8e090c4cdc294af629cbd72e0fba56d7860e979a7da8d757d982277bf5279ac588ad657eeb6f88f5f1c274061fd848bec0b9f45fd5872ca4829949d8158c537bc2d6e9ab11d9d43f88c5368f873a0f0c9fd7d615d70691ca39dad9a06679232bcd76ad0bd572e9d8df332ae6fcf4b49093789f9dc4de989d6ffe714ae687f54da9573750afd57c63edf6ab756879cde2dab3e4912370285a7f583a322b6cb527cf175dbd8c2bcba34f43bcddd15e5fffd5738dbddbd491993b9da24f6b14b7fdd4926f12a2636ef7c29fff5aa1cf9670489a58b1d7d110c0e36354f6b4f0385e7f38bff1b545c3c89234aa5604cb3958fd1c72f15a438d7bec4c55bebbb6a9a241a93586279cbee23b739cb70fc17af668b51ef673835f16188fbe8d20074cab31f3d975b5d01141e1f7d3437c77f6f052e689feb9cae2c146261cbbfdae2e6df588e2ec6fed8b83f57959ac422ee2d227c17cb789446bab5ff6dfe093ee29ee121c98471082d1ac495563b8337038569d69f9d28ed4c2e429f7a45f8e6fb7ac0e29181a832edd806e4a9d7afbff9a4638810e07043e5417ffa30383c688ed2a04fd0ea5469f4866db466eb5a6572022f569b94a4d26f54aa0d74e45b1a835aad8a53d13a734bafa3e970ad56ff262f82fc2f0000ffff7848a88329070000"
pubInput := "7b22617574686f72697a655370656e6448617368223a223134343638353132333635343338363133303436303238323831353838363631333531343335343736313638363130393334313635353437393030343733363039313937373833353437363633222c22636f6d6d697456616c756558223a223134303837393735383637323735393131303737333731323331333435323237383234363131393531343336383232313332373632343633373837313330353538393537383338333230333438222c22636f6d6d697456616c756559223a223135313133353139393630333834323034363234383739363432303639353230343831333336323234333131393738303335323839323336363933363538363033363735333835323939383739222c226e756c6c696669657248617368223a2236373437353138373831363439303638333130373935363737343035383538333533303037343432333236353239363235343530383630363638393434313536313632303532333335313935222c2274726565526f6f7448617368223a223130353331333231363134393930373937303334393231323832353835363631383639363134353536343837303536393531343835323635333230343634393236363330343939333431333130227d"
proof := "1f8b08000000000000ff62666360d6f9dfc8ccc8c81a50949f9fc6f8bf8981919991c9b188f17f0b0323b377513198c1e454ccf8bf83818141e57f3333232387bba1635a5a665e2a4492913182f17f1b0323632488626010ffdfcac8c8c8ee9a939a9b9a5702966263e400696e076b368269ee8069ee8268ee62606050f8dfc9ccc8c8946a04166562647234009bc0e4680831fd1fa3edff264646961f4b17bc559e92c1d8f343fd7330fbad90f4901f97c5f29e7b6f62b9fd43e587655550bcb31423cb0fab1c79a6ac03d96b7f1c6fd818f42cbae4d70f7b9e7b47fdc2af6ff921c674d2b77f9d161303c8b4596ad70f652df5baff43cfeec0ddaf7587a7ffe83a7269cdc49ffa413fe4163ac71d115a5fc9c8f223df3efbc7e28a05cf7eb85cdd357fc55b2ec11f36f6a7ce1de6ddc7f7436af2e2c499a2c72f3030828c7b147f655e75b493f90f693ecf2c815d1eae3faee795b77bfe5aa1f8438c63d5b21fe1930f30b2fc5876eaba89a3b482c40f5eb1dc85ba179a0eff70f233b30bf065dff143716ed5bc4b67f63a831d9771b9ed95834dfb991ffcd75efd67620d9dfea37945d5e6d825c6c77e30b93cdb6aeb60b98891e5c7a51f32a55bfddecbfef87aba7845448616d78fbbebff9a6fe417f6f9c1a31abf8dbf22c09c818101100000ffff5e148892f4010000"
rst, err := Verify(verifyKey, proof, pubInput) rst, err := Verify(verifyKey, proof, pubInput)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, true, rst) assert.Equal(t, true, rst)
}
func TestTransferOutput(t *testing.T) {
verifyKey := "1f8b08000000000000ff6c517b5493e7197f9f2f9f92145456b90c2beb97910de6412529322855ca25230c4a018b84d2400324342b0997844b8a45b9050541a508c74209acdc3ac54da954b13827eddada1db04015b40a94bb56a065f43ce0816f2741ba9d9dfef53bef73f95dde87b39170fcd93c0e80d50145ba4aa957699282157a60f309d00062600b09508122608f995008ec0902566119f1c9aa84204d6a864e0b6c152184cf167000380aa1686d03287f37600d04287fa1090971618b380094c2c35ce600e5e706ec1102949ff0098a4c4808c3169b07456b65a07cdd802d2140f90a4d48883d7b14002cc4c90ab542a333f736029710055bca01f0d6ead23312744c0e132857abe5a18a24265e23dae3b12b50e4ab54aa340a6f264091acfb9906f3f65a4ae0ae6f025b4e80bb3e6e7a112260cb3800dcf525f308052035bb85e8b50c22f63807c0f1272bc14c8cec8998f0bf622708004030b095849067d9772800ebff9f333581ad30e99e34ebfe54af58d72d59d3357d8d1d7b8a02e0c6c8b4ba749526c9741bb02264953ec4e69bb4683c20b63cdaf051451c8a777afe7ad4a2a6111d54c3bb6ed42d7f8d4ef2a521e77f958881c6a9ece473dd9d952adc6b8f737a1f4a8faacf07360a0e8f033ef3418e93ddc1e74e1113db8349cbae3b2e0f7ec4b7bfec2b6e316c1760c38edad1cba18a41fccdcbf97263e37424d0f85ee48601f2eddc2296c91999952d358ea91bf407e178ec37681f2f2cfd6ed1ed5766b65b499b0a4324335c2c492daef9a1f0b2173e3d517fca273d7c2f6e17367dda9a92550a3476ddbcb7f0e1e6540de6bd65bc1d27731a41267d8bcd0b11b4017f3bd36bad73ee1d20c49cd5921779fdda969a79bcd2f88d75e2fe33b33816d259b47de6ae230a44fa10bf30810268ec197499f451dfb5c55ef99feba6e5679ec5fca9132f3546cfce22f769073254f1418cd91d23688ff593949d45ff9271c5e16dafcee317bfffebf4a60ca706fc657be0b0fae3776781c6b18bb1a5f39b7c6af164024f387b52fa3166f6d68b659dda41b4f65af431d4f29566b660b46116c61f36e1e6955583ee48f80bd8fcdac3a2e16b775974ec8ed5afb64b8a81c68680c8b1f3b99b34b878e892dfada8e25194462496d5712d8750909dad6ca7f33b88392cd0b8b1b6ded5767079043583cad696eef2257cbfa23ec5e62d7bfba5462ef8b57bb9038df74801f7c51d3d17f06a5bd285fd1ff68c60577f887afe95d3a1e8ba3b6065c5f919b5d95e4b5779fb4e65b60173f5b21b3c55d6efd05a96a6d46c7db31a69abab13f5d16d9f028d67dd2ddab837176ab0dfeef1b9c2859666fceab6e0d260e6bc11ada63cba3ff953c4eb4f4e618c146cb89653178c9f7b495e7cd57bee7b0c8bf8f68646981f85fc4faabb3cba624f038dff8ef3f5f0ffbaf93c5e77b837909bea7a1fc7e8adbe47bd8403b8eb8c45b3e3c054a7d95d39d728716a6cd1636f9abaf2d0757e3c6edd6151fc6533b5015da3bcb54131b71f018ddd071fbba425e9a598bbc571e40fcf5996e236b7bf5d652ef082d0e598b3435847ffaaf9f368a0f1d1f81589edeef01cd42a1b9bcee6317c14b4d91618578bcb50309d9c5ca6b47e1e6814c738d655dbfcd0819925dbec6a2fed1fc0e9bf74f4a2cfbc273233799fd57ebf7d99008d2f9d4b8cdd13f95a0406839b17ed1ba7c1f4d3fb721e891daad1fe299b8bf1055fec031adf9fe6fdfd61db8379b4b78b5fa0de7db31fbfbb9331e45639c7a0c07a595cc5b89e3791653fafbe39b9794f183259fd7613e17ffc27b61a78f117fb8c89b8bbe89de1a2e3bc23402f5db99cf191f19627fe9835298d7e6369024baa5ab599af53ff409eefa46e748ae59bb8bab582c7b63d2136f85e0ff9aa4ada178b76090e2df7d3c2a4c8177e6678854f39018d21ed45fbf4b2e870dcf9d49d6345eec615ec3bdc34b437e0fe0cba24a946dd259ebf200468ab8414b55aa53b204fce5048b99a149d4222d7bef1bfd568eecba1e2b8a8a00831f94f000000ffffeb52afc268060000"
pubInput := "7b22636f6d6d697456616c756558223a223134303837393735383637323735393131303737333731323331333435323237383234363131393531343336383232313332373632343633373837313330353538393537383338333230333438222c22636f6d6d697456616c756559223a223135313133353139393630333834323034363234383739363432303639353230343831333336323234333131393738303335323839323336363933363538363033363735333835323939383739222c226e6f746548617368223a223136333038373933333937303234363632383332303634353233383932343138393038313435393030383636353731353234313234303933353337313939303335383038353530323535363439227d"
proof := "1f8b08000000000000ff62666360d6f9dfc8ccc8c81a50949f9fc6f8bf8981919991c9b188f17f0b0323b377513198c1e454ccf8bf83818141e57f3333232387bba1635a5a665e2a4492913182f17f1b0323632488626010ffdfcac8c8c8ee9a939a9b9a5702966263e400696e076b368269ee8069ee8268ee62606050f8dfc9ccc8c8946a04166562647234009bc0e4680831fd1fa3edff264646961f4ddc5f18955a16ccfba1906ff768ab2187fe8fd6dc5bdec1568cfb7ef0774915ab3759b833b2fc70d0df70ecdbc229d37ef031ea35c5ead87ef991a2de64615aa974e987988bd4810762d39d1940a6d56dd9197b33c1bce9c7e6cbf358e35e886ff8c179be6ffeeb599a677f30bdbebdecd18c8c7246961ffed93a5b3cd719c8fff8cc21bd6af7928ed21f46f53fdf7b37dd53f8c1ffe37dd0267ecd4a06469071611bb9839dde3c7bf383bb69def593f6f9b63ff6301fdc3439ce37f007afd8d50dd704d22519597ecc9af92af26ff9f99b3ff2bed878af787c30ed878dd10957162e158f1ffaaaafb86c8bcfed003b6ec5e9a3898bbfb708fdd0ba35713effa2e7753f7eff6f9ddfa6d858ff43e8a4d2d18b7edd5e8c2c3fa4774c15ce9c513fe5477df7f9836d519ef63fb436acf9b6563d2fed87e08463fb97acdbf69e818101100000ffff9650c672f4010000"
rst, err := Verify(verifyKey, proof, pubInput)
assert.Nil(t, err)
assert.Equal(t, true, rst)
}
func TestWithdraw(t *testing.T) {
verifyKey := "1f8b08000000000000ff6c51795093671a7f9fe4230d1a15224705c508b845442520ba8a42498c8051ea8180656345fc20c190484850504428208756a11e8834d80d663d285854c6455d0705d68a2e5a0b54915a8ecaacb25e94f5316abf9d2f48776667fffacdfb1cbfe37db83cc29532d95c004114ad5325a4ab3489723a1d981c0214800c985c029c503f60f6b02806663f01c14ac346b52a3e5cb3c5a04f05e61021641af33917804b8bfd46368023f505269f00472a6691102f268f0bc0a1e759cb5ce0487c812920c09188dfa31f8b848898ddd641bf913270427c812922c00911b34888335308001fc8d47432add15b7b3ce0134233c55c80c054bdce10af176d1785c62527c745d089a28d1abf8079b343fd421212541a3a50b48456ebff4f4394399212f8a39bc07c41803f3acebe08f164f67201f8a34bd6110e408cd52dac1bc9e0c7ece3024cf9dd8a5c14ab782f26feafd87e02002007e60021642af32507c0ee7fe7d82630a5ac6e8955f7f77ae9a86ed1882efb354ecc410e003f5691aad7a93489ec6d4040c86fd44f4c0eab45e12187da976e973aabd1609719e9bd7e7e3d862b266ccefdb2d88cfc6de6575b87172c060ac34f788ea76ebcedc42237fb17e3e70e34a278d1bf1fdbbb19fa519074fc68439a5d1661d9d28f4df0ba1a552cc54f7f21394be53307f06ceef449bb1206f720e772e3b46a557713507876f79a28a540198ccf85fab4825f2c4d981677fd9213d40a10247f9d27b3bd61b4b2694f9676c6ce9afa161d25f2e3073687ea50d6973fe540a47e2c728dd75fb6bdae3c0714ba24a698e65d72e8c4ccaf5fa65efea7b01ee70cb62462c87205daad9924fb3ee0761c21d6ac70abac3f68da15231e98fb8af9a02ce52b6c444515efeefa4014c6dd7c9066bce00d143eb333276f2bfabc0a677a78fd1679adfa28ba1b5f4b2ddf9fea43f76f331774a9fc5badeedcae79d5dc0af639843faa4b9eb53ff97339da563de9d1b41e7b8393d3164dfe35d04309140e2b3cebb76524987068e87a073743f402a34abe49bc27a91122372b5aeb5f3cff9d956da7474f53cd3a37172c684f1faea14d6d98a48a5c1814ebf00edd9cb5a6e045d93380c287cbd5bb453b3e2c45bed3706d94a3d20605ce6dd2b1376c2ea27df4acd28e6bfb7389352c50e871bf3da95aba54820de3a06d7b952909a7381dc1757fea35a1f041c599b13d55dd40e1969b8e3197fed1558bd5852edc85e27d0c1e3978b5f2c7ae9f3538ee62d8daa91794df8ca4ed79d46cd8d94e630bf793def696d077d81db9a94c360414baca2abd7c6c6eca81c2ee7ee17c5e5653d2eb8d2dde0ecbb29bf13196c2b0c7e06514cc0ce63fb5ef5efafe14eee54b66c2ed53c518b48a1fb3baf3b010b38e7ee178e77a4a310a9f0c99ff55b8b50428347977f9da3fec50e2e0ca079399882b9e287e53985ef807d88b3e675f1dd605ae1bb29ab33c13edd207ac7d81d3eb6225b6b5eeade86df9587238758c33dafa9bfd1a88e318a05013b03eafa2313319d396f795df3b33e482cb368d3fd6d27bad1f79572ed43f4affa1cefa79364061c8dc5d374c4f7136fec55c10b63d6222852736c4d9449b3df27186d673d58c0fd36380c2f3f93d2b94ab3e6d47c71503b67b8dcdcdf89d7c41fc361551e19c57cfa77f3b58ee4180c28a8b6a1f4d59c30614a5c406145df13e81cb02b79e74ceddf8314e38b628eaa974ee65a0509193974bf6fdfd34bafb6484259794203eef73b50bf85b5617f2440e5bca3c17b4b0643ba3e7f7d59f32f2b06671ac4b6f6b228d3fc4db6cb8630a32be1e0abb5fd7f2f82e5018e3ab769a762e7c32f29ad6dece769e65c2ca239b732c735a0770a2daa971c9cae1cf582ef9f99f024e3f6d4841b3ff8a3da136a78370383bbfeeeeb984669c7ae6966bc67dea3950b87052de573513f30ee2d8f57f7cd46e5155e28e3bf11f7df7ab220067b7f576081a62642c595271d29c299d05fe7877cf47e1272dd96538e6ade55447c5bd12e49bfb5de5c7f75d050a076e693216ef1808c52eb7a28775c1272a5053effab25c7efe6be4bf7998f1b3cfde0984800d2f24596bd0e8f99f44c83e8b0e5f2d1344ea687ab556ab0f8b4b550a430c7aa556a7caa0d76ca1359bd8d2b808835aad4a50d13af645fe130000ffff37a667a7c7060000"
//pubInput := "7b22416d6f756e74223a22353030303030303030222c22417574686f72697a655370656e6448617368223a2230222c224e756c6c696669657248617368223a2233393131373734303430353637393732383732393536303038333837313431313735303031343139363439363932393439323033313430303839303539303938393536373733333239313838222c2254726565526f6f7448617368223a2237343037333733363733363034323736313532383031333534303034383531333833343631353339333137393737333037393435313938363234383036353033393535333032353438373030227d"
//proof := "1f8b08000000000000ff62666360d6f9dfc8ccc8c81a50949f9fc6f8bf8981919991c9b188f17f0b0323b377513198c1e454ccf8bf83818141e57f3333232387bba1635a5a665e2a4492913182f17f1b0323632488626010ffdfcac8c8c8ee9a939a9b9a5702966263e400696e076b368269ee8069ee8268ee62606050f8dfc9ccc8c8946a04166562647234009bc0e4680831fd1fa3edff264646961f3cb782cffcf57b38f387a99d7c6ee7868c1f3fe4e619b92af066c9fc902ddcff4e74b2f27246961fcd1246476cad8a97ff98d813ff2dedc235b31f6cd613169a1acf32fea1b19e9125be36692503c8b4bf8c2e3b7e7eb698f2e3ee5229cfd3422adb7fec3aef7064554acebb1fba379fbb2d5a9a12c3c8f2635e4991d9a70acd9c1f5b049592aaf8f79dfec1bb559f6182a9ede31ffafd571654fc791bc4c008328ea5ae9af1f906c9fd3f8edddef3dca12f51fcc7612769b3df59672a7fe84e7cc3fe3bf7773523cb8fcd82b9571744a9b9fe58207621f796e6cfb33f625656354c2c78fff9074fd8dfbdda1f2d37831dd7ab5ad5c95b715feb8787c0a367910fbf16fd9855785449cec1d5ff876affba77fc6b773130b2fc90d76177f92a65d7f863d1753ec512a1d2fc1f874c4ef9b21a98f5fd600e8fd5fdf2f3db5206060640000000ffffbe0a8c21f4010000"
pubInput := "7b22416d6f756e74223a22333030303030303030222c22417574686f72697a655370656e6448617368223a2230222c224e756c6c696669657248617368223a223231303831383737323734333735363138373335313735373439373731303436353038353236303132343834373730373738303137323532353237363930353534343638383234363032303333222c2254726565526f6f7448617368223a223132363130353833363132333930383937343333363935303639393236343830353334333331333038313834303132323934383835373131303534393530343033333937393530343630323936227d"
proof := "1f8b08000000000000ff62666360d6f9dfc8ccc8c81a50949f9fc6f8bf8981919991c9b188f17f0b0323b377513198c1e454ccf8bf83818141e57f3333232387bba1635a5a665e2a4492913182f17f1b0323632488626010ffdfcac8c8c8ee9a939a9b9a5702966263e400696e076b368269ee8069ee8268ee62606050f8dfc9ccc8c8946a04166562647234009bc0e4680831fd1fa3edff264646961fbe01ef7e7c9b2095fec3ff5cd9b4a650fe653f56de9e10c1b2f3fcfb1fba6ca55b1af4f32730b2fc68d3f996a278fc47e18f4be65589afde5cb5fb61b961eb7aeec08f823f84dc4ffc906a35b9c50032ed2bf792b3494c0ae23f026f4ced59f0cf25f787724b689ddae940c11fac5f3d5438a7942431b2fc70e96aad173d3c63ee8ffa1eefe2cd9515313f38b6f04cace4586bfe43dc4f4bd4416195010323c8b89223b3055afe159cfeb1bb45f9ee7ed30a931f2d27bbd5ae2cdab1f987d8d23dcd960eb70f33b2fc30775ea619b9e360d28f0b8a2783d7ab775cfa71e5e6ac673573ae7dfec168a2f3f4c592af2bc08e0bd06c399ca215b6f4c7a58776c21a73ee95ffd8d1e6f4de7e4dda9a1fcaca379ebdad6f156664f9b1ddc665b518a7df841fc7c538664c49f937fb87cbc7b66216b3acf33fb8fd6bb56e2857fa32303000020000fffffbc89ea0f4010000"
rst, err := Verify(verifyKey, proof, pubInput)
assert.Nil(t, err)
assert.Equal(t, true, rst)
}
//
//func TestDeserializeWitness(t *testing.T) {
// //str := "7b0a202020202259223a202230783233222c0a202020202278223a202230783033220a7d0a"
// str := "7b22636d7468617368223a2230393265613834303464323431303566326263616638616132656365633239626230303039353965376137313433393539663465623638373232656531653765222c22636d7476616c756578223a2231663235383330333630353866613432376338346364663264303361666234363233623361376566313365366637653465656239663762316335666563326463222c22636d7476616c756579223a2232313639663266626634623839653431343631643734326430373036663362313137643761613531376663313164333261336563313765666664346638336137222c22636f6d6d69745f72616e646f6d223a226138353566323233222c2268656c70657231223a223031222c2268656c70657232223a223031222c2268656c70657233223a223031222c2268656c70657234223a223031222c2268656c70657235223a223031222c227061746830223a2231653434633733626137393830623034353061386539393763396439633738626535613964376365616635393764663738313436396131633964623465346339222c227061746831223a2231393161383065333737616639653064303465316437356538643730326434633264623231623935326239666666366263636133316639653966643564653030222c227061746832223a2232323064633230343161386338313038366139626338303834653766396565303738386165326338623739323865306232653236373233333962323933336233222c227061746833223a2232393564363331666366306564306433343734326163353630666537613063303538353232356366663931393438303664346439643865316630306531373437222c227061746834223a2232313538343961643762643433343461383037663466306339616566643231333135373265336362323161386232316161393665386131316334613231346535222c227061746835223a22222c227072696b6579223a2232613831613633623731616534383132343836396661316537363664643637633164336236383431653561646132643362623831326661303432363730313733222c227075626b6579223a2231356639646364656362396432623963323635643936376534623135363532636564393862663530303566646236623562333030626630376335303666386239222c22726f6f7468617368223a2232616665613563323866373631663432663335636361343731313730636130373263626534623639623662313863346133623435363337653937343738336334222c227472616e736665725f72616e646f6d223a223233222c227472616e736665725f76616c7565223a223031616566303830222c2276616c696430223a223031222c2276616c696431223a223031222c2276616c696432223a223031222c2276616c696433223a223031222c2276616c696434223a223031222c2276616c696435223a22222c2276616c7565223a2233306537227d0a"
// res, _ := hex.DecodeString(str)
// var buf bytes.Buffer
// buf.Write(res)
// decoder := json.NewDecoder(&buf)
//
// var ss mixTy.TestMsg2
//
// if err := decoder.Decode(&ss); err != nil {
// panic(err)
// }
// val, _ := hex.DecodeString(ss.Cmthash)
// var a big.Int
// a.SetBytes(val)
// fmt.Println("cmthash=", ss.Cmthash, "val=", a.String(), "v=", a)
// fmt.Println("cmtvaluex=", ss.Cmtvaluex)
// fmt.Println("y=", ss.Cmtvaluey)
// fmt.Println("roothash", ss.Roothash)
// //v,err := strconv.ParseInt(ss.Value,16,0)
// b, err := new(big.Int).SetString(ss.Value, 16)
// fmt.Println("erri", err)
// fmt.Println("value", ss.Value, "atoi", b)
//
//}
//
//func TestDeserial(t *testing.T) {
// val := make(map[string]interface{})
// val["cmthash"] = "1"
// hash := "0x2afea5c28f761f42f35cca471170ca072cbe4b69b6b18c4a3b45637e974783c4"
// hashb, _ := hex.DecodeString(hash[2:])
// val["value"] = hashb
//
// res, err := json.Marshal(val)
// assert.Nil(t, err)
// str := hex.EncodeToString(res)
// fmt.Println("res", string(res), "str", str)
//
// str2, _ := hex.DecodeString(str)
// var msg mixTy.TestMsg3
// json.Unmarshal(str2, &msg)
// fmt.Println("msg", msg.Cmthash, "val", hex.EncodeToString(msg.Value))
//
// val2 := make(map[string]interface{})
// var buff2 bytes.Buffer
// buff2.Write(str2)
// decode := json.NewDecoder(&buff2)
// err = decode.Decode(&val2)
// assert.Nil(t, err)
// for k, v := range val2 {
// fmt.Println("k=", k, "v=", v)
// }
//
//}
func TestDeserial(t *testing.T) {
val := make(map[string]interface{})
val["cmthash"] = "1"
hash := "0x2afea5c28f761f42f35cca471170ca072cbe4b69b6b18c4a3b45637e974783c4"
hashb, _ := hex.DecodeString(hash[2:])
val["value"] = hashb
var buf bytes.Buffer
encode := json.NewEncoder(&buf)
err := encode.Encode(val)
assert.Nil(t, err)
enstr := hex.EncodeToString(buf.Bytes())
fmt.Println("encode", enstr)
enbuff, _ := hex.DecodeString(enstr)
var buff2 bytes.Buffer
buff2.Write(enbuff)
decode := json.NewDecoder(&buff2)
val2 := make(map[string]interface{})
err = decode.Decode(&val2)
assert.Nil(t, err)
for k, v := range val2 {
fmt.Println("k=", k, "v=", v)
}
}
func TestDeserialDeposit(t *testing.T) {
pubInput := "7b22616d6f756e74223a223238323432303438222c226e6f746548617368223a223136333038373933333937303234363632383332303634353233383932343138393038313435393030383636353731353234313234303933353337313939303335383038353530323535363439227d"
var deposit types.DepositPublicInput
data, err := hex.DecodeString(pubInput)
assert.Nil(t, err)
err = json.Unmarshal(data, &deposit)
assert.Nil(t, err)
fmt.Println("notehash", deposit.NoteHash)
fmt.Println("amout", deposit.Amount)
}
func TestDeserialWithdraw(t *testing.T) {
//pubInput := "7b22416d6f756e74223a22353030303030303030222c22417574686f72697a655370656e6448617368223a2230222c224e756c6c696669657248617368223a2233393131373734303430353637393732383732393536303038333837313431313735303031343139363439363932393439323033313430303839303539303938393536373733333239313838222c2254726565526f6f7448617368223a2237343037333733363733363034323736313532383031333534303034383531333833343631353339333137393737333037393435313938363234383036353033393535333032353438373030227d"
pubInput := "7b22416d6f756e74223a22333030303030303030222c22417574686f72697a655370656e6448617368223a2230222c224e756c6c696669657248617368223a223231303831383737323734333735363138373335313735373439373731303436353038353236303132343834373730373738303137323532353237363930353534343638383234363032303333222c2254726565526f6f7448617368223a223132363130353833363132333930383937343333363935303639393236343830353334333331333038313834303132323934383835373131303534393530343033333937393530343630323936227d"
var withdraw types.WithdrawPublicInput
data, err := hex.DecodeString(pubInput)
assert.Nil(t, err)
err = json.Unmarshal(data, &withdraw)
assert.Nil(t, err)
fmt.Println("TreeRootHash", withdraw.TreeRootHash)
fmt.Println("AuthorizeSpendHash", withdraw.AuthorizeSpendHash)
fmt.Println("Amount", withdraw.Amount)
fmt.Println("NullifierHash", withdraw.NullifierHash)
} }
syntax = "proto3"; syntax = "proto3";
import "common.proto";
import "transaction.proto";
package types; package types;
option go_package = "../types";
import "common.proto";
import "transaction.proto";
//区分不同的验证电路 //区分不同的验证电路
enum VerifyType{ enum VerifyType{
DEPOSIT = 0; DEPOSIT = 0;
WITHDRAW = 1; WITHDRAW = 1;
TRANSFERINPUT = 2; TRANSFERINPUT = 2;
TRANSFEROUTPUT = 3; TRANSFEROUTPUT = 3;
AUTHORIZE = 4; AUTHORIZE = 4;
} }
message ZkVerifyKey { message ZkVerifyKey {
VerifyType type = 1; VerifyType type = 1;
string value = 2; string value = 2;
} }
...@@ -30,15 +31,18 @@ message AuthKeys{ ...@@ -30,15 +31,18 @@ message AuthKeys{
repeated string keys = 1; repeated string keys = 1;
} }
message PaymentKey{ message NoteAccountKey{
string addr = 1; //链上地址
string receiverKey = 2; string addr = 1;
string encryptKey = 3; //支票收款地址
string noteReceiveAddr = 2;
//note秘密信息接收key
string secretReceiveKey = 3;
} }
message TokenTxFeeAddrReq{ message TokenTxFeeAddrReq{
string assetExec = 1; string assetExec = 1;
string assetSymbol = 2; string assetSymbol = 2;
} }
enum MixConfigType{ enum MixConfigType{
...@@ -65,14 +69,14 @@ message MixConfigAction { ...@@ -65,14 +69,14 @@ message MixConfigAction {
oneof value { oneof value {
ZkVerifyKey verifyKey = 3; ZkVerifyKey verifyKey = 3;
string authKey = 4; string authKey = 4;
PaymentKey paymentKey = 5; NoteAccountKey noteAccountKey = 5;
} }
} }
//DH one time pubkey with secret //DH one time pubkey with secret
message DHSecret{ message DHSecret{
string peerKey = 1; string oneTimePubKey = 1;
string secret = 2; string secret = 2;
} }
...@@ -115,9 +119,9 @@ message MixWithdrawAction { ...@@ -115,9 +119,9 @@ message MixWithdrawAction {
} }
message MixAuthorizeAction { message MixAuthorizeAction {
string assetExec = 1; string assetExec = 1;
string assetSymbol = 2; string assetSymbol = 2;
ZkProofInfo proof = 3; ZkProofInfo proofInfo = 3;
} }
...@@ -135,44 +139,6 @@ message MixAction { ...@@ -135,44 +139,6 @@ message MixAction {
} }
message DepositPublicInput {
string noteHash = 1;
string amount = 2;
}
message WithdrawPublicInput {
string treeRootHash = 1;
string nullifierHash = 2;
string authorizeSpendHash = 3;
string amount = 4;
}
message TransferInputPublicInput {
string treeRootHash = 1;
string shieldAmountX = 2;
string shieldAmountY = 3;
string authorizeSpendHash = 4;
string nullifierHash = 5;
}
message TransferOutputPublicInput {
string noteHash = 1;
string shieldAmountX = 2;
string shieldAmountY = 3;
}
message AuthorizePublicInput {
string treeRootHash = 1;
string authorizePubKey = 2;
string authorizeHash = 3;
string authorizeSpendHash = 4;
}
message VerifyProofInfo{ message VerifyProofInfo{
VerifyType ty = 1; VerifyType ty = 1;
...@@ -384,17 +350,23 @@ message AuthTxReq{ ...@@ -384,17 +350,23 @@ message AuthTxReq{
message TransferInputTxReq{ message TransferInputTxReq{
string noteHashs = 1; string noteHashs = 1;
string zkPath = 2;
} }
message TransferOutputTxReq{ message TransferOutputTxReq{
DepositInfo deposit = 1; DepositInfo deposit = 1;
string zkPath = 2;
} }
message TransferTxReq{ message TransferTxReq{
TransferInputTxReq input = 1; TransferInputTxReq input = 1;
TransferOutputTxReq output = 2; TransferOutputTxReq output = 2;
string zkPath = 3;
}
message CreateZkKeyFileReq{
int32 ty = 1;
string savePath = 2;
} }
//加密了的input/output amount //加密了的input/output amount
...@@ -416,13 +388,13 @@ message ShieldAmountRst{ ...@@ -416,13 +388,13 @@ message ShieldAmountRst{
} }
message CreateRawTxReq{ message CreateRawTxReq{
int32 actionTy = 1; int32 actionTy = 1;
bytes data = 4; bytes data = 4;
string assetExec = 2; string assetExec = 2;
string assetSymbol = 3; string assetSymbol = 3;
string title = 6; //平行链名字 string title = 6; //平行链名字
int32 privacy = 7; //1:打印隐私数据 string zkProof = 7; //输入证明内容,方便测试,空:读pk文件产生proof
int32 verify = 8; //0:链上验证,1:本地验证 bool verifyOnChain = 8; //true:链上验证,false:本地验证
} }
......
...@@ -139,3 +139,12 @@ func (c *Jrpc) CreateRawTransaction(in *mixTy.CreateRawTxReq, result *interface{ ...@@ -139,3 +139,12 @@ func (c *Jrpc) CreateRawTransaction(in *mixTy.CreateRawTxReq, result *interface{
*result = hex.EncodeToString(types.Encode(reply)) *result = hex.EncodeToString(types.Encode(reply))
return err return err
} }
func (c *Jrpc) CreateZkKeyFile(in *mixTy.CreateZkKeyFileReq, result *interface{}) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "CreateZkKeyFile", in)
if err != nil {
return err
}
*result, err = types.PBToJSON(reply)
return err
}
package types
import (
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/hash/mimc"
)
type AuthorizeCircuit struct {
TreeRootHash frontend.Variable `gnark:",public"`
AuthorizeHash frontend.Variable `gnark:",public"`
AuthorizeSpendHash frontend.Variable `gnark:",public"`
Amount frontend.Variable
ReceiverPubKey frontend.Variable
ReturnPubKey frontend.Variable
AuthorizePubKey frontend.Variable
AuthorizePriKey frontend.Variable
SpendFlag frontend.Variable
NoteRandom frontend.Variable
NoteHash frontend.Variable
//tree path info
Path0 frontend.Variable
Path1 frontend.Variable
Path2 frontend.Variable
Path3 frontend.Variable
Path4 frontend.Variable
Path5 frontend.Variable
Path6 frontend.Variable
Path7 frontend.Variable
Path8 frontend.Variable
Path9 frontend.Variable
Helper0 frontend.Variable
Helper1 frontend.Variable
Helper2 frontend.Variable
Helper3 frontend.Variable
Helper4 frontend.Variable
Helper5 frontend.Variable
Helper6 frontend.Variable
Helper7 frontend.Variable
Helper8 frontend.Variable
Helper9 frontend.Variable
Valid0 frontend.Variable
Valid1 frontend.Variable
Valid2 frontend.Variable
Valid3 frontend.Variable
Valid4 frontend.Variable
Valid5 frontend.Variable
Valid6 frontend.Variable
Valid7 frontend.Variable
Valid8 frontend.Variable
Valid9 frontend.Variable
}
// Define declares the circuit's constraints
func (circuit *AuthorizeCircuit) Define(curveID ecc.ID, cs *frontend.ConstraintSystem) error {
// hash function
h, _ := mimc.NewMiMC("seed", curveID, cs)
mimc := &h
mimc.Write(circuit.AuthorizePriKey)
cs.AssertIsEqual(circuit.AuthorizePubKey, mimc.Sum())
mimc.Reset()
mimc.Write(circuit.AuthorizePubKey, circuit.NoteRandom)
cs.AssertIsEqual(circuit.AuthorizeHash, mimc.Sum())
mimc.Reset()
cs.AssertIsBoolean(circuit.SpendFlag)
targetSpendKey := cs.Select(circuit.SpendFlag, circuit.ReceiverPubKey, circuit.ReturnPubKey)
mimc.Write(targetSpendKey, circuit.Amount, circuit.NoteRandom)
cs.AssertIsEqual(circuit.AuthorizeSpendHash, mimc.Sum())
mimc.Reset()
mimc.Write(circuit.ReceiverPubKey, circuit.ReturnPubKey, circuit.AuthorizePubKey, circuit.Amount, circuit.NoteRandom)
cs.AssertIsEqual(circuit.NoteHash, mimc.Sum())
var proofSet, helper, valid []frontend.Variable
proofSet = append(proofSet, circuit.NoteHash)
proofSet = append(proofSet, circuit.Path0)
proofSet = append(proofSet, circuit.Path1)
proofSet = append(proofSet, circuit.Path2)
proofSet = append(proofSet, circuit.Path3)
proofSet = append(proofSet, circuit.Path4)
proofSet = append(proofSet, circuit.Path5)
proofSet = append(proofSet, circuit.Path6)
proofSet = append(proofSet, circuit.Path7)
proofSet = append(proofSet, circuit.Path8)
proofSet = append(proofSet, circuit.Path9)
//helper[0],valid[0]占位, 方便接口只设置有效值
helper = append(helper, cs.Constant("1"))
helper = append(helper, circuit.Helper0)
helper = append(helper, circuit.Helper1)
helper = append(helper, circuit.Helper2)
helper = append(helper, circuit.Helper3)
helper = append(helper, circuit.Helper4)
helper = append(helper, circuit.Helper5)
helper = append(helper, circuit.Helper6)
helper = append(helper, circuit.Helper7)
helper = append(helper, circuit.Helper8)
helper = append(helper, circuit.Helper9)
valid = append(valid, cs.Constant("1"))
valid = append(valid, circuit.Valid0)
valid = append(valid, circuit.Valid1)
valid = append(valid, circuit.Valid2)
valid = append(valid, circuit.Valid3)
valid = append(valid, circuit.Valid4)
valid = append(valid, circuit.Valid5)
valid = append(valid, circuit.Valid6)
valid = append(valid, circuit.Valid7)
valid = append(valid, circuit.Valid8)
valid = append(valid, circuit.Valid9)
VerifyMerkleProof(cs, mimc, circuit.TreeRootHash, proofSet, helper, valid)
return nil
}
package types
import (
"testing"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/backend"
"github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/frontend"
)
func TestAuthorize(t *testing.T) {
assert := groth16.NewAssert(t)
var authCircuit AuthorizeCircuit
// compiles our circuit into a R1CS
r1cs, err := frontend.Compile(ecc.BN254, backend.GROTH16, &authCircuit)
assert.NoError(err)
{
authCircuit.TreeRootHash.Assign("950328190378475063285997697131233976268556642407874368795731039491163033995")
authCircuit.AuthorizeHash.Assign("12118078255438699776281693699296572905522325280239057706039401491884511470990")
authCircuit.AuthorizeSpendHash.Assign("21866258877426223880121052705448065394371888667902748431050285218933372701264")
authCircuit.ReceiverPubKey.Assign("13496572805321444273664325641440458311310163934354047265362731297880627774936")
authCircuit.ReturnPubKey.Assign("10193030166569398670555398535278072963719579248877156082361830729347727033510")
authCircuit.AuthorizePubKey.Assign("2302306531516619173363925550130201424458047172090558749779153607734711372580")
authCircuit.AuthorizePriKey.Assign("17822967620457187568904804290291537271142779717280482398091401115827760898835")
authCircuit.NoteRandom.Assign("2824204835")
authCircuit.Amount.Assign("28242048")
authCircuit.SpendFlag.Assign("1")
authCircuit.NoteHash.Assign("11183619348394875496624033204802036013086293645689330234403504655205992608466")
authCircuit.Path0.Assign("19561523370160677851616596032513161448778901506614020103852017946679781620105")
authCircuit.Path1.Assign("13898857070666440684265042188056372750257678232709763835292910585848522658637")
authCircuit.Path2.Assign("15019169196974879571470243100379529757970866395477207575033769902587972032431")
authCircuit.Path3.Assign("0")
authCircuit.Path4.Assign("0")
authCircuit.Path5.Assign("0")
authCircuit.Path6.Assign("0")
authCircuit.Path7.Assign("0")
authCircuit.Path8.Assign("0")
authCircuit.Path9.Assign("0")
authCircuit.Helper0.Assign("1")
authCircuit.Helper1.Assign("1")
authCircuit.Helper2.Assign("1")
authCircuit.Helper3.Assign("0")
authCircuit.Helper4.Assign("0")
authCircuit.Helper5.Assign("0")
authCircuit.Helper6.Assign("0")
authCircuit.Helper7.Assign("0")
authCircuit.Helper8.Assign("0")
authCircuit.Helper9.Assign("0")
authCircuit.Valid0.Assign("1")
authCircuit.Valid1.Assign("1")
authCircuit.Valid2.Assign("1")
authCircuit.Valid3.Assign("0")
authCircuit.Valid4.Assign("0")
authCircuit.Valid5.Assign("0")
authCircuit.Valid6.Assign("0")
authCircuit.Valid7.Assign("0")
authCircuit.Valid8.Assign("0")
authCircuit.Valid9.Assign("0")
assert.ProverSucceeded(r1cs, &authCircuit)
}
}
package types
import (
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/hash/mimc"
)
//spend commit hash the circuit implementing
type DepositCircuit struct {
NoteHash frontend.Variable `gnark:",public"`
Amount frontend.Variable `gnark:",public"`
ReceiverPubKey frontend.Variable
ReturnPubKey frontend.Variable
AuthorizePubKey frontend.Variable
NoteRandom frontend.Variable
}
func (circuit *DepositCircuit) Define(curveID ecc.ID, cs *frontend.ConstraintSystem) error {
// hash function
mimc, _ := mimc.NewMiMC("seed", curveID, cs)
mimc.Write(circuit.ReceiverPubKey, circuit.ReturnPubKey, circuit.AuthorizePubKey, circuit.Amount, circuit.NoteRandom)
cs.AssertIsEqual(circuit.NoteHash, mimc.Sum())
return nil
}
package types
import (
"bytes"
"encoding/hex"
"fmt"
"github.com/consensys/gnark/backend/witness"
"github.com/stretchr/testify/assert"
"reflect"
"testing"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/backend"
"github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/frontend"
)
//receiver prikey="10190477835300927557649934238820360529458681672073866116232821892325659279502"
//receiver pubkey="13496572805321444273664325641440458311310163934354047265362731297880627774936"
//return prikey="7969140283216448215269095418467361784159407896899334866715345504515077887397"
//return pubkey="10193030166569398670555398535278072963719579248877156082361830729347727033510"
//authorize prikey="17822967620457187568904804290291537271142779717280482398091401115827760898835"
//authorize pubkey="2302306531516619173363925550130201424458047172090558749779153607734711372580"
//spend prikey="10407830929890509544473717262275616077696950294748419792758056545898949331744"
//spend pubkey="3656010751855274388516368747583374746848682779395325737100877017850943546836"
func TestDeposit(t *testing.T) {
assert := groth16.NewAssert(t)
var depositCircuit DepositCircuit
// compiles our circuit into a R1CS
r1cs, err := frontend.Compile(ecc.BN254, backend.GROTH16, &depositCircuit)
assert.NoError(err)
{
//var witness Deposit
depositCircuit.NoteHash.Assign("11183619348394875496624033204802036013086293645689330234403504655205992608466")
depositCircuit.Amount.Assign(28242048)
depositCircuit.ReceiverPubKey.Assign("13496572805321444273664325641440458311310163934354047265362731297880627774936")
depositCircuit.ReturnPubKey.Assign("10193030166569398670555398535278072963719579248877156082361830729347727033510")
depositCircuit.AuthorizePubKey.Assign("2302306531516619173363925550130201424458047172090558749779153607734711372580")
depositCircuit.NoteRandom.Assign(2824204835)
assert.ProverSucceeded(r1cs, &depositCircuit)
}
var pubBuf bytes.Buffer
witness.WritePublicTo(&pubBuf, ecc.BN254, &depositCircuit)
//fmt.Println("buf",hex.EncodeToString(pubBuf.Bytes()))
pubStr := hex.EncodeToString(pubBuf.Bytes())
var buf bytes.Buffer
pk, vk, err := groth16.Setup(r1cs)
assert.Nil(err)
buf.Reset()
vk.WriteTo(&buf)
//fmt.Println("vk",hex.EncodeToString(buf.Bytes()))
vkStr := hex.EncodeToString(buf.Bytes())
proof, err := groth16.Prove(r1cs, pk, &depositCircuit)
assert.Nil(err)
buf.Reset()
proof.WriteTo(&buf)
//fmt.Println("proof",hex.EncodeToString(buf.Bytes()))
pfStr := hex.EncodeToString(buf.Bytes())
d, _ := hex.DecodeString(vkStr)
vkt := groth16.NewVerifyingKey(ecc.BN254)
buf.Reset()
buf.Write(d)
vkt.ReadFrom(&buf)
d, _ = hex.DecodeString(pfStr)
buf.Reset()
buf.Write(d)
prt := groth16.NewProof(ecc.BN254)
prt.ReadFrom(&buf)
d, _ = hex.DecodeString(pubStr)
buf.Reset()
buf.Write(d)
err = groth16.ReadAndVerify(prt, vkt, &buf)
assert.Nil(err)
}
func TestDepositSetVal(t *testing.T) {
pubInput := "0000000218b9b448bd793dab9075f70ce404a87497b3a2d0d0b5d177441d6cada1e9b2d20000000000000000000000000000000000000000000000000000000001aef080"
str, _ := hex.DecodeString(pubInput)
var buf bytes.Buffer
buf.Write(str)
var val Witness
n, err := val.LimitReadFrom(&buf)
assert.Nil(t, err)
fmt.Println("n=", n)
//val=make([]fr.Element,2)
//val[0].SetInterface(0x18b9b448bd793dab9075f70ce404a87497b3a2d0d0b5d177441d6cada1e9b2d2)
//val[0].set
//val[1].SetInterface(0x0000000000000000000000000000000000000000000000000000000001aef080)
fmt.Println("0=", val[0].String(), "1=", val[1].String())
var depositCircuit DepositCircuit
getVal(&depositCircuit, val)
fmt.Println("deposit", frontend.GetAssignedValue(depositCircuit.NoteHash))
fmt.Println("amount", frontend.GetAssignedValue(depositCircuit.Amount))
}
func getVal(input frontend.Circuit, w Witness) {
tValue := reflect.ValueOf(input)
if tValue.Kind() == reflect.Ptr {
tValue = tValue.Elem()
}
//reft := reflect.TypeOf(input)
fmt.Println("fields", tValue.NumField())
for i, v := range w {
field := tValue.Type().Field((i))
fmt.Println("i=", i, "name=", field.Name)
f := tValue.FieldByName(field.Name)
a := f.Addr().Interface().(*frontend.Variable)
//a:=tValue.Field(i).Interface().(frontend.Variable)
a.Assign(v.String())
}
}
...@@ -46,23 +46,18 @@ const ( ...@@ -46,23 +46,18 @@ const (
//circuits default file name //circuits default file name
const ( const (
DepositCircuit = "circuit_deposit.r1cs" DepositPk = "circuit_deposit.pk"
DepositPk = "circuit_deposit.pk" DepositVk = "circuit_deposit.vk"
DepositVk = "circuit_deposit.vk"
WithdrawCircuit = "circuit_withdraw.r1cs" WithdrawPk = "circuit_withdraw.pk"
WithdrawPk = "circuit_withdraw.pk" WithdrawVk = "circuit_withdraw.vk"
WithdrawVk = "circuit_withdraw.vk"
AuthCircuit = "circuit_auth.r1cs" AuthPk = "circuit_auth.pk"
AuthPk = "circuit_auth.pk" AuthVk = "circuit_auth.vk"
AuthVk = "circuit_auth.vk"
TransInputCircuit = "circuit_transfer_input.r1cs" TransInputPk = "circuit_transfer_input.pk"
TransInputPk = "circuit_transfer_input.pk" TransInputVk = "circuit_transfer_input.vk"
TransInputVk = "circuit_transfer_input.vk"
TransOutputCircuit = "circuit_transfer_output.r1cs" TransOutputPk = "circuit_transfer_output.pk"
TransOutputPk = "circuit_transfer_output.pk" TransOutputVk = "circuit_transfer_output.vk"
TransOutputVk = "circuit_transfer_output.vk"
) )
This source diff could not be displayed because it is too large. You can view the blob instead.
package types
import (
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/hash/mimc"
)
type TransferInputCircuit struct {
TreeRootHash frontend.Variable `gnark:",public"`
AuthorizeSpendHash frontend.Variable `gnark:",public"`
NullifierHash frontend.Variable `gnark:",public"`
ShieldAmountX frontend.Variable `gnark:",public"`
ShieldAmountY frontend.Variable `gnark:",public"`
//secret
ReceiverPubKey frontend.Variable
ReturnPubKey frontend.Variable
AuthorizePubKey frontend.Variable
NoteRandom frontend.Variable
Amount frontend.Variable
AmountRandom frontend.Variable
SpendPriKey frontend.Variable
SpendFlag frontend.Variable
AuthorizeFlag frontend.Variable
NoteHash frontend.Variable
//tree path info
Path0 frontend.Variable
Path1 frontend.Variable
Path2 frontend.Variable
Path3 frontend.Variable
Path4 frontend.Variable
Path5 frontend.Variable
Path6 frontend.Variable
Path7 frontend.Variable
Path8 frontend.Variable
Path9 frontend.Variable
Helper0 frontend.Variable
Helper1 frontend.Variable
Helper2 frontend.Variable
Helper3 frontend.Variable
Helper4 frontend.Variable
Helper5 frontend.Variable
Helper6 frontend.Variable
Helper7 frontend.Variable
Helper8 frontend.Variable
Helper9 frontend.Variable
Valid0 frontend.Variable
Valid1 frontend.Variable
Valid2 frontend.Variable
Valid3 frontend.Variable
Valid4 frontend.Variable
Valid5 frontend.Variable
Valid6 frontend.Variable
Valid7 frontend.Variable
Valid8 frontend.Variable
Valid9 frontend.Variable
}
// Define declares the circuit's constraints
func (circuit *TransferInputCircuit) Define(curveID ecc.ID, cs *frontend.ConstraintSystem) error {
cs.AssertIsBoolean(circuit.SpendFlag)
cs.AssertIsBoolean(circuit.AuthorizeFlag)
// hash function
h, _ := mimc.NewMiMC("seed", curveID, cs)
mimc := &h
//verify spend private key
targetSpendKey := cs.Select(circuit.SpendFlag, circuit.ReceiverPubKey, circuit.ReturnPubKey)
mimc.Write(circuit.SpendPriKey)
cs.AssertIsEqual(targetSpendKey, mimc.Sum())
nullValue := cs.Constant(0)
mimc.Reset()
mimc.Write(targetSpendKey, circuit.Amount, circuit.NoteRandom)
calcAuthSpendHash := mimc.Sum()
targetAuthSpendHash := cs.Select(circuit.AuthorizeFlag, calcAuthSpendHash, nullValue)
cs.AssertIsEqual(circuit.AuthorizeSpendHash, targetAuthSpendHash)
mimc.Reset()
mimc.Write(circuit.NoteRandom)
cs.AssertIsEqual(circuit.NullifierHash, mimc.Sum())
//
calcReturnPubkey := cs.Select(circuit.AuthorizeFlag, circuit.ReturnPubKey, nullValue)
calcAuthPubkey := cs.Select(circuit.AuthorizeFlag, circuit.AuthorizePubKey, nullValue)
mimc.Reset()
mimc.Write(circuit.ReceiverPubKey, calcReturnPubkey, calcAuthPubkey, circuit.Amount, circuit.NoteRandom)
cs.AssertIsEqual(circuit.NoteHash, mimc.Sum())
var proofSet, helper, valid []frontend.Variable
proofSet = append(proofSet, circuit.NoteHash)
proofSet = append(proofSet, circuit.Path0)
proofSet = append(proofSet, circuit.Path1)
proofSet = append(proofSet, circuit.Path2)
proofSet = append(proofSet, circuit.Path3)
proofSet = append(proofSet, circuit.Path4)
proofSet = append(proofSet, circuit.Path5)
proofSet = append(proofSet, circuit.Path6)
proofSet = append(proofSet, circuit.Path7)
proofSet = append(proofSet, circuit.Path8)
proofSet = append(proofSet, circuit.Path9)
//helper[0],valid[0]占位, 方便接口只设置有效值
helper = append(helper, cs.Constant("1"))
helper = append(helper, circuit.Helper0)
helper = append(helper, circuit.Helper1)
helper = append(helper, circuit.Helper2)
helper = append(helper, circuit.Helper3)
helper = append(helper, circuit.Helper4)
helper = append(helper, circuit.Helper5)
helper = append(helper, circuit.Helper6)
helper = append(helper, circuit.Helper7)
helper = append(helper, circuit.Helper8)
helper = append(helper, circuit.Helper9)
valid = append(valid, cs.Constant("1"))
valid = append(valid, circuit.Valid0)
valid = append(valid, circuit.Valid1)
valid = append(valid, circuit.Valid2)
valid = append(valid, circuit.Valid3)
valid = append(valid, circuit.Valid4)
valid = append(valid, circuit.Valid5)
valid = append(valid, circuit.Valid6)
valid = append(valid, circuit.Valid7)
valid = append(valid, circuit.Valid8)
valid = append(valid, circuit.Valid9)
CommitValueVerify(cs, circuit.Amount, circuit.AmountRandom, circuit.ShieldAmountX, circuit.ShieldAmountY)
VerifyMerkleProof(cs, mimc, circuit.TreeRootHash, proofSet, helper, valid)
return nil
}
package types
import (
"testing"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/backend"
"github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/frontend"
)
func TestTransferInputAuth(t *testing.T) {
assert := groth16.NewAssert(t)
var inputCircuit TransferInputCircuit
// compiles our circuit into a R1CS
r1cs, err := frontend.Compile(ecc.BN254, backend.GROTH16, &inputCircuit)
assert.NoError(err)
{
inputCircuit.TreeRootHash.Assign("950328190378475063285997697131233976268556642407874368795731039491163033995")
inputCircuit.AuthorizeSpendHash.Assign("21866258877426223880121052705448065394371888667902748431050285218933372701264")
inputCircuit.NullifierHash.Assign("18261754976334473090934939020486888794395514077667802499672726421629833403191")
inputCircuit.ShieldAmountX.Assign("2999198834503527181782558341022909853195739283744640133924786234819945005771")
inputCircuit.ShieldAmountY.Assign("19443413539487113257436159186910517766382570615508121086985490610335878889881")
inputCircuit.ReceiverPubKey.Assign("13496572805321444273664325641440458311310163934354047265362731297880627774936")
inputCircuit.ReturnPubKey.Assign("10193030166569398670555398535278072963719579248877156082361830729347727033510")
inputCircuit.AuthorizePubKey.Assign("2302306531516619173363925550130201424458047172090558749779153607734711372580")
inputCircuit.NoteRandom.Assign("2824204835")
inputCircuit.Amount.Assign("28242048")
inputCircuit.AmountRandom.Assign("282420481")
inputCircuit.SpendPriKey.Assign("10190477835300927557649934238820360529458681672073866116232821892325659279502")
inputCircuit.SpendFlag.Assign("1")
inputCircuit.AuthorizeFlag.Assign("1")
inputCircuit.NoteHash.Assign("11183619348394875496624033204802036013086293645689330234403504655205992608466")
inputCircuit.Path0.Assign("19561523370160677851616596032513161448778901506614020103852017946679781620105")
inputCircuit.Path1.Assign("13898857070666440684265042188056372750257678232709763835292910585848522658637")
inputCircuit.Path2.Assign("15019169196974879571470243100379529757970866395477207575033769902587972032431")
inputCircuit.Path3.Assign("0")
inputCircuit.Path4.Assign("0")
inputCircuit.Path5.Assign("0")
inputCircuit.Path6.Assign("0")
inputCircuit.Path7.Assign("0")
inputCircuit.Path8.Assign("0")
inputCircuit.Path9.Assign("0")
inputCircuit.Helper0.Assign("1")
inputCircuit.Helper1.Assign("1")
inputCircuit.Helper2.Assign("1")
inputCircuit.Helper3.Assign("0")
inputCircuit.Helper4.Assign("0")
inputCircuit.Helper5.Assign("0")
inputCircuit.Helper6.Assign("0")
inputCircuit.Helper7.Assign("0")
inputCircuit.Helper8.Assign("0")
inputCircuit.Helper9.Assign("0")
inputCircuit.Valid0.Assign("1")
inputCircuit.Valid1.Assign("1")
inputCircuit.Valid2.Assign("1")
inputCircuit.Valid3.Assign("0")
inputCircuit.Valid4.Assign("0")
inputCircuit.Valid5.Assign("0")
inputCircuit.Valid6.Assign("0")
inputCircuit.Valid7.Assign("0")
inputCircuit.Valid8.Assign("0")
inputCircuit.Valid9.Assign("0")
assert.ProverSucceeded(r1cs, &inputCircuit)
}
}
//
//func TestTransferInputReturnKey(t *testing.T) {
//
// assert := groth16.NewAssert(t)
//
// r1cs := NewTransferInput()
// r1csBN256 := backend_bn256.Cast(r1cs)
// {
// good := backend.NewAssignment()
// good.Assign(backend.Public, "treeRootHash", "10531321614990797034921282585661869614556487056951485265320464926630499341310")
// good.Assign(backend.Public, "shieldAmountX", "14087975867275911077371231345227824611951436822132762463787130558957838320348")
// good.Assign(backend.Public, "shieldAmountY", "15113519960384204624879642069520481336224311978035289236693658603675385299879")
// good.Assign(backend.Public, "authorizeSpendHash", "6026163592877030954825395224309219861774131411806846860652261047183070579370")
// good.Assign(backend.Public, "nullifierHash", "6747518781649068310795677405858353007442326529625450860668944156162052335195")
//
// good.Assign(backend.Secret, "amount", "28242048")
// good.Assign(backend.Secret, "amountRandom", "35")
//
// good.Assign(backend.Secret, "receiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705")
// good.Assign(backend.Secret, "returnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497")
// good.Assign(backend.Secret, "authorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583")
//
// good.Assign(backend.Secret, "spendPriKey", "7969140283216448215269095418467361784159407896899334866715345504515077887397")
// //returnkey spend notehash
// good.Assign(backend.Secret, "spendFlag", "0")
//
// good.Assign(backend.Secret, "authorizeFlag", "1")
//
// good.Assign(backend.Secret, "noteRandom", "2824204835")
//
// good.Assign(backend.Secret, "noteHash", "16308793397024662832064523892418908145900866571524124093537199035808550255649")
//
// //nodehash="16308793397024662832064523892418908145900866571524124093537199035808550255649"
// good.Assign(backend.Secret, "path1", "19561523370160677851616596032513161448778901506614020103852017946679781620105")
// good.Assign(backend.Secret, "path2", "13898857070666440684265042188056372750257678232709763835292910585848522658637")
// good.Assign(backend.Secret, "path3", "15019169196974879571470243100379529757970866395477207575033769902587972032431")
// good.Assign(backend.Secret, "path4", "0")
// good.Assign(backend.Secret, "path5", "0")
// good.Assign(backend.Secret, "path6", "0")
// good.Assign(backend.Secret, "path7", "0")
// good.Assign(backend.Secret, "path8", "0")
// good.Assign(backend.Secret, "path9", "0")
//
// good.Assign(backend.Secret, "helper1", "1")
// good.Assign(backend.Secret, "helper2", "1")
// good.Assign(backend.Secret, "helper3", "1")
// good.Assign(backend.Secret, "helper4", "0")
// good.Assign(backend.Secret, "helper5", "0")
// good.Assign(backend.Secret, "helper6", "0")
// good.Assign(backend.Secret, "helper7", "0")
// good.Assign(backend.Secret, "helper8", "0")
// good.Assign(backend.Secret, "helper9", "0")
//
// good.Assign(backend.Secret, "valid1", "1")
// good.Assign(backend.Secret, "valid2", "1")
// good.Assign(backend.Secret, "valid3", "1")
// good.Assign(backend.Secret, "valid4", "0")
// good.Assign(backend.Secret, "valid5", "0")
// good.Assign(backend.Secret, "valid6", "0")
// good.Assign(backend.Secret, "valid7", "0")
// good.Assign(backend.Secret, "valid8", "0")
// good.Assign(backend.Secret, "valid9", "0")
//
// assert.Solved(&r1csBN256, good, nil)
// }
//
//}
//
//func TestTransferInputNoAuthorize(t *testing.T) {
//
// assert := groth16.NewAssert(t)
//
// r1cs := NewTransferInput()
// r1csBN256 := backend_bn256.Cast(r1cs)
// {
// good := backend.NewAssignment()
// good.Assign(backend.Public, "treeRootHash", "8924377726623516198388981994706612588174229761660626844219523809311621081152")
// good.Assign(backend.Public, "shieldAmountX", "20026900249169569699397829614948056401416692452575929785554743563301443795984")
// good.Assign(backend.Public, "shieldAmountY", "11443294504840468048882645872852838384649876010412151915870299030068051779303")
// good.Assign(backend.Public, "authorizeSpendHash", "0")
// good.Assign(backend.Public, "nullifierHash", "4493238794492517147695618716694376637191823831910850819304582851540887491471")
//
// good.Assign(backend.Secret, "amount", "500000000")
// good.Assign(backend.Secret, "amountRandom", "103649245823269378598256096359743803233")
//
// good.Assign(backend.Secret, "receiverPubKey", "7244551457692363731356498279463138379576484998878425864678733206990733443457")
// good.Assign(backend.Secret, "returnPubKey", "0")
// good.Assign(backend.Secret, "authorizePubKey", "0")
//
// good.Assign(backend.Secret, "spendPriKey", "19115616183616714814727844928908633989028519974595353009754871398745087846141")
// good.Assign(backend.Secret, "spendFlag", "1")
// //not need authorize
// good.Assign(backend.Secret, "authorizeFlag", "0")
//
// good.Assign(backend.Secret, "noteRandom", "16855817802811010832998322637530013398737002960466904173163094025121554818471")
//
// good.Assign(backend.Secret, "noteHash", "4757455985754753449547885621755931629265767091930770913671501411452663313694")
//
// good.Assign(backend.Secret, "path1", "21609869341494920403470153054548069228540665950349313465330160010270609674984")
// good.Assign(backend.Secret, "path2", "0")
// good.Assign(backend.Secret, "path3", "0")
// good.Assign(backend.Secret, "path4", "0")
// good.Assign(backend.Secret, "path5", "0")
// good.Assign(backend.Secret, "path6", "0")
// good.Assign(backend.Secret, "path7", "0")
// good.Assign(backend.Secret, "path8", "0")
// good.Assign(backend.Secret, "path9", "0")
//
// good.Assign(backend.Secret, "helper1", "0")
// good.Assign(backend.Secret, "helper2", "1")
// good.Assign(backend.Secret, "helper3", "1")
// good.Assign(backend.Secret, "helper4", "0")
// good.Assign(backend.Secret, "helper5", "0")
// good.Assign(backend.Secret, "helper6", "0")
// good.Assign(backend.Secret, "helper7", "0")
// good.Assign(backend.Secret, "helper8", "0")
// good.Assign(backend.Secret, "helper9", "0")
//
// good.Assign(backend.Secret, "valid1", "1")
// good.Assign(backend.Secret, "valid2", "0")
// good.Assign(backend.Secret, "valid3", "0")
// good.Assign(backend.Secret, "valid4", "0")
// good.Assign(backend.Secret, "valid5", "0")
// good.Assign(backend.Secret, "valid6", "0")
// good.Assign(backend.Secret, "valid7", "0")
// good.Assign(backend.Secret, "valid8", "0")
// good.Assign(backend.Secret, "valid9", "0")
//
// assert.Solved(&r1csBN256, good, nil)
// }
//
//}
package types
import (
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/hash/mimc"
)
type TransferOutputCircuit struct {
//public
NoteHash frontend.Variable `gnark:",public"`
ShieldAmountX frontend.Variable `gnark:",public"`
ShieldAmountY frontend.Variable `gnark:",public"`
//secret
ReceiverPubKey frontend.Variable
ReturnPubKey frontend.Variable
AuthorizePubKey frontend.Variable
NoteRandom frontend.Variable
Amount frontend.Variable
AmountRandom frontend.Variable
}
// Define declares the circuit's constraints
func (circuit *TransferOutputCircuit) Define(curveID ecc.ID, cs *frontend.ConstraintSystem) error {
// hash function
h, _ := mimc.NewMiMC("seed", curveID, cs)
mimc := &h
mimc.Write(circuit.ReceiverPubKey, circuit.ReturnPubKey, circuit.AuthorizePubKey, circuit.Amount, circuit.NoteRandom)
cs.AssertIsEqual(circuit.NoteHash, mimc.Sum())
CommitValueVerify(cs, circuit.Amount, circuit.AmountRandom, circuit.ShieldAmountX, circuit.ShieldAmountY)
return nil
}
package types
import (
"testing"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/backend"
"github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/frontend"
)
func TestTransferOutput(t *testing.T) {
assert := groth16.NewAssert(t)
var outCircuit TransferOutputCircuit
// compiles our circuit into a R1CS
r1cs, err := frontend.Compile(ecc.BN254, backend.GROTH16, &outCircuit)
assert.NoError(err)
{
outCircuit.NoteHash.Assign("11183619348394875496624033204802036013086293645689330234403504655205992608466")
outCircuit.ShieldAmountX.Assign("2999198834503527181782558341022909853195739283744640133924786234819945005771")
outCircuit.ShieldAmountY.Assign("19443413539487113257436159186910517766382570615508121086985490610335878889881")
outCircuit.ReceiverPubKey.Assign("13496572805321444273664325641440458311310163934354047265362731297880627774936")
outCircuit.ReturnPubKey.Assign("10193030166569398670555398535278072963719579248877156082361830729347727033510")
outCircuit.AuthorizePubKey.Assign("2302306531516619173363925550130201424458047172090558749779153607734711372580")
outCircuit.NoteRandom.Assign("2824204835")
outCircuit.Amount.Assign("28242048")
outCircuit.AmountRandom.Assign("282420481")
assert.ProverSucceeded(r1cs, &outCircuit)
}
}
...@@ -5,19 +5,12 @@ ...@@ -5,19 +5,12 @@
package types package types
import ( import (
"bytes"
"encoding/hex"
"encoding/json"
"reflect" "reflect"
"github.com/pkg/errors"
log "github.com/33cn/chain33/common/log/log15" log "github.com/33cn/chain33/common/log/log15"
coins "github.com/33cn/chain33/system/dapp/coins/types" coins "github.com/33cn/chain33/system/dapp/coins/types"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
token "github.com/33cn/plugin/plugin/dapp/token/types" token "github.com/33cn/plugin/plugin/dapp/token/types"
"github.com/consensys/gurvy/bn256/fr"
"github.com/consensys/gurvy/bn256/twistededwards"
) )
var ( var (
...@@ -78,7 +71,7 @@ func (p *MixType) GetLogMap() map[int64]*types.LogInfo { ...@@ -78,7 +71,7 @@ func (p *MixType) GetLogMap() map[int64]*types.LogInfo {
TyLogSubRoots: {Ty: reflect.TypeOf(ReceiptCommitSubRoots{}), Name: "LogSubRoots"}, TyLogSubRoots: {Ty: reflect.TypeOf(ReceiptCommitSubRoots{}), Name: "LogSubRoots"},
TyLogArchiveRootLeaves: {Ty: reflect.TypeOf(ReceiptArchiveLeaves{}), Name: "LogArchiveRootLeaves"}, TyLogArchiveRootLeaves: {Ty: reflect.TypeOf(ReceiptArchiveLeaves{}), Name: "LogArchiveRootLeaves"},
TyLogCommitTreeArchiveRoot: {Ty: reflect.TypeOf(ReceiptArchiveTreeRoot{}), Name: "LogCommitTreeArchiveRoot"}, TyLogCommitTreeArchiveRoot: {Ty: reflect.TypeOf(ReceiptArchiveTreeRoot{}), Name: "LogCommitTreeArchiveRoot"},
TyLogMixConfigPaymentKey: {Ty: reflect.TypeOf(PaymentKey{}), Name: "LogConfigReceivingKey"}, TyLogMixConfigPaymentKey: {Ty: reflect.TypeOf(NoteAccountKey{}), Name: "LogConfigReceivingKey"},
TyLogNulliferSet: {Ty: reflect.TypeOf(ExistValue{}), Name: "LogNullifierSet"}, TyLogNulliferSet: {Ty: reflect.TypeOf(ExistValue{}), Name: "LogNullifierSet"},
} }
} }
...@@ -99,126 +92,6 @@ func (p *MixType) GetPayload() types.Message { ...@@ -99,126 +92,6 @@ func (p *MixType) GetPayload() types.Message {
return &MixAction{} return &MixAction{}
} }
func DecodePubInput(ty VerifyType, input string) (interface{}, error) {
data, err := hex.DecodeString(input)
if err != nil {
return nil, errors.Wrapf(err, "decode string=%s", input)
}
switch ty {
case VerifyType_DEPOSIT:
var v DepositPublicInput
err = json.Unmarshal(data, &v)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal string=%s", input)
}
return &v, nil
case VerifyType_WITHDRAW:
var v WithdrawPublicInput
err = json.Unmarshal(data, &v)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal string=%s", input)
}
return &v, nil
case VerifyType_TRANSFERINPUT:
var v TransferInputPublicInput
err = json.Unmarshal(data, &v)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal string=%s", input)
}
return &v, nil
case VerifyType_TRANSFEROUTPUT:
var v TransferOutputPublicInput
err = json.Unmarshal(data, &v)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal string=%s", input)
}
return &v, nil
case VerifyType_AUTHORIZE:
var v AuthorizePublicInput
err = json.Unmarshal(data, &v)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal string=%s", input)
}
return &v, nil
}
return nil, types.ErrInvalidParam
}
func MulCurvePointG(val interface{}) *twistededwards.Point {
v := fr.FromInterface(val)
var point twistededwards.Point
ed := twistededwards.GetEdwardsCurve()
point.ScalarMul(&ed.Base, *v.FromMont())
return &point
}
func MulCurvePointH(pointHX, pointHY, val string) *twistededwards.Point {
v := fr.FromInterface(val)
var pointV, pointH twistededwards.Point
pointH.X.SetString(pointHX)
pointH.Y.SetString(pointHY)
pointV.ScalarMul(&pointH, *v.FromMont())
return &pointV
}
func GetCurveSum(points ...*twistededwards.Point) *twistededwards.Point {
//Add之前需初始化pointSum,不能空值,不然会等于0
pointSum := twistededwards.NewPoint(points[0].X, points[0].Y)
for _, a := range points[1:] {
pointSum.Add(&pointSum, a)
}
return &pointSum
}
//A=B+C
func CheckSumEqual(points ...*twistededwards.Point) bool {
if len(points) < 2 {
return false
}
//Add之前需初始化pointSum,不能空值,不然会等于0
pointSum := twistededwards.NewPoint(points[1].X, points[1].Y)
for _, a := range points[2:] {
pointSum.Add(&pointSum, a)
}
if pointSum.X.Equal(&points[0].X) && pointSum.Y.Equal(&points[0].Y) {
return true
}
return false
}
func GetByteBuff(input string) (*bytes.Buffer, error) {
var buffInput bytes.Buffer
res, err := hex.DecodeString(input)
if err != nil {
return nil, errors.Wrapf(err, "getByteBuff to %s", input)
}
buffInput.Write(res)
return &buffInput, nil
}
func Str2Byte(v string) []byte {
var fr fr.Element
fr.SetString(v)
return fr.Bytes()
}
func Byte2Str(v []byte) string {
var f fr.Element
f.SetBytes(v)
return f.String()
}
func GetFrRandom() string {
var f fr.Element
return f.SetRandom().String()
}
func GetAssetExecSymbol(cfg *types.Chain33Config, execer, symbol string) (string, string) { func GetAssetExecSymbol(cfg *types.Chain33Config, execer, symbol string) (string, string) {
if symbol == "" { if symbol == "" {
return coins.CoinsX, cfg.GetCoinSymbol() return coins.CoinsX, cfg.GetCoinSymbol()
......
package types
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestMulCurvePointG(t *testing.T) {
p := MulCurvePointG(3300000)
assert.Equal(t, "16340309671848023141603674621476146712179749929747125480153351030768864391631", p.X.String())
assert.Equal(t, "7282133334630698770430559968655675427988723121976895210725923327624387185615", p.Y.String())
}
package types
import (
"bytes"
"encoding/binary"
"encoding/hex"
"github.com/consensys/gnark-crypto/ecc"
bn254 "github.com/consensys/gnark-crypto/ecc/bn254/twistededwards"
"github.com/consensys/gnark/frontend"
"github.com/pkg/errors"
"io"
"math/big"
"reflect"
"github.com/consensys/gnark/std/algebra/twistededwards"
"github.com/consensys/gnark/std/hash/mimc"
ecc_bn254 "github.com/consensys/gnark-crypto/ecc/bn254"
"github.com/consensys/gnark-crypto/ecc/bn254/fr"
)
type Witness []fr.Element
func (witness *Witness) LimitReadFrom(r io.Reader) (int64, error) {
var buf [4]byte
if read, err := io.ReadFull(r, buf[:4]); err != nil {
return int64(read), err
}
sliceLen := binary.BigEndian.Uint32(buf[:4])
if len(*witness) != int(sliceLen) {
*witness = make([]fr.Element, sliceLen)
}
lr := io.LimitReader(r, int64(sliceLen*fr.Limbs*8))
dec := ecc_bn254.NewDecoder(lr)
for i := 0; i < int(sliceLen); i++ {
if err := dec.Decode(&(*witness)[i]); err != nil {
return dec.BytesRead() + 4, err
}
}
return dec.BytesRead() + 4, nil
}
func VerifyMerkleProof(cs *frontend.ConstraintSystem, mimc *mimc.MiMC, treeRootHash frontend.Variable, proofSet, helper, valid []frontend.Variable) {
sum := leafSum(mimc, proofSet[0])
for i := 1; i < len(proofSet); i++ {
cs.AssertIsBoolean(helper[i])
d1 := cs.Select(helper[i], sum, proofSet[i])
d2 := cs.Select(helper[i], proofSet[i], sum)
rst := nodeSum(mimc, d1, d2)
sum = cs.Select(valid[i], rst, sum)
}
// Compare our calculated Merkle root to the desired Merkle root.
cs.AssertIsEqual(sum, treeRootHash)
}
// nodeSum returns the hash created from data inserted to form a leaf.
// Without domain separation.
func nodeSum(mimc *mimc.MiMC, a, b frontend.Variable) frontend.Variable {
mimc.Reset()
mimc.Write(a, b)
return mimc.Sum()
}
// leafSum returns the hash created from data inserted to form a leaf.
// Without domain separation.
func leafSum(mimc *mimc.MiMC, data frontend.Variable) frontend.Variable {
mimc.Reset()
mimc.Write(data)
return mimc.Sum()
}
func CommitValueVerify(cs *frontend.ConstraintSystem, amount, amountRandom, shieldAmountX, shieldAmountY frontend.Variable) {
cs.AssertIsLessOrEqual(amount, 9000000000000000000)
curve, _ := twistededwards.NewEdCurve(ecc.BN254)
var pointAmount twistededwards.Point
pointAmount.ScalarMulFixedBase(cs, curve.BaseX, curve.BaseY, amount, curve)
var pointH bn254.PointAffine
pointH.X.SetString("9252662952969393856711468743327022054484546162727338092576697495684140272191")
pointH.Y.SetString("8220002160263982499510761441032261960817037857915665984040705585999508400744")
var pointRandom twistededwards.Point
pointRandom.ScalarMulFixedBase(cs, pointH.X, pointH.Y, amountRandom, curve)
var pointSum twistededwards.Point
pointSum.AddGeneric(cs, &pointAmount, &pointRandom, curve)
cs.AssertIsEqual(pointSum.X, shieldAmountX)
cs.AssertIsEqual(pointSum.Y, shieldAmountY)
}
func ConstructCircuitPubInput(pubInput string, circuit frontend.Circuit) error {
buf, err := GetByteBuff(pubInput)
if err != nil {
return errors.Wrapf(err, "decode string=%s", pubInput)
}
var witness Witness
_, err = witness.LimitReadFrom(buf)
if err != nil {
return errors.Wrapf(err, "LimitReadFrom pub input=%s", pubInput)
}
tValue := reflect.ValueOf(circuit)
if tValue.Kind() == reflect.Ptr {
tValue = tValue.Elem()
}
for i, v := range witness {
field := tValue.Type().Field(i)
tValue.FieldByName(field.Name).Addr().Interface().(*frontend.Variable).Assign(v.String())
}
return nil
}
func MulCurvePointG(val interface{}) *bn254.PointAffine {
var v fr.Element
v.SetInterface(val)
var scale big.Int
v.ToBigIntRegular(&scale)
var point bn254.PointAffine
ed := bn254.GetEdwardsCurve()
point.ScalarMul(&ed.Base, &scale)
return &point
}
func MulCurvePointH(pointHX, pointHY, val string) *bn254.PointAffine {
var v fr.Element
v.SetInterface(val)
var scale big.Int
v.ToBigIntRegular(&scale)
var pointV, pointH bn254.PointAffine
pointH.X.SetString(pointHX)
pointH.Y.SetString(pointHY)
pointV.ScalarMul(&pointH, &scale)
return &pointV
}
func GetCurveSum(points ...*bn254.PointAffine) *bn254.PointAffine {
//Add之前需初始化pointSum,不能空值,不然会等于0
pointSum := bn254.NewPointAffine(points[0].X, points[0].Y)
for _, a := range points[1:] {
pointSum.Add(&pointSum, a)
}
return &pointSum
}
//A=B+C
func CheckSumEqual(points ...*bn254.PointAffine) bool {
if len(points) < 2 {
return false
}
//Add之前需初始化pointSum,不能空值,不然会等于0
pointSum := bn254.NewPointAffine(points[1].X, points[1].Y)
for _, a := range points[2:] {
pointSum.Add(&pointSum, a)
}
if pointSum.X.Equal(&points[0].X) && pointSum.Y.Equal(&points[0].Y) {
return true
}
return false
}
func GetByteBuff(input string) (*bytes.Buffer, error) {
var buffInput bytes.Buffer
res, err := hex.DecodeString(input)
if err != nil {
return nil, errors.Wrapf(err, "getByteBuff to %s", input)
}
_, err = buffInput.Write(res)
if err != nil {
return nil, errors.Wrapf(err, "write buff %s", input)
}
return &buffInput, nil
}
func Str2Byte(v string) []byte {
var fr fr.Element
fr.SetString(v)
b := fr.Bytes()
return b[:]
}
func Byte2Str(v []byte) string {
var f fr.Element
f.SetBytes(v)
return f.String()
}
package types
import (
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/hash/mimc"
)
type WithdrawCircuit struct {
//public
TreeRootHash frontend.Variable `gnark:",public"`
AuthorizeSpendHash frontend.Variable `gnark:",public"`
NullifierHash frontend.Variable `gnark:",public"`
Amount frontend.Variable `gnark:",public"`
//secret
ReceiverPubKey frontend.Variable
ReturnPubKey frontend.Variable
AuthorizePubKey frontend.Variable
NoteRandom frontend.Variable
SpendPriKey frontend.Variable
SpendFlag frontend.Variable
AuthorizeFlag frontend.Variable
//tree path info
NoteHash frontend.Variable
Path0 frontend.Variable
Path1 frontend.Variable
Path2 frontend.Variable
Path3 frontend.Variable
Path4 frontend.Variable
Path5 frontend.Variable
Path6 frontend.Variable
Path7 frontend.Variable
Path8 frontend.Variable
Path9 frontend.Variable
Helper0 frontend.Variable
Helper1 frontend.Variable
Helper2 frontend.Variable
Helper3 frontend.Variable
Helper4 frontend.Variable
Helper5 frontend.Variable
Helper6 frontend.Variable
Helper7 frontend.Variable
Helper8 frontend.Variable
Helper9 frontend.Variable
Valid0 frontend.Variable
Valid1 frontend.Variable
Valid2 frontend.Variable
Valid3 frontend.Variable
Valid4 frontend.Variable
Valid5 frontend.Variable
Valid6 frontend.Variable
Valid7 frontend.Variable
Valid8 frontend.Variable
Valid9 frontend.Variable
}
// Define declares the circuit's constraints
func (circuit *WithdrawCircuit) Define(curveID ecc.ID, cs *frontend.ConstraintSystem) error {
cs.AssertIsBoolean(circuit.SpendFlag)
cs.AssertIsBoolean(circuit.AuthorizeFlag)
// hash function
h, _ := mimc.NewMiMC("seed", curveID, cs)
mimc := &h
mimc.Write(circuit.SpendPriKey)
targetSpendKey := cs.Select(circuit.SpendFlag, circuit.ReceiverPubKey, circuit.ReturnPubKey)
cs.AssertIsEqual(targetSpendKey, mimc.Sum())
nullValue := cs.Constant(0)
mimc.Reset()
mimc.Write(targetSpendKey, circuit.Amount, circuit.NoteRandom)
calcAuthHash := mimc.Sum()
targetAuthHash := cs.Select(circuit.AuthorizeFlag, calcAuthHash, nullValue)
cs.AssertIsEqual(circuit.AuthorizeSpendHash, targetAuthHash)
mimc.Reset()
mimc.Write(circuit.NoteRandom)
cs.AssertIsEqual(circuit.NullifierHash, mimc.Sum())
calcReturnPubkey := cs.Select(circuit.AuthorizeFlag, circuit.ReturnPubKey, nullValue)
calcAuthPubkey := cs.Select(circuit.AuthorizeFlag, circuit.AuthorizePubKey, nullValue)
mimc.Reset()
mimc.Write(circuit.ReceiverPubKey, calcReturnPubkey, calcAuthPubkey, circuit.Amount, circuit.NoteRandom)
cs.AssertIsEqual(circuit.NoteHash, mimc.Sum())
var proofSet, helper, valid []frontend.Variable
proofSet = append(proofSet, circuit.NoteHash)
proofSet = append(proofSet, circuit.Path0)
proofSet = append(proofSet, circuit.Path1)
proofSet = append(proofSet, circuit.Path2)
proofSet = append(proofSet, circuit.Path3)
proofSet = append(proofSet, circuit.Path4)
proofSet = append(proofSet, circuit.Path5)
proofSet = append(proofSet, circuit.Path6)
proofSet = append(proofSet, circuit.Path7)
proofSet = append(proofSet, circuit.Path8)
proofSet = append(proofSet, circuit.Path9)
//helper[0],valid[0]占位, 方便接口只设置有效值
helper = append(helper, cs.Constant("1"))
helper = append(helper, circuit.Helper0)
helper = append(helper, circuit.Helper1)
helper = append(helper, circuit.Helper2)
helper = append(helper, circuit.Helper3)
helper = append(helper, circuit.Helper4)
helper = append(helper, circuit.Helper5)
helper = append(helper, circuit.Helper6)
helper = append(helper, circuit.Helper7)
helper = append(helper, circuit.Helper8)
helper = append(helper, circuit.Helper9)
valid = append(valid, cs.Constant("1"))
valid = append(valid, circuit.Valid0)
valid = append(valid, circuit.Valid1)
valid = append(valid, circuit.Valid2)
valid = append(valid, circuit.Valid3)
valid = append(valid, circuit.Valid4)
valid = append(valid, circuit.Valid5)
valid = append(valid, circuit.Valid6)
valid = append(valid, circuit.Valid7)
valid = append(valid, circuit.Valid8)
valid = append(valid, circuit.Valid9)
VerifyMerkleProof(cs, mimc, circuit.TreeRootHash, proofSet, helper, valid)
return nil
}
package types
import (
"testing"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/backend"
"github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/frontend"
)
func TestWithdraw(t *testing.T) {
assert := groth16.NewAssert(t)
var withdrawCircuit WithdrawCircuit
// compiles our circuit into a R1CS
r1cs, err := frontend.Compile(ecc.BN254, backend.GROTH16, &withdrawCircuit)
assert.NoError(err)
{
withdrawCircuit.TreeRootHash.Assign("950328190378475063285997697131233976268556642407874368795731039491163033995")
withdrawCircuit.AuthorizeSpendHash.Assign("21866258877426223880121052705448065394371888667902748431050285218933372701264")
withdrawCircuit.NullifierHash.Assign("18261754976334473090934939020486888794395514077667802499672726421629833403191")
withdrawCircuit.Amount.Assign("28242048")
withdrawCircuit.ReceiverPubKey.Assign("13496572805321444273664325641440458311310163934354047265362731297880627774936")
withdrawCircuit.ReturnPubKey.Assign("10193030166569398670555398535278072963719579248877156082361830729347727033510")
withdrawCircuit.AuthorizePubKey.Assign("2302306531516619173363925550130201424458047172090558749779153607734711372580")
withdrawCircuit.NoteRandom.Assign("2824204835")
withdrawCircuit.SpendPriKey.Assign("10190477835300927557649934238820360529458681672073866116232821892325659279502")
withdrawCircuit.SpendFlag.Assign("1")
withdrawCircuit.AuthorizeFlag.Assign("1")
withdrawCircuit.NoteHash.Assign("11183619348394875496624033204802036013086293645689330234403504655205992608466")
withdrawCircuit.Path0.Assign("19561523370160677851616596032513161448778901506614020103852017946679781620105")
withdrawCircuit.Path1.Assign("13898857070666440684265042188056372750257678232709763835292910585848522658637")
withdrawCircuit.Path2.Assign("15019169196974879571470243100379529757970866395477207575033769902587972032431")
withdrawCircuit.Path3.Assign("0")
withdrawCircuit.Path4.Assign("0")
withdrawCircuit.Path5.Assign("0")
withdrawCircuit.Path6.Assign("0")
withdrawCircuit.Path7.Assign("0")
withdrawCircuit.Path8.Assign("0")
withdrawCircuit.Path9.Assign("0")
withdrawCircuit.Helper0.Assign("1")
withdrawCircuit.Helper1.Assign("1")
withdrawCircuit.Helper2.Assign("1")
withdrawCircuit.Helper3.Assign("0")
withdrawCircuit.Helper4.Assign("0")
withdrawCircuit.Helper5.Assign("0")
withdrawCircuit.Helper6.Assign("0")
withdrawCircuit.Helper7.Assign("0")
withdrawCircuit.Helper8.Assign("0")
withdrawCircuit.Helper9.Assign("0")
withdrawCircuit.Valid0.Assign("1")
withdrawCircuit.Valid1.Assign("1")
withdrawCircuit.Valid2.Assign("1")
withdrawCircuit.Valid3.Assign("0")
withdrawCircuit.Valid4.Assign("0")
withdrawCircuit.Valid5.Assign("0")
withdrawCircuit.Valid6.Assign("0")
withdrawCircuit.Valid7.Assign("0")
withdrawCircuit.Valid8.Assign("0")
withdrawCircuit.Valid9.Assign("0")
assert.ProverSucceeded(r1cs, &withdrawCircuit)
}
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package wallet
import (
"bytes"
"encoding/hex"
"github.com/pkg/errors"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/types"
wcom "github.com/33cn/chain33/wallet/common"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gnark-crypto/ecc/bn254/fr/mimc"
)
const CECBLOCKSIZE = 32
/*
从secp256k1根私钥创建支票需要的私钥和公钥
payPrivKey = rootPrivKey *G_X25519 这样很难泄露rootPrivKey
支票收款key: ReceiveKey= hash(payPrivKey) --或者*G的X坐标值, 看哪个电路少?
DH加解密key: encryptPubKey= payPrivKey *G_X25519, 也是很安全的,只是电路里面目前不支持x25519
*/
func newPrivacyKey(rootPrivKey []byte) *mixTy.AccountPrivacyKey {
ecdh := X25519()
key := ecdh.PublicKey(rootPrivKey)
payPrivKey := key.([32]byte)
//payPrivKey := mimcHashByte([][]byte{rootPrivKey})
//payPrivKey 可能超出fr的模,spendKey是payPrivKey对fr取的模,有可能和payPrivKey不相等,这里用spendKey取hash
//mimcHashByte 会对输入参数对fr取模,在电路上不会影响ReceiveKey
paymentKey := &mixTy.PaymentKeyPair{}
paymentKey.SpendKey = mixTy.Byte2Str(payPrivKey[:])
paymentKey.ReceiveKey = mixTy.Byte2Str(mimcHashByte([][]byte{mixTy.Str2Byte(paymentKey.SpendKey)}))
encryptKeyPair := &mixTy.EncryptKeyPair{}
pubkey := ecdh.PublicKey(payPrivKey)
//加解密是在x25519域,需要Hex编码,不要使用fr.string, 模范围不同
encryptKeyPair.PrivKey = hex.EncodeToString(payPrivKey[:])
pubData := pubkey.([32]byte)
encryptKeyPair.PubKey = hex.EncodeToString(pubData[:])
privacy := &mixTy.AccountPrivacyKey{}
privacy.PaymentKey = paymentKey
privacy.EncryptKey = encryptKeyPair
return privacy
}
//CEC加密需要保证明文是秘钥的倍数,如果不是,则需要填充明文,在解密时候把填充物去掉
//填充算法有pkcs5,pkcs7, 比如Pkcs5的思想填充的值为填充的长度,比如加密he,不足8
//则填充为he666666, 解密后直接算最后一个值为6,把解密值的后6个Byte去掉即可
func pKCS5Padding(plainText []byte, blockSize int) []byte {
if blockSize < CECBLOCKSIZE {
blockSize = CECBLOCKSIZE
}
padding := blockSize - (len(plainText) % blockSize)
//fmt.Println("pading", "passsize", blockSize, "plaintext", len(plainText), "pad", padding)
padText := bytes.Repeat([]byte{byte(padding)}, padding)
//fmt.Println("padding", padding, "text", common.ToHex(padText[:]))
newText := append(plainText, padText...)
return newText
}
func pKCS5UnPadding(plainText []byte) ([]byte, error) {
length := len(plainText)
number := int(plainText[length-1])
if number > length {
return nil, types.ErrInvalidParam
}
return plainText[:length-number], nil
}
func encryptDataWithPadding(password, data []byte) []byte {
paddingText := pKCS5Padding(data, len(password))
return wcom.CBCEncrypterPrivkey(password, paddingText)
}
func encryptData(peerPubKey string, data []byte) (*mixTy.DHSecret, error) {
ecdh := X25519()
oncePriv, oncePub, err := ecdh.GenerateKey(nil)
if err != nil {
return nil, errors.Wrapf(err, "x25519 generate key")
}
peerPubByte, err := hex.DecodeString(peerPubKey)
if err != nil {
return nil, errors.Wrapf(err, "encrypt Decode peer pubkey=%s", peerPubKey)
}
password := ecdh.ComputeSecret(oncePriv, peerPubByte)
encrypt := encryptDataWithPadding(password, data)
pubData := oncePub.([32]byte)
return &mixTy.DHSecret{OneTimePubKey: hex.EncodeToString(pubData[:]), Secret: common.ToHex(encrypt)}, nil
}
func decryptDataWithPading(password, data []byte) ([]byte, error) {
plainData := wcom.CBCDecrypterPrivkey(password, data)
return pKCS5UnPadding(plainData)
}
func decryptData(selfPrivKey string, peerPubKey string, cryptData []byte) ([]byte, error) {
ecdh := X25519()
self, err := hex.DecodeString(selfPrivKey)
if err != nil {
return nil, errors.Wrapf(err, "decrypt Decode self prikey=%s", selfPrivKey)
}
peer, err := hex.DecodeString(peerPubKey)
if err != nil {
return nil, errors.Wrapf(err, "decrypt Decode peer pubkey=%s", peerPubKey)
}
password := ecdh.ComputeSecret(self, peer)
return decryptDataWithPading(password, cryptData)
}
func mimcHashString(params []string) []byte {
var sum []byte
for _, k := range params {
sum = append(sum, mixTy.Str2Byte(k)...)
}
hash := mimcHashCalc(sum)
return hash
}
func mimcHashByte(params [][]byte) []byte {
var sum []byte
for _, k := range params {
sum = append(sum, k...)
}
hash := mimcHashCalc(sum)
return hash
}
func mimcHashCalc(sum []byte) []byte {
h := mimc.NewMiMC("seed")
h.Write(sum)
return h.Sum(nil)
}
...@@ -80,3 +80,7 @@ func (p *mixPolicy) On_DecryptSecretData(req *mixTy.DecryptSecretData) (types.Me ...@@ -80,3 +80,7 @@ func (p *mixPolicy) On_DecryptSecretData(req *mixTy.DecryptSecretData) (types.Me
func (p *mixPolicy) On_CreateRawTransaction(req *mixTy.CreateRawTxReq) (types.Message, error) { func (p *mixPolicy) On_CreateRawTransaction(req *mixTy.CreateRawTxReq) (types.Message, error) {
return p.createRawTx(req) return p.createRawTx(req)
} }
func (p *mixPolicy) On_CreateZkKeyFile(req *mixTy.CreateZkKeyFileReq) (types.Message, error) {
return p.createZkKeyFile(req)
}
...@@ -7,6 +7,9 @@ package wallet ...@@ -7,6 +7,9 @@ package wallet
import ( import (
"bytes" "bytes"
"encoding/hex" "encoding/hex"
"github.com/consensys/gnark/backend/groth16"
"os"
"path/filepath"
"github.com/33cn/chain33/system/dapp" "github.com/33cn/chain33/system/dapp"
"github.com/pkg/errors" "github.com/pkg/errors"
...@@ -17,138 +20,8 @@ import ( ...@@ -17,138 +20,8 @@ import (
wcom "github.com/33cn/chain33/wallet/common" wcom "github.com/33cn/chain33/wallet/common"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
mimcbn256 "github.com/consensys/gnark/crypto/hash/mimc/bn256"
) )
const CECBLOCKSIZE = 32
/*
从secp256k1根私钥创建支票需要的私钥和公钥
payPrivKey = rootPrivKey *G_X25519 这样很难泄露rootPrivKey
支票收款key: ReceiveKey= hash(payPrivKey) --或者*G的X坐标值, 看哪个电路少?
DH加解密key: encryptPubKey= payPrivKey *G_X25519, 也是很安全的,只是电路里面目前不支持x25519
*/
func newPrivacyKey(rootPrivKey []byte) *mixTy.AccountPrivacyKey {
ecdh := X25519()
key := ecdh.PublicKey(rootPrivKey)
payPrivKey := key.([32]byte)
//payPrivKey := mimcHashByte([][]byte{rootPrivKey})
//payPrivKey 可能超出fr的模,spendKey是payPrivKey对fr取的模,有可能和payPrivKey不相等,这里用spendKey取hash
//mimcHashByte 会对输入参数对fr取模,在电路上不会影响ReceiveKey
paymentKey := &mixTy.PaymentKeyPair{}
paymentKey.SpendKey = mixTy.Byte2Str(payPrivKey[:])
paymentKey.ReceiveKey = mixTy.Byte2Str(mimcHashByte([][]byte{mixTy.Str2Byte(paymentKey.SpendKey)}))
encryptKeyPair := &mixTy.EncryptKeyPair{}
pubkey := ecdh.PublicKey(payPrivKey)
//加解密是在x25519域,需要Hex编码,不要使用fr.string, 模范围不同
encryptKeyPair.PrivKey = hex.EncodeToString(payPrivKey[:])
pubData := pubkey.([32]byte)
encryptKeyPair.PubKey = hex.EncodeToString(pubData[:])
privacy := &mixTy.AccountPrivacyKey{}
privacy.PaymentKey = paymentKey
privacy.EncryptKey = encryptKeyPair
return privacy
}
//CEC加密需要保证明文是秘钥的倍数,如果不是,则需要填充明文,在解密时候把填充物去掉
//填充算法有pkcs5,pkcs7, 比如Pkcs5的思想填充的值为填充的长度,比如加密he,不足8
//则填充为he666666, 解密后直接算最后一个值为6,把解密值的后6个Byte去掉即可
func pKCS5Padding(plainText []byte, blockSize int) []byte {
if blockSize < CECBLOCKSIZE {
blockSize = CECBLOCKSIZE
}
padding := blockSize - (len(plainText) % blockSize)
//fmt.Println("pading", "passsize", blockSize, "plaintext", len(plainText), "pad", padding)
padText := bytes.Repeat([]byte{byte(padding)}, padding)
//fmt.Println("padding", padding, "text", common.ToHex(padText[:]))
newText := append(plainText, padText...)
return newText
}
func pKCS5UnPadding(plainText []byte) ([]byte, error) {
length := len(plainText)
number := int(plainText[length-1])
if number > length {
return nil, types.ErrInvalidParam
}
return plainText[:length-number], nil
}
func encryptDataWithPadding(password, data []byte) []byte {
paddingText := pKCS5Padding(data, len(password))
return wcom.CBCEncrypterPrivkey(password, paddingText)
}
func encryptData(peerPubKey string, data []byte) (*mixTy.DHSecret, error) {
ecdh := X25519()
oncePriv, oncePub, err := ecdh.GenerateKey(nil)
if err != nil {
return nil, errors.Wrapf(err, "x25519 generate key")
}
peerPubByte, err := hex.DecodeString(peerPubKey)
if err != nil {
return nil, errors.Wrapf(err, "encrypt Decode peer pubkey=%s", peerPubKey)
}
password := ecdh.ComputeSecret(oncePriv, peerPubByte)
encrypt := encryptDataWithPadding(password, data)
pubData := oncePub.([32]byte)
return &mixTy.DHSecret{PeerKey: hex.EncodeToString(pubData[:]), Secret: common.ToHex(encrypt)}, nil
}
func decryptDataWithPading(password, data []byte) ([]byte, error) {
plainData := wcom.CBCDecrypterPrivkey(password, data)
return pKCS5UnPadding(plainData)
}
func decryptData(selfPrivKey string, peerPubKey string, cryptData []byte) ([]byte, error) {
ecdh := X25519()
self, err := hex.DecodeString(selfPrivKey)
if err != nil {
return nil, errors.Wrapf(err, "decrypt Decode self prikey=%s", selfPrivKey)
}
peer, err := hex.DecodeString(peerPubKey)
if err != nil {
return nil, errors.Wrapf(err, "decrypt Decode peer pubkey=%s", peerPubKey)
}
password := ecdh.ComputeSecret(self, peer)
return decryptDataWithPading(password, cryptData)
}
func mimcHashString(params []string) []byte {
var sum []byte
for _, k := range params {
//fmt.Println("input:", k)
sum = append(sum, mixTy.Str2Byte(k)...)
}
hash := mimcHashCalc(sum)
//fmt.Println("hash=", getFrString(hash))
return hash
}
func mimcHashByte(params [][]byte) []byte {
var sum []byte
for _, k := range params {
sum = append(sum, k...)
}
hash := mimcHashCalc(sum)
//fmt.Println("hash=", getFrString(hash))
return hash
}
func mimcHashCalc(sum []byte) []byte {
return mimcbn256.Sum("seed", sum)
}
func (p *mixPolicy) getPrivKeyByAddr(addr string) (crypto.PrivKey, error) { func (p *mixPolicy) getPrivKeyByAddr(addr string) (crypto.PrivKey, error) {
//获取指定地址在钱包里的账户信息 //获取指定地址在钱包里的账户信息
Accountstor, err := p.store.GetAccountByAddr(addr) Accountstor, err := p.store.GetAccountByAddr(addr)
...@@ -419,3 +292,46 @@ func (p *mixPolicy) createRawTx(req *mixTy.CreateRawTxReq) (*types.Transaction, ...@@ -419,3 +292,46 @@ func (p *mixPolicy) createRawTx(req *mixTy.CreateRawTxReq) (*types.Transaction,
} }
} }
func (p *mixPolicy) createZkKeyFile(req *mixTy.CreateZkKeyFileReq) (*types.ReplyString, error) {
ccs, err := getCircuit(mixTy.VerifyType(req.Ty))
if err != nil {
return nil, err
}
pkName, vkName, err := getCircuitKeyFileName(mixTy.VerifyType(req.Ty))
if err != nil {
return nil, err
}
var bufPk, bufVk bytes.Buffer
pk, vk, err := groth16.Setup(ccs)
if err != nil {
return nil, errors.Wrapf(err, "setup")
}
pk.WriteRawTo(&bufPk)
vk.WriteRawTo(&bufVk)
file := filepath.Join(req.SavePath, pkName)
fPk, err := os.Create(file)
if err != nil {
return nil, errors.Wrapf(err, "create file")
}
defer fPk.Close()
fPk.WriteString(hex.EncodeToString(bufPk.Bytes()))
file = filepath.Join(req.SavePath, vkName)
fVk, err := os.Create(file)
if err != nil {
return nil, errors.Wrapf(err, "create file")
}
defer fVk.Close()
fVk.WriteString(hex.EncodeToString(bufVk.Bytes()))
var res types.ReplyString
res.Data = hex.EncodeToString(bufVk.Bytes())
return &res, nil
}
...@@ -6,6 +6,7 @@ package wallet ...@@ -6,6 +6,7 @@ package wallet
import ( import (
"encoding/hex" "encoding/hex"
"github.com/consensys/gnark/frontend"
"github.com/33cn/chain33/common" "github.com/33cn/chain33/common"
...@@ -61,12 +62,14 @@ func (p *mixPolicy) processMixTx(tx *types.Transaction, height, index int64) (*t ...@@ -61,12 +62,14 @@ func (p *mixPolicy) processMixTx(tx *types.Transaction, height, index int64) (*t
case mixTy.MixActionWithdraw: case mixTy.MixActionWithdraw:
var nulls []string var nulls []string
for _, m := range v.GetWithdraw().Proofs { for _, m := range v.GetWithdraw().Proofs {
out, err := mixTy.DecodePubInput(mixTy.VerifyType_WITHDRAW, m.PublicInput) var v mixTy.WithdrawCircuit
err := mixTy.ConstructCircuitPubInput(m.PublicInput, &v)
if err != nil { if err != nil {
bizlog.Error("processWithdraw decode", "pubInput", m.PublicInput) bizlog.Error("processWithdraw decode", "pubInput", m.PublicInput)
continue continue
} }
nulls = append(nulls, out.(*mixTy.WithdrawPublicInput).NullifierHash) nullHash := frontend.FromInterface(frontend.GetAssignedValue(v.NullifierHash))
nulls = append(nulls, nullHash.String())
} }
p.processNullifiers(nulls, table) p.processNullifiers(nulls, table)
...@@ -92,13 +95,14 @@ func (p *mixPolicy) processMixTx(tx *types.Transaction, height, index int64) (*t ...@@ -92,13 +95,14 @@ func (p *mixPolicy) processMixTx(tx *types.Transaction, height, index int64) (*t
func (p *mixPolicy) processDeposit(deposit *mixTy.MixDepositAction, heightIndex string, table *table.Table) { func (p *mixPolicy) processDeposit(deposit *mixTy.MixDepositAction, heightIndex string, table *table.Table) {
for _, proof := range deposit.Proofs { for _, proof := range deposit.Proofs {
data, err := mixTy.DecodePubInput(mixTy.VerifyType_DEPOSIT, proof.PublicInput) var v mixTy.DepositCircuit
err := mixTy.ConstructCircuitPubInput(proof.PublicInput, &v)
if err != nil { if err != nil {
bizlog.Error("processDeposit decode", "pubInput", proof.PublicInput) bizlog.Error("processDeposit decode", "pubInput", proof.PublicInput)
return return
} }
input := data.(*mixTy.DepositPublicInput) noteHash := frontend.FromInterface(frontend.GetAssignedValue(v.NoteHash))
p.processSecretGroup(input.NoteHash, proof.Secrets, heightIndex, table) p.processSecretGroup(noteHash.String(), proof.Secrets, heightIndex, table)
} }
} }
...@@ -106,45 +110,51 @@ func (p *mixPolicy) processDeposit(deposit *mixTy.MixDepositAction, heightIndex ...@@ -106,45 +110,51 @@ func (p *mixPolicy) processDeposit(deposit *mixTy.MixDepositAction, heightIndex
func (p *mixPolicy) processTransfer(transfer *mixTy.MixTransferAction, heightIndex string, table *table.Table) { func (p *mixPolicy) processTransfer(transfer *mixTy.MixTransferAction, heightIndex string, table *table.Table) {
var nulls []string var nulls []string
for _, in := range transfer.Inputs { for _, in := range transfer.Inputs {
data, err := mixTy.DecodePubInput(mixTy.VerifyType_TRANSFERINPUT, in.PublicInput) var v mixTy.TransferInputCircuit
err := mixTy.ConstructCircuitPubInput(in.PublicInput, &v)
if err != nil { if err != nil {
bizlog.Error("processTransfer.input decode", "pubInput", in.PublicInput) bizlog.Error("processTransfer.input decode", "pubInput", in.PublicInput)
return return
} }
input := data.(*mixTy.TransferInputPublicInput) nullHash := frontend.FromInterface(frontend.GetAssignedValue(v.NullifierHash))
nulls = append(nulls, input.NullifierHash) nulls = append(nulls, nullHash.String())
} }
p.processNullifiers(nulls, table) p.processNullifiers(nulls, table)
//out //out
data, err := mixTy.DecodePubInput(mixTy.VerifyType_TRANSFEROUTPUT, transfer.Output.PublicInput) var out mixTy.TransferOutputCircuit
err := mixTy.ConstructCircuitPubInput(transfer.Output.PublicInput, &out)
if err != nil { if err != nil {
bizlog.Error("processTransfer.output decode", "pubInput", transfer.Output.PublicInput) bizlog.Error("processTransfer.output decode", "pubInput", transfer.Output.PublicInput)
return return
} }
outInput := data.(*mixTy.TransferOutputPublicInput) noteHash := frontend.FromInterface(frontend.GetAssignedValue(out.NoteHash))
p.processSecretGroup(outInput.NoteHash, transfer.Output.Secrets, heightIndex, table) p.processSecretGroup(noteHash.String(), transfer.Output.Secrets, heightIndex, table)
//change //change
data, err = mixTy.DecodePubInput(mixTy.VerifyType_TRANSFEROUTPUT, transfer.Change.PublicInput) var change mixTy.TransferOutputCircuit
err = mixTy.ConstructCircuitPubInput(transfer.Change.PublicInput, &change)
if err != nil { if err != nil {
bizlog.Error("processTransfer.output decode", "pubInput", transfer.Change.PublicInput) bizlog.Error("processTransfer.output decode", "pubInput", transfer.Change.PublicInput)
return return
} }
changeInput := data.(*mixTy.TransferOutputPublicInput) changeNoteHash := frontend.FromInterface(frontend.GetAssignedValue(change.NoteHash))
p.processSecretGroup(changeInput.NoteHash, transfer.Change.Secrets, heightIndex, table) p.processSecretGroup(changeNoteHash.String(), transfer.Change.Secrets, heightIndex, table)
} }
func (p *mixPolicy) processAuth(auth *mixTy.MixAuthorizeAction, table *table.Table) { func (p *mixPolicy) processAuth(auth *mixTy.MixAuthorizeAction, table *table.Table) {
out, err := mixTy.DecodePubInput(mixTy.VerifyType_AUTHORIZE, auth.Proof.PublicInput) var v mixTy.AuthorizeCircuit
err := mixTy.ConstructCircuitPubInput(auth.ProofInfo.PublicInput, &v)
if err != nil { if err != nil {
bizlog.Error("processAuth decode", "pubInput", auth.Proof.PublicInput) bizlog.Error("processAuth decode", "pubInput", auth.ProofInfo.PublicInput)
return return
} }
input := out.(*mixTy.AuthorizePublicInput) authNullHash := frontend.FromInterface(frontend.GetAssignedValue(v.AuthorizeHash))
updateAuthSpend(table, input.AuthorizeSpendHash) updateAuthHash(table, authNullHash.String())
updateAuthHash(table, input.AuthorizeHash)
authSpendHash := frontend.FromInterface(frontend.GetAssignedValue(v.AuthorizeSpendHash))
updateAuthSpend(table, authSpendHash.String())
} }
...@@ -347,7 +357,7 @@ func (p *mixPolicy) decodeSecret(noteHash string, secretData string, privacyKeys ...@@ -347,7 +357,7 @@ func (p *mixPolicy) decodeSecret(noteHash string, secretData string, privacyKeys
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "decode for notehash=%s,crypt=%s", noteHash, dhSecret.Secret) return nil, errors.Wrapf(err, "decode for notehash=%s,crypt=%s", noteHash, dhSecret.Secret)
} }
decryptData, err := decryptData(key.Privacy.EncryptKey.PrivKey, dhSecret.PeerKey, cryptData) decryptData, err := decryptData(key.Privacy.EncryptKey.PrivKey, dhSecret.OneTimePubKey, cryptData)
if err != nil { if err != nil {
bizlog.Debug("processSecret.decryptData fail", "decrypt for notehash", noteHash, "secret", secretData, "addr", key.Addr, "err", err) bizlog.Debug("processSecret.decryptData fail", "decrypt for notehash", noteHash, "secret", secretData, "addr", key.Addr, "err", err)
continue continue
...@@ -359,7 +369,9 @@ func (p *mixPolicy) decodeSecret(noteHash string, secretData string, privacyKeys ...@@ -359,7 +369,9 @@ func (p *mixPolicy) decodeSecret(noteHash string, secretData string, privacyKeys
bizlog.Debug("processSecret.decode rawData fail", "addr", key.Addr, "err", err) bizlog.Debug("processSecret.decode rawData fail", "addr", key.Addr, "err", err)
continue continue
} }
bizlog.Info("processSecret.decode rawData OK", "notehash", noteHash, "addr", key.Addr) bizlog.Info("processSecret.decode rawData OK", "notehash", noteHash, "addr", key.Addr, "receiver", key.Privacy.PaymentKey.ReceiveKey, "recv", rawData.ReceiverKey,
"return", rawData.ReturnKey, "auth", rawData.AuthorizeKey)
//wallet产生deposit tx时候 确保了三个key不同,除非自己构造相同key的交易 //wallet产生deposit tx时候 确保了三个key不同,除非自己构造相同key的交易
if rawData.ReceiverKey == key.Privacy.PaymentKey.ReceiveKey || if rawData.ReceiverKey == key.Privacy.PaymentKey.ReceiveKey ||
rawData.ReturnKey == key.Privacy.PaymentKey.ReceiveKey || rawData.ReturnKey == key.Privacy.PaymentKey.ReceiveKey ||
......
...@@ -41,7 +41,7 @@ func TestNewPrivacyWithPrivKey(t *testing.T) { ...@@ -41,7 +41,7 @@ func TestNewPrivacyWithPrivKey(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
crypData, err := common.FromHex(data.Secret) crypData, err := common.FromHex(data.Secret)
assert.Nil(t, err) assert.Nil(t, err)
decryData1, err := decryptData(pairs.EncryptKey.PrivKey, data.PeerKey, crypData) decryData1, err := decryptData(pairs.EncryptKey.PrivKey, data.OneTimePubKey, crypData)
assert.Nil(t, err) assert.Nil(t, err)
var val mixTy.SecretData var val mixTy.SecretData
err = types.Decode(decryData1, &val) err = types.Decode(decryData1, &val)
...@@ -101,7 +101,7 @@ func TestEncodeSecretData(t *testing.T) { ...@@ -101,7 +101,7 @@ func TestEncodeSecretData(t *testing.T) {
data, err := common.FromHex(dhSecret.Secret) data, err := common.FromHex(dhSecret.Secret)
assert.Nil(t, err) assert.Nil(t, err)
rawData, err := decryptData(privacy.EncryptKey.PrivKey, dhSecret.PeerKey, data) rawData, err := decryptData(privacy.EncryptKey.PrivKey, dhSecret.OneTimePubKey, data)
assert.Nil(t, err) assert.Nil(t, err)
var rawSecret mixTy.SecretData var rawSecret mixTy.SecretData
types.Decode(rawData, &rawSecret) types.Decode(rawData, &rawSecret)
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package wallet package wallet
import ( import (
"path/filepath"
"strings" "strings"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
...@@ -15,59 +16,7 @@ import ( ...@@ -15,59 +16,7 @@ import (
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
) )
type AuthorizeInput struct { func (p *mixPolicy) getAuthParms(req *mixTy.AuthTxReq) (*mixTy.AuthorizeCircuit, error) {
//public
TreeRootHash string `tag:"public"`
AuthorizeHash string `tag:"public"`
AuthorizeSpendHash string `tag:"public"`
//secret
ReceiverPubKey string `tag:"secret"`
ReturnPubKey string `tag:"secret"`
AuthorizePubKey string `tag:"secret"`
AuthorizePriKey string `tag:"secret"`
NoteRandom string `tag:"secret"`
Amount string `tag:"secret"`
SpendFlag string `tag:"secret"`
NoteHash string `tag:"secret"`
//tree path info
Path0 string `tag:"secret"`
Path1 string `tag:"secret"`
Path2 string `tag:"secret"`
Path3 string `tag:"secret"`
Path4 string `tag:"secret"`
Path5 string `tag:"secret"`
Path6 string `tag:"secret"`
Path7 string `tag:"secret"`
Path8 string `tag:"secret"`
Path9 string `tag:"secret"`
Helper0 string `tag:"secret"`
Helper1 string `tag:"secret"`
Helper2 string `tag:"secret"`
Helper3 string `tag:"secret"`
Helper4 string `tag:"secret"`
Helper5 string `tag:"secret"`
Helper6 string `tag:"secret"`
Helper7 string `tag:"secret"`
Helper8 string `tag:"secret"`
Helper9 string `tag:"secret"`
Valid0 string `tag:"secret"`
Valid1 string `tag:"secret"`
Valid2 string `tag:"secret"`
Valid3 string `tag:"secret"`
Valid4 string `tag:"secret"`
Valid5 string `tag:"secret"`
Valid6 string `tag:"secret"`
Valid7 string `tag:"secret"`
Valid8 string `tag:"secret"`
Valid9 string `tag:"secret"`
}
func (p *mixPolicy) getAuthParms(req *mixTy.AuthTxReq) (*AuthorizeInput, error) {
note, err := p.getNoteInfo(req.NoteHash) note, err := p.getNoteInfo(req.NoteHash)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -90,25 +39,25 @@ func (p *mixPolicy) getAuthParms(req *mixTy.AuthTxReq) (*AuthorizeInput, error) ...@@ -90,25 +39,25 @@ func (p *mixPolicy) getAuthParms(req *mixTy.AuthTxReq) (*AuthorizeInput, error)
note.Secret.AuthorizeKey, privacyKey.Privacy.PaymentKey.ReceiveKey, note.Account) note.Secret.AuthorizeKey, privacyKey.Privacy.PaymentKey.ReceiveKey, note.Account)
} }
var input AuthorizeInput var input mixTy.AuthorizeCircuit
initTreePath(&input)
input.NoteHash = note.NoteHash input.NoteHash.Assign(note.NoteHash)
input.Amount = note.Secret.Amount input.Amount.Assign(note.Secret.Amount)
input.ReceiverPubKey = note.Secret.ReceiverKey input.ReceiverPubKey.Assign(note.Secret.ReceiverKey)
input.ReturnPubKey = note.Secret.ReturnKey input.ReturnPubKey.Assign(note.Secret.ReturnKey)
input.AuthorizePubKey = note.Secret.AuthorizeKey input.AuthorizePubKey.Assign(note.Secret.AuthorizeKey)
input.NoteRandom = note.Secret.NoteRandom input.NoteRandom.Assign(note.Secret.NoteRandom)
input.AuthorizePriKey = privacyKey.Privacy.PaymentKey.SpendKey input.AuthorizePriKey.Assign(privacyKey.Privacy.PaymentKey.SpendKey)
input.AuthorizeHash = mixTy.Byte2Str(mimcHashString([]string{input.AuthorizePubKey, note.Secret.NoteRandom})) input.AuthorizeHash.Assign(mixTy.Byte2Str(mimcHashString([]string{note.Secret.AuthorizeKey, note.Secret.NoteRandom})))
input.AuthorizeSpendHash = mixTy.Byte2Str(mimcHashString([]string{req.AuthorizeToAddr, note.Secret.Amount, note.Secret.NoteRandom})) input.AuthorizeSpendHash.Assign(mixTy.Byte2Str(mimcHashString([]string{req.AuthorizeToAddr, note.Secret.Amount, note.Secret.NoteRandom})))
//default auto to receiver //default auto to receiver
input.SpendFlag = "1" if note.Secret.ReturnKey != "0" && note.Secret.ReturnKey == req.AuthorizeToAddr {
if input.ReturnPubKey != "0" && input.ReturnPubKey == req.AuthorizeToAddr {
//auth to returner //auth to returner
input.SpendFlag = "0" input.SpendFlag.Assign("0")
} else {
input.SpendFlag.Assign("1")
} }
//get tree path //get tree path
...@@ -116,9 +65,8 @@ func (p *mixPolicy) getAuthParms(req *mixTy.AuthTxReq) (*AuthorizeInput, error) ...@@ -116,9 +65,8 @@ func (p *mixPolicy) getAuthParms(req *mixTy.AuthTxReq) (*AuthorizeInput, error)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "getTreeProof for hash=%s", note.NoteHash) return nil, errors.Wrapf(err, "getTreeProof for hash=%s", note.NoteHash)
} }
input.TreeRootHash = treeProof.TreeRootHash input.TreeRootHash.Assign(treeProof.TreeRootHash)
updateTreePath(&input, treeProof) updateTreePath(&input, treeProof)
return &input, nil return &input, nil
} }
...@@ -138,12 +86,13 @@ func (p *mixPolicy) createAuthTx(req *mixTy.CreateRawTxReq) (*types.Transaction, ...@@ -138,12 +86,13 @@ func (p *mixPolicy) createAuthTx(req *mixTy.CreateRawTxReq) (*types.Transaction,
return nil, errors.Wrapf(types.ErrInvalidParam, "asset exec=%s or symbol=%s not filled", req.AssetExec, req.AssetSymbol) return nil, errors.Wrapf(types.ErrInvalidParam, "asset exec=%s or symbol=%s not filled", req.AssetExec, req.AssetSymbol)
} }
proofInfo, err := getZkProofKeys(auth.ZkPath+mixTy.AuthCircuit, auth.ZkPath+mixTy.AuthPk, *input, req.Privacy) proofInfo, err := getZkProofKeys(mixTy.VerifyType_AUTHORIZE, auth.ZkPath, mixTy.AuthPk, input, req.ZkProof)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "getZkProofKeys note=%s", auth.NoteHash) return nil, errors.Wrapf(err, "getZkProofKeys note=%s", auth.NoteHash)
} }
//verify //verify
if err := p.verifyProofOnChain(mixTy.VerifyType_AUTHORIZE, proofInfo, auth.ZkPath+mixTy.AuthVk, req.Verify); err != nil { vkFile := filepath.Join(auth.ZkPath, mixTy.AuthVk)
if err := p.verifyProofOnChain(mixTy.VerifyType_AUTHORIZE, proofInfo, vkFile, req.VerifyOnChain); err != nil {
return nil, errors.Wrapf(err, "verifyProof fail for note=%s", auth.NoteHash) return nil, errors.Wrapf(err, "verifyProof fail for note=%s", auth.NoteHash)
} }
...@@ -152,7 +101,7 @@ func (p *mixPolicy) createAuthTx(req *mixTy.CreateRawTxReq) (*types.Transaction, ...@@ -152,7 +101,7 @@ func (p *mixPolicy) createAuthTx(req *mixTy.CreateRawTxReq) (*types.Transaction,
func (p *mixPolicy) getAuthTx(execName string, exec, symbol string, proof *mixTy.ZkProofInfo) (*types.Transaction, error) { func (p *mixPolicy) getAuthTx(execName string, exec, symbol string, proof *mixTy.ZkProofInfo) (*types.Transaction, error) {
payload := &mixTy.MixAuthorizeAction{} payload := &mixTy.MixAuthorizeAction{}
payload.Proof = proof payload.ProofInfo = proof
payload.AssetExec = exec payload.AssetExec = exec
payload.AssetSymbol = symbol payload.AssetSymbol = symbol
......
...@@ -6,8 +6,8 @@ package wallet ...@@ -6,8 +6,8 @@ package wallet
import ( import (
"encoding/hex" "encoding/hex"
"path/filepath"
"strconv" "strconv"
"strings" "strings"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
...@@ -17,21 +17,9 @@ import ( ...@@ -17,21 +17,9 @@ import (
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
fr_bn256 "github.com/consensys/gurvy/bn256/fr" "github.com/consensys/gnark-crypto/ecc/bn254/fr"
) )
type DepositInput struct {
//public
NoteHash string `tag:"public"`
Amount string `tag:"public"`
//secret
ReceiverPubKey string `tag:"secret"`
ReturnPubKey string `tag:"secret"`
AuthorizePubKey string `tag:"secret"`
NoteRandom string `tag:"secret"`
}
func (p *mixPolicy) depositParams(exec, symbol, receiver, returner, auth, amount string) (*mixTy.DepositProofResp, error) { func (p *mixPolicy) depositParams(exec, symbol, receiver, returner, auth, amount string) (*mixTy.DepositProofResp, error) {
if len(receiver) > 0 && len(returner) > 0 && (receiver == returner || receiver == auth || returner == auth) { if len(receiver) > 0 && len(returner) > 0 && (receiver == returner || receiver == auth || returner == auth) {
return nil, errors.Wrapf(types.ErrInvalidParam, "addrs should not be same to receiver=%s,return=%s,auth=%s", return nil, errors.Wrapf(types.ErrInvalidParam, "addrs should not be same to receiver=%s,return=%s,auth=%s",
...@@ -58,22 +46,24 @@ func (p *mixPolicy) depositParams(exec, symbol, receiver, returner, auth, amount ...@@ -58,22 +46,24 @@ func (p *mixPolicy) depositParams(exec, symbol, receiver, returner, auth, amount
secret.AssetSymbol = symbol secret.AssetSymbol = symbol
//1. nullifier 获取随机值 //1. nullifier 获取随机值
var fr fr_bn256.Element var r fr.Element
fr.SetRandom() _, err := r.SetRandom()
secret.NoteRandom = fr.String() if err != nil {
return nil, errors.Wrapf(err, "getRandom")
}
secret.NoteRandom = r.String()
//TODO 线上检查是否随机值在nullifer里面 //TODO 线上检查是否随机值在nullifer里面
// 获取receiving addr对应的paymentKey // 获取receiving addr对应的paymentKey
payKeys, e := p.getPaymentKey(receiver) receiverKey, e := p.getPaymentKey(receiver)
if e != nil { if e != nil {
return nil, errors.Wrapf(e, "get payment key for addr = %s", receiver) return nil, errors.Wrapf(e, "get payment key for addr = %s", receiver)
} }
secret.ReceiverKey = payKeys.ReceiverKey secret.ReceiverKey = receiverKey.NoteReceiveAddr
//获取return addr对应的key //获取return addr对应的key
var returnKey *mixTy.PaymentKey var returnKey *mixTy.NoteAccountKey
var err error
//如果Input不填,缺省空为“0”字符串 //如果Input不填,缺省空为“0”字符串
secret.ReturnKey = "0" secret.ReturnKey = "0"
if len(returner) > 0 { if len(returner) > 0 {
...@@ -81,38 +71,38 @@ func (p *mixPolicy) depositParams(exec, symbol, receiver, returner, auth, amount ...@@ -81,38 +71,38 @@ func (p *mixPolicy) depositParams(exec, symbol, receiver, returner, auth, amount
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "get payment key for return addr = %s", returner) return nil, errors.Wrapf(err, "get payment key for return addr = %s", returner)
} }
secret.ReturnKey = returnKey.ReceiverKey secret.ReturnKey = returnKey.NoteReceiveAddr
} }
//获取auth addr对应的key //获取auth addr对应的key
var authKey *mixTy.PaymentKey var authKey *mixTy.NoteAccountKey
secret.AuthorizeKey = "0" secret.AuthorizeKey = "0"
if len(auth) > 0 { if len(auth) > 0 {
authKey, err = p.getPaymentKey(auth) authKey, err = p.getPaymentKey(auth)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "get payment key for authorize addr = %s", auth) return nil, errors.Wrapf(err, "get payment key for authorize addr = %s", auth)
} }
secret.AuthorizeKey = authKey.ReceiverKey secret.AuthorizeKey = authKey.NoteReceiveAddr
} }
//DH加密 //DH加密
data := types.Encode(&secret) data := types.Encode(&secret)
var group mixTy.DHSecretGroup var group mixTy.DHSecretGroup
secretData, err := encryptData(payKeys.EncryptKey, data) secretData, err := encryptData(receiverKey.SecretReceiveKey, data)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "encryptData to addr = %s", receiver) return nil, errors.Wrapf(err, "encryptData to addr = %s", receiver)
} }
group.Receiver = hex.EncodeToString(types.Encode(secretData)) group.Receiver = hex.EncodeToString(types.Encode(secretData))
if returnKey != nil { if returnKey != nil {
secretData, err = encryptData(returnKey.EncryptKey, data) secretData, err = encryptData(returnKey.SecretReceiveKey, data)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "encryptData to addr = %s", returner) return nil, errors.Wrapf(err, "encryptData to addr = %s", returner)
} }
group.Returner = hex.EncodeToString(types.Encode(secretData)) group.Returner = hex.EncodeToString(types.Encode(secretData))
} }
if authKey != nil { if authKey != nil {
secretData, err = encryptData(authKey.EncryptKey, data) secretData, err = encryptData(authKey.SecretReceiveKey, data)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "encryptData to addr = %s", auth) return nil, errors.Wrapf(err, "encryptData to addr = %s", auth)
} }
...@@ -136,34 +126,56 @@ func (p *mixPolicy) depositParams(exec, symbol, receiver, returner, auth, amount ...@@ -136,34 +126,56 @@ func (p *mixPolicy) depositParams(exec, symbol, receiver, returner, auth, amount
} }
func (p *mixPolicy) getDepositProof(exec, symbol, receiver, returner, auth, amount, zkPath string, verifyOnChain, privacyPrint int32) (*mixTy.ZkProofInfo, error) { func (p *mixPolicy) getDepositProof(exec, symbol, receiver, returner, auth, amount, zkPath string, verifyOnChain bool, proof string) (*mixTy.ZkProofInfo, error) {
resp, err := p.depositParams(exec, symbol, receiver, returner, auth, amount) resp, err := p.depositParams(exec, symbol, receiver, returner, auth, amount)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var input DepositInput var input mixTy.DepositCircuit
input.NoteHash = resp.NoteHash input.NoteHash.Assign(resp.NoteHash)
input.Amount = resp.Proof.Amount input.Amount.Assign(resp.Proof.Amount)
input.ReceiverPubKey = resp.Proof.ReceiverKey input.ReceiverPubKey.Assign(resp.Proof.ReceiverKey)
input.AuthorizePubKey = resp.Proof.AuthorizeKey input.AuthorizePubKey.Assign(resp.Proof.AuthorizeKey)
input.ReturnPubKey = resp.Proof.ReturnKey input.ReturnPubKey.Assign(resp.Proof.ReturnKey)
input.NoteRandom = resp.Proof.NoteRandom input.NoteRandom.Assign(resp.Proof.NoteRandom)
proofInfo, err := getZkProofKeys(zkPath+mixTy.DepositCircuit, zkPath+mixTy.DepositPk, input, privacyPrint) proofInfo, err := getZkProofKeys(mixTy.VerifyType_DEPOSIT, zkPath, mixTy.DepositPk, &input, proof)
if err != nil { if err != nil {
return nil, err return nil, err
} }
//线上验证proof,失败的原因有可能circuit,Pk和线上vk不匹配,或不是一起产生的版本 //线上验证proof,失败的原因有可能circuit,Pk和线上vk不匹配,或不是一起产生的版本
if err := p.verifyProofOnChain(mixTy.VerifyType_DEPOSIT, proofInfo, zkPath+mixTy.DepositVk, verifyOnChain); err != nil { vkFile := filepath.Join(zkPath, mixTy.DepositVk)
if err := p.verifyProofOnChain(mixTy.VerifyType_DEPOSIT, proofInfo, vkFile, verifyOnChain); err != nil {
return nil, errors.Wrap(err, "verifyProof fail") return nil, errors.Wrap(err, "verifyProof fail")
} }
proofInfo.Secrets = resp.Secrets proofInfo.Secrets = resp.Secrets
return proofInfo, nil return proofInfo, nil
} }
func (p *mixPolicy) getDepositTx(execName string, assetExec, assetSymbol string, proofs []*mixTy.ZkProofInfo) (*types.Transaction, error) {
payload := &mixTy.MixDepositAction{}
payload.Proofs = proofs
payload.AssetExec = assetExec
payload.AssetSymbol = assetSymbol
cfg := p.getWalletOperate().GetAPI().GetConfig()
action := &mixTy.MixAction{
Ty: mixTy.MixActionDeposit,
Value: &mixTy.MixAction_Deposit{Deposit: payload},
}
tx := &types.Transaction{
Execer: []byte(execName),
Payload: types.Encode(action),
To: address.ExecAddress(execName),
Expire: types.Now().Unix() + int64(300), //5 min
}
return types.FormatTx(cfg, execName, tx)
}
func (p *mixPolicy) createDepositTx(req *mixTy.CreateRawTxReq) (*types.Transaction, error) { func (p *mixPolicy) createDepositTx(req *mixTy.CreateRawTxReq) (*types.Transaction, error) {
var deposit mixTy.DepositTxReq var deposit mixTy.DepositTxReq
err := types.Decode(req.Data, &deposit) err := types.Decode(req.Data, &deposit)
...@@ -178,7 +190,6 @@ func (p *mixPolicy) createDepositTx(req *mixTy.CreateRawTxReq) (*types.Transacti ...@@ -178,7 +190,6 @@ func (p *mixPolicy) createDepositTx(req *mixTy.CreateRawTxReq) (*types.Transacti
if len(deposit.ZkPath) == 0 { if len(deposit.ZkPath) == 0 {
deposit.ZkPath = "./" deposit.ZkPath = "./"
} }
//多个receiver //多个receiver
receivers := strings.Split(deposit.Deposit.ReceiverAddrs, ",") receivers := strings.Split(deposit.Deposit.ReceiverAddrs, ",")
amounts := strings.Split(deposit.Deposit.Amounts, ",") amounts := strings.Split(deposit.Deposit.Amounts, ",")
...@@ -188,35 +199,12 @@ func (p *mixPolicy) createDepositTx(req *mixTy.CreateRawTxReq) (*types.Transacti ...@@ -188,35 +199,12 @@ func (p *mixPolicy) createDepositTx(req *mixTy.CreateRawTxReq) (*types.Transacti
var proofs []*mixTy.ZkProofInfo var proofs []*mixTy.ZkProofInfo
for i, rcv := range receivers { for i, rcv := range receivers {
p, err := p.getDepositProof(req.AssetExec, req.AssetSymbol, rcv, deposit.Deposit.ReturnAddr, deposit.Deposit.AuthorizeAddr, amounts[i], deposit.ZkPath, req.Verify, req.Privacy) p, err := p.getDepositProof(req.AssetExec, req.AssetSymbol, rcv, deposit.Deposit.ReturnAddr, deposit.Deposit.AuthorizeAddr, amounts[i], deposit.ZkPath, req.VerifyOnChain, req.ZkProof)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "get Deposit proof for=%s", rcv) return nil, errors.Wrapf(err, "get Deposit proof for=%s", rcv)
} }
proofs = append(proofs, p) proofs = append(proofs, p)
} }
return p.getDepositTx(strings.TrimSpace(req.Title+mixTy.MixX), req.AssetExec, req.AssetSymbol, proofs) return p.getDepositTx(strings.TrimSpace(req.Title+mixTy.MixX), req.AssetExec, req.AssetSymbol, proofs)
} }
func (p *mixPolicy) getDepositTx(execName string, assetExec, assetSymbol string, proofs []*mixTy.ZkProofInfo) (*types.Transaction, error) {
payload := &mixTy.MixDepositAction{}
payload.Proofs = proofs
payload.AssetExec = assetExec
payload.AssetSymbol = assetSymbol
cfg := p.getWalletOperate().GetAPI().GetConfig()
action := &mixTy.MixAction{
Ty: mixTy.MixActionDeposit,
Value: &mixTy.MixAction_Deposit{Deposit: payload},
}
tx := &types.Transaction{
Execer: []byte(execName),
Payload: types.Encode(action),
To: address.ExecAddress(execName),
Expire: types.Now().Unix() + int64(300), //5 min
}
return types.FormatTx(cfg, execName, tx)
}
...@@ -6,6 +6,9 @@ package wallet ...@@ -6,6 +6,9 @@ package wallet
import ( import (
"fmt" "fmt"
"github.com/consensys/gnark/frontend"
"path/filepath"
"strconv" "strconv"
"strings" "strings"
...@@ -17,82 +20,11 @@ import ( ...@@ -17,82 +20,11 @@ import (
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
fr_bn256 "github.com/consensys/gurvy/bn256/fr" "github.com/consensys/gnark-crypto/ecc/bn254/fr"
"github.com/consensys/gurvy/bn256/twistededwards" "github.com/consensys/gnark-crypto/ecc/bn254/twistededwards"
) )
type TransferInput struct { func (p *mixPolicy) getTransferInputPart(note *mixTy.WalletNoteInfo) (*mixTy.TransferInputCircuit, error) {
//public
TreeRootHash string `tag:"public"`
AuthorizeSpendHash string `tag:"public"`
NullifierHash string `tag:"public"`
ShieldAmountX string `tag:"public"`
ShieldAmountY string `tag:"public"`
//secret
ReceiverPubKey string `tag:"secret"`
ReturnPubKey string `tag:"secret"`
AuthorizePubKey string `tag:"secret"`
NoteRandom string `tag:"secret"`
Amount string `tag:"secret"`
AmountRandom string `tag:"secret"`
SpendPriKey string `tag:"secret"`
SpendFlag string `tag:"secret"`
AuthorizeFlag string `tag:"secret"`
NoteHash string `tag:"secret"`
//tree path info
Path0 string `tag:"secret"`
Path1 string `tag:"secret"`
Path2 string `tag:"secret"`
Path3 string `tag:"secret"`
Path4 string `tag:"secret"`
Path5 string `tag:"secret"`
Path6 string `tag:"secret"`
Path7 string `tag:"secret"`
Path8 string `tag:"secret"`
Path9 string `tag:"secret"`
Helper0 string `tag:"secret"`
Helper1 string `tag:"secret"`
Helper2 string `tag:"secret"`
Helper3 string `tag:"secret"`
Helper4 string `tag:"secret"`
Helper5 string `tag:"secret"`
Helper6 string `tag:"secret"`
Helper7 string `tag:"secret"`
Helper8 string `tag:"secret"`
Helper9 string `tag:"secret"`
Valid0 string `tag:"secret"`
Valid1 string `tag:"secret"`
Valid2 string `tag:"secret"`
Valid3 string `tag:"secret"`
Valid4 string `tag:"secret"`
Valid5 string `tag:"secret"`
Valid6 string `tag:"secret"`
Valid7 string `tag:"secret"`
Valid8 string `tag:"secret"`
Valid9 string `tag:"secret"`
}
type TransferOutput struct {
//public
NoteHash string `tag:"public"`
ShieldAmountX string `tag:"public"`
ShieldAmountY string `tag:"public"`
//secret
ReceiverPubKey string `tag:"secret"`
ReturnPubKey string `tag:"secret"`
AuthorizePubKey string `tag:"secret"`
NoteRandom string `tag:"secret"`
Amount string `tag:"secret"`
AmountRandom string `tag:"secret"`
}
func (p *mixPolicy) getTransferInputPart(note *mixTy.WalletNoteInfo) (*TransferInput, error) {
//get spend privacy key //get spend privacy key
privacyKey, err := p.getAccountPrivacyKey(note.Account) privacyKey, err := p.getAccountPrivacyKey(note.Account)
if err != nil { if err != nil {
...@@ -104,45 +36,43 @@ func (p *mixPolicy) getTransferInputPart(note *mixTy.WalletNoteInfo) (*TransferI ...@@ -104,45 +36,43 @@ func (p *mixPolicy) getTransferInputPart(note *mixTy.WalletNoteInfo) (*TransferI
note.Secret.ReceiverKey, privacyKey.Privacy.PaymentKey.ReceiveKey, note.Account) note.Secret.ReceiverKey, privacyKey.Privacy.PaymentKey.ReceiveKey, note.Account)
} }
var input TransferInput var input mixTy.TransferInputCircuit
initTreePath(&input) input.NoteHash.Assign(note.NoteHash)
input.NoteHash = note.NoteHash input.Amount.Assign(note.Secret.Amount)
input.ReceiverPubKey.Assign(note.Secret.ReceiverKey)
input.Amount = note.Secret.Amount input.ReturnPubKey.Assign(note.Secret.ReturnKey)
input.ReceiverPubKey = note.Secret.ReceiverKey input.AuthorizePubKey.Assign(note.Secret.AuthorizeKey)
input.ReturnPubKey = note.Secret.ReturnKey input.NoteRandom.Assign(note.Secret.NoteRandom)
input.AuthorizePubKey = note.Secret.AuthorizeKey
input.NoteRandom = note.Secret.NoteRandom
//自己是payment 还是returner已经在解析note时候算好了,authSpendHash也对应算好了,如果note valid,则就用本地即可 //自己是payment 还是returner已经在解析note时候算好了,authSpendHash也对应算好了,如果note valid,则就用本地即可
input.AuthorizeSpendHash = note.AuthorizeSpendHash input.AuthorizeSpendHash.Assign(note.AuthorizeSpendHash)
input.NullifierHash = note.Nullifier input.NullifierHash.Assign(note.Nullifier)
input.SpendPriKey = privacyKey.Privacy.PaymentKey.SpendKey input.SpendPriKey.Assign(privacyKey.Privacy.PaymentKey.SpendKey)
//default auto to receiver
input.SpendFlag = "1"
//self is returner auth to returner //self is returner auth to returner
if privacyKey.Privacy.PaymentKey.ReceiveKey == note.Secret.ReturnKey { if privacyKey.Privacy.PaymentKey.ReceiveKey == note.Secret.ReturnKey {
input.SpendFlag = "0" input.SpendFlag.Assign("0")
} else {
input.SpendFlag.Assign("1")
} }
input.AuthorizeFlag = "0" if len(note.AuthorizeSpendHash) > LENNULLKEY {
if len(input.AuthorizeSpendHash) > LENNULLKEY { input.AuthorizeFlag.Assign("1")
input.AuthorizeFlag = "1" } else {
input.AuthorizeFlag.Assign("0")
} }
treeProof, err := p.getTreeProof(note.Secret.AssetExec, note.Secret.AssetSymbol, note.NoteHash) treeProof, err := p.getTreeProof(note.Secret.AssetExec, note.Secret.AssetSymbol, note.NoteHash)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "getTreeProof for hash=%s", note.NoteHash) return nil, errors.Wrapf(err, "getTreeProof for hash=%s", note.NoteHash)
} }
input.TreeRootHash = treeProof.TreeRootHash input.TreeRootHash.Assign(treeProof.TreeRootHash)
updateTreePath(&input, treeProof) updateTreePath(&input, treeProof)
return &input, nil return &input, nil
} }
func (p *mixPolicy) getTransferOutput(exec, symbol string, req *mixTy.DepositInfo) (*TransferOutput, *mixTy.DHSecretGroup, error) { func (p *mixPolicy) getTransferOutput(exec, symbol string, req *mixTy.DepositInfo) (*mixTy.TransferOutputCircuit, *mixTy.DHSecretGroup, error) {
//目前只支持一个ReceiverAddr //目前只支持一个ReceiverAddr
if strings.Contains(req.ReceiverAddrs, ",") || strings.Contains(req.Amounts, ",") { if strings.Contains(req.ReceiverAddrs, ",") || strings.Contains(req.Amounts, ",") {
return nil, nil, errors.Wrapf(types.ErrInvalidParam, "only support one addr or amount,addrs=%s,amount=%s", return nil, nil, errors.Wrapf(types.ErrInvalidParam, "only support one addr or amount,addrs=%s,amount=%s",
...@@ -153,13 +83,13 @@ func (p *mixPolicy) getTransferOutput(exec, symbol string, req *mixTy.DepositInf ...@@ -153,13 +83,13 @@ func (p *mixPolicy) getTransferOutput(exec, symbol string, req *mixTy.DepositInf
return nil, nil, errors.Wrapf(err, "deposit toAddr=%s", req.ReceiverAddrs) return nil, nil, errors.Wrapf(err, "deposit toAddr=%s", req.ReceiverAddrs)
} }
var input TransferOutput var input mixTy.TransferOutputCircuit
input.NoteHash = resp.NoteHash input.NoteHash.Assign(resp.NoteHash)
input.Amount = resp.Proof.Amount input.Amount.Assign(resp.Proof.Amount)
input.ReceiverPubKey = resp.Proof.ReceiverKey input.ReceiverPubKey.Assign(resp.Proof.ReceiverKey)
input.AuthorizePubKey = resp.Proof.AuthorizeKey input.AuthorizePubKey.Assign(resp.Proof.AuthorizeKey)
input.ReturnPubKey = resp.Proof.ReturnKey input.ReturnPubKey.Assign(resp.Proof.ReturnKey)
input.NoteRandom = resp.Proof.NoteRandom input.NoteRandom.Assign(resp.Proof.NoteRandom)
return &input, resp.Secrets, nil return &input, resp.Secrets, nil
...@@ -177,7 +107,7 @@ func getShieldValue(cfg *types.Chain33Config, inputAmounts []uint64, outAmount, ...@@ -177,7 +107,7 @@ func getShieldValue(cfg *types.Chain33Config, inputAmounts []uint64, outAmount,
} }
//get amount*G point //get amount*G point
//note = transfer + change + minTxFee //note = transfer + change + minTxFee
var inputGPoints []*twistededwards.Point var inputGPoints []*twistededwards.PointAffine
for _, i := range inputAmounts { for _, i := range inputAmounts {
inputGPoints = append(inputGPoints, mixTy.MulCurvePointG(i)) inputGPoints = append(inputGPoints, mixTy.MulCurvePointG(i))
} }
...@@ -193,31 +123,40 @@ func getShieldValue(cfg *types.Chain33Config, inputAmounts []uint64, outAmount, ...@@ -193,31 +123,40 @@ func getShieldValue(cfg *types.Chain33Config, inputAmounts []uint64, outAmount,
//三个混淆随机值可以随机获取,这里noteRandom和为了Nullifier计算的NoteRandom不同。 //三个混淆随机值可以随机获取,这里noteRandom和为了Nullifier计算的NoteRandom不同。
//获取随机值,截取一半给change和transfer,和值给Note,直接用完整的random值会溢出 //获取随机值,截取一半给change和transfer,和值给Note,直接用完整的random值会溢出
var rChange, rOut, v fr_bn256.Element var rChange, rOut, v fr.Element
random := v.SetRandom().String() _, err := v.SetRandom()
if err != nil {
return nil, errors.Wrapf(err, "getRandom")
}
random := v.String()
rChange.SetString(random[0 : len(random)/2]) rChange.SetString(random[0 : len(random)/2])
rOut.SetString(random[len(random)/2:]) rOut.SetString(random[len(random)/2:])
fmt.Println("rOut", rOut.String()) fmt.Println("rOut", rOut.String())
fmt.Println("rChange", rChange.String()) fmt.Println("rChange", rChange.String())
var rSumIn, rSumOut fr_bn256.Element var rSumIn, rSumOut fr.Element
rSumIn.SetZero() rSumIn.SetZero()
rSumOut.Add(&rChange, &rOut) rSumOut.Add(&rChange, &rOut)
var rInputs []fr_bn256.Element var rInputs []fr.Element
rInputs = append(rInputs, rSumOut) rInputs = append(rInputs, rSumOut)
//len(inputAmounts)>1场景,每个input的随机值设为随机值的1/3长度,这样加起来不会超过rOut+rChange //len(inputAmounts)>1场景,每个input的随机值设为随机值的1/3长度,这样加起来不会超过rOut+rChange
for i := 1; i < len(inputAmounts); i++ { for i := 1; i < len(inputAmounts); i++ {
var a, v fr_bn256.Element var a, v fr.Element
rv := v.SetRandom().String() _, err := v.SetRandom()
if err != nil {
return nil, errors.Wrapf(err, "getRandom")
}
rv := v.String()
a.SetString(rv[0 : len(random)/3]) a.SetString(rv[0 : len(random)/3])
rInputs = append(rInputs, a) rInputs = append(rInputs, a)
rSumIn.Add(&rSumIn, &a) rSumIn.Add(&rSumIn, &a)
} }
//如果len(inputAmounts)>1,则把rInputs[0]替换为rrSumOut-rSumIn,rSumIn都是1/3的随机值长度,减法应该不会溢出 //如果len(inputAmounts)>1,则把rInputs[0]替换为rrSumOut-rSumIn,rSumIn都是1/3的随机值长度,减法应该不会溢出
if len(rInputs) > 1 { if len(rInputs) > 1 {
var sub fr_bn256.Element var sub fr.Element
sub.Sub(&rSumOut, &rSumIn) sub.Sub(&rSumOut, &rSumIn)
rInputs[0] = sub rInputs[0] = sub
} }
...@@ -231,7 +170,7 @@ func getShieldValue(cfg *types.Chain33Config, inputAmounts []uint64, outAmount, ...@@ -231,7 +170,7 @@ func getShieldValue(cfg *types.Chain33Config, inputAmounts []uint64, outAmount,
pointHX := conf.GStr("pointHX") pointHX := conf.GStr("pointHX")
pointHY := conf.GStr("pointHY") pointHY := conf.GStr("pointHY")
var inputHPoints []*twistededwards.Point var inputHPoints []*twistededwards.PointAffine
for _, i := range rInputs { for _, i := range rInputs {
inputHPoints = append(inputHPoints, mixTy.MulCurvePointH(pointHX, pointHY, i.String())) inputHPoints = append(inputHPoints, mixTy.MulCurvePointH(pointHX, pointHY, i.String()))
} }
...@@ -301,7 +240,7 @@ func (p *mixPolicy) createTransferTx(req *mixTy.CreateRawTxReq) (*types.Transact ...@@ -301,7 +240,7 @@ func (p *mixPolicy) createTransferTx(req *mixTy.CreateRawTxReq) (*types.Transact
} }
//1.获取Input //1.获取Input
var inputParts []*TransferInput var inputParts []*mixTy.TransferInputCircuit
for _, n := range notes { for _, n := range notes {
input, err := p.getTransferInputPart(n) input, err := p.getTransferInputPart(n)
if err != nil { if err != nil {
...@@ -314,12 +253,9 @@ func (p *mixPolicy) createTransferTx(req *mixTy.CreateRawTxReq) (*types.Transact ...@@ -314,12 +253,9 @@ func (p *mixPolicy) createTransferTx(req *mixTy.CreateRawTxReq) (*types.Transact
var inputAmounts []uint64 var inputAmounts []uint64
var sumInput uint64 var sumInput uint64
for _, i := range inputParts { for _, i := range inputParts {
amount, err := strconv.ParseUint(i.Amount, 10, 64) amount := frontend.FromInterface(frontend.GetAssignedValue(i.Amount))
if err != nil { inputAmounts = append(inputAmounts, amount.Uint64())
return nil, errors.Wrapf(err, "input part parseUint=%s", i.Amount) sumInput += amount.Uint64()
}
inputAmounts = append(inputAmounts, amount)
sumInput += amount
} }
//2. 获取output //2. 获取output
...@@ -368,48 +304,59 @@ func (p *mixPolicy) createTransferTx(req *mixTy.CreateRawTxReq) (*types.Transact ...@@ -368,48 +304,59 @@ func (p *mixPolicy) createTransferTx(req *mixTy.CreateRawTxReq) (*types.Transact
//noteCommitX, transferX, changeX //noteCommitX, transferX, changeX
for i, input := range inputParts { for i, input := range inputParts {
input.ShieldAmountX = shieldValue.Inputs[i].X input.ShieldAmountX.Assign(shieldValue.Inputs[i].X)
input.ShieldAmountY = shieldValue.Inputs[i].Y input.ShieldAmountY.Assign(shieldValue.Inputs[i].Y)
input.AmountRandom = shieldValue.InputRandoms[i] input.AmountRandom.Assign(shieldValue.InputRandoms[i])
} }
outPart.ShieldAmountX = shieldValue.Output.X outPart.ShieldAmountX.Assign(shieldValue.Output.X)
outPart.ShieldAmountY = shieldValue.Output.Y outPart.ShieldAmountY.Assign(shieldValue.Output.Y)
outPart.AmountRandom = shieldValue.OutputRandom outPart.AmountRandom.Assign(shieldValue.OutputRandom)
changePart.ShieldAmountX.Assign(shieldValue.Change.X)
changePart.ShieldAmountY.Assign(shieldValue.Change.Y)
changePart.AmountRandom.Assign(shieldValue.ChangeRandom)
changePart.ShieldAmountX = shieldValue.Change.X //输入的proof,CI测试目的,正常情况下为空,需输入pk路径
changePart.ShieldAmountY = shieldValue.Change.Y proofs := make([]string, len(inputParts)+2)
changePart.AmountRandom = shieldValue.ChangeRandom if len(req.ZkProof) > 0 {
proofs = strings.Split(req.ZkProof, "-")
if len(proofs) != len(inputParts)+2 {
return nil, errors.Wrapf(types.ErrInvalidParam, "wrong proof num=%d, inputs=%d", len(proofs), len(inputParts)+2)
}
}
//verify input //verify input
var inputProofs []*mixTy.ZkProofInfo var inputProofs []*mixTy.ZkProofInfo
vkFile := filepath.Join(transfer.ZkPath, mixTy.TransInputVk)
for i, input := range inputParts { for i, input := range inputParts {
inputProof, err := getZkProofKeys(transfer.Input.ZkPath+mixTy.TransInputCircuit, transfer.Input.ZkPath+mixTy.TransInputPk, *input, req.Privacy) inputProof, err := getZkProofKeys(mixTy.VerifyType_TRANSFERINPUT, transfer.ZkPath, mixTy.TransInputPk, input, proofs[i])
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "verify.input getZkProofKeys,the i=%d", i) return nil, errors.Wrapf(err, "verify.input getZkProofKeys,the i=%d", i)
} }
if err := p.verifyProofOnChain(mixTy.VerifyType_TRANSFERINPUT, inputProof, transfer.Input.ZkPath+mixTy.TransInputVk, req.Verify); err != nil { if err := p.verifyProofOnChain(mixTy.VerifyType_TRANSFERINPUT, inputProof, vkFile, req.VerifyOnChain); err != nil {
return nil, errors.Wrapf(err, "input verifyProof fail,the i=%d", i) return nil, errors.Wrapf(err, "input verifyProof fail,the i=%d", i)
} }
inputProofs = append(inputProofs, inputProof) inputProofs = append(inputProofs, inputProof)
} }
//verify output //verify output
outputProof, err := getZkProofKeys(transfer.Output.ZkPath+mixTy.TransOutputCircuit, transfer.Output.ZkPath+mixTy.TransOutputPk, *outPart, req.Privacy) vkOutFile := filepath.Join(transfer.ZkPath, mixTy.TransOutputVk)
outputProof, err := getZkProofKeys(mixTy.VerifyType_TRANSFEROUTPUT, transfer.ZkPath, mixTy.TransOutputPk, outPart, proofs[len(inputParts)])
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "output getZkProofKeys") return nil, errors.Wrapf(err, "output getZkProofKeys")
} }
if err := p.verifyProofOnChain(mixTy.VerifyType_TRANSFEROUTPUT, outputProof, transfer.Output.ZkPath+mixTy.TransOutputVk, req.Verify); err != nil { if err := p.verifyProofOnChain(mixTy.VerifyType_TRANSFEROUTPUT, outputProof, vkOutFile, req.VerifyOnChain); err != nil {
return nil, errors.Wrapf(err, "output verifyProof fail") return nil, errors.Wrapf(err, "output verifyProof fail")
} }
outputProof.Secrets = outDHSecret outputProof.Secrets = outDHSecret
//verify change //verify change
changeProof, err := getZkProofKeys(transfer.Output.ZkPath+mixTy.TransOutputCircuit, transfer.Output.ZkPath+mixTy.TransOutputPk, *changePart, req.Privacy) changeProof, err := getZkProofKeys(mixTy.VerifyType_TRANSFEROUTPUT, transfer.ZkPath, mixTy.TransOutputPk, changePart, proofs[len(inputParts)+1])
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "change getZkProofKeys") return nil, errors.Wrapf(err, "change getZkProofKeys")
} }
if err := p.verifyProofOnChain(mixTy.VerifyType_TRANSFEROUTPUT, changeProof, transfer.Output.ZkPath+mixTy.TransOutputVk, req.Verify); err != nil { if err := p.verifyProofOnChain(mixTy.VerifyType_TRANSFEROUTPUT, changeProof, vkOutFile, req.VerifyOnChain); err != nil {
return nil, errors.Wrapf(err, "change verifyProof fail") return nil, errors.Wrapf(err, "change verifyProof fail")
} }
changeProof.Secrets = changeDHSecret changeProof.Secrets = changeDHSecret
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
package wallet package wallet
import ( import (
"strconv" "github.com/consensys/gnark/frontend"
"path/filepath"
"strings" "strings"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
...@@ -15,59 +16,7 @@ import ( ...@@ -15,59 +16,7 @@ import (
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
) )
type WithdrawInput struct { func (p *mixPolicy) getWithdrawParams(exec, symbol, noteHash string) (*mixTy.WithdrawCircuit, error) {
//public
TreeRootHash string `tag:"public"`
AuthorizeSpendHash string `tag:"public"`
NullifierHash string `tag:"public"`
Amount string `tag:"public"`
//secret
ReceiverPubKey string `tag:"secret"`
ReturnPubKey string `tag:"secret"`
AuthorizePubKey string `tag:"secret"`
NoteRandom string `tag:"secret"`
SpendPriKey string `tag:"secret"`
SpendFlag string `tag:"secret"`
AuthorizeFlag string `tag:"secret"`
//tree path info
NoteHash string `tag:"secret"`
Path0 string `tag:"secret"`
Path1 string `tag:"secret"`
Path2 string `tag:"secret"`
Path3 string `tag:"secret"`
Path4 string `tag:"secret"`
Path5 string `tag:"secret"`
Path6 string `tag:"secret"`
Path7 string `tag:"secret"`
Path8 string `tag:"secret"`
Path9 string `tag:"secret"`
Helper0 string `tag:"secret"`
Helper1 string `tag:"secret"`
Helper2 string `tag:"secret"`
Helper3 string `tag:"secret"`
Helper4 string `tag:"secret"`
Helper5 string `tag:"secret"`
Helper6 string `tag:"secret"`
Helper7 string `tag:"secret"`
Helper8 string `tag:"secret"`
Helper9 string `tag:"secret"`
Valid0 string `tag:"secret"`
Valid1 string `tag:"secret"`
Valid2 string `tag:"secret"`
Valid3 string `tag:"secret"`
Valid4 string `tag:"secret"`
Valid5 string `tag:"secret"`
Valid6 string `tag:"secret"`
Valid7 string `tag:"secret"`
Valid8 string `tag:"secret"`
Valid9 string `tag:"secret"`
}
func (p *mixPolicy) getWithdrawParams(exec, symbol, noteHash string) (*WithdrawInput, error) {
note, err := p.getNoteInfo(noteHash) note, err := p.getNoteInfo(noteHash)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -81,21 +30,21 @@ func (p *mixPolicy) getWithdrawParams(exec, symbol, noteHash string) (*WithdrawI ...@@ -81,21 +30,21 @@ func (p *mixPolicy) getWithdrawParams(exec, symbol, noteHash string) (*WithdrawI
note.Secret.AssetExec, note.Secret.AssetSymbol, exec, symbol) note.Secret.AssetExec, note.Secret.AssetSymbol, exec, symbol)
} }
var input WithdrawInput var input mixTy.WithdrawCircuit
initTreePath(&input) input.NullifierHash.Assign(note.Nullifier)
input.NullifierHash = note.Nullifier input.NoteHash.Assign(note.NoteHash)
input.NoteHash = note.NoteHash input.AuthorizeSpendHash.Assign(note.AuthorizeSpendHash)
input.AuthorizeSpendHash = note.AuthorizeSpendHash
input.Amount.Assign(note.Secret.Amount)
input.Amount = note.Secret.Amount input.ReceiverPubKey.Assign(note.Secret.ReceiverKey)
input.ReceiverPubKey = note.Secret.ReceiverKey input.ReturnPubKey.Assign(note.Secret.ReturnKey)
input.ReturnPubKey = note.Secret.ReturnKey input.AuthorizePubKey.Assign(note.Secret.AuthorizeKey)
input.AuthorizePubKey = note.Secret.AuthorizeKey input.NoteRandom.Assign(note.Secret.NoteRandom)
input.NoteRandom = note.Secret.NoteRandom
if len(note.AuthorizeSpendHash) > LENNULLKEY {
input.AuthorizeFlag = "0" input.AuthorizeFlag.Assign("1")
if len(input.AuthorizeSpendHash) > LENNULLKEY { } else {
input.AuthorizeFlag = "1" input.AuthorizeFlag.Assign("0")
} }
//get spend privacy key //get spend privacy key
...@@ -103,10 +52,11 @@ func (p *mixPolicy) getWithdrawParams(exec, symbol, noteHash string) (*WithdrawI ...@@ -103,10 +52,11 @@ func (p *mixPolicy) getWithdrawParams(exec, symbol, noteHash string) (*WithdrawI
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "getAccountPrivacyKey addr=%s", note.Account) return nil, errors.Wrapf(err, "getAccountPrivacyKey addr=%s", note.Account)
} }
input.SpendPriKey = privacyKey.Privacy.PaymentKey.SpendKey input.SpendPriKey.Assign(privacyKey.Privacy.PaymentKey.SpendKey)
input.SpendFlag = "1" if privacyKey.Privacy.PaymentKey.ReceiveKey == note.Secret.ReturnKey {
if privacyKey.Privacy.PaymentKey.ReceiveKey == input.ReturnPubKey { input.SpendFlag.Assign("0")
input.SpendFlag = "0" } else {
input.SpendFlag.Assign("1")
} }
//get tree path //get tree path
...@@ -114,7 +64,7 @@ func (p *mixPolicy) getWithdrawParams(exec, symbol, noteHash string) (*WithdrawI ...@@ -114,7 +64,7 @@ func (p *mixPolicy) getWithdrawParams(exec, symbol, noteHash string) (*WithdrawI
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "getTreeProof for hash=%s", note.NoteHash) return nil, errors.Wrapf(err, "getTreeProof for hash=%s", note.NoteHash)
} }
input.TreeRootHash = treeProof.TreeRootHash input.TreeRootHash.Assign(treeProof.TreeRootHash)
updateTreePath(&input, treeProof) updateTreePath(&input, treeProof)
return &input, nil return &input, nil
...@@ -148,21 +98,18 @@ func (p *mixPolicy) createWithdrawTx(req *mixTy.CreateRawTxReq) (*types.Transact ...@@ -148,21 +98,18 @@ func (p *mixPolicy) createWithdrawTx(req *mixTy.CreateRawTxReq) (*types.Transact
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "getWithdrawParams note=%s", note) return nil, errors.Wrapf(err, "getWithdrawParams note=%s", note)
} }
proofInfo, err := getZkProofKeys(mixTy.VerifyType_WITHDRAW, withdraw.ZkPath, mixTy.WithdrawPk, input, req.ZkProof)
proofInfo, err := getZkProofKeys(withdraw.ZkPath+mixTy.WithdrawCircuit, withdraw.ZkPath+mixTy.WithdrawPk, *input, req.Privacy)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "getZkProofKeys note=%s", note) return nil, errors.Wrapf(err, "getZkProofKeys note=%s", note)
} }
//verify //verify
if err := p.verifyProofOnChain(mixTy.VerifyType_WITHDRAW, proofInfo, withdraw.ZkPath+mixTy.WithdrawVk, req.Verify); err != nil { vkFile := filepath.Join(withdraw.ZkPath, mixTy.WithdrawVk)
if err := p.verifyProofOnChain(mixTy.VerifyType_WITHDRAW, proofInfo, vkFile, req.VerifyOnChain); err != nil {
return nil, errors.Wrapf(err, "verifyProof fail for note=%s", note) return nil, errors.Wrapf(err, "verifyProof fail for note=%s", note)
} }
v, err := strconv.Atoi(input.Amount) v := frontend.FromInterface(frontend.GetAssignedValue(input.Amount))
if err != nil { sum += v.Uint64()
return nil, errors.Wrapf(err, "atoi fail for note=%s,amount=%s", note, input.Amount)
}
sum += uint64(v)
proofs = append(proofs, proofInfo) proofs = append(proofs, proofInfo)
} }
......
...@@ -7,15 +7,16 @@ package wallet ...@@ -7,15 +7,16 @@ package wallet
import ( import (
"bytes" "bytes"
"encoding/hex" "encoding/hex"
"encoding/json" "github.com/consensys/gnark-crypto/ecc"
"fmt" "github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/backend/witness"
"os"
"path/filepath"
"reflect" "reflect"
"strconv" "strconv"
backend_bn256 "github.com/consensys/gnark/backend/bn256"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gnark/frontend" "github.com/consensys/gnark/frontend"
"github.com/consensys/gurvy"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/33cn/chain33/common" "github.com/33cn/chain33/common"
...@@ -24,42 +25,10 @@ import ( ...@@ -24,42 +25,10 @@ import (
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gnark/backend" "github.com/consensys/gnark/backend"
groth16_bn256 "github.com/consensys/gnark/backend/bn256/groth16"
"github.com/33cn/plugin/plugin/dapp/mix/executor/zksnark" "github.com/33cn/plugin/plugin/dapp/mix/executor/zksnark"
) )
//对secretData 编码为string,同时增加随机值
//func encodeSecretData(secret *mixTy.SecretData) (*mixTy.EncodedSecretData, error) {
// if secret == nil {
// return nil, errors.Wrap(types.ErrInvalidParam, "para is nil")
// }
// if len(secret.ReceiverKey) <= 0 {
// return nil, errors.Wrap(types.ErrInvalidParam, "spendPubKey is nil")
// }
// var val big.Int
// ret, succ := val.SetString(secret.Amount, 10)
// if !succ {
// return nil, errors.Wrapf(types.ErrInvalidParam, "wrong amount = %s", secret.Amount)
// }
// if ret.Sign() <= 0 {
// return nil, errors.Wrapf(types.ErrInvalidParam, "amount = %s, need bigger than 0", secret.Amount)
// }
//
// //获取随机值
// var fr fr_bn256.Element
// fr.SetRandom()
// secret.NoteRandom = fr.String()
// code := types.Encode(secret)
// var resp mixTy.EncodedSecretData
//
// resp.Encoded = common.ToHex(code)
// resp.RawData = secret
//
// return &resp, nil
//
//}
//产生随机秘钥和receivingPk对data DH加密,返回随机秘钥的公钥 //产生随机秘钥和receivingPk对data DH加密,返回随机秘钥的公钥
func encryptSecretData(req *mixTy.EncryptSecretData) (*mixTy.DHSecret, error) { func encryptSecretData(req *mixTy.EncryptSecretData) (*mixTy.DHSecret, error) {
secret, err := common.FromHex(req.Secret) secret, err := common.FromHex(req.Secret)
...@@ -87,17 +56,14 @@ func decryptSecretData(req *mixTy.DecryptSecretData) (*mixTy.SecretData, error) ...@@ -87,17 +56,14 @@ func decryptSecretData(req *mixTy.DecryptSecretData) (*mixTy.SecretData, error)
return &raw, nil return &raw, nil
} }
func (p *mixPolicy) verifyProofOnChain(ty mixTy.VerifyType, proof *mixTy.ZkProofInfo, vkPath string, verifyOnChain int32) error { func (p *mixPolicy) verifyProofOnChain(ty mixTy.VerifyType, proof *mixTy.ZkProofInfo, vkPath string, verifyOnChain bool) error {
//vkpath verify //vkpath verify
if verifyOnChain > 0 && len(vkPath) > 0 { if !verifyOnChain && len(vkPath) > 0 {
vk, err := getVerifyKey(vkPath) verifyKey, err := readZkKeyFile(vkPath)
if err != nil { if err != nil {
return errors.Wrapf(err, "getVerifyKey path=%s", vkPath) return errors.Wrapf(err, "getVerifyKey path=%s", vkPath)
} }
verifyKey, err := serializeObj(vk)
if err != nil {
return errors.Wrapf(err, "serial vk path=%s", vkPath)
}
pass, err := zksnark.Verify(verifyKey, proof.Proof, proof.PublicInput) pass, err := zksnark.Verify(verifyKey, proof.Proof, proof.PublicInput)
if err != nil || !pass { if err != nil || !pass {
return errors.Wrapf(err, "zk verify fail") return errors.Wrapf(err, "zk verify fail")
...@@ -115,7 +81,7 @@ func (p *mixPolicy) verifyProofOnChain(ty mixTy.VerifyType, proof *mixTy.ZkProof ...@@ -115,7 +81,7 @@ func (p *mixPolicy) verifyProofOnChain(ty mixTy.VerifyType, proof *mixTy.ZkProof
return err return err
} }
func (p *mixPolicy) getPaymentKey(addr string) (*mixTy.PaymentKey, error) { func (p *mixPolicy) getPaymentKey(addr string) (*mixTy.NoteAccountKey, error) {
msg, err := p.walletOperate.GetAPI().QueryChain(&types.ChainExecutor{ msg, err := p.walletOperate.GetAPI().QueryChain(&types.ChainExecutor{
Driver: "mix", Driver: "mix",
FuncName: "PaymentPubKey", FuncName: "PaymentPubKey",
...@@ -124,7 +90,7 @@ func (p *mixPolicy) getPaymentKey(addr string) (*mixTy.PaymentKey, error) { ...@@ -124,7 +90,7 @@ func (p *mixPolicy) getPaymentKey(addr string) (*mixTy.PaymentKey, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return msg.(*mixTy.PaymentKey), err return msg.(*mixTy.NoteAccountKey), err
} }
func (p *mixPolicy) getPathProof(exec, symbol, leaf string) (*mixTy.CommitTreeProve, error) { func (p *mixPolicy) getPathProof(exec, symbol, leaf string) (*mixTy.CommitTreeProve, error) {
...@@ -173,176 +139,138 @@ func (p *mixPolicy) getTreeProof(exec, symbol, leaf string) (*mixTy.TreePathProo ...@@ -173,176 +139,138 @@ func (p *mixPolicy) getTreeProof(exec, symbol, leaf string) (*mixTy.TreePathProo
return &proof, nil return &proof, nil
} }
//文件信息过大,pk文件超过1M,作为参数传递不合适,这里传路径信息 func getCircuit(circuitTy mixTy.VerifyType) (frontend.CompiledConstraintSystem, error) {
func getCircuit(path string) (*backend_bn256.R1CS, error) { switch circuitTy {
var bigIntR1cs frontend.R1CS case mixTy.VerifyType_DEPOSIT:
if err := gob.Read(path, &bigIntR1cs, gurvy.BN256); err != nil { return frontend.Compile(ecc.BN254, backend.GROTH16, &mixTy.DepositCircuit{})
return nil, errors.Wrapf(err, "getCircuit path=%s", path) case mixTy.VerifyType_WITHDRAW:
return frontend.Compile(ecc.BN254, backend.GROTH16, &mixTy.WithdrawCircuit{})
case mixTy.VerifyType_TRANSFERINPUT:
return frontend.Compile(ecc.BN254, backend.GROTH16, &mixTy.TransferInputCircuit{})
case mixTy.VerifyType_TRANSFEROUTPUT:
return frontend.Compile(ecc.BN254, backend.GROTH16, &mixTy.TransferOutputCircuit{})
case mixTy.VerifyType_AUTHORIZE:
return frontend.Compile(ecc.BN254, backend.GROTH16, &mixTy.AuthorizeCircuit{})
default:
return nil, errors.Wrapf(types.ErrInvalidParam, "ty=%d", circuitTy)
} }
r1cs := backend_bn256.Cast(&bigIntR1cs)
return &r1cs, nil
} }
func getProveKey(path string) (*groth16_bn256.ProvingKey, error) { func getCircuitKeyFileName(circuitTy mixTy.VerifyType) (string, string, error) {
var pk groth16_bn256.ProvingKey switch circuitTy {
if err := gob.Read(path, &pk, gurvy.BN256); err != nil { case mixTy.VerifyType_DEPOSIT:
return nil, errors.Wrapf(err, "getProveKey path=%s", path) return mixTy.DepositPk, mixTy.DepositVk, nil
case mixTy.VerifyType_WITHDRAW:
return mixTy.WithdrawPk, mixTy.WithdrawVk, nil
case mixTy.VerifyType_TRANSFERINPUT:
return mixTy.TransInputPk, mixTy.TransInputVk, nil
case mixTy.VerifyType_TRANSFEROUTPUT:
return mixTy.TransOutputPk, mixTy.TransOutputVk, nil
case mixTy.VerifyType_AUTHORIZE:
return mixTy.AuthPk, mixTy.AuthVk, nil
default:
return "", "", errors.Wrapf(types.ErrInvalidParam, "ty=%d", circuitTy)
} }
return &pk, nil
} }
func getVerifyKey(path string) (*groth16_bn256.VerifyingKey, error) { func readZkKeyFile(path string) (string, error) {
var vk groth16_bn256.VerifyingKey f, err := os.Open(path)
if err := gob.Read(path, &vk, gurvy.BN256); err != nil {
return nil, errors.Wrapf(err, "zk.verify.Deserize.VK=%s", path)
}
return &vk, nil
}
func createProof(circuit *backend_bn256.R1CS, pk *groth16_bn256.ProvingKey, inputs backend.Assignments) (*groth16_bn256.Proof, error) {
return groth16_bn256.Prove(circuit, pk, inputs)
}
func verifyProof(proof *groth16_bn256.Proof, vk *groth16_bn256.VerifyingKey, input backend.Assignments) bool {
ok, err := groth16_bn256.Verify(proof, vk, input)
if err != nil { if err != nil {
fmt.Println("err", err) return "", errors.Wrapf(err, "open file=%s", path)
return false
}
return ok
}
func getAssignments(obj interface{}) (backend.Assignments, error) {
ty := reflect.TypeOf(obj)
tv := reflect.ValueOf(obj)
n := ty.NumField()
assigns := backend.NewAssignment()
for i := 0; i < n; i++ {
name := ty.Field(i).Name
v, ok := ty.Field(i).Tag.Lookup("tag")
if !ok {
return nil, errors.Wrapf(types.ErrNotFound, "fieldname=%s not set tag", ty.Field(i).Name)
}
if v != string(backend.Secret) && v != string(backend.Public) {
return nil, errors.Wrapf(types.ErrInvalidParam, "tag=%s not correct", v)
}
assigns.Assign(backend.Visibility(v), name, tv.FieldByName(name).Interface())
} }
return assigns, nil
}
func serializeObj(from interface{}) (string, error) {
var buf bytes.Buffer var buf bytes.Buffer
_, err = buf.ReadFrom(f)
err := gob.Serialize(&buf, from, gurvy.BN256)
if err != nil { if err != nil {
return "", err return "", errors.Wrapf(err, "read file=%s", path)
} }
return hex.EncodeToString(buf.Bytes()), nil
return buf.String(), nil
} }
func serialInputs(assignments backend.Assignments) (string, error) { func createProof(circuit frontend.CompiledConstraintSystem, pk groth16.ProvingKey, witness frontend.Circuit) (groth16.Proof, error) {
rst := make(map[string]interface{}) return groth16.Prove(circuit, pk, witness)
publics := assignments.DiscardSecrets()
for k, v := range publics {
rst[k] = v.Value.String()
}
out, err := json.Marshal(rst)
if err != nil {
return "", err
}
return hex.EncodeToString(out), nil
} }
func initTreePath(obj interface{}) {
tv := reflect.ValueOf(obj)
for i := 0; i < mixTy.TreeLevel; i++ {
tv.Elem().FieldByName(fmt.Sprintf("Path%d", i)).SetString("0")
tv.Elem().FieldByName(fmt.Sprintf("Helper%d", i)).SetString("0")
tv.Elem().FieldByName(fmt.Sprintf("Valid%d", i)).SetString("0")
}
}
func updateTreePath(obj interface{}, treeProof *mixTy.TreePathProof) { func updateTreePath(obj interface{}, treeProof *mixTy.TreePathProof) {
tv := reflect.ValueOf(obj) tv := reflect.ValueOf(obj)
if tv.Kind() == reflect.Ptr {
tv = tv.Elem()
}
index := 0
for i, t := range treeProof.TreePath { for i, t := range treeProof.TreePath {
tv.Elem().FieldByName("Path" + strconv.Itoa(i)).SetString(t) tv.FieldByName("Path" + strconv.Itoa(i)).Addr().Interface().(*frontend.Variable).Assign(t)
tv.Elem().FieldByName("Helper" + strconv.Itoa(i)).SetString(strconv.Itoa(int(treeProof.Helpers[i]))) tv.FieldByName("Helper" + strconv.Itoa(i)).Addr().Interface().(*frontend.Variable).Assign(strconv.Itoa(int(treeProof.Helpers[i])))
tv.Elem().FieldByName("Valid" + strconv.Itoa(i)).SetString("1") tv.FieldByName("Valid" + strconv.Itoa(i)).Addr().Interface().(*frontend.Variable).Assign("1")
index = i + 1
} }
}
func printObj(obj interface{}) { //电路变量必须设置
ty := reflect.TypeOf(obj) for i := index; i < mixTy.TreeLevel; i++ {
tv := reflect.ValueOf(obj) tv.FieldByName("Path" + strconv.Itoa(i)).Addr().Interface().(*frontend.Variable).Assign("0")
n := ty.NumField() tv.FieldByName("Helper" + strconv.Itoa(i)).Addr().Interface().(*frontend.Variable).Assign("0")
tv.FieldByName("Valid" + strconv.Itoa(i)).Addr().Interface().(*frontend.Variable).Assign("0")
for i := 0; i < n; i++ {
name := ty.Field(i).Name
v, ok := ty.Field(i).Tag.Lookup("tag")
if !ok {
fmt.Println("fieldname=", ty.Field(i).Name, "not set tag")
}
fmt.Println("fieldname=", ty.Field(i).Name, "| value=", tv.FieldByName(name).Interface(), "| tag=", v)
} }
} }
func getZkProofKeys(circuitFile, pkFile string, inputs interface{}, privacyPrint int32) (*mixTy.ZkProofInfo, error) { func getZkProofKeys(circuitTy mixTy.VerifyType, path, file string, inputs frontend.Circuit, proof string) (*mixTy.ZkProofInfo, error) {
if privacyPrint > 0 { var proofKey bytes.Buffer
fmt.Println("--output zk parameters for circuit:", circuitFile)
rst, err := json.MarshalIndent(inputs, "", " ") //是Pk file, 需要生成proof
if len(proof) > 0 {
//直接读proof
pkBuf, err := mixTy.GetByteBuff(proof)
if err != nil { if err != nil {
fmt.Println(err) return nil, err
}
proofKey.Write(pkBuf.Bytes())
} else {
//从电路文件获取电路约束
circuit, err := getCircuit(circuitTy)
if err != nil {
return nil, err
}
//从pv 文件读取Pk结构
pkFile := filepath.Join(path, file)
pkStr, err := readZkKeyFile(pkFile)
if err != nil {
return nil, errors.Wrapf(err, "readZkKeyFile")
}
pkBuf, err := mixTy.GetByteBuff(pkStr)
if err != nil {
return nil, err
} }
fmt.Println(string(rst))
}
assignments, err := getAssignments(inputs) pk := groth16.NewProvingKey(ecc.BN254)
if err != nil { if _, err := pk.ReadFrom(pkBuf); err != nil {
return nil, err return nil, errors.Wrapf(err, "read pk")
} }
//产生zk 证明
proof, err := createProof(circuit, pk, inputs)
if err != nil {
return nil, errors.Wrapf(err, "create proof to %s", pkFile)
}
//从电路文件获取电路约束 if _, err := proof.WriteRawTo(&proofKey); err != nil {
circuit, err := getCircuit(circuitFile) return nil, errors.Wrapf(err, "write proof")
if err != nil { }
return nil, err
}
//从pv 文件读取Pk结构
pk, err := getProveKey(pkFile)
if err != nil {
return nil, err
}
//产生zk 证明
proof, err := createProof(circuit, pk, assignments)
if err != nil {
return nil, err
}
//序列号成字符串
proofKey, err := serializeObj(proof)
if err != nil {
return nil, err
} }
//序列号成字符串 //序列号成字符串
proofInput, err := serialInputs(assignments) var pubBuf bytes.Buffer
_, err := witness.WritePublicTo(&pubBuf, ecc.BN254, inputs)
if err != nil { if err != nil {
return nil, err return nil, errors.Wrapf(err, "write public input")
} }
return &mixTy.ZkProofInfo{ return &mixTy.ZkProofInfo{
Proof: proofKey, Proof: hex.EncodeToString(proofKey.Bytes()),
PublicInput: proofInput, PublicInput: hex.EncodeToString(pubBuf.Bytes()),
}, nil }, nil
} }
package wallet package wallet
import ( import (
"encoding/hex" "github.com/33cn/chain33/common"
"encoding/json"
"fmt"
"reflect"
"testing"
"github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/mix/executor/zksnark"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gnark/frontend"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"testing"
) )
func TestGetCommitValue(t *testing.T) { //func TestGetCommitValue(t *testing.T) {
var out, change, minFee, sum uint64 // var out, change, minFee, sum uint64
var inputs []uint64 // var inputs []uint64
inputs = []uint64{100, 80} // inputs = []uint64{100, 80}
out = 60 // out = 60
minFee = 1 // minFee = 1
for _, i := range inputs { // for _, i := range inputs {
sum += i // sum += i
} // }
change = sum - out - minFee // change = sum - out - minFee
_, err := getShieldValue(inputs, out, change, minFee) // _, err := getShieldValue(inputs, out, change, minFee)
assert.Nil(t, err) // assert.Nil(t, err)
//
a := "0a9c010a4d3136323433323838333039363632323833373538343930323239313730303834393836343035373630373234353332323934333436353837323033353436363930353333373131303333323139124b3238383637383239373931373237373235343930333236303134303538313534363138303135353433383231393339363836333632313634323236303434353739313434393237383237331a82033078656663333331616261616139653039353966636536356163343364626534306364646139356534356261636163613161326166626265366637323533633132326233346264323337353932343066306237623836653363343635666131343065666332636665623861653035366234323163303665353062396532646564636236383963336536656435363636373731343235663736313931653831356665666633646432393965633535386261323731343238333131623130353364376265633864646163313733393632326238666138326438373336666531623332633835376438343330643634646637336530643265326238373932396335633762366437336534383365363130303561313361376531643730636637653834656132613235343166373235363834656266613737653235313232326466313039336230313964646165623963376134393763316538653737386462313730323636323536666666363332643437363738626633366634383361373334346666326330" // a := "0a9c010a4d3136323433323838333039363632323833373538343930323239313730303834393836343035373630373234353332323934333436353837323033353436363930353333373131303333323139124b3238383637383239373931373237373235343930333236303134303538313534363138303135353433383231393339363836333632313634323236303434353739313434393237383237331a82033078656663333331616261616139653039353966636536356163343364626534306364646139356534356261636163613161326166626265366637323533633132326233346264323337353932343066306237623836653363343635666131343065666332636665623861653035366234323163303665353062396532646564636236383963336536656435363636373731343235663736313931653831356665666633646432393965633535386261323731343238333131623130353364376265633864646163313733393632326238666138326438373336666531623332633835376438343330643634646637336530643265326238373932396335633762366437336534383365363130303561313361376531643730636637653834656132613235343166373235363834656266613737653235313232326466313039336230313964646165623963376134393763316538653737386462313730323636323536666666363332643437363738626633366634383361373334346666326330"
da, err := hex.DecodeString(a) // da, err := hex.DecodeString(a)
assert.Nil(t, err) // assert.Nil(t, err)
//
var data mixTy.DHSecret // var data mixTy.DHSecret
//
err = types.Decode(da, &data) // err = types.Decode(da, &data)
assert.Nil(t, err) // assert.Nil(t, err)
//fmt.Println("data", data) // //fmt.Println("data", data)
//
var deposit mixTy.DepositProofResp // var deposit mixTy.DepositProofResp
deposit.NoteHash = "notehashstr" // deposit.NoteHash = "notehashstr"
deposit.Proof = &mixTy.SecretData{ // deposit.Proof = &mixTy.SecretData{
ReceiverKey: "receiverstr", // ReceiverKey: "receiverstr",
ReturnKey: "returnval", // ReturnKey: "returnval",
} // }
deposit.Secrets = &mixTy.DHSecretGroup{ // deposit.Secrets = &mixTy.DHSecretGroup{
Receiver: "receiverstr", // Receiver: "receiverstr",
Authorize: "authval", // Authorize: "authval",
} // }
ty := reflect.TypeOf(deposit) // ty := reflect.TypeOf(deposit)
val := reflect.ValueOf(deposit) // val := reflect.ValueOf(deposit)
n := ty.NumField() // n := ty.NumField()
for i := 0; i < n; i++ { // for i := 0; i < n; i++ {
//
fmt.Println("i=", i, "name=", ty.Field(i).Name, "valid", val.Field(i).IsZero(), "name", val.Field(i), "ty", val.FieldByName(ty.Field(i).Name)) // fmt.Println("i=", i, "name=", ty.Field(i).Name, "valid", val.Field(i).IsZero(), "name", val.Field(i), "ty", val.FieldByName(ty.Field(i).Name))
} // }
//
//type strA struct{ // //type strA struct{
// a backend.Assignment `secret:"public"` // // a backend.Assignment `secret:"public"`
// b backend.Assignment `secret:"private"` // // b backend.Assignment `secret:"private"`
//} // //}
//tt := strA{} // //tt := strA{}
// // //
//tt.a.Value.SetString("123",10) // //tt.a.Value.SetString("123",10)
//tt.a.IsPublic // //tt.a.IsPublic
//tt.a.Value.SetString("567",10) // //tt.a.Value.SetString("567",10)
//tp := reflect.TypeOf(tt) // //tp := reflect.TypeOf(tt)
//fmt.Println("tt",tp.Field(0).Tag.Get("secret")) // //fmt.Println("tt",tp.Field(0).Tag.Get("secret"))
} //}
func TestGetAssignments(t *testing.T) { //
deposit := DepositInput{ //func TestGetAssignments(t *testing.T) {
NoteHash: "111", // deposit := DepositInput{
Amount: "222", // NoteHash: "111",
ReceiverPubKey: "333", // Amount: "222",
ReturnPubKey: "444", // ReceiverPubKey: "333",
AuthorizePubKey: "555", // ReturnPubKey: "444",
NoteRandom: "666", // AuthorizePubKey: "555",
} // NoteRandom: "666",
assigns, err := getAssignments(deposit) // }
assert.Nil(t, err) // assigns, err := getAssignments(deposit)
val := assigns["NoteHash"].Value // assert.Nil(t, err)
// val := assigns["NoteHash"].Value
assert.Equal(t, val.String(), deposit.NoteHash) //
assert.Equal(t, assigns["NoteHash"].IsPublic, true) // assert.Equal(t, val.String(), deposit.NoteHash)
assert.Equal(t, assigns["ReceiverPubKey"].IsPublic, false) // assert.Equal(t, assigns["NoteHash"].IsPublic, true)
// assert.Equal(t, assigns["ReceiverPubKey"].IsPublic, false)
reduceAssign := assigns.DiscardSecrets() //
_, ok := reduceAssign["ReceiverPubKey"] // reduceAssign := assigns.DiscardSecrets()
assert.Equal(t, ok, false) // _, ok := reduceAssign["ReceiverPubKey"]
// assert.Equal(t, ok, false)
tv := reflect.ValueOf(&deposit) //
tv.Elem().FieldByName("NoteHash").SetString("999") // tv := reflect.ValueOf(&deposit)
//tv.FieldByName("NoteHash").Elem().SetString("999") // tv.Elem().FieldByName("NoteHash").SetString("999")
assert.Equal(t, "999", deposit.NoteHash) // //tv.FieldByName("NoteHash").Elem().SetString("999")
//var in WithdrawInput // assert.Equal(t, "999", deposit.NoteHash)
//initTreePath(&in) // //var in WithdrawInput
//assert.Equal(t, "99", in.Path1) // //initTreePath(&in)
printObj(deposit) // //assert.Equal(t, "99", in.Path1)
rst, err := json.MarshalIndent(deposit, "", " ") // printObj(deposit)
if err != nil { // rst, err := json.MarshalIndent(deposit, "", " ")
fmt.Println(err) // if err != nil {
return // fmt.Println(err)
} // return
fmt.Println(string(rst)) // }
} // fmt.Println(string(rst))
//}
func TestVerifyProof(t *testing.T) { //
deposit := DepositInput{ //func TestVerifyProof(t *testing.T) {
NoteHash: "319044369386253980478484545601022272388174242630360020319556034291986094405", // deposit := DepositInput{
Amount: "500000000", // NoteHash: "319044369386253980478484545601022272388174242630360020319556034291986094405",
ReceiverPubKey: "7244551457692363731356498279463138379576484998878425864678733206990733443457", // Amount: "500000000",
ReturnPubKey: "0", // ReceiverPubKey: "7244551457692363731356498279463138379576484998878425864678733206990733443457",
AuthorizePubKey: "0", // ReturnPubKey: "0",
NoteRandom: "21887946084880143097415438560893808581456164284155969619878297484093938793578", // AuthorizePubKey: "0",
} // NoteRandom: "21887946084880143097415438560893808581456164284155969619878297484093938793578",
assigns, err := getAssignments(deposit) // }
// assigns, err := getAssignments(deposit)
//从电路文件获取电路约束 //
circuit, err := getCircuit("../cmd/gnark/circuit/deposit/circuit_deposit.r1cs") // //从电路文件获取电路约束
assert.Nil(t, err) // circuit, err := getCircuit("../cmd/gnark/circuit/deposit/circuit_deposit.r1cs")
// assert.Nil(t, err)
//从pv 文件读取Pk结构 //
pk, err := getProveKey("../cmd/gnark/circuit/deposit/circuit_deposit.pk") // //从pv 文件读取Pk结构
assert.Nil(t, err) // pk, err := getProveKey("../cmd/gnark/circuit/deposit/circuit_deposit.pk")
// assert.Nil(t, err)
proof, err := createProof(circuit, pk, assigns) //
assert.Nil(t, err) // proof, err := createProof(circuit, pk, assigns)
// assert.Nil(t, err)
vk, err := getVerifyKey("../cmd/gnark/circuit/deposit/circuit_deposit.vk") //
assert.Nil(t, err) // vk, err := getVerifyKey("../cmd/gnark/circuit/deposit/circuit_deposit.vk")
rst := verifyProof(proof, vk, assigns.DiscardSecrets()) // assert.Nil(t, err)
assert.Equal(t, true, rst) // rst := verifyProof(proof, vk, assigns.DiscardSecrets())
// assert.Equal(t, true, rst)
proofKey, err := serializeObj(proof) //
assert.Nil(t, err) // proofKey, err := serializeObj(proof)
// assert.Nil(t, err)
verifyKey, err := serializeObj(vk) //
assert.Nil(t, err) // verifyKey, err := serializeObj(vk)
// assert.Nil(t, err)
proofInput, err := serialInputs(assigns) //
//fmt.Println("proofinput",proofInput) // proofInput, err := serialInputs(assigns)
assert.Nil(t, err) // //fmt.Println("proofinput",proofInput)
rt, err := zksnark.Verify(verifyKey, proofKey, proofInput) // assert.Nil(t, err)
assert.Nil(t, err) // rt, err := zksnark.Verify(verifyKey, proofKey, proofInput)
assert.Equal(t, true, rt) // assert.Nil(t, err)
// assert.Equal(t, true, rt)
//
//}
//func TestGetZkProofKeys(t *testing.T) {
// var depositCircuit mixTy.DepositCircuit
// depositCircuit.NoteHash.Assign("11183619348394875496624033204802036013086293645689330234403504655205992608466")
// depositCircuit.Amount.Assign(28242048)
// depositCircuit.ReceiverPubKey.Assign("13496572805321444273664325641440458311310163934354047265362731297880627774936")
// depositCircuit.ReturnPubKey.Assign("10193030166569398670555398535278072963719579248877156082361830729347727033510")
// depositCircuit.AuthorizePubKey.Assign("2302306531516619173363925550130201424458047172090558749779153607734711372580")
// depositCircuit.NoteRandom.Assign(2824204835)
//
// pkFile := "../cmd/gnark/circuit_deposit.pk"
// ret, err := getZkProofKeys(mixTy.VerifyType_DEPOSIT, pkFile, &depositCircuit, 0)
//
// assert.Nil(t, err)
// fmt.Println("rst", ret.PublicInput)
//}
func TestUpdateTreePath(t *testing.T) {
var proof mixTy.TreePathProof
proof.TreeRootHash = common.ToHex(common.Sha2Sum([]byte{1}))
path0 := "11183619348394875496624033204802036013086293645689330234403504655205992608466"
path1 := "13496572805321444273664325641440458311310163934354047265362731297880627774936"
proof.TreePath = append(proof.TreePath, path0)
proof.TreePath = append(proof.TreePath, path1)
proof.Helpers = append(proof.Helpers, []uint32{1, 2}...)
var input mixTy.AuthorizeCircuit
updateTreePath(&input, &proof)
ret0 := frontend.FromInterface(frontend.GetAssignedValue(input.Path0))
ret1 := frontend.FromInterface(frontend.GetAssignedValue(input.Path1))
assert.Equal(t, path0, ret0.String())
assert.Equal(t, path1, ret1.String())
path2 := "0"
ret2 := frontend.FromInterface(frontend.GetAssignedValue(input.Path2))
assert.Equal(t, path2, ret2.String())
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment