diff --git a/ChangeLog b/ChangeLog
index 15d72b5eaace54869ea16cae076d119b3597fed9..983078a6b115f7e3fd69c2208169782d2bde5a15 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 f8f2c64af8680f39c83cbeab2e94eb90e7b38774..60ef05400f6da4a1a72c89994ef9245a79aed8ce 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 484b7d1e08700a8e7ff57d988c1b59aa077e3386..729ce985fe4702897e189e8dd1cee85be365340c 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 8ef4276b2679209dffe8207605efb45dcaad9ed7..3082917bc22b9af3be9bd7ca46fe3f99aeb00b03 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 f2e47f6747c11ead4ef8ce62a34517006aa6c172..0b315552c40ee4db0d6402743354b471af64f891 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);
+}