]> git.codecow.com Git - nano25519.git/commitdiff
Add field element doubling template.
authorChris Duncan <chris@codecow.com>
Wed, 30 Sep 2026 15:30:58 +0000 (08:30 -0700)
committerChris Duncan <chris@codecow.com>
Wed, 30 Sep 2026 15:30:58 +0000 (08:30 -0700)
scripts/fe.gen.mjs
src/assembly/ed25519/fe.ts

index 3f62a701012beea31ae886bf886a03d74239e7d3..5bd688b24d62d23f76d438bb38a3c817e03419bc 100644 (file)
@@ -32,6 +32,7 @@ export function fe_add (h, f, g) {
  * @param {string} h Variable name of FieldElement difference destination
  * @param {string} f Variable name of FieldElement minuend source
  * @param {string} g Variable name of FieldElement subtrahend source
+ * @returns {string} Three vector subtraction commands
  */
 export function fe_sub (h, f, g) {
        return `
@@ -42,6 +43,22 @@ export function fe_sub (h, f, g) {
 `
 }
 
+/**
+ * Add a FieldElement to itself and store the sum.
+ *
+ * @param {string} h Variable name of FieldElement sum destination
+ * @param {string} f Variable name of FieldElement summand source
+ * @returns {string} Three vector doubling commands
+ */
+export function fe_dbl (h, f) {
+       return `
+       // ${h} = 2*${f}
+       ${h}0 = v128.shl<i32>(${f}0, 1)
+       ${h}1 = v128.shl<i32>(${f}1, 1)
+       ${h}2 = v128.shl<i32>(${f}2, 1)
+`
+}
+
 export const FE = `//! SPDX-FileCopyrightText: 2026 Chris Duncan <chris@codecow.com>
 //! SPDX-License-Identifier: GPL-3.0-or-later
 /**
@@ -172,9 +189,19 @@ export function fe_copy (h: FieldElement, f: FieldElement): void {
 export function fe_dbl (h: FieldElement, f: FieldElement): void {
        const h_ptr = changetype<usize>(h)
        const f_ptr = changetype<usize>(f)
-       v128.store(h_ptr, v128.shl<i32>(v128.load(f_ptr, 0), 1), 0)
-       v128.store(h_ptr, v128.shl<i32>(v128.load(f_ptr, 16), 1), 16)
-       v128.store_lane<i64>(h_ptr, v128.shl<i32>(v128.load(f_ptr, 32), 1), 0, 32)
+
+       let h0: v128, h1: v128, h2: v128
+
+       let f0 = v128.load(f_ptr, 0)
+       let f1 = v128.load(f_ptr, 16)
+       let f2 = v128.load(f_ptr, 32)
+
+       ${fe_dbl('h', 'f')}
+
+       // store h
+       v128.store(h_ptr, h0, 0)
+       v128.store(h_ptr, h1, 16)
+       v128.store_lane<u64>(h_ptr, h2, 0, 32)
 }
 
 /**
index fc46ae7a2e5b484b15c67e9bb2f4498b390e3a99..93e443a0908443bcb80471b941948c5b4cbae654 100644 (file)
@@ -131,9 +131,22 @@ export function fe_copy (h: FieldElement, f: FieldElement): void {
 export function fe_dbl (h: FieldElement, f: FieldElement): void {
        const h_ptr = changetype<usize>(h)
        const f_ptr = changetype<usize>(f)
-       v128.store(h_ptr, v128.shl<i32>(v128.load(f_ptr, 0), 1), 0)
-       v128.store(h_ptr, v128.shl<i32>(v128.load(f_ptr, 16), 1), 16)
-       v128.store_lane<i64>(h_ptr, v128.shl<i32>(v128.load(f_ptr, 32), 1), 0, 32)
+
+       let h0: v128, h1: v128, h2: v128
+
+       let f0 = v128.load(f_ptr, 0)
+       let f1 = v128.load(f_ptr, 16)
+       let f2 = v128.load(f_ptr, 32)
+
+       // h = 2*f
+       h0 = v128.shl<i32>(f0, 1)
+       h1 = v128.shl<i32>(f1, 1)
+       h2 = v128.shl<i32>(f2, 1)
+
+       // store h
+       v128.store(h_ptr, h0, 0)
+       v128.store(h_ptr, h1, 16)
+       v128.store_lane<u64>(h_ptr, h2, 0, 32)
 }
 
 /**