Skip to content

Commit

Permalink
Replace standard with prettier, format files
Browse files Browse the repository at this point in the history
  • Loading branch information
ranisalt committed Feb 2, 2022
1 parent c4a2e15 commit 34cff1b
Show file tree
Hide file tree
Showing 7 changed files with 444 additions and 1,515 deletions.
50 changes: 30 additions & 20 deletions argon2.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,29 @@
/// <reference types="node" />

export interface Options {
hashLength?: number;
timeCost?: number;
memoryCost?: number;
parallelism?: number;
type?: 0 | 1 | 2;
version?: number;
salt?: Buffer;
saltLength?: number;
raw?: boolean;
secret?: Buffer;
associatedData?: Buffer;
hashLength?: number;
timeCost?: number;
memoryCost?: number;
parallelism?: number;
type?: 0 | 1 | 2;
version?: number;
salt?: Buffer;
saltLength?: number;
raw?: boolean;
secret?: Buffer;
associatedData?: Buffer;
}

export interface NumericLimit {
max: number;
min: number;
max: number;
min: number;
}

export interface OptionLimits {
hashLength: NumericLimit;
memoryCost: NumericLimit;
timeCost: NumericLimit;
parallelism: NumericLimit;
hashLength: NumericLimit;
memoryCost: NumericLimit;
timeCost: NumericLimit;
parallelism: NumericLimit;
}

export const argon2d: 0;
Expand All @@ -34,7 +34,17 @@ export const argon2id: 2;

export const defaults: Options;
export const limits: OptionLimits;
export function hash(plain: Buffer | string, options: Options & {raw: true}): Promise<Buffer>;
export function hash(plain: Buffer | string, options?: Options & {raw?: false}): Promise<string>;
export function verify(hash: string, plain: Buffer | string, options?: Options): Promise<boolean>;
export function hash(
plain: Buffer | string,
options: Options & { raw: true }
): Promise<Buffer>;
export function hash(
plain: Buffer | string,
options?: Options & { raw?: false }
): Promise<string>;
export function verify(
hash: string,
plain: Buffer | string,
options?: Options
): Promise<boolean>;
export function needsRehash(hash: string, options?: Options): boolean;
122 changes: 80 additions & 42 deletions argon2.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
'use strict'
const assert = require('assert')
const { randomBytes, timingSafeEqual } = require('crypto')
const { promisify } = require('util')
"use strict";
const assert = require("assert");
const { randomBytes, timingSafeEqual } = require("crypto");
const { promisify } = require("util");

const binary = require('@mapbox/node-pre-gyp')
const path = require('path')
const bindingPath = binary.find(path.resolve(path.join(__dirname, './package.json')))
const { hash: _hash, limits, types, names, version } = require(bindingPath) /* eslint-disable-line */
const binary = require("@mapbox/node-pre-gyp");
const path = require("path");
const bindingPath = binary.find(
path.resolve(path.join(__dirname, "./package.json"))
);
const {
hash: _hash,
limits,
types,
names,
version,
} = require(bindingPath); /* eslint-disable-line */

const { deserialize, serialize } = require('@phc/format')
const { deserialize, serialize } = require("@phc/format");

const defaults = Object.freeze({
hashLength: 32,
Expand All @@ -17,53 +25,83 @@ const defaults = Object.freeze({
memoryCost: 1 << 12,
parallelism: 1,
type: types.argon2i,
version
})
version,
});

const bindingsHash = promisify(_hash)
const generateSalt = promisify(randomBytes)
const bindingsHash = promisify(_hash);
const generateSalt = promisify(randomBytes);

const assertLimits = options => ([key, { max, min }]) => {
const value = options[key]
assert(min <= value && value <= max, `Invalid ${key}, must be between ${min} and ${max}.`)
}
const assertLimits =
(options) =>
([key, { max, min }]) => {
const value = options[key];
assert(
min <= value && value <= max,
`Invalid ${key}, must be between ${min} and ${max}.`
);
};

