Skip to content

Instantly share code, notes, and snippets.

@ethankosakovsky
Last active June 11, 2020 12:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ethankosakovsky/268c52f018b94bea29a6e809381c05d6 to your computer and use it in GitHub Desktop.
Save ethankosakovsky/268c52f018b94bea29a6e809381c05d6 to your computer and use it in GitHub Desktop.
@realspencerdupre
Copy link

What is the motivation for using 83696968 ?

@ethankosakovsky
Copy link
Author

@realspencerdupre it is the word SEED in ASCII decimal.

@doc-hex
Copy link

doc-hex commented Apr 16, 2020

Still loving this proposal.

Some additions:

  • there are some wallet systems that used 18 words for BIP39 seed phrase (easy to add that above)
  • there should be an application number allocated for systems that want to import an XPRV directly (and example, text, etc)
  • Electrum has its own seed scheme which I've never gotten my head around, but perhaps application number should be reserved for that use case.

Might be nice to discuss the index value a little more. IMHO, it's practical to limit it's range to 0..999 or something smaller, because it may become a search-space later when you are trying to recover a forgotten value. (To me, this should be in an informational section of the standard, not a requirement.) Also, might be good to warn users that choosing a complex index number does not add much security, and not to treat it as a passcode/secret.

@doc-hex
Copy link

doc-hex commented Apr 16, 2020

