Skip to content

Directly deriving extended keys silently overflows (wraps around) the depth #1260

@quapka

Description

@quapka

BIP32 somewhat indirectly (I didn't find an explicit note about this in the BIP) enforces the depth of the derivation path (i.e., the length of /NUM/NUM/...) to be within the range [0, 255], because it gets serialized as a single byte. While this is recognized by NBitcoin in several places in the KeyPath implementation, there are ways how to overflow the depth.

In particular, see the ExtKey.cs and the ExtPubKey Derive(uint index) implementation that silently overflows the nDepth. This also affects indirectly BitcoinExtKey and BitcoinExtPubKey. Try the following:

var seed = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
ExtKey key = ExtKey.CreateFromSeed(seed);
ExtPubKey pubkey = key.Neuter();

for(int i = 0 ; i < 260; i++) {
    key = key.Derive(0);
    Console.WriteLine(key.Depth);
}
for(int i = 0 ; i < 260; i++) {
    pubkey = pubkey.Derive(0);
    Console.WriteLine(pubkey.Depth);
}

Contrary to #1259, I can see Ext[Pub]Key.Derive(uint index) being used, for example within the Wasabi Wallet.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions