summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Protzenko <protz@microsoft.com>2023-05-08 03:50:04 (GMT)
committerGitHub <noreply@github.com>2023-05-08 03:50:04 (GMT)
commit15665d896bae9c3d8b60bd7210ac1b7dc533b093 (patch)
tree828d0c447265d301089c91aec0803cf67a51e4f8
parent01cc9c1ff79bf18fe34c05c6cd573e79ff9487c3 (diff)
downloadcpython-15665d896bae9c3d8b60bd7210ac1b7dc533b093.zip
cpython-15665d896bae9c3d8b60bd7210ac1b7dc533b093.tar.gz
cpython-15665d896bae9c3d8b60bd7210ac1b7dc533b093.tar.bz2
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@krypto.org>
-rw-r--r--Makefile.pre.in2
-rw-r--r--Misc/NEWS.d/next/Security/2023-04-17-14-38-12.gh-issue-99108.720lG8.rst2
-rw-r--r--Modules/Setup2
-rw-r--r--Modules/Setup.stdlib.in2
-rw-r--r--Modules/_hacl/Hacl_Hash_SHA3.c826
-rw-r--r--Modules/_hacl/Hacl_Hash_SHA3.h136
-rw-r--r--Modules/_hacl/Hacl_Streaming_Types.h17
-rw-r--r--Modules/_hacl/include/krml/internal/target.h44
-rw-r--r--Modules/_hacl/include/krml/lowstar_endianness.h5
-rw-r--r--Modules/_hacl/internal/Hacl_Hash_SHA3.h65
-rw-r--r--Modules/_hacl/python_hacl_namespaces.h23
-rwxr-xr-xModules/_hacl/refresh.sh11
-rw-r--r--Modules/_sha3/LICENSE22
-rw-r--r--Modules/_sha3/README.txt8
-rw-r--r--Modules/_sha3/sha3.c193
-rw-r--r--Modules/_sha3/sha3.h49
-rw-r--r--Modules/clinic/sha3module.c.h (renamed from Modules/_sha3/clinic/sha3module.c.h)4
-rw-r--r--Modules/sha3module.c (renamed from Modules/_sha3/sha3module.c)191
-rw-r--r--PCbuild/pythoncore.vcxproj9
-rw-r--r--PCbuild/pythoncore.vcxproj.filters19
-rw-r--r--Tools/c-analyzer/cpython/_parser.py8
21 files changed, 1204 insertions, 434 deletions
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 736a520..3294665 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 0000000..f259acf
--- /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 1c6f2f7..e5bc078 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 a7803cf..8e66576 100644
--- a/Modules/Setup.stdlib.in
+++ b/Modules/Setup.stdlib.in
@@ -80,7 +80,7 @@
@MODULE__MD5_TRUE@_md5 md5module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_MD5.c -D_BSD_SOURCE -D_DEFAULT_SOURCE
@MODULE__SHA1_TRUE@_sha1 sha1module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA1.c -D_BSD_SOURCE -D_DEFAULT_SOURCE
@MODULE__SHA2_TRUE@_sha2 sha2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Streaming_SHA2.a
-@MODULE__SHA3_TRUE@_sha3 _sha3/sha3module.c
+@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@_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 0000000..100afe7
--- /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 0000000..2a5cf4b
--- /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 5105761..8a60b70 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 dcbe700..5a2f94e 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 32a7391..1aa2ccd 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 0000000..1c9808b
--- /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 ee28f24..0df2362 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 76b92ec..220ebbe 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 d2d484d..0000000
--- 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 b35919b..0000000
--- 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 e2d3fd7..0000000
--- a/Modules/_sha3/sha3.c
+++ /dev/null
@@ -1,193 +0,0 @@
-// sha3.c
-// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@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 f973d67..0000000
--- a/Modules/_sha3/sha3.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// sha3.h
-// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@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
index a0c7c1c..299803a 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
index 93abc3b..f051874 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 8aafcb7..28b1517 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 07476f3..75e6fbb 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 5924ab7..9bd54db 100644
--- a/Tools/c-analyzer/cpython/_parser.py
+++ b/Tools/c-analyzer/cpython/_parser.py
@@ -114,6 +114,7 @@ Modules/_hacl/*.h Modules/_hacl/include
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 @@ Modules/expat/xmlparse.c HAVE_EXPAT_CONFIG_H 1
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