From: Mark Wooding Date: Mon, 12 Sep 2016 21:29:09 +0000 (+0100) Subject: rand.c, algorithms.py: Support random access protocol of Latin-dance PRFs. X-Git-Tag: 1.2.0~52 X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/commitdiff_plain/35e5469a15e4f97b0fc0ecf70840b22e0bc0b1c2 rand.c, algorithms.py: Support random access protocol of Latin-dance PRFs. Add a new superclass for random bit generators based on Latin-dance PRFs (Salsa20, ChaCha, etc.) which exposes the `seek'/`tell' random access protocol to Python. --- diff --git a/algorithms.py b/algorithms.py index 3ceb207..c2ab4ee 100644 --- a/algorithms.py +++ b/algorithms.py @@ -85,7 +85,7 @@ for i in latindances: else: raise ValueError, 'failed to find root name for %s' % i print ('\t_("%(name)s", %(root)s_keysz, %(id)s_rand, ' + - 'RNGF_NONCE, %(ROOT)s_NONCESZ) \\') % \ + 'RNGF_NONCE | RNGF_LATIN, %(ROOT)s_NONCESZ) \\') % \ {'name': i, 'id': i.translate(None, '/'), 'root': root, 'ROOT': root.upper()} print '\t/* end */' diff --git a/rand.c b/rand.c index 4fcb155..784fd93 100644 --- a/rand.c +++ b/rand.c @@ -578,7 +578,7 @@ static PyTypeObject truerand_pytype_skel = { /*----- Generators from symmetric encryption algorithms -------------------*/ -static PyTypeObject *gccrand_pytype, *gcrand_pytype; +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); @@ -593,6 +593,7 @@ typedef struct gccrand_info { #define RNGF_INT 1u #define RNGF_NONCE 2u +#define RNGF_LATIN 4u typedef struct gccrand_pyobj { PyHeapTypeObject ty; @@ -669,8 +670,9 @@ 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 = gcrand_pytype; - Py_INCREF(gcrand_pytype); + g->ty.ht_type.tp_base = + (info->f & RNGF_LATIN) ? gclatinrand_pytype : gcrand_pytype; + Py_INCREF(g->ty.ht_type.tp_base); g->ty.ht_type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE); @@ -688,6 +690,28 @@ static PyObject *gccrget_name(PyObject *me, void *hunoz) static PyObject *gccrget_keysz(PyObject *me, void *hunoz) { return (keysz_pywrap(GCCRAND_INFO(me)->keysz)); } +static PyObject *gclrmeth_tell(PyObject *me, PyObject *arg) +{ + grand *r = GRAND_R(me); + PyObject *rc = 0; + kludge64 off; + + if (!PyArg_ParseTuple(arg, ":tell")) return (0); + r->ops->misc(r, SALSA20_TELLU64, &off); + rc = getk64(off); + return (rc); +} + +static PyObject *gclrmeth_seek(PyObject *me, PyObject *arg) +{ + grand *r = GRAND_R(me); + kludge64 off; + + if (!PyArg_ParseTuple(arg, "O&:seek", convk64, &off)) return (0); + r->ops->misc(r, SALSA20_SEEKU64, off); + RETURN_ME; +} + static PyGetSetDef gccrand_pygetset[] = { #define GETSETNAME(op, name) gccr##op##_##name GET (keysz, "CR.keysz -> acceptable key sizes") @@ -696,6 +720,14 @@ static PyGetSetDef gccrand_pygetset[] = { { 0 } }; +static PyMethodDef gclatinrand_pymethods[] = { +#define METHNAME(name) gclrmeth_##name + METH (tell, "R.tell() -> OFF") + METH (seek, "R.seek(OFF)") +#undef METHNAME + { 0 } +}; + static PyTypeObject gccrand_pytype_skel = { PyObject_HEAD_INIT(0) 0, /* Header */ "GCCRand", /* @tp_name@ */ @@ -792,6 +824,54 @@ static PyTypeObject gcrand_pytype_skel = { 0 /* @tp_is_gc@ */ }; +static PyTypeObject gclatinrand_pytype_skel = { + PyObject_HEAD_INIT(0) 0, /* Header */ + "GCLatinRand", /* @tp_name@ */ + sizeof(grand_pyobj), /* @tp_basicsize@ */ + 0, /* @tp_itemsize@ */ + + grand_pydealloc, /* @tp_dealloc@ */ + 0, /* @tp_print@ */ + 0, /* @tp_getattr@ */ + 0, /* @tp_setattr@ */ + 0, /* @tp_compare@ */ + 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@ */ + Py_TPFLAGS_BASETYPE, + + /* @tp_doc@ */ +"Abstract base class for symmetric crypto-based generators.", + + 0, /* @tp_traverse@ */ + 0, /* @tp_clear@ */ + 0, /* @tp_richcompare@ */ + 0, /* @tp_weaklistoffset@ */ + 0, /* @tp_iter@ */ + 0, /* @tp_iternext@ */ + gclatinrand_pymethods, /* @tp_methods@ */ + 0, /* @tp_members@ */ + 0, /* @tp_getset@ */ + 0, /* @tp_base@ */ + 0, /* @tp_dict@ */ + 0, /* @tp_descr_get@ */ + 0, /* @tp_descr_set@ */ + 0, /* @tp_dictoffset@ */ + 0, /* @tp_init@ */ + PyType_GenericAlloc, /* @tp_alloc@ */ + abstract_pynew, /* @tp_new@ */ + 0, /* @tp_free@ */ + 0 /* @tp_is_gc@ */ +}; + /*----- SSL and TLS generators --------------------------------------------*/ static PyObject *sslprf_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) @@ -1382,6 +1462,7 @@ void rand_pyinit(void) INITTYPE(tlsprf, grand); INITTYPE(gccrand, type); INITTYPE(gcrand, grand); + INITTYPE(gclatinrand, gcrand); rand_noisesrc(RAND_GLOBAL, &noise_source); rand_seed(RAND_GLOBAL, 160); addmethods(methods); @@ -1404,6 +1485,7 @@ void rand_pyinsert(PyObject *mod) INSERT("BBSPriv", bbspriv_pytype); INSERT("GCCRand", gccrand_pytype); INSERT("GCRand", gcrand_pytype); + INSERT("GCLatinRand", gclatinrand_pytype); rand_pyobj = grand_pywrap(&rand_global, 0); Py_INCREF(rand_pyobj); gccrands_dict = gccrands(); Py_INCREF(gccrands_dict); INSERT("gccrands", gccrands_dict);