Spaces:
Sleeping
Sleeping
| /** | |
| * BLAKE3 Compression Function - Highly Optimized | |
| * | |
| * Optimization techniques applied (from Fleek Network case study): | |
| * 1. Use 16 SMI variables for state instead of TypedArray | |
| * 2. Use 16 SMI variables for message words | |
| * 3. Fully inlined G function (no function call overhead) | |
| * 4. Use `| 0` for integer coercion (forces V8 to use 32-bit ALU) | |
| * 5. Hardcoded permutation swaps using only 2 temporary variables | |
| * 6. Offset-based access pattern (avoid creating new views) | |
| * | |
| * The compression function takes: | |
| * - cv: 8-word chaining value | |
| * - block: 16-word message block (64 bytes) | |
| * - counter: 64-bit block counter | |
| * - blockLen: number of input bytes in this block | |
| * - flags: domain separation flags | |
| * | |
| * And outputs 8 or 16 words depending on whether this is a root node. | |
| */ | |
| /** | |
| * Compress a single block. | |
| * | |
| * This is the hot path - every optimization matters here. | |
| * | |
| * @param cv - Chaining value array | |
| * @param cvOff - Offset into cv | |
| * @param block - Message block words | |
| * @param blockOff - Offset into block | |
| * @param out - Output array (8 or 16 words) | |
| * @param outOff - Offset into out | |
| * @param full - If true, output all 16 words (for XOF); if false, output 8 words | |
| * @param counter - 64-bit block counter | |
| * @param blockLen - Number of bytes in this block (0-64) | |
| * @param flags - Domain separation flags | |
| */ | |
| export function compress( | |
| cv: Uint32Array, | |
| cvOff: number, | |
| block: Uint32Array, | |
| blockOff: number, | |
| out: Uint32Array, | |
| outOff: number, | |
| full: boolean, | |
| counter: number, | |
| blockLen: number, | |
| flags: number, | |
| ): void { | |
| // Load message words into SMI variables for maximum performance | |
| // V8 optimizes SMI arithmetic directly with the ALU | |
| let m0 = block[blockOff] | 0; | |
| let m1 = block[blockOff + 1] | 0; | |
| let m2 = block[blockOff + 2] | 0; | |
| let m3 = block[blockOff + 3] | 0; | |
| let m4 = block[blockOff + 4] | 0; | |
| let m5 = block[blockOff + 5] | 0; | |
| let m6 = block[blockOff + 6] | 0; | |
| let m7 = block[blockOff + 7] | 0; | |
| let m8 = block[blockOff + 8] | 0; | |
| let m9 = block[blockOff + 9] | 0; | |
| let m10 = block[blockOff + 10] | 0; | |
| let m11 = block[blockOff + 11] | 0; | |
| let m12 = block[blockOff + 12] | 0; | |
| let m13 = block[blockOff + 13] | 0; | |
| let m14 = block[blockOff + 14] | 0; | |
| let m15 = block[blockOff + 15] | 0; | |
| // Initialize state: first 8 words from chaining value | |
| let s0 = cv[cvOff] | 0; | |
| let s1 = cv[cvOff + 1] | 0; | |
| let s2 = cv[cvOff + 2] | 0; | |
| let s3 = cv[cvOff + 3] | 0; | |
| let s4 = cv[cvOff + 4] | 0; | |
| let s5 = cv[cvOff + 5] | 0; | |
| let s6 = cv[cvOff + 6] | 0; | |
| let s7 = cv[cvOff + 7] | 0; | |
| // Words 8-11: IV constants | |
| let s8 = 0x6a09e667; | |
| let s9 = 0xbb67ae85; | |
| let s10 = 0x3c6ef372; | |
| let s11 = 0xa54ff53a; | |
| // Words 12-15: counter, blockLen, flags | |
| // Note: counter is 64-bit, split into low and high 32-bit words | |
| let s12 = counter | 0; | |
| let s13 = (counter / 0x100000000) | 0; | |
| let s14 = blockLen | 0; | |
| let s15 = flags | 0; | |
| // ============================================================ | |
| // 7 rounds of mixing | |
| // Each round consists of 4 column G functions and 4 diagonal G functions | |
| // followed by a message word permutation (except for round 7) | |
| // ============================================================ | |
| // ROUND 1 (message schedule: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) | |
| // Column G functions | |
| // G(0, 4, 8, 12) with m0, m1 | |
| s0 = (((s0 + s4) | 0) + m0) | 0; | |
| s12 ^= s0; | |
| s12 = (s12 >>> 16) | (s12 << 16); | |
| s8 = (s8 + s12) | 0; | |
| s4 ^= s8; | |
| s4 = (s4 >>> 12) | (s4 << 20); | |
| s0 = (((s0 + s4) | 0) + m1) | 0; | |
| s12 ^= s0; | |
| s12 = (s12 >>> 8) | (s12 << 24); | |
| s8 = (s8 + s12) | 0; | |
| s4 ^= s8; | |
| s4 = (s4 >>> 7) | (s4 << 25); | |
| // G(1, 5, 9, 13) with m2, m3 | |
| s1 = (((s1 + s5) | 0) + m2) | 0; | |
| s13 ^= s1; | |
| s13 = (s13 >>> 16) | (s13 << 16); | |
| s9 = (s9 + s13) | 0; | |
| s5 ^= s9; | |
| s5 = (s5 >>> 12) | (s5 << 20); | |
| s1 = (((s1 + s5) | 0) + m3) | 0; | |
| s13 ^= s1; | |
| s13 = (s13 >>> 8) | (s13 << 24); | |
| s9 = (s9 + s13) | 0; | |
| s5 ^= s9; | |
| s5 = (s5 >>> 7) | (s5 << 25); | |
| // G(2, 6, 10, 14) with m4, m5 | |
| s2 = (((s2 + s6) | 0) + m4) | 0; | |
| s14 ^= s2; | |
| s14 = (s14 >>> 16) | (s14 << 16); | |
| s10 = (s10 + s14) | 0; | |
| s6 ^= s10; | |
| s6 = (s6 >>> 12) | (s6 << 20); | |
| s2 = (((s2 + s6) | 0) + m5) | 0; | |
| s14 ^= s2; | |
| s14 = (s14 >>> 8) | (s14 << 24); | |
| s10 = (s10 + s14) | 0; | |
| s6 ^= s10; | |
| s6 = (s6 >>> 7) | (s6 << 25); | |
| // G(3, 7, 11, 15) with m6, m7 | |
| s3 = (((s3 + s7) | 0) + m6) | 0; | |
| s15 ^= s3; | |
| s15 = (s15 >>> 16) | (s15 << 16); | |
| s11 = (s11 + s15) | 0; | |
| s7 ^= s11; | |
| s7 = (s7 >>> 12) | (s7 << 20); | |
| s3 = (((s3 + s7) | 0) + m7) | 0; | |
| s15 ^= s3; | |
| s15 = (s15 >>> 8) | (s15 << 24); | |
| s11 = (s11 + s15) | 0; | |
| s7 ^= s11; | |
| s7 = (s7 >>> 7) | (s7 << 25); | |
| // Diagonal G functions | |
| // G(0, 5, 10, 15) with m8, m9 | |
| s0 = (((s0 + s5) | 0) + m8) | 0; | |
| s15 ^= s0; | |
| s15 = (s15 >>> 16) | (s15 << 16); | |
| s10 = (s10 + s15) | 0; | |
| s5 ^= s10; | |
| s5 = (s5 >>> 12) | (s5 << 20); | |
| s0 = (((s0 + s5) | 0) + m9) | 0; | |
| s15 ^= s0; | |
| s15 = (s15 >>> 8) | (s15 << 24); | |
| s10 = (s10 + s15) | 0; | |
| s5 ^= s10; | |
| s5 = (s5 >>> 7) | (s5 << 25); | |
| // G(1, 6, 11, 12) with m10, m11 | |
| s1 = (((s1 + s6) | 0) + m10) | 0; | |
| s12 ^= s1; | |
| s12 = (s12 >>> 16) | (s12 << 16); | |
| s11 = (s11 + s12) | 0; | |
| s6 ^= s11; | |
| s6 = (s6 >>> 12) | (s6 << 20); | |
| s1 = (((s1 + s6) | 0) + m11) | 0; | |
| s12 ^= s1; | |
| s12 = (s12 >>> 8) | (s12 << 24); | |
| s11 = (s11 + s12) | 0; | |
| s6 ^= s11; | |
| s6 = (s6 >>> 7) | (s6 << 25); | |
| // G(2, 7, 8, 13) with m12, m13 | |
| s2 = (((s2 + s7) | 0) + m12) | 0; | |
| s13 ^= s2; | |
| s13 = (s13 >>> 16) | (s13 << 16); | |
| s8 = (s8 + s13) | 0; | |
| s7 ^= s8; | |
| s7 = (s7 >>> 12) | (s7 << 20); | |
| s2 = (((s2 + s7) | 0) + m13) | 0; | |
| s13 ^= s2; | |
| s13 = (s13 >>> 8) | (s13 << 24); | |
| s8 = (s8 + s13) | 0; | |
| s7 ^= s8; | |
| s7 = (s7 >>> 7) | (s7 << 25); | |
| // G(3, 4, 9, 14) with m14, m15 | |
| s3 = (((s3 + s4) | 0) + m14) | 0; | |
| s14 ^= s3; | |
| s14 = (s14 >>> 16) | (s14 << 16); | |
| s9 = (s9 + s14) | 0; | |
| s4 ^= s9; | |
| s4 = (s4 >>> 12) | (s4 << 20); | |
| s3 = (((s3 + s4) | 0) + m15) | 0; | |
| s14 ^= s3; | |
| s14 = (s14 >>> 8) | (s14 << 24); | |
| s9 = (s9 + s14) | 0; | |
| s4 ^= s9; | |
| s4 = (s4 >>> 7) | (s4 << 25); | |
| // Permute message words for round 2 | |
| // Permutation: [2,6,3,10,7,0,4,13,1,11,12,5,9,14,15,8] | |
| // Using 2 temps for the two cycles in the permutation | |
| { | |
| const t0 = m0, | |
| t1 = m1; | |
| m0 = m2; | |
| m2 = m3; | |
| m3 = m10; | |
| m10 = m12; | |
| m12 = m9; | |
| m9 = m11; | |
| m11 = m5; | |
| m5 = t0; | |
| m1 = m6; | |
| m6 = m4; | |
| m4 = m7; | |
| m7 = m13; | |
| m13 = m14; | |
| m14 = m15; | |
| m15 = m8; | |
| m8 = t1; | |
| } | |
| // ROUND 2 (message schedule: 2,6,3,10,7,0,4,13,1,11,12,5,9,14,15,8) | |
| s0 = (((s0 + s4) | 0) + m0) | 0; | |
| s12 ^= s0; | |
| s12 = (s12 >>> 16) | (s12 << 16); | |
| s8 = (s8 + s12) | 0; | |
| s4 ^= s8; | |
| s4 = (s4 >>> 12) | (s4 << 20); | |
| s0 = (((s0 + s4) | 0) + m1) | 0; | |
| s12 ^= s0; | |
| s12 = (s12 >>> 8) | (s12 << 24); | |
| s8 = (s8 + s12) | 0; | |
| s4 ^= s8; | |
| s4 = (s4 >>> 7) | (s4 << 25); | |
| s1 = (((s1 + s5) | 0) + m2) | 0; | |
| s13 ^= s1; | |
| s13 = (s13 >>> 16) | (s13 << 16); | |
| s9 = (s9 + s13) | 0; | |
| s5 ^= s9; | |
| s5 = (s5 >>> 12) | (s5 << 20); | |
| s1 = (((s1 + s5) | 0) + m3) | 0; | |
| s13 ^= s1; | |
| s13 = (s13 >>> 8) | (s13 << 24); | |
| s9 = (s9 + s13) | 0; | |
| s5 ^= s9; | |
| s5 = (s5 >>> 7) | (s5 << 25); | |
| s2 = (((s2 + s6) | 0) + m4) | 0; | |
| s14 ^= s2; | |
| s14 = (s14 >>> 16) | (s14 << 16); | |
| s10 = (s10 + s14) | 0; | |
| s6 ^= s10; | |
| s6 = (s6 >>> 12) | (s6 << 20); | |
| s2 = (((s2 + s6) | 0) + m5) | 0; | |
| s14 ^= s2; | |
| s14 = (s14 >>> 8) | (s14 << 24); | |
| s10 = (s10 + s14) | 0; | |
| s6 ^= s10; | |
| s6 = (s6 >>> 7) | (s6 << 25); | |
| s3 = (((s3 + s7) | 0) + m6) | 0; | |
| s15 ^= s3; | |
| s15 = (s15 >>> 16) | (s15 << 16); | |
| s11 = (s11 + s15) | 0; | |
| s7 ^= s11; | |
| s7 = (s7 >>> 12) | (s7 << 20); | |
| s3 = (((s3 + s7) | 0) + m7) | 0; | |
| s15 ^= s3; | |
| s15 = (s15 >>> 8) | (s15 << 24); | |
| s11 = (s11 + s15) | 0; | |
| s7 ^= s11; | |
| s7 = (s7 >>> 7) | (s7 << 25); | |
| s0 = (((s0 + s5) | 0) + m8) | 0; | |
| s15 ^= s0; | |
| s15 = (s15 >>> 16) | (s15 << 16); | |
| s10 = (s10 + s15) | 0; | |
| s5 ^= s10; | |
| s5 = (s5 >>> 12) | (s5 << 20); | |
| s0 = (((s0 + s5) | 0) + m9) | 0; | |
| s15 ^= s0; | |
| s15 = (s15 >>> 8) | (s15 << 24); | |
| s10 = (s10 + s15) | 0; | |
| s5 ^= s10; | |
| s5 = (s5 >>> 7) | (s5 << 25); | |
| s1 = (((s1 + s6) | 0) + m10) | 0; | |
| s12 ^= s1; | |
| s12 = (s12 >>> 16) | (s12 << 16); | |
| s11 = (s11 + s12) | 0; | |
| s6 ^= s11; | |
| s6 = (s6 >>> 12) | (s6 << 20); | |
| s1 = (((s1 + s6) | 0) + m11) | 0; | |
| s12 ^= s1; | |
| s12 = (s12 >>> 8) | (s12 << 24); | |
| s11 = (s11 + s12) | 0; | |
| s6 ^= s11; | |
| s6 = (s6 >>> 7) | (s6 << 25); | |
| s2 = (((s2 + s7) | 0) + m12) | 0; | |
| s13 ^= s2; | |
| s13 = (s13 >>> 16) | (s13 << 16); | |
| s8 = (s8 + s13) | 0; | |
| s7 ^= s8; | |
| s7 = (s7 >>> 12) | (s7 << 20); | |
| s2 = (((s2 + s7) | 0) + m13) | 0; | |
| s13 ^= s2; | |
| s13 = (s13 >>> 8) | (s13 << 24); | |
| s8 = (s8 + s13) | 0; | |
| s7 ^= s8; | |
| s7 = (s7 >>> 7) | (s7 << 25); | |
| s3 = (((s3 + s4) | 0) + m14) | 0; | |
| s14 ^= s3; | |
| s14 = (s14 >>> 16) | (s14 << 16); | |
| s9 = (s9 + s14) | 0; | |
| s4 ^= s9; | |
| s4 = (s4 >>> 12) | (s4 << 20); | |
| s3 = (((s3 + s4) | 0) + m15) | 0; | |
| s14 ^= s3; | |
| s14 = (s14 >>> 8) | (s14 << 24); | |
| s9 = (s9 + s14) | 0; | |
| s4 ^= s9; | |
| s4 = (s4 >>> 7) | (s4 << 25); | |
| // Permute for round 3 | |
| { | |
| const t0 = m0, | |
| t1 = m1; | |
| m0 = m2; | |
| m2 = m3; | |
| m3 = m10; | |
| m10 = m12; | |
| m12 = m9; | |
| m9 = m11; | |
| m11 = m5; | |
| m5 = t0; | |
| m1 = m6; | |
| m6 = m4; | |
| m4 = m7; | |
| m7 = m13; | |
| m13 = m14; | |
| m14 = m15; | |
| m15 = m8; | |
| m8 = t1; | |
| } | |
| // ROUND 3 (message schedule: 3,4,10,12,13,2,7,14,6,5,9,0,11,15,8,1) | |
| s0 = (((s0 + s4) | 0) + m0) | 0; | |
| s12 ^= s0; | |
| s12 = (s12 >>> 16) | (s12 << 16); | |
| s8 = (s8 + s12) | 0; | |
| s4 ^= s8; | |
| s4 = (s4 >>> 12) | (s4 << 20); | |
| s0 = (((s0 + s4) | 0) + m1) | 0; | |
| s12 ^= s0; | |
| s12 = (s12 >>> 8) | (s12 << 24); | |
| s8 = (s8 + s12) | 0; | |
| s4 ^= s8; | |
| s4 = (s4 >>> 7) | (s4 << 25); | |
| s1 = (((s1 + s5) | 0) + m2) | 0; | |
| s13 ^= s1; | |
| s13 = (s13 >>> 16) | (s13 << 16); | |
| s9 = (s9 + s13) | 0; | |
| s5 ^= s9; | |
| s5 = (s5 >>> 12) | (s5 << 20); | |
| s1 = (((s1 + s5) | 0) + m3) | 0; | |
| s13 ^= s1; | |
| s13 = (s13 >>> 8) | (s13 << 24); | |
| s9 = (s9 + s13) | 0; | |
| s5 ^= s9; | |
| s5 = (s5 >>> 7) | (s5 << 25); | |
| s2 = (((s2 + s6) | 0) + m4) | 0; | |
| s14 ^= s2; | |
| s14 = (s14 >>> 16) | (s14 << 16); | |
| s10 = (s10 + s14) | 0; | |
| s6 ^= s10; | |
| s6 = (s6 >>> 12) | (s6 << 20); | |
| s2 = (((s2 + s6) | 0) + m5) | 0; | |
| s14 ^= s2; | |
| s14 = (s14 >>> 8) | (s14 << 24); | |
| s10 = (s10 + s14) | 0; | |
| s6 ^= s10; | |
| s6 = (s6 >>> 7) | (s6 << 25); | |
| s3 = (((s3 + s7) | 0) + m6) | 0; | |
| s15 ^= s3; | |
| s15 = (s15 >>> 16) | (s15 << 16); | |
| s11 = (s11 + s15) | 0; | |
| s7 ^= s11; | |
| s7 = (s7 >>> 12) | (s7 << 20); | |
| s3 = (((s3 + s7) | 0) + m7) | 0; | |
| s15 ^= s3; | |
| s15 = (s15 >>> 8) | (s15 << 24); | |
| s11 = (s11 + s15) | 0; | |
| s7 ^= s11; | |
| s7 = (s7 >>> 7) | (s7 << 25); | |
| s0 = (((s0 + s5) | 0) + m8) | 0; | |
| s15 ^= s0; | |
| s15 = (s15 >>> 16) | (s15 << 16); | |
| s10 = (s10 + s15) | 0; | |
| s5 ^= s10; | |
| s5 = (s5 >>> 12) | (s5 << 20); | |
| s0 = (((s0 + s5) | 0) + m9) | 0; | |
| s15 ^= s0; | |
| s15 = (s15 >>> 8) | (s15 << 24); | |
| s10 = (s10 + s15) | 0; | |
| s5 ^= s10; | |
| s5 = (s5 >>> 7) | (s5 << 25); | |
| s1 = (((s1 + s6) | 0) + m10) | 0; | |
| s12 ^= s1; | |
| s12 = (s12 >>> 16) | (s12 << 16); | |
| s11 = (s11 + s12) | 0; | |
| s6 ^= s11; | |
| s6 = (s6 >>> 12) | (s6 << 20); | |
| s1 = (((s1 + s6) | 0) + m11) | 0; | |
| s12 ^= s1; | |
| s12 = (s12 >>> 8) | (s12 << 24); | |
| s11 = (s11 + s12) | 0; | |
| s6 ^= s11; | |
| s6 = (s6 >>> 7) | (s6 << 25); | |
| s2 = (((s2 + s7) | 0) + m12) | 0; | |
| s13 ^= s2; | |
| s13 = (s13 >>> 16) | (s13 << 16); | |
| s8 = (s8 + s13) | 0; | |
| s7 ^= s8; | |
| s7 = (s7 >>> 12) | (s7 << 20); | |
| s2 = (((s2 + s7) | 0) + m13) | 0; | |
| s13 ^= s2; | |
| s13 = (s13 >>> 8) | (s13 << 24); | |
| s8 = (s8 + s13) | 0; | |
| s7 ^= s8; | |
| s7 = (s7 >>> 7) | (s7 << 25); | |
| s3 = (((s3 + s4) | 0) + m14) | 0; | |
| s14 ^= s3; | |
| s14 = (s14 >>> 16) | (s14 << 16); | |
| s9 = (s9 + s14) | 0; | |
| s4 ^= s9; | |
| s4 = (s4 >>> 12) | (s4 << 20); | |
| s3 = (((s3 + s4) | 0) + m15) | 0; | |
| s14 ^= s3; | |
| s14 = (s14 >>> 8) | (s14 << 24); | |
| s9 = (s9 + s14) | 0; | |
| s4 ^= s9; | |
| s4 = (s4 >>> 7) | (s4 << 25); | |
| // Permute for round 4 | |
| { | |
| const t0 = m0, | |
| t1 = m1; | |
| m0 = m2; | |
| m2 = m3; | |
| m3 = m10; | |
| m10 = m12; | |
| m12 = m9; | |
| m9 = m11; | |
| m11 = m5; | |
| m5 = t0; | |
| m1 = m6; | |
| m6 = m4; | |
| m4 = m7; | |
| m7 = m13; | |
| m13 = m14; | |
| m14 = m15; | |
| m15 = m8; | |
| m8 = t1; | |
| } | |
| // ROUND 4 (message schedule: 10,7,12,9,14,3,13,15,4,0,11,2,5,8,1,6) | |
| s0 = (((s0 + s4) | 0) + m0) | 0; | |
| s12 ^= s0; | |
| s12 = (s12 >>> 16) | (s12 << 16); | |
| s8 = (s8 + s12) | 0; | |
| s4 ^= s8; | |
| s4 = (s4 >>> 12) | (s4 << 20); | |
| s0 = (((s0 + s4) | 0) + m1) | 0; | |
| s12 ^= s0; | |
| s12 = (s12 >>> 8) | (s12 << 24); | |
| s8 = (s8 + s12) | 0; | |
| s4 ^= s8; | |
| s4 = (s4 >>> 7) | (s4 << 25); | |
| s1 = (((s1 + s5) | 0) + m2) | 0; | |
| s13 ^= s1; | |
| s13 = (s13 >>> 16) | (s13 << 16); | |
| s9 = (s9 + s13) | 0; | |
| s5 ^= s9; | |
| s5 = (s5 >>> 12) | (s5 << 20); | |
| s1 = (((s1 + s5) | 0) + m3) | 0; | |
| s13 ^= s1; | |
| s13 = (s13 >>> 8) | (s13 << 24); | |
| s9 = (s9 + s13) | 0; | |
| s5 ^= s9; | |
| s5 = (s5 >>> 7) | (s5 << 25); | |
| s2 = (((s2 + s6) | 0) + m4) | 0; | |
| s14 ^= s2; | |
| s14 = (s14 >>> 16) | (s14 << 16); | |
| s10 = (s10 + s14) | 0; | |
| s6 ^= s10; | |
| s6 = (s6 >>> 12) | (s6 << 20); | |
| s2 = (((s2 + s6) | 0) + m5) | 0; | |
| s14 ^= s2; | |
| s14 = (s14 >>> 8) | (s14 << 24); | |
| s10 = (s10 + s14) | 0; | |
| s6 ^= s10; | |
| s6 = (s6 >>> 7) | (s6 << 25); | |
| s3 = (((s3 + s7) | 0) + m6) | 0; | |
| s15 ^= s3; | |
| s15 = (s15 >>> 16) | (s15 << 16); | |
| s11 = (s11 + s15) | 0; | |
| s7 ^= s11; | |
| s7 = (s7 >>> 12) | (s7 << 20); | |
| s3 = (((s3 + s7) | 0) + m7) | 0; | |
| s15 ^= s3; | |
| s15 = (s15 >>> 8) | (s15 << 24); | |
| s11 = (s11 + s15) | 0; | |
| s7 ^= s11; | |
| s7 = (s7 >>> 7) | (s7 << 25); | |
| s0 = (((s0 + s5) | 0) + m8) | 0; | |
| s15 ^= s0; | |
| s15 = (s15 >>> 16) | (s15 << 16); | |
| s10 = (s10 + s15) | 0; | |
| s5 ^= s10; | |
| s5 = (s5 >>> 12) | (s5 << 20); | |
| s0 = (((s0 + s5) | 0) + m9) | 0; | |
| s15 ^= s0; | |
| s15 = (s15 >>> 8) | (s15 << 24); | |
| s10 = (s10 + s15) | 0; | |
| s5 ^= s10; | |
| s5 = (s5 >>> 7) | (s5 << 25); | |
| s1 = (((s1 + s6) | 0) + m10) | 0; | |
| s12 ^= s1; | |
| s12 = (s12 >>> 16) | (s12 << 16); | |
| s11 = (s11 + s12) | 0; | |
| s6 ^= s11; | |
| s6 = (s6 >>> 12) | (s6 << 20); | |
| s1 = (((s1 + s6) | 0) + m11) | 0; | |
| s12 ^= s1; | |
| s12 = (s12 >>> 8) | (s12 << 24); | |
| s11 = (s11 + s12) | 0; | |
| s6 ^= s11; | |
| s6 = (s6 >>> 7) | (s6 << 25); | |
| s2 = (((s2 + s7) | 0) + m12) | 0; | |
| s13 ^= s2; | |
| s13 = (s13 >>> 16) | (s13 << 16); | |
| s8 = (s8 + s13) | 0; | |
| s7 ^= s8; | |
| s7 = (s7 >>> 12) | (s7 << 20); | |
| s2 = (((s2 + s7) | 0) + m13) | 0; | |
| s13 ^= s2; | |
| s13 = (s13 >>> 8) | (s13 << 24); | |
| s8 = (s8 + s13) | 0; | |
| s7 ^= s8; | |
| s7 = (s7 >>> 7) | (s7 << 25); | |
| s3 = (((s3 + s4) | 0) + m14) | 0; | |
| s14 ^= s3; | |
| s14 = (s14 >>> 16) | (s14 << 16); | |
| s9 = (s9 + s14) | 0; | |
| s4 ^= s9; | |
| s4 = (s4 >>> 12) | (s4 << 20); | |
| s3 = (((s3 + s4) | 0) + m15) | 0; | |
| s14 ^= s3; | |
| s14 = (s14 >>> 8) | (s14 << 24); | |
| s9 = (s9 + s14) | 0; | |
| s4 ^= s9; | |
| s4 = (s4 >>> 7) | (s4 << 25); | |
| // Permute for round 5 | |
| { | |
| const t0 = m0, | |
| t1 = m1; | |
| m0 = m2; | |
| m2 = m3; | |
| m3 = m10; | |
| m10 = m12; | |
| m12 = m9; | |
| m9 = m11; | |
| m11 = m5; | |
| m5 = t0; | |
| m1 = m6; | |
| m6 = m4; | |
| m4 = m7; | |
| m7 = m13; | |
| m13 = m14; | |
| m14 = m15; | |
| m15 = m8; | |
| m8 = t1; | |
| } | |
| // ROUND 5 (message schedule: 12,13,9,11,15,10,14,8,7,2,5,3,0,1,6,4) | |
| s0 = (((s0 + s4) | 0) + m0) | 0; | |
| s12 ^= s0; | |
| s12 = (s12 >>> 16) | (s12 << 16); | |
| s8 = (s8 + s12) | 0; | |
| s4 ^= s8; | |
| s4 = (s4 >>> 12) | (s4 << 20); | |
| s0 = (((s0 + s4) | 0) + m1) | 0; | |
| s12 ^= s0; | |
| s12 = (s12 >>> 8) | (s12 << 24); | |
| s8 = (s8 + s12) | 0; | |
| s4 ^= s8; | |
| s4 = (s4 >>> 7) | (s4 << 25); | |
| s1 = (((s1 + s5) | 0) + m2) | 0; | |
| s13 ^= s1; | |
| s13 = (s13 >>> 16) | (s13 << 16); | |
| s9 = (s9 + s13) | 0; | |
| s5 ^= s9; | |
| s5 = (s5 >>> 12) | (s5 << 20); | |
| s1 = (((s1 + s5) | 0) + m3) | 0; | |
| s13 ^= s1; | |
| s13 = (s13 >>> 8) | (s13 << 24); | |
| s9 = (s9 + s13) | 0; | |
| s5 ^= s9; | |
| s5 = (s5 >>> 7) | (s5 << 25); | |
| s2 = (((s2 + s6) | 0) + m4) | 0; | |
| s14 ^= s2; | |
| s14 = (s14 >>> 16) | (s14 << 16); | |
| s10 = (s10 + s14) | 0; | |
| s6 ^= s10; | |
| s6 = (s6 >>> 12) | (s6 << 20); | |
| s2 = (((s2 + s6) | 0) + m5) | 0; | |
| s14 ^= s2; | |
| s14 = (s14 >>> 8) | (s14 << 24); | |
| s10 = (s10 + s14) | 0; | |
| s6 ^= s10; | |
| s6 = (s6 >>> 7) | (s6 << 25); | |
| s3 = (((s3 + s7) | 0) + m6) | 0; | |
| s15 ^= s3; | |
| s15 = (s15 >>> 16) | (s15 << 16); | |
| s11 = (s11 + s15) | 0; | |
| s7 ^= s11; | |
| s7 = (s7 >>> 12) | (s7 << 20); | |
| s3 = (((s3 + s7) | 0) + m7) | 0; | |
| s15 ^= s3; | |
| s15 = (s15 >>> 8) | (s15 << 24); | |
| s11 = (s11 + s15) | 0; | |
| s7 ^= s11; | |
| s7 = (s7 >>> 7) | (s7 << 25); | |
| s0 = (((s0 + s5) | 0) + m8) | 0; | |
| s15 ^= s0; | |
| s15 = (s15 >>> 16) | (s15 << 16); | |
| s10 = (s10 + s15) | 0; | |
| s5 ^= s10; | |
| s5 = (s5 >>> 12) | (s5 << 20); | |
| s0 = (((s0 + s5) | 0) + m9) | 0; | |
| s15 ^= s0; | |
| s15 = (s15 >>> 8) | (s15 << 24); | |
| s10 = (s10 + s15) | 0; | |
| s5 ^= s10; | |
| s5 = (s5 >>> 7) | (s5 << 25); | |
| s1 = (((s1 + s6) | 0) + m10) | 0; | |
| s12 ^= s1; | |
| s12 = (s12 >>> 16) | (s12 << 16); | |
| s11 = (s11 + s12) | 0; | |
| s6 ^= s11; | |
| s6 = (s6 >>> 12) | (s6 << 20); | |
| s1 = (((s1 + s6) | 0) + m11) | 0; | |
| s12 ^= s1; | |
| s12 = (s12 >>> 8) | (s12 << 24); | |
| s11 = (s11 + s12) | 0; | |
| s6 ^= s11; | |
| s6 = (s6 >>> 7) | (s6 << 25); | |
| s2 = (((s2 + s7) | 0) + m12) | 0; | |
| s13 ^= s2; | |
| s13 = (s13 >>> 16) | (s13 << 16); | |
| s8 = (s8 + s13) | 0; | |
| s7 ^= s8; | |
| s7 = (s7 >>> 12) | (s7 << 20); | |
| s2 = (((s2 + s7) | 0) + m13) | 0; | |
| s13 ^= s2; | |
| s13 = (s13 >>> 8) | (s13 << 24); | |
| s8 = (s8 + s13) | 0; | |
| s7 ^= s8; | |
| s7 = (s7 >>> 7) | (s7 << 25); | |
| s3 = (((s3 + s4) | 0) + m14) | 0; | |
| s14 ^= s3; | |
| s14 = (s14 >>> 16) | (s14 << 16); | |
| s9 = (s9 + s14) | 0; | |
| s4 ^= s9; | |
| s4 = (s4 >>> 12) | (s4 << 20); | |
| s3 = (((s3 + s4) | 0) + m15) | 0; | |
| s14 ^= s3; | |
| s14 = (s14 >>> 8) | (s14 << 24); | |
| s9 = (s9 + s14) | 0; | |
| s4 ^= s9; | |
| s4 = (s4 >>> 7) | (s4 << 25); | |
| // Permute for round 6 | |
| { | |
| const t0 = m0, | |
| t1 = m1; | |
| m0 = m2; | |
| m2 = m3; | |
| m3 = m10; | |
| m10 = m12; | |
| m12 = m9; | |
| m9 = m11; | |
| m11 = m5; | |
| m5 = t0; | |
| m1 = m6; | |
| m6 = m4; | |
| m4 = m7; | |
| m7 = m13; | |
| m13 = m14; | |
| m14 = m15; | |
| m15 = m8; | |
| m8 = t1; | |
| } | |
| // ROUND 6 (message schedule: 9,14,11,5,8,12,15,1,13,3,0,10,2,6,4,7) | |
| s0 = (((s0 + s4) | 0) + m0) | 0; | |
| s12 ^= s0; | |
| s12 = (s12 >>> 16) | (s12 << 16); | |
| s8 = (s8 + s12) | 0; | |
| s4 ^= s8; | |
| s4 = (s4 >>> 12) | (s4 << 20); | |
| s0 = (((s0 + s4) | 0) + m1) | 0; | |
| s12 ^= s0; | |
| s12 = (s12 >>> 8) | (s12 << 24); | |
| s8 = (s8 + s12) | 0; | |
| s4 ^= s8; | |
| s4 = (s4 >>> 7) | (s4 << 25); | |
| s1 = (((s1 + s5) | 0) + m2) | 0; | |
| s13 ^= s1; | |
| s13 = (s13 >>> 16) | (s13 << 16); | |
| s9 = (s9 + s13) | 0; | |
| s5 ^= s9; | |
| s5 = (s5 >>> 12) | (s5 << 20); | |
| s1 = (((s1 + s5) | 0) + m3) | 0; | |
| s13 ^= s1; | |
| s13 = (s13 >>> 8) | (s13 << 24); | |
| s9 = (s9 + s13) | 0; | |
| s5 ^= s9; | |
| s5 = (s5 >>> 7) | (s5 << 25); | |
| s2 = (((s2 + s6) | 0) + m4) | 0; | |
| s14 ^= s2; | |
| s14 = (s14 >>> 16) | (s14 << 16); | |
| s10 = (s10 + s14) | 0; | |
| s6 ^= s10; | |
| s6 = (s6 >>> 12) | (s6 << 20); | |
| s2 = (((s2 + s6) | 0) + m5) | 0; | |
| s14 ^= s2; | |
| s14 = (s14 >>> 8) | (s14 << 24); | |
| s10 = (s10 + s14) | 0; | |
| s6 ^= s10; | |
| s6 = (s6 >>> 7) | (s6 << 25); | |
| s3 = (((s3 + s7) | 0) + m6) | 0; | |
| s15 ^= s3; | |
| s15 = (s15 >>> 16) | (s15 << 16); | |
| s11 = (s11 + s15) | 0; | |
| s7 ^= s11; | |
| s7 = (s7 >>> 12) | (s7 << 20); | |
| s3 = (((s3 + s7) | 0) + m7) | 0; | |
| s15 ^= s3; | |
| s15 = (s15 >>> 8) | (s15 << 24); | |
| s11 = (s11 + s15) | 0; | |
| s7 ^= s11; | |
| s7 = (s7 >>> 7) | (s7 << 25); | |
| s0 = (((s0 + s5) | 0) + m8) | 0; | |
| s15 ^= s0; | |
| s15 = (s15 >>> 16) | (s15 << 16); | |
| s10 = (s10 + s15) | 0; | |
| s5 ^= s10; | |
| s5 = (s5 >>> 12) | (s5 << 20); | |
| s0 = (((s0 + s5) | 0) + m9) | 0; | |
| s15 ^= s0; | |
| s15 = (s15 >>> 8) | (s15 << 24); | |
| s10 = (s10 + s15) | 0; | |
| s5 ^= s10; | |
| s5 = (s5 >>> 7) | (s5 << 25); | |
| s1 = (((s1 + s6) | 0) + m10) | 0; | |
| s12 ^= s1; | |
| s12 = (s12 >>> 16) | (s12 << 16); | |
| s11 = (s11 + s12) | 0; | |
| s6 ^= s11; | |
| s6 = (s6 >>> 12) | (s6 << 20); | |
| s1 = (((s1 + s6) | 0) + m11) | 0; | |
| s12 ^= s1; | |
| s12 = (s12 >>> 8) | (s12 << 24); | |
| s11 = (s11 + s12) | 0; | |
| s6 ^= s11; | |
| s6 = (s6 >>> 7) | (s6 << 25); | |
| s2 = (((s2 + s7) | 0) + m12) | 0; | |
| s13 ^= s2; | |
| s13 = (s13 >>> 16) | (s13 << 16); | |
| s8 = (s8 + s13) | 0; | |
| s7 ^= s8; | |
| s7 = (s7 >>> 12) | (s7 << 20); | |
| s2 = (((s2 + s7) | 0) + m13) | 0; | |
| s13 ^= s2; | |
| s13 = (s13 >>> 8) | (s13 << 24); | |
| s8 = (s8 + s13) | 0; | |
| s7 ^= s8; | |
| s7 = (s7 >>> 7) | (s7 << 25); | |
| s3 = (((s3 + s4) | 0) + m14) | 0; | |
| s14 ^= s3; | |
| s14 = (s14 >>> 16) | (s14 << 16); | |
| s9 = (s9 + s14) | 0; | |
| s4 ^= s9; | |
| s4 = (s4 >>> 12) | (s4 << 20); | |
| s3 = (((s3 + s4) | 0) + m15) | 0; | |
| s14 ^= s3; | |
| s14 = (s14 >>> 8) | (s14 << 24); | |
| s9 = (s9 + s14) | 0; | |
| s4 ^= s9; | |
| s4 = (s4 >>> 7) | (s4 << 25); | |
| // Permute for round 7 | |
| { | |
| const t0 = m0, | |
| t1 = m1; | |
| m0 = m2; | |
| m2 = m3; | |
| m3 = m10; | |
| m10 = m12; | |
| m12 = m9; | |
| m9 = m11; | |
| m11 = m5; | |
| m5 = t0; | |
| m1 = m6; | |
| m6 = m4; | |
| m4 = m7; | |
| m7 = m13; | |
| m13 = m14; | |
| m14 = m15; | |
| m15 = m8; | |
| m8 = t1; | |
| } | |
| // ROUND 7 (message schedule: 11,15,5,0,1,9,8,6,14,10,2,12,3,4,7,13) | |
| s0 = (((s0 + s4) | 0) + m0) | 0; | |
| s12 ^= s0; | |
| s12 = (s12 >>> 16) | (s12 << 16); | |
| s8 = (s8 + s12) | 0; | |
| s4 ^= s8; | |
| s4 = (s4 >>> 12) | (s4 << 20); | |
| s0 = (((s0 + s4) | 0) + m1) | 0; | |
| s12 ^= s0; | |
| s12 = (s12 >>> 8) | (s12 << 24); | |
| s8 = (s8 + s12) | 0; | |
| s4 ^= s8; | |
| s4 = (s4 >>> 7) | (s4 << 25); | |
| s1 = (((s1 + s5) | 0) + m2) | 0; | |
| s13 ^= s1; | |
| s13 = (s13 >>> 16) | (s13 << 16); | |
| s9 = (s9 + s13) | 0; | |
| s5 ^= s9; | |
| s5 = (s5 >>> 12) | (s5 << 20); | |
| s1 = (((s1 + s5) | 0) + m3) | 0; | |
| s13 ^= s1; | |
| s13 = (s13 >>> 8) | (s13 << 24); | |
| s9 = (s9 + s13) | 0; | |
| s5 ^= s9; | |
| s5 = (s5 >>> 7) | (s5 << 25); | |
| s2 = (((s2 + s6) | 0) + m4) | 0; | |
| s14 ^= s2; | |
| s14 = (s14 >>> 16) | (s14 << 16); | |
| s10 = (s10 + s14) | 0; | |
| s6 ^= s10; | |
| s6 = (s6 >>> 12) | (s6 << 20); | |
| s2 = (((s2 + s6) | 0) + m5) | 0; | |
| s14 ^= s2; | |
| s14 = (s14 >>> 8) | (s14 << 24); | |
| s10 = (s10 + s14) | 0; | |
| s6 ^= s10; | |
| s6 = (s6 >>> 7) | (s6 << 25); | |
| s3 = (((s3 + s7) | 0) + m6) | 0; | |
| s15 ^= s3; | |
| s15 = (s15 >>> 16) | (s15 << 16); | |
| s11 = (s11 + s15) | 0; | |
| s7 ^= s11; | |
| s7 = (s7 >>> 12) | (s7 << 20); | |
| s3 = (((s3 + s7) | 0) + m7) | 0; | |
| s15 ^= s3; | |
| s15 = (s15 >>> 8) | (s15 << 24); | |
| s11 = (s11 + s15) | 0; | |
| s7 ^= s11; | |
| s7 = (s7 >>> 7) | (s7 << 25); | |
| s0 = (((s0 + s5) | 0) + m8) | 0; | |
| s15 ^= s0; | |
| s15 = (s15 >>> 16) | (s15 << 16); | |
| s10 = (s10 + s15) | 0; | |
| s5 ^= s10; | |
| s5 = (s5 >>> 12) | (s5 << 20); | |
| s0 = (((s0 + s5) | 0) + m9) | 0; | |
| s15 ^= s0; | |
| s15 = (s15 >>> 8) | (s15 << 24); | |
| s10 = (s10 + s15) | 0; | |
| s5 ^= s10; | |
| s5 = (s5 >>> 7) | (s5 << 25); | |
| s1 = (((s1 + s6) | 0) + m10) | 0; | |
| s12 ^= s1; | |
| s12 = (s12 >>> 16) | (s12 << 16); | |
| s11 = (s11 + s12) | 0; | |
| s6 ^= s11; | |
| s6 = (s6 >>> 12) | (s6 << 20); | |
| s1 = (((s1 + s6) | 0) + m11) | 0; | |
| s12 ^= s1; | |
| s12 = (s12 >>> 8) | (s12 << 24); | |
| s11 = (s11 + s12) | 0; | |
| s6 ^= s11; | |
| s6 = (s6 >>> 7) | (s6 << 25); | |
| s2 = (((s2 + s7) | 0) + m12) | 0; | |
| s13 ^= s2; | |
| s13 = (s13 >>> 16) | (s13 << 16); | |
| s8 = (s8 + s13) | 0; | |
| s7 ^= s8; | |
| s7 = (s7 >>> 12) | (s7 << 20); | |
| s2 = (((s2 + s7) | 0) + m13) | 0; | |
| s13 ^= s2; | |
| s13 = (s13 >>> 8) | (s13 << 24); | |
| s8 = (s8 + s13) | 0; | |
| s7 ^= s8; | |
| s7 = (s7 >>> 7) | (s7 << 25); | |
| s3 = (((s3 + s4) | 0) + m14) | 0; | |
| s14 ^= s3; | |
| s14 = (s14 >>> 16) | (s14 << 16); | |
| s9 = (s9 + s14) | 0; | |
| s4 ^= s9; | |
| s4 = (s4 >>> 12) | (s4 << 20); | |
| s3 = (((s3 + s4) | 0) + m15) | 0; | |
| s14 ^= s3; | |
| s14 = (s14 >>> 8) | (s14 << 24); | |
| s9 = (s9 + s14) | 0; | |
| s4 ^= s9; | |
| s4 = (s4 >>> 7) | (s4 << 25); | |
| // ============================================================ | |
| // Final XOR and output | |
| // ============================================================ | |
| // If full output needed (XOF mode), write words 8-15 first | |
| // (written first in case out === cv) | |
| if (full) { | |
| out[outOff + 8] = s8 ^ cv[cvOff]; | |
| out[outOff + 9] = s9 ^ cv[cvOff + 1]; | |
| out[outOff + 10] = s10 ^ cv[cvOff + 2]; | |
| out[outOff + 11] = s11 ^ cv[cvOff + 3]; | |
| out[outOff + 12] = s12 ^ cv[cvOff + 4]; | |
| out[outOff + 13] = s13 ^ cv[cvOff + 5]; | |
| out[outOff + 14] = s14 ^ cv[cvOff + 6]; | |
| out[outOff + 15] = s15 ^ cv[cvOff + 7]; | |
| } | |
| // Standard output: XOR state[0..7] with state[8..15] | |
| out[outOff] = s0 ^ s8; | |
| out[outOff + 1] = s1 ^ s9; | |
| out[outOff + 2] = s2 ^ s10; | |
| out[outOff + 3] = s3 ^ s11; | |
| out[outOff + 4] = s4 ^ s12; | |
| out[outOff + 5] = s5 ^ s13; | |
| out[outOff + 6] = s6 ^ s14; | |
| out[outOff + 7] = s7 ^ s15; | |
| } | |