/* -*-c-*-
*
- * $Id: mpmont.c,v 1.1 1999/11/17 18:02:16 mdw Exp $
+ * $Id: mpmont.c,v 1.2 1999/11/19 13:17:26 mdw Exp $
*
* Montgomery reduction
*
/*----- Revision history --------------------------------------------------*
*
* $Log: mpmont.c,v $
+ * Revision 1.2 1999/11/19 13:17:26 mdw
+ * Add extra interface to exponentiation which returns a Montgomerized
+ * result.
+ *
* Revision 1.1 1999/11/17 18:02:16 mdw
* New multiprecision integer arithmetic suite.
*
d->vl -= dv - d->v;
MP_SHRINK(d);
d->f = a->f & MP_BURN;
+ if (MP_CMP(d, >=, mm->m))
+ d = mp_sub(d, d, mm->m);
return (d);
}
d->vl -= dv - d->v;
MP_SHRINK(d);
d->f = (a->f | b->f) & MP_BURN;
+ if (MP_CMP(d, >=, mm->m))
+ d = mp_sub(d, d, mm->m);
return (d);
}
-/* --- @mpmont_exp@ --- *
+/* --- @mpmont_expr@ --- *
*
* Arguments: @mpmont *mm@ = pointer to Montgomery reduction context
* @const mp *a@ = base
* @const mp *e@ = exponent
*
- * Returns: Result, %$a^e \bmod m$%.
+ * Returns: Result, %$a^e R \bmod m$%.
*/
-mp *mpmont_exp(mpmont *mm, const mp *a, const mp *e)
+mp *mpmont_expr(mpmont *mm, const mp *a, const mp *e)
{
mpscan sc;
mp *ar = mpmont_mul(mm, MP_NEW, a, mm->r2);
mp *d = MP_COPY(mm->r);
+ mp *spare = MP_NEW;
mp_scan(&sc, e);
if (MP_STEP(&sc)) {
+ size_t sq = 0;
for (;;) {
mp *dd;
if (MP_BIT(&sc)) {
- dd = mpmont_mul(mm, MP_NEW, d, ar);
- MP_DROP(d);
- d = dd;
+ while (sq) {
+ dd = mpmont_mul(mm, spare, ar, ar);
+ spare = ar; ar = dd;
+ sq--;
+ }
+ dd = mpmont_mul(mm, spare, d, ar);
+ spare = d; d = dd;
}
+ sq++;
if (!MP_STEP(&sc))
break;
- dd = mpmont_mul(mm, MP_NEW, ar, ar);
- MP_DROP(ar);
- ar = dd;
}
}
MP_DROP(ar);
- return (mpmont_reduce(mm, d, d));
+ if (spare != MP_NEW)
+ MP_DROP(spare);
+ return (d);
+}
+
+/* --- @mpmont_exp@ --- *
+ *
+ * Arguments: @mpmont *mm@ = pointer to Montgomery reduction context
+ * @const mp *a@ = base
+ * @const mp *e@ = exponent
+ *
+ * Returns: Result, %$a^e \bmod m$%.
+ */
+
+mp *mpmont_exp(mpmont *mm, const mp *a, const mp *e)
+{
+ mp *d = mpmont_expr(mm, a, e);
+ d = mpmont_reduce(mm, d, d);
+ return (d);
}
/*----- Test rig ----------------------------------------------------------*/
fputs("\n*** bad r", stderr);
fputs("\nm = ", stderr); mp_writefile(m, stderr, 10);
fputs("\nexpected ", stderr); mp_writefile(r, stderr, 10);
- fputs("\n found ", stderr); mp_writefile(r, stderr, 10);
+ fputs("\n found ", stderr); mp_writefile(mm.r, stderr, 10);
fputc('\n', stderr);
ok = 0;
}
fputs("\n*** bad r2", stderr);
fputs("\nm = ", stderr); mp_writefile(m, stderr, 10);
fputs("\nexpected ", stderr); mp_writefile(r2, stderr, 10);
- fputs("\n found ", stderr); mp_writefile(r2, stderr, 10);
+ fputs("\n found ", stderr); mp_writefile(mm.r2, stderr, 10);
fputc('\n', stderr);
ok = 0;
}