[Python-checkins] gh-99108: Replace SHA3 implementation HACL* version (#103597)

gpshead webhook-mailer at python.org
Sun May 7 23:50:12 EDT 2023


https://github.com/python/cpython/commit/15665d896bae9c3d8b60bd7210ac1b7dc533b093
commit: 15665d896bae9c3d8b60bd7210ac1b7dc533b093
branch: main
author: Jonathan Protzenko <protz at microsoft.com>
committer: gpshead <greg at krypto.org>
date: 2023-05-07T20:50:04-07:00
summary:

gh-99108: Replace SHA3 implementation HACL* version (#103597)

Replaces our built-in SHA3 implementation with a verified one from the HACL* project.

This implementation is used when OpenSSL does not provide SHA3 or is not present.

3.11 shiped with a very slow tiny sha3 implementation to get off of the <=3.10 reference implementation that wound up having serious bugs. This brings us back to a reasonably performing built-in implementation consistent with what we've just replaced our other guaranteed available standard hash algorithms with: code from the HACL* project.

---------

Co-authored-by: Gregory P. Smith <greg at krypto.org>

files:
A Misc/NEWS.d/next/Security/2023-04-17-14-38-12.gh-issue-99108.720lG8.rst
A Modules/_hacl/Hacl_Hash_SHA3.c
A Modules/_hacl/Hacl_Hash_SHA3.h
A Modules/_hacl/internal/Hacl_Hash_SHA3.h
A Modules/clinic/sha3module.c.h
A Modules/sha3module.c
D Modules/_sha3/LICENSE
D Modules/_sha3/README.txt
D Modules/_sha3/clinic/sha3module.c.h
D Modules/_sha3/sha3.c
D Modules/_sha3/sha3.h
D Modules/_sha3/sha3module.c
M Makefile.pre.in
M Modules/Setup
M Modules/Setup.stdlib.in
M Modules/_hacl/Hacl_Streaming_Types.h
M Modules/_hacl/include/krml/internal/target.h
M Modules/_hacl/include/krml/lowstar_endianness.h
M Modules/_hacl/python_hacl_namespaces.h
M Modules/_hacl/refresh.sh
M PCbuild/pythoncore.vcxproj
M PCbuild/pythoncore.vcxproj.filters
M Tools/c-analyzer/cpython/_parser.py

diff --git a/Makefile.pre.in b/Makefile.pre.in
index 736a520d0e8f..329466580b9c 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -2698,7 +2698,7 @@ MODULE__IO_DEPS=$(srcdir)/Modules/_io/_iomodule.h
 MODULE__MD5_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HEADERS) Modules/_hacl/Hacl_Hash_MD5.h Modules/_hacl/Hacl_Hash_MD5.c
 MODULE__SHA1_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HEADERS) Modules/_hacl/Hacl_Hash_SHA1.h Modules/_hacl/Hacl_Hash_SHA1.c
 MODULE__SHA2_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA2_HEADERS) $(LIBHACL_SHA2_A)
-MODULE__SHA3_DEPS=$(srcdir)/Modules/_sha3/sha3.c $(srcdir)/Modules/_sha3/sha3.h $(srcdir)/Modules/hashlib.h
+MODULE__SHA3_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HEADERS) Modules/_hacl/Hacl_Hash_SHA3.h Modules/_hacl/Hacl_Hash_SHA3.c
 MODULE__SOCKET_DEPS=$(srcdir)/Modules/socketmodule.h $(srcdir)/Modules/addrinfo.h $(srcdir)/Modules/getaddrinfo.c $(srcdir)/Modules/getnameinfo.c
 MODULE__SSL_DEPS=$(srcdir)/Modules/_ssl.h $(srcdir)/Modules/_ssl/cert.c $(srcdir)/Modules/_ssl/debughelpers.c $(srcdir)/Modules/_ssl/misc.c $(srcdir)/Modules/_ssl_data.h $(srcdir)/Modules/_ssl_data_111.h $(srcdir)/Modules/_ssl_data_300.h $(srcdir)/Modules/socketmodule.h
 MODULE__TESTCAPI_DEPS=$(srcdir)/Modules/_testcapi/testcapi_long.h $(srcdir)/Modules/_testcapi/parts.h
diff --git a/Misc/NEWS.d/next/Security/2023-04-17-14-38-12.gh-issue-99108.720lG8.rst b/Misc/NEWS.d/next/Security/2023-04-17-14-38-12.gh-issue-99108.720lG8.rst
new file mode 100644
index 000000000000..f259acf75383
--- /dev/null
+++ b/Misc/NEWS.d/next/Security/2023-04-17-14-38-12.gh-issue-99108.720lG8.rst
@@ -0,0 +1,2 @@
+Upgrade built-in :mod:`hashlib` SHA3 implementation to a verified implementation
+from the ``HACL*`` project.  Used when OpenSSL is not present or lacks SHA3.
diff --git a/Modules/Setup b/Modules/Setup
index 1c6f2f7ea518..e5bc078af62c 100644
--- a/Modules/Setup
+++ b/Modules/Setup
@@ -166,7 +166,7 @@ PYTHONPATH=$(COREPYTHONPATH)
 #_md5 md5module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_MD5.c -D_BSD_SOURCE -D_DEFAULT_SOURCE
 #_sha1 sha1module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA1.c -D_BSD_SOURCE -D_DEFAULT_SOURCE
 #_sha2 sha2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Streaming_SHA2.a
-#_sha3 _sha3/sha3module.c
+#_sha3 sha3module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_sha3.c -D_BSD_SOURCE -D_DEFAULT_SOURCE
 
 # text encodings and unicode
 #_codecs_cn cjkcodecs/_codecs_cn.c
diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in
index a7803cf7c00e..8e66576b5c5f 100644
--- a/Modules/Setup.stdlib.in
+++ b/Modules/Setup.stdlib.in
@@ -80,7 +80,7 @@
 @MODULE__MD5_TRUE at _md5 md5module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_MD5.c -D_BSD_SOURCE -D_DEFAULT_SOURCE
 @MODULE__SHA1_TRUE at _sha1 sha1module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA1.c -D_BSD_SOURCE -D_DEFAULT_SOURCE
 @MODULE__SHA2_TRUE at _sha2 sha2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Streaming_SHA2.a
- at MODULE__SHA3_TRUE@_sha3 _sha3/sha3module.c
+ at MODULE__SHA3_TRUE@_sha3 sha3module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA3.c -D_BSD_SOURCE -D_DEFAULT_SOURCE
 @MODULE__BLAKE2_TRUE at _blake2 _blake2/blake2module.c _blake2/blake2b_impl.c _blake2/blake2s_impl.c
 
 ############################################################################
