From a9b96aa37ccca2fede045b1534fdb2e65b6045be Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Sun, 3 Aug 2025 03:44:40 -0700 Subject: [PATCH] Implement optimized square function for nacl. --- src/lib/nano-nacl.ts | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/lib/nano-nacl.ts b/src/lib/nano-nacl.ts index 789f52a..1840a11 100644 --- a/src/lib/nano-nacl.ts +++ b/src/lib/nano-nacl.ts @@ -139,7 +139,8 @@ export class NanoNaCl { } static Multiply (o: Float64Array, a: Float64Array, b: Float64Array): void { - let v, c, s = 1 << 16 + let v, c + const s = 1 << 16 const t = new Array(31) t.fill(0) @@ -178,7 +179,46 @@ export class NanoNaCl { } static Square (o: Float64Array, a: Float64Array): void { - this.Multiply(o, a, a) + let v, c + const s = 1 << 16 + const t = new Array(31) + t.fill(0) + + // init t values, same as Multiply except we can skip some iterations of + // the inner loop since a[x]*a[y] + a[y]*a[x] = 2*a[x]*a[y] + for (let i = 0; i < 16; i++) { + for (let j = i; j < 16; j++) { + //@ts-expect-error + t[i + j] += a[i] * a[j] * ((i < j) + 1) + } + } + + for (let i = 0; i < 15; i++) { + t[i] += 38 * t[i + 16] + } + // t15 left as is + + // first carry + c = 1 + for (let i = 0; i < 16; i++) { + v = t[i] + c + s - 1 + c = Math.floor(v / s) + t[i] = v - c * s + } + t[0] += 38 * (c - 1) + + // second carry + c = 1 + for (let i = 0; i < 16; i++) { + v = t[i] + c + s - 1 + c = Math.floor(v / s) + t[i] = v - c * s + } + t[0] += 38 * (c - 1) + + // assign result to output + o.set(t.slice(0, 16), 0) + // this.Multiply(o, a, a) } static inv25519 (o: Float64Array, i: Float64Array): void { -- 2.47.3