diff --git a/CHANGELOG.md b/CHANGELOG.md index e88dc8c..8a19bc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [0.1.0] - 2023-06-14 ### Added +- Function `decodeHexText` +- Function `decodeBech32` - Function `f4Jumble` +- Function `f4UnJumble` +- Function `isValidShieldedAddress` +- Function `isValidSaplingViewingKey` +- Function `matchSaplingAddress` - Function `isValidUnifiedAddress` +- Function `decodeUfvk` +- Function `decryptOrchardAction` +- Type `RawData` +- Type `ShieldedOutput` +- Type `OrchardAction` +- Type `OrchardDecodedAction` +- Type `UnifiedFullViewingKey` + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d974301 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +rustlib := librustzcash-wrapper/target/x86_64-unknown-linux-gnu/debug + +.PHONY: all + +all: haskell + +test: test/Spec.hs haskell + stack test + +haskell: src/ZcashHaskell/Orchard.hs src/ZcashHaskell/Sapling.hs src/ZcashHaskell/Types.hs src/ZcashHaskell/Utils.hs src/C/Zcash.chs package.yaml stack.yaml $(rustlib)/rustzcash_wrapper.h $(rustlib)/librustzcash_wrapper.a $(rustlib)/librustzcash_wrapper.so $(rustlib)/rustzcash_wrapper-uninstalled.pc + stack build + +$(rustlib)/rustzcash_wrapper.h: librustzcash-wrapper/src/lib.rs librustzcash-wrapper/Cargo.toml + cd librustzcash-wrapper && cargo +nightly cbuild diff --git a/README.md b/README.md index ed72755..41e7128 100644 --- a/README.md +++ b/README.md @@ -1 +1,7 @@ -# haskell-wrapper +# zcash-haskell + +A Haskell library to interact with the Zcash blockchain. + +## Installation + + diff --git a/app/Main.hs b/app/Main.hs deleted file mode 100644 index 56a7df4..0000000 --- a/app/Main.hs +++ /dev/null @@ -1,6 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module Main where - -main :: IO () -main = putStrLn "Zcash Utilities for Haskell" diff --git a/configure b/configure index 0af689b..21dc7bb 100755 --- a/configure +++ b/configure @@ -1,4 +1,5 @@ #!/bin/bash -export PKG_CONFIG_PATH=$(pwd)/librustzcash-wrapper/target/x86_64-unknown-linux-gnu/debug -export LD_LIBRARY_PATH=$(pwd)/librustzcash-wrapper/target/x86_64-unknown-linux-gnu/debug +echo "export PKG_CONFIG_PATH=$(pwd)/librustzcash-wrapper/target/x86_64-unknown-linux-gnu/debug:\$PKG_CONFIG_PATH" | tee -a ~/.bashrc +echo "export LD_LIBRARY_PATH=$(pwd)/librustzcash-wrapper/target/x86_64-unknown-linux-gnu/debug:\$LD_LIBRARY_PATH" | tee -a ~/.bashrc +source ~/.bashrc diff --git a/librustzcash-wrapper/Cargo.lock b/librustzcash-wrapper/Cargo.lock index c5c6ca0..7f7d85d 100644 --- a/librustzcash-wrapper/Cargo.lock +++ b/librustzcash-wrapper/Cargo.lock @@ -2,6 +2,27 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + [[package]] name = "ahash" version = "0.7.6" @@ -13,6 +34,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + [[package]] name = "arrayref" version = "0.3.7" @@ -25,12 +52,42 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + +[[package]] +name = "base64ct" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" + [[package]] name = "bech32" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf9ff0bbfd639f15c74af777d81383cf53efb7c93613f6cab67c6c11e05bbf8b" +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + [[package]] name = "bincode" version = "1.3.3" @@ -40,6 +97,38 @@ dependencies = [ "serde", ] +[[package]] +name = "bip0039" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef0f0152ec5cf17f49a5866afaa3439816207fd4f0a224c0211ffaf5e278426" +dependencies = [ + "hmac", + "pbkdf2", + "rand", + "sha2 0.10.6", + "unicode-normalization", + "zeroize", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blake2b_simd" version = "1.0.1" @@ -51,6 +140,17 @@ dependencies = [ "constant_time_eq", ] +[[package]] +name = "blake2s_simd" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -60,6 +160,28 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bls12_381" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7bc6d6292be3a19e6379786dac800f551e5865a5bb51ebbe3064ab80433f403" +dependencies = [ + "ff", + "group", + "pairing", + "rand_core", + "subtle", +] + [[package]] name = "borsh" version = "0.9.3" @@ -67,7 +189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" dependencies = [ "borsh-derive 0.9.3", - "hashbrown", + "hashbrown 0.11.2", ] [[package]] @@ -77,7 +199,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" dependencies = [ "borsh-derive 0.10.3", - "hashbrown", + "hashbrown 0.11.2", ] [[package]] @@ -156,21 +278,89 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" dependencies = [ - "sha2", + "sha2 0.9.9", ] +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "const_fn" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" + [[package]] name = "constant_time_eq" version = "0.2.5" @@ -186,6 +376,65 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "digest" version = "0.9.0" @@ -195,6 +444,60 @@ dependencies = [ "generic-array", ] +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "discard" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "equihash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab579d7cf78477773b03e80bc2f89702ef02d7112c711d54ca93dcdce68533d5" +dependencies = [ + "blake2b_simd", + "byteorder", +] + +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "f4jumble" version = "0.1.0" @@ -204,6 +507,52 @@ dependencies = [ "blake2b_simd", ] +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "bitvec", + "rand_core", + "subtle", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "fpe" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c4b37de5ae15812a764c958297cfc50f5c010438f60c6ce75d11b802abd404" +dependencies = [ + "cbc", + "cipher", + "libm", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "generic-array" version = "0.14.7" @@ -225,6 +574,58 @@ dependencies = [ "wasi", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "memuse", + "rand_core", + "subtle", +] + +[[package]] +name = "halo2_gadgets" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126a150072b0c38c7b573fe3eaf0af944a7fed09e154071bf2436d3f016f7230" +dependencies = [ + "arrayvec", + "bitvec", + "ff", + "group", + "halo2_proofs", + "lazy_static", + "pasta_curves", + "rand", + "subtle", + "uint", +] + +[[package]] +name = "halo2_legacy_pdqsort" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47716fe1ae67969c5e0b2ef826f32db8c3be72be325e1aa3c1951d06b5575ec5" + +[[package]] +name = "halo2_proofs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b867a8d9bbb85fca76fff60652b5cd19b853a1c4d0665cb89bee68b18d2caf0" +dependencies = [ + "blake2b_simd", + "ff", + "group", + "halo2_legacy_pdqsort", + "maybe-rayon", + "pasta_curves", + "rand_core", + "tracing", +] + [[package]] name = "hashbrown" version = "0.11.2" @@ -234,6 +635,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "haskell-ffi" version = "0.1.0" @@ -257,10 +664,206 @@ dependencies = [ ] [[package]] -name = "libc" -version = "0.2.141" +name = "heck" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "incrementalmerkletree" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5ad43a3f5795945459d577f6589cf62a476e92c79b75e70cd954364e14ce17b" +dependencies = [ + "serde", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "jubjub" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8499f7a74008aafbecb2a2e608a3e13e4dd3e84df198b604451efe93f2de6e61" +dependencies = [ + "bitvec", + "bls12_381", + "ff", + "group", + "rand_core", + "subtle", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] + +[[package]] +name = "libc" +version = "0.2.146" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" + +[[package]] +name = "libm" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memuse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2145869435ace5ea6ea3d35f59be559317ec9a0d04e1812d5f185a87b6d36f1a" +dependencies = [ + "nonempty", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] [[package]] name = "nonempty" @@ -268,6 +871,46 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi 0.2.6", + "libc", +] + [[package]] name = "once_cell" version = "1.17.1" @@ -280,6 +923,128 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "orchard" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6f418f2c25573923f81a091f38b4b19bc20f6c92b5070fb8f0711e64a2b998" +dependencies = [ + "aes", + "bitvec", + "blake2b_simd", + "ff", + "fpe", + "group", + "halo2_gadgets", + "halo2_proofs", + "hex", + "incrementalmerkletree", + "lazy_static", + "memuse", + "nonempty", + "pasta_curves", + "rand", + "reddsa", + "serde", + "subtle", + "tracing", + "zcash_note_encryption", +] + +[[package]] +name = "pairing" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" +dependencies = [ + "group", +] + +[[package]] +name = "password-hash" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "pasta_curves" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" +dependencies = [ + "blake2b_simd", + "ff", + "group", + "lazy_static", + "rand", + "static_assertions", + "subtle", +] + +[[package]] +name = "pbkdf2" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271779f35b581956db91a3e55737327a03aa051e90b1c47aeb189508533adfd7" +dependencies = [ + "digest 0.10.7", + "password-hash", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "petgraph" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -289,6 +1054,12 @@ dependencies = [ "toml", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + [[package]] name = "proc-macro2" version = "1.0.56" @@ -298,6 +1069,60 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost", +] + [[package]] name = "quote" version = "1.0.26" @@ -307,6 +1132,91 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rayon" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "reddsa" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b34d2c0df43159d2ff79d3cf929c9f11415529127344edb8160ad2be499fcd" +dependencies = [ + "blake2b_simd", + "byteorder", + "group", + "hex", + "jubjub", + "pasta_curves", + "rand_core", + "serde", + "thiserror", + "zeroize", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + [[package]] name = "ref-cast" version = "1.0.16" @@ -327,21 +1237,140 @@ dependencies = [ "syn 2.0.13", ] +[[package]] +name = "regex" +version = "1.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.37.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "rustzcash-wrapper" version = "0.1.0" dependencies = [ + "bech32 0.9.1", "borsh 0.10.3", "f4jumble", "haskell-ffi", + "orchard", "zcash_address", + "zcash_client_backend", + "zcash_note_encryption", + "zcash_primitives", ] +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "zeroize", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + [[package]] name = "serde" version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", +] + +[[package]] +name = "serde_json" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" +dependencies = [ + "sha1_smol", +] + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" [[package]] name = "sha2" @@ -349,13 +1378,100 @@ version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ - "block-buffer", + "block-buffer 0.9.0", "cfg-if", "cpufeatures", - "digest", + "digest 0.9.0", "opaque-debug", ] +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "standback" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" +dependencies = [ + "version_check", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stdweb" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" +dependencies = [ + "discard", + "rustc_version", + "stdweb-derive", + "stdweb-internal-macros", + "stdweb-internal-runtime", + "wasm-bindgen", +] + +[[package]] +name = "stdweb-derive" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_derive", + "syn 1.0.109", +] + +[[package]] +name = "stdweb-internal-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" +dependencies = [ + "base-x", + "proc-macro2", + "quote", + "serde", + "serde_derive", + "serde_json", + "sha1", + "syn 1.0.109", +] + +[[package]] +name = "stdweb-internal-runtime" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + [[package]] name = "syn" version = "1.0.109" @@ -378,6 +1494,99 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +dependencies = [ + "autocfg", + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys", +] + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", +] + +[[package]] +name = "time" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" +dependencies = [ + "const_fn", + "libc", + "standback", + "stdweb", + "time-macros", + "version_check", + "winapi", +] + +[[package]] +name = "time-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" +dependencies = [ + "proc-macro-hack", + "time-macros-impl", +] + +[[package]] +name = "time-macros-impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "standback", + "syn 1.0.109", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "toml" version = "0.5.11" @@ -387,18 +1596,94 @@ dependencies = [ "serde", ] +[[package]] +name = "tonic-build" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6fdaae4c2c638bb70fe42803a26fbd6fc6ac8c72f5c59f67ecc2a2dcabf4b07" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", +] + [[package]] name = "typenum" version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + [[package]] name = "unicode-ident" version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "universal-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "version_check" version = "0.9.4" @@ -411,18 +1696,210 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.13", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zcash_address" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "804268e702b664fc09d3e2ce82786d0addf4ae57ba6976469be63e09066bf9f7" dependencies = [ - "bech32", + "bech32 0.8.1", "bs58", "f4jumble", "zcash_encoding", ] +[[package]] +name = "zcash_client_backend" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55db8d2cb4ca82a71fa66ccd9fa5b211f5ab90c866721311ddd85f8f90d0701" +dependencies = [ + "base64", + "bech32 0.9.1", + "bls12_381", + "bs58", + "crossbeam-channel", + "group", + "memuse", + "nom", + "orchard", + "percent-encoding", + "prost", + "rayon", + "secrecy", + "subtle", + "time", + "tonic-build", + "tracing", + "which", + "zcash_address", + "zcash_encoding", + "zcash_note_encryption", + "zcash_primitives", +] + [[package]] name = "zcash_encoding" version = "0.2.0" @@ -432,3 +1909,69 @@ dependencies = [ "byteorder", "nonempty", ] + +[[package]] +name = "zcash_note_encryption" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb2149e6cd5fbee36c5b87c601715a8c35554602f7fe84af38b636afa2db318" +dependencies = [ + "chacha20", + "chacha20poly1305", + "cipher", + "rand_core", + "subtle", +] + +[[package]] +name = "zcash_primitives" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914d2195a478d5b63191584dff126f552751115181857b290211ec88e68acc3e" +dependencies = [ + "aes", + "bip0039", + "bitvec", + "blake2b_simd", + "blake2s_simd", + "bls12_381", + "byteorder", + "equihash", + "ff", + "fpe", + "group", + "hex", + "incrementalmerkletree", + "jubjub", + "lazy_static", + "memuse", + "nonempty", + "orchard", + "rand", + "rand_core", + "sha2 0.10.6", + "subtle", + "zcash_address", + "zcash_encoding", + "zcash_note_encryption", +] + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", +] diff --git a/librustzcash-wrapper/Cargo.toml b/librustzcash-wrapper/Cargo.toml index d26b3d0..55744d5 100644 --- a/librustzcash-wrapper/Cargo.toml +++ b/librustzcash-wrapper/Cargo.toml @@ -11,6 +11,11 @@ haskell-ffi.rev = "2bf292e2e56eac8e9fb0fb2e1450cf4a4bd01274" f4jumble = "0.1" zcash_address = "0.2.0" borsh = "0.10" +bech32 = "0.9.1" +orchard = "0.4.0" +zcash_note_encryption = "0.3.0" +zcash_primitives = "0.11.0" +zcash_client_backend = "0.9.0" [features] capi = [] diff --git a/librustzcash-wrapper/src/lib.rs b/librustzcash-wrapper/src/lib.rs index 696573b..6be1288 100644 --- a/librustzcash-wrapper/src/lib.rs +++ b/librustzcash-wrapper/src/lib.rs @@ -8,21 +8,180 @@ use std::{ use f4jumble; use borsh::{BorshDeserialize, BorshSerialize}; + use haskell_ffi::{ error::Result, - from_haskell::{marshall_from_haskell_var}, + from_haskell::{marshall_from_haskell_var, marshall_from_haskell_fixed}, to_haskell::{marshall_to_haskell_var, marshall_to_haskell_fixed}, FromHaskell, HaskellSize, ToHaskell }; +use zcash_primitives::{ + zip32::Scope as SaplingScope, + transaction::components::sapling::{ + GrothProofBytes, + OutputDescription, + CompactOutputDescription + }, + sapling::{ + value::ValueCommitment as SaplingValueCommitment, + keys::FullViewingKey as SaplingViewingKey, + note_encryption::SaplingDomain, + PaymentAddress, + note::ExtractedNoteCommitment as SaplingExtractedNoteCommitment + }, + consensus::{ + MainNetwork, + BlockHeight + } +}; + use zcash_address::{ Network, - unified::{Address, Encoding} + unified::{Address, Encoding, Ufvk, Container, Fvk}, + ZcashAddress +}; + +use zcash_client_backend::keys::sapling::ExtendedFullViewingKey; + +use orchard::{ + Action, + keys::{FullViewingKey, PreparedIncomingViewingKey, Scope}, + note::{Nullifier, TransmittedNoteCiphertext, ExtractedNoteCommitment}, + note_encryption::OrchardDomain, + primitives::redpallas::{VerificationKey, SpendAuth, Signature}, + value::ValueCommitment +}; + +use zcash_note_encryption::EphemeralKeyBytes; + +use bech32::{ + decode, + u5, + FromBase32, + ToBase32, + Variant }; pub enum RW {} pub const RW: PhantomData = PhantomData; +#[derive(BorshSerialize, BorshDeserialize)] +pub struct RawData { + hrp: Vec, + bytes: Vec +} + +impl ToHaskell for RawData { + fn to_haskell(&self, writer: &mut W, _tag: PhantomData) -> Result<()> { + self.serialize(writer)?; + Ok(()) + } +} + +//impl FromHaskell for RawData { + //fn from_haskell(buf: &mut &[u8], _tag: PhantomData) -> Result { + //let x = RawData::deserialize(buf)?; + //Ok(x) + //} +//} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct HshieldedOutput { + cv: Vec, + cmu: Vec, + eph_key: Vec, + enc_txt: Vec, + out_txt: Vec, + proof: Vec +} + +impl FromHaskell for HshieldedOutput { + fn from_haskell(buf: &mut &[u8], _tag: PhantomData) -> Result { + let x = HshieldedOutput::deserialize(buf)?; + Ok(x) + } +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct Haction { + nf: Vec, + rk: Vec, + cmx: Vec, + eph_key: Vec, + enc_txt: Vec, + out_txt: Vec, + cv: Vec, + auth: Vec +} + +impl FromHaskell for Haction { + fn from_haskell(buf: &mut &[u8], _tag: PhantomData) -> Result { + let x = Haction::deserialize(buf)?; + Ok(x) + } +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct Hnote { + note: u64, + recipient: Vec, + memo: Vec +} + +impl ToHaskell for Hnote { + fn to_haskell(&self, writer: &mut W, _tag: PhantomData) -> Result<()> { + self.serialize(writer)?; + Ok(()) + } +} + + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct Hufvk { + net: u8, + orchard: Vec, + sapling: Vec, + transparent: Vec +} + +impl ToHaskell for Hufvk { + fn to_haskell(&self, writer: &mut W, _tag: PhantomData) -> Result<()> { + self.serialize(writer)?; + Ok(()) + } +} + +impl Hufvk { + fn add_key_section(&mut self, fvk: &Fvk) { + if let Fvk::Orchard(v) = fvk { + self.orchard = v.to_vec(); + } + if let Fvk::Sapling(w) = fvk { + self.sapling = w.to_vec(); + } + if let Fvk::P2pkh(x) = fvk { + self.transparent = x.to_vec(); + } + } +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct Hsvk { + vk: Vec, + ovk: Vec +} + +impl ToHaskell for Hsvk { + fn to_haskell(&self, writer: &mut W, _tag: PhantomData) -> Result<()> { + self.serialize(writer)?; + Ok(()) + } +} + +fn to_array(v: Vec) -> [T; N] { + v.try_into().unwrap_or_else(|v: Vec| panic!("Expected a Vec of length {} but it was {}", N, v.len())) +} #[no_mangle] pub extern "C" fn rust_wrapper_f4jumble( @@ -35,6 +194,17 @@ pub extern "C" fn rust_wrapper_f4jumble( marshall_to_haskell_var(&result, out, out_len, RW); } +#[no_mangle] +pub extern "C" fn rust_wrapper_f4unjumble( + input: *const u8, + input_len: usize, + out: *mut u8, + out_len: &mut usize) { + let input: Vec = marshall_from_haskell_var(input, input_len, RW); + let result = f4jumble::f4jumble_inv(&input).unwrap(); + marshall_to_haskell_var(&result, out, out_len, RW); +} + #[no_mangle] pub extern "C" fn rust_wrapper_ua_decode( input: *const u8, @@ -43,3 +213,174 @@ pub extern "C" fn rust_wrapper_ua_decode( Address::decode(&input).is_ok() //marshall_to_haskell_var(&result, out, out_len, RW); } + +#[no_mangle] +pub extern "C" fn rust_wrapper_shielded_decode( + input: *const u8, + input_len: usize) -> bool { + let input: String = marshall_from_haskell_var(input, input_len, RW); + ZcashAddress::try_from_encoded(&input).is_ok() +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_bech32decode( + input: *const u8, + input_len: usize, + out: *mut u8, + out_len: &mut usize + ) { + let input: String = marshall_from_haskell_var(input, input_len, RW); + let decodedBytes = bech32::decode(&input); + match decodedBytes { + Ok((hrp, bytes, variant)) => { + let rd = RawData {hrp: hrp.into(), bytes: Vec::::from_base32(&bytes).unwrap()}; + marshall_to_haskell_var(&rd, out, out_len, RW); + } + Err(_e) => { + let rd1 = RawData {hrp: "fail".into(), bytes: vec![0]}; + marshall_to_haskell_var(&rd1, out, out_len, RW); + } + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_svk_decode( + input: *const u8, + input_len: usize + ) -> bool { + let input: Vec = marshall_from_haskell_var(input, input_len, RW); + let svk = ExtendedFullViewingKey::read(&*input); + match svk { + Ok(k) => { + true + } + Err(e) => { + print!("{}", e); + false + } + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_svk_check_address( + key_input: *const u8, + key_input_len: usize, + address_input: *const u8, + address_input_len: usize + ) -> bool { + let key_input: Vec = marshall_from_haskell_var(key_input, key_input_len, RW); + let address_input: Vec = marshall_from_haskell_var(address_input, address_input_len, RW); + let svk = ExtendedFullViewingKey::read(&*key_input); + let sa = PaymentAddress::from_bytes(&to_array(address_input)).unwrap(); + match svk { + Ok(k) => { + let (div_index, def_address) = k.default_address(); + sa == def_address + } + Err(e) => { + false + } + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_ufvk_decode( + input: *const u8, + input_len: usize, + out: *mut u8, + out_len: &mut usize + ) { + let input: String = marshall_from_haskell_var(input, input_len, RW); + let dec_key = Ufvk::decode(&input); + match dec_key { + Ok((n, ufvk)) => { + let x = match n { + Network::Main => 1, + Network::Test => 2, + Network::Regtest => 3 + }; + let mut hk = Hufvk { net: x, orchard: vec![0], sapling: vec![0], transparent: vec![0] }; + let fvks = ufvk.items(); + fvks.iter().for_each(|k| hk.add_key_section(k)); + marshall_to_haskell_var(&hk, out, out_len, RW); + } + Err(_e) => { + let hk0 = Hufvk { net: 0, orchard: vec![0], sapling: vec![0], transparent: vec![0] }; + marshall_to_haskell_var(&hk0, out, out_len, RW); + } + } +} + +//#[no_mangle] +//pub extern "C" fn rust_wrapper_sapling_note_decrypt( + //key: *const u8, + //key_len: usize, + //note: *const u8, + //note_len: usize, + //out: *mut u8, + //out_len: &mut usize + //){ + //let evk: Vec = marshall_from_haskell_var(key, key_len, RW); + //let note_input: HshieldedOutput = marshall_from_haskell_var(note,note_len,RW); + //let svk = ExtendedFullViewingKey::read(&*evk); + //match svk { + //Ok(k) => { + //let domain = SaplingDomain::for_height(MainNetwork, BlockHeight::from_u32(2000000)); + //let action: CompactOutputDescription = CompactOutputDescription { + //ephemeral_key: EphemeralKeyBytes(to_array(note_input.eph_key)), + //cmu: SaplingExtractedNoteCommitment::from_bytes(&to_array(note_input.cmu)).unwrap(), + //enc_ciphertext: to_array(note_input.enc_txt) + //}; + //let fvk = k.to_diversifiable_full_viewing_key().to_ivk(SaplingScope::External); + //let result = zcash_note_encryption::try_note_decryption(&domain, &ivk, &action); + //} + //Err(_e) => { + //let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0] }; + //marshall_to_haskell_var(&hn0, out, out_len, RW); + //} + //} +//} + +#[no_mangle] +pub extern "C" fn rust_wrapper_orchard_note_decrypt( + key: *const u8, + key_len: usize, + note: *const u8, + note_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let fvk_input: Vec = marshall_from_haskell_var(key, key_len, RW); + let note_input: Haction = marshall_from_haskell_var(note, note_len, RW); + let action: Action> = Action::from_parts( + Nullifier::from_bytes(&to_array(note_input.nf)).unwrap(), + VerificationKey::try_from(to_array(note_input.rk)).unwrap(), + ExtractedNoteCommitment::from_bytes(&to_array(note_input.cmx)).unwrap(), + TransmittedNoteCiphertext {epk_bytes: to_array(note_input.eph_key), enc_ciphertext: to_array(note_input.enc_txt), out_ciphertext: to_array(note_input.out_txt)}, + ValueCommitment::from_bytes(&to_array(note_input.cv)).unwrap(), + Signature::from(to_array(note_input.auth))); + let fvk_array = to_array(fvk_input); + let domain = OrchardDomain::for_nullifier(*action.nullifier()); + let dec_fvk = FullViewingKey::from_bytes(&fvk_array); + match dec_fvk { + Some(fvk) => { + let ivk = fvk.to_ivk(Scope::External); + let pivk = PreparedIncomingViewingKey::new(&ivk); + let result = zcash_note_encryption::try_note_decryption(&domain, &pivk, &action); + match result { + Some((n, r, m)) => { + let hn = Hnote {note: n.value().inner(), recipient: r.to_raw_address_bytes().to_vec(), memo: m.to_vec() }; + marshall_to_haskell_var(&hn, out, out_len, RW); + } + None => { + let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0] }; + marshall_to_haskell_var(&hn0, out, out_len, RW); + } + } + }, + None => { + let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0] }; + marshall_to_haskell_var(&hn0, out, out_len, RW); + } + } +} diff --git a/package.yaml b/package.yaml index 4abaff2..e4bb94b 100644 --- a/package.yaml +++ b/package.yaml @@ -9,6 +9,7 @@ copyright: "(c)2023 Vergara Technologies LLC" extra-source-files: - README.md - CHANGELOG.md +- configure # Metadata used when publishing your package synopsis: Utilities to interact with the Zcash blockchain @@ -26,9 +27,10 @@ library: source-dirs: src dependencies: - bytestring - - borsh + - borsh >= 0.2 - text - foreign-rust + - generics-sop pkg-config-dependencies: - rustzcash_wrapper-uninstalled @@ -44,3 +46,4 @@ tests: - zcash-haskell - hspec - bytestring + - text diff --git a/src/C/Zcash.chs b/src/C/Zcash.chs index 17cdeb5..1a85cf9 100644 --- a/src/C/Zcash.chs +++ b/src/C/Zcash.chs @@ -1,4 +1,6 @@ {-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DerivingVia #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE UndecidableInstances #-} @@ -11,6 +13,7 @@ import qualified Data.ByteString as BS import Codec.Borsh import Data.Text (Text) import Data.Word +import Data.Int import Data.Structured import Foreign.C.Types import Foreign.Rust.Marshall.External @@ -18,16 +21,21 @@ import Foreign.Rust.Marshall.Fixed import Foreign.Rust.Marshall.Variable import Foreign.Rust.Serialisation.Raw import Foreign.Rust.Serialisation.Raw.Base16 +import qualified Generics.SOP as SOP +import qualified GHC.Generics as GHC +import ZcashHaskell.Types -newtype CodedString = CodedString BS.ByteString - deriving (Eq) - deriving newtype (BorshSize, ToBorsh, FromBorsh) - deriving newtype (IsRaw) - deriving (Prelude.Show, Data.Structured.Show) via AsBase16 CodedString {# fun unsafe rust_wrapper_f4jumble as rustWrapperF4Jumble { toBorshVar* `BS.ByteString'& - , getVarBuffer `Buffer (CodedString)'& + , getVarBuffer `Buffer (BS.ByteString)'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_f4unjumble as rustWrapperF4UnJumble + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer (BS.ByteString)'& } -> `()' #} @@ -37,3 +45,44 @@ newtype CodedString = CodedString BS.ByteString } -> `Bool' #} + +{# fun pure unsafe rust_wrapper_shielded_decode as rustWrapperIsShielded + { toBorshVar* `BS.ByteString'& + } + -> `Bool' +#} + +{# fun unsafe rust_wrapper_bech32decode as rustWrapperBech32Decode + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer RawData'& + } + -> `()' +#} + +{# fun pure unsafe rust_wrapper_svk_decode as rustWrapperSaplingVkDecode + { toBorshVar* `BS.ByteString'& + } + -> `Bool' +#} + +{# fun pure unsafe rust_wrapper_svk_check_address as rustWrapperSaplingCheck + { toBorshVar* `BS.ByteString'& + , toBorshVar* `BS.ByteString'& + } + -> `Bool' +#} + +{# fun unsafe rust_wrapper_ufvk_decode as rustWrapperUfvkDecode + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer UnifiedFullViewingKey'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_orchard_note_decrypt as rustWrapperOrchardNoteDecode + { toBorshVar* `BS.ByteString'& + , toBorshVar* `OrchardAction'& + , getVarBuffer `Buffer OrchardDecodedAction'& + } + -> `()' + #} diff --git a/src/Zcash.hs b/src/Zcash.hs deleted file mode 100644 index 9b289f3..0000000 --- a/src/Zcash.hs +++ /dev/null @@ -1,15 +0,0 @@ -module Zcash - ( f4Jumble - , isValidUnifiedAddress - ) where - -import C.Zcash (CodedString, rustWrapperF4Jumble, rustWrapperIsUA) -import qualified Data.ByteString as BS -import Foreign.Rust.Marshall.Fixed -import Foreign.Rust.Marshall.Variable - -f4Jumble :: BS.ByteString -> CodedString -f4Jumble = withPureBorshVarBuffer . rustWrapperF4Jumble - -isValidUnifiedAddress :: BS.ByteString -> Bool -isValidUnifiedAddress = rustWrapperIsUA diff --git a/src/ZcashHaskell/Orchard.hs b/src/ZcashHaskell/Orchard.hs new file mode 100644 index 0000000..4c759b2 --- /dev/null +++ b/src/ZcashHaskell/Orchard.hs @@ -0,0 +1,34 @@ +module ZcashHaskell.Orchard where + +import C.Zcash + ( rustWrapperIsUA + , rustWrapperOrchardNoteDecode + , rustWrapperUfvkDecode + ) +import qualified Data.ByteString as BS +import Foreign.Rust.Marshall.Variable +import ZcashHaskell.Types + +-- | Check if given bytestring is a valid encoded unified address +isValidUnifiedAddress :: BS.ByteString -> Bool +isValidUnifiedAddress = rustWrapperIsUA + +-- | Attempt to decode the given bytestring into a Unified Full Viewing Key +decodeUfvk :: BS.ByteString -> Maybe UnifiedFullViewingKey +decodeUfvk str = + case net decodedKey of + 0 -> Nothing + _ -> Just decodedKey + where + decodedKey = (withPureBorshVarBuffer . rustWrapperUfvkDecode) str + +decryptOrchardAction :: + OrchardAction -> UnifiedFullViewingKey -> Maybe OrchardDecodedAction +decryptOrchardAction encAction key = + case a_value decodedAction of + 0 -> Nothing + _ -> Just decodedAction + where + decodedAction = + withPureBorshVarBuffer $ + rustWrapperOrchardNoteDecode (o_key key) encAction diff --git a/src/ZcashHaskell/Sapling.hs b/src/ZcashHaskell/Sapling.hs new file mode 100644 index 0000000..ed6a81d --- /dev/null +++ b/src/ZcashHaskell/Sapling.hs @@ -0,0 +1,20 @@ +module ZcashHaskell.Sapling where + +import C.Zcash + ( rustWrapperIsShielded + , rustWrapperSaplingCheck + , rustWrapperSaplingVkDecode + ) +import qualified Data.ByteString as BS + +-- | Check if given bytesting is a valid encoded shielded address +isValidShieldedAddress :: BS.ByteString -> Bool +isValidShieldedAddress = rustWrapperIsShielded + +-- | Check if given bytestring is a valid Sapling viewing key +isValidSaplingViewingKey :: BS.ByteString -> Bool +isValidSaplingViewingKey = rustWrapperSaplingVkDecode + +-- | Check if the given bytestring for the Sapling viewing key matches the second bytestring for the address +matchSaplingAddress :: BS.ByteString -> BS.ByteString -> Bool +matchSaplingAddress = rustWrapperSaplingCheck diff --git a/src/ZcashHaskell/Types.hs b/src/ZcashHaskell/Types.hs new file mode 100644 index 0000000..b4deba0 --- /dev/null +++ b/src/ZcashHaskell/Types.hs @@ -0,0 +1,75 @@ +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE UndecidableInstances #-} + +module ZcashHaskell.Types where + +import qualified Data.ByteString as BS +import Codec.Borsh +import Data.Word +import Data.Int +import Data.Structured +import qualified Generics.SOP as SOP +import qualified GHC.Generics as GHC + +data RawData = RawData { hrp :: BS.ByteString, bytes :: BS.ByteString} + deriving stock (Prelude.Show, GHC.Generic) + deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) + deriving anyclass (Data.Structured.Show) + deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct RawData + +data UnifiedFullViewingKey = + UnifiedFullViewingKey + { net :: Word8 + , o_key :: BS.ByteString + , s_key :: BS.ByteString + , t_key :: BS.ByteString + } + deriving stock (Eq, Prelude.Show, GHC.Generic) + deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) + deriving anyclass (Data.Structured.Show) + deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct UnifiedFullViewingKey + +data ShieldedOutput = + ShieldedOutput + { s_cv :: BS.ByteString + , s_cmu :: BS.ByteString + , s_ephKey :: BS.ByteString + , s_encCipherText :: BS.ByteString + , s_outCipherText :: BS.ByteString + , s_proof :: BS.ByteString + } + deriving stock (Eq, Prelude.Show, GHC.Generic) + deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) + deriving anyclass (Data.Structured.Show) + deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct ShieldedOutput + +data OrchardAction = + OrchardAction + { nf :: BS.ByteString + , rk :: BS.ByteString + , cmx :: BS.ByteString + , eph_key :: BS.ByteString + , enc_ciphertext :: BS.ByteString + , out_ciphertext :: BS.ByteString + , cv :: BS.ByteString + , auth :: BS.ByteString + } + deriving stock (Eq, Prelude.Show, GHC.Generic) + deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) + deriving anyclass (Data.Structured.Show) + deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OrchardAction + +data OrchardDecodedAction = + OrchardDecodedAction + { a_value :: Int64 + , a_recipient :: BS.ByteString + , a_memo :: BS.ByteString + } + deriving stock (Eq, Prelude.Show, GHC.Generic) + deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) + deriving anyclass (Data.Structured.Show) + deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OrchardDecodedAction + + diff --git a/src/ZcashHaskell/Utils.hs b/src/ZcashHaskell/Utils.hs new file mode 100644 index 0000000..8c28cc9 --- /dev/null +++ b/src/ZcashHaskell/Utils.hs @@ -0,0 +1,34 @@ +module ZcashHaskell.Utils where + +import C.Zcash + ( rustWrapperBech32Decode + , rustWrapperF4Jumble + , rustWrapperF4UnJumble + ) + +import qualified Data.ByteString as BS +import Foreign.Rust.Marshall.Variable +import ZcashHaskell.Types + +-- | Helper function to turn a hex-encoded strings to bytestring +decodeHexText :: String -> BS.ByteString +decodeHexText h = BS.pack $ hexRead h + where + hexRead hexText + | null chunk = [] + | otherwise = + fromIntegral (read ("0x" <> chunk)) : hexRead (drop 2 hexText) + where + chunk = take 2 hexText + +-- | Decode the given bytestring using Bech32 +decodeBech32 :: BS.ByteString -> RawData +decodeBech32 = withPureBorshVarBuffer . rustWrapperBech32Decode + +-- | Apply the F4Jumble transformation to the given bytestring +f4Jumble :: BS.ByteString -> BS.ByteString +f4Jumble = withPureBorshVarBuffer . rustWrapperF4Jumble + +-- | Apply the inverse F4Jumble transformation to the given bytestring +f4UnJumble :: BS.ByteString -> BS.ByteString +f4UnJumble = withPureBorshVarBuffer . rustWrapperF4UnJumble diff --git a/test/Spec.hs b/test/Spec.hs index dfbc469..0ad9d47 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -1,14 +1,33 @@ {-# LANGUAGE OverloadedStrings #-} -import C.Zcash (CodedString(CodedString), rustWrapperIsUA) +import C.Zcash (rustWrapperIsUA) import qualified Data.ByteString as BS +import qualified Data.Text.Encoding as E import Data.Word import Test.Hspec -import Zcash +import ZcashHaskell.Orchard +import ZcashHaskell.Sapling + ( isValidSaplingViewingKey + , isValidShieldedAddress + , matchSaplingAddress + ) +import ZcashHaskell.Types + ( OrchardAction(..) + , OrchardDecodedAction(..) + , RawData(..) + , UnifiedFullViewingKey(..) + ) +import ZcashHaskell.Utils main :: IO () main = do hspec $ do + describe "Bech32" $ do + let s = "bech321qqqsyrhqy2a" + let decodedString = decodeBech32 s + it "hrp matches" $ do hrp decodedString `shouldBe` "bech32" + it "data matches" $ do + bytes decodedString `shouldBe` BS.pack ([0x00, 0x01, 0x02] :: [Word8]) describe "F4Jumble" $ do it "jumble a string" $ do let input = @@ -111,7 +130,140 @@ main = do , 0x8d , 0x22 ] :: [Word8] - CodedString (BS.pack out) `shouldBe` f4Jumble (BS.pack input) + BS.pack out `shouldBe` f4Jumble (BS.pack input) + it "unjumble a string" $ do + let input = + [ 0x5d + , 0x7a + , 0x8f + , 0x73 + , 0x9a + , 0x2d + , 0x9e + , 0x94 + , 0x5b + , 0x0c + , 0xe1 + , 0x52 + , 0xa8 + , 0x04 + , 0x9e + , 0x29 + , 0x4c + , 0x4d + , 0x6e + , 0x66 + , 0xb1 + , 0x64 + , 0x93 + , 0x9d + , 0xaf + , 0xfa + , 0x2e + , 0xf6 + , 0xee + , 0x69 + , 0x21 + , 0x48 + , 0x1c + , 0xdd + , 0x86 + , 0xb3 + , 0xcc + , 0x43 + , 0x18 + , 0xd9 + , 0x61 + , 0x4f + , 0xc8 + , 0x20 + , 0x90 + , 0x5d + , 0x04 + , 0x2b + ] :: [Word8] + let out = + [ 0x03 + , 0x04 + , 0xd0 + , 0x29 + , 0x14 + , 0x1b + , 0x99 + , 0x5d + , 0xa5 + , 0x38 + , 0x7c + , 0x12 + , 0x59 + , 0x70 + , 0x67 + , 0x35 + , 0x04 + , 0xd6 + , 0xc7 + , 0x64 + , 0xd9 + , 0x1e + , 0xa6 + , 0xc0 + , 0x82 + , 0x12 + , 0x37 + , 0x70 + , 0xc7 + , 0x13 + , 0x9c + , 0xcd + , 0x88 + , 0xee + , 0x27 + , 0x36 + , 0x8c + , 0xd0 + , 0xc0 + , 0x92 + , 0x1a + , 0x04 + , 0x44 + , 0xc8 + , 0xe5 + , 0x85 + , 0x8d + , 0x22 + ] :: [Word8] + f4UnJumble (BS.pack out) `shouldBe` BS.pack input + describe "Sapling address" $ do + it "succeeds with valid address" $ do + let sa = + "zs17faa6l5ma55s55exq9rnr32tu0wl8nmqg7xp3e6tz0m5ajn2a6yxlc09t03mqdmvyphavvf3sl8" + isValidShieldedAddress sa `shouldBe` True + it "fails with invalid address" $ do + let sa = + "zs17faa6l5ma55s55exq9rnr32tu0wl8nmqg7xp3e6tz0m5ajn2a6yxlc09t03mqdmvyphavvffake" + isValidShieldedAddress sa `shouldBe` False + describe "Decode Sapling VK" $ do + let vk = + "zxviews1qdjagrrpqqqqpq8es75mlu6rref0qyrstchf8dxzeygtsejwfqu8ckhwl2qj5m8am7lmupxk3vkvdjm8pawjpmesjfapvsqw96pa46c2z0kk7letrxf7mkltwz54fwpxc7kc79mm5kce3rwn5ssl009zwsra2spppwgrx25s9k5hq65f69l4jz2tjmqgy0pl49qmtaj3nudk6wglwe2hpa327hydlchtyq9av6wjd6hu68e04ahwk9a9n2kt0kj3nj99nue65awtu5cwwcpjs" + let sa = + "zs1g2ne5w2r8kvalwzngsk3kfzppx3qcx5560pnfmw9rj5xfd3zfg9dkm7hyxnfyhc423fev5wuue4" + let sa' = + "zs17faa6l5ma55s55exq9rnr32tu0wl8nmqg7xp3e6tz0m5ajn2a6yxlc09t03mqdmvyphavvf3sl8" + let rawKey = decodeBech32 vk + let rawSa = decodeBech32 sa + let rawSa' = decodeBech32 sa' + it "is mainnet" $ do hrp rawKey `shouldBe` "zxviews" + it "is valid Sapling extended full viewing key" $ do + isValidSaplingViewingKey (bytes rawKey) `shouldBe` True + it "matches the right Sapling address" $ do + matchSaplingAddress (bytes rawKey) (bytes rawSa) `shouldBe` True + it "doesn't match the wrong Sapling address" $ do + matchSaplingAddress (bytes rawKey) (bytes rawSa') `shouldBe` False + describe "Decode invalid Sapling VK" $ do + let vk = + "zxviews1qdjagrrpqqqqpq8es75mlu6rref0qyrstchf8dxzeygtsejwfqu8ckhwl2qj5m8am7lmupxk3vkvdjm8pawjpmesjfapvsqw96pa46c2z0kk7letrxf7mkltwz54fwpxc7kc79mm5kce3rwn5ssl009zwsra2spppwgrx25s9k5hq65f69l4jz2tjmqgy0pl49qmtaj3nudk6wglwe2hpa327hydlchtyq9av6wjd6hu68e04ahwk9a9n2kt0kj3nj99nue65awtu5cwwfake" + let rawKey = decodeBech32 vk + it "is not mainnet" $ do hrp rawKey `shouldBe` "fail" describe "Unified address" $ do it "succeeds with correct UA" $ do let ua = @@ -121,3 +273,69 @@ main = do let ua = "u1salpdyefbreakingtheaddressh0h9v6qjr478k80amtkqkws5pr408lxt2953dpprvu06mahxt99cv65fgsm7sw8hlchplfg5pl89ur" isValidUnifiedAddress ua `shouldBe` False + describe "Decode UVK from YWallet" $ do + let uvk = + "uview1u833rp8yykd7h4druwht6xp6k8krle45fx8hqsw6vzw63n24atxpcatws82z092kryazuu6d7rayyut8m36wm4wpjy2z8r9hj48fx5pf49gw4sjrq8503qpz3vqj5hg0vg9vsqeasg5qjuyh94uyfm7v76udqcm2m0wfc25hcyqswcn56xxduq3xkgxkr0l73cjy88fdvf90eq5fda9g6x7yv7d0uckpevxg6540wc76xrc4axxvlt03ptaa2a0rektglmdy68656f3uzcdgqqyu0t7wk5cvwghyyvgqc0rp3vgu5ye4nd236ml57rjh083a2755qemf6dk6pw0qrnfm7246s8eg2hhzkzpf9h73chhng7xhmyem2sjh8rs2m9nhfcslsgenm" + let res = decodeUfvk uvk + it "is mainnet" $ do maybe 0 net res `shouldBe` 1 + it "has Orchard key" $ do BS.length (maybe "" o_key res) `shouldBe` 96 + it "has Sapling key" $ do BS.length (maybe "" s_key res) `shouldBe` 128 + it "does not have Transparent key" $ do + BS.length (maybe "" t_key res) `shouldBe` 1 + describe "Decode bad UVK" $ do + it "should fail" $ do + let fakeUvk = + "uview1u83changinga987bundchofch4ract3r5x8hqsw6vzw63n24atxpcatws82z092kryazuu6d7rayyut8m36wm4wpjy2z8r9hj48fx5pf49gw4sjrq8503qpz3vqj5hg0vg9vsqeasg5qjuyh94uyfm7v76udqcm2m0wfc25hcyqswcn56xxduq3xkgxkr0l73cjy88fdvf90eq5fda9g6x7yv7d0uckpevxg6540wc76xrc4axxvlt03ptaa2a0rektglmdy68656f3uzcdgqqyu0t7wk5cvwghyyvgqc0rp3vgu5ye4nd236ml57rjh083a2755qemf6dk6pw0qrnfm7246s8eg2hhzkzpf9h73chhng7xhmyem2sjh8rs2m9nhfcslsgenm" + decodeUfvk fakeUvk `shouldBe` Nothing + describe "Decode Orchard tx" $ do + let uvk = + "uview1u833rp8yykd7h4druwht6xp6k8krle45fx8hqsw6vzw63n24atxpcatws82z092kryazuu6d7rayyut8m36wm4wpjy2z8r9hj48fx5pf49gw4sjrq8503qpz3vqj5hg0vg9vsqeasg5qjuyh94uyfm7v76udqcm2m0wfc25hcyqswcn56xxduq3xkgxkr0l73cjy88fdvf90eq5fda9g6x7yv7d0uckpevxg6540wc76xrc4axxvlt03ptaa2a0rektglmdy68656f3uzcdgqqyu0t7wk5cvwghyyvgqc0rp3vgu5ye4nd236ml57rjh083a2755qemf6dk6pw0qrnfm7246s8eg2hhzkzpf9h73chhng7xhmyem2sjh8rs2m9nhfcslsgenm" + let res = decodeUfvk uvk + let a = + OrchardAction + (decodeHexText + "248b16d98dfa33f7ba69a0610a63b606699da76c288840b81d7691ee42764416") + (decodeHexText + "17fcc27cce560733edaf91439a8020c4a029a4e7d5893ce024d5ff4b40bbd0a9") + (decodeHexText + "34796d541864832acca43f083892e98a46c912802d5643672d3f25bea177c61c") + (decodeHexText + "a6d2ca10e3fc7446e372266ef45ee3dc0ba373bd378e6bf3092519a7f272bd8c") + (decodeHexText + "08beafdf59110b5d045e4acc13731ef1a27bfa3a9cabe1d575640c18f18ee6697fbb132d36e982ae3eadf5f37fd35f42c2bb07def14759deab1fbe2f98dc1d5913e4a6ef388b714e2cfd6d89ba2302800e02ab5f45e0e02e3895448518cd8afd2c37bb48a66d8b988a37de9d0838d92876894a311bb9f314ba842e5c18ff7a3d8c7f0ff1a7209e2d661595db8f4a4aa267b9593258914bf63c09286eeda7c9b27ddbb4646208c0d03a8fbdc5d96633335a5a65316f5b25189bdce735bdea7e900de56d3b475ae51b7c35eb7ae79ba104baeb0a5a09d1cd8bb347ab34fb26d62ddbf024f5394710626ec0a665b9c917e65b00256db635145164a0329db7bc5358f435d573b2662adf8a6128801825ec8fb7d8aeef567d35c875ddd784fceb7620355e3f056a648b39b4b2d29a1f5e7b7c4ec5fd2b1874ff1e832b308f8644e83878d90582b9a6fd6c293e19dd3e24dbe1b4c15c96608169843d46551900a8cb787b15f0f1696b736dd4c8ebacf1e3288b14e469bdc004fa8557d6b1395700eaba59334906bb012f876e4cd7acd2157719ebd2e28bd0cd4ab4ac458f8848e1c30e729803dd47102200fe703932a15c3618862ec83b40d3aa0ec2343641bcb9afbf931ab21aa4afdbe7e51deca24283c2ccab0eef6e07aac5a4bf3a775bf7d2ddfc8d8766c3bf8e35df1435cf515d93c3b9549477bd9f53d133f05dd256fbcc0b13a63e3e7f8cce6301ab4f19c114f5af079f8c581537458e861b553218a890ea3e77fb99781c7088cd43c67c155ec611c1148721cab5fd0168e4a5ec390b506ec44145474c") + (decodeHexText + "1e40d33446d9f0f0fad40f8829c1ffe860c11c3439e2c15d37c6c40282f9e933dc01798c800e6c92edb4d20478b92559510eda67f3855f68f5ab22ca31e1885c7fa9d4c9ebfb62ceb5e73267bcad0ba7") + (decodeHexText + "63d0d6e8e92691f700bf8af246dcd4ae1041b13e3969f7a9d819a06e0f9429bc") + (decodeHexText + "fe362be160accf2794841c244e8d80bbeb80b9bc95bb653d297a98d32bddf5a05dd5f874891d55924a83f722f75f576f63796770c31074067694cffb2cce7a2a") + let b = + OrchardAction + (decodeHexText + "8921446787f1bd28fa0e4cc5c945ea7fc71165a25f40cd2a325dae0c4467d12c") + (decodeHexText + "240b08b7861aa78989c68cbedd0038af9b3e3456bdc7ff582d597df571d54da2") + (decodeHexText + "e1bc8ccba69ab9f429bf735417aa005cf439d27500b0d3086dbf1be764b42a36") + (decodeHexText + "c89c58ef8553e7d09ba4090654edd1a8c98763c44d3dfb9dad18286c7ef363ae") + (decodeHexText + "0eee1ca5a3a4959cd4b8bc277e6e633f950680c4acb978c14ad8d944a784f46771c9d666a203ca3ac693943d79dd23f8b76a734a62e81932cbe98e8c851f47a11aaef50249e53151f38f88262a4bae8cf26f5f8b2db1d165aff9b57b64713a677c167608585c038e34ca7bbe468e5f86475ccec0a4a8b9a43b56e342e77a6bd09415787c9f4a1c6f20599f57545f1ac32c3a338d7a5bb2d35456adb880cb65c1455969e10df5d94b8c74b244e7093b1a88cc10697a7c2f4d34b6eae3296e64b820573b4d52e06b4427af5b8f5d6722d3a93fd85da615fceac732976ad2c1be4150b4821c149521f5419ea0746fb132d47f593cfc8a3aab6b2b4480c12fadf21280ccd3142e7188d9e5aef3fcd8c5dc0c066dc975bead023ef7f89a486b615b146110ae68b703a8349a5fc225b26a08b2adaf36fb44c9ad1be59d7ced134eb84e3f0b4aec19b71b2d26e910628a11446b97c5e6bbf97e1befa4e04b5947f83c65161b92f58088d28e57adc2a2873e27008e29772c5803502842045cb355d1ea5a9d27c2683dcb38cb49d26af39625ba99b1342f700387b939e7ff6c129417ca8836fe1e96331e35c8bc0763879e8c17cd4535fbcb27a2785c0a47294e07cb54837bb997df34882ce0bececc6adca365c76fc7533cf0503458937dcfb6058b016dbbd399b9f0cca44cbc881016f4957b5e10daada3393d5b2a4cb15ed983506d4d264f9855ce2ef87a7d4a1fc03293a22c28a53c4455447d546813fa33008e5d2d81848825fae2f437ab9575ba99c230e78f4b23e575e7647beff0e4c4e2b0a1f7320e9460") + (decodeHexText + "d727aeec27bb0f7463c6ed4f5b3f4085cfd3e7218478db0dcebfca875e025320fb64bc4062251823859e963446cadd9924c559e5f981480df5a4f036daf5a8033d4c8241e128902aa1aeaf6adc149730") + (decodeHexText + "98e72813aeb6ea05347798e35379bc881d9cf2b37d38850496ee956fbecd8eab") + (decodeHexText + "cb9926f519041343c957a74f2f67900ed3d250c4dbcd26b9e2addd5247b841a9fde2219d2ef8c9ae8145fecc7792ca6770830c58c95648087f3c8a0a69369402") + let decryptedNote = decryptOrchardAction a =<< res + let decryptedNote2 = decryptOrchardAction b =<< res + describe "First action (sender)" $ do + it "Decryption fails " $ do decryptedNote `shouldBe` Nothing + describe "Second action (recipient)" $ do + it "Decryption succeeds" $ do decryptedNote2 `shouldNotBe` Nothing + it "Tx amount is validated" $ do + (a_value <$> decryptedNote2) `shouldBe` Just 3000 + it "Memo is validated" $ do + let msg = maybe "" a_memo decryptedNote2 + msg `shouldBe` + "Hello World!\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL" diff --git a/zcash-haskell.cabal b/zcash-haskell.cabal index a4f20d2..433f5ae 100644 --- a/zcash-haskell.cabal +++ b/zcash-haskell.cabal @@ -18,6 +18,7 @@ build-type: Simple extra-source-files: README.md CHANGELOG.md + configure source-repository head type: git @@ -26,7 +27,10 @@ source-repository head library exposed-modules: C.Zcash - Zcash + ZcashHaskell.Orchard + ZcashHaskell.Sapling + ZcashHaskell.Types + ZcashHaskell.Utils other-modules: Paths_zcash_haskell hs-source-dirs: @@ -35,9 +39,10 @@ library rustzcash_wrapper-uninstalled build-depends: base >=4.7 && <5 - , borsh + , borsh >=0.2 , bytestring , foreign-rust + , generics-sop , text default-language: Haskell2010 @@ -53,5 +58,6 @@ test-suite zcash-haskell-test base >=4.7 && <5 , bytestring , hspec + , text , zcash-haskell default-language: Haskell2010