const hash = async (plain, { raw, salt, ...options } = {}) => {
options = { ...defaults, ...options }
options = { ...defaults, ...options };

Object.entries(limits).forEach(assertLimits(options))
Object.entries(limits).forEach(assertLimits(options));

salt = salt || await generateSalt(options.saltLength)
salt = salt || (await generateSalt(options.saltLength));

const hash = await bindingsHash(Buffer.from(plain), salt, options)
const hash = await bindingsHash(Buffer.from(plain), salt, options);
if (raw) {
return hash
return hash;
}

const { type, version, memoryCost: m, timeCost: t, parallelism: p, associatedData: data } = options
return serialize({ id: names[type], version, params: { m, t, p, ...(data ? { data } : {}) }, salt, hash })
}
const {
type,
version,
memoryCost: m,
timeCost: t,
parallelism: p,
associatedData: data,
} = options;
return serialize({
id: names[type],
version,
params: { m, t, p, ...(data ? { data } : {}) },
salt,
hash,
});
};

const needsRehash = (digest, options) => {
const { memoryCost, timeCost, version } = { ...defaults, ...options }
const { memoryCost, timeCost, version } = { ...defaults, ...options };

const { version: v, params: { m, t } } = deserialize(digest)
return +v !== +version || +m !== +memoryCost || +t !== +timeCost
}
const {
version: v,
params: { m, t },
} = deserialize(digest);
return +v !== +version || +m !== +memoryCost || +t !== +timeCost;
};

const verify = async (digest, plain, options) => {
const { id, version = 0x10, params: { m, t, p, data }, salt, hash } = deserialize(digest)
const {
id,
version = 0x10,
params: { m, t, p, data },
salt,
hash,
} = deserialize(digest);

return timingSafeEqual(await bindingsHash(Buffer.from(plain), salt, {
...options,
type: types[id],
version: +version,
hashLength: hash.length,
memoryCost: +m,
timeCost: +t,
parallelism: +p,
...(data ? { associatedData: Buffer.from(data, 'base64') } : {})
}), hash)
}
return timingSafeEqual(
await bindingsHash(Buffer.from(plain), salt, {
...options,
type: types[id],
version: +version,
hashLength: hash.length,
memoryCost: +m,
timeCost: +t,
parallelism: +p,
...(data ? { associatedData: Buffer.from(data, "base64") } : {}),
}),
hash
);
};

