/* -*-c-*-
*
- * $Id: mpmont-mexp.c,v 1.1 1999/11/19 13:19:29 mdw Exp $
+ * $Id: mpmont-mexp.c,v 1.3 1999/12/10 23:18:39 mdw Exp $
*
* Multiplle simultaneous exponentiations
*
/*----- Revision history --------------------------------------------------*
*
* $Log: mpmont-mexp.c,v $
+ * Revision 1.3 1999/12/10 23:18:39 mdw
+ * Change interface for suggested destinations.
+ *
+ * Revision 1.2 1999/11/21 11:35:10 mdw
+ * Performance improvement: use @mp_sqr@ and @mpmont_reduce@ instead of
+ * @mpmont_mul@ for squaring in exponentiation.
+ *
* Revision 1.1 1999/11/19 13:19:29 mdw
* Simultaneous exponentiation support.
*
/* --- @mpmont_mexpr@ --- *
*
* Arguments: @mpmont *mm@ = pointer to Montgomery reduction context
+ * @mp *d@ = fake destination
* @mpmont_factor *f@ = pointer to array of factors
* @size_t n@ = number of factors supplied
*
mpw w;
} scan;
-mp *mpmont_mexpr(mpmont *mm, mpmont_factor *f, size_t n)
+mp *mpmont_mexpr(mpmont *mm, mp *d, mpmont_factor *f, size_t n)
{
size_t vn = 1 << n;
mp **v = xmalloc(vn * sizeof(mp *));
/* --- Accumulate the result --- */
if (spare) {
- dd = mpmont_mul(mm, spare, a, a);
+ dd = mp_sqr(spare, a);
+ dd = mpmont_reduce(mm, dd, dd);
spare = a;
a = dd;
}
free(s);
}
+ if (d != MP_NEW)
+ MP_DROP(d);
+
return (a);
}
/* --- @mpmont_mexp@ --- *
*
* Arguments: @mpmont *mm@ = pointer to Montgomery reduction context
+ * @mp *d@ = fake destination
* @mpmont_factor *f@ = pointer to array of factors
* @size_t n@ = number of factors supplied
*
* Use: Convenient interface over @mpmont_mexpr@.
*/
-mp *mpmont_mexp(mpmont *mm, mpmont_factor *f, size_t n)
+mp *mpmont_mexp(mpmont *mm, mp *d, mpmont_factor *f, size_t n)
{
- mp *d = mpmont_mexpr(mm, f, n);
+ d = mpmont_mexpr(mm, d, f, n);
d = mpmont_reduce(mm, d, d);
return (d);
}
rr = *(mp **)v[j].buf;
mpmont_create(&mm, m);
- r = mpmont_mexp(&mm, f, n);
+ r = mpmont_mexp(&mm, MP_NEW, f, n);
if (MP_CMP(r, !=, rr)) {
fputs("\n*** mexp failed\n", stderr);
fputs("m = ", stderr); mp_writefile(m, stderr, 10);
MP_DROP(r);
MP_DROP(rr);
mpmont_destroy(&mm);
+ assert(mparena_count(MPARENA_GLOBAL) == 0);
return (ok);
}