Compare commits

..

46 commits

Author SHA1 Message Date
dea960c2ac
Functions to handle commitment tree nodes for Sapling and Orchard ()
This PR includes the functions for hashing commitment nodes for both Sapling and Orchard. It also includes functions to validate tree roots and Merkle paths.

Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/100
Co-authored-by: Rene Vergara <rene@vergara.network>
Co-committed-by: Rene Vergara <rene@vergara.network>
2024-11-15 18:48:36 +00:00
62cda9cc15
docs: version bump 2024-11-05 12:42:03 -06:00
5ce149c54f
Functions to create and manage Orchard commitment trees ()
This PR contains the functions to create, update and validate Orchard commitment trees.

Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/99
Co-authored-by: Rene Vergara <rene@vergara.network>
Co-committed-by: Rene Vergara <rene@vergara.network>
2024-11-05 18:28:45 +00:00
6d4b6840d3
Optimize transaction creation ()
Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/98
Co-authored-by: Rene Vergara <rene@vergara.network>
Co-committed-by: Rene Vergara <rene@vergara.network>
2024-10-30 16:47:11 +00:00
662a0d1148
Merge pull request 'Implement Frontier for Sapling' () from rav001 into milestone2
Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/97
2024-10-18 19:40:35 +00:00
4608577c41
docs: version bump 2024-10-18 14:39:05 -05:00
5a9ed11c25
fix(rust): SaplingFrontier marshalling 2024-10-18 12:25:30 -05:00
96cfe3a52a
feat: use SaplingFrontier for witnesses 2024-10-18 09:43:02 -05:00
3203c7e8ff
feat: implement Frontier for Sapling witnesses 2024-10-18 08:47:52 -05:00
396f15140a
Merge pull request 'feat: add toJSON for BlockResponse' () from rav001 into milestone2
Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/96
2024-10-11 13:19:08 +00:00
5a08c80285
feat: add toJSON for BlockResponse 2024-10-11 08:17:02 -05:00
003293cc3f
Merge pull request 'Orchard anchor and witness updates' () from rav001 into milestone2
Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/95
2024-10-01 12:51:41 +00:00
612ce812ef
Merge branch 'milestone2' into rav001 2024-10-01 07:15:15 -05:00
3969490283
feat: Use the notes to determine anchors 2024-09-30 14:50:54 -05:00
38e4131daa
feat!: update Orchard witness calculation
Now uses Frontier
2024-09-30 13:18:47 -05:00
48afd81595
feat!: migrate Orchard commitment trees to Frontier 2024-09-30 12:11:47 -05:00
12296026a0
Merge pull request 'Improve witness update functions.' () from rav001 into milestone2
Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/94
2024-09-25 19:47:43 +00:00
5de1844e9d
feat: improve witness updates 2024-09-25 14:43:11 -05:00
36fd2e59a4
Merge branch 'milestone2' into rav001 2024-09-23 10:20:10 -05:00
63a97b880c
Merge pull request 'Add block hash to BlockResponse' () from rav001 into milestone2
Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/93
2024-09-23 15:19:31 +00:00
f24ea80cde
feat: add block hash to BlockResponse 2024-09-23 10:17:35 -05:00
9df346389a
Merge branch 'milestone2' into rav001 2024-09-18 07:30:27 -05:00
91e2ebbabd
Merge pull request 'Add privacy policy error to TxError' () from rav001 into milestone2
Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/92
2024-09-18 12:29:35 +00:00
343495f6e7
feat: add privacy policy error to TxError 2024-09-18 07:27:53 -05:00
7350723801
Merge branch 'milestone2' into rav001 2024-09-17 13:09:54 -05:00
7965dc38c4
Merge pull request 'docs: update version' () from rav001 into milestone2
Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/91
2024-09-17 18:08:09 +00:00
ee165de652
Merge branch 'milestone2' into rav001 2024-09-17 18:07:54 +00:00
1f1ca4e206
docs: update version 2024-09-17 13:06:28 -05:00
f1e1570b25
Merge pull request 'Implement wagyu-zcash-parameters in Rust bindings' () from rav001 into milestone2
Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/90
2024-09-16 18:47:50 +00:00
5a8cd44fbc
feat: implement wagyu-zcash-parameters crate 2024-09-16 13:36:49 -05:00
cedc3a0cc1
Merge branch 'milestone2' into rav001 2024-08-30 11:19:07 -05:00
ce19e174cc
Merge pull request 'fix: decode unified addresses with no transparent receivers' () from rav001 into milestone2
Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/89
2024-08-30 16:12:13 +00:00
85a4741dcb
fix: decode unified addresses with no transparent receivers
ensures that a unified address that does not contain a transparent
receiver is properly represented in the type
2024-08-30 11:02:52 -05:00
0b2fae2b5d
Merge pull request 'Add JSON instances for Transaction' () from rav001 into milestone2
Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/88
2024-08-20 21:05:02 +00:00
b4069d6233
Merge branch 'milestone2' into rav001 2024-08-20 15:53:31 -05:00
c8f411fcdd
add JSON instances for Transaction 2024-08-20 15:50:07 -05:00
939ae687e8
Merge pull request 'Implement address comparison and validation' () from rav001 into milestone2
Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/87
2024-08-14 17:35:27 +00:00
e1622a0d7f
Merge branch 'milestone2' into rav001 2024-08-14 17:35:03 +00:00
774e135aab
Fix data type 2024-08-14 12:32:48 -05:00
b7c91e10fe
Add functions to compare and validate addresses 2024-08-14 12:32:30 -05:00
cbbdfe42af
Merge pull request 'Add ValidAddress' () from rav001 into milestone2
Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/86
2024-08-13 12:58:21 +00:00
9ca702a68e
Add ValidAddress 2024-08-13 07:56:25 -05:00
cc72fadef3
Merge pull request 'Add JSON instances for ZcashNet' () from rav001 into milestone2
Reviewed-on: https://git.vergara.tech/Vergara_Tech/zcash-haskell/pulls/85
2024-07-25 16:14:03 +00:00
7c79ee6163
Add JSON instances for ZcashNet 2024-07-25 11:09:17 -05:00
e8074419cf
Merge branch 'milestone2' of git.vergara.tech:Vergara_Tech/zcash-haskell into milestone2 2024-07-02 13:21:39 -05:00
90c8a7c302
Merge pull request 'Performance enhancement for transaction creation' () from rav001 into milestone2
Reviewed-on: https://git.vergara.tech/Vergara_Tech/zcash-haskell/pulls/83
2024-05-16 15:45:20 +00:00
16 changed files with 590 additions and 1860 deletions

View file

@ -5,58 +5,6 @@ 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.8.1.0]
### Fixed
- Producing nullifiers from decoding with viewing keys
## [0.8.0.0]
### Added
- `UnifiedIncomingViewingKey` type
- `ValidVk` type
- Address derivation from full viewing keys
- Address derivation from incoming viewing keys
- Orchard note decoding with full viewing key
- Orchard note decoding with incoming viewing key
- Sapling note decoding with full viewing key
- Sapling note decoding with incoming viewing key
### Fixed
- Transparent viewing key component generation
## [0.7.8.1]
### Changed
- Referenced libraries updated to use the new Vergara Tech git server
## [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

View file

@ -4,10 +4,10 @@ with-compiler: ghc-9.6.5
source-repository-package
type: git
location: https://code.vergara.tech/Vergara_Tech/haskell-foreign-rust.git
location: https://git.vergara.tech/Vergara_Tech/haskell-foreign-rust.git
tag: 335e804454cd30da2c526457be37e477f71e4665
source-repository-package
type: git
location: https://code.vergara.tech/Vergara_Tech/haskell-hexstring.git
location: https://git.vergara.tech/Vergara_Tech/haskell-hexstring.git
tag: 39d8da7b11a80269454c2f134a5c834e0f3cb9a7

View file

