catacomb.c, ec.c, group.c, mp.c: Count base/exponent pairs with `size_t'.
[catacomb-python] / ec.c
diff --git a/ec.c b/ec.c
index a77a91e..74bbf5e 100644 (file)
--- a/ec.c
+++ b/ec.c
@@ -186,7 +186,11 @@ static PyObject *ecpt_pymul(PyObject *x, PyObject *y)
   ec zz = EC_INIT;
 
   if (ECPT_PYCHECK(x)) { PyObject *t; t = x; x = y; y = t; }
-  if (!ECPT_PYCHECK(y) || (xx = tomp(x)) == 0) RETURN_NOTIMPL;
+  if (!ECPT_PYCHECK(y)) RETURN_NOTIMPL;
+  if (FE_PYCHECK(x) && FE_F(x)->ops->ty == FTY_PRIME)
+    xx = F_OUT(FE_F(x), MP_NEW, FE_X(x));
+  else if ((xx = implicitmp(x)) == 0)
+    RETURN_NOTIMPL;
   ec_imul(ECPT_C(y), &zz, ECPT_P(y), xx);
   MP_DROP(xx);
   return (ecpt_pywrap(ECPT_COBJ(y), &zz));
@@ -329,11 +333,15 @@ static PyObject *epmeth_parse(PyObject *me, PyObject *arg)
   char *p;
   qd_parse qd;
   PyObject *rc = 0;
+  int paren;
   ec pp = EC_INIT;
 
   if (!PyArg_ParseTuple(arg, "s:parse", &p)) goto end;
   qd.p = p; qd.e = 0;
+  qd_skipspc(&qd); paren = qd_delim(&qd, '(');
   if (!ec_ptparse(&qd, &pp)) VALERR(qd.e);
+  qd_skipspc(&qd); if (paren && !qd_delim(&qd, ')'))
+    { EC_DESTROY(&pp); VALERR("missing `)'"); }
   rc = Py_BuildValue("(Ns)", ecpt_pywrapout(me, &pp), qd.p);
 end:
   return (rc);