A bug in your vectors:

  • text says to use .../39'/... (hardened) but the examples show and use unhardened .../39/... path.
  • here is a corrected example (39'), using my proposed 18-word case:
Path Used:
  m/83696968'/39'/0'/18'/0'

Entropy:
  e487c442dd4da401d5957c19339b0db554dd6d83d18ab140

Words:
  tonight dilemma awful ritual surge abstract film question bomb
  orphan sell height evidence replace aunt course rally again

XPRV addition:

  • I am using .../32'/{index}' for XPRV application. Taking 64 bytes of the HMAC digest, the first 32 bytes are the chain code, and second 32 bytes are the private key for BIP32 XPRV value. Child number, depth, and parent fingerprint are forced to zero. Here's the index=0 result, using your example xprv:
Derived XPRV:
xprv9s21ZrQH143K2BEMZX8aj7fLpKA2VVzTtiS8sjtGRZFAW3EAgSoLxgGGknHJXeToGtMTvqDXC3MRm3MEKn77DPnvm22Grwj6vynt8GDxcJh

Path Used:
  m/83696968'/32'/0'

Entropy:
  0be763286e9e50a9977e85ce3923c537a1788ff7b0392b2e1dd24ac801ccef6d1f03b99a7552272fe6d67fb4f56d4f029adee8882ccc30259f362c55fe13d9ca

Additional "application number" idea: "HEX"

  • another number could be defined for general purpose entropy. A subpath component would be the number of bytes used. Rendering in hex only. It's a lot like the HDSEED case, except it doesn't assume 32 bytes length, and doesn't render in base58.
  • so, might be m/83696968'/128169'/{length}'/{index}'
  • length must be 16 <= length <= 64
  • this is general purpose enough that if someone wanted to use it with an inferior cryptocurrency, it should be easy
  • app_no = 128169 = 0x1F4A9 = a specific unicode

I will be pushing a PR to the https://github.com/Coldcard/firmware repo shortly. It will do all of the above, except the HEX case.

@ethankosakovsky
Copy link
Author

Thanks, fixed the mistaken path. For the 18 word path I get a different entropy 938033ed8b12698449d4bbca3c853c66b293ea1b1ce9d9dc

I've opened a PR at bitcoin/bips#910

@ethankosakovsky
Copy link
Author

@peter-conalgo I have experimented with splitting the apps into a separate BIP here https://github.com/ethankosakovsky/bips/blob/entropy_apps/bip-entropy-applications.mediawiki

@ethankosakovsky
Copy link
Author

What would the motivation be for deriving a new XPRV this was as opposed to just deriving it from a standard BIP32 path?

@doc-hex
Copy link

doc-hex commented Apr 17, 2020

Yeah, running it thru HMAC512 isn't adding much, but does create another barrier. I suppose for the XPRV case, we could just clear the child num / depth / master fingerprint and such. Your call, but I think it's appropriate for the purposes of the BIP to be able to output XPRV for those tools that need it as a master key.

@doc-hex
Copy link

doc-hex commented Apr 17, 2020

I plan to download and use your test code tomorrow. Should be able to fix the 18-word case then.

@doc-hex
Copy link

doc-hex commented Apr 17, 2020

Thanks, fixed the mistaken path. For the 18 word path I get a different entropy 938033ed8b12698449d4bbca3c853c66b293ea1b1ce9d9dc

Two issues at play here:

  • you changed the message used for HMAC from bip-entropy-from-bip32 to bip-entropy-from-k at some point (reasonable)
  • in your function __hmac_sha512 the arguments for key vs. message are swapped; that must have been correct in an earlier (unseen) version of your code that you used to make the vectors originally

My hacked version of bipentropy/bipentropy.py matches Coldcard now, but of course all test vectors need to change, both in test_entropy.py and the BIP text. I'll leave that for you!

@ethankosakovsky
Copy link
Author

ethankosakovsky commented Apr 18, 2020

__hmac_sha512() the "key" is our constant bip-entropy-from-k. I am unclear about what you mean for the last part of your message, as the message is our input and is the correct order for the function hmac.new(key, message, digestmod).

Python reference: https://docs.python.org/3/library/hmac.html#hmac.new

Other usage in the wild for example and in Bitcoin Core

@ethankosakovsky
Copy link
Author

@peter-conalgo

Yeah, running it thru HMAC512 isn't adding much, but does create another barrier. I suppose for the XPRV case, we could just clear the child num / depth / master fingerprint and such. Your call, but I think it's appropriate for the purposes of the BIP to be able to output XPRV for those tools that need it as a master key.

I think you are right, in the context of this BIP it should use the HMAC. While it makes no difference, in the context of this BIP's applications, it seems like an odd-ball to not use the entropy right?

@doc-hex
Copy link

doc-hex commented Apr 19, 2020

  1. I'll switch msg vs. key to HMAC512 to match your usage. I think the text of the BIP could be improved to make this clear to other implementors. Probably just a few more words here, or maybe whatever they say in other BIPs when they do the same thing.

The resulting private key (k) is then processed with HMAC-SHA512(k, "bip-entropy-from-bip32") to produce 512 bits of entropy.

  1. At this point, I'm against using HMAC512 step for XPRV to XPRV case. One reason: the parent wallet can make a PSBT operating on the derived XPRV's funds. That's a positive, IMHO. There are probably other cases where keeping the normal bip32 derivation working is helpful.

@ethankosakovsky
Copy link
Author

  1. Welp, I have updated the wording. My bad.

  2. Oh, I had quite warmed to the idea and pushed some code 🤦 but no worries: what would the PSBT usecase be specifically in this case and why would it be considered part of the entropy applications? I think others may have similar questions and we should probably make a note of the rationale. In another thought, there is nothing precluding the use of standard BIP32 derivation regardless of this proposal.

What I found interesting on second thought since I mentioned it was that this is different than BIP32 derivation mainly because we're also resetting the extended key child number etc., so I regard it as a different application entirely than BIP32 child derivation.

@doc-hex
Copy link

doc-hex commented Apr 20, 2020

  • Coldcard and your library are now in sync again. Coldcard supports WIF case properly now.
  • Only remaining question is XPRV design issue. I'm for leveraging BIP32 unchanged.
  • Minor concern: this BIP creates Bitcoin keys from random entropy. There is a very small chance that you'll make an invalid key that is zero or bigger than the order of the curve. I suggest a comment that this be reported to the user, with recommendation to move to next index value and to buy a lottery ticket immediately. BIP32 says:
  • In case parse256(IL) ≥ n or ki = 0, the resulting key is invalid, and one should proceed with the next value for i. (Note: this has probability lower than 1 in 2127.)

@ethankosakovsky
Copy link
Author

One reason: the parent wallet can make a PSBT operating on the derived XPRV's funds.

Can you explain this use-case a bit more detail?

@doc-hex
Copy link

doc-hex commented Apr 24, 2020

Use case: I generate XPRV for a new mobile wallet, derived from my master secret held in a Coldcard. I play around a bit, and then the wallet vendor goes evil, and/or Apple removes it from my device without my consent. To recover my funds, I can construct a PSBT file, containing full paths (ie. m/83696968'/32'/0'/whatever/...) and use my Coldcard to sign that. No help needed from extinct wallet, although I might have to search a little for derived key paths.

If the HMAC512 step was included, I'd have to import the XPRV into a Coldcard or other signing device, and then search for UTXO from that, and make PSBT based on that as a the master key.

@adam3us
Copy link

adam3us commented Apr 26, 2020

* Coldcard and your library are now in sync again. Coldcard supports WIF case properly now.

* Only remaining question is XPRV design issue. I'm for leveraging BIP32 unchanged.

* Minor concern: this BIP creates Bitcoin keys from random entropy. There is a very small chance that you'll make an invalid key that is zero or bigger than the order of the curve. I suggest a comment that this be reported to the user, with recommendation to move to next index value and to buy a lottery ticket immediately. BIP32 says:
  • In case parse256(IL) ≥ n or ki = 0, the resulting key is invalid, and one should proceed with the next value for i. (Note: this has probability lower than 1 in 2127.)

right from https://en.bitcoin.it/wiki/Secp256k1, n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 so the probability of exceeding n-1 is very low and as you say < 2^-127. close to 0 probability, but you could test for it then hash again.

@adam3us
Copy link

adam3us commented Apr 26, 2020

Use case: I generate XPRV for a new mobile wallet, derived from my master secret held in a Coldcard. I play around a bit, and then the wallet vendor goes evil, and/or Apple removes it from my device without my consent. To recover my funds, I can construct a PSBT file, containing full paths (ie. m/83696968'/32'/0'/whatever/...) and use my Coldcard to sign that. No help needed from extinct wallet, although I might have to search a little for derived key paths.

If the HMAC512 step was included, I'd have to import the XPRV into a Coldcard or other signing device, and then search for UTXO from that, and make PSBT based on that as a the master key.

few comments:

  • I don't think any current wallets support importing XPRV?

  • If I understand you propose to special case new export/import type XPRV to not use HMAC unlike other seed types

  • that trick would only work for this new XPRV type if other types are going through HMAC, if you wanted to handle on single coldcard both seed derivation and wallet derived from those seeds, maybe be better to work generically across key types?

  • eg you could type the seed into the same coldcard, and the wallet path and proceed as usual

  • or add user interface to select seed from the same cold card seed manager

however I think it may be undesirable for security reasons: you don't want to run other code on the seed manager because it's very high value, eg if there was a bug in the wallet code. For this reason ideally I think the seed manager device should be a single function coldcard, other HWW re-purposed, or an always offline computer with no network card, say locked in a physical safe.

Even worse would be people extracting full paths and putting the master seed manager seed into a standard wallet, so the HMAC there is almost a feature in making that unsupported/incompatible with BIP32 derivation paths below the derived seed.

@doc-hex
Copy link

doc-hex commented Apr 26, 2020

Even worse would be people extracting full paths and putting the master seed manager seed into a standard wallet, so the HMAC there is almost a feature in making that unsupported/incompatible with BIP32 derivation paths below the derived seed.

Very true. No-one needs this standard to in order to export a BIP32 XPRV into another wallet that's looking for it. We'd just be suggesting a subpath to use, which isn't very interesting. Applying HMAC512 as a "firewall" or operational "barrier" is consistent with the rest of this standard and how it works.

So I'll change Coldcard (back) to making XPRV from the HMAC entropy, unless someone gives a reason otherwise.

@adam3us
Copy link

adam3us commented Apr 26, 2020

Even worse would be people extracting full paths and putting the master seed manager seed into a standard wallet, so the HMAC there is almost a feature in making that unsupported/incompatible with BIP32 derivation paths below the derived seed.

Very true. No-one needs this standard to in order to export a BIP32 XPRV into another wallet that's looking for it. We'd just be suggesting a subpath to use, which isn't very interesting. Applying HMAC512 as a "firewall" or operational "barrier" is consistent with the rest of this standard and how it works.

So I'll change Coldcard (back) to making XPRV from the HMAC entropy, unless someone gives a reason otherwise.

out of interest which application do you have in mind for the XPRV? is there a coldcard mode for importing them?

@doc-hex
Copy link

doc-hex commented Apr 26, 2020

Yes, Coldcard supports XPRV as a master secret (held in secure element). That's why it came up when I implemented this.

@ethankosakovsky
Copy link
Author

I have added the reference to Coldcard implementation Coldcard/firmware#39, to the BIP pull request. Everything looks good from my side. Just awaiting the BIP number assignment.

@ethankosakovsky
Copy link
Author

This proposal has become BIP85

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment