math/f-{prime,niceprime}.c: Fix reduction for `add', `sub' and `neg'.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 22 Dec 2014 20:32:58 +0000 (20:32 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 27 Feb 2015 21:18:15 +0000 (21:18 +0000)
None of these worked properly at the modulus itself.  This causes the
`neg' method of prime curves to fail at 2-torsion points.

math/f-niceprime.c
math/f-prime.c
math/t/ec

index 342cb86..f31752d 100644 (file)
@@ -52,20 +52,21 @@ static int fzerop(field *ff, mp *x) { return (MP_ZEROP(x)); }
 
 static mp *fneg(field *ff, mp *d, mp *x) {
   fctx_niceprime *f = (fctx_niceprime *)ff;
-  return (mp_sub(d, f->r.p, x));
+  if (MP_ZEROP(x)) { if (d != x) mp_drop(d); return (MP_COPY(x)); }
+  else return (mp_sub(d, f->r.p, x));
 }
 
 static mp *fadd(field *ff, mp *d, mp *x, mp *y) {
   fctx_niceprime *f = (fctx_niceprime *)ff; d = mp_add(d, x, y);
   if (MP_NEGP(d)) d = mp_add(d, d, f->r.p);
-  else if (MP_CMP(d, >, f->r.p)) d = mp_sub(d, d, f->r.p);
+  else if (MP_CMP(d, >=, f->r.p)) d = mp_sub(d, d, f->r.p);
   return (d);
 }
 
 static mp *fsub(field *ff, mp *d, mp *x, mp *y) {
   fctx_niceprime *f = (fctx_niceprime *)ff; d = mp_sub(d, x, y);
   if (MP_NEGP(d)) d = mp_add(d, d, f->r.p);
-  else if (MP_CMP(d, >, f->r.p)) d = mp_sub(d, d, f->r.p);
+  else if (MP_CMP(d, >=, f->r.p)) d = mp_sub(d, d, f->r.p);
   return (d);
 }
 
index d9c5c17..b21ca2a 100644 (file)
@@ -63,20 +63,21 @@ static int fzerop(field *ff, mp *x) { return (MP_ZEROP(x)); }
 
 static mp *fneg(field *ff, mp *d, mp *x) {
   fctx_prime *f = (fctx_prime *)ff;
-  return (mp_sub(d, f->mm.m, x));
+  if (MP_ZEROP(x)) { if (d != x) mp_drop(d); return (MP_COPY(x)); }
+  else return (mp_sub(d, f->mm.m, x));
 }
 
 static mp *fadd(field *ff, mp *d, mp *x, mp *y) {
   fctx_prime *f = (fctx_prime *)ff; d = mp_add(d, x, y);
   if (MP_NEGP(d)) d = mp_add(d, d, f->mm.m);
-  else if (MP_CMP(d, >, f->mm.m)) d = mp_sub(d, d, f->mm.m);
+  else if (MP_CMP(d, >=, f->mm.m)) d = mp_sub(d, d, f->mm.m);
   return (d);
 }
 
 static mp *fsub(field *ff, mp *d, mp *x, mp *y) {
   fctx_prime *f = (fctx_prime *)ff; d = mp_sub(d, x, y);
   if (MP_NEGP(d)) d = mp_add(d, d, f->mm.m);
-  else if (MP_CMP(d, >, f->mm.m)) d = mp_sub(d, d, f->mm.m);
+  else if (MP_CMP(d, >=, f->mm.m)) d = mp_sub(d, d, f->mm.m);
   return (d);
 }
 
index acd16d6..1dc56ab 100644 (file)
--- a/math/t/ec
+++ b/math/t/ec
@@ -172,6 +172,13 @@ neg {
     "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012,
        0xf8e6d46a003725879cefee1294db32298c06885ee186b7ee";
 
+  "prime: 6277101735386680763835789423207666416102355444464034512659; prime: -3, 6"
+    "0xcdf65dc6c906c5c240dba0d156b911614abe806fa2b8dc0a, 0"
+    "0xcdf65dc6c906c5c240dba0d156b911614abe806fa2b8dc0a, 0";
+  "niceprime: 6277101735386680763835789423207666416102355444464034512659; prime: -3, 6"
+    "0xcdf65dc6c906c5c240dba0d156b911614abe806fa2b8dc0a, 0"
+    "0xcdf65dc6c906c5c240dba0d156b911614abe806fa2b8dc0a, 0";
+
   "niceprime: 6277101735386680763835789423207666416083908700390324961279
      prime: -3, 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1"
     "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012,