Addition of functinality for manipulating Unified Addresses and Viewing Keys #1

Merged
pitmutt merged 17 commits from dev020 into master 2023-12-04 16:31:17 +00:00
5 changed files with 65 additions and 1 deletions
Showing only changes of commit 1d558fc646 - Show all commits

View file

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- `matchOrchardAddress` function to ensure a UA matches a UVK and corresponding tests
- `makeZcashCall` function moved into this library
- `RpcResponse`, `RpcCall` types moved into this library
- Functions to decode Sapling transactions

View file

@ -47,7 +47,7 @@ use zcash_primitives::{
use zcash_address::{
Network,
unified::{Address, Encoding, Ufvk, Container, Fvk},
unified::{Address, Encoding, Ufvk, Container, Fvk, Receiver},
ZcashAddress
};
@ -320,6 +320,42 @@ pub extern "C" fn rust_wrapper_svk_check_address(
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_ufvk_check_address(
key_input: *const u8,
key_input_len: usize,
address_input: *const u8,
address_input_len: usize
) -> bool {
let key: String = marshall_from_haskell_var(key_input, key_input_len, RW);
let addy: String = marshall_from_haskell_var(address_input, address_input_len, RW);
let dec_key = Ufvk::decode(&key);
let dec_addy = Address::decode(&addy);
match dec_key {
Ok((n, ufvk)) => {
let i = ufvk.items();
if let Fvk::Orchard(k) = i[0] {
let orch_key = FullViewingKey::from_bytes(&k).unwrap();
let orch_addy = orch_key.address_at(0u32, Scope::External).to_raw_address_bytes();
match dec_addy {
Ok((n, recs)) => {
let j = recs.items();
j[0] == Receiver::Orchard(orch_addy)
},
Err(_e) => {
false
}
}
} else {
false
}
},
Err(_e) => {
false
}
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_ufvk_decode(
input: *const u8,

View file

@ -72,6 +72,13 @@ import ZcashHaskell.Types
-> `Bool'
#}
{# fun pure unsafe rust_wrapper_ufvk_check_address as rustWrapperOrchardCheck
{ toBorshVar* `BS.ByteString'&
, toBorshVar* `BS.ByteString'&
}
-> `Bool'
#}
{# fun unsafe rust_wrapper_sapling_note_decrypt_v2 as rustWrapperSaplingNoteDecode
{ toBorshVar* `BS.ByteString'&
, toBorshVar* `BS.ByteString'&

View file

@ -13,6 +13,7 @@ module ZcashHaskell.Orchard where
import C.Zcash
( rustWrapperIsUA
, rustWrapperOrchardCheck
, rustWrapperOrchardNoteDecode
, rustWrapperUfvkDecode
)
@ -33,6 +34,10 @@ decodeUfvk str =
where
decodedKey = (withPureBorshVarBuffer . rustWrapperUfvkDecode) str
-- | Check if the given UVK matches the UA given
matchOrchardAddress :: BS.ByteString -> BS.ByteString -> Bool
matchOrchardAddress = rustWrapperOrchardCheck
-- | Attempts to decode the given @OrchardAction@ using the given @UnifiedFullViewingKey@.
decryptOrchardAction ::
UnifiedFullViewingKey -> OrchardAction -> Maybe DecodedNote

View file

@ -2,14 +2,17 @@
import C.Zcash (rustWrapperIsUA)
import Data.Aeson
import Data.Bool (Bool(True))
import qualified Data.ByteString as BS
import qualified Data.Text as T
import qualified Data.Text.Encoding as E
import qualified Data.Text.Lazy.Encoding as LE
import qualified Data.Text.Lazy.IO as LTIO
import Data.Word
import GHC.Float.RealFracMethods (properFractionDoubleInteger)
import Test.Hspec
import ZcashHaskell.Orchard
import ZcashHaskell.Orchard (matchOrchardAddress)
import ZcashHaskell.Sapling
( decodeSaplingOutput
, getShieldedOutputs
@ -28,6 +31,7 @@ import ZcashHaskell.Types
, decodeHexText
)
import ZcashHaskell.Utils
import ZcashHaskell.Utils (decodeBech32)
main :: IO ()
main = do
@ -312,6 +316,17 @@ main = do
let fakeUvk =
"uview1u83changinga987bundchofch4ract3r5x8hqsw6vzw63n24atxpcatws82z092kryazuu6d7rayyut8m36wm4wpjy2z8r9hj48fx5pf49gw4sjrq8503qpz3vqj5hg0vg9vsqeasg5qjuyh94uyfm7v76udqcm2m0wfc25hcyqswcn56xxduq3xkgxkr0l73cjy88fdvf90eq5fda9g6x7yv7d0uckpevxg6540wc76xrc4axxvlt03ptaa2a0rektglmdy68656f3uzcdgqqyu0t7wk5cvwghyyvgqc0rp3vgu5ye4nd236ml57rjh083a2755qemf6dk6pw0qrnfm7246s8eg2hhzkzpf9h73chhng7xhmyem2sjh8rs2m9nhfcslsgenm"
decodeUfvk fakeUvk `shouldBe` Nothing
describe "Check if UA and UVK match" $ do
let ua =
"u15hjz9v46azzmdept050heh8795qxzwy2pykg097lg69jpk4qzah90cj2q4amq0c07gta60x8qgw00qewcy3hg9kv9h6zjkh3jc66vr40u6uu2dxmqkqhypud95vm0gq7y5ga7c8psdqgthsrwvgd676a2pavpcd4euwwapgackxa3qhvga0wnl0k6vncskxlq94vqwjd7zepy3qd5jh"
let ua' =
"u17n7hpwaujyq7ux8f9jpyymtnk5urw7pyrf60smp5mawy7jgz325hfvz3jn3zsfya8yxryf9q7ldk8nu8df0emra5wne28zq9d9nm2pu4x6qwjha565av9aze0xgujgslz74ufkj0c0cylqwjyrh9msjfh7jzal6d3qzrnhkkqy3pqm8j63y07jxj7txqeac982778rmt64f32aum94x"
let uvk =
"uview1u833rp8yykd7h4druwht6xp6k8krle45fx8hqsw6vzw63n24atxpcatws82z092kryazuu6d7rayyut8m36wm4wpjy2z8r9hj48fx5pf49gw4sjrq8503qpz3vqj5hg0vg9vsqeasg5qjuyh94uyfm7v76udqcm2m0wfc25hcyqswcn56xxduq3xkgxkr0l73cjy88fdvf90eq5fda9g6x7yv7d0uckpevxg6540wc76xrc4axxvlt03ptaa2a0rektglmdy68656f3uzcdgqqyu0t7wk5cvwghyyvgqc0rp3vgu5ye4nd236ml57rjh083a2755qemf6dk6pw0qrnfm7246s8eg2hhzkzpf9h73chhng7xhmyem2sjh8rs2m9nhfcslsgenm"
it "succeeds with correct address" $ do
matchOrchardAddress uvk ua `shouldBe` True
it "fails with wrong address" $ do
matchOrchardAddress uvk ua' `shouldBe` False
describe "Decode Sapling tx" $ do
let svk =
"zxviews1qvapd723qqqqpqq09ldgykvyusthmkky2w062esx5xg3nz4m29qxcvndyx6grrhrdepu4ns88sjr3u6mfp2hhwj5hfd6y24r0f64uwq65vjrmsh9mr568kenk33fcumag6djcjywkm5v295egjuk3qdd47atprs0j33nhaaqep3uqspzp5kg4mthugvug0sc3gc83atkrgmguw9g7gkvh82tugrntf66lnvyeh6ufh4j2xt0xr2r4zujtm3qvrmd3vvnulycuwqtetg2jk384"