(mpmont_reduce, mpmont_mul): Cope with negative numbers.
[u/mdw/catacomb] / mpmont.c
index be7d00e..4868bff 100644 (file)
--- a/mpmont.c
+++ b/mpmont.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: mpmont.c,v 1.10 2000/07/29 17:05:43 mdw Exp $
+ * $Id: mpmont.c,v 1.11 2000/10/08 12:04:27 mdw Exp $
  *
  * Montgomery reduction
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: mpmont.c,v $
+ * Revision 1.11  2000/10/08 12:04:27  mdw
+ * (mpmont_reduce, mpmont_mul): Cope with negative numbers.
+ *
  * Revision 1.10  2000/07/29 17:05:43  mdw
  * (mpmont_expr): Use sliding window exponentiation, with a drop-through
  * for small exponents to use a simple left-to-right bitwise routine.  This
@@ -246,8 +249,12 @@ mp *mpmont_reduce(mpmont *mm, mp *d, mp *a)
 
   memmove(d->v, d->v + n, MPWS(MP_LEN(d) - n));
   d->vl -= n;
-  if (MP_CMP(d, >=, mm->m))
-    d = mp_sub(d, d, mm->m);
+  if (MPX_UCMP(d->v, d->vl, >=, mm->m->v, mm->m->vl))
+    mpx_usub(d->v, d->vl, d->v, d->vl, mm->m->v, mm->m->vl);
+  if (d->f & MP_NEG) {
+    mpx_usub(d->v, d->vl, mm->m->v, mm->m->vl, d->v, d->vl);
+    d->f &= ~MP_NEG;
+  }
   MP_SHRINK(d);
   return (d);
 }
@@ -331,10 +338,12 @@ mp *mpmont_mul(mpmont *mm, mp *d, mp *a, mp *b)
 
     memmove(d->v, dv, MPWS(dvl - dv));
     d->vl -= dv - d->v;
+    if (MPX_UCMP(d->v, d->vl, >=, mm->m->v, mm->m->vl))
+      mpx_usub(d->v, d->vl, d->v, d->vl, mm->m->v, mm->m->vl);
+    if ((a->f ^ b->f) & MP_NEG)
+      mpx_usub(d->v, d->vl, mm->m->v, mm->m->vl, d->v, d->vl);
     MP_SHRINK(d);
     d->f = (a->f | b->f) & MP_BURN;
-    if (MP_CMP(d, >=, mm->m))
-      d = mp_sub(d, d, mm->m);
     MP_DROP(a);
     MP_DROP(b);
   }
@@ -584,7 +593,7 @@ static int tcreate(dstr *v)
     ok = 0;
   }
 
-  if (MP_CMP(mm.r, !=, r)) {
+  if (!MP_EQ(mm.r, r)) {
     fputs("\n*** bad r", stderr);
     fputs("\nm = ", stderr); mp_writefile(m, stderr, 10);
     fputs("\nexpected ", stderr); mp_writefile(r, stderr, 10);
@@ -593,7 +602,7 @@ static int tcreate(dstr *v)
     ok = 0;
   }
 
-  if (MP_CMP(mm.r2, !=, r2)) {
+  if (!MP_EQ(mm.r2, r2)) {
     fputs("\n*** bad r2", stderr);
     fputs("\nm = ", stderr); mp_writefile(m, stderr, 10);
     fputs("\nexpected ", stderr); mp_writefile(r2, stderr, 10);
@@ -626,7 +635,7 @@ static int tmul(dstr *v)
     mp *qr = mp_mul(MP_NEW, a, b);
     mp_div(0, &qr, qr, m);
 
-    if (MP_CMP(qr, !=, r)) {
+    if (!MP_EQ(qr, r)) {
       fputs("\n*** classical modmul failed", stderr);
       fputs("\n m = ", stderr); mp_writefile(m, stderr, 10);
       fputs("\n a = ", stderr); mp_writefile(a, stderr, 10);
@@ -645,7 +654,7 @@ static int tmul(dstr *v)
     mp *br = mpmont_mul(&mm, MP_NEW, b, mm.r2);
     mp *mr = mpmont_mul(&mm, MP_NEW, ar, br);
     mr = mpmont_reduce(&mm, mr, mr);
-    if (MP_CMP(mr, !=, r)) {
+    if (!MP_EQ(mr, r)) {
       fputs("\n*** montgomery modmul failed", stderr);
       fputs("\n m = ", stderr); mp_writefile(m, stderr, 10);
       fputs("\n a = ", stderr); mp_writefile(a, stderr, 10);
@@ -683,7 +692,7 @@ static int texp(dstr *v)
 
   mr = mpmont_exp(&mm, MP_NEW, a, b);
 
-  if (MP_CMP(mr, !=, r)) {
+  if (!MP_EQ(mr, r)) {
     fputs("\n*** montgomery modexp failed", stderr);
     fputs("\n m = ", stderr); mp_writefile(m, stderr, 10);
     fputs("\n a = ", stderr); mp_writefile(a, stderr, 10);