Compare commits
No commits in common. "master" and "0.7.7.0" have entirely different histories.
9 changed files with 4 additions and 416 deletions
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -5,17 +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/),
|
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).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [0.7.8.0]
|
|
||||||
|
|
||||||
## Added
|
|
||||||
|
|
||||||
- New `UnifiedIncomingViewingKey` type
|
|
||||||
- Functions to derive Orchard full viewing key
|
|
||||||
- Functions to derive Sapling full viewing key
|
|
||||||
- Functions to derive transparent "full viewing key"
|
|
||||||
- Functions to encode Unified Full Viewing Keys
|
|
||||||
- Functions to encode Unified Incoming Viewing Keys
|
|
||||||
|
|
||||||
## [0.7.7.0]
|
## [0.7.7.0]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -135,7 +135,7 @@ use zcash_primitives::{
|
||||||
|
|
||||||
use zcash_address::{
|
use zcash_address::{
|
||||||
Network,
|
Network,
|
||||||
unified::{Address, Encoding, Ufvk, Uivk, Ivk, Container, Fvk, Receiver},
|
unified::{Address, Encoding, Ufvk, Container, Fvk, Receiver},
|
||||||
ZcashAddress
|
ZcashAddress
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -690,35 +690,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)]
|
#[derive(Debug, BorshSerialize, BorshDeserialize)]
|
||||||
pub struct Hsvk {
|
pub struct Hsvk {
|
||||||
vk: Vec<u8>,
|
vk: Vec<u8>,
|
||||||
|
@ -997,34 +968,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]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_wrapper_sapling_esk_decrypt(
|
pub extern "C" fn rust_wrapper_sapling_esk_decrypt(
|
||||||
key: *const u8,
|
key: *const u8,
|
||||||
|
@ -2565,87 +2508,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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
{# fun unsafe rust_wrapper_orchard_note_decrypt as rustWrapperOrchardNoteDecode
|
||||||
{ toBorshVar* `BS.ByteString'&
|
{ toBorshVar* `BS.ByteString'&
|
||||||
, toBorshVar* `OrchardAction'&
|
, toBorshVar* `OrchardAction'&
|
||||||
|
@ -417,31 +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'&
|
|
||||||
}
|
|
||||||
-> `()'
|
|
||||||
#}
|
|
||||||
|
|
|
@ -15,42 +15,13 @@
|
||||||
module ZcashHaskell.Keys where
|
module ZcashHaskell.Keys where
|
||||||
|
|
||||||
import C.Zcash (rustWrapperGenSeedPhrase, rustWrapperGetSeed)
|
import C.Zcash (rustWrapperGenSeedPhrase, rustWrapperGetSeed)
|
||||||
import Crypto.Secp256k1 (createContext)
|
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import Data.HexString (hexBytes)
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.Encoding as E
|
|
||||||
import Data.Word (Word8(..))
|
|
||||||
import Foreign.Rust.Marshall.Variable
|
import Foreign.Rust.Marshall.Variable
|
||||||
( withBorshVarBuffer
|
( withBorshVarBuffer
|
||||||
, withPureBorshVarBuffer
|
, withPureBorshVarBuffer
|
||||||
)
|
)
|
||||||
import Haskoin.Address.Base58 (decodeBase58)
|
import ZcashHaskell.Types (Phrase, Seed(..), ToBytes(..))
|
||||||
import Haskoin.Crypto.Keys.Extended
|
|
||||||
( DerivPath(..)
|
|
||||||
, DerivPathI(..)
|
|
||||||
, XPubKey(..)
|
|
||||||
, derivePath
|
|
||||||
, deriveXPubKey
|
|
||||||
, xPubExport
|
|
||||||
)
|
|
||||||
import Haskoin.Network.Constants (btc)
|
|
||||||
import ZcashHaskell.Orchard (deriveOrchardFvk, deriveOrchardIvk)
|
|
||||||
import ZcashHaskell.Sapling (deriveSaplingFvk, deriveSaplingIvk)
|
|
||||||
import ZcashHaskell.Types
|
|
||||||
( OrchardSpendingKey(..)
|
|
||||||
, Phrase
|
|
||||||
, SaplingSpendingKey(..)
|
|
||||||
, Seed(..)
|
|
||||||
, ToBytes(..)
|
|
||||||
, TransparentSpendingKey(..)
|
|
||||||
, ZcashNet(..)
|
|
||||||
, uniFullViewingKeyHrp
|
|
||||||
, uniIncomingViewingKeyHrp
|
|
||||||
, uniTestFullViewingKeyHrp
|
|
||||||
, uniTestIncomingViewingKeyHrp
|
|
||||||
)
|
|
||||||
import ZcashHaskell.Utils (encodeBech32m, f4Jumble)
|
|
||||||
|
|
||||||
-- | Generate a random seed that can be used to generate private keys for shielded addresses and transparent addresses.
|
-- | Generate a random seed that can be used to generate private keys for shielded addresses and transparent addresses.
|
||||||
generateWalletSeedPhrase :: IO Phrase
|
generateWalletSeedPhrase :: IO Phrase
|
||||||
|
@ -65,97 +36,3 @@ getWalletSeed p =
|
||||||
where
|
where
|
||||||
result :: Seed
|
result :: Seed
|
||||||
result = (withPureBorshVarBuffer . rustWrapperGetSeed) p
|
result = (withPureBorshVarBuffer . rustWrapperGetSeed) p
|
||||||
|
|
||||||
-- | Derive a transparent root node for unified viewing keys
|
|
||||||
deriveFullTransparentNode :: TransparentSpendingKey -> IO BS.ByteString
|
|
||||||
deriveFullTransparentNode sk = do
|
|
||||||
ioCtx <- createContext
|
|
||||||
let tPubKey = deriveXPubKey ioCtx sk
|
|
||||||
let tPubKeyBytes = decodeBase58 $ xPubExport btc ioCtx tPubKey
|
|
||||||
case tPubKeyBytes of
|
|
||||||
Nothing -> fail "Unable to get transparent key bytes"
|
|
||||||
Just pb -> return $ BS.takeEnd 65 pb
|
|
||||||
|
|
||||||
-- | Derive a transparent incoming root node for unified incoming viewing keys
|
|
||||||
deriveIncomingTransparentNode :: TransparentSpendingKey -> IO BS.ByteString
|
|
||||||
deriveIncomingTransparentNode sk = do
|
|
||||||
ioCtx <- createContext
|
|
||||||
let path = Deriv :/ 0 :: DerivPath
|
|
||||||
let childPrvKey = derivePath ioCtx path sk
|
|
||||||
let tPubKey = deriveXPubKey ioCtx childPrvKey
|
|
||||||
let tPubKeyBytes = decodeBase58 $ xPubExport btc ioCtx tPubKey
|
|
||||||
case tPubKeyBytes of
|
|
||||||
Nothing -> fail "Unable to get transparent key bytes"
|
|
||||||
Just pb -> return $ BS.takeEnd 65 pb
|
|
||||||
|
|
||||||
-- | Derive a Unified Full Viewing Key
|
|
||||||
deriveUfvk ::
|
|
||||||
ZcashNet
|
|
||||||
-> OrchardSpendingKey
|
|
||||||
-> SaplingSpendingKey
|
|
||||||
-> TransparentSpendingKey
|
|
||||||
-> IO T.Text
|
|
||||||
deriveUfvk net okey skey tkey = do
|
|
||||||
tSec <- deriveFullTransparentNode tkey
|
|
||||||
let oSec = deriveOrchardFvk okey
|
|
||||||
let sSec = deriveSaplingFvk skey
|
|
||||||
case oSec of
|
|
||||||
Nothing -> fail "Unable to derive Orchard viewing key"
|
|
||||||
Just oSec' -> do
|
|
||||||
case sSec of
|
|
||||||
Nothing -> fail "Unable to derive Sapling viewing key"
|
|
||||||
Just sSec' ->
|
|
||||||
return $ encodeVK (hexBytes oSec') (hexBytes sSec') tSec net True
|
|
||||||
|
|
||||||
-- | Derive a Unified Incoming Viewing Key
|
|
||||||
deriveUivk ::
|
|
||||||
ZcashNet
|
|
||||||
-> OrchardSpendingKey
|
|
||||||
-> SaplingSpendingKey
|
|
||||||
-> TransparentSpendingKey
|
|
||||||
-> IO T.Text
|
|
||||||
deriveUivk net okey skey tkey = do
|
|
||||||
tSec <- deriveIncomingTransparentNode tkey
|
|
||||||
let oSec = deriveOrchardIvk okey
|
|
||||||
let sSec = deriveSaplingIvk skey
|
|
||||||
case oSec of
|
|
||||||
Nothing -> fail "Unable to derive Orchard viewing key"
|
|
||||||
Just oSec' -> do
|
|
||||||
case sSec of
|
|
||||||
Nothing -> fail "Unable to derive Sapling viewing key"
|
|
||||||
Just sSec' ->
|
|
||||||
return $ encodeVK (hexBytes oSec') (hexBytes sSec') tSec net False
|
|
||||||
|
|
||||||
-- | Encode a Unified Viewing Key per [ZIP-316](https://zips.z.cash/zip-0316)
|
|
||||||
encodeVK ::
|
|
||||||
BS.ByteString -- ^ Orchard FVK
|
|
||||||
-> BS.ByteString -- ^ Sapling FVK
|
|
||||||
-> BS.ByteString -- ^ Transparent root node
|
|
||||||
-> ZcashNet -- ^ Network
|
|
||||||
-> Bool -- ^ Full?
|
|
||||||
-> T.Text
|
|
||||||
encodeVK ovk svk tvk net full = encodeBech32m (E.encodeUtf8 hr) b
|
|
||||||
where
|
|
||||||
tReceiver = packReceiver 0x00 $ Just tvk
|
|
||||||
b = f4Jumble $ tReceiver <> sReceiver <> oReceiver <> padding
|
|
||||||
hr =
|
|
||||||
if full
|
|
||||||
then case net of
|
|
||||||
MainNet -> uniFullViewingKeyHrp
|
|
||||||
TestNet -> uniTestFullViewingKeyHrp
|
|
||||||
else case net of
|
|
||||||
MainNet -> uniIncomingViewingKeyHrp
|
|
||||||
TestNet -> uniTestIncomingViewingKeyHrp
|
|
||||||
sReceiver = packReceiver 0x02 $ Just svk
|
|
||||||
oReceiver = packReceiver 0x03 $ Just ovk
|
|
||||||
padding = E.encodeUtf8 $ T.justifyLeft 16 '\NUL' hr
|
|
||||||
packReceiver :: Word8 -> Maybe BS.ByteString -> BS.ByteString
|
|
||||||
packReceiver typeCode receiver' =
|
|
||||||
case receiver' of
|
|
||||||
Just receiver ->
|
|
||||||
if BS.length receiver > 1
|
|
||||||
then BS.singleton typeCode `BS.append`
|
|
||||||
(BS.singleton . toEnum . BS.length) receiver `BS.append`
|
|
||||||
receiver
|
|
||||||
else BS.empty
|
|
||||||
Nothing -> BS.empty
|
|
||||||
|
|
|
@ -19,8 +19,6 @@ module ZcashHaskell.Orchard where
|
||||||
|
|
||||||
import C.Zcash
|
import C.Zcash
|
||||||
( rustWrapperCombineOrchardNodes
|
( rustWrapperCombineOrchardNodes
|
||||||
, rustWrapperCreateOrchardFvk
|
|
||||||
, rustWrapperCreateOrchardIvk
|
|
||||||
, rustWrapperGenOrchardReceiver
|
, rustWrapperGenOrchardReceiver
|
||||||
, rustWrapperGenOrchardSpendKey
|
, rustWrapperGenOrchardSpendKey
|
||||||
, rustWrapperGetOrchardRootTest
|
, rustWrapperGetOrchardRootTest
|
||||||
|
@ -39,7 +37,6 @@ import C.Zcash
|
||||||
, rustWrapperReadOrchardWitnessAnchor
|
, rustWrapperReadOrchardWitnessAnchor
|
||||||
, rustWrapperUADecode
|
, rustWrapperUADecode
|
||||||
, rustWrapperUfvkDecode
|
, rustWrapperUfvkDecode
|
||||||
, rustWrapperUivkDecode
|
|
||||||
, rustWrapperUpdateOrchardWitness
|
, rustWrapperUpdateOrchardWitness
|
||||||
)
|
)
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
|
@ -160,15 +157,6 @@ decodeUfvk str =
|
||||||
where
|
where
|
||||||
decodedKey = (withPureBorshVarBuffer . rustWrapperUfvkDecode) str
|
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
|
-- | Check if the given UVK matches the UA given
|
||||||
matchOrchardAddress :: BS.ByteString -> BS.ByteString -> Bool
|
matchOrchardAddress :: BS.ByteString -> BS.ByteString -> Bool
|
||||||
matchOrchardAddress = rustWrapperOrchardCheck
|
matchOrchardAddress = rustWrapperOrchardCheck
|
||||||
|
@ -349,25 +337,3 @@ compareAddress a u =
|
||||||
Sapling s -> s_rec u == Just (sa_receiver s) && ua_net u == net_type s
|
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
|
Transparent t -> t_rec u == Just (ta_receiver t) && ua_net u == ta_network t
|
||||||
Exchange x -> False
|
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
|
import C.Zcash
|
||||||
( rustWrapperCombineSaplingNodes
|
( rustWrapperCombineSaplingNodes
|
||||||
, rustWrapperCreateSaplingFvk
|
|
||||||
, rustWrapperCreateSaplingIvk
|
|
||||||
, rustWrapperDecodeSaplingAddress
|
, rustWrapperDecodeSaplingAddress
|
||||||
, rustWrapperGetSaplingRootTest
|
, rustWrapperGetSaplingRootTest
|
||||||
, rustWrapperIsShielded
|
, rustWrapperIsShielded
|
||||||
|
@ -320,25 +318,3 @@ decodeSaplingAddress sapling_address = do
|
||||||
where
|
where
|
||||||
sa =
|
sa =
|
||||||
withPureBorshVarBuffer $ rustWrapperDecodeSaplingAddress sapling_address
|
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
|
|
||||||
|
|
|
@ -696,18 +696,6 @@ data UnifiedFullViewingKey = UnifiedFullViewingKey
|
||||||
deriving anyclass (Data.Structured.Show)
|
deriving anyclass (Data.Structured.Show)
|
||||||
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct UnifiedFullViewingKey
|
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct UnifiedFullViewingKey
|
||||||
|
|
||||||
-- | Type to represent a Unified Incoming Viewing Key
|
|
||||||
data UnifiedIncomingViewingKey = UnifiedIncomingViewingKey
|
|
||||||
{ i_net :: !Word8 -- ^ Number representing the network the key belongs to. @1@ for @mainnet@, @2@ for @testnet@ and @3@ for @regtestnet@.
|
|
||||||
, i_o_key :: !BS.ByteString -- ^ Raw bytes of the Orchard Incoming Viewing Key as specified in [ZIP-316](https://zips.z.cash/zip-0316)
|
|
||||||
, i_s_key :: !BS.ByteString -- ^ Raw bytes of the Sapling Incoming Viewing Key as specified in [ZIP-316](https://zips.z.cash/zip-0316)
|
|
||||||
, i_t_key :: !BS.ByteString -- ^ Raw bytes of the P2PKH chain code and public key as specified in [ZIP-316](https://zips.z.cash/zip-0316)
|
|
||||||
} deriving stock (Eq, Prelude.Show, GHC.Generic)
|
|
||||||
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
|
|
||||||
deriving anyclass (Data.Structured.Show)
|
|
||||||
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct
|
|
||||||
UnifiedIncomingViewingKey
|
|
||||||
|
|
||||||
-- | Type to represent an Orchard Action as provided by the @getrawtransaction@ RPC method of @zcashd@, and defined in the [Zcash Protocol](https://zips.z.cash/protocol/protocol.pdf)
|
-- | 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
|
data OrchardAction = OrchardAction
|
||||||
{ nf :: !HexString -- ^ The nullifier of the input note
|
{ nf :: !HexString -- ^ The nullifier of the input note
|
||||||
|
|
34
test/Spec.hs
34
test/Spec.hs
|
@ -45,12 +45,7 @@ import Test.HUnit
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
import Test.Hspec.QuickCheck
|
import Test.Hspec.QuickCheck
|
||||||
import Test.QuickCheck
|
import Test.QuickCheck
|
||||||
import ZcashHaskell.Keys
|
import ZcashHaskell.Keys (generateWalletSeedPhrase, getWalletSeed)
|
||||||
( deriveUfvk
|
|
||||||
, deriveUivk
|
|
||||||
, generateWalletSeedPhrase
|
|
||||||
, getWalletSeed
|
|
||||||
)
|
|
||||||
import ZcashHaskell.Orchard
|
import ZcashHaskell.Orchard
|
||||||
import ZcashHaskell.Sapling
|
import ZcashHaskell.Sapling
|
||||||
( decodeSaplingAddress
|
( decodeSaplingAddress
|
||||||
|
@ -1167,33 +1162,6 @@ main = do
|
||||||
Just addr -> do
|
Just addr -> do
|
||||||
let eadr = decodeExchangeAddress (E.encodeUtf8 addr)
|
let eadr = decodeExchangeAddress (E.encodeUtf8 addr)
|
||||||
eadr `shouldNotBe` Nothing
|
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
|
|
||||||
case oK of
|
|
||||||
Nothing -> assertFailure "Failed to generate Orchard SK"
|
|
||||||
Just o ->
|
|
||||||
case sK of
|
|
||||||
Nothing -> assertFailure "Failed to generate Sapling SK"
|
|
||||||
Just s -> do
|
|
||||||
fvk <- deriveUfvk MainNet o s tK
|
|
||||||
decodeUfvk (E.encodeUtf8 fvk) `shouldNotBe` Nothing
|
|
||||||
it "Generate IVK" $ do
|
|
||||||
tK <- genTransparentPrvKey (fromJust seed) MainNetCoin 0
|
|
||||||
case oK of
|
|
||||||
Nothing -> assertFailure "Failed to generate Orchard SK"
|
|
||||||
Just o ->
|
|
||||||
case sK of
|
|
||||||
Nothing -> assertFailure "Failed to generate Sapling SK"
|
|
||||||
Just s -> do
|
|
||||||
ivk <- deriveUivk MainNet o s tK
|
|
||||||
decodeUivk (E.encodeUtf8 ivk) `shouldNotBe` Nothing
|
|
||||||
|
|
||||||
-- | Properties
|
-- | Properties
|
||||||
prop_PhraseLength :: Property
|
prop_PhraseLength :: Property
|
||||||
|
|
|
@ -5,7 +5,7 @@ cabal-version: 3.0
|
||||||
-- see: https://github.com/sol/hpack
|
-- see: https://github.com/sol/hpack
|
||||||
|
|
||||||
name: zcash-haskell
|
name: zcash-haskell
|
||||||
version: 0.7.8.0
|
version: 0.7.7.0
|
||||||
synopsis: Utilities to interact with the Zcash blockchain
|
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>
|
description: Please see the README on the repo at <https://git.vergara.tech/Vergara_Tech/zcash-haskell#readme>
|
||||||
category: Blockchain
|
category: Blockchain
|
||||||
|
|
Loading…
Reference in a new issue