Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

argon2

Package Overview
Dependencies
Maintainers
1
Versions
78
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

argon2 - npm Package Compare versions

Comparing version 0.15.0 to 0.16.0

5

argon2/README.md

@@ -57,3 +57,3 @@ # Argon2

```
Usage: ./argon2 [-h] salt [-i|-d|-id] [-t iterations] [-m memory] [-p parallelism] [-l hash length] [-e|-r] [-v (10|13)]
Usage: ./argon2 [-h] salt [-i|-d|-id] [-t iterations] [-m memory] [-p parallelism] [-l hash length] [-e|-r]
Password is read from stdin

@@ -71,3 +71,2 @@ Parameters:

-r Output only the raw bytes of the hash
-v (10|13) Argon2 version (defaults to the most recent version, currently 13)
-h Print argon2 usage

@@ -267,3 +266,3 @@ ```

## Test suite
## Test Suite

@@ -270,0 +269,0 @@ There are two sets of test suites. One is a low level test for the hash

3

index.d.ts

@@ -32,4 +32,3 @@ // Type definitions for argon2 v0.14.0

export const limits: OptionLimits;
export function hash(plain: Buffer | string, salt: Buffer, options?: Options): Promise<string>;
export function generateSalt(length?: number): Promise<Buffer>;
export function hash(plain: Buffer | string, options?: Options): Promise<string>;
export function verify(hash: string, plain: Buffer | string): Promise<boolean>;

@@ -21,19 +21,2 @@ 'use strict'

