{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_HADDOCK prune #-}
module Cardano.Address.Derivation
(
Index
, indexToWord32
, indexFromWord32
, wholeDomainIndex
, coerceWholeDomainIndex
, nextIndex
, Depth (..)
, DerivationType (..)
, GenMasterKey (..)
, HardDerivation (..)
, SoftDerivation (..)
, XPrv
, xprvFromBytes
, xprvToBytes
, xprvPrivateKey
, xprvChainCode
, toXPub
, XPub
, xpubFromBytes
, xpubToBytes
, xpubPublicKey
, xpubChainCode
, XSignature
, sign
, verify
, DerivationScheme (..)
, deriveXPrv
, deriveXPub
, generate
, generateNew
, hashCredential
, hashWalletId
, credentialHashSize
, unsafeMkIndex
) where
import Prelude
import Cardano.Crypto.Wallet
( DerivationScheme (..) )
import Cardano.Mnemonic
( SomeMnemonic )
import Control.DeepSeq
( NFData )
import Crypto.Error
( eitherCryptoError )
import Crypto.Hash
( hash )
import Crypto.Hash.Algorithms
( Blake2b_160 (..), Blake2b_224 (..) )
import Crypto.Hash.IO
( HashAlgorithm (hashDigestSize) )
import Data.ByteArray
( ByteArrayAccess, ScrubbedBytes )
import Data.ByteString
( ByteString )
import Data.Coerce
( coerce )
import Data.Either.Extra
( eitherToMaybe )
import Data.Kind
( Type )
import Data.String
( fromString )
import Data.Word
( Word32 )
import Fmt
( Buildable (..) )
import GHC.Generics
( Generic )
import GHC.Stack
( HasCallStack )
import qualified Cardano.Crypto.Wallet as CC
import qualified Crypto.ECC.Edwards25519 as Ed25519
import qualified Data.ByteArray as BA
import qualified Data.ByteString as BS
type XPrv = CC.XPrv
type XPub = CC.XPub
type XSignature = CC.XSignature
xpubFromBytes :: ByteString -> Maybe XPub
xpubFromBytes :: ByteString -> Maybe XPub
xpubFromBytes = Either String XPub -> Maybe XPub
forall a b. Either a b -> Maybe b
eitherToMaybe (Either String XPub -> Maybe XPub)
-> (ByteString -> Either String XPub) -> ByteString -> Maybe XPub
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either String XPub
CC.xpub
xpubToBytes :: XPub -> ByteString
xpubToBytes :: XPub -> ByteString
xpubToBytes XPub
xpub = XPub -> ByteString
xpubPublicKey XPub
xpub ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> XPub -> ByteString
xpubChainCode XPub
xpub
xpubPublicKey :: XPub -> ByteString
xpubPublicKey :: XPub -> ByteString
xpubPublicKey (CC.XPub ByteString
pub ChainCode
_cc) = ByteString
pub
xpubChainCode :: XPub -> ByteString
xpubChainCode :: XPub -> ByteString
xpubChainCode (CC.XPub ByteString
_pub (CC.ChainCode ByteString
cc)) = ByteString
cc
xprvFromBytes :: ByteString -> Maybe XPrv
xprvFromBytes :: ByteString -> Maybe XPrv
xprvFromBytes ByteString
bytes
| ByteString -> Int
BS.length ByteString
bytes Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
96 = Maybe XPrv
forall a. Maybe a
Nothing
| Bool
otherwise = do
let (ByteString
prv, ByteString
cc) = Int -> ByteString -> (ByteString, ByteString)
BS.splitAt Int
64 ByteString
bytes
ByteString
pub <- ByteString -> Maybe ByteString
ed25519ScalarMult (Int -> ByteString -> ByteString
BS.take Int
32 ByteString
prv)
Either String XPrv -> Maybe XPrv
forall a b. Either a b -> Maybe b
eitherToMaybe (Either String XPrv -> Maybe XPrv)
-> Either String XPrv -> Maybe XPrv
forall a b. (a -> b) -> a -> b
$ ByteString -> Either String XPrv
forall bin. ByteArrayAccess bin => bin -> Either String XPrv
CC.xprv (ByteString -> Either String XPrv)
-> ByteString -> Either String XPrv
forall a b. (a -> b) -> a -> b
$ ByteString
prv ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
pub ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
cc
where
ed25519ScalarMult :: ByteString -> Maybe ByteString
ed25519ScalarMult :: ByteString -> Maybe ByteString
ed25519ScalarMult ByteString
bs = do
Scalar
scalar <- Either CryptoError Scalar -> Maybe Scalar
forall a b. Either a b -> Maybe b
eitherToMaybe (Either CryptoError Scalar -> Maybe Scalar)
-> Either CryptoError Scalar -> Maybe Scalar
forall a b. (a -> b) -> a -> b
$ CryptoFailable Scalar -> Either CryptoError Scalar
forall a. CryptoFailable a -> Either CryptoError a
eitherCryptoError (CryptoFailable Scalar -> Either CryptoError Scalar)
-> CryptoFailable Scalar -> Either CryptoError Scalar
forall a b. (a -> b) -> a -> b
$ ByteString -> CryptoFailable Scalar
forall bs. ByteArrayAccess bs => bs -> CryptoFailable Scalar
Ed25519.scalarDecodeLong ByteString
bs
ByteString -> Maybe ByteString
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> Maybe ByteString) -> ByteString -> Maybe ByteString
forall a b. (a -> b) -> a -> b
$ Point -> ByteString
forall bs. ByteArray bs => Point -> bs
Ed25519.pointEncode (Point -> ByteString) -> Point -> ByteString
forall a b. (a -> b) -> a -> b
$ Scalar -> Point
Ed25519.toPoint Scalar
scalar
xprvToBytes :: XPrv -> ByteString
xprvToBytes :: XPrv -> ByteString
xprvToBytes XPrv
xprv =
XPrv -> ByteString
xprvPrivateKey XPrv
xprv ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> XPrv -> ByteString
xprvChainCode XPrv
xprv
xprvPrivateKey :: XPrv -> ByteString
xprvPrivateKey :: XPrv -> ByteString
xprvPrivateKey = Int -> ByteString -> ByteString
BS.take Int
64 (ByteString -> ByteString)
-> (XPrv -> ByteString) -> XPrv -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XPrv -> ByteString
CC.unXPrv
xprvChainCode :: XPrv -> ByteString
xprvChainCode :: XPrv -> ByteString
xprvChainCode = Int -> ByteString -> ByteString
BS.drop Int
96 (ByteString -> ByteString)
-> (XPrv -> ByteString) -> XPrv -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XPrv -> ByteString
CC.unXPrv
toXPub :: HasCallStack => XPrv -> XPub
toXPub :: XPrv -> XPub
toXPub = HasCallStack => XPrv -> XPub
XPrv -> XPub
CC.toXPub
sign
:: ByteArrayAccess msg
=> XPrv
-> msg
-> XSignature
sign :: XPrv -> msg -> XSignature
sign =
ScrubbedBytes -> XPrv -> msg -> XSignature
forall passPhrase msg.
(ByteArrayAccess passPhrase, ByteArrayAccess msg) =>
passPhrase -> XPrv -> msg -> XSignature
CC.sign (ScrubbedBytes
forall a. Monoid a => a
mempty :: ScrubbedBytes)
verify
:: ByteArrayAccess msg
=> XPub
-> msg
-> XSignature
-> Bool
verify :: XPub -> msg -> XSignature -> Bool
verify =
XPub -> msg -> XSignature -> Bool
forall msg.
ByteArrayAccess msg =>
XPub -> msg -> XSignature -> Bool
CC.verify
deriveXPrv
:: DerivationScheme
-> XPrv
-> Index derivationType depth
-> XPrv
deriveXPrv :: DerivationScheme -> XPrv -> Index derivationType depth -> XPrv
deriveXPrv DerivationScheme
ds XPrv
prv (Index Word32
ix) =
DerivationScheme -> ScrubbedBytes -> XPrv -> Word32 -> XPrv
forall passPhrase.
ByteArrayAccess passPhrase =>
DerivationScheme -> passPhrase -> XPrv -> Word32 -> XPrv
CC.deriveXPrv DerivationScheme
ds (ScrubbedBytes
forall a. Monoid a => a
mempty :: ScrubbedBytes) XPrv
prv Word32
ix
deriveXPub
:: DerivationScheme
-> XPub
-> Index derivationType depth
-> Maybe XPub
deriveXPub :: DerivationScheme
-> XPub -> Index derivationType depth -> Maybe XPub
deriveXPub DerivationScheme
ds XPub
pub (Index Word32
ix) =
DerivationScheme -> XPub -> Word32 -> Maybe XPub
CC.deriveXPub DerivationScheme
ds XPub
pub Word32
ix
generate
:: ByteArrayAccess seed
=> seed
-> XPrv
generate :: seed -> XPrv
generate seed
seed =
seed -> ScrubbedBytes -> XPrv
forall passPhrase seed.
(ByteArrayAccess passPhrase, ByteArrayAccess seed) =>
seed -> passPhrase -> XPrv
CC.generate seed
seed (ScrubbedBytes
forall a. Monoid a => a
mempty :: ScrubbedBytes)
generateNew
:: (ByteArrayAccess seed, ByteArrayAccess sndFactor)
=> seed
-> sndFactor
-> XPrv
generateNew :: seed -> sndFactor -> XPrv
generateNew seed
seed sndFactor
sndFactor =
seed -> sndFactor -> ScrubbedBytes -> XPrv
forall keyPassPhrase generationPassPhrase seed.
(ByteArrayAccess keyPassPhrase,
ByteArrayAccess generationPassPhrase, ByteArrayAccess seed) =>
seed -> generationPassPhrase -> keyPassPhrase -> XPrv
CC.generateNew seed
seed sndFactor
sndFactor (ScrubbedBytes
forall a. Monoid a => a
mempty :: ScrubbedBytes)
hashCredential :: ByteString -> ByteString
hashCredential :: ByteString -> ByteString
hashCredential =
Digest Blake2b_224 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert (Digest Blake2b_224 -> ByteString)
-> (ByteString -> Digest Blake2b_224) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteArrayAccess ByteString, HashAlgorithm Blake2b_224) =>
ByteString -> Digest Blake2b_224
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
hash @_ @Blake2b_224
hashWalletId :: ByteString -> ByteString
hashWalletId :: ByteString -> ByteString
hashWalletId =
Digest Blake2b_160 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert (Digest Blake2b_160 -> ByteString)
-> (ByteString -> Digest Blake2b_160) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteArrayAccess ByteString, HashAlgorithm Blake2b_160) =>
ByteString -> Digest Blake2b_160
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
hash @_ @Blake2b_160
credentialHashSize :: Int
credentialHashSize :: Int
credentialHashSize = Blake2b_224 -> Int
forall a. HashAlgorithm a => a -> Int
hashDigestSize Blake2b_224
Blake2b_224
data Depth = RootK | AccountK | PaymentK | DelegationK | ScriptK | PolicyK
newtype Index (derivationType :: DerivationType) (depth :: Depth) = Index
{ Index derivationType depth -> Word32
indexToWord32 :: Word32
}
deriving stock ((forall x.
Index derivationType depth -> Rep (Index derivationType depth) x)
-> (forall x.
Rep (Index derivationType depth) x -> Index derivationType depth)
-> Generic (Index derivationType depth)
forall x.
Rep (Index derivationType depth) x -> Index derivationType depth
forall x.
Index derivationType depth -> Rep (Index derivationType depth) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (derivationType :: DerivationType) (depth :: Depth) x.
Rep (Index derivationType depth) x -> Index derivationType depth
forall (derivationType :: DerivationType) (depth :: Depth) x.
Index derivationType depth -> Rep (Index derivationType depth) x
$cto :: forall (derivationType :: DerivationType) (depth :: Depth) x.
Rep (Index derivationType depth) x -> Index derivationType depth
$cfrom :: forall (derivationType :: DerivationType) (depth :: Depth) x.
Index derivationType depth -> Rep (Index derivationType depth) x
Generic, Int -> Index derivationType depth -> ShowS
[Index derivationType depth] -> ShowS
Index derivationType depth -> String
(Int -> Index derivationType depth -> ShowS)
-> (Index derivationType depth -> String)
-> ([Index derivationType depth] -> ShowS)
-> Show (Index derivationType depth)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (derivationType :: DerivationType) (depth :: Depth).
Int -> Index derivationType depth -> ShowS
forall (derivationType :: DerivationType) (depth :: Depth).
[Index derivationType depth] -> ShowS
forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth -> String
showList :: [Index derivationType depth] -> ShowS
$cshowList :: forall (derivationType :: DerivationType) (depth :: Depth).
[Index derivationType depth] -> ShowS
show :: Index derivationType depth -> String
$cshow :: forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth -> String
showsPrec :: Int -> Index derivationType depth -> ShowS
$cshowsPrec :: forall (derivationType :: DerivationType) (depth :: Depth).
Int -> Index derivationType depth -> ShowS
Show, Index derivationType depth -> Index derivationType depth -> Bool
(Index derivationType depth -> Index derivationType depth -> Bool)
-> (Index derivationType depth
-> Index derivationType depth -> Bool)
-> Eq (Index derivationType depth)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth -> Index derivationType depth -> Bool
/= :: Index derivationType depth -> Index derivationType depth -> Bool
$c/= :: forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth -> Index derivationType depth -> Bool
== :: Index derivationType depth -> Index derivationType depth -> Bool
$c== :: forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth -> Index derivationType depth -> Bool
Eq, Eq (Index derivationType depth)
Eq (Index derivationType depth)
-> (Index derivationType depth
-> Index derivationType depth -> Ordering)
-> (Index derivationType depth
-> Index derivationType depth -> Bool)
-> (Index derivationType depth
-> Index derivationType depth -> Bool)
-> (Index derivationType depth
-> Index derivationType depth -> Bool)
-> (Index derivationType depth
-> Index derivationType depth -> Bool)
-> (Index derivationType depth
-> Index derivationType depth -> Index derivationType depth)
-> (Index derivationType depth
-> Index derivationType depth -> Index derivationType depth)
-> Ord (Index derivationType depth)
Index derivationType depth -> Index derivationType depth -> Bool
Index derivationType depth
-> Index derivationType depth -> Ordering
Index derivationType depth
-> Index derivationType depth -> Index derivationType depth
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
forall (derivationType :: DerivationType) (depth :: Depth).
Eq (Index derivationType depth)
forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth -> Index derivationType depth -> Bool
forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth
-> Index derivationType depth -> Ordering
forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth
-> Index derivationType depth -> Index derivationType depth
min :: Index derivationType depth
-> Index derivationType depth -> Index derivationType depth
$cmin :: forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth
-> Index derivationType depth -> Index derivationType depth
max :: Index derivationType depth
-> Index derivationType depth -> Index derivationType depth
$cmax :: forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth
-> Index derivationType depth -> Index derivationType depth
>= :: Index derivationType depth -> Index derivationType depth -> Bool
$c>= :: forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth -> Index derivationType depth -> Bool
> :: Index derivationType depth -> Index derivationType depth -> Bool
$c> :: forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth -> Index derivationType depth -> Bool
<= :: Index derivationType depth -> Index derivationType depth -> Bool
$c<= :: forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth -> Index derivationType depth -> Bool
< :: Index derivationType depth -> Index derivationType depth -> Bool
$c< :: forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth -> Index derivationType depth -> Bool
compare :: Index derivationType depth
-> Index derivationType depth -> Ordering
$ccompare :: forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth
-> Index derivationType depth -> Ordering
$cp1Ord :: forall (derivationType :: DerivationType) (depth :: Depth).
Eq (Index derivationType depth)
Ord)
instance NFData (Index derivationType depth)
instance Bounded (Index 'Hardened depth) where
minBound :: Index 'Hardened depth
minBound = Word32 -> Index 'Hardened depth
forall (derivationType :: DerivationType) (depth :: Depth).
Word32 -> Index derivationType depth
Index Word32
0x80000000
maxBound :: Index 'Hardened depth
maxBound = Word32 -> Index 'Hardened depth
forall (derivationType :: DerivationType) (depth :: Depth).
Word32 -> Index derivationType depth
Index Word32
forall a. Bounded a => a
maxBound
instance Bounded (Index 'Soft depth) where
minBound :: Index 'Soft depth
minBound = Word32 -> Index 'Soft depth
forall (derivationType :: DerivationType) (depth :: Depth).
Word32 -> Index derivationType depth
Index Word32
forall a. Bounded a => a
minBound
maxBound :: Index 'Soft depth
maxBound = let (Index Word32
ix) = Bounded (Index 'Hardened Any) => Index 'Hardened Any
forall a. Bounded a => a
minBound @(Index 'Hardened _) in Word32 -> Index 'Soft depth
forall (derivationType :: DerivationType) (depth :: Depth).
Word32 -> Index derivationType depth
Index (Word32
ix Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
1)
instance Bounded (Index 'WholeDomain depth) where
minBound :: Index 'WholeDomain depth
minBound = Word32 -> Index 'WholeDomain depth
forall (derivationType :: DerivationType) (depth :: Depth).
Word32 -> Index derivationType depth
Index Word32
forall a. Bounded a => a
minBound
maxBound :: Index 'WholeDomain depth
maxBound = Word32 -> Index 'WholeDomain depth
forall (derivationType :: DerivationType) (depth :: Depth).
Word32 -> Index derivationType depth
Index Word32
forall a. Bounded a => a
maxBound
unsafeMkIndex :: Word32 -> Index ty depth
unsafeMkIndex :: Word32 -> Index ty depth
unsafeMkIndex = Word32 -> Index ty depth
forall (derivationType :: DerivationType) (depth :: Depth).
Word32 -> Index derivationType depth
Index
indexFromWord32
:: forall ix derivationType depth.
(ix ~ Index derivationType depth, Bounded ix)
=> Word32 -> Maybe ix
indexFromWord32 :: Word32 -> Maybe ix
indexFromWord32 Word32
ix
| Word32
ix Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Index derivationType depth -> Word32
forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth -> Word32
indexToWord32 (Bounded ix => ix
forall a. Bounded a => a
minBound @ix) Bool -> Bool -> Bool
&& Word32
ix Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
<= Index derivationType depth -> Word32
forall (derivationType :: DerivationType) (depth :: Depth).
Index derivationType depth -> Word32
indexToWord32 (Bounded ix => ix
forall a. Bounded a => a
maxBound @ix) =
Index derivationType depth -> Maybe (Index derivationType depth)
forall a. a -> Maybe a
Just (Word32 -> Index derivationType depth
forall (derivationType :: DerivationType) (depth :: Depth).
Word32 -> Index derivationType depth
Index Word32
ix)
| Bool
otherwise =
Maybe ix
forall a. Maybe a
Nothing
nextIndex
:: forall ix derivationType depth.
(ix ~ Index derivationType depth, Bounded ix)
=> ix -> Maybe ix
nextIndex :: ix -> Maybe ix
nextIndex (Index ix) = Word32 -> Maybe ix
forall ix (derivationType :: DerivationType) (depth :: Depth).
(ix ~ Index derivationType depth, Bounded ix) =>
Word32 -> Maybe ix
indexFromWord32 (Word32
ix Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
1)
wholeDomainIndex :: Word32 -> Index 'WholeDomain depth
wholeDomainIndex :: Word32 -> Index 'WholeDomain depth
wholeDomainIndex = Word32 -> Index 'WholeDomain depth
forall (derivationType :: DerivationType) (depth :: Depth).
Word32 -> Index derivationType depth
Index
coerceWholeDomainIndex :: Index ty depth0 -> Index 'WholeDomain depth1
coerceWholeDomainIndex :: Index ty depth0 -> Index 'WholeDomain depth1
coerceWholeDomainIndex = Index ty depth0 -> Index 'WholeDomain depth1
coerce
instance Buildable (Index derivationType depth) where
build :: Index derivationType depth -> Builder
build (Index Word32
ix) = String -> Builder
forall a. IsString a => String -> a
fromString (Word32 -> String
forall a. Show a => a -> String
show Word32
ix)
data DerivationType = Hardened | Soft | WholeDomain
class HardDerivation (key :: Depth -> Type -> Type) where
type AccountIndexDerivationType key :: DerivationType
type AddressIndexDerivationType key :: DerivationType
type WithRole key :: Type
deriveAccountPrivateKey
:: key 'RootK XPrv
-> Index (AccountIndexDerivationType key) 'AccountK
-> key 'AccountK XPrv
deriveAddressPrivateKey
:: key 'AccountK XPrv
-> WithRole key
-> Index (AddressIndexDerivationType key) 'PaymentK
-> key 'PaymentK XPrv
class HardDerivation key => SoftDerivation (key :: Depth -> Type -> Type) where
deriveAddressPublicKey
:: key 'AccountK XPub
-> WithRole key
-> Index 'Soft 'PaymentK
-> key 'PaymentK XPub
class GenMasterKey (key :: Depth -> Type -> Type) where
type SecondFactor key :: Type
genMasterKeyFromMnemonic
:: SomeMnemonic -> SecondFactor key -> key 'RootK XPrv
genMasterKeyFromXPrv
:: XPrv -> key 'RootK XPrv