3

I'm reading master bitcoin book and I came to the part related to HD wallets and how to create a Child private key (link). It says the following:

The parent public key, chain code, and the index number are combined and hashed with the HMAC-SHA512 algorithm to produce a 512-bit hash. This 512-bit hash is split into two 256-bit halves. The right-half 256 bits of the hash output become the chain code for the child. The left-half 256 bits of the hash are added to the parent key to produce the child private key. In Extending a parent private key to create a child private key, we see this illustrated with the index set to 0 to produce the "zero" (first by index) child of the parent.

The bolded sentence causes me misunderstanding. What type of addition is this? If the classical addition of the left 256 bits of the hash result to the private key of the parent is implemented, then it will lead to a 512-bit private key of the child, which is not correct (the private key should be 256-bit). Is this perhaps referring to addition in the context of the "logical and" between the left hash result and the parent's private key? What type of addition is meant here when the result should be 256-bit? Some answer is given here, but I'm still not clear. The answer is related to the use of modules.

What further confuses me is that the book says that if the child's private key is known, the parent's private key can be determined? That would make perfect sense to me if it was about adding the left half of the hash to the parent's private key. You simply remove the part related to the hash from the 512-bit result and get parent's private key. However, how can it be done here?

1

2 Answers 2

1

If the classical addition of the left 256 bits of the hash result to the private key of the parent is implemented, then it will lead to a 512-bit private key of the child, which is not correct (the private key should be 256-bit).

As Michael Folkson explains in that answer you linked:

There is concatenation where 256 bits placed next to another 256 bits makes 512 bits. However, what you are referring to is scalar addition. A 256 bit number (256 bit parent private key) is added to another 256 bit number (left 256 bits of the SHA512) and the result modulo p (p = 2^256-2^32-977) is another 256 bit number.

It in some sense will behave like classical addition (before the modulo operation).

Although I am not 100% sure where p is specifically defined, the modulo p operation where p = 2^256-2^32-977 is the relevant operation that will shorten the resulting key to 256 bit. (because p is a 256 bit number)

So you add the left 256 bits to the parent private key to get the ( large 512 bit ) child private key, then you modulo p to shorten the result to 256 bit.

Okay, let's say you and Michael are right. How will the parent's private key be obtained knowing the child's private key? If the module's operations are really used to obtain a 256-bit key, then inversion and obtaining the parent's private key cannot be performed at all... In the book, they say that it is "relatively easy" to obtain the parent's private key from knowing the child's private key.

This was discussed partially here Xpriv can be calculated from the xpub + child private key?

according to: https://medium.com/@blainemalone01/hd-wallets-why-hardened-derivation-matters-89efcdc71671#cc82

the equation for deriving the parent key from child is:

child private key = (left 32 bytes + parent private key) % n

Bob solves for parent private key:

parent private key = (child private key - left 32 bytes) % n

Note here we are using modulo n which is the Secp256k1 curve order, this is a common operation in ECC. It is possible Michael meant modulo n but I cannot confirm this.

The same formula you provided is also mentioned here. But here they use G instead of n. I know that G is a generic point (a point on an elliptic curve) used to generate a public key from a private key. So is n actually G?)

In this section you will notice p is being used and is explained to be a global constant in Bitcoin software but nothing more is said about it: https://developer.bitcoin.org/devguide/wallets.html#hierarchical-deterministic-key-creation

This section G is being used: https://developer.bitcoin.org/devguide/wallets.html#id5

I know for certain G is used to derive public from private keys through scalar multiplication.

I do not want to state any incorrect facts about the utilization of these values, my opinion is that in this circumstance it makes more sense that the modulo operation is done via n because of this article that seems to detail it extremely well but since I don't know for certain I can only attempt to provide researched context.

