diff --git a/ChangeLog b/ChangeLog
index 4d25fe17210b3538536d6b364e533ce884f1f8e1..bfaa5e963000ff94a7e64df213055cb5cfbc9bdd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2022-02-17  Niels Möller  <nisse@lysator.liu.se>
+
+	* gcm.c: Require that GCM_TABLE_BITS == 8. Delete old code for
+	GCM_TABLE_BITS == 0 and GCM_TABLE_BITS == 4.
+	* gcm-internal.h: Delete checks for GCM_TABLE_BITS != 8.
+	* fat-x86_64.c: Likewise.
+	* fat-s390x.c: Likewise.
+	* fat-ppc.c: Likewise.
+	* fat-arm64.c: Likewise.
+
 2022-02-15  Niels Möller  <nisse@lysator.liu.se>
 
 	* fat-x86_64.c: Add fat setup for gcm.
diff --git a/fat-arm64.c b/fat-arm64.c
index fcb2ece815e499855773bf0bd2726e4e37742be8..f6aef25ed479367263c7bc5d774afb61293b4dec 100644
--- a/fat-arm64.c
+++ b/fat-arm64.c
@@ -148,7 +148,6 @@ DECLARE_FAT_FUNC(nettle_aes256_decrypt, aes256_crypt_func)
 DECLARE_FAT_FUNC_VAR(aes256_decrypt, aes256_crypt_func, c)
 DECLARE_FAT_FUNC_VAR(aes256_decrypt, aes256_crypt_func, arm64)
 
-#if GCM_TABLE_BITS == 8
 DECLARE_FAT_FUNC(_nettle_gcm_init_key, gcm_init_key_func)
 DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, c)
 DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, arm64)
@@ -156,7 +155,6 @@ DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, arm64)
 DECLARE_FAT_FUNC(_nettle_gcm_hash, gcm_hash_func)
 DECLARE_FAT_FUNC_VAR(gcm_hash, gcm_hash_func, c)
 DECLARE_FAT_FUNC_VAR(gcm_hash, gcm_hash_func, arm64)
-#endif /* GCM_TABLE_BITS == 8 */
 
 DECLARE_FAT_FUNC(nettle_sha1_compress, sha1_compress_func)
 DECLARE_FAT_FUNC_VAR(sha1_compress, sha1_compress_func, c)
@@ -207,21 +205,18 @@ fat_init (void)
     {
       if (verbose)
 	fprintf (stderr, "libnettle: enabling hardware-accelerated polynomial multiply code.\n");
-#if GCM_TABLE_BITS == 8
+
       /* Make sure _nettle_gcm_init_key_vec function is compatible
          with _nettle_gcm_hash_vec function e.g. _nettle_gcm_init_key_c()
          fills gcm_key table with values that are incompatible with
          _nettle_gcm_hash_arm64() */
       _nettle_gcm_init_key_vec = _nettle_gcm_init_key_arm64;
       _nettle_gcm_hash_vec = _nettle_gcm_hash_arm64;
-#endif /* GCM_TABLE_BITS == 8 */
     }
   else
     {
-#if GCM_TABLE_BITS == 8
       _nettle_gcm_init_key_vec = _nettle_gcm_init_key_c;
       _nettle_gcm_hash_vec = _nettle_gcm_hash_c;
-#endif /* GCM_TABLE_BITS == 8 */
     }
   if (features.have_sha1)
     {
@@ -272,7 +267,6 @@ DEFINE_FAT_FUNC(nettle_aes256_decrypt, void,
   uint8_t *dst,const uint8_t *src),
  (ctx, length, dst, src))
 
-#if GCM_TABLE_BITS == 8
 DEFINE_FAT_FUNC(_nettle_gcm_init_key, void,
 		(union nettle_block16 *table),
 		(table))
@@ -281,7 +275,6 @@ DEFINE_FAT_FUNC(_nettle_gcm_hash, void,
 		(const struct gcm_key *key, union nettle_block16 *x,
 		 size_t length, const uint8_t *data),
 		(key, x, length, data))
