From: Chris Duncan Date: Fri, 21 Aug 2026 20:32:29 +0000 (-0700) Subject: Copy field elements by passing pointers instead of objects. X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=c1aaa9c59a6890a5b06d793cafc097e7a8ca2762;p=nano25519.git Copy field elements by passing pointers instead of objects. --- diff --git a/src/assembly/fe.ts b/src/assembly/fe.ts index fe45af8..e79f535 100644 --- a/src/assembly/fe.ts +++ b/src/assembly/fe.ts @@ -82,13 +82,11 @@ export function fe_add (h: FieldElement, f: FieldElement, g: FieldElement): void */ //@ts-expect-error @inline -export function fe_cmov (f: FieldElement, g: FieldElement, b: u64): void { - const f_ptr = changetype(f) - const g_ptr = changetype(g) +export function fe_cmov (f: usize, g: usize, b: u64): void { const c = v128.splat(0 - b) - v128.store(f_ptr, v128.bitselect(v128.load(g_ptr), v128.load(f_ptr, 0), c)) - v128.store(f_ptr, v128.bitselect(v128.load(g_ptr, 16), v128.load(f_ptr, 16), c), 16) - v128.store_lane(f_ptr, v128.bitselect(v128.load(g_ptr, 32), v128.load(f_ptr, 32), c), 0, 32) + v128.store(f, v128.bitselect(v128.load(g), v128.load(f, 0), c)) + v128.store(f, v128.bitselect(v128.load(g, 16), v128.load(f, 16), c), 16) + v128.store_lane(f, v128.bitselect(v128.load(g, 32), v128.load(f, 32), c), 0, 32) } /** diff --git a/src/assembly/ge.ts b/src/assembly/ge.ts index ca953a9..e02a9bc 100644 --- a/src/assembly/ge.ts +++ b/src/assembly/ge.ts @@ -26,12 +26,12 @@ import { equal, negative } from './utils' //@ts-expect-error @inline function ge_cmov (t: ge_precomp, u: ge_precomp, b: u8): void { - fe_cmov(t.yplusx, u.yplusx, b) - fe_cmov(t.yminusx, u.yminusx, b) - fe_cmov(t.xy2d, u.xy2d, b) + fe_cmov(changetype(t.yplusx), changetype(u.yplusx), b) + fe_cmov(changetype(t.yminusx), changetype(u.yminusx), b) + fe_cmov(changetype(t.xy2d), changetype(u.xy2d), b) } -const base_precomp: ge_precomp = new ge_precomp() +const p: ge_precomp = new ge_precomp() //@ts-expect-error @inline function ge_cmov8_base (t: ge_precomp, offset: i32, b: i8): void { @@ -41,16 +41,16 @@ function ge_cmov8_base (t: ge_precomp, offset: i32, b: i8): void { ge_precomp_0(t) for (let i = 0; i < 8; i++) { const baseptr = base + offset + (i * 144) // 4 bytes * 12 values * 3 fields - memory.copy(changetype(base_precomp.yplusx), baseptr, 48) - memory.copy(changetype(base_precomp.yminusx), baseptr + 48, 48) - memory.copy(changetype(base_precomp.xy2d), baseptr + 96, 48) - ge_cmov(t, base_precomp, equal(babs, i8(i + 1))) + memory.copy(changetype(p.yplusx), baseptr, 48) + memory.copy(changetype(p.yminusx), baseptr + 48, 48) + memory.copy(changetype(p.xy2d), baseptr + 96, 48) + ge_cmov(t, p, equal(babs, i8(i + 1))) } - fe_copy(base_precomp.yplusx, t.yminusx) - fe_copy(base_precomp.yminusx, t.yplusx) - fe_neg(base_precomp.xy2d, t.xy2d) - ge_cmov(t, base_precomp, bnegative) + fe_copy(p.yplusx, t.yminusx) + fe_copy(p.yminusx, t.yplusx) + fe_neg(p.xy2d, t.xy2d) + ge_cmov(t, p, bnegative) } const u: FieldElement = fe() @@ -132,10 +132,10 @@ export function ge_frombytes (h: ge_p3, s: StaticArray): i32 { has_m_root = fe_iszero(m_root_check) has_p_root = fe_iszero(p_root_check) fe_mul(x_sqrtm1, h.X, fe_sqrtm1) /* x*sqrt(-1) */ - fe_cmov(h.X, x_sqrtm1, 1 - has_m_root) + fe_cmov(changetype(h.X), changetype(x_sqrtm1), 1 - has_m_root) fe_neg(negx, h.X) - fe_cmov(h.X, negx, fe_isnegative(h.X) ^ (s[31] >> 7)) + fe_cmov(changetype(h.X), changetype(negx), fe_isnegative(h.X) ^ (s[31] >> 7)) fe_mul(h.T, h.X, h.Y) return i32(has_m_root | has_p_root) - 1