diff --git a/Modules/_hacl/Hacl_Hash_SHA3.c b/Modules/_hacl/Hacl_Hash_SHA3.c
new file mode 100644
index 000000000000..100afe7c2c6d
--- /dev/null
+++ b/Modules/_hacl/Hacl_Hash_SHA3.c
@@ -0,0 +1,826 @@
+/* MIT License
+ *
+ * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation
+ * Copyright (c) 2022-2023 HACL* Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#include "internal/Hacl_Hash_SHA3.h"
+
+static uint32_t block_len(Spec_Hash_Definitions_hash_alg a)
+{
+  switch (a)
+  {
+    case Spec_Hash_Definitions_SHA3_224:
+      {
+        return (uint32_t)144U;
+      }
+    case Spec_Hash_Definitions_SHA3_256:
+      {
+        return (uint32_t)136U;
+      }
+    case Spec_Hash_Definitions_SHA3_384:
+      {
+        return (uint32_t)104U;
+      }
+    case Spec_Hash_Definitions_SHA3_512:
+      {
+        return (uint32_t)72U;
+      }
+    case Spec_Hash_Definitions_Shake128:
+      {
+        return (uint32_t)168U;
+      }
+    case Spec_Hash_Definitions_Shake256:
+      {
+        return (uint32_t)136U;
+      }
+    default:
+      {
+        KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, __LINE__);
+        KRML_HOST_EXIT(253U);
+      }
+  }
+}
+
+static uint32_t hash_len(Spec_Hash_Definitions_hash_alg a)
+{
+  switch (a)
+  {
+    case Spec_Hash_Definitions_SHA3_224:
+      {
+        return (uint32_t)28U;
+      }
+    case Spec_Hash_Definitions_SHA3_256:
+      {
+        return (uint32_t)32U;
+      }
+    case Spec_Hash_Definitions_SHA3_384:
+      {
+        return (uint32_t)48U;
+      }
+    case Spec_Hash_Definitions_SHA3_512:
+      {
+        return (uint32_t)64U;
+      }
+    default:
+      {
+        KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, __LINE__);
+        KRML_HOST_EXIT(253U);
+      }
+  }
+}
+
+void
+Hacl_Hash_SHA3_update_multi_sha3(
+  Spec_Hash_Definitions_hash_alg a,
+  uint64_t *s,
+  uint8_t *blocks,
+  uint32_t n_blocks
+)
+{
+  for (uint32_t i = (uint32_t)0U; i < n_blocks; i++)
+  {
+    uint8_t *block = blocks + i * block_len(a);
+    Hacl_Impl_SHA3_absorb_inner(block_len(a), block, s);
+  }
+}
+
+void
+Hacl_Hash_SHA3_update_last_sha3(
+  Spec_Hash_Definitions_hash_alg a,
+  uint64_t *s,
+  uint8_t *input,
+  uint32_t input_len
+)
+{
+  uint8_t suffix;
+  if (a == Spec_Hash_Definitions_Shake128 || a == Spec_Hash_Definitions_Shake256)
+  {
+    suffix = (uint8_t)0x1fU;
+  }
+  else
+  {
+    suffix = (uint8_t)0x06U;
+  }
+  uint32_t len = block_len(a);
+  if (input_len == len)
+  {
+    Hacl_Impl_SHA3_absorb_inner(len, input, s);
+    uint8_t *uu____0 = input + input_len;
+    uint8_t lastBlock_[200U] = { 0U };
+    uint8_t *lastBlock = lastBlock_;
+    memcpy(lastBlock, uu____0, (uint32_t)0U * sizeof (uint8_t));
+    lastBlock[0U] = suffix;
+    Hacl_Impl_SHA3_loadState(len, lastBlock, s);
+    if (!((suffix & (uint8_t)0x80U) == (uint8_t)0U) && (uint32_t)0U == len - (uint32_t)1U)
+    {
+      Hacl_Impl_SHA3_state_permute(s);
+    }
+    uint8_t nextBlock_[200U] = { 0U };
+    uint8_t *nextBlock = nextBlock_;
+    nextBlock[len - (uint32_t)1U] = (uint8_t)0x80U;
+    Hacl_Impl_SHA3_loadState(len, nextBlock, s);
+    Hacl_Impl_SHA3_state_permute(s);
+    return;
+  }
+  uint8_t lastBlock_[200U] = { 0U };
+  uint8_t *lastBlock = lastBlock_;
+  memcpy(lastBlock, input, input_len * sizeof (uint8_t));
+  lastBlock[input_len] = suffix;
+  Hacl_Impl_SHA3_loadState(len, lastBlock, s);
+  if (!((suffix & (uint8_t)0x80U) == (uint8_t)0U) && input_len == len - (uint32_t)1U)
+  {
+    Hacl_Impl_SHA3_state_permute(s);
+  }
+  uint8_t nextBlock_[200U] = { 0U };
+  uint8_t *nextBlock = nextBlock_;
+  nextBlock[len - (uint32_t)1U] = (uint8_t)0x80U;
+  Hacl_Impl_SHA3_loadState(len, nextBlock, s);
+  Hacl_Impl_SHA3_state_permute(s);
+}
+
+typedef struct hash_buf2_s
+{
+  Hacl_Streaming_Keccak_hash_buf fst;
+  Hacl_Streaming_Keccak_hash_buf snd;
+}
+hash_buf2;
+
+Spec_Hash_Definitions_hash_alg Hacl_Streaming_Keccak_get_alg(Hacl_Streaming_Keccak_state *s)
+{
+  Hacl_Streaming_Keccak_state scrut = *s;
+  Hacl_Streaming_Keccak_hash_buf block_state = scrut.block_state;
+  return block_state.fst;
+}
+
+Hacl_Streaming_Keccak_state *Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_hash_alg a)
+{
+  KRML_CHECK_SIZE(sizeof (uint8_t), block_len(a));
+  uint8_t *buf0 = (uint8_t *)KRML_HOST_CALLOC(block_len(a), sizeof (uint8_t));
+  uint64_t *buf = (uint64_t *)KRML_HOST_CALLOC((uint32_t)25U, sizeof (uint64_t));
+  Hacl_Streaming_Keccak_hash_buf block_state = { .fst = a, .snd = buf };
+  Hacl_Streaming_Keccak_state
+  s = { .block_state = block_state, .buf = buf0, .total_len = (uint64_t)(uint32_t)0U };
+  Hacl_Streaming_Keccak_state
+  *p = (Hacl_Streaming_Keccak_state *)KRML_HOST_MALLOC(sizeof (Hacl_Streaming_Keccak_state));
+  p[0U] = s;
+  uint64_t *s1 = block_state.snd;
+  for (uint32_t _i = 0U; _i < (uint32_t)25U; ++_i)
+    ((void **)s1)[_i] = (void *)(uint64_t)0U;
+  return p;
+}
+
+void Hacl_Streaming_Keccak_free(Hacl_Streaming_Keccak_state *s)
+{
+  Hacl_Streaming_Keccak_state scrut = *s;
+  uint8_t *buf = scrut.buf;
+  Hacl_Streaming_Keccak_hash_buf block_state = scrut.block_state;
+  uint64_t *s1 = block_state.snd;
+  KRML_HOST_FREE(s1);
+  KRML_HOST_FREE(buf);
+  KRML_HOST_FREE(s);
+}
+
+Hacl_Streaming_Keccak_state *Hacl_Streaming_Keccak_copy(Hacl_Streaming_Keccak_state *s0)
+{
+  Hacl_Streaming_Keccak_state scrut0 = *s0;
+  Hacl_Streaming_Keccak_hash_buf block_state0 = scrut0.block_state;
+  uint8_t *buf0 = scrut0.buf;
+  uint64_t total_len0 = scrut0.total_len;
+  Spec_Hash_Definitions_hash_alg i = block_state0.fst;
+  KRML_CHECK_SIZE(sizeof (uint8_t), block_len(i));
+  uint8_t *buf1 = (uint8_t *)KRML_HOST_CALLOC(block_len(i), sizeof (uint8_t));
+  memcpy(buf1, buf0, block_len(i) * sizeof (uint8_t));
+  uint64_t *buf = (uint64_t *)KRML_HOST_CALLOC((uint32_t)25U, sizeof (uint64_t));
+  Hacl_Streaming_Keccak_hash_buf block_state = { .fst = i, .snd = buf };
+  hash_buf2 scrut = { .fst = block_state0, .snd = block_state };
+  uint64_t *s_dst = scrut.snd.snd;
+  uint64_t *s_src = scrut.fst.snd;
+  memcpy(s_dst, s_src, (uint32_t)25U * sizeof (uint64_t));
+  Hacl_Streaming_Keccak_state
+  s = { .block_state = block_state, .buf = buf1, .total_len = total_len0 };
+  Hacl_Streaming_Keccak_state
+  *p = (Hacl_Streaming_Keccak_state *)KRML_HOST_MALLOC(sizeof (Hacl_Streaming_Keccak_state));
+  p[0U] = s;
+  return p;
+}
+
+void Hacl_Streaming_Keccak_reset(Hacl_Streaming_Keccak_state *s)
+{
+  Hacl_Streaming_Keccak_state scrut = *s;
+  uint8_t *buf = scrut.buf;
+  Hacl_Streaming_Keccak_hash_buf block_state = scrut.block_state;
+  uint64_t *s1 = block_state.snd;
+  for (uint32_t _i = 0U; _i < (uint32_t)25U; ++_i)
+    ((void **)s1)[_i] = (void *)(uint64_t)0U;
+  Hacl_Streaming_Keccak_state
+  tmp = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)(uint32_t)0U };
+  s[0U] = tmp;
+}
+
+uint32_t
+Hacl_Streaming_Keccak_update(Hacl_Streaming_Keccak_state *p, uint8_t *data, uint32_t len)
+{
+  Hacl_Streaming_Keccak_state s = *p;
+  Hacl_Streaming_Keccak_hash_buf block_state = s.block_state;
+  uint64_t total_len = s.total_len;
+  Spec_Hash_Definitions_hash_alg i = block_state.fst;
+  if ((uint64_t)len > (uint64_t)0xffffffffU - total_len)
+  {
+    return (uint32_t)1U;
+  }
+  uint32_t sz;
+  if (total_len % (uint64_t)block_len(i) == (uint64_t)0U && total_len > (uint64_t)0U)
+  {
+    sz = block_len(i);
+  }
+  else
+  {
+    sz = (uint32_t)(total_len % (uint64_t)block_len(i));
+  }
+  if (len <= block_len(i) - sz)
+  {
+    Hacl_Streaming_Keccak_state s1 = *p;
+    Hacl_Streaming_Keccak_hash_buf block_state1 = s1.block_state;
+    uint8_t *buf = s1.buf;
+    uint64_t total_len1 = s1.total_len;
+    uint32_t sz1;
+    if (total_len1 % (uint64_t)block_len(i) == (uint64_t)0U && total_len1 > (uint64_t)0U)
+    {
+      sz1 = block_len(i);
+    }
+    else
+    {
+      sz1 = (uint32_t)(total_len1 % (uint64_t)block_len(i));
+    }
+    uint8_t *buf2 = buf + sz1;
+    memcpy(buf2, data, len * sizeof (uint8_t));
+    uint64_t total_len2 = total_len1 + (uint64_t)len;
+    *p
+    =
+      (
+        (Hacl_Streaming_Keccak_state){
+          .block_state = block_state1,
+          .buf = buf,
+          .total_len = total_len2
+        }
+      );
+  }
+  else if (sz == (uint32_t)0U)
+  {
+    Hacl_Streaming_Keccak_state s1 = *p;
+    Hacl_Streaming_Keccak_hash_buf block_state1 = s1.block_state;
+    uint8_t *buf = s1.buf;
+    uint64_t total_len1 = s1.total_len;
+    uint32_t sz1;
+    if (total_len1 % (uint64_t)block_len(i) == (uint64_t)0U && total_len1 > (uint64_t)0U)
+    {
+      sz1 = block_len(i);
+    }
+    else
+    {
+      sz1 = (uint32_t)(total_len1 % (uint64_t)block_len(i));
+    }
+    if (!(sz1 == (uint32_t)0U))
+    {
+      Spec_Hash_Definitions_hash_alg a1 = block_state1.fst;
+      uint64_t *s2 = block_state1.snd;
+      Hacl_Hash_SHA3_update_multi_sha3(a1, s2, buf, block_len(i) / block_len(a1));
+    }
+    uint32_t ite;
+    if ((uint64_t)len % (uint64_t)block_len(i) == (uint64_t)0U && (uint64_t)len > (uint64_t)0U)
+    {
+      ite = block_len(i);
+    }
+    else
+    {
+      ite = (uint32_t)((uint64_t)len % (uint64_t)block_len(i));
+    }
+    uint32_t n_blocks = (len - ite) / block_len(i);
+    uint32_t data1_len = n_blocks * block_len(i);
+    uint32_t data2_len = len - data1_len;
+    uint8_t *data1 = data;
+    uint8_t *data2 = data + data1_len;
+    Spec_Hash_Definitions_hash_alg a1 = block_state1.fst;
+    uint64_t *s2 = block_state1.snd;
+    Hacl_Hash_SHA3_update_multi_sha3(a1, s2, data1, data1_len / block_len(a1));
+    uint8_t *dst = buf;
+    memcpy(dst, data2, data2_len * sizeof (uint8_t));
+    *p
+    =
+      (
+        (Hacl_Streaming_Keccak_state){
+          .block_state = block_state1,
+          .buf = buf,
+          .total_len = total_len1 + (uint64_t)len
+        }
+      );
+  }
+  else
+  {
+    uint32_t diff = block_len(i) - sz;
+    uint8_t *data1 = data;
+    uint8_t *data2 = data + diff;
+    Hacl_Streaming_Keccak_state s1 = *p;
+    Hacl_Streaming_Keccak_hash_buf block_state10 = s1.block_state;
+    uint8_t *buf0 = s1.buf;
+    uint64_t total_len10 = s1.total_len;
+    uint32_t sz10;
+    if (total_len10 % (uint64_t)block_len(i) == (uint64_t)0U && total_len10 > (uint64_t)0U)
+    {
+      sz10 = block_len(i);
+    }
+    else
+    {
+      sz10 = (uint32_t)(total_len10 % (uint64_t)block_len(i));
+    }
+    uint8_t *buf2 = buf0 + sz10;
+    memcpy(buf2, data1, diff * sizeof (uint8_t));
+    uint64_t total_len2 = total_len10 + (uint64_t)diff;
+    *p
+    =
+      (
+        (Hacl_Streaming_Keccak_state){
+          .block_state = block_state10,
+          .buf = buf0,
+          .total_len = total_len2
+        }
+      );
+    Hacl_Streaming_Keccak_state s10 = *p;
+    Hacl_Streaming_Keccak_hash_buf block_state1 = s10.block_state;
+    uint8_t *buf = s10.buf;
+    uint64_t total_len1 = s10.total_len;
+    uint32_t sz1;
+    if (total_len1 % (uint64_t)block_len(i) == (uint64_t)0U && total_len1 > (uint64_t)0U)
+    {
+      sz1 = block_len(i);
+    }
+    else
+    {
+      sz1 = (uint32_t)(total_len1 % (uint64_t)block_len(i));
+    }
+    if (!(sz1 == (uint32_t)0U))
+    {
+      Spec_Hash_Definitions_hash_alg a1 = block_state1.fst;
+      uint64_t *s2 = block_state1.snd;
+      Hacl_Hash_SHA3_update_multi_sha3(a1, s2, buf, block_len(i) / block_len(a1));
+    }
+    uint32_t ite;
+    if
+    (
+      (uint64_t)(len - diff)
+      % (uint64_t)block_len(i)
+      == (uint64_t)0U
+      && (uint64_t)(len - diff) > (uint64_t)0U
+    )
+    {
+      ite = block_len(i);
+    }
+    else
+    {
+      ite = (uint32_t)((uint64_t)(len - diff) % (uint64_t)block_len(i));
+    }
+    uint32_t n_blocks = (len - diff - ite) / block_len(i);
+    uint32_t data1_len = n_blocks * block_len(i);
+    uint32_t data2_len = len - diff - data1_len;
+    uint8_t *data11 = data2;
+    uint8_t *data21 = data2 + data1_len;
+    Spec_Hash_Definitions_hash_alg a1 = block_state1.fst;
+    uint64_t *s2 = block_state1.snd;
+    Hacl_Hash_SHA3_update_multi_sha3(a1, s2, data11, data1_len / block_len(a1));
+    uint8_t *dst = buf;
+    memcpy(dst, data21, data2_len * sizeof (uint8_t));
+    *p
+    =
+      (
+        (Hacl_Streaming_Keccak_state){
+          .block_state = block_state1,
+          .buf = buf,
+          .total_len = total_len1 + (uint64_t)(len - diff)
+        }
+      );
+  }
+  return (uint32_t)0U;
+}
+
+static void
+finish_(
+  Spec_Hash_Definitions_hash_alg a,
+  Hacl_Streaming_Keccak_state *p,
+  uint8_t *dst,
+  uint32_t l
+)
+{
+  Hacl_Streaming_Keccak_state scrut0 = *p;
+  Hacl_Streaming_Keccak_hash_buf block_state = scrut0.block_state;
+  uint8_t *buf_ = scrut0.buf;
+  uint64_t total_len = scrut0.total_len;
+  uint32_t r;
+  if (total_len % (uint64_t)block_len(a) == (uint64_t)0U && total_len > (uint64_t)0U)
+  {
+    r = block_len(a);
+  }
+  else
+  {
+    r = (uint32_t)(total_len % (uint64_t)block_len(a));
+  }
+  uint8_t *buf_1 = buf_;
+  uint64_t buf[25U] = { 0U };
+  Hacl_Streaming_Keccak_hash_buf tmp_block_state = { .fst = a, .snd = buf };
+  hash_buf2 scrut = { .fst = block_state, .snd = tmp_block_state };
+  uint64_t *s_dst = scrut.snd.snd;
+  uint64_t *s_src = scrut.fst.snd;
+  memcpy(s_dst, s_src, (uint32_t)25U * sizeof (uint64_t));
+  uint32_t ite0;
+  if (r % block_len(a) == (uint32_t)0U && r > (uint32_t)0U)
+  {
+    ite0 = block_len(a);
+  }
+  else
+  {
+    ite0 = r % block_len(a);
+  }
+  uint8_t *buf_last = buf_1 + r - ite0;
+  uint8_t *buf_multi = buf_1;
+  Spec_Hash_Definitions_hash_alg a1 = tmp_block_state.fst;
+  uint64_t *s0 = tmp_block_state.snd;
+  Hacl_Hash_SHA3_update_multi_sha3(a1, s0, buf_multi, (uint32_t)0U / block_len(a1));
+  Spec_Hash_Definitions_hash_alg a10 = tmp_block_state.fst;
+  uint64_t *s1 = tmp_block_state.snd;
+  Hacl_Hash_SHA3_update_last_sha3(a10, s1, buf_last, r);
+  Spec_Hash_Definitions_hash_alg a11 = tmp_block_state.fst;
+  uint64_t *s = tmp_block_state.snd;
+  if (a11 == Spec_Hash_Definitions_Shake128 || a11 == Spec_Hash_Definitions_Shake256)
+  {
+    uint32_t ite;
+    if (a11 == Spec_Hash_Definitions_Shake128 || a11 == Spec_Hash_Definitions_Shake256)
+    {
+      ite = l;
+    }
+    else
+    {
+      ite = hash_len(a11);
+    }
+    Hacl_Impl_SHA3_squeeze(s, block_len(a11), ite, dst);
+    return;
+  }
+  Hacl_Impl_SHA3_squeeze(s, block_len(a11), hash_len(a11), dst);
+}
+
+Hacl_Streaming_Keccak_error_code
+Hacl_Streaming_Keccak_finish(Hacl_Streaming_Keccak_state *s, uint8_t *dst)
+{
+  Spec_Hash_Definitions_hash_alg a1 = Hacl_Streaming_Keccak_get_alg(s);
+  if (a1 == Spec_Hash_Definitions_Shake128 || a1 == Spec_Hash_Definitions_Shake256)
+  {
+    return Hacl_Streaming_Keccak_InvalidAlgorithm;
+  }
+  finish_(a1, s, dst, hash_len(a1));
+  return Hacl_Streaming_Keccak_Success;
+}
+
+Hacl_Streaming_Keccak_error_code
+Hacl_Streaming_Keccak_squeeze(Hacl_Streaming_Keccak_state *s, uint8_t *dst, uint32_t l)
+{
+  Spec_Hash_Definitions_hash_alg a1 = Hacl_Streaming_Keccak_get_alg(s);
+  if (!(a1 == Spec_Hash_Definitions_Shake128 || a1 == Spec_Hash_Definitions_Shake256))
+  {
+    return Hacl_Streaming_Keccak_InvalidAlgorithm;
+  }
+  if (l == (uint32_t)0U)
+  {
+    return Hacl_Streaming_Keccak_InvalidLength;
+  }
+  finish_(a1, s, dst, l);
+  return Hacl_Streaming_Keccak_Success;
+}
+
+uint32_t Hacl_Streaming_Keccak_block_len(Hacl_Streaming_Keccak_state *s)
+{
+  Spec_Hash_Definitions_hash_alg a1 = Hacl_Streaming_Keccak_get_alg(s);
+  return block_len(a1);
+}
+
+uint32_t Hacl_Streaming_Keccak_hash_len(Hacl_Streaming_Keccak_state *s)
+{
+  Spec_Hash_Definitions_hash_alg a1 = Hacl_Streaming_Keccak_get_alg(s);
+  return hash_len(a1);
+}
+
+bool Hacl_Streaming_Keccak_is_shake(Hacl_Streaming_Keccak_state *s)
+{
+  Spec_Hash_Definitions_hash_alg uu____0 = Hacl_Streaming_Keccak_get_alg(s);
+  return uu____0 == Spec_Hash_Definitions_Shake128 || uu____0 == Spec_Hash_Definitions_Shake256;
+}
+
+void
+Hacl_SHA3_shake128_hacl(
+  uint32_t inputByteLen,
+  uint8_t *input,
+  uint32_t outputByteLen,
+  uint8_t *output
+)
+{
+  Hacl_Impl_SHA3_keccak((uint32_t)1344U,
+    (uint32_t)256U,
+    inputByteLen,
+    input,
+    (uint8_t)0x1FU,
+    outputByteLen,
+    output);
+}
+
+void
+Hacl_SHA3_shake256_hacl(
+  uint32_t inputByteLen,
+  uint8_t *input,
+  uint32_t outputByteLen,
+  uint8_t *output
+)
+{
+  Hacl_Impl_SHA3_keccak((uint32_t)1088U,
+    (uint32_t)512U,
+    inputByteLen,
+    input,
+    (uint8_t)0x1FU,
+    outputByteLen,
+    output);
+}
+
+void Hacl_SHA3_sha3_224(uint32_t inputByteLen, uint8_t *input, uint8_t *output)
+{
+  Hacl_Impl_SHA3_keccak((uint32_t)1152U,
+    (uint32_t)448U,
+    inputByteLen,
+    input,
+    (uint8_t)0x06U,
+    (uint32_t)28U,
+    output);
+}
+
+void Hacl_SHA3_sha3_256(uint32_t inputByteLen, uint8_t *input, uint8_t *output)
+{
+  Hacl_Impl_SHA3_keccak((uint32_t)1088U,
+    (uint32_t)512U,
+    inputByteLen,
+    input,
+    (uint8_t)0x06U,
+    (uint32_t)32U,
+    output);
+}
+
+void Hacl_SHA3_sha3_384(uint32_t inputByteLen, uint8_t *input, uint8_t *output)
+{
+  Hacl_Impl_SHA3_keccak((uint32_t)832U,
+    (uint32_t)768U,
+    inputByteLen,
+    input,
+    (uint8_t)0x06U,
+    (uint32_t)48U,
+    output);
+}
+
+void Hacl_SHA3_sha3_512(uint32_t inputByteLen, uint8_t *input, uint8_t *output)
+{
+  Hacl_Impl_SHA3_keccak((uint32_t)576U,
+    (uint32_t)1024U,
+    inputByteLen,
+    input,
+    (uint8_t)0x06U,
+    (uint32_t)64U,
+    output);
+}
+
+static const
+uint32_t
+keccak_rotc[24U] =
+  {
+    (uint32_t)1U, (uint32_t)3U, (uint32_t)6U, (uint32_t)10U, (uint32_t)15U, (uint32_t)21U,
+    (uint32_t)28U, (uint32_t)36U, (uint32_t)45U, (uint32_t)55U, (uint32_t)2U, (uint32_t)14U,
+    (uint32_t)27U, (uint32_t)41U, (uint32_t)56U, (uint32_t)8U, (uint32_t)25U, (uint32_t)43U,
+    (uint32_t)62U, (uint32_t)18U, (uint32_t)39U, (uint32_t)61U, (uint32_t)20U, (uint32_t)44U
+  };
+
+static const
+uint32_t
+keccak_piln[24U] =
+  {
+    (uint32_t)10U, (uint32_t)7U, (uint32_t)11U, (uint32_t)17U, (uint32_t)18U, (uint32_t)3U,
+    (uint32_t)5U, (uint32_t)16U, (uint32_t)8U, (uint32_t)21U, (uint32_t)24U, (uint32_t)4U,
+    (uint32_t)15U, (uint32_t)23U, (uint32_t)19U, (uint32_t)13U, (uint32_t)12U, (uint32_t)2U,
+    (uint32_t)20U, (uint32_t)14U, (uint32_t)22U, (uint32_t)9U, (uint32_t)6U, (uint32_t)1U
+  };
+
+static const
+uint64_t
+keccak_rndc[24U] =
+  {
+    (uint64_t)0x0000000000000001U, (uint64_t)0x0000000000008082U, (uint64_t)0x800000000000808aU,
+    (uint64_t)0x8000000080008000U, (uint64_t)0x000000000000808bU, (uint64_t)0x0000000080000001U,
+    (uint64_t)0x8000000080008081U, (uint64_t)0x8000000000008009U, (uint64_t)0x000000000000008aU,
+    (uint64_t)0x0000000000000088U, (uint64_t)0x0000000080008009U, (uint64_t)0x000000008000000aU,
+    (uint64_t)0x000000008000808bU, (uint64_t)0x800000000000008bU, (uint64_t)0x8000000000008089U,
+    (uint64_t)0x8000000000008003U, (uint64_t)0x8000000000008002U, (uint64_t)0x8000000000000080U,
+    (uint64_t)0x000000000000800aU, (uint64_t)0x800000008000000aU, (uint64_t)0x8000000080008081U,
+    (uint64_t)0x8000000000008080U, (uint64_t)0x0000000080000001U, (uint64_t)0x8000000080008008U
+  };
+
+void Hacl_Impl_SHA3_state_permute(uint64_t *s)
+{
+  for (uint32_t i0 = (uint32_t)0U; i0 < (uint32_t)24U; i0++)
+  {
+    uint64_t _C[5U] = { 0U };
+    KRML_MAYBE_FOR5(i,
+      (uint32_t)0U,
+      (uint32_t)5U,
+      (uint32_t)1U,
+      _C[i] =
+        s[i
+        + (uint32_t)0U]
+        ^
+          (s[i
+          + (uint32_t)5U]
+          ^ (s[i + (uint32_t)10U] ^ (s[i + (uint32_t)15U] ^ s[i + (uint32_t)20U]))););
+    KRML_MAYBE_FOR5(i1,
+      (uint32_t)0U,
+      (uint32_t)5U,
+      (uint32_t)1U,
+      uint64_t uu____0 = _C[(i1 + (uint32_t)1U) % (uint32_t)5U];
+      uint64_t
+      _D =
+        _C[(i1 + (uint32_t)4U)
+        % (uint32_t)5U]
+        ^ (uu____0 << (uint32_t)1U | uu____0 >> (uint32_t)63U);
+      KRML_MAYBE_FOR5(i,
+        (uint32_t)0U,
+        (uint32_t)5U,
+        (uint32_t)1U,
+        s[i1 + (uint32_t)5U * i] = s[i1 + (uint32_t)5U * i] ^ _D;););
+    uint64_t x = s[1U];
+    uint64_t current = x;
+    for (uint32_t i = (uint32_t)0U; i < (uint32_t)24U; i++)
+    {
+      uint32_t _Y = keccak_piln[i];
+      uint32_t r = keccak_rotc[i];
+      uint64_t temp = s[_Y];
+      uint64_t uu____1 = current;
+      s[_Y] = uu____1 << r | uu____1 >> ((uint32_t)64U - r);
+      current = temp;
+    }
+    KRML_MAYBE_FOR5(i,
+      (uint32_t)0U,
+      (uint32_t)5U,
+      (uint32_t)1U,
+      uint64_t
+      v0 =
+        s[(uint32_t)0U
+        + (uint32_t)5U * i]
+        ^ (~s[(uint32_t)1U + (uint32_t)5U * i] & s[(uint32_t)2U + (uint32_t)5U * i]);
+      uint64_t
+      v1 =
+        s[(uint32_t)1U
+        + (uint32_t)5U * i]
+        ^ (~s[(uint32_t)2U + (uint32_t)5U * i] & s[(uint32_t)3U + (uint32_t)5U * i]);
+      uint64_t
+      v2 =
+        s[(uint32_t)2U
+        + (uint32_t)5U * i]
+        ^ (~s[(uint32_t)3U + (uint32_t)5U * i] & s[(uint32_t)4U + (uint32_t)5U * i]);
+      uint64_t
+      v3 =
+        s[(uint32_t)3U
+        + (uint32_t)5U * i]
+        ^ (~s[(uint32_t)4U + (uint32_t)5U * i] & s[(uint32_t)0U + (uint32_t)5U * i]);
+      uint64_t
+      v4 =
+        s[(uint32_t)4U
+        + (uint32_t)5U * i]
+        ^ (~s[(uint32_t)0U + (uint32_t)5U * i] & s[(uint32_t)1U + (uint32_t)5U * i]);
+      s[(uint32_t)0U + (uint32_t)5U * i] = v0;
+      s[(uint32_t)1U + (uint32_t)5U * i] = v1;
+      s[(uint32_t)2U + (uint32_t)5U * i] = v2;
+      s[(uint32_t)3U + (uint32_t)5U * i] = v3;
+      s[(uint32_t)4U + (uint32_t)5U * i] = v4;);
+    uint64_t c = keccak_rndc[i0];
+    s[0U] = s[0U] ^ c;
+  }
+}
+
+void Hacl_Impl_SHA3_loadState(uint32_t rateInBytes, uint8_t *input, uint64_t *s)
+{
+  uint8_t block[200U] = { 0U };
+  memcpy(block, input, rateInBytes * sizeof (uint8_t));
+  for (uint32_t i = (uint32_t)0U; i < (uint32_t)25U; i++)
+  {
+    uint64_t u = load64_le(block + i * (uint32_t)8U);
+    uint64_t x = u;
+    s[i] = s[i] ^ x;
+  }
+}
+
+static void storeState(uint32_t rateInBytes, uint64_t *s, uint8_t *res)
+{
+  uint8_t block[200U] = { 0U };
+  for (uint32_t i = (uint32_t)0U; i < (uint32_t)25U; i++)
+  {
+    uint64_t sj = s[i];
+    store64_le(block + i * (uint32_t)8U, sj);
+  }
+  memcpy(res, block, rateInBytes * sizeof (uint8_t));
+}
+
+void Hacl_Impl_SHA3_absorb_inner(uint32_t rateInBytes, uint8_t *block, uint64_t *s)
+{
+  Hacl_Impl_SHA3_loadState(rateInBytes, block, s);
+  Hacl_Impl_SHA3_state_permute(s);
+}
+
+static void
+absorb(
+  uint64_t *s,
+  uint32_t rateInBytes,
+  uint32_t inputByteLen,
+  uint8_t *input,
+  uint8_t delimitedSuffix
+)
+{
+  uint32_t n_blocks = inputByteLen / rateInBytes;
+  uint32_t rem = inputByteLen % rateInBytes;
+  for (uint32_t i = (uint32_t)0U; i < n_blocks; i++)
+  {
+    uint8_t *block = input + i * rateInBytes;
+    Hacl_Impl_SHA3_absorb_inner(rateInBytes, block, s);
+  }
+  uint8_t *last = input + n_blocks * rateInBytes;
+  uint8_t lastBlock_[200U] = { 0U };
+  uint8_t *lastBlock = lastBlock_;
+  memcpy(lastBlock, last, rem * sizeof (uint8_t));
+  lastBlock[rem] = delimitedSuffix;
+  Hacl_Impl_SHA3_loadState(rateInBytes, lastBlock, s);
+  if (!((delimitedSuffix & (uint8_t)0x80U) == (uint8_t)0U) && rem == rateInBytes - (uint32_t)1U)
+  {
+    Hacl_Impl_SHA3_state_permute(s);
+  }
+  uint8_t nextBlock_[200U] = { 0U };
+  uint8_t *nextBlock = nextBlock_;
+  nextBlock[rateInBytes - (uint32_t)1U] = (uint8_t)0x80U;
+  Hacl_Impl_SHA3_loadState(rateInBytes, nextBlock, s);
+  Hacl_Impl_SHA3_state_permute(s);
+}
+
+void
+Hacl_Impl_SHA3_squeeze(
+  uint64_t *s,
+  uint32_t rateInBytes,
+  uint32_t outputByteLen,
+  uint8_t *output
+)
+{
+  uint32_t outBlocks = outputByteLen / rateInBytes;
+  uint32_t remOut = outputByteLen % rateInBytes;
+  uint8_t *last = output + outputByteLen - remOut;
+  uint8_t *blocks = output;
+  for (uint32_t i = (uint32_t)0U; i < outBlocks; i++)
+  {
+    storeState(rateInBytes, s, blocks + i * rateInBytes);
+    Hacl_Impl_SHA3_state_permute(s);
+  }
+  storeState(remOut, s, last);
+}
+
+void
+Hacl_Impl_SHA3_keccak(
+  uint32_t rate,
+  uint32_t capacity,
+  uint32_t inputByteLen,
+  uint8_t *input,
+  uint8_t delimitedSuffix,
+  uint32_t outputByteLen,
+  uint8_t *output
+)
+{
+  uint32_t rateInBytes = rate / (uint32_t)8U;
+  uint64_t s[25U] = { 0U };
+  absorb(s, rateInBytes, inputByteLen, input, delimitedSuffix);
+  Hacl_Impl_SHA3_squeeze(s, rateInBytes, outputByteLen, output);
+}
+
diff --git a/Modules/_hacl/Hacl_Hash_SHA3.h b/Modules/_hacl/Hacl_Hash_SHA3.h
new file mode 100644
index 000000000000..2a5cf4b1844b
--- /dev/null
+++ b/Modules/_hacl/Hacl_Hash_SHA3.h
@@ -0,0 +1,136 @@
+/* MIT License
+ *
+ * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation
+ * Copyright (c) 2022-2023 HACL* Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#ifndef __Hacl_Hash_SHA3_H
+#define __Hacl_Hash_SHA3_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include <string.h>
+#include "krml/types.h"
+#include "krml/lowstar_endianness.h"
+#include "krml/internal/target.h"
+
+#include "Hacl_Streaming_Types.h"
+
+typedef struct Hacl_Streaming_Keccak_hash_buf_s
+{
+  Spec_Hash_Definitions_hash_alg fst;
+  uint64_t *snd;
+}
+Hacl_Streaming_Keccak_hash_buf;
+
+typedef struct Hacl_Streaming_Keccak_state_s
+{
+  Hacl_Streaming_Keccak_hash_buf block_state;
+  uint8_t *buf;
+  uint64_t total_len;
+}
+Hacl_Streaming_Keccak_state;
+
+Spec_Hash_Definitions_hash_alg Hacl_Streaming_Keccak_get_alg(Hacl_Streaming_Keccak_state *s);
+
+Hacl_Streaming_Keccak_state *Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_hash_alg a);
+
+void Hacl_Streaming_Keccak_free(Hacl_Streaming_Keccak_state *s);
+
+Hacl_Streaming_Keccak_state *Hacl_Streaming_Keccak_copy(Hacl_Streaming_Keccak_state *s0);
+
+void Hacl_Streaming_Keccak_reset(Hacl_Streaming_Keccak_state *s);
+
+uint32_t
+Hacl_Streaming_Keccak_update(Hacl_Streaming_Keccak_state *p, uint8_t *data, uint32_t len);
+
+#define Hacl_Streaming_Keccak_Success 0
+#define Hacl_Streaming_Keccak_InvalidAlgorithm 1
+#define Hacl_Streaming_Keccak_InvalidLength 2
+
+typedef uint8_t Hacl_Streaming_Keccak_error_code;
+
+Hacl_Streaming_Keccak_error_code
+Hacl_Streaming_Keccak_finish(Hacl_Streaming_Keccak_state *s, uint8_t *dst);
+
+Hacl_Streaming_Keccak_error_code
+Hacl_Streaming_Keccak_squeeze(Hacl_Streaming_Keccak_state *s, uint8_t *dst, uint32_t l);
+
+uint32_t Hacl_Streaming_Keccak_block_len(Hacl_Streaming_Keccak_state *s);
+
+uint32_t Hacl_Streaming_Keccak_hash_len(Hacl_Streaming_Keccak_state *s);
+
+bool Hacl_Streaming_Keccak_is_shake(Hacl_Streaming_Keccak_state *s);
+
+void
+Hacl_SHA3_shake128_hacl(
+  uint32_t inputByteLen,
+  uint8_t *input,
+  uint32_t outputByteLen,
+  uint8_t *output
+);
+
+void
+Hacl_SHA3_shake256_hacl(
+  uint32_t inputByteLen,
+  uint8_t *input,
+  uint32_t outputByteLen,
+  uint8_t *output
+);
+
+void Hacl_SHA3_sha3_224(uint32_t inputByteLen, uint8_t *input, uint8_t *output);
+
+void Hacl_SHA3_sha3_256(uint32_t inputByteLen, uint8_t *input, uint8_t *output);
+
+void Hacl_SHA3_sha3_384(uint32_t inputByteLen, uint8_t *input, uint8_t *output);
+
+void Hacl_SHA3_sha3_512(uint32_t inputByteLen, uint8_t *input, uint8_t *output);
+
+void Hacl_Impl_SHA3_absorb_inner(uint32_t rateInBytes, uint8_t *block, uint64_t *s);
+
+void
+Hacl_Impl_SHA3_squeeze(
+  uint64_t *s,
+  uint32_t rateInBytes,
+  uint32_t outputByteLen,
+  uint8_t *output
+);
+
+void
+Hacl_Impl_SHA3_keccak(
+  uint32_t rate,
+  uint32_t capacity,
+  uint32_t inputByteLen,
+  uint8_t *input,
+  uint8_t delimitedSuffix,
+  uint32_t outputByteLen,
+  uint8_t *output
+);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define __Hacl_Hash_SHA3_H_DEFINED
+#endif
diff --git a/Modules/_hacl/Hacl_Streaming_Types.h b/Modules/_hacl/Hacl_Streaming_Types.h
index 51057611ca97..8a60b707bc49 100644
--- a/Modules/_hacl/Hacl_Streaming_Types.h
+++ b/Modules/_hacl/Hacl_Streaming_Types.h
@@ -35,6 +35,23 @@ extern "C" {
 #include "krml/lowstar_endianness.h"
 #include "krml/internal/target.h"
 
+#define Spec_Hash_Definitions_SHA2_224 0
+#define Spec_Hash_Definitions_SHA2_256 1
+#define Spec_Hash_Definitions_SHA2_384 2
+#define Spec_Hash_Definitions_SHA2_512 3
+#define Spec_Hash_Definitions_SHA1 4
+#define Spec_Hash_Definitions_MD5 5
+#define Spec_Hash_Definitions_Blake2S 6
+#define Spec_Hash_Definitions_Blake2B 7
+#define Spec_Hash_Definitions_SHA3_256 8
+#define Spec_Hash_Definitions_SHA3_224 9
+#define Spec_Hash_Definitions_SHA3_384 10
+#define Spec_Hash_Definitions_SHA3_512 11
+#define Spec_Hash_Definitions_Shake128 12
+#define Spec_Hash_Definitions_Shake256 13
+
+typedef uint8_t Spec_Hash_Definitions_hash_alg;
+
 typedef struct Hacl_Streaming_MD_state_32_s
 {
   uint32_t *block_state;
diff --git a/Modules/_hacl/include/krml/internal/target.h b/Modules/_hacl/include/krml/internal/target.h
index dcbe7007b17b..5a2f94eb2ec8 100644
--- a/Modules/_hacl/include/krml/internal/target.h
+++ b/Modules/_hacl/include/krml/internal/target.h
@@ -19,6 +19,28 @@
 #  define inline __inline__
 #endif
 
+/******************************************************************************/
+/* Macros that KaRaMeL will generate.                                         */
+/******************************************************************************/
+
+/* For "bare" targets that do not have a C stdlib, the user might want to use
+ * [-add-early-include '"mydefinitions.h"'] and override these. */
+#ifndef KRML_HOST_PRINTF
+#  define KRML_HOST_PRINTF printf
+#endif
+
+#if (                                                                          \
+    (defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) &&             \
+    (!(defined KRML_HOST_EPRINTF)))
+#  define KRML_HOST_EPRINTF(...) fprintf(stderr, __VA_ARGS__)
+#elif !(defined KRML_HOST_EPRINTF) && defined(_MSC_VER)
+#  define KRML_HOST_EPRINTF(...) fprintf(stderr, __VA_ARGS__)
+#endif
+
+#ifndef KRML_HOST_EXIT
+#  define KRML_HOST_EXIT exit
+#endif
+
 #ifndef KRML_HOST_MALLOC
 #  define KRML_HOST_MALLOC malloc
 #endif
