X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/catacomb-python/blobdiff_plain/16178155513725d7fee6e61316c200aaed7eff17..f1b0cf0da6b3bcc530d7f72982278510d94f6456:/pubkey.c diff --git a/pubkey.c b/pubkey.c index 4067ae0..7374429 100644 --- a/pubkey.c +++ b/pubkey.c @@ -1137,88 +1137,106 @@ end: /*----- X25519 and related algorithms -------------------------------------*/ -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); -} - -static PyObject *meth_x448(PyObject *me, PyObject *arg) -{ - const char *k, *p; - Py_ssize_t ksz, psz; - PyObject *rc = 0; - if (!PyArg_ParseTuple(arg, "s#s#:x448", &k, &ksz, &p, &psz)) goto end; - if (ksz != X448_KEYSZ) VALERR("bad key length"); - if (psz != X448_PUBSZ) VALERR("bad public length"); - rc = bytestring_pywrap(0, X448_OUTSZ); - x448((octet *)PyString_AS_STRING(rc), - (const octet *)k, (const octet *)p); - return (rc); -end: - return (0); -} - -/*----- Ed25519 -----------------------------------------------------------*/ - -static PyObject *meth_ed25519_pubkey(PyObject *me, PyObject *arg) -{ - const char *k; - Py_ssize_t ksz; - PyObject *rc = 0; - if (!PyArg_ParseTuple(arg, "s#:ed25519_pubkey", &k, &ksz)) goto end; - rc = bytestring_pywrap(0, ED25519_PUBSZ); - ed25519_pubkey((octet *)PyString_AS_STRING(rc), k, ksz); - return (rc); -end: - return (0); -} - -static PyObject *meth_ed25519_sign(PyObject *me, PyObject *arg, PyObject *kw) -{ - const char *k, *p = 0, *m; - Py_ssize_t ksz, psz, msz; - PyObject *rc = 0; - octet pp[ED25519_PUBSZ]; - char *kwlist[] = { "key", "msg", "pub", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#s#|s#:ed25519_sign", kwlist, - &k, &ksz, &m, &msz, &p, &psz)) - goto end; - if (p && psz != ED25519_PUBSZ) VALERR("bad public length"); - if (!p) { p = (const char *)pp; ed25519_pubkey(pp, k, ksz); } - rc = bytestring_pywrap(0, ED25519_SIGSZ); - ed25519_sign((octet *)PyString_AS_STRING(rc), k, ksz, - (const octet *)p, m, msz); - return (rc); -end: - return (0); -} - -static PyObject *meth_ed25519_verify(PyObject *me, PyObject *arg) -{ - const char *p, *m, *s; - Py_ssize_t psz, msz, ssz; - PyObject *rc = 0; - if (!PyArg_ParseTuple(arg, "s#s#s#:ed25519_verify", - &p, &psz, &m, &msz, &s, &ssz)) - goto end; - if (psz != ED25519_PUBSZ) VALERR("bad public length"); - if (ssz != ED25519_SIGSZ) VALERR("bad signature length"); - rc = getbool(!ed25519_verify((const octet *)p, m, msz, (const octet *)s)); - return (rc); -end: - return (0); -} +#define XDHS(_) \ + _(X25519, x25519) \ + _(X448, x448) + +#define DEFXDH(X, x) \ + static PyObject *meth_##x(PyObject *me, PyObject *arg) \ + { \ + const char *k, *p; \ + Py_ssize_t ksz, psz; \ + PyObject *rc = 0; \ + if (!PyArg_ParseTuple(arg, "s#s#:" #x, &k, &ksz, &p, &psz)) \ + goto end; \ + if (ksz != X##_KEYSZ) VALERR("bad key length"); \ + if (psz != X##_PUBSZ) VALERR("bad public length"); \ + rc = bytestring_pywrap(0, X##_OUTSZ); \ + x((octet *)PyString_AS_STRING(rc), \ + (const octet *)k, (const octet *)p); \ + return (rc); \ + end: \ + return (0); \ + } +XDHS(DEFXDH) +#undef DEFXDH + +/*----- Ed25519 and related algorithms ------------------------------------*/ + +#define EDDSAS(_) \ + _(ED25519, ed25519, -1, ctx) + +#define DEFEDDSA(ED, ed, phdflt, sigver) \ + \ + static PyObject *meth_##ed##_pubkey(PyObject *me, PyObject *arg) \ + { \ + const char *k; \ + Py_ssize_t ksz; \ + PyObject *rc = 0; \ + if (!PyArg_ParseTuple(arg, "s#:" #ed "_pubkey", &k, &ksz)) \ + goto end; \ + rc = bytestring_pywrap(0, ED##_PUBSZ); \ + ed##_pubkey((octet *)PyString_AS_STRING(rc), k, ksz); \ + return (rc); \ + end: \ + return (0); \ + } \ + \ + static PyObject *meth_##ed##_sign(PyObject *me, PyObject *arg, \ + PyObject *kw) \ + { \ + const char *k, *p = 0, *c = 0, *m; \ + Py_ssize_t ksz, psz, csz = 0, msz; \ + int ph = phdflt; \ + PyObject *rc = 0; \ + octet pp[ED##_PUBSZ]; \ + char *kwlist[] = { "key", "msg", "pub", "perso", "phflag", 0 }; \ + if (!PyArg_ParseTupleAndKeywords(arg, kw, \ + "s#s#|s#s#O&:" #ed "_sign", \ + kwlist, \ + &k, &ksz, &m, &msz, &p, &psz, \ + &c, &csz, convbool, &ph)) \ + goto end; \ + if (p && psz != ED##_PUBSZ) VALERR("bad public length"); \ + if (c && csz > ED##_MAXPERSOSZ) \ + VALERR("personalization string too long"); \ + if (c && ph == -1) ph = 0; \ + if (!p) { p = (const char *)pp; ed##_pubkey(pp, k, ksz); } \ + rc = bytestring_pywrap(0, ED##_SIGSZ); \ + ed##sigver##_sign((octet *)PyString_AS_STRING(rc), k, ksz, \ + (const octet *)p, ph, c, csz, m, msz); \ + return (rc); \ + end: \ + return (0); \ + } \ + \ + static PyObject *meth_##ed##_verify(PyObject *me, \ + PyObject *arg, PyObject *kw) \ + { \ + const char *p, *c = 0, *m, *s; \ + Py_ssize_t psz, csz = 0, msz, ssz; \ + int ph = phdflt; \ + PyObject *rc = 0; \ + char *kwlist[] = { "pub", "msg", "sig", "perso", "phflag", 0 }; \ + if (!PyArg_ParseTupleAndKeywords(arg, kw, \ + "s#s#s#|s#O&:" #ed "_verify", \ + kwlist, \ + &p, &psz, &m, &msz, &s, &ssz, \ + &c, &csz, convbool, &ph)) \ + goto end; \ + if (psz != ED##_PUBSZ) VALERR("bad public length"); \ + if (ssz != ED##_SIGSZ) VALERR("bad signature length"); \ + if (c && csz > ED##_MAXPERSOSZ) \ + VALERR("personalization string too long"); \ + if (c && ph == -1) ph = 0; \ + rc = getbool(!ed##sigver##_verify((const octet *)p, ph, c, csz, \ + m, msz, (const octet *)s)); \ + return (rc); \ + end: \ + return (0); \ + } +EDDSAS(DEFEDDSA) +#undef DEFEDDSA /*----- Global stuff ------------------------------------------------------*/ @@ -1234,16 +1252,22 @@ static PyMethodDef methods[] = { KWMETH(_pss_decode, 0) KWMETH(_RSAPriv_generate, "\ generate(NBITS, [event = pgen_nullev, rng = rand, nsteps = 0]) -> R") - METH (x25519, "\ -x25519(KEY, PUBLIC) -> SHARED") - METH (x448, "\ -x448(KEY, PUBLIC) -> SHARED") - METH (ed25519_pubkey, "\ -ed25519_pubkey(KEY) -> PUBLIC") - KWMETH(ed25519_sign, "\ -ed25519_sign(KEY, MSG, [PUBLIC]) -> SIG") - METH (ed25519_verify, "\ -ed25519_verify(PUBLIC, MSG, SIG) -> BOOL") +#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 } };