Add functions and tests for Bech32 and F4UnJumble

This commit is contained in:
Rene Vergara 2023-04-27 09:50:07 -05:00
parent 6c8a67f2d7
commit ccd4ede950
Signed by: pitmutt
GPG key ID: 65122AD495A7F5B2
5 changed files with 156 additions and 10 deletions

View file

@ -30,6 +30,7 @@ library:
- borsh >= 0.2 - borsh >= 0.2
- text - text
- foreign-rust - foreign-rust
- generics-sop
pkg-config-dependencies: pkg-config-dependencies:
- rustzcash_wrapper-uninstalled - rustzcash_wrapper-uninstalled
@ -45,3 +46,4 @@ tests:
- zcash-haskell - zcash-haskell
- hspec - hspec
- bytestring - bytestring
- text

View file

@ -1,4 +1,6 @@
{-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DerivingVia #-} {-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE UndecidableInstances #-}
@ -18,16 +20,25 @@ import Foreign.Rust.Marshall.Fixed
import Foreign.Rust.Marshall.Variable import Foreign.Rust.Marshall.Variable
import Foreign.Rust.Serialisation.Raw import Foreign.Rust.Serialisation.Raw
import Foreign.Rust.Serialisation.Raw.Base16 import Foreign.Rust.Serialisation.Raw.Base16
import qualified Generics.SOP as SOP
import qualified GHC.Generics as GHC
newtype CodedString = CodedString BS.ByteString data RawData = RawData { hrp :: BS.ByteString, bytes :: BS.ByteString}
deriving (Eq) deriving stock (Prelude.Show, GHC.Generic)
deriving newtype (BorshSize, ToBorsh, FromBorsh) deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
deriving newtype (IsRaw) deriving anyclass (Data.Structured.Show)
deriving (Prelude.Show, Data.Structured.Show) via AsBase16 CodedString deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct RawData
{# fun unsafe rust_wrapper_f4jumble as rustWrapperF4Jumble {# fun unsafe rust_wrapper_f4jumble as rustWrapperF4Jumble
{ toBorshVar* `BS.ByteString'& { toBorshVar* `BS.ByteString'&
, getVarBuffer `Buffer (CodedString)'& , getVarBuffer `Buffer (BS.ByteString)'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_f4unjumble as rustWrapperF4UnJumble
{ toBorshVar* `BS.ByteString'&
, getVarBuffer `Buffer (BS.ByteString)'&
} }
-> `()' -> `()'
#} #}
@ -43,3 +54,10 @@ newtype CodedString = CodedString BS.ByteString
} }
-> `Bool' -> `Bool'
#} #}
{# fun unsafe rust_wrapper_bech32decode as rustWrapperBech32Decode
{ toBorshVar* `BS.ByteString'&
, getVarBuffer `Buffer RawData'&
}
-> `()'
#}

View file

@ -1,12 +1,16 @@
module Zcash module Zcash
( f4Jumble ( f4Jumble
, f4UnJumble
, isValidUnifiedAddress , isValidUnifiedAddress
, isValidShieldedAddress , isValidShieldedAddress
, decodeBech32
) where ) where
import C.Zcash import C.Zcash
( CodedString ( RawData
, rustWrapperBech32Decode
, rustWrapperF4Jumble , rustWrapperF4Jumble
, rustWrapperF4UnJumble
, rustWrapperIsShielded , rustWrapperIsShielded
, rustWrapperIsUA , rustWrapperIsUA
) )
@ -14,11 +18,17 @@ import qualified Data.ByteString as BS
import Foreign.Rust.Marshall.Fixed import Foreign.Rust.Marshall.Fixed
import Foreign.Rust.Marshall.Variable import Foreign.Rust.Marshall.Variable
f4Jumble :: BS.ByteString -> CodedString f4Jumble :: BS.ByteString -> BS.ByteString
f4Jumble = withPureBorshVarBuffer . rustWrapperF4Jumble f4Jumble = withPureBorshVarBuffer . rustWrapperF4Jumble
f4UnJumble :: BS.ByteString -> BS.ByteString
f4UnJumble = withPureBorshVarBuffer . rustWrapperF4UnJumble
isValidUnifiedAddress :: BS.ByteString -> Bool isValidUnifiedAddress :: BS.ByteString -> Bool
isValidUnifiedAddress = rustWrapperIsUA isValidUnifiedAddress = rustWrapperIsUA
isValidShieldedAddress :: BS.ByteString -> Bool isValidShieldedAddress :: BS.ByteString -> Bool
isValidShieldedAddress = rustWrapperIsShielded isValidShieldedAddress = rustWrapperIsShielded
decodeBech32 :: BS.ByteString -> RawData
decodeBech32 = withPureBorshVarBuffer . rustWrapperBech32Decode

View file

@ -1,7 +1,8 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
import C.Zcash (CodedString(CodedString), rustWrapperIsUA) import C.Zcash (RawData(..), rustWrapperIsUA)
import qualified Data.ByteString as BS import qualified Data.ByteString as BS
import qualified Data.Text.Encoding as E
import Data.Word import Data.Word
import Test.Hspec import Test.Hspec
import Zcash import Zcash
@ -111,7 +112,120 @@ main = do
, 0x8d , 0x8d
, 0x22 , 0x22
] :: [Word8] ] :: [Word8]
CodedString (BS.pack out) `shouldBe` f4Jumble (BS.pack input) BS.pack out `shouldBe` f4Jumble (BS.pack input)
it "unjumble a string" $ do
let input =
[ 0x5d
, 0x7a
, 0x8f
, 0x73
, 0x9a
, 0x2d
, 0x9e
, 0x94
, 0x5b
, 0x0c
, 0xe1
, 0x52
, 0xa8
, 0x04
, 0x9e
, 0x29
, 0x4c
, 0x4d
, 0x6e
, 0x66
, 0xb1
, 0x64
, 0x93
, 0x9d
, 0xaf
, 0xfa
, 0x2e
, 0xf6
, 0xee
, 0x69
, 0x21
, 0x48
, 0x1c
, 0xdd
, 0x86
, 0xb3
, 0xcc
, 0x43
, 0x18
, 0xd9
, 0x61
, 0x4f
, 0xc8
, 0x20
, 0x90
, 0x5d
, 0x04
, 0x2b
] :: [Word8]
let out =
[ 0x03
, 0x04
, 0xd0
, 0x29
, 0x14
, 0x1b
, 0x99
, 0x5d
, 0xa5
, 0x38
, 0x7c
, 0x12
, 0x59
, 0x70
, 0x67
, 0x35
, 0x04
, 0xd6
, 0xc7
, 0x64
, 0xd9
, 0x1e
, 0xa6
, 0xc0
, 0x82
, 0x12
, 0x37
, 0x70
, 0xc7
, 0x13
, 0x9c
, 0xcd
, 0x88
, 0xee
, 0x27
, 0x36
, 0x8c
, 0xd0
, 0xc0
, 0x92
, 0x1a
, 0x04
, 0x44
, 0xc8
, 0xe5
, 0x85
, 0x8d
, 0x22
] :: [Word8]
f4UnJumble (BS.pack out) `shouldBe` BS.pack input
describe "Decode UVK from YWallet" $ do
let uvk =
"uview1u833rp8yykd7h4druwht6xp6k8krle45fx8hqsw6vzw63n24atxpcatws82z092kryazuu6d7rayyut8m36wm4wpjy2z8r9hj48fx5pf49gw4sjrq8503qpz3vqj5hg0vg9vsqeasg5qjuyh94uyfm7v76udqcm2m0wfc25hcyqswcn56xxduq3xkgxkr0l73cjy88fdvf90eq5fda9g6x7yv7d0uckpevxg6540wc76xrc4axxvlt03ptaa2a0rektglmdy68656f3uzcdgqqyu0t7wk5cvwghyyvgqc0rp3vgu5ye4nd236ml57rjh083a2755qemf6dk6pw0qrnfm7246s8eg2hhzkzpf9h73chhng7xhmyem2sjh8rs2m9nhfcslsgenm"
let res = decodeBech32 uvk
let rawBytes = f4UnJumble $ bytes res
it "decodes Bech32" $ do
print $ hrp res
print $ BS.length $ bytes res
hrp res `shouldBe` "uview"
it "unjumble result" $ do
BS.takeEnd 16 rawBytes `shouldBe` "uview00000000000"
describe "Unified address" $ do describe "Unified address" $ do
it "succeeds with correct UA" $ do it "succeeds with correct UA" $ do
let ua = let ua =

View file

@ -39,6 +39,7 @@ library
, borsh >=0.2 , borsh >=0.2
, bytestring , bytestring
, foreign-rust , foreign-rust
, generics-sop
, text , text
default-language: Haskell2010 default-language: Haskell2010
@ -54,5 +55,6 @@ test-suite zcash-haskell-test
base >=4.7 && <5 base >=4.7 && <5
, bytestring , bytestring
, hspec , hspec
, text
, zcash-haskell , zcash-haskell
default-language: Haskell2010 default-language: Haskell2010