X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/cfb291f03e0882cba9037be2a2756a6af41fb76a..54fd7594ee5df9dbc9745d98adaa01a5ed43b6e4:/rand.c diff --git a/rand.c b/rand.c index 675bf70..e72f450 100644 --- a/rand.c +++ b/rand.c @@ -102,16 +102,14 @@ static PyObject *grmeth_range(PyObject *me, PyObject *arg) if (!PyArg_ParseTuple(arg, "O:range", &m)) return (0); if (grand_check(me)) return (0); if (PyInt_Check(m)) { - long mm = PyInt_AS_LONG(m); - if (mm <= 0) - goto notpos; - if (mm <= 0xffffffff) + long mm = PyInt_AsLong(m); + if (mm == -1 && PyErr_Occurred()) PyErr_Clear(); + else if (mm <= 0) goto notpos; + else if (mm <= 0xffffffff) return (PyInt_FromLong(grand_range(GRAND_R(me), mm))); } - if ((x = getmp(m)) == 0) - goto end; - if (!MP_POSP(x)) - goto notpos; + if ((x = getmp(m)) == 0) goto end; + if (!MP_POSP(x)) goto notpos; y = mprand_range(MP_NEW, x, GRAND_R(me), 0); MP_DROP(x); return (mp_pywrap(y)); @@ -644,7 +642,7 @@ static PyObject *gcirand_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) static const char *const kwlist[] = { "key", "i", 0 }; struct bin k; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&:new", KWLIST, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&:new", KWLIST, convbin, &k, convu32, &i)) goto end; if (keysz(k.sz, info->keysz) != k.sz) VALERR("bad key length"); @@ -659,9 +657,11 @@ static PyObject *gcnrand_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { const gccrand_info *info = GCCRAND_INFO(ty); static const char *const kwlist[] = { "key", "nonce", 0 }; + static const octet zn[24] = { 0 }; struct bin k, n; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&:new", KWLIST, + n.p = zn; n.sz = info->noncesz; assert(info->noncesz <= sizeof(zn)); + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&:new", KWLIST, convbin, &k, convbin, &n)) goto end; if (keysz(k.sz, info->keysz) != k.sz) VALERR("bad key length"); @@ -1120,12 +1120,18 @@ static const PyTypeObject tlsprf_pytype_skel = { static PyObject *dsarand_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { struct bin in; + unsigned passes = 1; + grand *r; PyObject *rc = 0; - static const char *const kwlist[] = { "seed", 0 }; + static const char *const kwlist[] = { "seed", "passes", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&:new", KWLIST, convbin, &in)) + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&:new", KWLIST, + convbin, &in, convuint, &passes)) goto end; - rc = grand_dopywrap(ty, dsarand_create(in.p, in.sz), f_freeme); + if (!passes) VALERR("must be positive"); + r = dsarand_create(in.p, in.sz); + if (passes != 1) r->ops->misc(r, DSARAND_PASSES, passes); + rc = grand_dopywrap(ty, r, f_freeme); end: return (rc); } @@ -1139,9 +1145,32 @@ static PyObject *drget_seed(PyObject *me, void *hunoz) return (rc); } +static PyObject *drget_passes(PyObject *me, void *hunoz) +{ + grand *r = GRAND_R(me); + return (PyInt_FromLong(r->ops->misc(r, DSARAND_PASSES, 0))); +} + +static int drset_passes(PyObject *me, PyObject *val, void *hunoz) +{ + grand *r = GRAND_R(me); + long n; + int rc = -1; + + if (!val) NIERR("__del__"); + n = PyInt_AsLong(val); if (n == -1 && PyErr_Occurred()) goto end; + if (n <= 0) VALERR("must be positive"); + if (n > ULONG_MAX) VALERR("out of range"); + r->ops->misc(r, DSARAND_PASSES, (unsigned)n); + rc = 0; +end: + return (rc); +} + static const PyGetSetDef dsarand_pygetset[] = { #define GETSETNAME(op, name) dr##op##_##name GET (seed, "R.seed -> current generator seed") + GETSET(passes, "R.passes -> number of passes to create output") #undef GETSETNAME { 0 } };