5
  • Okay, let's say you and Michael are right. How will the parent's private key be obtained knowing the child's private key? If the module's operations are really used to obtain a 256-bit key, then inversion and obtaining the parent's private key cannot be performed at all... In the book, they say that it is "relatively easy" to obtain the parent's private key from knowing the child's private key.
    – dassd
    Apr 2, 2023 at 22:07
  • moving response to this to answer
    – Poseidon
    Apr 2, 2023 at 22:23
  • The same formula you provided is also mentioned here. But here they use G instead of n. I know that G is a generic point (a point on an elliptic curve) used to generate a public key from a private key. So is n actually G?). But here they use G instead of n. I know that G is a generic point (a point on an elliptic curve) used to generate a public key from a private key. So is n actually G?
    – dassd
    Apr 2, 2023 at 23:01
  • They also talks here about it.
    – dassd
    Apr 2, 2023 at 23:45
  • responding in answer
    – Poseidon
    Apr 3, 2023 at 3:55
1

What follows contains inaccurate notation and language on purpose, in order to make the conceptual explanation lighter and more straightforward.


A BIP32 extended private ("xprv") or public ("xpub") key is composed of two parts: the key itself and the chaincode. The key is either the private key k (for an xprv) or the public key K (for an xpub). The chaincode is a 256 bits integer, identical for both the private and public versions.

BIP32 defines the CKDpriv((kpar, cpar), i) → (ki, ci) function that derives a child extended private key from a parent extended private key at a given index i. (kpar, cpar) are the private key and the chaincode of the parent, and (ki, ci) the private key and the chaincode of the child at index i. Let's call Kpar the public key corresponding to kpar.

For unhardened derivation (i < 2^31), CKDpriv is defined as (loosely speaking):

  • let I = HMAC-SHA512(Key = cpar, Data = Kpar || i). (With all data serialized as bytes.)
  • ci is the rightmost 32 bytes of I.
  • ki is the leftmost 32 bytes of I (as an integer), added to kpar.

The insight in the above is that you can get I without knowing any secret: this makes sense, in some cases you may want an entity (such as an online server) to be able to derive public keys without having access to any secret. But this opens up the possibility to compute kpar from (Kpar, cpar) and ki, or in other words to compute the parent's xprv from the parent's xpub and any child private key (along with its index):

  1. From the parent's (Kpar, cpar) and the index i, compute I.
  2. Let IL be the leftmost 32 bytes of I.
  3. Compute kpar by substracting IL from ki.

Note by using hardened derivation, it's not possible to compute IL without the parent private key. This makes it impossible to use the above trick to get the parent private key from the child private key and parent extended key, at the cost of making it impossible to derive public keys without knowledge of the parent private key.

More on the security of BIP32 here.

6
  • First of all, thanks for the reply. Yes, I generally know the process of getting the child's private key from the parent's private key and the left half of the hash. However, there is constant talk about adding those two elements and getting the child's private key, but no one is talking about what type of addition it is. In the end, as I understand it, it's simple addition, like 2+2=4, 3+6=9, etc.
    – dassd
    Apr 4, 2023 at 12:28
  • Here it says that ki is parse256(IL) + kpar ( mod n) is used to obtain the child's private key. Since they don't point out anywhere that it's a special type of addition, I'd say it's just a "normal" addition. Also here(hierarchical deterministic Bitcoin wallet implementation) addPrivKes is used which just does the "normal" addition of the left half of the hash and the parent's private key.
    – dassd
    Apr 4, 2023 at 12:42
  • The whole problem arose because here Michael Folkson said that it is concatenation and not "normal" addition. I think he is wrong? See also my other question related to the same topic. Link
    – dassd
    Apr 4, 2023 at 12:46
  • I don't understand your comments. What is your question? The trick is to substract IL from ki. Apr 4, 2023 at 13:09
  • Yes, but the problem was that I didn't know if when getting the child's private key, the scalar addition of the parent's private key and the left half of the hash was done or if it was a "special" operation denoted with +. The problem was caused by the answer to this question, because I misinterpreted that concatenation was used. Since I thought it was concatenation, I didn't know what the opposite of that was, that is, what the - stands for.
    – dassd
    Apr 4, 2023 at 13:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.