-#endif /* GCM_TABLE_BITS == 8 */
 
 DEFINE_FAT_FUNC(nettle_sha1_compress, void,
 		(uint32_t *state, const uint8_t *input),
diff --git a/fat-ppc.c b/fat-ppc.c
index 3adbb88c3a96c3a3ca552a2d0912bce9a56b5e01..3cf720bd969ec0368f07b0d51e0bfb5a552a495a 100644
--- a/fat-ppc.c
+++ b/fat-ppc.c
@@ -153,7 +153,6 @@ DECLARE_FAT_FUNC(_nettle_aes_decrypt, aes_crypt_internal_func)
 DECLARE_FAT_FUNC_VAR(aes_decrypt, aes_crypt_internal_func, c)
 DECLARE_FAT_FUNC_VAR(aes_decrypt, aes_crypt_internal_func, ppc64)
 
-#if GCM_TABLE_BITS == 8
 DECLARE_FAT_FUNC(_nettle_gcm_init_key, gcm_init_key_func)
 DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, c)
 DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, ppc64)
@@ -161,7 +160,6 @@ DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, ppc64)
 DECLARE_FAT_FUNC(_nettle_gcm_hash, gcm_hash_func)
 DECLARE_FAT_FUNC_VAR(gcm_hash, gcm_hash_func, c)
 DECLARE_FAT_FUNC_VAR(gcm_hash, gcm_hash_func, ppc64)
-#endif /* GCM_TABLE_BITS == 8 */
 
 DECLARE_FAT_FUNC(_nettle_chacha_core, chacha_core_func)
 DECLARE_FAT_FUNC_VAR(chacha_core, chacha_core_func, c);
@@ -194,23 +192,20 @@ fat_init (void)
 	fprintf (stderr, "libnettle: enabling arch 2.07 code.\n");
       _nettle_aes_encrypt_vec = _nettle_aes_encrypt_ppc64;
       _nettle_aes_decrypt_vec = _nettle_aes_decrypt_ppc64;
-#if GCM_TABLE_BITS == 8
+
       /* Make sure _nettle_gcm_init_key_vec function is compatible
          with _nettle_gcm_hash_vec function e.g. _nettle_gcm_init_key_c()
          fills gcm_key table with values that are incompatible with
          _nettle_gcm_hash_ppc64() */
       _nettle_gcm_init_key_vec = _nettle_gcm_init_key_ppc64;
       _nettle_gcm_hash_vec = _nettle_gcm_hash_ppc64;
-#endif /* GCM_TABLE_BITS == 8 */
     }
   else
     {
       _nettle_aes_encrypt_vec = _nettle_aes_encrypt_c;
       _nettle_aes_decrypt_vec = _nettle_aes_decrypt_c;
-#if GCM_TABLE_BITS == 8
       _nettle_gcm_init_key_vec = _nettle_gcm_init_key_c;
       _nettle_gcm_hash_vec = _nettle_gcm_hash_c;
-#endif /* GCM_TABLE_BITS == 8 */
     }
   if (features.have_altivec)
     {
@@ -242,7 +237,6 @@ DEFINE_FAT_FUNC(_nettle_aes_decrypt, void,
  const uint8_t *src),
  (rounds, keys, T, length, dst, src))
 
-#if GCM_TABLE_BITS == 8
 DEFINE_FAT_FUNC(_nettle_gcm_init_key, void,
 		(union nettle_block16 *table),
 		(table))
@@ -251,7 +245,6 @@ DEFINE_FAT_FUNC(_nettle_gcm_hash, void,
 		(const struct gcm_key *key, union nettle_block16 *x,
 		 size_t length, const uint8_t *data),
 		(key, x, length, data))
