X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/848ba392a415557f73bbca53e2dc350348f96849..refs/heads/mdw/freebin:/pubkey.c diff --git a/pubkey.c b/pubkey.c index 50fa78c..9ec115a 100644 --- a/pubkey.c +++ b/pubkey.c @@ -54,54 +54,62 @@ static void dsa_pydealloc(PyObject *me) } static PyObject *dsa_setup(PyTypeObject *ty, PyObject *G, PyObject *u, - PyObject *p, PyObject *rng, PyObject *hash) + PyObject *p, PyObject *rng, PyObject *hash, + void (*calcpub)(group *, ge *, mp *)) { dsa_pyobj *g; + ge *pp; g = PyObject_New(dsa_pyobj, ty); - if (GROUP_G(G) != GE_G(p) && !group_samep(GROUP_G(G), GE_G(p))) - TYERR("public key not from group"); + if (p) Py_INCREF(p); if (!u) { g->d.u = 0; u = Py_None; - } else if ((g->d.u = getmp(u)) == 0) - goto end; + } else { + if ((g->d.u = getmp(u)) == 0) + goto end; + if (MP_PYCHECK(u)) Py_INCREF(u); + else u = mp_pywrap(g->d.u); + } + if (!p) { + assert(g->d.u); assert(calcpub); + pp = G_CREATE(GROUP_G(G)); + calcpub(GROUP_G(G), pp, g->d.u); + p = ge_pywrap(G, pp); + } else if (GROUP_G(G) != GE_G(p) && !group_samep(GROUP_G(G), GE_G(p))) + TYERR("public key not from group"); g->d.g = GROUP_G(G); g->d.p = GE_X(p); g->d.r = GRAND_R(rng); g->d.h = GCHASH_CH(hash); - g->G = G; Py_INCREF(G); g->u = u; Py_INCREF(u); g->p = p; Py_INCREF(p); + g->G = G; Py_INCREF(G); g->u = u; g->p = p; g->rng = rng; Py_INCREF(rng); g->hash = hash; Py_INCREF(hash); return ((PyObject *)g); end: - FREEOBJ(g); + Py_XDECREF(p); FREEOBJ(g); return (0); } static PyObject *dsapub_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { - PyObject *G, *p, *u = 0, *rng = rand_pyobj, *hash = sha_pyobj; + PyObject *G, *p, *rng = rand_pyobj, *hash = sha_pyobj; PyObject *rc = 0; - char *kwlist[] = { "G", "p", "u", "hash", "rng", 0 }; + static const char *const kwlist[] = { "G", "p", "hash", "rng", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!O!|OO!O!:new", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!O!|O!O!:new", KWLIST, group_pytype, &G, ge_pytype, &p, - &u, gchash_pytype, &hash, grand_pytype, &rng) || - (rc = dsa_setup(dsapub_pytype, G, u, p, rng, hash)) == 0) + (rc = dsa_setup(dsapub_pytype, G, 0, p, rng, hash, 0)) == 0) goto end; end: return (rc); } -static PyObject *dsameth_beginhash(PyObject *me, PyObject *arg) -{ - if (!PyArg_ParseTuple(arg, ":beginhash")) return (0); - return (ghash_pywrap(DSA_HASH(me), gdsa_beginhash(DSA_D(me)), f_freeme)); -} +static PyObject *dsameth_beginhash(PyObject *me) + { return (ghash_pywrap(DSA_HASH(me), gdsa_beginhash(DSA_D(me)))); } static PyObject *dsameth_endhash(PyObject *me, PyObject *arg) { @@ -111,7 +119,7 @@ static PyObject *dsameth_endhash(PyObject *me, PyObject *arg) gdsa_endhash(DSA_D(me), h); h = GH_COPY(h); rc = bytestring_pywrap(0, GH_CLASS(h)->hashsz); - GH_DONE(h, PyString_AS_STRING(rc)); + GH_DONE(h, BIN_PTR(rc)); GH_DESTROY(h); return (rc); } @@ -119,18 +127,17 @@ static PyObject *dsameth_endhash(PyObject *me, PyObject *arg) static PyObject *dsameth_sign(PyObject *me, PyObject *arg, PyObject *kw) { gdsa_sig s = GDSA_SIG_INIT; - char *p; - Py_ssize_t n; + struct bin h; mp *k = 0; PyObject *rc = 0; - char *kwlist[] = { "msg", "k", 0 }; + static const char *const kwlist[] = { "msg", "k", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#|O&:sign", kwlist, - &p, &n, convmp, &k)) + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&:sign", KWLIST, + convbin, &h, convmp, &k)) goto end; - if (n != DSA_D(me)->h->hashsz) + if (h.sz != DSA_D(me)->h->hashsz) VALERR("bad message length (doesn't match hash size)"); - gdsa_sign(DSA_D(me), &s, p, k); + gdsa_sign(DSA_D(me), &s, h.p, k); rc = Py_BuildValue("(NN)", mp_pywrap(s.r), mp_pywrap(s.s)); end: mp_drop(k); @@ -139,59 +146,60 @@ end: static PyObject *dsameth_verify(PyObject *me, PyObject *arg) { - char *p; - Py_ssize_t n; + struct bin h; gdsa_sig s = GDSA_SIG_INIT; PyObject *rc = 0; - if (!PyArg_ParseTuple(arg, "s#(O&O&):verify", - &p, &n, convmp, &s.r, convmp, &s.s)) + if (!PyArg_ParseTuple(arg, "O&(O&O&):verify", + convbin, &h, convmp, &s.r, convmp, &s.s)) goto end; - if (n != DSA_D(me)->h->hashsz) + if (h.sz != DSA_D(me)->h->hashsz) VALERR("bad message length (doesn't match hash size)"); - rc = getbool(!gdsa_verify(DSA_D(me), &s, p)); + rc = getbool(!gdsa_verify(DSA_D(me), &s, h.p)); end: mp_drop(s.r); mp_drop(s.s); return (rc); } +static void dsa_calcpub(group *g, ge *p, mp *u) { G_EXP(g, p, g->g, u); } + static PyObject *dsapriv_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { - PyObject *G, *p, *u = Py_None, *rng = rand_pyobj, *hash = sha_pyobj; + PyObject *G, *p = 0, *u, *rng = rand_pyobj, *hash = sha_pyobj; PyObject *rc = 0; - char *kwlist[] = { "G", "p", "u", "hash", "rng", 0 }; + static const char *const kwlist[] = { "G", "u", "p", "hash", "rng", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!O!O|O!O!:new", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!O|O!O!O!:new", KWLIST, group_pytype, &G, - ge_pytype, &p, &u, + ge_pytype, &p, gchash_pytype, &hash, grand_pytype, &rng) || - (rc = dsa_setup(dsapriv_pytype, G, u, p, rng, hash)) == 0) + (rc = dsa_setup(dsapriv_pytype, G, u, p, rng, hash, dsa_calcpub)) == 0) goto end; end: return (rc); } -static PyMethodDef dsapub_pymethods[] = { +static const PyMethodDef dsapub_pymethods[] = { #define METHNAME(name) dsameth_##name - METH (beginhash, "D.beginhash() -> hash object") - METH (endhash, "D.endhash(H) -> BYTES") - METH (verify, "D.verify(MSG, (R, S)) -> true/false") + NAMETH(beginhash, "D.beginhash() -> hash object") + METH (endhash, "D.endhash(H) -> BYTES") + METH (verify, "D.verify(MSG, (R, S)) -> true/false") #undef METHNAME { 0 } }; -static PyMethodDef dsapriv_pymethods[] = { +static const PyMethodDef dsapriv_pymethods[] = { #define METHNAME(name) dsameth_##name - KWMETH(sign, "D.sign(MSG, k = K) -> R, S") + KWMETH(sign, "D.sign(MSG, [k = K]) -> R, S") #undef METHNAME { 0 } }; -static PyMemberDef dsapub_pymembers[] = { +static const PyMemberDef dsapub_pymembers[] = { #define MEMBERSTRUCT dsa_pyobj MEMBER(G, T_OBJECT, READONLY, "D.G -> group to work in") MEMBER(p, T_OBJECT, READONLY, "D.p -> public key (group element") @@ -201,15 +209,15 @@ static PyMemberDef dsapub_pymembers[] = { { 0 } }; -static PyMemberDef dsapriv_pymembers[] = { +static const PyMemberDef dsapriv_pymembers[] = { #define MEMBERSTRUCT dsa_pyobj MEMBER(u, T_OBJECT, READONLY, "D.u -> private key (exponent)") #undef MEMBERSTRUCT { 0 } }; -static PyTypeObject dsapub_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject dsapub_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "DSAPub", /* @tp_name@ */ sizeof(dsa_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -233,7 +241,7 @@ static PyTypeObject dsapub_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"DSA public key information.", + "DSAPub(GROUP, P, [hash = sha], [rng = rand]): DSA public key.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ @@ -241,8 +249,8 @@ static PyTypeObject dsapub_pytype_skel = { 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ 0, /* @tp_iternext@ */ - dsapub_pymethods, /* @tp_methods@ */ - dsapub_pymembers, /* @tp_members@ */ + PYMETHODS(dsapub), /* @tp_methods@ */ + PYMEMBERS(dsapub), /* @tp_members@ */ 0, /* @tp_getset@ */ 0, /* @tp_base@ */ 0, /* @tp_dict@ */ @@ -256,8 +264,8 @@ static PyTypeObject dsapub_pytype_skel = { 0 /* @tp_is_gc@ */ }; -static PyTypeObject dsapriv_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject dsapriv_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "DSAPriv", /* @tp_name@ */ sizeof(dsa_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -281,7 +289,8 @@ static PyTypeObject dsapriv_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"DSA private key information.", + "DSAPriv(GROUP, U, [p = u G], [hash = sha], [rng = rand]): " + "DSA private key.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ @@ -289,8 +298,8 @@ static PyTypeObject dsapriv_pytype_skel = { 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ 0, /* @tp_iternext@ */ - dsapriv_pymethods, /* @tp_methods@ */ - dsapriv_pymembers, /* @tp_members@ */ + PYMETHODS(dsapriv), /* @tp_methods@ */ + PYMEMBERS(dsapriv), /* @tp_members@ */ 0, /* @tp_getset@ */ 0, /* @tp_base@ */ 0, /* @tp_dict@ */ @@ -307,46 +316,50 @@ static PyTypeObject dsapriv_pytype_skel = { static PyObject *kcdsapub_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { - PyObject *G, *p, *u = 0, *rng = rand_pyobj, *hash = has160_pyobj; + PyObject *G, *p, *rng = rand_pyobj, *hash = has160_pyobj; PyObject *rc = 0; - char *kwlist[] = { "G", "p", "u", "hash", "rng", 0 }; + static const char *const kwlist[] = { "G", "p", "hash", "rng", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!O!O|O!O!:new", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!O!|O!O!:new", KWLIST, group_pytype, &G, ge_pytype, &p, - &u, gchash_pytype, &hash, grand_pytype, &rng) || - (rc = dsa_setup(kcdsapub_pytype, G, u, p, rng, hash)) == 0) + (rc = dsa_setup(kcdsapub_pytype, G, 0, p, rng, hash, 0)) == 0) goto end; end: return (rc); } +static void kcdsa_calcpub(group *g, ge *p, mp *u) +{ + mp *uinv = mp_modinv(MP_NEW, u, g->r); + G_EXP(g, p, g->g, uinv); + mp_drop(uinv); +} + static PyObject *kcdsapriv_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { - PyObject *G, *p, *u = Py_None, *rng = rand_pyobj, *hash = has160_pyobj; + PyObject *G, *u, *p = 0, *rng = rand_pyobj, *hash = has160_pyobj; PyObject *rc = 0; - char *kwlist[] = { "G", "p", "u", "hash", "rng", 0 }; + static const char *const kwlist[] = { "G", "u", "p", "hash", "rng", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!O!|OO!O!:new", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!O|O!O!O!:new", KWLIST, group_pytype, &G, - ge_pytype, &p, &u, + ge_pytype, &p, gchash_pytype, &hash, grand_pytype, &rng) || - (rc = dsa_setup(kcdsapriv_pytype, G, u, p, rng, hash)) == 0) + (rc = dsa_setup(kcdsapriv_pytype, G, u, p, + rng, hash, kcdsa_calcpub)) == 0) goto end; end: return (rc); } -static PyObject *kcdsameth_beginhash(PyObject *me, PyObject *arg) -{ - if (!PyArg_ParseTuple(arg, ":beginhash")) return (0); - return (ghash_pywrap(DSA_HASH(me), gkcdsa_beginhash(DSA_D(me)), f_freeme)); -} +static PyObject *kcdsameth_beginhash(PyObject *me) + { return (ghash_pywrap(DSA_HASH(me), gkcdsa_beginhash(DSA_D(me)))); } static PyObject *kcdsameth_endhash(PyObject *me, PyObject *arg) { @@ -356,7 +369,7 @@ static PyObject *kcdsameth_endhash(PyObject *me, PyObject *arg) gkcdsa_endhash(DSA_D(me), h); h = GH_COPY(h); rc = bytestring_pywrap(0, GH_CLASS(h)->hashsz); - GH_DONE(h, PyString_AS_STRING(rc)); + GH_DONE(h, BIN_PTR(rc)); GH_DESTROY(h); return (rc); } @@ -364,20 +377,19 @@ static PyObject *kcdsameth_endhash(PyObject *me, PyObject *arg) static PyObject *kcdsameth_sign(PyObject *me, PyObject *arg, PyObject *kw) { gkcdsa_sig s = GKCDSA_SIG_INIT; - char *p; - Py_ssize_t n; + struct bin h; mp *k = 0; PyObject *r = 0, *rc = 0; - char *kwlist[] = { "msg", "k", 0 }; + static const char *const kwlist[] = { "msg", "k", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#|O&:sign", kwlist, - &p, &n, convmp, &k)) + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&:sign", KWLIST, + convbin, &h, convmp, &k)) goto end; - if (n != DSA_D(me)->h->hashsz) + if (h.sz != DSA_D(me)->h->hashsz) VALERR("bad message length (doesn't match hash size)"); r = bytestring_pywrap(0, DSA_D(me)->h->hashsz); - s.r = (octet *)PyString_AS_STRING(r); - gkcdsa_sign(DSA_D(me), &s, p, k); + s.r = (octet *)BIN_PTR(r); + gkcdsa_sign(DSA_D(me), &s, h.p, k); rc = Py_BuildValue("(ON)", r, mp_pywrap(s.s)); end: Py_XDECREF(r); @@ -387,42 +399,42 @@ end: static PyObject *kcdsameth_verify(PyObject *me, PyObject *arg) { - char *p; - Py_ssize_t n, rn; + struct bin h, sr; gkcdsa_sig s = GKCDSA_SIG_INIT; PyObject *rc = 0; - if (!PyArg_ParseTuple(arg, "s#(s#O&):verify", - &p, &n, &s.r, &rn, convmp, &s.s)) + if (!PyArg_ParseTuple(arg, "O&(O&O&):verify", + convbin, &h, convbin, &sr, convmp, &s.s)) goto end; - if (n != DSA_D(me)->h->hashsz) + if (h.sz != DSA_D(me)->h->hashsz) VALERR("bad message length (doesn't match hash size)"); - if (rn != DSA_D(me)->h->hashsz) + if (sr.sz != DSA_D(me)->h->hashsz) VALERR("bad signature `r' length (doesn't match hash size)"); - rc = getbool(!gkcdsa_verify(DSA_D(me), &s, p)); + s.r = (/*unconst*/ octet *)sr.p; + rc = getbool(!gkcdsa_verify(DSA_D(me), &s, h.p)); end: mp_drop(s.s); return (rc); } -static PyMethodDef kcdsapub_pymethods[] = { +static const PyMethodDef kcdsapub_pymethods[] = { #define METHNAME(name) kcdsameth_##name - METH (beginhash, "D.beginhash() -> hash object") - METH (endhash, "D.endhash(H) -> BYTES") - METH (verify, "D.verify(MSG, (R, S)) -> true/false") + NAMETH(beginhash, "D.beginhash() -> hash object") + METH (endhash, "D.endhash(H) -> BYTES") + METH (verify, "D.verify(MSG, (R, S)) -> true/false") #undef METHNAME { 0 } }; -static PyMethodDef kcdsapriv_pymethods[] = { +static const PyMethodDef kcdsapriv_pymethods[] = { #define METHNAME(name) kcdsameth_##name - KWMETH(sign, "D.sign(MSG, k = K) -> R, S") + KWMETH(sign, "D.sign(MSG, [k = K]) -> R, S") #undef METHNAME { 0 } }; -static PyTypeObject kcdsapub_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject kcdsapub_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "KCDSAPub", /* @tp_name@ */ sizeof(dsa_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -446,7 +458,7 @@ static PyTypeObject kcdsapub_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"KCDSA public key information.", + "KCDSAPub(GROUP, P, [hash = sha], [rng = rand]): KCDSA public key.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ @@ -454,8 +466,8 @@ static PyTypeObject kcdsapub_pytype_skel = { 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ 0, /* @tp_iternext@ */ - kcdsapub_pymethods, /* @tp_methods@ */ - dsapub_pymembers, /* @tp_members@ */ + PYMETHODS(kcdsapub), /* @tp_methods@ */ + PYMEMBERS(dsapub), /* @tp_members@ */ 0, /* @tp_getset@ */ 0, /* @tp_base@ */ 0, /* @tp_dict@ */ @@ -469,8 +481,8 @@ static PyTypeObject kcdsapub_pytype_skel = { 0 /* @tp_is_gc@ */ }; -static PyTypeObject kcdsapriv_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject kcdsapriv_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "KCDSAPriv", /* @tp_name@ */ sizeof(dsa_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -494,7 +506,8 @@ static PyTypeObject kcdsapriv_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"KCDSA private key information.", + "KCDSAPriv(GROUP, U, [p = u G], [hash = sha], [rng = rand]): " + "KCDSA private key.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ @@ -502,8 +515,8 @@ static PyTypeObject kcdsapriv_pytype_skel = { 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ 0, /* @tp_iternext@ */ - kcdsapriv_pymethods, /* @tp_methods@ */ - dsapriv_pymembers, /* @tp_members@ */ + PYMETHODS(kcdsapriv), /* @tp_methods@ */ + PYMEMBERS(dsapriv), /* @tp_members@ */ 0, /* @tp_getset@ */ 0, /* @tp_base@ */ 0, /* @tp_dict@ */ @@ -548,9 +561,9 @@ static PyObject *rsapub_pynew(PyTypeObject *ty, { rsa_pub rp = { 0 }; rsapub_pyobj *o; - char *kwlist[] = { "n", "e", 0 }; + static const char *const kwlist[] = { "n", "e", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&:new", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&:new", KWLIST, convmp, &rp.n, convmp, &rp.e)) goto end; if (!MP_ODDP(rp.n)) VALERR("RSA modulus must be even"); @@ -615,10 +628,10 @@ static PyObject *rsapriv_pynew(PyTypeObject *ty, { rsa_priv rp = { 0 }; PyObject *rng = Py_None; - char *kwlist[] = + static const char *const kwlist[] = { "n", "e", "d", "p", "q", "dp", "dq", "q_inv", "rng", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&O&O&O&O&O&O&O&O:new", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&O&O&O&O&O&O&O&O:new", KWLIST, convmp, &rp.n, convmp, &rp.e, convmp, &rp.d, convmp, &rp.p, convmp, &rp.q, @@ -628,7 +641,7 @@ static PyObject *rsapriv_pynew(PyTypeObject *ty, goto end; if ((rp.n && !MP_ODDP(rp.n)) || (rp.p && !MP_ODDP(rp.p)) || - (rp.p && !MP_ODDP(rp.q))) + (rp.q && !MP_ODDP(rp.q))) VALERR("RSA modulus and factors must be odd"); if (rsa_recover(&rp)) VALERR("couldn't construct private key"); if (rng != Py_None && !GRAND_PYCHECK(rng)) @@ -690,9 +703,9 @@ static PyObject *rsameth_privop(PyObject *me, PyObject *arg, PyObject *kw) PyObject *rng = RSA_RNG(me); mp *x = 0; PyObject *rc = 0; - char *kwlist[] = { "x", "rng", 0 }; + static const char *const kwlist[] = { "x", "rng", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O:privop", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O:privop", KWLIST, convmp, &x, &rng)) goto end; if (rng != Py_None && !GRAND_PYCHECK(rng)) @@ -704,66 +717,75 @@ end: return (rc); } -static PyObject *meth__RSAPriv_generate(PyObject *me, - PyObject *arg, PyObject *kw) +static PyObject *rsameth_generate(PyObject *me, PyObject *arg, PyObject *kw) { grand *r = &rand_global; unsigned nbits; unsigned n = 0; rsa_priv rp; - pgev evt = { 0 }; - char *kwlist[] = { "class", "nbits", "event", "rng", "nsteps", 0 }; + mp *e = 0; + struct excinfo exc = EXCINFO_INIT; + pypgev evt = { { 0 } }; + static const char *const kwlist[] = + { "nbits", "event", "rng", "nsteps", "e", 0 }; PyObject *rc = 0; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&|O&O&O&:generate", kwlist, - &me, convuint, &nbits, convpgev, &evt, - convgrand, &r, convuint, &n)) + evt.exc = &exc; + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&O&O&O&:generate", KWLIST, + convuint, &nbits, convpgev, &evt, + convgrand, &r, convuint, &n, + convmp, &e)) goto end; - if (rsa_gen(&rp, nbits, r, n, evt.proc, evt.ctx)) - PGENERR; + if (e) MP_COPY(e); + else e = mp_fromulong(MP_NEW, 65537); + if (rsa_gen_e(&rp, nbits, e, r, n, evt.ev.proc, evt.ev.ctx)) + PGENERR(&exc); rc = rsapriv_pywrap(&rp); end: droppgev(&evt); + mp_drop(e); return (rc); } -static PyGetSetDef rsapub_pygetset[] = { +static const PyGetSetDef rsapub_pygetset[] = { #define GETSETNAME(op, name) rsa##op##_##name - GET (n, "R.n -> N") - GET (e, "R.e -> E") + GET (n, "R.n -> N") + GET (e, "R.e -> E") #undef GETSETNAME { 0 } }; -static PyMethodDef rsapub_pymethods[] = { +static const PyMethodDef rsapub_pymethods[] = { #define METHNAME(name) rsameth_##name - METH (pubop, "R.pubop(X) -> X^E (mod N)") + METH (pubop, "R.pubop(X) -> X^E (mod N)") #undef METHNAME { 0 } }; -static PyGetSetDef rsapriv_pygetset[] = { +static const PyGetSetDef rsapriv_pygetset[] = { #define GETSETNAME(op, name) rsa##op##_##name - GET (d, "R.d -> D") - GET (p, "R.p -> P") - GET (q, "R.q -> Q") - GET (dp, "R.dp -> D mod (P - 1)") - GET (dq, "R.dq -> D mod (Q - 1)") - GET (q_inv, "R.q_inv -> Q^{-1} mod P") - GETSET(rng, "R.rng -> random number source for blinding") + GET (d, "R.d -> D") + GET (p, "R.p -> P") + GET (q, "R.q -> Q") + GET (dp, "R.dp -> D mod (P - 1)") + GET (dq, "R.dq -> D mod (Q - 1)") + GET (q_inv, "R.q_inv -> Q^{-1} mod P") + GETSET(rng, "R.rng -> random number source for blinding") #undef GETSETNAME { 0 } }; -static PyMethodDef rsapriv_pymethods[] = { +static const PyMethodDef rsapriv_pymethods[] = { #define METHNAME(name) rsameth_##name - KWMETH(privop, "R.privop(X, rng = None) -> X^D (mod N)") + KWMETH(privop, "R.privop(X, [rng = None]) -> X^D (mod N)") + KWSMTH(generate, "generate(NBITS, [event = pgen_nullev], [rng = rand], " + "[nsteps = 0]) -> R") #undef METHNAME { 0 } }; -static PyTypeObject rsapub_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject rsapub_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "RSAPub", /* @tp_name@ */ sizeof(rsapub_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -787,7 +809,7 @@ static PyTypeObject rsapub_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"RSA public key information.", + "RSAPub(N, E): RSA public key.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ @@ -795,9 +817,9 @@ static PyTypeObject rsapub_pytype_skel = { 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ 0, /* @tp_iternext@ */ - rsapub_pymethods, /* @tp_methods@ */ + PYMETHODS(rsapub), /* @tp_methods@ */ 0, /* @tp_members@ */ - rsapub_pygetset, /* @tp_getset@ */ + PYGETSET(rsapub), /* @tp_getset@ */ 0, /* @tp_base@ */ 0, /* @tp_dict@ */ 0, /* @tp_descr_get@ */ @@ -810,8 +832,8 @@ static PyTypeObject rsapub_pytype_skel = { 0 /* @tp_is_gc@ */ }; -static PyTypeObject rsapriv_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject rsapriv_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "RSAPriv", /* @tp_name@ */ sizeof(rsapriv_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -835,7 +857,8 @@ static PyTypeObject rsapriv_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"RSA private key information.", + "RSAPriv(..., [rng = rand]): RSA private key.\n" + " Keywords: n, e, d, p, q, dp, dq, q_inv; must provide enough", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ @@ -843,9 +866,9 @@ static PyTypeObject rsapriv_pytype_skel = { 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ 0, /* @tp_iternext@ */ - rsapriv_pymethods, /* @tp_methods@ */ + PYMETHODS(rsapriv), /* @tp_methods@ */ 0, /* @tp_members@ */ - rsapriv_pygetset, /* @tp_getset@ */ + PYGETSET(rsapriv), /* @tp_getset@ */ 0, /* @tp_base@ */ 0, /* @tp_dict@ */ 0, /* @tp_descr_get@ */ @@ -864,25 +887,24 @@ static PyObject *meth__p1crypt_encode(PyObject *me, PyObject *arg, PyObject *kw) { pkcs1 p1; - char *m, *ep; - Py_ssize_t msz, epsz; + struct bin m, ep = { 0, 0 }; unsigned long nbits; PyObject *rc = 0; octet *b = 0; size_t sz; mp *x; - char *kwlist[] = { "msg", "nbits", "ep", "rng", 0 }; + static const char *const kwlist[] = { "msg", "nbits", "ep", "rng", 0 }; - p1.r = &rand_global; ep = 0; epsz = 0; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#O&|s#O&:encode", kwlist, - &m, &msz, convulong, &nbits, - &ep, &epsz, convgrand, &p1.r)) + p1.r = &rand_global; + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|O&O&:encode", KWLIST, + convbin, &m, convulong, &nbits, + convbin, &ep, convgrand, &p1.r)) goto end; sz = (nbits + 7)/8; - p1.ep = ep; p1.epsz = epsz; - if (epsz + msz + 11 > sz) VALERR("buffer underflow"); + p1.ep = ep.p; p1.epsz = ep.sz; + if (ep.sz + m.sz + 11 > sz) VALERR("buffer underflow"); b = xmalloc(sz); - x = pkcs1_cryptencode(MP_NEW, m, msz, b, sz, nbits, &p1); + x = pkcs1_cryptencode(MP_NEW, m.p, m.sz, b, sz, nbits, &p1); rc = mp_pywrap(x); end: xfree(b); @@ -893,24 +915,23 @@ static PyObject *meth__p1crypt_decode(PyObject *me, PyObject *arg, PyObject *kw) { pkcs1 p1; - char *ep; - Py_ssize_t epsz; + struct bin ep = { 0, 0 }; unsigned long nbits; int n; PyObject *rc = 0; octet *b = 0; size_t sz; mp *x = 0; - char *kwlist[] = { "ct", "nbits", "ep", "rng", 0 }; + static const char *const kwlist[] = { "ct", "nbits", "ep", "rng", 0 }; - p1.r = &rand_global; ep = 0; epsz = 0; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|s#O&:decode", kwlist, + p1.r = &rand_global; + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|O&O&:decode", KWLIST, convmp, &x, convulong, &nbits, - &ep, &epsz, convgrand, &p1.r)) + convbin, &ep, convgrand, &p1.r)) goto end; sz = (nbits + 7)/8; - p1.ep = ep; p1.epsz = epsz; - if (epsz + 11 > sz) VALERR("buffer underflow"); + p1.ep = ep.p; p1.epsz = ep.sz; + if (ep.sz + 11 > sz) VALERR("buffer underflow"); b = xmalloc(sz); if ((n = pkcs1_cryptdecode(x, b, sz, nbits, &p1)) < 0) VALERR("decryption failed"); @@ -925,25 +946,24 @@ static PyObject *meth__p1sig_encode(PyObject *me, PyObject *arg, PyObject *kw) { pkcs1 p1; - char *m, *ep; - Py_ssize_t msz, epsz; + struct bin m, ep = { 0, 0 }; unsigned long nbits; PyObject *rc = 0; octet *b = 0; size_t sz; mp *x; - char *kwlist[] = { "msg", "nbits", "ep", "rng", 0 }; + static const char *const kwlist[] = { "msg", "nbits", "ep", "rng", 0 }; - p1.r = &rand_global; ep = 0; epsz = 0; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#O&|s#O&:encode", kwlist, - &m, &msz, convulong, &nbits, - &ep, &epsz, convgrand, &p1.r)) + p1.r = &rand_global; + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|O&O&:encode", KWLIST, + convbin, &m, convulong, &nbits, + convbin, &ep, convgrand, &p1.r)) goto end; sz = (nbits + 7)/8; - p1.ep = ep; p1.epsz = epsz; - if (epsz + msz + 11 > sz) VALERR("buffer underflow"); + p1.ep = ep.p; p1.epsz = ep.sz; + if (ep.sz + m.sz + 11 > sz) VALERR("buffer underflow"); b = xmalloc(sz); - x = pkcs1_sigencode(MP_NEW, m, msz, b, sz, nbits, &p1); + x = pkcs1_sigencode(MP_NEW, m.p, m.sz, b, sz, nbits, &p1); rc = mp_pywrap(x); end: xfree(b); @@ -954,8 +974,7 @@ static PyObject *meth__p1sig_decode(PyObject *me, PyObject *arg, PyObject *kw) { pkcs1 p1; - char *ep; - Py_ssize_t epsz; + struct bin ep = { 0, 0 }; unsigned long nbits; int n; PyObject *hukairz; @@ -963,16 +982,17 @@ static PyObject *meth__p1sig_decode(PyObject *me, octet *b = 0; size_t sz; mp *x = 0; - char *kwlist[] = { "msg", "sig", "nbits", "ep", "rng", 0 }; + static const char *const kwlist[] = + { "msg", "sig", "nbits", "ep", "rng", 0 }; - p1.r = &rand_global; ep = 0; epsz = 0; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&O&|s#O&:decode", kwlist, + p1.r = &rand_global; + if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&O&|O&O&:decode", KWLIST, &hukairz, convmp, &x, convulong, &nbits, - &ep, &epsz, convgrand, &p1.r)) + convbin, &ep, convgrand, &p1.r)) goto end; sz = (nbits + 7)/8; - p1.ep = ep; p1.epsz = epsz; - if (epsz + 10 > sz) VALERR("buffer underflow"); + p1.ep = ep.p; p1.epsz = ep.sz; + if (ep.sz + 10 > sz) VALERR("buffer underflow"); b = xmalloc(sz); if ((n = pkcs1_sigdecode(x, 0, 0, b, sz, nbits, &p1)) < 0) VALERR("verification failed"); @@ -987,28 +1007,29 @@ static PyObject *meth__oaep_encode(PyObject *me, PyObject *arg, PyObject *kw) { oaep o; - char *m, *ep; - Py_ssize_t msz, epsz; + struct bin m, ep = { 0, 0 }; unsigned long nbits; PyObject *rc = 0; octet *b = 0; size_t sz; mp *x; - char *kwlist[] = { "msg", "nbits", "mgf", "hash", "ep", "rng", 0 }; + static const char *const kwlist[] = + { "msg", "nbits", "mgf", "hash", "ep", "rng", 0 }; - o.r = &rand_global; o.cc = &sha_mgf; o.ch = &sha; ep = 0; epsz = 0; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#O&|O&O&s#O&:encode", kwlist, - &m, &msz, convulong, &nbits, + o.r = &rand_global; o.cc = &sha_mgf; o.ch = &sha; + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|O&O&O&O&:encode", + KWLIST, + convbin, &m, convulong, &nbits, convgccipher, &o.cc, convgchash, &o.ch, - &ep, &epsz, + convbin, &ep, convgrand, &o.r)) goto end; sz = (nbits + 7)/8; - o.ep = ep; o.epsz = epsz; - if (2 * o.ch->hashsz + 2 + msz > sz) VALERR("buffer underflow"); + o.ep = ep.p; o.epsz = ep.sz; + if (2 * o.ch->hashsz + 2 + m.sz > sz) VALERR("buffer underflow"); b = xmalloc(sz); - x = oaep_encode(MP_NEW, m, msz, b, sz, nbits, &o); + x = oaep_encode(MP_NEW, m.p, m.sz, b, sz, nbits, &o); rc = mp_pywrap(x); end: xfree(b); @@ -1019,26 +1040,26 @@ static PyObject *meth__oaep_decode(PyObject *me, PyObject *arg, PyObject *kw) { oaep o; - char *ep; - Py_ssize_t epsz; + struct bin ep = { 0, 0 }; unsigned long nbits; int n; PyObject *rc = 0; octet *b = 0; size_t sz; mp *x = 0; - char *kwlist[] = { "ct", "nbits", "mgf", "hash", "ep", "rng", 0 }; + static const char *const kwlist[] = + { "ct", "nbits", "mgf", "hash", "ep", "rng", 0 }; - o.r = &rand_global; o.cc = &sha_mgf; o.ch = &sha; ep = 0; epsz = 0; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|O&O&s#O&:decode", kwlist, + o.r = &rand_global; o.cc = &sha_mgf; o.ch = &sha; + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|O&O&O&O&:decode", KWLIST, convmp, &x, convulong, &nbits, convgccipher, &o.cc, convgchash, &o.ch, - &ep, &epsz, + convbin, &ep, convgrand, &o.r)) goto end; sz = (nbits + 7)/8; - o.ep = ep; o.epsz = epsz; + o.ep = ep.p; o.epsz = ep.sz; if (2 * o.ch->hashsz > sz) VALERR("buffer underflow"); b = xmalloc(sz); if ((n = oaep_decode(x, b, sz, nbits, &o)) < 0) @@ -1054,18 +1075,18 @@ static PyObject *meth__pss_encode(PyObject *me, PyObject *arg, PyObject *kw) { pss p; - char *m; - Py_ssize_t msz; + struct bin m; unsigned long nbits; PyObject *rc = 0; octet *b = 0; size_t sz; mp *x = 0; - char *kwlist[] = { "msg", "nbits", "mgf", "hash", "saltsz", "rng", 0 }; + static const char *const kwlist[] = + { "msg", "nbits", "mgf", "hash", "saltsz", "rng", 0 }; p.cc = &sha_mgf; p.ch = &sha; p.r = &rand_global; p.ssz = (size_t)-1; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#O&|O&O&O&O&:encode", kwlist, - &m, &msz, convulong, &nbits, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|O&O&O&O&:encode", KWLIST, + convbin, &m, convulong, &nbits, convgccipher, &p.cc, convgchash, &p.ch, convszt, &p.ssz, @@ -1075,7 +1096,7 @@ static PyObject *meth__pss_encode(PyObject *me, if (p.ssz == (size_t)-1) p.ssz = p.ch->hashsz; if (p.ch->hashsz + p.ssz + 2 > sz) VALERR("buffer underflow"); b = xmalloc(sz); - x = pss_encode(MP_NEW, m, msz, b, sz, nbits, &p); + x = pss_encode(MP_NEW, m.p, m.sz, b, sz, nbits, &p); rc = mp_pywrap(x); end: xfree(b); @@ -1086,20 +1107,21 @@ static PyObject *meth__pss_decode(PyObject *me, PyObject *arg, PyObject *kw) { pss p; - char *m; - Py_ssize_t msz; + struct bin m; unsigned long nbits; PyObject *rc = 0; octet *b = 0; size_t sz; int n; mp *x = 0; - char *kwlist[] = + static const char *const kwlist[] = { "msg", "sig", "nbits", "mgf", "hash", "saltsz", "rng", 0 }; p.cc = &sha_mgf; p.ch = &sha; p.r = &rand_global; p.ssz = (size_t)-1; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#O&O&|O&O&O&O&:decode", kwlist, - &m, &msz, convmp, &x, convulong, &nbits, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&O&|O&O&O&O&:decode", + KWLIST, + convbin, &m, convmp, &x, + convulong, &nbits, convgccipher, &p.cc, convgchash, &p.ch, convszt, &p.ssz, @@ -1109,7 +1131,7 @@ static PyObject *meth__pss_decode(PyObject *me, if (p.ssz == (size_t)-1) p.ssz = p.ch->hashsz; if (p.ch->hashsz + p.ssz + 2 > sz) VALERR("buffer underflow"); b = xmalloc(sz); - if ((n = pss_decode(x, m, msz, b, sz, nbits, &p)) < 0) + if ((n = pss_decode(x, m.p, m.sz, b, sz, nbits, &p)) < 0) VALERR("verification failed"); rc = Py_None; Py_INCREF(rc); end: @@ -1118,40 +1140,143 @@ end: return (rc); } -/*----- X25519 ------------------------------------------------------------*/ - -static PyObject *meth_x25519(PyObject *me, PyObject *arg) -{ - const char *k, *p; - Py_ssize_t ksz, psz; - PyObject *rc = 0; - if (!PyArg_ParseTuple(arg, "s#s#:x25519", &k, &ksz, &p, &psz)) goto end; - if (ksz != X25519_KEYSZ) VALERR("bad key length"); - if (psz != X25519_PUBSZ) VALERR("bad public length"); - rc = bytestring_pywrap(0, X25519_OUTSZ); - x25519((octet *)PyString_AS_STRING(rc), - (const octet *)k, (const octet *)p); - return (rc); -end: - return (0); -} +/*----- X25519 and related algorithms -------------------------------------*/ + +#define XDHS(_) \ + _(X25519, x25519) \ + _(X448, x448) + +#define DEFXDH(X, x) \ + static PyObject *meth_##x(PyObject *me, PyObject *arg) \ + { \ + struct bin k, p; \ + PyObject *rc = 0; \ + if (!PyArg_ParseTuple(arg, "O&O&:" #x, convbin, &k, convbin, &p)) \ + goto end; \ + if (k.sz != X##_KEYSZ) VALERR("bad key length"); \ + if (p.sz != X##_PUBSZ) VALERR("bad public length"); \ + rc = bytestring_pywrap(0, X##_OUTSZ); \ + x((octet *)BIN_PTR(rc), k.p, p.p); \ + return (rc); \ + end: \ + return (0); \ + } +XDHS(DEFXDH) +#undef DEFXDH + +/*----- Ed25519 and related algorithms ------------------------------------*/ + +#define EDDSAS(_) \ + _(ED25519, ed25519, -1, ctx) \ + _(ED448, ed448, 0, ) + +#define DEFEDDSA(ED, ed, phdflt, sigver) \ + \ + static PyObject *meth_##ed##_pubkey(PyObject *me, PyObject *arg) \ + { \ + struct bin k; \ + PyObject *rc = 0; \ + if (!PyArg_ParseTuple(arg, "O&:" #ed "_pubkey", convbin, &k)) \ + goto end; \ + rc = bytestring_pywrap(0, ED##_PUBSZ); \ + ed##_pubkey((octet *)BIN_PTR(rc), k.p, k.sz); \ + return (rc); \ + end: \ + return (0); \ + } \ + \ + static PyObject *meth_##ed##_sign(PyObject *me, PyObject *arg, \ + PyObject *kw) \ + { \ + struct bin k, p = { 0, 0}, c = { 0, 0 }, m; \ + int ph = phdflt; \ + PyObject *rc = 0; \ + octet pp[ED##_PUBSZ]; \ + static const char *const kwlist[] = \ + { "key", "msg", "pub", "perso", "phflag", 0 }; \ + if (!PyArg_ParseTupleAndKeywords(arg, kw, \ + "O&O&|O&O&O&:" #ed "_sign", \ + KWLIST, \ + convbin, &k, convbin, &m, \ + convbin, &p, convbin, &c, \ + convbool, &ph)) \ + goto end; \ + if (p.p && p.sz != ED##_PUBSZ) VALERR("bad public length"); \ + if (c.p && c.sz > ED##_MAXPERSOSZ) \ + VALERR("personalization string too long"); \ + if (c.p && ph == -1) ph = 0; \ + if (!p.p) { p.p = pp; ed##_pubkey(pp, k.p, k.sz); } \ + rc = bytestring_pywrap(0, ED##_SIGSZ); \ + ed##sigver##_sign((octet *)BIN_PTR(rc), k.p, k.sz, \ + p.p, ph, c.p, c.sz, m.p, m.sz); \ + return (rc); \ + end: \ + return (0); \ + } \ + \ + static PyObject *meth_##ed##_verify(PyObject *me, \ + PyObject *arg, PyObject *kw) \ + { \ + struct bin p, c = { 0, 0 }, m, s; \ + int ph = phdflt; \ + PyObject *rc = 0; \ + static const char *const kwlist[] = \ + { "pub", "msg", "sig", "perso", "phflag", 0 }; \ + if (!PyArg_ParseTupleAndKeywords(arg, kw, \ + "O&O&O&|O&O&:" #ed "_verify", \ + KWLIST, \ + convbin, &p, convbin, &m, \ + convbin, &s, \ + convbin, &c, convbool, &ph)) \ + goto end; \ + if (p.sz != ED##_PUBSZ) VALERR("bad public length"); \ + if (s.sz != ED##_SIGSZ) VALERR("bad signature length"); \ + if (c.p && c.sz > ED##_MAXPERSOSZ) \ + VALERR("personalization string too long"); \ + if (c.p && ph == -1) ph = 0; \ + rc = getbool(!ed##sigver##_verify(p.p, ph, c.p, c.sz, \ + m.p, m.sz, s.p)); \ + return (rc); \ + end: \ + return (0); \ + } +EDDSAS(DEFEDDSA) +#undef DEFEDDSA /*----- Global stuff ------------------------------------------------------*/ -static PyMethodDef methods[] = { +static const struct nameval consts[] = { + CONST(X25519_KEYSZ), CONST(X25519_PUBSZ), CONST(X25519_OUTSZ), + CONST(X448_KEYSZ), CONST(X448_PUBSZ), CONST(X448_OUTSZ), + CONST(ED25519_KEYSZ), CONST(ED25519_PUBSZ), CONST(ED25519_SIGSZ), + CONST(ED25519_MAXPERSOSZ), + CONST(ED448_KEYSZ), CONST(ED448_PUBSZ), CONST(ED448_SIGSZ), + CONST(ED448_MAXPERSOSZ), + { 0 } +}; + +static const PyMethodDef methods[] = { #define METHNAME(name) meth_##name - KWMETH(_p1crypt_encode, 0) - KWMETH(_p1crypt_decode, 0) - KWMETH(_p1sig_encode, 0) - KWMETH(_p1sig_decode, 0) - KWMETH(_oaep_encode, 0) - KWMETH(_oaep_decode, 0) - KWMETH(_pss_encode, 0) - KWMETH(_pss_decode, 0) - KWMETH(_RSAPriv_generate, "\ -generate(NBITS, [event = pgen_nullev, rng = rand, nsteps = 0]) -> R") - METH (x25519, "\ -x25519(KEY, PUBLIC) -> SHARED") + KWMETH(_p1crypt_encode, 0) + KWMETH(_p1crypt_decode, 0) + KWMETH(_p1sig_encode, 0) + KWMETH(_p1sig_decode, 0) + KWMETH(_oaep_encode, 0) + KWMETH(_oaep_decode, 0) + KWMETH(_pss_encode, 0) + KWMETH(_pss_decode, 0) +#define DEFMETH(X, x) \ + METH (x, "" #x "(KEY, PUBLIC) -> SHARED") + XDHS(DEFMETH) +#undef DEFMETH +#define DEFMETH(ED, ed, phdflt, sigver) \ + METH (ed##_pubkey, "" #ed "_pubkey(KEY) -> PUBLIC") \ + KWMETH(ed##_sign, "" #ed "_sign(KEY, MSG, [pub = PUBLIC], " \ + "[perso = STRING], [phflag = BOOL]) -> SIG") \ + KWMETH(ed##_verify, "" #ed "_verify(PUBLIC, MSG, SIG, " \ + "[perso = STRING], [phflag = BOOL]) -> BOOL") + EDDSAS(DEFMETH) +#undef DEFMETH #undef METHNAME { 0 } }; @@ -1175,6 +1300,7 @@ void pubkey_pyinsert(PyObject *mod) INSERT("KCDSAPriv", kcdsapriv_pytype); INSERT("RSAPub", rsapub_pytype); INSERT("RSAPriv", rsapriv_pytype); + setconstants(mod, consts); } /*----- That's all, folks -------------------------------------------------*/