bip32 / bip32.github.io

BIP32 is a Brainwallet-based implementation for BIP0032 deterministic wallet generation
Other
111 stars 71 forks source link

Fix bug that assumes toByteArrayUnsigned() always returns 32 bytes. #5

Closed anaoum closed 9 years ago

anaoum commented 9 years ago

To reproduce this bug, try entering the following XPRIV: xprv9s21ZrQH143K3GMYVMZBZCGProVPNqGXRXz3ktUYt1rXG813HhysPLeNj8AfahpW2d4Tc678FMYndMrw9sqUFuLD2mug9pwojMuNusRbsv9 and use the following derivation path: m/44'

The correct derived private key should be: xprv9tzN9JZpuT1wiz7y2qsBnjttAxvUQcdjCCEVXdMQmp32FeX4vGve5PA7yFan15Jo71HrxsA6VAnpqWW2JNoaXaLe3NeqWKoYS76AEBfioN7 but the code was previously outputting: DeaWiSNc9gKmPJgBaytskvDH3Cz4tebKSjxu9t2hSyGVx1gt2xdGPVXjPHoUQd9LBRpcJQDbFdQdEAzqWq2eVeErNLsGwEEWGEGgArZjHap4aP

This was as a result of line 185 in bip32.js calling this.eckey.priv.toByteArrayUnsigned() without verifying that the returned byte array had the correct length required for serialization (32 bytes).

Furthermore, errors would cascade down the path dangerously unnoticed. For example, using the path m/44'/0' with the XPRIV mentioned above, the correct derived private key should be: xprv9xUGaEZ5EBM1tGE9Ujp2EaPC85Pt8PRwMSmk53rvy3YmJbg6jBZM3mybraxFBWFgzrfhEhiiugDMArUqiGDSQF3zHL8wY6AZBXE77Jq2utJ however the original code would give: xprv9xUGaEZ5EBM1ueG3H1yNEgQuk9ivpzaHhVbp58hcCJSyrinvZC3k6uvzobs6Av5UmLvjfRQK6AWq2fL9ej27wjr3BURJFddYzvovFYngqLS

This was quite dangerous as there is nothing obviously wrong with the output. This cascading bug was due to line 254 in bip32.js which also incorrectly assumed that toByteArrayUnsigned() always returns a 32 byte long array.

anaoum commented 9 years ago

This solves issue #4

sarchar commented 9 years ago

Merged. Thanks for the commit.