@ -3,13 +3,13 @@ constraints: any.Cabal ==3.10.3.0,
any.Cabal-syntax ==3.10.3.0,
any.HUnit ==1.6.2.0,
any.OneTuple ==0.4.2,
any.QuickCheck ==2.15.0.1,
any.QuickCheck ==2.14.3,
QuickCheck -old-random +templatehaskell,
any.StateVar ==1.2.2,
any.aeson ==2.2.3.0,
aeson +ordered-keymap,
any.alex ==3.5.2.0,
any.ansi-terminal ==1.1.2,
any.alex ==3.5.1.0,
any.ansi-terminal ==1.1.1,
ansi-terminal -example,
any.ansi-terminal-types ==1.1,
any.appar ==0.1.8,
@ -25,7 +25,7 @@ constraints: any.Cabal ==3.10.3.0,
attoparsec -developer,
any.attoparsec-aeson ==2.2.2.0,
any.base ==4.18.2.1,
any.base-orphans ==0.9.3,
any.base-orphans ==0.9.2,
any.base16 ==1.0,
any.base16-bytestring ==1.0.2.0,
any.base58-bytestring ==0.1.0,
@ -40,7 +40,7 @@ constraints: any.Cabal ==3.10.3.0,
any.blaze-builder ==0.4.2.3,
any.borsh ==0.3.0,
any.byteorder ==1.0.4,
any.bytes ==0.17.4,
any.bytes ==0.17.3,
any.bytestring ==0.11.5.3,
any.c2hs ==0.28.8,
c2hs +base3 -regression,
@ -52,25 +52,28 @@ constraints: any.Cabal ==3.10.3.0,
cereal -bytestring-builder,
any.character-ps ==0.1,
any.colour ==2.3.6,
any.comonad ==5.0.9,
any.comonad ==5.0.8,
comonad +containers +distributive +indexed-traversable,
any.conduit ==1.3.6,
any.conduit-extra ==1.3.7,
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 ==1.0.1,
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.4.3,
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.13,
any.crypton-x509-validation ==1.6.12,
any.cryptonite ==0.30,
cryptonite -check_alignment +integer-gmp -old_toolchain_inliner +support_aesni +support_deepseq -support_pclmuldq +support_rdrand -support_sse +use_target_attributes,
any.data-default ==0.8.0.0,
any.data-default-class ==0.2.0.0,
any.data-default ==0.7.1.1,
any.data-default-class ==0.1.2.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.4,
any.deepseq ==1.4.8.1,
any.directory ==1.3.8.4,
@ -78,9 +81,9 @@ constraints: any.Cabal ==3.10.3.0,
distributive +semigroups +tagged,
any.dlist ==1.0,
dlist -werror,
any.entropy ==0.4.1.11,
any.entropy ==0.4.1.10,
entropy -donotgetentropy,
any.envy ==2.1.4.0,
any.envy ==2.1.3.0,
any.exceptions ==0.10.7,
any.filepath ==1.4.300.1,
any.foreign-rust ==0.1.0,
@ -89,61 +92,56 @@ constraints: any.Cabal ==3.10.3.0,
any.ghc-bignum ==1.3,
any.ghc-boot-th ==9.6.5,
any.ghc-prim ==0.10.0,
any.half ==0.3.2,
any.happy ==2.1.4,
any.happy-lib ==2.1.4,
any.hashable ==1.5.0.0,
hashable -arch-native -random-initial-seed,
any.haskell-lexer ==1.1.2,
any.half ==0.3.1,
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.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.10,
any.hspec-core ==2.11.10,
any.hspec-discover ==2.11.10,
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.18,
any.http-client ==0.7.17,
http-client +network-uri,
any.http-client-tls ==0.3.6.4,
any.http-conduit ==2.3.9.1,
any.http-client-tls ==0.3.6.3,
any.http-conduit ==2.3.9,
http-conduit +aeson,
any.http-types ==0.12.4,
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.4,
any.integer-logarithms ==1.0.3.1,
integer-logarithms -check-bounds +integer-gmp,
any.iproute ==1.7.15,
any.language-c ==0.10.0,
language-c +iecfpextension +usebytestrings,
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.21.0,
any.mono-traversable ==1.0.20.0,
any.mtl ==2.3.1,
any.murmur3 ==1.0.5,
any.network ==3.2.7.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.optparse-applicative ==0.18.1.0,
optparse-applicative +process,
any.os-string ==2.0.7,
any.os-string ==2.0.6,
any.parsec ==3.1.16.1,
any.pem ==0.2.4,
any.pretty ==1.1.3.6,
any.prettyprinter ==1.7.1,
prettyprinter -buildreadme +text,
any.prettyprinter-ansi-terminal ==1.1.3,
any.primitive ==0.9.0.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.3,
any.random ==1.2.1.2,
any.regex-base ==0.94.0.2,
any.regex-compat ==0.95.2.1,
any.regex-posix ==0.96.0.1,
@ -153,7 +151,7 @@ constraints: any.Cabal ==3.10.3.0,
any.safe ==0.3.21,
any.scientific ==0.3.8.0,
scientific -integer-simple,
any.secp256k1-haskell ==1.4.2,
any.secp256k1-haskell ==1.4.0,
any.semialign ==1.3.1,
semialign +semigroupoids,
any.semigroupoids ==6.0.1,
@ -163,44 +161,42 @@ constraints: any.Cabal ==3.10.3.0,
any.socks ==0.6.1,
any.sop-core ==0.5.0.2,
any.split ==0.2.5,
any.splitmix ==0.1.1,
any.splitmix ==0.1.0.5,
splitmix -optimised-mixer,
any.stm ==2.5.1.0,
any.streaming-commons ==0.2.3.0,
any.streaming-commons ==0.2.2.6,
streaming-commons -use-bytestring-builder,
any.strict ==0.5.1,
any.string-conversions ==0.4.0.1,
any.tagged ==0.8.9,
any.tagged ==0.8.8,
tagged +deepseq +transformers,
any.tasty ==1.5.3,
tasty +unix,
any.template-haskell ==2.20.0.0,
any.text ==2.0.2,
any.text-iso8601 ==0.1.1,
any.text-short ==0.1.6,
text-short -asserts,
any.tf-random ==0.5,
any.th-abstraction ==0.7.1.0,
any.th-compat ==0.1.6,
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.8,
any.tls ==2.1.7,
any.time-compat ==1.9.7,
any.tls ==2.1.0,
tls -devel,
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.12.0,
any.unix ==2.8.4.0,
any.unix-time ==0.4.16,
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.6,
any.vector ==0.13.2.0,
any.vector ==0.13.1.0,
vector +boundschecks -internalchecks -unsafechecks -wall,
any.vector-algorithms ==0.9.0.3,
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,
@ -209,4 +205,4 @@ constraints: any.Cabal ==3.10.3.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 2025-01-31T18:30:19Z
index-state: hackage.haskell.org 2024-10-11T12:55:31Z

File diff suppressed because it is too large Load diff

View file

@ -9,13 +9,13 @@ 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.9"
borsh = "0.10"
bech32 = "0.11"
orchard = "0.10.0"
zcash_note_encryption = "0.4.0"
zcash_primitives = { version = "0.21.0", features = ["transparent-inputs"]}
zcash_client_backend = "0.16.0"
sapling-crypto = "0.4"
zcash_primitives = { version = "0.19.0", features = ["transparent-inputs"]}
zcash_client_backend = "0.14.0"
sapling-crypto = "0.3"
zip32 = "0.1.2"
proc-macro2 = "1.0.66"
nonempty = "0.7.0"
@ -25,7 +25,6 @@ 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]

View file

@ -1,4 +1,4 @@
[toolchain]
channel = "nightly"
channel = "nightly-2024-02-04"
components = [ "rustfmt", "rustc-dev"]
profile = "minimal"

View file

