From 96b46851ce5d41b68990c3ef550c976c005c14c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:37:32 +0200 Subject: [PATCH 01/14] cleanup imports --- Modules/blake2module.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Modules/blake2module.c b/Modules/blake2module.c index 07aa89f573f05f..f84bed1d419851 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -13,7 +13,6 @@ # define Py_BUILD_CORE_MODULE 1 #endif -#include "pyconfig.h" #include "Python.h" #include "hashlib.h" #include "pycore_strhex.h" // _Py_strhex() @@ -133,14 +132,14 @@ static inline bool has_simd256(cpu_flags *flags) { #define HACL_CAN_COMPILE_VEC128 HACL_CAN_COMPILE_SIMD128 #define HACL_CAN_COMPILE_VEC256 HACL_CAN_COMPILE_SIMD256 -#include "_hacl/Hacl_Hash_Blake2b.h" #include "_hacl/Hacl_Hash_Blake2s.h" -#if HACL_CAN_COMPILE_SIMD256 -#include "_hacl/Hacl_Hash_Blake2b_Simd256.h" -#endif +#include "_hacl/Hacl_Hash_Blake2b.h" #if HACL_CAN_COMPILE_SIMD128 #include "_hacl/Hacl_Hash_Blake2s_Simd128.h" #endif +#if HACL_CAN_COMPILE_SIMD256 +#include "_hacl/Hacl_Hash_Blake2b_Simd256.h" +#endif // MODULE TYPE SLOTS From b457941e4f84065bfbf229820a80ba348cc94afb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:40:05 +0200 Subject: [PATCH 02/14] simplify detection of SIMD support --- Modules/blake2module.c | 194 ++++++++++++++++++++--------------------- Modules/hmacmodule.c | 4 +- 2 files changed, 97 insertions(+), 101 deletions(-) diff --git a/Modules/blake2module.c b/Modules/blake2module.c index f84bed1d419851..745392958a5a10 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -50,83 +50,6 @@ # undef HACL_CAN_COMPILE_SIMD256 #endif -// ECX -#define ECX_SSE3 (1 << 0) -#define ECX_SSSE3 (1 << 9) -#define ECX_SSE4_1 (1 << 19) -#define ECX_SSE4_2 (1 << 20) -#define ECX_AVX (1 << 28) - -// EBX -#define EBX_AVX2 (1 << 5) - -// EDX -#define EDX_SSE (1 << 25) -#define EDX_SSE2 (1 << 26) -#define EDX_CMOV (1 << 15) - -// zero-initialized by default -typedef struct { - bool sse, sse2, sse3, sse41, sse42, cmov, avx, avx2; - bool done; -} cpu_flags; - -void detect_cpu_features(cpu_flags *flags) { - if (!flags->done) { - int eax1 = 0, ebx1 = 0, ecx1 = 0, edx1 = 0; - int eax7 = 0, ebx7 = 0, ecx7 = 0, edx7 = 0; -#if defined(__x86_64__) && defined(__GNUC__) - __cpuid_count(1, 0, eax1, ebx1, ecx1, edx1); - __cpuid_count(7, 0, eax7, ebx7, ecx7, edx7); -#elif defined(_M_X64) - int info1[4] = { 0 }; - int info7[4] = { 0 }; - __cpuidex(info1, 1, 0); - __cpuidex(info7, 7, 0); - eax1 = info1[0]; - ebx1 = info1[1]; - ecx1 = info1[2]; - edx1 = info1[3]; - eax7 = info7[0]; - ebx7 = info7[1]; - ecx7 = info7[2]; - edx7 = info7[3]; -#endif - (void) eax1; (void) ebx1; (void) ecx1; (void) edx1; - (void) eax7; (void) ebx7; (void) ecx7; (void) edx7; - - - flags->avx = (ecx1 & ECX_AVX) != 0; - - flags->avx2 = (ebx7 & EBX_AVX2) != 0; - - flags->sse = (edx1 & EDX_SSE) != 0; - flags->sse2 = (edx1 & EDX_SSE2) != 0; - flags->cmov = (edx1 & EDX_CMOV) != 0; - - flags->sse3 = (ecx1 & ECX_SSE3) != 0; - /* ssse3 = (ecx1 & ECX_SSSE3) != 0; */ - flags->sse41 = (ecx1 & ECX_SSE4_1) != 0; - flags->sse42 = (ecx1 & ECX_SSE4_2) != 0; - - flags->done = true; - } -} - -#ifdef HACL_CAN_COMPILE_SIMD128 -static inline bool has_simd128(cpu_flags *flags) { - // For now this is Intel-only, could conceivably be #ifdef'd to something - // else. - return flags->sse && flags->sse2 && flags->sse3 && flags->sse41 && flags->sse42 && flags->cmov; -} -#endif - -#ifdef HACL_CAN_COMPILE_SIMD256 -static inline bool has_simd256(cpu_flags *flags) { - return flags->avx && flags->avx2; -} -#endif - // Small mismatch between the variable names Python defines as part of configure // at the ones HACL* expects to be set in order to enable those headers. #define HACL_CAN_COMPILE_VEC128 HACL_CAN_COMPILE_SIMD128 @@ -151,9 +74,10 @@ PyDoc_STRVAR(blake2mod__doc__, ); typedef struct { - PyTypeObject* blake2b_type; - PyTypeObject* blake2s_type; - cpu_flags flags; + PyTypeObject *blake2b_type; + PyTypeObject *blake2s_type; + bool can_run_simd128; + bool can_run_simd256; } Blake2State; static inline Blake2State* @@ -202,6 +126,82 @@ _blake2_free(void *module) (void)_blake2_clear((PyObject *)module); } +static void +blake2module_init_cpu_features(Blake2State *state) +{ + /* This must be kept in sync with hmacmodule_init_cpu_features() + * in hmacmodule.c */ + int eax1 = 0, ebx1 = 0, ecx1 = 0, edx1 = 0; + int eax7 = 0, ebx7 = 0, ecx7 = 0, edx7 = 0; +#if defined(__x86_64__) && defined(__GNUC__) + __cpuid_count(1, 0, eax1, ebx1, ecx1, edx1); + __cpuid_count(7, 0, eax7, ebx7, ecx7, edx7); +#elif defined(_M_X64) + int info1[4] = {0}; + __cpuidex(info1, 1, 0); + eax1 = info1[0], ebx1 = info1[1], ecx1 = info1[2], edx1 = info1[3]; + + int info7[4] = {0}; + __cpuidex(info7, 7, 0); + eax7 = info7[0], ebx7 = info7[1], ecx7 = info7[2], edx7 = info7[3]; +#endif + // fmt: off + (void)eax1; (void)ebx1; (void)ecx1; (void)edx1; + (void)eax7; (void)ebx7; (void)ecx7; (void)edx7; + // fmt: on + +#define EBX_AVX2 (1 << 5) +#define ECX_SSE3 (1 << 0) +#define ECX_SSSE3 (1 << 9) +#define ECX_SSE4_1 (1 << 19) +#define ECX_SSE4_2 (1 << 20) +#define ECX_AVX (1 << 28) +#define EDX_SSE (1 << 25) +#define EDX_SSE2 (1 << 26) +#define EDX_CMOV (1 << 15) + + bool avx = (ecx1 & ECX_AVX) != 0; + bool avx2 = (ebx7 & EBX_AVX2) != 0; + + bool sse = (edx1 & EDX_SSE) != 0; + bool sse2 = (edx1 & EDX_SSE2) != 0; + bool cmov = (edx1 & EDX_CMOV) != 0; + + bool sse3 = (ecx1 & ECX_SSE3) != 0; + bool sse41 = (ecx1 & ECX_SSE4_1) != 0; + bool sse42 = (ecx1 & ECX_SSE4_2) != 0; + +#undef EDX_CMOV +#undef EDX_SSE2 +#undef EDX_SSE +#undef ECX_AVX +#undef ECX_SSE4_2 +#undef ECX_SSE4_1 +#undef ECX_SSSE3 +#undef ECX_SSE3 +#undef EBX_AVX2 + +#if HACL_CAN_COMPILE_SIMD128 + // TODO(picnixz): use py_cpuid_features (gh-125022) to improve detection + state->can_run_simd128 = sse && sse2 && sse3 && sse41 && sse42 && cmov; +#else + // fmt: off + (void)sse; (void)sse2; (void)sse3; (void)sse41; (void)sse42; (void)cmov; + // fmt: on + state->can_run_simd128 = false; +#endif + +#if HACL_CAN_COMPILE_SIMD256 + // TODO(picnixz): use py_cpuid_features (gh-125022) to improve detection + state->can_run_simd256 = state->can_run_simd128 && avx && avx2; +#else + // fmt: off + (void)avx; (void)avx2; + // fmt: on + state->can_run_simd256 = false; +#endif +} + #define ADD_INT(d, name, value) do { \ PyObject *x = PyLong_FromLong(value); \ if (!x) \ @@ -222,11 +222,8 @@ _blake2_free(void *module) static int blake2_exec(PyObject *m) { - Blake2State* st = blake2_get_state(m); - - // This is called at module initialization-time, and so appears to be as - // good a place as any to probe the CPU flags. - detect_cpu_features(&st->flags); + Blake2State *st = blake2_get_state(m); + blake2module_init_cpu_features(st); ADD_INT_CONST("_GIL_MINSIZE", HASHLIB_GIL_MINSIZE); @@ -327,27 +324,26 @@ static inline bool is_blake2s(blake2_impl impl) { return !is_blake2b(impl); } -static inline blake2_impl type_to_impl(PyTypeObject *type) { +static inline blake2_impl +type_to_impl(PyTypeObject *type) { #if defined(HACL_CAN_COMPILE_SIMD128) || defined(HACL_CAN_COMPILE_SIMD256) - Blake2State* st = blake2_get_state_from_type(type); + Blake2State *st = blake2_get_state_from_type(type); #endif if (!strcmp(type->tp_name, blake2b_type_spec.name)) { -#ifdef HACL_CAN_COMPILE_SIMD256 - if (has_simd256(&st->flags)) - return Blake2b_256; - else -#endif +#if HACL_CAN_COMPILE_SIMD256 + return st->can_run_simd256 ? Blake2b_256 : Blake2b; +#else return Blake2b; - } else if (!strcmp(type->tp_name, blake2s_type_spec.name)) { -#ifdef HACL_CAN_COMPILE_SIMD128 - if (has_simd128(&st->flags)) - return Blake2s_128; - else #endif + } + else if (!strcmp(type->tp_name, blake2s_type_spec.name)) { +#if HACL_CAN_COMPILE_SIMD128 + return st->can_run_simd128 ? Blake2s_128 : Blake2s; +#else return Blake2s; - } else { - Py_UNREACHABLE(); +#endif } + Py_UNREACHABLE(); } typedef struct { diff --git a/Modules/hmacmodule.c b/Modules/hmacmodule.c index c7b49d4dee3d0a..b404d5732ec857 100644 --- a/Modules/hmacmodule.c +++ b/Modules/hmacmodule.c @@ -1715,11 +1715,11 @@ hmacmodule_init_cpu_features(hmacmodule_state *state) __cpuid_count(1, 0, eax1, ebx1, ecx1, edx1); __cpuid_count(7, 0, eax7, ebx7, ecx7, edx7); #elif defined(_M_X64) - int info1[4] = { 0 }; + int info1[4] = {0}; __cpuidex(info1, 1, 0); eax1 = info1[0], ebx1 = info1[1], ecx1 = info1[2], edx1 = info1[3]; - int info7[4] = { 0 }; + int info7[4] = {0}; __cpuidex(info7, 7, 0); eax7 = info7[0], ebx7 = info7[1], ecx7 = info7[2], edx7 = info7[3]; #endif From 163671053c960b5898e7030501aad8ebb403d7ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:41:32 +0200 Subject: [PATCH 03/14] correctly guard `update()` cases --- Modules/blake2module.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Modules/blake2module.c b/Modules/blake2module.c index 745392958a5a10..2c6aefe5a26850 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -351,10 +351,10 @@ typedef struct { union { Hacl_Hash_Blake2s_state_t *blake2s_state; Hacl_Hash_Blake2b_state_t *blake2b_state; -#ifdef HACL_CAN_COMPILE_SIMD128 +#if HACL_CAN_COMPILE_SIMD128 Hacl_Hash_Blake2s_Simd128_state_t *blake2s_128_state; #endif -#ifdef HACL_CAN_COMPILE_SIMD256 +#if HACL_CAN_COMPILE_SIMD256 Hacl_Hash_Blake2b_Simd256_state_t *blake2b_256_state; #endif }; @@ -420,14 +420,14 @@ static void update(Blake2Object *self, uint8_t *buf, Py_ssize_t len) { switch (self->impl) { - // These need to be ifdef'd out otherwise it's an unresolved symbol at - // link-time. -#ifdef HACL_CAN_COMPILE_SIMD256 + // blake2b_256_state and blake2s_128_state must be if'd since + // otherwise this results in an unresolved symbol at link-time. +#if HACL_CAN_COMPILE_SIMD256 case Blake2b_256: HACL_UPDATE(Hacl_Hash_Blake2b_Simd256_update,self->blake2b_256_state, buf, len); return; #endif -#ifdef HACL_CAN_COMPILE_SIMD128 +#if HACL_CAN_COMPILE_SIMD128 case Blake2s_128: HACL_UPDATE(Hacl_Hash_Blake2s_Simd128_update,self->blake2s_128_state, buf, len); return; From 59cf1296088be7c0868bfee42c59c5575bd2b14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:42:56 +0200 Subject: [PATCH 04/14] rewrite `py_blake2b_or_s_new` --- Modules/blake2module.c | 236 +++++++++++++++++++++-------------------- 1 file changed, 122 insertions(+), 114 deletions(-) diff --git a/Modules/blake2module.c b/Modules/blake2module.c index 2c6aefe5a26850..84c3d7ae381b15 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -443,6 +443,89 @@ update(Blake2Object *self, uint8_t *buf, Py_ssize_t len) } } +#define BLAKE2_IMPLNAME(SELF) \ + (is_blake2b((SELF)->impl) ? "blake2b" : "blake2s") +#define GET_BLAKE2_CONST(SELF, NAME) \ + (is_blake2b((SELF)->impl) \ + ? HACL_HASH_BLAKE2B_ ## NAME \ + : HACL_HASH_BLAKE2S_ ## NAME) + +#define MAX_OUT_BYTES(SELF) GET_BLAKE2_CONST(SELF, OUT_BYTES) +#define MAX_SALT_LENGTH(SELF) GET_BLAKE2_CONST(SELF, SALT_BYTES) +#define MAX_KEY_BYTES(SELF) GET_BLAKE2_CONST(SELF, KEY_BYTES) +#define MAX_PERSONAL_BYTES(SELF) GET_BLAKE2_CONST(SELF, PERSONAL_BYTES) + +static int +py_blake2_validate_params(Blake2Object *self, + int digest_size, + Py_buffer *key, Py_buffer *salt, Py_buffer *person, + int fanout, int depth, unsigned long leaf_size, + unsigned long long node_offset, int node_depth, + int inner_size) +{ + /* Validate digest size. */ + if (digest_size <= 0 || (unsigned int)digest_size > MAX_OUT_BYTES(self)) { + PyErr_Format( + PyExc_ValueError, + "digest_size for %s must be between 1 and %d bytes, got %d", + BLAKE2_IMPLNAME(self), MAX_OUT_BYTES(self), digest_size + ); + goto error; + } + +#define CHECK_LENGTH(NAME, VALUE, MAX) \ + do { \ + if ((size_t)(VALUE) > (size_t)(MAX)) { \ + PyErr_Format(PyExc_ValueError, \ + "maximum %s length is %zu bytes, got %zd", \ + (NAME), (size_t)(MAX), (Py_ssize_t)(VALUE)); \ + goto error; \ + } \ + } while (0) + /* Validate key parameter. */ + if (key->obj && key->len) { + CHECK_LENGTH("key", key->len, MAX_KEY_BYTES(self)); + } + /* Validate salt parameter. */ + if (salt->obj && salt->len) { + CHECK_LENGTH("salt", salt->len, MAX_SALT_LENGTH(self)); + } + /* Validate personalization parameter. */ + if (person->obj && person->len) { + CHECK_LENGTH("person", person->len, MAX_PERSONAL_BYTES(self)); + } +#undef CHECK_LENGTH +#define CHECK_TREE(NAME, VALUE, MIN, MAX) \ + do { \ + if ((VALUE) < (MIN) || (size_t)(VALUE) > (size_t)(MAX)) { \ + PyErr_Format(PyExc_ValueError, \ + "'%s' must be between %zu and %zu", \ + (NAME), (size_t)(MIN), (size_t)(MAX)); \ + goto error; \ + } \ + } while (0) + /* Validate tree parameters. */ + CHECK_TREE("fanout", fanout, 0, 255); + CHECK_TREE("depth", depth, 1, 255); + CHECK_TREE("node_depth", node_depth, 0, 255); + CHECK_TREE("inner_size", inner_size, 0, MAX_OUT_BYTES(self)); +#undef CHECK_TREE + if (leaf_size > 0xFFFFFFFFU) { + /* maximum: 2**32 - 1 */ + PyErr_SetString(PyExc_OverflowError, "'leaf_size' is too large"); + goto error; + } + if (is_blake2s(self->impl) && node_offset > 0xFFFFFFFFFFFFULL) { + /* maximum: 2**48 - 1 */ + PyErr_SetString(PyExc_OverflowError, "'node_offset' is too large"); + goto error; + } + return 0; +error: + return -1; +} + + static PyObject * py_blake2b_or_s_new(PyTypeObject *type, PyObject *data, int digest_size, Py_buffer *key, Py_buffer *salt, Py_buffer *person, @@ -452,7 +535,6 @@ py_blake2b_or_s_new(PyTypeObject *type, PyObject *data, int digest_size, { Blake2Object *self = NULL; - Py_buffer buf; self = new_Blake2Object(type); if (self == NULL) { @@ -482,96 +564,31 @@ py_blake2b_or_s_new(PyTypeObject *type, PyObject *data, int digest_size, default: Py_UNREACHABLE(); } - // Using Blake2b because we statically know that these are greater than the - // Blake2s sizes -- this avoids a VLA. - uint8_t salt_[HACL_HASH_BLAKE2B_SALT_BYTES] = { 0 }; - uint8_t personal_[HACL_HASH_BLAKE2B_PERSONAL_BYTES] = { 0 }; - /* Validate digest size. */ - if (digest_size <= 0 || - (unsigned) digest_size > (is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_OUT_BYTES : HACL_HASH_BLAKE2S_OUT_BYTES)) + // Unlike the state types, the parameters share a single (client-friendly) + // structure. + if (py_blake2_validate_params(self, + digest_size, + key, salt, person, + fanout, depth, leaf_size, + node_offset, node_depth, inner_size) < 0) { - PyErr_Format(PyExc_ValueError, - "digest_size for %s must be between 1 and %d bytes, here it is %d", - is_blake2b(self->impl) ? "Blake2b" : "Blake2s", - is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_OUT_BYTES : HACL_HASH_BLAKE2S_OUT_BYTES, - digest_size); goto error; } - /* Validate salt parameter. */ - if ((salt->obj != NULL) && salt->len) { - if ((size_t)salt->len > (is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_SALT_BYTES : HACL_HASH_BLAKE2S_SALT_BYTES)) { - PyErr_Format(PyExc_ValueError, - "maximum salt length is %d bytes", - (is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_SALT_BYTES : HACL_HASH_BLAKE2S_SALT_BYTES)); - goto error; - } - memcpy(salt_, salt->buf, salt->len); - } - - /* Validate personalization parameter. */ - if ((person->obj != NULL) && person->len) { - if ((size_t)person->len > (is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_PERSONAL_BYTES : HACL_HASH_BLAKE2S_PERSONAL_BYTES)) { - PyErr_Format(PyExc_ValueError, - "maximum person length is %d bytes", - (is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_PERSONAL_BYTES : HACL_HASH_BLAKE2S_PERSONAL_BYTES)); - goto error; - } - memcpy(personal_, person->buf, person->len); - } - - /* Validate tree parameters. */ - if (fanout < 0 || fanout > 255) { - PyErr_SetString(PyExc_ValueError, - "fanout must be between 0 and 255"); - goto error; - } - - if (depth <= 0 || depth > 255) { - PyErr_SetString(PyExc_ValueError, - "depth must be between 1 and 255"); - goto error; - } - - if (leaf_size > 0xFFFFFFFFU) { - PyErr_SetString(PyExc_OverflowError, "leaf_size is too large"); - goto error; - } - - if (is_blake2s(self->impl) && node_offset > 0xFFFFFFFFFFFFULL) { - /* maximum 2**48 - 1 */ - PyErr_SetString(PyExc_OverflowError, "node_offset is too large"); - goto error; - } - - if (node_depth < 0 || node_depth > 255) { - PyErr_SetString(PyExc_ValueError, - "node_depth must be between 0 and 255"); - goto error; - } - - if (inner_size < 0 || - (unsigned) inner_size > (is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_OUT_BYTES : HACL_HASH_BLAKE2S_OUT_BYTES)) { - PyErr_Format(PyExc_ValueError, - "inner_size must be between 0 and is %d", - (is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_OUT_BYTES : HACL_HASH_BLAKE2S_OUT_BYTES)); - goto error; + // Using Blake2b because we statically know that these are greater than the + // Blake2s sizes -- this avoids a VLA. + uint8_t salt_buffer[HACL_HASH_BLAKE2B_SALT_BYTES] = {0}; + uint8_t personal_buffer[HACL_HASH_BLAKE2B_PERSONAL_BYTES] = {0}; + if (salt->obj != NULL) { + assert(salt->buf != NULL); + memcpy(salt_buffer, salt->buf, salt->len); } - - /* Set key length. */ - if ((key->obj != NULL) && key->len) { - if ((size_t)key->len > (is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_KEY_BYTES : HACL_HASH_BLAKE2S_KEY_BYTES)) { - PyErr_Format(PyExc_ValueError, - "maximum key length is %d bytes", - (is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_KEY_BYTES : HACL_HASH_BLAKE2S_KEY_BYTES)); - goto error; - } + if (person->obj != NULL) { + assert(person->buf != NULL); + memcpy(personal_buffer, person->buf, person->len); } - // Unlike the state types, the parameters share a single (client-friendly) - // structure. - Hacl_Hash_Blake2b_blake2_params params = { .digest_length = digest_size, .key_length = (uint8_t)key->len, @@ -581,55 +598,46 @@ py_blake2b_or_s_new(PyTypeObject *type, PyObject *data, int digest_size, .node_offset = node_offset, .node_depth = node_depth, .inner_length = inner_size, - .salt = salt_, - .personal = personal_ + .salt = salt_buffer, + .personal = personal_buffer }; +#define BLAKE2_MALLOC(TYPE, STATE) \ + do { \ + STATE = Hacl_Hash_ ## TYPE ## _malloc_with_params_and_key( \ + ¶ms, last_node, key->buf); \ + if (STATE == NULL) { \ + (void)PyErr_NoMemory(); \ + goto error; \ + } \ + } while (0) + switch (self->impl) { #if HACL_CAN_COMPILE_SIMD256 - case Blake2b_256: { - self->blake2b_256_state = Hacl_Hash_Blake2b_Simd256_malloc_with_params_and_key(¶ms, last_node, key->buf); - if (self->blake2b_256_state == NULL) { - (void)PyErr_NoMemory(); - goto error; - } + case Blake2b_256: + BLAKE2_MALLOC(Blake2b_Simd256, self->blake2b_256_state); break; - } #endif #if HACL_CAN_COMPILE_SIMD128 - case Blake2s_128: { - self->blake2s_128_state = Hacl_Hash_Blake2s_Simd128_malloc_with_params_and_key(¶ms, last_node, key->buf); - if (self->blake2s_128_state == NULL) { - (void)PyErr_NoMemory(); - goto error; - } + case Blake2s_128: + BLAKE2_MALLOC(Blake2s_Simd128, self->blake2s_128_state); break; - } #endif - case Blake2b: { - self->blake2b_state = Hacl_Hash_Blake2b_malloc_with_params_and_key(¶ms, last_node, key->buf); - if (self->blake2b_state == NULL) { - (void)PyErr_NoMemory(); - goto error; - } + case Blake2b: + BLAKE2_MALLOC(Blake2b, self->blake2b_state); break; - } - case Blake2s: { - self->blake2s_state = Hacl_Hash_Blake2s_malloc_with_params_and_key(¶ms, last_node, key->buf); - if (self->blake2s_state == NULL) { - (void)PyErr_NoMemory(); - goto error; - } + case Blake2s: + BLAKE2_MALLOC(Blake2s, self->blake2s_state); break; - } default: Py_UNREACHABLE(); } +#undef BLAKE2_MALLOC /* Process initial data if any. */ if (data != NULL) { + Py_buffer buf; GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); - if (buf.len >= HASHLIB_GIL_MINSIZE) { Py_BEGIN_ALLOW_THREADS update(self, buf.buf, buf.len); From 479a1900a435da8382617988541e9bc7859aa285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:43:17 +0200 Subject: [PATCH 05/14] rename `py_blake2b_or_s_new` to `py_blake2_new` --- Modules/blake2module.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Modules/blake2module.c b/Modules/blake2module.c index 84c3d7ae381b15..fa66624d91bd3d 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -527,12 +527,11 @@ py_blake2_validate_params(Blake2Object *self, static PyObject * -py_blake2b_or_s_new(PyTypeObject *type, PyObject *data, int digest_size, - Py_buffer *key, Py_buffer *salt, Py_buffer *person, - int fanout, int depth, unsigned long leaf_size, - unsigned long long node_offset, int node_depth, - int inner_size, int last_node, int usedforsecurity) - +py_blake2_new(PyTypeObject *type, PyObject *data, int digest_size, + Py_buffer *key, Py_buffer *salt, Py_buffer *person, + int fanout, int depth, unsigned long leaf_size, + unsigned long long node_offset, int node_depth, + int inner_size, int last_node, int usedforsecurity) { Blake2Object *self = NULL; @@ -690,7 +689,9 @@ py_blake2b_new_impl(PyTypeObject *type, PyObject *data_obj, int digest_size, if (_Py_hashlib_data_argument(&data, data_obj, string) < 0) { return NULL; } - return py_blake2b_or_s_new(type, data, digest_size, key, salt, person, fanout, depth, leaf_size, node_offset, node_depth, inner_size, last_node, usedforsecurity); + return py_blake2_new(type, data, digest_size, key, salt, person, + fanout, depth, leaf_size, node_offset, node_depth, + inner_size, last_node, usedforsecurity); } /*[clinic input] @@ -728,7 +729,9 @@ py_blake2s_new_impl(PyTypeObject *type, PyObject *data_obj, int digest_size, if (_Py_hashlib_data_argument(&data, data_obj, string) < 0) { return NULL; } - return py_blake2b_or_s_new(type, data, digest_size, key, salt, person, fanout, depth, leaf_size, node_offset, node_depth, inner_size, last_node, usedforsecurity); + return py_blake2_new(type, data, digest_size, key, salt, person, + fanout, depth, leaf_size, node_offset, node_depth, + inner_size, last_node, usedforsecurity); } static int From 5caf7bd51a90ecb03ffb1b3b62eb38fbeea9e80e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:43:39 +0200 Subject: [PATCH 06/14] rewrite `blake2_blake2b_copy_locked` --- Modules/blake2module.c | 40 ++++++++++++++++------------------------ 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/Modules/blake2module.c b/Modules/blake2module.c index fa66624d91bd3d..22cc80c7f494ab 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -738,42 +738,34 @@ static int blake2_blake2b_copy_locked(Blake2Object *self, Blake2Object *cpy) { assert(cpy != NULL); +#define BLAKE2_COPY(TYPE, STATE_ATTR) \ + do { \ + cpy->STATE_ATTR = Hacl_Hash_ ## TYPE ## _copy(self->STATE_ATTR); \ + if (cpy->STATE_ATTR == NULL) { \ + goto error; \ + } \ + } while (0) switch (self->impl) { #if HACL_CAN_COMPILE_SIMD256 - case Blake2b_256: { - cpy->blake2b_256_state = Hacl_Hash_Blake2b_Simd256_copy(self->blake2b_256_state); - if (cpy->blake2b_256_state == NULL) { - goto error; - } + case Blake2b_256: + BLAKE2_COPY(Blake2b_Simd256, blake2b_256_state); break; - } #endif #if HACL_CAN_COMPILE_SIMD128 - case Blake2s_128: { - cpy->blake2s_128_state = Hacl_Hash_Blake2s_Simd128_copy(self->blake2s_128_state); - if (cpy->blake2s_128_state == NULL) { - goto error; - } + case Blake2s_128: + BLAKE2_COPY(Blake2s_Simd128, blake2s_128_state); break; - } #endif - case Blake2b: { - cpy->blake2b_state = Hacl_Hash_Blake2b_copy(self->blake2b_state); - if (cpy->blake2b_state == NULL) { - goto error; - } + case Blake2b: + BLAKE2_COPY(Blake2b, blake2b_state); break; - } - case Blake2s: { - cpy->blake2s_state = Hacl_Hash_Blake2s_copy(self->blake2s_state); - if (cpy->blake2s_state == NULL) { - goto error; - } + case Blake2s: + BLAKE2_COPY(Blake2s, blake2s_state); break; - } default: Py_UNREACHABLE(); } +#undef BLAKE2_COPY cpy->impl = self->impl; return 0; From 6c2c93c27540a668b635e5701492a96ccc16542d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:45:05 +0200 Subject: [PATCH 07/14] refactor computations of digest and hexdigest --- Modules/blake2module.c | 69 +++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 44 deletions(-) diff --git a/Modules/blake2module.c b/Modules/blake2module.c index 22cc80c7f494ab..9f832b8a0ef3ae 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -836,40 +836,42 @@ _blake2_blake2b_update_impl(Blake2Object *self, PyObject *data) Py_RETURN_NONE; } -/*[clinic input] -_blake2.blake2b.digest - -Return the digest value as a bytes object. -[clinic start generated code]*/ - -static PyObject * -_blake2_blake2b_digest_impl(Blake2Object *self) -/*[clinic end generated code: output=31ab8ad477f4a2f7 input=7d21659e9c5fff02]*/ +static uint8_t +blake2_blake2b_compute_digest(Blake2Object *self, uint8_t *digest) { - uint8_t digest[HACL_HASH_BLAKE2B_OUT_BYTES]; - - ENTER_HASHLIB(self); - uint8_t digest_length = 0; switch (self->impl) { #if HACL_CAN_COMPILE_SIMD256 case Blake2b_256: - digest_length = Hacl_Hash_Blake2b_Simd256_digest(self->blake2b_256_state, digest); - break; + return Hacl_Hash_Blake2b_Simd256_digest( + self->blake2b_256_state, digest); #endif #if HACL_CAN_COMPILE_SIMD128 case Blake2s_128: - digest_length = Hacl_Hash_Blake2s_Simd128_digest(self->blake2s_128_state, digest); - break; + return Hacl_Hash_Blake2s_Simd128_digest( + self->blake2s_128_state, digest); #endif case Blake2b: - digest_length = Hacl_Hash_Blake2b_digest(self->blake2b_state, digest); - break; + return Hacl_Hash_Blake2b_digest(self->blake2b_state, digest); case Blake2s: - digest_length = Hacl_Hash_Blake2s_digest(self->blake2s_state, digest); - break; + return Hacl_Hash_Blake2s_digest(self->blake2s_state, digest); default: Py_UNREACHABLE(); } +} + +/*[clinic input] +_blake2.blake2b.digest + +Return the digest value as a bytes object. +[clinic start generated code]*/ + +static PyObject * +_blake2_blake2b_digest_impl(Blake2Object *self) +/*[clinic end generated code: output=31ab8ad477f4a2f7 input=7d21659e9c5fff02]*/ +{ + uint8_t digest_length = 0, digest[HACL_HASH_BLAKE2B_OUT_BYTES]; + ENTER_HASHLIB(self); + digest_length = blake2_blake2b_compute_digest(self, digest); LEAVE_HASHLIB(self); return PyBytes_FromStringAndSize((const char *)digest, digest_length); } @@ -884,30 +886,9 @@ static PyObject * _blake2_blake2b_hexdigest_impl(Blake2Object *self) /*[clinic end generated code: output=5ef54b138db6610a input=76930f6946351f56]*/ { - uint8_t digest[HACL_HASH_BLAKE2B_OUT_BYTES]; - + uint8_t digest_length = 0, digest[HACL_HASH_BLAKE2B_OUT_BYTES]; ENTER_HASHLIB(self); - uint8_t digest_length = 0; - switch (self->impl) { -#if HACL_CAN_COMPILE_SIMD256 - case Blake2b_256: - digest_length = Hacl_Hash_Blake2b_Simd256_digest(self->blake2b_256_state, digest); - break; -#endif -#if HACL_CAN_COMPILE_SIMD128 - case Blake2s_128: - digest_length = Hacl_Hash_Blake2s_Simd128_digest(self->blake2s_128_state, digest); - break; -#endif - case Blake2b: - digest_length = Hacl_Hash_Blake2b_digest(self->blake2b_state, digest); - break; - case Blake2s: - digest_length = Hacl_Hash_Blake2s_digest(self->blake2s_state, digest); - break; - default: - Py_UNREACHABLE(); - } + digest_length = blake2_blake2b_compute_digest(self, digest); LEAVE_HASHLIB(self); return _Py_strhex((const char *)digest, digest_length); } From bd3e1279c94fbb84829ce356fd5b650d2a216ad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:45:34 +0200 Subject: [PATCH 08/14] refactor `py_blake2_clear` --- Modules/blake2module.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/Modules/blake2module.c b/Modules/blake2module.c index 9f832b8a0ef3ae..e75fab7517065f 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -960,38 +960,35 @@ py_blake2_clear(PyObject *op) // initializes the HACL* internal state to NULL before allocating // it. If an error occurs in the constructor, we should only free // states that were allocated (i.e. that are not NULL). +#define BLAKE2_FREE(TYPE, STATE) \ + do { \ + if (STATE != NULL) { \ + Hacl_Hash_ ## TYPE ## _free(STATE); \ + STATE = NULL; \ + } \ + } while (0) + switch (self->impl) { #if HACL_CAN_COMPILE_SIMD256 case Blake2b_256: - if (self->blake2b_256_state != NULL) { - Hacl_Hash_Blake2b_Simd256_free(self->blake2b_256_state); - self->blake2b_256_state = NULL; - } + BLAKE2_FREE(Blake2b_Simd256, self->blake2b_256_state); break; #endif #if HACL_CAN_COMPILE_SIMD128 case Blake2s_128: - if (self->blake2s_128_state != NULL) { - Hacl_Hash_Blake2s_Simd128_free(self->blake2s_128_state); - self->blake2s_128_state = NULL; - } + BLAKE2_FREE(Blake2s_Simd128, self->blake2s_128_state); break; #endif case Blake2b: - if (self->blake2b_state != NULL) { - Hacl_Hash_Blake2b_free(self->blake2b_state); - self->blake2b_state = NULL; - } + BLAKE2_FREE(Blake2b, self->blake2b_state); break; case Blake2s: - if (self->blake2s_state != NULL) { - Hacl_Hash_Blake2s_free(self->blake2s_state); - self->blake2s_state = NULL; - } + BLAKE2_FREE(Blake2s, self->blake2s_state); break; default: Py_UNREACHABLE(); } +#undef BLAKE2_FREE return 0; } From 1172bdf95921f4f825df56c8b8b03e8ff9c723a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:46:50 +0200 Subject: [PATCH 09/14] simplify `py_blake2b_get_name` and `py_blake2b_get_block_size` --- Modules/blake2module.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Modules/blake2module.c b/Modules/blake2module.c index e75fab7517065f..1367f5305cb12f 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -907,20 +907,18 @@ static PyObject * py_blake2b_get_name(PyObject *op, void *Py_UNUSED(closure)) { Blake2Object *self = _Blake2Object_CAST(op); - return PyUnicode_FromString(is_blake2b(self->impl) ? "blake2b" : "blake2s"); + return PyUnicode_FromString(BLAKE2_IMPLNAME(self)); } - static PyObject * py_blake2b_get_block_size(PyObject *op, void *Py_UNUSED(closure)) { Blake2Object *self = _Blake2Object_CAST(op); - return PyLong_FromLong(is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_BLOCK_BYTES : HACL_HASH_BLAKE2S_BLOCK_BYTES); + return PyLong_FromLong(GET_BLAKE2_CONST(self, BLOCK_BYTES)); } - static PyObject * py_blake2b_get_digest_size(PyObject *op, void *Py_UNUSED(closure)) { From f37596337c007cbf370076bb485fb58971232f9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:48:14 +0200 Subject: [PATCH 10/14] add `hacl_get_blake2_info` to extract static BLAKE-2 information - use this new helper in `py_blake2b_get_digest_size` - in the future, exposing `key_length` will be easier --- Modules/blake2module.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/Modules/blake2module.c b/Modules/blake2module.c index 1367f5305cb12f..0ea474c92eb4d0 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -919,29 +919,37 @@ py_blake2b_get_block_size(PyObject *op, void *Py_UNUSED(closure)) } -static PyObject * -py_blake2b_get_digest_size(PyObject *op, void *Py_UNUSED(closure)) +static Hacl_Hash_Blake2b_index +hacl_get_blake2_info(Blake2Object *self) { - Blake2Object *self = _Blake2Object_CAST(op); switch (self->impl) { #if HACL_CAN_COMPILE_SIMD256 case Blake2b_256: - return PyLong_FromLong(Hacl_Hash_Blake2b_Simd256_info(self->blake2b_256_state).digest_length); + return Hacl_Hash_Blake2b_Simd256_info(self->blake2b_256_state); #endif #if HACL_CAN_COMPILE_SIMD128 case Blake2s_128: - return PyLong_FromLong(Hacl_Hash_Blake2s_Simd128_info(self->blake2s_128_state).digest_length); + return Hacl_Hash_Blake2s_Simd128_info(self->blake2s_128_state); #endif case Blake2b: - return PyLong_FromLong(Hacl_Hash_Blake2b_info(self->blake2b_state).digest_length); + return Hacl_Hash_Blake2b_info(self->blake2b_state); case Blake2s: - return PyLong_FromLong(Hacl_Hash_Blake2s_info(self->blake2s_state).digest_length); + return Hacl_Hash_Blake2s_info(self->blake2s_state); default: Py_UNREACHABLE(); } } +static PyObject * +py_blake2b_get_digest_size(PyObject *op, void *Py_UNUSED(closure)) +{ + Blake2Object *self = _Blake2Object_CAST(op); + Hacl_Hash_Blake2b_index info = hacl_get_blake2_info(self); + return PyLong_FromLong(info.digest_length); +} + + static PyGetSetDef py_blake2b_getsetters[] = { {"name", py_blake2b_get_name, NULL, NULL, NULL}, {"block_size", py_blake2b_get_block_size, NULL, NULL, NULL}, From ecd8f1968c8a7c7e54a9d2d9fa82e68cd6b13868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:48:41 +0200 Subject: [PATCH 11/14] update module docstring --- Modules/blake2module.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/blake2module.c b/Modules/blake2module.c index 0ea474c92eb4d0..3c4dc44a9bbb6c 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -70,8 +70,7 @@ static PyType_Spec blake2b_type_spec; static PyType_Spec blake2s_type_spec; PyDoc_STRVAR(blake2mod__doc__, -"_blake2b provides BLAKE2b for hashlib\n" -); + "_blake2 provides BLAKE2b and BLAKE2s for hashlib\n"); typedef struct { PyTypeObject *blake2b_type; From f5c518333dff83a8e5c85ac0073ad22de93ad7b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:48:51 +0200 Subject: [PATCH 12/14] various cosmetic changes --- Modules/blake2module.c | 89 ++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/Modules/blake2module.c b/Modules/blake2module.c index 3c4dc44a9bbb6c..d3baf82e7114b8 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -79,7 +79,7 @@ typedef struct { bool can_run_simd256; } Blake2State; -static inline Blake2State* +static inline Blake2State * blake2_get_state(PyObject *module) { void *state = _PyModule_GetState(module); @@ -88,7 +88,7 @@ blake2_get_state(PyObject *module) } #if defined(HACL_CAN_COMPILE_SIMD128) || defined(HACL_CAN_COMPILE_SIMD256) -static inline Blake2State* +static inline Blake2State * blake2_get_state_from_type(PyTypeObject *module) { void *state = _PyType_GetModuleState(module); @@ -201,29 +201,32 @@ blake2module_init_cpu_features(Blake2State *state) #endif } -#define ADD_INT(d, name, value) do { \ - PyObject *x = PyLong_FromLong(value); \ - if (!x) \ - return -1; \ - if (PyDict_SetItemString(d, name, x) < 0) { \ - Py_DECREF(x); \ - return -1; \ - } \ - Py_DECREF(x); \ -} while(0) - -#define ADD_INT_CONST(NAME, VALUE) do { \ - if (PyModule_AddIntConstant(m, NAME, VALUE) < 0) { \ - return -1; \ - } \ -} while (0) - static int blake2_exec(PyObject *m) { Blake2State *st = blake2_get_state(m); blake2module_init_cpu_features(st); +#define ADD_INT(DICT, NAME, VALUE) \ + do { \ + PyObject *x = PyLong_FromLong(VALUE); \ + if (x == NULL) { \ + return -1; \ + } \ + int rc = PyDict_SetItemString(DICT, NAME, x); \ + Py_DECREF(x); \ + if (rc < 0) { \ + return -1; \ + } \ + } while(0) + +#define ADD_INT_CONST(NAME, VALUE) \ + do { \ + if (PyModule_AddIntConstant(m, NAME, VALUE) < 0) { \ + return -1; \ + } \ + } while (0) + ADD_INT_CONST("_GIL_MINSIZE", HASHLIB_GIL_MINSIZE); st->blake2b_type = (PyTypeObject *)PyType_FromModuleAndSpec( @@ -232,7 +235,6 @@ blake2_exec(PyObject *m) if (st->blake2b_type == NULL) { return -1; } - /* BLAKE2b */ if (PyModule_AddType(m, st->blake2b_type) < 0) { return -1; } @@ -252,9 +254,9 @@ blake2_exec(PyObject *m) st->blake2s_type = (PyTypeObject *)PyType_FromModuleAndSpec( m, &blake2s_type_spec, NULL); - if (NULL == st->blake2s_type) + if (st->blake2s_type == NULL) { return -1; - + } if (PyModule_AddType(m, st->blake2s_type) < 0) { return -1; } @@ -270,12 +272,11 @@ blake2_exec(PyObject *m) ADD_INT_CONST("BLAKE2S_MAX_KEY_SIZE", HACL_HASH_BLAKE2S_KEY_BYTES); ADD_INT_CONST("BLAKE2S_MAX_DIGEST_SIZE", HACL_HASH_BLAKE2S_OUT_BYTES); +#undef ADD_INT_CONST +#undef ADD_INT return 0; } -#undef ADD_INT -#undef ADD_INT_CONST - static PyModuleDef_Slot _blake2_slots[] = { {Py_mod_exec, blake2_exec}, {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, @@ -315,16 +316,21 @@ PyInit__blake2(void) // set. typedef enum { Blake2s, Blake2b, Blake2s_128, Blake2b_256 } blake2_impl; -static inline bool is_blake2b(blake2_impl impl) { - return impl == Blake2b || impl == Blake2b_256; +static inline bool +is_blake2b(blake2_impl impl) +{ + return impl == Blake2b || impl == Blake2b_256; } -static inline bool is_blake2s(blake2_impl impl) { - return !is_blake2b(impl); +static inline bool +is_blake2s(blake2_impl impl) +{ + return impl == Blake2s || impl == Blake2s_128; } static inline blake2_impl -type_to_impl(PyTypeObject *type) { +type_to_impl(PyTypeObject *type) +{ #if defined(HACL_CAN_COMPILE_SIMD128) || defined(HACL_CAN_COMPILE_SIMD256) Blake2State *st = blake2_get_state_from_type(type); #endif @@ -423,19 +429,23 @@ update(Blake2Object *self, uint8_t *buf, Py_ssize_t len) // otherwise this results in an unresolved symbol at link-time. #if HACL_CAN_COMPILE_SIMD256 case Blake2b_256: - HACL_UPDATE(Hacl_Hash_Blake2b_Simd256_update,self->blake2b_256_state, buf, len); + HACL_UPDATE(Hacl_Hash_Blake2b_Simd256_update, + self->blake2b_256_state, buf, len); return; #endif #if HACL_CAN_COMPILE_SIMD128 case Blake2s_128: - HACL_UPDATE(Hacl_Hash_Blake2s_Simd128_update,self->blake2s_128_state, buf, len); + HACL_UPDATE(Hacl_Hash_Blake2s_Simd128_update, + self->blake2s_128_state, buf, len); return; #endif case Blake2b: - HACL_UPDATE(Hacl_Hash_Blake2b_update,self->blake2b_state, buf, len); + HACL_UPDATE(Hacl_Hash_Blake2b_update, + self->blake2b_state, buf, len); return; case Blake2s: - HACL_UPDATE(Hacl_Hash_Blake2s_update,self->blake2s_state, buf, len); + HACL_UPDATE(Hacl_Hash_Blake2s_update, + self->blake2s_state, buf, len); return; default: Py_UNREACHABLE(); @@ -826,7 +836,8 @@ _blake2_blake2b_update_impl(Blake2Object *self, PyObject *data) update(self, buf.buf, buf.len); PyMutex_Unlock(&self->mutex); Py_END_ALLOW_THREADS - } else { + } + else { update(self, buf.buf, buf.len); } @@ -1022,7 +1033,7 @@ static PyType_Slot blake2b_type_slots[] = { {Py_tp_methods, py_blake2b_methods}, {Py_tp_getset, py_blake2b_getsetters}, {Py_tp_new, py_blake2b_new}, - {0,0} + {0, 0} }; static PyType_Slot blake2s_type_slots[] = { @@ -1035,12 +1046,12 @@ static PyType_Slot blake2s_type_slots[] = { // only the constructor differs, so that it can receive a clinic-generated // default digest length suitable for blake2s {Py_tp_new, py_blake2s_new}, - {0,0} + {0, 0} }; static PyType_Spec blake2b_type_spec = { .name = "_blake2.blake2b", - .basicsize = sizeof(Blake2Object), + .basicsize = sizeof(Blake2Object), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HEAPTYPE, .slots = blake2b_type_slots @@ -1048,7 +1059,7 @@ static PyType_Spec blake2b_type_spec = { static PyType_Spec blake2s_type_spec = { .name = "_blake2.blake2s", - .basicsize = sizeof(Blake2Object), + .basicsize = sizeof(Blake2Object), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HEAPTYPE, .slots = blake2s_type_slots From ce0e8485084b037115c753c7da5764168c854f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 1 Jun 2025 14:18:50 +0200 Subject: [PATCH 13/14] blurb --- .../Library/2025-06-01-14-18-48.gh-issue-135004.cq3-fp.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2025-06-01-14-18-48.gh-issue-135004.cq3-fp.rst diff --git a/Misc/NEWS.d/next/Library/2025-06-01-14-18-48.gh-issue-135004.cq3-fp.rst b/Misc/NEWS.d/next/Library/2025-06-01-14-18-48.gh-issue-135004.cq3-fp.rst new file mode 100644 index 00000000000000..4c59b0f8e19e6b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-06-01-14-18-48.gh-issue-135004.cq3-fp.rst @@ -0,0 +1,3 @@ +Rewrite and cleanup the internal :mod:`!_blake2` module. Some exception +messages were changed but their types were left untouched. Patch by Bénédikt +Tran. From b16e301fa4e59b5c486ad36b6897d63a2e6e2911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 8 Jun 2025 11:29:32 +0200 Subject: [PATCH 14/14] add missing blank line --- Modules/blake2module.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/blake2module.c b/Modules/blake2module.c index d3baf82e7114b8..2ce8c0cd3d7b6f 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -754,6 +754,7 @@ blake2_blake2b_copy_locked(Blake2Object *self, Blake2Object *cpy) goto error; \ } \ } while (0) + switch (self->impl) { #if HACL_CAN_COMPILE_SIMD256 case Blake2b_256: