-
-
Notifications
You must be signed in to change notification settings - Fork 17
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 Cardano key derivation according to CIP3-Icarus #158
Support Cardano key derivation according to CIP3-Icarus #158
Conversation
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.
Please review by commits, thank you 🙏
export const isValidPrivateKey = (_privateKey: Uint8Array | string | bigint) => | ||
true; | ||
|
||
export const deriveUnhardenedKeys = true; |
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.
Note that that the important difference of the bip32
version ed25519
is that it allows unhardened key derivation
src/curves/curve.ts
Outdated
@@ -24,7 +25,16 @@ export type Curve = { | |||
publicAdd: (publicKey: Uint8Array, tweak: Uint8Array) => Uint8Array; | |||
compressPublicKey: (publicKey: Uint8Array) => Uint8Array; | |||
decompressPublicKey: (publicKey: Uint8Array) => Uint8Array; | |||
}; | |||
} & ( |
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.
The motivation for this change, was to have place which decides whether the master node should be derived from seed (already implemented) or the new cip3Icarus
way, from entropy, as defined in entropyToCip3IcarusMasterNode
.
Tying masterNodeGenerationSpec
to curve
, seemed as the way which would require minimal changes to existing logic.
* @returns The `Uint8Array` corresponding to the `bigint` value. | ||
*/ | ||
export function numberToUint32(value: number) { | ||
export function numberToUint32(value: number, littleEndian = false) { |
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.
Needed later, to encode keyindex, for Cardano, the values are littleEndian
test/vectors/derivation.json
Outdated
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.
Please note that there are no deletions in this file, just additions. Only new cip3Icarus
were generated.
At first glance this looks great. I will be doing a proper review next week, thanks for your patience! |
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.
I didn't get through everything yet, but here's some initial comments for you. I'm not familiar with CIP-3, so I will take some time to read more about it to properly review the algorithms added here.
Some nits related to the code style we use. Sorry for that!
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.
@Mrtenz I was initially waiting for your full review, but then thought that you might be waiting for the cip3Icarus
=> cip3
refactor, so I did it. Your review came literally one second after I pushed :D. Sorry for that, please check these 3 commits too.
test/vectors/derivation.json
Outdated
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.
Did this in separate commit so I can squash it easier
curve, | ||
); | ||
switch (curve.masterNodeGenerationSpec) { | ||
case 'slip10': |
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.
You haven't asked for this, but, I noticed it now, the switch is IMO safer
@Mrtenz have you had time to look into |
Not yet, sorry about that. Will make time to look into this more this week! |
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.
I reviewed the cryptography to the best of my ability and it looks good. Just a few more minor nits, and some code is missing coverage. Once that's fixed I will approve!
Can you rebase your branch? |
To simplify the interface
So we can validate against it when creating fingerprint
Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
4da9f3a
to
e6b759a
Compare
@Mrtenz the last couple of issues should be resolved. Should I squash the commits or do you want to do it yourself? |
|
Should be fixed Should I squash the commits into some reasonable chunks, would that be relevant for audit too? do you want to do it yourself? Let me know :) |
No need to. We want to do an audit for some other smaller changes since the last audit anyway, so I will just squash when merging this PR. |
What is the current state of things and why does it need to change?
secp256k1
anded25519
getBip32Entropy
) are different from keys that would standard Cardano wallet give, for the same mnemonicmetamask-snaps
andmetamask-extension
repos, which are ready, awaiting feedback on this)What is the solution your changes offer and how does it work?
For this reasons
we add a new derivation
curve
, calleded25519Bip32
, this curve implements a slight modification of how standarded25519
is used in SLIP10.we add a new
deriver
, calledcip3Icarus
which derives keys according toCIP3
(which is the standard for Cardano)from the interface point of view, these changes allow us to call
which returns keys consistent with Cardano derivation standard
A longer explanation, also present in the code
CIP-3 defines standards for deriving keys on Cardano.
Key attributes
Root/Master key is derived from entropy, not seed. For this implementation we work with Icarus standard as it is the most widely used. See https://github.com/cardano-foundation/CIPs/blob/09d7d8ee1bd64f7e6b20b5a6cae088039dce00cb/CIP-0003/Icarus.md.
HD node consists of a 64 byte private key, 32 byte public key and 32 byte chain code. See https://github.com/cardano-foundation/CIPs/blob/09d7d8ee1bd64f7e6b20b5a6cae088039dce00cb/CIP-0003/CIP-0003.md#master-key-generation.
For derivation of BIP32 HD nodes, it uses modified implementation of ed25519 called BIP32-Ed25519. See https://input-output-hk.github.io/adrestia/static/Ed25519_BIP.pdf.
Are there any issues or other links reviewers should consult to understand this pull request better? For instance:
All sources are referenced in the code, and explained quite extensively, namely
Reference implementations