aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c
diff options
context:
space:
mode:
authornkozlovskiy <nmk@ydb.tech>2023-09-29 12:24:06 +0300
committernkozlovskiy <nmk@ydb.tech>2023-09-29 12:41:34 +0300
commite0e3e1717e3d33762ce61950504f9637a6e669ed (patch)
treebca3ff6939b10ed60c3d5c12439963a1146b9711 /contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c
parent38f2c5852db84c7b4d83adfcb009eb61541d1ccd (diff)
downloadydb-e0e3e1717e3d33762ce61950504f9637a6e669ed.tar.gz
add ydb deps
Diffstat (limited to 'contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c')
-rw-r--r--contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c416
1 files changed, 416 insertions, 0 deletions
diff --git a/contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c b/contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c
new file mode 100644
index 0000000000..c2cac98c75
--- /dev/null
+++ b/contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c
@@ -0,0 +1,416 @@
+/*
+ * Written in 2013 by Dmitry Chestnykh <dmitry@codingrobots.com>
+ * Modified for CPython by Christian Heimes <christian@python.org>
+ *
+ * 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/
+ */
+
+/* WARNING: autogenerated file!
+ *
+ * The blake2s_impl.c is autogenerated from blake2b_impl.c.
+ */
+
+#ifndef Py_BUILD_CORE_BUILTIN
+# define Py_BUILD_CORE_MODULE 1
+#endif
+
+#include "Python.h"
+#include "pycore_strhex.h" // _Py_strhex()
+
+#include "../hashlib.h"
+#include "blake2module.h"
+
+#ifndef HAVE_LIBB2
+/* pure SSE2 implementation is very slow, so only use the more optimized SSSE3+
+ * https://bugs.python.org/issue31834 */
+#if defined(__SSSE3__) || defined(__SSE4_1__) || defined(__AVX__) || defined(__XOP__)
+#include "impl/blake2b.c"
+#else
+#include "impl/blake2b-ref.c"
+#endif
+#endif // !HAVE_LIBB2
+
+#define HAVE_BLAKE2B 1
+
+extern PyType_Spec blake2b_type_spec;
+
+
+typedef struct {
+ PyObject_HEAD
+ blake2b_param param;
+ blake2b_state state;
+ PyThread_type_lock lock;
+} BLAKE2bObject;
+
+#include "clinic/blake2b_impl.c.h"
+
+/*[clinic input]
+module _blake2
+class _blake2.blake2b "BLAKE2bObject *" "&PyBlake2_BLAKE2bType"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d47b0527b39c673f]*/
+
+
+static BLAKE2bObject *
+new_BLAKE2bObject(PyTypeObject *type)
+{
+ BLAKE2bObject *self;
+ self = (BLAKE2bObject *)type->tp_alloc(type, 0);
+ if (self != NULL) {
+ self->lock = NULL;
+ }
+ return self;
+}
+
+/*[clinic input]
+@classmethod
+_blake2.blake2b.__new__ as py_blake2b_new
+ data: object(c_default="NULL") = b''
+ /
+ *
+ digest_size: int(c_default="BLAKE2B_OUTBYTES") = _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=b947312abff46977]*/
+{
+ BLAKE2bObject *self = NULL;
+ Py_buffer buf;
+
+ self = new_BLAKE2bObject(type);
+ if (self == NULL) {
+ goto error;
+ }
+
+ /* Zero parameter block. */
+ memset(&self->param, 0, sizeof(self->param));
+
+ /* Set digest size. */
+ if (digest_size <= 0 || digest_size > BLAKE2B_OUTBYTES) {
+ PyErr_Format(PyExc_ValueError,
+ "digest_size must be between 1 and %d bytes",
+ BLAKE2B_OUTBYTES);
+ goto error;
+ }
+ self->param.digest_length = digest_size;
+
+ /* Set salt parameter. */
+ if ((salt->obj != NULL) && salt->len) {
+ if (salt->len > BLAKE2B_SALTBYTES) {
+ PyErr_Format(PyExc_ValueError,
+ "maximum salt length is %d bytes",
+ BLAKE2B_SALTBYTES);
+ goto error;
+ }
+ memcpy(self->param.salt, salt->buf, salt->len);
+ }
+
+ /* Set personalization parameter. */
+ if ((person->obj != NULL) && person->len) {
+ if (person->len > BLAKE2B_PERSONALBYTES) {
+ PyErr_Format(PyExc_ValueError,
+ "maximum person length is %d bytes",
+ BLAKE2B_PERSONALBYTES);
+ goto error;
+ }
+ memcpy(self->param.personal, person->buf, person->len);
+ }
+
+ /* Set tree parameters. */
+ if (fanout < 0 || fanout > 255) {
+ PyErr_SetString(PyExc_ValueError,
+ "fanout must be between 0 and 255");
+ goto error;
+ }
+ self->param.fanout = (uint8_t)fanout;
+
+ if (depth <= 0 || depth > 255) {
+ PyErr_SetString(PyExc_ValueError,
+ "depth must be between 1 and 255");
+ goto error;
+ }
+ self->param.depth = (uint8_t)depth;
+
+ if (leaf_size > 0xFFFFFFFFU) {
+ PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
+ goto error;
+ }
+ // NB: Simple assignment here would be incorrect on big endian platforms.
+ store32(&(self->param.leaf_length), leaf_size);
+
+#ifdef HAVE_BLAKE2S
+ if (node_offset > 0xFFFFFFFFFFFFULL) {
+ /* maximum 2**48 - 1 */
+ PyErr_SetString(PyExc_OverflowError, "node_offset is too large");
+ goto error;
+ }
+ store48(&(self->param.node_offset), node_offset);
+#else
+ // NB: Simple assignment here would be incorrect on big endian platforms.
+ store64(&(self->param.node_offset), node_offset);
+#endif
+
+ if (node_depth < 0 || node_depth > 255) {
+ PyErr_SetString(PyExc_ValueError,
+ "node_depth must be between 0 and 255");
+ goto error;
+ }
+ self->param.node_depth = node_depth;
+
+ if (inner_size < 0 || inner_size > BLAKE2B_OUTBYTES) {
+ PyErr_Format(PyExc_ValueError,
+ "inner_size must be between 0 and is %d",
+ BLAKE2B_OUTBYTES);
+ goto error;
+ }
+ self->param.inner_length = inner_size;
+
+ /* Set key length. */
+ if ((key->obj != NULL) && key->len) {
+ if (key->len > BLAKE2B_KEYBYTES) {
+ PyErr_Format(PyExc_ValueError,
+ "maximum key length is %d bytes",
+ BLAKE2B_KEYBYTES);
+ goto error;
+ }
+ self->param.key_length = (uint8_t)key->len;
+ }
+
+ /* Initialize hash state. */
+ if (blake2b_init_param(&self->state, &self->param) < 0) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "error initializing hash state");
+ goto error;
+ }
+
+ /* Set last node flag (must come after initialization). */
+ self->state.last_node = last_node;
+
+ /* Process key block if any. */
+ if (self->param.key_length) {
+ uint8_t block[BLAKE2B_BLOCKBYTES];
+ memset(block, 0, sizeof(block));
+ memcpy(block, key->buf, key->len);
+ blake2b_update(&self->state, block, sizeof(block));
+ secure_zero_memory(block, sizeof(block));
+ }
+
+ /* 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
+ blake2b_update(&self->state, buf.buf, buf.len);
+ Py_END_ALLOW_THREADS
+ } else {
+ blake2b_update(&self->state, buf.buf, buf.len);
+ }
+ PyBuffer_Release(&buf);
+ }
+
+ return (PyObject *)self;
+
+ error:
+ if (self != NULL) {
+ Py_DECREF(self);
+ }
+ return NULL;
+}
+
+/*[clinic input]
+_blake2.blake2b.copy
+
+Return a copy of the hash object.
+[clinic start generated code]*/
+
+static PyObject *
+_blake2_blake2b_copy_impl(BLAKE2bObject *self)
+/*[clinic end generated code: output=ff6acee5f93656ae input=e383c2d199fd8a2e]*/
+{
+ BLAKE2bObject *cpy;
+
+ if ((cpy = new_BLAKE2bObject(Py_TYPE(self))) == NULL)
+ return NULL;
+
+ ENTER_HASHLIB(self);
+ cpy->param = self->param;
+ cpy->state = self->state;
+ 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(BLAKE2bObject *self, PyObject *data)
+/*[clinic end generated code: output=010dfcbe22654359 input=ffc4aa6a6a225d31]*/
+{
+ Py_buffer buf;
+
+ GET_BUFFER_VIEW_OR_ERROUT(data, &buf);
+
+ if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE)
+ self->lock = PyThread_allocate_lock();
+
+ if (self->lock != NULL) {
+ Py_BEGIN_ALLOW_THREADS
+ PyThread_acquire_lock(self->lock, 1);
+ blake2b_update(&self->state, buf.buf, buf.len);
+ PyThread_release_lock(self->lock);
+ Py_END_ALLOW_THREADS
+ } else {
+ blake2b_update(&self->state, 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(BLAKE2bObject *self)
+/*[clinic end generated code: output=a5864660f4bfc61a input=7d21659e9c5fff02]*/
+{
+ uint8_t digest[BLAKE2B_OUTBYTES];
+ blake2b_state state_cpy;
+
+ ENTER_HASHLIB(self);
+ state_cpy = self->state;
+ blake2b_final(&state_cpy, digest, self->param.digest_length);
+ LEAVE_HASHLIB(self);
+ return PyBytes_FromStringAndSize((const char *)digest,
+ self->param.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(BLAKE2bObject *self)
+/*[clinic end generated code: output=b5598a87d8794a60 input=76930f6946351f56]*/
+{
+ uint8_t digest[BLAKE2B_OUTBYTES];
+ blake2b_state state_cpy;
+
+ ENTER_HASHLIB(self);
+ state_cpy = self->state;
+ blake2b_final(&state_cpy, digest, self->param.digest_length);
+ LEAVE_HASHLIB(self);
+ return _Py_strhex((const char *)digest, self->param.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(BLAKE2bObject *self, void *closure)
+{
+ return PyUnicode_FromString("blake2b");
+}
+
+
+
+static PyObject *
+py_blake2b_get_block_size(BLAKE2bObject *self, void *closure)
+{
+ return PyLong_FromLong(BLAKE2B_BLOCKBYTES);
+}
+
+
+
+static PyObject *
+py_blake2b_get_digest_size(BLAKE2bObject *self, void *closure)
+{
+ return PyLong_FromLong(self->param.digest_length);
+}
+
+
+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(PyObject *self)
+{
+ BLAKE2bObject *obj = (BLAKE2bObject *)self;
+
+ /* Try not to leave state in memory. */
+ secure_zero_memory(&obj->param, sizeof(obj->param));
+ secure_zero_memory(&obj->state, sizeof(obj->state));
+ if (obj->lock) {
+ PyThread_free_lock(obj->lock);
+ obj->lock = NULL;
+ }
+
+ 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}
+};
+
+PyType_Spec blake2b_type_spec = {
+ .name = "_blake2.blake2b",
+ .basicsize = sizeof(BLAKE2bObject),
+ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE,
+ .slots = blake2b_type_slots
+};