|
47 | 47 | /**
|
48 | 48 | * @typedef HDKey
|
49 | 49 | * @prop {HDVersions} versions - magic bytes for base58 prefix
|
50 |
| - * @prop {Number} depth - of hd path - typically 0 is seed, 1-3 hardened, 4-5 are not |
| 50 | + * @prop {Number} depth - of hd path - typically 0 is seed, 1-3 hardened, 4-5 public |
51 | 51 | * @prop {Number} parentFingerprint - 32-bit int, slice of id, stored in child xkeys
|
52 | 52 | * @prop {Number} index - the final segment of an HD Path, the index of the wif/addr
|
53 | 53 | * @prop {Uint8Array} chainCode - extra 32-bytes of shared entropy for xkeys
|
@@ -374,24 +374,25 @@ var DashHd = ("object" === typeof module && exports) || {};
|
374 | 374 | let _indexDv = new DataView(_indexBuffer.buffer);
|
375 | 375 |
|
376 | 376 | DashHd.deriveChild = async function (hdkey, index, hardened = HARDENED) {
|
377 |
| - let seed = new Uint8Array(INDEXED_KEY_SIZE); |
| 377 | + // seed = indexedKey |
| 378 | + let indexedKey = new Uint8Array(INDEXED_KEY_SIZE); |
378 | 379 | if (hardened) {
|
379 | 380 | if (!hdkey.privateKey) {
|
380 | 381 | throw new Error("Could not derive hardened child key");
|
381 | 382 | }
|
382 | 383 | index += HARDENED_OFFSET;
|
383 |
| - seed.set([0], 0); |
384 |
| - seed.set(hdkey.privateKey, 1); |
| 384 | + indexedKey.set([0], 0); |
| 385 | + indexedKey.set(hdkey.privateKey, 1); |
385 | 386 | } else {
|
386 |
| - seed.set(hdkey.publicKey, 0); |
| 387 | + indexedKey.set(hdkey.publicKey, 0); |
387 | 388 | }
|
388 | 389 | _indexDv.setUint32(0, index, BUFFER_BE);
|
389 |
| - seed.set(_indexBuffer, KEY_SIZE); |
| 390 | + indexedKey.set(_indexBuffer, KEY_SIZE); |
390 | 391 |
|
391 | 392 | let chainAndKeys;
|
392 | 393 | try {
|
393 | 394 | //@ts-ignore
|
394 |
| - chainAndKeys = await DashHd._derive(seed, hdkey); |
| 395 | + chainAndKeys = await DashHd._derive(indexedKey, hdkey); |
395 | 396 | } catch (e) {
|
396 | 397 | // In essence:
|
397 | 398 | // if it couldn't produce a public key, just go on the next one
|
@@ -424,28 +425,28 @@ var DashHd = ("object" === typeof module && exports) || {};
|
424 | 425 | };
|
425 | 426 |
|
426 | 427 | //@ts-ignore
|
427 |
| - DashHd._derive = async function (indexedKey, parent) { |
| 428 | + DashHd._derive = async function (indexedKey, xParent) { |
428 | 429 | // seed = indexedKey
|
429 |
| - // I = nextDepth |
| 430 | + // I = hash |
430 | 431 | // IL = keyTweak
|
431 | 432 | // IR = nextChainCode
|
432 |
| - let nextDepth = await Utils.sha512hmac(parent.chainCode, indexedKey); |
433 |
| - let keyTweak = nextDepth.slice(0, 32); |
434 |
| - let nextChainCode = nextDepth.slice(32); |
435 |
| - |
436 |
| - let nextPrivKey; |
437 |
| - if (parent.privateKey) { |
438 |
| - let priv = parent.privateKey; |
439 |
| - nextPrivKey = await Utils.privateKeyTweakAdd(priv, keyTweak); |
| 433 | + let hash = await Utils.sha512hmac(xParent.chainCode, indexedKey); |
| 434 | + let keyTweak = hash.slice(0, 32); |
| 435 | + let hashedChainCode = hash.slice(32); |
| 436 | + |
| 437 | + let tweakedPrivKey; |
| 438 | + if (xParent.privateKey) { |
| 439 | + let priv = xParent.privateKey; |
| 440 | + tweakedPrivKey = await Utils.privateKeyTweakAdd(priv, keyTweak); |
440 | 441 | }
|
441 | 442 |
|
442 |
| - let pub = parent.publicKey; |
443 |
| - let nextPubkey = await Utils.publicKeyTweakAdd(pub, keyTweak); |
| 443 | + let pub = xParent.publicKey; |
| 444 | + let tweakedPubkey = await Utils.publicKeyTweakAdd(pub, keyTweak); |
444 | 445 |
|
445 | 446 | return {
|
446 |
| - chainCode: nextChainCode, |
447 |
| - privateKey: nextPrivKey, |
448 |
| - publicKey: nextPubkey, |
| 447 | + chainCode: hashedChainCode, |
| 448 | + privateKey: tweakedPrivKey, |
| 449 | + publicKey: tweakedPubkey, |
449 | 450 | };
|
450 | 451 | };
|
451 | 452 |
|
@@ -508,12 +509,12 @@ var DashHd = ("object" === typeof module && exports) || {};
|
508 | 509 | let coinType = opts?.coinType ?? 5;
|
509 | 510 | let versions = opts?.versions || DashHd.MAINNET;
|
510 | 511 |
|
511 |
| - // I = rootDepth |
| 512 | + // I = hash |
512 | 513 | // IL = rootPrivKey
|
513 | 514 | // IR = rootChainCode
|
514 |
| - let rootDepth = await Utils.sha512hmac(ROOT_CHAIN, seed); |
515 |
| - let rootPrivKey = rootDepth.slice(0, 32); |
516 |
| - let rootChainCode = rootDepth.slice(32); |
| 515 | + let hash = await Utils.sha512hmac(ROOT_CHAIN, seed); |
| 516 | + let rootPrivKey = hash.slice(0, 32); |
| 517 | + let rootChainCode = hash.slice(32); |
517 | 518 | let rootPubkey = await Utils.toPublicKey(rootPrivKey);
|
518 | 519 |
|
519 | 520 | let chainAndKeys = {
|
@@ -744,8 +745,8 @@ if ("object" === typeof module) {
|
744 | 745 |
|
745 | 746 | /**
|
746 | 747 | * @callback HDDeriveHelper
|
747 |
| - * @param {Uint8Array} seed - derived from index and chain code, or root |
748 |
| - * @param {HDDeriveHelperOptions} chainParts |
| 748 | + * @param {Uint8Array} indexedKey - (misnomer "seed") the parent key bytes + index bytes |
| 749 | + * @param {HDDeriveHelperOptions} xParent - the xKey parent (keys, chain code, etc) |
749 | 750 | * returns {Promise<HDDeriveHelperOptions>}
|
750 | 751 | * @throws Error - in the rare case the index can't produce a valid public key
|
751 | 752 | */
|
|
0 commit comments