X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/77f2f48ef941f17978c7fce1468885bc8c89969a..457b4e971a2795898c83a53ae4c27d6a893690d1:/algorithms.c diff --git a/algorithms.c b/algorithms.c index 06fdc32..5703901 100644 --- a/algorithms.c +++ b/algorithms.c @@ -35,21 +35,31 @@ PyTypeObject *keysz_pytype; PyTypeObject *keyszany_pytype, *keyszrange_pytype, *keyszset_pytype; PyObject *sha_pyobj, *has160_pyobj; +#ifndef KSZ_OPMASK +# define KSZ_OPMASK 0x1f +#endif + +#ifndef KSZ_16BIT +# define KSZ_16BIT 0x20 +#endif + PyObject *keysz_pywrap(const octet *k) { - switch (k[0]) { + unsigned op = *k++; +#define ARG(i) (op&KSZ_16BIT ? LOAD16(k + 2*(i)) : k[i]) + switch (op&KSZ_OPMASK) { case KSZ_ANY: { keysz_pyobj *o = PyObject_New(keysz_pyobj, keyszany_pytype); - o->dfl = k[1]; + o->dfl = ARG(0); return ((PyObject *)o); } break; case KSZ_RANGE: { keyszrange_pyobj *o = PyObject_New(keyszrange_pyobj, keyszrange_pytype); - o->dfl = k[1]; - o->min = k[2]; - o->max = k[3]; - o->mod = k[4]; + o->dfl = ARG(0); + o->min = ARG(1); + o->max = ARG(2); + o->mod = ARG(3); if (!o->mod) o->mod = 1; return ((PyObject *)o); } break; @@ -57,16 +67,17 @@ PyObject *keysz_pywrap(const octet *k) keyszset_pyobj *o = PyObject_New(keyszset_pyobj, keyszset_pytype); int i, n; - o->dfl = k[1]; - for (i = 0; k[i + 1]; i++) ; + o->dfl = ARG(0); + for (i = 0; ARG(i); i++) ; n = i; o->set = PyTuple_New(n); for (i = 0; i < n; i++) - PyTuple_SET_ITEM(o->set, i, PyInt_FromLong(k[i + 1])); + PyTuple_SET_ITEM(o->set, i, PyInt_FromLong(ARG(i))); return ((PyObject *)o); } break; default: abort(); } +#undef ARG } static PyObject *keyszany_pynew(PyTypeObject *ty, @@ -462,7 +473,7 @@ static PyObject *gcipher_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { char *kwlist[] = { "k", 0 }; char *k; - int sz; + Py_ssize_t sz; if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", kwlist, &k, &sz)) goto end; @@ -511,7 +522,7 @@ static PyObject *gccget_blksz(PyObject *me, void *hunoz) static PyObject *gcmeth_encrypt(PyObject *me, PyObject *arg) { char *p; - int sz; + Py_ssize_t sz; PyObject *rc = 0; if (!PyArg_ParseTuple(arg, "s#:encrypt", &p, &sz)) return (0); @@ -537,7 +548,7 @@ static PyObject *gcmeth_enczero(PyObject *me, PyObject *arg) static PyObject *gcmeth_decrypt(PyObject *me, PyObject *arg) { char *p; - int sz; + Py_ssize_t sz; PyObject *rc = 0; if (!PyArg_ParseTuple(arg, "s#:decrypt", &p, &sz)) return (0); @@ -563,9 +574,10 @@ static PyObject *gcmeth_deczero(PyObject *me, PyObject *arg) static PyObject *gcmeth_setiv(PyObject *me, PyObject *arg) { char *p; - int sz; + Py_ssize_t sz; if (!PyArg_ParseTuple(arg, "s#:setiv", &p, &sz)) goto end; + if (!GCIPHER_C(me)->ops->setiv) VALERR("`setiv' not supported"); if (!GC_CLASS(GCIPHER_C(me))->blksz) VALERR("not a block cipher mode"); if (sz != GC_CLASS(GCIPHER_C(me))->blksz) VALERR("bad IV length"); GC_SETIV(GCIPHER_C(me), p); @@ -577,6 +589,7 @@ end: static PyObject *gcmeth_bdry(PyObject *me, PyObject *arg) { if (!PyArg_ParseTuple(arg, ":bdry")) goto end; + if (!GCIPHER_C(me)->ops->bdry) VALERR("`bdry' not supported"); if (!GC_CLASS(GCIPHER_C(me))->blksz) VALERR("not a block cipher mode"); GC_BDRY(GCIPHER_C(me)); RETURN_ME; @@ -766,33 +779,12 @@ static PyObject *gchget_bufsz(PyObject *me, void *hunoz) static PyObject *ghmeth_hash(PyObject *me, PyObject *arg) { char *p; - int sz; + Py_ssize_t sz; if (!PyArg_ParseTuple(arg, "s#:hash", &p, &sz)) return (0); GH_HASH(GHASH_H(me), p, sz); RETURN_ME; } -static PyObject *ghmeth_done(PyObject *me, PyObject *arg) -{ - ghash *g; - PyObject *rc; - if (!PyArg_ParseTuple(arg, ":done")) return (0); - g = GH_COPY(GHASH_H(me)); - rc = bytestring_pywrap(0, g->ops->c->hashsz); - GH_DONE(g, PyString_AS_STRING(rc)); - GH_DESTROY(g); - return (rc); -} - -static PyGetSetDef gchash_pygetset[] = { -#define GETSETNAME(op, name) gch##op##_##name - GET (bufsz, "CH.bufsz -> hash buffer size, or zero") - GET (hashsz, "CH.hashsz -> hash output size") - GET (name, "CH.name -> name of this kind of hash") -#undef GETSETNAME - { 0 } -}; - #define GHMETH_HASHU_(n, W, w) \ static PyObject *ghmeth_hashu##w(PyObject *me, PyObject *arg) \ { \ @@ -809,7 +801,7 @@ DOUINTCONV(GHMETH_HASHU_) static PyObject *ghmeth_hashbuf##w(PyObject *me, PyObject *arg) \ { \ char *p; \ - int sz; \ + Py_ssize_t sz; \ if (!PyArg_ParseTuple(arg, "s#:hashbuf" #w, &p, &sz)) goto end; \ if (sz > MASK##n) TYERR("string too long"); \ GH_HASHBUF##W(GHASH_H(me), p, sz); \ @@ -827,13 +819,36 @@ static PyObject *ghmeth_hashstrz(PyObject *me, PyObject *arg) RETURN_ME; } +static PyObject *ghmeth_done(PyObject *me, PyObject *arg) +{ + ghash *g; + PyObject *rc; + if (!PyArg_ParseTuple(arg, ":done")) return (0); + g = GH_COPY(GHASH_H(me)); + rc = bytestring_pywrap(0, g->ops->c->hashsz); + GH_DONE(g, PyString_AS_STRING(rc)); + GH_DESTROY(g); + return (rc); +} + +static PyGetSetDef gchash_pygetset[] = { +#define GETSETNAME(op, name) gch##op##_##name + GET (bufsz, "CH.bufsz -> hash buffer size, or zero") + GET (hashsz, "CH.hashsz -> hash output size") + GET (name, "CH.name -> name of this kind of hash") +#undef GETSETNAME + { 0 } +}; + static PyMethodDef ghash_pymethods[] = { #define METHNAME(name) ghmeth_##name METH (hash, "H.hash(M)") #define METHU_(n, W, w) METH(hashu##w, "H.hashu" #w "(WORD)") DOUINTCONV(METHU_) +#undef METHU_ #define METHBUF_(n, W, w) METH(hashbuf##w, "H.hashbuf" #w "(BYTES)") DOUINTCONV(METHBUF_) +#undef METHBUF_ METH (hashstrz, "H.hashstrz(STRING)") METH (done, "H.done() -> HASH") #undef METHNAME @@ -948,7 +963,7 @@ static PyObject *gmac_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { char *kwlist[] = { "k", 0 }; char *k; - int sz; + Py_ssize_t sz; if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", kwlist, &k, &sz)) goto end; @@ -1183,6 +1198,394 @@ static PyTypeObject gmhash_pytype_skel = { 0 /* @tp_is_gc@ */ }; +/*----- Special snowflake for Poly1305 ------------------------------------*/ + +PyTypeObject *poly1305cls_pytype, *poly1305key_pytype, *poly1305hash_pytype; + +typedef struct poly1305key_pyobj { + PyHeapTypeObject ty; + poly1305_key k; +} poly1305key_pyobj; + +typedef struct poly1305hash_pyobj { + PyObject_HEAD + unsigned f; +#define f_mask 1u + poly1305_ctx ctx; +} poly1305hash_pyobj; + +#define P1305_F(o) (((poly1305hash_pyobj *)(o))->f) +#define P1305_CTX(o) (&((poly1305hash_pyobj *)(o))->ctx) +CONVFUNC(poly1305hash, poly1305_ctx *, P1305_CTX) + +static PyObject *poly1305hash_pynew(PyTypeObject *ty, + PyObject *arg, PyObject *kw) +{ + char *kwlist[] = { "mask", 0 }; + poly1305key_pyobj *pk = (poly1305key_pyobj *)ty; + poly1305hash_pyobj *ph; + char *m = 0; + Py_ssize_t sz; + + if (!PyArg_ParseTupleAndKeywords(arg, kw, "|s#:new", kwlist, &m, &sz)) + return (0); + if (m && sz != POLY1305_MASKSZ) VALERR("bad mask length"); + ph = PyObject_NEW(poly1305hash_pyobj, ty); + ph->f = 0; + if (m) ph->f |= f_mask; + poly1305_macinit(&ph->ctx, &pk->k, m); + Py_INCREF(ty); + return ((PyObject *)ph); +end: + return (0); +} + +static PyObject *poly1305key_pynew(PyTypeObject *ty, + PyObject *arg, PyObject *kw) +{ + char *kwlist[] = { "k", 0 }; + poly1305key_pyobj *pk; + char *k; + Py_ssize_t sz; + + if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", kwlist, &k, &sz)) + goto end; + if (keysz(sz, poly1305_keysz) != sz) VALERR("bad key length"); + + pk = newtype(ty, 0, 0); + pk->ty.ht_name = PyString_FromString("poly1305(keyed)"); + pk->ty.ht_type.tp_basicsize = sizeof(poly1305hash_pyobj); + pk->ty.ht_type.tp_name = PyString_AS_STRING(pk->ty.ht_name); + pk->ty.ht_type.tp_base = poly1305hash_pytype; + Py_INCREF(poly1305key_pytype); + pk->ty.ht_type.tp_flags = (Py_TPFLAGS_DEFAULT | + Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HEAPTYPE); + pk->ty.ht_type.tp_alloc = PyType_GenericAlloc; + pk->ty.ht_type.tp_free = 0; + pk->ty.ht_type.tp_new = poly1305hash_pynew; + typeready(&pk->ty.ht_type); + + poly1305_keyinit(&pk->k, k, sz); + return ((PyObject *)pk); + +end: + return (0); +} + +static PyObject *poly1305clsget_name(PyObject *me, void *hunoz) + { return (PyString_FromString("poly1305")); } + +static PyObject *poly1305clsget_keysz(PyObject *me, void *hunoz) + { return (keysz_pywrap(poly1305_keysz)); } + +static PyObject *poly1305clsget_masksz(PyObject *me, void *hunoz) + { return (PyInt_FromLong(POLY1305_MASKSZ)); } + +static PyObject *poly1305clsget_tagsz(PyObject *me, void *hunoz) + { return (PyInt_FromLong(POLY1305_TAGSZ)); } + +static PyObject *polymeth_copy(PyObject *me, PyObject *arg) +{ + poly1305hash_pyobj *ph; + if (!PyArg_ParseTuple(arg, ":copy")) return (0); + ph = PyObject_NEW(poly1305hash_pyobj, me->ob_type); + poly1305_copy(&ph->ctx, P1305_CTX(me)); + Py_INCREF(me->ob_type); + return ((PyObject *)ph); +} + +static PyObject *polymeth_hash(PyObject *me, PyObject *arg) +{ + char *p; + Py_ssize_t sz; + if (!PyArg_ParseTuple(arg, "s#:hash", &p, &sz)) return (0); + poly1305_hash(P1305_CTX(me), p, sz); + RETURN_ME; +} + +#define POLYMETH_HASHU_(n, W, w) \ + static PyObject *polymeth_hashu##w(PyObject *me, PyObject *arg) \ + { \ + uint##n x; \ + octet b[SZ_##W]; \ + if (!PyArg_ParseTuple(arg, "O&:hashu" #w, convu##n, &x)) goto end; \ + STORE##W(b, x); poly1305_hash(P1305_CTX(me), b, sizeof(b)); \ + RETURN_ME; \ + end: \ + return (0); \ + } +DOUINTCONV(POLYMETH_HASHU_) + +#define POLYMETH_HASHBUF_(n, W, w) \ + static PyObject *polymeth_hashbuf##w(PyObject *me, PyObject *arg) \ + { \ + char *p; \ + Py_ssize_t sz; \ + octet b[SZ_##W]; \ + if (!PyArg_ParseTuple(arg, "s#:hashbuf" #w, &p, &sz)) goto end; \ + if (sz > MASK##n) TYERR("string too long"); \ + STORE##W(b, sz); poly1305_hash(P1305_CTX(me), b, sizeof(b)); \ + poly1305_hash(P1305_CTX(me), p, sz); \ + RETURN_ME; \ + end: \ + return (0); \ + } +DOUINTCONV(POLYMETH_HASHBUF_) + +static PyObject *polymeth_hashstrz(PyObject *me, PyObject *arg) +{ + char *p; + if (!PyArg_ParseTuple(arg, "s:hashstrz", &p)) return (0); + poly1305_hash(P1305_CTX(me), p, strlen(p) + 1); + RETURN_ME; +} + +static PyObject *polymeth_flush(PyObject *me, PyObject *arg) +{ + if (!PyArg_ParseTuple(arg, ":flush")) return (0); + poly1305_flush(P1305_CTX(me)); + RETURN_ME; +} + +static PyObject *polymeth_flushzero(PyObject *me, PyObject *arg) +{ + if (!PyArg_ParseTuple(arg, ":flushzero")) return (0); + poly1305_flushzero(P1305_CTX(me)); + RETURN_ME; +} + +static PyObject *polymeth_concat(PyObject *me, PyObject *arg) +{ + PyObject *pre, *suff; + if (!PyArg_ParseTuple(arg, "OO:concat", &pre, &suff)) return (0); + if (!PyObject_TypeCheck(pre, poly1305hash_pytype) || + !PyObject_TypeCheck(suff, poly1305hash_pytype)) + TYERR("wanted a poly1305hash"); + if (me->ob_type != pre->ob_type || me->ob_type != suff->ob_type) + TYERR("key mismatch"); + if (P1305_CTX(pre)->nbuf) VALERR("prefix is not block-aligned"); + poly1305_concat(P1305_CTX(me), P1305_CTX(pre), P1305_CTX(suff)); + RETURN_ME; +end: + return (0); +} + +static PyObject *polymeth_done(PyObject *me, PyObject *arg) +{ + PyObject *rc; + if (!PyArg_ParseTuple(arg, ":done")) return (0); + if (!(P1305_F(me) & f_mask)) VALERR("no mask"); + rc = bytestring_pywrap(0, POLY1305_TAGSZ); + poly1305_done(P1305_CTX(me), PyString_AS_STRING(rc)); + return (rc); +end: + return (0); +} + +static PyGetSetDef poly1305cls_pygetset[] = { +#define GETSETNAME(op, name) poly1305cls##op##_##name + GET (keysz, "PC.keysz -> acceptable key sizes") + GET (masksz, "PC.masksz -> mask size") + GET (tagsz, "PC.tagsz -> MAC output size") + GET (name, "PC.name -> name of this kind of MAC") +#undef GETSETNAME + { 0 } +}; + +static PyMethodDef poly1305hash_pymethods[] = { +#define METHNAME(name) polymeth_##name + METH (copy, "P.copy() -> PP") + METH (hash, "P.hash(M)") +#define METHU_(n, W, w) METH(hashu##w, "P.hashu" #w "(WORD)") + DOUINTCONV(METHU_) +#undef METHU_ +#define METHBUF_(n, W, w) METH(hashbuf##w, "P.hashbuf" #w "(BYTES)") + DOUINTCONV(METHBUF_) +#undef METHBUF_ + METH (hashstrz, "P.hashstrz(STRING)") + METH (flush, "P.flush()") + METH (flushzero, "P.flushzero()") + METH (concat, "P.concat(PREFIX, SUFFIX)") + METH (done, "P.done() -> TAG") +#undef METHNAME + { 0 } +}; + +static PyTypeObject poly1305cls_pytype_skel = { + PyObject_HEAD_INIT(0) 0, /* Header */ + "Poly1305Class", /* @tp_name@ */ + sizeof(PyHeapTypeObject), /* @tp_basicsize@ */ + 0, /* @tp_itemsize@ */ + + 0, /* @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@ */ +"Poly1305 metametaclass. Best not to ask.", + + 0, /* @tp_traverse@ */ + 0, /* @tp_clear@ */ + 0, /* @tp_richcompare@ */ + 0, /* @tp_weaklistoffset@ */ + 0, /* @tp_iter@ */ + 0, /* @tp_iternext@ */ + 0, /* @tp_methods@ */ + 0, /* @tp_members@ */ + poly1305cls_pygetset, /* @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@ */ +}; + +static PyTypeObject poly1305key_pytype_skel = { + PyObject_HEAD_INIT(0) 0, /* Header */ + "poly1305", /* @tp_name@ */ + sizeof(poly1305key_pyobj), /* @tp_basicsize@ */ + 0, /* @tp_itemsize@ */ + + 0, /* @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@ */ +"Poly1305 key.", + + 0, /* @tp_traverse@ */ + 0, /* @tp_clear@ */ + 0, /* @tp_richcompare@ */ + 0, /* @tp_weaklistoffset@ */ + 0, /* @tp_iter@ */ + 0, /* @tp_iternext@ */ + 0, /* @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@ */ + poly1305key_pynew, /* @tp_new@ */ + 0, /* @tp_free@ */ + 0 /* @tp_is_gc@ */ +}; + +static PyTypeObject poly1305hash_pytype_skel = { + PyObject_HEAD_INIT(0) 0, /* Header */ + "Poly1305Hash", /* @tp_name@ */ + sizeof(poly1305hash_pyobj), /* @tp_basicsize@ */ + 0, /* @tp_itemsize@ */ + + 0, /* @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@ */ +"Poly1305 MAC context base class.", + + 0, /* @tp_traverse@ */ + 0, /* @tp_clear@ */ + 0, /* @tp_richcompare@ */ + 0, /* @tp_weaklistoffset@ */ + 0, /* @tp_iter@ */ + 0, /* @tp_iternext@ */ + poly1305hash_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@ */ +}; + +/*----- Special snowflake for HSalsa and HChaCha --------------------------*/ + +#define DEF_HDANCE(DANCE, HDANCE, dance, hdance) \ + static PyObject *meth_##hdance##_prf(PyObject *me, PyObject *arg) \ + { \ + dance##_ctx dance; \ + char *k, *n; \ + Py_ssize_t ksz, nsz; \ + PyObject *rc; \ + if (!PyArg_ParseTuple(arg, "s#s#:" #hdance "_prf", \ + &k, &ksz, &n, &nsz)) \ + goto end; \ + if (ksz != DANCE##_KEYSZ) VALERR("bad key length"); \ + if (nsz != HDANCE##_INSZ) VALERR("bad input length"); \ + rc = bytestring_pywrap(0, HSALSA20_OUTSZ); \ + dance##_init(&dance, k, ksz, 0); \ + hdance##_prf(&dance, n, PyString_AS_STRING(rc)); \ + return (rc); \ + end: \ + return (0); \ + } + +DEF_HDANCE(SALSA20, HSALSA20, salsa20, hsalsa20) +DEF_HDANCE(SALSA20, HSALSA20, salsa20, hsalsa2012) +DEF_HDANCE(SALSA20, HSALSA20, salsa20, hsalsa208) + +DEF_HDANCE(CHACHA, HCHACHA, chacha, hchacha20) +DEF_HDANCE(CHACHA, HCHACHA, chacha, hchacha12) +DEF_HDANCE(CHACHA, HCHACHA, chacha, hchacha8) + /*----- Pseudorandom permutations -----------------------------------------*/ static PyTypeObject *gcprp_pytype, *gprp_pytype; @@ -1244,7 +1647,7 @@ static PyObject *gprp_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { char *kwlist[] = { "key", 0 }; char *k; - int sz; + Py_ssize_t sz; const prpinfo *prp = GCPRP_PRP(ty); PyObject *me; @@ -1290,7 +1693,7 @@ static PyObject *gcpget_blksz(PyObject *me, void *hunoz) static PyObject *gpmeth_encrypt(PyObject *me, PyObject *arg) { char *p; - int n; + Py_ssize_t n; PyObject *rc = 0; if (!PyArg_ParseTuple(arg, "s#:encrypt", &p, &n)) goto end; @@ -1304,7 +1707,7 @@ end: static PyObject *gpmeth_decrypt(PyObject *me, PyObject *arg) { char *p; - int n; + Py_ssize_t n; PyObject *rc = 0; if (!PyArg_ParseTuple(arg, "s#:decrypt", &p, &n)) goto end; @@ -1448,6 +1851,17 @@ toschnorr(N) -> M: convert work factor to Schnorr group order") toif(N) -> M: convert work factor to integer factorization problem size") METH (_KeySZ_toec, "\ toec(N) -> M: convert work factor to elliptic curve group order") + METH (_KeySZ_toec, "\ +toec(N) -> M: convert work factor to elliptic curve group order") +#define METH_HDANCE(hdance, HDance) METH(hdance##_prf, "\ +" #hdance "_prf(K, N) -> H: calculate " HDance " hash of N with K") + METH_HDANCE(hsalsa20, "HSalsa20") + METH_HDANCE(hsalsa2012, "HSalsa20/12") + METH_HDANCE(hsalsa208, "HSalsa20/8") + METH_HDANCE(hchacha20, "HChaCha20") + METH_HDANCE(hchacha12, "HChaCha12") + METH_HDANCE(hchacha8, "HChaCha8") +#undef METH_DANCE #undef METHNAME { 0 } }; @@ -1465,6 +1879,9 @@ void algorithms_pyinit(void) INITTYPE(gcmac, type); INITTYPE(gmac, type); INITTYPE(gmhash, ghash); + INITTYPE(poly1305cls, type); + INITTYPE_META(poly1305key, type, poly1305cls); + INITTYPE(poly1305hash, root); INITTYPE(gcprp, type); INITTYPE(gprp, root); addmethods(methods); @@ -1495,6 +1912,9 @@ void algorithms_pyinsert(PyObject *mod) INSERT("GMAC", gmac_pytype); INSERT("GMACHash", gmhash_pytype); INSERT("gcmacs", gcmacs()); + INSERT("Poly1305Class", poly1305cls_pytype); + INSERT("poly1305", poly1305key_pytype); + INSERT("Poly1305Hash", poly1305hash_pytype); INSERT("GCPRP", gcprp_pytype); INSERT("GPRP", gprp_pytype); INSERT("gcprps", gcprps());