UNPKG

react-native-quick-crypto

Version:

A fast implementation of Node's `crypto` module written in C/C++ JSI

88 lines (85 loc) 4.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.argon2 = argon2; exports.argon2Sync = argon2Sync; var _reactNativeBuffer = require("@craftzdog/react-native-buffer"); var _reactNativeNitroModules = require("react-native-nitro-modules"); var _utils = require("./utils"); let native; function getNative() { if (native == null) { native = _reactNativeNitroModules.NitroModules.createHybridObject('Argon2'); } return native; } const ARGON2_VERSION = 0x13; // v1.3 // RFC 9106 § 3.1: Argon2 input/parameter constraints. // p (parallelism) 1 ≤ p ≤ 2^24 - 1 // T (tag length) 4 ≤ T ≤ 2^32 - 1 // m (memory in KiB) 8*p ≤ m ≤ 2^32 - 1 // t (passes) 1 ≤ t ≤ 2^32 - 1 // |salt| (nonce) 8 ≤ |s| ≤ 2^32 - 1 // v (version) 0x10 (v1.0) or 0x13 (v1.3) const ARGON2_MAX_U24 = 0xff_ffff; const ARGON2_MAX_U32 = 0xffff_ffff; function isUInt(value, max) { return typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value) && value >= 0 && value <= max; } function validateAlgorithm(algorithm) { if (algorithm !== 'argon2d' && algorithm !== 'argon2i' && algorithm !== 'argon2id') { throw new TypeError(`Unknown argon2 algorithm: ${algorithm}`); } } // Returns the resolved nonce ArrayBuffer so the caller can pass it // straight to native without re-resolving `params.nonce`. function validateArgon2Params(params, version) { if (!isUInt(params.parallelism, ARGON2_MAX_U24) || params.parallelism < 1) { throw new RangeError(`Invalid Argon2 parallelism: ${params.parallelism} ` + `(RFC 9106: 1 ≤ p ≤ 2^24 - 1)`); } if (!isUInt(params.tagLength, ARGON2_MAX_U32) || params.tagLength < 4) { throw new RangeError(`Invalid Argon2 tagLength: ${params.tagLength} ` + `(RFC 9106: 4 ≤ T ≤ 2^32 - 1)`); } const minMemory = 8 * params.parallelism; if (!isUInt(params.memory, ARGON2_MAX_U32) || params.memory < minMemory) { throw new RangeError(`Invalid Argon2 memory: ${params.memory} KiB ` + `(RFC 9106: 8 * p (= ${minMemory}) ≤ m ≤ 2^32 - 1)`); } if (!isUInt(params.passes, ARGON2_MAX_U32) || params.passes < 1) { throw new RangeError(`Invalid Argon2 passes: ${params.passes} ` + `(RFC 9106: 1 ≤ t ≤ 2^32 - 1)`); } if (version !== 0x10 && version !== 0x13) { throw new RangeError(`Invalid Argon2 version: 0x${version.toString(16)} ` + `(RFC 9106: 0x10 or 0x13)`); } // Salt (nonce) must be 8..2^32 - 1 bytes — measured against the resolved // ArrayBuffer because BinaryLike accepts strings whose UTF-8 length is // what actually reaches OpenSSL. const nonceAB = (0, _utils.binaryLikeToArrayBuffer)(params.nonce); if (nonceAB.byteLength < 8 || nonceAB.byteLength > ARGON2_MAX_U32) { throw new RangeError(`Invalid Argon2 nonce length: ${nonceAB.byteLength} bytes ` + `(RFC 9106: 8 ≤ |s| ≤ 2^32 - 1)`); } return nonceAB; } function toAB(value) { return (0, _utils.binaryLikeToArrayBuffer)(value); } function argon2Sync(algorithm, params) { validateAlgorithm(algorithm); const version = params.version ?? ARGON2_VERSION; const nonceAB = validateArgon2Params(params, version); const result = getNative().hashSync(algorithm, toAB(params.message), nonceAB, params.parallelism, params.tagLength, params.memory, params.passes, version, params.secret ? toAB(params.secret) : undefined, params.associatedData ? toAB(params.associatedData) : undefined); return _reactNativeBuffer.Buffer.from(result); } function argon2(algorithm, params, callback) { validateAlgorithm(algorithm); const version = params.version ?? ARGON2_VERSION; let nonceAB; try { nonceAB = validateArgon2Params(params, version); } catch (err) { callback(err, _reactNativeBuffer.Buffer.alloc(0)); return; } getNative().hash(algorithm, toAB(params.message), nonceAB, params.parallelism, params.tagLength, params.memory, params.passes, version, params.secret ? toAB(params.secret) : undefined, params.associatedData ? toAB(params.associatedData) : undefined).then(ab => callback(null, _reactNativeBuffer.Buffer.from(ab))).catch(err => callback(err, _reactNativeBuffer.Buffer.alloc(0))); } //# sourceMappingURL=argon2.js.map