0
# Hierarchical Key Derivation
1
2
Hierarchical deterministic key derivation supporting both hard and soft derivation paths for creating multiple keys from a single seed following BIP32-style derivation.
3
4
## Capabilities
5
6
### Path-Based Key Derivation
7
8
Derive keys from hierarchical paths using standard derivation notation.
9
10
```typescript { .api }
11
/**
12
* Derive key from hierarchical path
13
* @param pair - Parent key pair
14
* @param path - Derivation path (e.g., "//hard/soft/path")
15
* @param type - Key type for derivation
16
* @returns Derived key pair
17
*/
18
function keyFromPath(pair: Keypair, path: string, type: KeypairType): Keypair;
19
20
/**
21
* Extract path components from derivation string
22
* @param path - Full derivation path with optional password
23
* @returns Parsed path components
24
*/
25
function keyExtractPath(path: string): { path: string; password?: string };
26
27
/**
28
* Extract SURI (Secret URI) components
29
* @param suri - Secret URI containing mnemonic and derivation
30
* @returns Parsed SURI components
31
*/
32
function keyExtractSuri(suri: string): { phrase: string; path: string; password?: string };
33
```
34
35
**Usage Example:**
36
37
```typescript
38
import {
39
sr25519PairFromSeed,
40
keyFromPath,
41
keyExtractPath,
42
mnemonicToMiniSecret
43
} from "@polkadot/util-crypto";
44
45
const mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
46
const seed = mnemonicToMiniSecret(mnemonic);
47
const rootPair = sr25519PairFromSeed(seed);
48
49
// Derive keys from paths
50
const alicePair = keyFromPath(rootPair, "//Alice", "sr25519");
51
const bobPair = keyFromPath(rootPair, "//Bob", "sr25519");
52
const childPair = keyFromPath(alicePair, "/soft/path", "sr25519");
53
54
// Extract path components
55
const { path, password } = keyExtractPath("//hard/soft///password");
56
console.log(path); // "//hard/soft"
57
console.log(password); // "password"
58
```
59
60
### Algorithm-Specific Derivation
61
62
Hierarchical key derivation functions for specific cryptographic algorithms.
63
64
```typescript { .api }
65
/**
66
* Sr25519 hierarchical key derivation
67
* @param seed - Parent seed
68
* @param path - Derivation path
69
* @returns Derived key pair
70
*/
71
function keyHdkdSr25519(seed: Uint8Array, path: string): Keypair;
72
73
/**
74
* Ed25519 hierarchical key derivation
75
* @param seed - Parent seed
76
* @param path - Derivation path
77
* @returns Derived key pair
78
*/
79
function keyHdkdEd25519(seed: Uint8Array, path: string): Keypair;
80
81
/**
82
* ECDSA hierarchical key derivation
83
* @param seed - Parent seed
84
* @param path - Derivation path
85
* @returns Derived key pair
86
*/
87
function keyHdkdEcdsa(seed: Uint8Array, path: string): Keypair;
88
```
89
90
### Ethereum-Compatible HD Derivation
91
92
BIP32-compatible hierarchical deterministic key derivation for Ethereum.
93
94
```typescript { .api }
95
/**
96
* Ethereum-compatible HD key derivation (BIP32)
97
* @param seed - Master seed
98
* @param path - BIP32 derivation path (e.g., "m/44'/60'/0'/0/0")
99
* @returns Derived key pair
100
*/
101
function hdEthereum(seed: Uint8Array, path?: string): Keypair;
102
```
103
104
**Usage Example:**
105
106
```typescript
107
import { hdEthereum, mnemonicToLegacySeed } from "@polkadot/util-crypto";
108
109
const mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
110
const seed = mnemonicToLegacySeed(mnemonic);
111
112
// Ethereum account derivation paths
113
const account0 = hdEthereum(seed, "m/44'/60'/0'/0/0");
114
const account1 = hdEthereum(seed, "m/44'/60'/0'/0/1");
115
116
// Custom derivation path
117
const customPath = hdEthereum(seed, "m/44'/60'/1'/0/0");
118
```
119
120
### Ledger-Compatible Derivation
121
122
Derivation compatible with Ledger hardware wallets.
123
124
```typescript { .api }
125
/**
126
* Ledger-compatible key derivation
127
* @param mnemonic - 24-word mnemonic (or 25 with password)
128
* @param path - Derivation path
129
* @param rounds - Number of PBKDF2 rounds (default: 2048)
130
* @returns Derived Ed25519 key pair
131
*/
132
function hdLedger(mnemonic: string, path: string, rounds?: number): Keypair;
133
```
134
135
**Usage Example:**
136
137
```typescript
138
import { hdLedger } from "@polkadot/util-crypto";
139
140
// 24-word mnemonic
141
const mnemonic24 = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art";
142
const ledgerKey = hdLedger(mnemonic24, "m/44'/354'/0'/0'/0'");
143
144
// 25-word mnemonic (24 words + password)
145
const mnemonic25 = mnemonic24 + " password";
146
const ledgerKeyWithPassword = hdLedger(mnemonic25, "m/44'/354'/0'/0'/0'");
147
```
148
149
### Hierarchical Deterministic Key Derivation (HDKD)
150
151
Lower-level HDKD functions for specific cryptographic schemes.
152
153
```typescript { .api }
154
/**
155
* SR25519 hierarchical deterministic key derivation
156
* @param keypair - Parent keypair
157
* @param junction - Derivation junction with chain code and hard/soft flag
158
* @returns Derived keypair
159
*/
160
function keyHdkdSr25519(keypair: Keypair, junction: DeriveJunction): Keypair;
161
162
/**
163
* Ed25519 hierarchical deterministic key derivation (hard derivation only)
164
* @param keypair - Parent keypair
165
* @param junction - Derivation junction with chain code and hard flag
166
* @returns Derived keypair
167
*/
168
function keyHdkdEd25519(keypair: Keypair, junction: DeriveJunction): Keypair;
169
170
/**
171
* ECDSA/secp256k1 hierarchical deterministic key derivation (hard derivation only)
172
* @param keypair - Parent keypair
173
* @param junction - Derivation junction with chain code and hard flag
174
* @returns Derived keypair
175
*/
176
function keyHdkdEcdsa(keypair: Keypair, junction: DeriveJunction): Keypair;
177
```
178
179
### SURI Extraction
180
181
Extracts components from Substrate URI (SURI) format strings.
182
183
```typescript { .api }
184
interface ExtractResult {
185
derivePath: string;
186
password?: string;
187
path: DeriveJunction[];
188
phrase: string;
189
}
190
191
/**
192
* Extract phrase, path and password from SURI format
193
* @param suri - SURI string in format `<secret>/<soft-key>//<hard-key>///<password>`
194
* @returns Parsed SURI components
195
*/
196
function keyExtractSuri(suri: string): ExtractResult;
197
```
198
199
### Path Validation
200
201
Validate derivation paths for correctness.
202
203
```typescript { .api }
204
/**
205
* Validate hierarchical derivation path
206
* @param path - Derivation path to validate
207
* @returns true if path is valid
208
*/
209
function hdValidatePath(path: string): boolean;
210
```
211
212
**Usage Example:**
213
214
```typescript
215
import { hdValidatePath } from "@polkadot/util-crypto";
216
217
console.log(hdValidatePath("m/44'/60'/0'/0/0")); // true
218
console.log(hdValidatePath("//Alice/stash")); // true
219
console.log(hdValidatePath("invalid-path")); // false
220
```
221
222
## Derivation Path Notation
223
224
### Substrate/Polkadot Style
225
- `//hard` - Hard derivation
226
- `/soft` - Soft derivation
227
- `///password` - Password for derivation
228
- `//Alice` - Named hard derivation
229
- `/stash` - Named soft derivation
230
231
### BIP32 Style (Ethereum)
232
- `m/44'/60'/0'/0/0` - BIP32 path
233
- `'` indicates hardened derivation
234
- Numbers are derivation indices
235
236
## Complete Derivation Example
237
238
```typescript
239
import {
240
cryptoWaitReady,
241
mnemonicGenerate,
242
mnemonicToMiniSecret,
243
sr25519PairFromSeed,
244
keyFromPath,
245
encodeAddress
246
} from "@polkadot/util-crypto";
247
248
async function createDerivedAccounts() {
249
await cryptoWaitReady();
250
251
// Generate master mnemonic
252
const mnemonic = mnemonicGenerate(24);
253
const seed = mnemonicToMiniSecret(mnemonic);
254
const rootPair = sr25519PairFromSeed(seed);
255
256
// Create derived accounts
257
const accounts = {
258
alice: keyFromPath(rootPair, "//Alice", "sr25519"),
259
bob: keyFromPath(rootPair, "//Bob", "sr25519"),
260
stash: keyFromPath(rootPair, "//Alice/stash", "sr25519"),
261
controller: keyFromPath(rootPair, "//Alice/controller", "sr25519")
262
};
263
264
// Generate addresses
265
const addresses = Object.fromEntries(
266
Object.entries(accounts).map(([name, pair]) => [
267
name,
268
encodeAddress(pair.publicKey, 0) // Polkadot network
269
])
270
);
271
272
return { mnemonic, accounts, addresses };
273
}
274
```
275
276
## Security Considerations
277
278
### Hard vs Soft Derivation
279
- **Hard derivation** (`//`): Cannot derive child public keys from parent public key
280
- **Soft derivation** (`/`): Can derive child public keys, but less secure
281
- Use hard derivation for account separation
282
- Use soft derivation for address generation
283
284
### Path Security
285
- Keep derivation paths consistent and documented
286
- Use meaningful names for derived keys
287
- Protect passwords used in derivation paths
288
- Consider using standard derivation paths for compatibility
289
290
### Key Management
291
- Store master seed securely
292
- Derive keys on-demand rather than storing all derived keys
293
- Use appropriate key types for specific use cases
294
- Implement proper access controls for derived keys