]> git.codecow.com Git - nano25519.git/commitdiff
Overload conditional move of FieldElements for cleaner memory access.
authorChris Duncan <chris@codecow.com>
Fri, 21 Aug 2026 21:38:41 +0000 (14:38 -0700)
committerChris Duncan <chris@codecow.com>
Fri, 21 Aug 2026 21:38:41 +0000 (14:38 -0700)
src/assembly/fe.ts
src/assembly/ge.ts

index 06abed1072a144abdbeb5309dfe3025aa7d725de..a0c4e7f13684bfd1ac5b6782764c0ff23bab93c6 100644 (file)
@@ -76,19 +76,32 @@ export function fe_add (h: FieldElement, f: FieldElement, g: FieldElement): void
 /**
  * Conditionally copy values from one FieldElement to another.
  *
- * @param f FieldElement destination
- * @param g FieldElement source
- * @param b Copy `g` into `f` if 1, copy `f` into `f` if 0
+ * @param {usize} f FieldElement destination
+ * @param {usize} g FieldElement source
+ * @param {u64} b Copy `g` into `f` if 1, copy `f` into `f` if 0
  */
 //@ts-expect-error
 @inline
-export function fe_cmov (f: usize, g: usize, b: u64): void {
+export function fe_memcmov (f: usize, g: usize, b: u64): void {
        const c = v128.splat<u64>(0 - b)
        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<u64>(f, v128.bitselect(v128.load(g, 32), v128.load(f, 32), c), 0, 32)
 }
 
+/**
+ * Conditionally copy values from one FieldElement to another.
+ *
+ * @param {FieldElement} f destination
+ * @param {FieldElement} g source
+ * @param {u64} b Copy `g` into `f` if 1, copy `f` into `f` if 0
+ */
+//@ts-expect-error
+@inline
+export function fe_cmov (f: FieldElement, g: FieldElement, b: u64): void {
+       fe_memcmov(changetype<usize>(f), changetype<usize>(g), b)
+}
+
 /**
  * Copy values from one FieldElement to another.
  *
index 380245badf695c340bc45c626ab7dc4bfd116111..e7f5fc8722f93dd517b35b80d070d1e09d46fb8b 100644 (file)
 import { base } from './base'
 import { base2 } from './base2'
 import { ed25519_d, fe_sqrtm1 } from './constants'
-import { FieldElement, fe, fe_1, fe_add, fe_cmov, fe_frombytes, fe_isnegative, fe_iszero, fe_memcopy, fe_memneg, fe_mul, fe_neg, fe_pow22523, fe_sq, fe_sub } from './fe'
+import { FieldElement, fe, fe_1, fe_add, fe_cmov, fe_frombytes, fe_isnegative, fe_iszero, fe_memcmov, fe_memcopy, fe_memneg, fe_mul, fe_neg, fe_pow22523, fe_sq, fe_sub } from './fe'
 import { ge_add_cached, ge_add_precomp, ge_cached, ge_p1p1, ge_p1p1_to_p2, ge_p1p1_to_p3, ge_p2, ge_p2_0, ge_p2_dbl, ge_p2_to_p3, ge_p3, ge_p3_0, ge_p3_dbl, ge_p3_to_cached, ge_p3_tobytes, ge_precomp, ge_precomp_0, ge_sub_cached, ge_sub_precomp } from './p'
 import { equal, negative } from './utils'
 
 //@ts-expect-error
 @inline
 function ge_cmov (t: ge_precomp, u: usize, b: u8): void {
-       fe_cmov(changetype<usize>(t.yplusx), u, b)
-       fe_cmov(changetype<usize>(t.yminusx), u + 48, b)
-       fe_cmov(changetype<usize>(t.xy2d), u + 96, b)
+       fe_memcmov(changetype<usize>(t.yplusx), u, b)
+       fe_memcmov(changetype<usize>(t.yminusx), u + 48, b)
+       fe_memcmov(changetype<usize>(t.xy2d), u + 96, b)
 }
 
 const minust = changetype<usize>(new StaticArray<i32>(36))
@@ -130,10 +130,10 @@ export function ge_frombytes (h: ge_p3, s: StaticArray<u8>): 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(changetype<usize>(h.X), changetype<usize>(x_sqrtm1), 1 - has_m_root)
+       fe_cmov(h.X, x_sqrtm1, 1 - has_m_root)
 
        fe_neg(negx, h.X)
-       fe_cmov(changetype<usize>(h.X), changetype<usize>(negx), fe_isnegative(h.X) ^ (s[31] >> 7))
+       fe_cmov(h.X, 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