Skip to content

Extended key lineage.depth overflows and produces garbage key #1623

Open
@quapka

Description

@quapka

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.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions