Skip to main content
Go to Latest
File
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.// Copyright 2015 Fedor Indutny. All rights reserved. MIT license.// deno-lint-ignore-file no-var no-inner-declarations no-this-alias no-unused-vars
import { Buffer } from "../../../buffer.ts";
// Utilsfunction assert(val, msg) { if (!val) throw new Error(msg || "Assertion failed");}
// Could use `inherits` module, but don't want to move from single file// architecture yet.function inherits(ctor, superCtor) { ctor.super_ = superCtor; var TempCtor = function () {}; TempCtor.prototype = superCtor.prototype; ctor.prototype = new TempCtor(); ctor.prototype.constructor = ctor;}
// BNexport function BN(number, base, endian) { if (BN.isBN(number)) { return number; }
this.negative = 0; this.words = null; this.length = 0;
// Reduction context this.red = null;
if (number !== null) { if (base === "le" || base === "be") { endian = base; base = 10; }
this._init(number || 0, base || 10, endian || "be"); }}export default BN;
BN.BN = BN;BN.wordSize = 26;
BN.isBN = function isBN(num) { if (num instanceof BN) { return true; }
return num !== null && typeof num === "object" && num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);};
BN.max = function max(left, right) { if (left.cmp(right) > 0) return left; return right;};
BN.min = function min(left, right) { if (left.cmp(right) < 0) return left; return right;};
BN.prototype._init = function init(number, base, endian) { if (typeof number === "number") { return this._initNumber(number, base, endian); }
if (typeof number === "object") { return this._initArray(number, base, endian); }
if (base === "hex") { base = 16; } assert(base === (base | 0) && base >= 2 && base <= 36);
number = number.toString().replace(/\s+/g, ""); var start = 0; if (number[0] === "-") { start++; this.negative = 1; }
if (start < number.length) { if (base === 16) { this._parseHex(number, start, endian); } else { this._parseBase(number, base, start); if (endian === "le") { this._initArray(this.toArray(), base, endian); } } }};
BN.prototype._initNumber = function _initNumber(number, base, endian) { if (number < 0) { this.negative = 1; number = -number; } if (number < 0x4000000) { this.words = [number & 0x3ffffff]; this.length = 1; } else if (number < 0x10000000000000) { this.words = [ number & 0x3ffffff, (number / 0x4000000) & 0x3ffffff, ]; this.length = 2; } else { assert(number < 0x20000000000000); // 2 ^ 53 (unsafe) this.words = [ number & 0x3ffffff, (number / 0x4000000) & 0x3ffffff, 1, ]; this.length = 3; }
if (endian !== "le") return;
// Reverse the bytes this._initArray(this.toArray(), base, endian);};
BN.prototype._initArray = function _initArray(number, base, endian) { // Perhaps a Uint8Array assert(typeof number.length === "number"); if (number.length <= 0) { this.words = [0]; this.length = 1; return this; }
this.length = Math.ceil(number.length / 3); this.words = new Array(this.length); for (var i = 0; i < this.length; i++) { this.words[i] = 0; }
var j, w; var off = 0; if (endian === "be") { for (i = number.length - 1, j = 0; i >= 0; i -= 3) { w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16); this.words[j] |= (w << off) & 0x3ffffff; this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; off += 24; if (off >= 26) { off -= 26; j++; } } } else if (endian === "le") { for (i = 0, j = 0; i < number.length; i += 3) { w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16); this.words[j] |= (w << off) & 0x3ffffff; this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; off += 24; if (off >= 26) { off -= 26; j++; } } } return this._strip();};
function parseHex4Bits(string, index) { var c = string.charCodeAt(index); // '0' - '9' if (c >= 48 && c <= 57) { return c - 48; // 'A' - 'F' } else if (c >= 65 && c <= 70) { return c - 55; // 'a' - 'f' } else if (c >= 97 && c <= 102) { return c - 87; } else { assert(false, "Invalid character in " + string); }}
function parseHexByte(string, lowerBound, index) { var r = parseHex4Bits(string, index); if (index - 1 >= lowerBound) { r |= parseHex4Bits(string, index - 1) << 4; } return r;}
BN.prototype._parseHex = function _parseHex(number, start, endian) { // Create possibly bigger array to ensure that it fits the number this.length = Math.ceil((number.length - start) / 6); this.words = new Array(this.length); for (var i = 0; i < this.length; i++) { this.words[i] = 0; }
// 24-bits chunks var off = 0; var j = 0;
var w; if (endian === "be") { for (i = number.length - 1; i >= start; i -= 2) { w = parseHexByte(number, start, i) << off; this.words[j] |= w & 0x3ffffff; if (off >= 18) { off -= 18; j += 1; this.words[j] |= w >>> 26; } else { off += 8; } } } else { var parseLength = number.length - start; for ( i = parseLength % 2 === 0 ? start + 1 : start; i < number.length; i += 2 ) { w = parseHexByte(number, start, i) << off; this.words[j] |= w & 0x3ffffff; if (off >= 18) { off -= 18; j += 1; this.words[j] |= w >>> 26; } else { off += 8; } } }
this._strip();};
function parseBase(str, start, end, mul) { var r = 0; var b = 0; var len = Math.min(str.length, end); for (var i = start; i < len; i++) { var c = str.charCodeAt(i) - 48;
r *= mul;
// 'a' if (c >= 49) { b = c - 49 + 0xa;
// 'A' } else if (c >= 17) { b = c - 17 + 0xa;
// '0' - '9' } else { b = c; } assert(c >= 0 && b < mul, "Invalid character"); r += b; } return r;}
BN.prototype._parseBase = function _parseBase(number, base, start) { // Initialize as zero this.words = [0]; this.length = 1;
// Find length of limb in base for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) { limbLen++; } limbLen--; limbPow = (limbPow / base) | 0;
var total = number.length - start; var mod = total % limbLen; var end = Math.min(total, total - mod) + start;
var word = 0; for (var i = start; i < end; i += limbLen) { word = parseBase(number, i, i + limbLen, base);
this.imuln(limbPow); if (this.words[0] + word < 0x4000000) { this.words[0] += word; } else { this._iaddn(word); } }
if (mod !== 0) { var pow = 1; word = parseBase(number, i, number.length, base);
for (i = 0; i < mod; i++) { pow *= base; }
this.imuln(pow); if (this.words[0] + word < 0x4000000) { this.words[0] += word; } else { this._iaddn(word); } }
this._strip();};
BN.prototype.copy = function copy(dest) { dest.words = new Array(this.length); for (var i = 0; i < this.length; i++) { dest.words[i] = this.words[i]; } dest.length = this.length; dest.negative = this.negative; dest.red = this.red;};
function move(dest, src) { dest.words = src.words; dest.length = src.length; dest.negative = src.negative; dest.red = src.red;}
BN.prototype._move = function _move(dest) { move(dest, this);};
BN.prototype.clone = function clone() { var r = new BN(null); this.copy(r); return r;};
BN.prototype._expand = function _expand(size) { while (this.length < size) { this.words[this.length++] = 0; } return this;};
// Remove leading `0` from `this`BN.prototype._strip = function strip() { while (this.length > 1 && this.words[this.length - 1] === 0) { this.length--; } return this._normSign();};
BN.prototype._normSign = function _normSign() { // -0 = 0 if (this.length === 1 && this.words[0] === 0) { this.negative = 0; } return this;};
// Check Symbol.for because not everywhere where Symbol defined// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#Browser_compatibilityif (typeof Symbol !== "undefined" && typeof Symbol.for === "function") { try { BN.prototype[Symbol.for("nodejs.util.inspect.custom")] = inspect; } catch (e) { BN.prototype.inspect = inspect; }} else { BN.prototype.inspect = inspect;}
function inspect() { return (this.red ? "<BN-R: " : "<BN: ") + this.toString(16) + ">";}
/*
var zeros = []; var groupSizes = []; var groupBases = [];
var s = ''; var i = -1; while (++i < BN.wordSize) { zeros[i] = s; s += '0'; } groupSizes[0] = 0; groupSizes[1] = 0; groupBases[0] = 0; groupBases[1] = 0; var base = 2 - 1; while (++base < 36 + 1) { var groupSize = 0; var groupBase = 1; while (groupBase < (1 << BN.wordSize) / base) { groupBase *= base; groupSize += 1; } groupSizes[base] = groupSize; groupBases[base] = groupBase; }
*/
var zeros = [ "", "0", "00", "000", "0000", "00000", "000000", "0000000", "00000000", "000000000", "0000000000", "00000000000", "000000000000", "0000000000000", "00000000000000", "000000000000000", "0000000000000000", "00000000000000000", "000000000000000000", "0000000000000000000", "00000000000000000000", "000000000000000000000", "0000000000000000000000", "00000000000000000000000", "000000000000000000000000", "0000000000000000000000000",];
var groupSizes = [ 0, 0, 25, 16, 12, 11, 10, 9, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,];
var groupBases = [ 0, 0, 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216, 43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625, 16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632, 6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149, 24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176,];
BN.prototype.toString = function toString(base, padding) { base = base || 10; padding = padding | 0 || 1;
var out; if (base === 16 || base === "hex") { out = ""; var off = 0; var carry = 0; for (var i = 0; i < this.length; i++) { var w = this.words[i]; var word = (((w << off) | carry) & 0xffffff).toString(16); carry = (w >>> (24 - off)) & 0xffffff; if (carry !== 0 || i !== this.length - 1) { out = zeros[6 - word.length] + word + out; } else { out = word + out; } off += 2; if (off >= 26) { off -= 26; i--; } } if (carry !== 0) { out = carry.toString(16) + out; } while (out.length % padding !== 0) { out = "0" + out; } if (this.negative !== 0) { out = "-" + out; } return out; }
if (base === (base | 0) && base >= 2 && base <= 36) { // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base)); var groupSize = groupSizes[base]; // var groupBase = Math.pow(base, groupSize); var groupBase = groupBases[base]; out = ""; var c = this.clone(); c.negative = 0; while (!c.isZero()) { var r = c.modrn(groupBase).toString(base); c = c.idivn(groupBase);
if (!c.isZero()) { out = zeros[groupSize - r.length] + r + out; } else { out = r + out; } } if (this.isZero()) { out = "0" + out; } while (out.length % padding !== 0) { out = "0" + out; } if (this.negative !== 0) { out = "-" + out; } return out; }
assert(false, "Base should be between 2 and 36");};
BN.prototype.toNumber = function toNumber() { var ret = this.words[0]; if (this.length === 2) { ret += this.words[1] * 0x4000000; } else if (this.length === 3 && this.words[2] === 0x01) { // NOTE: at this stage it is known that the top bit is set ret += 0x10000000000000 + (this.words[1] * 0x4000000); } else if (this.length > 2) { assert(false, "Number can only safely store up to 53 bits"); } return (this.negative !== 0) ? -ret : ret;};
BN.prototype.toJSON = function toJSON() { return this.toString(16, 2);};
if (Buffer) { BN.prototype.toBuffer = function toBuffer(endian, length) { return this.toArrayLike(Buffer, endian, length); };}
BN.prototype.toArray = function toArray(endian, length) { return this.toArrayLike(Array, endian, length);};
var allocate = function allocate(ArrayType, size) { if (ArrayType.allocUnsafe) { return ArrayType.allocUnsafe(size); } return new ArrayType(size);};
BN.prototype.toArrayLike = function toArrayLike(ArrayType, endian, length) { this._strip();
var byteLength = this.byteLength(); var reqLength = length || Math.max(1, byteLength); assert(byteLength <= reqLength, "byte array longer than desired length"); assert(reqLength > 0, "Requested array length <= 0");
var res = allocate(ArrayType, reqLength); var postfix = endian === "le" ? "LE" : "BE"; this["_toArrayLike" + postfix](res, byteLength); return res;};
BN.prototype._toArrayLikeLE = function _toArrayLikeLE(res, byteLength) { var position = 0; var carry = 0;
for (var i = 0, shift = 0; i < this.length; i++) { var word = (this.words[i] << shift) | carry;
res[position++] = word & 0xff; if (position < res.length) { res[position++] = (word >> 8) & 0xff; } if (position < res.length) { res[position++] = (word >> 16) & 0xff; }
if (shift === 6) { if (position < res.length) { res[position++] = (word >> 24) & 0xff; } carry = 0; shift = 0; } else { carry = word >>> 24; shift += 2; } }
if (position < res.length) { res[position++] = carry;
while (position < res.length) { res[position++] = 0; } }};
BN.prototype._toArrayLikeBE = function _toArrayLikeBE(res, byteLength) { var position = res.length - 1; var carry = 0;
for (var i = 0, shift = 0; i < this.length; i++) { var word = (this.words[i] << shift) | carry;
res[position--] = word & 0xff; if (position >= 0) { res[position--] = (word >> 8) & 0xff; } if (position >= 0) { res[position--] = (word >> 16) & 0xff; }
if (shift === 6) { if (position >= 0) { res[position--] = (word >> 24) & 0xff; } carry = 0; shift = 0; } else { carry = word >>> 24; shift += 2; } }
if (position >= 0) { res[position--] = carry;
while (position >= 0) { res[position--] = 0; } }};
if (Math.clz32) { BN.prototype._countBits = function _countBits(w) { return 32 - Math.clz32(w); };} else { BN.prototype._countBits = function _countBits(w) { var t = w; var r = 0; if (t >= 0x1000) { r += 13; t >>>= 13; } if (t >= 0x40) { r += 7; t >>>= 7; } if (t >= 0x8) { r += 4; t >>>= 4; } if (t >= 0x02) { r += 2; t >>>= 2; } return r + t; };}
BN.prototype._zeroBits = function _zeroBits(w) { // Short-cut if (w === 0) return 26;
var t = w; var r = 0; if ((t & 0x1fff) === 0) { r += 13; t >>>= 13; } if ((t & 0x7f) === 0) { r += 7; t >>>= 7; } if ((t & 0xf) === 0) { r += 4; t >>>= 4; } if ((t & 0x3) === 0) { r += 2; t >>>= 2; } if ((t & 0x1) === 0) { r++; } return r;};
// Return number of used bits in a BNBN.prototype.bitLength = function bitLength() { var w = this.words[this.length - 1]; var hi = this._countBits(w); return (this.length - 1) * 26 + hi;};
function toBitArray(num) { var w = new Array(num.bitLength());
for (var bit = 0; bit < w.length; bit++) { var off = (bit / 26) | 0; var wbit = bit % 26;
w[bit] = (num.words[off] >>> wbit) & 0x01; }
return w;}
// Number of trailing zero bitsBN.prototype.zeroBits = function zeroBits() { if (this.isZero()) return 0;
var r = 0; for (var i = 0; i < this.length; i++) { var b = this._zeroBits(this.words[i]); r += b; if (b !== 26) break; } return r;};
BN.prototype.byteLength = function byteLength() { return Math.ceil(this.bitLength() / 8);};
BN.prototype.toTwos = function toTwos(width) { if (this.negative !== 0) { return this.abs().inotn(width).iaddn(1); } return this.clone();};
BN.prototype.fromTwos = function fromTwos(width) { if (this.testn(width - 1)) { return this.notn(width).iaddn(1).ineg(); } return this.clone();};
BN.prototype.isNeg = function isNeg() { return this.negative !== 0;};
// Return negative clone of `this`BN.prototype.neg = function neg() { return this.clone().ineg();};
BN.prototype.ineg = function ineg() { if (!this.isZero()) { this.negative ^= 1; }
return this;};
// Or `num` with `this` in-placeBN.prototype.iuor = function iuor(num) { while (this.length < num.length) { this.words[this.length++] = 0; }
for (var i = 0; i < num.length; i++) { this.words[i] = this.words[i] | num.words[i]; }
return this._strip();};
BN.prototype.ior = function ior(num) { assert((this.negative | num.negative) === 0); return this.iuor(num);};
// Or `num` with `this`BN.prototype.or = function or(num) { if (this.length > num.length) return this.clone().ior(num); return num.clone().ior(this);};
BN.prototype.uor = function uor(num) { if (this.length > num.length) return this.clone().iuor(num); return num.clone().iuor(this);};
// And `num` with `this` in-placeBN.prototype.iuand = function iuand(num) { // b = min-length(num, this) var b; if (this.length > num.length) { b = num; } else { b = this; }
for (var i = 0; i < b.length; i++) { this.words[i] = this.words[i] & num.words[i]; }
this.length = b.length;
return this._strip();};
BN.prototype.iand = function iand(num) { assert((this.negative | num.negative) === 0); return this.iuand(num);};
// And `num` with `this`BN.prototype.and = function and(num) { if (this.length > num.length) return this.clone().iand(num); return num.clone().iand(this);};
BN.prototype.uand = function uand(num) { if (this.length > num.length) return this.clone().iuand(num); return num.clone().iuand(this);};
// Xor `num` with `this` in-placeBN.prototype.iuxor = function iuxor(num) { // a.length > b.length var a; var b; if (this.length > num.length) { a = this; b = num; } else { a = num; b = this; }
for (var i = 0; i < b.length; i++) { this.words[i] = a.words[i] ^ b.words[i]; }
if (this !== a) { for (; i < a.length; i++) { this.words[i] = a.words[i]; } }
this.length = a.length;
return this._strip();};
BN.prototype.ixor = function ixor(num) { assert((this.negative | num.negative) === 0); return this.iuxor(num);};
// Xor `num` with `this`BN.prototype.xor = function xor(num) { if (this.length > num.length) return this.clone().ixor(num); return num.clone().ixor(this);};
BN.prototype.uxor = function uxor(num) { if (this.length > num.length) return this.clone().iuxor(num); return num.clone().iuxor(this);};
// Not ``this`` with ``width`` bitwidthBN.prototype.inotn = function inotn(width) { assert(typeof width === "number" && width >= 0);
var bytesNeeded = Math.ceil(width / 26) | 0; var bitsLeft = width % 26;
// Extend the buffer with leading zeroes this._expand(bytesNeeded);
if (bitsLeft > 0) { bytesNeeded--; }
// Handle complete words for (var i = 0; i < bytesNeeded; i++) { this.words[i] = ~this.words[i] & 0x3ffffff; }
// Handle the residue if (bitsLeft > 0) { this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft)); }
// And remove leading zeroes return this._strip();};
BN.prototype.notn = function notn(width) { return this.clone().inotn(width);};
// Set `bit` of `this`BN.prototype.setn = function setn(bit, val) { assert(typeof bit === "number" && bit >= 0);
var off = (bit / 26) | 0; var wbit = bit % 26;
this._expand(off + 1);
if (val) { this.words[off] = this.words[off] | (1 << wbit); } else { this.words[off] = this.words[off] & ~(1 << wbit); }
return this._strip();};
// Add `num` to `this` in-placeBN.prototype.iadd = function iadd(num) { var r;
// negative + positive if (this.negative !== 0 && num.negative === 0) { this.negative = 0; r = this.isub(num); this.negative ^= 1; return this._normSign();
// positive + negative } else if (this.negative === 0 && num.negative !== 0) { num.negative = 0; r = this.isub(num); num.negative = 1; return r._normSign(); }
// a.length > b.length var a, b; if (this.length > num.length) { a = this; b = num; } else { a = num; b = this; }
var carry = 0; for (var i = 0; i < b.length; i++) { r = (a.words[i] | 0) + (b.words[i] | 0) + carry; this.words[i] = r & 0x3ffffff; carry = r >>> 26; } for (; carry !== 0 && i < a.length; i++) { r = (a.words[i] | 0) + carry; this.words[i] = r & 0x3ffffff; carry = r >>> 26; }
this.length = a.length; if (carry !== 0) { this.words[this.length] = carry; this.length++; // Copy the rest of the words } else if (a !== this) { for (; i < a.length; i++) { this.words[i] = a.words[i]; } }
return this;};
// Add `num` to `this`BN.prototype.add = function add(num) { var res; if (num.negative !== 0 && this.negative === 0) { num.negative = 0; res = this.sub(num); num.negative ^= 1; return res; } else if (num.negative === 0 && this.negative !== 0) { this.negative = 0; res = num.sub(this); this.negative = 1; return res; }
if (this.length > num.length) return this.clone().iadd(num);
return num.clone().iadd(this);};
// Subtract `num` from `this` in-placeBN.prototype.isub = function isub(num) { // this - (-num) = this + num if (num.negative !== 0) { num.negative = 0; var r = this.iadd(num); num.negative = 1; return r._normSign();
// -this - num = -(this + num) } else if (this.negative !== 0) { this.negative = 0; this.iadd(num); this.negative = 1; return this._normSign(); }
// At this point both numbers are positive var cmp = this.cmp(num);
// Optimization - zeroify if (cmp === 0) { this.negative = 0; this.length = 1; this.words[0] = 0; return this; }
// a > b var a, b; if (cmp > 0) { a = this; b = num; } else { a = num; b = this; }
var carry = 0; for (var i = 0; i < b.length; i++) { r = (a.words[i] | 0) - (b.words[i] | 0) + carry; carry = r >> 26; this.words[i] = r & 0x3ffffff; } for (; carry !== 0 && i < a.length; i++) { r = (a.words[i] | 0) + carry; carry = r >> 26; this.words[i] = r & 0x3ffffff; }
// Copy rest of the words if (carry === 0 && i < a.length && a !== this) { for (; i < a.length; i++) { this.words[i] = a.words[i]; } }
this.length = Math.max(this.length, i);
if (a !== this) { this.negative = 1; }
return this._strip();};
// Subtract `num` from `this`BN.prototype.sub = function sub(num) { return this.clone().isub(num);};
function smallMulTo(self, num, out) { out.negative = num.negative ^ self.negative; var len = (self.length + num.length) | 0; out.length = len; len = (len - 1) | 0;
// Peel one iteration (compiler can't do it, because of code complexity) var a = self.words[0] | 0; var b = num.words[0] | 0; var r = a * b;
var lo = r & 0x3ffffff; var carry = (r / 0x4000000) | 0; out.words[0] = lo;
for (var k = 1; k < len; k++) { // Sum all words with the same `i + j = k` and accumulate `ncarry`, // note that ncarry could be >= 0x3ffffff var ncarry = carry >>> 26; var rword = carry & 0x3ffffff; var maxJ = Math.min(k, num.length - 1); for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) { var i = (k - j) | 0; a = self.words[i] | 0; b = num.words[j] | 0; r = a * b + rword; ncarry += (r / 0x4000000) | 0; rword = r & 0x3ffffff; } out.words[k] = rword | 0; carry = ncarry | 0; } if (carry !== 0) { out.words[k] = carry | 0; } else { out.length--; }
return out._strip();}
// TODO(indutny): it may be reasonable to omit it for users who don't need// to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit// multiplication (like elliptic secp256k1).var comb10MulTo = function comb10MulTo(self, num, out) { var a = self.words; var b = num.words; var o = out.words; var c = 0; var lo; var mid; var hi; var a0 = a[0] | 0; var al0 = a0 & 0x1fff; var ah0 = a0 >>> 13; var a1 = a[1] | 0; var al1 = a1 & 0x1fff; var ah1 = a1 >>> 13; var a2 = a[2] | 0; var al2 = a2 & 0x1fff; var ah2 = a2 >>> 13; var a3 = a[3] | 0; var al3 = a3 & 0x1fff; var ah3 = a3 >>> 13; var a4 = a[4] | 0; var al4 = a4 & 0x1fff; var ah4 = a4 >>> 13; var a5 = a[5] | 0; var al5 = a5 & 0x1fff; var ah5 = a5 >>> 13; var a6 = a[6] | 0; var al6 = a6 & 0x1fff; var ah6 = a6 >>> 13; var a7 = a[7] | 0; var al7 = a7 & 0x1fff; var ah7 = a7 >>> 13; var a8 = a[8] | 0; var al8 = a8 & 0x1fff; var ah8 = a8 >>> 13; var a9 = a[9] | 0; var al9 = a9 & 0x1fff; var ah9 = a9 >>> 13; var b0 = b[0] | 0; var bl0 = b0 & 0x1fff; var bh0 = b0 >>> 13; var b1 = b[1] | 0; var bl1 = b1 & 0x1fff; var bh1 = b1 >>> 13; var b2 = b[2] | 0; var bl2 = b2 & 0x1fff; var bh2 = b2 >>> 13; var b3 = b[3] | 0; var bl3 = b3 & 0x1fff; var bh3 = b3 >>> 13; var b4 = b[4] | 0; var bl4 = b4 & 0x1fff; var bh4 = b4 >>> 13; var b5 = b[5] | 0; var bl5 = b5 & 0x1fff; var bh5 = b5 >>> 13; var b6 = b[6] | 0; var bl6 = b6 & 0x1fff; var bh6 = b6 >>> 13; var b7 = b[7] | 0; var bl7 = b7 & 0x1fff; var bh7 = b7 >>> 13; var b8 = b[8] | 0; var bl8 = b8 & 0x1fff; var bh8 = b8 >>> 13; var b9 = b[9] | 0; var bl9 = b9 & 0x1fff; var bh9 = b9 >>> 13;
out.negative = self.negative ^ num.negative; out.length = 19; /* k = 0 */ lo = Math.imul(al0, bl0); mid = Math.imul(al0, bh0); mid = (mid + Math.imul(ah0, bl0)) | 0; hi = Math.imul(ah0, bh0); var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0; w0 &= 0x3ffffff; /* k = 1 */ lo = Math.imul(al1, bl0); mid = Math.imul(al1, bh0); mid = (mid + Math.imul(ah1, bl0)) | 0; hi = Math.imul(ah1, bh0); lo = (lo + Math.imul(al0, bl1)) | 0; mid = (mid + Math.imul(al0, bh1)) | 0; mid = (mid + Math.imul(ah0, bl1)) | 0; hi = (hi + Math.imul(ah0, bh1)) | 0; var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0; w1 &= 0x3ffffff; /* k = 2 */ lo = Math.imul(al2, bl0); mid = Math.imul(al2, bh0); mid = (mid + Math.imul(ah2, bl0)) | 0; hi = Math.imul(ah2, bh0); lo = (lo + Math.imul(al1, bl1)) | 0; mid = (mid + Math.imul(al1, bh1)) | 0; mid = (mid + Math.imul(ah1, bl1)) | 0; hi = (hi + Math.imul(ah1, bh1)) | 0; lo = (lo + Math.imul(al0, bl2)) | 0; mid = (mid + Math.imul(al0, bh2)) | 0; mid = (mid + Math.imul(ah0, bl2)) | 0; hi = (hi + Math.imul(ah0, bh2)) | 0; var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0; w2 &= 0x3ffffff; /* k = 3 */ lo = Math.imul(al3, bl0); mid = Math.imul(al3, bh0); mid = (mid + Math.imul(ah3, bl0)) | 0; hi = Math.imul(ah3, bh0); lo = (lo + Math.imul(al2, bl1)) | 0; mid = (mid + Math.imul(al2, bh1)) | 0; mid = (mid + Math.imul(ah2, bl1)) | 0; hi = (hi + Math.imul(ah2, bh1)) | 0; lo = (lo + Math.imul(al1, bl2)) | 0; mid = (mid + Math.imul(al1, bh2)) | 0; mid = (mid + Math.imul(ah1, bl2)) | 0; hi = (hi + Math.imul(ah1, bh2)) | 0; lo = (lo + Math.imul(al0, bl3)) | 0; mid = (mid + Math.imul(al0, bh3)) | 0; mid = (mid + Math.imul(ah0, bl3)) | 0; hi = (hi + Math.imul(ah0, bh3)) | 0; var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0; w3 &= 0x3ffffff; /* k = 4 */ lo = Math.imul(al4, bl0); mid = Math.imul(al4, bh0); mid = (mid + Math.imul(ah4, bl0)) | 0; hi = Math.imul(ah4, bh0); lo = (lo + Math.imul(al3, bl1)) | 0; mid = (mid + Math.imul(al3, bh1)) | 0; mid = (mid + Math.imul(ah3, bl1)) | 0; hi = (hi + Math.imul(ah3, bh1)) | 0; lo = (lo + Math.imul(al2, bl2)) | 0; mid = (mid + Math.imul(al2, bh2)) | 0; mid = (mid + Math.imul(ah2, bl2)) | 0; hi = (hi + Math.imul(ah2, bh2)) | 0; lo = (lo + Math.imul(al1, bl3)) | 0; mid = (mid + Math.imul(al1, bh3)) | 0; mid = (mid + Math.imul(ah1, bl3)) | 0; hi = (hi + Math.imul(ah1, bh3)) | 0; lo = (lo + Math.imul(al0, bl4)) | 0; mid = (mid + Math.imul(al0, bh4)) | 0; mid = (mid + Math.imul(ah0, bl4)) | 0; hi = (hi + Math.imul(ah0, bh4)) | 0; var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0; w4 &= 0x3ffffff; /* k = 5 */ lo = Math.imul(al5, bl0); mid = Math.imul(al5, bh0); mid = (mid + Math.imul(ah5, bl0)) | 0; hi = Math.imul(ah5, bh0); lo = (lo + Math.imul(al4, bl1)) | 0; mid = (mid + Math.imul(al4, bh1)) | 0; mid = (mid + Math.imul(ah4, bl1)) | 0; hi = (hi + Math.imul(ah4, bh1)) | 0; lo = (lo + Math.imul(al3, bl2)) | 0; mid = (mid + Math.imul(al3, bh2)) | 0; mid = (mid + Math.imul(ah3, bl2)) | 0; hi = (hi + Math.imul(ah3, bh2)) | 0; lo = (lo + Math.imul(al2, bl3)) | 0; mid = (mid + Math.imul(al2, bh3)) | 0; mid = (mid + Math.imul(ah2, bl3)) | 0; hi = (hi + Math.imul(ah2, bh3)) | 0; lo = (lo + Math.imul(al1, bl4)) | 0; mid = (mid + Math.imul(al1, bh4)) | 0; mid = (mid + Math.imul(ah1, bl4)) | 0; hi = (hi + Math.imul(ah1, bh4)) | 0; lo = (lo + Math.imul(al0, bl5)) | 0; mid = (mid + Math.imul(al0, bh5)) | 0; mid = (mid + Math.imul(ah0, bl5)) | 0; hi = (hi + Math.imul(ah0, bh5)) | 0; var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0; w5 &= 0x3ffffff; /* k = 6 */ lo = Math.imul(al6, bl0); mid = Math.imul(al6, bh0); mid = (mid + Math.imul(ah6, bl0)) | 0; hi = Math.imul(ah6, bh0); lo = (lo + Math.imul(al5, bl1)) | 0; mid = (mid + Math.imul(al5, bh1)) | 0; mid = (mid + Math.imul(ah5, bl1)) | 0; hi = (hi + Math.imul(ah5, bh1)) | 0; lo = (lo + Math.imul(al4, bl2)) | 0; mid = (mid + Math.imul(al4, bh2)) | 0; mid = (mid + Math.imul(ah4, bl2)) | 0; hi = (hi + Math.imul(ah4, bh2)) | 0; lo = (lo + Math.imul(al3, bl3)) | 0; mid = (mid + Math.imul(al3, bh3)) | 0; mid = (mid + Math.imul(ah3, bl3)) | 0; hi = (hi + Math.imul(ah3, bh3)) | 0; lo = (lo + Math.imul(al2, bl4)) | 0; mid = (mid + Math.imul(al2, bh4)) | 0; mid = (mid + Math.imul(ah2, bl4)) | 0; hi = (hi + Math.imul(ah2, bh4)) | 0; lo = (lo + Math.imul(al1, bl5)) | 0; mid = (mid + Math.imul(al1, bh5)) | 0; mid = (mid + Math.imul(ah1, bl5)) | 0; hi = (hi + Math.imul(ah1, bh5)) | 0; lo = (lo + Math.imul(al0, bl6)) | 0; mid = (mid + Math.imul(al0, bh6)) | 0; mid = (mid + Math.imul(ah0, bl6)) | 0; hi = (hi + Math.imul(ah0, bh6)) | 0; var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0; w6 &= 0x3ffffff; /* k = 7 */ lo = Math.imul(al7, bl0); mid = Math.imul(al7, bh0); mid = (mid + Math.imul(ah7, bl0)) | 0; hi = Math.imul(ah7, bh0); lo = (lo + Math.imul(al6, bl1)) | 0; mid = (mid + Math.imul(al6, bh1)) | 0; mid = (mid + Math.imul(ah6, bl1)) | 0; hi = (hi + Math.imul(ah6, bh1)) | 0; lo = (lo + Math.imul(al5, bl2)) | 0; mid = (mid + Math.imul(al5, bh2)) | 0; mid = (mid + Math.imul(ah5, bl2)) | 0; hi = (hi + Math.imul(ah5, bh2)) | 0; lo = (lo + Math.imul(al4, bl3)) | 0; mid = (mid + Math.imul(al4, bh3)) | 0; mid = (mid + Math.imul(ah4, bl3)) | 0; hi = (hi + Math.imul(ah4, bh3)) | 0; lo = (lo + Math.imul(al3, bl4)) | 0; mid = (mid + Math.imul(al3, bh4)) | 0; mid = (mid + Math.imul(ah3, bl4)) | 0; hi = (hi + Math.imul(ah3, bh4)) | 0; lo = (lo + Math.imul(al2, bl5)) | 0; mid = (mid + Math.imul(al2, bh5)) | 0; mid = (mid + Math.imul(ah2, bl5)) | 0; hi = (hi + Math.imul(ah2, bh5)) | 0; lo = (lo + Math.imul(al1, bl6)) | 0; mid = (mid + Math.imul(al1, bh6)) | 0; mid = (mid + Math.imul(ah1, bl6)) | 0; hi = (hi + Math.imul(ah1, bh6)) | 0; lo = (lo + Math.imul(al0, bl7)) | 0; mid = (mid + Math.imul(al0, bh7)) | 0; mid = (mid + Math.imul(ah0, bl7)) | 0; hi = (hi + Math.imul(ah0, bh7)) | 0; var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0; w7 &= 0x3ffffff; /* k = 8 */ lo = Math.imul(al8, bl0); mid = Math.imul(al8, bh0); mid = (mid + Math.imul(ah8, bl0)) | 0; hi = Math.imul(ah8, bh0); lo = (lo + Math.imul(al7, bl1)) | 0; mid = (mid + Math.imul(al7, bh1)) | 0; mid = (mid + Math.imul(ah7, bl1)) | 0; hi = (hi + Math.imul(ah7, bh1)) | 0; lo = (lo + Math.imul(al6, bl2)) | 0; mid = (mid + Math.imul(al6, bh2)) | 0; mid = (mid + Math.imul(ah6, bl2)) | 0; hi = (hi + Math.imul(ah6, bh2)) | 0; lo = (lo + Math.imul(al5, bl3)) | 0; mid = (mid + Math.imul(al5, bh3)) | 0; mid = (mid + Math.imul(ah5, bl3)) | 0; hi = (hi + Math.imul(ah5, bh3)) | 0; lo = (lo + Math.imul(al4, bl4)) | 0; mid = (mid + Math.imul(al4, bh4)) | 0; mid = (mid + Math.imul(ah4, bl4)) | 0; hi = (hi + Math.imul(ah4, bh4)) | 0; lo = (lo + Math.imul(al3, bl5)) | 0; mid = (mid + Math.imul(al3, bh5)) | 0; mid = (mid + Math.imul(ah3, bl5)) | 0; hi = (hi + Math.imul(ah3, bh5)) | 0; lo = (lo + Math.imul(al2, bl6)) | 0; mid = (mid + Math.imul(al2, bh6)) | 0; mid = (mid + Math.imul(ah2, bl6)) | 0; hi = (hi + Math.imul(ah2, bh6)) | 0; lo = (lo + Math.imul(al1, bl7)) | 0; mid = (mid + Math.imul(al1, bh7)) | 0; mid = (mid + Math.imul(ah1, bl7)) | 0; hi = (hi + Math.imul(ah1, bh7)) | 0; lo = (lo + Math.imul(al0, bl8)) | 0; mid = (mid + Math.imul(al0, bh8)) | 0; mid = (mid + Math.imul(ah0, bl8)) | 0; hi = (hi + Math.imul(ah0, bh8)) | 0; var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0; w8 &= 0x3ffffff; /* k = 9 */ lo = Math.imul(al9, bl0); mid = Math.imul(al9, bh0); mid = (mid + Math.imul(ah9, bl0)) | 0; hi = Math.imul(ah9, bh0); lo = (lo + Math.imul(al8, bl1)) | 0; mid = (mid + Math.imul(al8, bh1)) | 0; mid = (mid + Math.imul(ah8, bl1)) | 0; hi = (hi + Math.imul(ah8, bh1)) | 0; lo = (lo + Math.imul(al7, bl2)) | 0; mid = (mid + Math.imul(al7, bh2)) | 0; mid = (mid + Math.imul(ah7, bl2)) | 0; hi = (hi + Math.imul(ah7, bh2)) | 0; lo = (lo + Math.imul(al6, bl3)) | 0; mid = (mid + Math.imul(al6, bh3)) | 0; mid = (mid + Math.imul(ah6, bl3)) | 0; hi = (hi + Math.imul(ah6, bh3)) | 0; lo = (lo + Math.imul(al5, bl4)) | 0; mid = (mid + Math.imul(al5, bh4)) | 0; mid = (mid + Math.imul(ah5, bl4)) | 0; hi = (hi + Math.imul(ah5, bh4)) | 0; lo = (lo + Math.imul(al4, bl5)) | 0; mid = (mid + Math.imul(al4, bh5)) | 0; mid = (mid + Math.imul(ah4, bl5)) | 0; hi = (hi + Math.imul(ah4, bh5)) | 0; lo = (lo + Math.imul(al3, bl6)) | 0; mid = (mid + Math.imul(al3, bh6)) | 0; mid = (mid + Math.imul(ah3, bl6)) | 0; hi = (hi + Math.imul(ah3, bh6)) | 0; lo = (lo + Math.imul(al2, bl7)) | 0; mid = (mid + Math.imul(al2, bh7)) | 0; mid = (mid + Math.imul(ah2, bl7)) | 0; hi = (hi + Math.imul(ah2, bh7)) | 0; lo = (lo + Math.imul(al1, bl8)) | 0; mid = (mid + Math.imul(al1, bh8)) | 0; mid = (mid + Math.imul(ah1, bl8)) | 0; hi = (hi + Math.imul(ah1, bh8)) | 0; lo = (lo + Math.imul(al0, bl9)) | 0; mid = (mid + Math.imul(al0, bh9)) | 0; mid = (mid + Math.imul(ah0, bl9)) | 0; hi = (hi + Math.imul(ah0, bh9)) | 0; var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0; w9 &= 0x3ffffff; /* k = 10 */ lo = Math.imul(al9, bl1); mid = Math.imul(al9, bh1); mid = (mid + Math.imul(ah9, bl1)) | 0; hi = Math.imul(ah9, bh1); lo = (lo + Math.imul(al8, bl2)) | 0; mid = (mid + Math.imul(al8, bh2)) | 0; mid = (mid + Math.imul(ah8, bl2)) | 0; hi = (hi + Math.imul(ah8, bh2)) | 0; lo = (lo + Math.imul(al7, bl3)) | 0; mid = (mid + Math.imul(al7, bh3)) | 0; mid = (mid + Math.imul(ah7, bl3)) | 0; hi = (hi + Math.imul(ah7, bh3)) | 0; lo = (lo + Math.imul(al6, bl4)) | 0; mid = (mid + Math.imul(al6, bh4)) | 0; mid = (mid + Math.imul(ah6, bl4)) | 0; hi = (hi + Math.imul(ah6, bh4)) | 0; lo = (lo + Math.imul(al5, bl5)) | 0; mid = (mid + Math.imul(al5, bh5)) | 0; mid = (mid + Math.imul(ah5, bl5)) | 0; hi = (hi + Math.imul(ah5, bh5)) | 0; lo = (lo + Math.imul(al4, bl6)) | 0; mid = (mid + Math.imul(al4, bh6)) | 0; mid = (mid + Math.imul(ah4, bl6)) | 0; hi = (hi + Math.imul(ah4, bh6)) | 0; lo = (lo + Math.imul(al3, bl7)) | 0; mid = (mid + Math.imul(al3, bh7)) | 0; mid = (mid + Math.imul(ah3, bl7)) | 0; hi = (hi + Math.imul(ah3, bh7)) | 0; lo = (lo + Math.imul(al2, bl8)) | 0; mid = (mid + Math.imul(al2, bh8)) | 0; mid = (mid + Math.imul(ah2, bl8)) | 0; hi = (hi + Math.imul(ah2, bh8)) | 0; lo = (lo + Math.imul(al1, bl9)) | 0; mid = (mid + Math.imul(al1, bh9)) | 0; mid = (mid + Math.imul(ah1, bl9)) | 0; hi = (hi + Math.imul(ah1, bh9)) | 0; var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0; w10 &= 0x3ffffff; /* k = 11 */ lo = Math.imul(al9, bl2); mid = Math.imul(al9, bh2); mid = (mid + Math.imul(ah9, bl2)) | 0; hi = Math.imul(ah9, bh2); lo = (lo + Math.imul(al8, bl3)) | 0; mid = (mid + Math.imul(al8, bh3)) | 0; mid = (mid + Math.imul(ah8, bl3)) | 0; hi = (hi + Math.imul(ah8, bh3)) | 0; lo = (lo + Math.imul(al7, bl4)) | 0; mid = (mid + Math.imul(al7, bh4)) | 0; mid = (mid + Math.imul(ah7, bl4)) | 0; hi = (hi + Math.imul(ah7, bh4)) | 0; lo = (lo + Math.imul(al6, bl5)) | 0; mid = (mid + Math.imul(al6, bh5)) | 0; mid = (mid + Math.imul(ah6, bl5)) | 0; hi = (hi + Math.imul(ah6, bh5)) | 0; lo = (lo + Math.imul(al5, bl6)) | 0; mid = (mid + Math.imul(al5, bh6)) | 0; mid = (mid + Math.imul(ah5, bl6)) | 0; hi = (hi + Math.imul(ah5, bh6)) | 0; lo = (lo + Math.imul(al4, bl7)) | 0; mid = (mid + Math.imul(al4, bh7)) | 0; mid = (mid + Math.imul(ah4, bl7)) | 0; hi = (hi + Math.imul(ah4, bh7)) | 0; lo = (lo + Math.imul(al3, bl8)) | 0; mid = (mid + Math.imul(al3, bh8)) | 0; mid = (mid + Math.imul(ah3, bl8)) | 0; hi = (hi + Math.imul(ah3, bh8)) | 0; lo = (lo + Math.imul(al2, bl9)) | 0; mid = (mid + Math.imul(al2, bh9)) | 0; mid = (mid + Math.imul(ah2, bl9)) | 0; hi = (hi + Math.imul(ah2, bh9)) | 0; var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0; w11 &= 0x3ffffff; /* k = 12 */ lo = Math.imul(al9, bl3); mid = Math.imul(al9, bh3); mid = (mid + Math.imul(ah9, bl3)) | 0; hi = Math.imul(ah9, bh3); lo = (lo + Math.imul(al8, bl4)) | 0; mid = (mid + Math.imul(al8, bh4)) | 0; mid = (mid + Math.imul(ah8, bl4)) | 0; hi = (hi + Math.imul(ah8, bh4)) | 0; lo = (lo + Math.imul(al7, bl5)) | 0; mid = (mid + Math.imul(al7, bh5)) | 0; mid = (mid + Math.imul(ah7, bl5)) | 0; hi = (hi + Math.imul(ah7, bh5)) | 0; lo = (lo + Math.imul(al6, bl6)) | 0; mid = (mid + Math.imul(al6, bh6)) | 0; mid = (mid + Math.imul(ah6, bl6)) | 0; hi = (hi + Math.imul(ah6, bh6)) | 0; lo = (lo + Math.imul(al5, bl7)) | 0; mid = (mid + Math.imul(al5, bh7)) | 0; mid = (mid + Math.imul(ah5, bl7)) | 0; hi = (hi + Math.imul(ah5, bh7)) | 0; lo = (lo + Math.imul(al4, bl8)) | 0; mid = (mid + Math.imul(al4, bh8)) | 0; mid = (mid + Math.imul(ah4, bl8)) | 0; hi = (hi + Math.imul(ah4, bh8)) | 0; lo = (lo + Math.imul(al3, bl9)) | 0; mid = (mid + Math.imul(al3, bh9)) | 0; mid = (mid + Math.imul(ah3, bl9)) | 0; hi = (hi + Math.imul(ah3, bh9)) | 0; var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0; w12 &= 0x3ffffff; /* k = 13 */ lo = Math.imul(al9, bl4); mid = Math.imul(al9, bh4); mid = (mid + Math.imul(ah9, bl4)) | 0; hi = Math.imul(ah9, bh4); lo = (lo + Math.imul(al8, bl5)) | 0; mid = (mid + Math.imul(al8, bh5)) | 0; mid = (mid + Math.imul(ah8, bl5)) | 0; hi = (hi + Math.imul(ah8, bh5)) | 0; lo = (lo + Math.imul(al7, bl6)) | 0; mid = (mid + Math.imul(al7, bh6)) | 0; mid = (mid + Math.imul(ah7, bl6)) | 0; hi = (hi + Math.imul(ah7, bh6)) | 0; lo = (lo + Math.imul(al6, bl7)) | 0; mid = (mid + Math.imul(al6, bh7)) | 0; mid = (mid + Math.imul(ah6, bl7)) | 0; hi = (hi + Math.imul(ah6, bh7)) | 0; lo = (lo + Math.imul(al5, bl8)) | 0; mid = (mid + Math.imul(al5, bh8)) | 0; mid = (mid + Math.imul(ah5, bl8)) | 0; hi = (hi + Math.imul(ah5, bh8)) | 0; lo = (lo + Math.imul(al4, bl9)) | 0; mid = (mid + Math.imul(al4, bh9)) | 0; mid = (mid + Math.imul(ah4, bl9)) | 0; hi = (hi + Math.imul(ah4, bh9)) | 0; var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0; w13 &= 0x3ffffff; /* k = 14 */ lo = Math.imul(al9, bl5); mid = Math.imul(al9, bh5); mid = (mid + Math.imul(ah9, bl5)) | 0; hi = Math.imul(ah9, bh5); lo = (lo + Math.imul(al8, bl6)) | 0; mid = (mid + Math.imul(al8, bh6)) | 0; mid = (mid + Math.imul(ah8, bl6)) | 0; hi = (hi + Math.imul(ah8, bh6)) | 0; lo = (lo + Math.imul(al7, bl7)) | 0; mid = (mid + Math.imul(al7, bh7)) | 0; mid = (mid + Math.imul(ah7, bl7)) | 0; hi = (hi + Math.imul(ah7, bh7)) | 0; lo = (lo + Math.imul(al6, bl8)) | 0; mid = (mid + Math.imul(al6, bh8)) | 0; mid = (mid + Math.imul(ah6, bl8)) | 0; hi = (hi + Math.imul(ah6, bh8)) | 0; lo = (lo + Math.imul(al5, bl9)) | 0; mid = (mid + Math.imul(al5, bh9)) | 0; mid = (mid + Math.imul(ah5, bl9)) | 0; hi = (hi + Math.imul(ah5, bh9)) | 0; var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0; w14 &= 0x3ffffff; /* k = 15 */ lo = Math.imul(al9, bl6); mid = Math.imul(al9, bh6); mid = (mid + Math.imul(ah9, bl6)) | 0; hi = Math.imul(ah9, bh6); lo = (lo + Math.imul(al8, bl7)) | 0; mid = (mid + Math.imul(al8, bh7)) | 0; mid = (mid + Math.imul(ah8, bl7)) | 0; hi = (hi + Math.imul(ah8, bh7)) | 0; lo = (lo + Math.imul(al7, bl8)) | 0; mid = (mid + Math.imul(al7, bh8)) | 0; mid = (mid + Math.imul(ah7, bl8)) | 0; hi = (hi + Math.imul(ah7, bh8)) | 0; lo = (lo + Math.imul(al6, bl9)) | 0; mid = (mid + Math.imul(al6, bh9)) | 0; mid = (mid + Math.imul(ah6, bl9)) | 0; hi = (hi + Math.imul(ah6, bh9)) | 0; var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0; w15 &= 0x3ffffff; /* k = 16 */ lo = Math.imul(al9, bl7); mid = Math.imul(al9, bh7); mid = (mid + Math.imul(ah9, bl7)) | 0; hi = Math.imul(ah9, bh7); lo = (lo + Math.imul(al8, bl8)) | 0; mid = (mid + Math.imul(al8, bh8)) | 0; mid = (mid + Math.imul(ah8, bl8)) | 0; hi = (hi + Math.imul(ah8, bh8)) | 0; lo = (lo + Math.imul(al7, bl9)) | 0; mid = (mid + Math.imul(al7, bh9)) | 0; mid = (mid + Math.imul(ah7, bl9)) | 0; hi = (hi + Math.imul(ah7, bh9)) | 0; var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0; w16 &= 0x3ffffff; /* k = 17 */ lo = Math.imul(al9, bl8); mid = Math.imul(al9, bh8); mid = (mid + Math.imul(ah9, bl8)) | 0; hi = Math.imul(ah9, bh8); lo = (lo + Math.imul(al8, bl9)) | 0; mid = (mid + Math.imul(al8, bh9)) | 0; mid = (mid + Math.imul(ah8, bl9)) | 0; hi = (hi + Math.imul(ah8, bh9)) | 0; var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0; w17 &= 0x3ffffff; /* k = 18 */ lo = Math.imul(al9, bl9); mid = Math.imul(al9, bh9); mid = (mid + Math.imul(ah9, bl9)) | 0; hi = Math.imul(ah9, bh9); var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0; w18 &= 0x3ffffff; o[0] = w0; o[1] = w1; o[2] = w2; o[3] = w3; o[4] = w4; o[5] = w5; o[6] = w6; o[7] = w7; o[8] = w8; o[9] = w9; o[10] = w10; o[11] = w11; o[12] = w12; o[13] = w13; o[14] = w14; o[15] = w15; o[16] = w16; o[17] = w17; o[18] = w18; if (c !== 0) { o[19] = c; out.length++; } return out;};
// Polyfill combif (!Math.imul) { comb10MulTo = smallMulTo;}
function bigMulTo(self, num, out) { out.negative = num.negative ^ self.negative; out.length = self.length + num.length;
var carry = 0; var hncarry = 0; for (var k = 0; k < out.length - 1; k++) { // Sum all words with the same `i + j = k` and accumulate `ncarry`, // note that ncarry could be >= 0x3ffffff var ncarry = hncarry; hncarry = 0; var rword = carry & 0x3ffffff; var maxJ = Math.min(k, num.length - 1); for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) { var i = k - j; var a = self.words[i] | 0; var b = num.words[j] | 0; var r = a * b;
var lo = r & 0x3ffffff; ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; lo = (lo + rword) | 0; rword = lo & 0x3ffffff; ncarry = (ncarry + (lo >>> 26)) | 0;
hncarry += ncarry >>> 26; ncarry &= 0x3ffffff; } out.words[k] = rword; carry = ncarry; ncarry = hncarry; } if (carry !== 0) { out.words[k] = carry; } else { out.length--; }
return out._strip();}
function jumboMulTo(self, num, out) { // Temporary disable, see https://github.com/indutny/bn.js/issues/211 // var fftm = new FFTM(); // return fftm.mulp(self, num, out); return bigMulTo(self, num, out);}
BN.prototype.mulTo = function mulTo(num, out) { var res; var len = this.length + num.length; if (this.length === 10 && num.length === 10) { res = comb10MulTo(this, num, out); } else if (len < 63) { res = smallMulTo(this, num, out); } else if (len < 1024) { res = bigMulTo(this, num, out); } else { res = jumboMulTo(this, num, out); }
return res;};
// Cooley-Tukey algorithm for FFT// slightly revisited to rely on looping instead of recursion
function FFTM(x, y) { this.x = x; this.y = y;}
FFTM.prototype.makeRBT = function makeRBT(N) { var t = new Array(N); var l = BN.prototype._countBits(N) - 1; for (var i = 0; i < N; i++) { t[i] = this.revBin(i, l, N); }
return t;};
// Returns binary-reversed representation of `x`FFTM.prototype.revBin = function revBin(x, l, N) { if (x === 0 || x === N - 1) return x;
var rb = 0; for (var i = 0; i < l; i++) { rb |= (x & 1) << (l - i - 1); x >>= 1; }
return rb;};
// Performs "tweedling" phase, therefore 'emulating'// behaviour of the recursive algorithmFFTM.prototype.permute = function permute(rbt, rws, iws, rtws, itws, N) { for (var i = 0; i < N; i++) { rtws[i] = rws[rbt[i]]; itws[i] = iws[rbt[i]]; }};
FFTM.prototype.transform = function transform(rws, iws, rtws, itws, N, rbt) { this.permute(rbt, rws, iws, rtws, itws, N);
for (var s = 1; s < N; s <<= 1) { var l = s << 1;
var rtwdf = Math.cos(2 * Math.PI / l); var itwdf = Math.sin(2 * Math.PI / l);
for (var p = 0; p < N; p += l) { var rtwdf_ = rtwdf; var itwdf_ = itwdf;
for (var j = 0; j < s; j++) { var re = rtws[p + j]; var ie = itws[p + j];
var ro = rtws[p + j + s]; var io = itws[p + j + s];
var rx = rtwdf_ * ro - itwdf_ * io;
io = rtwdf_ * io + itwdf_ * ro; ro = rx;
rtws[p + j] = re + ro; itws[p + j] = ie + io;
rtws[p + j + s] = re - ro; itws[p + j + s] = ie - io;
/* jshint maxdepth : false */ if (j !== l) { rx = rtwdf * rtwdf_ - itwdf * itwdf_;
itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_; rtwdf_ = rx; } } } }};
FFTM.prototype.guessLen13b = function guessLen13b(n, m) { var N = Math.max(m, n) | 1; var odd = N & 1; var i = 0; for (N = N / 2 | 0; N; N = N >>> 1) { i++; }
return 1 << i + 1 + odd;};
FFTM.prototype.conjugate = function conjugate(rws, iws, N) { if (N <= 1) return;
for (var i = 0; i < N / 2; i++) { var t = rws[i];
rws[i] = rws[N - i - 1]; rws[N - i - 1] = t;
t = iws[i];
iws[i] = -iws[N - i - 1]; iws[N - i - 1] = -t; }};
FFTM.prototype.normalize13b = function normalize13b(ws, N) { var carry = 0; for (var i = 0; i < N / 2; i++) { var w = Math.round(ws[2 * i + 1] / N) * 0x2000 + Math.round(ws[2 * i] / N) + carry;
ws[i] = w & 0x3ffffff;
if (w < 0x4000000) { carry = 0; } else { carry = w / 0x4000000 | 0; } }
return ws;};
FFTM.prototype.convert13b = function convert13b(ws, len, rws, N) { var carry = 0; for (var i = 0; i < len; i++) { carry = carry + (ws[i] | 0);
rws[2 * i] = carry & 0x1fff; carry = carry >>> 13; rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13; }
// Pad with zeroes for (i = 2 * len; i < N; ++i) { rws[i] = 0; }
assert(carry === 0); assert((carry & ~0x1fff) === 0);};
FFTM.prototype.stub = function stub(N) { var ph = new Array(N); for (var i = 0; i < N; i++) { ph[i] = 0; }
return ph;};
FFTM.prototype.mulp = function mulp(x, y, out) { var N = 2 * this.guessLen13b(x.length, y.length);
var rbt = this.makeRBT(N);
var _ = this.stub(N);
var rws = new Array(N); var rwst = new Array(N); var iwst = new Array(N);
var nrws = new Array(N); var nrwst = new Array(N); var niwst = new Array(N);
var rmws = out.words; rmws.length = N;
this.convert13b(x.words, x.length, rws, N); this.convert13b(y.words, y.length, nrws, N);
this.transform(rws, _, rwst, iwst, N, rbt); this.transform(nrws, _, nrwst, niwst, N, rbt);
for (var i = 0; i < N; i++) { var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i]; iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i]; rwst[i] = rx; }
this.conjugate(rwst, iwst, N); this.transform(rwst, iwst, rmws, _, N, rbt); this.conjugate(rmws, _, N); this.normalize13b(rmws, N);
out.negative = x.negative ^ y.negative; out.length = x.length + y.length; return out._strip();};
// Multiply `this` by `num`BN.prototype.mul = function mul(num) { var out = new BN(null); out.words = new Array(this.length + num.length); return this.mulTo(num, out);};
// Multiply employing FFTBN.prototype.mulf = function mulf(num) { var out = new BN(null); out.words = new Array(this.length + num.length); return jumboMulTo(this, num, out);};
// In-place MultiplicationBN.prototype.imul = function imul(num) { return this.clone().mulTo(num, this);};
BN.prototype.imuln = function imuln(num) { var isNegNum = num < 0; if (isNegNum) num = -num;
assert(typeof num === "number"); assert(num < 0x4000000);
// Carry var carry = 0; for (var i = 0; i < this.length; i++) { var w = (this.words[i] | 0) * num; var lo = (w & 0x3ffffff) + (carry & 0x3ffffff); carry >>= 26; carry += (w / 0x4000000) | 0; // NOTE: lo is 27bit maximum carry += lo >>> 26; this.words[i] = lo & 0x3ffffff; }
if (carry !== 0) { this.words[i] = carry; this.length++; }
return isNegNum ? this.ineg() : this;};
BN.prototype.muln = function muln(num) { return this.clone().imuln(num);};
// `this` * `this`BN.prototype.sqr = function sqr() { return this.mul(this);};
// `this` * `this` in-placeBN.prototype.isqr = function isqr() { return this.imul(this.clone());};
// Math.pow(`this`, `num`)BN.prototype.pow = function pow(num) { var w = toBitArray(num); if (w.length === 0) return new BN(1);
// Skip leading zeroes var res = this; for (var i = 0; i < w.length; i++, res = res.sqr()) { if (w[i] !== 0) break; }
if (++i < w.length) { for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) { if (w[i] === 0) continue;
res = res.mul(q); } }
return res;};
// Shift-left in-placeBN.prototype.iushln = function iushln(bits) { assert(typeof bits === "number" && bits >= 0); var r = bits % 26; var s = (bits - r) / 26; var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r); var i;
if (r !== 0) { var carry = 0;
for (i = 0; i < this.length; i++) { var newCarry = this.words[i] & carryMask; var c = ((this.words[i] | 0) - newCarry) << r; this.words[i] = c | carry; carry = newCarry >>> (26 - r); }
if (carry) { this.words[i] = carry; this.length++; } }
if (s !== 0) { for (i = this.length - 1; i >= 0; i--) { this.words[i + s] = this.words[i]; }
for (i = 0; i < s; i++) { this.words[i] = 0; }
this.length += s; }
return this._strip();};
BN.prototype.ishln = function ishln(bits) { // TODO(indutny): implement me assert(this.negative === 0); return this.iushln(bits);};
// Shift-right in-place// NOTE: `hint` is a lowest bit before trailing zeroes// NOTE: if `extended` is present - it will be filled with destroyed bitsBN.prototype.iushrn = function iushrn(bits, hint, extended) { assert(typeof bits === "number" && bits >= 0); var h; if (hint) { h = (hint - (hint % 26)) / 26; } else { h = 0; }
var r = bits % 26; var s = Math.min((bits - r) / 26, this.length); var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); var maskedWords = extended;
h -= s; h = Math.max(0, h);
// Extended mode, copy masked part if (maskedWords) { for (var i = 0; i < s; i++) { maskedWords.words[i] = this.words[i]; } maskedWords.length = s; }
if (s === 0) { // No-op, we should not move anything at all } else if (this.length > s) { this.length -= s; for (i = 0; i < this.length; i++) { this.words[i] = this.words[i + s]; } } else { this.words[0] = 0; this.length = 1; }
var carry = 0; for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) { var word = this.words[i] | 0; this.words[i] = (carry << (26 - r)) | (word >>> r); carry = word & mask; }
// Push carried bits as a mask if (maskedWords && carry !== 0) { maskedWords.words[maskedWords.length++] = carry; }
if (this.length === 0) { this.words[0] = 0; this.length = 1; }
return this._strip();};
BN.prototype.ishrn = function ishrn(bits, hint, extended) { // TODO(indutny): implement me assert(this.negative === 0); return this.iushrn(bits, hint, extended);};
// Shift-leftBN.prototype.shln = function shln(bits) { return this.clone().ishln(bits);};
BN.prototype.ushln = function ushln(bits) { return this.clone().iushln(bits);};
// Shift-rightBN.prototype.shrn = function shrn(bits) { return this.clone().ishrn(bits);};
BN.prototype.ushrn = function ushrn(bits) { return this.clone().iushrn(bits);};
// Test if n bit is setBN.prototype.testn = function testn(bit) { assert(typeof bit === "number" && bit >= 0); var r = bit % 26; var s = (bit - r) / 26; var q = 1 << r;
// Fast case: bit is much higher than all existing words if (this.length <= s) return false;
// Check bit and return var w = this.words[s];
return !!(w & q);};
// Return only lowers bits of number (in-place)BN.prototype.imaskn = function imaskn(bits) { assert(typeof bits === "number" && bits >= 0); var r = bits % 26; var s = (bits - r) / 26;
assert(this.negative === 0, "imaskn works only with positive numbers");
if (this.length <= s) { return this; }
if (r !== 0) { s++; } this.length = Math.min(s, this.length);
if (r !== 0) { var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); this.words[this.length - 1] &= mask; }
return this._strip();};
// Return only lowers bits of numberBN.prototype.maskn = function maskn(bits) { return this.clone().imaskn(bits);};
// Add plain number `num` to `this`BN.prototype.iaddn = function iaddn(num) { assert(typeof num === "number"); assert(num < 0x4000000); if (num < 0) return this.isubn(-num);
// Possible sign change if (this.negative !== 0) { if (this.length === 1 && (this.words[0] | 0) <= num) { this.words[0] = num - (this.words[0] | 0); this.negative = 0; return this; }
this.negative = 0; this.isubn(num); this.negative = 1; return this; }
// Add without checks return this._iaddn(num);};
BN.prototype._iaddn = function _iaddn(num) { this.words[0] += num;
// Carry for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) { this.words[i] -= 0x4000000; if (i === this.length - 1) { this.words[i + 1] = 1; } else { this.words[i + 1]++; } } this.length = Math.max(this.length, i + 1);
return this;};
// Subtract plain number `num` from `this`BN.prototype.isubn = function isubn(num) { assert(typeof num === "number"); assert(num < 0x4000000); if (num < 0) return this.iaddn(-num);
if (this.negative !== 0) { this.negative = 0; this.iaddn(num); this.negative = 1; return this; }
this.words[0] -= num;
if (this.length === 1 && this.words[0] < 0) { this.words[0] = -this.words[0]; this.negative = 1; } else { // Carry for (var i = 0; i < this.length && this.words[i] < 0; i++) { this.words[i] += 0x4000000; this.words[i + 1] -= 1; } }
return this._strip();};
BN.prototype.addn = function addn(num) { return this.clone().iaddn(num);};
BN.prototype.subn = function subn(num) { return this.clone().isubn(num);};
BN.prototype.iabs = function iabs() { this.negative = 0;
return this;};
BN.prototype.abs = function abs() { return this.clone().iabs();};
BN.prototype._ishlnsubmul = function _ishlnsubmul(num, mul, shift) { var len = num.length + shift; var i;
this._expand(len);
var w; var carry = 0; for (i = 0; i < num.length; i++) { w = (this.words[i + shift] | 0) + carry; var right = (num.words[i] | 0) * mul; w -= right & 0x3ffffff; carry = (w >> 26) - ((right / 0x4000000) | 0); this.words[i + shift] = w & 0x3ffffff; } for (; i < this.length - shift; i++) { w = (this.words[i + shift] | 0) + carry; carry = w >> 26; this.words[i + shift] = w & 0x3ffffff; }
if (carry === 0) return this._strip();
// Subtraction overflow assert(carry === -1); carry = 0; for (i = 0; i < this.length; i++) { w = -(this.words[i] | 0) + carry; carry = w >> 26; this.words[i] = w & 0x3ffffff; } this.negative = 1;
return this._strip();};
BN.prototype._wordDiv = function _wordDiv(num, mode) { var shift = this.length - num.length;
var a = this.clone(); var b = num;
// Normalize var bhi = b.words[b.length - 1] | 0; var bhiBits = this._countBits(bhi); shift = 26 - bhiBits; if (shift !== 0) { b = b.ushln(shift); a.iushln(shift); bhi = b.words[b.length - 1] | 0; }
// Initialize quotient var m = a.length - b.length; var q;
if (mode !== "mod") { q = new BN(null); q.length = m + 1; q.words = new Array(q.length); for (var i = 0; i < q.length; i++) { q.words[i] = 0; } }
var diff = a.clone()._ishlnsubmul(b, 1, m); if (diff.negative === 0) { a = diff; if (q) { q.words[m] = 1; } }
for (var j = m - 1; j >= 0; j--) { var qj = (a.words[b.length + j] | 0) * 0x4000000 + (a.words[b.length + j - 1] | 0);
// NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max // (0x7ffffff) qj = Math.min((qj / bhi) | 0, 0x3ffffff);
a._ishlnsubmul(b, qj, j); while (a.negative !== 0) { qj--; a.negative = 0; a._ishlnsubmul(b, 1, j); if (!a.isZero()) { a.negative ^= 1; } } if (q) { q.words[j] = qj; } } if (q) { q._strip(); } a._strip();
// Denormalize if (mode !== "div" && shift !== 0) { a.iushrn(shift); }
return { div: q || null, mod: a, };};
// NOTE: 1) `mode` can be set to `mod` to request mod only,// to `div` to request div only, or be absent to// request both div & mod// 2) `positive` is true if unsigned mod is requestedBN.prototype.divmod = function divmod(num, mode, positive) { assert(!num.isZero());
if (this.isZero()) { return { div: new BN(0), mod: new BN(0), }; }
var div, mod, res; if (this.negative !== 0 && num.negative === 0) { res = this.neg().divmod(num, mode);
if (mode !== "mod") { div = res.div.neg(); }
if (mode !== "div") { mod = res.mod.neg(); if (positive && mod.negative !== 0) { mod.iadd(num); } }
return { div: div, mod: mod, }; }
if (this.negative === 0 && num.negative !== 0) { res = this.divmod(num.neg(), mode);
if (mode !== "mod") { div = res.div.neg(); }
return { div: div, mod: res.mod, }; }
if ((this.negative & num.negative) !== 0) { res = this.neg().divmod(num.neg(), mode);
if (mode !== "div") { mod = res.mod.neg(); if (positive && mod.negative !== 0) { mod.isub(num); } }
return { div: res.div, mod: mod, }; }
// Both numbers are positive at this point
// Strip both numbers to approximate shift value if (num.length > this.length || this.cmp(num) < 0) { return { div: new BN(0), mod: this, }; }
// Very short reduction if (num.length === 1) { if (mode === "div") { return { div: this.divn(num.words[0]), mod: null, }; }
if (mode === "mod") { return { div: null, mod: new BN(this.modrn(num.words[0])), }; }
return { div: this.divn(num.words[0]), mod: new BN(this.modrn(num.words[0])), }; }
return this._wordDiv(num, mode);};
// Find `this` / `num`BN.prototype.div = function div(num) { return this.divmod(num, "div", false).div;};
// Find `this` % `num`BN.prototype.mod = function mod(num) { return this.divmod(num, "mod", false).mod;};
BN.prototype.umod = function umod(num) { return this.divmod(num, "mod", true).mod;};
// Find Round(`this` / `num`)BN.prototype.divRound = function divRound(num) { var dm = this.divmod(num);
// Fast case - exact division if (dm.mod.isZero()) return dm.div;
var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;
var half = num.ushrn(1); var r2 = num.andln(1); var cmp = mod.cmp(half);
// Round down if (cmp < 0 || (r2 === 1 && cmp === 0)) return dm.div;
// Round up return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);};
BN.prototype.modrn = function modrn(num) { var isNegNum = num < 0; if (isNegNum) num = -num;
assert(num <= 0x3ffffff); var p = (1 << 26) % num;
var acc = 0; for (var i = this.length - 1; i >= 0; i--) { acc = (p * acc + (this.words[i] | 0)) % num; }
return isNegNum ? -acc : acc;};
// WARNING: DEPRECATEDBN.prototype.modn = function modn(num) { return this.modrn(num);};
// In-place division by numberBN.prototype.idivn = function idivn(num) { var isNegNum = num < 0; if (isNegNum) num = -num;
assert(num <= 0x3ffffff);
var carry = 0; for (var i = this.length - 1; i >= 0; i--) { var w = (this.words[i] | 0) + carry * 0x4000000; this.words[i] = (w / num) | 0; carry = w % num; }
this._strip(); return isNegNum ? this.ineg() : this;};
BN.prototype.divn = function divn(num) { return this.clone().idivn(num);};
BN.prototype.egcd = function egcd(p) { assert(p.negative === 0); assert(!p.isZero());
var x = this; var y = p.clone();
if (x.negative !== 0) { x = x.umod(p); } else { x = x.clone(); }
// A * x + B * y = x var A = new BN(1); var B = new BN(0);
// C * x + D * y = y var C = new BN(0); var D = new BN(1);
var g = 0;
while (x.isEven() && y.isEven()) { x.iushrn(1); y.iushrn(1); ++g; }
var yp = y.clone(); var xp = x.clone();
while (!x.isZero()) { for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1); if (i > 0) { x.iushrn(i); while (i-- > 0) { if (A.isOdd() || B.isOdd()) { A.iadd(yp); B.isub(xp); }
A.iushrn(1); B.iushrn(1); } }
for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1); if (j > 0) { y.iushrn(j); while (j-- > 0) { if (C.isOdd() || D.isOdd()) { C.iadd(yp); D.isub(xp); }
C.iushrn(1); D.iushrn(1); } }
if (x.cmp(y) >= 0) { x.isub(y); A.isub(C); B.isub(D); } else { y.isub(x); C.isub(A); D.isub(B); } }
return { a: C, b: D, gcd: y.iushln(g), };};
// This is reduced incarnation of the binary EEA// above, designated to invert members of the// _prime_ fields F(p) at a maximal speedBN.prototype._invmp = function _invmp(p) { assert(p.negative === 0); assert(!p.isZero());
var a = this; var b = p.clone();
if (a.negative !== 0) { a = a.umod(p); } else { a = a.clone(); }
var x1 = new BN(1); var x2 = new BN(0);
var delta = b.clone();
while (a.cmpn(1) > 0 && b.cmpn(1) > 0) { for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1); if (i > 0) { a.iushrn(i); while (i-- > 0) { if (x1.isOdd()) { x1.iadd(delta); }
x1.iushrn(1); } }
for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1); if (j > 0) { b.iushrn(j); while (j-- > 0) { if (x2.isOdd()) { x2.iadd(delta); }
x2.iushrn(1); } }
if (a.cmp(b) >= 0) { a.isub(b); x1.isub(x2); } else { b.isub(a); x2.isub(x1); } }
var res; if (a.cmpn(1) === 0) { res = x1; } else { res = x2; }
if (res.cmpn(0) < 0) { res.iadd(p); }
return res;};
BN.prototype.gcd = function gcd(num) { if (this.isZero()) return num.abs(); if (num.isZero()) return this.abs();
var a = this.clone(); var b = num.clone(); a.negative = 0; b.negative = 0;
// Remove common factor of two for (var shift = 0; a.isEven() && b.isEven(); shift++) { a.iushrn(1); b.iushrn(1); }
do { while (a.isEven()) { a.iushrn(1); } while (b.isEven()) { b.iushrn(1); }
var r = a.cmp(b); if (r < 0) { // Swap `a` and `b` to make `a` always bigger than `b` var t = a; a = b; b = t; } else if (r === 0 || b.cmpn(1) === 0) { break; }
a.isub(b); } while (true);
return b.iushln(shift);};
// Invert number in the field F(num)BN.prototype.invm = function invm(num) { return this.egcd(num).a.umod(num);};
BN.prototype.isEven = function isEven() { return (this.words[0] & 1) === 0;};
BN.prototype.isOdd = function isOdd() { return (this.words[0] & 1) === 1;};
// And first word and numBN.prototype.andln = function andln(num) { return this.words[0] & num;};
// Increment at the bit position in-lineBN.prototype.bincn = function bincn(bit) { assert(typeof bit === "number"); var r = bit % 26; var s = (bit - r) / 26; var q = 1 << r;
// Fast case: bit is much higher than all existing words if (this.length <= s) { this._expand(s + 1); this.words[s] |= q; return this; }
// Add bit and propagate, if needed var carry = q; for (var i = s; carry !== 0 && i < this.length; i++) { var w = this.words[i] | 0; w += carry; carry = w >>> 26; w &= 0x3ffffff; this.words[i] = w; } if (carry !== 0) { this.words[i] = carry; this.length++; } return this;};
BN.prototype.isZero = function isZero() { return this.length === 1 && this.words[0] === 0;};
BN.prototype.cmpn = function cmpn(num) { var negative = num < 0;
if (this.negative !== 0 && !negative) return -1; if (this.negative === 0 && negative) return 1;
this._strip();
var res; if (this.length > 1) { res = 1; } else { if (negative) { num = -num; }
assert(num <= 0x3ffffff, "Number is too big");
var w = this.words[0] | 0; res = w === num ? 0 : w < num ? -1 : 1; } if (this.negative !== 0) return -res | 0; return res;};
// Compare two numbers and return:// 1 - if `this` > `num`// 0 - if `this` == `num`// -1 - if `this` < `num`BN.prototype.cmp = function cmp(num) { if (this.negative !== 0 && num.negative === 0) return -1; if (this.negative === 0 && num.negative !== 0) return 1;
var res = this.ucmp(num); if (this.negative !== 0) return -res | 0; return res;};
// Unsigned comparisonBN.prototype.ucmp = function ucmp(num) { // At this point both numbers have the same sign if (this.length > num.length) return 1; if (this.length < num.length) return -1;
var res = 0; for (var i = this.length - 1; i >= 0; i--) { var a = this.words[i] | 0; var b = num.words[i] | 0;
if (a === b) continue; if (a < b) { res = -1; } else if (a > b) { res = 1; } break; } return res;};
BN.prototype.gtn = function gtn(num) { return this.cmpn(num) === 1;};
BN.prototype.gt = function gt(num) { return this.cmp(num) === 1;};
BN.prototype.gten = function gten(num) { return this.cmpn(num) >= 0;};
BN.prototype.gte = function gte(num) { return this.cmp(num) >= 0;};
BN.prototype.ltn = function ltn(num) { return this.cmpn(num) === -1;};
BN.prototype.lt = function lt(num) { return this.cmp(num) === -1;};
BN.prototype.lten = function lten(num) { return this.cmpn(num) <= 0;};
BN.prototype.lte = function lte(num) { return this.cmp(num) <= 0;};
BN.prototype.eqn = function eqn(num) { return this.cmpn(num) === 0;};
BN.prototype.eq = function eq(num) { return this.cmp(num) === 0;};
//// A reduce context, could be using montgomery or something better, depending// on the `m` itself.//BN.red = function red(num) { return new Red(num);};
BN.prototype.toRed = function toRed(ctx) { assert(!this.red, "Already a number in reduction context"); assert(this.negative === 0, "red works only with positives"); return ctx.convertTo(this)._forceRed(ctx);};
BN.prototype.fromRed = function fromRed() { assert(this.red, "fromRed works only with numbers in reduction context"); return this.red.convertFrom(this);};
BN.prototype._forceRed = function _forceRed(ctx) { this.red = ctx; return this;};
BN.prototype.forceRed = function forceRed(ctx) { assert(!this.red, "Already a number in reduction context"); return this._forceRed(ctx);};
BN.prototype.redAdd = function redAdd(num) { assert(this.red, "redAdd works only with red numbers"); return this.red.add(this, num);};
BN.prototype.redIAdd = function redIAdd(num) { assert(this.red, "redIAdd works only with red numbers"); return this.red.iadd(this, num);};
BN.prototype.redSub = function redSub(num) { assert(this.red, "redSub works only with red numbers"); return this.red.sub(this, num);};
BN.prototype.redISub = function redISub(num) { assert(this.red, "redISub works only with red numbers"); return this.red.isub(this, num);};
BN.prototype.redShl = function redShl(num) { assert(this.red, "redShl works only with red numbers"); return this.red.shl(this, num);};
BN.prototype.redMul = function redMul(num) { assert(this.red, "redMul works only with red numbers"); this.red._verify2(this, num); return this.red.mul(this, num);};
BN.prototype.redIMul = function redIMul(num) { assert(this.red, "redMul works only with red numbers"); this.red._verify2(this, num); return this.red.imul(this, num);};
BN.prototype.redSqr = function redSqr() { assert(this.red, "redSqr works only with red numbers"); this.red._verify1(this); return this.red.sqr(this);};
BN.prototype.redISqr = function redISqr() { assert(this.red, "redISqr works only with red numbers"); this.red._verify1(this); return this.red.isqr(this);};
// Square root over pBN.prototype.redSqrt = function redSqrt() { assert(this.red, "redSqrt works only with red numbers"); this.red._verify1(this); return this.red.sqrt(this);};
BN.prototype.redInvm = function redInvm() { assert(this.red, "redInvm works only with red numbers"); this.red._verify1(this); return this.red.invm(this);};
// Return negative clone of `this` % `red modulo`BN.prototype.redNeg = function redNeg() { assert(this.red, "redNeg works only with red numbers"); this.red._verify1(this); return this.red.neg(this);};
BN.prototype.redPow = function redPow(num) { assert(this.red && !num.red, "redPow(normalNum)"); this.red._verify1(this); return this.red.pow(this, num);};
// Prime numbers with efficient reductionvar primes = { k256: null, p224: null, p192: null, p25519: null,};
// Pseudo-Mersenne primefunction MPrime(name, p) { // P = 2 ^ N - K this.name = name; this.p = new BN(p, 16); this.n = this.p.bitLength(); this.k = new BN(1).iushln(this.n).isub(this.p);
this.tmp = this._tmp();}
MPrime.prototype._tmp = function _tmp() { var tmp = new BN(null); tmp.words = new Array(Math.ceil(this.n / 13)); return tmp;};
MPrime.prototype.ireduce = function ireduce(num) { // Assumes that `num` is less than `P^2` // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P) var r = num; var rlen;
do { this.split(r, this.tmp); r = this.imulK(r); r = r.iadd(this.tmp); rlen = r.bitLength(); } while (rlen > this.n);
var cmp = rlen < this.n ? -1 : r.ucmp(this.p); if (cmp === 0) { r.words[0] = 0; r.length = 1; } else if (cmp > 0) { r.isub(this.p); } else { if (r.strip !== undefined) { // r is a BN v4 instance r.strip(); } else { // r is a BN v5 instance r._strip(); } }
return r;};
MPrime.prototype.split = function split(input, out) { input.iushrn(this.n, 0, out);};
MPrime.prototype.imulK = function imulK(num) { return num.imul(this.k);};
function K256() { MPrime.call( this, "k256", "ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f", );}inherits(K256, MPrime);
K256.prototype.split = function split(input, output) { // 256 = 9 * 26 + 22 var mask = 0x3fffff;
var outLen = Math.min(input.length, 9); for (var i = 0; i < outLen; i++) { output.words[i] = input.words[i]; } output.length = outLen;
if (input.length <= 9) { input.words[0] = 0; input.length = 1; return; }
// Shift by 9 limbs var prev = input.words[9]; output.words[output.length++] = prev & mask;
for (i = 10; i < input.length; i++) { var next = input.words[i] | 0; input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22); prev = next; } prev >>>= 22; input.words[i - 10] = prev; if (prev === 0 && input.length > 10) { input.length -= 10; } else { input.length -= 9; }};
K256.prototype.imulK = function imulK(num) { // K = 0x1000003d1 = [ 0x40, 0x3d1 ] num.words[num.length] = 0; num.words[num.length + 1] = 0; num.length += 2;
// bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390 var lo = 0; for (var i = 0; i < num.length; i++) { var w = num.words[i] | 0; lo += w * 0x3d1; num.words[i] = lo & 0x3ffffff; lo = w * 0x40 + ((lo / 0x4000000) | 0); }
// Fast length reduction if (num.words[num.length - 1] === 0) { num.length--; if (num.words[num.length - 1] === 0) { num.length--; } } return num;};
function P224() { MPrime.call( this, "p224", "ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001", );}inherits(P224, MPrime);
function P192() { MPrime.call( this, "p192", "ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff", );}inherits(P192, MPrime);
function P25519() { // 2 ^ 255 - 19 MPrime.call( this, "25519", "7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed", );}inherits(P25519, MPrime);
P25519.prototype.imulK = function imulK(num) { // K = 0x13 var carry = 0; for (var i = 0; i < num.length; i++) { var hi = (num.words[i] | 0) * 0x13 + carry; var lo = hi & 0x3ffffff; hi >>>= 26;
num.words[i] = lo; carry = hi; } if (carry !== 0) { num.words[num.length++] = carry; } return num;};
// Exported mostly for testing purposes, use plain name insteadBN._prime = function prime(name) { // Cached version of prime if (primes[name]) return primes[name];
var prime; if (name === "k256") { prime = new K256(); } else if (name === "p224") { prime = new P224(); } else if (name === "p192") { prime = new P192(); } else if (name === "p25519") { prime = new P25519(); } else { throw new Error("Unknown prime " + name); } primes[name] = prime;
return prime;};
//// Base reduction engine//function Red(m) { if (typeof m === "string") { var prime = BN._prime(m); this.m = prime.p; this.prime = prime; } else { assert(m.gtn(1), "modulus must be greater than 1"); this.m = m; this.prime = null; }}
Red.prototype._verify1 = function _verify1(a) { assert(a.negative === 0, "red works only with positives"); assert(a.red, "red works only with red numbers");};
Red.prototype._verify2 = function _verify2(a, b) { assert((a.negative | b.negative) === 0, "red works only with positives"); assert(a.red && a.red === b.red, "red works only with red numbers");};
Red.prototype.imod = function imod(a) { if (this.prime) return this.prime.ireduce(a)._forceRed(this);
move(a, a.umod(this.m)._forceRed(this)); return a;};
Red.prototype.neg = function neg(a) { if (a.isZero()) { return a.clone(); }
return this.m.sub(a)._forceRed(this);};
Red.prototype.add = function add(a, b) { this._verify2(a, b);
var res = a.add(b); if (res.cmp(this.m) >= 0) { res.isub(this.m); } return res._forceRed(this);};
Red.prototype.iadd = function iadd(a, b) { this._verify2(a, b);
var res = a.iadd(b); if (res.cmp(this.m) >= 0) { res.isub(this.m); } return res;};
Red.prototype.sub = function sub(a, b) { this._verify2(a, b);
var res = a.sub(b); if (res.cmpn(0) < 0) { res.iadd(this.m); } return res._forceRed(this);};
Red.prototype.isub = function isub(a, b) { this._verify2(a, b);
var res = a.isub(b); if (res.cmpn(0) < 0) { res.iadd(this.m); } return res;};
Red.prototype.shl = function shl(a, num) { this._verify1(a); return this.imod(a.ushln(num));};
Red.prototype.imul = function imul(a, b) { this._verify2(a, b); return this.imod(a.imul(b));};
Red.prototype.mul = function mul(a, b) { this._verify2(a, b); return this.imod(a.mul(b));};
Red.prototype.isqr = function isqr(a) { return this.imul(a, a.clone());};
Red.prototype.sqr = function sqr(a) { return this.mul(a, a);};
Red.prototype.sqrt = function sqrt(a) { if (a.isZero()) return a.clone();
var mod3 = this.m.andln(3); assert(mod3 % 2 === 1);
// Fast case if (mod3 === 3) { var pow = this.m.add(new BN(1)).iushrn(2); return this.pow(a, pow); }
// Tonelli-Shanks algorithm (Totally unoptimized and slow) // // Find Q and S, that Q * 2 ^ S = (P - 1) var q = this.m.subn(1); var s = 0; while (!q.isZero() && q.andln(1) === 0) { s++; q.iushrn(1); } assert(!q.isZero());
var one = new BN(1).toRed(this); var nOne = one.redNeg();
// Find quadratic non-residue // NOTE: Max is such because of generalized Riemann hypothesis. var lpow = this.m.subn(1).iushrn(1); var z = this.m.bitLength(); z = new BN(2 * z * z).toRed(this);
while (this.pow(z, lpow).cmp(nOne) !== 0) { z.redIAdd(nOne); }
var c = this.pow(z, q); var r = this.pow(a, q.addn(1).iushrn(1)); var t = this.pow(a, q); var m = s; while (t.cmp(one) !== 0) { var tmp = t; for (var i = 0; tmp.cmp(one) !== 0; i++) { tmp = tmp.redSqr(); } assert(i < m); var b = this.pow(c, new BN(1).iushln(m - i - 1));
r = r.redMul(b); c = b.redSqr(); t = t.redMul(c); m = i; }
return r;};
Red.prototype.invm = function invm(a) { var inv = a._invmp(this.m); if (inv.negative !== 0) { inv.negative = 0; return this.imod(inv).redNeg(); } else { return this.imod(inv); }};
Red.prototype.pow = function pow(a, num) { if (num.isZero()) return new BN(1).toRed(this); if (num.cmpn(1) === 0) return a.clone();
var windowSize = 4; var wnd = new Array(1 << windowSize); wnd[0] = new BN(1).toRed(this); wnd[1] = a; for (var i = 2; i < wnd.length; i++) { wnd[i] = this.mul(wnd[i - 1], a); }
var res = wnd[0]; var current = 0; var currentLen = 0; var start = num.bitLength() % 26; if (start === 0) { start = 26; }
for (i = num.length - 1; i >= 0; i--) { var word = num.words[i]; for (var j = start - 1; j >= 0; j--) { var bit = (word >> j) & 1; if (res !== wnd[0]) { res = this.sqr(res); }
if (bit === 0 && current === 0) { currentLen = 0; continue; }
current <<= 1; current |= bit; currentLen++; if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;
res = this.mul(res, wnd[current]); currentLen = 0; current = 0; } start = 26; }
return res;};
Red.prototype.convertTo = function convertTo(num) { var r = num.umod(this.m);
return r === num ? r.clone() : r;};
Red.prototype.convertFrom = function convertFrom(num) { var res = num.clone(); res.red = null; return res;};
//// Montgomery method engine//
BN.mont = function mont(num) { return new Mont(num);};
function Mont(m) { Red.call(this, m);
this.shift = this.m.bitLength(); if (this.shift % 26 !== 0) { this.shift += 26 - (this.shift % 26); }
this.r = new BN(1).iushln(this.shift); this.r2 = this.imod(this.r.sqr()); this.rinv = this.r._invmp(this.m);
this.minv = this.rinv.mul(this.r).isubn(1).div(this.m); this.minv = this.minv.umod(this.r); this.minv = this.r.sub(this.minv);}inherits(Mont, Red);
Mont.prototype.convertTo = function convertTo(num) { return this.imod(num.ushln(this.shift));};
Mont.prototype.convertFrom = function convertFrom(num) { var r = this.imod(num.mul(this.rinv)); r.red = null; return r;};
Mont.prototype.imul = function imul(a, b) { if (a.isZero() || b.isZero()) { a.words[0] = 0; a.length = 1; return a; }
var t = a.imul(b); var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); var u = t.isub(c).iushrn(this.shift); var res = u;
if (u.cmp(this.m) >= 0) { res = u.isub(this.m); } else if (u.cmpn(0) < 0) { res = u.iadd(this.m); }
return res._forceRed(this);};
Mont.prototype.mul = function mul(a, b) { if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);
var t = a.mul(b); var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); var u = t.isub(c).iushrn(this.shift); var res = u; if (u.cmp(this.m) >= 0) { res = u.isub(this.m); } else if (u.cmpn(0) < 0) { res = u.iadd(this.m); }
return res._forceRed(this);};
Mont.prototype.invm = function invm(a) { // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R var res = this.imod(a._invmp(this.m).mul(this.r2)); return res._forceRed(this);};