//! SPDX-License-Identifier: GPL-3.0-or-later AND ISC
/**
-* Implementation derived from blake2b@2.1.4. Copyright 2017 Emil Bay
-* <github@tixz.dk> (https://github.com/emilbayes/blake2b). See LICENSES/ISC.txt
-*
-* Modified to use BigUint64 values, eliminate dependencies, port to TypeScript,
-* and embed in web workers.
-*
-* Original source commit: https://github.com/emilbayes/blake2b/blob/1f63e02e3f226642959506cdaa67c8819ff145cd/index.js
-*/
+ * Implementation derived from blake2b@2.1.4. Copyright 2017 Emil Bay
+ * <github@tixz.dk> (https://github.com/emilbayes/blake2b). See LICENSES/ISC.txt
+ *
+ * Modified to use BigUint64 values, eliminate dependencies, port to TypeScript,
+ * and embed in web workers.
+ *
+ * Original source commit: https://github.com/emilbayes/blake2b/blob/1f63e02e3f226642959506cdaa67c8819ff145cd/index.js
+ */
export class Blake2b {
/**
- * Derives account private keys from a wallet seed using the BLAKE2b hashing
- * algorithm.
- *
- * Separately, account public keys are derived from the private key using the
- * Ed25519 key algorithm, and account addresses are derived from the public key
- * as described in the Nano documentation.
- * https://docs.nano.org/integration-guides/the-basics/
- *
- * @param {ArrayBuffer} seed - 32-byte secret seed of the wallet
- * @param {number} index - 4-byte index of account to derive
- * @returns {Promise<ArrayBuffer>} Private key for the account
- */
+ * Derives account private keys from a wallet seed using the BLAKE2b hashing
+ * algorithm.
+ *
+ * Separately, account public keys are derived from the private key using the
+ * Ed25519 key algorithm, and account addresses are derived from the public key
+ * as described in the Nano documentation.
+ * https://docs.nano.org/integration-guides/the-basics/
+ *
+ * @param {ArrayBuffer} seed - 32-byte secret seed of the wallet
+ * @param {number} index - 4-byte index of account to derive
+ * @returns {Promise<ArrayBuffer>} Private key for the account
+ */
static ckd (seed: ArrayBuffer, index: number): Promise<ArrayBuffer> {
const b = new ArrayBuffer(4)
new DataView(b).setUint32(0, index, false)
}
/**
- * Compression function called during three phases: on keying (if applicable),
- * each time the input buffer is filled, and when finalizing message block.
- *
- * @param {boolean} final - If true, invert bits of v[14]
- */
+ * Compression function called during three phases: on keying (if applicable),
+ * each time the input buffer is filled, and when finalizing message block.
+ *
+ * @param {boolean} final - If true, invert bits of v[14]
+ */
#blake2bCompress (final: boolean): void {
// init work variables
}
// lo 64 bits of counter
- this.#v[12] ^= this.#t & ((1n << 64n) - 1n)
+ this.#v[12] ^= this.#t & 0xffffffffffffffffn
// hi 64 bits of counter
- this.#v[13] ^= this.#t & ((1n << 128n) - (1n << 64n))
+ this.#v[13] ^= this.#t & 0xffffffffffffffff0000000000000000n
// is last block flag set?
if (final) {
}
/**
- * Update the BLAKE2b streaming hash with additional input. When the 128-byte
- * input buffer is full, compress and start refilling.
- */
+ * Update the BLAKE2b streaming hash with additional input. When the 128-byte
+ * input buffer is full, compress and start refilling.
+ */
#blake2bUpdate (input: Uint8Array): void {
for (let i = 0; i < input.length; i++) {
if (this.#c === this.#b.byteLength) { // is buffer full?
}
/**
- * Completes a BLAKE2b streaming hash.
- *
- * @param {Uint8Array} out - Buffer to store the final output
- */
+ * Completes a BLAKE2b streaming hash.
+ *
+ * @param {Uint8Array} out - Buffer to store the final output
+ */
#blake2bFinal (out: Uint8Array<ArrayBuffer>): void {
this.#t += BigInt(this.#c) // add final message block size to total bytes
this.#b.fill(0, this.#c) // pad final block with zeros
#outlen: number
/**
- * Creates a BLAKE2b hashing context.
- *
- * @param {number} length - Output length between 1-64 bytes
- * @param {Uint8Array} [key] - (_optional_) Used for keyed hashing (MAC and PRF)
- * @param {Uint8Array} [salt] - (_optional_) Used to simplify randomized hashing for digital signatures
- * @param {Uint8Array} [personal] - (_optional_) Arbitrary user-specified value
- */
+ * Creates a BLAKE2b hashing context.
+ *
+ * @param {number} length - Output length between 1-64 bytes
+ * @param {Uint8Array} [key] - (_optional_) Used for keyed hashing (MAC and PRF)
+ * @param {Uint8Array} [salt] - (_optional_) Used to simplify randomized hashing for digital signatures
+ * @param {Uint8Array} [personal] - (_optional_) Arbitrary user-specified value
+ */
constructor (length: number, key?: Uint8Array<ArrayBuffer>, salt?: Uint8Array<ArrayBuffer>, personal?: Uint8Array<ArrayBuffer>)
constructor (length: unknown, key?: unknown, salt?: unknown, personal?: unknown) {
const B = this.constructor as typeof Blake2b
}
}
+ /**
+ * Adds bytes to the context of the streaming hash.
+ *
+ * @param {(ArrayBuffer|Uint8Array)} input - Bytes to hash
+ * @returns {Blake2b}
+ */
update (input: ArrayBuffer | Uint8Array): Blake2b {
if (input instanceof ArrayBuffer) {
input = new Uint8Array(input)
return this
}
+ /**
+ * Finalizes the streaming hash with one last compression and truncates the
+ * output to the requested byte length.
+ *
+ * @returns {Uint8Array<ArrayBuffer>}
+ */
digest (): Uint8Array<ArrayBuffer> {
const buf = new Uint8Array(this.#outlen)
- if (buf.length < this.#outlen) throw new RangeError('out must have at least outlen bytes of space')
this.#blake2bFinal(buf)
return buf
}