Compare commits
46 commits
Author | SHA1 | Date | |
---|---|---|---|
dea960c2ac | |||
62cda9cc15 | |||
5ce149c54f | |||
6d4b6840d3 | |||
662a0d1148 | |||
4608577c41 | |||
5a9ed11c25 | |||
96cfe3a52a | |||
3203c7e8ff | |||
396f15140a | |||
5a08c80285 | |||
003293cc3f | |||
612ce812ef | |||
3969490283 | |||
38e4131daa | |||
48afd81595 | |||
12296026a0 | |||
5de1844e9d | |||
36fd2e59a4 | |||
63a97b880c | |||
f24ea80cde | |||
9df346389a | |||
91e2ebbabd | |||
343495f6e7 | |||
7350723801 | |||
7965dc38c4 | |||
ee165de652 | |||
1f1ca4e206 | |||
f1e1570b25 | |||
5a8cd44fbc | |||
cedc3a0cc1 | |||
ce19e174cc | |||
85a4741dcb | |||
0b2fae2b5d | |||
b4069d6233 | |||
c8f411fcdd | |||
939ae687e8 | |||
e1622a0d7f | |||
774e135aab | |||
b7c91e10fe | |||
cbbdfe42af | |||
9ca702a68e | |||
cc72fadef3 | |||
7c79ee6163 | |||
e8074419cf | |||
90c8a7c302 |
16 changed files with 590 additions and 1860 deletions
52
CHANGELOG.md
52
CHANGELOG.md
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
847
librustzcash-wrapper/Cargo.lock
generated
847
librustzcash-wrapper/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -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]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[toolchain]
|
||||
channel = "nightly"
|
||||
channel = "nightly-2024-02-04"
|
||||
components = [ "rustfmt", "rustc-dev"]
|
||||
profile = "minimal"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
110
src/C/Zcash.chs
110
src/C/Zcash.chs
|
@ -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'&
|
||||
}
|
||||
-> `()'
|
||||
#}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
297
test/Spec.hs
297
test/Spec.hs
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue