ec.c, field.c, group.c, mp.c: Fix conversions in `pow' and scalar mul.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 24 Nov 2019 00:18:43 +0000 (00:18 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 11 Apr 2020 11:49:31 +0000 (12:49 +0100)
The base and modulus (if present) should belong to the base ring; the
exponent or scalar should be an integer; and we should use implicit-
conversion rules for all three.  (Of course, the modulus can also be
`None'.)

This tightening temporarily breaks a test multiplying an elliptic curve
point by a prime-field element Q n.  That used to work, but not for any
especially principled reason; and this wasn't commutative (n Q would
multiply n by the x-coordinate of Q coerced into the scalar field).  We
shall fix this soon.

ec.c
field.c
group.c
mp.c
t/t-convert.py
t/t-ec.py

diff --git a/ec.c b/ec.c
index 459c272..86aa17f 100644 (file)
--- a/ec.c
+++ b/ec.c
@@ -186,7 +186,7 @@ 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) || (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));
diff --git a/field.c b/field.c
index 9380678..ba00d34 100644 (file)
--- a/field.c
+++ b/field.c
@@ -174,7 +174,7 @@ static PyObject *fe_pyexp(PyObject *x, PyObject *y, PyObject *z)
   field *ff;
   mp *xx, *yy;
 
-  if (z != Py_None || !FE_PYCHECK(x) || (yy = tomp(y)) == 0)
+  if (z != Py_None || !FE_PYCHECK(x) || (yy = implicitmp(y)) == 0)
     RETURN_NOTIMPL;
   ff = FE_F(x); xx = FE_X(x); MP_COPY(xx);
   if (MP_NEGP(yy) && F_ZEROP(ff, xx)) ZDIVERR("division by zero");
diff --git a/group.c b/group.c
index 6b26d9d..8774290 100644 (file)
--- a/group.c
+++ b/group.c
@@ -589,7 +589,7 @@ static PyObject *ge_pyexp(PyObject *x, PyObject *n, PyObject *m)
   mp *nn;
   ge *z;
 
-  if (m != Py_None || !GE_PYCHECK(x) || (nn = getmp(n)) == 0)
+  if (m != Py_None || !GE_PYCHECK(x) || (nn = implicitmp(n)) == 0)
     RETURN_NOTIMPL;
   z = G_CREATE(GE_G(x));
   G_EXP(GE_G(x), z, GE_X(x), nn);
diff --git a/mp.c b/mp.c
index f45268b..96e3e86 100644 (file)
--- a/mp.c
+++ b/mp.c
@@ -465,7 +465,7 @@ static PyObject *mp_pyexp(PyObject *x, PyObject *y, PyObject *z)
   PyObject *rc = 0;
 
   if ((xx = implicitmp(x)) == 0 || (yy = implicitmp(y)) == 0 ||
-      (z && z != Py_None && (zz = tomp(z)) == 0)) {
+      (z && z != Py_None && (zz = implicitmp(z)) == 0)) {
     mp_drop(xx); mp_drop(yy); mp_drop(zz);
     RETURN_NOTIMPL;
   }
@@ -1993,8 +1993,8 @@ static PyObject *gf_pyexp(PyObject *x, PyObject *y, PyObject *z)
   mp *r = 0;
   PyObject *rc = 0;
 
-  if ((xx = tomp(x)) == 0 || (yy = tomp(y)) == 0 ||
-      (z && z != Py_None && (zz = tomp(z)) == 0)) {
+  if ((xx = implicitgf(x)) == 0 || (yy = implicitmp(y)) == 0 ||
+      (z && z != Py_None && (zz = implicitgf(z)) == 0)) {
     mp_drop(xx); mp_drop(yy); mp_drop(zz);
     RETURN_NOTIMPL;
   }
index dcf9d91..df80617 100644 (file)
@@ -51,7 +51,7 @@ class TestConvert (U.TestCase):
     me.assertEqual(pow(C.MP(5), 2, 7), 4)
     me.assertEqual(pow(5, C.MP(2), 7), 4)
     me.assertEqual(pow(5, 2, C.MP(7)), 4)
-    for bad in [lambda x: [x]]:
+    for bad in [C.GF, k, kk, float, lambda x: [x]]:
       me.assertRaises(TypeError, pow, C.MP(5), bad(2))
       me.assertRaises(TypeError, pow, C.MP(5), bad(2), 7)
       if not (T.PY2 and T.DEBUGP):
@@ -76,10 +76,10 @@ class TestConvert (U.TestCase):
     me.assertEqual(pow(C.GF(0x5), 2), C.GF(0x11))
     me.assertEqual(pow(C.GF(0x5), C.MP(2)), C.GF(0x11))
     me.assertEqual(pow(C.GF(5), 2, C.GF(0x13)), C.GF(0x2))
-    for bad in [lambda x: [x]]:
+    for bad in [k, kk, float, lambda x: [x]]:
       me.assertRaises(TypeError, pow, C.GF(5), bad(2))
       me.assertRaises(TypeError, T.lsl, C.GF(5), bad(2))
-    for bad in [lambda x: [x]]:
+    for bad in [C.MP, k, kk, float, lambda x: [x]]:
       me.assertRaises(TypeError, pow, bad(5), C.GF(2))
       me.assertRaises(TypeError, pow, bad(5), C.GF(2), bad(7))
       me.assertRaises(TypeError, pow, bad(5), bad(2), C.GF(7))
index b9c4516..467ead5 100644 (file)
--- a/t/t-ec.py
+++ b/t/t-ec.py
@@ -178,8 +178,9 @@ class TestCurves (T.GenericTestMixin):
     me.assertEqual(Q + R, 23*P)
     me.assertEqual(Q + R.point, 23*P)
     me.assertRaises(TypeError, T.add, Q.point, R.point)
+    me.assertRaises(TypeError, T.mul, kk(1), Q)
     me.assertEqual(Q - R, 11*P)
-    me.assertEqual(P*l(17), Q)
+    #me.assertEqual(P*l(17), Q)
 
     ## Ordering.
     me.assertTrue(P == P)