/*
 * 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 = PyObject_GC_New(Blake2Object, type);
    if (self == NULL) {
        return NULL;
    }
    HASHLIB_INIT_MUTEX(self);

    PyObject_GC_Track(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);
    // 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();
    }
    // 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 int
py_blake2_clear(PyObject *op)
{
    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).
    switch (self->impl) {
#if HACL_CAN_COMPILE_SIMD256
        case Blake2b_256:
            if (self->blake2b_256_state != NULL) {
                Hacl_Hash_Blake2b_Simd256_free(self->blake2b_256_state);
                self->blake2b_256_state = NULL;
            }
            break;
#endif
#if HACL_CAN_COMPILE_SIMD128
        case Blake2s_128:
            if (self->blake2s_128_state != NULL) {
                Hacl_Hash_Blake2s_Simd128_free(self->blake2s_128_state);
                self->blake2s_128_state = NULL;
            }
            break;
#endif
        case Blake2b:
            if (self->blake2b_state != NULL) {
                Hacl_Hash_Blake2b_free(self->blake2b_state);
                self->blake2b_state = NULL;
            }
            break;
        case Blake2s:
            if (self->blake2s_state != NULL) {
                Hacl_Hash_Blake2s_free(self->blake2s_state);
                self->blake2s_state = NULL;
            }
            break;
        default:
            Py_UNREACHABLE();
    }
    return 0;
}

static void
py_blake2_dealloc(PyObject *self)
{
    PyTypeObject *type = Py_TYPE(self);
    PyObject_GC_UnTrack(self);
    (void)py_blake2_clear(self);
    type->tp_free(self);
    Py_DECREF(type);
}

static int
py_blake2_traverse(PyObject *self, visitproc visit, void *arg)
{
    Py_VISIT(Py_TYPE(self));
    return 0;
}

static PyType_Slot blake2b_type_slots[] = {
    {Py_tp_clear, py_blake2_clear},
    {Py_tp_dealloc, py_blake2_dealloc},
    {Py_tp_traverse, py_blake2_traverse},
    {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_clear, py_blake2_clear},
    {Py_tp_dealloc, py_blake2_dealloc},
    {Py_tp_traverse, py_blake2_traverse},
    {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
             | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HEAPTYPE,
    .slots = blake2b_type_slots
};

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