Skip to content
This repository was archived by the owner on Oct 30, 2024. It is now read-only.

Commit 807b980

Browse files
committed
cleaner flow around the .toV3 KDF parameters
1 parent 2884429 commit 807b980

File tree

1 file changed

+53
-71
lines changed

1 file changed

+53
-71
lines changed

src/index.ts

Lines changed: 53 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,12 @@ function mergeToV3ParamsWithDefaults(params?: Partial<V3Params>): V3Params {
5252
}
5353
}
5454

55-
// KDF params
55+
// KDF
56+
57+
const enum KDFFunctions {
58+
PBKDF = 'pbkdf2',
59+
Scrypt = 'scrypt',
60+
}
5661

5762
interface ScryptKDFParams {
5863
dklen: number
@@ -69,48 +74,24 @@ interface PBKDFParams {
6974
salt: string
7075
}
7176

72-
// union of both the PBKDF2 and Scrypt KDF parameters representing all possible
73-
// parameters the user could supply
74-
type AllKDFParams = ScryptKDFParams & PBKDFParams
75-
7677
type KDFParams = ScryptKDFParams | PBKDFParams
7778

78-
function kdfParamsForPBKDF(params: AllKDFParams): PBKDFParams {
79-
delete params.n
80-
delete params.p
81-
delete params.r
82-
return params
83-
}
84-
85-
function kdfParamsForScrypt(params: AllKDFParams): ScryptKDFParams {
86-
delete params.c
87-
delete params.prf
88-
return params
89-
}
90-
91-
/**
92-
* Based on the parameter list passed to the Wallet.prototype.toV3() method this
93-
* returns a list of parameters for running the key derivation function.
94-
* @param params params passed into the .toV3() method
95-
*/
96-
function mergeKDFParamsWithDefaults(params: V3Params): AllKDFParams {
97-
const kdfDefaults = {
98-
c: 262144,
79+
function kdfParamsForPBKDF(opts: V3Params): PBKDFParams {
80+
return {
81+
dklen: opts.dklen,
82+
salt: opts.salt.toString('hex'),
83+
c: opts.c,
9984
prf: 'hmac-sha256',
100-
n: 262144,
101-
r: 8,
102-
p: 1,
103-
salt: params.salt.toString('hex'),
10485
}
86+
}
10587

88+
function kdfParamsForScrypt(opts: V3Params): ScryptKDFParams {
10689
return {
107-
dklen: params.dklen,
108-
salt: kdfDefaults.salt,
109-
c: params.c || kdfDefaults.c,
110-
prf: kdfDefaults.prf,
111-
n: params.n || kdfDefaults.n,
112-
r: params.r || kdfDefaults.r,
113-
p: params.p || kdfDefaults.p,
90+
dklen: opts.dklen,
91+
salt: opts.salt.toString('hex'),
92+
n: opts.n,
93+
r: opts.r,
94+
p: opts.p,
11495
}
11596
}
11697

@@ -413,40 +394,41 @@ export default class Wallet {
413394
throw new Error('This is a public key only wallet')
414395
}
415396

416-
const params = mergeToV3ParamsWithDefaults(opts)
417-
const kdfParams = mergeKDFParamsWithDefaults(params)
397+
const v3Params: V3Params = mergeToV3ParamsWithDefaults(opts)
418398

399+
let kdfParams: PBKDFParams | ScryptKDFParams
419400
let derivedKey: Buffer
420-
let finalKDFParams: KDFParams
421-
422-
if (params.kdf === 'pbkdf2') {
423-
derivedKey = crypto.pbkdf2Sync(
424-
Buffer.from(password),
425-
params.salt,
426-
kdfParams.c,
427-
kdfParams.dklen,
428-
'sha256',
429-
)
430-
finalKDFParams = kdfParamsForPBKDF(kdfParams)
431-
} else if (params.kdf === 'scrypt') {
432-
// FIXME: support progress reporting callback
433-
derivedKey = scryptsy(
434-
Buffer.from(password),
435-
params.salt,
436-
kdfParams.n,
437-
kdfParams.r,
438-
kdfParams.p,
439-
kdfParams.dklen,
440-
)
441-
finalKDFParams = kdfParamsForScrypt(kdfParams)
442-
} else {
443-
throw new Error('Unsupported kdf')
401+
switch (v3Params.kdf) {
402+
case KDFFunctions.PBKDF:
403+
kdfParams = kdfParamsForPBKDF(v3Params)
404+
derivedKey = crypto.pbkdf2Sync(
405+
Buffer.from(password),
406+
v3Params.salt,
407+
kdfParams.c,
408+
kdfParams.dklen,
409+
'sha256',
410+
)
411+
break
412+
case KDFFunctions.Scrypt:
413+
kdfParams = kdfParamsForScrypt(v3Params)
414+
// FIXME: support progress reporting callback
415+
derivedKey = scryptsy(
416+
Buffer.from(password),
417+
v3Params.salt,
418+
kdfParams.n,
419+
kdfParams.r,
420+
kdfParams.p,
421+
kdfParams.dklen,
422+
)
423+
break
424+
default:
425+
throw new Error('Unsupported kdf')
444426
}
445427

446428
const cipher: crypto.Cipher = crypto.createCipheriv(
447-
params.cipher,
429+
v3Params.cipher,
448430
derivedKey.slice(0, 16),
449-
params.iv,
431+
v3Params.iv,
450432
)
451433
if (!cipher) {
452434
throw new Error('Unsupported cipher')
@@ -459,15 +441,15 @@ export default class Wallet {
459441

460442
return {
461443
version: 3,
462-
id: uuidv4({ random: params.uuid }),
463-
// @ts-ignore FIXME: official V3 keystore spec omits the address key
444+
id: uuidv4({ random: v3Params.uuid }),
445+
// @ts-ignore - the official V3 keystore spec omits the address key
464446
address: this.getAddress().toString('hex'),
465447
crypto: {
466448
ciphertext: ciphertext.toString('hex'),
467-
cipherparams: { iv: params.iv.toString('hex') },
468-
cipher: params.cipher,
469-
kdf: params.kdf,
470-
kdfparams: finalKDFParams,
449+
cipherparams: { iv: v3Params.iv.toString('hex') },
450+
cipher: v3Params.cipher,
451+
kdf: v3Params.kdf,
452+
kdfparams: kdfParams,
471453
mac: mac.toString('hex'),
472454
},
473455
}

0 commit comments

Comments
 (0)