@ -66,8 +66,7 @@ use sapling_crypto::{
},
note_encryption::{
SaplingDomain,
Zip212Enforcement,
try_sapling_note_decryption
Zip212Enforcement
},
bundle::{
GrothProofBytes,
@ -83,8 +82,7 @@ use sapling_crypto::{
},
zip32::{
sapling_find_address,
DiversifierKey,
IncomingViewingKey as SaplingIncomingViewingKey
DiversifierKey
}
};
@ -118,7 +116,6 @@ use zcash_primitives::{
},
transparent::{
Bundle as TransparentBundle,
builder::TransparentSigningSet,
TxIn,
TxOut,
OutPoint,
@ -137,7 +134,7 @@ use zcash_primitives::{
use zcash_address::{
Network,
unified::{Address, Encoding, Ufvk, Uivk, Ivk, Container, Fvk, Receiver},
unified::{Address, Encoding, Ufvk, Container, Fvk, Receiver},
ZcashAddress
};
@ -159,7 +156,7 @@ use orchard::{
Flags
},
Action,
keys::{SpendAuthorizingKey, SpendingKey, FullViewingKey, IncomingViewingKey, PreparedIncomingViewingKey, Scope},
keys::{SpendingKey, FullViewingKey, PreparedIncomingViewingKey, Scope},
note::{Rho, RandomSeed, Note, Nullifier, TransmittedNoteCiphertext, ExtractedNoteCommitment},
note_encryption::OrchardDomain,
primitives::redpallas::{VerificationKey, SpendAuth, Signature},
@ -692,35 +689,6 @@ impl Hufvk {
}
}
#[derive(Debug, BorshSerialize, BorshDeserialize)]
pub struct Huivk {
net: u8,
orchard: Vec<u8>,
sapling: Vec<u8>,
transparent: Vec<u8>
}
impl<RW> ToHaskell<RW> for Huivk {
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> 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<u8>,
@ -999,34 +967,6 @@ 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,
@ -1145,116 +1085,6 @@ pub extern "C" fn rust_wrapper_sapling_note_decrypt_v2(
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_sapling_note_decrypt_fvk(
key: *const u8,
key_len: usize,
note: *const u8,
note_len: usize,
scope: bool,
pos: u64,
out: *mut u8,
out_len: &mut usize
){
let dfvk: Vec<u8> = marshall_from_haskell_var(key, key_len, RW);
let mut note_input: HshieldedOutput = marshall_from_haskell_var(note,note_len,RW);
let svk = DiversifiableFullViewingKey::from_bytes(&to_array(dfvk));
if svk.is_some().into() {
let domain = SaplingDomain::new(Zip212Enforcement::On);
let action2 = note_input.to_output_description();
match action2 {
Ok(action3) => {
let nk =
if scope {
svk.clone().unwrap().to_nk(SaplingScope::External)
} else {
svk.clone().unwrap().to_nk(SaplingScope::Internal)
};
let fvk =
if scope {
svk.unwrap().to_ivk(SaplingScope::External)
} else {
svk.unwrap().to_ivk(SaplingScope::Internal)
};
let pivk = SaplingPreparedIncomingViewingKey::new(&fvk);
let result = zcash_note_encryption::try_note_decryption(&domain, &pivk, &action3);
match result {
Some((n, r, m)) => {
let rseed = match n.rseed() {
Rseed::BeforeZip212(x) => {
Hrseed { kind: 1, bytes: x.to_bytes().to_vec()}
},
Rseed::AfterZip212(y) => {
Hrseed { kind: 2, bytes: y.to_vec()}
}
};
let hn = Hnote {note: n.value().inner(), recipient: r.to_bytes().to_vec(), memo: m.as_slice().to_vec(), nullifier: n.nf(&nk, pos).to_vec(), rho: vec![0], rseed};
marshall_to_haskell_var(&hn, out, out_len, RW);
}
None => {
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
marshall_to_haskell_var(&hn0, out, out_len, RW);
}
}
},
Err(_e1) => {
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0] , nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
marshall_to_haskell_var(&hn0, out, out_len, RW);
}
}
} else {
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
marshall_to_haskell_var(&hn0, out, out_len, RW);
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_sapling_note_decrypt_ivk(
key: *const u8,
key_len: usize,
note: *const u8,
note_len: usize,
out: *mut u8,
out_len: &mut usize
){
let ivk: Vec<u8> = marshall_from_haskell_var(key, key_len, RW);
let mut note_input: HshieldedOutput = marshall_from_haskell_var(note,note_len,RW);
let svk = SaplingIncomingViewingKey::from_bytes(&to_array(ivk));
if svk.is_some().into() {
let action2 = note_input.to_output_description();
match action2 {
Ok(action3) => {
let result = try_sapling_note_decryption(&svk.unwrap().prepare(), &action3, Zip212Enforcement::On);
match result {
Some((n, r, m)) => {
let rseed = match n.rseed() {
Rseed::BeforeZip212(x) => {
Hrseed { kind: 1, bytes: x.to_bytes().to_vec()}
},
Rseed::AfterZip212(y) => {
Hrseed { kind: 2, bytes: y.to_vec()}
}
};
let hn = Hnote {note: n.value().inner(), recipient: r.to_bytes().to_vec(), memo: m.as_slice().to_vec(), nullifier: vec![0], rho: vec![0], rseed};
marshall_to_haskell_var(&hn, out, out_len, RW);
}
None => {
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
marshall_to_haskell_var(&hn0, out, out_len, RW);
}
}
},
Err(_e1) => {
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0] , nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
marshall_to_haskell_var(&hn0, out, out_len, RW);
}
}
} else {
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
marshall_to_haskell_var(&hn0, out, out_len, RW);
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_orchard_note_decrypt(
key: *const u8,
@ -1301,99 +1131,6 @@ pub extern "C" fn rust_wrapper_orchard_note_decrypt(
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_orchard_note_decrypt_fvk(
key: *const u8,
key_len: usize,
note: *const u8,
note_len: usize,
external: bool,
out: *mut u8,
out_len: &mut usize
){
let fvk_input: Vec<u8> = marshall_from_haskell_var(key, key_len, RW);
let note_input: Haction = marshall_from_haskell_var(note, note_len, RW);
let action: Action<Signature<SpendAuth>> = Action::from_parts(
Nullifier::from_bytes(&to_array(note_input.nf.bytes)).unwrap(),
VerificationKey::try_from(to_array(note_input.rk.bytes)).unwrap(),
ExtractedNoteCommitment::from_bytes(&to_array(note_input.cmx.bytes)).unwrap(),
TransmittedNoteCiphertext {epk_bytes: to_array(note_input.eph_key.bytes), enc_ciphertext: to_array(note_input.enc_txt.bytes), out_ciphertext: to_array(note_input.out_txt.bytes)},
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_action(&action);
let dec_fvk = FullViewingKey::from_bytes(&fvk_array);
match dec_fvk {
Some(fvk) => {
let ivk = if external {
fvk.to_ivk(Scope::External)
} else {
fvk.to_ivk(Scope::Internal)
};
let pivk = PreparedIncomingViewingKey::new(&ivk);
let result = zcash_note_encryption::try_note_decryption(&domain, &pivk, &action);
match result {
Some((n, r, m)) => {
let rho = n.rho().to_bytes().to_vec();
let rseed = Hrseed {kind: 3, bytes: n.rseed().as_bytes().to_vec()};
let hn = Hnote {note: n.value().inner(), recipient: r.to_raw_address_bytes().to_vec(), memo: m.to_vec(), nullifier: n.nullifier(&fvk).to_bytes().to_vec(), rho, rseed};
marshall_to_haskell_var(&hn, out, out_len, RW);
}
None => {
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
marshall_to_haskell_var(&hn0, out, out_len, RW);
}
}
},
None => {
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
marshall_to_haskell_var(&hn0, out, out_len, RW);
}
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_orchard_note_decrypt_ivk(
key: *const u8,
key_len: usize,
note: *const u8,
note_len: usize,
out: *mut u8,
out_len: &mut usize
){
let ivk_input: Vec<u8> = marshall_from_haskell_var(key, key_len, RW);
let note_input: Haction = marshall_from_haskell_var(note, note_len, RW);
let action: Action<Signature<SpendAuth>> = Action::from_parts(
Nullifier::from_bytes(&to_array(note_input.nf.bytes)).unwrap(),
VerificationKey::try_from(to_array(note_input.rk.bytes)).unwrap(),
ExtractedNoteCommitment::from_bytes(&to_array(note_input.cmx.bytes)).unwrap(),
TransmittedNoteCiphertext {epk_bytes: to_array(note_input.eph_key.bytes), enc_ciphertext: to_array(note_input.enc_txt.bytes), out_ciphertext: to_array(note_input.out_txt.bytes)},
ValueCommitment::from_bytes(&to_array(note_input.cv.bytes)).unwrap(),
Signature::from(to_array(note_input.auth.bytes)));
let ivk_array = to_array(ivk_input);
let domain = OrchardDomain::for_action(&action);
let dec_fvk = IncomingViewingKey::from_bytes(&ivk_array);
if dec_fvk.is_some().into() {
let pivk = PreparedIncomingViewingKey::new(&dec_fvk.unwrap());
let result = zcash_note_encryption::try_note_decryption(&domain, &pivk, &action);
match result {
Some((n, r, m)) => {
let rho = n.rho().to_bytes().to_vec();
let rseed = Hrseed {kind: 3, bytes: n.rseed().as_bytes().to_vec()};
let hn = Hnote {note: n.value().inner(), recipient: r.to_raw_address_bytes().to_vec(), memo: m.to_vec(), nullifier: vec![0], rho, rseed};
marshall_to_haskell_var(&hn, out, out_len, RW);
}
None => {
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
marshall_to_haskell_var(&hn0, out, out_len, RW);
}
}
} else {
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
marshall_to_haskell_var(&hn0, out, out_len, RW);
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_orchard_note_decrypt_sk(
key: *const u8,
@ -1575,22 +1312,31 @@ pub extern "C" fn rust_wrapper_sapling_paymentaddress(
out_len: &mut usize
){
let extspk: Vec<u8> = marshall_from_haskell_var(extspk, extspk_len, RW);
if div_ix == 0 {
let sp_key = ExtendedSpendingKey::from_bytes(&extspk);
match sp_key {
Ok(sp_key_x) => {
let (_def_div, def_address) =
if div_ix == 0 {
sp_key_x.default_address()
} else {
let dfvk = sp_key_x.to_diversifiable_full_viewing_key();
dfvk.find_address(DiversifierIndex::from(div_ix)).unwrap()
};
let (_def_div, def_address) = sp_key_x.default_address();
marshall_to_haskell_var(&def_address.to_bytes().to_vec(), out, out_len, RW);
},
Err(_e) => {
marshall_to_haskell_var(&vec![0], out, out_len, RW);
}
}
} else {
let expsk = ExpandedSpendingKey::from_spending_key(&extspk);
let fvk = SaplingFullViewingKey::from_expanded_spending_key(&expsk);
let dk = DiversifierKey::master(&extspk);
let result = sapling_find_address(&fvk, &dk, DiversifierIndex::from(div_ix));
match result {
Some((_d, p_address)) => {
marshall_to_haskell_var(&p_address.to_bytes().to_vec(), out, out_len, RW);
},
None => {
marshall_to_haskell_var(&vec![0], out, out_len, RW);
}
}
}
}
#[no_mangle]
@ -1616,91 +1362,6 @@ pub extern "C" fn rust_wrapper_sapling_chgpaymentaddress(
marshall_to_haskell_var(&cPmtAddress.to_bytes().to_vec(), out, out_len, RW);
}
#[no_mangle]
pub extern "C" fn rust_wrapper_sapling_receiver_fvk(
fvk_in: *const u8,
fvk_in_len: usize,
div_ix: u32,
out: *mut u8,
out_len: &mut usize
){
let fvk_bytes: Vec<u8> = marshall_from_haskell_var(fvk_in, fvk_in_len, RW);
let fvk = DiversifiableFullViewingKey::from_bytes(&to_array(fvk_bytes));
if div_ix == 0 {
match fvk {
Some(k) => {
let (_def_div, def_address) = k.default_address();
marshall_to_haskell_var(&def_address.to_bytes().to_vec(), out, out_len, RW);
},
None => {
marshall_to_haskell_var(&vec![0], out, out_len, RW);
}
}
} else {
match fvk {
Some(k) => {
let result = k.find_address(DiversifierIndex::from(div_ix));
match result {
Some((_d, p_address)) => {
marshall_to_haskell_var(&p_address.to_bytes().to_vec(), out, out_len, RW);
},
None => {
marshall_to_haskell_var(&vec![0], out, out_len, RW);
}
}
},
None => {
marshall_to_haskell_var(&vec![0], out, out_len, RW);
}
}
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_sapling_change_receiver_fvk(
fvk_in: *const u8,
fvk_in_len: usize,
out: *mut u8,
out_len: &mut usize
){
let fvk_bytes: Vec<u8> = marshall_from_haskell_var(fvk_in, fvk_in_len, RW);
let dfvk = DiversifiableFullViewingKey::from_bytes(&to_array(fvk_bytes));
match dfvk {
Some(k) => {
let ( _div_ix, chg_address ) = k.change_address();
marshall_to_haskell_var(&chg_address.to_bytes().to_vec(), out, out_len, RW);
},
None => {
marshall_to_haskell_var(&vec![0], out, out_len, RW);
}
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_sapling_receiver_ivk(
ivk_in: *const u8,
ivk_in_len: usize,
div_ix: u32,
out: *mut u8,
out_len: &mut usize
){
let ivk_bytes: Vec<u8> = marshall_from_haskell_var(ivk_in, ivk_in_len, RW);
let ivk = SaplingIncomingViewingKey::from_bytes(&to_array(ivk_bytes));
if ivk.is_some().into() {
let result = ivk.unwrap().find_address(DiversifierIndex::from(div_ix));
match result {
Some((_d, p_address)) => {
marshall_to_haskell_var(&p_address.to_bytes().to_vec(), out, out_len, RW);
},
None => {
marshall_to_haskell_var(&vec![0], out, out_len, RW);
}
}
} else {
marshall_to_haskell_var(&vec![0], out, out_len, RW);
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_derive_orchard_spending_key(
seed: *const u8,
@ -1742,49 +1403,6 @@ pub extern "C" fn rust_wrapper_derive_orchard_receiver(
}
#[no_mangle]
pub extern "C" fn rust_wrapper_derive_orchard_receiver_fvk(
f_key: *const u8,
f_key_len: usize,
add_id: u32,
scope: bool,
out: *mut u8,
out_len: &mut usize
){
let vk_in: Vec<u8> = marshall_from_haskell_var(f_key, f_key_len, RW);
let fvk = FullViewingKey::from_bytes(&to_array(vk_in));
let sc = if scope {
Scope::External
} else {Scope::Internal};
match fvk {
Some(k) => {
let o_rec = k.address_at(add_id, sc);
marshall_to_haskell_var(&o_rec.to_raw_address_bytes().to_vec(), out, out_len, RW);
},
None => {
marshall_to_haskell_var(&vec![0], out, out_len, RW);
}
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_derive_orchard_receiver_ivk(
f_key: *const u8,
f_key_len: usize,
add_id: u32,
out: *mut u8,
out_len: &mut usize
){
let vk_in: Vec<u8> = marshall_from_haskell_var(f_key, f_key_len, RW);
let ivk = IncomingViewingKey::from_bytes(&to_array(vk_in));
if ivk.is_some().into() {
let o_rec = ivk.unwrap().address_at(add_id);
marshall_to_haskell_var(&o_rec.to_raw_address_bytes().to_vec(), out, out_len, RW);
} else {
marshall_to_haskell_var(&vec![0], out, out_len, RW);
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_bech32_encode(
hr: *const u8,
@ -2555,13 +2173,12 @@ pub extern "C" fn rust_wrapper_create_transaction(
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<HtransparentInput> = 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(tss.add_key(k), t_in.utxo.unpack(), t_in.coin.unpack()) {
match main_builder.add_transparent_input(k, t_in.utxo.unpack(), t_in.coin.unpack()) {
Ok(()) => {
//println!("added t-input in main");
continue;
@ -2569,7 +2186,7 @@ pub extern "C" fn rust_wrapper_create_transaction(
Err(_e) => { println!("Error reading transparent input"); }
}
} else {
match test_builder.add_transparent_input(tss.add_key(k), t_in.utxo.unpack(), t_in.coin.unpack()) {
match test_builder.add_transparent_input(k, t_in.utxo.unpack(), t_in.coin.unpack()) {
Ok(()) => {
//println!("added t-input in test");
continue;
@ -2579,14 +2196,12 @@ pub extern "C" fn rust_wrapper_create_transaction(
}
}
}
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())
@ -2601,9 +2216,8 @@ pub extern "C" fn rust_wrapper_create_transaction(
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::<String>(fvk, note, merkle_path);
let mb = main_builder.add_sapling_spend::<String>(&sk, note, merkle_path);
match mb {
Ok(()) => {
continue;
@ -2614,7 +2228,7 @@ pub extern "C" fn rust_wrapper_create_transaction(
}
}
} else {
let tb = test_builder.add_sapling_spend::<String>(fvk, note, merkle_path);
let tb = test_builder.add_sapling_spend::<String>(&sk, note, merkle_path);
match tb {
Ok(()) => {
continue;
@ -2633,11 +2247,9 @@ pub extern "C" fn rust_wrapper_create_transaction(
}
}
}
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 = Rho::from_bytes(&to_array(o_in.note.rho)).unwrap();
let rseed = RandomSeed::from_bytes(to_array(o_in.note.rseed.bytes), &rho).unwrap();
@ -2652,7 +2264,7 @@ pub extern "C" fn rust_wrapper_create_transaction(
}
).collect()));
if net {
let mb = main_builder.add_orchard_spend::<String>(FullViewingKey::from(&sp_key), note, merkle_path);
let mb = main_builder.add_orchard_spend::<String>(&sp_key, note, merkle_path);
match mb {
Ok(()) => {
//println!("added orchard inp: {:?}", val);
@ -2665,7 +2277,7 @@ pub extern "C" fn rust_wrapper_create_transaction(
}
}
} else {
let tb = test_builder.add_orchard_spend::<String>(FullViewingKey::from(&sp_key), note, merkle_path);
let tb = test_builder.add_orchard_spend::<String>(&sp_key, note, merkle_path);
match tb {
Ok(()) => {
//println!("added orchard inp: {:?}", val);
@ -2809,9 +2421,9 @@ pub extern "C" fn rust_wrapper_create_transaction(
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(&tss, &sap_key_array, &orch_keys, OsRng, &spend_prover, &output_prover, &FeeRule::standard())
main_builder.build(OsRng, &spend_prover, &output_prover, &FeeRule::standard())
} else {
test_builder.build(&tss, &sap_key_array, &orch_keys,OsRng, &spend_prover, &output_prover, &FeeRule::standard())
test_builder.build(OsRng, &spend_prover, &output_prover, &FeeRule::standard())
};
match result {
Ok(r) => {
@ -2889,87 +2501,3 @@ 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<u8> = 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<u8> = 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<u8> = 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<u8> = 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);
}
}
}

View file

@ -120,13 +120,6 @@ 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'&
@ -135,23 +128,6 @@ import ZcashHaskell.Types
-> `()'
#}
{# fun unsafe rust_wrapper_orchard_note_decrypt_fvk as rustWrapperOrchardNoteDecodeFvk
{ toBorshVar* `BS.ByteString'&
, toBorshVar* `OrchardAction'&
, `Bool'
, getVarBuffer `Buffer DecodedNote'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_orchard_note_decrypt_ivk as rustWrapperOrchardNoteDecodeIvk
{ toBorshVar* `BS.ByteString'&
, toBorshVar* `OrchardAction'&
, getVarBuffer `Buffer DecodedNote'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_orchard_note_decrypt_sk as rustWrapperOrchardNoteDecodeSK
{ toBorshVar* `BS.ByteString'&
, toBorshVar* `OrchardAction'&
@ -227,23 +203,6 @@ import ZcashHaskell.Types
-> `()'
#}
{# fun unsafe rust_wrapper_derive_orchard_receiver_fvk as rustWrapperGenOrchardReceiverFvk
{ toBorshVar* `BS.ByteString'&
, `Word32'
, `Bool'
, getVarBuffer `Buffer (BS.ByteString)'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_derive_orchard_receiver_ivk as rustWrapperGenOrchardReceiverIvk
{ toBorshVar* `BS.ByteString'&
, `Word32'
, getVarBuffer `Buffer (BS.ByteString)'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_read_sapling_commitment_tree as rustWrapperReadSaplingCommitmentTree
{ toBorshVar* `SaplingFrontier'&
, toBorshVar* `BS.ByteString'&
@ -451,72 +410,3 @@ 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'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_sapling_receiver_fvk as rustWrapperSaplingReceiverFvk
{ toBorshVar* `BS.ByteString'&
, `Word32'
, getVarBuffer `Buffer BS.ByteString'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_sapling_receiver_ivk as rustWrapperSaplingReceiverIvk
{ toBorshVar* `BS.ByteString'&
, `Word32'
, getVarBuffer `Buffer BS.ByteString'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_sapling_change_receiver_fvk as rustWrapperSaplingChgReceiverFvk
{ toBorshVar* `BS.ByteString'&
, getVarBuffer `Buffer BS.ByteString'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_sapling_note_decrypt_fvk as rustWrapperSaplingDecodeFvk
{ toBorshVar* `BS.ByteString'&
, toBorshVar* `ShieldedOutput'&
, `Bool'
, `Int64'
, getVarBuffer `Buffer DecodedNote'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_sapling_note_decrypt_ivk as rustWrapperSaplingDecodeIvk
{ toBorshVar* `BS.ByteString'&
, toBorshVar* `ShieldedOutput'&
, getVarBuffer `Buffer DecodedNote'&
}
-> `()'
#}

View file

@ -1,5 +1,3 @@
{-# LANGUAGE OverloadedStrings #-}
-- Copyright 2022-2024 Vergara Technologies LLC
-- This file is part of Zcash-Haskell.
--
@ -17,47 +15,13 @@
module ZcashHaskell.Keys where
import C.Zcash (rustWrapperGenSeedPhrase, rustWrapperGetSeed)
import Crypto.Secp256k1 (PubKey(..), createContext, exportPubKey)
import qualified Data.Binary as Bi
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BSL
import Data.HexString (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 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(..)
, UnifiedFullViewingKey(..)
, UnifiedIncomingViewingKey(..)
, ValidVk(..)
, ZcashNet(..)
, uniFullViewingKeyHrp
, uniIncomingViewingKeyHrp
, uniTestFullViewingKeyHrp
, uniTestIncomingViewingKeyHrp
)
import ZcashHaskell.Utils (encodeBech32m, f4Jumble)
import ZcashHaskell.Types (Phrase, Seed(..), ToBytes(..))
-- | Generate a random seed that can be used to generate private keys for shielded addresses and transparent addresses.
generateWalletSeedPhrase :: IO Phrase
@ -72,138 +36,3 @@ 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 (XPubKey d p i c k) = deriveXPubKey ioCtx sk
let tPubKeyBytes = BSL.toStrict (Bi.encode c) <> exportPubKey ioCtx True k
if BS.length tPubKeyBytes == 65
then return tPubKeyBytes
else fail "Unable to get transparent key bytes"
-- | 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 (XPubKey d p i c k) = deriveXPubKey ioCtx childPrvKey
let tPubKeyBytes = BSL.toStrict (Bi.encode c) <> exportPubKey ioCtx True k
if BS.length tPubKeyBytes == 65
then return tPubKeyBytes
else fail "Unable to get transparent key bytes"
-- | Derive a Unified Full Viewing Key
deriveUfvk ::
ZcashNet
-> Maybe OrchardSpendingKey
-> Maybe SaplingSpendingKey
-> Maybe TransparentSpendingKey
-> IO ValidVk
deriveUfvk net okey skey tkey = do
tSec <- maybe (return BS.empty) deriveFullTransparentNode tkey
let oSec = deriveOrchardFvk =<< okey
let sSec = deriveSaplingFvk =<< skey
case oSec of
Nothing -> fail "Unable to derive Orchard viewing key"
Just oSec' -> do
return $
FullVk $
UnifiedFullViewingKey
(case net of
MainNet -> 1
TestNet -> 2)
(hexBytes oSec')
(maybe BS.empty hexBytes sSec)
tSec
-- | Derive a Unified Incoming Viewing Key
deriveUivk ::
ZcashNet
-> Maybe OrchardSpendingKey
-> Maybe SaplingSpendingKey
-> Maybe TransparentSpendingKey
-> IO ValidVk
deriveUivk net okey skey tkey = do
tSec <- maybe (return BS.empty) deriveIncomingTransparentNode tkey
let oSec = deriveOrchardIvk =<< okey
let sSec = deriveSaplingIvk =<< skey
case oSec of
Nothing -> fail "Unable to derive Orchard viewing key"
Just oSec' -> do
return $
IncomingVk $
UnifiedIncomingViewingKey
(case net of
MainNet -> 1
TestNet -> 2)
(hexBytes oSec')
(maybe BS.empty hexBytes sSec)
tSec
-- | Encode a Unified Viewing Key per [ZIP-316](https://zips.z.cash/zip-0316)
encodeVK ::
ValidVk -- ^ The viewing key
-> T.Text
encodeVK vk = encodeBech32m (E.encodeUtf8 hr) b
where
tReceiver =
if tvk /= BS.empty
then packReceiver 0x00 $ Just tvk
else packReceiver 0x00 Nothing
b = f4Jumble $ tReceiver <> sReceiver <> oReceiver <> padding
tvk =
case vk of
FullVk f -> t_key f
IncomingVk i -> i_t_key i
svk =
case vk of
FullVk f -> s_key f
IncomingVk i -> i_s_key i
ovk =
case vk of
FullVk f -> o_key f
IncomingVk i -> i_o_key i
znet =
case vk of
FullVk f ->
if net f == 1
then MainNet
else TestNet
IncomingVk i ->
if i_net i == 1
then MainNet
else TestNet
hr =
case vk of
FullVk _ ->
case znet of
MainNet -> uniFullViewingKeyHrp
TestNet -> uniTestFullViewingKeyHrp
IncomingVk _ ->
case znet of
MainNet -> uniIncomingViewingKeyHrp
TestNet -> uniTestIncomingViewingKeyHrp
sReceiver =
packReceiver 0x02 $
if svk /= BS.empty
then Just svk
else Nothing
oReceiver =
packReceiver 0x03 $
if ovk /= BS.empty
then Just ovk
else Nothing
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

View file

@ -19,18 +19,12 @@ module ZcashHaskell.Orchard where
import C.Zcash
( rustWrapperCombineOrchardNodes
, rustWrapperCreateOrchardFvk
, rustWrapperCreateOrchardIvk
, rustWrapperGenOrchardReceiver
, rustWrapperGenOrchardReceiverFvk
, rustWrapperGenOrchardReceiverIvk
, rustWrapperGenOrchardSpendKey
, rustWrapperGetOrchardRootTest
, rustWrapperOrchardAddNodeTest
, rustWrapperOrchardCheck
, rustWrapperOrchardNoteDecode
, rustWrapperOrchardNoteDecodeFvk
, rustWrapperOrchardNoteDecodeIvk
, rustWrapperOrchardNoteDecodeSK
, rustWrapperReadOrchardCommitmentTree
, rustWrapperReadOrchardFrontier
@ -43,7 +37,6 @@ import C.Zcash
, rustWrapperReadOrchardWitnessAnchor
, rustWrapperUADecode
, rustWrapperUfvkDecode
, rustWrapperUivkDecode
, rustWrapperUpdateOrchardWitness
)
import qualified Data.ByteString as BS
@ -97,35 +90,6 @@ genOrchardReceiver i scope osk =
(fromIntegral i)
(scope == External)
-- | Derives an Orchard receiver for the given full viewing key and index
genOrchardReceiverFvk ::
Int -- ^ The index of the address to be created
-> Scope -- ^ `External` for wallet addresses, `Internal` for change addresses
-> BS.ByteString -- ^ The full viewing key
-> Maybe OrchardReceiver
genOrchardReceiverFvk i scope osk =
if BS.length k /= 43
then Nothing
else Just $ OrchardReceiver k
where
k =
withPureBorshVarBuffer $
rustWrapperGenOrchardReceiverFvk osk (fromIntegral i) (scope == External)
-- | Derives an Orchard receiver for the given incoming viewing key and index
genOrchardReceiverIvk ::
Int -- ^ The index of the address to be created
-> BS.ByteString -- ^ The full viewing key
-> Maybe OrchardReceiver
genOrchardReceiverIvk i osk =
if BS.length k /= 43
then Nothing
else Just $ OrchardReceiver k
where
k =
withPureBorshVarBuffer $
rustWrapperGenOrchardReceiverIvk osk (fromIntegral i)
-- | Checks if given bytestring is a valid encoded unified address
isValidUnifiedAddress :: BS.ByteString -> Maybe UnifiedAddress
isValidUnifiedAddress str =
@ -193,15 +157,6 @@ 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
@ -218,30 +173,6 @@ decryptOrchardAction key encAction =
withPureBorshVarBuffer $
rustWrapperOrchardNoteDecode (o_key key) encAction
-- | Attempts to decode the given @OrchardAction@ using the given @UnifiedFullViewingKey@.
decryptOrchardActionFvk ::
UnifiedFullViewingKey -> Scope -> OrchardAction -> Maybe DecodedNote
decryptOrchardActionFvk key scope encAction =
case a_value decodedAction of
0 -> Nothing
_ -> Just decodedAction
where
decodedAction =
withPureBorshVarBuffer $
rustWrapperOrchardNoteDecodeFvk (o_key key) encAction (scope == External)
-- | Attempts to decode the given @OrchardAction@ using the given @UnifiedFullViewingKey@.
decryptOrchardActionIvk ::
UnifiedIncomingViewingKey -> OrchardAction -> Maybe DecodedNote
decryptOrchardActionIvk key encAction =
case a_value decodedAction of
0 -> Nothing
_ -> Just decodedAction
where
decodedAction =
withPureBorshVarBuffer $
rustWrapperOrchardNoteDecodeIvk (i_o_key key) encAction
getSaplingFromUA :: BS.ByteString -> Maybe T.Text
getSaplingFromUA uadd = do
let a = isValidUnifiedAddress uadd
@ -406,25 +337,3 @@ compareAddress a 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

View file

@ -19,8 +19,6 @@ module ZcashHaskell.Sapling where
import C.Zcash
( rustWrapperCombineSaplingNodes
, rustWrapperCreateSaplingFvk
, rustWrapperCreateSaplingIvk
, rustWrapperDecodeSaplingAddress
, rustWrapperGetSaplingRootTest
, rustWrapperIsShielded
@ -34,14 +32,9 @@ import C.Zcash
, rustWrapperReadSaplingWitness
, rustWrapperSaplingCheck
, rustWrapperSaplingChgPaymentAddress
, rustWrapperSaplingChgReceiverFvk
, rustWrapperSaplingDecodeEsk
, rustWrapperSaplingDecodeFvk
, rustWrapperSaplingDecodeIvk
, rustWrapperSaplingNoteDecode
, rustWrapperSaplingPaymentAddress
, rustWrapperSaplingReceiverFvk
, rustWrapperSaplingReceiverIvk
, rustWrapperSaplingSpendingkey
, rustWrapperSaplingVkDecode
, rustWrapperTxParse
@ -51,7 +44,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 (Int64, Int8)
import Data.Int (Int8)
import qualified Data.Text as T
import Data.Word
import Foreign.Rust.Marshall.Variable
@ -100,27 +93,6 @@ decodeSaplingOutput key out =
decodedAction =
withPureBorshVarBuffer $ rustWrapperSaplingNoteDecode key out
-- | Attempt to decode the given @ShieldedOutput@ using the given Sapling full viewing key
decodeSaplingOutputFvk ::
BS.ByteString -> ShieldedOutput -> Scope -> Int64 -> Maybe DecodedNote
decodeSaplingOutputFvk fvk so scope pos =
case a_value decodedAction of
0 -> Nothing
_ -> Just decodedAction
where
decodedAction =
withPureBorshVarBuffer $
rustWrapperSaplingDecodeFvk fvk so (scope == External) pos
-- | Attempt to decode the given @ShieldedOutput@ using the given Sapling incoming viewing key
decodeSaplingOutputIvk :: BS.ByteString -> ShieldedOutput -> Maybe DecodedNote
decodeSaplingOutputIvk fvk so =
case a_value decodedAction of
0 -> Nothing
_ -> Just decodedAction
where
decodedAction = withPureBorshVarBuffer $ rustWrapperSaplingDecodeIvk fvk so
instance FromJSON RawTxResponse where
parseJSON =
withObject "RawTxResponse" $ \obj -> do
@ -210,28 +182,6 @@ genSaplingPaymentAddress i extspk =
(getBytes extspk)
(fromIntegral (i * 111)))
-- | Attempts to generate a Sapling receiver using an full viewing key and a diversifier index
genSaplingReceiverFvk :: Int -> BS.ByteString -> Maybe SaplingReceiver
genSaplingReceiverFvk i fvk =
if BS.length res == 43
then Just $ SaplingReceiver res
else Nothing
where
res =
withPureBorshVarBuffer
(rustWrapperSaplingReceiverFvk fvk (fromIntegral (i * 111)))
-- | Attempts to generate a Sapling receiver using an incoming viewing key and a diversifier index
genSaplingReceiverIvk :: Int -> BS.ByteString -> Maybe SaplingReceiver
genSaplingReceiverIvk i ivk =
if BS.length res == 43
then Just $ SaplingReceiver res
else Nothing
where
res =
withPureBorshVarBuffer
(rustWrapperSaplingReceiverIvk ivk (fromIntegral (i * 111)))
-- | Generate an internal Sapling address
genSaplingInternalAddress :: SaplingSpendingKey -> Maybe SaplingReceiver
genSaplingInternalAddress sk =
@ -242,15 +192,6 @@ genSaplingInternalAddress sk =
res =
withPureBorshVarBuffer (rustWrapperSaplingChgPaymentAddress $ getBytes sk)
-- | Generate a change Sapling receiver from Full Viewing Key
genSaplingInternalAddressFvk :: BS.ByteString -> Maybe SaplingReceiver
genSaplingInternalAddressFvk fvk =
if BS.length res == 43
then Just $ SaplingReceiver res
else Nothing
where
res = withPureBorshVarBuffer (rustWrapperSaplingChgReceiverFvk fvk)
getSaplingNodeValue :: BS.ByteString -> Maybe HexString
getSaplingNodeValue cmu =
if BS.length (hexBytes n) > 1
@ -377,25 +318,3 @@ 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

View file

@ -20,36 +20,33 @@ module ZcashHaskell.Transparent where
import Control.Exception (throwIO)
import Crypto.Hash
import Crypto.Secp256k1
import qualified Data.Binary as Bi
import qualified Data.ByteArray as BA
import qualified Data.ByteString as BS
import Data.ByteString.Base58 (bitcoinAlphabet, decodeBase58, encodeBase58)
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Short as Short
import qualified Data.ByteString.Char8 as BC
import Data.Char (chr)
import Data.HexString
import qualified Data.Text as T
import qualified Data.Text.Encoding as E
import Data.Word
import Haskoin.Address (Address(..))
import qualified Haskoin.Crypto.Hash as H (Hash256(..))
import qualified Haskoin.Crypto.Hash as H
import Haskoin.Crypto.Keys.Extended
import ZcashHaskell.Types
( AccountId
, CoinType(..)
, ExchangeAddress(..)
, RawData(..)
, Scope(..)
, Seed(..)
, ToBytes(..)
, TransparentAddress(..)
, TransparentReceiver(..)
, TransparentSpendingKey(..)
, TransparentType(..)
, ZcashNet(..)
, getTransparentPrefix
, getValue
)
-- ( AccountId
-- , CoinType(..)
-- , Scope(..)
-- , Seed(..)
-- , ToBytes(..)
-- , TransparentAddress(..)
-- , TransparentReceiver(..)
-- , TransparentSpendingKey(..)
-- , TransparentType(..)
-- , ZcashNet(..)
-- , getTransparentPrefix
-- , getValue
-- )
import ZcashHaskell.Utils (decodeBech32, encodeBech32m)
-- | Required for `TransparentReceiver` encoding and decoding
@ -106,76 +103,7 @@ genTransparentReceiver i scope xprvk = do
ScriptAddress j -> return $ TransparentReceiver P2SH $ fromBinary j
_anyOtherKind -> throwIO $ userError "Unsupported transparent address type"
-- | Generate a transparent receiver from a Full Transparent Node
genTransparentReceiverFvk ::
Int -- ^ The index of the address to be created
-> Scope -- ^ `External` for wallet addresses or `Internal` for change addresses
-> BS.ByteString -- ^ The transparent public key
-> IO (Maybe TransparentReceiver)
genTransparentReceiverFvk i scope pubkey = do
ioCtx <- createContext
let s =
case scope of
External -> 0
Internal -> 1
let path = Deriv :/ s :/ fromIntegral i :: SoftPath
let fp' = textToFingerprint "f09f8fbe"
case fp' of
Left e -> fail "couldn't get fingerprint"
Right fp -> do
let x = importPubKey ioCtx $ BS.takeEnd 33 pubkey
case x of
Nothing -> fail "couldn't get pubkey"
Just pk -> do
let prepKey =
XPubKey
3
fp
0
(Bi.decode $ BSL.fromStrict $ BS.take 32 pubkey)
pk
let childPubKey = derivePubPath ioCtx path prepKey
let x = xPubAddr ioCtx childPubKey
case x of
PubKeyAddress k ->
return $ Just $ TransparentReceiver P2PKH $ fromBinary k
ScriptAddress j ->
return $ Just $ TransparentReceiver P2SH $ fromBinary j
_anyOtherKind -> return Nothing
-- | Generate a transparent receiver from a Incoming Transparent Node
genTransparentReceiverIvk ::
Int -- ^ The index of the address to be created
-> BS.ByteString -- ^ The transparent public key
-> IO (Maybe TransparentReceiver)
genTransparentReceiverIvk i pubkey = do
ioCtx <- createContext
let path = Deriv :/ fromIntegral i :: SoftPath
let fp' = textToFingerprint "f09f8fbe"
case fp' of
Left e -> fail "couldn't get fingerprint"
Right fp -> do
let x = importPubKey ioCtx $ BS.takeEnd 33 pubkey
case x of
Nothing -> fail "couldn't get pubkey"
Just pk -> do
let prepKey =
XPubKey
3
fp
0
(Bi.decode $ BSL.fromStrict $ BS.take 32 pubkey)
pk
let childPubKey = derivePubPath ioCtx path prepKey
let x = xPubAddr ioCtx childPubKey
case x of
PubKeyAddress k ->
return $ Just $ TransparentReceiver P2PKH $ fromBinary k
ScriptAddress j ->
return $ Just $ TransparentReceiver P2SH $ fromBinary j
_anyOtherKind -> return Nothing
-- | Generate a transparent spending key
-- | Generate a transparent receiver
genTransparentSecretKey ::
Int -- ^ The index of the address to be created
-> Scope -- ^ `External` for wallet addresses or `Internal` for change addresses

View file

@ -268,10 +268,10 @@ instance FromJSON BlockResponse where
withObject "BlockResponse" $ \obj -> do
c <- obj .: "confirmations"
h <- obj .: "height"
t <- obj .: "time"
t <- obj .:? "time"
txs <- obj .: "tx"
hash <- obj .: "hash"
pure $ BlockResponse hash c h t txs
pure $ BlockResponse hash c h (fromMaybe 0 t) txs
instance ToJSON BlockResponse where
toJSON (BlockResponse h c ht t txs) =
@ -685,35 +685,17 @@ data ValidAddress
| Exchange !ExchangeAddress
deriving stock (Eq, Prelude.Show)
-- | A type to handle user-entered viewing keys
data ValidVk
= FullVk !UnifiedFullViewingKey
| IncomingVk !UnifiedIncomingViewingKey
deriving stock (Eq, Prelude.Show, Read)
-- | 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@.
, o_key :: !BS.ByteString -- ^ Raw bytes of the Orchard Full Viewing Key as specified in [ZIP-316](https://zips.z.cash/zip-0316)
, s_key :: !BS.ByteString -- ^ Raw bytes of the Sapling Full Viewing Key as specified in [ZIP-316](https://zips.z.cash/zip-0316)
, 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, Read)
} deriving stock (Eq, Prelude.Show, GHC.Generic)
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
deriving anyclass (Data.Structured.Show)
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct UnifiedFullViewingKey
-- | 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, Read)
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

View file

@ -135,7 +135,7 @@ createTransaction ::
-> IO (Either TxError HexString)
createTransaction sapAnchor orchAnchor tSpend sSpend oSpend outgoing znet bh build = do
txResult <-
withBorshBufferOfInitSize 102400 $
withBorshBufferOfInitSize 51200 $
rustWrapperCreateTx
(hexBytes sapAnchor)
(hexBytes orchAnchor)

View file

@ -22,13 +22,10 @@
import C.Zcash (rustWrapperUADecode)
import Control.Exception (throwIO)
import Control.Monad.IO.Class (liftIO)
import Crypto.Secp256k1
import Data.Aeson
import qualified Data.Binary as Bi
import Data.Bool (Bool(True))
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as C
import qualified Data.ByteString.Lazy as BSL
import Data.Either (isRight)
import Data.Foldable (sequenceA_)
import Data.HexString
@ -48,27 +45,15 @@ import Test.HUnit
import Test.Hspec
import Test.Hspec.QuickCheck
import Test.QuickCheck
import ZcashHaskell.Keys
( deriveFullTransparentNode
, deriveUfvk
, deriveUivk
, generateWalletSeedPhrase
, getWalletSeed
)
import ZcashHaskell.Keys (generateWalletSeedPhrase, getWalletSeed)
import ZcashHaskell.Orchard
import ZcashHaskell.Sapling
( decodeSaplingAddress
, decodeSaplingOutput
, decodeSaplingOutputEsk
, decodeSaplingOutputFvk
, decodeSaplingOutputIvk
, deriveSaplingFvk
, encodeSaplingAddress
, genSaplingInternalAddress
, genSaplingInternalAddressFvk
, genSaplingPaymentAddress
, genSaplingReceiverFvk
, genSaplingReceiverIvk
, genSaplingSpendingKey
, getSaplingFrontier
, getSaplingNotePosition
@ -119,9 +104,6 @@ import ZcashHaskell.Types
, TransparentType(..)
, UnifiedAddress(..)
, UnifiedFullViewingKey(..)
, UnifiedIncomingViewingKey(..)
, ValidAddress(..)
, ValidVk(..)
, ZcashNet(..)
, ZebraTxResponse(..)
, decodeHexText
@ -1180,216 +1162,77 @@ main = do
Just addr -> do
let eadr = decodeExchangeAddress (E.encodeUtf8 addr)
eadr `shouldNotBe` Nothing
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
FullVk fvk <- deriveUfvk MainNet oK sK (Just tK)
net fvk `shouldBe` 1
it "Generate IVK" $ do
tK <- genTransparentPrvKey (fromJust seed) MainNetCoin 0
IncomingVk ivk <- deriveUivk MainNet oK sK (Just tK)
i_net ivk `shouldBe` 1
describe "Use viewing keys" $ do
describe "FVKs" $ do
let fvk =
decodeUfvk
"uviewtest1jna46ql5qns5rlg99jgs6mhf0j9tk8zxvqsm472scgvmj0vs0rqv2kvdf626gftx7dgn2tltyf0s200gvjlsdvz5celpue9wxxw78txswqmayxc3pfrt5fs5frvr3ep0jrjg8euahqzc63yx9sy4z8lql4ev6q3asptl9rhsfzzrup2g5slwnlvy3dgft44jw3l08xtzypjmsrwxskgnp5s03xlc2kg5520a25pa6fdjxhzutam4wkwr6mh4zeq3qndpks8dk0y90y7gucgsp0j5k2xnhh90m3krk5glz4794dj93pf59h85dqms6337f85ccvpxhays94kvsj2hyjsltf52tygqs8y0vp2yf39drxl687the6xkp8nxkfffc3kqlkhw53t5plplde0vk9rwv340ys04gg48fs0pxfp35rvt2f2pvxjmgmln6lp5k2yzkm0r87k89p6xqv68a6uyfpsauswh9fsckfqey02pjedz5gs934qa"
let addrFromWallet =
"utest1act45pg36s7345emmp8lpxx560d4tjy2ef7vzzqvdqmt8d5gjxn7x4aarskvqzqccgyjrv5gc4mr6nf2elz6ylpu8hq3rgm0gj43jkl3elrugr49swlk0pv5edvcgnmhrqswkck6kvswvr89h2q0m6gtwktxzdkjp80c86nlp7x02kd0ttpsylsjddk488nmagtj85xclluug793h8n"
let cua =
"utest1zcjhrp39ux52ype4j6055fngdufet0h2d6hx564s48cgnzthm3xma3eca4x8sh5a89jk88nerngvy5uq9tyxgxq552k64rs93ell63f8sd2rurhn34lr6fjznw64uf473mehpn39gy2k0m86r3gpp5lcdh2senl7kwgl6hku03n0gpqvcfc7c48kjv9z49yp52etntgwkltsz3zvj0m"
let oa =
OrchardAction
describe "Tree updates" $ do
it "Orchard" $ do
let tree =
OrchardCommitmentTree $
hexString
"0136a7886d7d73bc1845223165fd9cb0cef02046c707e8f88a7f61564720bd0f3501dca1fbdd7b5ba92a0809af5e85874626ce0db14d0532a48e41dde6f0f81b46011f0001fb48c27bd07e68f27aba47cd6e93fa961e0ef8c63f993963a614e56855d2013c0001ea572db9c5c2d24c7ad9132ae32b27179466bf67a580d59901d13b281d3f530b01c160348f10b9ad893d9731317ebe36ac8665e01c52cbe15a56aa9b72e4e6c41e000001cd7695156de2debdc5b13ea84d32e4e3ac020fb0aa7cd372c57ce765103bd70401746e6bc066a10e7f80a9ff8993dcb25c819edd64f2ca10ac248ef7848d41450500011e6191f91b3fceb62dc881a156e1b9d2e88e09dca25093cf9c4936c8869fb41a013bf8b923e4187754e85175748d9cce4824a6787e4258977b5bfe1ba59012c032000001f3bbdc62260c4fca5c84bf3487246d4542da48eeeec8ec40c1029b6908eef83c00000000000000000000000000000000"
let cmx1 =
hexString
"1712ead46028d4349e234abf59e94e0640fe7a0829e2e2e17e1a931631810400"
let cmx2 =
hexString
"39f5ad39817fb432fa07c5feb3a957189fbe7662a4b5555ca95093b6d853cf07"
let cmx3 =
hexString
"84f7fbc4b9f87215c653078d7fdd90756c3ba370c745065167da9eb73a65a83f"
let cmx4 =
hexString
"e55ad64e1ea2b261893fdea6ad0509b66e5f62d3142f351298c7135c4498d429"
let finalTree =
getOrchardFrontier $
OrchardCommitmentTree $
hexString
"0184f7fbc4b9f87215c653078d7fdd90756c3ba370c745065167da9eb73a65a83f01e55ad64e1ea2b261893fdea6ad0509b66e5f62d3142f351298c7135c4498d4291f0000014b1a76d3820087b26cd087ca84e17f3067a25ebed82ad23a93fa485affb5530b01ea572db9c5c2d24c7ad9132ae32b27179466bf67a580d59901d13b281d3f530b01c160348f10b9ad893d9731317ebe36ac8665e01c52cbe15a56aa9b72e4e6c41e000001cd7695156de2debdc5b13ea84d32e4e3ac020fb0aa7cd372c57ce765103bd70401746e6bc066a10e7f80a9ff8993dcb25c819edd64f2ca10ac248ef7848d41450500011e6191f91b3fceb62dc881a156e1b9d2e88e09dca25093cf9c4936c8869fb41a013bf8b923e4187754e85175748d9cce4824a6787e4258977b5bfe1ba59012c032000001f3bbdc62260c4fca5c84bf3487246d4542da48eeeec8ec40c1029b6908eef83c00000000000000000000000000000000"
case getOrchardFrontier tree of
Nothing -> assertFailure "Failed to get frontier"
Just t1 ->
case updateOrchardCommitmentTree t1 cmx1 of
Nothing -> assertFailure "Failed to update frontier with cmx"
Just t2 -> do
case getOrchardWitness t2 of
Nothing -> assertFailure "Failed to get witness"
Just wit -> do
let uWit = updateOrchardWitness wit [cmx2, cmx3, cmx4]
Just (getOrchardWitnessAnchor uWit) `shouldBe`
getOrchardTreeAnchor <$>
finalTree
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
"33d6bf1d78f6414b725b5b43bfbb92b460d81cf04a352831d74bbc3c3aa86c2a")
"01bd8a3f3cfc964332a2ada8c09a0da9dfc24174befb938abb086b9be5ca049e49013607f5e51826c8e5f660571ddfae14cd6fb1dc026bcd6855459b4e9339b20521100000019f0d7efb00169bb2202152d3266059d208ab17d14642c3339f9075e997160657000000012f4f72c03f8c937a94919a01a07f21165cc8394295291cb888ca91ed003810390107114fe4bb4cd08b47f6ae47477c182d5da9fe5c189061808c1091e9bf3b4524000001447d6b9100cddd5f80c8cf4ddee2b87eba053bd987465aec2293bd0514e68b0d015f6c95e75f4601a0a31670a7deb970fc8988c611685161d2e1629d0a1a0ebd07015f8b9205e0514fa235d75c150b87e23866b882b39786852d1ab42aab11d31a4a0117ddeb3a5f8d2f6b2d0a07f28f01ab25e03a05a9319275bb86d72fcaef6fc01501f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39038cd7f6e2238d16ef49420963348dd4e4c7d23d5e5dac69507fba8937f63eb626f6856115bea2fa8db3a65a0ab294db41c51435d3b7ea27c7b2835aca28e82a2c1d9634efe07449a47c251518ac6f92c49f3a1ef119948f6a824d1e7ff7d0443e0101e49992fdd071d90bf56242d1aa625bbe267a34e0debd4307818a686d05b45447010c4b26766d89bf6cdb4fd3b0317b4e9a2fb3850f6a24869f32fe7cb0fd512e1803000121c06ee1f1584f79d50785797a694c742be2ded600367ab7d54f3ed49e3adf7201808304b4d7c4fc407f5ce28247a7119013aeaaf1481902419c42bc8b21575c15")
it "Orchard" $ do
let wit =
OrchardWitness $
hexString
"016225b41339a00dd764b452fca190a0245e7118224965942e3a6d798365c34631001f0000011d6f5da3f619bfaab957fc643c17eb144db0101c90f422da2fcbe0e80d74412e000000000001746e6bc066a10e7f80a9ff8993dcb25c819edd64f2ca10ac248ef7848d41450500011e6191f91b3fceb62dc881a156e1b9d2e88e09dca25093cf9c4936c8869fb41a013bf8b923e4187754e85175748d9cce4824a6787e4258977b5bfe1ba59012c032000001f3bbdc62260c4fca5c84bf3487246d4542da48eeeec8ec40c1029b6908eef83c00000000000000000000000000000000040e02c864db8b574f165f616d48e2f12eb25099b5c90186af26d9e50f5058863e0504bfbc12edc35e05042c16bbfb8fed591f01f18fe128eeb57f2c456c9eb222d6d261c549e95d9007bce4c6ae0b86bc865711cdd9f0fa92e2d5b5e149b51f3be127df3b1d2372adf6c811b2e456c1d64d0e9eb167a995f9c6b66a03c9cbda250101c094201bae3b4ef582a3e8654f65a72fbd41e20e1ec9a43d3f4101afc868731e000200019df5b9366d0f21caa678d1567390b5bfd3cfa0438271bcfe301b5558a2863301"
let cmxs =
[ hexString
"712ba86615ff4447e8d7c7b59f3873f03c03a173438b8e4c8d416756ed4fae10"
, hexString
"c094201bae3b4ef582a3e8654f65a72fbd41e20e1ec9a43d3f4101afc868731e"
, hexString
"ac20b8170b008888c19fc6e16f5e30a5ef1653e5219d0cd0c9353c3aa8f79823"
]
updateOrchardWitness wit cmxs `shouldBe`
OrchardWitness
(hexString
"ce6d2090bf747ddce410ad967ea98e727120710f9814a6d77ebdd593c6f9660b")
(hexString
"567be1d3c5e2b8aba20fba30edd357810eb40647f1f5f9bb4e23691a9c174235")
(hexString
"b4ee13a27e1b7f2674c7b3924c2178b4c010c05750b78b65cb741b10476d1c24")
(hexString
"e8c37d9a2ea88f2ef266fed77753744da9afedf2530940b15ad882cc187a69d6116c5c34cdaf94e1f178ec50ef95d49b46ab6a7206c2a6b57d9d55f65cc7f5f57ccb91d71e827af5286897a4c8ca9c3fc2dad60208adbc8bd3d81eb5febf4c3c75e69b83627fdff730a946bb2e6e6703c4c676675e34ece1b073ce61490298a93503fa10f2b86fbd1274825c72e26b2340d1ed338d3b254803614b2fc9778155c988516d6ce1f334aeca076063c06588961c0d7dfa1bafd59cbca1782fcd863fce1f25abdf151c9718dce3708f8cede130d9e785ed4798aebfca8fec386f4a4d38a75c7b054c453676ad9ce7de32f4c4687f6932686f52e381bd41508a468ca684ea2755d56522a7b4138f58d0b10e1195a6fe27393ca382d0525a74acde5e0f6f2cb8ff3d74221f2a02fe2fd1874a2cf6f542bfa8f0107a21728249ca549bbba66a5422fd9aeaaeff09d1edfecb711c15290c9e8d031baf41fe47a5da3f9a614016f45886fb4d3ea2795802bf7785c1c9e3de15dc18300891f6abb9569851a7c4bf4cd054f8f593969b42c80968bf732ebaa90abf1a7614d1d325e8ed930161e0fbf82333c96cea455743c3e3e3cd1cdd754383a6f2364eacc162059e31885045eee7f2d60b068e78e29490a4df0f34e690b3bb17923669b828d245727bf11b0fe1e0fc4b97b62be37f7a7944db5b5b13221b0000f74c3cdcf9c246e60e77327c4f853f4037eeb2feb9f5d84961e4321c54c30d193866897872b31113a5f819dc2a264d2ef7b91edd16504ad75b6ee622dad79dadaadcd005215932d66232738a7dd8d2")
(hexString
"0b7be09c8f69e068d3277f345a0a4bf11057ff4c46e7657bb8a61a1c2b4c0d61e8e561131f935053f02cb46360f13179dc4647a243fabdd9ac59ba9ac2529a3b7af0ea5020d2b4c17466ebf309448491")
(hexString
"81939f32c4ca40c0a4c9334cffd68339e207afc322b533cb9cbb7b156758dc94")
(hexString
"44e3d8c4fbac16fc0edfd634b396b0a4822fc9a2cfdc8ec293a5c6ffc2001e96d2840c303463e3bc9add8c9263c56569e5b7ac14cf8d84316735f4b77493c136")
let so =
ShieldedOutput
(hexString
"dae2e33897847cc968d4719efc6ff6ea69c7ea8f8567883ba891c3d99b7fc7f3")
(hexString
"3d7c752b89af7dd63430d458d54c60643533ed6db9c57f55131eb7303daf7844")
(hexString
"8f7bd84a946a9068cb2030dd8d1f7446bba2ff22a5cce5ac97cc5c46f1c9bba9")
(hexString
"bc7b212e7c0a598a1237493a014688ee1232f631928e50583df6a1980adefb867dca6f97aa468f3c3a3882db8f359fc0d29205a808173645c22ba8a815e307fec633ffd01d34830e639e4dda548cd6e3ea32054206ac77e60ae09b0bf911066caf2be0bc8e3936edfa3e05c74f2e8a8bf5bbd8867eb83fd7fe24107612f6a0eaa586c6997b19fbe43c3b7d3f8cd5f40ae1a5431cf9d0d336516fb22ce4e295f77326ada3b453b9813a4a63981a52b9ba65af43cc6ec198b384417247b8f1bb15199fba5e90e435c946d03f97c62f7b40fbfef85e456dcb8fdaec94585a600cb40b2ed6c23c08eba5115719944528c156bea996b993d6e1730a17c6cf036deee43a18bd6afbd6e0f55f6c35ab5557df8e1356866514784ab4dd5ff158f0c5bfb6011adefae26c6dcee7472b7086680a72859e231829b7cf408683ced04171065e8740abde2b528c790fbec34d80e15ca869aaa100640c7ab167d7538a48174ea7caac91297455f85a41a03ab760565dd899b6b10b7034b221f4390373bd2dc1e3766629f7d5b606449ef07057995da06a63b6bb07aa117fd26e7154e55636ab8df21c3e3665574899eb1186d2106a55cc20b7eee2bc9b5970acddbac4a74f2f5599d7b42c21e65f340363748b208e61800ce6317e43c7e55757e1c9210bc716a93edb5ca2ed26ead4c14510086fb6752a8bfa089787360cca5c6b053744ad1487f7032ba027ba7758ce842a372b2f7dd418ecbd6353ca199629faa8848dfb7f228610aa2f76324eb7092ca05c6e2e7c7e9972cf33009c716ad43adc492a25fb8d1d67e72f")
(hexString
"ebe23f6ad66a16f9e5faece7139ae55aae93631b8b36ba2b5d21885f29b39dab224549afef0137c612d0c7a8ec597e98ea5a08334392079e5ea5c061cef2ebe296e71b6845e6bea09291bba505a76a03")
(hexString
"ad238bb5d88ccc438998bbcda831b499775f76c706f67bd9e56b8c3d6a6479afcf562a459c8db54003b641f1ac83d2dfa83baf8e04d6c2ab335eec290b3f581b0063cb088b53eb30b372ce80ac86a904448b9766d02624caa42fd9828ba4912e075b786fcbed921bc4cd25555031b2cd92509894d8ade8f4da92007b010b506c5664802e4e80c3363cd6e16c2a67abdcb4f3aef7638095091ab74cf79b6dcb919f7b38547e9576a7512f0f128504bb3461b8fee69ab7774320f56b2af13a6c9d")
it "Orchard external receiver from fvk" $ do
case fvk of
Nothing -> assertFailure "Failed to parse VK"
Just k ->
genOrchardReceiverFvk 0 External (o_key k) `shouldNotBe` Nothing
it "Orchard internal receiver from fvk" $ do
case fvk of
Nothing -> assertFailure "Failed to parse VK"
Just k ->
genOrchardReceiverFvk 0 Internal (o_key k) `shouldNotBe` Nothing
it "Decrypt Orchard action with FVK" $ do
case fvk of
Nothing -> assertFailure "Failed to parse VK"
Just k ->
a_nullifier <$>
decryptOrchardActionFvk k External oa `shouldBe`
Just (hexString "00")
it "Sapling external receiver from fvk" $ do
case fvk of
Nothing -> assertFailure "Failed to parse VK"
Just k -> genSaplingReceiverFvk 0 (s_key k) `shouldNotBe` Nothing
it "Sapling internal receiver from fvk" $ do
case fvk of
Nothing -> assertFailure "Failed to parse VK"
Just k ->
genSaplingInternalAddressFvk (s_key k) `shouldNotBe` Nothing
it "Decode external Sapling with fvk" $ do
case fvk of
Nothing -> assertFailure "Failed to parse VK"
Just k ->
a_nullifier <$>
decodeSaplingOutputFvk (s_key k) so External 234878 `shouldBe`
Just (hexString "00")
it "Transparent external receiver from fvk" $ do
case fvk of
Nothing -> assertFailure "Failed to parse VK"
Just k -> do
recv <- genTransparentReceiverFvk 0 External (t_key k)
recv `shouldNotBe` Nothing
it "Transparent internal receiver from fvk" $ do
case fvk of
Nothing -> assertFailure "Failed to parse VK"
Just k -> do
recv <- genTransparentReceiverFvk 0 Internal (t_key k)
recv `shouldNotBe` Nothing
it "Generate UA from FVK" $ do
let parsedUA = parseAddress addrFromWallet
case fvk of
Nothing -> assertFailure "Failed to parse VK"
Just k -> do
case parsedUA of
Nothing -> assertFailure "Failed to parse UA"
Just va -> do
case va of
Unified ua -> do
let orec = genOrchardReceiverFvk 0 External (o_key k)
let srec = genSaplingReceiverFvk 0 (s_key k)
trec <- genTransparentReceiverFvk 0 External (t_key k)
let myUa = UnifiedAddress TestNet orec srec trec
myUa `shouldBe` ua
_any -> assertFailure "Address to UA"
it "Generate change UA from FVK" $ do
let parsedCua = parseAddress cua
case fvk of
Nothing -> assertFailure "Failed to parse VK"
Just k -> do
case parsedCua of
Nothing -> assertFailure "Failed to parse UA"
Just va -> do
case va of
Unified ua -> do
let orec = genOrchardReceiverFvk 0 Internal (o_key k)
let srec = genSaplingInternalAddressFvk (s_key k)
trec <- genTransparentReceiverFvk 0 Internal (t_key k)
let myUa = UnifiedAddress TestNet orec srec trec
myUa `shouldBe` ua
_any -> assertFailure "Address to UA"
describe "IVKs" $ do
let ivk =
decodeUivk
"uivktest10yy38f5v5sz5hnne93flkrpfqr4geyfuaq97u4fe9zkrng20ppeqsu7a6fkfttn0phjj9kutlnn4nzvfls233xujcv3fw6ax9w8pqzsw792py78dl8p4cyhv3eyusu589382qwf4pwz3vs7n6pv4qj7j6apg5nvw4yl4u5g033tpr2a7jjzt3f3khjm09wj7er7myr8vy04595nj6pqcdp3ndp98ckg82y0w08d8wnx7wynrzhmqrxh9pf0m50tj332vjld08uz027xwyegakyzem745y462khv9xzlc4h5rxwsqfklvak3x26excpcjn54e3cd2zttxujnuzv3rrtrpuld9e2"
let addrFromWallet =
"utest1act45pg36s7345emmp8lpxx560d4tjy2ef7vzzqvdqmt8d5gjxn7x4aarskvqzqccgyjrv5gc4mr6nf2elz6ylpu8hq3rgm0gj43jkl3elrugr49swlk0pv5edvcgnmhrqswkck6kvswvr89h2q0m6gtwktxzdkjp80c86nlp7x02kd0ttpsylsjddk488nmagtj85xclluug793h8n"
let oa =
OrchardAction
(hexString
"33d6bf1d78f6414b725b5b43bfbb92b460d81cf04a352831d74bbc3c3aa86c2a")
(hexString
"ce6d2090bf747ddce410ad967ea98e727120710f9814a6d77ebdd593c6f9660b")
(hexString
"567be1d3c5e2b8aba20fba30edd357810eb40647f1f5f9bb4e23691a9c174235")
(hexString
"b4ee13a27e1b7f2674c7b3924c2178b4c010c05750b78b65cb741b10476d1c24")
(hexString
"e8c37d9a2ea88f2ef266fed77753744da9afedf2530940b15ad882cc187a69d6116c5c34cdaf94e1f178ec50ef95d49b46ab6a7206c2a6b57d9d55f65cc7f5f57ccb91d71e827af5286897a4c8ca9c3fc2dad60208adbc8bd3d81eb5febf4c3c75e69b83627fdff730a946bb2e6e6703c4c676675e34ece1b073ce61490298a93503fa10f2b86fbd1274825c72e26b2340d1ed338d3b254803614b2fc9778155c988516d6ce1f334aeca076063c06588961c0d7dfa1bafd59cbca1782fcd863fce1f25abdf151c9718dce3708f8cede130d9e785ed4798aebfca8fec386f4a4d38a75c7b054c453676ad9ce7de32f4c4687f6932686f52e381bd41508a468ca684ea2755d56522a7b4138f58d0b10e1195a6fe27393ca382d0525a74acde5e0f6f2cb8ff3d74221f2a02fe2fd1874a2cf6f542bfa8f0107a21728249ca549bbba66a5422fd9aeaaeff09d1edfecb711c15290c9e8d031baf41fe47a5da3f9a614016f45886fb4d3ea2795802bf7785c1c9e3de15dc18300891f6abb9569851a7c4bf4cd054f8f593969b42c80968bf732ebaa90abf1a7614d1d325e8ed930161e0fbf82333c96cea455743c3e3e3cd1cdd754383a6f2364eacc162059e31885045eee7f2d60b068e78e29490a4df0f34e690b3bb17923669b828d245727bf11b0fe1e0fc4b97b62be37f7a7944db5b5b13221b0000f74c3cdcf9c246e60e77327c4f853f4037eeb2feb9f5d84961e4321c54c30d193866897872b31113a5f819dc2a264d2ef7b91edd16504ad75b6ee622dad79dadaadcd005215932d66232738a7dd8d2")
(hexString
"0b7be09c8f69e068d3277f345a0a4bf11057ff4c46e7657bb8a61a1c2b4c0d61e8e561131f935053f02cb46360f13179dc4647a243fabdd9ac59ba9ac2529a3b7af0ea5020d2b4c17466ebf309448491")
(hexString
"81939f32c4ca40c0a4c9334cffd68339e207afc322b533cb9cbb7b156758dc94")
(hexString
"44e3d8c4fbac16fc0edfd634b396b0a4822fc9a2cfdc8ec293a5c6ffc2001e96d2840c303463e3bc9add8c9263c56569e5b7ac14cf8d84316735f4b77493c136")
let so =
ShieldedOutput
(hexString
"dae2e33897847cc968d4719efc6ff6ea69c7ea8f8567883ba891c3d99b7fc7f3")
(hexString
"3d7c752b89af7dd63430d458d54c60643533ed6db9c57f55131eb7303daf7844")
(hexString
"8f7bd84a946a9068cb2030dd8d1f7446bba2ff22a5cce5ac97cc5c46f1c9bba9")
(hexString
"bc7b212e7c0a598a1237493a014688ee1232f631928e50583df6a1980adefb867dca6f97aa468f3c3a3882db8f359fc0d29205a808173645c22ba8a815e307fec633ffd01d34830e639e4dda548cd6e3ea32054206ac77e60ae09b0bf911066caf2be0bc8e3936edfa3e05c74f2e8a8bf5bbd8867eb83fd7fe24107612f6a0eaa586c6997b19fbe43c3b7d3f8cd5f40ae1a5431cf9d0d336516fb22ce4e295f77326ada3b453b9813a4a63981a52b9ba65af43cc6ec198b384417247b8f1bb15199fba5e90e435c946d03f97c62f7b40fbfef85e456dcb8fdaec94585a600cb40b2ed6c23c08eba5115719944528c156bea996b993d6e1730a17c6cf036deee43a18bd6afbd6e0f55f6c35ab5557df8e1356866514784ab4dd5ff158f0c5bfb6011adefae26c6dcee7472b7086680a72859e231829b7cf408683ced04171065e8740abde2b528c790fbec34d80e15ca869aaa100640c7ab167d7538a48174ea7caac91297455f85a41a03ab760565dd899b6b10b7034b221f4390373bd2dc1e3766629f7d5b606449ef07057995da06a63b6bb07aa117fd26e7154e55636ab8df21c3e3665574899eb1186d2106a55cc20b7eee2bc9b5970acddbac4a74f2f5599d7b42c21e65f340363748b208e61800ce6317e43c7e55757e1c9210bc716a93edb5ca2ed26ead4c14510086fb6752a8bfa089787360cca5c6b053744ad1487f7032ba027ba7758ce842a372b2f7dd418ecbd6353ca199629faa8848dfb7f228610aa2f76324eb7092ca05c6e2e7c7e9972cf33009c716ad43adc492a25fb8d1d67e72f")
(hexString
"ebe23f6ad66a16f9e5faece7139ae55aae93631b8b36ba2b5d21885f29b39dab224549afef0137c612d0c7a8ec597e98ea5a08334392079e5ea5c061cef2ebe296e71b6845e6bea09291bba505a76a03")
(hexString
"ad238bb5d88ccc438998bbcda831b499775f76c706f67bd9e56b8c3d6a6479afcf562a459c8db54003b641f1ac83d2dfa83baf8e04d6c2ab335eec290b3f581b0063cb088b53eb30b372ce80ac86a904448b9766d02624caa42fd9828ba4912e075b786fcbed921bc4cd25555031b2cd92509894d8ade8f4da92007b010b506c5664802e4e80c3363cd6e16c2a67abdcb4f3aef7638095091ab74cf79b6dcb919f7b38547e9576a7512f0f128504bb3461b8fee69ab7774320f56b2af13a6c9d")
it "Orchard external receiver from ivk" $ do
case ivk of
Nothing -> assertFailure "Failed to parse VK"
Just k -> genOrchardReceiverIvk 0 (i_o_key k) `shouldNotBe` Nothing
it "Decrypt Orchard action with IVK" $ do
case ivk of
Nothing -> assertFailure "Failed to parse VK"
Just k -> decryptOrchardActionIvk k oa `shouldNotBe` Nothing
it "Sapling external receiver from ivk" $ do
case ivk of
Nothing -> assertFailure "Failed to parse VK"
Just k -> genSaplingReceiverIvk 0 (i_s_key k) `shouldNotBe` Nothing
it "Decode external Sapling with ivk" $ do
case ivk of
Nothing -> assertFailure "Failed to parse VK"
Just k ->
decodeSaplingOutputIvk (i_s_key k) so `shouldNotBe` Nothing
it "Transparent external receiver from ivk" $ do
case ivk of
Nothing -> assertFailure "Failed to parse VK"
Just k -> do
recv <- genTransparentReceiverIvk 0 (i_t_key k)
recv `shouldNotBe` Nothing
it "Generate UA from IVK" $ do
let parsedUA = parseAddress addrFromWallet
case ivk of
Nothing -> assertFailure "Failed to parse VK"
Just k -> do
case parsedUA of
Nothing -> assertFailure "Failed to parse UA"
Just va -> do
case va of
Unified ua -> do
let orec = genOrchardReceiverIvk 0 (i_o_key k)
let srec = genSaplingReceiverIvk 0 (i_s_key k)
trec <- genTransparentReceiverIvk 0 (i_t_key k)
let myUa = UnifiedAddress TestNet orec srec trec
myUa `shouldBe` ua
_any -> assertFailure "Address to UA"
"016225b41339a00dd764b452fca190a0245e7118224965942e3a6d798365c34631001f0000011d6f5da3f619bfaab957fc643c17eb144db0101c90f422da2fcbe0e80d74412e000000000001746e6bc066a10e7f80a9ff8993dcb25c819edd64f2ca10ac248ef7848d41450500011e6191f91b3fceb62dc881a156e1b9d2e88e09dca25093cf9c4936c8869fb41a013bf8b923e4187754e85175748d9cce4824a6787e4258977b5bfe1ba59012c032000001f3bbdc62260c4fca5c84bf3487246d4542da48eeeec8ec40c1029b6908eef83c00000000000000000000000000000000040e02c864db8b574f165f616d48e2f12eb25099b5c90186af26d9e50f5058863e0504bfbc12edc35e05042c16bbfb8fed591f01f18fe128eeb57f2c456c9eb222d6d261c549e95d9007bce4c6ae0b86bc865711cdd9f0fa92e2d5b5e149b51f3be127df3b1d2372adf6c811b2e456c1d64d0e9eb167a995f9c6b66a03c9cbda250101c094201bae3b4ef582a3e8654f65a72fbd41e20e1ec9a43d3f4101afc868731e01ac20b8170b008888c19fc6e16f5e30a5ef1653e5219d0cd0c9353c3aa8f7982302010cfb50d8c877eb39e9c07082a032dd99d34be7c19fa7f30e9fecf5f14736240f019df5b9366d0f21caa678d1567390b5bfd3cfa0438271bcfe301b5558a2863301")
-- | Properties
prop_PhraseLength :: Property

View file

@ -5,7 +5,7 @@ cabal-version: 3.0
-- see: https://github.com/sol/hpack
name: zcash-haskell
version: 0.8.1.0
version: 0.7.5.0
synopsis: Utilities to interact with the Zcash blockchain
description: Please see the README on the repo at <https://git.vergara.tech/Vergara_Tech/zcash-haskell#readme>
category: Blockchain