Dart DocumentationbignumMontgomery

Montgomery class

Montgomery reduction on BigInteger

class Montgomery {

 BigInteger m;

 var mp;
 var mpl;
 var mph;
 var um;
 var mt2;

 /**
  * 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;
 }

 /**
  * 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;
 }

 /**
  * x/R mod m
  */
 BigInteger revert(BigInteger x) {
   var r = BigInteger.nbi();
   x.copyTo(r);
   this.reduce(r);
   return r;
 }

 /**
  * 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);
   }
 }

 /**
  * r = "x^2/R mod m"; x != r
  */
 sqrTo(x,r) {
   x.squareTo(r);
   this.reduce(r);
 }

 /**
  * r = "xy/R mod m"; x,y != r
  */
 mulTo(x,y,r) {
   x.multiplyTo(y,r);
   this.reduce(r);
 }
}

Constructors

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;
}

Properties

BigInteger m #

m

var mp #

mp

var mph #

mph

var mpl #

mpl

var mt2 #

mt2

var um #

um

Methods

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;
}

mulTo(x, y, r) #

r = "xy/R mod m"; x,y != r

mulTo(x,y,r) {
 x.multiplyTo(y,r);
 this.reduce(r);
}

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);
 }
}

BigInteger revert(BigInteger x) #

x/R mod m

BigInteger revert(BigInteger x) {
 var r = BigInteger.nbi();
 x.copyTo(r);
 this.reduce(r);
 return r;
}

sqrTo(x, r) #

r = "x^2/R mod m"; x != r

sqrTo(x,r) {
 x.squareTo(r);
 this.reduce(r);
}