-
Notifications
You must be signed in to change notification settings - Fork 213
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
Derive token policy forging keys according to CIP-1855 #2774
Changes from all commits
1cb2ff7
726386f
35f6d12
a14f6cb
fb7d7ef
c1015f7
c149e55
1a74768
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
{-# LANGUAGE DataKinds #-} | ||
|
||
-- | | ||
-- Copyright: © 2018-2021 IOHK | ||
-- License: Apache-2.0 | ||
-- | ||
-- Derivation of policy keys which are used to create scripts for the purposes | ||
-- of minting and burning. Derived according to CIP-1855 | ||
-- (https:/cardano-foundation/CIPs/blob/b2e9d02cb9a71ba9e754a432c78197428abf7e4c/CIP-1855/CIP-1855.md). | ||
-- | ||
-- The policy keys are derived from the following path: | ||
-- | ||
-- m / purpose' / coin_type' / policy_ix' | ||
-- m / 1855' / 1815' / [2^31 .. 2^32-1]' | ||
-- | ||
-- Where purpose' and coin_type' are fixed, and each new policy_ix' represents a | ||
-- different policy key. | ||
|
||
module Cardano.Wallet.Primitive.AddressDerivation.MintBurn | ||
( -- * Constants | ||
purposeCIP1855 | ||
-- * Helpers | ||
, derivePolicyKeyAndHash | ||
, derivePolicyPrivateKey | ||
) where | ||
|
||
import Prelude | ||
|
||
import Cardano.Address.Derivation | ||
( XPrv ) | ||
import Cardano.Address.Script | ||
( KeyHash ) | ||
import Cardano.Crypto.Wallet | ||
( deriveXPrv ) | ||
import Cardano.Crypto.Wallet.Types | ||
( DerivationScheme (DerivationScheme2) ) | ||
import Cardano.Wallet.Primitive.AddressDerivation | ||
( Depth (..) | ||
, DerivationType (..) | ||
, Index (..) | ||
, Passphrase (..) | ||
, WalletKey | ||
, getIndex | ||
, getRawKey | ||
, hashVerificationKey | ||
, liftRawKey | ||
, publicKey | ||
) | ||
import Cardano.Wallet.Primitive.AddressDiscovery | ||
( coinTypeAda ) | ||
|
||
import qualified Cardano.Address.Script as CA | ||
|
||
-- | Purpose for forged policy keys is a constant set to 1855' (or 0x8000073F) | ||
-- following the original CIP-1855: "Forging policy keys for HD Wallets". | ||
-- | ||
-- It indicates that the subtree of this node is used according to this | ||
-- specification. | ||
-- | ||
-- Hardened derivation is used at this level. | ||
purposeCIP1855 :: Index 'Hardened 'PurposeK | ||
purposeCIP1855 = toEnum 0x8000073F | ||
|
||
-- | Derive the policy private key that should be used to create mint/burn | ||
-- scripts. | ||
derivePolicyPrivateKey | ||
:: Passphrase purpose | ||
-- ^ Passphrase for wallet | ||
-> XPrv | ||
-- ^ Root private key to derive policy private key from | ||
-> Index 'Hardened 'PolicyK | ||
-- ^ Index of policy script | ||
-> XPrv | ||
-- ^ Policy private key | ||
derivePolicyPrivateKey (Passphrase pwd) rootXPrv (Index policyIx) = | ||
let | ||
purposeXPrv = -- lvl1 derivation; hardened derivation of purpose' | ||
deriveXPrv DerivationScheme2 pwd rootXPrv (getIndex purposeCIP1855) | ||
coinTypeXPrv = -- lvl2 derivation; hardened derivation of coin_type' | ||
deriveXPrv DerivationScheme2 pwd purposeXPrv (getIndex coinTypeAda) | ||
-- lvl3 derivation; hardened derivation of policy' index | ||
in deriveXPrv DerivationScheme2 pwd coinTypeXPrv policyIx | ||
|
||
-- | Derive the policy private key that should be used to create mint/burn | ||
-- scripts, as well as the key hash of the policy public key. | ||
derivePolicyKeyAndHash | ||
:: WalletKey key | ||
=> Passphrase "encryption" | ||
-- ^ Passphrase for wallet | ||
-> key 'RootK XPrv | ||
-- ^ Root private key to derive policy private key from | ||
-> Index 'Hardened 'PolicyK | ||
-- ^ Index of policy script | ||
-> (key 'PolicyK XPrv, KeyHash) | ||
-- ^ Policy private key | ||
derivePolicyKeyAndHash pwd rootPrv policyIx = (policyK, vkeyHash) | ||
where | ||
policyK = liftRawKey policyPrv | ||
policyPrv = derivePolicyPrivateKey pwd (getRawKey rootPrv) policyIx | ||
vkeyHash = hashVerificationKey CA.Payment (publicKey policyK) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Purpose field here doesn't look right ... right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah that's all fine, but |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better update all the comments about
Depth
, starting with the one just above.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmmm... not ideal. Kinda brutalizing the abstraction here, but 'ScriptK did it first and it's the path of least resistance...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated doco.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah if it weren't for ScriptK I would have asked you to try and find a better way of representing depth.