chiark / gitweb /
pubkey.c: Support the `ed2559ctx' signature scheme from RFC8032.
authorMark Wooding <mdw@distorted.org.uk>
Thu, 11 May 2017 09:42:15 +0000 (10:42 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 14 May 2017 03:29:42 +0000 (04:29 +0100)
Main difference is the addition of a personalization string.

In the wrapper classes, forward unknown keyword arguments on to the
underlying implementation.

catacomb.c
catacomb/__init__.py
pubkey.c

index 9c83c9dbe29877bd1b7654123f4362122ee9da36..9e3b9cb46fc8d29c0622c3e8b63df3282eefbda0 100644 (file)
@@ -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
index b9818e71a7eb3c717f538a82f0f24c21964c21fb..4840eef306cb706cefe85bbba1a7e8f71e6f4225 100644 (file)
@@ -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.
index 642da3efd3342ce0be11b606b162450f106961a8..73744299be232a845a2804ce30397c8c59d71cae 100644 (file)
--- 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,                    "\