]> git.codecow.com Git - libnemo.git/commitdiff
Use constants for masks instead of calculated values. Remove unnecessary range check...
authorChris Duncan <chris@codecow.com>
Mon, 29 Jun 2026 21:52:22 +0000 (14:52 -0700)
committerChris Duncan <chris@codecow.com>
Mon, 29 Jun 2026 21:52:22 +0000 (14:52 -0700)
src/lib/crypto/blake2b.ts

index c43370e489daed14981199865a4744a0470f8ff5..ae0e4b99136bd3ef48e186e3b82fc7ae6501b1a0 100644 (file)
@@ -2,28 +2,28 @@
 //! 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)
@@ -103,11 +103,11 @@ export class Blake2b {
        }
 
        /**
-       * 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
@@ -117,10 +117,10 @@ export class Blake2b {
                }
 
                // 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) {
@@ -145,9 +145,9 @@ export class Blake2b {
        }
 
        /**
-       * 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?
@@ -160,10 +160,10 @@ export class Blake2b {
        }
 
        /**
-       * 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
@@ -209,13 +209,13 @@ export class Blake2b {
        #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
@@ -277,6 +277,12 @@ export class 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)
@@ -288,9 +294,14 @@ export class Blake2b {
                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
        }