From: Chris Duncan Date: Thu, 24 Sep 2026 21:04:28 +0000 (-0700) Subject: Fix blakegen compression step. X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=13dd048a986489e9719b14e0c14b027419861d1b;p=nano25519.git Fix blakegen compression step. --- diff --git a/scripts/blake2b-gen.mjs b/scripts/blake2b-gen.mjs index f0bb7f4..815c555 100644 --- a/scripts/blake2b-gen.mjs +++ b/scripts/blake2b-gen.mjs @@ -73,7 +73,7 @@ const DECLARATIONS = (() => { * - Note: BLAKE2b reference supports 2¹²⁸-1, but this implementation restricts to 2⁶⁴-1 for compatibility with WASM without SIMD) */ b: StaticArray = new StaticArray(${B_LENGTH}) - c: i32 = 0 + c: u8 = 0 h: StaticArray = new StaticArray(${H_LENGTH}) p: StaticArray = new StaticArray(64) t: u64 = 0 @@ -184,7 +184,7 @@ function COMPRESS () { let output = ` // COMPRESS // Defined in BLAKE2 section 2.4 - compress (isFinal: u64): void { + compress (src: usize, isFinal: u64): void { // initialize compression buffers // - m: message buffer, represents current state of \`b\` during compression // - v: state vector, set to bytes of \`h\` and \`iv\` then modified by \`t\` during compression @@ -207,12 +207,11 @@ function COMPRESS () { v${14} ^= isFinal // copy input buffer to message block - const b_ptr = changetype(this.b) ` for (let i = 0; i < 16; i++) { output += ` - let m${i}: u64 = load(b_ptr + ${i << 3}) + let m${i}: u64 = load(src + ${i << 3}) ` } @@ -248,31 +247,34 @@ export class Blake2b { update (input: StaticArray, length: i32): Blake2b { const input_ptr: usize = changetype(input) const b_ptr: usize = changetype(this.b) - - let i = 0; - while (i < length) { - - // is buffer full? - if (this.c === ${B_LENGTH}) { - - // increment total byte counter + let i = 0 + + // fill existing partial buffer + if (this.c > 0) { + const b_rem = ${B_LENGTH} - this.c + const l_rem = length - i + const gap = u8(b_rem < l_rem ? b_rem : l_rem) + memory.copy(b_ptr + this.c, input_ptr + i, gap) + this.c += gap + i += gap + if (this.c === ${B_LENGTH} && i < length) { this.t += ${B_LENGTH} - - // reset buffer counter to zero this.c = 0 - - // compress (not final) - this.compress(0) - - } else { - const b_rem = ${B_LENGTH} - this.c - const l_rem = length - i - const n = b_rem < l_rem ? b_rem : l_rem - memory.copy(b_ptr + this.c, input_ptr + i, n) - this.c += n - i += n + this.compress(b_ptr, 0) } } + + // compress full blocks + while (length - i > ${B_LENGTH}) { + this.t += ${B_LENGTH} + this.compress(input_ptr + i, 0) + i += ${B_LENGTH} + } + + // store remaining partial block for further \`update()\` or \`digest()\` + memory.copy(b_ptr + this.c, input_ptr + i, u8(length - i)) + this.c += u8(length - i) + return this } @@ -286,7 +288,7 @@ export class Blake2b { this.b.fill(0, this.c) // set final block flag and compress - this.compress(u64(0 - 1)) + this.compress(changetype(this.b), 0xffffffffffffffff) // return byte array of 64-byte chain buffer memory.copy(changetype(output), changetype(this.h), 64) diff --git a/src/assembly/crypto_sign.ts b/src/assembly/crypto_sign.ts index 8ed0acc..5b2ace8 100644 --- a/src/assembly/crypto_sign.ts +++ b/src/assembly/crypto_sign.ts @@ -2,6 +2,7 @@ //! SPDX-License-Identifier: GPL-3.0-or-later import { KEY_BYTELENGTH } from './constants' +import { crypto_derive } from './crypto_derive' import { Blake2b } from './ed25519/blake2b' import { ge_scalarmult_base_tobytes } from './ed25519/ge' import { sc_muladd, sc_reduce } from './ed25519/sc' @@ -39,15 +40,14 @@ const S = new StaticArray(64) * @param {StaticArray} pub 32-byte public key from input buffer */ export function crypto_sign (RS: StaticArray, M: StaticArray, mlen: i32, prv: StaticArray, pub: StaticArray): i32 { - // // Derive `A` from private key - // crypto_derive(A, prv) - // let c = 0 - // for (let i = 0; i < KEY_BYTELENGTH; i++) { - // c |= A[i] ^ pub[i] - // } - // // Return early if `A` does not match public key - // if (c != 0) return c - memory.copy(changetype(A), changetype(pub), 32) + // Derive `A` from private key + crypto_derive(A, prv) + let c = 0 + for (let i = 0; i < KEY_BYTELENGTH; i++) { + c |= A[i] ^ pub[i] + } + // Return early if `A` does not match public key + if (c != 0) return c // Hash private key to `h` blake2b.init().update(prv, KEY_BYTELENGTH).digest(h) diff --git a/src/assembly/ed25519/blake2b.ts b/src/assembly/ed25519/blake2b.ts index 93a7071..2edcdee 100644 --- a/src/assembly/ed25519/blake2b.ts +++ b/src/assembly/ed25519/blake2b.ts @@ -3,54 +3,53 @@ export class Blake2b { - - /** - * Buffers and counters - * - b: input buffer, filled and refilled by input data in 128 byte increments - * - c: buffer counter, points to current index in `b` - * - h: chain buffer, updated after each compression - * - p: set according to BLAKE2 layout from constructor arguments - * - t: total byte counter, incremented by `c` - * - Note: BLAKE2b reference supports 2¹²⁸-1, but this implementation restricts to 2⁶⁴-1 for compatibility with WASM without SIMD) - */ - b: StaticArray = new StaticArray(128) - c: i32 = 0 - h: StaticArray = new StaticArray(8) - p: StaticArray = new StaticArray(64) - t: u64 = 0 - - - // COMPRESS - // Defined in BLAKE2 section 2.4 - compress (isFinal: u64): void { + /** + * Buffers and counters + * - b: input buffer, filled and refilled by input data in 128 byte increments + * - c: buffer counter, points to current index in `b` + * - h: chain buffer, updated after each compression + * - p: set according to BLAKE2 layout from constructor arguments + * - t: total byte counter, incremented by `c` + * - Note: BLAKE2b reference supports 2¹²⁸-1, but this implementation restricts to 2⁶⁴-1 for compatibility with WASM without SIMD) + */ + b: StaticArray = new StaticArray(128) + c: u8 = 0 + h: StaticArray = new StaticArray(8) + p: StaticArray = new StaticArray(64) + t: u64 = 0 + + + // COMPRESS + // Defined in BLAKE2 section 2.4 + compress (src: usize, isFinal: u64): void { // initialize compression buffers // - m: message buffer, represents current state of `b` during compression // - v: state vector, set to bytes of `h` and `iv` then modified by `t` during compression - - let v0: u64 = this.h[0] - let v8: u64 = 0x6a09e667f3bcc908 - - let v1: u64 = this.h[1] - let v9: u64 = 0xbb67ae8584caa73b - - let v2: u64 = this.h[2] - let v10: u64 = 0x3c6ef372fe94f82b - - let v3: u64 = this.h[3] - let v11: u64 = 0xa54ff53a5f1d36f1 - - let v4: u64 = this.h[4] - let v12: u64 = 0x510e527fade682d1 - - let v5: u64 = this.h[5] - let v13: u64 = 0x9b05688c2b3e6c1f - - let v6: u64 = this.h[6] - let v14: u64 = 0x1f83d9abfb41bd6b - - let v7: u64 = this.h[7] - let v15: u64 = 0x5be0cd19137e2179 - + + let v0: u64 = this.h[0] + let v8: u64 = 0x6a09e667f3bcc908 + + let v1: u64 = this.h[1] + let v9: u64 = 0xbb67ae8584caa73b + + let v2: u64 = this.h[2] + let v10: u64 = 0x3c6ef372fe94f82b + + let v3: u64 = this.h[3] + let v11: u64 = 0xa54ff53a5f1d36f1 + + let v4: u64 = this.h[4] + let v12: u64 = 0x510e527fade682d1 + + let v5: u64 = this.h[5] + let v13: u64 = 0x9b05688c2b3e6c1f + + let v6: u64 = this.h[6] + let v14: u64 = 0x1f83d9abfb41bd6b + + let v7: u64 = this.h[7] + let v15: u64 = 0x5be0cd19137e2179 + // lo 64 bits of counter v12 ^= this.t @@ -61,44 +60,43 @@ export class Blake2b { v14 ^= isFinal // copy input buffer to message block - const b_ptr = changetype(this.b) - - let m0: u64 = load(b_ptr + 0) - - let m1: u64 = load(b_ptr + 8) - - let m2: u64 = load(b_ptr + 16) - - let m3: u64 = load(b_ptr + 24) - - let m4: u64 = load(b_ptr + 32) - - let m5: u64 = load(b_ptr + 40) - - let m6: u64 = load(b_ptr + 48) - - let m7: u64 = load(b_ptr + 56) - - let m8: u64 = load(b_ptr + 64) - - let m9: u64 = load(b_ptr + 72) - - let m10: u64 = load(b_ptr + 80) - - let m11: u64 = load(b_ptr + 88) - - let m12: u64 = load(b_ptr + 96) - - let m13: u64 = load(b_ptr + 104) - - let m14: u64 = load(b_ptr + 112) - - let m15: u64 = load(b_ptr + 120) - + + let m0: u64 = load(src + 0) + + let m1: u64 = load(src + 8) + + let m2: u64 = load(src + 16) + + let m3: u64 = load(src + 24) + + let m4: u64 = load(src + 32) + + let m5: u64 = load(src + 40) + + let m6: u64 = load(src + 48) + + let m7: u64 = load(src + 56) + + let m8: u64 = load(src + 64) + + let m9: u64 = load(src + 72) + + let m10: u64 = load(src + 80) + + let m11: u64 = load(src + 88) + + let m12: u64 = load(src + 96) + + let m13: u64 = load(src + 104) + + let m14: u64 = load(src + 112) + + let m15: u64 = load(src + 120) + // twelve rounds of mixing - + // ROUND 0 - + v0 = v0 + v4 + m0 v12 = rotr(v12 ^ v0, 32) v8 = v8 + v12 @@ -107,7 +105,7 @@ export class Blake2b { v12 = rotr(v12 ^ v0, 16) v8 = v8 + v12 v4 = rotr(v4 ^ v8, 63) - + v1 = v1 + v5 + m2 v13 = rotr(v13 ^ v1, 32) v9 = v9 + v13 @@ -116,7 +114,7 @@ export class Blake2b { v13 = rotr(v13 ^ v1, 16) v9 = v9 + v13 v5 = rotr(v5 ^ v9, 63) - + v2 = v2 + v6 + m4 v14 = rotr(v14 ^ v2, 32) v10 = v10 + v14 @@ -125,7 +123,7 @@ export class Blake2b { v14 = rotr(v14 ^ v2, 16) v10 = v10 + v14 v6 = rotr(v6 ^ v10, 63) - + v3 = v3 + v7 + m6 v15 = rotr(v15 ^ v3, 32) v11 = v11 + v15 @@ -134,7 +132,7 @@ export class Blake2b { v15 = rotr(v15 ^ v3, 16) v11 = v11 + v15 v7 = rotr(v7 ^ v11, 63) - + v0 = v0 + v5 + m8 v15 = rotr(v15 ^ v0, 32) v10 = v10 + v15 @@ -143,7 +141,7 @@ export class Blake2b { v15 = rotr(v15 ^ v0, 16) v10 = v10 + v15 v5 = rotr(v5 ^ v10, 63) - + v1 = v1 + v6 + m10 v12 = rotr(v12 ^ v1, 32) v11 = v11 + v12 @@ -152,7 +150,7 @@ export class Blake2b { v12 = rotr(v12 ^ v1, 16) v11 = v11 + v12 v6 = rotr(v6 ^ v11, 63) - + v2 = v2 + v7 + m12 v13 = rotr(v13 ^ v2, 32) v8 = v8 + v13 @@ -161,7 +159,7 @@ export class Blake2b { v13 = rotr(v13 ^ v2, 16) v8 = v8 + v13 v7 = rotr(v7 ^ v8, 63) - + v3 = v3 + v4 + m14 v14 = rotr(v14 ^ v3, 32) v9 = v9 + v14 @@ -170,9 +168,9 @@ export class Blake2b { v14 = rotr(v14 ^ v3, 16) v9 = v9 + v14 v4 = rotr(v4 ^ v9, 63) - + // ROUND 1 - + v0 = v0 + v4 + m14 v12 = rotr(v12 ^ v0, 32) v8 = v8 + v12 @@ -181,7 +179,7 @@ export class Blake2b { v12 = rotr(v12 ^ v0, 16) v8 = v8 + v12 v4 = rotr(v4 ^ v8, 63) - + v1 = v1 + v5 + m4 v13 = rotr(v13 ^ v1, 32) v9 = v9 + v13 @@ -190,7 +188,7 @@ export class Blake2b { v13 = rotr(v13 ^ v1, 16) v9 = v9 + v13 v5 = rotr(v5 ^ v9, 63) - + v2 = v2 + v6 + m9 v14 = rotr(v14 ^ v2, 32) v10 = v10 + v14 @@ -199,7 +197,7 @@ export class Blake2b { v14 = rotr(v14 ^ v2, 16) v10 = v10 + v14 v6 = rotr(v6 ^ v10, 63) - + v3 = v3 + v7 + m13 v15 = rotr(v15 ^ v3, 32) v11 = v11 + v15 @@ -208,7 +206,7 @@ export class Blake2b { v15 = rotr(v15 ^ v3, 16) v11 = v11 + v15 v7 = rotr(v7 ^ v11, 63) - + v0 = v0 + v5 + m1 v15 = rotr(v15 ^ v0, 32) v10 = v10 + v15 @@ -217,7 +215,7 @@ export class Blake2b { v15 = rotr(v15 ^ v0, 16) v10 = v10 + v15 v5 = rotr(v5 ^ v10, 63) - + v1 = v1 + v6 + m0 v12 = rotr(v12 ^ v1, 32) v11 = v11 + v12 @@ -226,7 +224,7 @@ export class Blake2b { v12 = rotr(v12 ^ v1, 16) v11 = v11 + v12 v6 = rotr(v6 ^ v11, 63) - + v2 = v2 + v7 + m11 v13 = rotr(v13 ^ v2, 32) v8 = v8 + v13 @@ -235,7 +233,7 @@ export class Blake2b { v13 = rotr(v13 ^ v2, 16) v8 = v8 + v13 v7 = rotr(v7 ^ v8, 63) - + v3 = v3 + v4 + m5 v14 = rotr(v14 ^ v3, 32) v9 = v9 + v14 @@ -244,9 +242,9 @@ export class Blake2b { v14 = rotr(v14 ^ v3, 16) v9 = v9 + v14 v4 = rotr(v4 ^ v9, 63) - + // ROUND 2 - + v0 = v0 + v4 + m11 v12 = rotr(v12 ^ v0, 32) v8 = v8 + v12 @@ -255,7 +253,7 @@ export class Blake2b { v12 = rotr(v12 ^ v0, 16) v8 = v8 + v12 v4 = rotr(v4 ^ v8, 63) - + v1 = v1 + v5 + m12 v13 = rotr(v13 ^ v1, 32) v9 = v9 + v13 @@ -264,7 +262,7 @@ export class Blake2b { v13 = rotr(v13 ^ v1, 16) v9 = v9 + v13 v5 = rotr(v5 ^ v9, 63) - + v2 = v2 + v6 + m5 v14 = rotr(v14 ^ v2, 32) v10 = v10 + v14 @@ -273,7 +271,7 @@ export class Blake2b { v14 = rotr(v14 ^ v2, 16) v10 = v10 + v14 v6 = rotr(v6 ^ v10, 63) - + v3 = v3 + v7 + m15 v15 = rotr(v15 ^ v3, 32) v11 = v11 + v15 @@ -282,7 +280,7 @@ export class Blake2b { v15 = rotr(v15 ^ v3, 16) v11 = v11 + v15 v7 = rotr(v7 ^ v11, 63) - + v0 = v0 + v5 + m10 v15 = rotr(v15 ^ v0, 32) v10 = v10 + v15 @@ -291,7 +289,7 @@ export class Blake2b { v15 = rotr(v15 ^ v0, 16) v10 = v10 + v15 v5 = rotr(v5 ^ v10, 63) - + v1 = v1 + v6 + m3 v12 = rotr(v12 ^ v1, 32) v11 = v11 + v12 @@ -300,7 +298,7 @@ export class Blake2b { v12 = rotr(v12 ^ v1, 16) v11 = v11 + v12 v6 = rotr(v6 ^ v11, 63) - + v2 = v2 + v7 + m7 v13 = rotr(v13 ^ v2, 32) v8 = v8 + v13 @@ -309,7 +307,7 @@ export class Blake2b { v13 = rotr(v13 ^ v2, 16) v8 = v8 + v13 v7 = rotr(v7 ^ v8, 63) - + v3 = v3 + v4 + m9 v14 = rotr(v14 ^ v3, 32) v9 = v9 + v14 @@ -318,9 +316,9 @@ export class Blake2b { v14 = rotr(v14 ^ v3, 16) v9 = v9 + v14 v4 = rotr(v4 ^ v9, 63) - + // ROUND 3 - + v0 = v0 + v4 + m7 v12 = rotr(v12 ^ v0, 32) v8 = v8 + v12 @@ -329,7 +327,7 @@ export class Blake2b { v12 = rotr(v12 ^ v0, 16) v8 = v8 + v12 v4 = rotr(v4 ^ v8, 63) - + v1 = v1 + v5 + m3 v13 = rotr(v13 ^ v1, 32) v9 = v9 + v13 @@ -338,7 +336,7 @@ export class Blake2b { v13 = rotr(v13 ^ v1, 16) v9 = v9 + v13 v5 = rotr(v5 ^ v9, 63) - + v2 = v2 + v6 + m13 v14 = rotr(v14 ^ v2, 32) v10 = v10 + v14 @@ -347,7 +345,7 @@ export class Blake2b { v14 = rotr(v14 ^ v2, 16) v10 = v10 + v14 v6 = rotr(v6 ^ v10, 63) - + v3 = v3 + v7 + m11 v15 = rotr(v15 ^ v3, 32) v11 = v11 + v15 @@ -356,7 +354,7 @@ export class Blake2b { v15 = rotr(v15 ^ v3, 16) v11 = v11 + v15 v7 = rotr(v7 ^ v11, 63) - + v0 = v0 + v5 + m2 v15 = rotr(v15 ^ v0, 32) v10 = v10 + v15 @@ -365,7 +363,7 @@ export class Blake2b { v15 = rotr(v15 ^ v0, 16) v10 = v10 + v15 v5 = rotr(v5 ^ v10, 63) - + v1 = v1 + v6 + m5 v12 = rotr(v12 ^ v1, 32) v11 = v11 + v12 @@ -374,7 +372,7 @@ export class Blake2b { v12 = rotr(v12 ^ v1, 16) v11 = v11 + v12 v6 = rotr(v6 ^ v11, 63) - + v2 = v2 + v7 + m4 v13 = rotr(v13 ^ v2, 32) v8 = v8 + v13 @@ -383,7 +381,7 @@ export class Blake2b { v13 = rotr(v13 ^ v2, 16) v8 = v8 + v13 v7 = rotr(v7 ^ v8, 63) - + v3 = v3 + v4 + m15 v14 = rotr(v14 ^ v3, 32) v9 = v9 + v14 @@ -392,9 +390,9 @@ export class Blake2b { v14 = rotr(v14 ^ v3, 16) v9 = v9 + v14 v4 = rotr(v4 ^ v9, 63) - + // ROUND 4 - + v0 = v0 + v4 + m9 v12 = rotr(v12 ^ v0, 32) v8 = v8 + v12 @@ -403,7 +401,7 @@ export class Blake2b { v12 = rotr(v12 ^ v0, 16) v8 = v8 + v12 v4 = rotr(v4 ^ v8, 63) - + v1 = v1 + v5 + m5 v13 = rotr(v13 ^ v1, 32) v9 = v9 + v13 @@ -412,7 +410,7 @@ export class Blake2b { v13 = rotr(v13 ^ v1, 16) v9 = v9 + v13 v5 = rotr(v5 ^ v9, 63) - + v2 = v2 + v6 + m2 v14 = rotr(v14 ^ v2, 32) v10 = v10 + v14 @@ -421,7 +419,7 @@ export class Blake2b { v14 = rotr(v14 ^ v2, 16) v10 = v10 + v14 v6 = rotr(v6 ^ v10, 63) - + v3 = v3 + v7 + m10 v15 = rotr(v15 ^ v3, 32) v11 = v11 + v15 @@ -430,7 +428,7 @@ export class Blake2b { v15 = rotr(v15 ^ v3, 16) v11 = v11 + v15 v7 = rotr(v7 ^ v11, 63) - + v0 = v0 + v5 + m14 v15 = rotr(v15 ^ v0, 32) v10 = v10 + v15 @@ -439,7 +437,7 @@ export class Blake2b { v15 = rotr(v15 ^ v0, 16) v10 = v10 + v15 v5 = rotr(v5 ^ v10, 63) - + v1 = v1 + v6 + m11 v12 = rotr(v12 ^ v1, 32) v11 = v11 + v12 @@ -448,7 +446,7 @@ export class Blake2b { v12 = rotr(v12 ^ v1, 16) v11 = v11 + v12 v6 = rotr(v6 ^ v11, 63) - + v2 = v2 + v7 + m6 v13 = rotr(v13 ^ v2, 32) v8 = v8 + v13 @@ -457,7 +455,7 @@ export class Blake2b { v13 = rotr(v13 ^ v2, 16) v8 = v8 + v13 v7 = rotr(v7 ^ v8, 63) - + v3 = v3 + v4 + m3 v14 = rotr(v14 ^ v3, 32) v9 = v9 + v14 @@ -466,9 +464,9 @@ export class Blake2b { v14 = rotr(v14 ^ v3, 16) v9 = v9 + v14 v4 = rotr(v4 ^ v9, 63) - + // ROUND 5 - + v0 = v0 + v4 + m2 v12 = rotr(v12 ^ v0, 32) v8 = v8 + v12 @@ -477,7 +475,7 @@ export class Blake2b { v12 = rotr(v12 ^ v0, 16) v8 = v8 + v12 v4 = rotr(v4 ^ v8, 63) - + v1 = v1 + v5 + m6 v13 = rotr(v13 ^ v1, 32) v9 = v9 + v13 @@ -486,7 +484,7 @@ export class Blake2b { v13 = rotr(v13 ^ v1, 16) v9 = v9 + v13 v5 = rotr(v5 ^ v9, 63) - + v2 = v2 + v6 + m0 v14 = rotr(v14 ^ v2, 32) v10 = v10 + v14 @@ -495,7 +493,7 @@ export class Blake2b { v14 = rotr(v14 ^ v2, 16) v10 = v10 + v14 v6 = rotr(v6 ^ v10, 63) - + v3 = v3 + v7 + m8 v15 = rotr(v15 ^ v3, 32) v11 = v11 + v15 @@ -504,7 +502,7 @@ export class Blake2b { v15 = rotr(v15 ^ v3, 16) v11 = v11 + v15 v7 = rotr(v7 ^ v11, 63) - + v0 = v0 + v5 + m4 v15 = rotr(v15 ^ v0, 32) v10 = v10 + v15 @@ -513,7 +511,7 @@ export class Blake2b { v15 = rotr(v15 ^ v0, 16) v10 = v10 + v15 v5 = rotr(v5 ^ v10, 63) - + v1 = v1 + v6 + m7 v12 = rotr(v12 ^ v1, 32) v11 = v11 + v12 @@ -522,7 +520,7 @@ export class Blake2b { v12 = rotr(v12 ^ v1, 16) v11 = v11 + v12 v6 = rotr(v6 ^ v11, 63) - + v2 = v2 + v7 + m15 v13 = rotr(v13 ^ v2, 32) v8 = v8 + v13 @@ -531,7 +529,7 @@ export class Blake2b { v13 = rotr(v13 ^ v2, 16) v8 = v8 + v13 v7 = rotr(v7 ^ v8, 63) - + v3 = v3 + v4 + m1 v14 = rotr(v14 ^ v3, 32) v9 = v9 + v14 @@ -540,9 +538,9 @@ export class Blake2b { v14 = rotr(v14 ^ v3, 16) v9 = v9 + v14 v4 = rotr(v4 ^ v9, 63) - + // ROUND 6 - + v0 = v0 + v4 + m12 v12 = rotr(v12 ^ v0, 32) v8 = v8 + v12 @@ -551,7 +549,7 @@ export class Blake2b { v12 = rotr(v12 ^ v0, 16) v8 = v8 + v12 v4 = rotr(v4 ^ v8, 63) - + v1 = v1 + v5 + m1 v13 = rotr(v13 ^ v1, 32) v9 = v9 + v13 @@ -560,7 +558,7 @@ export class Blake2b { v13 = rotr(v13 ^ v1, 16) v9 = v9 + v13 v5 = rotr(v5 ^ v9, 63) - + v2 = v2 + v6 + m14 v14 = rotr(v14 ^ v2, 32) v10 = v10 + v14 @@ -569,7 +567,7 @@ export class Blake2b { v14 = rotr(v14 ^ v2, 16) v10 = v10 + v14 v6 = rotr(v6 ^ v10, 63) - + v3 = v3 + v7 + m4 v15 = rotr(v15 ^ v3, 32) v11 = v11 + v15 @@ -578,7 +576,7 @@ export class Blake2b { v15 = rotr(v15 ^ v3, 16) v11 = v11 + v15 v7 = rotr(v7 ^ v11, 63) - + v0 = v0 + v5 + m0 v15 = rotr(v15 ^ v0, 32) v10 = v10 + v15 @@ -587,7 +585,7 @@ export class Blake2b { v15 = rotr(v15 ^ v0, 16) v10 = v10 + v15 v5 = rotr(v5 ^ v10, 63) - + v1 = v1 + v6 + m6 v12 = rotr(v12 ^ v1, 32) v11 = v11 + v12 @@ -596,7 +594,7 @@ export class Blake2b { v12 = rotr(v12 ^ v1, 16) v11 = v11 + v12 v6 = rotr(v6 ^ v11, 63) - + v2 = v2 + v7 + m9 v13 = rotr(v13 ^ v2, 32) v8 = v8 + v13 @@ -605,7 +603,7 @@ export class Blake2b { v13 = rotr(v13 ^ v2, 16) v8 = v8 + v13 v7 = rotr(v7 ^ v8, 63) - + v3 = v3 + v4 + m8 v14 = rotr(v14 ^ v3, 32) v9 = v9 + v14 @@ -614,9 +612,9 @@ export class Blake2b { v14 = rotr(v14 ^ v3, 16) v9 = v9 + v14 v4 = rotr(v4 ^ v9, 63) - + // ROUND 7 - + v0 = v0 + v4 + m13 v12 = rotr(v12 ^ v0, 32) v8 = v8 + v12 @@ -625,7 +623,7 @@ export class Blake2b { v12 = rotr(v12 ^ v0, 16) v8 = v8 + v12 v4 = rotr(v4 ^ v8, 63) - + v1 = v1 + v5 + m7 v13 = rotr(v13 ^ v1, 32) v9 = v9 + v13 @@ -634,7 +632,7 @@ export class Blake2b { v13 = rotr(v13 ^ v1, 16) v9 = v9 + v13 v5 = rotr(v5 ^ v9, 63) - + v2 = v2 + v6 + m12 v14 = rotr(v14 ^ v2, 32) v10 = v10 + v14 @@ -643,7 +641,7 @@ export class Blake2b { v14 = rotr(v14 ^ v2, 16) v10 = v10 + v14 v6 = rotr(v6 ^ v10, 63) - + v3 = v3 + v7 + m3 v15 = rotr(v15 ^ v3, 32) v11 = v11 + v15 @@ -652,7 +650,7 @@ export class Blake2b { v15 = rotr(v15 ^ v3, 16) v11 = v11 + v15 v7 = rotr(v7 ^ v11, 63) - + v0 = v0 + v5 + m5 v15 = rotr(v15 ^ v0, 32) v10 = v10 + v15 @@ -661,7 +659,7 @@ export class Blake2b { v15 = rotr(v15 ^ v0, 16) v10 = v10 + v15 v5 = rotr(v5 ^ v10, 63) - + v1 = v1 + v6 + m15 v12 = rotr(v12 ^ v1, 32) v11 = v11 + v12 @@ -670,7 +668,7 @@ export class Blake2b { v12 = rotr(v12 ^ v1, 16) v11 = v11 + v12 v6 = rotr(v6 ^ v11, 63) - + v2 = v2 + v7 + m8 v13 = rotr(v13 ^ v2, 32) v8 = v8 + v13 @@ -679,7 +677,7 @@ export class Blake2b { v13 = rotr(v13 ^ v2, 16) v8 = v8 + v13 v7 = rotr(v7 ^ v8, 63) - + v3 = v3 + v4 + m2 v14 = rotr(v14 ^ v3, 32) v9 = v9 + v14 @@ -688,9 +686,9 @@ export class Blake2b { v14 = rotr(v14 ^ v3, 16) v9 = v9 + v14 v4 = rotr(v4 ^ v9, 63) - + // ROUND 8 - + v0 = v0 + v4 + m6 v12 = rotr(v12 ^ v0, 32) v8 = v8 + v12 @@ -699,7 +697,7 @@ export class Blake2b { v12 = rotr(v12 ^ v0, 16) v8 = v8 + v12 v4 = rotr(v4 ^ v8, 63) - + v1 = v1 + v5 + m14 v13 = rotr(v13 ^ v1, 32) v9 = v9 + v13 @@ -708,7 +706,7 @@ export class Blake2b { v13 = rotr(v13 ^ v1, 16) v9 = v9 + v13 v5 = rotr(v5 ^ v9, 63) - + v2 = v2 + v6 + m11 v14 = rotr(v14 ^ v2, 32) v10 = v10 + v14 @@ -717,7 +715,7 @@ export class Blake2b { v14 = rotr(v14 ^ v2, 16) v10 = v10 + v14 v6 = rotr(v6 ^ v10, 63) - + v3 = v3 + v7 + m0 v15 = rotr(v15 ^ v3, 32) v11 = v11 + v15 @@ -726,7 +724,7 @@ export class Blake2b { v15 = rotr(v15 ^ v3, 16) v11 = v11 + v15 v7 = rotr(v7 ^ v11, 63) - + v0 = v0 + v5 + m12 v15 = rotr(v15 ^ v0, 32) v10 = v10 + v15 @@ -735,7 +733,7 @@ export class Blake2b { v15 = rotr(v15 ^ v0, 16) v10 = v10 + v15 v5 = rotr(v5 ^ v10, 63) - + v1 = v1 + v6 + m13 v12 = rotr(v12 ^ v1, 32) v11 = v11 + v12 @@ -744,7 +742,7 @@ export class Blake2b { v12 = rotr(v12 ^ v1, 16) v11 = v11 + v12 v6 = rotr(v6 ^ v11, 63) - + v2 = v2 + v7 + m1 v13 = rotr(v13 ^ v2, 32) v8 = v8 + v13 @@ -753,7 +751,7 @@ export class Blake2b { v13 = rotr(v13 ^ v2, 16) v8 = v8 + v13 v7 = rotr(v7 ^ v8, 63) - + v3 = v3 + v4 + m10 v14 = rotr(v14 ^ v3, 32) v9 = v9 + v14 @@ -762,9 +760,9 @@ export class Blake2b { v14 = rotr(v14 ^ v3, 16) v9 = v9 + v14 v4 = rotr(v4 ^ v9, 63) - + // ROUND 9 - + v0 = v0 + v4 + m10 v12 = rotr(v12 ^ v0, 32) v8 = v8 + v12 @@ -773,7 +771,7 @@ export class Blake2b { v12 = rotr(v12 ^ v0, 16) v8 = v8 + v12 v4 = rotr(v4 ^ v8, 63) - + v1 = v1 + v5 + m8 v13 = rotr(v13 ^ v1, 32) v9 = v9 + v13 @@ -782,7 +780,7 @@ export class Blake2b { v13 = rotr(v13 ^ v1, 16) v9 = v9 + v13 v5 = rotr(v5 ^ v9, 63) - + v2 = v2 + v6 + m7 v14 = rotr(v14 ^ v2, 32) v10 = v10 + v14 @@ -791,7 +789,7 @@ export class Blake2b { v14 = rotr(v14 ^ v2, 16) v10 = v10 + v14 v6 = rotr(v6 ^ v10, 63) - + v3 = v3 + v7 + m1 v15 = rotr(v15 ^ v3, 32) v11 = v11 + v15 @@ -800,7 +798,7 @@ export class Blake2b { v15 = rotr(v15 ^ v3, 16) v11 = v11 + v15 v7 = rotr(v7 ^ v11, 63) - + v0 = v0 + v5 + m15 v15 = rotr(v15 ^ v0, 32) v10 = v10 + v15 @@ -809,7 +807,7 @@ export class Blake2b { v15 = rotr(v15 ^ v0, 16) v10 = v10 + v15 v5 = rotr(v5 ^ v10, 63) - + v1 = v1 + v6 + m9 v12 = rotr(v12 ^ v1, 32) v11 = v11 + v12 @@ -818,7 +816,7 @@ export class Blake2b { v12 = rotr(v12 ^ v1, 16) v11 = v11 + v12 v6 = rotr(v6 ^ v11, 63) - + v2 = v2 + v7 + m3 v13 = rotr(v13 ^ v2, 32) v8 = v8 + v13 @@ -827,7 +825,7 @@ export class Blake2b { v13 = rotr(v13 ^ v2, 16) v8 = v8 + v13 v7 = rotr(v7 ^ v8, 63) - + v3 = v3 + v4 + m13 v14 = rotr(v14 ^ v3, 32) v9 = v9 + v14 @@ -836,9 +834,9 @@ export class Blake2b { v14 = rotr(v14 ^ v3, 16) v9 = v9 + v14 v4 = rotr(v4 ^ v9, 63) - + // ROUND 10 - + v0 = v0 + v4 + m0 v12 = rotr(v12 ^ v0, 32) v8 = v8 + v12 @@ -847,7 +845,7 @@ export class Blake2b { v12 = rotr(v12 ^ v0, 16) v8 = v8 + v12 v4 = rotr(v4 ^ v8, 63) - + v1 = v1 + v5 + m2 v13 = rotr(v13 ^ v1, 32) v9 = v9 + v13 @@ -856,7 +854,7 @@ export class Blake2b { v13 = rotr(v13 ^ v1, 16) v9 = v9 + v13 v5 = rotr(v5 ^ v9, 63) - + v2 = v2 + v6 + m4 v14 = rotr(v14 ^ v2, 32) v10 = v10 + v14 @@ -865,7 +863,7 @@ export class Blake2b { v14 = rotr(v14 ^ v2, 16) v10 = v10 + v14 v6 = rotr(v6 ^ v10, 63) - + v3 = v3 + v7 + m6 v15 = rotr(v15 ^ v3, 32) v11 = v11 + v15 @@ -874,7 +872,7 @@ export class Blake2b { v15 = rotr(v15 ^ v3, 16) v11 = v11 + v15 v7 = rotr(v7 ^ v11, 63) - + v0 = v0 + v5 + m8 v15 = rotr(v15 ^ v0, 32) v10 = v10 + v15 @@ -883,7 +881,7 @@ export class Blake2b { v15 = rotr(v15 ^ v0, 16) v10 = v10 + v15 v5 = rotr(v5 ^ v10, 63) - + v1 = v1 + v6 + m10 v12 = rotr(v12 ^ v1, 32) v11 = v11 + v12 @@ -892,7 +890,7 @@ export class Blake2b { v12 = rotr(v12 ^ v1, 16) v11 = v11 + v12 v6 = rotr(v6 ^ v11, 63) - + v2 = v2 + v7 + m12 v13 = rotr(v13 ^ v2, 32) v8 = v8 + v13 @@ -901,7 +899,7 @@ export class Blake2b { v13 = rotr(v13 ^ v2, 16) v8 = v8 + v13 v7 = rotr(v7 ^ v8, 63) - + v3 = v3 + v4 + m14 v14 = rotr(v14 ^ v3, 32) v9 = v9 + v14 @@ -910,9 +908,9 @@ export class Blake2b { v14 = rotr(v14 ^ v3, 16) v9 = v9 + v14 v4 = rotr(v4 ^ v9, 63) - + // ROUND 11 - + v0 = v0 + v4 + m14 v12 = rotr(v12 ^ v0, 32) v8 = v8 + v12 @@ -921,7 +919,7 @@ export class Blake2b { v12 = rotr(v12 ^ v0, 16) v8 = v8 + v12 v4 = rotr(v4 ^ v8, 63) - + v1 = v1 + v5 + m4 v13 = rotr(v13 ^ v1, 32) v9 = v9 + v13 @@ -930,7 +928,7 @@ export class Blake2b { v13 = rotr(v13 ^ v1, 16) v9 = v9 + v13 v5 = rotr(v5 ^ v9, 63) - + v2 = v2 + v6 + m9 v14 = rotr(v14 ^ v2, 32) v10 = v10 + v14 @@ -939,7 +937,7 @@ export class Blake2b { v14 = rotr(v14 ^ v2, 16) v10 = v10 + v14 v6 = rotr(v6 ^ v10, 63) - + v3 = v3 + v7 + m13 v15 = rotr(v15 ^ v3, 32) v11 = v11 + v15 @@ -948,7 +946,7 @@ export class Blake2b { v15 = rotr(v15 ^ v3, 16) v11 = v11 + v15 v7 = rotr(v7 ^ v11, 63) - + v0 = v0 + v5 + m1 v15 = rotr(v15 ^ v0, 32) v10 = v10 + v15 @@ -957,7 +955,7 @@ export class Blake2b { v15 = rotr(v15 ^ v0, 16) v10 = v10 + v15 v5 = rotr(v5 ^ v10, 63) - + v1 = v1 + v6 + m0 v12 = rotr(v12 ^ v1, 32) v11 = v11 + v12 @@ -966,7 +964,7 @@ export class Blake2b { v12 = rotr(v12 ^ v1, 16) v11 = v11 + v12 v6 = rotr(v6 ^ v11, 63) - + v2 = v2 + v7 + m11 v13 = rotr(v13 ^ v2, 32) v8 = v8 + v13 @@ -975,7 +973,7 @@ export class Blake2b { v13 = rotr(v13 ^ v2, 16) v8 = v8 + v13 v7 = rotr(v7 ^ v8, 63) - + v3 = v3 + v4 + m5 v14 = rotr(v14 ^ v3, 32) v9 = v9 + v14 @@ -984,100 +982,101 @@ export class Blake2b { v14 = rotr(v14 ^ v3, 16) v9 = v9 + v14 v4 = rotr(v4 ^ v9, 63) - + // set new chain value - - this.h[0] ^= v0 ^ v8 - - this.h[1] ^= v1 ^ v9 - - this.h[2] ^= v2 ^ v10 - - this.h[3] ^= v3 ^ v11 - - this.h[4] ^= v4 ^ v12 - - this.h[5] ^= v5 ^ v13 - - this.h[6] ^= v6 ^ v14 - - this.h[7] ^= v7 ^ v15 - - } - - - - init(): Blake2b { - // reset buffers and counters - + this.h[0] ^= v0 ^ v8 + + this.h[1] ^= v1 ^ v9 + + this.h[2] ^= v2 ^ v10 + + this.h[3] ^= v3 ^ v11 + + this.h[4] ^= v4 ^ v12 + + this.h[5] ^= v5 ^ v13 + + this.h[6] ^= v6 ^ v14 + + this.h[7] ^= v7 ^ v15 + + } + + + + init (): Blake2b { + // reset buffers and counters + this.b.fill(0) this.c = 0 this.h.fill(0) this.p.fill(0) this.t = 0 - - - // initialize parameter block - this.p[0] = 64 // always 64 bytes for this implementation - this.p[1] = 0 // no key - this.p[2] = 1 // fanout - this.p[3] = 1 // depth - + + + // initialize parameter block + this.p[0] = 64 // always 64 bytes for this implementation + this.p[1] = 0 // no key + this.p[2] = 1 // fanout + this.p[3] = 1 // depth + // initialize hash state - - this.h[0] = 0x6a09e667f3bcc908 - - this.h[1] = 0xbb67ae8584caa73b - - this.h[2] = 0x3c6ef372fe94f82b - - this.h[3] = 0xa54ff53a5f1d36f1 - - this.h[4] = 0x510e527fade682d1 - - this.h[5] = 0x9b05688c2b3e6c1f - - this.h[6] = 0x1f83d9abfb41bd6b - - this.h[7] = 0x5be0cd19137e2179 - + + this.h[0] = 0x6a09e667f3bcc908 + + this.h[1] = 0xbb67ae8584caa73b + + this.h[2] = 0x3c6ef372fe94f82b + + this.h[3] = 0xa54ff53a5f1d36f1 + + this.h[4] = 0x510e527fade682d1 + + this.h[5] = 0x9b05688c2b3e6c1f + + this.h[6] = 0x1f83d9abfb41bd6b + + this.h[7] = 0x5be0cd19137e2179 + for (let i = 0; i < 8; i++) { this.h[i] ^= load(changetype(this.p) + (i << 3)) } return this } - // input: variable-length message bytes passed by user to be hashed update (input: StaticArray, length: i32): Blake2b { const input_ptr: usize = changetype(input) const b_ptr: usize = changetype(this.b) + let i = 0 - let i = 0; - while (i < length) { - - // is buffer full? - if (this.c === 128) { - - // increment total byte counter + // fill existing partial buffer + if (this.c > 0) { + const b_rem = 128 - this.c + const l_rem = length - i + const gap = u8(b_rem < l_rem ? b_rem : l_rem) + memory.copy(b_ptr + this.c, input_ptr + i, gap) + this.c += gap + i += gap + if (this.c === 128 && i < length) { this.t += 128 - - // reset buffer counter to zero this.c = 0 - - // compress (not final) - this.compress(0) - - } else { - const b_rem = 128 - this.c - const l_rem = length - i - const n = b_rem < l_rem ? b_rem : l_rem - memory.copy(b_ptr + this.c, input_ptr + i, n) - this.c += n - i += n + this.compress(b_ptr, 0) } } + + // compress full blocks + while (length - i > 128) { + this.t += 128 + this.compress(input_ptr + i, 0) + i += 128 + } + + // store remaining partial block for further `update()` or `digest()` + memory.copy(b_ptr + this.c, input_ptr + i, u8(length - i)) + this.c += u8(length - i) + return this } @@ -1091,18 +1090,18 @@ export class Blake2b { this.b.fill(0, this.c) // set final block flag and compress - this.compress(u64(0 - 1)) + this.compress(changetype(this.b), 0xffffffffffffffff) // return byte array of 64-byte chain buffer memory.copy(changetype(output), changetype(this.h), 64) // clear internal buffers and counters - + this.b.fill(0) this.c = 0 this.h.fill(0) this.p.fill(0) this.t = 0 - + } } diff --git a/test/index.html b/test/index.html index f31c013..9dafca9 100644 --- a/test/index.html +++ b/test/index.html @@ -430,7 +430,7 @@ SPDX-License-Identifier: GPL-3.0-or-later verifyTimes[i].push(duration) } else { privateKey = rand32.bytes - message = rand32.bytes + message = crypto.getRandomValues(new Uint8Array(32768)) start = performance.now() publicKey = derive(privateKey, api)