add crypto_pwhash api
This commit is contained in:
parent
64089d1fca
commit
4465a532c4
264
crypto_pwhash.js
Normal file
264
crypto_pwhash.js
Normal file
@ -0,0 +1,264 @@
|
||||
/* eslint-disable camelcase */
|
||||
const b4a = require('b4a')
|
||||
const argon2 = require('../../wasm/argon2-wasm')
|
||||
const { randombytes_buf } = require('./randombytes')
|
||||
|
||||
const crypto_pwhash_argon2i_ALG_ARGON2I13 = 1
|
||||
const crypto_pwhash_argon2i_BYTES_MIN = 16
|
||||
const crypto_pwhash_argon2i_BYTES_MAX = 4294967295
|
||||
const crypto_pwhash_argon2i_PASSWD_MIN = 0
|
||||
const crypto_pwhash_argon2i_PASSWD_MAX = 4294967295
|
||||
const crypto_pwhash_argon2i_SALTBYTES = 16
|
||||
const crypto_pwhash_argon2i_STRBYTES = 128
|
||||
const crypto_pwhash_argon2i_STRPREFIX = '$argon2i$'
|
||||
const crypto_pwhash_argon2i_OPSLIMIT_MIN = 3
|
||||
const crypto_pwhash_argon2i_OPSLIMIT_MAX = 4294967295
|
||||
const crypto_pwhash_argon2i_MEMLIMIT_MIN = 8192
|
||||
const crypto_pwhash_argon2i_MEMLIMIT_MAX = 2147483648
|
||||
const crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE = 4
|
||||
const crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE = 33554432
|
||||
const crypto_pwhash_argon2i_OPSLIMIT_MODERATE = 6
|
||||
const crypto_pwhash_argon2i_MEMLIMIT_MODERATE = 134217728
|
||||
const crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE = 8
|
||||
const crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE = 536870912
|
||||
|
||||
const crypto_pwhash_argon2id_ALG_ARGON2ID13 = 2
|
||||
const crypto_pwhash_argon2id_BYTES_MIN = 16
|
||||
const crypto_pwhash_argon2id_BYTES_MAX = 4294967295
|
||||
const crypto_pwhash_argon2id_PASSWD_MIN = 0
|
||||
const crypto_pwhash_argon2id_PASSWD_MAX = 4294967295
|
||||
const crypto_pwhash_argon2id_SALTBYTES = 16
|
||||
const crypto_pwhash_argon2id_STRBYTES = 128
|
||||
const crypto_pwhash_argon2id_STRPREFIX = '$argon2id$'
|
||||
const crypto_pwhash_argon2id_OPSLIMIT_MIN = 1
|
||||
const crypto_pwhash_argon2id_OPSLIMIT_MAX = 4294967295
|
||||
const crypto_pwhash_argon2id_MEMLIMIT_MIN = 8192
|
||||
const crypto_pwhash_argon2id_MEMLIMIT_MAX = 2147483648
|
||||
const crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE = 2
|
||||
const crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE = 67108864
|
||||
const crypto_pwhash_argon2id_OPSLIMIT_MODERATE = 3
|
||||
const crypto_pwhash_argon2id_MEMLIMIT_MODERATE = 268435456
|
||||
const crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE = 4
|
||||
const crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE = 1073741824
|
||||
|
||||
const crypto_pwhash_ALG_ARGON2I13 = crypto_pwhash_argon2i_ALG_ARGON2I13
|
||||
const crypto_pwhash_ALG_ARGON2ID13 = crypto_pwhash_argon2id_ALG_ARGON2ID13
|
||||
const crypto_pwhash_ALG_DEFAULT = crypto_pwhash_ALG_ARGON2ID13
|
||||
const crypto_pwhash_BYTES_MIN = crypto_pwhash_argon2id_BYTES_MIN
|
||||
const crypto_pwhash_BYTES_MAX = crypto_pwhash_argon2id_BYTES_MAX
|
||||
const crypto_pwhash_PASSWD_MIN = crypto_pwhash_argon2id_PASSWD_MIN
|
||||
const crypto_pwhash_PASSWD_MAX = crypto_pwhash_argon2id_PASSWD_MAX
|
||||
const crypto_pwhash_SALTBYTES = crypto_pwhash_argon2id_SALTBYTES
|
||||
const crypto_pwhash_STRBYTES = crypto_pwhash_argon2id_STRBYTES
|
||||
const crypto_pwhash_STRPREFIX = crypto_pwhash_argon2id_STRPREFIX
|
||||
const crypto_pwhash_OPSLIMIT_MIN = crypto_pwhash_argon2id_OPSLIMIT_MIN
|
||||
const crypto_pwhash_OPSLIMIT_MAX = crypto_pwhash_argon2id_OPSLIMIT_MAX
|
||||
const crypto_pwhash_MEMLIMIT_MIN = crypto_pwhash_argon2id_MEMLIMIT_MIN
|
||||
const crypto_pwhash_MEMLIMIT_MAX = crypto_pwhash_argon2id_MEMLIMIT_MAX
|
||||
const crypto_pwhash_OPSLIMIT_INTERACTIVE = crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE
|
||||
const crypto_pwhash_MEMLIMIT_INTERACTIVE = crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE
|
||||
const crypto_pwhash_OPSLIMIT_MODERATE = crypto_pwhash_argon2id_OPSLIMIT_MODERATE
|
||||
const crypto_pwhash_MEMLIMIT_MODERATE = crypto_pwhash_argon2id_MEMLIMIT_MODERATE
|
||||
const crypto_pwhash_OPSLIMIT_SENSITIVE = crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE
|
||||
const crypto_pwhash_MEMLIMIT_SENSITIVE = crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE
|
||||
|
||||
module.exports = {
|
||||
crypto_pwhash_ALG_ARGON2I13,
|
||||
crypto_pwhash_ALG_ARGON2ID13,
|
||||
crypto_pwhash_ALG_DEFAULT,
|
||||
crypto_pwhash_BYTES_MIN,
|
||||
crypto_pwhash_BYTES_MAX,
|
||||
crypto_pwhash_PASSWD_MIN,
|
||||
crypto_pwhash_PASSWD_MAX,
|
||||
crypto_pwhash_SALTBYTES,
|
||||
crypto_pwhash_STRBYTES,
|
||||
crypto_pwhash_STRPREFIX,
|
||||
crypto_pwhash_OPSLIMIT_MIN,
|
||||
crypto_pwhash_OPSLIMIT_MAX,
|
||||
crypto_pwhash_MEMLIMIT_MIN,
|
||||
crypto_pwhash_MEMLIMIT_MAX,
|
||||
crypto_pwhash_OPSLIMIT_INTERACTIVE,
|
||||
crypto_pwhash_MEMLIMIT_INTERACTIVE,
|
||||
crypto_pwhash_OPSLIMIT_MODERATE,
|
||||
crypto_pwhash_MEMLIMIT_MODERATE,
|
||||
crypto_pwhash_OPSLIMIT_SENSITIVE,
|
||||
crypto_pwhash_MEMLIMIT_SENSITIVE,
|
||||
crypto_pwhash_argon2i,
|
||||
crypto_pwhash_argon2id,
|
||||
crypto_pwhash_argon2i_str,
|
||||
crypto_pwhash_argon2id_str,
|
||||
crypto_pwhash,
|
||||
crypto_pwhash_str,
|
||||
crypto_pwhash_str_verify,
|
||||
crypto_pwhash_str_needs_rehash
|
||||
}
|
||||
|
||||
function crypto_pwhash_argon2i (out, passwd, salt, passes, memory, alg) {
|
||||
const outlen = out.byteLength
|
||||
const passwdlen = passwd.byteLength
|
||||
out.fill(0)
|
||||
|
||||
if (outlen > crypto_pwhash_argon2i_BYTES_MAX) {
|
||||
throw new Error('Too large')
|
||||
}
|
||||
|
||||
if (outlen < crypto_pwhash_argon2i_BYTES_MIN) {
|
||||
throw new Error('Invalid opts')
|
||||
}
|
||||
|
||||
if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX ||
|
||||
passes > crypto_pwhash_argon2i_OPSLIMIT_MAX ||
|
||||
memory > crypto_pwhash_argon2i_MEMLIMIT_MAX) {
|
||||
throw new Error('Too large')
|
||||
}
|
||||
|
||||
if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN ||
|
||||
(passes && passes < crypto_pwhash_argon2i_OPSLIMIT_MIN) ||
|
||||
(memory && memory < crypto_pwhash_argon2i_MEMLIMIT_MIN)) {
|
||||
throw new Error('Invalid opts')
|
||||
}
|
||||
|
||||
switch (alg) {
|
||||
case crypto_pwhash_argon2i_ALG_ARGON2I13: {
|
||||
const buf = argon2(passwd, salt, null, null, 'binary', { memory: memory >> 10, passes, outlen, type: argon2.ARGON2I })
|
||||
out.set(buf)
|
||||
return 0
|
||||
}
|
||||
|
||||
default:
|
||||
throw new Error('Invalid input')
|
||||
}
|
||||
}
|
||||
|
||||
function crypto_pwhash_argon2id (out, passwd, salt, passes, memory, alg) {
|
||||
const outlen = out.byteLength
|
||||
const passwdlen = passwd.byteLength
|
||||
out.fill(0)
|
||||
|
||||
if (outlen > crypto_pwhash_argon2id_BYTES_MAX) {
|
||||
throw new Error('Too large')
|
||||
}
|
||||
|
||||
if (outlen < crypto_pwhash_argon2id_BYTES_MIN) {
|
||||
throw new Error('Invalid opts')
|
||||
}
|
||||
|
||||
if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX ||
|
||||
passes > crypto_pwhash_argon2id_OPSLIMIT_MAX ||
|
||||
memory > crypto_pwhash_argon2id_MEMLIMIT_MAX) {
|
||||
throw new Error('Too large')
|
||||
}
|
||||
|
||||
if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN ||
|
||||
(passes && passes < crypto_pwhash_argon2id_OPSLIMIT_MIN) ||
|
||||
(memory && memory < crypto_pwhash_argon2id_MEMLIMIT_MIN)) {
|
||||
throw new Error('Invalid opts')
|
||||
}
|
||||
|
||||
switch (alg) {
|
||||
case crypto_pwhash_argon2id_ALG_ARGON2ID13: {
|
||||
const buf = argon2(passwd, salt, null, null, 'binary', { memory: memory >> 10, passes, outlen, type: argon2.ARGON2ID })
|
||||
out.set(buf)
|
||||
return 0
|
||||
}
|
||||
|
||||
default:
|
||||
throw new Error('Invalid input')
|
||||
}
|
||||
}
|
||||
|
||||
function crypto_pwhash_argon2i_str (out, passwd, salt, passes, memory, alg) {
|
||||
const outlen = 32
|
||||
const passwdlen = passwd.byteLength
|
||||
|
||||
if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX ||
|
||||
passes > crypto_pwhash_argon2i_OPSLIMIT_MAX ||
|
||||
memory > crypto_pwhash_argon2i_MEMLIMIT_MAX) {
|
||||
throw new Error('Too large')
|
||||
}
|
||||
|
||||
if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN ||
|
||||
(passes && passes < crypto_pwhash_argon2i_OPSLIMIT_MIN) ||
|
||||
(memory && memory < crypto_pwhash_argon2i_MEMLIMIT_MIN)) {
|
||||
throw new Error('Invalid opts')
|
||||
}
|
||||
|
||||
switch (alg) {
|
||||
case crypto_pwhash_argon2i_ALG_ARGON2I13:
|
||||
return argon2(passwd, salt, null, null, { memory: memory >> 10, passes, outlen, type: argon2.ARGON2I })
|
||||
|
||||
default:
|
||||
throw new Error('Invalid input')
|
||||
}
|
||||
}
|
||||
|
||||
function crypto_pwhash_argon2id_str (out, passwd, salt, passes, memory, alg) {
|
||||
const outlen = 32
|
||||
const passwdlen = passwd.byteLength
|
||||
|
||||
if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX ||
|
||||
passes > crypto_pwhash_argon2id_OPSLIMIT_MAX ||
|
||||
memory > crypto_pwhash_argon2id_MEMLIMIT_MAX) {
|
||||
throw new Error('Too large')
|
||||
}
|
||||
|
||||
if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN ||
|
||||
(passes && passes < crypto_pwhash_argon2id_OPSLIMIT_MIN) ||
|
||||
(memory && memory < crypto_pwhash_argon2id_MEMLIMIT_MIN)) {
|
||||
throw new Error('Invalid opts')
|
||||
}
|
||||
|
||||
switch (alg) {
|
||||
case crypto_pwhash_argon2id_ALG_ARGON2ID13:
|
||||
out.write(argon2(passwd, salt, null, null, { memory: memory >> 10, passes, outlen, type: argon2.ARGON2ID }))
|
||||
return
|
||||
|
||||
default:
|
||||
throw new Error('Invalid input')
|
||||
}
|
||||
}
|
||||
|
||||
function crypto_pwhash (out, passwd, salt, opslimit, memlimit, alg) {
|
||||
switch (alg) {
|
||||
case crypto_pwhash_argon2i_ALG_ARGON2I13:
|
||||
return crypto_pwhash_argon2i(out, passwd, salt, opslimit, memlimit, alg)
|
||||
|
||||
case crypto_pwhash_argon2id_ALG_ARGON2ID13:
|
||||
return crypto_pwhash_argon2id(out, passwd, salt, opslimit, memlimit, alg)
|
||||
}
|
||||
}
|
||||
|
||||
function crypto_pwhash_str (out, passwd, opslimit, memlimit) {
|
||||
const salt = b4a.alloc(crypto_pwhash_SALTBYTES)
|
||||
randombytes_buf(salt)
|
||||
|
||||
return crypto_pwhash_argon2id_str(out, passwd, salt, opslimit, memlimit, crypto_pwhash_ALG_DEFAULT)
|
||||
}
|
||||
|
||||
function crypto_pwhash_str_verify (str, passwd) {
|
||||
if (b4a.isBuffer(str)) return crypto_pwhash_str_verify(str.toString(), passwd)
|
||||
|
||||
if (str.slice(0, crypto_pwhash_argon2id_STRPREFIX.length) === crypto_pwhash_argon2id_STRPREFIX) {
|
||||
return argon2.verify(str, passwd, null)
|
||||
}
|
||||
|
||||
if (str.slice(0, crypto_pwhash_argon2i_STRPREFIX.length) === crypto_pwhash_argon2i_STRPREFIX) {
|
||||
return argon2.verify(str, passwd, null)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
function crypto_pwhash_str_needs_rehash (str, opslimit, memlimit, type) {
|
||||
memlimit >>= 10
|
||||
|
||||
if ((opslimit | memlimit) > 0xffffffff || (str.byteLength > crypto_pwhash_STRBYTES)) {
|
||||
throw new Error('Invalid opts.')
|
||||
}
|
||||
|
||||
try {
|
||||
return argon2.needsRehash(str, opslimit, memlimit, type)
|
||||
} catch {
|
||||
return true
|
||||
}
|
||||
}
|
3
index.js
3
index.js
@ -12,6 +12,7 @@ forward(require('./randombytes'))
|
||||
forward(require('./memory'))
|
||||
forward(require('./helpers'))
|
||||
forward(require('./utils'))
|
||||
forward(require('./crypto_aead'))
|
||||
forward(require('./crypto_auth'))
|
||||
forward(require('./crypto_box'))
|
||||
forward(require('./crypto_core'))
|
||||
@ -21,7 +22,7 @@ forward(require('./crypto_hash'))
|
||||
forward(require('./crypto_hash_sha256'))
|
||||
forward(require('./crypto_kdf'))
|
||||
forward(require('./crypto_kx'))
|
||||
forward(require('./crypto_aead'))
|
||||
forward(require('./crypto_pwhash'))
|
||||
forward(require('./crypto_onetimeauth'))
|
||||
forward(require('./crypto_scalarmult_ed25519'))
|
||||
// forward(require('./crypto_scalarmult'))
|
||||
|
@ -4,6 +4,7 @@
|
||||
"description": "WIP - a pure javascript version of sodium-native",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"argon2-wasm": "^0.9.0",
|
||||
"blake2b": "^2.1.1",
|
||||
"chacha20-universal": "^1.0.4",
|
||||
"nanoassert": "^2.0.0",
|
||||
|
Loading…
Reference in New Issue
Block a user