module.exports = { defaults, limits, hash, needsRehash, verify, ...types }
module.exports = { defaults, limits, hash, needsRehash, verify, ...types };
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"types": "argon2.d.ts",
"scripts": {
"install": "node-pre-gyp install --fallback-to-build",
"lint": "standard --verbose",
"format": "prettier --write \"**/*.{js,json,ts}\"",
"test": "nyc mocha test/test.js",
"test:ts": "tsc -p . && node test/test-d.js",
"postinstall": "opencollective-postinstall || true"
Expand Down Expand Up @@ -57,7 +57,7 @@
"mocha": "^9.2.0",
"node-gyp": "^8.4.1",
"nyc": "^15.1.0",
"standard": "^16.0.4",
"prettier": "^2.5.1",
"typescript": "^4.5.5"
},
"binary": {
Expand Down
80 changes: 41 additions & 39 deletions test/test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,65 +10,67 @@ const passwordBuffer = Buffer.from("password");

// hashes for argon2i and argon2d with default options
const hashes = Object.freeze({
argon2i: "$argon2i$v=19$m=4096,t=3,p=1$c29tZXNhbHQ$iWh06vD8Fy27wf9npn6FXWiCX4K6pW6Ue1Bnzz07Z8A",
argon2d: "$argon2d$v=19$m=4096,t=3,p=1$c29tZXNhbHQ$2+JCoQtY/2x5F0VB9pEVP3xBNguWP1T25Ui0PtZuk8o"
argon2i:
"$argon2i$v=19$m=4096,t=3,p=1$c29tZXNhbHQ$iWh06vD8Fy27wf9npn6FXWiCX4K6pW6Ue1Bnzz07Z8A",
argon2d:
"$argon2d$v=19$m=4096,t=3,p=1$c29tZXNhbHQ$2+JCoQtY/2x5F0VB9pEVP3xBNguWP1T25Ui0PtZuk8o",
});

function test_options() {
const defaults: argon2.Options = {
hashLength: 32,
timeCost: 3,
memoryCost: 1 << 12,
parallelism: 1,
type: argon2.argon2i,
raw: false
};
const defaults: argon2.Options = {
hashLength: 32,
timeCost: 3,
memoryCost: 1 << 12,
parallelism: 1,
type: argon2.argon2i,
raw: false,
};

console.log(argon2.defaults.hashLength === defaults.hashLength);
console.log(argon2.defaults.timeCost === defaults.timeCost);
console.log(argon2.defaults.memoryCost === defaults.memoryCost);
console.log(argon2.defaults.parallelism === defaults.parallelism);
console.log(argon2.defaults.type === defaults.type);
console.log(argon2.defaults.raw === defaults.raw);
console.log(argon2.defaults.hashLength === defaults.hashLength);
console.log(argon2.defaults.timeCost === defaults.timeCost);
console.log(argon2.defaults.memoryCost === defaults.memoryCost);
console.log(argon2.defaults.parallelism === defaults.parallelism);
console.log(argon2.defaults.type === defaults.type);
console.log(argon2.defaults.raw === defaults.raw);
}

function test_hash() {
return Promise.all([
argon2.hash(password), // String pw
argon2.hash(passwordBuffer) // Buffer pw
]);
return Promise.all([
argon2.hash(password), // String pw
argon2.hash(passwordBuffer), // Buffer pw
]);
}

function test_hashOptions() {
// All options separately, and together
return Promise.all([
argon2.hash(password, {type: argon2.argon2d}),
argon2.hash(password, {timeCost: 4}),
argon2.hash(password, {hashLength: 4}),
argon2.hash(password, {memoryCost: 1 << 13}),
argon2.hash(password, {parallelism: 2}),
argon2.hash(password, {salt: Buffer.from('1234567890abcdef')}),
argon2.hash(password, {associatedData: Buffer.from('associated data')}),
argon2.hash(password, {timeCost: 4, memoryCost: 1 << 13, parallelism: 2})
]);
// All options separately, and together
return Promise.all([
argon2.hash(password, { type: argon2.argon2d }),
argon2.hash(password, { timeCost: 4 }),
argon2.hash(password, { hashLength: 4 }),
argon2.hash(password, { memoryCost: 1 << 13 }),
argon2.hash(password, { parallelism: 2 }),
argon2.hash(password, { salt: Buffer.from("1234567890abcdef") }),
argon2.hash(password, { associatedData: Buffer.from("associated data") }),
argon2.hash(password, { timeCost: 4, memoryCost: 1 << 13, parallelism: 2 }),
]);
}

function test_verify() {
// Verify with string and buffer
return Promise.all([
argon2.verify(hashes.argon2d, password),
argon2.verify(hashes.argon2i, passwordBuffer)
]);
// Verify with string and buffer
return Promise.all([
argon2.verify(hashes.argon2d, password),
argon2.verify(hashes.argon2i, passwordBuffer),
]);
}

function test_raw(): Promise<Buffer> {
return argon2.hash(password, {raw: true});
return argon2.hash(password, { raw: true });
}

function test_string_1(): Promise<string> {
return argon2.hash(password);
return argon2.hash(password);
}

function test_string_2(): Promise<string> {
return argon2.hash(password, {raw: false});
return argon2.hash(password, { raw: false });
}
Loading

0 comments on commit 34cff1b

Please sign in to comment.