Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support DRep extended keys #320

Merged
merged 2 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/haskell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:

env:
# Modify this value to "invalidate" the cabal cache.
CABAL_CACHE_VERSION: "2023-09-21"
CABAL_CACHE_VERSION: "2023-10-17"

concurrency:
group: >
Expand Down
12 changes: 11 additions & 1 deletion cardano-api/internal/Cardano/Api/DeserialiseAnyOf.hs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ data SomeAddressVerificationKey
| AVrfVerificationKey (VerificationKey VrfKey)
| AStakeVerificationKey (VerificationKey StakeKey)
| AStakeExtendedVerificationKey (VerificationKey StakeExtendedKey)
| ADRepVerificationKey (VerificationKey DRepKey)
| ADRepExtendedVerificationKey (VerificationKey DRepExtendedKey)
deriving (Show)

renderSomeAddressVerificationKey :: SomeAddressVerificationKey -> Text
Expand All @@ -267,6 +269,8 @@ renderSomeAddressVerificationKey (AKesVerificationKey vk) = serialiseToBech32 vk
renderSomeAddressVerificationKey (AVrfVerificationKey vk) = serialiseToBech32 vk
renderSomeAddressVerificationKey (AStakeVerificationKey vk) = serialiseToBech32 vk
renderSomeAddressVerificationKey (AStakeExtendedVerificationKey vk) = serialiseToBech32 vk
renderSomeAddressVerificationKey (ADRepVerificationKey vk) = serialiseToBech32 vk
renderSomeAddressVerificationKey (ADRepExtendedVerificationKey vk) = serialiseToBech32 vk


mapSomeAddressVerificationKey :: ()
Expand All @@ -284,6 +288,8 @@ mapSomeAddressVerificationKey f = \case
AVrfVerificationKey vk -> f vk
AStakeVerificationKey vk -> f vk
AStakeExtendedVerificationKey vk -> f vk
ADRepVerificationKey vk -> f vk
ADRepExtendedVerificationKey vk -> f vk

