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>
This commit is contained in:
Jonathan Protzenko 2023-05-07 20:50:04 -07:00 committed by GitHub
parent 01cc9c1ff7
commit 15665d896b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 1204 additions and 434 deletions

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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
############################################################################

View File

@ -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);
}

View File

@ -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

View File

@ -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;

View File

@ -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 \

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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."

View File

@ -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.

View File

@ -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.

View File

@ -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;
}

View File

@ -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

View File

@ -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]*/

View File

@ -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;
}

View File

@ -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" />

View File

@ -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">

View File

@ -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