Description
I've tested the following on version3
and also master
(the code needs to be slightly different for the version3
to compile.
#include <bitcoin/system.hpp>
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace bc;
using namespace libbitcoin::system;
using namespace bc::system::wallet;
int main() {
// Example tests from https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#test-vector-1
data_chunk hd_seed = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
/* data_chunk seed_chunk(to_chunk(hd_seed)); */
hd_private m(hd_seed, hd_private::mainnet);
hd_public y = m.to_public();
for (int i = 0; i < 255; i++) {
y = y.derive_public(0);
}
printf("%d: ", y.lineage().depth);
std::cout << y << std::endl;
y = y.derive_public(0);
printf("%d: ", y.lineage().depth);
std::cout << y << std::endl;
return 0;
}
(The example does not show this for hd_private
, because I couldn't get the demo to derive 256th key, but the problem is most likely the same for hd_private
as well.)
which gives the following output:
255: xpubEND4cWBkwMUcwj3bjw4RNYcpnuvgbEaGSCAujB1XQro3Ptpvs8hDMFsBmk1mhfz9sGc3k4XPpueGAcR66Kb7HMXwfnKKBaV3i7YyMxLuwKh
0: 1111111111111111111111111111111111111111111111111111111111111111111111111111114rcJhr
For the version3
case it seemed clear, why the overflow happens in hd_private.cpp
and hd_public.cpp
. I haven't investigated further, where does the 1111111111111111111111111111111111111111111111111111111111111111111111111111114rcJhr
value come from though.
The master
versions hd_private.cpp
and hd_public.cpp
seem to be aware of this, but from my testing I see the same result for version3
and master
.
Maybe I just misunderstood how the key derivation is intended to work, but also from checking the examples, I am failing to see, e.g., some checks, that would be supposed to catch this in the client's code.