@@ -35,6 +57,28 @@
 #  define KRML_HOST_IGNORE(x) (void)(x)
 #endif
 
+/* In FStar.Buffer.fst, the size of arrays is uint32_t, but it's a number of
+ * *elements*. Do an ugly, run-time check (some of which KaRaMeL can eliminate).
+ */
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4))
+#  define _KRML_CHECK_SIZE_PRAGMA                                              \
+    _Pragma("GCC diagnostic ignored \"-Wtype-limits\"")
+#else
+#  define _KRML_CHECK_SIZE_PRAGMA
+#endif
+
+#define KRML_CHECK_SIZE(size_elt, sz)                                          \
+  do {                                                                         \
+    _KRML_CHECK_SIZE_PRAGMA                                                    \
+    if (((size_t)(sz)) > ((size_t)(SIZE_MAX / (size_elt)))) {                  \
+      KRML_HOST_PRINTF(                                                        \
+          "Maximum allocatable size exceeded, aborting before overflow at "    \
+          "%s:%d\n",                                                           \
+          __FILE__, __LINE__);                                                 \
+      KRML_HOST_EXIT(253);                                                     \
+    }                                                                          \
+  } while (0)
+
 /* Macros for prettier unrolling of loops */
 #define KRML_LOOP1(i, n, x) { \
   x \
