yenom / BitcoinKit

Bitcoin protocol toolkit for Swift
MIT License
842 stars 262 forks source link

Private key derivation algorithm producing an unexpected result #204

Closed lorenzozanotto closed 5 years ago

lorenzozanotto commented 5 years ago

Current behavior

Starting from an HDKeychain object created with a given seed and using the .testnetBTC network, trying to derive the master private key at certain paths produces an unexpected private key starting with Ck1t instead of tprv.

Expected behavior

Every derivation of a master private key starting with tprv should produce an output that starts with tprv as well.

Steps to reproduce

  1. Initialize an HDKeychain object with a seed containing the hexadecimal Data representation of the following string

00000ef9000000000008010000000073d000000000f0d90000000000050d0000060400000b0a0dcf6800003a0000000000000f0300004f0b00bc000000000000

  1. Derive the HDKeychain using the following master path to obtain an HDPrivateKey object

m/44'/1'/0'

  1. Derive the obtained HDPrivateKey object first at path 54 and then at 59 as reported below
masterPrivateKey.derived(at: UInt32(54)).derived(at: UInt32(59)).extended()

// Prints: Ck1tTgDDivpyZQt4ZNiCiZuc5x2iYHvPi6D3YaMCrewwAzuwkSMsU6kPv46DnYeRjxRDkc2BiPG5ewWVSBjsU25fheAEz73hNXZxFDtvamuJPH
// Expected: tprv8k4wA4ake4QNhtpriUFBrqtaM7gfEMzAENCBLAVU78cgeiw7kcNY9Ae3S1L8RmrKykcrcYf2fhvJ5dDeq7RWGLbhSB5MUNJTgJewgvFDEgH

Note that deriving the masterPrivateKey at, let's say, path 53 and then 59 produces the expected output. Same for deriving the key first at path 54 and then 60. There are certain circumstances where, given a master key, the derivation at some paths fail. The example above gives a systematic scenario to reproduce the behaviour.

Environment

pebble8888 commented 5 years ago

Probably It's bug. It's fixed by my branch pebble8888:keyconvert. Please wait it merged.

$ echo "00000ef9000000000008010000000073d000000000f0d90000000000050d0000060400000b0a0dcf6800003a0000000000000f0300004f0b00bc000000000000" > seed
$ cat seed | bx hd-new -v 70615956 > m
$ cat m | bx hd-private --index 44 --hard | bx hd-private --index 1 --hard | bx hd-private --index 0 --hard | bx hd-private --index 54 | bx hd-private --index 59
tprv8k4wA4ake4QNhtpriUFBrqtaM7gfEMzAENCBLAVU78cgeiw7kcNY9Ae3S1L8RmrKykcrcYf2fhvJ5dDeq7RWGLbhSB5MUNJTgJewgvFDEgH
lorenzozanotto commented 5 years ago

@usatie I'd like to ping in order to get the @pebble8888 keyconvert branch to be merged into master. That could make this great library working properly when it comes to private key derivation.

usatie commented 5 years ago

@lorenzozanotto @pebble8888 Thank you for your contribution! This bug is fixed now, please wait for the next release.