satoshilabs / slips

SatoshiLabs Improvement Proposals
Creative Commons Attribution Share Alike 4.0 International
1.51k stars 1.72k forks source link

SLIP-0023 : Modification Proposal #827

Closed ilap closed 3 years ago

ilap commented 4 years ago

The BIP-Ed25519 specification allows only ED25519 EdDSA compatible master secret by discarding those generated extended root private keys which do not have the 3rd highest bit of the last byte is cleared.

In other hand, SLIP-0023 allows any master secrets by explicity clearing the bit mentioned above. This modification causes that SLIP-0023 is not fully backward compatible with the BIP32-Ed25519 specification and therefore about 50% of the master secrets are not ED25519 compatible private keys.

The modification proposed by this document allows the master secret to become fully Ed25519 compatible privatkey meanings by that the public key derived from an exported master secret would be the same as the public key generated from any other tools that use ED25519 specification.

The rationale of this modification is to allow determistically derive an ED25519 keypair from a seed, which can be used in some other tools; that use ED25519; by importing the exported master secret or I.

  1. Let S be a seed byte sequence such as the master secret from SLIP-0039.
  2. Calculate I := HMAC-SHA512(Key = "ed25519 cardano seed", Data = S).
  3. Split I into two 32-byte sequences, IL := I[0:32] and IR := I[32:64].
  4. Let ~k (master secret) := IL
  5. Let k (root extended privatekey) = SHA-512(~k).
  6. If k[31] & 0x20 != 0, then
    • S := k
    • goto 2.
  7. Modify k by assigning k[0] := k[0] & 0xf8 and k[31] := (k[31] & 0x3f) | 0x40.
  8. Interpret k[0:32] as a 256-bit integer kL in little-endian byte order. Let kR := k[32:64] and use (kL, kR) as the root extended private key and c := IR as the root chain code.

Or changing the key instead of the seed, as it was implemented in Daedalus' key generation.

  1. Let S be a seed byte sequence such as the master secret from SLIP-0039.
  2. Let i := 0
  3. Calculate I := HMAC-SHA512(Key = "ed25519 cardano seed $i", Data = S).
  4. Split I into two 32-byte sequences, IL := I[0:32] and IR := I[32:64].
  5. Let ~k (master secret) := IL
  6. Let k (root extended privatekey) = SHA-512(~k).
  7. If k[31] & 0x20 != 0, then
    • i := i + 1
    • goto 3.
  8. Modify k by assigning k[0] := k[0] & 0xf8 and k[31] := (k[31] & 0x3f) | 0x40.
  9. Interpret k[0:32] as a 256-bit integer kL in little-endian byte order. Let kR := k[32:64] and use (kL, kR) as the root extended private key and c := IR as the root chain code.
prusnak commented 4 years ago

I am not sure if it makes sense to try to unify the methods as approach to the passphrase is very different in both.

andrewkozlik commented 4 years ago

My apologies for not replying earlier. I hadn't noticed this issue before and stumbled upon it just now.

In other hand, SLIP-0023 allows any master secrets by explicity clearing the bit mentioned above. This modification causes that SLIP-0023 is not fully backward compatible with the BIP32-Ed25519 specification and therefore about 50% of the master secrets are not ED25519 compatible private keys.

It seems rather odd to me to talk about "backward compatibility" with the BIP32-Ed25519 specification. First of all, AFAIK the master node derivation specified in BIP32-Ed25519 was never actually implemented in any wallet, only the child node derivation specified in BIP32-Ed25519 is used in practice. Secondly the chain code is derived completely differently in both schemes, so the proposed change wouldn't make it backward compatible anyway.

It is true that about 50% of the master secrets are not RFC 8032 compatible private keys. However, consider that 100% of non-root nodes don't have a RFC 8032 compatible private key, because BIP32-Ed25519 child node derivation works with the so called "extended private key" for which there is generally no SHA-512 pre-image.

