X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/78f06cd383e93224abc93b41e76e79d4fdc1286c..3d8f5f7c917e529be7140c9243eac691ec6419d5:/rand.c diff --git a/rand.c b/rand.c index 1c008b7..49aaa38 100644 --- a/rand.c +++ b/rand.c @@ -581,14 +581,17 @@ static PyTypeObject *gccrand_pytype, *gcrand_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 struct gccrand_info { const char *name; const octet *keysz; unsigned f; + size_t noncesz; gcrand_func *func; } gccrand_info; #define RNGF_INT 1u +#define RNGF_NONCE 2u typedef struct gccrand_pyobj { PyHeapTypeObject ty; @@ -596,13 +599,13 @@ typedef struct gccrand_pyobj { } gccrand_pyobj; #define GCCRAND_INFO(o) (((gccrand_pyobj *)(o))->info) -#define GCCRAND_DEF(name, ksz, func, f) \ +#define GCCRAND_DEF(name, ksz, func, f, nsz) \ static const gccrand_info func##_info = \ - { name, ksz, f, (gcrand_func *)func }; + { name, ksz, f, nsz, (gcrand_func *)func }; RNGS(GCCRAND_DEF) static const gccrand_info *const gcrandtab[] = { -#define GCCRAND_ENTRY(name, ksz, func, f) &func##_info, +#define GCCRAND_ENTRY(name, ksz, func, f, nsz) &func##_info, RNGS(GCCRAND_ENTRY) 0 }; @@ -641,6 +644,25 @@ end: return (0); } +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; + + if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#s#:new", kwlist, + &k, &ksz, &n, &nsz)) + goto end; + if (keysz(ksz, info->keysz) != ksz) VALERR("bad key length"); + if (nsz != info->noncesz) VALERR("bad nonce length"); + return (grand_dopywrap(ty, + ((gcnrand_func *)info->func)(k, ksz, n), + f_freeme)); +end: + return (0); +} + static PyObject *gccrand_pywrap(const gccrand_info *info) { gccrand_pyobj *g = newtype(gccrand_pytype, 0, info->name); @@ -653,10 +675,9 @@ static PyObject *gccrand_pywrap(const gccrand_info *info) 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 - g->ty.ht_type.tp_new = gcrand_pynew; + 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; typeready(&g->ty.ht_type); return ((PyObject *)g); }