diff --git a/Modules/_hacl/include/krml/lowstar_endianness.h b/Modules/_hacl/include/krml/lowstar_endianness.h
index 32a7391e817e..1aa2ccd644c0 100644
--- a/Modules/_hacl/include/krml/lowstar_endianness.h
+++ b/Modules/_hacl/include/krml/lowstar_endianness.h
@@ -77,7 +77,7 @@
 #  define le64toh(x) (x)
 
 /* ... for Windows (GCC-like, e.g. mingw or clang) */
-#elif (defined(_WIN32) || defined(_WIN64)) &&                                  \
+#elif (defined(_WIN32) || defined(_WIN64) || defined(__EMSCRIPTEN__)) &&       \
     (defined(__GNUC__) || defined(__clang__))
 
 #  define htobe16(x) __builtin_bswap16(x)
@@ -96,7 +96,8 @@
 #  define le64toh(x) (x)
 
 /* ... generic big-endian fallback code */
-#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+/* ... AIX doesn't have __BYTE_ORDER__ (with XLC compiler) & is always big-endian */
+#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || defined(_AIX)
 
 /* byte swapping code inspired by:
  * https://github.com/rweather/arduinolibs/blob/master/libraries/Crypto/utility/EndianUtil.h
diff --git a/Modules/_hacl/internal/Hacl_Hash_SHA3.h b/Modules/_hacl/internal/Hacl_Hash_SHA3.h
new file mode 100644
index 000000000000..1c9808b8dd49
--- /dev/null
+++ b/Modules/_hacl/internal/Hacl_Hash_SHA3.h
@@ -0,0 +1,65 @@
+/* MIT License
+ *
+ * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation
+ * Copyright (c) 2022-2023 HACL* Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#ifndef __internal_Hacl_Hash_SHA3_H
+#define __internal_Hacl_Hash_SHA3_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include <string.h>
+#include "krml/types.h"
+#include "krml/lowstar_endianness.h"
+#include "krml/internal/target.h"
+
+#include "../Hacl_Hash_SHA3.h"
+
+void
+Hacl_Hash_SHA3_update_multi_sha3(
+  Spec_Hash_Definitions_hash_alg a,
+  uint64_t *s,
+  uint8_t *blocks,
+  uint32_t n_blocks
+);
+
+void
+Hacl_Hash_SHA3_update_last_sha3(
+  Spec_Hash_Definitions_hash_alg a,
+  uint64_t *s,
+  uint8_t *input,
+  uint32_t input_len
+);
+
+void Hacl_Impl_SHA3_state_permute(uint64_t *s);
+
+void Hacl_Impl_SHA3_loadState(uint32_t rateInBytes, uint8_t *input, uint64_t *s);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define __internal_Hacl_Hash_SHA3_H_DEFINED
+#endif
diff --git a/Modules/_hacl/python_hacl_namespaces.h b/Modules/_hacl/python_hacl_namespaces.h
index ee28f244266b..0df236282ac5 100644
--- a/Modules/_hacl/python_hacl_namespaces.h
+++ b/Modules/_hacl/python_hacl_namespaces.h
@@ -59,5 +59,28 @@
 #define Hacl_Streaming_SHA1_legacy_copy python_hashlib_Hacl_Streaming_SHA1_legacy_copy
 #define Hacl_Streaming_SHA1_legacy_hash python_hashlib_Hacl_Streaming_SHA1_legacy_hash
 
+#define Hacl_Hash_SHA3_update_last_sha3 python_hashlib_Hacl_Hash_SHA3_update_last_sha3
+#define Hacl_Hash_SHA3_update_multi_sha3 python_hashlib_Hacl_Hash_SHA3_update_multi_sha3
+#define Hacl_Impl_SHA3_absorb_inner python_hashlib_Hacl_Impl_SHA3_absorb_inner
+#define Hacl_Impl_SHA3_keccak python_hashlib_Hacl_Impl_SHA3_keccak
+#define Hacl_Impl_SHA3_loadState python_hashlib_Hacl_Impl_SHA3_loadState
+#define Hacl_Impl_SHA3_squeeze python_hashlib_Hacl_Impl_SHA3_squeeze
+#define Hacl_Impl_SHA3_state_permute python_hashlib_Hacl_Impl_SHA3_state_permute
+#define Hacl_SHA3_sha3_224 python_hashlib_Hacl_SHA3_sha3_224
+#define Hacl_SHA3_sha3_256 python_hashlib_Hacl_SHA3_sha3_256
+#define Hacl_SHA3_sha3_384 python_hashlib_Hacl_SHA3_sha3_384
+#define Hacl_SHA3_sha3_512 python_hashlib_Hacl_SHA3_sha3_512
+#define Hacl_SHA3_shake128_hacl python_hashlib_Hacl_SHA3_shake128_hacl
+#define Hacl_SHA3_shake256_hacl python_hashlib_Hacl_SHA3_shake256_hacl
+#define Hacl_Streaming_Keccak_block_len python_hashlib_Hacl_Streaming_Keccak_block_len
+#define Hacl_Streaming_Keccak_copy python_hashlib_Hacl_Streaming_Keccak_copy
+#define Hacl_Streaming_Keccak_finish python_hashlib_Hacl_Streaming_Keccak_finish
+#define Hacl_Streaming_Keccak_free python_hashlib_Hacl_Streaming_Keccak_free
+#define Hacl_Streaming_Keccak_get_alg python_hashlib_Hacl_Streaming_Keccak_get_alg
+#define Hacl_Streaming_Keccak_hash_len python_hashlib_Hacl_Streaming_Keccak_hash_len
+#define Hacl_Streaming_Keccak_is_shake python_hashlib_Hacl_Streaming_Keccak_is_shake
+#define Hacl_Streaming_Keccak_malloc python_hashlib_Hacl_Streaming_Keccak_malloc
+#define Hacl_Streaming_Keccak_reset python_hashlib_Hacl_Streaming_Keccak_reset
+#define Hacl_Streaming_Keccak_update python_hashlib_Hacl_Streaming_Keccak_update
 
 #endif  // _PYTHON_HACL_NAMESPACES_H
diff --git a/Modules/_hacl/refresh.sh b/Modules/_hacl/refresh.sh
index 76b92ec45991..220ebbe55613 100755
--- a/Modules/_hacl/refresh.sh
+++ b/Modules/_hacl/refresh.sh
@@ -22,7 +22,7 @@ fi
 
 # Update this when updating to a new version after verifying that the changes
 # the update brings in are good.
-expected_hacl_star_rev=13e0c6721ac9206c4249ecc1dc04ed617ad1e262
+expected_hacl_star_rev=363eae2c2eb60e46f182ddd4bd1cd3f1d00b35c9
 
 hacl_dir="$(realpath "$1")"
 cd "$(dirname "$0")"
@@ -45,11 +45,14 @@ dist_files=(
   Hacl_Hash_SHA1.h
   internal/Hacl_Hash_SHA1.h
   Hacl_Hash_MD5.h
+  Hacl_Hash_SHA3.h
   internal/Hacl_Hash_MD5.h
+  internal/Hacl_Hash_SHA3.h
   internal/Hacl_SHA2_Generic.h
   Hacl_Streaming_SHA2.c
   Hacl_Hash_SHA1.c
   Hacl_Hash_MD5.c
+  Hacl_Hash_SHA3.c
 )
 
 declare -a include_files
@@ -134,9 +137,9 @@ $sed -i -z 's!#include <string.h>\n!#include <string.h>\n#include "python_hacl_n
 
 # Finally, we remove a bunch of ifdefs from target.h that are, again, useful in
 # the general case, but not exercised by the subset of HACL* that we vendor.
-$sed -z -i 's!#ifndef KRML_\(HOST_PRINTF\|HOST_EXIT\|PRE_ALIGN\|POST_ALIGN\|ALIGNED_MALLOC\|ALIGNED_FREE\|HOST_TIME\)\n\(\n\|#  [^\n]*\n\|[^#][^\n]*\n\)*#endif\n\n!!g' include/krml/internal/target.h
-$sed -z -i 's!\n\n\([^#][^\n]*\n\)*#define KRML_\(EABORT\|EXIT\|CHECK_SIZE\)[^\n]*\(\n  [^\n]*\)*!!g' include/krml/internal/target.h
+$sed -z -i 's!#ifndef KRML_\(PRE_ALIGN\|POST_ALIGN\|ALIGNED_MALLOC\|ALIGNED_FREE\|HOST_TIME\)\n\(\n\|#  [^\n]*\n\|[^#][^\n]*\n\)*#endif\n\n!!g' include/krml/internal/target.h
+$sed -z -i 's!\n\n\([^#][^\n]*\n\)*#define KRML_\(EABORT\|EXIT\)[^\n]*\(\n  [^\n]*\)*!!g' include/krml/internal/target.h
 $sed -z -i 's!\n\n\([^#][^\n]*\n\)*#if [^\n]*\n\(  [^\n]*\n\)*#define  KRML_\(EABORT\|EXIT\|CHECK_SIZE\)[^\n]*\(\n  [^\n]*\)*!!g' include/krml/internal/target.h
-$sed -z -i 's!\n\n\([^#][^\n]*\n\)*#if [^\n]*\n\(  [^\n]*\n\)*#  define _\?KRML_\(DEPRECATED\|CHECK_SIZE_PRAGMA\|HOST_EPRINTF\|HOST_SNPRINTF\)[^\n]*\n\([^#][^\n]*\n\|#el[^\n]*\n\|#  [^\n]*\n\)*#endif!!g' include/krml/internal/target.h
+$sed -z -i 's!\n\n\([^#][^\n]*\n\)*#if [^\n]*\n\(  [^\n]*\n\)*#  define _\?KRML_\(DEPRECATED\|HOST_SNPRINTF\)[^\n]*\n\([^#][^\n]*\n\|#el[^\n]*\n\|#  [^\n]*\n\)*#endif!!g' include/krml/internal/target.h
 
 echo "Updated; verify all is okay using git diff and git status."
diff --git a/Modules/_sha3/LICENSE b/Modules/_sha3/LICENSE
deleted file mode 100644
index d2d484d8820d..000000000000
--- a/Modules/_sha3/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015 Markku-Juhani O. Saarinen
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
diff --git a/Modules/_sha3/README.txt b/Modules/_sha3/README.txt
deleted file mode 100644
index b35919b01677..000000000000
--- a/Modules/_sha3/README.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-tiny_sha3
-=========
-
-https://github.com/mjosaarinen/tiny_sha3
-commit dcbb3192047c2a721f5f851db591871d428036a9
-
-- All functions have been converted to static functions.
-- sha3() function is commented out.
diff --git a/Modules/_sha3/sha3.c b/Modules/_sha3/sha3.c
deleted file mode 100644
index e2d3fd7b8ad8..000000000000
--- a/Modules/_sha3/sha3.c
+++ /dev/null
@@ -1,193 +0,0 @@
-// sha3.c
-// 19-Nov-11  Markku-Juhani O. Saarinen <mjos at iki.fi>
-
-// Revised 07-Aug-15 to match with official release of FIPS PUB 202 "SHA3"
-// Revised 03-Sep-15 for portability + OpenSSL - style API
-
-#include "sha3.h"
-
-// update the state with given number of rounds
-
-static void sha3_keccakf(uint64_t st[25])
-{
-    // constants
-    const uint64_t keccakf_rndc[24] = {
-        0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
-        0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
-        0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
-        0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
-        0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
-        0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
-        0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
-        0x8000000000008080, 0x0000000080000001, 0x8000000080008008
-    };
-    const int keccakf_rotc[24] = {
-        1,  3,  6,  10, 15, 21, 28, 36, 45, 55, 2,  14,
-        27, 41, 56, 8,  25, 43, 62, 18, 39, 61, 20, 44
-    };
-    const int keccakf_piln[24] = {
-        10, 7,  11, 17, 18, 3, 5,  16, 8,  21, 24, 4,
-        15, 23, 19, 13, 12, 2, 20, 14, 22, 9,  6,  1
-    };
-
-    // variables
-    int i, j, r;
-    uint64_t t, bc[5];
-
-#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
-    uint8_t *v;
-
-    // endianess conversion. this is redundant on little-endian targets
-    for (i = 0; i < 25; i++) {
-        v = (uint8_t *) &st[i];
-        st[i] = ((uint64_t) v[0])     | (((uint64_t) v[1]) << 8) |
-            (((uint64_t) v[2]) << 16) | (((uint64_t) v[3]) << 24) |
-            (((uint64_t) v[4]) << 32) | (((uint64_t) v[5]) << 40) |
-            (((uint64_t) v[6]) << 48) | (((uint64_t) v[7]) << 56);
-    }
-#endif
-
-    // actual iteration
-    for (r = 0; r < KECCAKF_ROUNDS; r++) {
-
-        // Theta
-        for (i = 0; i < 5; i++)
-            bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20];
-
-        for (i = 0; i < 5; i++) {
-            t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1);
-            for (j = 0; j < 25; j += 5)
-                st[j + i] ^= t;
-        }
-
-        // Rho Pi
-        t = st[1];
-        for (i = 0; i < 24; i++) {
-            j = keccakf_piln[i];
-            bc[0] = st[j];
-            st[j] = ROTL64(t, keccakf_rotc[i]);
-            t = bc[0];
-        }
-
-        //  Chi
-        for (j = 0; j < 25; j += 5) {
-            for (i = 0; i < 5; i++)
-                bc[i] = st[j + i];
-            for (i = 0; i < 5; i++)
-                st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5];
-        }
-
-        //  Iota
-        st[0] ^= keccakf_rndc[r];
-    }
-
-#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
-    // endianess conversion. this is redundant on little-endian targets
-    for (i = 0; i < 25; i++) {
-        v = (uint8_t *) &st[i];
-        t = st[i];
-        v[0] = t & 0xFF;
-        v[1] = (t >> 8) & 0xFF;
-        v[2] = (t >> 16) & 0xFF;
-        v[3] = (t >> 24) & 0xFF;
-        v[4] = (t >> 32) & 0xFF;
-        v[5] = (t >> 40) & 0xFF;
-        v[6] = (t >> 48) & 0xFF;
-        v[7] = (t >> 56) & 0xFF;
-    }
-#endif
-}
-
-// Initialize the context for SHA3
-
-static int sha3_init(sha3_ctx_t *c, int mdlen)
-{
-    int i;
-
-    for (i = 0; i < 25; i++)
-        c->st.q[i] = 0;
-    c->mdlen = mdlen;
-    c->rsiz = 200 - 2 * mdlen;
-    c->pt = 0;
-
-    return 1;
-}
-
-// update state with more data
-
-static int sha3_update(sha3_ctx_t *c, const void *data, size_t len)
-{
-    size_t i;
-    int j;
-
-    j = c->pt;
-    for (i = 0; i < len; i++) {
-        c->st.b[j++] ^= ((const uint8_t *) data)[i];
-        if (j >= c->rsiz) {
-            sha3_keccakf(c->st.q);
-            j = 0;
-        }
-    }
-    c->pt = j;
-
-    return 1;
-}
-
-// finalize and output a hash
-
-static int sha3_final(void *md, sha3_ctx_t *c)
-{
-    int i;
-
-    c->st.b[c->pt] ^= 0x06;
-    c->st.b[c->rsiz - 1] ^= 0x80;
-    sha3_keccakf(c->st.q);
-
-    for (i = 0; i < c->mdlen; i++) {
-        ((uint8_t *) md)[i] = c->st.b[i];
-    }
-
-    return 1;
-}
-
-#if 0
-// compute a SHA-3 hash (md) of given byte length from "in"
-
-void *sha3(const void *in, size_t inlen, void *md, int mdlen)
-{
-    sha3_ctx_t sha3;
-
-    sha3_init(&sha3, mdlen);
-    sha3_update(&sha3, in, inlen);
-    sha3_final(md, &sha3);
-
-    return md;
-}
-#endif
-
-// SHAKE128 and SHAKE256 extensible-output functionality
-
-static void shake_xof(sha3_ctx_t *c)
-{
-    c->st.b[c->pt] ^= 0x1F;
-    c->st.b[c->rsiz - 1] ^= 0x80;
-    sha3_keccakf(c->st.q);
-    c->pt = 0;
-}
-
-static void shake_out(sha3_ctx_t *c, void *out, size_t len)
-{
-    size_t i;
-    int j;
-
-    j = c->pt;
-    for (i = 0; i < len; i++) {
-        if (j >= c->rsiz) {
-            sha3_keccakf(c->st.q);
-            j = 0;
-        }
-        ((uint8_t *) out)[i] = c->st.b[j++];
-    }
-    c->pt = j;
-}
-
diff --git a/Modules/_sha3/sha3.h b/Modules/_sha3/sha3.h
deleted file mode 100644
index f973d6733ec2..000000000000
--- a/Modules/_sha3/sha3.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// sha3.h
-// 19-Nov-11  Markku-Juhani O. Saarinen <mjos at iki.fi>
-
-#ifndef SHA3_H
-#define SHA3_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#ifndef KECCAKF_ROUNDS
-#define KECCAKF_ROUNDS 24
-#endif
-
-#ifndef ROTL64
-#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))
-#endif
-
-// state context
-typedef struct {
-    union {                                 // state:
-        uint8_t b[200];                     // 8-bit bytes
-        uint64_t q[25];                     // 64-bit words
-    } st;
-    int pt, rsiz, mdlen;                    // these don't overflow
-} sha3_ctx_t;
-
-// Compression function.
-static void sha3_keccakf(uint64_t st[25]);
-
-// OpenSSL - like interfece
-static int sha3_init(sha3_ctx_t *c, int mdlen);    // mdlen = hash output in bytes
-static int sha3_update(sha3_ctx_t *c, const void *data, size_t len);
-static int sha3_final(void *md, sha3_ctx_t *c);    // digest goes to md
-
-// compute a sha3 hash (md) of given byte length from "in"
-#if 0
-static void *sha3(const void *in, size_t inlen, void *md, int mdlen);
-#endif
-
-// SHAKE128 and SHAKE256 extensible-output functions
-#define shake128_init(c) sha3_init(c, 16)
-#define shake256_init(c) sha3_init(c, 32)
-#define shake_update sha3_update
-
-static void shake_xof(sha3_ctx_t *c);
-static void shake_out(sha3_ctx_t *c, void *out, size_t len);
-
-#endif
-
diff --git a/Modules/_sha3/clinic/sha3module.c.h b/Modules/clinic/sha3module.c.h
similarity index 98%
rename from Modules/_sha3/clinic/sha3module.c.h
rename to Modules/clinic/sha3module.c.h
index a0c7c1c043e5..299803a3420b 100644
--- a/Modules/_sha3/clinic/sha3module.c.h
+++ b/Modules/clinic/sha3module.c.h
@@ -12,7 +12,7 @@ PyDoc_STRVAR(py_sha3_new__doc__,
 "sha3_224(data=b\'\', /, *, usedforsecurity=True)\n"
 "--\n"
 "\n"
-"Return a new BLAKE2b hash object.");
+"Return a new SHA3 hash object.");
 
 static PyObject *
 py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity);
@@ -193,4 +193,4 @@ _sha3_shake_128_hexdigest(SHA3object *self, PyObject *arg)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=747c3f34ddd14063 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=907cb475f3dc9ee0 input=a9049054013a1b77]*/
diff --git a/Modules/_sha3/sha3module.c b/Modules/sha3module.c
similarity index 75%
rename from Modules/_sha3/sha3module.c
rename to Modules/sha3module.c
index 93abc3b2710e..f05187498a19 100644
--- a/Modules/_sha3/sha3module.c
+++ b/Modules/sha3module.c
@@ -22,23 +22,9 @@
 #include "Python.h"
 #include "pycore_strhex.h"        // _Py_strhex()
 #include "pycore_typeobject.h"    // _PyType_GetModuleState()
