From ab55c37a33781d777010b619f213edc9fbea07b9 Mon Sep 17 00:00:00 2001 From: Jaco Date: Sat, 22 May 2021 18:24:37 +0300 Subject: [PATCH] Allow hdLedger derivation with optional 25th word password (#986) --- CHANGELOG.md | 1 + packages/util-crypto/src/hd/ledger/index.spec.ts | 6 ++++++ packages/util-crypto/src/hd/ledger/index.ts | 15 +++++++++++++-- packages/util-crypto/src/hd/ledger/master.ts | 4 ++-- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7793fcf51..4eadb576a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Changes: +- Allow hdLedger derivation with optional 25th word password - Sync with Substrate ss58 registry diff --git a/packages/util-crypto/src/hd/ledger/index.spec.ts b/packages/util-crypto/src/hd/ledger/index.spec.ts index f478689ea..d729e2bd4 100644 --- a/packages/util-crypto/src/hd/ledger/index.spec.ts +++ b/packages/util-crypto/src/hd/ledger/index.spec.ts @@ -7,6 +7,7 @@ import { hdLedger } from '..'; const MNE_0 = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'; const MNE_1 = 'open jelly jeans corn ketchup supreme brief element armed lens vault weather original scissors rug priority vicious lesson raven spot gossip powder person volcano'; +const MNE_P = `${MNE_1} testing`; const TESTS = { Kusama: { @@ -36,6 +37,11 @@ const TESTS = { ed25519: '0xe8c68348586d53e4e8d1a864b0e4e17c75e4eb06e0c63c1432bef2ba29e69d41', index: [0, 0], mnemonic: MNE_0 + }, + { + ed25519: '0x3890e8db837eba3f8f25215c753e1091062298ce671a51441e7ef89a7adc4f48', + index: [0, 0], + mnemonic: MNE_P } ] } diff --git a/packages/util-crypto/src/hd/ledger/index.ts b/packages/util-crypto/src/hd/ledger/index.ts index 6879160ef..fb49a9463 100644 --- a/packages/util-crypto/src/hd/ledger/index.ts +++ b/packages/util-crypto/src/hd/ledger/index.ts @@ -11,7 +11,18 @@ import { HARDENED, hdValidatePath } from '../validatePath'; import { ledgerDerivePrivate } from './derivePrivate'; import { ledgerMaster } from './master'; -export function hdLedger (mnemonic: string, path: string): Keypair { +export function hdLedger (_mnemonic: string, path: string): Keypair { + const parts = _mnemonic + .split(' ') + .map((s) => s.trim()) + .filter((s) => s); + + assert([12, 24, 25].includes(parts.length), 'Expected a mnemonic with 24 words (or 25 including a password)'); + + const [mnemonic, password] = parts.length === 25 + ? [parts.slice(0, 24).join(' '), parts[24]] + : [parts.join(' '), '']; + assert(mnemonicValidate(mnemonic), 'Invalid mnemonic passed to ledger derivation'); assert(hdValidatePath(path), 'Invalid derivation path'); @@ -21,7 +32,7 @@ export function hdLedger (mnemonic: string, path: string): Keypair { .slice(1) .map((n) => parseInt(n.replace("'", ''), 10)) .map((n) => (n < HARDENED) ? (n + HARDENED) : n) - .reduce((x, n) => ledgerDerivePrivate(x, n), ledgerMaster(mnemonic)) + .reduce((x, n) => ledgerDerivePrivate(x, n), ledgerMaster(mnemonic, password)) .slice(0, 32) ); } diff --git a/packages/util-crypto/src/hd/ledger/master.ts b/packages/util-crypto/src/hd/ledger/master.ts index 1846f3bef..a3b9b47ae 100644 --- a/packages/util-crypto/src/hd/ledger/master.ts +++ b/packages/util-crypto/src/hd/ledger/master.ts @@ -9,8 +9,8 @@ import { mnemonicToSeedSync } from '../../mnemonic/bip39'; const ED25519_CRYPTO = 'ed25519 seed'; // gets an xprv from a mnemonic -export function ledgerMaster (mnemonic: string): Uint8Array { - const seed = mnemonicToSeedSync(mnemonic); +export function ledgerMaster (mnemonic: string, password?: string): Uint8Array { + const seed = mnemonicToSeedSync(mnemonic, password); const chainCode = hmacSha256(ED25519_CRYPTO, new Uint8Array([1, ...seed])); let priv;