Skip to content

Instantly share code, notes, and snippets.

@mryhryki
Last active August 21, 2025 02:40
Show Gist options
  • Save mryhryki/bc83940c0a6d3571b0179cece3ccd1b6 to your computer and use it in GitHub Desktop.
Save mryhryki/bc83940c0a6d3571b0179cece3ccd1b6 to your computer and use it in GitHub Desktop.
Argon2 Test on Docker

Argon2id Test on Node.js

Environment variables

CONFIG

  • OWASP_MIN (default)
  • RFC9106_SEC4_2

COUNT

Specify the number of parallel executions as an integer. The default is 1.

PARALLELISM

Specify the number of parallel executions as an integer. The default is 1.

How to run on Node.js

$ COUNT=1 PARALLELISM=1 CONFIG=OWASP_MIN npm start

How to run on Docker

Build image

$ npm run docker:build

Run

$ COUNT=1 PARALLELISM=1 CONFIG=OWASP_MIN npm run docker:run
node_modules
FROM node:22.17.0
WORKDIR /app
COPY ./package.json ./package-lock.json ./index.js ./
RUN npm ci
CMD ["npm", "start"]
const { hash, verify } = require('@node-rs/argon2');
const getCount = () => {
const COUNT = process.env.COUNT ?? '1';
const count = Number.parseInt(COUNT, 10);
if (Number.isNaN(count)) {
throw new Error('process.env.COUNT must be a number');
}
return count;
};
const getParallelism = () => {
const PARALLELISM = process.env.PARALLELISM ?? '1';
const parallelism = Number.parseInt(PARALLELISM, 10);
if (Number.isNaN(parallelism)) {
throw new Error('process.env.PARALLELISM must be a number');
}
return parallelism;
}
const getConfiguration = () => {
const CONFIG = process.env.CONFIG ?? 'default';
switch (CONFIG) {
case 'default':
case 'OWASP_MIN':
return {
memoryCost: 19456, // 19MiB
timeCost: 2, // 2 iterations
parallelism: 1, // 1 parallel threads
};
case 'RFC9106_SEC4_2':
return {
memoryCost: 65536, // 64MiB
timeCost: 3, // 3 iterations
parallelism: 4, // 4 parallel threads
}
default:
throw new Error(`Undefined configuration: ${CONFIG}`);
}
};
/** @return {() => number[]} Stop showing memory usage */
const showMemoryUsage = () => {
const memoryUsageList = [];
const show = () => {
const usage = process.memoryUsage();
memoryUsageList.push(usage.rss)
console.log(`[DEBUG] Memory RSS: ${Math.round(usage.rss / 1024 / 1024 * 100) / 100} MB`);
};
show();
const intervalId = setInterval(show, 100);
return () => {
show();
clearInterval(intervalId);
return memoryUsageList;
};
};
const main = async () => {
const stop = showMemoryUsage();
const count = getCount();
const parallelism = getParallelism();
const start = performance.now();
const durationHashList = [];
const durationVerifyList = [];
const ids = Array.from({ length: count }).map((_, i) => i);
for (let i = 0; i < count; i += parallelism) {
const targets = ids.slice(i, i + parallelism);
await Promise.all((targets).map(async (id) => {
const secret = crypto.randomUUID();
const startHash = performance.now();
const hashResult = await hash(secret, {
...getConfiguration(),
outputLen: 32, // 32 bytes output
algorithm: 2, // Argon2id
});
const durationHash = performance.now() - startHash;
durationHashList.push(durationHash);
console.log(`[INFO] hash#${id} [${durationHash.toString(10)
.substring(0, 10)
.padEnd(10, '0')}ms]: ${secret} => ${hashResult}`);
const startVerify = performance.now();
const verifyResult = await verify(hashResult, secret);
const durationVerify = performance.now() - startVerify;
durationVerifyList.push(durationVerify);
console.log(`[INFO] verify#${id} [${durationVerify.toString(10)
.substring(0, 10)
.padEnd(10, '0')}ms]: ${secret} => ${verifyResult}`);
}))
}
const memoryUsages = stop();
const duration = performance.now() - start;
console.log([
'',
'# Summary',
'',
`- Total time: ${duration}ms`,
`- Max memory used: ${Math.max(...memoryUsages) / 1024 / 1024} MiB`,
'',
'## Duration Hash',
'',
`- Average: ${durationHashList.reduce((total, ms) => total + ms, 0) / count}ms`,
`- Max : ${Math.max(...durationHashList)}ms`,
`- Min : ${Math.min(...durationHashList)}ms`,
'',
'## Duration Verify',
'',
`- Average: ${durationVerifyList.reduce((total, ms) => total + ms, 0) / count}ms`,
`- Max : ${Math.max(...durationVerifyList)}ms`,
`- Min : ${Math.min(...durationVerifyList)}ms`,
'',
].join('\n'));
};
main().catch((err) => {
console.error('Error:', err);
process.exit(1);
});
{
"name": "argon2-test",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "argon2-test",
"license": "MIT",
"dependencies": {
"@node-rs/argon2": "^2.0.2"
}
},
"node_modules/@emnapi/core": {
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz",
"integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==",
"license": "MIT",
"optional": true,
"dependencies": {
"@emnapi/wasi-threads": "1.0.4",
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/runtime": {
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz",
"integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==",
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/wasi-threads": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz",
"integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==",
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@napi-rs/wasm-runtime": {
"version": "0.2.12",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz",
"integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"@emnapi/core": "^1.4.3",
"@emnapi/runtime": "^1.4.3",
"@tybys/wasm-util": "^0.10.0"
}
},
"node_modules/@node-rs/argon2": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2/-/argon2-2.0.2.tgz",
"integrity": "sha512-t64wIsPEtNd4aUPuTAyeL2ubxATCBGmeluaKXEMAFk/8w6AJIVVkeLKMBpgLW6LU2t5cQxT+env/c6jxbtTQBg==",
"license": "MIT",
"engines": {
"node": ">= 10"
},
"optionalDependencies": {
"@node-rs/argon2-android-arm-eabi": "2.0.2",
"@node-rs/argon2-android-arm64": "2.0.2",
"@node-rs/argon2-darwin-arm64": "2.0.2",
"@node-rs/argon2-darwin-x64": "2.0.2",
"@node-rs/argon2-freebsd-x64": "2.0.2",
"@node-rs/argon2-linux-arm-gnueabihf": "2.0.2",
"@node-rs/argon2-linux-arm64-gnu": "2.0.2",
"@node-rs/argon2-linux-arm64-musl": "2.0.2",
"@node-rs/argon2-linux-x64-gnu": "2.0.2",
"@node-rs/argon2-linux-x64-musl": "2.0.2",
"@node-rs/argon2-wasm32-wasi": "2.0.2",
"@node-rs/argon2-win32-arm64-msvc": "2.0.2",
"@node-rs/argon2-win32-ia32-msvc": "2.0.2",
"@node-rs/argon2-win32-x64-msvc": "2.0.2"
}
},
"node_modules/@node-rs/argon2-android-arm-eabi": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm-eabi/-/argon2-android-arm-eabi-2.0.2.tgz",
"integrity": "sha512-DV/H8p/jt40lrao5z5g6nM9dPNPGEHL+aK6Iy/og+dbL503Uj0AHLqj1Hk9aVUSCNnsDdUEKp4TVMi0YakDYKw==",
"cpu": [
"arm"
],
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@node-rs/argon2-android-arm64": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm64/-/argon2-android-arm64-2.0.2.tgz",
"integrity": "sha512-1LKwskau+8O1ktKx7TbK7jx1oMOMt4YEXZOdSNIar1TQKxm6isZ0cRXgHLibPHEcNHgYRsJWDE9zvDGBB17QDg==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@node-rs/argon2-darwin-arm64": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-arm64/-/argon2-darwin-arm64-2.0.2.tgz",
"integrity": "sha512-3TTNL/7wbcpNju5YcqUrCgXnXUSbD7ogeAKatzBVHsbpjZQbNb1NDxDjqqrWoTt6XL3z9mJUMGwbAk7zQltHtA==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@node-rs/argon2-darwin-x64": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-x64/-/argon2-darwin-x64-2.0.2.tgz",
"integrity": "sha512-vNPfkLj5Ij5111UTiYuwgxMqE7DRbOS2y58O2DIySzSHbcnu+nipmRKg+P0doRq6eKIJStyBK8dQi5Ic8pFyDw==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@node-rs/argon2-freebsd-x64": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2-freebsd-x64/-/argon2-freebsd-x64-2.0.2.tgz",
"integrity": "sha512-M8vQZk01qojQfCqQU0/O1j1a4zPPrz93zc9fSINY7Q/6RhQRBCYwDw7ltDCZXg5JRGlSaeS8cUXWyhPGar3cGg==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@node-rs/argon2-linux-arm-gnueabihf": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm-gnueabihf/-/argon2-linux-arm-gnueabihf-2.0.2.tgz",
"integrity": "sha512-7EmmEPHLzcu0G2GDh30L6G48CH38roFC2dqlQJmtRCxs6no3tTE/pvgBGatTp/o2n2oyOJcfmgndVFcUpwMnww==",
"cpu": [
"arm"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@node-rs/argon2-linux-arm64-gnu": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-gnu/-/argon2-linux-arm64-gnu-2.0.2.tgz",
"integrity": "sha512-6lsYh3Ftbk+HAIZ7wNuRF4SZDtxtFTfK+HYFAQQyW7Ig3LHqasqwfUKRXVSV5tJ+xTnxjqgKzvZSUJCAyIfHew==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@node-rs/argon2-linux-arm64-musl": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-musl/-/argon2-linux-arm64-musl-2.0.2.tgz",
"integrity": "sha512-p3YqVMNT/4DNR67tIHTYGbedYmXxW9QlFmF39SkXyEbGQwpgSf6pH457/fyXBIYznTU/smnG9EH+C1uzT5j4hA==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@node-rs/argon2-linux-x64-gnu": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-gnu/-/argon2-linux-x64-gnu-2.0.2.tgz",
"integrity": "sha512-ZM3jrHuJ0dKOhvA80gKJqBpBRmTJTFSo2+xVZR+phQcbAKRlDMSZMFDiKbSTnctkfwNFtjgDdh5g1vaEV04AvA==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@node-rs/argon2-linux-x64-musl": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-musl/-/argon2-linux-x64-musl-2.0.2.tgz",
"integrity": "sha512-of5uPqk7oCRF/44a89YlWTEfjsftPywyTULwuFDKyD8QtVZoonrJR6ZWvfFE/6jBT68S0okAkAzzMEdBVWdxWw==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@node-rs/argon2-wasm32-wasi": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2-wasm32-wasi/-/argon2-wasm32-wasi-2.0.2.tgz",
"integrity": "sha512-U3PzLYKSQYzTERstgtHLd4ZTkOF9co57zTXT77r0cVUsleGZOrd6ut7rHzeWwoJSiHOVxxa0OhG1JVQeB7lLoQ==",
"cpu": [
"wasm32"
],
"license": "MIT",
"optional": true,
"dependencies": {
"@napi-rs/wasm-runtime": "^0.2.5"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@node-rs/argon2-win32-arm64-msvc": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-arm64-msvc/-/argon2-win32-arm64-msvc-2.0.2.tgz",
"integrity": "sha512-Eisd7/NM0m23ijrGr6xI2iMocdOuyl6gO27gfMfya4C5BODbUSP7ljKJ7LrA0teqZMdYHesRDzx36Js++/vhiQ==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@node-rs/argon2-win32-ia32-msvc": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-ia32-msvc/-/argon2-win32-ia32-msvc-2.0.2.tgz",
"integrity": "sha512-GsE2ezwAYwh72f9gIjbGTZOf4HxEksb5M2eCaj+Y5rGYVwAdt7C12Q2e9H5LRYxWcFvLH4m4jiSZpQQ4upnPAQ==",
"cpu": [
"ia32"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@node-rs/argon2-win32-x64-msvc": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-x64-msvc/-/argon2-win32-x64-msvc-2.0.2.tgz",
"integrity": "sha512-cJxWXanH4Ew9CfuZ4IAEiafpOBCe97bzoKowHCGk5lG/7kR4WF/eknnBlHW9m8q7t10mKq75kruPLtbSDqgRTw==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tybys/wasm-util": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz",
"integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD",
"optional": true
}
}
}
{
"name": "argon2-test",
"license": "MIT",
"author": "mryhryki",
"type": "commonjs",
"main": "index.js",
"scripts": {
"docker:build": "docker build . -t argon2-test:576657fc",
"docker:run": "docker run --rm -it --memory=512m --cpus=1 --env=CONFIG --env=COUNT --env=PARALLELISM argon2-test:576657fc",
"start": "node ./index.js"
},
"dependencies": {
"@node-rs/argon2": "^2.0.2"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment