buffer.c: Implement `ec2osp' and `os2ecp' as operations on buffers.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 23 Nov 2019 14:26:34 +0000 (14:26 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 25 Nov 2019 17:51:31 +0000 (17:51 +0000)
buffer.c
t/t-ec.py

index c616403..d0df068 100644 (file)
--- a/buffer.c
+++ b/buffer.c
@@ -184,6 +184,22 @@ end:
   return (rc);
 }
 
+static PyObject *rbmeth_os2ecp(PyObject *me, PyObject *arg, PyObject *kw)
+{
+  PyObject *cobj;
+  ec pt = EC_INIT;
+  unsigned f = EC_XONLY | EC_LSB | EC_SORT | EC_EXPLY;
+  PyObject *rc = 0;
+  static const char *const kwlist[] = { "curve", "flags", 0 };
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!|O&:os2ecp", KWLIST,
+                                  eccurve_pytype, &cobj, convuint, &f))
+    goto end;
+  if (ec_os2ecp(ECCURVE_C(cobj), f, BUF_B(me), &pt)) VALERR("bad point");
+  rc = ecpt_pywrapout(cobj, &pt);
+end:
+  return (rc);
+}
+
 static PyObject *rbmeth_getge(PyObject *me, PyObject *arg)
 {
   PyObject *gobj;
@@ -257,6 +273,7 @@ static const PyMethodDef rbuf_pymethods[] = {
   NAMETH(getgf,                "RBUF.getgf() -> X")
   KWMETH(getecpt,      "RBUF.getecpt([curve = None]) -> P")
   METH (getecptraw,    "RBUF.getecptraw(CURVE) -> P")
+  KWMETH(os2ecp,       "RBUF.os2ecp(CURVE, [flags = ...]) -> P")
   METH (getge,         "RBUF.getge(GROUP) -> X")
   METH (getgeraw,      "RBUF.getgeraw(GROUP) -> X")
 #undef METHNAME
@@ -477,6 +494,25 @@ static PyObject *wbmeth_putecptraw(PyObject *me, PyObject *arg)
   RETURN_ME;
 }
 
+static PyObject *wbmeth_ec2osp(PyObject *me, PyObject *arg, PyObject *kw)
+{
+  PyTypeObject *ptobj;
+  ec_curve *cc;
+  ec pt = EC_INIT;
+  unsigned f = EC_EXPLY;
+  static const char *const kwlist[] = { "point", "flags", 0 };
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!|O&:os2ecp", KWLIST,
+                                  ecptcurve_pytype, &ptobj, convuint, &f))
+    goto end;
+  cc = ECPT_C(ptobj);
+  EC_OUT(cc, &pt, ECPT_P(ptobj));
+  if (ensurebuf(me, 2*cc->f->noctets + 1)) return (0);
+  if (ec_ec2osp(cc, f, BUF_B(me), &pt)) VALERR("invalid flags");
+  RETURN_ME;
+end:
+  return (0);
+}
+
 static PyObject *wbmeth_putge(PyObject *me, PyObject *arg)
 {
   PyObject *geobj;
@@ -523,6 +559,7 @@ static const PyMethodDef wbuf_pymethods[] = {
   METH (putgf,         "WBUF.putgf(X)")
   METH (putecpt,       "WBUF.putecpt(P)")
   METH (putecptraw,    "WBUF.putecptraw(P)")
+  KWMETH(ec2osp,       "WBUF.ec2osp(P, [flags = EC_EXPLY])")
   METH (putge,         "WBUF.putge(X)")
   METH (putgeraw,      "WBUF.putgeraw(X)")
 #undef METHNAME
index 870297e..b9c4516 100644 (file)
--- a/t/t-ec.py
+++ b/t/t-ec.py
@@ -201,8 +201,10 @@ class TestCurves (T.GenericTestMixin):
          .contents
     me.assertEqual(P.ec2osp(), t)
     me.assertEqual(C.WriteBuffer().putecptraw(P).contents, t)
+    me.assertEqual(C.WriteBuffer().ec2osp(P).contents, t)
     me.assertEqual(E.os2ecp(t), (P, Z0))
     me.assertEqual(C.ReadBuffer(t).getecptraw(E), P)
+    me.assertEqual(C.ReadBuffer(t).os2ecp(E), P)
     if isinstance(k, C.PrimeField): ybit = int(P.iy&1)
     else:
       try: ybit = int((P.y/P.x).value&C.GF(1))
@@ -212,7 +214,9 @@ class TestCurves (T.GenericTestMixin):
          .put(P.ix.storeb(k.noctets)) \
          .contents
     me.assertEqual(P.ec2osp(C.EC_LSB), t)
+    me.assertEqual(C.WriteBuffer().ec2osp(P, C.EC_LSB).contents, t)
     me.assertEqual(E.os2ecp(t, C.EC_LSB), (P, Z0))
+    me.assertEqual(C.ReadBuffer(t).os2ecp(E, C.EC_LSB), P)
 
     ## Curve methods.
     Q = E.find(P.x); me.assertTrue(Q == P or Q == -P)