Skip to content

Commit

Permalink
argon2: reload wasm module after timeout when using memory heavy pa…
Browse files Browse the repository at this point in the history
…rams (#199)

We manually reload the module if no memory-heavy (128MB+) argon2 computation has been requested
in a while, to deallocate the memory.
This is better than reloading the module every time (automatically done if the memory exceeds
`Argon2S2K.ARGON2_WASM_MEMORY_THRESHOLD_RELOAD`),
as doing so comes with a performance hit.

Co-authored-by: Daniel Huigens <d.huigens@protonmail.com>
  • Loading branch information
larabr and twiss authored Apr 12, 2024
1 parent 2810357 commit 3520bb5
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 9 deletions.
30 changes: 29 additions & 1 deletion lib/crypto/argon2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,36 @@ export interface Argon2Options {
params: Argon2Params
}

// We manually reload the module if no memory-heavy (128MB+) argon2 computation has been requested in a while,
// to deallocate the memory.
// This is better than reloading the module every time (automatically done if the memory exceeds `Argon2S2K.ARGON2_WASM_MEMORY_THRESHOLD_RELOAD`),
// as doing so comes with a performance hit.
const SECOND = 1000;
const TimeoutHandler = {
id: undefined,
cancelReloadingTimeout: (memoryExponent: number) => (
memoryExponent > ARGON2_PARAMS.MINIMUM.memoryExponent && clearTimeout(TimeoutHandler.id)
),
setupReloadingTimeout: (memoryExponent: number) => {
const shouldReloadAfterTimeout = memoryExponent > ARGON2_PARAMS.MINIMUM.memoryExponent &&
memoryExponent <= Argon2S2K.ARGON2_WASM_MEMORY_THRESHOLD_RELOAD;
// @ts-ignore NodeJS.Timeout typedef interfering
TimeoutHandler.id = shouldReloadAfterTimeout ?
setTimeout(
() => Argon2S2K.reloadWasmModule(),
10 * SECOND
) as any as number
: undefined;
}
};

export async function argon2({ password, salt, params = ARGON2_PARAMS.RECOMMENDED }: Argon2Options) {
TimeoutHandler.cancelReloadingTimeout(params.memoryExponent);

const s2k = new Argon2S2K({ ...defaultConfig, s2kArgon2Params: params });
s2k.salt = salt;
return s2k.produceKey(password, params.tagLength);
const result = await s2k.produceKey(password, params.tagLength);

TimeoutHandler.setupReloadingTimeout(params.memoryExponent);
return result;
}
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@openpgp/tweetnacl": "^1.0.3",
"@openpgp/web-stream-tools": "^0.0.13",
"jsmimeparser": "npm:@protontech/jsmimeparser@^3.0.1",
"openpgp": "npm:@protontech/openpgp@~5.11.1-0"
"openpgp": "npm:@protontech/openpgp@~5.11.2-0"
},
"devDependencies": {
"@types/bn.js": "^5.1.1",
Expand Down

0 comments on commit 3520bb5

Please sign in to comment.