Skip to content

Commit 8a4b851

Browse files
committed
port sha3
1 parent 802726a commit 8a4b851

File tree

1 file changed

+142
-136
lines changed

1 file changed

+142
-136
lines changed

Modules/_sha3/sha3module.c

Lines changed: 142 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,28 @@
122122
#define SHA3_squeeze Keccak_HashSqueeze
123123
#define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state))
124124

125+
typedef struct {
126+
PyTypeObject *sha3_224_type;
127+
PyTypeObject *sha3_256_type;
128+
PyTypeObject *sha3_384_type;
129+
PyTypeObject *sha3_512_type;
130+
PyTypeObject *shake128_type;
131+
PyTypeObject *shake256_type;
132+
#ifdef PY_WITH_KECCAK
133+
PyTypeObject *keccak224_type;
134+
PyTypeObject *keccak256_type;
135+
PyTypeObject *keccak384_type;
136+
PyTypeObject *keccak512_type;
137+
#endif
138+
} SHA3State;
139+
140+
static inline SHA3State*
141+
sha3_get_state(PyObject *module)
142+
{
143+
void *state = PyModule_GetState(module);
144+
assert(state != NULL);
145+
return (SHA3State *)state;
146+
}
125147

126148
/*[clinic input]
127149
module _sha3
@@ -142,19 +164,6 @@ typedef struct {
142164
PyThread_type_lock lock;
143165
} SHA3object;
144166

145-
static PyTypeObject SHA3_224type;
146-
static PyTypeObject SHA3_256type;
147-
static PyTypeObject SHA3_384type;
148-
static PyTypeObject SHA3_512type;
149-
#ifdef PY_WITH_KECCAK
150-
static PyTypeObject Keccak_224type;
151-
static PyTypeObject Keccak_256type;
152-
static PyTypeObject Keccak_384type;
153-
static PyTypeObject Keccak_512type;
154-
#endif
155-
static PyTypeObject SHAKE128type;
156-
static PyTypeObject SHAKE256type;
157-
158167
#include "clinic/sha3module.c.h"
159168

160169
static SHA3object *
@@ -184,42 +193,43 @@ static PyObject *
184193
py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity)
185194
/*[clinic end generated code: output=90409addc5d5e8b0 input=bcfcdf2e4368347a]*/
186195
{
187-
SHA3object *self = NULL;
188-
Py_buffer buf = {NULL, NULL};
189-
HashReturn res;
190-
191-
self = newSHA3object(type);
196+
SHA3object *self = newSHA3object(type);
192197
if (self == NULL) {
193198
goto error;
194199
}
195200

196-
if (type == &SHA3_224type) {
201+
SHA3State *state = PyType_GetModuleState(type);
202+
assert(state != NULL);
203+
204+
HashReturn res;
205+
if (type == state->sha3_224_type) {
197206
res = Keccak_HashInitialize_SHA3_224(&self->hash_state);
198-
} else if (type == &SHA3_256type) {
207+
} else if (type == state->sha3_256_type) {
199208
res = Keccak_HashInitialize_SHA3_256(&self->hash_state);
200-
} else if (type == &SHA3_384type) {
209+
} else if (type == state->sha3_384_type) {
201210
res = Keccak_HashInitialize_SHA3_384(&self->hash_state);
202-
} else if (type == &SHA3_512type) {
211+
} else if (type == state->sha3_512_type) {
203212
res = Keccak_HashInitialize_SHA3_512(&self->hash_state);
204213
#ifdef PY_WITH_KECCAK
205-
} else if (type == &Keccak_224type) {
214+
} else if (type == state->keccak224_type) {
206215
res = Keccak_HashInitialize(&self->hash_state, 1152, 448, 224, 0x01);
207-
} else if (type == &Keccak_256type) {
216+
} else if (type == state->keccak256_type) {
208217
res = Keccak_HashInitialize(&self->hash_state, 1088, 512, 256, 0x01);
209-
} else if (type == &Keccak_384type) {
218+
} else if (type == state->keccak384_type) {
210219
res = Keccak_HashInitialize(&self->hash_state, 832, 768, 384, 0x01);
211-
} else if (type == &Keccak_512type) {
220+
} else if (type == state->keccak512_type) {
212221
res = Keccak_HashInitialize(&self->hash_state, 576, 1024, 512, 0x01);
213222
#endif
214-
} else if (type == &SHAKE128type) {
223+
} else if (type == state->shake128_type) {
215224
res = Keccak_HashInitialize_SHAKE128(&self->hash_state);
216-
} else if (type == &SHAKE256type) {
225+
} else if (type == state->shake256_type) {
217226
res = Keccak_HashInitialize_SHAKE256(&self->hash_state);
218227
} else {
219228
PyErr_BadInternalCall();
220229
goto error;
221230
}
222231

232+
Py_buffer buf = {NULL, NULL};
223233
if (data) {
224234
GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error);
225235
if (buf.len >= HASHLIB_GIL_MINSIZE) {
@@ -416,27 +426,33 @@ static PyObject *
416426
SHA3_get_name(SHA3object *self, void *closure)
417427
{
418428
PyTypeObject *type = Py_TYPE(self);
419-
if (type == &SHA3_224type) {
429+
430+
SHA3State *state = PyType_GetModuleState(type);
431+
assert(state != NULL);
432+
433+
//Should I use Py_IS_TYPE instead of == here?
434+
435+
if (type == state->sha3_224_type) {
420436
return PyUnicode_FromString("sha3_224");
421-
} else if (type == &SHA3_256type) {
437+
} else if (type == state->sha3_256_type) {
422438
return PyUnicode_FromString("sha3_256");
423-
} else if (type == &SHA3_384type) {
439+
} else if (type == state->sha3_384_type) {
424440
return PyUnicode_FromString("sha3_384");
425-
} else if (type == &SHA3_512type) {
441+
} else if (type == state->sha3_512_type) {
426442
return PyUnicode_FromString("sha3_512");
427443
#ifdef PY_WITH_KECCAK
428-
} else if (type == &Keccak_224type) {
444+
} else if (type == state->keccak224_type) {
429445
return PyUnicode_FromString("keccak_224");
430-
} else if (type == &Keccak_256type) {
446+
} else if (type == state->keccak256_type) {
431447
return PyUnicode_FromString("keccak_256");
432-
} else if (type == &Keccak_384type) {
448+
} else if (type == state->keccak384_type) {
433449
return PyUnicode_FromString("keccak_384");
434-
} else if (type == &Keccak_512type) {
450+
} else if (type == state->keccak512_type) {
435451
return PyUnicode_FromString("keccak_512");
436452
#endif
437-
} else if (type == &SHAKE128type) {
453+
} else if (type == state->shake128_type) {
438454
return PyUnicode_FromString("shake_128");
439-
} else if (type == &SHAKE256type) {
455+
} else if (type == state->shake256_type) {
440456
return PyUnicode_FromString("shake_256");
441457
} else {
442458
PyErr_BadInternalCall();
@@ -476,7 +492,6 @@ SHA3_get_suffix(SHA3object *self, void *closure)
476492
return PyBytes_FromStringAndSize((const char *)suffix, 1);
477493
}
478494

479-
480495
static PyGetSetDef SHA3_getseters[] = {
481496
{"block_size", (getter)SHA3_get_block_size, NULL, NULL, NULL},
482497
{"name", (getter)SHA3_get_name, NULL, NULL, NULL},
@@ -487,48 +502,22 @@ static PyGetSetDef SHA3_getseters[] = {
487502
{NULL} /* Sentinel */
488503
};
489504

505+
#define SHA3_TYPE_SLOTS(type_slots_obj, type_doc, type_methods) \
506+
static PyType_Slot type_slots_obj[] = { \
507+
{Py_tp_dealloc, SHA3_dealloc}, \
508+
{Py_tp_doc, (char*)type_doc}, \
509+
{Py_tp_methods, type_methods}, \
510+
{Py_tp_getset, SHA3_getseters}, \
511+
{Py_tp_new, py_sha3_new}, \
512+
{0,0} \
513+
}
490514

491-
#define SHA3_TYPE(type_obj, type_name, type_doc, type_methods) \
492-
static PyTypeObject type_obj = { \
493-
PyVarObject_HEAD_INIT(NULL, 0) \
494-
type_name, /* tp_name */ \
495-
sizeof(SHA3object), /* tp_basicsize */ \
496-
0, /* tp_itemsize */ \
497-
/* methods */ \
498-
(destructor)SHA3_dealloc, /* tp_dealloc */ \
499-
0, /* tp_vectorcall_offset */ \
500-
0, /* tp_getattr */ \
501-
0, /* tp_setattr */ \
502-
0, /* tp_as_async */ \
503-
0, /* tp_repr */ \
504-
0, /* tp_as_number */ \
505-
0, /* tp_as_sequence */ \
506-
0, /* tp_as_mapping */ \
507-
0, /* tp_hash */ \
508-
0, /* tp_call */ \
509-
0, /* tp_str */ \
510-
0, /* tp_getattro */ \
511-
0, /* tp_setattro */ \
512-
0, /* tp_as_buffer */ \
513-
Py_TPFLAGS_DEFAULT, /* tp_flags */ \
514-
type_doc, /* tp_doc */ \
515-
0, /* tp_traverse */ \
516-
0, /* tp_clear */ \
517-
0, /* tp_richcompare */ \
518-
0, /* tp_weaklistoffset */ \
519-
0, /* tp_iter */ \
520-
0, /* tp_iternext */ \
521-
type_methods, /* tp_methods */ \
522-
NULL, /* tp_members */ \
523-
SHA3_getseters, /* tp_getset */ \
524-
0, /* tp_base */ \
525-
0, /* tp_dict */ \
526-
0, /* tp_descr_get */ \
527-
0, /* tp_descr_set */ \
528-
0, /* tp_dictoffset */ \
529-
0, /* tp_init */ \
530-
0, /* tp_alloc */ \
531-
py_sha3_new, /* tp_new */ \
515+
#define SHA3_TYPE_SPEC(type_spec_obj, type_name, type_slots) \
516+
static PyType_Spec type_spec_obj = { \
517+
.name = type_name, \
518+
.basicsize = sizeof(SHA3object), \
519+
.flags = Py_TPFLAGS_DEFAULT, \
520+
.slots = type_slots \
532521
}
533522

534523
PyDoc_STRVAR(sha3_224__doc__,
@@ -551,11 +540,6 @@ PyDoc_STRVAR(sha3_512__doc__,
551540
\n\
552541
Return a new SHA3 hash object with a hashbit length of 64 bytes.");
553542

554-
SHA3_TYPE(SHA3_224type, "_sha3.sha3_224", sha3_224__doc__, SHA3_methods);
555-
SHA3_TYPE(SHA3_256type, "_sha3.sha3_256", sha3_256__doc__, SHA3_methods);
556-
SHA3_TYPE(SHA3_384type, "_sha3.sha3_384", sha3_384__doc__, SHA3_methods);
557-
SHA3_TYPE(SHA3_512type, "_sha3.sha3_512", sha3_512__doc__, SHA3_methods);
558-
559543
#ifdef PY_WITH_KECCAK
560544
PyDoc_STRVAR(keccak_224__doc__,
561545
"keccak_224([data], *, usedforsecurity=True) -> Keccak object\n\
@@ -577,10 +561,32 @@ PyDoc_STRVAR(keccak_512__doc__,
577561
\n\
578562
Return a new Keccak hash object with a hashbit length of 64 bytes.");
579563

580-
SHA3_TYPE(Keccak_224type, "_sha3.keccak_224", keccak_224__doc__, SHA3_methods);
581-
SHA3_TYPE(Keccak_256type, "_sha3.keccak_256", keccak_256__doc__, SHA3_methods);
582-
SHA3_TYPE(Keccak_384type, "_sha3.keccak_384", keccak_384__doc__, SHA3_methods);
583-
SHA3_TYPE(Keccak_512type, "_sha3.keccak_512", keccak_512__doc__, SHA3_methods);
564+
#endif
565+
566+
SHA3_TYPE_SLOTS(SHA3_224slots, sha3_224__doc__, SHA3_methods);
567+
SHA3_TYPE_SPEC(SHA3_224typespec, "_sha3.sha3_224", SHA3_224slots);
568+
569+
SHA3_TYPE_SLOTS(SHA3_256slots, sha3_256__doc__, SHA3_methods);
570+
SHA3_TYPE_SPEC(SHA3_256typespec, "_sha3.sha3_256", SHA3_256slots);
571+
572+
SHA3_TYPE_SLOTS(SHA3_384slots, sha3_384__doc__, SHA3_methods);
573+
SHA3_TYPE_SPEC(SHA3_384typespec, "_sha3.sha3_384", SHA3_384slots);
574+
575+
SHA3_TYPE_SLOTS(SHA3_512slots, sha3_512__doc__, SHA3_methods);
576+
SHA3_TYPE_SPEC(SHA3_512typespec, "_sha3.sha3_512", SHA3_512slots);
577+
578+
#ifdef PY_WITH_KECCAK
579+
SHA3_TYPE_SLOTS(Keccak_224slots, keccak_224__doc__, SHA3_methods);
580+
SHA3_TYPE_SPEC(Keccak_224typespec, "_sha3.keccak_224", Keccak_224slots);
581+
582+
SHA3_TYPE_SLOTS(Keccak_256slots, keccak_256__doc__, SHA3_methods);
583+
SHA3_TYPE_SPEC(Keccak_256typespec, "_sha3.keccak_256", Keccak_256slots);
584+
585+
SHA3_TYPE_SLOTS(Keccak_384slots, keccak_384__doc__, SHA3_methods);
586+
SHA3_TYPE_SPEC(Keccak_384typespec, "_sha3.keccak_384", Keccak_384slots);
587+
588+
SHA3_TYPE_SLOTS(Keccak_512slots, keccak_512__doc__, SHA3_methods);
589+
SHA3_TYPE_SPEC(Keccak_512typespec, "_sha3.keccak_512", Keccak_512slots);
584590
#endif
585591

586592

@@ -684,58 +690,40 @@ PyDoc_STRVAR(shake_256__doc__,
684690
\n\
685691
Return a new SHAKE hash object.");
686692

687-
SHA3_TYPE(SHAKE128type, "_sha3.shake_128", shake_128__doc__, SHAKE_methods);
688-
SHA3_TYPE(SHAKE256type, "_sha3.shake_256", shake_256__doc__, SHAKE_methods);
693+
SHA3_TYPE_SLOTS(SHAKE128slots, shake_128__doc__, SHAKE_methods);
694+
SHA3_TYPE_SPEC(SHAKE128typespec, "_sha3.shake_128", SHAKE128slots);
689695

690-
691-
/* Initialize this module. */
692-
static struct PyModuleDef _SHA3module = {
693-
PyModuleDef_HEAD_INIT,
694-
"_sha3",
695-
NULL,
696-
-1,
697-
NULL,
698-
NULL,
699-
NULL,
700-
NULL,
701-
NULL
702-
};
696+
SHA3_TYPE_SLOTS(SHAKE256slots, shake_256__doc__, SHAKE_methods);
697+
SHA3_TYPE_SPEC(SHAKE256typespec, "_sha3.shake_256", SHAKE256slots);
703698

704699

705-
PyMODINIT_FUNC
706-
PyInit__sha3(void)
707-
{
708-
PyObject *m = NULL;
700+
static int sha3_exec(PyObject *m) {
701+
SHA3State *st = sha3_get_state(m);
709702

710-
if ((m = PyModule_Create(&_SHA3module)) == NULL) {
711-
return NULL;
712-
}
713-
714-
#define init_sha3type(name, type) \
715-
do { \
716-
Py_SET_TYPE(type, &PyType_Type); \
717-
if (PyType_Ready(type) < 0) { \
718-
goto error; \
719-
} \
720-
Py_INCREF((PyObject *)type); \
721-
if (PyModule_AddObject(m, name, (PyObject *)type) < 0) { \
722-
goto error; \
723-
} \
703+
#define init_sha3type(name, type, typespec) \
704+
do { \
705+
st->type = (PyTypeObject *)PyType_FromModuleAndSpec( \
706+
m, &typespec, NULL); \
707+
if (st->type == NULL) { \
708+
return -1; \
709+
} \
710+
if (PyModule_AddType(m, st->type) < 0) { \
711+
return -1; \
712+
} \
724713
} while(0)
725714

726-
init_sha3type("sha3_224", &SHA3_224type);
727-
init_sha3type("sha3_256", &SHA3_256type);
728-
init_sha3type("sha3_384", &SHA3_384type);
729-
init_sha3type("sha3_512", &SHA3_512type);
715+
init_sha3type("sha3_224", sha3_224_type, SHA3_224typespec);
716+
init_sha3type("sha3_256", sha3_256_type, SHA3_256typespec);
717+
init_sha3type("sha3_384", sha3_384_type, SHA3_384typespec);
718+
init_sha3type("sha3_512", sha3_512_type, SHA3_512typespec);
730719
#ifdef PY_WITH_KECCAK
731-
init_sha3type("keccak_224", &Keccak_224type);
732-
init_sha3type("keccak_256", &Keccak_256type);
733-
init_sha3type("keccak_384", &Keccak_384type);
734-
init_sha3type("keccak_512", &Keccak_512type);
720+
init_sha3type("keccak_224", keccak224_type, Keccak_224typespec);
721+
init_sha3type("keccak_256", keccak256_type, Keccak_256typespec);
722+
init_sha3type("keccak_384", keccak384_type, Keccak_384typespec);
723+
init_sha3type("keccak_512", keccak512_type, Keccak_512typespec);
735724
#endif
736-
init_sha3type("shake_128", &SHAKE128type);
737-
init_sha3type("shake_256", &SHAKE256type);
738-
725+
init_sha3type("shake_128", shake128_type, SHAKE128typespec);
726+
init_sha3type("shake_256", shake256_type, SHAKE256typespec);
739727
#undef init_sha3type
740728

741729
if (PyModule_AddIntConstant(m, "keccakopt", KeccakOpt) < 0) {
@@ -746,8 +734,26 @@ PyInit__sha3(void)
746734
goto error;
747735
}
748736

749-
return m;
737+
return 0;
750738
error:
751-
Py_DECREF(m);
752-
return NULL;
739+
return -1;
753740
}
741+
742+
static PyModuleDef_Slot _sha3_slots[] = {
743+
{Py_mod_exec, sha3_exec},
744+
{0, NULL}
745+
};
746+
747+
/* Initialize this module. */
748+
static struct PyModuleDef _sha3module = {
749+
PyModuleDef_HEAD_INIT,
750+
.m_name = "_sha3",
751+
.m_size = sizeof(SHA3State),
752+
.m_slots = _sha3_slots
753+
};
754+
755+
756+
PyMODINIT_FUNC
757+
PyInit__sha3(void) {
758+
return PyModuleDef_Init(&_sha3module);
759+
}

0 commit comments

Comments
 (0)