-
Notifications
You must be signed in to change notification settings - Fork 5.6k
BIP 32: Add simpler explanations where I got confused originally reading this. #785
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
base: master
Are you sure you want to change the base?
Changes from all commits
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 |
---|---|---|
|
@@ -51,10 +51,11 @@ Addition (+) of two coordinate pair is defined as application of the EC group op | |
Concatenation (||) is the operation of appending one byte sequence onto another. | ||
|
||
As standard conversion functions, we assume: | ||
* point(p): returns the coordinate pair resulting from EC point multiplication (repeated application of the EC group operation) of the secp256k1 base point with the integer p. | ||
* point(p): returns the coordinate pair resulting from EC point multiplication (repeated application of the EC group operation) of the secp256k1 base point with the integer p (similar to making public key). | ||
* ser<sub>32</sub>(i): serialize a 32-bit unsigned integer i as a 4-byte sequence, most significant byte first. | ||
* ser<sub>256</sub>(p): serializes the integer p as a 32-byte sequence, most significant byte first. | ||
* ser<sub>P</sub>(P): serializes the coordinate pair P = (x,y) as a byte sequence using SEC1's compressed form: (0x02 or 0x03) || ser<sub>256</sub>(x), where the header byte depends on the parity of the omitted y coordinate. | ||
* ser<sub>P</sub>(P): serializes the coordinate pair P = (x,y) (aka. the public key) as a byte sequence using [https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1.h#L177 SEC1]'s compressed form: (0x02 or 0x03) || ser<sub>256</sub>(x), where the header byte depends on the parity of the omitted y coordinate. | ||
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. Don't use a link to the master branch here, as it'll grow outdated over time. |
||
** [https://github.com/bitcoin-core/secp256k1 Libsecp256k1]'s pubkey_serialize and pubkey_parse functions implement this format. | ||
* parse<sub>256</sub>(p): interprets a 32-byte sequence as a 256-bit number, most significant byte first. | ||
|
||
|
||
|
@@ -64,6 +65,8 @@ In what follows, we will define a function that derives a number of child keys f | |
|
||
We represent an extended private key as (k, c), with k the normal private key, and c the chain code. An extended public key is represented as (K, c), with K = point(k) and c the chain code. | ||
|
||
When deriving child keys, a 'hardened' child key can only be generated using a private key. This provides security advantages and prevents adversarial public key tracing. It is typically used to separate 'accounts' from one another. | ||
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. I don't think the sentence with the word "typically" belongs here. BIP32 is a proposed specification, written in 2012. It's not a description of how things are in 2025. Any language here should relate to what it proposed in 2012. |
||
|
||
Each extended key has 2<sup>31</sup> normal child keys, and 2<sup>31</sup> hardened child keys. Each of these child keys has an index. The normal child keys use indices 0 through 2<sup>31</sup>-1. The hardened child keys use indices 2<sup>31</sup> through 2<sup>32</sup>-1. To ease notation for hardened key indices, a number i<sub>H</sub> represents i+2<sup>31</sup>. | ||
|
||
===Child key derivation (CKD) functions=== | ||
|
@@ -105,6 +108,8 @@ To compute the public child key of a parent private key: | |
* CKDpub(N(k<sub>par</sub>, c<sub>par</sub>), i) (works only for non-hardened child keys). | ||
The fact that they are equivalent is what makes non-hardened keys useful (one can derive child public keys of a given parent key without knowing any private key), and also what distinguishes them from hardened keys. The reason for not always using non-hardened keys (which are more useful) is security; see further for more information. | ||
|
||
The non-hardened result is typically used by a server to continually generate receive addresses without the ability to spend funds. | ||
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. Again, this is describing a 2025 state of affairs, not a 2012 proposal. I could see a separate section about "later adoption" being added perhaps, if that's considered useful, describing which parts of the proposal ended up being mainstream, and which ones weren't, but it should make it clear that that's separate from the historical proposal. |
||
|
||
====Public parent key → private child key==== | ||
|
||
This is not possible. | ||
|
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.
There seems to be a word missing here:
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.
Agree with adding "a" here (https://github.com/bitcoin/bips/pull/785/files#r1679635273).