The modification proposed by this document allows the master secret to become fully Ed25519 compatible privatkey meanings by that the public key derived from an exported master secret would be the same as the public key generated from any other tools that use ED25519 specification.

True, but again that only applies to the public key of the root node.

I don't like the idea of making the derivation process more complicated for the sake of achieving some level of RFC 8032 compatibility for only one node, while all other nodes still remain incompatible. Especially given that the root node is generally not used for signing anyway. BTW, SLIP-0023 clears the 3rd highest bit of the last byte just like the Icarus scheme does. To my knowledge the Icarus scheme is currently the most widespread and is more recent than the Daedalus scheme.

skaht commented 4 years ago

FYSA - there appears to be three major flavors of 25519 cryptography:

  1. RFC 8032 - utilized by SLIP 10
  2. RED25519 - used by Monero and I2P
  3. Ristretto - under IETF Standardization

Mimics RFC 8032 behaviors: % echo 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60 | ./25519 d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a

Associated RED25519 private key: % echo 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60 | bx sha512 | cut -c 1-64 | ./clamp | ./sc_reduce32 7c2cac12e69be96ae9065065462385e8fcff2768d980c0a3a520f006904de90f

Associated RED25519 public key: % echo 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60 | bx sha512 | cut -c 1-64 | ./clamp | ./sc_reduce32 | ./secret_key_to_public_key d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a

Note that both RFC 8032 and RED25519 share the same public ed25519 public key and the ed25519 seed can ALWAYS be transformed to a RED25519 private key.

Also worth noting the following:

// Big Endian Clamping // https://quirks.ed25519.info/basics/ // % echo 7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8 | ./endian32 // f8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f
// https://moderncrypto.org/mail-archive/curves/2017/000861.html; 64 = 0x40

output[0] &= (unsigned char)0xf8; output[31] &= (unsigned char)0x7f; output[31] |= (unsigned char)0x40;

sterlingwellscaffeine commented 3 years ago

Could you explain why in the Cardano Icarus Master Node Derivation, the string mnemonic is not appended to the passphrase as specified in the BIP-39 Proposal?

I ask since according to the Compliance section of the proposal, this derivation strategy should be used when the source of the master secret is BIP-39. However, according to my understanding, the string mnemonic needs to be appended to the passphrase in order to have compliance with BIP-39.

Thank you so much in advance for your response!

andrewkozlik commented 3 years ago

Could you explain why in the Cardano Icarus Master Node Derivation, the string mnemonic is not appended to the passphrase as specified in the BIP-39 Proposal?

I cannot explain why the Cardano community chose to use BIP-39 mnemonics differently to the way it is specified in the BIP-39 specification. We didn't make this up at SatoshiLabs, in fact it is an unpleasant problem for us, see https://github.com/trezor/trezor-firmware/issues/1783. The section of SLIP-0023 that you are referring to merely documents the existing state of things in the Cardano ecosystem. For a long time Cardano had not documentation on this topic, so we felt a need to create some. Recently they documented this in https://github.com/cardano-foundation/CIPs/blob/master/CIP-0003/CIP-0003.md, so you should ask your question there.

sterlingwellscaffeine commented 3 years ago

Could you explain why in the Cardano Icarus Master Node Derivation, the string mnemonic is not appended to the passphrase as specified in the BIP-39 Proposal?

I cannot explain why the Cardano community chose to use BIP-39 mnemonics differently to the way it is specified in the BIP-39 specification. We didn't make this up at SatoshiLabs, in fact it is an unpleasant problem for us, see trezor/trezor-firmware#1783. The section of SLIP-0023 that you are referring to merely documents the existing state of things in the Cardano ecosystem. For a long time Cardano had not documentation on this topic, so we felt a need to create some. Recently they documented this in https://github.com/cardano-foundation/CIPs/blob/master/CIP-0003/CIP-0003.md, so you should ask your question there.

Dear Andrew,

Thank you for your thoughtful response. I will follow up with them in the future about the idiosyncrasy mentioned above.

Sterling