From: Mark Wooding Date: Thu, 11 May 2017 09:42:15 +0000 (+0100) Subject: pubkey.c: Support the `ed2559ctx' signature scheme from RFC8032. X-Git-Tag: 1.2.0~5 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/catacomb-python/commitdiff_plain/5c4c02314ca241c437b28f301658fee743323739 pubkey.c: Support the `ed2559ctx' signature scheme from RFC8032. Main difference is the addition of a personalization string. In the wrapper classes, forward unknown keyword arguments on to the underlying implementation. --- diff --git a/catacomb.c b/catacomb.c index 9c83c9d..9e3b9cb 100644 --- a/catacomb.c +++ b/catacomb.c @@ -48,6 +48,7 @@ static const struct nameval consts[] = { C(X25519_KEYSZ), C(X25519_PUBSZ), C(X25519_OUTSZ), C(X448_KEYSZ), C(X448_PUBSZ), C(X448_OUTSZ), C(ED25519_KEYSZ), C(ED25519_PUBSZ), C(ED25519_SIGSZ), + C(ED25519_MAXPERSOSZ), #define ENTRY(tag, val, str) C(KERR_##tag), KEY_ERRORS(ENTRY) #undef ENTRY diff --git a/catacomb/__init__.py b/catacomb/__init__.py index b9818e7..4840eef 100644 --- a/catacomb/__init__.py +++ b/catacomb/__init__.py @@ -901,14 +901,14 @@ class _EdDSAPriv (_BasePriv, _EdDSAPub): class Ed25519Pub (_EdDSAPub): _PUBSZ = KeySZSet(ED25519_PUBSZ) _HASH = sha512 - def verify(me, msg, sig): - return ed25519_verify(me.pub, msg, sig) + def verify(me, msg, sig, **kw): + return ed25519_verify(me.pub, msg, sig, **kw) class Ed25519Priv (_EdDSAPriv, Ed25519Pub): _KEYSZ = KeySZAny(ED25519_KEYSZ) def _pubkey(me, priv): return ed25519_pubkey(priv) - def sign(me, msg): - return ed25519_sign(me.priv, msg, pub = me.pub) + def sign(me, msg, **kw): + return ed25519_sign(me.priv, msg, pub = me.pub, **kw) ###-------------------------------------------------------------------------- ### Built-in named curves and prime groups. diff --git a/pubkey.c b/pubkey.c index 642da3e..7374429 100644 --- a/pubkey.c +++ b/pubkey.c @@ -1164,9 +1164,9 @@ XDHS(DEFXDH) /*----- Ed25519 and related algorithms ------------------------------------*/ #define EDDSAS(_) \ - _(ED25519, ed25519) + _(ED25519, ed25519, -1, ctx) -#define DEFEDDSA(ED, ed) \ +#define DEFEDDSA(ED, ed, phdflt, sigver) \ \ static PyObject *meth_##ed##_pubkey(PyObject *me, PyObject *arg) \ { \ @@ -1185,21 +1185,26 @@ XDHS(DEFXDH) static PyObject *meth_##ed##_sign(PyObject *me, PyObject *arg, \ PyObject *kw) \ { \ - const char *k, *p = 0, *m; \ - Py_ssize_t ksz, psz, msz; \ + 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", 0 }; \ + char *kwlist[] = { "key", "msg", "pub", "perso", "phflag", 0 }; \ if (!PyArg_ParseTupleAndKeywords(arg, kw, \ - "s#s#|s#:" #ed "_sign", \ + "s#s#|s#s#O&:" #ed "_sign", \ kwlist, \ - &k, &ksz, &m, &msz, &p, &psz)) \ + &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##_sign((octet *)PyString_AS_STRING(rc), k, ksz, \ - (const octet *)p, m, msz); \ + ed##sigver##_sign((octet *)PyString_AS_STRING(rc), k, ksz, \ + (const octet *)p, ph, c, csz, m, msz); \ return (rc); \ end: \ return (0); \ @@ -1208,19 +1213,24 @@ XDHS(DEFXDH) static PyObject *meth_##ed##_verify(PyObject *me, \ PyObject *arg, PyObject *kw) \ { \ - const char *p, *m, *s; \ - Py_ssize_t psz, msz, ssz; \ + 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", 0 }; \ + char *kwlist[] = { "pub", "msg", "sig", "perso", "phflag", 0 }; \ if (!PyArg_ParseTupleAndKeywords(arg, kw, \ - "s#s#s#:" #ed "_verify", \ + "s#s#s#|s#O&:" #ed "_verify", \ kwlist, \ - &p, &psz, &m, &msz, &s, &ssz)) \ + &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"); \ - rc = getbool(!ed##_verify((const octet *)p, \ - m, msz, (const octet *)s)); \ + 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); \ @@ -1247,7 +1257,7 @@ generate(NBITS, [event = pgen_nullev, rng = rand, nsteps = 0]) -> R") " #x "(KEY, PUBLIC) -> SHARED") XDHS(DEFMETH) #undef DEFMETH -#define DEFMETH(ED, ed) \ +#define DEFMETH(ED, ed, phdflt, sigver) \ METH (ed##_pubkey, "\ " #ed "_pubkey(KEY) -> PUBLIC") \ KWMETH(ed##_sign, "\