More changes. Still embryonic.
[u/mdw/catacomb] / mp-arith.c
index 6f00656..c055f95 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: mp-arith.c,v 1.2 1999/12/10 23:18:39 mdw Exp $
+ * $Id: mp-arith.c,v 1.4 1999/12/13 15:35:16 mdw Exp $
  *
  * Basic arithmetic on multiprecision integers
  *
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: mp-arith.c,v $
+ * Revision 1.4  1999/12/13 15:35:16  mdw
+ * Slightly different rules on memory allocation.
+ *
+ * Revision 1.3  1999/12/11 10:57:43  mdw
+ * Karatsuba squaring algorithm.
+ *
  * Revision 1.2  1999/12/10 23:18:39  mdw
  * Change interface for suggested destinations.
  *
@@ -202,17 +208,19 @@ mp *mp_sub(mp *d, mp *a, mp *b)
 
 mp *mp_mul(mp *d, mp *a, mp *b)
 {
+  size_t m = MAX(MP_LEN(a), MP_LEN(b)) * 2 + KARATSUBA_SLOP;
+
   a = MP_COPY(a);
   b = MP_COPY(b);
 
-  MP_MODIFY(d, MP_LEN(a) + MP_LEN(b));
-  if (MP_LEN(a) <= KARATSUBA_CUTOFF || MP_LEN(b) <= KARATSUBA_CUTOFF)
+  if (MP_LEN(a) <= KARATSUBA_CUTOFF || MP_LEN(b) <= KARATSUBA_CUTOFF) {
+    MP_MODIFY(d, MP_LEN(a) + MP_LEN(b));
     mpx_umul(d->v, d->vl, a->v, a->vl, b->v, b->vl);
-  else {
-    size_t m = MAX(MP_LEN(a), MP_LEN(b)) * 2 + KARATSUBA_SLOP;
+  } else {
     mpw *s;
     m += 32;
     s = MP_ALLOC(m);
+    MP_MODIFY(d, 2 * m + 2);
     mpx_kmul(d->v, d->vl, a->v, a->vl, b->v, b->vl, s, s + m);
     MP_FREE(s);
   }
@@ -237,12 +245,12 @@ mp *mp_sqr(mp *d, mp *a)
   size_t m = MP_LEN(a);
 
   a = MP_COPY(a);
-  MP_MODIFY(d, 2 * m);
+  MP_MODIFY(d, 2 * m + 2);
   if (m > KARATSUBA_CUTOFF) {
     mpw *s;
     m = 2 * (m + 1) + 32;
     s = MP_ALLOC(m);
-    mpx_kmul(d->v, d->vl, a->v, a->vl, a->v, a->vl, s, s + m);
+    mpx_ksqr(d->v, d->vl, a->v, a->vl, s, s + m);
     MP_FREE(s);
   } else 
     mpx_usqr(d->v, d->vl, a->v, a->vl);