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

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

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

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

#if defined(HACL_CAN_COMPILE_SIMD128) || defined(HACL_CAN_COMPILE_SIMD256)
static inline Blake2State*
blake2_get_state_from_type(PyTypeObject *module)
{
    void *state = _PyType_GetModuleState(module);
    assert(state != NULL);
    return (Blake2State *)state;
}
#endif

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) {
#if defined(HACL_CAN_COMPILE_SIMD128) || defined(HACL_CAN_COMPILE_SIMD256)
    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
        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)
{
    Blake2Object *self;
    self = (Blake2Object *)type->tp_alloc(type, 0);
    if (self == NULL) {
        return NULL;
    }
    HASHLIB_INIT_MUTEX(self);

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

    // 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) {
        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;
    }

    /* 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;
        }
    }

    // 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(&params, 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(&params, last_node, key->buf);
            break;
#endif
        case Blake2b:
            self->blake2b_state = Hacl_Hash_Blake2b_malloc_with_params_and_key(&params, last_node, key->buf);
            break;
        case Blake2s:
            self->blake2s_state = Hacl_Hash_Blake2s_malloc_with_params_and_key(&params, 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:
	Py_XDECREF(self);
    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}
};


static void
py_blake2b_dealloc(Blake2Object *self)
{
    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);
            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);
            break;
#endif
        case Blake2b:
            // This happens if we hit "goto error" in the middle of the
            // initialization function. We leverage the fact that tp_alloc
            // guarantees that the contents of the object are NULL-initialized
            // (see documentation for PyType_GenericAlloc) to detect this case.
            if (self->blake2b_state != NULL)
                Hacl_Hash_Blake2b_free(self->blake2b_state);
            break;
        case Blake2s:
            if (self->blake2s_state != NULL)
                Hacl_Hash_Blake2s_free(self->blake2s_state);
            break;
        default:
            Py_UNREACHABLE();
    }

    PyTypeObject *type = Py_TYPE(self);
    PyObject_Free(self);
    Py_DECREF(type);
}

static PyType_Slot blake2b_type_slots[] = {
    {Py_tp_dealloc, py_blake2b_dealloc},
    {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[] = {
    {Py_tp_dealloc, py_blake2b_dealloc},
    {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),
    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE,
    .slots = blake2b_type_slots
};

static PyType_Spec blake2s_type_spec = {
    .name = "_blake2.blake2s",
    .basicsize =  sizeof(Blake2Object),
    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE,
    .slots = blake2s_type_slots
};
