Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | 1x 345x 345x 344x 344x 8x 7x 6x 336x 80x 79x 78x 78x 77x 76x 256x 15x 14x 13x 241x 16x 15x 14x 14x 13x 12x 12x 11x 10x 225x 224x 223x 222x 222x 221x 220x 220x 219x 218x 1x 323x 1x | /** * @file Key Derivation Function (KDF) Setup * @copyright Multifactor 2022 All Rights Reserved * * @description * Validate and setup a KDF configuration for a multi-factor derived key * * @author Vivek Nair (https://nair.me) <[email protected]> */ const defaults = require('../defaults') /** * Validate and setup a KDF configuration for a multi-factor derived key * * @example * // setup kdf configuration * const config = await mfkdf.setup.kdf({ * kdf: 'pbkdf2', * pbkdf2rounds: 100000, * pbkdf2digest: 'sha256' * }); // -> { type: 'pbkdf2', params: { rounds: 100000, digest: 'sha256' } } * * // derive key * const key = await mfkdf.kdf('password', 'salt', 8, config); * key.toString('hex') // -> 0394a2ede332c9a1 * * @param {Object} [options] - KDF configuration options * @param {string} [options.kdf='argon2id'] - KDF algorithm to use; hkdf, pbkdf2, bcrypt, scrypt, argon2i, argon2d, or argon2id * @param {string} [options.hkdfdigest='sha256'] - Hash function to use if using hkdf; sha1, sha256, sha384, or sha512 * @param {number} [options.pbkdf2rounds=310000] - Number of rounds to use if using pbkdf2 * @param {string} [options.pbkdf2digest='sha256'] - Hash function to use if using pbkdf2; sha1, sha256, sha384, or sha512 * @param {number} [options.bcryptrounds=10] - Number of rounds to use if using bcrypt * @param {number} [options.scryptcost=16384] - Iterations count (N) to use if using scrypt * @param {number} [options.scryptblocksize=8] - Block size (r) to use if using scrypt * @param {number} [options.scryptparallelism=1] - Parallelism factor (p) to use if using scrypt * @param {number} [options.argon2time=2] - Iterations to use if using argon2 * @param {number} [options.argon2mem=24576] - Memory to use if using argon2 * @param {number} [options.argon2parallelism=1] - Parallelism to use if using argon2 * @returns {object} A KDF configuration as a JSON object * @author Vivek Nair (https://nair.me) <[email protected]> * @since 0.7.0 * @memberOf setup */ function kdf (options) { options = Object.assign(Object.assign({}, defaults.kdf), options) if (typeof options.kdf !== 'string') throw new TypeError('kdf must be a string') const config = { type: options.kdf, params: {} } if (options.kdf === 'hkdf') { // hdkf digest if (typeof options.hkdfdigest !== 'string') throw new TypeError('hkdfdigest must be a string') if (!['sha1', 'sha256', 'sha384', 'sha512'].includes(options.hkdfdigest)) throw new RangeError('hkdfdigest must be one of sha1, sha256, sha384, or sha512') config.params.digest = options.hkdfdigest } else if (options.kdf === 'pbkdf2') { // pbkdf2 rounds if (!(Number.isInteger(options.pbkdf2rounds))) throw new TypeError('pbkdf2rounds must be an integer') if (!(options.pbkdf2rounds > 0)) throw new RangeError('pbkdf2rounds must be positive') config.params.rounds = options.pbkdf2rounds // pbkdf2 digest if (typeof options.pbkdf2digest !== 'string') throw new TypeError('pbkdf2digest must be a string') if (!['sha1', 'sha256', 'sha384', 'sha512'].includes(options.pbkdf2digest)) throw new RangeError('pbkdf2digest must be one of sha1, sha256, sha384, or sha512') config.params.digest = options.pbkdf2digest } else if (options.kdf === 'bcrypt') { // bcrypt rounds if (!(Number.isInteger(options.bcryptrounds))) throw new TypeError('bcryptrounds must be an integer') if (!(options.bcryptrounds > 0)) throw new RangeError('bcryptrounds must be positive') config.params.rounds = options.bcryptrounds } else if (options.kdf === 'scrypt') { // scrypt rounds if (!(Number.isInteger(options.scryptcost))) throw new TypeError('scryptcost must be a positive integer') if (!(options.scryptcost > 0)) throw new RangeError('scryptcost must be positive') config.params.rounds = options.scryptcost // scrypt block size if (!(Number.isInteger(options.scryptblocksize))) throw new TypeError('scryptblocksize must be an integer') if (!(options.scryptblocksize > 0)) throw new RangeError('scryptblocksize must be positive') config.params.blocksize = options.scryptblocksize // scrypt parallelism if (!(Number.isInteger(options.scryptparallelism))) throw new TypeError('scryptparallelism must be an integer') if (!(options.scryptparallelism > 0)) throw new RangeError('scryptparallelism must be positive') config.params.parallelism = options.scryptparallelism } else if (options.kdf === 'argon2i' || options.kdf === 'argon2d' || options.kdf === 'argon2id') { // argon2 rounds if (!(Number.isInteger(options.argon2time))) throw new TypeError('argon2time must be an integer') if (!(options.argon2time > 0)) throw new RangeError('argon2time must be positive') config.params.rounds = options.argon2time // argon2 memory if (!(Number.isInteger(options.argon2mem))) throw new TypeError('argon2mem must be an integer') if (!(options.argon2mem > 0)) throw new RangeError('argon2mem must be positive') config.params.memory = options.argon2mem // argon2 parallelism if (!(Number.isInteger(options.argon2parallelism))) throw new TypeError('argon2parallelism must be an integer') if (!(options.argon2parallelism > 0)) throw new RangeError('argon2parallelism must be positive') config.params.parallelism = options.argon2parallelism } else { throw new RangeError('kdf must be one of pbkdf2, bcrypt, scrypt, argon2i, argon2d, or argon2id') } return config } module.exports.kdf = kdf |