Comparing version 0.21.0 to 0.22.0
'use strict' | ||
const { ok } = require('assert').strict | ||
const { randomBytes, timingSafeEqual } = require('crypto') | ||
const { promisify } = require('util') | ||
const bindings = require('bindings')('argon2') | ||
const phc = require('@phc/format') | ||
const { hash: _hash, limits, types, names, version } = require('bindings')('argon2') | ||
const { deserialize, serialize } = require('@phc/format') | ||
const limits = Object.freeze(bindings.limits) | ||
const types = Object.freeze(bindings.types) | ||
const defaults = Object.freeze({ | ||
@@ -17,57 +15,50 @@ hashLength: 32, | ||
type: types.argon2i, | ||
version: bindings.version | ||
version | ||
}) | ||
const bindingsHash = promisify(bindings.hash) | ||
const bindingsHash = promisify(_hash) | ||
const generateSalt = promisify(randomBytes) | ||
const assertLimits = options => ([key, { max, min }]) => { | ||
const value = options[key] | ||
ok(min <= value && value <= max, `Invalid ${key}, must be between ${min} and ${max}.`) | ||
} | ||
const hash = async (plain, { raw, salt, ...options } = {}) => { | ||
options = { ...defaults, ...options } | ||
for (const [key, { max, min }] of Object.entries(limits)) { | ||
const value = options[key] | ||
if (value > max || value < min) { | ||
throw new Error(`Invalid ${key}, must be between ${min} and ${max}.`) | ||
} | ||
} | ||
Object.entries(limits).forEach(assertLimits(options)) | ||
salt = salt || await generateSalt(options.saltLength) | ||
const output = await bindingsHash(Buffer.from(plain), salt, options) | ||
const hash = await bindingsHash(Buffer.from(plain), salt, options) | ||
if (raw) { | ||
return output.hash | ||
return hash | ||
} | ||
return phc.serialize(output) | ||
const { type, version, memoryCost: m, timeCost: t, parallelism: p } = options | ||
return serialize({ id: names[type], version, params: { m, t, p }, salt, hash }) | ||
} | ||
const needsRehash = (digest, options) => { | ||
options = { ...defaults, ...options } | ||
const { memoryCost, timeCost, version } = { ...defaults, ...options } | ||
const { | ||
version, params: { m: memoryCost, t: timeCost } | ||
} = phc.deserialize(digest) | ||
return +version !== +options.version || | ||
+memoryCost !== +options.memoryCost || | ||
+timeCost !== +options.timeCost | ||
const { version: v, params: { m, t } } = deserialize(digest) | ||
return +v !== +version || +m !== +memoryCost || +t !== +timeCost | ||
} | ||
const verify = async (digest, plain) => { | ||
const { | ||
id: type, version = 0x10, params: { | ||
m: memoryCost, t: timeCost, p: parallelism | ||
}, salt, hash | ||
} = phc.deserialize(digest) | ||
const verify = async (digest, plain, options) => { | ||
const { id, version = 0x10, params: { m, t, p }, salt, hash } = deserialize(digest) | ||
const { hash: expected } = await bindingsHash(Buffer.from(plain), salt, { | ||
type: module.exports[type], | ||
return timingSafeEqual(await bindingsHash(Buffer.from(plain), salt, { | ||
...options, | ||
type: types[id], | ||
version: +version, | ||
hashLength: hash.length, | ||
memoryCost: +memoryCost, | ||
timeCost: +timeCost, | ||
parallelism: +parallelism | ||
}) | ||
return timingSafeEqual(expected, hash) | ||
memoryCost: +m, | ||
timeCost: +t, | ||
parallelism: +p | ||
}), hash) | ||
} | ||
module.exports = { defaults, limits, hash, needsRehash, verify, ...types } |
{ | ||
"name": "argon2", | ||
"version": "0.21.0", | ||
"version": "0.22.0", | ||
"description": "An Argon2 library for Node", | ||
@@ -11,4 +11,3 @@ "main": "argon2.js", | ||
"lint": "standard --verbose", | ||
"test": "mocha test/test.js", | ||
"test-ts": "tsc -p . && node test/test-d.js" | ||
"test": "nyc mocha test/test.js && tsc -p . && node test/test-d.js" | ||
}, | ||
@@ -34,10 +33,12 @@ "repository": { | ||
"@phc/format": "^0.5.0", | ||
"bindings": "^1.4.0", | ||
"node-addon-api": "^1.6.0" | ||
"bindings": "^1.5.0", | ||
"node-addon-api": "^1.6.3" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^11.9.4", | ||
"mocha": "^6.0.0", | ||
"@types/node": "^11.13.6", | ||
"mocha": "^6.1.4", | ||
"nyc": "^14.0.0", | ||
"sandra": "^0.3.2", | ||
"typescript": "^2.8.3" | ||
"standard": "^12.0.1", | ||
"typescript": "^3.4.4" | ||
}, | ||
@@ -48,4 +49,7 @@ "engines": { | ||
"standard": { | ||
"env": "mocha" | ||
"env": "mocha", | ||
"ignore": [ | ||
"test/test-d.js" | ||
] | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
const assert = require('assert') | ||
const assert = require('assert').strict | ||
const argon2 = require('../argon2') | ||
@@ -6,2 +6,3 @@ const { argon2i, argon2d, argon2id, defaults, limits } = argon2 | ||
const salt = Buffer.alloc(16, 'salt') | ||
const associatedData = Buffer.alloc(16, 'ad') | ||
@@ -12,2 +13,3 @@ // hashes for argon2i and argon2d with default options | ||
withNull: '$argon2i$v=19$m=4096,t=3,p=1$c2FsdHNhbHRzYWx0c2FsdA$Z3fEValT7xBg6b585WOlY2gufWl95ZfkFA8mPtWJ3UM', | ||
withAd: '$argon2i$v=19$m=4096,t=3,p=1$c2FsdHNhbHRzYWx0c2FsdA$1VVB4lnD1cmZaeQIlqyOMQ17g6H9rlC5S/vlYOWuD+M', | ||
argon2d: '$argon2d$v=19$m=4096,t=3,p=1$c2FsdHNhbHRzYWx0c2FsdA$3CYaDoobFaprD02HTMVVRLsrSgJjZK5QmqYWnWDEAlw', | ||
@@ -24,3 +26,3 @@ argon2id: '$argon2id$v=19$m=4096,t=3,p=1$c2FsdHNhbHRzYWx0c2FsdA$fxbFVdPGPQ1NJoy87CaTabyrXOKZepZ9SGBFwPkPJ28', | ||
it('defaults', () => { | ||
assert.deepStrictEqual({ | ||
assert.deepEqual({ | ||
hashLength: 32, | ||
@@ -39,3 +41,3 @@ saltLength: 16, | ||
const hash = await argon2.hash(password, { salt }) | ||
assert.strictEqual(hashes.argon2i, hash) | ||
assert.equal(hashes.argon2i, hash) | ||
}) | ||
@@ -50,3 +52,3 @@ | ||
const hash = await argon2.hash(password, { type: argon2d, salt }) | ||
assert.strictEqual(hashes.argon2d, hash) | ||
assert.equal(hashes.argon2d, hash) | ||
}) | ||
@@ -61,3 +63,3 @@ | ||
const hash = await argon2.hash(password, { type: argon2id, salt }) | ||
assert.strictEqual(hashes.argon2id, hash) | ||
assert.equal(hashes.argon2id, hash) | ||
}) | ||
@@ -72,3 +74,3 @@ | ||
const hash = await argon2.hash('pass\0word', { salt }) | ||
assert.strictEqual(hashes.withNull, hash) | ||
assert.equal(hashes.withNull, hash) | ||
}) | ||
@@ -80,2 +82,7 @@ | ||
}) | ||
it('with associated data', async () => { | ||
const hash = await argon2.hash(password, { associatedData, salt }) | ||
assert.equal(hashes.withAd, hash) | ||
}) | ||
}) | ||
@@ -214,2 +221,7 @@ | ||
it('verify with associated data', async () => { | ||
const hash = await argon2.hash(password, { associatedData }) | ||
assert(await argon2.verify(hash, 'password', { associatedData })) | ||
}) | ||
it('verify argon2d correct password', async () => { | ||
@@ -216,0 +228,0 @@ const hash = await argon2.hash(password, { type: argon2d }) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
199225
6
26
289
Updatedbindings@^1.5.0
Updatednode-addon-api@^1.6.3