1 package com.hurlant.math
\r
3 use namespace bi_internal;
\r
5 * Montgomery reduction
\r
7 internal class MontgomeryReduction implements IReduction
\r
9 private var m:BigInteger;
\r
11 private var mpl:int;
\r
12 private var mph:int;
\r
14 private var mt2:int;
\r
15 public function MontgomeryReduction(m:BigInteger) {
\r
20 um = (1<<(BigInteger.DB-15))-1;
\r
26 public function convert(x:BigInteger):BigInteger {
\r
27 var r:BigInteger = new BigInteger;
\r
28 x.abs().dlShiftTo(m.t, r);
\r
29 r.divRemTo(m, null, r);
\r
30 if (x.s<0 && r.compareTo(BigInteger.ZERO)>0) {
\r
38 public function revert(x:BigInteger):BigInteger {
\r
39 var r:BigInteger = new BigInteger;
\r
45 * x = x/R mod m (HAC 14.32)
\r
47 public function reduce(x:BigInteger):void {
\r
48 while (x.t<=mt2) { // pad x so am has enough room later
\r
51 for (var i:int=0; i<m.t; ++i) {
\r
52 // faster way of calculating u0 = x[i]*mp mod DV
\r
53 var j:int = x.a[i]&0x7fff;
\r
54 var u0:int = (j*mpl+(((j*mph+(x.a[i]>>15)*mpl)&um)<<15))&BigInteger.DM;
\r
55 // use am to combine the multiply-shift-add into one call
\r
57 x.a[j] += m.am(0, u0, x, i, 0, m.t);
\r
59 while (x.a[j]>=BigInteger.DV) {
\r
60 x.a[j] -= BigInteger.DV;
\r
65 x.drShiftTo(m.t, x);
\r
66 if (x.compareTo(m)>=0) {
\r
71 * r = "x^2/R mod m"; x != r
\r
73 public function sqrTo(x:BigInteger, r:BigInteger):void {
\r
78 * r = "xy/R mod m"; x,y != r
\r
80 public function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void {
\r