UNPKG

eligendiexercitationem

Version:

Yet another class for arbitrary-precision integers in pure JavaScript. Small. Well tested.

1,341 lines (1,330 loc) 160 kB
(function(){ /* Written in 2013-2015 by Peter O. Parts of the code were adapted by Peter O. from the public-domain code from the library CryptoPP by Wei Dai. Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ If you like this, you should donate to Peter O. at: http://peteroupc.github.io/ */ if(typeof StringBuilder=="undefined"){ var StringBuilder=function(){ this.str=""; } } StringBuilder.prototype.append=function(ch){ if(typeof ch=="number") this.str+=String.fromCharCode(ch); else this.str+=ch } StringBuilder.prototype.length=function(){ return this.str.length } StringBuilder.prototype.charAt=function(index){ // Get the character code, since that's what the caller expects return this.str.charCodeAt(index) } StringBuilder.prototype.toString=function(){ return this.str; } if(typeof JSInteropFactory=="undefined"){ var JSInteropFactory={}; } ///////////////////////////////////// // Adapted by Peter O. from CryptoPP by Wei Dai JSInteropFactory.divideFourWordsByTwo=function(dividend, divisor){ var t0=(dividend.lo&0xFFFF); var t1=(dividend.lo>>>16); var t2=(dividend.hi&0xFFFF); var t3=(dividend.hi>>>16); var b0=(divisor&0xFFFF); var b1=(divisor>>>16); var ret=JSInteropFactory.divideThreeWordsByTwo(t1,t2,t3,b0,b1); var qhigh=ret[0]; ret=JSInteropFactory.divideThreeWordsByTwo(t0,ret[1],ret[2],b0,b1); var qlow=ret[0]; return [(qlow|(qhigh<<16))>>>0,(ret[1]|(ret[2]<<16))>>>0]; } // Adapted by Peter O. from CryptoPP by Wei Dai JSInteropFactory.divideThreeWordsByTwo=function(a0,a1,a2,b0,b1){ var q=0; if(b1==0xFFFF) q=a2; else if(b1>0) q=((((a1|(a2<<16))>>>0)/((b1+1)&0xFFFF))&0xFFFF)|0; else q=((((a1|(a2<<16))>>>0)/b0)&0xFFFF)|0; var p=(b0*q)>>>0; var u=(a0-(p&0xFFFF))>>>0; a0=(u&0xFFFF); u=(a1-(p>>>16)-(((0-(u>>>16)))&0xFFFF)-((b1*q)>>>0))>>>0; a1=(u&0xFFFF); a2=((a2+(u>>>16))&0xFFFF); while(a2!=0 || a1>b1 || (a1==b1 && a0>=b0)){ u=(a0-b0)>>>0; a0=(u&0xFFFF); u=(a1-b1-(((0-(u>>>16)))&0xFFFF))>>>0; a1=(u&0xFFFF); a2=((a2+(u>>>16))&0xFFFF); q++; q&=0xFFFF; } return [q,a0,a1,a2] } JSInteropFactory.divide64By32=function(dividendLow,dividendHigh,divisor){ var remainder=0 var currentDividend=new ILong(dividendHigh,0); var result=JSInteropFactory.divideFourWordsByTwo(currentDividend,divisor); var quotientHigh=result[0]; remainder=result[1]; currentDividend=new ILong(dividendLow,remainder); result=JSInteropFactory.divideFourWordsByTwo(currentDividend,divisor); var quotientLow=result[0]; return new ILong(quotientLow,quotientHigh); } ///////////////////////////////////////////// var ILong=function(lo,hi){ // Convert lo and hi to unsigned this.lo=lo>>>0 this.hi=hi>>>0 } ILong.prototype.signum=function(){ if((this.lo|this.hi)==0)return 0; return ((this.hi>>>31)!=0) ? -1 : 1; } ILong.prototype.equals=function(other){ return this.lo==other.lo && this.hi==other.hi } ILong.prototype.negate=function(){ var ret=new ILong(this.lo,this.hi); if((this.lo|this.hi)!=0)ret._twosComplement(); return ret; } ILong.prototype.or=function(other){ return new ILong(this.lo|other.lo,this.hi|other.hi); } ILong.prototype.andInt=function(otherUnsigned){ return new ILong(this.lo&(otherUnsigned>>>0),0); } ILong.prototype.intValue=function(){ return this.lo|0; } ILong.prototype.shortValue=function(){ return (this.lo|0)&0xFFFF; } ILong.prototype.compareToLongAsInts=function(otherLo,otherHi){ otherHi|=0; // Signed comparison of high words if(otherHi!=(this.hi|0)){ return (otherHi>(this.hi|0)) ? -1 : 1; } otherLo=otherLo>>>0; // Unsigned comparison of low words if(otherLo!=this.lo){ return (otherLo>this.lo) ? -1 : 1; } return 0; } ILong.prototype.compareToInt=function(other){ other|=0; var otherHi=(other<0) ? -1 : 0; // Signed comparison of high words if(otherHi!=(this.hi|0)){ return (otherHi>(this.hi|0)) ? -1 : 1; } other=other>>>0; // Unsigned comparison of low words if(other!=this.lo){ return (other>this.lo) ? -1 : 1; } return 0; } ILong.prototype.equalsInt=function(other){ if(other<0){ return (~this.hi)==0 && this.lo==(other>>>0); } else { return this.hi==0 && this.lo==(other>>>0); } } ILong.prototype._twosComplement=function(){ if(this.lo==0){ this.hi=((this.hi-1)>>>0); } this.lo=((this.lo-1)>>>0); this.lo=(~this.lo)>>>0; this.hi=(~this.hi)>>>0; } ILong.prototype.remainderWithUnsignedDivisor=function(divisor){ if((this.hi>>>31)!=0){ // value is negative var ret=new ILong(this.lo,this.hi); ret._twosComplement(); // NOTE: since divisor is unsigned, overflow is impossible ret=ret._remainderUnsignedDividendUnsigned(divisor); ret._twosComplement(); return ret; } else { return this._remainderUnsignedDividendUnsigned(divisor); } } ILong.prototype.divideWithUnsignedDivisor=function(divisor){ if((this.hi>>>31)!=0){ // value is negative var ret=new ILong(this.lo,this.hi); ret._twosComplement(); // NOTE: since divisor is unsigned, overflow is impossible ret=ret._divideUnsignedDividendUnsigned(divisor); ret._twosComplement(); return ret; } else { return this._divideUnsignedDividendUnsigned(divisor); } } ILong.prototype._divideUnsignedDividendUnsigned=function(divisor){ divisor|=0; if(divisor<0)throw new RuntimeException("value is less than 0"); if(divisor==1)return this; if (this.hi==0){ return new ILong((this.lo>>>0)/divisor,0); } else { var rem=JSInteropFactory.divide64By32(this.lo,this.hi,divisor); return rem; } } ILong.prototype._remainderUnsignedDividendUnsigned=function(divisor){ divisor|=0; if(divisor<0)throw new RuntimeException("value is less than 0"); if(divisor==1)return this; if (divisor < 0x10000 || this.hi==0) { var r=this.hi%divisor; r=((this.lo>>>16)|(r<<16))%divisor; return new ILong( (((this.lo&0xFFFF)|(r<<16))%divisor)&0xFFFF, 0 ); } else { var rem=JSInteropFactory.divideFourWordsByTwo(this,divisor); return new ILong(rem[1],(rem[1]>>>31)==0 ? 0 : (1<<31)); } } ILong.prototype.shiftLeft=function(len){ if(len<=0)return this; if(len>=64){ return JSInteropFactory.LONG_ZERO; } else if(len>=32){ return new ILong(0,this.lo<<(len-32)); } else if(this.lo==0){ return new ILong(0,this.hi<<len); } else { var newhigh=this.hi<<len; var newlow=this.lo<<len; newhigh|=(this.lo>>>(32-len)); return new ILong(newlow,newhigh); } } ILong.prototype.shiftRight=function(len){ if(len<=0)return this; if(len>=64){ return ((this.hi>>>31)!=0) ? JSInteropFactory.LONG_MAX_VALUE() : JSInteropFactory.LONG_MIN_VALUE(); } else if(len>=32){ return new ILong((this.hi>>len-32),((this.hi>>>31)!=0) ? (~0) : 0); } else if(this.hi==0){ return new ILong(this.lo>>>len,0); } else { var newhigh=this.hi>>len; var newlow=this.lo>>>len; newlow|=(this.hi<<(32-len)); return new ILong(newlow,newhigh); } } JSInteropFactory.createStringBuilder=function(param){ return new StringBuilder(); } JSInteropFactory.createLong=function(param){ if(param.constructor==ILong)return param; return new ILong(param,(param<0) ? (~0) : 0); } JSInteropFactory.createLongFromInts=function(a,b){ return new ILong(a>>>0,b>>>0); } JSInteropFactory.LONG_MIN_VALUE_=new ILong(0,(1<<31)); JSInteropFactory.LONG_MAX_VALUE_=new ILong(~0,~0); JSInteropFactory.LONG_MIN_VALUE=function(){ return JSInteropFactory.LONG_MIN_VALUE_; } JSInteropFactory.LONG_MAX_VALUE=function(){ return JSInteropFactory.LONG_MAX_VALUE_; } JSInteropFactory.LONG_ZERO=new ILong(0,0) var Extras={} Extras.IntegersToDouble=function(){throw "Not implemented"} Extras.DoubleToIntegers=function(){throw "Not implemented"} if(typeof exports!=="undefined"){ exports.Extras=Extras; exports.JSInteropFactory=JSInteropFactory; exports.ILong=ILong; exports.StringBuilder=StringBuilder; } var BigInteger = function(wordCount, reg, negative) { this.wordCount = wordCount; this.words = reg; this.negative = negative; }; (function(constructor,prototype){ constructor.CountWords = function(array, n) { while (n != 0 && array[n - 1] == 0) { --n; } return (n|0); }; constructor.ShiftWordsLeftByBits = function(r, rstart, n, shiftBits) { { var u, carry = 0; if (shiftBits != 0) { for (var i = 0; i < n; ++i) { u = r[rstart + i]; r[rstart + i] = (((((((((u << (shiftBits|0))|0) | (carry & 65535)))|0)) & 65535))|0); carry = (((u & 65535) >> ((16 - shiftBits)|0))|0); } } return carry; } }; constructor.ShiftWordsRightByBits = function(r, rstart, n, shiftBits) { var u, carry = 0; { if (shiftBits != 0) { for (var i = n; i > 0; --i) { u = r[rstart + i - 1]; r[rstart + i - 1] = ((((((((((u & 65535) >> (shiftBits|0)) & 65535) | (carry & 65535)))|0)) & 65535))|0); carry = (((u & 65535) << ((16 - shiftBits)|0))|0); } } return carry; } }; constructor.ShiftWordsRightByBitsSignExtend = function(r, rstart, n, shiftBits) { { var u, carry = ((65535 << ((16 - shiftBits)|0))|0); if (shiftBits != 0) { for (var i = n; i > 0; --i) { u = r[rstart + i - 1]; r[rstart + i - 1] = ((((((((u & 65535) >> (shiftBits|0)) | (carry & 65535))|0)) & 65535))|0); carry = (((u & 65535) << ((16 - shiftBits)|0))|0); } } return carry; } }; constructor.ShiftWordsLeftByWords = function(r, rstart, n, shiftWords) { shiftWords = (shiftWords < n ? shiftWords : n); if (shiftWords != 0) { for (var i = n - 1; i >= shiftWords; --i) { r[rstart + i] = ((r[rstart + i - shiftWords]) & 65535); } for (var arrfillI = rstart; arrfillI < (rstart) + (shiftWords); arrfillI++) (r)[arrfillI] = 0; } }; constructor.ShiftWordsRightByWordsSignExtend = function(r, rstart, n, shiftWords) { shiftWords = (shiftWords < n ? shiftWords : n); if (shiftWords != 0) { for (var i = 0; i + shiftWords < n; ++i) { r[rstart + i] = ((r[rstart + i + shiftWords]) & 65535); } rstart = rstart + (n - shiftWords); for (var i = 0; i < shiftWords; ++i) { r[rstart + i] = (65535 & 65535); } } }; constructor.Compare = function(words1, astart, words2, bstart, n) { while ((n--) != 0) { var an = (words1[astart + n]) & 65535; var bn = (words2[bstart + n]) & 65535; if (an > bn) { return 1; } if (an < bn) { return -1; } } return 0; }; constructor.CompareWithOneBiggerWords1 = function(words1, astart, words2, bstart, words1Count) { if (words1[astart + words1Count - 1] != 0) { return 1; } var w1c = words1Count; --w1c; while ((w1c--) != 0) { var an = (words1[astart + w1c]) & 65535; var bn = (words2[bstart + w1c]) & 65535; if (an > bn) { return 1; } if (an < bn) { return -1; } } return 0; }; constructor.Increment = function(words1, words1Start, n, words2) { { var tmp = ((words1[words1Start]) & 65535); words1[words1Start] = ((tmp + words2) & 65535); if (((words1[words1Start]) & 65535) >= (tmp & 65535)) { return 0; } for (var i = 1; i < n; ++i) { words1[words1Start + i] = ((words1[words1Start + i] + 1) & 65535); if (words1[words1Start + i] != 0) { return 0; } } return 1; } }; constructor.Decrement = function(words1, words1Start, n, words2) { { var tmp = ((words1[words1Start]) & 65535); words1[words1Start] = ((tmp - words2) & 65535); if (((words1[words1Start]) & 65535) <= (tmp & 65535)) { return 0; } for (var i = 1; i < n; ++i) { tmp = words1[words1Start + i]; words1[words1Start + i] = ((words1[words1Start + i] - 1) & 65535); if (tmp != 0) { return 0; } } return 1; } }; constructor.TwosComplement = function(words1, words1Start, n) { BigInteger.Decrement(words1, words1Start, n, 1); for (var i = 0; i < n; ++i) { words1[words1Start + i] = ((~words1[words1Start + i]) & 65535); } }; constructor.Add = function(c, cstart, words1, astart, words2, bstart, n) { { var u; u = 0; for (var i = 0; i < n; i += 2) { u = ((words1[astart + i]) & 65535) + ((words2[bstart + i]) & 65535) + ((u >> 16)|0); c[cstart + i] = (u & 65535); u = ((words1[astart + i + 1]) & 65535) + ((words2[bstart + i + 1]) & 65535) + ((u >> 16)|0); c[cstart + i + 1] = (u & 65535); } return ((u) >>> 16); } }; constructor.AddOneByOne = function(c, cstart, words1, astart, words2, bstart, n) { { var u; u = 0; for (var i = 0; i < n; i += 1) { u = ((words1[astart + i]) & 65535) + ((words2[bstart + i]) & 65535) + ((u >> 16)|0); c[cstart + i] = (u & 65535); } return ((u) >>> 16); } }; constructor.SubtractOneBiggerWords1 = function(c, cstart, words1, astart, words2, bstart, words1Count) { { var u; u = 0; var cm1 = words1Count - 1; for (var i = 0; i < cm1; i += 1) { u = ((words1[astart]) & 65535) - ((words2[bstart]) & 65535) - ((u >> 31) & 1); c[cstart++] = (u & 65535); ++astart; ++bstart; } u = ((words1[astart]) & 65535) - ((u >> 31) & 1); c[cstart++] = (u & 65535); return ((u >> 31) & 1); } }; constructor.SubtractOneBiggerWords2 = function(c, cstart, words1, astart, words2, bstart, words2Count) { { var u; u = 0; var cm1 = words2Count - 1; for (var i = 0; i < cm1; i += 1) { u = ((words1[astart]) & 65535) - ((words2[bstart]) & 65535) - ((u >> 31) & 1); c[cstart++] = (u & 65535); ++astart; ++bstart; } u = 0 - ((words2[bstart]) & 65535) - ((u >> 31) & 1); c[cstart++] = (u & 65535); return ((u >> 31) & 1); } }; constructor.AddUnevenSize = function(c, cstart, wordsBigger, astart, acount, wordsSmaller, bstart, bcount) { { var u; u = 0; for (var i = 0; i < bcount; i += 1) { u = ((wordsBigger[astart + i]) & 65535) + ((wordsSmaller[bstart + i]) & 65535) + ((u >> 16)|0); c[cstart + i] = (u & 65535); } for (var i = bcount; i < acount; i += 1) { u = ((wordsBigger[astart + i]) & 65535) + ((u >> 16)|0); c[cstart + i] = (u & 65535); } return ((u) >>> 16); } }; constructor.Subtract = function(c, cstart, words1, astart, words2, bstart, n) { { var u; u = 0; for (var i = 0; i < n; i += 2) { u = ((words1[astart]) & 65535) - ((words2[bstart]) & 65535) - ((u >> 31) & 1); c[cstart++] = (u & 65535); ++astart; ++bstart; u = ((words1[astart]) & 65535) - ((words2[bstart]) & 65535) - ((u >> 31) & 1); c[cstart++] = (u & 65535); ++astart; ++bstart; } return ((u >> 31) & 1); } }; constructor.SubtractOneByOne = function(c, cstart, words1, astart, words2, bstart, n) { { var u; u = 0; for (var i = 0; i < n; i += 1) { u = ((words1[astart]) & 65535) - ((words2[bstart]) & 65535) - ((u >> 31) & 1); c[cstart++] = (u & 65535); ++astart; ++bstart; } return ((u >> 31) & 1); } }; constructor.LinearMultiplyAdd = function(productArr, cstart, words1, astart, words2, n) { { var carry = 0; var bint = (words2) & 65535; for (var i = 0; i < n; ++i) { var p; p = ((words1[astart + i]) & 65535) * bint; p = p + (carry & 65535); p = p + ((productArr[cstart + i]) & 65535); productArr[cstart + i] = (p & 65535); carry = ((p >> 16)|0); } return carry; } }; constructor.LinearMultiply = function(productArr, cstart, words1, astart, words2, n) { { var carry = 0; var bint = (words2) & 65535; for (var i = 0; i < n; ++i) { var p; p = ((words1[astart + i]) & 65535) * bint; p = p + (carry & 65535); productArr[cstart + i] = (p & 65535); carry = ((p >> 16)|0); } return carry; } }; constructor.BaselineSquare2 = function(result, rstart, words1, astart) { { var p; var c; var d; var e; p = ((words1[astart]) & 65535) * ((words1[astart]) & 65535); result[rstart] = (p & 65535); e = ((p) >>> 16); p = ((words1[astart]) & 65535) * ((words1[astart + 1]) & 65535); c = (p|0); d = ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 1] = (c & 65535); p = ((words1[astart + 1]) & 65535) * ((words1[astart + 1]) & 65535); p = p + (e); result[rstart + 2] = (p & 65535); result[rstart + 3] = ((p) >>> 16); } }; constructor.BaselineSquare4 = function(result, rstart, words1, astart) { { var p; var c; var d; var e; p = ((words1[astart]) & 65535) * ((words1[astart]) & 65535); result[rstart] = (p & 65535); e = ((p) >>> 16); p = ((words1[astart]) & 65535) * ((words1[astart + 1]) & 65535); c = (p|0); d = ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 1] = (c & 65535); p = ((words1[astart]) & 65535) * ((words1[astart + 2]) & 65535); c = (p|0); d = ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; p = ((words1[astart + 1]) & 65535) * ((words1[astart + 1]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 2] = (c & 65535); p = ((words1[astart]) & 65535) * ((words1[astart + 3]) & 65535); c = (p|0); d = ((p) >>> 16); p = ((words1[astart + 1]) & 65535) * ((words1[astart + 2]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 3] = (c & 65535); p = ((words1[astart + 1]) & 65535) * ((words1[astart + 3]) & 65535); c = (p|0); d = ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; p = ((words1[astart + 2]) & 65535) * ((words1[astart + 2]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 4] = (c & 65535); p = ((words1[astart + 2]) & 65535) * ((words1[astart + 3]) & 65535); c = (p|0); d = ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + (2 * 4) - 3] = (c & 65535); p = ((words1[astart + 3]) & 65535) * ((words1[astart + 3]) & 65535); p = p + (e); result[rstart + 6] = (p & 65535); result[rstart + 7] = ((p) >>> 16); } }; constructor.BaselineSquare8 = function(result, rstart, words1, astart) { { var p; var c; var d; var e; p = ((words1[astart]) & 65535) * ((words1[astart]) & 65535); result[rstart] = (p & 65535); e = ((p) >>> 16); p = ((words1[astart]) & 65535) * ((words1[astart + 1]) & 65535); c = (p|0); d = ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 1] = (c & 65535); p = ((words1[astart]) & 65535) * ((words1[astart + 2]) & 65535); c = (p|0); d = ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; p = ((words1[astart + 1]) & 65535) * ((words1[astart + 1]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 2] = (c & 65535); p = ((words1[astart]) & 65535) * ((words1[astart + 3]) & 65535); c = (p|0); d = ((p) >>> 16); p = ((words1[astart + 1]) & 65535) * ((words1[astart + 2]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 3] = (c & 65535); p = ((words1[astart]) & 65535) * ((words1[astart + 4]) & 65535); c = (p|0); d = ((p) >>> 16); p = ((words1[astart + 1]) & 65535) * ((words1[astart + 3]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; p = ((words1[astart + 2]) & 65535) * ((words1[astart + 2]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 4] = (c & 65535); p = ((words1[astart]) & 65535) * ((words1[astart + 5]) & 65535); c = (p|0); d = ((p) >>> 16); p = ((words1[astart + 1]) & 65535) * ((words1[astart + 4]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 2]) & 65535) * ((words1[astart + 3]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 5] = (c & 65535); p = ((words1[astart]) & 65535) * ((words1[astart + 6]) & 65535); c = (p|0); d = ((p) >>> 16); p = ((words1[astart + 1]) & 65535) * ((words1[astart + 5]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 2]) & 65535) * ((words1[astart + 4]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; p = ((words1[astart + 3]) & 65535) * ((words1[astart + 3]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 6] = (c & 65535); p = ((words1[astart]) & 65535) * ((words1[astart + 7]) & 65535); c = (p|0); d = ((p) >>> 16); p = ((words1[astart + 1]) & 65535) * ((words1[astart + 6]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 2]) & 65535) * ((words1[astart + 5]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 3]) & 65535) * ((words1[astart + 4]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 7] = (c & 65535); p = ((words1[astart + 1]) & 65535) * ((words1[astart + 7]) & 65535); c = (p|0); d = ((p) >>> 16); p = ((words1[astart + 2]) & 65535) * ((words1[astart + 6]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 3]) & 65535) * ((words1[astart + 5]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; p = ((words1[astart + 4]) & 65535) * ((words1[astart + 4]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 8] = (c & 65535); p = ((words1[astart + 2]) & 65535) * ((words1[astart + 7]) & 65535); c = (p|0); d = ((p) >>> 16); p = ((words1[astart + 3]) & 65535) * ((words1[astart + 6]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 4]) & 65535) * ((words1[astart + 5]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 9] = (c & 65535); p = ((words1[astart + 3]) & 65535) * ((words1[astart + 7]) & 65535); c = (p|0); d = ((p) >>> 16); p = ((words1[astart + 4]) & 65535) * ((words1[astart + 6]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; p = ((words1[astart + 5]) & 65535) * ((words1[astart + 5]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 10] = (c & 65535); p = ((words1[astart + 4]) & 65535) * ((words1[astart + 7]) & 65535); c = (p|0); d = ((p) >>> 16); p = ((words1[astart + 5]) & 65535) * ((words1[astart + 6]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 11] = (c & 65535); p = ((words1[astart + 5]) & 65535) * ((words1[astart + 7]) & 65535); c = (p|0); d = ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; p = ((words1[astart + 6]) & 65535) * ((words1[astart + 6]) & 65535); p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 12] = (c & 65535); p = ((words1[astart + 6]) & 65535) * ((words1[astart + 7]) & 65535); c = (p|0); d = ((p) >>> 16); d = ((((d << 1) + (((c|0) >> 15) & 1)))|0); c <<= 1; e = e + (c & 65535); c = (e|0); e = d + ((e) >>> 16); result[rstart + 13] = (c & 65535); p = ((words1[astart + 7]) & 65535) * ((words1[astart + 7]) & 65535); p = p + (e); result[rstart + 14] = (p & 65535); result[rstart + 15] = ((p) >>> 16); } }; constructor.BaselineMultiply2 = function(result, rstart, words1, astart, words2, bstart) { { var p; var c; var d; var a0 = (words1[astart]) & 65535; var a1 = (words1[astart + 1]) & 65535; var b0 = (words2[bstart]) & 65535; var b1 = (words2[bstart + 1]) & 65535; p = a0 * b0; c = (p|0); d = ((p) >>> 16); result[rstart] = (c & 65535); c = (d|0); d = ((d) >>> 16); p = a0 * b1; p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); p = a1 * b0; p = p + (c & 65535); c = (p|0); d = d + ((p) >>> 16); result[rstart + 1] = (c & 65535); p = a1 * b1; p = p + (d); result[rstart + 2] = (p & 65535); result[rstart + 3] = ((p) >>> 16); } }; constructor.ShortMask = 65535; constructor.BaselineMultiply4 = function(result, rstart, words1, astart, words2, bstart) { { var SMask = BigInteger.ShortMask; var p; var c; var d; var a0 = (words1[astart]) & SMask; var b0 = (words2[bstart]) & SMask; p = a0 * b0; c = (p|0); d = (p) >>> 16; result[rstart] = (c & 65535); c = (d|0); d = (d) >>> 16; p = a0 * ((words2[bstart + 1]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 1]) & SMask) * b0; p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 1] = (c & 65535); c = (d|0); d = (d) >>> 16; p = a0 * ((words2[bstart + 2]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 1]) & SMask) * ((words2[bstart + 1]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 2]) & SMask) * b0; p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 2] = (c & 65535); c = (d|0); d = (d) >>> 16; p = a0 * ((words2[bstart + 3]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 1]) & SMask) * ((words2[bstart + 2]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 2]) & SMask) * ((words2[bstart + 1]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 3]) & SMask) * b0; p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 3] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart + 1]) & SMask) * ((words2[bstart + 3]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 2]) & SMask) * ((words2[bstart + 2]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 3]) & SMask) * ((words2[bstart + 1]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 4] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart + 2]) & SMask) * ((words2[bstart + 3]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 3]) & SMask) * ((words2[bstart + 2]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 5] = (c & 65535); p = ((words1[astart + 3]) & SMask) * ((words2[bstart + 3]) & SMask); p = p + (d); result[rstart + 6] = (p & 65535); result[rstart + 7] = ((p) >>> 16); } }; constructor.BaselineMultiply8 = function(result, rstart, words1, astart, words2, bstart) { { var p; var c; var d; var SMask = BigInteger.ShortMask; p = ((words1[astart]) & SMask) * ((words2[bstart]) & SMask); c = (p|0); d = (p) >>> 16; result[rstart] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart]) & SMask) * ((words2[bstart + 1]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 1]) & SMask) * ((words2[bstart]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 1] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart]) & SMask) * ((words2[bstart + 2]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 1]) & SMask) * ((words2[bstart + 1]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 2]) & SMask) * ((words2[bstart]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 2] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart]) & SMask) * ((words2[bstart + 3]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 1]) & SMask) * ((words2[bstart + 2]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 2]) & SMask) * ((words2[bstart + 1]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 3]) & SMask) * ((words2[bstart]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 3] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart]) & SMask) * ((words2[bstart + 4]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 1]) & SMask) * ((words2[bstart + 3]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 2]) & SMask) * ((words2[bstart + 2]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 3]) & SMask) * ((words2[bstart + 1]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 4]) & SMask) * ((words2[bstart]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 4] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart]) & SMask) * ((words2[bstart + 5]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 1]) & SMask) * ((words2[bstart + 4]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 2]) & SMask) * ((words2[bstart + 3]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 3]) & SMask) * ((words2[bstart + 2]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 4]) & SMask) * ((words2[bstart + 1]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 5]) & SMask) * ((words2[bstart]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 5] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart]) & SMask) * ((words2[bstart + 6]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 1]) & SMask) * ((words2[bstart + 5]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 2]) & SMask) * ((words2[bstart + 4]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 3]) & SMask) * ((words2[bstart + 3]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 4]) & SMask) * ((words2[bstart + 2]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 5]) & SMask) * ((words2[bstart + 1]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 6]) & SMask) * ((words2[bstart]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 6] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart]) & SMask) * ((words2[bstart + 7]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 1]) & SMask) * ((words2[bstart + 6]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 2]) & SMask) * ((words2[bstart + 5]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 3]) & SMask) * ((words2[bstart + 4]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 4]) & SMask) * ((words2[bstart + 3]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 5]) & SMask) * ((words2[bstart + 2]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 6]) & SMask) * ((words2[bstart + 1]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 7]) & SMask) * ((words2[bstart]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 7] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart + 1]) & SMask) * ((words2[bstart + 7]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 2]) & SMask) * ((words2[bstart + 6]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 3]) & SMask) * ((words2[bstart + 5]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 4]) & SMask) * ((words2[bstart + 4]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 5]) & SMask) * ((words2[bstart + 3]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 6]) & SMask) * ((words2[bstart + 2]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 7]) & SMask) * ((words2[bstart + 1]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 8] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart + 2]) & SMask) * ((words2[bstart + 7]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 3]) & SMask) * ((words2[bstart + 6]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 4]) & SMask) * ((words2[bstart + 5]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 5]) & SMask) * ((words2[bstart + 4]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 6]) & SMask) * ((words2[bstart + 3]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 7]) & SMask) * ((words2[bstart + 2]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 9] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart + 3]) & SMask) * ((words2[bstart + 7]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 4]) & SMask) * ((words2[bstart + 6]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 5]) & SMask) * ((words2[bstart + 5]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 6]) & SMask) * ((words2[bstart + 4]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 7]) & SMask) * ((words2[bstart + 3]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 10] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart + 4]) & SMask) * ((words2[bstart + 7]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 5]) & SMask) * ((words2[bstart + 6]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 6]) & SMask) * ((words2[bstart + 5]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 7]) & SMask) * ((words2[bstart + 4]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 11] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart + 5]) & SMask) * ((words2[bstart + 7]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 6]) & SMask) * ((words2[bstart + 6]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 7]) & SMask) * ((words2[bstart + 5]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 12] = (c & 65535); c = (d|0); d = (d) >>> 16; p = ((words1[astart + 6]) & SMask) * ((words2[bstart + 7]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); p = ((words1[astart + 7]) & SMask) * ((words2[bstart + 6]) & SMask); p = p + ((c) & SMask); c = (p|0); d = d + ((p) >>> 16); result[rstart + 13] = (c & 65535); p = ((words1[astart + 7]) & SMask) * ((words2[bstart + 7]) & SMask); p = p + (d); result[rstart + 14] = (p & 65535); result[rstart + 15] = ((p) >>> 16); } }; constructor.RecursionLimit = 10; constructor.SameSizeMultiply = function(resultArr, resultStart, tempArr, tempStart, words1, words1Start, words2, words2Start, count) { if (count <= BigInteger.RecursionLimit) { if (count == 2) { BigInteger.BaselineMultiply2(resultArr, resultStart, words1, words1Start, words2, words2Start); } else if (count == 4) { BigInteger.BaselineMultiply4(resultArr, resultStart, words1, words1Start, words2, words2Start); } else if (count == 8) { BigInteger.BaselineMultiply8(resultArr, resultStart, words1, words1Start, words2, words2Start); } else { BigInteger.SchoolbookMultiply(resultArr, resultStart, words1, words1Start, count, words2, words2Start, count); } } else { var countA = count; while (countA != 0 && words1[words1Start + countA - 1] == 0) { --countA; } var countB = count; while (countB != 0 && words2[words2Start + countB - 1] == 0) { --countB; } var offset2For1 = 0; var offset2For2 = 0; if (countA == 0 || countB == 0) { for (var arrfillI = resultStart; arrfillI < (resultStart) + (count << 1); arrfillI++) (resultArr)[arrfillI] = 0; return; } if ((count & 1) == 0) { var count2 = count >> 1; if (countA <= count2 && countB <= count2) { for (var arrfillI = resultStart + count; arrfillI < (resultStart + count) + (count); arrfillI++) (resultArr)[arrfillI] = 0; if (count2 == 8) { BigInteger.BaselineMultiply8(resultArr, resultStart, words1, words1Start, words2, words2Start); } else { BigInteger.SameSizeMultiply(resultArr, resultStart, tempArr, tempStart, words1, words1Start, words2, words2Start, count2); } return; } var resultMediumHigh = resultStart + count; var resultHigh = resultMediumHigh + count2; var resultMediumLow = resultStart + count2; var tsn = tempStart + count; offset2For1 = BigInteger.Compare(words1, words1Start, words1, words1Start + count2, count2) > 0 ? 0 : count2; var tmpvar = ((words1Start + (count2 ^ offset2For1))|0); BigInteger.SubtractOneByOne(resultArr, resultStart, words1, words1Start + offset2For1, words1, tmpvar, count2); offset2For2 = BigInteger.Compare(words2, words2Start, words2, words2Start + count2, count2) > 0 ? 0 : count2; var tmp = words2Start + (count2 ^ offset2For2); BigInteger.SubtractOneByOne(resultArr, resultMediumLow, words2, words2Start + offset2For2, words2, tmp, count2); BigInteger.SameSizeMultiply(resultArr, resultMediu