diff --git a/CHANGELOG.md b/CHANGELOG.md index cf7b6d7..048a597 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,141 @@ 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). +## [0.7.8.0] + +## Added + +- New `UnifiedIncomingViewingKey` type +- Functions to derive Orchard full viewing key +- Functions to derive Sapling full viewing key +- Functions to derive transparent "full viewing key" +- Functions to encode Unified Full Viewing Keys +- Functions to encode Unified Incoming Viewing Keys + +## [0.7.7.0] + +### Changed + +- Updated Rust crates + +## [0.7.6.0] + +### Changed + +- Removed workaround for missing `time` field in Zebra's `getblock` response. + +## [0.7.5.0] + +### Added + +- Sapling commitment node functions +- Sapling Merkle path test + +### Changed + +- Upgraded Rust dependencies to latest versions: + - `zcash_primitives` 0.19.0 + - `zcash_client_backend` 0.14.0 + - `orchard` 0.10.0 + - `sapling-crypto` 0.3.0 + - `incrementalmerkletree` 0.7.0 + - `zip32` 0.1.2 + +## [0.7.4.0] + +### Added + +- `MerklePath` + +## [0.7.3.0] + +### Added + +- Function to create an Orchard hash from a note commitment +- Function to hash Orchard commitments + +### Changed + +- Modified frontiers to use `HexString` for ommers +- Optimized `createTransaction` + +## [0.7.2.0] + +### Changed + +- Modified Sapling commitment trees to use Frontier + +## [0.7.1.1] + +### Added + +- `ToJSON` instance for `BlockResponse` + +### Changed + +- Updated libraries: + - conduit + - data-fix + - happy + - happy-lib + - http-conduit + - iproute + - mono-traversable + - network + - secp256k1-haskell + - strict + - typed-process + +## [0.7.1.0] + +### Added + +- Type `OrchardFrontier` + +### Changed + +- Modified Orchard commitment trees functions to use Frontier + +## [0.7.0.2] + +### Changed + +- Modified witness update functions to skip the process if no commitments are present + +## [0.7.0.1] + +### Added +- New error type `PrivacyPolicyError` + +## [0.7.0.0] + +- Implement `wagyu-zcash-parameters` in Rust bindings + +## [0.6.2.3] + +### Fixed + +- Decoding of unified addresses with no transparent receivers + +## [0.6.2.2] + +- Added JSON instances for `ZcashNet` +- Added JSON instances for `Transaction` +- Added `ValidAddress` + +## [0.6.2.1] + +### Changed + +- Modified the parsing of raw transactions for shielded outputs +- Upgraded to GHC 9.6.5 + +## [0.6.2.0] + +### Changed + +- Performance enhancement for transaction creation + ## [0.6.1.1] ### Added diff --git a/cabal.project b/cabal.project index 989ae5a..1f0bf49 100644 --- a/cabal.project +++ b/cabal.project @@ -1,6 +1,6 @@ packages: ./*.cabal -with-compiler: ghc-9.4.8 +with-compiler: ghc-9.6.5 source-repository-package type: git diff --git a/cabal.project.freeze b/cabal.project.freeze index 5cf3ed7..206c446 100644 --- a/cabal.project.freeze +++ b/cabal.project.freeze @@ -1,40 +1,40 @@ active-repositories: hackage.haskell.org:merge -constraints: any.Cabal ==3.8.1.0, - any.Cabal-syntax ==3.8.1.0, +constraints: any.Cabal ==3.10.3.0, + any.Cabal-syntax ==3.10.3.0, any.HUnit ==1.6.2.0, - any.OneTuple ==0.4.1.1, + any.OneTuple ==0.4.2, any.QuickCheck ==2.14.3, QuickCheck -old-random +templatehaskell, any.StateVar ==1.2.2, - any.aeson ==2.2.1.0, + any.aeson ==2.2.3.0, aeson +ordered-keymap, any.alex ==3.5.1.0, - any.ansi-terminal ==1.1, + any.ansi-terminal ==1.1.1, ansi-terminal -example, any.ansi-terminal-types ==1.1, any.appar ==0.1.8, - any.array ==0.5.4.0, + any.array ==0.5.6.0, any.asn1-encoding ==0.9.6, any.asn1-parse ==0.9.5, any.asn1-types ==0.3.4, - any.assoc ==1.1, - assoc +tagged, + any.assoc ==1.1.1, + assoc -tagged, any.async ==2.2.5, async -bench, any.attoparsec ==0.14.4, attoparsec -developer, - any.attoparsec-aeson ==2.2.0.1, - any.base ==4.17.2.1, - any.base-orphans ==0.9.1, + any.attoparsec-aeson ==2.2.2.0, + any.base ==4.18.2.1, + any.base-orphans ==0.9.2, any.base16 ==1.0, any.base16-bytestring ==1.0.2.0, any.base58-bytestring ==0.1.0, any.base64-bytestring ==1.2.1.0, any.basement ==0.0.16, - any.bifunctors ==5.6.1, + any.bifunctors ==5.6.2, bifunctors +tagged, any.binary ==0.8.9.1, - any.binary-orphans ==1.0.4.1, + any.binary-orphans ==1.0.5, any.bitvec ==1.1.5.0, bitvec +simd, any.blaze-builder ==0.4.2.3, @@ -50,19 +50,20 @@ constraints: any.Cabal ==3.8.1.0, cborg +optimize-gmp, any.cereal ==0.5.8.3, cereal -bytestring-builder, + any.character-ps ==0.1, any.colour ==2.3.6, any.comonad ==5.0.8, comonad +containers +distributive +indexed-traversable, - any.conduit ==1.3.5, + any.conduit ==1.3.6, any.conduit-extra ==1.3.6, any.containers ==0.6.7, any.contravariant ==1.5.5, contravariant +semigroups +statevar +tagged, any.cookie ==0.5.0, - any.crypton ==0.34, + any.crypton ==1.0.0, crypton -check_alignment +integer-gmp -old_toolchain_inliner +support_aesni +support_deepseq +support_pclmuldq +support_rdrand -support_sse +use_target_attributes, - any.crypton-connection ==0.3.2, - any.crypton-x509 ==1.7.6, + any.crypton-connection ==0.4.1, + any.crypton-x509 ==1.7.7, any.crypton-x509-store ==1.6.9, any.crypton-x509-system ==1.6.7, any.crypton-x509-validation ==1.6.12, @@ -73,72 +74,73 @@ constraints: any.Cabal ==3.8.1.0, any.data-default-instances-containers ==0.0.1, any.data-default-instances-dlist ==0.0.1, any.data-default-instances-old-locale ==0.0.1, - any.data-fix ==0.3.2, - any.deepseq ==1.4.8.0, - any.directory ==1.3.7.1, + any.data-fix ==0.3.4, + any.deepseq ==1.4.8.1, + any.directory ==1.3.8.4, any.distributive ==0.6.2.1, distributive +semigroups +tagged, any.dlist ==1.0, dlist -werror, any.entropy ==0.4.1.10, entropy -donotgetentropy, - any.envy ==2.1.2.0, - any.exceptions ==0.10.5, - any.filepath ==1.4.2.2, - any.foldable1-classes-compat ==0.1, - foldable1-classes-compat +tagged, + any.envy ==2.1.3.0, + any.exceptions ==0.10.7, + any.filepath ==1.4.300.1, any.foreign-rust ==0.1.0, any.generically ==0.1.1, any.generics-sop ==0.5.1.4, any.ghc-bignum ==1.3, - any.ghc-boot-th ==9.4.8, - any.ghc-prim ==0.9.1, + any.ghc-boot-th ==9.6.5, + any.ghc-prim ==0.10.0, any.half ==0.3.1, - any.happy ==1.20.1.1, - any.hashable ==1.4.3.0, - hashable +integer-gmp -random-initial-seed, + any.happy ==2.0.2, + any.happy-lib ==2.0.2, + any.hashable ==1.4.7.0, + hashable -arch-native +integer-gmp -random-initial-seed, any.haskell-lexer ==1.1.1, - any.haskoin-core ==1.0.4, + any.haskoin-core ==1.1.0, any.hexstring ==0.12.1.0, any.hourglass ==0.2.12, any.hsc2hs ==0.68.10, hsc2hs -in-ghc-tree, - any.hspec ==2.11.7, - any.hspec-core ==2.11.7, - any.hspec-discover ==2.11.7, + any.hspec ==2.11.9, + any.hspec-core ==2.11.9, + any.hspec-discover ==2.11.9, any.hspec-expectations ==0.8.4, - any.http-client ==0.7.16, + any.http-client ==0.7.17, http-client +network-uri, any.http-client-tls ==0.3.6.3, - any.http-conduit ==2.3.8.3, + any.http-conduit ==2.3.9, http-conduit +aeson, any.http-types ==0.12.4, - any.indexed-traversable ==0.1.3, - any.indexed-traversable-instances ==0.1.1.2, - any.integer-conversion ==0.1.0.1, + any.indexed-traversable ==0.1.4, + any.indexed-traversable-instances ==0.1.2, + any.integer-conversion ==0.1.1, any.integer-gmp ==1.1, any.integer-logarithms ==1.0.3.1, integer-logarithms -check-bounds +integer-gmp, - any.iproute ==1.7.12, + any.iproute ==1.7.14, any.language-c ==0.9.3, language-c -allwarnings +iecfpextension +usebytestrings, any.memory ==0.18.0, memory +support_bytestring +support_deepseq, any.mime-types ==0.1.2.0, - any.mono-traversable ==1.0.17.0, - any.mtl ==2.2.2, + any.mono-traversable ==1.0.20.0, + any.mtl ==2.3.1, any.murmur3 ==1.0.5, - any.network ==3.1.4.0, + any.network ==3.2.4.0, network -devel, any.network-uri ==2.6.4.2, any.old-locale ==1.0.0.7, any.old-time ==1.1.0.4, + any.os-string ==2.0.6, any.parsec ==3.1.16.1, any.pem ==0.2.4, any.pretty ==1.1.3.6, any.primitive ==0.9.0.0, - any.process ==1.6.18.0, + any.process ==1.6.19.0, any.quickcheck-io ==0.2.0, + any.quickcheck-transformer ==0.3.1.2, any.random ==1.2.1.2, any.regex-base ==0.94.0.2, any.regex-compat ==0.95.2.1, @@ -147,12 +149,12 @@ constraints: any.Cabal ==3.8.1.0, any.resourcet ==1.3.0, any.rts ==1.0.2, any.safe ==0.3.21, - any.scientific ==0.3.7.0, - scientific -bytestring-builder -integer-simple, - any.secp256k1-haskell ==1.1.0, - any.semialign ==1.3, + any.scientific ==0.3.8.0, + scientific -integer-simple, + any.secp256k1-haskell ==1.4.0, + any.semialign ==1.3.1, semialign +semigroupoids, - any.semigroupoids ==6.0.0.1, + any.semigroupoids ==6.0.1, semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers, any.serialise ==0.2.6.1, serialise +newtime15, @@ -164,44 +166,43 @@ constraints: any.Cabal ==3.8.1.0, any.stm ==2.5.1.0, any.streaming-commons ==0.2.2.6, streaming-commons -use-bytestring-builder, - any.strict ==0.5, + any.strict ==0.5.1, any.string-conversions ==0.4.0.1, any.tagged ==0.8.8, tagged +deepseq +transformers, - any.template-haskell ==2.19.0.0, + any.template-haskell ==2.20.0.0, any.text ==2.0.2, - any.text-iso8601 ==0.1, - any.text-short ==0.1.5, + any.text-iso8601 ==0.1.1, + any.text-short ==0.1.6, text-short -asserts, any.tf-random ==0.5, - any.th-abstraction ==0.6.0.0, - any.th-compat ==0.1.4, - any.these ==1.2, + any.th-abstraction ==0.7.0.0, + any.th-compat ==0.1.5, + any.these ==1.2.1, any.time ==1.12.2, - any.time-compat ==1.9.6.1, - time-compat -old-locale, - any.tls ==2.0.1, + any.time-compat ==1.9.7, + any.tls ==2.1.0, tls -devel, - any.transformers ==0.5.6.2, + any.transformers ==0.6.1.0, any.transformers-compat ==0.7.2, transformers-compat -five +five-three -four +generic-deriving +mtl -three -two, - any.typed-process ==0.2.11.1, - any.unix ==2.7.3, - any.unix-time ==0.4.12, + any.typed-process ==0.2.12.0, + any.unix ==2.8.4.0, + any.unix-time ==0.4.15, any.unliftio-core ==0.2.1.0, any.unordered-containers ==0.2.20, unordered-containers -debug, any.utf8-string ==1.0.2, - any.uuid-types ==1.0.5.1, + any.uuid-types ==1.0.6, any.vector ==0.13.1.0, vector +boundschecks -internalchecks -unsafechecks -wall, - any.vector-algorithms ==0.9.0.1, + any.vector-algorithms ==0.9.0.2, vector-algorithms +bench +boundschecks -internalchecks -llvm +properties -unsafechecks, any.vector-stream ==0.1.0.1, any.void ==0.7.3, void -safe, any.wide-word ==0.1.6.0, - any.witherable ==0.4.2, - any.zlib ==0.7.0.0, + any.witherable ==0.5, + any.zlib ==0.7.1.0, zlib -bundled-c-zlib +non-blocking-ffi +pkg-config -index-state: hackage.haskell.org 2024-03-06T20:26:39Z +index-state: hackage.haskell.org 2024-10-11T12:55:31Z diff --git a/configure b/configure index bb38dfe..54d8aaf 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #!/bin/bash - -echo "export PKG_CONFIG_PATH=$HOME/.local/share/zcash-haskell:\$PKG_CONFIG_PATH" | tee -a ~/.bashrc -echo "export LD_LIBRARY_PATH=$HOME/.local/share/zcash-haskell:\$LD_LIBRARY_PATH" | tee -a ~/.bashrc +echo -e "\n" +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 53583a4..57a7a8f 100644 --- a/librustzcash-wrapper/Cargo.lock +++ b/librustzcash-wrapper/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -25,9 +25,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", @@ -35,46 +35,49 @@ dependencies = [ ] [[package]] -name = "anyhow" -version = "1.0.71" +name = "aho-corasick" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "base64" -version = "0.21.2" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.0.1" +version = "1.6.0" 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" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bech32" @@ -120,29 +123,39 @@ dependencies = [ [[package]] name = "bip0039" -version = "0.10.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef0f0152ec5cf17f49a5866afaa3439816207fd4f0a224c0211ffaf5e278426" +checksum = "568b6890865156d9043af490d4c4081c385dd68ea10acd6ca15733d511e6b51c" dependencies = [ "hmac", "pbkdf2", "rand", - "sha2 0.10.6", + "sha2 0.10.8", "unicode-normalization", "zeroize", ] [[package]] -name = "bitflags" -version = "1.3.2" +name = "bip32" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "aa13fae8b6255872fd86f7faf4b41168661d7d78609f7bfe6771b85c6739a15b" +dependencies = [ + "bs58 0.5.1", + "hmac", + "rand_core", + "ripemd", + "secp256k1", + "sha2 0.10.8", + "subtle", + "zeroize", +] [[package]] name = "bitflags" -version = "2.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -158,9 +171,9 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" dependencies = [ "arrayref", "arrayvec", @@ -169,9 +182,9 @@ dependencies = [ [[package]] name = "blake2s_simd" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" +checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae" dependencies = [ "arrayref", "arrayvec", @@ -215,41 +228,18 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" dependencies = [ - "borsh-derive 0.9.3", + "borsh-derive", "hashbrown 0.11.2", ] -[[package]] -name = "borsh" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" -dependencies = [ - "borsh-derive 0.10.3", - "hashbrown 0.12.3", -] - [[package]] name = "borsh-derive" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" dependencies = [ - "borsh-derive-internal 0.9.3", - "borsh-schema-derive-internal 0.9.3", - "proc-macro-crate", - "proc-macro2", - "syn 1.0.109", -] - -[[package]] -name = "borsh-derive" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" -dependencies = [ - "borsh-derive-internal 0.10.3", - "borsh-schema-derive-internal 0.10.3", + "borsh-derive-internal", + "borsh-schema-derive-internal", "proc-macro-crate", "proc-macro2", "syn 1.0.109", @@ -266,17 +256,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "borsh-derive-internal" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "borsh-schema-derive-internal" version = "0.9.3" @@ -288,17 +267,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "borsh-schema-derive-internal" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "bs58" version = "0.4.0" @@ -310,31 +278,25 @@ dependencies = [ [[package]] name = "bs58" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ - "sha2 0.10.6", + "sha2 0.10.8", "tinyvec", ] -[[package]] -name = "bumpalo" -version = "3.15.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" - [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.4.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cbc" @@ -347,9 +309,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.90" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -394,61 +359,61 @@ dependencies = [ [[package]] name = "constant_time_eq" -version = "0.2.5" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "core2" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239fa3ae9b63c2dc74bd3fa852d4792b8b305ae64eeede946265b6af62f1fff3" +dependencies = [ + "memchr", +] [[package]] name = "cpufeatures" -version = "0.2.6" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" -dependencies = [ - "cfg-if", -] +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" @@ -497,18 +462,18 @@ dependencies = [ [[package]] name = "document-features" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" dependencies = [ "litrs", ] [[package]] name = "either" -version = "1.8.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "equihash" @@ -521,43 +486,35 @@ dependencies = [ ] [[package]] -name = "errno" -version = "0.3.1" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 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" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a83e8d7fd0c526af4aad893b7c9fe41e2699ed8a776a6c74aecdeafe05afc75" +checksum = "0d42773cb15447644d170be20231a3268600e0c4cea8987d013b93ac973d3cf7" dependencies = [ "blake2b_simd", ] [[package]] name = "fastrand" -version = "1.9.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "ff" @@ -608,15 +565,27 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", "wasi", ] +[[package]] +name = "getset" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f636605b743120a8d32ed92fc27b6cde1a769f8f936c065151eb66f88ded513c" +dependencies = [ + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "group" version = "0.13.0" @@ -631,18 +600,20 @@ dependencies = [ [[package]] name = "halo2_gadgets" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126a150072b0c38c7b573fe3eaf0af944a7fed09e154071bf2436d3f016f7230" +checksum = "73a5e510d58a07d8ed238a5a8a436fe6c2c79e1bb2611f62688bc65007b4e6e7" dependencies = [ "arrayvec", "bitvec", "ff", "group", + "halo2_poseidon", "halo2_proofs", "lazy_static", "pasta_curves", "rand", + "sinsemilla", "subtle", "uint", ] @@ -653,6 +624,18 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47716fe1ae67969c5e0b2ef826f32db8c3be72be325e1aa3c1951d06b5575ec5" +[[package]] +name = "halo2_poseidon" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa3da60b81f02f9b33ebc6252d766f843291fb4d2247a07ae73d20b791fc56f" +dependencies = [ + "bitvec", + "ff", + "group", + "pasta_curves", +] + [[package]] name = "halo2_proofs" version = "0.3.0" @@ -680,12 +663,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "haskell-ffi" @@ -693,7 +673,7 @@ version = "0.1.0" source = "git+https://github.com/BeFunctional/haskell-rust-ffi.git?rev=2bf292e2e56eac8e9fb0fb2e1450cf4a4bd01274#2bf292e2e56eac8e9fb0fb2e1450cf4a4bd01274" dependencies = [ "bincode", - "borsh 0.9.3", + "borsh", "haskell-ffi-derive", "ref-cast", "serde", @@ -709,39 +689,17 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "hdwallet" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a03ba7d4c9ea41552cd4351965ff96883e629693ae85005c501bb4b9e1c48a7" -dependencies = [ - "lazy_static", - "rand_core", - "ring", - "secp256k1", - "thiserror", -] - [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.9" 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" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -759,22 +717,31 @@ dependencies = [ ] [[package]] -name = "incrementalmerkletree" -version = "0.5.1" +name = "home" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1872810fb725b06b8c153dde9e86f3ec26747b9b60096da7a869883b549cbe" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "incrementalmerkletree" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216c71634ac6f6ed13c2102d64354c0a04dcbdc30e31692c5972d3974d8b6d97" dependencies = [ "either", ] [[package]] name = "indexmap" -version = "1.9.3" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ - "autocfg", - "hashbrown 0.12.3", + "equivalent", + "hashbrown 0.15.2", ] [[package]] @@ -786,44 +753,15 @@ 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" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] -[[package]] -name = "js-sys" -version = "0.3.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" -dependencies = [ - "wasm-bindgen", -] - [[package]] name = "jubjub" version = "0.10.0" @@ -840,30 +778,30 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ "spin", ] [[package]] name = "libc" -version = "0.2.153" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libm" -version = "0.2.6" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "litrs" @@ -873,9 +811,9 @@ checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" [[package]] name = "log" -version = "0.4.19" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "maybe-rayon" @@ -889,27 +827,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.4" 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", -] +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memuse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2145869435ace5ea6ea3d35f59be559317ec9a0d04e1812d5f185a87b6d36f1a" -dependencies = [ - "nonempty", -] +checksum = "3d97bbf43eb4f088f8ca469930cde17fa036207c9a5e02ccc5107c4e8b17c964" [[package]] name = "minimal-lexical" @@ -919,9 +845,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "multimap" -version = "0.8.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" [[package]] name = "nom" @@ -941,11 +867,10 @@ checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -958,58 +883,60 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] [[package]] name = "once_cell" -version = "1.17.1" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "orchard" -version = "0.7.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb255c3ffdccd3c84fe9ebed72aef64fdc72e6a3e4180dd411002d47abaad42" +checksum = "02f7152474406422f572de163e0bc63b2126cdbfe17bc849efbbde36fcfe647e" dependencies = [ "aes", "bitvec", "blake2b_simd", + "core2", "ff", "fpe", + "getset", "group", "halo2_gadgets", + "halo2_poseidon", "halo2_proofs", "hex", "incrementalmerkletree", @@ -1020,8 +947,10 @@ dependencies = [ "rand", "reddsa", "serde", + "sinsemilla", "subtle", "tracing", + "visibility", "zcash_note_encryption", "zcash_spec", "zip32", @@ -1038,9 +967,9 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", "rand_core", @@ -1064,9 +993,9 @@ dependencies = [ [[package]] name = "pbkdf2" -version = "0.10.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271779f35b581956db91a3e55737327a03aa051e90b1c47aeb189508533adfd7" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", "password-hash", @@ -1074,15 +1003,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "petgraph" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", "indexmap", @@ -1090,9 +1019,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "poly1305" @@ -1113,18 +1042,21 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "prettyplease" -version = "0.2.15" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -1137,19 +1069,41 @@ dependencies = [ ] [[package]] -name = "proc-macro2" -version = "1.0.66" +name = "proc-macro-error-attr2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "prost" -version = "0.12.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "2c0fef6c4230e4ccf618a35c59d7ede15dea37de8427500f50aff708806e42ec" dependencies = [ "bytes", "prost-derive", @@ -1157,11 +1111,10 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.12.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" +checksum = "d0f3e5beed80eb580c68e2c600937ac2c4eedabdfd5ef1e5b7ea4f3fba84497b" dependencies = [ - "bytes", "heck", "itertools", "log", @@ -1172,38 +1125,37 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.32", + "syn 2.0.90", "tempfile", - "which", ] [[package]] name = "prost-derive" -version = "0.12.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "157c5a9d7ea5c2ed2d9fb8f495b64759f7816c7eaea54ba3978f0d63000162e3" dependencies = [ "anyhow", "itertools", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] name = "prost-types" -version = "0.12.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +checksum = "cc2f1e56baa61e93533aebc21af4d2134b70f66275e0fcdf3cbe43d77ff7e8fc" dependencies = [ "prost", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1246,9 +1198,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.7.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -1256,21 +1208,19 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "reddsa" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b34d2c0df43159d2ff79d3cf929c9f11415529127344edb8160ad2be499fcd" +checksum = "78a5191930e84973293aa5f532b513404460cd2216c1cfb76d08748c15b40b02" dependencies = [ "blake2b_simd", "byteorder", @@ -1297,64 +1247,54 @@ dependencies = [ "zeroize", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "ref-cast" -version = "1.0.16" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43faa91b1c8b36841ee70e97188a869d37ae21759da6846d4be66de5bf7b12c" +checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.16" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d2275aab483050ab2a7364c1a46604865ee7d6906684e08db0f090acf74f9e7" +checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] name = "regex" -version = "1.8.4" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "ripemd" @@ -1367,13 +1307,12 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.20" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ - "bitflags 1.3.2", + "bitflags", "errno", - "io-lifetimes", "libc", "linux-raw-sys", "windows-sys", @@ -1383,8 +1322,10 @@ dependencies = [ name = "rustzcash-wrapper" version = "0.1.0" dependencies = [ + "ahash", "bech32 0.11.0", - "borsh 0.10.3", + "bip0039", + "borsh", "f4jumble", "haskell-ffi", "incrementalmerkletree", @@ -1395,7 +1336,8 @@ dependencies = [ "rand_core", "sapling-crypto", "secp256k1", - "zcash_address 0.2.0", + "wagyu-zcash-parameters", + "zcash_address 0.2.1", "zcash_client_backend", "zcash_note_encryption", "zcash_primitives", @@ -1404,9 +1346,9 @@ dependencies = [ [[package]] name = "sapling-crypto" -version = "0.1.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02f4270033afcb0c74c5c7d59c73cfd1040367f67f224fe7ed9a919ae618f1b7" +checksum = "85c2acdbbab83d554fc2dceea5f7d6d3da71e57adb18a6c80b8901bd0eee54b0" dependencies = [ "aes", "bellman", @@ -1418,6 +1360,7 @@ dependencies = [ "document-features", "ff", "fpe", + "getset", "group", "hex", "incrementalmerkletree", @@ -1434,17 +1377,11 @@ dependencies = [ "zip32", ] -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - [[package]] name = "secp256k1" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" dependencies = [ "secp256k1-sys", ] @@ -1469,22 +1406,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.193" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -1502,9 +1439,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -1513,21 +1450,38 @@ dependencies = [ [[package]] name = "shardtree" -version = "0.2.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf20c7a2747d9083092e3a3eeb9a7ed75577ae364896bebbc5e0bdcd4e97735" +checksum = "b5f2390975ebfe8838f9e861f7a588123d49a7a7a0a08568ea831d8ad53fc9b4" dependencies = [ - "bitflags 2.4.2", + "bitflags", "either", "incrementalmerkletree", "tracing", ] [[package]] -name = "spin" -version = "0.5.2" +name = "shlex" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "sinsemilla" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d268ae0ea06faafe1662e9967cd4f9022014f5eeb798e0c302c876df8b7af9c" +dependencies = [ + "group", + "pasta_curves", + "subtle", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "static_assertions" @@ -1537,9 +1491,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "subtle" -version = "2.4.1" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -1554,9 +1508,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.32" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -1571,43 +1525,42 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.6.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ - "autocfg", "cfg-if", "fastrand", - "redox_syscall", + "once_cell", "rustix", "windows-sys", ] [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] name = "time" -version = "0.3.34" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "num-conv", @@ -1624,9 +1577,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -1648,24 +1601,24 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.10.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d021fc044c18582b9a2408cd0dd05b1596e3ecdb5c4df822bb0183545683889" +checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11" dependencies = [ "prettyplease", "proc-macro2", "prost-build", + "prost-types", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ - "cfg-if", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1673,29 +1626,29 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.24" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "uint" @@ -1711,40 +1664,95 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "universal-hash" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common", "subtle", ] [[package]] -name = "untrusted" -version = "0.7.1" +name = "version_check" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] -name = "version_check" -version = "0.9.4" +name = "visibility" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "wagyu-zcash-parameters" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c904628658374e651288f000934c33ef738b2d8b3e65d4100b70b395dbe2bb" +dependencies = [ + "wagyu-zcash-parameters-1", + "wagyu-zcash-parameters-2", + "wagyu-zcash-parameters-3", + "wagyu-zcash-parameters-4", + "wagyu-zcash-parameters-5", + "wagyu-zcash-parameters-6", +] + +[[package]] +name = "wagyu-zcash-parameters-1" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bf2e21bb027d3f8428c60d6a720b54a08bf6ce4e6f834ef8e0d38bb5695da8" + +[[package]] +name = "wagyu-zcash-parameters-2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a616ab2e51e74cc48995d476e94de810fb16fc73815f390bf2941b046cc9ba2c" + +[[package]] +name = "wagyu-zcash-parameters-3" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14da1e2e958ff93c0830ee68e91884069253bf3462a67831b02b367be75d6147" + +[[package]] +name = "wagyu-zcash-parameters-4" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f058aeef03a2070e8666ffb5d1057d8bb10313b204a254a6e6103eb958e9a6d6" + +[[package]] +name = "wagyu-zcash-parameters-5" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ffe916b30e608c032ae1b734f02574a3e12ec19ab5cc5562208d679efe4969d" + +[[package]] +name = "wagyu-zcash-parameters-6" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7b6d5a78adc3e8f198e9cd730f219a695431467f7ec29dcfc63ade885feebe1" [[package]] name = "wasi" @@ -1752,121 +1760,37 @@ 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.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.32", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.32", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "web-sys" -version = "0.3.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "which" -version = "4.4.0" +version = "6.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f" dependencies = [ "either", - "libc", - "once_cell", + "home", + "rustix", + "winsafe", ] -[[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" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", + "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", @@ -1875,45 +1799,57 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winsafe" +version = "0.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" [[package]] name = "wyz" @@ -1926,11 +1862,11 @@ dependencies = [ [[package]] name = "zcash_address" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804268e702b664fc09d3e2ce82786d0addf4ae57ba6976469be63e09066bf9f7" +checksum = "52be35a205369d480378646bff9c9fedafd8efe8af1e0e54bb858f405883f2b2" dependencies = [ - "bech32 0.8.1", + "bech32 0.9.1", "bs58 0.4.0", "f4jumble", "zcash_encoding", @@ -1938,26 +1874,28 @@ dependencies = [ [[package]] name = "zcash_address" -version = "0.3.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bce173f1d9ed4f806e310bc3a873301531e7a6dc209928584d6404e3f8228ef4" +checksum = "9b955fe87f2d9052e3729bdbeb0e94975355f4fe39f7d26aea9457bec6a0bb55" dependencies = [ - "bech32 0.9.1", - "bs58 0.5.0", + "bech32 0.11.0", + "bs58 0.5.1", + "core2", "f4jumble", "zcash_encoding", + "zcash_protocol", ] [[package]] name = "zcash_client_backend" -version = "0.11.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "001ec65dc2828ee648dc6d29f0944d7a877fe68ad06e001a203c11770ab1b3d4" +checksum = "c2a187ad05cdfe13707c07e6aedca8026b34921d081decfd0b43aac1efd438a7" dependencies = [ "base64", - "bech32 0.9.1", + "bech32 0.11.0", "bls12_381", - "bs58 0.5.0", + "bs58 0.5.1", "crossbeam-channel", "document-features", "group", @@ -1978,52 +1916,58 @@ dependencies = [ "tonic-build", "tracing", "which", - "zcash_address 0.3.1", + "zcash_address 0.6.2", "zcash_encoding", "zcash_keys", "zcash_note_encryption", "zcash_primitives", + "zcash_protocol", "zip32", + "zip321", ] [[package]] name = "zcash_encoding" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03391b81727875efa6ac0661a20883022b6fba92365dc121c48fa9b00c5aac0" +checksum = "3654116ae23ab67dd1f849b01f8821a8a156f884807ff665eac109bf28306c4d" dependencies = [ - "byteorder", + "core2", "nonempty", ] [[package]] name = "zcash_keys" -version = "0.1.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f22d3407fdd6992b49f037f23862ab376be6013be6f2d0bc85948a635edc1f5" +checksum = "6ad3cf576c6e6094cd03f446fcb83ad241ec315a088593cd50940f135cb03ce1" dependencies = [ - "bech32 0.9.1", + "bech32 0.11.0", + "blake2b_simd", "bls12_381", - "bs58 0.5.0", + "bs58 0.5.1", + "core2", "document-features", "group", "memuse", "nonempty", "rand_core", "sapling-crypto", + "secrecy", "subtle", "tracing", - "zcash_address 0.3.1", + "zcash_address 0.6.2", "zcash_encoding", - "zcash_primitives", + "zcash_protocol", + "zcash_transparent", "zip32", ] [[package]] name = "zcash_note_encryption" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b4580cd6cee12e44421dac43169be8d23791650816bdb34e6ddfa70ac89c1c5" +checksum = "77efec759c3798b6e4d829fcc762070d9b229b0f13338c40bf993b7b609c2272" dependencies = [ "chacha20", "chacha20poly1305", @@ -2034,20 +1978,21 @@ dependencies = [ [[package]] name = "zcash_primitives" -version = "0.14.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9070e084570bb78aed4f8d71fd6254492e62c87a5d01e084183980e98117092d" +checksum = "9b45f3ca3a9df34fcdbf036c2c814417bb417bde742812abc09d744bb3d7ed72" dependencies = [ "aes", - "bip0039", + "bip32", "blake2b_simd", + "bs58 0.5.1", "byteorder", "document-features", "equihash", "ff", "fpe", + "getset", "group", - "hdwallet", "hex", "incrementalmerkletree", "jubjub", @@ -2060,30 +2005,88 @@ dependencies = [ "ripemd", "sapling-crypto", "secp256k1", - "sha2 0.10.6", + "sha2 0.10.8", "subtle", "tracing", - "zcash_address 0.3.1", + "zcash_address 0.6.2", "zcash_encoding", "zcash_note_encryption", + "zcash_protocol", "zcash_spec", + "zcash_transparent", "zip32", ] [[package]] -name = "zcash_spec" -version = "0.1.0" +name = "zcash_protocol" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7a3bf58b673cb3dacd8ae09ba345998923a197ab0da70d6239d8e8838949e9b" +checksum = "82cb36b15b5a1be70b30c32ce40372dead6561df8a467e297f96b892873a63a2" +dependencies = [ + "core2", + "document-features", + "hex", + "memuse", +] + +[[package]] +name = "zcash_spec" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cede95491c2191d3e278cab76e097a44b17fde8d6ca0d4e3a22cf4807b2d857" dependencies = [ "blake2b_simd", ] [[package]] -name = "zeroize" -version = "1.6.0" +name = "zcash_transparent" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ed0512e8e02af804e852fbbc4bd5db35a9037bc253d2ce396506293a6e7dd745" +dependencies = [ + "bip32", + "blake2b_simd", + "bs58 0.5.1", + "core2", + "getset", + "hex", + "ripemd", + "secp256k1", + "sha2 0.10.8", + "subtle", + "zcash_address 0.6.2", + "zcash_encoding", + "zcash_protocol", + "zcash_spec", + "zip32", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -2096,16 +2099,30 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] name = "zip32" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4226d0aee9c9407c27064dfeec9d7b281c917de3374e1e5a2e2cfad9e09de19e" +checksum = "2e9943793abf9060b68e1889012dafbd5523ab5b125c0fcc24802d69182f2ac9" dependencies = [ "blake2b_simd", "memuse", "subtle", + "zcash_spec", +] + +[[package]] +name = "zip321" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3e613defb0940acef1f54774b51c7f48f2fa705613dd800870dc69f35cd2ea" +dependencies = [ + "base64", + "nom", + "percent-encoding", + "zcash_address 0.6.2", + "zcash_protocol", ] diff --git a/librustzcash-wrapper/Cargo.toml b/librustzcash-wrapper/Cargo.toml index b8b2b37..900fd1a 100644 --- a/librustzcash-wrapper/Cargo.toml +++ b/librustzcash-wrapper/Cargo.toml @@ -9,20 +9,23 @@ haskell-ffi.git = "https://github.com/BeFunctional/haskell-rust-ffi.git" haskell-ffi.rev = "2bf292e2e56eac8e9fb0fb2e1450cf4a4bd01274" f4jumble = "0.1" zcash_address = "0.2.0" -borsh = "0.10" +borsh = "0.9" bech32 = "0.11" -orchard = "0.7.1" +orchard = "0.10.0" zcash_note_encryption = "0.4.0" -zcash_primitives = { version = "0.14.0", features = ["transparent-inputs"]} -zcash_client_backend = "0.11.1" -sapling-crypto = "0.1.3" -zip32 = "0.1.0" +zcash_primitives = { version = "0.21.0", features = ["transparent-inputs"]} +zcash_client_backend = "0.16.0" +sapling-crypto = "0.4" +zip32 = "0.1.2" proc-macro2 = "1.0.66" nonempty = "0.7.0" -incrementalmerkletree = "0.5.0" -secp256k1 = "0.26.0" +incrementalmerkletree = "0.7.0" +secp256k1 = "0.27.0" jubjub = "0.10.0" rand_core = { version = "0.6.4", features = ["getrandom"]} +wagyu-zcash-parameters = "0.2.0" +bip0039 = "0.12.0" +ahash = "0.7.8" [features] diff --git a/librustzcash-wrapper/rust-toolchain.toml b/librustzcash-wrapper/rust-toolchain.toml index af255e0..7c4fd88 100644 --- a/librustzcash-wrapper/rust-toolchain.toml +++ b/librustzcash-wrapper/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2024-02-04" +channel = "nightly" components = [ "rustfmt", "rustc-dev"] profile = "minimal" diff --git a/librustzcash-wrapper/src/lib.rs b/librustzcash-wrapper/src/lib.rs index 7397401..025b49b 100644 --- a/librustzcash-wrapper/src/lib.rs +++ b/librustzcash-wrapper/src/lib.rs @@ -20,9 +20,9 @@ use borsh::{BorshDeserialize, BorshSerialize}; use haskell_ffi::{ error::Result, - from_haskell::{marshall_from_haskell_var, marshall_from_haskell_fixed}, - to_haskell::{marshall_to_haskell_var, marshall_to_haskell_fixed}, - FromHaskell, HaskellSize, ToHaskell + from_haskell::marshall_from_haskell_var, + to_haskell::marshall_to_haskell_var, + FromHaskell, ToHaskell }; use secp256k1::SecretKey; @@ -30,13 +30,20 @@ use secp256k1::SecretKey; use jubjub::Fr; use incrementalmerkletree::{ - frontier::CommitmentTree, + Hashable, + Level, + Position, + frontier::{ + CommitmentTree, + Frontier, + NonEmptyFrontier, + PathFiller + }, witness::IncrementalWitness }; use zip32::{ - Scope as SaplingScope, - ChildIndex + Scope as SaplingScope }; @@ -79,18 +86,21 @@ use sapling_crypto::{ } }; +use bip0039::{Count, Mnemonic, English}; + use zcash_primitives::{ merkle_tree::{ read_commitment_tree, write_commitment_tree, read_incremental_witness, - write_incremental_witness + write_incremental_witness, + read_frontier_v1, + read_nonempty_frontier_v1 }, legacy::{ Script, TransparentAddress }, - zip339::{Count, Mnemonic}, transaction::{ Transaction, fees::zip317::FeeRule, @@ -106,6 +116,7 @@ use zcash_primitives::{ }, transparent::{ Bundle as TransparentBundle, + builder::TransparentSigningSet, TxIn, TxOut, OutPoint, @@ -124,7 +135,7 @@ use zcash_primitives::{ use zcash_address::{ Network, - unified::{Address, Encoding, Ufvk, Container, Fvk, Receiver}, + unified::{Address, Encoding, Ufvk, Uivk, Ivk, Container, Fvk, Receiver}, ZcashAddress }; @@ -146,8 +157,8 @@ use orchard::{ Flags }, Action, - keys::{SpendingKey, FullViewingKey, PreparedIncomingViewingKey, Scope}, - note::{RandomSeed, Note, Nullifier, TransmittedNoteCiphertext, ExtractedNoteCommitment}, + keys::{SpendAuthorizingKey, SpendingKey, FullViewingKey, PreparedIncomingViewingKey, Scope}, + note::{Rho, RandomSeed, Note, Nullifier, TransmittedNoteCiphertext, ExtractedNoteCommitment}, note_encryption::OrchardDomain, primitives::redpallas::{VerificationKey, SpendAuth, Signature}, tree::{ @@ -167,6 +178,8 @@ use bech32::{ Bech32m }; +use wagyu_zcash_parameters::load_sapling_parameters; + pub enum RW {} pub const RW: PhantomData = PhantomData; @@ -260,6 +273,12 @@ impl ToHaskell for Hhex { } } +impl FromHaskell for Hhex { + fn from_haskell(buf: &mut &[u8], _tag: PhantomData) -> Result { + let x = Hhex::deserialize(buf)?; + Ok(x) + } +} #[derive(Debug, BorshSerialize, BorshDeserialize)] pub struct Haction { @@ -552,11 +571,11 @@ impl Hspend { } } -#[derive(Debug, BorshSerialize, BorshDeserialize)] +#[derive(BorshSerialize, BorshDeserialize)] pub struct HsaplingInput { sk: Vec, note: Hnote, - iw: Vec + iw: Hpath } impl FromHaskell for HsaplingInput { @@ -567,11 +586,11 @@ impl FromHaskell for HsaplingInput { } -#[derive(Debug, BorshSerialize, BorshDeserialize)] +#[derive(BorshSerialize, BorshDeserialize)] pub struct HorchardInput { sk: Vec, note: Hnote, - iw: Vec + iw: Hpath } impl FromHaskell for HorchardInput { @@ -671,6 +690,35 @@ impl Hufvk { } } +#[derive(Debug, BorshSerialize, BorshDeserialize)] +pub struct Huivk { + net: u8, + orchard: Vec, + sapling: Vec, + transparent: Vec +} + +impl ToHaskell for Huivk { + fn to_haskell(&self, writer: &mut W, _tag: PhantomData) -> Result<()> { + self.serialize(writer)?; + Ok(()) + } +} + +impl Huivk { + fn add_key_section(&mut self, ivk: &Ivk) { + if let Ivk::Orchard(v) = ivk { + self.orchard = v.to_vec(); + } + if let Ivk::Sapling(w) = ivk { + self.sapling = w.to_vec(); + } + if let Ivk::P2pkh(x) = ivk { + self.transparent = x.to_vec(); + } + } +} + #[derive(Debug, BorshSerialize, BorshDeserialize)] pub struct Hsvk { vk: Vec, @@ -684,6 +732,68 @@ impl ToHaskell for Hsvk { } } +#[derive(BorshSerialize, BorshDeserialize)] +pub struct Hfrontier { + position: u64, + leaf: Hhex, + ommers: Vec +} + +impl ToHaskell for Hfrontier { + fn to_haskell(&self, writer: &mut W, _tag: PhantomData) -> Result<()> { + self.serialize(writer)?; + Ok(()) + } +} + +impl FromHaskell for Hfrontier { + fn from_haskell(buf: &mut &[u8], _tag: PhantomData) -> Result { + let x = Hfrontier::deserialize(buf)?; + Ok(x) + } +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct Htree { + left: Hhex, + right: Hhex, + parents: Vec +} + +impl ToHaskell for Htree { + fn to_haskell(&self, writer: &mut W, _tag: PhantomData) -> Result<()> { + self.serialize(writer)?; + Ok(()) + } +} + +impl FromHaskell for Htree { + fn from_haskell(buf: &mut &[u8], _tag: PhantomData) -> Result { + let x = Htree::deserialize(buf)?; + Ok(x) + } +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct Hpath { + position: u32, + path: Vec +} + +impl ToHaskell for Hpath { + fn to_haskell(&self, writer: &mut W, _tag: PhantomData) -> Result<()> { + self.serialize(writer)?; + Ok(()) + } +} + +impl FromHaskell for Hpath { + fn from_haskell(buf: &mut &[u8], _tag: PhantomData) -> Result { + let x = Hpath::deserialize(buf)?; + Ok(x) + } +} + 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())) } @@ -887,6 +997,34 @@ pub extern "C" fn rust_wrapper_ufvk_decode( } } +#[no_mangle] +pub extern "C" fn rust_wrapper_uivk_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 = Uivk::decode(&input); + match dec_key { + Ok((n, uivk)) => { + let x = match n { + Network::Main => 1, + Network::Test => 2, + Network::Regtest => 3 + }; + let mut hk = Huivk { net: x, orchard: vec![0], sapling: vec![0], transparent: vec![0] }; + let ivks = uivk.items(); + ivks.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_esk_decrypt( key: *const u8, @@ -1024,7 +1162,7 @@ pub extern "C" fn rust_wrapper_orchard_note_decrypt( ValueCommitment::from_bytes(&to_array(note_input.cv.bytes)).unwrap(), Signature::from(to_array(note_input.auth.bytes))); let fvk_array = to_array(fvk_input); - let domain = OrchardDomain::for_nullifier(*action.nullifier()); + let domain = OrchardDomain::for_action(&action); let dec_fvk = FullViewingKey::from_bytes(&fvk_array); match dec_fvk { Some(fvk) => { @@ -1071,7 +1209,7 @@ pub extern "C" fn rust_wrapper_orchard_note_decrypt_sk( ValueCommitment::from_bytes(&to_array(note_input.cv.bytes)).unwrap(), Signature::from(to_array(note_input.auth.bytes))); let sk_array = to_array(sk_input); - let domain = OrchardDomain::for_nullifier(*action.nullifier()); + let domain = OrchardDomain::for_action(&action); let dec_sk = SpendingKey::from_bytes(sk_array).unwrap(); let fvk = FullViewingKey::from(&dec_sk); let ivk = if external { @@ -1184,7 +1322,7 @@ pub extern "C" fn rust_wrapper_gen_seed_phrase( out: *mut u8, out_len: &mut usize ){ - let mnemonic = Mnemonic::generate(Count::Words24); + let mnemonic: Mnemonic = Mnemonic::generate(Count::Words24); let seed = mnemonic.phrase().as_bytes().to_vec(); marshall_to_haskell_var(&seed, out, out_len, RW); } @@ -1197,7 +1335,7 @@ pub extern "C" fn rust_wrapper_recover_seed( out_len: &mut usize ){ let phrase: String = marshall_from_haskell_var(input, input_len, RW); - let mnemonic = Mnemonic::from_phrase(phrase); + let mnemonic = >::from_phrase(phrase); match mnemonic { Ok(m) => { let s = m.to_seed("").to_vec(); @@ -1339,6 +1477,31 @@ pub extern "C" fn rust_wrapper_bech32_encode( marshall_to_haskell_var(&string, out, out_len, RW); } +#[no_mangle] +pub extern "C" fn rust_wrapper_read_sapling_frontier( + tree: *const u8, + tree_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let tree_in: Vec = marshall_from_haskell_var(tree, tree_len, RW); + let tree_reader = Cursor::new(tree_in); + let comm_tree: CommitmentTree = read_commitment_tree(tree_reader).unwrap(); + //let comm_tree: Frontier = read_frontier_v1(tree_reader).unwrap(); + let frontier: Frontier = comm_tree.to_frontier(); + match frontier.value() { + Some(f1) => { + let (pos, leaf, omm) = f1.clone().into_parts(); + let f = Hfrontier { position: ::from(pos), leaf: Hhex { bytes: leaf.to_bytes().to_vec()}, ommers: omm.iter().map(|&x| Hhex { bytes: x.to_bytes().to_vec()}).collect()}; + marshall_to_haskell_var(&f, out, out_len, RW); + }, + None => { + let f0 = Hfrontier { position: 0, leaf: Hhex { bytes: vec![0]}, ommers: vec![Hhex { bytes: vec![0]}]}; + marshall_to_haskell_var(&f0, out, out_len, RW); + } + } +} + #[no_mangle] pub extern "C" fn rust_wrapper_read_sapling_commitment_tree( tree: *const u8, @@ -1348,39 +1511,21 @@ pub extern "C" fn rust_wrapper_read_sapling_commitment_tree( out: *mut u8, out_len: &mut usize ){ - let tree_in: Vec = marshall_from_haskell_var(tree, tree_len, RW); - let tree_reader = Cursor::new(tree_in); - let mut ct = read_commitment_tree::>, SAPLING_DEPTH>(tree_reader); - match ct { - Ok(mut comm_tree) => { - let node_in: Vec = marshall_from_haskell_var(node, node_len, RW); - let sap_note_comm = SaplingNoteCommitment::from_bytes(&to_array(node_in)); - if sap_note_comm.is_some().into() { - let n = Node::from_cmu(&sap_note_comm.unwrap()); - comm_tree.append(n); - let mut out_bytes: Vec = Vec::new(); - let result = write_commitment_tree(&comm_tree, &mut out_bytes ); - match result { - Ok(()) => { - let h = Hhex { bytes: out_bytes}; - marshall_to_haskell_var(&h, out, out_len, RW); - }, - Err(_e) => { - let h0 = Hhex { bytes: vec![0]}; - marshall_to_haskell_var(&h0, out, out_len, RW); - } - } - } else { - let h0 = Hhex { bytes: vec![0]}; - marshall_to_haskell_var(&h0, out, out_len, RW); - } - }, - Err(_e) => { - let h0 = Hhex { bytes: vec![0]}; - marshall_to_haskell_var(&h0, out, out_len, RW); - } + let tree_in: Hfrontier = marshall_from_haskell_var(tree, tree_len, RW); + let leaf = Node::from_bytes(to_array(tree_in.leaf.bytes)).unwrap(); + let mut comm_tree = NonEmptyFrontier::from_parts(Position::from(tree_in.position), leaf, tree_in.ommers.iter().map(|x| Node::from_bytes(to_array(x.bytes.clone())).unwrap() ).collect()).unwrap(); + let node_in: Vec = marshall_from_haskell_var(node, node_len, RW); + let sap_note_comm = SaplingNoteCommitment::from_bytes(&to_array(node_in)); + if sap_note_comm.is_some().into() { + let n = Node::from_cmu(&sap_note_comm.unwrap()); + comm_tree.append(n); + let (pos, leaf, omm) = comm_tree.into_parts(); + let f = Hfrontier { position: ::from(pos), leaf: Hhex { bytes: leaf.to_bytes().to_vec()}, ommers: omm.iter().map(|&x| Hhex { bytes: x.to_bytes().to_vec()}).collect()}; + marshall_to_haskell_var(&f, out, out_len, RW); + } else { + let f0 = Hfrontier { position: 0, leaf: Hhex { bytes: vec![0]}, ommers: vec![Hhex { bytes: vec![0]}]}; + marshall_to_haskell_var(&f0, out, out_len, RW); } - } #[no_mangle] @@ -1390,9 +1535,10 @@ pub extern "C" fn rust_wrapper_read_sapling_witness( out: *mut u8, out_len: &mut usize ){ - let tree_in: Vec = marshall_from_haskell_var(tree, tree_len, RW); - let tree_reader = Cursor::new(tree_in); - let ct: CommitmentTree = read_commitment_tree(tree_reader).unwrap(); + let tree_in: Hfrontier = marshall_from_haskell_var(tree, tree_len, RW); + let leaf = Node::from_bytes(to_array(tree_in.leaf.bytes)).unwrap(); + let frontier: Frontier = Frontier::from_parts(Position::from(tree_in.position), leaf, tree_in.ommers.iter().map(|x| Node::from_bytes(to_array(x.bytes.clone())).unwrap() ).collect()).unwrap(); + let ct: CommitmentTree = CommitmentTree::from_frontier(&frontier); let inc_wit = IncrementalWitness::from_tree(ct); let mut out_bytes: Vec = Vec::new(); let result = write_incremental_witness(&inc_wit, &mut out_bytes); @@ -1454,6 +1600,438 @@ pub extern "C" fn rust_wrapper_update_sapling_witness( } } +#[no_mangle] +pub extern "C" fn rust_wrapper_read_sapling_node( + cmu: *const u8, + cmu_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let node_in: Vec = marshall_from_haskell_var(cmu, cmu_len, RW); + let sapling_note_comm = SaplingNoteCommitment::from_bytes(&to_array(node_in)); + if sapling_note_comm.is_some().into() { + let n = Node::from_cmu(&sapling_note_comm.unwrap()); + let h = Hhex { bytes: n.to_bytes().to_vec()}; + marshall_to_haskell_var(&h, out, out_len, RW); + } else { + let h0 = Hhex { bytes: vec![0] }; + marshall_to_haskell_var(&h0, out, out_len, RW); + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_combine_sapling_nodes( + level: u8, + left: *const u8, + left_len: usize, + right: *const u8, + right_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let left_in: Vec = marshall_from_haskell_var(left, left_len, RW); + let right_in: Vec = marshall_from_haskell_var(right, right_len, RW); + if left_in.len() == 1 { + let n = Node::combine(Level::new(level), &Node::empty_leaf(), &Node::empty_leaf()); + let h = Hhex { bytes: n.to_bytes().to_vec() }; + marshall_to_haskell_var(&h, out, out_len, RW); + } else { + let left_node = Node::from_bytes(to_array(left_in)); + if left_node.is_some().into() { + if right_in.len() > 1 { + let right_node = Node::from_bytes(to_array(right_in)); + if right_node.is_some().into() { + let n = Node::combine(Level::new(level), &left_node.unwrap(), &right_node.unwrap()); + let h = Hhex { bytes: n.to_bytes().to_vec() }; + marshall_to_haskell_var(&h, out, out_len, RW); + } else { + let h0 = Hhex { bytes: vec![0] }; + marshall_to_haskell_var(&h0, out, out_len, RW); + } + } else { + let n = Node::combine(Level::new(level), &left_node.unwrap(), &Node::empty_leaf()); + let h = Hhex { bytes: n.to_bytes().to_vec() }; + marshall_to_haskell_var(&h, out, out_len, RW); + } + } else { + let h0 = Hhex { bytes: vec![0] }; + marshall_to_haskell_var(&h0, out, out_len, RW); + } + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_get_sapling_root( + level: u8, + out: *mut u8, + out_len: &mut usize + ){ + let tree: CommitmentTree = CommitmentTree::empty(); + let root = tree.root(); + let h = Hhex { bytes: root.to_bytes().to_vec() }; + marshall_to_haskell_var(&h, out, out_len, RW); +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_read_sapling_commitment_tree_parts( + tree: *const u8, + tree_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let tree_in: Vec = marshall_from_haskell_var(tree, tree_len, RW); + let tree_reader = Cursor::new(tree_in); + let comm_tree = read_commitment_tree(tree_reader); + match comm_tree { + Ok::, _>(c1) => { + let left = match c1.left() { + Some(x) => { + Hhex { bytes: x.to_bytes().to_vec() } + }, + None => { + Hhex { bytes: vec![0] } + } + }; + let right = match c1.right() { + Some(x) => { + Hhex { bytes: x.to_bytes().to_vec() } + }, + None => { + Hhex { bytes: vec![0] } + } + }; + let parents = c1.parents().iter().map(|x| match x { + Some(y) => { + Hhex { bytes: y.to_bytes().to_vec() } + }, + None => { + Hhex { bytes: vec![0] } + } + }).collect(); + let ht = Htree { left, right, parents}; + marshall_to_haskell_var(&ht, out, out_len, RW); + }, + Err(_e) => { + let ht0 = Htree { left: Hhex { bytes: vec![0] } , right: Hhex { bytes: vec![0] }, parents: vec![Hhex { bytes: vec![0] }]}; + marshall_to_haskell_var(&ht0, out, out_len, RW); + } + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_read_sapling_tree_anchor( + tree: *const u8, + tree_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let tree_in: Vec = marshall_from_haskell_var(tree, tree_len, RW); + let tree_reader = Cursor::new(tree_in); + let comm_tree = read_commitment_tree(tree_reader); + match comm_tree { + Ok::, _>(c1) => { + let root = c1.root(); + let h = Hhex { bytes: root.to_bytes().to_vec() }; + marshall_to_haskell_var(&h, out, out_len, RW); + }, + Err(_) => { + let h0 = Hhex { bytes: vec![0] }; + marshall_to_haskell_var(&h0, out, out_len, RW); + } + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_read_sapling_path_anchor( + path: *const u8, + path_len: usize, + cmx: *const u8, + cmx_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let path_in: Hpath = marshall_from_haskell_var(path, path_len, RW); + let cmx_in: Vec = marshall_from_haskell_var(cmx, cmx_len, RW); + let mk_path = sapling_crypto::MerklePath::from_parts(path_in.path.iter().map(|x| + if x.bytes.len() > 1 { + Node::from_bytes(to_array(x.bytes.clone())).unwrap() + } else { + Node::empty_leaf() + }).collect(), Position::from(u64::from(path_in.position))); + match mk_path { + Ok(mp1) => { + let nc = SaplingNoteCommitment::from_bytes(&to_array(cmx_in)); + if nc.is_some().into() { + let anchor = mp1.root(Node::from_cmu(&nc.unwrap())); + let h = Hhex { bytes: anchor.to_bytes().to_vec() }; + marshall_to_haskell_var(&h, out, out_len, RW); + } else { + let h0 = Hhex { bytes: vec![0] }; + marshall_to_haskell_var(&h0, out, out_len, RW); + } + }, + Err(_e) =>{ + let h0 = Hhex { bytes: vec![0] }; + marshall_to_haskell_var(&h0, out, out_len, RW); + } + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_read_orchard_frontier( + tree: *const u8, + tree_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let tree_in: Vec = marshall_from_haskell_var(tree, tree_len, RW); + let tree_reader = Cursor::new(tree_in); + let comm_tree = read_commitment_tree(tree_reader); + //let comm_tree = read_frontier_v1(tree_reader); + //let frontier: Frontier = comm_tree.to_frontier(); + match comm_tree { + Ok::, _>(f1) => { + let frontier = f1.to_frontier(); + match frontier.value() { + Some(f2) => { + let (pos, leaf, omm) = f2.clone().into_parts(); + let f = Hfrontier { position: ::from(pos), leaf: Hhex { bytes: leaf.to_bytes().to_vec()}, ommers: omm.iter().map(|&x| Hhex { bytes: x.to_bytes().to_vec()}).collect()}; + let comm_tree2: Frontier = Frontier::from_parts(Position::from(f.position), MerkleHashOrchard::from_bytes(&to_array(f.leaf.bytes.clone())).unwrap(), f.ommers.iter().map(|x| MerkleHashOrchard::from_bytes(&to_array(x.bytes.clone())).unwrap() ).collect()).unwrap(); + if f1.root() == comm_tree2.root() { + marshall_to_haskell_var(&f, out, out_len, RW); + } else { + let f0 = Hfrontier { position: 0, leaf: Hhex { bytes: vec![0]}, ommers: vec![Hhex { bytes: vec![0]}]}; + marshall_to_haskell_var(&f0, out, out_len, RW); + } + }, + None => { + let f0 = Hfrontier { position: 0, leaf: Hhex { bytes: vec![0]}, ommers: vec![Hhex { bytes: vec![0]}]}; + marshall_to_haskell_var(&f0, out, out_len, RW); + } + } + }, + Err(_e) => { + let f0 = Hfrontier { position: 0, leaf: Hhex { bytes: vec![0]}, ommers: vec![Hhex { bytes: vec![0]}]}; + marshall_to_haskell_var(&f0, out, out_len, RW); + } + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_read_orchard_tree_anchor( + tree: *const u8, + tree_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let tree_in: Vec = marshall_from_haskell_var(tree, tree_len, RW); + let tree_reader = Cursor::new(tree_in); + let comm_tree = read_commitment_tree(tree_reader); + match comm_tree { + Ok::, _>(c1) => { + let root = c1.root(); + let h = Hhex { bytes: root.to_bytes().to_vec() }; + marshall_to_haskell_var(&h, out, out_len, RW); + }, + Err(_) => { + let h0 = Hhex { bytes: vec![0] }; + marshall_to_haskell_var(&h0, out, out_len, RW); + } + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_read_orchard_commitment_tree_parts( + tree: *const u8, + tree_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let tree_in: Vec = marshall_from_haskell_var(tree, tree_len, RW); + let tree_reader = Cursor::new(tree_in); + let comm_tree = read_commitment_tree(tree_reader); + match comm_tree { + Ok::, _>(c1) => { + let left = match c1.left() { + Some(x) => { + Hhex { bytes: x.to_bytes().to_vec() } + }, + None => { + Hhex { bytes: vec![0] } + } + }; + let right = match c1.right() { + Some(x) => { + Hhex { bytes: x.to_bytes().to_vec() } + }, + None => { + Hhex { bytes: vec![0] } + } + }; + let parents = c1.parents().iter().map(|x| match x { + Some(y) => { + Hhex { bytes: y.to_bytes().to_vec() } + }, + None => { + Hhex { bytes: vec![0] } + } + }).collect(); + let ht = Htree { left, right, parents}; + marshall_to_haskell_var(&ht, out, out_len, RW); + }, + Err(_e) => { + let ht0 = Htree { left: Hhex { bytes: vec![0] } , right: Hhex { bytes: vec![0] }, parents: vec![Hhex { bytes: vec![0] }]}; + marshall_to_haskell_var(&ht0, out, out_len, RW); + } + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_read_orchard_witness_anchor( + wit: *const u8, + wit_len: usize, + out: *mut u8, + out_len: &mut usize + ) { + let wit_in: Vec = marshall_from_haskell_var(wit, wit_len, RW); + let wit_reader = Cursor::new(wit_in); + let iw: IncrementalWitness = read_incremental_witness(wit_reader).unwrap(); + let root = iw.root(); + let h = Hhex { bytes: root.to_bytes().to_vec() }; + marshall_to_haskell_var(&h, out, out_len, RW); +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_read_orchard_node( + cmx: *const u8, + cmx_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let node_in: Vec = marshall_from_haskell_var(cmx, cmx_len, RW); + let orchard_note_comm = ExtractedNoteCommitment::from_bytes(&to_array(node_in)); + if orchard_note_comm.is_some().into() { + let n = MerkleHashOrchard::from_cmx(&orchard_note_comm.unwrap()); + let h = Hhex { bytes: n.to_bytes().to_vec()}; + marshall_to_haskell_var(&h, out, out_len, RW); + } else { + let h0 = Hhex { bytes: vec![0] }; + marshall_to_haskell_var(&h0, out, out_len, RW); + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_read_orchard_path_anchor( + path: *const u8, + path_len: usize, + cmx: *const u8, + cmx_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let path_in: Hpath = marshall_from_haskell_var(path, path_len, RW); + let cmx_in: Vec = marshall_from_haskell_var(cmx, cmx_len, RW); + let mk_path = orchard::tree::MerklePath::from_parts(path_in.position, to_array(path_in.path.iter().map(|x| + if x.bytes.len() > 1 { + MerkleHashOrchard::from_bytes(&to_array(x.bytes.clone())).unwrap() + } else { + MerkleHashOrchard::empty_leaf() + } + ).collect())); + let nc = ExtractedNoteCommitment::from_bytes(&to_array(cmx_in)); + if nc.is_some().into() { + let anchor = mk_path.root(nc.unwrap()); + let h = Hhex { bytes: anchor.to_bytes().to_vec() }; + marshall_to_haskell_var(&h, out, out_len, RW); + } else { + let h0 = Hhex { bytes: vec![0] }; + marshall_to_haskell_var(&h0, out, out_len, RW); + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_combine_orchard_nodes( + level: u8, + left: *const u8, + left_len: usize, + right: *const u8, + right_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let left_in: Vec = marshall_from_haskell_var(left, left_len, RW); + let right_in: Vec = marshall_from_haskell_var(right, right_len, RW); + if left_in.len() == 1 { + let n = MerkleHashOrchard::combine(Level::new(level), &MerkleHashOrchard::empty_leaf(), &MerkleHashOrchard::empty_leaf()); + let h = Hhex { bytes: n.to_bytes().to_vec() }; + marshall_to_haskell_var(&h, out, out_len, RW); + } else { + let left_node = MerkleHashOrchard::from_bytes(&to_array(left_in)); + if left_node.is_some().into() { + if right_in.len() > 1 { + let right_node = MerkleHashOrchard::from_bytes(&to_array(right_in)); + if right_node.is_some().into() { + let n = MerkleHashOrchard::combine(Level::new(level), &left_node.unwrap(), &right_node.unwrap()); + let h = Hhex { bytes: n.to_bytes().to_vec() }; + marshall_to_haskell_var(&h, out, out_len, RW); + } else { + let h0 = Hhex { bytes: vec![0] }; + marshall_to_haskell_var(&h0, out, out_len, RW); + } + } else { + let n = MerkleHashOrchard::combine(Level::new(level), &left_node.unwrap(), &MerkleHashOrchard::empty_leaf()); + let h = Hhex { bytes: n.to_bytes().to_vec() }; + marshall_to_haskell_var(&h, out, out_len, RW); + } + } else { + let h0 = Hhex { bytes: vec![0] }; + marshall_to_haskell_var(&h0, out, out_len, RW); + } + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_get_orchard_root( + level: u8, + out: *mut u8, + out_len: &mut usize + ){ + let tree: CommitmentTree = CommitmentTree::empty(); + let root = tree.root(); + let h = Hhex { bytes: root.to_bytes().to_vec() }; + marshall_to_haskell_var(&h, out, out_len, RW); +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_orchard_add_node( + level: u8, + node: *const u8, + node_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let mut tree: CommitmentTree = CommitmentTree::empty(); + let node_in: Vec = marshall_from_haskell_var(node, node_len, RW); + let orchard_note_comm = ExtractedNoteCommitment::from_bytes(&to_array(node_in)); + if orchard_note_comm.is_some().into() { + let n = MerkleHashOrchard::from_cmx(&orchard_note_comm.unwrap()); + match tree.append(n) { + Ok(()) => { + let root = tree.root_at_depth(level, PathFiller::empty()); + let h = Hhex { bytes: root.to_bytes().to_vec() }; + marshall_to_haskell_var(&h, out, out_len, RW); + }, + Err(_) => { + let h0 = Hhex { bytes: vec![0] }; + marshall_to_haskell_var(&h0, out, out_len, RW); + } + } + } else { + let h0 = Hhex { bytes: vec![0] }; + marshall_to_haskell_var(&h0, out, out_len, RW); + } +} + #[no_mangle] pub extern "C" fn rust_wrapper_read_orchard_commitment_tree( tree: *const u8, @@ -1463,37 +2041,23 @@ pub extern "C" fn rust_wrapper_read_orchard_commitment_tree( out: *mut u8, out_len: &mut usize ){ - let tree_in: Vec = marshall_from_haskell_var(tree, tree_len, RW); - let tree_reader = Cursor::new(tree_in); - let ct = read_commitment_tree::>, 32>(tree_reader); - match ct { - Ok(mut comm_tree) => { - let node_in: Vec = marshall_from_haskell_var(node, node_len, RW); - let orchard_note_comm = ExtractedNoteCommitment::from_bytes(&to_array(node_in)); - if orchard_note_comm.is_some().into() { - let n = MerkleHashOrchard::from_cmx(&orchard_note_comm.unwrap()); - comm_tree.append(n); - let mut out_bytes: Vec = Vec::new(); - let result = write_commitment_tree(&comm_tree, &mut out_bytes ); - match result { - Ok(()) => { - let h = Hhex { bytes: out_bytes}; - marshall_to_haskell_var(&h, out, out_len, RW); - }, - Err(_e) => { - let h0 = Hhex { bytes: vec![0]}; - marshall_to_haskell_var(&h0, out, out_len, RW); - } - } - } else { - let h0 = Hhex { bytes: vec![0]}; - marshall_to_haskell_var(&h0, out, out_len, RW); - } - }, - Err(_e) => { - let h0 = Hhex { bytes: vec![0]}; - marshall_to_haskell_var(&h0, out, out_len, RW); - } + let tree_in: Hfrontier = marshall_from_haskell_var(tree, tree_len, RW); + //let tree_reader = Cursor::new(tree_in); + //let mut comm_tree: CommitmentTree = read_commitment_tree(tree_reader).unwrap(); + //let mut comm_tree: Frontier = read_frontier_v1(tree_reader).unwrap(); + let leaf = MerkleHashOrchard::from_bytes(&to_array(tree_in.leaf.bytes)).unwrap(); + let mut comm_tree: NonEmptyFrontier = NonEmptyFrontier::from_parts(Position::from(tree_in.position), leaf, tree_in.ommers.iter().map(|x| MerkleHashOrchard::from_bytes(&to_array(x.bytes.clone())).unwrap() ).collect()).unwrap(); + let node_in: Vec = marshall_from_haskell_var(node, node_len, RW); + let orchard_note_comm = ExtractedNoteCommitment::from_bytes(&to_array(node_in)); + if orchard_note_comm.is_some().into() { + let n = MerkleHashOrchard::from_cmx(&orchard_note_comm.unwrap()); + comm_tree.append(n); + let (pos, leaf, omm) = comm_tree.into_parts(); + let f = Hfrontier { position: ::from(pos), leaf: Hhex { bytes: leaf.to_bytes().to_vec()}, ommers: omm.iter().map(|&x| Hhex { bytes: x.to_bytes().to_vec()}).collect()}; + marshall_to_haskell_var(&f, out, out_len, RW); + } else { + let f0 = Hfrontier { position: 0, leaf: Hhex { bytes: vec![0]}, ommers: vec![Hhex { bytes: vec![0]}]}; + marshall_to_haskell_var(&f0, out, out_len, RW); } } @@ -1504,9 +2068,10 @@ pub extern "C" fn rust_wrapper_read_orchard_witness( out: *mut u8, out_len: &mut usize ){ - let tree_in: Vec = marshall_from_haskell_var(tree, tree_len, RW); - let tree_reader = Cursor::new(tree_in); - let ct: CommitmentTree = read_commitment_tree(tree_reader).unwrap(); + let tree_in: Hfrontier = marshall_from_haskell_var(tree, tree_len, RW); + let leaf = MerkleHashOrchard::from_bytes(&to_array(tree_in.leaf.bytes)).unwrap(); + let frontier: Frontier = Frontier::from_parts(Position::from(tree_in.position), leaf, tree_in.ommers.iter().map(|x| MerkleHashOrchard::from_bytes(&to_array(x.bytes.clone())).unwrap() ).collect()).unwrap(); + let ct: CommitmentTree = CommitmentTree::from_frontier(&frontier); let inc_wit = IncrementalWitness::from_tree(ct); let mut out_bytes: Vec = Vec::new(); let result = write_incremental_witness(&inc_wit, &mut out_bytes); @@ -1637,47 +2202,42 @@ pub extern "C" fn rust_wrapper_create_transaction( o_input_len: usize, out_list: *const u8, out_list_len: usize, - sapspend: *const u8, - sapspend_len: usize, - sapoutput: *const u8, - sapoutput_len: usize, net: bool, bl_height: u32, build: bool, out: *mut u8, out_len: &mut usize){ - let sap_wit_in: Vec = marshall_from_haskell_var(sap_wit, sap_wit_len, RW); - let sap_wit_reader = Cursor::new(sap_wit_in); - let sap_iw = read_commitment_tree::>, SAPLING_DEPTH>(sap_wit_reader); - let sap_anchor = match sap_iw { - Ok(s_iw) => { - Some(SaplingAnchor::from(s_iw.root())) - }, - Err(_e) => { + let sap_input: Vec = marshall_from_haskell_var(s_input, s_input_len, RW); + let sap_anchor_in: Vec = marshall_from_haskell_var(sap_wit, sap_wit_len, RW); + let sap_anchor = Node::from_bytes(to_array(sap_anchor_in)); + let sapling_anchor = + if sap_anchor.is_some().into() { + Some(SaplingAnchor::from(sap_anchor.unwrap())) + } else { None - } - }; - //println!("{:?}", sap_anchor); - let orch_wit_in: Vec = marshall_from_haskell_var(orch_wit, orch_wit_len, RW); - let orch_wit_reader = Cursor::new(orch_wit_in); - let orch_iw = read_commitment_tree::>, 32>(orch_wit_reader); - let orch_anchor = match orch_iw { - Ok(o_iw) => { - Some(OrchardAnchor::from(o_iw.root())) - }, - Err(_e) => { + }; + //println!("{:?}", sapling_anchor); + let orch_input: Vec = marshall_from_haskell_var(o_input, o_input_len, RW); + let orch_anchor_in : Vec = marshall_from_haskell_var(orch_wit, orch_wit_len, RW); + let orch_anchor = MerkleHashOrchard::from_bytes(&to_array(orch_anchor_in)); + let orchard_anchor = + if orch_anchor.is_some().into() { + Some(OrchardAnchor::from(orch_anchor.unwrap())) + } else { None - } - }; - let build_config = BuildConfig::Standard {sapling_anchor: sap_anchor, orchard_anchor: orch_anchor}; + }; + //println!("{:?}", orchard_anchor); + let build_config = BuildConfig::Standard {sapling_anchor, orchard_anchor}; let mut main_builder = Builder::new(MainNetwork, BlockHeight::from(bl_height), build_config); let mut test_builder = Builder::new(TestNetwork, BlockHeight::from(bl_height), build_config); let trans_input: Vec = marshall_from_haskell_var(t_input, t_input_len, RW); + let mut tss = TransparentSigningSet::new(); for t_in in trans_input { if t_in.sk.len() > 1 { + //println!("t inp: {:?}", t_in); let k = SecretKey::from_slice(&t_in.sk).unwrap(); if net { - match main_builder.add_transparent_input(k, t_in.utxo.unpack(), t_in.coin.unpack()) { + match main_builder.add_transparent_input(tss.add_key(k), t_in.utxo.unpack(), t_in.coin.unpack()) { Ok(()) => { //println!("added t-input in main"); continue; @@ -1685,7 +2245,7 @@ pub extern "C" fn rust_wrapper_create_transaction( Err(_e) => { println!("Error reading transparent input"); } } } else { - match test_builder.add_transparent_input(k, t_in.utxo.unpack(), t_in.coin.unpack()) { + match test_builder.add_transparent_input(tss.add_key(k), t_in.utxo.unpack(), t_in.coin.unpack()) { Ok(()) => { //println!("added t-input in test"); continue; @@ -1695,12 +2255,14 @@ pub extern "C" fn rust_wrapper_create_transaction( } } } - let sap_input: Vec = marshall_from_haskell_var(s_input, s_input_len, RW); + let mut sap_key_array = vec![]; for s_in in sap_input { if s_in.sk.len() > 1 { + //println!("s inp: {:?}", s_in); let sp_key = ExtendedSpendingKey::from_bytes(&s_in.sk); match sp_key { Ok(sk) => { + sap_key_array.push(sk.clone()); let pay_addr = PaymentAddress::from_bytes(&to_array(s_in.note.recipient)).unwrap(); let rseed = if s_in.note.rseed.kind == 1 { Rseed::BeforeZip212(Fr::from_bytes(&to_array(s_in.note.rseed.bytes)).unwrap()) @@ -1708,37 +2270,89 @@ pub extern "C" fn rust_wrapper_create_transaction( Rseed::AfterZip212(to_array(s_in.note.rseed.bytes)) }; let note = SaplingNote::from_parts(pay_addr, SaplingNoteValue::from_raw(s_in.note.note), rseed); - let wit_reader = Cursor::new(s_in.iw); - let iw: IncrementalWitness = read_incremental_witness(wit_reader).unwrap(); - let merkle_path = iw.path().unwrap(); + let mk_path = sapling_crypto::MerklePath::from_parts(s_in.iw.path.iter().map(|x| + if x.bytes.len() > 1 { + Node::from_bytes(to_array(x.bytes.clone())).unwrap() + } else { + Node::empty_leaf() + }).collect(), Position::from(u64::from(s_in.iw.position))); + let merkle_path = mk_path.unwrap(); + let fvk = sk.to_diversifiable_full_viewing_key().fvk().clone(); if net { - let _mb = main_builder.add_sapling_spend::(&sk, note, merkle_path).unwrap(); + let mb = main_builder.add_sapling_spend::(fvk, note, merkle_path); + match mb { + Ok(()) => { + continue; + }, + Err(_e) => { + let x = Hhex {bytes: vec![5]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } + } } else { - let _tb = test_builder.add_sapling_spend::(&sk, note, merkle_path).unwrap(); + let tb = test_builder.add_sapling_spend::(fvk, note, merkle_path); + match tb { + Ok(()) => { + continue; + }, + Err(_e) => { + let x = Hhex {bytes: vec![5]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } + } } }, Err(_e) => { - continue; + let x = Hhex {bytes: vec![5]}; + marshall_to_haskell_var(&x, out, out_len, RW); } } } } - let orch_input: Vec = marshall_from_haskell_var(o_input, o_input_len, RW); + let mut orch_keys = vec![]; for o_in in orch_input { if o_in.sk.len() > 1 { let sp_key = SpendingKey::from_bytes(o_in.sk[0..32].try_into().unwrap()).unwrap(); + orch_keys.push(SpendAuthorizingKey::from(&sp_key)); let pay_addr = OrchardAddress::from_raw_address_bytes(&to_array(o_in.note.recipient)).unwrap(); - let rho = Nullifier::from_bytes(&to_array(o_in.note.rho)).unwrap(); + let rho = Rho::from_bytes(&to_array(o_in.note.rho)).unwrap(); let rseed = RandomSeed::from_bytes(to_array(o_in.note.rseed.bytes), &rho).unwrap(); let val = NoteValue::from_raw(o_in.note.note); + //println!("o inp: {:?}", val); let note = Note::from_parts(pay_addr, val, rho, rseed).unwrap(); - let wit_reader = Cursor::new(o_in.iw); - let iw: IncrementalWitness = read_incremental_witness(wit_reader).unwrap(); - let merkle_path = OrchardMerklePath::from(iw.path().unwrap()); + let merkle_path = orchard::tree::MerklePath::from_parts(o_in.iw.position, to_array(o_in.iw.path.iter().map(|x| + if x.bytes.len() > 1 { + MerkleHashOrchard::from_bytes(&to_array(x.bytes.clone())).unwrap() + } else { + MerkleHashOrchard::empty_leaf() + } + ).collect())); if net { - let _mb = main_builder.add_orchard_spend::(&sp_key, note, merkle_path).unwrap(); + let mb = main_builder.add_orchard_spend::(FullViewingKey::from(&sp_key), note, merkle_path); + match mb { + Ok(()) => { + //println!("added orchard inp: {:?}", val); + continue; + }, + Err(e) => { + //println!("failed orchard inp: {:?}", e); + let x = Hhex {bytes: vec![7]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } + } } else { - let _tb = test_builder.add_orchard_spend::(&sp_key, note, merkle_path).unwrap(); + let tb = test_builder.add_orchard_spend::(FullViewingKey::from(&sp_key), note, merkle_path); + match tb { + Ok(()) => { + //println!("added orchard inp: {:?}", val); + continue; + }, + Err(e) => { + //println!("failed orchard inp: {:?}", e); + let x = Hhex {bytes: vec![7]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } + } } } } @@ -1748,19 +2362,49 @@ pub extern "C" fn rust_wrapper_create_transaction( 1 => { let recipient = TransparentAddress::PublicKeyHash(to_array(output.to)); let val = NonNegativeAmount::from_u64(output.amt).unwrap(); + //println!("t out: {:?} {:?}", val, output.chg); if net { - let _mb = main_builder.add_transparent_output(&recipient, val); + let mb = main_builder.add_transparent_output(&recipient, val); + match mb { + Ok(()) => { continue; }, + Err(_e) => { + let x = Hhex {bytes: vec![4]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } + } } else { - let _tb = test_builder.add_transparent_output(&recipient, val); + let tb = test_builder.add_transparent_output(&recipient, val); + match tb { + Ok(()) => { continue; }, + Err(_e) => { + let x = Hhex {bytes: vec![4]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } + } } }, 2 => { let recipient = TransparentAddress::ScriptHash(to_array(output.to)); let val = NonNegativeAmount::from_u64(output.amt).unwrap(); + //println!("t out: {:?} {:?}", val, output.chg); if net { - let _mb = main_builder.add_transparent_output(&recipient, val); + let mb = main_builder.add_transparent_output(&recipient, val); + match mb { + Ok(()) => { continue; }, + Err(_e) => { + let x = Hhex {bytes: vec![4]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } + } } else { - let _tb = test_builder.add_transparent_output(&recipient, val); + let tb = test_builder.add_transparent_output(&recipient, val); + match tb { + Ok(()) => { continue; }, + Err(_e) => { + let x = Hhex {bytes: vec![4]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } + } } }, 3 => { @@ -1768,10 +2412,26 @@ pub extern "C" fn rust_wrapper_create_transaction( let recipient = PaymentAddress::from_bytes(&to_array(output.to)).unwrap(); let val = NonNegativeAmount::from_u64(output.amt).unwrap(); let memo = MemoBytes::from_bytes(&output.memo).unwrap(); + //println!("s out: {:?} {:?}", val, output.chg); if net { - let _mb = main_builder.add_sapling_output::(ovk, recipient, val, memo); + let mb = main_builder.add_sapling_output::(ovk, recipient, val, memo); + match mb { + Ok(()) => { continue; }, + Err(_e) => { + let x = Hhex {bytes: vec![5]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } + } } else { - let _tb = test_builder.add_sapling_output::(ovk, recipient, val, memo); + let tb = test_builder.add_sapling_output::(ovk, recipient, val, memo); + match tb { + Ok(()) => { continue; }, + Err(_e) => { + let x = Hhex {bytes: vec![5]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } + } + //println!("add sap: {:?}", tb); } }, 4 => { @@ -1783,11 +2443,26 @@ pub extern "C" fn rust_wrapper_create_transaction( }; let recipient = OrchardAddress::from_raw_address_bytes(&to_array(output.to)).unwrap(); let val = output.amt; + //println!("o out: {:?} {:?}", val, output.chg); let memo = MemoBytes::from_bytes(&output.memo).unwrap(); if net { - let _mb = main_builder.add_orchard_output::(ovk, recipient, val, memo); + let mb = main_builder.add_orchard_output::(ovk, recipient, val, memo); + match mb { + Ok(()) => { continue; }, + Err(_e) => { + let x = Hhex {bytes: vec![6]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } + } } else { - let _tb = test_builder.add_orchard_output::(ovk, recipient, val, memo); + let tb = test_builder.add_orchard_output::(ovk, recipient, val, memo); + match tb { + Ok(()) => { continue; }, + Err(_e) => { + let x = Hhex {bytes: vec![6]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } + } } }, _ => { @@ -1796,16 +2471,23 @@ pub extern "C" fn rust_wrapper_create_transaction( } } if build { - let spend_params_in: Vec = marshall_from_haskell_var(sapspend, sapspend_len, RW); + //let fee_result = if net { + //main_builder.get_fee(&FeeRule::standard()) + //} else { + //test_builder.get_fee(&FeeRule::standard()) + //}; + //println!("fee: {:?}", fee_result); + let (spend_params_in, output_params_in) = load_sapling_parameters(); + //let spend_params_in: Vec = marshall_from_haskell_var(sapspend, sapspend_len, RW); let spend_params_reader = Cursor::new(spend_params_in); let spend_prover = SpendParameters::read(spend_params_reader, false).unwrap(); - let output_params_in: Vec = marshall_from_haskell_var(sapoutput, sapoutput_len, RW); + //let output_params_in: Vec = marshall_from_haskell_var(sapoutput, sapoutput_len, RW); let output_params_reader = Cursor::new(output_params_in); let output_prover = OutputParameters::read(output_params_reader, false).unwrap(); let result = if net { - main_builder.build(OsRng, &spend_prover, &output_prover, &FeeRule::standard()) + main_builder.build(&tss, &sap_key_array, &orch_keys, OsRng, &spend_prover, &output_prover, &FeeRule::standard()) } else { - test_builder.build(OsRng, &spend_prover, &output_prover, &FeeRule::standard()) + test_builder.build(&tss, &sap_key_array, &orch_keys,OsRng, &spend_prover, &output_prover, &FeeRule::standard()) }; match result { Ok(r) => { @@ -1817,10 +2499,12 @@ pub extern "C" fn rust_wrapper_create_transaction( Err(e) => { match e { Error::InsufficientFunds(y) => { + //println!("ins funds: {:?}", y); let x = Hhex {bytes: vec![0]}; marshall_to_haskell_var(&x, out, out_len, RW); }, Error::ChangeRequired(y1) => { + //println!("change req: {:?}", y1); let x = Hhex {bytes: vec![1]}; marshall_to_haskell_var(&x, out, out_len, RW); }, @@ -1881,3 +2565,87 @@ pub extern "C" fn rust_wrapper_create_transaction( } } } + +#[no_mangle] +pub extern "C" fn rust_wrapper_create_orchard_fvk( + orch_in: *const u8, + orch_in_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let input: Vec = marshall_from_haskell_var(orch_in, orch_in_len, RW); + let sk = SpendingKey::from_bytes(to_array(input)); + if sk.is_some().into() { + let fvk = FullViewingKey::from(&sk.unwrap()); + let x = Hhex {bytes: fvk.to_bytes().to_vec()}; + marshall_to_haskell_var(&x, out, out_len, RW); + } else { + let x = Hhex {bytes: vec![0]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_create_orchard_ivk( + orch_in: *const u8, + orch_in_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let input: Vec = marshall_from_haskell_var(orch_in, orch_in_len, RW); + let sk = SpendingKey::from_bytes(to_array(input)); + if sk.is_some().into() { + let fvk = FullViewingKey::from(&sk.unwrap()).to_ivk(Scope::External); + let x = Hhex {bytes: fvk.to_bytes().to_vec()}; + marshall_to_haskell_var(&x, out, out_len, RW); + } else { + let x = Hhex {bytes: vec![0]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_create_sapling_fvk( + sap_in: *const u8, + sap_in_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let input: Vec = marshall_from_haskell_var(sap_in, sap_in_len, RW); + let in_bytes: [u8; 169] = to_array(input); + let sk = ExtendedSpendingKey::from_bytes(&in_bytes); + match sk { + Ok(k) => { + let fvk = k.to_diversifiable_full_viewing_key(); + let x = Hhex {bytes: fvk.to_bytes().to_vec()}; + marshall_to_haskell_var(&x, out, out_len, RW); + }, + Err(_e) => { + let x = Hhex {bytes: vec![0]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } + } +} + +#[no_mangle] +pub extern "C" fn rust_wrapper_create_sapling_ivk( + sap_in: *const u8, + sap_in_len: usize, + out: *mut u8, + out_len: &mut usize + ){ + let input: Vec = marshall_from_haskell_var(sap_in, sap_in_len, RW); + let in_bytes: [u8; 169] = to_array(input); + let sk = ExtendedSpendingKey::from_bytes(&in_bytes); + match sk { + Ok(k) => { + let ivk = k.to_diversifiable_full_viewing_key().to_external_ivk(); + let x = Hhex {bytes: ivk.to_bytes().to_vec()}; + marshall_to_haskell_var(&x, out, out_len, RW); + }, + Err(_e) => { + let x = Hhex {bytes: vec![0]}; + marshall_to_haskell_var(&x, out, out_len, RW); + } + } +} diff --git a/src/C/Zcash.chs b/src/C/Zcash.chs index 0f35be4..b4c26de 100644 --- a/src/C/Zcash.chs +++ b/src/C/Zcash.chs @@ -120,6 +120,13 @@ import ZcashHaskell.Types -> `()' #} +{# fun unsafe rust_wrapper_uivk_decode as rustWrapperUivkDecode + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer UnifiedIncomingViewingKey'& + } + -> `()' +#} + {# fun unsafe rust_wrapper_orchard_note_decrypt as rustWrapperOrchardNoteDecode { toBorshVar* `BS.ByteString'& , toBorshVar* `OrchardAction'& @@ -204,15 +211,15 @@ import ZcashHaskell.Types #} {# fun unsafe rust_wrapper_read_sapling_commitment_tree as rustWrapperReadSaplingCommitmentTree - { toBorshVar* `BS.ByteString'& + { toBorshVar* `SaplingFrontier'& , toBorshVar* `BS.ByteString'& - , getVarBuffer `Buffer HexString'& + , getVarBuffer `Buffer SaplingFrontier'& } -> `()' #} {# fun unsafe rust_wrapper_read_sapling_witness as rustWrapperReadSaplingWitness - { toBorshVar* `BS.ByteString'& + { toBorshVar* `SaplingFrontier'& , getVarBuffer `Buffer HexString'& } -> `()' @@ -232,6 +239,13 @@ import ZcashHaskell.Types -> `()' #} +{# fun unsafe rust_wrapper_read_sapling_frontier as rustWrapperReadSaplingFrontier + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer SaplingFrontier'& + } + -> `()' +#} + {# fun unsafe rust_wrapper_decode_sapling_address as rustWrapperDecodeSaplingAddress { toBorshVar* `BS.ByteString'& , getVarBuffer `Buffer (BS.ByteString)'& @@ -239,16 +253,120 @@ import ZcashHaskell.Types -> `()' #} -{# fun unsafe rust_wrapper_read_orchard_commitment_tree as rustWrapperReadOrchardCommitmentTree +{# fun unsafe rust_wrapper_read_sapling_node as rustWrapperReadSaplingNode { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_combine_sapling_nodes as rustWrapperCombineSaplingNodes + { `Int8' + , toBorshVar* `BS.ByteString'& , toBorshVar* `BS.ByteString'& , getVarBuffer `Buffer HexString'& } -> `()' #} -{# fun unsafe rust_wrapper_read_orchard_witness as rustWrapperReadOrchardWitness +{# fun unsafe rust_wrapper_get_sapling_root as rustWrapperGetSaplingRootTest + { `Int8' + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_read_sapling_commitment_tree_parts as rustWrapperReadSaplingTreeParts { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer SaplingRawTree'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_read_sapling_tree_anchor as rustWrapperReadSaplingTreeAnchor + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_read_sapling_path_anchor as rustWrapperReadSaplingPathAnchor + { toBorshVar* `MerklePath'& + , toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_read_orchard_node as rustWrapperReadOrchardNode + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_combine_orchard_nodes as rustWrapperCombineOrchardNodes + { `Int8' + , toBorshVar* `BS.ByteString'& + , toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_read_orchard_tree_anchor as rustWrapperReadOrchardTreeAnchor + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_read_orchard_witness_anchor as rustWrapperReadOrchardWitnessAnchor + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_read_orchard_path_anchor as rustWrapperReadOrchardPathAnchor + { toBorshVar* `MerklePath'& + , toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_get_orchard_root as rustWrapperGetOrchardRootTest + { `Int8' + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_read_orchard_commitment_tree as rustWrapperReadOrchardCommitmentTree + { toBorshVar* `OrchardFrontier'& + , toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer OrchardFrontier'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_read_orchard_commitment_tree_parts as rustWrapperReadOrchardTreeParts + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer OrchardRawTree'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_read_orchard_frontier as rustWrapperReadOrchardFrontier + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer OrchardFrontier'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_read_orchard_witness as rustWrapperReadOrchardWitness + { toBorshVar* `OrchardFrontier'& , getVarBuffer `Buffer HexString'& } -> `()' @@ -260,6 +378,15 @@ import ZcashHaskell.Types -> `Word64' #} +{# fun unsafe rust_wrapper_orchard_add_node as rustWrapperOrchardAddNodeTest + { `Int8' + , toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer HexString'& + } + -> `()' + +#} + {# fun unsafe rust_wrapper_update_sapling_witness as rustWrapperUpdateSaplingWitness { toBorshVar* `BS.ByteString'& , toBorshVar* `[BS.ByteString]'& @@ -283,8 +410,6 @@ import ZcashHaskell.Types , toBorshVar* `[SaplingTxSpend]'& , toBorshVar* `[OrchardTxSpend]'& , toBorshVar* `[OutgoingNote]'& - , toBorshVar* `BS.ByteString'& - , toBorshVar* `BS.ByteString'& , `Bool' , `Word64' , `Bool' @@ -292,3 +417,31 @@ import ZcashHaskell.Types } -> `()' #} + +{# fun unsafe rust_wrapper_create_orchard_fvk as rustWrapperCreateOrchardFvk + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_create_orchard_ivk as rustWrapperCreateOrchardIvk + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_create_sapling_fvk as rustWrapperCreateSaplingFvk + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} + +{# fun unsafe rust_wrapper_create_sapling_ivk as rustWrapperCreateSaplingIvk + { toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} diff --git a/src/ZcashHaskell/Keys.hs b/src/ZcashHaskell/Keys.hs index 30484e7..67de27b 100644 --- a/src/ZcashHaskell/Keys.hs +++ b/src/ZcashHaskell/Keys.hs @@ -15,13 +15,42 @@ module ZcashHaskell.Keys where import C.Zcash (rustWrapperGenSeedPhrase, rustWrapperGetSeed) +import Crypto.Secp256k1 (createContext) import qualified Data.ByteString as BS +import Data.HexString (hexBytes) import qualified Data.Text as T +import qualified Data.Text.Encoding as E +import Data.Word (Word8(..)) import Foreign.Rust.Marshall.Variable ( withBorshVarBuffer , withPureBorshVarBuffer ) -import ZcashHaskell.Types (Phrase, Seed(..), ToBytes(..)) +import Haskoin.Address.Base58 (decodeBase58) +import Haskoin.Crypto.Keys.Extended + ( DerivPath(..) + , DerivPathI(..) + , XPubKey(..) + , derivePath + , deriveXPubKey + , xPubExport + ) +import Haskoin.Network.Constants (btc) +import ZcashHaskell.Orchard (deriveOrchardFvk, deriveOrchardIvk) +import ZcashHaskell.Sapling (deriveSaplingFvk, deriveSaplingIvk) +import ZcashHaskell.Types + ( OrchardSpendingKey(..) + , Phrase + , SaplingSpendingKey(..) + , Seed(..) + , ToBytes(..) + , TransparentSpendingKey(..) + , ZcashNet(..) + , uniFullViewingKeyHrp + , uniIncomingViewingKeyHrp + , uniTestFullViewingKeyHrp + , uniTestIncomingViewingKeyHrp + ) +import ZcashHaskell.Utils (encodeBech32m, f4Jumble) -- | Generate a random seed that can be used to generate private keys for shielded addresses and transparent addresses. generateWalletSeedPhrase :: IO Phrase @@ -36,3 +65,97 @@ getWalletSeed p = where result :: Seed result = (withPureBorshVarBuffer . rustWrapperGetSeed) p + +-- | Derive a transparent root node for unified viewing keys +deriveFullTransparentNode :: TransparentSpendingKey -> IO BS.ByteString +deriveFullTransparentNode sk = do + ioCtx <- createContext + let tPubKey = deriveXPubKey ioCtx sk + let tPubKeyBytes = decodeBase58 $ xPubExport btc ioCtx tPubKey + case tPubKeyBytes of + Nothing -> fail "Unable to get transparent key bytes" + Just pb -> return $ BS.takeEnd 65 pb + +-- | Derive a transparent incoming root node for unified incoming viewing keys +deriveIncomingTransparentNode :: TransparentSpendingKey -> IO BS.ByteString +deriveIncomingTransparentNode sk = do + ioCtx <- createContext + let path = Deriv :/ 0 :: DerivPath + let childPrvKey = derivePath ioCtx path sk + let tPubKey = deriveXPubKey ioCtx childPrvKey + let tPubKeyBytes = decodeBase58 $ xPubExport btc ioCtx tPubKey + case tPubKeyBytes of + Nothing -> fail "Unable to get transparent key bytes" + Just pb -> return $ BS.takeEnd 65 pb + +-- | Derive a Unified Full Viewing Key +deriveUfvk :: + ZcashNet + -> OrchardSpendingKey + -> SaplingSpendingKey + -> TransparentSpendingKey + -> IO T.Text +deriveUfvk net okey skey tkey = do + tSec <- deriveFullTransparentNode tkey + let oSec = deriveOrchardFvk okey + let sSec = deriveSaplingFvk skey + case oSec of + Nothing -> fail "Unable to derive Orchard viewing key" + Just oSec' -> do + case sSec of + Nothing -> fail "Unable to derive Sapling viewing key" + Just sSec' -> + return $ encodeVK (hexBytes oSec') (hexBytes sSec') tSec net True + +-- | Derive a Unified Incoming Viewing Key +deriveUivk :: + ZcashNet + -> OrchardSpendingKey + -> SaplingSpendingKey + -> TransparentSpendingKey + -> IO T.Text +deriveUivk net okey skey tkey = do + tSec <- deriveIncomingTransparentNode tkey + let oSec = deriveOrchardIvk okey + let sSec = deriveSaplingIvk skey + case oSec of + Nothing -> fail "Unable to derive Orchard viewing key" + Just oSec' -> do + case sSec of + Nothing -> fail "Unable to derive Sapling viewing key" + Just sSec' -> + return $ encodeVK (hexBytes oSec') (hexBytes sSec') tSec net False + +-- | Encode a Unified Viewing Key per [ZIP-316](https://zips.z.cash/zip-0316) +encodeVK :: + BS.ByteString -- ^ Orchard FVK + -> BS.ByteString -- ^ Sapling FVK + -> BS.ByteString -- ^ Transparent root node + -> ZcashNet -- ^ Network + -> Bool -- ^ Full? + -> T.Text +encodeVK ovk svk tvk net full = encodeBech32m (E.encodeUtf8 hr) b + where + tReceiver = packReceiver 0x00 $ Just tvk + b = f4Jumble $ tReceiver <> sReceiver <> oReceiver <> padding + hr = + if full + then case net of + MainNet -> uniFullViewingKeyHrp + TestNet -> uniTestFullViewingKeyHrp + else case net of + MainNet -> uniIncomingViewingKeyHrp + TestNet -> uniTestIncomingViewingKeyHrp + sReceiver = packReceiver 0x02 $ Just svk + oReceiver = packReceiver 0x03 $ Just ovk + padding = E.encodeUtf8 $ T.justifyLeft 16 '\NUL' hr + packReceiver :: Word8 -> Maybe BS.ByteString -> BS.ByteString + packReceiver typeCode receiver' = + case receiver' of + Just receiver -> + if BS.length receiver > 1 + then BS.singleton typeCode `BS.append` + (BS.singleton . toEnum . BS.length) receiver `BS.append` + receiver + else BS.empty + Nothing -> BS.empty diff --git a/src/ZcashHaskell/Orchard.hs b/src/ZcashHaskell/Orchard.hs index d7c3e38..b63a914 100644 --- a/src/ZcashHaskell/Orchard.hs +++ b/src/ZcashHaskell/Orchard.hs @@ -18,16 +18,28 @@ module ZcashHaskell.Orchard where import C.Zcash - ( rustWrapperGenOrchardReceiver + ( rustWrapperCombineOrchardNodes + , rustWrapperCreateOrchardFvk + , rustWrapperCreateOrchardIvk + , rustWrapperGenOrchardReceiver , rustWrapperGenOrchardSpendKey + , rustWrapperGetOrchardRootTest + , rustWrapperOrchardAddNodeTest , rustWrapperOrchardCheck , rustWrapperOrchardNoteDecode , rustWrapperOrchardNoteDecodeSK , rustWrapperReadOrchardCommitmentTree + , rustWrapperReadOrchardFrontier + , rustWrapperReadOrchardNode + , rustWrapperReadOrchardPathAnchor , rustWrapperReadOrchardPosition + , rustWrapperReadOrchardTreeAnchor + , rustWrapperReadOrchardTreeParts , rustWrapperReadOrchardWitness + , rustWrapperReadOrchardWitnessAnchor , rustWrapperUADecode , rustWrapperUfvkDecode + , rustWrapperUivkDecode , rustWrapperUpdateOrchardWitness ) import qualified Data.ByteString as BS @@ -37,6 +49,11 @@ import qualified Data.Text as T import qualified Data.Text.Encoding as E import Data.Word import Foreign.Rust.Marshall.Variable +import ZcashHaskell.Sapling (decodeSaplingAddress) +import ZcashHaskell.Transparent + ( decodeExchangeAddress + , decodeTransparentAddress + ) import ZcashHaskell.Types import ZcashHaskell.Utils (encodeBech32, encodeBech32m, f4Jumble) @@ -98,9 +115,9 @@ isValidUnifiedAddress str = (if BS.length (raw_s x) == 43 then Just $ SaplingReceiver (raw_s x) else Nothing) - (if not (BS.null (raw_t x)) + (if BS.length (raw_t x) > 1 then Just $ TransparentReceiver P2PKH (fromRawBytes $ raw_t x) - else if not (BS.null (raw_to x)) + else if BS.length (raw_to x) > 1 then Just $ TransparentReceiver P2SH (fromRawBytes $ raw_to x) else Nothing) @@ -143,6 +160,15 @@ decodeUfvk str = where decodedKey = (withPureBorshVarBuffer . rustWrapperUfvkDecode) str +-- | Attempts to decode the given bytestring into a Unified Full Viewing Key +decodeUivk :: BS.ByteString -> Maybe UnifiedIncomingViewingKey +decodeUivk str = + case i_net decodedKey of + 0 -> Nothing + _ -> Just decodedKey + where + decodedKey = (withPureBorshVarBuffer . rustWrapperUivkDecode) str + -- | Check if the given UVK matches the UA given matchOrchardAddress :: BS.ByteString -> BS.ByteString -> Bool matchOrchardAddress = rustWrapperOrchardCheck @@ -189,40 +215,159 @@ decryptOrchardActionSK sk scope oa = withPureBorshVarBuffer $ rustWrapperOrchardNoteDecodeSK (getBytes sk) oa (scope == External) --- | Update a Orchard commitment tree -updateOrchardCommitmentTree :: - OrchardCommitmentTree -- ^ the base tree - -> HexString -- ^ the new note commitment - -> Maybe OrchardCommitmentTree -updateOrchardCommitmentTree tree cmx = - if BS.length (hexBytes updatedTree) > 1 - then Just $ OrchardCommitmentTree updatedTree +getOrchardFrontier :: OrchardCommitmentTree -> Maybe OrchardFrontier +getOrchardFrontier tree = + if of_pos updatedTree > 1 + then Just updatedTree else Nothing where updatedTree = withPureBorshVarBuffer $ - rustWrapperReadOrchardCommitmentTree - (hexBytes $ orchTree tree) - (hexBytes cmx) + rustWrapperReadOrchardFrontier $ toBytes $ orchTree tree + +getOrchardTreeAnchor :: OrchardCommitmentTree -> HexString +getOrchardTreeAnchor tree = + withPureBorshVarBuffer $ + rustWrapperReadOrchardTreeAnchor $ toBytes $ orchTree tree + +getOrchardWitnessAnchor :: OrchardWitness -> HexString +getOrchardWitnessAnchor wit = + withPureBorshVarBuffer $ + rustWrapperReadOrchardWitnessAnchor $ toBytes $ orchWit wit + +getOrchardRootTest :: Int -> HexString +getOrchardRootTest level = + withPureBorshVarBuffer $ rustWrapperGetOrchardRootTest $ fromIntegral level + +addOrchardNodeGetRoot :: Int -> BS.ByteString -> HexString +addOrchardNodeGetRoot l n = + withPureBorshVarBuffer $ rustWrapperOrchardAddNodeTest (fromIntegral l) n + +getOrchardTreeParts :: OrchardCommitmentTree -> Maybe OrchardTree +getOrchardTreeParts h = + if isBlank (ort_left tree) && isBlank (ort_right tree) + then Nothing + else Just $ + OrchardTree + (parseHex $ ort_left tree) + (parseHex $ ort_right tree) + (map parseHex (ort_parents tree)) + where + isBlank h = (BS.length $ hexBytes $ h) == 1 + parseHex h = + if (BS.length $ hexBytes $ h) > 1 + then Just h + else Nothing + tree = + withPureBorshVarBuffer $ + rustWrapperReadOrchardTreeParts $ toBytes $ orchTree h + +getOrchardPathAnchor :: HexString -> MerklePath -> HexString +getOrchardPathAnchor hex p = + withPureBorshVarBuffer $ rustWrapperReadOrchardPathAnchor p (hexBytes hex) + +-- | Update a Orchard commitment tree +updateOrchardCommitmentTree :: + OrchardFrontier -- ^ the base tree + -> HexString -- ^ the new note commitment + -> Maybe OrchardFrontier +updateOrchardCommitmentTree tree cmx = + if of_pos updatedTree > 1 + then Just updatedTree + else Nothing + where + updatedTree = + withPureBorshVarBuffer $ + rustWrapperReadOrchardCommitmentTree tree (hexBytes cmx) -- | Get the Orchard incremental witness from a commitment tree -getOrchardWitness :: OrchardCommitmentTree -> Maybe OrchardWitness +getOrchardWitness :: OrchardFrontier -> Maybe OrchardWitness getOrchardWitness tree = if BS.length (hexBytes wit) > 1 then Just $ OrchardWitness wit else Nothing where - wit = - withPureBorshVarBuffer $ - rustWrapperReadOrchardWitness (hexBytes $ orchTree tree) + wit = withPureBorshVarBuffer $ rustWrapperReadOrchardWitness tree -- | Get the Sapling note position from a witness getOrchardNotePosition :: OrchardWitness -> Integer getOrchardNotePosition = fromIntegral . rustWrapperReadOrchardPosition . hexBytes . orchWit +-- | Update the witness of an Orchard note updateOrchardWitness :: OrchardWitness -> [HexString] -> OrchardWitness updateOrchardWitness wit cmus = - OrchardWitness $ - withPureBorshVarBuffer $ - rustWrapperUpdateOrchardWitness (toBytes $ orchWit wit) (map toBytes cmus) + if not (null cmus) + then OrchardWitness $ + withPureBorshVarBuffer $ + rustWrapperUpdateOrchardWitness + (toBytes $ orchWit wit) + (map toBytes cmus) + else wit + +getOrchardNodeValue :: BS.ByteString -> Maybe HexString +getOrchardNodeValue cmx = + if BS.length (hexBytes n) > 1 + then Just n + else Nothing + where + n = withPureBorshVarBuffer $ rustWrapperReadOrchardNode cmx + +combineOrchardNodes :: Integer -> HexString -> HexString -> Maybe HexString +combineOrchardNodes level n1 n2 = + if BS.length (hexBytes r) > 1 + then Just r + else Nothing + where + r = + withPureBorshVarBuffer $ + rustWrapperCombineOrchardNodes + (fromIntegral level) + (toBytes n1) + (toBytes n2) + +-- | Parse a potential Zcash address +parseAddress :: BS.ByteString -> Maybe ValidAddress +parseAddress t = + case isValidUnifiedAddress t of + Nothing -> + case decodeSaplingAddress t of + Nothing -> + case decodeTransparentAddress t of + Nothing -> + case decodeExchangeAddress t of + Nothing -> Nothing + Just x -> Just $ Exchange x + Just t -> Just $ Transparent t + Just s -> Just $ Sapling s + Just u -> Just $ Unified u + +compareAddress :: ValidAddress -> UnifiedAddress -> Bool +compareAddress a u = + case a of + Unified i -> i == u + Sapling s -> s_rec u == Just (sa_receiver s) && ua_net u == net_type s + Transparent t -> t_rec u == Just (ta_receiver t) && ua_net u == ta_network t + Exchange x -> False + +-- | Derive an Orchard Full Viewing Key +deriveOrchardFvk :: + OrchardSpendingKey -- ^ The Orchard spending key + -> Maybe HexString +deriveOrchardFvk sk = + if BS.length (hexBytes r) > 1 + then Just r + else Nothing + where + r = withPureBorshVarBuffer $ rustWrapperCreateOrchardFvk $ getBytes sk + +-- | Derive an Orchard Incoming Viewing Key +deriveOrchardIvk :: + OrchardSpendingKey -- ^ The Orchard spending key + -> Maybe HexString +deriveOrchardIvk sk = + if BS.length (hexBytes r) > 1 + then Just r + else Nothing + where + r = withPureBorshVarBuffer $ rustWrapperCreateOrchardIvk $ getBytes sk diff --git a/src/ZcashHaskell/Sapling.hs b/src/ZcashHaskell/Sapling.hs index 5ba501e..7b5cf72 100644 --- a/src/ZcashHaskell/Sapling.hs +++ b/src/ZcashHaskell/Sapling.hs @@ -18,10 +18,19 @@ module ZcashHaskell.Sapling where import C.Zcash - ( rustWrapperDecodeSaplingAddress + ( rustWrapperCombineSaplingNodes + , rustWrapperCreateSaplingFvk + , rustWrapperCreateSaplingIvk + , rustWrapperDecodeSaplingAddress + , rustWrapperGetSaplingRootTest , rustWrapperIsShielded , rustWrapperReadSaplingCommitmentTree + , rustWrapperReadSaplingFrontier + , rustWrapperReadSaplingNode + , rustWrapperReadSaplingPathAnchor , rustWrapperReadSaplingPosition + , rustWrapperReadSaplingTreeAnchor + , rustWrapperReadSaplingTreeParts , rustWrapperReadSaplingWitness , rustWrapperSaplingCheck , rustWrapperSaplingChgPaymentAddress @@ -37,6 +46,7 @@ import Data.Aeson import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as C import Data.HexString (HexString(..), fromText, hexString, toBytes, toText) +import Data.Int (Int8) import qualified Data.Text as T import Data.Word import Foreign.Rust.Marshall.Variable @@ -95,12 +105,35 @@ instance FromJSON RawTxResponse where c <- obj .: "confirmations" b <- obj .: "blocktime" sSpend <- obj .: "vShieldedSpend" + sOut <- obj .: "vShieldedOutput" case o of Nothing -> - pure $ RawTxResponse i h sSpend (getShieldedOutputs h) [] ht c b + pure $ + RawTxResponse + i + h + sSpend + (if not (null (sOut :: [Object])) + then getShieldedOutputs h + else []) + [] + ht + c + b Just o' -> do a <- o' .: "actions" - pure $ RawTxResponse i h sSpend (getShieldedOutputs h) a ht c b + pure $ + RawTxResponse + i + h + sSpend + (if not (null sOut) + then getShieldedOutputs h + else []) + a + ht + c + b -- | Attempt to decode the given raw tx with the given Sapling spending key decodeSaplingOutputEsk :: @@ -161,32 +194,88 @@ genSaplingInternalAddress sk = res = withPureBorshVarBuffer (rustWrapperSaplingChgPaymentAddress $ getBytes sk) --- | Update a Sapling commitment tree -updateSaplingCommitmentTree :: - SaplingCommitmentTree -- ^ the base tree - -> HexString -- ^ the new note commitment - -> Maybe SaplingCommitmentTree -updateSaplingCommitmentTree tree cmu = - if BS.length (hexBytes updatedTree) > 1 - then Just $ SaplingCommitmentTree updatedTree +getSaplingNodeValue :: BS.ByteString -> Maybe HexString +getSaplingNodeValue cmu = + if BS.length (hexBytes n) > 1 + then Just n + else Nothing + where + n = withPureBorshVarBuffer $ rustWrapperReadSaplingNode cmu + +combineSaplingNodes :: Int8 -> HexString -> HexString -> Maybe HexString +combineSaplingNodes level n1 n2 = + if BS.length (hexBytes r) > 1 + then Just r + else Nothing + where + r = + withPureBorshVarBuffer $ + rustWrapperCombineSaplingNodes level (toBytes n1) (toBytes n2) + +getSaplingRootTest :: Int8 -> HexString +getSaplingRootTest level = + withPureBorshVarBuffer $ rustWrapperGetSaplingRootTest level + +getSaplingTreeParts :: SaplingCommitmentTree -> Maybe SaplingTree +getSaplingTreeParts h = + if isBlank (srt_left tree) && isBlank (srt_right tree) + then Nothing + else Just $ + SaplingTree + (parseHex $ srt_left tree) + (parseHex $ srt_right tree) + (map parseHex (srt_parents tree)) + where + isBlank h = (BS.length $ hexBytes $ h) == 1 + parseHex h = + if (BS.length $ hexBytes $ h) > 1 + then Just h + else Nothing + tree = + withPureBorshVarBuffer $ + rustWrapperReadSaplingTreeParts $ toBytes $ sapTree h + +getSaplingTreeAnchor :: SaplingCommitmentTree -> HexString +getSaplingTreeAnchor tree = + withPureBorshVarBuffer $ + rustWrapperReadSaplingTreeAnchor $ toBytes $ sapTree tree + +getSaplingPathAnchor :: HexString -> MerklePath -> HexString +getSaplingPathAnchor hex p = + withPureBorshVarBuffer $ rustWrapperReadSaplingPathAnchor p (hexBytes hex) + +getSaplingFrontier :: SaplingCommitmentTree -> Maybe SaplingFrontier +getSaplingFrontier tree = + if sf_pos updatedTree > 1 + then Just updatedTree else Nothing where updatedTree = withPureBorshVarBuffer $ - rustWrapperReadSaplingCommitmentTree - (hexBytes $ sapTree tree) - (hexBytes cmu) + rustWrapperReadSaplingFrontier $ toBytes $ sapTree tree + +-- | Update a Sapling commitment tree +updateSaplingCommitmentTree :: + SaplingFrontier -- ^ the base tree + -> HexString -- ^ the new note commitment + -> Maybe SaplingFrontier +updateSaplingCommitmentTree tree cmu = + if sf_pos updatedTree > 1 + then Just updatedTree + else Nothing + where + updatedTree = + withPureBorshVarBuffer $ + rustWrapperReadSaplingCommitmentTree tree (hexBytes cmu) -- | Get the Sapling incremental witness from a commitment tree -getSaplingWitness :: SaplingCommitmentTree -> Maybe SaplingWitness +getSaplingWitness :: SaplingFrontier -> Maybe SaplingWitness getSaplingWitness tree = if BS.length (hexBytes wit) > 1 then Just $ SaplingWitness wit else Nothing where - wit = - withPureBorshVarBuffer $ - rustWrapperReadSaplingWitness (hexBytes $ sapTree tree) + wit = withPureBorshVarBuffer $ rustWrapperReadSaplingWitness tree -- | Get the Sapling note position from a witness getSaplingNotePosition :: SaplingWitness -> Integer @@ -195,9 +284,13 @@ getSaplingNotePosition = updateSaplingWitness :: SaplingWitness -> [HexString] -> SaplingWitness updateSaplingWitness wit cmus = - SaplingWitness $ - withPureBorshVarBuffer $ - rustWrapperUpdateSaplingWitness (toBytes $ sapWit wit) (map toBytes cmus) + if not (null cmus) + then SaplingWitness $ + withPureBorshVarBuffer $ + rustWrapperUpdateSaplingWitness + (toBytes $ sapWit wit) + (map toBytes cmus) + else wit -- | Encode a SaplingReceiver into HRF text encodeSaplingAddress :: ZcashNet -> SaplingReceiver -> Maybe T.Text @@ -227,3 +320,25 @@ decodeSaplingAddress sapling_address = do where sa = withPureBorshVarBuffer $ rustWrapperDecodeSaplingAddress sapling_address + +-- | Derive a Sapling Full Viewing Key +deriveSaplingFvk :: + SaplingSpendingKey -- ^ The Sapling spending key + -> Maybe HexString +deriveSaplingFvk sk = + if BS.length (hexBytes r) > 1 + then Just r + else Nothing + where + r = withPureBorshVarBuffer $ rustWrapperCreateSaplingFvk $ getBytes sk + +-- | Derive a Sapling Incoming Viewing Key +deriveSaplingIvk :: + SaplingSpendingKey -- ^ The Sapling spending key + -> Maybe HexString +deriveSaplingIvk sk = + if BS.length (hexBytes r) > 1 + then Just r + else Nothing + where + r = withPureBorshVarBuffer $ rustWrapperCreateSaplingIvk $ getBytes sk diff --git a/src/ZcashHaskell/Transparent.hs b/src/ZcashHaskell/Transparent.hs index 878a7d8..287fe99 100644 --- a/src/ZcashHaskell/Transparent.hs +++ b/src/ZcashHaskell/Transparent.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE OverloadedStrings #-} + -- Copyright 2022-2024 Vergara Technologies LLC -- -- This file is part of Zcash-Haskell. @@ -172,27 +174,27 @@ decodeTransparentAddress taddress = do -- | Encode an Exchange Addresss into HRF from TransparentReceiver encodeExchangeAddress :: ZcashNet -> TransparentReceiver -> Maybe T.Text encodeExchangeAddress net tr = do - case (tr_type tr) of + case tr_type tr of P2PKH -> do case net of MainNet -> do - let vhash = encodeBech32m (BC.pack "tex") (toBytes (tr_bytes tr)) + let vhash = encodeBech32m "tex" (toBytes (tr_bytes tr)) Just vhash TestNet -> do - let vhash = encodeBech32m (BC.pack "textest") (toBytes (tr_bytes tr)) + let vhash = encodeBech32m "textest" (toBytes (tr_bytes tr)) Just vhash - _ -> Nothing + _any -> Nothing -- | Decode an Exchange Address into a ExchangeAddress -decodeExchangeAddress :: T.Text -> Maybe ExchangeAddress +decodeExchangeAddress :: BS.ByteString -> Maybe ExchangeAddress decodeExchangeAddress ex = do - if (T.length ex) > 1 + if BS.length ex > 1 then do - let rawd = decodeBech32 (E.encodeUtf8 ex) - let tMain = BS.unpack (BC.pack "tex") - let tTest = BS.unpack (BC.pack "textest") - let tFail = BS.unpack (BC.pack "fail") - let hr = BS.unpack (hrp rawd) + let rawd = decodeBech32 ex + let tMain = "tex" + let tTest = "textest" + let tFail = "fail" + let hr = hrp rawd if hr /= tFail then do let transparentReceiver = bytes rawd diff --git a/src/ZcashHaskell/Types.hs b/src/ZcashHaskell/Types.hs index af60f0f..d478dc4 100644 --- a/src/ZcashHaskell/Types.hs +++ b/src/ZcashHaskell/Types.hs @@ -38,6 +38,7 @@ import Data.Maybe (fromJust, fromMaybe) import Data.Structured import qualified Data.Text as T import qualified Data.Text.Encoding as E +import qualified Data.Vector as V import Data.Word import qualified GHC.Generics as GHC import qualified Generics.SOP as SOP @@ -90,7 +91,7 @@ data ZcashNet = MainNet | TestNet | RegTestNet - deriving (Eq, Prelude.Show, Read) + deriving (Eq, Prelude.Show, Read, GHC.Generic, ToJSON, FromJSON) type AccountId = Int @@ -133,6 +134,18 @@ data Transaction = Transaction , tx_orchardBundle :: !(Maybe OrchardBundle) } deriving (Prelude.Show, Eq, Read) +instance ToJSON Transaction where + toJSON (Transaction t h c e tb sb ob) = + object + [ "txid" .= t + , "height" .= h + , "confirmations" .= c + , "expiry" .= e + , "transparent" .= tb + , "sapling" .= sb + , "orchard" .= ob + ] + -- | The transparent portion of a Zcash transaction data TransparentBundle = TransparentBundle { tb_vin :: ![H.TxIn] @@ -140,6 +153,10 @@ data TransparentBundle = TransparentBundle , tb_coinbase :: !Bool } deriving (Eq, Prelude.Show, Read) +instance ToJSON TransparentBundle where + toJSON (TransparentBundle vin vout c) = + object ["vin" .= vin, "vout" .= vout, "coinbase" .= c] + -- | Read a raw transparent bundle into the Haskell type fromRawTBundle :: RawTBundle -> Maybe TransparentBundle fromRawTBundle rtb = @@ -239,7 +256,8 @@ instance FromJSON RpcError where -- ** `zcashd` -- | Type to represent response from the `zcashd` RPC `getblock` method data BlockResponse = BlockResponse - { bl_confirmations :: !Integer -- ^ Block confirmations + { bl_hash :: !HexString + , bl_confirmations :: !Integer -- ^ Block confirmations , bl_height :: !Integer -- ^ Block height , bl_time :: !Integer -- ^ Block time , bl_txs :: ![HexString] -- ^ List of transaction IDs in the block @@ -250,9 +268,20 @@ instance FromJSON BlockResponse where withObject "BlockResponse" $ \obj -> do c <- obj .: "confirmations" h <- obj .: "height" - t <- obj .:? "time" + t <- obj .: "time" txs <- obj .: "tx" - pure $ BlockResponse c h (fromMaybe 0 t) txs + hash <- obj .: "hash" + pure $ BlockResponse hash c h t txs + +instance ToJSON BlockResponse where + toJSON (BlockResponse h c ht t txs) = + object + [ "hash" .= h + , "confirmations" .= c + , "height" .= ht + , "time" .= t + , "tx" .= txs + ] -- | Type to represent response from the `zcashd` RPC `getrawtransaction` data RawTxResponse = RawTxResponse @@ -324,6 +353,10 @@ data SaplingBundle = SaplingBundle , sbSig :: !HexString } deriving stock (Eq, Prelude.Show, GHC.Generic, Read) +instance ToJSON SaplingBundle where + toJSON (SaplingBundle s o v sig) = + object ["spends" .= s, "outputs" .= o, "value" .= v, "sig" .= sig] + fromRawSBundle :: RawSBundle -> Maybe SaplingBundle fromRawSBundle b = if zsb_empty b @@ -355,6 +388,17 @@ data OrchardBundle = OrchardBundle , obSig :: !HexString } deriving stock (Eq, Prelude.Show, GHC.Generic, Read) +instance ToJSON OrchardBundle where + toJSON (OrchardBundle a f v an p s) = + object + [ "actions" .= a + , "flags" .= f + , "value" .= v + , "anchor" .= an + , "proof" .= p + , "sig" .= s + ] + fromRawOBundle :: RawOBundle -> Maybe OrchardBundle fromRawOBundle b = if zob_empty b @@ -377,6 +421,10 @@ data OrchardFlags = OrchardFlags deriving anyclass (Data.Structured.Show) deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OrchardFlags +instance ToJSON OrchardFlags where + toJSON (OrchardFlags s o) = + Data.Aeson.Array $ V.fromList [Data.Aeson.Bool s, Data.Aeson.Bool o] + -- | Type for the response from the `zebrad` RPC method `getinfo` data ZebraGetInfo = ZebraGetInfo { zgi_build :: !T.Text @@ -501,6 +549,17 @@ data ShieldedSpend = ShieldedSpend deriving anyclass (Data.Structured.Show) deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct ShieldedSpend +instance ToJSON ShieldedSpend where + toJSON (ShieldedSpend cv a n rk p au) = + object + [ "cv" .= cv + , "anchor" .= a + , "nullifier" .= n + , "rk" .= rk + , "proof" .= p + , "spendAuthSig" .= au + ] + instance FromJSON ShieldedSpend where parseJSON = withObject "ShieldedSpend" $ \obj -> do @@ -525,6 +584,17 @@ data ShieldedOutput = ShieldedOutput deriving anyclass (Data.Structured.Show) deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct ShieldedOutput +instance ToJSON ShieldedOutput where + toJSON (ShieldedOutput c cm e enc o p) = + object + [ "cv" .= c + , "cmu" .= cm + , "ephemeralKey" .= e + , "encCiphertext" .= enc + , "outCiphertext" .= o + , "proof" .= p + ] + instance FromJSON ShieldedOutput where parseJSON = withObject "ShieldedOutput" $ \obj -> do @@ -541,6 +611,30 @@ newtype SaplingCommitmentTree = SaplingCommitmentTree { sapTree :: HexString } deriving (Eq, Prelude.Show, Read) +data SaplingRawTree = SaplingRawTree + { srt_left :: !HexString + , srt_right :: !HexString + , srt_parents :: ![HexString] + } deriving stock (Eq, Prelude.Show, GHC.Generic) + deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) + deriving anyclass (Data.Structured.Show) + deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct SaplingRawTree + +data SaplingTree = SaplingTree + { st_left :: !(Maybe HexString) + , st_right :: !(Maybe HexString) + , st_parents :: ![Maybe HexString] + } deriving (Eq, Prelude.Show, Read) + +data SaplingFrontier = SaplingFrontier + { sf_pos :: !Int64 + , sf_leaf :: !HexString + , sf_ommers :: ![HexString] + } deriving stock (Eq, Prelude.Show, GHC.Generic) + deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) + deriving anyclass (Data.Structured.Show) + deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct SaplingFrontier + -- | Type for a Sapling incremental witness newtype SaplingWitness = SaplingWitness { sapWit :: HexString @@ -583,6 +677,14 @@ data RawUA = RawUA deriving anyclass (Data.Structured.Show) deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct RawUA +-- | A type to handle user-entered addresses +data ValidAddress + = Unified !UnifiedAddress + | Sapling !SaplingAddress + | Transparent !TransparentAddress + | Exchange !ExchangeAddress + deriving stock (Eq, Prelude.Show) + -- | Type to represent a Unified Full Viewing Key data UnifiedFullViewingKey = UnifiedFullViewingKey { net :: !Word8 -- ^ Number representing the network the key belongs to. @1@ for @mainnet@, @2@ for @testnet@ and @3@ for @regtestnet@. @@ -594,6 +696,18 @@ data UnifiedFullViewingKey = UnifiedFullViewingKey deriving anyclass (Data.Structured.Show) deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct UnifiedFullViewingKey +-- | Type to represent a Unified Incoming Viewing Key +data UnifiedIncomingViewingKey = UnifiedIncomingViewingKey + { i_net :: !Word8 -- ^ Number representing the network the key belongs to. @1@ for @mainnet@, @2@ for @testnet@ and @3@ for @regtestnet@. + , i_o_key :: !BS.ByteString -- ^ Raw bytes of the Orchard Incoming Viewing Key as specified in [ZIP-316](https://zips.z.cash/zip-0316) + , i_s_key :: !BS.ByteString -- ^ Raw bytes of the Sapling Incoming Viewing Key as specified in [ZIP-316](https://zips.z.cash/zip-0316) + , i_t_key :: !BS.ByteString -- ^ Raw bytes of the P2PKH chain code and public key as specified in [ZIP-316](https://zips.z.cash/zip-0316) + } deriving stock (Eq, Prelude.Show, GHC.Generic) + deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) + deriving anyclass (Data.Structured.Show) + deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct + UnifiedIncomingViewingKey + -- | Type to represent an Orchard Action as provided by the @getrawtransaction@ RPC method of @zcashd@, and defined in the [Zcash Protocol](https://zips.z.cash/protocol/protocol.pdf) data OrchardAction = OrchardAction { nf :: !HexString -- ^ The nullifier of the input note @@ -609,6 +723,19 @@ data OrchardAction = OrchardAction deriving anyclass (Data.Structured.Show) deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OrchardAction +instance ToJSON OrchardAction where + toJSON (OrchardAction n r c e en o cv a) = + object + [ "nullifier" .= n + , "rk" .= r + , "cmx" .= c + , "ephemeralKey" .= e + , "encCiphertext" .= en + , "outCiphertext" .= o + , "cv" .= cv + , "spendAuthSig" .= a + ] + instance FromJSON OrchardAction where parseJSON = withObject "OrchardAction" $ \obj -> do @@ -622,11 +749,43 @@ instance FromJSON OrchardAction where a <- obj .: "spendAuthSig" pure $ OrchardAction n r c ephKey encText outText cval a +data MerklePath = MerklePath + { mp_position :: !Int32 + , mp_path :: ![HexString] + } deriving stock (Eq, Prelude.Show, GHC.Generic) + deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) + deriving anyclass (Data.Structured.Show) + deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct MerklePath + -- | Type for a Orchard note commitment tree newtype OrchardCommitmentTree = OrchardCommitmentTree { orchTree :: HexString } deriving (Eq, Prelude.Show, Read) +data OrchardRawTree = OrchardRawTree + { ort_left :: !HexString + , ort_right :: !HexString + , ort_parents :: ![HexString] + } deriving stock (Eq, Prelude.Show, GHC.Generic) + deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) + deriving anyclass (Data.Structured.Show) + deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OrchardRawTree + +data OrchardTree = OrchardTree + { ot_left :: !(Maybe HexString) + , ot_right :: !(Maybe HexString) + , ot_parents :: ![Maybe HexString] + } deriving (Eq, Prelude.Show, Read) + +data OrchardFrontier = OrchardFrontier + { of_pos :: !Int64 + , of_leaf :: !HexString + , of_ommers :: ![HexString] + } deriving stock (Eq, Prelude.Show, GHC.Generic) + deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) + deriving anyclass (Data.Structured.Show) + deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OrchardFrontier + -- | Type for a Sapling incremental witness newtype OrchardWitness = OrchardWitness { orchWit :: HexString @@ -665,7 +824,7 @@ data TransparentTxSpend = TransparentTxSpend data SaplingTxSpend = SaplingTxSpend { ss_sk :: !BS.ByteString , ss_note :: !DecodedNote - , ss_iw :: !BS.ByteString + , ss_iw :: !MerklePath } deriving stock (Eq, Prelude.Show, GHC.Generic) deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) deriving anyclass (Data.Structured.Show) @@ -674,7 +833,7 @@ data SaplingTxSpend = SaplingTxSpend data OrchardTxSpend = OrchardTxSpend { ss_sk :: !BS.ByteString , ss_note :: !DecodedNote - , ss_iw :: !BS.ByteString + , ss_iw :: !MerklePath } deriving stock (Eq, Prelude.Show, GHC.Generic) deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) deriving anyclass (Data.Structured.Show) @@ -712,6 +871,7 @@ data TxError | OrchardRecipient | SaplingBuilderNotAvailable | OrchardBuilderNotAvailable + | PrivacyPolicyError !T.Text | ZHError deriving (Eq, Prelude.Show, Read) diff --git a/src/ZcashHaskell/Utils.hs b/src/ZcashHaskell/Utils.hs index 59b38ed..03db2b5 100644 --- a/src/ZcashHaskell/Utils.hs +++ b/src/ZcashHaskell/Utils.hs @@ -123,50 +123,41 @@ readZebraTransaction hex = rawTx = (withPureBorshVarBuffer . rustWrapperTxRead) $ hexBytes hex createTransaction :: - Maybe SaplingCommitmentTree -- ^ to obtain the Sapling anchor - -> Maybe OrchardCommitmentTree -- ^ to obtain the Orchard anchor + HexString -- ^ to obtain the Sapling anchor + -> HexString -- ^ to obtain the Orchard anchor -> [TransparentTxSpend] -- ^ the list of transparent notes to spend -> [SaplingTxSpend] -- ^ the list of Sapling notes to spend -> [OrchardTxSpend] -- ^ the list of Orchard notes to spend -> [OutgoingNote] -- ^ the list of outgoing notes, including change notes - -> SaplingSpendParams -- ^ the Sapling circuit spending parameters - -> SaplingOutputParams -- ^ the Sapling circuit output parameters -> ZcashNet -- ^ the network to be used -> Int -- ^ target block height -> Bool -- ^ True to build, False to estimate fee - -> Either TxError HexString -createTransaction sapAnchor orchAnchor tSpend sSpend oSpend outgoing sParams oParams znet bh build = + -> IO (Either TxError HexString) +createTransaction sapAnchor orchAnchor tSpend sSpend oSpend outgoing znet bh build = do + txResult <- + withBorshBufferOfInitSize 51200 $ + rustWrapperCreateTx + (hexBytes sapAnchor) + (hexBytes orchAnchor) + tSpend + sSpend + oSpend + outgoing + (znet == MainNet) + (fromIntegral bh) + build if BS.length (hexBytes txResult) > 1 - then Right txResult + then pure $ Right txResult else case head (BS.unpack $ hexBytes txResult) of - 0 -> Left InsufficientFunds - 1 -> Left ChangeRequired - 2 -> Left Fee - 3 -> Left Balance - 4 -> Left TransparentBuild - 5 -> Left SaplingBuild - 6 -> Left OrchardBuild - 7 -> Left OrchardSpend - 8 -> Left OrchardRecipient - 9 -> Left SaplingBuilderNotAvailable - 10 -> Left OrchardBuilderNotAvailable - _ -> Left ZHError - where - txResult = - withPureBorshVarBuffer $ - rustWrapperCreateTx - (case sapAnchor of - Nothing -> "0" - Just sA -> toBytes $ sapTree sA) - (case orchAnchor of - Nothing -> "0" - Just oA -> toBytes $ orchTree oA) - tSpend - sSpend - oSpend - outgoing - (sapSParams sParams) - (sapOParams oParams) - (znet == MainNet) - (fromIntegral bh) - build + 0 -> pure $ Left InsufficientFunds + 1 -> pure $ Left ChangeRequired + 2 -> pure $ Left Fee + 3 -> pure $ Left Balance + 4 -> pure $ Left TransparentBuild + 5 -> pure $ Left SaplingBuild + 6 -> pure $ Left OrchardBuild + 7 -> pure $ Left OrchardSpend + 8 -> pure $ Left OrchardRecipient + 9 -> pure $ Left SaplingBuilderNotAvailable + 10 -> pure $ Left OrchardBuilderNotAvailable + _ -> pure $ Left ZHError diff --git a/test/Spec.hs b/test/Spec.hs index 7b0aac0..207b05a 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -40,11 +40,17 @@ import GHC.Float.RealFracMethods (properFractionDoubleInteger) import Haskoin.Crypto.Hash (ripemd160) import Haskoin.Crypto.Keys.Extended import Haskoin.Transaction.Common +import Network.HTTP.Simple (Response(..)) import Test.HUnit import Test.Hspec import Test.Hspec.QuickCheck import Test.QuickCheck -import ZcashHaskell.Keys (generateWalletSeedPhrase, getWalletSeed) +import ZcashHaskell.Keys + ( deriveUfvk + , deriveUivk + , generateWalletSeedPhrase + , getWalletSeed + ) import ZcashHaskell.Orchard import ZcashHaskell.Sapling ( decodeSaplingAddress @@ -54,6 +60,7 @@ import ZcashHaskell.Sapling , genSaplingInternalAddress , genSaplingPaymentAddress , genSaplingSpendingKey + , getSaplingFrontier , getSaplingNotePosition , getSaplingWitness , getShieldedOutputs @@ -72,6 +79,7 @@ import ZcashHaskell.Types , OrchardAction(..) , OrchardBundle(..) , OrchardCommitmentTree(..) + , OrchardFrontier(..) , OrchardSpendingKey(..) , OrchardWitness(..) , Phrase(..) @@ -82,9 +90,12 @@ import ZcashHaskell.Types , RawTxOut(..) , RawTxResponse(..) , RawZebraTx(..) + , RpcError(..) + , RpcResponse(..) , SaplingAddress(..) , SaplingBundle(..) , SaplingCommitmentTree(..) + , SaplingFrontier(..) , SaplingReceiver(..) , SaplingSpendingKey(..) , SaplingWitness(..) @@ -892,34 +903,36 @@ main = do Just t' -> do let tb = zt_tBundle t' show tb `shouldNotBe` "" - describe "Sapling commitment trees" $ do - let tree = - SaplingCommitmentTree $ - hexString - "01916df07670600aefa3b412a120d6b8d9a3d2ff9466a7ec770cd52d34ddb42313001000013c60b031a5e44650059fcc7101a3f551b807ab8b3a116a5a9c7fa0f3babbe735017c0d36686294ff19d59e58b6a2ac6a7ad607a804bc202c84012d8e94f233970c0128dbde5180af5304d8577376d78297130b615a327974c10881f6d876869aea05011b80b4ca60f74dfe33c78b062df73c84b8b44dab4604db16f5b61eea40134373010c96e4cc8a6a80fba0d41e4eb3070d80769104dc33fb61133b1304c15bf9e23e000107114fe4bb4cd08b47f6ae47477c182d5da9fe5c189061808c1091e9bf3b4524000001447d6b9100cddd5f80c8cf4ddee2b87eba053bd987465aec2293bd0514e68b0d015f6c95e75f4601a0a31670a7deb970fc8988c611685161d2e1629d0a1a0ebd07015f8b9205e0514fa235d75c150b87e23866b882b39786852d1ab42aab11d31a4a0117ddeb3a5f8d2f6b2d0a07f28f01ab25e03a05a9319275bb86d72fcaef6fc01501f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39" - let cmu1 = - hexString - "45e47c5df6f5c5e48aa3526e977b2d1b57eda57214e36f06128008cb17b0125f" - let cmu2 = - hexString - "426ef44b3b22e0eeda7e4d2b62bac63966572b224e50f97ee56c9490cde4910d" - let tree2 = - hexString - "01a47029e9b43722c57143a5d07681bff3e2315c9a28ad49d69e7c1f2f6e81ac160010000000000000012f4f72c03f8c937a94919a01a07f21165cc8394295291cb888ca91ed003810390107114fe4bb4cd08b47f6ae47477c182d5da9fe5c189061808c1091e9bf3b4524000001447d6b9100cddd5f80c8cf4ddee2b87eba053bd987465aec2293bd0514e68b0d015f6c95e75f4601a0a31670a7deb970fc8988c611685161d2e1629d0a1a0ebd07015f8b9205e0514fa235d75c150b87e23866b882b39786852d1ab42aab11d31a4a0117ddeb3a5f8d2f6b2d0a07f28f01ab25e03a05a9319275bb86d72fcaef6fc01501f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39" - it "Commitment tree is updated correctly" $ do - let t1 = updateSaplingCommitmentTree tree cmu1 - t1 `shouldNotBe` Nothing - it "Incremental witness is generated" $ do - let t1 = updateSaplingCommitmentTree tree cmu1 - case t1 of - Nothing -> assertFailure "Failed to append node to tree" - Just t -> getSaplingWitness t `shouldNotBe` Nothing - it "Position of note is obtained" $ do - let p = - getSaplingNotePosition <$> - (getSaplingWitness =<< updateSaplingCommitmentTree tree cmu1) - p `shouldBe` Just 129405 - describe "Orchard commitment trees" $ do + {- + -describe "Sapling commitment trees" $ do + - let tree = + - SaplingCommitmentTree $ + - hexString + - "01916df07670600aefa3b412a120d6b8d9a3d2ff9466a7ec770cd52d34ddb42313001000013c60b031a5e44650059fcc7101a3f551b807ab8b3a116a5a9c7fa0f3babbe735017c0d36686294ff19d59e58b6a2ac6a7ad607a804bc202c84012d8e94f233970c0128dbde5180af5304d8577376d78297130b615a327974c10881f6d876869aea05011b80b4ca60f74dfe33c78b062df73c84b8b44dab4604db16f5b61eea40134373010c96e4cc8a6a80fba0d41e4eb3070d80769104dc33fb61133b1304c15bf9e23e000107114fe4bb4cd08b47f6ae47477c182d5da9fe5c189061808c1091e9bf3b4524000001447d6b9100cddd5f80c8cf4ddee2b87eba053bd987465aec2293bd0514e68b0d015f6c95e75f4601a0a31670a7deb970fc8988c611685161d2e1629d0a1a0ebd07015f8b9205e0514fa235d75c150b87e23866b882b39786852d1ab42aab11d31a4a0117ddeb3a5f8d2f6b2d0a07f28f01ab25e03a05a9319275bb86d72fcaef6fc01501f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39" + - let cmu1 = + - hexString + - "45e47c5df6f5c5e48aa3526e977b2d1b57eda57214e36f06128008cb17b0125f" + - let cmu2 = + - hexString + - "426ef44b3b22e0eeda7e4d2b62bac63966572b224e50f97ee56c9490cde4910d" + - let tree2 = + - hexString + - "01a47029e9b43722c57143a5d07681bff3e2315c9a28ad49d69e7c1f2f6e81ac160010000000000000012f4f72c03f8c937a94919a01a07f21165cc8394295291cb888ca91ed003810390107114fe4bb4cd08b47f6ae47477c182d5da9fe5c189061808c1091e9bf3b4524000001447d6b9100cddd5f80c8cf4ddee2b87eba053bd987465aec2293bd0514e68b0d015f6c95e75f4601a0a31670a7deb970fc8988c611685161d2e1629d0a1a0ebd07015f8b9205e0514fa235d75c150b87e23866b882b39786852d1ab42aab11d31a4a0117ddeb3a5f8d2f6b2d0a07f28f01ab25e03a05a9319275bb86d72fcaef6fc01501f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39" + - it "Commitment tree is updated correctly" $ do + - let t1 = updateSaplingCommitmentTree tree cmu1 + - t1 `shouldNotBe` Nothing + - it "Incremental witness is generated" $ do + - let t1 = updateSaplingCommitmentTree tree cmu1 + - case t1 of + - Nothing -> assertFailure "Failed to append node to tree" + - Just t -> getSaplingWitness t `shouldNotBe` Nothing + - it "Position of note is obtained" $ do + - let p = + - getSaplingNotePosition <$> + - (getSaplingWitness =<< updateSaplingCommitmentTree tree cmu1) + - p `shouldBe` Just 129405 + -} + {- describe "Orchard commitment trees" $ do let tree = OrchardCommitmentTree $ hexString @@ -939,7 +952,7 @@ main = do let p = getOrchardNotePosition <$> (getOrchardWitness =<< updateOrchardCommitmentTree tree cmx) - p `shouldBe` Just 39432 + p `shouldBe` Just 39432 -} describe "Extract Sapling Address - UA Valid" $ do let sr = getSaplingFromUA @@ -1058,18 +1071,22 @@ main = do (hexString "97e5f003d16720844ba1bd157688a7697133f4bb4a33a7c91974937a1351d7af56d16d4a10bd196ddda700fcd8be517f8f9e39a17ba0eea235d98450a626be3a998ac31f35e8e082106a31fe94da11d02b73748db4aa519df6bbf25c1d62a2cf0b192c6a486bca2632fee9e4124ce2dba6f3366a14850f6a3b784d863119f52458ed774f8d63105b4f6a3d2e09cc74e3a02ec8386213087b4c849172ded6724a45c9c12744ec4a0f86a29b803b17187df5dd5f90e71d1f3f4578d4e1496e8892") it "Sap output 1" $ do - let pos = - getSaplingNotePosition <$> - (getSaplingWitness =<< - updateSaplingCommitmentTree - tree - (fromText - "fa430c51bb108db782764cff55de9c6b11bbecd2493d2e0fa9f646428feef858")) - case pos of - Nothing -> assertFailure "couldn't get note position" - Just p -> do - let dn = decodeSaplingOutputEsk sk so1 TestNet External p - dn `shouldBe` Nothing + case getSaplingFrontier tree of + Nothing -> assertFailure "failed to read comm tree" + Just tree' -> do + let pos = + sf_pos <$> + updateSaplingCommitmentTree + tree' + (fromText + "fa430c51bb108db782764cff55de9c6b11bbecd2493d2e0fa9f646428feef858") + case pos of + Nothing -> assertFailure "couldn't get note position" + Just p -> do + let dn = + decodeSaplingOutputEsk sk so1 TestNet External $ + fromIntegral p + dn `shouldBe` Nothing it "Sap output 2" $ do case readZebraTransaction txHex2 of Nothing -> assertFailure "Failed to read Tx" @@ -1079,24 +1096,27 @@ main = do Nothing -> assertFailure "Failed to get sapling bundle" Just sB -> do let sOuts = sbOutputs sB - let pos = - getSaplingNotePosition <$> - (getSaplingWitness =<< - updateSaplingCommitmentTree - tree - (fromText - "d163c69029e8cb05d874b798c7973b3b1b1b0e04f984a252b73c848698320843")) - case pos of - Nothing -> assertFailure "couldn't get note position" - Just p -> do - let dn = - decodeSaplingOutputEsk - sk - (head . tail $ sOuts) - TestNet - External - p - dn `shouldBe` Nothing + case getSaplingFrontier tree of + Nothing -> assertFailure "Failed to read tree" + Just tree' -> do + let pos = + getSaplingNotePosition <$> + (getSaplingWitness =<< + updateSaplingCommitmentTree + tree' + (fromText + "d163c69029e8cb05d874b798c7973b3b1b1b0e04f984a252b73c848698320843")) + case pos of + Nothing -> assertFailure "couldn't get note position" + Just p -> do + let dn = + decodeSaplingOutputEsk + sk + (head . tail $ sOuts) + TestNet + External + p + dn `shouldBe` Nothing it "Decode Sapling Output from Zingo" $ do case readZebraTransaction txHex of Nothing -> assertFailure "Failed to read Tx" @@ -1109,24 +1129,26 @@ main = do Nothing -> assertFailure "Failed to get sapling bundle" Just sB -> do let sOuts = sbOutputs sB - let pos = - getSaplingNotePosition <$> - (getSaplingWitness =<< - updateSaplingCommitmentTree - tree - (fromText - "d163c69029e8cb05d874b798c7973b3b1b1b0e04f984a252b73c848698320843")) - case pos of - Nothing -> assertFailure "couldn't get note position" - Just p -> do - let dn = - decodeSaplingOutputEsk - sK' - (head . tail $ sOuts) - MainNet - External - p - dn `shouldNotBe` Nothing + case getSaplingFrontier tree of + Nothing -> assertFailure "failed to read comm tree" + Just tree' -> do + let pos = + sf_pos <$> + updateSaplingCommitmentTree + tree' + (fromText + "d163c69029e8cb05d874b798c7973b3b1b1b0e04f984a252b73c848698320843") + case pos of + Nothing -> assertFailure "couldn't get note position" + Just p -> do + let dn = + decodeSaplingOutputEsk + sK' + (head . tail $ sOuts) + MainNet + External + (fromIntegral p) + dn `shouldNotBe` Nothing describe "Generate an ExchangeAddress (MainNet) from transparent address" $ do let ta = decodeTransparentAddress "t1dMjvesbzdG41xgKaGU3HgwYJwSgbCK54e" it "Try to generate valid ExchangeAddress from Transparent Address" $ do @@ -1143,43 +1165,35 @@ main = do case exch of Nothing -> assertFailure "Failed to encode Exchange address" Just addr -> do - let eadr = decodeExchangeAddress addr + let eadr = decodeExchangeAddress (E.encodeUtf8 addr) eadr `shouldNotBe` Nothing - describe "Witness updates" $ do - it "Sapling" $ do - let wit = - SaplingWitness $ - hexString - "01bd8a3f3cfc964332a2ada8c09a0da9dfc24174befb938abb086b9be5ca049e49013607f5e51826c8e5f660571ddfae14cd6fb1dc026bcd6855459b4e9339b20521100000019f0d7efb00169bb2202152d3266059d208ab17d14642c3339f9075e997160657000000012f4f72c03f8c937a94919a01a07f21165cc8394295291cb888ca91ed003810390107114fe4bb4cd08b47f6ae47477c182d5da9fe5c189061808c1091e9bf3b4524000001447d6b9100cddd5f80c8cf4ddee2b87eba053bd987465aec2293bd0514e68b0d015f6c95e75f4601a0a31670a7deb970fc8988c611685161d2e1629d0a1a0ebd07015f8b9205e0514fa235d75c150b87e23866b882b39786852d1ab42aab11d31a4a0117ddeb3a5f8d2f6b2d0a07f28f01ab25e03a05a9319275bb86d72fcaef6fc01501f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39038cd7f6e2238d16ef49420963348dd4e4c7d23d5e5dac69507fba8937f63eb626f6856115bea2fa8db3a65a0ab294db41c51435d3b7ea27c7b2835aca28e82a2c1d9634efe07449a47c251518ac6f92c49f3a1ef119948f6a824d1e7ff7d0443e0101e57ec972a9b9383dc9cb228980d2d7752bb2abebc4a604ca48c5457039d2e05b000301392bed8592185dde5ab7fc81aed75e98fcf041f1a3fda55ad0b0b139ba9380130001808304b4d7c4fc407f5ce28247a7119013aeaaf1481902419c42bc8b21575c15" - let cmus = - [ hexString - "958ccdc752f2f593f6c1c8e2d7201348cd896e54c6d3c92200bdbe8b859eac44" - , hexString - "e49992fdd071d90bf56242d1aa625bbe267a34e0debd4307818a686d05b45447" - , hexString - "0c4b26766d89bf6cdb4fd3b0317b4e9a2fb3850f6a24869f32fe7cb0fd512e18" - ] - updateSaplingWitness wit cmus `shouldBe` - SaplingWitness - (hexString - "01bd8a3f3cfc964332a2ada8c09a0da9dfc24174befb938abb086b9be5ca049e49013607f5e51826c8e5f660571ddfae14cd6fb1dc026bcd6855459b4e9339b20521100000019f0d7efb00169bb2202152d3266059d208ab17d14642c3339f9075e997160657000000012f4f72c03f8c937a94919a01a07f21165cc8394295291cb888ca91ed003810390107114fe4bb4cd08b47f6ae47477c182d5da9fe5c189061808c1091e9bf3b4524000001447d6b9100cddd5f80c8cf4ddee2b87eba053bd987465aec2293bd0514e68b0d015f6c95e75f4601a0a31670a7deb970fc8988c611685161d2e1629d0a1a0ebd07015f8b9205e0514fa235d75c150b87e23866b882b39786852d1ab42aab11d31a4a0117ddeb3a5f8d2f6b2d0a07f28f01ab25e03a05a9319275bb86d72fcaef6fc01501f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39038cd7f6e2238d16ef49420963348dd4e4c7d23d5e5dac69507fba8937f63eb626f6856115bea2fa8db3a65a0ab294db41c51435d3b7ea27c7b2835aca28e82a2c1d9634efe07449a47c251518ac6f92c49f3a1ef119948f6a824d1e7ff7d0443e0101e49992fdd071d90bf56242d1aa625bbe267a34e0debd4307818a686d05b45447010c4b26766d89bf6cdb4fd3b0317b4e9a2fb3850f6a24869f32fe7cb0fd512e1803000121c06ee1f1584f79d50785797a694c742be2ded600367ab7d54f3ed49e3adf7201808304b4d7c4fc407f5ce28247a7119013aeaaf1481902419c42bc8b21575c15") - it "Orchard" $ do - let wit = - OrchardWitness $ - hexString - "016225b41339a00dd764b452fca190a0245e7118224965942e3a6d798365c34631001f0000011d6f5da3f619bfaab957fc643c17eb144db0101c90f422da2fcbe0e80d74412e000000000001746e6bc066a10e7f80a9ff8993dcb25c819edd64f2ca10ac248ef7848d41450500011e6191f91b3fceb62dc881a156e1b9d2e88e09dca25093cf9c4936c8869fb41a013bf8b923e4187754e85175748d9cce4824a6787e4258977b5bfe1ba59012c032000001f3bbdc62260c4fca5c84bf3487246d4542da48eeeec8ec40c1029b6908eef83c00000000000000000000000000000000040e02c864db8b574f165f616d48e2f12eb25099b5c90186af26d9e50f5058863e0504bfbc12edc35e05042c16bbfb8fed591f01f18fe128eeb57f2c456c9eb222d6d261c549e95d9007bce4c6ae0b86bc865711cdd9f0fa92e2d5b5e149b51f3be127df3b1d2372adf6c811b2e456c1d64d0e9eb167a995f9c6b66a03c9cbda250101c094201bae3b4ef582a3e8654f65a72fbd41e20e1ec9a43d3f4101afc868731e000200019df5b9366d0f21caa678d1567390b5bfd3cfa0438271bcfe301b5558a2863301" - let cmxs = - [ hexString - "712ba86615ff4447e8d7c7b59f3873f03c03a173438b8e4c8d416756ed4fae10" - , hexString - "c094201bae3b4ef582a3e8654f65a72fbd41e20e1ec9a43d3f4101afc868731e" - , hexString - "ac20b8170b008888c19fc6e16f5e30a5ef1653e5219d0cd0c9353c3aa8f79823" - ] - updateOrchardWitness wit cmxs `shouldBe` - OrchardWitness - (hexString - "016225b41339a00dd764b452fca190a0245e7118224965942e3a6d798365c34631001f0000011d6f5da3f619bfaab957fc643c17eb144db0101c90f422da2fcbe0e80d74412e000000000001746e6bc066a10e7f80a9ff8993dcb25c819edd64f2ca10ac248ef7848d41450500011e6191f91b3fceb62dc881a156e1b9d2e88e09dca25093cf9c4936c8869fb41a013bf8b923e4187754e85175748d9cce4824a6787e4258977b5bfe1ba59012c032000001f3bbdc62260c4fca5c84bf3487246d4542da48eeeec8ec40c1029b6908eef83c00000000000000000000000000000000040e02c864db8b574f165f616d48e2f12eb25099b5c90186af26d9e50f5058863e0504bfbc12edc35e05042c16bbfb8fed591f01f18fe128eeb57f2c456c9eb222d6d261c549e95d9007bce4c6ae0b86bc865711cdd9f0fa92e2d5b5e149b51f3be127df3b1d2372adf6c811b2e456c1d64d0e9eb167a995f9c6b66a03c9cbda250101c094201bae3b4ef582a3e8654f65a72fbd41e20e1ec9a43d3f4101afc868731e0002010cfb50d8c877eb39e9c07082a032dd99d34be7c19fa7f30e9fecf5f14736240f019df5b9366d0f21caa678d1567390b5bfd3cfa0438271bcfe301b5558a2863301") + describe "Generate Viewing Keys" $ do + let p = + Phrase + "cloth swing left trap random tornado have great onion element until make shy dad success art tuition canvas thunder apple decade elegant struggle invest" + let seed = getWalletSeed p + let oK = genOrchardSpendingKey (fromJust seed) MainNetCoin 0 + let sK = genSaplingSpendingKey (fromJust seed) MainNetCoin 0 + it "Generate FVK" $ do + tK <- genTransparentPrvKey (fromJust seed) MainNetCoin 0 + case oK of + Nothing -> assertFailure "Failed to generate Orchard SK" + Just o -> + case sK of + Nothing -> assertFailure "Failed to generate Sapling SK" + Just s -> do + fvk <- deriveUfvk MainNet o s tK + decodeUfvk (E.encodeUtf8 fvk) `shouldNotBe` Nothing + it "Generate IVK" $ do + tK <- genTransparentPrvKey (fromJust seed) MainNetCoin 0 + case oK of + Nothing -> assertFailure "Failed to generate Orchard SK" + Just o -> + case sK of + Nothing -> assertFailure "Failed to generate Sapling SK" + Just s -> do + ivk <- deriveUivk MainNet o s tK + decodeUivk (E.encodeUtf8 ivk) `shouldNotBe` Nothing -- | Properties prop_PhraseLength :: Property diff --git a/zcash-haskell.cabal b/zcash-haskell.cabal index 361d33e..4cbdb81 100644 --- a/zcash-haskell.cabal +++ b/zcash-haskell.cabal @@ -5,7 +5,7 @@ cabal-version: 3.0 -- see: https://github.com/sol/hpack name: zcash-haskell -version: 0.6.1.1 +version: 0.7.8.0 synopsis: Utilities to interact with the Zcash blockchain description: Please see the README on the repo at category: Blockchain @@ -58,7 +58,8 @@ library , binary , text , haskoin-core - , secp256k1-haskell + , secp256k1-haskell >= 1.1 + , vector , utf8-string build-tool-depends: c2hs:c2hs @@ -85,5 +86,6 @@ test-suite zcash-haskell-test , binary , cryptonite , secp256k1-haskell + , http-conduit pkgconfig-depends: rustzcash_wrapper default-language: Haskell2010