chiark / gitweb /
Merge remote-tracking branch 'origin/HEAD'
[catacomb-python] / ec.c
diff --git a/ec.c b/ec.c
index 13b7798592601d2c174e42d1c7a56a2adc4200c7..c6034891ef71215c92d497ed2b1d8275c99f7cd7 100644 (file)
--- a/ec.c
+++ b/ec.c
@@ -204,8 +204,8 @@ static long ecpt_pyhash(PyObject *me)
   EC_OUT(ECPT_C(me), &p, ECPT_P(me));
   ec_putraw(ECPT_C(me), &b, &p);
   EC_DESTROY(&p);
-  xfree(q);
   h = unihash_hash(&unihash_global, h, BBASE(&b), BLEN(&b));
+  xfree(q);
   return (h % LONG_MAX);
 }
 
@@ -290,6 +290,34 @@ static PyObject *epmeth_toraw(PyObject *me, PyObject *arg)
   return (rc);
 }
 
+static PyObject *epmeth_ec2osp(PyObject *me, PyObject *arg, PyObject *kw)
+{
+  buf b;
+  PyObject *rc;
+  char *p;
+  ec_curve *c = ECPT_C(me);
+  ec pp = EC_INIT;
+  int f = EC_EXPLY;
+  int len;
+  char *kwlist[] = { "flags", 0 };
+
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "|i:ectosp", kwlist, &f))
+    return (0);
+  len = c->f->noctets * 2 + 1;
+  rc = bytestring_pywrap(0, len);
+  p = PyString_AS_STRING(rc);
+  buf_init(&b, p, len);
+  EC_OUT(c, &pp, ECPT_P(me));
+  if (ec_ec2osp(c, f, &b, &pp)) {
+    Py_DECREF(rc); rc = 0;
+    VALERR("invalid flags");
+  }
+  EC_DESTROY(&pp);
+  _PyString_Resize(&rc, BLEN(&b));
+end:
+  return (rc);
+}
+
 static PyObject *epget_curve(PyObject *me, void *hunoz)
   { RETURN_OBJ(ECPT_COBJ(me)); }
 
@@ -497,8 +525,8 @@ static PyObject *ecpt_pyint(PyObject *me)
   PyObject *rc = 0;
   if (EC_ATINF(ECPT_P(me))) VALERR("point at infinity");
   getecptout(&p, me);
-  if (mp_tolong_checked(p.x, &l)) goto end;
-  rc = PyInt_FromLong(l);
+  if (!mp_tolong_checked(p.x, &l, 0)) rc = PyInt_FromLong(l);
+  else rc = mp_topylong(p.x);
 end:
   EC_DESTROY(&p);
   return (rc);
@@ -656,6 +684,7 @@ static PyGetSetDef ecpt_pygetset[] = {
 static PyMethodDef ecpt_pymethods[] = {
 #define METHNAME(func) epmeth_##func
   METH (toraw,         "X.toraw() -> BIN")
+  KWMETH(ec2osp,       "X.ec2osp([flags = EC_EXPLY]) -> BIN")
   METH (dbl,           "X.dbl() -> X + X")
   METH (oncurvep,      "X.oncurvep() -> BOOL")
 #undef METHNAME
@@ -806,7 +835,7 @@ static PyObject *ecmeth_mmul(PyObject *me, PyObject *arg)
 static PyObject *meth__ECPtCurve_fromraw(PyObject *me, PyObject *arg)
 {
   char *p;
-  int len;
+  Py_ssize_t len;
   buf b;
   PyObject *rc = 0;
   ec_curve *cc;
@@ -824,11 +853,35 @@ end:
   return (rc);
 }
 
+static PyObject *meth__ECPtCurve_os2ecp(PyObject *me,
+                                       PyObject *arg, PyObject *kw)
+{
+  char *p;
+  Py_ssize_t len;
+  buf b;
+  PyObject *rc = 0;
+  ec_curve *cc;
+  int f = EC_XONLY | EC_LSB | EC_SORT | EC_EXPLY;
+  ec pp = EC_INIT;
+  char *kwlist[] = { "buf", "flags", 0 };
+
+  if (!PyArg_ParseTupleAndKeywords(arg, kw, "Os#|f:os2ecp", kwlist,
+                                  &me, &p, &len, &f))
+    return (0);
+  buf_init(&b, p, len);
+  cc = ECCURVE_C(me);
+  if (ec_os2ecp(cc, f, &b, &pp)) VALERR("bad point");
+  EC_IN(cc, &pp, &pp);
+  rc = Py_BuildValue("(NN)", ecpt_pywrap(me, &pp), bytestring_pywrapbuf(&b));
+end:
+  return (rc);
+}
+
 static PyObject *meth__ECPt_frombuf(PyObject *me, PyObject *arg)
 {
   buf b;
   char *p;
-  int sz;
+  Py_ssize_t sz;
   PyObject *rc = 0;
   ec pp = EC_INIT;
 
@@ -1492,6 +1545,7 @@ static PyMethodDef methods[] = {
 #define METHNAME(func) meth_##func
   METH (_ECPt_frombuf,         "frombuf(E, STR) -> (P, REST)")
   METH (_ECPtCurve_fromraw,    "fromraw(E, STR) -> (P, REST)")
+  KWMETH(_ECPtCurve_os2ecp,    "os2ecp(E, STR, [flags = ...]) -> (P, REST)")
   METH (_ECPt_parse,           "parse(E, STR) -> (P, REST)")
   METH (_ECCurve_parse,        "parse(STR) -> (E, REST)")
   METH (_ECInfo_parse,         "parse(STR) -> (I, REST)")