From 02ab9dbc6c15d4a9ac057a54b6e1d743a517c5fc Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Wed, 30 Sep 2026 08:46:30 -0700 Subject: [PATCH] Implement generated output in place of hand-inlined calls. --- scripts/p.gen.mjs | 91 +++++++++++---------------------------- src/assembly/ed25519/p.ts | 73 +++++++++++++++++-------------- 2 files changed, 65 insertions(+), 99 deletions(-) diff --git a/scripts/p.gen.mjs b/scripts/p.gen.mjs index 04c63d8..25a3e4d 100644 --- a/scripts/p.gen.mjs +++ b/scripts/p.gen.mjs @@ -9,7 +9,7 @@ * AssemblyScript compiler and type checker. */ -import { fe_add, fe_sub } from './fe.gen.mjs' +import { fe_add, fe_dbl, fe_sub } from './fe.gen.mjs' export const P = `//! SPDX-FileCopyrightText: 2026 Chris Duncan //! SPDX-License-Identifier: GPL-3.0-or-later @@ -230,18 +230,13 @@ export function ge_add_cached (r: ge_p1p1, p: ge_p3, q: ge_cached): void { const pX_ptr = changetype(p.X) const pY_ptr = changetype(p.Y) + let rX0 = v128.load(rX_ptr), rX1 = v128.load(rX_ptr, 16), rX2 = v128.load(rX_ptr, 32) + let rY0 = v128.load(rY_ptr), rY1 = v128.load(rY_ptr, 16), rY2 = v128.load(rY_ptr, 32) let pX0 = v128.load(pX_ptr), pX1 = v128.load(pX_ptr, 16), pX2 = v128.load(pX_ptr, 32) let pY0 = v128.load(pY_ptr), pY1 = v128.load(pY_ptr, 16), pY2 = v128.load(pY_ptr, 32) - // fe_add(r.X, p.Y, p.X) - let rX0 = v128.add(pY0, pX0) - let rX1 = v128.add(pY1, pX1) - let rX2 = v128.add(pY2, pX2) - - // fe_sub(r.Y, p.Y, p.X) - let rY0 = v128.sub(pY0, pX0) - let rY1 = v128.sub(pY1, pX1) - let rY2 = v128.sub(pY2, pX2) + ${fe_add('rX', 'pY', 'pX')} + ${fe_sub('rY', 'pY', 'pX')} // store r.X v128.store(rX_ptr, rX0) @@ -264,31 +259,13 @@ export function ge_add_cached (r: ge_p1p1, p: ge_p3, q: ge_cached): void { rY0 = v128.load(rY_ptr), rY1 = v128.load(rY_ptr, 16), rY2 = v128.load(rY_ptr, 32) let rZ0 = v128.load(rZ_ptr), rZ1 = v128.load(rZ_ptr, 16), rZ2 = v128.load(rZ_ptr, 32) let rT0 = v128.load(rT_ptr), rT1 = v128.load(rT_ptr, 16), rT2 = v128.load(rT_ptr, 32) + let t0: v128, t1: v128, t2: v128 - // fe_dbl(t0, r.X) - const t0 = v128.shl(rX0, 1) - const t1 = v128.shl(rX1, 1) - const t2 = v128.shl(rX2, 1) - - // fe_sub(r.X, r.Z, r.Y) - rX0 = v128.sub(rZ0, rY0) - rX1 = v128.sub(rZ1, rY1) - rX2 = v128.sub(rZ2, rY2) - - // fe_add(r.Y, r.Z, r.Y) - rY0 = v128.add(rZ0, rY0) - rY1 = v128.add(rZ1, rY1) - rY2 = v128.add(rZ2, rY2) - - // fe_add(r.Z, t, r.T) - rZ0 = v128.add(t0, rT0) - rZ1 = v128.add(t1, rT1) - rZ2 = v128.add(t2, rT2) - - // fe_sub(r.T, t, r.T) - rT0 = v128.sub(t0, rT0) - rT1 = v128.sub(t1, rT1) - rT2 = v128.sub(t2, rT2) + ${fe_dbl('t', 'rX')} + ${fe_sub('rX', 'rZ', 'rY')} + ${fe_add('rY', 'rZ', 'rY')} + ${fe_add('rZ', 't', 'rT')} + ${fe_sub('rT', 't', 'rT')} // store r.X v128.store(rX_ptr, rX0) @@ -326,18 +303,13 @@ export function ge_add_precomp (r: ge_p1p1, p: ge_p3, q: ge_precomp): void { const pY_ptr = changetype(p.Y) const pZ_ptr = changetype(p.Z) + let rX0 = v128.load(rX_ptr), rX1 = v128.load(rX_ptr, 16), rX2 = v128.load(rX_ptr, 32) + let rY0 = v128.load(rY_ptr), rY1 = v128.load(rY_ptr, 16), rY2 = v128.load(rY_ptr, 32) const pX0 = v128.load(pX_ptr), pX1 = v128.load(pX_ptr, 16), pX2 = v128.load(pX_ptr, 32) const pY0 = v128.load(pY_ptr), pY1 = v128.load(pY_ptr, 16), pY2 = v128.load(pY_ptr, 32) - // fe_add(r.X, p.Y, p.X) - let rX0 = v128.add(pY0, pX0) - let rX1 = v128.add(pY1, pX1) - let rX2 = v128.add(pY2, pX2) - - // fe_sub(r.Y, p.Y, p.X) - let rY0 = v128.sub(pY0, pX0) - let rY1 = v128.sub(pY1, pX1) - let rY2 = v128.sub(pY2, pX2) + ${fe_add('rX', 'pY', 'pX')} + ${fe_sub('rY', 'pY', 'pX')} // store r.X v128.store(rX_ptr, rX0) @@ -360,30 +332,15 @@ export function ge_add_precomp (r: ge_p1p1, p: ge_p3, q: ge_precomp): void { let rZ0 = v128.load(rZ_ptr), rZ1 = v128.load(rZ_ptr, 16), rZ2 = v128.load(rZ_ptr, 32) let rT0 = v128.load(rT_ptr), rT1 = v128.load(rT_ptr, 16), rT2 = v128.load(rT_ptr, 32) - // fe_dbl(t, p.Z) - const pZ0 = v128.shl(v128.load(pZ_ptr), 1) - const pZ1 = v128.shl(v128.load(pZ_ptr, 16), 1) - const pZ2 = v128.shl(v128.load(pZ_ptr, 32), 1) - - // fe_sub(r.X, r.Z, r.Y) - rX0 = v128.sub(rZ0, rY0) - rX1 = v128.sub(rZ1, rY1) - rX2 = v128.sub(rZ2, rY2) - - // fe_add(r.Y, r.Z, r.Y) - rY0 = v128.add(rZ0, rY0) - rY1 = v128.add(rZ1, rY1) - rY2 = v128.add(rZ2, rY2) - - // fe_add(r.Z, t, r.T) - rZ0 = v128.add(pZ0, rT0) - rZ1 = v128.add(pZ1, rT1) - rZ2 = v128.add(pZ2, rT2) - - // fe_sub(r.T, t, r.T) - rT0 = v128.sub(pZ0, rT0) - rT1 = v128.sub(pZ1, rT1) - rT2 = v128.sub(pZ2, rT2) + let pZ0 = v128.load(pZ_ptr, 0) + let pZ1 = v128.load(pZ_ptr, 16) + let pZ2 = v128.load(pZ_ptr, 32) + + ${fe_dbl('pZ', 'pZ')} + ${fe_sub('rX', 'rZ', 'rY')} + ${fe_add('rY', 'rZ', 'rY')} + ${fe_add('rZ', 'pZ', 'rT')} + ${fe_sub('rT', 'pZ', 'rT')} // store r.X v128.store(rX_ptr, rX0) diff --git a/src/assembly/ed25519/p.ts b/src/assembly/ed25519/p.ts index d859aa6..0472a56 100644 --- a/src/assembly/ed25519/p.ts +++ b/src/assembly/ed25519/p.ts @@ -232,18 +232,20 @@ export function ge_add_cached (r: ge_p1p1, p: ge_p3, q: ge_cached): void { const pX_ptr = changetype(p.X) const pY_ptr = changetype(p.Y) + let rX0 = v128.load(rX_ptr), rX1 = v128.load(rX_ptr, 16), rX2 = v128.load(rX_ptr, 32) + let rY0 = v128.load(rY_ptr), rY1 = v128.load(rY_ptr, 16), rY2 = v128.load(rY_ptr, 32) let pX0 = v128.load(pX_ptr), pX1 = v128.load(pX_ptr, 16), pX2 = v128.load(pX_ptr, 32) let pY0 = v128.load(pY_ptr), pY1 = v128.load(pY_ptr, 16), pY2 = v128.load(pY_ptr, 32) - // fe_add(r.X, p.Y, p.X) - let rX0 = v128.add(pY0, pX0) - let rX1 = v128.add(pY1, pX1) - let rX2 = v128.add(pY2, pX2) + // rX = pY + pX + rX0 = v128.add(pY0, pX0) + rX1 = v128.add(pY1, pX1) + rX2 = v128.add(pY2, pX2) - // fe_sub(r.Y, p.Y, p.X) - let rY0 = v128.sub(pY0, pX0) - let rY1 = v128.sub(pY1, pX1) - let rY2 = v128.sub(pY2, pX2) + // rY = pY - pX + rY0 = v128.sub(pY0, pX0) + rY1 = v128.sub(pY1, pX1) + rY2 = v128.sub(pY2, pX2) // store r.X v128.store(rX_ptr, rX0) @@ -266,28 +268,29 @@ export function ge_add_cached (r: ge_p1p1, p: ge_p3, q: ge_cached): void { rY0 = v128.load(rY_ptr), rY1 = v128.load(rY_ptr, 16), rY2 = v128.load(rY_ptr, 32) let rZ0 = v128.load(rZ_ptr), rZ1 = v128.load(rZ_ptr, 16), rZ2 = v128.load(rZ_ptr, 32) let rT0 = v128.load(rT_ptr), rT1 = v128.load(rT_ptr, 16), rT2 = v128.load(rT_ptr, 32) + let t0: v128, t1: v128, t2: v128 - // fe_dbl(t0, r.X) - const t0 = v128.shl(rX0, 1) - const t1 = v128.shl(rX1, 1) - const t2 = v128.shl(rX2, 1) + // t = 2*rX + t0 = v128.shl(rX0, 1) + t1 = v128.shl(rX1, 1) + t2 = v128.shl(rX2, 1) - // fe_sub(r.X, r.Z, r.Y) + // rX = rZ - rY rX0 = v128.sub(rZ0, rY0) rX1 = v128.sub(rZ1, rY1) rX2 = v128.sub(rZ2, rY2) - // fe_add(r.Y, r.Z, r.Y) + // rY = rZ + rY rY0 = v128.add(rZ0, rY0) rY1 = v128.add(rZ1, rY1) rY2 = v128.add(rZ2, rY2) - // fe_add(r.Z, t, r.T) + // rZ = t + rT rZ0 = v128.add(t0, rT0) rZ1 = v128.add(t1, rT1) rZ2 = v128.add(t2, rT2) - // fe_sub(r.T, t, r.T) + // rT = t - rT rT0 = v128.sub(t0, rT0) rT1 = v128.sub(t1, rT1) rT2 = v128.sub(t2, rT2) @@ -328,18 +331,20 @@ export function ge_add_precomp (r: ge_p1p1, p: ge_p3, q: ge_precomp): void { const pY_ptr = changetype(p.Y) const pZ_ptr = changetype(p.Z) + let rX0 = v128.load(rX_ptr), rX1 = v128.load(rX_ptr, 16), rX2 = v128.load(rX_ptr, 32) + let rY0 = v128.load(rY_ptr), rY1 = v128.load(rY_ptr, 16), rY2 = v128.load(rY_ptr, 32) const pX0 = v128.load(pX_ptr), pX1 = v128.load(pX_ptr, 16), pX2 = v128.load(pX_ptr, 32) const pY0 = v128.load(pY_ptr), pY1 = v128.load(pY_ptr, 16), pY2 = v128.load(pY_ptr, 32) - // fe_add(r.X, p.Y, p.X) - let rX0 = v128.add(pY0, pX0) - let rX1 = v128.add(pY1, pX1) - let rX2 = v128.add(pY2, pX2) + // rX = pY + pX + rX0 = v128.add(pY0, pX0) + rX1 = v128.add(pY1, pX1) + rX2 = v128.add(pY2, pX2) - // fe_sub(r.Y, p.Y, p.X) - let rY0 = v128.sub(pY0, pX0) - let rY1 = v128.sub(pY1, pX1) - let rY2 = v128.sub(pY2, pX2) + // rY = pY - pX + rY0 = v128.sub(pY0, pX0) + rY1 = v128.sub(pY1, pX1) + rY2 = v128.sub(pY2, pX2) // store r.X v128.store(rX_ptr, rX0) @@ -362,27 +367,31 @@ export function ge_add_precomp (r: ge_p1p1, p: ge_p3, q: ge_precomp): void { let rZ0 = v128.load(rZ_ptr), rZ1 = v128.load(rZ_ptr, 16), rZ2 = v128.load(rZ_ptr, 32) let rT0 = v128.load(rT_ptr), rT1 = v128.load(rT_ptr, 16), rT2 = v128.load(rT_ptr, 32) - // fe_dbl(t, p.Z) - const pZ0 = v128.shl(v128.load(pZ_ptr), 1) - const pZ1 = v128.shl(v128.load(pZ_ptr, 16), 1) - const pZ2 = v128.shl(v128.load(pZ_ptr, 32), 1) + let pZ0 = v128.load(pZ_ptr, 0) + let pZ1 = v128.load(pZ_ptr, 16) + let pZ2 = v128.load(pZ_ptr, 32) + + // pZ = 2*pZ + pZ0 = v128.shl(pZ0, 1) + pZ1 = v128.shl(pZ1, 1) + pZ2 = v128.shl(pZ2, 1) - // fe_sub(r.X, r.Z, r.Y) + // rX = rZ - rY rX0 = v128.sub(rZ0, rY0) rX1 = v128.sub(rZ1, rY1) rX2 = v128.sub(rZ2, rY2) - // fe_add(r.Y, r.Z, r.Y) + // rY = rZ + rY rY0 = v128.add(rZ0, rY0) rY1 = v128.add(rZ1, rY1) rY2 = v128.add(rZ2, rY2) - // fe_add(r.Z, t, r.T) + // rZ = pZ + rT rZ0 = v128.add(pZ0, rT0) rZ1 = v128.add(pZ1, rT1) rZ2 = v128.add(pZ2, rT2) - // fe_sub(r.T, t, r.T) + // rT = pZ - rT rT0 = v128.sub(pZ0, rT0) rT1 = v128.sub(pZ1, rT1) rT2 = v128.sub(pZ2, rT2) -- 2.52.0