X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/35e5469a15e4f97b0fc0ecf70840b22e0bc0b1c2..925aa45b22569dd0d08a695a89602f1781085f89:/rand.c diff --git a/rand.c b/rand.c index 784fd93..6fe78bc 100644 --- a/rand.c +++ b/rand.c @@ -173,7 +173,7 @@ end: static PyObject *grmeth_seedblock(PyObject *me, PyObject *arg) { char *p; - int n; + Py_ssize_t n; grand *r = GRAND_R(me); if (!PyArg_ParseTuple(arg, "s#:seedblock", &p, &n) || checkop(r, GRAND_SEEDBLOCK, "seedblock")) @@ -219,7 +219,7 @@ static PyObject *grmeth_mask(PyObject *me, PyObject *arg) { grand *r = GRAND_R(me); char *p, *q; - int sz; + Py_ssize_t sz; PyObject *rc; if (!PyArg_ParseTuple(arg, "s#:mask", &p, &sz)) return (0); @@ -452,7 +452,7 @@ static PyObject *trmeth_stretch(PyObject *me, PyObject *arg) static PyObject *trmeth_add(PyObject *me, PyObject *arg) { grand *r = GRAND_R(me); - char *p; int n; unsigned goodbits; + char *p; Py_ssize_t n; unsigned goodbits; if (!PyArg_ParseTuple(arg, "s#O&:add", &p, &n, convuint, &goodbits)) return (0); r->ops->misc(r, RAND_ADD, p, (size_t)n, goodbits); @@ -462,7 +462,7 @@ static PyObject *trmeth_add(PyObject *me, PyObject *arg) static PyObject *trmeth_key(PyObject *me, PyObject *arg) { grand *r = GRAND_R(me); - char *p; int n; + char *p; Py_ssize_t n; if (!PyArg_ParseTuple(arg, "s#:key", &p, &n)) return (0); r->ops->misc(r, RAND_KEY, p, (size_t)n); RETURN_ME; @@ -583,6 +583,12 @@ static PyTypeObject *gccrand_pytype, *gcrand_pytype, *gclatinrand_pytype; typedef grand *gcrand_func(const void *, size_t sz); typedef grand *gcirand_func(const void *, size_t sz, uint32); typedef grand *gcnrand_func(const void *, size_t sz, const void *); +typedef grand *gcshakerand_func(const void *, size_t, + const void *, size_t, + const void *, size_t); +typedef grand *gcshafuncrand_func(const void *, size_t, + const void *, size_t); +typedef grand *gckmacrand_func(const void *, size_t, const void *, size_t); typedef struct gccrand_info { const char *name; const octet *keysz; @@ -591,9 +597,15 @@ typedef struct gccrand_info { gcrand_func *func; } gccrand_info; -#define RNGF_INT 1u -#define RNGF_NONCE 2u -#define RNGF_LATIN 4u +#define RNGF_MASK 255u + +enum { + RNG_PLAIN = 0, + RNG_SEAL, + RNG_LATIN, + RNG_SHAKE, + RNG_KMAC +}; typedef struct gccrand_pyobj { PyHeapTypeObject ty; @@ -617,7 +629,7 @@ static PyObject *gcrand_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) const gccrand_info *info = GCCRAND_INFO(ty); static char *kwlist[] = { "key", 0 }; char *k; - int n; + Py_ssize_t n; if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", kwlist, &k, &n)) goto end; @@ -633,7 +645,7 @@ static PyObject *gcirand_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) uint32 i = 0; static char *kwlist[] = { "key", "i", 0 }; char *k; - int n; + Py_ssize_t n; if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#O&:new", kwlist, &k, &n, convu32, &i)) @@ -651,7 +663,7 @@ static PyObject *gcnrand_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) const gccrand_info *info = GCCRAND_INFO(ty); static char *kwlist[] = { "key", "nonce", 0 }; char *k, *n; - int ksz, nsz; + Py_ssize_t ksz, nsz; if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#s#:new", kwlist, &k, &ksz, &n, &nsz)) @@ -665,22 +677,56 @@ end: return (0); } +static PyObject *gcshakyrand_pynew(PyTypeObject *ty, + PyObject *arg, PyObject *kw) +{ + const gccrand_info *info = GCCRAND_INFO(ty); + static char *kwlist_shake[] = { "key", "func", "perso", 0 }; + static char *kwlist_func[] = { "key", "perso", 0 }; + char *k, *f = 0, *p = 0; + Py_ssize_t ksz, fsz = 0, psz = 0; + + if ((info->f&RNGF_MASK) == RNG_SHAKE + ? !PyArg_ParseTupleAndKeywords(arg, kw, "s#|s#s#:new", kwlist_shake, + &k, &ksz, &f, &fsz, &p, &psz) + : !PyArg_ParseTupleAndKeywords(arg, kw, "s#|s#:new", kwlist_func, + &k, &ksz, &p, &psz)) + goto end; + if (keysz(ksz, info->keysz) != ksz) VALERR("bad key length"); + return (grand_dopywrap(ty, + (info->f&RNGF_MASK) == RNG_SHAKE + ? ((gcshakerand_func *)info->func)(f, fsz, + p, psz, + k, ksz) + : ((gcshafuncrand_func *)info->func)(p, psz, + k, ksz), + f_freeme)); +end: + return (0); +} + static PyObject *gccrand_pywrap(const gccrand_info *info) { gccrand_pyobj *g = newtype(gccrand_pytype, 0, info->name); g->info = info; g->ty.ht_type.tp_basicsize = sizeof(grand_pyobj); - g->ty.ht_type.tp_base = - (info->f & RNGF_LATIN) ? gclatinrand_pytype : gcrand_pytype; + switch (info->f&RNGF_MASK) { + case RNG_LATIN: g->ty.ht_type.tp_base = gclatinrand_pytype; break; + default: g->ty.ht_type.tp_base = gcrand_pytype; break; + } Py_INCREF(g->ty.ht_type.tp_base); g->ty.ht_type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE); g->ty.ht_type.tp_alloc = PyType_GenericAlloc; g->ty.ht_type.tp_free = 0; - if (info->f & RNGF_INT) g->ty.ht_type.tp_new = gcirand_pynew; - else if (info->f & RNGF_NONCE) g->ty.ht_type.tp_new = gcnrand_pynew; - else g->ty.ht_type.tp_new = gcrand_pynew; + switch (info->f&RNGF_MASK) { + case RNG_LATIN: g->ty.ht_type.tp_new = gcnrand_pynew; break; + case RNG_SEAL: g->ty.ht_type.tp_new = gcirand_pynew; break; + case RNG_SHAKE: case RNG_KMAC: + g->ty.ht_type.tp_new = gcshakyrand_pynew; break; + default: g->ty.ht_type.tp_new = gcrand_pynew; break; + } typeready(&g->ty.ht_type); return ((PyObject *)g); }