}\r
\r
static Multiply (o: Float64Array, a: Float64Array, b: Float64Array): void {\r
- let v, c, s = 1 << 16\r
+ let v, c\r
+ const s = 1 << 16\r
const t = new Array(31)\r
t.fill(0)\r
\r
}\r
\r
static Square (o: Float64Array, a: Float64Array): void {\r
- this.Multiply(o, a, a)\r
+ let v, c\r
+ const s = 1 << 16\r
+ const t = new Array(31)\r
+ t.fill(0)\r
+\r
+ // init t values, same as Multiply except we can skip some iterations of\r
+ // the inner loop since a[x]*a[y] + a[y]*a[x] = 2*a[x]*a[y]\r
+ for (let i = 0; i < 16; i++) {\r
+ for (let j = i; j < 16; j++) {\r
+ //@ts-expect-error\r
+ t[i + j] += a[i] * a[j] * ((i < j) + 1)\r
+ }\r
+ }\r
+\r
+ for (let i = 0; i < 15; i++) {\r
+ t[i] += 38 * t[i + 16]\r
+ }\r
+ // t15 left as is\r
+\r
+ // first carry\r
+ c = 1\r
+ for (let i = 0; i < 16; i++) {\r
+ v = t[i] + c + s - 1\r
+ c = Math.floor(v / s)\r
+ t[i] = v - c * s\r
+ }\r
+ t[0] += 38 * (c - 1)\r
+\r
+ // second carry\r
+ c = 1\r
+ for (let i = 0; i < 16; i++) {\r
+ v = t[i] + c + s - 1\r
+ c = Math.floor(v / s)\r
+ t[i] = v - c * s\r
+ }\r
+ t[0] += 38 * (c - 1)\r
+\r
+ // assign result to output\r
+ o.set(t.slice(0, 16), 0)\r
+ // this.Multiply(o, a, a)\r
}\r
\r
static inv25519 (o: Float64Array, i: Float64Array): void {\r