-#include "../hashlib.h"
-
-#include "sha3.c"
+#include "hashlib.h"
 
 #define SHA3_MAX_DIGESTSIZE 64 /* 64 Bytes (512 Bits) for 224 to 512 */
-#define SHA3_LANESIZE 0
-#define SHA3_state sha3_ctx_t
-#define SHA3_init sha3_init
-#define SHA3_process sha3_update
-#define SHA3_done(state, digest) sha3_final(digest, state)
-#define SHA3_squeeze(state, out, len) shake_xof(state), shake_out(state, out, len)
-#define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state))
-
-// no optimization
-#define KeccakOpt 0
-
-typedef enum { SUCCESS = 1, FAIL = 0, BAD_HASHLEN = 2 } HashReturn;
 
 typedef struct {
     PyTypeObject *sha3_224_type;
@@ -70,10 +56,11 @@ class _sha3.shake_256 "SHA3object *" "&SHAKE256type"
 
 /* The structure for storing SHA3 info */
 
+#include "_hacl/Hacl_Hash_SHA3.h"
+
 typedef struct {
     PyObject_HEAD
-    SHA3_state hash_state;
-    PyThread_type_lock lock;
+    Hacl_Streaming_Keccak_state *hash_state;
 } SHA3object;
 
 #include "clinic/sha3module.c.h"
@@ -86,10 +73,23 @@ newSHA3object(PyTypeObject *type)
     if (newobj == NULL) {
         return NULL;
     }
-    newobj->lock = NULL;
     return newobj;
 }
 
