Set pbkdf2Encode rounds to default to 210,000 (#1983)

* Set pbkdf2Encode rounds to default to 210,000

* Cap amount of rounds to 2048 when onlyJS = true to prevent overflow issues.

* Patch tests to use a consistent amount of encoding rounds.

* lint

* Add additional docs

* lint

---------

Co-authored-by: Valentin Fernandez <tinchofernandez8@gmail.com>
This commit is contained in:
Tarik Gul
2025-08-20 12:55:25 -03:00
committed by GitHub
co-authored by Valentin Fernandez
parent 55a3201bd5
commit e5e6bdd814
15 changed files with 88 additions and 43 deletions
+5 -5
View File
@@ -358,7 +358,7 @@ describe('keypair', (): void => {
});
it('creates with dev phrase with derivation path specified', (): void => {
const pair = keyring.createFromUri(PHRASE);
const pair = keyring.createFromUri(PHRASE, undefined, undefined, undefined, 2048);
expect(
pair.address
@@ -367,7 +367,7 @@ describe('keypair', (): void => {
it('creates with dev phrase with derivation path specified - addFromUri', (): void => {
expect(
keyring.addFromUri(PHRASE).address
keyring.addFromUri(PHRASE, undefined, undefined, undefined, 2048).address
).toEqual(ETH_ADDRESS_ONE);
});
@@ -375,12 +375,12 @@ describe('keypair', (): void => {
const keyringUntyped = new Keyring();
expect(
keyringUntyped.addFromUri(PHRASE, {}, 'ethereum').address
keyringUntyped.addFromUri(PHRASE, {}, 'ethereum', undefined, 2048).address
).toEqual(ETH_ADDRESS_ONE);
});
it('encodes a pair toJSON (and decodes)', (): void => {
const pair = keyring.createFromUri(PHRASE);
const pair = keyring.createFromUri(PHRASE, undefined, undefined, undefined, 2048);
const json = pair.toJson('password');
expect(json.address).toEqual('0x0381351b1b46d2602b0992bb5d5531f9c1696b0812feb2534b6884adc47e2e1d8b'); // this is the public key (different from address for ethereum)
@@ -399,7 +399,7 @@ describe('keypair', (): void => {
});
it('encodes a pair toJSON and back', (): void => {
const pairOriginal = keyring.createFromUri(PHRASE);
const pairOriginal = keyring.createFromUri(PHRASE, undefined, undefined, undefined, 2048);
const json = pairOriginal.toJson('password');
const pair = keyring.addFromJson(
json
+17 -6
View File
@@ -152,10 +152,15 @@ export class Keyring implements KeyringInstance {
* @name addFromUri
* @summary Creates an account via an suri
* @description Extracts the phrase, path and password from a SURI format for specifying secret keys `<secret>/<soft-key>//<hard-key>///<password>` (the `///password` may be omitted, and `/<soft-key>` and `//<hard-key>` maybe repeated and mixed). The secret can be a hex string, mnemonic phrase or a string (to be padded)
*/
public addFromUri (suri: string, meta: KeyringPair$Meta = {}, type: KeypairType = this.type, wordlist?: string[]): KeyringPair {
* @param _suri
* @param meta
* @param type The supported types of pairs. Either 'ed25519' | 'sr25519' | 'ecdsa' | 'ethereum'.
* @param wordlist - Optional custom wordlist for mnemonic.
* @param rounds - Optional: Number of PBKDF2 iterations to run (default: 210000 (when onlyJS = true) or 2048 (when onlyJS = false).
*/
public addFromUri (suri: string, meta: KeyringPair$Meta = {}, type: KeypairType = this.type, wordlist?: string[], rounds?: number): KeyringPair {
return this.addPair(
this.createFromUri(suri, meta, type, wordlist)
this.createFromUri(suri, meta, type, wordlist, rounds)
);
}
@@ -202,8 +207,14 @@ export class Keyring implements KeyringInstance {
* @name createFromUri
* @summary Creates a Keypair from an suri
* @description This creates a pair from the suri, but does not add it to the keyring
*
* @param _suri
* @param meta
* @param type The supported types of pairs. Either 'ed25519' | 'sr25519' | 'ecdsa' | 'ethereum'.
* @param wordlist - Optional custom wordlist for mnemonic.
* @param rounds - Optional: Number of PBKDF2 iterations to run (default: 210000 (when onlyJS = true) or 2048 (when onlyJS = false).
*/
public createFromUri (_suri: string, meta: KeyringPair$Meta = {}, type: KeypairType = this.type, wordlist?: string[]): KeyringPair {
public createFromUri (_suri: string, meta: KeyringPair$Meta = {}, type: KeypairType = this.type, wordlist?: string[], rounds?: number): KeyringPair {
// here we only aut-add the dev phrase if we have a hard-derived path
const suri = _suri.startsWith('//')
? `${DEV_PHRASE}${_suri}`
@@ -219,8 +230,8 @@ export class Keyring implements KeyringInstance {
if ([12, 15, 18, 21, 24].includes(parts.length)) {
seed = type === 'ethereum'
? mnemonicToLegacySeed(phrase, '', false, 64)
: mnemonicToMiniSecret(phrase, password, wordlist);
? mnemonicToLegacySeed(phrase, '', false, 64, rounds)
: mnemonicToMiniSecret(phrase, password, wordlist, false, rounds);
} else {
if (phrase.length > 32) {
throw new Error('specified phrase is not a valid mnemonic and is invalid as a raw seed at > 32 bytes');
+1 -1
View File
@@ -98,7 +98,7 @@ describe('keyring.addFromUri', (): void => {
describe(`${type}`, (): void => {
tests.forEach(({ pk, ss, uri }): void => {
it(`creates ${uri}`, (): void => {
const pair = keyring.addFromUri(uri, {}, type as KeypairType);
const pair = keyring.addFromUri(uri, {}, type as KeypairType, undefined, 2048);
expect(u8aToHex(pair.publicKey)).toEqual(pk);
expect(pair.address).toEqual(ss);