From 1cbc9e094eae458ff83b0a59c33a929520c51a63 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Wed, 14 Oct 2020 20:17:08 +0200
Subject: [PATCH] Shared implementation of ecc_mod_pow_2k and related functions

---
 ChangeLog        | 10 ++++++++++
 ecc-curve25519.c | 27 ---------------------------
 ecc-curve448.c   | 35 -----------------------------------
 ecc-internal.h   | 20 ++++++++++++++++++++
 ecc-mod-arith.c  | 38 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 68 insertions(+), 62 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 15d72b5e..983078a6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2020-10-14  Niels Möller  <nisse@lysator.liu.se>
+
+	* ecc-mod-arith.c (ecc_mod_pow_2k, ecc_mod_pow_2k_mul): Moved
+	functions here.
+	* ecc-internal.h (ecc_mod_pow_2kp1): New macro, calling the more
+	general ecc_mod_pow_2k_mul.
+	* ecc-curve25519.c (ecc_mod_pow_2kp1): Deleted static function.
+	* ecc-curve448.c (ecc_mod_pow_2k, ecc_mod_pow_2kp1): Deleted
+	static functions.
+
 2020-10-13  Niels Möller  <nisse@lysator.liu.se>
 
 	* ecc-mod-inv.c (ecc_mod_inv_destructive): New helper function,
diff --git a/ecc-curve25519.c b/ecc-curve25519.c
index f8f2c64a..60ef0540 100644
--- a/ecc-curve25519.c
+++ b/ecc-curve25519.c
@@ -100,33 +100,6 @@ ecc_curve25519_modq (const struct ecc_modulo *q, mp_limb_t *rp)
   cnd_add_n (cy, rp, q->m, ECC_LIMB_SIZE);
 }
 
-/* Needs 2*ecc->size limbs at rp, and 2*ecc->size additional limbs of
-   scratch space. No overlap allowed. */
-static void
-ecc_mod_pow_2kp1 (const struct ecc_modulo *m,
-		  mp_limb_t *rp, const mp_limb_t *xp,
-		  unsigned k, mp_limb_t *tp)
-{
-  if (k & 1)
-    {
-      ecc_mod_sqr (m, tp, xp);
-      k--;
-    }
-  else
-    {
-      ecc_mod_sqr (m, rp, xp);
-      ecc_mod_sqr (m, tp, rp);
-      k -= 2;
-    }
-  while (k > 0)
-    {
-      ecc_mod_sqr (m, rp, tp);
-      ecc_mod_sqr (m, tp, rp);
-      k -= 2;
-    }
-  ecc_mod_mul (m, rp, tp, xp);
-}
-
 /* Computes a^{(p-5)/8} = a^{2^{252}-3} mod m. Needs 5 * n scratch
    space. */
 static void
diff --git a/ecc-curve448.c b/ecc-curve448.c
index 484b7d1e..729ce985 100644
--- a/ecc-curve448.c
+++ b/ecc-curve448.c
@@ -98,41 +98,6 @@ ecc_curve448_modp(const struct ecc_modulo *m, mp_limb_t *rp)
 #define ecc_curve448_modp ecc_mod
 #endif
 
-/* Needs 2*ecc->size limbs at rp, and 2*ecc->size additional limbs of
-   scratch space. No overlap allowed. */
-static void
-ecc_mod_pow_2k (const struct ecc_modulo *m,
-		mp_limb_t *rp, const mp_limb_t *xp,
-		unsigned k, mp_limb_t *tp)
-{
-  if (k & 1)
-    {
-      ecc_mod_sqr (m, rp, xp);
-      k--;
-    }
-  else
-    {
-      ecc_mod_sqr (m, tp, xp);
-      ecc_mod_sqr (m, rp, tp);
-      k -= 2;
-    }
-  while (k > 0)
-    {
-      ecc_mod_sqr (m, tp, rp);
-      ecc_mod_sqr (m, rp, tp);
-      k -= 2;
-    }
-}
-
-static void
-ecc_mod_pow_2kp1 (const struct ecc_modulo *m,
-		  mp_limb_t *rp, const mp_limb_t *xp,
-		  unsigned k, mp_limb_t *tp)
-{
-  ecc_mod_pow_2k (m, tp, xp, k, rp);
-  ecc_mod_mul (m, rp, tp, xp);
-}
-
 /* Computes a^{(p-3)/4} = a^{2^446-2^222-1} mod m. Needs 5 * n scratch
    space. */
 static void