+static void sha3_update(Hacl_Streaming_Keccak_state *state, uint8_t *buf, Py_ssize_t len) {
+  /* Note: we explicitly ignore the error code on the basis that it would take >
+   * 1 billion years to hash more than 2^64 bytes. */
+#if PY_SSIZE_T_MAX > UINT32_MAX
+  while (len > UINT32_MAX) {
+    Hacl_Streaming_Keccak_update(state, buf, UINT32_MAX);
+    len -= UINT32_MAX;
+    buf += UINT32_MAX;
+  }
+#endif
+  /* Cast to uint32_t is safe: len <= UINT32_MAX at this point. */
+  Hacl_Streaming_Keccak_update(state, buf, (uint32_t) len);
+}
+
 /*[clinic input]
 @classmethod
 _sha3.sha3_224.__new__ as py_sha3_new
@@ -98,14 +98,13 @@ _sha3.sha3_224.__new__ as py_sha3_new
     *
     usedforsecurity: bool = True
 
-Return a new BLAKE2b hash object.
+Return a new SHA3 hash object.
 [clinic start generated code]*/
 
 static PyObject *
 py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity)
-/*[clinic end generated code: output=90409addc5d5e8b0 input=bcfcdf2e4368347a]*/
+/*[clinic end generated code: output=90409addc5d5e8b0 input=637e5f8f6a93982a]*/
 {
-    HashReturn res;
     Py_buffer buf = {NULL, NULL};
     SHA3State *state = _PyType_GetModuleState(type);
     SHA3object *self = newSHA3object(type);
@@ -116,49 +115,29 @@ py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity)
     assert(state != NULL);
 
     if (type == state->sha3_224_type) {
-        res = sha3_init(&self->hash_state, 28);
+        self->hash_state = Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_SHA3_224);
     } else if (type == state->sha3_256_type) {
-        res = sha3_init(&self->hash_state, 32);
+        self->hash_state = Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_SHA3_256);
     } else if (type == state->sha3_384_type) {
-        res = sha3_init(&self->hash_state, 48);
+        self->hash_state = Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_SHA3_384);
     } else if (type == state->sha3_512_type) {
-        res = sha3_init(&self->hash_state, 64);
+        self->hash_state = Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_SHA3_512);
     } else if (type == state->shake_128_type) {
-        res = sha3_init(&self->hash_state, 16);
+        self->hash_state = Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_Shake128);
     } else if (type == state->shake_256_type) {
-        res = sha3_init(&self->hash_state, 32);
+        self->hash_state = Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_Shake256);
     } else {
         PyErr_BadInternalCall();
         goto error;
     }
 
