eligendiexercitationem
Version:
Yet another class for arbitrary-precision integers in pure JavaScript. Small. Well tested.
1,341 lines (1,330 loc) • 160 kB
JavaScript
(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