-#endif /* GCM_TABLE_BITS == 8 */
 
 DEFINE_FAT_FUNC(_nettle_chacha_core, void,
 		(uint32_t *dst, const uint32_t *src, unsigned rounds),
diff --git a/fat-s390x.c b/fat-s390x.c
index 6c68c445dce4a7e2153ab6aaf9317dcd9f5e0f74..a129573696d536eb55d7f85464cd6b6b683c58a3 100644
--- a/fat-s390x.c
+++ b/fat-s390x.c
@@ -242,7 +242,6 @@ DECLARE_FAT_FUNC_VAR(aes256_decrypt, aes256_crypt_func, c)
 DECLARE_FAT_FUNC_VAR(aes256_decrypt, aes256_crypt_func, s390x)
 
 /* GHASH */
-#if GCM_TABLE_BITS == 8
 DECLARE_FAT_FUNC(_nettle_gcm_init_key, gcm_init_key_func)
 DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, c)
 DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, s390x)
@@ -250,7 +249,6 @@ DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, s390x)
 DECLARE_FAT_FUNC(_nettle_gcm_hash, gcm_hash_func)
 DECLARE_FAT_FUNC_VAR(gcm_hash, gcm_hash_func, c)
 DECLARE_FAT_FUNC_VAR(gcm_hash, gcm_hash_func, s390x)
-#endif /* GCM_TABLE_BITS == 8 */
 
 DECLARE_FAT_FUNC(nettle_sha1_compress, sha1_compress_func)
 DECLARE_FAT_FUNC_VAR(sha1_compress, sha1_compress_func, c)
@@ -483,7 +481,6 @@ DEFINE_FAT_FUNC(nettle_aes256_decrypt, void,
  (ctx, length, dst, src))
 
 /* GHASH */
-#if GCM_TABLE_BITS == 8
 DEFINE_FAT_FUNC(_nettle_gcm_init_key, void,
 		(union nettle_block16 *table),
 		(table))
@@ -491,7 +488,6 @@ DEFINE_FAT_FUNC(_nettle_gcm_hash, void,
 		(const struct gcm_key *key, union nettle_block16 *x,
 		 size_t length, const uint8_t *data),
 		(key, x, length, data))
-#endif /* GCM_TABLE_BITS == 8 */
 
 /* SHA1 */
 DEFINE_FAT_FUNC(nettle_sha1_compress, void,
diff --git a/fat-x86_64.c b/fat-x86_64.c
index 21dab62fdc318ee6b475a05e74a21110cae5b0df..d9f72a03bc6ddcea492634175849f0388dbe09bb 100644
--- a/fat-x86_64.c
+++ b/fat-x86_64.c
@@ -160,7 +160,6 @@ DECLARE_FAT_FUNC(_nettle_sha256_compress, sha256_compress_func)
 DECLARE_FAT_FUNC_VAR(sha256_compress, sha256_compress_func, x86_64)
 DECLARE_FAT_FUNC_VAR(sha256_compress, sha256_compress_func, sha_ni)
 
-#if GCM_TABLE_BITS == 8
 DECLARE_FAT_FUNC(_nettle_gcm_init_key, gcm_init_key_func)
 DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, c)
 DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, pclmul)
@@ -168,7 +167,6 @@ DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, pclmul)
 DECLARE_FAT_FUNC(_nettle_gcm_hash, gcm_hash_func)
 DECLARE_FAT_FUNC_VAR(gcm_hash, gcm_hash_func, c)
 DECLARE_FAT_FUNC_VAR(gcm_hash, gcm_hash_func, pclmul)
