{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE PatternSynonyms #-}
module Cardano.Crypto.Wallet
( ChainCode(..)
, DerivationScheme(..)
, DerivationIndex
, pattern LatestScheme
, XPrv
, XPub(..)
, XSignature
, generate
, generateNew
, xprv
, xpub
, xsignature
, unXPrv
, unXPub
, unXSignature
, toXPub
, xPubGetPublicKey
, xPrvChangePass
, deriveXPrv
, deriveXPub
, sign
, verify
) where
import Basement.Compat.Typeable
import Control.DeepSeq (NFData)
import Control.Arrow (second)
import Crypto.Error (throwCryptoError, CryptoFailable(..), CryptoError(..))
import qualified Crypto.MAC.HMAC as HMAC
import qualified Crypto.PubKey.Ed25519 as Ed25519
import Crypto.KDF.PBKDF2 (fastPBKDF2_SHA512, Parameters(..))
import Data.ByteArray (ByteArrayAccess, convert)
import qualified Data.ByteArray as B (append, length, splitAt)
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as BC
import Data.Hashable (Hashable)
import Data.Word
import GHC.Generics (Generic)
import Cardano.Crypto.Wallet.Encrypted
import Cardano.Crypto.Wallet.Pure ( hFinalize,
hInitSeed)
import Cardano.Crypto.Wallet.Types
import GHC.Stack
newtype XPrv = XPrv EncryptedKey
deriving (XPrv -> ()
(XPrv -> ()) -> NFData XPrv
forall a. (a -> ()) -> NFData a
rnf :: XPrv -> ()
$crnf :: XPrv -> ()
NFData, Typeable, XPrv -> Int
XPrv -> Ptr p -> IO ()
XPrv -> (Ptr p -> IO a) -> IO a
(XPrv -> Int)
-> (forall p a. XPrv -> (Ptr p -> IO a) -> IO a)
-> (forall p. XPrv -> Ptr p -> IO ())
-> ByteArrayAccess XPrv
forall p. XPrv -> Ptr p -> IO ()
forall ba.
(ba -> Int)
-> (forall p a. ba -> (Ptr p -> IO a) -> IO a)
-> (forall p. ba -> Ptr p -> IO ())
-> ByteArrayAccess ba
forall p a. XPrv -> (Ptr p -> IO a) -> IO a
copyByteArrayToPtr :: XPrv -> Ptr p -> IO ()
$ccopyByteArrayToPtr :: forall p. XPrv -> Ptr p -> IO ()
withByteArray :: XPrv -> (Ptr p -> IO a) -> IO a
$cwithByteArray :: forall p a. XPrv -> (Ptr p -> IO a) -> IO a
length :: XPrv -> Int
$clength :: XPrv -> Int
ByteArrayAccess)
data XPub = XPub
{ XPub -> ByteString
xpubPublicKey :: !ByteString
, XPub -> ChainCode
xpubChaincode :: !ChainCode
} deriving (XPub -> XPub -> Bool
(XPub -> XPub -> Bool) -> (XPub -> XPub -> Bool) -> Eq XPub
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: XPub -> XPub -> Bool
$c/= :: XPub -> XPub -> Bool
== :: XPub -> XPub -> Bool
$c== :: XPub -> XPub -> Bool
Eq, Int -> XPub -> ShowS
[XPub] -> ShowS
XPub -> String
(Int -> XPub -> ShowS)
-> (XPub -> String) -> ([XPub] -> ShowS) -> Show XPub
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [XPub] -> ShowS
$cshowList :: [XPub] -> ShowS
show :: XPub -> String
$cshow :: XPub -> String
showsPrec :: Int -> XPub -> ShowS
$cshowsPrec :: Int -> XPub -> ShowS
Show, Eq XPub
Eq XPub
-> (XPub -> XPub -> Ordering)
-> (XPub -> XPub -> Bool)
-> (XPub -> XPub -> Bool)
-> (XPub -> XPub -> Bool)
-> (XPub -> XPub -> Bool)
-> (XPub -> XPub -> XPub)
-> (XPub -> XPub -> XPub)
-> Ord XPub
XPub -> XPub -> Bool
XPub -> XPub -> Ordering
XPub -> XPub -> XPub
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: XPub -> XPub -> XPub
$cmin :: XPub -> XPub -> XPub
max :: XPub -> XPub -> XPub
$cmax :: XPub -> XPub -> XPub
>= :: XPub -> XPub -> Bool
$c>= :: XPub -> XPub -> Bool
> :: XPub -> XPub -> Bool
$c> :: XPub -> XPub -> Bool
<= :: XPub -> XPub -> Bool
$c<= :: XPub -> XPub -> Bool
< :: XPub -> XPub -> Bool
$c< :: XPub -> XPub -> Bool
compare :: XPub -> XPub -> Ordering
$ccompare :: XPub -> XPub -> Ordering
$cp1Ord :: Eq XPub
Ord, Typeable, (forall x. XPub -> Rep XPub x)
-> (forall x. Rep XPub x -> XPub) -> Generic XPub
forall x. Rep XPub x -> XPub
forall x. XPub -> Rep XPub x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep XPub x -> XPub
$cfrom :: forall x. XPub -> Rep XPub x
Generic)
instance NFData XPub
instance Hashable XPub
newtype XSignature = XSignature
{ XSignature -> ByteString
unXSignature :: ByteString
} deriving (Int -> XSignature -> ShowS
[XSignature] -> ShowS
XSignature -> String
(Int -> XSignature -> ShowS)
-> (XSignature -> String)
-> ([XSignature] -> ShowS)
-> Show XSignature
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [XSignature] -> ShowS
$cshowList :: [XSignature] -> ShowS
show :: XSignature -> String
$cshow :: XSignature -> String
showsPrec :: Int -> XSignature -> ShowS
$cshowsPrec :: Int -> XSignature -> ShowS
Show, XSignature -> XSignature -> Bool
(XSignature -> XSignature -> Bool)
-> (XSignature -> XSignature -> Bool) -> Eq XSignature
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: XSignature -> XSignature -> Bool
$c/= :: XSignature -> XSignature -> Bool
== :: XSignature -> XSignature -> Bool
$c== :: XSignature -> XSignature -> Bool
Eq, Eq XSignature
Eq XSignature
-> (XSignature -> XSignature -> Ordering)
-> (XSignature -> XSignature -> Bool)
-> (XSignature -> XSignature -> Bool)
-> (XSignature -> XSignature -> Bool)
-> (XSignature -> XSignature -> Bool)
-> (XSignature -> XSignature -> XSignature)
-> (XSignature -> XSignature -> XSignature)
-> Ord XSignature
XSignature -> XSignature -> Bool
XSignature -> XSignature -> Ordering
XSignature -> XSignature -> XSignature
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: XSignature -> XSignature -> XSignature
$cmin :: XSignature -> XSignature -> XSignature
max :: XSignature -> XSignature -> XSignature
$cmax :: XSignature -> XSignature -> XSignature
>= :: XSignature -> XSignature -> Bool
$c>= :: XSignature -> XSignature -> Bool
> :: XSignature -> XSignature -> Bool
$c> :: XSignature -> XSignature -> Bool
<= :: XSignature -> XSignature -> Bool
$c<= :: XSignature -> XSignature -> Bool
< :: XSignature -> XSignature -> Bool
$c< :: XSignature -> XSignature -> Bool
compare :: XSignature -> XSignature -> Ordering
$ccompare :: XSignature -> XSignature -> Ordering
$cp1Ord :: Eq XSignature
Ord, XSignature -> ()
(XSignature -> ()) -> NFData XSignature
forall a. (a -> ()) -> NFData a
rnf :: XSignature -> ()
$crnf :: XSignature -> ()
NFData, Int -> XSignature -> Int
XSignature -> Int
(Int -> XSignature -> Int)
-> (XSignature -> Int) -> Hashable XSignature
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: XSignature -> Int
$chash :: XSignature -> Int
hashWithSalt :: Int -> XSignature -> Int
$chashWithSalt :: Int -> XSignature -> Int
Hashable, XSignature -> Int
XSignature -> Ptr p -> IO ()
XSignature -> (Ptr p -> IO a) -> IO a
(XSignature -> Int)
-> (forall p a. XSignature -> (Ptr p -> IO a) -> IO a)
-> (forall p. XSignature -> Ptr p -> IO ())
-> ByteArrayAccess XSignature
forall p. XSignature -> Ptr p -> IO ()
forall ba.
(ba -> Int)
-> (forall p a. ba -> (Ptr p -> IO a) -> IO a)
-> (forall p. ba -> Ptr p -> IO ())
-> ByteArrayAccess ba
forall p a. XSignature -> (Ptr p -> IO a) -> IO a
copyByteArrayToPtr :: XSignature -> Ptr p -> IO ()
$ccopyByteArrayToPtr :: forall p. XSignature -> Ptr p -> IO ()
withByteArray :: XSignature -> (Ptr p -> IO a) -> IO a
$cwithByteArray :: forall p a. XSignature -> (Ptr p -> IO a) -> IO a
length :: XSignature -> Int
$clength :: XSignature -> Int
ByteArrayAccess)
generate :: (ByteArrayAccess passPhrase, ByteArrayAccess seed)
=> seed
-> passPhrase
-> XPrv
generate :: seed -> passPhrase -> XPrv
generate seed
seed passPhrase
passPhrase
| seed -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length seed
seed Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
32 = String -> XPrv
forall a. HasCallStack => String -> a
error (String
"Wallet.generate: seed needs to be >= 32 bytes, got : " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (seed -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length seed
seed))
| Bool
otherwise = Int -> XPrv
loop Int
1
where
phrase :: Int -> ByteString
phrase :: Int -> ByteString
phrase Int
i = ByteString
"Root Seed Chain " ByteString -> ByteString -> ByteString
forall bs. ByteArray bs => bs -> bs -> bs
`B.append` String -> ByteString
BC.pack (Int -> String
forall a. Show a => a -> String
show Int
i)
loop :: Int -> XPrv
loop Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1000 = String -> XPrv
forall a. HasCallStack => String -> a
error String
"internal error: Wallet.generate looping forever"
| Bool
otherwise =
case ByteString
-> passPhrase -> ChainCode -> CryptoFailable EncryptedKey
forall passphrase secret cc.
(ByteArrayAccess passphrase, ByteArrayAccess secret,
ByteArrayAccess cc) =>
secret -> passphrase -> cc -> CryptoFailable EncryptedKey
encryptedCreate ByteString
iL passPhrase
passPhrase ChainCode
iR of
CryptoPassed EncryptedKey
k -> EncryptedKey -> XPrv
XPrv EncryptedKey
k
CryptoFailed CryptoError
err
| CryptoError
err CryptoError -> CryptoError -> Bool
forall a. Eq a => a -> a -> Bool
== CryptoError
CryptoError_SecretKeyStructureInvalid -> Int -> XPrv
loop (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
| Bool
otherwise -> String -> XPrv
forall a. HasCallStack => String -> a
error String
"internal error: Wallet.generate: got error from encryptedCreate"
where (ByteString
iL, ChainCode
iR) = Context SHA512 -> (ByteString, ChainCode)
hFinalize
(Context SHA512 -> (ByteString, ChainCode))
-> Context SHA512 -> (ByteString, ChainCode)
forall a b. (a -> b) -> a -> b
$ (Context SHA512 -> ByteString -> Context SHA512)
-> ByteString -> Context SHA512 -> Context SHA512
forall a b c. (a -> b -> c) -> b -> a -> c
flip Context SHA512 -> ByteString -> Context SHA512
forall message a.
(ByteArrayAccess message, HashAlgorithm a) =>
Context a -> message -> Context a
HMAC.update (Int -> ByteString
phrase Int
i)
(Context SHA512 -> Context SHA512)
-> Context SHA512 -> Context SHA512
forall a b. (a -> b) -> a -> b
$ seed -> Context SHA512
forall seed. ByteArrayAccess seed => seed -> Context SHA512
hInitSeed seed
seed
generateNew :: (ByteArrayAccess keyPassPhrase, ByteArrayAccess generationPassPhrase, ByteArrayAccess seed)
=> seed
-> generationPassPhrase
-> keyPassPhrase
-> XPrv
generateNew :: seed -> generationPassPhrase -> keyPassPhrase -> XPrv
generateNew seed
seed generationPassPhrase
genPassPhrase keyPassPhrase
memPassPhrase =
EncryptedKey -> XPrv
XPrv (EncryptedKey -> XPrv) -> EncryptedKey -> XPrv
forall a b. (a -> b) -> a -> b
$ ByteString -> keyPassPhrase -> EncryptedKey
forall passphrase secret.
(ByteArrayAccess passphrase, ByteArrayAccess secret) =>
secret -> passphrase -> EncryptedKey
encryptedCreateDirectWithTweak ByteString
out keyPassPhrase
memPassPhrase
where
out :: ByteString
out :: ByteString
out = Parameters -> generationPassPhrase -> seed -> ByteString
forall password salt out.
(ByteArrayAccess password, ByteArrayAccess salt, ByteArray out) =>
Parameters -> password -> salt -> out
fastPBKDF2_SHA512 (Int -> Int -> Parameters
Parameters Int
4096 Int
96) generationPassPhrase
genPassPhrase seed
seed
xprv :: ByteArrayAccess bin => bin -> Either String XPrv
xprv :: bin -> Either String XPrv
xprv bin
bs =
Either String XPrv
-> (EncryptedKey -> Either String XPrv)
-> Maybe EncryptedKey
-> Either String XPrv
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> Either String XPrv
forall a b. a -> Either a b
Left String
"error: xprv needs to be 128 bytes") (XPrv -> Either String XPrv
forall a b. b -> Either a b
Right (XPrv -> Either String XPrv)
-> (EncryptedKey -> XPrv) -> EncryptedKey -> Either String XPrv
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EncryptedKey -> XPrv
XPrv)
(Maybe EncryptedKey -> Either String XPrv)
-> Maybe EncryptedKey -> Either String XPrv
forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe EncryptedKey
encryptedKey
(ByteString -> Maybe EncryptedKey)
-> ByteString -> Maybe EncryptedKey
forall a b. (a -> b) -> a -> b
$ bin -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert bin
bs
unXPrv :: XPrv -> ByteString
unXPrv :: XPrv -> ByteString
unXPrv (XPrv EncryptedKey
e) = EncryptedKey -> ByteString
unEncryptedKey EncryptedKey
e
xpub :: ByteString -> Either String XPub
xpub :: ByteString -> Either String XPub
xpub ByteString
bs
| ByteString -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
64 = String -> Either String XPub
forall a b. a -> Either a b
Left (String
"error: xprv needs to be 64 bytes: got " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (ByteString -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length ByteString
bs) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" bytes")
| Bool
otherwise =
let (ByteString
b1, ByteString
b2) = Int -> ByteString -> (ByteString, ByteString)
forall bs. ByteArray bs => Int -> bs -> (bs, bs)
B.splitAt Int
32 ByteString
bs
in XPub -> Either String XPub
forall a b. b -> Either a b
Right (XPub -> Either String XPub) -> XPub -> Either String XPub
forall a b. (a -> b) -> a -> b
$ ByteString -> ChainCode -> XPub
XPub ByteString
b1 (ByteString -> ChainCode
ChainCode (ByteString -> ChainCode) -> ByteString -> ChainCode
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert ByteString
b2)
unXPub :: XPub -> ByteString
unXPub :: XPub -> ByteString
unXPub (XPub ByteString
pub (ChainCode ByteString
cc)) = ByteString -> ByteString -> ByteString
forall bs. ByteArray bs => bs -> bs -> bs
B.append ByteString
pub ByteString
cc
xsignature :: ByteString -> Either String XSignature
xsignature :: ByteString -> Either String XSignature
xsignature ByteString
bs
| ByteString -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
64 = String -> Either String XSignature
forall a b. a -> Either a b
Left (String
"error: xsignature needs to be 64 bytes: got " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (ByteString -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length ByteString
bs) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" bytes")
| Bool
otherwise = XSignature -> Either String XSignature
forall a b. b -> Either a b
Right (XSignature -> Either String XSignature)
-> XSignature -> Either String XSignature
forall a b. (a -> b) -> a -> b
$ ByteString -> XSignature
XSignature ByteString
bs
toXPub :: HasCallStack => XPrv -> XPub
toXPub :: XPrv -> XPub
toXPub (XPrv EncryptedKey
ekey) = ByteString -> ChainCode -> XPub
XPub ByteString
pub (ByteString -> ChainCode
ChainCode ByteString
cc)
where (ByteString
_,ByteString
r) = Int -> ByteString -> (ByteString, ByteString)
forall bs. ByteArray bs => Int -> bs -> (bs, bs)
B.splitAt Int
64 (ByteString -> (ByteString, ByteString))
-> ByteString -> (ByteString, ByteString)
forall a b. (a -> b) -> a -> b
$ EncryptedKey -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert EncryptedKey
ekey
(ByteString
pub, ByteString
cc) = Int -> ByteString -> (ByteString, ByteString)
forall bs. ByteArray bs => Int -> bs -> (bs, bs)
B.splitAt Int
32 ByteString
r
xPubGetPublicKey :: XPub -> Ed25519.PublicKey
xPubGetPublicKey :: XPub -> PublicKey
xPubGetPublicKey (XPub ByteString
pub ChainCode
_) =
CryptoFailable PublicKey -> PublicKey
forall a. CryptoFailable a -> a
throwCryptoError (CryptoFailable PublicKey -> PublicKey)
-> CryptoFailable PublicKey -> PublicKey
forall a b. (a -> b) -> a -> b
$ ByteString -> CryptoFailable PublicKey
forall ba. ByteArrayAccess ba => ba -> CryptoFailable PublicKey
Ed25519.publicKey ByteString
pub
xPrvChangePass :: (ByteArrayAccess oldPassPhrase, ByteArrayAccess newPassPhrase)
=> oldPassPhrase
-> newPassPhrase
-> XPrv
-> XPrv
xPrvChangePass :: oldPassPhrase -> newPassPhrase -> XPrv -> XPrv
xPrvChangePass oldPassPhrase
oldPass newPassPhrase
newPass (XPrv EncryptedKey
ekey) =
EncryptedKey -> XPrv
XPrv (EncryptedKey -> XPrv) -> EncryptedKey -> XPrv
forall a b. (a -> b) -> a -> b
$ oldPassPhrase -> newPassPhrase -> EncryptedKey -> EncryptedKey
forall oldPassPhrase newPassPhrase.
(ByteArrayAccess oldPassPhrase, ByteArrayAccess newPassPhrase) =>
oldPassPhrase -> newPassPhrase -> EncryptedKey -> EncryptedKey
encryptedChangePass oldPassPhrase
oldPass newPassPhrase
newPass EncryptedKey
ekey
deriveXPrv :: ByteArrayAccess passPhrase => DerivationScheme -> passPhrase -> XPrv -> Word32 -> XPrv
deriveXPrv :: DerivationScheme -> passPhrase -> XPrv -> Word32 -> XPrv
deriveXPrv DerivationScheme
ds passPhrase
passPhrase (XPrv EncryptedKey
ekey) Word32
n =
EncryptedKey -> XPrv
XPrv (DerivationScheme
-> EncryptedKey -> passPhrase -> Word32 -> EncryptedKey
forall passphrase.
ByteArrayAccess passphrase =>
DerivationScheme
-> EncryptedKey -> passphrase -> Word32 -> EncryptedKey
encryptedDerivePrivate DerivationScheme
ds EncryptedKey
ekey passPhrase
passPhrase Word32
n)
deriveXPub :: DerivationScheme -> XPub -> Word32 -> Maybe XPub
deriveXPub :: DerivationScheme -> XPub -> Word32 -> Maybe XPub
deriveXPub DerivationScheme
ds (XPub ByteString
pub (ChainCode ByteString
cc)) Word32
n
| Word32
n Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word32
0x80000000 = Maybe XPub
forall a. Maybe a
Nothing
| Bool
otherwise = XPub -> Maybe XPub
forall a. a -> Maybe a
Just (XPub -> Maybe XPub) -> XPub -> Maybe XPub
forall a b. (a -> b) -> a -> b
$ (ByteString -> ChainCode -> XPub)
-> (ByteString, ChainCode) -> XPub
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ByteString -> ChainCode -> XPub
XPub ((ByteString, ChainCode) -> XPub)
-> (ByteString, ChainCode) -> XPub
forall a b. (a -> b) -> a -> b
$ (ByteString -> ChainCode)
-> (ByteString, ByteString) -> (ByteString, ChainCode)
forall (a :: Type -> Type -> Type) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second ByteString -> ChainCode
ChainCode ((ByteString, ByteString) -> (ByteString, ChainCode))
-> (ByteString, ByteString) -> (ByteString, ChainCode)
forall a b. (a -> b) -> a -> b
$ DerivationScheme
-> (ByteString, ByteString) -> Word32 -> (ByteString, ByteString)
encryptedDerivePublic DerivationScheme
ds (ByteString
pub,ByteString
cc) Word32
n
sign :: (ByteArrayAccess passPhrase, ByteArrayAccess msg)
=> passPhrase
-> XPrv
-> msg
-> XSignature
sign :: passPhrase -> XPrv -> msg -> XSignature
sign passPhrase
passphrase (XPrv EncryptedKey
ekey) msg
ba =
ByteString -> XSignature
XSignature (ByteString -> XSignature) -> ByteString -> XSignature
forall a b. (a -> b) -> a -> b
$ let (Signature ByteString
sig) = EncryptedKey -> passPhrase -> msg -> Signature
forall passphrase msg.
(ByteArrayAccess passphrase, ByteArrayAccess msg) =>
EncryptedKey -> passphrase -> msg -> Signature
encryptedSign EncryptedKey
ekey passPhrase
passphrase msg
ba in ByteString
sig
verify :: ByteArrayAccess msg => XPub -> msg -> XSignature -> Bool
verify :: XPub -> msg -> XSignature -> Bool
verify (XPub ByteString
point ChainCode
_) msg
ba (XSignature ByteString
signature) =
let pub :: PublicKey
pub = CryptoFailable PublicKey -> PublicKey
forall a. CryptoFailable a -> a
throwCryptoError (CryptoFailable PublicKey -> PublicKey)
-> CryptoFailable PublicKey -> PublicKey
forall a b. (a -> b) -> a -> b
$ ByteString -> CryptoFailable PublicKey
forall ba. ByteArrayAccess ba => ba -> CryptoFailable PublicKey
Ed25519.publicKey ByteString
point
sig :: Signature
sig = CryptoFailable Signature -> Signature
forall a. CryptoFailable a -> a
throwCryptoError (CryptoFailable Signature -> Signature)
-> CryptoFailable Signature -> Signature
forall a b. (a -> b) -> a -> b
$ ByteString -> CryptoFailable Signature
forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature
Ed25519.signature ByteString
signature
in PublicKey -> msg -> Signature -> Bool
forall ba.
ByteArrayAccess ba =>
PublicKey -> ba -> Signature -> Bool
Ed25519.verify PublicKey
pub msg
ba Signature
sig