-    if (res != SUCCESS) {
-        PyErr_SetString(PyExc_RuntimeError,
-                        "internal error in SHA3 initialize()");
-        goto error;
-    }
-
     if (data) {
         GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error);
-        if (buf.len >= HASHLIB_GIL_MINSIZE) {
-            /* invariant: New objects can't be accessed by other code yet,
-             * thus it's safe to release the GIL without locking the object.
-             */
-            Py_BEGIN_ALLOW_THREADS
-            res = SHA3_process(&self->hash_state, buf.buf, buf.len);
-            Py_END_ALLOW_THREADS
-        }
-        else {
-            res = SHA3_process(&self->hash_state, buf.buf, buf.len);
-        }
-        if (res != SUCCESS) {
-            PyErr_SetString(PyExc_RuntimeError,
-                            "internal error in SHA3 Update()");
-            goto error;
-        }
-        PyBuffer_Release(&buf);
+        sha3_update(self->hash_state, buf.buf, buf.len);
     }
 
+    PyBuffer_Release(&buf);
+
     return (PyObject *)self;
 
   error:
@@ -177,10 +156,7 @@ py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity)
 static void
 SHA3_dealloc(SHA3object *self)
 {
-    if (self->lock) {
-        PyThread_free_lock(self->lock);
-    }
-
+    Hacl_Streaming_Keccak_free(self->hash_state);
     PyTypeObject *tp = Py_TYPE(self);
     PyObject_Free(self);
     Py_DECREF(tp);
@@ -205,9 +181,7 @@ _sha3_sha3_224_copy_impl(SHA3object *self)
     if ((newobj = newSHA3object(Py_TYPE(self))) == NULL) {
         return NULL;
     }
-    ENTER_HASHLIB(self);
-    SHA3_copystate(newobj->hash_state, self->hash_state);
-    LEAVE_HASHLIB(self);
+    newobj->hash_state = Hacl_Streaming_Keccak_copy(self->hash_state);
     return (PyObject *)newobj;
 }
 
@@ -222,20 +196,12 @@ static PyObject *
 _sha3_sha3_224_digest_impl(SHA3object *self)
 /*[clinic end generated code: output=fd531842e20b2d5b input=5b2a659536bbd248]*/
 {
-    unsigned char digest[SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE];
-    SHA3_state temp;
-    HashReturn res;
-
-    ENTER_HASHLIB(self);
-    SHA3_copystate(temp, self->hash_state);
-    LEAVE_HASHLIB(self);
-    res = SHA3_done(&temp, digest);
-    if (res != SUCCESS) {
-        PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()");
-        return NULL;
-    }
+    unsigned char digest[SHA3_MAX_DIGESTSIZE];
+    // This function errors out if the algorithm is Shake. Here, we know this
+    // not to be the case, and therefore do not perform error checking.
+    Hacl_Streaming_Keccak_finish(self->hash_state, digest);
     return PyBytes_FromStringAndSize((const char *)digest,
-                                      self->hash_state.mdlen);
+        Hacl_Streaming_Keccak_hash_len(self->hash_state));
 }
 
 
@@ -249,21 +215,10 @@ static PyObject *
 _sha3_sha3_224_hexdigest_impl(SHA3object *self)
 /*[clinic end generated code: output=75ad03257906918d input=2d91bb6e0d114ee3]*/
 {
-    unsigned char digest[SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE];
-    SHA3_state temp;
-    HashReturn res;
-
-    /* Get the raw (binary) digest value */
-    ENTER_HASHLIB(self);
-    SHA3_copystate(temp, self->hash_state);
-    LEAVE_HASHLIB(self);
-    res = SHA3_done(&temp, digest);
-    if (res != SUCCESS) {
-        PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()");
-        return NULL;
-    }
+    unsigned char digest[SHA3_MAX_DIGESTSIZE];
+    Hacl_Streaming_Keccak_finish(self->hash_state, digest);
     return _Py_strhex((const char *)digest,
-                      self->hash_state.mdlen);
+        Hacl_Streaming_Keccak_hash_len(self->hash_state));
 }
 
 
