| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Written in 2013 by Dmitry Chestnykh <dmitry@codingrobots.com> | 
					
						
							|  |  |  |  * Modified for CPython by Christian Heimes <christian@python.org> | 
					
						
							|  |  |  |  * Updated to use HACL* by Jonathan Protzenko <jonathan@protzenko.fr> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * To the extent possible under law, the author have dedicated all | 
					
						
							|  |  |  |  * copyright and related and neighboring rights to this software to | 
					
						
							|  |  |  |  * the public domain worldwide. This software is distributed without | 
					
						
							|  |  |  |  * any warranty. http://creativecommons.org/publicdomain/zero/1.0/
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef Py_BUILD_CORE_BUILTIN
 | 
					
						
							|  |  |  | #  define Py_BUILD_CORE_MODULE 1
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "pyconfig.h"
 | 
					
						
							|  |  |  | #include "Python.h"
 | 
					
						
							|  |  |  | #include "hashlib.h"
 | 
					
						
							|  |  |  | #include "pycore_strhex.h"       // _Py_strhex()
 | 
					
						
							|  |  |  | #include "pycore_typeobject.h"
 | 
					
						
							|  |  |  | #include "pycore_moduleobject.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // QUICK CPU AUTODETECTION
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // See https://github.com/python/cpython/pull/119316 -- we only enable
 | 
					
						
							|  |  |  | // vectorized versions for Intel CPUs, even though HACL*'s "vec128" modules also
 | 
					
						
							|  |  |  | // run on ARM NEON. (We could enable them on POWER -- but I don't have access to
 | 
					
						
							|  |  |  | // a test machine to see if that speeds anything up.)
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Note that configure.ac and the rest of the build are written in such a way
 | 
					
						
							|  |  |  | // that if the configure script finds suitable flags to compile HACL's SIMD128
 | 
					
						
							|  |  |  | // (resp. SIMD256) files, then Hacl_Hash_Blake2b_Simd128.c (resp. ...) will be
 | 
					
						
							|  |  |  | // pulled into the build automatically, and then only the CPU autodetection will
 | 
					
						
							|  |  |  | // need to be updated here.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(__x86_64__) && defined(__GNUC__)
 | 
					
						
							|  |  |  | #include <cpuid.h>
 | 
					
						
							|  |  |  | #elif defined(_M_X64)
 | 
					
						
							|  |  |  | #include <intrin.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdbool.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-16 12:23:05 +08:00
										 |  |  | // SIMD256 can't be compiled on macOS ARM64, and performance of SIMD128 isn't
 | 
					
						
							|  |  |  | // great; but when compiling a universal2 binary, autoconf will set
 | 
					
						
							|  |  |  | // HACL_CAN_COMPILE_SIMD128 and HACL_CAN_COMPILE_SIMD256 because they *can* be
 | 
					
						
							|  |  |  | // compiled on x86_64. If we're on macOS ARM64, disable these preprocessor
 | 
					
						
							|  |  |  | // symbols.
 | 
					
						
							|  |  |  | #if defined(__APPLE__) && defined(__arm64__)
 | 
					
						
							|  |  |  | #  undef HACL_CAN_COMPILE_SIMD128
 | 
					
						
							|  |  |  | #  undef HACL_CAN_COMPILE_SIMD256
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  | // 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]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     (void) eax1; (void) ebx1; (void) ecx1; (void) edx1; | 
					
						
							|  |  |  |     (void) eax7; (void) ebx7; (void) ecx7; (void) edx7; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-30 13:28:32 +03:00
										 |  |  | #ifdef HACL_CAN_COMPILE_SIMD128
 | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  | 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; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-08-30 13:28:32 +03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-30 13:28:32 +03:00
										 |  |  | #ifdef HACL_CAN_COMPILE_SIMD256
 | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  | static inline bool has_simd256(cpu_flags *flags) { | 
					
						
							|  |  |  |   return flags->avx && flags->avx2; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-08-30 13:28:32 +03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | // 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
 | 
					
						
							|  |  |  | #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
 | 
					
						
							|  |  |  | #if HACL_CAN_COMPILE_SIMD128
 | 
					
						
							|  |  |  | #include "_hacl/Hacl_Hash_Blake2s_Simd128.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // MODULE TYPE SLOTS
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyType_Spec blake2b_type_spec; | 
					
						
							|  |  |  | static PyType_Spec blake2s_type_spec; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(blake2mod__doc__, | 
					
						
							|  |  |  | "_blake2b provides BLAKE2b for hashlib\n" | 
					
						
							|  |  |  | ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |     PyTypeObject* blake2b_type; | 
					
						
							|  |  |  |     PyTypeObject* blake2s_type; | 
					
						
							|  |  |  |     cpu_flags flags; | 
					
						
							|  |  |  | } Blake2State; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline Blake2State* | 
					
						
							|  |  |  | blake2_get_state(PyObject *module) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     void *state = _PyModule_GetState(module); | 
					
						
							|  |  |  |     assert(state != NULL); | 
					
						
							|  |  |  |     return (Blake2State *)state; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-30 13:28:32 +03:00
										 |  |  | #if defined(HACL_CAN_COMPILE_SIMD128) || defined(HACL_CAN_COMPILE_SIMD256)
 | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  | static inline Blake2State* | 
					
						
							|  |  |  | blake2_get_state_from_type(PyTypeObject *module) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     void *state = _PyType_GetModuleState(module); | 
					
						
							|  |  |  |     assert(state != NULL); | 
					
						
							|  |  |  |     return (Blake2State *)state; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-08-30 13:28:32 +03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef blake2mod_functions[] = { | 
					
						
							|  |  |  |     {NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | _blake2_traverse(PyObject *module, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Blake2State *state = blake2_get_state(module); | 
					
						
							|  |  |  |     Py_VISIT(state->blake2b_type); | 
					
						
							|  |  |  |     Py_VISIT(state->blake2s_type); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | _blake2_clear(PyObject *module) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Blake2State *state = blake2_get_state(module); | 
					
						
							|  |  |  |     Py_CLEAR(state->blake2b_type); | 
					
						
							|  |  |  |     Py_CLEAR(state->blake2s_type); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | _blake2_free(void *module) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     (void)_blake2_clear((PyObject *)module); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #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); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // 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); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     st->blake2b_type = (PyTypeObject *)PyType_FromModuleAndSpec( | 
					
						
							|  |  |  |         m, &blake2b_type_spec, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (st->blake2b_type == NULL) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /* BLAKE2b */ | 
					
						
							|  |  |  |     if (PyModule_AddType(m, st->blake2b_type) < 0) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyObject *d = st->blake2b_type->tp_dict; | 
					
						
							|  |  |  |     ADD_INT(d, "SALT_SIZE", HACL_HASH_BLAKE2B_SALT_BYTES); | 
					
						
							|  |  |  |     ADD_INT(d, "PERSON_SIZE", HACL_HASH_BLAKE2B_PERSONAL_BYTES); | 
					
						
							|  |  |  |     ADD_INT(d, "MAX_KEY_SIZE", HACL_HASH_BLAKE2B_KEY_BYTES); | 
					
						
							|  |  |  |     ADD_INT(d, "MAX_DIGEST_SIZE", HACL_HASH_BLAKE2B_OUT_BYTES); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ADD_INT_CONST("BLAKE2B_SALT_SIZE", HACL_HASH_BLAKE2B_SALT_BYTES); | 
					
						
							|  |  |  |     ADD_INT_CONST("BLAKE2B_PERSON_SIZE", HACL_HASH_BLAKE2B_PERSONAL_BYTES); | 
					
						
							|  |  |  |     ADD_INT_CONST("BLAKE2B_MAX_KEY_SIZE", HACL_HASH_BLAKE2B_KEY_BYTES); | 
					
						
							|  |  |  |     ADD_INT_CONST("BLAKE2B_MAX_DIGEST_SIZE", HACL_HASH_BLAKE2B_OUT_BYTES); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* BLAKE2s */ | 
					
						
							|  |  |  |     st->blake2s_type = (PyTypeObject *)PyType_FromModuleAndSpec( | 
					
						
							|  |  |  |         m, &blake2s_type_spec, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (NULL == st->blake2s_type) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (PyModule_AddType(m, st->blake2s_type) < 0) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     d = st->blake2s_type->tp_dict; | 
					
						
							|  |  |  |     ADD_INT(d, "SALT_SIZE", HACL_HASH_BLAKE2S_SALT_BYTES); | 
					
						
							|  |  |  |     ADD_INT(d, "PERSON_SIZE", HACL_HASH_BLAKE2S_PERSONAL_BYTES); | 
					
						
							|  |  |  |     ADD_INT(d, "MAX_KEY_SIZE", HACL_HASH_BLAKE2S_KEY_BYTES); | 
					
						
							|  |  |  |     ADD_INT(d, "MAX_DIGEST_SIZE", HACL_HASH_BLAKE2S_OUT_BYTES); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ADD_INT_CONST("BLAKE2S_SALT_SIZE", HACL_HASH_BLAKE2S_SALT_BYTES); | 
					
						
							|  |  |  |     ADD_INT_CONST("BLAKE2S_PERSON_SIZE", HACL_HASH_BLAKE2S_PERSONAL_BYTES); | 
					
						
							|  |  |  |     ADD_INT_CONST("BLAKE2S_MAX_KEY_SIZE", HACL_HASH_BLAKE2S_KEY_BYTES); | 
					
						
							|  |  |  |     ADD_INT_CONST("BLAKE2S_MAX_DIGEST_SIZE", HACL_HASH_BLAKE2S_OUT_BYTES); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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}, | 
					
						
							|  |  |  |     {Py_mod_gil, Py_MOD_GIL_NOT_USED}, | 
					
						
							|  |  |  |     {0, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyModuleDef blake2_module = { | 
					
						
							|  |  |  |     .m_base = PyModuleDef_HEAD_INIT, | 
					
						
							|  |  |  |     .m_name = "_blake2", | 
					
						
							|  |  |  |     .m_doc = blake2mod__doc__, | 
					
						
							|  |  |  |     .m_size = sizeof(Blake2State), | 
					
						
							|  |  |  |     .m_methods = blake2mod_functions, | 
					
						
							|  |  |  |     .m_slots = _blake2_slots, | 
					
						
							|  |  |  |     .m_traverse = _blake2_traverse, | 
					
						
							|  |  |  |     .m_clear = _blake2_clear, | 
					
						
							|  |  |  |     .m_free = _blake2_free, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyMODINIT_FUNC | 
					
						
							|  |  |  | PyInit__blake2(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return PyModuleDef_Init(&blake2_module); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // IMPLEMENTATION OF METHODS
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // The HACL* API does not offer an agile API that can deal with either Blake2S
 | 
					
						
							|  |  |  | // or Blake2B -- the reason is that the underlying states are optimized (uint32s
 | 
					
						
							|  |  |  | // for S, uint64s for B). Therefore, we use a tagged union in this module to
 | 
					
						
							|  |  |  | // correctly dispatch. Note that the previous incarnation of this code
 | 
					
						
							|  |  |  | // transformed the Blake2b implementation into the Blake2s one using a script,
 | 
					
						
							|  |  |  | // so this is an improvement.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // The 128 and 256 versions are only available if i) we were able to compile
 | 
					
						
							|  |  |  | // them, and ii) if the CPU we run on also happens to have the right instruction
 | 
					
						
							|  |  |  | // 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_blake2s(blake2_impl impl) { | 
					
						
							|  |  |  |   return !is_blake2b(impl); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline blake2_impl type_to_impl(PyTypeObject *type) { | 
					
						
							| 
									
										
										
										
											2024-08-30 13:28:32 +03:00
										 |  |  | #if defined(HACL_CAN_COMPILE_SIMD128) || defined(HACL_CAN_COMPILE_SIMD256)
 | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |     Blake2State* st = blake2_get_state_from_type(type); | 
					
						
							| 
									
										
										
										
											2024-08-30 13:28:32 +03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |     if (!strcmp(type->tp_name, blake2b_type_spec.name)) { | 
					
						
							|  |  |  | #ifdef HACL_CAN_COMPILE_SIMD256
 | 
					
						
							|  |  |  |       if (has_simd256(&st->flags)) | 
					
						
							|  |  |  |         return Blake2b_256; | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         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
 | 
					
						
							|  |  |  |         return Blake2s; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       Py_UNREACHABLE(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |     PyObject_HEAD | 
					
						
							|  |  |  |     union { | 
					
						
							|  |  |  |         Hacl_Hash_Blake2s_state_t *blake2s_state; | 
					
						
							|  |  |  |         Hacl_Hash_Blake2b_state_t *blake2b_state; | 
					
						
							|  |  |  | #ifdef HACL_CAN_COMPILE_SIMD128
 | 
					
						
							|  |  |  |         Hacl_Hash_Blake2s_Simd128_state_t *blake2s_128_state; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef HACL_CAN_COMPILE_SIMD256
 | 
					
						
							|  |  |  |         Hacl_Hash_Blake2b_Simd256_state_t *blake2b_256_state; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     blake2_impl impl; | 
					
						
							|  |  |  |     bool use_mutex; | 
					
						
							|  |  |  |     PyMutex mutex; | 
					
						
							|  |  |  | } Blake2Object; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "clinic/blake2module.c.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | module _blake2 | 
					
						
							|  |  |  | class _blake2.blake2b "Blake2Object *" "&PyBlake2_BLAKE2bType" | 
					
						
							|  |  |  | class _blake2.blake2s "Blake2Object *" "&PyBlake2_BLAKE2sType" | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b7526666bd18af83]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Blake2Object * | 
					
						
							|  |  |  | new_Blake2Object(PyTypeObject *type) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |     Blake2Object *self = PyObject_GC_New(Blake2Object, type); | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |     if (self == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     HASHLIB_INIT_MUTEX(self); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |     PyObject_GC_Track(self); | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |     return self; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* HACL* takes a uint32_t for the length of its parameter, but Py_ssize_t can be
 | 
					
						
							|  |  |  |  * 64 bits so we loop in <4gig chunks when needed. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if PY_SSIZE_T_MAX > UINT32_MAX
 | 
					
						
							|  |  |  | #define HACL_UPDATE_LOOP(update,state,buf,len) \
 | 
					
						
							|  |  |  |   while (len > UINT32_MAX) { \ | 
					
						
							|  |  |  |     update(state, buf, UINT32_MAX); \ | 
					
						
							|  |  |  |     len -= UINT32_MAX; \ | 
					
						
							|  |  |  |     buf += UINT32_MAX; \ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define HACL_UPDATE_LOOP(update,state,buf,len)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define HACL_UPDATE(update,state,buf,len) do { \
 | 
					
						
							|  |  |  |   /* Note: we explicitly ignore the error code on the basis that it would take >
 | 
					
						
							|  |  |  |    * 1 billion years to overflow the maximum admissible length for SHA2-256 | 
					
						
							|  |  |  |    * (namely, 2^61-1 bytes). */ \ | 
					
						
							|  |  |  |   HACL_UPDATE_LOOP(update,state,buf,len) \ | 
					
						
							|  |  |  |   /* Cast to uint32_t is safe: len <= UINT32_MAX at this point. */ \ | 
					
						
							|  |  |  |   update(state, buf, (uint32_t) len); \ | 
					
						
							|  |  |  | } while (0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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
 | 
					
						
							|  |  |  |         case Blake2b_256: | 
					
						
							|  |  |  |             HACL_UPDATE(Hacl_Hash_Blake2b_Simd256_update,self->blake2b_256_state, buf, len); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef HACL_CAN_COMPILE_SIMD128
 | 
					
						
							|  |  |  |         case Blake2s_128: | 
					
						
							|  |  |  |             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); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         case Blake2s: | 
					
						
							|  |  |  |             HACL_UPDATE(Hacl_Hash_Blake2s_update,self->blake2s_state, buf, len); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             Py_UNREACHABLE(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Blake2Object *self = NULL; | 
					
						
							|  |  |  |     Py_buffer buf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     self = new_Blake2Object(type); | 
					
						
							|  |  |  |     if (self == NULL) { | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     self->impl = type_to_impl(type); | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |     // Ensure that the states are NULL-initialized in case of an error.
 | 
					
						
							|  |  |  |     // See: py_blake2_clear() for more details.
 | 
					
						
							|  |  |  |     switch (self->impl) { | 
					
						
							|  |  |  | #if HACL_CAN_COMPILE_SIMD256
 | 
					
						
							|  |  |  |         case Blake2b_256: | 
					
						
							|  |  |  |             self->blake2b_256_state = NULL; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if HACL_CAN_COMPILE_SIMD128
 | 
					
						
							|  |  |  |         case Blake2s_128: | 
					
						
							|  |  |  |             self->blake2s_128_state = NULL; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         case Blake2b: | 
					
						
							|  |  |  |             self->blake2b_state = NULL; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case Blake2s: | 
					
						
							|  |  |  |             self->blake2s_state = NULL; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             Py_UNREACHABLE(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |     // 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)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         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) { | 
					
						
							| 
									
										
										
										
											2024-11-05 16:05:13 +01:00
										 |  |  |         if ((size_t)salt->len > (is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_SALT_BYTES : HACL_HASH_BLAKE2S_SALT_BYTES)) { | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |             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) { | 
					
						
							| 
									
										
										
										
											2024-11-05 16:05:13 +01:00
										 |  |  |         if ((size_t)person->len > (is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_PERSONAL_BYTES : HACL_HASH_BLAKE2S_PERSONAL_BYTES)) { | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |             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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Set key length. */ | 
					
						
							|  |  |  |     if ((key->obj != NULL) && key->len) { | 
					
						
							| 
									
										
										
										
											2024-11-05 16:05:13 +01:00
										 |  |  |         if ((size_t)key->len > (is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_KEY_BYTES : HACL_HASH_BLAKE2S_KEY_BYTES)) { | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |             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; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // 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, | 
					
						
							|  |  |  |         .fanout = fanout, | 
					
						
							|  |  |  |         .depth = depth, | 
					
						
							|  |  |  |         .leaf_length = leaf_size, | 
					
						
							|  |  |  |         .node_offset = node_offset, | 
					
						
							|  |  |  |         .node_depth = node_depth, | 
					
						
							|  |  |  |         .inner_length = inner_size, | 
					
						
							|  |  |  |         .salt = salt_, | 
					
						
							|  |  |  |         .personal = personal_ | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  |             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); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         case Blake2b: | 
					
						
							|  |  |  |             self->blake2b_state = Hacl_Hash_Blake2b_malloc_with_params_and_key(¶ms, last_node, key->buf); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case Blake2s: | 
					
						
							|  |  |  |             self->blake2s_state = Hacl_Hash_Blake2s_malloc_with_params_and_key(¶ms, last_node, key->buf); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             Py_UNREACHABLE(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Process initial data if any. */ | 
					
						
							|  |  |  |     if (data != NULL) { | 
					
						
							|  |  |  |         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); | 
					
						
							|  |  |  |             Py_END_ALLOW_THREADS | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             update(self, buf.buf, buf.len); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         PyBuffer_Release(&buf); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return (PyObject *)self; | 
					
						
							|  |  |  | error: | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |     Py_XDECREF(self); | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | @classmethod | 
					
						
							|  |  |  | _blake2.blake2b.__new__ as py_blake2b_new | 
					
						
							|  |  |  |     data: object(c_default="NULL") = b'' | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  |     * | 
					
						
							|  |  |  |     digest_size: int(c_default="HACL_HASH_BLAKE2B_OUT_BYTES") = _blake2.blake2b.MAX_DIGEST_SIZE | 
					
						
							|  |  |  |     key: Py_buffer(c_default="NULL", py_default="b''") = None | 
					
						
							|  |  |  |     salt: Py_buffer(c_default="NULL", py_default="b''") = None | 
					
						
							|  |  |  |     person: Py_buffer(c_default="NULL", py_default="b''") = None | 
					
						
							|  |  |  |     fanout: int = 1 | 
					
						
							|  |  |  |     depth: int = 1 | 
					
						
							|  |  |  |     leaf_size: unsigned_long = 0 | 
					
						
							|  |  |  |     node_offset: unsigned_long_long = 0 | 
					
						
							|  |  |  |     node_depth: int = 0 | 
					
						
							|  |  |  |     inner_size: int = 0 | 
					
						
							|  |  |  |     last_node: bool = False | 
					
						
							|  |  |  |     usedforsecurity: bool = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Return a new BLAKE2b hash object. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | py_blake2b_new_impl(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) | 
					
						
							|  |  |  | /*[clinic end generated code: output=32bfd8f043c6896f input=8fee2b7b11428b2d]*/ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | @classmethod | 
					
						
							|  |  |  | _blake2.blake2s.__new__ as py_blake2s_new | 
					
						
							|  |  |  |     data: object(c_default="NULL") = b'' | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  |     * | 
					
						
							|  |  |  |     digest_size: int(c_default="HACL_HASH_BLAKE2S_OUT_BYTES") = _blake2.blake2s.MAX_DIGEST_SIZE | 
					
						
							|  |  |  |     key: Py_buffer(c_default="NULL", py_default="b''") = None | 
					
						
							|  |  |  |     salt: Py_buffer(c_default="NULL", py_default="b''") = None | 
					
						
							|  |  |  |     person: Py_buffer(c_default="NULL", py_default="b''") = None | 
					
						
							|  |  |  |     fanout: int = 1 | 
					
						
							|  |  |  |     depth: int = 1 | 
					
						
							|  |  |  |     leaf_size: unsigned_long = 0 | 
					
						
							|  |  |  |     node_offset: unsigned_long_long = 0 | 
					
						
							|  |  |  |     node_depth: int = 0 | 
					
						
							|  |  |  |     inner_size: int = 0 | 
					
						
							|  |  |  |     last_node: bool = False | 
					
						
							|  |  |  |     usedforsecurity: bool = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Return a new BLAKE2s hash object. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | py_blake2s_new_impl(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) | 
					
						
							|  |  |  | /*[clinic end generated code: output=556181f73905c686 input=8165a11980eac7f3]*/ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _blake2.blake2b.copy | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Return a copy of the hash object. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | _blake2_blake2b_copy_impl(Blake2Object *self) | 
					
						
							|  |  |  | /*[clinic end generated code: output=622d1c56b91c50d8 input=e383c2d199fd8a2e]*/ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Blake2Object *cpy; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((cpy = new_Blake2Object(Py_TYPE(self))) == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ENTER_HASHLIB(self); | 
					
						
							|  |  |  |     switch (self->impl) { | 
					
						
							|  |  |  | #if HACL_CAN_COMPILE_SIMD256
 | 
					
						
							|  |  |  |         case Blake2b_256: | 
					
						
							|  |  |  |             cpy->blake2b_256_state = Hacl_Hash_Blake2b_Simd256_copy(self->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); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         case Blake2b: | 
					
						
							|  |  |  |             cpy->blake2b_state = Hacl_Hash_Blake2b_copy(self->blake2b_state); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case Blake2s: | 
					
						
							|  |  |  |             cpy->blake2s_state = Hacl_Hash_Blake2s_copy(self->blake2s_state); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             Py_UNREACHABLE(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     cpy->impl = self->impl; | 
					
						
							|  |  |  |     LEAVE_HASHLIB(self); | 
					
						
							|  |  |  |     return (PyObject *)cpy; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _blake2.blake2b.update | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     data: object | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Update this hash object's state with the provided bytes-like object. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | _blake2_blake2b_update(Blake2Object *self, PyObject *data) | 
					
						
							|  |  |  | /*[clinic end generated code: output=e6d1ac88471df308 input=ffc4aa6a6a225d31]*/ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Py_buffer buf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     GET_BUFFER_VIEW_OR_ERROUT(data, &buf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!self->use_mutex && buf.len >= HASHLIB_GIL_MINSIZE) { | 
					
						
							|  |  |  |         self->use_mutex = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (self->use_mutex) { | 
					
						
							|  |  |  |         Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  |         PyMutex_Lock(&self->mutex); | 
					
						
							|  |  |  |         update(self, buf.buf, buf.len); | 
					
						
							|  |  |  |         PyMutex_Unlock(&self->mutex); | 
					
						
							|  |  |  |         Py_END_ALLOW_THREADS | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         update(self, buf.buf, buf.len); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyBuffer_Release(&buf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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]*/ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  | #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(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     LEAVE_HASHLIB(self); | 
					
						
							|  |  |  |     return PyBytes_FromStringAndSize((const char *)digest, digest_length); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _blake2.blake2b.hexdigest | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Return the digest value as a string of hexadecimal digits. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | _blake2_blake2b_hexdigest_impl(Blake2Object *self) | 
					
						
							|  |  |  | /*[clinic end generated code: output=5ef54b138db6610a input=76930f6946351f56]*/ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  | #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(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     LEAVE_HASHLIB(self); | 
					
						
							|  |  |  |     return _Py_strhex((const char *)digest, digest_length); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyMethodDef py_blake2b_methods[] = { | 
					
						
							|  |  |  |     _BLAKE2_BLAKE2B_COPY_METHODDEF | 
					
						
							|  |  |  |     _BLAKE2_BLAKE2B_DIGEST_METHODDEF | 
					
						
							|  |  |  |     _BLAKE2_BLAKE2B_HEXDIGEST_METHODDEF | 
					
						
							|  |  |  |     _BLAKE2_BLAKE2B_UPDATE_METHODDEF | 
					
						
							|  |  |  |     {NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | py_blake2b_get_name(Blake2Object *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return PyUnicode_FromString(is_blake2b(self->impl) ? "blake2b" : "blake2s"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | py_blake2b_get_block_size(Blake2Object *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return PyLong_FromLong(is_blake2b(self->impl) ? HACL_HASH_BLAKE2B_BLOCK_BYTES : HACL_HASH_BLAKE2S_BLOCK_BYTES); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | py_blake2b_get_digest_size(Blake2Object *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if HACL_CAN_COMPILE_SIMD128
 | 
					
						
							|  |  |  |         case Blake2s_128: | 
					
						
							|  |  |  |             return PyLong_FromLong(Hacl_Hash_Blake2s_Simd128_info(self->blake2s_128_state).digest_length); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         case Blake2b: | 
					
						
							|  |  |  |             return PyLong_FromLong(Hacl_Hash_Blake2b_info(self->blake2b_state).digest_length); | 
					
						
							|  |  |  |         case Blake2s: | 
					
						
							|  |  |  |             return PyLong_FromLong(Hacl_Hash_Blake2s_info(self->blake2s_state).digest_length); | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             Py_UNREACHABLE(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyGetSetDef py_blake2b_getsetters[] = { | 
					
						
							|  |  |  |     {"name", (getter)py_blake2b_get_name, | 
					
						
							|  |  |  |         NULL, NULL, NULL}, | 
					
						
							|  |  |  |     {"block_size", (getter)py_blake2b_get_block_size, | 
					
						
							|  |  |  |         NULL, NULL, NULL}, | 
					
						
							|  |  |  |     {"digest_size", (getter)py_blake2b_get_digest_size, | 
					
						
							|  |  |  |         NULL, NULL, NULL}, | 
					
						
							|  |  |  |     {NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  | static int | 
					
						
							|  |  |  | py_blake2_clear(PyObject *op) | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |     Blake2Object *self = (Blake2Object *)op; | 
					
						
							|  |  |  |     // The initialization function uses PyObject_GC_New() but explicitly
 | 
					
						
							|  |  |  |     // 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).
 | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |     switch (self->impl) { | 
					
						
							|  |  |  | #if HACL_CAN_COMPILE_SIMD256
 | 
					
						
							|  |  |  |         case Blake2b_256: | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |             if (self->blake2b_256_state != NULL) { | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |                 Hacl_Hash_Blake2b_Simd256_free(self->blake2b_256_state); | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |                 self->blake2b_256_state = NULL; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |             break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if HACL_CAN_COMPILE_SIMD128
 | 
					
						
							|  |  |  |         case Blake2s_128: | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |             if (self->blake2s_128_state != NULL) { | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |                 Hacl_Hash_Blake2s_Simd128_free(self->blake2s_128_state); | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |                 self->blake2s_128_state = NULL; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |             break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         case Blake2b: | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |             if (self->blake2b_state != NULL) { | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |                 Hacl_Hash_Blake2b_free(self->blake2b_state); | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |                 self->blake2b_state = NULL; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |             break; | 
					
						
							|  |  |  |         case Blake2s: | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |             if (self->blake2s_state != NULL) { | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |                 Hacl_Hash_Blake2s_free(self->blake2s_state); | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |                 self->blake2s_state = NULL; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             Py_UNREACHABLE(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  | static void | 
					
						
							|  |  |  | py_blake2_dealloc(PyObject *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |     PyTypeObject *type = Py_TYPE(self); | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |     PyObject_GC_UnTrack(self); | 
					
						
							|  |  |  |     (void)py_blake2_clear(self); | 
					
						
							|  |  |  |     type->tp_free(self); | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |     Py_DECREF(type); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  | static int | 
					
						
							|  |  |  | py_blake2_traverse(PyObject *self, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Py_VISIT(Py_TYPE(self)); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  | static PyType_Slot blake2b_type_slots[] = { | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |     {Py_tp_clear, py_blake2_clear}, | 
					
						
							|  |  |  |     {Py_tp_dealloc, py_blake2_dealloc}, | 
					
						
							|  |  |  |     {Py_tp_traverse, py_blake2_traverse}, | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |     {Py_tp_doc, (char *)py_blake2b_new__doc__}, | 
					
						
							|  |  |  |     {Py_tp_methods, py_blake2b_methods}, | 
					
						
							|  |  |  |     {Py_tp_getset, py_blake2b_getsetters}, | 
					
						
							|  |  |  |     {Py_tp_new, py_blake2b_new}, | 
					
						
							|  |  |  |     {0,0} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyType_Slot blake2s_type_slots[] = { | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |     {Py_tp_clear, py_blake2_clear}, | 
					
						
							|  |  |  |     {Py_tp_dealloc, py_blake2_dealloc}, | 
					
						
							|  |  |  |     {Py_tp_traverse, py_blake2_traverse}, | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |     {Py_tp_doc, (char *)py_blake2s_new__doc__}, | 
					
						
							|  |  |  |     {Py_tp_methods, py_blake2b_methods}, | 
					
						
							|  |  |  |     {Py_tp_getset, py_blake2b_getsetters}, | 
					
						
							|  |  |  |     // 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} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyType_Spec blake2b_type_spec = { | 
					
						
							|  |  |  |     .name = "_blake2.blake2b", | 
					
						
							|  |  |  |     .basicsize =  sizeof(Blake2Object), | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |     .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | 
					
						
							|  |  |  |              | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HEAPTYPE, | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |     .slots = blake2b_type_slots | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyType_Spec blake2s_type_spec = { | 
					
						
							|  |  |  |     .name = "_blake2.blake2s", | 
					
						
							|  |  |  |     .basicsize =  sizeof(Blake2Object), | 
					
						
							| 
									
										
										
										
											2024-12-26 16:03:57 +01:00
										 |  |  |     .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | 
					
						
							|  |  |  |              | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HEAPTYPE, | 
					
						
							| 
									
										
										
										
											2024-08-13 14:42:19 -07:00
										 |  |  |     .slots = blake2s_type_slots | 
					
						
							|  |  |  | }; |