-#endif /* GCM_TABLE_BITS == 8 */
 
 
 /* This function should usually be called only once, at startup. But
@@ -241,7 +239,6 @@ fat_init (void)
       _nettle_sha256_compress_vec = _nettle_sha256_compress_x86_64;
     }
 
-#if GCM_TABLE_BITS == 8
   if (features.have_pclmul)
     {
       if (verbose)
@@ -256,7 +253,7 @@ fat_init (void)
       _nettle_gcm_init_key_vec = _nettle_gcm_init_key_c;
       _nettle_gcm_hash_vec = _nettle_gcm_hash8;
     }
-#endif
+
   if (features.vendor == X86_INTEL)
     {
       if (verbose)
@@ -323,7 +320,6 @@ DEFINE_FAT_FUNC(_nettle_sha256_compress, void,
 		(uint32_t *state, const uint8_t *input, const uint32_t *k),
 		(state, input, k))
 
-#if GCM_TABLE_BITS == 8
 DEFINE_FAT_FUNC(_nettle_gcm_init_key, void,
 		(union nettle_block16 *table),
 		(table))
@@ -332,4 +328,3 @@ DEFINE_FAT_FUNC(_nettle_gcm_hash, void,
 		(const struct gcm_key *key, union nettle_block16 *x,
 		 size_t length, const uint8_t *data),
 		(key, x, length, data))
-#endif /* GCM_TABLE_BITS == 8 */
diff --git a/gcm-internal.h b/gcm-internal.h
index e1871562e9e03d09af499b76f34daeae5f7d4475..0b2d7cefc12d0e1c85391b1468ded5f463f00691 100644
--- a/gcm-internal.h
+++ b/gcm-internal.h
@@ -32,19 +32,10 @@
 #ifndef NETTLE_GCM_INTERNAL_H_INCLUDED
 #define NETTLE_GCM_INTERNAL_H_INCLUDED
 
-#if GCM_TABLE_BITS != 8
-/* The native implementations (currently ppc64 only) depend on the
-   GCM_TABLE_BITS == 8 layout */
-#undef HAVE_NATIVE_gcm_hash
-#undef HAVE_NATIVE_gcm_init_key
-#undef HAVE_NATIVE_fat_gcm_hash
-#undef HAVE_NATIVE_fat_gcm_init_key
-#endif
-
 /* Arrange so that _gcm_hash is an alias for the right implementation. */
 #if HAVE_NATIVE_gcm_hash || HAVE_NATIVE_fat_gcm_hash
 # define _gcm_hash _nettle_gcm_hash
-#elif GCM_TABLE_BITS == 8 && HAVE_NATIVE_gcm_hash8
+#elif HAVE_NATIVE_gcm_hash8
 # define _gcm_hash _nettle_gcm_hash8
 #else
 # define _gcm_hash _nettle_gcm_hash_c
diff --git a/gcm.c b/gcm.c
index fce1682bb825e3311334feabf123b20b593a14d2..e70c6887a25af6e65ea42b561c3afa22b62b6330 100644
--- a/gcm.c
+++ b/gcm.c
@@ -56,93 +56,19 @@
 #include "ctr-internal.h"
 #include "block-internal.h"
 
-#if !HAVE_NATIVE_gcm_hash
-# if GCM_TABLE_BITS == 0
-/* Sets x <- x * y mod r, using the plain bitwise algorithm from the
-   specification. y may be shorter than a full block, missing bytes
-   are assumed zero. */
-static void
-gcm_gf_mul (union nettle_block16 *x, const union nettle_block16 *y)
-{
-  union nettle_block16 V;
-  union nettle_block16 Z;
-  unsigned i;
-
-  memcpy(V.b, x, sizeof(V));
-  memset(Z.b, 0, sizeof(Z));
-
-  for (i = 0; i < GCM_BLOCK_SIZE; i++)
-    {
-      uint8_t b = y->b[i];
-      unsigned j;
-      for (j = 0; j < 8; j++, b <<= 1)
-	{
-	  if (b & 0x80)
-	    block16_xor(&Z, &V);
-	  
-	  block16_mulx_ghash(&V, &V);
-	}
-    }
-  memcpy (x->b, Z.b, sizeof(Z));
-}
-# else /* GCM_TABLE_BITS != 0 */
-
-#  if WORDS_BIGENDIAN
-#   define W(left,right) (0x##left##right)
-#  else
-#   define W(left,right) (0x##right##left)
-#  endif
-
-#  if GCM_TABLE_BITS == 4
-static const uint16_t
-shift_table[0x10] = {
-  W(00,00),W(1c,20),W(38,40),W(24,60),W(70,80),W(6c,a0),W(48,c0),W(54,e0),
-  W(e1,00),W(fd,20),W(d9,40),W(c5,60),W(91,80),W(8d,a0),W(a9,c0),W(b5,e0),
-};
-
-static void
-gcm_gf_shift_4(union nettle_block16 *x)
-{
-  uint64_t *u64 = x->u64;
-  uint64_t reduce;
-
-  /* Shift uses big-endian representation. */
-#if WORDS_BIGENDIAN
-  reduce = shift_table[u64[1] & 0xf];
-  u64[1] = (u64[1] >> 4) | ((u64[0] & 0xf) << 60);
-  u64[0] = (u64[0] >> 4) ^ (reduce << 48);
-#else /* ! WORDS_BIGENDIAN */
-# define RSHIFT_WORD_4(x) \
-  ((((x) & UINT64_C(0xf0f0f0f0f0f0f0f0)) >> 4) \
-   | (((x) & UINT64_C(0x000f0f0f0f0f0f0f)) << 12))
-  reduce = shift_table[(u64[1] >> 56) & 0xf];
-  u64[1] = RSHIFT_WORD_4(u64[1]) | ((u64[0] >> 52) & 0xf0);
-  u64[0] = RSHIFT_WORD_4(u64[0]) ^ reduce;
-# undef RSHIFT_WORD_4
-#endif /* ! WORDS_BIGENDIAN */
-}
-
-static void
-gcm_gf_mul (union nettle_block16 *x, const union nettle_block16 *table)
-{
-  union nettle_block16 Z;
-  unsigned i;
+#if GCM_TABLE_BITS != 8
+# error Unsupported table size.
+#endif
 
-  memset(Z.b, 0, sizeof(Z));
+#if !HAVE_NATIVE_gcm_hash
 
-  for (i = GCM_BLOCK_SIZE; i-- > 0;)
-    {
-      uint8_t b = x->b[i];
+# if WORDS_BIGENDIAN
+#  define W(left,right) (0x##left##right)
+# else
+#  define W(left,right) (0x##right##left)
+# endif
 
-      gcm_gf_shift_4(&Z);
-      block16_xor(&Z, &table[b & 0xf]);
-      gcm_gf_shift_4(&Z);
-      block16_xor(&Z, &table[b >> 4]);
-    }
-  memcpy (x->b, Z.b, sizeof(Z));
-}
-#  elif GCM_TABLE_BITS == 8
-#   if !HAVE_NATIVE_gcm_hash8
+# if !HAVE_NATIVE_gcm_hash8
 static const uint16_t
 shift_table[0x100] = {
   W(00,00),W(01,c2),W(03,84),W(02,46),W(07,08),W(06,ca),W(04,8c),W(05,4e),
@@ -212,13 +138,9 @@ gcm_gf_mul (union nettle_block16 *x, const union nettle_block16 *table)
   gcm_gf_shift_8(&Z);
   block16_xor3(x, &Z, &table[x->b[0]]);
 }
-#   endif /* ! HAVE_NATIVE_gcm_hash8 */
-#  else /* GCM_TABLE_BITS != 8 */
-#   error Unsupported table size.
-#  endif /* GCM_TABLE_BITS != 8 */
+# endif /* ! HAVE_NATIVE_gcm_hash8 */
 
-#  undef W
-# endif /* GCM_TABLE_BITS != 0 */
+# undef W
 #endif /* !HAVE_NATIVE_gcm_hash */
 
 
@@ -233,7 +155,6 @@ static
 void
 _nettle_gcm_init_key_c(union nettle_block16 *table)
 {
-#if GCM_TABLE_BITS
   /* Middle element if GCM_TABLE_BITS > 0, otherwise the first
      element */
   unsigned i = (1<<GCM_TABLE_BITS)/2;
@@ -248,7 +169,6 @@ _nettle_gcm_init_key_c(union nettle_block16 *table)
       for (j = 1; j < i; j++)
 	block16_xor3(&table[i+j], &table[i], &table[j]);
     }
-#endif
 }
 #endif /* !HAVE_NATIVE_gcm_init_key */