const validate = (salt, options) => new Promise((resolve, reject) => {
if (salt.length < 8) {
reject(new Error('Invalid salt, must be a buffer with 8 or more bytes.'))
}
for (let key of Object.keys(limits)) {
const max = limits[key].max
const min = limits[key].min
const value = options[key]
if (value > max || value < min) {
reject(new Error(`Invalid ${key}, must be between ${min} and ${max}.`))
}
}
resolve()
})
module.exports = {

@@ -46,19 +29,20 @@ defaults,

hash(plain, salt, options) {
salt = new Buffer(salt)
hash (plain, options) {
options = Object.assign({}, defaults, options)
return validate(salt, options).then(() => new Promise((resolve, reject) => {
bindings.hash(new Buffer(plain), salt, options, resolve, reject)
}))
},
return new Promise((resolve, reject) => {
for (let key of Object.keys(limits)) {
const max = limits[key].max
const min = limits[key].min
const value = options[key]
if (value > max || value < min) {
reject(new Error(`Invalid ${key}, must be between ${min} and ${max}.`))
}
}
generateSalt(length) {
return new Promise((resolve, reject) => {
crypto.randomBytes(length || 16, (err, salt) => {
/* istanbul ignore if */
crypto.randomBytes(16, (err, salt) => {
if (err) {
reject(err)
}
resolve(salt)
bindings.hash(Buffer.from(plain), salt, options, resolve, reject)
})

@@ -68,3 +52,3 @@ })

verify(hash, plain) {
verify (hash, plain) {
if (!/^\$argon2(i|d|id)(\$v=\d+)?\$m=\d+,t=\d+,p=\d+(?:\$[\w+/]+){2}$/.test(hash)) {

@@ -75,5 +59,5 @@ return Promise.reject(new Error('Invalid hash, must be in MCF, generated by Argon2.'))

return new Promise((resolve, reject) => {
bindings.verify(new Buffer(hash), new Buffer(plain), resolve, reject)
bindings.verify(Buffer.from(hash), Buffer.from(plain), resolve, reject)
})
}
}
{
"name": "argon2",
"version": "0.15.0",
"version": "0.16.0",
"description": "An Argon2 library for Node",

@@ -8,5 +8,5 @@ "main": "index.js",

"scripts": {
"benchmark": "babel-node benchmark.js",
"benchmark": "node benchmark.js",
"clean": "node-gyp clean",
"test": "tsc -p . && node test-d.js && xo && nyc --reporter=lcov ava"
"test": "tsc -p . && node test-d.js && standard && nyc --reporter=lcov ava"
},

@@ -36,13 +36,10 @@ "repository": {

"devDependencies": {
"@types/node": "^6.0.42",
"ava": "^0.17.0",
"babel-cli": "^6.18.0",
"@types/node": "^7.0.5",
"ava": "^0.19.1",
"babel-plugin-transform-async-to-generator": "^6.16.0",
"babel-preset-es2015": "^6.18.0",
"babel-register": "^6.18.0",
"nyc": "^10.0.0",
"object-assign": "^4.1.0",
"sandra": "^0.1.0",
"typescript": "^2.0.3",
"xo": "^0.17.1"
"mockery": "^2.0.0",
"nyc": "^11.0.1",
"sandra": "^0.2.1",
"standard": "^10.0.2",
"typescript": "^2.1.5"
},

@@ -56,16 +53,4 @@ "engines": {

],
"babel": "inherit",
"require": [
"babel-register"
]
},
"xo": {
"esnext": true,
"rules": {
"no-div-regex": "off",
"prefer-const": "off"
},
"semicolon": false,
"space": 2
"babel": "inherit"
}
}
# node-argon2
[![Greenkeeper badge](https://badges.greenkeeper.io/ranisalt/node-argon2.svg)](https://greenkeeper.io/)
[![NPM package][npm-image]][npm-url] [![Coverage status][coverage-image]][coverage-url] [![Code Quality][codequality-image]][codequality-url] [![Dependencies][david-dm-image]][david-dm-url] [![Codewake][codewake-image]][codewake-url]

@@ -3,0 +5,0 @@ - Linux: [![Linux build status][travis-image]][travis-url]

@@ -1,23 +0,40 @@

import test from 'ava'
import argon2, {defaults, limits} from './'
'use strict'
const test = require('ava')
const mockery = require('mockery')
let argon2, defaults, limits
const password = 'password'
const salt = new Buffer('somesalt')
const saltWithNull = new Buffer('\0abcdefghijklmno')
// Like argon2's modified base64 implementation, this function truncates any
// trailing '=' characters for a more compact representation.
const truncatedBase64 = buffer => buffer.toString('base64').replace(/=*$/, '')
// 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',
argon2id: '$argon2id$v=19$m=4096,t=3,p=1$c29tZXNhbHQ$qLml5cbqFAO6YxVHhrSBHP0UWdxrIxkNcM8aMX3blzU',
withNull: '$argon2i$v=19$m=4096,t=3,p=1$c29tZXNhbHQ$gk27gZBfGSSQTGxrg0xP9BjOw1pY1QMEdLcNe+t6N8Q',
raw: Buffer.from('iWh06vD8Fy27wf9npn6FXWiCX4K6pW6Ue1Bnzz07Z8A', 'base64'),
rawWithNull: Buffer.from('gk27gZBfGSSQTGxrg0xP9BjOw1pY1QMEdLcNe+t6N8Q', 'base64'),
rawArgon2d: Buffer.from('2+JCoQtY/2x5F0VB9pEVP3xBNguWP1T25Ui0PtZuk8o', 'base64')
argon2i: '$argon2i$v=19$m=4096,t=3,p=1$c2FsdHNhbHRzYWx0c2FsdA$Iv3dSMJ431p24TEj68Kxokm/ilAC9HfwREDIVPM/1/0',
withNull: '$argon2i$v=19$m=4096,t=3,p=1$c2FsdHNhbHRzYWx0c2FsdA$Z3fEValT7xBg6b585WOlY2gufWl95ZfkFA8mPtWJ3UM',
argon2d: '$argon2d$v=19$m=4096,t=3,p=1$c2FsdHNhbHRzYWx0c2FsdA$3CYaDoobFaprD02HTMVVRLsrSgJjZK5QmqYWnWDEAlw',
argon2id: '$argon2id$v=19$m=4096,t=3,p=1$c2FsdHNhbHRzYWx0c2FsdA$fxbFVdPGPQ1NJoy87CaTabyrXOKZepZ9SGBFwPkPJ28',
rawArgon2i: Buffer.from('22fddd48c278df5a76e13123ebc2b1a249bf8a5002f477f04440c854f33fd7fd', 'hex'),
rawWithNull: Buffer.from('6777c455a953ef1060e9be7ce563a563682e7d697de597e4140f263ed589dd43', 'hex'),
rawArgon2d: Buffer.from('dc261a0e8a1b15aa6b0f4d874cc55544bb2b4a026364ae509aa6169d60c4025c', 'hex'),
rawArgon2id: Buffer.from('7f16c555d3c63d0d4d268cbcec269369bcab5ce2997a967d486045c0f90f276f', 'hex')
})
mockery.registerMock('crypto', {
randomBytes (size, callback) {
callback(null, Buffer.alloc(size, 'salt'))
}
})
test.before(() => {
mockery.enable({useCleanCache: true, warnOnUnregistered: false})
argon2 = require('./')
defaults = argon2.defaults
limits = argon2.limits
})
test.after(() => {
mockery.disable()
})
test('defaults', t => {

@@ -35,56 +52,43 @@ t.deepEqual(defaults, {

test('basic hash', async t => {
t.is(await argon2.hash(password, salt), hashes.argon2i)
t.is(await argon2.hash(password), hashes.argon2i)
})
test('hash with null in password', async t => {
t.is(await argon2.hash('pass\0word', salt), hashes.withNull)
t.is(await argon2.hash('pass\0word'), hashes.withNull)
})
test('hash with null in salt', async t => {
const hash = await argon2.hash(password, saltWithNull)
const paramsLen = '$argon2i$v=19$m=4096,t=3,p=1$'.length
t.is(hash.substring(paramsLen, paramsLen + 22), truncatedBase64(saltWithNull))
})
test('with raw hash', async t => {
t.is((await argon2.hash(password, salt, {raw: true})).equals(hashes.raw), true)
t.is((await argon2.hash(password, {raw: true})).equals(hashes.rawArgon2i), true)
})
test('with raw hash, null in password', async t => {
t.is((await argon2.hash('pass\0word', salt, {raw: true})).equals(hashes.rawWithNull), true)
t.is((await argon2.hash('pass\0word', {raw: true})).equals(hashes.rawWithNull), true)
})
test('hash with longer salt', async t => {
/* Intentionally using a length that is not multiple of 3 */
const hash = await argon2.hash('password', await argon2.generateSalt(500))
t.regex(hash, /.*\$.{667}\$/)
t.true(await argon2.verify(hash, 'password'))
})
test('hash with argon2d', async t => {
t.is(await argon2.hash(password, salt, {type: argon2.argon2d}), hashes.argon2d)
t.is(await argon2.hash(password, {type: argon2.argon2d}), hashes.argon2d)
})
test('argon2d with raw hash', async t => {
t.is((await argon2.hash(password, salt, {type: argon2.argon2d, raw: true})).equals(hashes.rawArgon2d), true)
t.is((await argon2.hash(password, {type: argon2.argon2d, raw: true})).equals(hashes.rawArgon2d), true)
})
test('hash with argon2id', async t => {
t.is(await argon2.hash(password, salt, {type: argon2.argon2id}), hashes.argon2id)
t.is(await argon2.hash(password, {type: argon2.argon2id}), hashes.argon2id)
})
test('hash with short salt', async t => {
t.throws(argon2.hash(password, salt.slice(0, 7)), /invalid salt.+with 8 or more bytes/i)
test('argon2id with raw hash', async t => {
t.is((await argon2.hash(password, {type: argon2.argon2id, raw: true})).equals(hashes.rawArgon2id), true)
})
test('hash with time cost', async t => {
t.regex(await argon2.hash(password, salt, {timeCost: 4}), /t=4/)
t.regex(await argon2.hash(password, {timeCost: 4}), /t=4/)
})
test('hash with low time cost', async t => {
t.throws(argon2.hash(password, salt, {timeCost: limits.timeCost.min - 1}), /invalid timeCost.+between \d+ and \d+/i)
await t.throws(argon2.hash(password, {timeCost: limits.timeCost.min - 1}), /invalid timeCost.+between \d+ and \d+/i)
})
test('hash with high time cost', async t => {
t.throws(argon2.hash(password, salt, {timeCost: limits.timeCost.max + 1}), /invalid timeCost.+between \d+ and \d+/i)
await t.throws(argon2.hash(password, {timeCost: limits.timeCost.max + 1}), /invalid timeCost.+between \d+ and \d+/i)
})

@@ -94,81 +98,73 @@

// 4 bytes ascii == 6 bytes base64
t.regex(await argon2.hash(password, salt, {hashLength: 4}), /\$\w{6}$/)
t.regex(await argon2.hash(password, {hashLength: 4}), /\$\w{6}$/)
})
test('hash with low hash length', async t => {
t.throws(argon2.hash(password, salt, {hashLength: limits.hashLength.min - 1}), /invalid hashLength.+between \d+ and \d+/i)
await t.throws(argon2.hash(password, {hashLength: limits.hashLength.min - 1}), /invalid hashLength.+between \d+ and \d+/i)
})
test('hash with high hash length', async t => {
t.throws(argon2.hash(password, salt, {hashLength: limits.hashLength.max + 1}), /invalid hashLength.+between \d+ and \d+/i)
await t.throws(argon2.hash(password, {hashLength: limits.hashLength.max + 1}), /invalid hashLength.+between \d+ and \d+/i)
})
test('hash with memory cost', async t => {
t.regex(await argon2.hash(password, salt, {memoryCost: 13}), /m=8192/)
t.regex(await argon2.hash(password, {memoryCost: 13}), /m=8192/)
})
test('hash with low memory cost', async t => {
t.throws(argon2.hash(password, salt, {memoryCost: limits.memoryCost.min - 1}), /invalid memoryCost.+between \d+ and \d+/i)
await t.throws(argon2.hash(password, {memoryCost: limits.memoryCost.min - 1}), /invalid memoryCost.+between \d+ and \d+/i)
})
test('hash with high memory cost', async t => {
t.throws(argon2.hash(password, salt, {memoryCost: limits.memoryCost.max + 1}), /invalid memoryCost.+between \d+ and \d+/i)
await t.throws(argon2.hash(password, {memoryCost: limits.memoryCost.max + 1}), /invalid memoryCost.+between \d+ and \d+/i)
})
test('hash with parallelism', async t => {
t.regex(await argon2.hash(password, salt, {parallelism: 2}), /p=2/)
t.regex(await argon2.hash(password, {parallelism: 2}), /p=2/)
})
test('hash with low parallelism', async t => {
t.throws(argon2.hash(password, salt, {parallelism: limits.parallelism.min - 1}), /invalid parallelism.+between \d+ and \d+/i)
await t.throws(argon2.hash(password, {parallelism: limits.parallelism.min - 1}), /invalid parallelism.+between \d+ and \d+/i)
})
test('hash with high parallelism', async t => {
t.throws(argon2.hash(password, salt, {parallelism: limits.parallelism.max + 1}), /invalid parallelism.+between \d+ and \d+/i)
await t.throws(argon2.hash(password, {parallelism: limits.parallelism.max + 1}), /invalid parallelism.+between \d+ and \d+/i)
})
test('hash with all options', async t => {
t.regex(await argon2.hash(password, salt, {timeCost: 4, memoryCost: 13, parallelism: 2}), /m=8192,t=4,p=2/)
t.regex(await argon2.hash(password, {timeCost: 4, memoryCost: 13, parallelism: 2}), /m=8192,t=4,p=2/)
})
test('async generate salt with default length', async t => {
t.is((await argon2.generateSalt()).length, 16)
})
test('async generate salt with specified length', async t => {
t.is((await argon2.generateSalt(32)).length, 32)
})
test('verify correct password', async t => {
t.true(await argon2.verify(await argon2.hash(password, await argon2.generateSalt()), password))
t.true(await argon2.verify(await argon2.hash(password), password))
})
test('verify wrong password', async t => {
t.false(await argon2.verify(await argon2.hash(password, await argon2.generateSalt()), 'passworld'))
t.false(await argon2.verify(await argon2.hash(password), 'passworld'))
})
test('verify invalid hash', async t => {
const hash = await argon2.hash(password, await argon2.generateSalt())
const hash = await argon2.hash(password)
/* Cut just a piece of the hash making it invalid */
t.throws(argon2.verify(hash.slice(8), password), /invalid hash.+generated by argon2/i)
await t.throws(argon2.verify(hash.slice(8), password), /invalid hash.+generated by argon2/i)
})
test('verify with null in password', async t => {
t.true(await argon2.verify(await argon2.hash('pass\0word', await argon2.generateSalt()), 'pass\0word'))
t.true(await argon2.verify(await argon2.hash('pass\0word'), 'pass\0word'))
})
test('verify argon2d correct password', async t => {
t.true(await argon2.verify(await argon2.hash(password, await argon2.generateSalt(), {type: argon2.argon2d}), password))
t.true(await argon2.verify(await argon2.hash(password, {type: argon2.argon2d}), password))
})
test('verify argon2d wrong password', async t => {
t.false(await argon2.verify(await argon2.hash(password, await argon2.generateSalt(), {type: argon2.argon2d}), 'passworld'))
t.false(await argon2.verify(await argon2.hash(password, {type: argon2.argon2d}), 'passworld'))
})
test('verify argon2id correct password', async t => {
t.true(await argon2.verify(await argon2.hash(password, await argon2.generateSalt(), {type: argon2.argon2id}), password))
t.true(await argon2.verify(await argon2.hash(password, {type: argon2.argon2id}), password))
})
test('verify argon2id wrong password', async t => {
t.false(await argon2.verify(await argon2.hash(password, await argon2.generateSalt(), {type: argon2.argon2id}), 'passworld'))
t.false(await argon2.verify(await argon2.hash(password, {type: argon2.argon2id}), 'passworld'))
})

@@ -182,4 +178,5 @@

await argon2.hash(password, salt)
await argon2.hash(password)
clearInterval(timer)
t.pass()
})

@@ -193,4 +190,5 @@

await argon2.hash(password, salt)
await argon2.hash(password)
clearTimeout(timer)
t.pass()
})

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc