Compare commits

..

4 commits

5 changed files with 238 additions and 145 deletions

View file

@ -59,7 +59,8 @@ use zcash_address::{
use zcash_client_backend::keys::sapling::{ use zcash_client_backend::keys::sapling::{
ExtendedFullViewingKey, ExtendedFullViewingKey,
ExtendedSpendingKey ExtendedSpendingKey,
DiversifiableFullViewingKey
}; };
use zcash_primitives::zip32::{ AccountId, DiversifierIndex }; use zcash_primitives::zip32::{ AccountId, DiversifierIndex };
@ -632,7 +633,7 @@ pub extern "C" fn rust_wrapper_sapling_spendingkey(
out_len: &mut usize out_len: &mut usize
){ ){
let seed: Vec<u8> = marshall_from_haskell_var(iseed, iseed_len, RW); let seed: Vec<u8> = marshall_from_haskell_var(iseed, iseed_len, RW);
if ( seed.len() != 64 ) { if seed.len() != 64 {
// invalid seed length // invalid seed length
marshall_to_haskell_var(&vec![0], out, out_len, RW); marshall_to_haskell_var(&vec![0], out, out_len, RW);
} else { } else {
@ -669,6 +670,36 @@ pub extern "C" fn rust_wrapper_sapling_paymentaddress(
} }
} }
#[no_mangle]
pub extern "C" fn rust_wrapper_sapling_chgpaymentaddress(
extspk: *const u8,
extspk_len: usize,
out: *mut u8,
out_len: &mut usize
){
println!("Entering ChangeAddress generation....");
let vexspk: Vec<u8> = marshall_from_haskell_var(extspk, extspk_len, RW);
let vexspkp = &vexspk;
let extspku8 : &[u8] = &vexspkp;
println!("Received ExtendedSpendingKey in Bytes...\n{:?}\n",extspku8);
let extspk = match ExtendedSpendingKey::from_bytes(&extspku8) {
Ok( k ) => k,
Err( e ) => {
// error recovering ExtendedSpendingKey
println!("\n>>>> Error generating ExtendedSpendingKey");
marshall_to_haskell_var(&vec![0], out, out_len, RW);
return
}
};
println!("ExtendedSpendingKey -> {:?}",extspk);
let dfvk = extspk.to_diversifiable_full_viewing_key();
let ( divIx, cPmtAddress ) = dfvk.change_address();
println!("\nDiversifierIndex > {:?}\n\nChange Payment Address -> {:?}\n ",
divIx, cPmtAddress);
println!("Change Payment Address in bytes : \n{:?}",cPmtAddress.to_bytes());
marshall_to_haskell_var(&cPmtAddress.to_bytes().to_vec(), out, out_len, RW);
}
#[no_mangle] #[no_mangle]
pub extern "C" fn rust_wrapper_derive_orchard_spending_key( pub extern "C" fn rust_wrapper_derive_orchard_spending_key(
seed: *const u8, seed: *const u8,

View file

@ -149,6 +149,13 @@ import ZcashHaskell.Types
-> `()' -> `()'
#} #}
{# fun unsafe rust_wrapper_sapling_chgpaymentaddress as rustWrapperSaplingChgPaymentAddress
{ toBorshVar* `BS.ByteString'&
, getVarBuffer `Buffer (BS.ByteString)'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_derive_orchard_spending_key as rustWrapperGenOrchardSpendKey {# fun unsafe rust_wrapper_derive_orchard_spending_key as rustWrapperGenOrchardSpendKey
{ toBorshVar* `BS.ByteString'& { toBorshVar* `BS.ByteString'&
, `Word32' , `Word32'

View file

@ -22,6 +22,7 @@ import C.Zcash
, rustWrapperSaplingCheck , rustWrapperSaplingCheck
, rustWrapperSaplingNoteDecode , rustWrapperSaplingNoteDecode
, rustWrapperSaplingPaymentAddress , rustWrapperSaplingPaymentAddress
, rustWrapperSaplingChgPaymentAddress
, rustWrapperSaplingSpendingkey , rustWrapperSaplingSpendingkey
, rustWrapperSaplingVkDecode , rustWrapperSaplingVkDecode
, rustWrapperTxParse , rustWrapperTxParse
@ -40,6 +41,7 @@ import ZcashHaskell.Types
, DecodedNote(..) , DecodedNote(..)
, RawData(..) , RawData(..)
, RawTxResponse(..) , RawTxResponse(..)
, SaplingInternalReceiver
, SaplingReceiver , SaplingReceiver
, SaplingSpendingKey(..) , SaplingSpendingKey(..)
, Seed(..) , Seed(..)
@ -93,7 +95,6 @@ instance FromJSON RawTxResponse where
a <- o' .: "actions" a <- o' .: "actions"
pure $ RawTxResponse i h (getShieldedOutputs h) a ht c b pure $ RawTxResponse i h (getShieldedOutputs h) a ht c b
--
-- | Attempts to obtain a sapling SpendingKey using a HDSeed -- | Attempts to obtain a sapling SpendingKey using a HDSeed
genSaplingSpendingKey :: Seed -> Maybe SaplingSpendingKey genSaplingSpendingKey :: Seed -> Maybe SaplingSpendingKey
genSaplingSpendingKey seed = do genSaplingSpendingKey seed = do
@ -103,7 +104,6 @@ genSaplingSpendingKey seed = do
where where
res = withPureBorshVarBuffer (rustWrapperSaplingSpendingkey seed) res = withPureBorshVarBuffer (rustWrapperSaplingSpendingkey seed)
--
-- | Attempts to generate a sapling Payment Address using an ExtendedSpendingKey and a Diversifier Index -- | Attempts to generate a sapling Payment Address using an ExtendedSpendingKey and a Diversifier Index
genSaplingPaymentAddress :: SaplingSpendingKey -> Int -> Maybe SaplingReceiver genSaplingPaymentAddress :: SaplingSpendingKey -> Int -> Maybe SaplingReceiver
genSaplingPaymentAddress extspk i = genSaplingPaymentAddress extspk i =
@ -114,3 +114,8 @@ genSaplingPaymentAddress extspk i =
res = res =
withPureBorshVarBuffer withPureBorshVarBuffer
(rustWrapperSaplingPaymentAddress extspk (fromIntegral i)) (rustWrapperSaplingPaymentAddress extspk (fromIntegral i))
-- | Generate an internal Sapling address
genSaplingInternalAddress :: SaplingSpendingKey -> BS.ByteString -- SaplingInternalReceiver
genSaplingInternalAddress sk = withPureBorshVarBuffer (rustWrapperSaplingChgPaymentAddress sk)

View file

@ -54,6 +54,9 @@ type OrchardSpendingKey = BS.ByteString
-- | A Sapling receiver -- | A Sapling receiver
type SaplingReceiver = BS.ByteString type SaplingReceiver = BS.ByteString
-- | A Sapling internal receiver
type SaplingInternalReceiver = BS.ByteString
-- | An Orchard receiver -- | An Orchard receiver
type OrchardReceiver = BS.ByteString type OrchardReceiver = BS.ByteString

View file

@ -42,6 +42,7 @@ import ZcashHaskell.Orchard
import ZcashHaskell.Sapling import ZcashHaskell.Sapling
( decodeSaplingOutput ( decodeSaplingOutput
, genSaplingPaymentAddress , genSaplingPaymentAddress
, genSaplingInternalAddress
, genSaplingSpendingKey , genSaplingSpendingKey
, getShieldedOutputs , getShieldedOutputs
, isValidSaplingViewingKey , isValidSaplingViewingKey
@ -481,7 +482,7 @@ main = do
Nothing -> "Bad UA" Nothing -> "Bad UA"
Just u -> maybe "No transparent" encodeTransparent $ t_rec u Just u -> maybe "No transparent" encodeTransparent $ t_rec u
msg `shouldBe` "t1LPWuQnjCRH7JAeEErSXKixcUteLJRJjKD" msg `shouldBe` "t1LPWuQnjCRH7JAeEErSXKixcUteLJRJjKD"
describe "Transparent Private and Publicc Key Generation" $ do describe "Transparent Private and Public Key Generation" $ do
it "Obtain a transparent extended private key from HDSeed" $ do it "Obtain a transparent extended private key from HDSeed" $ do
let hdseed = let hdseed =
[ 206 [ 206
@ -578,156 +579,202 @@ main = do
---print $ show xtpubk ---print $ show xtpubk
xtpubk `shouldBe` testpbk xtpubk `shouldBe` testpbk
describe "Sapling SpendingKey test" $ do describe "Sapling SpendingKey test" $ do
let hdseed =
BS.pack $
[ 206
, 61
, 120
, 38
, 206
, 40
, 201
, 62
, 83
, 175
, 151
, 131
, 218
, 141
, 206
, 254
, 28
, 244
, 172
, 213
, 128
, 248
, 156
, 45
, 204
, 44
, 169
, 3
, 162
, 188
, 16
, 173
, 192
, 164
, 96
, 148
, 91
, 52
, 244
, 83
, 149
, 169
, 82
, 196
, 199
, 53
, 177
, 170
, 1
, 6
, 0
, 120
, 170
, 2
, 238
, 219
, 241
, 243
, 172
, 178
, 104
, 81
, 159
, 144
]
--xit "Call function with parameters" $ do
--let msg = genSaplingSpendingKey (word8ArrayToByteString hdseed)
--let msgArr = BS.unpack msg
--if (length msgArr) == 169
--then True
--else False
it "Generate Sapling spending key" $ do it "Generate Sapling spending key" $ do
p <- generateWalletSeedPhrase p <- generateWalletSeedPhrase
let s = getWalletSeed p let s = getWalletSeed p
genSaplingSpendingKey <$> s `shouldNotBe` Nothing genSaplingSpendingKey <$> s `shouldNotBe` Nothing
describe "Sapling Payment Address generation test" $ do describe "Sapling Payment Address generation test" $ do
it "Call genSaplingPaymentAddress" $ do it "Call genSaplingPaymentAddress" $ do
let hdseed1 =
[ 206
, 61
, 120
, 38
, 206
, 40
, 201
, 62
, 83
, 175
, 151
, 131
, 218
, 141
, 206
, 254
, 28
, 244
, 172
, 213
, 128
, 248
, 156
, 45
, 204
, 44
, 169
, 3
, 162
, 188
, 16
, 173
, 192
, 164
, 96
, 148
, 91
, 52
, 244
, 83
, 149
, 169
, 82
, 196
, 199
, 53
, 177
, 170
, 1
, 6
, 0
, 120
, 170
, 2
, 238
, 219
, 241
, 243
, 172
, 178
, 104
, 81
, 159
, 144
] :: [Word8]
p <- generateWalletSeedPhrase p <- generateWalletSeedPhrase
let s = getWalletSeed p let s = getWalletSeed p
genSaplingPaymentAddress (fromMaybe "" s) 0 `shouldNotBe` Nothing genSaplingPaymentAddress (fromMaybe "" s) 0 `shouldNotBe` Nothing
prop "Sapling receivers are valid" $ prop "Sapling receivers are valid" $
forAll genSapArgs $ \(i) -> prop_SaplingReceiver i forAll genSapArgs $ \i -> prop_SaplingReceiver i
describe "Sapling Change Payment Address generation test" $ do
it "Call genSaplingInternalAddress" $ do
let sk = [ 3
, 183
, 26
, 151
, 89
, 0
, 0
, 0
, 128
, 199
, 189
, 33
, 169
, 114
, 194
, 50
, 0
, 139
, 140
, 162
, 100
, 100
, 35
, 58
, 226
, 6
, 47
, 232
, 34
, 214
, 11
, 173
, 142
, 40
, 45
, 163
, 190
, 207
, 49
, 130
, 158
, 113
, 232
, 251
, 79
, 98
, 77
, 195
, 196
, 40
, 42
, 113
, 133
, 35
, 211
, 68
, 146
, 104
, 5
, 56
, 244
, 162
, 55
, 239
, 55
, 112
, 37
, 38
, 189
, 183
, 121
, 201
, 1
, 60
, 158
, 151
, 141
, 123
, 250
, 95
, 169
, 123
, 208
, 56
, 103
, 74
, 85
, 49
, 152
, 207
, 245
, 216
, 58
, 37
, 0
, 127
, 186
, 245
, 234
, 47
, 68
, 11
, 78
, 76
, 12
, 171
, 37
, 63
, 172
, 90
, 111
, 94
, 88
, 152
, 211
, 53
, 243
, 142
, 16
, 195
, 142
, 50
, 14
, 13
, 32
, 91
, 5
, 82
, 182
, 121
, 136
, 109
, 125
, 165
, 125
, 123
, 226
, 54
, 60
, 34
, 62
, 111
, 167
, 88
, 254
, 113
, 204
, 47
, 181
, 97
, 18
, 220
, 46
, 51
, 160
, 62
, 16
, 199
, 143
, 184
, 200
, 209
, 124
, 154
, 175
, 29
, 216
, 48
, 201] :: [Word8]
let cAdr = [31, 232, 31, 17, 195, -- 196
178, 208, 227, 206,
199, 105, 55, 147,
23, 151, 206, 117,
59, 249, 162, 218,
140, 189, 17, 60,
116, 106, 56, 64,
203, 152, 52, 155,
133, 179, 118, 47,
161, 70, 155, 21,
22, 41] :: [Word8]
let bscAdr = BS.pack cAdr
let ca = genSaplingInternalAddress (BS.pack sk)
ca `shouldBe` bscAdr
-- | Properties -- | Properties
prop_PhraseLength :: Int -> Property prop_PhraseLength :: Int -> Property