-
Notifications
You must be signed in to change notification settings - Fork 84
/
ec.scrypt
189 lines (146 loc) · 85.9 KB
/
ec.scrypt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
struct Point {
int x;
int y;
}
struct Signature {
int r;
int s;
}
library EC {
// Curve bits:
static const int CURVE_BITS = 256;
// Key int size:
static const int S = 33; // 32 bytes plus sign byte
// Curve coefficients:
static const int a = 0;
static const int b = 7;
// Generator point:
static const Point G = { 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798, 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 };
// Curve order:
static const int n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141;
static const bytes bn = b'414136d08c5ed2bf3ba048afe6dcaebafeffffffffffffffffffffffffffffff'; // LE
// Curve field value:
static const int P = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f;
static const bytes bP = b'2ffcfffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff'; // LE
// Upper bound of the eGCD mod inverse loop:
static const int UB = 368;
// Precalculated doublings for the generator point.
static Point[256] DOUBLINGS_G = [{55066263022277343669578718895168534326250603453777594175500187360389116729240, 32670510020758816978083085130507043184471273380659243275938904335757337482424}, {89565891926547004231252920425935692360644145829622209833684329913297188986597, 12158399299693830322967808612713398636155367887041628176798871954788371653930}, {103388573995635080359749164254216598308788835304023601477803095234286494993683, 37057141145242123013015316630864329550140216928701153669873286428255828810018}, {21262057306151627953595685090280431278183829487175876377991189246716355947009, 41749993296225487051377864631615517161996906063147759678534462689479575333124}, {104059883622109321374094289636044428849728529177856482232626205340719788190730, 112122903140080327253741791678230372394936108416576609264408917599318947489825}, {95440839670107969455973995843666399663662641812074432045896568980475242364517, 67400892360194400039319989411395972789004161889863182881857158544061243615929}, {86454928033100054822938644242727206101601557724291916072342392316125160730507, 41929975541376036990359335647717381527212342035893043668288666074313354583455}, {23971227478092690611538379282579297124953800109492367109857348294863777014350, 42342609885299334444880650568116455571250837701978463648617679521175848103706}, {59030624050581421406270513075794029219285200067000787157698366092408912155912, 8128656248049033031875480515138402531865803579197128279783442554673902546095}, {31809325515952716603993860438135646801954922215901515683284707473623428145741, 24377531977987817432088011602449325046972761657480460991275213238540072159220}, {16339661702852967382840638396154683021742565846854739320600712521008743256863, 36728284022334234592863792440353097018527397507662959793213172092233334129261}, {42114313391321156005599920754056349597018482182309287550535575450912996590705, 18211792713336063942313736004207749605328499756363387606667481967702897602819}, {10569428376872096169397247199835207726595431926877749141789405073030710146873, 95580118375493152898771330185112988759633284070886792649665201458589961475733}, {29955133736896634235893587837609964910900820068836768599575322235881802975190, 83725361430957575604497772232028370201521594201253320640285202099397696195124}, {7741290454269945723504810030002187313337519274815056282137434463684850516554, 2979905666851018206144735065445742806952013006906430309532921989383330523600}, {33602655200186679430886431101373729519010186911116350037909320311808627496821, 37360103261735091089003680850413001554296156453961728314327616229790563817069}, {24533671068980092868630552346995129420983823672304585196401986911541584152128, 2209357222459695347071765155987393997305194371900031813817445740077485301225}, {34424533203459102608471296411716955901929203809676354171491737723302766101825, 87733804348534428731161926933835660863551297059124747814746905172819546464288}, {74193831669845249654938577341216601539929459848933807922451592200153851425745, 29361396017150706741613988342393505196301946421006103373231627829781191611577}, {75996994270594548260051104099040009002173474732108538694613575188101535421242, 67731220512052072417843278921450425890601471538300788051881284779249943090810}, {63004655751848499058589887215149057167805706207141784701705408548476267919372, 33776887358425213876727286236887696644549240079971817446727643228044518554934}, {107219988410259287649822325760828753777881271537028923079899200557009639695550, 15425677638027042728233515882140468124385010133809940201784713737762399581231}, {113496403293373161892995045761087341014991661230000874253822611507549586770091, 92288978233865387499357228995099386605786555025834285738713074898639193985136}, {4402168996420289224849535114023409990325018394340995944430318114273800335863, 67104318001466418430256649108646734852945972191921730406768272163045294283904}, {51670963786757573841189746283202124387362261809800652891978209018731111316698, 68257551575553566084241009552849606333781498777275567535225153774080710909791}, {39774650486605686761949696375291962760476627649023643684500799050103063064789, 97280577493662175430906331419179376788053309764979933526226118285088405860254}, {17321708023578332183628700857357458473789564616208564602894355867116410260949, 97919434988400284406895062116320315016365801759636091852848099981382771845905}, {76575849854364972542951978758356689466650880857178783481542510110017069529320, 81925384519567487405199682290695043524776979911807891169446287270330277192180}, {107989063369659015153804811955459434214410196483964476598208978660096898619386, 42338160021087805224648939485129818613830046750563614152037885753448952924569}, {25379507781751782970997391382797328968603613636745039424586338729874508912637, 66678967052843214385960608145916057604491714224625771583834324020892145369029}, {102193949730178242338502490474683128513913323030888946433219655522103301391692, 6691527371710806382780054211605006078697403702312160758173793149761505802135}, {37586094085820668222219663528035831988292035114036566702275484810122124564900, 110500050436317590116317882856153568952218728972968181243435825114259637008685}, {7263983490427117408129518121638485560698559702481803384958991237905117384112, 93109094002033366773627505914545361927166820241279828474630961892312310241801}, {63340652510566015247975818591385417300086272434074184937732392505693958960902, 113667876764634414158091221422353531108236715357465572941896170017035409095320}, {113783330688848408326400254714688308943084902760190583586245237148771972268029, 49136863138091630742201940998618633678196612987804544425991276550671171170453}, {104610067874554658939189781067288826551534040873032177114963645859116975547034, 109770660671288161864329498510482442986586271328087679077837897757717839673046}, {101775883922931432108027453607406809406988783938200607927691949357708936019245, 71211677518830069576439009135279320536125727843027256193157225588947573710861}, {110691637496015646289262932234825854023102359733628734435283445248364686115670, 75300502224888127283828373326871043861231715295745491495384349459792808386515}, {4441278141344175957087852960979663063777598386288590018731867755649013517962, 7836136238007924788592053766414363238944904687598451784829364216715569810500}, {89749383265034677666862365486905244671167444330802547291623325584186528137154, 98309468026548637860626714749357698670012533693024507288465476348752328350038}, {115301655840403608332148854465368444683257224081574702572138639602380667382125, 103799472776126890762485670055583971987299536955028941653349419016168013365384}, {34828167905024529293425261847016829712897759939934247610415071312015953046280, 47968762878478268758489427369126262603811724231741657789486393243885145959658}, {51545007865675218331521052163329117547916750428334376359731030798802230204655, 106410582405992915570439467813541861485454771813746638713688333696184247730702}, {73599252554810039763407176139974374780648488828183406696254895715553023853401, 47578048250598054907858110438316220654276129654309504967125355240893257809602}, {98787353431067487068174780415369765662128367506208336868623541747762523303089, 70413563958895942572205979769129125709431089683617469237670049369710274330141}, {35158139218869787362323693979796990367921058080517113277431623829383205568969, 10295997985162667395889563220444841839650277790026794883844526680522437342755}, {8964980402707168350657927400892132353366269496956872817449479166659938883802, 43436562493669582162283754540252355903120339577829436566794554777028968127513}, {15200734767215737518231163530398231089737396965964050975192487891396519882168, 16668035065520662549877161813594040899471944430197287458384095143621564263367}, {37796942232071066358676457518924870482193007026528914004372298991835746383808, 41500641220791808004786750540350768710904110215016898096683828744807363604936}, {744654853145823512678710729425372655622767097643314990136170544084291976361, 21811628975969469444130274876674950438343669908561616590110157209566897229239}, {111242239008385952039057432864293978327910479690302189733526349492851051943515, 48678944480045457289293852267343808286651244662567230126433152661761421134978}, {64822851514371701744734127217317271752112350344524279674961846392399328587059, 31943858956135239004423171297694200648464614566963609709790210548050786133055}, {64447161864609791404195758691963071452721019060247337925015807247342017994823, 7561160199009862821682934691566626840504770282093073394715850644522417534762}, {23384853547122068788990499588260565640987768803883409730753963558864234152785, 74875455409133275347616261968367570739354909860053424157743477951969742386200}, {25014901206392249887698237444530503896296748023707107244397125743674754644790, 10433933909011809793968879060653803690577200525567091682194830769813011264330}, {16058435479155118972993837131799089058715967396125428615558605751627320645142, 50458543989467853184310582844531917678045791765530172581605874408799080266778}, {25497240280963516313937320941859063956353887664759333529694971679324342859874, 18198385112262447554198951719878713582193194360950043848907411919888800699475}, {111703840010970554703825044762397257236786082270905035457492386104226958443132, 12575192387335088647665557233642046097109374697403005848728748607053249552642}, {113599246344934629336805861786255890702306480065011524716308738005517377133750, 110309842344688524387480953361916993633315112298643725699639662741987291457779}, {62223290140977849549949037397413163042719030609658769845468333603013413866526, 98850328278678552505680434968308156848819817765906617232115049710824480247537}, {3155324650630266164941215407725229976924800176927891490779584824139541300135, 56314320032835626861988128097937936814282839310958875562434488369232472187232}, {78940842088341059937720881764219942614374815880107123037550313585999765034797, 11720516568179571270476509769942606239875063370184749544905787775519145474236}, {15507243805774944259617131345561156696188939847401319273193860618228585632400, 113088070675147226411797488422007342957654795984396137910695709288095002042967}, {101817088763764058272032685058193941686495949380163784665542336507398664578275, 61440383708720907418547117747158586276459762378915736297042955400063318409160}, {23129491278950567785970148376500648032717531886785241126168611397589814798013, 39307099057880941662675806615359097347682728603444928455093651353540932186784}, {63843472757015161619640823952764524318291830965488059905636263767209969312866, 106712674239183055714747170770237410600716249238757184591428740534726428083980}, {8241903038354912941099822707985246210294044712473769251710198461880050574899, 62697784033925076403474224442689974679135179320309080987220280194454804723717}, {17692067919141883746474430216313318912323253047795385992074267436472656099942, 42168706312448760835164198288963124085049274787903511949048046806853155067687}, {60339901160910692237675572757878163770580581369373573584664013679285413129091, 56214196748543440839296827556230703893730514912272645534922309181995758064550}, {37677678367764998054256419260552297374816808777506812193658101085944629689381, 96542930188656188775421614396743163957109245800132742492178822512944546868854}, {76492326435022593457109032906840314586595419299705002191405820035073916725430, 52712462544684042050659798408142998446211290189326915216568750458192003482817}, {87459896917474640671961280404348939194085731117863029170554666522628858367860, 19748635217315891647321224482939896170227416763285583086520508401939213234176}, {4199350326672760747807816527418159685216655440503240677878553304602602121738, 37834176166477149356292507688627259926034564110824553771704962901036071708041}, {17451455565379830237189058882419931909327937825123020642064169531348745912330, 110851835063999899423756612638945142128964968911486626329802042725525613408346}, {89639832565486215014541417774517172777425402823469120565037348938869913112470, 30572655366218421290699322537451162244586583424941183840353131006508265175422}, {7442624616783078815918535545170738536276686106683368472213004009997925387451, 77751573448339894342899057498199969560748665539929390648020324044053699567908}, {44497701670421232817550738477766131574027528256828192704387553796074849163496, 85115484315990908818625714664072075837750502822084508644932753849460649668119}, {60540754330080069959401906198898450479294126639715413570889179042286485863469, 40065985632112285488262829097473122728635230343056068824717075042107181358448}, {64303414747220612283598620667555879428236715359485947560901082787102828757209, 106228226569454347670647985876151839080805653229947291906912035484638171537232}, {53648153254893980119900785370237364158138815147385101116545069153555170288062, 34361801916858031928794980991103430340262038618413794433537084872221158631519}, {103585811642593135420456399622448891166663363501464111582343873522977792850477, 31409815155472435338582344935230131320197144774427706287861757740924066421722}, {75027487913834453984361996105244344495268805009066851630705393620238615786735, 4325061896769276104913772732319997098916385262805927028161444887858874342220}, {76702516343213003595855178542925743016592575440900459987979293581918663676498, 59169763974292048230483290348723286025776147993831754859145423822145515799140}, {82065288257280364930681258037857029580600229348145328350024440340670179446551, 23027132854424541515521319202161519225460618376982276335759008484746030223405}, {101493787511861733029271951475039268072513144731938223971108244357658061891365, 55437542190981407452923664626193149136100172061209688271244666364673120940509}, {6636410774506556864774005162061951749450537962799954397758090215581031792446, 33193850663848721154507883351096416412681014543344176760472364118972599175560}, {97007893071212898831976542306925407114333944783774668033349973529691460445404, 18507121058431491916818312533740360825972223949528183085794866203720624591878}, {47579402496219589148753080604487008179301822313334601064657607711684826233267, 57448470377652821134170456021628327741101079070106580787911301709526093883982}, {15033179896439470858126247808641765484544705738074160218957951164394937620308, 34117244282055289120898203738790815580918088000686828227920818069382230202610}, {12831426614286788027900392815123462940913304574075286993885122038414101217196, 36179658746250976381135601610242632021826214896264269021914509495791394149615}, {31731558888758314830347225402035966953019197198882726537928061332981883805116, 6359760100839187210073863293870527713027761135409961108195017073136576674018}, {108516937186382041812103670511048142301189499913949040064226297021918453104669, 77218777772268311707719666397699916259759523817816920080352731398095643624469}, {35499761538901346298861898883401367492089066355756477731651612619020269507900, 10609229642071556953120109475763397943884016840919846757331088165175050414822}, {62221449722415965098534394864216300756619410467360193813993841802984909839181, 30612701817593165310829908596077980446317954217062442246601062375597549071147}, {47023343771514073333682842422673144869316327792644186859934319437403081634095, 83317154179385276448599698389111199063686628672572418790396772309007183470821}, {22840966669343746868657542410372307235035375411707745900291535045354561578850, 80886292560052078022819942209443457651640717456431378184925170018374473757441}, {115183067000797961901920784023024616254245272923307973061240480176353201301430, 49763971281659542105744668679966078286699279184665337082856648066049033156975}, {107460092490405557856637269383143137018363307684850226624646466770567328913124, 27927879468288414295198600435976090224174968562527111521940172877594627850158}, {18928961140921885700908658116849834750075223885003133432284077605308119970073, 57811541833390055306833565592598106401230808311112346834369084436570498753337}, {8331289978464196047324092750470018314791143098216854808915615772554507199633, 87592962133464766467334907348498449098375430086853996682723463167279731306372}, {53779740109432100521872576345148245383728952983207835874526110853417815367225, 90939394492963130914544575569526310734855569061258844327812366475243930364929}, {50903437175324684576123794325687091093316794895342376267022156508043454547877, 70349280139070181932538936546431771279420426752065163651109781251026950404544}, {11673581412764099021153615077620366366802304893369795243117390666352665359806, 18493885180880533479983549127533520654731835271435443031664047750964210440946}, {79346041630131869075645430486783108716991485536433518103538843150249487037416, 3399478885375643092936720555036030158803236931787480448997057703838011734762}, {90110562832831649967185144230038867070402237425213645393423897349775852026001, 62079424087973467789382713581435573708404480254567931314506333392316481045699}, {38659527363743848181468463025813757193528718820669569569114028561419930348315, 104083246136889829683331969264423162114671872108616362771383171554424986219793}, {32543944108095182552403308115282823595699487874750970784134326899018753076265, 32924494876951284146279766638563025708747643322813908934636585593423158017785}, {87183516938829948739214915672694597601526144237528747913079459935123543116507, 5210361221244717547856165246556020619071402127820810229408988718584663707749}, {97963514608391620515365258119340011983767027607182736209046173629563994030411, 115226106161721418677257600232626422670483402750299325766423254986581008554271}, {114469486435796862354824725635274301733105436679732187907727741160909533840420, 15176610360357502916376731715182826626094867832295623397483794147117662068209}, {98432034282390382237828948384540370085442598032656811937139102930236777548604, 24813777388505064074621970457041023547619648696034102349374362496379715467175}, {1805616805351721617653443610838676066411318390548678811172302707980664066418, 29197166736887483563928586983131420527850770453920557715930559189098823391124}, {83611758343266467712438158213251624839283837284463888705796077990149381123587, 18101124850041158815009009485735144088925930424123803647507665853537289369319}, {49398952861877205296964985511595482837454065472867773380651392793273881817706, 103456599417569656329743525842643406894367321159609200220648758243892831845501}, {26557021881017484338287109395067993477080269267457693436680348679906749635481, 84487769519853421430030359463214449378435630494204186353059369760950916380835}, {54910438115352124820925906331600651980234249876402837107104827961903280048346, 35080546347367598434982768185387546912732524650521251475529423425038042189569}, {104964699132307836705335251996858916554346905150414321329455806487577227222877, 108021264621442630025722058757308611603027665565497116827018930375054827580536}, {30779593535010329084651325212930254896397289835007988481712809855381584203096, 75438522668351783504686245637900335802808862903871170538716693983846568968011}, {111531859894160106348996194269099060679947894846103401064923066647433585462032, 29241751855199681568367284518448893439960716762286924487213503019678103002705}, {63066765102144977597923579437181551876011710207298597143023780209765509321725, 106007349317296939888635500379499007381281650903559653902304432927687101375981}, {73729489189146206306669255701359614973467519172738994441001234600131693731952, 52215583774525796109567946288556659634043653399932078971590626905269875474081}, {18039326416892417753003755158326429558922487640705110383763721719977461130670, 22183031661069407114947469617732171225545226302519288081136966780058091537843}, {90043658892995399465363207869075768002289250211409595011736991935239142954926, 33195971463859634916825320647431346032578912048614106257629795755556424999572}, {5420721428656512733924502511426114039091019723753927823327107920655123143427, 11458489637841101089267453881300170307046154505862838558859267626137645974850}, {65439637510807713056358030282940995565074807966223863057633547322884310978260, 6474571117676685817754405485757825849845707811112126411536249919905291235664}, {57070623766206825319979971604352341937693971268571462200885005684041460744529, 65294641003401362594966851216569681914884202591426370350835007421691752226503}, {72947739749743623666767893079604022957810777496958067665094811548956867552663, 74931287229039237066253562221237323976647082407514979153759017931296701314826}, {95120790446093252839327344452467895851663435942220974758177611352160193500228, 40252511218087247830580930812776238463499994792031801540758272438053921180247}, {64865771952738249789114440545196421582918768733599534045195125031385885360346, 46211216742671250426576585530459394900178019437443360579906162037052661563266}, {34958276914040952500699582748843894357474821914666173518868387777824232206454, 92814217969284136468346182500006122495187572087944979217112043851363214063646}, {53097865109432700015174734468294135156387483155245154627764610227234210717734, 87675404738916139099090938273911264414778058285600924992648328889621933853939}, {14944996539173920287535718879437473208319387726469358424706553507748318061176, 46613147883270029947538528514141525607759085017677379708440701301821571539505}, {103558405691517931349553446884579863115096122592891559643307293876412976668177, 13744988175479693349153508932944119281940564264745175840075269177938566411196}, {34009678302028016429416675792156881929217167215919330167617059558107204398895, 52818492011674921634940119787779214367302340414675558363211486292657494734263}, {92137904221004991822640747341747548945462418389173665085162488592935043663263, 33517309963374711058233805017888397313880557032455674904311603088567752722188}, {110576394165891695959547398864574113324861677782985712232382940604063624860352, 57461221252293229523075183660643751795445411566005575478984600070226388935166}, {63325528419660284613648700910995098077763772416467869706013046991065094742686, 108393323332799615882600625899672562866564791265938552990560624893577369108811}, {16650325658330045346563110008023955204728736149712219077558782426015089744479, 106745057410625224717707804586771450297805286348157954948730939917388737042539}, {131611795964869315746733228552844550837488089277020511476213613441587846562, 83923066471392572458821227876885635434639856986135936389815903323954601786918}, {107872043834894622552741642145000578443189656222946491690889504134408605289317, 107099881035735432711210408988501874747725935128038800415340434399284629514586}, {104771248853243272236194848180534099944827442851439463989997715693033419914817, 19204842090783572478934763263896016084146536297748178843263225598863834152273}, {111175281461482630465516451385666215051004681245013976528598462758289754744929, 11718140657345423934070547093851147149502657148997117054604879635944084480924}, {105488831999329979845280202950265439784555002249815723414248217238410787198545, 60737856123767596328148824409984345799986282506783260172759469126809007188004}, {17310420785061577297752661644696441307039468088644562990992232456213652941707, 55135767764556490992818664763424664824858578437374820236794056603342661870707}, {82443941766934163206572457262087615792206098199618204196957878539943664124143, 2933900802655320228371872386727285565009607891164205160519475145640485435973}, {103962888990006132945402596005118657935911401245401713878311715854693536019743, 35170703879107070397528715355676250246151611539838021540277202550315100054233}, {76798050358113205419697175833140553167147138571698176181621558826323550756452, 110695089775790420212275781036515251705109498767909652055725128324950720721559}, {47484798214816784752283428012568388928491303787309098798019624575261039535228, 92757387985797433337504154397545024770971021650910819219563990946722655340125}, {97039663311497459657247911541193759080562874005661443810591707745986428879848, 99303278877429417088246557868681959316984965013771041163804468621043567898912}, {109195128225849040977606835881519875573565462568688209681805403608282150647549, 19112323507498003064396425936166321573933767740378942347221947598633080738522}, {29549999707259271673252605691545279799740052232833339972136839518663945868516, 16136664718778354741239915467490083114312845627443806165166400322025562172700}, {82879960253585350000979087803723632982965447634585893737399105385978335789638, 69839675855252625382864852692238872585628385971310815662725729943087609430139}, {22748028221779319076176510624118970842784515483405130895360428655102883872093, 45475484805375289014292969224159029645777915241785857295305535555664117202052}, {22971131504152232323989187247411808869683627396897027961368542431926019004233, 97609736426556728831591583803631233034684715940413408963258107819767740020195}, {106366286125714711143514653622793217383752466534676761043495549248010028815844, 63443518936078980928975271049594475518271079655621131486236396265316979810558}, {75243349452409400390670867080265400955826636238534964912250945418780832972765, 54981855232630153751619068839379710690392191850677614602646052403990831204099}, {35269368267879876076917370410294906058734293247594447113822550857168296692886, 95273891293316720854000721987756315180413338976852308839788251922692115805}, {107287887465783333787672797357624470089624197428007725918345876586585458515460, 8424212039425668253022291013437891429871302723219086751247826238756909595104}, {104996070104664638505320040442013632557530551413809799698237157067229055154261, 78673807004489092854216395411129353437829079224915559696534676000382399098335}, {28519628026037066657027912209611592939997525521524547924497404284374169515054, 113911143471074069342269815156022191118395698271153725836799489558703307009470}, {70661691742434068036519986667419907196041281127668848645928138120846244813005, 100286785047006832236729389681182172543048508833941702006321829459516874054045}, {20912437725801942983686217293131152237262404596163037810613525995454376577516, 56487811975550303384642959780870327480512649236944577417586609378984145534}, {105337008461688988395496963115550441795554320308823072776506794583685171281126, 32017945344679105301355390714034191900569536621409624903946887176817068091004}, {75685728382744045810490612211978229115853638039525209649070995925887462388674, 85529213318684499199278987295719119779748279834721244243621489005051282713327}, {43575908198494793243005774075373759548810068549539444933972772880645886663141, 69703777934707822825561719800850612270463729018593401066444767531444843422376}, {46793159748319014521754592728195492543648682627431155803053172123841138087004, 30896349737549724559469649176734599846674275470447944521491009517811476115886}, {101757012457202265442783729516325848567041695344201435111479322003948473610273, 5581666239041823897511191387175605974957398643319691692931775273945574355546}, {30209700677164570836251569796863977697827501003939778269324249569134489792003, 47413224699192139329891654683339940809213741191817662756932842522986369283987}, {74841650891382527078449938271109455202772530131693735678356618476847598486118, 29242638042721994709047470454581660554102402946865770918554005639977770323656}, {71631157476704051659259801706240663560508572801269375166786124610215506626710, 50626912648402731289281390580926582439784259522574187076012504768241480157237}, {75928542468193195488721590741574481272714198891253064800438184108329627778720, 75192750551909937947468929249355987104463312649195251159923289612823008422826}, {87929611941466450580474503142124427241088012317746799540322218015595119056635, 104894792315886610373915701617963847607765162153160773537780133243754931320852}, {54038406999518685708957755903010924118312453838615747233838912018122735660401, 23694175599991408963414726019522496431384061981312306500396236825552398271404}, {104811972735495353830322167991327219943131946744088941348424456729187245615225, 8467783976897375037636665426419232997456360183332998866888776438963891641752}, {3215551885474507458266292022538992596230437910109015106438584379300426977039, 37306322622624672463065915763956225690223522454760918147434180740861300687668}, {947390502650680957920869582008711724723808429374401610775941200653824958689, 86236473645369998874832829444512637388615157303166534859982939866800801290421}, {4142520438525914541011842624208056062406705649998025173845082041682105009068, 87900869236804138087371702825961176259461360124819616238035200569139627100447}, {35976083938318534650029463496695503152893117754555618189020557340809841204638, 91581555597957928166775283241751618539413557986610388037330404183144654090313}, {92099574356616060718641758322300714450252979003106256663913657963750974558615, 44679714547892089078501304545394627678115758391255360766903436677955303545885}, {102652556215175073222018368450968179239643399116479030486157396231787228507330, 14437232828413691012043572600308410207374052858180415647749396463091843383375}, {60526872670786283833918632266282189958727983389364017821054603492994282170193, 14027692582691445211169305233477544073839133566657605745596417381878123854178}, {48611368844139479430646292898246827799543615133757497943303942111011000011486, 94184599433492315644214590509977869566386224898957355163260253699332858500095}, {29436743060920481988952312356424937775284815172144744489261980482023293444299, 90938483595262914582675074472013558936350058640531727255070751800362248713128}, {94976567038575040138507300949054306311784168683241399150467020165872178418684, 65079320657075459505472718093134166223214459592164919156492801936293394346061}, {115415846104970316816674669646231381722554829723945808246505339409944432478334, 33126753624353590316677983729603901933376151587979623867133648552767197976839}, {18776033471282089014310671094577787458033563645391456854929614351132929947887, 75132272094628034345708172112257475055149432967843434987053037295066962960968}, {11832388558031419782808688022015883762691763226078981998965787321613871498267, 38657913077255361434444622743436849344919651203626641239625924177481274928933}, {5674256344222473770316337151722717121901524681814366176584467328211802271911, 6241280037293053435562565229917129205739093461742926377996529691184676112606}, {59026356685222097294628395983368866596266777678130656463811370893799945855553, 89585527340406565500019872698075135548357340032819778309253570440118818477036}, {82997769624973021721207329827925752179285999209160244580518381248798973329757, 34120506380485136088917855908736915544289626703143468135554854919091047095237}, {32833730202948453445551585602227016221189718115335492475756041315423310145004, 53428498708335298930383652178427276342268514807561120763391253036328211515369}, {105475728434031409379183406694662903881450546214247029555786593600199689335290, 113583883859274030372082034862029605514506016193810719839027086029553530647303}, {106135013536326263233204638779771538367307463662639765758785315935371743257267, 86028625094535483850261571256264386723357163272666519397289099603747119225149}, {26622173145108500381473837459513401868318671376325266944487505521378511663272, 25015334278771650323507319424566501275290669267697587988960111333611631525338}, {8421370599800668602652103103676786751239058426611888163586601660098353727225, 29567823868173186762768009528067406508648153893486721194867955006028793890909}, {43457843735276724612075728233726406612249501219998543099634755887188281768154, 63192765102271790090487849294643355539231117908172846139915612801187217034173}, {103417404801342136514940355813672218236352240817568397971691640510748940358223, 35110031909328754691401904954608234218729030798549406331812068095064570237972}, {114612401220431600857626100267884543594407662822495910668441731424729600844475, 104607607047518035749515575138521003921603783202160061984102438399564594284817}, {13990119276603863648855793891913240987255865021321113597676024132284912134507, 45762644100243963560173177200312509818364497605040202142354576105708649526139}, {92297683643826826163064140665368589970769892635084083631213834209281061470421, 112881168890164609406380094011411584051648553985034449899770310954622772391910}, {13922864845768229163833387034770518418928910654248512738626529054912919158553, 79126321700797654134629819022700262425734361986906066326971931873703874776829}, {41570227333295029806389479208245314517359112018029925112212608294602008426980, 23045309029356249714220314716068128691355103924384360360907873576255068618171}, {40228630408040464220910435747595136926324159053542900046172368281189438159800, 57003788001796941708539841608272678584351968322832676412429854825222401371502}, {80048584874349841980004729440562797202284935506199377684670339908062345334316, 33429049751972530035656964727545283238705649483087953982909059058238089924020}, {9234367843203278475460402406049705063687486936070061072085337642077459464894, 81007956585093945832919421410562969694439825683280800865606243366544248926160}, {39490693885239044366982942241753219569930195973938085206409539076747633253548, 4398739609727183326946131652218256147146051104900180052629746226509188319237}, {95822289762910972444474447423403522943496613059597976864337566726465943856851, 64164296153307859244227616480023302862568188165333043899999315127086687727186}, {80360436639024982802108928438318908385607328476345612824787216050095821450571, 57369573270620142518340730615920379521637759094789396191309454253793769270353}, {113220891681512744492539364929916345410061947313878915456447722256969001660153, 48632069096637554924274413793295750001160491151445521927536133070043743201297}, {45044543832417204813964322358265561912289006474729602217500750943638473625672, 26879011462743840335691591457228606967066124790316477921535328699756712074744}, {40815729452528180238295637155137130875534812174241845066103240363483841899109, 62963488700699789032569184806979115722324448122457023739501893021766746537757}, {42019196137391938823787938398084615301261359872699590349124401997914530858192, 34767682558797648670566810324631233163266973542786319846918260332343694917893}, {98656114654415212951351030182220503262040501999861380370740706389056647757506, 58503766529248989798675151322237530184126490579454294759021188248409021626097}, {70779672864013442204047147619761736872402708735011963696772144922503503135593, 66095546131926016776182664572158682372222134031052577075352350981138964190485}, {7147807088254754984115277020319280513928719273510749291220264632533393132003, 48870560607183744840505722498698757682142671336868405907998491847376392333741}, {51318518135047612923054807776796525309348753908885584948123548636564953982193, 30623581788749822100382745859868645699047673268215141926580384967860112471253}, {76388770101766026847299654420802367216385774412973782315160485495908694642195, 57710893937692665357647691724236515472507145065106377254221657836468024167436}, {91718707606862637550154068541437645781425587687664226689694763206157559813025, 112096003213917921965697623480695740549761355267313232789540725477513634374998}, {104427496169569391842377213290478515885839261332812951511591855258537350660157, 61132381960602712033174130914468477784017762207402074270409666098181344508219}, {27276644428692416698688499014810854312801165379030850386665499374796427550985, 30749753566896120889917442069556393166141012006459550615871962942905620475626}, {10534520053980272543867405036685817400667875723664235737120499452559222196604, 92628477256112478580738935680261058160861780653699013741020467863885755120243}, {14881952017843508107868018207655541299293805975448542164953269149202864001651, 95744524462485084732056560754575516048250645981636693364989777482955901810067}, {64250787150254837153343438979016395164129717520259441534727718215719657633396, 2226821049909366001426284673098873826917960544595316002560147822639123525016}, {112052232026769664929658561660710941635228959956787050473536200851071191032897, 66850838866234897399334488953202946314182773756688684015551691304105443157422}, {67655380319953589260148826173219524241109847135242745518793369102772071675834, 21029601506232444319368385136955684033497833311867654114423309422350207087357}, {92240156060407253479030676529662381214111644319002643127826873158938047083835, 111327482796856645338109375925255091131664696057056686983936700507225403719493}, {78627750631242170634484650157951616270326041285698762428910452596338546905565, 105735616450588913958761248879135978906628726313788624529292917321934778581901}, {37970007016072384636196615568949856628931570059897898485017028997234414061945, 85633666146296869475846120618182213756296576205663668204532591586342323566242}, {95279397291673716158331856496563878128970306290864555825308960160147858174289, 105017020600749110255205601310325343926653803681868124843703017010103026488325}, {84556908620397086490574354609607180077068693777212695160113645418094198446687, 100718452597198377694892433543251040205084258311006913553384445818907946819791}, {112030421148703629201942613873270492163488999678896447559274774208446269765955, 35384723941339661147011733585239808738288755024824978650787507425153094271729}, {101186060051338727518238790300531351495613041202762303390359395316390096421977, 70018069425595998018260816426652965226827561219175179343976674369210843266462}, {45387637969275774150653095889876699672169323470095019346305801601969322188915, 98434237446496148394183890050136756428510322717221929962654009239641273623945}, {83407264292599769979907512419974269146592549057292719108468866098684905146381, 11344377696059311412860255181221495902312688613306488893294163454119121825704}, {106823080507094536302171587221364767641207071699356594725100487456618775186796, 92690132246900151323277569114758090527006018018792578401159597199495559705760}, {51458812640674469987191057145664724195213971571581134911909867396919133773071, 8629245570289361512928824496793066884814249866400051283675066385256088984418}, {59934529777540515900169509345926368831906655562972450327405481276732036473944, 25750881830896011524081627616138971820801200943932001974011760182257795007870}, {67920502080269633306026372339646975598405744544879176039587252097767227126036, 86511203683128773200503204915391168752553058701578039004115361443541322212241}, {82877690455795689589323624744144337630277711329294127826630078132465967983811, 39922059842557940073913288636103872861952687103330770522978967679436902620067}, {107647080929067738343525460704633213843414790178366076706967300283813568943072, 107835997232065897977399831129863752621211712639335526979670771458251622188461}, {8718136510001795340016406650816398436241492966773881626425334457414292825707, 47828698862917730813607230394980222348159325738755616817276492989172802309159}, {106401248484515799960476859862399114279959120497224302323517862298350223656110, 90554055872943285359562789441845937705225388396376669909302342738611517756544}, {85914087585702408016005337307470673574025858586827994345031653897824524412368, 29212277550782883303312106838911213847133545583225907622635973696278860332923}, {47276261486337148374827016504378500997420604221918318826137905934201132672881, 54113652565211585717578927649047183887090734340027236246806164434159486622390}, {85166652415091435001797631336388904339331836647982294920464378555175360787302, 5983439944161437184729068253379966091033304045142912300433002697874386924481}, {98723003287129746819861849635856388307092482938644489660108201582085516618521, 103397407405374187698982141346926700394890519747915912573020442958629189307492}, {1410924839106319455438998906475131322254088508411264224845861103682022500650, 78473624517617731927860216277549078632861074607574001991821266037345967105658}, {76680320804797823168246424599385182501909051371397652720933062691171176057014, 94762424439059506170177300542547484894285259654945103834474381188217886845725}, {63395642421589016740518975608504846303065672135176650115036476193363423546538, 29236048674093813394523910922582374630829081423043497254162533033164154049666}, {77392770812506936202877798844009338869624245327085260572871517211271361583330, 9026183085953335931861042123363330152002153911485343327487109499224702177627}, {16914017336104237881775315886787930831164045006039241266138286261112962921466, 62804288124927804794141542013461961167839995408257184926209413592463329006125}, {115448225011842706572960659933294318341945799523635471708109888288281266225256, 8682685012247630765815268889801361118442695513083738308010936359908165836919}, {4032983015753143990395647783770666587927265353624430905763286836981504199392, 44353125519324157186344456159742269880631179110473143840214086765587351124293}, {87917229428110789366561422587307072970088695150214603900351294636804298290738, 37579621872809717799779570009674914438024800886176540314162770583770981830863}, {19277281477197177963613685635111727513957886411799201238917757645493897712993, 847959926674921704613916930352312808004252888284294958523157455244708242291}, {80609861913912564376813326121470687649554127203741395941834419933864230904708, 114172617133077519546499241751011876596863476376685168252563264143225481955342}];
static function modReduce(int k, int modulus) : int {
int res = k % modulus;
return (res < 0) ? res + modulus : res;
}
static function modInverseEGCD(int x, int n) : int {
// The following script already does modular reduction at the start so there's no
// need to normalize x before function call.
asm {
OP_2DUP OP_MOD OP_DUP OP_0 OP_LESSTHAN OP_IF OP_DUP OP_2 OP_PICK OP_ADD OP_ELSE OP_DUP OP_ENDIF OP_NIP OP_2 OP_ROLL OP_DROP
OP_DUP OP_TOALTSTACK OP_TOALTSTACK OP_TOALTSTACK
OP_1 OP_0 OP_1
loop(UB) {
OP_FROMALTSTACK OP_FROMALTSTACK OP_2DUP OP_DUP OP_IF OP_TUCK OP_MOD OP_TOALTSTACK OP_TOALTSTACK OP_DIV OP_MUL OP_SUB OP_TUCK OP_ELSE OP_TOALTSTACK OP_TOALTSTACK OP_DROP OP_DROP OP_ENDIF
}
OP_FROMALTSTACK OP_FROMALTSTACK OP_DROP OP_DROP OP_DROP OP_FROMALTSTACK OP_SWAP OP_NIP
}
}
static function modInverseBranchlessP(int x) : int {
// Implementation of branchless modular inverse script over the curves p-value.
// Script generator used: https://gist.github.com/msinkec/b7a265ca5f5f26078e7ab154b19512ef
asm {
2ffcfffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff00 OP_SWAP OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_NIP
}
}
static function modInverseBranchlessN(int x) : int {
// Like modInverseBranchlessP but over the value of the curve order (n).
asm {
414136d08c5ed2bf3ba048afe6dcaebafeffffffffffffffffffffffffffffff00 OP_SWAP OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_DUP OP_TOALTSTACK OP_DUP OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_FROMALTSTACK OP_MUL OP_OVER OP_MOD OP_NIP
}
}
static function negatePoint(Point p) : Point {
Point res = {p.x, modReduce(p.y * -1, P)};
return res;
}
static function doublePoint(Point p) : Point {
int lambda = (3 * p.x * p.x) * modInverseBranchlessP(2 * p.y);
int rx = modReduce(lambda * lambda - 2 * p.x, P);
int ry = modReduce(lambda * (p.x - rx) - p.y, P);
Point res = {rx, ry};
return res;
}
static function addPoints(Point p, Point q) : Point {
Point ret = {0, 0};
if (p.x == 0 && p.y == 0) {
// if P == inf -> P + Q = Q
ret = q;
} else if (q.x == 0 && q.y == 0) {
// if Q == inf -> P + Q = P
ret = p;
} else {
int N = 0;
int D = 0;
if (p.x == q.x && p.y == q.y) {
// P == Q
N = 3 * p.x * p.x + a;
D = 2 * p.y;
} else {
N = q.y - p.y;
D = q.x - p.x;
}
int lambda = modReduce(N * modInverseBranchlessP(D), P);
int rx = modReduce(lambda * lambda - p.x - q.x, P);
int ry = modReduce(lambda * (p.x - rx) - p.y, P);
ret = {rx, ry};
}
return ret;
}
static function multByScalar(Point p, int m) : Point {
// Double and add method.
// Lowest bit to highest.
Point q = {0, 0};
bytes mb = reverseBytes(num2bin(m, S), S);
bytes mask = reverseBytes(num2bin(1, S), S);
bytes zero = reverseBytes(num2bin(0, S), S);
loop (CURVE_BITS) : i {
if ((mb & (mask << i)) != zero) {
q = addPoints(q, p);
}
p = doublePoint(p);
}
return q;
}
static function multGeneratorByScalar(int m) : Point {
// Fixed-point scalar multiplication for the curve generator point.
Point q = {0, 0};
bytes mb = reverseBytes(num2bin(m, S), S);
bytes mask = reverseBytes(num2bin(1, S), S);
bytes zero = reverseBytes(num2bin(0, S), S);
loop (CURVE_BITS) : i {
if ((mb & (mask << i)) != zero) {
q = addPoints(q, DOUBLINGS_G[i]);
}
}
return q;
}
static function verifySig(bytes m, Signature sig, Point pubKey) : bool {
// Hash message.
Sha256 hash = hash256(m);
int hashInt = unpack(reverseBytes(hash, 32) + b'00');
require(sig.r >= 1 && sig.r < n && sig.s >= 1 && sig.s < n);
int sInv = modInverseBranchlessN(sig.s);
int u1 = modReduce(hashInt * sInv, n);
int u2 = modReduce(sig.r * sInv, n);
Point U1 = multGeneratorByScalar(u1);
Point U2 = multByScalar(pubKey, u2);
Point X = addPoints(U1, U2);
return sig.r == X.x;
}
static function point2PubKey(Point point) : PubKey {
// Convert a point to a uncompressed public key.
return PubKey(b'04' + toBEUnsigned(point.x, 32) + toBEUnsigned(point.y, 32));
}
static function toBEUnsigned(int n, static const int l) : bytes {
// Convert signed integer `n` to unsigned integer of `l` bytes, in big endian.
bytes m = Utils.toLEUnsigned(n, l);
return reverseBytes(m,l);
}
}