-- | Internal function to pretty render byron keys
prettyByronVerificationKey :: VerificationKey ByronKey-> Text
Expand Down Expand Up @@ -311,7 +317,9 @@ deserialiseAnyVerificationKeyBech32 =
allBech32VerKey
:: [FromSomeType SerialiseAsBech32 SomeAddressVerificationKey]
allBech32VerKey =
[ FromSomeType (AsVerificationKey AsPaymentKey) APaymentVerificationKey
[ FromSomeType (AsVerificationKey AsDRepKey) ADRepVerificationKey
, FromSomeType (AsVerificationKey AsDRepExtendedKey) ADRepExtendedVerificationKey
, FromSomeType (AsVerificationKey AsPaymentKey) APaymentVerificationKey
, FromSomeType (AsVerificationKey AsPaymentExtendedKey) APaymentExtendedVerificationKey
, FromSomeType (AsVerificationKey AsKesKey) AKesVerificationKey
, FromSomeType (AsVerificationKey AsVrfKey) AVrfVerificationKey
Expand All @@ -329,6 +337,8 @@ deserialiseAnyVerificationKeyTextEnvelope bs =
:: [FromSomeType HasTextEnvelope SomeAddressVerificationKey]
allTextEnvelopeCBOR =
[ FromSomeType (AsVerificationKey AsByronKey) AByronVerificationKey
, FromSomeType (AsVerificationKey AsDRepKey) ADRepVerificationKey
, FromSomeType (AsVerificationKey AsDRepExtendedKey) ADRepExtendedVerificationKey
, FromSomeType (AsVerificationKey AsPaymentKey) APaymentVerificationKey
, FromSomeType (AsVerificationKey AsPaymentExtendedKey) APaymentExtendedVerificationKey
, FromSomeType (AsVerificationKey AsStakeExtendedKey) AStakeExtendedVerificationKey
Expand Down
118 changes: 118 additions & 0 deletions cardano-api/internal/Cardano/Api/Keys/Shelley.hs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module Cardano.Api.Keys.Shelley (
CommitteeColdKey,
CommitteeHotKey,
DRepKey,
DRepExtendedKey,
PaymentKey,
PaymentExtendedKey,
StakeKey,
Expand Down Expand Up @@ -1605,6 +1606,123 @@ instance HasTextEnvelope (SigningKey DRepKey) where
proxy :: Proxy (Shelley.DSIGN StandardCrypto)
proxy = Proxy

---
--- Drep extended keys
---
data DRepExtendedKey

instance HasTypeProxy DRepExtendedKey where
data AsType DRepExtendedKey = AsDRepExtendedKey
proxyToAsType _ = AsDRepExtendedKey

instance Key DRepExtendedKey where

newtype VerificationKey DRepExtendedKey =
DRepExtendedVerificationKey Crypto.HD.XPub
deriving stock (Eq)
deriving anyclass SerialiseAsCBOR
deriving (Show, IsString) via UsingRawBytesHex (VerificationKey PaymentExtendedKey)

newtype SigningKey DRepExtendedKey =
DRepExtendedSigningKey Crypto.HD.XPrv
deriving anyclass SerialiseAsCBOR
deriving (Show, IsString) via UsingRawBytesHex (SigningKey PaymentExtendedKey)

deterministicSigningKey :: AsType DRepExtendedKey
-> Crypto.Seed
-> SigningKey DRepExtendedKey
deterministicSigningKey AsDRepExtendedKey seed =
DRepExtendedSigningKey
(Crypto.HD.generate seedbs BS.empty)
where
(seedbs, _) = Crypto.getBytesFromSeedT 32 seed

deterministicSigningKeySeedSize :: AsType DRepExtendedKey -> Word
deterministicSigningKeySeedSize AsDRepExtendedKey = 32

getVerificationKey :: SigningKey DRepExtendedKey
-> VerificationKey DRepExtendedKey
getVerificationKey (DRepExtendedSigningKey sk) =
DRepExtendedVerificationKey (Crypto.HD.toXPub sk)

-- | We use the hash of the normal non-extended pub key so that it is
-- consistent with the one used in addresses and signatures.
--
verificationKeyHash :: VerificationKey DRepExtendedKey
-> Hash DRepExtendedKey
verificationKeyHash (DRepExtendedVerificationKey vk) =
DRepExtendedKeyHash
. Shelley.KeyHash
. Crypto.castHash
$ Crypto.hashWith Crypto.HD.xpubPublicKey vk

newtype instance Hash DRepExtendedKey =
DRepExtendedKeyHash { unDRepExtendedKeyHash :: Shelley.KeyHash Shelley.DRepRole StandardCrypto }
deriving stock (Eq, Ord)
deriving (Show, IsString) via UsingRawBytesHex (Hash DRepKey)
deriving (ToCBOR, FromCBOR) via UsingRawBytes (Hash DRepKey)
deriving anyclass SerialiseAsCBOR

instance ToCBOR (VerificationKey DRepExtendedKey) where
toCBOR (DRepExtendedVerificationKey xpub) =
toCBOR (Crypto.HD.unXPub xpub)

instance FromCBOR (VerificationKey DRepExtendedKey) where
fromCBOR = do
bs <- fromCBOR
either fail (return . DRepExtendedVerificationKey)
(Crypto.HD.xpub (bs :: ByteString))

instance ToCBOR (SigningKey DRepExtendedKey) where
toCBOR (DRepExtendedSigningKey xprv) =
toCBOR (Crypto.HD.unXPrv xprv)

instance FromCBOR (SigningKey DRepExtendedKey) where
fromCBOR = do
bs <- fromCBOR
either fail (return . DRepExtendedSigningKey)
(Crypto.HD.xprv (bs :: ByteString))

instance SerialiseAsRawBytes (VerificationKey DRepExtendedKey) where
serialiseToRawBytes (DRepExtendedVerificationKey xpub) =
Crypto.HD.unXPub xpub

deserialiseFromRawBytes (AsVerificationKey AsDRepExtendedKey) bs =
first
(const (SerialiseAsRawBytesError "Unable to deserialise VerificationKey DRepExtendedKey"))
(DRepExtendedVerificationKey <$> Crypto.HD.xpub bs)

instance SerialiseAsRawBytes (SigningKey DRepExtendedKey) where
serialiseToRawBytes (DRepExtendedSigningKey xprv) =
Crypto.HD.unXPrv xprv

deserialiseFromRawBytes (AsSigningKey AsDRepExtendedKey) bs =
first
(const (SerialiseAsRawBytesError "Unable to deserialise SigningKey DRepExtendedKey"))
(DRepExtendedSigningKey <$> Crypto.HD.xprv bs)

instance SerialiseAsRawBytes (Hash DRepExtendedKey) where
serialiseToRawBytes (DRepExtendedKeyHash (Shelley.KeyHash vkh)) =
Crypto.hashToBytes vkh

deserialiseFromRawBytes (AsHash AsDRepExtendedKey) bs =
maybeToRight (SerialiseAsRawBytesError "Unable to deserialise Hash DRepExtendedKey") $
DRepExtendedKeyHash . Shelley.KeyHash <$> Crypto.hashFromBytes bs

instance HasTextEnvelope (VerificationKey DRepExtendedKey) where
textEnvelopeType _ = "DRepExtendedVerificationKey_ed25519_bip32"

instance HasTextEnvelope (SigningKey DRepExtendedKey) where
textEnvelopeType _ = "DRepExtendedSigningKey_ed25519_bip32"

instance SerialiseAsBech32 (VerificationKey DRepExtendedKey) where
bech32PrefixFor _ = "drep_xvk"
bech32PrefixesPermitted _ = ["drep_xvk"]

instance SerialiseAsBech32 (SigningKey DRepExtendedKey) where
bech32PrefixFor _ = "drep_xsk"
bech32PrefixesPermitted _ = ["drep_xsk"]

--
-- Committee keys
--
Expand Down