View on GitHub tezio logo

Crypto Notes

Keys Used During Master Secret Derivation

One of the steps in HD wallet creation is master-seed to master-key deviation. This involves using HMAC-SHA512 where the data is the master seed and the key is a character string based on the elliptic curve to be utilized later in the process. For the Ed25519 curve the key is “ed25519 seed”. Similarly, the key for the NIST P-256 curve (Secp256r1) is “Nist256p1 seed” as documented in SLIP10 specifications here. The key for the Secp256k1 (Bitcoin’s Koblitz curve) is “Bitcoin seed”. This last key is defined in BIP32. I believe I’ve verified these keys are correct by comparing the public key hashes the Tezio HSM generates to those generated by a Ledger device using the same mnemonic.

Domains of Elliptic Curves

Since secret keys for the three elliptic curves used in Tezos are 32 bytes in length, one might assume that the domains of these secret keys is 0 to 2256 - 1. However, these curves actually have more limited domains. The probability of drawing a random integer vetween 0 and 2256 - 1 (or 32 bytes) that is not on the curve’s domain, and thus not a valid key, is very small, but not zero. For Secp256k1 the domain is integers between 1 and n-1 where n = 2256 − 0x14551231950b75fc4402da1732fc9bebf For NIST P-256 (Secp256r1) the domain is between 1 and n-1 where n = 2256 − 2224 + 2192 − 0x4319055258e8617b0c46353d039cdaaf Source

Interestingly, the SLIP10 reference and others say that any number between 0 and 2^256 - 1 is a valid private key for Ed25519 but this makes no sense because the curve itself is a field defined by prime 2^255 - 19 and there is some discussion of “clamping” some bits to make the key valid. Source. My current best guess on this issue is that the implementation of Ed25519 takes care of these invalid keys on the fly and any number between 0 and 2^256-1 works.

About Public Keys

For the Ed25519 curve, public keys are 32 bytes. For Secp255k1 and NIST P-256, public keys are 64 bytes, 32 for an x coordinate and 32 for a y coordinate. However, the y coordinate can be found from the x coordinate since y is squared there is both a positive and a negative y coordinate for each x (above or below the x axis). So, while the value of the y coordinate doesn’t need to be preserved, one does need to keep track of if it is whether even or odd (I don’t understand what even/odd has to do with pos/neg). In compressed form the public key for these curves is the x coordinate with a prefix of 0x02 if the y coordinate is even and 0x03 if it is odd.