@@ -281,36 +236,8 @@ _sha3_sha3_224_update(SHA3object *self, PyObject *data)
 /*[clinic end generated code: output=d3223352286ed357 input=a887f54dcc4ae227]*/
 {
     Py_buffer buf;
-    HashReturn res;
-
     GET_BUFFER_VIEW_OR_ERROUT(data, &buf);
-
-    /* add new data, the function takes the length in bits not bytes */
-    if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) {
-        self->lock = PyThread_allocate_lock();
-    }
-    /* Once a lock exists all code paths must be synchronized. We have to
-     * release the GIL even for small buffers as acquiring the lock may take
-     * an unlimited amount of time when another thread updates this object
-     * with lots of data. */
-    if (self->lock) {
-        Py_BEGIN_ALLOW_THREADS
-        PyThread_acquire_lock(self->lock, 1);
-        res = SHA3_process(&self->hash_state, buf.buf, buf.len);
-        PyThread_release_lock(self->lock);
-        Py_END_ALLOW_THREADS
-    }
-    else {
-        res = SHA3_process(&self->hash_state, buf.buf, buf.len);
-    }
-
-    if (res != SUCCESS) {
-        PyBuffer_Release(&buf);
-        PyErr_SetString(PyExc_RuntimeError,
-                        "internal error in SHA3 Update()");
-        return NULL;
-    }
-
+    sha3_update(self->hash_state, buf.buf, buf.len);
     PyBuffer_Release(&buf);
     Py_RETURN_NONE;
 }
@@ -328,7 +255,7 @@ static PyMethodDef SHA3_methods[] = {
 static PyObject *
 SHA3_get_block_size(SHA3object *self, void *closure)
 {
-    int rate = self->hash_state.rsiz;
+    uint32_t rate = Hacl_Streaming_Keccak_block_len(self->hash_state);
     return PyLong_FromLong(rate);
 }
 
@@ -363,14 +290,19 @@ SHA3_get_name(SHA3object *self, void *closure)
 static PyObject *
 SHA3_get_digest_size(SHA3object *self, void *closure)
 {
-    return PyLong_FromLong(self->hash_state.mdlen);
+    // Preserving previous behavior: variable-length algorithms return 0
+    if (Hacl_Streaming_Keccak_is_shake(self->hash_state))
+      return PyLong_FromLong(0);
+    else
+      return PyLong_FromLong(Hacl_Streaming_Keccak_hash_len(self->hash_state));
 }
 
 
 static PyObject *
 SHA3_get_capacity_bits(SHA3object *self, void *closure)
 {
-    int capacity = 1600 - self->hash_state.rsiz * 8;
+    uint32_t rate = Hacl_Streaming_Keccak_block_len(self->hash_state) * 8;
+    int capacity = 1600 - rate;
     return PyLong_FromLong(capacity);
 }
 
@@ -378,7 +310,7 @@ SHA3_get_capacity_bits(SHA3object *self, void *closure)
 static PyObject *
 SHA3_get_rate_bits(SHA3object *self, void *closure)
 {
-    unsigned int rate = self->hash_state.rsiz * 8;
+    uint32_t rate = Hacl_Streaming_Keccak_block_len(self->hash_state) * 8;
     return PyLong_FromLong(rate);
 }
 
@@ -455,28 +387,26 @@ static PyObject *
 _SHAKE_digest(SHA3object *self, unsigned long digestlen, int hex)
 {
     unsigned char *digest = NULL;
-    SHA3_state temp;
     PyObject *result = NULL;
 
     if (digestlen >= (1 << 29)) {
         PyErr_SetString(PyExc_ValueError, "length is too large");
         return NULL;
     }
-    /* ExtractLane needs at least SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE and
-     * SHA3_LANESIZE extra space.
-     */
-    digest = (unsigned char*)PyMem_Malloc(digestlen + SHA3_LANESIZE);
+    digest = (unsigned char*)PyMem_Malloc(digestlen);
     if (digest == NULL) {
         return PyErr_NoMemory();
     }
 
-    /* Get the raw (binary) digest value */
-    ENTER_HASHLIB(self);
-    SHA3_copystate(temp, self->hash_state);
-    LEAVE_HASHLIB(self);
-    SHA3_squeeze(&temp, digest, digestlen);
+    /* Get the raw (binary) digest value. The HACL functions errors out if:
+     * - the algorith is not shake -- not the case here
+     * - the output length is zero -- we follow the existing behavior and return
+     *   an empty digest, without raising an error */
+    if (digestlen > 0) {
+        Hacl_Streaming_Keccak_squeeze(self->hash_state, digest, digestlen);
+    }
     if (hex) {
-         result = _Py_strhex((const char *)digest, digestlen);
+        result = _Py_strhex((const char *)digest, digestlen);
     } else {
         result = PyBytes_FromStringAndSize((const char *)digest,
                                            digestlen);
@@ -628,11 +558,8 @@ _sha3_exec(PyObject *m)
     init_sha3type(shake_256_type, SHAKE256_spec);
 #undef init_sha3type
 
-    if (PyModule_AddIntConstant(m, "keccakopt", KeccakOpt) < 0) {
-        return -1;
-    }
     if (PyModule_AddStringConstant(m, "implementation",
-                                   "tiny_sha3") < 0) {
+                                   "HACL") < 0) {
         return -1;
     }
 
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
index 8aafcb786a60..28b1517c6f6b 100644
--- a/PCbuild/pythoncore.vcxproj
+++ b/PCbuild/pythoncore.vcxproj
@@ -375,13 +375,16 @@
     <ClCompile Include="..\Modules\_contextvarsmodule.c" />
     <ClCompile Include="..\Modules\_csv.c" />
     <ClCompile Include="..\Modules\_functoolsmodule.c" />
+    <ClCompile Include="..\Modules\_hacl\Hacl_Hash_MD5.c" />
+    <ClCompile Include="..\Modules\_hacl\Hacl_Hash_SHA1.c" />
+    <ClCompile Include="..\Modules\_hacl\Hacl_Streaming_SHA2.c" />
+    <ClCompile Include="..\Modules\_hacl\Hacl_Hash_SHA3.c" />
     <ClCompile Include="..\Modules\_heapqmodule.c" />
     <ClCompile Include="..\Modules\_json.c" />
     <ClCompile Include="..\Modules\_localemodule.c" />
     <ClCompile Include="..\Modules\_lsprof.c" />
     <ClCompile Include="..\Modules\_pickle.c" />
     <ClCompile Include="..\Modules\_randommodule.c" />
-    <ClCompile Include="..\Modules\_sha3\sha3module.c" />
     <ClCompile Include="..\Modules\_sre\sre.c" />
     <ClInclude Include="..\Modules\_sre\sre.h" />
     <ClInclude Include="..\Modules\_sre\sre_constants.h" />
@@ -404,17 +407,15 @@
     <ClCompile Include="..\Modules\itertoolsmodule.c" />
     <ClCompile Include="..\Modules\main.c" />
     <ClCompile Include="..\Modules\mathmodule.c" />
-    <ClCompile Include="..\Modules\_hacl\Hacl_Hash_MD5.c" />
     <ClCompile Include="..\Modules\md5module.c" />
     <ClCompile Include="..\Modules\mmapmodule.c" />
     <ClCompile Include="..\Modules\_opcode.c" />
     <ClCompile Include="..\Modules\_operator.c" />
     <ClCompile Include="..\Modules\posixmodule.c" />
     <ClCompile Include="..\Modules\rotatingtree.c" />
-    <ClCompile Include="..\Modules\_hacl\Hacl_Hash_SHA1.c" />
     <ClCompile Include="..\Modules\sha1module.c" />
-    <ClCompile Include="..\Modules\_hacl\Hacl_Streaming_SHA2.c" />
     <ClCompile Include="..\Modules\sha2module.c" />
+    <ClCompile Include="..\Modules\sha3module.c" />
     <ClCompile Include="..\Modules\signalmodule.c" />
     <ClCompile Include="..\Modules\_statisticsmodule.c" />
     <ClCompile Include="..\Modules\symtablemodule.c" />
diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters
index 07476f308333..75e6fbb13f98 100644
--- a/PCbuild/pythoncore.vcxproj.filters
+++ b/PCbuild/pythoncore.vcxproj.filters
@@ -776,6 +776,15 @@
     <ClCompile Include="..\Modules\_functoolsmodule.c">
       <Filter>Modules</Filter>
     </ClCompile>
+    <ClCompile Include="..\Modules\_hacl\Hacl_Hash_SHA1.c">
+      <Filter>Modules</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Modules\_hacl\Hacl_Streaming_SHA2.c">
+      <Filter>Modules</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Modules\_hacl\Hacl_Hash_SHA3.c">
+      <Filter>Modules</Filter>
+    </ClCompile>
     <ClCompile Include="..\Modules\_heapqmodule.c">
       <Filter>Modules</Filter>
     </ClCompile>
@@ -794,9 +803,6 @@
     <ClCompile Include="..\Modules\_randommodule.c">
       <Filter>Modules</Filter>
     </ClCompile>
-    <ClCompile Include="..\Modules\_sha3\sha3module.c">
-      <Filter>Modules</Filter>
-    </ClCompile>
     <ClCompile Include="..\Modules\_sre\sre.c">
       <Filter>Modules</Filter>
     </ClCompile>
@@ -875,16 +881,13 @@
     <ClCompile Include="..\Modules\rotatingtree.c">
       <Filter>Modules</Filter>
     </ClCompile>
-    <ClCompile Include="..\Modules\_hacl\Hacl_Hash_SHA1.c">
-      <Filter>Modules</Filter>
-    </ClCompile>
     <ClCompile Include="..\Modules\sha1module.c">
       <Filter>Modules</Filter>
     </ClCompile>
-    <ClCompile Include="..\Modules\_hacl\Hacl_Streaming_SHA2.c">
+    <ClCompile Include="..\Modules\sha2module.c">
       <Filter>Modules</Filter>
     </ClCompile>
-    <ClCompile Include="..\Modules\sha2module.c">
+    <ClCompile Include="..\Modules\sha3module.c">
       <Filter>Modules</Filter>
     </ClCompile>
     <ClCompile Include="..\Modules\signalmodule.c">
diff --git a/Tools/c-analyzer/cpython/_parser.py b/Tools/c-analyzer/cpython/_parser.py
index 5924ab7860d8..9bd54db0f59c 100644
--- a/Tools/c-analyzer/cpython/_parser.py
+++ b/Tools/c-analyzer/cpython/_parser.py
@@ -114,6 +114,7 @@ def clean_lines(text):
 Modules/md5module.c	Modules/_hacl/include
 Modules/sha1module.c	Modules/_hacl/include
 Modules/sha2module.c	Modules/_hacl/include
+Modules/sha3module.c	Modules/_hacl/include
 Objects/stringlib/*.h	Objects
 
 # possible system-installed headers, just in case
@@ -271,13 +272,6 @@ def clean_lines(text):
 Modules/expat/xmlparse.c	XML_POOR_ENTROPY	1
 Modules/_dbmmodule.c	HAVE_GDBM_DASH_NDBM_H	1
 
-# from Modules/_sha3/sha3module.c
-Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c	PLATFORM_BYTE_ORDER	4321  # force big-endian
-Modules/_sha3/kcp/*.c	KeccakOpt	64
-Modules/_sha3/kcp/*.c	KeccakP200_excluded	1
-Modules/_sha3/kcp/*.c	KeccakP400_excluded	1
-Modules/_sha3/kcp/*.c	KeccakP800_excluded	1
-
 # others
 Modules/_sre/sre_lib.h	LOCAL(type)	static inline type
 Modules/_sre/sre_lib.h	SRE(F)	sre_ucs2_##F



More information about the Python-checkins mailing list