diff --git a/ChangeLog b/ChangeLog
index 13f74ed07751ce9bde19f2461f28832c999b9380..8fd30374d445e2aa12611914decd277ac286f4f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2016-07-13  Niels Möller  <nisse@lysator.liu.se>
+
+	* bignum.c (nettle_mpz_from_octets): Unconditionally use
+	mpz_import.
+	* gmp-glue.c (mpn_copyd, mpn_copyi, mpn_zero): Deleted
+	compatibility definitions for older versions of GMP.
+	* gmp-glue.h (mpn_sqr): Deleted compatibility definition.
+	* testsuite/testutils.c (mpz_combit): Deleted compatibility
+	definition.
+
+2016-07-12  Niels Möller  <nisse@lysator.liu.se>
+
+	* configure.ac: Check for mpz_powm_sec, and require GMP-5.0 or
+	later.
+	* bignum.h (mpz_powm_sec): Fall back to plain mpz_powm for
+	mini-gmp build.
+	* dsa-sign.c (dsa_sign): Use mpz_powm_sec.
+	* rsa-sign.c (rsa_compute_root): Likewise.
+	* rsa-sign-tr.c (rsa_blind, rsa_compute_root_tr): Likewise.
+	* rsa-blind.c (_rsa_blind): Likewise.
+
 2016-05-02  Niels Möller  <nisse@lysator.liu.se>
 
 	* nettle.texinfo: Update Curve25519 documentation.
diff --git a/bignum.c b/bignum.c
index 4980b1ad8daa77445ed98c01ce2f8883af9e306e..3352528765449a06c962e093fe842e95e9b912c4 100644
--- a/bignum.c
+++ b/bignum.c
@@ -135,26 +135,9 @@ nettle_mpz_get_str_256(size_t length, uint8_t *s, const mpz_t x)
 
 /* Converting from strings */
 
-#ifdef mpz_import
-/* Was introduced in GMP-4.1 */
-# define nettle_mpz_from_octets(x, length, s) \
+/* mpz_import was introduced in GMP-4.1 */
+#define nettle_mpz_from_octets(x, length, s) \
    mpz_import((x), (length), 1, 1, 0, 0, (s))
