From: Chris Duncan Date: Thu, 1 Oct 2026 21:24:04 +0000 (-0700) Subject: Simplify some arithmetic. Fix documentation. X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=063c423ff7f34c4ed583c96d1f551c53ab73597f;p=nano25519.git Simplify some arithmetic. Fix documentation. --- diff --git a/src/assembly/ed25519/fe.ts b/src/assembly/ed25519/fe.ts index e157b1d..a1f30ee 100644 --- a/src/assembly/ed25519/fe.ts +++ b/src/assembly/ed25519/fe.ts @@ -52,7 +52,7 @@ export function fe_0 (h: FieldElement): void { @inline export function fe_1 (h: FieldElement): void { fe_0(h) - store(changetype(h), 1, 0) + h[0] = 1 } /** diff --git a/src/assembly/ed25519/ge.ts b/src/assembly/ed25519/ge.ts index 4032647..de3c2b7 100644 --- a/src/assembly/ed25519/ge.ts +++ b/src/assembly/ed25519/ge.ts @@ -94,38 +94,55 @@ const vxx: FieldElement = fe() const m_root_check: FieldElement = fe() const p_root_check: FieldElement = fe() /** - * @returns -1 if bytes fail to decode to a point, 0 if decoding is successful + * Variable-time point negation converted from byte representation. + * + * Compiler optimization of vartime function is OK. + * + * @returns {i32} 0 if `s` decodes to a valid point, else -1 */ export function ge_frombytes_negate_vartime (h: ge_p3, s: StaticArray): i32 { - fe_frombytes(h.Y, s) fe_1(h.Z) + fe_frombytes(h.Y, s) + + // u = y²-1 + // v = dy²+1 fe_sq(u, h.Y) fe_mul(v, u, ed25519_d) - fe_sub(u, u, h.Z) /* u = y^2-1 */ - fe_add(v, v, h.Z) /* v = dy^2+1 */ + u[0] -= 1 + v[0] += 1 + // v3 = v³ fe_sq(v3, v) - fe_mul(v3, v3, v) /* v3 = v^3 */ + fe_mul(v3, v3, v) + + // x = uv⁷ fe_sq(h.X, v3) fe_mul(h.X, h.X, v) - fe_mul(h.X, h.X, u) /* x = uv^7 */ + fe_mul(h.X, h.X, u) + + // x = (uv⁷)^((q-5)/8) + fe_pow22523(h.X, h.X) - fe_pow22523(h.X, h.X) /* x = (uv^7)^((q-5)/8) */ + // x = uv³((uv⁷)^((q-5)/8)) fe_mul(h.X, h.X, v3) - fe_mul(h.X, h.X, u) /* x = uv^3(uv^7)^((q-5)/8) */ + fe_mul(h.X, h.X, u) + // vxx = vx² fe_sq(vxx, h.X) fe_mul(vxx, vxx, v) - fe_sub(m_root_check, vxx, u) /* vx^2-u */ + + // m = vx²-u + fe_sub(m_root_check, vxx, u) if (fe_iszero(m_root_check) == 0) { - fe_add(p_root_check, vxx, u) /* vx^2+u */ + // p = vx²+u + fe_add(p_root_check, vxx, u) if (fe_iszero(p_root_check) == 0) { return -1 } fe_mul(h.X, h.X, fe_sqrtm1) } - if (fe_isnegative(h.X) == (s[31] >> 7)) { /* vartime function - compiler optimization is fine */ + if (fe_isnegative(h.X) == (s[31] >> 7)) { fe_neg(h.X, h.X) } fe_mul(h.T, h.X, h.Y) diff --git a/src/assembly/ed25519/p.ts b/src/assembly/ed25519/p.ts index 4d03627..c1a7abb 100644 --- a/src/assembly/ed25519/p.ts +++ b/src/assembly/ed25519/p.ts @@ -123,9 +123,6 @@ export function ge_p3_0 (h: ge_p3): void { const ge_p3_dbl_t: FieldElement = fe() /** * r = 2 * p - * - * p.T is used as the temporary holder for r.Y² because the parameter is unused - * hereafter at all call sites and it eliminates an extra `t` buffer. */ export function ge_p3_dbl (r: ge_p1p1, p: ge_p3): void { const t = ge_p3_dbl_t