diff --git a/ecc-internal.h b/ecc-internal.h
index 8ef4276b..3082917b 100644
--- a/ecc-internal.h
+++ b/ecc-internal.h
@@ -49,6 +49,8 @@
 #define ecc_mod_submul_1 _nettle_ecc_mod_submul_1
 #define ecc_mod_mul _nettle_ecc_mod_mul
 #define ecc_mod_sqr _nettle_ecc_mod_sqr
+#define ecc_mod_pow_2k _nettle_ecc_mod_pow_2k
+#define ecc_mod_pow_2k_mul _nettle_ecc_mod_pow_2k_mul
 #define ecc_mod_random _nettle_ecc_mod_random
 #define ecc_mod _nettle_ecc_mod
 #define ecc_mod_inv _nettle_ecc_mod_inv
@@ -260,6 +262,24 @@ void
 ecc_mod_sqr (const struct ecc_modulo *m, mp_limb_t *rp,
 	     const mp_limb_t *ap);
 
+/* The pow functions needs 2*m->size limbs at both rp and tp. */
+/* R <-- X^{2^k} */
+void
+ecc_mod_pow_2k (const struct ecc_modulo *m,
+		mp_limb_t *rp, const mp_limb_t *xp,
+		unsigned k, mp_limb_t *tp);
+
+/* R <-- X^{2^k} Y  */
+void
+ecc_mod_pow_2k_mul (const struct ecc_modulo *m,
+		    mp_limb_t *rp, const mp_limb_t *xp,
+		    unsigned k, const mp_limb_t *yp,
+		    mp_limb_t *tp);
+
+/* R <-- X^{2^k + 1} */
+#define ecc_mod_pow_2kp1(m, rp, xp, k, tp) \
+  ecc_mod_pow_2k_mul (m, rp, xp, k, xp, tp)
+
 /* mod q operations. */
 void
 ecc_mod_random (const struct ecc_modulo *m, mp_limb_t *xp,
diff --git a/ecc-mod-arith.c b/ecc-mod-arith.c
index f2e47f67..0b315552 100644
--- a/ecc-mod-arith.c
+++ b/ecc-mod-arith.c
@@ -125,3 +125,41 @@ ecc_mod_sqr (const struct ecc_modulo *m, mp_limb_t *rp,
   mpn_sqr (rp, ap, m->size);
   m->reduce (m, rp);
 }
+
+/* Compute R <-- X^{2^k} mod M. Needs 2*ecc->size limbs at rp, and
+   2*ecc->size additional limbs of scratch space. No overlap
+   allowed. */
+void
+ecc_mod_pow_2k (const struct ecc_modulo *m,
+		mp_limb_t *rp, const mp_limb_t *xp,
+		unsigned k, mp_limb_t *tp)
+{
+  if (k & 1)
+    {
+      ecc_mod_sqr (m, rp, xp);
+      k--;
+    }
+  else
+    {
+      ecc_mod_sqr (m, tp, xp);
+      ecc_mod_sqr (m, rp, tp);
+      k -= 2;
+    }
+  while (k > 0)
+    {
+      ecc_mod_sqr (m, tp, rp);
+      ecc_mod_sqr (m, rp, tp);
+      k -= 2;
+    }
+}
+
+/* Computes R <-- X^{2^k} * Y. Scratch requirements as ecc_mod_pow_2k. */
+void
+ecc_mod_pow_2k_mul (const struct ecc_modulo *m,
+		    mp_limb_t *rp, const mp_limb_t *xp,
+		    unsigned k, const mp_limb_t *yp,
+		    mp_limb_t *tp)
+{
+  ecc_mod_pow_2k (m, tp, xp, k, rp);
+  ecc_mod_mul (m, rp, tp, yp);
+}
-- 
GitLab