-#else
-static void
-nettle_mpz_from_octets(mpz_t x,
-		       size_t length, const uint8_t *s)
-{
-  size_t i;
-
-  mpz_set_ui(x, 0);
-
-  for (i = 0; i < length; i++)
-    {
-      mpz_mul_2exp(x, x, 8);
-      mpz_add_ui(x, x, s[i]);
-    }
-}
-#endif
 
 void
 nettle_mpz_set_str_256_u(mpz_t x,
diff --git a/bignum.h b/bignum.h
index 24158e069561514c0c221fc3309c38a5a3dedb6b..9afcd299f8ed3a5bade1385d5ac91e5ee9462c1f 100644
--- a/bignum.h
+++ b/bignum.h
@@ -46,13 +46,10 @@
 
 # define GMP_NUMB_MASK (~(mp_limb_t) 0)
 
-/* Functions missing in older gmp versions, and checked for with ifdef */
+/* Function missing in older gmp versions, and checked for with ifdef */
 # define mpz_limbs_read mpz_limbs_read
-# define mpn_copyd mpn_copyd
-# define mpn_sqr mpn_sqr
-# define mpz_combit mpz_combit
-# define mpz_import mpz_import
-# define mpz_export mpz_export
+/* Side-channel silent powm not available in mini-gmp. */
+# define mpz_powm_sec mpz_powm
 #else
 # include <gmp.h>
 #endif
diff --git a/configure.ac b/configure.ac
index e1ee64c2e7bdc08b479651076c0bd394fe822974..1e88477328121bad3d3c6497172f84cc57a36f8b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -236,9 +236,9 @@ fi
 # Checks for libraries
 if test "x$enable_public_key" = "xyes" ; then
   if test "x$enable_mini_gmp" = "xno" ; then
-    AC_CHECK_LIB(gmp, __gmpz_getlimbn,,
+    AC_CHECK_LIB(gmp, __gmpz_powm_sec,,
         [AC_MSG_WARN(
-    [GNU MP not found, or not 3.1 or up, see http://gmplib.org/.
+    [GNU MP not found, or too old. GMP-5.0 or later is needed, see http://gmplib.org/.
     Support for public key algorithms will be unavailable.])]
         enable_public_key=no)
 
diff --git a/dsa-sign.c b/dsa-sign.c
index 62c7d4acb651df4e8b6f0963d883827f6427f8b2..9d6bb1849de248604b9e3c8403167e85b060b116 100644
--- a/dsa-sign.c
+++ b/dsa-sign.c
@@ -65,7 +65,7 @@ dsa_sign(const struct dsa_params *params,
   mpz_add_ui(k, k, 1);
 
   /* Compute r = (g^k (mod p)) (mod q) */
-  mpz_powm(tmp, params->g, k, params->p);
+  mpz_powm_sec(tmp, params->g, k, params->p);
   mpz_fdiv_r(signature->r, tmp, params->q);
 
   /* Compute hash */
diff --git a/gmp-glue.c b/gmp-glue.c
index f9a5e358c7de297a5c7a1e49d0c294142e3d1570..c44332df4f382e61742979751ab97822e777d9da 100644
--- a/gmp-glue.c
+++ b/gmp-glue.c
@@ -116,32 +116,6 @@ mpz_roinit_n (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs)
 }
 #endif /* !GMP_HAVE_mpz_limbs_read */
 
-#if !GMP_HAVE_mpn_copyd
-void
-mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t n)
-{
-  mp_size_t i;
-  for (i = n - 1; i >= 0; i--)
-    dst[i] = src[i];
-}
-
-void
-mpn_copyi (mp_ptr dst, mp_srcptr src, mp_size_t n)
-{
-  mp_size_t i;
-  for (i = 0; i < n; i++)
-    dst[i] = src[i];
-}
-
-void
-mpn_zero (mp_ptr ptr, mp_size_t n)
-{
-  mp_size_t i;
-  for (i = 0; i < n; i++)
-    ptr[i] = 0;
-}
-#endif /* !GMP_HAVE_mpn_copyd */
-
 void
 cnd_swap (mp_limb_t cnd, mp_limb_t *ap, mp_limb_t *bp, mp_size_t n)
 {
diff --git a/gmp-glue.h b/gmp-glue.h
index 7713757c4dbace397b9b9a33748227d3a647793f..648724bc756f6c57c8942bf996d2392f353097ff 100644
--- a/gmp-glue.h
+++ b/gmp-glue.h
@@ -41,12 +41,6 @@
 #define GMP_HAVE_mpz_limbs_read 0
 #endif
 
-#ifdef mpn_copyd
-#define GMP_HAVE_mpn_copyd 1
-#else
-#define GMP_HAVE_mpn_copyd 0
-#endif
-
 /* Name mangling. */
 #if !GMP_HAVE_mpz_limbs_read
 #define mpz_limbs_read _nettle_mpz_limbs_read
@@ -56,16 +50,6 @@
 #define mpz_roinit_n _nettle_mpz_roinit_n
 #endif
 
-#if !GMP_HAVE_mpn_copyd
-#define mpn_copyd _nettle_mpn_copyd
-#define mpn_copyi _nettle_mpn_copyi
-#define mpn_zero  _nettle_mpn_zero
-#endif
-
-#ifndef mpn_sqr
-#define mpn_sqr(rp, ap, n) mpn_mul_n((rp), (ap), (ap), (n))
-#endif
-
 #define cnd_swap _nettle_cnd_swap
 #define mpz_limbs_cmp _nettle_mpz_limbs_cmp
 #define mpz_limbs_read_n _nettle_mpz_limbs_read_n
@@ -130,20 +114,6 @@ mpz_roinit_n (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs);
 
 #endif /* !GMP_HAVE_mpz_limbs_read */
 
-#if !GMP_HAVE_mpn_copyd
-/* Copy elements, backwards */
-void
-mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t n);
-
-/* Copy elements, forwards */
-void
-mpn_copyi (mp_ptr dst, mp_srcptr src, mp_size_t n);
-
-/* Zero elements */
-void
-mpn_zero (mp_ptr ptr, mp_size_t n);
-#endif /* !GMP_HAVE_mpn_copyd */
-
 void
 cnd_swap (mp_limb_t cnd, mp_limb_t *ap, mp_limb_t *bp, mp_size_t n);
 
diff --git a/rsa-blind.c b/rsa-blind.c
index 7662f5034a80fb1ef19be73e506beeef70385f49..16b03d77a757a3af98956fee8f397276a6833a47 100644
--- a/rsa-blind.c
+++ b/rsa-blind.c
@@ -61,7 +61,7 @@ _rsa_blind (const struct rsa_public_key *pub,
   while (!mpz_invert (ri, r, pub->n));
 
   /* c = c*(r^e) mod n */
-  mpz_powm(r, r, pub->e, pub->n);
+  mpz_powm_sec(r, r, pub->e, pub->n);
   mpz_mul(c, c, r);
   mpz_fdiv_r(c, c, pub->n);
 
diff --git a/rsa-sign-tr.c b/rsa-sign-tr.c
index 3d80ed4e94d7d87886e5abb8bec01c0c9b51cab7..68233a3c7543756b658f63799749ae06e495aa3d 100644
--- a/rsa-sign-tr.c
+++ b/rsa-sign-tr.c
@@ -60,7 +60,7 @@ rsa_blind (const struct rsa_public_key *pub,
   while (!mpz_invert (ri, r, pub->n));
 
   /* c = c*(r^e) mod n */
-  mpz_powm(r, r, pub->e, pub->n);
+  mpz_powm_sec(r, r, pub->e, pub->n);
   mpz_mul(c, m, r);
   mpz_fdiv_r(c, c, pub->n);
 
@@ -97,7 +97,7 @@ rsa_compute_root_tr(const struct rsa_public_key *pub,
 
   rsa_compute_root (key, xb, mb);
 
-  mpz_powm(t, xb, pub->e, pub->n);
+  mpz_powm_sec(t, xb, pub->e, pub->n);
   res = (mpz_cmp(mb, t) == 0);
 
   if (res)
diff --git a/rsa-sign.c b/rsa-sign.c
index eba7388dfb32fc0619f698440c0b85bfb279c5fd..48323527dfadad4848170456050c841d8f2f139a 100644
--- a/rsa-sign.c
+++ b/rsa-sign.c
@@ -96,11 +96,11 @@ rsa_compute_root(const struct rsa_private_key *key,
 
   /* Compute xq = m^d % q = (m%q)^b % q */
   mpz_fdiv_r(xq, m, key->q);
-  mpz_powm(xq, xq, key->b, key->q);
+  mpz_powm_sec(xq, xq, key->b, key->q);
 
   /* Compute xp = m^d % p = (m%p)^a % p */
   mpz_fdiv_r(xp, m, key->p);
-  mpz_powm(xp, xp, key->a, key->p);
+  mpz_powm_sec(xp, xp, key->a, key->p);
 
   /* Set xp' = (xp - xq) c % p. */
   mpz_sub(xp, xp, xq);
diff --git a/testsuite/testutils.c b/testsuite/testutils.c
index 36efe855fd669aa4f2a618efacfa62747a7b6d48..01c9b944cd5ea6eee9e082dc2e4d52c211f14939 100644
--- a/testsuite/testutils.c
+++ b/testsuite/testutils.c
@@ -606,18 +606,6 @@ test_armor(const struct nettle_armor *armor,
 
 #if WITH_HOGWEED
 
-#ifndef mpz_combit
-/* Missing in older gmp */
-static void
-mpz_combit (mpz_t x, unsigned long int bit)
-{
-  if (mpz_tstbit(x, bit))
-    mpz_clrbit(x, bit);
-  else
-    mpz_setbit(x, bit);
-}
-#endif
-
 #ifndef mpn_zero_p
 int
 mpn_zero_p (mp_srcptr ap, mp_size_t n)