diff --git a/index.ts b/index.ts index 0c9c91c..f6d1e44 100644 --- a/index.ts +++ b/index.ts @@ -163,6 +163,9 @@ export class HDKey { if (!opt || typeof opt !== 'object') { throw new Error('HDKey.constructor must not be called directly'); } + if (typeof opt.depth !== 'undefined' && opt.depth >= 256) { + throw new Error('HDKey: opt.depth exceeds the serializable value 255'); + } this.versions = opt.versions || BITCOIN_VERSIONS; this.depth = opt.depth || 0; this.chainCode = opt.chainCode || null; diff --git a/test/hdkey.test.js b/test/hdkey.test.js index d9b281b..b5fe983 100644 --- a/test/hdkey.test.js +++ b/test/hdkey.test.js @@ -79,6 +79,55 @@ const fixtures = [ }, ]; describe('hdkey', () => { + it('Should throw an error when constructing a key of excesive depth', () => { + const seed = '000102030405060708090a0b0c0d0e0f'; + var hdkey = HDKey.fromMasterSeed(hexToBytes(seed)); + + const optMaxDepth = { + versions: hdkey.versions, + chainCode: hdkey.chainCode, + // The depth is the maximum 255 + depth: 255, + parentFingerprint: hdkey.fingerprint, + index: 0, + privateKey: hdkey.privateKey, + }; + // no errors + new HDKey(optMaxDepth); + + // Craft whatever key, but with excesive depth + const optTooDeep = { + versions: hdkey.versions, + chainCode: hdkey.chainCode, + // The depth is exceeding 255 + depth: 256, + parentFingerprint: hdkey.fingerprint, + index: 0, + privateKey: hdkey.privateKey, + }; + throws(() => new HDKey(optTooDeep)); + }); + it('Should throw an error when deriving keys of 256 depth', () => { + const seed = '000102030405060708090a0b0c0d0e0f'; + var hdkey = HDKey.fromMasterSeed(hexToBytes(seed)); + + // deriving 255 children should work + for (let i = 0; i < 255; i++) { + hdkey = hdkey.deriveChild(0); + } + // deriving one more shall throw an error + throws(() => hdkey.deriveChild(0)); + }); + it('Should throw an error when deriving from path of length 256', () => { + const seed = '000102030405060708090a0b0c0d0e0f'; + var hdkey = HDKey.fromMasterSeed(hexToBytes(seed)); + + // master key "lives" at 0th level, together with 255 + // more level its 256, which is still serializable + hdkey.derive('m' + '/0'.repeat(255)); + // but deriving one level deeper fails. + throws(() => hdkey.derive('m' + '/0'.repeat(256))); + }); it('Should derive private key correctly', () => { const seed = 'fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542'; const hdkey = HDKey.fromMasterSeed(hexToBytes(seed));