Fix passphrase seed generation and use LibAuth vectors

This commit is contained in:
Jim Hamill
2025-06-23 11:47:48 +00:00
parent 294ec12da9
commit 9b785e2d73
2 changed files with 117 additions and 108 deletions
+3 -1
View File
@@ -270,7 +270,9 @@ export class Mnemonic {
* @returns The seed (for use with HDPrivateNodes).
*/
public toSeed(): Uint8Array {
return deriveSeedFromBip39Mnemonic(this.toPhrase());
return deriveSeedFromBip39Mnemonic(this.toPhrase(false), {
passphrase: this.getPassphrase(),
});
}
/**
+114 -107
View File
@@ -1,6 +1,6 @@
import { describe, it, expect } from 'vitest';
import { Bytes } from '~/src/bytes';
import { Mnemonic, MnemonicRaw } from '~/src/mnemonic';
import { Bytes } from '../src/bytes';
import { Mnemonic, MnemonicRaw } from '../src/mnemonic';
describe('Success cases', () => {
// Simple array of cases
@@ -9,6 +9,7 @@ describe('Success cases', () => {
fromWords: Array<string>;
passphrase?: string;
raw: MnemonicRaw;
toEntropy: Uint8Array;
toSeed: Uint8Array;
toPhrase: string;
toPhraseWithoutPassphrase: string;
@@ -18,145 +19,151 @@ describe('Success cases', () => {
// No pass-phrase
{
fromPhrase:
'goose just fan kidney barrel album wave crowd movie flame cousin exhaust',
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
fromWords: [
'goose',
'just',
'fan',
'kidney',
'barrel',
'album',
'wave',
'crowd',
'movie',
'flame',
'cousin',
'exhaust',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'about',
],
raw: {
words: [
'goose',
'just',
'fan',
'kidney',
'barrel',
'album',
'wave',
'crowd',
'movie',
'flame',
'cousin',
'exhaust',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'about',
],
},
toEntropy: Bytes.fromHex(
'00000000000000000000000000000000',
).toUint8Array(),
toSeed: Bytes.fromHex(
'7066f43a742829f0edce7d8e3c31651df320f13913995a6500f4e515db372b35202227f923ff181defc35cea02f8468df39f8fa9d97a202d252e61562e4bbfb5',
'5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4',
).toUint8Array(),
toPhrase:
'goose just fan kidney barrel album wave crowd movie flame cousin exhaust',
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
toPhraseWithoutPassphrase:
'goose just fan kidney barrel album wave crowd movie flame cousin exhaust',
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
toWords: [
'goose',
'just',
'fan',
'kidney',
'barrel',
'album',
'wave',
'crowd',
'movie',
'flame',
'cousin',
'exhaust',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'about',
],
toWordsWithoutPassphrase: [
'goose',
'just',
'fan',
'kidney',
'barrel',
'album',
'wave',
'crowd',
'movie',
'flame',
'cousin',
'exhaust',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'abandon',
'about',
],
},
// Passphrase
{
fromPhrase:
'goose just fan kidney barrel album wave crowd movie flame cousin exhaust GeneralProtocols!',
'legal winner thank year wave sausage worth useful legal winner thank yellow Libauth',
fromWords: [
'goose',
'just',
'fan',
'kidney',
'barrel',
'album',
'legal',
'winner',
'thank',
'year',
'wave',
'crowd',
'movie',
'flame',
'cousin',
'exhaust',
'GeneralProtocols!',
'sausage',
'worth',
'useful',
'legal',
'winner',
'thank',
'yellow',
'Libauth',
],
passphrase: 'GeneralProtocols!',
passphrase: 'Libauth',
raw: {
words: [
'goose',
'just',
'fan',
'kidney',
'barrel',
'album',
'legal',
'winner',
'thank',
'year',
'wave',
'crowd',
'movie',
'flame',
'cousin',
'exhaust',
'sausage',
'worth',
'useful',
'legal',
'winner',
'thank',
'yellow',
],
passphrase: 'GeneralProtocols!',
passphrase: 'Libauth',
},
toEntropy: Bytes.fromHex(
'7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f',
).toUint8Array(),
toSeed: Bytes.fromHex(
'2f706756ab2083f7ce07c0c0fcde8f14f062da5de839f42763262b25e0d871f03dd2b561d55eaacc471c94da656ee7b0007fb48a64e31ec91a1a2ba706b46b89',
'0199495e71f9e7f40b52febf82dcb1a6c342e9178a5e8cfea4204cf6b2071e89345ab83e8a5f0ea3ae59025e5e2e8dd2c965752541912f28ead8a33ff7dd11dd',
).toUint8Array(),
toPhrase:
'goose just fan kidney barrel album wave crowd movie flame cousin exhaust GeneralProtocols!',
'legal winner thank year wave sausage worth useful legal winner thank yellow Libauth',
toPhraseWithoutPassphrase:
'goose just fan kidney barrel album wave crowd movie flame cousin exhaust',
'legal winner thank year wave sausage worth useful legal winner thank yellow',
toWords: [
'goose',
'just',
'fan',
'kidney',
'barrel',
'album',
'legal',
'winner',
'thank',
'year',
'wave',
'crowd',
'movie',
'flame',
'cousin',
'exhaust',
'GeneralProtocols!',
'sausage',
'worth',
'useful',
'legal',
'winner',
'thank',
'yellow',
'Libauth',
],
toWordsWithoutPassphrase: [
'goose',
'just',
'fan',
'kidney',
'barrel',
'album',
'legal',
'winner',
'thank',
'year',
'wave',
'crowd',
'movie',
'flame',
'cousin',
'exhaust',
'sausage',
'worth',
'useful',
'legal',
'winner',
'thank',
'yellow',
],
},
];
@@ -211,7 +218,7 @@ describe('Success cases', () => {
it.each(testCases)(
'toWords(withoutPassphrase)',
({ toWordsWithoutPassphrase, passphrase, raw }) => {
({ toWordsWithoutPassphrase, _passphrase, raw }) => {
const mnemonic = Mnemonic.fromRaw(raw);
expect(mnemonic.toWords(false)).toStrictEqual(toWordsWithoutPassphrase);
},