@@ -463,7 +471,7 @@ static PyObject *epget__z(PyObject *me, void *hunoz)
 static mp *coord_in(field *f, PyObject *x)
 {
   mp *xx;
-  if (FE_PYCHECK(x) && FE_F(x) == f)
+  if (FE_PYCHECK(x) && (FE_F(x) == f || field_samep(FE_F(x), f)))
     return (MP_COPY(FE_X(x)));
   else if ((xx = getmp(x)) == 0)
     return (0);
@@ -509,6 +517,7 @@ static int ecptxl_1(ec_curve *c, ec *p, PyObject *x)
   mp *xx = 0;
   int n;
   qd_parse qd;
+  int paren;
 
   Py_XINCREF(x);
   if (!x || x == Py_None)
@@ -517,10 +526,12 @@ static int ecptxl_1(ec_curve *c, ec *p, PyObject *x)
     getecptout(p, x);
     goto fix;
   } else if (TEXT_CHECK(x)) {
-    qd.p = TEXT_PTR(x);
-    qd.e = 0;
-    if (!ec_ptparse(&qd, p))
-      VALERR(qd.e);
+    qd.p = TEXT_PTR(x); qd.e = 0;
+    qd_skipspc(&qd); paren = qd_delim(&qd, '(');
+    if (!ec_ptparse(&qd, p)) VALERR(qd.e);
+    qd_skipspc(&qd); if (paren && !qd_delim(&qd, ')'))
+      { EC_DESTROY(p); VALERR("missing `)'"); }
+    qd_skipspc(&qd); if (!qd_eofp(&qd)) VALERR("junk at eof");
     goto fix;
   } else if (c && (xx = tomp(x)) != 0) {
     xx = F_IN(c->f, xx, xx);
@@ -528,7 +539,7 @@ static int ecptxl_1(ec_curve *c, ec *p, PyObject *x)
   } else if (PySequence_Check(x)) {
     t = x; x = 0;
     n = PySequence_Size(t); if (n < 0) goto end;
-    if (n != 2 && (n != 3 || !c))
+    if (n != 2 && n != 3)
       TYERR("want sequence of two or three items");
     if ((x = PySequence_GetItem(t, 0)) == 0 ||
        (y = PySequence_GetItem(t, 1)) == 0 ||
@@ -589,6 +600,7 @@ end:
   return (rc);
 }
 
+#ifdef PY2
 static PyObject *ecpt_pylong(PyObject *me)
 {
   ec p = EC_INIT;
@@ -600,6 +612,7 @@ end:
   EC_DESTROY(&p);
   return (rc);
 }
+#endif
 
 static PyObject *ecpt_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
 {
@@ -639,7 +652,9 @@ static const PyNumberMethods ecpt_pynumber = {
   0,                                   /* @nb_add@ */
   0,                                   /* @nb_subtract@ */
   0,                                   /* @nb_multiply@ */
+#ifdef PY2
   0,                                   /* @nb_divide@ */
+#endif
   0,                                   /* @nb_remainder@ */
   0,                                   /* @nb_divmod@ */
   0,                                   /* @nb_power@ */
@@ -653,17 +668,23 @@ static const PyNumberMethods ecpt_pynumber = {
   0,                                   /* @nb_and@ */
   0,                                   /* @nb_xor@ */
   0,                                   /* @nb_or@ */
+#ifdef PY2
   0,                                   /* @nb_coerce@ */
+#endif
   ecpt_pyint,                          /* @nb_int@ */
-  ecpt_pylong,                         /* @nb_long@ */
+  PY23(ecpt_pylong, 0),                        /* @nb_long@ */
   0,                                   /* @nb_float@ */
+#ifdef PY2
   0,                                   /* @nb_oct@ */
   0,                                   /* @nb_hex@ */
+#endif
 
   0,                                   /* @nb_inplace_add@ */
   0,                                   /* @nb_inplace_subtract@ */
   0,                                   /* @nb_inplace_multiply@ */
+#ifdef PY2
   0,                                   /* @nb_inplace_divide@ */
+#endif
   0,                                   /* @nb_inplace_remainder@ */
   0,                                   /* @nb_inplace_power@ */
   0,                                   /* @nb_inplace_lshift@ */
@@ -731,7 +752,7 @@ static const PyTypeObject ecpt_pytype_skel = {
 
 static const PyMemberDef ecpt_pymembers[] = {
 #define MEMBERSTRUCT ecpt_pyobj
-  MEMRNM(curve, T_OBJECT, ob_type, READONLY,
+  MEMRNM(curve, T_OBJECT, PY23(ob_type, ob_base.ob_type), READONLY,
                                    "P.curve -> elliptic curve containing P")
 #undef MEMBERSTRUCT
   { 0 }
@@ -765,7 +786,9 @@ static const PyNumberMethods ecptcurve_pynumber = {
   ecpt_pyadd,                          /* @nb_add@ */
   ecpt_pysub,                          /* @nb_subtract@ */
   ecpt_pymul,                          /* @nb_multiply@ */
+#ifdef PY2
   0,                                   /* @nb_divide@ */
+#endif
   0,                                   /* @nb_remainder@ */
   0,                                   /* @nb_divmod@ */
   0,                                   /* @nb_power@ */
@@ -779,12 +802,16 @@ static const PyNumberMethods ecptcurve_pynumber = {
   0,                                   /* @nb_and@ */
   0,                                   /* @nb_xor@ */
   0,                                   /* @nb_or@ */
+#ifdef PY2
   0,                                   /* @nb_coerce@ */
+#endif
   0,                                   /* @nb_int@ */
   0,                                   /* @nb_long@ */
   0,                                   /* @nb_float@ */
+#ifdef PY2
   0,                                   /* @nb_oct@ */
   0,                                   /* @nb_hex@ */
+#endif
 
   0,                                   /* @nb_inplace_add@ */
   0,                                   /* @nb_inplace_subtract@ */
@@ -886,7 +913,7 @@ static int ecmmul_fill(void *pp, PyObject *me, PyObject *x, PyObject *m)
   return (0);
 }
 
-static PyObject *ecmmul_exp(PyObject *me, void *pp, int n)
+static PyObject *ecmmul_exp(PyObject *me, void *pp, size_t n)
 {
   ec p = EC_INIT;
   ec_immul(ECCURVE_C(me), &p, pp, n);
@@ -959,7 +986,7 @@ static PyObject *ecmeth_parse(PyObject *me, PyObject *arg)
   if (!PyArg_ParseTuple(arg, "s:parse", &p)) goto end;
   qd.p = p; qd.e = 0;
   if ((c = ec_curveparse(&qd)) == 0) VALERR(qd.e);
-  rc = eccurve_pywrap(0, c);
+  rc = Py_BuildValue("(Ns)", eccurve_pywrap(0, c), qd.p);
 end:
   return (rc);
 }