@noble/hashes
Advanced tools
Comparing version 0.5.1 to 0.5.2
@@ -1,4 +0,4 @@ | ||
export declare function scrypt(password: string, salt: string): Promise<Uint8Array>; | ||
export declare function pbkdf2(password: string, salt: string): Promise<Uint8Array>; | ||
export declare function deriveMainSeed(username: string, password: string): Promise<Uint8Array>; | ||
export declare function scrypt(password: string, salt: string): Uint8Array; | ||
export declare function pbkdf2(password: string, salt: string): Uint8Array; | ||
export declare function deriveMainSeed(username: string, password: string): Uint8Array; | ||
export declare function deriveChildKey(seed: Uint8Array, protocol: string, accountId?: number | string, keyLength?: number): Uint8Array; | ||
@@ -5,0 +5,0 @@ declare type ESKDF = Promise<Readonly<{ |
28
eskdf.js
@@ -27,3 +27,3 @@ "use strict"; | ||
function scrypt(password, salt) { | ||
return (0, scrypt_js_1.scryptAsync)((0, utils_js_1.toBytes)(password), (0, utils_js_1.toBytes)(salt), { N: SCRYPT_FACTOR, r: 8, p: 1, dkLen: 32 }); | ||
return (0, scrypt_js_1.scrypt)(password, salt, { N: SCRYPT_FACTOR, r: 8, p: 1, dkLen: 32 }); | ||
} | ||
@@ -33,3 +33,3 @@ exports.scrypt = scrypt; | ||
function pbkdf2(password, salt) { | ||
return (0, pbkdf2_js_1.pbkdf2Async)(sha256_js_1.sha256, (0, utils_js_1.toBytes)(password), (0, utils_js_1.toBytes)(salt), { c: PBKDF2_FACTOR, dkLen: 32 }); | ||
return (0, pbkdf2_js_1.pbkdf2)(sha256_js_1.sha256, password, salt, { c: PBKDF2_FACTOR, dkLen: 32 }); | ||
} | ||
@@ -49,10 +49,9 @@ exports.pbkdf2 = pbkdf2; | ||
// username and password must have enough entropy. | ||
async function deriveMainSeed(username, password) { | ||
if (!strHasLength(username, 1, 255)) | ||
function deriveMainSeed(username, password) { | ||
if (!strHasLength(username, 8, 255)) | ||
throw new Error('invalid username'); | ||
if (!strHasLength(password, 1, 255)) | ||
if (!strHasLength(password, 8, 255)) | ||
throw new Error('invalid password'); | ||
const scrp = scrypt(password + '\u{1}', username + '\u{1}'); | ||
const pbkp = pbkdf2(password + '\u{2}', username + '\u{2}'); | ||
const [scr, pbk] = await Promise.all([scrp, pbkp]); | ||
const scr = scrypt(password + '\u{1}', username + '\u{1}'); | ||
const pbk = pbkdf2(password + '\u{2}', username + '\u{2}'); | ||
const res = xor32(scr, pbk); | ||
@@ -72,7 +71,5 @@ scr.fill(0); | ||
// We do an additional length check here to reduce the scope of DoS attacks | ||
if (!strHasLength(protocol, 3, 15)) | ||
if (!(strHasLength(protocol, 3, 15) && /^[a-z0-9]{3,15}$/.test(protocol))) { | ||
throw new Error('invalid protocol'); | ||
protocol = protocol.toLowerCase(); // Normalize to lower case. | ||
if (!/^[a-z0-9]{3,15}$/.test(protocol)) | ||
throw new Error('invalid protocol'); | ||
} | ||
const allowsStr = PROTOCOLS_ALLOWING_STR.includes(protocol); | ||
@@ -87,9 +84,8 @@ let salt; // Extract salt. Default is undefined. | ||
} | ||
else if (typeof accountId === 'number') { | ||
else if (Number.isSafeInteger(accountId)) { | ||
if (accountId < 0 || accountId > 2 ** 32 - 1) | ||
throw new Error('invalid accountId'); | ||
// Convert to Big Endian Uint32 | ||
const view = new DataView(new ArrayBuffer(4)); | ||
view.setUint32(0, accountId, false); | ||
salt = new Uint8Array(view.buffer); | ||
salt = new Uint8Array(4); | ||
(0, utils_js_1.createView)(salt).setUint32(0, accountId, false); | ||
} | ||
@@ -96,0 +92,0 @@ else { |
import { hkdf } from './hkdf.js'; | ||
import { sha256 } from './sha256.js'; | ||
import { pbkdf2Async } from './pbkdf2.js'; | ||
import { scryptAsync } from './scrypt.js'; | ||
import { toBytes } from './utils.js'; | ||
import { pbkdf2 as _pbkdf2 } from './pbkdf2.js'; | ||
import { scrypt as _scrypt } from './scrypt.js'; | ||
import { createView, toBytes } from './utils.js'; | ||
// A tiny KDF for various applications like AES key-gen | ||
@@ -24,7 +24,7 @@ // | ||
export function scrypt(password, salt) { | ||
return scryptAsync(toBytes(password), toBytes(salt), { N: SCRYPT_FACTOR, r: 8, p: 1, dkLen: 32 }); | ||
return _scrypt(password, salt, { N: SCRYPT_FACTOR, r: 8, p: 1, dkLen: 32 }); | ||
} | ||
// PBKDF2-HMAC-SHA256 | ||
export function pbkdf2(password, salt) { | ||
return pbkdf2Async(sha256, toBytes(password), toBytes(salt), { c: PBKDF2_FACTOR, dkLen: 32 }); | ||
return _pbkdf2(sha256, password, salt, { c: PBKDF2_FACTOR, dkLen: 32 }); | ||
} | ||
@@ -43,10 +43,9 @@ // Combines two 32-byte byte arrays | ||
// username and password must have enough entropy. | ||
export async function deriveMainSeed(username, password) { | ||
if (!strHasLength(username, 1, 255)) | ||
export function deriveMainSeed(username, password) { | ||
if (!strHasLength(username, 8, 255)) | ||
throw new Error('invalid username'); | ||
if (!strHasLength(password, 1, 255)) | ||
if (!strHasLength(password, 8, 255)) | ||
throw new Error('invalid password'); | ||
const scrp = scrypt(password + '\u{1}', username + '\u{1}'); | ||
const pbkp = pbkdf2(password + '\u{2}', username + '\u{2}'); | ||
const [scr, pbk] = await Promise.all([scrp, pbkp]); | ||
const scr = scrypt(password + '\u{1}', username + '\u{1}'); | ||
const pbk = pbkdf2(password + '\u{2}', username + '\u{2}'); | ||
const res = xor32(scr, pbk); | ||
@@ -65,7 +64,5 @@ scr.fill(0); | ||
// We do an additional length check here to reduce the scope of DoS attacks | ||
if (!strHasLength(protocol, 3, 15)) | ||
if (!(strHasLength(protocol, 3, 15) && /^[a-z0-9]{3,15}$/.test(protocol))) { | ||
throw new Error('invalid protocol'); | ||
protocol = protocol.toLowerCase(); // Normalize to lower case. | ||
if (!/^[a-z0-9]{3,15}$/.test(protocol)) | ||
throw new Error('invalid protocol'); | ||
} | ||
const allowsStr = PROTOCOLS_ALLOWING_STR.includes(protocol); | ||
@@ -80,9 +77,8 @@ let salt; // Extract salt. Default is undefined. | ||
} | ||
else if (typeof accountId === 'number') { | ||
else if (Number.isSafeInteger(accountId)) { | ||
if (accountId < 0 || accountId > 2 ** 32 - 1) | ||
throw new Error('invalid accountId'); | ||
// Convert to Big Endian Uint32 | ||
const view = new DataView(new ArrayBuffer(4)); | ||
view.setUint32(0, accountId, false); | ||
salt = new Uint8Array(view.buffer); | ||
salt = new Uint8Array(4); | ||
createView(salt).setUint32(0, accountId, false); | ||
} | ||
@@ -89,0 +85,0 @@ else { |
@@ -70,2 +70,9 @@ /*! noble-hashes - MIT License (c) 2021 Paul Miller (paulmillr.com) */ | ||
} | ||
export function assertBytes(bytes, ...lengths) { | ||
if (bytes instanceof Uint8Array && | ||
(!lengths.length || lengths.includes(bytes.length))) { | ||
return; | ||
} | ||
throw new TypeError(`Expected ${lengths} bytes, not ${typeof bytes} with length=${bytes.length}`); | ||
} | ||
export function assertHash(hash) { | ||
@@ -72,0 +79,0 @@ if (typeof hash !== 'function' || typeof hash.init !== 'function') |
{ | ||
"name": "@noble/hashes", | ||
"version": "0.5.1", | ||
"version": "0.5.2", | ||
"description": "Fast 0-dependency JS implementation of SHA2, SHA3, RIPEMD, BLAKE2/3, HMAC, HKDF, PBKDF2, Scrypt", | ||
@@ -5,0 +5,0 @@ "directories": { |
@@ -12,2 +12,2 @@ import { Input } from './utils.js'; | ||
export declare function scrypt(password: Input, salt: Input, _opts: ScryptOpts): Uint8Array; | ||
export declare function scryptAsync(password: Uint8Array, salt: Uint8Array, _opts: ScryptOpts): Promise<Uint8Array>; | ||
export declare function scryptAsync(password: Input, salt: Input, _opts: ScryptOpts): Promise<Uint8Array>; |
@@ -15,2 +15,3 @@ /*! noble-hashes - MIT License (c) 2021 Paul Miller (paulmillr.com) */ | ||
export declare function assertBool(b: boolean): void; | ||
export declare function assertBytes(bytes: Uint8Array, ...lengths: number[]): void; | ||
export declare function assertHash(hash: CHash): void; | ||
@@ -17,0 +18,0 @@ export declare abstract class Hash<T extends Hash<T>> { |
10
utils.js
"use strict"; | ||
/*! noble-hashes - MIT License (c) 2021 Paul Miller (paulmillr.com) */ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.randomBytes = exports.wrapConstructorWithOpts = exports.wrapConstructor = exports.checkOpts = exports.Hash = exports.assertHash = exports.assertBool = exports.assertNumber = exports.toBytes = exports.asyncLoop = exports.nextTick = exports.bytesToHex = exports.isLE = exports.rotr = exports.createView = exports.u32 = exports.u8 = void 0; | ||
exports.randomBytes = exports.wrapConstructorWithOpts = exports.wrapConstructor = exports.checkOpts = exports.Hash = exports.assertHash = exports.assertBytes = exports.assertBool = exports.assertNumber = exports.toBytes = exports.asyncLoop = exports.nextTick = exports.bytesToHex = exports.isLE = exports.rotr = exports.createView = exports.u32 = exports.u8 = void 0; | ||
// The import here is via the package name. This is to ensure | ||
@@ -82,2 +82,10 @@ // that exports mapping/resolution does fall into place. | ||
exports.assertBool = assertBool; | ||
function assertBytes(bytes, ...lengths) { | ||
if (bytes instanceof Uint8Array && | ||
(!lengths.length || lengths.includes(bytes.length))) { | ||
return; | ||
} | ||
throw new TypeError(`Expected ${lengths} bytes, not ${typeof bytes} with length=${bytes.length}`); | ||
} | ||
exports.assertBytes = assertBytes; | ||
function assertHash(hash) { | ||
@@ -84,0 +92,0 @@ if (typeof hash !== 'function' || typeof hash.init !== 'function') |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
256667
5685
0