Montgomery Class
Montgomery reduction on BigInteger
Constructors
Code new Montgomery(BigInteger m) #
Montgomery reduction
Montgomery(this.m) { this.mp = m.invDigit(); this.mpl = this.mp&0x7fff; this.mph = this.mp>>15; this.um = (1<<(BigInteger.BI_DB-15))-1; this.mt2 = 2*m.t; }
Methods
Code BigInteger convert(BigInteger x) #
xR mod m
BigInteger convert(BigInteger x) { var r = BigInteger.nbi(); x.abs().dlShiftTo(this.m.t,r); r.divRemTo(this.m,null,r); if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); return r; }
Code mulTo(x, y, r) #
r = "xy/R mod m"; x,y != r
mulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
Code void reduce(x) #
x = x/R mod m (HAC 14.32)
void reduce(x) { var x_array = x.array; while(x.t <= this.mt2) { // pad x so am has enough room later x_array[x.t++] = 0; } for(var i = 0; i < this.m.t; ++i) { // faster way of calculating u0 = x[i]*mp mod DV var j = x_array[i]&0x7fff; var u0 = (j*this.mpl+(((j*this.mph+(x_array[i]>>15)*this.mpl)&this.um)<<15))&BigInteger.BI_DM; // use am to combine the multiply-shift-add into one call j = i+this.m.t; x_array[j] += this.m.am(0,u0,x,i,0,this.m.t); // propagate carry while(x_array[j] >= BigInteger.BI_DV) { x_array[j] -= BigInteger.BI_DV; x_array[++j]++; } } x.clamp(); x.drShiftTo(this.m.t,x); if(x.compareTo(this.m) >= 0) { x.subTo(this.m,x); } }
Code BigInteger revert(BigInteger x) #
x/R mod m
BigInteger revert(BigInteger x) { var r = BigInteger.nbi(); x.copyTo(r); this.reduce(r); return r; }
Code sqrTo(x, r) #
r = "x^2/R mod m"; x != r
sqrTo(x,r) { x.squareTo(r); this.reduce(r); }
Fields
Code BigInteger m #
BigInteger m;
Code var mp #
var mp;
Code var mph #
var mph;
Code var mpl #
var mpl;
Code var mt2 #
var mt2;
Code var um #
var um;