From 8a4b8514437fa914767b1cfd51de5a79e533e028 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Mon, 10 Aug 2020 11:43:38 -0500 Subject: [PATCH 01/10] port sha3 --- Modules/_sha3/sha3module.c | 278 +++++++++++++++++++------------------ 1 file changed, 142 insertions(+), 136 deletions(-) diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index c826b42df13f92..96ef5f389d2758 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -122,6 +122,28 @@ #define SHA3_squeeze Keccak_HashSqueeze #define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state)) +typedef struct { + PyTypeObject *sha3_224_type; + PyTypeObject *sha3_256_type; + PyTypeObject *sha3_384_type; + PyTypeObject *sha3_512_type; + PyTypeObject *shake128_type; + PyTypeObject *shake256_type; +#ifdef PY_WITH_KECCAK + PyTypeObject *keccak224_type; + PyTypeObject *keccak256_type; + PyTypeObject *keccak384_type; + PyTypeObject *keccak512_type; +#endif +} SHA3State; + +static inline SHA3State* +sha3_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (SHA3State *)state; +} /*[clinic input] module _sha3 @@ -142,19 +164,6 @@ typedef struct { PyThread_type_lock lock; } SHA3object; -static PyTypeObject SHA3_224type; -static PyTypeObject SHA3_256type; -static PyTypeObject SHA3_384type; -static PyTypeObject SHA3_512type; -#ifdef PY_WITH_KECCAK -static PyTypeObject Keccak_224type; -static PyTypeObject Keccak_256type; -static PyTypeObject Keccak_384type; -static PyTypeObject Keccak_512type; -#endif -static PyTypeObject SHAKE128type; -static PyTypeObject SHAKE256type; - #include "clinic/sha3module.c.h" static SHA3object * @@ -184,42 +193,43 @@ static PyObject * py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity) /*[clinic end generated code: output=90409addc5d5e8b0 input=bcfcdf2e4368347a]*/ { - SHA3object *self = NULL; - Py_buffer buf = {NULL, NULL}; - HashReturn res; - - self = newSHA3object(type); + SHA3object *self = newSHA3object(type); if (self == NULL) { goto error; } - if (type == &SHA3_224type) { + SHA3State *state = PyType_GetModuleState(type); + assert(state != NULL); + + HashReturn res; + if (type == state->sha3_224_type) { res = Keccak_HashInitialize_SHA3_224(&self->hash_state); - } else if (type == &SHA3_256type) { + } else if (type == state->sha3_256_type) { res = Keccak_HashInitialize_SHA3_256(&self->hash_state); - } else if (type == &SHA3_384type) { + } else if (type == state->sha3_384_type) { res = Keccak_HashInitialize_SHA3_384(&self->hash_state); - } else if (type == &SHA3_512type) { + } else if (type == state->sha3_512_type) { res = Keccak_HashInitialize_SHA3_512(&self->hash_state); #ifdef PY_WITH_KECCAK - } else if (type == &Keccak_224type) { + } else if (type == state->keccak224_type) { res = Keccak_HashInitialize(&self->hash_state, 1152, 448, 224, 0x01); - } else if (type == &Keccak_256type) { + } else if (type == state->keccak256_type) { res = Keccak_HashInitialize(&self->hash_state, 1088, 512, 256, 0x01); - } else if (type == &Keccak_384type) { + } else if (type == state->keccak384_type) { res = Keccak_HashInitialize(&self->hash_state, 832, 768, 384, 0x01); - } else if (type == &Keccak_512type) { + } else if (type == state->keccak512_type) { res = Keccak_HashInitialize(&self->hash_state, 576, 1024, 512, 0x01); #endif - } else if (type == &SHAKE128type) { + } else if (type == state->shake128_type) { res = Keccak_HashInitialize_SHAKE128(&self->hash_state); - } else if (type == &SHAKE256type) { + } else if (type == state->shake256_type) { res = Keccak_HashInitialize_SHAKE256(&self->hash_state); } else { PyErr_BadInternalCall(); goto error; } + Py_buffer buf = {NULL, NULL}; if (data) { GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); if (buf.len >= HASHLIB_GIL_MINSIZE) { @@ -416,27 +426,33 @@ static PyObject * SHA3_get_name(SHA3object *self, void *closure) { PyTypeObject *type = Py_TYPE(self); - if (type == &SHA3_224type) { + + SHA3State *state = PyType_GetModuleState(type); + assert(state != NULL); + + //Should I use Py_IS_TYPE instead of == here? + + if (type == state->sha3_224_type) { return PyUnicode_FromString("sha3_224"); - } else if (type == &SHA3_256type) { + } else if (type == state->sha3_256_type) { return PyUnicode_FromString("sha3_256"); - } else if (type == &SHA3_384type) { + } else if (type == state->sha3_384_type) { return PyUnicode_FromString("sha3_384"); - } else if (type == &SHA3_512type) { + } else if (type == state->sha3_512_type) { return PyUnicode_FromString("sha3_512"); #ifdef PY_WITH_KECCAK - } else if (type == &Keccak_224type) { + } else if (type == state->keccak224_type) { return PyUnicode_FromString("keccak_224"); - } else if (type == &Keccak_256type) { + } else if (type == state->keccak256_type) { return PyUnicode_FromString("keccak_256"); - } else if (type == &Keccak_384type) { + } else if (type == state->keccak384_type) { return PyUnicode_FromString("keccak_384"); - } else if (type == &Keccak_512type) { + } else if (type == state->keccak512_type) { return PyUnicode_FromString("keccak_512"); #endif - } else if (type == &SHAKE128type) { + } else if (type == state->shake128_type) { return PyUnicode_FromString("shake_128"); - } else if (type == &SHAKE256type) { + } else if (type == state->shake256_type) { return PyUnicode_FromString("shake_256"); } else { PyErr_BadInternalCall(); @@ -476,7 +492,6 @@ SHA3_get_suffix(SHA3object *self, void *closure) return PyBytes_FromStringAndSize((const char *)suffix, 1); } - static PyGetSetDef SHA3_getseters[] = { {"block_size", (getter)SHA3_get_block_size, NULL, NULL, NULL}, {"name", (getter)SHA3_get_name, NULL, NULL, NULL}, @@ -487,48 +502,22 @@ static PyGetSetDef SHA3_getseters[] = { {NULL} /* Sentinel */ }; +#define SHA3_TYPE_SLOTS(type_slots_obj, type_doc, type_methods) \ + static PyType_Slot type_slots_obj[] = { \ + {Py_tp_dealloc, SHA3_dealloc}, \ + {Py_tp_doc, (char*)type_doc}, \ + {Py_tp_methods, type_methods}, \ + {Py_tp_getset, SHA3_getseters}, \ + {Py_tp_new, py_sha3_new}, \ + {0,0} \ + } -#define SHA3_TYPE(type_obj, type_name, type_doc, type_methods) \ - static PyTypeObject type_obj = { \ - PyVarObject_HEAD_INIT(NULL, 0) \ - type_name, /* tp_name */ \ - sizeof(SHA3object), /* tp_basicsize */ \ - 0, /* tp_itemsize */ \ - /* methods */ \ - (destructor)SHA3_dealloc, /* tp_dealloc */ \ - 0, /* tp_vectorcall_offset */ \ - 0, /* tp_getattr */ \ - 0, /* tp_setattr */ \ - 0, /* tp_as_async */ \ - 0, /* tp_repr */ \ - 0, /* tp_as_number */ \ - 0, /* tp_as_sequence */ \ - 0, /* tp_as_mapping */ \ - 0, /* tp_hash */ \ - 0, /* tp_call */ \ - 0, /* tp_str */ \ - 0, /* tp_getattro */ \ - 0, /* tp_setattro */ \ - 0, /* tp_as_buffer */ \ - Py_TPFLAGS_DEFAULT, /* tp_flags */ \ - type_doc, /* tp_doc */ \ - 0, /* tp_traverse */ \ - 0, /* tp_clear */ \ - 0, /* tp_richcompare */ \ - 0, /* tp_weaklistoffset */ \ - 0, /* tp_iter */ \ - 0, /* tp_iternext */ \ - type_methods, /* tp_methods */ \ - NULL, /* tp_members */ \ - SHA3_getseters, /* tp_getset */ \ - 0, /* tp_base */ \ - 0, /* tp_dict */ \ - 0, /* tp_descr_get */ \ - 0, /* tp_descr_set */ \ - 0, /* tp_dictoffset */ \ - 0, /* tp_init */ \ - 0, /* tp_alloc */ \ - py_sha3_new, /* tp_new */ \ +#define SHA3_TYPE_SPEC(type_spec_obj, type_name, type_slots) \ + static PyType_Spec type_spec_obj = { \ + .name = type_name, \ + .basicsize = sizeof(SHA3object), \ + .flags = Py_TPFLAGS_DEFAULT, \ + .slots = type_slots \ } PyDoc_STRVAR(sha3_224__doc__, @@ -551,11 +540,6 @@ PyDoc_STRVAR(sha3_512__doc__, \n\ Return a new SHA3 hash object with a hashbit length of 64 bytes."); -SHA3_TYPE(SHA3_224type, "_sha3.sha3_224", sha3_224__doc__, SHA3_methods); -SHA3_TYPE(SHA3_256type, "_sha3.sha3_256", sha3_256__doc__, SHA3_methods); -SHA3_TYPE(SHA3_384type, "_sha3.sha3_384", sha3_384__doc__, SHA3_methods); -SHA3_TYPE(SHA3_512type, "_sha3.sha3_512", sha3_512__doc__, SHA3_methods); - #ifdef PY_WITH_KECCAK PyDoc_STRVAR(keccak_224__doc__, "keccak_224([data], *, usedforsecurity=True) -> Keccak object\n\ @@ -577,10 +561,32 @@ PyDoc_STRVAR(keccak_512__doc__, \n\ Return a new Keccak hash object with a hashbit length of 64 bytes."); -SHA3_TYPE(Keccak_224type, "_sha3.keccak_224", keccak_224__doc__, SHA3_methods); -SHA3_TYPE(Keccak_256type, "_sha3.keccak_256", keccak_256__doc__, SHA3_methods); -SHA3_TYPE(Keccak_384type, "_sha3.keccak_384", keccak_384__doc__, SHA3_methods); -SHA3_TYPE(Keccak_512type, "_sha3.keccak_512", keccak_512__doc__, SHA3_methods); +#endif + +SHA3_TYPE_SLOTS(SHA3_224slots, sha3_224__doc__, SHA3_methods); +SHA3_TYPE_SPEC(SHA3_224typespec, "_sha3.sha3_224", SHA3_224slots); + +SHA3_TYPE_SLOTS(SHA3_256slots, sha3_256__doc__, SHA3_methods); +SHA3_TYPE_SPEC(SHA3_256typespec, "_sha3.sha3_256", SHA3_256slots); + +SHA3_TYPE_SLOTS(SHA3_384slots, sha3_384__doc__, SHA3_methods); +SHA3_TYPE_SPEC(SHA3_384typespec, "_sha3.sha3_384", SHA3_384slots); + +SHA3_TYPE_SLOTS(SHA3_512slots, sha3_512__doc__, SHA3_methods); +SHA3_TYPE_SPEC(SHA3_512typespec, "_sha3.sha3_512", SHA3_512slots); + +#ifdef PY_WITH_KECCAK +SHA3_TYPE_SLOTS(Keccak_224slots, keccak_224__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_224typespec, "_sha3.keccak_224", Keccak_224slots); + +SHA3_TYPE_SLOTS(Keccak_256slots, keccak_256__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_256typespec, "_sha3.keccak_256", Keccak_256slots); + +SHA3_TYPE_SLOTS(Keccak_384slots, keccak_384__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_384typespec, "_sha3.keccak_384", Keccak_384slots); + +SHA3_TYPE_SLOTS(Keccak_512slots, keccak_512__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_512typespec, "_sha3.keccak_512", Keccak_512slots); #endif @@ -684,58 +690,40 @@ PyDoc_STRVAR(shake_256__doc__, \n\ Return a new SHAKE hash object."); -SHA3_TYPE(SHAKE128type, "_sha3.shake_128", shake_128__doc__, SHAKE_methods); -SHA3_TYPE(SHAKE256type, "_sha3.shake_256", shake_256__doc__, SHAKE_methods); +SHA3_TYPE_SLOTS(SHAKE128slots, shake_128__doc__, SHAKE_methods); +SHA3_TYPE_SPEC(SHAKE128typespec, "_sha3.shake_128", SHAKE128slots); - -/* Initialize this module. */ -static struct PyModuleDef _SHA3module = { - PyModuleDef_HEAD_INIT, - "_sha3", - NULL, - -1, - NULL, - NULL, - NULL, - NULL, - NULL -}; +SHA3_TYPE_SLOTS(SHAKE256slots, shake_256__doc__, SHAKE_methods); +SHA3_TYPE_SPEC(SHAKE256typespec, "_sha3.shake_256", SHAKE256slots); -PyMODINIT_FUNC -PyInit__sha3(void) -{ - PyObject *m = NULL; +static int sha3_exec(PyObject *m) { + SHA3State *st = sha3_get_state(m); - if ((m = PyModule_Create(&_SHA3module)) == NULL) { - return NULL; - } - -#define init_sha3type(name, type) \ - do { \ - Py_SET_TYPE(type, &PyType_Type); \ - if (PyType_Ready(type) < 0) { \ - goto error; \ - } \ - Py_INCREF((PyObject *)type); \ - if (PyModule_AddObject(m, name, (PyObject *)type) < 0) { \ - goto error; \ - } \ +#define init_sha3type(name, type, typespec) \ + do { \ + st->type = (PyTypeObject *)PyType_FromModuleAndSpec( \ + m, &typespec, NULL); \ + if (st->type == NULL) { \ + return -1; \ + } \ + if (PyModule_AddType(m, st->type) < 0) { \ + return -1; \ + } \ } while(0) - init_sha3type("sha3_224", &SHA3_224type); - init_sha3type("sha3_256", &SHA3_256type); - init_sha3type("sha3_384", &SHA3_384type); - init_sha3type("sha3_512", &SHA3_512type); + init_sha3type("sha3_224", sha3_224_type, SHA3_224typespec); + init_sha3type("sha3_256", sha3_256_type, SHA3_256typespec); + init_sha3type("sha3_384", sha3_384_type, SHA3_384typespec); + init_sha3type("sha3_512", sha3_512_type, SHA3_512typespec); #ifdef PY_WITH_KECCAK - init_sha3type("keccak_224", &Keccak_224type); - init_sha3type("keccak_256", &Keccak_256type); - init_sha3type("keccak_384", &Keccak_384type); - init_sha3type("keccak_512", &Keccak_512type); + init_sha3type("keccak_224", keccak224_type, Keccak_224typespec); + init_sha3type("keccak_256", keccak256_type, Keccak_256typespec); + init_sha3type("keccak_384", keccak384_type, Keccak_384typespec); + init_sha3type("keccak_512", keccak512_type, Keccak_512typespec); #endif - init_sha3type("shake_128", &SHAKE128type); - init_sha3type("shake_256", &SHAKE256type); - + init_sha3type("shake_128", shake128_type, SHAKE128typespec); + init_sha3type("shake_256", shake256_type, SHAKE256typespec); #undef init_sha3type if (PyModule_AddIntConstant(m, "keccakopt", KeccakOpt) < 0) { @@ -746,8 +734,26 @@ PyInit__sha3(void) goto error; } - return m; + return 0; error: - Py_DECREF(m); - return NULL; + return -1; } + +static PyModuleDef_Slot _sha3_slots[] = { + {Py_mod_exec, sha3_exec}, + {0, NULL} +}; + +/* Initialize this module. */ +static struct PyModuleDef _sha3module = { + PyModuleDef_HEAD_INIT, + .m_name = "_sha3", + .m_size = sizeof(SHA3State), + .m_slots = _sha3_slots +}; + + +PyMODINIT_FUNC +PyInit__sha3(void) { + return PyModuleDef_Init(&_sha3module); +} \ No newline at end of file From 1361dfdaa8d8a74a268197dc44bc43f9cdbc8d64 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Thu, 13 Aug 2020 07:19:26 -0500 Subject: [PATCH 02/10] blurb --- .../Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst new file mode 100644 index 00000000000000..30d5c733126922 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst @@ -0,0 +1 @@ +Port :mod:`sha3` to multi-phase init From f91e1ae3ae329db1f6c3dd128be6ca13ee920721 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Fri, 21 Aug 2020 18:53:21 -0500 Subject: [PATCH 03/10] add comment --- Modules/_sha3/sha3module.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index 96ef5f389d2758..f7dbd9ab50c24a 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -512,6 +512,8 @@ static PyGetSetDef SHA3_getseters[] = { {0,0} \ } +// Using PyType_GetModuleState() on these types is safe since +// it cannot be subclassed: it does not have the Py_TPFLAGS_BASETYPE flag. #define SHA3_TYPE_SPEC(type_spec_obj, type_name, type_slots) \ static PyType_Spec type_spec_obj = { \ .name = type_name, \ From 050d597d859afaec6bc1f27760421eb29e5cbc4f Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Tue, 25 Aug 2020 20:46:13 -0500 Subject: [PATCH 04/10] update based on feedback --- ...2020-08-13-07-19-21.bpo-1653741.fubBkb.rst | 2 +- Modules/_sha3/sha3module.c | 83 +++++++++---------- 2 files changed, 42 insertions(+), 43 deletions(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst index 30d5c733126922..e5afa9a9c0d533 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst @@ -1 +1 @@ -Port :mod:`sha3` to multi-phase init +Port :mod:`sha3` to multi-phase init. Convert static types to heap types. diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index f7dbd9ab50c24a..756cad34fda987 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -127,13 +127,13 @@ typedef struct { PyTypeObject *sha3_256_type; PyTypeObject *sha3_384_type; PyTypeObject *sha3_512_type; - PyTypeObject *shake128_type; - PyTypeObject *shake256_type; + PyTypeObject *shake_128_type; + PyTypeObject *shake_256_type; #ifdef PY_WITH_KECCAK - PyTypeObject *keccak224_type; - PyTypeObject *keccak256_type; - PyTypeObject *keccak384_type; - PyTypeObject *keccak512_type; + PyTypeObject *keccak_224_type; + PyTypeObject *keccak_256_type; + PyTypeObject *keccak_384_type; + PyTypeObject *keccak_512_type; #endif } SHA3State; @@ -211,18 +211,18 @@ py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity) } else if (type == state->sha3_512_type) { res = Keccak_HashInitialize_SHA3_512(&self->hash_state); #ifdef PY_WITH_KECCAK - } else if (type == state->keccak224_type) { + } else if (type == state->keccak_224_type) { res = Keccak_HashInitialize(&self->hash_state, 1152, 448, 224, 0x01); - } else if (type == state->keccak256_type) { + } else if (type == state->keccak_256_type) { res = Keccak_HashInitialize(&self->hash_state, 1088, 512, 256, 0x01); - } else if (type == state->keccak384_type) { + } else if (type == state->keccak_384_type) { res = Keccak_HashInitialize(&self->hash_state, 832, 768, 384, 0x01); - } else if (type == state->keccak512_type) { + } else if (type == state->keccak_512_type) { res = Keccak_HashInitialize(&self->hash_state, 576, 1024, 512, 0x01); #endif - } else if (type == state->shake128_type) { + } else if (type == state->shake_128_type) { res = Keccak_HashInitialize_SHAKE128(&self->hash_state); - } else if (type == state->shake256_type) { + } else if (type == state->shake_256_type) { res = Keccak_HashInitialize_SHAKE256(&self->hash_state); } else { PyErr_BadInternalCall(); @@ -430,8 +430,6 @@ SHA3_get_name(SHA3object *self, void *closure) SHA3State *state = PyType_GetModuleState(type); assert(state != NULL); - //Should I use Py_IS_TYPE instead of == here? - if (type == state->sha3_224_type) { return PyUnicode_FromString("sha3_224"); } else if (type == state->sha3_256_type) { @@ -441,18 +439,18 @@ SHA3_get_name(SHA3object *self, void *closure) } else if (type == state->sha3_512_type) { return PyUnicode_FromString("sha3_512"); #ifdef PY_WITH_KECCAK - } else if (type == state->keccak224_type) { + } else if (type == state->keccak_224_type) { return PyUnicode_FromString("keccak_224"); - } else if (type == state->keccak256_type) { + } else if (type == state->keccak_256_type) { return PyUnicode_FromString("keccak_256"); - } else if (type == state->keccak384_type) { + } else if (type == state->keccak_384_type) { return PyUnicode_FromString("keccak_384"); - } else if (type == state->keccak512_type) { + } else if (type == state->keccak_512_type) { return PyUnicode_FromString("keccak_512"); #endif - } else if (type == state->shake128_type) { + } else if (type == state->shake_128_type) { return PyUnicode_FromString("shake_128"); - } else if (type == state->shake256_type) { + } else if (type == state->shake_256_type) { return PyUnicode_FromString("shake_256"); } else { PyErr_BadInternalCall(); @@ -512,8 +510,8 @@ static PyGetSetDef SHA3_getseters[] = { {0,0} \ } -// Using PyType_GetModuleState() on these types is safe since -// it cannot be subclassed: it does not have the Py_TPFLAGS_BASETYPE flag. +// Using PyType_GetModuleState() on these types is safe since they +// cannot be subclassed: it does not have the Py_TPFLAGS_BASETYPE flag. #define SHA3_TYPE_SPEC(type_spec_obj, type_name, type_slots) \ static PyType_Spec type_spec_obj = { \ .name = type_name, \ @@ -565,17 +563,17 @@ Return a new Keccak hash object with a hashbit length of 64 bytes."); #endif -SHA3_TYPE_SLOTS(SHA3_224slots, sha3_224__doc__, SHA3_methods); -SHA3_TYPE_SPEC(SHA3_224typespec, "_sha3.sha3_224", SHA3_224slots); +SHA3_TYPE_SLOTS(sha3_224slots, sha3_224__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_224typespec, "_sha3.sha3_224", sha3_224slots); -SHA3_TYPE_SLOTS(SHA3_256slots, sha3_256__doc__, SHA3_methods); -SHA3_TYPE_SPEC(SHA3_256typespec, "_sha3.sha3_256", SHA3_256slots); +SHA3_TYPE_SLOTS(sha3_256slots, sha3_256__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_256typespec, "_sha3.sha3_256", sha3_256slots); -SHA3_TYPE_SLOTS(SHA3_384slots, sha3_384__doc__, SHA3_methods); -SHA3_TYPE_SPEC(SHA3_384typespec, "_sha3.sha3_384", SHA3_384slots); +SHA3_TYPE_SLOTS(sha3_384slots, sha3_384__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_384typespec, "_sha3.sha3_384", sha3_384slots); -SHA3_TYPE_SLOTS(SHA3_512slots, sha3_512__doc__, SHA3_methods); -SHA3_TYPE_SPEC(SHA3_512typespec, "_sha3.sha3_512", SHA3_512slots); +SHA3_TYPE_SLOTS(sha3_512slots, sha3_512__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_512typespec, "_sha3.sha3_512", sha3_512slots); #ifdef PY_WITH_KECCAK SHA3_TYPE_SLOTS(Keccak_224slots, keccak_224__doc__, SHA3_methods); @@ -699,10 +697,11 @@ SHA3_TYPE_SLOTS(SHAKE256slots, shake_256__doc__, SHAKE_methods); SHA3_TYPE_SPEC(SHAKE256typespec, "_sha3.shake_256", SHAKE256slots); -static int sha3_exec(PyObject *m) { +static int +sha3_exec(PyObject *m) { SHA3State *st = sha3_get_state(m); -#define init_sha3type(name, type, typespec) \ +#define init_sha3type(type, typespec) \ do { \ st->type = (PyTypeObject *)PyType_FromModuleAndSpec( \ m, &typespec, NULL); \ @@ -714,18 +713,18 @@ static int sha3_exec(PyObject *m) { } \ } while(0) - init_sha3type("sha3_224", sha3_224_type, SHA3_224typespec); - init_sha3type("sha3_256", sha3_256_type, SHA3_256typespec); - init_sha3type("sha3_384", sha3_384_type, SHA3_384typespec); - init_sha3type("sha3_512", sha3_512_type, SHA3_512typespec); + init_sha3type(sha3_224_type, sha3_224typespec); + init_sha3type(sha3_256_type, sha3_256typespec); + init_sha3type(sha3_384_type, sha3_384typespec); + init_sha3type(sha3_512_type, sha3_512typespec); #ifdef PY_WITH_KECCAK - init_sha3type("keccak_224", keccak224_type, Keccak_224typespec); - init_sha3type("keccak_256", keccak256_type, Keccak_256typespec); - init_sha3type("keccak_384", keccak384_type, Keccak_384typespec); - init_sha3type("keccak_512", keccak512_type, Keccak_512typespec); + init_sha3type(keccak_224_type, Keccak_224typespec); + init_sha3type(keccak_256_type, Keccak_256typespec); + init_sha3type(keccak_384_type, Keccak_384typespec); + init_sha3type(keccak_512_type, Keccak_512typespec); #endif - init_sha3type("shake_128", shake128_type, SHAKE128typespec); - init_sha3type("shake_256", shake256_type, SHAKE256typespec); + init_sha3type(shake_128_type, SHAKE128typespec); + init_sha3type(shake_256_type, SHAKE256typespec); #undef init_sha3type if (PyModule_AddIntConstant(m, "keccakopt", KeccakOpt) < 0) { From 338958d1ce17f54e30bcdc2fd07d5140a0c9ee64 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Tue, 25 Aug 2020 20:48:51 -0500 Subject: [PATCH 05/10] update names --- Modules/_sha3/sha3module.c | 56 +++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index 756cad34fda987..4373f9f23117e2 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -563,30 +563,30 @@ Return a new Keccak hash object with a hashbit length of 64 bytes."); #endif -SHA3_TYPE_SLOTS(sha3_224slots, sha3_224__doc__, SHA3_methods); -SHA3_TYPE_SPEC(sha3_224typespec, "_sha3.sha3_224", sha3_224slots); +SHA3_TYPE_SLOTS(sha3_224_slots, sha3_224__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_224_spec, "_sha3.sha3_224", sha3_224_slots); -SHA3_TYPE_SLOTS(sha3_256slots, sha3_256__doc__, SHA3_methods); -SHA3_TYPE_SPEC(sha3_256typespec, "_sha3.sha3_256", sha3_256slots); +SHA3_TYPE_SLOTS(sha3_256_slots, sha3_256__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_256_spec, "_sha3.sha3_256", sha3_256_slots); -SHA3_TYPE_SLOTS(sha3_384slots, sha3_384__doc__, SHA3_methods); -SHA3_TYPE_SPEC(sha3_384typespec, "_sha3.sha3_384", sha3_384slots); +SHA3_TYPE_SLOTS(sha3_384_slots, sha3_384__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_384_spec, "_sha3.sha3_384", sha3_384_slots); -SHA3_TYPE_SLOTS(sha3_512slots, sha3_512__doc__, SHA3_methods); -SHA3_TYPE_SPEC(sha3_512typespec, "_sha3.sha3_512", sha3_512slots); +SHA3_TYPE_SLOTS(sha3_512_slots, sha3_512__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_512_spec, "_sha3.sha3_512", sha3_512_slots); #ifdef PY_WITH_KECCAK -SHA3_TYPE_SLOTS(Keccak_224slots, keccak_224__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_224typespec, "_sha3.keccak_224", Keccak_224slots); +SHA3_TYPE_SLOTS(Keccak_224_slots, keccak_224__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_224_spec, "_sha3.keccak_224", Keccak_224_slots); -SHA3_TYPE_SLOTS(Keccak_256slots, keccak_256__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_256typespec, "_sha3.keccak_256", Keccak_256slots); +SHA3_TYPE_SLOTS(Keccak_256_slots, keccak_256__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_256_spec, "_sha3.keccak_256", Keccak_256_slots); -SHA3_TYPE_SLOTS(Keccak_384slots, keccak_384__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_384typespec, "_sha3.keccak_384", Keccak_384slots); +SHA3_TYPE_SLOTS(Keccak_384_slots, keccak_384__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_384_spec, "_sha3.keccak_384", Keccak_384_slots); -SHA3_TYPE_SLOTS(Keccak_512slots, keccak_512__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_512typespec, "_sha3.keccak_512", Keccak_512slots); +SHA3_TYPE_SLOTS(Keccak_512_slots, keccak_512__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_512_spec, "_sha3.keccak_512", Keccak_512_slots); #endif @@ -691,10 +691,10 @@ PyDoc_STRVAR(shake_256__doc__, Return a new SHAKE hash object."); SHA3_TYPE_SLOTS(SHAKE128slots, shake_128__doc__, SHAKE_methods); -SHA3_TYPE_SPEC(SHAKE128typespec, "_sha3.shake_128", SHAKE128slots); +SHA3_TYPE_SPEC(SHAKE128_spec, "_sha3.shake_128", SHAKE128slots); SHA3_TYPE_SLOTS(SHAKE256slots, shake_256__doc__, SHAKE_methods); -SHA3_TYPE_SPEC(SHAKE256typespec, "_sha3.shake_256", SHAKE256slots); +SHA3_TYPE_SPEC(SHAKE256_spec, "_sha3.shake_256", SHAKE256slots); static int @@ -713,18 +713,18 @@ sha3_exec(PyObject *m) { } \ } while(0) - init_sha3type(sha3_224_type, sha3_224typespec); - init_sha3type(sha3_256_type, sha3_256typespec); - init_sha3type(sha3_384_type, sha3_384typespec); - init_sha3type(sha3_512_type, sha3_512typespec); + init_sha3type(sha3_224_type, sha3_224_spec); + init_sha3type(sha3_256_type, sha3_256_spec); + init_sha3type(sha3_384_type, sha3_384_spec); + init_sha3type(sha3_512_type, sha3_512_spec); #ifdef PY_WITH_KECCAK - init_sha3type(keccak_224_type, Keccak_224typespec); - init_sha3type(keccak_256_type, Keccak_256typespec); - init_sha3type(keccak_384_type, Keccak_384typespec); - init_sha3type(keccak_512_type, Keccak_512typespec); + init_sha3type(keccak_224_type, Keccak_224_spec); + init_sha3type(keccak_256_type, Keccak_256_spec); + init_sha3type(keccak_384_type, Keccak_384_spec); + init_sha3type(keccak_512_type, Keccak_512_spec); #endif - init_sha3type(shake_128_type, SHAKE128typespec); - init_sha3type(shake_256_type, SHAKE256typespec); + init_sha3type(shake_128_type, SHAKE128_spec); + init_sha3type(shake_256_type, SHAKE256_spec); #undef init_sha3type if (PyModule_AddIntConstant(m, "keccakopt", KeccakOpt) < 0) { From 227c6c0613607e042783bf0681ae47c73ad04e78 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Wed, 26 Aug 2020 20:27:43 -0500 Subject: [PATCH 06/10] misc changes based on PR review --- Modules/_sha3/sha3module.c | 69 ++++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index 4373f9f23117e2..4c642a18b6f35e 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -273,6 +273,8 @@ SHA3_dealloc(SHA3object *self) PyThread_free_lock(self->lock); } PyObject_Del(self); + + Py_DECREF(Py_TYPE(self)); } @@ -698,7 +700,52 @@ SHA3_TYPE_SPEC(SHAKE256_spec, "_sha3.shake_256", SHAKE256slots); static int -sha3_exec(PyObject *m) { +_sha3_traverse(PyObject *module, visitproc visit, void *arg) +{ + SHA3State *state = sha3_get_state(module); + Py_VISIT(state->sha3_224_type); + Py_VISIT(state->sha3_256_type); + Py_VISIT(state->sha3_384_type); + Py_VISIT(state->sha3_512_type); +#ifdef PY_WITH_KECCAK + Py_VISIT(state->keccak_224_type); + Py_VISIT(state->keccak_256_type); + Py_VISIT(state->keccak_384_type); + Py_VISIT(state->keccak_512_type); +#endif + Py_VISIT(state->shake_128_type); + Py_VISIT(state->shake_256_type); + return 0; +} + +static int +_sha3_clear(PyObject *module) +{ + SHA3State *state = sha3_get_state(module); + Py_CLEAR(state->sha3_224_type); + Py_CLEAR(state->sha3_256_type); + Py_CLEAR(state->sha3_384_type); + Py_CLEAR(state->sha3_512_type); +#ifdef PY_WITH_KECCAK + Py_CLEAR(state->keccak_224_type); + Py_CLEAR(state->keccak_256_type); + Py_CLEAR(state->keccak_384_type); + Py_CLEAR(state->keccak_512_type); +#endif + Py_CLEAR(state->shake_128_type); + Py_CLEAR(state->shake_256_type); + return 0; +} + +static void +_sha3_free(void *module) +{ + _sha3_clear((PyObject *)module); +} + +static int +sha3_exec(PyObject *m) +{ SHA3State *st = sha3_get_state(m); #define init_sha3type(type, typespec) \ @@ -728,16 +775,14 @@ sha3_exec(PyObject *m) { #undef init_sha3type if (PyModule_AddIntConstant(m, "keccakopt", KeccakOpt) < 0) { - goto error; + return -1; } if (PyModule_AddStringConstant(m, "implementation", KeccakP1600_implementation) < 0) { - goto error; + return -1; } return 0; - error: - return -1; } static PyModuleDef_Slot _sha3_slots[] = { @@ -747,14 +792,18 @@ static PyModuleDef_Slot _sha3_slots[] = { /* Initialize this module. */ static struct PyModuleDef _sha3module = { - PyModuleDef_HEAD_INIT, - .m_name = "_sha3", - .m_size = sizeof(SHA3State), - .m_slots = _sha3_slots + PyModuleDef_HEAD_INIT, + .m_name = "_sha3", + .m_size = sizeof(SHA3State), + .m_slots = _sha3_slots, + .m_traverse = _sha3_traverse, + .m_clear = _sha3_clear, + .m_free = _sha3_free, }; PyMODINIT_FUNC -PyInit__sha3(void) { +PyInit__sha3(void) +{ return PyModuleDef_Init(&_sha3module); } \ No newline at end of file From 027bfe690579e0793d4948c16ccb15fef03c258d Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Thu, 27 Aug 2020 18:17:43 -0500 Subject: [PATCH 07/10] update based on PR --- Modules/_sha3/sha3module.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index 4c642a18b6f35e..dac69c96a108b3 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -127,14 +127,14 @@ typedef struct { PyTypeObject *sha3_256_type; PyTypeObject *sha3_384_type; PyTypeObject *sha3_512_type; - PyTypeObject *shake_128_type; - PyTypeObject *shake_256_type; #ifdef PY_WITH_KECCAK PyTypeObject *keccak_224_type; PyTypeObject *keccak_256_type; PyTypeObject *keccak_384_type; PyTypeObject *keccak_512_type; #endif + PyTypeObject *shake_128_type; + PyTypeObject *shake_256_type; } SHA3State; static inline SHA3State* @@ -272,9 +272,8 @@ SHA3_dealloc(SHA3object *self) if (self->lock) { PyThread_free_lock(self->lock); } - PyObject_Del(self); - Py_DECREF(Py_TYPE(self)); + PyObject_Del(self); } @@ -516,7 +515,7 @@ static PyGetSetDef SHA3_getseters[] = { // cannot be subclassed: it does not have the Py_TPFLAGS_BASETYPE flag. #define SHA3_TYPE_SPEC(type_spec_obj, type_name, type_slots) \ static PyType_Spec type_spec_obj = { \ - .name = type_name, \ + .name = "_sha3." type_name, \ .basicsize = sizeof(SHA3object), \ .flags = Py_TPFLAGS_DEFAULT, \ .slots = type_slots \ @@ -566,29 +565,29 @@ Return a new Keccak hash object with a hashbit length of 64 bytes."); #endif SHA3_TYPE_SLOTS(sha3_224_slots, sha3_224__doc__, SHA3_methods); -SHA3_TYPE_SPEC(sha3_224_spec, "_sha3.sha3_224", sha3_224_slots); +SHA3_TYPE_SPEC(sha3_224_spec, "sha3_224", sha3_224_slots); SHA3_TYPE_SLOTS(sha3_256_slots, sha3_256__doc__, SHA3_methods); -SHA3_TYPE_SPEC(sha3_256_spec, "_sha3.sha3_256", sha3_256_slots); +SHA3_TYPE_SPEC(sha3_256_spec, "sha3_256", sha3_256_slots); SHA3_TYPE_SLOTS(sha3_384_slots, sha3_384__doc__, SHA3_methods); -SHA3_TYPE_SPEC(sha3_384_spec, "_sha3.sha3_384", sha3_384_slots); +SHA3_TYPE_SPEC(sha3_384_spec, "sha3_384", sha3_384_slots); SHA3_TYPE_SLOTS(sha3_512_slots, sha3_512__doc__, SHA3_methods); -SHA3_TYPE_SPEC(sha3_512_spec, "_sha3.sha3_512", sha3_512_slots); +SHA3_TYPE_SPEC(sha3_512_spec, "sha3_512", sha3_512_slots); #ifdef PY_WITH_KECCAK SHA3_TYPE_SLOTS(Keccak_224_slots, keccak_224__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_224_spec, "_sha3.keccak_224", Keccak_224_slots); +SHA3_TYPE_SPEC(Keccak_224_spec, "keccak_224", Keccak_224_slots); SHA3_TYPE_SLOTS(Keccak_256_slots, keccak_256__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_256_spec, "_sha3.keccak_256", Keccak_256_slots); +SHA3_TYPE_SPEC(Keccak_256_spec, "keccak_256", Keccak_256_slots); SHA3_TYPE_SLOTS(Keccak_384_slots, keccak_384__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_384_spec, "_sha3.keccak_384", Keccak_384_slots); +SHA3_TYPE_SPEC(Keccak_384_spec, "keccak_384", Keccak_384_slots); SHA3_TYPE_SLOTS(Keccak_512_slots, keccak_512__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_512_spec, "_sha3.keccak_512", Keccak_512_slots); +SHA3_TYPE_SPEC(Keccak_512_spec, "keccak_512", Keccak_512_slots); #endif @@ -693,10 +692,10 @@ PyDoc_STRVAR(shake_256__doc__, Return a new SHAKE hash object."); SHA3_TYPE_SLOTS(SHAKE128slots, shake_128__doc__, SHAKE_methods); -SHA3_TYPE_SPEC(SHAKE128_spec, "_sha3.shake_128", SHAKE128slots); +SHA3_TYPE_SPEC(SHAKE128_spec, "shake_128", SHAKE128slots); SHA3_TYPE_SLOTS(SHAKE256slots, shake_256__doc__, SHAKE_methods); -SHA3_TYPE_SPEC(SHAKE256_spec, "_sha3.shake_256", SHAKE256slots); +SHA3_TYPE_SPEC(SHAKE256_spec, "shake_256", SHAKE256slots); static int @@ -744,7 +743,7 @@ _sha3_free(void *module) } static int -sha3_exec(PyObject *m) +_sha3_exec(PyObject *m) { SHA3State *st = sha3_get_state(m); @@ -786,7 +785,7 @@ sha3_exec(PyObject *m) } static PyModuleDef_Slot _sha3_slots[] = { - {Py_mod_exec, sha3_exec}, + {Py_mod_exec, _sha3_exec}, {0, NULL} }; From 2b047e8911638f1d63d1e1859b1f4ae1628720f0 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Fri, 28 Aug 2020 20:57:53 -0500 Subject: [PATCH 08/10] decref after del --- Modules/_sha3/sha3module.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index dac69c96a108b3..6739f10c6f9262 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -272,8 +272,10 @@ SHA3_dealloc(SHA3object *self) if (self->lock) { PyThread_free_lock(self->lock); } - Py_DECREF(Py_TYPE(self)); + + PyObject *tp = Py_TYPE(self); PyObject_Del(self); + Py_DECREF(tp); } From 054ebee539311571ef2f99e35eb7bf27fdea798a Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Sat, 29 Aug 2020 11:05:22 -0500 Subject: [PATCH 09/10] Update Modules/_sha3/sha3module.c Co-authored-by: Victor Stinner --- Modules/_sha3/sha3module.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index 6739f10c6f9262..da6dde6812f264 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -273,7 +273,7 @@ SHA3_dealloc(SHA3object *self) PyThread_free_lock(self->lock); } - PyObject *tp = Py_TYPE(self); + PyTypeObject *tp = Py_TYPE(self); PyObject_Del(self); Py_DECREF(tp); } @@ -807,4 +807,4 @@ PyMODINIT_FUNC PyInit__sha3(void) { return PyModuleDef_Init(&_sha3module); -} \ No newline at end of file +} From e1294af1dfa3b62bbb1d2e11ab2e07220a06d582 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Tue, 1 Sep 2020 16:56:39 -0500 Subject: [PATCH 10/10] fix typo --- .../2020-08-13-07-19-21.bpo-1653741.fubBkb.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst index e5afa9a9c0d533..73a4fdbac48a24 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst @@ -1 +1 @@ -Port :mod:`sha3` to multi-phase init. Convert static types to heap types. +Port :mod:`_sha3` to multi-phase init. Convert static types to heap types.