sp_c64.c 1.7 MB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901349023490334904349053490634907349083490934910349113491234913349143491534916349173491834919349203492134922349233492434925349263492734928349293493034931349323493334934349353493634937349383493934940349413494234943349443494534946349473494834949349503495134952349533495434955349563495734958349593496034961349623496334964349653496634967349683496934970349713497234973349743497534976349773497834979349803498134982349833498434985349863498734988349893499034991349923499334994349953499634997349983499935000350013500235003350043500535006350073500835009350103501135012350133501435015350163501735018350193502035021350223502335024350253502635027350283502935030350313503235033350343503535036350373503835039350403504135042350433504435045350463504735048350493505035051350523505335054350553505635057350583505935060350613506235063350643506535066350673506835069350703507135072350733507435075350763507735078350793508035081350823508335084350853508635087350883508935090350913509235093350943509535096350973509835099351003510135102351033510435105351063510735108351093511035111351123511335114351153511635117351183511935120351213512235123351243512535126351273512835129351303513135132351333513435135351363513735138351393514035141351423514335144351453514635147351483514935150351513515235153351543515535156351573515835159351603516135162351633516435165351663516735168351693517035171351723517335174351753517635177351783517935180351813518235183351843518535186351873518835189351903519135192351933519435195351963519735198351993520035201352023520335204352053520635207352083520935210352113521235213352143521535216352173521835219352203522135222352233522435225352263522735228352293523035231352323523335234352353523635237352383523935240352413524235243352443524535246352473524835249352503525135252352533525435255352563525735258352593526035261352623526335264352653526635267352683526935270352713527235273352743527535276352773527835279352803528135282352833528435285352863528735288352893529035291352923529335294352953529635297352983529935300353013530235303353043530535306353073530835309353103531135312353133531435315353163531735318353193532035321353223532335324353253532635327353283532935330353313533235333353343533535336353373533835339353403534135342353433534435345353463534735348353493535035351353523535335354353553535635357353583535935360353613536235363353643536535366353673536835369353703537135372353733537435375353763537735378353793538035381353823538335384353853538635387353883538935390353913539235393353943539535396353973539835399354003540135402354033540435405354063540735408354093541035411354123541335414354153541635417354183541935420354213542235423354243542535426354273542835429354303543135432354333543435435354363543735438354393544035441354423544335444354453544635447354483544935450354513545235453354543545535456354573545835459354603546135462354633546435465354663546735468354693547035471354723547335474354753547635477354783547935480354813548235483354843548535486354873548835489354903549135492354933549435495354963549735498354993550035501355023550335504355053550635507355083550935510355113551235513355143551535516355173551835519355203552135522355233552435525355263552735528355293553035531355323553335534355353553635537355383553935540355413554235543355443554535546355473554835549355503555135552355533555435555355563555735558355593556035561355623556335564355653556635567355683556935570355713557235573355743557535576355773557835579355803558135582355833558435585355863558735588355893559035591355923559335594355953559635597355983559935600356013560235603356043560535606356073560835609356103561135612356133561435615356163561735618356193562035621356223562335624356253562635627356283562935630356313563235633356343563535636356373563835639356403564135642356433564435645356463564735648356493565035651356523565335654356553565635657356583565935660356613566235663356643566535666356673566835669356703567135672356733567435675356763567735678356793568035681356823568335684356853568635687356883568935690356913569235693356943569535696356973569835699357003570135702357033570435705357063570735708357093571035711357123571335714357153571635717357183571935720357213572235723357243572535726357273572835729357303573135732357333573435735357363573735738357393574035741357423574335744357453574635747357483574935750357513575235753357543575535756357573575835759357603576135762357633576435765357663576735768357693577035771357723577335774357753577635777357783577935780357813578235783357843578535786357873578835789357903579135792357933579435795357963579735798357993580035801358023580335804358053580635807358083580935810358113581235813358143581535816358173581835819358203582135822358233582435825358263582735828358293583035831358323583335834358353583635837358383583935840358413584235843358443584535846358473584835849358503585135852358533585435855358563585735858358593586035861358623586335864358653586635867358683586935870358713587235873358743587535876358773587835879358803588135882358833588435885358863588735888358893589035891358923589335894358953589635897358983589935900359013590235903359043590535906359073590835909359103591135912359133591435915359163591735918359193592035921359223592335924359253592635927359283592935930359313593235933359343593535936359373593835939359403594135942359433594435945359463594735948359493595035951359523595335954359553595635957359583595935960359613596235963359643596535966359673596835969359703597135972359733597435975359763597735978359793598035981359823598335984359853598635987359883598935990359913599235993359943599535996359973599835999360003600136002360033600436005360063600736008360093601036011360123601336014360153601636017360183601936020360213602236023360243602536026360273602836029360303603136032360333603436035360363603736038360393604036041360423604336044360453604636047360483604936050360513605236053360543605536056360573605836059360603606136062360633606436065360663606736068360693607036071360723607336074360753607636077360783607936080360813608236083360843608536086360873608836089360903609136092360933609436095360963609736098360993610036101361023610336104361053610636107361083610936110361113611236113361143611536116361173611836119361203612136122361233612436125361263612736128361293613036131361323613336134361353613636137361383613936140361413614236143361443614536146361473614836149361503615136152361533615436155361563615736158361593616036161361623616336164361653616636167361683616936170361713617236173361743617536176361773617836179361803618136182361833618436185361863618736188361893619036191361923619336194361953619636197361983619936200362013620236203362043620536206362073620836209362103621136212362133621436215362163621736218362193622036221362223622336224362253622636227362283622936230362313623236233362343623536236362373623836239362403624136242362433624436245362463624736248362493625036251362523625336254362553625636257362583625936260362613626236263362643626536266362673626836269362703627136272362733627436275362763627736278362793628036281362823628336284362853628636287362883628936290362913629236293362943629536296362973629836299363003630136302363033630436305363063630736308363093631036311363123631336314363153631636317363183631936320363213632236323363243632536326363273632836329363303633136332363333633436335363363633736338363393634036341363423634336344363453634636347363483634936350363513635236353363543635536356363573635836359363603636136362363633636436365363663636736368363693637036371363723637336374363753637636377363783637936380363813638236383363843638536386363873638836389363903639136392363933639436395363963639736398363993640036401364023640336404364053640636407364083640936410364113641236413364143641536416364173641836419364203642136422364233642436425364263642736428364293643036431364323643336434364353643636437364383643936440364413644236443364443644536446364473644836449364503645136452364533645436455364563645736458364593646036461364623646336464364653646636467364683646936470364713647236473364743647536476364773647836479364803648136482364833648436485364863648736488364893649036491364923649336494364953649636497364983649936500365013650236503365043650536506365073650836509365103651136512365133651436515365163651736518365193652036521365223652336524365253652636527365283652936530365313653236533365343653536536365373653836539365403654136542365433654436545365463654736548365493655036551365523655336554365553655636557365583655936560365613656236563365643656536566365673656836569365703657136572365733657436575365763657736578365793658036581365823658336584365853658636587365883658936590365913659236593365943659536596365973659836599366003660136602366033660436605366063660736608366093661036611366123661336614366153661636617366183661936620366213662236623366243662536626366273662836629366303663136632366333663436635366363663736638366393664036641366423664336644366453664636647366483664936650366513665236653366543665536656366573665836659366603666136662366633666436665366663666736668366693667036671366723667336674366753667636677366783667936680366813668236683366843668536686366873668836689366903669136692366933669436695366963669736698366993670036701367023670336704367053670636707367083670936710367113671236713367143671536716367173671836719367203672136722367233672436725367263672736728367293673036731367323673336734367353673636737367383673936740367413674236743367443674536746367473674836749367503675136752367533675436755367563675736758367593676036761367623676336764367653676636767367683676936770367713677236773367743677536776367773677836779367803678136782367833678436785367863678736788367893679036791367923679336794367953679636797367983679936800368013680236803368043680536806368073680836809368103681136812368133681436815368163681736818368193682036821368223682336824368253682636827368283682936830368313683236833368343683536836368373683836839368403684136842368433684436845368463684736848368493685036851368523685336854368553685636857368583685936860368613686236863368643686536866368673686836869368703687136872368733687436875368763687736878368793688036881368823688336884368853688636887368883688936890368913689236893368943689536896368973689836899369003690136902369033690436905369063690736908369093691036911369123691336914369153691636917369183691936920369213692236923369243692536926369273692836929369303693136932369333693436935369363693736938369393694036941369423694336944369453694636947369483694936950369513695236953369543695536956369573695836959369603696136962369633696436965369663696736968369693697036971369723697336974369753697636977369783697936980369813698236983369843698536986369873698836989369903699136992369933699436995369963699736998369993700037001370023700337004370053700637007370083700937010370113701237013370143701537016370173701837019370203702137022370233702437025370263702737028370293703037031370323703337034370353703637037370383703937040370413704237043370443704537046370473704837049370503705137052370533705437055370563705737058370593706037061370623706337064370653706637067370683706937070370713707237073370743707537076370773707837079370803708137082370833708437085370863708737088370893709037091370923709337094370953709637097370983709937100371013710237103371043710537106371073710837109371103711137112371133711437115371163711737118371193712037121371223712337124371253712637127371283712937130371313713237133371343713537136371373713837139371403714137142371433714437145371463714737148371493715037151371523715337154371553715637157371583715937160371613716237163371643716537166371673716837169371703717137172371733717437175371763717737178371793718037181371823718337184371853718637187371883718937190371913719237193371943719537196371973719837199372003720137202372033720437205372063720737208372093721037211372123721337214372153721637217372183721937220372213722237223372243722537226372273722837229372303723137232372333723437235372363723737238372393724037241372423724337244372453724637247372483724937250372513725237253372543725537256372573725837259372603726137262372633726437265372663726737268372693727037271372723727337274372753727637277372783727937280372813728237283372843728537286372873728837289372903729137292372933729437295372963729737298372993730037301373023730337304373053730637307373083730937310373113731237313373143731537316373173731837319373203732137322373233732437325373263732737328373293733037331373323733337334373353733637337373383733937340373413734237343373443734537346373473734837349373503735137352373533735437355373563735737358373593736037361373623736337364373653736637367373683736937370373713737237373373743737537376373773737837379373803738137382373833738437385373863738737388373893739037391373923739337394373953739637397373983739937400374013740237403374043740537406374073740837409374103741137412374133741437415374163741737418374193742037421374223742337424374253742637427374283742937430374313743237433374343743537436374373743837439374403744137442374433744437445374463744737448374493745037451374523745337454374553745637457374583745937460374613746237463374643746537466374673746837469374703747137472374733747437475374763747737478374793748037481374823748337484374853748637487374883748937490374913749237493374943749537496374973749837499375003750137502375033750437505375063750737508375093751037511375123751337514375153751637517375183751937520375213752237523375243752537526375273752837529375303753137532375333753437535375363753737538375393754037541375423754337544375453754637547375483754937550375513755237553375543755537556375573755837559375603756137562375633756437565375663756737568375693757037571375723757337574375753757637577375783757937580375813758237583375843758537586375873758837589375903759137592375933759437595375963759737598375993760037601376023760337604376053760637607376083760937610376113761237613376143761537616376173761837619376203762137622376233762437625376263762737628376293763037631376323763337634376353763637637376383763937640376413764237643376443764537646376473764837649376503765137652376533765437655376563765737658376593766037661376623766337664376653766637667376683766937670376713767237673376743767537676376773767837679376803768137682376833768437685376863768737688376893769037691376923769337694376953769637697376983769937700377013770237703377043770537706377073770837709377103771137712377133771437715377163771737718377193772037721377223772337724377253772637727377283772937730377313773237733377343773537736377373773837739377403774137742377433774437745377463774737748377493775037751377523775337754377553775637757377583775937760377613776237763377643776537766377673776837769377703777137772377733777437775377763777737778377793778037781377823778337784377853778637787377883778937790377913779237793377943779537796377973779837799378003780137802378033780437805378063780737808378093781037811378123781337814378153781637817378183781937820378213782237823378243782537826378273782837829378303783137832378333783437835378363783737838378393784037841378423784337844378453784637847378483784937850378513785237853378543785537856378573785837859378603786137862378633786437865378663786737868378693787037871378723787337874378753787637877378783787937880378813788237883378843788537886378873788837889378903789137892378933789437895378963789737898378993790037901379023790337904379053790637907379083790937910379113791237913379143791537916379173791837919379203792137922379233792437925379263792737928379293793037931379323793337934379353793637937379383793937940379413794237943379443794537946379473794837949379503795137952379533795437955379563795737958379593796037961379623796337964379653796637967379683796937970379713797237973379743797537976379773797837979379803798137982379833798437985379863798737988379893799037991379923799337994379953799637997379983799938000380013800238003380043800538006380073800838009380103801138012380133801438015380163801738018380193802038021380223802338024380253802638027380283802938030380313803238033380343803538036380373803838039380403804138042380433804438045380463804738048380493805038051380523805338054380553805638057380583805938060380613806238063380643806538066380673806838069380703807138072380733807438075380763807738078380793808038081380823808338084380853808638087380883808938090380913809238093380943809538096380973809838099381003810138102381033810438105381063810738108381093811038111381123811338114381153811638117381183811938120381213812238123381243812538126381273812838129381303813138132381333813438135381363813738138381393814038141381423814338144381453814638147381483814938150381513815238153381543815538156381573815838159381603816138162381633816438165381663816738168381693817038171381723817338174381753817638177381783817938180381813818238183381843818538186381873818838189381903819138192381933819438195381963819738198381993820038201382023820338204382053820638207382083820938210382113821238213382143821538216382173821838219382203822138222382233822438225382263822738228382293823038231382323823338234382353823638237382383823938240382413824238243382443824538246382473824838249382503825138252382533825438255382563825738258382593826038261382623826338264382653826638267382683826938270382713827238273382743827538276382773827838279382803828138282382833828438285382863828738288382893829038291382923829338294382953829638297382983829938300383013830238303383043830538306383073830838309383103831138312383133831438315383163831738318383193832038321383223832338324383253832638327383283832938330383313833238333383343833538336383373833838339383403834138342383433834438345383463834738348383493835038351383523835338354383553835638357383583835938360383613836238363383643836538366383673836838369383703837138372383733837438375383763837738378383793838038381383823838338384383853838638387383883838938390383913839238393383943839538396383973839838399384003840138402384033840438405384063840738408384093841038411384123841338414384153841638417384183841938420384213842238423384243842538426384273842838429384303843138432384333843438435384363843738438384393844038441384423844338444384453844638447384483844938450384513845238453384543845538456384573845838459384603846138462384633846438465384663846738468384693847038471384723847338474384753847638477384783847938480384813848238483384843848538486384873848838489384903849138492384933849438495384963849738498384993850038501385023850338504385053850638507385083850938510385113851238513385143851538516385173851838519385203852138522385233852438525385263852738528385293853038531385323853338534385353853638537385383853938540385413854238543385443854538546385473854838549385503855138552385533855438555385563855738558385593856038561385623856338564385653856638567385683856938570385713857238573385743857538576385773857838579385803858138582385833858438585385863858738588385893859038591385923859338594385953859638597385983859938600386013860238603386043860538606386073860838609386103861138612386133861438615386163861738618386193862038621386223862338624386253862638627386283862938630386313863238633386343863538636386373863838639386403864138642386433864438645386463864738648386493865038651386523865338654386553865638657386583865938660386613866238663386643866538666386673866838669386703867138672386733867438675386763867738678386793868038681386823868338684386853868638687386883868938690386913869238693386943869538696386973869838699387003870138702387033870438705387063870738708387093871038711387123871338714387153871638717387183871938720387213872238723387243872538726387273872838729387303873138732387333873438735387363873738738387393874038741387423874338744387453874638747387483874938750387513875238753387543875538756387573875838759387603876138762387633876438765387663876738768387693877038771387723877338774387753877638777387783877938780387813878238783387843878538786387873878838789387903879138792387933879438795387963879738798387993880038801388023880338804388053880638807388083880938810388113881238813388143881538816388173881838819388203882138822388233882438825388263882738828388293883038831388323883338834388353883638837388383883938840388413884238843388443884538846388473884838849388503885138852388533885438855388563885738858388593886038861388623886338864388653886638867388683886938870388713887238873388743887538876388773887838879388803888138882388833888438885388863888738888388893889038891388923889338894388953889638897388983889938900389013890238903389043890538906389073890838909389103891138912389133891438915389163891738918389193892038921389223892338924389253892638927389283892938930389313893238933389343893538936389373893838939389403894138942389433894438945389463894738948389493895038951389523895338954389553895638957389583895938960389613896238963389643896538966389673896838969389703897138972389733897438975389763897738978389793898038981389823898338984389853898638987389883898938990389913899238993389943899538996389973899838999390003900139002390033900439005390063900739008390093901039011390123901339014390153901639017390183901939020390213902239023390243902539026390273902839029390303903139032390333903439035390363903739038390393904039041390423904339044390453904639047390483904939050390513905239053390543905539056390573905839059390603906139062390633906439065390663906739068390693907039071390723907339074390753907639077390783907939080390813908239083390843908539086390873908839089390903909139092390933909439095390963909739098390993910039101391023910339104391053910639107391083910939110391113911239113391143911539116391173911839119391203912139122391233912439125391263912739128391293913039131391323913339134391353913639137391383913939140391413914239143391443914539146391473914839149391503915139152391533915439155391563915739158391593916039161391623916339164391653916639167391683916939170391713917239173391743917539176391773917839179391803918139182391833918439185391863918739188391893919039191391923919339194391953919639197391983919939200392013920239203392043920539206392073920839209392103921139212392133921439215392163921739218392193922039221392223922339224392253922639227392283922939230392313923239233392343923539236392373923839239392403924139242392433924439245392463924739248392493925039251392523925339254392553925639257392583925939260392613926239263392643926539266392673926839269392703927139272392733927439275392763927739278392793928039281392823928339284392853928639287392883928939290392913929239293392943929539296392973929839299393003930139302393033930439305393063930739308393093931039311393123931339314393153931639317393183931939320393213932239323393243932539326393273932839329393303933139332393333933439335393363933739338393393934039341393423934339344393453934639347393483934939350393513935239353393543935539356393573935839359393603936139362393633936439365393663936739368393693937039371393723937339374393753937639377393783937939380393813938239383393843938539386393873938839389393903939139392393933939439395393963939739398393993940039401394023940339404394053940639407394083940939410394113941239413394143941539416394173941839419394203942139422394233942439425394263942739428394293943039431394323943339434394353943639437394383943939440394413944239443394443944539446394473944839449394503945139452394533945439455394563945739458394593946039461394623946339464394653946639467394683946939470394713947239473394743947539476394773947839479394803948139482394833948439485394863948739488394893949039491394923949339494394953949639497394983949939500395013950239503395043950539506395073950839509395103951139512395133951439515395163951739518395193952039521395223952339524395253952639527395283952939530395313953239533395343953539536395373953839539395403954139542395433954439545395463954739548395493955039551395523955339554395553955639557395583955939560395613956239563395643956539566395673956839569395703957139572395733957439575395763957739578395793958039581395823958339584395853958639587395883958939590395913959239593395943959539596395973959839599396003960139602396033960439605396063960739608396093961039611396123961339614396153961639617396183961939620396213962239623396243962539626396273962839629396303963139632396333963439635396363963739638396393964039641396423964339644396453964639647396483964939650396513965239653396543965539656396573965839659396603966139662396633966439665396663966739668396693967039671396723967339674396753967639677396783967939680396813968239683396843968539686396873968839689396903969139692396933969439695396963969739698396993970039701397023970339704397053970639707397083970939710397113971239713397143971539716397173971839719397203972139722397233972439725397263972739728397293973039731397323973339734397353973639737397383973939740397413974239743397443974539746397473974839749397503975139752397533975439755397563975739758397593976039761397623976339764397653976639767397683976939770397713977239773397743977539776397773977839779397803978139782397833978439785397863978739788397893979039791397923979339794397953979639797397983979939800398013980239803398043980539806398073980839809398103981139812398133981439815398163981739818398193982039821398223982339824398253982639827398283982939830398313983239833398343983539836398373983839839398403984139842398433984439845398463984739848398493985039851398523985339854398553985639857398583985939860398613986239863398643986539866398673986839869398703987139872398733987439875398763987739878398793988039881398823988339884398853988639887398883988939890398913989239893398943989539896398973989839899399003990139902399033990439905399063990739908399093991039911399123991339914399153991639917399183991939920399213992239923399243992539926399273992839929399303993139932399333993439935399363993739938399393994039941399423994339944399453994639947399483994939950399513995239953399543995539956399573995839959399603996139962399633996439965399663996739968399693997039971399723997339974399753997639977399783997939980399813998239983399843998539986399873998839989399903999139992399933999439995399963999739998399994000040001400024000340004400054000640007400084000940010400114001240013400144001540016400174001840019400204002140022400234002440025400264002740028400294003040031400324003340034400354003640037400384003940040400414004240043400444004540046400474004840049400504005140052400534005440055400564005740058400594006040061400624006340064400654006640067400684006940070400714007240073400744007540076400774007840079400804008140082400834008440085400864008740088400894009040091400924009340094400954009640097400984009940100401014010240103401044010540106401074010840109401104011140112401134011440115401164011740118401194012040121401224012340124401254012640127401284012940130401314013240133401344013540136401374013840139401404014140142401434014440145401464014740148401494015040151401524015340154401554015640157401584015940160401614016240163401644016540166401674016840169401704017140172401734017440175401764017740178401794018040181401824018340184401854018640187401884018940190401914019240193401944019540196401974019840199402004020140202402034020440205402064020740208402094021040211402124021340214402154021640217402184021940220402214022240223402244022540226402274022840229402304023140232402334023440235402364023740238402394024040241402424024340244402454024640247402484024940250402514025240253402544025540256402574025840259402604026140262402634026440265402664026740268402694027040271402724027340274402754027640277402784027940280402814028240283402844028540286402874028840289402904029140292402934029440295402964029740298402994030040301403024030340304403054030640307403084030940310403114031240313403144031540316403174031840319403204032140322403234032440325403264032740328403294033040331403324033340334403354033640337403384033940340403414034240343403444034540346403474034840349403504035140352403534035440355403564035740358403594036040361403624036340364403654036640367403684036940370403714037240373403744037540376403774037840379403804038140382403834038440385403864038740388403894039040391403924039340394403954039640397403984039940400404014040240403404044040540406404074040840409404104041140412404134041440415404164041740418404194042040421404224042340424404254042640427404284042940430404314043240433404344043540436404374043840439404404044140442404434044440445404464044740448404494045040451404524045340454404554045640457404584045940460404614046240463404644046540466404674046840469404704047140472404734047440475404764047740478404794048040481404824048340484404854048640487404884048940490404914049240493404944049540496404974049840499405004050140502405034050440505405064050740508405094051040511405124051340514405154051640517405184051940520405214052240523405244052540526405274052840529405304053140532405334053440535405364053740538405394054040541405424054340544405454054640547405484054940550405514055240553405544055540556405574055840559405604056140562405634056440565405664056740568405694057040571405724057340574405754057640577405784057940580405814058240583405844058540586405874058840589405904059140592405934059440595405964059740598405994060040601406024060340604406054060640607406084060940610406114061240613406144061540616406174061840619406204062140622406234062440625406264062740628406294063040631406324063340634406354063640637406384063940640406414064240643406444064540646406474064840649406504065140652406534065440655406564065740658406594066040661406624066340664406654066640667406684066940670406714067240673406744067540676406774067840679406804068140682406834068440685406864068740688406894069040691406924069340694406954069640697406984069940700407014070240703407044070540706407074070840709407104071140712407134071440715407164071740718407194072040721407224072340724407254072640727407284072940730407314073240733407344073540736407374073840739407404074140742407434074440745407464074740748407494075040751407524075340754407554075640757407584075940760407614076240763407644076540766407674076840769407704077140772407734077440775407764077740778407794078040781407824078340784407854078640787407884078940790407914079240793407944079540796407974079840799408004080140802408034080440805408064080740808408094081040811408124081340814408154081640817408184081940820408214082240823408244082540826408274082840829408304083140832408334083440835408364083740838408394084040841408424084340844408454084640847408484084940850408514085240853408544085540856408574085840859408604086140862408634086440865408664086740868408694087040871408724087340874408754087640877408784087940880408814088240883408844088540886408874088840889408904089140892408934089440895408964089740898408994090040901409024090340904409054090640907409084090940910409114091240913409144091540916409174091840919409204092140922409234092440925409264092740928409294093040931409324093340934409354093640937409384093940940409414094240943409444094540946409474094840949409504095140952409534095440955409564095740958409594096040961409624096340964409654096640967409684096940970409714097240973409744097540976409774097840979409804098140982409834098440985409864098740988409894099040991409924099340994409954099640997409984099941000410014100241003410044100541006410074100841009410104101141012410134101441015410164101741018410194102041021410224102341024410254102641027410284102941030410314103241033410344103541036410374103841039410404104141042410434104441045410464104741048410494105041051410524105341054410554105641057410584105941060410614106241063410644106541066410674106841069410704107141072410734107441075410764107741078410794108041081410824108341084410854108641087410884108941090410914109241093410944109541096410974109841099411004110141102411034110441105411064110741108411094111041111411124111341114411154111641117411184111941120411214112241123411244112541126411274112841129411304113141132411334113441135411364113741138411394114041141411424114341144411454114641147411484114941150411514115241153411544115541156411574115841159411604116141162411634116441165411664116741168411694117041171411724117341174411754117641177411784117941180411814118241183411844118541186411874118841189411904119141192411934119441195411964119741198411994120041201412024120341204412054120641207412084120941210412114121241213412144121541216412174121841219412204122141222412234122441225412264122741228412294123041231412324123341234412354123641237412384123941240412414124241243412444124541246412474124841249412504125141252412534125441255412564125741258412594126041261412624126341264412654126641267412684126941270412714127241273412744127541276412774127841279412804128141282412834128441285412864128741288412894129041291412924129341294412954129641297412984129941300413014130241303413044130541306413074130841309413104131141312413134131441315413164131741318413194132041321413224132341324413254132641327413284132941330413314133241333413344133541336413374133841339413404134141342413434134441345413464134741348413494135041351413524135341354413554135641357413584135941360413614136241363413644136541366413674136841369413704137141372413734137441375413764137741378413794138041381413824138341384413854138641387413884138941390413914139241393413944139541396413974139841399414004140141402414034140441405414064140741408414094141041411414124141341414414154141641417414184141941420414214142241423414244142541426414274142841429414304143141432414334143441435414364143741438414394144041441414424144341444414454144641447414484144941450414514145241453414544145541456414574145841459414604146141462414634146441465414664146741468414694147041471414724147341474414754147641477414784147941480414814148241483414844148541486414874148841489414904149141492414934149441495414964149741498414994150041501415024150341504415054150641507415084150941510415114151241513415144151541516415174151841519415204152141522415234152441525415264152741528415294153041531415324153341534415354153641537415384153941540415414154241543415444154541546415474154841549415504155141552415534155441555415564155741558415594156041561415624156341564415654156641567415684156941570415714157241573415744157541576415774157841579415804158141582415834158441585415864158741588415894159041591415924159341594415954159641597415984159941600416014160241603416044160541606416074160841609416104161141612416134161441615416164161741618416194162041621416224162341624416254162641627416284162941630416314163241633416344163541636416374163841639416404164141642416434164441645416464164741648416494165041651416524165341654416554165641657416584165941660416614166241663416644166541666416674166841669416704167141672416734167441675416764167741678416794168041681416824168341684416854168641687416884168941690416914169241693416944169541696416974169841699417004170141702417034170441705417064170741708417094171041711417124171341714417154171641717417184171941720417214172241723417244172541726417274172841729417304173141732417334173441735417364173741738417394174041741417424174341744417454174641747417484174941750417514175241753417544175541756417574175841759417604176141762417634176441765417664176741768417694177041771417724177341774417754177641777417784177941780417814178241783417844178541786417874178841789417904179141792417934179441795417964179741798417994180041801418024180341804418054180641807418084180941810418114181241813418144181541816418174181841819418204182141822418234182441825418264182741828418294183041831418324183341834418354183641837418384183941840418414184241843418444184541846418474184841849418504185141852418534185441855418564185741858418594186041861418624186341864418654186641867418684186941870418714187241873418744187541876418774187841879418804188141882418834188441885418864188741888418894189041891418924189341894418954189641897418984189941900419014190241903419044190541906419074190841909419104191141912419134191441915419164191741918419194192041921419224192341924419254192641927419284192941930419314193241933419344193541936419374193841939419404194141942419434194441945419464194741948419494195041951419524195341954419554195641957419584195941960419614196241963419644196541966419674196841969419704197141972419734197441975419764197741978419794198041981419824198341984419854198641987419884198941990419914199241993419944199541996419974199841999420004200142002420034200442005420064200742008420094201042011420124201342014420154201642017420184201942020420214202242023420244202542026420274202842029420304203142032420334203442035420364203742038420394204042041420424204342044420454204642047420484204942050420514205242053420544205542056420574205842059420604206142062420634206442065420664206742068420694207042071420724207342074420754207642077420784207942080420814208242083420844208542086420874208842089420904209142092420934209442095420964209742098420994210042101421024210342104421054210642107421084210942110421114211242113421144211542116421174211842119421204212142122421234212442125421264212742128421294213042131421324213342134421354213642137421384213942140421414214242143421444214542146421474214842149421504215142152421534215442155421564215742158421594216042161421624216342164421654216642167421684216942170421714217242173421744217542176421774217842179421804218142182421834218442185421864218742188421894219042191421924219342194421954219642197421984219942200422014220242203422044220542206422074220842209422104221142212422134221442215422164221742218422194222042221422224222342224422254222642227422284222942230422314223242233422344223542236422374223842239422404224142242422434224442245422464224742248422494225042251422524225342254422554225642257422584225942260422614226242263422644226542266422674226842269422704227142272422734227442275422764227742278422794228042281422824228342284422854228642287422884228942290422914229242293422944229542296422974229842299423004230142302423034230442305423064230742308423094231042311423124231342314423154231642317423184231942320423214232242323423244232542326423274232842329423304233142332423334233442335423364233742338423394234042341423424234342344423454234642347423484234942350423514235242353423544235542356423574235842359423604236142362423634236442365423664236742368423694237042371423724237342374423754237642377423784237942380423814238242383423844238542386423874238842389423904239142392423934239442395423964239742398423994240042401424024240342404424054240642407424084240942410424114241242413424144241542416424174241842419424204242142422424234242442425424264242742428424294243042431424324243342434424354243642437424384243942440424414244242443424444244542446424474244842449424504245142452424534245442455424564245742458424594246042461424624246342464424654246642467424684246942470424714247242473424744247542476424774247842479424804248142482424834248442485424864248742488424894249042491424924249342494424954249642497424984249942500425014250242503425044250542506425074250842509425104251142512425134251442515425164251742518425194252042521425224252342524425254252642527425284252942530425314253242533425344253542536425374253842539425404254142542425434254442545425464254742548425494255042551425524255342554425554255642557425584255942560425614256242563425644256542566425674256842569425704257142572425734257442575425764257742578425794258042581425824258342584425854258642587425884258942590425914259242593425944259542596425974259842599426004260142602426034260442605426064260742608426094261042611426124261342614426154261642617426184261942620426214262242623426244262542626426274262842629426304263142632426334263442635426364263742638426394264042641426424264342644426454264642647426484264942650426514265242653426544265542656426574265842659426604266142662426634266442665426664266742668426694267042671426724267342674426754267642677426784267942680426814268242683426844268542686426874268842689426904269142692426934269442695426964269742698426994270042701427024270342704427054270642707427084270942710427114271242713427144271542716427174271842719427204272142722427234272442725427264272742728427294273042731427324273342734427354273642737427384273942740427414274242743427444274542746427474274842749427504275142752427534275442755427564275742758427594276042761427624276342764427654276642767427684276942770427714277242773427744277542776427774277842779427804278142782427834278442785427864278742788427894279042791427924279342794427954279642797427984279942800428014280242803428044280542806428074280842809428104281142812428134281442815428164281742818428194282042821428224282342824428254282642827428284282942830428314283242833428344283542836428374283842839428404284142842428434284442845428464284742848428494285042851428524285342854428554285642857428584285942860428614286242863428644286542866428674286842869428704287142872428734287442875428764287742878428794288042881428824288342884428854288642887428884288942890428914289242893428944289542896428974289842899429004290142902429034290442905429064290742908429094291042911429124291342914429154291642917429184291942920429214292242923429244292542926429274292842929429304293142932429334293442935429364293742938429394294042941429424294342944429454294642947429484294942950429514295242953429544295542956429574295842959429604296142962429634296442965429664296742968429694297042971429724297342974429754297642977429784297942980429814298242983429844298542986429874298842989429904299142992429934299442995429964299742998429994300043001430024300343004430054300643007430084300943010430114301243013430144301543016430174301843019430204302143022430234302443025430264302743028430294303043031430324303343034430354303643037430384303943040430414304243043430444304543046430474304843049430504305143052430534305443055430564305743058430594306043061430624306343064430654306643067430684306943070430714307243073430744307543076430774307843079430804308143082430834308443085430864308743088430894309043091430924309343094430954309643097430984309943100431014310243103431044310543106431074310843109431104311143112431134311443115431164311743118431194312043121431224312343124431254312643127431284312943130431314313243133431344313543136431374313843139431404314143142431434314443145431464314743148431494315043151431524315343154431554315643157431584315943160431614316243163431644316543166431674316843169431704317143172431734317443175431764317743178431794318043181431824318343184431854318643187431884318943190431914319243193431944319543196431974319843199432004320143202432034320443205432064320743208432094321043211432124321343214432154321643217432184321943220432214322243223432244322543226432274322843229432304323143232432334323443235432364323743238432394324043241432424324343244432454324643247432484324943250432514325243253432544325543256432574325843259432604326143262432634326443265432664326743268432694327043271432724327343274432754327643277432784327943280432814328243283432844328543286432874328843289432904329143292432934329443295432964329743298432994330043301433024330343304433054330643307433084330943310433114331243313433144331543316433174331843319433204332143322433234332443325433264332743328433294333043331433324333343334433354333643337433384333943340433414334243343433444334543346433474334843349433504335143352433534335443355433564335743358433594336043361433624336343364433654336643367433684336943370433714337243373433744337543376433774337843379433804338143382433834338443385433864338743388433894339043391433924339343394433954339643397433984339943400434014340243403434044340543406434074340843409434104341143412434134341443415434164341743418434194342043421434224342343424434254342643427434284342943430434314343243433434344343543436434374343843439434404344143442434434344443445434464344743448434494345043451434524345343454434554345643457434584345943460434614346243463434644346543466434674346843469434704347143472434734347443475434764347743478434794348043481434824348343484434854348643487434884348943490434914349243493434944349543496434974349843499435004350143502435034350443505435064350743508435094351043511435124351343514435154351643517435184351943520435214352243523435244352543526435274352843529435304353143532435334353443535435364353743538435394354043541435424354343544435454354643547435484354943550435514355243553435544355543556435574355843559435604356143562435634356443565435664356743568435694357043571435724357343574435754357643577435784357943580435814358243583435844358543586435874358843589435904359143592435934359443595435964359743598435994360043601436024360343604436054360643607436084360943610436114361243613436144361543616436174361843619436204362143622436234362443625436264362743628436294363043631436324363343634436354363643637436384363943640436414364243643436444364543646436474364843649436504365143652436534365443655436564365743658436594366043661436624366343664436654366643667436684366943670436714367243673436744367543676436774367843679436804368143682436834368443685436864368743688436894369043691436924369343694436954369643697436984369943700437014370243703437044370543706437074370843709437104371143712437134371443715437164371743718437194372043721437224372343724437254372643727437284372943730437314373243733437344373543736437374373843739437404374143742437434374443745437464374743748437494375043751437524375343754437554375643757437584375943760437614376243763437644376543766437674376843769437704377143772437734377443775437764377743778437794378043781437824378343784437854378643787437884378943790437914379243793437944379543796437974379843799438004380143802438034380443805438064380743808438094381043811438124381343814438154381643817438184381943820438214382243823438244382543826438274382843829438304383143832438334383443835438364383743838438394384043841438424384343844438454384643847438484384943850438514385243853438544385543856438574385843859438604386143862438634386443865438664386743868438694387043871438724387343874438754387643877438784387943880438814388243883438844388543886438874388843889438904389143892438934389443895438964389743898438994390043901439024390343904439054390643907439084390943910439114391243913439144391543916439174391843919439204392143922439234392443925439264392743928439294393043931439324393343934439354393643937439384393943940439414394243943439444394543946439474394843949439504395143952439534395443955439564395743958439594396043961439624396343964439654396643967439684396943970439714397243973439744397543976439774397843979439804398143982439834398443985439864398743988439894399043991439924399343994439954399643997439984399944000440014400244003440044400544006440074400844009440104401144012440134401444015440164401744018440194402044021440224402344024440254402644027440284402944030440314403244033440344403544036440374403844039440404404144042440434404444045440464404744048440494405044051440524405344054440554405644057440584405944060440614406244063440644406544066440674406844069440704407144072440734407444075440764407744078440794408044081440824408344084440854408644087440884408944090440914409244093440944409544096440974409844099441004410144102441034410444105441064410744108441094411044111441124411344114441154411644117441184411944120441214412244123441244412544126441274412844129441304413144132441334413444135441364413744138441394414044141441424414344144441454414644147441484414944150441514415244153441544415544156441574415844159441604416144162441634416444165441664416744168441694417044171441724417344174441754417644177441784417944180441814418244183441844418544186441874418844189441904419144192441934419444195441964419744198441994420044201442024420344204442054420644207442084420944210442114421244213442144421544216442174421844219442204422144222442234422444225442264422744228442294423044231442324423344234442354423644237442384423944240442414424244243442444424544246442474424844249442504425144252442534425444255442564425744258442594426044261442624426344264442654426644267442684426944270442714427244273442744427544276442774427844279442804428144282442834428444285442864428744288442894429044291442924429344294442954429644297442984429944300443014430244303443044430544306443074430844309443104431144312443134431444315443164431744318443194432044321443224432344324443254432644327443284432944330443314433244333443344433544336443374433844339443404434144342443434434444345443464434744348443494435044351443524435344354443554435644357443584435944360443614436244363443644436544366443674436844369443704437144372443734437444375443764437744378443794438044381443824438344384443854438644387443884438944390443914439244393443944439544396443974439844399444004440144402444034440444405444064440744408444094441044411444124441344414444154441644417444184441944420444214442244423444244442544426444274442844429444304443144432444334443444435444364443744438444394444044441444424444344444444454444644447444484444944450444514445244453444544445544456444574445844459444604446144462444634446444465444664446744468444694447044471444724447344474444754447644477444784447944480444814448244483444844448544486444874448844489444904449144492444934449444495444964449744498444994450044501445024450344504445054450644507445084450944510445114451244513445144451544516445174451844519445204452144522445234452444525445264452744528445294453044531445324453344534445354453644537445384453944540445414454244543445444454544546445474454844549445504455144552445534455444555445564455744558445594456044561445624456344564445654456644567445684456944570445714457244573445744457544576445774457844579445804458144582445834458444585445864458744588445894459044591445924459344594445954459644597445984459944600446014460244603446044460544606446074460844609446104461144612446134461444615446164461744618446194462044621446224462344624446254462644627446284462944630446314463244633446344463544636446374463844639446404464144642446434464444645446464464744648446494465044651446524465344654446554465644657446584465944660446614466244663446644466544666446674466844669446704467144672446734467444675446764467744678446794468044681446824468344684446854468644687446884468944690446914469244693446944469544696446974469844699447004470144702447034470444705447064470744708447094471044711447124471344714447154471644717447184471944720447214472244723447244472544726447274472844729447304473144732447334473444735447364473744738447394474044741447424474344744447454474644747447484474944750447514475244753447544475544756447574475844759447604476144762447634476444765447664476744768447694477044771447724477344774447754477644777447784477944780447814478244783447844478544786447874478844789447904479144792447934479444795447964479744798447994480044801448024480344804448054480644807448084480944810448114481244813448144481544816448174481844819448204482144822448234482444825448264482744828448294483044831448324483344834448354483644837448384483944840448414484244843448444484544846448474484844849448504485144852448534485444855448564485744858448594486044861448624486344864448654486644867448684486944870448714487244873448744487544876448774487844879448804488144882448834488444885448864488744888448894489044891448924489344894448954489644897448984489944900449014490244903449044490544906449074490844909449104491144912449134491444915449164491744918449194492044921449224492344924449254492644927449284492944930449314493244933449344493544936449374493844939449404494144942449434494444945449464494744948449494495044951449524495344954449554495644957449584495944960449614496244963449644496544966449674496844969449704497144972449734497444975449764497744978449794498044981449824498344984449854498644987449884498944990449914499244993449944499544996449974499844999450004500145002450034500445005450064500745008450094501045011450124501345014450154501645017450184501945020450214502245023450244502545026450274502845029450304503145032450334503445035450364503745038450394504045041450424504345044450454504645047450484504945050450514505245053450544505545056450574505845059450604506145062450634506445065450664506745068450694507045071450724507345074450754507645077450784507945080450814508245083450844508545086450874508845089450904509145092450934509445095450964509745098450994510045101451024510345104451054510645107451084510945110451114511245113451144511545116451174511845119451204512145122451234512445125451264512745128451294513045131451324513345134451354513645137451384513945140451414514245143451444514545146451474514845149451504515145152451534515445155451564515745158451594516045161451624516345164451654516645167451684516945170451714517245173451744517545176451774517845179451804518145182451834518445185451864518745188451894519045191451924519345194451954519645197451984519945200452014520245203452044520545206452074520845209452104521145212452134521445215452164521745218452194522045221452224522345224452254522645227452284522945230452314523245233452344523545236452374523845239452404524145242452434524445245452464524745248452494525045251452524525345254452554525645257452584525945260452614526245263452644526545266452674526845269452704527145272452734527445275452764527745278452794528045281452824528345284452854528645287452884528945290452914529245293452944529545296452974529845299453004530145302453034530445305453064530745308453094531045311453124531345314453154531645317453184531945320453214532245323453244532545326453274532845329453304533145332453334533445335453364533745338453394534045341453424534345344453454534645347453484534945350453514535245353453544535545356453574535845359453604536145362453634536445365453664536745368453694537045371453724537345374453754537645377453784537945380453814538245383453844538545386453874538845389453904539145392453934539445395453964539745398453994540045401454024540345404454054540645407454084540945410454114541245413454144541545416454174541845419454204542145422454234542445425454264542745428454294543045431454324543345434454354543645437454384543945440454414544245443454444544545446454474544845449454504545145452454534545445455454564545745458454594546045461454624546345464454654546645467454684546945470454714547245473454744547545476454774547845479454804548145482454834548445485454864548745488454894549045491454924549345494454954549645497454984549945500455014550245503455044550545506455074550845509455104551145512455134551445515455164551745518455194552045521455224552345524455254552645527455284552945530455314553245533455344553545536455374553845539455404554145542455434554445545455464554745548455494555045551455524555345554455554555645557455584555945560455614556245563455644556545566455674556845569455704557145572455734557445575455764557745578455794558045581455824558345584455854558645587455884558945590455914559245593455944559545596455974559845599456004560145602456034560445605456064560745608456094561045611456124561345614456154561645617456184561945620456214562245623456244562545626456274562845629456304563145632456334563445635456364563745638456394564045641456424564345644456454564645647456484564945650456514565245653456544565545656456574565845659456604566145662456634566445665456664566745668456694567045671456724567345674456754567645677456784567945680456814568245683456844568545686456874568845689456904569145692456934569445695456964569745698456994570045701457024570345704457054570645707457084570945710457114571245713457144571545716457174571845719457204572145722457234572445725457264572745728457294573045731457324573345734457354573645737457384573945740457414574245743457444574545746457474574845749457504575145752457534575445755457564575745758457594576045761457624576345764457654576645767457684576945770457714577245773457744577545776457774577845779457804578145782457834578445785457864578745788457894579045791457924579345794457954579645797457984579945800458014580245803458044580545806458074580845809458104581145812458134581445815458164581745818458194582045821458224582345824458254582645827458284582945830458314583245833458344583545836458374583845839458404584145842458434584445845458464584745848458494585045851458524585345854458554585645857458584585945860458614586245863458644586545866458674586845869458704587145872458734587445875458764587745878458794588045881458824588345884458854588645887458884588945890458914589245893458944589545896458974589845899459004590145902459034590445905459064590745908459094591045911459124591345914459154591645917459184591945920459214592245923459244592545926459274592845929459304593145932459334593445935459364593745938459394594045941459424594345944459454594645947459484594945950459514595245953459544595545956459574595845959459604596145962459634596445965459664596745968459694597045971459724597345974459754597645977459784597945980459814598245983459844598545986459874598845989459904599145992459934599445995459964599745998459994600046001460024600346004460054600646007460084600946010460114601246013460144601546016460174601846019460204602146022460234602446025460264602746028460294603046031460324603346034460354603646037460384603946040460414604246043460444604546046460474604846049460504605146052460534605446055460564605746058460594606046061460624606346064460654606646067460684606946070460714607246073460744607546076460774607846079460804608146082460834608446085460864608746088460894609046091460924609346094460954609646097460984609946100461014610246103461044610546106461074610846109461104611146112461134611446115461164611746118461194612046121461224612346124461254612646127461284612946130461314613246133461344613546136461374613846139461404614146142461434614446145461464614746148461494615046151461524615346154461554615646157461584615946160461614616246163461644616546166461674616846169461704617146172461734617446175461764617746178461794618046181461824618346184461854618646187461884618946190461914619246193461944619546196461974619846199462004620146202462034620446205462064620746208462094621046211462124621346214462154621646217462184621946220462214622246223462244622546226462274622846229462304623146232462334623446235462364623746238462394624046241462424624346244462454624646247462484624946250462514625246253462544625546256462574625846259462604626146262462634626446265462664626746268462694627046271462724627346274462754627646277462784627946280462814628246283462844628546286462874628846289462904629146292462934629446295462964629746298462994630046301463024630346304463054630646307463084630946310463114631246313463144631546316463174631846319463204632146322463234632446325463264632746328463294633046331463324633346334463354633646337463384633946340463414634246343463444634546346463474634846349463504635146352463534635446355463564635746358463594636046361463624636346364463654636646367463684636946370463714637246373463744637546376463774637846379463804638146382463834638446385463864638746388463894639046391463924639346394463954639646397463984639946400464014640246403464044640546406464074640846409464104641146412464134641446415464164641746418464194642046421464224642346424464254642646427464284642946430464314643246433464344643546436464374643846439464404644146442464434644446445464464644746448464494645046451464524645346454464554645646457464584645946460464614646246463464644646546466464674646846469464704647146472464734647446475464764647746478464794648046481464824648346484464854648646487464884648946490464914649246493464944649546496464974649846499465004650146502465034650446505465064650746508465094651046511465124651346514465154651646517465184651946520465214652246523465244652546526465274652846529465304653146532465334653446535465364653746538465394654046541465424654346544465454654646547465484654946550465514655246553465544655546556465574655846559465604656146562465634656446565465664656746568465694657046571465724657346574465754657646577465784657946580465814658246583465844658546586465874658846589465904659146592465934659446595465964659746598465994660046601466024660346604466054660646607466084660946610466114661246613466144661546616466174661846619466204662146622466234662446625466264662746628466294663046631466324663346634466354663646637466384663946640466414664246643466444664546646466474664846649466504665146652466534665446655466564665746658466594666046661466624666346664466654666646667466684666946670466714667246673466744667546676466774667846679466804668146682466834668446685466864668746688466894669046691466924669346694466954669646697466984669946700467014670246703467044670546706467074670846709467104671146712467134671446715467164671746718467194672046721467224672346724467254672646727467284672946730467314673246733467344673546736467374673846739467404674146742467434674446745467464674746748467494675046751467524675346754467554675646757467584675946760467614676246763467644676546766467674676846769467704677146772467734677446775467764677746778467794678046781467824678346784467854678646787467884678946790467914679246793467944679546796467974679846799468004680146802468034680446805468064680746808468094681046811468124681346814468154681646817468184681946820468214682246823468244682546826468274682846829468304683146832468334683446835468364683746838468394684046841468424684346844468454684646847468484684946850468514685246853468544685546856468574685846859468604686146862468634686446865468664686746868468694687046871468724687346874468754687646877468784687946880468814688246883468844688546886468874688846889468904689146892468934689446895468964689746898468994690046901469024690346904469054690646907469084690946910469114691246913469144691546916469174691846919469204692146922469234692446925469264692746928469294693046931469324693346934469354693646937469384693946940469414694246943469444694546946469474694846949469504695146952469534695446955469564695746958469594696046961469624696346964469654696646967469684696946970469714697246973469744697546976469774697846979469804698146982469834698446985469864698746988469894699046991469924699346994469954699646997469984699947000470014700247003470044700547006470074700847009470104701147012470134701447015470164701747018470194702047021470224702347024470254702647027470284702947030470314703247033470344703547036470374703847039470404704147042470434704447045470464704747048470494705047051470524705347054470554705647057470584705947060470614706247063470644706547066470674706847069470704707147072470734707447075470764707747078470794708047081470824708347084470854708647087470884708947090470914709247093470944709547096470974709847099471004710147102471034710447105471064710747108471094711047111471124711347114471154711647117471184711947120471214712247123471244712547126471274712847129471304713147132471334713447135471364713747138471394714047141471424714347144471454714647147471484714947150471514715247153471544715547156471574715847159471604716147162471634716447165471664716747168471694717047171471724717347174471754717647177471784717947180471814718247183471844718547186471874718847189471904719147192471934719447195471964719747198471994720047201472024720347204472054720647207472084720947210472114721247213472144721547216472174721847219472204722147222472234722447225472264722747228472294723047231472324723347234472354723647237472384723947240472414724247243472444724547246472474724847249472504725147252472534725447255472564725747258472594726047261472624726347264472654726647267472684726947270472714727247273472744727547276472774727847279472804728147282472834728447285472864728747288472894729047291472924729347294472954729647297472984729947300473014730247303473044730547306473074730847309473104731147312473134731447315473164731747318473194732047321473224732347324473254732647327473284732947330473314733247333473344733547336473374733847339473404734147342473434734447345473464734747348473494735047351473524735347354473554735647357473584735947360473614736247363473644736547366473674736847369473704737147372473734737447375473764737747378473794738047381473824738347384473854738647387473884738947390473914739247393473944739547396473974739847399474004740147402474034740447405474064740747408474094741047411474124741347414474154741647417474184741947420474214742247423474244742547426474274742847429474304743147432474334743447435474364743747438474394744047441474424744347444474454744647447474484744947450474514745247453474544745547456474574745847459474604746147462474634746447465474664746747468474694747047471474724747347474474754747647477474784747947480474814748247483474844748547486474874748847489474904749147492474934749447495474964749747498474994750047501475024750347504475054750647507475084750947510475114751247513475144751547516475174751847519475204752147522475234752447525475264752747528475294753047531475324753347534475354753647537475384753947540475414754247543475444754547546475474754847549475504755147552475534755447555475564755747558475594756047561475624756347564475654756647567475684756947570475714757247573475744757547576475774757847579475804758147582475834758447585475864758747588475894759047591475924759347594475954759647597475984759947600476014760247603476044760547606476074760847609476104761147612476134761447615476164761747618476194762047621476224762347624476254762647627476284762947630476314763247633476344763547636476374763847639476404764147642476434764447645476464764747648476494765047651476524765347654476554765647657476584765947660476614766247663476644766547666476674766847669476704767147672476734767447675476764767747678476794768047681476824768347684476854768647687476884768947690476914769247693476944769547696476974769847699477004770147702477034770447705477064770747708477094771047711477124771347714477154771647717477184771947720477214772247723477244772547726477274772847729477304773147732477334773447735477364773747738477394774047741477424774347744477454774647747477484774947750477514775247753477544775547756477574775847759477604776147762477634776447765477664776747768477694777047771477724777347774477754777647777477784777947780477814778247783477844778547786477874778847789477904779147792477934779447795477964779747798477994780047801478024780347804478054780647807478084780947810478114781247813478144781547816478174781847819478204782147822478234782447825478264782747828478294783047831478324783347834478354783647837478384783947840478414784247843478444784547846478474784847849478504785147852478534785447855478564785747858478594786047861478624786347864478654786647867478684786947870478714787247873478744787547876478774787847879478804788147882478834788447885478864788747888478894789047891478924789347894478954789647897478984789947900479014790247903479044790547906479074790847909479104791147912479134791447915479164791747918479194792047921479224792347924479254792647927479284792947930479314793247933479344793547936479374793847939479404794147942479434794447945479464794747948479494795047951479524795347954479554795647957479584795947960479614796247963479644796547966479674796847969479704797147972479734797447975479764797747978479794798047981479824798347984479854798647987479884798947990479914799247993479944799547996479974799847999480004800148002480034800448005480064800748008480094801048011480124801348014480154801648017480184801948020480214802248023480244802548026480274802848029480304803148032480334803448035480364803748038480394804048041480424804348044480454804648047480484804948050480514805248053480544805548056480574805848059480604806148062480634806448065480664806748068480694807048071480724807348074480754807648077480784807948080480814808248083480844808548086480874808848089480904809148092480934809448095480964809748098480994810048101481024810348104481054810648107481084810948110481114811248113481144811548116481174811848119481204812148122481234812448125481264812748128481294813048131481324813348134481354813648137481384813948140481414814248143481444814548146481474814848149481504815148152481534815448155481564815748158481594816048161481624816348164481654816648167481684816948170481714817248173481744817548176481774817848179481804818148182481834818448185481864818748188481894819048191481924819348194481954819648197481984819948200482014820248203482044820548206482074820848209482104821148212482134821448215482164821748218482194822048221482224822348224482254822648227482284822948230482314823248233482344823548236482374823848239482404824148242482434824448245482464824748248482494825048251482524825348254482554825648257482584825948260482614826248263482644826548266482674826848269482704827148272482734827448275482764827748278482794828048281482824828348284482854828648287482884828948290482914829248293482944829548296482974829848299483004830148302483034830448305483064830748308483094831048311483124831348314483154831648317483184831948320483214832248323483244832548326483274832848329483304833148332483334833448335483364833748338483394834048341483424834348344483454834648347483484834948350483514835248353483544835548356483574835848359483604836148362483634836448365483664836748368483694837048371483724837348374483754837648377483784837948380483814838248383483844838548386483874838848389483904839148392483934839448395483964839748398483994840048401484024840348404484054840648407484084840948410484114841248413484144841548416484174841848419484204842148422484234842448425484264842748428484294843048431484324843348434484354843648437484384843948440484414844248443484444844548446484474844848449484504845148452484534845448455484564845748458484594846048461484624846348464484654846648467484684846948470484714847248473484744847548476484774847848479484804848148482484834848448485484864848748488484894849048491484924849348494484954849648497484984849948500485014850248503485044850548506485074850848509485104851148512485134851448515485164851748518485194852048521485224852348524485254852648527485284852948530485314853248533485344853548536485374853848539485404854148542485434854448545485464854748548485494855048551485524855348554485554855648557485584855948560485614856248563485644856548566485674856848569485704857148572485734857448575485764857748578485794858048581485824858348584485854858648587485884858948590485914859248593485944859548596485974859848599486004860148602486034860448605486064860748608486094861048611486124861348614486154861648617486184861948620486214862248623486244862548626486274862848629486304863148632486334863448635486364863748638486394864048641486424864348644486454864648647486484864948650486514865248653486544865548656486574865848659486604866148662486634866448665486664866748668486694867048671486724867348674486754867648677486784867948680486814868248683486844868548686486874868848689486904869148692486934869448695486964869748698486994870048701487024870348704487054870648707487084870948710487114871248713487144871548716487174871848719487204872148722487234872448725487264872748728487294873048731487324873348734487354873648737487384873948740487414874248743487444874548746487474874848749487504875148752487534875448755487564875748758487594876048761487624876348764487654876648767487684876948770487714877248773487744877548776487774877848779487804878148782487834878448785487864878748788487894879048791487924879348794487954879648797487984879948800488014880248803488044880548806488074880848809488104881148812488134881448815488164881748818488194882048821488224882348824488254882648827488284882948830488314883248833488344883548836488374883848839488404884148842488434884448845488464884748848488494885048851488524885348854488554885648857488584885948860488614886248863488644886548866488674886848869488704887148872488734887448875488764887748878488794888048881488824888348884488854888648887488884888948890488914889248893488944889548896488974889848899489004890148902489034890448905489064890748908489094891048911489124891348914489154891648917489184891948920489214892248923489244892548926489274892848929489304893148932489334893448935489364893748938489394894048941489424894348944489454894648947489484894948950489514895248953489544895548956489574895848959489604896148962489634896448965489664896748968489694897048971489724897348974489754897648977489784897948980489814898248983489844898548986489874898848989489904899148992489934899448995489964899748998489994900049001490024900349004490054900649007490084900949010490114901249013490144901549016490174901849019490204902149022490234902449025490264902749028490294903049031490324903349034490354903649037490384903949040490414904249043490444904549046490474904849049490504905149052490534905449055490564905749058490594906049061490624906349064490654906649067490684906949070490714907249073490744907549076490774907849079490804908149082490834908449085490864908749088490894909049091490924909349094490954909649097490984909949100491014910249103491044910549106491074910849109491104911149112491134911449115491164911749118491194912049121491224912349124491254912649127491284912949130491314913249133491344913549136491374913849139491404914149142491434914449145491464914749148491494915049151491524915349154491554915649157491584915949160491614916249163491644916549166491674916849169491704917149172491734917449175491764917749178491794918049181491824918349184491854918649187491884918949190491914919249193491944919549196491974919849199492004920149202492034920449205492064920749208492094921049211492124921349214492154921649217492184921949220492214922249223492244922549226492274922849229492304923149232492334923449235492364923749238492394924049241492424924349244492454924649247492484924949250492514925249253492544925549256492574925849259492604926149262492634926449265492664926749268492694927049271492724927349274492754927649277492784927949280492814928249283492844928549286492874928849289492904929149292492934929449295492964929749298492994930049301493024930349304493054930649307493084930949310493114931249313493144931549316493174931849319493204932149322493234932449325493264932749328493294933049331493324933349334493354933649337493384933949340493414934249343493444934549346493474934849349493504935149352493534935449355493564935749358493594936049361493624936349364493654936649367493684936949370493714937249373493744937549376493774937849379493804938149382493834938449385493864938749388493894939049391493924939349394493954939649397493984939949400494014940249403494044940549406494074940849409494104941149412494134941449415494164941749418494194942049421494224942349424494254942649427494284942949430494314943249433494344943549436494374943849439494404944149442494434944449445494464944749448494494945049451494524945349454494554945649457494584945949460494614946249463494644946549466494674946849469494704947149472494734947449475494764947749478494794948049481494824948349484494854948649487494884948949490494914949249493494944949549496494974949849499495004950149502495034950449505495064950749508495094951049511495124951349514495154951649517495184951949520495214952249523495244952549526495274952849529495304953149532495334953449535495364953749538495394954049541495424954349544495454954649547495484954949550495514955249553495544955549556495574955849559495604956149562495634956449565495664956749568495694957049571495724957349574495754957649577495784957949580495814958249583495844958549586495874958849589495904959149592495934959449595495964959749598495994960049601496024960349604496054960649607496084960949610496114961249613496144961549616496174961849619496204962149622496234962449625496264962749628496294963049631496324963349634496354963649637496384963949640496414964249643496444964549646496474964849649496504965149652496534965449655496564965749658496594966049661496624966349664496654966649667496684966949670496714967249673496744967549676496774967849679496804968149682496834968449685496864968749688496894969049691496924969349694496954969649697496984969949700497014970249703497044970549706497074970849709497104971149712497134971449715497164971749718497194972049721497224972349724497254972649727497284972949730497314973249733497344973549736497374973849739497404974149742497434974449745497464974749748497494975049751497524975349754497554975649757497584975949760497614976249763497644976549766497674976849769497704977149772497734977449775497764977749778497794978049781497824978349784497854978649787497884978949790497914979249793497944979549796497974979849799498004980149802498034980449805498064980749808498094981049811498124981349814498154981649817498184981949820498214982249823498244982549826498274982849829498304983149832498334983449835498364983749838498394984049841498424984349844498454984649847498484984949850498514985249853498544985549856498574985849859498604986149862498634986449865498664986749868498694987049871498724987349874498754987649877498784987949880498814988249883498844988549886498874988849889498904989149892498934989449895498964989749898498994990049901499024990349904499054990649907499084990949910499114991249913499144991549916499174991849919499204992149922499234992449925499264992749928499294993049931499324993349934499354993649937499384993949940499414994249943499444994549946499474994849949499504995149952499534995449955499564995749958499594996049961499624996349964499654996649967499684996949970499714997249973499744997549976499774997849979499804998149982499834998449985499864998749988499894999049991499924999349994499954999649997499984999950000500015000250003500045000550006500075000850009500105001150012500135001450015500165001750018500195002050021500225002350024500255002650027500285002950030500315003250033500345003550036500375003850039500405004150042500435004450045500465004750048500495005050051500525005350054500555005650057500585005950060500615006250063500645006550066500675006850069500705007150072500735007450075500765007750078500795008050081500825008350084500855008650087500885008950090500915009250093500945009550096500975009850099501005010150102501035010450105501065010750108501095011050111501125011350114501155011650117501185011950120501215012250123501245012550126501275012850129501305013150132501335013450135501365013750138501395014050141501425014350144501455014650147501485014950150501515015250153501545015550156501575015850159501605016150162501635016450165501665016750168501695017050171501725017350174501755017650177501785017950180501815018250183501845018550186501875018850189501905019150192501935019450195501965019750198501995020050201502025020350204502055020650207502085020950210502115021250213502145021550216502175021850219502205022150222502235022450225502265022750228502295023050231502325023350234502355023650237502385023950240502415024250243502445024550246502475024850249502505025150252502535025450255502565025750258502595026050261502625026350264502655026650267502685026950270502715027250273502745027550276502775027850279502805028150282502835028450285502865028750288502895029050291502925029350294502955029650297502985029950300503015030250303503045030550306503075030850309503105031150312503135031450315503165031750318503195032050321503225032350324503255032650327503285032950330503315033250333503345033550336503375033850339503405034150342503435034450345503465034750348503495035050351503525035350354503555035650357503585035950360503615036250363503645036550366503675036850369503705037150372503735037450375503765037750378503795038050381503825038350384503855038650387503885038950390503915039250393503945039550396503975039850399504005040150402504035040450405504065040750408504095041050411504125041350414504155041650417504185041950420504215042250423504245042550426504275042850429504305043150432504335043450435504365043750438504395044050441504425044350444504455044650447504485044950450504515045250453504545045550456504575045850459504605046150462504635046450465504665046750468504695047050471504725047350474504755047650477504785047950480504815048250483504845048550486504875048850489504905049150492504935049450495504965049750498504995050050501505025050350504505055050650507505085050950510505115051250513505145051550516505175051850519505205052150522505235052450525505265052750528505295053050531505325053350534505355053650537505385053950540505415054250543505445054550546505475054850549505505055150552505535055450555505565055750558505595056050561505625056350564505655056650567505685056950570505715057250573505745057550576505775057850579505805058150582505835058450585505865058750588505895059050591505925059350594505955059650597505985059950600506015060250603506045060550606506075060850609506105061150612506135061450615506165061750618506195062050621506225062350624506255062650627506285062950630506315063250633506345063550636506375063850639506405064150642506435064450645506465064750648506495065050651506525065350654506555065650657506585065950660506615066250663506645066550666506675066850669506705067150672506735067450675506765067750678506795068050681506825068350684506855068650687506885068950690506915069250693506945069550696506975069850699507005070150702507035070450705507065070750708507095071050711507125071350714507155071650717507185071950720507215072250723507245072550726507275072850729507305073150732507335073450735507365073750738507395074050741507425074350744507455074650747507485074950750507515075250753507545075550756507575075850759507605076150762507635076450765507665076750768507695077050771507725077350774507755077650777507785077950780507815078250783507845078550786507875078850789507905079150792507935079450795507965079750798507995080050801508025080350804508055080650807508085080950810508115081250813508145081550816508175081850819508205082150822508235082450825508265082750828508295083050831508325083350834508355083650837508385083950840508415084250843508445084550846508475084850849508505085150852508535085450855508565085750858508595086050861508625086350864508655086650867508685086950870508715087250873508745087550876508775087850879508805088150882508835088450885508865088750888508895089050891508925089350894508955089650897508985089950900509015090250903509045090550906509075090850909509105091150912509135091450915509165091750918509195092050921509225092350924509255092650927509285092950930509315093250933509345093550936509375093850939509405094150942509435094450945509465094750948509495095050951509525095350954509555095650957509585095950960509615096250963509645096550966509675096850969509705097150972509735097450975509765097750978509795098050981509825098350984509855098650987509885098950990509915099250993509945099550996509975099850999510005100151002510035100451005510065100751008510095101051011510125101351014510155101651017510185101951020510215102251023510245102551026510275102851029510305103151032510335103451035510365103751038510395104051041510425104351044510455104651047510485104951050510515105251053510545105551056510575105851059510605106151062510635106451065510665106751068510695107051071510725107351074510755107651077510785107951080510815108251083510845108551086510875108851089510905109151092510935109451095510965109751098510995110051101511025110351104511055110651107511085110951110511115111251113511145111551116511175111851119511205112151122511235112451125511265112751128511295113051131511325113351134511355113651137511385113951140511415114251143511445114551146511475114851149511505115151152511535115451155511565115751158511595116051161511625116351164511655116651167511685116951170511715117251173511745117551176511775117851179511805118151182511835118451185511865118751188511895119051191511925119351194511955119651197511985119951200512015120251203512045120551206512075120851209512105121151212512135121451215512165121751218512195122051221512225122351224512255122651227512285122951230512315123251233512345123551236512375123851239512405124151242512435124451245512465124751248512495125051251512525125351254512555125651257512585125951260512615126251263512645126551266512675126851269512705127151272512735127451275512765127751278512795128051281512825128351284512855128651287512885128951290512915129251293512945129551296512975129851299513005130151302513035130451305513065130751308513095131051311513125131351314513155131651317513185131951320513215132251323513245132551326513275132851329513305133151332513335133451335513365133751338513395134051341513425134351344513455134651347513485134951350513515135251353513545135551356513575135851359513605136151362513635136451365513665136751368513695137051371513725137351374513755137651377513785137951380513815138251383513845138551386513875138851389513905139151392513935139451395513965139751398513995140051401514025140351404514055140651407514085140951410514115141251413514145141551416514175141851419514205142151422514235142451425514265142751428514295143051431514325143351434514355143651437514385143951440514415144251443514445144551446514475144851449514505145151452514535145451455514565145751458514595146051461514625146351464514655146651467514685146951470514715147251473514745147551476514775147851479514805148151482514835148451485514865148751488514895149051491514925149351494514955149651497514985149951500515015150251503515045150551506515075150851509515105151151512515135151451515515165151751518515195152051521515225152351524515255152651527515285152951530515315153251533515345153551536515375153851539515405154151542515435154451545515465154751548515495155051551515525155351554515555155651557515585155951560515615156251563515645156551566515675156851569515705157151572515735157451575515765157751578515795158051581515825158351584515855158651587515885158951590515915159251593515945159551596515975159851599516005160151602516035160451605516065160751608516095161051611516125161351614516155161651617516185161951620516215162251623516245162551626516275162851629516305163151632516335163451635516365163751638516395164051641516425164351644516455164651647516485164951650516515165251653516545165551656516575165851659516605166151662516635166451665516665166751668516695167051671516725167351674516755167651677516785167951680516815168251683516845168551686516875168851689516905169151692516935169451695516965169751698516995170051701517025170351704517055170651707517085170951710517115171251713517145171551716517175171851719517205172151722517235172451725517265172751728517295173051731517325173351734517355173651737517385173951740517415174251743517445174551746517475174851749517505175151752517535175451755517565175751758517595176051761517625176351764517655176651767517685176951770517715177251773517745177551776517775177851779517805178151782517835178451785517865178751788517895179051791517925179351794517955179651797517985179951800518015180251803518045180551806518075180851809518105181151812518135181451815518165181751818518195182051821518225182351824518255182651827518285182951830518315183251833518345183551836518375183851839518405184151842518435184451845518465184751848518495185051851518525185351854518555185651857518585185951860518615186251863518645186551866518675186851869518705187151872518735187451875518765187751878518795188051881518825188351884518855188651887518885188951890518915189251893518945189551896518975189851899519005190151902519035190451905519065190751908519095191051911519125191351914519155191651917519185191951920519215192251923519245192551926519275192851929519305193151932519335193451935519365193751938519395194051941519425194351944519455194651947519485194951950519515195251953519545195551956519575195851959519605196151962519635196451965519665196751968519695197051971519725197351974519755197651977519785197951980519815198251983519845198551986519875198851989519905199151992519935199451995519965199751998519995200052001520025200352004520055200652007520085200952010520115201252013520145201552016520175201852019520205202152022520235202452025520265202752028520295203052031520325203352034520355203652037520385203952040520415204252043520445204552046520475204852049520505205152052520535205452055520565205752058520595206052061520625206352064520655206652067520685206952070520715207252073520745207552076520775207852079520805208152082520835208452085520865208752088520895209052091520925209352094520955209652097520985209952100521015210252103521045210552106521075210852109521105211152112521135211452115521165211752118521195212052121521225212352124521255212652127521285212952130521315213252133521345213552136521375213852139521405214152142521435214452145521465214752148521495215052151521525215352154521555215652157521585215952160521615216252163521645216552166521675216852169521705217152172521735217452175521765217752178521795218052181521825218352184521855218652187521885218952190521915219252193521945219552196521975219852199522005220152202522035220452205522065220752208522095221052211522125221352214522155221652217522185221952220522215222252223522245222552226522275222852229522305223152232522335223452235522365223752238522395224052241522425224352244522455224652247522485224952250522515225252253522545225552256522575225852259522605226152262522635226452265522665226752268522695227052271522725227352274522755227652277522785227952280522815228252283522845228552286522875228852289522905229152292522935229452295522965229752298522995230052301523025230352304523055230652307523085230952310523115231252313523145231552316523175231852319523205232152322523235232452325523265232752328523295233052331523325233352334523355233652337523385233952340523415234252343523445234552346523475234852349523505235152352523535235452355523565235752358523595236052361523625236352364523655236652367523685236952370523715237252373523745237552376523775237852379523805238152382523835238452385523865238752388523895239052391523925239352394523955239652397523985239952400524015240252403524045240552406524075240852409524105241152412524135241452415524165241752418524195242052421524225242352424524255242652427524285242952430524315243252433524345243552436524375243852439524405244152442524435244452445524465244752448524495245052451524525245352454524555245652457524585245952460524615246252463524645246552466524675246852469524705247152472524735247452475524765247752478524795248052481524825248352484524855248652487524885248952490524915249252493524945249552496524975249852499525005250152502525035250452505525065250752508525095251052511525125251352514525155251652517525185251952520525215252252523525245252552526525275252852529525305253152532525335253452535525365253752538525395254052541525425254352544525455254652547525485254952550525515255252553525545255552556525575255852559525605256152562525635256452565525665256752568525695257052571525725257352574525755257652577525785257952580525815258252583525845258552586525875258852589525905259152592525935259452595525965259752598525995260052601526025260352604526055260652607526085260952610526115261252613526145261552616526175261852619526205262152622526235262452625526265262752628526295263052631526325263352634526355263652637526385263952640526415264252643526445264552646526475264852649526505265152652526535265452655526565265752658526595266052661526625266352664526655266652667526685266952670526715267252673526745267552676526775267852679526805268152682526835268452685526865268752688526895269052691526925269352694526955269652697526985269952700527015270252703527045270552706527075270852709527105271152712527135271452715527165271752718527195272052721527225272352724527255272652727527285272952730527315273252733527345273552736527375273852739527405274152742527435274452745527465274752748527495275052751527525275352754527555275652757527585275952760527615276252763527645276552766527675276852769527705277152772527735277452775527765277752778527795278052781527825278352784527855278652787527885278952790527915279252793527945279552796527975279852799528005280152802528035280452805528065280752808528095281052811528125281352814528155281652817528185281952820528215282252823528245282552826528275282852829528305283152832528335283452835528365283752838528395284052841528425284352844528455284652847528485284952850528515285252853528545285552856528575285852859528605286152862528635286452865528665286752868528695287052871528725287352874528755287652877528785287952880528815288252883528845288552886528875288852889528905289152892528935289452895528965289752898528995290052901529025290352904529055290652907529085290952910529115291252913529145291552916529175291852919529205292152922529235292452925529265292752928529295293052931529325293352934529355293652937529385293952940529415294252943529445294552946529475294852949529505295152952529535295452955529565295752958529595296052961529625296352964529655296652967529685296952970529715297252973529745297552976529775297852979529805298152982529835298452985529865298752988529895299052991529925299352994529955299652997529985299953000530015300253003530045300553006530075300853009530105301153012530135301453015530165301753018530195302053021530225302353024530255302653027530285302953030530315303253033530345303553036530375303853039530405304153042530435304453045530465304753048530495305053051530525305353054530555305653057530585305953060530615306253063530645306553066530675306853069530705307153072530735307453075530765307753078530795308053081530825308353084530855308653087530885308953090530915309253093530945309553096530975309853099531005310153102531035310453105531065310753108531095311053111531125311353114531155311653117531185311953120531215312253123531245312553126531275312853129531305313153132531335313453135531365313753138531395314053141531425314353144531455314653147531485314953150531515315253153531545315553156531575315853159531605316153162531635316453165531665316753168531695317053171531725317353174531755317653177531785317953180531815318253183531845318553186531875318853189531905319153192531935319453195531965319753198531995320053201532025320353204532055320653207532085320953210532115321253213532145321553216532175321853219532205322153222532235322453225532265322753228532295323053231532325323353234532355323653237532385323953240532415324253243532445324553246532475324853249532505325153252532535325453255532565325753258532595326053261532625326353264532655326653267532685326953270532715327253273532745327553276532775327853279532805328153282532835328453285532865328753288532895329053291532925329353294532955329653297532985329953300533015330253303533045330553306533075330853309533105331153312533135331453315533165331753318533195332053321533225332353324533255332653327533285332953330533315333253333533345333553336533375333853339533405334153342533435334453345533465334753348533495335053351533525335353354533555335653357533585335953360533615336253363533645336553366533675336853369533705337153372533735337453375533765337753378533795338053381533825338353384533855338653387533885338953390533915339253393533945339553396533975339853399534005340153402534035340453405534065340753408534095341053411534125341353414534155341653417534185341953420534215342253423534245342553426534275342853429534305343153432534335343453435534365343753438534395344053441534425344353444534455344653447534485344953450534515345253453534545345553456534575345853459534605346153462534635346453465534665346753468534695347053471534725347353474534755347653477534785347953480534815348253483534845348553486534875348853489534905349153492534935349453495534965349753498534995350053501535025350353504
  1. /* sp.c
  2. *
  3. * Copyright (C) 2006-2023 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. /* Implementation by Sean Parkinson. */
  22. #ifdef HAVE_CONFIG_H
  23. #include <config.h>
  24. #endif
  25. #include <wolfssl/wolfcrypt/settings.h>
  26. #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \
  27. defined(WOLFSSL_HAVE_SP_ECC)
  28. #include <wolfssl/wolfcrypt/error-crypt.h>
  29. #include <wolfssl/wolfcrypt/cpuid.h>
  30. #ifdef NO_INLINE
  31. #include <wolfssl/wolfcrypt/misc.h>
  32. #else
  33. #define WOLFSSL_MISC_INCLUDED
  34. #include <wolfcrypt/src/misc.c>
  35. #endif
  36. #ifdef RSA_LOW_MEM
  37. #ifndef SP_RSA_PRIVATE_EXP_D
  38. #define SP_RSA_PRIVATE_EXP_D
  39. #endif
  40. #ifndef WOLFSSL_SP_SMALL
  41. #define WOLFSSL_SP_SMALL
  42. #endif
  43. #endif
  44. #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
  45. #undef WOLFSSL_SP_SMALL_STACK
  46. #define WOLFSSL_SP_SMALL_STACK
  47. #endif
  48. #include <wolfssl/wolfcrypt/sp.h>
  49. #ifdef __IAR_SYSTEMS_ICC__
  50. #define __asm__ asm
  51. #define __volatile__ volatile
  52. #define WOLFSSL_NO_VAR_ASSIGN_REG
  53. #endif /* __IAR_SYSTEMS_ICC__ */
  54. #ifdef __KEIL__
  55. #define __asm__ __asm
  56. #define __volatile__ volatile
  57. #endif
  58. #ifndef WOLFSSL_SP_ASM
  59. #if SP_WORD_SIZE == 64
  60. #define SP_PRINT_NUM(var, name, total, words, bits) \
  61. do { \
  62. int ii; \
  63. byte nb[(bits + 7) / 8]; \
  64. sp_digit _s[words]; \
  65. XMEMCPY(_s, var, sizeof(_s)); \
  66. sp_##total##_norm_##words(_s); \
  67. sp_##total##_to_bin_##words(_s, nb); \
  68. fprintf(stderr, name "=0x"); \
  69. for (ii=0; ii<(bits + 7) / 8; ii++) \
  70. fprintf(stderr, "%02x", nb[ii]); \
  71. fprintf(stderr, "\n"); \
  72. } while (0)
  73. #define SP_PRINT_VAL(var, name) \
  74. fprintf(stderr, name "=0x" SP_PRINT_FMT "\n", var)
  75. #define SP_PRINT_INT(var, name) \
  76. fprintf(stderr, name "=%d\n", var)
  77. #if ((defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && \
  78. ((!defined(WC_NO_CACHE_RESISTANT) && \
  79. (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH))) || \
  80. (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP))) && \
  81. !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || (defined(WOLFSSL_SP_SMALL) && \
  82. defined(WOLFSSL_HAVE_SP_ECC) && (!defined(WOLFSSL_SP_NO_256) || \
  83. defined(WOLFSSL_SP_384) || defined(WOLFSSL_SP_521) || \
  84. defined(WOLFSSL_SP_1024)))
  85. /* Mask for address to obfuscate which of the two address will be used. */
  86. static const size_t addr_mask[2] = { 0, (size_t)-1 };
  87. #endif
  88. #if defined(WOLFSSL_SP_NONBLOCK) && (!defined(WOLFSSL_SP_NO_MALLOC) || \
  89. !defined(WOLFSSL_SP_SMALL))
  90. #error SP non-blocking requires small and no-malloc (WOLFSSL_SP_SMALL and WOLFSSL_SP_NO_MALLOC)
  91. #endif
  92. #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)
  93. #ifndef WOLFSSL_SP_NO_2048
  94. #ifdef WOLFSSL_SP_SMALL
  95. /* Read big endian unsigned byte array into r.
  96. *
  97. * r A single precision integer.
  98. * size Maximum number of bytes to convert
  99. * a Byte array.
  100. * n Number of bytes in array to read.
  101. */
  102. static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n)
  103. {
  104. int i;
  105. int j = 0;
  106. word32 s = 0;
  107. r[0] = 0;
  108. for (i = n-1; i >= 0; i--) {
  109. r[j] |= (((sp_digit)a[i]) << s);
  110. if (s >= 53U) {
  111. r[j] &= 0x1fffffffffffffffL;
  112. s = 61U - s;
  113. if (j + 1 >= size) {
  114. break;
  115. }
  116. r[++j] = (sp_digit)a[i] >> s;
  117. s = 8U - s;
  118. }
  119. else {
  120. s += 8U;
  121. }
  122. }
  123. for (j++; j < size; j++) {
  124. r[j] = 0;
  125. }
  126. }
  127. /* Convert an mp_int to an array of sp_digit.
  128. *
  129. * r A single precision integer.
  130. * size Maximum number of bytes to convert
  131. * a A multi-precision integer.
  132. */
  133. static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a)
  134. {
  135. #if DIGIT_BIT == 61
  136. int i;
  137. sp_digit j = (sp_digit)0 - (sp_digit)a->used;
  138. int o = 0;
  139. for (i = 0; i < size; i++) {
  140. sp_digit mask = (sp_digit)0 - (j >> 60);
  141. r[i] = a->dp[o] & mask;
  142. j++;
  143. o += (int)(j >> 60);
  144. }
  145. #elif DIGIT_BIT > 61
  146. unsigned int i;
  147. int j = 0;
  148. word32 s = 0;
  149. r[0] = 0;
  150. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  151. r[j] |= ((sp_digit)a->dp[i] << s);
  152. r[j] &= 0x1fffffffffffffffL;
  153. s = 61U - s;
  154. if (j + 1 >= size) {
  155. break;
  156. }
  157. /* lint allow cast of mismatch word32 and mp_digit */
  158. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  159. while ((s + 61U) <= (word32)DIGIT_BIT) {
  160. s += 61U;
  161. r[j] &= 0x1fffffffffffffffL;
  162. if (j + 1 >= size) {
  163. break;
  164. }
  165. if (s < (word32)DIGIT_BIT) {
  166. /* lint allow cast of mismatch word32 and mp_digit */
  167. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  168. }
  169. else {
  170. r[++j] = (sp_digit)0;
  171. }
  172. }
  173. s = (word32)DIGIT_BIT - s;
  174. }
  175. for (j++; j < size; j++) {
  176. r[j] = 0;
  177. }
  178. #else
  179. unsigned int i;
  180. int j = 0;
  181. int s = 0;
  182. r[0] = 0;
  183. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  184. r[j] |= ((sp_digit)a->dp[i]) << s;
  185. if (s + DIGIT_BIT >= 61) {
  186. r[j] &= 0x1fffffffffffffffL;
  187. if (j + 1 >= size) {
  188. break;
  189. }
  190. s = 61 - s;
  191. if (s == DIGIT_BIT) {
  192. r[++j] = 0;
  193. s = 0;
  194. }
  195. else {
  196. r[++j] = a->dp[i] >> s;
  197. s = DIGIT_BIT - s;
  198. }
  199. }
  200. else {
  201. s += DIGIT_BIT;
  202. }
  203. }
  204. for (j++; j < size; j++) {
  205. r[j] = 0;
  206. }
  207. #endif
  208. }
  209. /* Write r as big endian to byte array.
  210. * Fixed length number of bytes written: 256
  211. *
  212. * r A single precision integer.
  213. * a Byte array.
  214. */
  215. static void sp_2048_to_bin_34(sp_digit* r, byte* a)
  216. {
  217. int i;
  218. int j;
  219. int s = 0;
  220. int b;
  221. for (i=0; i<33; i++) {
  222. r[i+1] += r[i] >> 61;
  223. r[i] &= 0x1fffffffffffffffL;
  224. }
  225. j = 2055 / 8 - 1;
  226. a[j] = 0;
  227. for (i=0; i<34 && j>=0; i++) {
  228. b = 0;
  229. /* lint allow cast of mismatch sp_digit and int */
  230. a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
  231. b += 8 - s;
  232. if (j < 0) {
  233. break;
  234. }
  235. while (b < 61) {
  236. a[j--] = (byte)(r[i] >> b);
  237. b += 8;
  238. if (j < 0) {
  239. break;
  240. }
  241. }
  242. s = 8 - (b - 61);
  243. if (j >= 0) {
  244. a[j] = 0;
  245. }
  246. if (s != 0) {
  247. j++;
  248. }
  249. }
  250. }
  251. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  252. /* Normalize the values in each word to 61 bits.
  253. *
  254. * a Array of sp_digit to normalize.
  255. */
  256. static void sp_2048_norm_17(sp_digit* a)
  257. {
  258. int i;
  259. for (i = 0; i < 16; i++) {
  260. a[i+1] += a[i] >> 61;
  261. a[i] &= 0x1fffffffffffffffL;
  262. }
  263. }
  264. #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
  265. /* Normalize the values in each word to 61 bits.
  266. *
  267. * a Array of sp_digit to normalize.
  268. */
  269. static void sp_2048_norm_34(sp_digit* a)
  270. {
  271. int i;
  272. for (i = 0; i < 33; i++) {
  273. a[i+1] += a[i] >> 61;
  274. a[i] &= 0x1fffffffffffffffL;
  275. }
  276. }
  277. /* Multiply a and b into r. (r = a * b)
  278. *
  279. * r A single precision integer.
  280. * a A single precision integer.
  281. * b A single precision integer.
  282. */
  283. SP_NOINLINE static void sp_2048_mul_34(sp_digit* r, const sp_digit* a,
  284. const sp_digit* b)
  285. {
  286. int i;
  287. int imax;
  288. int k;
  289. sp_uint128 c;
  290. sp_uint128 lo;
  291. c = ((sp_uint128)a[33]) * b[33];
  292. r[67] = (sp_digit)(c >> 61);
  293. c &= 0x1fffffffffffffffL;
  294. for (k = 65; k >= 0; k--) {
  295. if (k >= 34) {
  296. i = k - 33;
  297. imax = 33;
  298. }
  299. else {
  300. i = 0;
  301. imax = k;
  302. }
  303. if (imax - i > 15) {
  304. int imaxlo;
  305. lo = 0;
  306. for (imaxlo = i; imaxlo <= imax; imaxlo += 15) {
  307. for (; i <= imax && i < imaxlo + 15; i++) {
  308. lo += ((sp_uint128)a[i]) * b[k - i];
  309. }
  310. c += lo >> 61;
  311. lo &= 0x1fffffffffffffffL;
  312. }
  313. r[k + 2] += (sp_digit)(c >> 61);
  314. r[k + 1] = (sp_digit)(c & 0x1fffffffffffffffL);
  315. c = lo & 0x1fffffffffffffffL;
  316. }
  317. else {
  318. lo = 0;
  319. for (; i <= imax; i++) {
  320. lo += ((sp_uint128)a[i]) * b[k - i];
  321. }
  322. c += lo >> 61;
  323. r[k + 2] += (sp_digit)(c >> 61);
  324. r[k + 1] = (sp_digit)(c & 0x1fffffffffffffffL);
  325. c = lo & 0x1fffffffffffffffL;
  326. }
  327. }
  328. r[0] = (sp_digit)c;
  329. }
  330. /* Square a and put result in r. (r = a * a)
  331. *
  332. * r A single precision integer.
  333. * a A single precision integer.
  334. */
  335. SP_NOINLINE static void sp_2048_sqr_34(sp_digit* r, const sp_digit* a)
  336. {
  337. int i;
  338. int imax;
  339. int k;
  340. sp_uint128 c;
  341. sp_uint128 t;
  342. c = ((sp_uint128)a[33]) * a[33];
  343. r[67] = (sp_digit)(c >> 61);
  344. c = (c & 0x1fffffffffffffffL) << 61;
  345. for (k = 65; k >= 0; k--) {
  346. i = (k + 1) / 2;
  347. if ((k & 1) == 0) {
  348. c += ((sp_uint128)a[i]) * a[i];
  349. i++;
  350. }
  351. if (k < 33) {
  352. imax = k;
  353. }
  354. else {
  355. imax = 33;
  356. }
  357. if (imax - i >= 14) {
  358. int imaxlo;
  359. sp_uint128 hi;
  360. hi = c >> 61;
  361. c &= 0x1fffffffffffffffL;
  362. for (imaxlo = i; imaxlo <= imax; imaxlo += 14) {
  363. t = 0;
  364. for (; i <= imax && i < imaxlo + 14; i++) {
  365. t += ((sp_uint128)a[i]) * a[k - i];
  366. }
  367. c += t * 2;
  368. hi += c >> 61;
  369. c &= 0x1fffffffffffffffL;
  370. }
  371. r[k + 2] += (sp_digit)(hi >> 61);
  372. r[k + 1] = (sp_digit)(hi & 0x1fffffffffffffffL);
  373. c <<= 61;
  374. }
  375. else
  376. {
  377. t = 0;
  378. for (; i <= imax; i++) {
  379. t += ((sp_uint128)a[i]) * a[k - i];
  380. }
  381. c += t * 2;
  382. r[k + 2] += (sp_digit) (c >> 122);
  383. r[k + 1] = (sp_digit)((c >> 61) & 0x1fffffffffffffffL);
  384. c = (c & 0x1fffffffffffffffL) << 61;
  385. }
  386. }
  387. r[0] = (sp_digit)(c >> 61);
  388. }
  389. /* Calculate the bottom digit of -1/a mod 2^n.
  390. *
  391. * a A single precision number.
  392. * rho Bottom word of inverse.
  393. */
  394. static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho)
  395. {
  396. sp_digit x;
  397. sp_digit b;
  398. b = a[0];
  399. x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
  400. x *= 2 - b * x; /* here x*a==1 mod 2**8 */
  401. x *= 2 - b * x; /* here x*a==1 mod 2**16 */
  402. x *= 2 - b * x; /* here x*a==1 mod 2**32 */
  403. x *= 2 - b * x; /* here x*a==1 mod 2**64 */
  404. x &= 0x1fffffffffffffffL;
  405. /* rho = -1/m mod b */
  406. *rho = ((sp_digit)1 << 61) - x;
  407. }
  408. /* Multiply a by scalar b into r. (r = a * b)
  409. *
  410. * r A single precision integer.
  411. * a A single precision integer.
  412. * b A scalar.
  413. */
  414. SP_NOINLINE static void sp_2048_mul_d_34(sp_digit* r, const sp_digit* a,
  415. sp_digit b)
  416. {
  417. sp_int128 tb = b;
  418. sp_int128 t = 0;
  419. int i;
  420. for (i = 0; i < 34; i++) {
  421. t += tb * a[i];
  422. r[i] = (sp_digit)(t & 0x1fffffffffffffffL);
  423. t >>= 61;
  424. }
  425. r[34] = (sp_digit)t;
  426. }
  427. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  428. /* Sub b from a into r. (r = a - b)
  429. *
  430. * r A single precision integer.
  431. * a A single precision integer.
  432. * b A single precision integer.
  433. */
  434. SP_NOINLINE static int sp_2048_sub_17(sp_digit* r, const sp_digit* a,
  435. const sp_digit* b)
  436. {
  437. int i;
  438. for (i = 0; i < 17; i++) {
  439. r[i] = a[i] - b[i];
  440. }
  441. return 0;
  442. }
  443. /* r = 2^n mod m where n is the number of bits to reduce by.
  444. * Given m must be 2048 bits, just need to subtract.
  445. *
  446. * r A single precision number.
  447. * m A single precision number.
  448. */
  449. static void sp_2048_mont_norm_17(sp_digit* r, const sp_digit* m)
  450. {
  451. /* Set r = 2^n - 1. */
  452. int i;
  453. for (i=0; i<16; i++) {
  454. r[i] = 0x1fffffffffffffffL;
  455. }
  456. r[16] = 0xffffffffffffL;
  457. /* r = (2^n - 1) mod n */
  458. (void)sp_2048_sub_17(r, r, m);
  459. /* Add one so r = 2^n mod m */
  460. r[0] += 1;
  461. }
  462. /* Compare a with b in constant time.
  463. *
  464. * a A single precision integer.
  465. * b A single precision integer.
  466. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  467. * respectively.
  468. */
  469. static sp_digit sp_2048_cmp_17(const sp_digit* a, const sp_digit* b)
  470. {
  471. sp_digit r = 0;
  472. int i;
  473. for (i=16; i>=0; i--) {
  474. r |= (a[i] - b[i]) & ~(((sp_digit)0 - r) >> 60);
  475. }
  476. return r;
  477. }
  478. /* Conditionally subtract b from a using the mask m.
  479. * m is -1 to subtract and 0 when not.
  480. *
  481. * r A single precision number representing condition subtract result.
  482. * a A single precision number to subtract from.
  483. * b A single precision number to subtract.
  484. * m Mask value to apply.
  485. */
  486. static void sp_2048_cond_sub_17(sp_digit* r, const sp_digit* a,
  487. const sp_digit* b, const sp_digit m)
  488. {
  489. int i;
  490. for (i = 0; i < 17; i++) {
  491. r[i] = a[i] - (b[i] & m);
  492. }
  493. }
  494. /* Mul a by scalar b and add into r. (r += a * b)
  495. *
  496. * r A single precision integer.
  497. * a A single precision integer.
  498. * b A scalar.
  499. */
  500. SP_NOINLINE static void sp_2048_mul_add_17(sp_digit* r, const sp_digit* a,
  501. const sp_digit b)
  502. {
  503. sp_int128 tb = b;
  504. sp_int128 t[4];
  505. int i;
  506. t[0] = 0;
  507. for (i = 0; i < 16; i += 4) {
  508. t[0] += (tb * a[i+0]) + r[i+0];
  509. t[1] = (tb * a[i+1]) + r[i+1];
  510. t[2] = (tb * a[i+2]) + r[i+2];
  511. t[3] = (tb * a[i+3]) + r[i+3];
  512. r[i+0] = t[0] & 0x1fffffffffffffffL;
  513. t[1] += t[0] >> 61;
  514. r[i+1] = t[1] & 0x1fffffffffffffffL;
  515. t[2] += t[1] >> 61;
  516. r[i+2] = t[2] & 0x1fffffffffffffffL;
  517. t[3] += t[2] >> 61;
  518. r[i+3] = t[3] & 0x1fffffffffffffffL;
  519. t[0] = t[3] >> 61;
  520. }
  521. t[0] += (tb * a[16]) + r[16];
  522. r[16] = t[0] & 0x1fffffffffffffffL;
  523. r[17] += (sp_digit)(t[0] >> 61);
  524. }
  525. /* Shift the result in the high 1024 bits down to the bottom.
  526. *
  527. * r A single precision number.
  528. * a A single precision number.
  529. */
  530. static void sp_2048_mont_shift_17(sp_digit* r, const sp_digit* a)
  531. {
  532. int i;
  533. sp_int128 n = a[16] >> 48;
  534. n += ((sp_int128)a[17]) << 13;
  535. for (i = 0; i < 16; i++) {
  536. r[i] = n & 0x1fffffffffffffffL;
  537. n >>= 61;
  538. n += ((sp_int128)a[18 + i]) << 13;
  539. }
  540. r[16] = (sp_digit)n;
  541. XMEMSET(&r[17], 0, sizeof(*r) * 17U);
  542. }
  543. /* Reduce the number back to 2048 bits using Montgomery reduction.
  544. *
  545. * a A single precision number to reduce in place.
  546. * m The single precision number representing the modulus.
  547. * mp The digit representing the negative inverse of m mod 2^n.
  548. */
  549. static void sp_2048_mont_reduce_17(sp_digit* a, const sp_digit* m, sp_digit mp)
  550. {
  551. int i;
  552. sp_digit mu;
  553. sp_digit over;
  554. sp_2048_norm_17(a + 17);
  555. for (i=0; i<16; i++) {
  556. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1fffffffffffffffL;
  557. sp_2048_mul_add_17(a+i, m, mu);
  558. a[i+1] += a[i] >> 61;
  559. }
  560. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0xffffffffffffL;
  561. sp_2048_mul_add_17(a+i, m, mu);
  562. a[i+1] += a[i] >> 61;
  563. a[i] &= 0x1fffffffffffffffL;
  564. sp_2048_mont_shift_17(a, a);
  565. over = a[16] - m[16];
  566. sp_2048_cond_sub_17(a, a, m, ~((over - 1) >> 63));
  567. sp_2048_norm_17(a);
  568. }
  569. /* Multiply a and b into r. (r = a * b)
  570. *
  571. * r A single precision integer.
  572. * a A single precision integer.
  573. * b A single precision integer.
  574. */
  575. SP_NOINLINE static void sp_2048_mul_17(sp_digit* r, const sp_digit* a,
  576. const sp_digit* b)
  577. {
  578. int i;
  579. int imax;
  580. int k;
  581. sp_uint128 c;
  582. sp_uint128 lo;
  583. c = ((sp_uint128)a[16]) * b[16];
  584. r[33] = (sp_digit)(c >> 61);
  585. c &= 0x1fffffffffffffffL;
  586. for (k = 31; k >= 0; k--) {
  587. if (k >= 17) {
  588. i = k - 16;
  589. imax = 16;
  590. }
  591. else {
  592. i = 0;
  593. imax = k;
  594. }
  595. if (imax - i > 15) {
  596. int imaxlo;
  597. lo = 0;
  598. for (imaxlo = i; imaxlo <= imax; imaxlo += 15) {
  599. for (; i <= imax && i < imaxlo + 15; i++) {
  600. lo += ((sp_uint128)a[i]) * b[k - i];
  601. }
  602. c += lo >> 61;
  603. lo &= 0x1fffffffffffffffL;
  604. }
  605. r[k + 2] += (sp_digit)(c >> 61);
  606. r[k + 1] = (sp_digit)(c & 0x1fffffffffffffffL);
  607. c = lo & 0x1fffffffffffffffL;
  608. }
  609. else {
  610. lo = 0;
  611. for (; i <= imax; i++) {
  612. lo += ((sp_uint128)a[i]) * b[k - i];
  613. }
  614. c += lo >> 61;
  615. r[k + 2] += (sp_digit)(c >> 61);
  616. r[k + 1] = (sp_digit)(c & 0x1fffffffffffffffL);
  617. c = lo & 0x1fffffffffffffffL;
  618. }
  619. }
  620. r[0] = (sp_digit)c;
  621. }
  622. /* Multiply two Montgomery form numbers mod the modulus (prime).
  623. * (r = a * b mod m)
  624. *
  625. * r Result of multiplication.
  626. * a First number to multiply in Montgomery form.
  627. * b Second number to multiply in Montgomery form.
  628. * m Modulus (prime).
  629. * mp Montgomery multiplier.
  630. */
  631. SP_NOINLINE static void sp_2048_mont_mul_17(sp_digit* r, const sp_digit* a,
  632. const sp_digit* b, const sp_digit* m, sp_digit mp)
  633. {
  634. sp_2048_mul_17(r, a, b);
  635. sp_2048_mont_reduce_17(r, m, mp);
  636. }
  637. /* Square a and put result in r. (r = a * a)
  638. *
  639. * r A single precision integer.
  640. * a A single precision integer.
  641. */
  642. SP_NOINLINE static void sp_2048_sqr_17(sp_digit* r, const sp_digit* a)
  643. {
  644. int i;
  645. int imax;
  646. int k;
  647. sp_uint128 c;
  648. sp_uint128 t;
  649. c = ((sp_uint128)a[16]) * a[16];
  650. r[33] = (sp_digit)(c >> 61);
  651. c = (c & 0x1fffffffffffffffL) << 61;
  652. for (k = 31; k >= 0; k--) {
  653. i = (k + 1) / 2;
  654. if ((k & 1) == 0) {
  655. c += ((sp_uint128)a[i]) * a[i];
  656. i++;
  657. }
  658. if (k < 16) {
  659. imax = k;
  660. }
  661. else {
  662. imax = 16;
  663. }
  664. if (imax - i >= 14) {
  665. int imaxlo;
  666. sp_uint128 hi;
  667. hi = c >> 61;
  668. c &= 0x1fffffffffffffffL;
  669. for (imaxlo = i; imaxlo <= imax; imaxlo += 14) {
  670. t = 0;
  671. for (; i <= imax && i < imaxlo + 14; i++) {
  672. t += ((sp_uint128)a[i]) * a[k - i];
  673. }
  674. c += t * 2;
  675. hi += c >> 61;
  676. c &= 0x1fffffffffffffffL;
  677. }
  678. r[k + 2] += (sp_digit)(hi >> 61);
  679. r[k + 1] = (sp_digit)(hi & 0x1fffffffffffffffL);
  680. c <<= 61;
  681. }
  682. else
  683. {
  684. t = 0;
  685. for (; i <= imax; i++) {
  686. t += ((sp_uint128)a[i]) * a[k - i];
  687. }
  688. c += t * 2;
  689. r[k + 2] += (sp_digit) (c >> 122);
  690. r[k + 1] = (sp_digit)((c >> 61) & 0x1fffffffffffffffL);
  691. c = (c & 0x1fffffffffffffffL) << 61;
  692. }
  693. }
  694. r[0] = (sp_digit)(c >> 61);
  695. }
  696. /* Square the Montgomery form number. (r = a * a mod m)
  697. *
  698. * r Result of squaring.
  699. * a Number to square in Montgomery form.
  700. * m Modulus (prime).
  701. * mp Montgomery multiplier.
  702. */
  703. SP_NOINLINE static void sp_2048_mont_sqr_17(sp_digit* r, const sp_digit* a,
  704. const sp_digit* m, sp_digit mp)
  705. {
  706. sp_2048_sqr_17(r, a);
  707. sp_2048_mont_reduce_17(r, m, mp);
  708. }
  709. /* Multiply a by scalar b into r. (r = a * b)
  710. *
  711. * r A single precision integer.
  712. * a A single precision integer.
  713. * b A scalar.
  714. */
  715. SP_NOINLINE static void sp_2048_mul_d_17(sp_digit* r, const sp_digit* a,
  716. sp_digit b)
  717. {
  718. sp_int128 tb = b;
  719. sp_int128 t = 0;
  720. int i;
  721. for (i = 0; i < 17; i++) {
  722. t += tb * a[i];
  723. r[i] = (sp_digit)(t & 0x1fffffffffffffffL);
  724. t >>= 61;
  725. }
  726. r[17] = (sp_digit)t;
  727. }
  728. #ifdef WOLFSSL_SP_SMALL
  729. /* Conditionally add a and b using the mask m.
  730. * m is -1 to add and 0 when not.
  731. *
  732. * r A single precision number representing conditional add result.
  733. * a A single precision number to add with.
  734. * b A single precision number to add.
  735. * m Mask value to apply.
  736. */
  737. static void sp_2048_cond_add_17(sp_digit* r, const sp_digit* a,
  738. const sp_digit* b, const sp_digit m)
  739. {
  740. int i;
  741. for (i = 0; i < 17; i++) {
  742. r[i] = a[i] + (b[i] & m);
  743. }
  744. }
  745. #endif /* WOLFSSL_SP_SMALL */
  746. /* Add b to a into r. (r = a + b)
  747. *
  748. * r A single precision integer.
  749. * a A single precision integer.
  750. * b A single precision integer.
  751. */
  752. SP_NOINLINE static int sp_2048_add_17(sp_digit* r, const sp_digit* a,
  753. const sp_digit* b)
  754. {
  755. int i;
  756. for (i = 0; i < 17; i++) {
  757. r[i] = a[i] + b[i];
  758. }
  759. return 0;
  760. }
  761. SP_NOINLINE static void sp_2048_rshift_17(sp_digit* r, const sp_digit* a,
  762. byte n)
  763. {
  764. int i;
  765. for (i=0; i<16; i++) {
  766. r[i] = ((a[i] >> n) | (a[i + 1] << (61 - n))) & 0x1fffffffffffffffL;
  767. }
  768. r[16] = a[16] >> n;
  769. }
  770. static WC_INLINE sp_digit sp_2048_div_word_17(sp_digit d1, sp_digit d0,
  771. sp_digit div)
  772. {
  773. #ifdef SP_USE_DIVTI3
  774. sp_int128 d = ((sp_int128)d1 << 61) + d0;
  775. return d / div;
  776. #elif defined(__x86_64__) || defined(__i386__)
  777. sp_int128 d = ((sp_int128)d1 << 61) + d0;
  778. sp_uint64 lo = (sp_uint64)d;
  779. sp_digit hi = (sp_digit)(d >> 64);
  780. __asm__ __volatile__ (
  781. "idiv %2"
  782. : "+a" (lo)
  783. : "d" (hi), "r" (div)
  784. : "cc"
  785. );
  786. return (sp_digit)lo;
  787. #elif !defined(__aarch64__) && !defined(SP_DIV_WORD_USE_DIV)
  788. sp_int128 d = ((sp_int128)d1 << 61) + d0;
  789. sp_digit dv = (div >> 1) + 1;
  790. sp_digit t1 = (sp_digit)(d >> 61);
  791. sp_digit t0 = (sp_digit)(d & 0x1fffffffffffffffL);
  792. sp_digit t2;
  793. sp_digit sign;
  794. sp_digit r;
  795. int i;
  796. sp_int128 m;
  797. r = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  798. t1 -= dv & (0 - r);
  799. for (i = 59; i >= 1; i--) {
  800. t1 += t1 + (((sp_uint64)t0 >> 60) & 1);
  801. t0 <<= 1;
  802. t2 = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  803. r += r + t2;
  804. t1 -= dv & (0 - t2);
  805. t1 += t2;
  806. }
  807. r += r + 1;
  808. m = d - ((sp_int128)r * div);
  809. r += (sp_digit)(m >> 61);
  810. m = d - ((sp_int128)r * div);
  811. r += (sp_digit)(m >> 122) - (sp_digit)(d >> 122);
  812. m = d - ((sp_int128)r * div);
  813. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  814. m *= sign;
  815. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  816. r += sign * t2;
  817. m = d - ((sp_int128)r * div);
  818. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  819. m *= sign;
  820. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  821. r += sign * t2;
  822. return r;
  823. #else
  824. sp_int128 d = ((sp_int128)d1 << 61) + d0;
  825. sp_digit r = 0;
  826. sp_digit t;
  827. sp_digit dv = (div >> 30) + 1;
  828. t = (sp_digit)(d >> 60);
  829. t = (t / dv) << 30;
  830. r += t;
  831. d -= (sp_int128)t * div;
  832. t = (sp_digit)(d >> 29);
  833. t = t / (dv << 1);
  834. r += t;
  835. d -= (sp_int128)t * div;
  836. t = (sp_digit)d;
  837. t = t / div;
  838. r += t;
  839. d -= (sp_int128)t * div;
  840. return r;
  841. #endif
  842. }
  843. static WC_INLINE sp_digit sp_2048_word_div_word_17(sp_digit d, sp_digit div)
  844. {
  845. #if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \
  846. defined(SP_DIV_WORD_USE_DIV)
  847. return d / div;
  848. #else
  849. return (sp_digit)((sp_uint64)(div - d) >> 63);
  850. #endif
  851. }
  852. /* Divide d in a and put remainder into r (m*d + r = a)
  853. * m is not calculated as it is not needed at this time.
  854. *
  855. * Full implementation.
  856. *
  857. * a Number to be divided.
  858. * d Number to divide with.
  859. * m Multiplier result.
  860. * r Remainder from the division.
  861. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  862. */
  863. static int sp_2048_div_17(const sp_digit* a, const sp_digit* d,
  864. const sp_digit* m, sp_digit* r)
  865. {
  866. int i;
  867. #ifndef WOLFSSL_SP_DIV_64
  868. #endif
  869. sp_digit dv;
  870. sp_digit r1;
  871. #ifdef WOLFSSL_SP_SMALL_STACK
  872. sp_digit* t1 = NULL;
  873. #else
  874. sp_digit t1[4 * 17 + 3];
  875. #endif
  876. sp_digit* t2 = NULL;
  877. sp_digit* sd = NULL;
  878. int err = MP_OKAY;
  879. (void)m;
  880. #ifdef WOLFSSL_SP_SMALL_STACK
  881. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 17 + 3), NULL,
  882. DYNAMIC_TYPE_TMP_BUFFER);
  883. if (t1 == NULL)
  884. err = MEMORY_E;
  885. #endif
  886. (void)m;
  887. if (err == MP_OKAY) {
  888. t2 = t1 + 34 + 1;
  889. sd = t2 + 17 + 1;
  890. sp_2048_mul_d_17(sd, d, (sp_digit)1 << 13);
  891. sp_2048_mul_d_34(t1, a, (sp_digit)1 << 13);
  892. dv = sd[16];
  893. t1[17 + 17] += t1[17 + 17 - 1] >> 61;
  894. t1[17 + 17 - 1] &= 0x1fffffffffffffffL;
  895. for (i=17; i>=0; i--) {
  896. r1 = sp_2048_div_word_17(t1[17 + i], t1[17 + i - 1], dv);
  897. sp_2048_mul_d_17(t2, sd, r1);
  898. (void)sp_2048_sub_17(&t1[i], &t1[i], t2);
  899. sp_2048_norm_17(&t1[i]);
  900. t1[17 + i] -= t2[17];
  901. t1[17 + i] += t1[17 + i - 1] >> 61;
  902. t1[17 + i - 1] &= 0x1fffffffffffffffL;
  903. r1 = sp_2048_div_word_17(-t1[17 + i], -t1[17 + i - 1], dv);
  904. r1 -= t1[17 + i];
  905. sp_2048_mul_d_17(t2, sd, r1);
  906. (void)sp_2048_add_17(&t1[i], &t1[i], t2);
  907. t1[17 + i] += t1[17 + i - 1] >> 61;
  908. t1[17 + i - 1] &= 0x1fffffffffffffffL;
  909. }
  910. t1[17 - 1] += t1[17 - 2] >> 61;
  911. t1[17 - 2] &= 0x1fffffffffffffffL;
  912. r1 = sp_2048_word_div_word_17(t1[17 - 1], dv);
  913. sp_2048_mul_d_17(t2, sd, r1);
  914. sp_2048_sub_17(t1, t1, t2);
  915. XMEMCPY(r, t1, sizeof(*r) * 34U);
  916. for (i=0; i<16; i++) {
  917. r[i+1] += r[i] >> 61;
  918. r[i] &= 0x1fffffffffffffffL;
  919. }
  920. sp_2048_cond_add_17(r, r, sd, r[16] >> 63);
  921. sp_2048_norm_17(r);
  922. sp_2048_rshift_17(r, r, 13);
  923. }
  924. #ifdef WOLFSSL_SP_SMALL_STACK
  925. if (t1 != NULL)
  926. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  927. #endif
  928. return err;
  929. }
  930. /* Reduce a modulo m into r. (r = a mod m)
  931. *
  932. * r A single precision number that is the reduced result.
  933. * a A single precision number that is to be reduced.
  934. * m A single precision number that is the modulus to reduce with.
  935. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  936. */
  937. static int sp_2048_mod_17(sp_digit* r, const sp_digit* a, const sp_digit* m)
  938. {
  939. return sp_2048_div_17(a, m, NULL, r);
  940. }
  941. /* Modular exponentiate a to the e mod m. (r = a^e mod m)
  942. *
  943. * r A single precision number that is the result of the operation.
  944. * a A single precision number being exponentiated.
  945. * e A single precision number that is the exponent.
  946. * bits The number of bits in the exponent.
  947. * m A single precision number that is the modulus.
  948. * returns 0 on success.
  949. * returns MEMORY_E on dynamic memory allocation failure.
  950. * returns MP_VAL when base is even or exponent is 0.
  951. */
  952. static int sp_2048_mod_exp_17(sp_digit* r, const sp_digit* a, const sp_digit* e,
  953. int bits, const sp_digit* m, int reduceA)
  954. {
  955. #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
  956. #ifdef WOLFSSL_SP_SMALL_STACK
  957. sp_digit* td = NULL;
  958. #else
  959. sp_digit td[3 * 34];
  960. #endif
  961. sp_digit* t[3] = {0, 0, 0};
  962. sp_digit* norm = NULL;
  963. sp_digit mp = 1;
  964. sp_digit n;
  965. int i;
  966. int c;
  967. byte y;
  968. int err = MP_OKAY;
  969. if (bits == 0) {
  970. err = MP_VAL;
  971. }
  972. #ifdef WOLFSSL_SP_SMALL_STACK
  973. if (err == MP_OKAY) {
  974. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 17 * 2, NULL,
  975. DYNAMIC_TYPE_TMP_BUFFER);
  976. if (td == NULL)
  977. err = MEMORY_E;
  978. }
  979. #endif
  980. if (err == MP_OKAY) {
  981. norm = td;
  982. for (i=0; i<3; i++) {
  983. t[i] = td + (i * 17 * 2);
  984. XMEMSET(t[i], 0, sizeof(sp_digit) * 17U * 2U);
  985. }
  986. sp_2048_mont_setup(m, &mp);
  987. sp_2048_mont_norm_17(norm, m);
  988. if (reduceA != 0) {
  989. err = sp_2048_mod_17(t[1], a, m);
  990. }
  991. else {
  992. XMEMCPY(t[1], a, sizeof(sp_digit) * 17U);
  993. }
  994. }
  995. if (err == MP_OKAY) {
  996. sp_2048_mul_17(t[1], t[1], norm);
  997. err = sp_2048_mod_17(t[1], t[1], m);
  998. }
  999. if (err == MP_OKAY) {
  1000. i = bits / 61;
  1001. c = bits % 61;
  1002. n = e[i--] << (61 - c);
  1003. for (; ; c--) {
  1004. if (c == 0) {
  1005. if (i == -1) {
  1006. break;
  1007. }
  1008. n = e[i--];
  1009. c = 61;
  1010. }
  1011. y = (int)((n >> 60) & 1);
  1012. n <<= 1;
  1013. sp_2048_mont_mul_17(t[y^1], t[0], t[1], m, mp);
  1014. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  1015. ((size_t)t[1] & addr_mask[y])),
  1016. sizeof(*t[2]) * 17 * 2);
  1017. sp_2048_mont_sqr_17(t[2], t[2], m, mp);
  1018. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  1019. ((size_t)t[1] & addr_mask[y])), t[2],
  1020. sizeof(*t[2]) * 17 * 2);
  1021. }
  1022. sp_2048_mont_reduce_17(t[0], m, mp);
  1023. n = sp_2048_cmp_17(t[0], m);
  1024. sp_2048_cond_sub_17(t[0], t[0], m, ~(n >> 63));
  1025. XMEMCPY(r, t[0], sizeof(*r) * 17 * 2);
  1026. }
  1027. #ifdef WOLFSSL_SP_SMALL_STACK
  1028. if (td != NULL)
  1029. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1030. #endif
  1031. return err;
  1032. #elif !defined(WC_NO_CACHE_RESISTANT)
  1033. #ifdef WOLFSSL_SP_SMALL_STACK
  1034. sp_digit* td = NULL;
  1035. #else
  1036. sp_digit td[3 * 34];
  1037. #endif
  1038. sp_digit* t[3] = {0, 0, 0};
  1039. sp_digit* norm = NULL;
  1040. sp_digit mp = 1;
  1041. sp_digit n;
  1042. int i;
  1043. int c;
  1044. byte y;
  1045. int err = MP_OKAY;
  1046. if (bits == 0) {
  1047. err = MP_VAL;
  1048. }
  1049. #ifdef WOLFSSL_SP_SMALL_STACK
  1050. if (err == MP_OKAY) {
  1051. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 17 * 2, NULL,
  1052. DYNAMIC_TYPE_TMP_BUFFER);
  1053. if (td == NULL)
  1054. err = MEMORY_E;
  1055. }
  1056. #endif
  1057. if (err == MP_OKAY) {
  1058. norm = td;
  1059. for (i=0; i<3; i++) {
  1060. t[i] = td + (i * 17 * 2);
  1061. }
  1062. sp_2048_mont_setup(m, &mp);
  1063. sp_2048_mont_norm_17(norm, m);
  1064. if (reduceA != 0) {
  1065. err = sp_2048_mod_17(t[1], a, m);
  1066. if (err == MP_OKAY) {
  1067. sp_2048_mul_17(t[1], t[1], norm);
  1068. err = sp_2048_mod_17(t[1], t[1], m);
  1069. }
  1070. }
  1071. else {
  1072. sp_2048_mul_17(t[1], a, norm);
  1073. err = sp_2048_mod_17(t[1], t[1], m);
  1074. }
  1075. }
  1076. if (err == MP_OKAY) {
  1077. i = bits / 61;
  1078. c = bits % 61;
  1079. n = e[i--] << (61 - c);
  1080. for (; ; c--) {
  1081. if (c == 0) {
  1082. if (i == -1) {
  1083. break;
  1084. }
  1085. n = e[i--];
  1086. c = 61;
  1087. }
  1088. y = (int)((n >> 60) & 1);
  1089. n <<= 1;
  1090. sp_2048_mont_mul_17(t[y^1], t[0], t[1], m, mp);
  1091. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  1092. ((size_t)t[1] & addr_mask[y])),
  1093. sizeof(*t[2]) * 17 * 2);
  1094. sp_2048_mont_sqr_17(t[2], t[2], m, mp);
  1095. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  1096. ((size_t)t[1] & addr_mask[y])), t[2],
  1097. sizeof(*t[2]) * 17 * 2);
  1098. }
  1099. sp_2048_mont_reduce_17(t[0], m, mp);
  1100. n = sp_2048_cmp_17(t[0], m);
  1101. sp_2048_cond_sub_17(t[0], t[0], m, ~(n >> 63));
  1102. XMEMCPY(r, t[0], sizeof(*r) * 17 * 2);
  1103. }
  1104. #ifdef WOLFSSL_SP_SMALL_STACK
  1105. if (td != NULL)
  1106. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1107. #endif
  1108. return err;
  1109. #else
  1110. #ifdef WOLFSSL_SP_SMALL_STACK
  1111. sp_digit* td = NULL;
  1112. #else
  1113. sp_digit td[(32 * 34) + 34];
  1114. #endif
  1115. sp_digit* t[32];
  1116. sp_digit* rt = NULL;
  1117. sp_digit* norm = NULL;
  1118. sp_digit mp = 1;
  1119. sp_digit n;
  1120. int i;
  1121. int c;
  1122. byte y;
  1123. int err = MP_OKAY;
  1124. if (bits == 0) {
  1125. err = MP_VAL;
  1126. }
  1127. #ifdef WOLFSSL_SP_SMALL_STACK
  1128. if (err == MP_OKAY) {
  1129. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((32 * 34) + 34), NULL,
  1130. DYNAMIC_TYPE_TMP_BUFFER);
  1131. if (td == NULL)
  1132. err = MEMORY_E;
  1133. }
  1134. #endif
  1135. if (err == MP_OKAY) {
  1136. norm = td;
  1137. for (i=0; i<32; i++)
  1138. t[i] = td + i * 34;
  1139. rt = td + 1088;
  1140. sp_2048_mont_setup(m, &mp);
  1141. sp_2048_mont_norm_17(norm, m);
  1142. if (reduceA != 0) {
  1143. err = sp_2048_mod_17(t[1], a, m);
  1144. if (err == MP_OKAY) {
  1145. sp_2048_mul_17(t[1], t[1], norm);
  1146. err = sp_2048_mod_17(t[1], t[1], m);
  1147. }
  1148. }
  1149. else {
  1150. sp_2048_mul_17(t[1], a, norm);
  1151. err = sp_2048_mod_17(t[1], t[1], m);
  1152. }
  1153. }
  1154. if (err == MP_OKAY) {
  1155. sp_2048_mont_sqr_17(t[ 2], t[ 1], m, mp);
  1156. sp_2048_mont_mul_17(t[ 3], t[ 2], t[ 1], m, mp);
  1157. sp_2048_mont_sqr_17(t[ 4], t[ 2], m, mp);
  1158. sp_2048_mont_mul_17(t[ 5], t[ 3], t[ 2], m, mp);
  1159. sp_2048_mont_sqr_17(t[ 6], t[ 3], m, mp);
  1160. sp_2048_mont_mul_17(t[ 7], t[ 4], t[ 3], m, mp);
  1161. sp_2048_mont_sqr_17(t[ 8], t[ 4], m, mp);
  1162. sp_2048_mont_mul_17(t[ 9], t[ 5], t[ 4], m, mp);
  1163. sp_2048_mont_sqr_17(t[10], t[ 5], m, mp);
  1164. sp_2048_mont_mul_17(t[11], t[ 6], t[ 5], m, mp);
  1165. sp_2048_mont_sqr_17(t[12], t[ 6], m, mp);
  1166. sp_2048_mont_mul_17(t[13], t[ 7], t[ 6], m, mp);
  1167. sp_2048_mont_sqr_17(t[14], t[ 7], m, mp);
  1168. sp_2048_mont_mul_17(t[15], t[ 8], t[ 7], m, mp);
  1169. sp_2048_mont_sqr_17(t[16], t[ 8], m, mp);
  1170. sp_2048_mont_mul_17(t[17], t[ 9], t[ 8], m, mp);
  1171. sp_2048_mont_sqr_17(t[18], t[ 9], m, mp);
  1172. sp_2048_mont_mul_17(t[19], t[10], t[ 9], m, mp);
  1173. sp_2048_mont_sqr_17(t[20], t[10], m, mp);
  1174. sp_2048_mont_mul_17(t[21], t[11], t[10], m, mp);
  1175. sp_2048_mont_sqr_17(t[22], t[11], m, mp);
  1176. sp_2048_mont_mul_17(t[23], t[12], t[11], m, mp);
  1177. sp_2048_mont_sqr_17(t[24], t[12], m, mp);
  1178. sp_2048_mont_mul_17(t[25], t[13], t[12], m, mp);
  1179. sp_2048_mont_sqr_17(t[26], t[13], m, mp);
  1180. sp_2048_mont_mul_17(t[27], t[14], t[13], m, mp);
  1181. sp_2048_mont_sqr_17(t[28], t[14], m, mp);
  1182. sp_2048_mont_mul_17(t[29], t[15], t[14], m, mp);
  1183. sp_2048_mont_sqr_17(t[30], t[15], m, mp);
  1184. sp_2048_mont_mul_17(t[31], t[16], t[15], m, mp);
  1185. bits = ((bits + 4) / 5) * 5;
  1186. i = ((bits + 60) / 61) - 1;
  1187. c = bits % 61;
  1188. if (c == 0) {
  1189. c = 61;
  1190. }
  1191. if (i < 17) {
  1192. n = e[i--] << (64 - c);
  1193. }
  1194. else {
  1195. n = 0;
  1196. i--;
  1197. }
  1198. if (c < 5) {
  1199. n |= e[i--] << (3 - c);
  1200. c += 61;
  1201. }
  1202. y = (int)((n >> 59) & 0x1f);
  1203. n <<= 5;
  1204. c -= 5;
  1205. XMEMCPY(rt, t[y], sizeof(sp_digit) * 34);
  1206. while ((i >= 0) || (c >= 5)) {
  1207. if (c >= 5) {
  1208. y = (byte)((n >> 59) & 0x1f);
  1209. n <<= 5;
  1210. c -= 5;
  1211. }
  1212. else if (c == 0) {
  1213. n = e[i--] << 3;
  1214. y = (byte)((n >> 59) & 0x1f);
  1215. n <<= 5;
  1216. c = 56;
  1217. }
  1218. else {
  1219. y = (byte)((n >> 59) & 0x1f);
  1220. n = e[i--] << 3;
  1221. c = 5 - c;
  1222. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  1223. n <<= c;
  1224. c = 61 - c;
  1225. }
  1226. sp_2048_mont_sqr_17(rt, rt, m, mp);
  1227. sp_2048_mont_sqr_17(rt, rt, m, mp);
  1228. sp_2048_mont_sqr_17(rt, rt, m, mp);
  1229. sp_2048_mont_sqr_17(rt, rt, m, mp);
  1230. sp_2048_mont_sqr_17(rt, rt, m, mp);
  1231. sp_2048_mont_mul_17(rt, rt, t[y], m, mp);
  1232. }
  1233. sp_2048_mont_reduce_17(rt, m, mp);
  1234. n = sp_2048_cmp_17(rt, m);
  1235. sp_2048_cond_sub_17(rt, rt, m, ~(n >> 63));
  1236. XMEMCPY(r, rt, sizeof(sp_digit) * 34);
  1237. }
  1238. #ifdef WOLFSSL_SP_SMALL_STACK
  1239. if (td != NULL)
  1240. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1241. #endif
  1242. return err;
  1243. #endif
  1244. }
  1245. #endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */
  1246. /* Sub b from a into r. (r = a - b)
  1247. *
  1248. * r A single precision integer.
  1249. * a A single precision integer.
  1250. * b A single precision integer.
  1251. */
  1252. SP_NOINLINE static int sp_2048_sub_34(sp_digit* r, const sp_digit* a,
  1253. const sp_digit* b)
  1254. {
  1255. int i;
  1256. for (i = 0; i < 34; i++) {
  1257. r[i] = a[i] - b[i];
  1258. }
  1259. return 0;
  1260. }
  1261. /* r = 2^n mod m where n is the number of bits to reduce by.
  1262. * Given m must be 2048 bits, just need to subtract.
  1263. *
  1264. * r A single precision number.
  1265. * m A single precision number.
  1266. */
  1267. static void sp_2048_mont_norm_34(sp_digit* r, const sp_digit* m)
  1268. {
  1269. /* Set r = 2^n - 1. */
  1270. int i;
  1271. for (i=0; i<33; i++) {
  1272. r[i] = 0x1fffffffffffffffL;
  1273. }
  1274. r[33] = 0x7ffffffffL;
  1275. /* r = (2^n - 1) mod n */
  1276. (void)sp_2048_sub_34(r, r, m);
  1277. /* Add one so r = 2^n mod m */
  1278. r[0] += 1;
  1279. }
  1280. /* Compare a with b in constant time.
  1281. *
  1282. * a A single precision integer.
  1283. * b A single precision integer.
  1284. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  1285. * respectively.
  1286. */
  1287. static sp_digit sp_2048_cmp_34(const sp_digit* a, const sp_digit* b)
  1288. {
  1289. sp_digit r = 0;
  1290. int i;
  1291. for (i=33; i>=0; i--) {
  1292. r |= (a[i] - b[i]) & ~(((sp_digit)0 - r) >> 60);
  1293. }
  1294. return r;
  1295. }
  1296. /* Conditionally subtract b from a using the mask m.
  1297. * m is -1 to subtract and 0 when not.
  1298. *
  1299. * r A single precision number representing condition subtract result.
  1300. * a A single precision number to subtract from.
  1301. * b A single precision number to subtract.
  1302. * m Mask value to apply.
  1303. */
  1304. static void sp_2048_cond_sub_34(sp_digit* r, const sp_digit* a,
  1305. const sp_digit* b, const sp_digit m)
  1306. {
  1307. int i;
  1308. for (i = 0; i < 34; i++) {
  1309. r[i] = a[i] - (b[i] & m);
  1310. }
  1311. }
  1312. /* Mul a by scalar b and add into r. (r += a * b)
  1313. *
  1314. * r A single precision integer.
  1315. * a A single precision integer.
  1316. * b A scalar.
  1317. */
  1318. SP_NOINLINE static void sp_2048_mul_add_34(sp_digit* r, const sp_digit* a,
  1319. const sp_digit b)
  1320. {
  1321. sp_int128 tb = b;
  1322. sp_int128 t[4];
  1323. int i;
  1324. t[0] = 0;
  1325. for (i = 0; i < 32; i += 4) {
  1326. t[0] += (tb * a[i+0]) + r[i+0];
  1327. t[1] = (tb * a[i+1]) + r[i+1];
  1328. t[2] = (tb * a[i+2]) + r[i+2];
  1329. t[3] = (tb * a[i+3]) + r[i+3];
  1330. r[i+0] = t[0] & 0x1fffffffffffffffL;
  1331. t[1] += t[0] >> 61;
  1332. r[i+1] = t[1] & 0x1fffffffffffffffL;
  1333. t[2] += t[1] >> 61;
  1334. r[i+2] = t[2] & 0x1fffffffffffffffL;
  1335. t[3] += t[2] >> 61;
  1336. r[i+3] = t[3] & 0x1fffffffffffffffL;
  1337. t[0] = t[3] >> 61;
  1338. }
  1339. t[0] += (tb * a[32]) + r[32];
  1340. t[1] = (tb * a[33]) + r[33];
  1341. r[32] = t[0] & 0x1fffffffffffffffL;
  1342. t[1] += t[0] >> 61;
  1343. r[33] = t[1] & 0x1fffffffffffffffL;
  1344. r[34] += (sp_digit)(t[1] >> 61);
  1345. }
  1346. /* Shift the result in the high 2048 bits down to the bottom.
  1347. *
  1348. * r A single precision number.
  1349. * a A single precision number.
  1350. */
  1351. static void sp_2048_mont_shift_34(sp_digit* r, const sp_digit* a)
  1352. {
  1353. int i;
  1354. sp_int128 n = a[33] >> 35;
  1355. n += ((sp_int128)a[34]) << 26;
  1356. for (i = 0; i < 33; i++) {
  1357. r[i] = n & 0x1fffffffffffffffL;
  1358. n >>= 61;
  1359. n += ((sp_int128)a[35 + i]) << 26;
  1360. }
  1361. r[33] = (sp_digit)n;
  1362. XMEMSET(&r[34], 0, sizeof(*r) * 34U);
  1363. }
  1364. /* Reduce the number back to 2048 bits using Montgomery reduction.
  1365. *
  1366. * a A single precision number to reduce in place.
  1367. * m The single precision number representing the modulus.
  1368. * mp The digit representing the negative inverse of m mod 2^n.
  1369. */
  1370. static void sp_2048_mont_reduce_34(sp_digit* a, const sp_digit* m, sp_digit mp)
  1371. {
  1372. int i;
  1373. sp_digit mu;
  1374. sp_digit over;
  1375. sp_2048_norm_34(a + 34);
  1376. #ifdef WOLFSSL_SP_DH
  1377. if (mp != 1) {
  1378. for (i=0; i<33; i++) {
  1379. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1fffffffffffffffL;
  1380. sp_2048_mul_add_34(a+i, m, mu);
  1381. a[i+1] += a[i] >> 61;
  1382. }
  1383. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x7ffffffffL;
  1384. sp_2048_mul_add_34(a+i, m, mu);
  1385. a[i+1] += a[i] >> 61;
  1386. a[i] &= 0x1fffffffffffffffL;
  1387. }
  1388. else {
  1389. for (i=0; i<33; i++) {
  1390. mu = a[i] & 0x1fffffffffffffffL;
  1391. sp_2048_mul_add_34(a+i, m, mu);
  1392. a[i+1] += a[i] >> 61;
  1393. }
  1394. mu = a[i] & 0x7ffffffffL;
  1395. sp_2048_mul_add_34(a+i, m, mu);
  1396. a[i+1] += a[i] >> 61;
  1397. a[i] &= 0x1fffffffffffffffL;
  1398. }
  1399. #else
  1400. for (i=0; i<33; i++) {
  1401. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1fffffffffffffffL;
  1402. sp_2048_mul_add_34(a+i, m, mu);
  1403. a[i+1] += a[i] >> 61;
  1404. }
  1405. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x7ffffffffL;
  1406. sp_2048_mul_add_34(a+i, m, mu);
  1407. a[i+1] += a[i] >> 61;
  1408. a[i] &= 0x1fffffffffffffffL;
  1409. #endif
  1410. sp_2048_mont_shift_34(a, a);
  1411. over = a[33] - m[33];
  1412. sp_2048_cond_sub_34(a, a, m, ~((over - 1) >> 63));
  1413. sp_2048_norm_34(a);
  1414. }
  1415. /* Multiply two Montgomery form numbers mod the modulus (prime).
  1416. * (r = a * b mod m)
  1417. *
  1418. * r Result of multiplication.
  1419. * a First number to multiply in Montgomery form.
  1420. * b Second number to multiply in Montgomery form.
  1421. * m Modulus (prime).
  1422. * mp Montgomery multiplier.
  1423. */
  1424. SP_NOINLINE static void sp_2048_mont_mul_34(sp_digit* r, const sp_digit* a,
  1425. const sp_digit* b, const sp_digit* m, sp_digit mp)
  1426. {
  1427. sp_2048_mul_34(r, a, b);
  1428. sp_2048_mont_reduce_34(r, m, mp);
  1429. }
  1430. /* Square the Montgomery form number. (r = a * a mod m)
  1431. *
  1432. * r Result of squaring.
  1433. * a Number to square in Montgomery form.
  1434. * m Modulus (prime).
  1435. * mp Montgomery multiplier.
  1436. */
  1437. SP_NOINLINE static void sp_2048_mont_sqr_34(sp_digit* r, const sp_digit* a,
  1438. const sp_digit* m, sp_digit mp)
  1439. {
  1440. sp_2048_sqr_34(r, a);
  1441. sp_2048_mont_reduce_34(r, m, mp);
  1442. }
  1443. /* Multiply a by scalar b into r. (r = a * b)
  1444. *
  1445. * r A single precision integer.
  1446. * a A single precision integer.
  1447. * b A scalar.
  1448. */
  1449. SP_NOINLINE static void sp_2048_mul_d_68(sp_digit* r, const sp_digit* a,
  1450. sp_digit b)
  1451. {
  1452. sp_int128 tb = b;
  1453. sp_int128 t = 0;
  1454. int i;
  1455. for (i = 0; i < 68; i++) {
  1456. t += tb * a[i];
  1457. r[i] = (sp_digit)(t & 0x1fffffffffffffffL);
  1458. t >>= 61;
  1459. }
  1460. r[68] = (sp_digit)t;
  1461. }
  1462. #ifdef WOLFSSL_SP_SMALL
  1463. /* Conditionally add a and b using the mask m.
  1464. * m is -1 to add and 0 when not.
  1465. *
  1466. * r A single precision number representing conditional add result.
  1467. * a A single precision number to add with.
  1468. * b A single precision number to add.
  1469. * m Mask value to apply.
  1470. */
  1471. static void sp_2048_cond_add_34(sp_digit* r, const sp_digit* a,
  1472. const sp_digit* b, const sp_digit m)
  1473. {
  1474. int i;
  1475. for (i = 0; i < 34; i++) {
  1476. r[i] = a[i] + (b[i] & m);
  1477. }
  1478. }
  1479. #endif /* WOLFSSL_SP_SMALL */
  1480. /* Add b to a into r. (r = a + b)
  1481. *
  1482. * r A single precision integer.
  1483. * a A single precision integer.
  1484. * b A single precision integer.
  1485. */
  1486. SP_NOINLINE static int sp_2048_add_34(sp_digit* r, const sp_digit* a,
  1487. const sp_digit* b)
  1488. {
  1489. int i;
  1490. for (i = 0; i < 34; i++) {
  1491. r[i] = a[i] + b[i];
  1492. }
  1493. return 0;
  1494. }
  1495. SP_NOINLINE static void sp_2048_rshift_34(sp_digit* r, const sp_digit* a,
  1496. byte n)
  1497. {
  1498. int i;
  1499. for (i=0; i<33; i++) {
  1500. r[i] = ((a[i] >> n) | (a[i + 1] << (61 - n))) & 0x1fffffffffffffffL;
  1501. }
  1502. r[33] = a[33] >> n;
  1503. }
  1504. static WC_INLINE sp_digit sp_2048_div_word_34(sp_digit d1, sp_digit d0,
  1505. sp_digit div)
  1506. {
  1507. #ifdef SP_USE_DIVTI3
  1508. sp_int128 d = ((sp_int128)d1 << 61) + d0;
  1509. return d / div;
  1510. #elif defined(__x86_64__) || defined(__i386__)
  1511. sp_int128 d = ((sp_int128)d1 << 61) + d0;
  1512. sp_uint64 lo = (sp_uint64)d;
  1513. sp_digit hi = (sp_digit)(d >> 64);
  1514. __asm__ __volatile__ (
  1515. "idiv %2"
  1516. : "+a" (lo)
  1517. : "d" (hi), "r" (div)
  1518. : "cc"
  1519. );
  1520. return (sp_digit)lo;
  1521. #elif !defined(__aarch64__) && !defined(SP_DIV_WORD_USE_DIV)
  1522. sp_int128 d = ((sp_int128)d1 << 61) + d0;
  1523. sp_digit dv = (div >> 1) + 1;
  1524. sp_digit t1 = (sp_digit)(d >> 61);
  1525. sp_digit t0 = (sp_digit)(d & 0x1fffffffffffffffL);
  1526. sp_digit t2;
  1527. sp_digit sign;
  1528. sp_digit r;
  1529. int i;
  1530. sp_int128 m;
  1531. r = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  1532. t1 -= dv & (0 - r);
  1533. for (i = 59; i >= 1; i--) {
  1534. t1 += t1 + (((sp_uint64)t0 >> 60) & 1);
  1535. t0 <<= 1;
  1536. t2 = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  1537. r += r + t2;
  1538. t1 -= dv & (0 - t2);
  1539. t1 += t2;
  1540. }
  1541. r += r + 1;
  1542. m = d - ((sp_int128)r * div);
  1543. r += (sp_digit)(m >> 61);
  1544. m = d - ((sp_int128)r * div);
  1545. r += (sp_digit)(m >> 122) - (sp_digit)(d >> 122);
  1546. m = d - ((sp_int128)r * div);
  1547. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  1548. m *= sign;
  1549. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  1550. r += sign * t2;
  1551. m = d - ((sp_int128)r * div);
  1552. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  1553. m *= sign;
  1554. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  1555. r += sign * t2;
  1556. return r;
  1557. #else
  1558. sp_int128 d = ((sp_int128)d1 << 61) + d0;
  1559. sp_digit r = 0;
  1560. sp_digit t;
  1561. sp_digit dv = (div >> 30) + 1;
  1562. t = (sp_digit)(d >> 60);
  1563. t = (t / dv) << 30;
  1564. r += t;
  1565. d -= (sp_int128)t * div;
  1566. t = (sp_digit)(d >> 29);
  1567. t = t / (dv << 1);
  1568. r += t;
  1569. d -= (sp_int128)t * div;
  1570. t = (sp_digit)d;
  1571. t = t / div;
  1572. r += t;
  1573. d -= (sp_int128)t * div;
  1574. return r;
  1575. #endif
  1576. }
  1577. static WC_INLINE sp_digit sp_2048_word_div_word_34(sp_digit d, sp_digit div)
  1578. {
  1579. #if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \
  1580. defined(SP_DIV_WORD_USE_DIV)
  1581. return d / div;
  1582. #else
  1583. return (sp_digit)((sp_uint64)(div - d) >> 63);
  1584. #endif
  1585. }
  1586. /* Divide d in a and put remainder into r (m*d + r = a)
  1587. * m is not calculated as it is not needed at this time.
  1588. *
  1589. * Full implementation.
  1590. *
  1591. * a Number to be divided.
  1592. * d Number to divide with.
  1593. * m Multiplier result.
  1594. * r Remainder from the division.
  1595. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  1596. */
  1597. static int sp_2048_div_34(const sp_digit* a, const sp_digit* d,
  1598. const sp_digit* m, sp_digit* r)
  1599. {
  1600. int i;
  1601. #ifndef WOLFSSL_SP_DIV_64
  1602. #endif
  1603. sp_digit dv;
  1604. sp_digit r1;
  1605. #ifdef WOLFSSL_SP_SMALL_STACK
  1606. sp_digit* t1 = NULL;
  1607. #else
  1608. sp_digit t1[4 * 34 + 3];
  1609. #endif
  1610. sp_digit* t2 = NULL;
  1611. sp_digit* sd = NULL;
  1612. int err = MP_OKAY;
  1613. (void)m;
  1614. #ifdef WOLFSSL_SP_SMALL_STACK
  1615. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 34 + 3), NULL,
  1616. DYNAMIC_TYPE_TMP_BUFFER);
  1617. if (t1 == NULL)
  1618. err = MEMORY_E;
  1619. #endif
  1620. (void)m;
  1621. if (err == MP_OKAY) {
  1622. t2 = t1 + 68 + 1;
  1623. sd = t2 + 34 + 1;
  1624. sp_2048_mul_d_34(sd, d, (sp_digit)1 << 26);
  1625. sp_2048_mul_d_68(t1, a, (sp_digit)1 << 26);
  1626. dv = sd[33];
  1627. t1[34 + 34] += t1[34 + 34 - 1] >> 61;
  1628. t1[34 + 34 - 1] &= 0x1fffffffffffffffL;
  1629. for (i=34; i>=0; i--) {
  1630. r1 = sp_2048_div_word_34(t1[34 + i], t1[34 + i - 1], dv);
  1631. sp_2048_mul_d_34(t2, sd, r1);
  1632. (void)sp_2048_sub_34(&t1[i], &t1[i], t2);
  1633. sp_2048_norm_34(&t1[i]);
  1634. t1[34 + i] -= t2[34];
  1635. t1[34 + i] += t1[34 + i - 1] >> 61;
  1636. t1[34 + i - 1] &= 0x1fffffffffffffffL;
  1637. r1 = sp_2048_div_word_34(-t1[34 + i], -t1[34 + i - 1], dv);
  1638. r1 -= t1[34 + i];
  1639. sp_2048_mul_d_34(t2, sd, r1);
  1640. (void)sp_2048_add_34(&t1[i], &t1[i], t2);
  1641. t1[34 + i] += t1[34 + i - 1] >> 61;
  1642. t1[34 + i - 1] &= 0x1fffffffffffffffL;
  1643. }
  1644. t1[34 - 1] += t1[34 - 2] >> 61;
  1645. t1[34 - 2] &= 0x1fffffffffffffffL;
  1646. r1 = sp_2048_word_div_word_34(t1[34 - 1], dv);
  1647. sp_2048_mul_d_34(t2, sd, r1);
  1648. sp_2048_sub_34(t1, t1, t2);
  1649. XMEMCPY(r, t1, sizeof(*r) * 68U);
  1650. for (i=0; i<33; i++) {
  1651. r[i+1] += r[i] >> 61;
  1652. r[i] &= 0x1fffffffffffffffL;
  1653. }
  1654. sp_2048_cond_add_34(r, r, sd, r[33] >> 63);
  1655. sp_2048_norm_34(r);
  1656. sp_2048_rshift_34(r, r, 26);
  1657. }
  1658. #ifdef WOLFSSL_SP_SMALL_STACK
  1659. if (t1 != NULL)
  1660. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1661. #endif
  1662. return err;
  1663. }
  1664. /* Reduce a modulo m into r. (r = a mod m)
  1665. *
  1666. * r A single precision number that is the reduced result.
  1667. * a A single precision number that is to be reduced.
  1668. * m A single precision number that is the modulus to reduce with.
  1669. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  1670. */
  1671. static int sp_2048_mod_34(sp_digit* r, const sp_digit* a, const sp_digit* m)
  1672. {
  1673. return sp_2048_div_34(a, m, NULL, r);
  1674. }
  1675. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  1676. /* Modular exponentiate a to the e mod m. (r = a^e mod m)
  1677. *
  1678. * r A single precision number that is the result of the operation.
  1679. * a A single precision number being exponentiated.
  1680. * e A single precision number that is the exponent.
  1681. * bits The number of bits in the exponent.
  1682. * m A single precision number that is the modulus.
  1683. * returns 0 on success.
  1684. * returns MEMORY_E on dynamic memory allocation failure.
  1685. * returns MP_VAL when base is even or exponent is 0.
  1686. */
  1687. static int sp_2048_mod_exp_34(sp_digit* r, const sp_digit* a, const sp_digit* e,
  1688. int bits, const sp_digit* m, int reduceA)
  1689. {
  1690. #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
  1691. #ifdef WOLFSSL_SP_SMALL_STACK
  1692. sp_digit* td = NULL;
  1693. #else
  1694. sp_digit td[3 * 68];
  1695. #endif
  1696. sp_digit* t[3] = {0, 0, 0};
  1697. sp_digit* norm = NULL;
  1698. sp_digit mp = 1;
  1699. sp_digit n;
  1700. int i;
  1701. int c;
  1702. byte y;
  1703. int err = MP_OKAY;
  1704. if (bits == 0) {
  1705. err = MP_VAL;
  1706. }
  1707. #ifdef WOLFSSL_SP_SMALL_STACK
  1708. if (err == MP_OKAY) {
  1709. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 34 * 2, NULL,
  1710. DYNAMIC_TYPE_TMP_BUFFER);
  1711. if (td == NULL)
  1712. err = MEMORY_E;
  1713. }
  1714. #endif
  1715. if (err == MP_OKAY) {
  1716. norm = td;
  1717. for (i=0; i<3; i++) {
  1718. t[i] = td + (i * 34 * 2);
  1719. XMEMSET(t[i], 0, sizeof(sp_digit) * 34U * 2U);
  1720. }
  1721. sp_2048_mont_setup(m, &mp);
  1722. sp_2048_mont_norm_34(norm, m);
  1723. if (reduceA != 0) {
  1724. err = sp_2048_mod_34(t[1], a, m);
  1725. }
  1726. else {
  1727. XMEMCPY(t[1], a, sizeof(sp_digit) * 34U);
  1728. }
  1729. }
  1730. if (err == MP_OKAY) {
  1731. sp_2048_mul_34(t[1], t[1], norm);
  1732. err = sp_2048_mod_34(t[1], t[1], m);
  1733. }
  1734. if (err == MP_OKAY) {
  1735. i = bits / 61;
  1736. c = bits % 61;
  1737. n = e[i--] << (61 - c);
  1738. for (; ; c--) {
  1739. if (c == 0) {
  1740. if (i == -1) {
  1741. break;
  1742. }
  1743. n = e[i--];
  1744. c = 61;
  1745. }
  1746. y = (int)((n >> 60) & 1);
  1747. n <<= 1;
  1748. sp_2048_mont_mul_34(t[y^1], t[0], t[1], m, mp);
  1749. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  1750. ((size_t)t[1] & addr_mask[y])),
  1751. sizeof(*t[2]) * 34 * 2);
  1752. sp_2048_mont_sqr_34(t[2], t[2], m, mp);
  1753. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  1754. ((size_t)t[1] & addr_mask[y])), t[2],
  1755. sizeof(*t[2]) * 34 * 2);
  1756. }
  1757. sp_2048_mont_reduce_34(t[0], m, mp);
  1758. n = sp_2048_cmp_34(t[0], m);
  1759. sp_2048_cond_sub_34(t[0], t[0], m, ~(n >> 63));
  1760. XMEMCPY(r, t[0], sizeof(*r) * 34 * 2);
  1761. }
  1762. #ifdef WOLFSSL_SP_SMALL_STACK
  1763. if (td != NULL)
  1764. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1765. #endif
  1766. return err;
  1767. #elif !defined(WC_NO_CACHE_RESISTANT)
  1768. #ifdef WOLFSSL_SP_SMALL_STACK
  1769. sp_digit* td = NULL;
  1770. #else
  1771. sp_digit td[3 * 68];
  1772. #endif
  1773. sp_digit* t[3] = {0, 0, 0};
  1774. sp_digit* norm = NULL;
  1775. sp_digit mp = 1;
  1776. sp_digit n;
  1777. int i;
  1778. int c;
  1779. byte y;
  1780. int err = MP_OKAY;
  1781. if (bits == 0) {
  1782. err = MP_VAL;
  1783. }
  1784. #ifdef WOLFSSL_SP_SMALL_STACK
  1785. if (err == MP_OKAY) {
  1786. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 34 * 2, NULL,
  1787. DYNAMIC_TYPE_TMP_BUFFER);
  1788. if (td == NULL)
  1789. err = MEMORY_E;
  1790. }
  1791. #endif
  1792. if (err == MP_OKAY) {
  1793. norm = td;
  1794. for (i=0; i<3; i++) {
  1795. t[i] = td + (i * 34 * 2);
  1796. }
  1797. sp_2048_mont_setup(m, &mp);
  1798. sp_2048_mont_norm_34(norm, m);
  1799. if (reduceA != 0) {
  1800. err = sp_2048_mod_34(t[1], a, m);
  1801. if (err == MP_OKAY) {
  1802. sp_2048_mul_34(t[1], t[1], norm);
  1803. err = sp_2048_mod_34(t[1], t[1], m);
  1804. }
  1805. }
  1806. else {
  1807. sp_2048_mul_34(t[1], a, norm);
  1808. err = sp_2048_mod_34(t[1], t[1], m);
  1809. }
  1810. }
  1811. if (err == MP_OKAY) {
  1812. i = bits / 61;
  1813. c = bits % 61;
  1814. n = e[i--] << (61 - c);
  1815. for (; ; c--) {
  1816. if (c == 0) {
  1817. if (i == -1) {
  1818. break;
  1819. }
  1820. n = e[i--];
  1821. c = 61;
  1822. }
  1823. y = (int)((n >> 60) & 1);
  1824. n <<= 1;
  1825. sp_2048_mont_mul_34(t[y^1], t[0], t[1], m, mp);
  1826. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  1827. ((size_t)t[1] & addr_mask[y])),
  1828. sizeof(*t[2]) * 34 * 2);
  1829. sp_2048_mont_sqr_34(t[2], t[2], m, mp);
  1830. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  1831. ((size_t)t[1] & addr_mask[y])), t[2],
  1832. sizeof(*t[2]) * 34 * 2);
  1833. }
  1834. sp_2048_mont_reduce_34(t[0], m, mp);
  1835. n = sp_2048_cmp_34(t[0], m);
  1836. sp_2048_cond_sub_34(t[0], t[0], m, ~(n >> 63));
  1837. XMEMCPY(r, t[0], sizeof(*r) * 34 * 2);
  1838. }
  1839. #ifdef WOLFSSL_SP_SMALL_STACK
  1840. if (td != NULL)
  1841. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1842. #endif
  1843. return err;
  1844. #else
  1845. #ifdef WOLFSSL_SP_SMALL_STACK
  1846. sp_digit* td = NULL;
  1847. #else
  1848. sp_digit td[(16 * 68) + 68];
  1849. #endif
  1850. sp_digit* t[16];
  1851. sp_digit* rt = NULL;
  1852. sp_digit* norm = NULL;
  1853. sp_digit mp = 1;
  1854. sp_digit n;
  1855. int i;
  1856. int c;
  1857. byte y;
  1858. int err = MP_OKAY;
  1859. if (bits == 0) {
  1860. err = MP_VAL;
  1861. }
  1862. #ifdef WOLFSSL_SP_SMALL_STACK
  1863. if (err == MP_OKAY) {
  1864. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((16 * 68) + 68), NULL,
  1865. DYNAMIC_TYPE_TMP_BUFFER);
  1866. if (td == NULL)
  1867. err = MEMORY_E;
  1868. }
  1869. #endif
  1870. if (err == MP_OKAY) {
  1871. norm = td;
  1872. for (i=0; i<16; i++)
  1873. t[i] = td + i * 68;
  1874. rt = td + 1088;
  1875. sp_2048_mont_setup(m, &mp);
  1876. sp_2048_mont_norm_34(norm, m);
  1877. if (reduceA != 0) {
  1878. err = sp_2048_mod_34(t[1], a, m);
  1879. if (err == MP_OKAY) {
  1880. sp_2048_mul_34(t[1], t[1], norm);
  1881. err = sp_2048_mod_34(t[1], t[1], m);
  1882. }
  1883. }
  1884. else {
  1885. sp_2048_mul_34(t[1], a, norm);
  1886. err = sp_2048_mod_34(t[1], t[1], m);
  1887. }
  1888. }
  1889. if (err == MP_OKAY) {
  1890. sp_2048_mont_sqr_34(t[ 2], t[ 1], m, mp);
  1891. sp_2048_mont_mul_34(t[ 3], t[ 2], t[ 1], m, mp);
  1892. sp_2048_mont_sqr_34(t[ 4], t[ 2], m, mp);
  1893. sp_2048_mont_mul_34(t[ 5], t[ 3], t[ 2], m, mp);
  1894. sp_2048_mont_sqr_34(t[ 6], t[ 3], m, mp);
  1895. sp_2048_mont_mul_34(t[ 7], t[ 4], t[ 3], m, mp);
  1896. sp_2048_mont_sqr_34(t[ 8], t[ 4], m, mp);
  1897. sp_2048_mont_mul_34(t[ 9], t[ 5], t[ 4], m, mp);
  1898. sp_2048_mont_sqr_34(t[10], t[ 5], m, mp);
  1899. sp_2048_mont_mul_34(t[11], t[ 6], t[ 5], m, mp);
  1900. sp_2048_mont_sqr_34(t[12], t[ 6], m, mp);
  1901. sp_2048_mont_mul_34(t[13], t[ 7], t[ 6], m, mp);
  1902. sp_2048_mont_sqr_34(t[14], t[ 7], m, mp);
  1903. sp_2048_mont_mul_34(t[15], t[ 8], t[ 7], m, mp);
  1904. bits = ((bits + 3) / 4) * 4;
  1905. i = ((bits + 60) / 61) - 1;
  1906. c = bits % 61;
  1907. if (c == 0) {
  1908. c = 61;
  1909. }
  1910. if (i < 34) {
  1911. n = e[i--] << (64 - c);
  1912. }
  1913. else {
  1914. n = 0;
  1915. i--;
  1916. }
  1917. if (c < 4) {
  1918. n |= e[i--] << (3 - c);
  1919. c += 61;
  1920. }
  1921. y = (int)((n >> 60) & 0xf);
  1922. n <<= 4;
  1923. c -= 4;
  1924. XMEMCPY(rt, t[y], sizeof(sp_digit) * 68);
  1925. while ((i >= 0) || (c >= 4)) {
  1926. if (c >= 4) {
  1927. y = (byte)((n >> 60) & 0xf);
  1928. n <<= 4;
  1929. c -= 4;
  1930. }
  1931. else if (c == 0) {
  1932. n = e[i--] << 3;
  1933. y = (byte)((n >> 60) & 0xf);
  1934. n <<= 4;
  1935. c = 57;
  1936. }
  1937. else {
  1938. y = (byte)((n >> 60) & 0xf);
  1939. n = e[i--] << 3;
  1940. c = 4 - c;
  1941. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  1942. n <<= c;
  1943. c = 61 - c;
  1944. }
  1945. sp_2048_mont_sqr_34(rt, rt, m, mp);
  1946. sp_2048_mont_sqr_34(rt, rt, m, mp);
  1947. sp_2048_mont_sqr_34(rt, rt, m, mp);
  1948. sp_2048_mont_sqr_34(rt, rt, m, mp);
  1949. sp_2048_mont_mul_34(rt, rt, t[y], m, mp);
  1950. }
  1951. sp_2048_mont_reduce_34(rt, m, mp);
  1952. n = sp_2048_cmp_34(rt, m);
  1953. sp_2048_cond_sub_34(rt, rt, m, ~(n >> 63));
  1954. XMEMCPY(r, rt, sizeof(sp_digit) * 68);
  1955. }
  1956. #ifdef WOLFSSL_SP_SMALL_STACK
  1957. if (td != NULL)
  1958. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1959. #endif
  1960. return err;
  1961. #endif
  1962. }
  1963. #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
  1964. #ifdef WOLFSSL_HAVE_SP_RSA
  1965. /* RSA public key operation.
  1966. *
  1967. * in Array of bytes representing the number to exponentiate, base.
  1968. * inLen Number of bytes in base.
  1969. * em Public exponent.
  1970. * mm Modulus.
  1971. * out Buffer to hold big-endian bytes of exponentiation result.
  1972. * Must be at least 256 bytes long.
  1973. * outLen Number of bytes in result.
  1974. * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
  1975. * an array is too long and MEMORY_E when dynamic memory allocation fails.
  1976. */
  1977. int sp_RsaPublic_2048(const byte* in, word32 inLen, const mp_int* em,
  1978. const mp_int* mm, byte* out, word32* outLen)
  1979. {
  1980. #ifdef WOLFSSL_SP_SMALL
  1981. #ifdef WOLFSSL_SP_SMALL_STACK
  1982. sp_digit* a = NULL;
  1983. #else
  1984. sp_digit a[34 * 5];
  1985. #endif
  1986. sp_digit* m = NULL;
  1987. sp_digit* r = NULL;
  1988. sp_digit* norm = NULL;
  1989. sp_uint64 e[1] = {0};
  1990. sp_digit mp = 0;
  1991. int i;
  1992. int err = MP_OKAY;
  1993. if (*outLen < 256U) {
  1994. err = MP_TO_E;
  1995. }
  1996. if (err == MP_OKAY) {
  1997. if (mp_count_bits(em) > 64) {
  1998. err = MP_READ_E;
  1999. }
  2000. else if (inLen > 256U) {
  2001. err = MP_READ_E;
  2002. }
  2003. else if (mp_count_bits(mm) != 2048) {
  2004. err = MP_READ_E;
  2005. }
  2006. else if (mp_iseven(mm)) {
  2007. err = MP_VAL;
  2008. }
  2009. }
  2010. #ifdef WOLFSSL_SP_SMALL_STACK
  2011. if (err == MP_OKAY) {
  2012. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 34 * 5, NULL,
  2013. DYNAMIC_TYPE_RSA);
  2014. if (a == NULL)
  2015. err = MEMORY_E;
  2016. }
  2017. #endif
  2018. if (err == MP_OKAY) {
  2019. r = a + 34 * 2;
  2020. m = r + 34 * 2;
  2021. norm = r;
  2022. sp_2048_from_bin(a, 34, in, inLen);
  2023. #if DIGIT_BIT >= 64
  2024. e[0] = (sp_uint64)em->dp[0];
  2025. #else
  2026. e[0] = (sp_uint64)em->dp[0];
  2027. if (em->used > 1) {
  2028. e[0] |= ((sp_uint64)em->dp[1]) << DIGIT_BIT;
  2029. }
  2030. #endif
  2031. if (e[0] == 0) {
  2032. err = MP_EXPTMOD_E;
  2033. }
  2034. }
  2035. if (err == MP_OKAY) {
  2036. sp_2048_from_mp(m, 34, mm);
  2037. sp_2048_mont_setup(m, &mp);
  2038. sp_2048_mont_norm_34(norm, m);
  2039. }
  2040. if (err == MP_OKAY) {
  2041. sp_2048_mul_34(a, a, norm);
  2042. err = sp_2048_mod_34(a, a, m);
  2043. }
  2044. if (err == MP_OKAY) {
  2045. for (i=63; i>=0; i--) {
  2046. if ((e[0] >> i) != 0) {
  2047. break;
  2048. }
  2049. }
  2050. XMEMCPY(r, a, sizeof(sp_digit) * 34 * 2);
  2051. for (i--; i>=0; i--) {
  2052. sp_2048_mont_sqr_34(r, r, m, mp);
  2053. if (((e[0] >> i) & 1) == 1) {
  2054. sp_2048_mont_mul_34(r, r, a, m, mp);
  2055. }
  2056. }
  2057. sp_2048_mont_reduce_34(r, m, mp);
  2058. mp = sp_2048_cmp_34(r, m);
  2059. sp_2048_cond_sub_34(r, r, m, ~(mp >> 63));
  2060. sp_2048_to_bin_34(r, out);
  2061. *outLen = 256;
  2062. }
  2063. #ifdef WOLFSSL_SP_SMALL_STACK
  2064. if (a != NULL)
  2065. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  2066. #endif
  2067. return err;
  2068. #else
  2069. #ifdef WOLFSSL_SP_SMALL_STACK
  2070. sp_digit* d = NULL;
  2071. #else
  2072. sp_digit d[34 * 5];
  2073. #endif
  2074. sp_digit* a = NULL;
  2075. sp_digit* m = NULL;
  2076. sp_digit* r = NULL;
  2077. sp_uint64 e[1] = {0};
  2078. int err = MP_OKAY;
  2079. if (*outLen < 256U) {
  2080. err = MP_TO_E;
  2081. }
  2082. if (err == MP_OKAY) {
  2083. if (mp_count_bits(em) > 64) {
  2084. err = MP_READ_E;
  2085. }
  2086. else if (inLen > 256U) {
  2087. err = MP_READ_E;
  2088. }
  2089. else if (mp_count_bits(mm) != 2048) {
  2090. err = MP_READ_E;
  2091. }
  2092. else if (mp_iseven(mm)) {
  2093. err = MP_VAL;
  2094. }
  2095. }
  2096. #ifdef WOLFSSL_SP_SMALL_STACK
  2097. if (err == MP_OKAY) {
  2098. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 34 * 5, NULL,
  2099. DYNAMIC_TYPE_RSA);
  2100. if (d == NULL)
  2101. err = MEMORY_E;
  2102. }
  2103. #endif
  2104. if (err == MP_OKAY) {
  2105. a = d;
  2106. r = a + 34 * 2;
  2107. m = r + 34 * 2;
  2108. sp_2048_from_bin(a, 34, in, inLen);
  2109. #if DIGIT_BIT >= 64
  2110. e[0] = (sp_uint64)em->dp[0];
  2111. #else
  2112. e[0] = (sp_uint64)em->dp[0];
  2113. if (em->used > 1) {
  2114. e[0] |= ((sp_uint64)em->dp[1]) << DIGIT_BIT;
  2115. }
  2116. #endif
  2117. if (e[0] == 0) {
  2118. err = MP_EXPTMOD_E;
  2119. }
  2120. }
  2121. if (err == MP_OKAY) {
  2122. sp_2048_from_mp(m, 34, mm);
  2123. if (e[0] == 0x3) {
  2124. sp_2048_sqr_34(r, a);
  2125. err = sp_2048_mod_34(r, r, m);
  2126. if (err == MP_OKAY) {
  2127. sp_2048_mul_34(r, a, r);
  2128. err = sp_2048_mod_34(r, r, m);
  2129. }
  2130. }
  2131. else {
  2132. sp_digit* norm = r;
  2133. int i;
  2134. sp_digit mp;
  2135. sp_2048_mont_setup(m, &mp);
  2136. sp_2048_mont_norm_34(norm, m);
  2137. sp_2048_mul_34(a, a, norm);
  2138. err = sp_2048_mod_34(a, a, m);
  2139. if (err == MP_OKAY) {
  2140. for (i=63; i>=0; i--) {
  2141. if ((e[0] >> i) != 0) {
  2142. break;
  2143. }
  2144. }
  2145. XMEMCPY(r, a, sizeof(sp_digit) * 68U);
  2146. for (i--; i>=0; i--) {
  2147. sp_2048_mont_sqr_34(r, r, m, mp);
  2148. if (((e[0] >> i) & 1) == 1) {
  2149. sp_2048_mont_mul_34(r, r, a, m, mp);
  2150. }
  2151. }
  2152. sp_2048_mont_reduce_34(r, m, mp);
  2153. mp = sp_2048_cmp_34(r, m);
  2154. sp_2048_cond_sub_34(r, r, m, ~(mp >> 63));
  2155. }
  2156. }
  2157. }
  2158. if (err == MP_OKAY) {
  2159. sp_2048_to_bin_34(r, out);
  2160. *outLen = 256;
  2161. }
  2162. #ifdef WOLFSSL_SP_SMALL_STACK
  2163. if (d != NULL)
  2164. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  2165. #endif
  2166. return err;
  2167. #endif /* WOLFSSL_SP_SMALL */
  2168. }
  2169. #ifndef WOLFSSL_RSA_PUBLIC_ONLY
  2170. #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM)
  2171. #endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */
  2172. /* RSA private key operation.
  2173. *
  2174. * in Array of bytes representing the number to exponentiate, base.
  2175. * inLen Number of bytes in base.
  2176. * dm Private exponent.
  2177. * pm First prime.
  2178. * qm Second prime.
  2179. * dpm First prime's CRT exponent.
  2180. * dqm Second prime's CRT exponent.
  2181. * qim Inverse of second prime mod p.
  2182. * mm Modulus.
  2183. * out Buffer to hold big-endian bytes of exponentiation result.
  2184. * Must be at least 256 bytes long.
  2185. * outLen Number of bytes in result.
  2186. * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
  2187. * an array is too long and MEMORY_E when dynamic memory allocation fails.
  2188. */
  2189. int sp_RsaPrivate_2048(const byte* in, word32 inLen, const mp_int* dm,
  2190. const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm,
  2191. const mp_int* qim, const mp_int* mm, byte* out, word32* outLen)
  2192. {
  2193. #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
  2194. #if defined(WOLFSSL_SP_SMALL)
  2195. #ifdef WOLFSSL_SP_SMALL_STACK
  2196. sp_digit* d = NULL;
  2197. #else
  2198. sp_digit d[34 * 4];
  2199. #endif
  2200. sp_digit* a = NULL;
  2201. sp_digit* m = NULL;
  2202. sp_digit* r = NULL;
  2203. int err = MP_OKAY;
  2204. (void)pm;
  2205. (void)qm;
  2206. (void)dpm;
  2207. (void)dqm;
  2208. (void)qim;
  2209. if (*outLen < 256U) {
  2210. err = MP_TO_E;
  2211. }
  2212. if (err == MP_OKAY) {
  2213. if (mp_count_bits(dm) > 2048) {
  2214. err = MP_READ_E;
  2215. }
  2216. else if (inLen > 256) {
  2217. err = MP_READ_E;
  2218. }
  2219. else if (mp_count_bits(mm) != 2048) {
  2220. err = MP_READ_E;
  2221. }
  2222. else if (mp_iseven(mm)) {
  2223. err = MP_VAL;
  2224. }
  2225. }
  2226. #ifdef WOLFSSL_SP_SMALL_STACK
  2227. if (err == MP_OKAY) {
  2228. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 34 * 4, NULL,
  2229. DYNAMIC_TYPE_RSA);
  2230. if (d == NULL)
  2231. err = MEMORY_E;
  2232. }
  2233. #endif
  2234. if (err == MP_OKAY) {
  2235. a = d + 34;
  2236. m = a + 68;
  2237. r = a;
  2238. sp_2048_from_bin(a, 34, in, inLen);
  2239. sp_2048_from_mp(d, 34, dm);
  2240. sp_2048_from_mp(m, 34, mm);
  2241. err = sp_2048_mod_exp_34(r, a, d, 2048, m, 0);
  2242. }
  2243. if (err == MP_OKAY) {
  2244. sp_2048_to_bin_34(r, out);
  2245. *outLen = 256;
  2246. }
  2247. #ifdef WOLFSSL_SP_SMALL_STACK
  2248. if (d != NULL)
  2249. #endif
  2250. {
  2251. /* only "a" and "r" are sensitive and need zeroized (same pointer) */
  2252. if (a != NULL)
  2253. ForceZero(a, sizeof(sp_digit) * 34);
  2254. #ifdef WOLFSSL_SP_SMALL_STACK
  2255. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  2256. #endif
  2257. }
  2258. return err;
  2259. #else
  2260. #ifdef WOLFSSL_SP_SMALL_STACK
  2261. sp_digit* d = NULL;
  2262. #else
  2263. sp_digit d[34 * 4];
  2264. #endif
  2265. sp_digit* a = NULL;
  2266. sp_digit* m = NULL;
  2267. sp_digit* r = NULL;
  2268. int err = MP_OKAY;
  2269. (void)pm;
  2270. (void)qm;
  2271. (void)dpm;
  2272. (void)dqm;
  2273. (void)qim;
  2274. if (*outLen < 256U) {
  2275. err = MP_TO_E;
  2276. }
  2277. if (err == MP_OKAY) {
  2278. if (mp_count_bits(dm) > 2048) {
  2279. err = MP_READ_E;
  2280. }
  2281. else if (inLen > 256U) {
  2282. err = MP_READ_E;
  2283. }
  2284. else if (mp_count_bits(mm) != 2048) {
  2285. err = MP_READ_E;
  2286. }
  2287. else if (mp_iseven(mm)) {
  2288. err = MP_VAL;
  2289. }
  2290. }
  2291. #ifdef WOLFSSL_SP_SMALL_STACK
  2292. if (err == MP_OKAY) {
  2293. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 34 * 4, NULL,
  2294. DYNAMIC_TYPE_RSA);
  2295. if (d == NULL)
  2296. err = MEMORY_E;
  2297. }
  2298. #endif
  2299. if (err == MP_OKAY) {
  2300. a = d + 34;
  2301. m = a + 68;
  2302. r = a;
  2303. sp_2048_from_bin(a, 34, in, inLen);
  2304. sp_2048_from_mp(d, 34, dm);
  2305. sp_2048_from_mp(m, 34, mm);
  2306. err = sp_2048_mod_exp_34(r, a, d, 2048, m, 0);
  2307. }
  2308. if (err == MP_OKAY) {
  2309. sp_2048_to_bin_34(r, out);
  2310. *outLen = 256;
  2311. }
  2312. #ifdef WOLFSSL_SP_SMALL_STACK
  2313. if (d != NULL)
  2314. #endif
  2315. {
  2316. /* only "a" and "r" are sensitive and need zeroized (same pointer) */
  2317. if (a != NULL)
  2318. ForceZero(a, sizeof(sp_digit) * 34);
  2319. #ifdef WOLFSSL_SP_SMALL_STACK
  2320. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  2321. #endif
  2322. }
  2323. return err;
  2324. #endif /* WOLFSSL_SP_SMALL */
  2325. #else
  2326. #if defined(WOLFSSL_SP_SMALL)
  2327. #ifdef WOLFSSL_SP_SMALL_STACK
  2328. sp_digit* a = NULL;
  2329. #else
  2330. sp_digit a[17 * 8];
  2331. #endif
  2332. sp_digit* p = NULL;
  2333. sp_digit* dp = NULL;
  2334. sp_digit* dq = NULL;
  2335. sp_digit* qi = NULL;
  2336. sp_digit* tmpa = NULL;
  2337. sp_digit* tmpb = NULL;
  2338. sp_digit* r = NULL;
  2339. int err = MP_OKAY;
  2340. (void)dm;
  2341. (void)mm;
  2342. if (*outLen < 256U) {
  2343. err = MP_TO_E;
  2344. }
  2345. if (err == MP_OKAY) {
  2346. if (inLen > 256) {
  2347. err = MP_READ_E;
  2348. }
  2349. else if (mp_count_bits(mm) != 2048) {
  2350. err = MP_READ_E;
  2351. }
  2352. else if (mp_iseven(mm)) {
  2353. err = MP_VAL;
  2354. }
  2355. else if (mp_iseven(pm)) {
  2356. err = MP_VAL;
  2357. }
  2358. else if (mp_iseven(qm)) {
  2359. err = MP_VAL;
  2360. }
  2361. }
  2362. #ifdef WOLFSSL_SP_SMALL_STACK
  2363. if (err == MP_OKAY) {
  2364. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 17 * 8, NULL,
  2365. DYNAMIC_TYPE_RSA);
  2366. if (a == NULL)
  2367. err = MEMORY_E;
  2368. }
  2369. #endif
  2370. if (err == MP_OKAY) {
  2371. p = a + 34;
  2372. qi = dq = dp = p + 17;
  2373. tmpa = qi + 17;
  2374. tmpb = tmpa + 34;
  2375. r = a;
  2376. sp_2048_from_bin(a, 34, in, inLen);
  2377. sp_2048_from_mp(p, 17, pm);
  2378. sp_2048_from_mp(dp, 17, dpm);
  2379. err = sp_2048_mod_exp_17(tmpa, a, dp, 1024, p, 1);
  2380. }
  2381. if (err == MP_OKAY) {
  2382. sp_2048_from_mp(p, 17, qm);
  2383. sp_2048_from_mp(dq, 17, dqm);
  2384. err = sp_2048_mod_exp_17(tmpb, a, dq, 1024, p, 1);
  2385. }
  2386. if (err == MP_OKAY) {
  2387. sp_2048_from_mp(p, 17, pm);
  2388. (void)sp_2048_sub_17(tmpa, tmpa, tmpb);
  2389. sp_2048_norm_17(tmpa);
  2390. sp_2048_cond_add_17(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[16] >> 63));
  2391. sp_2048_cond_add_17(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[16] >> 63));
  2392. sp_2048_norm_17(tmpa);
  2393. sp_2048_from_mp(qi, 17, qim);
  2394. sp_2048_mul_17(tmpa, tmpa, qi);
  2395. err = sp_2048_mod_17(tmpa, tmpa, p);
  2396. }
  2397. if (err == MP_OKAY) {
  2398. sp_2048_from_mp(p, 17, qm);
  2399. sp_2048_mul_17(tmpa, p, tmpa);
  2400. (void)sp_2048_add_34(r, tmpb, tmpa);
  2401. sp_2048_norm_34(r);
  2402. sp_2048_to_bin_34(r, out);
  2403. *outLen = 256;
  2404. }
  2405. #ifdef WOLFSSL_SP_SMALL_STACK
  2406. if (a != NULL)
  2407. #endif
  2408. {
  2409. ForceZero(a, sizeof(sp_digit) * 17 * 8);
  2410. #ifdef WOLFSSL_SP_SMALL_STACK
  2411. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  2412. #endif
  2413. }
  2414. return err;
  2415. #else
  2416. #ifdef WOLFSSL_SP_SMALL_STACK
  2417. sp_digit* a = NULL;
  2418. #else
  2419. sp_digit a[17 * 13];
  2420. #endif
  2421. sp_digit* p = NULL;
  2422. sp_digit* q = NULL;
  2423. sp_digit* dp = NULL;
  2424. sp_digit* dq = NULL;
  2425. sp_digit* qi = NULL;
  2426. sp_digit* tmpa = NULL;
  2427. sp_digit* tmpb = NULL;
  2428. sp_digit* r = NULL;
  2429. int err = MP_OKAY;
  2430. (void)dm;
  2431. (void)mm;
  2432. if (*outLen < 256U) {
  2433. err = MP_TO_E;
  2434. }
  2435. if (err == MP_OKAY) {
  2436. if (inLen > 256U) {
  2437. err = MP_READ_E;
  2438. }
  2439. else if (mp_count_bits(mm) != 2048) {
  2440. err = MP_READ_E;
  2441. }
  2442. else if (mp_iseven(mm)) {
  2443. err = MP_VAL;
  2444. }
  2445. else if (mp_iseven(pm)) {
  2446. err = MP_VAL;
  2447. }
  2448. else if (mp_iseven(qm)) {
  2449. err = MP_VAL;
  2450. }
  2451. }
  2452. #ifdef WOLFSSL_SP_SMALL_STACK
  2453. if (err == MP_OKAY) {
  2454. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 17 * 13, NULL,
  2455. DYNAMIC_TYPE_RSA);
  2456. if (a == NULL)
  2457. err = MEMORY_E;
  2458. }
  2459. #endif
  2460. if (err == MP_OKAY) {
  2461. p = a + 34 * 2;
  2462. q = p + 17;
  2463. dp = q + 17;
  2464. dq = dp + 17;
  2465. qi = dq + 17;
  2466. tmpa = qi + 17;
  2467. tmpb = tmpa + 34;
  2468. r = a;
  2469. sp_2048_from_bin(a, 34, in, inLen);
  2470. sp_2048_from_mp(p, 17, pm);
  2471. sp_2048_from_mp(q, 17, qm);
  2472. sp_2048_from_mp(dp, 17, dpm);
  2473. sp_2048_from_mp(dq, 17, dqm);
  2474. sp_2048_from_mp(qi, 17, qim);
  2475. err = sp_2048_mod_exp_17(tmpa, a, dp, 1024, p, 1);
  2476. }
  2477. if (err == MP_OKAY) {
  2478. err = sp_2048_mod_exp_17(tmpb, a, dq, 1024, q, 1);
  2479. }
  2480. if (err == MP_OKAY) {
  2481. (void)sp_2048_sub_17(tmpa, tmpa, tmpb);
  2482. sp_2048_norm_17(tmpa);
  2483. sp_2048_cond_add_17(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[16] >> 63));
  2484. sp_2048_cond_add_17(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[16] >> 63));
  2485. sp_2048_norm_17(tmpa);
  2486. sp_2048_mul_17(tmpa, tmpa, qi);
  2487. err = sp_2048_mod_17(tmpa, tmpa, p);
  2488. }
  2489. if (err == MP_OKAY) {
  2490. sp_2048_mul_17(tmpa, tmpa, q);
  2491. (void)sp_2048_add_34(r, tmpb, tmpa);
  2492. sp_2048_norm_34(r);
  2493. sp_2048_to_bin_34(r, out);
  2494. *outLen = 256;
  2495. }
  2496. #ifdef WOLFSSL_SP_SMALL_STACK
  2497. if (a != NULL)
  2498. #endif
  2499. {
  2500. ForceZero(a, sizeof(sp_digit) * 17 * 13);
  2501. #ifdef WOLFSSL_SP_SMALL_STACK
  2502. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  2503. #endif
  2504. }
  2505. return err;
  2506. #endif /* WOLFSSL_SP_SMALL */
  2507. #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
  2508. }
  2509. #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
  2510. #endif /* WOLFSSL_HAVE_SP_RSA */
  2511. #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
  2512. !defined(WOLFSSL_RSA_PUBLIC_ONLY))
  2513. /* Convert an array of sp_digit to an mp_int.
  2514. *
  2515. * a A single precision integer.
  2516. * r A multi-precision integer.
  2517. */
  2518. static int sp_2048_to_mp(const sp_digit* a, mp_int* r)
  2519. {
  2520. int err;
  2521. err = mp_grow(r, (2048 + DIGIT_BIT - 1) / DIGIT_BIT);
  2522. if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
  2523. #if DIGIT_BIT == 61
  2524. XMEMCPY(r->dp, a, sizeof(sp_digit) * 34);
  2525. r->used = 34;
  2526. mp_clamp(r);
  2527. #elif DIGIT_BIT < 61
  2528. int i;
  2529. int j = 0;
  2530. int s = 0;
  2531. r->dp[0] = 0;
  2532. for (i = 0; i < 34; i++) {
  2533. r->dp[j] |= (mp_digit)(a[i] << s);
  2534. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  2535. s = DIGIT_BIT - s;
  2536. r->dp[++j] = (mp_digit)(a[i] >> s);
  2537. while (s + DIGIT_BIT <= 61) {
  2538. s += DIGIT_BIT;
  2539. r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  2540. if (s == SP_WORD_SIZE) {
  2541. r->dp[j] = 0;
  2542. }
  2543. else {
  2544. r->dp[j] = (mp_digit)(a[i] >> s);
  2545. }
  2546. }
  2547. s = 61 - s;
  2548. }
  2549. r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;
  2550. mp_clamp(r);
  2551. #else
  2552. int i;
  2553. int j = 0;
  2554. int s = 0;
  2555. r->dp[0] = 0;
  2556. for (i = 0; i < 34; i++) {
  2557. r->dp[j] |= ((mp_digit)a[i]) << s;
  2558. if (s + 61 >= DIGIT_BIT) {
  2559. #if DIGIT_BIT != 32 && DIGIT_BIT != 64
  2560. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  2561. #endif
  2562. s = DIGIT_BIT - s;
  2563. r->dp[++j] = a[i] >> s;
  2564. s = 61 - s;
  2565. }
  2566. else {
  2567. s += 61;
  2568. }
  2569. }
  2570. r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;
  2571. mp_clamp(r);
  2572. #endif
  2573. }
  2574. return err;
  2575. }
  2576. /* Perform the modular exponentiation for Diffie-Hellman.
  2577. *
  2578. * base Base. MP integer.
  2579. * exp Exponent. MP integer.
  2580. * mod Modulus. MP integer.
  2581. * res Result. MP integer.
  2582. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  2583. * and MEMORY_E if memory allocation fails.
  2584. */
  2585. int sp_ModExp_2048(const mp_int* base, const mp_int* exp, const mp_int* mod,
  2586. mp_int* res)
  2587. {
  2588. #ifdef WOLFSSL_SP_SMALL
  2589. int err = MP_OKAY;
  2590. #ifdef WOLFSSL_SP_SMALL_STACK
  2591. sp_digit* b = NULL;
  2592. #else
  2593. sp_digit b[34 * 4];
  2594. #endif
  2595. sp_digit* e = NULL;
  2596. sp_digit* m = NULL;
  2597. sp_digit* r = NULL;
  2598. int expBits = mp_count_bits(exp);
  2599. if (mp_count_bits(base) > 2048) {
  2600. err = MP_READ_E;
  2601. }
  2602. else if (expBits > 2048) {
  2603. err = MP_READ_E;
  2604. }
  2605. else if (mp_count_bits(mod) != 2048) {
  2606. err = MP_READ_E;
  2607. }
  2608. else if (mp_iseven(mod)) {
  2609. err = MP_VAL;
  2610. }
  2611. #ifdef WOLFSSL_SP_SMALL_STACK
  2612. if (err == MP_OKAY) {
  2613. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 34 * 4, NULL,
  2614. DYNAMIC_TYPE_DH);
  2615. if (b == NULL)
  2616. err = MEMORY_E;
  2617. }
  2618. #endif
  2619. if (err == MP_OKAY) {
  2620. e = b + 34 * 2;
  2621. m = e + 34;
  2622. r = b;
  2623. sp_2048_from_mp(b, 34, base);
  2624. sp_2048_from_mp(e, 34, exp);
  2625. sp_2048_from_mp(m, 34, mod);
  2626. err = sp_2048_mod_exp_34(r, b, e, mp_count_bits(exp), m, 0);
  2627. }
  2628. if (err == MP_OKAY) {
  2629. err = sp_2048_to_mp(r, res);
  2630. }
  2631. #ifdef WOLFSSL_SP_SMALL_STACK
  2632. if (b != NULL)
  2633. #endif
  2634. {
  2635. /* only "e" is sensitive and needs zeroized */
  2636. if (e != NULL)
  2637. ForceZero(e, sizeof(sp_digit) * 34U);
  2638. #ifdef WOLFSSL_SP_SMALL_STACK
  2639. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  2640. #endif
  2641. }
  2642. return err;
  2643. #else
  2644. #ifdef WOLFSSL_SP_SMALL_STACK
  2645. sp_digit* b = NULL;
  2646. #else
  2647. sp_digit b[34 * 4];
  2648. #endif
  2649. sp_digit* e = NULL;
  2650. sp_digit* m = NULL;
  2651. sp_digit* r = NULL;
  2652. int err = MP_OKAY;
  2653. int expBits = mp_count_bits(exp);
  2654. if (mp_count_bits(base) > 2048) {
  2655. err = MP_READ_E;
  2656. }
  2657. else if (expBits > 2048) {
  2658. err = MP_READ_E;
  2659. }
  2660. else if (mp_count_bits(mod) != 2048) {
  2661. err = MP_READ_E;
  2662. }
  2663. else if (mp_iseven(mod)) {
  2664. err = MP_VAL;
  2665. }
  2666. #ifdef WOLFSSL_SP_SMALL_STACK
  2667. if (err == MP_OKAY) {
  2668. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 34 * 4, NULL, DYNAMIC_TYPE_DH);
  2669. if (b == NULL)
  2670. err = MEMORY_E;
  2671. }
  2672. #endif
  2673. if (err == MP_OKAY) {
  2674. e = b + 34 * 2;
  2675. m = e + 34;
  2676. r = b;
  2677. sp_2048_from_mp(b, 34, base);
  2678. sp_2048_from_mp(e, 34, exp);
  2679. sp_2048_from_mp(m, 34, mod);
  2680. err = sp_2048_mod_exp_34(r, b, e, expBits, m, 0);
  2681. }
  2682. if (err == MP_OKAY) {
  2683. err = sp_2048_to_mp(r, res);
  2684. }
  2685. #ifdef WOLFSSL_SP_SMALL_STACK
  2686. if (b != NULL)
  2687. #endif
  2688. {
  2689. /* only "e" is sensitive and needs zeroized */
  2690. if (e != NULL)
  2691. ForceZero(e, sizeof(sp_digit) * 34U);
  2692. #ifdef WOLFSSL_SP_SMALL_STACK
  2693. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  2694. #endif
  2695. }
  2696. return err;
  2697. #endif
  2698. }
  2699. #ifdef WOLFSSL_HAVE_SP_DH
  2700. #ifdef HAVE_FFDHE_2048
  2701. SP_NOINLINE static void sp_2048_lshift_34(sp_digit* r, const sp_digit* a,
  2702. byte n)
  2703. {
  2704. int i;
  2705. r[34] = a[33] >> (61 - n);
  2706. for (i=33; i>0; i--) {
  2707. r[i] = ((a[i] << n) | (a[i-1] >> (61 - n))) & 0x1fffffffffffffffL;
  2708. }
  2709. r[0] = (a[0] << n) & 0x1fffffffffffffffL;
  2710. }
  2711. /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
  2712. *
  2713. * r A single precision number that is the result of the operation.
  2714. * e A single precision number that is the exponent.
  2715. * bits The number of bits in the exponent.
  2716. * m A single precision number that is the modulus.
  2717. * returns 0 on success.
  2718. * returns MEMORY_E on dynamic memory allocation failure.
  2719. * returns MP_VAL when base is even.
  2720. */
  2721. static int sp_2048_mod_exp_2_34(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)
  2722. {
  2723. #ifdef WOLFSSL_SP_SMALL_STACK
  2724. sp_digit* td = NULL;
  2725. #else
  2726. sp_digit td[103];
  2727. #endif
  2728. sp_digit* norm = NULL;
  2729. sp_digit* tmp = NULL;
  2730. sp_digit mp = 1;
  2731. sp_digit n;
  2732. sp_digit o;
  2733. int i;
  2734. int c;
  2735. byte y;
  2736. int err = MP_OKAY;
  2737. if (bits == 0) {
  2738. err = MP_VAL;
  2739. }
  2740. #ifdef WOLFSSL_SP_SMALL_STACK
  2741. if (err == MP_OKAY) {
  2742. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 103, NULL,
  2743. DYNAMIC_TYPE_TMP_BUFFER);
  2744. if (td == NULL)
  2745. err = MEMORY_E;
  2746. }
  2747. #endif
  2748. if (err == MP_OKAY) {
  2749. norm = td;
  2750. tmp = td + 68;
  2751. XMEMSET(td, 0, sizeof(sp_digit) * 103);
  2752. sp_2048_mont_setup(m, &mp);
  2753. sp_2048_mont_norm_34(norm, m);
  2754. bits = ((bits + 4) / 5) * 5;
  2755. i = ((bits + 60) / 61) - 1;
  2756. c = bits % 61;
  2757. if (c == 0) {
  2758. c = 61;
  2759. }
  2760. if (i < 34) {
  2761. n = e[i--] << (64 - c);
  2762. }
  2763. else {
  2764. n = 0;
  2765. i--;
  2766. }
  2767. if (c < 5) {
  2768. n |= e[i--] << (3 - c);
  2769. c += 61;
  2770. }
  2771. y = (int)((n >> 59) & 0x1f);
  2772. n <<= 5;
  2773. c -= 5;
  2774. sp_2048_lshift_34(r, norm, (byte)y);
  2775. while ((i >= 0) || (c >= 5)) {
  2776. if (c >= 5) {
  2777. y = (byte)((n >> 59) & 0x1f);
  2778. n <<= 5;
  2779. c -= 5;
  2780. }
  2781. else if (c == 0) {
  2782. n = e[i--] << 3;
  2783. y = (byte)((n >> 59) & 0x1f);
  2784. n <<= 5;
  2785. c = 56;
  2786. }
  2787. else {
  2788. y = (byte)((n >> 59) & 0x1f);
  2789. n = e[i--] << 3;
  2790. c = 5 - c;
  2791. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  2792. n <<= c;
  2793. c = 61 - c;
  2794. }
  2795. sp_2048_mont_sqr_34(r, r, m, mp);
  2796. sp_2048_mont_sqr_34(r, r, m, mp);
  2797. sp_2048_mont_sqr_34(r, r, m, mp);
  2798. sp_2048_mont_sqr_34(r, r, m, mp);
  2799. sp_2048_mont_sqr_34(r, r, m, mp);
  2800. sp_2048_lshift_34(r, r, (byte)y);
  2801. sp_2048_mul_d_34(tmp, norm, (r[34] << 26) + (r[33] >> 35));
  2802. r[34] = 0;
  2803. r[33] &= 0x7ffffffffL;
  2804. (void)sp_2048_add_34(r, r, tmp);
  2805. sp_2048_norm_34(r);
  2806. o = sp_2048_cmp_34(r, m);
  2807. sp_2048_cond_sub_34(r, r, m, ~(o >> 63));
  2808. }
  2809. sp_2048_mont_reduce_34(r, m, mp);
  2810. n = sp_2048_cmp_34(r, m);
  2811. sp_2048_cond_sub_34(r, r, m, ~(n >> 63));
  2812. }
  2813. #ifdef WOLFSSL_SP_SMALL_STACK
  2814. if (td != NULL)
  2815. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  2816. #endif
  2817. return err;
  2818. }
  2819. #endif /* HAVE_FFDHE_2048 */
  2820. /* Perform the modular exponentiation for Diffie-Hellman.
  2821. *
  2822. * base Base.
  2823. * exp Array of bytes that is the exponent.
  2824. * expLen Length of data, in bytes, in exponent.
  2825. * mod Modulus.
  2826. * out Buffer to hold big-endian bytes of exponentiation result.
  2827. * Must be at least 256 bytes long.
  2828. * outLen Length, in bytes, of exponentiation result.
  2829. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  2830. * and MEMORY_E if memory allocation fails.
  2831. */
  2832. int sp_DhExp_2048(const mp_int* base, const byte* exp, word32 expLen,
  2833. const mp_int* mod, byte* out, word32* outLen)
  2834. {
  2835. #ifdef WOLFSSL_SP_SMALL_STACK
  2836. sp_digit* b = NULL;
  2837. #else
  2838. sp_digit b[34 * 4];
  2839. #endif
  2840. sp_digit* e = NULL;
  2841. sp_digit* m = NULL;
  2842. sp_digit* r = NULL;
  2843. word32 i;
  2844. int err = MP_OKAY;
  2845. if (mp_count_bits(base) > 2048) {
  2846. err = MP_READ_E;
  2847. }
  2848. else if (expLen > 256U) {
  2849. err = MP_READ_E;
  2850. }
  2851. else if (mp_count_bits(mod) != 2048) {
  2852. err = MP_READ_E;
  2853. }
  2854. else if (mp_iseven(mod)) {
  2855. err = MP_VAL;
  2856. }
  2857. #ifdef WOLFSSL_SP_SMALL_STACK
  2858. if (err == MP_OKAY) {
  2859. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 34 * 4, NULL,
  2860. DYNAMIC_TYPE_DH);
  2861. if (b == NULL)
  2862. err = MEMORY_E;
  2863. }
  2864. #endif
  2865. if (err == MP_OKAY) {
  2866. e = b + 34 * 2;
  2867. m = e + 34;
  2868. r = b;
  2869. sp_2048_from_mp(b, 34, base);
  2870. sp_2048_from_bin(e, 34, exp, expLen);
  2871. sp_2048_from_mp(m, 34, mod);
  2872. #ifdef HAVE_FFDHE_2048
  2873. if (base->used == 1 && base->dp[0] == 2U &&
  2874. (m[33] >> 3) == 0xffffffffL) {
  2875. err = sp_2048_mod_exp_2_34(r, e, expLen * 8U, m);
  2876. }
  2877. else {
  2878. #endif
  2879. err = sp_2048_mod_exp_34(r, b, e, expLen * 8U, m, 0);
  2880. #ifdef HAVE_FFDHE_2048
  2881. }
  2882. #endif
  2883. }
  2884. if (err == MP_OKAY) {
  2885. sp_2048_to_bin_34(r, out);
  2886. *outLen = 256;
  2887. for (i=0; i<256U && out[i] == 0U; i++) {
  2888. /* Search for first non-zero. */
  2889. }
  2890. *outLen -= i;
  2891. XMEMMOVE(out, out + i, *outLen);
  2892. }
  2893. #ifdef WOLFSSL_SP_SMALL_STACK
  2894. if (b != NULL)
  2895. #endif
  2896. {
  2897. /* only "e" is sensitive and needs zeroized */
  2898. if (e != NULL)
  2899. ForceZero(e, sizeof(sp_digit) * 34U);
  2900. #ifdef WOLFSSL_SP_SMALL_STACK
  2901. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  2902. #endif
  2903. }
  2904. return err;
  2905. }
  2906. #endif /* WOLFSSL_HAVE_SP_DH */
  2907. /* Perform the modular exponentiation for Diffie-Hellman.
  2908. *
  2909. * base Base. MP integer.
  2910. * exp Exponent. MP integer.
  2911. * mod Modulus. MP integer.
  2912. * res Result. MP integer.
  2913. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  2914. * and MEMORY_E if memory allocation fails.
  2915. */
  2916. int sp_ModExp_1024(const mp_int* base, const mp_int* exp, const mp_int* mod,
  2917. mp_int* res)
  2918. {
  2919. #ifdef WOLFSSL_SP_SMALL
  2920. int err = MP_OKAY;
  2921. #ifdef WOLFSSL_SP_SMALL_STACK
  2922. sp_digit* b = NULL;
  2923. #else
  2924. sp_digit b[17 * 4];
  2925. #endif
  2926. sp_digit* e = NULL;
  2927. sp_digit* m = NULL;
  2928. sp_digit* r = NULL;
  2929. int expBits = mp_count_bits(exp);
  2930. if (mp_count_bits(base) > 1024) {
  2931. err = MP_READ_E;
  2932. }
  2933. else if (expBits > 1024) {
  2934. err = MP_READ_E;
  2935. }
  2936. else if (mp_count_bits(mod) != 1024) {
  2937. err = MP_READ_E;
  2938. }
  2939. else if (mp_iseven(mod)) {
  2940. err = MP_VAL;
  2941. }
  2942. #ifdef WOLFSSL_SP_SMALL_STACK
  2943. if (err == MP_OKAY) {
  2944. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 17 * 4, NULL,
  2945. DYNAMIC_TYPE_DH);
  2946. if (b == NULL)
  2947. err = MEMORY_E;
  2948. }
  2949. #endif
  2950. if (err == MP_OKAY) {
  2951. e = b + 17 * 2;
  2952. m = e + 17;
  2953. r = b;
  2954. sp_2048_from_mp(b, 17, base);
  2955. sp_2048_from_mp(e, 17, exp);
  2956. sp_2048_from_mp(m, 17, mod);
  2957. err = sp_2048_mod_exp_17(r, b, e, mp_count_bits(exp), m, 0);
  2958. }
  2959. if (err == MP_OKAY) {
  2960. XMEMSET(r + 17, 0, sizeof(*r) * 17U);
  2961. err = sp_2048_to_mp(r, res);
  2962. }
  2963. #ifdef WOLFSSL_SP_SMALL_STACK
  2964. if (b != NULL)
  2965. #endif
  2966. {
  2967. /* only "e" is sensitive and needs zeroized */
  2968. if (e != NULL)
  2969. ForceZero(e, sizeof(sp_digit) * 34U);
  2970. #ifdef WOLFSSL_SP_SMALL_STACK
  2971. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  2972. #endif
  2973. }
  2974. return err;
  2975. #else
  2976. #ifdef WOLFSSL_SP_SMALL_STACK
  2977. sp_digit* b = NULL;
  2978. #else
  2979. sp_digit b[17 * 4];
  2980. #endif
  2981. sp_digit* e = NULL;
  2982. sp_digit* m = NULL;
  2983. sp_digit* r = NULL;
  2984. int err = MP_OKAY;
  2985. int expBits = mp_count_bits(exp);
  2986. if (mp_count_bits(base) > 1024) {
  2987. err = MP_READ_E;
  2988. }
  2989. else if (expBits > 1024) {
  2990. err = MP_READ_E;
  2991. }
  2992. else if (mp_count_bits(mod) != 1024) {
  2993. err = MP_READ_E;
  2994. }
  2995. else if (mp_iseven(mod)) {
  2996. err = MP_VAL;
  2997. }
  2998. #ifdef WOLFSSL_SP_SMALL_STACK
  2999. if (err == MP_OKAY) {
  3000. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 17 * 4, NULL, DYNAMIC_TYPE_DH);
  3001. if (b == NULL)
  3002. err = MEMORY_E;
  3003. }
  3004. #endif
  3005. if (err == MP_OKAY) {
  3006. e = b + 17 * 2;
  3007. m = e + 17;
  3008. r = b;
  3009. sp_2048_from_mp(b, 17, base);
  3010. sp_2048_from_mp(e, 17, exp);
  3011. sp_2048_from_mp(m, 17, mod);
  3012. err = sp_2048_mod_exp_17(r, b, e, expBits, m, 0);
  3013. }
  3014. if (err == MP_OKAY) {
  3015. XMEMSET(r + 17, 0, sizeof(*r) * 17U);
  3016. err = sp_2048_to_mp(r, res);
  3017. }
  3018. #ifdef WOLFSSL_SP_SMALL_STACK
  3019. if (b != NULL)
  3020. #endif
  3021. {
  3022. /* only "e" is sensitive and needs zeroized */
  3023. if (e != NULL)
  3024. ForceZero(e, sizeof(sp_digit) * 34U);
  3025. #ifdef WOLFSSL_SP_SMALL_STACK
  3026. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  3027. #endif
  3028. }
  3029. return err;
  3030. #endif
  3031. }
  3032. #endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */
  3033. #else
  3034. /* Read big endian unsigned byte array into r.
  3035. *
  3036. * r A single precision integer.
  3037. * size Maximum number of bytes to convert
  3038. * a Byte array.
  3039. * n Number of bytes in array to read.
  3040. */
  3041. static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n)
  3042. {
  3043. int i;
  3044. int j = 0;
  3045. word32 s = 0;
  3046. r[0] = 0;
  3047. for (i = n-1; i >= 0; i--) {
  3048. r[j] |= (((sp_digit)a[i]) << s);
  3049. if (s >= 49U) {
  3050. r[j] &= 0x1ffffffffffffffL;
  3051. s = 57U - s;
  3052. if (j + 1 >= size) {
  3053. break;
  3054. }
  3055. r[++j] = (sp_digit)a[i] >> s;
  3056. s = 8U - s;
  3057. }
  3058. else {
  3059. s += 8U;
  3060. }
  3061. }
  3062. for (j++; j < size; j++) {
  3063. r[j] = 0;
  3064. }
  3065. }
  3066. /* Convert an mp_int to an array of sp_digit.
  3067. *
  3068. * r A single precision integer.
  3069. * size Maximum number of bytes to convert
  3070. * a A multi-precision integer.
  3071. */
  3072. static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a)
  3073. {
  3074. #if DIGIT_BIT == 57
  3075. int i;
  3076. sp_digit j = (sp_digit)0 - (sp_digit)a->used;
  3077. int o = 0;
  3078. for (i = 0; i < size; i++) {
  3079. sp_digit mask = (sp_digit)0 - (j >> 56);
  3080. r[i] = a->dp[o] & mask;
  3081. j++;
  3082. o += (int)(j >> 56);
  3083. }
  3084. #elif DIGIT_BIT > 57
  3085. unsigned int i;
  3086. int j = 0;
  3087. word32 s = 0;
  3088. r[0] = 0;
  3089. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  3090. r[j] |= ((sp_digit)a->dp[i] << s);
  3091. r[j] &= 0x1ffffffffffffffL;
  3092. s = 57U - s;
  3093. if (j + 1 >= size) {
  3094. break;
  3095. }
  3096. /* lint allow cast of mismatch word32 and mp_digit */
  3097. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  3098. while ((s + 57U) <= (word32)DIGIT_BIT) {
  3099. s += 57U;
  3100. r[j] &= 0x1ffffffffffffffL;
  3101. if (j + 1 >= size) {
  3102. break;
  3103. }
  3104. if (s < (word32)DIGIT_BIT) {
  3105. /* lint allow cast of mismatch word32 and mp_digit */
  3106. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  3107. }
  3108. else {
  3109. r[++j] = (sp_digit)0;
  3110. }
  3111. }
  3112. s = (word32)DIGIT_BIT - s;
  3113. }
  3114. for (j++; j < size; j++) {
  3115. r[j] = 0;
  3116. }
  3117. #else
  3118. unsigned int i;
  3119. int j = 0;
  3120. int s = 0;
  3121. r[0] = 0;
  3122. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  3123. r[j] |= ((sp_digit)a->dp[i]) << s;
  3124. if (s + DIGIT_BIT >= 57) {
  3125. r[j] &= 0x1ffffffffffffffL;
  3126. if (j + 1 >= size) {
  3127. break;
  3128. }
  3129. s = 57 - s;
  3130. if (s == DIGIT_BIT) {
  3131. r[++j] = 0;
  3132. s = 0;
  3133. }
  3134. else {
  3135. r[++j] = a->dp[i] >> s;
  3136. s = DIGIT_BIT - s;
  3137. }
  3138. }
  3139. else {
  3140. s += DIGIT_BIT;
  3141. }
  3142. }
  3143. for (j++; j < size; j++) {
  3144. r[j] = 0;
  3145. }
  3146. #endif
  3147. }
  3148. /* Write r as big endian to byte array.
  3149. * Fixed length number of bytes written: 256
  3150. *
  3151. * r A single precision integer.
  3152. * a Byte array.
  3153. */
  3154. static void sp_2048_to_bin_36(sp_digit* r, byte* a)
  3155. {
  3156. int i;
  3157. int j;
  3158. int s = 0;
  3159. int b;
  3160. for (i=0; i<35; i++) {
  3161. r[i+1] += r[i] >> 57;
  3162. r[i] &= 0x1ffffffffffffffL;
  3163. }
  3164. j = 2055 / 8 - 1;
  3165. a[j] = 0;
  3166. for (i=0; i<36 && j>=0; i++) {
  3167. b = 0;
  3168. /* lint allow cast of mismatch sp_digit and int */
  3169. a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
  3170. b += 8 - s;
  3171. if (j < 0) {
  3172. break;
  3173. }
  3174. while (b < 57) {
  3175. a[j--] = (byte)(r[i] >> b);
  3176. b += 8;
  3177. if (j < 0) {
  3178. break;
  3179. }
  3180. }
  3181. s = 8 - (b - 57);
  3182. if (j >= 0) {
  3183. a[j] = 0;
  3184. }
  3185. if (s != 0) {
  3186. j++;
  3187. }
  3188. }
  3189. }
  3190. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  3191. /* Normalize the values in each word to 57 bits.
  3192. *
  3193. * a Array of sp_digit to normalize.
  3194. */
  3195. static void sp_2048_norm_18(sp_digit* a)
  3196. {
  3197. int i;
  3198. for (i = 0; i < 16; i += 8) {
  3199. a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL;
  3200. a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL;
  3201. a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL;
  3202. a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL;
  3203. a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL;
  3204. a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL;
  3205. a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL;
  3206. a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL;
  3207. }
  3208. a[17] += a[16] >> 57; a[16] &= 0x1ffffffffffffffL;
  3209. }
  3210. #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
  3211. /* Normalize the values in each word to 57 bits.
  3212. *
  3213. * a Array of sp_digit to normalize.
  3214. */
  3215. static void sp_2048_norm_36(sp_digit* a)
  3216. {
  3217. int i;
  3218. for (i = 0; i < 32; i += 8) {
  3219. a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL;
  3220. a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL;
  3221. a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL;
  3222. a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL;
  3223. a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL;
  3224. a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL;
  3225. a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL;
  3226. a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL;
  3227. }
  3228. a[33] += a[32] >> 57; a[32] &= 0x1ffffffffffffffL;
  3229. a[34] += a[33] >> 57; a[33] &= 0x1ffffffffffffffL;
  3230. a[35] += a[34] >> 57; a[34] &= 0x1ffffffffffffffL;
  3231. }
  3232. #ifndef WOLFSSL_SP_SMALL
  3233. /* Multiply a and b into r. (r = a * b)
  3234. *
  3235. * r A single precision integer.
  3236. * a A single precision integer.
  3237. * b A single precision integer.
  3238. */
  3239. SP_NOINLINE static void sp_2048_mul_9(sp_digit* r, const sp_digit* a,
  3240. const sp_digit* b)
  3241. {
  3242. sp_uint128 t0;
  3243. sp_uint128 t1;
  3244. sp_digit t[9];
  3245. t0 = ((sp_uint128)a[ 0]) * b[ 0];
  3246. t1 = ((sp_uint128)a[ 0]) * b[ 1]
  3247. + ((sp_uint128)a[ 1]) * b[ 0];
  3248. t[ 0] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3249. t0 = ((sp_uint128)a[ 0]) * b[ 2]
  3250. + ((sp_uint128)a[ 1]) * b[ 1]
  3251. + ((sp_uint128)a[ 2]) * b[ 0];
  3252. t[ 1] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3253. t1 = ((sp_uint128)a[ 0]) * b[ 3]
  3254. + ((sp_uint128)a[ 1]) * b[ 2]
  3255. + ((sp_uint128)a[ 2]) * b[ 1]
  3256. + ((sp_uint128)a[ 3]) * b[ 0];
  3257. t[ 2] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3258. t0 = ((sp_uint128)a[ 0]) * b[ 4]
  3259. + ((sp_uint128)a[ 1]) * b[ 3]
  3260. + ((sp_uint128)a[ 2]) * b[ 2]
  3261. + ((sp_uint128)a[ 3]) * b[ 1]
  3262. + ((sp_uint128)a[ 4]) * b[ 0];
  3263. t[ 3] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3264. t1 = ((sp_uint128)a[ 0]) * b[ 5]
  3265. + ((sp_uint128)a[ 1]) * b[ 4]
  3266. + ((sp_uint128)a[ 2]) * b[ 3]
  3267. + ((sp_uint128)a[ 3]) * b[ 2]
  3268. + ((sp_uint128)a[ 4]) * b[ 1]
  3269. + ((sp_uint128)a[ 5]) * b[ 0];
  3270. t[ 4] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3271. t0 = ((sp_uint128)a[ 0]) * b[ 6]
  3272. + ((sp_uint128)a[ 1]) * b[ 5]
  3273. + ((sp_uint128)a[ 2]) * b[ 4]
  3274. + ((sp_uint128)a[ 3]) * b[ 3]
  3275. + ((sp_uint128)a[ 4]) * b[ 2]
  3276. + ((sp_uint128)a[ 5]) * b[ 1]
  3277. + ((sp_uint128)a[ 6]) * b[ 0];
  3278. t[ 5] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3279. t1 = ((sp_uint128)a[ 0]) * b[ 7]
  3280. + ((sp_uint128)a[ 1]) * b[ 6]
  3281. + ((sp_uint128)a[ 2]) * b[ 5]
  3282. + ((sp_uint128)a[ 3]) * b[ 4]
  3283. + ((sp_uint128)a[ 4]) * b[ 3]
  3284. + ((sp_uint128)a[ 5]) * b[ 2]
  3285. + ((sp_uint128)a[ 6]) * b[ 1]
  3286. + ((sp_uint128)a[ 7]) * b[ 0];
  3287. t[ 6] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3288. t0 = ((sp_uint128)a[ 0]) * b[ 8]
  3289. + ((sp_uint128)a[ 1]) * b[ 7]
  3290. + ((sp_uint128)a[ 2]) * b[ 6]
  3291. + ((sp_uint128)a[ 3]) * b[ 5]
  3292. + ((sp_uint128)a[ 4]) * b[ 4]
  3293. + ((sp_uint128)a[ 5]) * b[ 3]
  3294. + ((sp_uint128)a[ 6]) * b[ 2]
  3295. + ((sp_uint128)a[ 7]) * b[ 1]
  3296. + ((sp_uint128)a[ 8]) * b[ 0];
  3297. t[ 7] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3298. t1 = ((sp_uint128)a[ 1]) * b[ 8]
  3299. + ((sp_uint128)a[ 2]) * b[ 7]
  3300. + ((sp_uint128)a[ 3]) * b[ 6]
  3301. + ((sp_uint128)a[ 4]) * b[ 5]
  3302. + ((sp_uint128)a[ 5]) * b[ 4]
  3303. + ((sp_uint128)a[ 6]) * b[ 3]
  3304. + ((sp_uint128)a[ 7]) * b[ 2]
  3305. + ((sp_uint128)a[ 8]) * b[ 1];
  3306. t[ 8] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3307. t0 = ((sp_uint128)a[ 2]) * b[ 8]
  3308. + ((sp_uint128)a[ 3]) * b[ 7]
  3309. + ((sp_uint128)a[ 4]) * b[ 6]
  3310. + ((sp_uint128)a[ 5]) * b[ 5]
  3311. + ((sp_uint128)a[ 6]) * b[ 4]
  3312. + ((sp_uint128)a[ 7]) * b[ 3]
  3313. + ((sp_uint128)a[ 8]) * b[ 2];
  3314. r[ 9] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3315. t1 = ((sp_uint128)a[ 3]) * b[ 8]
  3316. + ((sp_uint128)a[ 4]) * b[ 7]
  3317. + ((sp_uint128)a[ 5]) * b[ 6]
  3318. + ((sp_uint128)a[ 6]) * b[ 5]
  3319. + ((sp_uint128)a[ 7]) * b[ 4]
  3320. + ((sp_uint128)a[ 8]) * b[ 3];
  3321. r[10] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3322. t0 = ((sp_uint128)a[ 4]) * b[ 8]
  3323. + ((sp_uint128)a[ 5]) * b[ 7]
  3324. + ((sp_uint128)a[ 6]) * b[ 6]
  3325. + ((sp_uint128)a[ 7]) * b[ 5]
  3326. + ((sp_uint128)a[ 8]) * b[ 4];
  3327. r[11] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3328. t1 = ((sp_uint128)a[ 5]) * b[ 8]
  3329. + ((sp_uint128)a[ 6]) * b[ 7]
  3330. + ((sp_uint128)a[ 7]) * b[ 6]
  3331. + ((sp_uint128)a[ 8]) * b[ 5];
  3332. r[12] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3333. t0 = ((sp_uint128)a[ 6]) * b[ 8]
  3334. + ((sp_uint128)a[ 7]) * b[ 7]
  3335. + ((sp_uint128)a[ 8]) * b[ 6];
  3336. r[13] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3337. t1 = ((sp_uint128)a[ 7]) * b[ 8]
  3338. + ((sp_uint128)a[ 8]) * b[ 7];
  3339. r[14] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3340. t0 = ((sp_uint128)a[ 8]) * b[ 8];
  3341. r[15] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3342. r[16] = t0 & 0x1ffffffffffffffL;
  3343. r[17] = (sp_digit)(t0 >> 57);
  3344. XMEMCPY(r, t, sizeof(t));
  3345. }
  3346. /* Add b to a into r. (r = a + b)
  3347. *
  3348. * r A single precision integer.
  3349. * a A single precision integer.
  3350. * b A single precision integer.
  3351. */
  3352. SP_NOINLINE static int sp_2048_add_9(sp_digit* r, const sp_digit* a,
  3353. const sp_digit* b)
  3354. {
  3355. r[ 0] = a[ 0] + b[ 0];
  3356. r[ 1] = a[ 1] + b[ 1];
  3357. r[ 2] = a[ 2] + b[ 2];
  3358. r[ 3] = a[ 3] + b[ 3];
  3359. r[ 4] = a[ 4] + b[ 4];
  3360. r[ 5] = a[ 5] + b[ 5];
  3361. r[ 6] = a[ 6] + b[ 6];
  3362. r[ 7] = a[ 7] + b[ 7];
  3363. r[ 8] = a[ 8] + b[ 8];
  3364. return 0;
  3365. }
  3366. /* Add b to a into r. (r = a + b)
  3367. *
  3368. * r A single precision integer.
  3369. * a A single precision integer.
  3370. * b A single precision integer.
  3371. */
  3372. SP_NOINLINE static int sp_2048_add_18(sp_digit* r, const sp_digit* a,
  3373. const sp_digit* b)
  3374. {
  3375. int i;
  3376. for (i = 0; i < 16; i += 8) {
  3377. r[i + 0] = a[i + 0] + b[i + 0];
  3378. r[i + 1] = a[i + 1] + b[i + 1];
  3379. r[i + 2] = a[i + 2] + b[i + 2];
  3380. r[i + 3] = a[i + 3] + b[i + 3];
  3381. r[i + 4] = a[i + 4] + b[i + 4];
  3382. r[i + 5] = a[i + 5] + b[i + 5];
  3383. r[i + 6] = a[i + 6] + b[i + 6];
  3384. r[i + 7] = a[i + 7] + b[i + 7];
  3385. }
  3386. r[16] = a[16] + b[16];
  3387. r[17] = a[17] + b[17];
  3388. return 0;
  3389. }
  3390. /* Sub b from a into r. (r = a - b)
  3391. *
  3392. * r A single precision integer.
  3393. * a A single precision integer.
  3394. * b A single precision integer.
  3395. */
  3396. SP_NOINLINE static int sp_2048_sub_18(sp_digit* r, const sp_digit* a,
  3397. const sp_digit* b)
  3398. {
  3399. int i;
  3400. for (i = 0; i < 16; i += 8) {
  3401. r[i + 0] = a[i + 0] - b[i + 0];
  3402. r[i + 1] = a[i + 1] - b[i + 1];
  3403. r[i + 2] = a[i + 2] - b[i + 2];
  3404. r[i + 3] = a[i + 3] - b[i + 3];
  3405. r[i + 4] = a[i + 4] - b[i + 4];
  3406. r[i + 5] = a[i + 5] - b[i + 5];
  3407. r[i + 6] = a[i + 6] - b[i + 6];
  3408. r[i + 7] = a[i + 7] - b[i + 7];
  3409. }
  3410. r[16] = a[16] - b[16];
  3411. r[17] = a[17] - b[17];
  3412. return 0;
  3413. }
  3414. /* Multiply a and b into r. (r = a * b)
  3415. *
  3416. * r A single precision integer.
  3417. * a A single precision integer.
  3418. * b A single precision integer.
  3419. */
  3420. SP_NOINLINE static void sp_2048_mul_18(sp_digit* r, const sp_digit* a,
  3421. const sp_digit* b)
  3422. {
  3423. sp_digit* z0 = r;
  3424. sp_digit z1[18];
  3425. sp_digit* a1 = z1;
  3426. sp_digit b1[9];
  3427. sp_digit* z2 = r + 18;
  3428. (void)sp_2048_add_9(a1, a, &a[9]);
  3429. (void)sp_2048_add_9(b1, b, &b[9]);
  3430. sp_2048_mul_9(z2, &a[9], &b[9]);
  3431. sp_2048_mul_9(z0, a, b);
  3432. sp_2048_mul_9(z1, a1, b1);
  3433. (void)sp_2048_sub_18(z1, z1, z2);
  3434. (void)sp_2048_sub_18(z1, z1, z0);
  3435. (void)sp_2048_add_18(r + 9, r + 9, z1);
  3436. }
  3437. /* Add b to a into r. (r = a + b)
  3438. *
  3439. * r A single precision integer.
  3440. * a A single precision integer.
  3441. * b A single precision integer.
  3442. */
  3443. SP_NOINLINE static int sp_2048_add_36(sp_digit* r, const sp_digit* a,
  3444. const sp_digit* b)
  3445. {
  3446. int i;
  3447. for (i = 0; i < 32; i += 8) {
  3448. r[i + 0] = a[i + 0] + b[i + 0];
  3449. r[i + 1] = a[i + 1] + b[i + 1];
  3450. r[i + 2] = a[i + 2] + b[i + 2];
  3451. r[i + 3] = a[i + 3] + b[i + 3];
  3452. r[i + 4] = a[i + 4] + b[i + 4];
  3453. r[i + 5] = a[i + 5] + b[i + 5];
  3454. r[i + 6] = a[i + 6] + b[i + 6];
  3455. r[i + 7] = a[i + 7] + b[i + 7];
  3456. }
  3457. r[32] = a[32] + b[32];
  3458. r[33] = a[33] + b[33];
  3459. r[34] = a[34] + b[34];
  3460. r[35] = a[35] + b[35];
  3461. return 0;
  3462. }
  3463. /* Sub b from a into r. (r = a - b)
  3464. *
  3465. * r A single precision integer.
  3466. * a A single precision integer.
  3467. * b A single precision integer.
  3468. */
  3469. SP_NOINLINE static int sp_2048_sub_36(sp_digit* r, const sp_digit* a,
  3470. const sp_digit* b)
  3471. {
  3472. int i;
  3473. for (i = 0; i < 32; i += 8) {
  3474. r[i + 0] = a[i + 0] - b[i + 0];
  3475. r[i + 1] = a[i + 1] - b[i + 1];
  3476. r[i + 2] = a[i + 2] - b[i + 2];
  3477. r[i + 3] = a[i + 3] - b[i + 3];
  3478. r[i + 4] = a[i + 4] - b[i + 4];
  3479. r[i + 5] = a[i + 5] - b[i + 5];
  3480. r[i + 6] = a[i + 6] - b[i + 6];
  3481. r[i + 7] = a[i + 7] - b[i + 7];
  3482. }
  3483. r[32] = a[32] - b[32];
  3484. r[33] = a[33] - b[33];
  3485. r[34] = a[34] - b[34];
  3486. r[35] = a[35] - b[35];
  3487. return 0;
  3488. }
  3489. /* Multiply a and b into r. (r = a * b)
  3490. *
  3491. * r A single precision integer.
  3492. * a A single precision integer.
  3493. * b A single precision integer.
  3494. */
  3495. SP_NOINLINE static void sp_2048_mul_36(sp_digit* r, const sp_digit* a,
  3496. const sp_digit* b)
  3497. {
  3498. sp_digit* z0 = r;
  3499. sp_digit z1[36];
  3500. sp_digit* a1 = z1;
  3501. sp_digit b1[18];
  3502. sp_digit* z2 = r + 36;
  3503. (void)sp_2048_add_18(a1, a, &a[18]);
  3504. (void)sp_2048_add_18(b1, b, &b[18]);
  3505. sp_2048_mul_18(z2, &a[18], &b[18]);
  3506. sp_2048_mul_18(z0, a, b);
  3507. sp_2048_mul_18(z1, a1, b1);
  3508. (void)sp_2048_sub_36(z1, z1, z2);
  3509. (void)sp_2048_sub_36(z1, z1, z0);
  3510. (void)sp_2048_add_36(r + 18, r + 18, z1);
  3511. }
  3512. /* Square a and put result in r. (r = a * a)
  3513. *
  3514. * r A single precision integer.
  3515. * a A single precision integer.
  3516. */
  3517. SP_NOINLINE static void sp_2048_sqr_9(sp_digit* r, const sp_digit* a)
  3518. {
  3519. sp_uint128 t0;
  3520. sp_uint128 t1;
  3521. sp_digit t[9];
  3522. t0 = ((sp_uint128)a[ 0]) * a[ 0];
  3523. t1 = (((sp_uint128)a[ 0]) * a[ 1]) * 2;
  3524. t[ 0] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3525. t0 = (((sp_uint128)a[ 0]) * a[ 2]) * 2
  3526. + ((sp_uint128)a[ 1]) * a[ 1];
  3527. t[ 1] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3528. t1 = (((sp_uint128)a[ 0]) * a[ 3]
  3529. + ((sp_uint128)a[ 1]) * a[ 2]) * 2;
  3530. t[ 2] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3531. t0 = (((sp_uint128)a[ 0]) * a[ 4]
  3532. + ((sp_uint128)a[ 1]) * a[ 3]) * 2
  3533. + ((sp_uint128)a[ 2]) * a[ 2];
  3534. t[ 3] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3535. t1 = (((sp_uint128)a[ 0]) * a[ 5]
  3536. + ((sp_uint128)a[ 1]) * a[ 4]
  3537. + ((sp_uint128)a[ 2]) * a[ 3]) * 2;
  3538. t[ 4] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3539. t0 = (((sp_uint128)a[ 0]) * a[ 6]
  3540. + ((sp_uint128)a[ 1]) * a[ 5]
  3541. + ((sp_uint128)a[ 2]) * a[ 4]) * 2
  3542. + ((sp_uint128)a[ 3]) * a[ 3];
  3543. t[ 5] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3544. t1 = (((sp_uint128)a[ 0]) * a[ 7]
  3545. + ((sp_uint128)a[ 1]) * a[ 6]
  3546. + ((sp_uint128)a[ 2]) * a[ 5]
  3547. + ((sp_uint128)a[ 3]) * a[ 4]) * 2;
  3548. t[ 6] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3549. t0 = (((sp_uint128)a[ 0]) * a[ 8]
  3550. + ((sp_uint128)a[ 1]) * a[ 7]
  3551. + ((sp_uint128)a[ 2]) * a[ 6]
  3552. + ((sp_uint128)a[ 3]) * a[ 5]) * 2
  3553. + ((sp_uint128)a[ 4]) * a[ 4];
  3554. t[ 7] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3555. t1 = (((sp_uint128)a[ 1]) * a[ 8]
  3556. + ((sp_uint128)a[ 2]) * a[ 7]
  3557. + ((sp_uint128)a[ 3]) * a[ 6]
  3558. + ((sp_uint128)a[ 4]) * a[ 5]) * 2;
  3559. t[ 8] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3560. t0 = (((sp_uint128)a[ 2]) * a[ 8]
  3561. + ((sp_uint128)a[ 3]) * a[ 7]
  3562. + ((sp_uint128)a[ 4]) * a[ 6]) * 2
  3563. + ((sp_uint128)a[ 5]) * a[ 5];
  3564. r[ 9] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3565. t1 = (((sp_uint128)a[ 3]) * a[ 8]
  3566. + ((sp_uint128)a[ 4]) * a[ 7]
  3567. + ((sp_uint128)a[ 5]) * a[ 6]) * 2;
  3568. r[10] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3569. t0 = (((sp_uint128)a[ 4]) * a[ 8]
  3570. + ((sp_uint128)a[ 5]) * a[ 7]) * 2
  3571. + ((sp_uint128)a[ 6]) * a[ 6];
  3572. r[11] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3573. t1 = (((sp_uint128)a[ 5]) * a[ 8]
  3574. + ((sp_uint128)a[ 6]) * a[ 7]) * 2;
  3575. r[12] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3576. t0 = (((sp_uint128)a[ 6]) * a[ 8]) * 2
  3577. + ((sp_uint128)a[ 7]) * a[ 7];
  3578. r[13] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3579. t1 = (((sp_uint128)a[ 7]) * a[ 8]) * 2;
  3580. r[14] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  3581. t0 = ((sp_uint128)a[ 8]) * a[ 8];
  3582. r[15] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  3583. r[16] = t0 & 0x1ffffffffffffffL;
  3584. r[17] = (sp_digit)(t0 >> 57);
  3585. XMEMCPY(r, t, sizeof(t));
  3586. }
  3587. /* Square a and put result in r. (r = a * a)
  3588. *
  3589. * r A single precision integer.
  3590. * a A single precision integer.
  3591. */
  3592. SP_NOINLINE static void sp_2048_sqr_18(sp_digit* r, const sp_digit* a)
  3593. {
  3594. sp_digit* z0 = r;
  3595. sp_digit z1[18];
  3596. sp_digit* a1 = z1;
  3597. sp_digit* z2 = r + 18;
  3598. (void)sp_2048_add_9(a1, a, &a[9]);
  3599. sp_2048_sqr_9(z2, &a[9]);
  3600. sp_2048_sqr_9(z0, a);
  3601. sp_2048_sqr_9(z1, a1);
  3602. (void)sp_2048_sub_18(z1, z1, z2);
  3603. (void)sp_2048_sub_18(z1, z1, z0);
  3604. (void)sp_2048_add_18(r + 9, r + 9, z1);
  3605. }
  3606. /* Square a and put result in r. (r = a * a)
  3607. *
  3608. * r A single precision integer.
  3609. * a A single precision integer.
  3610. */
  3611. SP_NOINLINE static void sp_2048_sqr_36(sp_digit* r, const sp_digit* a)
  3612. {
  3613. sp_digit* z0 = r;
  3614. sp_digit z1[36];
  3615. sp_digit* a1 = z1;
  3616. sp_digit* z2 = r + 36;
  3617. (void)sp_2048_add_18(a1, a, &a[18]);
  3618. sp_2048_sqr_18(z2, &a[18]);
  3619. sp_2048_sqr_18(z0, a);
  3620. sp_2048_sqr_18(z1, a1);
  3621. (void)sp_2048_sub_36(z1, z1, z2);
  3622. (void)sp_2048_sub_36(z1, z1, z0);
  3623. (void)sp_2048_add_36(r + 18, r + 18, z1);
  3624. }
  3625. #endif /* !WOLFSSL_SP_SMALL */
  3626. /* Calculate the bottom digit of -1/a mod 2^n.
  3627. *
  3628. * a A single precision number.
  3629. * rho Bottom word of inverse.
  3630. */
  3631. static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho)
  3632. {
  3633. sp_digit x;
  3634. sp_digit b;
  3635. b = a[0];
  3636. x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
  3637. x *= 2 - b * x; /* here x*a==1 mod 2**8 */
  3638. x *= 2 - b * x; /* here x*a==1 mod 2**16 */
  3639. x *= 2 - b * x; /* here x*a==1 mod 2**32 */
  3640. x *= 2 - b * x; /* here x*a==1 mod 2**64 */
  3641. x &= 0x1ffffffffffffffL;
  3642. /* rho = -1/m mod b */
  3643. *rho = ((sp_digit)1 << 57) - x;
  3644. }
  3645. /* Multiply a by scalar b into r. (r = a * b)
  3646. *
  3647. * r A single precision integer.
  3648. * a A single precision integer.
  3649. * b A scalar.
  3650. */
  3651. SP_NOINLINE static void sp_2048_mul_d_36(sp_digit* r, const sp_digit* a,
  3652. sp_digit b)
  3653. {
  3654. sp_int128 tb = b;
  3655. sp_int128 t = 0;
  3656. sp_digit t2;
  3657. sp_int128 p[4];
  3658. int i;
  3659. for (i = 0; i < 36; i += 4) {
  3660. p[0] = tb * a[i + 0];
  3661. p[1] = tb * a[i + 1];
  3662. p[2] = tb * a[i + 2];
  3663. p[3] = tb * a[i + 3];
  3664. t += p[0];
  3665. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  3666. t >>= 57;
  3667. r[i + 0] = (sp_digit)t2;
  3668. t += p[1];
  3669. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  3670. t >>= 57;
  3671. r[i + 1] = (sp_digit)t2;
  3672. t += p[2];
  3673. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  3674. t >>= 57;
  3675. r[i + 2] = (sp_digit)t2;
  3676. t += p[3];
  3677. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  3678. t >>= 57;
  3679. r[i + 3] = (sp_digit)t2;
  3680. }
  3681. r[36] = (sp_digit)(t & 0x1ffffffffffffffL);
  3682. }
  3683. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  3684. /* r = 2^n mod m where n is the number of bits to reduce by.
  3685. * Given m must be 2048 bits, just need to subtract.
  3686. *
  3687. * r A single precision number.
  3688. * m A single precision number.
  3689. */
  3690. static void sp_2048_mont_norm_18(sp_digit* r, const sp_digit* m)
  3691. {
  3692. /* Set r = 2^n - 1. */
  3693. int i;
  3694. for (i = 0; i < 16; i += 8) {
  3695. r[i + 0] = 0x1ffffffffffffffL;
  3696. r[i + 1] = 0x1ffffffffffffffL;
  3697. r[i + 2] = 0x1ffffffffffffffL;
  3698. r[i + 3] = 0x1ffffffffffffffL;
  3699. r[i + 4] = 0x1ffffffffffffffL;
  3700. r[i + 5] = 0x1ffffffffffffffL;
  3701. r[i + 6] = 0x1ffffffffffffffL;
  3702. r[i + 7] = 0x1ffffffffffffffL;
  3703. }
  3704. r[16] = 0x1ffffffffffffffL;
  3705. r[17] = 0x7fffffffffffffL;
  3706. /* r = (2^n - 1) mod n */
  3707. (void)sp_2048_sub_18(r, r, m);
  3708. /* Add one so r = 2^n mod m */
  3709. r[0] += 1;
  3710. }
  3711. /* Compare a with b in constant time.
  3712. *
  3713. * a A single precision integer.
  3714. * b A single precision integer.
  3715. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  3716. * respectively.
  3717. */
  3718. static sp_digit sp_2048_cmp_18(const sp_digit* a, const sp_digit* b)
  3719. {
  3720. sp_digit r = 0;
  3721. int i;
  3722. r |= (a[17] - b[17]) & (0 - (sp_digit)1);
  3723. r |= (a[16] - b[16]) & ~(((sp_digit)0 - r) >> 56);
  3724. for (i = 8; i >= 0; i -= 8) {
  3725. r |= (a[i + 7] - b[i + 7]) & ~(((sp_digit)0 - r) >> 56);
  3726. r |= (a[i + 6] - b[i + 6]) & ~(((sp_digit)0 - r) >> 56);
  3727. r |= (a[i + 5] - b[i + 5]) & ~(((sp_digit)0 - r) >> 56);
  3728. r |= (a[i + 4] - b[i + 4]) & ~(((sp_digit)0 - r) >> 56);
  3729. r |= (a[i + 3] - b[i + 3]) & ~(((sp_digit)0 - r) >> 56);
  3730. r |= (a[i + 2] - b[i + 2]) & ~(((sp_digit)0 - r) >> 56);
  3731. r |= (a[i + 1] - b[i + 1]) & ~(((sp_digit)0 - r) >> 56);
  3732. r |= (a[i + 0] - b[i + 0]) & ~(((sp_digit)0 - r) >> 56);
  3733. }
  3734. return r;
  3735. }
  3736. /* Conditionally subtract b from a using the mask m.
  3737. * m is -1 to subtract and 0 when not.
  3738. *
  3739. * r A single precision number representing condition subtract result.
  3740. * a A single precision number to subtract from.
  3741. * b A single precision number to subtract.
  3742. * m Mask value to apply.
  3743. */
  3744. static void sp_2048_cond_sub_18(sp_digit* r, const sp_digit* a,
  3745. const sp_digit* b, const sp_digit m)
  3746. {
  3747. int i;
  3748. for (i = 0; i < 16; i += 8) {
  3749. r[i + 0] = a[i + 0] - (b[i + 0] & m);
  3750. r[i + 1] = a[i + 1] - (b[i + 1] & m);
  3751. r[i + 2] = a[i + 2] - (b[i + 2] & m);
  3752. r[i + 3] = a[i + 3] - (b[i + 3] & m);
  3753. r[i + 4] = a[i + 4] - (b[i + 4] & m);
  3754. r[i + 5] = a[i + 5] - (b[i + 5] & m);
  3755. r[i + 6] = a[i + 6] - (b[i + 6] & m);
  3756. r[i + 7] = a[i + 7] - (b[i + 7] & m);
  3757. }
  3758. r[16] = a[16] - (b[16] & m);
  3759. r[17] = a[17] - (b[17] & m);
  3760. }
  3761. /* Mul a by scalar b and add into r. (r += a * b)
  3762. *
  3763. * r A single precision integer.
  3764. * a A single precision integer.
  3765. * b A scalar.
  3766. */
  3767. SP_NOINLINE static void sp_2048_mul_add_18(sp_digit* r, const sp_digit* a,
  3768. const sp_digit b)
  3769. {
  3770. sp_int128 tb = b;
  3771. sp_int128 t[8];
  3772. int i;
  3773. t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL);
  3774. for (i = 0; i < 16; i += 8) {
  3775. t[1] = tb * a[i+1];
  3776. r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
  3777. t[2] = tb * a[i+2];
  3778. r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
  3779. t[3] = tb * a[i+3];
  3780. r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));
  3781. t[4] = tb * a[i+4];
  3782. r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));
  3783. t[5] = tb * a[i+5];
  3784. r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));
  3785. t[6] = tb * a[i+6];
  3786. r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL));
  3787. t[7] = tb * a[i+7];
  3788. r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL));
  3789. t[0] = tb * a[i+8];
  3790. r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL));
  3791. }
  3792. t[1] = tb * a[17];
  3793. r[17] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
  3794. r[18] += (sp_digit)(t[1] >> 57);
  3795. }
  3796. /* Shift the result in the high 1024 bits down to the bottom.
  3797. *
  3798. * r A single precision number.
  3799. * a A single precision number.
  3800. */
  3801. static void sp_2048_mont_shift_18(sp_digit* r, const sp_digit* a)
  3802. {
  3803. sp_uint64 n;
  3804. int i;
  3805. n = (sp_uint64)a[17];
  3806. n = n >> 55U;
  3807. for (i = 0; i < 16; i += 8) {
  3808. n += (sp_uint64)a[i+18] << 2U; r[i+0] = n & 0x1ffffffffffffffUL; n >>= 57U;
  3809. n += (sp_uint64)a[i+19] << 2U; r[i+1] = n & 0x1ffffffffffffffUL; n >>= 57U;
  3810. n += (sp_uint64)a[i+20] << 2U; r[i+2] = n & 0x1ffffffffffffffUL; n >>= 57U;
  3811. n += (sp_uint64)a[i+21] << 2U; r[i+3] = n & 0x1ffffffffffffffUL; n >>= 57U;
  3812. n += (sp_uint64)a[i+22] << 2U; r[i+4] = n & 0x1ffffffffffffffUL; n >>= 57U;
  3813. n += (sp_uint64)a[i+23] << 2U; r[i+5] = n & 0x1ffffffffffffffUL; n >>= 57U;
  3814. n += (sp_uint64)a[i+24] << 2U; r[i+6] = n & 0x1ffffffffffffffUL; n >>= 57U;
  3815. n += (sp_uint64)a[i+25] << 2U; r[i+7] = n & 0x1ffffffffffffffUL; n >>= 57U;
  3816. }
  3817. n += (sp_uint64)a[34] << 2U; r[16] = n & 0x1ffffffffffffffUL; n >>= 57U;
  3818. n += (sp_uint64)a[35] << 2U; r[17] = n;
  3819. XMEMSET(&r[18], 0, sizeof(*r) * 18U);
  3820. }
  3821. /* Reduce the number back to 2048 bits using Montgomery reduction.
  3822. *
  3823. * a A single precision number to reduce in place.
  3824. * m The single precision number representing the modulus.
  3825. * mp The digit representing the negative inverse of m mod 2^n.
  3826. */
  3827. static void sp_2048_mont_reduce_18(sp_digit* a, const sp_digit* m, sp_digit mp)
  3828. {
  3829. int i;
  3830. sp_digit mu;
  3831. sp_digit over;
  3832. sp_2048_norm_18(a + 18);
  3833. for (i=0; i<17; i++) {
  3834. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1ffffffffffffffL;
  3835. sp_2048_mul_add_18(a+i, m, mu);
  3836. a[i+1] += a[i] >> 57;
  3837. }
  3838. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x7fffffffffffffL;
  3839. sp_2048_mul_add_18(a+i, m, mu);
  3840. a[i+1] += a[i] >> 57;
  3841. a[i] &= 0x1ffffffffffffffL;
  3842. sp_2048_mont_shift_18(a, a);
  3843. over = a[17] - m[17];
  3844. sp_2048_cond_sub_18(a, a, m, ~((over - 1) >> 63));
  3845. sp_2048_norm_18(a);
  3846. }
  3847. /* Multiply two Montgomery form numbers mod the modulus (prime).
  3848. * (r = a * b mod m)
  3849. *
  3850. * r Result of multiplication.
  3851. * a First number to multiply in Montgomery form.
  3852. * b Second number to multiply in Montgomery form.
  3853. * m Modulus (prime).
  3854. * mp Montgomery multiplier.
  3855. */
  3856. SP_NOINLINE static void sp_2048_mont_mul_18(sp_digit* r, const sp_digit* a,
  3857. const sp_digit* b, const sp_digit* m, sp_digit mp)
  3858. {
  3859. sp_2048_mul_18(r, a, b);
  3860. sp_2048_mont_reduce_18(r, m, mp);
  3861. }
  3862. /* Square the Montgomery form number. (r = a * a mod m)
  3863. *
  3864. * r Result of squaring.
  3865. * a Number to square in Montgomery form.
  3866. * m Modulus (prime).
  3867. * mp Montgomery multiplier.
  3868. */
  3869. SP_NOINLINE static void sp_2048_mont_sqr_18(sp_digit* r, const sp_digit* a,
  3870. const sp_digit* m, sp_digit mp)
  3871. {
  3872. sp_2048_sqr_18(r, a);
  3873. sp_2048_mont_reduce_18(r, m, mp);
  3874. }
  3875. /* Multiply a by scalar b into r. (r = a * b)
  3876. *
  3877. * r A single precision integer.
  3878. * a A single precision integer.
  3879. * b A scalar.
  3880. */
  3881. SP_NOINLINE static void sp_2048_mul_d_18(sp_digit* r, const sp_digit* a,
  3882. sp_digit b)
  3883. {
  3884. sp_int128 tb = b;
  3885. sp_int128 t = 0;
  3886. sp_digit t2;
  3887. sp_int128 p[4];
  3888. int i;
  3889. for (i = 0; i < 16; i += 4) {
  3890. p[0] = tb * a[i + 0];
  3891. p[1] = tb * a[i + 1];
  3892. p[2] = tb * a[i + 2];
  3893. p[3] = tb * a[i + 3];
  3894. t += p[0];
  3895. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  3896. t >>= 57;
  3897. r[i + 0] = (sp_digit)t2;
  3898. t += p[1];
  3899. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  3900. t >>= 57;
  3901. r[i + 1] = (sp_digit)t2;
  3902. t += p[2];
  3903. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  3904. t >>= 57;
  3905. r[i + 2] = (sp_digit)t2;
  3906. t += p[3];
  3907. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  3908. t >>= 57;
  3909. r[i + 3] = (sp_digit)t2;
  3910. }
  3911. t += tb * a[16];
  3912. r[16] = (sp_digit)(t & 0x1ffffffffffffffL);
  3913. t >>= 57;
  3914. t += tb * a[17];
  3915. r[17] = (sp_digit)(t & 0x1ffffffffffffffL);
  3916. t >>= 57;
  3917. r[18] = (sp_digit)(t & 0x1ffffffffffffffL);
  3918. }
  3919. #ifndef WOLFSSL_SP_SMALL
  3920. /* Conditionally add a and b using the mask m.
  3921. * m is -1 to add and 0 when not.
  3922. *
  3923. * r A single precision number representing conditional add result.
  3924. * a A single precision number to add with.
  3925. * b A single precision number to add.
  3926. * m Mask value to apply.
  3927. */
  3928. static void sp_2048_cond_add_18(sp_digit* r, const sp_digit* a,
  3929. const sp_digit* b, const sp_digit m)
  3930. {
  3931. int i;
  3932. for (i = 0; i < 16; i += 8) {
  3933. r[i + 0] = a[i + 0] + (b[i + 0] & m);
  3934. r[i + 1] = a[i + 1] + (b[i + 1] & m);
  3935. r[i + 2] = a[i + 2] + (b[i + 2] & m);
  3936. r[i + 3] = a[i + 3] + (b[i + 3] & m);
  3937. r[i + 4] = a[i + 4] + (b[i + 4] & m);
  3938. r[i + 5] = a[i + 5] + (b[i + 5] & m);
  3939. r[i + 6] = a[i + 6] + (b[i + 6] & m);
  3940. r[i + 7] = a[i + 7] + (b[i + 7] & m);
  3941. }
  3942. r[16] = a[16] + (b[16] & m);
  3943. r[17] = a[17] + (b[17] & m);
  3944. }
  3945. #endif /* !WOLFSSL_SP_SMALL */
  3946. SP_NOINLINE static void sp_2048_rshift_18(sp_digit* r, const sp_digit* a,
  3947. byte n)
  3948. {
  3949. int i;
  3950. for (i=0; i<16; i += 8) {
  3951. r[i+0] = (a[i+0] >> n) | ((a[i+1] << (57 - n)) & 0x1ffffffffffffffL);
  3952. r[i+1] = (a[i+1] >> n) | ((a[i+2] << (57 - n)) & 0x1ffffffffffffffL);
  3953. r[i+2] = (a[i+2] >> n) | ((a[i+3] << (57 - n)) & 0x1ffffffffffffffL);
  3954. r[i+3] = (a[i+3] >> n) | ((a[i+4] << (57 - n)) & 0x1ffffffffffffffL);
  3955. r[i+4] = (a[i+4] >> n) | ((a[i+5] << (57 - n)) & 0x1ffffffffffffffL);
  3956. r[i+5] = (a[i+5] >> n) | ((a[i+6] << (57 - n)) & 0x1ffffffffffffffL);
  3957. r[i+6] = (a[i+6] >> n) | ((a[i+7] << (57 - n)) & 0x1ffffffffffffffL);
  3958. r[i+7] = (a[i+7] >> n) | ((a[i+8] << (57 - n)) & 0x1ffffffffffffffL);
  3959. }
  3960. r[16] = (a[16] >> n) | ((a[17] << (57 - n)) & 0x1ffffffffffffffL);
  3961. r[17] = a[17] >> n;
  3962. }
  3963. static WC_INLINE sp_digit sp_2048_div_word_18(sp_digit d1, sp_digit d0,
  3964. sp_digit div)
  3965. {
  3966. #ifdef SP_USE_DIVTI3
  3967. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  3968. return d / div;
  3969. #elif defined(__x86_64__) || defined(__i386__)
  3970. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  3971. sp_uint64 lo = (sp_uint64)d;
  3972. sp_digit hi = (sp_digit)(d >> 64);
  3973. __asm__ __volatile__ (
  3974. "idiv %2"
  3975. : "+a" (lo)
  3976. : "d" (hi), "r" (div)
  3977. : "cc"
  3978. );
  3979. return (sp_digit)lo;
  3980. #elif !defined(__aarch64__) && !defined(SP_DIV_WORD_USE_DIV)
  3981. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  3982. sp_digit dv = (div >> 1) + 1;
  3983. sp_digit t1 = (sp_digit)(d >> 57);
  3984. sp_digit t0 = (sp_digit)(d & 0x1ffffffffffffffL);
  3985. sp_digit t2;
  3986. sp_digit sign;
  3987. sp_digit r;
  3988. int i;
  3989. sp_int128 m;
  3990. r = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  3991. t1 -= dv & (0 - r);
  3992. for (i = 55; i >= 1; i--) {
  3993. t1 += t1 + (((sp_uint64)t0 >> 56) & 1);
  3994. t0 <<= 1;
  3995. t2 = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  3996. r += r + t2;
  3997. t1 -= dv & (0 - t2);
  3998. t1 += t2;
  3999. }
  4000. r += r + 1;
  4001. m = d - ((sp_int128)r * div);
  4002. r += (sp_digit)(m >> 57);
  4003. m = d - ((sp_int128)r * div);
  4004. r += (sp_digit)(m >> 114) - (sp_digit)(d >> 114);
  4005. m = d - ((sp_int128)r * div);
  4006. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  4007. m *= sign;
  4008. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  4009. r += sign * t2;
  4010. m = d - ((sp_int128)r * div);
  4011. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  4012. m *= sign;
  4013. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  4014. r += sign * t2;
  4015. return r;
  4016. #else
  4017. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  4018. sp_digit r = 0;
  4019. sp_digit t;
  4020. sp_digit dv = (div >> 26) + 1;
  4021. t = (sp_digit)(d >> 52);
  4022. t = (t / dv) << 26;
  4023. r += t;
  4024. d -= (sp_int128)t * div;
  4025. t = (sp_digit)(d >> 21);
  4026. t = t / (dv << 5);
  4027. r += t;
  4028. d -= (sp_int128)t * div;
  4029. t = (sp_digit)d;
  4030. t = t / div;
  4031. r += t;
  4032. d -= (sp_int128)t * div;
  4033. return r;
  4034. #endif
  4035. }
  4036. static WC_INLINE sp_digit sp_2048_word_div_word_18(sp_digit d, sp_digit div)
  4037. {
  4038. #if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \
  4039. defined(SP_DIV_WORD_USE_DIV)
  4040. return d / div;
  4041. #else
  4042. return (sp_digit)((sp_uint64)(div - d) >> 63);
  4043. #endif
  4044. }
  4045. /* Divide d in a and put remainder into r (m*d + r = a)
  4046. * m is not calculated as it is not needed at this time.
  4047. *
  4048. * Full implementation.
  4049. *
  4050. * a Number to be divided.
  4051. * d Number to divide with.
  4052. * m Multiplier result.
  4053. * r Remainder from the division.
  4054. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  4055. */
  4056. static int sp_2048_div_18(const sp_digit* a, const sp_digit* d,
  4057. const sp_digit* m, sp_digit* r)
  4058. {
  4059. int i;
  4060. #ifndef WOLFSSL_SP_DIV_64
  4061. #endif
  4062. sp_digit dv;
  4063. sp_digit r1;
  4064. #ifdef WOLFSSL_SP_SMALL_STACK
  4065. sp_digit* t1 = NULL;
  4066. #else
  4067. sp_digit t1[4 * 18 + 3];
  4068. #endif
  4069. sp_digit* t2 = NULL;
  4070. sp_digit* sd = NULL;
  4071. int err = MP_OKAY;
  4072. (void)m;
  4073. #ifdef WOLFSSL_SP_SMALL_STACK
  4074. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 18 + 3), NULL,
  4075. DYNAMIC_TYPE_TMP_BUFFER);
  4076. if (t1 == NULL)
  4077. err = MEMORY_E;
  4078. #endif
  4079. (void)m;
  4080. if (err == MP_OKAY) {
  4081. t2 = t1 + 36 + 1;
  4082. sd = t2 + 18 + 1;
  4083. sp_2048_mul_d_18(sd, d, (sp_digit)1 << 2);
  4084. sp_2048_mul_d_36(t1, a, (sp_digit)1 << 2);
  4085. dv = sd[17];
  4086. t1[18 + 18] += t1[18 + 18 - 1] >> 57;
  4087. t1[18 + 18 - 1] &= 0x1ffffffffffffffL;
  4088. for (i=18; i>=0; i--) {
  4089. r1 = sp_2048_div_word_18(t1[18 + i], t1[18 + i - 1], dv);
  4090. sp_2048_mul_d_18(t2, sd, r1);
  4091. (void)sp_2048_sub_18(&t1[i], &t1[i], t2);
  4092. sp_2048_norm_18(&t1[i]);
  4093. t1[18 + i] -= t2[18];
  4094. t1[18 + i] += t1[18 + i - 1] >> 57;
  4095. t1[18 + i - 1] &= 0x1ffffffffffffffL;
  4096. r1 = sp_2048_div_word_18(-t1[18 + i], -t1[18 + i - 1], dv);
  4097. r1 -= t1[18 + i];
  4098. sp_2048_mul_d_18(t2, sd, r1);
  4099. (void)sp_2048_add_18(&t1[i], &t1[i], t2);
  4100. t1[18 + i] += t1[18 + i - 1] >> 57;
  4101. t1[18 + i - 1] &= 0x1ffffffffffffffL;
  4102. }
  4103. t1[18 - 1] += t1[18 - 2] >> 57;
  4104. t1[18 - 2] &= 0x1ffffffffffffffL;
  4105. r1 = sp_2048_word_div_word_18(t1[18 - 1], dv);
  4106. sp_2048_mul_d_18(t2, sd, r1);
  4107. sp_2048_sub_18(t1, t1, t2);
  4108. XMEMCPY(r, t1, sizeof(*r) * 36U);
  4109. for (i=0; i<17; i++) {
  4110. r[i+1] += r[i] >> 57;
  4111. r[i] &= 0x1ffffffffffffffL;
  4112. }
  4113. sp_2048_cond_add_18(r, r, sd, r[17] >> 63);
  4114. sp_2048_norm_18(r);
  4115. sp_2048_rshift_18(r, r, 2);
  4116. }
  4117. #ifdef WOLFSSL_SP_SMALL_STACK
  4118. if (t1 != NULL)
  4119. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  4120. #endif
  4121. return err;
  4122. }
  4123. /* Reduce a modulo m into r. (r = a mod m)
  4124. *
  4125. * r A single precision number that is the reduced result.
  4126. * a A single precision number that is to be reduced.
  4127. * m A single precision number that is the modulus to reduce with.
  4128. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  4129. */
  4130. static int sp_2048_mod_18(sp_digit* r, const sp_digit* a, const sp_digit* m)
  4131. {
  4132. return sp_2048_div_18(a, m, NULL, r);
  4133. }
  4134. /* Modular exponentiate a to the e mod m. (r = a^e mod m)
  4135. *
  4136. * r A single precision number that is the result of the operation.
  4137. * a A single precision number being exponentiated.
  4138. * e A single precision number that is the exponent.
  4139. * bits The number of bits in the exponent.
  4140. * m A single precision number that is the modulus.
  4141. * returns 0 on success.
  4142. * returns MEMORY_E on dynamic memory allocation failure.
  4143. * returns MP_VAL when base is even or exponent is 0.
  4144. */
  4145. static int sp_2048_mod_exp_18(sp_digit* r, const sp_digit* a, const sp_digit* e,
  4146. int bits, const sp_digit* m, int reduceA)
  4147. {
  4148. #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
  4149. #ifdef WOLFSSL_SP_SMALL_STACK
  4150. sp_digit* td = NULL;
  4151. #else
  4152. sp_digit td[3 * 36];
  4153. #endif
  4154. sp_digit* t[3] = {0, 0, 0};
  4155. sp_digit* norm = NULL;
  4156. sp_digit mp = 1;
  4157. sp_digit n;
  4158. int i;
  4159. int c;
  4160. byte y;
  4161. int err = MP_OKAY;
  4162. if (bits == 0) {
  4163. err = MP_VAL;
  4164. }
  4165. #ifdef WOLFSSL_SP_SMALL_STACK
  4166. if (err == MP_OKAY) {
  4167. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 18 * 2, NULL,
  4168. DYNAMIC_TYPE_TMP_BUFFER);
  4169. if (td == NULL)
  4170. err = MEMORY_E;
  4171. }
  4172. #endif
  4173. if (err == MP_OKAY) {
  4174. norm = td;
  4175. for (i=0; i<3; i++) {
  4176. t[i] = td + (i * 18 * 2);
  4177. XMEMSET(t[i], 0, sizeof(sp_digit) * 18U * 2U);
  4178. }
  4179. sp_2048_mont_setup(m, &mp);
  4180. sp_2048_mont_norm_18(norm, m);
  4181. if (reduceA != 0) {
  4182. err = sp_2048_mod_18(t[1], a, m);
  4183. }
  4184. else {
  4185. XMEMCPY(t[1], a, sizeof(sp_digit) * 18U);
  4186. }
  4187. }
  4188. if (err == MP_OKAY) {
  4189. sp_2048_mul_18(t[1], t[1], norm);
  4190. err = sp_2048_mod_18(t[1], t[1], m);
  4191. }
  4192. if (err == MP_OKAY) {
  4193. i = bits / 57;
  4194. c = bits % 57;
  4195. n = e[i--] << (57 - c);
  4196. for (; ; c--) {
  4197. if (c == 0) {
  4198. if (i == -1) {
  4199. break;
  4200. }
  4201. n = e[i--];
  4202. c = 57;
  4203. }
  4204. y = (int)((n >> 56) & 1);
  4205. n <<= 1;
  4206. sp_2048_mont_mul_18(t[y^1], t[0], t[1], m, mp);
  4207. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  4208. ((size_t)t[1] & addr_mask[y])),
  4209. sizeof(*t[2]) * 18 * 2);
  4210. sp_2048_mont_sqr_18(t[2], t[2], m, mp);
  4211. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  4212. ((size_t)t[1] & addr_mask[y])), t[2],
  4213. sizeof(*t[2]) * 18 * 2);
  4214. }
  4215. sp_2048_mont_reduce_18(t[0], m, mp);
  4216. n = sp_2048_cmp_18(t[0], m);
  4217. sp_2048_cond_sub_18(t[0], t[0], m, ~(n >> 63));
  4218. XMEMCPY(r, t[0], sizeof(*r) * 18 * 2);
  4219. }
  4220. #ifdef WOLFSSL_SP_SMALL_STACK
  4221. if (td != NULL)
  4222. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  4223. #endif
  4224. return err;
  4225. #elif !defined(WC_NO_CACHE_RESISTANT)
  4226. #ifdef WOLFSSL_SP_SMALL_STACK
  4227. sp_digit* td = NULL;
  4228. #else
  4229. sp_digit td[3 * 36];
  4230. #endif
  4231. sp_digit* t[3] = {0, 0, 0};
  4232. sp_digit* norm = NULL;
  4233. sp_digit mp = 1;
  4234. sp_digit n;
  4235. int i;
  4236. int c;
  4237. byte y;
  4238. int err = MP_OKAY;
  4239. if (bits == 0) {
  4240. err = MP_VAL;
  4241. }
  4242. #ifdef WOLFSSL_SP_SMALL_STACK
  4243. if (err == MP_OKAY) {
  4244. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 18 * 2, NULL,
  4245. DYNAMIC_TYPE_TMP_BUFFER);
  4246. if (td == NULL)
  4247. err = MEMORY_E;
  4248. }
  4249. #endif
  4250. if (err == MP_OKAY) {
  4251. norm = td;
  4252. for (i=0; i<3; i++) {
  4253. t[i] = td + (i * 18 * 2);
  4254. }
  4255. sp_2048_mont_setup(m, &mp);
  4256. sp_2048_mont_norm_18(norm, m);
  4257. if (reduceA != 0) {
  4258. err = sp_2048_mod_18(t[1], a, m);
  4259. if (err == MP_OKAY) {
  4260. sp_2048_mul_18(t[1], t[1], norm);
  4261. err = sp_2048_mod_18(t[1], t[1], m);
  4262. }
  4263. }
  4264. else {
  4265. sp_2048_mul_18(t[1], a, norm);
  4266. err = sp_2048_mod_18(t[1], t[1], m);
  4267. }
  4268. }
  4269. if (err == MP_OKAY) {
  4270. i = bits / 57;
  4271. c = bits % 57;
  4272. n = e[i--] << (57 - c);
  4273. for (; ; c--) {
  4274. if (c == 0) {
  4275. if (i == -1) {
  4276. break;
  4277. }
  4278. n = e[i--];
  4279. c = 57;
  4280. }
  4281. y = (int)((n >> 56) & 1);
  4282. n <<= 1;
  4283. sp_2048_mont_mul_18(t[y^1], t[0], t[1], m, mp);
  4284. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  4285. ((size_t)t[1] & addr_mask[y])),
  4286. sizeof(*t[2]) * 18 * 2);
  4287. sp_2048_mont_sqr_18(t[2], t[2], m, mp);
  4288. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  4289. ((size_t)t[1] & addr_mask[y])), t[2],
  4290. sizeof(*t[2]) * 18 * 2);
  4291. }
  4292. sp_2048_mont_reduce_18(t[0], m, mp);
  4293. n = sp_2048_cmp_18(t[0], m);
  4294. sp_2048_cond_sub_18(t[0], t[0], m, ~(n >> 63));
  4295. XMEMCPY(r, t[0], sizeof(*r) * 18 * 2);
  4296. }
  4297. #ifdef WOLFSSL_SP_SMALL_STACK
  4298. if (td != NULL)
  4299. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  4300. #endif
  4301. return err;
  4302. #else
  4303. #ifdef WOLFSSL_SP_SMALL_STACK
  4304. sp_digit* td = NULL;
  4305. #else
  4306. sp_digit td[(32 * 36) + 36];
  4307. #endif
  4308. sp_digit* t[32];
  4309. sp_digit* rt = NULL;
  4310. sp_digit* norm = NULL;
  4311. sp_digit mp = 1;
  4312. sp_digit n;
  4313. int i;
  4314. int c;
  4315. byte y;
  4316. int err = MP_OKAY;
  4317. if (bits == 0) {
  4318. err = MP_VAL;
  4319. }
  4320. #ifdef WOLFSSL_SP_SMALL_STACK
  4321. if (err == MP_OKAY) {
  4322. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((32 * 36) + 36), NULL,
  4323. DYNAMIC_TYPE_TMP_BUFFER);
  4324. if (td == NULL)
  4325. err = MEMORY_E;
  4326. }
  4327. #endif
  4328. if (err == MP_OKAY) {
  4329. norm = td;
  4330. for (i=0; i<32; i++)
  4331. t[i] = td + i * 36;
  4332. rt = td + 1152;
  4333. sp_2048_mont_setup(m, &mp);
  4334. sp_2048_mont_norm_18(norm, m);
  4335. if (reduceA != 0) {
  4336. err = sp_2048_mod_18(t[1], a, m);
  4337. if (err == MP_OKAY) {
  4338. sp_2048_mul_18(t[1], t[1], norm);
  4339. err = sp_2048_mod_18(t[1], t[1], m);
  4340. }
  4341. }
  4342. else {
  4343. sp_2048_mul_18(t[1], a, norm);
  4344. err = sp_2048_mod_18(t[1], t[1], m);
  4345. }
  4346. }
  4347. if (err == MP_OKAY) {
  4348. sp_2048_mont_sqr_18(t[ 2], t[ 1], m, mp);
  4349. sp_2048_mont_mul_18(t[ 3], t[ 2], t[ 1], m, mp);
  4350. sp_2048_mont_sqr_18(t[ 4], t[ 2], m, mp);
  4351. sp_2048_mont_mul_18(t[ 5], t[ 3], t[ 2], m, mp);
  4352. sp_2048_mont_sqr_18(t[ 6], t[ 3], m, mp);
  4353. sp_2048_mont_mul_18(t[ 7], t[ 4], t[ 3], m, mp);
  4354. sp_2048_mont_sqr_18(t[ 8], t[ 4], m, mp);
  4355. sp_2048_mont_mul_18(t[ 9], t[ 5], t[ 4], m, mp);
  4356. sp_2048_mont_sqr_18(t[10], t[ 5], m, mp);
  4357. sp_2048_mont_mul_18(t[11], t[ 6], t[ 5], m, mp);
  4358. sp_2048_mont_sqr_18(t[12], t[ 6], m, mp);
  4359. sp_2048_mont_mul_18(t[13], t[ 7], t[ 6], m, mp);
  4360. sp_2048_mont_sqr_18(t[14], t[ 7], m, mp);
  4361. sp_2048_mont_mul_18(t[15], t[ 8], t[ 7], m, mp);
  4362. sp_2048_mont_sqr_18(t[16], t[ 8], m, mp);
  4363. sp_2048_mont_mul_18(t[17], t[ 9], t[ 8], m, mp);
  4364. sp_2048_mont_sqr_18(t[18], t[ 9], m, mp);
  4365. sp_2048_mont_mul_18(t[19], t[10], t[ 9], m, mp);
  4366. sp_2048_mont_sqr_18(t[20], t[10], m, mp);
  4367. sp_2048_mont_mul_18(t[21], t[11], t[10], m, mp);
  4368. sp_2048_mont_sqr_18(t[22], t[11], m, mp);
  4369. sp_2048_mont_mul_18(t[23], t[12], t[11], m, mp);
  4370. sp_2048_mont_sqr_18(t[24], t[12], m, mp);
  4371. sp_2048_mont_mul_18(t[25], t[13], t[12], m, mp);
  4372. sp_2048_mont_sqr_18(t[26], t[13], m, mp);
  4373. sp_2048_mont_mul_18(t[27], t[14], t[13], m, mp);
  4374. sp_2048_mont_sqr_18(t[28], t[14], m, mp);
  4375. sp_2048_mont_mul_18(t[29], t[15], t[14], m, mp);
  4376. sp_2048_mont_sqr_18(t[30], t[15], m, mp);
  4377. sp_2048_mont_mul_18(t[31], t[16], t[15], m, mp);
  4378. bits = ((bits + 4) / 5) * 5;
  4379. i = ((bits + 56) / 57) - 1;
  4380. c = bits % 57;
  4381. if (c == 0) {
  4382. c = 57;
  4383. }
  4384. if (i < 18) {
  4385. n = e[i--] << (64 - c);
  4386. }
  4387. else {
  4388. n = 0;
  4389. i--;
  4390. }
  4391. if (c < 5) {
  4392. n |= e[i--] << (7 - c);
  4393. c += 57;
  4394. }
  4395. y = (int)((n >> 59) & 0x1f);
  4396. n <<= 5;
  4397. c -= 5;
  4398. XMEMCPY(rt, t[y], sizeof(sp_digit) * 36);
  4399. while ((i >= 0) || (c >= 5)) {
  4400. if (c >= 5) {
  4401. y = (byte)((n >> 59) & 0x1f);
  4402. n <<= 5;
  4403. c -= 5;
  4404. }
  4405. else if (c == 0) {
  4406. n = e[i--] << 7;
  4407. y = (byte)((n >> 59) & 0x1f);
  4408. n <<= 5;
  4409. c = 52;
  4410. }
  4411. else {
  4412. y = (byte)((n >> 59) & 0x1f);
  4413. n = e[i--] << 7;
  4414. c = 5 - c;
  4415. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  4416. n <<= c;
  4417. c = 57 - c;
  4418. }
  4419. sp_2048_mont_sqr_18(rt, rt, m, mp);
  4420. sp_2048_mont_sqr_18(rt, rt, m, mp);
  4421. sp_2048_mont_sqr_18(rt, rt, m, mp);
  4422. sp_2048_mont_sqr_18(rt, rt, m, mp);
  4423. sp_2048_mont_sqr_18(rt, rt, m, mp);
  4424. sp_2048_mont_mul_18(rt, rt, t[y], m, mp);
  4425. }
  4426. sp_2048_mont_reduce_18(rt, m, mp);
  4427. n = sp_2048_cmp_18(rt, m);
  4428. sp_2048_cond_sub_18(rt, rt, m, ~(n >> 63));
  4429. XMEMCPY(r, rt, sizeof(sp_digit) * 36);
  4430. }
  4431. #ifdef WOLFSSL_SP_SMALL_STACK
  4432. if (td != NULL)
  4433. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  4434. #endif
  4435. return err;
  4436. #endif
  4437. }
  4438. #endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */
  4439. /* r = 2^n mod m where n is the number of bits to reduce by.
  4440. * Given m must be 2048 bits, just need to subtract.
  4441. *
  4442. * r A single precision number.
  4443. * m A single precision number.
  4444. */
  4445. static void sp_2048_mont_norm_36(sp_digit* r, const sp_digit* m)
  4446. {
  4447. /* Set r = 2^n - 1. */
  4448. int i;
  4449. for (i = 0; i < 32; i += 8) {
  4450. r[i + 0] = 0x1ffffffffffffffL;
  4451. r[i + 1] = 0x1ffffffffffffffL;
  4452. r[i + 2] = 0x1ffffffffffffffL;
  4453. r[i + 3] = 0x1ffffffffffffffL;
  4454. r[i + 4] = 0x1ffffffffffffffL;
  4455. r[i + 5] = 0x1ffffffffffffffL;
  4456. r[i + 6] = 0x1ffffffffffffffL;
  4457. r[i + 7] = 0x1ffffffffffffffL;
  4458. }
  4459. r[32] = 0x1ffffffffffffffL;
  4460. r[33] = 0x1ffffffffffffffL;
  4461. r[34] = 0x1ffffffffffffffL;
  4462. r[35] = 0x1fffffffffffffL;
  4463. /* r = (2^n - 1) mod n */
  4464. (void)sp_2048_sub_36(r, r, m);
  4465. /* Add one so r = 2^n mod m */
  4466. r[0] += 1;
  4467. }
  4468. /* Compare a with b in constant time.
  4469. *
  4470. * a A single precision integer.
  4471. * b A single precision integer.
  4472. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  4473. * respectively.
  4474. */
  4475. static sp_digit sp_2048_cmp_36(const sp_digit* a, const sp_digit* b)
  4476. {
  4477. sp_digit r = 0;
  4478. int i;
  4479. r |= (a[35] - b[35]) & (0 - (sp_digit)1);
  4480. r |= (a[34] - b[34]) & ~(((sp_digit)0 - r) >> 56);
  4481. r |= (a[33] - b[33]) & ~(((sp_digit)0 - r) >> 56);
  4482. r |= (a[32] - b[32]) & ~(((sp_digit)0 - r) >> 56);
  4483. for (i = 24; i >= 0; i -= 8) {
  4484. r |= (a[i + 7] - b[i + 7]) & ~(((sp_digit)0 - r) >> 56);
  4485. r |= (a[i + 6] - b[i + 6]) & ~(((sp_digit)0 - r) >> 56);
  4486. r |= (a[i + 5] - b[i + 5]) & ~(((sp_digit)0 - r) >> 56);
  4487. r |= (a[i + 4] - b[i + 4]) & ~(((sp_digit)0 - r) >> 56);
  4488. r |= (a[i + 3] - b[i + 3]) & ~(((sp_digit)0 - r) >> 56);
  4489. r |= (a[i + 2] - b[i + 2]) & ~(((sp_digit)0 - r) >> 56);
  4490. r |= (a[i + 1] - b[i + 1]) & ~(((sp_digit)0 - r) >> 56);
  4491. r |= (a[i + 0] - b[i + 0]) & ~(((sp_digit)0 - r) >> 56);
  4492. }
  4493. return r;
  4494. }
  4495. /* Conditionally subtract b from a using the mask m.
  4496. * m is -1 to subtract and 0 when not.
  4497. *
  4498. * r A single precision number representing condition subtract result.
  4499. * a A single precision number to subtract from.
  4500. * b A single precision number to subtract.
  4501. * m Mask value to apply.
  4502. */
  4503. static void sp_2048_cond_sub_36(sp_digit* r, const sp_digit* a,
  4504. const sp_digit* b, const sp_digit m)
  4505. {
  4506. int i;
  4507. for (i = 0; i < 32; i += 8) {
  4508. r[i + 0] = a[i + 0] - (b[i + 0] & m);
  4509. r[i + 1] = a[i + 1] - (b[i + 1] & m);
  4510. r[i + 2] = a[i + 2] - (b[i + 2] & m);
  4511. r[i + 3] = a[i + 3] - (b[i + 3] & m);
  4512. r[i + 4] = a[i + 4] - (b[i + 4] & m);
  4513. r[i + 5] = a[i + 5] - (b[i + 5] & m);
  4514. r[i + 6] = a[i + 6] - (b[i + 6] & m);
  4515. r[i + 7] = a[i + 7] - (b[i + 7] & m);
  4516. }
  4517. r[32] = a[32] - (b[32] & m);
  4518. r[33] = a[33] - (b[33] & m);
  4519. r[34] = a[34] - (b[34] & m);
  4520. r[35] = a[35] - (b[35] & m);
  4521. }
  4522. /* Mul a by scalar b and add into r. (r += a * b)
  4523. *
  4524. * r A single precision integer.
  4525. * a A single precision integer.
  4526. * b A scalar.
  4527. */
  4528. SP_NOINLINE static void sp_2048_mul_add_36(sp_digit* r, const sp_digit* a,
  4529. const sp_digit b)
  4530. {
  4531. sp_int128 tb = b;
  4532. sp_int128 t[8];
  4533. int i;
  4534. t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL);
  4535. for (i = 0; i < 32; i += 8) {
  4536. t[1] = tb * a[i+1];
  4537. r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
  4538. t[2] = tb * a[i+2];
  4539. r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
  4540. t[3] = tb * a[i+3];
  4541. r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));
  4542. t[4] = tb * a[i+4];
  4543. r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));
  4544. t[5] = tb * a[i+5];
  4545. r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));
  4546. t[6] = tb * a[i+6];
  4547. r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL));
  4548. t[7] = tb * a[i+7];
  4549. r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL));
  4550. t[0] = tb * a[i+8];
  4551. r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL));
  4552. }
  4553. t[1] = tb * a[33];
  4554. r[33] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
  4555. t[2] = tb * a[34];
  4556. r[34] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
  4557. t[3] = tb * a[35];
  4558. r[35] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));
  4559. r[36] += (sp_digit)(t[3] >> 57);
  4560. }
  4561. /* Shift the result in the high 2048 bits down to the bottom.
  4562. *
  4563. * r A single precision number.
  4564. * a A single precision number.
  4565. */
  4566. static void sp_2048_mont_shift_36(sp_digit* r, const sp_digit* a)
  4567. {
  4568. sp_digit n;
  4569. sp_digit s;
  4570. int i;
  4571. s = a[36]; n = a[35] >> 53;
  4572. for (i = 0; i < 32; i += 8) {
  4573. n += (s & 0x1ffffffffffffffL) << 4; r[i+0] = n & 0x1ffffffffffffffL;
  4574. n >>= 57; s = a[i+37] + (s >> 57);
  4575. n += (s & 0x1ffffffffffffffL) << 4; r[i+1] = n & 0x1ffffffffffffffL;
  4576. n >>= 57; s = a[i+38] + (s >> 57);
  4577. n += (s & 0x1ffffffffffffffL) << 4; r[i+2] = n & 0x1ffffffffffffffL;
  4578. n >>= 57; s = a[i+39] + (s >> 57);
  4579. n += (s & 0x1ffffffffffffffL) << 4; r[i+3] = n & 0x1ffffffffffffffL;
  4580. n >>= 57; s = a[i+40] + (s >> 57);
  4581. n += (s & 0x1ffffffffffffffL) << 4; r[i+4] = n & 0x1ffffffffffffffL;
  4582. n >>= 57; s = a[i+41] + (s >> 57);
  4583. n += (s & 0x1ffffffffffffffL) << 4; r[i+5] = n & 0x1ffffffffffffffL;
  4584. n >>= 57; s = a[i+42] + (s >> 57);
  4585. n += (s & 0x1ffffffffffffffL) << 4; r[i+6] = n & 0x1ffffffffffffffL;
  4586. n >>= 57; s = a[i+43] + (s >> 57);
  4587. n += (s & 0x1ffffffffffffffL) << 4; r[i+7] = n & 0x1ffffffffffffffL;
  4588. n >>= 57; s = a[i+44] + (s >> 57);
  4589. }
  4590. n += (s & 0x1ffffffffffffffL) << 4; r[32] = n & 0x1ffffffffffffffL;
  4591. n >>= 57; s = a[69] + (s >> 57);
  4592. n += (s & 0x1ffffffffffffffL) << 4; r[33] = n & 0x1ffffffffffffffL;
  4593. n >>= 57; s = a[70] + (s >> 57);
  4594. n += (s & 0x1ffffffffffffffL) << 4; r[34] = n & 0x1ffffffffffffffL;
  4595. n >>= 57; s = a[71] + (s >> 57);
  4596. n += s << 4; r[35] = n;
  4597. XMEMSET(&r[36], 0, sizeof(*r) * 36U);
  4598. }
  4599. /* Reduce the number back to 2048 bits using Montgomery reduction.
  4600. *
  4601. * a A single precision number to reduce in place.
  4602. * m The single precision number representing the modulus.
  4603. * mp The digit representing the negative inverse of m mod 2^n.
  4604. */
  4605. static void sp_2048_mont_reduce_36(sp_digit* a, const sp_digit* m, sp_digit mp)
  4606. {
  4607. int i;
  4608. sp_digit mu;
  4609. sp_digit over;
  4610. sp_2048_norm_36(a + 36);
  4611. #ifdef WOLFSSL_SP_DH
  4612. if (mp != 1) {
  4613. for (i=0; i<35; i++) {
  4614. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1ffffffffffffffL;
  4615. sp_2048_mul_add_36(a+i, m, mu);
  4616. a[i+1] += a[i] >> 57;
  4617. }
  4618. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1fffffffffffffL;
  4619. sp_2048_mul_add_36(a+i, m, mu);
  4620. a[i+1] += a[i] >> 57;
  4621. a[i] &= 0x1ffffffffffffffL;
  4622. }
  4623. else {
  4624. for (i=0; i<35; i++) {
  4625. mu = a[i] & 0x1ffffffffffffffL;
  4626. sp_2048_mul_add_36(a+i, m, mu);
  4627. a[i+1] += a[i] >> 57;
  4628. }
  4629. mu = a[i] & 0x1fffffffffffffL;
  4630. sp_2048_mul_add_36(a+i, m, mu);
  4631. a[i+1] += a[i] >> 57;
  4632. a[i] &= 0x1ffffffffffffffL;
  4633. }
  4634. #else
  4635. for (i=0; i<35; i++) {
  4636. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1ffffffffffffffL;
  4637. sp_2048_mul_add_36(a+i, m, mu);
  4638. a[i+1] += a[i] >> 57;
  4639. }
  4640. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1fffffffffffffL;
  4641. sp_2048_mul_add_36(a+i, m, mu);
  4642. a[i+1] += a[i] >> 57;
  4643. a[i] &= 0x1ffffffffffffffL;
  4644. #endif
  4645. sp_2048_mont_shift_36(a, a);
  4646. over = a[35] - m[35];
  4647. sp_2048_cond_sub_36(a, a, m, ~((over - 1) >> 63));
  4648. sp_2048_norm_36(a);
  4649. }
  4650. /* Multiply two Montgomery form numbers mod the modulus (prime).
  4651. * (r = a * b mod m)
  4652. *
  4653. * r Result of multiplication.
  4654. * a First number to multiply in Montgomery form.
  4655. * b Second number to multiply in Montgomery form.
  4656. * m Modulus (prime).
  4657. * mp Montgomery multiplier.
  4658. */
  4659. SP_NOINLINE static void sp_2048_mont_mul_36(sp_digit* r, const sp_digit* a,
  4660. const sp_digit* b, const sp_digit* m, sp_digit mp)
  4661. {
  4662. sp_2048_mul_36(r, a, b);
  4663. sp_2048_mont_reduce_36(r, m, mp);
  4664. }
  4665. /* Square the Montgomery form number. (r = a * a mod m)
  4666. *
  4667. * r Result of squaring.
  4668. * a Number to square in Montgomery form.
  4669. * m Modulus (prime).
  4670. * mp Montgomery multiplier.
  4671. */
  4672. SP_NOINLINE static void sp_2048_mont_sqr_36(sp_digit* r, const sp_digit* a,
  4673. const sp_digit* m, sp_digit mp)
  4674. {
  4675. sp_2048_sqr_36(r, a);
  4676. sp_2048_mont_reduce_36(r, m, mp);
  4677. }
  4678. /* Multiply a by scalar b into r. (r = a * b)
  4679. *
  4680. * r A single precision integer.
  4681. * a A single precision integer.
  4682. * b A scalar.
  4683. */
  4684. SP_NOINLINE static void sp_2048_mul_d_72(sp_digit* r, const sp_digit* a,
  4685. sp_digit b)
  4686. {
  4687. sp_int128 tb = b;
  4688. sp_int128 t = 0;
  4689. sp_digit t2;
  4690. sp_int128 p[4];
  4691. int i;
  4692. for (i = 0; i < 72; i += 4) {
  4693. p[0] = tb * a[i + 0];
  4694. p[1] = tb * a[i + 1];
  4695. p[2] = tb * a[i + 2];
  4696. p[3] = tb * a[i + 3];
  4697. t += p[0];
  4698. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  4699. t >>= 57;
  4700. r[i + 0] = (sp_digit)t2;
  4701. t += p[1];
  4702. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  4703. t >>= 57;
  4704. r[i + 1] = (sp_digit)t2;
  4705. t += p[2];
  4706. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  4707. t >>= 57;
  4708. r[i + 2] = (sp_digit)t2;
  4709. t += p[3];
  4710. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  4711. t >>= 57;
  4712. r[i + 3] = (sp_digit)t2;
  4713. }
  4714. r[72] = (sp_digit)(t & 0x1ffffffffffffffL);
  4715. }
  4716. #ifndef WOLFSSL_SP_SMALL
  4717. /* Conditionally add a and b using the mask m.
  4718. * m is -1 to add and 0 when not.
  4719. *
  4720. * r A single precision number representing conditional add result.
  4721. * a A single precision number to add with.
  4722. * b A single precision number to add.
  4723. * m Mask value to apply.
  4724. */
  4725. static void sp_2048_cond_add_36(sp_digit* r, const sp_digit* a,
  4726. const sp_digit* b, const sp_digit m)
  4727. {
  4728. int i;
  4729. for (i = 0; i < 32; i += 8) {
  4730. r[i + 0] = a[i + 0] + (b[i + 0] & m);
  4731. r[i + 1] = a[i + 1] + (b[i + 1] & m);
  4732. r[i + 2] = a[i + 2] + (b[i + 2] & m);
  4733. r[i + 3] = a[i + 3] + (b[i + 3] & m);
  4734. r[i + 4] = a[i + 4] + (b[i + 4] & m);
  4735. r[i + 5] = a[i + 5] + (b[i + 5] & m);
  4736. r[i + 6] = a[i + 6] + (b[i + 6] & m);
  4737. r[i + 7] = a[i + 7] + (b[i + 7] & m);
  4738. }
  4739. r[32] = a[32] + (b[32] & m);
  4740. r[33] = a[33] + (b[33] & m);
  4741. r[34] = a[34] + (b[34] & m);
  4742. r[35] = a[35] + (b[35] & m);
  4743. }
  4744. #endif /* !WOLFSSL_SP_SMALL */
  4745. SP_NOINLINE static void sp_2048_rshift_36(sp_digit* r, const sp_digit* a,
  4746. byte n)
  4747. {
  4748. int i;
  4749. for (i=0; i<32; i += 8) {
  4750. r[i+0] = (a[i+0] >> n) | ((a[i+1] << (57 - n)) & 0x1ffffffffffffffL);
  4751. r[i+1] = (a[i+1] >> n) | ((a[i+2] << (57 - n)) & 0x1ffffffffffffffL);
  4752. r[i+2] = (a[i+2] >> n) | ((a[i+3] << (57 - n)) & 0x1ffffffffffffffL);
  4753. r[i+3] = (a[i+3] >> n) | ((a[i+4] << (57 - n)) & 0x1ffffffffffffffL);
  4754. r[i+4] = (a[i+4] >> n) | ((a[i+5] << (57 - n)) & 0x1ffffffffffffffL);
  4755. r[i+5] = (a[i+5] >> n) | ((a[i+6] << (57 - n)) & 0x1ffffffffffffffL);
  4756. r[i+6] = (a[i+6] >> n) | ((a[i+7] << (57 - n)) & 0x1ffffffffffffffL);
  4757. r[i+7] = (a[i+7] >> n) | ((a[i+8] << (57 - n)) & 0x1ffffffffffffffL);
  4758. }
  4759. r[32] = (a[32] >> n) | ((a[33] << (57 - n)) & 0x1ffffffffffffffL);
  4760. r[33] = (a[33] >> n) | ((a[34] << (57 - n)) & 0x1ffffffffffffffL);
  4761. r[34] = (a[34] >> n) | ((a[35] << (57 - n)) & 0x1ffffffffffffffL);
  4762. r[35] = a[35] >> n;
  4763. }
  4764. static WC_INLINE sp_digit sp_2048_div_word_36(sp_digit d1, sp_digit d0,
  4765. sp_digit div)
  4766. {
  4767. #ifdef SP_USE_DIVTI3
  4768. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  4769. return d / div;
  4770. #elif defined(__x86_64__) || defined(__i386__)
  4771. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  4772. sp_uint64 lo = (sp_uint64)d;
  4773. sp_digit hi = (sp_digit)(d >> 64);
  4774. __asm__ __volatile__ (
  4775. "idiv %2"
  4776. : "+a" (lo)
  4777. : "d" (hi), "r" (div)
  4778. : "cc"
  4779. );
  4780. return (sp_digit)lo;
  4781. #elif !defined(__aarch64__) && !defined(SP_DIV_WORD_USE_DIV)
  4782. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  4783. sp_digit dv = (div >> 1) + 1;
  4784. sp_digit t1 = (sp_digit)(d >> 57);
  4785. sp_digit t0 = (sp_digit)(d & 0x1ffffffffffffffL);
  4786. sp_digit t2;
  4787. sp_digit sign;
  4788. sp_digit r;
  4789. int i;
  4790. sp_int128 m;
  4791. r = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  4792. t1 -= dv & (0 - r);
  4793. for (i = 55; i >= 1; i--) {
  4794. t1 += t1 + (((sp_uint64)t0 >> 56) & 1);
  4795. t0 <<= 1;
  4796. t2 = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  4797. r += r + t2;
  4798. t1 -= dv & (0 - t2);
  4799. t1 += t2;
  4800. }
  4801. r += r + 1;
  4802. m = d - ((sp_int128)r * div);
  4803. r += (sp_digit)(m >> 57);
  4804. m = d - ((sp_int128)r * div);
  4805. r += (sp_digit)(m >> 114) - (sp_digit)(d >> 114);
  4806. m = d - ((sp_int128)r * div);
  4807. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  4808. m *= sign;
  4809. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  4810. r += sign * t2;
  4811. m = d - ((sp_int128)r * div);
  4812. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  4813. m *= sign;
  4814. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  4815. r += sign * t2;
  4816. return r;
  4817. #else
  4818. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  4819. sp_digit r = 0;
  4820. sp_digit t;
  4821. sp_digit dv = (div >> 26) + 1;
  4822. t = (sp_digit)(d >> 52);
  4823. t = (t / dv) << 26;
  4824. r += t;
  4825. d -= (sp_int128)t * div;
  4826. t = (sp_digit)(d >> 21);
  4827. t = t / (dv << 5);
  4828. r += t;
  4829. d -= (sp_int128)t * div;
  4830. t = (sp_digit)d;
  4831. t = t / div;
  4832. r += t;
  4833. d -= (sp_int128)t * div;
  4834. return r;
  4835. #endif
  4836. }
  4837. static WC_INLINE sp_digit sp_2048_word_div_word_36(sp_digit d, sp_digit div)
  4838. {
  4839. #if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \
  4840. defined(SP_DIV_WORD_USE_DIV)
  4841. return d / div;
  4842. #else
  4843. return (sp_digit)((sp_uint64)(div - d) >> 63);
  4844. #endif
  4845. }
  4846. /* Divide d in a and put remainder into r (m*d + r = a)
  4847. * m is not calculated as it is not needed at this time.
  4848. *
  4849. * Full implementation.
  4850. *
  4851. * a Number to be divided.
  4852. * d Number to divide with.
  4853. * m Multiplier result.
  4854. * r Remainder from the division.
  4855. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  4856. */
  4857. static int sp_2048_div_36(const sp_digit* a, const sp_digit* d,
  4858. const sp_digit* m, sp_digit* r)
  4859. {
  4860. int i;
  4861. #ifndef WOLFSSL_SP_DIV_64
  4862. #endif
  4863. sp_digit dv;
  4864. sp_digit r1;
  4865. #ifdef WOLFSSL_SP_SMALL_STACK
  4866. sp_digit* t1 = NULL;
  4867. #else
  4868. sp_digit t1[4 * 36 + 3];
  4869. #endif
  4870. sp_digit* t2 = NULL;
  4871. sp_digit* sd = NULL;
  4872. int err = MP_OKAY;
  4873. (void)m;
  4874. #ifdef WOLFSSL_SP_SMALL_STACK
  4875. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 36 + 3), NULL,
  4876. DYNAMIC_TYPE_TMP_BUFFER);
  4877. if (t1 == NULL)
  4878. err = MEMORY_E;
  4879. #endif
  4880. (void)m;
  4881. if (err == MP_OKAY) {
  4882. t2 = t1 + 72 + 1;
  4883. sd = t2 + 36 + 1;
  4884. sp_2048_mul_d_36(sd, d, (sp_digit)1 << 4);
  4885. sp_2048_mul_d_72(t1, a, (sp_digit)1 << 4);
  4886. dv = sd[35];
  4887. t1[36 + 36] += t1[36 + 36 - 1] >> 57;
  4888. t1[36 + 36 - 1] &= 0x1ffffffffffffffL;
  4889. for (i=36; i>=0; i--) {
  4890. r1 = sp_2048_div_word_36(t1[36 + i], t1[36 + i - 1], dv);
  4891. sp_2048_mul_d_36(t2, sd, r1);
  4892. (void)sp_2048_sub_36(&t1[i], &t1[i], t2);
  4893. sp_2048_norm_36(&t1[i]);
  4894. t1[36 + i] -= t2[36];
  4895. t1[36 + i] += t1[36 + i - 1] >> 57;
  4896. t1[36 + i - 1] &= 0x1ffffffffffffffL;
  4897. r1 = sp_2048_div_word_36(-t1[36 + i], -t1[36 + i - 1], dv);
  4898. r1 -= t1[36 + i];
  4899. sp_2048_mul_d_36(t2, sd, r1);
  4900. (void)sp_2048_add_36(&t1[i], &t1[i], t2);
  4901. t1[36 + i] += t1[36 + i - 1] >> 57;
  4902. t1[36 + i - 1] &= 0x1ffffffffffffffL;
  4903. }
  4904. t1[36 - 1] += t1[36 - 2] >> 57;
  4905. t1[36 - 2] &= 0x1ffffffffffffffL;
  4906. r1 = sp_2048_word_div_word_36(t1[36 - 1], dv);
  4907. sp_2048_mul_d_36(t2, sd, r1);
  4908. sp_2048_sub_36(t1, t1, t2);
  4909. XMEMCPY(r, t1, sizeof(*r) * 72U);
  4910. for (i=0; i<35; i++) {
  4911. r[i+1] += r[i] >> 57;
  4912. r[i] &= 0x1ffffffffffffffL;
  4913. }
  4914. sp_2048_cond_add_36(r, r, sd, r[35] >> 63);
  4915. sp_2048_norm_36(r);
  4916. sp_2048_rshift_36(r, r, 4);
  4917. }
  4918. #ifdef WOLFSSL_SP_SMALL_STACK
  4919. if (t1 != NULL)
  4920. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  4921. #endif
  4922. return err;
  4923. }
  4924. /* Reduce a modulo m into r. (r = a mod m)
  4925. *
  4926. * r A single precision number that is the reduced result.
  4927. * a A single precision number that is to be reduced.
  4928. * m A single precision number that is the modulus to reduce with.
  4929. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  4930. */
  4931. static int sp_2048_mod_36(sp_digit* r, const sp_digit* a, const sp_digit* m)
  4932. {
  4933. return sp_2048_div_36(a, m, NULL, r);
  4934. }
  4935. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  4936. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \
  4937. defined(WOLFSSL_HAVE_SP_DH)
  4938. /* Modular exponentiate a to the e mod m. (r = a^e mod m)
  4939. *
  4940. * r A single precision number that is the result of the operation.
  4941. * a A single precision number being exponentiated.
  4942. * e A single precision number that is the exponent.
  4943. * bits The number of bits in the exponent.
  4944. * m A single precision number that is the modulus.
  4945. * returns 0 on success.
  4946. * returns MEMORY_E on dynamic memory allocation failure.
  4947. * returns MP_VAL when base is even or exponent is 0.
  4948. */
  4949. static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, const sp_digit* e,
  4950. int bits, const sp_digit* m, int reduceA)
  4951. {
  4952. #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
  4953. #ifdef WOLFSSL_SP_SMALL_STACK
  4954. sp_digit* td = NULL;
  4955. #else
  4956. sp_digit td[3 * 72];
  4957. #endif
  4958. sp_digit* t[3] = {0, 0, 0};
  4959. sp_digit* norm = NULL;
  4960. sp_digit mp = 1;
  4961. sp_digit n;
  4962. int i;
  4963. int c;
  4964. byte y;
  4965. int err = MP_OKAY;
  4966. if (bits == 0) {
  4967. err = MP_VAL;
  4968. }
  4969. #ifdef WOLFSSL_SP_SMALL_STACK
  4970. if (err == MP_OKAY) {
  4971. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 36 * 2, NULL,
  4972. DYNAMIC_TYPE_TMP_BUFFER);
  4973. if (td == NULL)
  4974. err = MEMORY_E;
  4975. }
  4976. #endif
  4977. if (err == MP_OKAY) {
  4978. norm = td;
  4979. for (i=0; i<3; i++) {
  4980. t[i] = td + (i * 36 * 2);
  4981. XMEMSET(t[i], 0, sizeof(sp_digit) * 36U * 2U);
  4982. }
  4983. sp_2048_mont_setup(m, &mp);
  4984. sp_2048_mont_norm_36(norm, m);
  4985. if (reduceA != 0) {
  4986. err = sp_2048_mod_36(t[1], a, m);
  4987. }
  4988. else {
  4989. XMEMCPY(t[1], a, sizeof(sp_digit) * 36U);
  4990. }
  4991. }
  4992. if (err == MP_OKAY) {
  4993. sp_2048_mul_36(t[1], t[1], norm);
  4994. err = sp_2048_mod_36(t[1], t[1], m);
  4995. }
  4996. if (err == MP_OKAY) {
  4997. i = bits / 57;
  4998. c = bits % 57;
  4999. n = e[i--] << (57 - c);
  5000. for (; ; c--) {
  5001. if (c == 0) {
  5002. if (i == -1) {
  5003. break;
  5004. }
  5005. n = e[i--];
  5006. c = 57;
  5007. }
  5008. y = (int)((n >> 56) & 1);
  5009. n <<= 1;
  5010. sp_2048_mont_mul_36(t[y^1], t[0], t[1], m, mp);
  5011. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  5012. ((size_t)t[1] & addr_mask[y])),
  5013. sizeof(*t[2]) * 36 * 2);
  5014. sp_2048_mont_sqr_36(t[2], t[2], m, mp);
  5015. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  5016. ((size_t)t[1] & addr_mask[y])), t[2],
  5017. sizeof(*t[2]) * 36 * 2);
  5018. }
  5019. sp_2048_mont_reduce_36(t[0], m, mp);
  5020. n = sp_2048_cmp_36(t[0], m);
  5021. sp_2048_cond_sub_36(t[0], t[0], m, ~(n >> 63));
  5022. XMEMCPY(r, t[0], sizeof(*r) * 36 * 2);
  5023. }
  5024. #ifdef WOLFSSL_SP_SMALL_STACK
  5025. if (td != NULL)
  5026. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  5027. #endif
  5028. return err;
  5029. #elif !defined(WC_NO_CACHE_RESISTANT)
  5030. #ifdef WOLFSSL_SP_SMALL_STACK
  5031. sp_digit* td = NULL;
  5032. #else
  5033. sp_digit td[3 * 72];
  5034. #endif
  5035. sp_digit* t[3] = {0, 0, 0};
  5036. sp_digit* norm = NULL;
  5037. sp_digit mp = 1;
  5038. sp_digit n;
  5039. int i;
  5040. int c;
  5041. byte y;
  5042. int err = MP_OKAY;
  5043. if (bits == 0) {
  5044. err = MP_VAL;
  5045. }
  5046. #ifdef WOLFSSL_SP_SMALL_STACK
  5047. if (err == MP_OKAY) {
  5048. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 36 * 2, NULL,
  5049. DYNAMIC_TYPE_TMP_BUFFER);
  5050. if (td == NULL)
  5051. err = MEMORY_E;
  5052. }
  5053. #endif
  5054. if (err == MP_OKAY) {
  5055. norm = td;
  5056. for (i=0; i<3; i++) {
  5057. t[i] = td + (i * 36 * 2);
  5058. }
  5059. sp_2048_mont_setup(m, &mp);
  5060. sp_2048_mont_norm_36(norm, m);
  5061. if (reduceA != 0) {
  5062. err = sp_2048_mod_36(t[1], a, m);
  5063. if (err == MP_OKAY) {
  5064. sp_2048_mul_36(t[1], t[1], norm);
  5065. err = sp_2048_mod_36(t[1], t[1], m);
  5066. }
  5067. }
  5068. else {
  5069. sp_2048_mul_36(t[1], a, norm);
  5070. err = sp_2048_mod_36(t[1], t[1], m);
  5071. }
  5072. }
  5073. if (err == MP_OKAY) {
  5074. i = bits / 57;
  5075. c = bits % 57;
  5076. n = e[i--] << (57 - c);
  5077. for (; ; c--) {
  5078. if (c == 0) {
  5079. if (i == -1) {
  5080. break;
  5081. }
  5082. n = e[i--];
  5083. c = 57;
  5084. }
  5085. y = (int)((n >> 56) & 1);
  5086. n <<= 1;
  5087. sp_2048_mont_mul_36(t[y^1], t[0], t[1], m, mp);
  5088. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  5089. ((size_t)t[1] & addr_mask[y])),
  5090. sizeof(*t[2]) * 36 * 2);
  5091. sp_2048_mont_sqr_36(t[2], t[2], m, mp);
  5092. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  5093. ((size_t)t[1] & addr_mask[y])), t[2],
  5094. sizeof(*t[2]) * 36 * 2);
  5095. }
  5096. sp_2048_mont_reduce_36(t[0], m, mp);
  5097. n = sp_2048_cmp_36(t[0], m);
  5098. sp_2048_cond_sub_36(t[0], t[0], m, ~(n >> 63));
  5099. XMEMCPY(r, t[0], sizeof(*r) * 36 * 2);
  5100. }
  5101. #ifdef WOLFSSL_SP_SMALL_STACK
  5102. if (td != NULL)
  5103. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  5104. #endif
  5105. return err;
  5106. #else
  5107. #ifdef WOLFSSL_SP_SMALL_STACK
  5108. sp_digit* td = NULL;
  5109. #else
  5110. sp_digit td[(16 * 72) + 72];
  5111. #endif
  5112. sp_digit* t[16];
  5113. sp_digit* rt = NULL;
  5114. sp_digit* norm = NULL;
  5115. sp_digit mp = 1;
  5116. sp_digit n;
  5117. int i;
  5118. int c;
  5119. byte y;
  5120. int err = MP_OKAY;
  5121. if (bits == 0) {
  5122. err = MP_VAL;
  5123. }
  5124. #ifdef WOLFSSL_SP_SMALL_STACK
  5125. if (err == MP_OKAY) {
  5126. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((16 * 72) + 72), NULL,
  5127. DYNAMIC_TYPE_TMP_BUFFER);
  5128. if (td == NULL)
  5129. err = MEMORY_E;
  5130. }
  5131. #endif
  5132. if (err == MP_OKAY) {
  5133. norm = td;
  5134. for (i=0; i<16; i++)
  5135. t[i] = td + i * 72;
  5136. rt = td + 1152;
  5137. sp_2048_mont_setup(m, &mp);
  5138. sp_2048_mont_norm_36(norm, m);
  5139. if (reduceA != 0) {
  5140. err = sp_2048_mod_36(t[1], a, m);
  5141. if (err == MP_OKAY) {
  5142. sp_2048_mul_36(t[1], t[1], norm);
  5143. err = sp_2048_mod_36(t[1], t[1], m);
  5144. }
  5145. }
  5146. else {
  5147. sp_2048_mul_36(t[1], a, norm);
  5148. err = sp_2048_mod_36(t[1], t[1], m);
  5149. }
  5150. }
  5151. if (err == MP_OKAY) {
  5152. sp_2048_mont_sqr_36(t[ 2], t[ 1], m, mp);
  5153. sp_2048_mont_mul_36(t[ 3], t[ 2], t[ 1], m, mp);
  5154. sp_2048_mont_sqr_36(t[ 4], t[ 2], m, mp);
  5155. sp_2048_mont_mul_36(t[ 5], t[ 3], t[ 2], m, mp);
  5156. sp_2048_mont_sqr_36(t[ 6], t[ 3], m, mp);
  5157. sp_2048_mont_mul_36(t[ 7], t[ 4], t[ 3], m, mp);
  5158. sp_2048_mont_sqr_36(t[ 8], t[ 4], m, mp);
  5159. sp_2048_mont_mul_36(t[ 9], t[ 5], t[ 4], m, mp);
  5160. sp_2048_mont_sqr_36(t[10], t[ 5], m, mp);
  5161. sp_2048_mont_mul_36(t[11], t[ 6], t[ 5], m, mp);
  5162. sp_2048_mont_sqr_36(t[12], t[ 6], m, mp);
  5163. sp_2048_mont_mul_36(t[13], t[ 7], t[ 6], m, mp);
  5164. sp_2048_mont_sqr_36(t[14], t[ 7], m, mp);
  5165. sp_2048_mont_mul_36(t[15], t[ 8], t[ 7], m, mp);
  5166. bits = ((bits + 3) / 4) * 4;
  5167. i = ((bits + 56) / 57) - 1;
  5168. c = bits % 57;
  5169. if (c == 0) {
  5170. c = 57;
  5171. }
  5172. if (i < 36) {
  5173. n = e[i--] << (64 - c);
  5174. }
  5175. else {
  5176. n = 0;
  5177. i--;
  5178. }
  5179. if (c < 4) {
  5180. n |= e[i--] << (7 - c);
  5181. c += 57;
  5182. }
  5183. y = (int)((n >> 60) & 0xf);
  5184. n <<= 4;
  5185. c -= 4;
  5186. XMEMCPY(rt, t[y], sizeof(sp_digit) * 72);
  5187. while ((i >= 0) || (c >= 4)) {
  5188. if (c >= 4) {
  5189. y = (byte)((n >> 60) & 0xf);
  5190. n <<= 4;
  5191. c -= 4;
  5192. }
  5193. else if (c == 0) {
  5194. n = e[i--] << 7;
  5195. y = (byte)((n >> 60) & 0xf);
  5196. n <<= 4;
  5197. c = 53;
  5198. }
  5199. else {
  5200. y = (byte)((n >> 60) & 0xf);
  5201. n = e[i--] << 7;
  5202. c = 4 - c;
  5203. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  5204. n <<= c;
  5205. c = 57 - c;
  5206. }
  5207. sp_2048_mont_sqr_36(rt, rt, m, mp);
  5208. sp_2048_mont_sqr_36(rt, rt, m, mp);
  5209. sp_2048_mont_sqr_36(rt, rt, m, mp);
  5210. sp_2048_mont_sqr_36(rt, rt, m, mp);
  5211. sp_2048_mont_mul_36(rt, rt, t[y], m, mp);
  5212. }
  5213. sp_2048_mont_reduce_36(rt, m, mp);
  5214. n = sp_2048_cmp_36(rt, m);
  5215. sp_2048_cond_sub_36(rt, rt, m, ~(n >> 63));
  5216. XMEMCPY(r, rt, sizeof(sp_digit) * 72);
  5217. }
  5218. #ifdef WOLFSSL_SP_SMALL_STACK
  5219. if (td != NULL)
  5220. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  5221. #endif
  5222. return err;
  5223. #endif
  5224. }
  5225. #endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) || */
  5226. /* WOLFSSL_HAVE_SP_DH */
  5227. #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
  5228. #ifdef WOLFSSL_HAVE_SP_RSA
  5229. /* RSA public key operation.
  5230. *
  5231. * in Array of bytes representing the number to exponentiate, base.
  5232. * inLen Number of bytes in base.
  5233. * em Public exponent.
  5234. * mm Modulus.
  5235. * out Buffer to hold big-endian bytes of exponentiation result.
  5236. * Must be at least 256 bytes long.
  5237. * outLen Number of bytes in result.
  5238. * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
  5239. * an array is too long and MEMORY_E when dynamic memory allocation fails.
  5240. */
  5241. int sp_RsaPublic_2048(const byte* in, word32 inLen, const mp_int* em,
  5242. const mp_int* mm, byte* out, word32* outLen)
  5243. {
  5244. #ifdef WOLFSSL_SP_SMALL
  5245. #ifdef WOLFSSL_SP_SMALL_STACK
  5246. sp_digit* a = NULL;
  5247. #else
  5248. sp_digit a[36 * 5];
  5249. #endif
  5250. sp_digit* m = NULL;
  5251. sp_digit* r = NULL;
  5252. sp_digit* norm = NULL;
  5253. sp_uint64 e[1] = {0};
  5254. sp_digit mp = 0;
  5255. int i;
  5256. int err = MP_OKAY;
  5257. if (*outLen < 256U) {
  5258. err = MP_TO_E;
  5259. }
  5260. if (err == MP_OKAY) {
  5261. if (mp_count_bits(em) > 64) {
  5262. err = MP_READ_E;
  5263. }
  5264. else if (inLen > 256U) {
  5265. err = MP_READ_E;
  5266. }
  5267. else if (mp_count_bits(mm) != 2048) {
  5268. err = MP_READ_E;
  5269. }
  5270. else if (mp_iseven(mm)) {
  5271. err = MP_VAL;
  5272. }
  5273. }
  5274. #ifdef WOLFSSL_SP_SMALL_STACK
  5275. if (err == MP_OKAY) {
  5276. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 5, NULL,
  5277. DYNAMIC_TYPE_RSA);
  5278. if (a == NULL)
  5279. err = MEMORY_E;
  5280. }
  5281. #endif
  5282. if (err == MP_OKAY) {
  5283. r = a + 36 * 2;
  5284. m = r + 36 * 2;
  5285. norm = r;
  5286. sp_2048_from_bin(a, 36, in, inLen);
  5287. #if DIGIT_BIT >= 64
  5288. e[0] = (sp_uint64)em->dp[0];
  5289. #else
  5290. e[0] = (sp_uint64)em->dp[0];
  5291. if (em->used > 1) {
  5292. e[0] |= ((sp_uint64)em->dp[1]) << DIGIT_BIT;
  5293. }
  5294. #endif
  5295. if (e[0] == 0) {
  5296. err = MP_EXPTMOD_E;
  5297. }
  5298. }
  5299. if (err == MP_OKAY) {
  5300. sp_2048_from_mp(m, 36, mm);
  5301. sp_2048_mont_setup(m, &mp);
  5302. sp_2048_mont_norm_36(norm, m);
  5303. }
  5304. if (err == MP_OKAY) {
  5305. sp_2048_mul_36(a, a, norm);
  5306. err = sp_2048_mod_36(a, a, m);
  5307. }
  5308. if (err == MP_OKAY) {
  5309. for (i=63; i>=0; i--) {
  5310. if ((e[0] >> i) != 0) {
  5311. break;
  5312. }
  5313. }
  5314. XMEMCPY(r, a, sizeof(sp_digit) * 36 * 2);
  5315. for (i--; i>=0; i--) {
  5316. sp_2048_mont_sqr_36(r, r, m, mp);
  5317. if (((e[0] >> i) & 1) == 1) {
  5318. sp_2048_mont_mul_36(r, r, a, m, mp);
  5319. }
  5320. }
  5321. sp_2048_mont_reduce_36(r, m, mp);
  5322. mp = sp_2048_cmp_36(r, m);
  5323. sp_2048_cond_sub_36(r, r, m, ~(mp >> 63));
  5324. sp_2048_to_bin_36(r, out);
  5325. *outLen = 256;
  5326. }
  5327. #ifdef WOLFSSL_SP_SMALL_STACK
  5328. if (a != NULL)
  5329. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  5330. #endif
  5331. return err;
  5332. #else
  5333. #ifdef WOLFSSL_SP_SMALL_STACK
  5334. sp_digit* d = NULL;
  5335. #else
  5336. sp_digit d[36 * 5];
  5337. #endif
  5338. sp_digit* a = NULL;
  5339. sp_digit* m = NULL;
  5340. sp_digit* r = NULL;
  5341. sp_uint64 e[1] = {0};
  5342. int err = MP_OKAY;
  5343. if (*outLen < 256U) {
  5344. err = MP_TO_E;
  5345. }
  5346. if (err == MP_OKAY) {
  5347. if (mp_count_bits(em) > 64) {
  5348. err = MP_READ_E;
  5349. }
  5350. else if (inLen > 256U) {
  5351. err = MP_READ_E;
  5352. }
  5353. else if (mp_count_bits(mm) != 2048) {
  5354. err = MP_READ_E;
  5355. }
  5356. else if (mp_iseven(mm)) {
  5357. err = MP_VAL;
  5358. }
  5359. }
  5360. #ifdef WOLFSSL_SP_SMALL_STACK
  5361. if (err == MP_OKAY) {
  5362. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 5, NULL,
  5363. DYNAMIC_TYPE_RSA);
  5364. if (d == NULL)
  5365. err = MEMORY_E;
  5366. }
  5367. #endif
  5368. if (err == MP_OKAY) {
  5369. a = d;
  5370. r = a + 36 * 2;
  5371. m = r + 36 * 2;
  5372. sp_2048_from_bin(a, 36, in, inLen);
  5373. #if DIGIT_BIT >= 64
  5374. e[0] = (sp_uint64)em->dp[0];
  5375. #else
  5376. e[0] = (sp_uint64)em->dp[0];
  5377. if (em->used > 1) {
  5378. e[0] |= ((sp_uint64)em->dp[1]) << DIGIT_BIT;
  5379. }
  5380. #endif
  5381. if (e[0] == 0) {
  5382. err = MP_EXPTMOD_E;
  5383. }
  5384. }
  5385. if (err == MP_OKAY) {
  5386. sp_2048_from_mp(m, 36, mm);
  5387. if (e[0] == 0x3) {
  5388. sp_2048_sqr_36(r, a);
  5389. err = sp_2048_mod_36(r, r, m);
  5390. if (err == MP_OKAY) {
  5391. sp_2048_mul_36(r, a, r);
  5392. err = sp_2048_mod_36(r, r, m);
  5393. }
  5394. }
  5395. else {
  5396. sp_digit* norm = r;
  5397. int i;
  5398. sp_digit mp;
  5399. sp_2048_mont_setup(m, &mp);
  5400. sp_2048_mont_norm_36(norm, m);
  5401. sp_2048_mul_36(a, a, norm);
  5402. err = sp_2048_mod_36(a, a, m);
  5403. if (err == MP_OKAY) {
  5404. for (i=63; i>=0; i--) {
  5405. if ((e[0] >> i) != 0) {
  5406. break;
  5407. }
  5408. }
  5409. XMEMCPY(r, a, sizeof(sp_digit) * 72U);
  5410. for (i--; i>=0; i--) {
  5411. sp_2048_mont_sqr_36(r, r, m, mp);
  5412. if (((e[0] >> i) & 1) == 1) {
  5413. sp_2048_mont_mul_36(r, r, a, m, mp);
  5414. }
  5415. }
  5416. sp_2048_mont_reduce_36(r, m, mp);
  5417. mp = sp_2048_cmp_36(r, m);
  5418. sp_2048_cond_sub_36(r, r, m, ~(mp >> 63));
  5419. }
  5420. }
  5421. }
  5422. if (err == MP_OKAY) {
  5423. sp_2048_to_bin_36(r, out);
  5424. *outLen = 256;
  5425. }
  5426. #ifdef WOLFSSL_SP_SMALL_STACK
  5427. if (d != NULL)
  5428. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  5429. #endif
  5430. return err;
  5431. #endif /* WOLFSSL_SP_SMALL */
  5432. }
  5433. #ifndef WOLFSSL_RSA_PUBLIC_ONLY
  5434. #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM)
  5435. #endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */
  5436. /* RSA private key operation.
  5437. *
  5438. * in Array of bytes representing the number to exponentiate, base.
  5439. * inLen Number of bytes in base.
  5440. * dm Private exponent.
  5441. * pm First prime.
  5442. * qm Second prime.
  5443. * dpm First prime's CRT exponent.
  5444. * dqm Second prime's CRT exponent.
  5445. * qim Inverse of second prime mod p.
  5446. * mm Modulus.
  5447. * out Buffer to hold big-endian bytes of exponentiation result.
  5448. * Must be at least 256 bytes long.
  5449. * outLen Number of bytes in result.
  5450. * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
  5451. * an array is too long and MEMORY_E when dynamic memory allocation fails.
  5452. */
  5453. int sp_RsaPrivate_2048(const byte* in, word32 inLen, const mp_int* dm,
  5454. const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm,
  5455. const mp_int* qim, const mp_int* mm, byte* out, word32* outLen)
  5456. {
  5457. #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
  5458. #if defined(WOLFSSL_SP_SMALL)
  5459. #ifdef WOLFSSL_SP_SMALL_STACK
  5460. sp_digit* d = NULL;
  5461. #else
  5462. sp_digit d[36 * 4];
  5463. #endif
  5464. sp_digit* a = NULL;
  5465. sp_digit* m = NULL;
  5466. sp_digit* r = NULL;
  5467. int err = MP_OKAY;
  5468. (void)pm;
  5469. (void)qm;
  5470. (void)dpm;
  5471. (void)dqm;
  5472. (void)qim;
  5473. if (*outLen < 256U) {
  5474. err = MP_TO_E;
  5475. }
  5476. if (err == MP_OKAY) {
  5477. if (mp_count_bits(dm) > 2048) {
  5478. err = MP_READ_E;
  5479. }
  5480. else if (inLen > 256) {
  5481. err = MP_READ_E;
  5482. }
  5483. else if (mp_count_bits(mm) != 2048) {
  5484. err = MP_READ_E;
  5485. }
  5486. else if (mp_iseven(mm)) {
  5487. err = MP_VAL;
  5488. }
  5489. }
  5490. #ifdef WOLFSSL_SP_SMALL_STACK
  5491. if (err == MP_OKAY) {
  5492. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 4, NULL,
  5493. DYNAMIC_TYPE_RSA);
  5494. if (d == NULL)
  5495. err = MEMORY_E;
  5496. }
  5497. #endif
  5498. if (err == MP_OKAY) {
  5499. a = d + 36;
  5500. m = a + 72;
  5501. r = a;
  5502. sp_2048_from_bin(a, 36, in, inLen);
  5503. sp_2048_from_mp(d, 36, dm);
  5504. sp_2048_from_mp(m, 36, mm);
  5505. err = sp_2048_mod_exp_36(r, a, d, 2048, m, 0);
  5506. }
  5507. if (err == MP_OKAY) {
  5508. sp_2048_to_bin_36(r, out);
  5509. *outLen = 256;
  5510. }
  5511. #ifdef WOLFSSL_SP_SMALL_STACK
  5512. if (d != NULL)
  5513. #endif
  5514. {
  5515. /* only "a" and "r" are sensitive and need zeroized (same pointer) */
  5516. if (a != NULL)
  5517. ForceZero(a, sizeof(sp_digit) * 36);
  5518. #ifdef WOLFSSL_SP_SMALL_STACK
  5519. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  5520. #endif
  5521. }
  5522. return err;
  5523. #else
  5524. #ifdef WOLFSSL_SP_SMALL_STACK
  5525. sp_digit* d = NULL;
  5526. #else
  5527. sp_digit d[36 * 4];
  5528. #endif
  5529. sp_digit* a = NULL;
  5530. sp_digit* m = NULL;
  5531. sp_digit* r = NULL;
  5532. int err = MP_OKAY;
  5533. (void)pm;
  5534. (void)qm;
  5535. (void)dpm;
  5536. (void)dqm;
  5537. (void)qim;
  5538. if (*outLen < 256U) {
  5539. err = MP_TO_E;
  5540. }
  5541. if (err == MP_OKAY) {
  5542. if (mp_count_bits(dm) > 2048) {
  5543. err = MP_READ_E;
  5544. }
  5545. else if (inLen > 256U) {
  5546. err = MP_READ_E;
  5547. }
  5548. else if (mp_count_bits(mm) != 2048) {
  5549. err = MP_READ_E;
  5550. }
  5551. else if (mp_iseven(mm)) {
  5552. err = MP_VAL;
  5553. }
  5554. }
  5555. #ifdef WOLFSSL_SP_SMALL_STACK
  5556. if (err == MP_OKAY) {
  5557. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 4, NULL,
  5558. DYNAMIC_TYPE_RSA);
  5559. if (d == NULL)
  5560. err = MEMORY_E;
  5561. }
  5562. #endif
  5563. if (err == MP_OKAY) {
  5564. a = d + 36;
  5565. m = a + 72;
  5566. r = a;
  5567. sp_2048_from_bin(a, 36, in, inLen);
  5568. sp_2048_from_mp(d, 36, dm);
  5569. sp_2048_from_mp(m, 36, mm);
  5570. err = sp_2048_mod_exp_36(r, a, d, 2048, m, 0);
  5571. }
  5572. if (err == MP_OKAY) {
  5573. sp_2048_to_bin_36(r, out);
  5574. *outLen = 256;
  5575. }
  5576. #ifdef WOLFSSL_SP_SMALL_STACK
  5577. if (d != NULL)
  5578. #endif
  5579. {
  5580. /* only "a" and "r" are sensitive and need zeroized (same pointer) */
  5581. if (a != NULL)
  5582. ForceZero(a, sizeof(sp_digit) * 36);
  5583. #ifdef WOLFSSL_SP_SMALL_STACK
  5584. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  5585. #endif
  5586. }
  5587. return err;
  5588. #endif /* WOLFSSL_SP_SMALL */
  5589. #else
  5590. #if defined(WOLFSSL_SP_SMALL)
  5591. #ifdef WOLFSSL_SP_SMALL_STACK
  5592. sp_digit* a = NULL;
  5593. #else
  5594. sp_digit a[18 * 8];
  5595. #endif
  5596. sp_digit* p = NULL;
  5597. sp_digit* dp = NULL;
  5598. sp_digit* dq = NULL;
  5599. sp_digit* qi = NULL;
  5600. sp_digit* tmpa = NULL;
  5601. sp_digit* tmpb = NULL;
  5602. sp_digit* r = NULL;
  5603. int err = MP_OKAY;
  5604. (void)dm;
  5605. (void)mm;
  5606. if (*outLen < 256U) {
  5607. err = MP_TO_E;
  5608. }
  5609. if (err == MP_OKAY) {
  5610. if (inLen > 256) {
  5611. err = MP_READ_E;
  5612. }
  5613. else if (mp_count_bits(mm) != 2048) {
  5614. err = MP_READ_E;
  5615. }
  5616. else if (mp_iseven(mm)) {
  5617. err = MP_VAL;
  5618. }
  5619. else if (mp_iseven(pm)) {
  5620. err = MP_VAL;
  5621. }
  5622. else if (mp_iseven(qm)) {
  5623. err = MP_VAL;
  5624. }
  5625. }
  5626. #ifdef WOLFSSL_SP_SMALL_STACK
  5627. if (err == MP_OKAY) {
  5628. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 8, NULL,
  5629. DYNAMIC_TYPE_RSA);
  5630. if (a == NULL)
  5631. err = MEMORY_E;
  5632. }
  5633. #endif
  5634. if (err == MP_OKAY) {
  5635. p = a + 36;
  5636. qi = dq = dp = p + 18;
  5637. tmpa = qi + 18;
  5638. tmpb = tmpa + 36;
  5639. r = a;
  5640. sp_2048_from_bin(a, 36, in, inLen);
  5641. sp_2048_from_mp(p, 18, pm);
  5642. sp_2048_from_mp(dp, 18, dpm);
  5643. err = sp_2048_mod_exp_18(tmpa, a, dp, 1024, p, 1);
  5644. }
  5645. if (err == MP_OKAY) {
  5646. sp_2048_from_mp(p, 18, qm);
  5647. sp_2048_from_mp(dq, 18, dqm);
  5648. err = sp_2048_mod_exp_18(tmpb, a, dq, 1024, p, 1);
  5649. }
  5650. if (err == MP_OKAY) {
  5651. sp_2048_from_mp(p, 18, pm);
  5652. (void)sp_2048_sub_18(tmpa, tmpa, tmpb);
  5653. sp_2048_norm_18(tmpa);
  5654. sp_2048_cond_add_18(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[17] >> 63));
  5655. sp_2048_cond_add_18(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[17] >> 63));
  5656. sp_2048_norm_18(tmpa);
  5657. sp_2048_from_mp(qi, 18, qim);
  5658. sp_2048_mul_18(tmpa, tmpa, qi);
  5659. err = sp_2048_mod_18(tmpa, tmpa, p);
  5660. }
  5661. if (err == MP_OKAY) {
  5662. sp_2048_from_mp(p, 18, qm);
  5663. sp_2048_mul_18(tmpa, p, tmpa);
  5664. (void)sp_2048_add_36(r, tmpb, tmpa);
  5665. sp_2048_norm_36(r);
  5666. sp_2048_to_bin_36(r, out);
  5667. *outLen = 256;
  5668. }
  5669. #ifdef WOLFSSL_SP_SMALL_STACK
  5670. if (a != NULL)
  5671. #endif
  5672. {
  5673. ForceZero(a, sizeof(sp_digit) * 18 * 8);
  5674. #ifdef WOLFSSL_SP_SMALL_STACK
  5675. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  5676. #endif
  5677. }
  5678. return err;
  5679. #else
  5680. #ifdef WOLFSSL_SP_SMALL_STACK
  5681. sp_digit* a = NULL;
  5682. #else
  5683. sp_digit a[18 * 13];
  5684. #endif
  5685. sp_digit* p = NULL;
  5686. sp_digit* q = NULL;
  5687. sp_digit* dp = NULL;
  5688. sp_digit* dq = NULL;
  5689. sp_digit* qi = NULL;
  5690. sp_digit* tmpa = NULL;
  5691. sp_digit* tmpb = NULL;
  5692. sp_digit* r = NULL;
  5693. int err = MP_OKAY;
  5694. (void)dm;
  5695. (void)mm;
  5696. if (*outLen < 256U) {
  5697. err = MP_TO_E;
  5698. }
  5699. if (err == MP_OKAY) {
  5700. if (inLen > 256U) {
  5701. err = MP_READ_E;
  5702. }
  5703. else if (mp_count_bits(mm) != 2048) {
  5704. err = MP_READ_E;
  5705. }
  5706. else if (mp_iseven(mm)) {
  5707. err = MP_VAL;
  5708. }
  5709. else if (mp_iseven(pm)) {
  5710. err = MP_VAL;
  5711. }
  5712. else if (mp_iseven(qm)) {
  5713. err = MP_VAL;
  5714. }
  5715. }
  5716. #ifdef WOLFSSL_SP_SMALL_STACK
  5717. if (err == MP_OKAY) {
  5718. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 13, NULL,
  5719. DYNAMIC_TYPE_RSA);
  5720. if (a == NULL)
  5721. err = MEMORY_E;
  5722. }
  5723. #endif
  5724. if (err == MP_OKAY) {
  5725. p = a + 36 * 2;
  5726. q = p + 18;
  5727. dp = q + 18;
  5728. dq = dp + 18;
  5729. qi = dq + 18;
  5730. tmpa = qi + 18;
  5731. tmpb = tmpa + 36;
  5732. r = a;
  5733. sp_2048_from_bin(a, 36, in, inLen);
  5734. sp_2048_from_mp(p, 18, pm);
  5735. sp_2048_from_mp(q, 18, qm);
  5736. sp_2048_from_mp(dp, 18, dpm);
  5737. sp_2048_from_mp(dq, 18, dqm);
  5738. sp_2048_from_mp(qi, 18, qim);
  5739. err = sp_2048_mod_exp_18(tmpa, a, dp, 1024, p, 1);
  5740. }
  5741. if (err == MP_OKAY) {
  5742. err = sp_2048_mod_exp_18(tmpb, a, dq, 1024, q, 1);
  5743. }
  5744. if (err == MP_OKAY) {
  5745. (void)sp_2048_sub_18(tmpa, tmpa, tmpb);
  5746. sp_2048_norm_18(tmpa);
  5747. sp_2048_cond_add_18(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[17] >> 63));
  5748. sp_2048_cond_add_18(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[17] >> 63));
  5749. sp_2048_norm_18(tmpa);
  5750. sp_2048_mul_18(tmpa, tmpa, qi);
  5751. err = sp_2048_mod_18(tmpa, tmpa, p);
  5752. }
  5753. if (err == MP_OKAY) {
  5754. sp_2048_mul_18(tmpa, tmpa, q);
  5755. (void)sp_2048_add_36(r, tmpb, tmpa);
  5756. sp_2048_norm_36(r);
  5757. sp_2048_to_bin_36(r, out);
  5758. *outLen = 256;
  5759. }
  5760. #ifdef WOLFSSL_SP_SMALL_STACK
  5761. if (a != NULL)
  5762. #endif
  5763. {
  5764. ForceZero(a, sizeof(sp_digit) * 18 * 13);
  5765. #ifdef WOLFSSL_SP_SMALL_STACK
  5766. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  5767. #endif
  5768. }
  5769. return err;
  5770. #endif /* WOLFSSL_SP_SMALL */
  5771. #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
  5772. }
  5773. #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
  5774. #endif /* WOLFSSL_HAVE_SP_RSA */
  5775. #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
  5776. !defined(WOLFSSL_RSA_PUBLIC_ONLY))
  5777. /* Convert an array of sp_digit to an mp_int.
  5778. *
  5779. * a A single precision integer.
  5780. * r A multi-precision integer.
  5781. */
  5782. static int sp_2048_to_mp(const sp_digit* a, mp_int* r)
  5783. {
  5784. int err;
  5785. err = mp_grow(r, (2048 + DIGIT_BIT - 1) / DIGIT_BIT);
  5786. if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
  5787. #if DIGIT_BIT == 57
  5788. XMEMCPY(r->dp, a, sizeof(sp_digit) * 36);
  5789. r->used = 36;
  5790. mp_clamp(r);
  5791. #elif DIGIT_BIT < 57
  5792. int i;
  5793. int j = 0;
  5794. int s = 0;
  5795. r->dp[0] = 0;
  5796. for (i = 0; i < 36; i++) {
  5797. r->dp[j] |= (mp_digit)(a[i] << s);
  5798. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  5799. s = DIGIT_BIT - s;
  5800. r->dp[++j] = (mp_digit)(a[i] >> s);
  5801. while (s + DIGIT_BIT <= 57) {
  5802. s += DIGIT_BIT;
  5803. r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  5804. if (s == SP_WORD_SIZE) {
  5805. r->dp[j] = 0;
  5806. }
  5807. else {
  5808. r->dp[j] = (mp_digit)(a[i] >> s);
  5809. }
  5810. }
  5811. s = 57 - s;
  5812. }
  5813. r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;
  5814. mp_clamp(r);
  5815. #else
  5816. int i;
  5817. int j = 0;
  5818. int s = 0;
  5819. r->dp[0] = 0;
  5820. for (i = 0; i < 36; i++) {
  5821. r->dp[j] |= ((mp_digit)a[i]) << s;
  5822. if (s + 57 >= DIGIT_BIT) {
  5823. #if DIGIT_BIT != 32 && DIGIT_BIT != 64
  5824. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  5825. #endif
  5826. s = DIGIT_BIT - s;
  5827. r->dp[++j] = a[i] >> s;
  5828. s = 57 - s;
  5829. }
  5830. else {
  5831. s += 57;
  5832. }
  5833. }
  5834. r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;
  5835. mp_clamp(r);
  5836. #endif
  5837. }
  5838. return err;
  5839. }
  5840. /* Perform the modular exponentiation for Diffie-Hellman.
  5841. *
  5842. * base Base. MP integer.
  5843. * exp Exponent. MP integer.
  5844. * mod Modulus. MP integer.
  5845. * res Result. MP integer.
  5846. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  5847. * and MEMORY_E if memory allocation fails.
  5848. */
  5849. int sp_ModExp_2048(const mp_int* base, const mp_int* exp, const mp_int* mod,
  5850. mp_int* res)
  5851. {
  5852. #ifdef WOLFSSL_SP_SMALL
  5853. int err = MP_OKAY;
  5854. #ifdef WOLFSSL_SP_SMALL_STACK
  5855. sp_digit* b = NULL;
  5856. #else
  5857. sp_digit b[36 * 4];
  5858. #endif
  5859. sp_digit* e = NULL;
  5860. sp_digit* m = NULL;
  5861. sp_digit* r = NULL;
  5862. int expBits = mp_count_bits(exp);
  5863. if (mp_count_bits(base) > 2048) {
  5864. err = MP_READ_E;
  5865. }
  5866. else if (expBits > 2048) {
  5867. err = MP_READ_E;
  5868. }
  5869. else if (mp_count_bits(mod) != 2048) {
  5870. err = MP_READ_E;
  5871. }
  5872. else if (mp_iseven(mod)) {
  5873. err = MP_VAL;
  5874. }
  5875. #ifdef WOLFSSL_SP_SMALL_STACK
  5876. if (err == MP_OKAY) {
  5877. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 4, NULL,
  5878. DYNAMIC_TYPE_DH);
  5879. if (b == NULL)
  5880. err = MEMORY_E;
  5881. }
  5882. #endif
  5883. if (err == MP_OKAY) {
  5884. e = b + 36 * 2;
  5885. m = e + 36;
  5886. r = b;
  5887. sp_2048_from_mp(b, 36, base);
  5888. sp_2048_from_mp(e, 36, exp);
  5889. sp_2048_from_mp(m, 36, mod);
  5890. err = sp_2048_mod_exp_36(r, b, e, mp_count_bits(exp), m, 0);
  5891. }
  5892. if (err == MP_OKAY) {
  5893. err = sp_2048_to_mp(r, res);
  5894. }
  5895. #ifdef WOLFSSL_SP_SMALL_STACK
  5896. if (b != NULL)
  5897. #endif
  5898. {
  5899. /* only "e" is sensitive and needs zeroized */
  5900. if (e != NULL)
  5901. ForceZero(e, sizeof(sp_digit) * 36U);
  5902. #ifdef WOLFSSL_SP_SMALL_STACK
  5903. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  5904. #endif
  5905. }
  5906. return err;
  5907. #else
  5908. #ifdef WOLFSSL_SP_SMALL_STACK
  5909. sp_digit* b = NULL;
  5910. #else
  5911. sp_digit b[36 * 4];
  5912. #endif
  5913. sp_digit* e = NULL;
  5914. sp_digit* m = NULL;
  5915. sp_digit* r = NULL;
  5916. int err = MP_OKAY;
  5917. int expBits = mp_count_bits(exp);
  5918. if (mp_count_bits(base) > 2048) {
  5919. err = MP_READ_E;
  5920. }
  5921. else if (expBits > 2048) {
  5922. err = MP_READ_E;
  5923. }
  5924. else if (mp_count_bits(mod) != 2048) {
  5925. err = MP_READ_E;
  5926. }
  5927. else if (mp_iseven(mod)) {
  5928. err = MP_VAL;
  5929. }
  5930. #ifdef WOLFSSL_SP_SMALL_STACK
  5931. if (err == MP_OKAY) {
  5932. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 4, NULL, DYNAMIC_TYPE_DH);
  5933. if (b == NULL)
  5934. err = MEMORY_E;
  5935. }
  5936. #endif
  5937. if (err == MP_OKAY) {
  5938. e = b + 36 * 2;
  5939. m = e + 36;
  5940. r = b;
  5941. sp_2048_from_mp(b, 36, base);
  5942. sp_2048_from_mp(e, 36, exp);
  5943. sp_2048_from_mp(m, 36, mod);
  5944. err = sp_2048_mod_exp_36(r, b, e, expBits, m, 0);
  5945. }
  5946. if (err == MP_OKAY) {
  5947. err = sp_2048_to_mp(r, res);
  5948. }
  5949. #ifdef WOLFSSL_SP_SMALL_STACK
  5950. if (b != NULL)
  5951. #endif
  5952. {
  5953. /* only "e" is sensitive and needs zeroized */
  5954. if (e != NULL)
  5955. ForceZero(e, sizeof(sp_digit) * 36U);
  5956. #ifdef WOLFSSL_SP_SMALL_STACK
  5957. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  5958. #endif
  5959. }
  5960. return err;
  5961. #endif
  5962. }
  5963. #ifdef WOLFSSL_HAVE_SP_DH
  5964. #ifdef HAVE_FFDHE_2048
  5965. SP_NOINLINE static void sp_2048_lshift_36(sp_digit* r, const sp_digit* a,
  5966. byte n)
  5967. {
  5968. sp_int_digit s;
  5969. sp_int_digit t;
  5970. s = (sp_int_digit)a[35];
  5971. r[36] = s >> (57U - n);
  5972. s = (sp_int_digit)(a[35]); t = (sp_int_digit)(a[34]);
  5973. r[35] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  5974. s = (sp_int_digit)(a[34]); t = (sp_int_digit)(a[33]);
  5975. r[34] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  5976. s = (sp_int_digit)(a[33]); t = (sp_int_digit)(a[32]);
  5977. r[33] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  5978. s = (sp_int_digit)(a[32]); t = (sp_int_digit)(a[31]);
  5979. r[32] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  5980. s = (sp_int_digit)(a[31]); t = (sp_int_digit)(a[30]);
  5981. r[31] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  5982. s = (sp_int_digit)(a[30]); t = (sp_int_digit)(a[29]);
  5983. r[30] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  5984. s = (sp_int_digit)(a[29]); t = (sp_int_digit)(a[28]);
  5985. r[29] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  5986. s = (sp_int_digit)(a[28]); t = (sp_int_digit)(a[27]);
  5987. r[28] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  5988. s = (sp_int_digit)(a[27]); t = (sp_int_digit)(a[26]);
  5989. r[27] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  5990. s = (sp_int_digit)(a[26]); t = (sp_int_digit)(a[25]);
  5991. r[26] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  5992. s = (sp_int_digit)(a[25]); t = (sp_int_digit)(a[24]);
  5993. r[25] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  5994. s = (sp_int_digit)(a[24]); t = (sp_int_digit)(a[23]);
  5995. r[24] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  5996. s = (sp_int_digit)(a[23]); t = (sp_int_digit)(a[22]);
  5997. r[23] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  5998. s = (sp_int_digit)(a[22]); t = (sp_int_digit)(a[21]);
  5999. r[22] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6000. s = (sp_int_digit)(a[21]); t = (sp_int_digit)(a[20]);
  6001. r[21] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6002. s = (sp_int_digit)(a[20]); t = (sp_int_digit)(a[19]);
  6003. r[20] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6004. s = (sp_int_digit)(a[19]); t = (sp_int_digit)(a[18]);
  6005. r[19] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6006. s = (sp_int_digit)(a[18]); t = (sp_int_digit)(a[17]);
  6007. r[18] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6008. s = (sp_int_digit)(a[17]); t = (sp_int_digit)(a[16]);
  6009. r[17] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6010. s = (sp_int_digit)(a[16]); t = (sp_int_digit)(a[15]);
  6011. r[16] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6012. s = (sp_int_digit)(a[15]); t = (sp_int_digit)(a[14]);
  6013. r[15] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6014. s = (sp_int_digit)(a[14]); t = (sp_int_digit)(a[13]);
  6015. r[14] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6016. s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);
  6017. r[13] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6018. s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);
  6019. r[12] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6020. s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);
  6021. r[11] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6022. s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);
  6023. r[10] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6024. s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);
  6025. r[9] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6026. s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);
  6027. r[8] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6028. s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);
  6029. r[7] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6030. s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);
  6031. r[6] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6032. s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);
  6033. r[5] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6034. s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);
  6035. r[4] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6036. s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);
  6037. r[3] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6038. s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);
  6039. r[2] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6040. s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);
  6041. r[1] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  6042. r[0] = (a[0] << n) & 0x1ffffffffffffffL;
  6043. }
  6044. /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
  6045. *
  6046. * r A single precision number that is the result of the operation.
  6047. * e A single precision number that is the exponent.
  6048. * bits The number of bits in the exponent.
  6049. * m A single precision number that is the modulus.
  6050. * returns 0 on success.
  6051. * returns MEMORY_E on dynamic memory allocation failure.
  6052. * returns MP_VAL when base is even.
  6053. */
  6054. static int sp_2048_mod_exp_2_36(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)
  6055. {
  6056. #ifdef WOLFSSL_SP_SMALL_STACK
  6057. sp_digit* td = NULL;
  6058. #else
  6059. sp_digit td[109];
  6060. #endif
  6061. sp_digit* norm = NULL;
  6062. sp_digit* tmp = NULL;
  6063. sp_digit mp = 1;
  6064. sp_digit n;
  6065. sp_digit o;
  6066. int i;
  6067. int c;
  6068. byte y;
  6069. int err = MP_OKAY;
  6070. if (bits == 0) {
  6071. err = MP_VAL;
  6072. }
  6073. #ifdef WOLFSSL_SP_SMALL_STACK
  6074. if (err == MP_OKAY) {
  6075. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 109, NULL,
  6076. DYNAMIC_TYPE_TMP_BUFFER);
  6077. if (td == NULL)
  6078. err = MEMORY_E;
  6079. }
  6080. #endif
  6081. if (err == MP_OKAY) {
  6082. norm = td;
  6083. tmp = td + 72;
  6084. XMEMSET(td, 0, sizeof(sp_digit) * 109);
  6085. sp_2048_mont_setup(m, &mp);
  6086. sp_2048_mont_norm_36(norm, m);
  6087. bits = ((bits + 4) / 5) * 5;
  6088. i = ((bits + 56) / 57) - 1;
  6089. c = bits % 57;
  6090. if (c == 0) {
  6091. c = 57;
  6092. }
  6093. if (i < 36) {
  6094. n = e[i--] << (64 - c);
  6095. }
  6096. else {
  6097. n = 0;
  6098. i--;
  6099. }
  6100. if (c < 5) {
  6101. n |= e[i--] << (7 - c);
  6102. c += 57;
  6103. }
  6104. y = (int)((n >> 59) & 0x1f);
  6105. n <<= 5;
  6106. c -= 5;
  6107. sp_2048_lshift_36(r, norm, (byte)y);
  6108. while ((i >= 0) || (c >= 5)) {
  6109. if (c >= 5) {
  6110. y = (byte)((n >> 59) & 0x1f);
  6111. n <<= 5;
  6112. c -= 5;
  6113. }
  6114. else if (c == 0) {
  6115. n = e[i--] << 7;
  6116. y = (byte)((n >> 59) & 0x1f);
  6117. n <<= 5;
  6118. c = 52;
  6119. }
  6120. else {
  6121. y = (byte)((n >> 59) & 0x1f);
  6122. n = e[i--] << 7;
  6123. c = 5 - c;
  6124. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  6125. n <<= c;
  6126. c = 57 - c;
  6127. }
  6128. sp_2048_mont_sqr_36(r, r, m, mp);
  6129. sp_2048_mont_sqr_36(r, r, m, mp);
  6130. sp_2048_mont_sqr_36(r, r, m, mp);
  6131. sp_2048_mont_sqr_36(r, r, m, mp);
  6132. sp_2048_mont_sqr_36(r, r, m, mp);
  6133. sp_2048_lshift_36(r, r, (byte)y);
  6134. sp_2048_mul_d_36(tmp, norm, (r[36] << 4) + (r[35] >> 53));
  6135. r[36] = 0;
  6136. r[35] &= 0x1fffffffffffffL;
  6137. (void)sp_2048_add_36(r, r, tmp);
  6138. sp_2048_norm_36(r);
  6139. o = sp_2048_cmp_36(r, m);
  6140. sp_2048_cond_sub_36(r, r, m, ~(o >> 63));
  6141. }
  6142. sp_2048_mont_reduce_36(r, m, mp);
  6143. n = sp_2048_cmp_36(r, m);
  6144. sp_2048_cond_sub_36(r, r, m, ~(n >> 63));
  6145. }
  6146. #ifdef WOLFSSL_SP_SMALL_STACK
  6147. if (td != NULL)
  6148. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  6149. #endif
  6150. return err;
  6151. }
  6152. #endif /* HAVE_FFDHE_2048 */
  6153. /* Perform the modular exponentiation for Diffie-Hellman.
  6154. *
  6155. * base Base.
  6156. * exp Array of bytes that is the exponent.
  6157. * expLen Length of data, in bytes, in exponent.
  6158. * mod Modulus.
  6159. * out Buffer to hold big-endian bytes of exponentiation result.
  6160. * Must be at least 256 bytes long.
  6161. * outLen Length, in bytes, of exponentiation result.
  6162. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  6163. * and MEMORY_E if memory allocation fails.
  6164. */
  6165. int sp_DhExp_2048(const mp_int* base, const byte* exp, word32 expLen,
  6166. const mp_int* mod, byte* out, word32* outLen)
  6167. {
  6168. #ifdef WOLFSSL_SP_SMALL_STACK
  6169. sp_digit* b = NULL;
  6170. #else
  6171. sp_digit b[36 * 4];
  6172. #endif
  6173. sp_digit* e = NULL;
  6174. sp_digit* m = NULL;
  6175. sp_digit* r = NULL;
  6176. word32 i;
  6177. int err = MP_OKAY;
  6178. if (mp_count_bits(base) > 2048) {
  6179. err = MP_READ_E;
  6180. }
  6181. else if (expLen > 256U) {
  6182. err = MP_READ_E;
  6183. }
  6184. else if (mp_count_bits(mod) != 2048) {
  6185. err = MP_READ_E;
  6186. }
  6187. else if (mp_iseven(mod)) {
  6188. err = MP_VAL;
  6189. }
  6190. #ifdef WOLFSSL_SP_SMALL_STACK
  6191. if (err == MP_OKAY) {
  6192. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 4, NULL,
  6193. DYNAMIC_TYPE_DH);
  6194. if (b == NULL)
  6195. err = MEMORY_E;
  6196. }
  6197. #endif
  6198. if (err == MP_OKAY) {
  6199. e = b + 36 * 2;
  6200. m = e + 36;
  6201. r = b;
  6202. sp_2048_from_mp(b, 36, base);
  6203. sp_2048_from_bin(e, 36, exp, expLen);
  6204. sp_2048_from_mp(m, 36, mod);
  6205. #ifdef HAVE_FFDHE_2048
  6206. if (base->used == 1 && base->dp[0] == 2U &&
  6207. (m[35] >> 21) == 0xffffffffL) {
  6208. err = sp_2048_mod_exp_2_36(r, e, expLen * 8U, m);
  6209. }
  6210. else {
  6211. #endif
  6212. err = sp_2048_mod_exp_36(r, b, e, expLen * 8U, m, 0);
  6213. #ifdef HAVE_FFDHE_2048
  6214. }
  6215. #endif
  6216. }
  6217. if (err == MP_OKAY) {
  6218. sp_2048_to_bin_36(r, out);
  6219. *outLen = 256;
  6220. for (i=0; i<256U && out[i] == 0U; i++) {
  6221. /* Search for first non-zero. */
  6222. }
  6223. *outLen -= i;
  6224. XMEMMOVE(out, out + i, *outLen);
  6225. }
  6226. #ifdef WOLFSSL_SP_SMALL_STACK
  6227. if (b != NULL)
  6228. #endif
  6229. {
  6230. /* only "e" is sensitive and needs zeroized */
  6231. if (e != NULL)
  6232. ForceZero(e, sizeof(sp_digit) * 36U);
  6233. #ifdef WOLFSSL_SP_SMALL_STACK
  6234. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  6235. #endif
  6236. }
  6237. return err;
  6238. }
  6239. #endif /* WOLFSSL_HAVE_SP_DH */
  6240. /* Perform the modular exponentiation for Diffie-Hellman.
  6241. *
  6242. * base Base. MP integer.
  6243. * exp Exponent. MP integer.
  6244. * mod Modulus. MP integer.
  6245. * res Result. MP integer.
  6246. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  6247. * and MEMORY_E if memory allocation fails.
  6248. */
  6249. int sp_ModExp_1024(const mp_int* base, const mp_int* exp, const mp_int* mod,
  6250. mp_int* res)
  6251. {
  6252. #ifdef WOLFSSL_SP_SMALL
  6253. int err = MP_OKAY;
  6254. #ifdef WOLFSSL_SP_SMALL_STACK
  6255. sp_digit* b = NULL;
  6256. #else
  6257. sp_digit b[18 * 4];
  6258. #endif
  6259. sp_digit* e = NULL;
  6260. sp_digit* m = NULL;
  6261. sp_digit* r = NULL;
  6262. int expBits = mp_count_bits(exp);
  6263. if (mp_count_bits(base) > 1024) {
  6264. err = MP_READ_E;
  6265. }
  6266. else if (expBits > 1024) {
  6267. err = MP_READ_E;
  6268. }
  6269. else if (mp_count_bits(mod) != 1024) {
  6270. err = MP_READ_E;
  6271. }
  6272. else if (mp_iseven(mod)) {
  6273. err = MP_VAL;
  6274. }
  6275. #ifdef WOLFSSL_SP_SMALL_STACK
  6276. if (err == MP_OKAY) {
  6277. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 4, NULL,
  6278. DYNAMIC_TYPE_DH);
  6279. if (b == NULL)
  6280. err = MEMORY_E;
  6281. }
  6282. #endif
  6283. if (err == MP_OKAY) {
  6284. e = b + 18 * 2;
  6285. m = e + 18;
  6286. r = b;
  6287. sp_2048_from_mp(b, 18, base);
  6288. sp_2048_from_mp(e, 18, exp);
  6289. sp_2048_from_mp(m, 18, mod);
  6290. err = sp_2048_mod_exp_18(r, b, e, mp_count_bits(exp), m, 0);
  6291. }
  6292. if (err == MP_OKAY) {
  6293. XMEMSET(r + 18, 0, sizeof(*r) * 18U);
  6294. err = sp_2048_to_mp(r, res);
  6295. }
  6296. #ifdef WOLFSSL_SP_SMALL_STACK
  6297. if (b != NULL)
  6298. #endif
  6299. {
  6300. /* only "e" is sensitive and needs zeroized */
  6301. if (e != NULL)
  6302. ForceZero(e, sizeof(sp_digit) * 36U);
  6303. #ifdef WOLFSSL_SP_SMALL_STACK
  6304. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  6305. #endif
  6306. }
  6307. return err;
  6308. #else
  6309. #ifdef WOLFSSL_SP_SMALL_STACK
  6310. sp_digit* b = NULL;
  6311. #else
  6312. sp_digit b[18 * 4];
  6313. #endif
  6314. sp_digit* e = NULL;
  6315. sp_digit* m = NULL;
  6316. sp_digit* r = NULL;
  6317. int err = MP_OKAY;
  6318. int expBits = mp_count_bits(exp);
  6319. if (mp_count_bits(base) > 1024) {
  6320. err = MP_READ_E;
  6321. }
  6322. else if (expBits > 1024) {
  6323. err = MP_READ_E;
  6324. }
  6325. else if (mp_count_bits(mod) != 1024) {
  6326. err = MP_READ_E;
  6327. }
  6328. else if (mp_iseven(mod)) {
  6329. err = MP_VAL;
  6330. }
  6331. #ifdef WOLFSSL_SP_SMALL_STACK
  6332. if (err == MP_OKAY) {
  6333. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 4, NULL, DYNAMIC_TYPE_DH);
  6334. if (b == NULL)
  6335. err = MEMORY_E;
  6336. }
  6337. #endif
  6338. if (err == MP_OKAY) {
  6339. e = b + 18 * 2;
  6340. m = e + 18;
  6341. r = b;
  6342. sp_2048_from_mp(b, 18, base);
  6343. sp_2048_from_mp(e, 18, exp);
  6344. sp_2048_from_mp(m, 18, mod);
  6345. err = sp_2048_mod_exp_18(r, b, e, expBits, m, 0);
  6346. }
  6347. if (err == MP_OKAY) {
  6348. XMEMSET(r + 18, 0, sizeof(*r) * 18U);
  6349. err = sp_2048_to_mp(r, res);
  6350. }
  6351. #ifdef WOLFSSL_SP_SMALL_STACK
  6352. if (b != NULL)
  6353. #endif
  6354. {
  6355. /* only "e" is sensitive and needs zeroized */
  6356. if (e != NULL)
  6357. ForceZero(e, sizeof(sp_digit) * 36U);
  6358. #ifdef WOLFSSL_SP_SMALL_STACK
  6359. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  6360. #endif
  6361. }
  6362. return err;
  6363. #endif
  6364. }
  6365. #endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */
  6366. #endif /* WOLFSSL_SP_SMALL */
  6367. #endif /* !WOLFSSL_SP_NO_2048 */
  6368. #ifndef WOLFSSL_SP_NO_3072
  6369. #ifdef WOLFSSL_SP_SMALL
  6370. /* Read big endian unsigned byte array into r.
  6371. *
  6372. * r A single precision integer.
  6373. * size Maximum number of bytes to convert
  6374. * a Byte array.
  6375. * n Number of bytes in array to read.
  6376. */
  6377. static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n)
  6378. {
  6379. int i;
  6380. int j = 0;
  6381. word32 s = 0;
  6382. r[0] = 0;
  6383. for (i = n-1; i >= 0; i--) {
  6384. r[j] |= (((sp_digit)a[i]) << s);
  6385. if (s >= 52U) {
  6386. r[j] &= 0xfffffffffffffffL;
  6387. s = 60U - s;
  6388. if (j + 1 >= size) {
  6389. break;
  6390. }
  6391. r[++j] = (sp_digit)a[i] >> s;
  6392. s = 8U - s;
  6393. }
  6394. else {
  6395. s += 8U;
  6396. }
  6397. }
  6398. for (j++; j < size; j++) {
  6399. r[j] = 0;
  6400. }
  6401. }
  6402. /* Convert an mp_int to an array of sp_digit.
  6403. *
  6404. * r A single precision integer.
  6405. * size Maximum number of bytes to convert
  6406. * a A multi-precision integer.
  6407. */
  6408. static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a)
  6409. {
  6410. #if DIGIT_BIT == 60
  6411. int i;
  6412. sp_digit j = (sp_digit)0 - (sp_digit)a->used;
  6413. int o = 0;
  6414. for (i = 0; i < size; i++) {
  6415. sp_digit mask = (sp_digit)0 - (j >> 59);
  6416. r[i] = a->dp[o] & mask;
  6417. j++;
  6418. o += (int)(j >> 59);
  6419. }
  6420. #elif DIGIT_BIT > 60
  6421. unsigned int i;
  6422. int j = 0;
  6423. word32 s = 0;
  6424. r[0] = 0;
  6425. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  6426. r[j] |= ((sp_digit)a->dp[i] << s);
  6427. r[j] &= 0xfffffffffffffffL;
  6428. s = 60U - s;
  6429. if (j + 1 >= size) {
  6430. break;
  6431. }
  6432. /* lint allow cast of mismatch word32 and mp_digit */
  6433. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  6434. while ((s + 60U) <= (word32)DIGIT_BIT) {
  6435. s += 60U;
  6436. r[j] &= 0xfffffffffffffffL;
  6437. if (j + 1 >= size) {
  6438. break;
  6439. }
  6440. if (s < (word32)DIGIT_BIT) {
  6441. /* lint allow cast of mismatch word32 and mp_digit */
  6442. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  6443. }
  6444. else {
  6445. r[++j] = (sp_digit)0;
  6446. }
  6447. }
  6448. s = (word32)DIGIT_BIT - s;
  6449. }
  6450. for (j++; j < size; j++) {
  6451. r[j] = 0;
  6452. }
  6453. #else
  6454. unsigned int i;
  6455. int j = 0;
  6456. int s = 0;
  6457. r[0] = 0;
  6458. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  6459. r[j] |= ((sp_digit)a->dp[i]) << s;
  6460. if (s + DIGIT_BIT >= 60) {
  6461. r[j] &= 0xfffffffffffffffL;
  6462. if (j + 1 >= size) {
  6463. break;
  6464. }
  6465. s = 60 - s;
  6466. if (s == DIGIT_BIT) {
  6467. r[++j] = 0;
  6468. s = 0;
  6469. }
  6470. else {
  6471. r[++j] = a->dp[i] >> s;
  6472. s = DIGIT_BIT - s;
  6473. }
  6474. }
  6475. else {
  6476. s += DIGIT_BIT;
  6477. }
  6478. }
  6479. for (j++; j < size; j++) {
  6480. r[j] = 0;
  6481. }
  6482. #endif
  6483. }
  6484. /* Write r as big endian to byte array.
  6485. * Fixed length number of bytes written: 384
  6486. *
  6487. * r A single precision integer.
  6488. * a Byte array.
  6489. */
  6490. static void sp_3072_to_bin_52(sp_digit* r, byte* a)
  6491. {
  6492. int i;
  6493. int j;
  6494. int s = 0;
  6495. int b;
  6496. for (i=0; i<51; i++) {
  6497. r[i+1] += r[i] >> 60;
  6498. r[i] &= 0xfffffffffffffffL;
  6499. }
  6500. j = 3079 / 8 - 1;
  6501. a[j] = 0;
  6502. for (i=0; i<52 && j>=0; i++) {
  6503. b = 0;
  6504. /* lint allow cast of mismatch sp_digit and int */
  6505. a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
  6506. b += 8 - s;
  6507. if (j < 0) {
  6508. break;
  6509. }
  6510. while (b < 60) {
  6511. a[j--] = (byte)(r[i] >> b);
  6512. b += 8;
  6513. if (j < 0) {
  6514. break;
  6515. }
  6516. }
  6517. s = 8 - (b - 60);
  6518. if (j >= 0) {
  6519. a[j] = 0;
  6520. }
  6521. if (s != 0) {
  6522. j++;
  6523. }
  6524. }
  6525. }
  6526. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  6527. /* Normalize the values in each word to 60 bits.
  6528. *
  6529. * a Array of sp_digit to normalize.
  6530. */
  6531. static void sp_3072_norm_26(sp_digit* a)
  6532. {
  6533. int i;
  6534. for (i = 0; i < 25; i++) {
  6535. a[i+1] += a[i] >> 60;
  6536. a[i] &= 0xfffffffffffffffL;
  6537. }
  6538. }
  6539. #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
  6540. /* Normalize the values in each word to 60 bits.
  6541. *
  6542. * a Array of sp_digit to normalize.
  6543. */
  6544. static void sp_3072_norm_52(sp_digit* a)
  6545. {
  6546. int i;
  6547. for (i = 0; i < 51; i++) {
  6548. a[i+1] += a[i] >> 60;
  6549. a[i] &= 0xfffffffffffffffL;
  6550. }
  6551. }
  6552. /* Multiply a and b into r. (r = a * b)
  6553. *
  6554. * r A single precision integer.
  6555. * a A single precision integer.
  6556. * b A single precision integer.
  6557. */
  6558. SP_NOINLINE static void sp_3072_mul_52(sp_digit* r, const sp_digit* a,
  6559. const sp_digit* b)
  6560. {
  6561. int i;
  6562. int imax;
  6563. int k;
  6564. sp_uint128 c;
  6565. sp_uint128 lo;
  6566. c = ((sp_uint128)a[51]) * b[51];
  6567. r[103] = (sp_digit)(c >> 60);
  6568. c &= 0xfffffffffffffffL;
  6569. for (k = 101; k >= 0; k--) {
  6570. if (k >= 52) {
  6571. i = k - 51;
  6572. imax = 51;
  6573. }
  6574. else {
  6575. i = 0;
  6576. imax = k;
  6577. }
  6578. lo = 0;
  6579. for (; i <= imax; i++) {
  6580. lo += ((sp_uint128)a[i]) * b[k - i];
  6581. }
  6582. c += lo >> 60;
  6583. r[k + 2] += (sp_digit)(c >> 60);
  6584. r[k + 1] = (sp_digit)(c & 0xfffffffffffffffL);
  6585. c = lo & 0xfffffffffffffffL;
  6586. }
  6587. r[0] = (sp_digit)c;
  6588. }
  6589. /* Square a and put result in r. (r = a * a)
  6590. *
  6591. * r A single precision integer.
  6592. * a A single precision integer.
  6593. */
  6594. SP_NOINLINE static void sp_3072_sqr_52(sp_digit* r, const sp_digit* a)
  6595. {
  6596. int i;
  6597. int imax;
  6598. int k;
  6599. sp_uint128 c;
  6600. sp_uint128 t;
  6601. c = ((sp_uint128)a[51]) * a[51];
  6602. r[103] = (sp_digit)(c >> 60);
  6603. c = (c & 0xfffffffffffffffL) << 60;
  6604. for (k = 101; k >= 0; k--) {
  6605. i = (k + 1) / 2;
  6606. if ((k & 1) == 0) {
  6607. c += ((sp_uint128)a[i]) * a[i];
  6608. i++;
  6609. }
  6610. if (k < 51) {
  6611. imax = k;
  6612. }
  6613. else {
  6614. imax = 51;
  6615. }
  6616. t = 0;
  6617. for (; i <= imax; i++) {
  6618. t += ((sp_uint128)a[i]) * a[k - i];
  6619. }
  6620. c += t * 2;
  6621. r[k + 2] += (sp_digit) (c >> 120);
  6622. r[k + 1] = (sp_digit)((c >> 60) & 0xfffffffffffffffL);
  6623. c = (c & 0xfffffffffffffffL) << 60;
  6624. }
  6625. r[0] = (sp_digit)(c >> 60);
  6626. }
  6627. /* Calculate the bottom digit of -1/a mod 2^n.
  6628. *
  6629. * a A single precision number.
  6630. * rho Bottom word of inverse.
  6631. */
  6632. static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho)
  6633. {
  6634. sp_digit x;
  6635. sp_digit b;
  6636. b = a[0];
  6637. x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
  6638. x *= 2 - b * x; /* here x*a==1 mod 2**8 */
  6639. x *= 2 - b * x; /* here x*a==1 mod 2**16 */
  6640. x *= 2 - b * x; /* here x*a==1 mod 2**32 */
  6641. x *= 2 - b * x; /* here x*a==1 mod 2**64 */
  6642. x &= 0xfffffffffffffffL;
  6643. /* rho = -1/m mod b */
  6644. *rho = ((sp_digit)1 << 60) - x;
  6645. }
  6646. /* Multiply a by scalar b into r. (r = a * b)
  6647. *
  6648. * r A single precision integer.
  6649. * a A single precision integer.
  6650. * b A scalar.
  6651. */
  6652. SP_NOINLINE static void sp_3072_mul_d_52(sp_digit* r, const sp_digit* a,
  6653. sp_digit b)
  6654. {
  6655. sp_int128 tb = b;
  6656. sp_int128 t = 0;
  6657. int i;
  6658. for (i = 0; i < 52; i++) {
  6659. t += tb * a[i];
  6660. r[i] = (sp_digit)(t & 0xfffffffffffffffL);
  6661. t >>= 60;
  6662. }
  6663. r[52] = (sp_digit)t;
  6664. }
  6665. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  6666. /* Sub b from a into r. (r = a - b)
  6667. *
  6668. * r A single precision integer.
  6669. * a A single precision integer.
  6670. * b A single precision integer.
  6671. */
  6672. SP_NOINLINE static int sp_3072_sub_26(sp_digit* r, const sp_digit* a,
  6673. const sp_digit* b)
  6674. {
  6675. int i;
  6676. for (i = 0; i < 26; i++) {
  6677. r[i] = a[i] - b[i];
  6678. }
  6679. return 0;
  6680. }
  6681. /* r = 2^n mod m where n is the number of bits to reduce by.
  6682. * Given m must be 3072 bits, just need to subtract.
  6683. *
  6684. * r A single precision number.
  6685. * m A single precision number.
  6686. */
  6687. static void sp_3072_mont_norm_26(sp_digit* r, const sp_digit* m)
  6688. {
  6689. /* Set r = 2^n - 1. */
  6690. int i;
  6691. for (i=0; i<25; i++) {
  6692. r[i] = 0xfffffffffffffffL;
  6693. }
  6694. r[25] = 0xfffffffffL;
  6695. /* r = (2^n - 1) mod n */
  6696. (void)sp_3072_sub_26(r, r, m);
  6697. /* Add one so r = 2^n mod m */
  6698. r[0] += 1;
  6699. }
  6700. /* Compare a with b in constant time.
  6701. *
  6702. * a A single precision integer.
  6703. * b A single precision integer.
  6704. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  6705. * respectively.
  6706. */
  6707. static sp_digit sp_3072_cmp_26(const sp_digit* a, const sp_digit* b)
  6708. {
  6709. sp_digit r = 0;
  6710. int i;
  6711. for (i=25; i>=0; i--) {
  6712. r |= (a[i] - b[i]) & ~(((sp_digit)0 - r) >> 59);
  6713. }
  6714. return r;
  6715. }
  6716. /* Conditionally subtract b from a using the mask m.
  6717. * m is -1 to subtract and 0 when not.
  6718. *
  6719. * r A single precision number representing condition subtract result.
  6720. * a A single precision number to subtract from.
  6721. * b A single precision number to subtract.
  6722. * m Mask value to apply.
  6723. */
  6724. static void sp_3072_cond_sub_26(sp_digit* r, const sp_digit* a,
  6725. const sp_digit* b, const sp_digit m)
  6726. {
  6727. int i;
  6728. for (i = 0; i < 26; i++) {
  6729. r[i] = a[i] - (b[i] & m);
  6730. }
  6731. }
  6732. /* Mul a by scalar b and add into r. (r += a * b)
  6733. *
  6734. * r A single precision integer.
  6735. * a A single precision integer.
  6736. * b A scalar.
  6737. */
  6738. SP_NOINLINE static void sp_3072_mul_add_26(sp_digit* r, const sp_digit* a,
  6739. const sp_digit b)
  6740. {
  6741. sp_int128 tb = b;
  6742. sp_int128 t[4];
  6743. int i;
  6744. t[0] = 0;
  6745. for (i = 0; i < 24; i += 4) {
  6746. t[0] += (tb * a[i+0]) + r[i+0];
  6747. t[1] = (tb * a[i+1]) + r[i+1];
  6748. t[2] = (tb * a[i+2]) + r[i+2];
  6749. t[3] = (tb * a[i+3]) + r[i+3];
  6750. r[i+0] = t[0] & 0xfffffffffffffffL;
  6751. t[1] += t[0] >> 60;
  6752. r[i+1] = t[1] & 0xfffffffffffffffL;
  6753. t[2] += t[1] >> 60;
  6754. r[i+2] = t[2] & 0xfffffffffffffffL;
  6755. t[3] += t[2] >> 60;
  6756. r[i+3] = t[3] & 0xfffffffffffffffL;
  6757. t[0] = t[3] >> 60;
  6758. }
  6759. t[0] += (tb * a[24]) + r[24];
  6760. t[1] = (tb * a[25]) + r[25];
  6761. r[24] = t[0] & 0xfffffffffffffffL;
  6762. t[1] += t[0] >> 60;
  6763. r[25] = t[1] & 0xfffffffffffffffL;
  6764. r[26] += (sp_digit)(t[1] >> 60);
  6765. }
  6766. /* Shift the result in the high 1536 bits down to the bottom.
  6767. *
  6768. * r A single precision number.
  6769. * a A single precision number.
  6770. */
  6771. static void sp_3072_mont_shift_26(sp_digit* r, const sp_digit* a)
  6772. {
  6773. int i;
  6774. sp_int128 n = a[25] >> 36;
  6775. n += ((sp_int128)a[26]) << 24;
  6776. for (i = 0; i < 25; i++) {
  6777. r[i] = n & 0xfffffffffffffffL;
  6778. n >>= 60;
  6779. n += ((sp_int128)a[27 + i]) << 24;
  6780. }
  6781. r[25] = (sp_digit)n;
  6782. XMEMSET(&r[26], 0, sizeof(*r) * 26U);
  6783. }
  6784. /* Reduce the number back to 3072 bits using Montgomery reduction.
  6785. *
  6786. * a A single precision number to reduce in place.
  6787. * m The single precision number representing the modulus.
  6788. * mp The digit representing the negative inverse of m mod 2^n.
  6789. */
  6790. static void sp_3072_mont_reduce_26(sp_digit* a, const sp_digit* m, sp_digit mp)
  6791. {
  6792. int i;
  6793. sp_digit mu;
  6794. sp_digit over;
  6795. sp_3072_norm_26(a + 26);
  6796. for (i=0; i<25; i++) {
  6797. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0xfffffffffffffffL;
  6798. sp_3072_mul_add_26(a+i, m, mu);
  6799. a[i+1] += a[i] >> 60;
  6800. }
  6801. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0xfffffffffL;
  6802. sp_3072_mul_add_26(a+i, m, mu);
  6803. a[i+1] += a[i] >> 60;
  6804. a[i] &= 0xfffffffffffffffL;
  6805. sp_3072_mont_shift_26(a, a);
  6806. over = a[25] - m[25];
  6807. sp_3072_cond_sub_26(a, a, m, ~((over - 1) >> 63));
  6808. sp_3072_norm_26(a);
  6809. }
  6810. /* Multiply a and b into r. (r = a * b)
  6811. *
  6812. * r A single precision integer.
  6813. * a A single precision integer.
  6814. * b A single precision integer.
  6815. */
  6816. SP_NOINLINE static void sp_3072_mul_26(sp_digit* r, const sp_digit* a,
  6817. const sp_digit* b)
  6818. {
  6819. int i;
  6820. int imax;
  6821. int k;
  6822. sp_uint128 c;
  6823. sp_uint128 lo;
  6824. c = ((sp_uint128)a[25]) * b[25];
  6825. r[51] = (sp_digit)(c >> 60);
  6826. c &= 0xfffffffffffffffL;
  6827. for (k = 49; k >= 0; k--) {
  6828. if (k >= 26) {
  6829. i = k - 25;
  6830. imax = 25;
  6831. }
  6832. else {
  6833. i = 0;
  6834. imax = k;
  6835. }
  6836. lo = 0;
  6837. for (; i <= imax; i++) {
  6838. lo += ((sp_uint128)a[i]) * b[k - i];
  6839. }
  6840. c += lo >> 60;
  6841. r[k + 2] += (sp_digit)(c >> 60);
  6842. r[k + 1] = (sp_digit)(c & 0xfffffffffffffffL);
  6843. c = lo & 0xfffffffffffffffL;
  6844. }
  6845. r[0] = (sp_digit)c;
  6846. }
  6847. /* Multiply two Montgomery form numbers mod the modulus (prime).
  6848. * (r = a * b mod m)
  6849. *
  6850. * r Result of multiplication.
  6851. * a First number to multiply in Montgomery form.
  6852. * b Second number to multiply in Montgomery form.
  6853. * m Modulus (prime).
  6854. * mp Montgomery multiplier.
  6855. */
  6856. SP_NOINLINE static void sp_3072_mont_mul_26(sp_digit* r, const sp_digit* a,
  6857. const sp_digit* b, const sp_digit* m, sp_digit mp)
  6858. {
  6859. sp_3072_mul_26(r, a, b);
  6860. sp_3072_mont_reduce_26(r, m, mp);
  6861. }
  6862. /* Square a and put result in r. (r = a * a)
  6863. *
  6864. * r A single precision integer.
  6865. * a A single precision integer.
  6866. */
  6867. SP_NOINLINE static void sp_3072_sqr_26(sp_digit* r, const sp_digit* a)
  6868. {
  6869. int i;
  6870. int imax;
  6871. int k;
  6872. sp_uint128 c;
  6873. sp_uint128 t;
  6874. c = ((sp_uint128)a[25]) * a[25];
  6875. r[51] = (sp_digit)(c >> 60);
  6876. c = (c & 0xfffffffffffffffL) << 60;
  6877. for (k = 49; k >= 0; k--) {
  6878. i = (k + 1) / 2;
  6879. if ((k & 1) == 0) {
  6880. c += ((sp_uint128)a[i]) * a[i];
  6881. i++;
  6882. }
  6883. if (k < 25) {
  6884. imax = k;
  6885. }
  6886. else {
  6887. imax = 25;
  6888. }
  6889. t = 0;
  6890. for (; i <= imax; i++) {
  6891. t += ((sp_uint128)a[i]) * a[k - i];
  6892. }
  6893. c += t * 2;
  6894. r[k + 2] += (sp_digit) (c >> 120);
  6895. r[k + 1] = (sp_digit)((c >> 60) & 0xfffffffffffffffL);
  6896. c = (c & 0xfffffffffffffffL) << 60;
  6897. }
  6898. r[0] = (sp_digit)(c >> 60);
  6899. }
  6900. /* Square the Montgomery form number. (r = a * a mod m)
  6901. *
  6902. * r Result of squaring.
  6903. * a Number to square in Montgomery form.
  6904. * m Modulus (prime).
  6905. * mp Montgomery multiplier.
  6906. */
  6907. SP_NOINLINE static void sp_3072_mont_sqr_26(sp_digit* r, const sp_digit* a,
  6908. const sp_digit* m, sp_digit mp)
  6909. {
  6910. sp_3072_sqr_26(r, a);
  6911. sp_3072_mont_reduce_26(r, m, mp);
  6912. }
  6913. /* Multiply a by scalar b into r. (r = a * b)
  6914. *
  6915. * r A single precision integer.
  6916. * a A single precision integer.
  6917. * b A scalar.
  6918. */
  6919. SP_NOINLINE static void sp_3072_mul_d_26(sp_digit* r, const sp_digit* a,
  6920. sp_digit b)
  6921. {
  6922. sp_int128 tb = b;
  6923. sp_int128 t = 0;
  6924. int i;
  6925. for (i = 0; i < 26; i++) {
  6926. t += tb * a[i];
  6927. r[i] = (sp_digit)(t & 0xfffffffffffffffL);
  6928. t >>= 60;
  6929. }
  6930. r[26] = (sp_digit)t;
  6931. }
  6932. #ifdef WOLFSSL_SP_SMALL
  6933. /* Conditionally add a and b using the mask m.
  6934. * m is -1 to add and 0 when not.
  6935. *
  6936. * r A single precision number representing conditional add result.
  6937. * a A single precision number to add with.
  6938. * b A single precision number to add.
  6939. * m Mask value to apply.
  6940. */
  6941. static void sp_3072_cond_add_26(sp_digit* r, const sp_digit* a,
  6942. const sp_digit* b, const sp_digit m)
  6943. {
  6944. int i;
  6945. for (i = 0; i < 26; i++) {
  6946. r[i] = a[i] + (b[i] & m);
  6947. }
  6948. }
  6949. #endif /* WOLFSSL_SP_SMALL */
  6950. /* Add b to a into r. (r = a + b)
  6951. *
  6952. * r A single precision integer.
  6953. * a A single precision integer.
  6954. * b A single precision integer.
  6955. */
  6956. SP_NOINLINE static int sp_3072_add_26(sp_digit* r, const sp_digit* a,
  6957. const sp_digit* b)
  6958. {
  6959. int i;
  6960. for (i = 0; i < 26; i++) {
  6961. r[i] = a[i] + b[i];
  6962. }
  6963. return 0;
  6964. }
  6965. SP_NOINLINE static void sp_3072_rshift_26(sp_digit* r, const sp_digit* a,
  6966. byte n)
  6967. {
  6968. int i;
  6969. for (i=0; i<25; i++) {
  6970. r[i] = ((a[i] >> n) | (a[i + 1] << (60 - n))) & 0xfffffffffffffffL;
  6971. }
  6972. r[25] = a[25] >> n;
  6973. }
  6974. static WC_INLINE sp_digit sp_3072_div_word_26(sp_digit d1, sp_digit d0,
  6975. sp_digit div)
  6976. {
  6977. #ifdef SP_USE_DIVTI3
  6978. sp_int128 d = ((sp_int128)d1 << 60) + d0;
  6979. return d / div;
  6980. #elif defined(__x86_64__) || defined(__i386__)
  6981. sp_int128 d = ((sp_int128)d1 << 60) + d0;
  6982. sp_uint64 lo = (sp_uint64)d;
  6983. sp_digit hi = (sp_digit)(d >> 64);
  6984. __asm__ __volatile__ (
  6985. "idiv %2"
  6986. : "+a" (lo)
  6987. : "d" (hi), "r" (div)
  6988. : "cc"
  6989. );
  6990. return (sp_digit)lo;
  6991. #elif !defined(__aarch64__) && !defined(SP_DIV_WORD_USE_DIV)
  6992. sp_int128 d = ((sp_int128)d1 << 60) + d0;
  6993. sp_digit dv = (div >> 1) + 1;
  6994. sp_digit t1 = (sp_digit)(d >> 60);
  6995. sp_digit t0 = (sp_digit)(d & 0xfffffffffffffffL);
  6996. sp_digit t2;
  6997. sp_digit sign;
  6998. sp_digit r;
  6999. int i;
  7000. sp_int128 m;
  7001. r = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  7002. t1 -= dv & (0 - r);
  7003. for (i = 58; i >= 1; i--) {
  7004. t1 += t1 + (((sp_uint64)t0 >> 59) & 1);
  7005. t0 <<= 1;
  7006. t2 = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  7007. r += r + t2;
  7008. t1 -= dv & (0 - t2);
  7009. t1 += t2;
  7010. }
  7011. r += r + 1;
  7012. m = d - ((sp_int128)r * div);
  7013. r += (sp_digit)(m >> 60);
  7014. m = d - ((sp_int128)r * div);
  7015. r += (sp_digit)(m >> 120) - (sp_digit)(d >> 120);
  7016. m = d - ((sp_int128)r * div);
  7017. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  7018. m *= sign;
  7019. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  7020. r += sign * t2;
  7021. m = d - ((sp_int128)r * div);
  7022. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  7023. m *= sign;
  7024. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  7025. r += sign * t2;
  7026. return r;
  7027. #else
  7028. sp_int128 d = ((sp_int128)d1 << 60) + d0;
  7029. sp_digit r = 0;
  7030. sp_digit t;
  7031. sp_digit dv = (div >> 29) + 1;
  7032. t = (sp_digit)(d >> 58);
  7033. t = (t / dv) << 29;
  7034. r += t;
  7035. d -= (sp_int128)t * div;
  7036. t = (sp_digit)(d >> 27);
  7037. t = t / (dv << 2);
  7038. r += t;
  7039. d -= (sp_int128)t * div;
  7040. t = (sp_digit)d;
  7041. t = t / div;
  7042. r += t;
  7043. d -= (sp_int128)t * div;
  7044. return r;
  7045. #endif
  7046. }
  7047. static WC_INLINE sp_digit sp_3072_word_div_word_26(sp_digit d, sp_digit div)
  7048. {
  7049. #if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \
  7050. defined(SP_DIV_WORD_USE_DIV)
  7051. return d / div;
  7052. #else
  7053. return (sp_digit)((sp_uint64)(div - d) >> 63);
  7054. #endif
  7055. }
  7056. /* Divide d in a and put remainder into r (m*d + r = a)
  7057. * m is not calculated as it is not needed at this time.
  7058. *
  7059. * Full implementation.
  7060. *
  7061. * a Number to be divided.
  7062. * d Number to divide with.
  7063. * m Multiplier result.
  7064. * r Remainder from the division.
  7065. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  7066. */
  7067. static int sp_3072_div_26(const sp_digit* a, const sp_digit* d,
  7068. const sp_digit* m, sp_digit* r)
  7069. {
  7070. int i;
  7071. #ifndef WOLFSSL_SP_DIV_64
  7072. #endif
  7073. sp_digit dv;
  7074. sp_digit r1;
  7075. #ifdef WOLFSSL_SP_SMALL_STACK
  7076. sp_digit* t1 = NULL;
  7077. #else
  7078. sp_digit t1[4 * 26 + 3];
  7079. #endif
  7080. sp_digit* t2 = NULL;
  7081. sp_digit* sd = NULL;
  7082. int err = MP_OKAY;
  7083. (void)m;
  7084. #ifdef WOLFSSL_SP_SMALL_STACK
  7085. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 26 + 3), NULL,
  7086. DYNAMIC_TYPE_TMP_BUFFER);
  7087. if (t1 == NULL)
  7088. err = MEMORY_E;
  7089. #endif
  7090. (void)m;
  7091. if (err == MP_OKAY) {
  7092. t2 = t1 + 52 + 1;
  7093. sd = t2 + 26 + 1;
  7094. sp_3072_mul_d_26(sd, d, (sp_digit)1 << 24);
  7095. sp_3072_mul_d_52(t1, a, (sp_digit)1 << 24);
  7096. dv = sd[25];
  7097. t1[26 + 26] += t1[26 + 26 - 1] >> 60;
  7098. t1[26 + 26 - 1] &= 0xfffffffffffffffL;
  7099. for (i=26; i>=0; i--) {
  7100. r1 = sp_3072_div_word_26(t1[26 + i], t1[26 + i - 1], dv);
  7101. sp_3072_mul_d_26(t2, sd, r1);
  7102. (void)sp_3072_sub_26(&t1[i], &t1[i], t2);
  7103. sp_3072_norm_26(&t1[i]);
  7104. t1[26 + i] -= t2[26];
  7105. t1[26 + i] += t1[26 + i - 1] >> 60;
  7106. t1[26 + i - 1] &= 0xfffffffffffffffL;
  7107. r1 = sp_3072_div_word_26(-t1[26 + i], -t1[26 + i - 1], dv);
  7108. r1 -= t1[26 + i];
  7109. sp_3072_mul_d_26(t2, sd, r1);
  7110. (void)sp_3072_add_26(&t1[i], &t1[i], t2);
  7111. t1[26 + i] += t1[26 + i - 1] >> 60;
  7112. t1[26 + i - 1] &= 0xfffffffffffffffL;
  7113. }
  7114. t1[26 - 1] += t1[26 - 2] >> 60;
  7115. t1[26 - 2] &= 0xfffffffffffffffL;
  7116. r1 = sp_3072_word_div_word_26(t1[26 - 1], dv);
  7117. sp_3072_mul_d_26(t2, sd, r1);
  7118. sp_3072_sub_26(t1, t1, t2);
  7119. XMEMCPY(r, t1, sizeof(*r) * 52U);
  7120. for (i=0; i<25; i++) {
  7121. r[i+1] += r[i] >> 60;
  7122. r[i] &= 0xfffffffffffffffL;
  7123. }
  7124. sp_3072_cond_add_26(r, r, sd, r[25] >> 63);
  7125. sp_3072_norm_26(r);
  7126. sp_3072_rshift_26(r, r, 24);
  7127. }
  7128. #ifdef WOLFSSL_SP_SMALL_STACK
  7129. if (t1 != NULL)
  7130. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  7131. #endif
  7132. return err;
  7133. }
  7134. /* Reduce a modulo m into r. (r = a mod m)
  7135. *
  7136. * r A single precision number that is the reduced result.
  7137. * a A single precision number that is to be reduced.
  7138. * m A single precision number that is the modulus to reduce with.
  7139. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  7140. */
  7141. static int sp_3072_mod_26(sp_digit* r, const sp_digit* a, const sp_digit* m)
  7142. {
  7143. return sp_3072_div_26(a, m, NULL, r);
  7144. }
  7145. /* Modular exponentiate a to the e mod m. (r = a^e mod m)
  7146. *
  7147. * r A single precision number that is the result of the operation.
  7148. * a A single precision number being exponentiated.
  7149. * e A single precision number that is the exponent.
  7150. * bits The number of bits in the exponent.
  7151. * m A single precision number that is the modulus.
  7152. * returns 0 on success.
  7153. * returns MEMORY_E on dynamic memory allocation failure.
  7154. * returns MP_VAL when base is even or exponent is 0.
  7155. */
  7156. static int sp_3072_mod_exp_26(sp_digit* r, const sp_digit* a, const sp_digit* e,
  7157. int bits, const sp_digit* m, int reduceA)
  7158. {
  7159. #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
  7160. #ifdef WOLFSSL_SP_SMALL_STACK
  7161. sp_digit* td = NULL;
  7162. #else
  7163. sp_digit td[3 * 52];
  7164. #endif
  7165. sp_digit* t[3] = {0, 0, 0};
  7166. sp_digit* norm = NULL;
  7167. sp_digit mp = 1;
  7168. sp_digit n;
  7169. int i;
  7170. int c;
  7171. byte y;
  7172. int err = MP_OKAY;
  7173. if (bits == 0) {
  7174. err = MP_VAL;
  7175. }
  7176. #ifdef WOLFSSL_SP_SMALL_STACK
  7177. if (err == MP_OKAY) {
  7178. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 26 * 2, NULL,
  7179. DYNAMIC_TYPE_TMP_BUFFER);
  7180. if (td == NULL)
  7181. err = MEMORY_E;
  7182. }
  7183. #endif
  7184. if (err == MP_OKAY) {
  7185. norm = td;
  7186. for (i=0; i<3; i++) {
  7187. t[i] = td + (i * 26 * 2);
  7188. XMEMSET(t[i], 0, sizeof(sp_digit) * 26U * 2U);
  7189. }
  7190. sp_3072_mont_setup(m, &mp);
  7191. sp_3072_mont_norm_26(norm, m);
  7192. if (reduceA != 0) {
  7193. err = sp_3072_mod_26(t[1], a, m);
  7194. }
  7195. else {
  7196. XMEMCPY(t[1], a, sizeof(sp_digit) * 26U);
  7197. }
  7198. }
  7199. if (err == MP_OKAY) {
  7200. sp_3072_mul_26(t[1], t[1], norm);
  7201. err = sp_3072_mod_26(t[1], t[1], m);
  7202. }
  7203. if (err == MP_OKAY) {
  7204. i = bits / 60;
  7205. c = bits % 60;
  7206. n = e[i--] << (60 - c);
  7207. for (; ; c--) {
  7208. if (c == 0) {
  7209. if (i == -1) {
  7210. break;
  7211. }
  7212. n = e[i--];
  7213. c = 60;
  7214. }
  7215. y = (int)((n >> 59) & 1);
  7216. n <<= 1;
  7217. sp_3072_mont_mul_26(t[y^1], t[0], t[1], m, mp);
  7218. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  7219. ((size_t)t[1] & addr_mask[y])),
  7220. sizeof(*t[2]) * 26 * 2);
  7221. sp_3072_mont_sqr_26(t[2], t[2], m, mp);
  7222. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  7223. ((size_t)t[1] & addr_mask[y])), t[2],
  7224. sizeof(*t[2]) * 26 * 2);
  7225. }
  7226. sp_3072_mont_reduce_26(t[0], m, mp);
  7227. n = sp_3072_cmp_26(t[0], m);
  7228. sp_3072_cond_sub_26(t[0], t[0], m, ~(n >> 63));
  7229. XMEMCPY(r, t[0], sizeof(*r) * 26 * 2);
  7230. }
  7231. #ifdef WOLFSSL_SP_SMALL_STACK
  7232. if (td != NULL)
  7233. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  7234. #endif
  7235. return err;
  7236. #elif !defined(WC_NO_CACHE_RESISTANT)
  7237. #ifdef WOLFSSL_SP_SMALL_STACK
  7238. sp_digit* td = NULL;
  7239. #else
  7240. sp_digit td[3 * 52];
  7241. #endif
  7242. sp_digit* t[3] = {0, 0, 0};
  7243. sp_digit* norm = NULL;
  7244. sp_digit mp = 1;
  7245. sp_digit n;
  7246. int i;
  7247. int c;
  7248. byte y;
  7249. int err = MP_OKAY;
  7250. if (bits == 0) {
  7251. err = MP_VAL;
  7252. }
  7253. #ifdef WOLFSSL_SP_SMALL_STACK
  7254. if (err == MP_OKAY) {
  7255. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 26 * 2, NULL,
  7256. DYNAMIC_TYPE_TMP_BUFFER);
  7257. if (td == NULL)
  7258. err = MEMORY_E;
  7259. }
  7260. #endif
  7261. if (err == MP_OKAY) {
  7262. norm = td;
  7263. for (i=0; i<3; i++) {
  7264. t[i] = td + (i * 26 * 2);
  7265. }
  7266. sp_3072_mont_setup(m, &mp);
  7267. sp_3072_mont_norm_26(norm, m);
  7268. if (reduceA != 0) {
  7269. err = sp_3072_mod_26(t[1], a, m);
  7270. if (err == MP_OKAY) {
  7271. sp_3072_mul_26(t[1], t[1], norm);
  7272. err = sp_3072_mod_26(t[1], t[1], m);
  7273. }
  7274. }
  7275. else {
  7276. sp_3072_mul_26(t[1], a, norm);
  7277. err = sp_3072_mod_26(t[1], t[1], m);
  7278. }
  7279. }
  7280. if (err == MP_OKAY) {
  7281. i = bits / 60;
  7282. c = bits % 60;
  7283. n = e[i--] << (60 - c);
  7284. for (; ; c--) {
  7285. if (c == 0) {
  7286. if (i == -1) {
  7287. break;
  7288. }
  7289. n = e[i--];
  7290. c = 60;
  7291. }
  7292. y = (int)((n >> 59) & 1);
  7293. n <<= 1;
  7294. sp_3072_mont_mul_26(t[y^1], t[0], t[1], m, mp);
  7295. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  7296. ((size_t)t[1] & addr_mask[y])),
  7297. sizeof(*t[2]) * 26 * 2);
  7298. sp_3072_mont_sqr_26(t[2], t[2], m, mp);
  7299. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  7300. ((size_t)t[1] & addr_mask[y])), t[2],
  7301. sizeof(*t[2]) * 26 * 2);
  7302. }
  7303. sp_3072_mont_reduce_26(t[0], m, mp);
  7304. n = sp_3072_cmp_26(t[0], m);
  7305. sp_3072_cond_sub_26(t[0], t[0], m, ~(n >> 63));
  7306. XMEMCPY(r, t[0], sizeof(*r) * 26 * 2);
  7307. }
  7308. #ifdef WOLFSSL_SP_SMALL_STACK
  7309. if (td != NULL)
  7310. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  7311. #endif
  7312. return err;
  7313. #else
  7314. #ifdef WOLFSSL_SP_SMALL_STACK
  7315. sp_digit* td = NULL;
  7316. #else
  7317. sp_digit td[(32 * 52) + 52];
  7318. #endif
  7319. sp_digit* t[32];
  7320. sp_digit* rt = NULL;
  7321. sp_digit* norm = NULL;
  7322. sp_digit mp = 1;
  7323. sp_digit n;
  7324. int i;
  7325. int c;
  7326. byte y;
  7327. int err = MP_OKAY;
  7328. if (bits == 0) {
  7329. err = MP_VAL;
  7330. }
  7331. #ifdef WOLFSSL_SP_SMALL_STACK
  7332. if (err == MP_OKAY) {
  7333. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((32 * 52) + 52), NULL,
  7334. DYNAMIC_TYPE_TMP_BUFFER);
  7335. if (td == NULL)
  7336. err = MEMORY_E;
  7337. }
  7338. #endif
  7339. if (err == MP_OKAY) {
  7340. norm = td;
  7341. for (i=0; i<32; i++)
  7342. t[i] = td + i * 52;
  7343. rt = td + 1664;
  7344. sp_3072_mont_setup(m, &mp);
  7345. sp_3072_mont_norm_26(norm, m);
  7346. if (reduceA != 0) {
  7347. err = sp_3072_mod_26(t[1], a, m);
  7348. if (err == MP_OKAY) {
  7349. sp_3072_mul_26(t[1], t[1], norm);
  7350. err = sp_3072_mod_26(t[1], t[1], m);
  7351. }
  7352. }
  7353. else {
  7354. sp_3072_mul_26(t[1], a, norm);
  7355. err = sp_3072_mod_26(t[1], t[1], m);
  7356. }
  7357. }
  7358. if (err == MP_OKAY) {
  7359. sp_3072_mont_sqr_26(t[ 2], t[ 1], m, mp);
  7360. sp_3072_mont_mul_26(t[ 3], t[ 2], t[ 1], m, mp);
  7361. sp_3072_mont_sqr_26(t[ 4], t[ 2], m, mp);
  7362. sp_3072_mont_mul_26(t[ 5], t[ 3], t[ 2], m, mp);
  7363. sp_3072_mont_sqr_26(t[ 6], t[ 3], m, mp);
  7364. sp_3072_mont_mul_26(t[ 7], t[ 4], t[ 3], m, mp);
  7365. sp_3072_mont_sqr_26(t[ 8], t[ 4], m, mp);
  7366. sp_3072_mont_mul_26(t[ 9], t[ 5], t[ 4], m, mp);
  7367. sp_3072_mont_sqr_26(t[10], t[ 5], m, mp);
  7368. sp_3072_mont_mul_26(t[11], t[ 6], t[ 5], m, mp);
  7369. sp_3072_mont_sqr_26(t[12], t[ 6], m, mp);
  7370. sp_3072_mont_mul_26(t[13], t[ 7], t[ 6], m, mp);
  7371. sp_3072_mont_sqr_26(t[14], t[ 7], m, mp);
  7372. sp_3072_mont_mul_26(t[15], t[ 8], t[ 7], m, mp);
  7373. sp_3072_mont_sqr_26(t[16], t[ 8], m, mp);
  7374. sp_3072_mont_mul_26(t[17], t[ 9], t[ 8], m, mp);
  7375. sp_3072_mont_sqr_26(t[18], t[ 9], m, mp);
  7376. sp_3072_mont_mul_26(t[19], t[10], t[ 9], m, mp);
  7377. sp_3072_mont_sqr_26(t[20], t[10], m, mp);
  7378. sp_3072_mont_mul_26(t[21], t[11], t[10], m, mp);
  7379. sp_3072_mont_sqr_26(t[22], t[11], m, mp);
  7380. sp_3072_mont_mul_26(t[23], t[12], t[11], m, mp);
  7381. sp_3072_mont_sqr_26(t[24], t[12], m, mp);
  7382. sp_3072_mont_mul_26(t[25], t[13], t[12], m, mp);
  7383. sp_3072_mont_sqr_26(t[26], t[13], m, mp);
  7384. sp_3072_mont_mul_26(t[27], t[14], t[13], m, mp);
  7385. sp_3072_mont_sqr_26(t[28], t[14], m, mp);
  7386. sp_3072_mont_mul_26(t[29], t[15], t[14], m, mp);
  7387. sp_3072_mont_sqr_26(t[30], t[15], m, mp);
  7388. sp_3072_mont_mul_26(t[31], t[16], t[15], m, mp);
  7389. bits = ((bits + 4) / 5) * 5;
  7390. i = ((bits + 59) / 60) - 1;
  7391. c = bits % 60;
  7392. if (c == 0) {
  7393. c = 60;
  7394. }
  7395. if (i < 26) {
  7396. n = e[i--] << (64 - c);
  7397. }
  7398. else {
  7399. n = 0;
  7400. i--;
  7401. }
  7402. if (c < 5) {
  7403. n |= e[i--] << (4 - c);
  7404. c += 60;
  7405. }
  7406. y = (int)((n >> 59) & 0x1f);
  7407. n <<= 5;
  7408. c -= 5;
  7409. XMEMCPY(rt, t[y], sizeof(sp_digit) * 52);
  7410. while ((i >= 0) || (c >= 5)) {
  7411. if (c >= 5) {
  7412. y = (byte)((n >> 59) & 0x1f);
  7413. n <<= 5;
  7414. c -= 5;
  7415. }
  7416. else if (c == 0) {
  7417. n = e[i--] << 4;
  7418. y = (byte)((n >> 59) & 0x1f);
  7419. n <<= 5;
  7420. c = 55;
  7421. }
  7422. else {
  7423. y = (byte)((n >> 59) & 0x1f);
  7424. n = e[i--] << 4;
  7425. c = 5 - c;
  7426. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  7427. n <<= c;
  7428. c = 60 - c;
  7429. }
  7430. sp_3072_mont_sqr_26(rt, rt, m, mp);
  7431. sp_3072_mont_sqr_26(rt, rt, m, mp);
  7432. sp_3072_mont_sqr_26(rt, rt, m, mp);
  7433. sp_3072_mont_sqr_26(rt, rt, m, mp);
  7434. sp_3072_mont_sqr_26(rt, rt, m, mp);
  7435. sp_3072_mont_mul_26(rt, rt, t[y], m, mp);
  7436. }
  7437. sp_3072_mont_reduce_26(rt, m, mp);
  7438. n = sp_3072_cmp_26(rt, m);
  7439. sp_3072_cond_sub_26(rt, rt, m, ~(n >> 63));
  7440. XMEMCPY(r, rt, sizeof(sp_digit) * 52);
  7441. }
  7442. #ifdef WOLFSSL_SP_SMALL_STACK
  7443. if (td != NULL)
  7444. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  7445. #endif
  7446. return err;
  7447. #endif
  7448. }
  7449. #endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */
  7450. /* Sub b from a into r. (r = a - b)
  7451. *
  7452. * r A single precision integer.
  7453. * a A single precision integer.
  7454. * b A single precision integer.
  7455. */
  7456. SP_NOINLINE static int sp_3072_sub_52(sp_digit* r, const sp_digit* a,
  7457. const sp_digit* b)
  7458. {
  7459. int i;
  7460. for (i = 0; i < 52; i++) {
  7461. r[i] = a[i] - b[i];
  7462. }
  7463. return 0;
  7464. }
  7465. /* r = 2^n mod m where n is the number of bits to reduce by.
  7466. * Given m must be 3072 bits, just need to subtract.
  7467. *
  7468. * r A single precision number.
  7469. * m A single precision number.
  7470. */
  7471. static void sp_3072_mont_norm_52(sp_digit* r, const sp_digit* m)
  7472. {
  7473. /* Set r = 2^n - 1. */
  7474. int i;
  7475. for (i=0; i<51; i++) {
  7476. r[i] = 0xfffffffffffffffL;
  7477. }
  7478. r[51] = 0xfffL;
  7479. /* r = (2^n - 1) mod n */
  7480. (void)sp_3072_sub_52(r, r, m);
  7481. /* Add one so r = 2^n mod m */
  7482. r[0] += 1;
  7483. }
  7484. /* Compare a with b in constant time.
  7485. *
  7486. * a A single precision integer.
  7487. * b A single precision integer.
  7488. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  7489. * respectively.
  7490. */
  7491. static sp_digit sp_3072_cmp_52(const sp_digit* a, const sp_digit* b)
  7492. {
  7493. sp_digit r = 0;
  7494. int i;
  7495. for (i=51; i>=0; i--) {
  7496. r |= (a[i] - b[i]) & ~(((sp_digit)0 - r) >> 59);
  7497. }
  7498. return r;
  7499. }
  7500. /* Conditionally subtract b from a using the mask m.
  7501. * m is -1 to subtract and 0 when not.
  7502. *
  7503. * r A single precision number representing condition subtract result.
  7504. * a A single precision number to subtract from.
  7505. * b A single precision number to subtract.
  7506. * m Mask value to apply.
  7507. */
  7508. static void sp_3072_cond_sub_52(sp_digit* r, const sp_digit* a,
  7509. const sp_digit* b, const sp_digit m)
  7510. {
  7511. int i;
  7512. for (i = 0; i < 52; i++) {
  7513. r[i] = a[i] - (b[i] & m);
  7514. }
  7515. }
  7516. /* Mul a by scalar b and add into r. (r += a * b)
  7517. *
  7518. * r A single precision integer.
  7519. * a A single precision integer.
  7520. * b A scalar.
  7521. */
  7522. SP_NOINLINE static void sp_3072_mul_add_52(sp_digit* r, const sp_digit* a,
  7523. const sp_digit b)
  7524. {
  7525. sp_int128 tb = b;
  7526. sp_int128 t[4];
  7527. int i;
  7528. t[0] = 0;
  7529. for (i = 0; i < 48; i += 4) {
  7530. t[0] += (tb * a[i+0]) + r[i+0];
  7531. t[1] = (tb * a[i+1]) + r[i+1];
  7532. t[2] = (tb * a[i+2]) + r[i+2];
  7533. t[3] = (tb * a[i+3]) + r[i+3];
  7534. r[i+0] = t[0] & 0xfffffffffffffffL;
  7535. t[1] += t[0] >> 60;
  7536. r[i+1] = t[1] & 0xfffffffffffffffL;
  7537. t[2] += t[1] >> 60;
  7538. r[i+2] = t[2] & 0xfffffffffffffffL;
  7539. t[3] += t[2] >> 60;
  7540. r[i+3] = t[3] & 0xfffffffffffffffL;
  7541. t[0] = t[3] >> 60;
  7542. }
  7543. t[0] += (tb * a[48]) + r[48];
  7544. t[1] = (tb * a[49]) + r[49];
  7545. t[2] = (tb * a[50]) + r[50];
  7546. t[3] = (tb * a[51]) + r[51];
  7547. r[48] = t[0] & 0xfffffffffffffffL;
  7548. t[1] += t[0] >> 60;
  7549. r[49] = t[1] & 0xfffffffffffffffL;
  7550. t[2] += t[1] >> 60;
  7551. r[50] = t[2] & 0xfffffffffffffffL;
  7552. t[3] += t[2] >> 60;
  7553. r[51] = t[3] & 0xfffffffffffffffL;
  7554. r[52] += (sp_digit)(t[3] >> 60);
  7555. }
  7556. /* Shift the result in the high 3072 bits down to the bottom.
  7557. *
  7558. * r A single precision number.
  7559. * a A single precision number.
  7560. */
  7561. static void sp_3072_mont_shift_52(sp_digit* r, const sp_digit* a)
  7562. {
  7563. int i;
  7564. sp_int128 n = a[51] >> 12;
  7565. n += ((sp_int128)a[52]) << 48;
  7566. for (i = 0; i < 51; i++) {
  7567. r[i] = n & 0xfffffffffffffffL;
  7568. n >>= 60;
  7569. n += ((sp_int128)a[53 + i]) << 48;
  7570. }
  7571. r[51] = (sp_digit)n;
  7572. XMEMSET(&r[52], 0, sizeof(*r) * 52U);
  7573. }
  7574. /* Reduce the number back to 3072 bits using Montgomery reduction.
  7575. *
  7576. * a A single precision number to reduce in place.
  7577. * m The single precision number representing the modulus.
  7578. * mp The digit representing the negative inverse of m mod 2^n.
  7579. */
  7580. static void sp_3072_mont_reduce_52(sp_digit* a, const sp_digit* m, sp_digit mp)
  7581. {
  7582. int i;
  7583. sp_digit mu;
  7584. sp_digit over;
  7585. sp_3072_norm_52(a + 52);
  7586. #ifdef WOLFSSL_SP_DH
  7587. if (mp != 1) {
  7588. for (i=0; i<51; i++) {
  7589. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0xfffffffffffffffL;
  7590. sp_3072_mul_add_52(a+i, m, mu);
  7591. a[i+1] += a[i] >> 60;
  7592. }
  7593. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0xfffL;
  7594. sp_3072_mul_add_52(a+i, m, mu);
  7595. a[i+1] += a[i] >> 60;
  7596. a[i] &= 0xfffffffffffffffL;
  7597. }
  7598. else {
  7599. for (i=0; i<51; i++) {
  7600. mu = a[i] & 0xfffffffffffffffL;
  7601. sp_3072_mul_add_52(a+i, m, mu);
  7602. a[i+1] += a[i] >> 60;
  7603. }
  7604. mu = a[i] & 0xfffL;
  7605. sp_3072_mul_add_52(a+i, m, mu);
  7606. a[i+1] += a[i] >> 60;
  7607. a[i] &= 0xfffffffffffffffL;
  7608. }
  7609. #else
  7610. for (i=0; i<51; i++) {
  7611. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0xfffffffffffffffL;
  7612. sp_3072_mul_add_52(a+i, m, mu);
  7613. a[i+1] += a[i] >> 60;
  7614. }
  7615. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0xfffL;
  7616. sp_3072_mul_add_52(a+i, m, mu);
  7617. a[i+1] += a[i] >> 60;
  7618. a[i] &= 0xfffffffffffffffL;
  7619. #endif
  7620. sp_3072_mont_shift_52(a, a);
  7621. over = a[51] - m[51];
  7622. sp_3072_cond_sub_52(a, a, m, ~((over - 1) >> 63));
  7623. sp_3072_norm_52(a);
  7624. }
  7625. /* Multiply two Montgomery form numbers mod the modulus (prime).
  7626. * (r = a * b mod m)
  7627. *
  7628. * r Result of multiplication.
  7629. * a First number to multiply in Montgomery form.
  7630. * b Second number to multiply in Montgomery form.
  7631. * m Modulus (prime).
  7632. * mp Montgomery multiplier.
  7633. */
  7634. SP_NOINLINE static void sp_3072_mont_mul_52(sp_digit* r, const sp_digit* a,
  7635. const sp_digit* b, const sp_digit* m, sp_digit mp)
  7636. {
  7637. sp_3072_mul_52(r, a, b);
  7638. sp_3072_mont_reduce_52(r, m, mp);
  7639. }
  7640. /* Square the Montgomery form number. (r = a * a mod m)
  7641. *
  7642. * r Result of squaring.
  7643. * a Number to square in Montgomery form.
  7644. * m Modulus (prime).
  7645. * mp Montgomery multiplier.
  7646. */
  7647. SP_NOINLINE static void sp_3072_mont_sqr_52(sp_digit* r, const sp_digit* a,
  7648. const sp_digit* m, sp_digit mp)
  7649. {
  7650. sp_3072_sqr_52(r, a);
  7651. sp_3072_mont_reduce_52(r, m, mp);
  7652. }
  7653. /* Multiply a by scalar b into r. (r = a * b)
  7654. *
  7655. * r A single precision integer.
  7656. * a A single precision integer.
  7657. * b A scalar.
  7658. */
  7659. SP_NOINLINE static void sp_3072_mul_d_104(sp_digit* r, const sp_digit* a,
  7660. sp_digit b)
  7661. {
  7662. sp_int128 tb = b;
  7663. sp_int128 t = 0;
  7664. int i;
  7665. for (i = 0; i < 104; i++) {
  7666. t += tb * a[i];
  7667. r[i] = (sp_digit)(t & 0xfffffffffffffffL);
  7668. t >>= 60;
  7669. }
  7670. r[104] = (sp_digit)t;
  7671. }
  7672. #ifdef WOLFSSL_SP_SMALL
  7673. /* Conditionally add a and b using the mask m.
  7674. * m is -1 to add and 0 when not.
  7675. *
  7676. * r A single precision number representing conditional add result.
  7677. * a A single precision number to add with.
  7678. * b A single precision number to add.
  7679. * m Mask value to apply.
  7680. */
  7681. static void sp_3072_cond_add_52(sp_digit* r, const sp_digit* a,
  7682. const sp_digit* b, const sp_digit m)
  7683. {
  7684. int i;
  7685. for (i = 0; i < 52; i++) {
  7686. r[i] = a[i] + (b[i] & m);
  7687. }
  7688. }
  7689. #endif /* WOLFSSL_SP_SMALL */
  7690. /* Add b to a into r. (r = a + b)
  7691. *
  7692. * r A single precision integer.
  7693. * a A single precision integer.
  7694. * b A single precision integer.
  7695. */
  7696. SP_NOINLINE static int sp_3072_add_52(sp_digit* r, const sp_digit* a,
  7697. const sp_digit* b)
  7698. {
  7699. int i;
  7700. for (i = 0; i < 52; i++) {
  7701. r[i] = a[i] + b[i];
  7702. }
  7703. return 0;
  7704. }
  7705. SP_NOINLINE static void sp_3072_rshift_52(sp_digit* r, const sp_digit* a,
  7706. byte n)
  7707. {
  7708. int i;
  7709. for (i=0; i<51; i++) {
  7710. r[i] = ((a[i] >> n) | (a[i + 1] << (60 - n))) & 0xfffffffffffffffL;
  7711. }
  7712. r[51] = a[51] >> n;
  7713. }
  7714. static WC_INLINE sp_digit sp_3072_div_word_52(sp_digit d1, sp_digit d0,
  7715. sp_digit div)
  7716. {
  7717. #ifdef SP_USE_DIVTI3
  7718. sp_int128 d = ((sp_int128)d1 << 60) + d0;
  7719. return d / div;
  7720. #elif defined(__x86_64__) || defined(__i386__)
  7721. sp_int128 d = ((sp_int128)d1 << 60) + d0;
  7722. sp_uint64 lo = (sp_uint64)d;
  7723. sp_digit hi = (sp_digit)(d >> 64);
  7724. __asm__ __volatile__ (
  7725. "idiv %2"
  7726. : "+a" (lo)
  7727. : "d" (hi), "r" (div)
  7728. : "cc"
  7729. );
  7730. return (sp_digit)lo;
  7731. #elif !defined(__aarch64__) && !defined(SP_DIV_WORD_USE_DIV)
  7732. sp_int128 d = ((sp_int128)d1 << 60) + d0;
  7733. sp_digit dv = (div >> 1) + 1;
  7734. sp_digit t1 = (sp_digit)(d >> 60);
  7735. sp_digit t0 = (sp_digit)(d & 0xfffffffffffffffL);
  7736. sp_digit t2;
  7737. sp_digit sign;
  7738. sp_digit r;
  7739. int i;
  7740. sp_int128 m;
  7741. r = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  7742. t1 -= dv & (0 - r);
  7743. for (i = 58; i >= 1; i--) {
  7744. t1 += t1 + (((sp_uint64)t0 >> 59) & 1);
  7745. t0 <<= 1;
  7746. t2 = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  7747. r += r + t2;
  7748. t1 -= dv & (0 - t2);
  7749. t1 += t2;
  7750. }
  7751. r += r + 1;
  7752. m = d - ((sp_int128)r * div);
  7753. r += (sp_digit)(m >> 60);
  7754. m = d - ((sp_int128)r * div);
  7755. r += (sp_digit)(m >> 120) - (sp_digit)(d >> 120);
  7756. m = d - ((sp_int128)r * div);
  7757. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  7758. m *= sign;
  7759. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  7760. r += sign * t2;
  7761. m = d - ((sp_int128)r * div);
  7762. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  7763. m *= sign;
  7764. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  7765. r += sign * t2;
  7766. return r;
  7767. #else
  7768. sp_int128 d = ((sp_int128)d1 << 60) + d0;
  7769. sp_digit r = 0;
  7770. sp_digit t;
  7771. sp_digit dv = (div >> 29) + 1;
  7772. t = (sp_digit)(d >> 58);
  7773. t = (t / dv) << 29;
  7774. r += t;
  7775. d -= (sp_int128)t * div;
  7776. t = (sp_digit)(d >> 27);
  7777. t = t / (dv << 2);
  7778. r += t;
  7779. d -= (sp_int128)t * div;
  7780. t = (sp_digit)d;
  7781. t = t / div;
  7782. r += t;
  7783. d -= (sp_int128)t * div;
  7784. return r;
  7785. #endif
  7786. }
  7787. static WC_INLINE sp_digit sp_3072_word_div_word_52(sp_digit d, sp_digit div)
  7788. {
  7789. #if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \
  7790. defined(SP_DIV_WORD_USE_DIV)
  7791. return d / div;
  7792. #else
  7793. return (sp_digit)((sp_uint64)(div - d) >> 63);
  7794. #endif
  7795. }
  7796. /* Divide d in a and put remainder into r (m*d + r = a)
  7797. * m is not calculated as it is not needed at this time.
  7798. *
  7799. * Full implementation.
  7800. *
  7801. * a Number to be divided.
  7802. * d Number to divide with.
  7803. * m Multiplier result.
  7804. * r Remainder from the division.
  7805. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  7806. */
  7807. static int sp_3072_div_52(const sp_digit* a, const sp_digit* d,
  7808. const sp_digit* m, sp_digit* r)
  7809. {
  7810. int i;
  7811. #ifndef WOLFSSL_SP_DIV_64
  7812. #endif
  7813. sp_digit dv;
  7814. sp_digit r1;
  7815. #ifdef WOLFSSL_SP_SMALL_STACK
  7816. sp_digit* t1 = NULL;
  7817. #else
  7818. sp_digit t1[4 * 52 + 3];
  7819. #endif
  7820. sp_digit* t2 = NULL;
  7821. sp_digit* sd = NULL;
  7822. int err = MP_OKAY;
  7823. (void)m;
  7824. #ifdef WOLFSSL_SP_SMALL_STACK
  7825. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 52 + 3), NULL,
  7826. DYNAMIC_TYPE_TMP_BUFFER);
  7827. if (t1 == NULL)
  7828. err = MEMORY_E;
  7829. #endif
  7830. (void)m;
  7831. if (err == MP_OKAY) {
  7832. t2 = t1 + 104 + 1;
  7833. sd = t2 + 52 + 1;
  7834. sp_3072_mul_d_52(sd, d, (sp_digit)1 << 48);
  7835. sp_3072_mul_d_104(t1, a, (sp_digit)1 << 48);
  7836. dv = sd[51];
  7837. t1[52 + 52] += t1[52 + 52 - 1] >> 60;
  7838. t1[52 + 52 - 1] &= 0xfffffffffffffffL;
  7839. for (i=52; i>=0; i--) {
  7840. r1 = sp_3072_div_word_52(t1[52 + i], t1[52 + i - 1], dv);
  7841. sp_3072_mul_d_52(t2, sd, r1);
  7842. (void)sp_3072_sub_52(&t1[i], &t1[i], t2);
  7843. sp_3072_norm_52(&t1[i]);
  7844. t1[52 + i] -= t2[52];
  7845. t1[52 + i] += t1[52 + i - 1] >> 60;
  7846. t1[52 + i - 1] &= 0xfffffffffffffffL;
  7847. r1 = sp_3072_div_word_52(-t1[52 + i], -t1[52 + i - 1], dv);
  7848. r1 -= t1[52 + i];
  7849. sp_3072_mul_d_52(t2, sd, r1);
  7850. (void)sp_3072_add_52(&t1[i], &t1[i], t2);
  7851. t1[52 + i] += t1[52 + i - 1] >> 60;
  7852. t1[52 + i - 1] &= 0xfffffffffffffffL;
  7853. }
  7854. t1[52 - 1] += t1[52 - 2] >> 60;
  7855. t1[52 - 2] &= 0xfffffffffffffffL;
  7856. r1 = sp_3072_word_div_word_52(t1[52 - 1], dv);
  7857. sp_3072_mul_d_52(t2, sd, r1);
  7858. sp_3072_sub_52(t1, t1, t2);
  7859. XMEMCPY(r, t1, sizeof(*r) * 104U);
  7860. for (i=0; i<51; i++) {
  7861. r[i+1] += r[i] >> 60;
  7862. r[i] &= 0xfffffffffffffffL;
  7863. }
  7864. sp_3072_cond_add_52(r, r, sd, r[51] >> 63);
  7865. sp_3072_norm_52(r);
  7866. sp_3072_rshift_52(r, r, 48);
  7867. }
  7868. #ifdef WOLFSSL_SP_SMALL_STACK
  7869. if (t1 != NULL)
  7870. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  7871. #endif
  7872. return err;
  7873. }
  7874. /* Reduce a modulo m into r. (r = a mod m)
  7875. *
  7876. * r A single precision number that is the reduced result.
  7877. * a A single precision number that is to be reduced.
  7878. * m A single precision number that is the modulus to reduce with.
  7879. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  7880. */
  7881. static int sp_3072_mod_52(sp_digit* r, const sp_digit* a, const sp_digit* m)
  7882. {
  7883. return sp_3072_div_52(a, m, NULL, r);
  7884. }
  7885. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  7886. /* Modular exponentiate a to the e mod m. (r = a^e mod m)
  7887. *
  7888. * r A single precision number that is the result of the operation.
  7889. * a A single precision number being exponentiated.
  7890. * e A single precision number that is the exponent.
  7891. * bits The number of bits in the exponent.
  7892. * m A single precision number that is the modulus.
  7893. * returns 0 on success.
  7894. * returns MEMORY_E on dynamic memory allocation failure.
  7895. * returns MP_VAL when base is even or exponent is 0.
  7896. */
  7897. static int sp_3072_mod_exp_52(sp_digit* r, const sp_digit* a, const sp_digit* e,
  7898. int bits, const sp_digit* m, int reduceA)
  7899. {
  7900. #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
  7901. #ifdef WOLFSSL_SP_SMALL_STACK
  7902. sp_digit* td = NULL;
  7903. #else
  7904. sp_digit td[3 * 104];
  7905. #endif
  7906. sp_digit* t[3] = {0, 0, 0};
  7907. sp_digit* norm = NULL;
  7908. sp_digit mp = 1;
  7909. sp_digit n;
  7910. int i;
  7911. int c;
  7912. byte y;
  7913. int err = MP_OKAY;
  7914. if (bits == 0) {
  7915. err = MP_VAL;
  7916. }
  7917. #ifdef WOLFSSL_SP_SMALL_STACK
  7918. if (err == MP_OKAY) {
  7919. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 52 * 2, NULL,
  7920. DYNAMIC_TYPE_TMP_BUFFER);
  7921. if (td == NULL)
  7922. err = MEMORY_E;
  7923. }
  7924. #endif
  7925. if (err == MP_OKAY) {
  7926. norm = td;
  7927. for (i=0; i<3; i++) {
  7928. t[i] = td + (i * 52 * 2);
  7929. XMEMSET(t[i], 0, sizeof(sp_digit) * 52U * 2U);
  7930. }
  7931. sp_3072_mont_setup(m, &mp);
  7932. sp_3072_mont_norm_52(norm, m);
  7933. if (reduceA != 0) {
  7934. err = sp_3072_mod_52(t[1], a, m);
  7935. }
  7936. else {
  7937. XMEMCPY(t[1], a, sizeof(sp_digit) * 52U);
  7938. }
  7939. }
  7940. if (err == MP_OKAY) {
  7941. sp_3072_mul_52(t[1], t[1], norm);
  7942. err = sp_3072_mod_52(t[1], t[1], m);
  7943. }
  7944. if (err == MP_OKAY) {
  7945. i = bits / 60;
  7946. c = bits % 60;
  7947. n = e[i--] << (60 - c);
  7948. for (; ; c--) {
  7949. if (c == 0) {
  7950. if (i == -1) {
  7951. break;
  7952. }
  7953. n = e[i--];
  7954. c = 60;
  7955. }
  7956. y = (int)((n >> 59) & 1);
  7957. n <<= 1;
  7958. sp_3072_mont_mul_52(t[y^1], t[0], t[1], m, mp);
  7959. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  7960. ((size_t)t[1] & addr_mask[y])),
  7961. sizeof(*t[2]) * 52 * 2);
  7962. sp_3072_mont_sqr_52(t[2], t[2], m, mp);
  7963. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  7964. ((size_t)t[1] & addr_mask[y])), t[2],
  7965. sizeof(*t[2]) * 52 * 2);
  7966. }
  7967. sp_3072_mont_reduce_52(t[0], m, mp);
  7968. n = sp_3072_cmp_52(t[0], m);
  7969. sp_3072_cond_sub_52(t[0], t[0], m, ~(n >> 63));
  7970. XMEMCPY(r, t[0], sizeof(*r) * 52 * 2);
  7971. }
  7972. #ifdef WOLFSSL_SP_SMALL_STACK
  7973. if (td != NULL)
  7974. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  7975. #endif
  7976. return err;
  7977. #elif !defined(WC_NO_CACHE_RESISTANT)
  7978. #ifdef WOLFSSL_SP_SMALL_STACK
  7979. sp_digit* td = NULL;
  7980. #else
  7981. sp_digit td[3 * 104];
  7982. #endif
  7983. sp_digit* t[3] = {0, 0, 0};
  7984. sp_digit* norm = NULL;
  7985. sp_digit mp = 1;
  7986. sp_digit n;
  7987. int i;
  7988. int c;
  7989. byte y;
  7990. int err = MP_OKAY;
  7991. if (bits == 0) {
  7992. err = MP_VAL;
  7993. }
  7994. #ifdef WOLFSSL_SP_SMALL_STACK
  7995. if (err == MP_OKAY) {
  7996. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 52 * 2, NULL,
  7997. DYNAMIC_TYPE_TMP_BUFFER);
  7998. if (td == NULL)
  7999. err = MEMORY_E;
  8000. }
  8001. #endif
  8002. if (err == MP_OKAY) {
  8003. norm = td;
  8004. for (i=0; i<3; i++) {
  8005. t[i] = td + (i * 52 * 2);
  8006. }
  8007. sp_3072_mont_setup(m, &mp);
  8008. sp_3072_mont_norm_52(norm, m);
  8009. if (reduceA != 0) {
  8010. err = sp_3072_mod_52(t[1], a, m);
  8011. if (err == MP_OKAY) {
  8012. sp_3072_mul_52(t[1], t[1], norm);
  8013. err = sp_3072_mod_52(t[1], t[1], m);
  8014. }
  8015. }
  8016. else {
  8017. sp_3072_mul_52(t[1], a, norm);
  8018. err = sp_3072_mod_52(t[1], t[1], m);
  8019. }
  8020. }
  8021. if (err == MP_OKAY) {
  8022. i = bits / 60;
  8023. c = bits % 60;
  8024. n = e[i--] << (60 - c);
  8025. for (; ; c--) {
  8026. if (c == 0) {
  8027. if (i == -1) {
  8028. break;
  8029. }
  8030. n = e[i--];
  8031. c = 60;
  8032. }
  8033. y = (int)((n >> 59) & 1);
  8034. n <<= 1;
  8035. sp_3072_mont_mul_52(t[y^1], t[0], t[1], m, mp);
  8036. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  8037. ((size_t)t[1] & addr_mask[y])),
  8038. sizeof(*t[2]) * 52 * 2);
  8039. sp_3072_mont_sqr_52(t[2], t[2], m, mp);
  8040. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  8041. ((size_t)t[1] & addr_mask[y])), t[2],
  8042. sizeof(*t[2]) * 52 * 2);
  8043. }
  8044. sp_3072_mont_reduce_52(t[0], m, mp);
  8045. n = sp_3072_cmp_52(t[0], m);
  8046. sp_3072_cond_sub_52(t[0], t[0], m, ~(n >> 63));
  8047. XMEMCPY(r, t[0], sizeof(*r) * 52 * 2);
  8048. }
  8049. #ifdef WOLFSSL_SP_SMALL_STACK
  8050. if (td != NULL)
  8051. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  8052. #endif
  8053. return err;
  8054. #else
  8055. #ifdef WOLFSSL_SP_SMALL_STACK
  8056. sp_digit* td = NULL;
  8057. #else
  8058. sp_digit td[(16 * 104) + 104];
  8059. #endif
  8060. sp_digit* t[16];
  8061. sp_digit* rt = NULL;
  8062. sp_digit* norm = NULL;
  8063. sp_digit mp = 1;
  8064. sp_digit n;
  8065. int i;
  8066. int c;
  8067. byte y;
  8068. int err = MP_OKAY;
  8069. if (bits == 0) {
  8070. err = MP_VAL;
  8071. }
  8072. #ifdef WOLFSSL_SP_SMALL_STACK
  8073. if (err == MP_OKAY) {
  8074. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((16 * 104) + 104), NULL,
  8075. DYNAMIC_TYPE_TMP_BUFFER);
  8076. if (td == NULL)
  8077. err = MEMORY_E;
  8078. }
  8079. #endif
  8080. if (err == MP_OKAY) {
  8081. norm = td;
  8082. for (i=0; i<16; i++)
  8083. t[i] = td + i * 104;
  8084. rt = td + 1664;
  8085. sp_3072_mont_setup(m, &mp);
  8086. sp_3072_mont_norm_52(norm, m);
  8087. if (reduceA != 0) {
  8088. err = sp_3072_mod_52(t[1], a, m);
  8089. if (err == MP_OKAY) {
  8090. sp_3072_mul_52(t[1], t[1], norm);
  8091. err = sp_3072_mod_52(t[1], t[1], m);
  8092. }
  8093. }
  8094. else {
  8095. sp_3072_mul_52(t[1], a, norm);
  8096. err = sp_3072_mod_52(t[1], t[1], m);
  8097. }
  8098. }
  8099. if (err == MP_OKAY) {
  8100. sp_3072_mont_sqr_52(t[ 2], t[ 1], m, mp);
  8101. sp_3072_mont_mul_52(t[ 3], t[ 2], t[ 1], m, mp);
  8102. sp_3072_mont_sqr_52(t[ 4], t[ 2], m, mp);
  8103. sp_3072_mont_mul_52(t[ 5], t[ 3], t[ 2], m, mp);
  8104. sp_3072_mont_sqr_52(t[ 6], t[ 3], m, mp);
  8105. sp_3072_mont_mul_52(t[ 7], t[ 4], t[ 3], m, mp);
  8106. sp_3072_mont_sqr_52(t[ 8], t[ 4], m, mp);
  8107. sp_3072_mont_mul_52(t[ 9], t[ 5], t[ 4], m, mp);
  8108. sp_3072_mont_sqr_52(t[10], t[ 5], m, mp);
  8109. sp_3072_mont_mul_52(t[11], t[ 6], t[ 5], m, mp);
  8110. sp_3072_mont_sqr_52(t[12], t[ 6], m, mp);
  8111. sp_3072_mont_mul_52(t[13], t[ 7], t[ 6], m, mp);
  8112. sp_3072_mont_sqr_52(t[14], t[ 7], m, mp);
  8113. sp_3072_mont_mul_52(t[15], t[ 8], t[ 7], m, mp);
  8114. bits = ((bits + 3) / 4) * 4;
  8115. i = ((bits + 59) / 60) - 1;
  8116. c = bits % 60;
  8117. if (c == 0) {
  8118. c = 60;
  8119. }
  8120. if (i < 52) {
  8121. n = e[i--] << (64 - c);
  8122. }
  8123. else {
  8124. n = 0;
  8125. i--;
  8126. }
  8127. if (c < 4) {
  8128. n |= e[i--] << (4 - c);
  8129. c += 60;
  8130. }
  8131. y = (int)((n >> 60) & 0xf);
  8132. n <<= 4;
  8133. c -= 4;
  8134. XMEMCPY(rt, t[y], sizeof(sp_digit) * 104);
  8135. while ((i >= 0) || (c >= 4)) {
  8136. if (c >= 4) {
  8137. y = (byte)((n >> 60) & 0xf);
  8138. n <<= 4;
  8139. c -= 4;
  8140. }
  8141. else if (c == 0) {
  8142. n = e[i--] << 4;
  8143. y = (byte)((n >> 60) & 0xf);
  8144. n <<= 4;
  8145. c = 56;
  8146. }
  8147. else {
  8148. y = (byte)((n >> 60) & 0xf);
  8149. n = e[i--] << 4;
  8150. c = 4 - c;
  8151. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  8152. n <<= c;
  8153. c = 60 - c;
  8154. }
  8155. sp_3072_mont_sqr_52(rt, rt, m, mp);
  8156. sp_3072_mont_sqr_52(rt, rt, m, mp);
  8157. sp_3072_mont_sqr_52(rt, rt, m, mp);
  8158. sp_3072_mont_sqr_52(rt, rt, m, mp);
  8159. sp_3072_mont_mul_52(rt, rt, t[y], m, mp);
  8160. }
  8161. sp_3072_mont_reduce_52(rt, m, mp);
  8162. n = sp_3072_cmp_52(rt, m);
  8163. sp_3072_cond_sub_52(rt, rt, m, ~(n >> 63));
  8164. XMEMCPY(r, rt, sizeof(sp_digit) * 104);
  8165. }
  8166. #ifdef WOLFSSL_SP_SMALL_STACK
  8167. if (td != NULL)
  8168. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  8169. #endif
  8170. return err;
  8171. #endif
  8172. }
  8173. #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
  8174. #ifdef WOLFSSL_HAVE_SP_RSA
  8175. /* RSA public key operation.
  8176. *
  8177. * in Array of bytes representing the number to exponentiate, base.
  8178. * inLen Number of bytes in base.
  8179. * em Public exponent.
  8180. * mm Modulus.
  8181. * out Buffer to hold big-endian bytes of exponentiation result.
  8182. * Must be at least 384 bytes long.
  8183. * outLen Number of bytes in result.
  8184. * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
  8185. * an array is too long and MEMORY_E when dynamic memory allocation fails.
  8186. */
  8187. int sp_RsaPublic_3072(const byte* in, word32 inLen, const mp_int* em,
  8188. const mp_int* mm, byte* out, word32* outLen)
  8189. {
  8190. #ifdef WOLFSSL_SP_SMALL
  8191. #ifdef WOLFSSL_SP_SMALL_STACK
  8192. sp_digit* a = NULL;
  8193. #else
  8194. sp_digit a[52 * 5];
  8195. #endif
  8196. sp_digit* m = NULL;
  8197. sp_digit* r = NULL;
  8198. sp_digit* norm = NULL;
  8199. sp_uint64 e[1] = {0};
  8200. sp_digit mp = 0;
  8201. int i;
  8202. int err = MP_OKAY;
  8203. if (*outLen < 384U) {
  8204. err = MP_TO_E;
  8205. }
  8206. if (err == MP_OKAY) {
  8207. if (mp_count_bits(em) > 64) {
  8208. err = MP_READ_E;
  8209. }
  8210. else if (inLen > 384U) {
  8211. err = MP_READ_E;
  8212. }
  8213. else if (mp_count_bits(mm) != 3072) {
  8214. err = MP_READ_E;
  8215. }
  8216. else if (mp_iseven(mm)) {
  8217. err = MP_VAL;
  8218. }
  8219. }
  8220. #ifdef WOLFSSL_SP_SMALL_STACK
  8221. if (err == MP_OKAY) {
  8222. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 52 * 5, NULL,
  8223. DYNAMIC_TYPE_RSA);
  8224. if (a == NULL)
  8225. err = MEMORY_E;
  8226. }
  8227. #endif
  8228. if (err == MP_OKAY) {
  8229. r = a + 52 * 2;
  8230. m = r + 52 * 2;
  8231. norm = r;
  8232. sp_3072_from_bin(a, 52, in, inLen);
  8233. #if DIGIT_BIT >= 64
  8234. e[0] = (sp_uint64)em->dp[0];
  8235. #else
  8236. e[0] = (sp_uint64)em->dp[0];
  8237. if (em->used > 1) {
  8238. e[0] |= ((sp_uint64)em->dp[1]) << DIGIT_BIT;
  8239. }
  8240. #endif
  8241. if (e[0] == 0) {
  8242. err = MP_EXPTMOD_E;
  8243. }
  8244. }
  8245. if (err == MP_OKAY) {
  8246. sp_3072_from_mp(m, 52, mm);
  8247. sp_3072_mont_setup(m, &mp);
  8248. sp_3072_mont_norm_52(norm, m);
  8249. }
  8250. if (err == MP_OKAY) {
  8251. sp_3072_mul_52(a, a, norm);
  8252. err = sp_3072_mod_52(a, a, m);
  8253. }
  8254. if (err == MP_OKAY) {
  8255. for (i=63; i>=0; i--) {
  8256. if ((e[0] >> i) != 0) {
  8257. break;
  8258. }
  8259. }
  8260. XMEMCPY(r, a, sizeof(sp_digit) * 52 * 2);
  8261. for (i--; i>=0; i--) {
  8262. sp_3072_mont_sqr_52(r, r, m, mp);
  8263. if (((e[0] >> i) & 1) == 1) {
  8264. sp_3072_mont_mul_52(r, r, a, m, mp);
  8265. }
  8266. }
  8267. sp_3072_mont_reduce_52(r, m, mp);
  8268. mp = sp_3072_cmp_52(r, m);
  8269. sp_3072_cond_sub_52(r, r, m, ~(mp >> 63));
  8270. sp_3072_to_bin_52(r, out);
  8271. *outLen = 384;
  8272. }
  8273. #ifdef WOLFSSL_SP_SMALL_STACK
  8274. if (a != NULL)
  8275. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  8276. #endif
  8277. return err;
  8278. #else
  8279. #ifdef WOLFSSL_SP_SMALL_STACK
  8280. sp_digit* d = NULL;
  8281. #else
  8282. sp_digit d[52 * 5];
  8283. #endif
  8284. sp_digit* a = NULL;
  8285. sp_digit* m = NULL;
  8286. sp_digit* r = NULL;
  8287. sp_uint64 e[1] = {0};
  8288. int err = MP_OKAY;
  8289. if (*outLen < 384U) {
  8290. err = MP_TO_E;
  8291. }
  8292. if (err == MP_OKAY) {
  8293. if (mp_count_bits(em) > 64) {
  8294. err = MP_READ_E;
  8295. }
  8296. else if (inLen > 384U) {
  8297. err = MP_READ_E;
  8298. }
  8299. else if (mp_count_bits(mm) != 3072) {
  8300. err = MP_READ_E;
  8301. }
  8302. else if (mp_iseven(mm)) {
  8303. err = MP_VAL;
  8304. }
  8305. }
  8306. #ifdef WOLFSSL_SP_SMALL_STACK
  8307. if (err == MP_OKAY) {
  8308. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 52 * 5, NULL,
  8309. DYNAMIC_TYPE_RSA);
  8310. if (d == NULL)
  8311. err = MEMORY_E;
  8312. }
  8313. #endif
  8314. if (err == MP_OKAY) {
  8315. a = d;
  8316. r = a + 52 * 2;
  8317. m = r + 52 * 2;
  8318. sp_3072_from_bin(a, 52, in, inLen);
  8319. #if DIGIT_BIT >= 64
  8320. e[0] = (sp_uint64)em->dp[0];
  8321. #else
  8322. e[0] = (sp_uint64)em->dp[0];
  8323. if (em->used > 1) {
  8324. e[0] |= ((sp_uint64)em->dp[1]) << DIGIT_BIT;
  8325. }
  8326. #endif
  8327. if (e[0] == 0) {
  8328. err = MP_EXPTMOD_E;
  8329. }
  8330. }
  8331. if (err == MP_OKAY) {
  8332. sp_3072_from_mp(m, 52, mm);
  8333. if (e[0] == 0x3) {
  8334. sp_3072_sqr_52(r, a);
  8335. err = sp_3072_mod_52(r, r, m);
  8336. if (err == MP_OKAY) {
  8337. sp_3072_mul_52(r, a, r);
  8338. err = sp_3072_mod_52(r, r, m);
  8339. }
  8340. }
  8341. else {
  8342. sp_digit* norm = r;
  8343. int i;
  8344. sp_digit mp;
  8345. sp_3072_mont_setup(m, &mp);
  8346. sp_3072_mont_norm_52(norm, m);
  8347. sp_3072_mul_52(a, a, norm);
  8348. err = sp_3072_mod_52(a, a, m);
  8349. if (err == MP_OKAY) {
  8350. for (i=63; i>=0; i--) {
  8351. if ((e[0] >> i) != 0) {
  8352. break;
  8353. }
  8354. }
  8355. XMEMCPY(r, a, sizeof(sp_digit) * 104U);
  8356. for (i--; i>=0; i--) {
  8357. sp_3072_mont_sqr_52(r, r, m, mp);
  8358. if (((e[0] >> i) & 1) == 1) {
  8359. sp_3072_mont_mul_52(r, r, a, m, mp);
  8360. }
  8361. }
  8362. sp_3072_mont_reduce_52(r, m, mp);
  8363. mp = sp_3072_cmp_52(r, m);
  8364. sp_3072_cond_sub_52(r, r, m, ~(mp >> 63));
  8365. }
  8366. }
  8367. }
  8368. if (err == MP_OKAY) {
  8369. sp_3072_to_bin_52(r, out);
  8370. *outLen = 384;
  8371. }
  8372. #ifdef WOLFSSL_SP_SMALL_STACK
  8373. if (d != NULL)
  8374. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  8375. #endif
  8376. return err;
  8377. #endif /* WOLFSSL_SP_SMALL */
  8378. }
  8379. #ifndef WOLFSSL_RSA_PUBLIC_ONLY
  8380. #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM)
  8381. #endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */
  8382. /* RSA private key operation.
  8383. *
  8384. * in Array of bytes representing the number to exponentiate, base.
  8385. * inLen Number of bytes in base.
  8386. * dm Private exponent.
  8387. * pm First prime.
  8388. * qm Second prime.
  8389. * dpm First prime's CRT exponent.
  8390. * dqm Second prime's CRT exponent.
  8391. * qim Inverse of second prime mod p.
  8392. * mm Modulus.
  8393. * out Buffer to hold big-endian bytes of exponentiation result.
  8394. * Must be at least 384 bytes long.
  8395. * outLen Number of bytes in result.
  8396. * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
  8397. * an array is too long and MEMORY_E when dynamic memory allocation fails.
  8398. */
  8399. int sp_RsaPrivate_3072(const byte* in, word32 inLen, const mp_int* dm,
  8400. const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm,
  8401. const mp_int* qim, const mp_int* mm, byte* out, word32* outLen)
  8402. {
  8403. #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
  8404. #if defined(WOLFSSL_SP_SMALL)
  8405. #ifdef WOLFSSL_SP_SMALL_STACK
  8406. sp_digit* d = NULL;
  8407. #else
  8408. sp_digit d[52 * 4];
  8409. #endif
  8410. sp_digit* a = NULL;
  8411. sp_digit* m = NULL;
  8412. sp_digit* r = NULL;
  8413. int err = MP_OKAY;
  8414. (void)pm;
  8415. (void)qm;
  8416. (void)dpm;
  8417. (void)dqm;
  8418. (void)qim;
  8419. if (*outLen < 384U) {
  8420. err = MP_TO_E;
  8421. }
  8422. if (err == MP_OKAY) {
  8423. if (mp_count_bits(dm) > 3072) {
  8424. err = MP_READ_E;
  8425. }
  8426. else if (inLen > 384) {
  8427. err = MP_READ_E;
  8428. }
  8429. else if (mp_count_bits(mm) != 3072) {
  8430. err = MP_READ_E;
  8431. }
  8432. else if (mp_iseven(mm)) {
  8433. err = MP_VAL;
  8434. }
  8435. }
  8436. #ifdef WOLFSSL_SP_SMALL_STACK
  8437. if (err == MP_OKAY) {
  8438. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 52 * 4, NULL,
  8439. DYNAMIC_TYPE_RSA);
  8440. if (d == NULL)
  8441. err = MEMORY_E;
  8442. }
  8443. #endif
  8444. if (err == MP_OKAY) {
  8445. a = d + 52;
  8446. m = a + 104;
  8447. r = a;
  8448. sp_3072_from_bin(a, 52, in, inLen);
  8449. sp_3072_from_mp(d, 52, dm);
  8450. sp_3072_from_mp(m, 52, mm);
  8451. err = sp_3072_mod_exp_52(r, a, d, 3072, m, 0);
  8452. }
  8453. if (err == MP_OKAY) {
  8454. sp_3072_to_bin_52(r, out);
  8455. *outLen = 384;
  8456. }
  8457. #ifdef WOLFSSL_SP_SMALL_STACK
  8458. if (d != NULL)
  8459. #endif
  8460. {
  8461. /* only "a" and "r" are sensitive and need zeroized (same pointer) */
  8462. if (a != NULL)
  8463. ForceZero(a, sizeof(sp_digit) * 52);
  8464. #ifdef WOLFSSL_SP_SMALL_STACK
  8465. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  8466. #endif
  8467. }
  8468. return err;
  8469. #else
  8470. #ifdef WOLFSSL_SP_SMALL_STACK
  8471. sp_digit* d = NULL;
  8472. #else
  8473. sp_digit d[52 * 4];
  8474. #endif
  8475. sp_digit* a = NULL;
  8476. sp_digit* m = NULL;
  8477. sp_digit* r = NULL;
  8478. int err = MP_OKAY;
  8479. (void)pm;
  8480. (void)qm;
  8481. (void)dpm;
  8482. (void)dqm;
  8483. (void)qim;
  8484. if (*outLen < 384U) {
  8485. err = MP_TO_E;
  8486. }
  8487. if (err == MP_OKAY) {
  8488. if (mp_count_bits(dm) > 3072) {
  8489. err = MP_READ_E;
  8490. }
  8491. else if (inLen > 384U) {
  8492. err = MP_READ_E;
  8493. }
  8494. else if (mp_count_bits(mm) != 3072) {
  8495. err = MP_READ_E;
  8496. }
  8497. else if (mp_iseven(mm)) {
  8498. err = MP_VAL;
  8499. }
  8500. }
  8501. #ifdef WOLFSSL_SP_SMALL_STACK
  8502. if (err == MP_OKAY) {
  8503. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 52 * 4, NULL,
  8504. DYNAMIC_TYPE_RSA);
  8505. if (d == NULL)
  8506. err = MEMORY_E;
  8507. }
  8508. #endif
  8509. if (err == MP_OKAY) {
  8510. a = d + 52;
  8511. m = a + 104;
  8512. r = a;
  8513. sp_3072_from_bin(a, 52, in, inLen);
  8514. sp_3072_from_mp(d, 52, dm);
  8515. sp_3072_from_mp(m, 52, mm);
  8516. err = sp_3072_mod_exp_52(r, a, d, 3072, m, 0);
  8517. }
  8518. if (err == MP_OKAY) {
  8519. sp_3072_to_bin_52(r, out);
  8520. *outLen = 384;
  8521. }
  8522. #ifdef WOLFSSL_SP_SMALL_STACK
  8523. if (d != NULL)
  8524. #endif
  8525. {
  8526. /* only "a" and "r" are sensitive and need zeroized (same pointer) */
  8527. if (a != NULL)
  8528. ForceZero(a, sizeof(sp_digit) * 52);
  8529. #ifdef WOLFSSL_SP_SMALL_STACK
  8530. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  8531. #endif
  8532. }
  8533. return err;
  8534. #endif /* WOLFSSL_SP_SMALL */
  8535. #else
  8536. #if defined(WOLFSSL_SP_SMALL)
  8537. #ifdef WOLFSSL_SP_SMALL_STACK
  8538. sp_digit* a = NULL;
  8539. #else
  8540. sp_digit a[26 * 8];
  8541. #endif
  8542. sp_digit* p = NULL;
  8543. sp_digit* dp = NULL;
  8544. sp_digit* dq = NULL;
  8545. sp_digit* qi = NULL;
  8546. sp_digit* tmpa = NULL;
  8547. sp_digit* tmpb = NULL;
  8548. sp_digit* r = NULL;
  8549. int err = MP_OKAY;
  8550. (void)dm;
  8551. (void)mm;
  8552. if (*outLen < 384U) {
  8553. err = MP_TO_E;
  8554. }
  8555. if (err == MP_OKAY) {
  8556. if (inLen > 384) {
  8557. err = MP_READ_E;
  8558. }
  8559. else if (mp_count_bits(mm) != 3072) {
  8560. err = MP_READ_E;
  8561. }
  8562. else if (mp_iseven(mm)) {
  8563. err = MP_VAL;
  8564. }
  8565. else if (mp_iseven(pm)) {
  8566. err = MP_VAL;
  8567. }
  8568. else if (mp_iseven(qm)) {
  8569. err = MP_VAL;
  8570. }
  8571. }
  8572. #ifdef WOLFSSL_SP_SMALL_STACK
  8573. if (err == MP_OKAY) {
  8574. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 26 * 8, NULL,
  8575. DYNAMIC_TYPE_RSA);
  8576. if (a == NULL)
  8577. err = MEMORY_E;
  8578. }
  8579. #endif
  8580. if (err == MP_OKAY) {
  8581. p = a + 52;
  8582. qi = dq = dp = p + 26;
  8583. tmpa = qi + 26;
  8584. tmpb = tmpa + 52;
  8585. r = a;
  8586. sp_3072_from_bin(a, 52, in, inLen);
  8587. sp_3072_from_mp(p, 26, pm);
  8588. sp_3072_from_mp(dp, 26, dpm);
  8589. err = sp_3072_mod_exp_26(tmpa, a, dp, 1536, p, 1);
  8590. }
  8591. if (err == MP_OKAY) {
  8592. sp_3072_from_mp(p, 26, qm);
  8593. sp_3072_from_mp(dq, 26, dqm);
  8594. err = sp_3072_mod_exp_26(tmpb, a, dq, 1536, p, 1);
  8595. }
  8596. if (err == MP_OKAY) {
  8597. sp_3072_from_mp(p, 26, pm);
  8598. (void)sp_3072_sub_26(tmpa, tmpa, tmpb);
  8599. sp_3072_norm_26(tmpa);
  8600. sp_3072_cond_add_26(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[25] >> 63));
  8601. sp_3072_cond_add_26(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[25] >> 63));
  8602. sp_3072_norm_26(tmpa);
  8603. sp_3072_from_mp(qi, 26, qim);
  8604. sp_3072_mul_26(tmpa, tmpa, qi);
  8605. err = sp_3072_mod_26(tmpa, tmpa, p);
  8606. }
  8607. if (err == MP_OKAY) {
  8608. sp_3072_from_mp(p, 26, qm);
  8609. sp_3072_mul_26(tmpa, p, tmpa);
  8610. (void)sp_3072_add_52(r, tmpb, tmpa);
  8611. sp_3072_norm_52(r);
  8612. sp_3072_to_bin_52(r, out);
  8613. *outLen = 384;
  8614. }
  8615. #ifdef WOLFSSL_SP_SMALL_STACK
  8616. if (a != NULL)
  8617. #endif
  8618. {
  8619. ForceZero(a, sizeof(sp_digit) * 26 * 8);
  8620. #ifdef WOLFSSL_SP_SMALL_STACK
  8621. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  8622. #endif
  8623. }
  8624. return err;
  8625. #else
  8626. #ifdef WOLFSSL_SP_SMALL_STACK
  8627. sp_digit* a = NULL;
  8628. #else
  8629. sp_digit a[26 * 13];
  8630. #endif
  8631. sp_digit* p = NULL;
  8632. sp_digit* q = NULL;
  8633. sp_digit* dp = NULL;
  8634. sp_digit* dq = NULL;
  8635. sp_digit* qi = NULL;
  8636. sp_digit* tmpa = NULL;
  8637. sp_digit* tmpb = NULL;
  8638. sp_digit* r = NULL;
  8639. int err = MP_OKAY;
  8640. (void)dm;
  8641. (void)mm;
  8642. if (*outLen < 384U) {
  8643. err = MP_TO_E;
  8644. }
  8645. if (err == MP_OKAY) {
  8646. if (inLen > 384U) {
  8647. err = MP_READ_E;
  8648. }
  8649. else if (mp_count_bits(mm) != 3072) {
  8650. err = MP_READ_E;
  8651. }
  8652. else if (mp_iseven(mm)) {
  8653. err = MP_VAL;
  8654. }
  8655. else if (mp_iseven(pm)) {
  8656. err = MP_VAL;
  8657. }
  8658. else if (mp_iseven(qm)) {
  8659. err = MP_VAL;
  8660. }
  8661. }
  8662. #ifdef WOLFSSL_SP_SMALL_STACK
  8663. if (err == MP_OKAY) {
  8664. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 26 * 13, NULL,
  8665. DYNAMIC_TYPE_RSA);
  8666. if (a == NULL)
  8667. err = MEMORY_E;
  8668. }
  8669. #endif
  8670. if (err == MP_OKAY) {
  8671. p = a + 52 * 2;
  8672. q = p + 26;
  8673. dp = q + 26;
  8674. dq = dp + 26;
  8675. qi = dq + 26;
  8676. tmpa = qi + 26;
  8677. tmpb = tmpa + 52;
  8678. r = a;
  8679. sp_3072_from_bin(a, 52, in, inLen);
  8680. sp_3072_from_mp(p, 26, pm);
  8681. sp_3072_from_mp(q, 26, qm);
  8682. sp_3072_from_mp(dp, 26, dpm);
  8683. sp_3072_from_mp(dq, 26, dqm);
  8684. sp_3072_from_mp(qi, 26, qim);
  8685. err = sp_3072_mod_exp_26(tmpa, a, dp, 1536, p, 1);
  8686. }
  8687. if (err == MP_OKAY) {
  8688. err = sp_3072_mod_exp_26(tmpb, a, dq, 1536, q, 1);
  8689. }
  8690. if (err == MP_OKAY) {
  8691. (void)sp_3072_sub_26(tmpa, tmpa, tmpb);
  8692. sp_3072_norm_26(tmpa);
  8693. sp_3072_cond_add_26(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[25] >> 63));
  8694. sp_3072_cond_add_26(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[25] >> 63));
  8695. sp_3072_norm_26(tmpa);
  8696. sp_3072_mul_26(tmpa, tmpa, qi);
  8697. err = sp_3072_mod_26(tmpa, tmpa, p);
  8698. }
  8699. if (err == MP_OKAY) {
  8700. sp_3072_mul_26(tmpa, tmpa, q);
  8701. (void)sp_3072_add_52(r, tmpb, tmpa);
  8702. sp_3072_norm_52(r);
  8703. sp_3072_to_bin_52(r, out);
  8704. *outLen = 384;
  8705. }
  8706. #ifdef WOLFSSL_SP_SMALL_STACK
  8707. if (a != NULL)
  8708. #endif
  8709. {
  8710. ForceZero(a, sizeof(sp_digit) * 26 * 13);
  8711. #ifdef WOLFSSL_SP_SMALL_STACK
  8712. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  8713. #endif
  8714. }
  8715. return err;
  8716. #endif /* WOLFSSL_SP_SMALL */
  8717. #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
  8718. }
  8719. #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
  8720. #endif /* WOLFSSL_HAVE_SP_RSA */
  8721. #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
  8722. !defined(WOLFSSL_RSA_PUBLIC_ONLY))
  8723. /* Convert an array of sp_digit to an mp_int.
  8724. *
  8725. * a A single precision integer.
  8726. * r A multi-precision integer.
  8727. */
  8728. static int sp_3072_to_mp(const sp_digit* a, mp_int* r)
  8729. {
  8730. int err;
  8731. err = mp_grow(r, (3072 + DIGIT_BIT - 1) / DIGIT_BIT);
  8732. if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
  8733. #if DIGIT_BIT == 60
  8734. XMEMCPY(r->dp, a, sizeof(sp_digit) * 52);
  8735. r->used = 52;
  8736. mp_clamp(r);
  8737. #elif DIGIT_BIT < 60
  8738. int i;
  8739. int j = 0;
  8740. int s = 0;
  8741. r->dp[0] = 0;
  8742. for (i = 0; i < 52; i++) {
  8743. r->dp[j] |= (mp_digit)(a[i] << s);
  8744. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  8745. s = DIGIT_BIT - s;
  8746. r->dp[++j] = (mp_digit)(a[i] >> s);
  8747. while (s + DIGIT_BIT <= 60) {
  8748. s += DIGIT_BIT;
  8749. r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  8750. if (s == SP_WORD_SIZE) {
  8751. r->dp[j] = 0;
  8752. }
  8753. else {
  8754. r->dp[j] = (mp_digit)(a[i] >> s);
  8755. }
  8756. }
  8757. s = 60 - s;
  8758. }
  8759. r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;
  8760. mp_clamp(r);
  8761. #else
  8762. int i;
  8763. int j = 0;
  8764. int s = 0;
  8765. r->dp[0] = 0;
  8766. for (i = 0; i < 52; i++) {
  8767. r->dp[j] |= ((mp_digit)a[i]) << s;
  8768. if (s + 60 >= DIGIT_BIT) {
  8769. #if DIGIT_BIT != 32 && DIGIT_BIT != 64
  8770. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  8771. #endif
  8772. s = DIGIT_BIT - s;
  8773. r->dp[++j] = a[i] >> s;
  8774. s = 60 - s;
  8775. }
  8776. else {
  8777. s += 60;
  8778. }
  8779. }
  8780. r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;
  8781. mp_clamp(r);
  8782. #endif
  8783. }
  8784. return err;
  8785. }
  8786. /* Perform the modular exponentiation for Diffie-Hellman.
  8787. *
  8788. * base Base. MP integer.
  8789. * exp Exponent. MP integer.
  8790. * mod Modulus. MP integer.
  8791. * res Result. MP integer.
  8792. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  8793. * and MEMORY_E if memory allocation fails.
  8794. */
  8795. int sp_ModExp_3072(const mp_int* base, const mp_int* exp, const mp_int* mod,
  8796. mp_int* res)
  8797. {
  8798. #ifdef WOLFSSL_SP_SMALL
  8799. int err = MP_OKAY;
  8800. #ifdef WOLFSSL_SP_SMALL_STACK
  8801. sp_digit* b = NULL;
  8802. #else
  8803. sp_digit b[52 * 4];
  8804. #endif
  8805. sp_digit* e = NULL;
  8806. sp_digit* m = NULL;
  8807. sp_digit* r = NULL;
  8808. int expBits = mp_count_bits(exp);
  8809. if (mp_count_bits(base) > 3072) {
  8810. err = MP_READ_E;
  8811. }
  8812. else if (expBits > 3072) {
  8813. err = MP_READ_E;
  8814. }
  8815. else if (mp_count_bits(mod) != 3072) {
  8816. err = MP_READ_E;
  8817. }
  8818. else if (mp_iseven(mod)) {
  8819. err = MP_VAL;
  8820. }
  8821. #ifdef WOLFSSL_SP_SMALL_STACK
  8822. if (err == MP_OKAY) {
  8823. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 52 * 4, NULL,
  8824. DYNAMIC_TYPE_DH);
  8825. if (b == NULL)
  8826. err = MEMORY_E;
  8827. }
  8828. #endif
  8829. if (err == MP_OKAY) {
  8830. e = b + 52 * 2;
  8831. m = e + 52;
  8832. r = b;
  8833. sp_3072_from_mp(b, 52, base);
  8834. sp_3072_from_mp(e, 52, exp);
  8835. sp_3072_from_mp(m, 52, mod);
  8836. err = sp_3072_mod_exp_52(r, b, e, mp_count_bits(exp), m, 0);
  8837. }
  8838. if (err == MP_OKAY) {
  8839. err = sp_3072_to_mp(r, res);
  8840. }
  8841. #ifdef WOLFSSL_SP_SMALL_STACK
  8842. if (b != NULL)
  8843. #endif
  8844. {
  8845. /* only "e" is sensitive and needs zeroized */
  8846. if (e != NULL)
  8847. ForceZero(e, sizeof(sp_digit) * 52U);
  8848. #ifdef WOLFSSL_SP_SMALL_STACK
  8849. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  8850. #endif
  8851. }
  8852. return err;
  8853. #else
  8854. #ifdef WOLFSSL_SP_SMALL_STACK
  8855. sp_digit* b = NULL;
  8856. #else
  8857. sp_digit b[52 * 4];
  8858. #endif
  8859. sp_digit* e = NULL;
  8860. sp_digit* m = NULL;
  8861. sp_digit* r = NULL;
  8862. int err = MP_OKAY;
  8863. int expBits = mp_count_bits(exp);
  8864. if (mp_count_bits(base) > 3072) {
  8865. err = MP_READ_E;
  8866. }
  8867. else if (expBits > 3072) {
  8868. err = MP_READ_E;
  8869. }
  8870. else if (mp_count_bits(mod) != 3072) {
  8871. err = MP_READ_E;
  8872. }
  8873. else if (mp_iseven(mod)) {
  8874. err = MP_VAL;
  8875. }
  8876. #ifdef WOLFSSL_SP_SMALL_STACK
  8877. if (err == MP_OKAY) {
  8878. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 52 * 4, NULL, DYNAMIC_TYPE_DH);
  8879. if (b == NULL)
  8880. err = MEMORY_E;
  8881. }
  8882. #endif
  8883. if (err == MP_OKAY) {
  8884. e = b + 52 * 2;
  8885. m = e + 52;
  8886. r = b;
  8887. sp_3072_from_mp(b, 52, base);
  8888. sp_3072_from_mp(e, 52, exp);
  8889. sp_3072_from_mp(m, 52, mod);
  8890. err = sp_3072_mod_exp_52(r, b, e, expBits, m, 0);
  8891. }
  8892. if (err == MP_OKAY) {
  8893. err = sp_3072_to_mp(r, res);
  8894. }
  8895. #ifdef WOLFSSL_SP_SMALL_STACK
  8896. if (b != NULL)
  8897. #endif
  8898. {
  8899. /* only "e" is sensitive and needs zeroized */
  8900. if (e != NULL)
  8901. ForceZero(e, sizeof(sp_digit) * 52U);
  8902. #ifdef WOLFSSL_SP_SMALL_STACK
  8903. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  8904. #endif
  8905. }
  8906. return err;
  8907. #endif
  8908. }
  8909. #ifdef WOLFSSL_HAVE_SP_DH
  8910. #ifdef HAVE_FFDHE_3072
  8911. SP_NOINLINE static void sp_3072_lshift_52(sp_digit* r, const sp_digit* a,
  8912. byte n)
  8913. {
  8914. int i;
  8915. r[52] = a[51] >> (60 - n);
  8916. for (i=51; i>0; i--) {
  8917. r[i] = ((a[i] << n) | (a[i-1] >> (60 - n))) & 0xfffffffffffffffL;
  8918. }
  8919. r[0] = (a[0] << n) & 0xfffffffffffffffL;
  8920. }
  8921. /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
  8922. *
  8923. * r A single precision number that is the result of the operation.
  8924. * e A single precision number that is the exponent.
  8925. * bits The number of bits in the exponent.
  8926. * m A single precision number that is the modulus.
  8927. * returns 0 on success.
  8928. * returns MEMORY_E on dynamic memory allocation failure.
  8929. * returns MP_VAL when base is even.
  8930. */
  8931. static int sp_3072_mod_exp_2_52(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)
  8932. {
  8933. #ifdef WOLFSSL_SP_SMALL_STACK
  8934. sp_digit* td = NULL;
  8935. #else
  8936. sp_digit td[157];
  8937. #endif
  8938. sp_digit* norm = NULL;
  8939. sp_digit* tmp = NULL;
  8940. sp_digit mp = 1;
  8941. sp_digit n;
  8942. sp_digit o;
  8943. int i;
  8944. int c;
  8945. byte y;
  8946. int err = MP_OKAY;
  8947. if (bits == 0) {
  8948. err = MP_VAL;
  8949. }
  8950. #ifdef WOLFSSL_SP_SMALL_STACK
  8951. if (err == MP_OKAY) {
  8952. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 157, NULL,
  8953. DYNAMIC_TYPE_TMP_BUFFER);
  8954. if (td == NULL)
  8955. err = MEMORY_E;
  8956. }
  8957. #endif
  8958. if (err == MP_OKAY) {
  8959. norm = td;
  8960. tmp = td + 104;
  8961. XMEMSET(td, 0, sizeof(sp_digit) * 157);
  8962. sp_3072_mont_setup(m, &mp);
  8963. sp_3072_mont_norm_52(norm, m);
  8964. bits = ((bits + 4) / 5) * 5;
  8965. i = ((bits + 59) / 60) - 1;
  8966. c = bits % 60;
  8967. if (c == 0) {
  8968. c = 60;
  8969. }
  8970. if (i < 52) {
  8971. n = e[i--] << (64 - c);
  8972. }
  8973. else {
  8974. n = 0;
  8975. i--;
  8976. }
  8977. if (c < 5) {
  8978. n |= e[i--] << (4 - c);
  8979. c += 60;
  8980. }
  8981. y = (int)((n >> 59) & 0x1f);
  8982. n <<= 5;
  8983. c -= 5;
  8984. sp_3072_lshift_52(r, norm, (byte)y);
  8985. while ((i >= 0) || (c >= 5)) {
  8986. if (c >= 5) {
  8987. y = (byte)((n >> 59) & 0x1f);
  8988. n <<= 5;
  8989. c -= 5;
  8990. }
  8991. else if (c == 0) {
  8992. n = e[i--] << 4;
  8993. y = (byte)((n >> 59) & 0x1f);
  8994. n <<= 5;
  8995. c = 55;
  8996. }
  8997. else {
  8998. y = (byte)((n >> 59) & 0x1f);
  8999. n = e[i--] << 4;
  9000. c = 5 - c;
  9001. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  9002. n <<= c;
  9003. c = 60 - c;
  9004. }
  9005. sp_3072_mont_sqr_52(r, r, m, mp);
  9006. sp_3072_mont_sqr_52(r, r, m, mp);
  9007. sp_3072_mont_sqr_52(r, r, m, mp);
  9008. sp_3072_mont_sqr_52(r, r, m, mp);
  9009. sp_3072_mont_sqr_52(r, r, m, mp);
  9010. sp_3072_lshift_52(r, r, (byte)y);
  9011. sp_3072_mul_d_52(tmp, norm, (r[52] << 48) + (r[51] >> 12));
  9012. r[52] = 0;
  9013. r[51] &= 0xfffL;
  9014. (void)sp_3072_add_52(r, r, tmp);
  9015. sp_3072_norm_52(r);
  9016. o = sp_3072_cmp_52(r, m);
  9017. sp_3072_cond_sub_52(r, r, m, ~(o >> 63));
  9018. }
  9019. sp_3072_mont_reduce_52(r, m, mp);
  9020. n = sp_3072_cmp_52(r, m);
  9021. sp_3072_cond_sub_52(r, r, m, ~(n >> 63));
  9022. }
  9023. #ifdef WOLFSSL_SP_SMALL_STACK
  9024. if (td != NULL)
  9025. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  9026. #endif
  9027. return err;
  9028. }
  9029. #endif /* HAVE_FFDHE_3072 */
  9030. /* Perform the modular exponentiation for Diffie-Hellman.
  9031. *
  9032. * base Base.
  9033. * exp Array of bytes that is the exponent.
  9034. * expLen Length of data, in bytes, in exponent.
  9035. * mod Modulus.
  9036. * out Buffer to hold big-endian bytes of exponentiation result.
  9037. * Must be at least 384 bytes long.
  9038. * outLen Length, in bytes, of exponentiation result.
  9039. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  9040. * and MEMORY_E if memory allocation fails.
  9041. */
  9042. int sp_DhExp_3072(const mp_int* base, const byte* exp, word32 expLen,
  9043. const mp_int* mod, byte* out, word32* outLen)
  9044. {
  9045. #ifdef WOLFSSL_SP_SMALL_STACK
  9046. sp_digit* b = NULL;
  9047. #else
  9048. sp_digit b[52 * 4];
  9049. #endif
  9050. sp_digit* e = NULL;
  9051. sp_digit* m = NULL;
  9052. sp_digit* r = NULL;
  9053. word32 i;
  9054. int err = MP_OKAY;
  9055. if (mp_count_bits(base) > 3072) {
  9056. err = MP_READ_E;
  9057. }
  9058. else if (expLen > 384U) {
  9059. err = MP_READ_E;
  9060. }
  9061. else if (mp_count_bits(mod) != 3072) {
  9062. err = MP_READ_E;
  9063. }
  9064. else if (mp_iseven(mod)) {
  9065. err = MP_VAL;
  9066. }
  9067. #ifdef WOLFSSL_SP_SMALL_STACK
  9068. if (err == MP_OKAY) {
  9069. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 52 * 4, NULL,
  9070. DYNAMIC_TYPE_DH);
  9071. if (b == NULL)
  9072. err = MEMORY_E;
  9073. }
  9074. #endif
  9075. if (err == MP_OKAY) {
  9076. e = b + 52 * 2;
  9077. m = e + 52;
  9078. r = b;
  9079. sp_3072_from_mp(b, 52, base);
  9080. sp_3072_from_bin(e, 52, exp, expLen);
  9081. sp_3072_from_mp(m, 52, mod);
  9082. #ifdef HAVE_FFDHE_3072
  9083. if (base->used == 1 && base->dp[0] == 2U &&
  9084. ((m[51] << 20) | (m[50] >> 40)) == 0xffffffffL) {
  9085. err = sp_3072_mod_exp_2_52(r, e, expLen * 8U, m);
  9086. }
  9087. else {
  9088. #endif
  9089. err = sp_3072_mod_exp_52(r, b, e, expLen * 8U, m, 0);
  9090. #ifdef HAVE_FFDHE_3072
  9091. }
  9092. #endif
  9093. }
  9094. if (err == MP_OKAY) {
  9095. sp_3072_to_bin_52(r, out);
  9096. *outLen = 384;
  9097. for (i=0; i<384U && out[i] == 0U; i++) {
  9098. /* Search for first non-zero. */
  9099. }
  9100. *outLen -= i;
  9101. XMEMMOVE(out, out + i, *outLen);
  9102. }
  9103. #ifdef WOLFSSL_SP_SMALL_STACK
  9104. if (b != NULL)
  9105. #endif
  9106. {
  9107. /* only "e" is sensitive and needs zeroized */
  9108. if (e != NULL)
  9109. ForceZero(e, sizeof(sp_digit) * 52U);
  9110. #ifdef WOLFSSL_SP_SMALL_STACK
  9111. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  9112. #endif
  9113. }
  9114. return err;
  9115. }
  9116. #endif /* WOLFSSL_HAVE_SP_DH */
  9117. /* Perform the modular exponentiation for Diffie-Hellman.
  9118. *
  9119. * base Base. MP integer.
  9120. * exp Exponent. MP integer.
  9121. * mod Modulus. MP integer.
  9122. * res Result. MP integer.
  9123. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  9124. * and MEMORY_E if memory allocation fails.
  9125. */
  9126. int sp_ModExp_1536(const mp_int* base, const mp_int* exp, const mp_int* mod,
  9127. mp_int* res)
  9128. {
  9129. #ifdef WOLFSSL_SP_SMALL
  9130. int err = MP_OKAY;
  9131. #ifdef WOLFSSL_SP_SMALL_STACK
  9132. sp_digit* b = NULL;
  9133. #else
  9134. sp_digit b[26 * 4];
  9135. #endif
  9136. sp_digit* e = NULL;
  9137. sp_digit* m = NULL;
  9138. sp_digit* r = NULL;
  9139. int expBits = mp_count_bits(exp);
  9140. if (mp_count_bits(base) > 1536) {
  9141. err = MP_READ_E;
  9142. }
  9143. else if (expBits > 1536) {
  9144. err = MP_READ_E;
  9145. }
  9146. else if (mp_count_bits(mod) != 1536) {
  9147. err = MP_READ_E;
  9148. }
  9149. else if (mp_iseven(mod)) {
  9150. err = MP_VAL;
  9151. }
  9152. #ifdef WOLFSSL_SP_SMALL_STACK
  9153. if (err == MP_OKAY) {
  9154. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 26 * 4, NULL,
  9155. DYNAMIC_TYPE_DH);
  9156. if (b == NULL)
  9157. err = MEMORY_E;
  9158. }
  9159. #endif
  9160. if (err == MP_OKAY) {
  9161. e = b + 26 * 2;
  9162. m = e + 26;
  9163. r = b;
  9164. sp_3072_from_mp(b, 26, base);
  9165. sp_3072_from_mp(e, 26, exp);
  9166. sp_3072_from_mp(m, 26, mod);
  9167. err = sp_3072_mod_exp_26(r, b, e, mp_count_bits(exp), m, 0);
  9168. }
  9169. if (err == MP_OKAY) {
  9170. XMEMSET(r + 26, 0, sizeof(*r) * 26U);
  9171. err = sp_3072_to_mp(r, res);
  9172. }
  9173. #ifdef WOLFSSL_SP_SMALL_STACK
  9174. if (b != NULL)
  9175. #endif
  9176. {
  9177. /* only "e" is sensitive and needs zeroized */
  9178. if (e != NULL)
  9179. ForceZero(e, sizeof(sp_digit) * 52U);
  9180. #ifdef WOLFSSL_SP_SMALL_STACK
  9181. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  9182. #endif
  9183. }
  9184. return err;
  9185. #else
  9186. #ifdef WOLFSSL_SP_SMALL_STACK
  9187. sp_digit* b = NULL;
  9188. #else
  9189. sp_digit b[26 * 4];
  9190. #endif
  9191. sp_digit* e = NULL;
  9192. sp_digit* m = NULL;
  9193. sp_digit* r = NULL;
  9194. int err = MP_OKAY;
  9195. int expBits = mp_count_bits(exp);
  9196. if (mp_count_bits(base) > 1536) {
  9197. err = MP_READ_E;
  9198. }
  9199. else if (expBits > 1536) {
  9200. err = MP_READ_E;
  9201. }
  9202. else if (mp_count_bits(mod) != 1536) {
  9203. err = MP_READ_E;
  9204. }
  9205. else if (mp_iseven(mod)) {
  9206. err = MP_VAL;
  9207. }
  9208. #ifdef WOLFSSL_SP_SMALL_STACK
  9209. if (err == MP_OKAY) {
  9210. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 26 * 4, NULL, DYNAMIC_TYPE_DH);
  9211. if (b == NULL)
  9212. err = MEMORY_E;
  9213. }
  9214. #endif
  9215. if (err == MP_OKAY) {
  9216. e = b + 26 * 2;
  9217. m = e + 26;
  9218. r = b;
  9219. sp_3072_from_mp(b, 26, base);
  9220. sp_3072_from_mp(e, 26, exp);
  9221. sp_3072_from_mp(m, 26, mod);
  9222. err = sp_3072_mod_exp_26(r, b, e, expBits, m, 0);
  9223. }
  9224. if (err == MP_OKAY) {
  9225. XMEMSET(r + 26, 0, sizeof(*r) * 26U);
  9226. err = sp_3072_to_mp(r, res);
  9227. }
  9228. #ifdef WOLFSSL_SP_SMALL_STACK
  9229. if (b != NULL)
  9230. #endif
  9231. {
  9232. /* only "e" is sensitive and needs zeroized */
  9233. if (e != NULL)
  9234. ForceZero(e, sizeof(sp_digit) * 52U);
  9235. #ifdef WOLFSSL_SP_SMALL_STACK
  9236. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  9237. #endif
  9238. }
  9239. return err;
  9240. #endif
  9241. }
  9242. #endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */
  9243. #else
  9244. /* Read big endian unsigned byte array into r.
  9245. *
  9246. * r A single precision integer.
  9247. * size Maximum number of bytes to convert
  9248. * a Byte array.
  9249. * n Number of bytes in array to read.
  9250. */
  9251. static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n)
  9252. {
  9253. int i;
  9254. int j = 0;
  9255. word32 s = 0;
  9256. r[0] = 0;
  9257. for (i = n-1; i >= 0; i--) {
  9258. r[j] |= (((sp_digit)a[i]) << s);
  9259. if (s >= 49U) {
  9260. r[j] &= 0x1ffffffffffffffL;
  9261. s = 57U - s;
  9262. if (j + 1 >= size) {
  9263. break;
  9264. }
  9265. r[++j] = (sp_digit)a[i] >> s;
  9266. s = 8U - s;
  9267. }
  9268. else {
  9269. s += 8U;
  9270. }
  9271. }
  9272. for (j++; j < size; j++) {
  9273. r[j] = 0;
  9274. }
  9275. }
  9276. /* Convert an mp_int to an array of sp_digit.
  9277. *
  9278. * r A single precision integer.
  9279. * size Maximum number of bytes to convert
  9280. * a A multi-precision integer.
  9281. */
  9282. static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a)
  9283. {
  9284. #if DIGIT_BIT == 57
  9285. int i;
  9286. sp_digit j = (sp_digit)0 - (sp_digit)a->used;
  9287. int o = 0;
  9288. for (i = 0; i < size; i++) {
  9289. sp_digit mask = (sp_digit)0 - (j >> 56);
  9290. r[i] = a->dp[o] & mask;
  9291. j++;
  9292. o += (int)(j >> 56);
  9293. }
  9294. #elif DIGIT_BIT > 57
  9295. unsigned int i;
  9296. int j = 0;
  9297. word32 s = 0;
  9298. r[0] = 0;
  9299. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  9300. r[j] |= ((sp_digit)a->dp[i] << s);
  9301. r[j] &= 0x1ffffffffffffffL;
  9302. s = 57U - s;
  9303. if (j + 1 >= size) {
  9304. break;
  9305. }
  9306. /* lint allow cast of mismatch word32 and mp_digit */
  9307. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  9308. while ((s + 57U) <= (word32)DIGIT_BIT) {
  9309. s += 57U;
  9310. r[j] &= 0x1ffffffffffffffL;
  9311. if (j + 1 >= size) {
  9312. break;
  9313. }
  9314. if (s < (word32)DIGIT_BIT) {
  9315. /* lint allow cast of mismatch word32 and mp_digit */
  9316. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  9317. }
  9318. else {
  9319. r[++j] = (sp_digit)0;
  9320. }
  9321. }
  9322. s = (word32)DIGIT_BIT - s;
  9323. }
  9324. for (j++; j < size; j++) {
  9325. r[j] = 0;
  9326. }
  9327. #else
  9328. unsigned int i;
  9329. int j = 0;
  9330. int s = 0;
  9331. r[0] = 0;
  9332. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  9333. r[j] |= ((sp_digit)a->dp[i]) << s;
  9334. if (s + DIGIT_BIT >= 57) {
  9335. r[j] &= 0x1ffffffffffffffL;
  9336. if (j + 1 >= size) {
  9337. break;
  9338. }
  9339. s = 57 - s;
  9340. if (s == DIGIT_BIT) {
  9341. r[++j] = 0;
  9342. s = 0;
  9343. }
  9344. else {
  9345. r[++j] = a->dp[i] >> s;
  9346. s = DIGIT_BIT - s;
  9347. }
  9348. }
  9349. else {
  9350. s += DIGIT_BIT;
  9351. }
  9352. }
  9353. for (j++; j < size; j++) {
  9354. r[j] = 0;
  9355. }
  9356. #endif
  9357. }
  9358. /* Write r as big endian to byte array.
  9359. * Fixed length number of bytes written: 384
  9360. *
  9361. * r A single precision integer.
  9362. * a Byte array.
  9363. */
  9364. static void sp_3072_to_bin_54(sp_digit* r, byte* a)
  9365. {
  9366. int i;
  9367. int j;
  9368. int s = 0;
  9369. int b;
  9370. for (i=0; i<53; i++) {
  9371. r[i+1] += r[i] >> 57;
  9372. r[i] &= 0x1ffffffffffffffL;
  9373. }
  9374. j = 3079 / 8 - 1;
  9375. a[j] = 0;
  9376. for (i=0; i<54 && j>=0; i++) {
  9377. b = 0;
  9378. /* lint allow cast of mismatch sp_digit and int */
  9379. a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
  9380. b += 8 - s;
  9381. if (j < 0) {
  9382. break;
  9383. }
  9384. while (b < 57) {
  9385. a[j--] = (byte)(r[i] >> b);
  9386. b += 8;
  9387. if (j < 0) {
  9388. break;
  9389. }
  9390. }
  9391. s = 8 - (b - 57);
  9392. if (j >= 0) {
  9393. a[j] = 0;
  9394. }
  9395. if (s != 0) {
  9396. j++;
  9397. }
  9398. }
  9399. }
  9400. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  9401. /* Normalize the values in each word to 57 bits.
  9402. *
  9403. * a Array of sp_digit to normalize.
  9404. */
  9405. static void sp_3072_norm_27(sp_digit* a)
  9406. {
  9407. int i;
  9408. for (i = 0; i < 24; i += 8) {
  9409. a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL;
  9410. a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL;
  9411. a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL;
  9412. a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL;
  9413. a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL;
  9414. a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL;
  9415. a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL;
  9416. a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL;
  9417. }
  9418. a[25] += a[24] >> 57; a[24] &= 0x1ffffffffffffffL;
  9419. a[26] += a[25] >> 57; a[25] &= 0x1ffffffffffffffL;
  9420. }
  9421. #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
  9422. /* Normalize the values in each word to 57 bits.
  9423. *
  9424. * a Array of sp_digit to normalize.
  9425. */
  9426. static void sp_3072_norm_54(sp_digit* a)
  9427. {
  9428. int i;
  9429. for (i = 0; i < 48; i += 8) {
  9430. a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL;
  9431. a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL;
  9432. a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL;
  9433. a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL;
  9434. a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL;
  9435. a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL;
  9436. a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL;
  9437. a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL;
  9438. }
  9439. a[49] += a[48] >> 57; a[48] &= 0x1ffffffffffffffL;
  9440. a[50] += a[49] >> 57; a[49] &= 0x1ffffffffffffffL;
  9441. a[51] += a[50] >> 57; a[50] &= 0x1ffffffffffffffL;
  9442. a[52] += a[51] >> 57; a[51] &= 0x1ffffffffffffffL;
  9443. a[53] += a[52] >> 57; a[52] &= 0x1ffffffffffffffL;
  9444. }
  9445. #ifndef WOLFSSL_SP_SMALL
  9446. /* Multiply a and b into r. (r = a * b)
  9447. *
  9448. * r A single precision integer.
  9449. * a A single precision integer.
  9450. * b A single precision integer.
  9451. */
  9452. SP_NOINLINE static void sp_3072_mul_9(sp_digit* r, const sp_digit* a,
  9453. const sp_digit* b)
  9454. {
  9455. sp_uint128 t0;
  9456. sp_uint128 t1;
  9457. sp_digit t[9];
  9458. t0 = ((sp_uint128)a[ 0]) * b[ 0];
  9459. t1 = ((sp_uint128)a[ 0]) * b[ 1]
  9460. + ((sp_uint128)a[ 1]) * b[ 0];
  9461. t[ 0] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9462. t0 = ((sp_uint128)a[ 0]) * b[ 2]
  9463. + ((sp_uint128)a[ 1]) * b[ 1]
  9464. + ((sp_uint128)a[ 2]) * b[ 0];
  9465. t[ 1] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9466. t1 = ((sp_uint128)a[ 0]) * b[ 3]
  9467. + ((sp_uint128)a[ 1]) * b[ 2]
  9468. + ((sp_uint128)a[ 2]) * b[ 1]
  9469. + ((sp_uint128)a[ 3]) * b[ 0];
  9470. t[ 2] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9471. t0 = ((sp_uint128)a[ 0]) * b[ 4]
  9472. + ((sp_uint128)a[ 1]) * b[ 3]
  9473. + ((sp_uint128)a[ 2]) * b[ 2]
  9474. + ((sp_uint128)a[ 3]) * b[ 1]
  9475. + ((sp_uint128)a[ 4]) * b[ 0];
  9476. t[ 3] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9477. t1 = ((sp_uint128)a[ 0]) * b[ 5]
  9478. + ((sp_uint128)a[ 1]) * b[ 4]
  9479. + ((sp_uint128)a[ 2]) * b[ 3]
  9480. + ((sp_uint128)a[ 3]) * b[ 2]
  9481. + ((sp_uint128)a[ 4]) * b[ 1]
  9482. + ((sp_uint128)a[ 5]) * b[ 0];
  9483. t[ 4] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9484. t0 = ((sp_uint128)a[ 0]) * b[ 6]
  9485. + ((sp_uint128)a[ 1]) * b[ 5]
  9486. + ((sp_uint128)a[ 2]) * b[ 4]
  9487. + ((sp_uint128)a[ 3]) * b[ 3]
  9488. + ((sp_uint128)a[ 4]) * b[ 2]
  9489. + ((sp_uint128)a[ 5]) * b[ 1]
  9490. + ((sp_uint128)a[ 6]) * b[ 0];
  9491. t[ 5] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9492. t1 = ((sp_uint128)a[ 0]) * b[ 7]
  9493. + ((sp_uint128)a[ 1]) * b[ 6]
  9494. + ((sp_uint128)a[ 2]) * b[ 5]
  9495. + ((sp_uint128)a[ 3]) * b[ 4]
  9496. + ((sp_uint128)a[ 4]) * b[ 3]
  9497. + ((sp_uint128)a[ 5]) * b[ 2]
  9498. + ((sp_uint128)a[ 6]) * b[ 1]
  9499. + ((sp_uint128)a[ 7]) * b[ 0];
  9500. t[ 6] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9501. t0 = ((sp_uint128)a[ 0]) * b[ 8]
  9502. + ((sp_uint128)a[ 1]) * b[ 7]
  9503. + ((sp_uint128)a[ 2]) * b[ 6]
  9504. + ((sp_uint128)a[ 3]) * b[ 5]
  9505. + ((sp_uint128)a[ 4]) * b[ 4]
  9506. + ((sp_uint128)a[ 5]) * b[ 3]
  9507. + ((sp_uint128)a[ 6]) * b[ 2]
  9508. + ((sp_uint128)a[ 7]) * b[ 1]
  9509. + ((sp_uint128)a[ 8]) * b[ 0];
  9510. t[ 7] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9511. t1 = ((sp_uint128)a[ 1]) * b[ 8]
  9512. + ((sp_uint128)a[ 2]) * b[ 7]
  9513. + ((sp_uint128)a[ 3]) * b[ 6]
  9514. + ((sp_uint128)a[ 4]) * b[ 5]
  9515. + ((sp_uint128)a[ 5]) * b[ 4]
  9516. + ((sp_uint128)a[ 6]) * b[ 3]
  9517. + ((sp_uint128)a[ 7]) * b[ 2]
  9518. + ((sp_uint128)a[ 8]) * b[ 1];
  9519. t[ 8] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9520. t0 = ((sp_uint128)a[ 2]) * b[ 8]
  9521. + ((sp_uint128)a[ 3]) * b[ 7]
  9522. + ((sp_uint128)a[ 4]) * b[ 6]
  9523. + ((sp_uint128)a[ 5]) * b[ 5]
  9524. + ((sp_uint128)a[ 6]) * b[ 4]
  9525. + ((sp_uint128)a[ 7]) * b[ 3]
  9526. + ((sp_uint128)a[ 8]) * b[ 2];
  9527. r[ 9] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9528. t1 = ((sp_uint128)a[ 3]) * b[ 8]
  9529. + ((sp_uint128)a[ 4]) * b[ 7]
  9530. + ((sp_uint128)a[ 5]) * b[ 6]
  9531. + ((sp_uint128)a[ 6]) * b[ 5]
  9532. + ((sp_uint128)a[ 7]) * b[ 4]
  9533. + ((sp_uint128)a[ 8]) * b[ 3];
  9534. r[10] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9535. t0 = ((sp_uint128)a[ 4]) * b[ 8]
  9536. + ((sp_uint128)a[ 5]) * b[ 7]
  9537. + ((sp_uint128)a[ 6]) * b[ 6]
  9538. + ((sp_uint128)a[ 7]) * b[ 5]
  9539. + ((sp_uint128)a[ 8]) * b[ 4];
  9540. r[11] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9541. t1 = ((sp_uint128)a[ 5]) * b[ 8]
  9542. + ((sp_uint128)a[ 6]) * b[ 7]
  9543. + ((sp_uint128)a[ 7]) * b[ 6]
  9544. + ((sp_uint128)a[ 8]) * b[ 5];
  9545. r[12] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9546. t0 = ((sp_uint128)a[ 6]) * b[ 8]
  9547. + ((sp_uint128)a[ 7]) * b[ 7]
  9548. + ((sp_uint128)a[ 8]) * b[ 6];
  9549. r[13] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9550. t1 = ((sp_uint128)a[ 7]) * b[ 8]
  9551. + ((sp_uint128)a[ 8]) * b[ 7];
  9552. r[14] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9553. t0 = ((sp_uint128)a[ 8]) * b[ 8];
  9554. r[15] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9555. r[16] = t0 & 0x1ffffffffffffffL;
  9556. r[17] = (sp_digit)(t0 >> 57);
  9557. XMEMCPY(r, t, sizeof(t));
  9558. }
  9559. /* Add b to a into r. (r = a + b)
  9560. *
  9561. * r A single precision integer.
  9562. * a A single precision integer.
  9563. * b A single precision integer.
  9564. */
  9565. SP_NOINLINE static int sp_3072_add_9(sp_digit* r, const sp_digit* a,
  9566. const sp_digit* b)
  9567. {
  9568. r[ 0] = a[ 0] + b[ 0];
  9569. r[ 1] = a[ 1] + b[ 1];
  9570. r[ 2] = a[ 2] + b[ 2];
  9571. r[ 3] = a[ 3] + b[ 3];
  9572. r[ 4] = a[ 4] + b[ 4];
  9573. r[ 5] = a[ 5] + b[ 5];
  9574. r[ 6] = a[ 6] + b[ 6];
  9575. r[ 7] = a[ 7] + b[ 7];
  9576. r[ 8] = a[ 8] + b[ 8];
  9577. return 0;
  9578. }
  9579. /* Sub b from a into r. (r = a - b)
  9580. *
  9581. * r A single precision integer.
  9582. * a A single precision integer.
  9583. * b A single precision integer.
  9584. */
  9585. SP_NOINLINE static int sp_3072_sub_18(sp_digit* r, const sp_digit* a,
  9586. const sp_digit* b)
  9587. {
  9588. int i;
  9589. for (i = 0; i < 16; i += 8) {
  9590. r[i + 0] = a[i + 0] - b[i + 0];
  9591. r[i + 1] = a[i + 1] - b[i + 1];
  9592. r[i + 2] = a[i + 2] - b[i + 2];
  9593. r[i + 3] = a[i + 3] - b[i + 3];
  9594. r[i + 4] = a[i + 4] - b[i + 4];
  9595. r[i + 5] = a[i + 5] - b[i + 5];
  9596. r[i + 6] = a[i + 6] - b[i + 6];
  9597. r[i + 7] = a[i + 7] - b[i + 7];
  9598. }
  9599. r[16] = a[16] - b[16];
  9600. r[17] = a[17] - b[17];
  9601. return 0;
  9602. }
  9603. /* Add b to a into r. (r = a + b)
  9604. *
  9605. * r A single precision integer.
  9606. * a A single precision integer.
  9607. * b A single precision integer.
  9608. */
  9609. SP_NOINLINE static int sp_3072_add_18(sp_digit* r, const sp_digit* a,
  9610. const sp_digit* b)
  9611. {
  9612. int i;
  9613. for (i = 0; i < 16; i += 8) {
  9614. r[i + 0] = a[i + 0] + b[i + 0];
  9615. r[i + 1] = a[i + 1] + b[i + 1];
  9616. r[i + 2] = a[i + 2] + b[i + 2];
  9617. r[i + 3] = a[i + 3] + b[i + 3];
  9618. r[i + 4] = a[i + 4] + b[i + 4];
  9619. r[i + 5] = a[i + 5] + b[i + 5];
  9620. r[i + 6] = a[i + 6] + b[i + 6];
  9621. r[i + 7] = a[i + 7] + b[i + 7];
  9622. }
  9623. r[16] = a[16] + b[16];
  9624. r[17] = a[17] + b[17];
  9625. return 0;
  9626. }
  9627. /* Multiply a and b into r. (r = a * b)
  9628. *
  9629. * r A single precision integer.
  9630. * a A single precision integer.
  9631. * b A single precision integer.
  9632. */
  9633. SP_NOINLINE static void sp_3072_mul_27(sp_digit* r, const sp_digit* a,
  9634. const sp_digit* b)
  9635. {
  9636. sp_digit p0[18];
  9637. sp_digit p1[18];
  9638. sp_digit p2[18];
  9639. sp_digit p3[18];
  9640. sp_digit p4[18];
  9641. sp_digit p5[18];
  9642. sp_digit t0[18];
  9643. sp_digit t1[18];
  9644. sp_digit t2[18];
  9645. sp_digit a0[9];
  9646. sp_digit a1[9];
  9647. sp_digit a2[9];
  9648. sp_digit b0[9];
  9649. sp_digit b1[9];
  9650. sp_digit b2[9];
  9651. (void)sp_3072_add_9(a0, a, &a[9]);
  9652. (void)sp_3072_add_9(b0, b, &b[9]);
  9653. (void)sp_3072_add_9(a1, &a[9], &a[18]);
  9654. (void)sp_3072_add_9(b1, &b[9], &b[18]);
  9655. (void)sp_3072_add_9(a2, a0, &a[18]);
  9656. (void)sp_3072_add_9(b2, b0, &b[18]);
  9657. sp_3072_mul_9(p0, a, b);
  9658. sp_3072_mul_9(p2, &a[9], &b[9]);
  9659. sp_3072_mul_9(p4, &a[18], &b[18]);
  9660. sp_3072_mul_9(p1, a0, b0);
  9661. sp_3072_mul_9(p3, a1, b1);
  9662. sp_3072_mul_9(p5, a2, b2);
  9663. XMEMSET(r, 0, sizeof(*r)*2U*27U);
  9664. (void)sp_3072_sub_18(t0, p3, p2);
  9665. (void)sp_3072_sub_18(t1, p1, p2);
  9666. (void)sp_3072_sub_18(t2, p5, t0);
  9667. (void)sp_3072_sub_18(t2, t2, t1);
  9668. (void)sp_3072_sub_18(t0, t0, p4);
  9669. (void)sp_3072_sub_18(t1, t1, p0);
  9670. (void)sp_3072_add_18(r, r, p0);
  9671. (void)sp_3072_add_18(&r[9], &r[9], t1);
  9672. (void)sp_3072_add_18(&r[18], &r[18], t2);
  9673. (void)sp_3072_add_18(&r[27], &r[27], t0);
  9674. (void)sp_3072_add_18(&r[36], &r[36], p4);
  9675. }
  9676. /* Add b to a into r. (r = a + b)
  9677. *
  9678. * r A single precision integer.
  9679. * a A single precision integer.
  9680. * b A single precision integer.
  9681. */
  9682. SP_NOINLINE static int sp_3072_add_27(sp_digit* r, const sp_digit* a,
  9683. const sp_digit* b)
  9684. {
  9685. int i;
  9686. for (i = 0; i < 24; i += 8) {
  9687. r[i + 0] = a[i + 0] + b[i + 0];
  9688. r[i + 1] = a[i + 1] + b[i + 1];
  9689. r[i + 2] = a[i + 2] + b[i + 2];
  9690. r[i + 3] = a[i + 3] + b[i + 3];
  9691. r[i + 4] = a[i + 4] + b[i + 4];
  9692. r[i + 5] = a[i + 5] + b[i + 5];
  9693. r[i + 6] = a[i + 6] + b[i + 6];
  9694. r[i + 7] = a[i + 7] + b[i + 7];
  9695. }
  9696. r[24] = a[24] + b[24];
  9697. r[25] = a[25] + b[25];
  9698. r[26] = a[26] + b[26];
  9699. return 0;
  9700. }
  9701. /* Add b to a into r. (r = a + b)
  9702. *
  9703. * r A single precision integer.
  9704. * a A single precision integer.
  9705. * b A single precision integer.
  9706. */
  9707. SP_NOINLINE static int sp_3072_add_54(sp_digit* r, const sp_digit* a,
  9708. const sp_digit* b)
  9709. {
  9710. int i;
  9711. for (i = 0; i < 48; i += 8) {
  9712. r[i + 0] = a[i + 0] + b[i + 0];
  9713. r[i + 1] = a[i + 1] + b[i + 1];
  9714. r[i + 2] = a[i + 2] + b[i + 2];
  9715. r[i + 3] = a[i + 3] + b[i + 3];
  9716. r[i + 4] = a[i + 4] + b[i + 4];
  9717. r[i + 5] = a[i + 5] + b[i + 5];
  9718. r[i + 6] = a[i + 6] + b[i + 6];
  9719. r[i + 7] = a[i + 7] + b[i + 7];
  9720. }
  9721. r[48] = a[48] + b[48];
  9722. r[49] = a[49] + b[49];
  9723. r[50] = a[50] + b[50];
  9724. r[51] = a[51] + b[51];
  9725. r[52] = a[52] + b[52];
  9726. r[53] = a[53] + b[53];
  9727. return 0;
  9728. }
  9729. /* Sub b from a into r. (r = a - b)
  9730. *
  9731. * r A single precision integer.
  9732. * a A single precision integer.
  9733. * b A single precision integer.
  9734. */
  9735. SP_NOINLINE static int sp_3072_sub_54(sp_digit* r, const sp_digit* a,
  9736. const sp_digit* b)
  9737. {
  9738. int i;
  9739. for (i = 0; i < 48; i += 8) {
  9740. r[i + 0] = a[i + 0] - b[i + 0];
  9741. r[i + 1] = a[i + 1] - b[i + 1];
  9742. r[i + 2] = a[i + 2] - b[i + 2];
  9743. r[i + 3] = a[i + 3] - b[i + 3];
  9744. r[i + 4] = a[i + 4] - b[i + 4];
  9745. r[i + 5] = a[i + 5] - b[i + 5];
  9746. r[i + 6] = a[i + 6] - b[i + 6];
  9747. r[i + 7] = a[i + 7] - b[i + 7];
  9748. }
  9749. r[48] = a[48] - b[48];
  9750. r[49] = a[49] - b[49];
  9751. r[50] = a[50] - b[50];
  9752. r[51] = a[51] - b[51];
  9753. r[52] = a[52] - b[52];
  9754. r[53] = a[53] - b[53];
  9755. return 0;
  9756. }
  9757. /* Multiply a and b into r. (r = a * b)
  9758. *
  9759. * r A single precision integer.
  9760. * a A single precision integer.
  9761. * b A single precision integer.
  9762. */
  9763. SP_NOINLINE static void sp_3072_mul_54(sp_digit* r, const sp_digit* a,
  9764. const sp_digit* b)
  9765. {
  9766. sp_digit* z0 = r;
  9767. sp_digit z1[54];
  9768. sp_digit* a1 = z1;
  9769. sp_digit b1[27];
  9770. sp_digit* z2 = r + 54;
  9771. (void)sp_3072_add_27(a1, a, &a[27]);
  9772. (void)sp_3072_add_27(b1, b, &b[27]);
  9773. sp_3072_mul_27(z2, &a[27], &b[27]);
  9774. sp_3072_mul_27(z0, a, b);
  9775. sp_3072_mul_27(z1, a1, b1);
  9776. (void)sp_3072_sub_54(z1, z1, z2);
  9777. (void)sp_3072_sub_54(z1, z1, z0);
  9778. (void)sp_3072_add_54(r + 27, r + 27, z1);
  9779. }
  9780. /* Square a and put result in r. (r = a * a)
  9781. *
  9782. * r A single precision integer.
  9783. * a A single precision integer.
  9784. */
  9785. SP_NOINLINE static void sp_3072_sqr_9(sp_digit* r, const sp_digit* a)
  9786. {
  9787. sp_uint128 t0;
  9788. sp_uint128 t1;
  9789. sp_digit t[9];
  9790. t0 = ((sp_uint128)a[ 0]) * a[ 0];
  9791. t1 = (((sp_uint128)a[ 0]) * a[ 1]) * 2;
  9792. t[ 0] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9793. t0 = (((sp_uint128)a[ 0]) * a[ 2]) * 2
  9794. + ((sp_uint128)a[ 1]) * a[ 1];
  9795. t[ 1] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9796. t1 = (((sp_uint128)a[ 0]) * a[ 3]
  9797. + ((sp_uint128)a[ 1]) * a[ 2]) * 2;
  9798. t[ 2] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9799. t0 = (((sp_uint128)a[ 0]) * a[ 4]
  9800. + ((sp_uint128)a[ 1]) * a[ 3]) * 2
  9801. + ((sp_uint128)a[ 2]) * a[ 2];
  9802. t[ 3] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9803. t1 = (((sp_uint128)a[ 0]) * a[ 5]
  9804. + ((sp_uint128)a[ 1]) * a[ 4]
  9805. + ((sp_uint128)a[ 2]) * a[ 3]) * 2;
  9806. t[ 4] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9807. t0 = (((sp_uint128)a[ 0]) * a[ 6]
  9808. + ((sp_uint128)a[ 1]) * a[ 5]
  9809. + ((sp_uint128)a[ 2]) * a[ 4]) * 2
  9810. + ((sp_uint128)a[ 3]) * a[ 3];
  9811. t[ 5] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9812. t1 = (((sp_uint128)a[ 0]) * a[ 7]
  9813. + ((sp_uint128)a[ 1]) * a[ 6]
  9814. + ((sp_uint128)a[ 2]) * a[ 5]
  9815. + ((sp_uint128)a[ 3]) * a[ 4]) * 2;
  9816. t[ 6] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9817. t0 = (((sp_uint128)a[ 0]) * a[ 8]
  9818. + ((sp_uint128)a[ 1]) * a[ 7]
  9819. + ((sp_uint128)a[ 2]) * a[ 6]
  9820. + ((sp_uint128)a[ 3]) * a[ 5]) * 2
  9821. + ((sp_uint128)a[ 4]) * a[ 4];
  9822. t[ 7] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9823. t1 = (((sp_uint128)a[ 1]) * a[ 8]
  9824. + ((sp_uint128)a[ 2]) * a[ 7]
  9825. + ((sp_uint128)a[ 3]) * a[ 6]
  9826. + ((sp_uint128)a[ 4]) * a[ 5]) * 2;
  9827. t[ 8] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9828. t0 = (((sp_uint128)a[ 2]) * a[ 8]
  9829. + ((sp_uint128)a[ 3]) * a[ 7]
  9830. + ((sp_uint128)a[ 4]) * a[ 6]) * 2
  9831. + ((sp_uint128)a[ 5]) * a[ 5];
  9832. r[ 9] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9833. t1 = (((sp_uint128)a[ 3]) * a[ 8]
  9834. + ((sp_uint128)a[ 4]) * a[ 7]
  9835. + ((sp_uint128)a[ 5]) * a[ 6]) * 2;
  9836. r[10] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9837. t0 = (((sp_uint128)a[ 4]) * a[ 8]
  9838. + ((sp_uint128)a[ 5]) * a[ 7]) * 2
  9839. + ((sp_uint128)a[ 6]) * a[ 6];
  9840. r[11] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9841. t1 = (((sp_uint128)a[ 5]) * a[ 8]
  9842. + ((sp_uint128)a[ 6]) * a[ 7]) * 2;
  9843. r[12] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9844. t0 = (((sp_uint128)a[ 6]) * a[ 8]) * 2
  9845. + ((sp_uint128)a[ 7]) * a[ 7];
  9846. r[13] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9847. t1 = (((sp_uint128)a[ 7]) * a[ 8]) * 2;
  9848. r[14] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  9849. t0 = ((sp_uint128)a[ 8]) * a[ 8];
  9850. r[15] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  9851. r[16] = t0 & 0x1ffffffffffffffL;
  9852. r[17] = (sp_digit)(t0 >> 57);
  9853. XMEMCPY(r, t, sizeof(t));
  9854. }
  9855. /* Square a into r. (r = a * a)
  9856. *
  9857. * r A single precision integer.
  9858. * a A single precision integer.
  9859. */
  9860. SP_NOINLINE static void sp_3072_sqr_27(sp_digit* r, const sp_digit* a)
  9861. {
  9862. sp_digit p0[18];
  9863. sp_digit p1[18];
  9864. sp_digit p2[18];
  9865. sp_digit p3[18];
  9866. sp_digit p4[18];
  9867. sp_digit p5[18];
  9868. sp_digit t0[18];
  9869. sp_digit t1[18];
  9870. sp_digit t2[18];
  9871. sp_digit a0[9];
  9872. sp_digit a1[9];
  9873. sp_digit a2[9];
  9874. (void)sp_3072_add_9(a0, a, &a[9]);
  9875. (void)sp_3072_add_9(a1, &a[9], &a[18]);
  9876. (void)sp_3072_add_9(a2, a0, &a[18]);
  9877. sp_3072_sqr_9(p0, a);
  9878. sp_3072_sqr_9(p2, &a[9]);
  9879. sp_3072_sqr_9(p4, &a[18]);
  9880. sp_3072_sqr_9(p1, a0);
  9881. sp_3072_sqr_9(p3, a1);
  9882. sp_3072_sqr_9(p5, a2);
  9883. XMEMSET(r, 0, sizeof(*r)*2U*27U);
  9884. (void)sp_3072_sub_18(t0, p3, p2);
  9885. (void)sp_3072_sub_18(t1, p1, p2);
  9886. (void)sp_3072_sub_18(t2, p5, t0);
  9887. (void)sp_3072_sub_18(t2, t2, t1);
  9888. (void)sp_3072_sub_18(t0, t0, p4);
  9889. (void)sp_3072_sub_18(t1, t1, p0);
  9890. (void)sp_3072_add_18(r, r, p0);
  9891. (void)sp_3072_add_18(&r[9], &r[9], t1);
  9892. (void)sp_3072_add_18(&r[18], &r[18], t2);
  9893. (void)sp_3072_add_18(&r[27], &r[27], t0);
  9894. (void)sp_3072_add_18(&r[36], &r[36], p4);
  9895. }
  9896. /* Square a and put result in r. (r = a * a)
  9897. *
  9898. * r A single precision integer.
  9899. * a A single precision integer.
  9900. */
  9901. SP_NOINLINE static void sp_3072_sqr_54(sp_digit* r, const sp_digit* a)
  9902. {
  9903. sp_digit* z0 = r;
  9904. sp_digit z1[54];
  9905. sp_digit* a1 = z1;
  9906. sp_digit* z2 = r + 54;
  9907. (void)sp_3072_add_27(a1, a, &a[27]);
  9908. sp_3072_sqr_27(z2, &a[27]);
  9909. sp_3072_sqr_27(z0, a);
  9910. sp_3072_sqr_27(z1, a1);
  9911. (void)sp_3072_sub_54(z1, z1, z2);
  9912. (void)sp_3072_sub_54(z1, z1, z0);
  9913. (void)sp_3072_add_54(r + 27, r + 27, z1);
  9914. }
  9915. #endif /* !WOLFSSL_SP_SMALL */
  9916. /* Calculate the bottom digit of -1/a mod 2^n.
  9917. *
  9918. * a A single precision number.
  9919. * rho Bottom word of inverse.
  9920. */
  9921. static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho)
  9922. {
  9923. sp_digit x;
  9924. sp_digit b;
  9925. b = a[0];
  9926. x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
  9927. x *= 2 - b * x; /* here x*a==1 mod 2**8 */
  9928. x *= 2 - b * x; /* here x*a==1 mod 2**16 */
  9929. x *= 2 - b * x; /* here x*a==1 mod 2**32 */
  9930. x *= 2 - b * x; /* here x*a==1 mod 2**64 */
  9931. x &= 0x1ffffffffffffffL;
  9932. /* rho = -1/m mod b */
  9933. *rho = ((sp_digit)1 << 57) - x;
  9934. }
  9935. /* Multiply a by scalar b into r. (r = a * b)
  9936. *
  9937. * r A single precision integer.
  9938. * a A single precision integer.
  9939. * b A scalar.
  9940. */
  9941. SP_NOINLINE static void sp_3072_mul_d_54(sp_digit* r, const sp_digit* a,
  9942. sp_digit b)
  9943. {
  9944. sp_int128 tb = b;
  9945. sp_int128 t = 0;
  9946. sp_digit t2;
  9947. sp_int128 p[4];
  9948. int i;
  9949. for (i = 0; i < 52; i += 4) {
  9950. p[0] = tb * a[i + 0];
  9951. p[1] = tb * a[i + 1];
  9952. p[2] = tb * a[i + 2];
  9953. p[3] = tb * a[i + 3];
  9954. t += p[0];
  9955. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  9956. t >>= 57;
  9957. r[i + 0] = (sp_digit)t2;
  9958. t += p[1];
  9959. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  9960. t >>= 57;
  9961. r[i + 1] = (sp_digit)t2;
  9962. t += p[2];
  9963. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  9964. t >>= 57;
  9965. r[i + 2] = (sp_digit)t2;
  9966. t += p[3];
  9967. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  9968. t >>= 57;
  9969. r[i + 3] = (sp_digit)t2;
  9970. }
  9971. t += tb * a[52];
  9972. r[52] = (sp_digit)(t & 0x1ffffffffffffffL);
  9973. t >>= 57;
  9974. t += tb * a[53];
  9975. r[53] = (sp_digit)(t & 0x1ffffffffffffffL);
  9976. t >>= 57;
  9977. r[54] = (sp_digit)(t & 0x1ffffffffffffffL);
  9978. }
  9979. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  9980. /* Sub b from a into r. (r = a - b)
  9981. *
  9982. * r A single precision integer.
  9983. * a A single precision integer.
  9984. * b A single precision integer.
  9985. */
  9986. SP_NOINLINE static int sp_3072_sub_27(sp_digit* r, const sp_digit* a,
  9987. const sp_digit* b)
  9988. {
  9989. int i;
  9990. for (i = 0; i < 24; i += 8) {
  9991. r[i + 0] = a[i + 0] - b[i + 0];
  9992. r[i + 1] = a[i + 1] - b[i + 1];
  9993. r[i + 2] = a[i + 2] - b[i + 2];
  9994. r[i + 3] = a[i + 3] - b[i + 3];
  9995. r[i + 4] = a[i + 4] - b[i + 4];
  9996. r[i + 5] = a[i + 5] - b[i + 5];
  9997. r[i + 6] = a[i + 6] - b[i + 6];
  9998. r[i + 7] = a[i + 7] - b[i + 7];
  9999. }
  10000. r[24] = a[24] - b[24];
  10001. r[25] = a[25] - b[25];
  10002. r[26] = a[26] - b[26];
  10003. return 0;
  10004. }
  10005. /* r = 2^n mod m where n is the number of bits to reduce by.
  10006. * Given m must be 3072 bits, just need to subtract.
  10007. *
  10008. * r A single precision number.
  10009. * m A single precision number.
  10010. */
  10011. static void sp_3072_mont_norm_27(sp_digit* r, const sp_digit* m)
  10012. {
  10013. /* Set r = 2^n - 1. */
  10014. int i;
  10015. for (i = 0; i < 24; i += 8) {
  10016. r[i + 0] = 0x1ffffffffffffffL;
  10017. r[i + 1] = 0x1ffffffffffffffL;
  10018. r[i + 2] = 0x1ffffffffffffffL;
  10019. r[i + 3] = 0x1ffffffffffffffL;
  10020. r[i + 4] = 0x1ffffffffffffffL;
  10021. r[i + 5] = 0x1ffffffffffffffL;
  10022. r[i + 6] = 0x1ffffffffffffffL;
  10023. r[i + 7] = 0x1ffffffffffffffL;
  10024. }
  10025. r[24] = 0x1ffffffffffffffL;
  10026. r[25] = 0x1ffffffffffffffL;
  10027. r[26] = 0x3fffffffffffffL;
  10028. /* r = (2^n - 1) mod n */
  10029. (void)sp_3072_sub_27(r, r, m);
  10030. /* Add one so r = 2^n mod m */
  10031. r[0] += 1;
  10032. }
  10033. /* Compare a with b in constant time.
  10034. *
  10035. * a A single precision integer.
  10036. * b A single precision integer.
  10037. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  10038. * respectively.
  10039. */
  10040. static sp_digit sp_3072_cmp_27(const sp_digit* a, const sp_digit* b)
  10041. {
  10042. sp_digit r = 0;
  10043. int i;
  10044. r |= (a[26] - b[26]) & (0 - (sp_digit)1);
  10045. r |= (a[25] - b[25]) & ~(((sp_digit)0 - r) >> 56);
  10046. r |= (a[24] - b[24]) & ~(((sp_digit)0 - r) >> 56);
  10047. for (i = 16; i >= 0; i -= 8) {
  10048. r |= (a[i + 7] - b[i + 7]) & ~(((sp_digit)0 - r) >> 56);
  10049. r |= (a[i + 6] - b[i + 6]) & ~(((sp_digit)0 - r) >> 56);
  10050. r |= (a[i + 5] - b[i + 5]) & ~(((sp_digit)0 - r) >> 56);
  10051. r |= (a[i + 4] - b[i + 4]) & ~(((sp_digit)0 - r) >> 56);
  10052. r |= (a[i + 3] - b[i + 3]) & ~(((sp_digit)0 - r) >> 56);
  10053. r |= (a[i + 2] - b[i + 2]) & ~(((sp_digit)0 - r) >> 56);
  10054. r |= (a[i + 1] - b[i + 1]) & ~(((sp_digit)0 - r) >> 56);
  10055. r |= (a[i + 0] - b[i + 0]) & ~(((sp_digit)0 - r) >> 56);
  10056. }
  10057. return r;
  10058. }
  10059. /* Conditionally subtract b from a using the mask m.
  10060. * m is -1 to subtract and 0 when not.
  10061. *
  10062. * r A single precision number representing condition subtract result.
  10063. * a A single precision number to subtract from.
  10064. * b A single precision number to subtract.
  10065. * m Mask value to apply.
  10066. */
  10067. static void sp_3072_cond_sub_27(sp_digit* r, const sp_digit* a,
  10068. const sp_digit* b, const sp_digit m)
  10069. {
  10070. int i;
  10071. for (i = 0; i < 24; i += 8) {
  10072. r[i + 0] = a[i + 0] - (b[i + 0] & m);
  10073. r[i + 1] = a[i + 1] - (b[i + 1] & m);
  10074. r[i + 2] = a[i + 2] - (b[i + 2] & m);
  10075. r[i + 3] = a[i + 3] - (b[i + 3] & m);
  10076. r[i + 4] = a[i + 4] - (b[i + 4] & m);
  10077. r[i + 5] = a[i + 5] - (b[i + 5] & m);
  10078. r[i + 6] = a[i + 6] - (b[i + 6] & m);
  10079. r[i + 7] = a[i + 7] - (b[i + 7] & m);
  10080. }
  10081. r[24] = a[24] - (b[24] & m);
  10082. r[25] = a[25] - (b[25] & m);
  10083. r[26] = a[26] - (b[26] & m);
  10084. }
  10085. /* Mul a by scalar b and add into r. (r += a * b)
  10086. *
  10087. * r A single precision integer.
  10088. * a A single precision integer.
  10089. * b A scalar.
  10090. */
  10091. SP_NOINLINE static void sp_3072_mul_add_27(sp_digit* r, const sp_digit* a,
  10092. const sp_digit b)
  10093. {
  10094. sp_int128 tb = b;
  10095. sp_int128 t[8];
  10096. int i;
  10097. t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL);
  10098. for (i = 0; i < 24; i += 8) {
  10099. t[1] = tb * a[i+1];
  10100. r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
  10101. t[2] = tb * a[i+2];
  10102. r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
  10103. t[3] = tb * a[i+3];
  10104. r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));
  10105. t[4] = tb * a[i+4];
  10106. r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));
  10107. t[5] = tb * a[i+5];
  10108. r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));
  10109. t[6] = tb * a[i+6];
  10110. r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL));
  10111. t[7] = tb * a[i+7];
  10112. r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL));
  10113. t[0] = tb * a[i+8];
  10114. r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL));
  10115. }
  10116. t[1] = tb * a[25];
  10117. r[25] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
  10118. t[2] = tb * a[26];
  10119. r[26] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
  10120. r[27] += (sp_digit)(t[2] >> 57);
  10121. }
  10122. /* Shift the result in the high 1536 bits down to the bottom.
  10123. *
  10124. * r A single precision number.
  10125. * a A single precision number.
  10126. */
  10127. static void sp_3072_mont_shift_27(sp_digit* r, const sp_digit* a)
  10128. {
  10129. sp_digit n;
  10130. sp_digit s;
  10131. int i;
  10132. s = a[27]; n = a[26] >> 54;
  10133. for (i = 0; i < 24; i += 8) {
  10134. n += (s & 0x1ffffffffffffffL) << 3; r[i+0] = n & 0x1ffffffffffffffL;
  10135. n >>= 57; s = a[i+28] + (s >> 57);
  10136. n += (s & 0x1ffffffffffffffL) << 3; r[i+1] = n & 0x1ffffffffffffffL;
  10137. n >>= 57; s = a[i+29] + (s >> 57);
  10138. n += (s & 0x1ffffffffffffffL) << 3; r[i+2] = n & 0x1ffffffffffffffL;
  10139. n >>= 57; s = a[i+30] + (s >> 57);
  10140. n += (s & 0x1ffffffffffffffL) << 3; r[i+3] = n & 0x1ffffffffffffffL;
  10141. n >>= 57; s = a[i+31] + (s >> 57);
  10142. n += (s & 0x1ffffffffffffffL) << 3; r[i+4] = n & 0x1ffffffffffffffL;
  10143. n >>= 57; s = a[i+32] + (s >> 57);
  10144. n += (s & 0x1ffffffffffffffL) << 3; r[i+5] = n & 0x1ffffffffffffffL;
  10145. n >>= 57; s = a[i+33] + (s >> 57);
  10146. n += (s & 0x1ffffffffffffffL) << 3; r[i+6] = n & 0x1ffffffffffffffL;
  10147. n >>= 57; s = a[i+34] + (s >> 57);
  10148. n += (s & 0x1ffffffffffffffL) << 3; r[i+7] = n & 0x1ffffffffffffffL;
  10149. n >>= 57; s = a[i+35] + (s >> 57);
  10150. }
  10151. n += (s & 0x1ffffffffffffffL) << 3; r[24] = n & 0x1ffffffffffffffL;
  10152. n >>= 57; s = a[52] + (s >> 57);
  10153. n += (s & 0x1ffffffffffffffL) << 3; r[25] = n & 0x1ffffffffffffffL;
  10154. n >>= 57; s = a[53] + (s >> 57);
  10155. n += s << 3; r[26] = n;
  10156. XMEMSET(&r[27], 0, sizeof(*r) * 27U);
  10157. }
  10158. /* Reduce the number back to 3072 bits using Montgomery reduction.
  10159. *
  10160. * a A single precision number to reduce in place.
  10161. * m The single precision number representing the modulus.
  10162. * mp The digit representing the negative inverse of m mod 2^n.
  10163. */
  10164. static void sp_3072_mont_reduce_27(sp_digit* a, const sp_digit* m, sp_digit mp)
  10165. {
  10166. int i;
  10167. sp_digit mu;
  10168. sp_digit over;
  10169. sp_3072_norm_27(a + 27);
  10170. for (i=0; i<26; i++) {
  10171. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1ffffffffffffffL;
  10172. sp_3072_mul_add_27(a+i, m, mu);
  10173. a[i+1] += a[i] >> 57;
  10174. }
  10175. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x3fffffffffffffL;
  10176. sp_3072_mul_add_27(a+i, m, mu);
  10177. a[i+1] += a[i] >> 57;
  10178. a[i] &= 0x1ffffffffffffffL;
  10179. sp_3072_mont_shift_27(a, a);
  10180. over = a[26] - m[26];
  10181. sp_3072_cond_sub_27(a, a, m, ~((over - 1) >> 63));
  10182. sp_3072_norm_27(a);
  10183. }
  10184. /* Multiply two Montgomery form numbers mod the modulus (prime).
  10185. * (r = a * b mod m)
  10186. *
  10187. * r Result of multiplication.
  10188. * a First number to multiply in Montgomery form.
  10189. * b Second number to multiply in Montgomery form.
  10190. * m Modulus (prime).
  10191. * mp Montgomery multiplier.
  10192. */
  10193. SP_NOINLINE static void sp_3072_mont_mul_27(sp_digit* r, const sp_digit* a,
  10194. const sp_digit* b, const sp_digit* m, sp_digit mp)
  10195. {
  10196. sp_3072_mul_27(r, a, b);
  10197. sp_3072_mont_reduce_27(r, m, mp);
  10198. }
  10199. /* Square the Montgomery form number. (r = a * a mod m)
  10200. *
  10201. * r Result of squaring.
  10202. * a Number to square in Montgomery form.
  10203. * m Modulus (prime).
  10204. * mp Montgomery multiplier.
  10205. */
  10206. SP_NOINLINE static void sp_3072_mont_sqr_27(sp_digit* r, const sp_digit* a,
  10207. const sp_digit* m, sp_digit mp)
  10208. {
  10209. sp_3072_sqr_27(r, a);
  10210. sp_3072_mont_reduce_27(r, m, mp);
  10211. }
  10212. /* Multiply a by scalar b into r. (r = a * b)
  10213. *
  10214. * r A single precision integer.
  10215. * a A single precision integer.
  10216. * b A scalar.
  10217. */
  10218. SP_NOINLINE static void sp_3072_mul_d_27(sp_digit* r, const sp_digit* a,
  10219. sp_digit b)
  10220. {
  10221. sp_int128 tb = b;
  10222. sp_int128 t = 0;
  10223. sp_digit t2;
  10224. sp_int128 p[4];
  10225. int i;
  10226. for (i = 0; i < 24; i += 4) {
  10227. p[0] = tb * a[i + 0];
  10228. p[1] = tb * a[i + 1];
  10229. p[2] = tb * a[i + 2];
  10230. p[3] = tb * a[i + 3];
  10231. t += p[0];
  10232. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  10233. t >>= 57;
  10234. r[i + 0] = (sp_digit)t2;
  10235. t += p[1];
  10236. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  10237. t >>= 57;
  10238. r[i + 1] = (sp_digit)t2;
  10239. t += p[2];
  10240. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  10241. t >>= 57;
  10242. r[i + 2] = (sp_digit)t2;
  10243. t += p[3];
  10244. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  10245. t >>= 57;
  10246. r[i + 3] = (sp_digit)t2;
  10247. }
  10248. t += tb * a[24];
  10249. r[24] = (sp_digit)(t & 0x1ffffffffffffffL);
  10250. t >>= 57;
  10251. t += tb * a[25];
  10252. r[25] = (sp_digit)(t & 0x1ffffffffffffffL);
  10253. t >>= 57;
  10254. t += tb * a[26];
  10255. r[26] = (sp_digit)(t & 0x1ffffffffffffffL);
  10256. t >>= 57;
  10257. r[27] = (sp_digit)(t & 0x1ffffffffffffffL);
  10258. }
  10259. #ifndef WOLFSSL_SP_SMALL
  10260. /* Conditionally add a and b using the mask m.
  10261. * m is -1 to add and 0 when not.
  10262. *
  10263. * r A single precision number representing conditional add result.
  10264. * a A single precision number to add with.
  10265. * b A single precision number to add.
  10266. * m Mask value to apply.
  10267. */
  10268. static void sp_3072_cond_add_27(sp_digit* r, const sp_digit* a,
  10269. const sp_digit* b, const sp_digit m)
  10270. {
  10271. int i;
  10272. for (i = 0; i < 24; i += 8) {
  10273. r[i + 0] = a[i + 0] + (b[i + 0] & m);
  10274. r[i + 1] = a[i + 1] + (b[i + 1] & m);
  10275. r[i + 2] = a[i + 2] + (b[i + 2] & m);
  10276. r[i + 3] = a[i + 3] + (b[i + 3] & m);
  10277. r[i + 4] = a[i + 4] + (b[i + 4] & m);
  10278. r[i + 5] = a[i + 5] + (b[i + 5] & m);
  10279. r[i + 6] = a[i + 6] + (b[i + 6] & m);
  10280. r[i + 7] = a[i + 7] + (b[i + 7] & m);
  10281. }
  10282. r[24] = a[24] + (b[24] & m);
  10283. r[25] = a[25] + (b[25] & m);
  10284. r[26] = a[26] + (b[26] & m);
  10285. }
  10286. #endif /* !WOLFSSL_SP_SMALL */
  10287. SP_NOINLINE static void sp_3072_rshift_27(sp_digit* r, const sp_digit* a,
  10288. byte n)
  10289. {
  10290. int i;
  10291. for (i=0; i<24; i += 8) {
  10292. r[i+0] = (a[i+0] >> n) | ((a[i+1] << (57 - n)) & 0x1ffffffffffffffL);
  10293. r[i+1] = (a[i+1] >> n) | ((a[i+2] << (57 - n)) & 0x1ffffffffffffffL);
  10294. r[i+2] = (a[i+2] >> n) | ((a[i+3] << (57 - n)) & 0x1ffffffffffffffL);
  10295. r[i+3] = (a[i+3] >> n) | ((a[i+4] << (57 - n)) & 0x1ffffffffffffffL);
  10296. r[i+4] = (a[i+4] >> n) | ((a[i+5] << (57 - n)) & 0x1ffffffffffffffL);
  10297. r[i+5] = (a[i+5] >> n) | ((a[i+6] << (57 - n)) & 0x1ffffffffffffffL);
  10298. r[i+6] = (a[i+6] >> n) | ((a[i+7] << (57 - n)) & 0x1ffffffffffffffL);
  10299. r[i+7] = (a[i+7] >> n) | ((a[i+8] << (57 - n)) & 0x1ffffffffffffffL);
  10300. }
  10301. r[24] = (a[24] >> n) | ((a[25] << (57 - n)) & 0x1ffffffffffffffL);
  10302. r[25] = (a[25] >> n) | ((a[26] << (57 - n)) & 0x1ffffffffffffffL);
  10303. r[26] = a[26] >> n;
  10304. }
  10305. static WC_INLINE sp_digit sp_3072_div_word_27(sp_digit d1, sp_digit d0,
  10306. sp_digit div)
  10307. {
  10308. #ifdef SP_USE_DIVTI3
  10309. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  10310. return d / div;
  10311. #elif defined(__x86_64__) || defined(__i386__)
  10312. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  10313. sp_uint64 lo = (sp_uint64)d;
  10314. sp_digit hi = (sp_digit)(d >> 64);
  10315. __asm__ __volatile__ (
  10316. "idiv %2"
  10317. : "+a" (lo)
  10318. : "d" (hi), "r" (div)
  10319. : "cc"
  10320. );
  10321. return (sp_digit)lo;
  10322. #elif !defined(__aarch64__) && !defined(SP_DIV_WORD_USE_DIV)
  10323. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  10324. sp_digit dv = (div >> 1) + 1;
  10325. sp_digit t1 = (sp_digit)(d >> 57);
  10326. sp_digit t0 = (sp_digit)(d & 0x1ffffffffffffffL);
  10327. sp_digit t2;
  10328. sp_digit sign;
  10329. sp_digit r;
  10330. int i;
  10331. sp_int128 m;
  10332. r = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  10333. t1 -= dv & (0 - r);
  10334. for (i = 55; i >= 1; i--) {
  10335. t1 += t1 + (((sp_uint64)t0 >> 56) & 1);
  10336. t0 <<= 1;
  10337. t2 = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  10338. r += r + t2;
  10339. t1 -= dv & (0 - t2);
  10340. t1 += t2;
  10341. }
  10342. r += r + 1;
  10343. m = d - ((sp_int128)r * div);
  10344. r += (sp_digit)(m >> 57);
  10345. m = d - ((sp_int128)r * div);
  10346. r += (sp_digit)(m >> 114) - (sp_digit)(d >> 114);
  10347. m = d - ((sp_int128)r * div);
  10348. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  10349. m *= sign;
  10350. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  10351. r += sign * t2;
  10352. m = d - ((sp_int128)r * div);
  10353. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  10354. m *= sign;
  10355. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  10356. r += sign * t2;
  10357. return r;
  10358. #else
  10359. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  10360. sp_digit r = 0;
  10361. sp_digit t;
  10362. sp_digit dv = (div >> 26) + 1;
  10363. t = (sp_digit)(d >> 52);
  10364. t = (t / dv) << 26;
  10365. r += t;
  10366. d -= (sp_int128)t * div;
  10367. t = (sp_digit)(d >> 21);
  10368. t = t / (dv << 5);
  10369. r += t;
  10370. d -= (sp_int128)t * div;
  10371. t = (sp_digit)d;
  10372. t = t / div;
  10373. r += t;
  10374. d -= (sp_int128)t * div;
  10375. return r;
  10376. #endif
  10377. }
  10378. static WC_INLINE sp_digit sp_3072_word_div_word_27(sp_digit d, sp_digit div)
  10379. {
  10380. #if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \
  10381. defined(SP_DIV_WORD_USE_DIV)
  10382. return d / div;
  10383. #else
  10384. return (sp_digit)((sp_uint64)(div - d) >> 63);
  10385. #endif
  10386. }
  10387. /* Divide d in a and put remainder into r (m*d + r = a)
  10388. * m is not calculated as it is not needed at this time.
  10389. *
  10390. * Full implementation.
  10391. *
  10392. * a Number to be divided.
  10393. * d Number to divide with.
  10394. * m Multiplier result.
  10395. * r Remainder from the division.
  10396. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  10397. */
  10398. static int sp_3072_div_27(const sp_digit* a, const sp_digit* d,
  10399. const sp_digit* m, sp_digit* r)
  10400. {
  10401. int i;
  10402. #ifndef WOLFSSL_SP_DIV_64
  10403. #endif
  10404. sp_digit dv;
  10405. sp_digit r1;
  10406. #ifdef WOLFSSL_SP_SMALL_STACK
  10407. sp_digit* t1 = NULL;
  10408. #else
  10409. sp_digit t1[4 * 27 + 3];
  10410. #endif
  10411. sp_digit* t2 = NULL;
  10412. sp_digit* sd = NULL;
  10413. int err = MP_OKAY;
  10414. (void)m;
  10415. #ifdef WOLFSSL_SP_SMALL_STACK
  10416. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 27 + 3), NULL,
  10417. DYNAMIC_TYPE_TMP_BUFFER);
  10418. if (t1 == NULL)
  10419. err = MEMORY_E;
  10420. #endif
  10421. (void)m;
  10422. if (err == MP_OKAY) {
  10423. t2 = t1 + 54 + 1;
  10424. sd = t2 + 27 + 1;
  10425. sp_3072_mul_d_27(sd, d, (sp_digit)1 << 3);
  10426. sp_3072_mul_d_54(t1, a, (sp_digit)1 << 3);
  10427. dv = sd[26];
  10428. t1[27 + 27] += t1[27 + 27 - 1] >> 57;
  10429. t1[27 + 27 - 1] &= 0x1ffffffffffffffL;
  10430. for (i=27; i>=0; i--) {
  10431. r1 = sp_3072_div_word_27(t1[27 + i], t1[27 + i - 1], dv);
  10432. sp_3072_mul_d_27(t2, sd, r1);
  10433. (void)sp_3072_sub_27(&t1[i], &t1[i], t2);
  10434. sp_3072_norm_27(&t1[i]);
  10435. t1[27 + i] -= t2[27];
  10436. t1[27 + i] += t1[27 + i - 1] >> 57;
  10437. t1[27 + i - 1] &= 0x1ffffffffffffffL;
  10438. r1 = sp_3072_div_word_27(-t1[27 + i], -t1[27 + i - 1], dv);
  10439. r1 -= t1[27 + i];
  10440. sp_3072_mul_d_27(t2, sd, r1);
  10441. (void)sp_3072_add_27(&t1[i], &t1[i], t2);
  10442. t1[27 + i] += t1[27 + i - 1] >> 57;
  10443. t1[27 + i - 1] &= 0x1ffffffffffffffL;
  10444. }
  10445. t1[27 - 1] += t1[27 - 2] >> 57;
  10446. t1[27 - 2] &= 0x1ffffffffffffffL;
  10447. r1 = sp_3072_word_div_word_27(t1[27 - 1], dv);
  10448. sp_3072_mul_d_27(t2, sd, r1);
  10449. sp_3072_sub_27(t1, t1, t2);
  10450. XMEMCPY(r, t1, sizeof(*r) * 54U);
  10451. for (i=0; i<26; i++) {
  10452. r[i+1] += r[i] >> 57;
  10453. r[i] &= 0x1ffffffffffffffL;
  10454. }
  10455. sp_3072_cond_add_27(r, r, sd, r[26] >> 63);
  10456. sp_3072_norm_27(r);
  10457. sp_3072_rshift_27(r, r, 3);
  10458. }
  10459. #ifdef WOLFSSL_SP_SMALL_STACK
  10460. if (t1 != NULL)
  10461. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  10462. #endif
  10463. return err;
  10464. }
  10465. /* Reduce a modulo m into r. (r = a mod m)
  10466. *
  10467. * r A single precision number that is the reduced result.
  10468. * a A single precision number that is to be reduced.
  10469. * m A single precision number that is the modulus to reduce with.
  10470. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  10471. */
  10472. static int sp_3072_mod_27(sp_digit* r, const sp_digit* a, const sp_digit* m)
  10473. {
  10474. return sp_3072_div_27(a, m, NULL, r);
  10475. }
  10476. /* Modular exponentiate a to the e mod m. (r = a^e mod m)
  10477. *
  10478. * r A single precision number that is the result of the operation.
  10479. * a A single precision number being exponentiated.
  10480. * e A single precision number that is the exponent.
  10481. * bits The number of bits in the exponent.
  10482. * m A single precision number that is the modulus.
  10483. * returns 0 on success.
  10484. * returns MEMORY_E on dynamic memory allocation failure.
  10485. * returns MP_VAL when base is even or exponent is 0.
  10486. */
  10487. static int sp_3072_mod_exp_27(sp_digit* r, const sp_digit* a, const sp_digit* e,
  10488. int bits, const sp_digit* m, int reduceA)
  10489. {
  10490. #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
  10491. #ifdef WOLFSSL_SP_SMALL_STACK
  10492. sp_digit* td = NULL;
  10493. #else
  10494. sp_digit td[3 * 54];
  10495. #endif
  10496. sp_digit* t[3] = {0, 0, 0};
  10497. sp_digit* norm = NULL;
  10498. sp_digit mp = 1;
  10499. sp_digit n;
  10500. int i;
  10501. int c;
  10502. byte y;
  10503. int err = MP_OKAY;
  10504. if (bits == 0) {
  10505. err = MP_VAL;
  10506. }
  10507. #ifdef WOLFSSL_SP_SMALL_STACK
  10508. if (err == MP_OKAY) {
  10509. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 27 * 2, NULL,
  10510. DYNAMIC_TYPE_TMP_BUFFER);
  10511. if (td == NULL)
  10512. err = MEMORY_E;
  10513. }
  10514. #endif
  10515. if (err == MP_OKAY) {
  10516. norm = td;
  10517. for (i=0; i<3; i++) {
  10518. t[i] = td + (i * 27 * 2);
  10519. XMEMSET(t[i], 0, sizeof(sp_digit) * 27U * 2U);
  10520. }
  10521. sp_3072_mont_setup(m, &mp);
  10522. sp_3072_mont_norm_27(norm, m);
  10523. if (reduceA != 0) {
  10524. err = sp_3072_mod_27(t[1], a, m);
  10525. }
  10526. else {
  10527. XMEMCPY(t[1], a, sizeof(sp_digit) * 27U);
  10528. }
  10529. }
  10530. if (err == MP_OKAY) {
  10531. sp_3072_mul_27(t[1], t[1], norm);
  10532. err = sp_3072_mod_27(t[1], t[1], m);
  10533. }
  10534. if (err == MP_OKAY) {
  10535. i = bits / 57;
  10536. c = bits % 57;
  10537. n = e[i--] << (57 - c);
  10538. for (; ; c--) {
  10539. if (c == 0) {
  10540. if (i == -1) {
  10541. break;
  10542. }
  10543. n = e[i--];
  10544. c = 57;
  10545. }
  10546. y = (int)((n >> 56) & 1);
  10547. n <<= 1;
  10548. sp_3072_mont_mul_27(t[y^1], t[0], t[1], m, mp);
  10549. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  10550. ((size_t)t[1] & addr_mask[y])),
  10551. sizeof(*t[2]) * 27 * 2);
  10552. sp_3072_mont_sqr_27(t[2], t[2], m, mp);
  10553. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  10554. ((size_t)t[1] & addr_mask[y])), t[2],
  10555. sizeof(*t[2]) * 27 * 2);
  10556. }
  10557. sp_3072_mont_reduce_27(t[0], m, mp);
  10558. n = sp_3072_cmp_27(t[0], m);
  10559. sp_3072_cond_sub_27(t[0], t[0], m, ~(n >> 63));
  10560. XMEMCPY(r, t[0], sizeof(*r) * 27 * 2);
  10561. }
  10562. #ifdef WOLFSSL_SP_SMALL_STACK
  10563. if (td != NULL)
  10564. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  10565. #endif
  10566. return err;
  10567. #elif !defined(WC_NO_CACHE_RESISTANT)
  10568. #ifdef WOLFSSL_SP_SMALL_STACK
  10569. sp_digit* td = NULL;
  10570. #else
  10571. sp_digit td[3 * 54];
  10572. #endif
  10573. sp_digit* t[3] = {0, 0, 0};
  10574. sp_digit* norm = NULL;
  10575. sp_digit mp = 1;
  10576. sp_digit n;
  10577. int i;
  10578. int c;
  10579. byte y;
  10580. int err = MP_OKAY;
  10581. if (bits == 0) {
  10582. err = MP_VAL;
  10583. }
  10584. #ifdef WOLFSSL_SP_SMALL_STACK
  10585. if (err == MP_OKAY) {
  10586. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 27 * 2, NULL,
  10587. DYNAMIC_TYPE_TMP_BUFFER);
  10588. if (td == NULL)
  10589. err = MEMORY_E;
  10590. }
  10591. #endif
  10592. if (err == MP_OKAY) {
  10593. norm = td;
  10594. for (i=0; i<3; i++) {
  10595. t[i] = td + (i * 27 * 2);
  10596. }
  10597. sp_3072_mont_setup(m, &mp);
  10598. sp_3072_mont_norm_27(norm, m);
  10599. if (reduceA != 0) {
  10600. err = sp_3072_mod_27(t[1], a, m);
  10601. if (err == MP_OKAY) {
  10602. sp_3072_mul_27(t[1], t[1], norm);
  10603. err = sp_3072_mod_27(t[1], t[1], m);
  10604. }
  10605. }
  10606. else {
  10607. sp_3072_mul_27(t[1], a, norm);
  10608. err = sp_3072_mod_27(t[1], t[1], m);
  10609. }
  10610. }
  10611. if (err == MP_OKAY) {
  10612. i = bits / 57;
  10613. c = bits % 57;
  10614. n = e[i--] << (57 - c);
  10615. for (; ; c--) {
  10616. if (c == 0) {
  10617. if (i == -1) {
  10618. break;
  10619. }
  10620. n = e[i--];
  10621. c = 57;
  10622. }
  10623. y = (int)((n >> 56) & 1);
  10624. n <<= 1;
  10625. sp_3072_mont_mul_27(t[y^1], t[0], t[1], m, mp);
  10626. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  10627. ((size_t)t[1] & addr_mask[y])),
  10628. sizeof(*t[2]) * 27 * 2);
  10629. sp_3072_mont_sqr_27(t[2], t[2], m, mp);
  10630. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  10631. ((size_t)t[1] & addr_mask[y])), t[2],
  10632. sizeof(*t[2]) * 27 * 2);
  10633. }
  10634. sp_3072_mont_reduce_27(t[0], m, mp);
  10635. n = sp_3072_cmp_27(t[0], m);
  10636. sp_3072_cond_sub_27(t[0], t[0], m, ~(n >> 63));
  10637. XMEMCPY(r, t[0], sizeof(*r) * 27 * 2);
  10638. }
  10639. #ifdef WOLFSSL_SP_SMALL_STACK
  10640. if (td != NULL)
  10641. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  10642. #endif
  10643. return err;
  10644. #else
  10645. #ifdef WOLFSSL_SP_SMALL_STACK
  10646. sp_digit* td = NULL;
  10647. #else
  10648. sp_digit td[(32 * 54) + 54];
  10649. #endif
  10650. sp_digit* t[32];
  10651. sp_digit* rt = NULL;
  10652. sp_digit* norm = NULL;
  10653. sp_digit mp = 1;
  10654. sp_digit n;
  10655. int i;
  10656. int c;
  10657. byte y;
  10658. int err = MP_OKAY;
  10659. if (bits == 0) {
  10660. err = MP_VAL;
  10661. }
  10662. #ifdef WOLFSSL_SP_SMALL_STACK
  10663. if (err == MP_OKAY) {
  10664. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((32 * 54) + 54), NULL,
  10665. DYNAMIC_TYPE_TMP_BUFFER);
  10666. if (td == NULL)
  10667. err = MEMORY_E;
  10668. }
  10669. #endif
  10670. if (err == MP_OKAY) {
  10671. norm = td;
  10672. for (i=0; i<32; i++)
  10673. t[i] = td + i * 54;
  10674. rt = td + 1728;
  10675. sp_3072_mont_setup(m, &mp);
  10676. sp_3072_mont_norm_27(norm, m);
  10677. if (reduceA != 0) {
  10678. err = sp_3072_mod_27(t[1], a, m);
  10679. if (err == MP_OKAY) {
  10680. sp_3072_mul_27(t[1], t[1], norm);
  10681. err = sp_3072_mod_27(t[1], t[1], m);
  10682. }
  10683. }
  10684. else {
  10685. sp_3072_mul_27(t[1], a, norm);
  10686. err = sp_3072_mod_27(t[1], t[1], m);
  10687. }
  10688. }
  10689. if (err == MP_OKAY) {
  10690. sp_3072_mont_sqr_27(t[ 2], t[ 1], m, mp);
  10691. sp_3072_mont_mul_27(t[ 3], t[ 2], t[ 1], m, mp);
  10692. sp_3072_mont_sqr_27(t[ 4], t[ 2], m, mp);
  10693. sp_3072_mont_mul_27(t[ 5], t[ 3], t[ 2], m, mp);
  10694. sp_3072_mont_sqr_27(t[ 6], t[ 3], m, mp);
  10695. sp_3072_mont_mul_27(t[ 7], t[ 4], t[ 3], m, mp);
  10696. sp_3072_mont_sqr_27(t[ 8], t[ 4], m, mp);
  10697. sp_3072_mont_mul_27(t[ 9], t[ 5], t[ 4], m, mp);
  10698. sp_3072_mont_sqr_27(t[10], t[ 5], m, mp);
  10699. sp_3072_mont_mul_27(t[11], t[ 6], t[ 5], m, mp);
  10700. sp_3072_mont_sqr_27(t[12], t[ 6], m, mp);
  10701. sp_3072_mont_mul_27(t[13], t[ 7], t[ 6], m, mp);
  10702. sp_3072_mont_sqr_27(t[14], t[ 7], m, mp);
  10703. sp_3072_mont_mul_27(t[15], t[ 8], t[ 7], m, mp);
  10704. sp_3072_mont_sqr_27(t[16], t[ 8], m, mp);
  10705. sp_3072_mont_mul_27(t[17], t[ 9], t[ 8], m, mp);
  10706. sp_3072_mont_sqr_27(t[18], t[ 9], m, mp);
  10707. sp_3072_mont_mul_27(t[19], t[10], t[ 9], m, mp);
  10708. sp_3072_mont_sqr_27(t[20], t[10], m, mp);
  10709. sp_3072_mont_mul_27(t[21], t[11], t[10], m, mp);
  10710. sp_3072_mont_sqr_27(t[22], t[11], m, mp);
  10711. sp_3072_mont_mul_27(t[23], t[12], t[11], m, mp);
  10712. sp_3072_mont_sqr_27(t[24], t[12], m, mp);
  10713. sp_3072_mont_mul_27(t[25], t[13], t[12], m, mp);
  10714. sp_3072_mont_sqr_27(t[26], t[13], m, mp);
  10715. sp_3072_mont_mul_27(t[27], t[14], t[13], m, mp);
  10716. sp_3072_mont_sqr_27(t[28], t[14], m, mp);
  10717. sp_3072_mont_mul_27(t[29], t[15], t[14], m, mp);
  10718. sp_3072_mont_sqr_27(t[30], t[15], m, mp);
  10719. sp_3072_mont_mul_27(t[31], t[16], t[15], m, mp);
  10720. bits = ((bits + 4) / 5) * 5;
  10721. i = ((bits + 56) / 57) - 1;
  10722. c = bits % 57;
  10723. if (c == 0) {
  10724. c = 57;
  10725. }
  10726. if (i < 27) {
  10727. n = e[i--] << (64 - c);
  10728. }
  10729. else {
  10730. n = 0;
  10731. i--;
  10732. }
  10733. if (c < 5) {
  10734. n |= e[i--] << (7 - c);
  10735. c += 57;
  10736. }
  10737. y = (int)((n >> 59) & 0x1f);
  10738. n <<= 5;
  10739. c -= 5;
  10740. XMEMCPY(rt, t[y], sizeof(sp_digit) * 54);
  10741. while ((i >= 0) || (c >= 5)) {
  10742. if (c >= 5) {
  10743. y = (byte)((n >> 59) & 0x1f);
  10744. n <<= 5;
  10745. c -= 5;
  10746. }
  10747. else if (c == 0) {
  10748. n = e[i--] << 7;
  10749. y = (byte)((n >> 59) & 0x1f);
  10750. n <<= 5;
  10751. c = 52;
  10752. }
  10753. else {
  10754. y = (byte)((n >> 59) & 0x1f);
  10755. n = e[i--] << 7;
  10756. c = 5 - c;
  10757. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  10758. n <<= c;
  10759. c = 57 - c;
  10760. }
  10761. sp_3072_mont_sqr_27(rt, rt, m, mp);
  10762. sp_3072_mont_sqr_27(rt, rt, m, mp);
  10763. sp_3072_mont_sqr_27(rt, rt, m, mp);
  10764. sp_3072_mont_sqr_27(rt, rt, m, mp);
  10765. sp_3072_mont_sqr_27(rt, rt, m, mp);
  10766. sp_3072_mont_mul_27(rt, rt, t[y], m, mp);
  10767. }
  10768. sp_3072_mont_reduce_27(rt, m, mp);
  10769. n = sp_3072_cmp_27(rt, m);
  10770. sp_3072_cond_sub_27(rt, rt, m, ~(n >> 63));
  10771. XMEMCPY(r, rt, sizeof(sp_digit) * 54);
  10772. }
  10773. #ifdef WOLFSSL_SP_SMALL_STACK
  10774. if (td != NULL)
  10775. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  10776. #endif
  10777. return err;
  10778. #endif
  10779. }
  10780. #endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */
  10781. /* r = 2^n mod m where n is the number of bits to reduce by.
  10782. * Given m must be 3072 bits, just need to subtract.
  10783. *
  10784. * r A single precision number.
  10785. * m A single precision number.
  10786. */
  10787. static void sp_3072_mont_norm_54(sp_digit* r, const sp_digit* m)
  10788. {
  10789. /* Set r = 2^n - 1. */
  10790. int i;
  10791. for (i = 0; i < 48; i += 8) {
  10792. r[i + 0] = 0x1ffffffffffffffL;
  10793. r[i + 1] = 0x1ffffffffffffffL;
  10794. r[i + 2] = 0x1ffffffffffffffL;
  10795. r[i + 3] = 0x1ffffffffffffffL;
  10796. r[i + 4] = 0x1ffffffffffffffL;
  10797. r[i + 5] = 0x1ffffffffffffffL;
  10798. r[i + 6] = 0x1ffffffffffffffL;
  10799. r[i + 7] = 0x1ffffffffffffffL;
  10800. }
  10801. r[48] = 0x1ffffffffffffffL;
  10802. r[49] = 0x1ffffffffffffffL;
  10803. r[50] = 0x1ffffffffffffffL;
  10804. r[51] = 0x1ffffffffffffffL;
  10805. r[52] = 0x1ffffffffffffffL;
  10806. r[53] = 0x7ffffffffffffL;
  10807. /* r = (2^n - 1) mod n */
  10808. (void)sp_3072_sub_54(r, r, m);
  10809. /* Add one so r = 2^n mod m */
  10810. r[0] += 1;
  10811. }
  10812. /* Compare a with b in constant time.
  10813. *
  10814. * a A single precision integer.
  10815. * b A single precision integer.
  10816. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  10817. * respectively.
  10818. */
  10819. static sp_digit sp_3072_cmp_54(const sp_digit* a, const sp_digit* b)
  10820. {
  10821. sp_digit r = 0;
  10822. int i;
  10823. r |= (a[53] - b[53]) & (0 - (sp_digit)1);
  10824. r |= (a[52] - b[52]) & ~(((sp_digit)0 - r) >> 56);
  10825. r |= (a[51] - b[51]) & ~(((sp_digit)0 - r) >> 56);
  10826. r |= (a[50] - b[50]) & ~(((sp_digit)0 - r) >> 56);
  10827. r |= (a[49] - b[49]) & ~(((sp_digit)0 - r) >> 56);
  10828. r |= (a[48] - b[48]) & ~(((sp_digit)0 - r) >> 56);
  10829. for (i = 40; i >= 0; i -= 8) {
  10830. r |= (a[i + 7] - b[i + 7]) & ~(((sp_digit)0 - r) >> 56);
  10831. r |= (a[i + 6] - b[i + 6]) & ~(((sp_digit)0 - r) >> 56);
  10832. r |= (a[i + 5] - b[i + 5]) & ~(((sp_digit)0 - r) >> 56);
  10833. r |= (a[i + 4] - b[i + 4]) & ~(((sp_digit)0 - r) >> 56);
  10834. r |= (a[i + 3] - b[i + 3]) & ~(((sp_digit)0 - r) >> 56);
  10835. r |= (a[i + 2] - b[i + 2]) & ~(((sp_digit)0 - r) >> 56);
  10836. r |= (a[i + 1] - b[i + 1]) & ~(((sp_digit)0 - r) >> 56);
  10837. r |= (a[i + 0] - b[i + 0]) & ~(((sp_digit)0 - r) >> 56);
  10838. }
  10839. return r;
  10840. }
  10841. /* Conditionally subtract b from a using the mask m.
  10842. * m is -1 to subtract and 0 when not.
  10843. *
  10844. * r A single precision number representing condition subtract result.
  10845. * a A single precision number to subtract from.
  10846. * b A single precision number to subtract.
  10847. * m Mask value to apply.
  10848. */
  10849. static void sp_3072_cond_sub_54(sp_digit* r, const sp_digit* a,
  10850. const sp_digit* b, const sp_digit m)
  10851. {
  10852. int i;
  10853. for (i = 0; i < 48; i += 8) {
  10854. r[i + 0] = a[i + 0] - (b[i + 0] & m);
  10855. r[i + 1] = a[i + 1] - (b[i + 1] & m);
  10856. r[i + 2] = a[i + 2] - (b[i + 2] & m);
  10857. r[i + 3] = a[i + 3] - (b[i + 3] & m);
  10858. r[i + 4] = a[i + 4] - (b[i + 4] & m);
  10859. r[i + 5] = a[i + 5] - (b[i + 5] & m);
  10860. r[i + 6] = a[i + 6] - (b[i + 6] & m);
  10861. r[i + 7] = a[i + 7] - (b[i + 7] & m);
  10862. }
  10863. r[48] = a[48] - (b[48] & m);
  10864. r[49] = a[49] - (b[49] & m);
  10865. r[50] = a[50] - (b[50] & m);
  10866. r[51] = a[51] - (b[51] & m);
  10867. r[52] = a[52] - (b[52] & m);
  10868. r[53] = a[53] - (b[53] & m);
  10869. }
  10870. /* Mul a by scalar b and add into r. (r += a * b)
  10871. *
  10872. * r A single precision integer.
  10873. * a A single precision integer.
  10874. * b A scalar.
  10875. */
  10876. SP_NOINLINE static void sp_3072_mul_add_54(sp_digit* r, const sp_digit* a,
  10877. const sp_digit b)
  10878. {
  10879. sp_int128 tb = b;
  10880. sp_int128 t[8];
  10881. int i;
  10882. t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL);
  10883. for (i = 0; i < 48; i += 8) {
  10884. t[1] = tb * a[i+1];
  10885. r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
  10886. t[2] = tb * a[i+2];
  10887. r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
  10888. t[3] = tb * a[i+3];
  10889. r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));
  10890. t[4] = tb * a[i+4];
  10891. r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));
  10892. t[5] = tb * a[i+5];
  10893. r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));
  10894. t[6] = tb * a[i+6];
  10895. r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL));
  10896. t[7] = tb * a[i+7];
  10897. r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL));
  10898. t[0] = tb * a[i+8];
  10899. r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL));
  10900. }
  10901. t[1] = tb * a[49];
  10902. r[49] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
  10903. t[2] = tb * a[50];
  10904. r[50] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
  10905. t[3] = tb * a[51];
  10906. r[51] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));
  10907. t[4] = tb * a[52];
  10908. r[52] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));
  10909. t[5] = tb * a[53];
  10910. r[53] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));
  10911. r[54] += (sp_digit)(t[5] >> 57);
  10912. }
  10913. /* Shift the result in the high 3072 bits down to the bottom.
  10914. *
  10915. * r A single precision number.
  10916. * a A single precision number.
  10917. */
  10918. static void sp_3072_mont_shift_54(sp_digit* r, const sp_digit* a)
  10919. {
  10920. int i;
  10921. sp_int128 n = a[53] >> 51;
  10922. n += ((sp_int128)a[54]) << 6;
  10923. for (i = 0; i < 48; i += 8) {
  10924. r[i + 0] = n & 0x1ffffffffffffffL;
  10925. n >>= 57; n += ((sp_int128)a[i + 55]) << 6;
  10926. r[i + 1] = n & 0x1ffffffffffffffL;
  10927. n >>= 57; n += ((sp_int128)a[i + 56]) << 6;
  10928. r[i + 2] = n & 0x1ffffffffffffffL;
  10929. n >>= 57; n += ((sp_int128)a[i + 57]) << 6;
  10930. r[i + 3] = n & 0x1ffffffffffffffL;
  10931. n >>= 57; n += ((sp_int128)a[i + 58]) << 6;
  10932. r[i + 4] = n & 0x1ffffffffffffffL;
  10933. n >>= 57; n += ((sp_int128)a[i + 59]) << 6;
  10934. r[i + 5] = n & 0x1ffffffffffffffL;
  10935. n >>= 57; n += ((sp_int128)a[i + 60]) << 6;
  10936. r[i + 6] = n & 0x1ffffffffffffffL;
  10937. n >>= 57; n += ((sp_int128)a[i + 61]) << 6;
  10938. r[i + 7] = n & 0x1ffffffffffffffL;
  10939. n >>= 57; n += ((sp_int128)a[i + 62]) << 6;
  10940. }
  10941. r[48] = n & 0x1ffffffffffffffL; n >>= 57; n += ((sp_int128)a[103]) << 6;
  10942. r[49] = n & 0x1ffffffffffffffL; n >>= 57; n += ((sp_int128)a[104]) << 6;
  10943. r[50] = n & 0x1ffffffffffffffL; n >>= 57; n += ((sp_int128)a[105]) << 6;
  10944. r[51] = n & 0x1ffffffffffffffL; n >>= 57; n += ((sp_int128)a[106]) << 6;
  10945. r[52] = n & 0x1ffffffffffffffL; n >>= 57; n += ((sp_int128)a[107]) << 6;
  10946. r[53] = (sp_digit)n;
  10947. XMEMSET(&r[54], 0, sizeof(*r) * 54U);
  10948. }
  10949. /* Reduce the number back to 3072 bits using Montgomery reduction.
  10950. *
  10951. * a A single precision number to reduce in place.
  10952. * m The single precision number representing the modulus.
  10953. * mp The digit representing the negative inverse of m mod 2^n.
  10954. */
  10955. static void sp_3072_mont_reduce_54(sp_digit* a, const sp_digit* m, sp_digit mp)
  10956. {
  10957. int i;
  10958. sp_digit mu;
  10959. sp_digit over;
  10960. sp_3072_norm_54(a + 54);
  10961. #ifdef WOLFSSL_SP_DH
  10962. if (mp != 1) {
  10963. for (i=0; i<53; i++) {
  10964. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1ffffffffffffffL;
  10965. sp_3072_mul_add_54(a+i, m, mu);
  10966. a[i+1] += a[i] >> 57;
  10967. }
  10968. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x7ffffffffffffL;
  10969. sp_3072_mul_add_54(a+i, m, mu);
  10970. a[i+1] += a[i] >> 57;
  10971. a[i] &= 0x1ffffffffffffffL;
  10972. }
  10973. else {
  10974. for (i=0; i<53; i++) {
  10975. mu = a[i] & 0x1ffffffffffffffL;
  10976. sp_3072_mul_add_54(a+i, m, mu);
  10977. a[i+1] += a[i] >> 57;
  10978. }
  10979. mu = a[i] & 0x7ffffffffffffL;
  10980. sp_3072_mul_add_54(a+i, m, mu);
  10981. a[i+1] += a[i] >> 57;
  10982. a[i] &= 0x1ffffffffffffffL;
  10983. }
  10984. #else
  10985. for (i=0; i<53; i++) {
  10986. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1ffffffffffffffL;
  10987. sp_3072_mul_add_54(a+i, m, mu);
  10988. a[i+1] += a[i] >> 57;
  10989. }
  10990. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x7ffffffffffffL;
  10991. sp_3072_mul_add_54(a+i, m, mu);
  10992. a[i+1] += a[i] >> 57;
  10993. a[i] &= 0x1ffffffffffffffL;
  10994. #endif
  10995. sp_3072_mont_shift_54(a, a);
  10996. over = a[53] - m[53];
  10997. sp_3072_cond_sub_54(a, a, m, ~((over - 1) >> 63));
  10998. sp_3072_norm_54(a);
  10999. }
  11000. /* Multiply two Montgomery form numbers mod the modulus (prime).
  11001. * (r = a * b mod m)
  11002. *
  11003. * r Result of multiplication.
  11004. * a First number to multiply in Montgomery form.
  11005. * b Second number to multiply in Montgomery form.
  11006. * m Modulus (prime).
  11007. * mp Montgomery multiplier.
  11008. */
  11009. SP_NOINLINE static void sp_3072_mont_mul_54(sp_digit* r, const sp_digit* a,
  11010. const sp_digit* b, const sp_digit* m, sp_digit mp)
  11011. {
  11012. sp_3072_mul_54(r, a, b);
  11013. sp_3072_mont_reduce_54(r, m, mp);
  11014. }
  11015. /* Square the Montgomery form number. (r = a * a mod m)
  11016. *
  11017. * r Result of squaring.
  11018. * a Number to square in Montgomery form.
  11019. * m Modulus (prime).
  11020. * mp Montgomery multiplier.
  11021. */
  11022. SP_NOINLINE static void sp_3072_mont_sqr_54(sp_digit* r, const sp_digit* a,
  11023. const sp_digit* m, sp_digit mp)
  11024. {
  11025. sp_3072_sqr_54(r, a);
  11026. sp_3072_mont_reduce_54(r, m, mp);
  11027. }
  11028. /* Multiply a by scalar b into r. (r = a * b)
  11029. *
  11030. * r A single precision integer.
  11031. * a A single precision integer.
  11032. * b A scalar.
  11033. */
  11034. SP_NOINLINE static void sp_3072_mul_d_108(sp_digit* r, const sp_digit* a,
  11035. sp_digit b)
  11036. {
  11037. sp_int128 tb = b;
  11038. sp_int128 t = 0;
  11039. sp_digit t2;
  11040. sp_int128 p[4];
  11041. int i;
  11042. for (i = 0; i < 108; i += 4) {
  11043. p[0] = tb * a[i + 0];
  11044. p[1] = tb * a[i + 1];
  11045. p[2] = tb * a[i + 2];
  11046. p[3] = tb * a[i + 3];
  11047. t += p[0];
  11048. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  11049. t >>= 57;
  11050. r[i + 0] = (sp_digit)t2;
  11051. t += p[1];
  11052. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  11053. t >>= 57;
  11054. r[i + 1] = (sp_digit)t2;
  11055. t += p[2];
  11056. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  11057. t >>= 57;
  11058. r[i + 2] = (sp_digit)t2;
  11059. t += p[3];
  11060. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  11061. t >>= 57;
  11062. r[i + 3] = (sp_digit)t2;
  11063. }
  11064. r[108] = (sp_digit)(t & 0x1ffffffffffffffL);
  11065. }
  11066. #ifndef WOLFSSL_SP_SMALL
  11067. /* Conditionally add a and b using the mask m.
  11068. * m is -1 to add and 0 when not.
  11069. *
  11070. * r A single precision number representing conditional add result.
  11071. * a A single precision number to add with.
  11072. * b A single precision number to add.
  11073. * m Mask value to apply.
  11074. */
  11075. static void sp_3072_cond_add_54(sp_digit* r, const sp_digit* a,
  11076. const sp_digit* b, const sp_digit m)
  11077. {
  11078. int i;
  11079. for (i = 0; i < 48; i += 8) {
  11080. r[i + 0] = a[i + 0] + (b[i + 0] & m);
  11081. r[i + 1] = a[i + 1] + (b[i + 1] & m);
  11082. r[i + 2] = a[i + 2] + (b[i + 2] & m);
  11083. r[i + 3] = a[i + 3] + (b[i + 3] & m);
  11084. r[i + 4] = a[i + 4] + (b[i + 4] & m);
  11085. r[i + 5] = a[i + 5] + (b[i + 5] & m);
  11086. r[i + 6] = a[i + 6] + (b[i + 6] & m);
  11087. r[i + 7] = a[i + 7] + (b[i + 7] & m);
  11088. }
  11089. r[48] = a[48] + (b[48] & m);
  11090. r[49] = a[49] + (b[49] & m);
  11091. r[50] = a[50] + (b[50] & m);
  11092. r[51] = a[51] + (b[51] & m);
  11093. r[52] = a[52] + (b[52] & m);
  11094. r[53] = a[53] + (b[53] & m);
  11095. }
  11096. #endif /* !WOLFSSL_SP_SMALL */
  11097. SP_NOINLINE static void sp_3072_rshift_54(sp_digit* r, const sp_digit* a,
  11098. byte n)
  11099. {
  11100. int i;
  11101. for (i=0; i<48; i += 8) {
  11102. r[i+0] = (a[i+0] >> n) | ((a[i+1] << (57 - n)) & 0x1ffffffffffffffL);
  11103. r[i+1] = (a[i+1] >> n) | ((a[i+2] << (57 - n)) & 0x1ffffffffffffffL);
  11104. r[i+2] = (a[i+2] >> n) | ((a[i+3] << (57 - n)) & 0x1ffffffffffffffL);
  11105. r[i+3] = (a[i+3] >> n) | ((a[i+4] << (57 - n)) & 0x1ffffffffffffffL);
  11106. r[i+4] = (a[i+4] >> n) | ((a[i+5] << (57 - n)) & 0x1ffffffffffffffL);
  11107. r[i+5] = (a[i+5] >> n) | ((a[i+6] << (57 - n)) & 0x1ffffffffffffffL);
  11108. r[i+6] = (a[i+6] >> n) | ((a[i+7] << (57 - n)) & 0x1ffffffffffffffL);
  11109. r[i+7] = (a[i+7] >> n) | ((a[i+8] << (57 - n)) & 0x1ffffffffffffffL);
  11110. }
  11111. r[48] = (a[48] >> n) | ((a[49] << (57 - n)) & 0x1ffffffffffffffL);
  11112. r[49] = (a[49] >> n) | ((a[50] << (57 - n)) & 0x1ffffffffffffffL);
  11113. r[50] = (a[50] >> n) | ((a[51] << (57 - n)) & 0x1ffffffffffffffL);
  11114. r[51] = (a[51] >> n) | ((a[52] << (57 - n)) & 0x1ffffffffffffffL);
  11115. r[52] = (a[52] >> n) | ((a[53] << (57 - n)) & 0x1ffffffffffffffL);
  11116. r[53] = a[53] >> n;
  11117. }
  11118. static WC_INLINE sp_digit sp_3072_div_word_54(sp_digit d1, sp_digit d0,
  11119. sp_digit div)
  11120. {
  11121. #ifdef SP_USE_DIVTI3
  11122. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  11123. return d / div;
  11124. #elif defined(__x86_64__) || defined(__i386__)
  11125. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  11126. sp_uint64 lo = (sp_uint64)d;
  11127. sp_digit hi = (sp_digit)(d >> 64);
  11128. __asm__ __volatile__ (
  11129. "idiv %2"
  11130. : "+a" (lo)
  11131. : "d" (hi), "r" (div)
  11132. : "cc"
  11133. );
  11134. return (sp_digit)lo;
  11135. #elif !defined(__aarch64__) && !defined(SP_DIV_WORD_USE_DIV)
  11136. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  11137. sp_digit dv = (div >> 1) + 1;
  11138. sp_digit t1 = (sp_digit)(d >> 57);
  11139. sp_digit t0 = (sp_digit)(d & 0x1ffffffffffffffL);
  11140. sp_digit t2;
  11141. sp_digit sign;
  11142. sp_digit r;
  11143. int i;
  11144. sp_int128 m;
  11145. r = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  11146. t1 -= dv & (0 - r);
  11147. for (i = 55; i >= 1; i--) {
  11148. t1 += t1 + (((sp_uint64)t0 >> 56) & 1);
  11149. t0 <<= 1;
  11150. t2 = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  11151. r += r + t2;
  11152. t1 -= dv & (0 - t2);
  11153. t1 += t2;
  11154. }
  11155. r += r + 1;
  11156. m = d - ((sp_int128)r * div);
  11157. r += (sp_digit)(m >> 57);
  11158. m = d - ((sp_int128)r * div);
  11159. r += (sp_digit)(m >> 114) - (sp_digit)(d >> 114);
  11160. m = d - ((sp_int128)r * div);
  11161. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  11162. m *= sign;
  11163. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  11164. r += sign * t2;
  11165. m = d - ((sp_int128)r * div);
  11166. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  11167. m *= sign;
  11168. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  11169. r += sign * t2;
  11170. return r;
  11171. #else
  11172. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  11173. sp_digit r = 0;
  11174. sp_digit t;
  11175. sp_digit dv = (div >> 26) + 1;
  11176. t = (sp_digit)(d >> 52);
  11177. t = (t / dv) << 26;
  11178. r += t;
  11179. d -= (sp_int128)t * div;
  11180. t = (sp_digit)(d >> 21);
  11181. t = t / (dv << 5);
  11182. r += t;
  11183. d -= (sp_int128)t * div;
  11184. t = (sp_digit)d;
  11185. t = t / div;
  11186. r += t;
  11187. d -= (sp_int128)t * div;
  11188. return r;
  11189. #endif
  11190. }
  11191. static WC_INLINE sp_digit sp_3072_word_div_word_54(sp_digit d, sp_digit div)
  11192. {
  11193. #if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \
  11194. defined(SP_DIV_WORD_USE_DIV)
  11195. return d / div;
  11196. #else
  11197. return (sp_digit)((sp_uint64)(div - d) >> 63);
  11198. #endif
  11199. }
  11200. /* Divide d in a and put remainder into r (m*d + r = a)
  11201. * m is not calculated as it is not needed at this time.
  11202. *
  11203. * Full implementation.
  11204. *
  11205. * a Number to be divided.
  11206. * d Number to divide with.
  11207. * m Multiplier result.
  11208. * r Remainder from the division.
  11209. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  11210. */
  11211. static int sp_3072_div_54(const sp_digit* a, const sp_digit* d,
  11212. const sp_digit* m, sp_digit* r)
  11213. {
  11214. int i;
  11215. #ifndef WOLFSSL_SP_DIV_64
  11216. #endif
  11217. sp_digit dv;
  11218. sp_digit r1;
  11219. #ifdef WOLFSSL_SP_SMALL_STACK
  11220. sp_digit* t1 = NULL;
  11221. #else
  11222. sp_digit t1[4 * 54 + 3];
  11223. #endif
  11224. sp_digit* t2 = NULL;
  11225. sp_digit* sd = NULL;
  11226. int err = MP_OKAY;
  11227. (void)m;
  11228. #ifdef WOLFSSL_SP_SMALL_STACK
  11229. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 54 + 3), NULL,
  11230. DYNAMIC_TYPE_TMP_BUFFER);
  11231. if (t1 == NULL)
  11232. err = MEMORY_E;
  11233. #endif
  11234. (void)m;
  11235. if (err == MP_OKAY) {
  11236. t2 = t1 + 108 + 1;
  11237. sd = t2 + 54 + 1;
  11238. sp_3072_mul_d_54(sd, d, (sp_digit)1 << 6);
  11239. sp_3072_mul_d_108(t1, a, (sp_digit)1 << 6);
  11240. dv = sd[53];
  11241. t1[54 + 54] += t1[54 + 54 - 1] >> 57;
  11242. t1[54 + 54 - 1] &= 0x1ffffffffffffffL;
  11243. for (i=54; i>=0; i--) {
  11244. r1 = sp_3072_div_word_54(t1[54 + i], t1[54 + i - 1], dv);
  11245. sp_3072_mul_d_54(t2, sd, r1);
  11246. (void)sp_3072_sub_54(&t1[i], &t1[i], t2);
  11247. sp_3072_norm_54(&t1[i]);
  11248. t1[54 + i] -= t2[54];
  11249. t1[54 + i] += t1[54 + i - 1] >> 57;
  11250. t1[54 + i - 1] &= 0x1ffffffffffffffL;
  11251. r1 = sp_3072_div_word_54(-t1[54 + i], -t1[54 + i - 1], dv);
  11252. r1 -= t1[54 + i];
  11253. sp_3072_mul_d_54(t2, sd, r1);
  11254. (void)sp_3072_add_54(&t1[i], &t1[i], t2);
  11255. t1[54 + i] += t1[54 + i - 1] >> 57;
  11256. t1[54 + i - 1] &= 0x1ffffffffffffffL;
  11257. }
  11258. t1[54 - 1] += t1[54 - 2] >> 57;
  11259. t1[54 - 2] &= 0x1ffffffffffffffL;
  11260. r1 = sp_3072_word_div_word_54(t1[54 - 1], dv);
  11261. sp_3072_mul_d_54(t2, sd, r1);
  11262. sp_3072_sub_54(t1, t1, t2);
  11263. XMEMCPY(r, t1, sizeof(*r) * 108U);
  11264. for (i=0; i<53; i++) {
  11265. r[i+1] += r[i] >> 57;
  11266. r[i] &= 0x1ffffffffffffffL;
  11267. }
  11268. sp_3072_cond_add_54(r, r, sd, r[53] >> 63);
  11269. sp_3072_norm_54(r);
  11270. sp_3072_rshift_54(r, r, 6);
  11271. }
  11272. #ifdef WOLFSSL_SP_SMALL_STACK
  11273. if (t1 != NULL)
  11274. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  11275. #endif
  11276. return err;
  11277. }
  11278. /* Reduce a modulo m into r. (r = a mod m)
  11279. *
  11280. * r A single precision number that is the reduced result.
  11281. * a A single precision number that is to be reduced.
  11282. * m A single precision number that is the modulus to reduce with.
  11283. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  11284. */
  11285. static int sp_3072_mod_54(sp_digit* r, const sp_digit* a, const sp_digit* m)
  11286. {
  11287. return sp_3072_div_54(a, m, NULL, r);
  11288. }
  11289. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  11290. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \
  11291. defined(WOLFSSL_HAVE_SP_DH)
  11292. /* Modular exponentiate a to the e mod m. (r = a^e mod m)
  11293. *
  11294. * r A single precision number that is the result of the operation.
  11295. * a A single precision number being exponentiated.
  11296. * e A single precision number that is the exponent.
  11297. * bits The number of bits in the exponent.
  11298. * m A single precision number that is the modulus.
  11299. * returns 0 on success.
  11300. * returns MEMORY_E on dynamic memory allocation failure.
  11301. * returns MP_VAL when base is even or exponent is 0.
  11302. */
  11303. static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, const sp_digit* e,
  11304. int bits, const sp_digit* m, int reduceA)
  11305. {
  11306. #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
  11307. #ifdef WOLFSSL_SP_SMALL_STACK
  11308. sp_digit* td = NULL;
  11309. #else
  11310. sp_digit td[3 * 108];
  11311. #endif
  11312. sp_digit* t[3] = {0, 0, 0};
  11313. sp_digit* norm = NULL;
  11314. sp_digit mp = 1;
  11315. sp_digit n;
  11316. int i;
  11317. int c;
  11318. byte y;
  11319. int err = MP_OKAY;
  11320. if (bits == 0) {
  11321. err = MP_VAL;
  11322. }
  11323. #ifdef WOLFSSL_SP_SMALL_STACK
  11324. if (err == MP_OKAY) {
  11325. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 54 * 2, NULL,
  11326. DYNAMIC_TYPE_TMP_BUFFER);
  11327. if (td == NULL)
  11328. err = MEMORY_E;
  11329. }
  11330. #endif
  11331. if (err == MP_OKAY) {
  11332. norm = td;
  11333. for (i=0; i<3; i++) {
  11334. t[i] = td + (i * 54 * 2);
  11335. XMEMSET(t[i], 0, sizeof(sp_digit) * 54U * 2U);
  11336. }
  11337. sp_3072_mont_setup(m, &mp);
  11338. sp_3072_mont_norm_54(norm, m);
  11339. if (reduceA != 0) {
  11340. err = sp_3072_mod_54(t[1], a, m);
  11341. }
  11342. else {
  11343. XMEMCPY(t[1], a, sizeof(sp_digit) * 54U);
  11344. }
  11345. }
  11346. if (err == MP_OKAY) {
  11347. sp_3072_mul_54(t[1], t[1], norm);
  11348. err = sp_3072_mod_54(t[1], t[1], m);
  11349. }
  11350. if (err == MP_OKAY) {
  11351. i = bits / 57;
  11352. c = bits % 57;
  11353. n = e[i--] << (57 - c);
  11354. for (; ; c--) {
  11355. if (c == 0) {
  11356. if (i == -1) {
  11357. break;
  11358. }
  11359. n = e[i--];
  11360. c = 57;
  11361. }
  11362. y = (int)((n >> 56) & 1);
  11363. n <<= 1;
  11364. sp_3072_mont_mul_54(t[y^1], t[0], t[1], m, mp);
  11365. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  11366. ((size_t)t[1] & addr_mask[y])),
  11367. sizeof(*t[2]) * 54 * 2);
  11368. sp_3072_mont_sqr_54(t[2], t[2], m, mp);
  11369. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  11370. ((size_t)t[1] & addr_mask[y])), t[2],
  11371. sizeof(*t[2]) * 54 * 2);
  11372. }
  11373. sp_3072_mont_reduce_54(t[0], m, mp);
  11374. n = sp_3072_cmp_54(t[0], m);
  11375. sp_3072_cond_sub_54(t[0], t[0], m, ~(n >> 63));
  11376. XMEMCPY(r, t[0], sizeof(*r) * 54 * 2);
  11377. }
  11378. #ifdef WOLFSSL_SP_SMALL_STACK
  11379. if (td != NULL)
  11380. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  11381. #endif
  11382. return err;
  11383. #elif !defined(WC_NO_CACHE_RESISTANT)
  11384. #ifdef WOLFSSL_SP_SMALL_STACK
  11385. sp_digit* td = NULL;
  11386. #else
  11387. sp_digit td[3 * 108];
  11388. #endif
  11389. sp_digit* t[3] = {0, 0, 0};
  11390. sp_digit* norm = NULL;
  11391. sp_digit mp = 1;
  11392. sp_digit n;
  11393. int i;
  11394. int c;
  11395. byte y;
  11396. int err = MP_OKAY;
  11397. if (bits == 0) {
  11398. err = MP_VAL;
  11399. }
  11400. #ifdef WOLFSSL_SP_SMALL_STACK
  11401. if (err == MP_OKAY) {
  11402. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 54 * 2, NULL,
  11403. DYNAMIC_TYPE_TMP_BUFFER);
  11404. if (td == NULL)
  11405. err = MEMORY_E;
  11406. }
  11407. #endif
  11408. if (err == MP_OKAY) {
  11409. norm = td;
  11410. for (i=0; i<3; i++) {
  11411. t[i] = td + (i * 54 * 2);
  11412. }
  11413. sp_3072_mont_setup(m, &mp);
  11414. sp_3072_mont_norm_54(norm, m);
  11415. if (reduceA != 0) {
  11416. err = sp_3072_mod_54(t[1], a, m);
  11417. if (err == MP_OKAY) {
  11418. sp_3072_mul_54(t[1], t[1], norm);
  11419. err = sp_3072_mod_54(t[1], t[1], m);
  11420. }
  11421. }
  11422. else {
  11423. sp_3072_mul_54(t[1], a, norm);
  11424. err = sp_3072_mod_54(t[1], t[1], m);
  11425. }
  11426. }
  11427. if (err == MP_OKAY) {
  11428. i = bits / 57;
  11429. c = bits % 57;
  11430. n = e[i--] << (57 - c);
  11431. for (; ; c--) {
  11432. if (c == 0) {
  11433. if (i == -1) {
  11434. break;
  11435. }
  11436. n = e[i--];
  11437. c = 57;
  11438. }
  11439. y = (int)((n >> 56) & 1);
  11440. n <<= 1;
  11441. sp_3072_mont_mul_54(t[y^1], t[0], t[1], m, mp);
  11442. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  11443. ((size_t)t[1] & addr_mask[y])),
  11444. sizeof(*t[2]) * 54 * 2);
  11445. sp_3072_mont_sqr_54(t[2], t[2], m, mp);
  11446. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  11447. ((size_t)t[1] & addr_mask[y])), t[2],
  11448. sizeof(*t[2]) * 54 * 2);
  11449. }
  11450. sp_3072_mont_reduce_54(t[0], m, mp);
  11451. n = sp_3072_cmp_54(t[0], m);
  11452. sp_3072_cond_sub_54(t[0], t[0], m, ~(n >> 63));
  11453. XMEMCPY(r, t[0], sizeof(*r) * 54 * 2);
  11454. }
  11455. #ifdef WOLFSSL_SP_SMALL_STACK
  11456. if (td != NULL)
  11457. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  11458. #endif
  11459. return err;
  11460. #else
  11461. #ifdef WOLFSSL_SP_SMALL_STACK
  11462. sp_digit* td = NULL;
  11463. #else
  11464. sp_digit td[(16 * 108) + 108];
  11465. #endif
  11466. sp_digit* t[16];
  11467. sp_digit* rt = NULL;
  11468. sp_digit* norm = NULL;
  11469. sp_digit mp = 1;
  11470. sp_digit n;
  11471. int i;
  11472. int c;
  11473. byte y;
  11474. int err = MP_OKAY;
  11475. if (bits == 0) {
  11476. err = MP_VAL;
  11477. }
  11478. #ifdef WOLFSSL_SP_SMALL_STACK
  11479. if (err == MP_OKAY) {
  11480. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((16 * 108) + 108), NULL,
  11481. DYNAMIC_TYPE_TMP_BUFFER);
  11482. if (td == NULL)
  11483. err = MEMORY_E;
  11484. }
  11485. #endif
  11486. if (err == MP_OKAY) {
  11487. norm = td;
  11488. for (i=0; i<16; i++)
  11489. t[i] = td + i * 108;
  11490. rt = td + 1728;
  11491. sp_3072_mont_setup(m, &mp);
  11492. sp_3072_mont_norm_54(norm, m);
  11493. if (reduceA != 0) {
  11494. err = sp_3072_mod_54(t[1], a, m);
  11495. if (err == MP_OKAY) {
  11496. sp_3072_mul_54(t[1], t[1], norm);
  11497. err = sp_3072_mod_54(t[1], t[1], m);
  11498. }
  11499. }
  11500. else {
  11501. sp_3072_mul_54(t[1], a, norm);
  11502. err = sp_3072_mod_54(t[1], t[1], m);
  11503. }
  11504. }
  11505. if (err == MP_OKAY) {
  11506. sp_3072_mont_sqr_54(t[ 2], t[ 1], m, mp);
  11507. sp_3072_mont_mul_54(t[ 3], t[ 2], t[ 1], m, mp);
  11508. sp_3072_mont_sqr_54(t[ 4], t[ 2], m, mp);
  11509. sp_3072_mont_mul_54(t[ 5], t[ 3], t[ 2], m, mp);
  11510. sp_3072_mont_sqr_54(t[ 6], t[ 3], m, mp);
  11511. sp_3072_mont_mul_54(t[ 7], t[ 4], t[ 3], m, mp);
  11512. sp_3072_mont_sqr_54(t[ 8], t[ 4], m, mp);
  11513. sp_3072_mont_mul_54(t[ 9], t[ 5], t[ 4], m, mp);
  11514. sp_3072_mont_sqr_54(t[10], t[ 5], m, mp);
  11515. sp_3072_mont_mul_54(t[11], t[ 6], t[ 5], m, mp);
  11516. sp_3072_mont_sqr_54(t[12], t[ 6], m, mp);
  11517. sp_3072_mont_mul_54(t[13], t[ 7], t[ 6], m, mp);
  11518. sp_3072_mont_sqr_54(t[14], t[ 7], m, mp);
  11519. sp_3072_mont_mul_54(t[15], t[ 8], t[ 7], m, mp);
  11520. bits = ((bits + 3) / 4) * 4;
  11521. i = ((bits + 56) / 57) - 1;
  11522. c = bits % 57;
  11523. if (c == 0) {
  11524. c = 57;
  11525. }
  11526. if (i < 54) {
  11527. n = e[i--] << (64 - c);
  11528. }
  11529. else {
  11530. n = 0;
  11531. i--;
  11532. }
  11533. if (c < 4) {
  11534. n |= e[i--] << (7 - c);
  11535. c += 57;
  11536. }
  11537. y = (int)((n >> 60) & 0xf);
  11538. n <<= 4;
  11539. c -= 4;
  11540. XMEMCPY(rt, t[y], sizeof(sp_digit) * 108);
  11541. while ((i >= 0) || (c >= 4)) {
  11542. if (c >= 4) {
  11543. y = (byte)((n >> 60) & 0xf);
  11544. n <<= 4;
  11545. c -= 4;
  11546. }
  11547. else if (c == 0) {
  11548. n = e[i--] << 7;
  11549. y = (byte)((n >> 60) & 0xf);
  11550. n <<= 4;
  11551. c = 53;
  11552. }
  11553. else {
  11554. y = (byte)((n >> 60) & 0xf);
  11555. n = e[i--] << 7;
  11556. c = 4 - c;
  11557. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  11558. n <<= c;
  11559. c = 57 - c;
  11560. }
  11561. sp_3072_mont_sqr_54(rt, rt, m, mp);
  11562. sp_3072_mont_sqr_54(rt, rt, m, mp);
  11563. sp_3072_mont_sqr_54(rt, rt, m, mp);
  11564. sp_3072_mont_sqr_54(rt, rt, m, mp);
  11565. sp_3072_mont_mul_54(rt, rt, t[y], m, mp);
  11566. }
  11567. sp_3072_mont_reduce_54(rt, m, mp);
  11568. n = sp_3072_cmp_54(rt, m);
  11569. sp_3072_cond_sub_54(rt, rt, m, ~(n >> 63));
  11570. XMEMCPY(r, rt, sizeof(sp_digit) * 108);
  11571. }
  11572. #ifdef WOLFSSL_SP_SMALL_STACK
  11573. if (td != NULL)
  11574. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  11575. #endif
  11576. return err;
  11577. #endif
  11578. }
  11579. #endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) || */
  11580. /* WOLFSSL_HAVE_SP_DH */
  11581. #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
  11582. #ifdef WOLFSSL_HAVE_SP_RSA
  11583. /* RSA public key operation.
  11584. *
  11585. * in Array of bytes representing the number to exponentiate, base.
  11586. * inLen Number of bytes in base.
  11587. * em Public exponent.
  11588. * mm Modulus.
  11589. * out Buffer to hold big-endian bytes of exponentiation result.
  11590. * Must be at least 384 bytes long.
  11591. * outLen Number of bytes in result.
  11592. * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
  11593. * an array is too long and MEMORY_E when dynamic memory allocation fails.
  11594. */
  11595. int sp_RsaPublic_3072(const byte* in, word32 inLen, const mp_int* em,
  11596. const mp_int* mm, byte* out, word32* outLen)
  11597. {
  11598. #ifdef WOLFSSL_SP_SMALL
  11599. #ifdef WOLFSSL_SP_SMALL_STACK
  11600. sp_digit* a = NULL;
  11601. #else
  11602. sp_digit a[54 * 5];
  11603. #endif
  11604. sp_digit* m = NULL;
  11605. sp_digit* r = NULL;
  11606. sp_digit* norm = NULL;
  11607. sp_uint64 e[1] = {0};
  11608. sp_digit mp = 0;
  11609. int i;
  11610. int err = MP_OKAY;
  11611. if (*outLen < 384U) {
  11612. err = MP_TO_E;
  11613. }
  11614. if (err == MP_OKAY) {
  11615. if (mp_count_bits(em) > 64) {
  11616. err = MP_READ_E;
  11617. }
  11618. else if (inLen > 384U) {
  11619. err = MP_READ_E;
  11620. }
  11621. else if (mp_count_bits(mm) != 3072) {
  11622. err = MP_READ_E;
  11623. }
  11624. else if (mp_iseven(mm)) {
  11625. err = MP_VAL;
  11626. }
  11627. }
  11628. #ifdef WOLFSSL_SP_SMALL_STACK
  11629. if (err == MP_OKAY) {
  11630. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 5, NULL,
  11631. DYNAMIC_TYPE_RSA);
  11632. if (a == NULL)
  11633. err = MEMORY_E;
  11634. }
  11635. #endif
  11636. if (err == MP_OKAY) {
  11637. r = a + 54 * 2;
  11638. m = r + 54 * 2;
  11639. norm = r;
  11640. sp_3072_from_bin(a, 54, in, inLen);
  11641. #if DIGIT_BIT >= 64
  11642. e[0] = (sp_uint64)em->dp[0];
  11643. #else
  11644. e[0] = (sp_uint64)em->dp[0];
  11645. if (em->used > 1) {
  11646. e[0] |= ((sp_uint64)em->dp[1]) << DIGIT_BIT;
  11647. }
  11648. #endif
  11649. if (e[0] == 0) {
  11650. err = MP_EXPTMOD_E;
  11651. }
  11652. }
  11653. if (err == MP_OKAY) {
  11654. sp_3072_from_mp(m, 54, mm);
  11655. sp_3072_mont_setup(m, &mp);
  11656. sp_3072_mont_norm_54(norm, m);
  11657. }
  11658. if (err == MP_OKAY) {
  11659. sp_3072_mul_54(a, a, norm);
  11660. err = sp_3072_mod_54(a, a, m);
  11661. }
  11662. if (err == MP_OKAY) {
  11663. for (i=63; i>=0; i--) {
  11664. if ((e[0] >> i) != 0) {
  11665. break;
  11666. }
  11667. }
  11668. XMEMCPY(r, a, sizeof(sp_digit) * 54 * 2);
  11669. for (i--; i>=0; i--) {
  11670. sp_3072_mont_sqr_54(r, r, m, mp);
  11671. if (((e[0] >> i) & 1) == 1) {
  11672. sp_3072_mont_mul_54(r, r, a, m, mp);
  11673. }
  11674. }
  11675. sp_3072_mont_reduce_54(r, m, mp);
  11676. mp = sp_3072_cmp_54(r, m);
  11677. sp_3072_cond_sub_54(r, r, m, ~(mp >> 63));
  11678. sp_3072_to_bin_54(r, out);
  11679. *outLen = 384;
  11680. }
  11681. #ifdef WOLFSSL_SP_SMALL_STACK
  11682. if (a != NULL)
  11683. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  11684. #endif
  11685. return err;
  11686. #else
  11687. #ifdef WOLFSSL_SP_SMALL_STACK
  11688. sp_digit* d = NULL;
  11689. #else
  11690. sp_digit d[54 * 5];
  11691. #endif
  11692. sp_digit* a = NULL;
  11693. sp_digit* m = NULL;
  11694. sp_digit* r = NULL;
  11695. sp_uint64 e[1] = {0};
  11696. int err = MP_OKAY;
  11697. if (*outLen < 384U) {
  11698. err = MP_TO_E;
  11699. }
  11700. if (err == MP_OKAY) {
  11701. if (mp_count_bits(em) > 64) {
  11702. err = MP_READ_E;
  11703. }
  11704. else if (inLen > 384U) {
  11705. err = MP_READ_E;
  11706. }
  11707. else if (mp_count_bits(mm) != 3072) {
  11708. err = MP_READ_E;
  11709. }
  11710. else if (mp_iseven(mm)) {
  11711. err = MP_VAL;
  11712. }
  11713. }
  11714. #ifdef WOLFSSL_SP_SMALL_STACK
  11715. if (err == MP_OKAY) {
  11716. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 5, NULL,
  11717. DYNAMIC_TYPE_RSA);
  11718. if (d == NULL)
  11719. err = MEMORY_E;
  11720. }
  11721. #endif
  11722. if (err == MP_OKAY) {
  11723. a = d;
  11724. r = a + 54 * 2;
  11725. m = r + 54 * 2;
  11726. sp_3072_from_bin(a, 54, in, inLen);
  11727. #if DIGIT_BIT >= 64
  11728. e[0] = (sp_uint64)em->dp[0];
  11729. #else
  11730. e[0] = (sp_uint64)em->dp[0];
  11731. if (em->used > 1) {
  11732. e[0] |= ((sp_uint64)em->dp[1]) << DIGIT_BIT;
  11733. }
  11734. #endif
  11735. if (e[0] == 0) {
  11736. err = MP_EXPTMOD_E;
  11737. }
  11738. }
  11739. if (err == MP_OKAY) {
  11740. sp_3072_from_mp(m, 54, mm);
  11741. if (e[0] == 0x3) {
  11742. sp_3072_sqr_54(r, a);
  11743. err = sp_3072_mod_54(r, r, m);
  11744. if (err == MP_OKAY) {
  11745. sp_3072_mul_54(r, a, r);
  11746. err = sp_3072_mod_54(r, r, m);
  11747. }
  11748. }
  11749. else {
  11750. sp_digit* norm = r;
  11751. int i;
  11752. sp_digit mp;
  11753. sp_3072_mont_setup(m, &mp);
  11754. sp_3072_mont_norm_54(norm, m);
  11755. sp_3072_mul_54(a, a, norm);
  11756. err = sp_3072_mod_54(a, a, m);
  11757. if (err == MP_OKAY) {
  11758. for (i=63; i>=0; i--) {
  11759. if ((e[0] >> i) != 0) {
  11760. break;
  11761. }
  11762. }
  11763. XMEMCPY(r, a, sizeof(sp_digit) * 108U);
  11764. for (i--; i>=0; i--) {
  11765. sp_3072_mont_sqr_54(r, r, m, mp);
  11766. if (((e[0] >> i) & 1) == 1) {
  11767. sp_3072_mont_mul_54(r, r, a, m, mp);
  11768. }
  11769. }
  11770. sp_3072_mont_reduce_54(r, m, mp);
  11771. mp = sp_3072_cmp_54(r, m);
  11772. sp_3072_cond_sub_54(r, r, m, ~(mp >> 63));
  11773. }
  11774. }
  11775. }
  11776. if (err == MP_OKAY) {
  11777. sp_3072_to_bin_54(r, out);
  11778. *outLen = 384;
  11779. }
  11780. #ifdef WOLFSSL_SP_SMALL_STACK
  11781. if (d != NULL)
  11782. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  11783. #endif
  11784. return err;
  11785. #endif /* WOLFSSL_SP_SMALL */
  11786. }
  11787. #ifndef WOLFSSL_RSA_PUBLIC_ONLY
  11788. #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM)
  11789. #endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */
  11790. /* RSA private key operation.
  11791. *
  11792. * in Array of bytes representing the number to exponentiate, base.
  11793. * inLen Number of bytes in base.
  11794. * dm Private exponent.
  11795. * pm First prime.
  11796. * qm Second prime.
  11797. * dpm First prime's CRT exponent.
  11798. * dqm Second prime's CRT exponent.
  11799. * qim Inverse of second prime mod p.
  11800. * mm Modulus.
  11801. * out Buffer to hold big-endian bytes of exponentiation result.
  11802. * Must be at least 384 bytes long.
  11803. * outLen Number of bytes in result.
  11804. * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
  11805. * an array is too long and MEMORY_E when dynamic memory allocation fails.
  11806. */
  11807. int sp_RsaPrivate_3072(const byte* in, word32 inLen, const mp_int* dm,
  11808. const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm,
  11809. const mp_int* qim, const mp_int* mm, byte* out, word32* outLen)
  11810. {
  11811. #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
  11812. #if defined(WOLFSSL_SP_SMALL)
  11813. #ifdef WOLFSSL_SP_SMALL_STACK
  11814. sp_digit* d = NULL;
  11815. #else
  11816. sp_digit d[54 * 4];
  11817. #endif
  11818. sp_digit* a = NULL;
  11819. sp_digit* m = NULL;
  11820. sp_digit* r = NULL;
  11821. int err = MP_OKAY;
  11822. (void)pm;
  11823. (void)qm;
  11824. (void)dpm;
  11825. (void)dqm;
  11826. (void)qim;
  11827. if (*outLen < 384U) {
  11828. err = MP_TO_E;
  11829. }
  11830. if (err == MP_OKAY) {
  11831. if (mp_count_bits(dm) > 3072) {
  11832. err = MP_READ_E;
  11833. }
  11834. else if (inLen > 384) {
  11835. err = MP_READ_E;
  11836. }
  11837. else if (mp_count_bits(mm) != 3072) {
  11838. err = MP_READ_E;
  11839. }
  11840. else if (mp_iseven(mm)) {
  11841. err = MP_VAL;
  11842. }
  11843. }
  11844. #ifdef WOLFSSL_SP_SMALL_STACK
  11845. if (err == MP_OKAY) {
  11846. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 4, NULL,
  11847. DYNAMIC_TYPE_RSA);
  11848. if (d == NULL)
  11849. err = MEMORY_E;
  11850. }
  11851. #endif
  11852. if (err == MP_OKAY) {
  11853. a = d + 54;
  11854. m = a + 108;
  11855. r = a;
  11856. sp_3072_from_bin(a, 54, in, inLen);
  11857. sp_3072_from_mp(d, 54, dm);
  11858. sp_3072_from_mp(m, 54, mm);
  11859. err = sp_3072_mod_exp_54(r, a, d, 3072, m, 0);
  11860. }
  11861. if (err == MP_OKAY) {
  11862. sp_3072_to_bin_54(r, out);
  11863. *outLen = 384;
  11864. }
  11865. #ifdef WOLFSSL_SP_SMALL_STACK
  11866. if (d != NULL)
  11867. #endif
  11868. {
  11869. /* only "a" and "r" are sensitive and need zeroized (same pointer) */
  11870. if (a != NULL)
  11871. ForceZero(a, sizeof(sp_digit) * 54);
  11872. #ifdef WOLFSSL_SP_SMALL_STACK
  11873. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  11874. #endif
  11875. }
  11876. return err;
  11877. #else
  11878. #ifdef WOLFSSL_SP_SMALL_STACK
  11879. sp_digit* d = NULL;
  11880. #else
  11881. sp_digit d[54 * 4];
  11882. #endif
  11883. sp_digit* a = NULL;
  11884. sp_digit* m = NULL;
  11885. sp_digit* r = NULL;
  11886. int err = MP_OKAY;
  11887. (void)pm;
  11888. (void)qm;
  11889. (void)dpm;
  11890. (void)dqm;
  11891. (void)qim;
  11892. if (*outLen < 384U) {
  11893. err = MP_TO_E;
  11894. }
  11895. if (err == MP_OKAY) {
  11896. if (mp_count_bits(dm) > 3072) {
  11897. err = MP_READ_E;
  11898. }
  11899. else if (inLen > 384U) {
  11900. err = MP_READ_E;
  11901. }
  11902. else if (mp_count_bits(mm) != 3072) {
  11903. err = MP_READ_E;
  11904. }
  11905. else if (mp_iseven(mm)) {
  11906. err = MP_VAL;
  11907. }
  11908. }
  11909. #ifdef WOLFSSL_SP_SMALL_STACK
  11910. if (err == MP_OKAY) {
  11911. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 4, NULL,
  11912. DYNAMIC_TYPE_RSA);
  11913. if (d == NULL)
  11914. err = MEMORY_E;
  11915. }
  11916. #endif
  11917. if (err == MP_OKAY) {
  11918. a = d + 54;
  11919. m = a + 108;
  11920. r = a;
  11921. sp_3072_from_bin(a, 54, in, inLen);
  11922. sp_3072_from_mp(d, 54, dm);
  11923. sp_3072_from_mp(m, 54, mm);
  11924. err = sp_3072_mod_exp_54(r, a, d, 3072, m, 0);
  11925. }
  11926. if (err == MP_OKAY) {
  11927. sp_3072_to_bin_54(r, out);
  11928. *outLen = 384;
  11929. }
  11930. #ifdef WOLFSSL_SP_SMALL_STACK
  11931. if (d != NULL)
  11932. #endif
  11933. {
  11934. /* only "a" and "r" are sensitive and need zeroized (same pointer) */
  11935. if (a != NULL)
  11936. ForceZero(a, sizeof(sp_digit) * 54);
  11937. #ifdef WOLFSSL_SP_SMALL_STACK
  11938. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  11939. #endif
  11940. }
  11941. return err;
  11942. #endif /* WOLFSSL_SP_SMALL */
  11943. #else
  11944. #if defined(WOLFSSL_SP_SMALL)
  11945. #ifdef WOLFSSL_SP_SMALL_STACK
  11946. sp_digit* a = NULL;
  11947. #else
  11948. sp_digit a[27 * 8];
  11949. #endif
  11950. sp_digit* p = NULL;
  11951. sp_digit* dp = NULL;
  11952. sp_digit* dq = NULL;
  11953. sp_digit* qi = NULL;
  11954. sp_digit* tmpa = NULL;
  11955. sp_digit* tmpb = NULL;
  11956. sp_digit* r = NULL;
  11957. int err = MP_OKAY;
  11958. (void)dm;
  11959. (void)mm;
  11960. if (*outLen < 384U) {
  11961. err = MP_TO_E;
  11962. }
  11963. if (err == MP_OKAY) {
  11964. if (inLen > 384) {
  11965. err = MP_READ_E;
  11966. }
  11967. else if (mp_count_bits(mm) != 3072) {
  11968. err = MP_READ_E;
  11969. }
  11970. else if (mp_iseven(mm)) {
  11971. err = MP_VAL;
  11972. }
  11973. else if (mp_iseven(pm)) {
  11974. err = MP_VAL;
  11975. }
  11976. else if (mp_iseven(qm)) {
  11977. err = MP_VAL;
  11978. }
  11979. }
  11980. #ifdef WOLFSSL_SP_SMALL_STACK
  11981. if (err == MP_OKAY) {
  11982. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 27 * 8, NULL,
  11983. DYNAMIC_TYPE_RSA);
  11984. if (a == NULL)
  11985. err = MEMORY_E;
  11986. }
  11987. #endif
  11988. if (err == MP_OKAY) {
  11989. p = a + 54;
  11990. qi = dq = dp = p + 27;
  11991. tmpa = qi + 27;
  11992. tmpb = tmpa + 54;
  11993. r = a;
  11994. sp_3072_from_bin(a, 54, in, inLen);
  11995. sp_3072_from_mp(p, 27, pm);
  11996. sp_3072_from_mp(dp, 27, dpm);
  11997. err = sp_3072_mod_exp_27(tmpa, a, dp, 1536, p, 1);
  11998. }
  11999. if (err == MP_OKAY) {
  12000. sp_3072_from_mp(p, 27, qm);
  12001. sp_3072_from_mp(dq, 27, dqm);
  12002. err = sp_3072_mod_exp_27(tmpb, a, dq, 1536, p, 1);
  12003. }
  12004. if (err == MP_OKAY) {
  12005. sp_3072_from_mp(p, 27, pm);
  12006. (void)sp_3072_sub_27(tmpa, tmpa, tmpb);
  12007. sp_3072_norm_27(tmpa);
  12008. sp_3072_cond_add_27(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[26] >> 63));
  12009. sp_3072_cond_add_27(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[26] >> 63));
  12010. sp_3072_norm_27(tmpa);
  12011. sp_3072_from_mp(qi, 27, qim);
  12012. sp_3072_mul_27(tmpa, tmpa, qi);
  12013. err = sp_3072_mod_27(tmpa, tmpa, p);
  12014. }
  12015. if (err == MP_OKAY) {
  12016. sp_3072_from_mp(p, 27, qm);
  12017. sp_3072_mul_27(tmpa, p, tmpa);
  12018. (void)sp_3072_add_54(r, tmpb, tmpa);
  12019. sp_3072_norm_54(r);
  12020. sp_3072_to_bin_54(r, out);
  12021. *outLen = 384;
  12022. }
  12023. #ifdef WOLFSSL_SP_SMALL_STACK
  12024. if (a != NULL)
  12025. #endif
  12026. {
  12027. ForceZero(a, sizeof(sp_digit) * 27 * 8);
  12028. #ifdef WOLFSSL_SP_SMALL_STACK
  12029. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  12030. #endif
  12031. }
  12032. return err;
  12033. #else
  12034. #ifdef WOLFSSL_SP_SMALL_STACK
  12035. sp_digit* a = NULL;
  12036. #else
  12037. sp_digit a[27 * 13];
  12038. #endif
  12039. sp_digit* p = NULL;
  12040. sp_digit* q = NULL;
  12041. sp_digit* dp = NULL;
  12042. sp_digit* dq = NULL;
  12043. sp_digit* qi = NULL;
  12044. sp_digit* tmpa = NULL;
  12045. sp_digit* tmpb = NULL;
  12046. sp_digit* r = NULL;
  12047. int err = MP_OKAY;
  12048. (void)dm;
  12049. (void)mm;
  12050. if (*outLen < 384U) {
  12051. err = MP_TO_E;
  12052. }
  12053. if (err == MP_OKAY) {
  12054. if (inLen > 384U) {
  12055. err = MP_READ_E;
  12056. }
  12057. else if (mp_count_bits(mm) != 3072) {
  12058. err = MP_READ_E;
  12059. }
  12060. else if (mp_iseven(mm)) {
  12061. err = MP_VAL;
  12062. }
  12063. else if (mp_iseven(pm)) {
  12064. err = MP_VAL;
  12065. }
  12066. else if (mp_iseven(qm)) {
  12067. err = MP_VAL;
  12068. }
  12069. }
  12070. #ifdef WOLFSSL_SP_SMALL_STACK
  12071. if (err == MP_OKAY) {
  12072. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 27 * 13, NULL,
  12073. DYNAMIC_TYPE_RSA);
  12074. if (a == NULL)
  12075. err = MEMORY_E;
  12076. }
  12077. #endif
  12078. if (err == MP_OKAY) {
  12079. p = a + 54 * 2;
  12080. q = p + 27;
  12081. dp = q + 27;
  12082. dq = dp + 27;
  12083. qi = dq + 27;
  12084. tmpa = qi + 27;
  12085. tmpb = tmpa + 54;
  12086. r = a;
  12087. sp_3072_from_bin(a, 54, in, inLen);
  12088. sp_3072_from_mp(p, 27, pm);
  12089. sp_3072_from_mp(q, 27, qm);
  12090. sp_3072_from_mp(dp, 27, dpm);
  12091. sp_3072_from_mp(dq, 27, dqm);
  12092. sp_3072_from_mp(qi, 27, qim);
  12093. err = sp_3072_mod_exp_27(tmpa, a, dp, 1536, p, 1);
  12094. }
  12095. if (err == MP_OKAY) {
  12096. err = sp_3072_mod_exp_27(tmpb, a, dq, 1536, q, 1);
  12097. }
  12098. if (err == MP_OKAY) {
  12099. (void)sp_3072_sub_27(tmpa, tmpa, tmpb);
  12100. sp_3072_norm_27(tmpa);
  12101. sp_3072_cond_add_27(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[26] >> 63));
  12102. sp_3072_cond_add_27(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[26] >> 63));
  12103. sp_3072_norm_27(tmpa);
  12104. sp_3072_mul_27(tmpa, tmpa, qi);
  12105. err = sp_3072_mod_27(tmpa, tmpa, p);
  12106. }
  12107. if (err == MP_OKAY) {
  12108. sp_3072_mul_27(tmpa, tmpa, q);
  12109. (void)sp_3072_add_54(r, tmpb, tmpa);
  12110. sp_3072_norm_54(r);
  12111. sp_3072_to_bin_54(r, out);
  12112. *outLen = 384;
  12113. }
  12114. #ifdef WOLFSSL_SP_SMALL_STACK
  12115. if (a != NULL)
  12116. #endif
  12117. {
  12118. ForceZero(a, sizeof(sp_digit) * 27 * 13);
  12119. #ifdef WOLFSSL_SP_SMALL_STACK
  12120. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  12121. #endif
  12122. }
  12123. return err;
  12124. #endif /* WOLFSSL_SP_SMALL */
  12125. #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
  12126. }
  12127. #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
  12128. #endif /* WOLFSSL_HAVE_SP_RSA */
  12129. #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
  12130. !defined(WOLFSSL_RSA_PUBLIC_ONLY))
  12131. /* Convert an array of sp_digit to an mp_int.
  12132. *
  12133. * a A single precision integer.
  12134. * r A multi-precision integer.
  12135. */
  12136. static int sp_3072_to_mp(const sp_digit* a, mp_int* r)
  12137. {
  12138. int err;
  12139. err = mp_grow(r, (3072 + DIGIT_BIT - 1) / DIGIT_BIT);
  12140. if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
  12141. #if DIGIT_BIT == 57
  12142. XMEMCPY(r->dp, a, sizeof(sp_digit) * 54);
  12143. r->used = 54;
  12144. mp_clamp(r);
  12145. #elif DIGIT_BIT < 57
  12146. int i;
  12147. int j = 0;
  12148. int s = 0;
  12149. r->dp[0] = 0;
  12150. for (i = 0; i < 54; i++) {
  12151. r->dp[j] |= (mp_digit)(a[i] << s);
  12152. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  12153. s = DIGIT_BIT - s;
  12154. r->dp[++j] = (mp_digit)(a[i] >> s);
  12155. while (s + DIGIT_BIT <= 57) {
  12156. s += DIGIT_BIT;
  12157. r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  12158. if (s == SP_WORD_SIZE) {
  12159. r->dp[j] = 0;
  12160. }
  12161. else {
  12162. r->dp[j] = (mp_digit)(a[i] >> s);
  12163. }
  12164. }
  12165. s = 57 - s;
  12166. }
  12167. r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;
  12168. mp_clamp(r);
  12169. #else
  12170. int i;
  12171. int j = 0;
  12172. int s = 0;
  12173. r->dp[0] = 0;
  12174. for (i = 0; i < 54; i++) {
  12175. r->dp[j] |= ((mp_digit)a[i]) << s;
  12176. if (s + 57 >= DIGIT_BIT) {
  12177. #if DIGIT_BIT != 32 && DIGIT_BIT != 64
  12178. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  12179. #endif
  12180. s = DIGIT_BIT - s;
  12181. r->dp[++j] = a[i] >> s;
  12182. s = 57 - s;
  12183. }
  12184. else {
  12185. s += 57;
  12186. }
  12187. }
  12188. r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;
  12189. mp_clamp(r);
  12190. #endif
  12191. }
  12192. return err;
  12193. }
  12194. /* Perform the modular exponentiation for Diffie-Hellman.
  12195. *
  12196. * base Base. MP integer.
  12197. * exp Exponent. MP integer.
  12198. * mod Modulus. MP integer.
  12199. * res Result. MP integer.
  12200. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  12201. * and MEMORY_E if memory allocation fails.
  12202. */
  12203. int sp_ModExp_3072(const mp_int* base, const mp_int* exp, const mp_int* mod,
  12204. mp_int* res)
  12205. {
  12206. #ifdef WOLFSSL_SP_SMALL
  12207. int err = MP_OKAY;
  12208. #ifdef WOLFSSL_SP_SMALL_STACK
  12209. sp_digit* b = NULL;
  12210. #else
  12211. sp_digit b[54 * 4];
  12212. #endif
  12213. sp_digit* e = NULL;
  12214. sp_digit* m = NULL;
  12215. sp_digit* r = NULL;
  12216. int expBits = mp_count_bits(exp);
  12217. if (mp_count_bits(base) > 3072) {
  12218. err = MP_READ_E;
  12219. }
  12220. else if (expBits > 3072) {
  12221. err = MP_READ_E;
  12222. }
  12223. else if (mp_count_bits(mod) != 3072) {
  12224. err = MP_READ_E;
  12225. }
  12226. else if (mp_iseven(mod)) {
  12227. err = MP_VAL;
  12228. }
  12229. #ifdef WOLFSSL_SP_SMALL_STACK
  12230. if (err == MP_OKAY) {
  12231. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 4, NULL,
  12232. DYNAMIC_TYPE_DH);
  12233. if (b == NULL)
  12234. err = MEMORY_E;
  12235. }
  12236. #endif
  12237. if (err == MP_OKAY) {
  12238. e = b + 54 * 2;
  12239. m = e + 54;
  12240. r = b;
  12241. sp_3072_from_mp(b, 54, base);
  12242. sp_3072_from_mp(e, 54, exp);
  12243. sp_3072_from_mp(m, 54, mod);
  12244. err = sp_3072_mod_exp_54(r, b, e, mp_count_bits(exp), m, 0);
  12245. }
  12246. if (err == MP_OKAY) {
  12247. err = sp_3072_to_mp(r, res);
  12248. }
  12249. #ifdef WOLFSSL_SP_SMALL_STACK
  12250. if (b != NULL)
  12251. #endif
  12252. {
  12253. /* only "e" is sensitive and needs zeroized */
  12254. if (e != NULL)
  12255. ForceZero(e, sizeof(sp_digit) * 54U);
  12256. #ifdef WOLFSSL_SP_SMALL_STACK
  12257. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  12258. #endif
  12259. }
  12260. return err;
  12261. #else
  12262. #ifdef WOLFSSL_SP_SMALL_STACK
  12263. sp_digit* b = NULL;
  12264. #else
  12265. sp_digit b[54 * 4];
  12266. #endif
  12267. sp_digit* e = NULL;
  12268. sp_digit* m = NULL;
  12269. sp_digit* r = NULL;
  12270. int err = MP_OKAY;
  12271. int expBits = mp_count_bits(exp);
  12272. if (mp_count_bits(base) > 3072) {
  12273. err = MP_READ_E;
  12274. }
  12275. else if (expBits > 3072) {
  12276. err = MP_READ_E;
  12277. }
  12278. else if (mp_count_bits(mod) != 3072) {
  12279. err = MP_READ_E;
  12280. }
  12281. else if (mp_iseven(mod)) {
  12282. err = MP_VAL;
  12283. }
  12284. #ifdef WOLFSSL_SP_SMALL_STACK
  12285. if (err == MP_OKAY) {
  12286. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 4, NULL, DYNAMIC_TYPE_DH);
  12287. if (b == NULL)
  12288. err = MEMORY_E;
  12289. }
  12290. #endif
  12291. if (err == MP_OKAY) {
  12292. e = b + 54 * 2;
  12293. m = e + 54;
  12294. r = b;
  12295. sp_3072_from_mp(b, 54, base);
  12296. sp_3072_from_mp(e, 54, exp);
  12297. sp_3072_from_mp(m, 54, mod);
  12298. err = sp_3072_mod_exp_54(r, b, e, expBits, m, 0);
  12299. }
  12300. if (err == MP_OKAY) {
  12301. err = sp_3072_to_mp(r, res);
  12302. }
  12303. #ifdef WOLFSSL_SP_SMALL_STACK
  12304. if (b != NULL)
  12305. #endif
  12306. {
  12307. /* only "e" is sensitive and needs zeroized */
  12308. if (e != NULL)
  12309. ForceZero(e, sizeof(sp_digit) * 54U);
  12310. #ifdef WOLFSSL_SP_SMALL_STACK
  12311. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  12312. #endif
  12313. }
  12314. return err;
  12315. #endif
  12316. }
  12317. #ifdef WOLFSSL_HAVE_SP_DH
  12318. #ifdef HAVE_FFDHE_3072
  12319. SP_NOINLINE static void sp_3072_lshift_54(sp_digit* r, const sp_digit* a,
  12320. byte n)
  12321. {
  12322. sp_int_digit s;
  12323. sp_int_digit t;
  12324. s = (sp_int_digit)a[53];
  12325. r[54] = s >> (57U - n);
  12326. s = (sp_int_digit)(a[53]); t = (sp_int_digit)(a[52]);
  12327. r[53] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12328. s = (sp_int_digit)(a[52]); t = (sp_int_digit)(a[51]);
  12329. r[52] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12330. s = (sp_int_digit)(a[51]); t = (sp_int_digit)(a[50]);
  12331. r[51] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12332. s = (sp_int_digit)(a[50]); t = (sp_int_digit)(a[49]);
  12333. r[50] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12334. s = (sp_int_digit)(a[49]); t = (sp_int_digit)(a[48]);
  12335. r[49] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12336. s = (sp_int_digit)(a[48]); t = (sp_int_digit)(a[47]);
  12337. r[48] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12338. s = (sp_int_digit)(a[47]); t = (sp_int_digit)(a[46]);
  12339. r[47] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12340. s = (sp_int_digit)(a[46]); t = (sp_int_digit)(a[45]);
  12341. r[46] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12342. s = (sp_int_digit)(a[45]); t = (sp_int_digit)(a[44]);
  12343. r[45] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12344. s = (sp_int_digit)(a[44]); t = (sp_int_digit)(a[43]);
  12345. r[44] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12346. s = (sp_int_digit)(a[43]); t = (sp_int_digit)(a[42]);
  12347. r[43] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12348. s = (sp_int_digit)(a[42]); t = (sp_int_digit)(a[41]);
  12349. r[42] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12350. s = (sp_int_digit)(a[41]); t = (sp_int_digit)(a[40]);
  12351. r[41] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12352. s = (sp_int_digit)(a[40]); t = (sp_int_digit)(a[39]);
  12353. r[40] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12354. s = (sp_int_digit)(a[39]); t = (sp_int_digit)(a[38]);
  12355. r[39] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12356. s = (sp_int_digit)(a[38]); t = (sp_int_digit)(a[37]);
  12357. r[38] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12358. s = (sp_int_digit)(a[37]); t = (sp_int_digit)(a[36]);
  12359. r[37] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12360. s = (sp_int_digit)(a[36]); t = (sp_int_digit)(a[35]);
  12361. r[36] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12362. s = (sp_int_digit)(a[35]); t = (sp_int_digit)(a[34]);
  12363. r[35] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12364. s = (sp_int_digit)(a[34]); t = (sp_int_digit)(a[33]);
  12365. r[34] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12366. s = (sp_int_digit)(a[33]); t = (sp_int_digit)(a[32]);
  12367. r[33] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12368. s = (sp_int_digit)(a[32]); t = (sp_int_digit)(a[31]);
  12369. r[32] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12370. s = (sp_int_digit)(a[31]); t = (sp_int_digit)(a[30]);
  12371. r[31] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12372. s = (sp_int_digit)(a[30]); t = (sp_int_digit)(a[29]);
  12373. r[30] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12374. s = (sp_int_digit)(a[29]); t = (sp_int_digit)(a[28]);
  12375. r[29] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12376. s = (sp_int_digit)(a[28]); t = (sp_int_digit)(a[27]);
  12377. r[28] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12378. s = (sp_int_digit)(a[27]); t = (sp_int_digit)(a[26]);
  12379. r[27] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12380. s = (sp_int_digit)(a[26]); t = (sp_int_digit)(a[25]);
  12381. r[26] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12382. s = (sp_int_digit)(a[25]); t = (sp_int_digit)(a[24]);
  12383. r[25] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12384. s = (sp_int_digit)(a[24]); t = (sp_int_digit)(a[23]);
  12385. r[24] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12386. s = (sp_int_digit)(a[23]); t = (sp_int_digit)(a[22]);
  12387. r[23] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12388. s = (sp_int_digit)(a[22]); t = (sp_int_digit)(a[21]);
  12389. r[22] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12390. s = (sp_int_digit)(a[21]); t = (sp_int_digit)(a[20]);
  12391. r[21] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12392. s = (sp_int_digit)(a[20]); t = (sp_int_digit)(a[19]);
  12393. r[20] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12394. s = (sp_int_digit)(a[19]); t = (sp_int_digit)(a[18]);
  12395. r[19] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12396. s = (sp_int_digit)(a[18]); t = (sp_int_digit)(a[17]);
  12397. r[18] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12398. s = (sp_int_digit)(a[17]); t = (sp_int_digit)(a[16]);
  12399. r[17] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12400. s = (sp_int_digit)(a[16]); t = (sp_int_digit)(a[15]);
  12401. r[16] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12402. s = (sp_int_digit)(a[15]); t = (sp_int_digit)(a[14]);
  12403. r[15] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12404. s = (sp_int_digit)(a[14]); t = (sp_int_digit)(a[13]);
  12405. r[14] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12406. s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);
  12407. r[13] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12408. s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);
  12409. r[12] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12410. s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);
  12411. r[11] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12412. s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);
  12413. r[10] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12414. s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);
  12415. r[9] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12416. s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);
  12417. r[8] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12418. s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);
  12419. r[7] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12420. s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);
  12421. r[6] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12422. s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);
  12423. r[5] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12424. s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);
  12425. r[4] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12426. s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);
  12427. r[3] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12428. s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);
  12429. r[2] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12430. s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);
  12431. r[1] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
  12432. r[0] = (a[0] << n) & 0x1ffffffffffffffL;
  12433. }
  12434. /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
  12435. *
  12436. * r A single precision number that is the result of the operation.
  12437. * e A single precision number that is the exponent.
  12438. * bits The number of bits in the exponent.
  12439. * m A single precision number that is the modulus.
  12440. * returns 0 on success.
  12441. * returns MEMORY_E on dynamic memory allocation failure.
  12442. * returns MP_VAL when base is even.
  12443. */
  12444. static int sp_3072_mod_exp_2_54(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)
  12445. {
  12446. #ifdef WOLFSSL_SP_SMALL_STACK
  12447. sp_digit* td = NULL;
  12448. #else
  12449. sp_digit td[163];
  12450. #endif
  12451. sp_digit* norm = NULL;
  12452. sp_digit* tmp = NULL;
  12453. sp_digit mp = 1;
  12454. sp_digit n;
  12455. sp_digit o;
  12456. int i;
  12457. int c;
  12458. byte y;
  12459. int err = MP_OKAY;
  12460. if (bits == 0) {
  12461. err = MP_VAL;
  12462. }
  12463. #ifdef WOLFSSL_SP_SMALL_STACK
  12464. if (err == MP_OKAY) {
  12465. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 163, NULL,
  12466. DYNAMIC_TYPE_TMP_BUFFER);
  12467. if (td == NULL)
  12468. err = MEMORY_E;
  12469. }
  12470. #endif
  12471. if (err == MP_OKAY) {
  12472. norm = td;
  12473. tmp = td + 108;
  12474. XMEMSET(td, 0, sizeof(sp_digit) * 163);
  12475. sp_3072_mont_setup(m, &mp);
  12476. sp_3072_mont_norm_54(norm, m);
  12477. bits = ((bits + 4) / 5) * 5;
  12478. i = ((bits + 56) / 57) - 1;
  12479. c = bits % 57;
  12480. if (c == 0) {
  12481. c = 57;
  12482. }
  12483. if (i < 54) {
  12484. n = e[i--] << (64 - c);
  12485. }
  12486. else {
  12487. n = 0;
  12488. i--;
  12489. }
  12490. if (c < 5) {
  12491. n |= e[i--] << (7 - c);
  12492. c += 57;
  12493. }
  12494. y = (int)((n >> 59) & 0x1f);
  12495. n <<= 5;
  12496. c -= 5;
  12497. sp_3072_lshift_54(r, norm, (byte)y);
  12498. while ((i >= 0) || (c >= 5)) {
  12499. if (c >= 5) {
  12500. y = (byte)((n >> 59) & 0x1f);
  12501. n <<= 5;
  12502. c -= 5;
  12503. }
  12504. else if (c == 0) {
  12505. n = e[i--] << 7;
  12506. y = (byte)((n >> 59) & 0x1f);
  12507. n <<= 5;
  12508. c = 52;
  12509. }
  12510. else {
  12511. y = (byte)((n >> 59) & 0x1f);
  12512. n = e[i--] << 7;
  12513. c = 5 - c;
  12514. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  12515. n <<= c;
  12516. c = 57 - c;
  12517. }
  12518. sp_3072_mont_sqr_54(r, r, m, mp);
  12519. sp_3072_mont_sqr_54(r, r, m, mp);
  12520. sp_3072_mont_sqr_54(r, r, m, mp);
  12521. sp_3072_mont_sqr_54(r, r, m, mp);
  12522. sp_3072_mont_sqr_54(r, r, m, mp);
  12523. sp_3072_lshift_54(r, r, (byte)y);
  12524. sp_3072_mul_d_54(tmp, norm, (r[54] << 6) + (r[53] >> 51));
  12525. r[54] = 0;
  12526. r[53] &= 0x7ffffffffffffL;
  12527. (void)sp_3072_add_54(r, r, tmp);
  12528. sp_3072_norm_54(r);
  12529. o = sp_3072_cmp_54(r, m);
  12530. sp_3072_cond_sub_54(r, r, m, ~(o >> 63));
  12531. }
  12532. sp_3072_mont_reduce_54(r, m, mp);
  12533. n = sp_3072_cmp_54(r, m);
  12534. sp_3072_cond_sub_54(r, r, m, ~(n >> 63));
  12535. }
  12536. #ifdef WOLFSSL_SP_SMALL_STACK
  12537. if (td != NULL)
  12538. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  12539. #endif
  12540. return err;
  12541. }
  12542. #endif /* HAVE_FFDHE_3072 */
  12543. /* Perform the modular exponentiation for Diffie-Hellman.
  12544. *
  12545. * base Base.
  12546. * exp Array of bytes that is the exponent.
  12547. * expLen Length of data, in bytes, in exponent.
  12548. * mod Modulus.
  12549. * out Buffer to hold big-endian bytes of exponentiation result.
  12550. * Must be at least 384 bytes long.
  12551. * outLen Length, in bytes, of exponentiation result.
  12552. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  12553. * and MEMORY_E if memory allocation fails.
  12554. */
  12555. int sp_DhExp_3072(const mp_int* base, const byte* exp, word32 expLen,
  12556. const mp_int* mod, byte* out, word32* outLen)
  12557. {
  12558. #ifdef WOLFSSL_SP_SMALL_STACK
  12559. sp_digit* b = NULL;
  12560. #else
  12561. sp_digit b[54 * 4];
  12562. #endif
  12563. sp_digit* e = NULL;
  12564. sp_digit* m = NULL;
  12565. sp_digit* r = NULL;
  12566. word32 i;
  12567. int err = MP_OKAY;
  12568. if (mp_count_bits(base) > 3072) {
  12569. err = MP_READ_E;
  12570. }
  12571. else if (expLen > 384U) {
  12572. err = MP_READ_E;
  12573. }
  12574. else if (mp_count_bits(mod) != 3072) {
  12575. err = MP_READ_E;
  12576. }
  12577. else if (mp_iseven(mod)) {
  12578. err = MP_VAL;
  12579. }
  12580. #ifdef WOLFSSL_SP_SMALL_STACK
  12581. if (err == MP_OKAY) {
  12582. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 4, NULL,
  12583. DYNAMIC_TYPE_DH);
  12584. if (b == NULL)
  12585. err = MEMORY_E;
  12586. }
  12587. #endif
  12588. if (err == MP_OKAY) {
  12589. e = b + 54 * 2;
  12590. m = e + 54;
  12591. r = b;
  12592. sp_3072_from_mp(b, 54, base);
  12593. sp_3072_from_bin(e, 54, exp, expLen);
  12594. sp_3072_from_mp(m, 54, mod);
  12595. #ifdef HAVE_FFDHE_3072
  12596. if (base->used == 1 && base->dp[0] == 2U &&
  12597. (m[53] >> 19) == 0xffffffffL) {
  12598. err = sp_3072_mod_exp_2_54(r, e, expLen * 8U, m);
  12599. }
  12600. else {
  12601. #endif
  12602. err = sp_3072_mod_exp_54(r, b, e, expLen * 8U, m, 0);
  12603. #ifdef HAVE_FFDHE_3072
  12604. }
  12605. #endif
  12606. }
  12607. if (err == MP_OKAY) {
  12608. sp_3072_to_bin_54(r, out);
  12609. *outLen = 384;
  12610. for (i=0; i<384U && out[i] == 0U; i++) {
  12611. /* Search for first non-zero. */
  12612. }
  12613. *outLen -= i;
  12614. XMEMMOVE(out, out + i, *outLen);
  12615. }
  12616. #ifdef WOLFSSL_SP_SMALL_STACK
  12617. if (b != NULL)
  12618. #endif
  12619. {
  12620. /* only "e" is sensitive and needs zeroized */
  12621. if (e != NULL)
  12622. ForceZero(e, sizeof(sp_digit) * 54U);
  12623. #ifdef WOLFSSL_SP_SMALL_STACK
  12624. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  12625. #endif
  12626. }
  12627. return err;
  12628. }
  12629. #endif /* WOLFSSL_HAVE_SP_DH */
  12630. /* Perform the modular exponentiation for Diffie-Hellman.
  12631. *
  12632. * base Base. MP integer.
  12633. * exp Exponent. MP integer.
  12634. * mod Modulus. MP integer.
  12635. * res Result. MP integer.
  12636. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  12637. * and MEMORY_E if memory allocation fails.
  12638. */
  12639. int sp_ModExp_1536(const mp_int* base, const mp_int* exp, const mp_int* mod,
  12640. mp_int* res)
  12641. {
  12642. #ifdef WOLFSSL_SP_SMALL
  12643. int err = MP_OKAY;
  12644. #ifdef WOLFSSL_SP_SMALL_STACK
  12645. sp_digit* b = NULL;
  12646. #else
  12647. sp_digit b[27 * 4];
  12648. #endif
  12649. sp_digit* e = NULL;
  12650. sp_digit* m = NULL;
  12651. sp_digit* r = NULL;
  12652. int expBits = mp_count_bits(exp);
  12653. if (mp_count_bits(base) > 1536) {
  12654. err = MP_READ_E;
  12655. }
  12656. else if (expBits > 1536) {
  12657. err = MP_READ_E;
  12658. }
  12659. else if (mp_count_bits(mod) != 1536) {
  12660. err = MP_READ_E;
  12661. }
  12662. else if (mp_iseven(mod)) {
  12663. err = MP_VAL;
  12664. }
  12665. #ifdef WOLFSSL_SP_SMALL_STACK
  12666. if (err == MP_OKAY) {
  12667. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 27 * 4, NULL,
  12668. DYNAMIC_TYPE_DH);
  12669. if (b == NULL)
  12670. err = MEMORY_E;
  12671. }
  12672. #endif
  12673. if (err == MP_OKAY) {
  12674. e = b + 27 * 2;
  12675. m = e + 27;
  12676. r = b;
  12677. sp_3072_from_mp(b, 27, base);
  12678. sp_3072_from_mp(e, 27, exp);
  12679. sp_3072_from_mp(m, 27, mod);
  12680. err = sp_3072_mod_exp_27(r, b, e, mp_count_bits(exp), m, 0);
  12681. }
  12682. if (err == MP_OKAY) {
  12683. XMEMSET(r + 27, 0, sizeof(*r) * 27U);
  12684. err = sp_3072_to_mp(r, res);
  12685. }
  12686. #ifdef WOLFSSL_SP_SMALL_STACK
  12687. if (b != NULL)
  12688. #endif
  12689. {
  12690. /* only "e" is sensitive and needs zeroized */
  12691. if (e != NULL)
  12692. ForceZero(e, sizeof(sp_digit) * 54U);
  12693. #ifdef WOLFSSL_SP_SMALL_STACK
  12694. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  12695. #endif
  12696. }
  12697. return err;
  12698. #else
  12699. #ifdef WOLFSSL_SP_SMALL_STACK
  12700. sp_digit* b = NULL;
  12701. #else
  12702. sp_digit b[27 * 4];
  12703. #endif
  12704. sp_digit* e = NULL;
  12705. sp_digit* m = NULL;
  12706. sp_digit* r = NULL;
  12707. int err = MP_OKAY;
  12708. int expBits = mp_count_bits(exp);
  12709. if (mp_count_bits(base) > 1536) {
  12710. err = MP_READ_E;
  12711. }
  12712. else if (expBits > 1536) {
  12713. err = MP_READ_E;
  12714. }
  12715. else if (mp_count_bits(mod) != 1536) {
  12716. err = MP_READ_E;
  12717. }
  12718. else if (mp_iseven(mod)) {
  12719. err = MP_VAL;
  12720. }
  12721. #ifdef WOLFSSL_SP_SMALL_STACK
  12722. if (err == MP_OKAY) {
  12723. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 27 * 4, NULL, DYNAMIC_TYPE_DH);
  12724. if (b == NULL)
  12725. err = MEMORY_E;
  12726. }
  12727. #endif
  12728. if (err == MP_OKAY) {
  12729. e = b + 27 * 2;
  12730. m = e + 27;
  12731. r = b;
  12732. sp_3072_from_mp(b, 27, base);
  12733. sp_3072_from_mp(e, 27, exp);
  12734. sp_3072_from_mp(m, 27, mod);
  12735. err = sp_3072_mod_exp_27(r, b, e, expBits, m, 0);
  12736. }
  12737. if (err == MP_OKAY) {
  12738. XMEMSET(r + 27, 0, sizeof(*r) * 27U);
  12739. err = sp_3072_to_mp(r, res);
  12740. }
  12741. #ifdef WOLFSSL_SP_SMALL_STACK
  12742. if (b != NULL)
  12743. #endif
  12744. {
  12745. /* only "e" is sensitive and needs zeroized */
  12746. if (e != NULL)
  12747. ForceZero(e, sizeof(sp_digit) * 54U);
  12748. #ifdef WOLFSSL_SP_SMALL_STACK
  12749. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  12750. #endif
  12751. }
  12752. return err;
  12753. #endif
  12754. }
  12755. #endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */
  12756. #endif /* WOLFSSL_SP_SMALL */
  12757. #endif /* !WOLFSSL_SP_NO_3072 */
  12758. #ifdef WOLFSSL_SP_4096
  12759. #ifdef WOLFSSL_SP_SMALL
  12760. /* Read big endian unsigned byte array into r.
  12761. *
  12762. * r A single precision integer.
  12763. * size Maximum number of bytes to convert
  12764. * a Byte array.
  12765. * n Number of bytes in array to read.
  12766. */
  12767. static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n)
  12768. {
  12769. int i;
  12770. int j = 0;
  12771. word32 s = 0;
  12772. r[0] = 0;
  12773. for (i = n-1; i >= 0; i--) {
  12774. r[j] |= (((sp_digit)a[i]) << s);
  12775. if (s >= 51U) {
  12776. r[j] &= 0x7ffffffffffffffL;
  12777. s = 59U - s;
  12778. if (j + 1 >= size) {
  12779. break;
  12780. }
  12781. r[++j] = (sp_digit)a[i] >> s;
  12782. s = 8U - s;
  12783. }
  12784. else {
  12785. s += 8U;
  12786. }
  12787. }
  12788. for (j++; j < size; j++) {
  12789. r[j] = 0;
  12790. }
  12791. }
  12792. /* Convert an mp_int to an array of sp_digit.
  12793. *
  12794. * r A single precision integer.
  12795. * size Maximum number of bytes to convert
  12796. * a A multi-precision integer.
  12797. */
  12798. static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a)
  12799. {
  12800. #if DIGIT_BIT == 59
  12801. int i;
  12802. sp_digit j = (sp_digit)0 - (sp_digit)a->used;
  12803. int o = 0;
  12804. for (i = 0; i < size; i++) {
  12805. sp_digit mask = (sp_digit)0 - (j >> 58);
  12806. r[i] = a->dp[o] & mask;
  12807. j++;
  12808. o += (int)(j >> 58);
  12809. }
  12810. #elif DIGIT_BIT > 59
  12811. unsigned int i;
  12812. int j = 0;
  12813. word32 s = 0;
  12814. r[0] = 0;
  12815. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  12816. r[j] |= ((sp_digit)a->dp[i] << s);
  12817. r[j] &= 0x7ffffffffffffffL;
  12818. s = 59U - s;
  12819. if (j + 1 >= size) {
  12820. break;
  12821. }
  12822. /* lint allow cast of mismatch word32 and mp_digit */
  12823. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  12824. while ((s + 59U) <= (word32)DIGIT_BIT) {
  12825. s += 59U;
  12826. r[j] &= 0x7ffffffffffffffL;
  12827. if (j + 1 >= size) {
  12828. break;
  12829. }
  12830. if (s < (word32)DIGIT_BIT) {
  12831. /* lint allow cast of mismatch word32 and mp_digit */
  12832. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  12833. }
  12834. else {
  12835. r[++j] = (sp_digit)0;
  12836. }
  12837. }
  12838. s = (word32)DIGIT_BIT - s;
  12839. }
  12840. for (j++; j < size; j++) {
  12841. r[j] = 0;
  12842. }
  12843. #else
  12844. unsigned int i;
  12845. int j = 0;
  12846. int s = 0;
  12847. r[0] = 0;
  12848. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  12849. r[j] |= ((sp_digit)a->dp[i]) << s;
  12850. if (s + DIGIT_BIT >= 59) {
  12851. r[j] &= 0x7ffffffffffffffL;
  12852. if (j + 1 >= size) {
  12853. break;
  12854. }
  12855. s = 59 - s;
  12856. if (s == DIGIT_BIT) {
  12857. r[++j] = 0;
  12858. s = 0;
  12859. }
  12860. else {
  12861. r[++j] = a->dp[i] >> s;
  12862. s = DIGIT_BIT - s;
  12863. }
  12864. }
  12865. else {
  12866. s += DIGIT_BIT;
  12867. }
  12868. }
  12869. for (j++; j < size; j++) {
  12870. r[j] = 0;
  12871. }
  12872. #endif
  12873. }
  12874. /* Write r as big endian to byte array.
  12875. * Fixed length number of bytes written: 512
  12876. *
  12877. * r A single precision integer.
  12878. * a Byte array.
  12879. */
  12880. static void sp_4096_to_bin_70(sp_digit* r, byte* a)
  12881. {
  12882. int i;
  12883. int j;
  12884. int s = 0;
  12885. int b;
  12886. for (i=0; i<69; i++) {
  12887. r[i+1] += r[i] >> 59;
  12888. r[i] &= 0x7ffffffffffffffL;
  12889. }
  12890. j = 4103 / 8 - 1;
  12891. a[j] = 0;
  12892. for (i=0; i<70 && j>=0; i++) {
  12893. b = 0;
  12894. /* lint allow cast of mismatch sp_digit and int */
  12895. a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
  12896. b += 8 - s;
  12897. if (j < 0) {
  12898. break;
  12899. }
  12900. while (b < 59) {
  12901. a[j--] = (byte)(r[i] >> b);
  12902. b += 8;
  12903. if (j < 0) {
  12904. break;
  12905. }
  12906. }
  12907. s = 8 - (b - 59);
  12908. if (j >= 0) {
  12909. a[j] = 0;
  12910. }
  12911. if (s != 0) {
  12912. j++;
  12913. }
  12914. }
  12915. }
  12916. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  12917. #if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D)
  12918. /* Normalize the values in each word to 59 bits.
  12919. *
  12920. * a Array of sp_digit to normalize.
  12921. */
  12922. static void sp_4096_norm_35(sp_digit* a)
  12923. {
  12924. int i;
  12925. for (i = 0; i < 34; i++) {
  12926. a[i+1] += a[i] >> 59;
  12927. a[i] &= 0x7ffffffffffffffL;
  12928. }
  12929. }
  12930. #endif /* WOLFSSL_HAVE_SP_RSA & !SP_RSA_PRIVATE_EXP_D */
  12931. #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
  12932. /* Normalize the values in each word to 59 bits.
  12933. *
  12934. * a Array of sp_digit to normalize.
  12935. */
  12936. static void sp_4096_norm_70(sp_digit* a)
  12937. {
  12938. int i;
  12939. for (i = 0; i < 69; i++) {
  12940. a[i+1] += a[i] >> 59;
  12941. a[i] &= 0x7ffffffffffffffL;
  12942. }
  12943. }
  12944. /* Multiply a and b into r. (r = a * b)
  12945. *
  12946. * r A single precision integer.
  12947. * a A single precision integer.
  12948. * b A single precision integer.
  12949. */
  12950. SP_NOINLINE static void sp_4096_mul_70(sp_digit* r, const sp_digit* a,
  12951. const sp_digit* b)
  12952. {
  12953. int i;
  12954. int imax;
  12955. int k;
  12956. sp_uint128 c;
  12957. sp_uint128 lo;
  12958. c = ((sp_uint128)a[69]) * b[69];
  12959. r[139] = (sp_digit)(c >> 59);
  12960. c &= 0x7ffffffffffffffL;
  12961. for (k = 137; k >= 0; k--) {
  12962. if (k >= 70) {
  12963. i = k - 69;
  12964. imax = 69;
  12965. }
  12966. else {
  12967. i = 0;
  12968. imax = k;
  12969. }
  12970. lo = 0;
  12971. for (; i <= imax; i++) {
  12972. lo += ((sp_uint128)a[i]) * b[k - i];
  12973. }
  12974. c += lo >> 59;
  12975. r[k + 2] += (sp_digit)(c >> 59);
  12976. r[k + 1] = (sp_digit)(c & 0x7ffffffffffffffL);
  12977. c = lo & 0x7ffffffffffffffL;
  12978. }
  12979. r[0] = (sp_digit)c;
  12980. }
  12981. /* Square a and put result in r. (r = a * a)
  12982. *
  12983. * r A single precision integer.
  12984. * a A single precision integer.
  12985. */
  12986. SP_NOINLINE static void sp_4096_sqr_70(sp_digit* r, const sp_digit* a)
  12987. {
  12988. int i;
  12989. int imax;
  12990. int k;
  12991. sp_uint128 c;
  12992. sp_uint128 t;
  12993. c = ((sp_uint128)a[69]) * a[69];
  12994. r[139] = (sp_digit)(c >> 59);
  12995. c = (c & 0x7ffffffffffffffL) << 59;
  12996. for (k = 137; k >= 0; k--) {
  12997. i = (k + 1) / 2;
  12998. if ((k & 1) == 0) {
  12999. c += ((sp_uint128)a[i]) * a[i];
  13000. i++;
  13001. }
  13002. if (k < 69) {
  13003. imax = k;
  13004. }
  13005. else {
  13006. imax = 69;
  13007. }
  13008. t = 0;
  13009. for (; i <= imax; i++) {
  13010. t += ((sp_uint128)a[i]) * a[k - i];
  13011. }
  13012. c += t * 2;
  13013. r[k + 2] += (sp_digit) (c >> 118);
  13014. r[k + 1] = (sp_digit)((c >> 59) & 0x7ffffffffffffffL);
  13015. c = (c & 0x7ffffffffffffffL) << 59;
  13016. }
  13017. r[0] = (sp_digit)(c >> 59);
  13018. }
  13019. /* Calculate the bottom digit of -1/a mod 2^n.
  13020. *
  13021. * a A single precision number.
  13022. * rho Bottom word of inverse.
  13023. */
  13024. static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho)
  13025. {
  13026. sp_digit x;
  13027. sp_digit b;
  13028. b = a[0];
  13029. x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
  13030. x *= 2 - b * x; /* here x*a==1 mod 2**8 */
  13031. x *= 2 - b * x; /* here x*a==1 mod 2**16 */
  13032. x *= 2 - b * x; /* here x*a==1 mod 2**32 */
  13033. x *= 2 - b * x; /* here x*a==1 mod 2**64 */
  13034. x &= 0x7ffffffffffffffL;
  13035. /* rho = -1/m mod b */
  13036. *rho = ((sp_digit)1 << 59) - x;
  13037. }
  13038. /* Multiply a by scalar b into r. (r = a * b)
  13039. *
  13040. * r A single precision integer.
  13041. * a A single precision integer.
  13042. * b A scalar.
  13043. */
  13044. SP_NOINLINE static void sp_4096_mul_d_70(sp_digit* r, const sp_digit* a,
  13045. sp_digit b)
  13046. {
  13047. sp_int128 tb = b;
  13048. sp_int128 t = 0;
  13049. int i;
  13050. for (i = 0; i < 70; i++) {
  13051. t += tb * a[i];
  13052. r[i] = (sp_digit)(t & 0x7ffffffffffffffL);
  13053. t >>= 59;
  13054. }
  13055. r[70] = (sp_digit)t;
  13056. }
  13057. #if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
  13058. #if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D)
  13059. /* Sub b from a into r. (r = a - b)
  13060. *
  13061. * r A single precision integer.
  13062. * a A single precision integer.
  13063. * b A single precision integer.
  13064. */
  13065. SP_NOINLINE static int sp_4096_sub_35(sp_digit* r, const sp_digit* a,
  13066. const sp_digit* b)
  13067. {
  13068. int i;
  13069. for (i = 0; i < 35; i++) {
  13070. r[i] = a[i] - b[i];
  13071. }
  13072. return 0;
  13073. }
  13074. /* r = 2^n mod m where n is the number of bits to reduce by.
  13075. * Given m must be 4096 bits, just need to subtract.
  13076. *
  13077. * r A single precision number.
  13078. * m A single precision number.
  13079. */
  13080. static void sp_4096_mont_norm_35(sp_digit* r, const sp_digit* m)
  13081. {
  13082. /* Set r = 2^n - 1. */
  13083. int i;
  13084. for (i=0; i<34; i++) {
  13085. r[i] = 0x7ffffffffffffffL;
  13086. }
  13087. r[34] = 0x3ffffffffffL;
  13088. /* r = (2^n - 1) mod n */
  13089. (void)sp_4096_sub_35(r, r, m);
  13090. /* Add one so r = 2^n mod m */
  13091. r[0] += 1;
  13092. }
  13093. /* Compare a with b in constant time.
  13094. *
  13095. * a A single precision integer.
  13096. * b A single precision integer.
  13097. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  13098. * respectively.
  13099. */
  13100. static sp_digit sp_4096_cmp_35(const sp_digit* a, const sp_digit* b)
  13101. {
  13102. sp_digit r = 0;
  13103. int i;
  13104. for (i=34; i>=0; i--) {
  13105. r |= (a[i] - b[i]) & ~(((sp_digit)0 - r) >> 58);
  13106. }
  13107. return r;
  13108. }
  13109. /* Conditionally subtract b from a using the mask m.
  13110. * m is -1 to subtract and 0 when not.
  13111. *
  13112. * r A single precision number representing condition subtract result.
  13113. * a A single precision number to subtract from.
  13114. * b A single precision number to subtract.
  13115. * m Mask value to apply.
  13116. */
  13117. static void sp_4096_cond_sub_35(sp_digit* r, const sp_digit* a,
  13118. const sp_digit* b, const sp_digit m)
  13119. {
  13120. int i;
  13121. for (i = 0; i < 35; i++) {
  13122. r[i] = a[i] - (b[i] & m);
  13123. }
  13124. }
  13125. /* Mul a by scalar b and add into r. (r += a * b)
  13126. *
  13127. * r A single precision integer.
  13128. * a A single precision integer.
  13129. * b A scalar.
  13130. */
  13131. SP_NOINLINE static void sp_4096_mul_add_35(sp_digit* r, const sp_digit* a,
  13132. const sp_digit b)
  13133. {
  13134. sp_int128 tb = b;
  13135. sp_int128 t[4];
  13136. int i;
  13137. t[0] = 0;
  13138. for (i = 0; i < 32; i += 4) {
  13139. t[0] += (tb * a[i+0]) + r[i+0];
  13140. t[1] = (tb * a[i+1]) + r[i+1];
  13141. t[2] = (tb * a[i+2]) + r[i+2];
  13142. t[3] = (tb * a[i+3]) + r[i+3];
  13143. r[i+0] = t[0] & 0x7ffffffffffffffL;
  13144. t[1] += t[0] >> 59;
  13145. r[i+1] = t[1] & 0x7ffffffffffffffL;
  13146. t[2] += t[1] >> 59;
  13147. r[i+2] = t[2] & 0x7ffffffffffffffL;
  13148. t[3] += t[2] >> 59;
  13149. r[i+3] = t[3] & 0x7ffffffffffffffL;
  13150. t[0] = t[3] >> 59;
  13151. }
  13152. t[0] += (tb * a[32]) + r[32];
  13153. t[1] = (tb * a[33]) + r[33];
  13154. t[2] = (tb * a[34]) + r[34];
  13155. r[32] = t[0] & 0x7ffffffffffffffL;
  13156. t[1] += t[0] >> 59;
  13157. r[33] = t[1] & 0x7ffffffffffffffL;
  13158. t[2] += t[1] >> 59;
  13159. r[34] = t[2] & 0x7ffffffffffffffL;
  13160. r[35] += (sp_digit)(t[2] >> 59);
  13161. }
  13162. /* Shift the result in the high 2048 bits down to the bottom.
  13163. *
  13164. * r A single precision number.
  13165. * a A single precision number.
  13166. */
  13167. static void sp_4096_mont_shift_35(sp_digit* r, const sp_digit* a)
  13168. {
  13169. int i;
  13170. sp_int128 n = a[34] >> 42;
  13171. n += ((sp_int128)a[35]) << 17;
  13172. for (i = 0; i < 34; i++) {
  13173. r[i] = n & 0x7ffffffffffffffL;
  13174. n >>= 59;
  13175. n += ((sp_int128)a[36 + i]) << 17;
  13176. }
  13177. r[34] = (sp_digit)n;
  13178. XMEMSET(&r[35], 0, sizeof(*r) * 35U);
  13179. }
  13180. /* Reduce the number back to 4096 bits using Montgomery reduction.
  13181. *
  13182. * a A single precision number to reduce in place.
  13183. * m The single precision number representing the modulus.
  13184. * mp The digit representing the negative inverse of m mod 2^n.
  13185. */
  13186. static void sp_4096_mont_reduce_35(sp_digit* a, const sp_digit* m, sp_digit mp)
  13187. {
  13188. int i;
  13189. sp_digit mu;
  13190. sp_digit over;
  13191. sp_4096_norm_35(a + 35);
  13192. for (i=0; i<34; i++) {
  13193. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x7ffffffffffffffL;
  13194. sp_4096_mul_add_35(a+i, m, mu);
  13195. a[i+1] += a[i] >> 59;
  13196. }
  13197. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x3ffffffffffL;
  13198. sp_4096_mul_add_35(a+i, m, mu);
  13199. a[i+1] += a[i] >> 59;
  13200. a[i] &= 0x7ffffffffffffffL;
  13201. sp_4096_mont_shift_35(a, a);
  13202. over = a[34] - m[34];
  13203. sp_4096_cond_sub_35(a, a, m, ~((over - 1) >> 63));
  13204. sp_4096_norm_35(a);
  13205. }
  13206. /* Multiply a and b into r. (r = a * b)
  13207. *
  13208. * r A single precision integer.
  13209. * a A single precision integer.
  13210. * b A single precision integer.
  13211. */
  13212. SP_NOINLINE static void sp_4096_mul_35(sp_digit* r, const sp_digit* a,
  13213. const sp_digit* b)
  13214. {
  13215. int i;
  13216. int imax;
  13217. int k;
  13218. sp_uint128 c;
  13219. sp_uint128 lo;
  13220. c = ((sp_uint128)a[34]) * b[34];
  13221. r[69] = (sp_digit)(c >> 59);
  13222. c &= 0x7ffffffffffffffL;
  13223. for (k = 67; k >= 0; k--) {
  13224. if (k >= 35) {
  13225. i = k - 34;
  13226. imax = 34;
  13227. }
  13228. else {
  13229. i = 0;
  13230. imax = k;
  13231. }
  13232. lo = 0;
  13233. for (; i <= imax; i++) {
  13234. lo += ((sp_uint128)a[i]) * b[k - i];
  13235. }
  13236. c += lo >> 59;
  13237. r[k + 2] += (sp_digit)(c >> 59);
  13238. r[k + 1] = (sp_digit)(c & 0x7ffffffffffffffL);
  13239. c = lo & 0x7ffffffffffffffL;
  13240. }
  13241. r[0] = (sp_digit)c;
  13242. }
  13243. /* Multiply two Montgomery form numbers mod the modulus (prime).
  13244. * (r = a * b mod m)
  13245. *
  13246. * r Result of multiplication.
  13247. * a First number to multiply in Montgomery form.
  13248. * b Second number to multiply in Montgomery form.
  13249. * m Modulus (prime).
  13250. * mp Montgomery multiplier.
  13251. */
  13252. SP_NOINLINE static void sp_4096_mont_mul_35(sp_digit* r, const sp_digit* a,
  13253. const sp_digit* b, const sp_digit* m, sp_digit mp)
  13254. {
  13255. sp_4096_mul_35(r, a, b);
  13256. sp_4096_mont_reduce_35(r, m, mp);
  13257. }
  13258. /* Square a and put result in r. (r = a * a)
  13259. *
  13260. * r A single precision integer.
  13261. * a A single precision integer.
  13262. */
  13263. SP_NOINLINE static void sp_4096_sqr_35(sp_digit* r, const sp_digit* a)
  13264. {
  13265. int i;
  13266. int imax;
  13267. int k;
  13268. sp_uint128 c;
  13269. sp_uint128 t;
  13270. c = ((sp_uint128)a[34]) * a[34];
  13271. r[69] = (sp_digit)(c >> 59);
  13272. c = (c & 0x7ffffffffffffffL) << 59;
  13273. for (k = 67; k >= 0; k--) {
  13274. i = (k + 1) / 2;
  13275. if ((k & 1) == 0) {
  13276. c += ((sp_uint128)a[i]) * a[i];
  13277. i++;
  13278. }
  13279. if (k < 34) {
  13280. imax = k;
  13281. }
  13282. else {
  13283. imax = 34;
  13284. }
  13285. t = 0;
  13286. for (; i <= imax; i++) {
  13287. t += ((sp_uint128)a[i]) * a[k - i];
  13288. }
  13289. c += t * 2;
  13290. r[k + 2] += (sp_digit) (c >> 118);
  13291. r[k + 1] = (sp_digit)((c >> 59) & 0x7ffffffffffffffL);
  13292. c = (c & 0x7ffffffffffffffL) << 59;
  13293. }
  13294. r[0] = (sp_digit)(c >> 59);
  13295. }
  13296. /* Square the Montgomery form number. (r = a * a mod m)
  13297. *
  13298. * r Result of squaring.
  13299. * a Number to square in Montgomery form.
  13300. * m Modulus (prime).
  13301. * mp Montgomery multiplier.
  13302. */
  13303. SP_NOINLINE static void sp_4096_mont_sqr_35(sp_digit* r, const sp_digit* a,
  13304. const sp_digit* m, sp_digit mp)
  13305. {
  13306. sp_4096_sqr_35(r, a);
  13307. sp_4096_mont_reduce_35(r, m, mp);
  13308. }
  13309. /* Multiply a by scalar b into r. (r = a * b)
  13310. *
  13311. * r A single precision integer.
  13312. * a A single precision integer.
  13313. * b A scalar.
  13314. */
  13315. SP_NOINLINE static void sp_4096_mul_d_35(sp_digit* r, const sp_digit* a,
  13316. sp_digit b)
  13317. {
  13318. sp_int128 tb = b;
  13319. sp_int128 t = 0;
  13320. int i;
  13321. for (i = 0; i < 35; i++) {
  13322. t += tb * a[i];
  13323. r[i] = (sp_digit)(t & 0x7ffffffffffffffL);
  13324. t >>= 59;
  13325. }
  13326. r[35] = (sp_digit)t;
  13327. }
  13328. #ifdef WOLFSSL_SP_SMALL
  13329. /* Conditionally add a and b using the mask m.
  13330. * m is -1 to add and 0 when not.
  13331. *
  13332. * r A single precision number representing conditional add result.
  13333. * a A single precision number to add with.
  13334. * b A single precision number to add.
  13335. * m Mask value to apply.
  13336. */
  13337. static void sp_4096_cond_add_35(sp_digit* r, const sp_digit* a,
  13338. const sp_digit* b, const sp_digit m)
  13339. {
  13340. int i;
  13341. for (i = 0; i < 35; i++) {
  13342. r[i] = a[i] + (b[i] & m);
  13343. }
  13344. }
  13345. #endif /* WOLFSSL_SP_SMALL */
  13346. /* Add b to a into r. (r = a + b)
  13347. *
  13348. * r A single precision integer.
  13349. * a A single precision integer.
  13350. * b A single precision integer.
  13351. */
  13352. SP_NOINLINE static int sp_4096_add_35(sp_digit* r, const sp_digit* a,
  13353. const sp_digit* b)
  13354. {
  13355. int i;
  13356. for (i = 0; i < 35; i++) {
  13357. r[i] = a[i] + b[i];
  13358. }
  13359. return 0;
  13360. }
  13361. SP_NOINLINE static void sp_4096_rshift_35(sp_digit* r, const sp_digit* a,
  13362. byte n)
  13363. {
  13364. int i;
  13365. for (i=0; i<34; i++) {
  13366. r[i] = ((a[i] >> n) | (a[i + 1] << (59 - n))) & 0x7ffffffffffffffL;
  13367. }
  13368. r[34] = a[34] >> n;
  13369. }
  13370. static WC_INLINE sp_digit sp_4096_div_word_35(sp_digit d1, sp_digit d0,
  13371. sp_digit div)
  13372. {
  13373. #ifdef SP_USE_DIVTI3
  13374. sp_int128 d = ((sp_int128)d1 << 59) + d0;
  13375. return d / div;
  13376. #elif defined(__x86_64__) || defined(__i386__)
  13377. sp_int128 d = ((sp_int128)d1 << 59) + d0;
  13378. sp_uint64 lo = (sp_uint64)d;
  13379. sp_digit hi = (sp_digit)(d >> 64);
  13380. __asm__ __volatile__ (
  13381. "idiv %2"
  13382. : "+a" (lo)
  13383. : "d" (hi), "r" (div)
  13384. : "cc"
  13385. );
  13386. return (sp_digit)lo;
  13387. #elif !defined(__aarch64__) && !defined(SP_DIV_WORD_USE_DIV)
  13388. sp_int128 d = ((sp_int128)d1 << 59) + d0;
  13389. sp_digit dv = (div >> 1) + 1;
  13390. sp_digit t1 = (sp_digit)(d >> 59);
  13391. sp_digit t0 = (sp_digit)(d & 0x7ffffffffffffffL);
  13392. sp_digit t2;
  13393. sp_digit sign;
  13394. sp_digit r;
  13395. int i;
  13396. sp_int128 m;
  13397. r = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  13398. t1 -= dv & (0 - r);
  13399. for (i = 57; i >= 1; i--) {
  13400. t1 += t1 + (((sp_uint64)t0 >> 58) & 1);
  13401. t0 <<= 1;
  13402. t2 = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  13403. r += r + t2;
  13404. t1 -= dv & (0 - t2);
  13405. t1 += t2;
  13406. }
  13407. r += r + 1;
  13408. m = d - ((sp_int128)r * div);
  13409. r += (sp_digit)(m >> 59);
  13410. m = d - ((sp_int128)r * div);
  13411. r += (sp_digit)(m >> 118) - (sp_digit)(d >> 118);
  13412. m = d - ((sp_int128)r * div);
  13413. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  13414. m *= sign;
  13415. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  13416. r += sign * t2;
  13417. m = d - ((sp_int128)r * div);
  13418. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  13419. m *= sign;
  13420. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  13421. r += sign * t2;
  13422. return r;
  13423. #else
  13424. sp_int128 d = ((sp_int128)d1 << 59) + d0;
  13425. sp_digit r = 0;
  13426. sp_digit t;
  13427. sp_digit dv = (div >> 28) + 1;
  13428. t = (sp_digit)(d >> 56);
  13429. t = (t / dv) << 28;
  13430. r += t;
  13431. d -= (sp_int128)t * div;
  13432. t = (sp_digit)(d >> 25);
  13433. t = t / (dv << 3);
  13434. r += t;
  13435. d -= (sp_int128)t * div;
  13436. t = (sp_digit)d;
  13437. t = t / div;
  13438. r += t;
  13439. d -= (sp_int128)t * div;
  13440. return r;
  13441. #endif
  13442. }
  13443. static WC_INLINE sp_digit sp_4096_word_div_word_35(sp_digit d, sp_digit div)
  13444. {
  13445. #if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \
  13446. defined(SP_DIV_WORD_USE_DIV)
  13447. return d / div;
  13448. #else
  13449. return (sp_digit)((sp_uint64)(div - d) >> 63);
  13450. #endif
  13451. }
  13452. /* Divide d in a and put remainder into r (m*d + r = a)
  13453. * m is not calculated as it is not needed at this time.
  13454. *
  13455. * Full implementation.
  13456. *
  13457. * a Number to be divided.
  13458. * d Number to divide with.
  13459. * m Multiplier result.
  13460. * r Remainder from the division.
  13461. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  13462. */
  13463. static int sp_4096_div_35(const sp_digit* a, const sp_digit* d,
  13464. const sp_digit* m, sp_digit* r)
  13465. {
  13466. int i;
  13467. #ifndef WOLFSSL_SP_DIV_64
  13468. #endif
  13469. sp_digit dv;
  13470. sp_digit r1;
  13471. #ifdef WOLFSSL_SP_SMALL_STACK
  13472. sp_digit* t1 = NULL;
  13473. #else
  13474. sp_digit t1[4 * 35 + 3];
  13475. #endif
  13476. sp_digit* t2 = NULL;
  13477. sp_digit* sd = NULL;
  13478. int err = MP_OKAY;
  13479. (void)m;
  13480. #ifdef WOLFSSL_SP_SMALL_STACK
  13481. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 35 + 3), NULL,
  13482. DYNAMIC_TYPE_TMP_BUFFER);
  13483. if (t1 == NULL)
  13484. err = MEMORY_E;
  13485. #endif
  13486. (void)m;
  13487. if (err == MP_OKAY) {
  13488. t2 = t1 + 70 + 1;
  13489. sd = t2 + 35 + 1;
  13490. sp_4096_mul_d_35(sd, d, (sp_digit)1 << 17);
  13491. sp_4096_mul_d_70(t1, a, (sp_digit)1 << 17);
  13492. dv = sd[34];
  13493. t1[35 + 35] += t1[35 + 35 - 1] >> 59;
  13494. t1[35 + 35 - 1] &= 0x7ffffffffffffffL;
  13495. for (i=35; i>=0; i--) {
  13496. r1 = sp_4096_div_word_35(t1[35 + i], t1[35 + i - 1], dv);
  13497. sp_4096_mul_d_35(t2, sd, r1);
  13498. (void)sp_4096_sub_35(&t1[i], &t1[i], t2);
  13499. sp_4096_norm_35(&t1[i]);
  13500. t1[35 + i] -= t2[35];
  13501. t1[35 + i] += t1[35 + i - 1] >> 59;
  13502. t1[35 + i - 1] &= 0x7ffffffffffffffL;
  13503. r1 = sp_4096_div_word_35(-t1[35 + i], -t1[35 + i - 1], dv);
  13504. r1 -= t1[35 + i];
  13505. sp_4096_mul_d_35(t2, sd, r1);
  13506. (void)sp_4096_add_35(&t1[i], &t1[i], t2);
  13507. t1[35 + i] += t1[35 + i - 1] >> 59;
  13508. t1[35 + i - 1] &= 0x7ffffffffffffffL;
  13509. }
  13510. t1[35 - 1] += t1[35 - 2] >> 59;
  13511. t1[35 - 2] &= 0x7ffffffffffffffL;
  13512. r1 = sp_4096_word_div_word_35(t1[35 - 1], dv);
  13513. sp_4096_mul_d_35(t2, sd, r1);
  13514. sp_4096_sub_35(t1, t1, t2);
  13515. XMEMCPY(r, t1, sizeof(*r) * 70U);
  13516. for (i=0; i<34; i++) {
  13517. r[i+1] += r[i] >> 59;
  13518. r[i] &= 0x7ffffffffffffffL;
  13519. }
  13520. sp_4096_cond_add_35(r, r, sd, r[34] >> 63);
  13521. sp_4096_norm_35(r);
  13522. sp_4096_rshift_35(r, r, 17);
  13523. }
  13524. #ifdef WOLFSSL_SP_SMALL_STACK
  13525. if (t1 != NULL)
  13526. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  13527. #endif
  13528. return err;
  13529. }
  13530. /* Reduce a modulo m into r. (r = a mod m)
  13531. *
  13532. * r A single precision number that is the reduced result.
  13533. * a A single precision number that is to be reduced.
  13534. * m A single precision number that is the modulus to reduce with.
  13535. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  13536. */
  13537. static int sp_4096_mod_35(sp_digit* r, const sp_digit* a, const sp_digit* m)
  13538. {
  13539. return sp_4096_div_35(a, m, NULL, r);
  13540. }
  13541. /* Modular exponentiate a to the e mod m. (r = a^e mod m)
  13542. *
  13543. * r A single precision number that is the result of the operation.
  13544. * a A single precision number being exponentiated.
  13545. * e A single precision number that is the exponent.
  13546. * bits The number of bits in the exponent.
  13547. * m A single precision number that is the modulus.
  13548. * returns 0 on success.
  13549. * returns MEMORY_E on dynamic memory allocation failure.
  13550. * returns MP_VAL when base is even or exponent is 0.
  13551. */
  13552. static int sp_4096_mod_exp_35(sp_digit* r, const sp_digit* a, const sp_digit* e,
  13553. int bits, const sp_digit* m, int reduceA)
  13554. {
  13555. #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
  13556. #ifdef WOLFSSL_SP_SMALL_STACK
  13557. sp_digit* td = NULL;
  13558. #else
  13559. sp_digit td[3 * 70];
  13560. #endif
  13561. sp_digit* t[3] = {0, 0, 0};
  13562. sp_digit* norm = NULL;
  13563. sp_digit mp = 1;
  13564. sp_digit n;
  13565. int i;
  13566. int c;
  13567. byte y;
  13568. int err = MP_OKAY;
  13569. if (bits == 0) {
  13570. err = MP_VAL;
  13571. }
  13572. #ifdef WOLFSSL_SP_SMALL_STACK
  13573. if (err == MP_OKAY) {
  13574. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 35 * 2, NULL,
  13575. DYNAMIC_TYPE_TMP_BUFFER);
  13576. if (td == NULL)
  13577. err = MEMORY_E;
  13578. }
  13579. #endif
  13580. if (err == MP_OKAY) {
  13581. norm = td;
  13582. for (i=0; i<3; i++) {
  13583. t[i] = td + (i * 35 * 2);
  13584. XMEMSET(t[i], 0, sizeof(sp_digit) * 35U * 2U);
  13585. }
  13586. sp_4096_mont_setup(m, &mp);
  13587. sp_4096_mont_norm_35(norm, m);
  13588. if (reduceA != 0) {
  13589. err = sp_4096_mod_35(t[1], a, m);
  13590. }
  13591. else {
  13592. XMEMCPY(t[1], a, sizeof(sp_digit) * 35U);
  13593. }
  13594. }
  13595. if (err == MP_OKAY) {
  13596. sp_4096_mul_35(t[1], t[1], norm);
  13597. err = sp_4096_mod_35(t[1], t[1], m);
  13598. }
  13599. if (err == MP_OKAY) {
  13600. i = bits / 59;
  13601. c = bits % 59;
  13602. n = e[i--] << (59 - c);
  13603. for (; ; c--) {
  13604. if (c == 0) {
  13605. if (i == -1) {
  13606. break;
  13607. }
  13608. n = e[i--];
  13609. c = 59;
  13610. }
  13611. y = (int)((n >> 58) & 1);
  13612. n <<= 1;
  13613. sp_4096_mont_mul_35(t[y^1], t[0], t[1], m, mp);
  13614. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  13615. ((size_t)t[1] & addr_mask[y])),
  13616. sizeof(*t[2]) * 35 * 2);
  13617. sp_4096_mont_sqr_35(t[2], t[2], m, mp);
  13618. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  13619. ((size_t)t[1] & addr_mask[y])), t[2],
  13620. sizeof(*t[2]) * 35 * 2);
  13621. }
  13622. sp_4096_mont_reduce_35(t[0], m, mp);
  13623. n = sp_4096_cmp_35(t[0], m);
  13624. sp_4096_cond_sub_35(t[0], t[0], m, ~(n >> 63));
  13625. XMEMCPY(r, t[0], sizeof(*r) * 35 * 2);
  13626. }
  13627. #ifdef WOLFSSL_SP_SMALL_STACK
  13628. if (td != NULL)
  13629. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  13630. #endif
  13631. return err;
  13632. #elif !defined(WC_NO_CACHE_RESISTANT)
  13633. #ifdef WOLFSSL_SP_SMALL_STACK
  13634. sp_digit* td = NULL;
  13635. #else
  13636. sp_digit td[3 * 70];
  13637. #endif
  13638. sp_digit* t[3] = {0, 0, 0};
  13639. sp_digit* norm = NULL;
  13640. sp_digit mp = 1;
  13641. sp_digit n;
  13642. int i;
  13643. int c;
  13644. byte y;
  13645. int err = MP_OKAY;
  13646. if (bits == 0) {
  13647. err = MP_VAL;
  13648. }
  13649. #ifdef WOLFSSL_SP_SMALL_STACK
  13650. if (err == MP_OKAY) {
  13651. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 35 * 2, NULL,
  13652. DYNAMIC_TYPE_TMP_BUFFER);
  13653. if (td == NULL)
  13654. err = MEMORY_E;
  13655. }
  13656. #endif
  13657. if (err == MP_OKAY) {
  13658. norm = td;
  13659. for (i=0; i<3; i++) {
  13660. t[i] = td + (i * 35 * 2);
  13661. }
  13662. sp_4096_mont_setup(m, &mp);
  13663. sp_4096_mont_norm_35(norm, m);
  13664. if (reduceA != 0) {
  13665. err = sp_4096_mod_35(t[1], a, m);
  13666. if (err == MP_OKAY) {
  13667. sp_4096_mul_35(t[1], t[1], norm);
  13668. err = sp_4096_mod_35(t[1], t[1], m);
  13669. }
  13670. }
  13671. else {
  13672. sp_4096_mul_35(t[1], a, norm);
  13673. err = sp_4096_mod_35(t[1], t[1], m);
  13674. }
  13675. }
  13676. if (err == MP_OKAY) {
  13677. i = bits / 59;
  13678. c = bits % 59;
  13679. n = e[i--] << (59 - c);
  13680. for (; ; c--) {
  13681. if (c == 0) {
  13682. if (i == -1) {
  13683. break;
  13684. }
  13685. n = e[i--];
  13686. c = 59;
  13687. }
  13688. y = (int)((n >> 58) & 1);
  13689. n <<= 1;
  13690. sp_4096_mont_mul_35(t[y^1], t[0], t[1], m, mp);
  13691. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  13692. ((size_t)t[1] & addr_mask[y])),
  13693. sizeof(*t[2]) * 35 * 2);
  13694. sp_4096_mont_sqr_35(t[2], t[2], m, mp);
  13695. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  13696. ((size_t)t[1] & addr_mask[y])), t[2],
  13697. sizeof(*t[2]) * 35 * 2);
  13698. }
  13699. sp_4096_mont_reduce_35(t[0], m, mp);
  13700. n = sp_4096_cmp_35(t[0], m);
  13701. sp_4096_cond_sub_35(t[0], t[0], m, ~(n >> 63));
  13702. XMEMCPY(r, t[0], sizeof(*r) * 35 * 2);
  13703. }
  13704. #ifdef WOLFSSL_SP_SMALL_STACK
  13705. if (td != NULL)
  13706. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  13707. #endif
  13708. return err;
  13709. #else
  13710. #ifdef WOLFSSL_SP_SMALL_STACK
  13711. sp_digit* td = NULL;
  13712. #else
  13713. sp_digit td[(32 * 70) + 70];
  13714. #endif
  13715. sp_digit* t[32];
  13716. sp_digit* rt = NULL;
  13717. sp_digit* norm = NULL;
  13718. sp_digit mp = 1;
  13719. sp_digit n;
  13720. int i;
  13721. int c;
  13722. byte y;
  13723. int err = MP_OKAY;
  13724. if (bits == 0) {
  13725. err = MP_VAL;
  13726. }
  13727. #ifdef WOLFSSL_SP_SMALL_STACK
  13728. if (err == MP_OKAY) {
  13729. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((32 * 70) + 70), NULL,
  13730. DYNAMIC_TYPE_TMP_BUFFER);
  13731. if (td == NULL)
  13732. err = MEMORY_E;
  13733. }
  13734. #endif
  13735. if (err == MP_OKAY) {
  13736. norm = td;
  13737. for (i=0; i<32; i++)
  13738. t[i] = td + i * 70;
  13739. rt = td + 2240;
  13740. sp_4096_mont_setup(m, &mp);
  13741. sp_4096_mont_norm_35(norm, m);
  13742. if (reduceA != 0) {
  13743. err = sp_4096_mod_35(t[1], a, m);
  13744. if (err == MP_OKAY) {
  13745. sp_4096_mul_35(t[1], t[1], norm);
  13746. err = sp_4096_mod_35(t[1], t[1], m);
  13747. }
  13748. }
  13749. else {
  13750. sp_4096_mul_35(t[1], a, norm);
  13751. err = sp_4096_mod_35(t[1], t[1], m);
  13752. }
  13753. }
  13754. if (err == MP_OKAY) {
  13755. sp_4096_mont_sqr_35(t[ 2], t[ 1], m, mp);
  13756. sp_4096_mont_mul_35(t[ 3], t[ 2], t[ 1], m, mp);
  13757. sp_4096_mont_sqr_35(t[ 4], t[ 2], m, mp);
  13758. sp_4096_mont_mul_35(t[ 5], t[ 3], t[ 2], m, mp);
  13759. sp_4096_mont_sqr_35(t[ 6], t[ 3], m, mp);
  13760. sp_4096_mont_mul_35(t[ 7], t[ 4], t[ 3], m, mp);
  13761. sp_4096_mont_sqr_35(t[ 8], t[ 4], m, mp);
  13762. sp_4096_mont_mul_35(t[ 9], t[ 5], t[ 4], m, mp);
  13763. sp_4096_mont_sqr_35(t[10], t[ 5], m, mp);
  13764. sp_4096_mont_mul_35(t[11], t[ 6], t[ 5], m, mp);
  13765. sp_4096_mont_sqr_35(t[12], t[ 6], m, mp);
  13766. sp_4096_mont_mul_35(t[13], t[ 7], t[ 6], m, mp);
  13767. sp_4096_mont_sqr_35(t[14], t[ 7], m, mp);
  13768. sp_4096_mont_mul_35(t[15], t[ 8], t[ 7], m, mp);
  13769. sp_4096_mont_sqr_35(t[16], t[ 8], m, mp);
  13770. sp_4096_mont_mul_35(t[17], t[ 9], t[ 8], m, mp);
  13771. sp_4096_mont_sqr_35(t[18], t[ 9], m, mp);
  13772. sp_4096_mont_mul_35(t[19], t[10], t[ 9], m, mp);
  13773. sp_4096_mont_sqr_35(t[20], t[10], m, mp);
  13774. sp_4096_mont_mul_35(t[21], t[11], t[10], m, mp);
  13775. sp_4096_mont_sqr_35(t[22], t[11], m, mp);
  13776. sp_4096_mont_mul_35(t[23], t[12], t[11], m, mp);
  13777. sp_4096_mont_sqr_35(t[24], t[12], m, mp);
  13778. sp_4096_mont_mul_35(t[25], t[13], t[12], m, mp);
  13779. sp_4096_mont_sqr_35(t[26], t[13], m, mp);
  13780. sp_4096_mont_mul_35(t[27], t[14], t[13], m, mp);
  13781. sp_4096_mont_sqr_35(t[28], t[14], m, mp);
  13782. sp_4096_mont_mul_35(t[29], t[15], t[14], m, mp);
  13783. sp_4096_mont_sqr_35(t[30], t[15], m, mp);
  13784. sp_4096_mont_mul_35(t[31], t[16], t[15], m, mp);
  13785. bits = ((bits + 4) / 5) * 5;
  13786. i = ((bits + 58) / 59) - 1;
  13787. c = bits % 59;
  13788. if (c == 0) {
  13789. c = 59;
  13790. }
  13791. if (i < 35) {
  13792. n = e[i--] << (64 - c);
  13793. }
  13794. else {
  13795. n = 0;
  13796. i--;
  13797. }
  13798. if (c < 5) {
  13799. n |= e[i--] << (5 - c);
  13800. c += 59;
  13801. }
  13802. y = (int)((n >> 59) & 0x1f);
  13803. n <<= 5;
  13804. c -= 5;
  13805. XMEMCPY(rt, t[y], sizeof(sp_digit) * 70);
  13806. while ((i >= 0) || (c >= 5)) {
  13807. if (c >= 5) {
  13808. y = (byte)((n >> 59) & 0x1f);
  13809. n <<= 5;
  13810. c -= 5;
  13811. }
  13812. else if (c == 0) {
  13813. n = e[i--] << 5;
  13814. y = (byte)((n >> 59) & 0x1f);
  13815. n <<= 5;
  13816. c = 54;
  13817. }
  13818. else {
  13819. y = (byte)((n >> 59) & 0x1f);
  13820. n = e[i--] << 5;
  13821. c = 5 - c;
  13822. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  13823. n <<= c;
  13824. c = 59 - c;
  13825. }
  13826. sp_4096_mont_sqr_35(rt, rt, m, mp);
  13827. sp_4096_mont_sqr_35(rt, rt, m, mp);
  13828. sp_4096_mont_sqr_35(rt, rt, m, mp);
  13829. sp_4096_mont_sqr_35(rt, rt, m, mp);
  13830. sp_4096_mont_sqr_35(rt, rt, m, mp);
  13831. sp_4096_mont_mul_35(rt, rt, t[y], m, mp);
  13832. }
  13833. sp_4096_mont_reduce_35(rt, m, mp);
  13834. n = sp_4096_cmp_35(rt, m);
  13835. sp_4096_cond_sub_35(rt, rt, m, ~(n >> 63));
  13836. XMEMCPY(r, rt, sizeof(sp_digit) * 70);
  13837. }
  13838. #ifdef WOLFSSL_SP_SMALL_STACK
  13839. if (td != NULL)
  13840. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  13841. #endif
  13842. return err;
  13843. #endif
  13844. }
  13845. #endif /* WOLFSSL_HAVE_SP_RSA & !SP_RSA_PRIVATE_EXP_D */
  13846. #endif /* (WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH) & !WOLFSSL_RSA_PUBLIC_ONLY */
  13847. /* Sub b from a into r. (r = a - b)
  13848. *
  13849. * r A single precision integer.
  13850. * a A single precision integer.
  13851. * b A single precision integer.
  13852. */
  13853. SP_NOINLINE static int sp_4096_sub_70(sp_digit* r, const sp_digit* a,
  13854. const sp_digit* b)
  13855. {
  13856. int i;
  13857. for (i = 0; i < 70; i++) {
  13858. r[i] = a[i] - b[i];
  13859. }
  13860. return 0;
  13861. }
  13862. /* r = 2^n mod m where n is the number of bits to reduce by.
  13863. * Given m must be 4096 bits, just need to subtract.
  13864. *
  13865. * r A single precision number.
  13866. * m A single precision number.
  13867. */
  13868. static void sp_4096_mont_norm_70(sp_digit* r, const sp_digit* m)
  13869. {
  13870. /* Set r = 2^n - 1. */
  13871. int i;
  13872. for (i=0; i<69; i++) {
  13873. r[i] = 0x7ffffffffffffffL;
  13874. }
  13875. r[69] = 0x1ffffffL;
  13876. /* r = (2^n - 1) mod n */
  13877. (void)sp_4096_sub_70(r, r, m);
  13878. /* Add one so r = 2^n mod m */
  13879. r[0] += 1;
  13880. }
  13881. /* Compare a with b in constant time.
  13882. *
  13883. * a A single precision integer.
  13884. * b A single precision integer.
  13885. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  13886. * respectively.
  13887. */
  13888. static sp_digit sp_4096_cmp_70(const sp_digit* a, const sp_digit* b)
  13889. {
  13890. sp_digit r = 0;
  13891. int i;
  13892. for (i=69; i>=0; i--) {
  13893. r |= (a[i] - b[i]) & ~(((sp_digit)0 - r) >> 58);
  13894. }
  13895. return r;
  13896. }
  13897. /* Conditionally subtract b from a using the mask m.
  13898. * m is -1 to subtract and 0 when not.
  13899. *
  13900. * r A single precision number representing condition subtract result.
  13901. * a A single precision number to subtract from.
  13902. * b A single precision number to subtract.
  13903. * m Mask value to apply.
  13904. */
  13905. static void sp_4096_cond_sub_70(sp_digit* r, const sp_digit* a,
  13906. const sp_digit* b, const sp_digit m)
  13907. {
  13908. int i;
  13909. for (i = 0; i < 70; i++) {
  13910. r[i] = a[i] - (b[i] & m);
  13911. }
  13912. }
  13913. /* Mul a by scalar b and add into r. (r += a * b)
  13914. *
  13915. * r A single precision integer.
  13916. * a A single precision integer.
  13917. * b A scalar.
  13918. */
  13919. SP_NOINLINE static void sp_4096_mul_add_70(sp_digit* r, const sp_digit* a,
  13920. const sp_digit b)
  13921. {
  13922. sp_int128 tb = b;
  13923. sp_int128 t[4];
  13924. int i;
  13925. t[0] = 0;
  13926. for (i = 0; i < 68; i += 4) {
  13927. t[0] += (tb * a[i+0]) + r[i+0];
  13928. t[1] = (tb * a[i+1]) + r[i+1];
  13929. t[2] = (tb * a[i+2]) + r[i+2];
  13930. t[3] = (tb * a[i+3]) + r[i+3];
  13931. r[i+0] = t[0] & 0x7ffffffffffffffL;
  13932. t[1] += t[0] >> 59;
  13933. r[i+1] = t[1] & 0x7ffffffffffffffL;
  13934. t[2] += t[1] >> 59;
  13935. r[i+2] = t[2] & 0x7ffffffffffffffL;
  13936. t[3] += t[2] >> 59;
  13937. r[i+3] = t[3] & 0x7ffffffffffffffL;
  13938. t[0] = t[3] >> 59;
  13939. }
  13940. t[0] += (tb * a[68]) + r[68];
  13941. t[1] = (tb * a[69]) + r[69];
  13942. r[68] = t[0] & 0x7ffffffffffffffL;
  13943. t[1] += t[0] >> 59;
  13944. r[69] = t[1] & 0x7ffffffffffffffL;
  13945. r[70] += (sp_digit)(t[1] >> 59);
  13946. }
  13947. /* Shift the result in the high 4096 bits down to the bottom.
  13948. *
  13949. * r A single precision number.
  13950. * a A single precision number.
  13951. */
  13952. static void sp_4096_mont_shift_70(sp_digit* r, const sp_digit* a)
  13953. {
  13954. int i;
  13955. sp_int128 n = a[69] >> 25;
  13956. n += ((sp_int128)a[70]) << 34;
  13957. for (i = 0; i < 69; i++) {
  13958. r[i] = n & 0x7ffffffffffffffL;
  13959. n >>= 59;
  13960. n += ((sp_int128)a[71 + i]) << 34;
  13961. }
  13962. r[69] = (sp_digit)n;
  13963. XMEMSET(&r[70], 0, sizeof(*r) * 70U);
  13964. }
  13965. /* Reduce the number back to 4096 bits using Montgomery reduction.
  13966. *
  13967. * a A single precision number to reduce in place.
  13968. * m The single precision number representing the modulus.
  13969. * mp The digit representing the negative inverse of m mod 2^n.
  13970. */
  13971. static void sp_4096_mont_reduce_70(sp_digit* a, const sp_digit* m, sp_digit mp)
  13972. {
  13973. int i;
  13974. sp_digit mu;
  13975. sp_digit over;
  13976. sp_4096_norm_70(a + 70);
  13977. #ifdef WOLFSSL_SP_DH
  13978. if (mp != 1) {
  13979. for (i=0; i<69; i++) {
  13980. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x7ffffffffffffffL;
  13981. sp_4096_mul_add_70(a+i, m, mu);
  13982. a[i+1] += a[i] >> 59;
  13983. }
  13984. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1ffffffL;
  13985. sp_4096_mul_add_70(a+i, m, mu);
  13986. a[i+1] += a[i] >> 59;
  13987. a[i] &= 0x7ffffffffffffffL;
  13988. }
  13989. else {
  13990. for (i=0; i<69; i++) {
  13991. mu = a[i] & 0x7ffffffffffffffL;
  13992. sp_4096_mul_add_70(a+i, m, mu);
  13993. a[i+1] += a[i] >> 59;
  13994. }
  13995. mu = a[i] & 0x1ffffffL;
  13996. sp_4096_mul_add_70(a+i, m, mu);
  13997. a[i+1] += a[i] >> 59;
  13998. a[i] &= 0x7ffffffffffffffL;
  13999. }
  14000. #else
  14001. for (i=0; i<69; i++) {
  14002. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x7ffffffffffffffL;
  14003. sp_4096_mul_add_70(a+i, m, mu);
  14004. a[i+1] += a[i] >> 59;
  14005. }
  14006. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1ffffffL;
  14007. sp_4096_mul_add_70(a+i, m, mu);
  14008. a[i+1] += a[i] >> 59;
  14009. a[i] &= 0x7ffffffffffffffL;
  14010. #endif
  14011. sp_4096_mont_shift_70(a, a);
  14012. over = a[69] - m[69];
  14013. sp_4096_cond_sub_70(a, a, m, ~((over - 1) >> 63));
  14014. sp_4096_norm_70(a);
  14015. }
  14016. /* Multiply two Montgomery form numbers mod the modulus (prime).
  14017. * (r = a * b mod m)
  14018. *
  14019. * r Result of multiplication.
  14020. * a First number to multiply in Montgomery form.
  14021. * b Second number to multiply in Montgomery form.
  14022. * m Modulus (prime).
  14023. * mp Montgomery multiplier.
  14024. */
  14025. SP_NOINLINE static void sp_4096_mont_mul_70(sp_digit* r, const sp_digit* a,
  14026. const sp_digit* b, const sp_digit* m, sp_digit mp)
  14027. {
  14028. sp_4096_mul_70(r, a, b);
  14029. sp_4096_mont_reduce_70(r, m, mp);
  14030. }
  14031. /* Square the Montgomery form number. (r = a * a mod m)
  14032. *
  14033. * r Result of squaring.
  14034. * a Number to square in Montgomery form.
  14035. * m Modulus (prime).
  14036. * mp Montgomery multiplier.
  14037. */
  14038. SP_NOINLINE static void sp_4096_mont_sqr_70(sp_digit* r, const sp_digit* a,
  14039. const sp_digit* m, sp_digit mp)
  14040. {
  14041. sp_4096_sqr_70(r, a);
  14042. sp_4096_mont_reduce_70(r, m, mp);
  14043. }
  14044. /* Multiply a by scalar b into r. (r = a * b)
  14045. *
  14046. * r A single precision integer.
  14047. * a A single precision integer.
  14048. * b A scalar.
  14049. */
  14050. SP_NOINLINE static void sp_4096_mul_d_140(sp_digit* r, const sp_digit* a,
  14051. sp_digit b)
  14052. {
  14053. sp_int128 tb = b;
  14054. sp_int128 t = 0;
  14055. int i;
  14056. for (i = 0; i < 140; i++) {
  14057. t += tb * a[i];
  14058. r[i] = (sp_digit)(t & 0x7ffffffffffffffL);
  14059. t >>= 59;
  14060. }
  14061. r[140] = (sp_digit)t;
  14062. }
  14063. #ifdef WOLFSSL_SP_SMALL
  14064. /* Conditionally add a and b using the mask m.
  14065. * m is -1 to add and 0 when not.
  14066. *
  14067. * r A single precision number representing conditional add result.
  14068. * a A single precision number to add with.
  14069. * b A single precision number to add.
  14070. * m Mask value to apply.
  14071. */
  14072. static void sp_4096_cond_add_70(sp_digit* r, const sp_digit* a,
  14073. const sp_digit* b, const sp_digit m)
  14074. {
  14075. int i;
  14076. for (i = 0; i < 70; i++) {
  14077. r[i] = a[i] + (b[i] & m);
  14078. }
  14079. }
  14080. #endif /* WOLFSSL_SP_SMALL */
  14081. /* Add b to a into r. (r = a + b)
  14082. *
  14083. * r A single precision integer.
  14084. * a A single precision integer.
  14085. * b A single precision integer.
  14086. */
  14087. SP_NOINLINE static int sp_4096_add_70(sp_digit* r, const sp_digit* a,
  14088. const sp_digit* b)
  14089. {
  14090. int i;
  14091. for (i = 0; i < 70; i++) {
  14092. r[i] = a[i] + b[i];
  14093. }
  14094. return 0;
  14095. }
  14096. SP_NOINLINE static void sp_4096_rshift_70(sp_digit* r, const sp_digit* a,
  14097. byte n)
  14098. {
  14099. int i;
  14100. for (i=0; i<69; i++) {
  14101. r[i] = ((a[i] >> n) | (a[i + 1] << (59 - n))) & 0x7ffffffffffffffL;
  14102. }
  14103. r[69] = a[69] >> n;
  14104. }
  14105. static WC_INLINE sp_digit sp_4096_div_word_70(sp_digit d1, sp_digit d0,
  14106. sp_digit div)
  14107. {
  14108. #ifdef SP_USE_DIVTI3
  14109. sp_int128 d = ((sp_int128)d1 << 59) + d0;
  14110. return d / div;
  14111. #elif defined(__x86_64__) || defined(__i386__)
  14112. sp_int128 d = ((sp_int128)d1 << 59) + d0;
  14113. sp_uint64 lo = (sp_uint64)d;
  14114. sp_digit hi = (sp_digit)(d >> 64);
  14115. __asm__ __volatile__ (
  14116. "idiv %2"
  14117. : "+a" (lo)
  14118. : "d" (hi), "r" (div)
  14119. : "cc"
  14120. );
  14121. return (sp_digit)lo;
  14122. #elif !defined(__aarch64__) && !defined(SP_DIV_WORD_USE_DIV)
  14123. sp_int128 d = ((sp_int128)d1 << 59) + d0;
  14124. sp_digit dv = (div >> 1) + 1;
  14125. sp_digit t1 = (sp_digit)(d >> 59);
  14126. sp_digit t0 = (sp_digit)(d & 0x7ffffffffffffffL);
  14127. sp_digit t2;
  14128. sp_digit sign;
  14129. sp_digit r;
  14130. int i;
  14131. sp_int128 m;
  14132. r = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  14133. t1 -= dv & (0 - r);
  14134. for (i = 57; i >= 1; i--) {
  14135. t1 += t1 + (((sp_uint64)t0 >> 58) & 1);
  14136. t0 <<= 1;
  14137. t2 = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  14138. r += r + t2;
  14139. t1 -= dv & (0 - t2);
  14140. t1 += t2;
  14141. }
  14142. r += r + 1;
  14143. m = d - ((sp_int128)r * div);
  14144. r += (sp_digit)(m >> 59);
  14145. m = d - ((sp_int128)r * div);
  14146. r += (sp_digit)(m >> 118) - (sp_digit)(d >> 118);
  14147. m = d - ((sp_int128)r * div);
  14148. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  14149. m *= sign;
  14150. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  14151. r += sign * t2;
  14152. m = d - ((sp_int128)r * div);
  14153. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  14154. m *= sign;
  14155. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  14156. r += sign * t2;
  14157. return r;
  14158. #else
  14159. sp_int128 d = ((sp_int128)d1 << 59) + d0;
  14160. sp_digit r = 0;
  14161. sp_digit t;
  14162. sp_digit dv = (div >> 28) + 1;
  14163. t = (sp_digit)(d >> 56);
  14164. t = (t / dv) << 28;
  14165. r += t;
  14166. d -= (sp_int128)t * div;
  14167. t = (sp_digit)(d >> 25);
  14168. t = t / (dv << 3);
  14169. r += t;
  14170. d -= (sp_int128)t * div;
  14171. t = (sp_digit)d;
  14172. t = t / div;
  14173. r += t;
  14174. d -= (sp_int128)t * div;
  14175. return r;
  14176. #endif
  14177. }
  14178. static WC_INLINE sp_digit sp_4096_word_div_word_70(sp_digit d, sp_digit div)
  14179. {
  14180. #if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \
  14181. defined(SP_DIV_WORD_USE_DIV)
  14182. return d / div;
  14183. #else
  14184. return (sp_digit)((sp_uint64)(div - d) >> 63);
  14185. #endif
  14186. }
  14187. /* Divide d in a and put remainder into r (m*d + r = a)
  14188. * m is not calculated as it is not needed at this time.
  14189. *
  14190. * Full implementation.
  14191. *
  14192. * a Number to be divided.
  14193. * d Number to divide with.
  14194. * m Multiplier result.
  14195. * r Remainder from the division.
  14196. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  14197. */
  14198. static int sp_4096_div_70(const sp_digit* a, const sp_digit* d,
  14199. const sp_digit* m, sp_digit* r)
  14200. {
  14201. int i;
  14202. #ifndef WOLFSSL_SP_DIV_64
  14203. #endif
  14204. sp_digit dv;
  14205. sp_digit r1;
  14206. #ifdef WOLFSSL_SP_SMALL_STACK
  14207. sp_digit* t1 = NULL;
  14208. #else
  14209. sp_digit t1[4 * 70 + 3];
  14210. #endif
  14211. sp_digit* t2 = NULL;
  14212. sp_digit* sd = NULL;
  14213. int err = MP_OKAY;
  14214. (void)m;
  14215. #ifdef WOLFSSL_SP_SMALL_STACK
  14216. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 70 + 3), NULL,
  14217. DYNAMIC_TYPE_TMP_BUFFER);
  14218. if (t1 == NULL)
  14219. err = MEMORY_E;
  14220. #endif
  14221. (void)m;
  14222. if (err == MP_OKAY) {
  14223. t2 = t1 + 140 + 1;
  14224. sd = t2 + 70 + 1;
  14225. sp_4096_mul_d_70(sd, d, (sp_digit)1 << 34);
  14226. sp_4096_mul_d_140(t1, a, (sp_digit)1 << 34);
  14227. dv = sd[69];
  14228. t1[70 + 70] += t1[70 + 70 - 1] >> 59;
  14229. t1[70 + 70 - 1] &= 0x7ffffffffffffffL;
  14230. for (i=70; i>=0; i--) {
  14231. r1 = sp_4096_div_word_70(t1[70 + i], t1[70 + i - 1], dv);
  14232. sp_4096_mul_d_70(t2, sd, r1);
  14233. (void)sp_4096_sub_70(&t1[i], &t1[i], t2);
  14234. sp_4096_norm_70(&t1[i]);
  14235. t1[70 + i] -= t2[70];
  14236. t1[70 + i] += t1[70 + i - 1] >> 59;
  14237. t1[70 + i - 1] &= 0x7ffffffffffffffL;
  14238. r1 = sp_4096_div_word_70(-t1[70 + i], -t1[70 + i - 1], dv);
  14239. r1 -= t1[70 + i];
  14240. sp_4096_mul_d_70(t2, sd, r1);
  14241. (void)sp_4096_add_70(&t1[i], &t1[i], t2);
  14242. t1[70 + i] += t1[70 + i - 1] >> 59;
  14243. t1[70 + i - 1] &= 0x7ffffffffffffffL;
  14244. }
  14245. t1[70 - 1] += t1[70 - 2] >> 59;
  14246. t1[70 - 2] &= 0x7ffffffffffffffL;
  14247. r1 = sp_4096_word_div_word_70(t1[70 - 1], dv);
  14248. sp_4096_mul_d_70(t2, sd, r1);
  14249. sp_4096_sub_70(t1, t1, t2);
  14250. XMEMCPY(r, t1, sizeof(*r) * 140U);
  14251. for (i=0; i<69; i++) {
  14252. r[i+1] += r[i] >> 59;
  14253. r[i] &= 0x7ffffffffffffffL;
  14254. }
  14255. sp_4096_cond_add_70(r, r, sd, r[69] >> 63);
  14256. sp_4096_norm_70(r);
  14257. sp_4096_rshift_70(r, r, 34);
  14258. }
  14259. #ifdef WOLFSSL_SP_SMALL_STACK
  14260. if (t1 != NULL)
  14261. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  14262. #endif
  14263. return err;
  14264. }
  14265. /* Reduce a modulo m into r. (r = a mod m)
  14266. *
  14267. * r A single precision number that is the reduced result.
  14268. * a A single precision number that is to be reduced.
  14269. * m A single precision number that is the modulus to reduce with.
  14270. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  14271. */
  14272. static int sp_4096_mod_70(sp_digit* r, const sp_digit* a, const sp_digit* m)
  14273. {
  14274. return sp_4096_div_70(a, m, NULL, r);
  14275. }
  14276. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  14277. /* Modular exponentiate a to the e mod m. (r = a^e mod m)
  14278. *
  14279. * r A single precision number that is the result of the operation.
  14280. * a A single precision number being exponentiated.
  14281. * e A single precision number that is the exponent.
  14282. * bits The number of bits in the exponent.
  14283. * m A single precision number that is the modulus.
  14284. * returns 0 on success.
  14285. * returns MEMORY_E on dynamic memory allocation failure.
  14286. * returns MP_VAL when base is even or exponent is 0.
  14287. */
  14288. static int sp_4096_mod_exp_70(sp_digit* r, const sp_digit* a, const sp_digit* e,
  14289. int bits, const sp_digit* m, int reduceA)
  14290. {
  14291. #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
  14292. #ifdef WOLFSSL_SP_SMALL_STACK
  14293. sp_digit* td = NULL;
  14294. #else
  14295. sp_digit td[3 * 140];
  14296. #endif
  14297. sp_digit* t[3] = {0, 0, 0};
  14298. sp_digit* norm = NULL;
  14299. sp_digit mp = 1;
  14300. sp_digit n;
  14301. int i;
  14302. int c;
  14303. byte y;
  14304. int err = MP_OKAY;
  14305. if (bits == 0) {
  14306. err = MP_VAL;
  14307. }
  14308. #ifdef WOLFSSL_SP_SMALL_STACK
  14309. if (err == MP_OKAY) {
  14310. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 70 * 2, NULL,
  14311. DYNAMIC_TYPE_TMP_BUFFER);
  14312. if (td == NULL)
  14313. err = MEMORY_E;
  14314. }
  14315. #endif
  14316. if (err == MP_OKAY) {
  14317. norm = td;
  14318. for (i=0; i<3; i++) {
  14319. t[i] = td + (i * 70 * 2);
  14320. XMEMSET(t[i], 0, sizeof(sp_digit) * 70U * 2U);
  14321. }
  14322. sp_4096_mont_setup(m, &mp);
  14323. sp_4096_mont_norm_70(norm, m);
  14324. if (reduceA != 0) {
  14325. err = sp_4096_mod_70(t[1], a, m);
  14326. }
  14327. else {
  14328. XMEMCPY(t[1], a, sizeof(sp_digit) * 70U);
  14329. }
  14330. }
  14331. if (err == MP_OKAY) {
  14332. sp_4096_mul_70(t[1], t[1], norm);
  14333. err = sp_4096_mod_70(t[1], t[1], m);
  14334. }
  14335. if (err == MP_OKAY) {
  14336. i = bits / 59;
  14337. c = bits % 59;
  14338. n = e[i--] << (59 - c);
  14339. for (; ; c--) {
  14340. if (c == 0) {
  14341. if (i == -1) {
  14342. break;
  14343. }
  14344. n = e[i--];
  14345. c = 59;
  14346. }
  14347. y = (int)((n >> 58) & 1);
  14348. n <<= 1;
  14349. sp_4096_mont_mul_70(t[y^1], t[0], t[1], m, mp);
  14350. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  14351. ((size_t)t[1] & addr_mask[y])),
  14352. sizeof(*t[2]) * 70 * 2);
  14353. sp_4096_mont_sqr_70(t[2], t[2], m, mp);
  14354. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  14355. ((size_t)t[1] & addr_mask[y])), t[2],
  14356. sizeof(*t[2]) * 70 * 2);
  14357. }
  14358. sp_4096_mont_reduce_70(t[0], m, mp);
  14359. n = sp_4096_cmp_70(t[0], m);
  14360. sp_4096_cond_sub_70(t[0], t[0], m, ~(n >> 63));
  14361. XMEMCPY(r, t[0], sizeof(*r) * 70 * 2);
  14362. }
  14363. #ifdef WOLFSSL_SP_SMALL_STACK
  14364. if (td != NULL)
  14365. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  14366. #endif
  14367. return err;
  14368. #elif !defined(WC_NO_CACHE_RESISTANT)
  14369. #ifdef WOLFSSL_SP_SMALL_STACK
  14370. sp_digit* td = NULL;
  14371. #else
  14372. sp_digit td[3 * 140];
  14373. #endif
  14374. sp_digit* t[3] = {0, 0, 0};
  14375. sp_digit* norm = NULL;
  14376. sp_digit mp = 1;
  14377. sp_digit n;
  14378. int i;
  14379. int c;
  14380. byte y;
  14381. int err = MP_OKAY;
  14382. if (bits == 0) {
  14383. err = MP_VAL;
  14384. }
  14385. #ifdef WOLFSSL_SP_SMALL_STACK
  14386. if (err == MP_OKAY) {
  14387. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 70 * 2, NULL,
  14388. DYNAMIC_TYPE_TMP_BUFFER);
  14389. if (td == NULL)
  14390. err = MEMORY_E;
  14391. }
  14392. #endif
  14393. if (err == MP_OKAY) {
  14394. norm = td;
  14395. for (i=0; i<3; i++) {
  14396. t[i] = td + (i * 70 * 2);
  14397. }
  14398. sp_4096_mont_setup(m, &mp);
  14399. sp_4096_mont_norm_70(norm, m);
  14400. if (reduceA != 0) {
  14401. err = sp_4096_mod_70(t[1], a, m);
  14402. if (err == MP_OKAY) {
  14403. sp_4096_mul_70(t[1], t[1], norm);
  14404. err = sp_4096_mod_70(t[1], t[1], m);
  14405. }
  14406. }
  14407. else {
  14408. sp_4096_mul_70(t[1], a, norm);
  14409. err = sp_4096_mod_70(t[1], t[1], m);
  14410. }
  14411. }
  14412. if (err == MP_OKAY) {
  14413. i = bits / 59;
  14414. c = bits % 59;
  14415. n = e[i--] << (59 - c);
  14416. for (; ; c--) {
  14417. if (c == 0) {
  14418. if (i == -1) {
  14419. break;
  14420. }
  14421. n = e[i--];
  14422. c = 59;
  14423. }
  14424. y = (int)((n >> 58) & 1);
  14425. n <<= 1;
  14426. sp_4096_mont_mul_70(t[y^1], t[0], t[1], m, mp);
  14427. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  14428. ((size_t)t[1] & addr_mask[y])),
  14429. sizeof(*t[2]) * 70 * 2);
  14430. sp_4096_mont_sqr_70(t[2], t[2], m, mp);
  14431. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  14432. ((size_t)t[1] & addr_mask[y])), t[2],
  14433. sizeof(*t[2]) * 70 * 2);
  14434. }
  14435. sp_4096_mont_reduce_70(t[0], m, mp);
  14436. n = sp_4096_cmp_70(t[0], m);
  14437. sp_4096_cond_sub_70(t[0], t[0], m, ~(n >> 63));
  14438. XMEMCPY(r, t[0], sizeof(*r) * 70 * 2);
  14439. }
  14440. #ifdef WOLFSSL_SP_SMALL_STACK
  14441. if (td != NULL)
  14442. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  14443. #endif
  14444. return err;
  14445. #else
  14446. #ifdef WOLFSSL_SP_SMALL_STACK
  14447. sp_digit* td = NULL;
  14448. #else
  14449. sp_digit td[(16 * 140) + 140];
  14450. #endif
  14451. sp_digit* t[16];
  14452. sp_digit* rt = NULL;
  14453. sp_digit* norm = NULL;
  14454. sp_digit mp = 1;
  14455. sp_digit n;
  14456. int i;
  14457. int c;
  14458. byte y;
  14459. int err = MP_OKAY;
  14460. if (bits == 0) {
  14461. err = MP_VAL;
  14462. }
  14463. #ifdef WOLFSSL_SP_SMALL_STACK
  14464. if (err == MP_OKAY) {
  14465. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((16 * 140) + 140), NULL,
  14466. DYNAMIC_TYPE_TMP_BUFFER);
  14467. if (td == NULL)
  14468. err = MEMORY_E;
  14469. }
  14470. #endif
  14471. if (err == MP_OKAY) {
  14472. norm = td;
  14473. for (i=0; i<16; i++)
  14474. t[i] = td + i * 140;
  14475. rt = td + 2240;
  14476. sp_4096_mont_setup(m, &mp);
  14477. sp_4096_mont_norm_70(norm, m);
  14478. if (reduceA != 0) {
  14479. err = sp_4096_mod_70(t[1], a, m);
  14480. if (err == MP_OKAY) {
  14481. sp_4096_mul_70(t[1], t[1], norm);
  14482. err = sp_4096_mod_70(t[1], t[1], m);
  14483. }
  14484. }
  14485. else {
  14486. sp_4096_mul_70(t[1], a, norm);
  14487. err = sp_4096_mod_70(t[1], t[1], m);
  14488. }
  14489. }
  14490. if (err == MP_OKAY) {
  14491. sp_4096_mont_sqr_70(t[ 2], t[ 1], m, mp);
  14492. sp_4096_mont_mul_70(t[ 3], t[ 2], t[ 1], m, mp);
  14493. sp_4096_mont_sqr_70(t[ 4], t[ 2], m, mp);
  14494. sp_4096_mont_mul_70(t[ 5], t[ 3], t[ 2], m, mp);
  14495. sp_4096_mont_sqr_70(t[ 6], t[ 3], m, mp);
  14496. sp_4096_mont_mul_70(t[ 7], t[ 4], t[ 3], m, mp);
  14497. sp_4096_mont_sqr_70(t[ 8], t[ 4], m, mp);
  14498. sp_4096_mont_mul_70(t[ 9], t[ 5], t[ 4], m, mp);
  14499. sp_4096_mont_sqr_70(t[10], t[ 5], m, mp);
  14500. sp_4096_mont_mul_70(t[11], t[ 6], t[ 5], m, mp);
  14501. sp_4096_mont_sqr_70(t[12], t[ 6], m, mp);
  14502. sp_4096_mont_mul_70(t[13], t[ 7], t[ 6], m, mp);
  14503. sp_4096_mont_sqr_70(t[14], t[ 7], m, mp);
  14504. sp_4096_mont_mul_70(t[15], t[ 8], t[ 7], m, mp);
  14505. bits = ((bits + 3) / 4) * 4;
  14506. i = ((bits + 58) / 59) - 1;
  14507. c = bits % 59;
  14508. if (c == 0) {
  14509. c = 59;
  14510. }
  14511. if (i < 70) {
  14512. n = e[i--] << (64 - c);
  14513. }
  14514. else {
  14515. n = 0;
  14516. i--;
  14517. }
  14518. if (c < 4) {
  14519. n |= e[i--] << (5 - c);
  14520. c += 59;
  14521. }
  14522. y = (int)((n >> 60) & 0xf);
  14523. n <<= 4;
  14524. c -= 4;
  14525. XMEMCPY(rt, t[y], sizeof(sp_digit) * 140);
  14526. while ((i >= 0) || (c >= 4)) {
  14527. if (c >= 4) {
  14528. y = (byte)((n >> 60) & 0xf);
  14529. n <<= 4;
  14530. c -= 4;
  14531. }
  14532. else if (c == 0) {
  14533. n = e[i--] << 5;
  14534. y = (byte)((n >> 60) & 0xf);
  14535. n <<= 4;
  14536. c = 55;
  14537. }
  14538. else {
  14539. y = (byte)((n >> 60) & 0xf);
  14540. n = e[i--] << 5;
  14541. c = 4 - c;
  14542. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  14543. n <<= c;
  14544. c = 59 - c;
  14545. }
  14546. sp_4096_mont_sqr_70(rt, rt, m, mp);
  14547. sp_4096_mont_sqr_70(rt, rt, m, mp);
  14548. sp_4096_mont_sqr_70(rt, rt, m, mp);
  14549. sp_4096_mont_sqr_70(rt, rt, m, mp);
  14550. sp_4096_mont_mul_70(rt, rt, t[y], m, mp);
  14551. }
  14552. sp_4096_mont_reduce_70(rt, m, mp);
  14553. n = sp_4096_cmp_70(rt, m);
  14554. sp_4096_cond_sub_70(rt, rt, m, ~(n >> 63));
  14555. XMEMCPY(r, rt, sizeof(sp_digit) * 140);
  14556. }
  14557. #ifdef WOLFSSL_SP_SMALL_STACK
  14558. if (td != NULL)
  14559. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  14560. #endif
  14561. return err;
  14562. #endif
  14563. }
  14564. #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
  14565. #ifdef WOLFSSL_HAVE_SP_RSA
  14566. /* RSA public key operation.
  14567. *
  14568. * in Array of bytes representing the number to exponentiate, base.
  14569. * inLen Number of bytes in base.
  14570. * em Public exponent.
  14571. * mm Modulus.
  14572. * out Buffer to hold big-endian bytes of exponentiation result.
  14573. * Must be at least 512 bytes long.
  14574. * outLen Number of bytes in result.
  14575. * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
  14576. * an array is too long and MEMORY_E when dynamic memory allocation fails.
  14577. */
  14578. int sp_RsaPublic_4096(const byte* in, word32 inLen, const mp_int* em,
  14579. const mp_int* mm, byte* out, word32* outLen)
  14580. {
  14581. #ifdef WOLFSSL_SP_SMALL
  14582. #ifdef WOLFSSL_SP_SMALL_STACK
  14583. sp_digit* a = NULL;
  14584. #else
  14585. sp_digit a[70 * 5];
  14586. #endif
  14587. sp_digit* m = NULL;
  14588. sp_digit* r = NULL;
  14589. sp_digit* norm = NULL;
  14590. sp_uint64 e[1] = {0};
  14591. sp_digit mp = 0;
  14592. int i;
  14593. int err = MP_OKAY;
  14594. if (*outLen < 512U) {
  14595. err = MP_TO_E;
  14596. }
  14597. if (err == MP_OKAY) {
  14598. if (mp_count_bits(em) > 64) {
  14599. err = MP_READ_E;
  14600. }
  14601. else if (inLen > 512U) {
  14602. err = MP_READ_E;
  14603. }
  14604. else if (mp_count_bits(mm) != 4096) {
  14605. err = MP_READ_E;
  14606. }
  14607. else if (mp_iseven(mm)) {
  14608. err = MP_VAL;
  14609. }
  14610. }
  14611. #ifdef WOLFSSL_SP_SMALL_STACK
  14612. if (err == MP_OKAY) {
  14613. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 70 * 5, NULL,
  14614. DYNAMIC_TYPE_RSA);
  14615. if (a == NULL)
  14616. err = MEMORY_E;
  14617. }
  14618. #endif
  14619. if (err == MP_OKAY) {
  14620. r = a + 70 * 2;
  14621. m = r + 70 * 2;
  14622. norm = r;
  14623. sp_4096_from_bin(a, 70, in, inLen);
  14624. #if DIGIT_BIT >= 64
  14625. e[0] = (sp_uint64)em->dp[0];
  14626. #else
  14627. e[0] = (sp_uint64)em->dp[0];
  14628. if (em->used > 1) {
  14629. e[0] |= ((sp_uint64)em->dp[1]) << DIGIT_BIT;
  14630. }
  14631. #endif
  14632. if (e[0] == 0) {
  14633. err = MP_EXPTMOD_E;
  14634. }
  14635. }
  14636. if (err == MP_OKAY) {
  14637. sp_4096_from_mp(m, 70, mm);
  14638. sp_4096_mont_setup(m, &mp);
  14639. sp_4096_mont_norm_70(norm, m);
  14640. }
  14641. if (err == MP_OKAY) {
  14642. sp_4096_mul_70(a, a, norm);
  14643. err = sp_4096_mod_70(a, a, m);
  14644. }
  14645. if (err == MP_OKAY) {
  14646. for (i=63; i>=0; i--) {
  14647. if ((e[0] >> i) != 0) {
  14648. break;
  14649. }
  14650. }
  14651. XMEMCPY(r, a, sizeof(sp_digit) * 70 * 2);
  14652. for (i--; i>=0; i--) {
  14653. sp_4096_mont_sqr_70(r, r, m, mp);
  14654. if (((e[0] >> i) & 1) == 1) {
  14655. sp_4096_mont_mul_70(r, r, a, m, mp);
  14656. }
  14657. }
  14658. sp_4096_mont_reduce_70(r, m, mp);
  14659. mp = sp_4096_cmp_70(r, m);
  14660. sp_4096_cond_sub_70(r, r, m, ~(mp >> 63));
  14661. sp_4096_to_bin_70(r, out);
  14662. *outLen = 512;
  14663. }
  14664. #ifdef WOLFSSL_SP_SMALL_STACK
  14665. if (a != NULL)
  14666. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  14667. #endif
  14668. return err;
  14669. #else
  14670. #ifdef WOLFSSL_SP_SMALL_STACK
  14671. sp_digit* d = NULL;
  14672. #else
  14673. sp_digit d[70 * 5];
  14674. #endif
  14675. sp_digit* a = NULL;
  14676. sp_digit* m = NULL;
  14677. sp_digit* r = NULL;
  14678. sp_uint64 e[1] = {0};
  14679. int err = MP_OKAY;
  14680. if (*outLen < 512U) {
  14681. err = MP_TO_E;
  14682. }
  14683. if (err == MP_OKAY) {
  14684. if (mp_count_bits(em) > 64) {
  14685. err = MP_READ_E;
  14686. }
  14687. else if (inLen > 512U) {
  14688. err = MP_READ_E;
  14689. }
  14690. else if (mp_count_bits(mm) != 4096) {
  14691. err = MP_READ_E;
  14692. }
  14693. else if (mp_iseven(mm)) {
  14694. err = MP_VAL;
  14695. }
  14696. }
  14697. #ifdef WOLFSSL_SP_SMALL_STACK
  14698. if (err == MP_OKAY) {
  14699. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 70 * 5, NULL,
  14700. DYNAMIC_TYPE_RSA);
  14701. if (d == NULL)
  14702. err = MEMORY_E;
  14703. }
  14704. #endif
  14705. if (err == MP_OKAY) {
  14706. a = d;
  14707. r = a + 70 * 2;
  14708. m = r + 70 * 2;
  14709. sp_4096_from_bin(a, 70, in, inLen);
  14710. #if DIGIT_BIT >= 64
  14711. e[0] = (sp_uint64)em->dp[0];
  14712. #else
  14713. e[0] = (sp_uint64)em->dp[0];
  14714. if (em->used > 1) {
  14715. e[0] |= ((sp_uint64)em->dp[1]) << DIGIT_BIT;
  14716. }
  14717. #endif
  14718. if (e[0] == 0) {
  14719. err = MP_EXPTMOD_E;
  14720. }
  14721. }
  14722. if (err == MP_OKAY) {
  14723. sp_4096_from_mp(m, 70, mm);
  14724. if (e[0] == 0x3) {
  14725. sp_4096_sqr_70(r, a);
  14726. err = sp_4096_mod_70(r, r, m);
  14727. if (err == MP_OKAY) {
  14728. sp_4096_mul_70(r, a, r);
  14729. err = sp_4096_mod_70(r, r, m);
  14730. }
  14731. }
  14732. else {
  14733. sp_digit* norm = r;
  14734. int i;
  14735. sp_digit mp;
  14736. sp_4096_mont_setup(m, &mp);
  14737. sp_4096_mont_norm_70(norm, m);
  14738. sp_4096_mul_70(a, a, norm);
  14739. err = sp_4096_mod_70(a, a, m);
  14740. if (err == MP_OKAY) {
  14741. for (i=63; i>=0; i--) {
  14742. if ((e[0] >> i) != 0) {
  14743. break;
  14744. }
  14745. }
  14746. XMEMCPY(r, a, sizeof(sp_digit) * 140U);
  14747. for (i--; i>=0; i--) {
  14748. sp_4096_mont_sqr_70(r, r, m, mp);
  14749. if (((e[0] >> i) & 1) == 1) {
  14750. sp_4096_mont_mul_70(r, r, a, m, mp);
  14751. }
  14752. }
  14753. sp_4096_mont_reduce_70(r, m, mp);
  14754. mp = sp_4096_cmp_70(r, m);
  14755. sp_4096_cond_sub_70(r, r, m, ~(mp >> 63));
  14756. }
  14757. }
  14758. }
  14759. if (err == MP_OKAY) {
  14760. sp_4096_to_bin_70(r, out);
  14761. *outLen = 512;
  14762. }
  14763. #ifdef WOLFSSL_SP_SMALL_STACK
  14764. if (d != NULL)
  14765. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  14766. #endif
  14767. return err;
  14768. #endif /* WOLFSSL_SP_SMALL */
  14769. }
  14770. #ifndef WOLFSSL_RSA_PUBLIC_ONLY
  14771. #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM)
  14772. #endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */
  14773. /* RSA private key operation.
  14774. *
  14775. * in Array of bytes representing the number to exponentiate, base.
  14776. * inLen Number of bytes in base.
  14777. * dm Private exponent.
  14778. * pm First prime.
  14779. * qm Second prime.
  14780. * dpm First prime's CRT exponent.
  14781. * dqm Second prime's CRT exponent.
  14782. * qim Inverse of second prime mod p.
  14783. * mm Modulus.
  14784. * out Buffer to hold big-endian bytes of exponentiation result.
  14785. * Must be at least 512 bytes long.
  14786. * outLen Number of bytes in result.
  14787. * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
  14788. * an array is too long and MEMORY_E when dynamic memory allocation fails.
  14789. */
  14790. int sp_RsaPrivate_4096(const byte* in, word32 inLen, const mp_int* dm,
  14791. const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm,
  14792. const mp_int* qim, const mp_int* mm, byte* out, word32* outLen)
  14793. {
  14794. #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
  14795. #if defined(WOLFSSL_SP_SMALL)
  14796. #ifdef WOLFSSL_SP_SMALL_STACK
  14797. sp_digit* d = NULL;
  14798. #else
  14799. sp_digit d[70 * 4];
  14800. #endif
  14801. sp_digit* a = NULL;
  14802. sp_digit* m = NULL;
  14803. sp_digit* r = NULL;
  14804. int err = MP_OKAY;
  14805. (void)pm;
  14806. (void)qm;
  14807. (void)dpm;
  14808. (void)dqm;
  14809. (void)qim;
  14810. if (*outLen < 512U) {
  14811. err = MP_TO_E;
  14812. }
  14813. if (err == MP_OKAY) {
  14814. if (mp_count_bits(dm) > 4096) {
  14815. err = MP_READ_E;
  14816. }
  14817. else if (inLen > 512) {
  14818. err = MP_READ_E;
  14819. }
  14820. else if (mp_count_bits(mm) != 4096) {
  14821. err = MP_READ_E;
  14822. }
  14823. else if (mp_iseven(mm)) {
  14824. err = MP_VAL;
  14825. }
  14826. }
  14827. #ifdef WOLFSSL_SP_SMALL_STACK
  14828. if (err == MP_OKAY) {
  14829. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 70 * 4, NULL,
  14830. DYNAMIC_TYPE_RSA);
  14831. if (d == NULL)
  14832. err = MEMORY_E;
  14833. }
  14834. #endif
  14835. if (err == MP_OKAY) {
  14836. a = d + 70;
  14837. m = a + 140;
  14838. r = a;
  14839. sp_4096_from_bin(a, 70, in, inLen);
  14840. sp_4096_from_mp(d, 70, dm);
  14841. sp_4096_from_mp(m, 70, mm);
  14842. err = sp_4096_mod_exp_70(r, a, d, 4096, m, 0);
  14843. }
  14844. if (err == MP_OKAY) {
  14845. sp_4096_to_bin_70(r, out);
  14846. *outLen = 512;
  14847. }
  14848. #ifdef WOLFSSL_SP_SMALL_STACK
  14849. if (d != NULL)
  14850. #endif
  14851. {
  14852. /* only "a" and "r" are sensitive and need zeroized (same pointer) */
  14853. if (a != NULL)
  14854. ForceZero(a, sizeof(sp_digit) * 70);
  14855. #ifdef WOLFSSL_SP_SMALL_STACK
  14856. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  14857. #endif
  14858. }
  14859. return err;
  14860. #else
  14861. #ifdef WOLFSSL_SP_SMALL_STACK
  14862. sp_digit* d = NULL;
  14863. #else
  14864. sp_digit d[70 * 4];
  14865. #endif
  14866. sp_digit* a = NULL;
  14867. sp_digit* m = NULL;
  14868. sp_digit* r = NULL;
  14869. int err = MP_OKAY;
  14870. (void)pm;
  14871. (void)qm;
  14872. (void)dpm;
  14873. (void)dqm;
  14874. (void)qim;
  14875. if (*outLen < 512U) {
  14876. err = MP_TO_E;
  14877. }
  14878. if (err == MP_OKAY) {
  14879. if (mp_count_bits(dm) > 4096) {
  14880. err = MP_READ_E;
  14881. }
  14882. else if (inLen > 512U) {
  14883. err = MP_READ_E;
  14884. }
  14885. else if (mp_count_bits(mm) != 4096) {
  14886. err = MP_READ_E;
  14887. }
  14888. else if (mp_iseven(mm)) {
  14889. err = MP_VAL;
  14890. }
  14891. }
  14892. #ifdef WOLFSSL_SP_SMALL_STACK
  14893. if (err == MP_OKAY) {
  14894. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 70 * 4, NULL,
  14895. DYNAMIC_TYPE_RSA);
  14896. if (d == NULL)
  14897. err = MEMORY_E;
  14898. }
  14899. #endif
  14900. if (err == MP_OKAY) {
  14901. a = d + 70;
  14902. m = a + 140;
  14903. r = a;
  14904. sp_4096_from_bin(a, 70, in, inLen);
  14905. sp_4096_from_mp(d, 70, dm);
  14906. sp_4096_from_mp(m, 70, mm);
  14907. err = sp_4096_mod_exp_70(r, a, d, 4096, m, 0);
  14908. }
  14909. if (err == MP_OKAY) {
  14910. sp_4096_to_bin_70(r, out);
  14911. *outLen = 512;
  14912. }
  14913. #ifdef WOLFSSL_SP_SMALL_STACK
  14914. if (d != NULL)
  14915. #endif
  14916. {
  14917. /* only "a" and "r" are sensitive and need zeroized (same pointer) */
  14918. if (a != NULL)
  14919. ForceZero(a, sizeof(sp_digit) * 70);
  14920. #ifdef WOLFSSL_SP_SMALL_STACK
  14921. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  14922. #endif
  14923. }
  14924. return err;
  14925. #endif /* WOLFSSL_SP_SMALL */
  14926. #else
  14927. #if defined(WOLFSSL_SP_SMALL)
  14928. #ifdef WOLFSSL_SP_SMALL_STACK
  14929. sp_digit* a = NULL;
  14930. #else
  14931. sp_digit a[35 * 8];
  14932. #endif
  14933. sp_digit* p = NULL;
  14934. sp_digit* dp = NULL;
  14935. sp_digit* dq = NULL;
  14936. sp_digit* qi = NULL;
  14937. sp_digit* tmpa = NULL;
  14938. sp_digit* tmpb = NULL;
  14939. sp_digit* r = NULL;
  14940. int err = MP_OKAY;
  14941. (void)dm;
  14942. (void)mm;
  14943. if (*outLen < 512U) {
  14944. err = MP_TO_E;
  14945. }
  14946. if (err == MP_OKAY) {
  14947. if (inLen > 512) {
  14948. err = MP_READ_E;
  14949. }
  14950. else if (mp_count_bits(mm) != 4096) {
  14951. err = MP_READ_E;
  14952. }
  14953. else if (mp_iseven(mm)) {
  14954. err = MP_VAL;
  14955. }
  14956. else if (mp_iseven(pm)) {
  14957. err = MP_VAL;
  14958. }
  14959. else if (mp_iseven(qm)) {
  14960. err = MP_VAL;
  14961. }
  14962. }
  14963. #ifdef WOLFSSL_SP_SMALL_STACK
  14964. if (err == MP_OKAY) {
  14965. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 35 * 8, NULL,
  14966. DYNAMIC_TYPE_RSA);
  14967. if (a == NULL)
  14968. err = MEMORY_E;
  14969. }
  14970. #endif
  14971. if (err == MP_OKAY) {
  14972. p = a + 70;
  14973. qi = dq = dp = p + 35;
  14974. tmpa = qi + 35;
  14975. tmpb = tmpa + 70;
  14976. r = a;
  14977. sp_4096_from_bin(a, 70, in, inLen);
  14978. sp_4096_from_mp(p, 35, pm);
  14979. sp_4096_from_mp(dp, 35, dpm);
  14980. err = sp_4096_mod_exp_35(tmpa, a, dp, 2048, p, 1);
  14981. }
  14982. if (err == MP_OKAY) {
  14983. sp_4096_from_mp(p, 35, qm);
  14984. sp_4096_from_mp(dq, 35, dqm);
  14985. err = sp_4096_mod_exp_35(tmpb, a, dq, 2048, p, 1);
  14986. }
  14987. if (err == MP_OKAY) {
  14988. sp_4096_from_mp(p, 35, pm);
  14989. (void)sp_4096_sub_35(tmpa, tmpa, tmpb);
  14990. sp_4096_norm_35(tmpa);
  14991. sp_4096_cond_add_35(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[34] >> 63));
  14992. sp_4096_cond_add_35(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[34] >> 63));
  14993. sp_4096_norm_35(tmpa);
  14994. sp_4096_from_mp(qi, 35, qim);
  14995. sp_4096_mul_35(tmpa, tmpa, qi);
  14996. err = sp_4096_mod_35(tmpa, tmpa, p);
  14997. }
  14998. if (err == MP_OKAY) {
  14999. sp_4096_from_mp(p, 35, qm);
  15000. sp_4096_mul_35(tmpa, p, tmpa);
  15001. (void)sp_4096_add_70(r, tmpb, tmpa);
  15002. sp_4096_norm_70(r);
  15003. sp_4096_to_bin_70(r, out);
  15004. *outLen = 512;
  15005. }
  15006. #ifdef WOLFSSL_SP_SMALL_STACK
  15007. if (a != NULL)
  15008. #endif
  15009. {
  15010. ForceZero(a, sizeof(sp_digit) * 35 * 8);
  15011. #ifdef WOLFSSL_SP_SMALL_STACK
  15012. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  15013. #endif
  15014. }
  15015. return err;
  15016. #else
  15017. #ifdef WOLFSSL_SP_SMALL_STACK
  15018. sp_digit* a = NULL;
  15019. #else
  15020. sp_digit a[35 * 13];
  15021. #endif
  15022. sp_digit* p = NULL;
  15023. sp_digit* q = NULL;
  15024. sp_digit* dp = NULL;
  15025. sp_digit* dq = NULL;
  15026. sp_digit* qi = NULL;
  15027. sp_digit* tmpa = NULL;
  15028. sp_digit* tmpb = NULL;
  15029. sp_digit* r = NULL;
  15030. int err = MP_OKAY;
  15031. (void)dm;
  15032. (void)mm;
  15033. if (*outLen < 512U) {
  15034. err = MP_TO_E;
  15035. }
  15036. if (err == MP_OKAY) {
  15037. if (inLen > 512U) {
  15038. err = MP_READ_E;
  15039. }
  15040. else if (mp_count_bits(mm) != 4096) {
  15041. err = MP_READ_E;
  15042. }
  15043. else if (mp_iseven(mm)) {
  15044. err = MP_VAL;
  15045. }
  15046. else if (mp_iseven(pm)) {
  15047. err = MP_VAL;
  15048. }
  15049. else if (mp_iseven(qm)) {
  15050. err = MP_VAL;
  15051. }
  15052. }
  15053. #ifdef WOLFSSL_SP_SMALL_STACK
  15054. if (err == MP_OKAY) {
  15055. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 35 * 13, NULL,
  15056. DYNAMIC_TYPE_RSA);
  15057. if (a == NULL)
  15058. err = MEMORY_E;
  15059. }
  15060. #endif
  15061. if (err == MP_OKAY) {
  15062. p = a + 70 * 2;
  15063. q = p + 35;
  15064. dp = q + 35;
  15065. dq = dp + 35;
  15066. qi = dq + 35;
  15067. tmpa = qi + 35;
  15068. tmpb = tmpa + 70;
  15069. r = a;
  15070. sp_4096_from_bin(a, 70, in, inLen);
  15071. sp_4096_from_mp(p, 35, pm);
  15072. sp_4096_from_mp(q, 35, qm);
  15073. sp_4096_from_mp(dp, 35, dpm);
  15074. sp_4096_from_mp(dq, 35, dqm);
  15075. sp_4096_from_mp(qi, 35, qim);
  15076. err = sp_4096_mod_exp_35(tmpa, a, dp, 2048, p, 1);
  15077. }
  15078. if (err == MP_OKAY) {
  15079. err = sp_4096_mod_exp_35(tmpb, a, dq, 2048, q, 1);
  15080. }
  15081. if (err == MP_OKAY) {
  15082. (void)sp_4096_sub_35(tmpa, tmpa, tmpb);
  15083. sp_4096_norm_35(tmpa);
  15084. sp_4096_cond_add_35(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[34] >> 63));
  15085. sp_4096_cond_add_35(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[34] >> 63));
  15086. sp_4096_norm_35(tmpa);
  15087. sp_4096_mul_35(tmpa, tmpa, qi);
  15088. err = sp_4096_mod_35(tmpa, tmpa, p);
  15089. }
  15090. if (err == MP_OKAY) {
  15091. sp_4096_mul_35(tmpa, tmpa, q);
  15092. (void)sp_4096_add_70(r, tmpb, tmpa);
  15093. sp_4096_norm_70(r);
  15094. sp_4096_to_bin_70(r, out);
  15095. *outLen = 512;
  15096. }
  15097. #ifdef WOLFSSL_SP_SMALL_STACK
  15098. if (a != NULL)
  15099. #endif
  15100. {
  15101. ForceZero(a, sizeof(sp_digit) * 35 * 13);
  15102. #ifdef WOLFSSL_SP_SMALL_STACK
  15103. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  15104. #endif
  15105. }
  15106. return err;
  15107. #endif /* WOLFSSL_SP_SMALL */
  15108. #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
  15109. }
  15110. #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
  15111. #endif /* WOLFSSL_HAVE_SP_RSA */
  15112. #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
  15113. !defined(WOLFSSL_RSA_PUBLIC_ONLY))
  15114. /* Convert an array of sp_digit to an mp_int.
  15115. *
  15116. * a A single precision integer.
  15117. * r A multi-precision integer.
  15118. */
  15119. static int sp_4096_to_mp(const sp_digit* a, mp_int* r)
  15120. {
  15121. int err;
  15122. err = mp_grow(r, (4096 + DIGIT_BIT - 1) / DIGIT_BIT);
  15123. if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
  15124. #if DIGIT_BIT == 59
  15125. XMEMCPY(r->dp, a, sizeof(sp_digit) * 70);
  15126. r->used = 70;
  15127. mp_clamp(r);
  15128. #elif DIGIT_BIT < 59
  15129. int i;
  15130. int j = 0;
  15131. int s = 0;
  15132. r->dp[0] = 0;
  15133. for (i = 0; i < 70; i++) {
  15134. r->dp[j] |= (mp_digit)(a[i] << s);
  15135. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  15136. s = DIGIT_BIT - s;
  15137. r->dp[++j] = (mp_digit)(a[i] >> s);
  15138. while (s + DIGIT_BIT <= 59) {
  15139. s += DIGIT_BIT;
  15140. r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  15141. if (s == SP_WORD_SIZE) {
  15142. r->dp[j] = 0;
  15143. }
  15144. else {
  15145. r->dp[j] = (mp_digit)(a[i] >> s);
  15146. }
  15147. }
  15148. s = 59 - s;
  15149. }
  15150. r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;
  15151. mp_clamp(r);
  15152. #else
  15153. int i;
  15154. int j = 0;
  15155. int s = 0;
  15156. r->dp[0] = 0;
  15157. for (i = 0; i < 70; i++) {
  15158. r->dp[j] |= ((mp_digit)a[i]) << s;
  15159. if (s + 59 >= DIGIT_BIT) {
  15160. #if DIGIT_BIT != 32 && DIGIT_BIT != 64
  15161. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  15162. #endif
  15163. s = DIGIT_BIT - s;
  15164. r->dp[++j] = a[i] >> s;
  15165. s = 59 - s;
  15166. }
  15167. else {
  15168. s += 59;
  15169. }
  15170. }
  15171. r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;
  15172. mp_clamp(r);
  15173. #endif
  15174. }
  15175. return err;
  15176. }
  15177. /* Perform the modular exponentiation for Diffie-Hellman.
  15178. *
  15179. * base Base. MP integer.
  15180. * exp Exponent. MP integer.
  15181. * mod Modulus. MP integer.
  15182. * res Result. MP integer.
  15183. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  15184. * and MEMORY_E if memory allocation fails.
  15185. */
  15186. int sp_ModExp_4096(const mp_int* base, const mp_int* exp, const mp_int* mod,
  15187. mp_int* res)
  15188. {
  15189. #ifdef WOLFSSL_SP_SMALL
  15190. int err = MP_OKAY;
  15191. #ifdef WOLFSSL_SP_SMALL_STACK
  15192. sp_digit* b = NULL;
  15193. #else
  15194. sp_digit b[70 * 4];
  15195. #endif
  15196. sp_digit* e = NULL;
  15197. sp_digit* m = NULL;
  15198. sp_digit* r = NULL;
  15199. int expBits = mp_count_bits(exp);
  15200. if (mp_count_bits(base) > 4096) {
  15201. err = MP_READ_E;
  15202. }
  15203. else if (expBits > 4096) {
  15204. err = MP_READ_E;
  15205. }
  15206. else if (mp_count_bits(mod) != 4096) {
  15207. err = MP_READ_E;
  15208. }
  15209. else if (mp_iseven(mod)) {
  15210. err = MP_VAL;
  15211. }
  15212. #ifdef WOLFSSL_SP_SMALL_STACK
  15213. if (err == MP_OKAY) {
  15214. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 70 * 4, NULL,
  15215. DYNAMIC_TYPE_DH);
  15216. if (b == NULL)
  15217. err = MEMORY_E;
  15218. }
  15219. #endif
  15220. if (err == MP_OKAY) {
  15221. e = b + 70 * 2;
  15222. m = e + 70;
  15223. r = b;
  15224. sp_4096_from_mp(b, 70, base);
  15225. sp_4096_from_mp(e, 70, exp);
  15226. sp_4096_from_mp(m, 70, mod);
  15227. err = sp_4096_mod_exp_70(r, b, e, mp_count_bits(exp), m, 0);
  15228. }
  15229. if (err == MP_OKAY) {
  15230. err = sp_4096_to_mp(r, res);
  15231. }
  15232. #ifdef WOLFSSL_SP_SMALL_STACK
  15233. if (b != NULL)
  15234. #endif
  15235. {
  15236. /* only "e" is sensitive and needs zeroized */
  15237. if (e != NULL)
  15238. ForceZero(e, sizeof(sp_digit) * 70U);
  15239. #ifdef WOLFSSL_SP_SMALL_STACK
  15240. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  15241. #endif
  15242. }
  15243. return err;
  15244. #else
  15245. #ifdef WOLFSSL_SP_SMALL_STACK
  15246. sp_digit* b = NULL;
  15247. #else
  15248. sp_digit b[70 * 4];
  15249. #endif
  15250. sp_digit* e = NULL;
  15251. sp_digit* m = NULL;
  15252. sp_digit* r = NULL;
  15253. int err = MP_OKAY;
  15254. int expBits = mp_count_bits(exp);
  15255. if (mp_count_bits(base) > 4096) {
  15256. err = MP_READ_E;
  15257. }
  15258. else if (expBits > 4096) {
  15259. err = MP_READ_E;
  15260. }
  15261. else if (mp_count_bits(mod) != 4096) {
  15262. err = MP_READ_E;
  15263. }
  15264. else if (mp_iseven(mod)) {
  15265. err = MP_VAL;
  15266. }
  15267. #ifdef WOLFSSL_SP_SMALL_STACK
  15268. if (err == MP_OKAY) {
  15269. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 70 * 4, NULL, DYNAMIC_TYPE_DH);
  15270. if (b == NULL)
  15271. err = MEMORY_E;
  15272. }
  15273. #endif
  15274. if (err == MP_OKAY) {
  15275. e = b + 70 * 2;
  15276. m = e + 70;
  15277. r = b;
  15278. sp_4096_from_mp(b, 70, base);
  15279. sp_4096_from_mp(e, 70, exp);
  15280. sp_4096_from_mp(m, 70, mod);
  15281. err = sp_4096_mod_exp_70(r, b, e, expBits, m, 0);
  15282. }
  15283. if (err == MP_OKAY) {
  15284. err = sp_4096_to_mp(r, res);
  15285. }
  15286. #ifdef WOLFSSL_SP_SMALL_STACK
  15287. if (b != NULL)
  15288. #endif
  15289. {
  15290. /* only "e" is sensitive and needs zeroized */
  15291. if (e != NULL)
  15292. ForceZero(e, sizeof(sp_digit) * 70U);
  15293. #ifdef WOLFSSL_SP_SMALL_STACK
  15294. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  15295. #endif
  15296. }
  15297. return err;
  15298. #endif
  15299. }
  15300. #ifdef WOLFSSL_HAVE_SP_DH
  15301. #ifdef HAVE_FFDHE_4096
  15302. SP_NOINLINE static void sp_4096_lshift_70(sp_digit* r, const sp_digit* a,
  15303. byte n)
  15304. {
  15305. int i;
  15306. r[70] = a[69] >> (59 - n);
  15307. for (i=69; i>0; i--) {
  15308. r[i] = ((a[i] << n) | (a[i-1] >> (59 - n))) & 0x7ffffffffffffffL;
  15309. }
  15310. r[0] = (a[0] << n) & 0x7ffffffffffffffL;
  15311. }
  15312. /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
  15313. *
  15314. * r A single precision number that is the result of the operation.
  15315. * e A single precision number that is the exponent.
  15316. * bits The number of bits in the exponent.
  15317. * m A single precision number that is the modulus.
  15318. * returns 0 on success.
  15319. * returns MEMORY_E on dynamic memory allocation failure.
  15320. * returns MP_VAL when base is even.
  15321. */
  15322. static int sp_4096_mod_exp_2_70(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)
  15323. {
  15324. #ifdef WOLFSSL_SP_SMALL_STACK
  15325. sp_digit* td = NULL;
  15326. #else
  15327. sp_digit td[211];
  15328. #endif
  15329. sp_digit* norm = NULL;
  15330. sp_digit* tmp = NULL;
  15331. sp_digit mp = 1;
  15332. sp_digit n;
  15333. sp_digit o;
  15334. int i;
  15335. int c;
  15336. byte y;
  15337. int err = MP_OKAY;
  15338. if (bits == 0) {
  15339. err = MP_VAL;
  15340. }
  15341. #ifdef WOLFSSL_SP_SMALL_STACK
  15342. if (err == MP_OKAY) {
  15343. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 211, NULL,
  15344. DYNAMIC_TYPE_TMP_BUFFER);
  15345. if (td == NULL)
  15346. err = MEMORY_E;
  15347. }
  15348. #endif
  15349. if (err == MP_OKAY) {
  15350. norm = td;
  15351. tmp = td + 140;
  15352. XMEMSET(td, 0, sizeof(sp_digit) * 211);
  15353. sp_4096_mont_setup(m, &mp);
  15354. sp_4096_mont_norm_70(norm, m);
  15355. bits = ((bits + 4) / 5) * 5;
  15356. i = ((bits + 58) / 59) - 1;
  15357. c = bits % 59;
  15358. if (c == 0) {
  15359. c = 59;
  15360. }
  15361. if (i < 70) {
  15362. n = e[i--] << (64 - c);
  15363. }
  15364. else {
  15365. n = 0;
  15366. i--;
  15367. }
  15368. if (c < 5) {
  15369. n |= e[i--] << (5 - c);
  15370. c += 59;
  15371. }
  15372. y = (int)((n >> 59) & 0x1f);
  15373. n <<= 5;
  15374. c -= 5;
  15375. sp_4096_lshift_70(r, norm, (byte)y);
  15376. while ((i >= 0) || (c >= 5)) {
  15377. if (c >= 5) {
  15378. y = (byte)((n >> 59) & 0x1f);
  15379. n <<= 5;
  15380. c -= 5;
  15381. }
  15382. else if (c == 0) {
  15383. n = e[i--] << 5;
  15384. y = (byte)((n >> 59) & 0x1f);
  15385. n <<= 5;
  15386. c = 54;
  15387. }
  15388. else {
  15389. y = (byte)((n >> 59) & 0x1f);
  15390. n = e[i--] << 5;
  15391. c = 5 - c;
  15392. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  15393. n <<= c;
  15394. c = 59 - c;
  15395. }
  15396. sp_4096_mont_sqr_70(r, r, m, mp);
  15397. sp_4096_mont_sqr_70(r, r, m, mp);
  15398. sp_4096_mont_sqr_70(r, r, m, mp);
  15399. sp_4096_mont_sqr_70(r, r, m, mp);
  15400. sp_4096_mont_sqr_70(r, r, m, mp);
  15401. sp_4096_lshift_70(r, r, (byte)y);
  15402. sp_4096_mul_d_70(tmp, norm, (r[70] << 34) + (r[69] >> 25));
  15403. r[70] = 0;
  15404. r[69] &= 0x1ffffffL;
  15405. (void)sp_4096_add_70(r, r, tmp);
  15406. sp_4096_norm_70(r);
  15407. o = sp_4096_cmp_70(r, m);
  15408. sp_4096_cond_sub_70(r, r, m, ~(o >> 63));
  15409. }
  15410. sp_4096_mont_reduce_70(r, m, mp);
  15411. n = sp_4096_cmp_70(r, m);
  15412. sp_4096_cond_sub_70(r, r, m, ~(n >> 63));
  15413. }
  15414. #ifdef WOLFSSL_SP_SMALL_STACK
  15415. if (td != NULL)
  15416. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  15417. #endif
  15418. return err;
  15419. }
  15420. #endif /* HAVE_FFDHE_4096 */
  15421. /* Perform the modular exponentiation for Diffie-Hellman.
  15422. *
  15423. * base Base.
  15424. * exp Array of bytes that is the exponent.
  15425. * expLen Length of data, in bytes, in exponent.
  15426. * mod Modulus.
  15427. * out Buffer to hold big-endian bytes of exponentiation result.
  15428. * Must be at least 512 bytes long.
  15429. * outLen Length, in bytes, of exponentiation result.
  15430. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  15431. * and MEMORY_E if memory allocation fails.
  15432. */
  15433. int sp_DhExp_4096(const mp_int* base, const byte* exp, word32 expLen,
  15434. const mp_int* mod, byte* out, word32* outLen)
  15435. {
  15436. #ifdef WOLFSSL_SP_SMALL_STACK
  15437. sp_digit* b = NULL;
  15438. #else
  15439. sp_digit b[70 * 4];
  15440. #endif
  15441. sp_digit* e = NULL;
  15442. sp_digit* m = NULL;
  15443. sp_digit* r = NULL;
  15444. word32 i;
  15445. int err = MP_OKAY;
  15446. if (mp_count_bits(base) > 4096) {
  15447. err = MP_READ_E;
  15448. }
  15449. else if (expLen > 512U) {
  15450. err = MP_READ_E;
  15451. }
  15452. else if (mp_count_bits(mod) != 4096) {
  15453. err = MP_READ_E;
  15454. }
  15455. else if (mp_iseven(mod)) {
  15456. err = MP_VAL;
  15457. }
  15458. #ifdef WOLFSSL_SP_SMALL_STACK
  15459. if (err == MP_OKAY) {
  15460. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 70 * 4, NULL,
  15461. DYNAMIC_TYPE_DH);
  15462. if (b == NULL)
  15463. err = MEMORY_E;
  15464. }
  15465. #endif
  15466. if (err == MP_OKAY) {
  15467. e = b + 70 * 2;
  15468. m = e + 70;
  15469. r = b;
  15470. sp_4096_from_mp(b, 70, base);
  15471. sp_4096_from_bin(e, 70, exp, expLen);
  15472. sp_4096_from_mp(m, 70, mod);
  15473. #ifdef HAVE_FFDHE_4096
  15474. if (base->used == 1 && base->dp[0] == 2U &&
  15475. ((m[69] << 7) | (m[68] >> 52)) == 0xffffffffL) {
  15476. err = sp_4096_mod_exp_2_70(r, e, expLen * 8U, m);
  15477. }
  15478. else {
  15479. #endif
  15480. err = sp_4096_mod_exp_70(r, b, e, expLen * 8U, m, 0);
  15481. #ifdef HAVE_FFDHE_4096
  15482. }
  15483. #endif
  15484. }
  15485. if (err == MP_OKAY) {
  15486. sp_4096_to_bin_70(r, out);
  15487. *outLen = 512;
  15488. for (i=0; i<512U && out[i] == 0U; i++) {
  15489. /* Search for first non-zero. */
  15490. }
  15491. *outLen -= i;
  15492. XMEMMOVE(out, out + i, *outLen);
  15493. }
  15494. #ifdef WOLFSSL_SP_SMALL_STACK
  15495. if (b != NULL)
  15496. #endif
  15497. {
  15498. /* only "e" is sensitive and needs zeroized */
  15499. if (e != NULL)
  15500. ForceZero(e, sizeof(sp_digit) * 70U);
  15501. #ifdef WOLFSSL_SP_SMALL_STACK
  15502. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  15503. #endif
  15504. }
  15505. return err;
  15506. }
  15507. #endif /* WOLFSSL_HAVE_SP_DH */
  15508. #endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */
  15509. #else
  15510. /* Read big endian unsigned byte array into r.
  15511. *
  15512. * r A single precision integer.
  15513. * size Maximum number of bytes to convert
  15514. * a Byte array.
  15515. * n Number of bytes in array to read.
  15516. */
  15517. static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n)
  15518. {
  15519. int i;
  15520. int j = 0;
  15521. word32 s = 0;
  15522. r[0] = 0;
  15523. for (i = n-1; i >= 0; i--) {
  15524. r[j] |= (((sp_digit)a[i]) << s);
  15525. if (s >= 45U) {
  15526. r[j] &= 0x1fffffffffffffL;
  15527. s = 53U - s;
  15528. if (j + 1 >= size) {
  15529. break;
  15530. }
  15531. r[++j] = (sp_digit)a[i] >> s;
  15532. s = 8U - s;
  15533. }
  15534. else {
  15535. s += 8U;
  15536. }
  15537. }
  15538. for (j++; j < size; j++) {
  15539. r[j] = 0;
  15540. }
  15541. }
  15542. /* Convert an mp_int to an array of sp_digit.
  15543. *
  15544. * r A single precision integer.
  15545. * size Maximum number of bytes to convert
  15546. * a A multi-precision integer.
  15547. */
  15548. static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a)
  15549. {
  15550. #if DIGIT_BIT == 53
  15551. int i;
  15552. sp_digit j = (sp_digit)0 - (sp_digit)a->used;
  15553. int o = 0;
  15554. for (i = 0; i < size; i++) {
  15555. sp_digit mask = (sp_digit)0 - (j >> 52);
  15556. r[i] = a->dp[o] & mask;
  15557. j++;
  15558. o += (int)(j >> 52);
  15559. }
  15560. #elif DIGIT_BIT > 53
  15561. unsigned int i;
  15562. int j = 0;
  15563. word32 s = 0;
  15564. r[0] = 0;
  15565. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  15566. r[j] |= ((sp_digit)a->dp[i] << s);
  15567. r[j] &= 0x1fffffffffffffL;
  15568. s = 53U - s;
  15569. if (j + 1 >= size) {
  15570. break;
  15571. }
  15572. /* lint allow cast of mismatch word32 and mp_digit */
  15573. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  15574. while ((s + 53U) <= (word32)DIGIT_BIT) {
  15575. s += 53U;
  15576. r[j] &= 0x1fffffffffffffL;
  15577. if (j + 1 >= size) {
  15578. break;
  15579. }
  15580. if (s < (word32)DIGIT_BIT) {
  15581. /* lint allow cast of mismatch word32 and mp_digit */
  15582. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  15583. }
  15584. else {
  15585. r[++j] = (sp_digit)0;
  15586. }
  15587. }
  15588. s = (word32)DIGIT_BIT - s;
  15589. }
  15590. for (j++; j < size; j++) {
  15591. r[j] = 0;
  15592. }
  15593. #else
  15594. unsigned int i;
  15595. int j = 0;
  15596. int s = 0;
  15597. r[0] = 0;
  15598. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  15599. r[j] |= ((sp_digit)a->dp[i]) << s;
  15600. if (s + DIGIT_BIT >= 53) {
  15601. r[j] &= 0x1fffffffffffffL;
  15602. if (j + 1 >= size) {
  15603. break;
  15604. }
  15605. s = 53 - s;
  15606. if (s == DIGIT_BIT) {
  15607. r[++j] = 0;
  15608. s = 0;
  15609. }
  15610. else {
  15611. r[++j] = a->dp[i] >> s;
  15612. s = DIGIT_BIT - s;
  15613. }
  15614. }
  15615. else {
  15616. s += DIGIT_BIT;
  15617. }
  15618. }
  15619. for (j++; j < size; j++) {
  15620. r[j] = 0;
  15621. }
  15622. #endif
  15623. }
  15624. /* Write r as big endian to byte array.
  15625. * Fixed length number of bytes written: 512
  15626. *
  15627. * r A single precision integer.
  15628. * a Byte array.
  15629. */
  15630. static void sp_4096_to_bin_78(sp_digit* r, byte* a)
  15631. {
  15632. int i;
  15633. int j;
  15634. int s = 0;
  15635. int b;
  15636. for (i=0; i<77; i++) {
  15637. r[i+1] += r[i] >> 53;
  15638. r[i] &= 0x1fffffffffffffL;
  15639. }
  15640. j = 4103 / 8 - 1;
  15641. a[j] = 0;
  15642. for (i=0; i<78 && j>=0; i++) {
  15643. b = 0;
  15644. /* lint allow cast of mismatch sp_digit and int */
  15645. a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
  15646. b += 8 - s;
  15647. if (j < 0) {
  15648. break;
  15649. }
  15650. while (b < 53) {
  15651. a[j--] = (byte)(r[i] >> b);
  15652. b += 8;
  15653. if (j < 0) {
  15654. break;
  15655. }
  15656. }
  15657. s = 8 - (b - 53);
  15658. if (j >= 0) {
  15659. a[j] = 0;
  15660. }
  15661. if (s != 0) {
  15662. j++;
  15663. }
  15664. }
  15665. }
  15666. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  15667. #if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D)
  15668. /* Normalize the values in each word to 53 bits.
  15669. *
  15670. * a Array of sp_digit to normalize.
  15671. */
  15672. static void sp_4096_norm_39(sp_digit* a)
  15673. {
  15674. int i;
  15675. for (i = 0; i < 32; i += 8) {
  15676. a[i+1] += a[i+0] >> 53; a[i+0] &= 0x1fffffffffffffL;
  15677. a[i+2] += a[i+1] >> 53; a[i+1] &= 0x1fffffffffffffL;
  15678. a[i+3] += a[i+2] >> 53; a[i+2] &= 0x1fffffffffffffL;
  15679. a[i+4] += a[i+3] >> 53; a[i+3] &= 0x1fffffffffffffL;
  15680. a[i+5] += a[i+4] >> 53; a[i+4] &= 0x1fffffffffffffL;
  15681. a[i+6] += a[i+5] >> 53; a[i+5] &= 0x1fffffffffffffL;
  15682. a[i+7] += a[i+6] >> 53; a[i+6] &= 0x1fffffffffffffL;
  15683. a[i+8] += a[i+7] >> 53; a[i+7] &= 0x1fffffffffffffL;
  15684. }
  15685. a[33] += a[32] >> 53; a[32] &= 0x1fffffffffffffL;
  15686. a[34] += a[33] >> 53; a[33] &= 0x1fffffffffffffL;
  15687. a[35] += a[34] >> 53; a[34] &= 0x1fffffffffffffL;
  15688. a[36] += a[35] >> 53; a[35] &= 0x1fffffffffffffL;
  15689. a[37] += a[36] >> 53; a[36] &= 0x1fffffffffffffL;
  15690. a[38] += a[37] >> 53; a[37] &= 0x1fffffffffffffL;
  15691. }
  15692. #endif /* WOLFSSL_HAVE_SP_RSA & !SP_RSA_PRIVATE_EXP_D */
  15693. #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
  15694. /* Normalize the values in each word to 53 bits.
  15695. *
  15696. * a Array of sp_digit to normalize.
  15697. */
  15698. static void sp_4096_norm_78(sp_digit* a)
  15699. {
  15700. int i;
  15701. for (i = 0; i < 72; i += 8) {
  15702. a[i+1] += a[i+0] >> 53; a[i+0] &= 0x1fffffffffffffL;
  15703. a[i+2] += a[i+1] >> 53; a[i+1] &= 0x1fffffffffffffL;
  15704. a[i+3] += a[i+2] >> 53; a[i+2] &= 0x1fffffffffffffL;
  15705. a[i+4] += a[i+3] >> 53; a[i+3] &= 0x1fffffffffffffL;
  15706. a[i+5] += a[i+4] >> 53; a[i+4] &= 0x1fffffffffffffL;
  15707. a[i+6] += a[i+5] >> 53; a[i+5] &= 0x1fffffffffffffL;
  15708. a[i+7] += a[i+6] >> 53; a[i+6] &= 0x1fffffffffffffL;
  15709. a[i+8] += a[i+7] >> 53; a[i+7] &= 0x1fffffffffffffL;
  15710. }
  15711. a[73] += a[72] >> 53; a[72] &= 0x1fffffffffffffL;
  15712. a[74] += a[73] >> 53; a[73] &= 0x1fffffffffffffL;
  15713. a[75] += a[74] >> 53; a[74] &= 0x1fffffffffffffL;
  15714. a[76] += a[75] >> 53; a[75] &= 0x1fffffffffffffL;
  15715. a[77] += a[76] >> 53; a[76] &= 0x1fffffffffffffL;
  15716. }
  15717. #ifndef WOLFSSL_SP_SMALL
  15718. /* Multiply a and b into r. (r = a * b)
  15719. *
  15720. * r A single precision integer.
  15721. * a A single precision integer.
  15722. * b A single precision integer.
  15723. */
  15724. SP_NOINLINE static void sp_4096_mul_13(sp_digit* r, const sp_digit* a,
  15725. const sp_digit* b)
  15726. {
  15727. sp_uint128 t0;
  15728. sp_uint128 t1;
  15729. sp_digit t[13];
  15730. t0 = ((sp_uint128)a[ 0]) * b[ 0];
  15731. t1 = ((sp_uint128)a[ 0]) * b[ 1]
  15732. + ((sp_uint128)a[ 1]) * b[ 0];
  15733. t[ 0] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  15734. t0 = ((sp_uint128)a[ 0]) * b[ 2]
  15735. + ((sp_uint128)a[ 1]) * b[ 1]
  15736. + ((sp_uint128)a[ 2]) * b[ 0];
  15737. t[ 1] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  15738. t1 = ((sp_uint128)a[ 0]) * b[ 3]
  15739. + ((sp_uint128)a[ 1]) * b[ 2]
  15740. + ((sp_uint128)a[ 2]) * b[ 1]
  15741. + ((sp_uint128)a[ 3]) * b[ 0];
  15742. t[ 2] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  15743. t0 = ((sp_uint128)a[ 0]) * b[ 4]
  15744. + ((sp_uint128)a[ 1]) * b[ 3]
  15745. + ((sp_uint128)a[ 2]) * b[ 2]
  15746. + ((sp_uint128)a[ 3]) * b[ 1]
  15747. + ((sp_uint128)a[ 4]) * b[ 0];
  15748. t[ 3] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  15749. t1 = ((sp_uint128)a[ 0]) * b[ 5]
  15750. + ((sp_uint128)a[ 1]) * b[ 4]
  15751. + ((sp_uint128)a[ 2]) * b[ 3]
  15752. + ((sp_uint128)a[ 3]) * b[ 2]
  15753. + ((sp_uint128)a[ 4]) * b[ 1]
  15754. + ((sp_uint128)a[ 5]) * b[ 0];
  15755. t[ 4] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  15756. t0 = ((sp_uint128)a[ 0]) * b[ 6]
  15757. + ((sp_uint128)a[ 1]) * b[ 5]
  15758. + ((sp_uint128)a[ 2]) * b[ 4]
  15759. + ((sp_uint128)a[ 3]) * b[ 3]
  15760. + ((sp_uint128)a[ 4]) * b[ 2]
  15761. + ((sp_uint128)a[ 5]) * b[ 1]
  15762. + ((sp_uint128)a[ 6]) * b[ 0];
  15763. t[ 5] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  15764. t1 = ((sp_uint128)a[ 0]) * b[ 7]
  15765. + ((sp_uint128)a[ 1]) * b[ 6]
  15766. + ((sp_uint128)a[ 2]) * b[ 5]
  15767. + ((sp_uint128)a[ 3]) * b[ 4]
  15768. + ((sp_uint128)a[ 4]) * b[ 3]
  15769. + ((sp_uint128)a[ 5]) * b[ 2]
  15770. + ((sp_uint128)a[ 6]) * b[ 1]
  15771. + ((sp_uint128)a[ 7]) * b[ 0];
  15772. t[ 6] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  15773. t0 = ((sp_uint128)a[ 0]) * b[ 8]
  15774. + ((sp_uint128)a[ 1]) * b[ 7]
  15775. + ((sp_uint128)a[ 2]) * b[ 6]
  15776. + ((sp_uint128)a[ 3]) * b[ 5]
  15777. + ((sp_uint128)a[ 4]) * b[ 4]
  15778. + ((sp_uint128)a[ 5]) * b[ 3]
  15779. + ((sp_uint128)a[ 6]) * b[ 2]
  15780. + ((sp_uint128)a[ 7]) * b[ 1]
  15781. + ((sp_uint128)a[ 8]) * b[ 0];
  15782. t[ 7] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  15783. t1 = ((sp_uint128)a[ 0]) * b[ 9]
  15784. + ((sp_uint128)a[ 1]) * b[ 8]
  15785. + ((sp_uint128)a[ 2]) * b[ 7]
  15786. + ((sp_uint128)a[ 3]) * b[ 6]
  15787. + ((sp_uint128)a[ 4]) * b[ 5]
  15788. + ((sp_uint128)a[ 5]) * b[ 4]
  15789. + ((sp_uint128)a[ 6]) * b[ 3]
  15790. + ((sp_uint128)a[ 7]) * b[ 2]
  15791. + ((sp_uint128)a[ 8]) * b[ 1]
  15792. + ((sp_uint128)a[ 9]) * b[ 0];
  15793. t[ 8] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  15794. t0 = ((sp_uint128)a[ 0]) * b[10]
  15795. + ((sp_uint128)a[ 1]) * b[ 9]
  15796. + ((sp_uint128)a[ 2]) * b[ 8]
  15797. + ((sp_uint128)a[ 3]) * b[ 7]
  15798. + ((sp_uint128)a[ 4]) * b[ 6]
  15799. + ((sp_uint128)a[ 5]) * b[ 5]
  15800. + ((sp_uint128)a[ 6]) * b[ 4]
  15801. + ((sp_uint128)a[ 7]) * b[ 3]
  15802. + ((sp_uint128)a[ 8]) * b[ 2]
  15803. + ((sp_uint128)a[ 9]) * b[ 1]
  15804. + ((sp_uint128)a[10]) * b[ 0];
  15805. t[ 9] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  15806. t1 = ((sp_uint128)a[ 0]) * b[11]
  15807. + ((sp_uint128)a[ 1]) * b[10]
  15808. + ((sp_uint128)a[ 2]) * b[ 9]
  15809. + ((sp_uint128)a[ 3]) * b[ 8]
  15810. + ((sp_uint128)a[ 4]) * b[ 7]
  15811. + ((sp_uint128)a[ 5]) * b[ 6]
  15812. + ((sp_uint128)a[ 6]) * b[ 5]
  15813. + ((sp_uint128)a[ 7]) * b[ 4]
  15814. + ((sp_uint128)a[ 8]) * b[ 3]
  15815. + ((sp_uint128)a[ 9]) * b[ 2]
  15816. + ((sp_uint128)a[10]) * b[ 1]
  15817. + ((sp_uint128)a[11]) * b[ 0];
  15818. t[10] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  15819. t0 = ((sp_uint128)a[ 0]) * b[12]
  15820. + ((sp_uint128)a[ 1]) * b[11]
  15821. + ((sp_uint128)a[ 2]) * b[10]
  15822. + ((sp_uint128)a[ 3]) * b[ 9]
  15823. + ((sp_uint128)a[ 4]) * b[ 8]
  15824. + ((sp_uint128)a[ 5]) * b[ 7]
  15825. + ((sp_uint128)a[ 6]) * b[ 6]
  15826. + ((sp_uint128)a[ 7]) * b[ 5]
  15827. + ((sp_uint128)a[ 8]) * b[ 4]
  15828. + ((sp_uint128)a[ 9]) * b[ 3]
  15829. + ((sp_uint128)a[10]) * b[ 2]
  15830. + ((sp_uint128)a[11]) * b[ 1]
  15831. + ((sp_uint128)a[12]) * b[ 0];
  15832. t[11] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  15833. t1 = ((sp_uint128)a[ 1]) * b[12]
  15834. + ((sp_uint128)a[ 2]) * b[11]
  15835. + ((sp_uint128)a[ 3]) * b[10]
  15836. + ((sp_uint128)a[ 4]) * b[ 9]
  15837. + ((sp_uint128)a[ 5]) * b[ 8]
  15838. + ((sp_uint128)a[ 6]) * b[ 7]
  15839. + ((sp_uint128)a[ 7]) * b[ 6]
  15840. + ((sp_uint128)a[ 8]) * b[ 5]
  15841. + ((sp_uint128)a[ 9]) * b[ 4]
  15842. + ((sp_uint128)a[10]) * b[ 3]
  15843. + ((sp_uint128)a[11]) * b[ 2]
  15844. + ((sp_uint128)a[12]) * b[ 1];
  15845. t[12] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  15846. t0 = ((sp_uint128)a[ 2]) * b[12]
  15847. + ((sp_uint128)a[ 3]) * b[11]
  15848. + ((sp_uint128)a[ 4]) * b[10]
  15849. + ((sp_uint128)a[ 5]) * b[ 9]
  15850. + ((sp_uint128)a[ 6]) * b[ 8]
  15851. + ((sp_uint128)a[ 7]) * b[ 7]
  15852. + ((sp_uint128)a[ 8]) * b[ 6]
  15853. + ((sp_uint128)a[ 9]) * b[ 5]
  15854. + ((sp_uint128)a[10]) * b[ 4]
  15855. + ((sp_uint128)a[11]) * b[ 3]
  15856. + ((sp_uint128)a[12]) * b[ 2];
  15857. r[13] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  15858. t1 = ((sp_uint128)a[ 3]) * b[12]
  15859. + ((sp_uint128)a[ 4]) * b[11]
  15860. + ((sp_uint128)a[ 5]) * b[10]
  15861. + ((sp_uint128)a[ 6]) * b[ 9]
  15862. + ((sp_uint128)a[ 7]) * b[ 8]
  15863. + ((sp_uint128)a[ 8]) * b[ 7]
  15864. + ((sp_uint128)a[ 9]) * b[ 6]
  15865. + ((sp_uint128)a[10]) * b[ 5]
  15866. + ((sp_uint128)a[11]) * b[ 4]
  15867. + ((sp_uint128)a[12]) * b[ 3];
  15868. r[14] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  15869. t0 = ((sp_uint128)a[ 4]) * b[12]
  15870. + ((sp_uint128)a[ 5]) * b[11]
  15871. + ((sp_uint128)a[ 6]) * b[10]
  15872. + ((sp_uint128)a[ 7]) * b[ 9]
  15873. + ((sp_uint128)a[ 8]) * b[ 8]
  15874. + ((sp_uint128)a[ 9]) * b[ 7]
  15875. + ((sp_uint128)a[10]) * b[ 6]
  15876. + ((sp_uint128)a[11]) * b[ 5]
  15877. + ((sp_uint128)a[12]) * b[ 4];
  15878. r[15] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  15879. t1 = ((sp_uint128)a[ 5]) * b[12]
  15880. + ((sp_uint128)a[ 6]) * b[11]
  15881. + ((sp_uint128)a[ 7]) * b[10]
  15882. + ((sp_uint128)a[ 8]) * b[ 9]
  15883. + ((sp_uint128)a[ 9]) * b[ 8]
  15884. + ((sp_uint128)a[10]) * b[ 7]
  15885. + ((sp_uint128)a[11]) * b[ 6]
  15886. + ((sp_uint128)a[12]) * b[ 5];
  15887. r[16] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  15888. t0 = ((sp_uint128)a[ 6]) * b[12]
  15889. + ((sp_uint128)a[ 7]) * b[11]
  15890. + ((sp_uint128)a[ 8]) * b[10]
  15891. + ((sp_uint128)a[ 9]) * b[ 9]
  15892. + ((sp_uint128)a[10]) * b[ 8]
  15893. + ((sp_uint128)a[11]) * b[ 7]
  15894. + ((sp_uint128)a[12]) * b[ 6];
  15895. r[17] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  15896. t1 = ((sp_uint128)a[ 7]) * b[12]
  15897. + ((sp_uint128)a[ 8]) * b[11]
  15898. + ((sp_uint128)a[ 9]) * b[10]
  15899. + ((sp_uint128)a[10]) * b[ 9]
  15900. + ((sp_uint128)a[11]) * b[ 8]
  15901. + ((sp_uint128)a[12]) * b[ 7];
  15902. r[18] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  15903. t0 = ((sp_uint128)a[ 8]) * b[12]
  15904. + ((sp_uint128)a[ 9]) * b[11]
  15905. + ((sp_uint128)a[10]) * b[10]
  15906. + ((sp_uint128)a[11]) * b[ 9]
  15907. + ((sp_uint128)a[12]) * b[ 8];
  15908. r[19] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  15909. t1 = ((sp_uint128)a[ 9]) * b[12]
  15910. + ((sp_uint128)a[10]) * b[11]
  15911. + ((sp_uint128)a[11]) * b[10]
  15912. + ((sp_uint128)a[12]) * b[ 9];
  15913. r[20] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  15914. t0 = ((sp_uint128)a[10]) * b[12]
  15915. + ((sp_uint128)a[11]) * b[11]
  15916. + ((sp_uint128)a[12]) * b[10];
  15917. r[21] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  15918. t1 = ((sp_uint128)a[11]) * b[12]
  15919. + ((sp_uint128)a[12]) * b[11];
  15920. r[22] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  15921. t0 = ((sp_uint128)a[12]) * b[12];
  15922. r[23] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  15923. r[24] = t0 & 0x1fffffffffffffL;
  15924. r[25] = (sp_digit)(t0 >> 53);
  15925. XMEMCPY(r, t, sizeof(t));
  15926. }
  15927. /* Add b to a into r. (r = a + b)
  15928. *
  15929. * r A single precision integer.
  15930. * a A single precision integer.
  15931. * b A single precision integer.
  15932. */
  15933. SP_NOINLINE static int sp_4096_add_13(sp_digit* r, const sp_digit* a,
  15934. const sp_digit* b)
  15935. {
  15936. r[ 0] = a[ 0] + b[ 0];
  15937. r[ 1] = a[ 1] + b[ 1];
  15938. r[ 2] = a[ 2] + b[ 2];
  15939. r[ 3] = a[ 3] + b[ 3];
  15940. r[ 4] = a[ 4] + b[ 4];
  15941. r[ 5] = a[ 5] + b[ 5];
  15942. r[ 6] = a[ 6] + b[ 6];
  15943. r[ 7] = a[ 7] + b[ 7];
  15944. r[ 8] = a[ 8] + b[ 8];
  15945. r[ 9] = a[ 9] + b[ 9];
  15946. r[10] = a[10] + b[10];
  15947. r[11] = a[11] + b[11];
  15948. r[12] = a[12] + b[12];
  15949. return 0;
  15950. }
  15951. /* Sub b from a into r. (r = a - b)
  15952. *
  15953. * r A single precision integer.
  15954. * a A single precision integer.
  15955. * b A single precision integer.
  15956. */
  15957. SP_NOINLINE static int sp_4096_sub_26(sp_digit* r, const sp_digit* a,
  15958. const sp_digit* b)
  15959. {
  15960. int i;
  15961. for (i = 0; i < 24; i += 8) {
  15962. r[i + 0] = a[i + 0] - b[i + 0];
  15963. r[i + 1] = a[i + 1] - b[i + 1];
  15964. r[i + 2] = a[i + 2] - b[i + 2];
  15965. r[i + 3] = a[i + 3] - b[i + 3];
  15966. r[i + 4] = a[i + 4] - b[i + 4];
  15967. r[i + 5] = a[i + 5] - b[i + 5];
  15968. r[i + 6] = a[i + 6] - b[i + 6];
  15969. r[i + 7] = a[i + 7] - b[i + 7];
  15970. }
  15971. r[24] = a[24] - b[24];
  15972. r[25] = a[25] - b[25];
  15973. return 0;
  15974. }
  15975. /* Add b to a into r. (r = a + b)
  15976. *
  15977. * r A single precision integer.
  15978. * a A single precision integer.
  15979. * b A single precision integer.
  15980. */
  15981. SP_NOINLINE static int sp_4096_add_26(sp_digit* r, const sp_digit* a,
  15982. const sp_digit* b)
  15983. {
  15984. int i;
  15985. for (i = 0; i < 24; i += 8) {
  15986. r[i + 0] = a[i + 0] + b[i + 0];
  15987. r[i + 1] = a[i + 1] + b[i + 1];
  15988. r[i + 2] = a[i + 2] + b[i + 2];
  15989. r[i + 3] = a[i + 3] + b[i + 3];
  15990. r[i + 4] = a[i + 4] + b[i + 4];
  15991. r[i + 5] = a[i + 5] + b[i + 5];
  15992. r[i + 6] = a[i + 6] + b[i + 6];
  15993. r[i + 7] = a[i + 7] + b[i + 7];
  15994. }
  15995. r[24] = a[24] + b[24];
  15996. r[25] = a[25] + b[25];
  15997. return 0;
  15998. }
  15999. /* Multiply a and b into r. (r = a * b)
  16000. *
  16001. * r A single precision integer.
  16002. * a A single precision integer.
  16003. * b A single precision integer.
  16004. */
  16005. SP_NOINLINE static void sp_4096_mul_39(sp_digit* r, const sp_digit* a,
  16006. const sp_digit* b)
  16007. {
  16008. sp_digit p0[26];
  16009. sp_digit p1[26];
  16010. sp_digit p2[26];
  16011. sp_digit p3[26];
  16012. sp_digit p4[26];
  16013. sp_digit p5[26];
  16014. sp_digit t0[26];
  16015. sp_digit t1[26];
  16016. sp_digit t2[26];
  16017. sp_digit a0[13];
  16018. sp_digit a1[13];
  16019. sp_digit a2[13];
  16020. sp_digit b0[13];
  16021. sp_digit b1[13];
  16022. sp_digit b2[13];
  16023. (void)sp_4096_add_13(a0, a, &a[13]);
  16024. (void)sp_4096_add_13(b0, b, &b[13]);
  16025. (void)sp_4096_add_13(a1, &a[13], &a[26]);
  16026. (void)sp_4096_add_13(b1, &b[13], &b[26]);
  16027. (void)sp_4096_add_13(a2, a0, &a[26]);
  16028. (void)sp_4096_add_13(b2, b0, &b[26]);
  16029. sp_4096_mul_13(p0, a, b);
  16030. sp_4096_mul_13(p2, &a[13], &b[13]);
  16031. sp_4096_mul_13(p4, &a[26], &b[26]);
  16032. sp_4096_mul_13(p1, a0, b0);
  16033. sp_4096_mul_13(p3, a1, b1);
  16034. sp_4096_mul_13(p5, a2, b2);
  16035. XMEMSET(r, 0, sizeof(*r)*2U*39U);
  16036. (void)sp_4096_sub_26(t0, p3, p2);
  16037. (void)sp_4096_sub_26(t1, p1, p2);
  16038. (void)sp_4096_sub_26(t2, p5, t0);
  16039. (void)sp_4096_sub_26(t2, t2, t1);
  16040. (void)sp_4096_sub_26(t0, t0, p4);
  16041. (void)sp_4096_sub_26(t1, t1, p0);
  16042. (void)sp_4096_add_26(r, r, p0);
  16043. (void)sp_4096_add_26(&r[13], &r[13], t1);
  16044. (void)sp_4096_add_26(&r[26], &r[26], t2);
  16045. (void)sp_4096_add_26(&r[39], &r[39], t0);
  16046. (void)sp_4096_add_26(&r[52], &r[52], p4);
  16047. }
  16048. /* Add b to a into r. (r = a + b)
  16049. *
  16050. * r A single precision integer.
  16051. * a A single precision integer.
  16052. * b A single precision integer.
  16053. */
  16054. SP_NOINLINE static int sp_4096_add_39(sp_digit* r, const sp_digit* a,
  16055. const sp_digit* b)
  16056. {
  16057. int i;
  16058. for (i = 0; i < 32; i += 8) {
  16059. r[i + 0] = a[i + 0] + b[i + 0];
  16060. r[i + 1] = a[i + 1] + b[i + 1];
  16061. r[i + 2] = a[i + 2] + b[i + 2];
  16062. r[i + 3] = a[i + 3] + b[i + 3];
  16063. r[i + 4] = a[i + 4] + b[i + 4];
  16064. r[i + 5] = a[i + 5] + b[i + 5];
  16065. r[i + 6] = a[i + 6] + b[i + 6];
  16066. r[i + 7] = a[i + 7] + b[i + 7];
  16067. }
  16068. r[32] = a[32] + b[32];
  16069. r[33] = a[33] + b[33];
  16070. r[34] = a[34] + b[34];
  16071. r[35] = a[35] + b[35];
  16072. r[36] = a[36] + b[36];
  16073. r[37] = a[37] + b[37];
  16074. r[38] = a[38] + b[38];
  16075. return 0;
  16076. }
  16077. /* Add b to a into r. (r = a + b)
  16078. *
  16079. * r A single precision integer.
  16080. * a A single precision integer.
  16081. * b A single precision integer.
  16082. */
  16083. SP_NOINLINE static int sp_4096_add_78(sp_digit* r, const sp_digit* a,
  16084. const sp_digit* b)
  16085. {
  16086. int i;
  16087. for (i = 0; i < 72; i += 8) {
  16088. r[i + 0] = a[i + 0] + b[i + 0];
  16089. r[i + 1] = a[i + 1] + b[i + 1];
  16090. r[i + 2] = a[i + 2] + b[i + 2];
  16091. r[i + 3] = a[i + 3] + b[i + 3];
  16092. r[i + 4] = a[i + 4] + b[i + 4];
  16093. r[i + 5] = a[i + 5] + b[i + 5];
  16094. r[i + 6] = a[i + 6] + b[i + 6];
  16095. r[i + 7] = a[i + 7] + b[i + 7];
  16096. }
  16097. r[72] = a[72] + b[72];
  16098. r[73] = a[73] + b[73];
  16099. r[74] = a[74] + b[74];
  16100. r[75] = a[75] + b[75];
  16101. r[76] = a[76] + b[76];
  16102. r[77] = a[77] + b[77];
  16103. return 0;
  16104. }
  16105. /* Sub b from a into r. (r = a - b)
  16106. *
  16107. * r A single precision integer.
  16108. * a A single precision integer.
  16109. * b A single precision integer.
  16110. */
  16111. SP_NOINLINE static int sp_4096_sub_78(sp_digit* r, const sp_digit* a,
  16112. const sp_digit* b)
  16113. {
  16114. int i;
  16115. for (i = 0; i < 72; i += 8) {
  16116. r[i + 0] = a[i + 0] - b[i + 0];
  16117. r[i + 1] = a[i + 1] - b[i + 1];
  16118. r[i + 2] = a[i + 2] - b[i + 2];
  16119. r[i + 3] = a[i + 3] - b[i + 3];
  16120. r[i + 4] = a[i + 4] - b[i + 4];
  16121. r[i + 5] = a[i + 5] - b[i + 5];
  16122. r[i + 6] = a[i + 6] - b[i + 6];
  16123. r[i + 7] = a[i + 7] - b[i + 7];
  16124. }
  16125. r[72] = a[72] - b[72];
  16126. r[73] = a[73] - b[73];
  16127. r[74] = a[74] - b[74];
  16128. r[75] = a[75] - b[75];
  16129. r[76] = a[76] - b[76];
  16130. r[77] = a[77] - b[77];
  16131. return 0;
  16132. }
  16133. /* Multiply a and b into r. (r = a * b)
  16134. *
  16135. * r A single precision integer.
  16136. * a A single precision integer.
  16137. * b A single precision integer.
  16138. */
  16139. SP_NOINLINE static void sp_4096_mul_78(sp_digit* r, const sp_digit* a,
  16140. const sp_digit* b)
  16141. {
  16142. sp_digit* z0 = r;
  16143. sp_digit z1[78];
  16144. sp_digit* a1 = z1;
  16145. sp_digit b1[39];
  16146. sp_digit* z2 = r + 78;
  16147. (void)sp_4096_add_39(a1, a, &a[39]);
  16148. (void)sp_4096_add_39(b1, b, &b[39]);
  16149. sp_4096_mul_39(z2, &a[39], &b[39]);
  16150. sp_4096_mul_39(z0, a, b);
  16151. sp_4096_mul_39(z1, a1, b1);
  16152. (void)sp_4096_sub_78(z1, z1, z2);
  16153. (void)sp_4096_sub_78(z1, z1, z0);
  16154. (void)sp_4096_add_78(r + 39, r + 39, z1);
  16155. }
  16156. /* Square a and put result in r. (r = a * a)
  16157. *
  16158. * r A single precision integer.
  16159. * a A single precision integer.
  16160. */
  16161. SP_NOINLINE static void sp_4096_sqr_13(sp_digit* r, const sp_digit* a)
  16162. {
  16163. sp_uint128 t0;
  16164. sp_uint128 t1;
  16165. sp_digit t[13];
  16166. t0 = ((sp_uint128)a[ 0]) * a[ 0];
  16167. t1 = (((sp_uint128)a[ 0]) * a[ 1]) * 2;
  16168. t[ 0] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  16169. t0 = (((sp_uint128)a[ 0]) * a[ 2]) * 2
  16170. + ((sp_uint128)a[ 1]) * a[ 1];
  16171. t[ 1] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  16172. t1 = (((sp_uint128)a[ 0]) * a[ 3]
  16173. + ((sp_uint128)a[ 1]) * a[ 2]) * 2;
  16174. t[ 2] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  16175. t0 = (((sp_uint128)a[ 0]) * a[ 4]
  16176. + ((sp_uint128)a[ 1]) * a[ 3]) * 2
  16177. + ((sp_uint128)a[ 2]) * a[ 2];
  16178. t[ 3] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  16179. t1 = (((sp_uint128)a[ 0]) * a[ 5]
  16180. + ((sp_uint128)a[ 1]) * a[ 4]
  16181. + ((sp_uint128)a[ 2]) * a[ 3]) * 2;
  16182. t[ 4] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  16183. t0 = (((sp_uint128)a[ 0]) * a[ 6]
  16184. + ((sp_uint128)a[ 1]) * a[ 5]
  16185. + ((sp_uint128)a[ 2]) * a[ 4]) * 2
  16186. + ((sp_uint128)a[ 3]) * a[ 3];
  16187. t[ 5] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  16188. t1 = (((sp_uint128)a[ 0]) * a[ 7]
  16189. + ((sp_uint128)a[ 1]) * a[ 6]
  16190. + ((sp_uint128)a[ 2]) * a[ 5]
  16191. + ((sp_uint128)a[ 3]) * a[ 4]) * 2;
  16192. t[ 6] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  16193. t0 = (((sp_uint128)a[ 0]) * a[ 8]
  16194. + ((sp_uint128)a[ 1]) * a[ 7]
  16195. + ((sp_uint128)a[ 2]) * a[ 6]
  16196. + ((sp_uint128)a[ 3]) * a[ 5]) * 2
  16197. + ((sp_uint128)a[ 4]) * a[ 4];
  16198. t[ 7] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  16199. t1 = (((sp_uint128)a[ 0]) * a[ 9]
  16200. + ((sp_uint128)a[ 1]) * a[ 8]
  16201. + ((sp_uint128)a[ 2]) * a[ 7]
  16202. + ((sp_uint128)a[ 3]) * a[ 6]
  16203. + ((sp_uint128)a[ 4]) * a[ 5]) * 2;
  16204. t[ 8] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  16205. t0 = (((sp_uint128)a[ 0]) * a[10]
  16206. + ((sp_uint128)a[ 1]) * a[ 9]
  16207. + ((sp_uint128)a[ 2]) * a[ 8]
  16208. + ((sp_uint128)a[ 3]) * a[ 7]
  16209. + ((sp_uint128)a[ 4]) * a[ 6]) * 2
  16210. + ((sp_uint128)a[ 5]) * a[ 5];
  16211. t[ 9] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  16212. t1 = (((sp_uint128)a[ 0]) * a[11]
  16213. + ((sp_uint128)a[ 1]) * a[10]
  16214. + ((sp_uint128)a[ 2]) * a[ 9]
  16215. + ((sp_uint128)a[ 3]) * a[ 8]
  16216. + ((sp_uint128)a[ 4]) * a[ 7]
  16217. + ((sp_uint128)a[ 5]) * a[ 6]) * 2;
  16218. t[10] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  16219. t0 = (((sp_uint128)a[ 0]) * a[12]
  16220. + ((sp_uint128)a[ 1]) * a[11]
  16221. + ((sp_uint128)a[ 2]) * a[10]
  16222. + ((sp_uint128)a[ 3]) * a[ 9]
  16223. + ((sp_uint128)a[ 4]) * a[ 8]
  16224. + ((sp_uint128)a[ 5]) * a[ 7]) * 2
  16225. + ((sp_uint128)a[ 6]) * a[ 6];
  16226. t[11] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  16227. t1 = (((sp_uint128)a[ 1]) * a[12]
  16228. + ((sp_uint128)a[ 2]) * a[11]
  16229. + ((sp_uint128)a[ 3]) * a[10]
  16230. + ((sp_uint128)a[ 4]) * a[ 9]
  16231. + ((sp_uint128)a[ 5]) * a[ 8]
  16232. + ((sp_uint128)a[ 6]) * a[ 7]) * 2;
  16233. t[12] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  16234. t0 = (((sp_uint128)a[ 2]) * a[12]
  16235. + ((sp_uint128)a[ 3]) * a[11]
  16236. + ((sp_uint128)a[ 4]) * a[10]
  16237. + ((sp_uint128)a[ 5]) * a[ 9]
  16238. + ((sp_uint128)a[ 6]) * a[ 8]) * 2
  16239. + ((sp_uint128)a[ 7]) * a[ 7];
  16240. r[13] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  16241. t1 = (((sp_uint128)a[ 3]) * a[12]
  16242. + ((sp_uint128)a[ 4]) * a[11]
  16243. + ((sp_uint128)a[ 5]) * a[10]
  16244. + ((sp_uint128)a[ 6]) * a[ 9]
  16245. + ((sp_uint128)a[ 7]) * a[ 8]) * 2;
  16246. r[14] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  16247. t0 = (((sp_uint128)a[ 4]) * a[12]
  16248. + ((sp_uint128)a[ 5]) * a[11]
  16249. + ((sp_uint128)a[ 6]) * a[10]
  16250. + ((sp_uint128)a[ 7]) * a[ 9]) * 2
  16251. + ((sp_uint128)a[ 8]) * a[ 8];
  16252. r[15] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  16253. t1 = (((sp_uint128)a[ 5]) * a[12]
  16254. + ((sp_uint128)a[ 6]) * a[11]
  16255. + ((sp_uint128)a[ 7]) * a[10]
  16256. + ((sp_uint128)a[ 8]) * a[ 9]) * 2;
  16257. r[16] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  16258. t0 = (((sp_uint128)a[ 6]) * a[12]
  16259. + ((sp_uint128)a[ 7]) * a[11]
  16260. + ((sp_uint128)a[ 8]) * a[10]) * 2
  16261. + ((sp_uint128)a[ 9]) * a[ 9];
  16262. r[17] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  16263. t1 = (((sp_uint128)a[ 7]) * a[12]
  16264. + ((sp_uint128)a[ 8]) * a[11]
  16265. + ((sp_uint128)a[ 9]) * a[10]) * 2;
  16266. r[18] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  16267. t0 = (((sp_uint128)a[ 8]) * a[12]
  16268. + ((sp_uint128)a[ 9]) * a[11]) * 2
  16269. + ((sp_uint128)a[10]) * a[10];
  16270. r[19] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  16271. t1 = (((sp_uint128)a[ 9]) * a[12]
  16272. + ((sp_uint128)a[10]) * a[11]) * 2;
  16273. r[20] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  16274. t0 = (((sp_uint128)a[10]) * a[12]) * 2
  16275. + ((sp_uint128)a[11]) * a[11];
  16276. r[21] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  16277. t1 = (((sp_uint128)a[11]) * a[12]) * 2;
  16278. r[22] = t0 & 0x1fffffffffffffL; t1 += t0 >> 53;
  16279. t0 = ((sp_uint128)a[12]) * a[12];
  16280. r[23] = t1 & 0x1fffffffffffffL; t0 += t1 >> 53;
  16281. r[24] = t0 & 0x1fffffffffffffL;
  16282. r[25] = (sp_digit)(t0 >> 53);
  16283. XMEMCPY(r, t, sizeof(t));
  16284. }
  16285. /* Square a into r. (r = a * a)
  16286. *
  16287. * r A single precision integer.
  16288. * a A single precision integer.
  16289. */
  16290. SP_NOINLINE static void sp_4096_sqr_39(sp_digit* r, const sp_digit* a)
  16291. {
  16292. sp_digit p0[26];
  16293. sp_digit p1[26];
  16294. sp_digit p2[26];
  16295. sp_digit p3[26];
  16296. sp_digit p4[26];
  16297. sp_digit p5[26];
  16298. sp_digit t0[26];
  16299. sp_digit t1[26];
  16300. sp_digit t2[26];
  16301. sp_digit a0[13];
  16302. sp_digit a1[13];
  16303. sp_digit a2[13];
  16304. (void)sp_4096_add_13(a0, a, &a[13]);
  16305. (void)sp_4096_add_13(a1, &a[13], &a[26]);
  16306. (void)sp_4096_add_13(a2, a0, &a[26]);
  16307. sp_4096_sqr_13(p0, a);
  16308. sp_4096_sqr_13(p2, &a[13]);
  16309. sp_4096_sqr_13(p4, &a[26]);
  16310. sp_4096_sqr_13(p1, a0);
  16311. sp_4096_sqr_13(p3, a1);
  16312. sp_4096_sqr_13(p5, a2);
  16313. XMEMSET(r, 0, sizeof(*r)*2U*39U);
  16314. (void)sp_4096_sub_26(t0, p3, p2);
  16315. (void)sp_4096_sub_26(t1, p1, p2);
  16316. (void)sp_4096_sub_26(t2, p5, t0);
  16317. (void)sp_4096_sub_26(t2, t2, t1);
  16318. (void)sp_4096_sub_26(t0, t0, p4);
  16319. (void)sp_4096_sub_26(t1, t1, p0);
  16320. (void)sp_4096_add_26(r, r, p0);
  16321. (void)sp_4096_add_26(&r[13], &r[13], t1);
  16322. (void)sp_4096_add_26(&r[26], &r[26], t2);
  16323. (void)sp_4096_add_26(&r[39], &r[39], t0);
  16324. (void)sp_4096_add_26(&r[52], &r[52], p4);
  16325. }
  16326. /* Square a and put result in r. (r = a * a)
  16327. *
  16328. * r A single precision integer.
  16329. * a A single precision integer.
  16330. */
  16331. SP_NOINLINE static void sp_4096_sqr_78(sp_digit* r, const sp_digit* a)
  16332. {
  16333. sp_digit* z0 = r;
  16334. sp_digit z1[78];
  16335. sp_digit* a1 = z1;
  16336. sp_digit* z2 = r + 78;
  16337. (void)sp_4096_add_39(a1, a, &a[39]);
  16338. sp_4096_sqr_39(z2, &a[39]);
  16339. sp_4096_sqr_39(z0, a);
  16340. sp_4096_sqr_39(z1, a1);
  16341. (void)sp_4096_sub_78(z1, z1, z2);
  16342. (void)sp_4096_sub_78(z1, z1, z0);
  16343. (void)sp_4096_add_78(r + 39, r + 39, z1);
  16344. }
  16345. #endif /* !WOLFSSL_SP_SMALL */
  16346. /* Calculate the bottom digit of -1/a mod 2^n.
  16347. *
  16348. * a A single precision number.
  16349. * rho Bottom word of inverse.
  16350. */
  16351. static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho)
  16352. {
  16353. sp_digit x;
  16354. sp_digit b;
  16355. b = a[0];
  16356. x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
  16357. x *= 2 - b * x; /* here x*a==1 mod 2**8 */
  16358. x *= 2 - b * x; /* here x*a==1 mod 2**16 */
  16359. x *= 2 - b * x; /* here x*a==1 mod 2**32 */
  16360. x *= 2 - b * x; /* here x*a==1 mod 2**64 */
  16361. x &= 0x1fffffffffffffL;
  16362. /* rho = -1/m mod b */
  16363. *rho = ((sp_digit)1 << 53) - x;
  16364. }
  16365. /* Multiply a by scalar b into r. (r = a * b)
  16366. *
  16367. * r A single precision integer.
  16368. * a A single precision integer.
  16369. * b A scalar.
  16370. */
  16371. SP_NOINLINE static void sp_4096_mul_d_78(sp_digit* r, const sp_digit* a,
  16372. sp_digit b)
  16373. {
  16374. sp_int128 tb = b;
  16375. sp_int128 t = 0;
  16376. sp_digit t2;
  16377. sp_int128 p[4];
  16378. int i;
  16379. for (i = 0; i < 76; i += 4) {
  16380. p[0] = tb * a[i + 0];
  16381. p[1] = tb * a[i + 1];
  16382. p[2] = tb * a[i + 2];
  16383. p[3] = tb * a[i + 3];
  16384. t += p[0];
  16385. t2 = (sp_digit)(t & 0x1fffffffffffffL);
  16386. t >>= 53;
  16387. r[i + 0] = (sp_digit)t2;
  16388. t += p[1];
  16389. t2 = (sp_digit)(t & 0x1fffffffffffffL);
  16390. t >>= 53;
  16391. r[i + 1] = (sp_digit)t2;
  16392. t += p[2];
  16393. t2 = (sp_digit)(t & 0x1fffffffffffffL);
  16394. t >>= 53;
  16395. r[i + 2] = (sp_digit)t2;
  16396. t += p[3];
  16397. t2 = (sp_digit)(t & 0x1fffffffffffffL);
  16398. t >>= 53;
  16399. r[i + 3] = (sp_digit)t2;
  16400. }
  16401. t += tb * a[76];
  16402. r[76] = (sp_digit)(t & 0x1fffffffffffffL);
  16403. t >>= 53;
  16404. t += tb * a[77];
  16405. r[77] = (sp_digit)(t & 0x1fffffffffffffL);
  16406. t >>= 53;
  16407. r[78] = (sp_digit)(t & 0x1fffffffffffffL);
  16408. }
  16409. #if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
  16410. #if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D)
  16411. /* Sub b from a into r. (r = a - b)
  16412. *
  16413. * r A single precision integer.
  16414. * a A single precision integer.
  16415. * b A single precision integer.
  16416. */
  16417. SP_NOINLINE static int sp_4096_sub_39(sp_digit* r, const sp_digit* a,
  16418. const sp_digit* b)
  16419. {
  16420. int i;
  16421. for (i = 0; i < 32; i += 8) {
  16422. r[i + 0] = a[i + 0] - b[i + 0];
  16423. r[i + 1] = a[i + 1] - b[i + 1];
  16424. r[i + 2] = a[i + 2] - b[i + 2];
  16425. r[i + 3] = a[i + 3] - b[i + 3];
  16426. r[i + 4] = a[i + 4] - b[i + 4];
  16427. r[i + 5] = a[i + 5] - b[i + 5];
  16428. r[i + 6] = a[i + 6] - b[i + 6];
  16429. r[i + 7] = a[i + 7] - b[i + 7];
  16430. }
  16431. r[32] = a[32] - b[32];
  16432. r[33] = a[33] - b[33];
  16433. r[34] = a[34] - b[34];
  16434. r[35] = a[35] - b[35];
  16435. r[36] = a[36] - b[36];
  16436. r[37] = a[37] - b[37];
  16437. r[38] = a[38] - b[38];
  16438. return 0;
  16439. }
  16440. /* r = 2^n mod m where n is the number of bits to reduce by.
  16441. * Given m must be 4096 bits, just need to subtract.
  16442. *
  16443. * r A single precision number.
  16444. * m A single precision number.
  16445. */
  16446. static void sp_4096_mont_norm_39(sp_digit* r, const sp_digit* m)
  16447. {
  16448. /* Set r = 2^n - 1. */
  16449. int i;
  16450. for (i = 0; i < 32; i += 8) {
  16451. r[i + 0] = 0x1fffffffffffffL;
  16452. r[i + 1] = 0x1fffffffffffffL;
  16453. r[i + 2] = 0x1fffffffffffffL;
  16454. r[i + 3] = 0x1fffffffffffffL;
  16455. r[i + 4] = 0x1fffffffffffffL;
  16456. r[i + 5] = 0x1fffffffffffffL;
  16457. r[i + 6] = 0x1fffffffffffffL;
  16458. r[i + 7] = 0x1fffffffffffffL;
  16459. }
  16460. r[32] = 0x1fffffffffffffL;
  16461. r[33] = 0x1fffffffffffffL;
  16462. r[34] = 0x1fffffffffffffL;
  16463. r[35] = 0x1fffffffffffffL;
  16464. r[36] = 0x1fffffffffffffL;
  16465. r[37] = 0x1fffffffffffffL;
  16466. r[38] = 0x3ffffffffL;
  16467. /* r = (2^n - 1) mod n */
  16468. (void)sp_4096_sub_39(r, r, m);
  16469. /* Add one so r = 2^n mod m */
  16470. r[0] += 1;
  16471. }
  16472. /* Compare a with b in constant time.
  16473. *
  16474. * a A single precision integer.
  16475. * b A single precision integer.
  16476. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  16477. * respectively.
  16478. */
  16479. static sp_digit sp_4096_cmp_39(const sp_digit* a, const sp_digit* b)
  16480. {
  16481. sp_digit r = 0;
  16482. int i;
  16483. r |= (a[38] - b[38]) & (0 - (sp_digit)1);
  16484. r |= (a[37] - b[37]) & ~(((sp_digit)0 - r) >> 52);
  16485. r |= (a[36] - b[36]) & ~(((sp_digit)0 - r) >> 52);
  16486. r |= (a[35] - b[35]) & ~(((sp_digit)0 - r) >> 52);
  16487. r |= (a[34] - b[34]) & ~(((sp_digit)0 - r) >> 52);
  16488. r |= (a[33] - b[33]) & ~(((sp_digit)0 - r) >> 52);
  16489. r |= (a[32] - b[32]) & ~(((sp_digit)0 - r) >> 52);
  16490. for (i = 24; i >= 0; i -= 8) {
  16491. r |= (a[i + 7] - b[i + 7]) & ~(((sp_digit)0 - r) >> 52);
  16492. r |= (a[i + 6] - b[i + 6]) & ~(((sp_digit)0 - r) >> 52);
  16493. r |= (a[i + 5] - b[i + 5]) & ~(((sp_digit)0 - r) >> 52);
  16494. r |= (a[i + 4] - b[i + 4]) & ~(((sp_digit)0 - r) >> 52);
  16495. r |= (a[i + 3] - b[i + 3]) & ~(((sp_digit)0 - r) >> 52);
  16496. r |= (a[i + 2] - b[i + 2]) & ~(((sp_digit)0 - r) >> 52);
  16497. r |= (a[i + 1] - b[i + 1]) & ~(((sp_digit)0 - r) >> 52);
  16498. r |= (a[i + 0] - b[i + 0]) & ~(((sp_digit)0 - r) >> 52);
  16499. }
  16500. return r;
  16501. }
  16502. /* Conditionally subtract b from a using the mask m.
  16503. * m is -1 to subtract and 0 when not.
  16504. *
  16505. * r A single precision number representing condition subtract result.
  16506. * a A single precision number to subtract from.
  16507. * b A single precision number to subtract.
  16508. * m Mask value to apply.
  16509. */
  16510. static void sp_4096_cond_sub_39(sp_digit* r, const sp_digit* a,
  16511. const sp_digit* b, const sp_digit m)
  16512. {
  16513. int i;
  16514. for (i = 0; i < 32; i += 8) {
  16515. r[i + 0] = a[i + 0] - (b[i + 0] & m);
  16516. r[i + 1] = a[i + 1] - (b[i + 1] & m);
  16517. r[i + 2] = a[i + 2] - (b[i + 2] & m);
  16518. r[i + 3] = a[i + 3] - (b[i + 3] & m);
  16519. r[i + 4] = a[i + 4] - (b[i + 4] & m);
  16520. r[i + 5] = a[i + 5] - (b[i + 5] & m);
  16521. r[i + 6] = a[i + 6] - (b[i + 6] & m);
  16522. r[i + 7] = a[i + 7] - (b[i + 7] & m);
  16523. }
  16524. r[32] = a[32] - (b[32] & m);
  16525. r[33] = a[33] - (b[33] & m);
  16526. r[34] = a[34] - (b[34] & m);
  16527. r[35] = a[35] - (b[35] & m);
  16528. r[36] = a[36] - (b[36] & m);
  16529. r[37] = a[37] - (b[37] & m);
  16530. r[38] = a[38] - (b[38] & m);
  16531. }
  16532. /* Mul a by scalar b and add into r. (r += a * b)
  16533. *
  16534. * r A single precision integer.
  16535. * a A single precision integer.
  16536. * b A scalar.
  16537. */
  16538. SP_NOINLINE static void sp_4096_mul_add_39(sp_digit* r, const sp_digit* a,
  16539. const sp_digit b)
  16540. {
  16541. sp_int128 tb = b;
  16542. sp_int128 t[8];
  16543. int i;
  16544. t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1fffffffffffffL);
  16545. for (i = 0; i < 32; i += 8) {
  16546. t[1] = tb * a[i+1];
  16547. r[i+1] += (sp_digit)((t[0] >> 53) + (t[1] & 0x1fffffffffffffL));
  16548. t[2] = tb * a[i+2];
  16549. r[i+2] += (sp_digit)((t[1] >> 53) + (t[2] & 0x1fffffffffffffL));
  16550. t[3] = tb * a[i+3];
  16551. r[i+3] += (sp_digit)((t[2] >> 53) + (t[3] & 0x1fffffffffffffL));
  16552. t[4] = tb * a[i+4];
  16553. r[i+4] += (sp_digit)((t[3] >> 53) + (t[4] & 0x1fffffffffffffL));
  16554. t[5] = tb * a[i+5];
  16555. r[i+5] += (sp_digit)((t[4] >> 53) + (t[5] & 0x1fffffffffffffL));
  16556. t[6] = tb * a[i+6];
  16557. r[i+6] += (sp_digit)((t[5] >> 53) + (t[6] & 0x1fffffffffffffL));
  16558. t[7] = tb * a[i+7];
  16559. r[i+7] += (sp_digit)((t[6] >> 53) + (t[7] & 0x1fffffffffffffL));
  16560. t[0] = tb * a[i+8];
  16561. r[i+8] += (sp_digit)((t[7] >> 53) + (t[0] & 0x1fffffffffffffL));
  16562. }
  16563. t[1] = tb * a[33];
  16564. r[33] += (sp_digit)((t[0] >> 53) + (t[1] & 0x1fffffffffffffL));
  16565. t[2] = tb * a[34];
  16566. r[34] += (sp_digit)((t[1] >> 53) + (t[2] & 0x1fffffffffffffL));
  16567. t[3] = tb * a[35];
  16568. r[35] += (sp_digit)((t[2] >> 53) + (t[3] & 0x1fffffffffffffL));
  16569. t[4] = tb * a[36];
  16570. r[36] += (sp_digit)((t[3] >> 53) + (t[4] & 0x1fffffffffffffL));
  16571. t[5] = tb * a[37];
  16572. r[37] += (sp_digit)((t[4] >> 53) + (t[5] & 0x1fffffffffffffL));
  16573. t[6] = tb * a[38];
  16574. r[38] += (sp_digit)((t[5] >> 53) + (t[6] & 0x1fffffffffffffL));
  16575. r[39] += (sp_digit)(t[6] >> 53);
  16576. }
  16577. /* Shift the result in the high 2048 bits down to the bottom.
  16578. *
  16579. * r A single precision number.
  16580. * a A single precision number.
  16581. */
  16582. static void sp_4096_mont_shift_39(sp_digit* r, const sp_digit* a)
  16583. {
  16584. int i;
  16585. sp_int128 n = a[38] >> 34;
  16586. n += ((sp_int128)a[39]) << 19;
  16587. for (i = 0; i < 32; i += 8) {
  16588. r[i + 0] = n & 0x1fffffffffffffL;
  16589. n >>= 53; n += ((sp_int128)a[i + 40]) << 19;
  16590. r[i + 1] = n & 0x1fffffffffffffL;
  16591. n >>= 53; n += ((sp_int128)a[i + 41]) << 19;
  16592. r[i + 2] = n & 0x1fffffffffffffL;
  16593. n >>= 53; n += ((sp_int128)a[i + 42]) << 19;
  16594. r[i + 3] = n & 0x1fffffffffffffL;
  16595. n >>= 53; n += ((sp_int128)a[i + 43]) << 19;
  16596. r[i + 4] = n & 0x1fffffffffffffL;
  16597. n >>= 53; n += ((sp_int128)a[i + 44]) << 19;
  16598. r[i + 5] = n & 0x1fffffffffffffL;
  16599. n >>= 53; n += ((sp_int128)a[i + 45]) << 19;
  16600. r[i + 6] = n & 0x1fffffffffffffL;
  16601. n >>= 53; n += ((sp_int128)a[i + 46]) << 19;
  16602. r[i + 7] = n & 0x1fffffffffffffL;
  16603. n >>= 53; n += ((sp_int128)a[i + 47]) << 19;
  16604. }
  16605. r[32] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[72]) << 19;
  16606. r[33] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[73]) << 19;
  16607. r[34] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[74]) << 19;
  16608. r[35] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[75]) << 19;
  16609. r[36] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[76]) << 19;
  16610. r[37] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[77]) << 19;
  16611. r[38] = (sp_digit)n;
  16612. XMEMSET(&r[39], 0, sizeof(*r) * 39U);
  16613. }
  16614. /* Reduce the number back to 4096 bits using Montgomery reduction.
  16615. *
  16616. * a A single precision number to reduce in place.
  16617. * m The single precision number representing the modulus.
  16618. * mp The digit representing the negative inverse of m mod 2^n.
  16619. */
  16620. static void sp_4096_mont_reduce_39(sp_digit* a, const sp_digit* m, sp_digit mp)
  16621. {
  16622. int i;
  16623. sp_digit mu;
  16624. sp_digit over;
  16625. sp_4096_norm_39(a + 39);
  16626. for (i=0; i<38; i++) {
  16627. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1fffffffffffffL;
  16628. sp_4096_mul_add_39(a+i, m, mu);
  16629. a[i+1] += a[i] >> 53;
  16630. }
  16631. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x3ffffffffL;
  16632. sp_4096_mul_add_39(a+i, m, mu);
  16633. a[i+1] += a[i] >> 53;
  16634. a[i] &= 0x1fffffffffffffL;
  16635. sp_4096_mont_shift_39(a, a);
  16636. over = a[38] - m[38];
  16637. sp_4096_cond_sub_39(a, a, m, ~((over - 1) >> 63));
  16638. sp_4096_norm_39(a);
  16639. }
  16640. /* Multiply two Montgomery form numbers mod the modulus (prime).
  16641. * (r = a * b mod m)
  16642. *
  16643. * r Result of multiplication.
  16644. * a First number to multiply in Montgomery form.
  16645. * b Second number to multiply in Montgomery form.
  16646. * m Modulus (prime).
  16647. * mp Montgomery multiplier.
  16648. */
  16649. SP_NOINLINE static void sp_4096_mont_mul_39(sp_digit* r, const sp_digit* a,
  16650. const sp_digit* b, const sp_digit* m, sp_digit mp)
  16651. {
  16652. sp_4096_mul_39(r, a, b);
  16653. sp_4096_mont_reduce_39(r, m, mp);
  16654. }
  16655. /* Square the Montgomery form number. (r = a * a mod m)
  16656. *
  16657. * r Result of squaring.
  16658. * a Number to square in Montgomery form.
  16659. * m Modulus (prime).
  16660. * mp Montgomery multiplier.
  16661. */
  16662. SP_NOINLINE static void sp_4096_mont_sqr_39(sp_digit* r, const sp_digit* a,
  16663. const sp_digit* m, sp_digit mp)
  16664. {
  16665. sp_4096_sqr_39(r, a);
  16666. sp_4096_mont_reduce_39(r, m, mp);
  16667. }
  16668. /* Multiply a by scalar b into r. (r = a * b)
  16669. *
  16670. * r A single precision integer.
  16671. * a A single precision integer.
  16672. * b A scalar.
  16673. */
  16674. SP_NOINLINE static void sp_4096_mul_d_39(sp_digit* r, const sp_digit* a,
  16675. sp_digit b)
  16676. {
  16677. sp_int128 tb = b;
  16678. sp_int128 t = 0;
  16679. sp_digit t2;
  16680. sp_int128 p[4];
  16681. int i;
  16682. for (i = 0; i < 36; i += 4) {
  16683. p[0] = tb * a[i + 0];
  16684. p[1] = tb * a[i + 1];
  16685. p[2] = tb * a[i + 2];
  16686. p[3] = tb * a[i + 3];
  16687. t += p[0];
  16688. t2 = (sp_digit)(t & 0x1fffffffffffffL);
  16689. t >>= 53;
  16690. r[i + 0] = (sp_digit)t2;
  16691. t += p[1];
  16692. t2 = (sp_digit)(t & 0x1fffffffffffffL);
  16693. t >>= 53;
  16694. r[i + 1] = (sp_digit)t2;
  16695. t += p[2];
  16696. t2 = (sp_digit)(t & 0x1fffffffffffffL);
  16697. t >>= 53;
  16698. r[i + 2] = (sp_digit)t2;
  16699. t += p[3];
  16700. t2 = (sp_digit)(t & 0x1fffffffffffffL);
  16701. t >>= 53;
  16702. r[i + 3] = (sp_digit)t2;
  16703. }
  16704. t += tb * a[36];
  16705. r[36] = (sp_digit)(t & 0x1fffffffffffffL);
  16706. t >>= 53;
  16707. t += tb * a[37];
  16708. r[37] = (sp_digit)(t & 0x1fffffffffffffL);
  16709. t >>= 53;
  16710. t += tb * a[38];
  16711. r[38] = (sp_digit)(t & 0x1fffffffffffffL);
  16712. t >>= 53;
  16713. r[39] = (sp_digit)(t & 0x1fffffffffffffL);
  16714. }
  16715. #ifndef WOLFSSL_SP_SMALL
  16716. /* Conditionally add a and b using the mask m.
  16717. * m is -1 to add and 0 when not.
  16718. *
  16719. * r A single precision number representing conditional add result.
  16720. * a A single precision number to add with.
  16721. * b A single precision number to add.
  16722. * m Mask value to apply.
  16723. */
  16724. static void sp_4096_cond_add_39(sp_digit* r, const sp_digit* a,
  16725. const sp_digit* b, const sp_digit m)
  16726. {
  16727. int i;
  16728. for (i = 0; i < 32; i += 8) {
  16729. r[i + 0] = a[i + 0] + (b[i + 0] & m);
  16730. r[i + 1] = a[i + 1] + (b[i + 1] & m);
  16731. r[i + 2] = a[i + 2] + (b[i + 2] & m);
  16732. r[i + 3] = a[i + 3] + (b[i + 3] & m);
  16733. r[i + 4] = a[i + 4] + (b[i + 4] & m);
  16734. r[i + 5] = a[i + 5] + (b[i + 5] & m);
  16735. r[i + 6] = a[i + 6] + (b[i + 6] & m);
  16736. r[i + 7] = a[i + 7] + (b[i + 7] & m);
  16737. }
  16738. r[32] = a[32] + (b[32] & m);
  16739. r[33] = a[33] + (b[33] & m);
  16740. r[34] = a[34] + (b[34] & m);
  16741. r[35] = a[35] + (b[35] & m);
  16742. r[36] = a[36] + (b[36] & m);
  16743. r[37] = a[37] + (b[37] & m);
  16744. r[38] = a[38] + (b[38] & m);
  16745. }
  16746. #endif /* !WOLFSSL_SP_SMALL */
  16747. SP_NOINLINE static void sp_4096_rshift_39(sp_digit* r, const sp_digit* a,
  16748. byte n)
  16749. {
  16750. int i;
  16751. for (i=0; i<32; i += 8) {
  16752. r[i+0] = (a[i+0] >> n) | ((a[i+1] << (53 - n)) & 0x1fffffffffffffL);
  16753. r[i+1] = (a[i+1] >> n) | ((a[i+2] << (53 - n)) & 0x1fffffffffffffL);
  16754. r[i+2] = (a[i+2] >> n) | ((a[i+3] << (53 - n)) & 0x1fffffffffffffL);
  16755. r[i+3] = (a[i+3] >> n) | ((a[i+4] << (53 - n)) & 0x1fffffffffffffL);
  16756. r[i+4] = (a[i+4] >> n) | ((a[i+5] << (53 - n)) & 0x1fffffffffffffL);
  16757. r[i+5] = (a[i+5] >> n) | ((a[i+6] << (53 - n)) & 0x1fffffffffffffL);
  16758. r[i+6] = (a[i+6] >> n) | ((a[i+7] << (53 - n)) & 0x1fffffffffffffL);
  16759. r[i+7] = (a[i+7] >> n) | ((a[i+8] << (53 - n)) & 0x1fffffffffffffL);
  16760. }
  16761. r[32] = (a[32] >> n) | ((a[33] << (53 - n)) & 0x1fffffffffffffL);
  16762. r[33] = (a[33] >> n) | ((a[34] << (53 - n)) & 0x1fffffffffffffL);
  16763. r[34] = (a[34] >> n) | ((a[35] << (53 - n)) & 0x1fffffffffffffL);
  16764. r[35] = (a[35] >> n) | ((a[36] << (53 - n)) & 0x1fffffffffffffL);
  16765. r[36] = (a[36] >> n) | ((a[37] << (53 - n)) & 0x1fffffffffffffL);
  16766. r[37] = (a[37] >> n) | ((a[38] << (53 - n)) & 0x1fffffffffffffL);
  16767. r[38] = a[38] >> n;
  16768. }
  16769. static WC_INLINE sp_digit sp_4096_div_word_39(sp_digit d1, sp_digit d0,
  16770. sp_digit div)
  16771. {
  16772. #ifdef SP_USE_DIVTI3
  16773. sp_int128 d = ((sp_int128)d1 << 53) + d0;
  16774. return d / div;
  16775. #elif defined(__x86_64__) || defined(__i386__)
  16776. sp_int128 d = ((sp_int128)d1 << 53) + d0;
  16777. sp_uint64 lo = (sp_uint64)d;
  16778. sp_digit hi = (sp_digit)(d >> 64);
  16779. __asm__ __volatile__ (
  16780. "idiv %2"
  16781. : "+a" (lo)
  16782. : "d" (hi), "r" (div)
  16783. : "cc"
  16784. );
  16785. return (sp_digit)lo;
  16786. #elif !defined(__aarch64__) && !defined(SP_DIV_WORD_USE_DIV)
  16787. sp_int128 d = ((sp_int128)d1 << 53) + d0;
  16788. sp_digit dv = (div >> 1) + 1;
  16789. sp_digit t1 = (sp_digit)(d >> 53);
  16790. sp_digit t0 = (sp_digit)(d & 0x1fffffffffffffL);
  16791. sp_digit t2;
  16792. sp_digit sign;
  16793. sp_digit r;
  16794. int i;
  16795. sp_int128 m;
  16796. r = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  16797. t1 -= dv & (0 - r);
  16798. for (i = 51; i >= 1; i--) {
  16799. t1 += t1 + (((sp_uint64)t0 >> 52) & 1);
  16800. t0 <<= 1;
  16801. t2 = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  16802. r += r + t2;
  16803. t1 -= dv & (0 - t2);
  16804. t1 += t2;
  16805. }
  16806. r += r + 1;
  16807. m = d - ((sp_int128)r * div);
  16808. r += (sp_digit)(m >> 53);
  16809. m = d - ((sp_int128)r * div);
  16810. r += (sp_digit)(m >> 106) - (sp_digit)(d >> 106);
  16811. m = d - ((sp_int128)r * div);
  16812. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  16813. m *= sign;
  16814. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  16815. r += sign * t2;
  16816. m = d - ((sp_int128)r * div);
  16817. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  16818. m *= sign;
  16819. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  16820. r += sign * t2;
  16821. return r;
  16822. #else
  16823. sp_int128 d = ((sp_int128)d1 << 53) + d0;
  16824. sp_digit r = 0;
  16825. sp_digit t;
  16826. sp_digit dv = (div >> 22) + 1;
  16827. t = (sp_digit)(d >> 44);
  16828. t = (t / dv) << 22;
  16829. r += t;
  16830. d -= (sp_int128)t * div;
  16831. t = (sp_digit)(d >> 13);
  16832. t = t / (dv << 9);
  16833. r += t;
  16834. d -= (sp_int128)t * div;
  16835. t = (sp_digit)d;
  16836. t = t / div;
  16837. r += t;
  16838. d -= (sp_int128)t * div;
  16839. return r;
  16840. #endif
  16841. }
  16842. static WC_INLINE sp_digit sp_4096_word_div_word_39(sp_digit d, sp_digit div)
  16843. {
  16844. #if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \
  16845. defined(SP_DIV_WORD_USE_DIV)
  16846. return d / div;
  16847. #else
  16848. return (sp_digit)((sp_uint64)(div - d) >> 63);
  16849. #endif
  16850. }
  16851. /* Divide d in a and put remainder into r (m*d + r = a)
  16852. * m is not calculated as it is not needed at this time.
  16853. *
  16854. * Full implementation.
  16855. *
  16856. * a Number to be divided.
  16857. * d Number to divide with.
  16858. * m Multiplier result.
  16859. * r Remainder from the division.
  16860. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  16861. */
  16862. static int sp_4096_div_39(const sp_digit* a, const sp_digit* d,
  16863. const sp_digit* m, sp_digit* r)
  16864. {
  16865. int i;
  16866. #ifndef WOLFSSL_SP_DIV_64
  16867. #endif
  16868. sp_digit dv;
  16869. sp_digit r1;
  16870. #ifdef WOLFSSL_SP_SMALL_STACK
  16871. sp_digit* t1 = NULL;
  16872. #else
  16873. sp_digit t1[4 * 39 + 3];
  16874. #endif
  16875. sp_digit* t2 = NULL;
  16876. sp_digit* sd = NULL;
  16877. int err = MP_OKAY;
  16878. (void)m;
  16879. #ifdef WOLFSSL_SP_SMALL_STACK
  16880. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 39 + 3), NULL,
  16881. DYNAMIC_TYPE_TMP_BUFFER);
  16882. if (t1 == NULL)
  16883. err = MEMORY_E;
  16884. #endif
  16885. (void)m;
  16886. if (err == MP_OKAY) {
  16887. t2 = t1 + 78 + 1;
  16888. sd = t2 + 39 + 1;
  16889. sp_4096_mul_d_39(sd, d, (sp_digit)1 << 19);
  16890. sp_4096_mul_d_78(t1, a, (sp_digit)1 << 19);
  16891. dv = sd[38];
  16892. t1[39 + 39] += t1[39 + 39 - 1] >> 53;
  16893. t1[39 + 39 - 1] &= 0x1fffffffffffffL;
  16894. for (i=39; i>=0; i--) {
  16895. r1 = sp_4096_div_word_39(t1[39 + i], t1[39 + i - 1], dv);
  16896. sp_4096_mul_d_39(t2, sd, r1);
  16897. (void)sp_4096_sub_39(&t1[i], &t1[i], t2);
  16898. sp_4096_norm_39(&t1[i]);
  16899. t1[39 + i] -= t2[39];
  16900. t1[39 + i] += t1[39 + i - 1] >> 53;
  16901. t1[39 + i - 1] &= 0x1fffffffffffffL;
  16902. r1 = sp_4096_div_word_39(-t1[39 + i], -t1[39 + i - 1], dv);
  16903. r1 -= t1[39 + i];
  16904. sp_4096_mul_d_39(t2, sd, r1);
  16905. (void)sp_4096_add_39(&t1[i], &t1[i], t2);
  16906. t1[39 + i] += t1[39 + i - 1] >> 53;
  16907. t1[39 + i - 1] &= 0x1fffffffffffffL;
  16908. }
  16909. t1[39 - 1] += t1[39 - 2] >> 53;
  16910. t1[39 - 2] &= 0x1fffffffffffffL;
  16911. r1 = sp_4096_word_div_word_39(t1[39 - 1], dv);
  16912. sp_4096_mul_d_39(t2, sd, r1);
  16913. sp_4096_sub_39(t1, t1, t2);
  16914. XMEMCPY(r, t1, sizeof(*r) * 78U);
  16915. for (i=0; i<38; i++) {
  16916. r[i+1] += r[i] >> 53;
  16917. r[i] &= 0x1fffffffffffffL;
  16918. }
  16919. sp_4096_cond_add_39(r, r, sd, r[38] >> 63);
  16920. sp_4096_norm_39(r);
  16921. sp_4096_rshift_39(r, r, 19);
  16922. }
  16923. #ifdef WOLFSSL_SP_SMALL_STACK
  16924. if (t1 != NULL)
  16925. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  16926. #endif
  16927. return err;
  16928. }
  16929. /* Reduce a modulo m into r. (r = a mod m)
  16930. *
  16931. * r A single precision number that is the reduced result.
  16932. * a A single precision number that is to be reduced.
  16933. * m A single precision number that is the modulus to reduce with.
  16934. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  16935. */
  16936. static int sp_4096_mod_39(sp_digit* r, const sp_digit* a, const sp_digit* m)
  16937. {
  16938. return sp_4096_div_39(a, m, NULL, r);
  16939. }
  16940. /* Modular exponentiate a to the e mod m. (r = a^e mod m)
  16941. *
  16942. * r A single precision number that is the result of the operation.
  16943. * a A single precision number being exponentiated.
  16944. * e A single precision number that is the exponent.
  16945. * bits The number of bits in the exponent.
  16946. * m A single precision number that is the modulus.
  16947. * returns 0 on success.
  16948. * returns MEMORY_E on dynamic memory allocation failure.
  16949. * returns MP_VAL when base is even or exponent is 0.
  16950. */
  16951. static int sp_4096_mod_exp_39(sp_digit* r, const sp_digit* a, const sp_digit* e,
  16952. int bits, const sp_digit* m, int reduceA)
  16953. {
  16954. #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
  16955. #ifdef WOLFSSL_SP_SMALL_STACK
  16956. sp_digit* td = NULL;
  16957. #else
  16958. sp_digit td[3 * 78];
  16959. #endif
  16960. sp_digit* t[3] = {0, 0, 0};
  16961. sp_digit* norm = NULL;
  16962. sp_digit mp = 1;
  16963. sp_digit n;
  16964. int i;
  16965. int c;
  16966. byte y;
  16967. int err = MP_OKAY;
  16968. if (bits == 0) {
  16969. err = MP_VAL;
  16970. }
  16971. #ifdef WOLFSSL_SP_SMALL_STACK
  16972. if (err == MP_OKAY) {
  16973. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 39 * 2, NULL,
  16974. DYNAMIC_TYPE_TMP_BUFFER);
  16975. if (td == NULL)
  16976. err = MEMORY_E;
  16977. }
  16978. #endif
  16979. if (err == MP_OKAY) {
  16980. norm = td;
  16981. for (i=0; i<3; i++) {
  16982. t[i] = td + (i * 39 * 2);
  16983. XMEMSET(t[i], 0, sizeof(sp_digit) * 39U * 2U);
  16984. }
  16985. sp_4096_mont_setup(m, &mp);
  16986. sp_4096_mont_norm_39(norm, m);
  16987. if (reduceA != 0) {
  16988. err = sp_4096_mod_39(t[1], a, m);
  16989. }
  16990. else {
  16991. XMEMCPY(t[1], a, sizeof(sp_digit) * 39U);
  16992. }
  16993. }
  16994. if (err == MP_OKAY) {
  16995. sp_4096_mul_39(t[1], t[1], norm);
  16996. err = sp_4096_mod_39(t[1], t[1], m);
  16997. }
  16998. if (err == MP_OKAY) {
  16999. i = bits / 53;
  17000. c = bits % 53;
  17001. n = e[i--] << (53 - c);
  17002. for (; ; c--) {
  17003. if (c == 0) {
  17004. if (i == -1) {
  17005. break;
  17006. }
  17007. n = e[i--];
  17008. c = 53;
  17009. }
  17010. y = (int)((n >> 52) & 1);
  17011. n <<= 1;
  17012. sp_4096_mont_mul_39(t[y^1], t[0], t[1], m, mp);
  17013. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  17014. ((size_t)t[1] & addr_mask[y])),
  17015. sizeof(*t[2]) * 39 * 2);
  17016. sp_4096_mont_sqr_39(t[2], t[2], m, mp);
  17017. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  17018. ((size_t)t[1] & addr_mask[y])), t[2],
  17019. sizeof(*t[2]) * 39 * 2);
  17020. }
  17021. sp_4096_mont_reduce_39(t[0], m, mp);
  17022. n = sp_4096_cmp_39(t[0], m);
  17023. sp_4096_cond_sub_39(t[0], t[0], m, ~(n >> 63));
  17024. XMEMCPY(r, t[0], sizeof(*r) * 39 * 2);
  17025. }
  17026. #ifdef WOLFSSL_SP_SMALL_STACK
  17027. if (td != NULL)
  17028. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  17029. #endif
  17030. return err;
  17031. #elif !defined(WC_NO_CACHE_RESISTANT)
  17032. #ifdef WOLFSSL_SP_SMALL_STACK
  17033. sp_digit* td = NULL;
  17034. #else
  17035. sp_digit td[3 * 78];
  17036. #endif
  17037. sp_digit* t[3] = {0, 0, 0};
  17038. sp_digit* norm = NULL;
  17039. sp_digit mp = 1;
  17040. sp_digit n;
  17041. int i;
  17042. int c;
  17043. byte y;
  17044. int err = MP_OKAY;
  17045. if (bits == 0) {
  17046. err = MP_VAL;
  17047. }
  17048. #ifdef WOLFSSL_SP_SMALL_STACK
  17049. if (err == MP_OKAY) {
  17050. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 39 * 2, NULL,
  17051. DYNAMIC_TYPE_TMP_BUFFER);
  17052. if (td == NULL)
  17053. err = MEMORY_E;
  17054. }
  17055. #endif
  17056. if (err == MP_OKAY) {
  17057. norm = td;
  17058. for (i=0; i<3; i++) {
  17059. t[i] = td + (i * 39 * 2);
  17060. }
  17061. sp_4096_mont_setup(m, &mp);
  17062. sp_4096_mont_norm_39(norm, m);
  17063. if (reduceA != 0) {
  17064. err = sp_4096_mod_39(t[1], a, m);
  17065. if (err == MP_OKAY) {
  17066. sp_4096_mul_39(t[1], t[1], norm);
  17067. err = sp_4096_mod_39(t[1], t[1], m);
  17068. }
  17069. }
  17070. else {
  17071. sp_4096_mul_39(t[1], a, norm);
  17072. err = sp_4096_mod_39(t[1], t[1], m);
  17073. }
  17074. }
  17075. if (err == MP_OKAY) {
  17076. i = bits / 53;
  17077. c = bits % 53;
  17078. n = e[i--] << (53 - c);
  17079. for (; ; c--) {
  17080. if (c == 0) {
  17081. if (i == -1) {
  17082. break;
  17083. }
  17084. n = e[i--];
  17085. c = 53;
  17086. }
  17087. y = (int)((n >> 52) & 1);
  17088. n <<= 1;
  17089. sp_4096_mont_mul_39(t[y^1], t[0], t[1], m, mp);
  17090. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  17091. ((size_t)t[1] & addr_mask[y])),
  17092. sizeof(*t[2]) * 39 * 2);
  17093. sp_4096_mont_sqr_39(t[2], t[2], m, mp);
  17094. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  17095. ((size_t)t[1] & addr_mask[y])), t[2],
  17096. sizeof(*t[2]) * 39 * 2);
  17097. }
  17098. sp_4096_mont_reduce_39(t[0], m, mp);
  17099. n = sp_4096_cmp_39(t[0], m);
  17100. sp_4096_cond_sub_39(t[0], t[0], m, ~(n >> 63));
  17101. XMEMCPY(r, t[0], sizeof(*r) * 39 * 2);
  17102. }
  17103. #ifdef WOLFSSL_SP_SMALL_STACK
  17104. if (td != NULL)
  17105. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  17106. #endif
  17107. return err;
  17108. #else
  17109. #ifdef WOLFSSL_SP_SMALL_STACK
  17110. sp_digit* td = NULL;
  17111. #else
  17112. sp_digit td[(32 * 78) + 78];
  17113. #endif
  17114. sp_digit* t[32];
  17115. sp_digit* rt = NULL;
  17116. sp_digit* norm = NULL;
  17117. sp_digit mp = 1;
  17118. sp_digit n;
  17119. int i;
  17120. int c;
  17121. byte y;
  17122. int err = MP_OKAY;
  17123. if (bits == 0) {
  17124. err = MP_VAL;
  17125. }
  17126. #ifdef WOLFSSL_SP_SMALL_STACK
  17127. if (err == MP_OKAY) {
  17128. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((32 * 78) + 78), NULL,
  17129. DYNAMIC_TYPE_TMP_BUFFER);
  17130. if (td == NULL)
  17131. err = MEMORY_E;
  17132. }
  17133. #endif
  17134. if (err == MP_OKAY) {
  17135. norm = td;
  17136. for (i=0; i<32; i++)
  17137. t[i] = td + i * 78;
  17138. rt = td + 2496;
  17139. sp_4096_mont_setup(m, &mp);
  17140. sp_4096_mont_norm_39(norm, m);
  17141. if (reduceA != 0) {
  17142. err = sp_4096_mod_39(t[1], a, m);
  17143. if (err == MP_OKAY) {
  17144. sp_4096_mul_39(t[1], t[1], norm);
  17145. err = sp_4096_mod_39(t[1], t[1], m);
  17146. }
  17147. }
  17148. else {
  17149. sp_4096_mul_39(t[1], a, norm);
  17150. err = sp_4096_mod_39(t[1], t[1], m);
  17151. }
  17152. }
  17153. if (err == MP_OKAY) {
  17154. sp_4096_mont_sqr_39(t[ 2], t[ 1], m, mp);
  17155. sp_4096_mont_mul_39(t[ 3], t[ 2], t[ 1], m, mp);
  17156. sp_4096_mont_sqr_39(t[ 4], t[ 2], m, mp);
  17157. sp_4096_mont_mul_39(t[ 5], t[ 3], t[ 2], m, mp);
  17158. sp_4096_mont_sqr_39(t[ 6], t[ 3], m, mp);
  17159. sp_4096_mont_mul_39(t[ 7], t[ 4], t[ 3], m, mp);
  17160. sp_4096_mont_sqr_39(t[ 8], t[ 4], m, mp);
  17161. sp_4096_mont_mul_39(t[ 9], t[ 5], t[ 4], m, mp);
  17162. sp_4096_mont_sqr_39(t[10], t[ 5], m, mp);
  17163. sp_4096_mont_mul_39(t[11], t[ 6], t[ 5], m, mp);
  17164. sp_4096_mont_sqr_39(t[12], t[ 6], m, mp);
  17165. sp_4096_mont_mul_39(t[13], t[ 7], t[ 6], m, mp);
  17166. sp_4096_mont_sqr_39(t[14], t[ 7], m, mp);
  17167. sp_4096_mont_mul_39(t[15], t[ 8], t[ 7], m, mp);
  17168. sp_4096_mont_sqr_39(t[16], t[ 8], m, mp);
  17169. sp_4096_mont_mul_39(t[17], t[ 9], t[ 8], m, mp);
  17170. sp_4096_mont_sqr_39(t[18], t[ 9], m, mp);
  17171. sp_4096_mont_mul_39(t[19], t[10], t[ 9], m, mp);
  17172. sp_4096_mont_sqr_39(t[20], t[10], m, mp);
  17173. sp_4096_mont_mul_39(t[21], t[11], t[10], m, mp);
  17174. sp_4096_mont_sqr_39(t[22], t[11], m, mp);
  17175. sp_4096_mont_mul_39(t[23], t[12], t[11], m, mp);
  17176. sp_4096_mont_sqr_39(t[24], t[12], m, mp);
  17177. sp_4096_mont_mul_39(t[25], t[13], t[12], m, mp);
  17178. sp_4096_mont_sqr_39(t[26], t[13], m, mp);
  17179. sp_4096_mont_mul_39(t[27], t[14], t[13], m, mp);
  17180. sp_4096_mont_sqr_39(t[28], t[14], m, mp);
  17181. sp_4096_mont_mul_39(t[29], t[15], t[14], m, mp);
  17182. sp_4096_mont_sqr_39(t[30], t[15], m, mp);
  17183. sp_4096_mont_mul_39(t[31], t[16], t[15], m, mp);
  17184. bits = ((bits + 4) / 5) * 5;
  17185. i = ((bits + 52) / 53) - 1;
  17186. c = bits % 53;
  17187. if (c == 0) {
  17188. c = 53;
  17189. }
  17190. if (i < 39) {
  17191. n = e[i--] << (64 - c);
  17192. }
  17193. else {
  17194. n = 0;
  17195. i--;
  17196. }
  17197. if (c < 5) {
  17198. n |= e[i--] << (11 - c);
  17199. c += 53;
  17200. }
  17201. y = (int)((n >> 59) & 0x1f);
  17202. n <<= 5;
  17203. c -= 5;
  17204. XMEMCPY(rt, t[y], sizeof(sp_digit) * 78);
  17205. while ((i >= 0) || (c >= 5)) {
  17206. if (c >= 5) {
  17207. y = (byte)((n >> 59) & 0x1f);
  17208. n <<= 5;
  17209. c -= 5;
  17210. }
  17211. else if (c == 0) {
  17212. n = e[i--] << 11;
  17213. y = (byte)((n >> 59) & 0x1f);
  17214. n <<= 5;
  17215. c = 48;
  17216. }
  17217. else {
  17218. y = (byte)((n >> 59) & 0x1f);
  17219. n = e[i--] << 11;
  17220. c = 5 - c;
  17221. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  17222. n <<= c;
  17223. c = 53 - c;
  17224. }
  17225. sp_4096_mont_sqr_39(rt, rt, m, mp);
  17226. sp_4096_mont_sqr_39(rt, rt, m, mp);
  17227. sp_4096_mont_sqr_39(rt, rt, m, mp);
  17228. sp_4096_mont_sqr_39(rt, rt, m, mp);
  17229. sp_4096_mont_sqr_39(rt, rt, m, mp);
  17230. sp_4096_mont_mul_39(rt, rt, t[y], m, mp);
  17231. }
  17232. sp_4096_mont_reduce_39(rt, m, mp);
  17233. n = sp_4096_cmp_39(rt, m);
  17234. sp_4096_cond_sub_39(rt, rt, m, ~(n >> 63));
  17235. XMEMCPY(r, rt, sizeof(sp_digit) * 78);
  17236. }
  17237. #ifdef WOLFSSL_SP_SMALL_STACK
  17238. if (td != NULL)
  17239. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  17240. #endif
  17241. return err;
  17242. #endif
  17243. }
  17244. #endif /* WOLFSSL_HAVE_SP_RSA & !SP_RSA_PRIVATE_EXP_D */
  17245. #endif /* (WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH) & !WOLFSSL_RSA_PUBLIC_ONLY */
  17246. /* r = 2^n mod m where n is the number of bits to reduce by.
  17247. * Given m must be 4096 bits, just need to subtract.
  17248. *
  17249. * r A single precision number.
  17250. * m A single precision number.
  17251. */
  17252. static void sp_4096_mont_norm_78(sp_digit* r, const sp_digit* m)
  17253. {
  17254. /* Set r = 2^n - 1. */
  17255. int i;
  17256. for (i = 0; i < 72; i += 8) {
  17257. r[i + 0] = 0x1fffffffffffffL;
  17258. r[i + 1] = 0x1fffffffffffffL;
  17259. r[i + 2] = 0x1fffffffffffffL;
  17260. r[i + 3] = 0x1fffffffffffffL;
  17261. r[i + 4] = 0x1fffffffffffffL;
  17262. r[i + 5] = 0x1fffffffffffffL;
  17263. r[i + 6] = 0x1fffffffffffffL;
  17264. r[i + 7] = 0x1fffffffffffffL;
  17265. }
  17266. r[72] = 0x1fffffffffffffL;
  17267. r[73] = 0x1fffffffffffffL;
  17268. r[74] = 0x1fffffffffffffL;
  17269. r[75] = 0x1fffffffffffffL;
  17270. r[76] = 0x1fffffffffffffL;
  17271. r[77] = 0x7fffL;
  17272. /* r = (2^n - 1) mod n */
  17273. (void)sp_4096_sub_78(r, r, m);
  17274. /* Add one so r = 2^n mod m */
  17275. r[0] += 1;
  17276. }
  17277. /* Compare a with b in constant time.
  17278. *
  17279. * a A single precision integer.
  17280. * b A single precision integer.
  17281. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  17282. * respectively.
  17283. */
  17284. static sp_digit sp_4096_cmp_78(const sp_digit* a, const sp_digit* b)
  17285. {
  17286. sp_digit r = 0;
  17287. int i;
  17288. r |= (a[77] - b[77]) & (0 - (sp_digit)1);
  17289. r |= (a[76] - b[76]) & ~(((sp_digit)0 - r) >> 52);
  17290. r |= (a[75] - b[75]) & ~(((sp_digit)0 - r) >> 52);
  17291. r |= (a[74] - b[74]) & ~(((sp_digit)0 - r) >> 52);
  17292. r |= (a[73] - b[73]) & ~(((sp_digit)0 - r) >> 52);
  17293. r |= (a[72] - b[72]) & ~(((sp_digit)0 - r) >> 52);
  17294. for (i = 64; i >= 0; i -= 8) {
  17295. r |= (a[i + 7] - b[i + 7]) & ~(((sp_digit)0 - r) >> 52);
  17296. r |= (a[i + 6] - b[i + 6]) & ~(((sp_digit)0 - r) >> 52);
  17297. r |= (a[i + 5] - b[i + 5]) & ~(((sp_digit)0 - r) >> 52);
  17298. r |= (a[i + 4] - b[i + 4]) & ~(((sp_digit)0 - r) >> 52);
  17299. r |= (a[i + 3] - b[i + 3]) & ~(((sp_digit)0 - r) >> 52);
  17300. r |= (a[i + 2] - b[i + 2]) & ~(((sp_digit)0 - r) >> 52);
  17301. r |= (a[i + 1] - b[i + 1]) & ~(((sp_digit)0 - r) >> 52);
  17302. r |= (a[i + 0] - b[i + 0]) & ~(((sp_digit)0 - r) >> 52);
  17303. }
  17304. return r;
  17305. }
  17306. /* Conditionally subtract b from a using the mask m.
  17307. * m is -1 to subtract and 0 when not.
  17308. *
  17309. * r A single precision number representing condition subtract result.
  17310. * a A single precision number to subtract from.
  17311. * b A single precision number to subtract.
  17312. * m Mask value to apply.
  17313. */
  17314. static void sp_4096_cond_sub_78(sp_digit* r, const sp_digit* a,
  17315. const sp_digit* b, const sp_digit m)
  17316. {
  17317. int i;
  17318. for (i = 0; i < 72; i += 8) {
  17319. r[i + 0] = a[i + 0] - (b[i + 0] & m);
  17320. r[i + 1] = a[i + 1] - (b[i + 1] & m);
  17321. r[i + 2] = a[i + 2] - (b[i + 2] & m);
  17322. r[i + 3] = a[i + 3] - (b[i + 3] & m);
  17323. r[i + 4] = a[i + 4] - (b[i + 4] & m);
  17324. r[i + 5] = a[i + 5] - (b[i + 5] & m);
  17325. r[i + 6] = a[i + 6] - (b[i + 6] & m);
  17326. r[i + 7] = a[i + 7] - (b[i + 7] & m);
  17327. }
  17328. r[72] = a[72] - (b[72] & m);
  17329. r[73] = a[73] - (b[73] & m);
  17330. r[74] = a[74] - (b[74] & m);
  17331. r[75] = a[75] - (b[75] & m);
  17332. r[76] = a[76] - (b[76] & m);
  17333. r[77] = a[77] - (b[77] & m);
  17334. }
  17335. /* Mul a by scalar b and add into r. (r += a * b)
  17336. *
  17337. * r A single precision integer.
  17338. * a A single precision integer.
  17339. * b A scalar.
  17340. */
  17341. SP_NOINLINE static void sp_4096_mul_add_78(sp_digit* r, const sp_digit* a,
  17342. const sp_digit b)
  17343. {
  17344. sp_int128 tb = b;
  17345. sp_int128 t[8];
  17346. int i;
  17347. t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1fffffffffffffL);
  17348. for (i = 0; i < 72; i += 8) {
  17349. t[1] = tb * a[i+1];
  17350. r[i+1] += (sp_digit)((t[0] >> 53) + (t[1] & 0x1fffffffffffffL));
  17351. t[2] = tb * a[i+2];
  17352. r[i+2] += (sp_digit)((t[1] >> 53) + (t[2] & 0x1fffffffffffffL));
  17353. t[3] = tb * a[i+3];
  17354. r[i+3] += (sp_digit)((t[2] >> 53) + (t[3] & 0x1fffffffffffffL));
  17355. t[4] = tb * a[i+4];
  17356. r[i+4] += (sp_digit)((t[3] >> 53) + (t[4] & 0x1fffffffffffffL));
  17357. t[5] = tb * a[i+5];
  17358. r[i+5] += (sp_digit)((t[4] >> 53) + (t[5] & 0x1fffffffffffffL));
  17359. t[6] = tb * a[i+6];
  17360. r[i+6] += (sp_digit)((t[5] >> 53) + (t[6] & 0x1fffffffffffffL));
  17361. t[7] = tb * a[i+7];
  17362. r[i+7] += (sp_digit)((t[6] >> 53) + (t[7] & 0x1fffffffffffffL));
  17363. t[0] = tb * a[i+8];
  17364. r[i+8] += (sp_digit)((t[7] >> 53) + (t[0] & 0x1fffffffffffffL));
  17365. }
  17366. t[1] = tb * a[73];
  17367. r[73] += (sp_digit)((t[0] >> 53) + (t[1] & 0x1fffffffffffffL));
  17368. t[2] = tb * a[74];
  17369. r[74] += (sp_digit)((t[1] >> 53) + (t[2] & 0x1fffffffffffffL));
  17370. t[3] = tb * a[75];
  17371. r[75] += (sp_digit)((t[2] >> 53) + (t[3] & 0x1fffffffffffffL));
  17372. t[4] = tb * a[76];
  17373. r[76] += (sp_digit)((t[3] >> 53) + (t[4] & 0x1fffffffffffffL));
  17374. t[5] = tb * a[77];
  17375. r[77] += (sp_digit)((t[4] >> 53) + (t[5] & 0x1fffffffffffffL));
  17376. r[78] += (sp_digit)(t[5] >> 53);
  17377. }
  17378. /* Shift the result in the high 4096 bits down to the bottom.
  17379. *
  17380. * r A single precision number.
  17381. * a A single precision number.
  17382. */
  17383. static void sp_4096_mont_shift_78(sp_digit* r, const sp_digit* a)
  17384. {
  17385. int i;
  17386. sp_int128 n = a[77] >> 15;
  17387. n += ((sp_int128)a[78]) << 38;
  17388. for (i = 0; i < 72; i += 8) {
  17389. r[i + 0] = n & 0x1fffffffffffffL;
  17390. n >>= 53; n += ((sp_int128)a[i + 79]) << 38;
  17391. r[i + 1] = n & 0x1fffffffffffffL;
  17392. n >>= 53; n += ((sp_int128)a[i + 80]) << 38;
  17393. r[i + 2] = n & 0x1fffffffffffffL;
  17394. n >>= 53; n += ((sp_int128)a[i + 81]) << 38;
  17395. r[i + 3] = n & 0x1fffffffffffffL;
  17396. n >>= 53; n += ((sp_int128)a[i + 82]) << 38;
  17397. r[i + 4] = n & 0x1fffffffffffffL;
  17398. n >>= 53; n += ((sp_int128)a[i + 83]) << 38;
  17399. r[i + 5] = n & 0x1fffffffffffffL;
  17400. n >>= 53; n += ((sp_int128)a[i + 84]) << 38;
  17401. r[i + 6] = n & 0x1fffffffffffffL;
  17402. n >>= 53; n += ((sp_int128)a[i + 85]) << 38;
  17403. r[i + 7] = n & 0x1fffffffffffffL;
  17404. n >>= 53; n += ((sp_int128)a[i + 86]) << 38;
  17405. }
  17406. r[72] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[151]) << 38;
  17407. r[73] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[152]) << 38;
  17408. r[74] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[153]) << 38;
  17409. r[75] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[154]) << 38;
  17410. r[76] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[155]) << 38;
  17411. r[77] = (sp_digit)n;
  17412. XMEMSET(&r[78], 0, sizeof(*r) * 78U);
  17413. }
  17414. /* Reduce the number back to 4096 bits using Montgomery reduction.
  17415. *
  17416. * a A single precision number to reduce in place.
  17417. * m The single precision number representing the modulus.
  17418. * mp The digit representing the negative inverse of m mod 2^n.
  17419. */
  17420. static void sp_4096_mont_reduce_78(sp_digit* a, const sp_digit* m, sp_digit mp)
  17421. {
  17422. int i;
  17423. sp_digit mu;
  17424. sp_digit over;
  17425. sp_4096_norm_78(a + 78);
  17426. #ifdef WOLFSSL_SP_DH
  17427. if (mp != 1) {
  17428. for (i=0; i<77; i++) {
  17429. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1fffffffffffffL;
  17430. sp_4096_mul_add_78(a+i, m, mu);
  17431. a[i+1] += a[i] >> 53;
  17432. }
  17433. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x7fffL;
  17434. sp_4096_mul_add_78(a+i, m, mu);
  17435. a[i+1] += a[i] >> 53;
  17436. a[i] &= 0x1fffffffffffffL;
  17437. }
  17438. else {
  17439. for (i=0; i<77; i++) {
  17440. mu = a[i] & 0x1fffffffffffffL;
  17441. sp_4096_mul_add_78(a+i, m, mu);
  17442. a[i+1] += a[i] >> 53;
  17443. }
  17444. mu = a[i] & 0x7fffL;
  17445. sp_4096_mul_add_78(a+i, m, mu);
  17446. a[i+1] += a[i] >> 53;
  17447. a[i] &= 0x1fffffffffffffL;
  17448. }
  17449. #else
  17450. for (i=0; i<77; i++) {
  17451. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1fffffffffffffL;
  17452. sp_4096_mul_add_78(a+i, m, mu);
  17453. a[i+1] += a[i] >> 53;
  17454. }
  17455. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x7fffL;
  17456. sp_4096_mul_add_78(a+i, m, mu);
  17457. a[i+1] += a[i] >> 53;
  17458. a[i] &= 0x1fffffffffffffL;
  17459. #endif
  17460. sp_4096_mont_shift_78(a, a);
  17461. over = a[77] - m[77];
  17462. sp_4096_cond_sub_78(a, a, m, ~((over - 1) >> 63));
  17463. sp_4096_norm_78(a);
  17464. }
  17465. /* Multiply two Montgomery form numbers mod the modulus (prime).
  17466. * (r = a * b mod m)
  17467. *
  17468. * r Result of multiplication.
  17469. * a First number to multiply in Montgomery form.
  17470. * b Second number to multiply in Montgomery form.
  17471. * m Modulus (prime).
  17472. * mp Montgomery multiplier.
  17473. */
  17474. SP_NOINLINE static void sp_4096_mont_mul_78(sp_digit* r, const sp_digit* a,
  17475. const sp_digit* b, const sp_digit* m, sp_digit mp)
  17476. {
  17477. sp_4096_mul_78(r, a, b);
  17478. sp_4096_mont_reduce_78(r, m, mp);
  17479. }
  17480. /* Square the Montgomery form number. (r = a * a mod m)
  17481. *
  17482. * r Result of squaring.
  17483. * a Number to square in Montgomery form.
  17484. * m Modulus (prime).
  17485. * mp Montgomery multiplier.
  17486. */
  17487. SP_NOINLINE static void sp_4096_mont_sqr_78(sp_digit* r, const sp_digit* a,
  17488. const sp_digit* m, sp_digit mp)
  17489. {
  17490. sp_4096_sqr_78(r, a);
  17491. sp_4096_mont_reduce_78(r, m, mp);
  17492. }
  17493. /* Multiply a by scalar b into r. (r = a * b)
  17494. *
  17495. * r A single precision integer.
  17496. * a A single precision integer.
  17497. * b A scalar.
  17498. */
  17499. SP_NOINLINE static void sp_4096_mul_d_156(sp_digit* r, const sp_digit* a,
  17500. sp_digit b)
  17501. {
  17502. sp_int128 tb = b;
  17503. sp_int128 t = 0;
  17504. sp_digit t2;
  17505. sp_int128 p[4];
  17506. int i;
  17507. for (i = 0; i < 156; i += 4) {
  17508. p[0] = tb * a[i + 0];
  17509. p[1] = tb * a[i + 1];
  17510. p[2] = tb * a[i + 2];
  17511. p[3] = tb * a[i + 3];
  17512. t += p[0];
  17513. t2 = (sp_digit)(t & 0x1fffffffffffffL);
  17514. t >>= 53;
  17515. r[i + 0] = (sp_digit)t2;
  17516. t += p[1];
  17517. t2 = (sp_digit)(t & 0x1fffffffffffffL);
  17518. t >>= 53;
  17519. r[i + 1] = (sp_digit)t2;
  17520. t += p[2];
  17521. t2 = (sp_digit)(t & 0x1fffffffffffffL);
  17522. t >>= 53;
  17523. r[i + 2] = (sp_digit)t2;
  17524. t += p[3];
  17525. t2 = (sp_digit)(t & 0x1fffffffffffffL);
  17526. t >>= 53;
  17527. r[i + 3] = (sp_digit)t2;
  17528. }
  17529. r[156] = (sp_digit)(t & 0x1fffffffffffffL);
  17530. }
  17531. #ifndef WOLFSSL_SP_SMALL
  17532. /* Conditionally add a and b using the mask m.
  17533. * m is -1 to add and 0 when not.
  17534. *
  17535. * r A single precision number representing conditional add result.
  17536. * a A single precision number to add with.
  17537. * b A single precision number to add.
  17538. * m Mask value to apply.
  17539. */
  17540. static void sp_4096_cond_add_78(sp_digit* r, const sp_digit* a,
  17541. const sp_digit* b, const sp_digit m)
  17542. {
  17543. int i;
  17544. for (i = 0; i < 72; i += 8) {
  17545. r[i + 0] = a[i + 0] + (b[i + 0] & m);
  17546. r[i + 1] = a[i + 1] + (b[i + 1] & m);
  17547. r[i + 2] = a[i + 2] + (b[i + 2] & m);
  17548. r[i + 3] = a[i + 3] + (b[i + 3] & m);
  17549. r[i + 4] = a[i + 4] + (b[i + 4] & m);
  17550. r[i + 5] = a[i + 5] + (b[i + 5] & m);
  17551. r[i + 6] = a[i + 6] + (b[i + 6] & m);
  17552. r[i + 7] = a[i + 7] + (b[i + 7] & m);
  17553. }
  17554. r[72] = a[72] + (b[72] & m);
  17555. r[73] = a[73] + (b[73] & m);
  17556. r[74] = a[74] + (b[74] & m);
  17557. r[75] = a[75] + (b[75] & m);
  17558. r[76] = a[76] + (b[76] & m);
  17559. r[77] = a[77] + (b[77] & m);
  17560. }
  17561. #endif /* !WOLFSSL_SP_SMALL */
  17562. SP_NOINLINE static void sp_4096_rshift_78(sp_digit* r, const sp_digit* a,
  17563. byte n)
  17564. {
  17565. int i;
  17566. for (i=0; i<72; i += 8) {
  17567. r[i+0] = (a[i+0] >> n) | ((a[i+1] << (53 - n)) & 0x1fffffffffffffL);
  17568. r[i+1] = (a[i+1] >> n) | ((a[i+2] << (53 - n)) & 0x1fffffffffffffL);
  17569. r[i+2] = (a[i+2] >> n) | ((a[i+3] << (53 - n)) & 0x1fffffffffffffL);
  17570. r[i+3] = (a[i+3] >> n) | ((a[i+4] << (53 - n)) & 0x1fffffffffffffL);
  17571. r[i+4] = (a[i+4] >> n) | ((a[i+5] << (53 - n)) & 0x1fffffffffffffL);
  17572. r[i+5] = (a[i+5] >> n) | ((a[i+6] << (53 - n)) & 0x1fffffffffffffL);
  17573. r[i+6] = (a[i+6] >> n) | ((a[i+7] << (53 - n)) & 0x1fffffffffffffL);
  17574. r[i+7] = (a[i+7] >> n) | ((a[i+8] << (53 - n)) & 0x1fffffffffffffL);
  17575. }
  17576. r[72] = (a[72] >> n) | ((a[73] << (53 - n)) & 0x1fffffffffffffL);
  17577. r[73] = (a[73] >> n) | ((a[74] << (53 - n)) & 0x1fffffffffffffL);
  17578. r[74] = (a[74] >> n) | ((a[75] << (53 - n)) & 0x1fffffffffffffL);
  17579. r[75] = (a[75] >> n) | ((a[76] << (53 - n)) & 0x1fffffffffffffL);
  17580. r[76] = (a[76] >> n) | ((a[77] << (53 - n)) & 0x1fffffffffffffL);
  17581. r[77] = a[77] >> n;
  17582. }
  17583. static WC_INLINE sp_digit sp_4096_div_word_78(sp_digit d1, sp_digit d0,
  17584. sp_digit div)
  17585. {
  17586. #ifdef SP_USE_DIVTI3
  17587. sp_int128 d = ((sp_int128)d1 << 53) + d0;
  17588. return d / div;
  17589. #elif defined(__x86_64__) || defined(__i386__)
  17590. sp_int128 d = ((sp_int128)d1 << 53) + d0;
  17591. sp_uint64 lo = (sp_uint64)d;
  17592. sp_digit hi = (sp_digit)(d >> 64);
  17593. __asm__ __volatile__ (
  17594. "idiv %2"
  17595. : "+a" (lo)
  17596. : "d" (hi), "r" (div)
  17597. : "cc"
  17598. );
  17599. return (sp_digit)lo;
  17600. #elif !defined(__aarch64__) && !defined(SP_DIV_WORD_USE_DIV)
  17601. sp_int128 d = ((sp_int128)d1 << 53) + d0;
  17602. sp_digit dv = (div >> 1) + 1;
  17603. sp_digit t1 = (sp_digit)(d >> 53);
  17604. sp_digit t0 = (sp_digit)(d & 0x1fffffffffffffL);
  17605. sp_digit t2;
  17606. sp_digit sign;
  17607. sp_digit r;
  17608. int i;
  17609. sp_int128 m;
  17610. r = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  17611. t1 -= dv & (0 - r);
  17612. for (i = 51; i >= 1; i--) {
  17613. t1 += t1 + (((sp_uint64)t0 >> 52) & 1);
  17614. t0 <<= 1;
  17615. t2 = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  17616. r += r + t2;
  17617. t1 -= dv & (0 - t2);
  17618. t1 += t2;
  17619. }
  17620. r += r + 1;
  17621. m = d - ((sp_int128)r * div);
  17622. r += (sp_digit)(m >> 53);
  17623. m = d - ((sp_int128)r * div);
  17624. r += (sp_digit)(m >> 106) - (sp_digit)(d >> 106);
  17625. m = d - ((sp_int128)r * div);
  17626. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  17627. m *= sign;
  17628. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  17629. r += sign * t2;
  17630. m = d - ((sp_int128)r * div);
  17631. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  17632. m *= sign;
  17633. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  17634. r += sign * t2;
  17635. return r;
  17636. #else
  17637. sp_int128 d = ((sp_int128)d1 << 53) + d0;
  17638. sp_digit r = 0;
  17639. sp_digit t;
  17640. sp_digit dv = (div >> 22) + 1;
  17641. t = (sp_digit)(d >> 44);
  17642. t = (t / dv) << 22;
  17643. r += t;
  17644. d -= (sp_int128)t * div;
  17645. t = (sp_digit)(d >> 13);
  17646. t = t / (dv << 9);
  17647. r += t;
  17648. d -= (sp_int128)t * div;
  17649. t = (sp_digit)d;
  17650. t = t / div;
  17651. r += t;
  17652. d -= (sp_int128)t * div;
  17653. return r;
  17654. #endif
  17655. }
  17656. static WC_INLINE sp_digit sp_4096_word_div_word_78(sp_digit d, sp_digit div)
  17657. {
  17658. #if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \
  17659. defined(SP_DIV_WORD_USE_DIV)
  17660. return d / div;
  17661. #else
  17662. return (sp_digit)((sp_uint64)(div - d) >> 63);
  17663. #endif
  17664. }
  17665. /* Divide d in a and put remainder into r (m*d + r = a)
  17666. * m is not calculated as it is not needed at this time.
  17667. *
  17668. * Full implementation.
  17669. *
  17670. * a Number to be divided.
  17671. * d Number to divide with.
  17672. * m Multiplier result.
  17673. * r Remainder from the division.
  17674. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  17675. */
  17676. static int sp_4096_div_78(const sp_digit* a, const sp_digit* d,
  17677. const sp_digit* m, sp_digit* r)
  17678. {
  17679. int i;
  17680. #ifndef WOLFSSL_SP_DIV_64
  17681. #endif
  17682. sp_digit dv;
  17683. sp_digit r1;
  17684. #ifdef WOLFSSL_SP_SMALL_STACK
  17685. sp_digit* t1 = NULL;
  17686. #else
  17687. sp_digit t1[4 * 78 + 3];
  17688. #endif
  17689. sp_digit* t2 = NULL;
  17690. sp_digit* sd = NULL;
  17691. int err = MP_OKAY;
  17692. (void)m;
  17693. #ifdef WOLFSSL_SP_SMALL_STACK
  17694. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 78 + 3), NULL,
  17695. DYNAMIC_TYPE_TMP_BUFFER);
  17696. if (t1 == NULL)
  17697. err = MEMORY_E;
  17698. #endif
  17699. (void)m;
  17700. if (err == MP_OKAY) {
  17701. t2 = t1 + 156 + 1;
  17702. sd = t2 + 78 + 1;
  17703. sp_4096_mul_d_78(sd, d, (sp_digit)1 << 38);
  17704. sp_4096_mul_d_156(t1, a, (sp_digit)1 << 38);
  17705. dv = sd[77];
  17706. t1[78 + 78] += t1[78 + 78 - 1] >> 53;
  17707. t1[78 + 78 - 1] &= 0x1fffffffffffffL;
  17708. for (i=78; i>=0; i--) {
  17709. r1 = sp_4096_div_word_78(t1[78 + i], t1[78 + i - 1], dv);
  17710. sp_4096_mul_d_78(t2, sd, r1);
  17711. (void)sp_4096_sub_78(&t1[i], &t1[i], t2);
  17712. sp_4096_norm_78(&t1[i]);
  17713. t1[78 + i] -= t2[78];
  17714. t1[78 + i] += t1[78 + i - 1] >> 53;
  17715. t1[78 + i - 1] &= 0x1fffffffffffffL;
  17716. r1 = sp_4096_div_word_78(-t1[78 + i], -t1[78 + i - 1], dv);
  17717. r1 -= t1[78 + i];
  17718. sp_4096_mul_d_78(t2, sd, r1);
  17719. (void)sp_4096_add_78(&t1[i], &t1[i], t2);
  17720. t1[78 + i] += t1[78 + i - 1] >> 53;
  17721. t1[78 + i - 1] &= 0x1fffffffffffffL;
  17722. }
  17723. t1[78 - 1] += t1[78 - 2] >> 53;
  17724. t1[78 - 2] &= 0x1fffffffffffffL;
  17725. r1 = sp_4096_word_div_word_78(t1[78 - 1], dv);
  17726. sp_4096_mul_d_78(t2, sd, r1);
  17727. sp_4096_sub_78(t1, t1, t2);
  17728. XMEMCPY(r, t1, sizeof(*r) * 156U);
  17729. for (i=0; i<77; i++) {
  17730. r[i+1] += r[i] >> 53;
  17731. r[i] &= 0x1fffffffffffffL;
  17732. }
  17733. sp_4096_cond_add_78(r, r, sd, r[77] >> 63);
  17734. sp_4096_norm_78(r);
  17735. sp_4096_rshift_78(r, r, 38);
  17736. }
  17737. #ifdef WOLFSSL_SP_SMALL_STACK
  17738. if (t1 != NULL)
  17739. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  17740. #endif
  17741. return err;
  17742. }
  17743. /* Reduce a modulo m into r. (r = a mod m)
  17744. *
  17745. * r A single precision number that is the reduced result.
  17746. * a A single precision number that is to be reduced.
  17747. * m A single precision number that is the modulus to reduce with.
  17748. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  17749. */
  17750. static int sp_4096_mod_78(sp_digit* r, const sp_digit* a, const sp_digit* m)
  17751. {
  17752. return sp_4096_div_78(a, m, NULL, r);
  17753. }
  17754. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
  17755. #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \
  17756. defined(WOLFSSL_HAVE_SP_DH)
  17757. /* Modular exponentiate a to the e mod m. (r = a^e mod m)
  17758. *
  17759. * r A single precision number that is the result of the operation.
  17760. * a A single precision number being exponentiated.
  17761. * e A single precision number that is the exponent.
  17762. * bits The number of bits in the exponent.
  17763. * m A single precision number that is the modulus.
  17764. * returns 0 on success.
  17765. * returns MEMORY_E on dynamic memory allocation failure.
  17766. * returns MP_VAL when base is even or exponent is 0.
  17767. */
  17768. static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, const sp_digit* e,
  17769. int bits, const sp_digit* m, int reduceA)
  17770. {
  17771. #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
  17772. #ifdef WOLFSSL_SP_SMALL_STACK
  17773. sp_digit* td = NULL;
  17774. #else
  17775. sp_digit td[3 * 156];
  17776. #endif
  17777. sp_digit* t[3] = {0, 0, 0};
  17778. sp_digit* norm = NULL;
  17779. sp_digit mp = 1;
  17780. sp_digit n;
  17781. int i;
  17782. int c;
  17783. byte y;
  17784. int err = MP_OKAY;
  17785. if (bits == 0) {
  17786. err = MP_VAL;
  17787. }
  17788. #ifdef WOLFSSL_SP_SMALL_STACK
  17789. if (err == MP_OKAY) {
  17790. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 78 * 2, NULL,
  17791. DYNAMIC_TYPE_TMP_BUFFER);
  17792. if (td == NULL)
  17793. err = MEMORY_E;
  17794. }
  17795. #endif
  17796. if (err == MP_OKAY) {
  17797. norm = td;
  17798. for (i=0; i<3; i++) {
  17799. t[i] = td + (i * 78 * 2);
  17800. XMEMSET(t[i], 0, sizeof(sp_digit) * 78U * 2U);
  17801. }
  17802. sp_4096_mont_setup(m, &mp);
  17803. sp_4096_mont_norm_78(norm, m);
  17804. if (reduceA != 0) {
  17805. err = sp_4096_mod_78(t[1], a, m);
  17806. }
  17807. else {
  17808. XMEMCPY(t[1], a, sizeof(sp_digit) * 78U);
  17809. }
  17810. }
  17811. if (err == MP_OKAY) {
  17812. sp_4096_mul_78(t[1], t[1], norm);
  17813. err = sp_4096_mod_78(t[1], t[1], m);
  17814. }
  17815. if (err == MP_OKAY) {
  17816. i = bits / 53;
  17817. c = bits % 53;
  17818. n = e[i--] << (53 - c);
  17819. for (; ; c--) {
  17820. if (c == 0) {
  17821. if (i == -1) {
  17822. break;
  17823. }
  17824. n = e[i--];
  17825. c = 53;
  17826. }
  17827. y = (int)((n >> 52) & 1);
  17828. n <<= 1;
  17829. sp_4096_mont_mul_78(t[y^1], t[0], t[1], m, mp);
  17830. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  17831. ((size_t)t[1] & addr_mask[y])),
  17832. sizeof(*t[2]) * 78 * 2);
  17833. sp_4096_mont_sqr_78(t[2], t[2], m, mp);
  17834. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  17835. ((size_t)t[1] & addr_mask[y])), t[2],
  17836. sizeof(*t[2]) * 78 * 2);
  17837. }
  17838. sp_4096_mont_reduce_78(t[0], m, mp);
  17839. n = sp_4096_cmp_78(t[0], m);
  17840. sp_4096_cond_sub_78(t[0], t[0], m, ~(n >> 63));
  17841. XMEMCPY(r, t[0], sizeof(*r) * 78 * 2);
  17842. }
  17843. #ifdef WOLFSSL_SP_SMALL_STACK
  17844. if (td != NULL)
  17845. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  17846. #endif
  17847. return err;
  17848. #elif !defined(WC_NO_CACHE_RESISTANT)
  17849. #ifdef WOLFSSL_SP_SMALL_STACK
  17850. sp_digit* td = NULL;
  17851. #else
  17852. sp_digit td[3 * 156];
  17853. #endif
  17854. sp_digit* t[3] = {0, 0, 0};
  17855. sp_digit* norm = NULL;
  17856. sp_digit mp = 1;
  17857. sp_digit n;
  17858. int i;
  17859. int c;
  17860. byte y;
  17861. int err = MP_OKAY;
  17862. if (bits == 0) {
  17863. err = MP_VAL;
  17864. }
  17865. #ifdef WOLFSSL_SP_SMALL_STACK
  17866. if (err == MP_OKAY) {
  17867. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 78 * 2, NULL,
  17868. DYNAMIC_TYPE_TMP_BUFFER);
  17869. if (td == NULL)
  17870. err = MEMORY_E;
  17871. }
  17872. #endif
  17873. if (err == MP_OKAY) {
  17874. norm = td;
  17875. for (i=0; i<3; i++) {
  17876. t[i] = td + (i * 78 * 2);
  17877. }
  17878. sp_4096_mont_setup(m, &mp);
  17879. sp_4096_mont_norm_78(norm, m);
  17880. if (reduceA != 0) {
  17881. err = sp_4096_mod_78(t[1], a, m);
  17882. if (err == MP_OKAY) {
  17883. sp_4096_mul_78(t[1], t[1], norm);
  17884. err = sp_4096_mod_78(t[1], t[1], m);
  17885. }
  17886. }
  17887. else {
  17888. sp_4096_mul_78(t[1], a, norm);
  17889. err = sp_4096_mod_78(t[1], t[1], m);
  17890. }
  17891. }
  17892. if (err == MP_OKAY) {
  17893. i = bits / 53;
  17894. c = bits % 53;
  17895. n = e[i--] << (53 - c);
  17896. for (; ; c--) {
  17897. if (c == 0) {
  17898. if (i == -1) {
  17899. break;
  17900. }
  17901. n = e[i--];
  17902. c = 53;
  17903. }
  17904. y = (int)((n >> 52) & 1);
  17905. n <<= 1;
  17906. sp_4096_mont_mul_78(t[y^1], t[0], t[1], m, mp);
  17907. XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
  17908. ((size_t)t[1] & addr_mask[y])),
  17909. sizeof(*t[2]) * 78 * 2);
  17910. sp_4096_mont_sqr_78(t[2], t[2], m, mp);
  17911. XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
  17912. ((size_t)t[1] & addr_mask[y])), t[2],
  17913. sizeof(*t[2]) * 78 * 2);
  17914. }
  17915. sp_4096_mont_reduce_78(t[0], m, mp);
  17916. n = sp_4096_cmp_78(t[0], m);
  17917. sp_4096_cond_sub_78(t[0], t[0], m, ~(n >> 63));
  17918. XMEMCPY(r, t[0], sizeof(*r) * 78 * 2);
  17919. }
  17920. #ifdef WOLFSSL_SP_SMALL_STACK
  17921. if (td != NULL)
  17922. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  17923. #endif
  17924. return err;
  17925. #else
  17926. #ifdef WOLFSSL_SP_SMALL_STACK
  17927. sp_digit* td = NULL;
  17928. #else
  17929. sp_digit td[(16 * 156) + 156];
  17930. #endif
  17931. sp_digit* t[16];
  17932. sp_digit* rt = NULL;
  17933. sp_digit* norm = NULL;
  17934. sp_digit mp = 1;
  17935. sp_digit n;
  17936. int i;
  17937. int c;
  17938. byte y;
  17939. int err = MP_OKAY;
  17940. if (bits == 0) {
  17941. err = MP_VAL;
  17942. }
  17943. #ifdef WOLFSSL_SP_SMALL_STACK
  17944. if (err == MP_OKAY) {
  17945. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((16 * 156) + 156), NULL,
  17946. DYNAMIC_TYPE_TMP_BUFFER);
  17947. if (td == NULL)
  17948. err = MEMORY_E;
  17949. }
  17950. #endif
  17951. if (err == MP_OKAY) {
  17952. norm = td;
  17953. for (i=0; i<16; i++)
  17954. t[i] = td + i * 156;
  17955. rt = td + 2496;
  17956. sp_4096_mont_setup(m, &mp);
  17957. sp_4096_mont_norm_78(norm, m);
  17958. if (reduceA != 0) {
  17959. err = sp_4096_mod_78(t[1], a, m);
  17960. if (err == MP_OKAY) {
  17961. sp_4096_mul_78(t[1], t[1], norm);
  17962. err = sp_4096_mod_78(t[1], t[1], m);
  17963. }
  17964. }
  17965. else {
  17966. sp_4096_mul_78(t[1], a, norm);
  17967. err = sp_4096_mod_78(t[1], t[1], m);
  17968. }
  17969. }
  17970. if (err == MP_OKAY) {
  17971. sp_4096_mont_sqr_78(t[ 2], t[ 1], m, mp);
  17972. sp_4096_mont_mul_78(t[ 3], t[ 2], t[ 1], m, mp);
  17973. sp_4096_mont_sqr_78(t[ 4], t[ 2], m, mp);
  17974. sp_4096_mont_mul_78(t[ 5], t[ 3], t[ 2], m, mp);
  17975. sp_4096_mont_sqr_78(t[ 6], t[ 3], m, mp);
  17976. sp_4096_mont_mul_78(t[ 7], t[ 4], t[ 3], m, mp);
  17977. sp_4096_mont_sqr_78(t[ 8], t[ 4], m, mp);
  17978. sp_4096_mont_mul_78(t[ 9], t[ 5], t[ 4], m, mp);
  17979. sp_4096_mont_sqr_78(t[10], t[ 5], m, mp);
  17980. sp_4096_mont_mul_78(t[11], t[ 6], t[ 5], m, mp);
  17981. sp_4096_mont_sqr_78(t[12], t[ 6], m, mp);
  17982. sp_4096_mont_mul_78(t[13], t[ 7], t[ 6], m, mp);
  17983. sp_4096_mont_sqr_78(t[14], t[ 7], m, mp);
  17984. sp_4096_mont_mul_78(t[15], t[ 8], t[ 7], m, mp);
  17985. bits = ((bits + 3) / 4) * 4;
  17986. i = ((bits + 52) / 53) - 1;
  17987. c = bits % 53;
  17988. if (c == 0) {
  17989. c = 53;
  17990. }
  17991. if (i < 78) {
  17992. n = e[i--] << (64 - c);
  17993. }
  17994. else {
  17995. n = 0;
  17996. i--;
  17997. }
  17998. if (c < 4) {
  17999. n |= e[i--] << (11 - c);
  18000. c += 53;
  18001. }
  18002. y = (int)((n >> 60) & 0xf);
  18003. n <<= 4;
  18004. c -= 4;
  18005. XMEMCPY(rt, t[y], sizeof(sp_digit) * 156);
  18006. while ((i >= 0) || (c >= 4)) {
  18007. if (c >= 4) {
  18008. y = (byte)((n >> 60) & 0xf);
  18009. n <<= 4;
  18010. c -= 4;
  18011. }
  18012. else if (c == 0) {
  18013. n = e[i--] << 11;
  18014. y = (byte)((n >> 60) & 0xf);
  18015. n <<= 4;
  18016. c = 49;
  18017. }
  18018. else {
  18019. y = (byte)((n >> 60) & 0xf);
  18020. n = e[i--] << 11;
  18021. c = 4 - c;
  18022. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  18023. n <<= c;
  18024. c = 53 - c;
  18025. }
  18026. sp_4096_mont_sqr_78(rt, rt, m, mp);
  18027. sp_4096_mont_sqr_78(rt, rt, m, mp);
  18028. sp_4096_mont_sqr_78(rt, rt, m, mp);
  18029. sp_4096_mont_sqr_78(rt, rt, m, mp);
  18030. sp_4096_mont_mul_78(rt, rt, t[y], m, mp);
  18031. }
  18032. sp_4096_mont_reduce_78(rt, m, mp);
  18033. n = sp_4096_cmp_78(rt, m);
  18034. sp_4096_cond_sub_78(rt, rt, m, ~(n >> 63));
  18035. XMEMCPY(r, rt, sizeof(sp_digit) * 156);
  18036. }
  18037. #ifdef WOLFSSL_SP_SMALL_STACK
  18038. if (td != NULL)
  18039. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  18040. #endif
  18041. return err;
  18042. #endif
  18043. }
  18044. #endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) || */
  18045. /* WOLFSSL_HAVE_SP_DH */
  18046. #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
  18047. #ifdef WOLFSSL_HAVE_SP_RSA
  18048. /* RSA public key operation.
  18049. *
  18050. * in Array of bytes representing the number to exponentiate, base.
  18051. * inLen Number of bytes in base.
  18052. * em Public exponent.
  18053. * mm Modulus.
  18054. * out Buffer to hold big-endian bytes of exponentiation result.
  18055. * Must be at least 512 bytes long.
  18056. * outLen Number of bytes in result.
  18057. * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
  18058. * an array is too long and MEMORY_E when dynamic memory allocation fails.
  18059. */
  18060. int sp_RsaPublic_4096(const byte* in, word32 inLen, const mp_int* em,
  18061. const mp_int* mm, byte* out, word32* outLen)
  18062. {
  18063. #ifdef WOLFSSL_SP_SMALL
  18064. #ifdef WOLFSSL_SP_SMALL_STACK
  18065. sp_digit* a = NULL;
  18066. #else
  18067. sp_digit a[78 * 5];
  18068. #endif
  18069. sp_digit* m = NULL;
  18070. sp_digit* r = NULL;
  18071. sp_digit* norm = NULL;
  18072. sp_uint64 e[1] = {0};
  18073. sp_digit mp = 0;
  18074. int i;
  18075. int err = MP_OKAY;
  18076. if (*outLen < 512U) {
  18077. err = MP_TO_E;
  18078. }
  18079. if (err == MP_OKAY) {
  18080. if (mp_count_bits(em) > 64) {
  18081. err = MP_READ_E;
  18082. }
  18083. else if (inLen > 512U) {
  18084. err = MP_READ_E;
  18085. }
  18086. else if (mp_count_bits(mm) != 4096) {
  18087. err = MP_READ_E;
  18088. }
  18089. else if (mp_iseven(mm)) {
  18090. err = MP_VAL;
  18091. }
  18092. }
  18093. #ifdef WOLFSSL_SP_SMALL_STACK
  18094. if (err == MP_OKAY) {
  18095. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 5, NULL,
  18096. DYNAMIC_TYPE_RSA);
  18097. if (a == NULL)
  18098. err = MEMORY_E;
  18099. }
  18100. #endif
  18101. if (err == MP_OKAY) {
  18102. r = a + 78 * 2;
  18103. m = r + 78 * 2;
  18104. norm = r;
  18105. sp_4096_from_bin(a, 78, in, inLen);
  18106. #if DIGIT_BIT >= 64
  18107. e[0] = (sp_uint64)em->dp[0];
  18108. #else
  18109. e[0] = (sp_uint64)em->dp[0];
  18110. if (em->used > 1) {
  18111. e[0] |= ((sp_uint64)em->dp[1]) << DIGIT_BIT;
  18112. }
  18113. #endif
  18114. if (e[0] == 0) {
  18115. err = MP_EXPTMOD_E;
  18116. }
  18117. }
  18118. if (err == MP_OKAY) {
  18119. sp_4096_from_mp(m, 78, mm);
  18120. sp_4096_mont_setup(m, &mp);
  18121. sp_4096_mont_norm_78(norm, m);
  18122. }
  18123. if (err == MP_OKAY) {
  18124. sp_4096_mul_78(a, a, norm);
  18125. err = sp_4096_mod_78(a, a, m);
  18126. }
  18127. if (err == MP_OKAY) {
  18128. for (i=63; i>=0; i--) {
  18129. if ((e[0] >> i) != 0) {
  18130. break;
  18131. }
  18132. }
  18133. XMEMCPY(r, a, sizeof(sp_digit) * 78 * 2);
  18134. for (i--; i>=0; i--) {
  18135. sp_4096_mont_sqr_78(r, r, m, mp);
  18136. if (((e[0] >> i) & 1) == 1) {
  18137. sp_4096_mont_mul_78(r, r, a, m, mp);
  18138. }
  18139. }
  18140. sp_4096_mont_reduce_78(r, m, mp);
  18141. mp = sp_4096_cmp_78(r, m);
  18142. sp_4096_cond_sub_78(r, r, m, ~(mp >> 63));
  18143. sp_4096_to_bin_78(r, out);
  18144. *outLen = 512;
  18145. }
  18146. #ifdef WOLFSSL_SP_SMALL_STACK
  18147. if (a != NULL)
  18148. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  18149. #endif
  18150. return err;
  18151. #else
  18152. #ifdef WOLFSSL_SP_SMALL_STACK
  18153. sp_digit* d = NULL;
  18154. #else
  18155. sp_digit d[78 * 5];
  18156. #endif
  18157. sp_digit* a = NULL;
  18158. sp_digit* m = NULL;
  18159. sp_digit* r = NULL;
  18160. sp_uint64 e[1] = {0};
  18161. int err = MP_OKAY;
  18162. if (*outLen < 512U) {
  18163. err = MP_TO_E;
  18164. }
  18165. if (err == MP_OKAY) {
  18166. if (mp_count_bits(em) > 64) {
  18167. err = MP_READ_E;
  18168. }
  18169. else if (inLen > 512U) {
  18170. err = MP_READ_E;
  18171. }
  18172. else if (mp_count_bits(mm) != 4096) {
  18173. err = MP_READ_E;
  18174. }
  18175. else if (mp_iseven(mm)) {
  18176. err = MP_VAL;
  18177. }
  18178. }
  18179. #ifdef WOLFSSL_SP_SMALL_STACK
  18180. if (err == MP_OKAY) {
  18181. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 5, NULL,
  18182. DYNAMIC_TYPE_RSA);
  18183. if (d == NULL)
  18184. err = MEMORY_E;
  18185. }
  18186. #endif
  18187. if (err == MP_OKAY) {
  18188. a = d;
  18189. r = a + 78 * 2;
  18190. m = r + 78 * 2;
  18191. sp_4096_from_bin(a, 78, in, inLen);
  18192. #if DIGIT_BIT >= 64
  18193. e[0] = (sp_uint64)em->dp[0];
  18194. #else
  18195. e[0] = (sp_uint64)em->dp[0];
  18196. if (em->used > 1) {
  18197. e[0] |= ((sp_uint64)em->dp[1]) << DIGIT_BIT;
  18198. }
  18199. #endif
  18200. if (e[0] == 0) {
  18201. err = MP_EXPTMOD_E;
  18202. }
  18203. }
  18204. if (err == MP_OKAY) {
  18205. sp_4096_from_mp(m, 78, mm);
  18206. if (e[0] == 0x3) {
  18207. sp_4096_sqr_78(r, a);
  18208. err = sp_4096_mod_78(r, r, m);
  18209. if (err == MP_OKAY) {
  18210. sp_4096_mul_78(r, a, r);
  18211. err = sp_4096_mod_78(r, r, m);
  18212. }
  18213. }
  18214. else {
  18215. sp_digit* norm = r;
  18216. int i;
  18217. sp_digit mp;
  18218. sp_4096_mont_setup(m, &mp);
  18219. sp_4096_mont_norm_78(norm, m);
  18220. sp_4096_mul_78(a, a, norm);
  18221. err = sp_4096_mod_78(a, a, m);
  18222. if (err == MP_OKAY) {
  18223. for (i=63; i>=0; i--) {
  18224. if ((e[0] >> i) != 0) {
  18225. break;
  18226. }
  18227. }
  18228. XMEMCPY(r, a, sizeof(sp_digit) * 156U);
  18229. for (i--; i>=0; i--) {
  18230. sp_4096_mont_sqr_78(r, r, m, mp);
  18231. if (((e[0] >> i) & 1) == 1) {
  18232. sp_4096_mont_mul_78(r, r, a, m, mp);
  18233. }
  18234. }
  18235. sp_4096_mont_reduce_78(r, m, mp);
  18236. mp = sp_4096_cmp_78(r, m);
  18237. sp_4096_cond_sub_78(r, r, m, ~(mp >> 63));
  18238. }
  18239. }
  18240. }
  18241. if (err == MP_OKAY) {
  18242. sp_4096_to_bin_78(r, out);
  18243. *outLen = 512;
  18244. }
  18245. #ifdef WOLFSSL_SP_SMALL_STACK
  18246. if (d != NULL)
  18247. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  18248. #endif
  18249. return err;
  18250. #endif /* WOLFSSL_SP_SMALL */
  18251. }
  18252. #ifndef WOLFSSL_RSA_PUBLIC_ONLY
  18253. #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM)
  18254. #endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */
  18255. /* RSA private key operation.
  18256. *
  18257. * in Array of bytes representing the number to exponentiate, base.
  18258. * inLen Number of bytes in base.
  18259. * dm Private exponent.
  18260. * pm First prime.
  18261. * qm Second prime.
  18262. * dpm First prime's CRT exponent.
  18263. * dqm Second prime's CRT exponent.
  18264. * qim Inverse of second prime mod p.
  18265. * mm Modulus.
  18266. * out Buffer to hold big-endian bytes of exponentiation result.
  18267. * Must be at least 512 bytes long.
  18268. * outLen Number of bytes in result.
  18269. * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
  18270. * an array is too long and MEMORY_E when dynamic memory allocation fails.
  18271. */
  18272. int sp_RsaPrivate_4096(const byte* in, word32 inLen, const mp_int* dm,
  18273. const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm,
  18274. const mp_int* qim, const mp_int* mm, byte* out, word32* outLen)
  18275. {
  18276. #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
  18277. #if defined(WOLFSSL_SP_SMALL)
  18278. #ifdef WOLFSSL_SP_SMALL_STACK
  18279. sp_digit* d = NULL;
  18280. #else
  18281. sp_digit d[78 * 4];
  18282. #endif
  18283. sp_digit* a = NULL;
  18284. sp_digit* m = NULL;
  18285. sp_digit* r = NULL;
  18286. int err = MP_OKAY;
  18287. (void)pm;
  18288. (void)qm;
  18289. (void)dpm;
  18290. (void)dqm;
  18291. (void)qim;
  18292. if (*outLen < 512U) {
  18293. err = MP_TO_E;
  18294. }
  18295. if (err == MP_OKAY) {
  18296. if (mp_count_bits(dm) > 4096) {
  18297. err = MP_READ_E;
  18298. }
  18299. else if (inLen > 512) {
  18300. err = MP_READ_E;
  18301. }
  18302. else if (mp_count_bits(mm) != 4096) {
  18303. err = MP_READ_E;
  18304. }
  18305. else if (mp_iseven(mm)) {
  18306. err = MP_VAL;
  18307. }
  18308. }
  18309. #ifdef WOLFSSL_SP_SMALL_STACK
  18310. if (err == MP_OKAY) {
  18311. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 4, NULL,
  18312. DYNAMIC_TYPE_RSA);
  18313. if (d == NULL)
  18314. err = MEMORY_E;
  18315. }
  18316. #endif
  18317. if (err == MP_OKAY) {
  18318. a = d + 78;
  18319. m = a + 156;
  18320. r = a;
  18321. sp_4096_from_bin(a, 78, in, inLen);
  18322. sp_4096_from_mp(d, 78, dm);
  18323. sp_4096_from_mp(m, 78, mm);
  18324. err = sp_4096_mod_exp_78(r, a, d, 4096, m, 0);
  18325. }
  18326. if (err == MP_OKAY) {
  18327. sp_4096_to_bin_78(r, out);
  18328. *outLen = 512;
  18329. }
  18330. #ifdef WOLFSSL_SP_SMALL_STACK
  18331. if (d != NULL)
  18332. #endif
  18333. {
  18334. /* only "a" and "r" are sensitive and need zeroized (same pointer) */
  18335. if (a != NULL)
  18336. ForceZero(a, sizeof(sp_digit) * 78);
  18337. #ifdef WOLFSSL_SP_SMALL_STACK
  18338. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  18339. #endif
  18340. }
  18341. return err;
  18342. #else
  18343. #ifdef WOLFSSL_SP_SMALL_STACK
  18344. sp_digit* d = NULL;
  18345. #else
  18346. sp_digit d[78 * 4];
  18347. #endif
  18348. sp_digit* a = NULL;
  18349. sp_digit* m = NULL;
  18350. sp_digit* r = NULL;
  18351. int err = MP_OKAY;
  18352. (void)pm;
  18353. (void)qm;
  18354. (void)dpm;
  18355. (void)dqm;
  18356. (void)qim;
  18357. if (*outLen < 512U) {
  18358. err = MP_TO_E;
  18359. }
  18360. if (err == MP_OKAY) {
  18361. if (mp_count_bits(dm) > 4096) {
  18362. err = MP_READ_E;
  18363. }
  18364. else if (inLen > 512U) {
  18365. err = MP_READ_E;
  18366. }
  18367. else if (mp_count_bits(mm) != 4096) {
  18368. err = MP_READ_E;
  18369. }
  18370. else if (mp_iseven(mm)) {
  18371. err = MP_VAL;
  18372. }
  18373. }
  18374. #ifdef WOLFSSL_SP_SMALL_STACK
  18375. if (err == MP_OKAY) {
  18376. d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 4, NULL,
  18377. DYNAMIC_TYPE_RSA);
  18378. if (d == NULL)
  18379. err = MEMORY_E;
  18380. }
  18381. #endif
  18382. if (err == MP_OKAY) {
  18383. a = d + 78;
  18384. m = a + 156;
  18385. r = a;
  18386. sp_4096_from_bin(a, 78, in, inLen);
  18387. sp_4096_from_mp(d, 78, dm);
  18388. sp_4096_from_mp(m, 78, mm);
  18389. err = sp_4096_mod_exp_78(r, a, d, 4096, m, 0);
  18390. }
  18391. if (err == MP_OKAY) {
  18392. sp_4096_to_bin_78(r, out);
  18393. *outLen = 512;
  18394. }
  18395. #ifdef WOLFSSL_SP_SMALL_STACK
  18396. if (d != NULL)
  18397. #endif
  18398. {
  18399. /* only "a" and "r" are sensitive and need zeroized (same pointer) */
  18400. if (a != NULL)
  18401. ForceZero(a, sizeof(sp_digit) * 78);
  18402. #ifdef WOLFSSL_SP_SMALL_STACK
  18403. XFREE(d, NULL, DYNAMIC_TYPE_RSA);
  18404. #endif
  18405. }
  18406. return err;
  18407. #endif /* WOLFSSL_SP_SMALL */
  18408. #else
  18409. #if defined(WOLFSSL_SP_SMALL)
  18410. #ifdef WOLFSSL_SP_SMALL_STACK
  18411. sp_digit* a = NULL;
  18412. #else
  18413. sp_digit a[39 * 8];
  18414. #endif
  18415. sp_digit* p = NULL;
  18416. sp_digit* dp = NULL;
  18417. sp_digit* dq = NULL;
  18418. sp_digit* qi = NULL;
  18419. sp_digit* tmpa = NULL;
  18420. sp_digit* tmpb = NULL;
  18421. sp_digit* r = NULL;
  18422. int err = MP_OKAY;
  18423. (void)dm;
  18424. (void)mm;
  18425. if (*outLen < 512U) {
  18426. err = MP_TO_E;
  18427. }
  18428. if (err == MP_OKAY) {
  18429. if (inLen > 512) {
  18430. err = MP_READ_E;
  18431. }
  18432. else if (mp_count_bits(mm) != 4096) {
  18433. err = MP_READ_E;
  18434. }
  18435. else if (mp_iseven(mm)) {
  18436. err = MP_VAL;
  18437. }
  18438. else if (mp_iseven(pm)) {
  18439. err = MP_VAL;
  18440. }
  18441. else if (mp_iseven(qm)) {
  18442. err = MP_VAL;
  18443. }
  18444. }
  18445. #ifdef WOLFSSL_SP_SMALL_STACK
  18446. if (err == MP_OKAY) {
  18447. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 39 * 8, NULL,
  18448. DYNAMIC_TYPE_RSA);
  18449. if (a == NULL)
  18450. err = MEMORY_E;
  18451. }
  18452. #endif
  18453. if (err == MP_OKAY) {
  18454. p = a + 78;
  18455. qi = dq = dp = p + 39;
  18456. tmpa = qi + 39;
  18457. tmpb = tmpa + 78;
  18458. r = a;
  18459. sp_4096_from_bin(a, 78, in, inLen);
  18460. sp_4096_from_mp(p, 39, pm);
  18461. sp_4096_from_mp(dp, 39, dpm);
  18462. err = sp_4096_mod_exp_39(tmpa, a, dp, 2048, p, 1);
  18463. }
  18464. if (err == MP_OKAY) {
  18465. sp_4096_from_mp(p, 39, qm);
  18466. sp_4096_from_mp(dq, 39, dqm);
  18467. err = sp_4096_mod_exp_39(tmpb, a, dq, 2048, p, 1);
  18468. }
  18469. if (err == MP_OKAY) {
  18470. sp_4096_from_mp(p, 39, pm);
  18471. (void)sp_4096_sub_39(tmpa, tmpa, tmpb);
  18472. sp_4096_norm_39(tmpa);
  18473. sp_4096_cond_add_39(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[38] >> 63));
  18474. sp_4096_cond_add_39(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[38] >> 63));
  18475. sp_4096_norm_39(tmpa);
  18476. sp_4096_from_mp(qi, 39, qim);
  18477. sp_4096_mul_39(tmpa, tmpa, qi);
  18478. err = sp_4096_mod_39(tmpa, tmpa, p);
  18479. }
  18480. if (err == MP_OKAY) {
  18481. sp_4096_from_mp(p, 39, qm);
  18482. sp_4096_mul_39(tmpa, p, tmpa);
  18483. (void)sp_4096_add_78(r, tmpb, tmpa);
  18484. sp_4096_norm_78(r);
  18485. sp_4096_to_bin_78(r, out);
  18486. *outLen = 512;
  18487. }
  18488. #ifdef WOLFSSL_SP_SMALL_STACK
  18489. if (a != NULL)
  18490. #endif
  18491. {
  18492. ForceZero(a, sizeof(sp_digit) * 39 * 8);
  18493. #ifdef WOLFSSL_SP_SMALL_STACK
  18494. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  18495. #endif
  18496. }
  18497. return err;
  18498. #else
  18499. #ifdef WOLFSSL_SP_SMALL_STACK
  18500. sp_digit* a = NULL;
  18501. #else
  18502. sp_digit a[39 * 13];
  18503. #endif
  18504. sp_digit* p = NULL;
  18505. sp_digit* q = NULL;
  18506. sp_digit* dp = NULL;
  18507. sp_digit* dq = NULL;
  18508. sp_digit* qi = NULL;
  18509. sp_digit* tmpa = NULL;
  18510. sp_digit* tmpb = NULL;
  18511. sp_digit* r = NULL;
  18512. int err = MP_OKAY;
  18513. (void)dm;
  18514. (void)mm;
  18515. if (*outLen < 512U) {
  18516. err = MP_TO_E;
  18517. }
  18518. if (err == MP_OKAY) {
  18519. if (inLen > 512U) {
  18520. err = MP_READ_E;
  18521. }
  18522. else if (mp_count_bits(mm) != 4096) {
  18523. err = MP_READ_E;
  18524. }
  18525. else if (mp_iseven(mm)) {
  18526. err = MP_VAL;
  18527. }
  18528. else if (mp_iseven(pm)) {
  18529. err = MP_VAL;
  18530. }
  18531. else if (mp_iseven(qm)) {
  18532. err = MP_VAL;
  18533. }
  18534. }
  18535. #ifdef WOLFSSL_SP_SMALL_STACK
  18536. if (err == MP_OKAY) {
  18537. a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 39 * 13, NULL,
  18538. DYNAMIC_TYPE_RSA);
  18539. if (a == NULL)
  18540. err = MEMORY_E;
  18541. }
  18542. #endif
  18543. if (err == MP_OKAY) {
  18544. p = a + 78 * 2;
  18545. q = p + 39;
  18546. dp = q + 39;
  18547. dq = dp + 39;
  18548. qi = dq + 39;
  18549. tmpa = qi + 39;
  18550. tmpb = tmpa + 78;
  18551. r = a;
  18552. sp_4096_from_bin(a, 78, in, inLen);
  18553. sp_4096_from_mp(p, 39, pm);
  18554. sp_4096_from_mp(q, 39, qm);
  18555. sp_4096_from_mp(dp, 39, dpm);
  18556. sp_4096_from_mp(dq, 39, dqm);
  18557. sp_4096_from_mp(qi, 39, qim);
  18558. err = sp_4096_mod_exp_39(tmpa, a, dp, 2048, p, 1);
  18559. }
  18560. if (err == MP_OKAY) {
  18561. err = sp_4096_mod_exp_39(tmpb, a, dq, 2048, q, 1);
  18562. }
  18563. if (err == MP_OKAY) {
  18564. (void)sp_4096_sub_39(tmpa, tmpa, tmpb);
  18565. sp_4096_norm_39(tmpa);
  18566. sp_4096_cond_add_39(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[38] >> 63));
  18567. sp_4096_cond_add_39(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[38] >> 63));
  18568. sp_4096_norm_39(tmpa);
  18569. sp_4096_mul_39(tmpa, tmpa, qi);
  18570. err = sp_4096_mod_39(tmpa, tmpa, p);
  18571. }
  18572. if (err == MP_OKAY) {
  18573. sp_4096_mul_39(tmpa, tmpa, q);
  18574. (void)sp_4096_add_78(r, tmpb, tmpa);
  18575. sp_4096_norm_78(r);
  18576. sp_4096_to_bin_78(r, out);
  18577. *outLen = 512;
  18578. }
  18579. #ifdef WOLFSSL_SP_SMALL_STACK
  18580. if (a != NULL)
  18581. #endif
  18582. {
  18583. ForceZero(a, sizeof(sp_digit) * 39 * 13);
  18584. #ifdef WOLFSSL_SP_SMALL_STACK
  18585. XFREE(a, NULL, DYNAMIC_TYPE_RSA);
  18586. #endif
  18587. }
  18588. return err;
  18589. #endif /* WOLFSSL_SP_SMALL */
  18590. #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
  18591. }
  18592. #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
  18593. #endif /* WOLFSSL_HAVE_SP_RSA */
  18594. #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
  18595. !defined(WOLFSSL_RSA_PUBLIC_ONLY))
  18596. /* Convert an array of sp_digit to an mp_int.
  18597. *
  18598. * a A single precision integer.
  18599. * r A multi-precision integer.
  18600. */
  18601. static int sp_4096_to_mp(const sp_digit* a, mp_int* r)
  18602. {
  18603. int err;
  18604. err = mp_grow(r, (4096 + DIGIT_BIT - 1) / DIGIT_BIT);
  18605. if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
  18606. #if DIGIT_BIT == 53
  18607. XMEMCPY(r->dp, a, sizeof(sp_digit) * 78);
  18608. r->used = 78;
  18609. mp_clamp(r);
  18610. #elif DIGIT_BIT < 53
  18611. int i;
  18612. int j = 0;
  18613. int s = 0;
  18614. r->dp[0] = 0;
  18615. for (i = 0; i < 78; i++) {
  18616. r->dp[j] |= (mp_digit)(a[i] << s);
  18617. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  18618. s = DIGIT_BIT - s;
  18619. r->dp[++j] = (mp_digit)(a[i] >> s);
  18620. while (s + DIGIT_BIT <= 53) {
  18621. s += DIGIT_BIT;
  18622. r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  18623. if (s == SP_WORD_SIZE) {
  18624. r->dp[j] = 0;
  18625. }
  18626. else {
  18627. r->dp[j] = (mp_digit)(a[i] >> s);
  18628. }
  18629. }
  18630. s = 53 - s;
  18631. }
  18632. r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;
  18633. mp_clamp(r);
  18634. #else
  18635. int i;
  18636. int j = 0;
  18637. int s = 0;
  18638. r->dp[0] = 0;
  18639. for (i = 0; i < 78; i++) {
  18640. r->dp[j] |= ((mp_digit)a[i]) << s;
  18641. if (s + 53 >= DIGIT_BIT) {
  18642. #if DIGIT_BIT != 32 && DIGIT_BIT != 64
  18643. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  18644. #endif
  18645. s = DIGIT_BIT - s;
  18646. r->dp[++j] = a[i] >> s;
  18647. s = 53 - s;
  18648. }
  18649. else {
  18650. s += 53;
  18651. }
  18652. }
  18653. r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;
  18654. mp_clamp(r);
  18655. #endif
  18656. }
  18657. return err;
  18658. }
  18659. /* Perform the modular exponentiation for Diffie-Hellman.
  18660. *
  18661. * base Base. MP integer.
  18662. * exp Exponent. MP integer.
  18663. * mod Modulus. MP integer.
  18664. * res Result. MP integer.
  18665. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  18666. * and MEMORY_E if memory allocation fails.
  18667. */
  18668. int sp_ModExp_4096(const mp_int* base, const mp_int* exp, const mp_int* mod,
  18669. mp_int* res)
  18670. {
  18671. #ifdef WOLFSSL_SP_SMALL
  18672. int err = MP_OKAY;
  18673. #ifdef WOLFSSL_SP_SMALL_STACK
  18674. sp_digit* b = NULL;
  18675. #else
  18676. sp_digit b[78 * 4];
  18677. #endif
  18678. sp_digit* e = NULL;
  18679. sp_digit* m = NULL;
  18680. sp_digit* r = NULL;
  18681. int expBits = mp_count_bits(exp);
  18682. if (mp_count_bits(base) > 4096) {
  18683. err = MP_READ_E;
  18684. }
  18685. else if (expBits > 4096) {
  18686. err = MP_READ_E;
  18687. }
  18688. else if (mp_count_bits(mod) != 4096) {
  18689. err = MP_READ_E;
  18690. }
  18691. else if (mp_iseven(mod)) {
  18692. err = MP_VAL;
  18693. }
  18694. #ifdef WOLFSSL_SP_SMALL_STACK
  18695. if (err == MP_OKAY) {
  18696. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 4, NULL,
  18697. DYNAMIC_TYPE_DH);
  18698. if (b == NULL)
  18699. err = MEMORY_E;
  18700. }
  18701. #endif
  18702. if (err == MP_OKAY) {
  18703. e = b + 78 * 2;
  18704. m = e + 78;
  18705. r = b;
  18706. sp_4096_from_mp(b, 78, base);
  18707. sp_4096_from_mp(e, 78, exp);
  18708. sp_4096_from_mp(m, 78, mod);
  18709. err = sp_4096_mod_exp_78(r, b, e, mp_count_bits(exp), m, 0);
  18710. }
  18711. if (err == MP_OKAY) {
  18712. err = sp_4096_to_mp(r, res);
  18713. }
  18714. #ifdef WOLFSSL_SP_SMALL_STACK
  18715. if (b != NULL)
  18716. #endif
  18717. {
  18718. /* only "e" is sensitive and needs zeroized */
  18719. if (e != NULL)
  18720. ForceZero(e, sizeof(sp_digit) * 78U);
  18721. #ifdef WOLFSSL_SP_SMALL_STACK
  18722. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  18723. #endif
  18724. }
  18725. return err;
  18726. #else
  18727. #ifdef WOLFSSL_SP_SMALL_STACK
  18728. sp_digit* b = NULL;
  18729. #else
  18730. sp_digit b[78 * 4];
  18731. #endif
  18732. sp_digit* e = NULL;
  18733. sp_digit* m = NULL;
  18734. sp_digit* r = NULL;
  18735. int err = MP_OKAY;
  18736. int expBits = mp_count_bits(exp);
  18737. if (mp_count_bits(base) > 4096) {
  18738. err = MP_READ_E;
  18739. }
  18740. else if (expBits > 4096) {
  18741. err = MP_READ_E;
  18742. }
  18743. else if (mp_count_bits(mod) != 4096) {
  18744. err = MP_READ_E;
  18745. }
  18746. else if (mp_iseven(mod)) {
  18747. err = MP_VAL;
  18748. }
  18749. #ifdef WOLFSSL_SP_SMALL_STACK
  18750. if (err == MP_OKAY) {
  18751. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 4, NULL, DYNAMIC_TYPE_DH);
  18752. if (b == NULL)
  18753. err = MEMORY_E;
  18754. }
  18755. #endif
  18756. if (err == MP_OKAY) {
  18757. e = b + 78 * 2;
  18758. m = e + 78;
  18759. r = b;
  18760. sp_4096_from_mp(b, 78, base);
  18761. sp_4096_from_mp(e, 78, exp);
  18762. sp_4096_from_mp(m, 78, mod);
  18763. err = sp_4096_mod_exp_78(r, b, e, expBits, m, 0);
  18764. }
  18765. if (err == MP_OKAY) {
  18766. err = sp_4096_to_mp(r, res);
  18767. }
  18768. #ifdef WOLFSSL_SP_SMALL_STACK
  18769. if (b != NULL)
  18770. #endif
  18771. {
  18772. /* only "e" is sensitive and needs zeroized */
  18773. if (e != NULL)
  18774. ForceZero(e, sizeof(sp_digit) * 78U);
  18775. #ifdef WOLFSSL_SP_SMALL_STACK
  18776. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  18777. #endif
  18778. }
  18779. return err;
  18780. #endif
  18781. }
  18782. #ifdef WOLFSSL_HAVE_SP_DH
  18783. #ifdef HAVE_FFDHE_4096
  18784. SP_NOINLINE static void sp_4096_lshift_78(sp_digit* r, const sp_digit* a,
  18785. byte n)
  18786. {
  18787. sp_int_digit s;
  18788. sp_int_digit t;
  18789. s = (sp_int_digit)a[77];
  18790. r[78] = s >> (53U - n);
  18791. s = (sp_int_digit)(a[77]); t = (sp_int_digit)(a[76]);
  18792. r[77] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18793. s = (sp_int_digit)(a[76]); t = (sp_int_digit)(a[75]);
  18794. r[76] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18795. s = (sp_int_digit)(a[75]); t = (sp_int_digit)(a[74]);
  18796. r[75] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18797. s = (sp_int_digit)(a[74]); t = (sp_int_digit)(a[73]);
  18798. r[74] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18799. s = (sp_int_digit)(a[73]); t = (sp_int_digit)(a[72]);
  18800. r[73] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18801. s = (sp_int_digit)(a[72]); t = (sp_int_digit)(a[71]);
  18802. r[72] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18803. s = (sp_int_digit)(a[71]); t = (sp_int_digit)(a[70]);
  18804. r[71] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18805. s = (sp_int_digit)(a[70]); t = (sp_int_digit)(a[69]);
  18806. r[70] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18807. s = (sp_int_digit)(a[69]); t = (sp_int_digit)(a[68]);
  18808. r[69] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18809. s = (sp_int_digit)(a[68]); t = (sp_int_digit)(a[67]);
  18810. r[68] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18811. s = (sp_int_digit)(a[67]); t = (sp_int_digit)(a[66]);
  18812. r[67] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18813. s = (sp_int_digit)(a[66]); t = (sp_int_digit)(a[65]);
  18814. r[66] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18815. s = (sp_int_digit)(a[65]); t = (sp_int_digit)(a[64]);
  18816. r[65] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18817. s = (sp_int_digit)(a[64]); t = (sp_int_digit)(a[63]);
  18818. r[64] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18819. s = (sp_int_digit)(a[63]); t = (sp_int_digit)(a[62]);
  18820. r[63] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18821. s = (sp_int_digit)(a[62]); t = (sp_int_digit)(a[61]);
  18822. r[62] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18823. s = (sp_int_digit)(a[61]); t = (sp_int_digit)(a[60]);
  18824. r[61] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18825. s = (sp_int_digit)(a[60]); t = (sp_int_digit)(a[59]);
  18826. r[60] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18827. s = (sp_int_digit)(a[59]); t = (sp_int_digit)(a[58]);
  18828. r[59] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18829. s = (sp_int_digit)(a[58]); t = (sp_int_digit)(a[57]);
  18830. r[58] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18831. s = (sp_int_digit)(a[57]); t = (sp_int_digit)(a[56]);
  18832. r[57] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18833. s = (sp_int_digit)(a[56]); t = (sp_int_digit)(a[55]);
  18834. r[56] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18835. s = (sp_int_digit)(a[55]); t = (sp_int_digit)(a[54]);
  18836. r[55] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18837. s = (sp_int_digit)(a[54]); t = (sp_int_digit)(a[53]);
  18838. r[54] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18839. s = (sp_int_digit)(a[53]); t = (sp_int_digit)(a[52]);
  18840. r[53] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18841. s = (sp_int_digit)(a[52]); t = (sp_int_digit)(a[51]);
  18842. r[52] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18843. s = (sp_int_digit)(a[51]); t = (sp_int_digit)(a[50]);
  18844. r[51] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18845. s = (sp_int_digit)(a[50]); t = (sp_int_digit)(a[49]);
  18846. r[50] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18847. s = (sp_int_digit)(a[49]); t = (sp_int_digit)(a[48]);
  18848. r[49] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18849. s = (sp_int_digit)(a[48]); t = (sp_int_digit)(a[47]);
  18850. r[48] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18851. s = (sp_int_digit)(a[47]); t = (sp_int_digit)(a[46]);
  18852. r[47] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18853. s = (sp_int_digit)(a[46]); t = (sp_int_digit)(a[45]);
  18854. r[46] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18855. s = (sp_int_digit)(a[45]); t = (sp_int_digit)(a[44]);
  18856. r[45] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18857. s = (sp_int_digit)(a[44]); t = (sp_int_digit)(a[43]);
  18858. r[44] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18859. s = (sp_int_digit)(a[43]); t = (sp_int_digit)(a[42]);
  18860. r[43] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18861. s = (sp_int_digit)(a[42]); t = (sp_int_digit)(a[41]);
  18862. r[42] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18863. s = (sp_int_digit)(a[41]); t = (sp_int_digit)(a[40]);
  18864. r[41] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18865. s = (sp_int_digit)(a[40]); t = (sp_int_digit)(a[39]);
  18866. r[40] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18867. s = (sp_int_digit)(a[39]); t = (sp_int_digit)(a[38]);
  18868. r[39] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18869. s = (sp_int_digit)(a[38]); t = (sp_int_digit)(a[37]);
  18870. r[38] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18871. s = (sp_int_digit)(a[37]); t = (sp_int_digit)(a[36]);
  18872. r[37] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18873. s = (sp_int_digit)(a[36]); t = (sp_int_digit)(a[35]);
  18874. r[36] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18875. s = (sp_int_digit)(a[35]); t = (sp_int_digit)(a[34]);
  18876. r[35] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18877. s = (sp_int_digit)(a[34]); t = (sp_int_digit)(a[33]);
  18878. r[34] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18879. s = (sp_int_digit)(a[33]); t = (sp_int_digit)(a[32]);
  18880. r[33] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18881. s = (sp_int_digit)(a[32]); t = (sp_int_digit)(a[31]);
  18882. r[32] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18883. s = (sp_int_digit)(a[31]); t = (sp_int_digit)(a[30]);
  18884. r[31] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18885. s = (sp_int_digit)(a[30]); t = (sp_int_digit)(a[29]);
  18886. r[30] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18887. s = (sp_int_digit)(a[29]); t = (sp_int_digit)(a[28]);
  18888. r[29] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18889. s = (sp_int_digit)(a[28]); t = (sp_int_digit)(a[27]);
  18890. r[28] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18891. s = (sp_int_digit)(a[27]); t = (sp_int_digit)(a[26]);
  18892. r[27] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18893. s = (sp_int_digit)(a[26]); t = (sp_int_digit)(a[25]);
  18894. r[26] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18895. s = (sp_int_digit)(a[25]); t = (sp_int_digit)(a[24]);
  18896. r[25] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18897. s = (sp_int_digit)(a[24]); t = (sp_int_digit)(a[23]);
  18898. r[24] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18899. s = (sp_int_digit)(a[23]); t = (sp_int_digit)(a[22]);
  18900. r[23] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18901. s = (sp_int_digit)(a[22]); t = (sp_int_digit)(a[21]);
  18902. r[22] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18903. s = (sp_int_digit)(a[21]); t = (sp_int_digit)(a[20]);
  18904. r[21] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18905. s = (sp_int_digit)(a[20]); t = (sp_int_digit)(a[19]);
  18906. r[20] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18907. s = (sp_int_digit)(a[19]); t = (sp_int_digit)(a[18]);
  18908. r[19] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18909. s = (sp_int_digit)(a[18]); t = (sp_int_digit)(a[17]);
  18910. r[18] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18911. s = (sp_int_digit)(a[17]); t = (sp_int_digit)(a[16]);
  18912. r[17] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18913. s = (sp_int_digit)(a[16]); t = (sp_int_digit)(a[15]);
  18914. r[16] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18915. s = (sp_int_digit)(a[15]); t = (sp_int_digit)(a[14]);
  18916. r[15] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18917. s = (sp_int_digit)(a[14]); t = (sp_int_digit)(a[13]);
  18918. r[14] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18919. s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);
  18920. r[13] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18921. s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);
  18922. r[12] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18923. s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);
  18924. r[11] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18925. s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);
  18926. r[10] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18927. s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);
  18928. r[9] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18929. s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);
  18930. r[8] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18931. s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);
  18932. r[7] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18933. s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);
  18934. r[6] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18935. s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);
  18936. r[5] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18937. s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);
  18938. r[4] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18939. s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);
  18940. r[3] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18941. s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);
  18942. r[2] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18943. s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);
  18944. r[1] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
  18945. r[0] = (a[0] << n) & 0x1fffffffffffffL;
  18946. }
  18947. /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
  18948. *
  18949. * r A single precision number that is the result of the operation.
  18950. * e A single precision number that is the exponent.
  18951. * bits The number of bits in the exponent.
  18952. * m A single precision number that is the modulus.
  18953. * returns 0 on success.
  18954. * returns MEMORY_E on dynamic memory allocation failure.
  18955. * returns MP_VAL when base is even.
  18956. */
  18957. static int sp_4096_mod_exp_2_78(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)
  18958. {
  18959. #ifdef WOLFSSL_SP_SMALL_STACK
  18960. sp_digit* td = NULL;
  18961. #else
  18962. sp_digit td[235];
  18963. #endif
  18964. sp_digit* norm = NULL;
  18965. sp_digit* tmp = NULL;
  18966. sp_digit mp = 1;
  18967. sp_digit n;
  18968. sp_digit o;
  18969. int i;
  18970. int c;
  18971. byte y;
  18972. int err = MP_OKAY;
  18973. if (bits == 0) {
  18974. err = MP_VAL;
  18975. }
  18976. #ifdef WOLFSSL_SP_SMALL_STACK
  18977. if (err == MP_OKAY) {
  18978. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 235, NULL,
  18979. DYNAMIC_TYPE_TMP_BUFFER);
  18980. if (td == NULL)
  18981. err = MEMORY_E;
  18982. }
  18983. #endif
  18984. if (err == MP_OKAY) {
  18985. norm = td;
  18986. tmp = td + 156;
  18987. XMEMSET(td, 0, sizeof(sp_digit) * 235);
  18988. sp_4096_mont_setup(m, &mp);
  18989. sp_4096_mont_norm_78(norm, m);
  18990. bits = ((bits + 4) / 5) * 5;
  18991. i = ((bits + 52) / 53) - 1;
  18992. c = bits % 53;
  18993. if (c == 0) {
  18994. c = 53;
  18995. }
  18996. if (i < 78) {
  18997. n = e[i--] << (64 - c);
  18998. }
  18999. else {
  19000. n = 0;
  19001. i--;
  19002. }
  19003. if (c < 5) {
  19004. n |= e[i--] << (11 - c);
  19005. c += 53;
  19006. }
  19007. y = (int)((n >> 59) & 0x1f);
  19008. n <<= 5;
  19009. c -= 5;
  19010. sp_4096_lshift_78(r, norm, (byte)y);
  19011. while ((i >= 0) || (c >= 5)) {
  19012. if (c >= 5) {
  19013. y = (byte)((n >> 59) & 0x1f);
  19014. n <<= 5;
  19015. c -= 5;
  19016. }
  19017. else if (c == 0) {
  19018. n = e[i--] << 11;
  19019. y = (byte)((n >> 59) & 0x1f);
  19020. n <<= 5;
  19021. c = 48;
  19022. }
  19023. else {
  19024. y = (byte)((n >> 59) & 0x1f);
  19025. n = e[i--] << 11;
  19026. c = 5 - c;
  19027. y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
  19028. n <<= c;
  19029. c = 53 - c;
  19030. }
  19031. sp_4096_mont_sqr_78(r, r, m, mp);
  19032. sp_4096_mont_sqr_78(r, r, m, mp);
  19033. sp_4096_mont_sqr_78(r, r, m, mp);
  19034. sp_4096_mont_sqr_78(r, r, m, mp);
  19035. sp_4096_mont_sqr_78(r, r, m, mp);
  19036. sp_4096_lshift_78(r, r, (byte)y);
  19037. sp_4096_mul_d_78(tmp, norm, (r[78] << 38) + (r[77] >> 15));
  19038. r[78] = 0;
  19039. r[77] &= 0x7fffL;
  19040. (void)sp_4096_add_78(r, r, tmp);
  19041. sp_4096_norm_78(r);
  19042. o = sp_4096_cmp_78(r, m);
  19043. sp_4096_cond_sub_78(r, r, m, ~(o >> 63));
  19044. }
  19045. sp_4096_mont_reduce_78(r, m, mp);
  19046. n = sp_4096_cmp_78(r, m);
  19047. sp_4096_cond_sub_78(r, r, m, ~(n >> 63));
  19048. }
  19049. #ifdef WOLFSSL_SP_SMALL_STACK
  19050. if (td != NULL)
  19051. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  19052. #endif
  19053. return err;
  19054. }
  19055. #endif /* HAVE_FFDHE_4096 */
  19056. /* Perform the modular exponentiation for Diffie-Hellman.
  19057. *
  19058. * base Base.
  19059. * exp Array of bytes that is the exponent.
  19060. * expLen Length of data, in bytes, in exponent.
  19061. * mod Modulus.
  19062. * out Buffer to hold big-endian bytes of exponentiation result.
  19063. * Must be at least 512 bytes long.
  19064. * outLen Length, in bytes, of exponentiation result.
  19065. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  19066. * and MEMORY_E if memory allocation fails.
  19067. */
  19068. int sp_DhExp_4096(const mp_int* base, const byte* exp, word32 expLen,
  19069. const mp_int* mod, byte* out, word32* outLen)
  19070. {
  19071. #ifdef WOLFSSL_SP_SMALL_STACK
  19072. sp_digit* b = NULL;
  19073. #else
  19074. sp_digit b[78 * 4];
  19075. #endif
  19076. sp_digit* e = NULL;
  19077. sp_digit* m = NULL;
  19078. sp_digit* r = NULL;
  19079. word32 i;
  19080. int err = MP_OKAY;
  19081. if (mp_count_bits(base) > 4096) {
  19082. err = MP_READ_E;
  19083. }
  19084. else if (expLen > 512U) {
  19085. err = MP_READ_E;
  19086. }
  19087. else if (mp_count_bits(mod) != 4096) {
  19088. err = MP_READ_E;
  19089. }
  19090. else if (mp_iseven(mod)) {
  19091. err = MP_VAL;
  19092. }
  19093. #ifdef WOLFSSL_SP_SMALL_STACK
  19094. if (err == MP_OKAY) {
  19095. b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 4, NULL,
  19096. DYNAMIC_TYPE_DH);
  19097. if (b == NULL)
  19098. err = MEMORY_E;
  19099. }
  19100. #endif
  19101. if (err == MP_OKAY) {
  19102. e = b + 78 * 2;
  19103. m = e + 78;
  19104. r = b;
  19105. sp_4096_from_mp(b, 78, base);
  19106. sp_4096_from_bin(e, 78, exp, expLen);
  19107. sp_4096_from_mp(m, 78, mod);
  19108. #ifdef HAVE_FFDHE_4096
  19109. if (base->used == 1 && base->dp[0] == 2U &&
  19110. ((m[77] << 17) | (m[76] >> 36)) == 0xffffffffL) {
  19111. err = sp_4096_mod_exp_2_78(r, e, expLen * 8U, m);
  19112. }
  19113. else {
  19114. #endif
  19115. err = sp_4096_mod_exp_78(r, b, e, expLen * 8U, m, 0);
  19116. #ifdef HAVE_FFDHE_4096
  19117. }
  19118. #endif
  19119. }
  19120. if (err == MP_OKAY) {
  19121. sp_4096_to_bin_78(r, out);
  19122. *outLen = 512;
  19123. for (i=0; i<512U && out[i] == 0U; i++) {
  19124. /* Search for first non-zero. */
  19125. }
  19126. *outLen -= i;
  19127. XMEMMOVE(out, out + i, *outLen);
  19128. }
  19129. #ifdef WOLFSSL_SP_SMALL_STACK
  19130. if (b != NULL)
  19131. #endif
  19132. {
  19133. /* only "e" is sensitive and needs zeroized */
  19134. if (e != NULL)
  19135. ForceZero(e, sizeof(sp_digit) * 78U);
  19136. #ifdef WOLFSSL_SP_SMALL_STACK
  19137. XFREE(b, NULL, DYNAMIC_TYPE_DH);
  19138. #endif
  19139. }
  19140. return err;
  19141. }
  19142. #endif /* WOLFSSL_HAVE_SP_DH */
  19143. #endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */
  19144. #endif /* WOLFSSL_SP_SMALL */
  19145. #endif /* WOLFSSL_SP_4096 */
  19146. #endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */
  19147. #ifdef WOLFSSL_HAVE_SP_ECC
  19148. #ifndef WOLFSSL_SP_NO_256
  19149. /* Point structure to use. */
  19150. typedef struct sp_point_256 {
  19151. /* X ordinate of point. */
  19152. sp_digit x[2 * 5];
  19153. /* Y ordinate of point. */
  19154. sp_digit y[2 * 5];
  19155. /* Z ordinate of point. */
  19156. sp_digit z[2 * 5];
  19157. /* Indicates point is at infinity. */
  19158. int infinity;
  19159. } sp_point_256;
  19160. /* The modulus (prime) of the curve P256. */
  19161. static const sp_digit p256_mod[5] = {
  19162. 0xfffffffffffffL,0x00fffffffffffL,0x0000000000000L,0x0001000000000L,
  19163. 0x0ffffffff0000L
  19164. };
  19165. /* The Montgomery normalizer for modulus of the curve P256. */
  19166. static const sp_digit p256_norm_mod[5] = {
  19167. 0x0000000000001L,0xff00000000000L,0xfffffffffffffL,0xfffefffffffffL,
  19168. 0x000000000ffffL
  19169. };
  19170. /* The Montgomery multiplier for modulus of the curve P256. */
  19171. static const sp_digit p256_mp_mod = 0x0000000000001;
  19172. #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
  19173. defined(HAVE_ECC_VERIFY)
  19174. /* The order of the curve P256. */
  19175. static const sp_digit p256_order[5] = {
  19176. 0x9cac2fc632551L,0xada7179e84f3bL,0xfffffffbce6faL,0x0000fffffffffL,
  19177. 0x0ffffffff0000L
  19178. };
  19179. #endif
  19180. /* The order of the curve P256 minus 2. */
  19181. static const sp_digit p256_order2[5] = {
  19182. 0x9cac2fc63254fL,0xada7179e84f3bL,0xfffffffbce6faL,0x0000fffffffffL,
  19183. 0x0ffffffff0000L
  19184. };
  19185. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  19186. /* The Montgomery normalizer for order of the curve P256. */
  19187. static const sp_digit p256_norm_order[5] = {
  19188. 0x6353d039cdaafL,0x5258e8617b0c4L,0x0000000431905L,0xffff000000000L,
  19189. 0x000000000ffffL
  19190. };
  19191. #endif
  19192. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  19193. /* The Montgomery multiplier for order of the curve P256. */
  19194. static const sp_digit p256_mp_order = 0x1c8aaee00bc4fL;
  19195. #endif
  19196. /* The base point of curve P256. */
  19197. static const sp_point_256 p256_base = {
  19198. /* X ordinate */
  19199. {
  19200. 0x13945d898c296L,0x812deb33a0f4aL,0x3a440f277037dL,0x4247f8bce6e56L,
  19201. 0x06b17d1f2e12cL,
  19202. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0
  19203. },
  19204. /* Y ordinate */
  19205. {
  19206. 0x6406837bf51f5L,0x576b315ececbbL,0xc0f9e162bce33L,0x7f9b8ee7eb4a7L,
  19207. 0x04fe342e2fe1aL,
  19208. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0
  19209. },
  19210. /* Z ordinate */
  19211. {
  19212. 0x0000000000001L,0x0000000000000L,0x0000000000000L,0x0000000000000L,
  19213. 0x0000000000000L,
  19214. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0
  19215. },
  19216. /* infinity */
  19217. 0
  19218. };
  19219. #if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)
  19220. static const sp_digit p256_b[5] = {
  19221. 0xe3c3e27d2604bL,0xb0cc53b0f63bcL,0x69886bc651d06L,0x93e7b3ebbd557L,
  19222. 0x05ac635d8aa3aL
  19223. };
  19224. #endif
  19225. #ifdef WOLFSSL_SP_SMALL
  19226. /* Multiply a and b into r. (r = a * b)
  19227. *
  19228. * r A single precision integer.
  19229. * a A single precision integer.
  19230. * b A single precision integer.
  19231. */
  19232. SP_NOINLINE static void sp_256_mul_5(sp_digit* r, const sp_digit* a,
  19233. const sp_digit* b)
  19234. {
  19235. int i;
  19236. int imax;
  19237. int k;
  19238. sp_uint128 c;
  19239. sp_uint128 lo;
  19240. c = ((sp_uint128)a[4]) * b[4];
  19241. r[9] = (sp_digit)(c >> 52);
  19242. c &= 0xfffffffffffffL;
  19243. for (k = 7; k >= 0; k--) {
  19244. if (k >= 5) {
  19245. i = k - 4;
  19246. imax = 4;
  19247. }
  19248. else {
  19249. i = 0;
  19250. imax = k;
  19251. }
  19252. lo = 0;
  19253. for (; i <= imax; i++) {
  19254. lo += ((sp_uint128)a[i]) * b[k - i];
  19255. }
  19256. c += lo >> 52;
  19257. r[k + 2] += (sp_digit)(c >> 52);
  19258. r[k + 1] = (sp_digit)(c & 0xfffffffffffffL);
  19259. c = lo & 0xfffffffffffffL;
  19260. }
  19261. r[0] = (sp_digit)c;
  19262. }
  19263. #else
  19264. /* Multiply a and b into r. (r = a * b)
  19265. *
  19266. * r A single precision integer.
  19267. * a A single precision integer.
  19268. * b A single precision integer.
  19269. */
  19270. SP_NOINLINE static void sp_256_mul_5(sp_digit* r, const sp_digit* a,
  19271. const sp_digit* b)
  19272. {
  19273. sp_int128 t0 = ((sp_int128)a[ 0]) * b[ 0];
  19274. sp_int128 t1 = ((sp_int128)a[ 0]) * b[ 1]
  19275. + ((sp_int128)a[ 1]) * b[ 0];
  19276. sp_int128 t2 = ((sp_int128)a[ 0]) * b[ 2]
  19277. + ((sp_int128)a[ 1]) * b[ 1]
  19278. + ((sp_int128)a[ 2]) * b[ 0];
  19279. sp_int128 t3 = ((sp_int128)a[ 0]) * b[ 3]
  19280. + ((sp_int128)a[ 1]) * b[ 2]
  19281. + ((sp_int128)a[ 2]) * b[ 1]
  19282. + ((sp_int128)a[ 3]) * b[ 0];
  19283. sp_int128 t4 = ((sp_int128)a[ 0]) * b[ 4]
  19284. + ((sp_int128)a[ 1]) * b[ 3]
  19285. + ((sp_int128)a[ 2]) * b[ 2]
  19286. + ((sp_int128)a[ 3]) * b[ 1]
  19287. + ((sp_int128)a[ 4]) * b[ 0];
  19288. sp_int128 t5 = ((sp_int128)a[ 1]) * b[ 4]
  19289. + ((sp_int128)a[ 2]) * b[ 3]
  19290. + ((sp_int128)a[ 3]) * b[ 2]
  19291. + ((sp_int128)a[ 4]) * b[ 1];
  19292. sp_int128 t6 = ((sp_int128)a[ 2]) * b[ 4]
  19293. + ((sp_int128)a[ 3]) * b[ 3]
  19294. + ((sp_int128)a[ 4]) * b[ 2];
  19295. sp_int128 t7 = ((sp_int128)a[ 3]) * b[ 4]
  19296. + ((sp_int128)a[ 4]) * b[ 3];
  19297. sp_int128 t8 = ((sp_int128)a[ 4]) * b[ 4];
  19298. t1 += t0 >> 52; r[ 0] = t0 & 0xfffffffffffffL;
  19299. t2 += t1 >> 52; r[ 1] = t1 & 0xfffffffffffffL;
  19300. t3 += t2 >> 52; r[ 2] = t2 & 0xfffffffffffffL;
  19301. t4 += t3 >> 52; r[ 3] = t3 & 0xfffffffffffffL;
  19302. t5 += t4 >> 52; r[ 4] = t4 & 0xfffffffffffffL;
  19303. t6 += t5 >> 52; r[ 5] = t5 & 0xfffffffffffffL;
  19304. t7 += t6 >> 52; r[ 6] = t6 & 0xfffffffffffffL;
  19305. t8 += t7 >> 52; r[ 7] = t7 & 0xfffffffffffffL;
  19306. r[9] = (sp_digit)(t8 >> 52);
  19307. r[8] = t8 & 0xfffffffffffffL;
  19308. }
  19309. #endif /* WOLFSSL_SP_SMALL */
  19310. #ifdef WOLFSSL_SP_SMALL
  19311. /* Square a and put result in r. (r = a * a)
  19312. *
  19313. * r A single precision integer.
  19314. * a A single precision integer.
  19315. */
  19316. SP_NOINLINE static void sp_256_sqr_5(sp_digit* r, const sp_digit* a)
  19317. {
  19318. int i;
  19319. int imax;
  19320. int k;
  19321. sp_uint128 c;
  19322. sp_uint128 t;
  19323. c = ((sp_uint128)a[4]) * a[4];
  19324. r[9] = (sp_digit)(c >> 52);
  19325. c = (c & 0xfffffffffffffL) << 52;
  19326. for (k = 7; k >= 0; k--) {
  19327. i = (k + 1) / 2;
  19328. if ((k & 1) == 0) {
  19329. c += ((sp_uint128)a[i]) * a[i];
  19330. i++;
  19331. }
  19332. if (k < 4) {
  19333. imax = k;
  19334. }
  19335. else {
  19336. imax = 4;
  19337. }
  19338. t = 0;
  19339. for (; i <= imax; i++) {
  19340. t += ((sp_uint128)a[i]) * a[k - i];
  19341. }
  19342. c += t * 2;
  19343. r[k + 2] += (sp_digit) (c >> 104);
  19344. r[k + 1] = (sp_digit)((c >> 52) & 0xfffffffffffffL);
  19345. c = (c & 0xfffffffffffffL) << 52;
  19346. }
  19347. r[0] = (sp_digit)(c >> 52);
  19348. }
  19349. #else
  19350. /* Square a and put result in r. (r = a * a)
  19351. *
  19352. * r A single precision integer.
  19353. * a A single precision integer.
  19354. */
  19355. SP_NOINLINE static void sp_256_sqr_5(sp_digit* r, const sp_digit* a)
  19356. {
  19357. sp_int128 t0 = ((sp_int128)a[ 0]) * a[ 0];
  19358. sp_int128 t1 = (((sp_int128)a[ 0]) * a[ 1]) * 2;
  19359. sp_int128 t2 = (((sp_int128)a[ 0]) * a[ 2]) * 2
  19360. + ((sp_int128)a[ 1]) * a[ 1];
  19361. sp_int128 t3 = (((sp_int128)a[ 0]) * a[ 3]
  19362. + ((sp_int128)a[ 1]) * a[ 2]) * 2;
  19363. sp_int128 t4 = (((sp_int128)a[ 0]) * a[ 4]
  19364. + ((sp_int128)a[ 1]) * a[ 3]) * 2
  19365. + ((sp_int128)a[ 2]) * a[ 2];
  19366. sp_int128 t5 = (((sp_int128)a[ 1]) * a[ 4]
  19367. + ((sp_int128)a[ 2]) * a[ 3]) * 2;
  19368. sp_int128 t6 = (((sp_int128)a[ 2]) * a[ 4]) * 2
  19369. + ((sp_int128)a[ 3]) * a[ 3];
  19370. sp_int128 t7 = (((sp_int128)a[ 3]) * a[ 4]) * 2;
  19371. sp_int128 t8 = ((sp_int128)a[ 4]) * a[ 4];
  19372. t1 += t0 >> 52; r[ 0] = t0 & 0xfffffffffffffL;
  19373. t2 += t1 >> 52; r[ 1] = t1 & 0xfffffffffffffL;
  19374. t3 += t2 >> 52; r[ 2] = t2 & 0xfffffffffffffL;
  19375. t4 += t3 >> 52; r[ 3] = t3 & 0xfffffffffffffL;
  19376. t5 += t4 >> 52; r[ 4] = t4 & 0xfffffffffffffL;
  19377. t6 += t5 >> 52; r[ 5] = t5 & 0xfffffffffffffL;
  19378. t7 += t6 >> 52; r[ 6] = t6 & 0xfffffffffffffL;
  19379. t8 += t7 >> 52; r[ 7] = t7 & 0xfffffffffffffL;
  19380. r[9] = (sp_digit)(t8 >> 52);
  19381. r[8] = t8 & 0xfffffffffffffL;
  19382. }
  19383. #endif /* WOLFSSL_SP_SMALL */
  19384. #ifdef WOLFSSL_SP_SMALL
  19385. /* Add b to a into r. (r = a + b)
  19386. *
  19387. * r A single precision integer.
  19388. * a A single precision integer.
  19389. * b A single precision integer.
  19390. */
  19391. SP_NOINLINE static int sp_256_add_5(sp_digit* r, const sp_digit* a,
  19392. const sp_digit* b)
  19393. {
  19394. int i;
  19395. for (i = 0; i < 5; i++) {
  19396. r[i] = a[i] + b[i];
  19397. }
  19398. return 0;
  19399. }
  19400. #else
  19401. /* Add b to a into r. (r = a + b)
  19402. *
  19403. * r A single precision integer.
  19404. * a A single precision integer.
  19405. * b A single precision integer.
  19406. */
  19407. SP_NOINLINE static int sp_256_add_5(sp_digit* r, const sp_digit* a,
  19408. const sp_digit* b)
  19409. {
  19410. r[ 0] = a[ 0] + b[ 0];
  19411. r[ 1] = a[ 1] + b[ 1];
  19412. r[ 2] = a[ 2] + b[ 2];
  19413. r[ 3] = a[ 3] + b[ 3];
  19414. r[ 4] = a[ 4] + b[ 4];
  19415. return 0;
  19416. }
  19417. #endif /* WOLFSSL_SP_SMALL */
  19418. #ifdef WOLFSSL_SP_SMALL
  19419. /* Sub b from a into r. (r = a - b)
  19420. *
  19421. * r A single precision integer.
  19422. * a A single precision integer.
  19423. * b A single precision integer.
  19424. */
  19425. SP_NOINLINE static int sp_256_sub_5(sp_digit* r, const sp_digit* a,
  19426. const sp_digit* b)
  19427. {
  19428. int i;
  19429. for (i = 0; i < 5; i++) {
  19430. r[i] = a[i] - b[i];
  19431. }
  19432. return 0;
  19433. }
  19434. #else
  19435. /* Sub b from a into r. (r = a - b)
  19436. *
  19437. * r A single precision integer.
  19438. * a A single precision integer.
  19439. * b A single precision integer.
  19440. */
  19441. SP_NOINLINE static int sp_256_sub_5(sp_digit* r, const sp_digit* a,
  19442. const sp_digit* b)
  19443. {
  19444. r[ 0] = a[ 0] - b[ 0];
  19445. r[ 1] = a[ 1] - b[ 1];
  19446. r[ 2] = a[ 2] - b[ 2];
  19447. r[ 3] = a[ 3] - b[ 3];
  19448. r[ 4] = a[ 4] - b[ 4];
  19449. return 0;
  19450. }
  19451. #endif /* WOLFSSL_SP_SMALL */
  19452. /* Convert an mp_int to an array of sp_digit.
  19453. *
  19454. * r A single precision integer.
  19455. * size Maximum number of bytes to convert
  19456. * a A multi-precision integer.
  19457. */
  19458. static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a)
  19459. {
  19460. #if DIGIT_BIT == 52
  19461. int i;
  19462. sp_digit j = (sp_digit)0 - (sp_digit)a->used;
  19463. int o = 0;
  19464. for (i = 0; i < size; i++) {
  19465. sp_digit mask = (sp_digit)0 - (j >> 51);
  19466. r[i] = a->dp[o] & mask;
  19467. j++;
  19468. o += (int)(j >> 51);
  19469. }
  19470. #elif DIGIT_BIT > 52
  19471. unsigned int i;
  19472. int j = 0;
  19473. word32 s = 0;
  19474. r[0] = 0;
  19475. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  19476. r[j] |= ((sp_digit)a->dp[i] << s);
  19477. r[j] &= 0xfffffffffffffL;
  19478. s = 52U - s;
  19479. if (j + 1 >= size) {
  19480. break;
  19481. }
  19482. /* lint allow cast of mismatch word32 and mp_digit */
  19483. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  19484. while ((s + 52U) <= (word32)DIGIT_BIT) {
  19485. s += 52U;
  19486. r[j] &= 0xfffffffffffffL;
  19487. if (j + 1 >= size) {
  19488. break;
  19489. }
  19490. if (s < (word32)DIGIT_BIT) {
  19491. /* lint allow cast of mismatch word32 and mp_digit */
  19492. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  19493. }
  19494. else {
  19495. r[++j] = (sp_digit)0;
  19496. }
  19497. }
  19498. s = (word32)DIGIT_BIT - s;
  19499. }
  19500. for (j++; j < size; j++) {
  19501. r[j] = 0;
  19502. }
  19503. #else
  19504. unsigned int i;
  19505. int j = 0;
  19506. int s = 0;
  19507. r[0] = 0;
  19508. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  19509. r[j] |= ((sp_digit)a->dp[i]) << s;
  19510. if (s + DIGIT_BIT >= 52) {
  19511. r[j] &= 0xfffffffffffffL;
  19512. if (j + 1 >= size) {
  19513. break;
  19514. }
  19515. s = 52 - s;
  19516. if (s == DIGIT_BIT) {
  19517. r[++j] = 0;
  19518. s = 0;
  19519. }
  19520. else {
  19521. r[++j] = a->dp[i] >> s;
  19522. s = DIGIT_BIT - s;
  19523. }
  19524. }
  19525. else {
  19526. s += DIGIT_BIT;
  19527. }
  19528. }
  19529. for (j++; j < size; j++) {
  19530. r[j] = 0;
  19531. }
  19532. #endif
  19533. }
  19534. /* Convert a point of type ecc_point to type sp_point_256.
  19535. *
  19536. * p Point of type sp_point_256 (result).
  19537. * pm Point of type ecc_point.
  19538. */
  19539. static void sp_256_point_from_ecc_point_5(sp_point_256* p,
  19540. const ecc_point* pm)
  19541. {
  19542. XMEMSET(p->x, 0, sizeof(p->x));
  19543. XMEMSET(p->y, 0, sizeof(p->y));
  19544. XMEMSET(p->z, 0, sizeof(p->z));
  19545. sp_256_from_mp(p->x, 5, pm->x);
  19546. sp_256_from_mp(p->y, 5, pm->y);
  19547. sp_256_from_mp(p->z, 5, pm->z);
  19548. p->infinity = 0;
  19549. }
  19550. /* Convert an array of sp_digit to an mp_int.
  19551. *
  19552. * a A single precision integer.
  19553. * r A multi-precision integer.
  19554. */
  19555. static int sp_256_to_mp(const sp_digit* a, mp_int* r)
  19556. {
  19557. int err;
  19558. err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT);
  19559. if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
  19560. #if DIGIT_BIT == 52
  19561. XMEMCPY(r->dp, a, sizeof(sp_digit) * 5);
  19562. r->used = 5;
  19563. mp_clamp(r);
  19564. #elif DIGIT_BIT < 52
  19565. int i;
  19566. int j = 0;
  19567. int s = 0;
  19568. r->dp[0] = 0;
  19569. for (i = 0; i < 5; i++) {
  19570. r->dp[j] |= (mp_digit)(a[i] << s);
  19571. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  19572. s = DIGIT_BIT - s;
  19573. r->dp[++j] = (mp_digit)(a[i] >> s);
  19574. while (s + DIGIT_BIT <= 52) {
  19575. s += DIGIT_BIT;
  19576. r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  19577. if (s == SP_WORD_SIZE) {
  19578. r->dp[j] = 0;
  19579. }
  19580. else {
  19581. r->dp[j] = (mp_digit)(a[i] >> s);
  19582. }
  19583. }
  19584. s = 52 - s;
  19585. }
  19586. r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;
  19587. mp_clamp(r);
  19588. #else
  19589. int i;
  19590. int j = 0;
  19591. int s = 0;
  19592. r->dp[0] = 0;
  19593. for (i = 0; i < 5; i++) {
  19594. r->dp[j] |= ((mp_digit)a[i]) << s;
  19595. if (s + 52 >= DIGIT_BIT) {
  19596. #if DIGIT_BIT != 32 && DIGIT_BIT != 64
  19597. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  19598. #endif
  19599. s = DIGIT_BIT - s;
  19600. r->dp[++j] = a[i] >> s;
  19601. s = 52 - s;
  19602. }
  19603. else {
  19604. s += 52;
  19605. }
  19606. }
  19607. r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;
  19608. mp_clamp(r);
  19609. #endif
  19610. }
  19611. return err;
  19612. }
  19613. /* Convert a point of type sp_point_256 to type ecc_point.
  19614. *
  19615. * p Point of type sp_point_256.
  19616. * pm Point of type ecc_point (result).
  19617. * returns MEMORY_E when allocation of memory in ecc_point fails otherwise
  19618. * MP_OKAY.
  19619. */
  19620. static int sp_256_point_to_ecc_point_5(const sp_point_256* p, ecc_point* pm)
  19621. {
  19622. int err;
  19623. err = sp_256_to_mp(p->x, pm->x);
  19624. if (err == MP_OKAY) {
  19625. err = sp_256_to_mp(p->y, pm->y);
  19626. }
  19627. if (err == MP_OKAY) {
  19628. err = sp_256_to_mp(p->z, pm->z);
  19629. }
  19630. return err;
  19631. }
  19632. /* Compare a with b in constant time.
  19633. *
  19634. * a A single precision integer.
  19635. * b A single precision integer.
  19636. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  19637. * respectively.
  19638. */
  19639. static sp_digit sp_256_cmp_5(const sp_digit* a, const sp_digit* b)
  19640. {
  19641. sp_digit r = 0;
  19642. #ifdef WOLFSSL_SP_SMALL
  19643. int i;
  19644. for (i=4; i>=0; i--) {
  19645. r |= (a[i] - b[i]) & ~(((sp_digit)0 - r) >> 51);
  19646. }
  19647. #else
  19648. r |= (a[ 4] - b[ 4]) & (0 - (sp_digit)1);
  19649. r |= (a[ 3] - b[ 3]) & ~(((sp_digit)0 - r) >> 51);
  19650. r |= (a[ 2] - b[ 2]) & ~(((sp_digit)0 - r) >> 51);
  19651. r |= (a[ 1] - b[ 1]) & ~(((sp_digit)0 - r) >> 51);
  19652. r |= (a[ 0] - b[ 0]) & ~(((sp_digit)0 - r) >> 51);
  19653. #endif /* WOLFSSL_SP_SMALL */
  19654. return r;
  19655. }
  19656. /* Conditionally subtract b from a using the mask m.
  19657. * m is -1 to subtract and 0 when not.
  19658. *
  19659. * r A single precision number representing condition subtract result.
  19660. * a A single precision number to subtract from.
  19661. * b A single precision number to subtract.
  19662. * m Mask value to apply.
  19663. */
  19664. static void sp_256_cond_sub_5(sp_digit* r, const sp_digit* a,
  19665. const sp_digit* b, const sp_digit m)
  19666. {
  19667. #ifdef WOLFSSL_SP_SMALL
  19668. int i;
  19669. for (i = 0; i < 5; i++) {
  19670. r[i] = a[i] - (b[i] & m);
  19671. }
  19672. #else
  19673. r[ 0] = a[ 0] - (b[ 0] & m);
  19674. r[ 1] = a[ 1] - (b[ 1] & m);
  19675. r[ 2] = a[ 2] - (b[ 2] & m);
  19676. r[ 3] = a[ 3] - (b[ 3] & m);
  19677. r[ 4] = a[ 4] - (b[ 4] & m);
  19678. #endif /* WOLFSSL_SP_SMALL */
  19679. }
  19680. /* Mul a by scalar b and add into r. (r += a * b)
  19681. *
  19682. * r A single precision integer.
  19683. * a A single precision integer.
  19684. * b A scalar.
  19685. */
  19686. SP_NOINLINE static void sp_256_mul_add_5(sp_digit* r, const sp_digit* a,
  19687. const sp_digit b)
  19688. {
  19689. #ifdef WOLFSSL_SP_SMALL
  19690. sp_int128 tb = b;
  19691. sp_int128 t[4];
  19692. int i;
  19693. t[0] = 0;
  19694. for (i = 0; i < 4; i += 4) {
  19695. t[0] += (tb * a[i+0]) + r[i+0];
  19696. t[1] = (tb * a[i+1]) + r[i+1];
  19697. t[2] = (tb * a[i+2]) + r[i+2];
  19698. t[3] = (tb * a[i+3]) + r[i+3];
  19699. r[i+0] = t[0] & 0xfffffffffffffL;
  19700. t[1] += t[0] >> 52;
  19701. r[i+1] = t[1] & 0xfffffffffffffL;
  19702. t[2] += t[1] >> 52;
  19703. r[i+2] = t[2] & 0xfffffffffffffL;
  19704. t[3] += t[2] >> 52;
  19705. r[i+3] = t[3] & 0xfffffffffffffL;
  19706. t[0] = t[3] >> 52;
  19707. }
  19708. t[0] += (tb * a[4]) + r[4];
  19709. r[4] = t[0] & 0xfffffffffffffL;
  19710. r[5] += (sp_digit)(t[0] >> 52);
  19711. #else
  19712. sp_int128 tb = b;
  19713. sp_int128 t[5];
  19714. t[ 0] = tb * a[ 0];
  19715. t[ 1] = tb * a[ 1];
  19716. t[ 2] = tb * a[ 2];
  19717. t[ 3] = tb * a[ 3];
  19718. t[ 4] = tb * a[ 4];
  19719. r[ 0] += (sp_digit) (t[ 0] & 0xfffffffffffffL);
  19720. r[ 1] += (sp_digit)((t[ 0] >> 52) + (t[ 1] & 0xfffffffffffffL));
  19721. r[ 2] += (sp_digit)((t[ 1] >> 52) + (t[ 2] & 0xfffffffffffffL));
  19722. r[ 3] += (sp_digit)((t[ 2] >> 52) + (t[ 3] & 0xfffffffffffffL));
  19723. r[ 4] += (sp_digit)((t[ 3] >> 52) + (t[ 4] & 0xfffffffffffffL));
  19724. r[ 5] += (sp_digit) (t[ 4] >> 52);
  19725. #endif /* WOLFSSL_SP_SMALL */
  19726. }
  19727. /* Normalize the values in each word to 52 bits.
  19728. *
  19729. * a Array of sp_digit to normalize.
  19730. */
  19731. static void sp_256_norm_5(sp_digit* a)
  19732. {
  19733. #ifdef WOLFSSL_SP_SMALL
  19734. int i;
  19735. for (i = 0; i < 4; i++) {
  19736. a[i+1] += a[i] >> 52;
  19737. a[i] &= 0xfffffffffffffL;
  19738. }
  19739. #else
  19740. a[1] += a[0] >> 52; a[0] &= 0xfffffffffffffL;
  19741. a[2] += a[1] >> 52; a[1] &= 0xfffffffffffffL;
  19742. a[3] += a[2] >> 52; a[2] &= 0xfffffffffffffL;
  19743. a[4] += a[3] >> 52; a[3] &= 0xfffffffffffffL;
  19744. #endif /* WOLFSSL_SP_SMALL */
  19745. }
  19746. /* Shift the result in the high 256 bits down to the bottom.
  19747. *
  19748. * r A single precision number.
  19749. * a A single precision number.
  19750. */
  19751. static void sp_256_mont_shift_5(sp_digit* r, const sp_digit* a)
  19752. {
  19753. #ifdef WOLFSSL_SP_SMALL
  19754. int i;
  19755. sp_uint64 n;
  19756. n = a[4] >> 48;
  19757. for (i = 0; i < 4; i++) {
  19758. n += (sp_uint64)a[5 + i] << 4;
  19759. r[i] = n & 0xfffffffffffffL;
  19760. n >>= 52;
  19761. }
  19762. n += (sp_uint64)a[9] << 4;
  19763. r[4] = n;
  19764. #else
  19765. sp_uint64 n;
  19766. n = a[4] >> 48;
  19767. n += (sp_uint64)a[ 5] << 4U; r[ 0] = n & 0xfffffffffffffUL; n >>= 52U;
  19768. n += (sp_uint64)a[ 6] << 4U; r[ 1] = n & 0xfffffffffffffUL; n >>= 52U;
  19769. n += (sp_uint64)a[ 7] << 4U; r[ 2] = n & 0xfffffffffffffUL; n >>= 52U;
  19770. n += (sp_uint64)a[ 8] << 4U; r[ 3] = n & 0xfffffffffffffUL; n >>= 52U;
  19771. n += (sp_uint64)a[ 9] << 4U; r[ 4] = n;
  19772. #endif /* WOLFSSL_SP_SMALL */
  19773. XMEMSET(&r[5], 0, sizeof(*r) * 5U);
  19774. }
  19775. /* Reduce the number back to 256 bits using Montgomery reduction.
  19776. *
  19777. * a A single precision number to reduce in place.
  19778. * m The single precision number representing the modulus.
  19779. * mp The digit representing the negative inverse of m mod 2^n.
  19780. */
  19781. static void sp_256_mont_reduce_order_5(sp_digit* a, const sp_digit* m, sp_digit mp)
  19782. {
  19783. int i;
  19784. sp_digit mu;
  19785. sp_digit over;
  19786. sp_256_norm_5(a + 5);
  19787. for (i=0; i<4; i++) {
  19788. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0xfffffffffffffL;
  19789. sp_256_mul_add_5(a+i, m, mu);
  19790. a[i+1] += a[i] >> 52;
  19791. }
  19792. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0xffffffffffffL;
  19793. sp_256_mul_add_5(a+i, m, mu);
  19794. a[i+1] += a[i] >> 52;
  19795. a[i] &= 0xfffffffffffffL;
  19796. sp_256_mont_shift_5(a, a);
  19797. over = a[4] >> 48;
  19798. sp_256_cond_sub_5(a, a, m, ~((over - 1) >> 63));
  19799. sp_256_norm_5(a);
  19800. }
  19801. /* Reduce the number back to 256 bits using Montgomery reduction.
  19802. *
  19803. * a A single precision number to reduce in place.
  19804. * m The single precision number representing the modulus.
  19805. * mp The digit representing the negative inverse of m mod 2^n.
  19806. */
  19807. static void sp_256_mont_reduce_5(sp_digit* a, const sp_digit* m, sp_digit mp)
  19808. {
  19809. int i;
  19810. sp_int128 t;
  19811. sp_digit am;
  19812. (void)m;
  19813. (void)mp;
  19814. for (i = 0; i < 4; i++) {
  19815. am = a[i] & 0xfffffffffffffL;
  19816. /* Fifth word of modulus word */
  19817. t = am; t *= 0x0ffffffff0000L;
  19818. a[i + 1] += (am << 44) & 0xfffffffffffffL;
  19819. a[i + 2] += am >> 8;
  19820. a[i + 3] += (am << 36) & 0xfffffffffffffL;
  19821. a[i + 4] += (am >> 16) + (t & 0xfffffffffffffL);
  19822. a[i + 5] += t >> 52;
  19823. a[i + 1] += a[i] >> 52;
  19824. }
  19825. am = a[4] & 0xffffffffffff;
  19826. /* Fifth word of modulus word */
  19827. t = am; t *= 0x0ffffffff0000L;
  19828. a[4 + 1] += (am << 44) & 0xfffffffffffffL;
  19829. a[4 + 2] += am >> 8;
  19830. a[4 + 3] += (am << 36) & 0xfffffffffffffL;
  19831. a[4 + 4] += (am >> 16) + (t & 0xfffffffffffffL);
  19832. a[4 + 5] += t >> 52;
  19833. a[0] = (a[4] >> 48) + ((a[5] << 4) & 0xfffffffffffffL);
  19834. a[1] = (a[5] >> 48) + ((a[6] << 4) & 0xfffffffffffffL);
  19835. a[2] = (a[6] >> 48) + ((a[7] << 4) & 0xfffffffffffffL);
  19836. a[3] = (a[7] >> 48) + ((a[8] << 4) & 0xfffffffffffffL);
  19837. a[4] = (a[8] >> 48) + (a[9] << 4);
  19838. a[1] += a[0] >> 52; a[0] &= 0xfffffffffffffL;
  19839. a[2] += a[1] >> 52; a[1] &= 0xfffffffffffffL;
  19840. a[3] += a[2] >> 52; a[2] &= 0xfffffffffffffL;
  19841. a[4] += a[3] >> 52; a[3] &= 0xfffffffffffffL;
  19842. /* Get the bit over, if any. */
  19843. am = a[4] >> 48;
  19844. /* Create mask. */
  19845. am = 0 - am;
  19846. a[0] -= 0x000fffffffffffffL & am;
  19847. a[1] -= 0x00000fffffffffffL & am;
  19848. /* p256_mod[2] is zero */
  19849. a[3] -= 0x0000001000000000L & am;
  19850. a[4] -= 0x0000ffffffff0000L & am;
  19851. a[1] += a[0] >> 52; a[0] &= 0xfffffffffffffL;
  19852. a[2] += a[1] >> 52; a[1] &= 0xfffffffffffffL;
  19853. a[3] += a[2] >> 52; a[2] &= 0xfffffffffffffL;
  19854. a[4] += a[3] >> 52; a[3] &= 0xfffffffffffffL;
  19855. }
  19856. /* Multiply two Montgomery form numbers mod the modulus (prime).
  19857. * (r = a * b mod m)
  19858. *
  19859. * r Result of multiplication.
  19860. * a First number to multiply in Montgomery form.
  19861. * b Second number to multiply in Montgomery form.
  19862. * m Modulus (prime).
  19863. * mp Montgomery multiplier.
  19864. */
  19865. SP_NOINLINE static void sp_256_mont_mul_5(sp_digit* r, const sp_digit* a,
  19866. const sp_digit* b, const sp_digit* m, sp_digit mp)
  19867. {
  19868. sp_256_mul_5(r, a, b);
  19869. sp_256_mont_reduce_5(r, m, mp);
  19870. }
  19871. /* Square the Montgomery form number. (r = a * a mod m)
  19872. *
  19873. * r Result of squaring.
  19874. * a Number to square in Montgomery form.
  19875. * m Modulus (prime).
  19876. * mp Montgomery multiplier.
  19877. */
  19878. SP_NOINLINE static void sp_256_mont_sqr_5(sp_digit* r, const sp_digit* a,
  19879. const sp_digit* m, sp_digit mp)
  19880. {
  19881. sp_256_sqr_5(r, a);
  19882. sp_256_mont_reduce_5(r, m, mp);
  19883. }
  19884. #if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY)
  19885. /* Square the Montgomery form number a number of times. (r = a ^ n mod m)
  19886. *
  19887. * r Result of squaring.
  19888. * a Number to square in Montgomery form.
  19889. * n Number of times to square.
  19890. * m Modulus (prime).
  19891. * mp Montgomery multiplier.
  19892. */
  19893. SP_NOINLINE static void sp_256_mont_sqr_n_5(sp_digit* r,
  19894. const sp_digit* a, int n, const sp_digit* m, sp_digit mp)
  19895. {
  19896. sp_256_mont_sqr_5(r, a, m, mp);
  19897. for (; n > 1; n--) {
  19898. sp_256_mont_sqr_5(r, r, m, mp);
  19899. }
  19900. }
  19901. #endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */
  19902. #ifdef WOLFSSL_SP_SMALL
  19903. /* Mod-2 for the P256 curve. */
  19904. static const uint64_t p256_mod_minus_2[4] = {
  19905. 0xfffffffffffffffdU,0x00000000ffffffffU,0x0000000000000000U,
  19906. 0xffffffff00000001U
  19907. };
  19908. #endif /* !WOLFSSL_SP_SMALL */
  19909. /* Invert the number, in Montgomery form, modulo the modulus (prime) of the
  19910. * P256 curve. (r = 1 / a mod m)
  19911. *
  19912. * r Inverse result.
  19913. * a Number to invert.
  19914. * td Temporary data.
  19915. */
  19916. static void sp_256_mont_inv_5(sp_digit* r, const sp_digit* a, sp_digit* td)
  19917. {
  19918. #ifdef WOLFSSL_SP_SMALL
  19919. sp_digit* t = td;
  19920. int i;
  19921. XMEMCPY(t, a, sizeof(sp_digit) * 5);
  19922. for (i=254; i>=0; i--) {
  19923. sp_256_mont_sqr_5(t, t, p256_mod, p256_mp_mod);
  19924. if (p256_mod_minus_2[i / 64] & ((sp_digit)1 << (i % 64)))
  19925. sp_256_mont_mul_5(t, t, a, p256_mod, p256_mp_mod);
  19926. }
  19927. XMEMCPY(r, t, sizeof(sp_digit) * 5);
  19928. #else
  19929. sp_digit* t1 = td;
  19930. sp_digit* t2 = td + 2 * 5;
  19931. sp_digit* t3 = td + 4 * 5;
  19932. /* 0x2 */
  19933. sp_256_mont_sqr_5(t1, a, p256_mod, p256_mp_mod);
  19934. /* 0x3 */
  19935. sp_256_mont_mul_5(t2, t1, a, p256_mod, p256_mp_mod);
  19936. /* 0xc */
  19937. sp_256_mont_sqr_n_5(t1, t2, 2, p256_mod, p256_mp_mod);
  19938. /* 0xd */
  19939. sp_256_mont_mul_5(t3, t1, a, p256_mod, p256_mp_mod);
  19940. /* 0xf */
  19941. sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod);
  19942. /* 0xf0 */
  19943. sp_256_mont_sqr_n_5(t1, t2, 4, p256_mod, p256_mp_mod);
  19944. /* 0xfd */
  19945. sp_256_mont_mul_5(t3, t3, t1, p256_mod, p256_mp_mod);
  19946. /* 0xff */
  19947. sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod);
  19948. /* 0xff00 */
  19949. sp_256_mont_sqr_n_5(t1, t2, 8, p256_mod, p256_mp_mod);
  19950. /* 0xfffd */
  19951. sp_256_mont_mul_5(t3, t3, t1, p256_mod, p256_mp_mod);
  19952. /* 0xffff */
  19953. sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod);
  19954. /* 0xffff0000 */
  19955. sp_256_mont_sqr_n_5(t1, t2, 16, p256_mod, p256_mp_mod);
  19956. /* 0xfffffffd */
  19957. sp_256_mont_mul_5(t3, t3, t1, p256_mod, p256_mp_mod);
  19958. /* 0xffffffff */
  19959. sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod);
  19960. /* 0xffffffff00000000 */
  19961. sp_256_mont_sqr_n_5(t1, t2, 32, p256_mod, p256_mp_mod);
  19962. /* 0xffffffffffffffff */
  19963. sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod);
  19964. /* 0xffffffff00000001 */
  19965. sp_256_mont_mul_5(r, t1, a, p256_mod, p256_mp_mod);
  19966. /* 0xffffffff000000010000000000000000000000000000000000000000 */
  19967. sp_256_mont_sqr_n_5(r, r, 160, p256_mod, p256_mp_mod);
  19968. /* 0xffffffff00000001000000000000000000000000ffffffffffffffff */
  19969. sp_256_mont_mul_5(r, r, t2, p256_mod, p256_mp_mod);
  19970. /* 0xffffffff00000001000000000000000000000000ffffffffffffffff00000000 */
  19971. sp_256_mont_sqr_n_5(r, r, 32, p256_mod, p256_mp_mod);
  19972. /* 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffd */
  19973. sp_256_mont_mul_5(r, r, t3, p256_mod, p256_mp_mod);
  19974. #endif /* WOLFSSL_SP_SMALL */
  19975. }
  19976. /* Map the Montgomery form projective coordinate point to an affine point.
  19977. *
  19978. * r Resulting affine coordinate point.
  19979. * p Montgomery form projective coordinate point.
  19980. * t Temporary ordinate data.
  19981. */
  19982. static void sp_256_map_5(sp_point_256* r, const sp_point_256* p,
  19983. sp_digit* t)
  19984. {
  19985. sp_digit* t1 = t;
  19986. sp_digit* t2 = t + 2*5;
  19987. sp_int64 n;
  19988. sp_256_mont_inv_5(t1, p->z, t + 2*5);
  19989. sp_256_mont_sqr_5(t2, t1, p256_mod, p256_mp_mod);
  19990. sp_256_mont_mul_5(t1, t2, t1, p256_mod, p256_mp_mod);
  19991. /* x /= z^2 */
  19992. sp_256_mont_mul_5(r->x, p->x, t2, p256_mod, p256_mp_mod);
  19993. XMEMSET(r->x + 5, 0, sizeof(sp_digit) * 5U);
  19994. sp_256_mont_reduce_5(r->x, p256_mod, p256_mp_mod);
  19995. /* Reduce x to less than modulus */
  19996. n = sp_256_cmp_5(r->x, p256_mod);
  19997. sp_256_cond_sub_5(r->x, r->x, p256_mod, ~(n >> 51));
  19998. sp_256_norm_5(r->x);
  19999. /* y /= z^3 */
  20000. sp_256_mont_mul_5(r->y, p->y, t1, p256_mod, p256_mp_mod);
  20001. XMEMSET(r->y + 5, 0, sizeof(sp_digit) * 5U);
  20002. sp_256_mont_reduce_5(r->y, p256_mod, p256_mp_mod);
  20003. /* Reduce y to less than modulus */
  20004. n = sp_256_cmp_5(r->y, p256_mod);
  20005. sp_256_cond_sub_5(r->y, r->y, p256_mod, ~(n >> 51));
  20006. sp_256_norm_5(r->y);
  20007. XMEMSET(r->z, 0, sizeof(r->z) / 2);
  20008. r->z[0] = 1;
  20009. }
  20010. /* Add two Montgomery form numbers (r = a + b % m).
  20011. *
  20012. * r Result of addition.
  20013. * a First number to add in Montgomery form.
  20014. * b Second number to add in Montgomery form.
  20015. * m Modulus (prime).
  20016. */
  20017. static void sp_256_mont_add_5(sp_digit* r, const sp_digit* a, const sp_digit* b,
  20018. const sp_digit* m)
  20019. {
  20020. sp_digit over;
  20021. (void)sp_256_add_5(r, a, b);
  20022. sp_256_norm_5(r);
  20023. over = r[4] >> 48;
  20024. sp_256_cond_sub_5(r, r, m, ~((over - 1) >> 63));
  20025. sp_256_norm_5(r);
  20026. }
  20027. /* Double a Montgomery form number (r = a + a % m).
  20028. *
  20029. * r Result of doubling.
  20030. * a Number to double in Montgomery form.
  20031. * m Modulus (prime).
  20032. */
  20033. static void sp_256_mont_dbl_5(sp_digit* r, const sp_digit* a, const sp_digit* m)
  20034. {
  20035. sp_digit over;
  20036. (void)sp_256_add_5(r, a, a);
  20037. sp_256_norm_5(r);
  20038. over = r[4] >> 48;
  20039. sp_256_cond_sub_5(r, r, m, ~((over - 1) >> 63));
  20040. sp_256_norm_5(r);
  20041. }
  20042. /* Triple a Montgomery form number (r = a + a + a % m).
  20043. *
  20044. * r Result of Tripling.
  20045. * a Number to triple in Montgomery form.
  20046. * m Modulus (prime).
  20047. */
  20048. static void sp_256_mont_tpl_5(sp_digit* r, const sp_digit* a, const sp_digit* m)
  20049. {
  20050. sp_digit over;
  20051. (void)sp_256_add_5(r, a, a);
  20052. sp_256_norm_5(r);
  20053. over = r[4] >> 48;
  20054. sp_256_cond_sub_5(r, r, m, ~((over - 1) >> 63));
  20055. sp_256_norm_5(r);
  20056. (void)sp_256_add_5(r, r, a);
  20057. sp_256_norm_5(r);
  20058. over = r[4] >> 48;
  20059. sp_256_cond_sub_5(r, r, m, ~((over - 1) >> 63));
  20060. sp_256_norm_5(r);
  20061. }
  20062. #ifdef WOLFSSL_SP_SMALL
  20063. /* Conditionally add a and b using the mask m.
  20064. * m is -1 to add and 0 when not.
  20065. *
  20066. * r A single precision number representing conditional add result.
  20067. * a A single precision number to add with.
  20068. * b A single precision number to add.
  20069. * m Mask value to apply.
  20070. */
  20071. static void sp_256_cond_add_5(sp_digit* r, const sp_digit* a,
  20072. const sp_digit* b, const sp_digit m)
  20073. {
  20074. int i;
  20075. for (i = 0; i < 5; i++) {
  20076. r[i] = a[i] + (b[i] & m);
  20077. }
  20078. }
  20079. #endif /* WOLFSSL_SP_SMALL */
  20080. #ifndef WOLFSSL_SP_SMALL
  20081. /* Conditionally add a and b using the mask m.
  20082. * m is -1 to add and 0 when not.
  20083. *
  20084. * r A single precision number representing conditional add result.
  20085. * a A single precision number to add with.
  20086. * b A single precision number to add.
  20087. * m Mask value to apply.
  20088. */
  20089. static void sp_256_cond_add_5(sp_digit* r, const sp_digit* a,
  20090. const sp_digit* b, const sp_digit m)
  20091. {
  20092. r[ 0] = a[ 0] + (b[ 0] & m);
  20093. r[ 1] = a[ 1] + (b[ 1] & m);
  20094. r[ 2] = a[ 2] + (b[ 2] & m);
  20095. r[ 3] = a[ 3] + (b[ 3] & m);
  20096. r[ 4] = a[ 4] + (b[ 4] & m);
  20097. }
  20098. #endif /* !WOLFSSL_SP_SMALL */
  20099. /* Subtract two Montgomery form numbers (r = a - b % m).
  20100. *
  20101. * r Result of subtration.
  20102. * a Number to subtract from in Montgomery form.
  20103. * b Number to subtract with in Montgomery form.
  20104. * m Modulus (prime).
  20105. */
  20106. static void sp_256_mont_sub_5(sp_digit* r, const sp_digit* a, const sp_digit* b,
  20107. const sp_digit* m)
  20108. {
  20109. (void)sp_256_sub_5(r, a, b);
  20110. sp_256_norm_5(r);
  20111. sp_256_cond_add_5(r, r, m, r[4] >> 48);
  20112. sp_256_norm_5(r);
  20113. }
  20114. /* Shift number left one bit.
  20115. * Bottom bit is lost.
  20116. *
  20117. * r Result of shift.
  20118. * a Number to shift.
  20119. */
  20120. SP_NOINLINE static void sp_256_rshift1_5(sp_digit* r, const sp_digit* a)
  20121. {
  20122. #ifdef WOLFSSL_SP_SMALL
  20123. int i;
  20124. for (i=0; i<4; i++) {
  20125. r[i] = (a[i] >> 1) + ((a[i + 1] << 51) & 0xfffffffffffffL);
  20126. }
  20127. #else
  20128. r[0] = (a[0] >> 1) + ((a[1] << 51) & 0xfffffffffffffL);
  20129. r[1] = (a[1] >> 1) + ((a[2] << 51) & 0xfffffffffffffL);
  20130. r[2] = (a[2] >> 1) + ((a[3] << 51) & 0xfffffffffffffL);
  20131. r[3] = (a[3] >> 1) + ((a[4] << 51) & 0xfffffffffffffL);
  20132. #endif
  20133. r[4] = a[4] >> 1;
  20134. }
  20135. /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)
  20136. *
  20137. * r Result of division by 2.
  20138. * a Number to divide.
  20139. * m Modulus (prime).
  20140. */
  20141. static void sp_256_mont_div2_5(sp_digit* r, const sp_digit* a,
  20142. const sp_digit* m)
  20143. {
  20144. sp_256_cond_add_5(r, a, m, 0 - (a[0] & 1));
  20145. sp_256_norm_5(r);
  20146. sp_256_rshift1_5(r, r);
  20147. }
  20148. /* Double the Montgomery form projective point p.
  20149. *
  20150. * r Result of doubling point.
  20151. * p Point to double.
  20152. * t Temporary ordinate data.
  20153. */
  20154. static void sp_256_proj_point_dbl_5(sp_point_256* r, const sp_point_256* p,
  20155. sp_digit* t)
  20156. {
  20157. sp_digit* t1 = t;
  20158. sp_digit* t2 = t + 2*5;
  20159. sp_digit* x;
  20160. sp_digit* y;
  20161. sp_digit* z;
  20162. x = r->x;
  20163. y = r->y;
  20164. z = r->z;
  20165. /* Put infinity into result. */
  20166. if (r != p) {
  20167. r->infinity = p->infinity;
  20168. }
  20169. /* T1 = Z * Z */
  20170. sp_256_mont_sqr_5(t1, p->z, p256_mod, p256_mp_mod);
  20171. /* Z = Y * Z */
  20172. sp_256_mont_mul_5(z, p->y, p->z, p256_mod, p256_mp_mod);
  20173. /* Z = 2Z */
  20174. sp_256_mont_dbl_5(z, z, p256_mod);
  20175. /* T2 = X - T1 */
  20176. sp_256_mont_sub_5(t2, p->x, t1, p256_mod);
  20177. /* T1 = X + T1 */
  20178. sp_256_mont_add_5(t1, p->x, t1, p256_mod);
  20179. /* T2 = T1 * T2 */
  20180. sp_256_mont_mul_5(t2, t1, t2, p256_mod, p256_mp_mod);
  20181. /* T1 = 3T2 */
  20182. sp_256_mont_tpl_5(t1, t2, p256_mod);
  20183. /* Y = 2Y */
  20184. sp_256_mont_dbl_5(y, p->y, p256_mod);
  20185. /* Y = Y * Y */
  20186. sp_256_mont_sqr_5(y, y, p256_mod, p256_mp_mod);
  20187. /* T2 = Y * Y */
  20188. sp_256_mont_sqr_5(t2, y, p256_mod, p256_mp_mod);
  20189. /* T2 = T2/2 */
  20190. sp_256_mont_div2_5(t2, t2, p256_mod);
  20191. /* Y = Y * X */
  20192. sp_256_mont_mul_5(y, y, p->x, p256_mod, p256_mp_mod);
  20193. /* X = T1 * T1 */
  20194. sp_256_mont_sqr_5(x, t1, p256_mod, p256_mp_mod);
  20195. /* X = X - Y */
  20196. sp_256_mont_sub_5(x, x, y, p256_mod);
  20197. /* X = X - Y */
  20198. sp_256_mont_sub_5(x, x, y, p256_mod);
  20199. /* Y = Y - X */
  20200. sp_256_mont_sub_5(y, y, x, p256_mod);
  20201. /* Y = Y * T1 */
  20202. sp_256_mont_mul_5(y, y, t1, p256_mod, p256_mp_mod);
  20203. /* Y = Y - T2 */
  20204. sp_256_mont_sub_5(y, y, t2, p256_mod);
  20205. }
  20206. #ifdef WOLFSSL_SP_NONBLOCK
  20207. typedef struct sp_256_proj_point_dbl_5_ctx {
  20208. int state;
  20209. sp_digit* t1;
  20210. sp_digit* t2;
  20211. sp_digit* x;
  20212. sp_digit* y;
  20213. sp_digit* z;
  20214. } sp_256_proj_point_dbl_5_ctx;
  20215. /* Double the Montgomery form projective point p.
  20216. *
  20217. * r Result of doubling point.
  20218. * p Point to double.
  20219. * t Temporary ordinate data.
  20220. */
  20221. static int sp_256_proj_point_dbl_5_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
  20222. const sp_point_256* p, sp_digit* t)
  20223. {
  20224. int err = FP_WOULDBLOCK;
  20225. sp_256_proj_point_dbl_5_ctx* ctx = (sp_256_proj_point_dbl_5_ctx*)sp_ctx->data;
  20226. typedef char ctx_size_test[sizeof(sp_256_proj_point_dbl_5_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  20227. (void)sizeof(ctx_size_test);
  20228. switch (ctx->state) {
  20229. case 0:
  20230. ctx->t1 = t;
  20231. ctx->t2 = t + 2*5;
  20232. ctx->x = r->x;
  20233. ctx->y = r->y;
  20234. ctx->z = r->z;
  20235. /* Put infinity into result. */
  20236. if (r != p) {
  20237. r->infinity = p->infinity;
  20238. }
  20239. ctx->state = 1;
  20240. break;
  20241. case 1:
  20242. /* T1 = Z * Z */
  20243. sp_256_mont_sqr_5(ctx->t1, p->z, p256_mod, p256_mp_mod);
  20244. ctx->state = 2;
  20245. break;
  20246. case 2:
  20247. /* Z = Y * Z */
  20248. sp_256_mont_mul_5(ctx->z, p->y, p->z, p256_mod, p256_mp_mod);
  20249. ctx->state = 3;
  20250. break;
  20251. case 3:
  20252. /* Z = 2Z */
  20253. sp_256_mont_dbl_5(ctx->z, ctx->z, p256_mod);
  20254. ctx->state = 4;
  20255. break;
  20256. case 4:
  20257. /* T2 = X - T1 */
  20258. sp_256_mont_sub_5(ctx->t2, p->x, ctx->t1, p256_mod);
  20259. ctx->state = 5;
  20260. break;
  20261. case 5:
  20262. /* T1 = X + T1 */
  20263. sp_256_mont_add_5(ctx->t1, p->x, ctx->t1, p256_mod);
  20264. ctx->state = 6;
  20265. break;
  20266. case 6:
  20267. /* T2 = T1 * T2 */
  20268. sp_256_mont_mul_5(ctx->t2, ctx->t1, ctx->t2, p256_mod, p256_mp_mod);
  20269. ctx->state = 7;
  20270. break;
  20271. case 7:
  20272. /* T1 = 3T2 */
  20273. sp_256_mont_tpl_5(ctx->t1, ctx->t2, p256_mod);
  20274. ctx->state = 8;
  20275. break;
  20276. case 8:
  20277. /* Y = 2Y */
  20278. sp_256_mont_dbl_5(ctx->y, p->y, p256_mod);
  20279. ctx->state = 9;
  20280. break;
  20281. case 9:
  20282. /* Y = Y * Y */
  20283. sp_256_mont_sqr_5(ctx->y, ctx->y, p256_mod, p256_mp_mod);
  20284. ctx->state = 10;
  20285. break;
  20286. case 10:
  20287. /* T2 = Y * Y */
  20288. sp_256_mont_sqr_5(ctx->t2, ctx->y, p256_mod, p256_mp_mod);
  20289. ctx->state = 11;
  20290. break;
  20291. case 11:
  20292. /* T2 = T2/2 */
  20293. sp_256_mont_div2_5(ctx->t2, ctx->t2, p256_mod);
  20294. ctx->state = 12;
  20295. break;
  20296. case 12:
  20297. /* Y = Y * X */
  20298. sp_256_mont_mul_5(ctx->y, ctx->y, p->x, p256_mod, p256_mp_mod);
  20299. ctx->state = 13;
  20300. break;
  20301. case 13:
  20302. /* X = T1 * T1 */
  20303. sp_256_mont_sqr_5(ctx->x, ctx->t1, p256_mod, p256_mp_mod);
  20304. ctx->state = 14;
  20305. break;
  20306. case 14:
  20307. /* X = X - Y */
  20308. sp_256_mont_sub_5(ctx->x, ctx->x, ctx->y, p256_mod);
  20309. ctx->state = 15;
  20310. break;
  20311. case 15:
  20312. /* X = X - Y */
  20313. sp_256_mont_sub_5(ctx->x, ctx->x, ctx->y, p256_mod);
  20314. ctx->state = 16;
  20315. break;
  20316. case 16:
  20317. /* Y = Y - X */
  20318. sp_256_mont_sub_5(ctx->y, ctx->y, ctx->x, p256_mod);
  20319. ctx->state = 17;
  20320. break;
  20321. case 17:
  20322. /* Y = Y * T1 */
  20323. sp_256_mont_mul_5(ctx->y, ctx->y, ctx->t1, p256_mod, p256_mp_mod);
  20324. ctx->state = 18;
  20325. break;
  20326. case 18:
  20327. /* Y = Y - T2 */
  20328. sp_256_mont_sub_5(ctx->y, ctx->y, ctx->t2, p256_mod);
  20329. ctx->state = 19;
  20330. /* fall-through */
  20331. case 19:
  20332. err = MP_OKAY;
  20333. break;
  20334. }
  20335. if (err == MP_OKAY && ctx->state != 19) {
  20336. err = FP_WOULDBLOCK;
  20337. }
  20338. return err;
  20339. }
  20340. #endif /* WOLFSSL_SP_NONBLOCK */
  20341. /* Compare two numbers to determine if they are equal.
  20342. * Constant time implementation.
  20343. *
  20344. * a First number to compare.
  20345. * b Second number to compare.
  20346. * returns 1 when equal and 0 otherwise.
  20347. */
  20348. static int sp_256_cmp_equal_5(const sp_digit* a, const sp_digit* b)
  20349. {
  20350. return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) |
  20351. (a[3] ^ b[3]) | (a[4] ^ b[4])) == 0;
  20352. }
  20353. /* Returns 1 if the number of zero.
  20354. * Implementation is constant time.
  20355. *
  20356. * a Number to check.
  20357. * returns 1 if the number is zero and 0 otherwise.
  20358. */
  20359. static int sp_256_iszero_5(const sp_digit* a)
  20360. {
  20361. return (a[0] | a[1] | a[2] | a[3] | a[4]) == 0;
  20362. }
  20363. /* Add two Montgomery form projective points.
  20364. *
  20365. * r Result of addition.
  20366. * p First point to add.
  20367. * q Second point to add.
  20368. * t Temporary ordinate data.
  20369. */
  20370. static void sp_256_proj_point_add_5(sp_point_256* r,
  20371. const sp_point_256* p, const sp_point_256* q, sp_digit* t)
  20372. {
  20373. sp_digit* t6 = t;
  20374. sp_digit* t1 = t + 2*5;
  20375. sp_digit* t2 = t + 4*5;
  20376. sp_digit* t3 = t + 6*5;
  20377. sp_digit* t4 = t + 8*5;
  20378. sp_digit* t5 = t + 10*5;
  20379. /* U1 = X1*Z2^2 */
  20380. sp_256_mont_sqr_5(t1, q->z, p256_mod, p256_mp_mod);
  20381. sp_256_mont_mul_5(t3, t1, q->z, p256_mod, p256_mp_mod);
  20382. sp_256_mont_mul_5(t1, t1, p->x, p256_mod, p256_mp_mod);
  20383. /* U2 = X2*Z1^2 */
  20384. sp_256_mont_sqr_5(t2, p->z, p256_mod, p256_mp_mod);
  20385. sp_256_mont_mul_5(t4, t2, p->z, p256_mod, p256_mp_mod);
  20386. sp_256_mont_mul_5(t2, t2, q->x, p256_mod, p256_mp_mod);
  20387. /* S1 = Y1*Z2^3 */
  20388. sp_256_mont_mul_5(t3, t3, p->y, p256_mod, p256_mp_mod);
  20389. /* S2 = Y2*Z1^3 */
  20390. sp_256_mont_mul_5(t4, t4, q->y, p256_mod, p256_mp_mod);
  20391. /* Check double */
  20392. if ((~p->infinity) & (~q->infinity) &
  20393. sp_256_cmp_equal_5(t2, t1) &
  20394. sp_256_cmp_equal_5(t4, t3)) {
  20395. sp_256_proj_point_dbl_5(r, p, t);
  20396. }
  20397. else {
  20398. sp_digit* x = t6;
  20399. sp_digit* y = t1;
  20400. sp_digit* z = t2;
  20401. /* H = U2 - U1 */
  20402. sp_256_mont_sub_5(t2, t2, t1, p256_mod);
  20403. /* R = S2 - S1 */
  20404. sp_256_mont_sub_5(t4, t4, t3, p256_mod);
  20405. /* X3 = R^2 - H^3 - 2*U1*H^2 */
  20406. sp_256_mont_sqr_5(t5, t2, p256_mod, p256_mp_mod);
  20407. sp_256_mont_mul_5(y, t1, t5, p256_mod, p256_mp_mod);
  20408. sp_256_mont_mul_5(t5, t5, t2, p256_mod, p256_mp_mod);
  20409. /* Z3 = H*Z1*Z2 */
  20410. sp_256_mont_mul_5(z, p->z, t2, p256_mod, p256_mp_mod);
  20411. sp_256_mont_mul_5(z, z, q->z, p256_mod, p256_mp_mod);
  20412. sp_256_mont_sqr_5(x, t4, p256_mod, p256_mp_mod);
  20413. sp_256_mont_sub_5(x, x, t5, p256_mod);
  20414. sp_256_mont_mul_5(t5, t5, t3, p256_mod, p256_mp_mod);
  20415. sp_256_mont_dbl_5(t3, y, p256_mod);
  20416. sp_256_mont_sub_5(x, x, t3, p256_mod);
  20417. /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
  20418. sp_256_mont_sub_5(y, y, x, p256_mod);
  20419. sp_256_mont_mul_5(y, y, t4, p256_mod, p256_mp_mod);
  20420. sp_256_mont_sub_5(y, y, t5, p256_mod);
  20421. {
  20422. int i;
  20423. sp_digit maskp = 0 - (q->infinity & (!p->infinity));
  20424. sp_digit maskq = 0 - (p->infinity & (!q->infinity));
  20425. sp_digit maskt = ~(maskp | maskq);
  20426. sp_digit inf = (sp_digit)(p->infinity & q->infinity);
  20427. for (i = 0; i < 5; i++) {
  20428. r->x[i] = (p->x[i] & maskp) | (q->x[i] & maskq) |
  20429. (x[i] & maskt);
  20430. }
  20431. for (i = 0; i < 5; i++) {
  20432. r->y[i] = (p->y[i] & maskp) | (q->y[i] & maskq) |
  20433. (y[i] & maskt);
  20434. }
  20435. for (i = 0; i < 5; i++) {
  20436. r->z[i] = (p->z[i] & maskp) | (q->z[i] & maskq) |
  20437. (z[i] & maskt);
  20438. }
  20439. r->z[0] |= inf;
  20440. r->infinity = (word32)inf;
  20441. }
  20442. }
  20443. }
  20444. #ifdef WOLFSSL_SP_NONBLOCK
  20445. typedef struct sp_256_proj_point_add_5_ctx {
  20446. int state;
  20447. sp_256_proj_point_dbl_5_ctx dbl_ctx;
  20448. const sp_point_256* ap[2];
  20449. sp_point_256* rp[2];
  20450. sp_digit* t1;
  20451. sp_digit* t2;
  20452. sp_digit* t3;
  20453. sp_digit* t4;
  20454. sp_digit* t5;
  20455. sp_digit* t6;
  20456. sp_digit* x;
  20457. sp_digit* y;
  20458. sp_digit* z;
  20459. } sp_256_proj_point_add_5_ctx;
  20460. /* Add two Montgomery form projective points.
  20461. *
  20462. * r Result of addition.
  20463. * p First point to add.
  20464. * q Second point to add.
  20465. * t Temporary ordinate data.
  20466. */
  20467. static int sp_256_proj_point_add_5_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
  20468. const sp_point_256* p, const sp_point_256* q, sp_digit* t)
  20469. {
  20470. int err = FP_WOULDBLOCK;
  20471. sp_256_proj_point_add_5_ctx* ctx = (sp_256_proj_point_add_5_ctx*)sp_ctx->data;
  20472. /* Ensure only the first point is the same as the result. */
  20473. if (q == r) {
  20474. const sp_point_256* a = p;
  20475. p = q;
  20476. q = a;
  20477. }
  20478. typedef char ctx_size_test[sizeof(sp_256_proj_point_add_5_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  20479. (void)sizeof(ctx_size_test);
  20480. switch (ctx->state) {
  20481. case 0: /* INIT */
  20482. ctx->t6 = t;
  20483. ctx->t1 = t + 2*5;
  20484. ctx->t2 = t + 4*5;
  20485. ctx->t3 = t + 6*5;
  20486. ctx->t4 = t + 8*5;
  20487. ctx->t5 = t + 10*5;
  20488. ctx->x = ctx->t6;
  20489. ctx->y = ctx->t1;
  20490. ctx->z = ctx->t2;
  20491. ctx->state = 1;
  20492. break;
  20493. case 1:
  20494. /* U1 = X1*Z2^2 */
  20495. sp_256_mont_sqr_5(ctx->t1, q->z, p256_mod, p256_mp_mod);
  20496. ctx->state = 2;
  20497. break;
  20498. case 2:
  20499. sp_256_mont_mul_5(ctx->t3, ctx->t1, q->z, p256_mod, p256_mp_mod);
  20500. ctx->state = 3;
  20501. break;
  20502. case 3:
  20503. sp_256_mont_mul_5(ctx->t1, ctx->t1, p->x, p256_mod, p256_mp_mod);
  20504. ctx->state = 4;
  20505. break;
  20506. case 4:
  20507. /* U2 = X2*Z1^2 */
  20508. sp_256_mont_sqr_5(ctx->t2, p->z, p256_mod, p256_mp_mod);
  20509. ctx->state = 5;
  20510. break;
  20511. case 5:
  20512. sp_256_mont_mul_5(ctx->t4, ctx->t2, p->z, p256_mod, p256_mp_mod);
  20513. ctx->state = 6;
  20514. break;
  20515. case 6:
  20516. sp_256_mont_mul_5(ctx->t2, ctx->t2, q->x, p256_mod, p256_mp_mod);
  20517. ctx->state = 7;
  20518. break;
  20519. case 7:
  20520. /* S1 = Y1*Z2^3 */
  20521. sp_256_mont_mul_5(ctx->t3, ctx->t3, p->y, p256_mod, p256_mp_mod);
  20522. ctx->state = 8;
  20523. break;
  20524. case 8:
  20525. /* S2 = Y2*Z1^3 */
  20526. sp_256_mont_mul_5(ctx->t4, ctx->t4, q->y, p256_mod, p256_mp_mod);
  20527. ctx->state = 9;
  20528. break;
  20529. case 9:
  20530. /* Check double */
  20531. if ((~p->infinity) & (~q->infinity) &
  20532. sp_256_cmp_equal_5(ctx->t2, ctx->t1) &
  20533. sp_256_cmp_equal_5(ctx->t4, ctx->t3)) {
  20534. XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx));
  20535. sp_256_proj_point_dbl_5(r, p, t);
  20536. ctx->state = 25;
  20537. }
  20538. else {
  20539. ctx->state = 10;
  20540. }
  20541. break;
  20542. case 10:
  20543. /* H = U2 - U1 */
  20544. sp_256_mont_sub_5(ctx->t2, ctx->t2, ctx->t1, p256_mod);
  20545. ctx->state = 11;
  20546. break;
  20547. case 11:
  20548. /* R = S2 - S1 */
  20549. sp_256_mont_sub_5(ctx->t4, ctx->t4, ctx->t3, p256_mod);
  20550. ctx->state = 12;
  20551. break;
  20552. case 12:
  20553. /* X3 = R^2 - H^3 - 2*U1*H^2 */
  20554. sp_256_mont_sqr_5(ctx->t5, ctx->t2, p256_mod, p256_mp_mod);
  20555. ctx->state = 13;
  20556. break;
  20557. case 13:
  20558. sp_256_mont_mul_5(ctx->y, ctx->t1, ctx->t5, p256_mod, p256_mp_mod);
  20559. ctx->state = 14;
  20560. break;
  20561. case 14:
  20562. sp_256_mont_mul_5(ctx->t5, ctx->t5, ctx->t2, p256_mod, p256_mp_mod);
  20563. ctx->state = 15;
  20564. break;
  20565. case 15:
  20566. /* Z3 = H*Z1*Z2 */
  20567. sp_256_mont_mul_5(ctx->z, p->z, ctx->t2, p256_mod, p256_mp_mod);
  20568. ctx->state = 16;
  20569. break;
  20570. case 16:
  20571. sp_256_mont_mul_5(ctx->z, ctx->z, q->z, p256_mod, p256_mp_mod);
  20572. ctx->state = 17;
  20573. break;
  20574. case 17:
  20575. sp_256_mont_sqr_5(ctx->x, ctx->t4, p256_mod, p256_mp_mod);
  20576. ctx->state = 18;
  20577. break;
  20578. case 18:
  20579. sp_256_mont_sub_5(ctx->x, ctx->x, ctx->t5, p256_mod);
  20580. ctx->state = 19;
  20581. break;
  20582. case 19:
  20583. sp_256_mont_mul_5(ctx->t5, ctx->t5, ctx->t3, p256_mod, p256_mp_mod);
  20584. ctx->state = 20;
  20585. break;
  20586. case 20:
  20587. sp_256_mont_dbl_5(ctx->t3, ctx->y, p256_mod);
  20588. sp_256_mont_sub_5(ctx->x, ctx->x, ctx->t3, p256_mod);
  20589. ctx->state = 21;
  20590. break;
  20591. case 21:
  20592. /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
  20593. sp_256_mont_sub_5(ctx->y, ctx->y, ctx->x, p256_mod);
  20594. ctx->state = 22;
  20595. break;
  20596. case 22:
  20597. sp_256_mont_mul_5(ctx->y, ctx->y, ctx->t4, p256_mod, p256_mp_mod);
  20598. ctx->state = 23;
  20599. break;
  20600. case 23:
  20601. sp_256_mont_sub_5(ctx->y, ctx->y, ctx->t5, p256_mod);
  20602. ctx->state = 24;
  20603. break;
  20604. case 24:
  20605. {
  20606. {
  20607. int i;
  20608. sp_digit maskp = 0 - (q->infinity & (!p->infinity));
  20609. sp_digit maskq = 0 - (p->infinity & (!q->infinity));
  20610. sp_digit maskt = ~(maskp | maskq);
  20611. sp_digit inf = (sp_digit)(p->infinity & q->infinity);
  20612. for (i = 0; i < 5; i++) {
  20613. r->x[i] = (p->x[i] & maskp) | (q->x[i] & maskq) |
  20614. (ctx->x[i] & maskt);
  20615. }
  20616. for (i = 0; i < 5; i++) {
  20617. r->y[i] = (p->y[i] & maskp) | (q->y[i] & maskq) |
  20618. (ctx->y[i] & maskt);
  20619. }
  20620. for (i = 0; i < 5; i++) {
  20621. r->z[i] = (p->z[i] & maskp) | (q->z[i] & maskq) |
  20622. (ctx->z[i] & maskt);
  20623. }
  20624. r->z[0] |= inf;
  20625. r->infinity = (word32)inf;
  20626. }
  20627. ctx->state = 25;
  20628. break;
  20629. }
  20630. case 25:
  20631. err = MP_OKAY;
  20632. break;
  20633. }
  20634. if (err == MP_OKAY && ctx->state != 25) {
  20635. err = FP_WOULDBLOCK;
  20636. }
  20637. return err;
  20638. }
  20639. #endif /* WOLFSSL_SP_NONBLOCK */
  20640. /* Multiply a number by Montgomery normalizer mod modulus (prime).
  20641. *
  20642. * r The resulting Montgomery form number.
  20643. * a The number to convert.
  20644. * m The modulus (prime).
  20645. * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise.
  20646. */
  20647. static int sp_256_mod_mul_norm_5(sp_digit* r, const sp_digit* a, const sp_digit* m)
  20648. {
  20649. #ifdef WOLFSSL_SP_SMALL_STACK
  20650. int64_t* t = NULL;
  20651. #else
  20652. int64_t t[2 * 8];
  20653. #endif
  20654. int64_t* a32 = NULL;
  20655. int64_t o;
  20656. int err = MP_OKAY;
  20657. (void)m;
  20658. #ifdef WOLFSSL_SP_SMALL_STACK
  20659. t = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 8, NULL, DYNAMIC_TYPE_ECC);
  20660. if (t == NULL)
  20661. return MEMORY_E;
  20662. #endif
  20663. if (err == MP_OKAY) {
  20664. a32 = t + 8;
  20665. a32[0] = (sp_digit)(a[0]) & 0xffffffffL;
  20666. a32[1] = (sp_digit)(a[0] >> 32U);
  20667. a32[1] |= (sp_digit)(a[1] << 20U);
  20668. a32[1] &= 0xffffffffL;
  20669. a32[2] = (sp_digit)(a[1] >> 12U) & 0xffffffffL;
  20670. a32[3] = (sp_digit)(a[1] >> 44U);
  20671. a32[3] |= (sp_digit)(a[2] << 8U);
  20672. a32[3] &= 0xffffffffL;
  20673. a32[4] = (sp_digit)(a[2] >> 24U);
  20674. a32[4] |= (sp_digit)(a[3] << 28U);
  20675. a32[4] &= 0xffffffffL;
  20676. a32[5] = (sp_digit)(a[3] >> 4U) & 0xffffffffL;
  20677. a32[6] = (sp_digit)(a[3] >> 36U);
  20678. a32[6] |= (sp_digit)(a[4] << 16U);
  20679. a32[6] &= 0xffffffffL;
  20680. a32[7] = (sp_digit)(a[4] >> 16U) & 0xffffffffL;
  20681. /* 1 1 0 -1 -1 -1 -1 0 */
  20682. t[0] = 0 + a32[0] + a32[1] - a32[3] - a32[4] - a32[5] - a32[6];
  20683. /* 0 1 1 0 -1 -1 -1 -1 */
  20684. t[1] = 0 + a32[1] + a32[2] - a32[4] - a32[5] - a32[6] - a32[7];
  20685. /* 0 0 1 1 0 -1 -1 -1 */
  20686. t[2] = 0 + a32[2] + a32[3] - a32[5] - a32[6] - a32[7];
  20687. /* -1 -1 0 2 2 1 0 -1 */
  20688. t[3] = 0 - a32[0] - a32[1] + 2 * a32[3] + 2 * a32[4] + a32[5] - a32[7];
  20689. /* 0 -1 -1 0 2 2 1 0 */
  20690. t[4] = 0 - a32[1] - a32[2] + 2 * a32[4] + 2 * a32[5] + a32[6];
  20691. /* 0 0 -1 -1 0 2 2 1 */
  20692. t[5] = 0 - a32[2] - a32[3] + 2 * a32[5] + 2 * a32[6] + a32[7];
  20693. /* -1 -1 0 0 0 1 3 2 */
  20694. t[6] = 0 - a32[0] - a32[1] + a32[5] + 3 * a32[6] + 2 * a32[7];
  20695. /* 1 0 -1 -1 -1 -1 0 3 */
  20696. t[7] = 0 + a32[0] - a32[2] - a32[3] - a32[4] - a32[5] + 3 * a32[7];
  20697. t[1] += t[0] >> 32U; t[0] &= 0xffffffffL;
  20698. t[2] += t[1] >> 32U; t[1] &= 0xffffffffL;
  20699. t[3] += t[2] >> 32U; t[2] &= 0xffffffffL;
  20700. t[4] += t[3] >> 32U; t[3] &= 0xffffffffL;
  20701. t[5] += t[4] >> 32U; t[4] &= 0xffffffffL;
  20702. t[6] += t[5] >> 32U; t[5] &= 0xffffffffL;
  20703. t[7] += t[6] >> 32U; t[6] &= 0xffffffffL;
  20704. o = t[7] >> 32U; t[7] &= 0xffffffffL;
  20705. t[0] += o;
  20706. t[3] -= o;
  20707. t[6] -= o;
  20708. t[7] += o;
  20709. t[1] += t[0] >> 32U; t[0] &= 0xffffffffL;
  20710. t[2] += t[1] >> 32U; t[1] &= 0xffffffffL;
  20711. t[3] += t[2] >> 32U; t[2] &= 0xffffffffL;
  20712. t[4] += t[3] >> 32U; t[3] &= 0xffffffffL;
  20713. t[5] += t[4] >> 32U; t[4] &= 0xffffffffL;
  20714. t[6] += t[5] >> 32U; t[5] &= 0xffffffffL;
  20715. t[7] += t[6] >> 32U; t[6] &= 0xffffffffL;
  20716. r[0] = t[0];
  20717. r[0] |= t[1] << 32U;
  20718. r[0] &= 0xfffffffffffffLL;
  20719. r[1] = (t[1] >> 20);
  20720. r[1] |= t[2] << 12U;
  20721. r[1] |= t[3] << 44U;
  20722. r[1] &= 0xfffffffffffffLL;
  20723. r[2] = (t[3] >> 8);
  20724. r[2] |= t[4] << 24U;
  20725. r[2] &= 0xfffffffffffffLL;
  20726. r[3] = (t[4] >> 28);
  20727. r[3] |= t[5] << 4U;
  20728. r[3] |= t[6] << 36U;
  20729. r[3] &= 0xfffffffffffffLL;
  20730. r[4] = (t[6] >> 16);
  20731. r[4] |= t[7] << 16U;
  20732. }
  20733. #ifdef WOLFSSL_SP_SMALL_STACK
  20734. if (t != NULL)
  20735. XFREE(t, NULL, DYNAMIC_TYPE_ECC);
  20736. #endif
  20737. return err;
  20738. }
  20739. #ifdef WOLFSSL_SP_SMALL
  20740. /* Multiply the point by the scalar and return the result.
  20741. * If map is true then convert result to affine coordinates.
  20742. *
  20743. * Small implementation using add and double that is cache attack resistant but
  20744. * allocates memory rather than use large stacks.
  20745. * 256 adds and doubles.
  20746. *
  20747. * r Resulting point.
  20748. * g Point to multiply.
  20749. * k Scalar to multiply by.
  20750. * map Indicates whether to convert result to affine.
  20751. * ct Constant time required.
  20752. * heap Heap to use for allocation.
  20753. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  20754. */
  20755. static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g,
  20756. const sp_digit* k, int map, int ct, void* heap)
  20757. {
  20758. #ifdef WOLFSSL_SP_SMALL_STACK
  20759. sp_point_256* t = NULL;
  20760. sp_digit* tmp = NULL;
  20761. #else
  20762. sp_point_256 t[3];
  20763. sp_digit tmp[2 * 5 * 6];
  20764. #endif
  20765. sp_digit n;
  20766. int i;
  20767. int c;
  20768. int y;
  20769. int err = MP_OKAY;
  20770. /* Implementation is constant time. */
  20771. (void)ct;
  20772. (void)heap;
  20773. #ifdef WOLFSSL_SP_SMALL_STACK
  20774. t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 3, heap,
  20775. DYNAMIC_TYPE_ECC);
  20776. if (t == NULL)
  20777. err = MEMORY_E;
  20778. if (err == MP_OKAY) {
  20779. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 6, heap,
  20780. DYNAMIC_TYPE_ECC);
  20781. if (tmp == NULL)
  20782. err = MEMORY_E;
  20783. }
  20784. #endif
  20785. if (err == MP_OKAY) {
  20786. XMEMSET(t, 0, sizeof(sp_point_256) * 3);
  20787. /* t[0] = {0, 0, 1} * norm */
  20788. t[0].infinity = 1;
  20789. /* t[1] = {g->x, g->y, g->z} * norm */
  20790. err = sp_256_mod_mul_norm_5(t[1].x, g->x, p256_mod);
  20791. }
  20792. if (err == MP_OKAY)
  20793. err = sp_256_mod_mul_norm_5(t[1].y, g->y, p256_mod);
  20794. if (err == MP_OKAY)
  20795. err = sp_256_mod_mul_norm_5(t[1].z, g->z, p256_mod);
  20796. if (err == MP_OKAY) {
  20797. i = 4;
  20798. c = 48;
  20799. n = k[i--] << (52 - c);
  20800. for (; ; c--) {
  20801. if (c == 0) {
  20802. if (i == -1)
  20803. break;
  20804. n = k[i--];
  20805. c = 52;
  20806. }
  20807. y = (n >> 51) & 1;
  20808. n <<= 1;
  20809. sp_256_proj_point_add_5(&t[y^1], &t[0], &t[1], tmp);
  20810. XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) +
  20811. ((size_t)&t[1] & addr_mask[y])),
  20812. sizeof(sp_point_256));
  20813. sp_256_proj_point_dbl_5(&t[2], &t[2], tmp);
  20814. XMEMCPY((void*)(((size_t)&t[0] & addr_mask[y^1]) +
  20815. ((size_t)&t[1] & addr_mask[y])), &t[2],
  20816. sizeof(sp_point_256));
  20817. }
  20818. if (map != 0) {
  20819. sp_256_map_5(r, &t[0], tmp);
  20820. }
  20821. else {
  20822. XMEMCPY(r, &t[0], sizeof(sp_point_256));
  20823. }
  20824. }
  20825. #ifdef WOLFSSL_SP_SMALL_STACK
  20826. if (tmp != NULL)
  20827. #endif
  20828. {
  20829. ForceZero(tmp, sizeof(sp_digit) * 2 * 5 * 6);
  20830. #ifdef WOLFSSL_SP_SMALL_STACK
  20831. XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
  20832. #endif
  20833. }
  20834. #ifdef WOLFSSL_SP_SMALL_STACK
  20835. if (t != NULL)
  20836. #endif
  20837. {
  20838. ForceZero(t, sizeof(sp_point_256) * 3);
  20839. #ifdef WOLFSSL_SP_SMALL_STACK
  20840. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  20841. #endif
  20842. }
  20843. return err;
  20844. }
  20845. #ifdef WOLFSSL_SP_NONBLOCK
  20846. typedef struct sp_256_ecc_mulmod_5_ctx {
  20847. int state;
  20848. union {
  20849. sp_256_proj_point_dbl_5_ctx dbl_ctx;
  20850. sp_256_proj_point_add_5_ctx add_ctx;
  20851. };
  20852. sp_point_256 t[3];
  20853. sp_digit tmp[2 * 5 * 6];
  20854. sp_digit n;
  20855. int i;
  20856. int c;
  20857. int y;
  20858. } sp_256_ecc_mulmod_5_ctx;
  20859. static int sp_256_ecc_mulmod_5_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
  20860. const sp_point_256* g, const sp_digit* k, int map, int ct, void* heap)
  20861. {
  20862. int err = FP_WOULDBLOCK;
  20863. sp_256_ecc_mulmod_5_ctx* ctx = (sp_256_ecc_mulmod_5_ctx*)sp_ctx->data;
  20864. typedef char ctx_size_test[sizeof(sp_256_ecc_mulmod_5_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  20865. (void)sizeof(ctx_size_test);
  20866. /* Implementation is constant time. */
  20867. (void)ct;
  20868. switch (ctx->state) {
  20869. case 0: /* INIT */
  20870. XMEMSET(ctx->t, 0, sizeof(sp_point_256) * 3);
  20871. ctx->i = 4;
  20872. ctx->c = 48;
  20873. ctx->n = k[ctx->i--] << (52 - ctx->c);
  20874. /* t[0] = {0, 0, 1} * norm */
  20875. ctx->t[0].infinity = 1;
  20876. ctx->state = 1;
  20877. break;
  20878. case 1: /* T1X */
  20879. /* t[1] = {g->x, g->y, g->z} * norm */
  20880. err = sp_256_mod_mul_norm_5(ctx->t[1].x, g->x, p256_mod);
  20881. ctx->state = 2;
  20882. break;
  20883. case 2: /* T1Y */
  20884. err = sp_256_mod_mul_norm_5(ctx->t[1].y, g->y, p256_mod);
  20885. ctx->state = 3;
  20886. break;
  20887. case 3: /* T1Z */
  20888. err = sp_256_mod_mul_norm_5(ctx->t[1].z, g->z, p256_mod);
  20889. ctx->state = 4;
  20890. break;
  20891. case 4: /* ADDPREP */
  20892. if (ctx->c == 0) {
  20893. if (ctx->i == -1) {
  20894. ctx->state = 7;
  20895. break;
  20896. }
  20897. ctx->n = k[ctx->i--];
  20898. ctx->c = 52;
  20899. }
  20900. ctx->y = (ctx->n >> 51) & 1;
  20901. ctx->n <<= 1;
  20902. XMEMSET(&ctx->add_ctx, 0, sizeof(ctx->add_ctx));
  20903. ctx->state = 5;
  20904. break;
  20905. case 5: /* ADD */
  20906. err = sp_256_proj_point_add_5_nb((sp_ecc_ctx_t*)&ctx->add_ctx,
  20907. &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp);
  20908. if (err == MP_OKAY) {
  20909. XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) +
  20910. ((size_t)&ctx->t[1] & addr_mask[ctx->y])),
  20911. sizeof(sp_point_256));
  20912. XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx));
  20913. ctx->state = 6;
  20914. }
  20915. break;
  20916. case 6: /* DBL */
  20917. err = sp_256_proj_point_dbl_5_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2],
  20918. &ctx->t[2], ctx->tmp);
  20919. if (err == MP_OKAY) {
  20920. XMEMCPY((void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) +
  20921. ((size_t)&ctx->t[1] & addr_mask[ctx->y])), &ctx->t[2],
  20922. sizeof(sp_point_256));
  20923. ctx->state = 4;
  20924. ctx->c--;
  20925. }
  20926. break;
  20927. case 7: /* MAP */
  20928. if (map != 0) {
  20929. sp_256_map_5(r, &ctx->t[0], ctx->tmp);
  20930. }
  20931. else {
  20932. XMEMCPY(r, &ctx->t[0], sizeof(sp_point_256));
  20933. }
  20934. err = MP_OKAY;
  20935. break;
  20936. }
  20937. if (err == MP_OKAY && ctx->state != 7) {
  20938. err = FP_WOULDBLOCK;
  20939. }
  20940. if (err != FP_WOULDBLOCK) {
  20941. ForceZero(ctx->tmp, sizeof(ctx->tmp));
  20942. ForceZero(ctx->t, sizeof(ctx->t));
  20943. }
  20944. (void)heap;
  20945. return err;
  20946. }
  20947. #endif /* WOLFSSL_SP_NONBLOCK */
  20948. #else
  20949. /* A table entry for pre-computed points. */
  20950. typedef struct sp_table_entry_256 {
  20951. sp_digit x[5];
  20952. sp_digit y[5];
  20953. } sp_table_entry_256;
  20954. /* Conditionally copy a into r using the mask m.
  20955. * m is -1 to copy and 0 when not.
  20956. *
  20957. * r A single precision number to copy over.
  20958. * a A single precision number to copy.
  20959. * m Mask value to apply.
  20960. */
  20961. static void sp_256_cond_copy_5(sp_digit* r, const sp_digit* a, const sp_digit m)
  20962. {
  20963. sp_digit t[5];
  20964. #ifdef WOLFSSL_SP_SMALL
  20965. int i;
  20966. for (i = 0; i < 5; i++) {
  20967. t[i] = r[i] ^ a[i];
  20968. }
  20969. for (i = 0; i < 5; i++) {
  20970. r[i] ^= t[i] & m;
  20971. }
  20972. #else
  20973. t[ 0] = r[ 0] ^ a[ 0];
  20974. t[ 1] = r[ 1] ^ a[ 1];
  20975. t[ 2] = r[ 2] ^ a[ 2];
  20976. t[ 3] = r[ 3] ^ a[ 3];
  20977. t[ 4] = r[ 4] ^ a[ 4];
  20978. r[ 0] ^= t[ 0] & m;
  20979. r[ 1] ^= t[ 1] & m;
  20980. r[ 2] ^= t[ 2] & m;
  20981. r[ 3] ^= t[ 3] & m;
  20982. r[ 4] ^= t[ 4] & m;
  20983. #endif /* WOLFSSL_SP_SMALL */
  20984. }
  20985. /* Double the Montgomery form projective point p a number of times.
  20986. *
  20987. * r Result of repeated doubling of point.
  20988. * p Point to double.
  20989. * n Number of times to double
  20990. * t Temporary ordinate data.
  20991. */
  20992. static void sp_256_proj_point_dbl_n_5(sp_point_256* p, int i,
  20993. sp_digit* t)
  20994. {
  20995. sp_digit* w = t;
  20996. sp_digit* a = t + 2*5;
  20997. sp_digit* b = t + 4*5;
  20998. sp_digit* t1 = t + 6*5;
  20999. sp_digit* t2 = t + 8*5;
  21000. sp_digit* x;
  21001. sp_digit* y;
  21002. sp_digit* z;
  21003. volatile int n = i;
  21004. x = p->x;
  21005. y = p->y;
  21006. z = p->z;
  21007. /* Y = 2*Y */
  21008. sp_256_mont_dbl_5(y, y, p256_mod);
  21009. /* W = Z^4 */
  21010. sp_256_mont_sqr_5(w, z, p256_mod, p256_mp_mod);
  21011. sp_256_mont_sqr_5(w, w, p256_mod, p256_mp_mod);
  21012. #ifndef WOLFSSL_SP_SMALL
  21013. while (--n > 0)
  21014. #else
  21015. while (--n >= 0)
  21016. #endif
  21017. {
  21018. /* A = 3*(X^2 - W) */
  21019. sp_256_mont_sqr_5(t1, x, p256_mod, p256_mp_mod);
  21020. sp_256_mont_sub_5(t1, t1, w, p256_mod);
  21021. sp_256_mont_tpl_5(a, t1, p256_mod);
  21022. /* B = X*Y^2 */
  21023. sp_256_mont_sqr_5(t1, y, p256_mod, p256_mp_mod);
  21024. sp_256_mont_mul_5(b, t1, x, p256_mod, p256_mp_mod);
  21025. /* X = A^2 - 2B */
  21026. sp_256_mont_sqr_5(x, a, p256_mod, p256_mp_mod);
  21027. sp_256_mont_dbl_5(t2, b, p256_mod);
  21028. sp_256_mont_sub_5(x, x, t2, p256_mod);
  21029. /* B = 2.(B - X) */
  21030. sp_256_mont_sub_5(t2, b, x, p256_mod);
  21031. sp_256_mont_dbl_5(b, t2, p256_mod);
  21032. /* Z = Z*Y */
  21033. sp_256_mont_mul_5(z, z, y, p256_mod, p256_mp_mod);
  21034. /* t1 = Y^4 */
  21035. sp_256_mont_sqr_5(t1, t1, p256_mod, p256_mp_mod);
  21036. #ifdef WOLFSSL_SP_SMALL
  21037. if (n != 0)
  21038. #endif
  21039. {
  21040. /* W = W*Y^4 */
  21041. sp_256_mont_mul_5(w, w, t1, p256_mod, p256_mp_mod);
  21042. }
  21043. /* y = 2*A*(B - X) - Y^4 */
  21044. sp_256_mont_mul_5(y, b, a, p256_mod, p256_mp_mod);
  21045. sp_256_mont_sub_5(y, y, t1, p256_mod);
  21046. }
  21047. #ifndef WOLFSSL_SP_SMALL
  21048. /* A = 3*(X^2 - W) */
  21049. sp_256_mont_sqr_5(t1, x, p256_mod, p256_mp_mod);
  21050. sp_256_mont_sub_5(t1, t1, w, p256_mod);
  21051. sp_256_mont_tpl_5(a, t1, p256_mod);
  21052. /* B = X*Y^2 */
  21053. sp_256_mont_sqr_5(t1, y, p256_mod, p256_mp_mod);
  21054. sp_256_mont_mul_5(b, t1, x, p256_mod, p256_mp_mod);
  21055. /* X = A^2 - 2B */
  21056. sp_256_mont_sqr_5(x, a, p256_mod, p256_mp_mod);
  21057. sp_256_mont_dbl_5(t2, b, p256_mod);
  21058. sp_256_mont_sub_5(x, x, t2, p256_mod);
  21059. /* B = 2.(B - X) */
  21060. sp_256_mont_sub_5(t2, b, x, p256_mod);
  21061. sp_256_mont_dbl_5(b, t2, p256_mod);
  21062. /* Z = Z*Y */
  21063. sp_256_mont_mul_5(z, z, y, p256_mod, p256_mp_mod);
  21064. /* t1 = Y^4 */
  21065. sp_256_mont_sqr_5(t1, t1, p256_mod, p256_mp_mod);
  21066. /* y = 2*A*(B - X) - Y^4 */
  21067. sp_256_mont_mul_5(y, b, a, p256_mod, p256_mp_mod);
  21068. sp_256_mont_sub_5(y, y, t1, p256_mod);
  21069. #endif /* WOLFSSL_SP_SMALL */
  21070. /* Y = Y/2 */
  21071. sp_256_mont_div2_5(y, y, p256_mod);
  21072. }
  21073. /* Double the Montgomery form projective point p a number of times.
  21074. *
  21075. * r Result of repeated doubling of point.
  21076. * p Point to double.
  21077. * n Number of times to double
  21078. * t Temporary ordinate data.
  21079. */
  21080. static void sp_256_proj_point_dbl_n_store_5(sp_point_256* r,
  21081. const sp_point_256* p, int n, int m, sp_digit* t)
  21082. {
  21083. sp_digit* w = t;
  21084. sp_digit* a = t + 2*5;
  21085. sp_digit* b = t + 4*5;
  21086. sp_digit* t1 = t + 6*5;
  21087. sp_digit* t2 = t + 8*5;
  21088. sp_digit* x = r[2*m].x;
  21089. sp_digit* y = r[(1<<n)*m].y;
  21090. sp_digit* z = r[2*m].z;
  21091. int i;
  21092. int j;
  21093. for (i=0; i<5; i++) {
  21094. x[i] = p->x[i];
  21095. }
  21096. for (i=0; i<5; i++) {
  21097. y[i] = p->y[i];
  21098. }
  21099. for (i=0; i<5; i++) {
  21100. z[i] = p->z[i];
  21101. }
  21102. /* Y = 2*Y */
  21103. sp_256_mont_dbl_5(y, y, p256_mod);
  21104. /* W = Z^4 */
  21105. sp_256_mont_sqr_5(w, z, p256_mod, p256_mp_mod);
  21106. sp_256_mont_sqr_5(w, w, p256_mod, p256_mp_mod);
  21107. j = m;
  21108. for (i=1; i<=n; i++) {
  21109. j *= 2;
  21110. /* A = 3*(X^2 - W) */
  21111. sp_256_mont_sqr_5(t1, x, p256_mod, p256_mp_mod);
  21112. sp_256_mont_sub_5(t1, t1, w, p256_mod);
  21113. sp_256_mont_tpl_5(a, t1, p256_mod);
  21114. /* B = X*Y^2 */
  21115. sp_256_mont_sqr_5(t1, y, p256_mod, p256_mp_mod);
  21116. sp_256_mont_mul_5(b, t1, x, p256_mod, p256_mp_mod);
  21117. x = r[j].x;
  21118. /* X = A^2 - 2B */
  21119. sp_256_mont_sqr_5(x, a, p256_mod, p256_mp_mod);
  21120. sp_256_mont_dbl_5(t2, b, p256_mod);
  21121. sp_256_mont_sub_5(x, x, t2, p256_mod);
  21122. /* B = 2.(B - X) */
  21123. sp_256_mont_sub_5(t2, b, x, p256_mod);
  21124. sp_256_mont_dbl_5(b, t2, p256_mod);
  21125. /* Z = Z*Y */
  21126. sp_256_mont_mul_5(r[j].z, z, y, p256_mod, p256_mp_mod);
  21127. z = r[j].z;
  21128. /* t1 = Y^4 */
  21129. sp_256_mont_sqr_5(t1, t1, p256_mod, p256_mp_mod);
  21130. if (i != n) {
  21131. /* W = W*Y^4 */
  21132. sp_256_mont_mul_5(w, w, t1, p256_mod, p256_mp_mod);
  21133. }
  21134. /* y = 2*A*(B - X) - Y^4 */
  21135. sp_256_mont_mul_5(y, b, a, p256_mod, p256_mp_mod);
  21136. sp_256_mont_sub_5(y, y, t1, p256_mod);
  21137. /* Y = Y/2 */
  21138. sp_256_mont_div2_5(r[j].y, y, p256_mod);
  21139. r[j].infinity = 0;
  21140. }
  21141. }
  21142. /* Add two Montgomery form projective points.
  21143. *
  21144. * ra Result of addition.
  21145. * rs Result of subtraction.
  21146. * p First point to add.
  21147. * q Second point to add.
  21148. * t Temporary ordinate data.
  21149. */
  21150. static void sp_256_proj_point_add_sub_5(sp_point_256* ra,
  21151. sp_point_256* rs, const sp_point_256* p, const sp_point_256* q,
  21152. sp_digit* t)
  21153. {
  21154. sp_digit* t1 = t;
  21155. sp_digit* t2 = t + 2*5;
  21156. sp_digit* t3 = t + 4*5;
  21157. sp_digit* t4 = t + 6*5;
  21158. sp_digit* t5 = t + 8*5;
  21159. sp_digit* t6 = t + 10*5;
  21160. sp_digit* xa = ra->x;
  21161. sp_digit* ya = ra->y;
  21162. sp_digit* za = ra->z;
  21163. sp_digit* xs = rs->x;
  21164. sp_digit* ys = rs->y;
  21165. sp_digit* zs = rs->z;
  21166. XMEMCPY(xa, p->x, sizeof(p->x) / 2);
  21167. XMEMCPY(ya, p->y, sizeof(p->y) / 2);
  21168. XMEMCPY(za, p->z, sizeof(p->z) / 2);
  21169. ra->infinity = 0;
  21170. rs->infinity = 0;
  21171. /* U1 = X1*Z2^2 */
  21172. sp_256_mont_sqr_5(t1, q->z, p256_mod, p256_mp_mod);
  21173. sp_256_mont_mul_5(t3, t1, q->z, p256_mod, p256_mp_mod);
  21174. sp_256_mont_mul_5(t1, t1, xa, p256_mod, p256_mp_mod);
  21175. /* U2 = X2*Z1^2 */
  21176. sp_256_mont_sqr_5(t2, za, p256_mod, p256_mp_mod);
  21177. sp_256_mont_mul_5(t4, t2, za, p256_mod, p256_mp_mod);
  21178. sp_256_mont_mul_5(t2, t2, q->x, p256_mod, p256_mp_mod);
  21179. /* S1 = Y1*Z2^3 */
  21180. sp_256_mont_mul_5(t3, t3, ya, p256_mod, p256_mp_mod);
  21181. /* S2 = Y2*Z1^3 */
  21182. sp_256_mont_mul_5(t4, t4, q->y, p256_mod, p256_mp_mod);
  21183. /* H = U2 - U1 */
  21184. sp_256_mont_sub_5(t2, t2, t1, p256_mod);
  21185. /* RS = S2 + S1 */
  21186. sp_256_mont_add_5(t6, t4, t3, p256_mod);
  21187. /* R = S2 - S1 */
  21188. sp_256_mont_sub_5(t4, t4, t3, p256_mod);
  21189. /* Z3 = H*Z1*Z2 */
  21190. /* ZS = H*Z1*Z2 */
  21191. sp_256_mont_mul_5(za, za, q->z, p256_mod, p256_mp_mod);
  21192. sp_256_mont_mul_5(za, za, t2, p256_mod, p256_mp_mod);
  21193. XMEMCPY(zs, za, sizeof(p->z)/2);
  21194. /* X3 = R^2 - H^3 - 2*U1*H^2 */
  21195. /* XS = RS^2 - H^3 - 2*U1*H^2 */
  21196. sp_256_mont_sqr_5(xa, t4, p256_mod, p256_mp_mod);
  21197. sp_256_mont_sqr_5(xs, t6, p256_mod, p256_mp_mod);
  21198. sp_256_mont_sqr_5(t5, t2, p256_mod, p256_mp_mod);
  21199. sp_256_mont_mul_5(ya, t1, t5, p256_mod, p256_mp_mod);
  21200. sp_256_mont_mul_5(t5, t5, t2, p256_mod, p256_mp_mod);
  21201. sp_256_mont_sub_5(xa, xa, t5, p256_mod);
  21202. sp_256_mont_sub_5(xs, xs, t5, p256_mod);
  21203. sp_256_mont_dbl_5(t1, ya, p256_mod);
  21204. sp_256_mont_sub_5(xa, xa, t1, p256_mod);
  21205. sp_256_mont_sub_5(xs, xs, t1, p256_mod);
  21206. /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
  21207. /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */
  21208. sp_256_mont_sub_5(ys, ya, xs, p256_mod);
  21209. sp_256_mont_sub_5(ya, ya, xa, p256_mod);
  21210. sp_256_mont_mul_5(ya, ya, t4, p256_mod, p256_mp_mod);
  21211. sp_256_sub_5(t6, p256_mod, t6);
  21212. sp_256_mont_mul_5(ys, ys, t6, p256_mod, p256_mp_mod);
  21213. sp_256_mont_mul_5(t5, t5, t3, p256_mod, p256_mp_mod);
  21214. sp_256_mont_sub_5(ya, ya, t5, p256_mod);
  21215. sp_256_mont_sub_5(ys, ys, t5, p256_mod);
  21216. }
  21217. /* Structure used to describe recoding of scalar multiplication. */
  21218. typedef struct ecc_recode_256 {
  21219. /* Index into pre-computation table. */
  21220. uint8_t i;
  21221. /* Use the negative of the point. */
  21222. uint8_t neg;
  21223. } ecc_recode_256;
  21224. /* The index into pre-computation table to use. */
  21225. static const uint8_t recode_index_5_6[66] = {
  21226. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  21227. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  21228. 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
  21229. 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
  21230. 0, 1,
  21231. };
  21232. /* Whether to negate y-ordinate. */
  21233. static const uint8_t recode_neg_5_6[66] = {
  21234. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  21235. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  21236. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  21237. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  21238. 0, 0,
  21239. };
  21240. /* Recode the scalar for multiplication using pre-computed values and
  21241. * subtraction.
  21242. *
  21243. * k Scalar to multiply by.
  21244. * v Vector of operations to perform.
  21245. */
  21246. static void sp_256_ecc_recode_6_5(const sp_digit* k, ecc_recode_256* v)
  21247. {
  21248. int i;
  21249. int j;
  21250. uint8_t y;
  21251. int carry = 0;
  21252. int o;
  21253. sp_digit n;
  21254. j = 0;
  21255. n = k[j];
  21256. o = 0;
  21257. for (i=0; i<43; i++) {
  21258. y = (int8_t)n;
  21259. if (o + 6 < 52) {
  21260. y &= 0x3f;
  21261. n >>= 6;
  21262. o += 6;
  21263. }
  21264. else if (o + 6 == 52) {
  21265. n >>= 6;
  21266. if (++j < 5)
  21267. n = k[j];
  21268. o = 0;
  21269. }
  21270. else if (++j < 5) {
  21271. n = k[j];
  21272. y |= (uint8_t)((n << (52 - o)) & 0x3f);
  21273. o -= 46;
  21274. n >>= o;
  21275. }
  21276. y += (uint8_t)carry;
  21277. v[i].i = recode_index_5_6[y];
  21278. v[i].neg = recode_neg_5_6[y];
  21279. carry = (y >> 6) + v[i].neg;
  21280. }
  21281. }
  21282. #ifndef WC_NO_CACHE_RESISTANT
  21283. /* Touch each possible point that could be being copied.
  21284. *
  21285. * r Point to copy into.
  21286. * table Table - start of the entries to access
  21287. * idx Index of entry to retrieve.
  21288. */
  21289. static void sp_256_get_point_33_5(sp_point_256* r, const sp_point_256* table,
  21290. int idx)
  21291. {
  21292. int i;
  21293. sp_digit mask;
  21294. r->x[0] = 0;
  21295. r->x[1] = 0;
  21296. r->x[2] = 0;
  21297. r->x[3] = 0;
  21298. r->x[4] = 0;
  21299. r->y[0] = 0;
  21300. r->y[1] = 0;
  21301. r->y[2] = 0;
  21302. r->y[3] = 0;
  21303. r->y[4] = 0;
  21304. r->z[0] = 0;
  21305. r->z[1] = 0;
  21306. r->z[2] = 0;
  21307. r->z[3] = 0;
  21308. r->z[4] = 0;
  21309. for (i = 1; i < 33; i++) {
  21310. mask = 0 - (i == idx);
  21311. r->x[0] |= mask & table[i].x[0];
  21312. r->x[1] |= mask & table[i].x[1];
  21313. r->x[2] |= mask & table[i].x[2];
  21314. r->x[3] |= mask & table[i].x[3];
  21315. r->x[4] |= mask & table[i].x[4];
  21316. r->y[0] |= mask & table[i].y[0];
  21317. r->y[1] |= mask & table[i].y[1];
  21318. r->y[2] |= mask & table[i].y[2];
  21319. r->y[3] |= mask & table[i].y[3];
  21320. r->y[4] |= mask & table[i].y[4];
  21321. r->z[0] |= mask & table[i].z[0];
  21322. r->z[1] |= mask & table[i].z[1];
  21323. r->z[2] |= mask & table[i].z[2];
  21324. r->z[3] |= mask & table[i].z[3];
  21325. r->z[4] |= mask & table[i].z[4];
  21326. }
  21327. }
  21328. #endif /* !WC_NO_CACHE_RESISTANT */
  21329. /* Multiply the point by the scalar and return the result.
  21330. * If map is true then convert result to affine coordinates.
  21331. *
  21332. * Window technique of 6 bits. (Add-Sub variation.)
  21333. * Calculate 0..32 times the point. Use function that adds and
  21334. * subtracts the same two points.
  21335. * Recode to add or subtract one of the computed points.
  21336. * Double to push up.
  21337. * NOT a sliding window.
  21338. *
  21339. * r Resulting point.
  21340. * g Point to multiply.
  21341. * k Scalar to multiply by.
  21342. * map Indicates whether to convert result to affine.
  21343. * ct Constant time required.
  21344. * heap Heap to use for allocation.
  21345. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  21346. */
  21347. static int sp_256_ecc_mulmod_win_add_sub_5(sp_point_256* r, const sp_point_256* g,
  21348. const sp_digit* k, int map, int ct, void* heap)
  21349. {
  21350. #ifdef WOLFSSL_SP_SMALL_STACK
  21351. sp_point_256* t = NULL;
  21352. sp_digit* tmp = NULL;
  21353. #else
  21354. sp_point_256 t[33+2];
  21355. sp_digit tmp[2 * 5 * 6];
  21356. #endif
  21357. sp_point_256* rt = NULL;
  21358. sp_point_256* p = NULL;
  21359. sp_digit* negy;
  21360. int i;
  21361. ecc_recode_256 v[43];
  21362. int err = MP_OKAY;
  21363. /* Constant time used for cache attack resistance implementation. */
  21364. (void)ct;
  21365. (void)heap;
  21366. #ifdef WOLFSSL_SP_SMALL_STACK
  21367. t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) *
  21368. (33+2), heap, DYNAMIC_TYPE_ECC);
  21369. if (t == NULL)
  21370. err = MEMORY_E;
  21371. if (err == MP_OKAY) {
  21372. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 6,
  21373. heap, DYNAMIC_TYPE_ECC);
  21374. if (tmp == NULL)
  21375. err = MEMORY_E;
  21376. }
  21377. #endif
  21378. if (err == MP_OKAY) {
  21379. rt = t + 33;
  21380. p = t + 33+1;
  21381. /* t[0] = {0, 0, 1} * norm */
  21382. XMEMSET(&t[0], 0, sizeof(t[0]));
  21383. t[0].infinity = 1;
  21384. /* t[1] = {g->x, g->y, g->z} * norm */
  21385. err = sp_256_mod_mul_norm_5(t[1].x, g->x, p256_mod);
  21386. }
  21387. if (err == MP_OKAY) {
  21388. err = sp_256_mod_mul_norm_5(t[1].y, g->y, p256_mod);
  21389. }
  21390. if (err == MP_OKAY) {
  21391. err = sp_256_mod_mul_norm_5(t[1].z, g->z, p256_mod);
  21392. }
  21393. if (err == MP_OKAY) {
  21394. t[1].infinity = 0;
  21395. /* t[2] ... t[32] */
  21396. sp_256_proj_point_dbl_n_store_5(t, &t[ 1], 5, 1, tmp);
  21397. sp_256_proj_point_add_5(&t[ 3], &t[ 2], &t[ 1], tmp);
  21398. sp_256_proj_point_dbl_5(&t[ 6], &t[ 3], tmp);
  21399. sp_256_proj_point_add_sub_5(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp);
  21400. sp_256_proj_point_dbl_5(&t[10], &t[ 5], tmp);
  21401. sp_256_proj_point_add_sub_5(&t[11], &t[ 9], &t[10], &t[ 1], tmp);
  21402. sp_256_proj_point_dbl_5(&t[12], &t[ 6], tmp);
  21403. sp_256_proj_point_dbl_5(&t[14], &t[ 7], tmp);
  21404. sp_256_proj_point_add_sub_5(&t[15], &t[13], &t[14], &t[ 1], tmp);
  21405. sp_256_proj_point_dbl_5(&t[18], &t[ 9], tmp);
  21406. sp_256_proj_point_add_sub_5(&t[19], &t[17], &t[18], &t[ 1], tmp);
  21407. sp_256_proj_point_dbl_5(&t[20], &t[10], tmp);
  21408. sp_256_proj_point_dbl_5(&t[22], &t[11], tmp);
  21409. sp_256_proj_point_add_sub_5(&t[23], &t[21], &t[22], &t[ 1], tmp);
  21410. sp_256_proj_point_dbl_5(&t[24], &t[12], tmp);
  21411. sp_256_proj_point_dbl_5(&t[26], &t[13], tmp);
  21412. sp_256_proj_point_add_sub_5(&t[27], &t[25], &t[26], &t[ 1], tmp);
  21413. sp_256_proj_point_dbl_5(&t[28], &t[14], tmp);
  21414. sp_256_proj_point_dbl_5(&t[30], &t[15], tmp);
  21415. sp_256_proj_point_add_sub_5(&t[31], &t[29], &t[30], &t[ 1], tmp);
  21416. negy = t[0].y;
  21417. sp_256_ecc_recode_6_5(k, v);
  21418. i = 42;
  21419. #ifndef WC_NO_CACHE_RESISTANT
  21420. if (ct) {
  21421. sp_256_get_point_33_5(rt, t, v[i].i);
  21422. rt->infinity = !v[i].i;
  21423. }
  21424. else
  21425. #endif
  21426. {
  21427. XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_256));
  21428. }
  21429. for (--i; i>=0; i--) {
  21430. sp_256_proj_point_dbl_n_5(rt, 6, tmp);
  21431. #ifndef WC_NO_CACHE_RESISTANT
  21432. if (ct) {
  21433. sp_256_get_point_33_5(p, t, v[i].i);
  21434. p->infinity = !v[i].i;
  21435. }
  21436. else
  21437. #endif
  21438. {
  21439. XMEMCPY(p, &t[v[i].i], sizeof(sp_point_256));
  21440. }
  21441. sp_256_sub_5(negy, p256_mod, p->y);
  21442. sp_256_norm_5(negy);
  21443. sp_256_cond_copy_5(p->y, negy, (sp_digit)0 - v[i].neg);
  21444. sp_256_proj_point_add_5(rt, rt, p, tmp);
  21445. }
  21446. if (map != 0) {
  21447. sp_256_map_5(r, rt, tmp);
  21448. }
  21449. else {
  21450. XMEMCPY(r, rt, sizeof(sp_point_256));
  21451. }
  21452. }
  21453. #ifdef WOLFSSL_SP_SMALL_STACK
  21454. if (t != NULL)
  21455. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  21456. if (tmp != NULL)
  21457. XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
  21458. #endif
  21459. return err;
  21460. }
  21461. #ifdef FP_ECC
  21462. #endif /* FP_ECC */
  21463. /* Add two Montgomery form projective points. The second point has a q value of
  21464. * one.
  21465. * Only the first point can be the same pointer as the result point.
  21466. *
  21467. * r Result of addition.
  21468. * p First point to add.
  21469. * q Second point to add.
  21470. * t Temporary ordinate data.
  21471. */
  21472. static void sp_256_proj_point_add_qz1_5(sp_point_256* r,
  21473. const sp_point_256* p, const sp_point_256* q, sp_digit* t)
  21474. {
  21475. sp_digit* t2 = t;
  21476. sp_digit* t3 = t + 2*5;
  21477. sp_digit* t6 = t + 4*5;
  21478. sp_digit* t1 = t + 6*5;
  21479. sp_digit* t4 = t + 8*5;
  21480. sp_digit* t5 = t + 10*5;
  21481. /* Calculate values to subtract from P->x and P->y. */
  21482. /* U2 = X2*Z1^2 */
  21483. sp_256_mont_sqr_5(t2, p->z, p256_mod, p256_mp_mod);
  21484. sp_256_mont_mul_5(t4, t2, p->z, p256_mod, p256_mp_mod);
  21485. sp_256_mont_mul_5(t2, t2, q->x, p256_mod, p256_mp_mod);
  21486. /* S2 = Y2*Z1^3 */
  21487. sp_256_mont_mul_5(t4, t4, q->y, p256_mod, p256_mp_mod);
  21488. if ((~p->infinity) & (~q->infinity) &
  21489. sp_256_cmp_equal_5(p->x, t2) &
  21490. sp_256_cmp_equal_5(p->y, t4)) {
  21491. sp_256_proj_point_dbl_5(r, p, t);
  21492. }
  21493. else {
  21494. sp_digit* x = t2;
  21495. sp_digit* y = t3;
  21496. sp_digit* z = t6;
  21497. /* H = U2 - X1 */
  21498. sp_256_mont_sub_5(t2, t2, p->x, p256_mod);
  21499. /* R = S2 - Y1 */
  21500. sp_256_mont_sub_5(t4, t4, p->y, p256_mod);
  21501. /* Z3 = H*Z1 */
  21502. sp_256_mont_mul_5(z, p->z, t2, p256_mod, p256_mp_mod);
  21503. /* X3 = R^2 - H^3 - 2*X1*H^2 */
  21504. sp_256_mont_sqr_5(t1, t2, p256_mod, p256_mp_mod);
  21505. sp_256_mont_mul_5(t3, p->x, t1, p256_mod, p256_mp_mod);
  21506. sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);
  21507. sp_256_mont_sqr_5(t2, t4, p256_mod, p256_mp_mod);
  21508. sp_256_mont_sub_5(t2, t2, t1, p256_mod);
  21509. sp_256_mont_dbl_5(t5, t3, p256_mod);
  21510. sp_256_mont_sub_5(x, t2, t5, p256_mod);
  21511. /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */
  21512. sp_256_mont_sub_5(t3, t3, x, p256_mod);
  21513. sp_256_mont_mul_5(t3, t3, t4, p256_mod, p256_mp_mod);
  21514. sp_256_mont_mul_5(t1, t1, p->y, p256_mod, p256_mp_mod);
  21515. sp_256_mont_sub_5(y, t3, t1, p256_mod);
  21516. {
  21517. int i;
  21518. sp_digit maskp = 0 - (q->infinity & (!p->infinity));
  21519. sp_digit maskq = 0 - (p->infinity & (!q->infinity));
  21520. sp_digit maskt = ~(maskp | maskq);
  21521. sp_digit inf = (sp_digit)(p->infinity & q->infinity);
  21522. for (i = 0; i < 5; i++) {
  21523. r->x[i] = (p->x[i] & maskp) | (q->x[i] & maskq) |
  21524. (x[i] & maskt);
  21525. }
  21526. for (i = 0; i < 5; i++) {
  21527. r->y[i] = (p->y[i] & maskp) | (q->y[i] & maskq) |
  21528. (y[i] & maskt);
  21529. }
  21530. for (i = 0; i < 5; i++) {
  21531. r->z[i] = (p->z[i] & maskp) | (q->z[i] & maskq) |
  21532. (z[i] & maskt);
  21533. }
  21534. r->z[0] |= inf;
  21535. r->infinity = (word32)inf;
  21536. }
  21537. }
  21538. }
  21539. #ifdef FP_ECC
  21540. /* Convert the projective point to affine.
  21541. * Ordinates are in Montgomery form.
  21542. *
  21543. * a Point to convert.
  21544. * t Temporary data.
  21545. */
  21546. static void sp_256_proj_to_affine_5(sp_point_256* a, sp_digit* t)
  21547. {
  21548. sp_digit* t1 = t;
  21549. sp_digit* t2 = t + 2 * 5;
  21550. sp_digit* tmp = t + 4 * 5;
  21551. sp_256_mont_inv_5(t1, a->z, tmp);
  21552. sp_256_mont_sqr_5(t2, t1, p256_mod, p256_mp_mod);
  21553. sp_256_mont_mul_5(t1, t2, t1, p256_mod, p256_mp_mod);
  21554. sp_256_mont_mul_5(a->x, a->x, t2, p256_mod, p256_mp_mod);
  21555. sp_256_mont_mul_5(a->y, a->y, t1, p256_mod, p256_mp_mod);
  21556. XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod));
  21557. }
  21558. /* Generate the pre-computed table of points for the base point.
  21559. *
  21560. * width = 8
  21561. * 256 entries
  21562. * 32 bits between
  21563. *
  21564. * a The base point.
  21565. * table Place to store generated point data.
  21566. * tmp Temporary data.
  21567. * heap Heap to use for allocation.
  21568. */
  21569. static int sp_256_gen_stripe_table_5(const sp_point_256* a,
  21570. sp_table_entry_256* table, sp_digit* tmp, void* heap)
  21571. {
  21572. #ifdef WOLFSSL_SP_SMALL_STACK
  21573. sp_point_256* t = NULL;
  21574. #else
  21575. sp_point_256 t[3];
  21576. #endif
  21577. sp_point_256* s1 = NULL;
  21578. sp_point_256* s2 = NULL;
  21579. int i;
  21580. int j;
  21581. int err = MP_OKAY;
  21582. (void)heap;
  21583. #ifdef WOLFSSL_SP_SMALL_STACK
  21584. t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 3, heap,
  21585. DYNAMIC_TYPE_ECC);
  21586. if (t == NULL)
  21587. err = MEMORY_E;
  21588. #endif
  21589. if (err == MP_OKAY) {
  21590. s1 = t + 1;
  21591. s2 = t + 2;
  21592. err = sp_256_mod_mul_norm_5(t->x, a->x, p256_mod);
  21593. }
  21594. if (err == MP_OKAY) {
  21595. err = sp_256_mod_mul_norm_5(t->y, a->y, p256_mod);
  21596. }
  21597. if (err == MP_OKAY) {
  21598. err = sp_256_mod_mul_norm_5(t->z, a->z, p256_mod);
  21599. }
  21600. if (err == MP_OKAY) {
  21601. t->infinity = 0;
  21602. sp_256_proj_to_affine_5(t, tmp);
  21603. XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));
  21604. s1->infinity = 0;
  21605. XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));
  21606. s2->infinity = 0;
  21607. /* table[0] = {0, 0, infinity} */
  21608. XMEMSET(&table[0], 0, sizeof(sp_table_entry_256));
  21609. /* table[1] = Affine version of 'a' in Montgomery form */
  21610. XMEMCPY(table[1].x, t->x, sizeof(table->x));
  21611. XMEMCPY(table[1].y, t->y, sizeof(table->y));
  21612. for (i=1; i<8; i++) {
  21613. sp_256_proj_point_dbl_n_5(t, 32, tmp);
  21614. sp_256_proj_to_affine_5(t, tmp);
  21615. XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));
  21616. XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));
  21617. }
  21618. for (i=1; i<8; i++) {
  21619. XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));
  21620. XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));
  21621. for (j=(1<<i)+1; j<(1<<(i+1)); j++) {
  21622. XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));
  21623. XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));
  21624. sp_256_proj_point_add_qz1_5(t, s1, s2, tmp);
  21625. sp_256_proj_to_affine_5(t, tmp);
  21626. XMEMCPY(table[j].x, t->x, sizeof(table->x));
  21627. XMEMCPY(table[j].y, t->y, sizeof(table->y));
  21628. }
  21629. }
  21630. }
  21631. #ifdef WOLFSSL_SP_SMALL_STACK
  21632. if (t != NULL)
  21633. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  21634. #endif
  21635. return err;
  21636. }
  21637. #endif /* FP_ECC */
  21638. #ifndef WC_NO_CACHE_RESISTANT
  21639. /* Touch each possible entry that could be being copied.
  21640. *
  21641. * r Point to copy into.
  21642. * table Table - start of the entries to access
  21643. * idx Index of entry to retrieve.
  21644. */
  21645. static void sp_256_get_entry_256_5(sp_point_256* r,
  21646. const sp_table_entry_256* table, int idx)
  21647. {
  21648. int i;
  21649. sp_digit mask;
  21650. r->x[0] = 0;
  21651. r->x[1] = 0;
  21652. r->x[2] = 0;
  21653. r->x[3] = 0;
  21654. r->x[4] = 0;
  21655. r->y[0] = 0;
  21656. r->y[1] = 0;
  21657. r->y[2] = 0;
  21658. r->y[3] = 0;
  21659. r->y[4] = 0;
  21660. for (i = 1; i < 256; i++) {
  21661. mask = 0 - (i == idx);
  21662. r->x[0] |= mask & table[i].x[0];
  21663. r->x[1] |= mask & table[i].x[1];
  21664. r->x[2] |= mask & table[i].x[2];
  21665. r->x[3] |= mask & table[i].x[3];
  21666. r->x[4] |= mask & table[i].x[4];
  21667. r->y[0] |= mask & table[i].y[0];
  21668. r->y[1] |= mask & table[i].y[1];
  21669. r->y[2] |= mask & table[i].y[2];
  21670. r->y[3] |= mask & table[i].y[3];
  21671. r->y[4] |= mask & table[i].y[4];
  21672. }
  21673. }
  21674. #endif /* !WC_NO_CACHE_RESISTANT */
  21675. /* Multiply the point by the scalar and return the result.
  21676. * If map is true then convert result to affine coordinates.
  21677. *
  21678. * Stripe implementation.
  21679. * Pre-generated: 2^0, 2^32, ...
  21680. * Pre-generated: products of all combinations of above.
  21681. * 8 doubles and adds (with qz=1)
  21682. *
  21683. * r Resulting point.
  21684. * k Scalar to multiply by.
  21685. * table Pre-computed table.
  21686. * map Indicates whether to convert result to affine.
  21687. * ct Constant time required.
  21688. * heap Heap to use for allocation.
  21689. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  21690. */
  21691. static int sp_256_ecc_mulmod_stripe_5(sp_point_256* r, const sp_point_256* g,
  21692. const sp_table_entry_256* table, const sp_digit* k, int map,
  21693. int ct, void* heap)
  21694. {
  21695. #ifdef WOLFSSL_SP_SMALL_STACK
  21696. sp_point_256* rt = NULL;
  21697. sp_digit* t = NULL;
  21698. #else
  21699. sp_point_256 rt[2];
  21700. sp_digit t[2 * 5 * 6];
  21701. #endif
  21702. sp_point_256* p = NULL;
  21703. int i;
  21704. int j;
  21705. int y;
  21706. int x;
  21707. int err = MP_OKAY;
  21708. (void)g;
  21709. /* Constant time used for cache attack resistance implementation. */
  21710. (void)ct;
  21711. (void)heap;
  21712. #ifdef WOLFSSL_SP_SMALL_STACK
  21713. rt = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 2, heap,
  21714. DYNAMIC_TYPE_ECC);
  21715. if (rt == NULL)
  21716. err = MEMORY_E;
  21717. if (err == MP_OKAY) {
  21718. t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 6, heap,
  21719. DYNAMIC_TYPE_ECC);
  21720. if (t == NULL)
  21721. err = MEMORY_E;
  21722. }
  21723. #endif
  21724. if (err == MP_OKAY) {
  21725. p = rt + 1;
  21726. XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));
  21727. XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));
  21728. y = 0;
  21729. x = 31;
  21730. for (j=0; j<8; j++) {
  21731. y |= (int)(((k[x / 52] >> (x % 52)) & 1) << j);
  21732. x += 32;
  21733. }
  21734. #ifndef WC_NO_CACHE_RESISTANT
  21735. if (ct) {
  21736. sp_256_get_entry_256_5(rt, table, y);
  21737. } else
  21738. #endif
  21739. {
  21740. XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));
  21741. XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));
  21742. }
  21743. rt->infinity = !y;
  21744. for (i=30; i>=0; i--) {
  21745. y = 0;
  21746. x = i;
  21747. for (j=0; j<8; j++) {
  21748. y |= (int)(((k[x / 52] >> (x % 52)) & 1) << j);
  21749. x += 32;
  21750. }
  21751. sp_256_proj_point_dbl_5(rt, rt, t);
  21752. #ifndef WC_NO_CACHE_RESISTANT
  21753. if (ct) {
  21754. sp_256_get_entry_256_5(p, table, y);
  21755. }
  21756. else
  21757. #endif
  21758. {
  21759. XMEMCPY(p->x, table[y].x, sizeof(table[y].x));
  21760. XMEMCPY(p->y, table[y].y, sizeof(table[y].y));
  21761. }
  21762. p->infinity = !y;
  21763. sp_256_proj_point_add_qz1_5(rt, rt, p, t);
  21764. }
  21765. if (map != 0) {
  21766. sp_256_map_5(r, rt, t);
  21767. }
  21768. else {
  21769. XMEMCPY(r, rt, sizeof(sp_point_256));
  21770. }
  21771. }
  21772. #ifdef WOLFSSL_SP_SMALL_STACK
  21773. if (t != NULL)
  21774. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  21775. if (rt != NULL)
  21776. XFREE(rt, heap, DYNAMIC_TYPE_ECC);
  21777. #endif
  21778. return err;
  21779. }
  21780. #ifdef FP_ECC
  21781. #ifndef FP_ENTRIES
  21782. #define FP_ENTRIES 16
  21783. #endif
  21784. /* Cache entry - holds precomputation tables for a point. */
  21785. typedef struct sp_cache_256_t {
  21786. /* X ordinate of point that table was generated from. */
  21787. sp_digit x[5];
  21788. /* Y ordinate of point that table was generated from. */
  21789. sp_digit y[5];
  21790. /* Precomputation table for point. */
  21791. sp_table_entry_256 table[256];
  21792. /* Count of entries in table. */
  21793. uint32_t cnt;
  21794. /* Point and table set in entry. */
  21795. int set;
  21796. } sp_cache_256_t;
  21797. /* Cache of tables. */
  21798. static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES];
  21799. /* Index of last entry in cache. */
  21800. static THREAD_LS_T int sp_cache_256_last = -1;
  21801. /* Cache has been initialized. */
  21802. static THREAD_LS_T int sp_cache_256_inited = 0;
  21803. #ifndef HAVE_THREAD_LS
  21804. #ifndef WOLFSSL_MUTEX_INITIALIZER
  21805. static volatile int initCacheMutex_256 = 0;
  21806. #endif
  21807. static wolfSSL_Mutex sp_cache_256_lock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(sp_cache_256_lock);
  21808. #endif
  21809. /* Get the cache entry for the point.
  21810. *
  21811. * g [in] Point scalar multiplying.
  21812. * cache [out] Cache table to use.
  21813. */
  21814. static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache)
  21815. {
  21816. int i;
  21817. int j;
  21818. uint32_t least;
  21819. if (sp_cache_256_inited == 0) {
  21820. for (i=0; i<FP_ENTRIES; i++) {
  21821. sp_cache_256[i].set = 0;
  21822. }
  21823. sp_cache_256_inited = 1;
  21824. }
  21825. /* Compare point with those in cache. */
  21826. for (i=0; i<FP_ENTRIES; i++) {
  21827. if (!sp_cache_256[i].set)
  21828. continue;
  21829. if (sp_256_cmp_equal_5(g->x, sp_cache_256[i].x) &
  21830. sp_256_cmp_equal_5(g->y, sp_cache_256[i].y)) {
  21831. sp_cache_256[i].cnt++;
  21832. break;
  21833. }
  21834. }
  21835. /* No match. */
  21836. if (i == FP_ENTRIES) {
  21837. /* Find empty entry. */
  21838. i = (sp_cache_256_last + 1) % FP_ENTRIES;
  21839. for (; i != sp_cache_256_last; i=(i+1)%FP_ENTRIES) {
  21840. if (!sp_cache_256[i].set) {
  21841. break;
  21842. }
  21843. }
  21844. /* Evict least used. */
  21845. if (i == sp_cache_256_last) {
  21846. least = sp_cache_256[0].cnt;
  21847. for (j=1; j<FP_ENTRIES; j++) {
  21848. if (sp_cache_256[j].cnt < least) {
  21849. i = j;
  21850. least = sp_cache_256[i].cnt;
  21851. }
  21852. }
  21853. }
  21854. XMEMCPY(sp_cache_256[i].x, g->x, sizeof(sp_cache_256[i].x));
  21855. XMEMCPY(sp_cache_256[i].y, g->y, sizeof(sp_cache_256[i].y));
  21856. sp_cache_256[i].set = 1;
  21857. sp_cache_256[i].cnt = 1;
  21858. }
  21859. *cache = &sp_cache_256[i];
  21860. sp_cache_256_last = i;
  21861. }
  21862. #endif /* FP_ECC */
  21863. /* Multiply the base point of P256 by the scalar and return the result.
  21864. * If map is true then convert result to affine coordinates.
  21865. *
  21866. * r Resulting point.
  21867. * g Point to multiply.
  21868. * k Scalar to multiply by.
  21869. * map Indicates whether to convert result to affine.
  21870. * ct Constant time required.
  21871. * heap Heap to use for allocation.
  21872. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  21873. */
  21874. static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g,
  21875. const sp_digit* k, int map, int ct, void* heap)
  21876. {
  21877. #ifndef FP_ECC
  21878. return sp_256_ecc_mulmod_win_add_sub_5(r, g, k, map, ct, heap);
  21879. #else
  21880. #ifdef WOLFSSL_SP_SMALL_STACK
  21881. sp_digit* tmp;
  21882. #else
  21883. sp_digit tmp[2 * 5 * 6];
  21884. #endif
  21885. sp_cache_256_t* cache;
  21886. int err = MP_OKAY;
  21887. #ifdef WOLFSSL_SP_SMALL_STACK
  21888. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 6, heap, DYNAMIC_TYPE_ECC);
  21889. if (tmp == NULL) {
  21890. err = MEMORY_E;
  21891. }
  21892. #endif
  21893. #ifndef HAVE_THREAD_LS
  21894. if (err == MP_OKAY) {
  21895. #ifndef WOLFSSL_MUTEX_INITIALIZER
  21896. if (initCacheMutex_256 == 0) {
  21897. wc_InitMutex(&sp_cache_256_lock);
  21898. initCacheMutex_256 = 1;
  21899. }
  21900. #endif
  21901. if (wc_LockMutex(&sp_cache_256_lock) != 0) {
  21902. err = BAD_MUTEX_E;
  21903. }
  21904. }
  21905. #endif /* HAVE_THREAD_LS */
  21906. if (err == MP_OKAY) {
  21907. sp_ecc_get_cache_256(g, &cache);
  21908. if (cache->cnt == 2)
  21909. sp_256_gen_stripe_table_5(g, cache->table, tmp, heap);
  21910. #ifndef HAVE_THREAD_LS
  21911. wc_UnLockMutex(&sp_cache_256_lock);
  21912. #endif /* HAVE_THREAD_LS */
  21913. if (cache->cnt < 2) {
  21914. err = sp_256_ecc_mulmod_win_add_sub_5(r, g, k, map, ct, heap);
  21915. }
  21916. else {
  21917. err = sp_256_ecc_mulmod_stripe_5(r, g, cache->table, k,
  21918. map, ct, heap);
  21919. }
  21920. }
  21921. #ifdef WOLFSSL_SP_SMALL_STACK
  21922. XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
  21923. #endif
  21924. return err;
  21925. #endif
  21926. }
  21927. #endif
  21928. /* Multiply the point by the scalar and return the result.
  21929. * If map is true then convert result to affine coordinates.
  21930. *
  21931. * km Scalar to multiply by.
  21932. * p Point to multiply.
  21933. * r Resulting point.
  21934. * map Indicates whether to convert result to affine.
  21935. * heap Heap to use for allocation.
  21936. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  21937. */
  21938. int sp_ecc_mulmod_256(const mp_int* km, const ecc_point* gm, ecc_point* r,
  21939. int map, void* heap)
  21940. {
  21941. #ifdef WOLFSSL_SP_SMALL_STACK
  21942. sp_point_256* point = NULL;
  21943. sp_digit* k = NULL;
  21944. #else
  21945. sp_point_256 point[1];
  21946. sp_digit k[5];
  21947. #endif
  21948. int err = MP_OKAY;
  21949. #ifdef WOLFSSL_SP_SMALL_STACK
  21950. point = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap,
  21951. DYNAMIC_TYPE_ECC);
  21952. if (point == NULL)
  21953. err = MEMORY_E;
  21954. if (err == MP_OKAY) {
  21955. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,
  21956. DYNAMIC_TYPE_ECC);
  21957. if (k == NULL)
  21958. err = MEMORY_E;
  21959. }
  21960. #endif
  21961. if (err == MP_OKAY) {
  21962. sp_256_from_mp(k, 5, km);
  21963. sp_256_point_from_ecc_point_5(point, gm);
  21964. err = sp_256_ecc_mulmod_5(point, point, k, map, 1, heap);
  21965. }
  21966. if (err == MP_OKAY) {
  21967. err = sp_256_point_to_ecc_point_5(point, r);
  21968. }
  21969. #ifdef WOLFSSL_SP_SMALL_STACK
  21970. if (k != NULL)
  21971. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  21972. if (point != NULL)
  21973. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  21974. #endif
  21975. return err;
  21976. }
  21977. /* Multiply the point by the scalar, add point a and return the result.
  21978. * If map is true then convert result to affine coordinates.
  21979. *
  21980. * km Scalar to multiply by.
  21981. * p Point to multiply.
  21982. * am Point to add to scalar multiply result.
  21983. * inMont Point to add is in montgomery form.
  21984. * r Resulting point.
  21985. * map Indicates whether to convert result to affine.
  21986. * heap Heap to use for allocation.
  21987. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  21988. */
  21989. int sp_ecc_mulmod_add_256(const mp_int* km, const ecc_point* gm,
  21990. const ecc_point* am, int inMont, ecc_point* r, int map, void* heap)
  21991. {
  21992. #ifdef WOLFSSL_SP_SMALL_STACK
  21993. sp_point_256* point = NULL;
  21994. sp_digit* k = NULL;
  21995. #else
  21996. sp_point_256 point[2];
  21997. sp_digit k[5 + 5 * 2 * 6];
  21998. #endif
  21999. sp_point_256* addP = NULL;
  22000. sp_digit* tmp = NULL;
  22001. int err = MP_OKAY;
  22002. #ifdef WOLFSSL_SP_SMALL_STACK
  22003. point = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 2, heap,
  22004. DYNAMIC_TYPE_ECC);
  22005. if (point == NULL)
  22006. err = MEMORY_E;
  22007. if (err == MP_OKAY) {
  22008. k = (sp_digit*)XMALLOC(
  22009. sizeof(sp_digit) * (5 + 5 * 2 * 6), heap,
  22010. DYNAMIC_TYPE_ECC);
  22011. if (k == NULL)
  22012. err = MEMORY_E;
  22013. }
  22014. #endif
  22015. if (err == MP_OKAY) {
  22016. addP = point + 1;
  22017. tmp = k + 5;
  22018. sp_256_from_mp(k, 5, km);
  22019. sp_256_point_from_ecc_point_5(point, gm);
  22020. sp_256_point_from_ecc_point_5(addP, am);
  22021. }
  22022. if ((err == MP_OKAY) && (!inMont)) {
  22023. err = sp_256_mod_mul_norm_5(addP->x, addP->x, p256_mod);
  22024. }
  22025. if ((err == MP_OKAY) && (!inMont)) {
  22026. err = sp_256_mod_mul_norm_5(addP->y, addP->y, p256_mod);
  22027. }
  22028. if ((err == MP_OKAY) && (!inMont)) {
  22029. err = sp_256_mod_mul_norm_5(addP->z, addP->z, p256_mod);
  22030. }
  22031. if (err == MP_OKAY) {
  22032. err = sp_256_ecc_mulmod_5(point, point, k, 0, 0, heap);
  22033. }
  22034. if (err == MP_OKAY) {
  22035. sp_256_proj_point_add_5(point, point, addP, tmp);
  22036. if (map) {
  22037. sp_256_map_5(point, point, tmp);
  22038. }
  22039. err = sp_256_point_to_ecc_point_5(point, r);
  22040. }
  22041. #ifdef WOLFSSL_SP_SMALL_STACK
  22042. if (k != NULL)
  22043. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  22044. if (point != NULL)
  22045. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  22046. #endif
  22047. return err;
  22048. }
  22049. #ifdef WOLFSSL_SP_SMALL
  22050. /* Multiply the base point of P256 by the scalar and return the result.
  22051. * If map is true then convert result to affine coordinates.
  22052. *
  22053. * r Resulting point.
  22054. * k Scalar to multiply by.
  22055. * map Indicates whether to convert result to affine.
  22056. * heap Heap to use for allocation.
  22057. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  22058. */
  22059. static int sp_256_ecc_mulmod_base_5(sp_point_256* r, const sp_digit* k,
  22060. int map, int ct, void* heap)
  22061. {
  22062. /* No pre-computed values. */
  22063. return sp_256_ecc_mulmod_5(r, &p256_base, k, map, ct, heap);
  22064. }
  22065. #ifdef WOLFSSL_SP_NONBLOCK
  22066. static int sp_256_ecc_mulmod_base_5_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
  22067. const sp_digit* k, int map, int ct, void* heap)
  22068. {
  22069. /* No pre-computed values. */
  22070. return sp_256_ecc_mulmod_5_nb(sp_ctx, r, &p256_base, k, map, ct, heap);
  22071. }
  22072. #endif /* WOLFSSL_SP_NONBLOCK */
  22073. #else
  22074. /* Striping precomputation table.
  22075. * 8 points combined into a table of 256 points.
  22076. * Distance of 32 between points.
  22077. */
  22078. static const sp_table_entry_256 p256_table[256] = {
  22079. /* 0 */
  22080. { { 0x00, 0x00, 0x00, 0x00, 0x00 },
  22081. { 0x00, 0x00, 0x00, 0x00, 0x00 } },
  22082. /* 1 */
  22083. { { 0x730d418a9143cL,0xfc5fedb60179eL,0x762251075ba95L,0x55c679fb732b7L,
  22084. 0x018905f76a537L },
  22085. { 0x25357ce95560aL,0xe4ba19e45cddfL,0xd21f3258b4ab8L,0x5d85d2e88688dL,
  22086. 0x08571ff182588L } },
  22087. /* 2 */
  22088. { { 0x886024147519aL,0xac26b372f0202L,0x785ebc8d0981eL,0x58e9a9d4a7caaL,
  22089. 0x0d953c50ddbdfL },
  22090. { 0x361ccfd590f8fL,0x6b44e6c9179d6L,0x2eb64cf72e962L,0x88f37fd961102L,
  22091. 0x0863ebb7e9eb2L } },
  22092. /* 3 */
  22093. { { 0x6b6235cdb6485L,0xa22f0a2f97785L,0xf7e300b808f0eL,0x80a03e68d9544L,
  22094. 0x000076055b5ffL },
  22095. { 0x4eb9b838d2010L,0xbb3243708a763L,0x42a660654014fL,0x3ee0e0e47d398L,
  22096. 0x0830877613437L } },
  22097. /* 4 */
  22098. { { 0x22fc516a0d2bbL,0x6c1a6234994f9L,0x7c62c8b0d5cc1L,0x667f9241cf3a5L,
  22099. 0x02f5e6961fd1bL },
  22100. { 0x5c70bf5a01797L,0x4d609561925c1L,0x71fdb523d20b4L,0x0f7b04911b370L,
  22101. 0x0f648f9168d6fL } },
  22102. /* 5 */
  22103. { { 0x66847e137bbbcL,0x9e8a6a0bec9e5L,0x9d73463e43446L,0x0015b1c427617L,
  22104. 0x05abe0285133dL },
  22105. { 0xa837cc04c7dabL,0x4c43260c0792aL,0x8e6cc37573d9fL,0x73830c9315627L,
  22106. 0x094bb725b6b6fL } },
  22107. /* 6 */
  22108. { { 0x9b48f720f141cL,0xcd2df5bc74bbfL,0x11045c46199b3L,0xc4efdc3f61294L,
  22109. 0x0cdd6bbcb2f7dL },
  22110. { 0x6700beaf436fdL,0x6db99326beccaL,0x14f25226f647fL,0xe5f60c0fa7920L,
  22111. 0x0a361bebd4bdaL } },
  22112. /* 7 */
  22113. { { 0xa2558597c13c7L,0x5f50b7c3e128aL,0x3c09d1dc38d63L,0x292c07039aecfL,
  22114. 0x0ba12ca09c4b5L },
  22115. { 0x08fa459f91dfdL,0x66ceea07fb9e4L,0xd780b293af43bL,0xef4b1eceb0899L,
  22116. 0x053ebb99d701fL } },
  22117. /* 8 */
  22118. { { 0x7ee31b0e63d34L,0x72a9e54fab4feL,0x5e7b5a4f46005L,0x4831c0493334dL,
  22119. 0x08589fb9206d5L },
  22120. { 0x0f5cc6583553aL,0x4ae25649e5aa7L,0x0044652087909L,0x1c4fcc9045071L,
  22121. 0x0ebb0696d0254L } },
  22122. /* 9 */
  22123. { { 0x6ca15ac1647c5L,0x47c4cf5799461L,0x64dfbacb8127dL,0x7da3dc666aa37L,
  22124. 0x0eb2820cbd1b2L },
  22125. { 0x6f8d86a87e008L,0x9d922378f3940L,0x0ccecb2d87dfaL,0xda1d56ed2e428L,
  22126. 0x01f28289b55a7L } },
  22127. /* 10 */
  22128. { { 0xaa0c03b89da99L,0x9eb8284022abbL,0x81c05e8a6f2d7L,0x4d6327847862bL,
  22129. 0x0337a4b5905e5L },
  22130. { 0x7500d21f7794aL,0xb77d6d7f613c6L,0x4cfd6e8207005L,0xfbd60a5a37810L,
  22131. 0x00d65e0d5f4c2L } },
  22132. /* 11 */
  22133. { { 0x09bbeb5275d38L,0x450be0a358d9dL,0x73eb2654268a7L,0xa232f0762ff49L,
  22134. 0x0c23da24252f4L },
  22135. { 0x1b84f0b94520cL,0x63b05bd78e5daL,0x4d29ea1096667L,0xcff13a4dcb869L,
  22136. 0x019de3b8cc790L } },
  22137. /* 12 */
  22138. { { 0xa716c26c5fe04L,0x0b3bba1bdb183L,0x4cb712c3b28deL,0xcbfd7432c586aL,
  22139. 0x0e34dcbd491fcL },
  22140. { 0x8d46baaa58403L,0x8682e97a53b40L,0x6aaa8af9a6974L,0x0f7f9e3901273L,
  22141. 0x0e7641f447b4eL } },
  22142. /* 13 */
  22143. { { 0x53941df64ba59L,0xec0b0242fc7d7L,0x1581859d33f10L,0x57bf4f06dfc6aL,
  22144. 0x04a12df57052aL },
  22145. { 0x6338f9439dbd0L,0xd4bde53e1fbfaL,0x1f1b314d3c24bL,0xea46fd5e4ffa2L,
  22146. 0x06af5aa93bb5bL } },
  22147. /* 14 */
  22148. { { 0x0b69910c91999L,0x402a580491da1L,0x8cc20900a24b4L,0x40133e0094b4bL,
  22149. 0x05fe3475a66a4L },
  22150. { 0x8cabdf93e7b4bL,0x1a7c23f91ab0fL,0xd1e6263292b50L,0xa91642e889aecL,
  22151. 0x0b544e308ecfeL } },
  22152. /* 15 */
  22153. { { 0x8c6e916ddfdceL,0x66f89179e6647L,0xd4e67e12c3291L,0xc20b4e8d6e764L,
  22154. 0x0e0b6b2bda6b0L },
  22155. { 0x12df2bb7efb57L,0xde790c40070d3L,0x79bc9441aac0dL,0x3774f90336ad6L,
  22156. 0x071c023de25a6L } },
  22157. /* 16 */
  22158. { { 0x8c244bfe20925L,0xc38fdce86762aL,0xd38706391c19aL,0x24f65a96a5d5dL,
  22159. 0x061d587d421d3L },
  22160. { 0x673a2a37173eaL,0x0853778b65e87L,0x5bab43e238480L,0xefbe10f8441e0L,
  22161. 0x0fa11fe124621L } },
  22162. /* 17 */
  22163. { { 0x91f2b2cb19ffdL,0x5bb1923c231c8L,0xac5ca8e01ba8dL,0xbedcb6d03d678L,
  22164. 0x0586eb04c1f13L },
  22165. { 0x5c6e527e8ed09L,0x3c1819ede20c3L,0x6c652fa1e81a3L,0x4f11278fd6c05L,
  22166. 0x019d5ac087086L } },
  22167. /* 18 */
  22168. { { 0x9f581309a4e1fL,0x1be92700741e9L,0xfd28d20ab7de7L,0x563f26a5ef0beL,
  22169. 0x0e7c0073f7f9cL },
  22170. { 0xd663a0ef59f76L,0x5420fcb0501f6L,0xa6602d4669b3bL,0x3c0ac08c1f7a7L,
  22171. 0x0e08504fec65bL } },
  22172. /* 19 */
  22173. { { 0x8f68da031b3caL,0x9ee6da6d66f09L,0x4f246e86d1cabL,0x96b45bfd81fa9L,
  22174. 0x078f018825b09L },
  22175. { 0xefde43a25787fL,0x0d1dccac9bb7eL,0x35bfc368016f8L,0x747a0cea4877bL,
  22176. 0x043a773b87e94L } },
  22177. /* 20 */
  22178. { { 0x77734d2b533d5L,0xf6a1bdddc0625L,0x79ec293673b8aL,0x66b1577e7c9aaL,
  22179. 0x0bb6de651c3b2L },
  22180. { 0x9303ab65259b3L,0xd3d03a7480e7eL,0xb3cfc27d6a0afL,0xb99bc5ac83d19L,
  22181. 0x060b4619a5d18L } },
  22182. /* 21 */
  22183. { { 0xa38e11ae5aa1cL,0x2b49e73658bd6L,0xe5f87edb8b765L,0xffcd0b130014eL,
  22184. 0x09d0f27b2aeebL },
  22185. { 0x246317a730a55L,0x2fddbbc83aca9L,0xc019a719c955bL,0xc48d07c1dfe0aL,
  22186. 0x0244a566d356eL } },
  22187. /* 22 */
  22188. { { 0x0394aeacf1f96L,0xa9024c271c6dbL,0x2cbd3b99f2122L,0xef692626ac1b8L,
  22189. 0x045e58c873581L },
  22190. { 0xf479da38f9dbcL,0x46e888a040d3fL,0x6e0bed7a8aaf1L,0xb7a4945adfb24L,
  22191. 0x0c040e21cc1e4L } },
  22192. /* 23 */
  22193. { { 0xaf0006f8117b6L,0xff73a35433847L,0xd9475eb651969L,0x6ec7482b35761L,
  22194. 0x01cdf5c97682cL },
  22195. { 0x775b411f04839L,0xf448de16987dbL,0x70b32197dbeacL,0xff3db2921dd1bL,
  22196. 0x0046755f8a92dL } },
  22197. /* 24 */
  22198. { { 0xac5d2bce8ffcdL,0x8b2fe61a82cc8L,0x202d6c70d53c4L,0xa5f3f6f161727L,
  22199. 0x0046e5e113b83L },
  22200. { 0x8ff64d8007f01L,0x125af43183e7bL,0x5e1a03c7fb1efL,0x005b045c5ea63L,
  22201. 0x06e0106c3303dL } },
  22202. /* 25 */
  22203. { { 0x7358488dd73b1L,0x8f995ed0d948cL,0x56a2ab7767070L,0xcf1f38385ea8cL,
  22204. 0x0442594ede901L },
  22205. { 0xaa2c912d4b65bL,0x3b96c90c37f8fL,0xe978d1f94c234L,0xe68ed326e4a15L,
  22206. 0x0a796fa514c2eL } },
  22207. /* 26 */
  22208. { { 0xfb604823addd7L,0x83e56693b3359L,0xcbf3c809e2a61L,0x66e9f885b78e3L,
  22209. 0x0e4ad2da9c697L },
  22210. { 0xf7f428e048a61L,0x8cc092d9a0357L,0x03ed8ef082d19L,0x5143fc3a1af4cL,
  22211. 0x0c5e94046c37bL } },
  22212. /* 27 */
  22213. { { 0xa538c2be75f9eL,0xe8cb123a78476L,0x109c04b6fd1a9L,0x4747d85e4df0bL,
  22214. 0x063283dafdb46L },
  22215. { 0x28cf7baf2df15L,0x550ad9a7f4ce7L,0x834bcc3e592c4L,0xa938fab226adeL,
  22216. 0x068bd19ab1981L } },
  22217. /* 28 */
  22218. { { 0xead511887d659L,0xf4b359305ac08L,0xfe74fe33374d5L,0xdfd696986981cL,
  22219. 0x0495292f53c6fL },
  22220. { 0x78c9e1acec896L,0x10ec5b44844a8L,0x64d60a7d964b2L,0x68376696f7e26L,
  22221. 0x00ec7530d2603L } },
  22222. /* 29 */
  22223. { { 0x13a05ad2687bbL,0x6af32e21fa2daL,0xdd4607ba1f83bL,0x3f0b390f5ef51L,
  22224. 0x00f6207a66486L },
  22225. { 0x7e3bb0f138233L,0x6c272aa718bd6L,0x6ec88aedd66b9L,0x6dcf8ed004072L,
  22226. 0x0ff0db07208edL } },
  22227. /* 30 */
  22228. { { 0xfa1014c95d553L,0xfd5d680a8a749L,0xf3b566fa44052L,0x0ea3183b4317fL,
  22229. 0x0313b513c8874L },
  22230. { 0x2e2ac08d11549L,0x0bb4dee21cb40L,0x7f2320e071ee1L,0x9f8126b987dd4L,
  22231. 0x02d3abcf986f1L } },
  22232. /* 31 */
  22233. { { 0x88501815581a2L,0x56632211af4c2L,0xcab2e999a0a6dL,0x8cdf19ba7a0f0L,
  22234. 0x0c036fa10ded9L },
  22235. { 0xe08bac1fbd009L,0x9006d1581629aL,0xb9e0d8f0b68b1L,0x0194c2eb32779L,
  22236. 0x0a6b2a2c4b6d4L } },
  22237. /* 32 */
  22238. { { 0x3e50f6d3549cfL,0x6ffacd665ed43L,0xe11fcb46f3369L,0x9860695bfdaccL,
  22239. 0x0810ee252af7cL },
  22240. { 0x50fe17159bb2cL,0xbe758b357b654L,0x69fea72f7dfbeL,0x17452b057e74dL,
  22241. 0x0d485717a9273L } },
  22242. /* 33 */
  22243. { { 0x41a8af0cb5a98L,0x931f3110bf117L,0xb382adfd3da8fL,0x604e1994e2cbaL,
  22244. 0x06a6045a72f9aL },
  22245. { 0xc0d3fa2b2411dL,0x3e510e96e0170L,0x865b3ccbe0eb8L,0x57903bcc9f738L,
  22246. 0x0d3e45cfaf9e1L } },
  22247. /* 34 */
  22248. { { 0xf69bbe83f7669L,0x8272877d6bce1L,0x244278d09f8aeL,0xc19c9548ae543L,
  22249. 0x0207755dee3c2L },
  22250. { 0xd61d96fef1945L,0xefb12d28c387bL,0x2df64aa18813cL,0xb00d9fbcd1d67L,
  22251. 0x048dc5ee57154L } },
  22252. /* 35 */
  22253. { { 0x790bff7e5a199L,0xcf989ccbb7123L,0xa519c79e0efb8L,0xf445c27a2bfe0L,
  22254. 0x0f2fb0aeddff6L },
  22255. { 0x09575f0b5025fL,0xd740fa9f2241cL,0x80bfbd0550543L,0xd5258fa3c8ad3L,
  22256. 0x0a13e9015db28L } },
  22257. /* 36 */
  22258. { { 0x7a350a2b65cbcL,0x722a464226f9fL,0x23f07a10b04b9L,0x526f265ce241eL,
  22259. 0x02bf0d6b01497L },
  22260. { 0x4dd3f4b216fb7L,0x67fbdda26ad3dL,0x708505cf7d7b8L,0xe89faeb7b83f6L,
  22261. 0x042a94a5a162fL } },
  22262. /* 37 */
  22263. { { 0x6ad0beaadf191L,0x9025a268d7584L,0x94dc1f60f8a48L,0xde3de86030504L,
  22264. 0x02c2dd969c65eL },
  22265. { 0x2171d93849c17L,0xba1da250dd6d0L,0xc3a5485460488L,0x6dbc4810c7063L,
  22266. 0x0f437fa1f42c5L } },
  22267. /* 38 */
  22268. { { 0x0d7144a0f7dabL,0x931776e9ac6aaL,0x5f397860f0497L,0x7aa852c0a050fL,
  22269. 0x0aaf45b335470L },
  22270. { 0x37c33c18d364aL,0x063e49716585eL,0x5ec5444d40b9bL,0x72bcf41716811L,
  22271. 0x0cdf6310df4f2L } },
  22272. /* 39 */
  22273. { { 0x3c6238ea8b7efL,0x1885bc2287747L,0xbda8e3408e935L,0x2ff2419567722L,
  22274. 0x0f0d008bada9eL },
  22275. { 0x2671d2414d3b1L,0x85b019ea76291L,0x53bcbdbb37549L,0x7b8b5c61b96d4L,
  22276. 0x05bd5c2f5ca88L } },
  22277. /* 40 */
  22278. { { 0xf469ef49a3154L,0x956e2b2e9aef0L,0xa924a9c3e85a5L,0x471945aaec1eaL,
  22279. 0x0aa12dfc8a09eL },
  22280. { 0x272274df69f1dL,0x2ca2ff5e7326fL,0x7a9dd44e0e4c8L,0xa901b9d8ce73bL,
  22281. 0x06c036e73e48cL } },
  22282. /* 41 */
  22283. { { 0xae12a0f6e3138L,0x0025ad345a5cfL,0x5672bc56966efL,0xbe248993c64b4L,
  22284. 0x0292ff65896afL },
  22285. { 0x50d445e213402L,0x274392c9fed52L,0xa1c72e8f6580eL,0x7276097b397fdL,
  22286. 0x0644e0c90311bL } },
  22287. /* 42 */
  22288. { { 0x421e1a47153f0L,0x79920418c9e1eL,0x05d7672b86c3bL,0x9a7793bdce877L,
  22289. 0x0f25ae793cab7L },
  22290. { 0x194a36d869d0cL,0x824986c2641f3L,0x96e945e9d55c8L,0x0a3e49fb5ea30L,
  22291. 0x039b8e65313dbL } },
  22292. /* 43 */
  22293. { { 0x54200b6fd2e59L,0x669255c98f377L,0xe2a573935e2c0L,0xdb06d9dab21a0L,
  22294. 0x039122f2f0f19L },
  22295. { 0xce1e003cad53cL,0x0fe65c17e3cfbL,0xaa13877225b2cL,0xff8d72baf1d29L,
  22296. 0x08de80af8ce80L } },
  22297. /* 44 */
  22298. { { 0xea8d9207bbb76L,0x7c21782758afbL,0xc0436b1921c7eL,0x8c04dfa2b74b1L,
  22299. 0x0871949062e36L },
  22300. { 0x928bba3993df5L,0xb5f3b3d26ab5fL,0x5b55050639d75L,0xfde1011aa78a8L,
  22301. 0x0fc315e6a5b74L } },
  22302. /* 45 */
  22303. { { 0xfd41ae8d6ecfaL,0xf61aec7f86561L,0x924741d5f8c44L,0x908898452a7b4L,
  22304. 0x0e6d4a7adee38L },
  22305. { 0x52ed14593c75dL,0xa4dd271162605L,0xba2c7db70a70dL,0xae57d2aede937L,
  22306. 0x035dfaf9a9be2L } },
  22307. /* 46 */
  22308. { { 0x56fcdaa736636L,0x97ae2cab7e6b9L,0xf34996609f51dL,0x0d2bfb10bf410L,
  22309. 0x01da5c7d71c83L },
  22310. { 0x1e4833cce6825L,0x8ff9573c3b5c4L,0x23036b815ad11L,0xb9d6a28552c7fL,
  22311. 0x07077c0fddbf4L } },
  22312. /* 47 */
  22313. { { 0x3ff8d46b9661cL,0x6b0d2cfd71bf6L,0x847f8f7a1dfd3L,0xfe440373e140aL,
  22314. 0x053a8632ee50eL },
  22315. { 0x6ff68696d8051L,0x95c74f468a097L,0xe4e26bddaec0cL,0xfcc162994dc35L,
  22316. 0x0028ca76d34e1L } },
  22317. /* 48 */
  22318. { { 0xd47dcfc9877eeL,0x10801d0002d11L,0x4c260b6c8b362L,0xf046d002c1175L,
  22319. 0x004c17cd86962L },
  22320. { 0xbd094b0daddf5L,0x7524ce55c06d9L,0x2da03b5bea235L,0x7474663356e67L,
  22321. 0x0f7ba4de9fed9L } },
  22322. /* 49 */
  22323. { { 0xbfa34ebe1263fL,0x3571ae7ce6d0dL,0x2a6f523557637L,0x1c41d24405538L,
  22324. 0x0e31f96005213L },
  22325. { 0xb9216ea6b6ec6L,0x2e73c2fc44d1bL,0x9d0a29437a1d1L,0xd47bc10e7eac8L,
  22326. 0x0aa3a6259ce34L } },
  22327. /* 50 */
  22328. { { 0xf9df536f3dcd3L,0x50d2bf7360fbcL,0xf504f5b6cededL,0xdaee491710fadL,
  22329. 0x02398dd627e79L },
  22330. { 0x705a36d09569eL,0xbb5149f769cf4L,0x5f6034cea0619L,0x6210ff9c03773L,
  22331. 0x05717f5b21c04L } },
  22332. /* 51 */
  22333. { { 0x229c921dd895eL,0x0040c284519feL,0xd637ecd8e5185L,0x28defa13d2391L,
  22334. 0x0660a2c560e3cL },
  22335. { 0xa88aed67fcbd0L,0x780ea9f0969ccL,0x2e92b4dc84724L,0x245332b2f4817L,
  22336. 0x0624ee54c4f52L } },
  22337. /* 52 */
  22338. { { 0x49ce4d897ecccL,0xd93f9880aa095L,0x43a7c204d49d1L,0xfbc0723c24230L,
  22339. 0x04f392afb92bdL },
  22340. { 0x9f8fa7de44fd9L,0xe457b32156696L,0x68ebc3cb66cfbL,0x399cdb2fa8033L,
  22341. 0x08a3e7977ccdbL } },
  22342. /* 53 */
  22343. { { 0x1881f06c4b125L,0x00f6e3ca8cddeL,0xc7a13e9ae34e3L,0x4404ef6999de5L,
  22344. 0x03888d02370c2L },
  22345. { 0x8035644f91081L,0x615f015504762L,0x32cd36e3d9fcfL,0x23361827edc86L,
  22346. 0x0a5e62e471810L } },
  22347. /* 54 */
  22348. { { 0x25ee32facd6c8L,0x5454bcbc661a8L,0x8df9931699c63L,0x5adc0ce3edf79L,
  22349. 0x02c4768e6466aL },
  22350. { 0x6ff8c90a64bc9L,0x20e4779f5cb34L,0xc05e884630a60L,0x52a0d949d064bL,
  22351. 0x07b5e6441f9e6L } },
  22352. /* 55 */
  22353. { { 0x9422c1d28444aL,0xd8be136a39216L,0xb0c7fcee996c5L,0x744a2387afe5fL,
  22354. 0x0b8af73cb0c8dL },
  22355. { 0xe83aa338b86fdL,0x58a58a5cff5fdL,0x0ac9433fee3f1L,0x0895c9ee8f6f2L,
  22356. 0x0a036395f7f3fL } },
  22357. /* 56 */
  22358. { { 0x3c6bba10f7770L,0x81a12a0e248c7L,0x1bc2b9fa6f16dL,0xb533100df6825L,
  22359. 0x04be36b01875fL },
  22360. { 0x6086e9fb56dbbL,0x8b07e7a4f8922L,0x6d52f20306fefL,0x00c0eeaccc056L,
  22361. 0x08cbc9a871bdcL } },
  22362. /* 57 */
  22363. { { 0x1895cc0dac4abL,0x40712ff112e13L,0xa1cee57a874a4L,0x35f86332ae7c6L,
  22364. 0x044e7553e0c08L },
  22365. { 0x03fff7734002dL,0x8b0b34425c6d5L,0xe8738b59d35cbL,0xfc1895f702760L,
  22366. 0x0470a683a5eb8L } },
  22367. /* 58 */
  22368. { { 0x761dc90513482L,0x2a01e9276a81bL,0xce73083028720L,0xc6efcda441ee0L,
  22369. 0x016410690c63dL },
  22370. { 0x34a066d06a2edL,0x45189b100bf50L,0xb8218c9dd4d77L,0xbb4fd914ae72aL,
  22371. 0x0d73479fd7abcL } },
  22372. /* 59 */
  22373. { { 0xefb165ad4c6e5L,0x8f5b06d04d7edL,0x575cb14262cf0L,0x666b12ed5bb18L,
  22374. 0x0816469e30771L },
  22375. { 0xb9d79561e291eL,0x22c1de1661d7aL,0x35e0513eb9dafL,0x3f9cf49827eb1L,
  22376. 0x00a36dd23f0ddL } },
  22377. /* 60 */
  22378. { { 0xd32c741d5533cL,0x9e8684628f098L,0x349bd117c5f5aL,0xb11839a228adeL,
  22379. 0x0e331dfd6fdbaL },
  22380. { 0x0ab686bcc6ed8L,0xbdef7a260e510L,0xce850d77160c3L,0x33899063d9a7bL,
  22381. 0x0d3b4782a492eL } },
  22382. /* 61 */
  22383. { { 0x9b6e8f3821f90L,0xed66eb7aada14L,0xa01311692edd9L,0xa5bd0bb669531L,
  22384. 0x07281275a4c86L },
  22385. { 0x858f7d3ff47e5L,0xbc61016441503L,0xdfd9bb15e1616L,0x505962b0f11a7L,
  22386. 0x02c062e7ece14L } },
  22387. /* 62 */
  22388. { { 0xf996f0159ac2eL,0x36cbdb2713a76L,0x8e46047281e77L,0x7ef12ad6d2880L,
  22389. 0x0282a35f92c4eL },
  22390. { 0x54b1ec0ce5cd2L,0xc91379c2299c3L,0xe82c11ecf99efL,0x2abd992caf383L,
  22391. 0x0c71cd513554dL } },
  22392. /* 63 */
  22393. { { 0x5de9c09b578f4L,0x58e3affa7a488L,0x9182f1f1884e2L,0xf3a38f76b1b75L,
  22394. 0x0c50f6740cf47L },
  22395. { 0x4adf3374b68eaL,0x2369965fe2a9cL,0x5a53050a406f3L,0x58dc2f86a2228L,
  22396. 0x0b9ecb3a72129L } },
  22397. /* 64 */
  22398. { { 0x8410ef4f8b16aL,0xfec47b266a56fL,0xd9c87c197241aL,0xab1b0a406b8e6L,
  22399. 0x0803f3e02cd42L },
  22400. { 0x309a804dbec69L,0xf73bbad05f7f0L,0xd8e197fa83b85L,0xadc1c6097273aL,
  22401. 0x0c097440e5067L } },
  22402. /* 65 */
  22403. { { 0xa56f2c379ab34L,0x8b841df8d1846L,0x76c68efa8ee06L,0x1f30203144591L,
  22404. 0x0f1af32d5915fL },
  22405. { 0x375315d75bd50L,0xbaf72f67bc99cL,0x8d7723f837cffL,0x1c8b0613a4184L,
  22406. 0x023d0f130e2d4L } },
  22407. /* 66 */
  22408. { { 0xab6edf41500d9L,0xe5fcbeada8857L,0x97259510d890aL,0xfadd52fe86488L,
  22409. 0x0b0288dd6c0a3L },
  22410. { 0x20f30650bcb08L,0x13695d6e16853L,0x989aa7671af63L,0xc8d231f520a7bL,
  22411. 0x0ffd3724ff408L } },
  22412. /* 67 */
  22413. { { 0x68e64b458e6cbL,0x20317a5d28539L,0xaa75f56992dadL,0x26df3814ae0b7L,
  22414. 0x0f5590f4ad78cL },
  22415. { 0x24bd3cf0ba55aL,0x4a0c778bae0fcL,0x83b674a0fc472L,0x4a201ce9864f6L,
  22416. 0x018d6da54f6f7L } },
  22417. /* 68 */
  22418. { { 0x3e225d5be5a2bL,0x835934f3c6ed9L,0x2626ffc6fe799L,0x216a431409262L,
  22419. 0x050bbb4d97990L },
  22420. { 0x191c6e57ec63eL,0x40181dcdb2378L,0x236e0f665422cL,0x49c341a8099b0L,
  22421. 0x02b10011801feL } },
  22422. /* 69 */
  22423. { { 0x8b5c59b391593L,0xa2598270fcfc6L,0x19adcbbc385f5L,0xae0c7144f3aadL,
  22424. 0x0dd55899983fbL },
  22425. { 0x88b8e74b82ff4L,0x4071e734c993bL,0x3c0322ad2e03cL,0x60419a7a9eaf4L,
  22426. 0x0e6e4c551149dL } },
  22427. /* 70 */
  22428. { { 0x655bb1e9af288L,0x64f7ada93155fL,0xb2820e5647e1aL,0x56ff43697e4bcL,
  22429. 0x051e00db107edL },
  22430. { 0x169b8771c327eL,0x0b4a96c2ad43dL,0xdeb477929cdb2L,0x9177c07d51f53L,
  22431. 0x0e22f42414982L } },
  22432. /* 71 */
  22433. { { 0x5e8f4635f1abbL,0xb568538874cd4L,0x5a8034d7edc0cL,0x48c9c9472c1fbL,
  22434. 0x0f709373d52dcL },
  22435. { 0x966bba8af30d6L,0x4af137b69c401L,0x361c47e95bf5fL,0x5b113966162a9L,
  22436. 0x0bd52d288e727L } },
  22437. /* 72 */
  22438. { { 0x55c7a9c5fa877L,0x727d3a3d48ab1L,0x3d189d817dad6L,0x77a643f43f9e7L,
  22439. 0x0a0d0f8e4c8aaL },
  22440. { 0xeafd8cc94f92dL,0xbe0c4ddb3a0bbL,0x82eba14d818c8L,0x6a0022cc65f8bL,
  22441. 0x0a56c78c7946dL } },
  22442. /* 73 */
  22443. { { 0x2391b0dd09529L,0xa63daddfcf296L,0xb5bf481803e0eL,0x367a2c77351f5L,
  22444. 0x0d8befdf8731aL },
  22445. { 0x19d42fc0157f4L,0xd7fec8e650ab9L,0x2d48b0af51caeL,0x6478cdf9cb400L,
  22446. 0x0854a68a5ce9fL } },
  22447. /* 74 */
  22448. { { 0x5f67b63506ea5L,0x89a4fe0d66dc3L,0xe95cd4d9286c4L,0x6a953f101d3bfL,
  22449. 0x05cacea0b9884L },
  22450. { 0xdf60c9ceac44dL,0xf4354d1c3aa90L,0xd5dbabe3db29aL,0xefa908dd3de8aL,
  22451. 0x0e4982d1235e4L } },
  22452. /* 75 */
  22453. { { 0x04a22c34cd55eL,0xb32680d132231L,0xfa1d94358695bL,0x0499fb345afa1L,
  22454. 0x08046b7f616b2L },
  22455. { 0x3581e38e7d098L,0x8df46f0b70b53L,0x4cb78c4d7f61eL,0xaf5530dea9ea4L,
  22456. 0x0eb17ca7b9082L } },
  22457. /* 76 */
  22458. { { 0x1b59876a145b9L,0x0fc1bc71ec175L,0x92715bba5cf6bL,0xe131d3e035653L,
  22459. 0x0097b00bafab5L },
  22460. { 0x6c8e9565f69e1L,0x5ab5be5199aa6L,0xa4fd98477e8f7L,0xcc9e6033ba11dL,
  22461. 0x0f95c747bafdbL } },
  22462. /* 77 */
  22463. { { 0xf01d3bebae45eL,0xf0c4bc6955558L,0xbc64fc6a8ebe9L,0xd837aeb705b1dL,
  22464. 0x03512601e566eL },
  22465. { 0x6f1e1fa1161cdL,0xd54c65ef87933L,0x24f21e5328ab8L,0xab6b4757eee27L,
  22466. 0x00ef971236068L } },
  22467. /* 78 */
  22468. { { 0x98cf754ca4226L,0x38f8642c8e025L,0x68e17905eede1L,0xbc9548963f744L,
  22469. 0x0fc16d9333b4fL },
  22470. { 0x6fb31e7c800caL,0x312678adaabe9L,0xff3e8b5138063L,0x7a173d6244976L,
  22471. 0x014ca4af1b95dL } },
  22472. /* 79 */
  22473. { { 0x771babd2f81d5L,0x6901f7d1967a4L,0xad9c9071a5f9dL,0x231dd898bef7cL,
  22474. 0x04057b063f59cL },
  22475. { 0xd82fe89c05c0aL,0x6f1dc0df85bffL,0x35a16dbe4911cL,0x0b133befccaeaL,
  22476. 0x01c3b5d64f133L } },
  22477. /* 80 */
  22478. { { 0x14bfe80ec21feL,0x6ac255be825feL,0xf4a5d67f6ce11L,0x63af98bc5a072L,
  22479. 0x0fad27148db7eL },
  22480. { 0x0b6ac29ab05b3L,0x3c4e251ae690cL,0x2aade7d37a9a8L,0x1a840a7dc875cL,
  22481. 0x077387de39f0eL } },
  22482. /* 81 */
  22483. { { 0xecc49a56c0dd7L,0xd846086c741e9L,0x505aecea5cffcL,0xc47e8f7a1408fL,
  22484. 0x0b37b85c0bef0L },
  22485. { 0x6b6e4cc0e6a8fL,0xbf6b388f23359L,0x39cef4efd6d4bL,0x28d5aba453facL,
  22486. 0x09c135ac8f9f6L } },
  22487. /* 82 */
  22488. { { 0xa320284e35743L,0xb185a3cdef32aL,0xdf19819320d6aL,0x851fb821b1761L,
  22489. 0x05721361fc433L },
  22490. { 0xdb36a71fc9168L,0x735e5c403c1f0L,0x7bcd8f55f98baL,0x11bdf64ca87e3L,
  22491. 0x0dcbac3c9e6bbL } },
  22492. /* 83 */
  22493. { { 0xd99684518cbe2L,0x189c9eb04ef01L,0x47feebfd242fcL,0x6862727663c7eL,
  22494. 0x0b8c1c89e2d62L },
  22495. { 0x58bddc8e1d569L,0xc8b7d88cd051aL,0x11f31eb563809L,0x22d426c27fd9fL,
  22496. 0x05d23bbda2f94L } },
  22497. /* 84 */
  22498. { { 0xc729495c8f8beL,0x803bf362bf0a1L,0xf63d4ac2961c4L,0xe9009e418403dL,
  22499. 0x0c109f9cb91ecL },
  22500. { 0x095d058945705L,0x96ddeb85c0c2dL,0xa40449bb9083dL,0x1ee184692b8d7L,
  22501. 0x09bc3344f2eeeL } },
  22502. /* 85 */
  22503. { { 0xae35642913074L,0x2748a542b10d5L,0x310732a55491bL,0x4cc1469ca665bL,
  22504. 0x029591d525f1aL },
  22505. { 0xf5b6bb84f983fL,0x419f5f84e1e76L,0x0baa189be7eefL,0x332c1200d4968L,
  22506. 0x06376551f18efL } },
  22507. /* 86 */
  22508. { { 0x5f14e562976ccL,0xe60ef12c38bdaL,0xcca985222bca3L,0x987abbfa30646L,
  22509. 0x0bdb79dc808e2L },
  22510. { 0xcb5c9cb06a772L,0xaafe536dcefd2L,0xc2b5db838f475L,0xc14ac2a3e0227L,
  22511. 0x08ee86001add3L } },
  22512. /* 87 */
  22513. { { 0x96981a4ade873L,0x4dc4fba48ccbeL,0xa054ba57ee9aaL,0xaa4b2cee28995L,
  22514. 0x092e51d7a6f77L },
  22515. { 0xbafa87190a34dL,0x5bf6bd1ed1948L,0xcaf1144d698f7L,0xaaaad00ee6e30L,
  22516. 0x05182f86f0a56L } },
  22517. /* 88 */
  22518. { { 0x6212c7a4cc99cL,0x683e6d9ca1fbaL,0xac98c5aff609bL,0xa6f25dbb27cb5L,
  22519. 0x091dcab5d4073L },
  22520. { 0x6cc3d5f575a70L,0x396f8d87fa01bL,0x99817360cb361L,0x4f2b165d4e8c8L,
  22521. 0x017a0cedb9797L } },
  22522. /* 89 */
  22523. { { 0x61e2a076c8d3aL,0x39210f924b388L,0x3a835d9701aadL,0xdf4194d0eae41L,
  22524. 0x02e8ce36c7f4cL },
  22525. { 0x73dab037a862bL,0xb760e4c8fa912L,0x3baf2dd01ba9bL,0x68f3f96453883L,
  22526. 0x0f4ccc6cb34f6L } },
  22527. /* 90 */
  22528. { { 0xf525cf1f79687L,0x9592efa81544eL,0x5c78d297c5954L,0xf3c9e1231741aL,
  22529. 0x0ac0db4889a0dL },
  22530. { 0xfc711df01747fL,0x58ef17df1386bL,0xccb6bb5592b93L,0x74a2e5880e4f5L,
  22531. 0x095a64a6194c9L } },
  22532. /* 91 */
  22533. { { 0x1efdac15a4c93L,0x738258514172cL,0x6cb0bad40269bL,0x06776a8dfb1c1L,
  22534. 0x0231e54ba2921L },
  22535. { 0xdf9178ae6d2dcL,0x3f39112918a70L,0xe5b72234d6aa6L,0x31e1f627726b5L,
  22536. 0x0ab0be032d8a7L } },
  22537. /* 92 */
  22538. { { 0xad0e98d131f2dL,0xe33b04f101097L,0x5e9a748637f09L,0xa6791ac86196dL,
  22539. 0x0f1bcc8802cf6L },
  22540. { 0x69140e8daacb4L,0x5560f6500925cL,0x77937a63c4e40L,0xb271591cc8fc4L,
  22541. 0x0851694695aebL } },
  22542. /* 93 */
  22543. { { 0x5c143f1dcf593L,0x29b018be3bde3L,0xbdd9d3d78202bL,0x55d8e9cdadc29L,
  22544. 0x08f67d9d2daadL },
  22545. { 0x116567481ea5fL,0xe9e34c590c841L,0x5053fa8e7d2ddL,0x8b5dffdd43f40L,
  22546. 0x0f84572b9c072L } },
  22547. /* 94 */
  22548. { { 0xa7a7197af71c9L,0x447a7365655e1L,0xe1d5063a14494L,0x2c19a1b4ae070L,
  22549. 0x0edee2710616bL },
  22550. { 0x034f511734121L,0x554a25e9f0b2fL,0x40c2ecf1cac6eL,0xd7f48dc148f3aL,
  22551. 0x09fd27e9b44ebL } },
  22552. /* 95 */
  22553. { { 0x7658af6e2cb16L,0x2cfe5919b63ccL,0x68d5583e3eb7dL,0xf3875a8c58161L,
  22554. 0x0a40c2fb6958fL },
  22555. { 0xec560fedcc158L,0xc655f230568c9L,0xa307e127ad804L,0xdecfd93967049L,
  22556. 0x099bc9bb87dc6L } },
  22557. /* 96 */
  22558. { { 0x9521d927dafc6L,0x695c09cd1984aL,0x9366dde52c1fbL,0x7e649d9581a0fL,
  22559. 0x09abe210ba16dL },
  22560. { 0xaf84a48915220L,0x6a4dd816c6480L,0x681ca5afa7317L,0x44b0c7d539871L,
  22561. 0x07881c25787f3L } },
  22562. /* 97 */
  22563. { { 0x99b51e0bcf3ffL,0xc5127f74f6933L,0xd01d9680d02cbL,0x89408fb465a2dL,
  22564. 0x015e6e319a30eL },
  22565. { 0xd6e0d3e0e05f4L,0xdc43588404646L,0x4f850d3fad7bdL,0x72cebe61c7d1cL,
  22566. 0x00e55facf1911L } },
  22567. /* 98 */
  22568. { { 0xd9806f8787564L,0x2131e85ce67e9L,0x819e8d61a3317L,0x65776b0158cabL,
  22569. 0x0d73d09766fe9L },
  22570. { 0x834251eb7206eL,0x0fc618bb42424L,0xe30a520a51929L,0xa50b5dcbb8595L,
  22571. 0x09250a3748f15L } },
  22572. /* 99 */
  22573. { { 0xf08f8be577410L,0x035077a8c6cafL,0xc0a63a4fd408aL,0x8c0bf1f63289eL,
  22574. 0x077414082c1ccL },
  22575. { 0x40fa6eb0991cdL,0x6649fdc29605aL,0x324fd40c1ca08L,0x20b93a68a3c7bL,
  22576. 0x08cb04f4d12ebL } },
  22577. /* 100 */
  22578. { { 0x2d0556906171cL,0xcdb0240c3fb1cL,0x89068419073e9L,0x3b51db8e6b4fdL,
  22579. 0x0e4e429ef4712L },
  22580. { 0xdd53c38ec36f4L,0x01ff4b6a270b8L,0x79a9a48f9d2dcL,0x65525d066e078L,
  22581. 0x037bca2ff3c6eL } },
  22582. /* 101 */
  22583. { { 0x2e3c7df562470L,0xa2c0964ac94cdL,0x0c793be44f272L,0xb22a7c6d5df98L,
  22584. 0x059913edc3002L },
  22585. { 0x39a835750592aL,0x80e783de027a1L,0xa05d64f99e01dL,0xe226cf8c0375eL,
  22586. 0x043786e4ab013L } },
  22587. /* 102 */
  22588. { { 0x2b0ed9e56b5a6L,0xa6d9fc68f9ff3L,0x97846a70750d9L,0x9e7aec15e8455L,
  22589. 0x08638ca98b7e7L },
  22590. { 0xae0960afc24b2L,0xaf4dace8f22f5L,0xecba78f05398eL,0xa6f03b765dd0aL,
  22591. 0x01ecdd36a7b3aL } },
  22592. /* 103 */
  22593. { { 0xacd626c5ff2f3L,0xc02873a9785d3L,0x2110d54a2d516L,0xf32dad94c9fadL,
  22594. 0x0d85d0f85d459L },
  22595. { 0x00b8d10b11da3L,0x30a78318c49f7L,0x208decdd2c22cL,0x3c62556988f49L,
  22596. 0x0a04f19c3b4edL } },
  22597. /* 104 */
  22598. { { 0x924c8ed7f93bdL,0x5d392f51f6087L,0x21b71afcb64acL,0x50b07cae330a8L,
  22599. 0x092b2eeea5c09L },
  22600. { 0xc4c9485b6e235L,0xa92936c0f085aL,0x0508891ab2ca4L,0x276c80faa6b3eL,
  22601. 0x01ee782215834L } },
  22602. /* 105 */
  22603. { { 0xa2e00e63e79f7L,0xb2f399d906a60L,0x607c09df590e7L,0xe1509021054a6L,
  22604. 0x0f3f2ced857a6L },
  22605. { 0x510f3f10d9b55L,0xacd8642648200L,0x8bd0e7c9d2fcfL,0xe210e5631aa7eL,
  22606. 0x00f56a4543da3L } },
  22607. /* 106 */
  22608. { { 0x1bffa1043e0dfL,0xcc9c007e6d5b2L,0x4a8517a6c74b6L,0xe2631a656ec0dL,
  22609. 0x0bd8f17411969L },
  22610. { 0xbbb86beb7494aL,0x6f45f3b8388a9L,0x4e5a79a1567d4L,0xfa09df7a12a7aL,
  22611. 0x02d1a1c3530ccL } },
  22612. /* 107 */
  22613. { { 0xe3813506508daL,0xc4a1d795a7192L,0xa9944b3336180L,0xba46cddb59497L,
  22614. 0x0a107a65eb91fL },
  22615. { 0x1d1c50f94d639L,0x758a58b7d7e6dL,0xd37ca1c8b4af3L,0x9af21a7c5584bL,
  22616. 0x0183d760af87aL } },
  22617. /* 108 */
  22618. { { 0x697110dde59a4L,0x070e8bef8729dL,0xf2ebe78f1ad8dL,0xd754229b49634L,
  22619. 0x01d44179dc269L },
  22620. { 0xdc0cf8390d30eL,0x530de8110cb32L,0xbc0339a0a3b27L,0xd26231af1dc52L,
  22621. 0x0771f9cc29606L } },
  22622. /* 109 */
  22623. { { 0x93e7785040739L,0xb98026a939999L,0x5f8fc2644539dL,0x718ecf40f6f2fL,
  22624. 0x064427a310362L },
  22625. { 0xf2d8785428aa8L,0x3febfb49a84f4L,0x23d01ac7b7adcL,0x0d6d201b2c6dfL,
  22626. 0x049d9b7496ae9L } },
  22627. /* 110 */
  22628. { { 0x8d8bc435d1099L,0x4e8e8d1a08cc7L,0xcb68a412adbcdL,0x544502c2e2a02L,
  22629. 0x09037d81b3f60L },
  22630. { 0xbac27074c7b61L,0xab57bfd72e7cdL,0x96d5352fe2031L,0x639c61ccec965L,
  22631. 0x008c3de6a7cc0L } },
  22632. /* 111 */
  22633. { { 0xdd020f6d552abL,0x9805cd81f120fL,0x135129156baffL,0x6b2f06fb7c3e9L,
  22634. 0x0c69094424579L },
  22635. { 0x3ae9c41231bd1L,0x875cc5820517bL,0x9d6a1221eac6eL,0x3ac0208837abfL,
  22636. 0x03fa3db02cafeL } },
  22637. /* 112 */
  22638. { { 0xa3e6505058880L,0xef643943f2d75L,0xab249257da365L,0x08ff4147861cfL,
  22639. 0x0c5c4bdb0fdb8L },
  22640. { 0x13e34b272b56bL,0x9511b9043a735L,0x8844969c8327eL,0xb6b5fd8ce37dfL,
  22641. 0x02d56db9446c2L } },
  22642. /* 113 */
  22643. { { 0x1782fff46ac6bL,0x2607a2e425246L,0x9a48de1d19f79L,0xba42fafea3c40L,
  22644. 0x00f56bd9de503L },
  22645. { 0xd4ed1345cda49L,0xfc816f299d137L,0xeb43402821158L,0xb5f1e7c6a54aaL,
  22646. 0x04003bb9d1173L } },
  22647. /* 114 */
  22648. { { 0xe8189a0803387L,0xf539cbd4043b8L,0x2877f21ece115L,0x2f9e4297208ddL,
  22649. 0x053765522a07fL },
  22650. { 0x80a21a8a4182dL,0x7a3219df79a49L,0xa19a2d4a2bbd0L,0x4549674d0a2e1L,
  22651. 0x07a056f586c5dL } },
  22652. /* 115 */
  22653. { { 0xb25589d8a2a47L,0x48c3df2773646L,0xbf0d5395b5829L,0x267551ec000eaL,
  22654. 0x077d482f17a1aL },
  22655. { 0x1bd9587853948L,0xbd6cfbffeeb8aL,0x0681e47a6f817L,0xb0e4ab6ec0578L,
  22656. 0x04115012b2b38L } },
  22657. /* 116 */
  22658. { { 0x3f0f46de28cedL,0x609b13ec473c7L,0xe5c63921d5da7L,0x094661b8ce9e6L,
  22659. 0x0cdf04572fbeaL },
  22660. { 0x3c58b6c53c3b0L,0x10447b843c1cbL,0xcb9780e97fe3cL,0x3109fb2b8ae12L,
  22661. 0x0ee703dda9738L } },
  22662. /* 117 */
  22663. { { 0x15140ff57e43aL,0xd3b1b811b8345L,0xf42b986d44660L,0xce212b3b5dff8L,
  22664. 0x02a0ad89da162L },
  22665. { 0x4a6946bc277baL,0x54c141c27664eL,0xabf6274c788c9L,0x4659141aa64ccL,
  22666. 0x0d62d0b67ac2bL } },
  22667. /* 118 */
  22668. { { 0x5d87b2c054ac4L,0x59f27df78839cL,0x18128d6570058L,0x2426edf7cbf3bL,
  22669. 0x0b39a23f2991cL },
  22670. { 0x84a15f0b16ae5L,0xb1a136f51b952L,0x27007830c6a05L,0x4cc51d63c137fL,
  22671. 0x004ed0092c067L } },
  22672. /* 119 */
  22673. { { 0x185d19ae90393L,0x294a3d64e61f4L,0x854fc143047b4L,0xc387ae0001a69L,
  22674. 0x0a0a91fc10177L },
  22675. { 0xa3f01ae2c831eL,0x822b727e16ff0L,0xa3075b4bb76aeL,0x0c418f12c8a15L,
  22676. 0x0084cf9889ed2L } },
  22677. /* 120 */
  22678. { { 0x509defca6becfL,0x807dffb328d98L,0x778e8b92fceaeL,0xf77e5d8a15c44L,
  22679. 0x0d57955b273abL },
  22680. { 0xda79e31b5d4f1L,0x4b3cfa7a1c210L,0xc27c20baa52f0L,0x41f1d4d12089dL,
  22681. 0x08e14ea4202d1L } },
  22682. /* 121 */
  22683. { { 0x50345f2897042L,0x1f43402c4aeedL,0x8bdfb218d0533L,0xd158c8d9c194cL,
  22684. 0x0597e1a372aa4L },
  22685. { 0x7ec1acf0bd68cL,0xdcab024945032L,0x9fe3e846d4be0L,0x4dea5b9c8d7acL,
  22686. 0x0ca3f0236199bL } },
  22687. /* 122 */
  22688. { { 0xa10b56170bd20L,0xf16d3f5de7592L,0x4b2ade20ea897L,0x07e4a3363ff14L,
  22689. 0x0bde7fd7e309cL },
  22690. { 0xbb6d2b8f5432cL,0xcbe043444b516L,0x8f95b5a210dc1L,0xd1983db01e6ffL,
  22691. 0x0b623ad0e0a7dL } },
  22692. /* 123 */
  22693. { { 0xbd67560c7b65bL,0x9023a4a289a75L,0x7b26795ab8c55L,0x137bf8220fd0dL,
  22694. 0x0d6aa2e4658ecL },
  22695. { 0xbc00b5138bb85L,0x21d833a95c10aL,0x702a32e8c31d1L,0x513ab24ff00b1L,
  22696. 0x0111662e02dccL } },
  22697. /* 124 */
  22698. { { 0x14015efb42b87L,0x701b6c4dff781L,0x7d7c129bd9f5dL,0x50f866ecccd7aL,
  22699. 0x0db3ee1cb94b7L },
  22700. { 0xf3db0f34837cfL,0x8bb9578d4fb26L,0xc56657de7eed1L,0x6a595d2cdf937L,
  22701. 0x0886a64425220L } },
  22702. /* 125 */
  22703. { { 0x34cfb65b569eaL,0x41f72119c13c2L,0x15a619e200111L,0x17bc8badc85daL,
  22704. 0x0a70cf4eb018aL },
  22705. { 0xf97ae8c4a6a65L,0x270134378f224L,0xf7e096036e5cfL,0x7b77be3a609e4L,
  22706. 0x0aa4772abd174L } },
  22707. /* 126 */
  22708. { { 0x761317aa60cc0L,0x610368115f676L,0xbc1bb5ac79163L,0xf974ded98bb4bL,
  22709. 0x0611a6ddc30faL },
  22710. { 0x78cbcc15ee47aL,0x824e0d96a530eL,0xdd9ed882e8962L,0x9c8836f35adf3L,
  22711. 0x05cfffaf81642L } },
  22712. /* 127 */
  22713. { { 0x54cff9b7a99cdL,0x9d843c45a1c0dL,0x2c739e17bf3b9L,0x994c038a908f6L,
  22714. 0x06e5a6b237dc1L },
  22715. { 0xb454e0ba5db77L,0x7facf60d63ef8L,0x6608378b7b880L,0xabcce591c0c67L,
  22716. 0x0481a238d242dL } },
  22717. /* 128 */
  22718. { { 0x17bc035d0b34aL,0x6b8327c0a7e34L,0xc0362d1440b38L,0xf9438fb7262daL,
  22719. 0x02c41114ce0cdL },
  22720. { 0x5cef1ad95a0b1L,0xa867d543622baL,0x1e486c9c09b37L,0x929726d6cdd20L,
  22721. 0x020477abf42ffL } },
  22722. /* 129 */
  22723. { { 0x5173c18d65dbfL,0x0e339edad82f7L,0xcf1001c77bf94L,0x96b67022d26bdL,
  22724. 0x0ac66409ac773L },
  22725. { 0xbb36fc6261cc3L,0xc9190e7e908b0L,0x45e6c10213f7bL,0x2f856541cebaaL,
  22726. 0x0ce8e6975cc12L } },
  22727. /* 130 */
  22728. { { 0x21b41bc0a67d2L,0x0a444d248a0f1L,0x59b473762d476L,0xb4a80e044f1d6L,
  22729. 0x008fde365250bL },
  22730. { 0xec3da848bf287L,0x82d3369d6eaceL,0x2449482c2a621L,0x6cd73582dfdc9L,
  22731. 0x02f7e2fd2565dL } },
  22732. /* 131 */
  22733. { { 0xb92dbc3770fa7L,0x5c379043f9ae4L,0x7761171095e8dL,0x02ae54f34e9d1L,
  22734. 0x0c65be92e9077L },
  22735. { 0x8a303f6fd0a40L,0xe3bcce784b275L,0xf9767bfe7d822L,0x3b3a7ae4f5854L,
  22736. 0x04bff8e47d119L } },
  22737. /* 132 */
  22738. { { 0x1d21f00ff1480L,0x7d0754db16cd4L,0xbe0f3ea2ab8fbL,0x967dac81d2efbL,
  22739. 0x03e4e4ae65772L },
  22740. { 0x8f36d3c5303e6L,0x4b922623977e1L,0x324c3c03bd999L,0x60289ed70e261L,
  22741. 0x05388aefd58ecL } },
  22742. /* 133 */
  22743. { { 0x317eb5e5d7713L,0xee75de49daad1L,0x74fb26109b985L,0xbe0e32f5bc4fcL,
  22744. 0x05cf908d14f75L },
  22745. { 0x435108e657b12L,0xa5b96ed9e6760L,0x970ccc2bfd421L,0x0ce20e29f51f8L,
  22746. 0x0a698ba4060f0L } },
  22747. /* 134 */
  22748. { { 0xb1686ef748fecL,0xa27e9d2cf973dL,0xe265effe6e755L,0xad8d630b6544cL,
  22749. 0x0b142ef8a7aebL },
  22750. { 0x1af9f17d5770aL,0x672cb3412fad3L,0xf3359de66af3bL,0x50756bd60d1bdL,
  22751. 0x0d1896a965851L } },
  22752. /* 135 */
  22753. { { 0x957ab33c41c08L,0xac5468e2e1ec5L,0xc472f6c87de94L,0xda3918816b73aL,
  22754. 0x0267b0e0b7981L },
  22755. { 0x54e5d8e62b988L,0x55116d21e76e5L,0xd2a6f99d8ddc7L,0x93934610faf03L,
  22756. 0x0b54e287aa111L } },
  22757. /* 136 */
  22758. { { 0x122b5178a876bL,0xff085104b40a0L,0x4f29f7651ff96L,0xd4e6050b31ab1L,
  22759. 0x084abb28b5f87L },
  22760. { 0xd439f8270790aL,0x9d85e3f46bd5eL,0xc1e22122d6cb5L,0x564075f55c1b6L,
  22761. 0x0e5436f671765L } },
  22762. /* 137 */
  22763. { { 0x9025e2286e8d5L,0xb4864453be53fL,0x408e3a0353c95L,0xe99ed832f5bdeL,
  22764. 0x00404f68b5b9cL },
  22765. { 0x33bdea781e8e5L,0x18163c2f5bcadL,0x119caa33cdf50L,0xc701575769600L,
  22766. 0x03a4263df0ac1L } },
  22767. /* 138 */
  22768. { { 0x65ecc9aeb596dL,0xe7023c92b4c29L,0xe01396101ea03L,0xa3674704b4b62L,
  22769. 0x00ca8fd3f905eL },
  22770. { 0x23a42551b2b61L,0x9c390fcd06925L,0x392a63e1eb7a8L,0x0c33e7f1d2be0L,
  22771. 0x096dca2644ddbL } },
  22772. /* 139 */
  22773. { { 0xbb43a387510afL,0xa8a9a36a01203L,0xf950378846feaL,0x59dcd23a57702L,
  22774. 0x04363e2123aadL },
  22775. { 0x3a1c740246a47L,0xd2e55dd24dca4L,0xd8faf96b362b8L,0x98c4f9b086045L,
  22776. 0x0840e115cd8bbL } },
  22777. /* 140 */
  22778. { { 0x205e21023e8a7L,0xcdd8dc7a0bf12L,0x63a5ddfc808a8L,0xd6d4e292a2721L,
  22779. 0x05e0d6abd30deL },
  22780. { 0x721c27cfc0f64L,0x1d0e55ed8807aL,0xd1f9db242eec0L,0xa25a26a7bef91L,
  22781. 0x07dea48f42945L } },
  22782. /* 141 */
  22783. { { 0xf6f1ce5060a81L,0x72f8f95615abdL,0x6ac268be79f9cL,0x16d1cfd36c540L,
  22784. 0x0abc2a2beebfdL },
  22785. { 0x66f91d3e2eac7L,0x63d2dd04668acL,0x282d31b6f10baL,0xefc16790e3770L,
  22786. 0x04ea353946c7eL } },
  22787. /* 142 */
  22788. { { 0xa2f8d5266309dL,0xc081945a3eed8L,0x78c5dc10a51c6L,0xffc3cecaf45a5L,
  22789. 0x03a76e6891c94L },
  22790. { 0xce8a47d7b0d0fL,0x968f584a5f9aaL,0xe697fbe963aceL,0x646451a30c724L,
  22791. 0x08212a10a465eL } },
  22792. /* 143 */
  22793. { { 0xc61c3cfab8caaL,0x840e142390ef7L,0xe9733ca18eb8eL,0xb164cd1dff677L,
  22794. 0x0aa7cab71599cL },
  22795. { 0xc9273bc837bd1L,0xd0c36af5d702fL,0x423da49c06407L,0x17c317621292fL,
  22796. 0x040e38073fe06L } },
  22797. /* 144 */
  22798. { { 0x80824a7bf9b7cL,0x203fbe30d0f4fL,0x7cf9ce3365d23L,0x5526bfbe53209L,
  22799. 0x0e3604700b305L },
  22800. { 0xb99116cc6c2c7L,0x08ba4cbee64dcL,0x37ad9ec726837L,0xe15fdcded4346L,
  22801. 0x06542d677a3deL } },
  22802. /* 145 */
  22803. { { 0x2b6d07b6c377aL,0x47903448be3f3L,0x0da8af76cb038L,0x6f21d6fdd3a82L,
  22804. 0x0a6534aee09bbL },
  22805. { 0x1780d1035facfL,0x339dcb47e630aL,0x447f39335e55aL,0xef226ea50fe1cL,
  22806. 0x0f3cb672fdc9aL } },
  22807. /* 146 */
  22808. { { 0x719fe3b55fd83L,0x6c875ddd10eb3L,0x5cea784e0d7a4L,0x70e733ac9fa90L,
  22809. 0x07cafaa2eaae8L },
  22810. { 0x14d041d53b338L,0xa0ef87e6c69b8L,0x1672b0fe0acc0L,0x522efb93d1081L,
  22811. 0x00aab13c1b9bdL } },
  22812. /* 147 */
  22813. { { 0xce278d2681297L,0xb1b509546addcL,0x661aaf2cb350eL,0x12e92dc431737L,
  22814. 0x04b91a6028470L },
  22815. { 0xf109572f8ddcfL,0x1e9a911af4dcfL,0x372430e08ebf6L,0x1cab48f4360acL,
  22816. 0x049534c537232L } },
  22817. /* 148 */
  22818. { { 0xf7d71f07b7e9dL,0xa313cd516f83dL,0xc047ee3a478efL,0xc5ee78ef264b6L,
  22819. 0x0caf46c4fd65aL },
  22820. { 0xd0c7792aa8266L,0x66913684bba04L,0xe4b16b0edf454L,0x770f56e65168aL,
  22821. 0x014ce9e5704c6L } },
  22822. /* 149 */
  22823. { { 0x45e3e965e8f91L,0xbacb0f2492994L,0x0c8a0a0d3aca1L,0x9a71d31cc70f9L,
  22824. 0x01bb708a53e4cL },
  22825. { 0xa9e69558bdd7aL,0x08018a26b1d5cL,0xc9cf1ec734a05L,0x0102b093aa714L,
  22826. 0x0f9d126f2da30L } },
  22827. /* 150 */
  22828. { { 0xbca7aaff9563eL,0xfeb49914a0749L,0xf5f1671dd077aL,0xcc69e27a0311bL,
  22829. 0x0807afcb9729eL },
  22830. { 0xa9337c9b08b77L,0x85443c7e387f8L,0x76fd8ba86c3a7L,0xcd8c85fafa594L,
  22831. 0x0751adcd16568L } },
  22832. /* 151 */
  22833. { { 0xa38b410715c0dL,0x718f7697f78aeL,0x3fbf06dd113eaL,0x743f665eab149L,
  22834. 0x029ec44682537L },
  22835. { 0x4719cb50bebbcL,0xbfe45054223d9L,0xd2dedb1399ee5L,0x077d90cd5b3a8L,
  22836. 0x0ff9370e392a4L } },
  22837. /* 152 */
  22838. { { 0x2d69bc6b75b65L,0xd5266651c559aL,0xde9d7d24188f8L,0xd01a28a9f33e3L,
  22839. 0x09776478ba2a9L },
  22840. { 0x2622d929af2c7L,0x6d4e690923885L,0x89a51e9334f5dL,0x82face6cc7e5aL,
  22841. 0x074a6313fac2fL } },
  22842. /* 153 */
  22843. { { 0x4dfddb75f079cL,0x9518e36fbbb2fL,0x7cd36dd85b07cL,0x863d1b6cfcf0eL,
  22844. 0x0ab75be150ff4L },
  22845. { 0x367c0173fc9b7L,0x20d2594fd081bL,0x4091236b90a74L,0x59f615fdbf03cL,
  22846. 0x04ebeac2e0b44L } },
  22847. /* 154 */
  22848. { { 0xc5fe75c9f2c53L,0x118eae9411eb6L,0x95ac5d8d25220L,0xaffcc8887633fL,
  22849. 0x0df99887b2c1bL },
  22850. { 0x8eed2850aaecbL,0x1b01d6a272bb7L,0x1cdbcac9d4918L,0x4058978dd511bL,
  22851. 0x027b040a7779fL } },
  22852. /* 155 */
  22853. { { 0x05db7f73b2eb2L,0x088e1b2118904L,0x962327ee0df85L,0xa3f5501b71525L,
  22854. 0x0b393dd37e4cfL },
  22855. { 0x30e7b3fd75165L,0xc2bcd33554a12L,0xf7b5022d66344L,0x34196c36f1be0L,
  22856. 0x009588c12d046L } },
  22857. /* 156 */
  22858. { { 0x6093f02601c3bL,0xf8cf5c335fe08L,0x94aff28fb0252L,0x648b955cf2808L,
  22859. 0x081c879a9db9fL },
  22860. { 0xe687cc6f56c51L,0x693f17618c040L,0x059353bfed471L,0x1bc444f88a419L,
  22861. 0x0fa0d48f55fc1L } },
  22862. /* 157 */
  22863. { { 0xe1c9de1608e4dL,0x113582822cbc6L,0x57ec2d7010ddaL,0x67d6f6b7ddc11L,
  22864. 0x08ea0e156b6a3L },
  22865. { 0x4e02f2383b3b4L,0x943f01f53ca35L,0xde03ca569966bL,0xb5ac4ff6632b2L,
  22866. 0x03f5ab924fa00L } },
  22867. /* 158 */
  22868. { { 0xbb0d959739efbL,0xf4e7ebec0d337L,0x11a67d1c751b0L,0x256e2da52dd64L,
  22869. 0x08bc768872b74L },
  22870. { 0xe3b7282d3d253L,0xa1f58d779fa5bL,0x16767bba9f679L,0xf34fa1cac168eL,
  22871. 0x0b386f19060fcL } },
  22872. /* 159 */
  22873. { { 0x3c1352fedcfc2L,0x6262f8af0d31fL,0x57288c25396bfL,0x9c4d9a02b4eaeL,
  22874. 0x04cb460f71b06L },
  22875. { 0x7b4d35b8095eaL,0x596fc07603ae6L,0x614a16592bbf8L,0x5223e1475f66bL,
  22876. 0x052c0d50895efL } },
  22877. /* 160 */
  22878. { { 0xc210e15339848L,0xe870778c8d231L,0x956e170e87a28L,0x9c0b9d1de6616L,
  22879. 0x04ac3c9382bb0L },
  22880. { 0xe05516998987dL,0xc4ae09f4d619bL,0xa3f933d8b2376L,0x05f41de0b7651L,
  22881. 0x0380d94c7e397L } },
  22882. /* 161 */
  22883. { { 0x355aa81542e75L,0xa1ee01b9b701aL,0x24d708796c724L,0x37af6b3a29776L,
  22884. 0x02ce3e171de26L },
  22885. { 0xfeb49f5d5bc1aL,0x7e2777e2b5cfeL,0x513756ca65560L,0x4e4d4feaac2f9L,
  22886. 0x02e6cd8520b62L } },
  22887. /* 162 */
  22888. { { 0x5954b8c31c31dL,0x005bf21a0c368L,0x5c79ec968533dL,0x9d540bd7626e7L,
  22889. 0x0ca17754742c6L },
  22890. { 0xedafff6d2dbb2L,0xbd174a9d18cc6L,0xa4578e8fd0d8cL,0x2ce6875e8793aL,
  22891. 0x0a976a7139cabL } },
  22892. /* 163 */
  22893. { { 0x51f1b93fb353dL,0x8b57fcfa720a6L,0x1b15281d75cabL,0x4999aa88cfa73L,
  22894. 0x08720a7170a1fL },
  22895. { 0xe8d37693e1b90L,0x0b16f6dfc38c3L,0x52a8742d345dcL,0x893c8ea8d00abL,
  22896. 0x09719ef29c769L } },
  22897. /* 164 */
  22898. { { 0xeed8d58e35909L,0xdc33ddc116820L,0xe2050269366d8L,0x04c1d7f999d06L,
  22899. 0x0a5072976e157L },
  22900. { 0xa37eac4e70b2eL,0x576890aa8a002L,0x45b2a5c84dcf6L,0x7725cd71bf186L,
  22901. 0x099389c9df7b7L } },
  22902. /* 165 */
  22903. { { 0xc08f27ada7a4bL,0x03fd389366238L,0x66f512c3abe9dL,0x82e46b672e897L,
  22904. 0x0a88806aa202cL },
  22905. { 0x2044ad380184eL,0xc4126a8b85660L,0xd844f17a8cb78L,0xdcfe79d670c0aL,
  22906. 0x00043bffb4738L } },
  22907. /* 166 */
  22908. { { 0x9b5dc36d5192eL,0xd34590b2af8d5L,0x1601781acf885L,0x486683566d0a1L,
  22909. 0x052f3ef01ba6cL },
  22910. { 0x6732a0edcb64dL,0x238068379f398L,0x040f3090a482cL,0x7e7516cbe5fa7L,
  22911. 0x03296bd899ef2L } },
  22912. /* 167 */
  22913. { { 0xaba89454d81d7L,0xef51eb9b3c476L,0x1c579869eade7L,0x71e9619a21cd8L,
  22914. 0x03b90febfaee5L },
  22915. { 0x3023e5496f7cbL,0xd87fb51bc4939L,0x9beb5ce55be41L,0x0b1803f1dd489L,
  22916. 0x06e88069d9f81L } },
  22917. /* 168 */
  22918. { { 0x7ab11b43ea1dbL,0xa95259d292ce3L,0xf84f1860a7ff1L,0xad13851b02218L,
  22919. 0x0a7222beadefaL },
  22920. { 0xc78ec2b0a9144L,0x51f2fa59c5a2aL,0x147ce385a0240L,0xc69091d1eca56L,
  22921. 0x0be94d523bc2aL } },
  22922. /* 169 */
  22923. { { 0x4945e0b226ce7L,0x47967e8b7072fL,0x5a6c63eb8afd7L,0xc766edea46f18L,
  22924. 0x07782defe9be8L },
  22925. { 0xd2aa43db38626L,0x8776f67ad1760L,0x4499cdb460ae7L,0x2e4b341b86fc5L,
  22926. 0x003838567a289L } },
  22927. /* 170 */
  22928. { { 0xdaefd79ec1a0fL,0xfdceb39c972d8L,0x8f61a953bbcd6L,0xb420f5575ffc5L,
  22929. 0x0dbd986c4adf7L },
  22930. { 0xa881415f39eb7L,0xf5b98d976c81aL,0xf2f717d6ee2fcL,0xbbd05465475dcL,
  22931. 0x08e24d3c46860L } },
  22932. /* 171 */
  22933. { { 0xd8e549a587390L,0x4f0cbec588749L,0x25983c612bb19L,0xafc846e07da4bL,
  22934. 0x0541a99c4407bL },
  22935. { 0x41692624c8842L,0x2ad86c05ffdb2L,0xf7fcf626044c1L,0x35d1c59d14b44L,
  22936. 0x0c0092c49f57dL } },
  22937. /* 172 */
  22938. { { 0xc75c3df2e61efL,0xc82e1b35cad3cL,0x09f29f47e8841L,0x944dc62d30d19L,
  22939. 0x075e406347286L },
  22940. { 0x41fc5bbc237d0L,0xf0ec4f01c9e7dL,0x82bd534c9537bL,0x858691c51a162L,
  22941. 0x05b7cb658c784L } },
  22942. /* 173 */
  22943. { { 0xa70848a28ead1L,0x08fd3b47f6964L,0x67e5b39802dc5L,0x97a19ae4bfd17L,
  22944. 0x07ae13eba8df0L },
  22945. { 0x16ef8eadd384eL,0xd9b6b2ff06fd2L,0xbcdb5f30361a2L,0xe3fd204b98784L,
  22946. 0x0787d8074e2a8L } },
  22947. /* 174 */
  22948. { { 0x25d6b757fbb1cL,0xb2ca201debc5eL,0xd2233ffe47bddL,0x84844a55e9a36L,
  22949. 0x05c2228199ef2L },
  22950. { 0xd4a8588315250L,0x2b827097c1773L,0xef5d33f21b21aL,0xf2b0ab7c4ea1dL,
  22951. 0x0e45d37abbaf0L } },
  22952. /* 175 */
  22953. { { 0xf1e3428511c8aL,0xc8bdca6cd3d2dL,0x27c39a7ebb229L,0xb9d3578a71a76L,
  22954. 0x0ed7bc12284dfL },
  22955. { 0x2a6df93dea561L,0x8dd48f0ed1cf2L,0xbad23e85443f1L,0x6d27d8b861405L,
  22956. 0x0aac97cc945caL } },
  22957. /* 176 */
  22958. { { 0x4ea74a16bd00aL,0xadf5c0bcc1eb5L,0xf9bfc06d839e9L,0xdc4e092bb7f11L,
  22959. 0x0318f97b31163L },
  22960. { 0x0c5bec30d7138L,0x23abc30220eccL,0x022360644e8dfL,0xff4d2bb7972fbL,
  22961. 0x0fa41faa19a84L } },
  22962. /* 177 */
  22963. { { 0x2d974a6642269L,0xce9bb783bd440L,0x941e60bc81814L,0xe9e2398d38e47L,
  22964. 0x038bb6b2c1d26L },
  22965. { 0xe4a256a577f87L,0x53dc11fe1cc64L,0x22807288b52d2L,0x01a5ff336abf6L,
  22966. 0x094dd0905ce76L } },
  22967. /* 178 */
  22968. { { 0xcf7dcde93f92aL,0xcb89b5f315156L,0x995e750a01333L,0x2ae902404df9cL,
  22969. 0x092077867d25cL },
  22970. { 0x71e010bf39d44L,0x2096bb53d7e24L,0xc9c3d8f5f2c90L,0xeb514c44b7b35L,
  22971. 0x081e8428bd29bL } },
  22972. /* 179 */
  22973. { { 0x9c2bac477199fL,0xee6b5ecdd96ddL,0xe40fd0e8cb8eeL,0xa4b18af7db3feL,
  22974. 0x01b94ab62dbbfL },
  22975. { 0x0d8b3ce47f143L,0xfc63f4616344fL,0xc59938351e623L,0x90eef18f270fcL,
  22976. 0x006a38e280555L } },
  22977. /* 180 */
  22978. { { 0xb0139b3355b49L,0x60b4ebf99b2e5L,0x269f3dc20e265L,0xd4f8c08ffa6bdL,
  22979. 0x0a7b36c2083d9L },
  22980. { 0x15c3a1b3e8830L,0xe1a89f9c0b64dL,0x2d16930d5fceaL,0x2a20cfeee4a2eL,
  22981. 0x0be54c6b4a282L } },
  22982. /* 181 */
  22983. { { 0xdb3df8d91167cL,0x79e7a6625ed6cL,0x46ac7f4517c3fL,0x22bb7105648f3L,
  22984. 0x0bf30a5abeae0L },
  22985. { 0x785be93828a68L,0x327f3ef0368e7L,0x92146b25161c3L,0xd13ae11b5feb5L,
  22986. 0x0d1c820de2732L } },
  22987. /* 182 */
  22988. { { 0xe13479038b363L,0x546b05e519043L,0x026cad158c11fL,0x8da34fe57abe6L,
  22989. 0x0b7d17bed68a1L },
  22990. { 0xa5891e29c2559L,0x765bfffd8444cL,0x4e469484f7a03L,0xcc64498de4af7L,
  22991. 0x03997fd5e6412L } },
  22992. /* 183 */
  22993. { { 0x746828bd61507L,0xd534a64d2af20L,0xa8a15e329e132L,0x13e8ffeddfb08L,
  22994. 0x00eeb89293c6cL },
  22995. { 0x69a3ea7e259f8L,0xe6d13e7e67e9bL,0xd1fa685ce1db7L,0xb6ef277318f6aL,
  22996. 0x0228916f8c922L } },
  22997. /* 184 */
  22998. { { 0xae25b0a12ab5bL,0x1f957bc136959L,0x16e2b0ccc1117L,0x097e8058429edL,
  22999. 0x0ec05ad1d6e93L },
  23000. { 0xba5beac3f3708L,0x3530b59d77157L,0x18234e531baf9L,0x1b3747b552371L,
  23001. 0x07d3141567ff1L } },
  23002. /* 185 */
  23003. { { 0x9c05cf6dfefabL,0x68dcb377077bdL,0xa38bb95be2f22L,0xd7a3e53ead973L,
  23004. 0x0e9ce66fc9bc1L },
  23005. { 0xa15766f6a02a1L,0xdf60e600ed75aL,0x8cdc1b938c087L,0x0651f8947f346L,
  23006. 0x0d9650b017228L } },
  23007. /* 186 */
  23008. { { 0xb4c4a5a057e60L,0xbe8def25e4504L,0x7c1ccbdcbccc3L,0xb7a2a63532081L,
  23009. 0x014d6699a804eL },
  23010. { 0xa8415db1f411aL,0x0bf80d769c2c8L,0xc2f77ad09fbafL,0x598ab4deef901L,
  23011. 0x06f4c68410d43L } },
  23012. /* 187 */
  23013. { { 0x6df4e96c24a96L,0x85fcbd99a3872L,0xb2ae30a534dbcL,0x9abb3c466ef28L,
  23014. 0x04c4350fd6118L },
  23015. { 0x7f716f855b8daL,0x94463c38a1296L,0xae9334341a423L,0x18b5c37e1413eL,
  23016. 0x0a726d2425a31L } },
  23017. /* 188 */
  23018. { { 0x6b3ee948c1086L,0x3dcbd3a2e1daeL,0x3d022f3f1de50L,0xf3923f35ed3f0L,
  23019. 0x013639e82cc6cL },
  23020. { 0x938fbcdafaa86L,0xfb2654a2589acL,0x5051329f45bc5L,0x35a31963b26e4L,
  23021. 0x0ca9365e1c1a3L } },
  23022. /* 189 */
  23023. { { 0x5ac754c3b2d20L,0x17904e241b361L,0xc9d071d742a54L,0x72a5b08521c4cL,
  23024. 0x09ce29c34970bL },
  23025. { 0x81f736d3e0ad6L,0x9ef2f8434c8ccL,0xce862d98060daL,0xaf9835ed1d1a6L,
  23026. 0x048c4abd7ab42L } },
  23027. /* 190 */
  23028. { { 0x1b0cc40c7485aL,0xbbe5274dbfd22L,0x263d2e8ead455L,0x33cb493c76989L,
  23029. 0x078017c32f67bL },
  23030. { 0x35769930cb5eeL,0x940c408ed2b9dL,0x72f1a4dc0d14eL,0x1c04f8b7bf552L,
  23031. 0x053cd0454de5cL } },
  23032. /* 191 */
  23033. { { 0x585fa5d28ccacL,0x56005b746ebcdL,0xd0123aa5f823eL,0xfa8f7c79f0a1cL,
  23034. 0x0eea465c1d3d7L },
  23035. { 0x0659f0551803bL,0x9f7ce6af70781L,0x9288e706c0b59L,0x91934195a7702L,
  23036. 0x01b6e42a47ae6L } },
  23037. /* 192 */
  23038. { { 0x0937cf67d04c3L,0xe289eeb8112e8L,0x2594d601e312bL,0xbd3d56b5d8879L,
  23039. 0x00224da14187fL },
  23040. { 0xbb8630c5fe36fL,0x604ef51f5f87aL,0x3b429ec580f3cL,0xff33964fb1bfbL,
  23041. 0x060838ef042bfL } },
  23042. /* 193 */
  23043. { { 0xcb2f27e0bbe99L,0xf304aa39ee432L,0xfa939037bda44L,0x16435f497c7a9L,
  23044. 0x0636eb2022d33L },
  23045. { 0xd0e6193ae00aaL,0xfe31ae6d2ffcfL,0xf93901c875a00L,0x8bacf43658a29L,
  23046. 0x08844eeb63921L } },
  23047. /* 194 */
  23048. { { 0x171d26b3bae58L,0x7117e39f3e114L,0x1a8eada7db3dfL,0x789ecd37bc7f8L,
  23049. 0x027ba83dc51fbL },
  23050. { 0xf439ffbf54de5L,0x0bb5fe1a71a7dL,0xb297a48727703L,0xa4ab42ee8e35dL,
  23051. 0x0adb62d3487f3L } },
  23052. /* 195 */
  23053. { { 0x168a2a175df2aL,0x4f618c32e99b1L,0x46b0916082aa0L,0xc8b2c9e4f2e71L,
  23054. 0x0b990fd7675e7L },
  23055. { 0x9d96b4df37313L,0x79d0b40789082L,0x80877111c2055L,0xd18d66c9ae4a7L,
  23056. 0x081707ef94d10L } },
  23057. /* 196 */
  23058. { { 0x7cab203d6ff96L,0xfc0d84336097dL,0x042db4b5b851bL,0xaa5c268823c4dL,
  23059. 0x03792daead5a8L },
  23060. { 0x18865941afa0bL,0x4142d83671528L,0xbe4e0a7f3e9e7L,0x01ba17c825275L,
  23061. 0x05abd635e94b0L } },
  23062. /* 197 */
  23063. { { 0xfa84e0ac4927cL,0x35a7c8cf23727L,0xadca0dfe38860L,0xb610a4bcd5ea4L,
  23064. 0x05995bf21846aL },
  23065. { 0xf860b829dfa33L,0xae958fc18be90L,0x8630366caafe2L,0x411e9b3baf447L,
  23066. 0x044c32ca2d483L } },
  23067. /* 198 */
  23068. { { 0xa97f1e40ed80cL,0xb131d2ca82a74L,0xc2d6ad95f938cL,0xa54c53f2124b7L,
  23069. 0x01f2162fb8082L },
  23070. { 0x67cc5720b173eL,0x66085f12f97e4L,0xc9d65dc40e8a6L,0x07c98cebc20e4L,
  23071. 0x08f1d402bc3e9L } },
  23072. /* 199 */
  23073. { { 0x92f9cfbc4058aL,0xb6292f56704f5L,0xc1d8c57b15e14L,0xdbf9c55cfe37bL,
  23074. 0x0b1980f43926eL },
  23075. { 0x33e0932c76b09L,0x9d33b07f7898cL,0x63bb4611df527L,0x8e456f08ead48L,
  23076. 0x02828ad9b3744L } },
  23077. /* 200 */
  23078. { { 0x722c4c4cf4ac5L,0x3fdde64afb696L,0x0890832f5ac1aL,0xb3900551baa2eL,
  23079. 0x04973f1275a14L },
  23080. { 0xd8335322eac5dL,0xf50bd9b568e59L,0x25883935e07eeL,0x8ac7ab36720faL,
  23081. 0x06dac8ed0db16L } },
  23082. /* 201 */
  23083. { { 0x545aeeda835efL,0xd21d10ed51f7bL,0x3741b094aa113L,0xde4c035a65e01L,
  23084. 0x04b23ef5920b9L },
  23085. { 0xbb6803c4c7341L,0x6d3f58bc37e82L,0x51e3ee8d45770L,0x9a4e73527863aL,
  23086. 0x04dd71534ddf4L } },
  23087. /* 202 */
  23088. { { 0x4467295476cd9L,0x2fe31a725bbf9L,0xc4b67e0648d07L,0x4dbb1441c8b8fL,
  23089. 0x0fd3170002f4aL },
  23090. { 0x43ff48995d0e1L,0xd10ef729aa1cbL,0x179898276e695L,0xf365e0d5f9764L,
  23091. 0x014fac58c9569L } },
  23092. /* 203 */
  23093. { { 0xa0065f312ae18L,0xc0fcc93fc9ad9L,0xa7d284651958dL,0xda50d9a142408L,
  23094. 0x0ed7c765136abL },
  23095. { 0x70f1a25d4abbcL,0xf3f1a113ea462L,0xb51952f9b5dd8L,0x9f53c609b0755L,
  23096. 0x0fefcb7f74d2eL } },
  23097. /* 204 */
  23098. { { 0x9497aba119185L,0x30aac45ba4bd0L,0xa521179d54e8cL,0xd80b492479deaL,
  23099. 0x01801a57e87e0L },
  23100. { 0xd3f8dfcafffb0L,0x0bae255240073L,0xb5fdfbc6cf33cL,0x1064781d763b5L,
  23101. 0x09f8fc11e1eadL } },
  23102. /* 205 */
  23103. { { 0x3a1715e69544cL,0x67f04b7813158L,0x78a4c320eaf85L,0x69a91e22a8fd2L,
  23104. 0x0a9d3809d3d3aL },
  23105. { 0xc2c2c59a2da3bL,0xf61895c847936L,0x3d5086938ccbcL,0x8ef75e65244e6L,
  23106. 0x03006b9aee117L } },
  23107. /* 206 */
  23108. { { 0x1f2b0c9eead28L,0x5d89f4dfbc0bbL,0x2ce89397eef63L,0xf761074757fdbL,
  23109. 0x00ab85fd745f8L },
  23110. { 0xa7c933e5b4549L,0x5c97922f21ecdL,0x43b80404be2bbL,0x42c2261a1274bL,
  23111. 0x0b122d67511e9L } },
  23112. /* 207 */
  23113. { { 0x607be66a5ae7aL,0xfa76adcbe33beL,0xeb6e5c501e703L,0xbaecaf9043014L,
  23114. 0x09f599dc1097dL },
  23115. { 0x5b7180ff250edL,0x74349a20dc6d7L,0x0b227a38eb915L,0x4b78425605a41L,
  23116. 0x07d5528e08a29L } },
  23117. /* 208 */
  23118. { { 0x58f6620c26defL,0xea582b2d1ef0fL,0x1ce3881025585L,0x1730fbe7d79b0L,
  23119. 0x028ccea01303fL },
  23120. { 0xabcd179644ba5L,0xe806fff0b8d1dL,0x6b3e17b1fc643L,0x13bfa60a76fc6L,
  23121. 0x0c18baf48a1d0L } },
  23122. /* 209 */
  23123. { { 0x638c85dc4216dL,0x67206142ac34eL,0x5f5064a00c010L,0x596bd453a1719L,
  23124. 0x09def809db7a9L },
  23125. { 0x8642e67ab8d2cL,0x336237a2b641eL,0x4c4218bb42404L,0x8ce57d506a6d6L,
  23126. 0x00357f8b06880L } },
  23127. /* 210 */
  23128. { { 0xdbe644cd2cc88L,0x8df0b8f39d8e9L,0xd30a0c8cc61c2L,0x98874a309874cL,
  23129. 0x0e4a01add1b48L },
  23130. { 0x1eeacf57cd8f9L,0x3ebd594c482edL,0xbd2f7871b767dL,0xcc30a7295c717L,
  23131. 0x0466d7d79ce10L } },
  23132. /* 211 */
  23133. { { 0x318929dada2c7L,0xc38f9aa27d47dL,0x20a59e14fa0a6L,0xad1a90e4fd288L,
  23134. 0x0c672a522451eL },
  23135. { 0x07cc85d86b655L,0x3bf9ad4af1306L,0x71172a6f0235dL,0x751399a086805L,
  23136. 0x05e3d64faf2a6L } },
  23137. /* 212 */
  23138. { { 0x410c79b3b4416L,0x85eab26d99aa6L,0xb656a74cd8fcfL,0x42fc5ebff74adL,
  23139. 0x06c8a7a95eb8eL },
  23140. { 0x60ba7b02a63bdL,0x038b8f004710cL,0x12d90b06b2f23L,0xca918c6c37383L,
  23141. 0x0348ae422ad82L } },
  23142. /* 213 */
  23143. { { 0x746635ccda2fbL,0xa18e0726d27f4L,0x92b1f2022accaL,0x2d2e85adf7824L,
  23144. 0x0c1074de0d9efL },
  23145. { 0x3ce44ae9a65b3L,0xac05d7151bfcfL,0xe6a9788fd71e4L,0x4ffcd4711f50cL,
  23146. 0x0fbadfbdbc9e5L } },
  23147. /* 214 */
  23148. { { 0x3f1cd20a99363L,0x8f6cf22775171L,0x4d359b2b91565L,0x6fcd968175cd2L,
  23149. 0x0b7f976b48371L },
  23150. { 0x8e24d5d6dbf74L,0xfd71c3af36575L,0x243dfe38d23baL,0xc80548f477600L,
  23151. 0x0f4d41b2ecafcL } },
  23152. /* 215 */
  23153. { { 0x1cf28fdabd48dL,0x3632c078a451fL,0x17146e9ce81beL,0x0f106ace29741L,
  23154. 0x0180824eae016L },
  23155. { 0x7698b66e58358L,0x52ce6ca358038L,0xe41e6c5635687L,0x6d2582380e345L,
  23156. 0x067e5f63983cfL } },
  23157. /* 216 */
  23158. { { 0xccb8dcf4899efL,0xf09ebb44c0f89L,0x2598ec9949015L,0x1fc6546f9276bL,
  23159. 0x09fef789a04c1L },
  23160. { 0x67ecf53d2a071L,0x7fa4519b096d3L,0x11e2eefb10e1aL,0x4e20ca6b3fb06L,
  23161. 0x0bc80c181a99cL } },
  23162. /* 217 */
  23163. { { 0x536f8e5eb82e6L,0xc7f56cb920972L,0x0b5da5e1a484fL,0xdf10c78e21715L,
  23164. 0x049270e629f8cL },
  23165. { 0x9b7bbea6b50adL,0xc1a2388ffc1a3L,0x107197b9a0284L,0x2f7f5403eb178L,
  23166. 0x0d2ee52f96137L } },
  23167. /* 218 */
  23168. { { 0xcd28588e0362aL,0xa78fa5d94dd37L,0x434a526442fa8L,0xb733aff836e5aL,
  23169. 0x0dfb478bee5abL },
  23170. { 0xf1ce7673eede6L,0xd42b5b2f04a91L,0x530da2fa5390aL,0x473a5e66f7bf5L,
  23171. 0x0d9a140b408dfL } },
  23172. /* 219 */
  23173. { { 0x221b56e8ea498L,0x293563ee090e0L,0x35d2ade623478L,0x4b1ae06b83913L,
  23174. 0x0760c058d623fL },
  23175. { 0x9b58cc198aa79L,0xd2f07aba7f0b8L,0xde2556af74890L,0x04094e204110fL,
  23176. 0x07141982d8f19L } },
  23177. /* 220 */
  23178. { { 0xa0e334d4b0f45L,0x38392a94e16f0L,0x3c61d5ed9280bL,0x4e473af324c6bL,
  23179. 0x03af9d1ce89d5L },
  23180. { 0xf798120930371L,0x4c21c17097fd8L,0xc42309beda266L,0x7dd60e9545dcdL,
  23181. 0x0b1f815c37395L } },
  23182. /* 221 */
  23183. { { 0xaa78e89fec44aL,0x473caa4caf84fL,0x1b6a624c8c2aeL,0xf052691c807dcL,
  23184. 0x0a41aed141543L },
  23185. { 0x353997d5ffe04L,0xdf625b6e20424L,0x78177758bacb2L,0x60ef85d660be8L,
  23186. 0x0d6e9c1dd86fbL } },
  23187. /* 222 */
  23188. { { 0x2e97ec6853264L,0xb7e2304a0b3aaL,0x8eae9be771533L,0xf8c21b912bb7bL,
  23189. 0x09c9c6e10ae9bL },
  23190. { 0x09a59e030b74cL,0x4d6a631e90a23L,0x49b79f24ed749L,0x61b689f44b23aL,
  23191. 0x0566bd59640faL } },
  23192. /* 223 */
  23193. { { 0xc0118c18061f3L,0xd37c83fc70066L,0x7273245190b25L,0x345ef05fc8e02L,
  23194. 0x0cf2c7390f525L },
  23195. { 0xbceb410eb30cfL,0xba0d77703aa09L,0x50ff255cfd2ebL,0x0979e842c43a1L,
  23196. 0x002f517558aa2L } },
  23197. /* 224 */
  23198. { { 0xef794addb7d07L,0x4224455500396L,0x78aa3ce0b4fc7L,0xd97dfaff8eaccL,
  23199. 0x014e9ada5e8d4L },
  23200. { 0x480a12f7079e2L,0xcde4b0800edaaL,0x838157d45baa3L,0x9ae801765e2d7L,
  23201. 0x0a0ad4fab8e9dL } },
  23202. /* 225 */
  23203. { { 0xb76214a653618L,0x3c31eaaa5f0bfL,0x4949d5e187281L,0xed1e1553e7374L,
  23204. 0x0bcd530b86e56L },
  23205. { 0xbe85332e9c47bL,0xfeb50059ab169L,0x92bfbb4dc2776L,0x341dcdba97611L,
  23206. 0x0909283cf6979L } },
  23207. /* 226 */
  23208. { { 0x0032476e81a13L,0x996217123967bL,0x32e19d69bee1aL,0x549a08ed361bdL,
  23209. 0x035eeb7c9ace1L },
  23210. { 0x0ae5a7e4e5bdcL,0xd3b6ceec6e128L,0xe266bc12dcd2cL,0xe86452e4224c6L,
  23211. 0x09a8b2cf4448aL } },
  23212. /* 227 */
  23213. { { 0x71bf209d03b59L,0xa3b65af2abf64L,0xbd5eec9c90e62L,0x1379ff7ff168eL,
  23214. 0x06bdb60f4d449L },
  23215. { 0xafebc8a55bc30L,0x1610097fe0dadL,0xc1e3bddc79eadL,0x08a942e197414L,
  23216. 0x001ec3cfd94baL } },
  23217. /* 228 */
  23218. { { 0x277ebdc9485c2L,0x7922fb10c7ba6L,0x0a28d8a48cc9aL,0x64f64f61d60f7L,
  23219. 0x0d1acb1c04754L },
  23220. { 0x902b126f36612L,0x4ee0618d8bd26L,0x08357ee59c3a4L,0x26c24df8a8133L,
  23221. 0x07dcd079d4056L } },
  23222. /* 229 */
  23223. { { 0x7d4d3f05a4b48L,0x52372307725ceL,0x12a915aadcd29L,0x19b8d18f79718L,
  23224. 0x00bf53589377dL },
  23225. { 0xcd95a6c68ea73L,0xca823a584d35eL,0x473a723c7f3bbL,0x86fc9fb674c6fL,
  23226. 0x0d28be4d9e166L } },
  23227. /* 230 */
  23228. { { 0xb990638fa8e4bL,0x6e893fd8fc5d2L,0x36fb6fc559f18L,0x88ce3a6de2aa4L,
  23229. 0x0d76007aa510fL },
  23230. { 0x0aab6523a4988L,0x4474dd02732d1L,0x3407278b455cfL,0xbb017f467082aL,
  23231. 0x0f2b52f68b303L } },
  23232. /* 231 */
  23233. { { 0x7eafa9835b4caL,0xfcbb669cbc0d5L,0x66431982d2232L,0xed3a8eeeb680cL,
  23234. 0x0d8dbe98ecc5aL },
  23235. { 0x9be3fc5a02709L,0xe5f5ba1fa8cbaL,0x10ea85230be68L,0x9705febd43cdfL,
  23236. 0x0e01593a3ee55L } },
  23237. /* 232 */
  23238. { { 0x5af50ea75a0a6L,0xac57858033d3eL,0x0176406512226L,0xef066fe6d50fdL,
  23239. 0x0afec07b1aeb8L },
  23240. { 0x9956780bb0a31L,0xcc37309aae7fbL,0x1abf3896f1af3L,0xbfdd9153a15a0L,
  23241. 0x0a71b93546e2dL } },
  23242. /* 233 */
  23243. { { 0xe12e018f593d2L,0x28a078122bbf8L,0xba4f2add1a904L,0x23d9150505db0L,
  23244. 0x053a2005c6285L },
  23245. { 0x8b639e7f2b935L,0x5ac182961a07cL,0x518ca2c2bff97L,0x8e3d86bceea77L,
  23246. 0x0bf47d19b3d58L } },
  23247. /* 234 */
  23248. { { 0x967a7dd7665d5L,0x572f2f4de5672L,0x0d4903f4e3030L,0xa1b6144005ae8L,
  23249. 0x0001c2c7f39c9L },
  23250. { 0xa801469efc6d6L,0xaa7bc7a724143L,0x78150a4c810bdL,0xb99b5f65670baL,
  23251. 0x0fdadf8e786ffL } },
  23252. /* 235 */
  23253. { { 0x8cb88ffc00785L,0x913b48eb67fd3L,0xf368fbc77fa75L,0x3c940454d055bL,
  23254. 0x03a838e4d5aa4L },
  23255. { 0x663293e97bb9aL,0x63441d94d9561L,0xadb2a839eb933L,0x1da3515591a60L,
  23256. 0x03cdb8257873eL } },
  23257. /* 236 */
  23258. { { 0x140a97de77eabL,0x0d41648109137L,0xeb1d0dff7e1c5L,0x7fba762dcad2cL,
  23259. 0x05a60cc89f1f5L },
  23260. { 0x3638240d45673L,0x195913c65580bL,0xd64b7411b82beL,0x8fc0057284b8dL,
  23261. 0x0922ff56fdbfdL } },
  23262. /* 237 */
  23263. { { 0x65deec9a129a1L,0x57cc284e041b2L,0xebfbe3ca5b1ceL,0xcd6204380c46cL,
  23264. 0x072919a7df6c5L },
  23265. { 0xf453a8fb90f9aL,0x0b88e4031b298L,0x96f1856d719c0L,0x089ae32c0e777L,
  23266. 0x05e7917803624L } },
  23267. /* 238 */
  23268. { { 0x6ec557f63cdfbL,0x71f1cae4fd5c1L,0x60597ca8e6a35L,0x2fabfce26bea5L,
  23269. 0x04e0a5371e24cL },
  23270. { 0xa40d3a5765357L,0x440d73a2b4276L,0x1d11a323c89afL,0x04eeb8f370ae4L,
  23271. 0x0f5ff7818d566L } },
  23272. /* 239 */
  23273. { { 0x3e3fe1a09df21L,0x8ee66e8e47fbfL,0x9c8901526d5d2L,0x5e642096bd0a2L,
  23274. 0x0e41df0e9533fL },
  23275. { 0xfda40b3ba9e3fL,0xeb2604d895305L,0xf0367c7f2340cL,0x155f0866e1927L,
  23276. 0x08edd7d6eac4fL } },
  23277. /* 240 */
  23278. { { 0x1dc0e0bfc8ff3L,0x2be936f42fc9aL,0xca381ef14efd8L,0xee9667016f7ccL,
  23279. 0x01432c1caed8aL },
  23280. { 0x8482970b23c26L,0x730735b273ec6L,0xaef0f5aa64fe8L,0xd2c6e389f6e5eL,
  23281. 0x0caef480b5ac8L } },
  23282. /* 241 */
  23283. { { 0x5c97875315922L,0x713063cca5524L,0x64ef2cbd82951L,0xe236f3ce60d0bL,
  23284. 0x0d0ba177e8efaL },
  23285. { 0x9ae8fb1b3af60L,0xe53d2da20e53aL,0xf9eef281a796aL,0xae1601d63605dL,
  23286. 0x0f31c957c1c54L } },
  23287. /* 242 */
  23288. { { 0x58d5249cc4597L,0xb0bae0a028c0fL,0x34a814adc5015L,0x7c3aefc5fc557L,
  23289. 0x0013404cb96e1L },
  23290. { 0xe2585c9a824bfL,0x5e001eaed7b29L,0x1ef68acd59318L,0x3e6c8d6ee6826L,
  23291. 0x06f377c4b9193L } },
  23292. /* 243 */
  23293. { { 0x3bad1a8333fd2L,0x025a2a95b89f9L,0xaf75acea89302L,0x9506211e5037eL,
  23294. 0x06dba3e4ed2d0L },
  23295. { 0xef98cd04399cdL,0x6ee6b73adea48L,0x17ecaf31811c6L,0xf4a772f60752cL,
  23296. 0x0f13cf3423becL } },
  23297. /* 244 */
  23298. { { 0xb9ec0a919e2ebL,0x95f62c0f68ceeL,0xaba229983a9a1L,0xbad3cfba3bb67L,
  23299. 0x0c83fa9a9274bL },
  23300. { 0xd1b0b62fa1ce0L,0xf53418efbf0d7L,0x2706f04e58b60L,0x2683bfa8ef9e5L,
  23301. 0x0b49d70f45d70L } },
  23302. /* 245 */
  23303. { { 0xc7510fad5513bL,0xecb1751e2d914L,0x9fb9d5905f32eL,0xf1cf6d850418dL,
  23304. 0x059cfadbb0c30L },
  23305. { 0x7ac2355cb7fd6L,0xb8820426a3e16L,0x0a78864249367L,0x4b67eaeec58c9L,
  23306. 0x05babf362354aL } },
  23307. /* 246 */
  23308. { { 0x981d1ee424865L,0x78f2e5577f37cL,0x9e0c0588b0028L,0xc8f0702970f1bL,
  23309. 0x06188c6a79026L },
  23310. { 0x9a19bd0f244daL,0x5cfb08087306fL,0xf2136371eccedL,0xb9d935470f9b9L,
  23311. 0x0993fe475df50L } },
  23312. /* 247 */
  23313. { { 0x31cdf9b2c3609L,0xc02c46d4ea68eL,0xa77510184eb19L,0x616b7ac9ec1a9L,
  23314. 0x081f764664c80L },
  23315. { 0xc2a5a75fbe978L,0xd3f183b3561d7L,0x01dd2bf6743feL,0x060d838d1f045L,
  23316. 0x0564a812a5fe9L } },
  23317. /* 248 */
  23318. { { 0xa64f4fa817d1dL,0x44bea82e0f7a5L,0xd57f9aa55f968L,0x1d6cb5ff5a0fcL,
  23319. 0x0226bf3cf00e5L },
  23320. { 0x1a9f92f2833cfL,0x5a4f4f89a8d6dL,0xf3f7f7720a0a3L,0x783611536c498L,
  23321. 0x068779f47ff25L } },
  23322. /* 249 */
  23323. { { 0x0c1c173043d08L,0x741fc020fa79bL,0xa6d26d0a54467L,0x2e0bd3767e289L,
  23324. 0x097bcb0d1eb09L },
  23325. { 0x6eaa8f32ed3c3L,0x51b281bc482abL,0xfa178f3c8a4f1L,0x46554d1bf4f3bL,
  23326. 0x0a872ffe80a78L } },
  23327. /* 250 */
  23328. { { 0xb7935a32b2086L,0x0e8160f486b1aL,0xb6ae6bee1eb71L,0xa36a9bd0cd913L,
  23329. 0x002812bfcb732L },
  23330. { 0xfd7cacf605318L,0x50fdfd6d1da63L,0x102d619646e5dL,0x96afa1d683982L,
  23331. 0x007391cc9fe53L } },
  23332. /* 251 */
  23333. { { 0x157f08b80d02bL,0xd162877f7fc50L,0x8d542ae6b8333L,0x2a087aca1af87L,
  23334. 0x0355d2adc7e6dL },
  23335. { 0xf335a287386e1L,0x94f8e43275b41L,0x79989eafd272aL,0x3a79286ca2cdeL,
  23336. 0x03dc2b1e37c2aL } },
  23337. /* 252 */
  23338. { { 0x9d21c04581352L,0x25376782bed68L,0xfed701f0a00c8L,0x846b203bd5909L,
  23339. 0x0c47869103ccdL },
  23340. { 0xa770824c768edL,0x026841f6575dbL,0xaccce0e72feeaL,0x4d3273313ed56L,
  23341. 0x0ccc42968d5bbL } },
  23342. /* 253 */
  23343. { { 0x50de13d7620b9L,0x8a5992a56a94eL,0x75487c9d89a5cL,0x71cfdc0076406L,
  23344. 0x0e147eb42aa48L },
  23345. { 0xab4eeacf3ae46L,0xfb50350fbe274L,0x8c840eafd4936L,0x96e3df2afe474L,
  23346. 0x0239ac047080eL } },
  23347. /* 254 */
  23348. { { 0xd1f352bfee8d4L,0xcffa7b0fec481L,0xce9af3cce80b5L,0xe59d105c4c9e2L,
  23349. 0x0c55fa1a3f5f7L },
  23350. { 0x6f14e8257c227L,0x3f342be00b318L,0xa904fb2c5b165L,0xb69909afc998aL,
  23351. 0x0094cd99cd4f4L } },
  23352. /* 255 */
  23353. { { 0x81c84d703bebaL,0x5032ceb2918a9L,0x3bd49ec8631d1L,0xad33a445f2c9eL,
  23354. 0x0b90a30b642abL },
  23355. { 0x5404fb4a5abf9L,0xc375db7603b46L,0xa35d89f004750L,0x24f76f9a42cccL,
  23356. 0x0019f8b9a1b79L } },
  23357. };
  23358. /* Multiply the base point of P256 by the scalar and return the result.
  23359. * If map is true then convert result to affine coordinates.
  23360. *
  23361. * Stripe implementation.
  23362. * Pre-generated: 2^0, 2^32, ...
  23363. * Pre-generated: products of all combinations of above.
  23364. * 8 doubles and adds (with qz=1)
  23365. *
  23366. * r Resulting point.
  23367. * k Scalar to multiply by.
  23368. * map Indicates whether to convert result to affine.
  23369. * ct Constant time required.
  23370. * heap Heap to use for allocation.
  23371. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  23372. */
  23373. static int sp_256_ecc_mulmod_base_5(sp_point_256* r, const sp_digit* k,
  23374. int map, int ct, void* heap)
  23375. {
  23376. return sp_256_ecc_mulmod_stripe_5(r, &p256_base, p256_table,
  23377. k, map, ct, heap);
  23378. }
  23379. #endif
  23380. /* Multiply the base point of P256 by the scalar and return the result.
  23381. * If map is true then convert result to affine coordinates.
  23382. *
  23383. * km Scalar to multiply by.
  23384. * r Resulting point.
  23385. * map Indicates whether to convert result to affine.
  23386. * heap Heap to use for allocation.
  23387. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  23388. */
  23389. int sp_ecc_mulmod_base_256(const mp_int* km, ecc_point* r, int map, void* heap)
  23390. {
  23391. #ifdef WOLFSSL_SP_SMALL_STACK
  23392. sp_point_256* point = NULL;
  23393. sp_digit* k = NULL;
  23394. #else
  23395. sp_point_256 point[1];
  23396. sp_digit k[5];
  23397. #endif
  23398. int err = MP_OKAY;
  23399. #ifdef WOLFSSL_SP_SMALL_STACK
  23400. point = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap,
  23401. DYNAMIC_TYPE_ECC);
  23402. if (point == NULL)
  23403. err = MEMORY_E;
  23404. if (err == MP_OKAY) {
  23405. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,
  23406. DYNAMIC_TYPE_ECC);
  23407. if (k == NULL)
  23408. err = MEMORY_E;
  23409. }
  23410. #endif
  23411. if (err == MP_OKAY) {
  23412. sp_256_from_mp(k, 5, km);
  23413. err = sp_256_ecc_mulmod_base_5(point, k, map, 1, heap);
  23414. }
  23415. if (err == MP_OKAY) {
  23416. err = sp_256_point_to_ecc_point_5(point, r);
  23417. }
  23418. #ifdef WOLFSSL_SP_SMALL_STACK
  23419. if (k != NULL)
  23420. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  23421. if (point != NULL)
  23422. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  23423. #endif
  23424. return err;
  23425. }
  23426. /* Multiply the base point of P256 by the scalar, add point a and return
  23427. * the result. If map is true then convert result to affine coordinates.
  23428. *
  23429. * km Scalar to multiply by.
  23430. * am Point to add to scalar multiply result.
  23431. * inMont Point to add is in montgomery form.
  23432. * r Resulting point.
  23433. * map Indicates whether to convert result to affine.
  23434. * heap Heap to use for allocation.
  23435. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  23436. */
  23437. int sp_ecc_mulmod_base_add_256(const mp_int* km, const ecc_point* am,
  23438. int inMont, ecc_point* r, int map, void* heap)
  23439. {
  23440. #ifdef WOLFSSL_SP_SMALL_STACK
  23441. sp_point_256* point = NULL;
  23442. sp_digit* k = NULL;
  23443. #else
  23444. sp_point_256 point[2];
  23445. sp_digit k[5 + 5 * 2 * 6];
  23446. #endif
  23447. sp_point_256* addP = NULL;
  23448. sp_digit* tmp = NULL;
  23449. int err = MP_OKAY;
  23450. #ifdef WOLFSSL_SP_SMALL_STACK
  23451. point = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 2, heap,
  23452. DYNAMIC_TYPE_ECC);
  23453. if (point == NULL)
  23454. err = MEMORY_E;
  23455. if (err == MP_OKAY) {
  23456. k = (sp_digit*)XMALLOC(
  23457. sizeof(sp_digit) * (5 + 5 * 2 * 6),
  23458. heap, DYNAMIC_TYPE_ECC);
  23459. if (k == NULL)
  23460. err = MEMORY_E;
  23461. }
  23462. #endif
  23463. if (err == MP_OKAY) {
  23464. addP = point + 1;
  23465. tmp = k + 5;
  23466. sp_256_from_mp(k, 5, km);
  23467. sp_256_point_from_ecc_point_5(addP, am);
  23468. }
  23469. if ((err == MP_OKAY) && (!inMont)) {
  23470. err = sp_256_mod_mul_norm_5(addP->x, addP->x, p256_mod);
  23471. }
  23472. if ((err == MP_OKAY) && (!inMont)) {
  23473. err = sp_256_mod_mul_norm_5(addP->y, addP->y, p256_mod);
  23474. }
  23475. if ((err == MP_OKAY) && (!inMont)) {
  23476. err = sp_256_mod_mul_norm_5(addP->z, addP->z, p256_mod);
  23477. }
  23478. if (err == MP_OKAY) {
  23479. err = sp_256_ecc_mulmod_base_5(point, k, 0, 0, heap);
  23480. }
  23481. if (err == MP_OKAY) {
  23482. sp_256_proj_point_add_5(point, point, addP, tmp);
  23483. if (map) {
  23484. sp_256_map_5(point, point, tmp);
  23485. }
  23486. err = sp_256_point_to_ecc_point_5(point, r);
  23487. }
  23488. #ifdef WOLFSSL_SP_SMALL_STACK
  23489. if (k != NULL)
  23490. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  23491. if (point)
  23492. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  23493. #endif
  23494. return err;
  23495. }
  23496. #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
  23497. defined(HAVE_ECC_VERIFY)
  23498. #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */
  23499. /* Add 1 to a. (a = a + 1)
  23500. *
  23501. * r A single precision integer.
  23502. * a A single precision integer.
  23503. */
  23504. SP_NOINLINE static void sp_256_add_one_5(sp_digit* a)
  23505. {
  23506. a[0]++;
  23507. sp_256_norm_5(a);
  23508. }
  23509. /* Read big endian unsigned byte array into r.
  23510. *
  23511. * r A single precision integer.
  23512. * size Maximum number of bytes to convert
  23513. * a Byte array.
  23514. * n Number of bytes in array to read.
  23515. */
  23516. static void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n)
  23517. {
  23518. int i;
  23519. int j = 0;
  23520. word32 s = 0;
  23521. r[0] = 0;
  23522. for (i = n-1; i >= 0; i--) {
  23523. r[j] |= (((sp_digit)a[i]) << s);
  23524. if (s >= 44U) {
  23525. r[j] &= 0xfffffffffffffL;
  23526. s = 52U - s;
  23527. if (j + 1 >= size) {
  23528. break;
  23529. }
  23530. r[++j] = (sp_digit)a[i] >> s;
  23531. s = 8U - s;
  23532. }
  23533. else {
  23534. s += 8U;
  23535. }
  23536. }
  23537. for (j++; j < size; j++) {
  23538. r[j] = 0;
  23539. }
  23540. }
  23541. /* Generates a scalar that is in the range 1..order-1.
  23542. *
  23543. * rng Random number generator.
  23544. * k Scalar value.
  23545. * returns RNG failures, MEMORY_E when memory allocation fails and
  23546. * MP_OKAY on success.
  23547. */
  23548. static int sp_256_ecc_gen_k_5(WC_RNG* rng, sp_digit* k)
  23549. {
  23550. int err;
  23551. byte buf[32];
  23552. do {
  23553. err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));
  23554. if (err == 0) {
  23555. sp_256_from_bin(k, 5, buf, (int)sizeof(buf));
  23556. if (sp_256_cmp_5(k, p256_order2) <= 0) {
  23557. sp_256_add_one_5(k);
  23558. break;
  23559. }
  23560. }
  23561. }
  23562. while (err == 0);
  23563. return err;
  23564. }
  23565. /* Makes a random EC key pair.
  23566. *
  23567. * rng Random number generator.
  23568. * priv Generated private value.
  23569. * pub Generated public point.
  23570. * heap Heap to use for allocation.
  23571. * returns ECC_INF_E when the point does not have the correct order, RNG
  23572. * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.
  23573. */
  23574. int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)
  23575. {
  23576. #ifdef WOLFSSL_SP_SMALL_STACK
  23577. sp_point_256* point = NULL;
  23578. sp_digit* k = NULL;
  23579. #else
  23580. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  23581. sp_point_256 point[2];
  23582. #else
  23583. sp_point_256 point[1];
  23584. #endif
  23585. sp_digit k[5];
  23586. #endif
  23587. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  23588. sp_point_256* infinity = NULL;
  23589. #endif
  23590. int err = MP_OKAY;
  23591. (void)heap;
  23592. #ifdef WOLFSSL_SP_SMALL_STACK
  23593. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  23594. point = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 2, heap, DYNAMIC_TYPE_ECC);
  23595. #else
  23596. point = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap, DYNAMIC_TYPE_ECC);
  23597. #endif
  23598. if (point == NULL)
  23599. err = MEMORY_E;
  23600. if (err == MP_OKAY) {
  23601. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,
  23602. DYNAMIC_TYPE_ECC);
  23603. if (k == NULL)
  23604. err = MEMORY_E;
  23605. }
  23606. #endif
  23607. if (err == MP_OKAY) {
  23608. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  23609. infinity = point + 1;
  23610. #endif
  23611. err = sp_256_ecc_gen_k_5(rng, k);
  23612. }
  23613. if (err == MP_OKAY) {
  23614. err = sp_256_ecc_mulmod_base_5(point, k, 1, 1, NULL);
  23615. }
  23616. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  23617. if (err == MP_OKAY) {
  23618. err = sp_256_ecc_mulmod_5(infinity, point, p256_order, 1, 1, NULL);
  23619. }
  23620. if (err == MP_OKAY) {
  23621. if (sp_256_iszero_5(point->x) || sp_256_iszero_5(point->y)) {
  23622. err = ECC_INF_E;
  23623. }
  23624. }
  23625. #endif
  23626. if (err == MP_OKAY) {
  23627. err = sp_256_to_mp(k, priv);
  23628. }
  23629. if (err == MP_OKAY) {
  23630. err = sp_256_point_to_ecc_point_5(point, pub);
  23631. }
  23632. #ifdef WOLFSSL_SP_SMALL_STACK
  23633. if (k != NULL)
  23634. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  23635. if (point != NULL) {
  23636. /* point is not sensitive, so no need to zeroize */
  23637. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  23638. }
  23639. #endif
  23640. return err;
  23641. }
  23642. #ifdef WOLFSSL_SP_NONBLOCK
  23643. typedef struct sp_ecc_key_gen_256_ctx {
  23644. int state;
  23645. sp_256_ecc_mulmod_5_ctx mulmod_ctx;
  23646. sp_digit k[5];
  23647. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  23648. sp_point_256 point[2];
  23649. #else
  23650. sp_point_256 point[1];
  23651. #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN */
  23652. } sp_ecc_key_gen_256_ctx;
  23653. int sp_ecc_make_key_256_nb(sp_ecc_ctx_t* sp_ctx, WC_RNG* rng, mp_int* priv,
  23654. ecc_point* pub, void* heap)
  23655. {
  23656. int err = FP_WOULDBLOCK;
  23657. sp_ecc_key_gen_256_ctx* ctx = (sp_ecc_key_gen_256_ctx*)sp_ctx->data;
  23658. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  23659. sp_point_256* infinity = ctx->point + 1;
  23660. #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN */
  23661. typedef char ctx_size_test[sizeof(sp_ecc_key_gen_256_ctx)
  23662. >= sizeof(*sp_ctx) ? -1 : 1];
  23663. (void)sizeof(ctx_size_test);
  23664. switch (ctx->state) {
  23665. case 0:
  23666. err = sp_256_ecc_gen_k_5(rng, ctx->k);
  23667. if (err == MP_OKAY) {
  23668. err = FP_WOULDBLOCK;
  23669. ctx->state = 1;
  23670. }
  23671. break;
  23672. case 1:
  23673. err = sp_256_ecc_mulmod_base_5_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx,
  23674. ctx->point, ctx->k, 1, 1, heap);
  23675. if (err == MP_OKAY) {
  23676. err = FP_WOULDBLOCK;
  23677. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  23678. XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
  23679. ctx->state = 2;
  23680. #else
  23681. ctx->state = 3;
  23682. #endif
  23683. }
  23684. break;
  23685. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  23686. case 2:
  23687. err = sp_256_ecc_mulmod_5_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx,
  23688. infinity, ctx->point, p256_order, 1, 1);
  23689. if (err == MP_OKAY) {
  23690. if (sp_256_iszero_5(ctx->point->x) ||
  23691. sp_256_iszero_5(ctx->point->y)) {
  23692. err = ECC_INF_E;
  23693. }
  23694. else {
  23695. err = FP_WOULDBLOCK;
  23696. ctx->state = 3;
  23697. }
  23698. }
  23699. break;
  23700. #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN */
  23701. case 3:
  23702. err = sp_256_to_mp(ctx->k, priv);
  23703. if (err == MP_OKAY) {
  23704. err = sp_256_point_to_ecc_point_5(ctx->point, pub);
  23705. }
  23706. break;
  23707. }
  23708. if (err != FP_WOULDBLOCK) {
  23709. XMEMSET(ctx, 0, sizeof(sp_ecc_key_gen_256_ctx));
  23710. }
  23711. return err;
  23712. }
  23713. #endif /* WOLFSSL_SP_NONBLOCK */
  23714. #ifdef HAVE_ECC_DHE
  23715. /* Write r as big endian to byte array.
  23716. * Fixed length number of bytes written: 32
  23717. *
  23718. * r A single precision integer.
  23719. * a Byte array.
  23720. */
  23721. static void sp_256_to_bin_5(sp_digit* r, byte* a)
  23722. {
  23723. int i;
  23724. int j;
  23725. int s = 0;
  23726. int b;
  23727. for (i=0; i<4; i++) {
  23728. r[i+1] += r[i] >> 52;
  23729. r[i] &= 0xfffffffffffffL;
  23730. }
  23731. j = 263 / 8 - 1;
  23732. a[j] = 0;
  23733. for (i=0; i<5 && j>=0; i++) {
  23734. b = 0;
  23735. /* lint allow cast of mismatch sp_digit and int */
  23736. a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
  23737. b += 8 - s;
  23738. if (j < 0) {
  23739. break;
  23740. }
  23741. while (b < 52) {
  23742. a[j--] = (byte)(r[i] >> b);
  23743. b += 8;
  23744. if (j < 0) {
  23745. break;
  23746. }
  23747. }
  23748. s = 8 - (b - 52);
  23749. if (j >= 0) {
  23750. a[j] = 0;
  23751. }
  23752. if (s != 0) {
  23753. j++;
  23754. }
  23755. }
  23756. }
  23757. /* Multiply the point by the scalar and serialize the X ordinate.
  23758. * The number is 0 padded to maximum size on output.
  23759. *
  23760. * priv Scalar to multiply the point by.
  23761. * pub Point to multiply.
  23762. * out Buffer to hold X ordinate.
  23763. * outLen On entry, size of the buffer in bytes.
  23764. * On exit, length of data in buffer in bytes.
  23765. * heap Heap to use for allocation.
  23766. * returns BUFFER_E if the buffer is to small for output size,
  23767. * MEMORY_E when memory allocation fails and MP_OKAY on success.
  23768. */
  23769. int sp_ecc_secret_gen_256(const mp_int* priv, const ecc_point* pub, byte* out,
  23770. word32* outLen, void* heap)
  23771. {
  23772. #ifdef WOLFSSL_SP_SMALL_STACK
  23773. sp_point_256* point = NULL;
  23774. sp_digit* k = NULL;
  23775. #else
  23776. sp_point_256 point[1];
  23777. sp_digit k[5];
  23778. #endif
  23779. int err = MP_OKAY;
  23780. if (*outLen < 32U) {
  23781. err = BUFFER_E;
  23782. }
  23783. #ifdef WOLFSSL_SP_SMALL_STACK
  23784. if (err == MP_OKAY) {
  23785. point = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap,
  23786. DYNAMIC_TYPE_ECC);
  23787. if (point == NULL)
  23788. err = MEMORY_E;
  23789. }
  23790. if (err == MP_OKAY) {
  23791. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,
  23792. DYNAMIC_TYPE_ECC);
  23793. if (k == NULL)
  23794. err = MEMORY_E;
  23795. }
  23796. #endif
  23797. if (err == MP_OKAY) {
  23798. sp_256_from_mp(k, 5, priv);
  23799. sp_256_point_from_ecc_point_5(point, pub);
  23800. err = sp_256_ecc_mulmod_5(point, point, k, 1, 1, heap);
  23801. }
  23802. if (err == MP_OKAY) {
  23803. sp_256_to_bin_5(point->x, out);
  23804. *outLen = 32;
  23805. }
  23806. #ifdef WOLFSSL_SP_SMALL_STACK
  23807. if (k != NULL)
  23808. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  23809. if (point != NULL)
  23810. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  23811. #endif
  23812. return err;
  23813. }
  23814. #ifdef WOLFSSL_SP_NONBLOCK
  23815. typedef struct sp_ecc_sec_gen_256_ctx {
  23816. int state;
  23817. union {
  23818. sp_256_ecc_mulmod_5_ctx mulmod_ctx;
  23819. };
  23820. sp_digit k[5];
  23821. sp_point_256 point;
  23822. } sp_ecc_sec_gen_256_ctx;
  23823. int sp_ecc_secret_gen_256_nb(sp_ecc_ctx_t* sp_ctx, const mp_int* priv,
  23824. const ecc_point* pub, byte* out, word32* outLen, void* heap)
  23825. {
  23826. int err = FP_WOULDBLOCK;
  23827. sp_ecc_sec_gen_256_ctx* ctx = (sp_ecc_sec_gen_256_ctx*)sp_ctx->data;
  23828. typedef char ctx_size_test[sizeof(sp_ecc_sec_gen_256_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  23829. (void)sizeof(ctx_size_test);
  23830. if (*outLen < 32U) {
  23831. err = BUFFER_E;
  23832. }
  23833. switch (ctx->state) {
  23834. case 0:
  23835. sp_256_from_mp(ctx->k, 5, priv);
  23836. sp_256_point_from_ecc_point_5(&ctx->point, pub);
  23837. ctx->state = 1;
  23838. break;
  23839. case 1:
  23840. err = sp_256_ecc_mulmod_5_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx,
  23841. &ctx->point, &ctx->point, ctx->k, 1, 1, heap);
  23842. if (err == MP_OKAY) {
  23843. sp_256_to_bin_5(ctx->point.x, out);
  23844. *outLen = 32;
  23845. }
  23846. break;
  23847. }
  23848. if (err == MP_OKAY && ctx->state != 1) {
  23849. err = FP_WOULDBLOCK;
  23850. }
  23851. if (err != FP_WOULDBLOCK) {
  23852. XMEMSET(ctx, 0, sizeof(sp_ecc_sec_gen_256_ctx));
  23853. }
  23854. return err;
  23855. }
  23856. #endif /* WOLFSSL_SP_NONBLOCK */
  23857. #endif /* HAVE_ECC_DHE */
  23858. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  23859. #endif
  23860. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  23861. SP_NOINLINE static void sp_256_rshift_5(sp_digit* r, const sp_digit* a,
  23862. byte n)
  23863. {
  23864. int i;
  23865. #ifdef WOLFSSL_SP_SMALL
  23866. for (i=0; i<4; i++) {
  23867. r[i] = ((a[i] >> n) | (a[i + 1] << (52 - n))) & 0xfffffffffffffL;
  23868. }
  23869. #else
  23870. for (i=0; i<0; i += 8) {
  23871. r[i+0] = (a[i+0] >> n) | ((a[i+1] << (52 - n)) & 0xfffffffffffffL);
  23872. r[i+1] = (a[i+1] >> n) | ((a[i+2] << (52 - n)) & 0xfffffffffffffL);
  23873. r[i+2] = (a[i+2] >> n) | ((a[i+3] << (52 - n)) & 0xfffffffffffffL);
  23874. r[i+3] = (a[i+3] >> n) | ((a[i+4] << (52 - n)) & 0xfffffffffffffL);
  23875. r[i+4] = (a[i+4] >> n) | ((a[i+5] << (52 - n)) & 0xfffffffffffffL);
  23876. r[i+5] = (a[i+5] >> n) | ((a[i+6] << (52 - n)) & 0xfffffffffffffL);
  23877. r[i+6] = (a[i+6] >> n) | ((a[i+7] << (52 - n)) & 0xfffffffffffffL);
  23878. r[i+7] = (a[i+7] >> n) | ((a[i+8] << (52 - n)) & 0xfffffffffffffL);
  23879. }
  23880. r[0] = (a[0] >> n) | ((a[1] << (52 - n)) & 0xfffffffffffffL);
  23881. r[1] = (a[1] >> n) | ((a[2] << (52 - n)) & 0xfffffffffffffL);
  23882. r[2] = (a[2] >> n) | ((a[3] << (52 - n)) & 0xfffffffffffffL);
  23883. r[3] = (a[3] >> n) | ((a[4] << (52 - n)) & 0xfffffffffffffL);
  23884. #endif /* WOLFSSL_SP_SMALL */
  23885. r[4] = a[4] >> n;
  23886. }
  23887. /* Multiply a by scalar b into r. (r = a * b)
  23888. *
  23889. * r A single precision integer.
  23890. * a A single precision integer.
  23891. * b A scalar.
  23892. */
  23893. SP_NOINLINE static void sp_256_mul_d_5(sp_digit* r, const sp_digit* a,
  23894. sp_digit b)
  23895. {
  23896. #ifdef WOLFSSL_SP_SMALL
  23897. sp_int128 tb = b;
  23898. sp_int128 t = 0;
  23899. int i;
  23900. for (i = 0; i < 5; i++) {
  23901. t += tb * a[i];
  23902. r[i] = (sp_digit)(t & 0xfffffffffffffL);
  23903. t >>= 52;
  23904. }
  23905. r[5] = (sp_digit)t;
  23906. #else
  23907. sp_int128 tb = b;
  23908. sp_int128 t[5];
  23909. t[ 0] = tb * a[ 0];
  23910. t[ 1] = tb * a[ 1];
  23911. t[ 2] = tb * a[ 2];
  23912. t[ 3] = tb * a[ 3];
  23913. t[ 4] = tb * a[ 4];
  23914. r[ 0] = (sp_digit) (t[ 0] & 0xfffffffffffffL);
  23915. r[ 1] = (sp_digit)((t[ 0] >> 52) + (t[ 1] & 0xfffffffffffffL));
  23916. r[ 2] = (sp_digit)((t[ 1] >> 52) + (t[ 2] & 0xfffffffffffffL));
  23917. r[ 3] = (sp_digit)((t[ 2] >> 52) + (t[ 3] & 0xfffffffffffffL));
  23918. r[ 4] = (sp_digit)((t[ 3] >> 52) + (t[ 4] & 0xfffffffffffffL));
  23919. r[ 5] = (sp_digit) (t[ 4] >> 52);
  23920. #endif /* WOLFSSL_SP_SMALL */
  23921. }
  23922. SP_NOINLINE static void sp_256_lshift_10(sp_digit* r, const sp_digit* a,
  23923. byte n)
  23924. {
  23925. #ifdef WOLFSSL_SP_SMALL
  23926. int i;
  23927. r[10] = a[9] >> (52 - n);
  23928. for (i=9; i>0; i--) {
  23929. r[i] = ((a[i] << n) | (a[i-1] >> (52 - n))) & 0xfffffffffffffL;
  23930. }
  23931. #else
  23932. sp_int_digit s;
  23933. sp_int_digit t;
  23934. s = (sp_int_digit)a[9];
  23935. r[10] = s >> (52U - n);
  23936. s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);
  23937. r[9] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
  23938. s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);
  23939. r[8] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
  23940. s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);
  23941. r[7] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
  23942. s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);
  23943. r[6] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
  23944. s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);
  23945. r[5] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
  23946. s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);
  23947. r[4] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
  23948. s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);
  23949. r[3] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
  23950. s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);
  23951. r[2] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
  23952. s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);
  23953. r[1] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
  23954. #endif /* WOLFSSL_SP_SMALL */
  23955. r[0] = (a[0] << n) & 0xfffffffffffffL;
  23956. }
  23957. /* Divide d in a and put remainder into r (m*d + r = a)
  23958. * m is not calculated as it is not needed at this time.
  23959. *
  23960. * Simplified based on top word of divisor being very large.
  23961. *
  23962. * a Number to be divided.
  23963. * d Number to divide with.
  23964. * m Multiplier result.
  23965. * r Remainder from the division.
  23966. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  23967. */
  23968. static int sp_256_div_5(const sp_digit* a, const sp_digit* d,
  23969. const sp_digit* m, sp_digit* r)
  23970. {
  23971. int i;
  23972. sp_digit r1;
  23973. sp_digit mask;
  23974. #ifdef WOLFSSL_SP_SMALL_STACK
  23975. sp_digit* t1 = NULL;
  23976. #else
  23977. sp_digit t1[4 * 5 + 3];
  23978. #endif
  23979. sp_digit* t2 = NULL;
  23980. sp_digit* sd = NULL;
  23981. int err = MP_OKAY;
  23982. (void)m;
  23983. #ifdef WOLFSSL_SP_SMALL_STACK
  23984. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 5 + 3), NULL,
  23985. DYNAMIC_TYPE_TMP_BUFFER);
  23986. if (t1 == NULL)
  23987. err = MEMORY_E;
  23988. #endif
  23989. (void)m;
  23990. if (err == MP_OKAY) {
  23991. t2 = t1 + 10 + 1;
  23992. sd = t2 + 5 + 1;
  23993. sp_256_mul_d_5(sd, d, (sp_digit)1 << 4);
  23994. sp_256_lshift_10(t1, a, 4);
  23995. t1[5 + 5] += t1[5 + 5 - 1] >> 52;
  23996. t1[5 + 5 - 1] &= 0xfffffffffffffL;
  23997. for (i=4; i>=0; i--) {
  23998. r1 = t1[5 + i];
  23999. sp_256_mul_d_5(t2, sd, r1);
  24000. (void)sp_256_sub_5(&t1[i], &t1[i], t2);
  24001. t1[5 + i] -= t2[5];
  24002. sp_256_norm_5(&t1[i + 1]);
  24003. r1 = t1[5 + i];
  24004. sp_256_mul_d_5(t2, sd, r1);
  24005. (void)sp_256_sub_5(&t1[i], &t1[i], t2);
  24006. t1[5 + i] -= t2[5];
  24007. sp_256_norm_5(&t1[i + 1]);
  24008. mask = ~((t1[5 + i] - 1) >> 63);
  24009. sp_256_cond_sub_5(t1 + i, t1 + i, sd, mask);
  24010. sp_256_norm_5(&t1[i + 1]);
  24011. }
  24012. sp_256_norm_5(t1);
  24013. sp_256_rshift_5(r, t1, 4);
  24014. }
  24015. #ifdef WOLFSSL_SP_SMALL_STACK
  24016. if (t1 != NULL)
  24017. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  24018. #endif
  24019. return err;
  24020. }
  24021. /* Reduce a modulo m into r. (r = a mod m)
  24022. *
  24023. * r A single precision number that is the reduced result.
  24024. * a A single precision number that is to be reduced.
  24025. * m A single precision number that is the modulus to reduce with.
  24026. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  24027. */
  24028. static int sp_256_mod_5(sp_digit* r, const sp_digit* a, const sp_digit* m)
  24029. {
  24030. return sp_256_div_5(a, m, NULL, r);
  24031. }
  24032. #endif
  24033. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  24034. /* Multiply two number mod the order of P256 curve. (r = a * b mod order)
  24035. *
  24036. * r Result of the multiplication.
  24037. * a First operand of the multiplication.
  24038. * b Second operand of the multiplication.
  24039. */
  24040. static void sp_256_mont_mul_order_5(sp_digit* r, const sp_digit* a, const sp_digit* b)
  24041. {
  24042. sp_256_mul_5(r, a, b);
  24043. sp_256_mont_reduce_order_5(r, p256_order, p256_mp_order);
  24044. }
  24045. #if defined(HAVE_ECC_SIGN) || (defined(HAVE_ECC_VERIFY) && defined(WOLFSSL_SP_SMALL))
  24046. #ifdef WOLFSSL_SP_SMALL
  24047. /* Order-2 for the P256 curve. */
  24048. static const uint64_t p256_order_minus_2[4] = {
  24049. 0xf3b9cac2fc63254fU,0xbce6faada7179e84U,0xffffffffffffffffU,
  24050. 0xffffffff00000000U
  24051. };
  24052. #else
  24053. /* The low half of the order-2 of the P256 curve. */
  24054. static const sp_int_digit p256_order_low[2] = {
  24055. 0xf3b9cac2fc63254fU,0xbce6faada7179e84U
  24056. };
  24057. #endif /* WOLFSSL_SP_SMALL */
  24058. /* Square number mod the order of P256 curve. (r = a * a mod order)
  24059. *
  24060. * r Result of the squaring.
  24061. * a Number to square.
  24062. */
  24063. static void sp_256_mont_sqr_order_5(sp_digit* r, const sp_digit* a)
  24064. {
  24065. sp_256_sqr_5(r, a);
  24066. sp_256_mont_reduce_order_5(r, p256_order, p256_mp_order);
  24067. }
  24068. #ifndef WOLFSSL_SP_SMALL
  24069. /* Square number mod the order of P256 curve a number of times.
  24070. * (r = a ^ n mod order)
  24071. *
  24072. * r Result of the squaring.
  24073. * a Number to square.
  24074. */
  24075. static void sp_256_mont_sqr_n_order_5(sp_digit* r, const sp_digit* a, int n)
  24076. {
  24077. int i;
  24078. sp_256_mont_sqr_order_5(r, a);
  24079. for (i=1; i<n; i++) {
  24080. sp_256_mont_sqr_order_5(r, r);
  24081. }
  24082. }
  24083. #endif /* !WOLFSSL_SP_SMALL */
  24084. /* Invert the number, in Montgomery form, modulo the order of the P256 curve.
  24085. * (r = 1 / a mod order)
  24086. *
  24087. * r Inverse result.
  24088. * a Number to invert.
  24089. * td Temporary data.
  24090. */
  24091. #ifdef WOLFSSL_SP_NONBLOCK
  24092. typedef struct sp_256_mont_inv_order_5_ctx {
  24093. int state;
  24094. int i;
  24095. } sp_256_mont_inv_order_5_ctx;
  24096. static int sp_256_mont_inv_order_5_nb(sp_ecc_ctx_t* sp_ctx, sp_digit* r, const sp_digit* a,
  24097. sp_digit* t)
  24098. {
  24099. int err = FP_WOULDBLOCK;
  24100. sp_256_mont_inv_order_5_ctx* ctx = (sp_256_mont_inv_order_5_ctx*)sp_ctx;
  24101. typedef char ctx_size_test[sizeof(sp_256_mont_inv_order_5_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  24102. (void)sizeof(ctx_size_test);
  24103. switch (ctx->state) {
  24104. case 0:
  24105. XMEMCPY(t, a, sizeof(sp_digit) * 5);
  24106. ctx->i = 254;
  24107. ctx->state = 1;
  24108. break;
  24109. case 1:
  24110. sp_256_mont_sqr_order_5(t, t);
  24111. ctx->state = 2;
  24112. break;
  24113. case 2:
  24114. if ((p256_order_minus_2[ctx->i / 64] & ((sp_int_digit)1 << (ctx->i % 64))) != 0) {
  24115. sp_256_mont_mul_order_5(t, t, a);
  24116. }
  24117. ctx->i--;
  24118. ctx->state = (ctx->i == 0) ? 3 : 1;
  24119. break;
  24120. case 3:
  24121. XMEMCPY(r, t, sizeof(sp_digit) * 5U);
  24122. err = MP_OKAY;
  24123. break;
  24124. }
  24125. return err;
  24126. }
  24127. #endif /* WOLFSSL_SP_NONBLOCK */
  24128. static void sp_256_mont_inv_order_5(sp_digit* r, const sp_digit* a,
  24129. sp_digit* td)
  24130. {
  24131. #ifdef WOLFSSL_SP_SMALL
  24132. sp_digit* t = td;
  24133. int i;
  24134. XMEMCPY(t, a, sizeof(sp_digit) * 5);
  24135. for (i=254; i>=0; i--) {
  24136. sp_256_mont_sqr_order_5(t, t);
  24137. if ((p256_order_minus_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
  24138. sp_256_mont_mul_order_5(t, t, a);
  24139. }
  24140. }
  24141. XMEMCPY(r, t, sizeof(sp_digit) * 5U);
  24142. #else
  24143. sp_digit* t = td;
  24144. sp_digit* t2 = td + 2 * 5;
  24145. sp_digit* t3 = td + 4 * 5;
  24146. int i;
  24147. /* t = a^2 */
  24148. sp_256_mont_sqr_order_5(t, a);
  24149. /* t = a^3 = t * a */
  24150. sp_256_mont_mul_order_5(t, t, a);
  24151. /* t2= a^c = t ^ 2 ^ 2 */
  24152. sp_256_mont_sqr_n_order_5(t2, t, 2);
  24153. /* t3= a^f = t2 * t */
  24154. sp_256_mont_mul_order_5(t3, t2, t);
  24155. /* t2= a^f0 = t3 ^ 2 ^ 4 */
  24156. sp_256_mont_sqr_n_order_5(t2, t3, 4);
  24157. /* t = a^ff = t2 * t3 */
  24158. sp_256_mont_mul_order_5(t, t2, t3);
  24159. /* t2= a^ff00 = t ^ 2 ^ 8 */
  24160. sp_256_mont_sqr_n_order_5(t2, t, 8);
  24161. /* t = a^ffff = t2 * t */
  24162. sp_256_mont_mul_order_5(t, t2, t);
  24163. /* t2= a^ffff0000 = t ^ 2 ^ 16 */
  24164. sp_256_mont_sqr_n_order_5(t2, t, 16);
  24165. /* t = a^ffffffff = t2 * t */
  24166. sp_256_mont_mul_order_5(t, t2, t);
  24167. /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64 */
  24168. sp_256_mont_sqr_n_order_5(t2, t, 64);
  24169. /* t2= a^ffffffff00000000ffffffff = t2 * t */
  24170. sp_256_mont_mul_order_5(t2, t2, t);
  24171. /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32 */
  24172. sp_256_mont_sqr_n_order_5(t2, t2, 32);
  24173. /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */
  24174. sp_256_mont_mul_order_5(t2, t2, t);
  24175. /* t2= a^ffffffff00000000ffffffffffffffffbce6 */
  24176. sp_256_mont_sqr_order_5(t2, t2);
  24177. sp_256_mont_mul_order_5(t2, t2, a);
  24178. sp_256_mont_sqr_n_order_5(t2, t2, 5);
  24179. sp_256_mont_mul_order_5(t2, t2, t3);
  24180. for (i=121; i>=112; i--) {
  24181. sp_256_mont_sqr_order_5(t2, t2);
  24182. if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
  24183. sp_256_mont_mul_order_5(t2, t2, a);
  24184. }
  24185. }
  24186. /* t2= a^ffffffff00000000ffffffffffffffffbce6f */
  24187. sp_256_mont_sqr_n_order_5(t2, t2, 4);
  24188. sp_256_mont_mul_order_5(t2, t2, t3);
  24189. /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */
  24190. for (i=107; i>=64; i--) {
  24191. sp_256_mont_sqr_order_5(t2, t2);
  24192. if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
  24193. sp_256_mont_mul_order_5(t2, t2, a);
  24194. }
  24195. }
  24196. /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */
  24197. sp_256_mont_sqr_n_order_5(t2, t2, 4);
  24198. sp_256_mont_mul_order_5(t2, t2, t3);
  24199. /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */
  24200. for (i=59; i>=32; i--) {
  24201. sp_256_mont_sqr_order_5(t2, t2);
  24202. if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
  24203. sp_256_mont_mul_order_5(t2, t2, a);
  24204. }
  24205. }
  24206. /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */
  24207. sp_256_mont_sqr_n_order_5(t2, t2, 4);
  24208. sp_256_mont_mul_order_5(t2, t2, t3);
  24209. /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */
  24210. for (i=27; i>=0; i--) {
  24211. sp_256_mont_sqr_order_5(t2, t2);
  24212. if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
  24213. sp_256_mont_mul_order_5(t2, t2, a);
  24214. }
  24215. }
  24216. /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */
  24217. sp_256_mont_sqr_n_order_5(t2, t2, 4);
  24218. /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */
  24219. sp_256_mont_mul_order_5(r, t2, t3);
  24220. #endif /* WOLFSSL_SP_SMALL */
  24221. }
  24222. #endif /* HAVE_ECC_SIGN || (HAVE_ECC_VERIFY && WOLFSSL_SP_SMALL) */
  24223. #endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */
  24224. #ifdef HAVE_ECC_SIGN
  24225. #ifndef SP_ECC_MAX_SIG_GEN
  24226. #define SP_ECC_MAX_SIG_GEN 64
  24227. #endif
  24228. /* Calculate second signature value S from R, k and private value.
  24229. *
  24230. * s = (r * x + e) / k
  24231. *
  24232. * s Signature value.
  24233. * r First signature value.
  24234. * k Ephemeral private key.
  24235. * x Private key as a number.
  24236. * e Hash of message as a number.
  24237. * tmp Temporary storage for intermediate numbers.
  24238. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  24239. */
  24240. static int sp_256_calc_s_5(sp_digit* s, const sp_digit* r, sp_digit* k,
  24241. sp_digit* x, const sp_digit* e, sp_digit* tmp)
  24242. {
  24243. int err;
  24244. sp_digit carry;
  24245. sp_int64 c;
  24246. sp_digit* kInv = k;
  24247. /* Conv k to Montgomery form (mod order) */
  24248. sp_256_mul_5(k, k, p256_norm_order);
  24249. err = sp_256_mod_5(k, k, p256_order);
  24250. if (err == MP_OKAY) {
  24251. sp_256_norm_5(k);
  24252. /* kInv = 1/k mod order */
  24253. sp_256_mont_inv_order_5(kInv, k, tmp);
  24254. sp_256_norm_5(kInv);
  24255. /* s = r * x + e */
  24256. sp_256_mul_5(x, x, r);
  24257. err = sp_256_mod_5(x, x, p256_order);
  24258. }
  24259. if (err == MP_OKAY) {
  24260. sp_256_norm_5(x);
  24261. carry = sp_256_add_5(s, e, x);
  24262. sp_256_cond_sub_5(s, s, p256_order, 0 - carry);
  24263. sp_256_norm_5(s);
  24264. c = sp_256_cmp_5(s, p256_order);
  24265. sp_256_cond_sub_5(s, s, p256_order,
  24266. (sp_digit)0 - (sp_digit)(c >= 0));
  24267. sp_256_norm_5(s);
  24268. /* s = s * k^-1 mod order */
  24269. sp_256_mont_mul_order_5(s, s, kInv);
  24270. sp_256_norm_5(s);
  24271. }
  24272. return err;
  24273. }
  24274. /* Sign the hash using the private key.
  24275. * e = [hash, 256 bits] from binary
  24276. * r = (k.G)->x mod order
  24277. * s = (r * x + e) / k mod order
  24278. * The hash is truncated to the first 256 bits.
  24279. *
  24280. * hash Hash to sign.
  24281. * hashLen Length of the hash data.
  24282. * rng Random number generator.
  24283. * priv Private part of key - scalar.
  24284. * rm First part of result as an mp_int.
  24285. * sm Sirst part of result as an mp_int.
  24286. * heap Heap to use for allocation.
  24287. * returns RNG failures, MEMORY_E when memory allocation fails and
  24288. * MP_OKAY on success.
  24289. */
  24290. int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng,
  24291. const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap)
  24292. {
  24293. #ifdef WOLFSSL_SP_SMALL_STACK
  24294. sp_digit* e = NULL;
  24295. sp_point_256* point = NULL;
  24296. #else
  24297. sp_digit e[7 * 2 * 5];
  24298. sp_point_256 point[1];
  24299. #endif
  24300. sp_digit* x = NULL;
  24301. sp_digit* k = NULL;
  24302. sp_digit* r = NULL;
  24303. sp_digit* tmp = NULL;
  24304. sp_digit* s = NULL;
  24305. sp_int64 c;
  24306. int err = MP_OKAY;
  24307. int i;
  24308. (void)heap;
  24309. #ifdef WOLFSSL_SP_SMALL_STACK
  24310. if (err == MP_OKAY) {
  24311. point = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap,
  24312. DYNAMIC_TYPE_ECC);
  24313. if (point == NULL)
  24314. err = MEMORY_E;
  24315. }
  24316. if (err == MP_OKAY) {
  24317. e = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 5, heap,
  24318. DYNAMIC_TYPE_ECC);
  24319. if (e == NULL)
  24320. err = MEMORY_E;
  24321. }
  24322. #endif
  24323. if (err == MP_OKAY) {
  24324. x = e + 2 * 5;
  24325. k = e + 4 * 5;
  24326. r = e + 6 * 5;
  24327. tmp = e + 8 * 5;
  24328. s = e;
  24329. if (hashLen > 32U) {
  24330. hashLen = 32U;
  24331. }
  24332. }
  24333. for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {
  24334. /* New random point. */
  24335. if (km == NULL || mp_iszero(km)) {
  24336. err = sp_256_ecc_gen_k_5(rng, k);
  24337. }
  24338. else {
  24339. sp_256_from_mp(k, 5, km);
  24340. mp_zero(km);
  24341. }
  24342. if (err == MP_OKAY) {
  24343. err = sp_256_ecc_mulmod_base_5(point, k, 1, 1, heap);
  24344. }
  24345. if (err == MP_OKAY) {
  24346. /* r = point->x mod order */
  24347. XMEMCPY(r, point->x, sizeof(sp_digit) * 5U);
  24348. sp_256_norm_5(r);
  24349. c = sp_256_cmp_5(r, p256_order);
  24350. sp_256_cond_sub_5(r, r, p256_order,
  24351. (sp_digit)0 - (sp_digit)(c >= 0));
  24352. sp_256_norm_5(r);
  24353. if (!sp_256_iszero_5(r)) {
  24354. /* x is modified in calculation of s. */
  24355. sp_256_from_mp(x, 5, priv);
  24356. /* s ptr == e ptr, e is modified in calculation of s. */
  24357. sp_256_from_bin(e, 5, hash, (int)hashLen);
  24358. err = sp_256_calc_s_5(s, r, k, x, e, tmp);
  24359. /* Check that signature is usable. */
  24360. if ((err == MP_OKAY) && (!sp_256_iszero_5(s))) {
  24361. break;
  24362. }
  24363. }
  24364. }
  24365. #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
  24366. i = 1;
  24367. #endif
  24368. }
  24369. if (i == 0) {
  24370. err = RNG_FAILURE_E;
  24371. }
  24372. if (err == MP_OKAY) {
  24373. err = sp_256_to_mp(r, rm);
  24374. }
  24375. if (err == MP_OKAY) {
  24376. err = sp_256_to_mp(s, sm);
  24377. }
  24378. #ifdef WOLFSSL_SP_SMALL_STACK
  24379. if (e != NULL)
  24380. #endif
  24381. {
  24382. ForceZero(e, sizeof(sp_digit) * 7 * 2 * 5);
  24383. #ifdef WOLFSSL_SP_SMALL_STACK
  24384. XFREE(e, heap, DYNAMIC_TYPE_ECC);
  24385. #endif
  24386. }
  24387. #ifdef WOLFSSL_SP_SMALL_STACK
  24388. if (point != NULL)
  24389. #endif
  24390. {
  24391. ForceZero(point, sizeof(sp_point_256));
  24392. #ifdef WOLFSSL_SP_SMALL_STACK
  24393. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  24394. #endif
  24395. }
  24396. return err;
  24397. }
  24398. #ifdef WOLFSSL_SP_NONBLOCK
  24399. typedef struct sp_ecc_sign_256_ctx {
  24400. int state;
  24401. union {
  24402. sp_256_ecc_mulmod_5_ctx mulmod_ctx;
  24403. sp_256_mont_inv_order_5_ctx mont_inv_order_ctx;
  24404. };
  24405. sp_digit e[2*5];
  24406. sp_digit x[2*5];
  24407. sp_digit k[2*5];
  24408. sp_digit r[2*5];
  24409. sp_digit tmp[3 * 2*5];
  24410. sp_point_256 point;
  24411. sp_digit* s;
  24412. sp_digit* kInv;
  24413. int i;
  24414. } sp_ecc_sign_256_ctx;
  24415. int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng,
  24416. mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap)
  24417. {
  24418. int err = FP_WOULDBLOCK;
  24419. sp_ecc_sign_256_ctx* ctx = (sp_ecc_sign_256_ctx*)sp_ctx->data;
  24420. typedef char ctx_size_test[sizeof(sp_ecc_sign_256_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  24421. (void)sizeof(ctx_size_test);
  24422. switch (ctx->state) {
  24423. case 0: /* INIT */
  24424. ctx->s = ctx->e;
  24425. ctx->kInv = ctx->k;
  24426. ctx->i = SP_ECC_MAX_SIG_GEN;
  24427. ctx->state = 1;
  24428. break;
  24429. case 1: /* GEN */
  24430. /* New random point. */
  24431. if (km == NULL || mp_iszero(km)) {
  24432. err = sp_256_ecc_gen_k_5(rng, ctx->k);
  24433. }
  24434. else {
  24435. sp_256_from_mp(ctx->k, 5, km);
  24436. mp_zero(km);
  24437. }
  24438. XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
  24439. ctx->state = 2;
  24440. break;
  24441. case 2: /* MULMOD */
  24442. err = sp_256_ecc_mulmod_5_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx,
  24443. &ctx->point, &p256_base, ctx->k, 1, 1, heap);
  24444. if (err == MP_OKAY) {
  24445. ctx->state = 3;
  24446. }
  24447. break;
  24448. case 3: /* MODORDER */
  24449. {
  24450. sp_int64 c;
  24451. /* r = point->x mod order */
  24452. XMEMCPY(ctx->r, ctx->point.x, sizeof(sp_digit) * 5U);
  24453. sp_256_norm_5(ctx->r);
  24454. c = sp_256_cmp_5(ctx->r, p256_order);
  24455. sp_256_cond_sub_5(ctx->r, ctx->r, p256_order,
  24456. (sp_digit)0 - (sp_digit)(c >= 0));
  24457. sp_256_norm_5(ctx->r);
  24458. if (hashLen > 32U) {
  24459. hashLen = 32U;
  24460. }
  24461. sp_256_from_mp(ctx->x, 5, priv);
  24462. sp_256_from_bin(ctx->e, 5, hash, (int)hashLen);
  24463. ctx->state = 4;
  24464. break;
  24465. }
  24466. case 4: /* KMODORDER */
  24467. /* Conv k to Montgomery form (mod order) */
  24468. sp_256_mul_5(ctx->k, ctx->k, p256_norm_order);
  24469. err = sp_256_mod_5(ctx->k, ctx->k, p256_order);
  24470. if (err == MP_OKAY) {
  24471. sp_256_norm_5(ctx->k);
  24472. XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
  24473. ctx->state = 5;
  24474. }
  24475. break;
  24476. case 5: /* KINV */
  24477. /* kInv = 1/k mod order */
  24478. err = sp_256_mont_inv_order_5_nb((sp_ecc_ctx_t*)&ctx->mont_inv_order_ctx, ctx->kInv, ctx->k, ctx->tmp);
  24479. if (err == MP_OKAY) {
  24480. XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
  24481. ctx->state = 6;
  24482. }
  24483. break;
  24484. case 6: /* KINVNORM */
  24485. sp_256_norm_5(ctx->kInv);
  24486. ctx->state = 7;
  24487. break;
  24488. case 7: /* R */
  24489. /* s = r * x + e */
  24490. sp_256_mul_5(ctx->x, ctx->x, ctx->r);
  24491. ctx->state = 8;
  24492. break;
  24493. case 8: /* S1 */
  24494. err = sp_256_mod_5(ctx->x, ctx->x, p256_order);
  24495. if (err == MP_OKAY)
  24496. ctx->state = 9;
  24497. break;
  24498. case 9: /* S2 */
  24499. {
  24500. sp_digit carry;
  24501. sp_int64 c;
  24502. sp_256_norm_5(ctx->x);
  24503. carry = sp_256_add_5(ctx->s, ctx->e, ctx->x);
  24504. sp_256_cond_sub_5(ctx->s, ctx->s,
  24505. p256_order, 0 - carry);
  24506. sp_256_norm_5(ctx->s);
  24507. c = sp_256_cmp_5(ctx->s, p256_order);
  24508. sp_256_cond_sub_5(ctx->s, ctx->s, p256_order,
  24509. (sp_digit)0 - (sp_digit)(c >= 0));
  24510. sp_256_norm_5(ctx->s);
  24511. /* s = s * k^-1 mod order */
  24512. sp_256_mont_mul_order_5(ctx->s, ctx->s, ctx->kInv);
  24513. sp_256_norm_5(ctx->s);
  24514. /* Check that signature is usable. */
  24515. if (sp_256_iszero_5(ctx->s) == 0) {
  24516. ctx->state = 10;
  24517. break;
  24518. }
  24519. #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
  24520. ctx->i = 1;
  24521. #endif
  24522. /* not usable gen, try again */
  24523. ctx->i--;
  24524. if (ctx->i == 0) {
  24525. err = RNG_FAILURE_E;
  24526. }
  24527. ctx->state = 1;
  24528. break;
  24529. }
  24530. case 10: /* RES */
  24531. err = sp_256_to_mp(ctx->r, rm);
  24532. if (err == MP_OKAY) {
  24533. err = sp_256_to_mp(ctx->s, sm);
  24534. }
  24535. break;
  24536. }
  24537. if (err == MP_OKAY && ctx->state != 10) {
  24538. err = FP_WOULDBLOCK;
  24539. }
  24540. if (err != FP_WOULDBLOCK) {
  24541. XMEMSET(ctx->e, 0, sizeof(sp_digit) * 2U * 5U);
  24542. XMEMSET(ctx->x, 0, sizeof(sp_digit) * 2U * 5U);
  24543. XMEMSET(ctx->k, 0, sizeof(sp_digit) * 2U * 5U);
  24544. XMEMSET(ctx->r, 0, sizeof(sp_digit) * 2U * 5U);
  24545. XMEMSET(ctx->tmp, 0, sizeof(sp_digit) * 3U * 2U * 5U);
  24546. }
  24547. return err;
  24548. }
  24549. #endif /* WOLFSSL_SP_NONBLOCK */
  24550. #endif /* HAVE_ECC_SIGN */
  24551. #ifndef WOLFSSL_SP_SMALL
  24552. static const char sp_256_tab64_5[64] = {
  24553. 64, 1, 59, 2, 60, 48, 54, 3,
  24554. 61, 40, 49, 28, 55, 34, 43, 4,
  24555. 62, 52, 38, 41, 50, 19, 29, 21,
  24556. 56, 31, 35, 12, 44, 15, 23, 5,
  24557. 63, 58, 47, 53, 39, 27, 33, 42,
  24558. 51, 37, 18, 20, 30, 11, 14, 22,
  24559. 57, 46, 26, 32, 36, 17, 10, 13,
  24560. 45, 25, 16, 9, 24, 8, 7, 6};
  24561. static int sp_256_num_bits_52_5(sp_digit v)
  24562. {
  24563. v |= v >> 1;
  24564. v |= v >> 2;
  24565. v |= v >> 4;
  24566. v |= v >> 8;
  24567. v |= v >> 16;
  24568. v |= v >> 32;
  24569. return sp_256_tab64_5[((uint64_t)((v - (v >> 1))*0x07EDD5E59A4E28C2)) >> 58];
  24570. }
  24571. static int sp_256_num_bits_5(const sp_digit* a)
  24572. {
  24573. int i;
  24574. int r = 0;
  24575. for (i = 4; i >= 0; i--) {
  24576. if (a[i] != 0) {
  24577. r = sp_256_num_bits_52_5(a[i]);
  24578. r += i * 52;
  24579. break;
  24580. }
  24581. }
  24582. return r;
  24583. }
  24584. /* Non-constant time modular inversion.
  24585. *
  24586. * @param [out] r Resulting number.
  24587. * @param [in] a Number to invert.
  24588. * @param [in] m Modulus.
  24589. * @return MP_OKAY on success.
  24590. * @return MEMEORY_E when dynamic memory allocation fails.
  24591. */
  24592. static int sp_256_mod_inv_5(sp_digit* r, const sp_digit* a, const sp_digit* m)
  24593. {
  24594. int err = MP_OKAY;
  24595. #ifdef WOLFSSL_SP_SMALL_STACK
  24596. sp_digit* u = NULL;
  24597. #else
  24598. sp_digit u[5 * 4];
  24599. #endif
  24600. sp_digit* v = NULL;
  24601. sp_digit* b = NULL;
  24602. sp_digit* d = NULL;
  24603. int ut;
  24604. int vt;
  24605. #ifdef WOLFSSL_SP_SMALL_STACK
  24606. u = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 4, NULL,
  24607. DYNAMIC_TYPE_ECC);
  24608. if (u == NULL)
  24609. err = MEMORY_E;
  24610. #endif
  24611. if (err == MP_OKAY) {
  24612. v = u + 5;
  24613. b = u + 2 * 5;
  24614. d = u + 3 * 5;
  24615. XMEMCPY(u, m, sizeof(sp_digit) * 5);
  24616. XMEMCPY(v, a, sizeof(sp_digit) * 5);
  24617. ut = sp_256_num_bits_5(u);
  24618. vt = sp_256_num_bits_5(v);
  24619. XMEMSET(b, 0, sizeof(sp_digit) * 5);
  24620. if ((v[0] & 1) == 0) {
  24621. sp_256_rshift1_5(v, v);
  24622. XMEMCPY(d, m, sizeof(sp_digit) * 5);
  24623. d[0]++;
  24624. sp_256_rshift1_5(d, d);
  24625. vt--;
  24626. while ((v[0] & 1) == 0) {
  24627. sp_256_rshift1_5(v, v);
  24628. if (d[0] & 1)
  24629. sp_256_add_5(d, d, m);
  24630. sp_256_rshift1_5(d, d);
  24631. vt--;
  24632. }
  24633. }
  24634. else {
  24635. XMEMSET(d+1, 0, sizeof(sp_digit) * (5 - 1));
  24636. d[0] = 1;
  24637. }
  24638. while (ut > 1 && vt > 1) {
  24639. if ((ut > vt) || ((ut == vt) &&
  24640. (sp_256_cmp_5(u, v) >= 0))) {
  24641. sp_256_sub_5(u, u, v);
  24642. sp_256_norm_5(u);
  24643. sp_256_sub_5(b, b, d);
  24644. sp_256_norm_5(b);
  24645. if (b[4] < 0)
  24646. sp_256_add_5(b, b, m);
  24647. sp_256_norm_5(b);
  24648. ut = sp_256_num_bits_5(u);
  24649. do {
  24650. sp_256_rshift1_5(u, u);
  24651. if (b[0] & 1)
  24652. sp_256_add_5(b, b, m);
  24653. sp_256_rshift1_5(b, b);
  24654. ut--;
  24655. }
  24656. while (ut > 0 && (u[0] & 1) == 0);
  24657. }
  24658. else {
  24659. sp_256_sub_5(v, v, u);
  24660. sp_256_norm_5(v);
  24661. sp_256_sub_5(d, d, b);
  24662. sp_256_norm_5(d);
  24663. if (d[4] < 0)
  24664. sp_256_add_5(d, d, m);
  24665. sp_256_norm_5(d);
  24666. vt = sp_256_num_bits_5(v);
  24667. do {
  24668. sp_256_rshift1_5(v, v);
  24669. if (d[0] & 1)
  24670. sp_256_add_5(d, d, m);
  24671. sp_256_rshift1_5(d, d);
  24672. vt--;
  24673. }
  24674. while (vt > 0 && (v[0] & 1) == 0);
  24675. }
  24676. }
  24677. if (ut == 1)
  24678. XMEMCPY(r, b, sizeof(sp_digit) * 5);
  24679. else
  24680. XMEMCPY(r, d, sizeof(sp_digit) * 5);
  24681. }
  24682. #ifdef WOLFSSL_SP_SMALL_STACK
  24683. if (u != NULL)
  24684. XFREE(u, NULL, DYNAMIC_TYPE_ECC);
  24685. #endif
  24686. return err;
  24687. }
  24688. #endif /* WOLFSSL_SP_SMALL */
  24689. /* Add point p1 into point p2. Handles p1 == p2 and result at infinity.
  24690. *
  24691. * p1 First point to add and holds result.
  24692. * p2 Second point to add.
  24693. * tmp Temporary storage for intermediate numbers.
  24694. */
  24695. static void sp_256_add_points_5(sp_point_256* p1, const sp_point_256* p2,
  24696. sp_digit* tmp)
  24697. {
  24698. sp_256_proj_point_add_5(p1, p1, p2, tmp);
  24699. if (sp_256_iszero_5(p1->z)) {
  24700. if (sp_256_iszero_5(p1->x) && sp_256_iszero_5(p1->y)) {
  24701. sp_256_proj_point_dbl_5(p1, p2, tmp);
  24702. }
  24703. else {
  24704. /* Y ordinate is not used from here - don't set. */
  24705. p1->x[0] = 0;
  24706. p1->x[1] = 0;
  24707. p1->x[2] = 0;
  24708. p1->x[3] = 0;
  24709. p1->x[4] = 0;
  24710. XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));
  24711. }
  24712. }
  24713. }
  24714. /* Calculate the verification point: [e/s]G + [r/s]Q
  24715. *
  24716. * p1 Calculated point.
  24717. * p2 Public point and temporary.
  24718. * s Second part of signature as a number.
  24719. * u1 Temporary number.
  24720. * u2 Temporary number.
  24721. * heap Heap to use for allocation.
  24722. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  24723. */
  24724. static int sp_256_calc_vfy_point_5(sp_point_256* p1, sp_point_256* p2,
  24725. sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap)
  24726. {
  24727. int err;
  24728. #ifndef WOLFSSL_SP_SMALL
  24729. err = sp_256_mod_inv_5(s, s, p256_order);
  24730. if (err == MP_OKAY)
  24731. #endif /* !WOLFSSL_SP_SMALL */
  24732. {
  24733. sp_256_mul_5(s, s, p256_norm_order);
  24734. err = sp_256_mod_5(s, s, p256_order);
  24735. }
  24736. if (err == MP_OKAY) {
  24737. sp_256_norm_5(s);
  24738. #ifdef WOLFSSL_SP_SMALL
  24739. {
  24740. sp_256_mont_inv_order_5(s, s, tmp);
  24741. sp_256_mont_mul_order_5(u1, u1, s);
  24742. sp_256_mont_mul_order_5(u2, u2, s);
  24743. }
  24744. #else
  24745. {
  24746. sp_256_mont_mul_order_5(u1, u1, s);
  24747. sp_256_mont_mul_order_5(u2, u2, s);
  24748. }
  24749. #endif /* WOLFSSL_SP_SMALL */
  24750. {
  24751. err = sp_256_ecc_mulmod_base_5(p1, u1, 0, 0, heap);
  24752. }
  24753. }
  24754. if ((err == MP_OKAY) && sp_256_iszero_5(p1->z)) {
  24755. p1->infinity = 1;
  24756. }
  24757. if (err == MP_OKAY) {
  24758. err = sp_256_ecc_mulmod_5(p2, p2, u2, 0, 0, heap);
  24759. }
  24760. if ((err == MP_OKAY) && sp_256_iszero_5(p2->z)) {
  24761. p2->infinity = 1;
  24762. }
  24763. if (err == MP_OKAY) {
  24764. sp_256_add_points_5(p1, p2, tmp);
  24765. }
  24766. return err;
  24767. }
  24768. #ifdef HAVE_ECC_VERIFY
  24769. /* Verify the signature values with the hash and public key.
  24770. * e = Truncate(hash, 256)
  24771. * u1 = e/s mod order
  24772. * u2 = r/s mod order
  24773. * r == (u1.G + u2.Q)->x mod order
  24774. * Optimization: Leave point in projective form.
  24775. * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')
  24776. * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'
  24777. * The hash is truncated to the first 256 bits.
  24778. *
  24779. * hash Hash to sign.
  24780. * hashLen Length of the hash data.
  24781. * rng Random number generator.
  24782. * priv Private part of key - scalar.
  24783. * rm First part of result as an mp_int.
  24784. * sm Sirst part of result as an mp_int.
  24785. * heap Heap to use for allocation.
  24786. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  24787. */
  24788. int sp_ecc_verify_256(const byte* hash, word32 hashLen, const mp_int* pX,
  24789. const mp_int* pY, const mp_int* pZ, const mp_int* rm, const mp_int* sm,
  24790. int* res, void* heap)
  24791. {
  24792. #ifdef WOLFSSL_SP_SMALL_STACK
  24793. sp_digit* u1 = NULL;
  24794. sp_point_256* p1 = NULL;
  24795. #else
  24796. sp_digit u1[18 * 5];
  24797. sp_point_256 p1[2];
  24798. #endif
  24799. sp_digit* u2 = NULL;
  24800. sp_digit* s = NULL;
  24801. sp_digit* tmp = NULL;
  24802. sp_point_256* p2 = NULL;
  24803. sp_digit carry;
  24804. sp_int64 c = 0;
  24805. int err = MP_OKAY;
  24806. #ifdef WOLFSSL_SP_SMALL_STACK
  24807. if (err == MP_OKAY) {
  24808. p1 = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 2, heap,
  24809. DYNAMIC_TYPE_ECC);
  24810. if (p1 == NULL)
  24811. err = MEMORY_E;
  24812. }
  24813. if (err == MP_OKAY) {
  24814. u1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 5, heap,
  24815. DYNAMIC_TYPE_ECC);
  24816. if (u1 == NULL)
  24817. err = MEMORY_E;
  24818. }
  24819. #endif
  24820. if (err == MP_OKAY) {
  24821. u2 = u1 + 2 * 5;
  24822. s = u1 + 4 * 5;
  24823. tmp = u1 + 6 * 5;
  24824. p2 = p1 + 1;
  24825. if (hashLen > 32U) {
  24826. hashLen = 32U;
  24827. }
  24828. sp_256_from_bin(u1, 5, hash, (int)hashLen);
  24829. sp_256_from_mp(u2, 5, rm);
  24830. sp_256_from_mp(s, 5, sm);
  24831. sp_256_from_mp(p2->x, 5, pX);
  24832. sp_256_from_mp(p2->y, 5, pY);
  24833. sp_256_from_mp(p2->z, 5, pZ);
  24834. err = sp_256_calc_vfy_point_5(p1, p2, s, u1, u2, tmp, heap);
  24835. }
  24836. if (err == MP_OKAY) {
  24837. /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
  24838. /* Reload r and convert to Montgomery form. */
  24839. sp_256_from_mp(u2, 5, rm);
  24840. err = sp_256_mod_mul_norm_5(u2, u2, p256_mod);
  24841. }
  24842. if (err == MP_OKAY) {
  24843. /* u1 = r.z'.z' mod prime */
  24844. sp_256_mont_sqr_5(p1->z, p1->z, p256_mod, p256_mp_mod);
  24845. sp_256_mont_mul_5(u1, u2, p1->z, p256_mod, p256_mp_mod);
  24846. *res = (int)(sp_256_cmp_5(p1->x, u1) == 0);
  24847. if (*res == 0) {
  24848. /* Reload r and add order. */
  24849. sp_256_from_mp(u2, 5, rm);
  24850. carry = sp_256_add_5(u2, u2, p256_order);
  24851. /* Carry means result is greater than mod and is not valid. */
  24852. if (carry == 0) {
  24853. sp_256_norm_5(u2);
  24854. /* Compare with mod and if greater or equal then not valid. */
  24855. c = sp_256_cmp_5(u2, p256_mod);
  24856. }
  24857. }
  24858. if ((*res == 0) && (c < 0)) {
  24859. /* Convert to Montogomery form */
  24860. err = sp_256_mod_mul_norm_5(u2, u2, p256_mod);
  24861. if (err == MP_OKAY) {
  24862. /* u1 = (r + 1*order).z'.z' mod prime */
  24863. {
  24864. sp_256_mont_mul_5(u1, u2, p1->z, p256_mod, p256_mp_mod);
  24865. }
  24866. *res = (sp_256_cmp_5(p1->x, u1) == 0);
  24867. }
  24868. }
  24869. }
  24870. #ifdef WOLFSSL_SP_SMALL_STACK
  24871. if (u1 != NULL)
  24872. XFREE(u1, heap, DYNAMIC_TYPE_ECC);
  24873. if (p1 != NULL)
  24874. XFREE(p1, heap, DYNAMIC_TYPE_ECC);
  24875. #endif
  24876. return err;
  24877. }
  24878. #ifdef WOLFSSL_SP_NONBLOCK
  24879. typedef struct sp_ecc_verify_256_ctx {
  24880. int state;
  24881. union {
  24882. sp_256_ecc_mulmod_5_ctx mulmod_ctx;
  24883. sp_256_mont_inv_order_5_ctx mont_inv_order_ctx;
  24884. sp_256_proj_point_dbl_5_ctx dbl_ctx;
  24885. sp_256_proj_point_add_5_ctx add_ctx;
  24886. };
  24887. sp_digit u1[2*5];
  24888. sp_digit u2[2*5];
  24889. sp_digit s[2*5];
  24890. sp_digit tmp[2*5 * 6];
  24891. sp_point_256 p1;
  24892. sp_point_256 p2;
  24893. } sp_ecc_verify_256_ctx;
  24894. int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash,
  24895. word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ,
  24896. const mp_int* rm, const mp_int* sm, int* res, void* heap)
  24897. {
  24898. int err = FP_WOULDBLOCK;
  24899. sp_ecc_verify_256_ctx* ctx = (sp_ecc_verify_256_ctx*)sp_ctx->data;
  24900. typedef char ctx_size_test[sizeof(sp_ecc_verify_256_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  24901. (void)sizeof(ctx_size_test);
  24902. switch (ctx->state) {
  24903. case 0: /* INIT */
  24904. if (hashLen > 32U) {
  24905. hashLen = 32U;
  24906. }
  24907. sp_256_from_bin(ctx->u1, 5, hash, (int)hashLen);
  24908. sp_256_from_mp(ctx->u2, 5, rm);
  24909. sp_256_from_mp(ctx->s, 5, sm);
  24910. sp_256_from_mp(ctx->p2.x, 5, pX);
  24911. sp_256_from_mp(ctx->p2.y, 5, pY);
  24912. sp_256_from_mp(ctx->p2.z, 5, pZ);
  24913. ctx->state = 1;
  24914. break;
  24915. case 1: /* NORMS0 */
  24916. sp_256_mul_5(ctx->s, ctx->s, p256_norm_order);
  24917. err = sp_256_mod_5(ctx->s, ctx->s, p256_order);
  24918. if (err == MP_OKAY)
  24919. ctx->state = 2;
  24920. break;
  24921. case 2: /* NORMS1 */
  24922. sp_256_norm_5(ctx->s);
  24923. XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
  24924. ctx->state = 3;
  24925. break;
  24926. case 3: /* NORMS2 */
  24927. err = sp_256_mont_inv_order_5_nb((sp_ecc_ctx_t*)&ctx->mont_inv_order_ctx, ctx->s, ctx->s, ctx->tmp);
  24928. if (err == MP_OKAY) {
  24929. ctx->state = 4;
  24930. }
  24931. break;
  24932. case 4: /* NORMS3 */
  24933. sp_256_mont_mul_order_5(ctx->u1, ctx->u1, ctx->s);
  24934. ctx->state = 5;
  24935. break;
  24936. case 5: /* NORMS4 */
  24937. sp_256_mont_mul_order_5(ctx->u2, ctx->u2, ctx->s);
  24938. XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
  24939. ctx->state = 6;
  24940. break;
  24941. case 6: /* MULBASE */
  24942. err = sp_256_ecc_mulmod_5_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx, &ctx->p1, &p256_base, ctx->u1, 0, 0, heap);
  24943. if (err == MP_OKAY) {
  24944. if (sp_256_iszero_5(ctx->p1.z)) {
  24945. ctx->p1.infinity = 1;
  24946. }
  24947. XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
  24948. ctx->state = 7;
  24949. }
  24950. break;
  24951. case 7: /* MULMOD */
  24952. err = sp_256_ecc_mulmod_5_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx, &ctx->p2, &ctx->p2, ctx->u2, 0, 0, heap);
  24953. if (err == MP_OKAY) {
  24954. if (sp_256_iszero_5(ctx->p2.z)) {
  24955. ctx->p2.infinity = 1;
  24956. }
  24957. XMEMSET(&ctx->add_ctx, 0, sizeof(ctx->add_ctx));
  24958. ctx->state = 8;
  24959. }
  24960. break;
  24961. case 8: /* ADD */
  24962. err = sp_256_proj_point_add_5_nb((sp_ecc_ctx_t*)&ctx->add_ctx, &ctx->p1, &ctx->p1, &ctx->p2, ctx->tmp);
  24963. if (err == MP_OKAY)
  24964. ctx->state = 9;
  24965. break;
  24966. case 9: /* MONT */
  24967. /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
  24968. /* Reload r and convert to Montgomery form. */
  24969. sp_256_from_mp(ctx->u2, 5, rm);
  24970. err = sp_256_mod_mul_norm_5(ctx->u2, ctx->u2, p256_mod);
  24971. if (err == MP_OKAY)
  24972. ctx->state = 10;
  24973. break;
  24974. case 10: /* SQR */
  24975. /* u1 = r.z'.z' mod prime */
  24976. sp_256_mont_sqr_5(ctx->p1.z, ctx->p1.z, p256_mod, p256_mp_mod);
  24977. ctx->state = 11;
  24978. break;
  24979. case 11: /* MUL */
  24980. sp_256_mont_mul_5(ctx->u1, ctx->u2, ctx->p1.z, p256_mod, p256_mp_mod);
  24981. ctx->state = 12;
  24982. break;
  24983. case 12: /* RES */
  24984. {
  24985. sp_int64 c = 0;
  24986. err = MP_OKAY; /* math okay, now check result */
  24987. *res = (int)(sp_256_cmp_5(ctx->p1.x, ctx->u1) == 0);
  24988. if (*res == 0) {
  24989. sp_digit carry;
  24990. /* Reload r and add order. */
  24991. sp_256_from_mp(ctx->u2, 5, rm);
  24992. carry = sp_256_add_5(ctx->u2, ctx->u2, p256_order);
  24993. /* Carry means result is greater than mod and is not valid. */
  24994. if (carry == 0) {
  24995. sp_256_norm_5(ctx->u2);
  24996. /* Compare with mod and if greater or equal then not valid. */
  24997. c = sp_256_cmp_5(ctx->u2, p256_mod);
  24998. }
  24999. }
  25000. if ((*res == 0) && (c < 0)) {
  25001. /* Convert to Montogomery form */
  25002. err = sp_256_mod_mul_norm_5(ctx->u2, ctx->u2, p256_mod);
  25003. if (err == MP_OKAY) {
  25004. /* u1 = (r + 1*order).z'.z' mod prime */
  25005. sp_256_mont_mul_5(ctx->u1, ctx->u2, ctx->p1.z, p256_mod,
  25006. p256_mp_mod);
  25007. *res = (int)(sp_256_cmp_5(ctx->p1.x, ctx->u1) == 0);
  25008. }
  25009. }
  25010. break;
  25011. }
  25012. } /* switch */
  25013. if (err == MP_OKAY && ctx->state != 12) {
  25014. err = FP_WOULDBLOCK;
  25015. }
  25016. return err;
  25017. }
  25018. #endif /* WOLFSSL_SP_NONBLOCK */
  25019. #endif /* HAVE_ECC_VERIFY */
  25020. #ifdef HAVE_ECC_CHECK_KEY
  25021. /* Check that the x and y ordinates are a valid point on the curve.
  25022. *
  25023. * point EC point.
  25024. * heap Heap to use if dynamically allocating.
  25025. * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
  25026. * not on the curve and MP_OKAY otherwise.
  25027. */
  25028. static int sp_256_ecc_is_point_5(const sp_point_256* point,
  25029. void* heap)
  25030. {
  25031. #ifdef WOLFSSL_SP_SMALL_STACK
  25032. sp_digit* t1 = NULL;
  25033. #else
  25034. sp_digit t1[5 * 4];
  25035. #endif
  25036. sp_digit* t2 = NULL;
  25037. int err = MP_OKAY;
  25038. #ifdef WOLFSSL_SP_SMALL_STACK
  25039. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 4, heap, DYNAMIC_TYPE_ECC);
  25040. if (t1 == NULL)
  25041. err = MEMORY_E;
  25042. #endif
  25043. (void)heap;
  25044. if (err == MP_OKAY) {
  25045. t2 = t1 + 2 * 5;
  25046. /* y^2 - x^3 - a.x = b */
  25047. sp_256_sqr_5(t1, point->y);
  25048. (void)sp_256_mod_5(t1, t1, p256_mod);
  25049. sp_256_sqr_5(t2, point->x);
  25050. (void)sp_256_mod_5(t2, t2, p256_mod);
  25051. sp_256_mul_5(t2, t2, point->x);
  25052. (void)sp_256_mod_5(t2, t2, p256_mod);
  25053. sp_256_mont_sub_5(t1, t1, t2, p256_mod);
  25054. /* y^2 - x^3 + 3.x = b, when a = -3 */
  25055. sp_256_mont_add_5(t1, t1, point->x, p256_mod);
  25056. sp_256_mont_add_5(t1, t1, point->x, p256_mod);
  25057. sp_256_mont_add_5(t1, t1, point->x, p256_mod);
  25058. if (sp_256_cmp_5(t1, p256_b) != 0) {
  25059. err = MP_VAL;
  25060. }
  25061. }
  25062. #ifdef WOLFSSL_SP_SMALL_STACK
  25063. if (t1 != NULL)
  25064. XFREE(t1, heap, DYNAMIC_TYPE_ECC);
  25065. #endif
  25066. return err;
  25067. }
  25068. /* Check that the x and y ordinates are a valid point on the curve.
  25069. *
  25070. * pX X ordinate of EC point.
  25071. * pY Y ordinate of EC point.
  25072. * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
  25073. * not on the curve and MP_OKAY otherwise.
  25074. */
  25075. int sp_ecc_is_point_256(const mp_int* pX, const mp_int* pY)
  25076. {
  25077. #ifdef WOLFSSL_SP_SMALL_STACK
  25078. sp_point_256* pub = NULL;
  25079. #else
  25080. sp_point_256 pub[1];
  25081. #endif
  25082. const byte one[1] = { 1 };
  25083. int err = MP_OKAY;
  25084. #ifdef WOLFSSL_SP_SMALL_STACK
  25085. pub = (sp_point_256*)XMALLOC(sizeof(sp_point_256), NULL,
  25086. DYNAMIC_TYPE_ECC);
  25087. if (pub == NULL)
  25088. err = MEMORY_E;
  25089. #endif
  25090. if (err == MP_OKAY) {
  25091. sp_256_from_mp(pub->x, 5, pX);
  25092. sp_256_from_mp(pub->y, 5, pY);
  25093. sp_256_from_bin(pub->z, 5, one, (int)sizeof(one));
  25094. err = sp_256_ecc_is_point_5(pub, NULL);
  25095. }
  25096. #ifdef WOLFSSL_SP_SMALL_STACK
  25097. if (pub != NULL)
  25098. XFREE(pub, NULL, DYNAMIC_TYPE_ECC);
  25099. #endif
  25100. return err;
  25101. }
  25102. /* Check that the private scalar generates the EC point (px, py), the point is
  25103. * on the curve and the point has the correct order.
  25104. *
  25105. * pX X ordinate of EC point.
  25106. * pY Y ordinate of EC point.
  25107. * privm Private scalar that generates EC point.
  25108. * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
  25109. * not on the curve, ECC_INF_E if the point does not have the correct order,
  25110. * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and
  25111. * MP_OKAY otherwise.
  25112. */
  25113. int sp_ecc_check_key_256(const mp_int* pX, const mp_int* pY,
  25114. const mp_int* privm, void* heap)
  25115. {
  25116. #ifdef WOLFSSL_SP_SMALL_STACK
  25117. sp_digit* priv = NULL;
  25118. sp_point_256* pub = NULL;
  25119. #else
  25120. sp_digit priv[5];
  25121. sp_point_256 pub[2];
  25122. #endif
  25123. sp_point_256* p = NULL;
  25124. const byte one[1] = { 1 };
  25125. int err = MP_OKAY;
  25126. /* Quick check the lengs of public key ordinates and private key are in
  25127. * range. Proper check later.
  25128. */
  25129. if (((mp_count_bits(pX) > 256) ||
  25130. (mp_count_bits(pY) > 256) ||
  25131. ((privm != NULL) && (mp_count_bits(privm) > 256)))) {
  25132. err = ECC_OUT_OF_RANGE_E;
  25133. }
  25134. #ifdef WOLFSSL_SP_SMALL_STACK
  25135. if (err == MP_OKAY) {
  25136. pub = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 2, heap,
  25137. DYNAMIC_TYPE_ECC);
  25138. if (pub == NULL)
  25139. err = MEMORY_E;
  25140. }
  25141. if (err == MP_OKAY && privm) {
  25142. priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,
  25143. DYNAMIC_TYPE_ECC);
  25144. if (priv == NULL)
  25145. err = MEMORY_E;
  25146. }
  25147. #endif
  25148. if (err == MP_OKAY) {
  25149. p = pub + 1;
  25150. sp_256_from_mp(pub->x, 5, pX);
  25151. sp_256_from_mp(pub->y, 5, pY);
  25152. sp_256_from_bin(pub->z, 5, one, (int)sizeof(one));
  25153. if (privm)
  25154. sp_256_from_mp(priv, 5, privm);
  25155. /* Check point at infinitiy. */
  25156. if ((sp_256_iszero_5(pub->x) != 0) &&
  25157. (sp_256_iszero_5(pub->y) != 0)) {
  25158. err = ECC_INF_E;
  25159. }
  25160. }
  25161. /* Check range of X and Y */
  25162. if ((err == MP_OKAY) &&
  25163. ((sp_256_cmp_5(pub->x, p256_mod) >= 0) ||
  25164. (sp_256_cmp_5(pub->y, p256_mod) >= 0))) {
  25165. err = ECC_OUT_OF_RANGE_E;
  25166. }
  25167. if (err == MP_OKAY) {
  25168. /* Check point is on curve */
  25169. err = sp_256_ecc_is_point_5(pub, heap);
  25170. }
  25171. if (err == MP_OKAY) {
  25172. /* Point * order = infinity */
  25173. err = sp_256_ecc_mulmod_5(p, pub, p256_order, 1, 1, heap);
  25174. }
  25175. /* Check result is infinity */
  25176. if ((err == MP_OKAY) && ((sp_256_iszero_5(p->x) == 0) ||
  25177. (sp_256_iszero_5(p->y) == 0))) {
  25178. err = ECC_INF_E;
  25179. }
  25180. if (privm) {
  25181. if (err == MP_OKAY) {
  25182. /* Base * private = point */
  25183. err = sp_256_ecc_mulmod_base_5(p, priv, 1, 1, heap);
  25184. }
  25185. /* Check result is public key */
  25186. if ((err == MP_OKAY) &&
  25187. ((sp_256_cmp_5(p->x, pub->x) != 0) ||
  25188. (sp_256_cmp_5(p->y, pub->y) != 0))) {
  25189. err = ECC_PRIV_KEY_E;
  25190. }
  25191. }
  25192. #ifdef WOLFSSL_SP_SMALL_STACK
  25193. if (pub != NULL)
  25194. XFREE(pub, heap, DYNAMIC_TYPE_ECC);
  25195. if (priv != NULL)
  25196. XFREE(priv, heap, DYNAMIC_TYPE_ECC);
  25197. #endif
  25198. return err;
  25199. }
  25200. #endif
  25201. #ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL
  25202. /* Add two projective EC points together.
  25203. * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)
  25204. *
  25205. * pX First EC point's X ordinate.
  25206. * pY First EC point's Y ordinate.
  25207. * pZ First EC point's Z ordinate.
  25208. * qX Second EC point's X ordinate.
  25209. * qY Second EC point's Y ordinate.
  25210. * qZ Second EC point's Z ordinate.
  25211. * rX Resultant EC point's X ordinate.
  25212. * rY Resultant EC point's Y ordinate.
  25213. * rZ Resultant EC point's Z ordinate.
  25214. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  25215. */
  25216. int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,
  25217. mp_int* qX, mp_int* qY, mp_int* qZ,
  25218. mp_int* rX, mp_int* rY, mp_int* rZ)
  25219. {
  25220. #ifdef WOLFSSL_SP_SMALL_STACK
  25221. sp_digit* tmp = NULL;
  25222. sp_point_256* p = NULL;
  25223. #else
  25224. sp_digit tmp[2 * 5 * 6];
  25225. sp_point_256 p[2];
  25226. #endif
  25227. sp_point_256* q = NULL;
  25228. int err = MP_OKAY;
  25229. #ifdef WOLFSSL_SP_SMALL_STACK
  25230. if (err == MP_OKAY) {
  25231. p = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 2, NULL,
  25232. DYNAMIC_TYPE_ECC);
  25233. if (p == NULL)
  25234. err = MEMORY_E;
  25235. }
  25236. if (err == MP_OKAY) {
  25237. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 6, NULL,
  25238. DYNAMIC_TYPE_ECC);
  25239. if (tmp == NULL) {
  25240. err = MEMORY_E;
  25241. }
  25242. }
  25243. #endif
  25244. if (err == MP_OKAY) {
  25245. q = p + 1;
  25246. sp_256_from_mp(p->x, 5, pX);
  25247. sp_256_from_mp(p->y, 5, pY);
  25248. sp_256_from_mp(p->z, 5, pZ);
  25249. sp_256_from_mp(q->x, 5, qX);
  25250. sp_256_from_mp(q->y, 5, qY);
  25251. sp_256_from_mp(q->z, 5, qZ);
  25252. p->infinity = sp_256_iszero_5(p->x) &
  25253. sp_256_iszero_5(p->y);
  25254. q->infinity = sp_256_iszero_5(q->x) &
  25255. sp_256_iszero_5(q->y);
  25256. sp_256_proj_point_add_5(p, p, q, tmp);
  25257. }
  25258. if (err == MP_OKAY) {
  25259. err = sp_256_to_mp(p->x, rX);
  25260. }
  25261. if (err == MP_OKAY) {
  25262. err = sp_256_to_mp(p->y, rY);
  25263. }
  25264. if (err == MP_OKAY) {
  25265. err = sp_256_to_mp(p->z, rZ);
  25266. }
  25267. #ifdef WOLFSSL_SP_SMALL_STACK
  25268. if (tmp != NULL)
  25269. XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
  25270. if (p != NULL)
  25271. XFREE(p, NULL, DYNAMIC_TYPE_ECC);
  25272. #endif
  25273. return err;
  25274. }
  25275. /* Double a projective EC point.
  25276. * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)
  25277. *
  25278. * pX EC point's X ordinate.
  25279. * pY EC point's Y ordinate.
  25280. * pZ EC point's Z ordinate.
  25281. * rX Resultant EC point's X ordinate.
  25282. * rY Resultant EC point's Y ordinate.
  25283. * rZ Resultant EC point's Z ordinate.
  25284. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  25285. */
  25286. int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,
  25287. mp_int* rX, mp_int* rY, mp_int* rZ)
  25288. {
  25289. #ifdef WOLFSSL_SP_SMALL_STACK
  25290. sp_digit* tmp = NULL;
  25291. sp_point_256* p = NULL;
  25292. #else
  25293. sp_digit tmp[2 * 5 * 2];
  25294. sp_point_256 p[1];
  25295. #endif
  25296. int err = MP_OKAY;
  25297. #ifdef WOLFSSL_SP_SMALL_STACK
  25298. if (err == MP_OKAY) {
  25299. p = (sp_point_256*)XMALLOC(sizeof(sp_point_256), NULL,
  25300. DYNAMIC_TYPE_ECC);
  25301. if (p == NULL)
  25302. err = MEMORY_E;
  25303. }
  25304. if (err == MP_OKAY) {
  25305. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 2, NULL,
  25306. DYNAMIC_TYPE_ECC);
  25307. if (tmp == NULL)
  25308. err = MEMORY_E;
  25309. }
  25310. #endif
  25311. if (err == MP_OKAY) {
  25312. sp_256_from_mp(p->x, 5, pX);
  25313. sp_256_from_mp(p->y, 5, pY);
  25314. sp_256_from_mp(p->z, 5, pZ);
  25315. p->infinity = sp_256_iszero_5(p->x) &
  25316. sp_256_iszero_5(p->y);
  25317. sp_256_proj_point_dbl_5(p, p, tmp);
  25318. }
  25319. if (err == MP_OKAY) {
  25320. err = sp_256_to_mp(p->x, rX);
  25321. }
  25322. if (err == MP_OKAY) {
  25323. err = sp_256_to_mp(p->y, rY);
  25324. }
  25325. if (err == MP_OKAY) {
  25326. err = sp_256_to_mp(p->z, rZ);
  25327. }
  25328. #ifdef WOLFSSL_SP_SMALL_STACK
  25329. if (tmp != NULL)
  25330. XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
  25331. if (p != NULL)
  25332. XFREE(p, NULL, DYNAMIC_TYPE_ECC);
  25333. #endif
  25334. return err;
  25335. }
  25336. /* Map a projective EC point to affine in place.
  25337. * pZ will be one.
  25338. *
  25339. * pX EC point's X ordinate.
  25340. * pY EC point's Y ordinate.
  25341. * pZ EC point's Z ordinate.
  25342. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  25343. */
  25344. int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ)
  25345. {
  25346. #ifdef WOLFSSL_SP_SMALL_STACK
  25347. sp_digit* tmp = NULL;
  25348. sp_point_256* p = NULL;
  25349. #else
  25350. sp_digit tmp[2 * 5 * 4];
  25351. sp_point_256 p[1];
  25352. #endif
  25353. int err = MP_OKAY;
  25354. #ifdef WOLFSSL_SP_SMALL_STACK
  25355. if (err == MP_OKAY) {
  25356. p = (sp_point_256*)XMALLOC(sizeof(sp_point_256), NULL,
  25357. DYNAMIC_TYPE_ECC);
  25358. if (p == NULL)
  25359. err = MEMORY_E;
  25360. }
  25361. if (err == MP_OKAY) {
  25362. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 4, NULL,
  25363. DYNAMIC_TYPE_ECC);
  25364. if (tmp == NULL)
  25365. err = MEMORY_E;
  25366. }
  25367. #endif
  25368. if (err == MP_OKAY) {
  25369. sp_256_from_mp(p->x, 5, pX);
  25370. sp_256_from_mp(p->y, 5, pY);
  25371. sp_256_from_mp(p->z, 5, pZ);
  25372. p->infinity = sp_256_iszero_5(p->x) &
  25373. sp_256_iszero_5(p->y);
  25374. sp_256_map_5(p, p, tmp);
  25375. }
  25376. if (err == MP_OKAY) {
  25377. err = sp_256_to_mp(p->x, pX);
  25378. }
  25379. if (err == MP_OKAY) {
  25380. err = sp_256_to_mp(p->y, pY);
  25381. }
  25382. if (err == MP_OKAY) {
  25383. err = sp_256_to_mp(p->z, pZ);
  25384. }
  25385. #ifdef WOLFSSL_SP_SMALL_STACK
  25386. if (tmp != NULL)
  25387. XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
  25388. if (p != NULL)
  25389. XFREE(p, NULL, DYNAMIC_TYPE_ECC);
  25390. #endif
  25391. return err;
  25392. }
  25393. #endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */
  25394. #ifdef HAVE_COMP_KEY
  25395. /* Find the square root of a number mod the prime of the curve.
  25396. *
  25397. * y The number to operate on and the result.
  25398. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  25399. */
  25400. static int sp_256_mont_sqrt_5(sp_digit* y)
  25401. {
  25402. #ifdef WOLFSSL_SP_SMALL_STACK
  25403. sp_digit* t1 = NULL;
  25404. #else
  25405. sp_digit t1[4 * 5];
  25406. #endif
  25407. sp_digit* t2 = NULL;
  25408. int err = MP_OKAY;
  25409. #ifdef WOLFSSL_SP_SMALL_STACK
  25410. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 5, NULL, DYNAMIC_TYPE_ECC);
  25411. if (t1 == NULL) {
  25412. err = MEMORY_E;
  25413. }
  25414. #endif
  25415. if (err == MP_OKAY) {
  25416. t2 = t1 + 2 * 5;
  25417. {
  25418. /* t2 = y ^ 0x2 */
  25419. sp_256_mont_sqr_5(t2, y, p256_mod, p256_mp_mod);
  25420. /* t1 = y ^ 0x3 */
  25421. sp_256_mont_mul_5(t1, t2, y, p256_mod, p256_mp_mod);
  25422. /* t2 = y ^ 0xc */
  25423. sp_256_mont_sqr_n_5(t2, t1, 2, p256_mod, p256_mp_mod);
  25424. /* t1 = y ^ 0xf */
  25425. sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);
  25426. /* t2 = y ^ 0xf0 */
  25427. sp_256_mont_sqr_n_5(t2, t1, 4, p256_mod, p256_mp_mod);
  25428. /* t1 = y ^ 0xff */
  25429. sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);
  25430. /* t2 = y ^ 0xff00 */
  25431. sp_256_mont_sqr_n_5(t2, t1, 8, p256_mod, p256_mp_mod);
  25432. /* t1 = y ^ 0xffff */
  25433. sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);
  25434. /* t2 = y ^ 0xffff0000 */
  25435. sp_256_mont_sqr_n_5(t2, t1, 16, p256_mod, p256_mp_mod);
  25436. /* t1 = y ^ 0xffffffff */
  25437. sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);
  25438. /* t1 = y ^ 0xffffffff00000000 */
  25439. sp_256_mont_sqr_n_5(t1, t1, 32, p256_mod, p256_mp_mod);
  25440. /* t1 = y ^ 0xffffffff00000001 */
  25441. sp_256_mont_mul_5(t1, t1, y, p256_mod, p256_mp_mod);
  25442. /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */
  25443. sp_256_mont_sqr_n_5(t1, t1, 96, p256_mod, p256_mp_mod);
  25444. /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */
  25445. sp_256_mont_mul_5(t1, t1, y, p256_mod, p256_mp_mod);
  25446. sp_256_mont_sqr_n_5(y, t1, 94, p256_mod, p256_mp_mod);
  25447. }
  25448. }
  25449. #ifdef WOLFSSL_SP_SMALL_STACK
  25450. if (t1 != NULL)
  25451. XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
  25452. #endif
  25453. return err;
  25454. }
  25455. /* Uncompress the point given the X ordinate.
  25456. *
  25457. * xm X ordinate.
  25458. * odd Whether the Y ordinate is odd.
  25459. * ym Calculated Y ordinate.
  25460. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  25461. */
  25462. int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym)
  25463. {
  25464. #ifdef WOLFSSL_SP_SMALL_STACK
  25465. sp_digit* x = NULL;
  25466. #else
  25467. sp_digit x[4 * 5];
  25468. #endif
  25469. sp_digit* y = NULL;
  25470. int err = MP_OKAY;
  25471. #ifdef WOLFSSL_SP_SMALL_STACK
  25472. x = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 5, NULL, DYNAMIC_TYPE_ECC);
  25473. if (x == NULL)
  25474. err = MEMORY_E;
  25475. #endif
  25476. if (err == MP_OKAY) {
  25477. y = x + 2 * 5;
  25478. sp_256_from_mp(x, 5, xm);
  25479. err = sp_256_mod_mul_norm_5(x, x, p256_mod);
  25480. }
  25481. if (err == MP_OKAY) {
  25482. /* y = x^3 */
  25483. {
  25484. sp_256_mont_sqr_5(y, x, p256_mod, p256_mp_mod);
  25485. sp_256_mont_mul_5(y, y, x, p256_mod, p256_mp_mod);
  25486. }
  25487. /* y = x^3 - 3x */
  25488. sp_256_mont_sub_5(y, y, x, p256_mod);
  25489. sp_256_mont_sub_5(y, y, x, p256_mod);
  25490. sp_256_mont_sub_5(y, y, x, p256_mod);
  25491. /* y = x^3 - 3x + b */
  25492. err = sp_256_mod_mul_norm_5(x, p256_b, p256_mod);
  25493. }
  25494. if (err == MP_OKAY) {
  25495. sp_256_mont_add_5(y, y, x, p256_mod);
  25496. /* y = sqrt(x^3 - 3x + b) */
  25497. err = sp_256_mont_sqrt_5(y);
  25498. }
  25499. if (err == MP_OKAY) {
  25500. XMEMSET(y + 5, 0, 5U * sizeof(sp_digit));
  25501. sp_256_mont_reduce_5(y, p256_mod, p256_mp_mod);
  25502. if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) {
  25503. sp_256_mont_sub_5(y, p256_mod, y, p256_mod);
  25504. }
  25505. err = sp_256_to_mp(y, ym);
  25506. }
  25507. #ifdef WOLFSSL_SP_SMALL_STACK
  25508. if (x != NULL)
  25509. XFREE(x, NULL, DYNAMIC_TYPE_ECC);
  25510. #endif
  25511. return err;
  25512. }
  25513. #endif
  25514. #endif /* !WOLFSSL_SP_NO_256 */
  25515. #ifdef WOLFSSL_SP_384
  25516. /* Point structure to use. */
  25517. typedef struct sp_point_384 {
  25518. /* X ordinate of point. */
  25519. sp_digit x[2 * 7];
  25520. /* Y ordinate of point. */
  25521. sp_digit y[2 * 7];
  25522. /* Z ordinate of point. */
  25523. sp_digit z[2 * 7];
  25524. /* Indicates point is at infinity. */
  25525. int infinity;
  25526. } sp_point_384;
  25527. /* The modulus (prime) of the curve P384. */
  25528. static const sp_digit p384_mod[7] = {
  25529. 0x000000ffffffffL,0x7ffe0000000000L,0x7ffffffffbffffL,0x7fffffffffffffL,
  25530. 0x7fffffffffffffL,0x7fffffffffffffL,0x3fffffffffffffL
  25531. };
  25532. /* The Montgomery normalizer for modulus of the curve P384. */
  25533. static const sp_digit p384_norm_mod[7] = {
  25534. 0x7fffff00000001L,0x0001ffffffffffL,0x00000000040000L,0x00000000000000L,
  25535. 0x00000000000000L,0x00000000000000L,0x00000000000000L
  25536. };
  25537. /* The Montgomery multiplier for modulus of the curve P384. */
  25538. static sp_digit p384_mp_mod = 0x0000100000001;
  25539. #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
  25540. defined(HAVE_ECC_VERIFY)
  25541. /* The order of the curve P384. */
  25542. static const sp_digit p384_order[7] = {
  25543. 0x6c196accc52973L,0x1b6491614ef5d9L,0x07d0dcb77d6068L,0x7ffffffe3b1a6cL,
  25544. 0x7fffffffffffffL,0x7fffffffffffffL,0x3fffffffffffffL
  25545. };
  25546. #endif
  25547. /* The order of the curve P384 minus 2. */
  25548. static const sp_digit p384_order2[7] = {
  25549. 0x6c196accc52971L,0x1b6491614ef5d9L,0x07d0dcb77d6068L,0x7ffffffe3b1a6cL,
  25550. 0x7fffffffffffffL,0x7fffffffffffffL,0x3fffffffffffffL
  25551. };
  25552. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  25553. /* The Montgomery normalizer for order of the curve P384. */
  25554. static const sp_digit p384_norm_order[7] = {
  25555. 0x13e695333ad68dL,0x649b6e9eb10a26L,0x782f2348829f97L,0x00000001c4e593L,
  25556. 0x00000000000000L,0x00000000000000L,0x00000000000000L
  25557. };
  25558. #endif
  25559. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  25560. /* The Montgomery multiplier for order of the curve P384. */
  25561. static sp_digit p384_mp_order = 0x546089e88fdc45L;
  25562. #endif
  25563. /* The base point of curve P384. */
  25564. static const sp_point_384 p384_base = {
  25565. /* X ordinate */
  25566. {
  25567. 0x545e3872760ab7L,0x64bb7eaa52d874L,0x020950a8e1540bL,0x5d3cdcc2cfba0fL,
  25568. 0x0ad746e1d3b628L,0x26f1d638e3de64L,0x2aa1f288afa2c1L,
  25569. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  25570. (sp_digit)0, (sp_digit)0
  25571. },
  25572. /* Y ordinate */
  25573. {
  25574. 0x431d7c90ea0e5fL,0x639c3afd033af4L,0x4ed7c2e3002982L,0x44d0a3e74ed188L,
  25575. 0x2dc29f8f41dbd2L,0x0debb3d317f252L,0x0d85f792a5898bL,
  25576. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  25577. (sp_digit)0, (sp_digit)0
  25578. },
  25579. /* Z ordinate */
  25580. {
  25581. 0x00000000000001L,0x00000000000000L,0x00000000000000L,0x00000000000000L,
  25582. 0x00000000000000L,0x00000000000000L,0x00000000000000L,
  25583. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  25584. (sp_digit)0, (sp_digit)0
  25585. },
  25586. /* infinity */
  25587. 0
  25588. };
  25589. #if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)
  25590. static const sp_digit p384_b[7] = {
  25591. 0x05c8edd3ec2aefL,0x731b145da33a55L,0x3d404e1d6b1958L,0x740a089018a044L,
  25592. 0x02d19181d9c6efL,0x7c9311c0ad7c7fL,0x2ccc4be9f88fb9L
  25593. };
  25594. #endif
  25595. #ifdef WOLFSSL_SP_SMALL
  25596. /* Multiply a and b into r. (r = a * b)
  25597. *
  25598. * r A single precision integer.
  25599. * a A single precision integer.
  25600. * b A single precision integer.
  25601. */
  25602. SP_NOINLINE static void sp_384_mul_7(sp_digit* r, const sp_digit* a,
  25603. const sp_digit* b)
  25604. {
  25605. int i;
  25606. int imax;
  25607. int k;
  25608. sp_uint128 c;
  25609. sp_uint128 lo;
  25610. c = ((sp_uint128)a[6]) * b[6];
  25611. r[13] = (sp_digit)(c >> 55);
  25612. c &= 0x7fffffffffffffL;
  25613. for (k = 11; k >= 0; k--) {
  25614. if (k >= 7) {
  25615. i = k - 6;
  25616. imax = 6;
  25617. }
  25618. else {
  25619. i = 0;
  25620. imax = k;
  25621. }
  25622. lo = 0;
  25623. for (; i <= imax; i++) {
  25624. lo += ((sp_uint128)a[i]) * b[k - i];
  25625. }
  25626. c += lo >> 55;
  25627. r[k + 2] += (sp_digit)(c >> 55);
  25628. r[k + 1] = (sp_digit)(c & 0x7fffffffffffffL);
  25629. c = lo & 0x7fffffffffffffL;
  25630. }
  25631. r[0] = (sp_digit)c;
  25632. }
  25633. #else
  25634. /* Multiply a and b into r. (r = a * b)
  25635. *
  25636. * r A single precision integer.
  25637. * a A single precision integer.
  25638. * b A single precision integer.
  25639. */
  25640. SP_NOINLINE static void sp_384_mul_7(sp_digit* r, const sp_digit* a,
  25641. const sp_digit* b)
  25642. {
  25643. sp_int128 t0 = ((sp_int128)a[ 0]) * b[ 0];
  25644. sp_int128 t1 = ((sp_int128)a[ 0]) * b[ 1]
  25645. + ((sp_int128)a[ 1]) * b[ 0];
  25646. sp_int128 t2 = ((sp_int128)a[ 0]) * b[ 2]
  25647. + ((sp_int128)a[ 1]) * b[ 1]
  25648. + ((sp_int128)a[ 2]) * b[ 0];
  25649. sp_int128 t3 = ((sp_int128)a[ 0]) * b[ 3]
  25650. + ((sp_int128)a[ 1]) * b[ 2]
  25651. + ((sp_int128)a[ 2]) * b[ 1]
  25652. + ((sp_int128)a[ 3]) * b[ 0];
  25653. sp_int128 t4 = ((sp_int128)a[ 0]) * b[ 4]
  25654. + ((sp_int128)a[ 1]) * b[ 3]
  25655. + ((sp_int128)a[ 2]) * b[ 2]
  25656. + ((sp_int128)a[ 3]) * b[ 1]
  25657. + ((sp_int128)a[ 4]) * b[ 0];
  25658. sp_int128 t5 = ((sp_int128)a[ 0]) * b[ 5]
  25659. + ((sp_int128)a[ 1]) * b[ 4]
  25660. + ((sp_int128)a[ 2]) * b[ 3]
  25661. + ((sp_int128)a[ 3]) * b[ 2]
  25662. + ((sp_int128)a[ 4]) * b[ 1]
  25663. + ((sp_int128)a[ 5]) * b[ 0];
  25664. sp_int128 t6 = ((sp_int128)a[ 0]) * b[ 6]
  25665. + ((sp_int128)a[ 1]) * b[ 5]
  25666. + ((sp_int128)a[ 2]) * b[ 4]
  25667. + ((sp_int128)a[ 3]) * b[ 3]
  25668. + ((sp_int128)a[ 4]) * b[ 2]
  25669. + ((sp_int128)a[ 5]) * b[ 1]
  25670. + ((sp_int128)a[ 6]) * b[ 0];
  25671. sp_int128 t7 = ((sp_int128)a[ 1]) * b[ 6]
  25672. + ((sp_int128)a[ 2]) * b[ 5]
  25673. + ((sp_int128)a[ 3]) * b[ 4]
  25674. + ((sp_int128)a[ 4]) * b[ 3]
  25675. + ((sp_int128)a[ 5]) * b[ 2]
  25676. + ((sp_int128)a[ 6]) * b[ 1];
  25677. sp_int128 t8 = ((sp_int128)a[ 2]) * b[ 6]
  25678. + ((sp_int128)a[ 3]) * b[ 5]
  25679. + ((sp_int128)a[ 4]) * b[ 4]
  25680. + ((sp_int128)a[ 5]) * b[ 3]
  25681. + ((sp_int128)a[ 6]) * b[ 2];
  25682. sp_int128 t9 = ((sp_int128)a[ 3]) * b[ 6]
  25683. + ((sp_int128)a[ 4]) * b[ 5]
  25684. + ((sp_int128)a[ 5]) * b[ 4]
  25685. + ((sp_int128)a[ 6]) * b[ 3];
  25686. sp_int128 t10 = ((sp_int128)a[ 4]) * b[ 6]
  25687. + ((sp_int128)a[ 5]) * b[ 5]
  25688. + ((sp_int128)a[ 6]) * b[ 4];
  25689. sp_int128 t11 = ((sp_int128)a[ 5]) * b[ 6]
  25690. + ((sp_int128)a[ 6]) * b[ 5];
  25691. sp_int128 t12 = ((sp_int128)a[ 6]) * b[ 6];
  25692. t1 += t0 >> 55; r[ 0] = t0 & 0x7fffffffffffffL;
  25693. t2 += t1 >> 55; r[ 1] = t1 & 0x7fffffffffffffL;
  25694. t3 += t2 >> 55; r[ 2] = t2 & 0x7fffffffffffffL;
  25695. t4 += t3 >> 55; r[ 3] = t3 & 0x7fffffffffffffL;
  25696. t5 += t4 >> 55; r[ 4] = t4 & 0x7fffffffffffffL;
  25697. t6 += t5 >> 55; r[ 5] = t5 & 0x7fffffffffffffL;
  25698. t7 += t6 >> 55; r[ 6] = t6 & 0x7fffffffffffffL;
  25699. t8 += t7 >> 55; r[ 7] = t7 & 0x7fffffffffffffL;
  25700. t9 += t8 >> 55; r[ 8] = t8 & 0x7fffffffffffffL;
  25701. t10 += t9 >> 55; r[ 9] = t9 & 0x7fffffffffffffL;
  25702. t11 += t10 >> 55; r[10] = t10 & 0x7fffffffffffffL;
  25703. t12 += t11 >> 55; r[11] = t11 & 0x7fffffffffffffL;
  25704. r[13] = (sp_digit)(t12 >> 55);
  25705. r[12] = t12 & 0x7fffffffffffffL;
  25706. }
  25707. #endif /* WOLFSSL_SP_SMALL */
  25708. #ifdef WOLFSSL_SP_SMALL
  25709. /* Square a and put result in r. (r = a * a)
  25710. *
  25711. * r A single precision integer.
  25712. * a A single precision integer.
  25713. */
  25714. SP_NOINLINE static void sp_384_sqr_7(sp_digit* r, const sp_digit* a)
  25715. {
  25716. int i;
  25717. int imax;
  25718. int k;
  25719. sp_uint128 c;
  25720. sp_uint128 t;
  25721. c = ((sp_uint128)a[6]) * a[6];
  25722. r[13] = (sp_digit)(c >> 55);
  25723. c = (c & 0x7fffffffffffffL) << 55;
  25724. for (k = 11; k >= 0; k--) {
  25725. i = (k + 1) / 2;
  25726. if ((k & 1) == 0) {
  25727. c += ((sp_uint128)a[i]) * a[i];
  25728. i++;
  25729. }
  25730. if (k < 6) {
  25731. imax = k;
  25732. }
  25733. else {
  25734. imax = 6;
  25735. }
  25736. t = 0;
  25737. for (; i <= imax; i++) {
  25738. t += ((sp_uint128)a[i]) * a[k - i];
  25739. }
  25740. c += t * 2;
  25741. r[k + 2] += (sp_digit) (c >> 110);
  25742. r[k + 1] = (sp_digit)((c >> 55) & 0x7fffffffffffffL);
  25743. c = (c & 0x7fffffffffffffL) << 55;
  25744. }
  25745. r[0] = (sp_digit)(c >> 55);
  25746. }
  25747. #else
  25748. /* Square a and put result in r. (r = a * a)
  25749. *
  25750. * r A single precision integer.
  25751. * a A single precision integer.
  25752. */
  25753. SP_NOINLINE static void sp_384_sqr_7(sp_digit* r, const sp_digit* a)
  25754. {
  25755. sp_int128 t0 = ((sp_int128)a[ 0]) * a[ 0];
  25756. sp_int128 t1 = (((sp_int128)a[ 0]) * a[ 1]) * 2;
  25757. sp_int128 t2 = (((sp_int128)a[ 0]) * a[ 2]) * 2
  25758. + ((sp_int128)a[ 1]) * a[ 1];
  25759. sp_int128 t3 = (((sp_int128)a[ 0]) * a[ 3]
  25760. + ((sp_int128)a[ 1]) * a[ 2]) * 2;
  25761. sp_int128 t4 = (((sp_int128)a[ 0]) * a[ 4]
  25762. + ((sp_int128)a[ 1]) * a[ 3]) * 2
  25763. + ((sp_int128)a[ 2]) * a[ 2];
  25764. sp_int128 t5 = (((sp_int128)a[ 0]) * a[ 5]
  25765. + ((sp_int128)a[ 1]) * a[ 4]
  25766. + ((sp_int128)a[ 2]) * a[ 3]) * 2;
  25767. sp_int128 t6 = (((sp_int128)a[ 0]) * a[ 6]
  25768. + ((sp_int128)a[ 1]) * a[ 5]
  25769. + ((sp_int128)a[ 2]) * a[ 4]) * 2
  25770. + ((sp_int128)a[ 3]) * a[ 3];
  25771. sp_int128 t7 = (((sp_int128)a[ 1]) * a[ 6]
  25772. + ((sp_int128)a[ 2]) * a[ 5]
  25773. + ((sp_int128)a[ 3]) * a[ 4]) * 2;
  25774. sp_int128 t8 = (((sp_int128)a[ 2]) * a[ 6]
  25775. + ((sp_int128)a[ 3]) * a[ 5]) * 2
  25776. + ((sp_int128)a[ 4]) * a[ 4];
  25777. sp_int128 t9 = (((sp_int128)a[ 3]) * a[ 6]
  25778. + ((sp_int128)a[ 4]) * a[ 5]) * 2;
  25779. sp_int128 t10 = (((sp_int128)a[ 4]) * a[ 6]) * 2
  25780. + ((sp_int128)a[ 5]) * a[ 5];
  25781. sp_int128 t11 = (((sp_int128)a[ 5]) * a[ 6]) * 2;
  25782. sp_int128 t12 = ((sp_int128)a[ 6]) * a[ 6];
  25783. t1 += t0 >> 55; r[ 0] = t0 & 0x7fffffffffffffL;
  25784. t2 += t1 >> 55; r[ 1] = t1 & 0x7fffffffffffffL;
  25785. t3 += t2 >> 55; r[ 2] = t2 & 0x7fffffffffffffL;
  25786. t4 += t3 >> 55; r[ 3] = t3 & 0x7fffffffffffffL;
  25787. t5 += t4 >> 55; r[ 4] = t4 & 0x7fffffffffffffL;
  25788. t6 += t5 >> 55; r[ 5] = t5 & 0x7fffffffffffffL;
  25789. t7 += t6 >> 55; r[ 6] = t6 & 0x7fffffffffffffL;
  25790. t8 += t7 >> 55; r[ 7] = t7 & 0x7fffffffffffffL;
  25791. t9 += t8 >> 55; r[ 8] = t8 & 0x7fffffffffffffL;
  25792. t10 += t9 >> 55; r[ 9] = t9 & 0x7fffffffffffffL;
  25793. t11 += t10 >> 55; r[10] = t10 & 0x7fffffffffffffL;
  25794. t12 += t11 >> 55; r[11] = t11 & 0x7fffffffffffffL;
  25795. r[13] = (sp_digit)(t12 >> 55);
  25796. r[12] = t12 & 0x7fffffffffffffL;
  25797. }
  25798. #endif /* WOLFSSL_SP_SMALL */
  25799. #ifdef WOLFSSL_SP_SMALL
  25800. /* Add b to a into r. (r = a + b)
  25801. *
  25802. * r A single precision integer.
  25803. * a A single precision integer.
  25804. * b A single precision integer.
  25805. */
  25806. SP_NOINLINE static int sp_384_add_7(sp_digit* r, const sp_digit* a,
  25807. const sp_digit* b)
  25808. {
  25809. int i;
  25810. for (i = 0; i < 7; i++) {
  25811. r[i] = a[i] + b[i];
  25812. }
  25813. return 0;
  25814. }
  25815. #else
  25816. /* Add b to a into r. (r = a + b)
  25817. *
  25818. * r A single precision integer.
  25819. * a A single precision integer.
  25820. * b A single precision integer.
  25821. */
  25822. SP_NOINLINE static int sp_384_add_7(sp_digit* r, const sp_digit* a,
  25823. const sp_digit* b)
  25824. {
  25825. r[ 0] = a[ 0] + b[ 0];
  25826. r[ 1] = a[ 1] + b[ 1];
  25827. r[ 2] = a[ 2] + b[ 2];
  25828. r[ 3] = a[ 3] + b[ 3];
  25829. r[ 4] = a[ 4] + b[ 4];
  25830. r[ 5] = a[ 5] + b[ 5];
  25831. r[ 6] = a[ 6] + b[ 6];
  25832. return 0;
  25833. }
  25834. #endif /* WOLFSSL_SP_SMALL */
  25835. #ifdef WOLFSSL_SP_SMALL
  25836. /* Sub b from a into r. (r = a - b)
  25837. *
  25838. * r A single precision integer.
  25839. * a A single precision integer.
  25840. * b A single precision integer.
  25841. */
  25842. SP_NOINLINE static int sp_384_sub_7(sp_digit* r, const sp_digit* a,
  25843. const sp_digit* b)
  25844. {
  25845. int i;
  25846. for (i = 0; i < 7; i++) {
  25847. r[i] = a[i] - b[i];
  25848. }
  25849. return 0;
  25850. }
  25851. #else
  25852. /* Sub b from a into r. (r = a - b)
  25853. *
  25854. * r A single precision integer.
  25855. * a A single precision integer.
  25856. * b A single precision integer.
  25857. */
  25858. SP_NOINLINE static int sp_384_sub_7(sp_digit* r, const sp_digit* a,
  25859. const sp_digit* b)
  25860. {
  25861. r[ 0] = a[ 0] - b[ 0];
  25862. r[ 1] = a[ 1] - b[ 1];
  25863. r[ 2] = a[ 2] - b[ 2];
  25864. r[ 3] = a[ 3] - b[ 3];
  25865. r[ 4] = a[ 4] - b[ 4];
  25866. r[ 5] = a[ 5] - b[ 5];
  25867. r[ 6] = a[ 6] - b[ 6];
  25868. return 0;
  25869. }
  25870. #endif /* WOLFSSL_SP_SMALL */
  25871. /* Convert an mp_int to an array of sp_digit.
  25872. *
  25873. * r A single precision integer.
  25874. * size Maximum number of bytes to convert
  25875. * a A multi-precision integer.
  25876. */
  25877. static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a)
  25878. {
  25879. #if DIGIT_BIT == 55
  25880. int i;
  25881. sp_digit j = (sp_digit)0 - (sp_digit)a->used;
  25882. int o = 0;
  25883. for (i = 0; i < size; i++) {
  25884. sp_digit mask = (sp_digit)0 - (j >> 54);
  25885. r[i] = a->dp[o] & mask;
  25886. j++;
  25887. o += (int)(j >> 54);
  25888. }
  25889. #elif DIGIT_BIT > 55
  25890. unsigned int i;
  25891. int j = 0;
  25892. word32 s = 0;
  25893. r[0] = 0;
  25894. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  25895. r[j] |= ((sp_digit)a->dp[i] << s);
  25896. r[j] &= 0x7fffffffffffffL;
  25897. s = 55U - s;
  25898. if (j + 1 >= size) {
  25899. break;
  25900. }
  25901. /* lint allow cast of mismatch word32 and mp_digit */
  25902. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  25903. while ((s + 55U) <= (word32)DIGIT_BIT) {
  25904. s += 55U;
  25905. r[j] &= 0x7fffffffffffffL;
  25906. if (j + 1 >= size) {
  25907. break;
  25908. }
  25909. if (s < (word32)DIGIT_BIT) {
  25910. /* lint allow cast of mismatch word32 and mp_digit */
  25911. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  25912. }
  25913. else {
  25914. r[++j] = (sp_digit)0;
  25915. }
  25916. }
  25917. s = (word32)DIGIT_BIT - s;
  25918. }
  25919. for (j++; j < size; j++) {
  25920. r[j] = 0;
  25921. }
  25922. #else
  25923. unsigned int i;
  25924. int j = 0;
  25925. int s = 0;
  25926. r[0] = 0;
  25927. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  25928. r[j] |= ((sp_digit)a->dp[i]) << s;
  25929. if (s + DIGIT_BIT >= 55) {
  25930. r[j] &= 0x7fffffffffffffL;
  25931. if (j + 1 >= size) {
  25932. break;
  25933. }
  25934. s = 55 - s;
  25935. if (s == DIGIT_BIT) {
  25936. r[++j] = 0;
  25937. s = 0;
  25938. }
  25939. else {
  25940. r[++j] = a->dp[i] >> s;
  25941. s = DIGIT_BIT - s;
  25942. }
  25943. }
  25944. else {
  25945. s += DIGIT_BIT;
  25946. }
  25947. }
  25948. for (j++; j < size; j++) {
  25949. r[j] = 0;
  25950. }
  25951. #endif
  25952. }
  25953. /* Convert a point of type ecc_point to type sp_point_384.
  25954. *
  25955. * p Point of type sp_point_384 (result).
  25956. * pm Point of type ecc_point.
  25957. */
  25958. static void sp_384_point_from_ecc_point_7(sp_point_384* p,
  25959. const ecc_point* pm)
  25960. {
  25961. XMEMSET(p->x, 0, sizeof(p->x));
  25962. XMEMSET(p->y, 0, sizeof(p->y));
  25963. XMEMSET(p->z, 0, sizeof(p->z));
  25964. sp_384_from_mp(p->x, 7, pm->x);
  25965. sp_384_from_mp(p->y, 7, pm->y);
  25966. sp_384_from_mp(p->z, 7, pm->z);
  25967. p->infinity = 0;
  25968. }
  25969. /* Convert an array of sp_digit to an mp_int.
  25970. *
  25971. * a A single precision integer.
  25972. * r A multi-precision integer.
  25973. */
  25974. static int sp_384_to_mp(const sp_digit* a, mp_int* r)
  25975. {
  25976. int err;
  25977. err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT);
  25978. if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
  25979. #if DIGIT_BIT == 55
  25980. XMEMCPY(r->dp, a, sizeof(sp_digit) * 7);
  25981. r->used = 7;
  25982. mp_clamp(r);
  25983. #elif DIGIT_BIT < 55
  25984. int i;
  25985. int j = 0;
  25986. int s = 0;
  25987. r->dp[0] = 0;
  25988. for (i = 0; i < 7; i++) {
  25989. r->dp[j] |= (mp_digit)(a[i] << s);
  25990. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  25991. s = DIGIT_BIT - s;
  25992. r->dp[++j] = (mp_digit)(a[i] >> s);
  25993. while (s + DIGIT_BIT <= 55) {
  25994. s += DIGIT_BIT;
  25995. r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  25996. if (s == SP_WORD_SIZE) {
  25997. r->dp[j] = 0;
  25998. }
  25999. else {
  26000. r->dp[j] = (mp_digit)(a[i] >> s);
  26001. }
  26002. }
  26003. s = 55 - s;
  26004. }
  26005. r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT;
  26006. mp_clamp(r);
  26007. #else
  26008. int i;
  26009. int j = 0;
  26010. int s = 0;
  26011. r->dp[0] = 0;
  26012. for (i = 0; i < 7; i++) {
  26013. r->dp[j] |= ((mp_digit)a[i]) << s;
  26014. if (s + 55 >= DIGIT_BIT) {
  26015. #if DIGIT_BIT != 32 && DIGIT_BIT != 64
  26016. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  26017. #endif
  26018. s = DIGIT_BIT - s;
  26019. r->dp[++j] = a[i] >> s;
  26020. s = 55 - s;
  26021. }
  26022. else {
  26023. s += 55;
  26024. }
  26025. }
  26026. r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT;
  26027. mp_clamp(r);
  26028. #endif
  26029. }
  26030. return err;
  26031. }
  26032. /* Convert a point of type sp_point_384 to type ecc_point.
  26033. *
  26034. * p Point of type sp_point_384.
  26035. * pm Point of type ecc_point (result).
  26036. * returns MEMORY_E when allocation of memory in ecc_point fails otherwise
  26037. * MP_OKAY.
  26038. */
  26039. static int sp_384_point_to_ecc_point_7(const sp_point_384* p, ecc_point* pm)
  26040. {
  26041. int err;
  26042. err = sp_384_to_mp(p->x, pm->x);
  26043. if (err == MP_OKAY) {
  26044. err = sp_384_to_mp(p->y, pm->y);
  26045. }
  26046. if (err == MP_OKAY) {
  26047. err = sp_384_to_mp(p->z, pm->z);
  26048. }
  26049. return err;
  26050. }
  26051. /* Compare a with b in constant time.
  26052. *
  26053. * a A single precision integer.
  26054. * b A single precision integer.
  26055. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  26056. * respectively.
  26057. */
  26058. static sp_digit sp_384_cmp_7(const sp_digit* a, const sp_digit* b)
  26059. {
  26060. sp_digit r = 0;
  26061. #ifdef WOLFSSL_SP_SMALL
  26062. int i;
  26063. for (i=6; i>=0; i--) {
  26064. r |= (a[i] - b[i]) & ~(((sp_digit)0 - r) >> 54);
  26065. }
  26066. #else
  26067. r |= (a[ 6] - b[ 6]) & (0 - (sp_digit)1);
  26068. r |= (a[ 5] - b[ 5]) & ~(((sp_digit)0 - r) >> 54);
  26069. r |= (a[ 4] - b[ 4]) & ~(((sp_digit)0 - r) >> 54);
  26070. r |= (a[ 3] - b[ 3]) & ~(((sp_digit)0 - r) >> 54);
  26071. r |= (a[ 2] - b[ 2]) & ~(((sp_digit)0 - r) >> 54);
  26072. r |= (a[ 1] - b[ 1]) & ~(((sp_digit)0 - r) >> 54);
  26073. r |= (a[ 0] - b[ 0]) & ~(((sp_digit)0 - r) >> 54);
  26074. #endif /* WOLFSSL_SP_SMALL */
  26075. return r;
  26076. }
  26077. /* Conditionally subtract b from a using the mask m.
  26078. * m is -1 to subtract and 0 when not.
  26079. *
  26080. * r A single precision number representing condition subtract result.
  26081. * a A single precision number to subtract from.
  26082. * b A single precision number to subtract.
  26083. * m Mask value to apply.
  26084. */
  26085. static void sp_384_cond_sub_7(sp_digit* r, const sp_digit* a,
  26086. const sp_digit* b, const sp_digit m)
  26087. {
  26088. #ifdef WOLFSSL_SP_SMALL
  26089. int i;
  26090. for (i = 0; i < 7; i++) {
  26091. r[i] = a[i] - (b[i] & m);
  26092. }
  26093. #else
  26094. r[ 0] = a[ 0] - (b[ 0] & m);
  26095. r[ 1] = a[ 1] - (b[ 1] & m);
  26096. r[ 2] = a[ 2] - (b[ 2] & m);
  26097. r[ 3] = a[ 3] - (b[ 3] & m);
  26098. r[ 4] = a[ 4] - (b[ 4] & m);
  26099. r[ 5] = a[ 5] - (b[ 5] & m);
  26100. r[ 6] = a[ 6] - (b[ 6] & m);
  26101. #endif /* WOLFSSL_SP_SMALL */
  26102. }
  26103. /* Mul a by scalar b and add into r. (r += a * b)
  26104. *
  26105. * r A single precision integer.
  26106. * a A single precision integer.
  26107. * b A scalar.
  26108. */
  26109. SP_NOINLINE static void sp_384_mul_add_7(sp_digit* r, const sp_digit* a,
  26110. const sp_digit b)
  26111. {
  26112. #ifdef WOLFSSL_SP_SMALL
  26113. sp_int128 tb = b;
  26114. sp_int128 t[4];
  26115. int i;
  26116. t[0] = 0;
  26117. for (i = 0; i < 4; i += 4) {
  26118. t[0] += (tb * a[i+0]) + r[i+0];
  26119. t[1] = (tb * a[i+1]) + r[i+1];
  26120. t[2] = (tb * a[i+2]) + r[i+2];
  26121. t[3] = (tb * a[i+3]) + r[i+3];
  26122. r[i+0] = t[0] & 0x7fffffffffffffL;
  26123. t[1] += t[0] >> 55;
  26124. r[i+1] = t[1] & 0x7fffffffffffffL;
  26125. t[2] += t[1] >> 55;
  26126. r[i+2] = t[2] & 0x7fffffffffffffL;
  26127. t[3] += t[2] >> 55;
  26128. r[i+3] = t[3] & 0x7fffffffffffffL;
  26129. t[0] = t[3] >> 55;
  26130. }
  26131. t[0] += (tb * a[4]) + r[4];
  26132. t[1] = (tb * a[5]) + r[5];
  26133. t[2] = (tb * a[6]) + r[6];
  26134. r[4] = t[0] & 0x7fffffffffffffL;
  26135. t[1] += t[0] >> 55;
  26136. r[5] = t[1] & 0x7fffffffffffffL;
  26137. t[2] += t[1] >> 55;
  26138. r[6] = t[2] & 0x7fffffffffffffL;
  26139. r[7] += (sp_digit)(t[2] >> 55);
  26140. #else
  26141. sp_int128 tb = b;
  26142. sp_int128 t[7];
  26143. t[ 0] = tb * a[ 0];
  26144. t[ 1] = tb * a[ 1];
  26145. t[ 2] = tb * a[ 2];
  26146. t[ 3] = tb * a[ 3];
  26147. t[ 4] = tb * a[ 4];
  26148. t[ 5] = tb * a[ 5];
  26149. t[ 6] = tb * a[ 6];
  26150. r[ 0] += (sp_digit) (t[ 0] & 0x7fffffffffffffL);
  26151. r[ 1] += (sp_digit)((t[ 0] >> 55) + (t[ 1] & 0x7fffffffffffffL));
  26152. r[ 2] += (sp_digit)((t[ 1] >> 55) + (t[ 2] & 0x7fffffffffffffL));
  26153. r[ 3] += (sp_digit)((t[ 2] >> 55) + (t[ 3] & 0x7fffffffffffffL));
  26154. r[ 4] += (sp_digit)((t[ 3] >> 55) + (t[ 4] & 0x7fffffffffffffL));
  26155. r[ 5] += (sp_digit)((t[ 4] >> 55) + (t[ 5] & 0x7fffffffffffffL));
  26156. r[ 6] += (sp_digit)((t[ 5] >> 55) + (t[ 6] & 0x7fffffffffffffL));
  26157. r[ 7] += (sp_digit) (t[ 6] >> 55);
  26158. #endif /* WOLFSSL_SP_SMALL */
  26159. }
  26160. /* Normalize the values in each word to 55 bits.
  26161. *
  26162. * a Array of sp_digit to normalize.
  26163. */
  26164. static void sp_384_norm_7(sp_digit* a)
  26165. {
  26166. #ifdef WOLFSSL_SP_SMALL
  26167. int i;
  26168. for (i = 0; i < 6; i++) {
  26169. a[i+1] += a[i] >> 55;
  26170. a[i] &= 0x7fffffffffffffL;
  26171. }
  26172. #else
  26173. a[1] += a[0] >> 55; a[0] &= 0x7fffffffffffffL;
  26174. a[2] += a[1] >> 55; a[1] &= 0x7fffffffffffffL;
  26175. a[3] += a[2] >> 55; a[2] &= 0x7fffffffffffffL;
  26176. a[4] += a[3] >> 55; a[3] &= 0x7fffffffffffffL;
  26177. a[5] += a[4] >> 55; a[4] &= 0x7fffffffffffffL;
  26178. a[6] += a[5] >> 55; a[5] &= 0x7fffffffffffffL;
  26179. #endif /* WOLFSSL_SP_SMALL */
  26180. }
  26181. /* Shift the result in the high 384 bits down to the bottom.
  26182. *
  26183. * r A single precision number.
  26184. * a A single precision number.
  26185. */
  26186. static void sp_384_mont_shift_7(sp_digit* r, const sp_digit* a)
  26187. {
  26188. #ifdef WOLFSSL_SP_SMALL
  26189. int i;
  26190. sp_uint64 n;
  26191. n = a[6] >> 54;
  26192. for (i = 0; i < 6; i++) {
  26193. n += (sp_uint64)a[7 + i] << 1;
  26194. r[i] = n & 0x7fffffffffffffL;
  26195. n >>= 55;
  26196. }
  26197. n += (sp_uint64)a[13] << 1;
  26198. r[6] = n;
  26199. #else
  26200. sp_uint64 n;
  26201. n = a[6] >> 54;
  26202. n += (sp_uint64)a[ 7] << 1U; r[ 0] = n & 0x7fffffffffffffUL; n >>= 55U;
  26203. n += (sp_uint64)a[ 8] << 1U; r[ 1] = n & 0x7fffffffffffffUL; n >>= 55U;
  26204. n += (sp_uint64)a[ 9] << 1U; r[ 2] = n & 0x7fffffffffffffUL; n >>= 55U;
  26205. n += (sp_uint64)a[10] << 1U; r[ 3] = n & 0x7fffffffffffffUL; n >>= 55U;
  26206. n += (sp_uint64)a[11] << 1U; r[ 4] = n & 0x7fffffffffffffUL; n >>= 55U;
  26207. n += (sp_uint64)a[12] << 1U; r[ 5] = n & 0x7fffffffffffffUL; n >>= 55U;
  26208. n += (sp_uint64)a[13] << 1U; r[ 6] = n;
  26209. #endif /* WOLFSSL_SP_SMALL */
  26210. XMEMSET(&r[7], 0, sizeof(*r) * 7U);
  26211. }
  26212. /* Reduce the number back to 384 bits using Montgomery reduction.
  26213. *
  26214. * a A single precision number to reduce in place.
  26215. * m The single precision number representing the modulus.
  26216. * mp The digit representing the negative inverse of m mod 2^n.
  26217. */
  26218. static void sp_384_mont_reduce_order_7(sp_digit* a, const sp_digit* m, sp_digit mp)
  26219. {
  26220. int i;
  26221. sp_digit mu;
  26222. sp_digit over;
  26223. sp_384_norm_7(a + 7);
  26224. for (i=0; i<6; i++) {
  26225. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x7fffffffffffffL;
  26226. sp_384_mul_add_7(a+i, m, mu);
  26227. a[i+1] += a[i] >> 55;
  26228. }
  26229. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x3fffffffffffffL;
  26230. sp_384_mul_add_7(a+i, m, mu);
  26231. a[i+1] += a[i] >> 55;
  26232. a[i] &= 0x7fffffffffffffL;
  26233. sp_384_mont_shift_7(a, a);
  26234. over = a[6] >> 54;
  26235. sp_384_cond_sub_7(a, a, m, ~((over - 1) >> 63));
  26236. sp_384_norm_7(a);
  26237. }
  26238. /* Reduce the number back to 384 bits using Montgomery reduction.
  26239. *
  26240. * a A single precision number to reduce in place.
  26241. * m The single precision number representing the modulus.
  26242. * mp The digit representing the negative inverse of m mod 2^n.
  26243. */
  26244. static void sp_384_mont_reduce_7(sp_digit* a, const sp_digit* m, sp_digit mp)
  26245. {
  26246. int i;
  26247. sp_digit am;
  26248. (void)m;
  26249. (void)mp;
  26250. for (i = 0; i < 6; i++) {
  26251. am = (a[i] * 0x100000001) & 0x7fffffffffffffL;
  26252. a[i + 0] += (am << 32) & 0x7fffffffffffffL;
  26253. a[i + 1] += (am >> 23) - ((am << 41) & 0x7fffffffffffffL);
  26254. a[i + 2] += -(am >> 14) - ((am << 18) & 0x7fffffffffffffL);
  26255. a[i + 3] += -(am >> 37);
  26256. a[i + 6] += (am << 54) & 0x7fffffffffffffL;
  26257. a[i + 7] += am >> 1;
  26258. a[i + 1] += a[i] >> 55;
  26259. }
  26260. am = (a[6] * 0x100000001) & 0x3fffffffffffff;
  26261. a[6 + 0] += (am << 32) & 0x7fffffffffffffL;
  26262. a[6 + 1] += (am >> 23) - ((am << 41) & 0x7fffffffffffffL);
  26263. a[6 + 2] += -(am >> 14) - ((am << 18) & 0x7fffffffffffffL);
  26264. a[6 + 3] += -(am >> 37);
  26265. a[6 + 6] += (am << 54) & 0x7fffffffffffffL;
  26266. a[6 + 7] += am >> 1;
  26267. a[0] = (a[6] >> 54) + ((a[7] << 1) & 0x7fffffffffffffL);
  26268. a[1] = (a[7] >> 54) + ((a[8] << 1) & 0x7fffffffffffffL);
  26269. a[2] = (a[8] >> 54) + ((a[9] << 1) & 0x7fffffffffffffL);
  26270. a[3] = (a[9] >> 54) + ((a[10] << 1) & 0x7fffffffffffffL);
  26271. a[4] = (a[10] >> 54) + ((a[11] << 1) & 0x7fffffffffffffL);
  26272. a[5] = (a[11] >> 54) + ((a[12] << 1) & 0x7fffffffffffffL);
  26273. a[6] = (a[12] >> 54) + (a[13] << 1);
  26274. a[1] += a[0] >> 55; a[0] &= 0x7fffffffffffffL;
  26275. a[2] += a[1] >> 55; a[1] &= 0x7fffffffffffffL;
  26276. a[3] += a[2] >> 55; a[2] &= 0x7fffffffffffffL;
  26277. a[4] += a[3] >> 55; a[3] &= 0x7fffffffffffffL;
  26278. a[5] += a[4] >> 55; a[4] &= 0x7fffffffffffffL;
  26279. a[6] += a[5] >> 55; a[5] &= 0x7fffffffffffffL;
  26280. /* Get the bit over, if any. */
  26281. am = a[6] >> 54;
  26282. /* Create mask. */
  26283. am = 0 - am;
  26284. a[0] -= 0x00000000ffffffffL & am;
  26285. a[1] -= 0x007ffe0000000000L & am;
  26286. a[2] -= 0x007ffffffffbffffL & am;
  26287. a[3] -= 0x007fffffffffffffL & am;
  26288. a[4] -= 0x007fffffffffffffL & am;
  26289. a[5] -= 0x007fffffffffffffL & am;
  26290. a[6] -= 0x003fffffffffffffL & am;
  26291. a[1] += a[0] >> 55; a[0] &= 0x7fffffffffffffL;
  26292. a[2] += a[1] >> 55; a[1] &= 0x7fffffffffffffL;
  26293. a[3] += a[2] >> 55; a[2] &= 0x7fffffffffffffL;
  26294. a[4] += a[3] >> 55; a[3] &= 0x7fffffffffffffL;
  26295. a[5] += a[4] >> 55; a[4] &= 0x7fffffffffffffL;
  26296. a[6] += a[5] >> 55; a[5] &= 0x7fffffffffffffL;
  26297. }
  26298. /* Multiply two Montgomery form numbers mod the modulus (prime).
  26299. * (r = a * b mod m)
  26300. *
  26301. * r Result of multiplication.
  26302. * a First number to multiply in Montgomery form.
  26303. * b Second number to multiply in Montgomery form.
  26304. * m Modulus (prime).
  26305. * mp Montgomery multiplier.
  26306. */
  26307. SP_NOINLINE static void sp_384_mont_mul_7(sp_digit* r, const sp_digit* a,
  26308. const sp_digit* b, const sp_digit* m, sp_digit mp)
  26309. {
  26310. sp_384_mul_7(r, a, b);
  26311. sp_384_mont_reduce_7(r, m, mp);
  26312. }
  26313. /* Square the Montgomery form number. (r = a * a mod m)
  26314. *
  26315. * r Result of squaring.
  26316. * a Number to square in Montgomery form.
  26317. * m Modulus (prime).
  26318. * mp Montgomery multiplier.
  26319. */
  26320. SP_NOINLINE static void sp_384_mont_sqr_7(sp_digit* r, const sp_digit* a,
  26321. const sp_digit* m, sp_digit mp)
  26322. {
  26323. sp_384_sqr_7(r, a);
  26324. sp_384_mont_reduce_7(r, m, mp);
  26325. }
  26326. #if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY)
  26327. /* Square the Montgomery form number a number of times. (r = a ^ n mod m)
  26328. *
  26329. * r Result of squaring.
  26330. * a Number to square in Montgomery form.
  26331. * n Number of times to square.
  26332. * m Modulus (prime).
  26333. * mp Montgomery multiplier.
  26334. */
  26335. SP_NOINLINE static void sp_384_mont_sqr_n_7(sp_digit* r,
  26336. const sp_digit* a, int n, const sp_digit* m, sp_digit mp)
  26337. {
  26338. sp_384_mont_sqr_7(r, a, m, mp);
  26339. for (; n > 1; n--) {
  26340. sp_384_mont_sqr_7(r, r, m, mp);
  26341. }
  26342. }
  26343. #endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */
  26344. #ifdef WOLFSSL_SP_SMALL
  26345. /* Mod-2 for the P384 curve. */
  26346. static const uint64_t p384_mod_minus_2[6] = {
  26347. 0x00000000fffffffdU,0xffffffff00000000U,0xfffffffffffffffeU,
  26348. 0xffffffffffffffffU,0xffffffffffffffffU,0xffffffffffffffffU
  26349. };
  26350. #endif /* !WOLFSSL_SP_SMALL */
  26351. /* Invert the number, in Montgomery form, modulo the modulus (prime) of the
  26352. * P384 curve. (r = 1 / a mod m)
  26353. *
  26354. * r Inverse result.
  26355. * a Number to invert.
  26356. * td Temporary data.
  26357. */
  26358. static void sp_384_mont_inv_7(sp_digit* r, const sp_digit* a, sp_digit* td)
  26359. {
  26360. #ifdef WOLFSSL_SP_SMALL
  26361. sp_digit* t = td;
  26362. int i;
  26363. XMEMCPY(t, a, sizeof(sp_digit) * 7);
  26364. for (i=382; i>=0; i--) {
  26365. sp_384_mont_sqr_7(t, t, p384_mod, p384_mp_mod);
  26366. if (p384_mod_minus_2[i / 64] & ((sp_digit)1 << (i % 64)))
  26367. sp_384_mont_mul_7(t, t, a, p384_mod, p384_mp_mod);
  26368. }
  26369. XMEMCPY(r, t, sizeof(sp_digit) * 7);
  26370. #else
  26371. sp_digit* t1 = td;
  26372. sp_digit* t2 = td + 2 * 7;
  26373. sp_digit* t3 = td + 4 * 7;
  26374. sp_digit* t4 = td + 6 * 7;
  26375. sp_digit* t5 = td + 8 * 7;
  26376. /* 0x2 */
  26377. sp_384_mont_sqr_7(t1, a, p384_mod, p384_mp_mod);
  26378. /* 0x3 */
  26379. sp_384_mont_mul_7(t5, t1, a, p384_mod, p384_mp_mod);
  26380. /* 0xc */
  26381. sp_384_mont_sqr_n_7(t1, t5, 2, p384_mod, p384_mp_mod);
  26382. /* 0xf */
  26383. sp_384_mont_mul_7(t2, t5, t1, p384_mod, p384_mp_mod);
  26384. /* 0x1e */
  26385. sp_384_mont_sqr_7(t1, t2, p384_mod, p384_mp_mod);
  26386. /* 0x1f */
  26387. sp_384_mont_mul_7(t4, t1, a, p384_mod, p384_mp_mod);
  26388. /* 0x3e0 */
  26389. sp_384_mont_sqr_n_7(t1, t4, 5, p384_mod, p384_mp_mod);
  26390. /* 0x3ff */
  26391. sp_384_mont_mul_7(t2, t4, t1, p384_mod, p384_mp_mod);
  26392. /* 0x7fe0 */
  26393. sp_384_mont_sqr_n_7(t1, t2, 5, p384_mod, p384_mp_mod);
  26394. /* 0x7fff */
  26395. sp_384_mont_mul_7(t4, t4, t1, p384_mod, p384_mp_mod);
  26396. /* 0x3fff8000 */
  26397. sp_384_mont_sqr_n_7(t1, t4, 15, p384_mod, p384_mp_mod);
  26398. /* 0x3fffffff */
  26399. sp_384_mont_mul_7(t2, t4, t1, p384_mod, p384_mp_mod);
  26400. /* 0xfffffffc */
  26401. sp_384_mont_sqr_n_7(t3, t2, 2, p384_mod, p384_mp_mod);
  26402. /* 0xfffffffd */
  26403. sp_384_mont_mul_7(r, t3, a, p384_mod, p384_mp_mod);
  26404. /* 0xffffffff */
  26405. sp_384_mont_mul_7(t3, t5, t3, p384_mod, p384_mp_mod);
  26406. /* 0xfffffffc0000000 */
  26407. sp_384_mont_sqr_n_7(t1, t2, 30, p384_mod, p384_mp_mod);
  26408. /* 0xfffffffffffffff */
  26409. sp_384_mont_mul_7(t2, t2, t1, p384_mod, p384_mp_mod);
  26410. /* 0xfffffffffffffff000000000000000 */
  26411. sp_384_mont_sqr_n_7(t1, t2, 60, p384_mod, p384_mp_mod);
  26412. /* 0xffffffffffffffffffffffffffffff */
  26413. sp_384_mont_mul_7(t2, t2, t1, p384_mod, p384_mp_mod);
  26414. /* 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */
  26415. sp_384_mont_sqr_n_7(t1, t2, 120, p384_mod, p384_mp_mod);
  26416. /* 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
  26417. sp_384_mont_mul_7(t2, t2, t1, p384_mod, p384_mp_mod);
  26418. /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */
  26419. sp_384_mont_sqr_n_7(t1, t2, 15, p384_mod, p384_mp_mod);
  26420. /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
  26421. sp_384_mont_mul_7(t2, t4, t1, p384_mod, p384_mp_mod);
  26422. /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000 */
  26423. sp_384_mont_sqr_n_7(t1, t2, 33, p384_mod, p384_mp_mod);
  26424. /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff */
  26425. sp_384_mont_mul_7(t2, t3, t1, p384_mod, p384_mp_mod);
  26426. /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000000000000 */
  26427. sp_384_mont_sqr_n_7(t1, t2, 96, p384_mod, p384_mp_mod);
  26428. /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffd */
  26429. sp_384_mont_mul_7(r, r, t1, p384_mod, p384_mp_mod);
  26430. #endif /* WOLFSSL_SP_SMALL */
  26431. }
  26432. /* Map the Montgomery form projective coordinate point to an affine point.
  26433. *
  26434. * r Resulting affine coordinate point.
  26435. * p Montgomery form projective coordinate point.
  26436. * t Temporary ordinate data.
  26437. */
  26438. static void sp_384_map_7(sp_point_384* r, const sp_point_384* p,
  26439. sp_digit* t)
  26440. {
  26441. sp_digit* t1 = t;
  26442. sp_digit* t2 = t + 2*7;
  26443. sp_int64 n;
  26444. sp_384_mont_inv_7(t1, p->z, t + 2*7);
  26445. sp_384_mont_sqr_7(t2, t1, p384_mod, p384_mp_mod);
  26446. sp_384_mont_mul_7(t1, t2, t1, p384_mod, p384_mp_mod);
  26447. /* x /= z^2 */
  26448. sp_384_mont_mul_7(r->x, p->x, t2, p384_mod, p384_mp_mod);
  26449. XMEMSET(r->x + 7, 0, sizeof(sp_digit) * 7U);
  26450. sp_384_mont_reduce_7(r->x, p384_mod, p384_mp_mod);
  26451. /* Reduce x to less than modulus */
  26452. n = sp_384_cmp_7(r->x, p384_mod);
  26453. sp_384_cond_sub_7(r->x, r->x, p384_mod, ~(n >> 54));
  26454. sp_384_norm_7(r->x);
  26455. /* y /= z^3 */
  26456. sp_384_mont_mul_7(r->y, p->y, t1, p384_mod, p384_mp_mod);
  26457. XMEMSET(r->y + 7, 0, sizeof(sp_digit) * 7U);
  26458. sp_384_mont_reduce_7(r->y, p384_mod, p384_mp_mod);
  26459. /* Reduce y to less than modulus */
  26460. n = sp_384_cmp_7(r->y, p384_mod);
  26461. sp_384_cond_sub_7(r->y, r->y, p384_mod, ~(n >> 54));
  26462. sp_384_norm_7(r->y);
  26463. XMEMSET(r->z, 0, sizeof(r->z) / 2);
  26464. r->z[0] = 1;
  26465. }
  26466. /* Add two Montgomery form numbers (r = a + b % m).
  26467. *
  26468. * r Result of addition.
  26469. * a First number to add in Montgomery form.
  26470. * b Second number to add in Montgomery form.
  26471. * m Modulus (prime).
  26472. */
  26473. static void sp_384_mont_add_7(sp_digit* r, const sp_digit* a, const sp_digit* b,
  26474. const sp_digit* m)
  26475. {
  26476. sp_digit over;
  26477. (void)sp_384_add_7(r, a, b);
  26478. sp_384_norm_7(r);
  26479. over = r[6] >> 54;
  26480. sp_384_cond_sub_7(r, r, m, ~((over - 1) >> 63));
  26481. sp_384_norm_7(r);
  26482. }
  26483. /* Double a Montgomery form number (r = a + a % m).
  26484. *
  26485. * r Result of doubling.
  26486. * a Number to double in Montgomery form.
  26487. * m Modulus (prime).
  26488. */
  26489. static void sp_384_mont_dbl_7(sp_digit* r, const sp_digit* a, const sp_digit* m)
  26490. {
  26491. sp_digit over;
  26492. (void)sp_384_add_7(r, a, a);
  26493. sp_384_norm_7(r);
  26494. over = r[6] >> 54;
  26495. sp_384_cond_sub_7(r, r, m, ~((over - 1) >> 63));
  26496. sp_384_norm_7(r);
  26497. }
  26498. /* Triple a Montgomery form number (r = a + a + a % m).
  26499. *
  26500. * r Result of Tripling.
  26501. * a Number to triple in Montgomery form.
  26502. * m Modulus (prime).
  26503. */
  26504. static void sp_384_mont_tpl_7(sp_digit* r, const sp_digit* a, const sp_digit* m)
  26505. {
  26506. sp_digit over;
  26507. (void)sp_384_add_7(r, a, a);
  26508. sp_384_norm_7(r);
  26509. over = r[6] >> 54;
  26510. sp_384_cond_sub_7(r, r, m, ~((over - 1) >> 63));
  26511. sp_384_norm_7(r);
  26512. (void)sp_384_add_7(r, r, a);
  26513. sp_384_norm_7(r);
  26514. over = r[6] >> 54;
  26515. sp_384_cond_sub_7(r, r, m, ~((over - 1) >> 63));
  26516. sp_384_norm_7(r);
  26517. }
  26518. #ifdef WOLFSSL_SP_SMALL
  26519. /* Conditionally add a and b using the mask m.
  26520. * m is -1 to add and 0 when not.
  26521. *
  26522. * r A single precision number representing conditional add result.
  26523. * a A single precision number to add with.
  26524. * b A single precision number to add.
  26525. * m Mask value to apply.
  26526. */
  26527. static void sp_384_cond_add_7(sp_digit* r, const sp_digit* a,
  26528. const sp_digit* b, const sp_digit m)
  26529. {
  26530. int i;
  26531. for (i = 0; i < 7; i++) {
  26532. r[i] = a[i] + (b[i] & m);
  26533. }
  26534. }
  26535. #endif /* WOLFSSL_SP_SMALL */
  26536. #ifndef WOLFSSL_SP_SMALL
  26537. /* Conditionally add a and b using the mask m.
  26538. * m is -1 to add and 0 when not.
  26539. *
  26540. * r A single precision number representing conditional add result.
  26541. * a A single precision number to add with.
  26542. * b A single precision number to add.
  26543. * m Mask value to apply.
  26544. */
  26545. static void sp_384_cond_add_7(sp_digit* r, const sp_digit* a,
  26546. const sp_digit* b, const sp_digit m)
  26547. {
  26548. r[ 0] = a[ 0] + (b[ 0] & m);
  26549. r[ 1] = a[ 1] + (b[ 1] & m);
  26550. r[ 2] = a[ 2] + (b[ 2] & m);
  26551. r[ 3] = a[ 3] + (b[ 3] & m);
  26552. r[ 4] = a[ 4] + (b[ 4] & m);
  26553. r[ 5] = a[ 5] + (b[ 5] & m);
  26554. r[ 6] = a[ 6] + (b[ 6] & m);
  26555. }
  26556. #endif /* !WOLFSSL_SP_SMALL */
  26557. /* Subtract two Montgomery form numbers (r = a - b % m).
  26558. *
  26559. * r Result of subtration.
  26560. * a Number to subtract from in Montgomery form.
  26561. * b Number to subtract with in Montgomery form.
  26562. * m Modulus (prime).
  26563. */
  26564. static void sp_384_mont_sub_7(sp_digit* r, const sp_digit* a, const sp_digit* b,
  26565. const sp_digit* m)
  26566. {
  26567. (void)sp_384_sub_7(r, a, b);
  26568. sp_384_norm_7(r);
  26569. sp_384_cond_add_7(r, r, m, r[6] >> 54);
  26570. sp_384_norm_7(r);
  26571. }
  26572. /* Shift number left one bit.
  26573. * Bottom bit is lost.
  26574. *
  26575. * r Result of shift.
  26576. * a Number to shift.
  26577. */
  26578. SP_NOINLINE static void sp_384_rshift1_7(sp_digit* r, const sp_digit* a)
  26579. {
  26580. #ifdef WOLFSSL_SP_SMALL
  26581. int i;
  26582. for (i=0; i<6; i++) {
  26583. r[i] = (a[i] >> 1) + ((a[i + 1] << 54) & 0x7fffffffffffffL);
  26584. }
  26585. #else
  26586. r[0] = (a[0] >> 1) + ((a[1] << 54) & 0x7fffffffffffffL);
  26587. r[1] = (a[1] >> 1) + ((a[2] << 54) & 0x7fffffffffffffL);
  26588. r[2] = (a[2] >> 1) + ((a[3] << 54) & 0x7fffffffffffffL);
  26589. r[3] = (a[3] >> 1) + ((a[4] << 54) & 0x7fffffffffffffL);
  26590. r[4] = (a[4] >> 1) + ((a[5] << 54) & 0x7fffffffffffffL);
  26591. r[5] = (a[5] >> 1) + ((a[6] << 54) & 0x7fffffffffffffL);
  26592. #endif
  26593. r[6] = a[6] >> 1;
  26594. }
  26595. /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)
  26596. *
  26597. * r Result of division by 2.
  26598. * a Number to divide.
  26599. * m Modulus (prime).
  26600. */
  26601. static void sp_384_mont_div2_7(sp_digit* r, const sp_digit* a,
  26602. const sp_digit* m)
  26603. {
  26604. sp_384_cond_add_7(r, a, m, 0 - (a[0] & 1));
  26605. sp_384_norm_7(r);
  26606. sp_384_rshift1_7(r, r);
  26607. }
  26608. /* Double the Montgomery form projective point p.
  26609. *
  26610. * r Result of doubling point.
  26611. * p Point to double.
  26612. * t Temporary ordinate data.
  26613. */
  26614. static void sp_384_proj_point_dbl_7(sp_point_384* r, const sp_point_384* p,
  26615. sp_digit* t)
  26616. {
  26617. sp_digit* t1 = t;
  26618. sp_digit* t2 = t + 2*7;
  26619. sp_digit* x;
  26620. sp_digit* y;
  26621. sp_digit* z;
  26622. x = r->x;
  26623. y = r->y;
  26624. z = r->z;
  26625. /* Put infinity into result. */
  26626. if (r != p) {
  26627. r->infinity = p->infinity;
  26628. }
  26629. /* T1 = Z * Z */
  26630. sp_384_mont_sqr_7(t1, p->z, p384_mod, p384_mp_mod);
  26631. /* Z = Y * Z */
  26632. sp_384_mont_mul_7(z, p->y, p->z, p384_mod, p384_mp_mod);
  26633. /* Z = 2Z */
  26634. sp_384_mont_dbl_7(z, z, p384_mod);
  26635. /* T2 = X - T1 */
  26636. sp_384_mont_sub_7(t2, p->x, t1, p384_mod);
  26637. /* T1 = X + T1 */
  26638. sp_384_mont_add_7(t1, p->x, t1, p384_mod);
  26639. /* T2 = T1 * T2 */
  26640. sp_384_mont_mul_7(t2, t1, t2, p384_mod, p384_mp_mod);
  26641. /* T1 = 3T2 */
  26642. sp_384_mont_tpl_7(t1, t2, p384_mod);
  26643. /* Y = 2Y */
  26644. sp_384_mont_dbl_7(y, p->y, p384_mod);
  26645. /* Y = Y * Y */
  26646. sp_384_mont_sqr_7(y, y, p384_mod, p384_mp_mod);
  26647. /* T2 = Y * Y */
  26648. sp_384_mont_sqr_7(t2, y, p384_mod, p384_mp_mod);
  26649. /* T2 = T2/2 */
  26650. sp_384_mont_div2_7(t2, t2, p384_mod);
  26651. /* Y = Y * X */
  26652. sp_384_mont_mul_7(y, y, p->x, p384_mod, p384_mp_mod);
  26653. /* X = T1 * T1 */
  26654. sp_384_mont_sqr_7(x, t1, p384_mod, p384_mp_mod);
  26655. /* X = X - Y */
  26656. sp_384_mont_sub_7(x, x, y, p384_mod);
  26657. /* X = X - Y */
  26658. sp_384_mont_sub_7(x, x, y, p384_mod);
  26659. /* Y = Y - X */
  26660. sp_384_mont_sub_7(y, y, x, p384_mod);
  26661. /* Y = Y * T1 */
  26662. sp_384_mont_mul_7(y, y, t1, p384_mod, p384_mp_mod);
  26663. /* Y = Y - T2 */
  26664. sp_384_mont_sub_7(y, y, t2, p384_mod);
  26665. }
  26666. #ifdef WOLFSSL_SP_NONBLOCK
  26667. typedef struct sp_384_proj_point_dbl_7_ctx {
  26668. int state;
  26669. sp_digit* t1;
  26670. sp_digit* t2;
  26671. sp_digit* x;
  26672. sp_digit* y;
  26673. sp_digit* z;
  26674. } sp_384_proj_point_dbl_7_ctx;
  26675. /* Double the Montgomery form projective point p.
  26676. *
  26677. * r Result of doubling point.
  26678. * p Point to double.
  26679. * t Temporary ordinate data.
  26680. */
  26681. static int sp_384_proj_point_dbl_7_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
  26682. const sp_point_384* p, sp_digit* t)
  26683. {
  26684. int err = FP_WOULDBLOCK;
  26685. sp_384_proj_point_dbl_7_ctx* ctx = (sp_384_proj_point_dbl_7_ctx*)sp_ctx->data;
  26686. typedef char ctx_size_test[sizeof(sp_384_proj_point_dbl_7_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  26687. (void)sizeof(ctx_size_test);
  26688. switch (ctx->state) {
  26689. case 0:
  26690. ctx->t1 = t;
  26691. ctx->t2 = t + 2*7;
  26692. ctx->x = r->x;
  26693. ctx->y = r->y;
  26694. ctx->z = r->z;
  26695. /* Put infinity into result. */
  26696. if (r != p) {
  26697. r->infinity = p->infinity;
  26698. }
  26699. ctx->state = 1;
  26700. break;
  26701. case 1:
  26702. /* T1 = Z * Z */
  26703. sp_384_mont_sqr_7(ctx->t1, p->z, p384_mod, p384_mp_mod);
  26704. ctx->state = 2;
  26705. break;
  26706. case 2:
  26707. /* Z = Y * Z */
  26708. sp_384_mont_mul_7(ctx->z, p->y, p->z, p384_mod, p384_mp_mod);
  26709. ctx->state = 3;
  26710. break;
  26711. case 3:
  26712. /* Z = 2Z */
  26713. sp_384_mont_dbl_7(ctx->z, ctx->z, p384_mod);
  26714. ctx->state = 4;
  26715. break;
  26716. case 4:
  26717. /* T2 = X - T1 */
  26718. sp_384_mont_sub_7(ctx->t2, p->x, ctx->t1, p384_mod);
  26719. ctx->state = 5;
  26720. break;
  26721. case 5:
  26722. /* T1 = X + T1 */
  26723. sp_384_mont_add_7(ctx->t1, p->x, ctx->t1, p384_mod);
  26724. ctx->state = 6;
  26725. break;
  26726. case 6:
  26727. /* T2 = T1 * T2 */
  26728. sp_384_mont_mul_7(ctx->t2, ctx->t1, ctx->t2, p384_mod, p384_mp_mod);
  26729. ctx->state = 7;
  26730. break;
  26731. case 7:
  26732. /* T1 = 3T2 */
  26733. sp_384_mont_tpl_7(ctx->t1, ctx->t2, p384_mod);
  26734. ctx->state = 8;
  26735. break;
  26736. case 8:
  26737. /* Y = 2Y */
  26738. sp_384_mont_dbl_7(ctx->y, p->y, p384_mod);
  26739. ctx->state = 9;
  26740. break;
  26741. case 9:
  26742. /* Y = Y * Y */
  26743. sp_384_mont_sqr_7(ctx->y, ctx->y, p384_mod, p384_mp_mod);
  26744. ctx->state = 10;
  26745. break;
  26746. case 10:
  26747. /* T2 = Y * Y */
  26748. sp_384_mont_sqr_7(ctx->t2, ctx->y, p384_mod, p384_mp_mod);
  26749. ctx->state = 11;
  26750. break;
  26751. case 11:
  26752. /* T2 = T2/2 */
  26753. sp_384_mont_div2_7(ctx->t2, ctx->t2, p384_mod);
  26754. ctx->state = 12;
  26755. break;
  26756. case 12:
  26757. /* Y = Y * X */
  26758. sp_384_mont_mul_7(ctx->y, ctx->y, p->x, p384_mod, p384_mp_mod);
  26759. ctx->state = 13;
  26760. break;
  26761. case 13:
  26762. /* X = T1 * T1 */
  26763. sp_384_mont_sqr_7(ctx->x, ctx->t1, p384_mod, p384_mp_mod);
  26764. ctx->state = 14;
  26765. break;
  26766. case 14:
  26767. /* X = X - Y */
  26768. sp_384_mont_sub_7(ctx->x, ctx->x, ctx->y, p384_mod);
  26769. ctx->state = 15;
  26770. break;
  26771. case 15:
  26772. /* X = X - Y */
  26773. sp_384_mont_sub_7(ctx->x, ctx->x, ctx->y, p384_mod);
  26774. ctx->state = 16;
  26775. break;
  26776. case 16:
  26777. /* Y = Y - X */
  26778. sp_384_mont_sub_7(ctx->y, ctx->y, ctx->x, p384_mod);
  26779. ctx->state = 17;
  26780. break;
  26781. case 17:
  26782. /* Y = Y * T1 */
  26783. sp_384_mont_mul_7(ctx->y, ctx->y, ctx->t1, p384_mod, p384_mp_mod);
  26784. ctx->state = 18;
  26785. break;
  26786. case 18:
  26787. /* Y = Y - T2 */
  26788. sp_384_mont_sub_7(ctx->y, ctx->y, ctx->t2, p384_mod);
  26789. ctx->state = 19;
  26790. /* fall-through */
  26791. case 19:
  26792. err = MP_OKAY;
  26793. break;
  26794. }
  26795. if (err == MP_OKAY && ctx->state != 19) {
  26796. err = FP_WOULDBLOCK;
  26797. }
  26798. return err;
  26799. }
  26800. #endif /* WOLFSSL_SP_NONBLOCK */
  26801. /* Compare two numbers to determine if they are equal.
  26802. * Constant time implementation.
  26803. *
  26804. * a First number to compare.
  26805. * b Second number to compare.
  26806. * returns 1 when equal and 0 otherwise.
  26807. */
  26808. static int sp_384_cmp_equal_7(const sp_digit* a, const sp_digit* b)
  26809. {
  26810. return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) |
  26811. (a[3] ^ b[3]) | (a[4] ^ b[4]) | (a[5] ^ b[5]) |
  26812. (a[6] ^ b[6])) == 0;
  26813. }
  26814. /* Returns 1 if the number of zero.
  26815. * Implementation is constant time.
  26816. *
  26817. * a Number to check.
  26818. * returns 1 if the number is zero and 0 otherwise.
  26819. */
  26820. static int sp_384_iszero_7(const sp_digit* a)
  26821. {
  26822. return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6]) == 0;
  26823. }
  26824. /* Add two Montgomery form projective points.
  26825. *
  26826. * r Result of addition.
  26827. * p First point to add.
  26828. * q Second point to add.
  26829. * t Temporary ordinate data.
  26830. */
  26831. static void sp_384_proj_point_add_7(sp_point_384* r,
  26832. const sp_point_384* p, const sp_point_384* q, sp_digit* t)
  26833. {
  26834. sp_digit* t6 = t;
  26835. sp_digit* t1 = t + 2*7;
  26836. sp_digit* t2 = t + 4*7;
  26837. sp_digit* t3 = t + 6*7;
  26838. sp_digit* t4 = t + 8*7;
  26839. sp_digit* t5 = t + 10*7;
  26840. /* U1 = X1*Z2^2 */
  26841. sp_384_mont_sqr_7(t1, q->z, p384_mod, p384_mp_mod);
  26842. sp_384_mont_mul_7(t3, t1, q->z, p384_mod, p384_mp_mod);
  26843. sp_384_mont_mul_7(t1, t1, p->x, p384_mod, p384_mp_mod);
  26844. /* U2 = X2*Z1^2 */
  26845. sp_384_mont_sqr_7(t2, p->z, p384_mod, p384_mp_mod);
  26846. sp_384_mont_mul_7(t4, t2, p->z, p384_mod, p384_mp_mod);
  26847. sp_384_mont_mul_7(t2, t2, q->x, p384_mod, p384_mp_mod);
  26848. /* S1 = Y1*Z2^3 */
  26849. sp_384_mont_mul_7(t3, t3, p->y, p384_mod, p384_mp_mod);
  26850. /* S2 = Y2*Z1^3 */
  26851. sp_384_mont_mul_7(t4, t4, q->y, p384_mod, p384_mp_mod);
  26852. /* Check double */
  26853. if ((~p->infinity) & (~q->infinity) &
  26854. sp_384_cmp_equal_7(t2, t1) &
  26855. sp_384_cmp_equal_7(t4, t3)) {
  26856. sp_384_proj_point_dbl_7(r, p, t);
  26857. }
  26858. else {
  26859. sp_digit* x = t6;
  26860. sp_digit* y = t1;
  26861. sp_digit* z = t2;
  26862. /* H = U2 - U1 */
  26863. sp_384_mont_sub_7(t2, t2, t1, p384_mod);
  26864. /* R = S2 - S1 */
  26865. sp_384_mont_sub_7(t4, t4, t3, p384_mod);
  26866. /* X3 = R^2 - H^3 - 2*U1*H^2 */
  26867. sp_384_mont_sqr_7(t5, t2, p384_mod, p384_mp_mod);
  26868. sp_384_mont_mul_7(y, t1, t5, p384_mod, p384_mp_mod);
  26869. sp_384_mont_mul_7(t5, t5, t2, p384_mod, p384_mp_mod);
  26870. /* Z3 = H*Z1*Z2 */
  26871. sp_384_mont_mul_7(z, p->z, t2, p384_mod, p384_mp_mod);
  26872. sp_384_mont_mul_7(z, z, q->z, p384_mod, p384_mp_mod);
  26873. sp_384_mont_sqr_7(x, t4, p384_mod, p384_mp_mod);
  26874. sp_384_mont_sub_7(x, x, t5, p384_mod);
  26875. sp_384_mont_mul_7(t5, t5, t3, p384_mod, p384_mp_mod);
  26876. sp_384_mont_dbl_7(t3, y, p384_mod);
  26877. sp_384_mont_sub_7(x, x, t3, p384_mod);
  26878. /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
  26879. sp_384_mont_sub_7(y, y, x, p384_mod);
  26880. sp_384_mont_mul_7(y, y, t4, p384_mod, p384_mp_mod);
  26881. sp_384_mont_sub_7(y, y, t5, p384_mod);
  26882. {
  26883. int i;
  26884. sp_digit maskp = 0 - (q->infinity & (!p->infinity));
  26885. sp_digit maskq = 0 - (p->infinity & (!q->infinity));
  26886. sp_digit maskt = ~(maskp | maskq);
  26887. sp_digit inf = (sp_digit)(p->infinity & q->infinity);
  26888. for (i = 0; i < 7; i++) {
  26889. r->x[i] = (p->x[i] & maskp) | (q->x[i] & maskq) |
  26890. (x[i] & maskt);
  26891. }
  26892. for (i = 0; i < 7; i++) {
  26893. r->y[i] = (p->y[i] & maskp) | (q->y[i] & maskq) |
  26894. (y[i] & maskt);
  26895. }
  26896. for (i = 0; i < 7; i++) {
  26897. r->z[i] = (p->z[i] & maskp) | (q->z[i] & maskq) |
  26898. (z[i] & maskt);
  26899. }
  26900. r->z[0] |= inf;
  26901. r->infinity = (word32)inf;
  26902. }
  26903. }
  26904. }
  26905. #ifdef WOLFSSL_SP_NONBLOCK
  26906. typedef struct sp_384_proj_point_add_7_ctx {
  26907. int state;
  26908. sp_384_proj_point_dbl_7_ctx dbl_ctx;
  26909. const sp_point_384* ap[2];
  26910. sp_point_384* rp[2];
  26911. sp_digit* t1;
  26912. sp_digit* t2;
  26913. sp_digit* t3;
  26914. sp_digit* t4;
  26915. sp_digit* t5;
  26916. sp_digit* t6;
  26917. sp_digit* x;
  26918. sp_digit* y;
  26919. sp_digit* z;
  26920. } sp_384_proj_point_add_7_ctx;
  26921. /* Add two Montgomery form projective points.
  26922. *
  26923. * r Result of addition.
  26924. * p First point to add.
  26925. * q Second point to add.
  26926. * t Temporary ordinate data.
  26927. */
  26928. static int sp_384_proj_point_add_7_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
  26929. const sp_point_384* p, const sp_point_384* q, sp_digit* t)
  26930. {
  26931. int err = FP_WOULDBLOCK;
  26932. sp_384_proj_point_add_7_ctx* ctx = (sp_384_proj_point_add_7_ctx*)sp_ctx->data;
  26933. /* Ensure only the first point is the same as the result. */
  26934. if (q == r) {
  26935. const sp_point_384* a = p;
  26936. p = q;
  26937. q = a;
  26938. }
  26939. typedef char ctx_size_test[sizeof(sp_384_proj_point_add_7_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  26940. (void)sizeof(ctx_size_test);
  26941. switch (ctx->state) {
  26942. case 0: /* INIT */
  26943. ctx->t6 = t;
  26944. ctx->t1 = t + 2*7;
  26945. ctx->t2 = t + 4*7;
  26946. ctx->t3 = t + 6*7;
  26947. ctx->t4 = t + 8*7;
  26948. ctx->t5 = t + 10*7;
  26949. ctx->x = ctx->t6;
  26950. ctx->y = ctx->t1;
  26951. ctx->z = ctx->t2;
  26952. ctx->state = 1;
  26953. break;
  26954. case 1:
  26955. /* U1 = X1*Z2^2 */
  26956. sp_384_mont_sqr_7(ctx->t1, q->z, p384_mod, p384_mp_mod);
  26957. ctx->state = 2;
  26958. break;
  26959. case 2:
  26960. sp_384_mont_mul_7(ctx->t3, ctx->t1, q->z, p384_mod, p384_mp_mod);
  26961. ctx->state = 3;
  26962. break;
  26963. case 3:
  26964. sp_384_mont_mul_7(ctx->t1, ctx->t1, p->x, p384_mod, p384_mp_mod);
  26965. ctx->state = 4;
  26966. break;
  26967. case 4:
  26968. /* U2 = X2*Z1^2 */
  26969. sp_384_mont_sqr_7(ctx->t2, p->z, p384_mod, p384_mp_mod);
  26970. ctx->state = 5;
  26971. break;
  26972. case 5:
  26973. sp_384_mont_mul_7(ctx->t4, ctx->t2, p->z, p384_mod, p384_mp_mod);
  26974. ctx->state = 6;
  26975. break;
  26976. case 6:
  26977. sp_384_mont_mul_7(ctx->t2, ctx->t2, q->x, p384_mod, p384_mp_mod);
  26978. ctx->state = 7;
  26979. break;
  26980. case 7:
  26981. /* S1 = Y1*Z2^3 */
  26982. sp_384_mont_mul_7(ctx->t3, ctx->t3, p->y, p384_mod, p384_mp_mod);
  26983. ctx->state = 8;
  26984. break;
  26985. case 8:
  26986. /* S2 = Y2*Z1^3 */
  26987. sp_384_mont_mul_7(ctx->t4, ctx->t4, q->y, p384_mod, p384_mp_mod);
  26988. ctx->state = 9;
  26989. break;
  26990. case 9:
  26991. /* Check double */
  26992. if ((~p->infinity) & (~q->infinity) &
  26993. sp_384_cmp_equal_7(ctx->t2, ctx->t1) &
  26994. sp_384_cmp_equal_7(ctx->t4, ctx->t3)) {
  26995. XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx));
  26996. sp_384_proj_point_dbl_7(r, p, t);
  26997. ctx->state = 25;
  26998. }
  26999. else {
  27000. ctx->state = 10;
  27001. }
  27002. break;
  27003. case 10:
  27004. /* H = U2 - U1 */
  27005. sp_384_mont_sub_7(ctx->t2, ctx->t2, ctx->t1, p384_mod);
  27006. ctx->state = 11;
  27007. break;
  27008. case 11:
  27009. /* R = S2 - S1 */
  27010. sp_384_mont_sub_7(ctx->t4, ctx->t4, ctx->t3, p384_mod);
  27011. ctx->state = 12;
  27012. break;
  27013. case 12:
  27014. /* X3 = R^2 - H^3 - 2*U1*H^2 */
  27015. sp_384_mont_sqr_7(ctx->t5, ctx->t2, p384_mod, p384_mp_mod);
  27016. ctx->state = 13;
  27017. break;
  27018. case 13:
  27019. sp_384_mont_mul_7(ctx->y, ctx->t1, ctx->t5, p384_mod, p384_mp_mod);
  27020. ctx->state = 14;
  27021. break;
  27022. case 14:
  27023. sp_384_mont_mul_7(ctx->t5, ctx->t5, ctx->t2, p384_mod, p384_mp_mod);
  27024. ctx->state = 15;
  27025. break;
  27026. case 15:
  27027. /* Z3 = H*Z1*Z2 */
  27028. sp_384_mont_mul_7(ctx->z, p->z, ctx->t2, p384_mod, p384_mp_mod);
  27029. ctx->state = 16;
  27030. break;
  27031. case 16:
  27032. sp_384_mont_mul_7(ctx->z, ctx->z, q->z, p384_mod, p384_mp_mod);
  27033. ctx->state = 17;
  27034. break;
  27035. case 17:
  27036. sp_384_mont_sqr_7(ctx->x, ctx->t4, p384_mod, p384_mp_mod);
  27037. ctx->state = 18;
  27038. break;
  27039. case 18:
  27040. sp_384_mont_sub_7(ctx->x, ctx->x, ctx->t5, p384_mod);
  27041. ctx->state = 19;
  27042. break;
  27043. case 19:
  27044. sp_384_mont_mul_7(ctx->t5, ctx->t5, ctx->t3, p384_mod, p384_mp_mod);
  27045. ctx->state = 20;
  27046. break;
  27047. case 20:
  27048. sp_384_mont_dbl_7(ctx->t3, ctx->y, p384_mod);
  27049. sp_384_mont_sub_7(ctx->x, ctx->x, ctx->t3, p384_mod);
  27050. ctx->state = 21;
  27051. break;
  27052. case 21:
  27053. /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
  27054. sp_384_mont_sub_7(ctx->y, ctx->y, ctx->x, p384_mod);
  27055. ctx->state = 22;
  27056. break;
  27057. case 22:
  27058. sp_384_mont_mul_7(ctx->y, ctx->y, ctx->t4, p384_mod, p384_mp_mod);
  27059. ctx->state = 23;
  27060. break;
  27061. case 23:
  27062. sp_384_mont_sub_7(ctx->y, ctx->y, ctx->t5, p384_mod);
  27063. ctx->state = 24;
  27064. break;
  27065. case 24:
  27066. {
  27067. {
  27068. int i;
  27069. sp_digit maskp = 0 - (q->infinity & (!p->infinity));
  27070. sp_digit maskq = 0 - (p->infinity & (!q->infinity));
  27071. sp_digit maskt = ~(maskp | maskq);
  27072. sp_digit inf = (sp_digit)(p->infinity & q->infinity);
  27073. for (i = 0; i < 7; i++) {
  27074. r->x[i] = (p->x[i] & maskp) | (q->x[i] & maskq) |
  27075. (ctx->x[i] & maskt);
  27076. }
  27077. for (i = 0; i < 7; i++) {
  27078. r->y[i] = (p->y[i] & maskp) | (q->y[i] & maskq) |
  27079. (ctx->y[i] & maskt);
  27080. }
  27081. for (i = 0; i < 7; i++) {
  27082. r->z[i] = (p->z[i] & maskp) | (q->z[i] & maskq) |
  27083. (ctx->z[i] & maskt);
  27084. }
  27085. r->z[0] |= inf;
  27086. r->infinity = (word32)inf;
  27087. }
  27088. ctx->state = 25;
  27089. break;
  27090. }
  27091. case 25:
  27092. err = MP_OKAY;
  27093. break;
  27094. }
  27095. if (err == MP_OKAY && ctx->state != 25) {
  27096. err = FP_WOULDBLOCK;
  27097. }
  27098. return err;
  27099. }
  27100. #endif /* WOLFSSL_SP_NONBLOCK */
  27101. /* Multiply a number by Montgomery normalizer mod modulus (prime).
  27102. *
  27103. * r The resulting Montgomery form number.
  27104. * a The number to convert.
  27105. * m The modulus (prime).
  27106. * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise.
  27107. */
  27108. static int sp_384_mod_mul_norm_7(sp_digit* r, const sp_digit* a, const sp_digit* m)
  27109. {
  27110. #ifdef WOLFSSL_SP_SMALL_STACK
  27111. int64_t* t = NULL;
  27112. #else
  27113. int64_t t[2 * 12];
  27114. #endif
  27115. int64_t* a32 = NULL;
  27116. int64_t o;
  27117. int err = MP_OKAY;
  27118. (void)m;
  27119. #ifdef WOLFSSL_SP_SMALL_STACK
  27120. t = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 12, NULL, DYNAMIC_TYPE_ECC);
  27121. if (t == NULL)
  27122. err = MEMORY_E;
  27123. #endif
  27124. if (err == MP_OKAY) {
  27125. a32 = t + 12;
  27126. a32[0] = (sp_digit)(a[0]) & 0xffffffffL;
  27127. a32[1] = (sp_digit)(a[0] >> 32U);
  27128. a32[1] |= (sp_digit)(a[1] << 23U);
  27129. a32[1] &= 0xffffffffL;
  27130. a32[2] = (sp_digit)(a[1] >> 9U) & 0xffffffffL;
  27131. a32[3] = (sp_digit)(a[1] >> 41U);
  27132. a32[3] |= (sp_digit)(a[2] << 14U);
  27133. a32[3] &= 0xffffffffL;
  27134. a32[4] = (sp_digit)(a[2] >> 18U) & 0xffffffffL;
  27135. a32[5] = (sp_digit)(a[2] >> 50U);
  27136. a32[5] |= (sp_digit)(a[3] << 5U);
  27137. a32[5] &= 0xffffffffL;
  27138. a32[6] = (sp_digit)(a[3] >> 27U);
  27139. a32[6] |= (sp_digit)(a[4] << 28U);
  27140. a32[6] &= 0xffffffffL;
  27141. a32[7] = (sp_digit)(a[4] >> 4U) & 0xffffffffL;
  27142. a32[8] = (sp_digit)(a[4] >> 36U);
  27143. a32[8] |= (sp_digit)(a[5] << 19U);
  27144. a32[8] &= 0xffffffffL;
  27145. a32[9] = (sp_digit)(a[5] >> 13U) & 0xffffffffL;
  27146. a32[10] = (sp_digit)(a[5] >> 45U);
  27147. a32[10] |= (sp_digit)(a[6] << 10U);
  27148. a32[10] &= 0xffffffffL;
  27149. a32[11] = (sp_digit)(a[6] >> 22U) & 0xffffffffL;
  27150. /* 1 0 0 0 0 0 0 0 1 1 0 -1 */
  27151. t[0] = 0 + a32[0] + a32[8] + a32[9] - a32[11];
  27152. /* -1 1 0 0 0 0 0 0 -1 0 1 1 */
  27153. t[1] = 0 - a32[0] + a32[1] - a32[8] + a32[10] + a32[11];
  27154. /* 0 -1 1 0 0 0 0 0 0 -1 0 1 */
  27155. t[2] = 0 - a32[1] + a32[2] - a32[9] + a32[11];
  27156. /* 1 0 -1 1 0 0 0 0 1 1 -1 -1 */
  27157. t[3] = 0 + a32[0] - a32[2] + a32[3] + a32[8] + a32[9] - a32[10] - a32[11];
  27158. /* 1 1 0 -1 1 0 0 0 1 2 1 -2 */
  27159. t[4] = 0 + a32[0] + a32[1] - a32[3] + a32[4] + a32[8] + 2 * a32[9] + a32[10] - 2 * a32[11];
  27160. /* 0 1 1 0 -1 1 0 0 0 1 2 1 */
  27161. t[5] = 0 + a32[1] + a32[2] - a32[4] + a32[5] + a32[9] + 2 * a32[10] + a32[11];
  27162. /* 0 0 1 1 0 -1 1 0 0 0 1 2 */
  27163. t[6] = 0 + a32[2] + a32[3] - a32[5] + a32[6] + a32[10] + 2 * a32[11];
  27164. /* 0 0 0 1 1 0 -1 1 0 0 0 1 */
  27165. t[7] = 0 + a32[3] + a32[4] - a32[6] + a32[7] + a32[11];
  27166. /* 0 0 0 0 1 1 0 -1 1 0 0 0 */
  27167. t[8] = 0 + a32[4] + a32[5] - a32[7] + a32[8];
  27168. /* 0 0 0 0 0 1 1 0 -1 1 0 0 */
  27169. t[9] = 0 + a32[5] + a32[6] - a32[8] + a32[9];
  27170. /* 0 0 0 0 0 0 1 1 0 -1 1 0 */
  27171. t[10] = 0 + a32[6] + a32[7] - a32[9] + a32[10];
  27172. /* 0 0 0 0 0 0 0 1 1 0 -1 1 */
  27173. t[11] = 0 + a32[7] + a32[8] - a32[10] + a32[11];
  27174. t[1] += t[0] >> 32; t[0] &= 0xffffffff;
  27175. t[2] += t[1] >> 32; t[1] &= 0xffffffff;
  27176. t[3] += t[2] >> 32; t[2] &= 0xffffffff;
  27177. t[4] += t[3] >> 32; t[3] &= 0xffffffff;
  27178. t[5] += t[4] >> 32; t[4] &= 0xffffffff;
  27179. t[6] += t[5] >> 32; t[5] &= 0xffffffff;
  27180. t[7] += t[6] >> 32; t[6] &= 0xffffffff;
  27181. t[8] += t[7] >> 32; t[7] &= 0xffffffff;
  27182. t[9] += t[8] >> 32; t[8] &= 0xffffffff;
  27183. t[10] += t[9] >> 32; t[9] &= 0xffffffff;
  27184. t[11] += t[10] >> 32; t[10] &= 0xffffffff;
  27185. o = t[11] >> 32; t[11] &= 0xffffffff;
  27186. t[0] += o;
  27187. t[1] -= o;
  27188. t[3] += o;
  27189. t[4] += o;
  27190. t[1] += t[0] >> 32; t[0] &= 0xffffffff;
  27191. t[2] += t[1] >> 32; t[1] &= 0xffffffff;
  27192. t[3] += t[2] >> 32; t[2] &= 0xffffffff;
  27193. t[4] += t[3] >> 32; t[3] &= 0xffffffff;
  27194. t[5] += t[4] >> 32; t[4] &= 0xffffffff;
  27195. t[6] += t[5] >> 32; t[5] &= 0xffffffff;
  27196. t[7] += t[6] >> 32; t[6] &= 0xffffffff;
  27197. t[8] += t[7] >> 32; t[7] &= 0xffffffff;
  27198. t[9] += t[8] >> 32; t[8] &= 0xffffffff;
  27199. t[10] += t[9] >> 32; t[9] &= 0xffffffff;
  27200. t[11] += t[10] >> 32; t[10] &= 0xffffffff;
  27201. r[0] = t[0];
  27202. r[0] |= t[1] << 32U;
  27203. r[0] &= 0x7fffffffffffffLL;
  27204. r[1] = (t[1] >> 23);
  27205. r[1] |= t[2] << 9U;
  27206. r[1] |= t[3] << 41U;
  27207. r[1] &= 0x7fffffffffffffLL;
  27208. r[2] = (t[3] >> 14);
  27209. r[2] |= t[4] << 18U;
  27210. r[2] |= t[5] << 50U;
  27211. r[2] &= 0x7fffffffffffffLL;
  27212. r[3] = (t[5] >> 5);
  27213. r[3] |= t[6] << 27U;
  27214. r[3] &= 0x7fffffffffffffLL;
  27215. r[4] = (t[6] >> 28);
  27216. r[4] |= t[7] << 4U;
  27217. r[4] |= t[8] << 36U;
  27218. r[4] &= 0x7fffffffffffffLL;
  27219. r[5] = (t[8] >> 19);
  27220. r[5] |= t[9] << 13U;
  27221. r[5] |= t[10] << 45U;
  27222. r[5] &= 0x7fffffffffffffLL;
  27223. r[6] = (t[10] >> 10);
  27224. r[6] |= t[11] << 22U;
  27225. }
  27226. #ifdef WOLFSSL_SP_SMALL_STACK
  27227. if (t != NULL)
  27228. XFREE(t, NULL, DYNAMIC_TYPE_ECC);
  27229. #endif
  27230. return err;
  27231. }
  27232. #ifdef WOLFSSL_SP_SMALL
  27233. /* Multiply the point by the scalar and return the result.
  27234. * If map is true then convert result to affine coordinates.
  27235. *
  27236. * Small implementation using add and double that is cache attack resistant but
  27237. * allocates memory rather than use large stacks.
  27238. * 384 adds and doubles.
  27239. *
  27240. * r Resulting point.
  27241. * g Point to multiply.
  27242. * k Scalar to multiply by.
  27243. * map Indicates whether to convert result to affine.
  27244. * ct Constant time required.
  27245. * heap Heap to use for allocation.
  27246. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  27247. */
  27248. static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g,
  27249. const sp_digit* k, int map, int ct, void* heap)
  27250. {
  27251. #ifdef WOLFSSL_SP_SMALL_STACK
  27252. sp_point_384* t = NULL;
  27253. sp_digit* tmp = NULL;
  27254. #else
  27255. sp_point_384 t[3];
  27256. sp_digit tmp[2 * 7 * 6];
  27257. #endif
  27258. sp_digit n;
  27259. int i;
  27260. int c;
  27261. int y;
  27262. int err = MP_OKAY;
  27263. /* Implementation is constant time. */
  27264. (void)ct;
  27265. (void)heap;
  27266. #ifdef WOLFSSL_SP_SMALL_STACK
  27267. t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 3, heap,
  27268. DYNAMIC_TYPE_ECC);
  27269. if (t == NULL)
  27270. err = MEMORY_E;
  27271. if (err == MP_OKAY) {
  27272. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 6, heap,
  27273. DYNAMIC_TYPE_ECC);
  27274. if (tmp == NULL)
  27275. err = MEMORY_E;
  27276. }
  27277. #endif
  27278. if (err == MP_OKAY) {
  27279. XMEMSET(t, 0, sizeof(sp_point_384) * 3);
  27280. /* t[0] = {0, 0, 1} * norm */
  27281. t[0].infinity = 1;
  27282. /* t[1] = {g->x, g->y, g->z} * norm */
  27283. err = sp_384_mod_mul_norm_7(t[1].x, g->x, p384_mod);
  27284. }
  27285. if (err == MP_OKAY)
  27286. err = sp_384_mod_mul_norm_7(t[1].y, g->y, p384_mod);
  27287. if (err == MP_OKAY)
  27288. err = sp_384_mod_mul_norm_7(t[1].z, g->z, p384_mod);
  27289. if (err == MP_OKAY) {
  27290. i = 6;
  27291. c = 54;
  27292. n = k[i--] << (55 - c);
  27293. for (; ; c--) {
  27294. if (c == 0) {
  27295. if (i == -1)
  27296. break;
  27297. n = k[i--];
  27298. c = 55;
  27299. }
  27300. y = (n >> 54) & 1;
  27301. n <<= 1;
  27302. sp_384_proj_point_add_7(&t[y^1], &t[0], &t[1], tmp);
  27303. XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) +
  27304. ((size_t)&t[1] & addr_mask[y])),
  27305. sizeof(sp_point_384));
  27306. sp_384_proj_point_dbl_7(&t[2], &t[2], tmp);
  27307. XMEMCPY((void*)(((size_t)&t[0] & addr_mask[y^1]) +
  27308. ((size_t)&t[1] & addr_mask[y])), &t[2],
  27309. sizeof(sp_point_384));
  27310. }
  27311. if (map != 0) {
  27312. sp_384_map_7(r, &t[0], tmp);
  27313. }
  27314. else {
  27315. XMEMCPY(r, &t[0], sizeof(sp_point_384));
  27316. }
  27317. }
  27318. #ifdef WOLFSSL_SP_SMALL_STACK
  27319. if (tmp != NULL)
  27320. #endif
  27321. {
  27322. ForceZero(tmp, sizeof(sp_digit) * 2 * 7 * 6);
  27323. #ifdef WOLFSSL_SP_SMALL_STACK
  27324. XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
  27325. #endif
  27326. }
  27327. #ifdef WOLFSSL_SP_SMALL_STACK
  27328. if (t != NULL)
  27329. #endif
  27330. {
  27331. ForceZero(t, sizeof(sp_point_384) * 3);
  27332. #ifdef WOLFSSL_SP_SMALL_STACK
  27333. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  27334. #endif
  27335. }
  27336. return err;
  27337. }
  27338. #ifdef WOLFSSL_SP_NONBLOCK
  27339. typedef struct sp_384_ecc_mulmod_7_ctx {
  27340. int state;
  27341. union {
  27342. sp_384_proj_point_dbl_7_ctx dbl_ctx;
  27343. sp_384_proj_point_add_7_ctx add_ctx;
  27344. };
  27345. sp_point_384 t[3];
  27346. sp_digit tmp[2 * 7 * 6];
  27347. sp_digit n;
  27348. int i;
  27349. int c;
  27350. int y;
  27351. } sp_384_ecc_mulmod_7_ctx;
  27352. static int sp_384_ecc_mulmod_7_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
  27353. const sp_point_384* g, const sp_digit* k, int map, int ct, void* heap)
  27354. {
  27355. int err = FP_WOULDBLOCK;
  27356. sp_384_ecc_mulmod_7_ctx* ctx = (sp_384_ecc_mulmod_7_ctx*)sp_ctx->data;
  27357. typedef char ctx_size_test[sizeof(sp_384_ecc_mulmod_7_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  27358. (void)sizeof(ctx_size_test);
  27359. /* Implementation is constant time. */
  27360. (void)ct;
  27361. switch (ctx->state) {
  27362. case 0: /* INIT */
  27363. XMEMSET(ctx->t, 0, sizeof(sp_point_384) * 3);
  27364. ctx->i = 6;
  27365. ctx->c = 54;
  27366. ctx->n = k[ctx->i--] << (55 - ctx->c);
  27367. /* t[0] = {0, 0, 1} * norm */
  27368. ctx->t[0].infinity = 1;
  27369. ctx->state = 1;
  27370. break;
  27371. case 1: /* T1X */
  27372. /* t[1] = {g->x, g->y, g->z} * norm */
  27373. err = sp_384_mod_mul_norm_7(ctx->t[1].x, g->x, p384_mod);
  27374. ctx->state = 2;
  27375. break;
  27376. case 2: /* T1Y */
  27377. err = sp_384_mod_mul_norm_7(ctx->t[1].y, g->y, p384_mod);
  27378. ctx->state = 3;
  27379. break;
  27380. case 3: /* T1Z */
  27381. err = sp_384_mod_mul_norm_7(ctx->t[1].z, g->z, p384_mod);
  27382. ctx->state = 4;
  27383. break;
  27384. case 4: /* ADDPREP */
  27385. if (ctx->c == 0) {
  27386. if (ctx->i == -1) {
  27387. ctx->state = 7;
  27388. break;
  27389. }
  27390. ctx->n = k[ctx->i--];
  27391. ctx->c = 55;
  27392. }
  27393. ctx->y = (ctx->n >> 54) & 1;
  27394. ctx->n <<= 1;
  27395. XMEMSET(&ctx->add_ctx, 0, sizeof(ctx->add_ctx));
  27396. ctx->state = 5;
  27397. break;
  27398. case 5: /* ADD */
  27399. err = sp_384_proj_point_add_7_nb((sp_ecc_ctx_t*)&ctx->add_ctx,
  27400. &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp);
  27401. if (err == MP_OKAY) {
  27402. XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) +
  27403. ((size_t)&ctx->t[1] & addr_mask[ctx->y])),
  27404. sizeof(sp_point_384));
  27405. XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx));
  27406. ctx->state = 6;
  27407. }
  27408. break;
  27409. case 6: /* DBL */
  27410. err = sp_384_proj_point_dbl_7_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2],
  27411. &ctx->t[2], ctx->tmp);
  27412. if (err == MP_OKAY) {
  27413. XMEMCPY((void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) +
  27414. ((size_t)&ctx->t[1] & addr_mask[ctx->y])), &ctx->t[2],
  27415. sizeof(sp_point_384));
  27416. ctx->state = 4;
  27417. ctx->c--;
  27418. }
  27419. break;
  27420. case 7: /* MAP */
  27421. if (map != 0) {
  27422. sp_384_map_7(r, &ctx->t[0], ctx->tmp);
  27423. }
  27424. else {
  27425. XMEMCPY(r, &ctx->t[0], sizeof(sp_point_384));
  27426. }
  27427. err = MP_OKAY;
  27428. break;
  27429. }
  27430. if (err == MP_OKAY && ctx->state != 7) {
  27431. err = FP_WOULDBLOCK;
  27432. }
  27433. if (err != FP_WOULDBLOCK) {
  27434. ForceZero(ctx->tmp, sizeof(ctx->tmp));
  27435. ForceZero(ctx->t, sizeof(ctx->t));
  27436. }
  27437. (void)heap;
  27438. return err;
  27439. }
  27440. #endif /* WOLFSSL_SP_NONBLOCK */
  27441. #else
  27442. /* A table entry for pre-computed points. */
  27443. typedef struct sp_table_entry_384 {
  27444. sp_digit x[7];
  27445. sp_digit y[7];
  27446. } sp_table_entry_384;
  27447. /* Conditionally copy a into r using the mask m.
  27448. * m is -1 to copy and 0 when not.
  27449. *
  27450. * r A single precision number to copy over.
  27451. * a A single precision number to copy.
  27452. * m Mask value to apply.
  27453. */
  27454. static void sp_384_cond_copy_7(sp_digit* r, const sp_digit* a, const sp_digit m)
  27455. {
  27456. sp_digit t[7];
  27457. #ifdef WOLFSSL_SP_SMALL
  27458. int i;
  27459. for (i = 0; i < 7; i++) {
  27460. t[i] = r[i] ^ a[i];
  27461. }
  27462. for (i = 0; i < 7; i++) {
  27463. r[i] ^= t[i] & m;
  27464. }
  27465. #else
  27466. t[ 0] = r[ 0] ^ a[ 0];
  27467. t[ 1] = r[ 1] ^ a[ 1];
  27468. t[ 2] = r[ 2] ^ a[ 2];
  27469. t[ 3] = r[ 3] ^ a[ 3];
  27470. t[ 4] = r[ 4] ^ a[ 4];
  27471. t[ 5] = r[ 5] ^ a[ 5];
  27472. t[ 6] = r[ 6] ^ a[ 6];
  27473. r[ 0] ^= t[ 0] & m;
  27474. r[ 1] ^= t[ 1] & m;
  27475. r[ 2] ^= t[ 2] & m;
  27476. r[ 3] ^= t[ 3] & m;
  27477. r[ 4] ^= t[ 4] & m;
  27478. r[ 5] ^= t[ 5] & m;
  27479. r[ 6] ^= t[ 6] & m;
  27480. #endif /* WOLFSSL_SP_SMALL */
  27481. }
  27482. /* Double the Montgomery form projective point p a number of times.
  27483. *
  27484. * r Result of repeated doubling of point.
  27485. * p Point to double.
  27486. * n Number of times to double
  27487. * t Temporary ordinate data.
  27488. */
  27489. static void sp_384_proj_point_dbl_n_7(sp_point_384* p, int i,
  27490. sp_digit* t)
  27491. {
  27492. sp_digit* w = t;
  27493. sp_digit* a = t + 2*7;
  27494. sp_digit* b = t + 4*7;
  27495. sp_digit* t1 = t + 6*7;
  27496. sp_digit* t2 = t + 8*7;
  27497. sp_digit* x;
  27498. sp_digit* y;
  27499. sp_digit* z;
  27500. volatile int n = i;
  27501. x = p->x;
  27502. y = p->y;
  27503. z = p->z;
  27504. /* Y = 2*Y */
  27505. sp_384_mont_dbl_7(y, y, p384_mod);
  27506. /* W = Z^4 */
  27507. sp_384_mont_sqr_7(w, z, p384_mod, p384_mp_mod);
  27508. sp_384_mont_sqr_7(w, w, p384_mod, p384_mp_mod);
  27509. #ifndef WOLFSSL_SP_SMALL
  27510. while (--n > 0)
  27511. #else
  27512. while (--n >= 0)
  27513. #endif
  27514. {
  27515. /* A = 3*(X^2 - W) */
  27516. sp_384_mont_sqr_7(t1, x, p384_mod, p384_mp_mod);
  27517. sp_384_mont_sub_7(t1, t1, w, p384_mod);
  27518. sp_384_mont_tpl_7(a, t1, p384_mod);
  27519. /* B = X*Y^2 */
  27520. sp_384_mont_sqr_7(t1, y, p384_mod, p384_mp_mod);
  27521. sp_384_mont_mul_7(b, t1, x, p384_mod, p384_mp_mod);
  27522. /* X = A^2 - 2B */
  27523. sp_384_mont_sqr_7(x, a, p384_mod, p384_mp_mod);
  27524. sp_384_mont_dbl_7(t2, b, p384_mod);
  27525. sp_384_mont_sub_7(x, x, t2, p384_mod);
  27526. /* B = 2.(B - X) */
  27527. sp_384_mont_sub_7(t2, b, x, p384_mod);
  27528. sp_384_mont_dbl_7(b, t2, p384_mod);
  27529. /* Z = Z*Y */
  27530. sp_384_mont_mul_7(z, z, y, p384_mod, p384_mp_mod);
  27531. /* t1 = Y^4 */
  27532. sp_384_mont_sqr_7(t1, t1, p384_mod, p384_mp_mod);
  27533. #ifdef WOLFSSL_SP_SMALL
  27534. if (n != 0)
  27535. #endif
  27536. {
  27537. /* W = W*Y^4 */
  27538. sp_384_mont_mul_7(w, w, t1, p384_mod, p384_mp_mod);
  27539. }
  27540. /* y = 2*A*(B - X) - Y^4 */
  27541. sp_384_mont_mul_7(y, b, a, p384_mod, p384_mp_mod);
  27542. sp_384_mont_sub_7(y, y, t1, p384_mod);
  27543. }
  27544. #ifndef WOLFSSL_SP_SMALL
  27545. /* A = 3*(X^2 - W) */
  27546. sp_384_mont_sqr_7(t1, x, p384_mod, p384_mp_mod);
  27547. sp_384_mont_sub_7(t1, t1, w, p384_mod);
  27548. sp_384_mont_tpl_7(a, t1, p384_mod);
  27549. /* B = X*Y^2 */
  27550. sp_384_mont_sqr_7(t1, y, p384_mod, p384_mp_mod);
  27551. sp_384_mont_mul_7(b, t1, x, p384_mod, p384_mp_mod);
  27552. /* X = A^2 - 2B */
  27553. sp_384_mont_sqr_7(x, a, p384_mod, p384_mp_mod);
  27554. sp_384_mont_dbl_7(t2, b, p384_mod);
  27555. sp_384_mont_sub_7(x, x, t2, p384_mod);
  27556. /* B = 2.(B - X) */
  27557. sp_384_mont_sub_7(t2, b, x, p384_mod);
  27558. sp_384_mont_dbl_7(b, t2, p384_mod);
  27559. /* Z = Z*Y */
  27560. sp_384_mont_mul_7(z, z, y, p384_mod, p384_mp_mod);
  27561. /* t1 = Y^4 */
  27562. sp_384_mont_sqr_7(t1, t1, p384_mod, p384_mp_mod);
  27563. /* y = 2*A*(B - X) - Y^4 */
  27564. sp_384_mont_mul_7(y, b, a, p384_mod, p384_mp_mod);
  27565. sp_384_mont_sub_7(y, y, t1, p384_mod);
  27566. #endif /* WOLFSSL_SP_SMALL */
  27567. /* Y = Y/2 */
  27568. sp_384_mont_div2_7(y, y, p384_mod);
  27569. }
  27570. /* Double the Montgomery form projective point p a number of times.
  27571. *
  27572. * r Result of repeated doubling of point.
  27573. * p Point to double.
  27574. * n Number of times to double
  27575. * t Temporary ordinate data.
  27576. */
  27577. static void sp_384_proj_point_dbl_n_store_7(sp_point_384* r,
  27578. const sp_point_384* p, int n, int m, sp_digit* t)
  27579. {
  27580. sp_digit* w = t;
  27581. sp_digit* a = t + 2*7;
  27582. sp_digit* b = t + 4*7;
  27583. sp_digit* t1 = t + 6*7;
  27584. sp_digit* t2 = t + 8*7;
  27585. sp_digit* x = r[2*m].x;
  27586. sp_digit* y = r[(1<<n)*m].y;
  27587. sp_digit* z = r[2*m].z;
  27588. int i;
  27589. int j;
  27590. for (i=0; i<7; i++) {
  27591. x[i] = p->x[i];
  27592. }
  27593. for (i=0; i<7; i++) {
  27594. y[i] = p->y[i];
  27595. }
  27596. for (i=0; i<7; i++) {
  27597. z[i] = p->z[i];
  27598. }
  27599. /* Y = 2*Y */
  27600. sp_384_mont_dbl_7(y, y, p384_mod);
  27601. /* W = Z^4 */
  27602. sp_384_mont_sqr_7(w, z, p384_mod, p384_mp_mod);
  27603. sp_384_mont_sqr_7(w, w, p384_mod, p384_mp_mod);
  27604. j = m;
  27605. for (i=1; i<=n; i++) {
  27606. j *= 2;
  27607. /* A = 3*(X^2 - W) */
  27608. sp_384_mont_sqr_7(t1, x, p384_mod, p384_mp_mod);
  27609. sp_384_mont_sub_7(t1, t1, w, p384_mod);
  27610. sp_384_mont_tpl_7(a, t1, p384_mod);
  27611. /* B = X*Y^2 */
  27612. sp_384_mont_sqr_7(t1, y, p384_mod, p384_mp_mod);
  27613. sp_384_mont_mul_7(b, t1, x, p384_mod, p384_mp_mod);
  27614. x = r[j].x;
  27615. /* X = A^2 - 2B */
  27616. sp_384_mont_sqr_7(x, a, p384_mod, p384_mp_mod);
  27617. sp_384_mont_dbl_7(t2, b, p384_mod);
  27618. sp_384_mont_sub_7(x, x, t2, p384_mod);
  27619. /* B = 2.(B - X) */
  27620. sp_384_mont_sub_7(t2, b, x, p384_mod);
  27621. sp_384_mont_dbl_7(b, t2, p384_mod);
  27622. /* Z = Z*Y */
  27623. sp_384_mont_mul_7(r[j].z, z, y, p384_mod, p384_mp_mod);
  27624. z = r[j].z;
  27625. /* t1 = Y^4 */
  27626. sp_384_mont_sqr_7(t1, t1, p384_mod, p384_mp_mod);
  27627. if (i != n) {
  27628. /* W = W*Y^4 */
  27629. sp_384_mont_mul_7(w, w, t1, p384_mod, p384_mp_mod);
  27630. }
  27631. /* y = 2*A*(B - X) - Y^4 */
  27632. sp_384_mont_mul_7(y, b, a, p384_mod, p384_mp_mod);
  27633. sp_384_mont_sub_7(y, y, t1, p384_mod);
  27634. /* Y = Y/2 */
  27635. sp_384_mont_div2_7(r[j].y, y, p384_mod);
  27636. r[j].infinity = 0;
  27637. }
  27638. }
  27639. /* Add two Montgomery form projective points.
  27640. *
  27641. * ra Result of addition.
  27642. * rs Result of subtraction.
  27643. * p First point to add.
  27644. * q Second point to add.
  27645. * t Temporary ordinate data.
  27646. */
  27647. static void sp_384_proj_point_add_sub_7(sp_point_384* ra,
  27648. sp_point_384* rs, const sp_point_384* p, const sp_point_384* q,
  27649. sp_digit* t)
  27650. {
  27651. sp_digit* t1 = t;
  27652. sp_digit* t2 = t + 2*7;
  27653. sp_digit* t3 = t + 4*7;
  27654. sp_digit* t4 = t + 6*7;
  27655. sp_digit* t5 = t + 8*7;
  27656. sp_digit* t6 = t + 10*7;
  27657. sp_digit* xa = ra->x;
  27658. sp_digit* ya = ra->y;
  27659. sp_digit* za = ra->z;
  27660. sp_digit* xs = rs->x;
  27661. sp_digit* ys = rs->y;
  27662. sp_digit* zs = rs->z;
  27663. XMEMCPY(xa, p->x, sizeof(p->x) / 2);
  27664. XMEMCPY(ya, p->y, sizeof(p->y) / 2);
  27665. XMEMCPY(za, p->z, sizeof(p->z) / 2);
  27666. ra->infinity = 0;
  27667. rs->infinity = 0;
  27668. /* U1 = X1*Z2^2 */
  27669. sp_384_mont_sqr_7(t1, q->z, p384_mod, p384_mp_mod);
  27670. sp_384_mont_mul_7(t3, t1, q->z, p384_mod, p384_mp_mod);
  27671. sp_384_mont_mul_7(t1, t1, xa, p384_mod, p384_mp_mod);
  27672. /* U2 = X2*Z1^2 */
  27673. sp_384_mont_sqr_7(t2, za, p384_mod, p384_mp_mod);
  27674. sp_384_mont_mul_7(t4, t2, za, p384_mod, p384_mp_mod);
  27675. sp_384_mont_mul_7(t2, t2, q->x, p384_mod, p384_mp_mod);
  27676. /* S1 = Y1*Z2^3 */
  27677. sp_384_mont_mul_7(t3, t3, ya, p384_mod, p384_mp_mod);
  27678. /* S2 = Y2*Z1^3 */
  27679. sp_384_mont_mul_7(t4, t4, q->y, p384_mod, p384_mp_mod);
  27680. /* H = U2 - U1 */
  27681. sp_384_mont_sub_7(t2, t2, t1, p384_mod);
  27682. /* RS = S2 + S1 */
  27683. sp_384_mont_add_7(t6, t4, t3, p384_mod);
  27684. /* R = S2 - S1 */
  27685. sp_384_mont_sub_7(t4, t4, t3, p384_mod);
  27686. /* Z3 = H*Z1*Z2 */
  27687. /* ZS = H*Z1*Z2 */
  27688. sp_384_mont_mul_7(za, za, q->z, p384_mod, p384_mp_mod);
  27689. sp_384_mont_mul_7(za, za, t2, p384_mod, p384_mp_mod);
  27690. XMEMCPY(zs, za, sizeof(p->z)/2);
  27691. /* X3 = R^2 - H^3 - 2*U1*H^2 */
  27692. /* XS = RS^2 - H^3 - 2*U1*H^2 */
  27693. sp_384_mont_sqr_7(xa, t4, p384_mod, p384_mp_mod);
  27694. sp_384_mont_sqr_7(xs, t6, p384_mod, p384_mp_mod);
  27695. sp_384_mont_sqr_7(t5, t2, p384_mod, p384_mp_mod);
  27696. sp_384_mont_mul_7(ya, t1, t5, p384_mod, p384_mp_mod);
  27697. sp_384_mont_mul_7(t5, t5, t2, p384_mod, p384_mp_mod);
  27698. sp_384_mont_sub_7(xa, xa, t5, p384_mod);
  27699. sp_384_mont_sub_7(xs, xs, t5, p384_mod);
  27700. sp_384_mont_dbl_7(t1, ya, p384_mod);
  27701. sp_384_mont_sub_7(xa, xa, t1, p384_mod);
  27702. sp_384_mont_sub_7(xs, xs, t1, p384_mod);
  27703. /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
  27704. /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */
  27705. sp_384_mont_sub_7(ys, ya, xs, p384_mod);
  27706. sp_384_mont_sub_7(ya, ya, xa, p384_mod);
  27707. sp_384_mont_mul_7(ya, ya, t4, p384_mod, p384_mp_mod);
  27708. sp_384_sub_7(t6, p384_mod, t6);
  27709. sp_384_mont_mul_7(ys, ys, t6, p384_mod, p384_mp_mod);
  27710. sp_384_mont_mul_7(t5, t5, t3, p384_mod, p384_mp_mod);
  27711. sp_384_mont_sub_7(ya, ya, t5, p384_mod);
  27712. sp_384_mont_sub_7(ys, ys, t5, p384_mod);
  27713. }
  27714. /* Structure used to describe recoding of scalar multiplication. */
  27715. typedef struct ecc_recode_384 {
  27716. /* Index into pre-computation table. */
  27717. uint8_t i;
  27718. /* Use the negative of the point. */
  27719. uint8_t neg;
  27720. } ecc_recode_384;
  27721. /* The index into pre-computation table to use. */
  27722. static const uint8_t recode_index_7_6[66] = {
  27723. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  27724. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  27725. 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
  27726. 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
  27727. 0, 1,
  27728. };
  27729. /* Whether to negate y-ordinate. */
  27730. static const uint8_t recode_neg_7_6[66] = {
  27731. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  27732. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  27733. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  27734. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  27735. 0, 0,
  27736. };
  27737. /* Recode the scalar for multiplication using pre-computed values and
  27738. * subtraction.
  27739. *
  27740. * k Scalar to multiply by.
  27741. * v Vector of operations to perform.
  27742. */
  27743. static void sp_384_ecc_recode_6_7(const sp_digit* k, ecc_recode_384* v)
  27744. {
  27745. int i;
  27746. int j;
  27747. uint8_t y;
  27748. int carry = 0;
  27749. int o;
  27750. sp_digit n;
  27751. j = 0;
  27752. n = k[j];
  27753. o = 0;
  27754. for (i=0; i<65; i++) {
  27755. y = (int8_t)n;
  27756. if (o + 6 < 55) {
  27757. y &= 0x3f;
  27758. n >>= 6;
  27759. o += 6;
  27760. }
  27761. else if (o + 6 == 55) {
  27762. n >>= 6;
  27763. if (++j < 7)
  27764. n = k[j];
  27765. o = 0;
  27766. }
  27767. else if (++j < 7) {
  27768. n = k[j];
  27769. y |= (uint8_t)((n << (55 - o)) & 0x3f);
  27770. o -= 49;
  27771. n >>= o;
  27772. }
  27773. y += (uint8_t)carry;
  27774. v[i].i = recode_index_7_6[y];
  27775. v[i].neg = recode_neg_7_6[y];
  27776. carry = (y >> 6) + v[i].neg;
  27777. }
  27778. }
  27779. #ifndef WC_NO_CACHE_RESISTANT
  27780. /* Touch each possible point that could be being copied.
  27781. *
  27782. * r Point to copy into.
  27783. * table Table - start of the entries to access
  27784. * idx Index of entry to retrieve.
  27785. */
  27786. static void sp_384_get_point_33_7(sp_point_384* r, const sp_point_384* table,
  27787. int idx)
  27788. {
  27789. int i;
  27790. sp_digit mask;
  27791. r->x[0] = 0;
  27792. r->x[1] = 0;
  27793. r->x[2] = 0;
  27794. r->x[3] = 0;
  27795. r->x[4] = 0;
  27796. r->x[5] = 0;
  27797. r->x[6] = 0;
  27798. r->y[0] = 0;
  27799. r->y[1] = 0;
  27800. r->y[2] = 0;
  27801. r->y[3] = 0;
  27802. r->y[4] = 0;
  27803. r->y[5] = 0;
  27804. r->y[6] = 0;
  27805. r->z[0] = 0;
  27806. r->z[1] = 0;
  27807. r->z[2] = 0;
  27808. r->z[3] = 0;
  27809. r->z[4] = 0;
  27810. r->z[5] = 0;
  27811. r->z[6] = 0;
  27812. for (i = 1; i < 33; i++) {
  27813. mask = 0 - (i == idx);
  27814. r->x[0] |= mask & table[i].x[0];
  27815. r->x[1] |= mask & table[i].x[1];
  27816. r->x[2] |= mask & table[i].x[2];
  27817. r->x[3] |= mask & table[i].x[3];
  27818. r->x[4] |= mask & table[i].x[4];
  27819. r->x[5] |= mask & table[i].x[5];
  27820. r->x[6] |= mask & table[i].x[6];
  27821. r->y[0] |= mask & table[i].y[0];
  27822. r->y[1] |= mask & table[i].y[1];
  27823. r->y[2] |= mask & table[i].y[2];
  27824. r->y[3] |= mask & table[i].y[3];
  27825. r->y[4] |= mask & table[i].y[4];
  27826. r->y[5] |= mask & table[i].y[5];
  27827. r->y[6] |= mask & table[i].y[6];
  27828. r->z[0] |= mask & table[i].z[0];
  27829. r->z[1] |= mask & table[i].z[1];
  27830. r->z[2] |= mask & table[i].z[2];
  27831. r->z[3] |= mask & table[i].z[3];
  27832. r->z[4] |= mask & table[i].z[4];
  27833. r->z[5] |= mask & table[i].z[5];
  27834. r->z[6] |= mask & table[i].z[6];
  27835. }
  27836. }
  27837. #endif /* !WC_NO_CACHE_RESISTANT */
  27838. /* Multiply the point by the scalar and return the result.
  27839. * If map is true then convert result to affine coordinates.
  27840. *
  27841. * Window technique of 6 bits. (Add-Sub variation.)
  27842. * Calculate 0..32 times the point. Use function that adds and
  27843. * subtracts the same two points.
  27844. * Recode to add or subtract one of the computed points.
  27845. * Double to push up.
  27846. * NOT a sliding window.
  27847. *
  27848. * r Resulting point.
  27849. * g Point to multiply.
  27850. * k Scalar to multiply by.
  27851. * map Indicates whether to convert result to affine.
  27852. * ct Constant time required.
  27853. * heap Heap to use for allocation.
  27854. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  27855. */
  27856. static int sp_384_ecc_mulmod_win_add_sub_7(sp_point_384* r, const sp_point_384* g,
  27857. const sp_digit* k, int map, int ct, void* heap)
  27858. {
  27859. #ifdef WOLFSSL_SP_SMALL_STACK
  27860. sp_point_384* t = NULL;
  27861. sp_digit* tmp = NULL;
  27862. #else
  27863. sp_point_384 t[33+2];
  27864. sp_digit tmp[2 * 7 * 6];
  27865. #endif
  27866. sp_point_384* rt = NULL;
  27867. sp_point_384* p = NULL;
  27868. sp_digit* negy;
  27869. int i;
  27870. ecc_recode_384 v[65];
  27871. int err = MP_OKAY;
  27872. /* Constant time used for cache attack resistance implementation. */
  27873. (void)ct;
  27874. (void)heap;
  27875. #ifdef WOLFSSL_SP_SMALL_STACK
  27876. t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) *
  27877. (33+2), heap, DYNAMIC_TYPE_ECC);
  27878. if (t == NULL)
  27879. err = MEMORY_E;
  27880. if (err == MP_OKAY) {
  27881. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 6,
  27882. heap, DYNAMIC_TYPE_ECC);
  27883. if (tmp == NULL)
  27884. err = MEMORY_E;
  27885. }
  27886. #endif
  27887. if (err == MP_OKAY) {
  27888. rt = t + 33;
  27889. p = t + 33+1;
  27890. /* t[0] = {0, 0, 1} * norm */
  27891. XMEMSET(&t[0], 0, sizeof(t[0]));
  27892. t[0].infinity = 1;
  27893. /* t[1] = {g->x, g->y, g->z} * norm */
  27894. err = sp_384_mod_mul_norm_7(t[1].x, g->x, p384_mod);
  27895. }
  27896. if (err == MP_OKAY) {
  27897. err = sp_384_mod_mul_norm_7(t[1].y, g->y, p384_mod);
  27898. }
  27899. if (err == MP_OKAY) {
  27900. err = sp_384_mod_mul_norm_7(t[1].z, g->z, p384_mod);
  27901. }
  27902. if (err == MP_OKAY) {
  27903. t[1].infinity = 0;
  27904. /* t[2] ... t[32] */
  27905. sp_384_proj_point_dbl_n_store_7(t, &t[ 1], 5, 1, tmp);
  27906. sp_384_proj_point_add_7(&t[ 3], &t[ 2], &t[ 1], tmp);
  27907. sp_384_proj_point_dbl_7(&t[ 6], &t[ 3], tmp);
  27908. sp_384_proj_point_add_sub_7(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp);
  27909. sp_384_proj_point_dbl_7(&t[10], &t[ 5], tmp);
  27910. sp_384_proj_point_add_sub_7(&t[11], &t[ 9], &t[10], &t[ 1], tmp);
  27911. sp_384_proj_point_dbl_7(&t[12], &t[ 6], tmp);
  27912. sp_384_proj_point_dbl_7(&t[14], &t[ 7], tmp);
  27913. sp_384_proj_point_add_sub_7(&t[15], &t[13], &t[14], &t[ 1], tmp);
  27914. sp_384_proj_point_dbl_7(&t[18], &t[ 9], tmp);
  27915. sp_384_proj_point_add_sub_7(&t[19], &t[17], &t[18], &t[ 1], tmp);
  27916. sp_384_proj_point_dbl_7(&t[20], &t[10], tmp);
  27917. sp_384_proj_point_dbl_7(&t[22], &t[11], tmp);
  27918. sp_384_proj_point_add_sub_7(&t[23], &t[21], &t[22], &t[ 1], tmp);
  27919. sp_384_proj_point_dbl_7(&t[24], &t[12], tmp);
  27920. sp_384_proj_point_dbl_7(&t[26], &t[13], tmp);
  27921. sp_384_proj_point_add_sub_7(&t[27], &t[25], &t[26], &t[ 1], tmp);
  27922. sp_384_proj_point_dbl_7(&t[28], &t[14], tmp);
  27923. sp_384_proj_point_dbl_7(&t[30], &t[15], tmp);
  27924. sp_384_proj_point_add_sub_7(&t[31], &t[29], &t[30], &t[ 1], tmp);
  27925. negy = t[0].y;
  27926. sp_384_ecc_recode_6_7(k, v);
  27927. i = 64;
  27928. #ifndef WC_NO_CACHE_RESISTANT
  27929. if (ct) {
  27930. sp_384_get_point_33_7(rt, t, v[i].i);
  27931. rt->infinity = !v[i].i;
  27932. }
  27933. else
  27934. #endif
  27935. {
  27936. XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_384));
  27937. }
  27938. for (--i; i>=0; i--) {
  27939. sp_384_proj_point_dbl_n_7(rt, 6, tmp);
  27940. #ifndef WC_NO_CACHE_RESISTANT
  27941. if (ct) {
  27942. sp_384_get_point_33_7(p, t, v[i].i);
  27943. p->infinity = !v[i].i;
  27944. }
  27945. else
  27946. #endif
  27947. {
  27948. XMEMCPY(p, &t[v[i].i], sizeof(sp_point_384));
  27949. }
  27950. sp_384_sub_7(negy, p384_mod, p->y);
  27951. sp_384_norm_7(negy);
  27952. sp_384_cond_copy_7(p->y, negy, (sp_digit)0 - v[i].neg);
  27953. sp_384_proj_point_add_7(rt, rt, p, tmp);
  27954. }
  27955. if (map != 0) {
  27956. sp_384_map_7(r, rt, tmp);
  27957. }
  27958. else {
  27959. XMEMCPY(r, rt, sizeof(sp_point_384));
  27960. }
  27961. }
  27962. #ifdef WOLFSSL_SP_SMALL_STACK
  27963. if (t != NULL)
  27964. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  27965. if (tmp != NULL)
  27966. XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
  27967. #endif
  27968. return err;
  27969. }
  27970. #ifdef FP_ECC
  27971. #endif /* FP_ECC */
  27972. /* Add two Montgomery form projective points. The second point has a q value of
  27973. * one.
  27974. * Only the first point can be the same pointer as the result point.
  27975. *
  27976. * r Result of addition.
  27977. * p First point to add.
  27978. * q Second point to add.
  27979. * t Temporary ordinate data.
  27980. */
  27981. static void sp_384_proj_point_add_qz1_7(sp_point_384* r,
  27982. const sp_point_384* p, const sp_point_384* q, sp_digit* t)
  27983. {
  27984. sp_digit* t2 = t;
  27985. sp_digit* t3 = t + 2*7;
  27986. sp_digit* t6 = t + 4*7;
  27987. sp_digit* t1 = t + 6*7;
  27988. sp_digit* t4 = t + 8*7;
  27989. sp_digit* t5 = t + 10*7;
  27990. /* Calculate values to subtract from P->x and P->y. */
  27991. /* U2 = X2*Z1^2 */
  27992. sp_384_mont_sqr_7(t2, p->z, p384_mod, p384_mp_mod);
  27993. sp_384_mont_mul_7(t4, t2, p->z, p384_mod, p384_mp_mod);
  27994. sp_384_mont_mul_7(t2, t2, q->x, p384_mod, p384_mp_mod);
  27995. /* S2 = Y2*Z1^3 */
  27996. sp_384_mont_mul_7(t4, t4, q->y, p384_mod, p384_mp_mod);
  27997. if ((~p->infinity) & (~q->infinity) &
  27998. sp_384_cmp_equal_7(p->x, t2) &
  27999. sp_384_cmp_equal_7(p->y, t4)) {
  28000. sp_384_proj_point_dbl_7(r, p, t);
  28001. }
  28002. else {
  28003. sp_digit* x = t2;
  28004. sp_digit* y = t3;
  28005. sp_digit* z = t6;
  28006. /* H = U2 - X1 */
  28007. sp_384_mont_sub_7(t2, t2, p->x, p384_mod);
  28008. /* R = S2 - Y1 */
  28009. sp_384_mont_sub_7(t4, t4, p->y, p384_mod);
  28010. /* Z3 = H*Z1 */
  28011. sp_384_mont_mul_7(z, p->z, t2, p384_mod, p384_mp_mod);
  28012. /* X3 = R^2 - H^3 - 2*X1*H^2 */
  28013. sp_384_mont_sqr_7(t1, t2, p384_mod, p384_mp_mod);
  28014. sp_384_mont_mul_7(t3, p->x, t1, p384_mod, p384_mp_mod);
  28015. sp_384_mont_mul_7(t1, t1, t2, p384_mod, p384_mp_mod);
  28016. sp_384_mont_sqr_7(t2, t4, p384_mod, p384_mp_mod);
  28017. sp_384_mont_sub_7(t2, t2, t1, p384_mod);
  28018. sp_384_mont_dbl_7(t5, t3, p384_mod);
  28019. sp_384_mont_sub_7(x, t2, t5, p384_mod);
  28020. /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */
  28021. sp_384_mont_sub_7(t3, t3, x, p384_mod);
  28022. sp_384_mont_mul_7(t3, t3, t4, p384_mod, p384_mp_mod);
  28023. sp_384_mont_mul_7(t1, t1, p->y, p384_mod, p384_mp_mod);
  28024. sp_384_mont_sub_7(y, t3, t1, p384_mod);
  28025. {
  28026. int i;
  28027. sp_digit maskp = 0 - (q->infinity & (!p->infinity));
  28028. sp_digit maskq = 0 - (p->infinity & (!q->infinity));
  28029. sp_digit maskt = ~(maskp | maskq);
  28030. sp_digit inf = (sp_digit)(p->infinity & q->infinity);
  28031. for (i = 0; i < 7; i++) {
  28032. r->x[i] = (p->x[i] & maskp) | (q->x[i] & maskq) |
  28033. (x[i] & maskt);
  28034. }
  28035. for (i = 0; i < 7; i++) {
  28036. r->y[i] = (p->y[i] & maskp) | (q->y[i] & maskq) |
  28037. (y[i] & maskt);
  28038. }
  28039. for (i = 0; i < 7; i++) {
  28040. r->z[i] = (p->z[i] & maskp) | (q->z[i] & maskq) |
  28041. (z[i] & maskt);
  28042. }
  28043. r->z[0] |= inf;
  28044. r->infinity = (word32)inf;
  28045. }
  28046. }
  28047. }
  28048. #ifdef FP_ECC
  28049. /* Convert the projective point to affine.
  28050. * Ordinates are in Montgomery form.
  28051. *
  28052. * a Point to convert.
  28053. * t Temporary data.
  28054. */
  28055. static void sp_384_proj_to_affine_7(sp_point_384* a, sp_digit* t)
  28056. {
  28057. sp_digit* t1 = t;
  28058. sp_digit* t2 = t + 2 * 7;
  28059. sp_digit* tmp = t + 4 * 7;
  28060. sp_384_mont_inv_7(t1, a->z, tmp);
  28061. sp_384_mont_sqr_7(t2, t1, p384_mod, p384_mp_mod);
  28062. sp_384_mont_mul_7(t1, t2, t1, p384_mod, p384_mp_mod);
  28063. sp_384_mont_mul_7(a->x, a->x, t2, p384_mod, p384_mp_mod);
  28064. sp_384_mont_mul_7(a->y, a->y, t1, p384_mod, p384_mp_mod);
  28065. XMEMCPY(a->z, p384_norm_mod, sizeof(p384_norm_mod));
  28066. }
  28067. /* Generate the pre-computed table of points for the base point.
  28068. *
  28069. * width = 8
  28070. * 256 entries
  28071. * 48 bits between
  28072. *
  28073. * a The base point.
  28074. * table Place to store generated point data.
  28075. * tmp Temporary data.
  28076. * heap Heap to use for allocation.
  28077. */
  28078. static int sp_384_gen_stripe_table_7(const sp_point_384* a,
  28079. sp_table_entry_384* table, sp_digit* tmp, void* heap)
  28080. {
  28081. #ifdef WOLFSSL_SP_SMALL_STACK
  28082. sp_point_384* t = NULL;
  28083. #else
  28084. sp_point_384 t[3];
  28085. #endif
  28086. sp_point_384* s1 = NULL;
  28087. sp_point_384* s2 = NULL;
  28088. int i;
  28089. int j;
  28090. int err = MP_OKAY;
  28091. (void)heap;
  28092. #ifdef WOLFSSL_SP_SMALL_STACK
  28093. t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 3, heap,
  28094. DYNAMIC_TYPE_ECC);
  28095. if (t == NULL)
  28096. err = MEMORY_E;
  28097. #endif
  28098. if (err == MP_OKAY) {
  28099. s1 = t + 1;
  28100. s2 = t + 2;
  28101. err = sp_384_mod_mul_norm_7(t->x, a->x, p384_mod);
  28102. }
  28103. if (err == MP_OKAY) {
  28104. err = sp_384_mod_mul_norm_7(t->y, a->y, p384_mod);
  28105. }
  28106. if (err == MP_OKAY) {
  28107. err = sp_384_mod_mul_norm_7(t->z, a->z, p384_mod);
  28108. }
  28109. if (err == MP_OKAY) {
  28110. t->infinity = 0;
  28111. sp_384_proj_to_affine_7(t, tmp);
  28112. XMEMCPY(s1->z, p384_norm_mod, sizeof(p384_norm_mod));
  28113. s1->infinity = 0;
  28114. XMEMCPY(s2->z, p384_norm_mod, sizeof(p384_norm_mod));
  28115. s2->infinity = 0;
  28116. /* table[0] = {0, 0, infinity} */
  28117. XMEMSET(&table[0], 0, sizeof(sp_table_entry_384));
  28118. /* table[1] = Affine version of 'a' in Montgomery form */
  28119. XMEMCPY(table[1].x, t->x, sizeof(table->x));
  28120. XMEMCPY(table[1].y, t->y, sizeof(table->y));
  28121. for (i=1; i<8; i++) {
  28122. sp_384_proj_point_dbl_n_7(t, 48, tmp);
  28123. sp_384_proj_to_affine_7(t, tmp);
  28124. XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));
  28125. XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));
  28126. }
  28127. for (i=1; i<8; i++) {
  28128. XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));
  28129. XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));
  28130. for (j=(1<<i)+1; j<(1<<(i+1)); j++) {
  28131. XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));
  28132. XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));
  28133. sp_384_proj_point_add_qz1_7(t, s1, s2, tmp);
  28134. sp_384_proj_to_affine_7(t, tmp);
  28135. XMEMCPY(table[j].x, t->x, sizeof(table->x));
  28136. XMEMCPY(table[j].y, t->y, sizeof(table->y));
  28137. }
  28138. }
  28139. }
  28140. #ifdef WOLFSSL_SP_SMALL_STACK
  28141. if (t != NULL)
  28142. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  28143. #endif
  28144. return err;
  28145. }
  28146. #endif /* FP_ECC */
  28147. #ifndef WC_NO_CACHE_RESISTANT
  28148. /* Touch each possible entry that could be being copied.
  28149. *
  28150. * r Point to copy into.
  28151. * table Table - start of the entries to access
  28152. * idx Index of entry to retrieve.
  28153. */
  28154. static void sp_384_get_entry_256_7(sp_point_384* r,
  28155. const sp_table_entry_384* table, int idx)
  28156. {
  28157. int i;
  28158. sp_digit mask;
  28159. r->x[0] = 0;
  28160. r->x[1] = 0;
  28161. r->x[2] = 0;
  28162. r->x[3] = 0;
  28163. r->x[4] = 0;
  28164. r->x[5] = 0;
  28165. r->x[6] = 0;
  28166. r->y[0] = 0;
  28167. r->y[1] = 0;
  28168. r->y[2] = 0;
  28169. r->y[3] = 0;
  28170. r->y[4] = 0;
  28171. r->y[5] = 0;
  28172. r->y[6] = 0;
  28173. for (i = 1; i < 256; i++) {
  28174. mask = 0 - (i == idx);
  28175. r->x[0] |= mask & table[i].x[0];
  28176. r->x[1] |= mask & table[i].x[1];
  28177. r->x[2] |= mask & table[i].x[2];
  28178. r->x[3] |= mask & table[i].x[3];
  28179. r->x[4] |= mask & table[i].x[4];
  28180. r->x[5] |= mask & table[i].x[5];
  28181. r->x[6] |= mask & table[i].x[6];
  28182. r->y[0] |= mask & table[i].y[0];
  28183. r->y[1] |= mask & table[i].y[1];
  28184. r->y[2] |= mask & table[i].y[2];
  28185. r->y[3] |= mask & table[i].y[3];
  28186. r->y[4] |= mask & table[i].y[4];
  28187. r->y[5] |= mask & table[i].y[5];
  28188. r->y[6] |= mask & table[i].y[6];
  28189. }
  28190. }
  28191. #endif /* !WC_NO_CACHE_RESISTANT */
  28192. /* Multiply the point by the scalar and return the result.
  28193. * If map is true then convert result to affine coordinates.
  28194. *
  28195. * Stripe implementation.
  28196. * Pre-generated: 2^0, 2^48, ...
  28197. * Pre-generated: products of all combinations of above.
  28198. * 8 doubles and adds (with qz=1)
  28199. *
  28200. * r Resulting point.
  28201. * k Scalar to multiply by.
  28202. * table Pre-computed table.
  28203. * map Indicates whether to convert result to affine.
  28204. * ct Constant time required.
  28205. * heap Heap to use for allocation.
  28206. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  28207. */
  28208. static int sp_384_ecc_mulmod_stripe_7(sp_point_384* r, const sp_point_384* g,
  28209. const sp_table_entry_384* table, const sp_digit* k, int map,
  28210. int ct, void* heap)
  28211. {
  28212. #ifdef WOLFSSL_SP_SMALL_STACK
  28213. sp_point_384* rt = NULL;
  28214. sp_digit* t = NULL;
  28215. #else
  28216. sp_point_384 rt[2];
  28217. sp_digit t[2 * 7 * 6];
  28218. #endif
  28219. sp_point_384* p = NULL;
  28220. int i;
  28221. int j;
  28222. int y;
  28223. int x;
  28224. int err = MP_OKAY;
  28225. (void)g;
  28226. /* Constant time used for cache attack resistance implementation. */
  28227. (void)ct;
  28228. (void)heap;
  28229. #ifdef WOLFSSL_SP_SMALL_STACK
  28230. rt = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 2, heap,
  28231. DYNAMIC_TYPE_ECC);
  28232. if (rt == NULL)
  28233. err = MEMORY_E;
  28234. if (err == MP_OKAY) {
  28235. t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 6, heap,
  28236. DYNAMIC_TYPE_ECC);
  28237. if (t == NULL)
  28238. err = MEMORY_E;
  28239. }
  28240. #endif
  28241. if (err == MP_OKAY) {
  28242. p = rt + 1;
  28243. XMEMCPY(p->z, p384_norm_mod, sizeof(p384_norm_mod));
  28244. XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod));
  28245. y = 0;
  28246. x = 47;
  28247. for (j=0; j<8; j++) {
  28248. y |= (int)(((k[x / 55] >> (x % 55)) & 1) << j);
  28249. x += 48;
  28250. }
  28251. #ifndef WC_NO_CACHE_RESISTANT
  28252. if (ct) {
  28253. sp_384_get_entry_256_7(rt, table, y);
  28254. } else
  28255. #endif
  28256. {
  28257. XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));
  28258. XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));
  28259. }
  28260. rt->infinity = !y;
  28261. for (i=46; i>=0; i--) {
  28262. y = 0;
  28263. x = i;
  28264. for (j=0; j<8; j++) {
  28265. y |= (int)(((k[x / 55] >> (x % 55)) & 1) << j);
  28266. x += 48;
  28267. }
  28268. sp_384_proj_point_dbl_7(rt, rt, t);
  28269. #ifndef WC_NO_CACHE_RESISTANT
  28270. if (ct) {
  28271. sp_384_get_entry_256_7(p, table, y);
  28272. }
  28273. else
  28274. #endif
  28275. {
  28276. XMEMCPY(p->x, table[y].x, sizeof(table[y].x));
  28277. XMEMCPY(p->y, table[y].y, sizeof(table[y].y));
  28278. }
  28279. p->infinity = !y;
  28280. sp_384_proj_point_add_qz1_7(rt, rt, p, t);
  28281. }
  28282. if (map != 0) {
  28283. sp_384_map_7(r, rt, t);
  28284. }
  28285. else {
  28286. XMEMCPY(r, rt, sizeof(sp_point_384));
  28287. }
  28288. }
  28289. #ifdef WOLFSSL_SP_SMALL_STACK
  28290. if (t != NULL)
  28291. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  28292. if (rt != NULL)
  28293. XFREE(rt, heap, DYNAMIC_TYPE_ECC);
  28294. #endif
  28295. return err;
  28296. }
  28297. #ifdef FP_ECC
  28298. #ifndef FP_ENTRIES
  28299. #define FP_ENTRIES 16
  28300. #endif
  28301. /* Cache entry - holds precomputation tables for a point. */
  28302. typedef struct sp_cache_384_t {
  28303. /* X ordinate of point that table was generated from. */
  28304. sp_digit x[7];
  28305. /* Y ordinate of point that table was generated from. */
  28306. sp_digit y[7];
  28307. /* Precomputation table for point. */
  28308. sp_table_entry_384 table[256];
  28309. /* Count of entries in table. */
  28310. uint32_t cnt;
  28311. /* Point and table set in entry. */
  28312. int set;
  28313. } sp_cache_384_t;
  28314. /* Cache of tables. */
  28315. static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES];
  28316. /* Index of last entry in cache. */
  28317. static THREAD_LS_T int sp_cache_384_last = -1;
  28318. /* Cache has been initialized. */
  28319. static THREAD_LS_T int sp_cache_384_inited = 0;
  28320. #ifndef HAVE_THREAD_LS
  28321. #ifndef WOLFSSL_MUTEX_INITIALIZER
  28322. static volatile int initCacheMutex_384 = 0;
  28323. #endif
  28324. static wolfSSL_Mutex sp_cache_384_lock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(sp_cache_384_lock);
  28325. #endif
  28326. /* Get the cache entry for the point.
  28327. *
  28328. * g [in] Point scalar multiplying.
  28329. * cache [out] Cache table to use.
  28330. */
  28331. static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache)
  28332. {
  28333. int i;
  28334. int j;
  28335. uint32_t least;
  28336. if (sp_cache_384_inited == 0) {
  28337. for (i=0; i<FP_ENTRIES; i++) {
  28338. sp_cache_384[i].set = 0;
  28339. }
  28340. sp_cache_384_inited = 1;
  28341. }
  28342. /* Compare point with those in cache. */
  28343. for (i=0; i<FP_ENTRIES; i++) {
  28344. if (!sp_cache_384[i].set)
  28345. continue;
  28346. if (sp_384_cmp_equal_7(g->x, sp_cache_384[i].x) &
  28347. sp_384_cmp_equal_7(g->y, sp_cache_384[i].y)) {
  28348. sp_cache_384[i].cnt++;
  28349. break;
  28350. }
  28351. }
  28352. /* No match. */
  28353. if (i == FP_ENTRIES) {
  28354. /* Find empty entry. */
  28355. i = (sp_cache_384_last + 1) % FP_ENTRIES;
  28356. for (; i != sp_cache_384_last; i=(i+1)%FP_ENTRIES) {
  28357. if (!sp_cache_384[i].set) {
  28358. break;
  28359. }
  28360. }
  28361. /* Evict least used. */
  28362. if (i == sp_cache_384_last) {
  28363. least = sp_cache_384[0].cnt;
  28364. for (j=1; j<FP_ENTRIES; j++) {
  28365. if (sp_cache_384[j].cnt < least) {
  28366. i = j;
  28367. least = sp_cache_384[i].cnt;
  28368. }
  28369. }
  28370. }
  28371. XMEMCPY(sp_cache_384[i].x, g->x, sizeof(sp_cache_384[i].x));
  28372. XMEMCPY(sp_cache_384[i].y, g->y, sizeof(sp_cache_384[i].y));
  28373. sp_cache_384[i].set = 1;
  28374. sp_cache_384[i].cnt = 1;
  28375. }
  28376. *cache = &sp_cache_384[i];
  28377. sp_cache_384_last = i;
  28378. }
  28379. #endif /* FP_ECC */
  28380. /* Multiply the base point of P384 by the scalar and return the result.
  28381. * If map is true then convert result to affine coordinates.
  28382. *
  28383. * r Resulting point.
  28384. * g Point to multiply.
  28385. * k Scalar to multiply by.
  28386. * map Indicates whether to convert result to affine.
  28387. * ct Constant time required.
  28388. * heap Heap to use for allocation.
  28389. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  28390. */
  28391. static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g,
  28392. const sp_digit* k, int map, int ct, void* heap)
  28393. {
  28394. #ifndef FP_ECC
  28395. return sp_384_ecc_mulmod_win_add_sub_7(r, g, k, map, ct, heap);
  28396. #else
  28397. #ifdef WOLFSSL_SP_SMALL_STACK
  28398. sp_digit* tmp;
  28399. #else
  28400. sp_digit tmp[2 * 7 * 7];
  28401. #endif
  28402. sp_cache_384_t* cache;
  28403. int err = MP_OKAY;
  28404. #ifdef WOLFSSL_SP_SMALL_STACK
  28405. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 7, heap, DYNAMIC_TYPE_ECC);
  28406. if (tmp == NULL) {
  28407. err = MEMORY_E;
  28408. }
  28409. #endif
  28410. #ifndef HAVE_THREAD_LS
  28411. if (err == MP_OKAY) {
  28412. #ifndef WOLFSSL_MUTEX_INITIALIZER
  28413. if (initCacheMutex_384 == 0) {
  28414. wc_InitMutex(&sp_cache_384_lock);
  28415. initCacheMutex_384 = 1;
  28416. }
  28417. #endif
  28418. if (wc_LockMutex(&sp_cache_384_lock) != 0) {
  28419. err = BAD_MUTEX_E;
  28420. }
  28421. }
  28422. #endif /* HAVE_THREAD_LS */
  28423. if (err == MP_OKAY) {
  28424. sp_ecc_get_cache_384(g, &cache);
  28425. if (cache->cnt == 2)
  28426. sp_384_gen_stripe_table_7(g, cache->table, tmp, heap);
  28427. #ifndef HAVE_THREAD_LS
  28428. wc_UnLockMutex(&sp_cache_384_lock);
  28429. #endif /* HAVE_THREAD_LS */
  28430. if (cache->cnt < 2) {
  28431. err = sp_384_ecc_mulmod_win_add_sub_7(r, g, k, map, ct, heap);
  28432. }
  28433. else {
  28434. err = sp_384_ecc_mulmod_stripe_7(r, g, cache->table, k,
  28435. map, ct, heap);
  28436. }
  28437. }
  28438. #ifdef WOLFSSL_SP_SMALL_STACK
  28439. XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
  28440. #endif
  28441. return err;
  28442. #endif
  28443. }
  28444. #endif
  28445. /* Multiply the point by the scalar and return the result.
  28446. * If map is true then convert result to affine coordinates.
  28447. *
  28448. * km Scalar to multiply by.
  28449. * p Point to multiply.
  28450. * r Resulting point.
  28451. * map Indicates whether to convert result to affine.
  28452. * heap Heap to use for allocation.
  28453. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  28454. */
  28455. int sp_ecc_mulmod_384(const mp_int* km, const ecc_point* gm, ecc_point* r,
  28456. int map, void* heap)
  28457. {
  28458. #ifdef WOLFSSL_SP_SMALL_STACK
  28459. sp_point_384* point = NULL;
  28460. sp_digit* k = NULL;
  28461. #else
  28462. sp_point_384 point[1];
  28463. sp_digit k[7];
  28464. #endif
  28465. int err = MP_OKAY;
  28466. #ifdef WOLFSSL_SP_SMALL_STACK
  28467. point = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap,
  28468. DYNAMIC_TYPE_ECC);
  28469. if (point == NULL)
  28470. err = MEMORY_E;
  28471. if (err == MP_OKAY) {
  28472. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap,
  28473. DYNAMIC_TYPE_ECC);
  28474. if (k == NULL)
  28475. err = MEMORY_E;
  28476. }
  28477. #endif
  28478. if (err == MP_OKAY) {
  28479. sp_384_from_mp(k, 7, km);
  28480. sp_384_point_from_ecc_point_7(point, gm);
  28481. err = sp_384_ecc_mulmod_7(point, point, k, map, 1, heap);
  28482. }
  28483. if (err == MP_OKAY) {
  28484. err = sp_384_point_to_ecc_point_7(point, r);
  28485. }
  28486. #ifdef WOLFSSL_SP_SMALL_STACK
  28487. if (k != NULL)
  28488. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  28489. if (point != NULL)
  28490. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  28491. #endif
  28492. return err;
  28493. }
  28494. /* Multiply the point by the scalar, add point a and return the result.
  28495. * If map is true then convert result to affine coordinates.
  28496. *
  28497. * km Scalar to multiply by.
  28498. * p Point to multiply.
  28499. * am Point to add to scalar multiply result.
  28500. * inMont Point to add is in montgomery form.
  28501. * r Resulting point.
  28502. * map Indicates whether to convert result to affine.
  28503. * heap Heap to use for allocation.
  28504. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  28505. */
  28506. int sp_ecc_mulmod_add_384(const mp_int* km, const ecc_point* gm,
  28507. const ecc_point* am, int inMont, ecc_point* r, int map, void* heap)
  28508. {
  28509. #ifdef WOLFSSL_SP_SMALL_STACK
  28510. sp_point_384* point = NULL;
  28511. sp_digit* k = NULL;
  28512. #else
  28513. sp_point_384 point[2];
  28514. sp_digit k[7 + 7 * 2 * 6];
  28515. #endif
  28516. sp_point_384* addP = NULL;
  28517. sp_digit* tmp = NULL;
  28518. int err = MP_OKAY;
  28519. #ifdef WOLFSSL_SP_SMALL_STACK
  28520. point = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 2, heap,
  28521. DYNAMIC_TYPE_ECC);
  28522. if (point == NULL)
  28523. err = MEMORY_E;
  28524. if (err == MP_OKAY) {
  28525. k = (sp_digit*)XMALLOC(
  28526. sizeof(sp_digit) * (7 + 7 * 2 * 6), heap,
  28527. DYNAMIC_TYPE_ECC);
  28528. if (k == NULL)
  28529. err = MEMORY_E;
  28530. }
  28531. #endif
  28532. if (err == MP_OKAY) {
  28533. addP = point + 1;
  28534. tmp = k + 7;
  28535. sp_384_from_mp(k, 7, km);
  28536. sp_384_point_from_ecc_point_7(point, gm);
  28537. sp_384_point_from_ecc_point_7(addP, am);
  28538. }
  28539. if ((err == MP_OKAY) && (!inMont)) {
  28540. err = sp_384_mod_mul_norm_7(addP->x, addP->x, p384_mod);
  28541. }
  28542. if ((err == MP_OKAY) && (!inMont)) {
  28543. err = sp_384_mod_mul_norm_7(addP->y, addP->y, p384_mod);
  28544. }
  28545. if ((err == MP_OKAY) && (!inMont)) {
  28546. err = sp_384_mod_mul_norm_7(addP->z, addP->z, p384_mod);
  28547. }
  28548. if (err == MP_OKAY) {
  28549. err = sp_384_ecc_mulmod_7(point, point, k, 0, 0, heap);
  28550. }
  28551. if (err == MP_OKAY) {
  28552. sp_384_proj_point_add_7(point, point, addP, tmp);
  28553. if (map) {
  28554. sp_384_map_7(point, point, tmp);
  28555. }
  28556. err = sp_384_point_to_ecc_point_7(point, r);
  28557. }
  28558. #ifdef WOLFSSL_SP_SMALL_STACK
  28559. if (k != NULL)
  28560. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  28561. if (point != NULL)
  28562. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  28563. #endif
  28564. return err;
  28565. }
  28566. #ifdef WOLFSSL_SP_SMALL
  28567. /* Multiply the base point of P384 by the scalar and return the result.
  28568. * If map is true then convert result to affine coordinates.
  28569. *
  28570. * r Resulting point.
  28571. * k Scalar to multiply by.
  28572. * map Indicates whether to convert result to affine.
  28573. * heap Heap to use for allocation.
  28574. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  28575. */
  28576. static int sp_384_ecc_mulmod_base_7(sp_point_384* r, const sp_digit* k,
  28577. int map, int ct, void* heap)
  28578. {
  28579. /* No pre-computed values. */
  28580. return sp_384_ecc_mulmod_7(r, &p384_base, k, map, ct, heap);
  28581. }
  28582. #ifdef WOLFSSL_SP_NONBLOCK
  28583. static int sp_384_ecc_mulmod_base_7_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
  28584. const sp_digit* k, int map, int ct, void* heap)
  28585. {
  28586. /* No pre-computed values. */
  28587. return sp_384_ecc_mulmod_7_nb(sp_ctx, r, &p384_base, k, map, ct, heap);
  28588. }
  28589. #endif /* WOLFSSL_SP_NONBLOCK */
  28590. #else
  28591. /* Striping precomputation table.
  28592. * 8 points combined into a table of 256 points.
  28593. * Distance of 48 between points.
  28594. */
  28595. static const sp_table_entry_384 p384_table[256] = {
  28596. /* 0 */
  28597. { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  28598. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
  28599. /* 1 */
  28600. { { 0x50756649c0b528L,0x71c541ad9c707bL,0x71506d35b8838dL,
  28601. 0x4d1877fc3ce1d7L,0x6de2b645486845L,0x227025fee46c29L,
  28602. 0x134eab708a6785L },
  28603. { 0x043dad4b03a4feL,0x517ef769535846L,0x58ba0ec14286feL,
  28604. 0x47a7fecc5d6f3aL,0x1a840c6c352196L,0x3d3bb00044c72dL,
  28605. 0x0ade2af0968571L } },
  28606. /* 2 */
  28607. { { 0x0647532b0c535bL,0x52a6e0a0c52c53L,0x5085aae6b24375L,
  28608. 0x7096bb501c66b5L,0x47bdb3df9b7b7bL,0x11227e9b2f0be6L,
  28609. 0x088b172704fa51L },
  28610. { 0x0e796f2680dc64L,0x796eb06a482ebfL,0x2b441d02e04839L,
  28611. 0x19bef7312a5aecL,0x02247c38b8efb5L,0x099ed1185c329eL,
  28612. 0x1ed71d7cdb096fL } },
  28613. /* 3 */
  28614. { { 0x6a3cc39edffea5L,0x7a386fafd3f9c4L,0x366f78fbd8d6efL,
  28615. 0x529c7ad7873b80L,0x79eb30380eb471L,0x07c5d3b51760b7L,
  28616. 0x36ee4f1cc69183L },
  28617. { 0x5ba260f526b605L,0x2f1dfaf0aa6e6fL,0x6bb5ca812a5752L,
  28618. 0x3002d8d1276bc9L,0x01f82269483777L,0x1df33eaaf733cdL,
  28619. 0x2b97e555f59255L } },
  28620. /* 4 */
  28621. { { 0x480c57f26feef9L,0x4d28741c248048L,0x0c9cf8af1f0c68L,
  28622. 0x778f6a639a8016L,0x148e88c42e9c53L,0x464051757ecfe9L,
  28623. 0x1a940bd0e2a5e1L },
  28624. { 0x713a46b74536feL,0x1757b153e1d7ebL,0x30dc8c9da07486L,
  28625. 0x3b7460c1879b5eL,0x4b766c5317b315L,0x1b9de3aaf4d377L,
  28626. 0x245f124c2cf8f5L } },
  28627. /* 5 */
  28628. { { 0x426e2ee349ddd0L,0x7df3365f84a022L,0x03b005d29a7c45L,
  28629. 0x422c2337f9b5a4L,0x060494f4bde761L,0x5245e5db6da0b0L,
  28630. 0x22b71d744677f2L },
  28631. { 0x19d097b7d5a7ceL,0x6bcb468823d34cL,0x1c3692d3be1d09L,
  28632. 0x3c80ec7aa01f02L,0x7170f2ebaafd97L,0x06cbcc7d79d4e8L,
  28633. 0x04a8da511fe760L } },
  28634. /* 6 */
  28635. { { 0x79c07a4fc52870L,0x6e9034a752c251L,0x603860a367382cL,
  28636. 0x56d912d6aa87d0L,0x0a348a24abaf76L,0x6c5a23da14adcbL,
  28637. 0x3cf60479a522b2L },
  28638. { 0x18dd774c61ed22L,0x0ff30168f93b0cL,0x3f79ae15642eddL,
  28639. 0x40510f4915fbcbL,0x2c9ddfdfd1c6d6L,0x67b81b62aee55eL,
  28640. 0x2824de79b07a43L } },
  28641. /* 7 */
  28642. { { 0x6c66efe085c629L,0x48c212b7913470L,0x4480fd2d057f0aL,
  28643. 0x725ec7a89a9eb1L,0x78ce97ca1972b7L,0x54760ee70154fbL,
  28644. 0x362a40e27b9f93L },
  28645. { 0x474dc7e7b14461L,0x602819389ef037L,0x1a13bc284370b2L,
  28646. 0x0193ff1295a59dL,0x79615bde6ea5d2L,0x2e76e3d886acc1L,
  28647. 0x3bb796812e2b60L } },
  28648. /* 8 */
  28649. { { 0x04cbb3893b9a2dL,0x4c16010a18baabL,0x19f7cb50f60831L,
  28650. 0x084f400a0936c1L,0x72f1cdd5bbbf00L,0x1b30b725dc6702L,
  28651. 0x182753e4fcc50cL },
  28652. { 0x059a07eadaf9d6L,0x26d81e24bf603cL,0x45583c839dc399L,
  28653. 0x5579d4d6b1103aL,0x2e14ea59489ae7L,0x492f6e1c5ecc97L,
  28654. 0x03740dc05db420L } },
  28655. /* 9 */
  28656. { { 0x413be88510521fL,0x3753ee49982e99L,0x6cd4f7098e1cc5L,
  28657. 0x613c92bda4ec1dL,0x495378b677efe0L,0x132a2143839927L,
  28658. 0x0cf8c336291c0bL },
  28659. { 0x7fc89d2208353fL,0x751b9da85657e1L,0x349b8a97d405c3L,
  28660. 0x65a964b048428fL,0x1adf481276455eL,0x5560c8d89c2ffcL,
  28661. 0x144fc11fac21a3L } },
  28662. /* 10 */
  28663. { { 0x7611f4df5bdf53L,0x634eb16234db80L,0x3c713b8e51174cL,
  28664. 0x52c3c68ac4b2edL,0x53025ba8bebe75L,0x7175d98143105bL,
  28665. 0x33ca8e266a48faL },
  28666. { 0x0c9281d24fd048L,0x76b3177604bbf3L,0x3b26ae754e106fL,
  28667. 0x7f782275c6efc6L,0x36662538a4cb67L,0x0ca1255843e464L,
  28668. 0x2a4674e142d9bcL } },
  28669. /* 11 */
  28670. { { 0x303b4085d480d8L,0x68f23650f4fa7bL,0x552a3ceeba3367L,
  28671. 0x6da0c4947926e3L,0x6e0f5482eb8003L,0x0de717f3d6738aL,
  28672. 0x22e5dcc826a477L },
  28673. { 0x1b05b27209cfc2L,0x7f0a0b65b6e146L,0x63586549ed3126L,
  28674. 0x7d628dd2b23124L,0x383423fe510391L,0x57ff609eabd569L,
  28675. 0x301f04370131baL } },
  28676. /* 12 */
  28677. { { 0x22fe4cdb32f048L,0x7f228ebdadbf5aL,0x02a99adb2d7c8eL,
  28678. 0x01a02e05286706L,0x62d6adf627a89fL,0x49c6ce906fbf2bL,
  28679. 0x0207256dae90b9L },
  28680. { 0x23e036e71d6cebL,0x199ed8d604e3d7L,0x0c1a11c076d16fL,
  28681. 0x389291fb3da3f3L,0x47adc60f8f942eL,0x177048468e4b9aL,
  28682. 0x20c09f5e61d927L } },
  28683. /* 13 */
  28684. { { 0x129ea63615b0b8L,0x03fb4a9b588367L,0x5ad6da8da2d051L,
  28685. 0x33f782f44caeaaL,0x5a27fa80d45291L,0x6d1ed796942da4L,
  28686. 0x08435a931ef556L },
  28687. { 0x004abb25351130L,0x6d33207c6fd7e7L,0x702130972074b7L,
  28688. 0x0e34748af900f7L,0x762a531a28c87aL,0x3a903b5a4a6ac7L,
  28689. 0x1775b79c35b105L } },
  28690. /* 14 */
  28691. { { 0x7470fd846612ceL,0x7dd9b431b32e53L,0x04bcd2be1a61bcL,
  28692. 0x36ed7c5b5c260bL,0x6795f5ef0a4084L,0x46e2880b401c93L,
  28693. 0x17d246c5aa8bdeL },
  28694. { 0x707ae4db41b38dL,0x233c31f7f9558fL,0x585110ec67bdf4L,
  28695. 0x4d0cc931d0c703L,0x26fbe4356841a7L,0x64323e95239c44L,
  28696. 0x371dc9230f3221L } },
  28697. /* 15 */
  28698. { { 0x70ff1ae4b1ec9dL,0x7c1dcfddee0daaL,0x53286782188748L,
  28699. 0x6a5d9381e6f207L,0x3aa6c7d6523c4cL,0x6c02d83e0d97e2L,
  28700. 0x16a9c916b45312L },
  28701. { 0x78146744b74de8L,0x742ec415269c6fL,0x237a2c6a860e79L,
  28702. 0x186baf17ba68a7L,0x4261e8789fa51fL,0x3dc136480a5903L,
  28703. 0x1953899e0cf159L } },
  28704. /* 16 */
  28705. { { 0x0205de2f9fbe67L,0x1706fee51c886fL,0x31a0b803c712bfL,
  28706. 0x0a6aa11ede7603L,0x2463ef2a145c31L,0x615403b30e8f4aL,
  28707. 0x3f024d6c5f5c5eL },
  28708. { 0x53bc4fd4d01f95L,0x7d512ac15a692cL,0x72be38fcfe6aa0L,
  28709. 0x437f0b77bbca1eL,0x7fdcf70774a10eL,0x392d6c5cde37f3L,
  28710. 0x229cbce79621d1L } },
  28711. /* 17 */
  28712. { { 0x2de4da2341c342L,0x5ca9d4e08844e7L,0x60dd073bcf74c9L,
  28713. 0x4f30aa499b63ecL,0x23efd1eafa00d5L,0x7c99a7db1257b3L,
  28714. 0x00febc9b3171b1L },
  28715. { 0x7e2fcf3045f8acL,0x2a642e9e3ce610L,0x23f82be69c5299L,
  28716. 0x66e49ad967c279L,0x1c895ddfd7a842L,0x798981e22f6d25L,
  28717. 0x0d595cb59322f3L } },
  28718. /* 18 */
  28719. { { 0x4bac017d8c1bbaL,0x73872161e7aafdL,0x0fd865f43d8163L,
  28720. 0x019d89457708b7L,0x1b983c4dd70684L,0x095e109b74d841L,
  28721. 0x25f1f0b3e0c76fL },
  28722. { 0x4e61ddf96010e8L,0x1c40a53f542e5eL,0x01a74dfc8365f9L,
  28723. 0x69b36b92773333L,0x08e0fccc139ed3L,0x266d216ddc4269L,
  28724. 0x1f2b47717ce9b5L } },
  28725. /* 19 */
  28726. { { 0x0a9a81da57a41fL,0x0825d800736cccL,0x2d7876b4579d28L,
  28727. 0x3340ea6211a1e3L,0x49e89284f3ff54L,0x6276a210fe2c6eL,
  28728. 0x01c3c8f31be7cbL },
  28729. { 0x2211da5d186e14L,0x1e6ffbb61bfea8L,0x536c7d060211d2L,
  28730. 0x320168720d1d55L,0x5835525ed667baL,0x5125e52495205eL,
  28731. 0x16113b9f3e9129L } },
  28732. /* 20 */
  28733. { { 0x3086073f3b236fL,0x283b03c443b5f5L,0x78e49ed0a067a7L,
  28734. 0x2a878fb79fb2b8L,0x662f04348a9337L,0x57ee2cf732d50bL,
  28735. 0x18b50dd65fd514L },
  28736. { 0x5feb9ef2955926L,0x2c3edbef06a7b0L,0x32728dad651029L,
  28737. 0x116d00b1c4b347L,0x13254052bf1a1aL,0x3e77bf7fee5ec1L,
  28738. 0x253943ca388882L } },
  28739. /* 21 */
  28740. { { 0x32e5b33062e8afL,0x46ebd147a6d321L,0x2c8076dec6a15cL,
  28741. 0x7328d511ff0d80L,0x10ad7e926def0eL,0x4e8ca85937d736L,
  28742. 0x02638c26e8bf2fL },
  28743. { 0x1deeb3fff1d63fL,0x5014417fa6e8efL,0x6e1da3de5c8f43L,
  28744. 0x7ca942b42295d9L,0x23faacf75bb4d1L,0x4a71fcd680053dL,
  28745. 0x04af4f90204dceL } },
  28746. /* 22 */
  28747. { { 0x23780d104cbba5L,0x4e8ff46bba9980L,0x2072a6da8d881fL,
  28748. 0x3cc3d881ae11c9L,0x2eee84ff19be89L,0x69b708ed77f004L,
  28749. 0x2a82928534eef9L },
  28750. { 0x794331187d4543L,0x70e0f3edc0cc41L,0x3ab1fa0b84c854L,
  28751. 0x1478355c1d87baL,0x6f35fa7748ba28L,0x37b8be0531584dL,
  28752. 0x03c3141c23a69fL } },
  28753. /* 23 */
  28754. { { 0x5c244cdef029ddL,0x0d0f0a0cc37018L,0x17f8476604f6afL,
  28755. 0x13a6dd6ccc95c3L,0x5a242e9801b8f6L,0x211ca9cc632131L,
  28756. 0x264a6a46a4694fL },
  28757. { 0x3ffd7235285887L,0x284be28302046fL,0x57f4b9b882f1d6L,
  28758. 0x5e21772c940661L,0x7619a735c600cfL,0x2f76f5a50c9106L,
  28759. 0x28d89c8c69de31L } },
  28760. /* 24 */
  28761. { { 0x799b5c91361ed8L,0x36ead8c66cd95cL,0x046c9969a91f5cL,
  28762. 0x46bbdba2a66ea9L,0x29db0e0215a599L,0x26c8849b36f756L,
  28763. 0x22c3feb31ff679L },
  28764. { 0x585d1237b5d9efL,0x5ac57f522e8e8dL,0x617e66e8b56c41L,
  28765. 0x68826f276823cfL,0x0983f0e6f39231L,0x4e1075099084bdL,
  28766. 0x2a541f82be0416L } },
  28767. /* 25 */
  28768. { { 0x468a6e14cf381cL,0x4f7b845c6399edL,0x36aa29732ebe74L,
  28769. 0x19c726911ab46aL,0x2ad1fe431eec0eL,0x301e35051fd1eaL,
  28770. 0x36da815e7a1ab3L },
  28771. { 0x05672e4507832aL,0x4ebf10fca51251L,0x6015843421cff0L,
  28772. 0x3affad832fc013L,0x712b58d9b45540L,0x1e4751d1f6213eL,
  28773. 0x0e7c2b218bafa7L } },
  28774. /* 26 */
  28775. { { 0x7abf784c52edf5L,0x6fcb4b135ca7b1L,0x435e46ac5f735cL,
  28776. 0x67f8364ca48c5fL,0x46d45b5fbd956bL,0x10deda6065db94L,
  28777. 0x0b37fdf85068f9L },
  28778. { 0x74b3ba61f47ec8L,0x42c7ddf08c10ccL,0x1531a1fe422a20L,
  28779. 0x366f913d12be38L,0x6a846e30cb2edfL,0x2785898c994fedL,
  28780. 0x061be85f331af3L } },
  28781. /* 27 */
  28782. { { 0x23f5361dfcb91eL,0x3c26c8da6b1491L,0x6e444a1e620d65L,
  28783. 0x0c3babd5e8ac13L,0x573723ce612b82L,0x2d10e62a142c37L,
  28784. 0x3d1a114c2d98bdL },
  28785. { 0x33950b401896f6L,0x7134efe7c12110L,0x31239fd2978472L,
  28786. 0x30333bf5978965L,0x79f93313dd769fL,0x457fb9e11662caL,
  28787. 0x190a73b251ae3cL } },
  28788. /* 28 */
  28789. { { 0x04dd54bb75f9a4L,0x0d7253a76ae093L,0x08f5b930792bbcL,
  28790. 0x041f79adafc265L,0x4a9ff24c61c11bL,0x0019c94e724725L,
  28791. 0x21975945d9cc2aL },
  28792. { 0x3dfe76722b4a2bL,0x17f2f6107c1d94L,0x546e1ae2944b01L,
  28793. 0x53f1f06401e72dL,0x2dbe43fc7632d6L,0x5639132e185903L,
  28794. 0x0f2f34eb448385L } },
  28795. /* 29 */
  28796. { { 0x7b4cc7ec30ce93L,0x58fb6e4e4145f7L,0x5d1ed5540043b5L,
  28797. 0x19ffbe1f633adfL,0x5bfc0907259033L,0x6378f872e7ca0eL,
  28798. 0x2c127b2c01eb3cL },
  28799. { 0x076eaf4f58839cL,0x2db54560bc9f68L,0x42ad0319b84062L,
  28800. 0x46c325d1fb019dL,0x76d2a19ee9eebcL,0x6fbd6d9e2aa8f7L,
  28801. 0x2396a598fe0991L } },
  28802. /* 30 */
  28803. { { 0x662fddf7fbd5e1L,0x7ca8ed22563ad3L,0x5b4768efece3b3L,
  28804. 0x643786a422d1eaL,0x36ce80494950e1L,0x1a30795b7f2778L,
  28805. 0x107f395c93f332L },
  28806. { 0x7939c28332c144L,0x491610e3c8dc0bL,0x099ba2bfdac5fcL,
  28807. 0x5c2e3149ec29a7L,0x31b731d06f1dc3L,0x1cbb60d465d462L,
  28808. 0x3ca5461362cfd9L } },
  28809. /* 31 */
  28810. { { 0x653ff736ddc103L,0x7c6f2bdec0dfb2L,0x73f81b73a097d0L,
  28811. 0x05b775f84f180fL,0x56b2085af23413L,0x0d6f36256a61feL,
  28812. 0x26d3ed267fa68fL },
  28813. { 0x54f89251d27ac2L,0x4fc6ad94a71202L,0x7ebf01969b4cc5L,
  28814. 0x7ba364dbc14760L,0x4f8370959a2587L,0x7b7631e37c6188L,
  28815. 0x29e51845f104cbL } },
  28816. /* 32 */
  28817. { { 0x426b775e3c647bL,0x327319e0a69180L,0x0c5cb034f6ff2fL,
  28818. 0x73aa39b98e9897L,0x7ee615f49fde6eL,0x3f712aa61e0db4L,
  28819. 0x33ca06c2ba2ce9L },
  28820. { 0x14973541b8a543L,0x4b4e6101ba61faL,0x1d94e4233d0698L,
  28821. 0x501513c715d570L,0x1b8f8c3d01436bL,0x52f41a0445cf64L,
  28822. 0x3f709c3a75fb04L } },
  28823. /* 33 */
  28824. { { 0x073c0cbc7f41d6L,0x227c36f5ac8201L,0x508e110fef65d8L,
  28825. 0x0f317229529b7fL,0x45fc6030d00e24L,0x118a65d30cebeaL,
  28826. 0x3340cc4223a448L },
  28827. { 0x204c999797612cL,0x7c05dd4ce9c5a3L,0x7b865d0a8750e4L,
  28828. 0x2f82c876ab7d34L,0x2243ddd2ab4808L,0x6834b9df8a4914L,
  28829. 0x123319ed950e0fL } },
  28830. /* 34 */
  28831. { { 0x50430efc14ab48L,0x7e9e4ce0d4e89cL,0x2332207fd8656dL,
  28832. 0x4a2809e97f4511L,0x2162bb1b968e2dL,0x29526d54af2972L,
  28833. 0x13edd9adcd939dL },
  28834. { 0x793bca31e1ff7fL,0x6b959c9e4d2227L,0x628ac27809a5baL,
  28835. 0x2c71ffc7fbaa5fL,0x0c0b058f13c9ceL,0x5676eae68de2cfL,
  28836. 0x35508036ea19a4L } },
  28837. /* 35 */
  28838. { { 0x030bbd6dda1265L,0x67f9d12e31bb34L,0x7e4d8196e3ded3L,
  28839. 0x7b9120e5352498L,0x75857bce72d875L,0x4ead976a396caeL,
  28840. 0x31c5860553a64dL },
  28841. { 0x1a0f792ee32189L,0x564c4efb8165d0L,0x7adc7d1a7fbcbeL,
  28842. 0x7ed7c2ccf327b7L,0x35df1b448ce33dL,0x6f67eb838997cdL,
  28843. 0x3ee37ec0077917L } },
  28844. /* 36 */
  28845. { { 0x345fa74d5bb921L,0x097c9a56ccfd8eL,0x00a0b5e8f971f8L,
  28846. 0x723d95223f69d4L,0x08e2e5c2777f87L,0x68b13676200109L,
  28847. 0x26ab5df0acbad6L },
  28848. { 0x01bca7daac34aeL,0x49ca4d5f664dadL,0x110687b850914bL,
  28849. 0x1203d6f06443c9L,0x7a2ac743b04d4cL,0x40d96bd3337f82L,
  28850. 0x13728be0929c06L } },
  28851. /* 37 */
  28852. { { 0x631ca61127bc1aL,0x2b362fd5a77cd1L,0x17897d68568fb7L,
  28853. 0x21070af33db5b2L,0x6872e76221794aL,0x436f29fb076963L,
  28854. 0x1f2acfc0ecb7b3L },
  28855. { 0x19bf15ca9b3586L,0x32489a4a17aee2L,0x2b31af3c929551L,
  28856. 0x0db7c420b9b19fL,0x538c39bd308c2bL,0x438775c0dea88fL,
  28857. 0x1537304d7cd07fL } },
  28858. /* 38 */
  28859. { { 0x53598d943caf0dL,0x1d5244bfe266adL,0x7158feb7ab3811L,
  28860. 0x1f46e13cf6fb53L,0x0dcab632eb9447L,0x46302968cfc632L,
  28861. 0x0b53d3cc5b6ec7L },
  28862. { 0x69811ca143b7caL,0x5865bcf9f2a11aL,0x74ded7fa093b06L,
  28863. 0x1c878ec911d5afL,0x04610e82616e49L,0x1e157fe9640eb0L,
  28864. 0x046e6f8561d6c2L } },
  28865. /* 39 */
  28866. { { 0x631a3d3bbe682cL,0x3a4ce9dde5ba95L,0x28f11f7502f1f1L,
  28867. 0x0a55cf0c957e88L,0x495e4ec7e0a3bcL,0x30ad4d87ba365cL,
  28868. 0x0217b97a4c26f3L },
  28869. { 0x01a9088c2e67fdL,0x7501c4c3d5e5e7L,0x265b7bb854c820L,
  28870. 0x729263c87e6b52L,0x308b9e3b8fb035L,0x33f1b86c1b23abL,
  28871. 0x0e81b8b21fc99cL } },
  28872. /* 40 */
  28873. { { 0x59f5a87237cac0L,0x6b3a86b0cf28b9L,0x13a53db13a4fc2L,
  28874. 0x313c169a1c253bL,0x060158304ed2bbL,0x21e171b71679bcL,
  28875. 0x10cdb754d76f86L },
  28876. { 0x44355392ab473aL,0x64eb7cbda08caeL,0x3086426a900c71L,
  28877. 0x49016ed9f3c33cL,0x7e6354ab7e04f9L,0x17c4c91a40cd2eL,
  28878. 0x3509f461024c66L } },
  28879. /* 41 */
  28880. { { 0x2848f50f9b5a31L,0x68d1755b6c5504L,0x48cd5d5672ec00L,
  28881. 0x4d77421919d023L,0x1e1e349ef68807L,0x4ab5130cf415d7L,
  28882. 0x305464c6c7dbe6L },
  28883. { 0x64eb0bad74251eL,0x64c6957e52bda4L,0x6c12583440dee6L,
  28884. 0x6d3bee05b00490L,0x186970de53dbc4L,0x3be03b37567a56L,
  28885. 0x2b553b1ebdc55bL } },
  28886. /* 42 */
  28887. { { 0x74dc3579efdc58L,0x26d29fed1bb71cL,0x334c825a9515afL,
  28888. 0x433c1e839273a6L,0x0d8a4e41cff423L,0x3454098fe42f8eL,
  28889. 0x1046674bf98686L },
  28890. { 0x09a3e029c05dd2L,0x54d7cfc7fb53a7L,0x35f0ad37e14d7cL,
  28891. 0x73a294a13767b9L,0x3f519678275f4fL,0x788c63393993a4L,
  28892. 0x0781680b620123L } },
  28893. /* 43 */
  28894. { { 0x4c8e2ed4d5ffe8L,0x112db7d42fe4ebL,0x433b8f2d2be2edL,
  28895. 0x23e30b29a82cbcL,0x35d2f4c06ee85aL,0x78ff31ffe4b252L,
  28896. 0x0d31295c8cbff5L },
  28897. { 0x314806ea0376a2L,0x4ea09e22bc0589L,0x0879575f00ba97L,
  28898. 0x188226d2996bb7L,0x7799368dc9411fL,0x7ab24e5c8cae36L,
  28899. 0x2b6a8e2ee4ea33L } },
  28900. /* 44 */
  28901. { { 0x70c7127d4ed72aL,0x24c9743ef34697L,0x2fd30e7a93683aL,
  28902. 0x538a89c246012cL,0x6c660a5394ed82L,0x79a95ea239d7e0L,
  28903. 0x3f3af3bbfb170dL },
  28904. { 0x3b75aa779ae8c1L,0x33995a3cc0dde4L,0x7489d5720b7bfdL,
  28905. 0x599677ef9fa937L,0x3defd64c5ab44bL,0x27d52dc234522bL,
  28906. 0x2ac65d1a8450e0L } },
  28907. /* 45 */
  28908. { { 0x478585ec837d7dL,0x5f7971dc174887L,0x67576ed7bb296dL,
  28909. 0x5a78e529a74926L,0x640f73f4fa104bL,0x7d42a8b16e4730L,
  28910. 0x108c7eaa75fd01L },
  28911. { 0x60661ef96e6896L,0x18d3a0761f3aa7L,0x6e71e163455539L,
  28912. 0x165827d6a7e583L,0x4e7f77e9527935L,0x790bebe2ae912eL,
  28913. 0x0b8fe9561adb55L } },
  28914. /* 46 */
  28915. { { 0x4d48036a9951a8L,0x371084f255a085L,0x66aeca69cea2c5L,
  28916. 0x04c99f40c745e7L,0x08dc4bfd9a0924L,0x0b0ec146b29df7L,
  28917. 0x05106218d01c91L },
  28918. { 0x2a56ee99caedc7L,0x5d9b23a203922cL,0x1ce4c80b6a3ec4L,
  28919. 0x2666bcb75338cbL,0x185a81aac8c4aaL,0x2b4fb60a06c39eL,
  28920. 0x0327e1b3633f42L } },
  28921. /* 47 */
  28922. { { 0x72814710b2a556L,0x52c864f6e16534L,0x4978de66ddd9f2L,
  28923. 0x151f5950276cf0L,0x450ac6781d2dc2L,0x114b7a22dd61b2L,
  28924. 0x3b32b07f29faf8L },
  28925. { 0x68444fdc2d6e94L,0x68526bd9e437bcL,0x0ca780e8b0d887L,
  28926. 0x69f3f850a716aaL,0x500b953e42cd57L,0x4e57744d812e7dL,
  28927. 0x000a5f0e715f48L } },
  28928. /* 48 */
  28929. { { 0x2aab10b8243a7dL,0x727d1f4b18b675L,0x0e6b9fdd91bbbbL,
  28930. 0x0d58269fc337e5L,0x45d6664105a266L,0x11946af1b14072L,
  28931. 0x2c2334f91e46e1L },
  28932. { 0x6dc5f8756d2411L,0x21b34eaa25188bL,0x0d2797da83529eL,
  28933. 0x324df55616784bL,0x7039ec66d267dfL,0x2de79cdb2d108cL,
  28934. 0x14011b1ad0bde0L } },
  28935. /* 49 */
  28936. { { 0x2e160266425043L,0x55fbe11b712125L,0x7e3c58b3947fd9L,
  28937. 0x67aacc79c37ad3L,0x4a18e18d2dea0fL,0x5eef06e5674351L,
  28938. 0x37c3483ae33439L },
  28939. { 0x5d5e1d75bb4045L,0x0f9d72db296efdL,0x60b1899dd894a9L,
  28940. 0x06e8818ded949aL,0x747fd853c39434L,0x0953b937d9efabL,
  28941. 0x09f08c0beeb901L } },
  28942. /* 50 */
  28943. { { 0x1d208a8f2d49ceL,0x54042c5be1445aL,0x1c2681fd943646L,
  28944. 0x219c8094e2e674L,0x442cddf07238b8L,0x574a051c590832L,
  28945. 0x0b72f4d61c818aL },
  28946. { 0x7bc3cbe4680967L,0x0c8b3f25ae596bL,0x0445b0da74a9efL,
  28947. 0x0bbf46c40363b7L,0x1df575c50677a3L,0x016ea6e73d68adL,
  28948. 0x0b5207bd8db0fdL } },
  28949. /* 51 */
  28950. { { 0x2d39fdfea1103eL,0x2b252bf0362e34L,0x63d66c992baab9L,
  28951. 0x5ac97706de8550L,0x0cca390c39c1acL,0x0d9bec5f01b2eaL,
  28952. 0x369360a0f7e5f3L },
  28953. { 0x6dd3461e201067L,0x70b2d3f63ed614L,0x487580487c54c7L,
  28954. 0x6020e48a44af2aL,0x1ccf80b21aab04L,0x3cf3b12d88d798L,
  28955. 0x349368eccc506fL } },
  28956. /* 52 */
  28957. { { 0x5a053753b0a354L,0x65e818dbb9b0aeL,0x7d5855ee50e4bfL,
  28958. 0x58dc06885c7467L,0x5ee15073e57bd3L,0x63254ebc1e07fdL,
  28959. 0x1d48e0392aa39bL },
  28960. { 0x4e227c6558ffe9L,0x0c3033d8a82a3eL,0x7bde65c214e8d2L,
  28961. 0x6e23561559c16aL,0x5094c5e6deaffdL,0x78dca2880f1f91L,
  28962. 0x3d9d3f947d838dL } },
  28963. /* 53 */
  28964. { { 0x387ae5af63408fL,0x6d539aeb4e6edfL,0x7f3d3186368e70L,
  28965. 0x01a6446bc19989L,0x35288fbcd4482fL,0x39288d34ec2736L,
  28966. 0x1de9c47159ad76L },
  28967. { 0x695dc7944f8d65L,0x3eca2c35575094L,0x0c918059a79b69L,
  28968. 0x4573a48c32a74eL,0x580d8bc8b93f52L,0x190be3a3d071eaL,
  28969. 0x2333e686b3a8cbL } },
  28970. /* 54 */
  28971. { { 0x2b110c7196fee2L,0x3ac70e99128a51L,0x20a6bb6b75d5e6L,
  28972. 0x5f447fa513149aL,0x560d69714cc7b2L,0x1d3ee25279fab1L,
  28973. 0x369adb2ccca959L },
  28974. { 0x3fddb13dd821c2L,0x70bf21ba647be8L,0x64121227e3cbc9L,
  28975. 0x12633a4c892320L,0x3c15c61660f26dL,0x1932c3b3d19900L,
  28976. 0x18c718563eab71L } },
  28977. /* 55 */
  28978. { { 0x72ebe0fd752366L,0x681c2737d11759L,0x143c805e7ae4f0L,
  28979. 0x78ed3c2cc7b324L,0x5c16e14820254fL,0x226a4f1c4ec9f0L,
  28980. 0x2891bb915eaac6L },
  28981. { 0x061eb453763b33L,0x07f88b81781a87L,0x72b5ac7a87127cL,
  28982. 0x7ea4e4cd7ff8b5L,0x5e8c3ce33908b6L,0x0bcb8a3d37feffL,
  28983. 0x01da9e8e7fc50bL } },
  28984. /* 56 */
  28985. { { 0x639dfe9e338d10L,0x32dfe856823608L,0x46a1d73bca3b9aL,
  28986. 0x2da685d4b0230eL,0x6e0bc1057b6d69L,0x7144ec724a5520L,
  28987. 0x0b067c26b87083L },
  28988. { 0x0fc3f0eef4c43dL,0x63500f509552b7L,0x220d74af6f8b86L,
  28989. 0x038996eafa2aa9L,0x7f6750f4aee4d2L,0x3e1d3f06718720L,
  28990. 0x1ea1d37243814cL } },
  28991. /* 57 */
  28992. { { 0x322d4597c27050L,0x1beeb3ce17f109L,0x15e5ce2e6ef42eL,
  28993. 0x6c8be27da6b3a0L,0x66e3347f4d5f5cL,0x7172133899c279L,
  28994. 0x250aff4e548743L },
  28995. { 0x28f0f6a43b566dL,0x0cd2437fefbca0L,0x5b1108cb36bdbaL,
  28996. 0x48a834d41fb7c2L,0x6cb8565680579fL,0x42da2412b45d9fL,
  28997. 0x33dfc1abb6c06eL } },
  28998. /* 58 */
  28999. { { 0x56e3c48ef96c80L,0x65667bb6c1381eL,0x09f70514375487L,
  29000. 0x1548ff115f4a08L,0x237de2d21a0710L,0x1425cdee9f43dfL,
  29001. 0x26a6a42e055b0aL },
  29002. { 0x4ea9ea9dc7dfcbL,0x4df858583ac58aL,0x1d274f819f1d39L,
  29003. 0x26e9c56cf91fcbL,0x6cee31c7c3a465L,0x0bb8e00b108b28L,
  29004. 0x226158da117301L } },
  29005. /* 59 */
  29006. { { 0x5a7cd4fce73946L,0x7b6a462d0ac653L,0x732ea4bb1a3da5L,
  29007. 0x7c8e9f54711af4L,0x0a6cd55d4655f9L,0x341e6d13e4754aL,
  29008. 0x373c87098879a8L },
  29009. { 0x7bc82e61b818bfL,0x5f2db48f44879fL,0x2a2f06833f1d28L,
  29010. 0x494e5b691a74c0L,0x17d6cf35fd6b57L,0x5f7028d1c25dfcL,
  29011. 0x377a9ab9562cb6L } },
  29012. /* 60 */
  29013. { { 0x4de8877e787b2eL,0x183e7352621a52L,0x2ab0509974962bL,
  29014. 0x045a450496cb8aL,0x3bf7118b5591c7L,0x7724f98d761c35L,
  29015. 0x301607e8d5a0c1L },
  29016. { 0x0f58a3f24d4d58L,0x3771c19c464f3cL,0x06746f9c0bfafaL,
  29017. 0x56564c9c8feb52L,0x0d66d9a7d8a45fL,0x403578141193caL,
  29018. 0x00b0d0bdc19260L } },
  29019. /* 61 */
  29020. { { 0x571407157bdbc2L,0x138d5a1c2c0b99L,0x2ee4a8057dcbeaL,
  29021. 0x051ff2b58e9ed1L,0x067378ad9e7cdaL,0x7cc2c1db97a49eL,
  29022. 0x1e7536ccd849d6L },
  29023. { 0x531fd95f3497c4L,0x55dc08325f61a7L,0x144e942bce32bfL,
  29024. 0x642d572f09e53aL,0x556ff188261678L,0x3e79c0d9d513d6L,
  29025. 0x0bbbc6656f6d52L } },
  29026. /* 62 */
  29027. { { 0x57d3eb50596edcL,0x26c520a487451dL,0x0a92db40aea8d6L,
  29028. 0x27df6345109616L,0x7733d611fd727cL,0x61d14171fef709L,
  29029. 0x36169ae417c36bL },
  29030. { 0x6899f5d4091cf7L,0x56ce5dfe4ed0c1L,0x2c430ce5913fbcL,
  29031. 0x1b13547e0f8caeL,0x4840a8275d3699L,0x59b8ef209e81adL,
  29032. 0x22362dff5ea1a2L } },
  29033. /* 63 */
  29034. { { 0x7237237bd98425L,0x73258e162a9d0bL,0x0a59a1e8bb5118L,
  29035. 0x4190a7ee5d8077L,0x13684905fdbf7cL,0x31c4033a52626bL,
  29036. 0x010a30e4fbd448L },
  29037. { 0x47623f981e909aL,0x670af7c325b481L,0x3d004241fa4944L,
  29038. 0x0905a2ca47f240L,0x58f3cdd7a187c3L,0x78b93aee05b43fL,
  29039. 0x19b91d4ef8d63bL } },
  29040. /* 64 */
  29041. { { 0x0d34e116973cf4L,0x4116fc9e69ee0eL,0x657ae2b4a482bbL,
  29042. 0x3522eed134d7cdL,0x741e0dde0a036aL,0x6554316a51cc7bL,
  29043. 0x00f31c6ca89837L },
  29044. { 0x26770aa06b1dd7L,0x38233a4ceba649L,0x065a1110c96feaL,
  29045. 0x18d367839e0f15L,0x794543660558d1L,0x39b605139065dcL,
  29046. 0x29abbec071b637L } },
  29047. /* 65 */
  29048. { { 0x1464b401ab5245L,0x16db891b27ff74L,0x724eb49cb26e34L,
  29049. 0x74fee3bc9cc33eL,0x6a8bdbebe085eaL,0x5c2e75ca207129L,
  29050. 0x1d03f2268e6b08L },
  29051. { 0x28b0a328e23b23L,0x645dc26209a0bcL,0x62c28990348d49L,
  29052. 0x4dd9be1fa333d0L,0x6183aac74a72e4L,0x1d6f3ee69e1d03L,
  29053. 0x2fff96db0ff670L } },
  29054. /* 66 */
  29055. { { 0x2358f5c6a2123fL,0x5b2bfc51bedb63L,0x4fc6674be649ecL,
  29056. 0x51fc16e44b813aL,0x2ffe10a73754c1L,0x69a0c7a053aeefL,
  29057. 0x150e605fb6b9b4L },
  29058. { 0x179eef6b8b83c4L,0x64293b28ad05efL,0x331795fab98572L,
  29059. 0x09823eec78727dL,0x36508042b89b81L,0x65f1106adb927eL,
  29060. 0x2fc0234617f47cL } },
  29061. /* 67 */
  29062. { { 0x12aa244e8068dbL,0x0c834ae5348f00L,0x310fc1a4771cb3L,
  29063. 0x6c90a2f9e19ef9L,0x77946fa0573471L,0x37f5df81e5f72fL,
  29064. 0x204f5d72cbe048L },
  29065. { 0x613c724383bba6L,0x1ce14844967e0aL,0x797c85e69aa493L,
  29066. 0x4fb15b0f2ce765L,0x5807978e2e8aa7L,0x52c75859876a75L,
  29067. 0x1554635c763d3eL } },
  29068. /* 68 */
  29069. { { 0x4f292200623f3bL,0x6222be53d7fe07L,0x1e02a9a08c2571L,
  29070. 0x22c6058216b912L,0x1ec20044c7ba17L,0x53f94c5efde12bL,
  29071. 0x102b8aadfe32a4L },
  29072. { 0x45377aa927b102L,0x0d41b8062ee371L,0x77085a9018e62aL,
  29073. 0x0c69980024847cL,0x14739b423a73a9L,0x52ec6961fe3c17L,
  29074. 0x38a779c94b5a7dL } },
  29075. /* 69 */
  29076. { { 0x4d14008435af04L,0x363bfd8325b4e8L,0x48cdb715097c95L,
  29077. 0x1b534540f8bee0L,0x4ca1e5c90c2a76L,0x4b52c193d6eee0L,
  29078. 0x277a33c79becf5L },
  29079. { 0x0fee0d511d3d06L,0x4627f3d6a58f8cL,0x7c81ac245119b8L,
  29080. 0x0c8d526ba1e07aL,0x3dbc242f55bac2L,0x2399df8f91fffdL,
  29081. 0x353e982079ba3bL } },
  29082. /* 70 */
  29083. { { 0x6405d3b0ab9645L,0x7f31abe3ee236bL,0x456170a9babbb1L,
  29084. 0x09634a2456a118L,0x5b1c6045acb9e5L,0x2c75c20d89d521L,
  29085. 0x2e27ccf5626399L },
  29086. { 0x307cd97fed2ce4L,0x1c2fbb02b64087L,0x542a068d27e64dL,
  29087. 0x148c030b3bc6a6L,0x671129e616ade5L,0x123f40db60dafcL,
  29088. 0x07688f3c621220L } },
  29089. /* 71 */
  29090. { { 0x1c46b342f2c4b5L,0x27decc0b3c8f04L,0x0d9bd433464c54L,
  29091. 0x1f3d893b818572L,0x2536043b536c94L,0x57e00c4b19ebf9L,
  29092. 0x3938fb9e5ad55eL },
  29093. { 0x6b390024c8b22fL,0x4583f97e20a976L,0x2559d24abcbad7L,
  29094. 0x67a9cabc9bd8c6L,0x73a56f09432e4aL,0x79eb0beb53a3b7L,
  29095. 0x3e19d47f6f8221L } },
  29096. /* 72 */
  29097. { { 0x7399cb9d10e0b2L,0x32acc1b8a36e2aL,0x287d60c2407035L,
  29098. 0x42c82420ea4b5cL,0x13f286658bc268L,0x3c91181156e064L,
  29099. 0x234b83dcdeb963L },
  29100. { 0x79bc95486cfee6L,0x4d8fd3cb78af36L,0x07362ba5e80da8L,
  29101. 0x79d024a0d681b0L,0x6b58406907f87fL,0x4b40f1e977e58fL,
  29102. 0x38dcc6fd5fa342L } },
  29103. /* 73 */
  29104. { { 0x72282be1cd0abeL,0x02bd0fdfdf44e5L,0x19b0e0d2f753e4L,
  29105. 0x4514e76ce8c4c0L,0x02ebc9c8cdcc1bL,0x6ac0c0373e9fddL,
  29106. 0x0dc414af1c81a9L },
  29107. { 0x7a109246f32562L,0x26982e6a3768edL,0x5ecd8daed76ab5L,
  29108. 0x2eaa70061eb261L,0x09e7c038a8c514L,0x2a2603cc300658L,
  29109. 0x25d93ab9e55cd4L } },
  29110. /* 74 */
  29111. { { 0x11b19fcbd5256aL,0x41e4d94274770fL,0x0133c1a411001fL,
  29112. 0x360bac481dbca3L,0x45908b18a9c22bL,0x1e34396fafb03aL,
  29113. 0x1b84fea7486edaL },
  29114. { 0x183c62a71e6e16L,0x5f1dc30e93da8eL,0x6cb97b502573c3L,
  29115. 0x3708bf0964e3fcL,0x35a7f042eeacceL,0x56370da902c27fL,
  29116. 0x3a873c3b72797fL } },
  29117. /* 75 */
  29118. { { 0x6573c9cea4cc9bL,0x2c3b5f9d91e6dcL,0x2a90e2dbd9505eL,
  29119. 0x66a75444025f81L,0x1571fb894b03cdL,0x5d1a1f00fd26f3L,
  29120. 0x0d19a9fd618855L },
  29121. { 0x659acd56515664L,0x7279478bd616a3L,0x09a909e76d56c3L,
  29122. 0x2fd70474250358L,0x3a1a25c850579cL,0x11b9e0f71b74ccL,
  29123. 0x1268daef3d1bffL } },
  29124. /* 76 */
  29125. { { 0x7f5acc46d93106L,0x5bc15512f939c8L,0x504b5f92f996deL,
  29126. 0x25965549be7a64L,0x357a3a2ae9b80dL,0x3f2bcf9c139cc0L,
  29127. 0x0a7ddd99f23b35L },
  29128. { 0x6868f5a8a0b1c5L,0x319ec52f15b1beL,0x0770000a849021L,
  29129. 0x7f4d50287bd608L,0x62c971d28a9d7fL,0x164e89309acb72L,
  29130. 0x2a29f002cf4a32L } },
  29131. /* 77 */
  29132. { { 0x58a852ae11a338L,0x27e3a35f2dcef8L,0x494d5731ce9e18L,
  29133. 0x49516f33f4bb3eL,0x386b26ba370097L,0x4e8fac1ec30248L,
  29134. 0x2ac26d4c44455dL },
  29135. { 0x20484198eb9dd0L,0x75982a0e06512bL,0x152271b9279b05L,
  29136. 0x5908a9857e36d2L,0x6a933ab45a60abL,0x58d8b1acb24fafL,
  29137. 0x28fbcf19425590L } },
  29138. /* 78 */
  29139. { { 0x5420e9df010879L,0x4aba72aec2f313L,0x438e544eda7494L,
  29140. 0x2e8e189ce6f7eaL,0x2f771e4efe45bdL,0x0d780293bce7efL,
  29141. 0x1569ad3d0d02acL },
  29142. { 0x325251ebeaf771L,0x02510f1a8511e2L,0x3863816bf8aad1L,
  29143. 0x60fdb15fe6ac19L,0x4792aef52a348cL,0x38e57a104e9838L,
  29144. 0x0d171611a1df1bL } },
  29145. /* 79 */
  29146. { { 0x15ceb0bea65e90L,0x6e56482db339bcL,0x37f618f7b0261fL,
  29147. 0x6351abc226dabcL,0x0e999f617b74baL,0x37d3cc57af5b69L,
  29148. 0x21df2b987aac68L },
  29149. { 0x2dddaa3a358610L,0x2da264bc560e47L,0x545615d538bf13L,
  29150. 0x1c95ac244b8cc7L,0x77de1f741852cbL,0x75d324f00996abL,
  29151. 0x3a79b13b46aa3bL } },
  29152. /* 80 */
  29153. { { 0x7db63998683186L,0x6849bb989d530cL,0x7b53c39ef7ed73L,
  29154. 0x53bcfbf664d3ffL,0x25ef27c57f71c7L,0x50120ee80f3ad6L,
  29155. 0x243aba40ed0205L },
  29156. { 0x2aae5e0ee1fcebL,0x3449d0d8343fbeL,0x5b2864fb7cffc7L,
  29157. 0x64dceb5407ac3eL,0x20303a5695523dL,0x3def70812010b2L,
  29158. 0x07be937f2e9b6fL } },
  29159. /* 81 */
  29160. { { 0x5838f9e0540015L,0x728d8720efb9f7L,0x1ab5864490b0c8L,
  29161. 0x6531754458fdcfL,0x600ff9612440c0L,0x48735b36a585b7L,
  29162. 0x3d4aaea86b865dL },
  29163. { 0x6898942cac32adL,0x3c84c5531f23a1L,0x3c9dbd572f7edeL,
  29164. 0x5691f0932a2976L,0x186f0db1ac0d27L,0x4fbed18bed5bc9L,
  29165. 0x0e26b0dee0b38cL } },
  29166. /* 82 */
  29167. { { 0x1188b4f8e60f5bL,0x602a915455b4a2L,0x60e06af289ff99L,
  29168. 0x579fe4bed999e5L,0x2bc03b15e6d9ddL,0x1689649edd66d5L,
  29169. 0x3165e277dca9d2L },
  29170. { 0x7cb8a529cf5279L,0x57f8035b34d84dL,0x352e2eb26de8f1L,
  29171. 0x6406820c3367c4L,0x5d148f4c899899L,0x483e1408482e15L,
  29172. 0x1680bd1e517606L } },
  29173. /* 83 */
  29174. { { 0x5c877cc1c90202L,0x2881f158eae1f4L,0x6f45e207df4267L,
  29175. 0x59280eba1452d8L,0x4465b61e267db5L,0x171f1137e09e5cL,
  29176. 0x1368eb821daa93L },
  29177. { 0x70fe26e3e66861L,0x52a6663170da7dL,0x71d1ce5b7d79dcL,
  29178. 0x1cffe9be1e1afdL,0x703745115a29c4L,0x73b7f897b2f65aL,
  29179. 0x02218c3a95891aL } },
  29180. /* 84 */
  29181. { { 0x16866db8a9e8c9L,0x4770b770123d9bL,0x4c116cf34a8465L,
  29182. 0x079b28263fc86aL,0x3751c755a72b58L,0x7bc8df1673243aL,
  29183. 0x12fff72454f064L },
  29184. { 0x15c049b89554e7L,0x4ea9ef44d7cd9aL,0x42f50765c0d4f1L,
  29185. 0x158bb603cb011bL,0x0809dde16470b1L,0x63cad7422ea819L,
  29186. 0x38b6cd70f90d7eL } },
  29187. /* 85 */
  29188. { { 0x1e4aab6328e33fL,0x70575f026da3aeL,0x7e1b55c8c55219L,
  29189. 0x328d4b403d24caL,0x03b6df1f0a5bd1L,0x26b4bb8b648ed0L,
  29190. 0x17161f2f10b76aL },
  29191. { 0x6cdb32bae8b4c0L,0x33176266227056L,0x4975fa58519b45L,
  29192. 0x254602ea511d96L,0x4e82e93e402a67L,0x0ca8b5929cdb4fL,
  29193. 0x3ae7e0a07918f5L } },
  29194. /* 86 */
  29195. { { 0x60f9d1fecf5b9bL,0x6257e40d2cd469L,0x6c7aa814d28456L,
  29196. 0x58aac7caac8e79L,0x703a55f0293cbfL,0x702390a0f48378L,
  29197. 0x24b9ae07218b07L },
  29198. { 0x1ebc66cdaf24e3L,0x7d9ae5f9f8e199L,0x42055ee921a245L,
  29199. 0x035595936e4d49L,0x129c45d425c08bL,0x6486c5f19ce6ddL,
  29200. 0x027dbd5f18ba24L } },
  29201. /* 87 */
  29202. { { 0x7d6b78d29375fbL,0x0a3dc6ba22ae38L,0x35090fa91feaf6L,
  29203. 0x7f18587fb7b16eL,0x6e7091dd924608L,0x54e102cdbf5ff8L,
  29204. 0x31b131a4c22079L },
  29205. { 0x368f87d6a53fb0L,0x1d3f3d69a3f240L,0x36bf5f9e40e1c6L,
  29206. 0x17f150e01f8456L,0x76e5d0835eb447L,0x662fc0a1207100L,
  29207. 0x14e3dd97a98e39L } },
  29208. /* 88 */
  29209. { { 0x0249d9c2663b4bL,0x56b68f9a71ba1cL,0x74b119567f9c02L,
  29210. 0x5e6f336d8c92acL,0x2ced58f9f74a84L,0x4b75a2c2a467c5L,
  29211. 0x30557011cf740eL },
  29212. { 0x6a87993be454ebL,0x29b7076fb99a68L,0x62ae74aaf99bbaL,
  29213. 0x399f9aa8fb6c1bL,0x553c24a396dd27L,0x2868337a815ea6L,
  29214. 0x343ab6635cc776L } },
  29215. /* 89 */
  29216. { { 0x0e0b0eec142408L,0x79728229662121L,0x605d0ac75e6250L,
  29217. 0x49a097a01edfbeL,0x1e20cd270df6b6L,0x7438a0ca9291edL,
  29218. 0x29daa430da5f90L },
  29219. { 0x7a33844624825aL,0x181715986985c1L,0x53a6853cae0b92L,
  29220. 0x6d98401bd925e8L,0x5a0a34f5dd5e24L,0x7b818ef53cf265L,
  29221. 0x0836e43c9d3194L } },
  29222. /* 90 */
  29223. { { 0x1179b70e6c5fd9L,0x0246d9305dd44cL,0x635255edfbe2fbL,
  29224. 0x5397b3523b4199L,0x59350cc47e6640L,0x2b57aa97ed4375L,
  29225. 0x37efd31abd153aL },
  29226. { 0x7a7afa6907f4faL,0x75c10cb94e6a7eL,0x60a925ab69cc47L,
  29227. 0x2ff5bcd9239bd5L,0x13c2113e425f11L,0x56bd3d2f8a1437L,
  29228. 0x2c9adbab13774fL } },
  29229. /* 91 */
  29230. { { 0x4ab9f52a2e5f2bL,0x5e537e70b58903L,0x0f242658ebe4f2L,
  29231. 0x2648a1e7a5f9aeL,0x1b4c5081e73007L,0x6827d4aff51850L,
  29232. 0x3925e41726cd01L },
  29233. { 0x56dd8a55ab3cfbL,0x72d6a31b6d5beaL,0x697bd2e5575112L,
  29234. 0x66935519a7aa12L,0x55e97dda7a3aceL,0x0e16afb4237b4cL,
  29235. 0x00b68fbff08093L } },
  29236. /* 92 */
  29237. { { 0x4b00366481d0d9L,0x37cb031fbfc5c4L,0x14643f6800dd03L,
  29238. 0x6793fef60fe0faL,0x4f43e329c92803L,0x1fce86b96a6d26L,
  29239. 0x0ad416975e213aL },
  29240. { 0x7cc6a6711adcc9L,0x64b8a63c43c2d9L,0x1e6caa2a67c0d0L,
  29241. 0x610deffd17a54bL,0x57d669d5f38423L,0x77364b8f022636L,
  29242. 0x36d4d13602e024L } },
  29243. /* 93 */
  29244. { { 0x72e667ae50a2f5L,0x1b15c950c3a21aL,0x3ccc37c72e6dfeL,
  29245. 0x027f7e1d094fb8L,0x43ae1e90aa5d7eL,0x3f5feac3d97ce5L,
  29246. 0x0363ed0a336e55L },
  29247. { 0x235f73d7663784L,0x5d8cfc588ad5a4L,0x10ab6ff333016eL,
  29248. 0x7d8886af2e1497L,0x549f34fd17988eL,0x3fc4fcaee69a33L,
  29249. 0x0622b133a13d9eL } },
  29250. /* 94 */
  29251. { { 0x6344cfa796c53eL,0x0e9a10d00136fdL,0x5d1d284a56efd8L,
  29252. 0x608b1968f8aca7L,0x2fa5a66776edcaL,0x13430c44f1609cL,
  29253. 0x1499973cb2152aL },
  29254. { 0x3764648104ab58L,0x3226e409fadafcL,0x1513a8466459ddL,
  29255. 0x649206ec365035L,0x46149aa3f765b1L,0x3aebf0a035248eL,
  29256. 0x1ee60b8c373494L } },
  29257. /* 95 */
  29258. { { 0x4e9efcc15f3060L,0x5e5d50fd77cdc8L,0x071e5403516b58L,
  29259. 0x1b7d4e89b24ceaL,0x53b1fa66d6dc03L,0x457f15f892ab5fL,
  29260. 0x076332c9397260L },
  29261. { 0x31422b79d7584bL,0x0b01d47e41ba80L,0x3e5611a3171528L,
  29262. 0x5f53b9a9fc1be4L,0x7e2fc3d82f110fL,0x006cf350ef0fbfL,
  29263. 0x123ae98ec81c12L } },
  29264. /* 96 */
  29265. { { 0x310d41df46e2f6L,0x2ff032a286cf13L,0x64751a721c4eadL,
  29266. 0x7b62bcc0339b95L,0x49acf0c195afa4L,0x359d48742544e5L,
  29267. 0x276b7632d9e2afL },
  29268. { 0x656c6be182579aL,0x75b65a4d85b199L,0x04a911d1721bfaL,
  29269. 0x46e023d0e33477L,0x1ec2d580acd869L,0x540b456f398a37L,
  29270. 0x001f698210153dL } },
  29271. /* 97 */
  29272. { { 0x3ca35217b00dd0L,0x73961d034f4d3cL,0x4f520b61c4119dL,
  29273. 0x4919fde5cccff7L,0x4d0e0e6f38134dL,0x55c22586003e91L,
  29274. 0x24d39d5d8f1b19L },
  29275. { 0x4d4fc3d73234dcL,0x40c50c9d5f8368L,0x149afbc86bf2b8L,
  29276. 0x1dbafefc21d7f1L,0x42e6b61355107fL,0x6e506cf4b54f29L,
  29277. 0x0f498a6c615228L } },
  29278. /* 98 */
  29279. { { 0x30618f437cfaf8L,0x059640658532c4L,0x1c8a4d90e96e1dL,
  29280. 0x4a327bcca4fb92L,0x54143b8040f1a0L,0x4ec0928c5a49e4L,
  29281. 0x2af5ad488d9b1fL },
  29282. { 0x1b392bd5338f55L,0x539c0292b41823L,0x1fe35d4df86a02L,
  29283. 0x5fa5bb17988c65L,0x02b6cb715adc26L,0x09a48a0c2cb509L,
  29284. 0x365635f1a5a9f2L } },
  29285. /* 99 */
  29286. { { 0x58aa87bdc21f31L,0x156900c7cb1935L,0x0ec1f75ee2b6cfL,
  29287. 0x5f3e35a77ec314L,0x582dec7b9b7621L,0x3e65deb0e8202aL,
  29288. 0x325c314b8a66b7L },
  29289. { 0x702e2a22f24d66L,0x3a20e9982014f1L,0x6424c5b86bbfb0L,
  29290. 0x424eea4d795351L,0x7fc4cce7c22055L,0x581383fceb92d7L,
  29291. 0x32b663f49ee81bL } },
  29292. /* 100 */
  29293. { { 0x76e2d0b648b73eL,0x59ca39fa50bddaL,0x18bb44f786a7e4L,
  29294. 0x28c8d49d464360L,0x1b8bf1d3a574eaL,0x7c670b9bf1635aL,
  29295. 0x2efb30a291f4b3L },
  29296. { 0x5326c069cec548L,0x03bbe481416531L,0x08a415c8d93d6fL,
  29297. 0x3414a52120d383L,0x1f17a0fc6e9c5cL,0x0de9a090717463L,
  29298. 0x22d84b3c67ff07L } },
  29299. /* 101 */
  29300. { { 0x30b5014c3830ebL,0x70791dc1a18b37L,0x09e6ea4e24f423L,
  29301. 0x65e148a5253132L,0x446f05d5d40449L,0x7ad5d3d707c0e9L,
  29302. 0x18eedd63dd3ab5L },
  29303. { 0x40d2eac6bb29e0L,0x5b0e9605e83c38L,0x554f2c666a56a8L,
  29304. 0x0ac27b6c94c48bL,0x1aaecdd91bafe5L,0x73c6e2bdf72634L,
  29305. 0x306dab96d19e03L } },
  29306. /* 102 */
  29307. { { 0x6d3e4b42772f41L,0x1aba7796f3a39bL,0x3a03fbb980e9c0L,
  29308. 0x2f2ea5da2186a8L,0x358ff444ef1fcfL,0x0798cc0329fcdcL,
  29309. 0x39a28bcc9aa46dL },
  29310. { 0x42775c977fe4d2L,0x5eb8fc5483d6b0L,0x0bfe37c039e3f7L,
  29311. 0x429292eaf9df60L,0x188bdf4b840cd5L,0x06e10e090749cdL,
  29312. 0x0e52678e73192eL } },
  29313. /* 103 */
  29314. { { 0x05de80b08df5feL,0x2af8c77406c5f8L,0x53573c50a0304aL,
  29315. 0x277b10b751bca0L,0x65cf8c559132a5L,0x4c667abe25f73cL,
  29316. 0x0271809e05a575L },
  29317. { 0x41ced461f7a2fbL,0x0889a9ebdd7075L,0x320c63f2b7760eL,
  29318. 0x4f8d4324151c63L,0x5af47315be2e5eL,0x73c62f6aee2885L,
  29319. 0x206d6412a56a97L } },
  29320. /* 104 */
  29321. { { 0x6b1c508b21d232L,0x3781185974ead6L,0x1aba7c3ebe1fcfL,
  29322. 0x5bdc03cd3f3a5aL,0x74a25036a0985bL,0x5929e30b7211b2L,
  29323. 0x16a9f3bc366bd7L },
  29324. { 0x566a7057dcfffcL,0x23b5708a644bc0L,0x348cda2aa5ba8cL,
  29325. 0x466aa96b9750d4L,0x6a435ed9b20834L,0x2e7730f2cf9901L,
  29326. 0x2b5cd71d5b0410L } },
  29327. /* 105 */
  29328. { { 0x285ab3cee76ef4L,0x68895e3a57275dL,0x6fab2e48fd1265L,
  29329. 0x0f1de060428c94L,0x668a2b080b5905L,0x1b589dc3b0cb37L,
  29330. 0x3c037886592c9bL },
  29331. { 0x7fb5c0f2e90d4dL,0x334eefb3d8c91aL,0x75747124700388L,
  29332. 0x547a2c2e2737f5L,0x2af9c080e37541L,0x0a295370d9091aL,
  29333. 0x0bb5c36dad99e6L } },
  29334. /* 106 */
  29335. { { 0x644116586f25cbL,0x0c3f41f9ee1f5dL,0x00628d43a3dedaL,
  29336. 0x16e1437aae9669L,0x6aba7861bf3e59L,0x60735631ff4c44L,
  29337. 0x345609efaa615eL },
  29338. { 0x41f54792e6acefL,0x4791583f75864dL,0x37f2ff5c7508b1L,
  29339. 0x1288912516c3b0L,0x51a2135f6a539bL,0x3b775511f42091L,
  29340. 0x127c6afa7afe66L } },
  29341. /* 107 */
  29342. { { 0x79f4f4f7492b73L,0x583d967256342dL,0x51a729bff33ca3L,
  29343. 0x3977d2c22d8986L,0x066f528ba8d40bL,0x5d759d30f8eb94L,
  29344. 0x0f8e649192b408L },
  29345. { 0x22d84e752555bbL,0x76953855c728c7L,0x3b2254e72aaaa4L,
  29346. 0x508cd4ce6c0212L,0x726296d6b5a6daL,0x7a77aa066986f3L,
  29347. 0x2267a497bbcf31L } },
  29348. /* 108 */
  29349. { { 0x7f3651bf825dc4L,0x3988817388c56fL,0x257313ed6c3dd0L,
  29350. 0x3feab7f3b8ffadL,0x6c0d3cb9e9c9b4L,0x1317be0a7b6ac4L,
  29351. 0x2a5f399d7df850L },
  29352. { 0x2fe5a36c934f5eL,0x429199df88ded1L,0x435ea21619b357L,
  29353. 0x6aac6a063bac2bL,0x600c149978f5edL,0x76543aa1114c95L,
  29354. 0x163ca9c83c7596L } },
  29355. /* 109 */
  29356. { { 0x7dda4a3e4daedbL,0x1824cba360a4cdL,0x09312efd70e0c6L,
  29357. 0x454e68a146c885L,0x40aee762fe5c47L,0x29811cbd755a59L,
  29358. 0x34b37c95f28319L },
  29359. { 0x77c58b08b717d2L,0x309470d9a0f491L,0x1ab9f40448e01cL,
  29360. 0x21c8bd819207b1L,0x6a01803e9361bcL,0x6e5e4c350ec415L,
  29361. 0x14fd55a91f8798L } },
  29362. /* 110 */
  29363. { { 0x4cee562f512a90L,0x0008361d53e390L,0x3789b307a892cfL,
  29364. 0x064f7be8770ae9L,0x41435d848762cfL,0x662204dd38baa6L,
  29365. 0x23d6dcf73f6c5aL },
  29366. { 0x69bef2d2c75d95L,0x2b037c0c9bb43eL,0x495fb4d79a34cfL,
  29367. 0x184e140c601260L,0x60193f8d435f9cL,0x283fa52a0c3ad2L,
  29368. 0x1998635e3a7925L } },
  29369. /* 111 */
  29370. { { 0x1cfd458ce382deL,0x0dddbd201bbcaeL,0x14d2ae8ed45d60L,
  29371. 0x73d764ab0c24cbL,0x2a97fe899778adL,0x0dbd1e01eddfe9L,
  29372. 0x2ba5c72d4042c3L },
  29373. { 0x27eebc3af788f1L,0x53ffc827fc5a30L,0x6d1d0726d35188L,
  29374. 0x4721275c50aa2aL,0x077125f02e690fL,0x6da8142405db5dL,
  29375. 0x126cef68992513L } },
  29376. /* 112 */
  29377. { { 0x3c6067035b2d69L,0x2a1ad7db2361acL,0x3debece6cad41cL,
  29378. 0x30095b30f9afc1L,0x25f50b9bd9c011L,0x79201b2f2c1da1L,
  29379. 0x3b5c151449c5bdL },
  29380. { 0x76eff4127abdb4L,0x2d31e03ce0382aL,0x24ff21f8bda143L,
  29381. 0x0671f244fd3ebaL,0x0c1c00b6bcc6fbL,0x18de9f7c3ebefbL,
  29382. 0x33dd48c3809c67L } },
  29383. /* 113 */
  29384. { { 0x61d6c2722d94edL,0x7e426e31041cceL,0x4097439f1b47b0L,
  29385. 0x579e798b2d205bL,0x6a430d67f830ebL,0x0d2c676700f727L,
  29386. 0x05fea83a82f25bL },
  29387. { 0x3f3482df866b98L,0x3dd353b6a5a9cdL,0x77fe6ae1a48170L,
  29388. 0x2f75cc2a8f7cddL,0x7442a3863dad17L,0x643de42d877a79L,
  29389. 0x0fec8a38fe7238L } },
  29390. /* 114 */
  29391. { { 0x79b70c0760ac07L,0x195d3af37e9b29L,0x1317ff20f7cf27L,
  29392. 0x624e1c739e7504L,0x67330ef50f943dL,0x775e8cf455d793L,
  29393. 0x17b94d2d913a9fL },
  29394. { 0x4b627203609e7fL,0x06aac5fb93e041L,0x603c515fdc2611L,
  29395. 0x2592ca0d7ae472L,0x02395d1f50a6cbL,0x466ef9648f85d9L,
  29396. 0x297cf879768f72L } },
  29397. /* 115 */
  29398. { { 0x3489d67d85fa94L,0x0a6e5b739c8e04L,0x7ebb5eab442e90L,
  29399. 0x52665a007efbd0L,0x0967ca57b0d739L,0x24891f9d932b63L,
  29400. 0x3cc2d6dbadc9d3L },
  29401. { 0x4b4773c81c5338L,0x73cd47dad7a0f9L,0x7c755bab6ae158L,
  29402. 0x50b03d6becefcaL,0x574d6e256d57f0L,0x188db4fffb92aeL,
  29403. 0x197e10118071eaL } },
  29404. /* 116 */
  29405. { { 0x45d0cbcba1e7f1L,0x1180056abec91aL,0x6c5f86624bbc28L,
  29406. 0x442c83f3b8e518L,0x4e16ae1843ecb4L,0x670cef2fd786c9L,
  29407. 0x205b4acb637d2cL },
  29408. { 0x70b0e539aa8671L,0x67c982056bebd0L,0x645c831a5e7c36L,
  29409. 0x09e06951a14b32L,0x5dd610ad4c89e6L,0x41c35f20164831L,
  29410. 0x3821f29cb4cdb8L } },
  29411. /* 117 */
  29412. { { 0x2831ffaba10079L,0x70f6dac9ffe444L,0x1cfa32ccc03717L,
  29413. 0x01519fda22a3c8L,0x23215e815aaa27L,0x390671ad65cbf7L,
  29414. 0x03dd4d72de7d52L },
  29415. { 0x1ecd972ee95923L,0x166f8da3813e8eL,0x33199bbd387a1aL,
  29416. 0x04525fe15e3dc7L,0x44d2ef54165898L,0x4b7e47d3dc47f7L,
  29417. 0x10d5c8db0b5d44L } },
  29418. /* 118 */
  29419. { { 0x176d95ba9cdb1bL,0x14025f04f23dfcL,0x49379332891687L,
  29420. 0x6625e5ccbb2a57L,0x7ac0abdbf9d0e5L,0x7aded4fbea15b2L,
  29421. 0x314844ac184d67L },
  29422. { 0x6d9ce34f05eae3L,0x3805d2875856d2L,0x1c2122f85e40ebL,
  29423. 0x51cb9f2d483a9aL,0x367e91e20f1702L,0x573c3559838dfdL,
  29424. 0x0b282b0cb85af1L } },
  29425. /* 119 */
  29426. { { 0x6a12e4ef871eb5L,0x64bb517e14f5ffL,0x29e04d3aaa530bL,
  29427. 0x1b07d88268f261L,0x411be11ed16fb0L,0x1f480536db70bfL,
  29428. 0x17a7deadfd34e4L },
  29429. { 0x76d72f30646612L,0x5a3bbb43a1b0a0L,0x5e1687440e82bfL,
  29430. 0x713b5e69481112L,0x46c3dcb499e174L,0x0862da3b4e2a24L,
  29431. 0x31cb55b4d62681L } },
  29432. /* 120 */
  29433. { { 0x5ffc74dae5bb45L,0x18944c37adb9beL,0x6aaa63b1ee641aL,
  29434. 0x090f4b6ee057d3L,0x4045cedd2ee00fL,0x21c2c798f7c282L,
  29435. 0x2c2c6ef38cd6bdL },
  29436. { 0x40d78501a06293L,0x56f8caa5cc89a8L,0x7231d5f91b37aeL,
  29437. 0x655f1e5a465c6dL,0x3f59a81f9cf783L,0x09bbba04c23624L,
  29438. 0x0f71ee23bbacdeL } },
  29439. /* 121 */
  29440. { { 0x38d398c4741456L,0x5204c0654243c3L,0x34498c916ea77eL,
  29441. 0x12238c60e5fe43L,0x0fc54f411c7625L,0x30b2ca43aa80b6L,
  29442. 0x06bead1bb6ea92L },
  29443. { 0x5902ba8674b4adL,0x075ab5b0fa254eL,0x58db83426521adL,
  29444. 0x5b66b6b3958e39L,0x2ce4e39890e07bL,0x46702513338b37L,
  29445. 0x363690c2ded4d7L } },
  29446. /* 122 */
  29447. { { 0x765642c6b75791L,0x0f4c4300d7f673L,0x404d8bbe101425L,
  29448. 0x61e91c88651f1bL,0x61ddc9bc60aed8L,0x0ef36910ce2e65L,
  29449. 0x04b44367aa63b8L },
  29450. { 0x72822d3651b7dcL,0x4b750157a2716dL,0x091cb4f2118d16L,
  29451. 0x662ba93b101993L,0x447cbd54a1d40aL,0x12cdd48d674848L,
  29452. 0x16f10415cbec69L } },
  29453. /* 123 */
  29454. { { 0x0c57a3a751cd0eL,0x0833d7478fadceL,0x1e751f55686436L,
  29455. 0x489636c58e1df7L,0x26ad6da941266fL,0x22225d3559880fL,
  29456. 0x35b397c45ba0e2L },
  29457. { 0x3ca97b70e1f2ceL,0x78e50427a8680cL,0x06137e042a8f91L,
  29458. 0x7ec40d2500b712L,0x3f0ad688ad7b0dL,0x24746fb33f9513L,
  29459. 0x3638fcce688f0bL } },
  29460. /* 124 */
  29461. { { 0x753163750bed6fL,0x786507cd16157bL,0x1d6ec228ce022aL,
  29462. 0x587255f42d1b31L,0x0c6adf72a3a0f6L,0x4bfeee2da33f5eL,
  29463. 0x08b7300814de6cL },
  29464. { 0x00bf8df9a56e11L,0x75aead48fe42e8L,0x3de9bad911b2e2L,
  29465. 0x0fadb233e4b8bbL,0x5b054e8fd84f7dL,0x5eb3064152889bL,
  29466. 0x01c1c6e8c777a1L } },
  29467. /* 125 */
  29468. { { 0x5fa0e598f8fcb9L,0x11c129a1ae18dfL,0x5c41b482a2273bL,
  29469. 0x545664e5044c9cL,0x7e01c915bfb9abL,0x7f626e19296aa0L,
  29470. 0x20c91a9822a087L },
  29471. { 0x273a9fbe3c378fL,0x0f126b44b7d350L,0x493764a75df951L,
  29472. 0x32dec3c367d24bL,0x1a7ae987fed9d3L,0x58a93055928b85L,
  29473. 0x11626975d7775fL } },
  29474. /* 126 */
  29475. { { 0x2bb174a95540a9L,0x10de02c58b613fL,0x2fa8f7b861f3eeL,
  29476. 0x44731260bdf3b3L,0x19c38ff7da41feL,0x3535a16e3d7172L,
  29477. 0x21a948b83cc7feL },
  29478. { 0x0e6f72868bc259L,0x0c70799df3c979L,0x526919955584c3L,
  29479. 0x4d95fda04f8fa2L,0x7bb228e6c0f091L,0x4f728b88d92194L,
  29480. 0x2b361c5a136bedL } },
  29481. /* 127 */
  29482. { { 0x0c72ca10c53841L,0x4036ab49f9da12L,0x578408d2b7082bL,
  29483. 0x2c4903201fbf5eL,0x14722b3f42a6a8L,0x1997b786181694L,
  29484. 0x25c6f10de32849L },
  29485. { 0x79f46d517ff2ffL,0x2dc5d97528f6deL,0x518a494489aa72L,
  29486. 0x52748f8af3cf97L,0x472da30a96bb16L,0x1be228f92465a9L,
  29487. 0x196f0c47d60479L } },
  29488. /* 128 */
  29489. { { 0x47dd7d139b3239L,0x049c9b06775d0fL,0x627ffc00562d5eL,
  29490. 0x04f578d5e5e243L,0x43a788ffcef8b9L,0x7db320be9dde28L,
  29491. 0x00837528b8572fL },
  29492. { 0x2969eca306d695L,0x195b72795ec194L,0x5e1fa9b8e77e50L,
  29493. 0x4c627f2b3fbfd5L,0x4b91e0d0ee10ffL,0x5698c8d0f35833L,
  29494. 0x12d3a9431f475eL } },
  29495. /* 129 */
  29496. { { 0x6409457a0db57eL,0x795b35192e0433L,0x146f973fe79805L,
  29497. 0x3d49c516dfb9cfL,0x50dfc3646b3cdaL,0x16a08a2210ad06L,
  29498. 0x2b4ef5bcd5b826L },
  29499. { 0x5ebabfee2e3e3eL,0x2e048e724d9726L,0x0a7a7ed6abef40L,
  29500. 0x71ff7f83e39ad8L,0x3405ac52a1b852L,0x2e3233357a608dL,
  29501. 0x38c1bf3b0e40e6L } },
  29502. /* 130 */
  29503. { { 0x59aec823e4712cL,0x6ed9878331ddadL,0x1cc6faf629f2a0L,
  29504. 0x445ff79f36c18cL,0x4edc7ed57aff3dL,0x22ee54c8bdd9e8L,
  29505. 0x35398f42d72ec5L },
  29506. { 0x4e7a1cceee0ecfL,0x4c66a707dd1d31L,0x629ad157a23c04L,
  29507. 0x3b2c6031dc3c83L,0x3336acbcd3d96cL,0x26ce43adfce0f0L,
  29508. 0x3c869c98d699dcL } },
  29509. /* 131 */
  29510. { { 0x58b3cd9586ba11L,0x5d6514b8090033L,0x7c88c3bd736782L,
  29511. 0x1735f84f2130edL,0x47784095a9dee0L,0x76312c6e47901bL,
  29512. 0x1725f6ebc51455L },
  29513. { 0x6744344bc4503eL,0x16630b4d66e12fL,0x7b3481752c3ec7L,
  29514. 0x47bb2ed1f46f95L,0x08a1a497dd1bcfL,0x1f525df2b8ed93L,
  29515. 0x0fe492ea993713L } },
  29516. /* 132 */
  29517. { { 0x71b8dd7268b448L,0x1743dfaf3728d7L,0x23938d547f530aL,
  29518. 0x648c3d497d0fc6L,0x26c0d769e3ad45L,0x4d25108769a806L,
  29519. 0x3fbf2025143575L },
  29520. { 0x485bfd90339366L,0x2de2b99ed87461L,0x24a33347713badL,
  29521. 0x1674bc7073958aL,0x5bb2373ee85b5fL,0x57f9bd657e662cL,
  29522. 0x2041b248d39042L } },
  29523. /* 133 */
  29524. { { 0x5f01617d02f4eeL,0x2a8e31c4244b91L,0x2dab3e790229e0L,
  29525. 0x72d319ea7544afL,0x01ffb8b000cb56L,0x065e63b0daafd3L,
  29526. 0x3d7200a7111d6fL },
  29527. { 0x4561ce1b568973L,0x37034c532dd8ecL,0x1368215020be02L,
  29528. 0x30e7184cf289ebL,0x199e0c27d815deL,0x7ee1b4dff324e5L,
  29529. 0x2f4a11de7fab5cL } },
  29530. /* 134 */
  29531. { { 0x33c2f99b1cdf2bL,0x1e0d78bf42a2c0L,0x64485dececaa67L,
  29532. 0x2242a41be93e92L,0x62297b1f15273cL,0x16ebfaafb02205L,
  29533. 0x0f50f805f1fdabL },
  29534. { 0x28bb0b3a70eb28L,0x5b1c7d0160d683L,0x05c30a37959f78L,
  29535. 0x3d9301184922d2L,0x46c1ead7dbcb1aL,0x03ee161146a597L,
  29536. 0x2d413ed9a6ccc1L } },
  29537. /* 135 */
  29538. { { 0x685ab5f97a27c2L,0x59178214023751L,0x4ffef3c585ab17L,
  29539. 0x2bc85302aba2a9L,0x675b001780e856L,0x103c8a37f0b33dL,
  29540. 0x2241e98ece70a6L },
  29541. { 0x546738260189edL,0x086c8f7a6b96edL,0x00832ad878a129L,
  29542. 0x0b679056ba7462L,0x020ce6264bf8c4L,0x3f9f4b4d92abfbL,
  29543. 0x3e9c55343c92edL } },
  29544. /* 136 */
  29545. { { 0x482cec9b3f5034L,0x08b59b3cd1fa30L,0x5a55d1bc8e58b5L,
  29546. 0x464a5259337d8eL,0x0a5b6c66ade5a5L,0x55db77b504ddadL,
  29547. 0x015992935eac35L },
  29548. { 0x54fe51025e32fcL,0x5d7f52dbe4a579L,0x08c564a8c58696L,
  29549. 0x4482a8bec4503fL,0x440e75d9d94de9L,0x6992d768020bfaL,
  29550. 0x06c311e8ba01f6L } },
  29551. /* 137 */
  29552. { { 0x2a6ac808223878L,0x04d3ccb4aab0b8L,0x6e6ef09ff6e823L,
  29553. 0x15cb03ee9158dcL,0x0dc58919171bf7L,0x3273568abf3cb1L,
  29554. 0x1b55245b88d98bL },
  29555. { 0x28e9383b1de0c1L,0x30d5009e4f1f1bL,0x334d185a56a134L,
  29556. 0x0875865dfa4c46L,0x266edf5eae3beeL,0x2e03ff16d1f7e5L,
  29557. 0x29a36bd9f0c16dL } },
  29558. /* 138 */
  29559. { { 0x004cff44b2e045L,0x426c96380ba982L,0x422292281e46d7L,
  29560. 0x508dd8d29d7204L,0x3a4ea73fb2995eL,0x4be64090ae07b2L,
  29561. 0x3339177a0eff22L },
  29562. { 0x74a97ec2b3106eL,0x0c616d09169f5fL,0x1bb5d8907241a7L,
  29563. 0x661fb67f6d41bdL,0x018a88a0daf136L,0x746333a093a7b4L,
  29564. 0x3e19f1ac76424eL } },
  29565. /* 139 */
  29566. { { 0x542a5656527296L,0x0e7b9ce22f1bc9L,0x31b0945992b89bL,
  29567. 0x6e0570eb85056dL,0x32daf813483ae5L,0x69eeae9d59bb55L,
  29568. 0x315ad4b730b557L },
  29569. { 0x2bc16795f32923L,0x6b02b7ba55130eL,0x1e9da67c012f85L,
  29570. 0x5616f014dabf8fL,0x777395fcd9c723L,0x2ff075e7743246L,
  29571. 0x2993538aff142eL } },
  29572. /* 140 */
  29573. { { 0x72dae20e552b40L,0x2e4ba69aa5d042L,0x001e563e618bd2L,
  29574. 0x28feeba3c98772L,0x648c356da2a907L,0x687e2325069ea7L,
  29575. 0x0d34ab09a394f0L },
  29576. { 0x73c21813111286L,0x5829b53b304e20L,0x6fba574de08076L,
  29577. 0x79f7058f61614eL,0x4e71c9316f1191L,0x24ef12193e0a89L,
  29578. 0x35dc4e2bc9d848L } },
  29579. /* 141 */
  29580. { { 0x045e6d3b4ad1cdL,0x729c95493782f0L,0x77f59de85b361aL,
  29581. 0x5309b4babf28f8L,0x4d893d9290935fL,0x736f47f2b2669eL,
  29582. 0x23270922d757f3L },
  29583. { 0x23a4826f70d4e9L,0x68a8c63215d33eL,0x4d6c2069205c9cL,
  29584. 0x46b2938a5eebe0L,0x41d1f1e2de3892L,0x5ca1775544bcb0L,
  29585. 0x3130629e5d19dcL } },
  29586. /* 142 */
  29587. { { 0x6e2681593375acL,0x117cfbabc22621L,0x6c903cd4e13ccaL,
  29588. 0x6f358f14d4bd97L,0x1bc58fa11089f1L,0x36aa2db4ac426aL,
  29589. 0x15ced8464b7ea1L },
  29590. { 0x6966836cba7df5L,0x7c2b1851568113L,0x22b50ff2ffca66L,
  29591. 0x50e77d9f48e49aL,0x32775e9bbc7cc9L,0x403915bb0ece71L,
  29592. 0x1b8ec7cb9dd7aaL } },
  29593. /* 143 */
  29594. { { 0x65a888b677788bL,0x51887fac2e7806L,0x06792636f98d2bL,
  29595. 0x47bbcd59824c3bL,0x1aca908c43e6dcL,0x2e00d15c708981L,
  29596. 0x08e031c2c80634L },
  29597. { 0x77fbc3a297c5ecL,0x10a7948af2919eL,0x10cdafb1fb6b2fL,
  29598. 0x27762309b486f0L,0x13abf26bbac641L,0x53da38478fc3eeL,
  29599. 0x3c22eff379bf55L } },
  29600. /* 144 */
  29601. { { 0x0163f484770ee3L,0x7f28e8942e0cbfL,0x5f86cb51b43831L,
  29602. 0x00feccd4e4782fL,0x40e5b417eafe7dL,0x79e5742bbea228L,
  29603. 0x3717154aa469beL },
  29604. { 0x271d74a270f721L,0x40eb400890b70cL,0x0e37be81d4cb02L,
  29605. 0x786907f4e8d43fL,0x5a1f5b590a7acbL,0x048861883851fdL,
  29606. 0x11534a1e563dbbL } },
  29607. /* 145 */
  29608. { { 0x37a6357c525435L,0x6afe6f897b78a5L,0x7b7ff311d4f67bL,
  29609. 0x38879df15dc9f4L,0x727def7b8ba987L,0x20285dd0db4436L,
  29610. 0x156b0fc64b9243L },
  29611. { 0x7e3a6ec0c1c390L,0x668a88d9bcf690L,0x5925aba5440dbeL,
  29612. 0x0f6891a044f593L,0x70b46edfed4d97L,0x1a6cc361bab201L,
  29613. 0x046f5bc6e160bcL } },
  29614. /* 146 */
  29615. { { 0x79350f076bc9d1L,0x077d9e79a586b9L,0x0896bc0c705764L,
  29616. 0x58e632b90e7e46L,0x14e87e0ad32488L,0x4b1bb3f72c6e00L,
  29617. 0x3c3ce9684a5fc5L },
  29618. { 0x108fbaf1f703aaL,0x08405ecec17577L,0x199a8e2d44be73L,
  29619. 0x2eb22ed0067763L,0x633944deda3300L,0x20d739eb8e5efbL,
  29620. 0x2bbbd94086b532L } },
  29621. /* 147 */
  29622. { { 0x03c8b17a19045dL,0x6205a0a504980bL,0x67fdb3e962b9f0L,
  29623. 0x16399e01511a4bL,0x44b09fe9dffc96L,0x00a74ff44a1381L,
  29624. 0x14590deed3f886L },
  29625. { 0x54e3d5c2a23ddbL,0x310e5138209d28L,0x613f45490c1c9bL,
  29626. 0x6bbc85d44bbec8L,0x2f85fc559e73f6L,0x0d71fa7d0fa8cbL,
  29627. 0x2898571d17fbb9L } },
  29628. /* 148 */
  29629. { { 0x5607a84335167dL,0x3009c1eb910f91L,0x7ce63447e62d0bL,
  29630. 0x03a0633afcf89eL,0x1234b5aaa50872L,0x5a307b534d547bL,
  29631. 0x2f4e97138a952eL },
  29632. { 0x13914c2db0f658L,0x6cdcb47e6e75baL,0x5549169caca772L,
  29633. 0x0f20423dfeb16fL,0x6b1ae19d180239L,0x0b7b3bee9b7626L,
  29634. 0x1ca81adacfe4efL } },
  29635. /* 149 */
  29636. { { 0x219ec3ad19d96fL,0x3549f6548132dbL,0x699889c7aacd0bL,
  29637. 0x74602a58730b19L,0x62dc63bcece81cL,0x316f991c0c317aL,
  29638. 0x2b8627867b95e3L },
  29639. { 0x67a25ddced1eedL,0x7e14f0eba756e7L,0x0873fbc09b0495L,
  29640. 0x0fefb0e16596adL,0x03e6cd98ef39bbL,0x1179b1cded249dL,
  29641. 0x35c79c1db1edc2L } },
  29642. /* 150 */
  29643. { { 0x1368309d4245bfL,0x442e55852a7667L,0x095b0f0f348b65L,
  29644. 0x6834cf459dfad4L,0x6645950c9be910L,0x06bd81288c71e6L,
  29645. 0x1b015b6e944edfL },
  29646. { 0x7a6a83045ab0e3L,0x6afe88b9252ad0L,0x2285bd65523502L,
  29647. 0x6c78543879a282L,0x1c5e264b5c6393L,0x3a820c6a7453eeL,
  29648. 0x37562d1d61d3c3L } },
  29649. /* 151 */
  29650. { { 0x6c084f62230c72L,0x599490270bc6cfL,0x1d3369ddd3c53dL,
  29651. 0x516ddb5fac5da0L,0x35ab1e15011b1aL,0x5fba9106d3a180L,
  29652. 0x3be0f092a0917cL },
  29653. { 0x57328f9fdc2538L,0x0526323fc8d5f6L,0x10cbb79521e602L,
  29654. 0x50d01167147ae2L,0x2ec7f1b3cda99eL,0x43073cc736e7beL,
  29655. 0x1ded89cadd83a6L } },
  29656. /* 152 */
  29657. { { 0x1d51bda65d56d5L,0x63f2fd4d2dc056L,0x326413d310ea6dL,
  29658. 0x3abba5bca92876L,0x6b9aa8bc4d6ebeL,0x1961c687f15d5dL,
  29659. 0x311cf07464c381L },
  29660. { 0x2321b1064cd8aeL,0x6e3caac4443850L,0x3346fc4887d2d0L,
  29661. 0x1640417e0e640fL,0x4a958a52a07a9eL,0x1346a1b1cb374cL,
  29662. 0x0a793cf79beccbL } },
  29663. /* 153 */
  29664. { { 0x29d56cba89aaa5L,0x1581898c0b3c15L,0x1af5b77293c082L,
  29665. 0x1617ba53a006ceL,0x62dd3b384e475fL,0x71a9820c3f962aL,
  29666. 0x0e4938920b854eL },
  29667. { 0x0b8d98849808abL,0x64c14923546de7L,0x6a20883b78a6fcL,
  29668. 0x72de211428acd6L,0x009678b47915bbL,0x21b5269ae5dae6L,
  29669. 0x313cc0e60b9457L } },
  29670. /* 154 */
  29671. { { 0x69ee421b1de38bL,0x44b484c6cec1c7L,0x0240596c6a8493L,
  29672. 0x2321a62c85fb9eL,0x7a10921802a341L,0x3d2a95507e45c3L,
  29673. 0x0752f40f3b6714L },
  29674. { 0x596a38798751e6L,0x46bf186a0feb85L,0x0b23093e23b49cL,
  29675. 0x1bfa7bc5afdc07L,0x4ba96f873eefadL,0x292e453fae9e44L,
  29676. 0x2773646667b75cL } },
  29677. /* 155 */
  29678. { { 0x1f81a64e94f22aL,0x3125ee3d8683ddL,0x76a660a13b9582L,
  29679. 0x5aa584c3640c6eL,0x27cc99fd472953L,0x7048f4d58061d1L,
  29680. 0x379a1397ac81e8L },
  29681. { 0x5d1ecd2b6b956bL,0x0829e0366b0697L,0x49548cec502421L,
  29682. 0x7af5e2f717c059L,0x329a25a0fec54eL,0x028e99e4bcd7f1L,
  29683. 0x071d5fe81fca78L } },
  29684. /* 156 */
  29685. { { 0x4b5c4aeb0fdfe4L,0x1367e11326ce37L,0x7c16f020ef5f19L,
  29686. 0x3c55303d77b471L,0x23a4457a06e46aL,0x2174426dd98424L,
  29687. 0x226f592114bd69L },
  29688. { 0x4411b94455f15aL,0x52e0115381fae4L,0x45b6d8efbc8f7eL,
  29689. 0x58b1221bd86d26L,0x284fb6f8a7ec1fL,0x045835939ddd30L,
  29690. 0x0216960accd598L } },
  29691. /* 157 */
  29692. { { 0x4b61f9ec1f138aL,0x4460cd1e18502bL,0x277e4fce3c4726L,
  29693. 0x0244246d6414b9L,0x28fbfcef256984L,0x3347ed0db40577L,
  29694. 0x3b57fa9e044718L },
  29695. { 0x4f73bcd6d1c833L,0x2c0d0dcf7f0136L,0x2010ac75454254L,
  29696. 0x7dc4f6151539a8L,0x0b8929ef6ea495L,0x517e20119d2bdfL,
  29697. 0x1e29f9a126ba15L } },
  29698. /* 158 */
  29699. { { 0x683a7c10470cd8L,0x0d05f0dbe0007fL,0x2f6a5026d649cdL,
  29700. 0x249ce2fdaed603L,0x116dc1e7a96609L,0x199bd8d82a0b98L,
  29701. 0x0694ad0219aeb2L },
  29702. { 0x03a3656e864045L,0x4e552273df82a6L,0x19bcc7553d17abL,
  29703. 0x74ac536c1df632L,0x440302fb4a86f6L,0x1becec0e31c9feL,
  29704. 0x002045f8fa46b8L } },
  29705. /* 159 */
  29706. { { 0x5833ba384310a2L,0x1db83fad93f8baL,0x0a12713ee2f7edL,
  29707. 0x40e0f0fdcd2788L,0x1746de5fb239a5L,0x573748965cfa15L,
  29708. 0x1e3dedda0ef650L },
  29709. { 0x6c8ca1c87607aeL,0x785dab9554fc0eL,0x649d8f91860ac8L,
  29710. 0x4436f88b52c0f9L,0x67f22ca8a5e4a3L,0x1f990fd219e4c9L,
  29711. 0x013dd21c08573fL } },
  29712. /* 160 */
  29713. { { 0x05d116141d161cL,0x5c1d2789da2ea5L,0x11f0d861f99f34L,
  29714. 0x692c2650963153L,0x3bd69f5329539eL,0x215898eef8885fL,
  29715. 0x041f79dd86f7f1L },
  29716. { 0x76dcc5e96beebdL,0x7f2b50cb42a332L,0x067621cabef8abL,
  29717. 0x31e0be607054edL,0x4c67c5e357a3daL,0x5b1a63fbfb1c2bL,
  29718. 0x3112efbf5e5c31L } },
  29719. /* 161 */
  29720. { { 0x3f83e24c0c62f1L,0x51dc9c32aae4e0L,0x2ff89b33b66c78L,
  29721. 0x21b1c7d354142cL,0x243d8d381c84bcL,0x68729ee50cf4b7L,
  29722. 0x0ed29e0f442e09L },
  29723. { 0x1ad7b57576451eL,0x6b2e296d6b91dcL,0x53f2b306e30f42L,
  29724. 0x3964ebd9ee184aL,0x0a32855df110e4L,0x31f2f90ddae05fL,
  29725. 0x3410cd04e23702L } },
  29726. /* 162 */
  29727. { { 0x60d1522ca8f2feL,0x12909237a83e34L,0x15637f80d58590L,
  29728. 0x3c72431b6d714dL,0x7c8e59a615bea2L,0x5f977b688ef35aL,
  29729. 0x071c198c0b3ab0L },
  29730. { 0x2b54c699699b4bL,0x14da473c2fd0bcL,0x7ba818ea0ad427L,
  29731. 0x35117013940b2fL,0x6e1df6b5e609dbL,0x3f42502720b64dL,
  29732. 0x01ee7dc890e524L } },
  29733. /* 163 */
  29734. { { 0x12ec1448ff4e49L,0x3e2edac882522bL,0x20455ab300f93aL,
  29735. 0x5849585bd67c14L,0x0393d5aa34ba8bL,0x30f9a1f2044fa7L,
  29736. 0x1059c9377a93e0L },
  29737. { 0x4e641cc0139e73L,0x0d9f23c9b0fa78L,0x4b2ad87e2b83f9L,
  29738. 0x1c343a9f6d9e3cL,0x1098a4cb46de4dL,0x4ddc893843a41eL,
  29739. 0x1797f4167d6e3aL } },
  29740. /* 164 */
  29741. { { 0x4add4675856031L,0x499bd5e5f7a0ffL,0x39ea1f1202271eL,
  29742. 0x0ecd7480d7a91eL,0x395f5e5fc10956L,0x0fa7f6b0c9f79bL,
  29743. 0x2fad4623aed6cbL },
  29744. { 0x1563c33ae65825L,0x29881cafac827aL,0x50650baf4c45a1L,
  29745. 0x034aad988fb9e9L,0x20a6224dc5904cL,0x6fb141a990732bL,
  29746. 0x3ec9ae1b5755deL } },
  29747. /* 165 */
  29748. { { 0x3108e7c686ae17L,0x2e73a383b4ad8aL,0x4e6bb142ba4243L,
  29749. 0x24d355922c1d80L,0x2f850dd9a088baL,0x21c50325dd5e70L,
  29750. 0x33237dd5bd7fa4L },
  29751. { 0x7823a39cab7630L,0x1535f71cff830eL,0x70d92ff0599261L,
  29752. 0x227154d2a2477cL,0x495e9bbb4f871cL,0x40d2034835686bL,
  29753. 0x31b08f97eaa942L } },
  29754. /* 166 */
  29755. { { 0x0016c19034d8ddL,0x68961627cf376fL,0x6acc90681615aeL,
  29756. 0x6bc7690c2e3204L,0x6ddf28d2fe19a2L,0x609b98f84dae4dL,
  29757. 0x0f32bfd7c94413L },
  29758. { 0x7d7edc6b21f843L,0x49bbd2ebbc9872L,0x593d6ada7b6a23L,
  29759. 0x55736602939e9cL,0x79461537680e39L,0x7a7ee9399ca7cdL,
  29760. 0x008776f6655effL } },
  29761. /* 167 */
  29762. { { 0x64585f777233cfL,0x63ec12854de0f6L,0x6b7f9bbbc3f99dL,
  29763. 0x301c014b1b55d3L,0x7cf3663bbeb568L,0x24959dcb085bd1L,
  29764. 0x12366aa6752881L },
  29765. { 0x77a74c0da5e57aL,0x3279ca93ad939fL,0x33c3c8a1ef08c9L,
  29766. 0x641b05ab42825eL,0x02f416d7d098dbL,0x7e3d58be292b68L,
  29767. 0x1864dbc46e1f46L } },
  29768. /* 168 */
  29769. { { 0x1da167b8153a9dL,0x47593d07d9e155L,0x386d984e12927fL,
  29770. 0x421a6f08a60c7cL,0x5ae9661c24dab3L,0x7927b2e7874507L,
  29771. 0x3266ea80609d53L },
  29772. { 0x7d198f4c26b1e3L,0x430d4ea2c4048eL,0x58d8ab77e84ba3L,
  29773. 0x1cb14299c37297L,0x6db6031e8f695cL,0x159bd855e26d55L,
  29774. 0x3f3f6d318a73ddL } },
  29775. /* 169 */
  29776. { { 0x3ee958cca40298L,0x02a7e5eba32ad6L,0x43b4bab96f0e1eL,
  29777. 0x534be79062b2b1L,0x029ead089b37e3L,0x4d585da558f5aaL,
  29778. 0x1f9737eb43c376L },
  29779. { 0x0426dfd9b86202L,0x4162866bc0a9f3L,0x18fc518e7bb465L,
  29780. 0x6db63380fed812L,0x421e117f709c30L,0x1597f8d0f5cee6L,
  29781. 0x04ffbf1289b06aL } },
  29782. /* 170 */
  29783. { { 0x61a1987ffa0a5fL,0x42058c7fc213c6L,0x15b1d38447d2c9L,
  29784. 0x3d5f5d7932565eL,0x5db754af445fa7L,0x5d489189fba499L,
  29785. 0x02c4c55f51141bL },
  29786. { 0x26b15972e9993dL,0x2fc90bcbd97c45L,0x2ff60f8684b0f1L,
  29787. 0x1dc641dd339ab0L,0x3e38e6be23f82cL,0x3368162752c817L,
  29788. 0x19bba80ceb45ceL } },
  29789. /* 171 */
  29790. { { 0x7c6e95b4c6c693L,0x6bbc6d5efa7093L,0x74d7f90bf3bf1cL,
  29791. 0x54d5be1f0299a1L,0x7cb24f0aa427c6L,0x0a18f3e086c941L,
  29792. 0x058a1c90e4faefL },
  29793. { 0x3d6bd016927e1eL,0x1da4ce773098b8L,0x2133522e690056L,
  29794. 0x0751416d3fc37eL,0x1beed1643eda66L,0x5288b6727d5c54L,
  29795. 0x199320e78655c6L } },
  29796. /* 172 */
  29797. { { 0x74575027eeaf94L,0x124bd533c3ceaeL,0x69421ab7a8a1d7L,
  29798. 0x37f2127e093f3dL,0x40281765252a08L,0x25a228798d856dL,
  29799. 0x326eca62759c4cL },
  29800. { 0x0c337c51acb0a5L,0x122ba78c1ef110L,0x02498adbb68dc4L,
  29801. 0x67240c124b089eL,0x135865d25d9f89L,0x338a76d5ae5670L,
  29802. 0x03a8efaf130385L } },
  29803. /* 173 */
  29804. { { 0x3a450ac5e49beaL,0x282af80bb4b395L,0x6779eb0db1a139L,
  29805. 0x737cabdd174e55L,0x017b14ca79b5f2L,0x61fdef6048e137L,
  29806. 0x3acc12641f6277L },
  29807. { 0x0f730746fe5096L,0x21d05c09d55ea1L,0x64d44bddb1a560L,
  29808. 0x75e5035c4778deL,0x158b7776613513L,0x7b5efa90c7599eL,
  29809. 0x2caa0791253b95L } },
  29810. /* 174 */
  29811. { { 0x288e5b6d53e6baL,0x435228909d45feL,0x33b4cf23b2a437L,
  29812. 0x45b352017d6db0L,0x4372d579d6ef32L,0x0fa9e5badbbd84L,
  29813. 0x3a78cff24759bbL },
  29814. { 0x0899d2039eab6eL,0x4cf47d2f76bc22L,0x373f739a3a8c69L,
  29815. 0x09beaa5b1000b3L,0x0acdfbe83ebae5L,0x10c10befb0e900L,
  29816. 0x33d2ac4cc31be3L } },
  29817. /* 175 */
  29818. { { 0x765845931e08fbL,0x2a3c2a0dc58007L,0x7270da587d90e1L,
  29819. 0x1ee648b2bc8f86L,0x5d2ca68107b29eL,0x2b7064846e9e92L,
  29820. 0x3633ed98dbb962L },
  29821. { 0x5e0f16a0349b1bL,0x58d8941f570ca4L,0x20abe376a4cf34L,
  29822. 0x0f4bd69a360977L,0x21eb07cc424ba7L,0x720d2ecdbbe6ecL,
  29823. 0x255597d5a97c34L } },
  29824. /* 176 */
  29825. { { 0x67bbf21a0f5e94L,0x422a3b05a64fc1L,0x773ac447ebddc7L,
  29826. 0x1a1331c08019f1L,0x01ef6d269744ddL,0x55f7be5b3b401aL,
  29827. 0x072e031c681273L },
  29828. { 0x7183289e21c677L,0x5e0a3391f3162fL,0x5e02d9e65d914aL,
  29829. 0x07c79ea1adce2fL,0x667ca5c2e1cbe4L,0x4f287f22caccdaL,
  29830. 0x27eaa81673e75bL } },
  29831. /* 177 */
  29832. { { 0x5246180a078fe6L,0x67cc8c9fa3bb15L,0x370f8dd123db31L,
  29833. 0x1938dafa69671aL,0x5af72624950c5eL,0x78cc5221ebddf8L,
  29834. 0x22d616fe2a84caL },
  29835. { 0x723985a839327fL,0x24fa95584a5e22L,0x3d8a5b3138d38bL,
  29836. 0x3829ef4a017acfL,0x4f09b00ae055c4L,0x01df84552e4516L,
  29837. 0x2a7a18993e8306L } },
  29838. /* 178 */
  29839. { { 0x7b6224bc310eccL,0x69e2cff429da16L,0x01c850e5722869L,
  29840. 0x2e4889443ee84bL,0x264a8df1b3d09fL,0x18a73fe478d0d6L,
  29841. 0x370b52740f9635L },
  29842. { 0x52b7d3a9d6f501L,0x5c49808129ee42L,0x5b64e2643fd30cL,
  29843. 0x27d903fe31b32cL,0x594cb084d078f9L,0x567fb33e3ae650L,
  29844. 0x0db7be9932cb65L } },
  29845. /* 179 */
  29846. { { 0x19b78113ed7cbeL,0x002b2f097a1c8cL,0x70b1dc17fa5794L,
  29847. 0x786e8419519128L,0x1a45ba376af995L,0x4f6aa84b8d806cL,
  29848. 0x204b4b3bc7ca47L },
  29849. { 0x7581a05fd94972L,0x1c73cadb870799L,0x758f6fefc09b88L,
  29850. 0x35c62ba8049b42L,0x6f5e71fc164cc3L,0x0cd738b5702721L,
  29851. 0x10021afac9a423L } },
  29852. /* 180 */
  29853. { { 0x654f7937e3c115L,0x5d198288b515cbL,0x4add965c25a6e3L,
  29854. 0x5a37df33cd76ffL,0x57bb7e288e1631L,0x049b69089e1a31L,
  29855. 0x383a88f4122a99L },
  29856. { 0x4c0e4ef3d80a73L,0x553c77ac9f30e2L,0x20bb18c2021e82L,
  29857. 0x2aec0d1c4225c5L,0x397fce0ac9c302L,0x2ab0c2a246e8aaL,
  29858. 0x02e5e5190be080L } },
  29859. /* 181 */
  29860. { { 0x7a255a4ae03080L,0x0d68b01513f624L,0x29905bd4e48c8cL,
  29861. 0x1d81507027466bL,0x1684aaeb70dee1L,0x7dd460719f0981L,
  29862. 0x29c43b0f0a390cL },
  29863. { 0x272567681b1f7dL,0x1d2a5f8502e0efL,0x0fd5cd6b221befL,
  29864. 0x5eb4749e9a0434L,0x7d1553a324e2a6L,0x2eefd8e86a7804L,
  29865. 0x2ad80d5335109cL } },
  29866. /* 182 */
  29867. { { 0x25342aef4c209dL,0x24e811ac4e0865L,0x3f209757f8ae9dL,
  29868. 0x1473ff8a5da57bL,0x340f61c3919cedL,0x7523bf85fb9bc0L,
  29869. 0x319602ebca7cceL },
  29870. { 0x121e7541d442cbL,0x4ffa748e49c95cL,0x11493cd1d131dcL,
  29871. 0x42b215172ab6b5L,0x045fd87e13cc77L,0x0ae305df76342fL,
  29872. 0x373b033c538512L } },
  29873. /* 183 */
  29874. { { 0x389541e9539819L,0x769f3b29b7e239L,0x0d05f695e3232cL,
  29875. 0x029d04f0e9a9fbL,0x58b78b7a697fb8L,0x7531b082e6386bL,
  29876. 0x215d235bed95a9L },
  29877. { 0x503947c1859c5dL,0x4b82a6ba45443fL,0x78328eab71b3a5L,
  29878. 0x7d8a77f8cb3509L,0x53fcd9802e41d4L,0x77552091976edbL,
  29879. 0x226c60ad7a5156L } },
  29880. /* 184 */
  29881. { { 0x77ad6a43360710L,0x0fdeabd326d7aeL,0x4012886c92104aL,
  29882. 0x2d6c378dd7ae33L,0x7e72ef2c0725f3L,0x4a4671f4ca18e0L,
  29883. 0x0afe3b4bb6220fL },
  29884. { 0x212cf4b56e0d6aL,0x7c24d086521960L,0x0662cf71bd414dL,
  29885. 0x1085b916c58c25L,0x781eed2be9a350L,0x26880e80db6ab2L,
  29886. 0x169e356442f061L } },
  29887. /* 185 */
  29888. { { 0x57aa2ad748b02cL,0x68a34256772a9aL,0x1591c44962f96cL,
  29889. 0x110a9edd6e53d2L,0x31eab597e091a3L,0x603e64e200c65dL,
  29890. 0x2f66b72e8a1cfcL },
  29891. { 0x5c79d138543f7fL,0x412524363fdfa3L,0x547977e3b40008L,
  29892. 0x735ca25436d9f7L,0x232b4888cae049L,0x27ce37a53d8f23L,
  29893. 0x34d45881a9b470L } },
  29894. /* 186 */
  29895. { { 0x76b95255924f43L,0x035c9f3bd1aa5dL,0x5eb71a010b4bd0L,
  29896. 0x6ce8dda7e39f46L,0x35679627ea70c0L,0x5c987767c7d77eL,
  29897. 0x1fa28952b620b7L },
  29898. { 0x106f50b5924407L,0x1cc3435a889411L,0x0597cdce3bc528L,
  29899. 0x738f8b0d5077d1L,0x5894dd60c7dd6aL,0x0013d0721f5e2eL,
  29900. 0x344573480527d3L } },
  29901. /* 187 */
  29902. { { 0x2e2c1da52abf77L,0x394aa8464ad05eL,0x095259b7330a83L,
  29903. 0x686e81cf6a11f5L,0x405c7e48c93c7cL,0x65c3ca9444a2ecL,
  29904. 0x07bed6c59c3563L },
  29905. { 0x51f9d994fb1471L,0x3c3ecfa5283b4eL,0x494dccda63f6ccL,
  29906. 0x4d07b255363a75L,0x0d2b6d3155d118L,0x3c688299fc9497L,
  29907. 0x235692fa3dea3aL } },
  29908. /* 188 */
  29909. { { 0x16b4d452669e98L,0x72451fa85406b9L,0x674a145d39151fL,
  29910. 0x325ffd067ae098L,0x527e7805cd1ae0L,0x422a1d1789e48dL,
  29911. 0x3e27be63f55e07L },
  29912. { 0x7f95f6dee0b63fL,0x008e444cc74969L,0x01348f3a72b614L,
  29913. 0x000cfac81348c3L,0x508ae3e5309ce5L,0x2584fcdee44d34L,
  29914. 0x3a4dd994899ee9L } },
  29915. /* 189 */
  29916. { { 0x4d289cc0368708L,0x0e5ebc60dc3b40L,0x78cc44bfab1162L,
  29917. 0x77ef2173b7d11eL,0x06091718e39746L,0x30fe19319b83a4L,
  29918. 0x17e8f2988529c6L },
  29919. { 0x68188bdcaa9f2aL,0x0e64b1350c1bddL,0x5b18ebac7cc4b3L,
  29920. 0x75315a9fcc046eL,0x36e9770fd43db4L,0x54c5857fc69121L,
  29921. 0x0417e18f3e909aL } },
  29922. /* 190 */
  29923. { { 0x29795db38059adL,0x6efd20c8fd4016L,0x3b6d1ce8f95a1aL,
  29924. 0x4db68f177f8238L,0x14ec7278d2340fL,0x47bd77ff2b77abL,
  29925. 0x3d2dc8cd34e9fcL },
  29926. { 0x285980a5a83f0bL,0x08352e2d516654L,0x74894460481e1bL,
  29927. 0x17f6f3709c480dL,0x6b590d1b55221eL,0x45c100dc4c9be9L,
  29928. 0x1b13225f9d8b91L } },
  29929. /* 191 */
  29930. { { 0x0b905fb4b41d9dL,0x48cc8a474cb7a2L,0x4eda67e8de09b2L,
  29931. 0x1de47c829adde8L,0x118ad5b9933d77L,0x7a12665ac3f9a4L,
  29932. 0x05631a4fb52997L },
  29933. { 0x5fb2a8e6806e63L,0x27d96bbcca369bL,0x46066f1a6b8c7bL,
  29934. 0x63b58fc7ca3072L,0x170a36229c0d62L,0x57176f1e463203L,
  29935. 0x0c7ce083e73b9cL } },
  29936. /* 192 */
  29937. { { 0x31caf2c09e1c72L,0x6530253219e9d2L,0x7650c98b601c57L,
  29938. 0x182469f99d56c0L,0x415f65d292b7a7L,0x30f62a55549b8eL,
  29939. 0x30f443f643f465L },
  29940. { 0x6b35c575ddadd0L,0x14a23cf6d299eeL,0x2f0198c0967d7dL,
  29941. 0x1013058178d5bfL,0x39da601c9cc879L,0x09d8963ec340baL,
  29942. 0x1b735db13ad2a7L } },
  29943. /* 193 */
  29944. { { 0x20916ffdc83f01L,0x16892aa7c9f217L,0x6bff179888d532L,
  29945. 0x4adf3c3d366288L,0x41a62b954726aeL,0x3139609022aeb6L,
  29946. 0x3e8ab9b37aff7aL },
  29947. { 0x76bbc70f24659aL,0x33fa98513886c6L,0x13b26af62c4ea6L,
  29948. 0x3c4d5826389a0cL,0x526ec28c02bf6aL,0x751ff083d79a7cL,
  29949. 0x110ac647990224L } },
  29950. /* 194 */
  29951. { { 0x2c6c62fa2b6e20L,0x3d37edad30c299L,0x6ef25b44b65fcaL,
  29952. 0x7470846914558eL,0x712456eb913275L,0x075a967a9a280eL,
  29953. 0x186c8188f2a2a0L },
  29954. { 0x2f3b41a6a560b1L,0x3a8070b3f9e858L,0x140936ff0e1e78L,
  29955. 0x5fd298abe6da8aL,0x3823a55d08f153L,0x3445eafaee7552L,
  29956. 0x2a5fc96731a8b2L } },
  29957. /* 195 */
  29958. { { 0x06317be58edbbbL,0x4a38f3bfbe2786L,0x445b60f75896b7L,
  29959. 0x6ec7c92b5adf57L,0x07b6be8038a441L,0x1bcfe002879655L,
  29960. 0x2a2174037d6d0eL },
  29961. { 0x776790cf9e48bdL,0x73e14a2c4ed1d3L,0x7eb5ed5f2fc2f7L,
  29962. 0x3e0aedb821b384L,0x0ee3b7e151c12fL,0x51a6a29e044bb2L,
  29963. 0x0ba13a00cb0d86L } },
  29964. /* 196 */
  29965. { { 0x77607d563ec8d8L,0x023fc726996e44L,0x6bd63f577a9986L,
  29966. 0x114a6351e53973L,0x3efe97989da046L,0x1051166e117ed7L,
  29967. 0x0354933dd4fb5fL },
  29968. { 0x7699ca2f30c073L,0x4c973b83b9e6d3L,0x2017c2abdbc3e8L,
  29969. 0x0cdcdd7a26522bL,0x511070f5b23c7dL,0x70672327e83d57L,
  29970. 0x278f842b4a9f26L } },
  29971. /* 197 */
  29972. { { 0x0824f0d4ae972fL,0x60578dd08dcf52L,0x48a74858290fbbL,
  29973. 0x7302748bf23030L,0x184b229a178acfL,0x3e8460ade089d6L,
  29974. 0x13f2b557fad533L },
  29975. { 0x7f96f3ae728d15L,0x018d8d40066341L,0x01fb94955a289aL,
  29976. 0x2d32ed6afc2657L,0x23f4f5e462c3acL,0x60eba5703bfc5aL,
  29977. 0x1b91cc06f16c7aL } },
  29978. /* 198 */
  29979. { { 0x411d68af8219b9L,0x79cca36320f4eeL,0x5c404e0ed72e20L,
  29980. 0x417cb8692e43f2L,0x305d29c7d98599L,0x3b754d5794a230L,
  29981. 0x1c97fb4be404e9L },
  29982. { 0x7cdbafababd109L,0x1ead0eb0ca5090L,0x1a2b56095303e3L,
  29983. 0x75dea935012c8fL,0x67e31c071b1d1dL,0x7c324fbfd172c3L,
  29984. 0x157e257e6498f7L } },
  29985. /* 199 */
  29986. { { 0x19b00db175645bL,0x4c4f6cb69725f1L,0x36d9ce67bd47ceL,
  29987. 0x2005e105179d64L,0x7b952e717867feL,0x3c28599204032cL,
  29988. 0x0f5659d44fb347L },
  29989. { 0x1ebcdedb979775L,0x4378d45cfd11a8L,0x14c85413ca66e9L,
  29990. 0x3dd17d681c8a4dL,0x58368e7dc23142L,0x14f3eaac6116afL,
  29991. 0x0adb45b255f6a0L } },
  29992. /* 200 */
  29993. { { 0x2f5e76279ad982L,0x125b3917034d09L,0x3839a6399e6ed3L,
  29994. 0x32fe0b3ebcd6a2L,0x24ccce8be90482L,0x467e26befcc187L,
  29995. 0x2828434e2e218eL },
  29996. { 0x17247cd386efd9L,0x27f36a468d85c3L,0x65e181ef203bbfL,
  29997. 0x0433a6761120afL,0x1d607a2a8f8625L,0x49f4e55a13d919L,
  29998. 0x3367c3b7943e9dL } },
  29999. /* 201 */
  30000. { { 0x3391c7d1a46d4dL,0x38233d602d260cL,0x02127a0f78b7d4L,
  30001. 0x56841c162c24c0L,0x4273648fd09aa8L,0x019480bb0e754eL,
  30002. 0x3b927987b87e58L },
  30003. { 0x6676be48c76f73L,0x01ec024e9655aeL,0x720fe1c6376704L,
  30004. 0x17e06b98885db3L,0x656adec85a4200L,0x73780893c3ce88L,
  30005. 0x0a339cdd8df664L } },
  30006. /* 202 */
  30007. { { 0x69af7244544ac7L,0x31ab7402084d2fL,0x67eceb7ef7cb19L,
  30008. 0x16f8583b996f61L,0x1e208d12faf91aL,0x4a91584ce4a42eL,
  30009. 0x3e08337216c93eL },
  30010. { 0x7a6eea94f4cf77L,0x07a52894678c60L,0x302dd06b14631eL,
  30011. 0x7fddb7225c9ceaL,0x55e441d7acd153L,0x2a00d4490b0f44L,
  30012. 0x053ef125338cdbL } },
  30013. /* 203 */
  30014. { { 0x120c0c51584e3cL,0x78b3efca804f37L,0x662108aefb1dccL,
  30015. 0x11deb55f126709L,0x66def11ada8125L,0x05bbc0d1001711L,
  30016. 0x1ee1c99c7fa316L },
  30017. { 0x746f287de53510L,0x1733ef2e32d09cL,0x1df64a2b0924beL,
  30018. 0x19758da8f6405eL,0x28f6eb3913e484L,0x7175a1090cc640L,
  30019. 0x048aee0d63f0bcL } },
  30020. /* 204 */
  30021. { { 0x1f3b1e3b0b29c3L,0x48649f4882a215L,0x485eca3a9e0dedL,
  30022. 0x4228ba85cc82e4L,0x36da1f39bc9379L,0x1659a7078499d1L,
  30023. 0x0a67d5f6c04188L },
  30024. { 0x6ac39658afdce3L,0x0d667a0bde8ef6L,0x0ae6ec0bfe8548L,
  30025. 0x6d9cb2650571bfL,0x54bea107760ab9L,0x705c53bd340cf2L,
  30026. 0x111a86b610c70fL } },
  30027. /* 205 */
  30028. { { 0x7ecea05c6b8195L,0x4f8be93ce3738dL,0x305de9eb9f5d12L,
  30029. 0x2c3b9d3d474b56L,0x673691a05746c3L,0x2e3482c428c6eaL,
  30030. 0x2a8085fde1f472L },
  30031. { 0x69d15877fd3226L,0x4609c9ec017cc3L,0x71e9b7fc1c3dbcL,
  30032. 0x4f8951254e2675L,0x63ee9d15afa010L,0x0f05775b645190L,
  30033. 0x28a0a439397ae3L } },
  30034. /* 206 */
  30035. { { 0x387fa03e9de330L,0x40cc32b828b6abL,0x02a482fbc04ac9L,
  30036. 0x68cad6e70429b7L,0x741877bff6f2c4L,0x48efe633d3b28bL,
  30037. 0x3e612218fe24b3L },
  30038. { 0x6fc1d34fe37657L,0x3d04b9e1c8b5a1L,0x6a2c332ef8f163L,
  30039. 0x7ca97e2b135690L,0x37357d2a31208aL,0x29f02f2332bd68L,
  30040. 0x17c674c3e63a57L } },
  30041. /* 207 */
  30042. { { 0x683d9a0e6865bbL,0x5e77ec68ad4ce5L,0x4d18f236788bd6L,
  30043. 0x7f34b87204f4e3L,0x391ca40e9e578dL,0x3470ed6ddf4e23L,
  30044. 0x225544b3e50989L },
  30045. { 0x48eda8cb4e462bL,0x2a948825cf9109L,0x473adedc7e1300L,
  30046. 0x37b843b82192edL,0x2b9ac1537dde36L,0x4efe7412732332L,
  30047. 0x29cc5981b5262bL } },
  30048. /* 208 */
  30049. { { 0x190d2fcad260f5L,0x7c53dd81d18027L,0x003def5f55db0eL,
  30050. 0x7f5ed25bee2df7L,0x2b87e9be167d2eL,0x2b999c7bbcd224L,
  30051. 0x1d68a2c260ad50L },
  30052. { 0x010bcde84607a6L,0x0250de9b7e1bedL,0x746d36bfaf1b56L,
  30053. 0x3359475ff56abbL,0x7e84b9bc440b20L,0x2eaa7e3b52f162L,
  30054. 0x01165412f36a69L } },
  30055. /* 209 */
  30056. { { 0x639a02329e5836L,0x7aa3ee2e4d3a27L,0x5bc9b258ecb279L,
  30057. 0x4cb3dfae2d62c6L,0x08d9d3b0c6c437L,0x5a2c177d47eab2L,
  30058. 0x36120479fc1f26L },
  30059. { 0x7609a75bd20e4aL,0x3ba414e17551fcL,0x42cd800e1b90c9L,
  30060. 0x04921811b88f9bL,0x4443697f9562fdL,0x3a8081b8186959L,
  30061. 0x3f5b5c97379e73L } },
  30062. /* 210 */
  30063. { { 0x6fd0e3cf13eafbL,0x3976b5415cbf67L,0x4de40889e48402L,
  30064. 0x17e4d36f24062aL,0x16ae7755cf334bL,0x2730ac94b7e0e1L,
  30065. 0x377592742f48e0L },
  30066. { 0x5e10b18a045041L,0x682792afaae5a1L,0x19383ec971b816L,
  30067. 0x208b17dae2ffc0L,0x439f9d933179b6L,0x55485a9090bcaeL,
  30068. 0x1c316f42a2a35cL } },
  30069. /* 211 */
  30070. { { 0x67173897bdf646L,0x0b6956653ef94eL,0x5be3c97f7ea852L,
  30071. 0x3110c12671f08eL,0x2474076a3fc7ecL,0x53408be503fe72L,
  30072. 0x09155f53a5b44eL },
  30073. { 0x5c804bdd4c27cdL,0x61e81eb8ffd50eL,0x2f7157fdf84717L,
  30074. 0x081f880d646440L,0x7aa892acddec51L,0x6ae70683443f33L,
  30075. 0x31ed9e8b33a75aL } },
  30076. /* 212 */
  30077. { { 0x0d724f8e357586L,0x1febbec91b4134L,0x6ff7b98a9475fdL,
  30078. 0x1c4d9b94e1f364L,0x2b8790499cef00L,0x42fd2080a1b31dL,
  30079. 0x3a3bbc6d9b0145L },
  30080. { 0x75bfebc37e3ca9L,0x28db49c1723bd7L,0x50b12fa8a1f17aL,
  30081. 0x733d95bbc84b98L,0x45ede81f6c109eL,0x18f5e46fb37b5fL,
  30082. 0x34b980804aaec1L } },
  30083. /* 213 */
  30084. { { 0x56060c8a4f57bfL,0x0d2dfe223054c2L,0x718a5bbc03e5d6L,
  30085. 0x7b3344cc19b3b9L,0x4d11c9c054bcefL,0x1f5ad422c22e33L,
  30086. 0x2609299076f86bL },
  30087. { 0x7b7a5fba89fd01L,0x7013113ef3b016L,0x23d5e0a173e34eL,
  30088. 0x736c14462f0f50L,0x1ef5f7ac74536aL,0x4baba6f4400ea4L,
  30089. 0x17b310612c9828L } },
  30090. /* 214 */
  30091. { { 0x4ebb19a708c8d3L,0x209f8c7f03d9bbL,0x00461cfe5798fbL,
  30092. 0x4f93b6ae822fadL,0x2e5b33b5ad5447L,0x40b024e547a84bL,
  30093. 0x22ffad40443385L },
  30094. { 0x33809c888228bfL,0x559f655fefbe84L,0x0032f529fd2f60L,
  30095. 0x5a2191ece3478cL,0x5b957fcd771246L,0x6fec181f9ed123L,
  30096. 0x33eed3624136a3L } },
  30097. /* 215 */
  30098. { { 0x6a5df93b26139aL,0x55076598fd7134L,0x356a592f34f81dL,
  30099. 0x493c6b5a3d4741L,0x435498a4e2a39bL,0x2cd26a0d931c88L,
  30100. 0x01925ea3fc7835L },
  30101. { 0x6e8d992b1efa05L,0x79508a727c667bL,0x5f3c15e6b4b698L,
  30102. 0x11b6c755257b93L,0x617f5af4b46393L,0x248d995b2b6656L,
  30103. 0x339db62e2e22ecL } },
  30104. /* 216 */
  30105. { { 0x52537a083843dcL,0x6a283c82a768c7L,0x13aa6bf25227acL,
  30106. 0x768d76ba8baf5eL,0x682977a6525808L,0x67ace52ac23b0bL,
  30107. 0x2374b5a2ed612dL },
  30108. { 0x7139e60133c3a4L,0x715697a4f1d446L,0x4b018bf36677a0L,
  30109. 0x1dd43837414d83L,0x505ec70730d4f6L,0x09ac100907fa79L,
  30110. 0x21caad6e03217eL } },
  30111. /* 217 */
  30112. { { 0x0776d3999d4d49L,0x33bdd87e8bcff8L,0x1036b87f068fadL,
  30113. 0x0a9b8ffde4c872L,0x7ab2533596b1eaL,0x305a88fb965378L,
  30114. 0x3356d8fa4d65e5L },
  30115. { 0x3366fa77d1ff11L,0x1e0bdbdcd2075cL,0x46910cefc967caL,
  30116. 0x7ce700737a1ff6L,0x1c5dc15409c9bdL,0x368436b9bdb595L,
  30117. 0x3e7ccd6560b5efL } },
  30118. /* 218 */
  30119. { { 0x1443789422c792L,0x524792b1717f2bL,0x1f7c1d95048e7aL,
  30120. 0x5cfe2a225b0d12L,0x245594d29ce85bL,0x20134d254ce168L,
  30121. 0x1b83296803921aL },
  30122. { 0x79a78285b3beceL,0x3c738c3f3124d6L,0x6ab9d1fe0907cdL,
  30123. 0x0652ceb7fc104cL,0x06b5f58c8ae3fdL,0x486959261c5328L,
  30124. 0x0b3813ae677c90L } },
  30125. /* 219 */
  30126. { { 0x66b9941ac37b82L,0x651a4b609b0686L,0x046711edf3fc31L,
  30127. 0x77f89f38faa89bL,0x2683ddbf2d5edbL,0x389ef1dfaa3c25L,
  30128. 0x20b3616e66273eL },
  30129. { 0x3c6db6e0cb5d37L,0x5d7ae5dc342bc4L,0x74a1dc6c52062bL,
  30130. 0x6f7c0bec109557L,0x5c51f7bc221d91L,0x0d7b5880745288L,
  30131. 0x1c46c145c4b0ddL } },
  30132. /* 220 */
  30133. { { 0x59ed485ea99eccL,0x201b71956bc21dL,0x72d5c32f73de65L,
  30134. 0x1aefd76547643eL,0x580a452cfb2c2dL,0x7cb1a63f5c4dc9L,
  30135. 0x39a8df727737aaL },
  30136. { 0x365a341deca452L,0x714a1ad1689cbaL,0x16981d12c42697L,
  30137. 0x5a124f4ac91c75L,0x1b2e3f2fedc0dbL,0x4a1c72b8e9d521L,
  30138. 0x3855b4694e4e20L } },
  30139. /* 221 */
  30140. { { 0x16b3d047181ae9L,0x17508832f011afL,0x50d33cfeb2ebd1L,
  30141. 0x1deae237349984L,0x147c641aa6adecL,0x24a9fb4ebb1ddbL,
  30142. 0x2b367504a7a969L },
  30143. { 0x4c55a3d430301bL,0x379ef6a5d492cbL,0x3c56541fc0f269L,
  30144. 0x73a546e91698ceL,0x2c2b62ee0b9b5dL,0x6284184d43d0efL,
  30145. 0x0e1f5cf6a4b9f0L } },
  30146. /* 222 */
  30147. { { 0x44833e8cd3fdacL,0x28e6665cb71c27L,0x2f8bf87f4ddbf3L,
  30148. 0x6cc6c767fb38daL,0x3bc114d734e8b5L,0x12963d5a78ca29L,
  30149. 0x34532a161ece41L },
  30150. { 0x2443af5d2d37e9L,0x54e6008c8c452bL,0x2c55d54111cf1bL,
  30151. 0x55ac7f7522575aL,0x00a6fba3f8575fL,0x3f92ef3b793b8dL,
  30152. 0x387b97d69ecdf7L } },
  30153. /* 223 */
  30154. { { 0x0b464812d29f46L,0x36161daa626f9aL,0x5202fbdb264ca5L,
  30155. 0x21245805ff1304L,0x7f9c4a65657885L,0x542d3887f9501cL,
  30156. 0x086420deef8507L },
  30157. { 0x5e159aa1b26cfbL,0x3f0ef5ffd0a50eL,0x364b29663a432aL,
  30158. 0x49c56888af32a8L,0x6f937e3e0945d1L,0x3cbdeec6d766cdL,
  30159. 0x2d80d342ece61aL } },
  30160. /* 224 */
  30161. { { 0x255e3026d8356eL,0x4ddba628c4de9aL,0x074323b593e0d9L,
  30162. 0x333bdb0a10eefbL,0x318b396e473c52L,0x6ebb5a95efd3d3L,
  30163. 0x3f3bff52aa4e4fL },
  30164. { 0x3138a111c731d5L,0x674365e283b308L,0x5585edd9c416f2L,
  30165. 0x466763d9070fd4L,0x1b568befce8128L,0x16eb040e7b921eL,
  30166. 0x3d5c898687c157L } },
  30167. /* 225 */
  30168. { { 0x14827736973088L,0x4e110d53f301e6L,0x1f811b09870023L,
  30169. 0x53b5e500dbcacaL,0x4ddf0df1e6a7dcL,0x1e9575fb10ce35L,
  30170. 0x3fdc153644d936L },
  30171. { 0x763547e2260594L,0x26e5ae764efc59L,0x13be6f4d791a29L,
  30172. 0x2021e61e3a0cf1L,0x339cd2b4a1c202L,0x5c7451e08f5121L,
  30173. 0x3728b3a851be68L } },
  30174. /* 226 */
  30175. { { 0x78873653277538L,0x444b9ed2ee7156L,0x79ac8b8b069cd3L,
  30176. 0x5f0e90933770e8L,0x307662c615389eL,0x40fe6d95a80057L,
  30177. 0x04822170cf993cL },
  30178. { 0x677d5690fbfec2L,0x0355af4ae95cb3L,0x417411794fe79eL,
  30179. 0x48daf87400a085L,0x33521d3b5f0aaaL,0x53567a3be00ff7L,
  30180. 0x04712ccfb1cafbL } },
  30181. /* 227 */
  30182. { { 0x2b983283c3a7f3L,0x579f11b146a9a6L,0x1143d3b16a020eL,
  30183. 0x20f1483ef58b20L,0x3f03e18d747f06L,0x3129d12f15de37L,
  30184. 0x24c911f7222833L },
  30185. { 0x1e0febcf3d5897L,0x505e26c01cdaacL,0x4f45a9adcff0e9L,
  30186. 0x14dfac063c5cebL,0x69e5ce713fededL,0x3481444a44611aL,
  30187. 0x0ea49295c7fdffL } },
  30188. /* 228 */
  30189. { { 0x64554cb4093beeL,0x344b4b18dd81f6L,0x350f43b4de9b59L,
  30190. 0x28a96a220934caL,0x4aa8da5689a515L,0x27171cbd518509L,
  30191. 0x0cfc1753f47c95L },
  30192. { 0x7dfe091b615d6eL,0x7d1ee0aa0fb5c1L,0x145eef3200b7b5L,
  30193. 0x33fe88feeab18fL,0x1d62d4f87453e2L,0x43b8db4e47fff1L,
  30194. 0x1572f2b8b8f368L } },
  30195. /* 229 */
  30196. { { 0x6bc94e6b4e84f3L,0x60629dee586a66L,0x3bbad5fe65ca18L,
  30197. 0x217670db6c2fefL,0x0320a7f4e3272aL,0x3ccff0d976a6deL,
  30198. 0x3c26da8ae48cccL },
  30199. { 0x53ecf156778435L,0x7533064765a443L,0x6c5c12f03ca5deL,
  30200. 0x44f8245350dabfL,0x342cdd777cf8b3L,0x2b539c42e9f58dL,
  30201. 0x10138affc279b1L } },
  30202. /* 230 */
  30203. { { 0x1b135e204c5ddbL,0x40887dfeaa1d37L,0x7fb0ef83da76ffL,
  30204. 0x521f2b79af55a5L,0x3f9b38b4c3f0d0L,0x20a9838cce61ceL,
  30205. 0x24bb4e2f4b1e32L },
  30206. { 0x003f6aa386e27cL,0x68df59db0a0f8eL,0x21677d5192e713L,
  30207. 0x14ab9757501276L,0x411944af961524L,0x3184f39abc5c3fL,
  30208. 0x2a8dda80ca078dL } },
  30209. /* 231 */
  30210. { { 0x0592233cdbc95cL,0x54d5de5c66f40fL,0x351caa1512ab86L,
  30211. 0x681bdbee020084L,0x6ee2480c853e68L,0x6a5a44262b918fL,
  30212. 0x06574e15a3b91dL },
  30213. { 0x31ba03dacd7fbeL,0x0c3da7c18a57a9L,0x49aaaded492d6bL,
  30214. 0x3071ff53469e02L,0x5efb4f0d7248c6L,0x6db5fb67f12628L,
  30215. 0x29cff668e3d024L } },
  30216. /* 232 */
  30217. { { 0x1b9ef3bb1b17ceL,0x6ccf8c24fe6312L,0x34c15487f45008L,
  30218. 0x1a84044095972cL,0x515073a47e449eL,0x2ddc93f9097feeL,
  30219. 0x1008fdc894c434L },
  30220. { 0x08e5edb73399faL,0x65b1aa65547d4cL,0x3a117a1057c498L,
  30221. 0x7e16c3089d13acL,0x502f2ae4b6f851L,0x57a70f3eb62673L,
  30222. 0x111b48a9a03667L } },
  30223. /* 233 */
  30224. { { 0x5023024be164f1L,0x25ad117032401eL,0x46612b3bfe3427L,
  30225. 0x2f4f406a8a02b7L,0x16a93a5c4ddf07L,0x7ee71968fcdbe9L,
  30226. 0x2267875ace37daL },
  30227. { 0x687e88b59eb2a6L,0x3ac7368fe716d3L,0x28d953a554a036L,
  30228. 0x34d52c0acca08fL,0x742a7cf8dd4fd9L,0x10bfeb8575ea60L,
  30229. 0x290e454d868dccL } },
  30230. /* 234 */
  30231. { { 0x4e72a3a8a4bdd2L,0x1ba36d1dee04d5L,0x7a43136b63195bL,
  30232. 0x6ca8e286a519f3L,0x568e64aece08a9L,0x571d5000b5c10bL,
  30233. 0x3f75e9f5dbdd40L },
  30234. { 0x6fb0a698d6fa45L,0x0ce42209d7199cL,0x1f68275f708a3eL,
  30235. 0x5749832e91ec3cL,0x6c3665521428b2L,0x14b2bf5747bd4aL,
  30236. 0x3b6f940e42a22bL } },
  30237. /* 235 */
  30238. { { 0x4da0adbfb26c82L,0x16792a585f39acL,0x17df9dfda3975cL,
  30239. 0x4796b4afaf479bL,0x67be67234e0020L,0x69df5f201dda25L,
  30240. 0x09f71a4d12b3dcL },
  30241. { 0x64ff5ec260a46aL,0x579c5b86385101L,0x4f29a7d549f697L,
  30242. 0x4e64261242e2ebL,0x54ecacdfb6b296L,0x46e0638b5fddadL,
  30243. 0x31eefd3208891dL } },
  30244. /* 236 */
  30245. { { 0x5b72c749fe01b2L,0x230cf27523713aL,0x533d1810e0d1e1L,
  30246. 0x5590db7d1dd1e2L,0x7b8ab73e8e43d3L,0x4c8a19bd1c17caL,
  30247. 0x19222ce9f74810L },
  30248. { 0x6398b3dddc4582L,0x0352b7d88dfd53L,0x3c55b4e10c5a63L,
  30249. 0x38194d13f8a237L,0x106683fd25dd87L,0x59e0b62443458eL,
  30250. 0x196cb70aa9cbb9L } },
  30251. /* 237 */
  30252. { { 0x2885f7cd021d63L,0x162bfd4c3e1043L,0x77173dcf98fcd1L,
  30253. 0x13d4591d6add36L,0x59311154d0d8f2L,0x74336e86e79b8aL,
  30254. 0x13faadc5661883L },
  30255. { 0x18938e7d9ec924L,0x14bcda8fcaa0a1L,0x706d85d41a1355L,
  30256. 0x0ac34520d168deL,0x5a92499fe17826L,0x36c2e3b4f00600L,
  30257. 0x29c2fd7b5f63deL } },
  30258. /* 238 */
  30259. { { 0x41250dfe2216c5L,0x44a0ec0366a217L,0x575bc1adf8b0dfL,
  30260. 0x5ff5cdbdb1800bL,0x7843d4dde8ca18L,0x5fa9e420865705L,
  30261. 0x235c38be6c6b02L },
  30262. { 0x473b78aae91abbL,0x39470c6051e44bL,0x3f973cc2dc08c3L,
  30263. 0x2837932c5c91f6L,0x25e39ed754ec25L,0x1371c837118e53L,
  30264. 0x3b99f3b0aeafe2L } },
  30265. /* 239 */
  30266. { { 0x03acf51be46c65L,0x271fceacbaf5c3L,0x476589ed3a5e25L,
  30267. 0x78ec8c3c3c399cL,0x1f5c8bf4ac4c19L,0x730bb733ec68d2L,
  30268. 0x29a37e00dd287eL },
  30269. { 0x448ed1bf92b5faL,0x10827c17b86478L,0x55e6fc05b28263L,
  30270. 0x0af1226c73a66aL,0x0b66e5df0d09c1L,0x26128315a02682L,
  30271. 0x22d84932c5e808L } },
  30272. /* 240 */
  30273. { { 0x5ec3afc26e3392L,0x08e142e45c0084L,0x4388d5ad0f01feL,
  30274. 0x0f7acd36e6140cL,0x028c14ed97dffbL,0x311845675a38c6L,
  30275. 0x01c1c8f09a3062L },
  30276. { 0x5a302f4cf49e7dL,0x79267e254a44e1L,0x746165052317a1L,
  30277. 0x53a09263a566e8L,0x7d478ad5f73abcL,0x187ce5c947dad3L,
  30278. 0x18564e1a1ec45fL } },
  30279. /* 241 */
  30280. { { 0x7b9577a9aa0486L,0x766b40c7aaaef6L,0x1f6a411f5db907L,
  30281. 0x4543dd4d80beaeL,0x0ad938c7482806L,0x451568bf4b9be1L,
  30282. 0x3367ec85d30a22L },
  30283. { 0x5446425747843dL,0x18d94ac223c6b2L,0x052ff3a354d359L,
  30284. 0x0b4933f89723f5L,0x03fb517740e056L,0x226b892871dddaL,
  30285. 0x2768c2b753f0fdL } },
  30286. /* 242 */
  30287. { { 0x685282ccfa5200L,0x411ed433627b89L,0x77d5c9b8bc9c1dL,
  30288. 0x4a13ef2ee5cd29L,0x5582a612407c9eL,0x2307cb42fc3aa9L,
  30289. 0x2e661df79956b8L },
  30290. { 0x0e972b015254deL,0x5b63e14def8adeL,0x06995be2ca4a95L,
  30291. 0x6cc0cc1e94bf27L,0x7ed8499fe0052aL,0x671a6ca5a5e0f9L,
  30292. 0x31e10d4ba10f05L } },
  30293. /* 243 */
  30294. { { 0x690af07e9b2d8aL,0x6030af9e32c8ddL,0x45c7ca3bf2b235L,
  30295. 0x40959077b76c81L,0x61eee7f70d5a96L,0x6b04f6aafe9e38L,
  30296. 0x3c726f55f1898dL },
  30297. { 0x77d0142a1a6194L,0x1c1631215708b9L,0x403a4f0a9b7585L,
  30298. 0x066c8e29f7cef0L,0x6fc32f98cf575eL,0x518a09d818c297L,
  30299. 0x34144e99989e75L } },
  30300. /* 244 */
  30301. { { 0x6adbada859fb6aL,0x0dcfb6506ccd51L,0x68f88b8d573e0dL,
  30302. 0x4b1ce35bd9af30L,0x241c8293ece2c9L,0x3b5f402c5c4adeL,
  30303. 0x34b9b1ee6fde87L },
  30304. { 0x5e625340075e63L,0x54c3f3d9050da1L,0x2a3f9152509016L,
  30305. 0x3274e46111bc18L,0x3a7504fd01ac73L,0x4169b387a43209L,
  30306. 0x35626f852bc6d4L } },
  30307. /* 245 */
  30308. { { 0x576a4f4662e53bL,0x5ea3f20eecec26L,0x4e5f02be5cd7b0L,
  30309. 0x72cc5ac3314be8L,0x0f604ed3201fe9L,0x2a29378ea54bceL,
  30310. 0x2d52bd4d6ec4b6L },
  30311. { 0x6a4c2b212c1c76L,0x778fd64a1bfa6dL,0x326828691863d6L,
  30312. 0x5616c8bd06a336L,0x5fab552564da4dL,0x46640cab3e91d2L,
  30313. 0x1d21f06427299eL } },
  30314. /* 246 */
  30315. { { 0x2bfe37dde98e9cL,0x164c54822332ebL,0x5b736c7df266e4L,
  30316. 0x59dab3a8da084cL,0x0ae1eab346f118L,0x182090a4327e3fL,
  30317. 0x07b13489dae2e6L },
  30318. { 0x3bc92645452baaL,0x30b159894ae574L,0x5b947c5c78e1f4L,
  30319. 0x18f0e004a3c77fL,0x48ca8f357077d9L,0x349ffdcef9bca9L,
  30320. 0x3ed224bfd54772L } },
  30321. /* 247 */
  30322. { { 0x1bdad02db8dff8L,0x69fab4450b44b6L,0x3b6802d187518bL,
  30323. 0x098368d8eb556cL,0x3fe1943fbefcf4L,0x008851d0de6d42L,
  30324. 0x322cbc4605fe25L },
  30325. { 0x2528aaf0d51afbL,0x7d48a9363a0cecL,0x4ba8f77d9a8f8bL,
  30326. 0x7dee903437d6c7L,0x1ff5a0d9ccc4b4L,0x34d9bd2fa99831L,
  30327. 0x30d9e4f58667c6L } },
  30328. /* 248 */
  30329. { { 0x38909b51b85197L,0x7ba16992512bd4L,0x2c776cfcfffec5L,
  30330. 0x2be7879075843cL,0x557e2b05d28ffcL,0x641b17bc5ce357L,
  30331. 0x1fcaf8a3710306L },
  30332. { 0x54dca2299a2d48L,0x745d06ef305acaL,0x7c41c65c6944c2L,
  30333. 0x679412ec431902L,0x48f2b15ee62827L,0x341a96d8afe06eL,
  30334. 0x2a78fd3690c0e1L } },
  30335. /* 249 */
  30336. { { 0x6b7cec83fbc9c6L,0x238e8a82eefc67L,0x5d3c1d9ff0928cL,
  30337. 0x55b816d6409bbfL,0x7969612adae364L,0x55b6ff96db654eL,
  30338. 0x129beca10073a9L },
  30339. { 0x0b1d2acdfc73deL,0x5d1a3605fa64bdL,0x436076146743beL,
  30340. 0x64044b89fcce0cL,0x7ae7b3c18f7fafL,0x7f083ee27cea36L,
  30341. 0x0292cd0d7c1ff0L } },
  30342. /* 250 */
  30343. { { 0x5a3c4c019b7d2eL,0x1a35a9b89712fbL,0x38736cc4f18c72L,
  30344. 0x603dd832a44e6bL,0x000d1d44aed104L,0x69b1f2fc274ebeL,
  30345. 0x03a7b993f76977L },
  30346. { 0x299f3b3e346910L,0x5243f45295afd5L,0x34342cbfa588bdL,
  30347. 0x72c40dd1155510L,0x718024fed2f991L,0x2f935e765ad82aL,
  30348. 0x246799ea371fb8L } },
  30349. /* 251 */
  30350. { { 0x24fe4c76250533L,0x01cafb02fdf18eL,0x505cb25d462882L,
  30351. 0x3e038175157d87L,0x7e3e99b10cdeb1L,0x38b7e72ebc7936L,
  30352. 0x081845f7c73433L },
  30353. { 0x049e61be05ebd5L,0x6ab82d8f0581f6L,0x62adffb427ac2eL,
  30354. 0x19431f809d198dL,0x36195f6c58b1d6L,0x22cc4c9dedc9a7L,
  30355. 0x24b146d8e694fcL } },
  30356. /* 252 */
  30357. { { 0x7c7bc8288b364dL,0x5c10f683cb894aL,0x19a62a68452958L,
  30358. 0x1fc24dcb4ce90eL,0x726baa4ed9581fL,0x1f34447dde73d6L,
  30359. 0x04c56708f30a21L },
  30360. { 0x131e583a3f4963L,0x071215b4d502e7L,0x196aca542e5940L,
  30361. 0x3afd5a91f7450eL,0x671b6eedf49497L,0x6aac7aca5c29e4L,
  30362. 0x3fb512470f138bL } },
  30363. /* 253 */
  30364. { { 0x5eadc3f4eb453eL,0x16c795ba34b666L,0x5d7612a4697fddL,
  30365. 0x24dd19bb499e86L,0x415b89ca3eeb9bL,0x7c83edf599d809L,
  30366. 0x13bc64c9b70269L },
  30367. { 0x52d3243dca3233L,0x0b21444b3a96a7L,0x6d551bc0083b90L,
  30368. 0x4f535b88c61176L,0x11e61924298010L,0x0a155b415bb61dL,
  30369. 0x17f94fbd26658fL } },
  30370. /* 254 */
  30371. { { 0x2dd06b90c28c65L,0x48582339c8fa6eL,0x01ac8bf2085d94L,
  30372. 0x053e660e020fdcL,0x1bece667edf07bL,0x4558f2b33ce24cL,
  30373. 0x2f1a766e8673fcL },
  30374. { 0x1d77cd13c06819L,0x4d5dc5056f3a01L,0x18896c6fa18d69L,
  30375. 0x120047ca76d625L,0x6af8457d4f4e45L,0x70ddc53358b60aL,
  30376. 0x330e11130e82f0L } },
  30377. /* 255 */
  30378. { { 0x0643b1cd4c2356L,0x10a2ea0a8f7c92L,0x2752513011d029L,
  30379. 0x4cd4c50321f579L,0x5fdf9ba5724792L,0x2f691653e2ddc0L,
  30380. 0x0cfed3d84226cbL },
  30381. { 0x704902a950f955L,0x069bfdb87bbf0cL,0x5817eeda8a5f84L,
  30382. 0x1914cdd9089905L,0x0e4a323d7b93f4L,0x1cc3fc340af0b2L,
  30383. 0x23874161bd6303L } },
  30384. };
  30385. /* Multiply the base point of P384 by the scalar and return the result.
  30386. * If map is true then convert result to affine coordinates.
  30387. *
  30388. * Stripe implementation.
  30389. * Pre-generated: 2^0, 2^48, ...
  30390. * Pre-generated: products of all combinations of above.
  30391. * 8 doubles and adds (with qz=1)
  30392. *
  30393. * r Resulting point.
  30394. * k Scalar to multiply by.
  30395. * map Indicates whether to convert result to affine.
  30396. * ct Constant time required.
  30397. * heap Heap to use for allocation.
  30398. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  30399. */
  30400. static int sp_384_ecc_mulmod_base_7(sp_point_384* r, const sp_digit* k,
  30401. int map, int ct, void* heap)
  30402. {
  30403. return sp_384_ecc_mulmod_stripe_7(r, &p384_base, p384_table,
  30404. k, map, ct, heap);
  30405. }
  30406. #endif
  30407. /* Multiply the base point of P384 by the scalar and return the result.
  30408. * If map is true then convert result to affine coordinates.
  30409. *
  30410. * km Scalar to multiply by.
  30411. * r Resulting point.
  30412. * map Indicates whether to convert result to affine.
  30413. * heap Heap to use for allocation.
  30414. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  30415. */
  30416. int sp_ecc_mulmod_base_384(const mp_int* km, ecc_point* r, int map, void* heap)
  30417. {
  30418. #ifdef WOLFSSL_SP_SMALL_STACK
  30419. sp_point_384* point = NULL;
  30420. sp_digit* k = NULL;
  30421. #else
  30422. sp_point_384 point[1];
  30423. sp_digit k[7];
  30424. #endif
  30425. int err = MP_OKAY;
  30426. #ifdef WOLFSSL_SP_SMALL_STACK
  30427. point = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap,
  30428. DYNAMIC_TYPE_ECC);
  30429. if (point == NULL)
  30430. err = MEMORY_E;
  30431. if (err == MP_OKAY) {
  30432. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap,
  30433. DYNAMIC_TYPE_ECC);
  30434. if (k == NULL)
  30435. err = MEMORY_E;
  30436. }
  30437. #endif
  30438. if (err == MP_OKAY) {
  30439. sp_384_from_mp(k, 7, km);
  30440. err = sp_384_ecc_mulmod_base_7(point, k, map, 1, heap);
  30441. }
  30442. if (err == MP_OKAY) {
  30443. err = sp_384_point_to_ecc_point_7(point, r);
  30444. }
  30445. #ifdef WOLFSSL_SP_SMALL_STACK
  30446. if (k != NULL)
  30447. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  30448. if (point != NULL)
  30449. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  30450. #endif
  30451. return err;
  30452. }
  30453. /* Multiply the base point of P384 by the scalar, add point a and return
  30454. * the result. If map is true then convert result to affine coordinates.
  30455. *
  30456. * km Scalar to multiply by.
  30457. * am Point to add to scalar multiply result.
  30458. * inMont Point to add is in montgomery form.
  30459. * r Resulting point.
  30460. * map Indicates whether to convert result to affine.
  30461. * heap Heap to use for allocation.
  30462. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  30463. */
  30464. int sp_ecc_mulmod_base_add_384(const mp_int* km, const ecc_point* am,
  30465. int inMont, ecc_point* r, int map, void* heap)
  30466. {
  30467. #ifdef WOLFSSL_SP_SMALL_STACK
  30468. sp_point_384* point = NULL;
  30469. sp_digit* k = NULL;
  30470. #else
  30471. sp_point_384 point[2];
  30472. sp_digit k[7 + 7 * 2 * 6];
  30473. #endif
  30474. sp_point_384* addP = NULL;
  30475. sp_digit* tmp = NULL;
  30476. int err = MP_OKAY;
  30477. #ifdef WOLFSSL_SP_SMALL_STACK
  30478. point = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 2, heap,
  30479. DYNAMIC_TYPE_ECC);
  30480. if (point == NULL)
  30481. err = MEMORY_E;
  30482. if (err == MP_OKAY) {
  30483. k = (sp_digit*)XMALLOC(
  30484. sizeof(sp_digit) * (7 + 7 * 2 * 6),
  30485. heap, DYNAMIC_TYPE_ECC);
  30486. if (k == NULL)
  30487. err = MEMORY_E;
  30488. }
  30489. #endif
  30490. if (err == MP_OKAY) {
  30491. addP = point + 1;
  30492. tmp = k + 7;
  30493. sp_384_from_mp(k, 7, km);
  30494. sp_384_point_from_ecc_point_7(addP, am);
  30495. }
  30496. if ((err == MP_OKAY) && (!inMont)) {
  30497. err = sp_384_mod_mul_norm_7(addP->x, addP->x, p384_mod);
  30498. }
  30499. if ((err == MP_OKAY) && (!inMont)) {
  30500. err = sp_384_mod_mul_norm_7(addP->y, addP->y, p384_mod);
  30501. }
  30502. if ((err == MP_OKAY) && (!inMont)) {
  30503. err = sp_384_mod_mul_norm_7(addP->z, addP->z, p384_mod);
  30504. }
  30505. if (err == MP_OKAY) {
  30506. err = sp_384_ecc_mulmod_base_7(point, k, 0, 0, heap);
  30507. }
  30508. if (err == MP_OKAY) {
  30509. sp_384_proj_point_add_7(point, point, addP, tmp);
  30510. if (map) {
  30511. sp_384_map_7(point, point, tmp);
  30512. }
  30513. err = sp_384_point_to_ecc_point_7(point, r);
  30514. }
  30515. #ifdef WOLFSSL_SP_SMALL_STACK
  30516. if (k != NULL)
  30517. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  30518. if (point)
  30519. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  30520. #endif
  30521. return err;
  30522. }
  30523. #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
  30524. defined(HAVE_ECC_VERIFY)
  30525. #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */
  30526. /* Add 1 to a. (a = a + 1)
  30527. *
  30528. * r A single precision integer.
  30529. * a A single precision integer.
  30530. */
  30531. SP_NOINLINE static void sp_384_add_one_7(sp_digit* a)
  30532. {
  30533. a[0]++;
  30534. sp_384_norm_7(a);
  30535. }
  30536. /* Read big endian unsigned byte array into r.
  30537. *
  30538. * r A single precision integer.
  30539. * size Maximum number of bytes to convert
  30540. * a Byte array.
  30541. * n Number of bytes in array to read.
  30542. */
  30543. static void sp_384_from_bin(sp_digit* r, int size, const byte* a, int n)
  30544. {
  30545. int i;
  30546. int j = 0;
  30547. word32 s = 0;
  30548. r[0] = 0;
  30549. for (i = n-1; i >= 0; i--) {
  30550. r[j] |= (((sp_digit)a[i]) << s);
  30551. if (s >= 47U) {
  30552. r[j] &= 0x7fffffffffffffL;
  30553. s = 55U - s;
  30554. if (j + 1 >= size) {
  30555. break;
  30556. }
  30557. r[++j] = (sp_digit)a[i] >> s;
  30558. s = 8U - s;
  30559. }
  30560. else {
  30561. s += 8U;
  30562. }
  30563. }
  30564. for (j++; j < size; j++) {
  30565. r[j] = 0;
  30566. }
  30567. }
  30568. /* Generates a scalar that is in the range 1..order-1.
  30569. *
  30570. * rng Random number generator.
  30571. * k Scalar value.
  30572. * returns RNG failures, MEMORY_E when memory allocation fails and
  30573. * MP_OKAY on success.
  30574. */
  30575. static int sp_384_ecc_gen_k_7(WC_RNG* rng, sp_digit* k)
  30576. {
  30577. int err;
  30578. byte buf[48];
  30579. do {
  30580. err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));
  30581. if (err == 0) {
  30582. sp_384_from_bin(k, 7, buf, (int)sizeof(buf));
  30583. if (sp_384_cmp_7(k, p384_order2) <= 0) {
  30584. sp_384_add_one_7(k);
  30585. break;
  30586. }
  30587. }
  30588. }
  30589. while (err == 0);
  30590. return err;
  30591. }
  30592. /* Makes a random EC key pair.
  30593. *
  30594. * rng Random number generator.
  30595. * priv Generated private value.
  30596. * pub Generated public point.
  30597. * heap Heap to use for allocation.
  30598. * returns ECC_INF_E when the point does not have the correct order, RNG
  30599. * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.
  30600. */
  30601. int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)
  30602. {
  30603. #ifdef WOLFSSL_SP_SMALL_STACK
  30604. sp_point_384* point = NULL;
  30605. sp_digit* k = NULL;
  30606. #else
  30607. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  30608. sp_point_384 point[2];
  30609. #else
  30610. sp_point_384 point[1];
  30611. #endif
  30612. sp_digit k[7];
  30613. #endif
  30614. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  30615. sp_point_384* infinity = NULL;
  30616. #endif
  30617. int err = MP_OKAY;
  30618. (void)heap;
  30619. #ifdef WOLFSSL_SP_SMALL_STACK
  30620. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  30621. point = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 2, heap, DYNAMIC_TYPE_ECC);
  30622. #else
  30623. point = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC);
  30624. #endif
  30625. if (point == NULL)
  30626. err = MEMORY_E;
  30627. if (err == MP_OKAY) {
  30628. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap,
  30629. DYNAMIC_TYPE_ECC);
  30630. if (k == NULL)
  30631. err = MEMORY_E;
  30632. }
  30633. #endif
  30634. if (err == MP_OKAY) {
  30635. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  30636. infinity = point + 1;
  30637. #endif
  30638. err = sp_384_ecc_gen_k_7(rng, k);
  30639. }
  30640. if (err == MP_OKAY) {
  30641. err = sp_384_ecc_mulmod_base_7(point, k, 1, 1, NULL);
  30642. }
  30643. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  30644. if (err == MP_OKAY) {
  30645. err = sp_384_ecc_mulmod_7(infinity, point, p384_order, 1, 1, NULL);
  30646. }
  30647. if (err == MP_OKAY) {
  30648. if (sp_384_iszero_7(point->x) || sp_384_iszero_7(point->y)) {
  30649. err = ECC_INF_E;
  30650. }
  30651. }
  30652. #endif
  30653. if (err == MP_OKAY) {
  30654. err = sp_384_to_mp(k, priv);
  30655. }
  30656. if (err == MP_OKAY) {
  30657. err = sp_384_point_to_ecc_point_7(point, pub);
  30658. }
  30659. #ifdef WOLFSSL_SP_SMALL_STACK
  30660. if (k != NULL)
  30661. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  30662. if (point != NULL) {
  30663. /* point is not sensitive, so no need to zeroize */
  30664. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  30665. }
  30666. #endif
  30667. return err;
  30668. }
  30669. #ifdef WOLFSSL_SP_NONBLOCK
  30670. typedef struct sp_ecc_key_gen_384_ctx {
  30671. int state;
  30672. sp_384_ecc_mulmod_7_ctx mulmod_ctx;
  30673. sp_digit k[7];
  30674. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  30675. sp_point_384 point[2];
  30676. #else
  30677. sp_point_384 point[1];
  30678. #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN */
  30679. } sp_ecc_key_gen_384_ctx;
  30680. int sp_ecc_make_key_384_nb(sp_ecc_ctx_t* sp_ctx, WC_RNG* rng, mp_int* priv,
  30681. ecc_point* pub, void* heap)
  30682. {
  30683. int err = FP_WOULDBLOCK;
  30684. sp_ecc_key_gen_384_ctx* ctx = (sp_ecc_key_gen_384_ctx*)sp_ctx->data;
  30685. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  30686. sp_point_384* infinity = ctx->point + 1;
  30687. #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN */
  30688. typedef char ctx_size_test[sizeof(sp_ecc_key_gen_384_ctx)
  30689. >= sizeof(*sp_ctx) ? -1 : 1];
  30690. (void)sizeof(ctx_size_test);
  30691. switch (ctx->state) {
  30692. case 0:
  30693. err = sp_384_ecc_gen_k_7(rng, ctx->k);
  30694. if (err == MP_OKAY) {
  30695. err = FP_WOULDBLOCK;
  30696. ctx->state = 1;
  30697. }
  30698. break;
  30699. case 1:
  30700. err = sp_384_ecc_mulmod_base_7_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx,
  30701. ctx->point, ctx->k, 1, 1, heap);
  30702. if (err == MP_OKAY) {
  30703. err = FP_WOULDBLOCK;
  30704. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  30705. XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
  30706. ctx->state = 2;
  30707. #else
  30708. ctx->state = 3;
  30709. #endif
  30710. }
  30711. break;
  30712. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  30713. case 2:
  30714. err = sp_384_ecc_mulmod_7_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx,
  30715. infinity, ctx->point, p384_order, 1, 1);
  30716. if (err == MP_OKAY) {
  30717. if (sp_384_iszero_7(ctx->point->x) ||
  30718. sp_384_iszero_7(ctx->point->y)) {
  30719. err = ECC_INF_E;
  30720. }
  30721. else {
  30722. err = FP_WOULDBLOCK;
  30723. ctx->state = 3;
  30724. }
  30725. }
  30726. break;
  30727. #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN */
  30728. case 3:
  30729. err = sp_384_to_mp(ctx->k, priv);
  30730. if (err == MP_OKAY) {
  30731. err = sp_384_point_to_ecc_point_7(ctx->point, pub);
  30732. }
  30733. break;
  30734. }
  30735. if (err != FP_WOULDBLOCK) {
  30736. XMEMSET(ctx, 0, sizeof(sp_ecc_key_gen_384_ctx));
  30737. }
  30738. return err;
  30739. }
  30740. #endif /* WOLFSSL_SP_NONBLOCK */
  30741. #ifdef HAVE_ECC_DHE
  30742. /* Write r as big endian to byte array.
  30743. * Fixed length number of bytes written: 48
  30744. *
  30745. * r A single precision integer.
  30746. * a Byte array.
  30747. */
  30748. static void sp_384_to_bin_7(sp_digit* r, byte* a)
  30749. {
  30750. int i;
  30751. int j;
  30752. int s = 0;
  30753. int b;
  30754. for (i=0; i<6; i++) {
  30755. r[i+1] += r[i] >> 55;
  30756. r[i] &= 0x7fffffffffffffL;
  30757. }
  30758. j = 391 / 8 - 1;
  30759. a[j] = 0;
  30760. for (i=0; i<7 && j>=0; i++) {
  30761. b = 0;
  30762. /* lint allow cast of mismatch sp_digit and int */
  30763. a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
  30764. b += 8 - s;
  30765. if (j < 0) {
  30766. break;
  30767. }
  30768. while (b < 55) {
  30769. a[j--] = (byte)(r[i] >> b);
  30770. b += 8;
  30771. if (j < 0) {
  30772. break;
  30773. }
  30774. }
  30775. s = 8 - (b - 55);
  30776. if (j >= 0) {
  30777. a[j] = 0;
  30778. }
  30779. if (s != 0) {
  30780. j++;
  30781. }
  30782. }
  30783. }
  30784. /* Multiply the point by the scalar and serialize the X ordinate.
  30785. * The number is 0 padded to maximum size on output.
  30786. *
  30787. * priv Scalar to multiply the point by.
  30788. * pub Point to multiply.
  30789. * out Buffer to hold X ordinate.
  30790. * outLen On entry, size of the buffer in bytes.
  30791. * On exit, length of data in buffer in bytes.
  30792. * heap Heap to use for allocation.
  30793. * returns BUFFER_E if the buffer is to small for output size,
  30794. * MEMORY_E when memory allocation fails and MP_OKAY on success.
  30795. */
  30796. int sp_ecc_secret_gen_384(const mp_int* priv, const ecc_point* pub, byte* out,
  30797. word32* outLen, void* heap)
  30798. {
  30799. #ifdef WOLFSSL_SP_SMALL_STACK
  30800. sp_point_384* point = NULL;
  30801. sp_digit* k = NULL;
  30802. #else
  30803. sp_point_384 point[1];
  30804. sp_digit k[7];
  30805. #endif
  30806. int err = MP_OKAY;
  30807. if (*outLen < 48U) {
  30808. err = BUFFER_E;
  30809. }
  30810. #ifdef WOLFSSL_SP_SMALL_STACK
  30811. if (err == MP_OKAY) {
  30812. point = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap,
  30813. DYNAMIC_TYPE_ECC);
  30814. if (point == NULL)
  30815. err = MEMORY_E;
  30816. }
  30817. if (err == MP_OKAY) {
  30818. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap,
  30819. DYNAMIC_TYPE_ECC);
  30820. if (k == NULL)
  30821. err = MEMORY_E;
  30822. }
  30823. #endif
  30824. if (err == MP_OKAY) {
  30825. sp_384_from_mp(k, 7, priv);
  30826. sp_384_point_from_ecc_point_7(point, pub);
  30827. err = sp_384_ecc_mulmod_7(point, point, k, 1, 1, heap);
  30828. }
  30829. if (err == MP_OKAY) {
  30830. sp_384_to_bin_7(point->x, out);
  30831. *outLen = 48;
  30832. }
  30833. #ifdef WOLFSSL_SP_SMALL_STACK
  30834. if (k != NULL)
  30835. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  30836. if (point != NULL)
  30837. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  30838. #endif
  30839. return err;
  30840. }
  30841. #ifdef WOLFSSL_SP_NONBLOCK
  30842. typedef struct sp_ecc_sec_gen_384_ctx {
  30843. int state;
  30844. union {
  30845. sp_384_ecc_mulmod_7_ctx mulmod_ctx;
  30846. };
  30847. sp_digit k[7];
  30848. sp_point_384 point;
  30849. } sp_ecc_sec_gen_384_ctx;
  30850. int sp_ecc_secret_gen_384_nb(sp_ecc_ctx_t* sp_ctx, const mp_int* priv,
  30851. const ecc_point* pub, byte* out, word32* outLen, void* heap)
  30852. {
  30853. int err = FP_WOULDBLOCK;
  30854. sp_ecc_sec_gen_384_ctx* ctx = (sp_ecc_sec_gen_384_ctx*)sp_ctx->data;
  30855. typedef char ctx_size_test[sizeof(sp_ecc_sec_gen_384_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  30856. (void)sizeof(ctx_size_test);
  30857. if (*outLen < 32U) {
  30858. err = BUFFER_E;
  30859. }
  30860. switch (ctx->state) {
  30861. case 0:
  30862. sp_384_from_mp(ctx->k, 7, priv);
  30863. sp_384_point_from_ecc_point_7(&ctx->point, pub);
  30864. ctx->state = 1;
  30865. break;
  30866. case 1:
  30867. err = sp_384_ecc_mulmod_7_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx,
  30868. &ctx->point, &ctx->point, ctx->k, 1, 1, heap);
  30869. if (err == MP_OKAY) {
  30870. sp_384_to_bin_7(ctx->point.x, out);
  30871. *outLen = 48;
  30872. }
  30873. break;
  30874. }
  30875. if (err == MP_OKAY && ctx->state != 1) {
  30876. err = FP_WOULDBLOCK;
  30877. }
  30878. if (err != FP_WOULDBLOCK) {
  30879. XMEMSET(ctx, 0, sizeof(sp_ecc_sec_gen_384_ctx));
  30880. }
  30881. return err;
  30882. }
  30883. #endif /* WOLFSSL_SP_NONBLOCK */
  30884. #endif /* HAVE_ECC_DHE */
  30885. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  30886. #endif
  30887. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  30888. SP_NOINLINE static void sp_384_rshift_7(sp_digit* r, const sp_digit* a,
  30889. byte n)
  30890. {
  30891. int i;
  30892. #ifdef WOLFSSL_SP_SMALL
  30893. for (i=0; i<6; i++) {
  30894. r[i] = ((a[i] >> n) | (a[i + 1] << (55 - n))) & 0x7fffffffffffffL;
  30895. }
  30896. #else
  30897. for (i=0; i<0; i += 8) {
  30898. r[i+0] = (a[i+0] >> n) | ((a[i+1] << (55 - n)) & 0x7fffffffffffffL);
  30899. r[i+1] = (a[i+1] >> n) | ((a[i+2] << (55 - n)) & 0x7fffffffffffffL);
  30900. r[i+2] = (a[i+2] >> n) | ((a[i+3] << (55 - n)) & 0x7fffffffffffffL);
  30901. r[i+3] = (a[i+3] >> n) | ((a[i+4] << (55 - n)) & 0x7fffffffffffffL);
  30902. r[i+4] = (a[i+4] >> n) | ((a[i+5] << (55 - n)) & 0x7fffffffffffffL);
  30903. r[i+5] = (a[i+5] >> n) | ((a[i+6] << (55 - n)) & 0x7fffffffffffffL);
  30904. r[i+6] = (a[i+6] >> n) | ((a[i+7] << (55 - n)) & 0x7fffffffffffffL);
  30905. r[i+7] = (a[i+7] >> n) | ((a[i+8] << (55 - n)) & 0x7fffffffffffffL);
  30906. }
  30907. r[0] = (a[0] >> n) | ((a[1] << (55 - n)) & 0x7fffffffffffffL);
  30908. r[1] = (a[1] >> n) | ((a[2] << (55 - n)) & 0x7fffffffffffffL);
  30909. r[2] = (a[2] >> n) | ((a[3] << (55 - n)) & 0x7fffffffffffffL);
  30910. r[3] = (a[3] >> n) | ((a[4] << (55 - n)) & 0x7fffffffffffffL);
  30911. r[4] = (a[4] >> n) | ((a[5] << (55 - n)) & 0x7fffffffffffffL);
  30912. r[5] = (a[5] >> n) | ((a[6] << (55 - n)) & 0x7fffffffffffffL);
  30913. #endif /* WOLFSSL_SP_SMALL */
  30914. r[6] = a[6] >> n;
  30915. }
  30916. /* Multiply a by scalar b into r. (r = a * b)
  30917. *
  30918. * r A single precision integer.
  30919. * a A single precision integer.
  30920. * b A scalar.
  30921. */
  30922. SP_NOINLINE static void sp_384_mul_d_7(sp_digit* r, const sp_digit* a,
  30923. sp_digit b)
  30924. {
  30925. #ifdef WOLFSSL_SP_SMALL
  30926. sp_int128 tb = b;
  30927. sp_int128 t = 0;
  30928. int i;
  30929. for (i = 0; i < 7; i++) {
  30930. t += tb * a[i];
  30931. r[i] = (sp_digit)(t & 0x7fffffffffffffL);
  30932. t >>= 55;
  30933. }
  30934. r[7] = (sp_digit)t;
  30935. #else
  30936. sp_int128 tb = b;
  30937. sp_int128 t[7];
  30938. t[ 0] = tb * a[ 0];
  30939. t[ 1] = tb * a[ 1];
  30940. t[ 2] = tb * a[ 2];
  30941. t[ 3] = tb * a[ 3];
  30942. t[ 4] = tb * a[ 4];
  30943. t[ 5] = tb * a[ 5];
  30944. t[ 6] = tb * a[ 6];
  30945. r[ 0] = (sp_digit) (t[ 0] & 0x7fffffffffffffL);
  30946. r[ 1] = (sp_digit)((t[ 0] >> 55) + (t[ 1] & 0x7fffffffffffffL));
  30947. r[ 2] = (sp_digit)((t[ 1] >> 55) + (t[ 2] & 0x7fffffffffffffL));
  30948. r[ 3] = (sp_digit)((t[ 2] >> 55) + (t[ 3] & 0x7fffffffffffffL));
  30949. r[ 4] = (sp_digit)((t[ 3] >> 55) + (t[ 4] & 0x7fffffffffffffL));
  30950. r[ 5] = (sp_digit)((t[ 4] >> 55) + (t[ 5] & 0x7fffffffffffffL));
  30951. r[ 6] = (sp_digit)((t[ 5] >> 55) + (t[ 6] & 0x7fffffffffffffL));
  30952. r[ 7] = (sp_digit) (t[ 6] >> 55);
  30953. #endif /* WOLFSSL_SP_SMALL */
  30954. }
  30955. SP_NOINLINE static void sp_384_lshift_14(sp_digit* r, const sp_digit* a,
  30956. byte n)
  30957. {
  30958. #ifdef WOLFSSL_SP_SMALL
  30959. int i;
  30960. r[14] = a[13] >> (55 - n);
  30961. for (i=13; i>0; i--) {
  30962. r[i] = ((a[i] << n) | (a[i-1] >> (55 - n))) & 0x7fffffffffffffL;
  30963. }
  30964. #else
  30965. sp_int_digit s;
  30966. sp_int_digit t;
  30967. s = (sp_int_digit)a[13];
  30968. r[14] = s >> (55U - n);
  30969. s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);
  30970. r[13] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
  30971. s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);
  30972. r[12] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
  30973. s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);
  30974. r[11] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
  30975. s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);
  30976. r[10] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
  30977. s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);
  30978. r[9] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
  30979. s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);
  30980. r[8] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
  30981. s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);
  30982. r[7] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
  30983. s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);
  30984. r[6] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
  30985. s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);
  30986. r[5] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
  30987. s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);
  30988. r[4] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
  30989. s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);
  30990. r[3] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
  30991. s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);
  30992. r[2] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
  30993. s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);
  30994. r[1] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
  30995. #endif /* WOLFSSL_SP_SMALL */
  30996. r[0] = (a[0] << n) & 0x7fffffffffffffL;
  30997. }
  30998. /* Divide d in a and put remainder into r (m*d + r = a)
  30999. * m is not calculated as it is not needed at this time.
  31000. *
  31001. * Simplified based on top word of divisor being (1 << 55) - 1
  31002. *
  31003. * a Number to be divided.
  31004. * d Number to divide with.
  31005. * m Multiplier result.
  31006. * r Remainder from the division.
  31007. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  31008. */
  31009. static int sp_384_div_7(const sp_digit* a, const sp_digit* d,
  31010. const sp_digit* m, sp_digit* r)
  31011. {
  31012. int i;
  31013. sp_digit r1;
  31014. sp_digit mask;
  31015. #ifdef WOLFSSL_SP_SMALL_STACK
  31016. sp_digit* t1 = NULL;
  31017. #else
  31018. sp_digit t1[4 * 7 + 3];
  31019. #endif
  31020. sp_digit* t2 = NULL;
  31021. sp_digit* sd = NULL;
  31022. int err = MP_OKAY;
  31023. (void)m;
  31024. #ifdef WOLFSSL_SP_SMALL_STACK
  31025. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 7 + 3), NULL,
  31026. DYNAMIC_TYPE_TMP_BUFFER);
  31027. if (t1 == NULL)
  31028. err = MEMORY_E;
  31029. #endif
  31030. (void)m;
  31031. if (err == MP_OKAY) {
  31032. t2 = t1 + 14 + 1;
  31033. sd = t2 + 7 + 1;
  31034. sp_384_mul_d_7(sd, d, (sp_digit)1 << 1);
  31035. sp_384_lshift_14(t1, a, 1);
  31036. t1[7 + 7] += t1[7 + 7 - 1] >> 55;
  31037. t1[7 + 7 - 1] &= 0x7fffffffffffffL;
  31038. for (i=6; i>=0; i--) {
  31039. r1 = t1[7 + i];
  31040. sp_384_mul_d_7(t2, sd, r1);
  31041. (void)sp_384_sub_7(&t1[i], &t1[i], t2);
  31042. t1[7 + i] -= t2[7];
  31043. sp_384_norm_7(&t1[i + 1]);
  31044. mask = ~((t1[7 + i] - 1) >> 63);
  31045. sp_384_cond_sub_7(t1 + i, t1 + i, sd, mask);
  31046. sp_384_norm_7(&t1[i + 1]);
  31047. }
  31048. sp_384_norm_7(t1);
  31049. sp_384_rshift_7(r, t1, 1);
  31050. }
  31051. #ifdef WOLFSSL_SP_SMALL_STACK
  31052. if (t1 != NULL)
  31053. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  31054. #endif
  31055. return err;
  31056. }
  31057. /* Reduce a modulo m into r. (r = a mod m)
  31058. *
  31059. * r A single precision number that is the reduced result.
  31060. * a A single precision number that is to be reduced.
  31061. * m A single precision number that is the modulus to reduce with.
  31062. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  31063. */
  31064. static int sp_384_mod_7(sp_digit* r, const sp_digit* a, const sp_digit* m)
  31065. {
  31066. return sp_384_div_7(a, m, NULL, r);
  31067. }
  31068. #endif
  31069. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  31070. /* Multiply two number mod the order of P384 curve. (r = a * b mod order)
  31071. *
  31072. * r Result of the multiplication.
  31073. * a First operand of the multiplication.
  31074. * b Second operand of the multiplication.
  31075. */
  31076. static void sp_384_mont_mul_order_7(sp_digit* r, const sp_digit* a, const sp_digit* b)
  31077. {
  31078. sp_384_mul_7(r, a, b);
  31079. sp_384_mont_reduce_order_7(r, p384_order, p384_mp_order);
  31080. }
  31081. #if defined(HAVE_ECC_SIGN) || (defined(HAVE_ECC_VERIFY) && defined(WOLFSSL_SP_SMALL))
  31082. #ifdef WOLFSSL_SP_SMALL
  31083. /* Order-2 for the P384 curve. */
  31084. static const uint64_t p384_order_minus_2[6] = {
  31085. 0xecec196accc52971U,0x581a0db248b0a77aU,0xc7634d81f4372ddfU,
  31086. 0xffffffffffffffffU,0xffffffffffffffffU,0xffffffffffffffffU
  31087. };
  31088. #else
  31089. /* The low half of the order-2 of the P384 curve. */
  31090. static const uint64_t p384_order_low[3] = {
  31091. 0xecec196accc52971U,0x581a0db248b0a77aU,0xc7634d81f4372ddfU
  31092. };
  31093. #endif /* WOLFSSL_SP_SMALL */
  31094. /* Square number mod the order of P384 curve. (r = a * a mod order)
  31095. *
  31096. * r Result of the squaring.
  31097. * a Number to square.
  31098. */
  31099. static void sp_384_mont_sqr_order_7(sp_digit* r, const sp_digit* a)
  31100. {
  31101. sp_384_sqr_7(r, a);
  31102. sp_384_mont_reduce_order_7(r, p384_order, p384_mp_order);
  31103. }
  31104. #ifndef WOLFSSL_SP_SMALL
  31105. /* Square number mod the order of P384 curve a number of times.
  31106. * (r = a ^ n mod order)
  31107. *
  31108. * r Result of the squaring.
  31109. * a Number to square.
  31110. */
  31111. static void sp_384_mont_sqr_n_order_7(sp_digit* r, const sp_digit* a, int n)
  31112. {
  31113. int i;
  31114. sp_384_mont_sqr_order_7(r, a);
  31115. for (i=1; i<n; i++) {
  31116. sp_384_mont_sqr_order_7(r, r);
  31117. }
  31118. }
  31119. #endif /* !WOLFSSL_SP_SMALL */
  31120. /* Invert the number, in Montgomery form, modulo the order of the P384 curve.
  31121. * (r = 1 / a mod order)
  31122. *
  31123. * r Inverse result.
  31124. * a Number to invert.
  31125. * td Temporary data.
  31126. */
  31127. #ifdef WOLFSSL_SP_NONBLOCK
  31128. typedef struct sp_384_mont_inv_order_7_ctx {
  31129. int state;
  31130. int i;
  31131. } sp_384_mont_inv_order_7_ctx;
  31132. static int sp_384_mont_inv_order_7_nb(sp_ecc_ctx_t* sp_ctx, sp_digit* r, const sp_digit* a,
  31133. sp_digit* t)
  31134. {
  31135. int err = FP_WOULDBLOCK;
  31136. sp_384_mont_inv_order_7_ctx* ctx = (sp_384_mont_inv_order_7_ctx*)sp_ctx;
  31137. typedef char ctx_size_test[sizeof(sp_384_mont_inv_order_7_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  31138. (void)sizeof(ctx_size_test);
  31139. switch (ctx->state) {
  31140. case 0:
  31141. XMEMCPY(t, a, sizeof(sp_digit) * 7);
  31142. ctx->i = 382;
  31143. ctx->state = 1;
  31144. break;
  31145. case 1:
  31146. sp_384_mont_sqr_order_7(t, t);
  31147. ctx->state = 2;
  31148. break;
  31149. case 2:
  31150. if ((p384_order_minus_2[ctx->i / 64] & ((sp_int_digit)1 << (ctx->i % 64))) != 0) {
  31151. sp_384_mont_mul_order_7(t, t, a);
  31152. }
  31153. ctx->i--;
  31154. ctx->state = (ctx->i == 0) ? 3 : 1;
  31155. break;
  31156. case 3:
  31157. XMEMCPY(r, t, sizeof(sp_digit) * 7U);
  31158. err = MP_OKAY;
  31159. break;
  31160. }
  31161. return err;
  31162. }
  31163. #endif /* WOLFSSL_SP_NONBLOCK */
  31164. static void sp_384_mont_inv_order_7(sp_digit* r, const sp_digit* a,
  31165. sp_digit* td)
  31166. {
  31167. #ifdef WOLFSSL_SP_SMALL
  31168. sp_digit* t = td;
  31169. int i;
  31170. XMEMCPY(t, a, sizeof(sp_digit) * 7);
  31171. for (i=382; i>=0; i--) {
  31172. sp_384_mont_sqr_order_7(t, t);
  31173. if ((p384_order_minus_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
  31174. sp_384_mont_mul_order_7(t, t, a);
  31175. }
  31176. }
  31177. XMEMCPY(r, t, sizeof(sp_digit) * 7U);
  31178. #else
  31179. sp_digit* t = td;
  31180. sp_digit* t2 = td + 2 * 7;
  31181. sp_digit* t3 = td + 4 * 7;
  31182. int i;
  31183. /* t = a^2 */
  31184. sp_384_mont_sqr_order_7(t, a);
  31185. /* t = a^3 = t * a */
  31186. sp_384_mont_mul_order_7(t, t, a);
  31187. /* t2= a^c = t ^ 2 ^ 2 */
  31188. sp_384_mont_sqr_n_order_7(t2, t, 2);
  31189. /* t = a^f = t2 * t */
  31190. sp_384_mont_mul_order_7(t, t2, t);
  31191. /* t2= a^f0 = t ^ 2 ^ 4 */
  31192. sp_384_mont_sqr_n_order_7(t2, t, 4);
  31193. /* t = a^ff = t2 * t */
  31194. sp_384_mont_mul_order_7(t, t2, t);
  31195. /* t2= a^ff00 = t ^ 2 ^ 8 */
  31196. sp_384_mont_sqr_n_order_7(t2, t, 8);
  31197. /* t3= a^ffff = t2 * t */
  31198. sp_384_mont_mul_order_7(t3, t2, t);
  31199. /* t2= a^ffff0000 = t3 ^ 2 ^ 16 */
  31200. sp_384_mont_sqr_n_order_7(t2, t3, 16);
  31201. /* t = a^ffffffff = t2 * t3 */
  31202. sp_384_mont_mul_order_7(t, t2, t3);
  31203. /* t2= a^ffffffff0000 = t ^ 2 ^ 16 */
  31204. sp_384_mont_sqr_n_order_7(t2, t, 16);
  31205. /* t = a^ffffffffffff = t2 * t3 */
  31206. sp_384_mont_mul_order_7(t, t2, t3);
  31207. /* t2= a^ffffffffffff000000000000 = t ^ 2 ^ 48 */
  31208. sp_384_mont_sqr_n_order_7(t2, t, 48);
  31209. /* t= a^fffffffffffffffffffffffff = t2 * t */
  31210. sp_384_mont_mul_order_7(t, t2, t);
  31211. /* t2= a^ffffffffffffffffffffffff000000000000000000000000 */
  31212. sp_384_mont_sqr_n_order_7(t2, t, 96);
  31213. /* t2= a^ffffffffffffffffffffffffffffffffffffffffffffffff = t2 * t */
  31214. sp_384_mont_mul_order_7(t2, t2, t);
  31215. for (i=191; i>=1; i--) {
  31216. sp_384_mont_sqr_order_7(t2, t2);
  31217. if ((p384_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
  31218. sp_384_mont_mul_order_7(t2, t2, a);
  31219. }
  31220. }
  31221. sp_384_mont_sqr_order_7(t2, t2);
  31222. sp_384_mont_mul_order_7(r, t2, a);
  31223. #endif /* WOLFSSL_SP_SMALL */
  31224. }
  31225. #endif /* HAVE_ECC_SIGN || (HAVE_ECC_VERIFY && WOLFSSL_SP_SMALL) */
  31226. #endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */
  31227. #ifdef HAVE_ECC_SIGN
  31228. #ifndef SP_ECC_MAX_SIG_GEN
  31229. #define SP_ECC_MAX_SIG_GEN 64
  31230. #endif
  31231. /* Calculate second signature value S from R, k and private value.
  31232. *
  31233. * s = (r * x + e) / k
  31234. *
  31235. * s Signature value.
  31236. * r First signature value.
  31237. * k Ephemeral private key.
  31238. * x Private key as a number.
  31239. * e Hash of message as a number.
  31240. * tmp Temporary storage for intermediate numbers.
  31241. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  31242. */
  31243. static int sp_384_calc_s_7(sp_digit* s, const sp_digit* r, sp_digit* k,
  31244. sp_digit* x, const sp_digit* e, sp_digit* tmp)
  31245. {
  31246. int err;
  31247. sp_digit carry;
  31248. sp_int64 c;
  31249. sp_digit* kInv = k;
  31250. /* Conv k to Montgomery form (mod order) */
  31251. sp_384_mul_7(k, k, p384_norm_order);
  31252. err = sp_384_mod_7(k, k, p384_order);
  31253. if (err == MP_OKAY) {
  31254. sp_384_norm_7(k);
  31255. /* kInv = 1/k mod order */
  31256. sp_384_mont_inv_order_7(kInv, k, tmp);
  31257. sp_384_norm_7(kInv);
  31258. /* s = r * x + e */
  31259. sp_384_mul_7(x, x, r);
  31260. err = sp_384_mod_7(x, x, p384_order);
  31261. }
  31262. if (err == MP_OKAY) {
  31263. sp_384_norm_7(x);
  31264. carry = sp_384_add_7(s, e, x);
  31265. sp_384_cond_sub_7(s, s, p384_order, 0 - carry);
  31266. sp_384_norm_7(s);
  31267. c = sp_384_cmp_7(s, p384_order);
  31268. sp_384_cond_sub_7(s, s, p384_order,
  31269. (sp_digit)0 - (sp_digit)(c >= 0));
  31270. sp_384_norm_7(s);
  31271. /* s = s * k^-1 mod order */
  31272. sp_384_mont_mul_order_7(s, s, kInv);
  31273. sp_384_norm_7(s);
  31274. }
  31275. return err;
  31276. }
  31277. /* Sign the hash using the private key.
  31278. * e = [hash, 384 bits] from binary
  31279. * r = (k.G)->x mod order
  31280. * s = (r * x + e) / k mod order
  31281. * The hash is truncated to the first 384 bits.
  31282. *
  31283. * hash Hash to sign.
  31284. * hashLen Length of the hash data.
  31285. * rng Random number generator.
  31286. * priv Private part of key - scalar.
  31287. * rm First part of result as an mp_int.
  31288. * sm Sirst part of result as an mp_int.
  31289. * heap Heap to use for allocation.
  31290. * returns RNG failures, MEMORY_E when memory allocation fails and
  31291. * MP_OKAY on success.
  31292. */
  31293. int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng,
  31294. const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap)
  31295. {
  31296. #ifdef WOLFSSL_SP_SMALL_STACK
  31297. sp_digit* e = NULL;
  31298. sp_point_384* point = NULL;
  31299. #else
  31300. sp_digit e[7 * 2 * 7];
  31301. sp_point_384 point[1];
  31302. #endif
  31303. sp_digit* x = NULL;
  31304. sp_digit* k = NULL;
  31305. sp_digit* r = NULL;
  31306. sp_digit* tmp = NULL;
  31307. sp_digit* s = NULL;
  31308. sp_int64 c;
  31309. int err = MP_OKAY;
  31310. int i;
  31311. (void)heap;
  31312. #ifdef WOLFSSL_SP_SMALL_STACK
  31313. if (err == MP_OKAY) {
  31314. point = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap,
  31315. DYNAMIC_TYPE_ECC);
  31316. if (point == NULL)
  31317. err = MEMORY_E;
  31318. }
  31319. if (err == MP_OKAY) {
  31320. e = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 7, heap,
  31321. DYNAMIC_TYPE_ECC);
  31322. if (e == NULL)
  31323. err = MEMORY_E;
  31324. }
  31325. #endif
  31326. if (err == MP_OKAY) {
  31327. x = e + 2 * 7;
  31328. k = e + 4 * 7;
  31329. r = e + 6 * 7;
  31330. tmp = e + 8 * 7;
  31331. s = e;
  31332. if (hashLen > 48U) {
  31333. hashLen = 48U;
  31334. }
  31335. }
  31336. for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {
  31337. /* New random point. */
  31338. if (km == NULL || mp_iszero(km)) {
  31339. err = sp_384_ecc_gen_k_7(rng, k);
  31340. }
  31341. else {
  31342. sp_384_from_mp(k, 7, km);
  31343. mp_zero(km);
  31344. }
  31345. if (err == MP_OKAY) {
  31346. err = sp_384_ecc_mulmod_base_7(point, k, 1, 1, heap);
  31347. }
  31348. if (err == MP_OKAY) {
  31349. /* r = point->x mod order */
  31350. XMEMCPY(r, point->x, sizeof(sp_digit) * 7U);
  31351. sp_384_norm_7(r);
  31352. c = sp_384_cmp_7(r, p384_order);
  31353. sp_384_cond_sub_7(r, r, p384_order,
  31354. (sp_digit)0 - (sp_digit)(c >= 0));
  31355. sp_384_norm_7(r);
  31356. if (!sp_384_iszero_7(r)) {
  31357. /* x is modified in calculation of s. */
  31358. sp_384_from_mp(x, 7, priv);
  31359. /* s ptr == e ptr, e is modified in calculation of s. */
  31360. sp_384_from_bin(e, 7, hash, (int)hashLen);
  31361. err = sp_384_calc_s_7(s, r, k, x, e, tmp);
  31362. /* Check that signature is usable. */
  31363. if ((err == MP_OKAY) && (!sp_384_iszero_7(s))) {
  31364. break;
  31365. }
  31366. }
  31367. }
  31368. #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
  31369. i = 1;
  31370. #endif
  31371. }
  31372. if (i == 0) {
  31373. err = RNG_FAILURE_E;
  31374. }
  31375. if (err == MP_OKAY) {
  31376. err = sp_384_to_mp(r, rm);
  31377. }
  31378. if (err == MP_OKAY) {
  31379. err = sp_384_to_mp(s, sm);
  31380. }
  31381. #ifdef WOLFSSL_SP_SMALL_STACK
  31382. if (e != NULL)
  31383. #endif
  31384. {
  31385. ForceZero(e, sizeof(sp_digit) * 7 * 2 * 7);
  31386. #ifdef WOLFSSL_SP_SMALL_STACK
  31387. XFREE(e, heap, DYNAMIC_TYPE_ECC);
  31388. #endif
  31389. }
  31390. #ifdef WOLFSSL_SP_SMALL_STACK
  31391. if (point != NULL)
  31392. #endif
  31393. {
  31394. ForceZero(point, sizeof(sp_point_384));
  31395. #ifdef WOLFSSL_SP_SMALL_STACK
  31396. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  31397. #endif
  31398. }
  31399. return err;
  31400. }
  31401. #ifdef WOLFSSL_SP_NONBLOCK
  31402. typedef struct sp_ecc_sign_384_ctx {
  31403. int state;
  31404. union {
  31405. sp_384_ecc_mulmod_7_ctx mulmod_ctx;
  31406. sp_384_mont_inv_order_7_ctx mont_inv_order_ctx;
  31407. };
  31408. sp_digit e[2*7];
  31409. sp_digit x[2*7];
  31410. sp_digit k[2*7];
  31411. sp_digit r[2*7];
  31412. sp_digit tmp[3 * 2*7];
  31413. sp_point_384 point;
  31414. sp_digit* s;
  31415. sp_digit* kInv;
  31416. int i;
  31417. } sp_ecc_sign_384_ctx;
  31418. int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng,
  31419. mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap)
  31420. {
  31421. int err = FP_WOULDBLOCK;
  31422. sp_ecc_sign_384_ctx* ctx = (sp_ecc_sign_384_ctx*)sp_ctx->data;
  31423. typedef char ctx_size_test[sizeof(sp_ecc_sign_384_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  31424. (void)sizeof(ctx_size_test);
  31425. switch (ctx->state) {
  31426. case 0: /* INIT */
  31427. ctx->s = ctx->e;
  31428. ctx->kInv = ctx->k;
  31429. ctx->i = SP_ECC_MAX_SIG_GEN;
  31430. ctx->state = 1;
  31431. break;
  31432. case 1: /* GEN */
  31433. /* New random point. */
  31434. if (km == NULL || mp_iszero(km)) {
  31435. err = sp_384_ecc_gen_k_7(rng, ctx->k);
  31436. }
  31437. else {
  31438. sp_384_from_mp(ctx->k, 7, km);
  31439. mp_zero(km);
  31440. }
  31441. XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
  31442. ctx->state = 2;
  31443. break;
  31444. case 2: /* MULMOD */
  31445. err = sp_384_ecc_mulmod_7_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx,
  31446. &ctx->point, &p384_base, ctx->k, 1, 1, heap);
  31447. if (err == MP_OKAY) {
  31448. ctx->state = 3;
  31449. }
  31450. break;
  31451. case 3: /* MODORDER */
  31452. {
  31453. sp_int64 c;
  31454. /* r = point->x mod order */
  31455. XMEMCPY(ctx->r, ctx->point.x, sizeof(sp_digit) * 7U);
  31456. sp_384_norm_7(ctx->r);
  31457. c = sp_384_cmp_7(ctx->r, p384_order);
  31458. sp_384_cond_sub_7(ctx->r, ctx->r, p384_order,
  31459. (sp_digit)0 - (sp_digit)(c >= 0));
  31460. sp_384_norm_7(ctx->r);
  31461. if (hashLen > 48U) {
  31462. hashLen = 48U;
  31463. }
  31464. sp_384_from_mp(ctx->x, 7, priv);
  31465. sp_384_from_bin(ctx->e, 7, hash, (int)hashLen);
  31466. ctx->state = 4;
  31467. break;
  31468. }
  31469. case 4: /* KMODORDER */
  31470. /* Conv k to Montgomery form (mod order) */
  31471. sp_384_mul_7(ctx->k, ctx->k, p384_norm_order);
  31472. err = sp_384_mod_7(ctx->k, ctx->k, p384_order);
  31473. if (err == MP_OKAY) {
  31474. sp_384_norm_7(ctx->k);
  31475. XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
  31476. ctx->state = 5;
  31477. }
  31478. break;
  31479. case 5: /* KINV */
  31480. /* kInv = 1/k mod order */
  31481. err = sp_384_mont_inv_order_7_nb((sp_ecc_ctx_t*)&ctx->mont_inv_order_ctx, ctx->kInv, ctx->k, ctx->tmp);
  31482. if (err == MP_OKAY) {
  31483. XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
  31484. ctx->state = 6;
  31485. }
  31486. break;
  31487. case 6: /* KINVNORM */
  31488. sp_384_norm_7(ctx->kInv);
  31489. ctx->state = 7;
  31490. break;
  31491. case 7: /* R */
  31492. /* s = r * x + e */
  31493. sp_384_mul_7(ctx->x, ctx->x, ctx->r);
  31494. ctx->state = 8;
  31495. break;
  31496. case 8: /* S1 */
  31497. err = sp_384_mod_7(ctx->x, ctx->x, p384_order);
  31498. if (err == MP_OKAY)
  31499. ctx->state = 9;
  31500. break;
  31501. case 9: /* S2 */
  31502. {
  31503. sp_digit carry;
  31504. sp_int64 c;
  31505. sp_384_norm_7(ctx->x);
  31506. carry = sp_384_add_7(ctx->s, ctx->e, ctx->x);
  31507. sp_384_cond_sub_7(ctx->s, ctx->s,
  31508. p384_order, 0 - carry);
  31509. sp_384_norm_7(ctx->s);
  31510. c = sp_384_cmp_7(ctx->s, p384_order);
  31511. sp_384_cond_sub_7(ctx->s, ctx->s, p384_order,
  31512. (sp_digit)0 - (sp_digit)(c >= 0));
  31513. sp_384_norm_7(ctx->s);
  31514. /* s = s * k^-1 mod order */
  31515. sp_384_mont_mul_order_7(ctx->s, ctx->s, ctx->kInv);
  31516. sp_384_norm_7(ctx->s);
  31517. /* Check that signature is usable. */
  31518. if (sp_384_iszero_7(ctx->s) == 0) {
  31519. ctx->state = 10;
  31520. break;
  31521. }
  31522. #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
  31523. ctx->i = 1;
  31524. #endif
  31525. /* not usable gen, try again */
  31526. ctx->i--;
  31527. if (ctx->i == 0) {
  31528. err = RNG_FAILURE_E;
  31529. }
  31530. ctx->state = 1;
  31531. break;
  31532. }
  31533. case 10: /* RES */
  31534. err = sp_384_to_mp(ctx->r, rm);
  31535. if (err == MP_OKAY) {
  31536. err = sp_384_to_mp(ctx->s, sm);
  31537. }
  31538. break;
  31539. }
  31540. if (err == MP_OKAY && ctx->state != 10) {
  31541. err = FP_WOULDBLOCK;
  31542. }
  31543. if (err != FP_WOULDBLOCK) {
  31544. XMEMSET(ctx->e, 0, sizeof(sp_digit) * 2U * 7U);
  31545. XMEMSET(ctx->x, 0, sizeof(sp_digit) * 2U * 7U);
  31546. XMEMSET(ctx->k, 0, sizeof(sp_digit) * 2U * 7U);
  31547. XMEMSET(ctx->r, 0, sizeof(sp_digit) * 2U * 7U);
  31548. XMEMSET(ctx->tmp, 0, sizeof(sp_digit) * 3U * 2U * 7U);
  31549. }
  31550. return err;
  31551. }
  31552. #endif /* WOLFSSL_SP_NONBLOCK */
  31553. #endif /* HAVE_ECC_SIGN */
  31554. #ifndef WOLFSSL_SP_SMALL
  31555. static const char sp_384_tab64_7[64] = {
  31556. 64, 1, 59, 2, 60, 48, 54, 3,
  31557. 61, 40, 49, 28, 55, 34, 43, 4,
  31558. 62, 52, 38, 41, 50, 19, 29, 21,
  31559. 56, 31, 35, 12, 44, 15, 23, 5,
  31560. 63, 58, 47, 53, 39, 27, 33, 42,
  31561. 51, 37, 18, 20, 30, 11, 14, 22,
  31562. 57, 46, 26, 32, 36, 17, 10, 13,
  31563. 45, 25, 16, 9, 24, 8, 7, 6};
  31564. static int sp_384_num_bits_55_7(sp_digit v)
  31565. {
  31566. v |= v >> 1;
  31567. v |= v >> 2;
  31568. v |= v >> 4;
  31569. v |= v >> 8;
  31570. v |= v >> 16;
  31571. v |= v >> 32;
  31572. return sp_384_tab64_7[((uint64_t)((v - (v >> 1))*0x07EDD5E59A4E28C2)) >> 58];
  31573. }
  31574. static int sp_384_num_bits_7(const sp_digit* a)
  31575. {
  31576. int i;
  31577. int r = 0;
  31578. for (i = 6; i >= 0; i--) {
  31579. if (a[i] != 0) {
  31580. r = sp_384_num_bits_55_7(a[i]);
  31581. r += i * 55;
  31582. break;
  31583. }
  31584. }
  31585. return r;
  31586. }
  31587. /* Non-constant time modular inversion.
  31588. *
  31589. * @param [out] r Resulting number.
  31590. * @param [in] a Number to invert.
  31591. * @param [in] m Modulus.
  31592. * @return MP_OKAY on success.
  31593. * @return MEMEORY_E when dynamic memory allocation fails.
  31594. */
  31595. static int sp_384_mod_inv_7(sp_digit* r, const sp_digit* a, const sp_digit* m)
  31596. {
  31597. int err = MP_OKAY;
  31598. #ifdef WOLFSSL_SP_SMALL_STACK
  31599. sp_digit* u = NULL;
  31600. #else
  31601. sp_digit u[7 * 4];
  31602. #endif
  31603. sp_digit* v = NULL;
  31604. sp_digit* b = NULL;
  31605. sp_digit* d = NULL;
  31606. int ut;
  31607. int vt;
  31608. #ifdef WOLFSSL_SP_SMALL_STACK
  31609. u = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 4, NULL,
  31610. DYNAMIC_TYPE_ECC);
  31611. if (u == NULL)
  31612. err = MEMORY_E;
  31613. #endif
  31614. if (err == MP_OKAY) {
  31615. v = u + 7;
  31616. b = u + 2 * 7;
  31617. d = u + 3 * 7;
  31618. XMEMCPY(u, m, sizeof(sp_digit) * 7);
  31619. XMEMCPY(v, a, sizeof(sp_digit) * 7);
  31620. ut = sp_384_num_bits_7(u);
  31621. vt = sp_384_num_bits_7(v);
  31622. XMEMSET(b, 0, sizeof(sp_digit) * 7);
  31623. if ((v[0] & 1) == 0) {
  31624. sp_384_rshift1_7(v, v);
  31625. XMEMCPY(d, m, sizeof(sp_digit) * 7);
  31626. d[0]++;
  31627. sp_384_rshift1_7(d, d);
  31628. vt--;
  31629. while ((v[0] & 1) == 0) {
  31630. sp_384_rshift1_7(v, v);
  31631. if (d[0] & 1)
  31632. sp_384_add_7(d, d, m);
  31633. sp_384_rshift1_7(d, d);
  31634. vt--;
  31635. }
  31636. }
  31637. else {
  31638. XMEMSET(d+1, 0, sizeof(sp_digit) * (7 - 1));
  31639. d[0] = 1;
  31640. }
  31641. while (ut > 1 && vt > 1) {
  31642. if ((ut > vt) || ((ut == vt) &&
  31643. (sp_384_cmp_7(u, v) >= 0))) {
  31644. sp_384_sub_7(u, u, v);
  31645. sp_384_norm_7(u);
  31646. sp_384_sub_7(b, b, d);
  31647. sp_384_norm_7(b);
  31648. if (b[6] < 0)
  31649. sp_384_add_7(b, b, m);
  31650. sp_384_norm_7(b);
  31651. ut = sp_384_num_bits_7(u);
  31652. do {
  31653. sp_384_rshift1_7(u, u);
  31654. if (b[0] & 1)
  31655. sp_384_add_7(b, b, m);
  31656. sp_384_rshift1_7(b, b);
  31657. ut--;
  31658. }
  31659. while (ut > 0 && (u[0] & 1) == 0);
  31660. }
  31661. else {
  31662. sp_384_sub_7(v, v, u);
  31663. sp_384_norm_7(v);
  31664. sp_384_sub_7(d, d, b);
  31665. sp_384_norm_7(d);
  31666. if (d[6] < 0)
  31667. sp_384_add_7(d, d, m);
  31668. sp_384_norm_7(d);
  31669. vt = sp_384_num_bits_7(v);
  31670. do {
  31671. sp_384_rshift1_7(v, v);
  31672. if (d[0] & 1)
  31673. sp_384_add_7(d, d, m);
  31674. sp_384_rshift1_7(d, d);
  31675. vt--;
  31676. }
  31677. while (vt > 0 && (v[0] & 1) == 0);
  31678. }
  31679. }
  31680. if (ut == 1)
  31681. XMEMCPY(r, b, sizeof(sp_digit) * 7);
  31682. else
  31683. XMEMCPY(r, d, sizeof(sp_digit) * 7);
  31684. }
  31685. #ifdef WOLFSSL_SP_SMALL_STACK
  31686. if (u != NULL)
  31687. XFREE(u, NULL, DYNAMIC_TYPE_ECC);
  31688. #endif
  31689. return err;
  31690. }
  31691. #endif /* WOLFSSL_SP_SMALL */
  31692. /* Add point p1 into point p2. Handles p1 == p2 and result at infinity.
  31693. *
  31694. * p1 First point to add and holds result.
  31695. * p2 Second point to add.
  31696. * tmp Temporary storage for intermediate numbers.
  31697. */
  31698. static void sp_384_add_points_7(sp_point_384* p1, const sp_point_384* p2,
  31699. sp_digit* tmp)
  31700. {
  31701. sp_384_proj_point_add_7(p1, p1, p2, tmp);
  31702. if (sp_384_iszero_7(p1->z)) {
  31703. if (sp_384_iszero_7(p1->x) && sp_384_iszero_7(p1->y)) {
  31704. sp_384_proj_point_dbl_7(p1, p2, tmp);
  31705. }
  31706. else {
  31707. /* Y ordinate is not used from here - don't set. */
  31708. p1->x[0] = 0;
  31709. p1->x[1] = 0;
  31710. p1->x[2] = 0;
  31711. p1->x[3] = 0;
  31712. p1->x[4] = 0;
  31713. p1->x[5] = 0;
  31714. p1->x[6] = 0;
  31715. XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod));
  31716. }
  31717. }
  31718. }
  31719. /* Calculate the verification point: [e/s]G + [r/s]Q
  31720. *
  31721. * p1 Calculated point.
  31722. * p2 Public point and temporary.
  31723. * s Second part of signature as a number.
  31724. * u1 Temporary number.
  31725. * u2 Temporary number.
  31726. * heap Heap to use for allocation.
  31727. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  31728. */
  31729. static int sp_384_calc_vfy_point_7(sp_point_384* p1, sp_point_384* p2,
  31730. sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap)
  31731. {
  31732. int err;
  31733. #ifndef WOLFSSL_SP_SMALL
  31734. err = sp_384_mod_inv_7(s, s, p384_order);
  31735. if (err == MP_OKAY)
  31736. #endif /* !WOLFSSL_SP_SMALL */
  31737. {
  31738. sp_384_mul_7(s, s, p384_norm_order);
  31739. err = sp_384_mod_7(s, s, p384_order);
  31740. }
  31741. if (err == MP_OKAY) {
  31742. sp_384_norm_7(s);
  31743. #ifdef WOLFSSL_SP_SMALL
  31744. {
  31745. sp_384_mont_inv_order_7(s, s, tmp);
  31746. sp_384_mont_mul_order_7(u1, u1, s);
  31747. sp_384_mont_mul_order_7(u2, u2, s);
  31748. }
  31749. #else
  31750. {
  31751. sp_384_mont_mul_order_7(u1, u1, s);
  31752. sp_384_mont_mul_order_7(u2, u2, s);
  31753. }
  31754. #endif /* WOLFSSL_SP_SMALL */
  31755. {
  31756. err = sp_384_ecc_mulmod_base_7(p1, u1, 0, 0, heap);
  31757. }
  31758. }
  31759. if ((err == MP_OKAY) && sp_384_iszero_7(p1->z)) {
  31760. p1->infinity = 1;
  31761. }
  31762. if (err == MP_OKAY) {
  31763. err = sp_384_ecc_mulmod_7(p2, p2, u2, 0, 0, heap);
  31764. }
  31765. if ((err == MP_OKAY) && sp_384_iszero_7(p2->z)) {
  31766. p2->infinity = 1;
  31767. }
  31768. if (err == MP_OKAY) {
  31769. sp_384_add_points_7(p1, p2, tmp);
  31770. }
  31771. return err;
  31772. }
  31773. #ifdef HAVE_ECC_VERIFY
  31774. /* Verify the signature values with the hash and public key.
  31775. * e = Truncate(hash, 384)
  31776. * u1 = e/s mod order
  31777. * u2 = r/s mod order
  31778. * r == (u1.G + u2.Q)->x mod order
  31779. * Optimization: Leave point in projective form.
  31780. * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')
  31781. * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'
  31782. * The hash is truncated to the first 384 bits.
  31783. *
  31784. * hash Hash to sign.
  31785. * hashLen Length of the hash data.
  31786. * rng Random number generator.
  31787. * priv Private part of key - scalar.
  31788. * rm First part of result as an mp_int.
  31789. * sm Sirst part of result as an mp_int.
  31790. * heap Heap to use for allocation.
  31791. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  31792. */
  31793. int sp_ecc_verify_384(const byte* hash, word32 hashLen, const mp_int* pX,
  31794. const mp_int* pY, const mp_int* pZ, const mp_int* rm, const mp_int* sm,
  31795. int* res, void* heap)
  31796. {
  31797. #ifdef WOLFSSL_SP_SMALL_STACK
  31798. sp_digit* u1 = NULL;
  31799. sp_point_384* p1 = NULL;
  31800. #else
  31801. sp_digit u1[18 * 7];
  31802. sp_point_384 p1[2];
  31803. #endif
  31804. sp_digit* u2 = NULL;
  31805. sp_digit* s = NULL;
  31806. sp_digit* tmp = NULL;
  31807. sp_point_384* p2 = NULL;
  31808. sp_digit carry;
  31809. sp_int64 c = 0;
  31810. int err = MP_OKAY;
  31811. #ifdef WOLFSSL_SP_SMALL_STACK
  31812. if (err == MP_OKAY) {
  31813. p1 = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 2, heap,
  31814. DYNAMIC_TYPE_ECC);
  31815. if (p1 == NULL)
  31816. err = MEMORY_E;
  31817. }
  31818. if (err == MP_OKAY) {
  31819. u1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 7, heap,
  31820. DYNAMIC_TYPE_ECC);
  31821. if (u1 == NULL)
  31822. err = MEMORY_E;
  31823. }
  31824. #endif
  31825. if (err == MP_OKAY) {
  31826. u2 = u1 + 2 * 7;
  31827. s = u1 + 4 * 7;
  31828. tmp = u1 + 6 * 7;
  31829. p2 = p1 + 1;
  31830. if (hashLen > 48U) {
  31831. hashLen = 48U;
  31832. }
  31833. sp_384_from_bin(u1, 7, hash, (int)hashLen);
  31834. sp_384_from_mp(u2, 7, rm);
  31835. sp_384_from_mp(s, 7, sm);
  31836. sp_384_from_mp(p2->x, 7, pX);
  31837. sp_384_from_mp(p2->y, 7, pY);
  31838. sp_384_from_mp(p2->z, 7, pZ);
  31839. err = sp_384_calc_vfy_point_7(p1, p2, s, u1, u2, tmp, heap);
  31840. }
  31841. if (err == MP_OKAY) {
  31842. /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
  31843. /* Reload r and convert to Montgomery form. */
  31844. sp_384_from_mp(u2, 7, rm);
  31845. err = sp_384_mod_mul_norm_7(u2, u2, p384_mod);
  31846. }
  31847. if (err == MP_OKAY) {
  31848. /* u1 = r.z'.z' mod prime */
  31849. sp_384_mont_sqr_7(p1->z, p1->z, p384_mod, p384_mp_mod);
  31850. sp_384_mont_mul_7(u1, u2, p1->z, p384_mod, p384_mp_mod);
  31851. *res = (int)(sp_384_cmp_7(p1->x, u1) == 0);
  31852. if (*res == 0) {
  31853. /* Reload r and add order. */
  31854. sp_384_from_mp(u2, 7, rm);
  31855. carry = sp_384_add_7(u2, u2, p384_order);
  31856. /* Carry means result is greater than mod and is not valid. */
  31857. if (carry == 0) {
  31858. sp_384_norm_7(u2);
  31859. /* Compare with mod and if greater or equal then not valid. */
  31860. c = sp_384_cmp_7(u2, p384_mod);
  31861. }
  31862. }
  31863. if ((*res == 0) && (c < 0)) {
  31864. /* Convert to Montogomery form */
  31865. err = sp_384_mod_mul_norm_7(u2, u2, p384_mod);
  31866. if (err == MP_OKAY) {
  31867. /* u1 = (r + 1*order).z'.z' mod prime */
  31868. {
  31869. sp_384_mont_mul_7(u1, u2, p1->z, p384_mod, p384_mp_mod);
  31870. }
  31871. *res = (sp_384_cmp_7(p1->x, u1) == 0);
  31872. }
  31873. }
  31874. }
  31875. #ifdef WOLFSSL_SP_SMALL_STACK
  31876. if (u1 != NULL)
  31877. XFREE(u1, heap, DYNAMIC_TYPE_ECC);
  31878. if (p1 != NULL)
  31879. XFREE(p1, heap, DYNAMIC_TYPE_ECC);
  31880. #endif
  31881. return err;
  31882. }
  31883. #ifdef WOLFSSL_SP_NONBLOCK
  31884. typedef struct sp_ecc_verify_384_ctx {
  31885. int state;
  31886. union {
  31887. sp_384_ecc_mulmod_7_ctx mulmod_ctx;
  31888. sp_384_mont_inv_order_7_ctx mont_inv_order_ctx;
  31889. sp_384_proj_point_dbl_7_ctx dbl_ctx;
  31890. sp_384_proj_point_add_7_ctx add_ctx;
  31891. };
  31892. sp_digit u1[2*7];
  31893. sp_digit u2[2*7];
  31894. sp_digit s[2*7];
  31895. sp_digit tmp[2*7 * 6];
  31896. sp_point_384 p1;
  31897. sp_point_384 p2;
  31898. } sp_ecc_verify_384_ctx;
  31899. int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash,
  31900. word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ,
  31901. const mp_int* rm, const mp_int* sm, int* res, void* heap)
  31902. {
  31903. int err = FP_WOULDBLOCK;
  31904. sp_ecc_verify_384_ctx* ctx = (sp_ecc_verify_384_ctx*)sp_ctx->data;
  31905. typedef char ctx_size_test[sizeof(sp_ecc_verify_384_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  31906. (void)sizeof(ctx_size_test);
  31907. switch (ctx->state) {
  31908. case 0: /* INIT */
  31909. if (hashLen > 48U) {
  31910. hashLen = 48U;
  31911. }
  31912. sp_384_from_bin(ctx->u1, 7, hash, (int)hashLen);
  31913. sp_384_from_mp(ctx->u2, 7, rm);
  31914. sp_384_from_mp(ctx->s, 7, sm);
  31915. sp_384_from_mp(ctx->p2.x, 7, pX);
  31916. sp_384_from_mp(ctx->p2.y, 7, pY);
  31917. sp_384_from_mp(ctx->p2.z, 7, pZ);
  31918. ctx->state = 1;
  31919. break;
  31920. case 1: /* NORMS0 */
  31921. sp_384_mul_7(ctx->s, ctx->s, p384_norm_order);
  31922. err = sp_384_mod_7(ctx->s, ctx->s, p384_order);
  31923. if (err == MP_OKAY)
  31924. ctx->state = 2;
  31925. break;
  31926. case 2: /* NORMS1 */
  31927. sp_384_norm_7(ctx->s);
  31928. XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
  31929. ctx->state = 3;
  31930. break;
  31931. case 3: /* NORMS2 */
  31932. err = sp_384_mont_inv_order_7_nb((sp_ecc_ctx_t*)&ctx->mont_inv_order_ctx, ctx->s, ctx->s, ctx->tmp);
  31933. if (err == MP_OKAY) {
  31934. ctx->state = 4;
  31935. }
  31936. break;
  31937. case 4: /* NORMS3 */
  31938. sp_384_mont_mul_order_7(ctx->u1, ctx->u1, ctx->s);
  31939. ctx->state = 5;
  31940. break;
  31941. case 5: /* NORMS4 */
  31942. sp_384_mont_mul_order_7(ctx->u2, ctx->u2, ctx->s);
  31943. XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
  31944. ctx->state = 6;
  31945. break;
  31946. case 6: /* MULBASE */
  31947. err = sp_384_ecc_mulmod_7_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx, &ctx->p1, &p384_base, ctx->u1, 0, 0, heap);
  31948. if (err == MP_OKAY) {
  31949. if (sp_384_iszero_7(ctx->p1.z)) {
  31950. ctx->p1.infinity = 1;
  31951. }
  31952. XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
  31953. ctx->state = 7;
  31954. }
  31955. break;
  31956. case 7: /* MULMOD */
  31957. err = sp_384_ecc_mulmod_7_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx, &ctx->p2, &ctx->p2, ctx->u2, 0, 0, heap);
  31958. if (err == MP_OKAY) {
  31959. if (sp_384_iszero_7(ctx->p2.z)) {
  31960. ctx->p2.infinity = 1;
  31961. }
  31962. XMEMSET(&ctx->add_ctx, 0, sizeof(ctx->add_ctx));
  31963. ctx->state = 8;
  31964. }
  31965. break;
  31966. case 8: /* ADD */
  31967. err = sp_384_proj_point_add_7_nb((sp_ecc_ctx_t*)&ctx->add_ctx, &ctx->p1, &ctx->p1, &ctx->p2, ctx->tmp);
  31968. if (err == MP_OKAY)
  31969. ctx->state = 9;
  31970. break;
  31971. case 9: /* MONT */
  31972. /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
  31973. /* Reload r and convert to Montgomery form. */
  31974. sp_384_from_mp(ctx->u2, 7, rm);
  31975. err = sp_384_mod_mul_norm_7(ctx->u2, ctx->u2, p384_mod);
  31976. if (err == MP_OKAY)
  31977. ctx->state = 10;
  31978. break;
  31979. case 10: /* SQR */
  31980. /* u1 = r.z'.z' mod prime */
  31981. sp_384_mont_sqr_7(ctx->p1.z, ctx->p1.z, p384_mod, p384_mp_mod);
  31982. ctx->state = 11;
  31983. break;
  31984. case 11: /* MUL */
  31985. sp_384_mont_mul_7(ctx->u1, ctx->u2, ctx->p1.z, p384_mod, p384_mp_mod);
  31986. ctx->state = 12;
  31987. break;
  31988. case 12: /* RES */
  31989. {
  31990. sp_int64 c = 0;
  31991. err = MP_OKAY; /* math okay, now check result */
  31992. *res = (int)(sp_384_cmp_7(ctx->p1.x, ctx->u1) == 0);
  31993. if (*res == 0) {
  31994. sp_digit carry;
  31995. /* Reload r and add order. */
  31996. sp_384_from_mp(ctx->u2, 7, rm);
  31997. carry = sp_384_add_7(ctx->u2, ctx->u2, p384_order);
  31998. /* Carry means result is greater than mod and is not valid. */
  31999. if (carry == 0) {
  32000. sp_384_norm_7(ctx->u2);
  32001. /* Compare with mod and if greater or equal then not valid. */
  32002. c = sp_384_cmp_7(ctx->u2, p384_mod);
  32003. }
  32004. }
  32005. if ((*res == 0) && (c < 0)) {
  32006. /* Convert to Montogomery form */
  32007. err = sp_384_mod_mul_norm_7(ctx->u2, ctx->u2, p384_mod);
  32008. if (err == MP_OKAY) {
  32009. /* u1 = (r + 1*order).z'.z' mod prime */
  32010. sp_384_mont_mul_7(ctx->u1, ctx->u2, ctx->p1.z, p384_mod,
  32011. p384_mp_mod);
  32012. *res = (int)(sp_384_cmp_7(ctx->p1.x, ctx->u1) == 0);
  32013. }
  32014. }
  32015. break;
  32016. }
  32017. } /* switch */
  32018. if (err == MP_OKAY && ctx->state != 12) {
  32019. err = FP_WOULDBLOCK;
  32020. }
  32021. return err;
  32022. }
  32023. #endif /* WOLFSSL_SP_NONBLOCK */
  32024. #endif /* HAVE_ECC_VERIFY */
  32025. #ifdef HAVE_ECC_CHECK_KEY
  32026. /* Check that the x and y ordinates are a valid point on the curve.
  32027. *
  32028. * point EC point.
  32029. * heap Heap to use if dynamically allocating.
  32030. * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
  32031. * not on the curve and MP_OKAY otherwise.
  32032. */
  32033. static int sp_384_ecc_is_point_7(const sp_point_384* point,
  32034. void* heap)
  32035. {
  32036. #ifdef WOLFSSL_SP_SMALL_STACK
  32037. sp_digit* t1 = NULL;
  32038. #else
  32039. sp_digit t1[7 * 4];
  32040. #endif
  32041. sp_digit* t2 = NULL;
  32042. int err = MP_OKAY;
  32043. #ifdef WOLFSSL_SP_SMALL_STACK
  32044. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 4, heap, DYNAMIC_TYPE_ECC);
  32045. if (t1 == NULL)
  32046. err = MEMORY_E;
  32047. #endif
  32048. (void)heap;
  32049. if (err == MP_OKAY) {
  32050. t2 = t1 + 2 * 7;
  32051. /* y^2 - x^3 - a.x = b */
  32052. sp_384_sqr_7(t1, point->y);
  32053. (void)sp_384_mod_7(t1, t1, p384_mod);
  32054. sp_384_sqr_7(t2, point->x);
  32055. (void)sp_384_mod_7(t2, t2, p384_mod);
  32056. sp_384_mul_7(t2, t2, point->x);
  32057. (void)sp_384_mod_7(t2, t2, p384_mod);
  32058. sp_384_mont_sub_7(t1, t1, t2, p384_mod);
  32059. /* y^2 - x^3 + 3.x = b, when a = -3 */
  32060. sp_384_mont_add_7(t1, t1, point->x, p384_mod);
  32061. sp_384_mont_add_7(t1, t1, point->x, p384_mod);
  32062. sp_384_mont_add_7(t1, t1, point->x, p384_mod);
  32063. if (sp_384_cmp_7(t1, p384_b) != 0) {
  32064. err = MP_VAL;
  32065. }
  32066. }
  32067. #ifdef WOLFSSL_SP_SMALL_STACK
  32068. if (t1 != NULL)
  32069. XFREE(t1, heap, DYNAMIC_TYPE_ECC);
  32070. #endif
  32071. return err;
  32072. }
  32073. /* Check that the x and y ordinates are a valid point on the curve.
  32074. *
  32075. * pX X ordinate of EC point.
  32076. * pY Y ordinate of EC point.
  32077. * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
  32078. * not on the curve and MP_OKAY otherwise.
  32079. */
  32080. int sp_ecc_is_point_384(const mp_int* pX, const mp_int* pY)
  32081. {
  32082. #ifdef WOLFSSL_SP_SMALL_STACK
  32083. sp_point_384* pub = NULL;
  32084. #else
  32085. sp_point_384 pub[1];
  32086. #endif
  32087. const byte one[1] = { 1 };
  32088. int err = MP_OKAY;
  32089. #ifdef WOLFSSL_SP_SMALL_STACK
  32090. pub = (sp_point_384*)XMALLOC(sizeof(sp_point_384), NULL,
  32091. DYNAMIC_TYPE_ECC);
  32092. if (pub == NULL)
  32093. err = MEMORY_E;
  32094. #endif
  32095. if (err == MP_OKAY) {
  32096. sp_384_from_mp(pub->x, 7, pX);
  32097. sp_384_from_mp(pub->y, 7, pY);
  32098. sp_384_from_bin(pub->z, 7, one, (int)sizeof(one));
  32099. err = sp_384_ecc_is_point_7(pub, NULL);
  32100. }
  32101. #ifdef WOLFSSL_SP_SMALL_STACK
  32102. if (pub != NULL)
  32103. XFREE(pub, NULL, DYNAMIC_TYPE_ECC);
  32104. #endif
  32105. return err;
  32106. }
  32107. /* Check that the private scalar generates the EC point (px, py), the point is
  32108. * on the curve and the point has the correct order.
  32109. *
  32110. * pX X ordinate of EC point.
  32111. * pY Y ordinate of EC point.
  32112. * privm Private scalar that generates EC point.
  32113. * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
  32114. * not on the curve, ECC_INF_E if the point does not have the correct order,
  32115. * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and
  32116. * MP_OKAY otherwise.
  32117. */
  32118. int sp_ecc_check_key_384(const mp_int* pX, const mp_int* pY,
  32119. const mp_int* privm, void* heap)
  32120. {
  32121. #ifdef WOLFSSL_SP_SMALL_STACK
  32122. sp_digit* priv = NULL;
  32123. sp_point_384* pub = NULL;
  32124. #else
  32125. sp_digit priv[7];
  32126. sp_point_384 pub[2];
  32127. #endif
  32128. sp_point_384* p = NULL;
  32129. const byte one[1] = { 1 };
  32130. int err = MP_OKAY;
  32131. /* Quick check the lengs of public key ordinates and private key are in
  32132. * range. Proper check later.
  32133. */
  32134. if (((mp_count_bits(pX) > 384) ||
  32135. (mp_count_bits(pY) > 384) ||
  32136. ((privm != NULL) && (mp_count_bits(privm) > 384)))) {
  32137. err = ECC_OUT_OF_RANGE_E;
  32138. }
  32139. #ifdef WOLFSSL_SP_SMALL_STACK
  32140. if (err == MP_OKAY) {
  32141. pub = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 2, heap,
  32142. DYNAMIC_TYPE_ECC);
  32143. if (pub == NULL)
  32144. err = MEMORY_E;
  32145. }
  32146. if (err == MP_OKAY && privm) {
  32147. priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap,
  32148. DYNAMIC_TYPE_ECC);
  32149. if (priv == NULL)
  32150. err = MEMORY_E;
  32151. }
  32152. #endif
  32153. if (err == MP_OKAY) {
  32154. p = pub + 1;
  32155. sp_384_from_mp(pub->x, 7, pX);
  32156. sp_384_from_mp(pub->y, 7, pY);
  32157. sp_384_from_bin(pub->z, 7, one, (int)sizeof(one));
  32158. if (privm)
  32159. sp_384_from_mp(priv, 7, privm);
  32160. /* Check point at infinitiy. */
  32161. if ((sp_384_iszero_7(pub->x) != 0) &&
  32162. (sp_384_iszero_7(pub->y) != 0)) {
  32163. err = ECC_INF_E;
  32164. }
  32165. }
  32166. /* Check range of X and Y */
  32167. if ((err == MP_OKAY) &&
  32168. ((sp_384_cmp_7(pub->x, p384_mod) >= 0) ||
  32169. (sp_384_cmp_7(pub->y, p384_mod) >= 0))) {
  32170. err = ECC_OUT_OF_RANGE_E;
  32171. }
  32172. if (err == MP_OKAY) {
  32173. /* Check point is on curve */
  32174. err = sp_384_ecc_is_point_7(pub, heap);
  32175. }
  32176. if (err == MP_OKAY) {
  32177. /* Point * order = infinity */
  32178. err = sp_384_ecc_mulmod_7(p, pub, p384_order, 1, 1, heap);
  32179. }
  32180. /* Check result is infinity */
  32181. if ((err == MP_OKAY) && ((sp_384_iszero_7(p->x) == 0) ||
  32182. (sp_384_iszero_7(p->y) == 0))) {
  32183. err = ECC_INF_E;
  32184. }
  32185. if (privm) {
  32186. if (err == MP_OKAY) {
  32187. /* Base * private = point */
  32188. err = sp_384_ecc_mulmod_base_7(p, priv, 1, 1, heap);
  32189. }
  32190. /* Check result is public key */
  32191. if ((err == MP_OKAY) &&
  32192. ((sp_384_cmp_7(p->x, pub->x) != 0) ||
  32193. (sp_384_cmp_7(p->y, pub->y) != 0))) {
  32194. err = ECC_PRIV_KEY_E;
  32195. }
  32196. }
  32197. #ifdef WOLFSSL_SP_SMALL_STACK
  32198. if (pub != NULL)
  32199. XFREE(pub, heap, DYNAMIC_TYPE_ECC);
  32200. if (priv != NULL)
  32201. XFREE(priv, heap, DYNAMIC_TYPE_ECC);
  32202. #endif
  32203. return err;
  32204. }
  32205. #endif
  32206. #ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL
  32207. /* Add two projective EC points together.
  32208. * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)
  32209. *
  32210. * pX First EC point's X ordinate.
  32211. * pY First EC point's Y ordinate.
  32212. * pZ First EC point's Z ordinate.
  32213. * qX Second EC point's X ordinate.
  32214. * qY Second EC point's Y ordinate.
  32215. * qZ Second EC point's Z ordinate.
  32216. * rX Resultant EC point's X ordinate.
  32217. * rY Resultant EC point's Y ordinate.
  32218. * rZ Resultant EC point's Z ordinate.
  32219. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  32220. */
  32221. int sp_ecc_proj_add_point_384(mp_int* pX, mp_int* pY, mp_int* pZ,
  32222. mp_int* qX, mp_int* qY, mp_int* qZ,
  32223. mp_int* rX, mp_int* rY, mp_int* rZ)
  32224. {
  32225. #ifdef WOLFSSL_SP_SMALL_STACK
  32226. sp_digit* tmp = NULL;
  32227. sp_point_384* p = NULL;
  32228. #else
  32229. sp_digit tmp[2 * 7 * 6];
  32230. sp_point_384 p[2];
  32231. #endif
  32232. sp_point_384* q = NULL;
  32233. int err = MP_OKAY;
  32234. #ifdef WOLFSSL_SP_SMALL_STACK
  32235. if (err == MP_OKAY) {
  32236. p = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 2, NULL,
  32237. DYNAMIC_TYPE_ECC);
  32238. if (p == NULL)
  32239. err = MEMORY_E;
  32240. }
  32241. if (err == MP_OKAY) {
  32242. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 6, NULL,
  32243. DYNAMIC_TYPE_ECC);
  32244. if (tmp == NULL) {
  32245. err = MEMORY_E;
  32246. }
  32247. }
  32248. #endif
  32249. if (err == MP_OKAY) {
  32250. q = p + 1;
  32251. sp_384_from_mp(p->x, 7, pX);
  32252. sp_384_from_mp(p->y, 7, pY);
  32253. sp_384_from_mp(p->z, 7, pZ);
  32254. sp_384_from_mp(q->x, 7, qX);
  32255. sp_384_from_mp(q->y, 7, qY);
  32256. sp_384_from_mp(q->z, 7, qZ);
  32257. p->infinity = sp_384_iszero_7(p->x) &
  32258. sp_384_iszero_7(p->y);
  32259. q->infinity = sp_384_iszero_7(q->x) &
  32260. sp_384_iszero_7(q->y);
  32261. sp_384_proj_point_add_7(p, p, q, tmp);
  32262. }
  32263. if (err == MP_OKAY) {
  32264. err = sp_384_to_mp(p->x, rX);
  32265. }
  32266. if (err == MP_OKAY) {
  32267. err = sp_384_to_mp(p->y, rY);
  32268. }
  32269. if (err == MP_OKAY) {
  32270. err = sp_384_to_mp(p->z, rZ);
  32271. }
  32272. #ifdef WOLFSSL_SP_SMALL_STACK
  32273. if (tmp != NULL)
  32274. XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
  32275. if (p != NULL)
  32276. XFREE(p, NULL, DYNAMIC_TYPE_ECC);
  32277. #endif
  32278. return err;
  32279. }
  32280. /* Double a projective EC point.
  32281. * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)
  32282. *
  32283. * pX EC point's X ordinate.
  32284. * pY EC point's Y ordinate.
  32285. * pZ EC point's Z ordinate.
  32286. * rX Resultant EC point's X ordinate.
  32287. * rY Resultant EC point's Y ordinate.
  32288. * rZ Resultant EC point's Z ordinate.
  32289. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  32290. */
  32291. int sp_ecc_proj_dbl_point_384(mp_int* pX, mp_int* pY, mp_int* pZ,
  32292. mp_int* rX, mp_int* rY, mp_int* rZ)
  32293. {
  32294. #ifdef WOLFSSL_SP_SMALL_STACK
  32295. sp_digit* tmp = NULL;
  32296. sp_point_384* p = NULL;
  32297. #else
  32298. sp_digit tmp[2 * 7 * 2];
  32299. sp_point_384 p[1];
  32300. #endif
  32301. int err = MP_OKAY;
  32302. #ifdef WOLFSSL_SP_SMALL_STACK
  32303. if (err == MP_OKAY) {
  32304. p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), NULL,
  32305. DYNAMIC_TYPE_ECC);
  32306. if (p == NULL)
  32307. err = MEMORY_E;
  32308. }
  32309. if (err == MP_OKAY) {
  32310. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 2, NULL,
  32311. DYNAMIC_TYPE_ECC);
  32312. if (tmp == NULL)
  32313. err = MEMORY_E;
  32314. }
  32315. #endif
  32316. if (err == MP_OKAY) {
  32317. sp_384_from_mp(p->x, 7, pX);
  32318. sp_384_from_mp(p->y, 7, pY);
  32319. sp_384_from_mp(p->z, 7, pZ);
  32320. p->infinity = sp_384_iszero_7(p->x) &
  32321. sp_384_iszero_7(p->y);
  32322. sp_384_proj_point_dbl_7(p, p, tmp);
  32323. }
  32324. if (err == MP_OKAY) {
  32325. err = sp_384_to_mp(p->x, rX);
  32326. }
  32327. if (err == MP_OKAY) {
  32328. err = sp_384_to_mp(p->y, rY);
  32329. }
  32330. if (err == MP_OKAY) {
  32331. err = sp_384_to_mp(p->z, rZ);
  32332. }
  32333. #ifdef WOLFSSL_SP_SMALL_STACK
  32334. if (tmp != NULL)
  32335. XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
  32336. if (p != NULL)
  32337. XFREE(p, NULL, DYNAMIC_TYPE_ECC);
  32338. #endif
  32339. return err;
  32340. }
  32341. /* Map a projective EC point to affine in place.
  32342. * pZ will be one.
  32343. *
  32344. * pX EC point's X ordinate.
  32345. * pY EC point's Y ordinate.
  32346. * pZ EC point's Z ordinate.
  32347. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  32348. */
  32349. int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ)
  32350. {
  32351. #ifdef WOLFSSL_SP_SMALL_STACK
  32352. sp_digit* tmp = NULL;
  32353. sp_point_384* p = NULL;
  32354. #else
  32355. sp_digit tmp[2 * 7 * 6];
  32356. sp_point_384 p[1];
  32357. #endif
  32358. int err = MP_OKAY;
  32359. #ifdef WOLFSSL_SP_SMALL_STACK
  32360. if (err == MP_OKAY) {
  32361. p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), NULL,
  32362. DYNAMIC_TYPE_ECC);
  32363. if (p == NULL)
  32364. err = MEMORY_E;
  32365. }
  32366. if (err == MP_OKAY) {
  32367. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 6, NULL,
  32368. DYNAMIC_TYPE_ECC);
  32369. if (tmp == NULL)
  32370. err = MEMORY_E;
  32371. }
  32372. #endif
  32373. if (err == MP_OKAY) {
  32374. sp_384_from_mp(p->x, 7, pX);
  32375. sp_384_from_mp(p->y, 7, pY);
  32376. sp_384_from_mp(p->z, 7, pZ);
  32377. p->infinity = sp_384_iszero_7(p->x) &
  32378. sp_384_iszero_7(p->y);
  32379. sp_384_map_7(p, p, tmp);
  32380. }
  32381. if (err == MP_OKAY) {
  32382. err = sp_384_to_mp(p->x, pX);
  32383. }
  32384. if (err == MP_OKAY) {
  32385. err = sp_384_to_mp(p->y, pY);
  32386. }
  32387. if (err == MP_OKAY) {
  32388. err = sp_384_to_mp(p->z, pZ);
  32389. }
  32390. #ifdef WOLFSSL_SP_SMALL_STACK
  32391. if (tmp != NULL)
  32392. XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
  32393. if (p != NULL)
  32394. XFREE(p, NULL, DYNAMIC_TYPE_ECC);
  32395. #endif
  32396. return err;
  32397. }
  32398. #endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */
  32399. #ifdef HAVE_COMP_KEY
  32400. /* Find the square root of a number mod the prime of the curve.
  32401. *
  32402. * y The number to operate on and the result.
  32403. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  32404. */
  32405. static int sp_384_mont_sqrt_7(sp_digit* y)
  32406. {
  32407. #ifdef WOLFSSL_SP_SMALL_STACK
  32408. sp_digit* t1 = NULL;
  32409. #else
  32410. sp_digit t1[5 * 2 * 7];
  32411. #endif
  32412. sp_digit* t2 = NULL;
  32413. sp_digit* t3 = NULL;
  32414. sp_digit* t4 = NULL;
  32415. sp_digit* t5 = NULL;
  32416. int err = MP_OKAY;
  32417. #ifdef WOLFSSL_SP_SMALL_STACK
  32418. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 2 * 7, NULL, DYNAMIC_TYPE_ECC);
  32419. if (t1 == NULL)
  32420. err = MEMORY_E;
  32421. #endif
  32422. if (err == MP_OKAY) {
  32423. t2 = t1 + 2 * 7;
  32424. t3 = t1 + 4 * 7;
  32425. t4 = t1 + 6 * 7;
  32426. t5 = t1 + 8 * 7;
  32427. {
  32428. /* t2 = y ^ 0x2 */
  32429. sp_384_mont_sqr_7(t2, y, p384_mod, p384_mp_mod);
  32430. /* t1 = y ^ 0x3 */
  32431. sp_384_mont_mul_7(t1, t2, y, p384_mod, p384_mp_mod);
  32432. /* t5 = y ^ 0xc */
  32433. sp_384_mont_sqr_n_7(t5, t1, 2, p384_mod, p384_mp_mod);
  32434. /* t1 = y ^ 0xf */
  32435. sp_384_mont_mul_7(t1, t1, t5, p384_mod, p384_mp_mod);
  32436. /* t2 = y ^ 0x1e */
  32437. sp_384_mont_sqr_7(t2, t1, p384_mod, p384_mp_mod);
  32438. /* t3 = y ^ 0x1f */
  32439. sp_384_mont_mul_7(t3, t2, y, p384_mod, p384_mp_mod);
  32440. /* t2 = y ^ 0x3e0 */
  32441. sp_384_mont_sqr_n_7(t2, t3, 5, p384_mod, p384_mp_mod);
  32442. /* t1 = y ^ 0x3ff */
  32443. sp_384_mont_mul_7(t1, t3, t2, p384_mod, p384_mp_mod);
  32444. /* t2 = y ^ 0x7fe0 */
  32445. sp_384_mont_sqr_n_7(t2, t1, 5, p384_mod, p384_mp_mod);
  32446. /* t3 = y ^ 0x7fff */
  32447. sp_384_mont_mul_7(t3, t3, t2, p384_mod, p384_mp_mod);
  32448. /* t2 = y ^ 0x3fff800 */
  32449. sp_384_mont_sqr_n_7(t2, t3, 15, p384_mod, p384_mp_mod);
  32450. /* t4 = y ^ 0x3ffffff */
  32451. sp_384_mont_mul_7(t4, t3, t2, p384_mod, p384_mp_mod);
  32452. /* t2 = y ^ 0xffffffc000000 */
  32453. sp_384_mont_sqr_n_7(t2, t4, 30, p384_mod, p384_mp_mod);
  32454. /* t1 = y ^ 0xfffffffffffff */
  32455. sp_384_mont_mul_7(t1, t4, t2, p384_mod, p384_mp_mod);
  32456. /* t2 = y ^ 0xfffffffffffffff000000000000000 */
  32457. sp_384_mont_sqr_n_7(t2, t1, 60, p384_mod, p384_mp_mod);
  32458. /* t1 = y ^ 0xffffffffffffffffffffffffffffff */
  32459. sp_384_mont_mul_7(t1, t1, t2, p384_mod, p384_mp_mod);
  32460. /* t2 = y ^ 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */
  32461. sp_384_mont_sqr_n_7(t2, t1, 120, p384_mod, p384_mp_mod);
  32462. /* t1 = y ^ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
  32463. sp_384_mont_mul_7(t1, t1, t2, p384_mod, p384_mp_mod);
  32464. /* t2 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */
  32465. sp_384_mont_sqr_n_7(t2, t1, 15, p384_mod, p384_mp_mod);
  32466. /* t1 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
  32467. sp_384_mont_mul_7(t1, t3, t2, p384_mod, p384_mp_mod);
  32468. /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 */
  32469. sp_384_mont_sqr_n_7(t2, t1, 31, p384_mod, p384_mp_mod);
  32470. /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff */
  32471. sp_384_mont_mul_7(t1, t4, t2, p384_mod, p384_mp_mod);
  32472. /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff0 */
  32473. sp_384_mont_sqr_n_7(t2, t1, 4, p384_mod, p384_mp_mod);
  32474. /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc */
  32475. sp_384_mont_mul_7(t1, t5, t2, p384_mod, p384_mp_mod);
  32476. /* t2 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000 */
  32477. sp_384_mont_sqr_n_7(t2, t1, 62, p384_mod, p384_mp_mod);
  32478. /* t1 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000001 */
  32479. sp_384_mont_mul_7(t1, y, t2, p384_mod, p384_mp_mod);
  32480. /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc00000000000000040000000 */
  32481. sp_384_mont_sqr_n_7(y, t1, 30, p384_mod, p384_mp_mod);
  32482. }
  32483. }
  32484. #ifdef WOLFSSL_SP_SMALL_STACK
  32485. if (t1 != NULL)
  32486. XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
  32487. #endif
  32488. return err;
  32489. }
  32490. /* Uncompress the point given the X ordinate.
  32491. *
  32492. * xm X ordinate.
  32493. * odd Whether the Y ordinate is odd.
  32494. * ym Calculated Y ordinate.
  32495. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  32496. */
  32497. int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym)
  32498. {
  32499. #ifdef WOLFSSL_SP_SMALL_STACK
  32500. sp_digit* x = NULL;
  32501. #else
  32502. sp_digit x[4 * 7];
  32503. #endif
  32504. sp_digit* y = NULL;
  32505. int err = MP_OKAY;
  32506. #ifdef WOLFSSL_SP_SMALL_STACK
  32507. x = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 7, NULL, DYNAMIC_TYPE_ECC);
  32508. if (x == NULL)
  32509. err = MEMORY_E;
  32510. #endif
  32511. if (err == MP_OKAY) {
  32512. y = x + 2 * 7;
  32513. sp_384_from_mp(x, 7, xm);
  32514. err = sp_384_mod_mul_norm_7(x, x, p384_mod);
  32515. }
  32516. if (err == MP_OKAY) {
  32517. /* y = x^3 */
  32518. {
  32519. sp_384_mont_sqr_7(y, x, p384_mod, p384_mp_mod);
  32520. sp_384_mont_mul_7(y, y, x, p384_mod, p384_mp_mod);
  32521. }
  32522. /* y = x^3 - 3x */
  32523. sp_384_mont_sub_7(y, y, x, p384_mod);
  32524. sp_384_mont_sub_7(y, y, x, p384_mod);
  32525. sp_384_mont_sub_7(y, y, x, p384_mod);
  32526. /* y = x^3 - 3x + b */
  32527. err = sp_384_mod_mul_norm_7(x, p384_b, p384_mod);
  32528. }
  32529. if (err == MP_OKAY) {
  32530. sp_384_mont_add_7(y, y, x, p384_mod);
  32531. /* y = sqrt(x^3 - 3x + b) */
  32532. err = sp_384_mont_sqrt_7(y);
  32533. }
  32534. if (err == MP_OKAY) {
  32535. XMEMSET(y + 7, 0, 7U * sizeof(sp_digit));
  32536. sp_384_mont_reduce_7(y, p384_mod, p384_mp_mod);
  32537. if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) {
  32538. sp_384_mont_sub_7(y, p384_mod, y, p384_mod);
  32539. }
  32540. err = sp_384_to_mp(y, ym);
  32541. }
  32542. #ifdef WOLFSSL_SP_SMALL_STACK
  32543. if (x != NULL)
  32544. XFREE(x, NULL, DYNAMIC_TYPE_ECC);
  32545. #endif
  32546. return err;
  32547. }
  32548. #endif
  32549. #endif /* WOLFSSL_SP_384 */
  32550. #ifdef WOLFSSL_SP_521
  32551. /* Point structure to use. */
  32552. typedef struct sp_point_521 {
  32553. /* X ordinate of point. */
  32554. sp_digit x[2 * 9];
  32555. /* Y ordinate of point. */
  32556. sp_digit y[2 * 9];
  32557. /* Z ordinate of point. */
  32558. sp_digit z[2 * 9];
  32559. /* Indicates point is at infinity. */
  32560. int infinity;
  32561. } sp_point_521;
  32562. /* The modulus (prime) of the curve P521. */
  32563. static const sp_digit p521_mod[9] = {
  32564. 0x3ffffffffffffffL,0x3ffffffffffffffL,0x3ffffffffffffffL,0x3ffffffffffffffL,
  32565. 0x3ffffffffffffffL,0x3ffffffffffffffL,0x3ffffffffffffffL,0x3ffffffffffffffL,
  32566. 0x1ffffffffffffffL
  32567. };
  32568. /* The Montgomery normalizer for modulus of the curve P521. */
  32569. static const sp_digit p521_norm_mod[9] = {
  32570. 0x000000000000001L,0x000000000000000L,0x000000000000000L,0x000000000000000L,
  32571. 0x000000000000000L,0x000000000000000L,0x000000000000000L,0x000000000000000L,
  32572. 0x000000000000000L
  32573. };
  32574. /* The Montgomery multiplier for modulus of the curve P521. */
  32575. static sp_digit p521_mp_mod = 0x00000000000001;
  32576. #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
  32577. defined(HAVE_ECC_VERIFY)
  32578. /* The order of the curve P521. */
  32579. static const sp_digit p521_order[9] = {
  32580. 0x36fb71e91386409L,0x1726e226711ebaeL,0x0148f709a5d03bbL,0x20efcbe59adff30L,
  32581. 0x3fffffffa518687L,0x3ffffffffffffffL,0x3ffffffffffffffL,0x3ffffffffffffffL,
  32582. 0x1ffffffffffffffL
  32583. };
  32584. #endif
  32585. /* The order of the curve P521 minus 2. */
  32586. static const sp_digit p521_order2[9] = {
  32587. 0x36fb71e91386407L,0x1726e226711ebaeL,0x0148f709a5d03bbL,0x20efcbe59adff30L,
  32588. 0x3fffffffa518687L,0x3ffffffffffffffL,0x3ffffffffffffffL,0x3ffffffffffffffL,
  32589. 0x1ffffffffffffffL
  32590. };
  32591. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  32592. /* The Montgomery normalizer for order of the curve P521. */
  32593. static const sp_digit p521_norm_order[9] = {
  32594. 0x09048e16ec79bf7L,0x28d91dd98ee1451L,0x3eb708f65a2fc44L,0x1f10341a65200cfL,
  32595. 0x000000005ae7978L,0x000000000000000L,0x000000000000000L,0x000000000000000L,
  32596. 0x000000000000000L
  32597. };
  32598. #endif
  32599. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  32600. /* The Montgomery multiplier for order of the curve P521. */
  32601. static sp_digit p521_mp_order = 0x12f5ccd79a995c7L;
  32602. #endif
  32603. /* The base point of curve P521. */
  32604. static const sp_point_521 p521_base = {
  32605. /* X ordinate */
  32606. {
  32607. 0x17e7e31c2e5bd66L,0x22cf0615a90a6feL,0x0127a2ffa8de334L,
  32608. 0x1dfbf9d64a3f877L,0x06b4d3dbaa14b5eL,0x14fed487e0a2bd8L,
  32609. 0x15b4429c6481390L,0x3a73678fb2d988eL,0x0c6858e06b70404L,
  32610. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  32611. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0
  32612. },
  32613. /* Y ordinate */
  32614. {
  32615. 0x0be94769fd16650L,0x31c21a89cb09022L,0x39013fad0761353L,
  32616. 0x2657bd099031542L,0x3273e662c97ee72L,0x1e6d11a05ebef45L,
  32617. 0x3d1bd998f544495L,0x3001172297ed0b1L,0x11839296a789a3bL,
  32618. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  32619. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0
  32620. },
  32621. /* Z ordinate */
  32622. {
  32623. 0x000000000000001L,0x000000000000000L,0x000000000000000L,
  32624. 0x000000000000000L,0x000000000000000L,0x000000000000000L,
  32625. 0x000000000000000L,0x000000000000000L,0x000000000000000L,
  32626. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  32627. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0
  32628. },
  32629. /* infinity */
  32630. 0
  32631. };
  32632. #if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)
  32633. static const sp_digit p521_b[9] = {
  32634. 0x3451fd46b503f00L,0x0f7e20f4b0d3c7bL,0x00bd3bb1bf07357L,0x147b1fa4dec594bL,
  32635. 0x18ef109e1561939L,0x26cc57cee2d2264L,0x0540eea2da725b9L,0x2687e4a688682daL,
  32636. 0x051953eb9618e1cL
  32637. };
  32638. #endif
  32639. #ifdef WOLFSSL_SP_SMALL
  32640. /* Multiply a and b into r. (r = a * b)
  32641. *
  32642. * r A single precision integer.
  32643. * a A single precision integer.
  32644. * b A single precision integer.
  32645. */
  32646. SP_NOINLINE static void sp_521_mul_9(sp_digit* r, const sp_digit* a,
  32647. const sp_digit* b)
  32648. {
  32649. int i;
  32650. int imax;
  32651. int k;
  32652. sp_uint128 c;
  32653. sp_uint128 lo;
  32654. c = ((sp_uint128)a[8]) * b[8];
  32655. r[17] = (sp_digit)(c >> 58);
  32656. c &= 0x3ffffffffffffffL;
  32657. for (k = 15; k >= 0; k--) {
  32658. if (k >= 9) {
  32659. i = k - 8;
  32660. imax = 8;
  32661. }
  32662. else {
  32663. i = 0;
  32664. imax = k;
  32665. }
  32666. lo = 0;
  32667. for (; i <= imax; i++) {
  32668. lo += ((sp_uint128)a[i]) * b[k - i];
  32669. }
  32670. c += lo >> 58;
  32671. r[k + 2] += (sp_digit)(c >> 58);
  32672. r[k + 1] = (sp_digit)(c & 0x3ffffffffffffffL);
  32673. c = lo & 0x3ffffffffffffffL;
  32674. }
  32675. r[0] = (sp_digit)c;
  32676. }
  32677. #else
  32678. /* Multiply a and b into r. (r = a * b)
  32679. *
  32680. * r A single precision integer.
  32681. * a A single precision integer.
  32682. * b A single precision integer.
  32683. */
  32684. SP_NOINLINE static void sp_521_mul_9(sp_digit* r, const sp_digit* a,
  32685. const sp_digit* b)
  32686. {
  32687. sp_int128 t0;
  32688. sp_int128 t1;
  32689. sp_digit t[9];
  32690. t0 = ((sp_int128)a[ 0]) * b[ 0];
  32691. t1 = ((sp_int128)a[ 0]) * b[ 1]
  32692. + ((sp_int128)a[ 1]) * b[ 0];
  32693. t[ 0] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32694. t0 = ((sp_int128)a[ 0]) * b[ 2]
  32695. + ((sp_int128)a[ 1]) * b[ 1]
  32696. + ((sp_int128)a[ 2]) * b[ 0];
  32697. t[ 1] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32698. t1 = ((sp_int128)a[ 0]) * b[ 3]
  32699. + ((sp_int128)a[ 1]) * b[ 2]
  32700. + ((sp_int128)a[ 2]) * b[ 1]
  32701. + ((sp_int128)a[ 3]) * b[ 0];
  32702. t[ 2] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32703. t0 = ((sp_int128)a[ 0]) * b[ 4]
  32704. + ((sp_int128)a[ 1]) * b[ 3]
  32705. + ((sp_int128)a[ 2]) * b[ 2]
  32706. + ((sp_int128)a[ 3]) * b[ 1]
  32707. + ((sp_int128)a[ 4]) * b[ 0];
  32708. t[ 3] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32709. t1 = ((sp_int128)a[ 0]) * b[ 5]
  32710. + ((sp_int128)a[ 1]) * b[ 4]
  32711. + ((sp_int128)a[ 2]) * b[ 3]
  32712. + ((sp_int128)a[ 3]) * b[ 2]
  32713. + ((sp_int128)a[ 4]) * b[ 1]
  32714. + ((sp_int128)a[ 5]) * b[ 0];
  32715. t[ 4] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32716. t0 = ((sp_int128)a[ 0]) * b[ 6]
  32717. + ((sp_int128)a[ 1]) * b[ 5]
  32718. + ((sp_int128)a[ 2]) * b[ 4]
  32719. + ((sp_int128)a[ 3]) * b[ 3]
  32720. + ((sp_int128)a[ 4]) * b[ 2]
  32721. + ((sp_int128)a[ 5]) * b[ 1]
  32722. + ((sp_int128)a[ 6]) * b[ 0];
  32723. t[ 5] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32724. t1 = ((sp_int128)a[ 0]) * b[ 7]
  32725. + ((sp_int128)a[ 1]) * b[ 6]
  32726. + ((sp_int128)a[ 2]) * b[ 5]
  32727. + ((sp_int128)a[ 3]) * b[ 4]
  32728. + ((sp_int128)a[ 4]) * b[ 3]
  32729. + ((sp_int128)a[ 5]) * b[ 2]
  32730. + ((sp_int128)a[ 6]) * b[ 1]
  32731. + ((sp_int128)a[ 7]) * b[ 0];
  32732. t[ 6] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32733. t0 = ((sp_int128)a[ 0]) * b[ 8]
  32734. + ((sp_int128)a[ 1]) * b[ 7]
  32735. + ((sp_int128)a[ 2]) * b[ 6]
  32736. + ((sp_int128)a[ 3]) * b[ 5]
  32737. + ((sp_int128)a[ 4]) * b[ 4]
  32738. + ((sp_int128)a[ 5]) * b[ 3]
  32739. + ((sp_int128)a[ 6]) * b[ 2]
  32740. + ((sp_int128)a[ 7]) * b[ 1]
  32741. + ((sp_int128)a[ 8]) * b[ 0];
  32742. t[ 7] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32743. t1 = ((sp_int128)a[ 1]) * b[ 8]
  32744. + ((sp_int128)a[ 2]) * b[ 7]
  32745. + ((sp_int128)a[ 3]) * b[ 6]
  32746. + ((sp_int128)a[ 4]) * b[ 5]
  32747. + ((sp_int128)a[ 5]) * b[ 4]
  32748. + ((sp_int128)a[ 6]) * b[ 3]
  32749. + ((sp_int128)a[ 7]) * b[ 2]
  32750. + ((sp_int128)a[ 8]) * b[ 1];
  32751. t[ 8] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32752. t0 = ((sp_int128)a[ 2]) * b[ 8]
  32753. + ((sp_int128)a[ 3]) * b[ 7]
  32754. + ((sp_int128)a[ 4]) * b[ 6]
  32755. + ((sp_int128)a[ 5]) * b[ 5]
  32756. + ((sp_int128)a[ 6]) * b[ 4]
  32757. + ((sp_int128)a[ 7]) * b[ 3]
  32758. + ((sp_int128)a[ 8]) * b[ 2];
  32759. r[ 9] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32760. t1 = ((sp_int128)a[ 3]) * b[ 8]
  32761. + ((sp_int128)a[ 4]) * b[ 7]
  32762. + ((sp_int128)a[ 5]) * b[ 6]
  32763. + ((sp_int128)a[ 6]) * b[ 5]
  32764. + ((sp_int128)a[ 7]) * b[ 4]
  32765. + ((sp_int128)a[ 8]) * b[ 3];
  32766. r[10] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32767. t0 = ((sp_int128)a[ 4]) * b[ 8]
  32768. + ((sp_int128)a[ 5]) * b[ 7]
  32769. + ((sp_int128)a[ 6]) * b[ 6]
  32770. + ((sp_int128)a[ 7]) * b[ 5]
  32771. + ((sp_int128)a[ 8]) * b[ 4];
  32772. r[11] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32773. t1 = ((sp_int128)a[ 5]) * b[ 8]
  32774. + ((sp_int128)a[ 6]) * b[ 7]
  32775. + ((sp_int128)a[ 7]) * b[ 6]
  32776. + ((sp_int128)a[ 8]) * b[ 5];
  32777. r[12] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32778. t0 = ((sp_int128)a[ 6]) * b[ 8]
  32779. + ((sp_int128)a[ 7]) * b[ 7]
  32780. + ((sp_int128)a[ 8]) * b[ 6];
  32781. r[13] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32782. t1 = ((sp_int128)a[ 7]) * b[ 8]
  32783. + ((sp_int128)a[ 8]) * b[ 7];
  32784. r[14] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32785. t0 = ((sp_int128)a[ 8]) * b[ 8];
  32786. r[15] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32787. r[16] = t0 & 0x3ffffffffffffffL;
  32788. r[17] = (sp_digit)(t0 >> 58);
  32789. XMEMCPY(r, t, sizeof(t));
  32790. }
  32791. #endif /* WOLFSSL_SP_SMALL */
  32792. #ifdef WOLFSSL_SP_SMALL
  32793. /* Square a and put result in r. (r = a * a)
  32794. *
  32795. * r A single precision integer.
  32796. * a A single precision integer.
  32797. */
  32798. SP_NOINLINE static void sp_521_sqr_9(sp_digit* r, const sp_digit* a)
  32799. {
  32800. int i;
  32801. int imax;
  32802. int k;
  32803. sp_uint128 c;
  32804. sp_uint128 t;
  32805. c = ((sp_uint128)a[8]) * a[8];
  32806. r[17] = (sp_digit)(c >> 58);
  32807. c = (c & 0x3ffffffffffffffL) << 58;
  32808. for (k = 15; k >= 0; k--) {
  32809. i = (k + 1) / 2;
  32810. if ((k & 1) == 0) {
  32811. c += ((sp_uint128)a[i]) * a[i];
  32812. i++;
  32813. }
  32814. if (k < 8) {
  32815. imax = k;
  32816. }
  32817. else {
  32818. imax = 8;
  32819. }
  32820. t = 0;
  32821. for (; i <= imax; i++) {
  32822. t += ((sp_uint128)a[i]) * a[k - i];
  32823. }
  32824. c += t * 2;
  32825. r[k + 2] += (sp_digit) (c >> 116);
  32826. r[k + 1] = (sp_digit)((c >> 58) & 0x3ffffffffffffffL);
  32827. c = (c & 0x3ffffffffffffffL) << 58;
  32828. }
  32829. r[0] = (sp_digit)(c >> 58);
  32830. }
  32831. #else
  32832. /* Square a and put result in r. (r = a * a)
  32833. *
  32834. * r A single precision integer.
  32835. * a A single precision integer.
  32836. */
  32837. SP_NOINLINE static void sp_521_sqr_9(sp_digit* r, const sp_digit* a)
  32838. {
  32839. sp_int128 t0;
  32840. sp_int128 t1;
  32841. sp_digit t[9];
  32842. t0 = ((sp_int128)a[ 0]) * a[ 0];
  32843. t1 = (((sp_int128)a[ 0]) * a[ 1]) * 2;
  32844. t[ 0] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32845. t0 = (((sp_int128)a[ 0]) * a[ 2]) * 2
  32846. + ((sp_int128)a[ 1]) * a[ 1];
  32847. t[ 1] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32848. t1 = (((sp_int128)a[ 0]) * a[ 3]
  32849. + ((sp_int128)a[ 1]) * a[ 2]) * 2;
  32850. t[ 2] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32851. t0 = (((sp_int128)a[ 0]) * a[ 4]
  32852. + ((sp_int128)a[ 1]) * a[ 3]) * 2
  32853. + ((sp_int128)a[ 2]) * a[ 2];
  32854. t[ 3] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32855. t1 = (((sp_int128)a[ 0]) * a[ 5]
  32856. + ((sp_int128)a[ 1]) * a[ 4]
  32857. + ((sp_int128)a[ 2]) * a[ 3]) * 2;
  32858. t[ 4] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32859. t0 = (((sp_int128)a[ 0]) * a[ 6]
  32860. + ((sp_int128)a[ 1]) * a[ 5]
  32861. + ((sp_int128)a[ 2]) * a[ 4]) * 2
  32862. + ((sp_int128)a[ 3]) * a[ 3];
  32863. t[ 5] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32864. t1 = (((sp_int128)a[ 0]) * a[ 7]
  32865. + ((sp_int128)a[ 1]) * a[ 6]
  32866. + ((sp_int128)a[ 2]) * a[ 5]
  32867. + ((sp_int128)a[ 3]) * a[ 4]) * 2;
  32868. t[ 6] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32869. t0 = (((sp_int128)a[ 0]) * a[ 8]
  32870. + ((sp_int128)a[ 1]) * a[ 7]
  32871. + ((sp_int128)a[ 2]) * a[ 6]
  32872. + ((sp_int128)a[ 3]) * a[ 5]) * 2
  32873. + ((sp_int128)a[ 4]) * a[ 4];
  32874. t[ 7] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32875. t1 = (((sp_int128)a[ 1]) * a[ 8]
  32876. + ((sp_int128)a[ 2]) * a[ 7]
  32877. + ((sp_int128)a[ 3]) * a[ 6]
  32878. + ((sp_int128)a[ 4]) * a[ 5]) * 2;
  32879. t[ 8] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32880. t0 = (((sp_int128)a[ 2]) * a[ 8]
  32881. + ((sp_int128)a[ 3]) * a[ 7]
  32882. + ((sp_int128)a[ 4]) * a[ 6]) * 2
  32883. + ((sp_int128)a[ 5]) * a[ 5];
  32884. r[ 9] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32885. t1 = (((sp_int128)a[ 3]) * a[ 8]
  32886. + ((sp_int128)a[ 4]) * a[ 7]
  32887. + ((sp_int128)a[ 5]) * a[ 6]) * 2;
  32888. r[10] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32889. t0 = (((sp_int128)a[ 4]) * a[ 8]
  32890. + ((sp_int128)a[ 5]) * a[ 7]) * 2
  32891. + ((sp_int128)a[ 6]) * a[ 6];
  32892. r[11] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32893. t1 = (((sp_int128)a[ 5]) * a[ 8]
  32894. + ((sp_int128)a[ 6]) * a[ 7]) * 2;
  32895. r[12] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32896. t0 = (((sp_int128)a[ 6]) * a[ 8]) * 2
  32897. + ((sp_int128)a[ 7]) * a[ 7];
  32898. r[13] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32899. t1 = (((sp_int128)a[ 7]) * a[ 8]) * 2;
  32900. r[14] = t0 & 0x3ffffffffffffffL; t1 += t0 >> 58;
  32901. t0 = ((sp_int128)a[ 8]) * a[ 8];
  32902. r[15] = t1 & 0x3ffffffffffffffL; t0 += t1 >> 58;
  32903. r[16] = t0 & 0x3ffffffffffffffL;
  32904. r[17] = (sp_digit)(t0 >> 58);
  32905. XMEMCPY(r, t, sizeof(t));
  32906. }
  32907. #endif /* WOLFSSL_SP_SMALL */
  32908. #ifdef WOLFSSL_SP_SMALL
  32909. /* Add b to a into r. (r = a + b)
  32910. *
  32911. * r A single precision integer.
  32912. * a A single precision integer.
  32913. * b A single precision integer.
  32914. */
  32915. SP_NOINLINE static int sp_521_add_9(sp_digit* r, const sp_digit* a,
  32916. const sp_digit* b)
  32917. {
  32918. int i;
  32919. for (i = 0; i < 9; i++) {
  32920. r[i] = a[i] + b[i];
  32921. }
  32922. return 0;
  32923. }
  32924. #else
  32925. /* Add b to a into r. (r = a + b)
  32926. *
  32927. * r A single precision integer.
  32928. * a A single precision integer.
  32929. * b A single precision integer.
  32930. */
  32931. SP_NOINLINE static int sp_521_add_9(sp_digit* r, const sp_digit* a,
  32932. const sp_digit* b)
  32933. {
  32934. r[ 0] = a[ 0] + b[ 0];
  32935. r[ 1] = a[ 1] + b[ 1];
  32936. r[ 2] = a[ 2] + b[ 2];
  32937. r[ 3] = a[ 3] + b[ 3];
  32938. r[ 4] = a[ 4] + b[ 4];
  32939. r[ 5] = a[ 5] + b[ 5];
  32940. r[ 6] = a[ 6] + b[ 6];
  32941. r[ 7] = a[ 7] + b[ 7];
  32942. r[ 8] = a[ 8] + b[ 8];
  32943. return 0;
  32944. }
  32945. #endif /* WOLFSSL_SP_SMALL */
  32946. #ifdef WOLFSSL_SP_SMALL
  32947. /* Sub b from a into r. (r = a - b)
  32948. *
  32949. * r A single precision integer.
  32950. * a A single precision integer.
  32951. * b A single precision integer.
  32952. */
  32953. SP_NOINLINE static int sp_521_sub_9(sp_digit* r, const sp_digit* a,
  32954. const sp_digit* b)
  32955. {
  32956. int i;
  32957. for (i = 0; i < 9; i++) {
  32958. r[i] = a[i] - b[i];
  32959. }
  32960. return 0;
  32961. }
  32962. #else
  32963. /* Sub b from a into r. (r = a - b)
  32964. *
  32965. * r A single precision integer.
  32966. * a A single precision integer.
  32967. * b A single precision integer.
  32968. */
  32969. SP_NOINLINE static int sp_521_sub_9(sp_digit* r, const sp_digit* a,
  32970. const sp_digit* b)
  32971. {
  32972. r[ 0] = a[ 0] - b[ 0];
  32973. r[ 1] = a[ 1] - b[ 1];
  32974. r[ 2] = a[ 2] - b[ 2];
  32975. r[ 3] = a[ 3] - b[ 3];
  32976. r[ 4] = a[ 4] - b[ 4];
  32977. r[ 5] = a[ 5] - b[ 5];
  32978. r[ 6] = a[ 6] - b[ 6];
  32979. r[ 7] = a[ 7] - b[ 7];
  32980. r[ 8] = a[ 8] - b[ 8];
  32981. return 0;
  32982. }
  32983. #endif /* WOLFSSL_SP_SMALL */
  32984. /* Convert an mp_int to an array of sp_digit.
  32985. *
  32986. * r A single precision integer.
  32987. * size Maximum number of bytes to convert
  32988. * a A multi-precision integer.
  32989. */
  32990. static void sp_521_from_mp(sp_digit* r, int size, const mp_int* a)
  32991. {
  32992. #if DIGIT_BIT == 58
  32993. int i;
  32994. sp_digit j = (sp_digit)0 - (sp_digit)a->used;
  32995. int o = 0;
  32996. for (i = 0; i < size; i++) {
  32997. sp_digit mask = (sp_digit)0 - (j >> 57);
  32998. r[i] = a->dp[o] & mask;
  32999. j++;
  33000. o += (int)(j >> 57);
  33001. }
  33002. #elif DIGIT_BIT > 58
  33003. unsigned int i;
  33004. int j = 0;
  33005. word32 s = 0;
  33006. r[0] = 0;
  33007. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  33008. r[j] |= ((sp_digit)a->dp[i] << s);
  33009. r[j] &= 0x3ffffffffffffffL;
  33010. s = 58U - s;
  33011. if (j + 1 >= size) {
  33012. break;
  33013. }
  33014. /* lint allow cast of mismatch word32 and mp_digit */
  33015. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  33016. while ((s + 58U) <= (word32)DIGIT_BIT) {
  33017. s += 58U;
  33018. r[j] &= 0x3ffffffffffffffL;
  33019. if (j + 1 >= size) {
  33020. break;
  33021. }
  33022. if (s < (word32)DIGIT_BIT) {
  33023. /* lint allow cast of mismatch word32 and mp_digit */
  33024. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  33025. }
  33026. else {
  33027. r[++j] = (sp_digit)0;
  33028. }
  33029. }
  33030. s = (word32)DIGIT_BIT - s;
  33031. }
  33032. for (j++; j < size; j++) {
  33033. r[j] = 0;
  33034. }
  33035. #else
  33036. unsigned int i;
  33037. int j = 0;
  33038. int s = 0;
  33039. r[0] = 0;
  33040. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  33041. r[j] |= ((sp_digit)a->dp[i]) << s;
  33042. if (s + DIGIT_BIT >= 58) {
  33043. r[j] &= 0x3ffffffffffffffL;
  33044. if (j + 1 >= size) {
  33045. break;
  33046. }
  33047. s = 58 - s;
  33048. if (s == DIGIT_BIT) {
  33049. r[++j] = 0;
  33050. s = 0;
  33051. }
  33052. else {
  33053. r[++j] = a->dp[i] >> s;
  33054. s = DIGIT_BIT - s;
  33055. }
  33056. }
  33057. else {
  33058. s += DIGIT_BIT;
  33059. }
  33060. }
  33061. for (j++; j < size; j++) {
  33062. r[j] = 0;
  33063. }
  33064. #endif
  33065. }
  33066. /* Convert a point of type ecc_point to type sp_point_521.
  33067. *
  33068. * p Point of type sp_point_521 (result).
  33069. * pm Point of type ecc_point.
  33070. */
  33071. static void sp_521_point_from_ecc_point_9(sp_point_521* p,
  33072. const ecc_point* pm)
  33073. {
  33074. XMEMSET(p->x, 0, sizeof(p->x));
  33075. XMEMSET(p->y, 0, sizeof(p->y));
  33076. XMEMSET(p->z, 0, sizeof(p->z));
  33077. sp_521_from_mp(p->x, 9, pm->x);
  33078. sp_521_from_mp(p->y, 9, pm->y);
  33079. sp_521_from_mp(p->z, 9, pm->z);
  33080. p->infinity = 0;
  33081. }
  33082. /* Convert an array of sp_digit to an mp_int.
  33083. *
  33084. * a A single precision integer.
  33085. * r A multi-precision integer.
  33086. */
  33087. static int sp_521_to_mp(const sp_digit* a, mp_int* r)
  33088. {
  33089. int err;
  33090. err = mp_grow(r, (521 + DIGIT_BIT - 1) / DIGIT_BIT);
  33091. if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
  33092. #if DIGIT_BIT == 58
  33093. XMEMCPY(r->dp, a, sizeof(sp_digit) * 9);
  33094. r->used = 9;
  33095. mp_clamp(r);
  33096. #elif DIGIT_BIT < 58
  33097. int i;
  33098. int j = 0;
  33099. int s = 0;
  33100. r->dp[0] = 0;
  33101. for (i = 0; i < 9; i++) {
  33102. r->dp[j] |= (mp_digit)(a[i] << s);
  33103. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  33104. s = DIGIT_BIT - s;
  33105. r->dp[++j] = (mp_digit)(a[i] >> s);
  33106. while (s + DIGIT_BIT <= 58) {
  33107. s += DIGIT_BIT;
  33108. r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  33109. if (s == SP_WORD_SIZE) {
  33110. r->dp[j] = 0;
  33111. }
  33112. else {
  33113. r->dp[j] = (mp_digit)(a[i] >> s);
  33114. }
  33115. }
  33116. s = 58 - s;
  33117. }
  33118. r->used = (521 + DIGIT_BIT - 1) / DIGIT_BIT;
  33119. mp_clamp(r);
  33120. #else
  33121. int i;
  33122. int j = 0;
  33123. int s = 0;
  33124. r->dp[0] = 0;
  33125. for (i = 0; i < 9; i++) {
  33126. r->dp[j] |= ((mp_digit)a[i]) << s;
  33127. if (s + 58 >= DIGIT_BIT) {
  33128. #if DIGIT_BIT != 32 && DIGIT_BIT != 64
  33129. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  33130. #endif
  33131. s = DIGIT_BIT - s;
  33132. r->dp[++j] = a[i] >> s;
  33133. s = 58 - s;
  33134. }
  33135. else {
  33136. s += 58;
  33137. }
  33138. }
  33139. r->used = (521 + DIGIT_BIT - 1) / DIGIT_BIT;
  33140. mp_clamp(r);
  33141. #endif
  33142. }
  33143. return err;
  33144. }
  33145. /* Convert a point of type sp_point_521 to type ecc_point.
  33146. *
  33147. * p Point of type sp_point_521.
  33148. * pm Point of type ecc_point (result).
  33149. * returns MEMORY_E when allocation of memory in ecc_point fails otherwise
  33150. * MP_OKAY.
  33151. */
  33152. static int sp_521_point_to_ecc_point_9(const sp_point_521* p, ecc_point* pm)
  33153. {
  33154. int err;
  33155. err = sp_521_to_mp(p->x, pm->x);
  33156. if (err == MP_OKAY) {
  33157. err = sp_521_to_mp(p->y, pm->y);
  33158. }
  33159. if (err == MP_OKAY) {
  33160. err = sp_521_to_mp(p->z, pm->z);
  33161. }
  33162. return err;
  33163. }
  33164. /* Normalize the values in each word to 58 bits.
  33165. *
  33166. * a Array of sp_digit to normalize.
  33167. */
  33168. static void sp_521_norm_9(sp_digit* a)
  33169. {
  33170. #ifdef WOLFSSL_SP_SMALL
  33171. int i;
  33172. for (i = 0; i < 8; i++) {
  33173. a[i+1] += a[i] >> 58;
  33174. a[i] &= 0x3ffffffffffffffL;
  33175. }
  33176. #else
  33177. a[1] += a[0] >> 58; a[0] &= 0x3ffffffffffffffL;
  33178. a[2] += a[1] >> 58; a[1] &= 0x3ffffffffffffffL;
  33179. a[3] += a[2] >> 58; a[2] &= 0x3ffffffffffffffL;
  33180. a[4] += a[3] >> 58; a[3] &= 0x3ffffffffffffffL;
  33181. a[5] += a[4] >> 58; a[4] &= 0x3ffffffffffffffL;
  33182. a[6] += a[5] >> 58; a[5] &= 0x3ffffffffffffffL;
  33183. a[7] += a[6] >> 58; a[6] &= 0x3ffffffffffffffL;
  33184. a[8] += a[7] >> 58; a[7] &= 0x3ffffffffffffffL;
  33185. #endif /* WOLFSSL_SP_SMALL */
  33186. }
  33187. /* Reduce the number back to 521 bits using Montgomery reduction.
  33188. *
  33189. * a A single precision number to reduce in place.
  33190. * m The single precision number representing the modulus.
  33191. * mp The digit representing the negative inverse of m mod 2^n.
  33192. */
  33193. static void sp_521_mont_reduce_9(sp_digit* a, const sp_digit* m, sp_digit mp)
  33194. {
  33195. int i;
  33196. (void)m;
  33197. (void)mp;
  33198. for (i = 0; i < 8; i++) {
  33199. a[i] += ((a[8 + i] >> 57) + (a[8 + i + 1] << 1)) & 0x3ffffffffffffffL;
  33200. }
  33201. a[8] &= 0x1ffffffffffffff;
  33202. a[8] += ((a[16] >> 57) + (a[17] << 1)) & 0x3ffffffffffffffL;
  33203. sp_521_norm_9(a);
  33204. a[0] += a[8] >> 57;
  33205. a[8] &= 0x1ffffffffffffff;
  33206. }
  33207. /* Compare a with b in constant time.
  33208. *
  33209. * a A single precision integer.
  33210. * b A single precision integer.
  33211. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  33212. * respectively.
  33213. */
  33214. static sp_digit sp_521_cmp_9(const sp_digit* a, const sp_digit* b)
  33215. {
  33216. sp_digit r = 0;
  33217. #ifdef WOLFSSL_SP_SMALL
  33218. int i;
  33219. for (i=8; i>=0; i--) {
  33220. r |= (a[i] - b[i]) & ~(((sp_digit)0 - r) >> 57);
  33221. }
  33222. #else
  33223. r |= (a[ 8] - b[ 8]) & (0 - (sp_digit)1);
  33224. r |= (a[ 7] - b[ 7]) & ~(((sp_digit)0 - r) >> 57);
  33225. r |= (a[ 6] - b[ 6]) & ~(((sp_digit)0 - r) >> 57);
  33226. r |= (a[ 5] - b[ 5]) & ~(((sp_digit)0 - r) >> 57);
  33227. r |= (a[ 4] - b[ 4]) & ~(((sp_digit)0 - r) >> 57);
  33228. r |= (a[ 3] - b[ 3]) & ~(((sp_digit)0 - r) >> 57);
  33229. r |= (a[ 2] - b[ 2]) & ~(((sp_digit)0 - r) >> 57);
  33230. r |= (a[ 1] - b[ 1]) & ~(((sp_digit)0 - r) >> 57);
  33231. r |= (a[ 0] - b[ 0]) & ~(((sp_digit)0 - r) >> 57);
  33232. #endif /* WOLFSSL_SP_SMALL */
  33233. return r;
  33234. }
  33235. /* Conditionally subtract b from a using the mask m.
  33236. * m is -1 to subtract and 0 when not.
  33237. *
  33238. * r A single precision number representing condition subtract result.
  33239. * a A single precision number to subtract from.
  33240. * b A single precision number to subtract.
  33241. * m Mask value to apply.
  33242. */
  33243. static void sp_521_cond_sub_9(sp_digit* r, const sp_digit* a,
  33244. const sp_digit* b, const sp_digit m)
  33245. {
  33246. #ifdef WOLFSSL_SP_SMALL
  33247. int i;
  33248. for (i = 0; i < 9; i++) {
  33249. r[i] = a[i] - (b[i] & m);
  33250. }
  33251. #else
  33252. r[ 0] = a[ 0] - (b[ 0] & m);
  33253. r[ 1] = a[ 1] - (b[ 1] & m);
  33254. r[ 2] = a[ 2] - (b[ 2] & m);
  33255. r[ 3] = a[ 3] - (b[ 3] & m);
  33256. r[ 4] = a[ 4] - (b[ 4] & m);
  33257. r[ 5] = a[ 5] - (b[ 5] & m);
  33258. r[ 6] = a[ 6] - (b[ 6] & m);
  33259. r[ 7] = a[ 7] - (b[ 7] & m);
  33260. r[ 8] = a[ 8] - (b[ 8] & m);
  33261. #endif /* WOLFSSL_SP_SMALL */
  33262. }
  33263. /* Mul a by scalar b and add into r. (r += a * b)
  33264. *
  33265. * r A single precision integer.
  33266. * a A single precision integer.
  33267. * b A scalar.
  33268. */
  33269. SP_NOINLINE static void sp_521_mul_add_9(sp_digit* r, const sp_digit* a,
  33270. const sp_digit b)
  33271. {
  33272. #ifdef WOLFSSL_SP_SMALL
  33273. sp_int128 tb = b;
  33274. sp_int128 t[4];
  33275. int i;
  33276. t[0] = 0;
  33277. for (i = 0; i < 8; i += 4) {
  33278. t[0] += (tb * a[i+0]) + r[i+0];
  33279. t[1] = (tb * a[i+1]) + r[i+1];
  33280. t[2] = (tb * a[i+2]) + r[i+2];
  33281. t[3] = (tb * a[i+3]) + r[i+3];
  33282. r[i+0] = t[0] & 0x3ffffffffffffffL;
  33283. t[1] += t[0] >> 58;
  33284. r[i+1] = t[1] & 0x3ffffffffffffffL;
  33285. t[2] += t[1] >> 58;
  33286. r[i+2] = t[2] & 0x3ffffffffffffffL;
  33287. t[3] += t[2] >> 58;
  33288. r[i+3] = t[3] & 0x3ffffffffffffffL;
  33289. t[0] = t[3] >> 58;
  33290. }
  33291. t[0] += (tb * a[8]) + r[8];
  33292. r[8] = t[0] & 0x3ffffffffffffffL;
  33293. r[9] += (sp_digit)(t[0] >> 58);
  33294. #else
  33295. sp_int128 tb = b;
  33296. sp_int128 t[9];
  33297. t[ 0] = tb * a[ 0];
  33298. t[ 1] = tb * a[ 1];
  33299. t[ 2] = tb * a[ 2];
  33300. t[ 3] = tb * a[ 3];
  33301. t[ 4] = tb * a[ 4];
  33302. t[ 5] = tb * a[ 5];
  33303. t[ 6] = tb * a[ 6];
  33304. t[ 7] = tb * a[ 7];
  33305. t[ 8] = tb * a[ 8];
  33306. r[ 0] += (sp_digit) (t[ 0] & 0x3ffffffffffffffL);
  33307. r[ 1] += (sp_digit)((t[ 0] >> 58) + (t[ 1] & 0x3ffffffffffffffL));
  33308. r[ 2] += (sp_digit)((t[ 1] >> 58) + (t[ 2] & 0x3ffffffffffffffL));
  33309. r[ 3] += (sp_digit)((t[ 2] >> 58) + (t[ 3] & 0x3ffffffffffffffL));
  33310. r[ 4] += (sp_digit)((t[ 3] >> 58) + (t[ 4] & 0x3ffffffffffffffL));
  33311. r[ 5] += (sp_digit)((t[ 4] >> 58) + (t[ 5] & 0x3ffffffffffffffL));
  33312. r[ 6] += (sp_digit)((t[ 5] >> 58) + (t[ 6] & 0x3ffffffffffffffL));
  33313. r[ 7] += (sp_digit)((t[ 6] >> 58) + (t[ 7] & 0x3ffffffffffffffL));
  33314. r[ 8] += (sp_digit)((t[ 7] >> 58) + (t[ 8] & 0x3ffffffffffffffL));
  33315. r[ 9] += (sp_digit) (t[ 8] >> 58);
  33316. #endif /* WOLFSSL_SP_SMALL */
  33317. }
  33318. /* Shift the result in the high 521 bits down to the bottom.
  33319. *
  33320. * r A single precision number.
  33321. * a A single precision number.
  33322. */
  33323. static void sp_521_mont_shift_9(sp_digit* r, const sp_digit* a)
  33324. {
  33325. #ifdef WOLFSSL_SP_SMALL
  33326. int i;
  33327. sp_uint64 n;
  33328. n = a[8] >> 57;
  33329. for (i = 0; i < 8; i++) {
  33330. n += (sp_uint64)a[9 + i] << 1;
  33331. r[i] = n & 0x3ffffffffffffffL;
  33332. n >>= 58;
  33333. }
  33334. n += (sp_uint64)a[17] << 1;
  33335. r[8] = n;
  33336. #else
  33337. sp_uint64 n;
  33338. n = a[8] >> 57;
  33339. n += (sp_uint64)a[ 9] << 1U; r[ 0] = n & 0x3ffffffffffffffUL; n >>= 58U;
  33340. n += (sp_uint64)a[10] << 1U; r[ 1] = n & 0x3ffffffffffffffUL; n >>= 58U;
  33341. n += (sp_uint64)a[11] << 1U; r[ 2] = n & 0x3ffffffffffffffUL; n >>= 58U;
  33342. n += (sp_uint64)a[12] << 1U; r[ 3] = n & 0x3ffffffffffffffUL; n >>= 58U;
  33343. n += (sp_uint64)a[13] << 1U; r[ 4] = n & 0x3ffffffffffffffUL; n >>= 58U;
  33344. n += (sp_uint64)a[14] << 1U; r[ 5] = n & 0x3ffffffffffffffUL; n >>= 58U;
  33345. n += (sp_uint64)a[15] << 1U; r[ 6] = n & 0x3ffffffffffffffUL; n >>= 58U;
  33346. n += (sp_uint64)a[16] << 1U; r[ 7] = n & 0x3ffffffffffffffUL; n >>= 58U;
  33347. n += (sp_uint64)a[17] << 1U; r[ 8] = n;
  33348. #endif /* WOLFSSL_SP_SMALL */
  33349. XMEMSET(&r[9], 0, sizeof(*r) * 9U);
  33350. }
  33351. /* Reduce the number back to 521 bits using Montgomery reduction.
  33352. *
  33353. * a A single precision number to reduce in place.
  33354. * m The single precision number representing the modulus.
  33355. * mp The digit representing the negative inverse of m mod 2^n.
  33356. */
  33357. static void sp_521_mont_reduce_order_9(sp_digit* a, const sp_digit* m, sp_digit mp)
  33358. {
  33359. int i;
  33360. sp_digit mu;
  33361. sp_digit over;
  33362. sp_521_norm_9(a + 9);
  33363. for (i=0; i<8; i++) {
  33364. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x3ffffffffffffffL;
  33365. sp_521_mul_add_9(a+i, m, mu);
  33366. a[i+1] += a[i] >> 58;
  33367. }
  33368. mu = ((sp_uint64)a[i] * (sp_uint64)mp) & 0x1ffffffffffffffL;
  33369. sp_521_mul_add_9(a+i, m, mu);
  33370. a[i+1] += a[i] >> 58;
  33371. a[i] &= 0x3ffffffffffffffL;
  33372. sp_521_mont_shift_9(a, a);
  33373. over = a[8] >> 57;
  33374. sp_521_cond_sub_9(a, a, m, ~((over - 1) >> 63));
  33375. sp_521_norm_9(a);
  33376. }
  33377. /* Multiply two Montgomery form numbers mod the modulus (prime).
  33378. * (r = a * b mod m)
  33379. *
  33380. * r Result of multiplication.
  33381. * a First number to multiply in Montgomery form.
  33382. * b Second number to multiply in Montgomery form.
  33383. * m Modulus (prime).
  33384. * mp Montgomery multiplier.
  33385. */
  33386. SP_NOINLINE static void sp_521_mont_mul_9(sp_digit* r, const sp_digit* a,
  33387. const sp_digit* b, const sp_digit* m, sp_digit mp)
  33388. {
  33389. sp_521_mul_9(r, a, b);
  33390. sp_521_mont_reduce_9(r, m, mp);
  33391. }
  33392. /* Square the Montgomery form number. (r = a * a mod m)
  33393. *
  33394. * r Result of squaring.
  33395. * a Number to square in Montgomery form.
  33396. * m Modulus (prime).
  33397. * mp Montgomery multiplier.
  33398. */
  33399. SP_NOINLINE static void sp_521_mont_sqr_9(sp_digit* r, const sp_digit* a,
  33400. const sp_digit* m, sp_digit mp)
  33401. {
  33402. sp_521_sqr_9(r, a);
  33403. sp_521_mont_reduce_9(r, m, mp);
  33404. }
  33405. #ifndef WOLFSSL_SP_SMALL
  33406. /* Square the Montgomery form number a number of times. (r = a ^ n mod m)
  33407. *
  33408. * r Result of squaring.
  33409. * a Number to square in Montgomery form.
  33410. * n Number of times to square.
  33411. * m Modulus (prime).
  33412. * mp Montgomery multiplier.
  33413. */
  33414. SP_NOINLINE static void sp_521_mont_sqr_n_9(sp_digit* r,
  33415. const sp_digit* a, int n, const sp_digit* m, sp_digit mp)
  33416. {
  33417. sp_521_mont_sqr_9(r, a, m, mp);
  33418. for (; n > 1; n--) {
  33419. sp_521_mont_sqr_9(r, r, m, mp);
  33420. }
  33421. }
  33422. #endif /* !WOLFSSL_SP_SMALL */
  33423. #ifdef WOLFSSL_SP_SMALL
  33424. /* Mod-2 for the P521 curve. */
  33425. static const uint64_t p521_mod_minus_2[9] = {
  33426. 0xfffffffffffffffdU,0xffffffffffffffffU,0xffffffffffffffffU,
  33427. 0xffffffffffffffffU,0xffffffffffffffffU,0xffffffffffffffffU,
  33428. 0xffffffffffffffffU,0xffffffffffffffffU,0x00000000000001ffU
  33429. };
  33430. #endif /* !WOLFSSL_SP_SMALL */
  33431. /* Invert the number, in Montgomery form, modulo the modulus (prime) of the
  33432. * P521 curve. (r = 1 / a mod m)
  33433. *
  33434. * r Inverse result.
  33435. * a Number to invert.
  33436. * td Temporary data.
  33437. */
  33438. static void sp_521_mont_inv_9(sp_digit* r, const sp_digit* a, sp_digit* td)
  33439. {
  33440. #ifdef WOLFSSL_SP_SMALL
  33441. sp_digit* t = td;
  33442. int i;
  33443. XMEMCPY(t, a, sizeof(sp_digit) * 9);
  33444. for (i=519; i>=0; i--) {
  33445. sp_521_mont_sqr_9(t, t, p521_mod, p521_mp_mod);
  33446. if (p521_mod_minus_2[i / 64] & ((sp_digit)1 << (i % 64)))
  33447. sp_521_mont_mul_9(t, t, a, p521_mod, p521_mp_mod);
  33448. }
  33449. XMEMCPY(r, t, sizeof(sp_digit) * 9);
  33450. #else
  33451. sp_digit* t1 = td;
  33452. sp_digit* t2 = td + 2 * 9;
  33453. sp_digit* t3 = td + 4 * 9;
  33454. /* 0x2 */
  33455. sp_521_mont_sqr_9(t1, a, p521_mod, p521_mp_mod);
  33456. /* 0x3 */
  33457. sp_521_mont_mul_9(t2, t1, a, p521_mod, p521_mp_mod);
  33458. /* 0x6 */
  33459. sp_521_mont_sqr_9(t1, t2, p521_mod, p521_mp_mod);
  33460. /* 0x7 */
  33461. sp_521_mont_mul_9(t3, t1, a, p521_mod, p521_mp_mod);
  33462. /* 0xc */
  33463. sp_521_mont_sqr_n_9(t1, t2, 2, p521_mod, p521_mp_mod);
  33464. /* 0xf */
  33465. sp_521_mont_mul_9(t2, t2, t1, p521_mod, p521_mp_mod);
  33466. /* 0x78 */
  33467. sp_521_mont_sqr_n_9(t1, t2, 3, p521_mod, p521_mp_mod);
  33468. /* 0x7f */
  33469. sp_521_mont_mul_9(t3, t3, t1, p521_mod, p521_mp_mod);
  33470. /* 0xf0 */
  33471. sp_521_mont_sqr_n_9(t1, t2, 4, p521_mod, p521_mp_mod);
  33472. /* 0xff */
  33473. sp_521_mont_mul_9(t2, t2, t1, p521_mod, p521_mp_mod);
  33474. /* 0xff00 */
  33475. sp_521_mont_sqr_n_9(t1, t2, 8, p521_mod, p521_mp_mod);
  33476. /* 0xffff */
  33477. sp_521_mont_mul_9(t2, t2, t1, p521_mod, p521_mp_mod);
  33478. /* 0xffff0000 */
  33479. sp_521_mont_sqr_n_9(t1, t2, 16, p521_mod, p521_mp_mod);
  33480. /* 0xffffffff */
  33481. sp_521_mont_mul_9(t2, t2, t1, p521_mod, p521_mp_mod);
  33482. /* 0xffffffff00000000 */
  33483. sp_521_mont_sqr_n_9(t1, t2, 32, p521_mod, p521_mp_mod);
  33484. /* 0xffffffffffffffff */
  33485. sp_521_mont_mul_9(t2, t2, t1, p521_mod, p521_mp_mod);
  33486. /* 0xffffffffffffffff0000000000000000 */
  33487. sp_521_mont_sqr_n_9(t1, t2, 64, p521_mod, p521_mp_mod);
  33488. /* 0xffffffffffffffffffffffffffffffff */
  33489. sp_521_mont_mul_9(t2, t2, t1, p521_mod, p521_mp_mod);
  33490. /* 0xffffffffffffffffffffffffffffffff00000000000000000000000000000000 */
  33491. sp_521_mont_sqr_n_9(t1, t2, 128, p521_mod, p521_mp_mod);
  33492. /* 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
  33493. sp_521_mont_mul_9(t2, t2, t1, p521_mod, p521_mp_mod);
  33494. /* 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000 */
  33495. sp_521_mont_sqr_n_9(t1, t2, 256, p521_mod, p521_mp_mod);
  33496. /* 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
  33497. sp_521_mont_mul_9(t2, t2, t1, p521_mod, p521_mp_mod);
  33498. /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80 */
  33499. sp_521_mont_sqr_n_9(t1, t2, 7, p521_mod, p521_mp_mod);
  33500. /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
  33501. sp_521_mont_mul_9(t2, t3, t1, p521_mod, p521_mp_mod);
  33502. /* 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc */
  33503. sp_521_mont_sqr_n_9(t1, t2, 2, p521_mod, p521_mp_mod);
  33504. /* 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd */
  33505. sp_521_mont_mul_9(r, t1, a, p521_mod, p521_mp_mod);
  33506. #endif /* WOLFSSL_SP_SMALL */
  33507. }
  33508. /* Map the Montgomery form projective coordinate point to an affine point.
  33509. *
  33510. * r Resulting affine coordinate point.
  33511. * p Montgomery form projective coordinate point.
  33512. * t Temporary ordinate data.
  33513. */
  33514. static void sp_521_map_9(sp_point_521* r, const sp_point_521* p,
  33515. sp_digit* t)
  33516. {
  33517. sp_digit* t1 = t;
  33518. sp_digit* t2 = t + 2*9;
  33519. sp_int64 n;
  33520. sp_521_mont_inv_9(t1, p->z, t + 2*9);
  33521. sp_521_mont_sqr_9(t2, t1, p521_mod, p521_mp_mod);
  33522. sp_521_mont_mul_9(t1, t2, t1, p521_mod, p521_mp_mod);
  33523. /* x /= z^2 */
  33524. sp_521_mont_mul_9(r->x, p->x, t2, p521_mod, p521_mp_mod);
  33525. XMEMSET(r->x + 9, 0, sizeof(sp_digit) * 9U);
  33526. sp_521_mont_reduce_9(r->x, p521_mod, p521_mp_mod);
  33527. /* Reduce x to less than modulus */
  33528. n = sp_521_cmp_9(r->x, p521_mod);
  33529. sp_521_cond_sub_9(r->x, r->x, p521_mod, ~(n >> 57));
  33530. sp_521_norm_9(r->x);
  33531. /* y /= z^3 */
  33532. sp_521_mont_mul_9(r->y, p->y, t1, p521_mod, p521_mp_mod);
  33533. XMEMSET(r->y + 9, 0, sizeof(sp_digit) * 9U);
  33534. sp_521_mont_reduce_9(r->y, p521_mod, p521_mp_mod);
  33535. /* Reduce y to less than modulus */
  33536. n = sp_521_cmp_9(r->y, p521_mod);
  33537. sp_521_cond_sub_9(r->y, r->y, p521_mod, ~(n >> 57));
  33538. sp_521_norm_9(r->y);
  33539. XMEMSET(r->z, 0, sizeof(r->z) / 2);
  33540. r->z[0] = 1;
  33541. }
  33542. /* Add two Montgomery form numbers (r = a + b % m).
  33543. *
  33544. * r Result of addition.
  33545. * a First number to add in Montgomery form.
  33546. * b Second number to add in Montgomery form.
  33547. * m Modulus (prime).
  33548. */
  33549. static void sp_521_mont_add_9(sp_digit* r, const sp_digit* a, const sp_digit* b,
  33550. const sp_digit* m)
  33551. {
  33552. sp_digit over;
  33553. (void)sp_521_add_9(r, a, b);
  33554. sp_521_norm_9(r);
  33555. over = r[8] >> 57;
  33556. sp_521_cond_sub_9(r, r, m, ~((over - 1) >> 63));
  33557. sp_521_norm_9(r);
  33558. }
  33559. /* Double a Montgomery form number (r = a + a % m).
  33560. *
  33561. * r Result of doubling.
  33562. * a Number to double in Montgomery form.
  33563. * m Modulus (prime).
  33564. */
  33565. static void sp_521_mont_dbl_9(sp_digit* r, const sp_digit* a, const sp_digit* m)
  33566. {
  33567. sp_digit over;
  33568. (void)sp_521_add_9(r, a, a);
  33569. sp_521_norm_9(r);
  33570. over = r[8] >> 57;
  33571. sp_521_cond_sub_9(r, r, m, ~((over - 1) >> 63));
  33572. sp_521_norm_9(r);
  33573. }
  33574. /* Triple a Montgomery form number (r = a + a + a % m).
  33575. *
  33576. * r Result of Tripling.
  33577. * a Number to triple in Montgomery form.
  33578. * m Modulus (prime).
  33579. */
  33580. static void sp_521_mont_tpl_9(sp_digit* r, const sp_digit* a, const sp_digit* m)
  33581. {
  33582. sp_digit over;
  33583. (void)sp_521_add_9(r, a, a);
  33584. sp_521_norm_9(r);
  33585. over = r[8] >> 57;
  33586. sp_521_cond_sub_9(r, r, m, ~((over - 1) >> 63));
  33587. sp_521_norm_9(r);
  33588. (void)sp_521_add_9(r, r, a);
  33589. sp_521_norm_9(r);
  33590. over = r[8] >> 57;
  33591. sp_521_cond_sub_9(r, r, m, ~((over - 1) >> 63));
  33592. sp_521_norm_9(r);
  33593. }
  33594. #ifdef WOLFSSL_SP_SMALL
  33595. /* Conditionally add a and b using the mask m.
  33596. * m is -1 to add and 0 when not.
  33597. *
  33598. * r A single precision number representing conditional add result.
  33599. * a A single precision number to add with.
  33600. * b A single precision number to add.
  33601. * m Mask value to apply.
  33602. */
  33603. static void sp_521_cond_add_9(sp_digit* r, const sp_digit* a,
  33604. const sp_digit* b, const sp_digit m)
  33605. {
  33606. int i;
  33607. for (i = 0; i < 9; i++) {
  33608. r[i] = a[i] + (b[i] & m);
  33609. }
  33610. }
  33611. #endif /* WOLFSSL_SP_SMALL */
  33612. #ifndef WOLFSSL_SP_SMALL
  33613. /* Conditionally add a and b using the mask m.
  33614. * m is -1 to add and 0 when not.
  33615. *
  33616. * r A single precision number representing conditional add result.
  33617. * a A single precision number to add with.
  33618. * b A single precision number to add.
  33619. * m Mask value to apply.
  33620. */
  33621. static void sp_521_cond_add_9(sp_digit* r, const sp_digit* a,
  33622. const sp_digit* b, const sp_digit m)
  33623. {
  33624. r[ 0] = a[ 0] + (b[ 0] & m);
  33625. r[ 1] = a[ 1] + (b[ 1] & m);
  33626. r[ 2] = a[ 2] + (b[ 2] & m);
  33627. r[ 3] = a[ 3] + (b[ 3] & m);
  33628. r[ 4] = a[ 4] + (b[ 4] & m);
  33629. r[ 5] = a[ 5] + (b[ 5] & m);
  33630. r[ 6] = a[ 6] + (b[ 6] & m);
  33631. r[ 7] = a[ 7] + (b[ 7] & m);
  33632. r[ 8] = a[ 8] + (b[ 8] & m);
  33633. }
  33634. #endif /* !WOLFSSL_SP_SMALL */
  33635. /* Subtract two Montgomery form numbers (r = a - b % m).
  33636. *
  33637. * r Result of subtration.
  33638. * a Number to subtract from in Montgomery form.
  33639. * b Number to subtract with in Montgomery form.
  33640. * m Modulus (prime).
  33641. */
  33642. static void sp_521_mont_sub_9(sp_digit* r, const sp_digit* a, const sp_digit* b,
  33643. const sp_digit* m)
  33644. {
  33645. (void)sp_521_sub_9(r, a, b);
  33646. sp_521_norm_9(r);
  33647. sp_521_cond_add_9(r, r, m, r[8] >> 57);
  33648. sp_521_norm_9(r);
  33649. }
  33650. /* Shift number left one bit.
  33651. * Bottom bit is lost.
  33652. *
  33653. * r Result of shift.
  33654. * a Number to shift.
  33655. */
  33656. SP_NOINLINE static void sp_521_rshift1_9(sp_digit* r, const sp_digit* a)
  33657. {
  33658. #ifdef WOLFSSL_SP_SMALL
  33659. int i;
  33660. for (i=0; i<8; i++) {
  33661. r[i] = (a[i] >> 1) + ((a[i + 1] << 57) & 0x3ffffffffffffffL);
  33662. }
  33663. #else
  33664. r[0] = (a[0] >> 1) + ((a[1] << 57) & 0x3ffffffffffffffL);
  33665. r[1] = (a[1] >> 1) + ((a[2] << 57) & 0x3ffffffffffffffL);
  33666. r[2] = (a[2] >> 1) + ((a[3] << 57) & 0x3ffffffffffffffL);
  33667. r[3] = (a[3] >> 1) + ((a[4] << 57) & 0x3ffffffffffffffL);
  33668. r[4] = (a[4] >> 1) + ((a[5] << 57) & 0x3ffffffffffffffL);
  33669. r[5] = (a[5] >> 1) + ((a[6] << 57) & 0x3ffffffffffffffL);
  33670. r[6] = (a[6] >> 1) + ((a[7] << 57) & 0x3ffffffffffffffL);
  33671. r[7] = (a[7] >> 1) + ((a[8] << 57) & 0x3ffffffffffffffL);
  33672. #endif
  33673. r[8] = a[8] >> 1;
  33674. }
  33675. /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)
  33676. *
  33677. * r Result of division by 2.
  33678. * a Number to divide.
  33679. * m Modulus (prime).
  33680. */
  33681. static void sp_521_mont_div2_9(sp_digit* r, const sp_digit* a,
  33682. const sp_digit* m)
  33683. {
  33684. sp_521_cond_add_9(r, a, m, 0 - (a[0] & 1));
  33685. sp_521_norm_9(r);
  33686. sp_521_rshift1_9(r, r);
  33687. }
  33688. /* Double the Montgomery form projective point p.
  33689. *
  33690. * r Result of doubling point.
  33691. * p Point to double.
  33692. * t Temporary ordinate data.
  33693. */
  33694. static void sp_521_proj_point_dbl_9(sp_point_521* r, const sp_point_521* p,
  33695. sp_digit* t)
  33696. {
  33697. sp_digit* t1 = t;
  33698. sp_digit* t2 = t + 2*9;
  33699. sp_digit* x;
  33700. sp_digit* y;
  33701. sp_digit* z;
  33702. x = r->x;
  33703. y = r->y;
  33704. z = r->z;
  33705. /* Put infinity into result. */
  33706. if (r != p) {
  33707. r->infinity = p->infinity;
  33708. }
  33709. /* T1 = Z * Z */
  33710. sp_521_mont_sqr_9(t1, p->z, p521_mod, p521_mp_mod);
  33711. /* Z = Y * Z */
  33712. sp_521_mont_mul_9(z, p->y, p->z, p521_mod, p521_mp_mod);
  33713. /* Z = 2Z */
  33714. sp_521_mont_dbl_9(z, z, p521_mod);
  33715. /* T2 = X - T1 */
  33716. sp_521_mont_sub_9(t2, p->x, t1, p521_mod);
  33717. /* T1 = X + T1 */
  33718. sp_521_mont_add_9(t1, p->x, t1, p521_mod);
  33719. /* T2 = T1 * T2 */
  33720. sp_521_mont_mul_9(t2, t1, t2, p521_mod, p521_mp_mod);
  33721. /* T1 = 3T2 */
  33722. sp_521_mont_tpl_9(t1, t2, p521_mod);
  33723. /* Y = 2Y */
  33724. sp_521_mont_dbl_9(y, p->y, p521_mod);
  33725. /* Y = Y * Y */
  33726. sp_521_mont_sqr_9(y, y, p521_mod, p521_mp_mod);
  33727. /* T2 = Y * Y */
  33728. sp_521_mont_sqr_9(t2, y, p521_mod, p521_mp_mod);
  33729. /* T2 = T2/2 */
  33730. sp_521_mont_div2_9(t2, t2, p521_mod);
  33731. /* Y = Y * X */
  33732. sp_521_mont_mul_9(y, y, p->x, p521_mod, p521_mp_mod);
  33733. /* X = T1 * T1 */
  33734. sp_521_mont_sqr_9(x, t1, p521_mod, p521_mp_mod);
  33735. /* X = X - Y */
  33736. sp_521_mont_sub_9(x, x, y, p521_mod);
  33737. /* X = X - Y */
  33738. sp_521_mont_sub_9(x, x, y, p521_mod);
  33739. /* Y = Y - X */
  33740. sp_521_mont_sub_9(y, y, x, p521_mod);
  33741. /* Y = Y * T1 */
  33742. sp_521_mont_mul_9(y, y, t1, p521_mod, p521_mp_mod);
  33743. /* Y = Y - T2 */
  33744. sp_521_mont_sub_9(y, y, t2, p521_mod);
  33745. }
  33746. #ifdef WOLFSSL_SP_NONBLOCK
  33747. typedef struct sp_521_proj_point_dbl_9_ctx {
  33748. int state;
  33749. sp_digit* t1;
  33750. sp_digit* t2;
  33751. sp_digit* x;
  33752. sp_digit* y;
  33753. sp_digit* z;
  33754. } sp_521_proj_point_dbl_9_ctx;
  33755. /* Double the Montgomery form projective point p.
  33756. *
  33757. * r Result of doubling point.
  33758. * p Point to double.
  33759. * t Temporary ordinate data.
  33760. */
  33761. static int sp_521_proj_point_dbl_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
  33762. const sp_point_521* p, sp_digit* t)
  33763. {
  33764. int err = FP_WOULDBLOCK;
  33765. sp_521_proj_point_dbl_9_ctx* ctx = (sp_521_proj_point_dbl_9_ctx*)sp_ctx->data;
  33766. typedef char ctx_size_test[sizeof(sp_521_proj_point_dbl_9_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  33767. (void)sizeof(ctx_size_test);
  33768. switch (ctx->state) {
  33769. case 0:
  33770. ctx->t1 = t;
  33771. ctx->t2 = t + 2*9;
  33772. ctx->x = r->x;
  33773. ctx->y = r->y;
  33774. ctx->z = r->z;
  33775. /* Put infinity into result. */
  33776. if (r != p) {
  33777. r->infinity = p->infinity;
  33778. }
  33779. ctx->state = 1;
  33780. break;
  33781. case 1:
  33782. /* T1 = Z * Z */
  33783. sp_521_mont_sqr_9(ctx->t1, p->z, p521_mod, p521_mp_mod);
  33784. ctx->state = 2;
  33785. break;
  33786. case 2:
  33787. /* Z = Y * Z */
  33788. sp_521_mont_mul_9(ctx->z, p->y, p->z, p521_mod, p521_mp_mod);
  33789. ctx->state = 3;
  33790. break;
  33791. case 3:
  33792. /* Z = 2Z */
  33793. sp_521_mont_dbl_9(ctx->z, ctx->z, p521_mod);
  33794. ctx->state = 4;
  33795. break;
  33796. case 4:
  33797. /* T2 = X - T1 */
  33798. sp_521_mont_sub_9(ctx->t2, p->x, ctx->t1, p521_mod);
  33799. ctx->state = 5;
  33800. break;
  33801. case 5:
  33802. /* T1 = X + T1 */
  33803. sp_521_mont_add_9(ctx->t1, p->x, ctx->t1, p521_mod);
  33804. ctx->state = 6;
  33805. break;
  33806. case 6:
  33807. /* T2 = T1 * T2 */
  33808. sp_521_mont_mul_9(ctx->t2, ctx->t1, ctx->t2, p521_mod, p521_mp_mod);
  33809. ctx->state = 7;
  33810. break;
  33811. case 7:
  33812. /* T1 = 3T2 */
  33813. sp_521_mont_tpl_9(ctx->t1, ctx->t2, p521_mod);
  33814. ctx->state = 8;
  33815. break;
  33816. case 8:
  33817. /* Y = 2Y */
  33818. sp_521_mont_dbl_9(ctx->y, p->y, p521_mod);
  33819. ctx->state = 9;
  33820. break;
  33821. case 9:
  33822. /* Y = Y * Y */
  33823. sp_521_mont_sqr_9(ctx->y, ctx->y, p521_mod, p521_mp_mod);
  33824. ctx->state = 10;
  33825. break;
  33826. case 10:
  33827. /* T2 = Y * Y */
  33828. sp_521_mont_sqr_9(ctx->t2, ctx->y, p521_mod, p521_mp_mod);
  33829. ctx->state = 11;
  33830. break;
  33831. case 11:
  33832. /* T2 = T2/2 */
  33833. sp_521_mont_div2_9(ctx->t2, ctx->t2, p521_mod);
  33834. ctx->state = 12;
  33835. break;
  33836. case 12:
  33837. /* Y = Y * X */
  33838. sp_521_mont_mul_9(ctx->y, ctx->y, p->x, p521_mod, p521_mp_mod);
  33839. ctx->state = 13;
  33840. break;
  33841. case 13:
  33842. /* X = T1 * T1 */
  33843. sp_521_mont_sqr_9(ctx->x, ctx->t1, p521_mod, p521_mp_mod);
  33844. ctx->state = 14;
  33845. break;
  33846. case 14:
  33847. /* X = X - Y */
  33848. sp_521_mont_sub_9(ctx->x, ctx->x, ctx->y, p521_mod);
  33849. ctx->state = 15;
  33850. break;
  33851. case 15:
  33852. /* X = X - Y */
  33853. sp_521_mont_sub_9(ctx->x, ctx->x, ctx->y, p521_mod);
  33854. ctx->state = 16;
  33855. break;
  33856. case 16:
  33857. /* Y = Y - X */
  33858. sp_521_mont_sub_9(ctx->y, ctx->y, ctx->x, p521_mod);
  33859. ctx->state = 17;
  33860. break;
  33861. case 17:
  33862. /* Y = Y * T1 */
  33863. sp_521_mont_mul_9(ctx->y, ctx->y, ctx->t1, p521_mod, p521_mp_mod);
  33864. ctx->state = 18;
  33865. break;
  33866. case 18:
  33867. /* Y = Y - T2 */
  33868. sp_521_mont_sub_9(ctx->y, ctx->y, ctx->t2, p521_mod);
  33869. ctx->state = 19;
  33870. /* fall-through */
  33871. case 19:
  33872. err = MP_OKAY;
  33873. break;
  33874. }
  33875. if (err == MP_OKAY && ctx->state != 19) {
  33876. err = FP_WOULDBLOCK;
  33877. }
  33878. return err;
  33879. }
  33880. #endif /* WOLFSSL_SP_NONBLOCK */
  33881. /* Compare two numbers to determine if they are equal.
  33882. * Constant time implementation.
  33883. *
  33884. * a First number to compare.
  33885. * b Second number to compare.
  33886. * returns 1 when equal and 0 otherwise.
  33887. */
  33888. static int sp_521_cmp_equal_9(const sp_digit* a, const sp_digit* b)
  33889. {
  33890. return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) |
  33891. (a[3] ^ b[3]) | (a[4] ^ b[4]) | (a[5] ^ b[5]) |
  33892. (a[6] ^ b[6]) | (a[7] ^ b[7]) | (a[8] ^ b[8])) == 0;
  33893. }
  33894. /* Returns 1 if the number of zero.
  33895. * Implementation is constant time.
  33896. *
  33897. * a Number to check.
  33898. * returns 1 if the number is zero and 0 otherwise.
  33899. */
  33900. static int sp_521_iszero_9(const sp_digit* a)
  33901. {
  33902. return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] |
  33903. a[8]) == 0;
  33904. }
  33905. /* Add two Montgomery form projective points.
  33906. *
  33907. * r Result of addition.
  33908. * p First point to add.
  33909. * q Second point to add.
  33910. * t Temporary ordinate data.
  33911. */
  33912. static void sp_521_proj_point_add_9(sp_point_521* r,
  33913. const sp_point_521* p, const sp_point_521* q, sp_digit* t)
  33914. {
  33915. sp_digit* t6 = t;
  33916. sp_digit* t1 = t + 2*9;
  33917. sp_digit* t2 = t + 4*9;
  33918. sp_digit* t3 = t + 6*9;
  33919. sp_digit* t4 = t + 8*9;
  33920. sp_digit* t5 = t + 10*9;
  33921. /* U1 = X1*Z2^2 */
  33922. sp_521_mont_sqr_9(t1, q->z, p521_mod, p521_mp_mod);
  33923. sp_521_mont_mul_9(t3, t1, q->z, p521_mod, p521_mp_mod);
  33924. sp_521_mont_mul_9(t1, t1, p->x, p521_mod, p521_mp_mod);
  33925. /* U2 = X2*Z1^2 */
  33926. sp_521_mont_sqr_9(t2, p->z, p521_mod, p521_mp_mod);
  33927. sp_521_mont_mul_9(t4, t2, p->z, p521_mod, p521_mp_mod);
  33928. sp_521_mont_mul_9(t2, t2, q->x, p521_mod, p521_mp_mod);
  33929. /* S1 = Y1*Z2^3 */
  33930. sp_521_mont_mul_9(t3, t3, p->y, p521_mod, p521_mp_mod);
  33931. /* S2 = Y2*Z1^3 */
  33932. sp_521_mont_mul_9(t4, t4, q->y, p521_mod, p521_mp_mod);
  33933. /* Check double */
  33934. if ((~p->infinity) & (~q->infinity) &
  33935. sp_521_cmp_equal_9(t2, t1) &
  33936. sp_521_cmp_equal_9(t4, t3)) {
  33937. sp_521_proj_point_dbl_9(r, p, t);
  33938. }
  33939. else {
  33940. sp_digit* x = t6;
  33941. sp_digit* y = t1;
  33942. sp_digit* z = t2;
  33943. /* H = U2 - U1 */
  33944. sp_521_mont_sub_9(t2, t2, t1, p521_mod);
  33945. /* R = S2 - S1 */
  33946. sp_521_mont_sub_9(t4, t4, t3, p521_mod);
  33947. /* X3 = R^2 - H^3 - 2*U1*H^2 */
  33948. sp_521_mont_sqr_9(t5, t2, p521_mod, p521_mp_mod);
  33949. sp_521_mont_mul_9(y, t1, t5, p521_mod, p521_mp_mod);
  33950. sp_521_mont_mul_9(t5, t5, t2, p521_mod, p521_mp_mod);
  33951. /* Z3 = H*Z1*Z2 */
  33952. sp_521_mont_mul_9(z, p->z, t2, p521_mod, p521_mp_mod);
  33953. sp_521_mont_mul_9(z, z, q->z, p521_mod, p521_mp_mod);
  33954. sp_521_mont_sqr_9(x, t4, p521_mod, p521_mp_mod);
  33955. sp_521_mont_sub_9(x, x, t5, p521_mod);
  33956. sp_521_mont_mul_9(t5, t5, t3, p521_mod, p521_mp_mod);
  33957. sp_521_mont_dbl_9(t3, y, p521_mod);
  33958. sp_521_mont_sub_9(x, x, t3, p521_mod);
  33959. /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
  33960. sp_521_mont_sub_9(y, y, x, p521_mod);
  33961. sp_521_mont_mul_9(y, y, t4, p521_mod, p521_mp_mod);
  33962. sp_521_mont_sub_9(y, y, t5, p521_mod);
  33963. {
  33964. int i;
  33965. sp_digit maskp = 0 - (q->infinity & (!p->infinity));
  33966. sp_digit maskq = 0 - (p->infinity & (!q->infinity));
  33967. sp_digit maskt = ~(maskp | maskq);
  33968. sp_digit inf = (sp_digit)(p->infinity & q->infinity);
  33969. for (i = 0; i < 9; i++) {
  33970. r->x[i] = (p->x[i] & maskp) | (q->x[i] & maskq) |
  33971. (x[i] & maskt);
  33972. }
  33973. for (i = 0; i < 9; i++) {
  33974. r->y[i] = (p->y[i] & maskp) | (q->y[i] & maskq) |
  33975. (y[i] & maskt);
  33976. }
  33977. for (i = 0; i < 9; i++) {
  33978. r->z[i] = (p->z[i] & maskp) | (q->z[i] & maskq) |
  33979. (z[i] & maskt);
  33980. }
  33981. r->z[0] |= inf;
  33982. r->infinity = (word32)inf;
  33983. }
  33984. }
  33985. }
  33986. #ifdef WOLFSSL_SP_NONBLOCK
  33987. typedef struct sp_521_proj_point_add_9_ctx {
  33988. int state;
  33989. sp_521_proj_point_dbl_9_ctx dbl_ctx;
  33990. const sp_point_521* ap[2];
  33991. sp_point_521* rp[2];
  33992. sp_digit* t1;
  33993. sp_digit* t2;
  33994. sp_digit* t3;
  33995. sp_digit* t4;
  33996. sp_digit* t5;
  33997. sp_digit* t6;
  33998. sp_digit* x;
  33999. sp_digit* y;
  34000. sp_digit* z;
  34001. } sp_521_proj_point_add_9_ctx;
  34002. /* Add two Montgomery form projective points.
  34003. *
  34004. * r Result of addition.
  34005. * p First point to add.
  34006. * q Second point to add.
  34007. * t Temporary ordinate data.
  34008. */
  34009. static int sp_521_proj_point_add_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
  34010. const sp_point_521* p, const sp_point_521* q, sp_digit* t)
  34011. {
  34012. int err = FP_WOULDBLOCK;
  34013. sp_521_proj_point_add_9_ctx* ctx = (sp_521_proj_point_add_9_ctx*)sp_ctx->data;
  34014. /* Ensure only the first point is the same as the result. */
  34015. if (q == r) {
  34016. const sp_point_521* a = p;
  34017. p = q;
  34018. q = a;
  34019. }
  34020. typedef char ctx_size_test[sizeof(sp_521_proj_point_add_9_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  34021. (void)sizeof(ctx_size_test);
  34022. switch (ctx->state) {
  34023. case 0: /* INIT */
  34024. ctx->t6 = t;
  34025. ctx->t1 = t + 2*9;
  34026. ctx->t2 = t + 4*9;
  34027. ctx->t3 = t + 6*9;
  34028. ctx->t4 = t + 8*9;
  34029. ctx->t5 = t + 10*9;
  34030. ctx->x = ctx->t6;
  34031. ctx->y = ctx->t1;
  34032. ctx->z = ctx->t2;
  34033. ctx->state = 1;
  34034. break;
  34035. case 1:
  34036. /* U1 = X1*Z2^2 */
  34037. sp_521_mont_sqr_9(ctx->t1, q->z, p521_mod, p521_mp_mod);
  34038. ctx->state = 2;
  34039. break;
  34040. case 2:
  34041. sp_521_mont_mul_9(ctx->t3, ctx->t1, q->z, p521_mod, p521_mp_mod);
  34042. ctx->state = 3;
  34043. break;
  34044. case 3:
  34045. sp_521_mont_mul_9(ctx->t1, ctx->t1, p->x, p521_mod, p521_mp_mod);
  34046. ctx->state = 4;
  34047. break;
  34048. case 4:
  34049. /* U2 = X2*Z1^2 */
  34050. sp_521_mont_sqr_9(ctx->t2, p->z, p521_mod, p521_mp_mod);
  34051. ctx->state = 5;
  34052. break;
  34053. case 5:
  34054. sp_521_mont_mul_9(ctx->t4, ctx->t2, p->z, p521_mod, p521_mp_mod);
  34055. ctx->state = 6;
  34056. break;
  34057. case 6:
  34058. sp_521_mont_mul_9(ctx->t2, ctx->t2, q->x, p521_mod, p521_mp_mod);
  34059. ctx->state = 7;
  34060. break;
  34061. case 7:
  34062. /* S1 = Y1*Z2^3 */
  34063. sp_521_mont_mul_9(ctx->t3, ctx->t3, p->y, p521_mod, p521_mp_mod);
  34064. ctx->state = 8;
  34065. break;
  34066. case 8:
  34067. /* S2 = Y2*Z1^3 */
  34068. sp_521_mont_mul_9(ctx->t4, ctx->t4, q->y, p521_mod, p521_mp_mod);
  34069. ctx->state = 9;
  34070. break;
  34071. case 9:
  34072. /* Check double */
  34073. if ((~p->infinity) & (~q->infinity) &
  34074. sp_521_cmp_equal_9(ctx->t2, ctx->t1) &
  34075. sp_521_cmp_equal_9(ctx->t4, ctx->t3)) {
  34076. XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx));
  34077. sp_521_proj_point_dbl_9(r, p, t);
  34078. ctx->state = 25;
  34079. }
  34080. else {
  34081. ctx->state = 10;
  34082. }
  34083. break;
  34084. case 10:
  34085. /* H = U2 - U1 */
  34086. sp_521_mont_sub_9(ctx->t2, ctx->t2, ctx->t1, p521_mod);
  34087. ctx->state = 11;
  34088. break;
  34089. case 11:
  34090. /* R = S2 - S1 */
  34091. sp_521_mont_sub_9(ctx->t4, ctx->t4, ctx->t3, p521_mod);
  34092. ctx->state = 12;
  34093. break;
  34094. case 12:
  34095. /* X3 = R^2 - H^3 - 2*U1*H^2 */
  34096. sp_521_mont_sqr_9(ctx->t5, ctx->t2, p521_mod, p521_mp_mod);
  34097. ctx->state = 13;
  34098. break;
  34099. case 13:
  34100. sp_521_mont_mul_9(ctx->y, ctx->t1, ctx->t5, p521_mod, p521_mp_mod);
  34101. ctx->state = 14;
  34102. break;
  34103. case 14:
  34104. sp_521_mont_mul_9(ctx->t5, ctx->t5, ctx->t2, p521_mod, p521_mp_mod);
  34105. ctx->state = 15;
  34106. break;
  34107. case 15:
  34108. /* Z3 = H*Z1*Z2 */
  34109. sp_521_mont_mul_9(ctx->z, p->z, ctx->t2, p521_mod, p521_mp_mod);
  34110. ctx->state = 16;
  34111. break;
  34112. case 16:
  34113. sp_521_mont_mul_9(ctx->z, ctx->z, q->z, p521_mod, p521_mp_mod);
  34114. ctx->state = 17;
  34115. break;
  34116. case 17:
  34117. sp_521_mont_sqr_9(ctx->x, ctx->t4, p521_mod, p521_mp_mod);
  34118. ctx->state = 18;
  34119. break;
  34120. case 18:
  34121. sp_521_mont_sub_9(ctx->x, ctx->x, ctx->t5, p521_mod);
  34122. ctx->state = 19;
  34123. break;
  34124. case 19:
  34125. sp_521_mont_mul_9(ctx->t5, ctx->t5, ctx->t3, p521_mod, p521_mp_mod);
  34126. ctx->state = 20;
  34127. break;
  34128. case 20:
  34129. sp_521_mont_dbl_9(ctx->t3, ctx->y, p521_mod);
  34130. sp_521_mont_sub_9(ctx->x, ctx->x, ctx->t3, p521_mod);
  34131. ctx->state = 21;
  34132. break;
  34133. case 21:
  34134. /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
  34135. sp_521_mont_sub_9(ctx->y, ctx->y, ctx->x, p521_mod);
  34136. ctx->state = 22;
  34137. break;
  34138. case 22:
  34139. sp_521_mont_mul_9(ctx->y, ctx->y, ctx->t4, p521_mod, p521_mp_mod);
  34140. ctx->state = 23;
  34141. break;
  34142. case 23:
  34143. sp_521_mont_sub_9(ctx->y, ctx->y, ctx->t5, p521_mod);
  34144. ctx->state = 24;
  34145. break;
  34146. case 24:
  34147. {
  34148. {
  34149. int i;
  34150. sp_digit maskp = 0 - (q->infinity & (!p->infinity));
  34151. sp_digit maskq = 0 - (p->infinity & (!q->infinity));
  34152. sp_digit maskt = ~(maskp | maskq);
  34153. sp_digit inf = (sp_digit)(p->infinity & q->infinity);
  34154. for (i = 0; i < 9; i++) {
  34155. r->x[i] = (p->x[i] & maskp) | (q->x[i] & maskq) |
  34156. (ctx->x[i] & maskt);
  34157. }
  34158. for (i = 0; i < 9; i++) {
  34159. r->y[i] = (p->y[i] & maskp) | (q->y[i] & maskq) |
  34160. (ctx->y[i] & maskt);
  34161. }
  34162. for (i = 0; i < 9; i++) {
  34163. r->z[i] = (p->z[i] & maskp) | (q->z[i] & maskq) |
  34164. (ctx->z[i] & maskt);
  34165. }
  34166. r->z[0] |= inf;
  34167. r->infinity = (word32)inf;
  34168. }
  34169. ctx->state = 25;
  34170. break;
  34171. }
  34172. case 25:
  34173. err = MP_OKAY;
  34174. break;
  34175. }
  34176. if (err == MP_OKAY && ctx->state != 25) {
  34177. err = FP_WOULDBLOCK;
  34178. }
  34179. return err;
  34180. }
  34181. #endif /* WOLFSSL_SP_NONBLOCK */
  34182. /* Multiply a number by Montgomery normalizer mod modulus (prime).
  34183. *
  34184. * r The resulting Montgomery form number.
  34185. * a The number to convert.
  34186. * m The modulus (prime).
  34187. * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise.
  34188. */
  34189. static int sp_521_mod_mul_norm_9(sp_digit* r, const sp_digit* a, const sp_digit* m)
  34190. {
  34191. (void)m;
  34192. if (r != a) {
  34193. XMEMCPY(r, a, 9 * sizeof(sp_digit));
  34194. }
  34195. return MP_OKAY;
  34196. }
  34197. #ifdef WOLFSSL_SP_SMALL
  34198. /* Multiply the point by the scalar and return the result.
  34199. * If map is true then convert result to affine coordinates.
  34200. *
  34201. * Small implementation using add and double that is cache attack resistant but
  34202. * allocates memory rather than use large stacks.
  34203. * 521 adds and doubles.
  34204. *
  34205. * r Resulting point.
  34206. * g Point to multiply.
  34207. * k Scalar to multiply by.
  34208. * map Indicates whether to convert result to affine.
  34209. * ct Constant time required.
  34210. * heap Heap to use for allocation.
  34211. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  34212. */
  34213. static int sp_521_ecc_mulmod_9(sp_point_521* r, const sp_point_521* g,
  34214. const sp_digit* k, int map, int ct, void* heap)
  34215. {
  34216. #ifdef WOLFSSL_SP_SMALL_STACK
  34217. sp_point_521* t = NULL;
  34218. sp_digit* tmp = NULL;
  34219. #else
  34220. sp_point_521 t[3];
  34221. sp_digit tmp[2 * 9 * 6];
  34222. #endif
  34223. sp_digit n;
  34224. int i;
  34225. int c;
  34226. int y;
  34227. int err = MP_OKAY;
  34228. /* Implementation is constant time. */
  34229. (void)ct;
  34230. (void)heap;
  34231. #ifdef WOLFSSL_SP_SMALL_STACK
  34232. t = (sp_point_521*)XMALLOC(sizeof(sp_point_521) * 3, heap,
  34233. DYNAMIC_TYPE_ECC);
  34234. if (t == NULL)
  34235. err = MEMORY_E;
  34236. if (err == MP_OKAY) {
  34237. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 9 * 6, heap,
  34238. DYNAMIC_TYPE_ECC);
  34239. if (tmp == NULL)
  34240. err = MEMORY_E;
  34241. }
  34242. #endif
  34243. if (err == MP_OKAY) {
  34244. XMEMSET(t, 0, sizeof(sp_point_521) * 3);
  34245. /* t[0] = {0, 0, 1} * norm */
  34246. t[0].infinity = 1;
  34247. /* t[1] = {g->x, g->y, g->z} * norm */
  34248. err = sp_521_mod_mul_norm_9(t[1].x, g->x, p521_mod);
  34249. }
  34250. if (err == MP_OKAY)
  34251. err = sp_521_mod_mul_norm_9(t[1].y, g->y, p521_mod);
  34252. if (err == MP_OKAY)
  34253. err = sp_521_mod_mul_norm_9(t[1].z, g->z, p521_mod);
  34254. if (err == MP_OKAY) {
  34255. i = 8;
  34256. c = 57;
  34257. n = k[i--] << (58 - c);
  34258. for (; ; c--) {
  34259. if (c == 0) {
  34260. if (i == -1)
  34261. break;
  34262. n = k[i--];
  34263. c = 58;
  34264. }
  34265. y = (n >> 57) & 1;
  34266. n <<= 1;
  34267. sp_521_proj_point_add_9(&t[y^1], &t[0], &t[1], tmp);
  34268. XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) +
  34269. ((size_t)&t[1] & addr_mask[y])),
  34270. sizeof(sp_point_521));
  34271. sp_521_proj_point_dbl_9(&t[2], &t[2], tmp);
  34272. XMEMCPY((void*)(((size_t)&t[0] & addr_mask[y^1]) +
  34273. ((size_t)&t[1] & addr_mask[y])), &t[2],
  34274. sizeof(sp_point_521));
  34275. }
  34276. if (map != 0) {
  34277. sp_521_map_9(r, &t[0], tmp);
  34278. }
  34279. else {
  34280. XMEMCPY(r, &t[0], sizeof(sp_point_521));
  34281. }
  34282. }
  34283. #ifdef WOLFSSL_SP_SMALL_STACK
  34284. if (tmp != NULL)
  34285. #endif
  34286. {
  34287. ForceZero(tmp, sizeof(sp_digit) * 2 * 9 * 6);
  34288. #ifdef WOLFSSL_SP_SMALL_STACK
  34289. XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
  34290. #endif
  34291. }
  34292. #ifdef WOLFSSL_SP_SMALL_STACK
  34293. if (t != NULL)
  34294. #endif
  34295. {
  34296. ForceZero(t, sizeof(sp_point_521) * 3);
  34297. #ifdef WOLFSSL_SP_SMALL_STACK
  34298. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  34299. #endif
  34300. }
  34301. return err;
  34302. }
  34303. #ifdef WOLFSSL_SP_NONBLOCK
  34304. typedef struct sp_521_ecc_mulmod_9_ctx {
  34305. int state;
  34306. union {
  34307. sp_521_proj_point_dbl_9_ctx dbl_ctx;
  34308. sp_521_proj_point_add_9_ctx add_ctx;
  34309. };
  34310. sp_point_521 t[3];
  34311. sp_digit tmp[2 * 9 * 6];
  34312. sp_digit n;
  34313. int i;
  34314. int c;
  34315. int y;
  34316. } sp_521_ecc_mulmod_9_ctx;
  34317. static int sp_521_ecc_mulmod_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
  34318. const sp_point_521* g, const sp_digit* k, int map, int ct, void* heap)
  34319. {
  34320. int err = FP_WOULDBLOCK;
  34321. sp_521_ecc_mulmod_9_ctx* ctx = (sp_521_ecc_mulmod_9_ctx*)sp_ctx->data;
  34322. typedef char ctx_size_test[sizeof(sp_521_ecc_mulmod_9_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  34323. (void)sizeof(ctx_size_test);
  34324. /* Implementation is constant time. */
  34325. (void)ct;
  34326. switch (ctx->state) {
  34327. case 0: /* INIT */
  34328. XMEMSET(ctx->t, 0, sizeof(sp_point_521) * 3);
  34329. ctx->i = 8;
  34330. ctx->c = 57;
  34331. ctx->n = k[ctx->i--] << (58 - ctx->c);
  34332. /* t[0] = {0, 0, 1} * norm */
  34333. ctx->t[0].infinity = 1;
  34334. ctx->state = 1;
  34335. break;
  34336. case 1: /* T1X */
  34337. /* t[1] = {g->x, g->y, g->z} * norm */
  34338. err = sp_521_mod_mul_norm_9(ctx->t[1].x, g->x, p521_mod);
  34339. ctx->state = 2;
  34340. break;
  34341. case 2: /* T1Y */
  34342. err = sp_521_mod_mul_norm_9(ctx->t[1].y, g->y, p521_mod);
  34343. ctx->state = 3;
  34344. break;
  34345. case 3: /* T1Z */
  34346. err = sp_521_mod_mul_norm_9(ctx->t[1].z, g->z, p521_mod);
  34347. ctx->state = 4;
  34348. break;
  34349. case 4: /* ADDPREP */
  34350. if (ctx->c == 0) {
  34351. if (ctx->i == -1) {
  34352. ctx->state = 7;
  34353. break;
  34354. }
  34355. ctx->n = k[ctx->i--];
  34356. ctx->c = 58;
  34357. }
  34358. ctx->y = (ctx->n >> 57) & 1;
  34359. ctx->n <<= 1;
  34360. XMEMSET(&ctx->add_ctx, 0, sizeof(ctx->add_ctx));
  34361. ctx->state = 5;
  34362. break;
  34363. case 5: /* ADD */
  34364. err = sp_521_proj_point_add_9_nb((sp_ecc_ctx_t*)&ctx->add_ctx,
  34365. &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp);
  34366. if (err == MP_OKAY) {
  34367. XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) +
  34368. ((size_t)&ctx->t[1] & addr_mask[ctx->y])),
  34369. sizeof(sp_point_521));
  34370. XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx));
  34371. ctx->state = 6;
  34372. }
  34373. break;
  34374. case 6: /* DBL */
  34375. err = sp_521_proj_point_dbl_9_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2],
  34376. &ctx->t[2], ctx->tmp);
  34377. if (err == MP_OKAY) {
  34378. XMEMCPY((void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) +
  34379. ((size_t)&ctx->t[1] & addr_mask[ctx->y])), &ctx->t[2],
  34380. sizeof(sp_point_521));
  34381. ctx->state = 4;
  34382. ctx->c--;
  34383. }
  34384. break;
  34385. case 7: /* MAP */
  34386. if (map != 0) {
  34387. sp_521_map_9(r, &ctx->t[0], ctx->tmp);
  34388. }
  34389. else {
  34390. XMEMCPY(r, &ctx->t[0], sizeof(sp_point_521));
  34391. }
  34392. err = MP_OKAY;
  34393. break;
  34394. }
  34395. if (err == MP_OKAY && ctx->state != 7) {
  34396. err = FP_WOULDBLOCK;
  34397. }
  34398. if (err != FP_WOULDBLOCK) {
  34399. ForceZero(ctx->tmp, sizeof(ctx->tmp));
  34400. ForceZero(ctx->t, sizeof(ctx->t));
  34401. }
  34402. (void)heap;
  34403. return err;
  34404. }
  34405. #endif /* WOLFSSL_SP_NONBLOCK */
  34406. #else
  34407. /* A table entry for pre-computed points. */
  34408. typedef struct sp_table_entry_521 {
  34409. sp_digit x[9];
  34410. sp_digit y[9];
  34411. } sp_table_entry_521;
  34412. /* Conditionally copy a into r using the mask m.
  34413. * m is -1 to copy and 0 when not.
  34414. *
  34415. * r A single precision number to copy over.
  34416. * a A single precision number to copy.
  34417. * m Mask value to apply.
  34418. */
  34419. static void sp_521_cond_copy_9(sp_digit* r, const sp_digit* a, const sp_digit m)
  34420. {
  34421. sp_digit t[9];
  34422. #ifdef WOLFSSL_SP_SMALL
  34423. int i;
  34424. for (i = 0; i < 9; i++) {
  34425. t[i] = r[i] ^ a[i];
  34426. }
  34427. for (i = 0; i < 9; i++) {
  34428. r[i] ^= t[i] & m;
  34429. }
  34430. #else
  34431. t[ 0] = r[ 0] ^ a[ 0];
  34432. t[ 1] = r[ 1] ^ a[ 1];
  34433. t[ 2] = r[ 2] ^ a[ 2];
  34434. t[ 3] = r[ 3] ^ a[ 3];
  34435. t[ 4] = r[ 4] ^ a[ 4];
  34436. t[ 5] = r[ 5] ^ a[ 5];
  34437. t[ 6] = r[ 6] ^ a[ 6];
  34438. t[ 7] = r[ 7] ^ a[ 7];
  34439. t[ 8] = r[ 8] ^ a[ 8];
  34440. r[ 0] ^= t[ 0] & m;
  34441. r[ 1] ^= t[ 1] & m;
  34442. r[ 2] ^= t[ 2] & m;
  34443. r[ 3] ^= t[ 3] & m;
  34444. r[ 4] ^= t[ 4] & m;
  34445. r[ 5] ^= t[ 5] & m;
  34446. r[ 6] ^= t[ 6] & m;
  34447. r[ 7] ^= t[ 7] & m;
  34448. r[ 8] ^= t[ 8] & m;
  34449. #endif /* WOLFSSL_SP_SMALL */
  34450. }
  34451. /* Double the Montgomery form projective point p a number of times.
  34452. *
  34453. * r Result of repeated doubling of point.
  34454. * p Point to double.
  34455. * n Number of times to double
  34456. * t Temporary ordinate data.
  34457. */
  34458. static void sp_521_proj_point_dbl_n_9(sp_point_521* p, int i,
  34459. sp_digit* t)
  34460. {
  34461. sp_digit* w = t;
  34462. sp_digit* a = t + 2*9;
  34463. sp_digit* b = t + 4*9;
  34464. sp_digit* t1 = t + 6*9;
  34465. sp_digit* t2 = t + 8*9;
  34466. sp_digit* x;
  34467. sp_digit* y;
  34468. sp_digit* z;
  34469. volatile int n = i;
  34470. x = p->x;
  34471. y = p->y;
  34472. z = p->z;
  34473. /* Y = 2*Y */
  34474. sp_521_mont_dbl_9(y, y, p521_mod);
  34475. /* W = Z^4 */
  34476. sp_521_mont_sqr_9(w, z, p521_mod, p521_mp_mod);
  34477. sp_521_mont_sqr_9(w, w, p521_mod, p521_mp_mod);
  34478. #ifndef WOLFSSL_SP_SMALL
  34479. while (--n > 0)
  34480. #else
  34481. while (--n >= 0)
  34482. #endif
  34483. {
  34484. /* A = 3*(X^2 - W) */
  34485. sp_521_mont_sqr_9(t1, x, p521_mod, p521_mp_mod);
  34486. sp_521_mont_sub_9(t1, t1, w, p521_mod);
  34487. sp_521_mont_tpl_9(a, t1, p521_mod);
  34488. /* B = X*Y^2 */
  34489. sp_521_mont_sqr_9(t1, y, p521_mod, p521_mp_mod);
  34490. sp_521_mont_mul_9(b, t1, x, p521_mod, p521_mp_mod);
  34491. /* X = A^2 - 2B */
  34492. sp_521_mont_sqr_9(x, a, p521_mod, p521_mp_mod);
  34493. sp_521_mont_dbl_9(t2, b, p521_mod);
  34494. sp_521_mont_sub_9(x, x, t2, p521_mod);
  34495. /* B = 2.(B - X) */
  34496. sp_521_mont_sub_9(t2, b, x, p521_mod);
  34497. sp_521_mont_dbl_9(b, t2, p521_mod);
  34498. /* Z = Z*Y */
  34499. sp_521_mont_mul_9(z, z, y, p521_mod, p521_mp_mod);
  34500. /* t1 = Y^4 */
  34501. sp_521_mont_sqr_9(t1, t1, p521_mod, p521_mp_mod);
  34502. #ifdef WOLFSSL_SP_SMALL
  34503. if (n != 0)
  34504. #endif
  34505. {
  34506. /* W = W*Y^4 */
  34507. sp_521_mont_mul_9(w, w, t1, p521_mod, p521_mp_mod);
  34508. }
  34509. /* y = 2*A*(B - X) - Y^4 */
  34510. sp_521_mont_mul_9(y, b, a, p521_mod, p521_mp_mod);
  34511. sp_521_mont_sub_9(y, y, t1, p521_mod);
  34512. }
  34513. #ifndef WOLFSSL_SP_SMALL
  34514. /* A = 3*(X^2 - W) */
  34515. sp_521_mont_sqr_9(t1, x, p521_mod, p521_mp_mod);
  34516. sp_521_mont_sub_9(t1, t1, w, p521_mod);
  34517. sp_521_mont_tpl_9(a, t1, p521_mod);
  34518. /* B = X*Y^2 */
  34519. sp_521_mont_sqr_9(t1, y, p521_mod, p521_mp_mod);
  34520. sp_521_mont_mul_9(b, t1, x, p521_mod, p521_mp_mod);
  34521. /* X = A^2 - 2B */
  34522. sp_521_mont_sqr_9(x, a, p521_mod, p521_mp_mod);
  34523. sp_521_mont_dbl_9(t2, b, p521_mod);
  34524. sp_521_mont_sub_9(x, x, t2, p521_mod);
  34525. /* B = 2.(B - X) */
  34526. sp_521_mont_sub_9(t2, b, x, p521_mod);
  34527. sp_521_mont_dbl_9(b, t2, p521_mod);
  34528. /* Z = Z*Y */
  34529. sp_521_mont_mul_9(z, z, y, p521_mod, p521_mp_mod);
  34530. /* t1 = Y^4 */
  34531. sp_521_mont_sqr_9(t1, t1, p521_mod, p521_mp_mod);
  34532. /* y = 2*A*(B - X) - Y^4 */
  34533. sp_521_mont_mul_9(y, b, a, p521_mod, p521_mp_mod);
  34534. sp_521_mont_sub_9(y, y, t1, p521_mod);
  34535. #endif /* WOLFSSL_SP_SMALL */
  34536. /* Y = Y/2 */
  34537. sp_521_mont_div2_9(y, y, p521_mod);
  34538. }
  34539. /* Double the Montgomery form projective point p a number of times.
  34540. *
  34541. * r Result of repeated doubling of point.
  34542. * p Point to double.
  34543. * n Number of times to double
  34544. * t Temporary ordinate data.
  34545. */
  34546. static void sp_521_proj_point_dbl_n_store_9(sp_point_521* r,
  34547. const sp_point_521* p, int n, int m, sp_digit* t)
  34548. {
  34549. sp_digit* w = t;
  34550. sp_digit* a = t + 2*9;
  34551. sp_digit* b = t + 4*9;
  34552. sp_digit* t1 = t + 6*9;
  34553. sp_digit* t2 = t + 8*9;
  34554. sp_digit* x = r[2*m].x;
  34555. sp_digit* y = r[(1<<n)*m].y;
  34556. sp_digit* z = r[2*m].z;
  34557. int i;
  34558. int j;
  34559. for (i=0; i<9; i++) {
  34560. x[i] = p->x[i];
  34561. }
  34562. for (i=0; i<9; i++) {
  34563. y[i] = p->y[i];
  34564. }
  34565. for (i=0; i<9; i++) {
  34566. z[i] = p->z[i];
  34567. }
  34568. /* Y = 2*Y */
  34569. sp_521_mont_dbl_9(y, y, p521_mod);
  34570. /* W = Z^4 */
  34571. sp_521_mont_sqr_9(w, z, p521_mod, p521_mp_mod);
  34572. sp_521_mont_sqr_9(w, w, p521_mod, p521_mp_mod);
  34573. j = m;
  34574. for (i=1; i<=n; i++) {
  34575. j *= 2;
  34576. /* A = 3*(X^2 - W) */
  34577. sp_521_mont_sqr_9(t1, x, p521_mod, p521_mp_mod);
  34578. sp_521_mont_sub_9(t1, t1, w, p521_mod);
  34579. sp_521_mont_tpl_9(a, t1, p521_mod);
  34580. /* B = X*Y^2 */
  34581. sp_521_mont_sqr_9(t1, y, p521_mod, p521_mp_mod);
  34582. sp_521_mont_mul_9(b, t1, x, p521_mod, p521_mp_mod);
  34583. x = r[j].x;
  34584. /* X = A^2 - 2B */
  34585. sp_521_mont_sqr_9(x, a, p521_mod, p521_mp_mod);
  34586. sp_521_mont_dbl_9(t2, b, p521_mod);
  34587. sp_521_mont_sub_9(x, x, t2, p521_mod);
  34588. /* B = 2.(B - X) */
  34589. sp_521_mont_sub_9(t2, b, x, p521_mod);
  34590. sp_521_mont_dbl_9(b, t2, p521_mod);
  34591. /* Z = Z*Y */
  34592. sp_521_mont_mul_9(r[j].z, z, y, p521_mod, p521_mp_mod);
  34593. z = r[j].z;
  34594. /* t1 = Y^4 */
  34595. sp_521_mont_sqr_9(t1, t1, p521_mod, p521_mp_mod);
  34596. if (i != n) {
  34597. /* W = W*Y^4 */
  34598. sp_521_mont_mul_9(w, w, t1, p521_mod, p521_mp_mod);
  34599. }
  34600. /* y = 2*A*(B - X) - Y^4 */
  34601. sp_521_mont_mul_9(y, b, a, p521_mod, p521_mp_mod);
  34602. sp_521_mont_sub_9(y, y, t1, p521_mod);
  34603. /* Y = Y/2 */
  34604. sp_521_mont_div2_9(r[j].y, y, p521_mod);
  34605. r[j].infinity = 0;
  34606. }
  34607. }
  34608. /* Add two Montgomery form projective points.
  34609. *
  34610. * ra Result of addition.
  34611. * rs Result of subtraction.
  34612. * p First point to add.
  34613. * q Second point to add.
  34614. * t Temporary ordinate data.
  34615. */
  34616. static void sp_521_proj_point_add_sub_9(sp_point_521* ra,
  34617. sp_point_521* rs, const sp_point_521* p, const sp_point_521* q,
  34618. sp_digit* t)
  34619. {
  34620. sp_digit* t1 = t;
  34621. sp_digit* t2 = t + 2*9;
  34622. sp_digit* t3 = t + 4*9;
  34623. sp_digit* t4 = t + 6*9;
  34624. sp_digit* t5 = t + 8*9;
  34625. sp_digit* t6 = t + 10*9;
  34626. sp_digit* xa = ra->x;
  34627. sp_digit* ya = ra->y;
  34628. sp_digit* za = ra->z;
  34629. sp_digit* xs = rs->x;
  34630. sp_digit* ys = rs->y;
  34631. sp_digit* zs = rs->z;
  34632. XMEMCPY(xa, p->x, sizeof(p->x) / 2);
  34633. XMEMCPY(ya, p->y, sizeof(p->y) / 2);
  34634. XMEMCPY(za, p->z, sizeof(p->z) / 2);
  34635. ra->infinity = 0;
  34636. rs->infinity = 0;
  34637. /* U1 = X1*Z2^2 */
  34638. sp_521_mont_sqr_9(t1, q->z, p521_mod, p521_mp_mod);
  34639. sp_521_mont_mul_9(t3, t1, q->z, p521_mod, p521_mp_mod);
  34640. sp_521_mont_mul_9(t1, t1, xa, p521_mod, p521_mp_mod);
  34641. /* U2 = X2*Z1^2 */
  34642. sp_521_mont_sqr_9(t2, za, p521_mod, p521_mp_mod);
  34643. sp_521_mont_mul_9(t4, t2, za, p521_mod, p521_mp_mod);
  34644. sp_521_mont_mul_9(t2, t2, q->x, p521_mod, p521_mp_mod);
  34645. /* S1 = Y1*Z2^3 */
  34646. sp_521_mont_mul_9(t3, t3, ya, p521_mod, p521_mp_mod);
  34647. /* S2 = Y2*Z1^3 */
  34648. sp_521_mont_mul_9(t4, t4, q->y, p521_mod, p521_mp_mod);
  34649. /* H = U2 - U1 */
  34650. sp_521_mont_sub_9(t2, t2, t1, p521_mod);
  34651. /* RS = S2 + S1 */
  34652. sp_521_mont_add_9(t6, t4, t3, p521_mod);
  34653. /* R = S2 - S1 */
  34654. sp_521_mont_sub_9(t4, t4, t3, p521_mod);
  34655. /* Z3 = H*Z1*Z2 */
  34656. /* ZS = H*Z1*Z2 */
  34657. sp_521_mont_mul_9(za, za, q->z, p521_mod, p521_mp_mod);
  34658. sp_521_mont_mul_9(za, za, t2, p521_mod, p521_mp_mod);
  34659. XMEMCPY(zs, za, sizeof(p->z)/2);
  34660. /* X3 = R^2 - H^3 - 2*U1*H^2 */
  34661. /* XS = RS^2 - H^3 - 2*U1*H^2 */
  34662. sp_521_mont_sqr_9(xa, t4, p521_mod, p521_mp_mod);
  34663. sp_521_mont_sqr_9(xs, t6, p521_mod, p521_mp_mod);
  34664. sp_521_mont_sqr_9(t5, t2, p521_mod, p521_mp_mod);
  34665. sp_521_mont_mul_9(ya, t1, t5, p521_mod, p521_mp_mod);
  34666. sp_521_mont_mul_9(t5, t5, t2, p521_mod, p521_mp_mod);
  34667. sp_521_mont_sub_9(xa, xa, t5, p521_mod);
  34668. sp_521_mont_sub_9(xs, xs, t5, p521_mod);
  34669. sp_521_mont_dbl_9(t1, ya, p521_mod);
  34670. sp_521_mont_sub_9(xa, xa, t1, p521_mod);
  34671. sp_521_mont_sub_9(xs, xs, t1, p521_mod);
  34672. /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
  34673. /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */
  34674. sp_521_mont_sub_9(ys, ya, xs, p521_mod);
  34675. sp_521_mont_sub_9(ya, ya, xa, p521_mod);
  34676. sp_521_mont_mul_9(ya, ya, t4, p521_mod, p521_mp_mod);
  34677. sp_521_sub_9(t6, p521_mod, t6);
  34678. sp_521_mont_mul_9(ys, ys, t6, p521_mod, p521_mp_mod);
  34679. sp_521_mont_mul_9(t5, t5, t3, p521_mod, p521_mp_mod);
  34680. sp_521_mont_sub_9(ya, ya, t5, p521_mod);
  34681. sp_521_mont_sub_9(ys, ys, t5, p521_mod);
  34682. }
  34683. /* Structure used to describe recoding of scalar multiplication. */
  34684. typedef struct ecc_recode_521 {
  34685. /* Index into pre-computation table. */
  34686. uint8_t i;
  34687. /* Use the negative of the point. */
  34688. uint8_t neg;
  34689. } ecc_recode_521;
  34690. /* The index into pre-computation table to use. */
  34691. static const uint8_t recode_index_9_6[66] = {
  34692. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  34693. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  34694. 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
  34695. 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
  34696. 0, 1,
  34697. };
  34698. /* Whether to negate y-ordinate. */
  34699. static const uint8_t recode_neg_9_6[66] = {
  34700. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  34701. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  34702. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  34703. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  34704. 0, 0,
  34705. };
  34706. /* Recode the scalar for multiplication using pre-computed values and
  34707. * subtraction.
  34708. *
  34709. * k Scalar to multiply by.
  34710. * v Vector of operations to perform.
  34711. */
  34712. static void sp_521_ecc_recode_6_9(const sp_digit* k, ecc_recode_521* v)
  34713. {
  34714. int i;
  34715. int j;
  34716. uint8_t y;
  34717. int carry = 0;
  34718. int o;
  34719. sp_digit n;
  34720. j = 0;
  34721. n = k[j];
  34722. o = 0;
  34723. for (i=0; i<87; i++) {
  34724. y = (int8_t)n;
  34725. if (o + 6 < 58) {
  34726. y &= 0x3f;
  34727. n >>= 6;
  34728. o += 6;
  34729. }
  34730. else if (o + 6 == 58) {
  34731. n >>= 6;
  34732. if (++j < 9)
  34733. n = k[j];
  34734. o = 0;
  34735. }
  34736. else if (++j < 9) {
  34737. n = k[j];
  34738. y |= (uint8_t)((n << (58 - o)) & 0x3f);
  34739. o -= 52;
  34740. n >>= o;
  34741. }
  34742. y += (uint8_t)carry;
  34743. v[i].i = recode_index_9_6[y];
  34744. v[i].neg = recode_neg_9_6[y];
  34745. carry = (y >> 6) + v[i].neg;
  34746. }
  34747. }
  34748. #ifndef WC_NO_CACHE_RESISTANT
  34749. /* Touch each possible point that could be being copied.
  34750. *
  34751. * r Point to copy into.
  34752. * table Table - start of the entries to access
  34753. * idx Index of entry to retrieve.
  34754. */
  34755. static void sp_521_get_point_33_9(sp_point_521* r, const sp_point_521* table,
  34756. int idx)
  34757. {
  34758. int i;
  34759. sp_digit mask;
  34760. r->x[0] = 0;
  34761. r->x[1] = 0;
  34762. r->x[2] = 0;
  34763. r->x[3] = 0;
  34764. r->x[4] = 0;
  34765. r->x[5] = 0;
  34766. r->x[6] = 0;
  34767. r->x[7] = 0;
  34768. r->x[8] = 0;
  34769. r->y[0] = 0;
  34770. r->y[1] = 0;
  34771. r->y[2] = 0;
  34772. r->y[3] = 0;
  34773. r->y[4] = 0;
  34774. r->y[5] = 0;
  34775. r->y[6] = 0;
  34776. r->y[7] = 0;
  34777. r->y[8] = 0;
  34778. r->z[0] = 0;
  34779. r->z[1] = 0;
  34780. r->z[2] = 0;
  34781. r->z[3] = 0;
  34782. r->z[4] = 0;
  34783. r->z[5] = 0;
  34784. r->z[6] = 0;
  34785. r->z[7] = 0;
  34786. r->z[8] = 0;
  34787. for (i = 1; i < 33; i++) {
  34788. mask = 0 - (i == idx);
  34789. r->x[0] |= mask & table[i].x[0];
  34790. r->x[1] |= mask & table[i].x[1];
  34791. r->x[2] |= mask & table[i].x[2];
  34792. r->x[3] |= mask & table[i].x[3];
  34793. r->x[4] |= mask & table[i].x[4];
  34794. r->x[5] |= mask & table[i].x[5];
  34795. r->x[6] |= mask & table[i].x[6];
  34796. r->x[7] |= mask & table[i].x[7];
  34797. r->x[8] |= mask & table[i].x[8];
  34798. r->y[0] |= mask & table[i].y[0];
  34799. r->y[1] |= mask & table[i].y[1];
  34800. r->y[2] |= mask & table[i].y[2];
  34801. r->y[3] |= mask & table[i].y[3];
  34802. r->y[4] |= mask & table[i].y[4];
  34803. r->y[5] |= mask & table[i].y[5];
  34804. r->y[6] |= mask & table[i].y[6];
  34805. r->y[7] |= mask & table[i].y[7];
  34806. r->y[8] |= mask & table[i].y[8];
  34807. r->z[0] |= mask & table[i].z[0];
  34808. r->z[1] |= mask & table[i].z[1];
  34809. r->z[2] |= mask & table[i].z[2];
  34810. r->z[3] |= mask & table[i].z[3];
  34811. r->z[4] |= mask & table[i].z[4];
  34812. r->z[5] |= mask & table[i].z[5];
  34813. r->z[6] |= mask & table[i].z[6];
  34814. r->z[7] |= mask & table[i].z[7];
  34815. r->z[8] |= mask & table[i].z[8];
  34816. }
  34817. }
  34818. #endif /* !WC_NO_CACHE_RESISTANT */
  34819. /* Multiply the point by the scalar and return the result.
  34820. * If map is true then convert result to affine coordinates.
  34821. *
  34822. * Window technique of 6 bits. (Add-Sub variation.)
  34823. * Calculate 0..32 times the point. Use function that adds and
  34824. * subtracts the same two points.
  34825. * Recode to add or subtract one of the computed points.
  34826. * Double to push up.
  34827. * NOT a sliding window.
  34828. *
  34829. * r Resulting point.
  34830. * g Point to multiply.
  34831. * k Scalar to multiply by.
  34832. * map Indicates whether to convert result to affine.
  34833. * ct Constant time required.
  34834. * heap Heap to use for allocation.
  34835. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  34836. */
  34837. static int sp_521_ecc_mulmod_win_add_sub_9(sp_point_521* r, const sp_point_521* g,
  34838. const sp_digit* k, int map, int ct, void* heap)
  34839. {
  34840. #ifdef WOLFSSL_SP_SMALL_STACK
  34841. sp_point_521* t = NULL;
  34842. sp_digit* tmp = NULL;
  34843. #else
  34844. sp_point_521 t[33+2];
  34845. sp_digit tmp[2 * 9 * 6];
  34846. #endif
  34847. sp_point_521* rt = NULL;
  34848. sp_point_521* p = NULL;
  34849. sp_digit* negy;
  34850. int i;
  34851. ecc_recode_521 v[87];
  34852. int err = MP_OKAY;
  34853. /* Constant time used for cache attack resistance implementation. */
  34854. (void)ct;
  34855. (void)heap;
  34856. #ifdef WOLFSSL_SP_SMALL_STACK
  34857. t = (sp_point_521*)XMALLOC(sizeof(sp_point_521) *
  34858. (33+2), heap, DYNAMIC_TYPE_ECC);
  34859. if (t == NULL)
  34860. err = MEMORY_E;
  34861. if (err == MP_OKAY) {
  34862. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 9 * 6,
  34863. heap, DYNAMIC_TYPE_ECC);
  34864. if (tmp == NULL)
  34865. err = MEMORY_E;
  34866. }
  34867. #endif
  34868. if (err == MP_OKAY) {
  34869. rt = t + 33;
  34870. p = t + 33+1;
  34871. /* t[0] = {0, 0, 1} * norm */
  34872. XMEMSET(&t[0], 0, sizeof(t[0]));
  34873. t[0].infinity = 1;
  34874. /* t[1] = {g->x, g->y, g->z} * norm */
  34875. err = sp_521_mod_mul_norm_9(t[1].x, g->x, p521_mod);
  34876. }
  34877. if (err == MP_OKAY) {
  34878. err = sp_521_mod_mul_norm_9(t[1].y, g->y, p521_mod);
  34879. }
  34880. if (err == MP_OKAY) {
  34881. err = sp_521_mod_mul_norm_9(t[1].z, g->z, p521_mod);
  34882. }
  34883. if (err == MP_OKAY) {
  34884. t[1].infinity = 0;
  34885. /* t[2] ... t[32] */
  34886. sp_521_proj_point_dbl_n_store_9(t, &t[ 1], 5, 1, tmp);
  34887. sp_521_proj_point_add_9(&t[ 3], &t[ 2], &t[ 1], tmp);
  34888. sp_521_proj_point_dbl_9(&t[ 6], &t[ 3], tmp);
  34889. sp_521_proj_point_add_sub_9(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp);
  34890. sp_521_proj_point_dbl_9(&t[10], &t[ 5], tmp);
  34891. sp_521_proj_point_add_sub_9(&t[11], &t[ 9], &t[10], &t[ 1], tmp);
  34892. sp_521_proj_point_dbl_9(&t[12], &t[ 6], tmp);
  34893. sp_521_proj_point_dbl_9(&t[14], &t[ 7], tmp);
  34894. sp_521_proj_point_add_sub_9(&t[15], &t[13], &t[14], &t[ 1], tmp);
  34895. sp_521_proj_point_dbl_9(&t[18], &t[ 9], tmp);
  34896. sp_521_proj_point_add_sub_9(&t[19], &t[17], &t[18], &t[ 1], tmp);
  34897. sp_521_proj_point_dbl_9(&t[20], &t[10], tmp);
  34898. sp_521_proj_point_dbl_9(&t[22], &t[11], tmp);
  34899. sp_521_proj_point_add_sub_9(&t[23], &t[21], &t[22], &t[ 1], tmp);
  34900. sp_521_proj_point_dbl_9(&t[24], &t[12], tmp);
  34901. sp_521_proj_point_dbl_9(&t[26], &t[13], tmp);
  34902. sp_521_proj_point_add_sub_9(&t[27], &t[25], &t[26], &t[ 1], tmp);
  34903. sp_521_proj_point_dbl_9(&t[28], &t[14], tmp);
  34904. sp_521_proj_point_dbl_9(&t[30], &t[15], tmp);
  34905. sp_521_proj_point_add_sub_9(&t[31], &t[29], &t[30], &t[ 1], tmp);
  34906. negy = t[0].y;
  34907. sp_521_ecc_recode_6_9(k, v);
  34908. i = 86;
  34909. #ifndef WC_NO_CACHE_RESISTANT
  34910. if (ct) {
  34911. sp_521_get_point_33_9(rt, t, v[i].i);
  34912. rt->infinity = !v[i].i;
  34913. }
  34914. else
  34915. #endif
  34916. {
  34917. XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_521));
  34918. }
  34919. for (--i; i>=0; i--) {
  34920. sp_521_proj_point_dbl_n_9(rt, 6, tmp);
  34921. #ifndef WC_NO_CACHE_RESISTANT
  34922. if (ct) {
  34923. sp_521_get_point_33_9(p, t, v[i].i);
  34924. p->infinity = !v[i].i;
  34925. }
  34926. else
  34927. #endif
  34928. {
  34929. XMEMCPY(p, &t[v[i].i], sizeof(sp_point_521));
  34930. }
  34931. sp_521_sub_9(negy, p521_mod, p->y);
  34932. sp_521_norm_9(negy);
  34933. sp_521_cond_copy_9(p->y, negy, (sp_digit)0 - v[i].neg);
  34934. sp_521_proj_point_add_9(rt, rt, p, tmp);
  34935. }
  34936. if (map != 0) {
  34937. sp_521_map_9(r, rt, tmp);
  34938. }
  34939. else {
  34940. XMEMCPY(r, rt, sizeof(sp_point_521));
  34941. }
  34942. }
  34943. #ifdef WOLFSSL_SP_SMALL_STACK
  34944. if (t != NULL)
  34945. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  34946. if (tmp != NULL)
  34947. XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
  34948. #endif
  34949. return err;
  34950. }
  34951. #ifdef FP_ECC
  34952. #endif /* FP_ECC */
  34953. /* Add two Montgomery form projective points. The second point has a q value of
  34954. * one.
  34955. * Only the first point can be the same pointer as the result point.
  34956. *
  34957. * r Result of addition.
  34958. * p First point to add.
  34959. * q Second point to add.
  34960. * t Temporary ordinate data.
  34961. */
  34962. static void sp_521_proj_point_add_qz1_9(sp_point_521* r,
  34963. const sp_point_521* p, const sp_point_521* q, sp_digit* t)
  34964. {
  34965. sp_digit* t2 = t;
  34966. sp_digit* t3 = t + 2*9;
  34967. sp_digit* t6 = t + 4*9;
  34968. sp_digit* t1 = t + 6*9;
  34969. sp_digit* t4 = t + 8*9;
  34970. sp_digit* t5 = t + 10*9;
  34971. /* Calculate values to subtract from P->x and P->y. */
  34972. /* U2 = X2*Z1^2 */
  34973. sp_521_mont_sqr_9(t2, p->z, p521_mod, p521_mp_mod);
  34974. sp_521_mont_mul_9(t4, t2, p->z, p521_mod, p521_mp_mod);
  34975. sp_521_mont_mul_9(t2, t2, q->x, p521_mod, p521_mp_mod);
  34976. /* S2 = Y2*Z1^3 */
  34977. sp_521_mont_mul_9(t4, t4, q->y, p521_mod, p521_mp_mod);
  34978. if ((~p->infinity) & (~q->infinity) &
  34979. sp_521_cmp_equal_9(p->x, t2) &
  34980. sp_521_cmp_equal_9(p->y, t4)) {
  34981. sp_521_proj_point_dbl_9(r, p, t);
  34982. }
  34983. else {
  34984. sp_digit* x = t2;
  34985. sp_digit* y = t3;
  34986. sp_digit* z = t6;
  34987. /* H = U2 - X1 */
  34988. sp_521_mont_sub_9(t2, t2, p->x, p521_mod);
  34989. /* R = S2 - Y1 */
  34990. sp_521_mont_sub_9(t4, t4, p->y, p521_mod);
  34991. /* Z3 = H*Z1 */
  34992. sp_521_mont_mul_9(z, p->z, t2, p521_mod, p521_mp_mod);
  34993. /* X3 = R^2 - H^3 - 2*X1*H^2 */
  34994. sp_521_mont_sqr_9(t1, t2, p521_mod, p521_mp_mod);
  34995. sp_521_mont_mul_9(t3, p->x, t1, p521_mod, p521_mp_mod);
  34996. sp_521_mont_mul_9(t1, t1, t2, p521_mod, p521_mp_mod);
  34997. sp_521_mont_sqr_9(t2, t4, p521_mod, p521_mp_mod);
  34998. sp_521_mont_sub_9(t2, t2, t1, p521_mod);
  34999. sp_521_mont_dbl_9(t5, t3, p521_mod);
  35000. sp_521_mont_sub_9(x, t2, t5, p521_mod);
  35001. /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */
  35002. sp_521_mont_sub_9(t3, t3, x, p521_mod);
  35003. sp_521_mont_mul_9(t3, t3, t4, p521_mod, p521_mp_mod);
  35004. sp_521_mont_mul_9(t1, t1, p->y, p521_mod, p521_mp_mod);
  35005. sp_521_mont_sub_9(y, t3, t1, p521_mod);
  35006. {
  35007. int i;
  35008. sp_digit maskp = 0 - (q->infinity & (!p->infinity));
  35009. sp_digit maskq = 0 - (p->infinity & (!q->infinity));
  35010. sp_digit maskt = ~(maskp | maskq);
  35011. sp_digit inf = (sp_digit)(p->infinity & q->infinity);
  35012. for (i = 0; i < 9; i++) {
  35013. r->x[i] = (p->x[i] & maskp) | (q->x[i] & maskq) |
  35014. (x[i] & maskt);
  35015. }
  35016. for (i = 0; i < 9; i++) {
  35017. r->y[i] = (p->y[i] & maskp) | (q->y[i] & maskq) |
  35018. (y[i] & maskt);
  35019. }
  35020. for (i = 0; i < 9; i++) {
  35021. r->z[i] = (p->z[i] & maskp) | (q->z[i] & maskq) |
  35022. (z[i] & maskt);
  35023. }
  35024. r->z[0] |= inf;
  35025. r->infinity = (word32)inf;
  35026. }
  35027. }
  35028. }
  35029. #ifdef FP_ECC
  35030. /* Convert the projective point to affine.
  35031. * Ordinates are in Montgomery form.
  35032. *
  35033. * a Point to convert.
  35034. * t Temporary data.
  35035. */
  35036. static void sp_521_proj_to_affine_9(sp_point_521* a, sp_digit* t)
  35037. {
  35038. sp_digit* t1 = t;
  35039. sp_digit* t2 = t + 2 * 9;
  35040. sp_digit* tmp = t + 4 * 9;
  35041. sp_521_mont_inv_9(t1, a->z, tmp);
  35042. sp_521_mont_sqr_9(t2, t1, p521_mod, p521_mp_mod);
  35043. sp_521_mont_mul_9(t1, t2, t1, p521_mod, p521_mp_mod);
  35044. sp_521_mont_mul_9(a->x, a->x, t2, p521_mod, p521_mp_mod);
  35045. sp_521_mont_mul_9(a->y, a->y, t1, p521_mod, p521_mp_mod);
  35046. XMEMCPY(a->z, p521_norm_mod, sizeof(p521_norm_mod));
  35047. }
  35048. /* Generate the pre-computed table of points for the base point.
  35049. *
  35050. * width = 8
  35051. * 256 entries
  35052. * 65 bits between
  35053. *
  35054. * a The base point.
  35055. * table Place to store generated point data.
  35056. * tmp Temporary data.
  35057. * heap Heap to use for allocation.
  35058. */
  35059. static int sp_521_gen_stripe_table_9(const sp_point_521* a,
  35060. sp_table_entry_521* table, sp_digit* tmp, void* heap)
  35061. {
  35062. #ifdef WOLFSSL_SP_SMALL_STACK
  35063. sp_point_521* t = NULL;
  35064. #else
  35065. sp_point_521 t[3];
  35066. #endif
  35067. sp_point_521* s1 = NULL;
  35068. sp_point_521* s2 = NULL;
  35069. int i;
  35070. int j;
  35071. int err = MP_OKAY;
  35072. (void)heap;
  35073. #ifdef WOLFSSL_SP_SMALL_STACK
  35074. t = (sp_point_521*)XMALLOC(sizeof(sp_point_521) * 3, heap,
  35075. DYNAMIC_TYPE_ECC);
  35076. if (t == NULL)
  35077. err = MEMORY_E;
  35078. #endif
  35079. if (err == MP_OKAY) {
  35080. s1 = t + 1;
  35081. s2 = t + 2;
  35082. err = sp_521_mod_mul_norm_9(t->x, a->x, p521_mod);
  35083. }
  35084. if (err == MP_OKAY) {
  35085. err = sp_521_mod_mul_norm_9(t->y, a->y, p521_mod);
  35086. }
  35087. if (err == MP_OKAY) {
  35088. err = sp_521_mod_mul_norm_9(t->z, a->z, p521_mod);
  35089. }
  35090. if (err == MP_OKAY) {
  35091. t->infinity = 0;
  35092. sp_521_proj_to_affine_9(t, tmp);
  35093. XMEMCPY(s1->z, p521_norm_mod, sizeof(p521_norm_mod));
  35094. s1->infinity = 0;
  35095. XMEMCPY(s2->z, p521_norm_mod, sizeof(p521_norm_mod));
  35096. s2->infinity = 0;
  35097. /* table[0] = {0, 0, infinity} */
  35098. XMEMSET(&table[0], 0, sizeof(sp_table_entry_521));
  35099. /* table[1] = Affine version of 'a' in Montgomery form */
  35100. XMEMCPY(table[1].x, t->x, sizeof(table->x));
  35101. XMEMCPY(table[1].y, t->y, sizeof(table->y));
  35102. for (i=1; i<8; i++) {
  35103. sp_521_proj_point_dbl_n_9(t, 66, tmp);
  35104. sp_521_proj_to_affine_9(t, tmp);
  35105. XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));
  35106. XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));
  35107. }
  35108. for (i=1; i<8; i++) {
  35109. XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));
  35110. XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));
  35111. for (j=(1<<i)+1; j<(1<<(i+1)); j++) {
  35112. XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));
  35113. XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));
  35114. sp_521_proj_point_add_qz1_9(t, s1, s2, tmp);
  35115. sp_521_proj_to_affine_9(t, tmp);
  35116. XMEMCPY(table[j].x, t->x, sizeof(table->x));
  35117. XMEMCPY(table[j].y, t->y, sizeof(table->y));
  35118. }
  35119. }
  35120. }
  35121. #ifdef WOLFSSL_SP_SMALL_STACK
  35122. if (t != NULL)
  35123. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  35124. #endif
  35125. return err;
  35126. }
  35127. #endif /* FP_ECC */
  35128. #ifndef WC_NO_CACHE_RESISTANT
  35129. /* Touch each possible entry that could be being copied.
  35130. *
  35131. * r Point to copy into.
  35132. * table Table - start of the entries to access
  35133. * idx Index of entry to retrieve.
  35134. */
  35135. static void sp_521_get_entry_256_9(sp_point_521* r,
  35136. const sp_table_entry_521* table, int idx)
  35137. {
  35138. int i;
  35139. sp_digit mask;
  35140. r->x[0] = 0;
  35141. r->x[1] = 0;
  35142. r->x[2] = 0;
  35143. r->x[3] = 0;
  35144. r->x[4] = 0;
  35145. r->x[5] = 0;
  35146. r->x[6] = 0;
  35147. r->x[7] = 0;
  35148. r->x[8] = 0;
  35149. r->y[0] = 0;
  35150. r->y[1] = 0;
  35151. r->y[2] = 0;
  35152. r->y[3] = 0;
  35153. r->y[4] = 0;
  35154. r->y[5] = 0;
  35155. r->y[6] = 0;
  35156. r->y[7] = 0;
  35157. r->y[8] = 0;
  35158. for (i = 1; i < 256; i++) {
  35159. mask = 0 - (i == idx);
  35160. r->x[0] |= mask & table[i].x[0];
  35161. r->x[1] |= mask & table[i].x[1];
  35162. r->x[2] |= mask & table[i].x[2];
  35163. r->x[3] |= mask & table[i].x[3];
  35164. r->x[4] |= mask & table[i].x[4];
  35165. r->x[5] |= mask & table[i].x[5];
  35166. r->x[6] |= mask & table[i].x[6];
  35167. r->x[7] |= mask & table[i].x[7];
  35168. r->x[8] |= mask & table[i].x[8];
  35169. r->y[0] |= mask & table[i].y[0];
  35170. r->y[1] |= mask & table[i].y[1];
  35171. r->y[2] |= mask & table[i].y[2];
  35172. r->y[3] |= mask & table[i].y[3];
  35173. r->y[4] |= mask & table[i].y[4];
  35174. r->y[5] |= mask & table[i].y[5];
  35175. r->y[6] |= mask & table[i].y[6];
  35176. r->y[7] |= mask & table[i].y[7];
  35177. r->y[8] |= mask & table[i].y[8];
  35178. }
  35179. }
  35180. #endif /* !WC_NO_CACHE_RESISTANT */
  35181. /* Multiply the point by the scalar and return the result.
  35182. * If map is true then convert result to affine coordinates.
  35183. *
  35184. * Stripe implementation.
  35185. * Pre-generated: 2^0, 2^65, ...
  35186. * Pre-generated: products of all combinations of above.
  35187. * 8 doubles and adds (with qz=1)
  35188. *
  35189. * r Resulting point.
  35190. * k Scalar to multiply by.
  35191. * table Pre-computed table.
  35192. * map Indicates whether to convert result to affine.
  35193. * ct Constant time required.
  35194. * heap Heap to use for allocation.
  35195. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  35196. */
  35197. static int sp_521_ecc_mulmod_stripe_9(sp_point_521* r, const sp_point_521* g,
  35198. const sp_table_entry_521* table, const sp_digit* k, int map,
  35199. int ct, void* heap)
  35200. {
  35201. #ifdef WOLFSSL_SP_SMALL_STACK
  35202. sp_point_521* rt = NULL;
  35203. sp_digit* t = NULL;
  35204. #else
  35205. sp_point_521 rt[2];
  35206. sp_digit t[2 * 9 * 6];
  35207. #endif
  35208. sp_point_521* p = NULL;
  35209. int i;
  35210. int j;
  35211. int y;
  35212. int x;
  35213. int err = MP_OKAY;
  35214. (void)g;
  35215. /* Constant time used for cache attack resistance implementation. */
  35216. (void)ct;
  35217. (void)heap;
  35218. #ifdef WOLFSSL_SP_SMALL_STACK
  35219. rt = (sp_point_521*)XMALLOC(sizeof(sp_point_521) * 2, heap,
  35220. DYNAMIC_TYPE_ECC);
  35221. if (rt == NULL)
  35222. err = MEMORY_E;
  35223. if (err == MP_OKAY) {
  35224. t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 9 * 6, heap,
  35225. DYNAMIC_TYPE_ECC);
  35226. if (t == NULL)
  35227. err = MEMORY_E;
  35228. }
  35229. #endif
  35230. if (err == MP_OKAY) {
  35231. p = rt + 1;
  35232. XMEMCPY(p->z, p521_norm_mod, sizeof(p521_norm_mod));
  35233. XMEMCPY(rt->z, p521_norm_mod, sizeof(p521_norm_mod));
  35234. y = 0;
  35235. x = 65;
  35236. for (j=0; j<8 && x<521; j++) {
  35237. y |= (int)(((k[x / 58] >> (x % 58)) & 1) << j);
  35238. x += 66;
  35239. }
  35240. #ifndef WC_NO_CACHE_RESISTANT
  35241. if (ct) {
  35242. sp_521_get_entry_256_9(rt, table, y);
  35243. } else
  35244. #endif
  35245. {
  35246. XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));
  35247. XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));
  35248. }
  35249. rt->infinity = !y;
  35250. for (i=64; i>=0; i--) {
  35251. y = 0;
  35252. x = i;
  35253. for (j=0; j<8 && x<521; j++) {
  35254. y |= (int)(((k[x / 58] >> (x % 58)) & 1) << j);
  35255. x += 66;
  35256. }
  35257. sp_521_proj_point_dbl_9(rt, rt, t);
  35258. #ifndef WC_NO_CACHE_RESISTANT
  35259. if (ct) {
  35260. sp_521_get_entry_256_9(p, table, y);
  35261. }
  35262. else
  35263. #endif
  35264. {
  35265. XMEMCPY(p->x, table[y].x, sizeof(table[y].x));
  35266. XMEMCPY(p->y, table[y].y, sizeof(table[y].y));
  35267. }
  35268. p->infinity = !y;
  35269. sp_521_proj_point_add_qz1_9(rt, rt, p, t);
  35270. }
  35271. if (map != 0) {
  35272. sp_521_map_9(r, rt, t);
  35273. }
  35274. else {
  35275. XMEMCPY(r, rt, sizeof(sp_point_521));
  35276. }
  35277. }
  35278. #ifdef WOLFSSL_SP_SMALL_STACK
  35279. if (t != NULL)
  35280. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  35281. if (rt != NULL)
  35282. XFREE(rt, heap, DYNAMIC_TYPE_ECC);
  35283. #endif
  35284. return err;
  35285. }
  35286. #ifdef FP_ECC
  35287. #ifndef FP_ENTRIES
  35288. #define FP_ENTRIES 16
  35289. #endif
  35290. /* Cache entry - holds precomputation tables for a point. */
  35291. typedef struct sp_cache_521_t {
  35292. /* X ordinate of point that table was generated from. */
  35293. sp_digit x[9];
  35294. /* Y ordinate of point that table was generated from. */
  35295. sp_digit y[9];
  35296. /* Precomputation table for point. */
  35297. sp_table_entry_521 table[256];
  35298. /* Count of entries in table. */
  35299. uint32_t cnt;
  35300. /* Point and table set in entry. */
  35301. int set;
  35302. } sp_cache_521_t;
  35303. /* Cache of tables. */
  35304. static THREAD_LS_T sp_cache_521_t sp_cache_521[FP_ENTRIES];
  35305. /* Index of last entry in cache. */
  35306. static THREAD_LS_T int sp_cache_521_last = -1;
  35307. /* Cache has been initialized. */
  35308. static THREAD_LS_T int sp_cache_521_inited = 0;
  35309. #ifndef HAVE_THREAD_LS
  35310. #ifndef WOLFSSL_MUTEX_INITIALIZER
  35311. static volatile int initCacheMutex_521 = 0;
  35312. #endif
  35313. static wolfSSL_Mutex sp_cache_521_lock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(sp_cache_521_lock);
  35314. #endif
  35315. /* Get the cache entry for the point.
  35316. *
  35317. * g [in] Point scalar multiplying.
  35318. * cache [out] Cache table to use.
  35319. */
  35320. static void sp_ecc_get_cache_521(const sp_point_521* g, sp_cache_521_t** cache)
  35321. {
  35322. int i;
  35323. int j;
  35324. uint32_t least;
  35325. if (sp_cache_521_inited == 0) {
  35326. for (i=0; i<FP_ENTRIES; i++) {
  35327. sp_cache_521[i].set = 0;
  35328. }
  35329. sp_cache_521_inited = 1;
  35330. }
  35331. /* Compare point with those in cache. */
  35332. for (i=0; i<FP_ENTRIES; i++) {
  35333. if (!sp_cache_521[i].set)
  35334. continue;
  35335. if (sp_521_cmp_equal_9(g->x, sp_cache_521[i].x) &
  35336. sp_521_cmp_equal_9(g->y, sp_cache_521[i].y)) {
  35337. sp_cache_521[i].cnt++;
  35338. break;
  35339. }
  35340. }
  35341. /* No match. */
  35342. if (i == FP_ENTRIES) {
  35343. /* Find empty entry. */
  35344. i = (sp_cache_521_last + 1) % FP_ENTRIES;
  35345. for (; i != sp_cache_521_last; i=(i+1)%FP_ENTRIES) {
  35346. if (!sp_cache_521[i].set) {
  35347. break;
  35348. }
  35349. }
  35350. /* Evict least used. */
  35351. if (i == sp_cache_521_last) {
  35352. least = sp_cache_521[0].cnt;
  35353. for (j=1; j<FP_ENTRIES; j++) {
  35354. if (sp_cache_521[j].cnt < least) {
  35355. i = j;
  35356. least = sp_cache_521[i].cnt;
  35357. }
  35358. }
  35359. }
  35360. XMEMCPY(sp_cache_521[i].x, g->x, sizeof(sp_cache_521[i].x));
  35361. XMEMCPY(sp_cache_521[i].y, g->y, sizeof(sp_cache_521[i].y));
  35362. sp_cache_521[i].set = 1;
  35363. sp_cache_521[i].cnt = 1;
  35364. }
  35365. *cache = &sp_cache_521[i];
  35366. sp_cache_521_last = i;
  35367. }
  35368. #endif /* FP_ECC */
  35369. /* Multiply the base point of P521 by the scalar and return the result.
  35370. * If map is true then convert result to affine coordinates.
  35371. *
  35372. * r Resulting point.
  35373. * g Point to multiply.
  35374. * k Scalar to multiply by.
  35375. * map Indicates whether to convert result to affine.
  35376. * ct Constant time required.
  35377. * heap Heap to use for allocation.
  35378. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  35379. */
  35380. static int sp_521_ecc_mulmod_9(sp_point_521* r, const sp_point_521* g,
  35381. const sp_digit* k, int map, int ct, void* heap)
  35382. {
  35383. #ifndef FP_ECC
  35384. return sp_521_ecc_mulmod_win_add_sub_9(r, g, k, map, ct, heap);
  35385. #else
  35386. #ifdef WOLFSSL_SP_SMALL_STACK
  35387. sp_digit* tmp;
  35388. #else
  35389. sp_digit tmp[2 * 9 * 6];
  35390. #endif
  35391. sp_cache_521_t* cache;
  35392. int err = MP_OKAY;
  35393. #ifdef WOLFSSL_SP_SMALL_STACK
  35394. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 9 * 6, heap, DYNAMIC_TYPE_ECC);
  35395. if (tmp == NULL) {
  35396. err = MEMORY_E;
  35397. }
  35398. #endif
  35399. #ifndef HAVE_THREAD_LS
  35400. if (err == MP_OKAY) {
  35401. #ifndef WOLFSSL_MUTEX_INITIALIZER
  35402. if (initCacheMutex_521 == 0) {
  35403. wc_InitMutex(&sp_cache_521_lock);
  35404. initCacheMutex_521 = 1;
  35405. }
  35406. #endif
  35407. if (wc_LockMutex(&sp_cache_521_lock) != 0) {
  35408. err = BAD_MUTEX_E;
  35409. }
  35410. }
  35411. #endif /* HAVE_THREAD_LS */
  35412. if (err == MP_OKAY) {
  35413. sp_ecc_get_cache_521(g, &cache);
  35414. if (cache->cnt == 2)
  35415. sp_521_gen_stripe_table_9(g, cache->table, tmp, heap);
  35416. #ifndef HAVE_THREAD_LS
  35417. wc_UnLockMutex(&sp_cache_521_lock);
  35418. #endif /* HAVE_THREAD_LS */
  35419. if (cache->cnt < 2) {
  35420. err = sp_521_ecc_mulmod_win_add_sub_9(r, g, k, map, ct, heap);
  35421. }
  35422. else {
  35423. err = sp_521_ecc_mulmod_stripe_9(r, g, cache->table, k,
  35424. map, ct, heap);
  35425. }
  35426. }
  35427. #ifdef WOLFSSL_SP_SMALL_STACK
  35428. XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
  35429. #endif
  35430. return err;
  35431. #endif
  35432. }
  35433. #endif
  35434. /* Multiply the point by the scalar and return the result.
  35435. * If map is true then convert result to affine coordinates.
  35436. *
  35437. * km Scalar to multiply by.
  35438. * p Point to multiply.
  35439. * r Resulting point.
  35440. * map Indicates whether to convert result to affine.
  35441. * heap Heap to use for allocation.
  35442. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  35443. */
  35444. int sp_ecc_mulmod_521(const mp_int* km, const ecc_point* gm, ecc_point* r,
  35445. int map, void* heap)
  35446. {
  35447. #ifdef WOLFSSL_SP_SMALL_STACK
  35448. sp_point_521* point = NULL;
  35449. sp_digit* k = NULL;
  35450. #else
  35451. sp_point_521 point[1];
  35452. sp_digit k[9];
  35453. #endif
  35454. int err = MP_OKAY;
  35455. #ifdef WOLFSSL_SP_SMALL_STACK
  35456. point = (sp_point_521*)XMALLOC(sizeof(sp_point_521), heap,
  35457. DYNAMIC_TYPE_ECC);
  35458. if (point == NULL)
  35459. err = MEMORY_E;
  35460. if (err == MP_OKAY) {
  35461. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9, heap,
  35462. DYNAMIC_TYPE_ECC);
  35463. if (k == NULL)
  35464. err = MEMORY_E;
  35465. }
  35466. #endif
  35467. if (err == MP_OKAY) {
  35468. sp_521_from_mp(k, 9, km);
  35469. sp_521_point_from_ecc_point_9(point, gm);
  35470. err = sp_521_ecc_mulmod_9(point, point, k, map, 1, heap);
  35471. }
  35472. if (err == MP_OKAY) {
  35473. err = sp_521_point_to_ecc_point_9(point, r);
  35474. }
  35475. #ifdef WOLFSSL_SP_SMALL_STACK
  35476. if (k != NULL)
  35477. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  35478. if (point != NULL)
  35479. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  35480. #endif
  35481. return err;
  35482. }
  35483. /* Multiply the point by the scalar, add point a and return the result.
  35484. * If map is true then convert result to affine coordinates.
  35485. *
  35486. * km Scalar to multiply by.
  35487. * p Point to multiply.
  35488. * am Point to add to scalar multiply result.
  35489. * inMont Point to add is in montgomery form.
  35490. * r Resulting point.
  35491. * map Indicates whether to convert result to affine.
  35492. * heap Heap to use for allocation.
  35493. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  35494. */
  35495. int sp_ecc_mulmod_add_521(const mp_int* km, const ecc_point* gm,
  35496. const ecc_point* am, int inMont, ecc_point* r, int map, void* heap)
  35497. {
  35498. #ifdef WOLFSSL_SP_SMALL_STACK
  35499. sp_point_521* point = NULL;
  35500. sp_digit* k = NULL;
  35501. #else
  35502. sp_point_521 point[2];
  35503. sp_digit k[9 + 9 * 2 * 6];
  35504. #endif
  35505. sp_point_521* addP = NULL;
  35506. sp_digit* tmp = NULL;
  35507. int err = MP_OKAY;
  35508. #ifdef WOLFSSL_SP_SMALL_STACK
  35509. point = (sp_point_521*)XMALLOC(sizeof(sp_point_521) * 2, heap,
  35510. DYNAMIC_TYPE_ECC);
  35511. if (point == NULL)
  35512. err = MEMORY_E;
  35513. if (err == MP_OKAY) {
  35514. k = (sp_digit*)XMALLOC(
  35515. sizeof(sp_digit) * (9 + 9 * 2 * 6), heap,
  35516. DYNAMIC_TYPE_ECC);
  35517. if (k == NULL)
  35518. err = MEMORY_E;
  35519. }
  35520. #endif
  35521. if (err == MP_OKAY) {
  35522. addP = point + 1;
  35523. tmp = k + 9;
  35524. sp_521_from_mp(k, 9, km);
  35525. sp_521_point_from_ecc_point_9(point, gm);
  35526. sp_521_point_from_ecc_point_9(addP, am);
  35527. }
  35528. if ((err == MP_OKAY) && (!inMont)) {
  35529. err = sp_521_mod_mul_norm_9(addP->x, addP->x, p521_mod);
  35530. }
  35531. if ((err == MP_OKAY) && (!inMont)) {
  35532. err = sp_521_mod_mul_norm_9(addP->y, addP->y, p521_mod);
  35533. }
  35534. if ((err == MP_OKAY) && (!inMont)) {
  35535. err = sp_521_mod_mul_norm_9(addP->z, addP->z, p521_mod);
  35536. }
  35537. if (err == MP_OKAY) {
  35538. err = sp_521_ecc_mulmod_9(point, point, k, 0, 0, heap);
  35539. }
  35540. if (err == MP_OKAY) {
  35541. sp_521_proj_point_add_9(point, point, addP, tmp);
  35542. if (map) {
  35543. sp_521_map_9(point, point, tmp);
  35544. }
  35545. err = sp_521_point_to_ecc_point_9(point, r);
  35546. }
  35547. #ifdef WOLFSSL_SP_SMALL_STACK
  35548. if (k != NULL)
  35549. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  35550. if (point != NULL)
  35551. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  35552. #endif
  35553. return err;
  35554. }
  35555. #ifdef WOLFSSL_SP_SMALL
  35556. /* Multiply the base point of P521 by the scalar and return the result.
  35557. * If map is true then convert result to affine coordinates.
  35558. *
  35559. * r Resulting point.
  35560. * k Scalar to multiply by.
  35561. * map Indicates whether to convert result to affine.
  35562. * heap Heap to use for allocation.
  35563. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  35564. */
  35565. static int sp_521_ecc_mulmod_base_9(sp_point_521* r, const sp_digit* k,
  35566. int map, int ct, void* heap)
  35567. {
  35568. /* No pre-computed values. */
  35569. return sp_521_ecc_mulmod_9(r, &p521_base, k, map, ct, heap);
  35570. }
  35571. #ifdef WOLFSSL_SP_NONBLOCK
  35572. static int sp_521_ecc_mulmod_base_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
  35573. const sp_digit* k, int map, int ct, void* heap)
  35574. {
  35575. /* No pre-computed values. */
  35576. return sp_521_ecc_mulmod_9_nb(sp_ctx, r, &p521_base, k, map, ct, heap);
  35577. }
  35578. #endif /* WOLFSSL_SP_NONBLOCK */
  35579. #else
  35580. /* Striping precomputation table.
  35581. * 8 points combined into a table of 256 points.
  35582. * Distance of 66 between points.
  35583. */
  35584. static const sp_table_entry_521 p521_table[256] = {
  35585. /* 0 */
  35586. { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  35587. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
  35588. /* 1 */
  35589. { { 0x17e7e31c2e5bd66L,0x22cf0615a90a6feL,0x0127a2ffa8de334L,
  35590. 0x1dfbf9d64a3f877L,0x06b4d3dbaa14b5eL,0x14fed487e0a2bd8L,
  35591. 0x15b4429c6481390L,0x3a73678fb2d988eL,0x0c6858e06b70404L },
  35592. { 0x0be94769fd16650L,0x31c21a89cb09022L,0x39013fad0761353L,
  35593. 0x2657bd099031542L,0x3273e662c97ee72L,0x1e6d11a05ebef45L,
  35594. 0x3d1bd998f544495L,0x3001172297ed0b1L,0x11839296a789a3bL } },
  35595. /* 2 */
  35596. { { 0x03986670f0ccb51L,0x387404d9525d2a0L,0x0f21b2b29ed9b87L,
  35597. 0x2aa8eb74cddfd63L,0x0e9d08ffb06c0e9L,0x19d8589fc4ecd74L,
  35598. 0x0a3ef4dd8bf44c9L,0x0eb6e92863051d6L,0x13e96a576dda004L },
  35599. { 0x3de24f8632d95a3L,0x057bc5314920a4aL,0x063e9bdaba1979fL,
  35600. 0x3d2a58adc1eab76L,0x214258d98dde053L,0x18708d7316628b7L,
  35601. 0x3fd32c9fa5a19d0L,0x33ab03b519443a3L,0x1852aea9dd1ef78L } },
  35602. /* 3 */
  35603. { { 0x0a91dd8eaaf1fe3L,0x0e19891002d4af4L,0x06a921abf0d20dbL,
  35604. 0x26a9da32503fda8L,0x09a1eec37941287L,0x1ce0d0f3cde46afL,
  35605. 0x22abc1c913fbe62L,0x3cc4dca2d0aaf88L,0x157874c0a862b9eL },
  35606. { 0x2c8f184e6f03d49L,0x0d5f907922f80c2L,0x1ef3815cbdefa9cL,
  35607. 0x2ad7f6370f00b39L,0x1faeb109d7a41c7L,0x213d34e12fbd9f2L,
  35608. 0x2f0aae2f98cca1aL,0x25a2df80f51f59cL,0x00724b1ab581d58L } },
  35609. /* 4 */
  35610. { { 0x04f2d4bdf9314e0L,0x3a14379e802ab24L,0x1083582efb03daaL,
  35611. 0x20fb1ff9b49e48cL,0x2199d74a880f1c2L,0x25401f9cb56ce65L,
  35612. 0x33f03e5f120b9b3L,0x2da18c348ddcd1dL,0x121f4c192733b78L },
  35613. { 0x103ff6dfa8b51f0L,0x2bed45038af7c3cL,0x380e83254171ae7L,
  35614. 0x2e33684365444c0L,0x24f3a8c01e83501L,0x3201c1a4415ddc7L,
  35615. 0x2238218f52196aaL,0x29fc4d826c2aa95L,0x1db8c25790694a0L } },
  35616. /* 5 */
  35617. { { 0x00370ccb2c0958dL,0x3bc599a69ece1ccL,0x33cf480c9b3889aL,
  35618. 0x3cbeacf85249e4bL,0x2507489670b2984L,0x34cf6caa5d4790dL,
  35619. 0x0a4daa9cab99d5aL,0x1cc95365174cad1L,0x00aa26cca5216c7L },
  35620. { 0x1be1d41f9e66d18L,0x3bbe5aa845f9eb3L,0x14a2ddb0d24b80aL,
  35621. 0x09d7262defc14c8L,0x2dfd3c8486dcfb2L,0x329354b184f9d0dL,
  35622. 0x151e646e703fa13L,0x149f43238a5dc61L,0x1c6f5e90eacbfa8L } },
  35623. /* 6 */
  35624. { { 0x2c2f1e74ab2d58fL,0x2fe0b0a825e00a8L,0x2b24770bb76ac1bL,
  35625. 0x3b5599fdef5960fL,0x2fd96897e8e4ed9L,0x3ef83c576300761L,
  35626. 0x1cdcb166395a133L,0x3ac954793ce7766L,0x082de08424a720dL },
  35627. { 0x3aa53b260ea91afL,0x212bdde8c77f765L,0x32395cd09bbea43L,
  35628. 0x36bcc016387360bL,0x2e5c78e97997c19L,0x1d6c611510ed831L,
  35629. 0x02ce16faae9b5f5L,0x3ea1973a1bccc23L,0x073983ce58f4f63L } },
  35630. /* 7 */
  35631. { { 0x2e931318217609dL,0x2a7750904bf002bL,0x264c286c63297f8L,
  35632. 0x359efc7197b845fL,0x38d03eee5cc3782L,0x2ae4de67a305136L,
  35633. 0x3784c701acacb29L,0x3361c857ac6d6c1L,0x0f82c409fa81affL },
  35634. { 0x07d3766378139a4L,0x25a7aed56faa4c0L,0x0d6f68c8bc9dc6dL,
  35635. 0x1857e4fc90b1f18L,0x2741717d9844e84L,0x02fc483a118728aL,
  35636. 0x1699d78e930e79fL,0x2db7b85552809adL,0x07de69c77026a4fL } },
  35637. /* 8 */
  35638. { { 0x1b51bb04bee80d7L,0x3da87dda4b79a58L,0x246ca0ebc3bd0e1L,
  35639. 0x29e4c1913c20de7L,0x3390db0771c0bffL,0x2b6873a65f19ee1L,
  35640. 0x14b512095c33e1fL,0x21958f1402b76b1L,0x0b0c231d360d311L },
  35641. { 0x228929839bcab2fL,0x019e01937488281L,0x2084763dc2a0c0cL,
  35642. 0x1cc64e30f8c18bdL,0x152e46eb988e9daL,0x297783f5a6fa3cbL,
  35643. 0x2c0e26e55c8d2d6L,0x3fd5fce8ff58f6cL,0x14a899c6d9f1e4bL } },
  35644. /* 9 */
  35645. { { 0x3f6e3a1ec05ce88L,0x30925adabf480a7L,0x20776fbeb007f8fL,
  35646. 0x2f7baf7b5002e74L,0x2693700f7b50ec0L,0x3dec0c3abbe5dd0L,
  35647. 0x101f77806e37a13L,0x2b83d73c5f45c6eL,0x1599036e5dfca95L },
  35648. { 0x0af64b5000e8e0cL,0x0ab8101bed37e40L,0x1a67449f23bad3fL,
  35649. 0x108956c96a57d87L,0x28e33c6500ca918L,0x0b009f07e9abcf9L,
  35650. 0x2840a514373c00cL,0x1090267cf36865cL,0x0e798c62b79d0e8L } },
  35651. /* 10 */
  35652. { { 0x0c7c4a8ae4d0f28L,0x2957bd59b401bbaL,0x1f65066e40233a8L,
  35653. 0x2d574c86dd8de61L,0x2b8351b078deccaL,0x1f5522ace2e59b5L,
  35654. 0x31ab0b2e889e535L,0x14dedea7a38bf98L,0x05945c60f95e75cL },
  35655. { 0x0a27d347867d79cL,0x182c5607206602fL,0x19ab976b8c517f4L,
  35656. 0x21986e47b65fb0bL,0x1d9c1d15ffcd044L,0x253276e5cc29e89L,
  35657. 0x2c5a3b8a2cf259fL,0x0c7ba39e12e1d77L,0x004062526073e51L } },
  35658. /* 11 */
  35659. { { 0x2e04e5cf1631bbaL,0x1b077c55bd14937L,0x3f30e4c3099040eL,
  35660. 0x10dadaafb1c1980L,0x0f6b94f6edb649aL,0x1adf82d4d53d427L,
  35661. 0x1e6dd27fecf4693L,0x1432a9e9c41fae8L,0x022889edac56894L },
  35662. { 0x012916ed05596f2L,0x0076b2c08f2e2e4L,0x13ece7d4abe1e39L,
  35663. 0x102a7240c4c9407L,0x1c6d146d0b28150L,0x13b8625a76f34fcL,
  35664. 0x1226fb6fa1d5b17L,0x0261126ba8586a4L,0x154754ceedfb8a8L } },
  35665. /* 12 */
  35666. { { 0x24e27b04270b2f0L,0x0d3922fd35d35edL,0x3e8b0c2722ba84bL,
  35667. 0x2767fe6dc72c61aL,0x334fd6bc4f54a58L,0x104bd276621f937L,
  35668. 0x389d16b7c669fd7L,0x381d1002366eddfL,0x1cfafb9426bc902L },
  35669. { 0x0a4f2d1662935caL,0x1f1c0e65f7311b3L,0x29e5353c79f8284L,
  35670. 0x2254857c3d30227L,0x080911b9d9ed8d9L,0x3789ea8d673c22fL,
  35671. 0x1e320d4b03540e6L,0x064ed4bd358fbdaL,0x0e6a0217fd694efL } },
  35672. /* 13 */
  35673. { { 0x37de62774214780L,0x19a05c81d167aadL,0x39b7e9c7fb01ca0L,
  35674. 0x3075b52df1fde15L,0x0a66caa39e55548L,0x2141693d15d5864L,
  35675. 0x0864ebf8141b039L,0x274fe972835f132L,0x053bf8af9509e12L },
  35676. { 0x09b29d885285092L,0x0c76aa3bb5797efL,0x290ef618aab982fL,
  35677. 0x3d34989bb4670cdL,0x307ed8e090eee14L,0x1cdb410108a55c2L,
  35678. 0x27d01d1977920e8L,0x2dced1fb897ffb7L,0x1b93c921c3abc7aL } },
  35679. /* 14 */
  35680. { { 0x36a07cca08b2b14L,0x1e37aefc5d31fc2L,0x3828c40cb2a4aa9L,
  35681. 0x1ca42b720e0a472L,0x28c1edde695c782L,0x03ef4880236a2caL,
  35682. 0x2db94e741ceb2f9L,0x152397e272794c8L,0x07d18266085b73cL },
  35683. { 0x1ebf82a2defd012L,0x32c2516854dfbdaL,0x35353ef0811d01eL,
  35684. 0x29ecaf537a8f155L,0x27bf969c859c882L,0x2c96b46c0287e5cL,
  35685. 0x136005063adf5e0L,0x3f861307fcc1bc9L,0x1178e515bec4112L } },
  35686. /* 15 */
  35687. { { 0x314787fefe3d3d5L,0x1dbd967625c89e4L,0x3ed1e0b6acf529eL,
  35688. 0x080717a3764571dL,0x15f5667af9c2b7bL,0x0d5dbbd1e200e3cL,
  35689. 0x00154af38c766ffL,0x0ed4e7c188f2001L,0x09647d3c44bde88L },
  35690. { 0x2075638de1b21a4L,0x0e67055c420704cL,0x206775c03599bb6L,
  35691. 0x1feb79833d4c8b9L,0x0efc190595c7fdeL,0x35ece5806c65510L,
  35692. 0x2fa73e7e70ac8cdL,0x01d912a96a0f5a9L,0x04234f8cfac6308L } },
  35693. /* 16 */
  35694. { { 0x231e71a286492adL,0x0f791197e1ab13bL,0x00d4da713cb408fL,
  35695. 0x3a6a1adc413a25cL,0x32572c1617ad0f5L,0x173072676698b93L,
  35696. 0x162e0c77d223ef2L,0x2c817b7fda584eeL,0x08e818d28f381d8L },
  35697. { 0x21231cf8cdf1f60L,0x103cad9c5dd83dcL,0x2f8ce045a4038b6L,
  35698. 0x3700dc1a27ef9c9L,0x372ea0dcb422285L,0x2021988dc65afe3L,
  35699. 0x26fe48a16f7855cL,0x2fd1353867f1f0cL,0x13efdbc856e8f68L } },
  35700. /* 17 */
  35701. { { 0x234d04fe6a3ace5L,0x2d80fa258647077L,0x0007f75ed0f40dbL,
  35702. 0x2f256c966d6d370L,0x22615f02015e0e6L,0x0c7a8fe37ef2e99L,
  35703. 0x3ff824b2ec5433dL,0x0ccb90ac2c39040L,0x11119315060c480L },
  35704. { 0x197ea28045452f1L,0x19e33dc7cfdcee6L,0x3ddc41e9328e80bL,
  35705. 0x1bb9abc708d294aL,0x1b44215e7b7f265L,0x02900a2f10e016eL,
  35706. 0x2476e23aa734f2fL,0x033df8f1c91e508L,0x1f16dc2e8b068c6L } },
  35707. /* 18 */
  35708. { { 0x0dfae6ffffc0de5L,0x06053ead297c92fL,0x3658ea2aa8dda80L,
  35709. 0x3d7693c11046404L,0x334100611f3b1caL,0x1b833e23c92e736L,
  35710. 0x055c8248c324ed9L,0x0b8a52dfa8cd08cL,0x1d36e835b648909L },
  35711. { 0x2b77ae707372f27L,0x26d3ea0eeb8669fL,0x1ae165429ebb477L,
  35712. 0x19bf00fbcfe85d7L,0x16991c7c4942ec2L,0x1894f4f0397f1aaL,
  35713. 0x34e738a0f61e4f5L,0x3a465e847fd6379L,0x00260524cd4624dL } },
  35714. /* 19 */
  35715. { { 0x1b5d0ca01342e08L,0x3b53c2dd27c2bd1L,0x02d96529d804509L,
  35716. 0x36db600d673ad54L,0x34c3848005eb087L,0x1d6a1e13aa99aa1L,
  35717. 0x34317ee972c7a0cL,0x3efd2305a7885a1L,0x14f81c556e0e5c9L },
  35718. { 0x2b0b12be120674dL,0x3c26e4867c02b09L,0x332dd658caa6c6bL,
  35719. 0x2be0a4b66787879L,0x125fdbf80c771c5L,0x199b0df57604d4aL,
  35720. 0x0df680e61bd7983L,0x0260e36b251a874L,0x09f58dcf684c39fL } },
  35721. /* 20 */
  35722. { { 0x01691027b7dc837L,0x065d52d43ac7105L,0x092ad7e6741b2d7L,
  35723. 0x076f20928e013d0L,0x2c8e20bcf1d0a7fL,0x286076c15c2c815L,
  35724. 0x3b508a6732e3b9dL,0x01249e2018db829L,0x04511af502cc9f7L },
  35725. { 0x3820d94c56f4ffaL,0x08168b13c303e82L,0x3d4ea1a0606a1c6L,
  35726. 0x199e6cc5bee67ccL,0x2e4f240fc1bab64L,0x0b5f710c16a8214L,
  35727. 0x23c07322539b789L,0x198cc0d95fc481bL,0x05928405280cedbL } },
  35728. /* 21 */
  35729. { { 0x0d087114397760cL,0x082dd8727f341a4L,0x07fa987e24f7b90L,
  35730. 0x281488cd6831ffbL,0x1ae21ca100e33b8L,0x2c0c8881cf6fabfL,
  35731. 0x145da6458c060a3L,0x18bbe6e71cee3b8L,0x0aa31c661e527ffL },
  35732. { 0x3518eb081430b5eL,0x3e73a943b835a6bL,0x30b5aa6ebe8bb32L,
  35733. 0x3ca7f875a243b36L,0x31a59cc9a1f15f7L,0x22aca98f3975a3cL,
  35734. 0x07ce54f4d679940L,0x01ddba16c73bd0dL,0x1768ff423c0286dL } },
  35735. /* 22 */
  35736. { { 0x164104c33dcec23L,0x03586f3741d4661L,0x2f514c4f309abafL,
  35737. 0x3d779221c5521b6L,0x1d3539ba3f01bc8L,0x28efa3b3775aebcL,
  35738. 0x1d865fbb7e665d3L,0x12683e4676b0f2dL,0x173fe203da3f121L },
  35739. { 0x03ae9a178d4a3d1L,0x173d62194c5b601L,0x26c041176463a4dL,
  35740. 0x23fe12be913abc0L,0x3ffea422d316c63L,0x188ad84d44bc8e5L,
  35741. 0x27068d691eaa046L,0x2ccf12215ba8e5fL,0x1b542d1b2e3f4a1L } },
  35742. /* 23 */
  35743. { { 0x11b2d5e1f487402L,0x005b99eabc7757dL,0x31f56da9c20ae36L,
  35744. 0x187b3916ff47acfL,0x3027a9e1825b7d3L,0x210459250b6c18cL,
  35745. 0x0773d0bf228777eL,0x297c3d7f3831116L,0x01fb2b3151d2dd7L },
  35746. { 0x02773e8fbaa096aL,0x1c9baf824ea1e04L,0x0d072c7f1781152L,
  35747. 0x342ad7729d9714fL,0x187ef2d4a38d3dfL,0x1fac470aed29f61L,
  35748. 0x2da22f5c9c2013bL,0x3b2b578d4f0d02dL,0x039846d50a5a325L } },
  35749. /* 24 */
  35750. { { 0x2da77361677df58L,0x2f559c72d435b1dL,0x07d70a080ff2364L,
  35751. 0x0a6194c90c0110fL,0x2c35101e7a0a854L,0x231735da0800b74L,
  35752. 0x2cf13fbebc61434L,0x23703fc5646bb29L,0x0fb91c7c2e698bfL },
  35753. { 0x27c5cad12de14d5L,0x12317d95872089aL,0x24307cdbb3dabc4L,
  35754. 0x0471da0475e7e37L,0x2754620499c58f0L,0x269d39247a2601bL,
  35755. 0x3e37c3e52ad0a2cL,0x31cb480d1a172caL,0x0ec7a8632450a0bL } },
  35756. /* 25 */
  35757. { { 0x3818c218a86786eL,0x0dfdd084df8b20cL,0x10d1a7e6eb20ed5L,
  35758. 0x1c17371200d765aL,0x024f7bd759790ecL,0x387c3c511a458b2L,
  35759. 0x1915ca09e7ef9d4L,0x089bf4c304a2f3aL,0x02d810145f66c71L },
  35760. { 0x12749f5b71d87e5L,0x0ec505ec0b3b68cL,0x2d2ee0baff1625fL,
  35761. 0x2a7f2b9989c0915L,0x337bd985f97f7b3L,0x3e9b430435bafe3L,
  35762. 0x32f13720aa81b97L,0x376c6ca7c680487L,0x03de326a2f85cc0L } },
  35763. /* 26 */
  35764. { { 0x2f3398b38c2ee78L,0x0f44069d682fb89L,0x1706565a7f8e40cL,
  35765. 0x38c10067974d68cL,0x2b8174b6ed12985L,0x3e0294a8878a990L,
  35766. 0x18d80e25a15ee8aL,0x3aa6974783f9a14L,0x0848cbbc13804f6L },
  35767. { 0x2828690dfd45169L,0x1f8261674fa341dL,0x0811cdb8bfc238dL,
  35768. 0x1e858b3d9208dd6L,0x3b4d15b8c849954L,0x18126699252eaceL,
  35769. 0x21cfed822cbc57cL,0x1662eb10c893aa2L,0x0d94356346957c6L } },
  35770. /* 27 */
  35771. { { 0x306925368271323L,0x2782a12734135caL,0x1fbf2b31cc7d24dL,
  35772. 0x13d5e8f8d86ab8dL,0x20294e85644f64bL,0x0f3b52b852411a1L,
  35773. 0x2cda47ddc82ee74L,0x3e5a32e4a9a95f8L,0x13f989c42efbfc1L },
  35774. { 0x2d98bdfb8651600L,0x18d0d1e8f3ebbafL,0x254335b1a2268c3L,
  35775. 0x3775609541e4e84L,0x3852eb1e9558da7L,0x0a57d516945cec8L,
  35776. 0x06d101df5ae5852L,0x3e18b951b8bbd99L,0x1faf7e16a2c5d89L } },
  35777. /* 28 */
  35778. { { 0x1746c8ec7ec136dL,0x07609f3444d46c3L,0x3ad3f187a116f8eL,
  35779. 0x23c4dba1195d928L,0x0850983c22f1b96L,0x39c5c967506a8a5L,
  35780. 0x3c149c2123ecc4bL,0x2e0b77372ad49d8L,0x16da7f50b181022L },
  35781. { 0x19e532d0ca5e258L,0x22b45e5ed8a9efeL,0x242ec77fddefa14L,
  35782. 0x335d3e6db123428L,0x07fd122d458518bL,0x2d42cb5f14ecc2eL,
  35783. 0x01aae9bb8cd193fL,0x1b824685a6bbaf0L,0x1c57e49b10a1de2L } },
  35784. /* 29 */
  35785. { { 0x0abe67521210716L,0x0a5a8c1f809000bL,0x011d8c83795b81aL,
  35786. 0x0d3767be9aa52bfL,0x3677d686f68f203L,0x3d7389d56f8be7aL,
  35787. 0x357c5c6a13f277bL,0x12e33df648906e5L,0x13270c3d2f4c74fL },
  35788. { 0x1c8609c8d209aa4L,0x104e8b6cad50dbeL,0x2d1a2992345d46fL,
  35789. 0x3ae521f0d3e5adcL,0x2b440a375186f2aL,0x3694d6393e9c85dL,
  35790. 0x25b3103a4209367L,0x182e3c47ab78ffcL,0x1a99a570153505dL } },
  35791. /* 30 */
  35792. { { 0x21513936e7495bbL,0x0bf4a12421e746bL,0x2b0b29fd76fcebdL,
  35793. 0x26f1839c872708cL,0x3517a09e2a1a0d4L,0x362eb7e27d60ae0L,
  35794. 0x148bb4ac37809e9L,0x3121d2a937a782bL,0x027fd041312cb6cL },
  35795. { 0x05502eeead4fb6dL,0x3097b42980b2fb0L,0x2841bd7f4a07760L,
  35796. 0x0c953b7385162e9L,0x10397614cc28b60L,0x207bb64ee75078eL,
  35797. 0x2d4b0b4221b71d1L,0x3906740438f08ccL,0x096dfe58a27dab0L } },
  35798. /* 31 */
  35799. { { 0x0d6fcd67debd24eL,0x3f29826b8ac1d53L,0x022ef217c26cbe3L,
  35800. 0x382e58838fe9f63L,0x2c7f9f87dd42d03L,0x25cbffb98d2fc85L,
  35801. 0x0d3e7722b1ec538L,0x14dfa0ea55f0758L,0x162edfe5f860f6aL },
  35802. { 0x0a05400f0ea20b8L,0x0ab1f875e5a4010L,0x25c90edb0cac287L,
  35803. 0x0c2d8a4e69ddd96L,0x2af2cb7089df5b9L,0x0bfaf04bde299dbL,
  35804. 0x190ad3030732bf5L,0x38d04e999037ae8L,0x0d536eae15f93e7L } },
  35805. /* 32 */
  35806. { { 0x06119f6a1c88f3cL,0x397fb0bb1a5129bL,0x2c605742ff2a924L,
  35807. 0x07b76c8b1f1322aL,0x0fa5d25bb60addeL,0x3045f7825ca24e3L,
  35808. 0x2929c1fa5ac4f7eL,0x257d507cd6add20L,0x180d1c4e8f90afdL },
  35809. { 0x3c4e73da7cd8358L,0x18695fca872480bL,0x3130ad94d288393L,
  35810. 0x198ada9e38bdbcbL,0x379c262cde37e24L,0x06d65ee42eaffe2L,
  35811. 0x0d4e646cae01ef6L,0x3e1167078cfc298L,0x00e52a42280dd01L } },
  35812. /* 33 */
  35813. { { 0x2d640a40f013755L,0x3739dfee0e03a5cL,0x0e797eb64b310b6L,
  35814. 0x02e4f2968d89e27L,0x358bdffc98e704bL,0x08c30dc8630d83fL,
  35815. 0x3385d153b1f323bL,0x0efdf5ace422169L,0x04a071130f556b9L },
  35816. { 0x1a2096bfeef3f88L,0x2ea1a6e0ace514aL,0x184a872664a722eL,
  35817. 0x286163fe509ff88L,0x17490c9daa0dc0bL,0x056233a0cde67adL,
  35818. 0x32cee21d356f628L,0x2bba5f766f1fe9eL,0x0d21e61a4e8a3cfL } },
  35819. /* 34 */
  35820. { { 0x05db629e9068656L,0x2f5c327fb7937fbL,0x15bdfcd45546623L,
  35821. 0x3498a469d071e2bL,0x2761e688ef7981dL,0x16e49cbceb14f64L,
  35822. 0x146fec6a96892a5L,0x0bd59085f9ee019L,0x15e793c03cbab9eL },
  35823. { 0x0fd95436eff39beL,0x2bc1fb6ffd3da02L,0x3abdb02416165a1L,
  35824. 0x3f751e600a60f51L,0x060b2e6fb37c5d2L,0x3a36e662761b65eL,
  35825. 0x28b9bbe3e3284ecL,0x062ce7c127ad761L,0x18e3b3e8a789dadL } },
  35826. /* 35 */
  35827. { { 0x3026c56e51e61f0L,0x2f2a8cc1fc9d5d5L,0x26ebb1aeaf41dddL,
  35828. 0x1f38b5fd6ea4a80L,0x2bc5ead91a33e93L,0x391a01f47df3007L,
  35829. 0x01951990ab665d2L,0x101270a913d554dL,0x0aa099c1ca67966L },
  35830. { 0x161a9098f97e387L,0x145de1178775a6dL,0x112b7ff1d6abf60L,
  35831. 0x293426a72247fe9L,0x1d2282e2b42da55L,0x1d0616b57969f1cL,
  35832. 0x0baeffdfa5a203eL,0x0285866c4da77a8L,0x1a3a5eef9141eccL } },
  35833. /* 36 */
  35834. { { 0x2f20d0a7a573b81L,0x3072a1986533bcaL,0x2d8d0b711c347eaL,
  35835. 0x1b2e826750bbc34L,0x05067a8ca6aea01L,0x284d47be998274aL,
  35836. 0x1c26346a52c6007L,0x00cf36ae16062c4L,0x121f17fa45dbb1cL },
  35837. { 0x3b8b87afc3279d6L,0x39daaf0807c7867L,0x2a83806c21dde30L,
  35838. 0x0af18fe093c0abdL,0x246bd1a53eafd7eL,0x084e4591ec1d389L,
  35839. 0x32d9bfcd6f4931aL,0x273c6acb3f4e705L,0x10a62f3eb4b4db5L } },
  35840. /* 37 */
  35841. { { 0x002de36e0689a1bL,0x3327f5f72bf9cb9L,0x2d7e255d0bfb9dcL,
  35842. 0x3b92b681367937aL,0x2bfd2e774d7ee87L,0x1c2cae6d6a140e7L,
  35843. 0x103bba282c66577L,0x141c69eb2a09ae8L,0x11aac7028bac7cdL },
  35844. { 0x261d39c680c8f04L,0x271332d22ced78bL,0x09bd95744f3c2f0L,
  35845. 0x2d2ab32d64c4c58L,0x25adfb2096d72e4L,0x3f4fb33f6dc1832L,
  35846. 0x352a73c67d9e431L,0x215f0521e89bf85L,0x1e33d95366364d0L } },
  35847. /* 38 */
  35848. { { 0x264506b4cec9e7fL,0x1592d0c2aae63f9L,0x101f173fa284a44L,
  35849. 0x1f85725d1c9786dL,0x082dec033e7b7bdL,0x298edd8b5b319eaL,
  35850. 0x0e2fcd1fe2e9340L,0x39d48e821386cfeL,0x0fdccce4da89ae6L },
  35851. { 0x397f8eec12fd820L,0x3e24aa5b691ccc1L,0x241d55997bf4325L,
  35852. 0x2b00add4f3d65f4L,0x1f677ceba3aef35L,0x06eeb1b229cfe57L,
  35853. 0x1278b05b2892b7dL,0x117da41d4560f31L,0x01c2f5ed53fa47fL } },
  35854. /* 39 */
  35855. { { 0x114165eab40b79cL,0x1bbb6096d226a0eL,0x2b7d8a6c107fbfbL,
  35856. 0x22e3807ca2f684dL,0x1a4d79907d431dbL,0x11c79a161397437L,
  35857. 0x376ff869a91472aL,0x047f56341a5a660L,0x006ce369b74c463L },
  35858. { 0x00773d11add1452L,0x3a7257b63a68a9bL,0x0e32ca15a40c2e4L,
  35859. 0x0dabd8bc63fa3feL,0x2eec9484b3fcb7dL,0x2c81016cb28cdbbL,
  35860. 0x2d8352a4d6e7a93L,0x00f9db64340c655L,0x0e5dd375603d9caL } },
  35861. /* 40 */
  35862. { { 0x05f297d8b481bf7L,0x0a8f90a84ce0f33L,0x128cdc40b96c06aL,
  35863. 0x17c462768f27851L,0x16cd57fa79a2bf3L,0x0d5f4caee2b6e62L,
  35864. 0x176fadc1a4935c9L,0x0f78547ec96030bL,0x1ba98721eb424f2L },
  35865. { 0x002daaf52a4b397L,0x17d330342d39523L,0x0db37b7e79cdc3cL,
  35866. 0x3b2cce5c2d8a6f9L,0x092808c7ff34336L,0x08a236c7b4f72dfL,
  35867. 0x2ed59aec290eff0L,0x3e97ca91e7547a5L,0x0929d7ed87076d8L } },
  35868. /* 41 */
  35869. { { 0x0edaf0be660043cL,0x28b32c05b81d376L,0x28e7e2cc3b3d84aL,
  35870. 0x0c1709a7f12748dL,0x13de33e3647b501L,0x2272941340653b8L,
  35871. 0x0db11ddb3361b97L,0x24bc2335460ce61L,0x0c6d5b801ecc8ecL },
  35872. { 0x3f91c1547ab9887L,0x2178a9ad6ac044cL,0x0e5a133fc8182f2L,
  35873. 0x1d0e361a4b26dcdL,0x043282e815c435aL,0x31ef36a8f24ad1fL,
  35874. 0x158c86191231f59L,0x0f328eb90970d34L,0x0117f568febc5a2L } },
  35875. /* 42 */
  35876. { { 0x0cbd9d5bf5caa87L,0x3f183da37632763L,0x0dbbc7d4dede17bL,
  35877. 0x11609c2d6fd8fadL,0x1cc098fe7bf6e59L,0x175ee3d621c4de9L,
  35878. 0x25a533ca5eb6870L,0x029b12df7bbb92cL,0x0ef8e045c324a70L },
  35879. { 0x20c1c9270cf52bcL,0x0fd8ea43318a605L,0x021cbf3028fb4bfL,
  35880. 0x35d48efbfc57ffdL,0x38b9ce1050a8102L,0x19886c7bfccc268L,
  35881. 0x0a78078e9da4d00L,0x2184a5dd7e27f30L,0x0eb590448650017L } },
  35882. /* 43 */
  35883. { { 0x26664fdebbd33ecL,0x269983396b55e62L,0x2c0550fb56ed0cfL,
  35884. 0x2b4756aa9bbb341L,0x3948a7f07b4ca5fL,0x3f870468db6bb96L,
  35885. 0x12544bd2e37887eL,0x363a907d86b1247L,0x0be49df70712bffL },
  35886. { 0x0e2f1f565acdb56L,0x04f21179796f798L,0x1354e17a0412f2fL,
  35887. 0x33f6724efbee5ffL,0x325a957e48a2867L,0x28618d7e72a745aL,
  35888. 0x26ae711f55c19b4L,0x150766ce1a3d634L,0x000ac4480414c94L } },
  35889. /* 44 */
  35890. { { 0x01bcf89d4ad38dbL,0x03ce04f5c51445bL,0x2759cb70243a118L,
  35891. 0x18c58e9c5b16d30L,0x213648bdb5dd64dL,0x137a65a6ef4bbfaL,
  35892. 0x1e8c45a47187f9eL,0x3429d9779a44b8bL,0x048e075f29c4bdaL },
  35893. { 0x03354745e4dd88dL,0x20d8e2015debf00L,0x1c01227288f7182L,
  35894. 0x2479a26277b92cdL,0x1cd3f71bad008fdL,0x3936878908508c5L,
  35895. 0x262bb15cb023ff3L,0x13f95f9ae70d6d5L,0x072143f41657fb0L } },
  35896. /* 45 */
  35897. { { 0x06b046c26f40f2cL,0x3491b1b35f0c76cL,0x22701953a9b7bd5L,
  35898. 0x2e23c010dbeaa95L,0x021d0660d5ac929L,0x2f5b6f9864dce4bL,
  35899. 0x3c43f9d279ed159L,0x34094ddf1356b45L,0x179800eda50b8fcL },
  35900. { 0x08ddc0b36132f31L,0x3d3c04ab79ce8eeL,0x1ec3203de2b96f8L,
  35901. 0x0508c6d94cce216L,0x0a14093caedb038L,0x30af8be6b423348L,
  35902. 0x2bc09fb9f86d445L,0x11e37f4f654cbdbL,0x13d757b58991aefL } },
  35903. /* 46 */
  35904. { { 0x19ad100580f894bL,0x09222b649791bdfL,0x3e142e5a6865b61L,
  35905. 0x14c5fe6a04d1525L,0x2f8a33541c86e10L,0x299b55e362aa082L,
  35906. 0x358e23a67906607L,0x2ad711f7d82b97dL,0x107cadd4c90a7f8L },
  35907. { 0x16b044f6764ad0eL,0x3f8384940626ccdL,0x0a625f14db6af69L,
  35908. 0x27c6f5df550b7abL,0x25cfa895ce9f277L,0x1bc66b0e5e6447cL,
  35909. 0x2f44b1d4e94cedbL,0x09fd70d4cd05c06L,0x03bcac43fff50c7L } },
  35910. /* 47 */
  35911. { { 0x342951c83c1d4cfL,0x1e4742c9170d3c5L,0x0ef69c2dcc71e03L,
  35912. 0x0a4a8c41d9faa3eL,0x3b12948bd2ea57aL,0x3fabae0c956d1aeL,
  35913. 0x1abf592adc1e090L,0x29a26834b463112L,0x0199e8c9ff5c4a8L },
  35914. { 0x1f7b9cdeb28171aL,0x1e100f55da61ef2L,0x33bf22ff824cefdL,
  35915. 0x24efcccf31562d3L,0x2b01ceb72ee09b3L,0x080a6737affe0e8L,
  35916. 0x2bf7515bb34c452L,0x173ce8f0fa2819bL,0x1a65dee07bb49d0L } },
  35917. /* 48 */
  35918. { { 0x1a958d6b114257bL,0x2bf507525d78c02L,0x39b53aae7b11729L,
  35919. 0x24fb746b20c1ca1L,0x11eb679750791b0L,0x099d6d2b3fbf1f4L,
  35920. 0x29517f0e54bd37eL,0x0268e2698b5fa35L,0x06b96f805d82021L },
  35921. { 0x015d51757b5f9f4L,0x2790d9016d13452L,0x1de0e4870160e5cL,
  35922. 0x2547bdacfe0d10bL,0x1f7497faf953fefL,0x05bbc2de467933dL,
  35923. 0x12eeed24e3cc4d0L,0x05c0ff172aa1c94L,0x1b6f1ba4029a3bdL } },
  35924. /* 49 */
  35925. { { 0x2668435529252acL,0x189b01d39ec360aL,0x0cc1e0be86ab3daL,
  35926. 0x3dd3b57714d5420L,0x00cd41fd0534a53L,0x19d22472a7bfc50L,
  35927. 0x13b5ad0e7c945c5L,0x026237a92e257b1L,0x1ffefc67bef1515L },
  35928. { 0x08dc109306033fdL,0x21e5e7cda1d7666L,0x2f26e3c335c51b2L,
  35929. 0x3f44938a75934e6L,0x0c41dbdfca47259L,0x33036255758315cL,
  35930. 0x28ff8606224b610L,0x21c1e81075397baL,0x1fd2920e15cae4dL } },
  35931. /* 50 */
  35932. { { 0x2d15f0ccd67da85L,0x22dbd16b1528559L,0x2021f1ac71c3ae9L,
  35933. 0x0991d564890bc17L,0x166e856dc1feb22L,0x3ed2e91ca8bc558L,
  35934. 0x1d920b65eb14566L,0x32e6cd1a22f4a8aL,0x061943ce86ef9d4L },
  35935. { 0x0696218aac91174L,0x1467b1077648d2dL,0x2df29f0763a485bL,
  35936. 0x09dc4b22ccedfbeL,0x3b053863098517fL,0x3fcf8f9280b9fb0L,
  35937. 0x09648646bc45bb1L,0x2e4fd1aba25bca5L,0x1462aeb1649ebd2L } },
  35938. /* 51 */
  35939. { { 0x334f41fe8e4d3c3L,0x361ffd6edfa76c7L,0x2c0ad910b579c80L,
  35940. 0x186e1cd26bbc085L,0x02b0a6cc02a24b7L,0x3cb4655c152f14aL,
  35941. 0x3e6cdd3b4c7029aL,0x028d0392e438ab6L,0x0cf8e774f812606L },
  35942. { 0x07f9dbc2e229950L,0x07e11b67e0adc0fL,0x19a3f10c05f3ab1L,
  35943. 0x13c3c608328adebL,0x0ccbfb332203eadL,0x199c1bc5476f2f2L,
  35944. 0x059d5e3bd9caf00L,0x3993968e6f89418L,0x14c984387c8dcafL } },
  35945. /* 52 */
  35946. { { 0x08a757f8e011531L,0x16c5cb0f7355f1cL,0x09fdc2d99e297f4L,
  35947. 0x07ee4ed9056a3abL,0x0a5488e869d4ee8L,0x2edeadc2960ced5L,
  35948. 0x3df3a9ddd561c30L,0x0ccaed6f68e12ceL,0x124f909f8e01ddfL },
  35949. { 0x1b8aa84ab41e782L,0x08049a14776e1f1L,0x2a7d99482bd21deL,
  35950. 0x3afd2d904efd26eL,0x37cd1e22405963dL,0x2eb583bbb4da7eeL,
  35951. 0x2e30eddcf495dd1L,0x084b7ad1d5a4e24L,0x10baaf11bd8af0aL } },
  35952. /* 53 */
  35953. { { 0x146017416ec64e2L,0x052b3df5f1baf9cL,0x04a3668b7176bfdL,
  35954. 0x3cdd06c107078d4L,0x22d3b67b072e3f3L,0x15f64a35947e952L,
  35955. 0x08f419623edca3eL,0x2ebbca6dd3a2dcbL,0x0383d99cb47327aL },
  35956. { 0x08dd0b3da342a3fL,0x00918b7bd2a5520L,0x242eeab5a860120L,
  35957. 0x0141b952db46c71L,0x310c6cf1a5e1e2aL,0x3e40f3426e85c43L,
  35958. 0x0166f5334fc3660L,0x10d4e5a7800044dL,0x0fafaa26074155cL } },
  35959. /* 54 */
  35960. { { 0x05cd0e6712de285L,0x3fe2c21a7d77172L,0x2b92df4ed389cd2L,
  35961. 0x0c156e67210dca8L,0x2e07a003363524dL,0x1b82524d1bfbd68L,
  35962. 0x28952b0a2c82dadL,0x1fadacd899885caL,0x02c9afcb188af21L },
  35963. { 0x3b9d4769a64c5b5L,0x23577913133f874L,0x18ef11c6dbffa0dL,
  35964. 0x23d07052bb55821L,0x235efe854ce1d97L,0x11d15d74947e79cL,
  35965. 0x289c03f9d0c14c0L,0x2770034b20e3af6L,0x16fa25f040b36ccL } },
  35966. /* 55 */
  35967. { { 0x23d9dea9cad682dL,0x32c6cd18da4e46cL,0x19885c0f24d787aL,
  35968. 0x31f50620f3a7d70L,0x353555e46dff62fL,0x2473681746aca77L,
  35969. 0x0633ed569b1cb28L,0x150a36c536f114bL,0x1941acbb86c2a34L },
  35970. { 0x06a70c824db8127L,0x1958fd06df3d6f6L,0x1abeb908d9b484aL,
  35971. 0x18e2670982a3613L,0x344436957aaeaaeL,0x02a4b2344fb5acaL,
  35972. 0x0bcb973bc94f99dL,0x1597e5e3cb8af41L,0x07456a388ef716aL } },
  35973. /* 56 */
  35974. { { 0x082dfe496fc1f77L,0x310d7c4d1eb5a98L,0x14dc25ebe457b04L,
  35975. 0x1a6dbdd92abd09aL,0x104d83da164a170L,0x03208cc380e1cf5L,
  35976. 0x239b3eb0b9db52eL,0x0536a621acd3b50L,0x16a76587f2a5988L },
  35977. { 0x118f8e8ebc71a5dL,0x10690a150148cdaL,0x09ccc182cbcc491L,
  35978. 0x34f82415e9f58fcL,0x1e239d8eb4afe59L,0x365252cb98cf6c3L,
  35979. 0x04fd61bac8582dfL,0x3bf662e4569051cL,0x10ee0866a9dfceaL } },
  35980. /* 57 */
  35981. { { 0x350c47052e07a4dL,0x34e2e3975d1740aL,0x047ce1af12267f6L,
  35982. 0x12ce71417ded053L,0x186f739be03e4b4L,0x1f0bc6f167cf5e5L,
  35983. 0x23fad4ca19bca7eL,0x22bec7147007b01L,0x080da3937a57f42L },
  35984. { 0x1d8ca9d102369faL,0x26ffedc1b038d7aL,0x19a796b55d80e00L,
  35985. 0x37ab0342530b828L,0x1787c187ada0e42L,0x33e812d9b06f8b1L,
  35986. 0x1773406d4ae2cc9L,0x18a156c33a981d9L,0x0d82d525245c7c9L } },
  35987. /* 58 */
  35988. { { 0x1cb238cae93de69L,0x0f20cceff6ba6dbL,0x1f4de8b79836496L,
  35989. 0x112ba2fe2b8cf20L,0x24c3ebacce13a22L,0x15696b582f1b9e1L,
  35990. 0x3e9459a837a53c5L,0x1bf361d7634d6f1L,0x01fb3705534f9f4L },
  35991. { 0x0e9270c7fb974a1L,0x123e83a7b49205eL,0x2c3d64bffbd4234L,
  35992. 0x10f5e7d2cf05059L,0x13b9f32a0a05aa4L,0x32408d7b615693cL,
  35993. 0x352b484bebcf8daL,0x027459612661e36L,0x183aa4d59f1e48dL } },
  35994. /* 59 */
  35995. { { 0x2585d75dbffad9fL,0x3d85d3d06763f3bL,0x3f59e6c6934564dL,
  35996. 0x3460f566c31bdceL,0x3929c8950b80793L,0x2658aeadaebd3f0L,
  35997. 0x291273bd445a952L,0x1e16d4ad86517aaL,0x1be4fccdfff3d1cL },
  35998. { 0x1c384d97cb2857fL,0x20c1601adeafd01L,0x1d1743ace6b24cfL,
  35999. 0x28af10f5adbd4a3L,0x314e564b92c7b8fL,0x0ae7c06a3c38a2fL,
  36000. 0x1383e61b69bc73dL,0x251aeae2fad00f7L,0x0aeaccea0c59791L } },
  36001. /* 60 */
  36002. { { 0x268baee0163c2deL,0x342cafac9da2926L,0x3124ffdae767c42L,
  36003. 0x3542ab2a50d5a1bL,0x2e01091cf926da5L,0x0c92fb35a670d33L,
  36004. 0x13a0a93d2545405L,0x332746dad63c506L,0x14ff144925ed611L },
  36005. { 0x361a60cc1ed9259L,0x0dea8cbc7569fdfL,0x313d07aef4311beL,
  36006. 0x12539be9ee80e11L,0x28bd3730c99f33dL,0x2e555f710e4a305L,
  36007. 0x22bee573cf8ccf5L,0x158402f1b518346L,0x14527cd194383b1L } },
  36008. /* 61 */
  36009. { { 0x3e651353427af4eL,0x302ec4c4364df52L,0x276acaa671c32e6L,
  36010. 0x3534ea70ddaf63aL,0x3471709aa9d7b3fL,0x060147004933a18L,
  36011. 0x28ee1c225ce41d0L,0x13b215224a13fe7L,0x13d22d829c9535cL },
  36012. { 0x301ed9da1b15e02L,0x24aeb0c07961a1aL,0x21835764135b1d0L,
  36013. 0x2ddbdc56692fe9eL,0x118090d0dc0ee59L,0x2014865a45c6814L,
  36014. 0x1279045c1531bbbL,0x1da15d024c3f082L,0x008963b48cc7633L } },
  36015. /* 62 */
  36016. { { 0x3e8b620f4aaaed5L,0x2379f7fa1c7ba03L,0x030ffebfcb4b106L,
  36017. 0x39f0e88556cac88L,0x02769b805d4dfbeL,0x34e7abc29e89aa3L,
  36018. 0x15f032377de7706L,0x2dcc7c6a4911fd8L,0x12aa1b81a8442d9L },
  36019. { 0x19e67d0b1152e8fL,0x1cf65e4ad78530aL,0x1073f1cb57a22e7L,
  36020. 0x272fc76928b8360L,0x2c22b449a03af0aL,0x34b5f4745a6c583L,
  36021. 0x098ee4b82c1ac8dL,0x3a855d422b29affL,0x15054992440e3cbL } },
  36022. /* 63 */
  36023. { { 0x0004a0aa13a4602L,0x31c68f434b1839cL,0x2463a6d79bc5505L,
  36024. 0x0eb553677d293f8L,0x373d3c7b8e878ebL,0x113b3e95fb32a41L,
  36025. 0x24d1795b3bb2782L,0x0abc228c3d87ec4L,0x1155b7e50014f63L },
  36026. { 0x2c42ecc9ef0021aL,0x05ff5fe15b27518L,0x03b82e6478bc580L,
  36027. 0x1a45416936c4389L,0x04cd7eea5af0746L,0x14abb42b66ec287L,
  36028. 0x09f09de8ba39a2dL,0x3e9901d1d126ad5L,0x13fd5c8f7bd9e57L } },
  36029. /* 64 */
  36030. { { 0x3d8ce7b5a53c22bL,0x0cff35f2ad11a86L,0x24e248acb394787L,
  36031. 0x07a8e31e43f1132L,0x315c34237a9888bL,0x2dc0818cdabedbaL,
  36032. 0x3508fab913b8a8fL,0x1ccacd2ddf31645L,0x050a931d7a7f9e4L },
  36033. { 0x10a429056d21d18L,0x198c1d56d04286aL,0x0a8b894a6b05826L,
  36034. 0x18e0a33dd72d1a1L,0x2127702a38a1adeL,0x37dedc253ecbe16L,
  36035. 0x0d1db683ff7d05aL,0x3357074fd6a4a9aL,0x0f5243ce1dbc093L } },
  36036. /* 65 */
  36037. { { 0x3c183c3d37d7891L,0x140527f6197b2a3L,0x03d68f21844117bL,
  36038. 0x095681fd9603db9L,0x3ad303202af51ecL,0x019dbbd63f969b2L,
  36039. 0x0e000c95de68f31L,0x14951d4238c7f29L,0x159783e5a957773L },
  36040. { 0x01db5712e537ad9L,0x1c44b4d6fa73defL,0x2b48d57f9bcb5e8L,
  36041. 0x242a2cf2f1eed48L,0x1e5ecdb5c1eff78L,0x0e1f9fb53cc1b84L,
  36042. 0x321e3d30da83923L,0x299f13647f3d1c8L,0x09f8487bb62e412L } },
  36043. /* 66 */
  36044. { { 0x2f5f80f8cb8e08eL,0x34b104925bfb5a1L,0x374360b7dcdf7cfL,
  36045. 0x37d5fd3417c0186L,0x2458061f24dbaffL,0x37a65312c664f0aL,
  36046. 0x07e0626c6ca8d09L,0x172f3bdc349349dL,0x0ffd4e5d4e3b999L },
  36047. { 0x171e245c6f40077L,0x0b81141c8f9418cL,0x2f7e6a6bfd88159L,
  36048. 0x345b6767380d721L,0x03eb5770cba0959L,0x10358f74b9fe3faL,
  36049. 0x1e441958eb0881cL,0x07d3558ccef6baeL,0x034fb0397df3afdL } },
  36050. /* 67 */
  36051. { { 0x384e05eb358815cL,0x32cb5390421f65eL,0x188907f05d7a3abL,
  36052. 0x355ea7520721e9dL,0x042d64cbd350778L,0x33ca27fa74d33feL,
  36053. 0x2b2c6e0859cd5acL,0x02d8a0dcb564774L,0x06bc06d482e18b4L },
  36054. { 0x10695a0da4ed375L,0x2bd620a636abab4L,0x21b4f4b7092c51bL,
  36055. 0x2b9e8cd6cd6c0a2L,0x20567efd88ab87dL,0x0c830dd29cd64d8L,
  36056. 0x158b307a49fc103L,0x33a6dcdeb2b128dL,0x01ed30696a34c0fL } },
  36057. /* 68 */
  36058. { { 0x1550ab0bd3902feL,0x292d2e1aa74ecf6L,0x20a9975cac379bbL,
  36059. 0x0c4ccd81770e967L,0x21afc2c58045e87L,0x3be72fc7cb16630L,
  36060. 0x383c4281ff8d6feL,0x0c7560afb57426fL,0x1579d1d9d5b5281L },
  36061. { 0x07da3055519258eL,0x14e7e409f78aa1aL,0x1747d6a230d673fL,
  36062. 0x08d7d745a11a7eaL,0x35f7e41f5ab1aebL,0x1a9ffacd6effa51L,
  36063. 0x2d5187bd546abb1L,0x14f74abef53a385L,0x1607437be13bcc9L } },
  36064. /* 69 */
  36065. { { 0x1f165a9ee9755a3L,0x35686ae0b26ac55L,0x245aab6b97e60c8L,
  36066. 0x2c2ac1789c59687L,0x26db0830f3004cdL,0x16b2f7ae7830ed4L,
  36067. 0x1e8498aae1ec1a7L,0x318b904f51211d8L,0x1e9589e09bbb1b9L },
  36068. { 0x35120819c72258dL,0x335cd170564f519L,0x3a7b91c11fdb61dL,
  36069. 0x2fe215e4239b189L,0x2530bc68ed1d3e9L,0x2d6d13fe6ab01bfL,
  36070. 0x10edd5125c16bb6L,0x36d70e2182edb6eL,0x1aa96fe8b08fbbeL } },
  36071. /* 70 */
  36072. { { 0x23a5dd8f257c0f8L,0x13724b74e84364cL,0x39cebbb8ce03488L,
  36073. 0x14e91c98aa40fcdL,0x352e06c6d6217adL,0x0c90a336877c805L,
  36074. 0x30c62cf5b723e0cL,0x20b307974e224b0L,0x1fdd9a90f1f477fL },
  36075. { 0x30d27ba1763ab59L,0x1f64f9c8de0fa60L,0x0264945968aacf2L,
  36076. 0x0c85c0357560556L,0x303146d9f63251aL,0x196fc3cb3daef9cL,
  36077. 0x2323fb6cdcf455eL,0x11d1202a803398cL,0x1496e49e62cd96aL } },
  36078. /* 71 */
  36079. { { 0x2ff0b7e40574c09L,0x3c990cffa03a5afL,0x1352eb237d91b76L,
  36080. 0x2ddfb70c4082cefL,0x3424a36dc3c0c62L,0x31b10d7be624e52L,
  36081. 0x08d076e9ea64c27L,0x2792cb7f087138eL,0x139cc3852f6a4e6L },
  36082. { 0x238a3ffbb096b91L,0x0b2795cf6350f94L,0x1b118c577558ee7L,
  36083. 0x34b711f52d3045bL,0x142e1955f54ec89L,0x10dd1d70801b74dL,
  36084. 0x2e9041004aed6a7L,0x0cb2707770ca8afL,0x1fb597417a2ed93L } },
  36085. /* 72 */
  36086. { { 0x00f1981859bae66L,0x23a6c61175f06cfL,0x1c03452a3c1eab4L,
  36087. 0x033fe040ce71b3aL,0x15f98d6fe2384a0L,0x2283756f35fb784L,
  36088. 0x3e1c06f7a00e3d3L,0x2987d5b765228f1L,0x0d09d21a7d18e53L },
  36089. { 0x1cfdbaf880eb3fbL,0x3f4a5d7a0fdf27eL,0x3d6fa28a74b464cL,
  36090. 0x17f7ec4f80d86e9L,0x3232a6128b8200dL,0x06a361b80ef23d2L,
  36091. 0x2d6ea7d1fb92c28L,0x06309a19d7eb9c1L,0x11d9b08608aefabL } },
  36092. /* 73 */
  36093. { { 0x3cf6146bbd2f539L,0x14bf01db89ae885L,0x1d18d4be4a67960L,
  36094. 0x08a7cfce6a0da08L,0x1433f873a8f8234L,0x05bd15a1a2e11aeL,
  36095. 0x1477507a1d3f367L,0x3889b7d80f8a0bfL,0x00377cb02c56975L },
  36096. { 0x275add38c01dd59L,0x04ea7ae7068debcL,0x11044dfc54039c2L,
  36097. 0x0181fb83619a42bL,0x1661fc40e202ee2L,0x02c0bd5a25bb7a5L,
  36098. 0x2f1a246b4d7398dL,0x1c49732e5a64796L,0x09fd5c281afc13fL } },
  36099. /* 74 */
  36100. { { 0x058c54bd7073a5aL,0x206972187ab1f72L,0x0a39e720201a87cL,
  36101. 0x23903800f3947e1L,0x358f199de952a9fL,0x15b300addaf712aL,
  36102. 0x3162f31cf12322dL,0x27846d98d398e0fL,0x16984c017ee8f96L },
  36103. { 0x1f433625c89f1faL,0x0a98c2da5ec1e3cL,0x1e5c4b05b7f44a0L,
  36104. 0x1453fb79330ccc4L,0x04b025aa4a7ccaeL,0x2136deb4349ba1dL,
  36105. 0x31c1fe7d5b77bbfL,0x33480e7bc6aa3d5L,0x18d65eba928418cL } },
  36106. /* 75 */
  36107. { { 0x37866ab8abb2537L,0x3132ed96cc25be8L,0x27ed2a428ad314aL,
  36108. 0x18843a7865a09feL,0x089801b4e95d19fL,0x2ba2e08cc7ae5e8L,
  36109. 0x1c9642aae77a62aL,0x22e125a4f58a97dL,0x0adff5bfe973e36L },
  36110. { 0x3efae21492b0deeL,0x0fa7ba580b0b3a8L,0x3c996f3b99e5214L,
  36111. 0x2c3a4ee3d6484d9L,0x01064c13edd78b2L,0x15ce39ea355070eL,
  36112. 0x33b1a4e6b970dafL,0x0823ebdbb305a0dL,0x180dbfa3f4f74aeL } },
  36113. /* 76 */
  36114. { { 0x024621a907a6aa0L,0x1b2da101e1e7dacL,0x0b688168a934ef5L,
  36115. 0x34e6e6a4121130eL,0x082541f2070d638L,0x3f222d41a5a32a8L,
  36116. 0x2357840c5970531L,0x2533d55937b56bdL,0x097e7e898c7c4d4L },
  36117. { 0x1dc98d96b6ebb2fL,0x285ff1eaa7849b8L,0x0fdbfa2a2c68292L,
  36118. 0x032cb86146ed83cL,0x181ca4cfe9c6327L,0x046567562636c99L,
  36119. 0x0b8d1994082638bL,0x0c253913cc23a95L,0x0d696399eb844e6L } },
  36120. /* 77 */
  36121. { { 0x200f362b83769eeL,0x0102b0fbf132cfeL,0x388957abd68772dL,
  36122. 0x0965029c4a30e4cL,0x3ec242a31622644L,0x168695464271323L,
  36123. 0x1c2172d1e48f1e6L,0x1ff51a2f5c3c412L,0x041c8692d2b709bL },
  36124. { 0x2388aa1df816784L,0x23229406f9d7393L,0x1ffb02a678124a5L,
  36125. 0x383b69c87826d27L,0x1e67a65eca73299L,0x15b1c6da282f47dL,
  36126. 0x05aa30d81e91e88L,0x2efc8debb8bd300L,0x073d94007500595L } },
  36127. /* 78 */
  36128. { { 0x112ac4a010c0ef3L,0x152f613a06c682aL,0x23dc4f3535090e6L,
  36129. 0x3ced1f4626a3c15L,0x2f238c09c10dc41L,0x106b3d9c48bb741L,
  36130. 0x358520224c16afcL,0x2b9bc732e4cd20dL,0x1271a4b5f292275L },
  36131. { 0x12fd4733ce688b5L,0x19b4df72a71a2deL,0x326e541711d0145L,
  36132. 0x3b8f30d06a3f3a4L,0x02122c11fe3ba14L,0x174de6d5ae2ad33L,
  36133. 0x122f91c0fa763bfL,0x25696578b4abbc5L,0x0acd4e21b3d31cfL } },
  36134. /* 79 */
  36135. { { 0x013a7791d8e061aL,0x01f9c2b32128c10L,0x0266eb2f636a627L,
  36136. 0x085dec97275ab02L,0x170ff35cfe917eaL,0x106262fb76de2efL,
  36137. 0x0ae4455008db2b0L,0x3439c3d6293f338L,0x043ed0923972257L },
  36138. { 0x0ad77b3e2e129e6L,0x312a1c3c6f935cbL,0x0dff20056333fb8L,
  36139. 0x304a9a4550ebb94L,0x2b8fe2640bc2658L,0x259682be5770332L,
  36140. 0x11d99e694eb5841L,0x3721df4eea94fb7L,0x0832df13b208a1eL } },
  36141. /* 80 */
  36142. { { 0x2ad2247d181c3f2L,0x34d6fbccdec8fffL,0x3cba74890672915L,
  36143. 0x23ff69e8e876d33L,0x179275686e4f70dL,0x3fc7de7889ad906L,
  36144. 0x1fa4e8e80408636L,0x27d8263a12ce73dL,0x0da57aa0be9d8a0L },
  36145. { 0x00cecf54efcea66L,0x3cabb2bf1dbebb5L,0x1a48c91585a898dL,
  36146. 0x29c4fc02a958fc6L,0x344b5cb9fb111bdL,0x149883459a1ebeaL,
  36147. 0x0b35abc6d5fb126L,0x3134abe54fc6eebL,0x0ed99709370ff94L } },
  36148. /* 81 */
  36149. { { 0x09f56e068b54c89L,0x3305f739cdf08abL,0x283fab089b5308eL,
  36150. 0x0a550fef46c823bL,0x0844dd706b0f3a1L,0x3b0b90346c8133eL,
  36151. 0x19914a80975c89dL,0x137dc22c046ba4eL,0x0176b4ba1707467L },
  36152. { 0x1216ea98fdfc175L,0x1ff18df83d6c31cL,0x285fceb33a3477bL,
  36153. 0x13c088faade2340L,0x351c6d922b67981L,0x304fd47641e1c82L,
  36154. 0x2d60b55859d5a49L,0x32acb9a7e142febL,0x05c2499a8446d0cL } },
  36155. /* 82 */
  36156. { { 0x1d581fb73e7bcf1L,0x37987374f05ef90L,0x17ecfa199fd916dL,
  36157. 0x1cf05676e5f18a6L,0x2641328301a7588L,0x250aa4613b5de25L,
  36158. 0x2ba4bb9672ce892L,0x375ffcfb9161e05L,0x1234fb7a148ce54L },
  36159. { 0x05d80aff009be8cL,0x24e35de37c6e87cL,0x2e84312de62062eL,
  36160. 0x1fd81c312e69f88L,0x3a1b5da3748d29eL,0x11c5d14d73670faL,
  36161. 0x2b9e671e51bd2faL,0x31a8650262ac15aL,0x049bb584abc49f7L } },
  36162. /* 83 */
  36163. { { 0x1f255301ea470f7L,0x2fe023a49538c2aL,0x29ea71a0038da01L,
  36164. 0x385644f2a1c2615L,0x3b8281fdb0d2b2eL,0x063970aab85c012L,
  36165. 0x2943abdb5c6eb01L,0x3540695ab19307eL,0x0531aaf64771a92L },
  36166. { 0x279ef4906345730L,0x2aa93a11bcdf0a5L,0x26b01a7c3aab946L,
  36167. 0x28a059b7d3be05cL,0x24e04dc3ecb808dL,0x1bb066d3a7ecff0L,
  36168. 0x16d13e9e0b61db7L,0x14e11b9fd997bbbL,0x0e570ed8c0786a7L } },
  36169. /* 84 */
  36170. { { 0x2456e58108ce13fL,0x3f163438e5e04d9L,0x284bea3949e9b5bL,
  36171. 0x2f1d6bd99f412daL,0x0a891566bea9b66L,0x3d856569f2d35b7L,
  36172. 0x2e25201b3cecf0bL,0x297e90c4b1cf400L,0x14b81d768986135L },
  36173. { 0x047bc25841078ecL,0x2a72585e7115350L,0x06094851f8fc75aL,
  36174. 0x0fb38d0247da858L,0x088e54102998d4eL,0x36a2b17a6a7d9c1L,
  36175. 0x2c230cbf280f885L,0x2ddd71932b2823fL,0x02b0ac864b05094L } },
  36176. /* 85 */
  36177. { { 0x3606e398f5daf7fL,0x2152244249d419aL,0x1c5c08c58a72483L,
  36178. 0x343243cfb8e8895L,0x008795f022f362fL,0x1097d6ab258cebdL,
  36179. 0x06dbfb71710bd10L,0x2ef370805f817b0L,0x1c8d9c7dc82c1b8L },
  36180. { 0x1b41fdf18b8bed9L,0x20cc238e88c495fL,0x1de77291c4bbe94L,
  36181. 0x0ad05122abef3e4L,0x3c44da4629b0b97L,0x06fd428a577f18cL,
  36182. 0x1e313190b9c4630L,0x2ab6462d9bdde1aL,0x0f5a8a4e2fa121bL } },
  36183. /* 86 */
  36184. { { 0x0a55109ca0251eaL,0x3bb62c9e9b26c23L,0x0beb5620f528f2aL,
  36185. 0x3a2b84ff15a406aL,0x085993c079a8421L,0x346ac35c4d27c71L,
  36186. 0x35d90929e083590L,0x299be5b8a4a6ebaL,0x0ce96c2f1f8f599L },
  36187. { 0x0bc4b5112be8bd7L,0x11a83cf19fa66f9L,0x07d34d3a3864f48L,
  36188. 0x049cfd0e6076273L,0x026dce5671f6471L,0x00ac25af0caf0c9L,
  36189. 0x0682b7f7134ebffL,0x22d655813c02c34L,0x11cfd23d7eae3ceL } },
  36190. /* 87 */
  36191. { { 0x09646cca27689a6L,0x1f710d55905cafeL,0x248eb57cbfccd6aL,
  36192. 0x3ed6c6b7f94c2f6L,0x3711d8bf49b11ffL,0x1c39696e7cb6036L,
  36193. 0x118a1de879fdf0bL,0x354125d4d060dafL,0x114c8c526bd8cbfL },
  36194. { 0x1fe725bef7388bdL,0x0f6f7f9ffeba9f5L,0x1b897e6de2acf1cL,
  36195. 0x26a7afc6fede0e5L,0x36978514681a72cL,0x1499c2bd94995c1L,
  36196. 0x157d483925ecd9fL,0x32c090def374a0fL,0x1ceb5d732a7c80eL } },
  36197. /* 88 */
  36198. { { 0x3f9fccecfd376d7L,0x3aacfa99ac21369L,0x0d08d5b91bd86b4L,
  36199. 0x1fa2a8c1361ab24L,0x37f866a4faa3d5bL,0x2e04eb849fcf50aL,
  36200. 0x0a920695d19fa8bL,0x073774e1e635f8dL,0x073df7c0a69a32cL },
  36201. { 0x22c01bb38315b16L,0x29f226786323e6fL,0x3fb408b6b8531daL,
  36202. 0x231a024aa068f50L,0x2836faad4b159e4L,0x11a65cc1dfa4f67L,
  36203. 0x17e476d4ed6361aL,0x07e995a72cfd98aL,0x185b69d8183e781L } },
  36204. /* 89 */
  36205. { { 0x0f27eb3ab9cb764L,0x3bf0863af075b46L,0x0ddb0479aa79bbbL,
  36206. 0x09027950bd51dd8L,0x1bc699b96b4d16dL,0x3236322b8d70e34L,
  36207. 0x23a45d13b2ae258L,0x1301215e705499eL,0x0d9773b73576c55L },
  36208. { 0x220a4730218c299L,0x38a6ce67de28ce5L,0x2009484f414f69bL,
  36209. 0x0de68b293511a12L,0x268db7ab3b2c749L,0x0d70d5fc2701dcfL,
  36210. 0x3de3f26181f0599L,0x1b82024c4c0f62dL,0x060f3effcd0e0fbL } },
  36211. /* 90 */
  36212. { { 0x23c14beb25d6530L,0x056ce66a5f503dcL,0x3c4bfbf7f6225e0L,
  36213. 0x27052d3c3c48270L,0x23f7e8ecf83d8c5L,0x3ac7bc3f3c00bf7L,
  36214. 0x1f0c6035d353c91L,0x3b8d0e5310a9480L,0x1b5787128ab7be8L },
  36215. { 0x0937d3ab70110cdL,0x293bf11de446d68L,0x2f5bc53a4c19e0fL,
  36216. 0x3cce35427cb1ab2L,0x3e54ac1c6bd3010L,0x13ca8efcfb8aa0aL,
  36217. 0x09c7b931ea67c3eL,0x0d8bde93299bbc2L,0x0b05bda2c4f34a2L } },
  36218. /* 91 */
  36219. { { 0x024a071d1f575cdL,0x24ec06948dc60adL,0x36029a2c9d40156L,
  36220. 0x22e72452980504cL,0x1095b31c150c434L,0x0bf5258a40915cfL,
  36221. 0x10b2776f975fd22L,0x24dee85c1221b88L,0x1f6ac29b8136dbaL },
  36222. { 0x1edef55775da491L,0x14fe78adaab6082L,0x21061bb40d5b259L,
  36223. 0x04535449f619a5aL,0x181ead062cfc453L,0x3cedc48cbc8772aL,
  36224. 0x06f20d3f3e4f07aL,0x3d6ec4b341ae259L,0x15e241363696910L } },
  36225. /* 92 */
  36226. { { 0x0844fd03ecfc44eL,0x17cb21410ecf543L,0x27dbc9bd059a409L,
  36227. 0x3ebd96fb37e697fL,0x1a67961cd239328L,0x2ed77f778c4091cL,
  36228. 0x3dc5baea9e39bfbL,0x30de6008adb404cL,0x141bed7aa9b5f12L },
  36229. { 0x16f0059fd94d941L,0x3a7c01f53fc0602L,0x3598779f05e3fc6L,
  36230. 0x2cc0120f26798ebL,0x372a198704c40f0L,0x192929c4134bfbbL,
  36231. 0x367f1edb773b5b4L,0x2f4a802d9dc3d24L,0x1694f7e03012a9fL } },
  36232. /* 93 */
  36233. { { 0x1f5dd738a9095fdL,0x1e80874f3a15e83L,0x396be5edc767c4bL,
  36234. 0x3fc6028202242a9L,0x366f10aab56497eL,0x261e5d9ae615b87L,
  36235. 0x280601312988243L,0x2a4a585d233dceeL,0x01207d9076c555dL },
  36236. { 0x3049a011c44394dL,0x097bdc339279142L,0x09f0b1694265f5fL,
  36237. 0x3f8426ccfe078e8L,0x3a30932e42c5bd9L,0x1b3e2bc81fca90fL,
  36238. 0x366722736abfcacL,0x09ac2b7dfe813ccL,0x0e02f1e92fbfa9dL } },
  36239. /* 94 */
  36240. { { 0x124e4a663be4d4aL,0x15efb59bcf32465L,0x13fa7e7a7ccd1faL,
  36241. 0x1aa2317474f75f2L,0x23f251f1e70e8cfL,0x0d5533d6c95e65eL,
  36242. 0x1a71090a5ec58eeL,0x227a9a349a35c19L,0x04c7c23d4d20850L },
  36243. { 0x3ae575bbd52d132L,0x236a9ce32073158L,0x2e51e4e63b990fbL,
  36244. 0x19ac8e74e1c25a9L,0x0a5d49fed51d6b3L,0x0ea301ebb57e21dL,
  36245. 0x286ae2025091d94L,0x3bd68403e116b91L,0x1c21af59d747eb4L } },
  36246. /* 95 */
  36247. { { 0x37bc01edd441308L,0x0d251218c222417L,0x0a74759611cd0dcL,
  36248. 0x185308f3998abceL,0x1f8bafed211a712L,0x324f81e4dfcc5edL,
  36249. 0x0c52cf4efbb9ff4L,0x360aa203c3b763bL,0x028480cdd2cddc9L },
  36250. { 0x0f1ca0dc3f807acL,0x393f0af41c1527aL,0x0a1491f8bb6c6a3L,
  36251. 0x3f4f5b7eb36b4f4L,0x15fb46ffbe3ee1cL,0x37573ef3b91ac6eL,
  36252. 0x38e8b75207b3ac7L,0x3446b56030366c6L,0x08452c669f4c7bdL } },
  36253. /* 96 */
  36254. { { 0x02b4747c0ace6d5L,0x32d92ef9ca1eb69L,0x089989bc2614d5aL,
  36255. 0x0dbfc171c7bccc1L,0x2d35ac450817fe8L,0x1d6a70f1dcbac91L,
  36256. 0x00d6fd7f5fc2163L,0x25ccfedbe786b2fL,0x09a7643c315720eL },
  36257. { 0x32216b4f3845ccfL,0x1d3a0242f016f52L,0x0c74d60490379c1L,
  36258. 0x2858d632019e954L,0x1aa677b6dbd7220L,0x1b8b823a0e3e710L,
  36259. 0x2f6da537332c196L,0x18c36c0ca1d7925L,0x00c52b274cf9c30L } },
  36260. /* 97 */
  36261. { { 0x2c2e7828ea58bebL,0x013074d997e921bL,0x1fad20b40ff02b4L,
  36262. 0x2d8a74f9a9551b5L,0x166c81991fb5df7L,0x38b3f8fbc61a11bL,
  36263. 0x10d16bbe690bde6L,0x23a4a5ebae68050L,0x0cb59d81548baccL },
  36264. { 0x105d3adbaf66a23L,0x0dce1d037ec2076L,0x35de4b00f432c33L,
  36265. 0x3a01f4e80f9b554L,0x3066bca80e17fe8L,0x2b7fe954a5513fdL,
  36266. 0x226ea460c2b96cbL,0x13ff27c06365116L,0x11ed543816724a3L } },
  36267. /* 98 */
  36268. { { 0x2a873fbbd7f8a61L,0x2335c6ef9602ed8L,0x1eb3667f69805e1L,
  36269. 0x1855c74f703f572L,0x1783f9bc8ab8d4fL,0x10e62c538b91485L,
  36270. 0x1811b536c3774b2L,0x38f0cb6d28d8dd3L,0x1389f7f12972debL },
  36271. { 0x397f21c798fefb2L,0x1bf2d441eea9caeL,0x3760fadbb5689c7L,
  36272. 0x39f4cfa9b144befL,0x3236134a51a648bL,0x261624ed04a8a64L,
  36273. 0x26ada44a3d81698L,0x2d15d8512563cf9L,0x140b4dfc79b7687L } },
  36274. /* 99 */
  36275. { { 0x3b145707abe5bb9L,0x32ff63947606fa0L,0x1f49c9827affae0L,
  36276. 0x1229a1ed550836bL,0x3eeb41733c3a725L,0x0e09f18c20098feL,
  36277. 0x23b70e7014fdc3dL,0x1c5a1f4063e12d7L,0x0151d483e00fbcfL },
  36278. { 0x14e3c7c6b578aa3L,0x33a6d74c10f6b85L,0x1e9bb6008101511L,
  36279. 0x04bd016b1bd57e2L,0x02008ac7b4ec311L,0x1714be99f99a936L,
  36280. 0x0ac2eb73c00d392L,0x1d14fb86e66622bL,0x08fdfa31d9560b5L } },
  36281. /* 100 */
  36282. { { 0x074a0e0251cf8d8L,0x225274107caf4b3L,0x0a4933ebce52d4dL,
  36283. 0x145716f36b82dcdL,0x016200b93e1ac5fL,0x1e4dcdbb4fb37f3L,
  36284. 0x2e69402506a266aL,0x3e4d56168722fa9L,0x00e081cdd539190L },
  36285. { 0x15f995653e28412L,0x149bcb6c9c592c1L,0x25eb1df3adc70d1L,
  36286. 0x32b74d77b773558L,0x1a838ffe2d2c453L,0x30339627b510a12L,
  36287. 0x19b609ad20c1375L,0x3ec1cb57eea06f6L,0x1ad5be41dcc622eL } },
  36288. /* 101 */
  36289. { { 0x23af6678f850756L,0x0deab94bced65d5L,0x0a53796842f586dL,
  36290. 0x27fdd0fe65c434eL,0x193f1a8bacdaaf9L,0x027df364be9d579L,
  36291. 0x10650b1af04e154L,0x3f6698efe682b5bL,0x00e67b1cead55abL },
  36292. { 0x260a8e0b5f43178L,0x3504b6730d6cccdL,0x3a63880f680856bL,
  36293. 0x198b988b1c4f5efL,0x36ff824457f372dL,0x36c13946b5edef9L,
  36294. 0x115c8d0f2bde808L,0x00bcb879e07f92fL,0x1941f475bfbb8e5L } },
  36295. /* 102 */
  36296. { { 0x1482bf9d63543ecL,0x32d9f2845fbcf9eL,0x0638160ccc63985L,
  36297. 0x355ca6f707a2b14L,0x1a22686df556cbeL,0x207addf358bb65fL,
  36298. 0x3a2ed9b124cb5fcL,0x16e5935ed3d99cbL,0x17260b29aa77833L },
  36299. { 0x1bfc7b6a43df7c6L,0x32b08ef081c1b08L,0x37bc345d958085aL,
  36300. 0x34a8ca822f3adbcL,0x2d1953c5e9d8f20L,0x13da0343c22493dL,
  36301. 0x29912c7d25d7c6cL,0x19131939a88dcb7L,0x0ebda1c06c452ceL } },
  36302. /* 103 */
  36303. { { 0x2677c5c411dd110L,0x1e1ea8b26471289L,0x2a41a45666d60d6L,
  36304. 0x2ab057e7c554ef9L,0x30e0cc7b273e716L,0x29892ac2a4ee18fL,
  36305. 0x39c260a40571172L,0x3c4c3979d95b868L,0x046af8d78b52ef6L },
  36306. { 0x16214b170f38dffL,0x1760a048e84415eL,0x04d4957ed8123e3L,
  36307. 0x2e83698058411a9L,0x154f84413618fa9L,0x27aa56af9f374a9L,
  36308. 0x2a30b4f1c2563e1L,0x26aa7111678532cL,0x183c748add661ffL } },
  36309. /* 104 */
  36310. { { 0x2981f399de58cafL,0x2e03f61d4fa990cL,0x1f242d11948605bL,
  36311. 0x0180fbac02b20feL,0x17c73d79cf490cfL,0x0935186d00dfc94L,
  36312. 0x2420cf844209fd7L,0x23e89ac0fdb489cL,0x1526f4bd29eb343L },
  36313. { 0x24d034ac389e51cL,0x2957a5b6df663a5L,0x17dee913c583acdL,
  36314. 0x1effac0d102cabaL,0x09d461e29079307L,0x10efe2faa85b8deL,
  36315. 0x3d8c3fb0a675330L,0x0977275d2690ae9L,0x0ec7c41e6d66bb9L } },
  36316. /* 105 */
  36317. { { 0x29b345dc5da8398L,0x1a107eece310c0bL,0x05627c3bb47abc6L,
  36318. 0x0adce34b37738ebL,0x3687311858fbeb1L,0x2f53d3d352f0ab5L,
  36319. 0x0e1b0e9521db1cbL,0x2f8f8a9a432bbf9L,0x194375215eb7bfeL },
  36320. { 0x0b234f12edfd661L,0x26613bb54b07d13L,0x3260d8f8f98c014L,
  36321. 0x391ef8e1640cb49L,0x195e8b672fe76e4L,0x0ac03a0950d61cfL,
  36322. 0x161eb8916c397ffL,0x06ef8ee6fdc16ebL,0x0007ee90182ae13L } },
  36323. /* 106 */
  36324. { { 0x36fea9e93fbcb5cL,0x2f960e7ea14a6f4L,0x3125fd611ba0382L,
  36325. 0x1ff362898dc2c90L,0x23d8d4704a59ae3L,0x13106de6ade3183L,
  36326. 0x249cc51bac243d4L,0x1fa7f10007fabb6L,0x0f6988ea44a83dcL },
  36327. { 0x190caa4f077f79eL,0x05d807678964353L,0x3bb3d21b4b77f4dL,
  36328. 0x18240df86d8477aL,0x2135becf0031b3fL,0x0a40f76bc44fb60L,
  36329. 0x319296f6c01379fL,0x2b614daf79f2a9bL,0x06c57d3b6849dbbL } },
  36330. /* 107 */
  36331. { { 0x23fee389abfccb0L,0x38a892e59db98e5L,0x0f0284ba6d276c6L,
  36332. 0x2e919614f47e1daL,0x11b8ab9b6c38ba3L,0x1e81ccc5b8eacdbL,
  36333. 0x233f3201fc97424L,0x379ebf7505c6094L,0x0214dacfa81ac61L },
  36334. { 0x25a9f37eaa3198cL,0x228d17f22e6754dL,0x312ad4f5ecbccbeL,
  36335. 0x180308dd452909fL,0x228a27b05e841ffL,0x0a167fcd767a316L,
  36336. 0x0bde372d3774446L,0x16fe0701183ffaaL,0x1810a0e49a129cfL } },
  36337. /* 108 */
  36338. { { 0x08203af45843c3eL,0x078c0eaafaeb9daL,0x08f3624df62b460L,
  36339. 0x22b48796aa0e5ecL,0x39a242b0e568734L,0x0a9db1b4b3c4b1cL,
  36340. 0x2751a2c848ed013L,0x0b416dcaa870bd4L,0x0f3b63296c392c0L },
  36341. { 0x24b42adc6f3d1f0L,0x37314cbd4cae533L,0x333583443d9c2f0L,
  36342. 0x3bb7237672d5e04L,0x1ee87192fb50118L,0x15d06708c0e7869L,
  36343. 0x396b0c9977267d5L,0x30d6918bbe930c3L,0x1f7454fb7963cd3L } },
  36344. /* 109 */
  36345. { { 0x0f281949d153926L,0x0a32460ad5d5204L,0x3b30509e94c942eL,
  36346. 0x0ab7a75ad5d2d08L,0x18b3ca314c5acc5L,0x18f56f16a9d1b0eL,
  36347. 0x0cc9890f4ea307cL,0x2465109554e8b87L,0x08e271198bff76dL },
  36348. { 0x3900e463c8e672bL,0x19d734fcb7f09f1L,0x11f7af2163c9703L,
  36349. 0x021eb3aaac1c125L,0x17e8d236974d699L,0x04f7045520bc86aL,
  36350. 0x36cd13dcfbc1dc8L,0x2bfc8338af20013L,0x03f2a54662c82bfL } },
  36351. /* 110 */
  36352. { { 0x1cf41e61588a8bcL,0x23343884314b2c3L,0x22bd758e7a456f4L,
  36353. 0x12d22e6e55cce15L,0x3a6b89b9e1600d5L,0x263320bd1877e02L,
  36354. 0x177147f7fd4f170L,0x317e459fc073452L,0x048b13385116116L },
  36355. { 0x2b763335d2617f0L,0x295dc9bb2e181b7L,0x032d1b91fce93f9L,
  36356. 0x22db212e65ea4f0L,0x1823ca5bef7a438L,0x168cbdaeffa0089L,
  36357. 0x0b5c586f19c0283L,0x07767c9b356b78fL,0x1e77f5ddc776d0cL } },
  36358. /* 111 */
  36359. { { 0x09feec86ee764c9L,0x3b20dac1f20b30fL,0x32e6a005b142d1bL,
  36360. 0x28ca7a297a9afc6L,0x23ffe241c70ef51L,0x0a59b0a145f4a63L,
  36361. 0x3acc76bb389e287L,0x086d4e8b6a2a4b1L,0x04a902c9126732aL },
  36362. { 0x2c51b9c8f7ce110L,0x0cea1ebac0dbc65L,0x10980a6a59e2dccL,
  36363. 0x29f9e36d40209a5L,0x0c95bb030ceaf26L,0x1310bd0a0bcf0e1L,
  36364. 0x2c4a0a6dd6e9f72L,0x0bbf1da3778a5c2L,0x16f4aedce4b03d2L } },
  36365. /* 112 */
  36366. { { 0x37f032aeded03c0L,0x128149623775341L,0x3c4f9a85be0f268L,
  36367. 0x1ff82e6daedb426L,0x2f2fb5887bdda0cL,0x30f339f865a271fL,
  36368. 0x0d2ae5f8a96960eL,0x0866ac10f6755daL,0x06829c8081bdb21L },
  36369. { 0x3f872fade59f006L,0x27ff1b2e5fbd69aL,0x15db58ae7ef8c2bL,
  36370. 0x287d332a87cdc64L,0x289c27cc4c2e23cL,0x21af73186be3183L,
  36371. 0x18de43eee5d7e7cL,0x3c22e4896d1fe6fL,0x0b453e7f4634b24L } },
  36372. /* 113 */
  36373. { { 0x0c496d0e3048bdaL,0x19d2650f0f79395L,0x09f74c2d509ee2bL,
  36374. 0x07950f14226b081L,0x3105a365bb01f69L,0x22c5c1273665828L,
  36375. 0x2c946734d93ffe7L,0x29d540a7e66cfe0L,0x091785c5ea20161L },
  36376. { 0x055f978953dbdb6L,0x3a13665fb2867edL,0x102936d4d75aea9L,
  36377. 0x2a30549dbe91cefL,0x347c76356a9c17cL,0x0e5ce34a73d984cL,
  36378. 0x3336094a68360b0L,0x1fc874f90c2a1a5L,0x1b40ae532dee2b2L } },
  36379. /* 114 */
  36380. { { 0x0110e825164cb8bL,0x26bd3c954a99f5aL,0x2d0e8d185527697L,
  36381. 0x21fed93ab138435L,0x3ac424592cf6c57L,0x33836042102058eL,
  36382. 0x04c15c5d8fff37fL,0x0fb262ca139276aL,0x010ed8055673266L },
  36383. { 0x06f403051f3ee9eL,0x38fba6ce2b7c784L,0x3a6ea13d64492e8L,
  36384. 0x1160386aec74f21L,0x10bfd729827b49fL,0x3f1e8d7f0a0f45eL,
  36385. 0x23ad4f8fe50fa5aL,0x077c9dcf69516b7L,0x1f878bfaae4d9a2L } },
  36386. /* 115 */
  36387. { { 0x260d8e8abad5678L,0x29cb3b9803096ebL,0x20b44c288e210afL,
  36388. 0x1db49533e7ee753L,0x0959e2ba564447fL,0x25844cb07ecdaf1L,
  36389. 0x140f19393c44d72L,0x199235ea2207ff0L,0x09127a861288d09L },
  36390. { 0x136c0218a9e690cL,0x331487aad3e856dL,0x0423b00ee54c85dL,
  36391. 0x096bcea392026bdL,0x0b7731d85b37935L,0x1073ed5787cd8c2L,
  36392. 0x3c4529b5361d781L,0x098d3a907ca7bbfL,0x0e8cf5755b19f7dL } },
  36393. /* 116 */
  36394. { { 0x1edb80dd212b398L,0x25860754f74dcc0L,0x20478a52fa95d03L,
  36395. 0x0ca9e0979b43821L,0x1330ece4fad1e64L,0x01e24dbf80616f1L,
  36396. 0x3f6ea3508f7313bL,0x1ad8077260bf679L,0x0e8dbf3a602d555L },
  36397. { 0x3763234279e05bcL,0x3d03b3d1114f4f0L,0x1f4d7fa307937f5L,
  36398. 0x0d84235f888c431L,0x3c2a98bbc5cffadL,0x1f51fe03cbc07bcL,
  36399. 0x322e1c30ab1719dL,0x37e51ef27e462a6L,0x1f9f53dc52ae834L } },
  36400. /* 117 */
  36401. { { 0x266b49ec183f89bL,0x2d7c097d601b53cL,0x02b594ec3080d3fL,
  36402. 0x100dc73645f4c29L,0x3b7f7e26d4b6b19L,0x356ded93dd506aaL,
  36403. 0x0036c5e55269eb2L,0x099d4386a1705feL,0x1cea0ff0f22da5fL },
  36404. { 0x02bd56a3a8e11f8L,0x190087d7e6ad518L,0x2c5a0ccc92d7298L,
  36405. 0x39948fd942f19d0L,0x3f7fabfb4d64569L,0x0f279b2f2391a06L,
  36406. 0x35ff20b4275947cL,0x2ba88ace54b54e3L,0x1b0818f8e381f04L } },
  36407. /* 118 */
  36408. { { 0x3e5bffae50d90f0L,0x0ec46fd4047370eL,0x2711a691dfac4cbL,
  36409. 0x0753a869dcf8432L,0x3e586eeb662ec21L,0x030bc7f56a5e7aeL,
  36410. 0x3bbfea4df16ab1aL,0x09bdbfa78fdfb15L,0x15e1b05960e5ae5L },
  36411. { 0x08e04a58630e62eL,0x00c439911f86dc7L,0x2b6143b4447a3d0L,
  36412. 0x145d18b9e8f3c79L,0x00002724d92abb8L,0x114a5b7e0c27a82L,
  36413. 0x0ed8121d805d70eL,0x351383ce126ccf5L,0x0962d6bffbc6834L } },
  36414. /* 119 */
  36415. { { 0x13fe58d48e07711L,0x20d92349c28ecb4L,0x092d8cdff04c70fL,
  36416. 0x1e145047c50545eL,0x03e4f8a5515bb65L,0x104cd8bdb0c7364L,
  36417. 0x206d4d73f871520L,0x0c5fcbf8097bbb2L,0x0ad32a6e417954eL },
  36418. { 0x238c63f69d147dfL,0x2ec1b9c42fcdedfL,0x2bef28d514deb69L,
  36419. 0x3ee34470f66e537L,0x10385c6044b2307L,0x1e003a0cecda77eL,
  36420. 0x101c1c68ea2f49eL,0x1e063c0a2c961f5L,0x055970782215cefL } },
  36421. /* 120 */
  36422. { { 0x0c351db54c1d751L,0x114c06e83e54484L,0x334fbfdc8bed814L,
  36423. 0x0e33c8da02a9dfaL,0x0e04f2860498d81L,0x1a96db6a4a30529L,
  36424. 0x1a910396192dba1L,0x10409277aa56d7eL,0x08580dd45780172L },
  36425. { 0x10725000e09221cL,0x016c87c877815baL,0x2fa1e0e6095062eL,
  36426. 0x1edbddd44a51232L,0x1f1f34aca657fb9L,0x27fc575974a646fL,
  36427. 0x09ec79a66cd5ac4L,0x2baa37075a25f41L,0x067388fca84e72bL } },
  36428. /* 121 */
  36429. { { 0x120b49da6ef1dd3L,0x281178ee9b35d99L,0x180af33d5f48391L,
  36430. 0x2cbbc1d1d2a7212L,0x278bfb1eae53cf5L,0x36a41bea8d6cba6L,
  36431. 0x1f2cf4eca97fd6eL,0x21627c6a4de246eL,0x10d667533693ab2L },
  36432. { 0x351049673691fafL,0x0f4ea755fb18616L,0x21bb930a8525dc7L,
  36433. 0x07902c16da5f8a4L,0x3413bedca094f57L,0x3469ae617a5a805L,
  36434. 0x2de8b79e7d4f728L,0x115355450ff68faL,0x0fb859b8444d16eL } },
  36435. /* 122 */
  36436. { { 0x022083e7c667aafL,0x1172e52a4732e9fL,0x19318ca0e94a335L,
  36437. 0x08f93aa831f287aL,0x242f56844c3afffL,0x0354b42e886b10dL,
  36438. 0x1301d4fcc68a8b6L,0x2f3850069616daaL,0x0a3547f762c907aL },
  36439. { 0x3dd3ed3fbe260ceL,0x1dd4b6037007e98L,0x375d6f1da3e4271L,
  36440. 0x1294987c43b57eaL,0x3d20cd6bb5f1686L,0x086b195af9ec7d8L,
  36441. 0x3b918e9d638c102L,0x0bee0c4dee3d99cL,0x17423eb44384adaL } },
  36442. /* 123 */
  36443. { { 0x14e27c42a1fbcf4L,0x34a16d7eb357b86L,0x2bdd915e66074c0L,
  36444. 0x043bc29aa69d70bL,0x1067cf4581e6965L,0x2fb87ee84f16be8L,
  36445. 0x1279e72be013c17L,0x33d6616901b5b6bL,0x0310042951d5142L },
  36446. { 0x2735ec1a22bbc45L,0x14e469fd5bd361aL,0x39d0236001de4eeL,
  36447. 0x146a8be3494c16bL,0x0187db78aa8b218L,0x06a2230c38b0db6L,
  36448. 0x3e7d5bcfcc083faL,0x3408ee476adfef4L,0x0f462d85460f4fdL } },
  36449. /* 124 */
  36450. { { 0x168ba024972d703L,0x132874e426280fdL,0x2542ae28c855fc4L,
  36451. 0x1816c6d14dba6e3L,0x34c7f7e484fd4f3L,0x08c208f4b822c1eL,
  36452. 0x09fd13042f3b982L,0x20d6727ff4c4c62L,0x1bb56af0652c6c6L },
  36453. { 0x1bf05e206e0f16aL,0x2b0beb5d191297bL,0x0a980f92c71afc1L,
  36454. 0x35cdb2002879668L,0x2236178dc13ae37L,0x2d1bbc417c83bf1L,
  36455. 0x2509e4443a58b82L,0x366c32545f73d10L,0x1667d0bb415640eL } },
  36456. /* 125 */
  36457. { { 0x2a30a613d22842dL,0x3803d6cf13b380eL,0x0f876df82b798c6L,
  36458. 0x1b5e34823161d93L,0x1e788854ada92d8L,0x166c2650294b4e4L,
  36459. 0x05fc9a499b26fbaL,0x3c4d17704ceb413L,0x1dda5c0926934e3L },
  36460. { 0x30dcac2fad6d673L,0x3f7c1403cecff9bL,0x1941631756e96d8L,
  36461. 0x24c2936038fb39cL,0x231d130013990f4L,0x156058e3cab2a4dL,
  36462. 0x1d5679ee91966c7L,0x07369b7c3d5d39bL,0x111be124868ccd7L } },
  36463. /* 126 */
  36464. { { 0x244c726475cc1b4L,0x3f0be4adce5e33dL,0x26d10e3d7eb7915L,
  36465. 0x06bd030e381969fL,0x1e1ad24fcbb44e2L,0x0d581b9662198aeL,
  36466. 0x0f93f7270ba4ddcL,0x2935f0e0d28b069L,0x02193d0c9a23362L },
  36467. { 0x2cb7b8cf769fd7fL,0x176a5e26884ee78L,0x0c566b910fef181L,
  36468. 0x0249a4c50e1ed3eL,0x1925b37c02088b3L,0x1a9903951dedc6fL,
  36469. 0x21c6efa049a9212L,0x15acb4f77c6f7f4L,0x0649b5f9d7d232aL } },
  36470. /* 127 */
  36471. { { 0x240adf8679a9c35L,0x36638f2dd35e5b5L,0x0ebb5f8e9dafcdaL,
  36472. 0x13ab5281cf1192eL,0x22edde557473861L,0x1db382e6f61b03bL,
  36473. 0x15fb96773317385L,0x2bab66d74cc9d02L,0x13672f0aeb3ee09L },
  36474. { 0x388c76d64e54ba5L,0x39ebc7711d34868L,0x29d1b2a7708163fL,
  36475. 0x27b784902b5fe8fL,0x2c720303a0447b4L,0x1af4084f67d92d9L,
  36476. 0x203ea5b1c78029eL,0x174ac72bc71c02aL,0x103179180eb3bb8L } },
  36477. /* 128 */
  36478. { { 0x1bf4f9faf2ed12fL,0x346793ce03f62abL,0x3db5a39e81aece1L,
  36479. 0x08589bbdaf0255eL,0x20cf5b28df98333L,0x00e4b350442b97aL,
  36480. 0x067855ab1594502L,0x187199f12621dafL,0x04ace7e5938a3fdL },
  36481. { 0x1c5b9ef28c7dea9L,0x3e56e829a9c6116L,0x02578202769cd02L,
  36482. 0x0225375a2580d37L,0x3b5dea95a213b0bL,0x05f2a2240dcc2dfL,
  36483. 0x1ba052fe243ed06L,0x25b685b3d345fecL,0x1c0d8691d6b226fL } },
  36484. /* 129 */
  36485. { { 0x22edf3fbf8015c2L,0x208db712540b62aL,0x36e0a6a43157e7fL,
  36486. 0x0968b412c33a243L,0x1a809dbab318ef3L,0x299f288673019a3L,
  36487. 0x3ebc49dd26937adL,0x261123c9f04b20fL,0x02987b3db2f3c9bL },
  36488. { 0x3e7aed0fd2e3dc7L,0x3a2f6dd057f554dL,0x2c9a58a45f25498L,
  36489. 0x2e882721743f035L,0x2d579e1ee83d5baL,0x140affb4c7b2371L,
  36490. 0x01bef11f4cad0baL,0x3299710cb9b387dL,0x1913b10afaabbffL } },
  36491. /* 130 */
  36492. { { 0x19f7df053053af7L,0x011d96ca2873d2fL,0x38fc7ce90438603L,
  36493. 0x1bab2317775105dL,0x3fb59ec618fbed3L,0x06c6fb3c9ec4c4eL,
  36494. 0x1973a99d2656ffaL,0x2d654cd384d1651L,0x18c3261888cc362L },
  36495. { 0x013a414aa7f6ff8L,0x2bae20feadf1ebdL,0x086b7cc307ba092L,
  36496. 0x0948d18403be876L,0x302140c93dc81c1L,0x184120d64f5349cL,
  36497. 0x1795f3a1ed7e3ceL,0x3505b8ae47b3f7cL,0x191160dc11a369eL } },
  36498. /* 131 */
  36499. { { 0x272f46e8b57d7ccL,0x02c3952fc08e1a6L,0x396e05b3a91d314L,
  36500. 0x2a693b09b8221b0L,0x3c50f58e91b9ab3L,0x1789abc1d0bfabaL,
  36501. 0x1cd9f71592c6085L,0x0b22650f351daecL,0x17c3ed97fd4c7f0L },
  36502. { 0x3b02503e6d54964L,0x34458b1a8c63014L,0x2cf49cc28c22d9bL,
  36503. 0x1000d4d190063fdL,0x2b4cc0668a45c78L,0x10b6f80e3a8ccd7L,
  36504. 0x36c3cd7ad727f8fL,0x0b5dac55fa447f7L,0x1b3a7f894c9ec99L } },
  36505. /* 132 */
  36506. { { 0x1e6e397af09ea77L,0x1d82e5d77097164L,0x0c08b94a197b26aL,
  36507. 0x2a2da3398663010L,0x15bd23564041bacL,0x25deccfe8668345L,
  36508. 0x3bd02986ca5b94dL,0x07e67cc7e1fe397L,0x0b8f76c55a6b190L },
  36509. { 0x35bf8c33846ec9fL,0x08817277ab29185L,0x1ec0a3108df0f46L,
  36510. 0x20f3ebb64a24b2dL,0x065049fb2879db2L,0x1bb940c51df7001L,
  36511. 0x2dce4548d24bac9L,0x1a13e9f6dac595aL,0x0fc0110cdabab1cL } },
  36512. /* 133 */
  36513. { { 0x11b66d84d308bf2L,0x04f27f598e00105L,0x1f92fd383bf9990L,
  36514. 0x210fff23bf1a24bL,0x0313ea287a10efdL,0x2837dd0149f8c5bL,
  36515. 0x2bd2a18ef6e3cd3L,0x3933b2e5b90c3dbL,0x18cc1ebecf2a70eL },
  36516. { 0x0d14ad71a70404cL,0x087743e738a8c20L,0x3cde3aa3e0726adL,
  36517. 0x0458d8e9a42e532L,0x1c6b1e2b40ab596L,0x1b3bb16f9c2ffd1L,
  36518. 0x3757c01296dd0b6L,0x247a3532ca9d1d1L,0x0aa08988ca63d7dL } },
  36519. /* 134 */
  36520. { { 0x22dcfcaf8db0396L,0x3a3cded08b69daaL,0x034996485724e8aL,
  36521. 0x311efc524fd94beL,0x2b0247a4ef647c3L,0x2baf6a3a2d802d1L,
  36522. 0x158df0abf3e4397L,0x2eac8b8748c7e9eL,0x0ef38e692b1f881L },
  36523. { 0x33c168926cf3047L,0x053e51654e61607L,0x1d1c293f20b6dadL,
  36524. 0x1bbd5eaec5ff7a1L,0x01794de382ea543L,0x2ffb34bc346a3ffL,
  36525. 0x3860429ba508e22L,0x0c7e0443c29ff6dL,0x1962ade6f647cdeL } },
  36526. /* 135 */
  36527. { { 0x196a537fec78898L,0x2779cb783e9dff2L,0x36acd34cb08f0b3L,
  36528. 0x20b69e34d4fdb41L,0x3a0392cc1acd8bbL,0x160552757fa0134L,
  36529. 0x27c6d9ab7adedeeL,0x0fcde20e4068301L,0x1915855ffa24ed9L },
  36530. { 0x1570e36bf9ebef3L,0x011a977d2cc5dcaL,0x1a95a6816b5ce21L,
  36531. 0x204a2343847e6e2L,0x13979159aadf392L,0x323eaecb5aeaaf9L,
  36532. 0x07af10411afee05L,0x38defc64b0ebf97L,0x0f7aa72e81cd7dcL } },
  36533. /* 136 */
  36534. { { 0x0fa3c0f16c386eeL,0x2c11a7530260e48L,0x1722876a3136b33L,
  36535. 0x248f101b019e783L,0x24debe27d343c0aL,0x25bc03abbc8838fL,
  36536. 0x29dcff09d7b1e11L,0x34215283d776092L,0x1e253582ec599c1L },
  36537. { 0x08ef2625138c7edL,0x10c651951fe2373L,0x13addd0a9488decL,
  36538. 0x3ea095faf70adb9L,0x31f08c989eb9f1eL,0x0058dda3160f1baL,
  36539. 0x020e3df17369114L,0x145398a0bfe2f6fL,0x0d526b810059cbdL } },
  36540. /* 137 */
  36541. { { 0x049522fa0025949L,0x36223c2ef625149L,0x2f5fe637216fb26L,
  36542. 0x1911ca09fd8cd10L,0x399fc2681d8ec3bL,0x231dc4364762868L,
  36543. 0x1b27626d232ead6L,0x27e9e396ff8bf94L,0x0040f9f4fedfd10L },
  36544. { 0x152ea516b4a05e0L,0x3523bbc871e3ac6L,0x26191997dfdbcb0L,
  36545. 0x0122d3087f5934dL,0x2be92303a0d11b2L,0x2317a0269bd5a6dL,
  36546. 0x005d8e2b8f60967L,0x27289c89ad6acdaL,0x1bdd6cff180db34L } },
  36547. /* 138 */
  36548. { { 0x09f8576943cc612L,0x10c67a0cacc71e9L,0x2297cccadebdc91L,
  36549. 0x10ac18660864897L,0x025b1cc7c4918fbL,0x191b97c2b32cc21L,
  36550. 0x0e3e22751d3347aL,0x00023abed2ab964L,0x151821460382c4aL },
  36551. { 0x02481dbbf96a461L,0x048ba6d4a8ee90fL,0x058e464db08b51cL,
  36552. 0x1e1b5a82074870aL,0x0f533cef7b1014bL,0x05517df059f4fb5L,
  36553. 0x1b7b9f6cfb32948L,0x30a67a91b4c7112L,0x081cfad76139621L } },
  36554. /* 139 */
  36555. { { 0x3796327478a7f0eL,0x060f8b785dc177bL,0x26df572117e8914L,
  36556. 0x026df354b3f4928L,0x3ad83c1603cdb1bL,0x027be326790ae7eL,
  36557. 0x254ccd6971d2ea7L,0x083f06253f16e3bL,0x0fcf757b4e534a5L },
  36558. { 0x25518cc86b62347L,0x072749ef0aa4a16L,0x2b052966727fec5L,
  36559. 0x0e82b90f9bcbba8L,0x205ca066bbc8a8eL,0x20ce61b6014d6d7L,
  36560. 0x374cdd91ffcdb18L,0x0890cbd296ee8c8L,0x12408763a490d20L } },
  36561. /* 140 */
  36562. { { 0x098b9724efac14dL,0x12fe369e6a74f39L,0x0dbdd6e07c29b6fL,
  36563. 0x3f5c5dc54e03c7aL,0x271b03263fac30cL,0x26d157d53247b48L,
  36564. 0x3092bfbf9383351L,0x0ef65da979e2449L,0x128a97674e1b481L },
  36565. { 0x1b63c41583e5924L,0x26bfc63c5c7418aL,0x33cdab227a2861fL,
  36566. 0x36a2846adc0ad16L,0x0e8db6971939d5dL,0x3b042014afed1ecL,
  36567. 0x0e1801562379df0L,0x12aeabd69920493L,0x1508d98c43434f9L } },
  36568. /* 141 */
  36569. { { 0x2a9fe73cfffc80fL,0x38ba6f50d1cfdb7L,0x3ed3c9d37ba7e23L,
  36570. 0x349e8ff0d5c9fecL,0x38e04a03d733766L,0x2ef83d0f436d33cL,
  36571. 0x186f4f8ce017522L,0x2c0df61fadc676aL,0x1536d1b50ae2fe6L },
  36572. { 0x31f5defda40bab1L,0x1aa2be6caf698cdL,0x1c890d4aca8707dL,
  36573. 0x3fd90ffe2ad7a29L,0x14bf8ec2f4d72f0L,0x3ae4f88a7130436L,
  36574. 0x2dfd0136b0eaba0L,0x2820af12c3a3c74L,0x1429f252e5a9d34L } },
  36575. /* 142 */
  36576. { { 0x2ffd4c17d0e7020L,0x1a6aaad52085a12L,0x1708588f348f9b1L,
  36577. 0x3fe21661aef6f80L,0x115f9c381daebf6L,0x12a529eecce61fdL,
  36578. 0x2d68497e455f2c0L,0x1e630e690510a83L,0x1541c1ad4a61ef7L },
  36579. { 0x247b628072709c4L,0x035a2e204397f9dL,0x0874e92e0f63b33L,
  36580. 0x2e7e2faa6eb46f6L,0x08318981a144e4fL,0x1a31a81f056bf06L,
  36581. 0x200b66e19c5c82bL,0x1ebb216315e88dbL,0x0119b25511007cbL } },
  36582. /* 143 */
  36583. { { 0x21ced27c887027dL,0x03ccd4afeaca184L,0x3c1c19d511e2605L,
  36584. 0x2a5fd31a7d5b8dcL,0x325226bb402d4c3L,0x0f9eb0c39bcd5abL,
  36585. 0x18fdfb3b9011c38L,0x28d8d0ec308f4cfL,0x00ba8c390f7af2eL },
  36586. { 0x030c3d67e851bacL,0x070e2697d513f31L,0x3c6467fba061899L,
  36587. 0x13a5f2f6fd001aeL,0x17734adadd49d02L,0x232db4a914e6df7L,
  36588. 0x24b3ad90ba8f9f2L,0x1a4a1ea4860c137L,0x06ab28732efa7b9L } },
  36589. /* 144 */
  36590. { { 0x1dab52d22ed5986L,0x3989e9614cf819cL,0x237acf155fe3deeL,
  36591. 0x035eba2c4cba3fbL,0x134a08b94cd6149L,0x270570c09c1b861L,
  36592. 0x25ad46a85ffd52fL,0x002ef568893cd46L,0x1e644d1b6d554d7L },
  36593. { 0x2830686862e4e9cL,0x335db121d8ff925L,0x1679c0839caafe5L,
  36594. 0x3ae360f58b580c2L,0x211bc4ae2c0e4cbL,0x13f2818a4478953L,
  36595. 0x22704596a0d7c86L,0x104b3d5e17757a6L,0x1be2f4677d0f3e0L } },
  36596. /* 145 */
  36597. { { 0x00012ddab01a6dcL,0x2f5b06b86b6da53L,0x1aecb9b05079391L,
  36598. 0x2798a84187ceb9fL,0x3a96536b7c2714fL,0x385d952dc65e3b9L,
  36599. 0x2b3dd4eec11bd05L,0x2fd871c459b83beL,0x1d70f7aa57287edL },
  36600. { 0x2ea6f7d51eb5932L,0x3a82a97e20b2909L,0x20977739f7dc354L,
  36601. 0x0aa6f95e4d05d6dL,0x378545eccd33519L,0x2d90f2766007d08L,
  36602. 0x23abec32b8e2567L,0x19426e504775c8fL,0x0ee656dea68cf1cL } },
  36603. /* 146 */
  36604. { { 0x138e140a0890debL,0x2f61f6f3ae12f53L,0x3f72ba041decbf7L,
  36605. 0x02a9a082fa547c3L,0x38c486298afeec7L,0x1c043b11d546428L,
  36606. 0x3879b1ecdba558eL,0x085733b6476e231L,0x14c08de3e4cef5eL },
  36607. { 0x01534ed16266da2L,0x0c8baded3240267L,0x0aef699276889ceL,
  36608. 0x1fc170a1134df7bL,0x31ac519ab652509L,0x168f321b48edf84L,
  36609. 0x0c4575682ebb726L,0x14dcc314c76e58aL,0x0be2e00e8b87380L } },
  36610. /* 147 */
  36611. { { 0x007c80057ed32e9L,0x39033df009265ceL,0x2abbabb54830427L,
  36612. 0x1bf3a082fd16141L,0x3b2c43e81564977L,0x3fbd9922d4d4ca4L,
  36613. 0x3bdca5671e8353cL,0x3f5e49c85f4fe40L,0x1dc40a9c109a813L },
  36614. { 0x3eaa6c33db21a38L,0x088b875cfbdf91aL,0x04e7bd1d507fcaeL,
  36615. 0x19161e9deac7fdaL,0x20c64a4d6f5bac6L,0x29f0de29631d3d8L,
  36616. 0x02e4094ca837d96L,0x3853fd0f7d4c4f9L,0x13f8a9a4347fb49L } },
  36617. /* 148 */
  36618. { { 0x1ab4edf992f8923L,0x2a9781bf4827ce1L,0x1b871b1340eee24L,
  36619. 0x07e4782ed009efaL,0x2f3d4c62c2957d1L,0x1ffdeabd096beb4L,
  36620. 0x14cbe92d231286cL,0x0d4a65904acac04L,0x19f6706a231c3e2L },
  36621. { 0x2b3bbd2225c02afL,0x2f0598fe8fa6341L,0x2b75b84f482e53eL,
  36622. 0x084aff1577e9b7cL,0x0512a73da912b45L,0x354faa90c2f6f50L,
  36623. 0x27fd53ac0f43d93L,0x092d3f0d63f9030L,0x0a32cb183be9194L } },
  36624. /* 149 */
  36625. { { 0x39b0c2d3fa6a746L,0x29e488756892a38L,0x091478cdf2b5e84L,
  36626. 0x1f4c199b2cdc296L,0x2f6d71d068a8806L,0x01974612c269c27L,
  36627. 0x1c944850007a3e0L,0x24eb1c11abd2ee3L,0x1fd2b6a3129c654L },
  36628. { 0x3d5d5bde45f2771L,0x0ac22bd0cbb6574L,0x00fbf232a6bb854L,
  36629. 0x10fa2fb32c8bb35L,0x2bf8e247f0fcb61L,0x368c0e6f3b3144eL,
  36630. 0x02a0df955d56f78L,0x3f8aa455f18655bL,0x18ca6d35cbf3031L } },
  36631. /* 150 */
  36632. { { 0x1800b1bbe0c4923L,0x2b9d01a40a41ef7L,0x337f957bd0c7046L,
  36633. 0x2765957e2e08e62L,0x2500f4150aa8e1aL,0x00b9ebbb34a49feL,
  36634. 0x29692e826a9c6d2L,0x15df2d33d62ce7cL,0x11f3093868cbf41L },
  36635. { 0x1cb5e7a333ed442L,0x3238be41bfbdeebL,0x01233d98f228ae5L,
  36636. 0x369fff84970b66cL,0x1ba2318354632f2L,0x0b4b14496521dccL,
  36637. 0x17d9c4a0caae5b1L,0x003dafc03996261L,0x172c5d1008654f2L } },
  36638. /* 151 */
  36639. { { 0x09540462fc283e0L,0x0ce611fb8220396L,0x340eb7fd1622f76L,
  36640. 0x07bd66317b7ebc6L,0x37e00d9bbecf515L,0x2310ff51ad364bdL,
  36641. 0x11d1d27543e3b3aL,0x2db4ce65384b194L,0x0c6dd841a1daf05L },
  36642. { 0x3da17e023b991adL,0x0ac84dc7ee94508L,0x2c5a0ddc1879aabL,
  36643. 0x2b57d8eb372d05fL,0x01e2a7d50173bc8L,0x041b4020bf3d484L,
  36644. 0x3012cf63373fd06L,0x117bc7a084779f6L,0x18ca07766d95765L } },
  36645. /* 152 */
  36646. { { 0x24347b9af80dfafL,0x2d8c7e71199fce3L,0x1b266ddbc238a80L,
  36647. 0x196aa1c6281bfc7L,0x0af31c35f6161e3L,0x31a11ba39fdeb24L,
  36648. 0x0175b4c03831d1fL,0x1cc68799a7441a1L,0x0c76da9d620934bL },
  36649. { 0x01f597ba3e4e78bL,0x137b7154267e6a6L,0x399593088c612c1L,
  36650. 0x01e6c81d162fcdcL,0x3a22769007c5683L,0x1f9b6bcf1110311L,
  36651. 0x129103b6df23c8fL,0x1e58d3d98b0950aL,0x0f9f4ea6db18b3bL } },
  36652. /* 153 */
  36653. { { 0x269eb88ced36049L,0x13ff87d06e67e31L,0x35636a72e10887aL,
  36654. 0x2319682ee29a42dL,0x096e4295567dd6aL,0x2aaffeb50b3e316L,
  36655. 0x2f26a45286b5f31L,0x3940c7df7ebca3dL,0x120c5d9e0ac0e1aL },
  36656. { 0x3bee3ffacc10da7L,0x0b57e651251b96bL,0x3e863c4220ff67eL,
  36657. 0x052f5bd8cba3b05L,0x3c3fc9ef4fe6f74L,0x0efee1c12a78f03L,
  36658. 0x03342d25ff3cba0L,0x334b863f4d802ecL,0x1ac1e63e7530050L } },
  36659. /* 154 */
  36660. { { 0x183d07c8f3d6a02L,0x3050f1fbd343477L,0x0bf0d4c7af6171fL,
  36661. 0x26209f173c32a65L,0x32b697882c8a93eL,0x2957a2e92840b1eL,
  36662. 0x2d64f0633c87d58L,0x007f06ba208bf30L,0x1c12ce9b53f986dL },
  36663. { 0x19639fd95dc1b79L,0x23dd50fd3985aa1L,0x3c4cede2fb9f272L,
  36664. 0x203543eba79b9c0L,0x3c2d530ed042f76L,0x375662b0151af0eL,
  36665. 0x29491000a4006bcL,0x258a4fcca1b2784L,0x14677782255b6bfL } },
  36666. /* 155 */
  36667. { { 0x381421ee30c98feL,0x03fac3f0b35c16bL,0x0ca614df6ad2debL,
  36668. 0x37a6e8c53a26cb1L,0x04f04b16dd38134L,0x01fe32a2910f7aeL,
  36669. 0x0f3917fc556ee0fL,0x33504f0720eece9L,0x1998397dd24b1adL },
  36670. { 0x201e17edf4781e6L,0x1f0c651bc7e4072L,0x2613b53090da32dL,
  36671. 0x3729f23181e889eL,0x2ddc697092495b1L,0x1582026073cbefbL,
  36672. 0x1134d71d3d82bb4L,0x231073f37768c21L,0x0d23dd171b59679L } },
  36673. /* 156 */
  36674. { { 0x3a40f84d4dd7e96L,0x1323aa1027f0325L,0x29e6a9d11393711L,
  36675. 0x0863f631b5b15bcL,0x200269e7c3b6066L,0x164a757eb4eeaa1L,
  36676. 0x2e365b1413c6b00L,0x2abb306b5f90088L,0x1d36a82621a4798L },
  36677. { 0x2ac45c4c1003c81L,0x27bd6bd0f6180abL,0x1f5e60f774699efL,
  36678. 0x2aefd74a160da99L,0x1c84acef1f312e7L,0x34922d48bd4fb20L,
  36679. 0x265c6063e32ca29L,0x065cffa6a9f1607L,0x017e3686c9a5284L } },
  36680. /* 157 */
  36681. { { 0x32efe659e90de99L,0x1216f2b416ad8c2L,0x2a52e14e4892be4L,
  36682. 0x0c0898a1a1f1229L,0x15eb3db542ad854L,0x11796104987c3a5L,
  36683. 0x17573948e81863dL,0x2b7933f87383e3bL,0x03fbd6f1ff57d84L },
  36684. { 0x03711ddd1bf968cL,0x235f35237e91cb5L,0x1223e425a566d55L,
  36685. 0x0e1709b410527c2L,0x17c2c17430cf833L,0x050f6766f9ee07cL,
  36686. 0x3d3faee3bdc33e5L,0x2046bce16b0d653L,0x1137551cf429fd1L } },
  36687. /* 158 */
  36688. { { 0x128f55b20193bb2L,0x15e741cc42e1c92L,0x2309d345d27696eL,
  36689. 0x0caa1c61a297b81L,0x1110386839a43e4L,0x0ccbc420a3044f8L,
  36690. 0x05cbb48286ecf3aL,0x236bccd22a8dc0eL,0x0c6698ffcaaef15L },
  36691. { 0x044c54af6908745L,0x0cdb91a8cd4fee8L,0x2852d561e821a6bL,
  36692. 0x1c0d8d245fda530L,0x181f613151b2979L,0x3d1a97bdb8408eeL,
  36693. 0x114f7f6817dc2beL,0x316fe4f7a82be38L,0x136c3cf3cd5ed72L } },
  36694. /* 159 */
  36695. { { 0x38799ab7b080de4L,0x3de0775a760e5aeL,0x2aaa986f8f633b8L,
  36696. 0x0e2952f1729dad0L,0x1a9c2fbb95d74c0L,0x005e24c1dbf2d81L,
  36697. 0x286f0d8451b4408L,0x0c98d03c030e274L,0x14c3038e9520c54L },
  36698. { 0x14bc3816977aad9L,0x3f420b5c21ef8f2L,0x020c875fed08adbL,
  36699. 0x350d1595bf01b42L,0x00fd6dd4ee1ce84L,0x297ead01c713638L,
  36700. 0x2eeb6f23338b226L,0x309b351dfab042eL,0x078e4db08bb5f80L } },
  36701. /* 160 */
  36702. { { 0x111d12a1078342aL,0x11c979566841900L,0x1d590fd3ffdd053L,
  36703. 0x27c1bc2b07fa916L,0x33e19bc69cf694aL,0x27773403db492b6L,
  36704. 0x32dd4e3ce38f5ebL,0x07154e1003d9ad8L,0x085cab8fdfbe15eL },
  36705. { 0x2943f6b8d09422fL,0x0a5d583e6230ec2L,0x01fa2ef2e4d917dL,
  36706. 0x0ecd7df04fd5691L,0x3edaad3ff674352L,0x0d1c90b49d34d01L,
  36707. 0x38615d594114359L,0x2533472c9cc04eeL,0x07da0437004bd77L } },
  36708. /* 161 */
  36709. { { 0x24b99a62d712c44L,0x0da3e29a5895de0L,0x0432d65e2287148L,
  36710. 0x019bd6f17e23b5aL,0x14ec3479d140283L,0x0c9b6dc39b3cc48L,
  36711. 0x32936b96db6f449L,0x086bf296b026328L,0x04d69e248c72feaL },
  36712. { 0x2a89092a71269fbL,0x2f6ea061942d802L,0x02a39fb55db22f6L,
  36713. 0x37d8c47a7407673L,0x090ac2c1d0fceb0L,0x2c7cdca9bebade7L,
  36714. 0x0c41932393b222cL,0x399d18a9bcf7ef2L,0x0019dea30b22fe8L } },
  36715. /* 162 */
  36716. { { 0x1f689ac12b3118bL,0x3b8e75b2dba959fL,0x22c2187cd978d06L,
  36717. 0x206354df61f3f30L,0x2e9f56db2b985b6L,0x38263055d611454L,
  36718. 0x212cd20f8398715L,0x0711efa5a9720ecL,0x1fb3dda0338d9acL },
  36719. { 0x06b7fe0cfa0a9b8L,0x22eb1f88b73dd7cL,0x1e04136887c8947L,
  36720. 0x37a453152f3ce05L,0x00f51ea64ed811dL,0x321c15df2309058L,
  36721. 0x2bbcb463914d834L,0x3d4bbb493954aa2L,0x0019e5eb9e82644L } },
  36722. /* 163 */
  36723. { { 0x365a04e66d52313L,0x25151534fdcaf47L,0x1dafa6b7ae11fd6L,
  36724. 0x3615c6ac91caf03L,0x2ae5a8d68921f79L,0x3b17384f5317e59L,
  36725. 0x24bd39fde17716aL,0x19e0dc39bb692ddL,0x1efffe94085990dL },
  36726. { 0x3fa0e27d88f92e8L,0x3bc3f671dc48f3cL,0x174c89274dbaa21L,
  36727. 0x296e6e89d898966L,0x246ebcaf6d4cfa4L,0x3e38a1c04324274L,
  36728. 0x3aeea20317a10d8L,0x2c28ec1dc778514L,0x0eadf0c479168c6L } },
  36729. /* 164 */
  36730. { { 0x1bc1e484c854477L,0x3096d218e391f04L,0x202b869c54d92beL,
  36731. 0x0caf879fb490f53L,0x06b460c4ae318deL,0x2909abfbd51c7acL,
  36732. 0x052dc138ae7bf3aL,0x37a748eb89b7761L,0x1649d3fc1d55782L },
  36733. { 0x07cae310ade1979L,0x1c1074ed2f1ca36L,0x3c4056c3c9bea84L,
  36734. 0x0ab5d2b919ce248L,0x0ecbe49ae36fe18L,0x3107e7d64affdbdL,
  36735. 0x2307156680db80dL,0x1cc1cd6eb01bf91L,0x0c06d68b4c7d6d0L } },
  36736. /* 165 */
  36737. { { 0x3e22be7854dfcf2L,0x069f7e9ab8ef436L,0x3ad1a521ec46ee2L,
  36738. 0x1e906a52133d18cL,0x32aa123f3ee9452L,0x2b8f2a484517ae6L,
  36739. 0x05d9255634a82acL,0x0b63385dab283f2L,0x078504cf7fc1908L },
  36740. { 0x34ce7c43799793cL,0x375862d5467ed75L,0x1f9395ff980874dL,
  36741. 0x346e2fd8798b3dbL,0x3dcfcf54f00ea45L,0x0c00d6c09a18d84L,
  36742. 0x28a9cb67423b760L,0x01dfa7ef1d4d100L,0x0f47b52ce37051aL } },
  36743. /* 166 */
  36744. { { 0x3f7d8ad96bec962L,0x3207d85f8041ebaL,0x0509214e1058d1cL,
  36745. 0x10d08e5327d9311L,0x11a6605136c298cL,0x037e090f644014bL,
  36746. 0x1cdea4c36437549L,0x2dec48c4ef87bf9L,0x076249a60f7d27fL },
  36747. { 0x09758381cf593a0L,0x33bbee0d931679dL,0x1333e05c99910c9L,
  36748. 0x07d0860238cbd68L,0x34f5e8f4f30ea5eL,0x1b032d1d5bece93L,
  36749. 0x3dcc6a2cae6e2ebL,0x3045d82cc1ff422L,0x01aee17901c0ff8L } },
  36750. /* 167 */
  36751. { { 0x048336b89aa9e14L,0x0d09c7d9d9c03f0L,0x0433906b6980666L,
  36752. 0x387aedeac8d36a8L,0x3eb59a05330247eL,0x0003d3565a6d2a9L,
  36753. 0x026b5bd78ef8258L,0x15b13976ce3ad18L,0x03b06a43e5d7d68L },
  36754. { 0x20ae838ed2a0ee7L,0x2f94a3c5ba204eaL,0x1f5c4ea6413704bL,
  36755. 0x2d81b8a619e2adbL,0x2f459ed2b5be80cL,0x1d85486bc66c6dcL,
  36756. 0x116f3b7a9cce4d1L,0x1a494e6bfe652a9L,0x00797d92e86b341L } },
  36757. /* 168 */
  36758. { { 0x1aeede15af3a8caL,0x091e0a970d47b09L,0x23fbf93ec080339L,
  36759. 0x3139bd096d1079eL,0x081e76009b04f93L,0x0603ff1b93b04bbL,
  36760. 0x0aef3a797366d45L,0x076474a4f2ed438L,0x061a149694468d7L },
  36761. { 0x12c541c675a67a1L,0x0e34c23d7fa41bdL,0x3cccf6be988e67dL,
  36762. 0x2f861626218a9c2L,0x27067045bae03ecL,0x032a365bb340985L,
  36763. 0x00735d1facdd991L,0x3c871ea842a08c3L,0x0152a27e5543328L } },
  36764. /* 169 */
  36765. { { 0x1d609e0e6057e27L,0x22da9f1e915368fL,0x11451f32dd5b87eL,
  36766. 0x22343bd478bfd66L,0x125567546ea397aL,0x08a2d20312619a8L,
  36767. 0x01997aea45c8b13L,0x19f48f6f839df74L,0x1f80e2ea28fc518L },
  36768. { 0x295412d69d0820bL,0x1cc49c7a9968618L,0x0221eb06380d031L,
  36769. 0x3f1d7fa5c1b09f2L,0x35a71d2507ffd4eL,0x1f2dd50dece5a95L,
  36770. 0x0dbee361c80051cL,0x0b51781f6d35eb5L,0x1431c7481f49b19L } },
  36771. /* 170 */
  36772. { { 0x2ab2d0408e1cc4dL,0x1d634eb4b707b97L,0x3dfe5c9c7393e93L,
  36773. 0x2a74cde5a0c33adL,0x2e24f86d7530d86L,0x02c6ec2fbd4a0f2L,
  36774. 0x1b4e3cab5d1a64fL,0x031665aaaf07d53L,0x1443e3d87cc3bc0L },
  36775. { 0x10a82131d60e7b0L,0x2d8a6d74cf40639L,0x2e42fd05338dfc9L,
  36776. 0x303a0871bab152bL,0x306ac09cb0678f2L,0x0c0637db97275d7L,
  36777. 0x38c667833575135L,0x38b760729beb02fL,0x0e17fc8020e9d0aL } },
  36778. /* 171 */
  36779. { { 0x2dd47411baaa5ebL,0x2edd65e6f600da2L,0x0c40cdffed2202cL,
  36780. 0x3c13824450761a0L,0x120748b871c23a8L,0x167a4a25974507bL,
  36781. 0x06dbfe586a15756L,0x269d1f1a35f3540L,0x148da0ad0df2256L },
  36782. { 0x0fcc5db7f9069d7L,0x1f49157014c6932L,0x0899e9a2db3a248L,
  36783. 0x0e2d3fa5c8316adL,0x0d27f35e452bfd5L,0x38b6b24dce81329L,
  36784. 0x3ee7e27cbbc549eL,0x24d800a1c8a77fcL,0x0d03179878d28daL } },
  36785. /* 172 */
  36786. { { 0x1b7e9bb3b66c047L,0x1961a580a8f8762L,0x2297c8db9c0022eL,
  36787. 0x28f4229d28d13e0L,0x1fcd398de0e76acL,0x0c8399abefc69c7L,
  36788. 0x1c9fc52fbb6eaa8L,0x2cad2a0b43af05eL,0x00f4e00cf6f4e7aL },
  36789. { 0x24c0e9a4890c439L,0x1928aef0d69ac90L,0x079dd9b7497d375L,
  36790. 0x03584b7a50a5691L,0x0e60d0033a1ff3fL,0x08905f68d6189ffL,
  36791. 0x2b8385815da8c05L,0x25aa941841353bdL,0x120800728d2f16eL } },
  36792. /* 173 */
  36793. { { 0x36f2372ab039042L,0x1a5e327e8213b65L,0x1d2f58bec14310eL,
  36794. 0x007f881170f40ffL,0x2b0a5a9283200c1L,0x187ebfe39a1a3deL,
  36795. 0x31226526c95d1deL,0x3b45e8788049edeL,0x0898e63dd78c2a5L },
  36796. { 0x36533da22bba4eeL,0x3d8e5fd25a95d2eL,0x29f714f2a6b93efL,
  36797. 0x2f477f75cfd024cL,0x269bca1b1a08248L,0x28b80c9d8bccfcbL,
  36798. 0x1df7419a177e64bL,0x2f472f143a64dd7L,0x095b87a979f4a56L } },
  36799. /* 174 */
  36800. { { 0x03736a967c1f177L,0x34d4218004cf27aL,0x3b926eac9a5b1b6L,
  36801. 0x29b09fbcc725092L,0x1122b48707a9c01L,0x346b2616b64eee9L,
  36802. 0x3f175b9eb94e2a9L,0x364514470081b54L,0x0b1d13eb2525102L },
  36803. { 0x3e7dbeb675a1171L,0x20a5705b034ac73L,0x1b5a057c88cab22L,
  36804. 0x25b4c03a73e36c9L,0x3269552eb73ea9eL,0x383e637ec3800dfL,
  36805. 0x10480fea9d035c9L,0x2cc66183926e34aL,0x037a35e9512c036L } },
  36806. /* 175 */
  36807. { { 0x16729ee8f00df48L,0x329ed846b20c131L,0x17f98b3a8123b89L,
  36808. 0x06708728fa925e9L,0x3e2bb3ce7e0431bL,0x371de065169cf7aL,
  36809. 0x2b3df12f86cc2baL,0x373c17fc0179397L,0x05ef955dd7add27L },
  36810. { 0x0c22ffa00ee402fL,0x0d78a8ecc2ed338L,0x11d0643cb1015b3L,
  36811. 0x114f3465a215095L,0x2f0be54b4c6183fL,0x3083379319993c8L,
  36812. 0x24c475a5f4cfee4L,0x07b6772aa5cbe02L,0x19cde4af2005911L } },
  36813. /* 176 */
  36814. { { 0x29d0bc8d771f428L,0x07b36790f28e0a7L,0x2480eb93acf03acL,
  36815. 0x2041968a8fe357bL,0x22f0b8a7316232fL,0x0951d2887f013eaL,
  36816. 0x315f6f4a8df7e70L,0x0394946b13fc8eeL,0x06b66e21b73e095L },
  36817. { 0x1c9848067a41deeL,0x2a56b9ecf8acfd6L,0x0386891454e12cfL,
  36818. 0x37fbbf29a915366L,0x011e9cb75f0dddbL,0x3bc8230d7da46c9L,
  36819. 0x333cf6a9b9e766fL,0x1d2a7a37c400062L,0x1c4b8a55ac9d1c1L } },
  36820. /* 177 */
  36821. { { 0x19f58625c4cccb8L,0x3d4824bbd34fbeaL,0x257689efc87870bL,
  36822. 0x25b685081b8a3d3L,0x07c52107da2366fL,0x1283c3c240cc680L,
  36823. 0x2a47b0478d4ceadL,0x1d526ca267b891cL,0x110ae96534e6420L },
  36824. { 0x0c1d655cced05b0L,0x30fc2405d6550cbL,0x30a48e577cd7abaL,
  36825. 0x24d03a635b6ebadL,0x3603d24f184b008L,0x15c85cf49a60d94L,
  36826. 0x1141de6e1458832L,0x1fcd074d22c9984L,0x06be52257dcefa2L } },
  36827. /* 178 */
  36828. { { 0x2678f33c947e655L,0x3edda82248de564L,0x2745790239d1ff0L,
  36829. 0x248f36edf3acb7fL,0x105f6d41cea0874L,0x2771562084c9b6eL,
  36830. 0x0317025b1ae9ae7L,0x22a738514d033a7L,0x0c307502c29a2c3L },
  36831. { 0x0124f11c156ace2L,0x1c3f9de7fc94a43L,0x1a816e1171b22c1L,
  36832. 0x20d57789e5d837eL,0x27c6cc79da19bcaL,0x3587ddc06b649faL,
  36833. 0x1c06bb285901121L,0x10aeffa03209898L,0x15e4050d338aa26L } },
  36834. /* 179 */
  36835. { { 0x1397829eaad87bcL,0x324d9e07a132f72L,0x024d6ade4fdee0aL,
  36836. 0x295a435fd5ad5e7L,0x3d14fb0b950b9abL,0x16839edbc26ca74L,
  36837. 0x2f4ff3d0684f232L,0x1ccec1453a74d81L,0x077e63bdd26e8adL },
  36838. { 0x2fd06ece0d25c6dL,0x00086802e8b73c2L,0x17708c5bb398dd9L,
  36839. 0x360663fe3f06c09L,0x1b7e2cd68077f06L,0x18e8d5ca1f543fcL,
  36840. 0x125a9aef75e0572L,0x03a56fc95e24beaL,0x111847d3df0739dL } },
  36841. /* 180 */
  36842. { { 0x2ab9cc7fec82924L,0x1b75a69c8835a54L,0x27dea06ef0e21c7L,
  36843. 0x3089c60e41298d4L,0x2716807c8ab3e51L,0x123c491bd36cd7aL,
  36844. 0x1560958f3ede0a7L,0x0e37bc524d91104L,0x0f75f6583d1874bL },
  36845. { 0x39189e10b927eb7L,0x318d670b8bc49e8L,0x02337fe966f4a87L,
  36846. 0x208417956142dcbL,0x2e58c39f9102b83L,0x246d4ca58ffb801L,
  36847. 0x2ff97b3f052ee39L,0x14181fd6e15332eL,0x16a935e5f6c5f80L } },
  36848. /* 181 */
  36849. { { 0x19a0355dfd88d38L,0x33638f15277d03cL,0x29e304d006e1555L,
  36850. 0x1b3f42c3398c89cL,0x135f2ad31f16b70L,0x1e8f7e7fc55b702L,
  36851. 0x1e5fb5b30c5213fL,0x2368a7ca7324a95L,0x144a0ecfdd42b85L },
  36852. { 0x1c115df52658a92L,0x0fb45f10a0585adL,0x1f707fd92a91bceL,
  36853. 0x3f67357625a9565L,0x35a9472b1663c8bL,0x00cf86f41dd8d0fL,
  36854. 0x1c02fb14e44ca8bL,0x3ecc89e87261879L,0x1b5ece0f2c4cc4fL } },
  36855. /* 182 */
  36856. { { 0x3127bab31211943L,0x232b195a10c9705L,0x0b88d855fc3e44aL,
  36857. 0x0333a47ba974bf8L,0x078ec7d1247ababL,0x3367fbe9748f771L,
  36858. 0x255766a3986de70L,0x31fe8cb1ee19e09L,0x0873e54018beeaeL },
  36859. { 0x16e86f2b38d17c1L,0x3ef431c7e810372L,0x2b79f88499cb9cbL,
  36860. 0x33bdc7b202f8446L,0x146c896921d47c5L,0x34c58cc6b2a8ef0L,
  36861. 0x28765b5f921c0e3L,0x3c9c0c7e8207b9dL,0x0fed5dafd5f41efL } },
  36862. /* 183 */
  36863. { { 0x2f10b9d4cda1348L,0x1a7f48970c04ea2L,0x25b18957c22bb07L,
  36864. 0x31fd6b3c711142aL,0x09fef80295cafd6L,0x38227d773dc6850L,
  36865. 0x3d2ba8e12029f5eL,0x32d625d4aa3ec3eL,0x09061e2275f6f70L },
  36866. { 0x30a4ac51fbda16aL,0x0439e7c77e8a8adL,0x2132d9945f6f799L,
  36867. 0x2bbad2e93bee8b3L,0x34bf2d53d450d59L,0x18831ea1aa3826cL,
  36868. 0x13c6f476010204eL,0x3d5a98fe250f429L,0x13214c91d1987eaL } },
  36869. /* 184 */
  36870. { { 0x14fb120490d66c3L,0x35cca2837208139L,0x0c3804b4294deaeL,
  36871. 0x2acc777119ee805L,0x28342ed113f2fa2L,0x0c0d3839c3fd57aL,
  36872. 0x0ae3c1b18da72f2L,0x1680ab70c36faf6L,0x09c179bdf6f3e94L },
  36873. { 0x2c928ef7484c26fL,0x2df6c7bcab6ec51L,0x35483f58dda7206L,
  36874. 0x0312f1fb6d8221fL,0x1975cafdcfde4e2L,0x1afbb0812134487L,
  36875. 0x16db67c5b596708L,0x1d222d5e6aa229bL,0x01522c6d87e4118L } },
  36876. /* 185 */
  36877. { { 0x2890757c471d4aeL,0x12c6950e8769d82L,0x31826aa701a1fefL,
  36878. 0x14967197e4ee24aL,0x1d789df35bf4d4eL,0x2de70fca48ebe4aL,
  36879. 0x0cf1303ccb46c60L,0x03b125560b39f3dL,0x11c7da081b4257fL },
  36880. { 0x12c6ae59aeef274L,0x16fd3c50df020feL,0x3023e13c86afe6cL,
  36881. 0x398a8894d82a9d2L,0x022589fa5d21dacL,0x3e9d2c3ecf55caeL,
  36882. 0x2891a93d4a3916dL,0x33ef79db36372c4L,0x19aa0391a3f59f4L } },
  36883. /* 186 */
  36884. { { 0x14ba69e203fc3f1L,0x1a332d8841a8a41L,0x0540aad5fa9f091L,
  36885. 0x03affdfb5bec206L,0x0bef94afdecb8f2L,0x02af476cb202986L,
  36886. 0x0e0a7ce25d8ca0bL,0x16e69d799e9040aL,0x1b2dd7662ddd6e9L },
  36887. { 0x3dff279f289d7eeL,0x157567ba8881721L,0x3d54c18adac64d7L,
  36888. 0x33dfb004066bac3L,0x2b48d70a43a8c46L,0x02ce7be1bf2439fL,
  36889. 0x145a20965c53c11L,0x008f9155ddf30e1L,0x16ea33430f757ddL } },
  36890. /* 187 */
  36891. { { 0x29f39490ff53d2cL,0x24565ac00d26e7eL,0x1014d59979678dcL,
  36892. 0x2aea29ade2bc429L,0x08b517b104dd72dL,0x1b4e6f83bd77950L,
  36893. 0x217f70142b90bcaL,0x044632baa8fa7b6L,0x16da01689d606b3L },
  36894. { 0x26ca563f46afff7L,0x171ee8d29797cfaL,0x24c8aa998fd8394L,
  36895. 0x11ad8fd4d7b07ffL,0x0d1f509e542a601L,0x3e33436d4205a22L,
  36896. 0x236772d1918daa9L,0x3719994179aede2L,0x1ef4ab03a819cc6L } },
  36897. /* 188 */
  36898. { { 0x2089d14d376d986L,0x1381de8b70d6c01L,0x309a53ff2c86d0fL,
  36899. 0x11448f0ff207045L,0x31b656fc2fef4baL,0x3fbea2ee14b3569L,
  36900. 0x110b77b57c74891L,0x284a63c14e0f920L,0x04c4b55d3ad52c5L },
  36901. { 0x110cff3f3827633L,0x1e1357802bfa594L,0x38823ead32fa086L,
  36902. 0x058ae47361b2ce1L,0x0e6f3638a3dcf4dL,0x22dff5081e2da96L,
  36903. 0x1683e733792112eL,0x210cda5901137b9L,0x1223b84210f28e2L } },
  36904. /* 189 */
  36905. { { 0x028a9a9c3ebeb27L,0x3372d4fbd643e1bL,0x2e114dae7f37d7bL,
  36906. 0x391c9ba9f27a228L,0x28c141388033522L,0x058855d667540e1L,
  36907. 0x0564d859b1aeca6L,0x238d9c67f3faff3L,0x0433a577af11aebL },
  36908. { 0x3f26ce06feba922L,0x320fb91d695a4f0L,0x274028bf378e5f6L,
  36909. 0x1a2f70fdbc5fde5L,0x2a6ed90aed2a5e3L,0x291f2f54f40d282L,
  36910. 0x0e2bc83b1c3a4c4L,0x003ae93c2a9b937L,0x1c097c7af4374caL } },
  36911. /* 190 */
  36912. { { 0x037717879c28de7L,0x2a8aaaae70cc300L,0x182666bc61eb617L,
  36913. 0x33d35e2d4110c20L,0x19870fc72e0b5b5L,0x102def175da9d4bL,
  36914. 0x32d03a3b4689f5dL,0x182a6a5ff619e1fL,0x1c06ab7b5eefd60L },
  36915. { 0x19eadb1ffb71704L,0x3962ece43f8ec7aL,0x382cab4f19aa436L,
  36916. 0x3eb83cf6773bb2aL,0x16e20ad12da492dL,0x36ef4988a83d52fL,
  36917. 0x12eb54af89fa0f7L,0x01d637314286ba3L,0x0b79799f816ef7dL } },
  36918. /* 191 */
  36919. { { 0x2c46462104f98ccL,0x056489cabb7aba7L,0x3dd07e62186f451L,
  36920. 0x09a35b5a6d9eba4L,0x0fd43a8f3d17ce0L,0x302ade5ed4d1d82L,
  36921. 0x1f991de87f1c137L,0x38358efd65ea04eL,0x08de293a85be547L },
  36922. { 0x182add38ef668b1L,0x39acb584725d902L,0x2b121c1d4263c54L,
  36923. 0x23bbfd939ccf39dL,0x02871612a3134b2L,0x2824d652bdc6a6bL,
  36924. 0x1108e831c88af2bL,0x0df682d92444aeaL,0x1138febc5c55cf4L } },
  36925. /* 192 */
  36926. { { 0x29ca589c4a2daa2L,0x29c0f1003d8231fL,0x1058d517510318eL,
  36927. 0x1c92aedbca5be33L,0x194296ab4264934L,0x314595f42f954f8L,
  36928. 0x080ea89af9398faL,0x386c788cb7bb13eL,0x1372f81761e67b1L },
  36929. { 0x1014bc73a20f662L,0x1f9df127b654094L,0x096fb62b96521fbL,
  36930. 0x19e8ba34dfa27d4L,0x25804170e3a659cL,0x3b5428d03caca89L,
  36931. 0x03c00f1674fce69L,0x2764eaa914dfbf7L,0x198f3c3bfda4ce9L } },
  36932. /* 193 */
  36933. { { 0x2b1f5cd81614189L,0x15b11492c967deeL,0x24b245fb415ec7dL,
  36934. 0x371ebdafbe71eeaL,0x074b48e82302bc8L,0x2db46c7e46ddc38L,
  36935. 0x280c974a1336e09L,0x2d894a1704d5f99L,0x12d59bcb813c7ccL },
  36936. { 0x1ad83b47c019927L,0x3c999d8c37f56f7L,0x2c5a31e05d23e10L,
  36937. 0x3e915ab1180576fL,0x1243cac822aa6e5L,0x372327a51a5594aL,
  36938. 0x0a4065c69c9c7f4L,0x0c06eb6c9f82789L,0x1ccdfa7a34eae41L } },
  36939. /* 194 */
  36940. { { 0x36a864d59cb1a7dL,0x19328dabbee3b85L,0x3acb1c22b0d84d8L,
  36941. 0x3af66037c743ba0L,0x07f94ced97e80a6L,0x29cb0457d60ab31L,
  36942. 0x107bb7a29cd1233L,0x028c3384a8aa31cL,0x1500229ca564ed8L },
  36943. { 0x374bad52f1c180bL,0x2fa6635d26a8425L,0x08ab56dbd1bad08L,
  36944. 0x3902befaa6a5e31L,0x3153dc5fc6ed3e3L,0x2fa4fb422a2fa5eL,
  36945. 0x2e23bdadc7f0959L,0x0a77a3490a420b3L,0x016417523c6dc27L } },
  36946. /* 195 */
  36947. { { 0x0eeccf16c14a31eL,0x3894d2cb78f0b5dL,0x35997cec43c3488L,
  36948. 0x27645ab24dbe6ecL,0x29f7e4400421045L,0x1154d60dc745700L,
  36949. 0x14a4678c9c7c124L,0x2eb67325d5237b2L,0x14e4ca678183167L },
  36950. { 0x33af0558d0312bfL,0x2fd3d5505879980L,0x05a7fa41781dbd1L,
  36951. 0x2a003bbc7549665L,0x079c3b8d033494dL,0x327db9a5b1417b0L,
  36952. 0x030aaa70ae1ade1L,0x018300a23c305daL,0x00c7f4cfe3ba62aL } },
  36953. /* 196 */
  36954. { { 0x18b447d057d6006L,0x25db9bf5c722c03L,0x2029abcf40f538bL,
  36955. 0x21bc40e9e0d79dfL,0x05e472c4b13bee3L,0x07f2c650829ab08L,
  36956. 0x0abf4943b045f63L,0x1ade79770767f00L,0x1b528c0bc70a555L },
  36957. { 0x29d07ee8a8640b8L,0x04408f438d004aeL,0x255bbe24ae89256L,
  36958. 0x093e95e77371f39L,0x1377bbfe5e358e5L,0x30251f915f389c5L,
  36959. 0x29782664651c6c3L,0x305697ef63543d2L,0x08d6fcdd28fe2e1L } },
  36960. /* 197 */
  36961. { { 0x164a2f65c7202c8L,0x0d01496952c362dL,0x16721434fbf57d6L,
  36962. 0x1787660c28e1053L,0x15ef0fbe1811421L,0x1bd5fe7f1e9d635L,
  36963. 0x2269d35705dcf8eL,0x27e5d7752695b64L,0x0f18f015d7abdb4L },
  36964. { 0x3131110b4799ce6L,0x2fee64b2f2df6c1L,0x0c9ff7ba21e235bL,
  36965. 0x04ec63d27fb07c0L,0x1abcf959b009d69L,0x350851ba3698654L,
  36966. 0x1f23f10e6872130L,0x0e1ad560ca05eb9L,0x143c9b5bb689ae7L } },
  36967. /* 198 */
  36968. { { 0x23328db48c74424L,0x05b8474672cbad0L,0x192a40d6e217326L,
  36969. 0x13032f71d4b94d0L,0x0d733bb01dd83a9L,0x2de914817188c14L,
  36970. 0x0011c8cd0d631a5L,0x1f3573370289669L,0x1e622f112cc646eL },
  36971. { 0x3d6e29a3e1e4c4bL,0x2094e27ec552291L,0x05b54fd3e319d5fL,
  36972. 0x2682822e599f8dcL,0x3d8cbe8db8c4ce5L,0x3bb0f5d6f29d279L,
  36973. 0x1a313dcc4496eaaL,0x24d805f71c8ea28L,0x1a5250ff77a8cebL } },
  36974. /* 199 */
  36975. { { 0x15a0726fe29bd79L,0x12a0413e642cd29L,0x146daad56983657L,
  36976. 0x2e543507fbda41aL,0x06e6f7f450e580aL,0x03cdc62af1d6d45L,
  36977. 0x234087508cc97bfL,0x2244146e8b29295L,0x17275c39077e64dL },
  36978. { 0x37cccaff77ca6bdL,0x037d06f6c637d7cL,0x0ff8019e01f7e0aL,
  36979. 0x112a9975cae7d1bL,0x06e3663e9be4f3dL,0x3be76db5e08b62bL,
  36980. 0x24a9aa5f37f9223L,0x322e9fc2b4e76afL,0x098a0a57c70f69cL } },
  36981. /* 200 */
  36982. { { 0x1c50cf400fd5286L,0x16e755ca92c0f36L,0x0f9e051ae73e1eaL,
  36983. 0x10a546ce093d798L,0x09fb4d667fe9b51L,0x3714215ac0d2cb4L,
  36984. 0x30022e4b537a80eL,0x22bb9a7b8404a32L,0x0ed7c8b9e5c6a54L },
  36985. { 0x06007bcd933619bL,0x1d9a38ae77f865dL,0x15d3cc6e2a2e0ceL,
  36986. 0x17dfbafccbea7bbL,0x167cc4f6435a14fL,0x214305b1d72e263L,
  36987. 0x379c96cb2185fc7L,0x11d10261d29d917L,0x1397468f8ae27dbL } },
  36988. /* 201 */
  36989. { { 0x1de68adc88684f6L,0x3b6aad8669f6ff1L,0x1735b27a18f57c1L,
  36990. 0x1963b3627ac9634L,0x2d879f7eab27e7bL,0x1f56fbecf622271L,
  36991. 0x3ad73ca8fdc96d6L,0x15b5f21361ab8deL,0x1a4c7e91976ce8eL },
  36992. { 0x001a5406319ffa6L,0x3993b04d3b01314L,0x296cd541242c0caL,
  36993. 0x3bafcb2bbb87da6L,0x028bee8059da259L,0x23a24392239e5e3L,
  36994. 0x227fd9e9484bebbL,0x18c6039491b43ecL,0x1b78be2a54a625dL } },
  36995. /* 202 */
  36996. { { 0x223554af472f13aL,0x264edd5ccfa4728L,0x29f096c168a2facL,
  36997. 0x0752c49d4d49abfL,0x3e77070ca7cfe76L,0x1f9f37da10c061cL,
  36998. 0x162ed466b6aaadcL,0x3e36368b757aa85L,0x016a81a2e0039faL },
  36999. { 0x080759c4e3de3bfL,0x38b8454bcc222aaL,0x2d9aaa7eba5b0c1L,
  37000. 0x14e7e70472b2cb7L,0x3b0dc5c194c65d5L,0x28fd2d842ae6f61L,
  37001. 0x0b5f9fd32f8c96cL,0x0877d2610bf30a3L,0x0f431ae27ccb90eL } },
  37002. /* 203 */
  37003. { { 0x32a0a0d6a0ccd0aL,0x3bb209664ed554eL,0x06fd9de672a6a3eL,
  37004. 0x1203681773ec4d2L,0x16739874d8d9c51L,0x0a68d72712a9113L,
  37005. 0x177eadd9cf35b2eL,0x1c2875af66d7e24L,0x1d69af0f59d2a04L },
  37006. { 0x2f844c7ba7535fdL,0x3530f6a10bfce6cL,0x09ede951974b45bL,
  37007. 0x25ff5114fb17f85L,0x1e6c37c0e6982e9L,0x0b0fbdaa98fdc17L,
  37008. 0x36a8d609b0f6a9dL,0x06de2fb74d6185dL,0x1764048a46aede1L } },
  37009. /* 204 */
  37010. { { 0x07c6ee551a251d1L,0x12fc48349e77f69L,0x138cec518a28befL,
  37011. 0x21ce202f9b930b5L,0x21be9b20b1b2b78L,0x1e5a867b1a733e3L,
  37012. 0x10bdeae41dfeae3L,0x20300959dbf27edL,0x16a8b815a0503e1L },
  37013. { 0x0a085f653f5ef65L,0x3eefe5dec94414bL,0x07e3a3346fe661dL,
  37014. 0x3b86e57dfbe23aaL,0x15b65eaec25ddfdL,0x30b808ec881d39aL,
  37015. 0x283bb511869a154L,0x1f9f61806d5dd0bL,0x0151464652cfa87L } },
  37016. /* 205 */
  37017. { { 0x10853c857fa58f1L,0x2939a1329319c09L,0x2d0a1b81f40db58L,
  37018. 0x041563a32f41ee5L,0x242e388cfa4651eL,0x110d8220699011bL,
  37019. 0x2b8fd051b0d5394L,0x33f3b0afcd6cf89L,0x0fd4ae787095702L },
  37020. { 0x079bc29df53d498L,0x0c713844dfd890fL,0x056c17a3cedf4cfL,
  37021. 0x071b36445764edaL,0x39228cddb246113L,0x3480afc6acc2914L,
  37022. 0x108612e97757b68L,0x09ad2999b79f398L,0x051c200fe654f60L } },
  37023. /* 206 */
  37024. { { 0x296103cb1a2b4b5L,0x332ffa10f025a3aL,0x072d986ffb5b98dL,
  37025. 0x3c85a74eb09a8dcL,0x2771371f12fa07aL,0x1f0a67be2ee16e6L,
  37026. 0x372efceae10d34eL,0x15bc4f52f71a788L,0x039378df75d8dd8L },
  37027. { 0x1e902ffde7ff5d9L,0x2a1748c9682728cL,0x13a6f4192fcd0e9L,
  37028. 0x0dc56c1dacf5c6eL,0x26e711d1cf52a57L,0x30a4a0675c9aaa1L,
  37029. 0x015de60b61b1df2L,0x2791c89395d7320L,0x1dc68e893e118b7L } },
  37030. /* 207 */
  37031. { { 0x3924ff96ffeda73L,0x27d01a83688062dL,0x20eaf89584dfe70L,
  37032. 0x0ba0d568100da38L,0x0fd777d7c009511L,0x2fe3cb20967514aL,
  37033. 0x05311bb0c495652L,0x36755fd8c64a113L,0x0d5698d0e4f8466L },
  37034. { 0x10d64fa015d204dL,0x09afe9b744314f8L,0x0e63a7698c947b6L,
  37035. 0x11c14cde95821feL,0x0df5c782f525a65L,0x157eebfd5638891L,
  37036. 0x2e383048aa1e418L,0x18f4d23c886391fL,0x04df25239591384L } },
  37037. /* 208 */
  37038. { { 0x2f4fd69d8695310L,0x3ac27dfa1da3a9dL,0x1812e0d532a8e28L,
  37039. 0x11315cab1e40e70L,0x0785d6293dda677L,0x369daec87e60038L,
  37040. 0x3c72172bfe2a5a3L,0x22a39bb456e428aL,0x04cd80e61bfd178L },
  37041. { 0x1f4037016730056L,0x117fbf73b4f50eeL,0x363c1aa5074246fL,
  37042. 0x14bfe4ab9cc2bf5L,0x11bb2063f21e5c6L,0x0b489501bbc20c3L,
  37043. 0x15001c18306ecc1L,0x150913b766ce87cL,0x1f4e4eb25b8c0ccL } },
  37044. /* 209 */
  37045. { { 0x161a714a1db5c18L,0x139879d9dc1d33bL,0x3be57bf685de945L,
  37046. 0x14f48516f97a5c3L,0x3ee49a5f2221b0cL,0x12c4740ee4c6206L,
  37047. 0x02213700b91afa1L,0x002bf1abbf924fbL,0x13c50554e945262L },
  37048. { 0x02c45e77364c92eL,0x000995cd4863a35L,0x1a0284d3f3c5e05L,
  37049. 0x0936fdd91af4a07L,0x2485f304f312f84L,0x049e944f86a23caL,
  37050. 0x20e0bc583f56311L,0x1c293b5e5431c69L,0x0c692855e104b7bL } },
  37051. /* 210 */
  37052. { { 0x106185c644614e7L,0x01b2b91d2690923L,0x12ea2587e5282e9L,
  37053. 0x02b44a15f356150L,0x0ba5593b5376399L,0x3574a919dc31fdcL,
  37054. 0x29a1bac2cf6dc4dL,0x2576959369158edL,0x1c8639f7e141878L },
  37055. { 0x1c96b02f8589620L,0x11a28d079101501L,0x1a11096ad09c2feL,
  37056. 0x2627194abbafc8bL,0x3547e1b8fbc73c2L,0x1df6fdcf37be7e2L,
  37057. 0x13552d7073785a9L,0x0f4fc2a4a86a9f8L,0x15b227611403a39L } },
  37058. /* 211 */
  37059. { { 0x1a5a7b01fbfaf32L,0x298b42f99874862L,0x0f5ef5e3b44d5c5L,
  37060. 0x3b7d0eefd891e5cL,0x1260ae5a03ea001L,0x1a5f18b2a39d0a1L,
  37061. 0x1a7643eb899ebd2L,0x09698da800f99d4L,0x0eaef178c51ba07L },
  37062. { 0x2cf8e9f9bd51f28L,0x3aef6ea1c48112aL,0x2d3a5bfc836539fL,
  37063. 0x334439bc23e1e02L,0x08241ab0e408a34L,0x22998a860413284L,
  37064. 0x2048d6843e71ce9L,0x3461e773a14508cL,0x1fa5cba23be1cf3L } },
  37065. /* 212 */
  37066. { { 0x3e8c9d22973a15cL,0x3b237750a5e7ccbL,0x0a390b6afb3e66fL,
  37067. 0x0daad97bc88e6bdL,0x266c5fcdb0bb1e4L,0x2bd21c2e3c98807L,
  37068. 0x344e243cffe8a35L,0x05c8996b8a1bcaeL,0x114da2e283a51ddL },
  37069. { 0x29c9a56c1e3d708L,0x18b4fc72c3be992L,0x298497e875404feL,
  37070. 0x1acf3a91bebc1c0L,0x283886263138b7dL,0x070c24241e018d3L,
  37071. 0x03864727e842807L,0x2899fc2bde75f96L,0x104c1b86582b236L } },
  37072. /* 213 */
  37073. { { 0x2ff09eda526c894L,0x2fc48052b1f48ccL,0x0dcd3cd9293495aL,
  37074. 0x04a4b9ad55adbe5L,0x21036c31bffaaebL,0x01ffccb864de5baL,
  37075. 0x1d67b8a9d237e77L,0x0922f59696c360aL,0x1b348edb556db29L },
  37076. { 0x2e9f9b2ded46575L,0x32822bfe9a6b3dbL,0x33a1f16d37d1496L,
  37077. 0x2c5e279740756baL,0x1c827cc454a507dL,0x259399dc178b38aL,
  37078. 0x0e46f229b6e4a52L,0x19214158ec2e930L,0x0a3e75c24484bc4L } },
  37079. /* 214 */
  37080. { { 0x3cb476fd2f6615dL,0x3e6de36636a6a43L,0x1f1cd2bdf1074b7L,
  37081. 0x21a6e55bcc78bf7L,0x3b596eadf2bda30L,0x156c94e3cf328bdL,
  37082. 0x0846db91c09f8b3L,0x190b91bcfdbcf1bL,0x1ff9bb9398e2a14L },
  37083. { 0x118d4f5a17bd645L,0x0cfaaf6f5b55494L,0x06fc734d0957570L,
  37084. 0x17d7d4f10d401faL,0x3fd27dd1998ca06L,0x254b472a652766fL,
  37085. 0x2c101cddc4e3046L,0x2c01e132ad3ee06L,0x00346d079f94a56L } },
  37086. /* 215 */
  37087. { { 0x1eb8e4fa6bfdeddL,0x28a179e9d31be65L,0x14d13d09a252993L,
  37088. 0x3986697dd9e2f57L,0x20cebb340eaa10bL,0x36fdea0f4f6c20fL,
  37089. 0x0f23e1c633a78b1L,0x20de49992f0fb0cL,0x1c96630f8f107a0L },
  37090. { 0x3f4cb4bdef86a80L,0x13b1e0fe0966aeeL,0x3604609532c81faL,
  37091. 0x3322e427a4a92fdL,0x31788416071bb7aL,0x286ae4a32875cc5L,
  37092. 0x0455a57f7f14becL,0x3a266ffa805b97eL,0x02d7b8c76b9bf21L } },
  37093. /* 216 */
  37094. { { 0x28605634b9f8e7dL,0x05dadd8ff162a11L,0x1a7e2feed68a201L,
  37095. 0x0f99460c6439e97L,0x2e9377ad6cc6776L,0x1c0c8c85f5f4040L,
  37096. 0x0bb505ccfc47207L,0x09da55cfb80c54dL,0x0f31bf1ef8c0f1aL },
  37097. { 0x35f5c4b0c935667L,0x14b0e41834ae2d8L,0x2c2e37c3a574741L,
  37098. 0x1302dcb8337bfeaL,0x1f4f60247fd5fccL,0x2785bccedd0fe6eL,
  37099. 0x34ef9c05c2e3547L,0x2b38e888d311cc1L,0x1244092f279495aL } },
  37100. /* 217 */
  37101. { { 0x3fd7851b30f9170L,0x2a87a4dff396c56L,0x15e0928437b9715L,
  37102. 0x1670cbc49cf3ff5L,0x248be1e3488acd2L,0x296f18ad685173cL,
  37103. 0x156f463a3408607L,0x3870d8a5bac5460L,0x1e7397fad192774L },
  37104. { 0x22f99f49c8225b5L,0x3f39251addf134dL,0x35308541e91b33eL,
  37105. 0x0d0e3cf5a4d1477L,0x2e727b54e0bd2d9L,0x188b65002d778b5L,
  37106. 0x36a94b42d929c27L,0x3c814dab39c8d5bL,0x04464a18cd5fccaL } },
  37107. /* 218 */
  37108. { { 0x1be0aababa95d63L,0x203185ed2cd1b63L,0x38630e0d8142927L,
  37109. 0x0aad5bbc13190c3L,0x1785e3633875be0L,0x04b24f930a3fae5L,
  37110. 0x2f82a3d5401795cL,0x2bf5a27fd47078dL,0x16b3c48c89510eeL },
  37111. { 0x1287ebad4f064beL,0x1f555553af6a65eL,0x1ef2623727ea1a7L,
  37112. 0x24627cd9b1919d1L,0x1c59d6ebda911f5L,0x1493484df950d73L,
  37113. 0x15b38d3a84daea7L,0x0f1271ec774710eL,0x01cca13e7041a82L } },
  37114. /* 219 */
  37115. { { 0x399860c874d64b0L,0x16c248594f38318L,0x0000eaa11986337L,
  37116. 0x0258873457459c0L,0x277d70dcd62c679L,0x016f5336f875f75L,
  37117. 0x2f8f30eff0f2703L,0x16de01dbb1884d8L,0x1d8812048167e44L },
  37118. { 0x1749a0e161f9758L,0x2457fa8f13f38a0L,0x0e41911dd8afe60L,
  37119. 0x2b1e6946827d4dfL,0x02ca5cf8efe36a8L,0x12415fd59fed52dL,
  37120. 0x244b641bdcae07eL,0x1960edc7fc31690L,0x1064815a5364b60L } },
  37121. /* 220 */
  37122. { { 0x0c69c3eef39cc39L,0x011593e98d5b45eL,0x3542412fb990983L,
  37123. 0x34de76eca96f4f0L,0x0e7e75e3da1d531L,0x2c051ec52197c62L,
  37124. 0x129ab02dac4e220L,0x1d3bfd6794728cfL,0x0f1c964f7fe37b0L },
  37125. { 0x080c0a60e301262L,0x1601814e4288b5cL,0x3f9acc8a90299a4L,
  37126. 0x15c5303c70b699dL,0x26e66d9f7dfae90L,0x1e11a490d997fc5L,
  37127. 0x0c307cc866dd8c4L,0x1439316bfa63f13L,0x03960e3ba63e0bfL } },
  37128. /* 221 */
  37129. { { 0x2785136959ecdb3L,0x2bd85fe7a566f86L,0x32b8cde0dc88289L,
  37130. 0x2c1f01e78554516L,0x350e22415fe9070L,0x1635b50bddfc134L,
  37131. 0x3b629ab3ab73723L,0x3f49453f506e6e9L,0x1937b32d80e7400L },
  37132. { 0x1d80d4d7147886fL,0x33b5855db2072b9L,0x0692642717bbe08L,
  37133. 0x262aed2f487853aL,0x26530308b9dcdf1L,0x2674671d962f991L,
  37134. 0x0ab126fbf192dadL,0x378c5568f46ccc1L,0x00e943f4be5fa24L } },
  37135. /* 222 */
  37136. { { 0x14240587fe9ea48L,0x13e09586d5d21b1L,0x013c78719740af2L,
  37137. 0x1e5c3ae1d3674b1L,0x0b62ba3aa27a9beL,0x306fc2b10ffbe38L,
  37138. 0x3130e10a23f2862L,0x33afd4709dbcd2bL,0x185f6cd1e9aae55L },
  37139. { 0x0defa7f40369093L,0x076759616078289L,0x3f33e512ed9e11fL,
  37140. 0x167b448225a6402L,0x28b73c399bf8a84L,0x3dbd53fa0c91557L,
  37141. 0x25235554a305698L,0x0ecc4aa75b694f0L,0x16ae6a6f9042a09L } },
  37142. /* 223 */
  37143. { { 0x2e123c9152cdd35L,0x390ea21900bbc6cL,0x30dfb9ce5bd5ae6L,
  37144. 0x129d601245224afL,0x3f502eec2b4acb8L,0x28cfbd3a31fd57fL,
  37145. 0x1d20019c8a7b93aL,0x2f3ac1ac40d5ff6L,0x0273e319ff00ba3L },
  37146. { 0x02c2f77abe360a3L,0x3d7212b7fbf2986L,0x0ca6650b6fcc57eL,
  37147. 0x15aabc2c80a693cL,0x0a24ef1563f4f8eL,0x3a917c4d7214228L,
  37148. 0x036dbed8f62fd91L,0x040efcb248e80a0L,0x18a4a9ca4c01a4dL } },
  37149. /* 224 */
  37150. { { 0x23fb7985448e339L,0x1dc33c628e65d8aL,0x174d7a69170cde8L,
  37151. 0x164ad819eb04581L,0x0848138ab4bb05cL,0x24279e537834b6cL,
  37152. 0x0315f7149dab924L,0x289620e8cdad9e4L,0x13ccd9074d9a335L },
  37153. { 0x039c5e0ac1b784dL,0x17231bb949eb87aL,0x2146a1c88ec0ab6L,
  37154. 0x2411b06fd634f21L,0x33fda502a2201f7L,0x096e4195c73b189L,
  37155. 0x16dfcdff3f88eb2L,0x29731b07c326315L,0x0acaa3222aa484fL } },
  37156. /* 225 */
  37157. { { 0x3e74bc3c9b4dfd6L,0x2a014fe39d8a4c5L,0x1c059d8c352025bL,
  37158. 0x332e16882d00c1fL,0x2238713591c9036L,0x2a57ed3bcb18fc2L,
  37159. 0x10c6c61a99d9d8cL,0x259a0f5f13ce661L,0x169162969c96829L },
  37160. { 0x113c267cb63ee53L,0x04b985d7ab0d4dfL,0x1a11191abfca67bL,
  37161. 0x277b86bda7eccdaL,0x011dc11e75ad064L,0x2e7e5d9535e9bc0L,
  37162. 0x2b133280f030b8dL,0x3318a8800068fc2L,0x194e17c98d239d8L } },
  37163. /* 226 */
  37164. { { 0x20d80b41d8fe898L,0x28a2dcc86114d1cL,0x038504f217408d7L,
  37165. 0x35459aa9abfc7cfL,0x0cc560e355d381cL,0x39878b367379821L,
  37166. 0x34951acb041f0a5L,0x2b0b188445bd766L,0x0c4509e16d37ee2L },
  37167. { 0x02a20c42c6fd79eL,0x1fb938ebde2c3aeL,0x23c1bad819ca95bL,
  37168. 0x37a615495a4f66dL,0x2f9c19d0f10d674L,0x1f179aa45f7992cL,
  37169. 0x22db6fa03fabaf4L,0x3463a162f12b4b3L,0x0c976c2380a1fc9L } },
  37170. /* 227 */
  37171. { { 0x1171ef8b064f114L,0x2c55953cbc3d324L,0x185457b262b783cL,
  37172. 0x0043cd24db0c149L,0x299a41fed468c67L,0x1fdfdaa7bc9b4bfL,
  37173. 0x1bfc1bf6da2267aL,0x3b500958ee36e80L,0x00e14b36c85c340L },
  37174. { 0x257e26425db67e6L,0x3d3a25fcba417d7L,0x2514026c426885dL,
  37175. 0x188fa1d424de0cbL,0x03c538691312be2L,0x15cd3e7615ad6f6L,
  37176. 0x2a48615b1cae559L,0x2ed61681eff8b56L,0x1d07a4c96f0ce8aL } },
  37177. /* 228 */
  37178. { { 0x3f54d05523aa2e9L,0x107833b4f42181eL,0x36e27f9bfb69c88L,
  37179. 0x11058af7e155a0fL,0x107b0dcc9dcb07fL,0x15e94db98b45e0eL,
  37180. 0x347d3ca2cbb8ab6L,0x18dc262e68349f3L,0x1f2ff154d685eeaL },
  37181. { 0x28b768a56b232acL,0x35b8d8fca94aad5L,0x3a168837fc604e8L,
  37182. 0x20f4429da46eba1L,0x0f9455fbeebc58aL,0x359538bab5792bcL,
  37183. 0x3c82551a20d6c37L,0x2e4c63103f2e769L,0x0b26d7b3cd760d9L } },
  37184. /* 229 */
  37185. { { 0x3090c3ebb2eaf45L,0x1364718bfee4bdeL,0x3ea4a736f23ded2L,
  37186. 0x2f5bfc3f78efca8L,0x1ca1102f5b5b99eL,0x1f80caa2f28ad57L,
  37187. 0x3f17a8f6203cd80L,0x156c55042d122a2L,0x109b86660a7e1dcL },
  37188. { 0x148b1da02a2fbd8L,0x217a2cec8ba296cL,0x20e48712b509fedL,
  37189. 0x1231a8f94584de2L,0x01633b503685601L,0x15449c45c402487L,
  37190. 0x131047939251432L,0x382eded24c7481fL,0x0ea623e722b8542L } },
  37191. /* 230 */
  37192. { { 0x04823d324972688L,0x20f04800fd5d882L,0x26906d0d452858bL,
  37193. 0x210b1bdd1f86535L,0x10146d89a842195L,0x1146ef0b23e28baL,
  37194. 0x3284fa29ec1de77L,0x3913fd88adae3dfL,0x06083f1dbe97b71L },
  37195. { 0x1649333999dd56bL,0x2b02ea5e91f7a66L,0x18aebbe8fb202cfL,
  37196. 0x363d875ef299983L,0x185adc14d47c29dL,0x3e7f5071bd7ed47L,
  37197. 0x113e6ce65ac7884L,0x274f8739a7753fdL,0x0231ace591effe5L } },
  37198. /* 231 */
  37199. { { 0x267a438a9fda771L,0x3d94b2198c4038bL,0x1e48e133f23b626L,
  37200. 0x3c80d74b47f7ec6L,0x28d13e878599f88L,0x2d47381c5c8e844L,
  37201. 0x19ba82890aa292fL,0x052d397ce9c3aefL,0x155dde826733745L },
  37202. { 0x0b2b77ed6f59a95L,0x214f8c080810802L,0x2ac1ebac779793fL,
  37203. 0x266d5ad99d94894L,0x19722a5006ecdcbL,0x138aeb412af6e7eL,
  37204. 0x34dd4d26210f3f0L,0x2e034329683fcc0L,0x041333d8080dac0L } },
  37205. /* 232 */
  37206. { { 0x051070935a85a06L,0x19b9d90bbc6d13aL,0x0b71a07b3a6d4e1L,
  37207. 0x000c0ca79aa12a4L,0x13d555259d6dd6cL,0x3e2b41788312e99L,
  37208. 0x34cccdee3b26af6L,0x19090838f5504aaL,0x1bd79798934a940L },
  37209. { 0x2a1d1848e0c7ff0L,0x217bf2550ecd03cL,0x31aef51d318bbaeL,
  37210. 0x139d61e3e9ba590L,0x3c2895f52e5d3edL,0x3c4419f134a8a76L,
  37211. 0x3f4ee53af278771L,0x1d369b337a59279L,0x19235188da1a56dL } },
  37212. /* 233 */
  37213. { { 0x083212003d310edL,0x3ba33261ec0c46cL,0x1d2684c558a8d20L,
  37214. 0x33adc59fb227952L,0x04bf55bb55e25f3L,0x1872405eb3c453dL,
  37215. 0x3343c0819edc770L,0x2d7b5d669139b7aL,0x07858df9f7e04c9L },
  37216. { 0x3a47ebb3bf13222L,0x147737a81f68453L,0x3ac3c0d8242f1e4L,
  37217. 0x134dbae1c786fa7L,0x2bea3190d93257dL,0x3af8accfd279dd6L,
  37218. 0x110096406d191f4L,0x2b1e19eab14f030L,0x1f45215cf8bd381L } },
  37219. /* 234 */
  37220. { { 0x07e8a8efa493b79L,0x389c2d3ac70ab0eL,0x3fa09ff22320b20L,
  37221. 0x2baa470e4f67ce4L,0x2138a8d965ee1baL,0x1ef543937b6a586L,
  37222. 0x23c8e069ab238c9L,0x1305bfda352288dL,0x158af8e00e5ce4cL },
  37223. { 0x0cdcf06cfc509a1L,0x1047bf09b301d5bL,0x1fd64d9c57f060fL,
  37224. 0x14ccba672b1b433L,0x18b8e9510a95148L,0x04370ff563e6acfL,
  37225. 0x2f3509a7e98709bL,0x04b1e0e4210f5d7L,0x1b628ccc9d05a93L } },
  37226. /* 235 */
  37227. { { 0x1934f00e341463fL,0x229b3854369e807L,0x20fc4109553f14cL,
  37228. 0x16aa4fd2a476d21L,0x32cd58067c23bdeL,0x10cf72027d1f1e1L,
  37229. 0x232a7d1d3300548L,0x176a4302f9fe5d6L,0x12e08b777d588c7L },
  37230. { 0x3c1281761a10d37L,0x2d86057143d6977L,0x15db79477c60ed7L,
  37231. 0x1dccf14c42ca2beL,0x053118267a0aa2bL,0x2d06567e417eaaeL,
  37232. 0x337784f40e98166L,0x1ab32732d09485aL,0x0c56835d77c6986L } },
  37233. /* 236 */
  37234. { { 0x1d714cb2b450a66L,0x222171f6ff7053aL,0x0d85b466a0c0131L,
  37235. 0x2656f7f0699956aL,0x0e67792d102a21eL,0x15429e5de835f26L,
  37236. 0x34d3372a01bb57bL,0x352550b1188cd75L,0x08b7be4e1c088daL },
  37237. { 0x073b03f95812273L,0x1bb4cbb8fdd5fc6L,0x0eae6da6217a2e2L,
  37238. 0x1d098767d3cb1c4L,0x1b7c1da2d9b50b5L,0x12a1779d0e5c7eaL,
  37239. 0x22137b22c4fb87cL,0x0649bdcb0d147b0L,0x1731345668c77baL } },
  37240. /* 237 */
  37241. { { 0x23e8c7a8a3ba183L,0x33aeeff8e27e9cfL,0x06870f9ba60f4e8L,
  37242. 0x0d72d806a0e3a91L,0x212e52db455176eL,0x3dc4afc7e42f709L,
  37243. 0x2054cd95f9e4598L,0x3502e6f4c803efaL,0x17a2cf19bf6dd5fL },
  37244. { 0x1cf6ca266736febL,0x21bd2779f3f8bdcL,0x3ce8fc290563bdeL,
  37245. 0x339c9adb93f182aL,0x13f29235baae8a3L,0x143fe97b48e0911L,
  37246. 0x3ef744a4b557f56L,0x1b74a8514f95044L,0x1b07c676a533e42L } },
  37247. /* 238 */
  37248. { { 0x1e603f235d96872L,0x288f30fe96e32bdL,0x071be988dc5fab1L,
  37249. 0x22750c302f55166L,0x0764d9cc3e32e84L,0x0b031035fb09a78L,
  37250. 0x3b83b4f7238212fL,0x29044b651860e21L,0x010281fa6712f18L },
  37251. { 0x028048f64858b37L,0x0526bcd5f797660L,0x0791619ebb18e0eL,
  37252. 0x2ce7cac2e82c886L,0x21039cbae210200L,0x255e74756a1fab9L,
  37253. 0x08515e4efdcddb3L,0x1e2a86ce23aa89eL,0x02c1a552c3cc818L } },
  37254. /* 239 */
  37255. { { 0x2c7f5000ea723dcL,0x3c13d10ac548c5eL,0x1445be885c860a5L,
  37256. 0x0fffc465c098f52L,0x0c4c58cea61f999L,0x273580db0fee917L,
  37257. 0x3923bbe6d151e6bL,0x3f519d68eac555eL,0x1474ec07c52ceb2L },
  37258. { 0x06a3d32ed88239dL,0x2e2b9a0d6b9a531L,0x23259feeb2e70d1L,
  37259. 0x0710ef02ed7d3f7L,0x38f62a705223bf7L,0x3f9e6694f34882dL,
  37260. 0x2b7f932224860e9L,0x2562f61561c0c92L,0x10f8e0f7330b594L } },
  37261. /* 240 */
  37262. { { 0x335c7bb3c67d520L,0x12562c8ff2a7b2bL,0x31948bbaa808d8fL,
  37263. 0x33884d7a2b81de3L,0x1c888eff7418c30L,0x1cc512af376366aL,
  37264. 0x06a53472075df0fL,0x1ff16d527225514L,0x11c4ef389795fbbL },
  37265. { 0x3e2c9ac43f5e698L,0x1ff2f38e2978e8fL,0x090e3089c2e1ce7L,
  37266. 0x3feb0756005b417L,0x0381b9d2a5a74f3L,0x17ce582ebbb6888L,
  37267. 0x37abbed958b143fL,0x2dc6197ff414436L,0x0ce8e97e6807a05L } },
  37268. /* 241 */
  37269. { { 0x251e61b8ce86a83L,0x10567efdf9c5808L,0x3dd748f03377860L,
  37270. 0x0dd1414890bf049L,0x0934ea09b87cb2cL,0x119e5106f52543dL,
  37271. 0x3a416a5146c403cL,0x23ac7a2b51c408eL,0x1b389b81a60af63L },
  37272. { 0x299934ee8150c69L,0x1d642389f052f39L,0x28916a0194ff74fL,
  37273. 0x0c86f546dd97702L,0x21877963038f49dL,0x34ed29a1af0cc17L,
  37274. 0x0af189fe2f3fbffL,0x0426c5026cddf5fL,0x1b3029ea13b9b8fL } },
  37275. /* 242 */
  37276. { { 0x37938d225a2fd88L,0x3cbdf33ae8180fbL,0x1c80d7a6dff4890L,
  37277. 0x0d8a20fe61930f8L,0x2998e530500c78fL,0x097771cfb64ad64L,
  37278. 0x13708a018a8f1b3L,0x0a2edb7ff661f57L,0x059dcd3554f0d1fL },
  37279. { 0x3c6e41d23a74e7dL,0x187af976ccb7d85L,0x3fa79e7ffa0b94bL,
  37280. 0x2dcbaede834f0bfL,0x201adf9c3473662L,0x119e4992a19057bL,
  37281. 0x209c571502c3265L,0x242185a444d24beL,0x195897f34aa2474L } },
  37282. /* 243 */
  37283. { { 0x045d359abadc253L,0x12e4b31e5f25792L,0x35bd9a218212e05L,
  37284. 0x17a94ae209c8aa6L,0x22e61c6769bb80aL,0x22c3e2cfa8e39e3L,
  37285. 0x1d854cfb274b1a0L,0x0b5cedaa90b8f6eL,0x1638ba225235601L },
  37286. { 0x0ec0e6f75c8c576L,0x0839f392f1f749fL,0x20c869d80726abbL,
  37287. 0x1aa2808fadc2562L,0x276110b15a908c6L,0x21bd869b2a7d43aL,
  37288. 0x0a69d8668c99941L,0x2843e777c8bb4a8L,0x1e0bfee1897bbf8L } },
  37289. /* 244 */
  37290. { { 0x2d8681848319e4fL,0x1bdad56961be809L,0x1886267132656beL,
  37291. 0x316614a73eafbd7L,0x162b29cfbac252aL,0x0a98d6379f3117cL,
  37292. 0x00ac70ee050609aL,0x2c7c3df2e7290a5L,0x1adfb44aaeca885L },
  37293. { 0x2b7a936e798678eL,0x07840e655010e19L,0x1e37816860b7ca0L,
  37294. 0x20edd17615fc924L,0x0a4705ed6eeffd4L,0x0a9743dd76ecd8aL,
  37295. 0x09fee357d68d49bL,0x35a1b46a14a688eL,0x1addbbc25491a7fL } },
  37296. /* 245 */
  37297. { { 0x10cba20969686a3L,0x2c71578f014fd78L,0x313426f47102308L,
  37298. 0x2c5240cc0e05c4aL,0x32d01527b1f9165L,0x2a68d38916dc805L,
  37299. 0x3e35c86fcf6647aL,0x38e0947d52e52c2L,0x0e3fccb22a55a15L },
  37300. { 0x271e4ec5b4dc0beL,0x0d89236c735712aL,0x3f43046e1007bb1L,
  37301. 0x35f6a72668fcdafL,0x28349bc505a6806L,0x04f8214272ff1bbL,
  37302. 0x3448c126871e73eL,0x2ebe579aa889d9fL,0x1b9ba77787c2da7L } },
  37303. /* 246 */
  37304. { { 0x2be58eec5a73375L,0x37da75ea2b10e06L,0x150aceca835a175L,
  37305. 0x027d41f4c3cb3ccL,0x3c60b0424b87b06L,0x043e43b26b94e8aL,
  37306. 0x1689bb4931e1824L,0x06a3914b1f43eb7L,0x013ab4534914763L },
  37307. { 0x32dd8568c84f3afL,0x3702486eab8cfabL,0x2a858b96b070829L,
  37308. 0x103a2a094591950L,0x05c35322b42260dL,0x27b6834ae797b6bL,
  37309. 0x22b90abca795603L,0x14c0a1af41f1ae5L,0x10a2e22dac7b1ecL } },
  37310. /* 247 */
  37311. { { 0x25fc09d239d8f0aL,0x0b80f2ae2840859L,0x17680173477b92bL,
  37312. 0x27e38d8581390daL,0x19eb061beab38edL,0x3a1159c1e6c0247L,
  37313. 0x21a2e0cd4226543L,0x00c3e83ddfb1cbfL,0x0931d242162760aL },
  37314. { 0x29f834cf8646bc3L,0x25294902ba5be7eL,0x3890379177d17dfL,
  37315. 0x113ffad9b364070L,0x077b924659dfd06L,0x3660753e06bb0bbL,
  37316. 0x37b0932df3b7f2cL,0x2762f26f0fda7cdL,0x125daef34f3dd85L } },
  37317. /* 248 */
  37318. { { 0x008451ba2c123bcL,0x20e9a02063e952bL,0x170298957b8ad1eL,
  37319. 0x0d3c3c4bc595b75L,0x30a9fa14dcc7f2eL,0x0bf9e0b07daa70cL,
  37320. 0x1f54ddefc9a2bbbL,0x0294f4c671a5dc2L,0x1dc0b8238cbd646L },
  37321. { 0x249290144dfb6f6L,0x35f2d1b900749bdL,0x240e48537ad8270L,
  37322. 0x2d5c3636f6469c2L,0x2f170d58b84d661L,0x0d13874b289c88eL,
  37323. 0x1de1faeeb4cf146L,0x17a9c8957f256aeL,0x1f8cd6e110adbdcL } },
  37324. /* 249 */
  37325. { { 0x257c6b978b8a0a7L,0x12badba0cfb7a8aL,0x17c14bd13fe724bL,
  37326. 0x223f0ba3b927918L,0x1fb147eefc41868L,0x3998b3ee34e6292L,
  37327. 0x0ba2ece9f191f12L,0x35435861c8a2656L,0x02dbd6d0f1b00b8L },
  37328. { 0x15cfdfe24c93cc9L,0x35de02e79c639e2L,0x3a5838baf7eb29eL,
  37329. 0x1f93772fda40722L,0x3a180d6bb022538L,0x251f1f0992c942fL,
  37330. 0x23f3cd6d68e548cL,0x0f34a0a9ed8ca64L,0x00fb8f036132d10L } },
  37331. /* 250 */
  37332. { { 0x198b3f08cd9d494L,0x0196e653d3e7ce0L,0x22203c738fa99b2L,
  37333. 0x0536348a72dd992L,0x0c51c54b3199f4cL,0x084e8ccb76b5d71L,
  37334. 0x0c7b2f9a32ce0bdL,0x3c82bce88421622L,0x0d16defa3625b1fL },
  37335. { 0x0e0054819a296ebL,0x13fc5746a44c4d1L,0x2d2bfeaa454f1d9L,
  37336. 0x00d3502f5ff5f7aL,0x21801a4afae65a8L,0x178379dd813c51fL,
  37337. 0x172ca0983048f9aL,0x3445e8ec67297fdL,0x0e0a237dba71821L } },
  37338. /* 251 */
  37339. { { 0x1babf8491630ee8L,0x16270817ad4c07bL,0x2b2da051f47bde6L,
  37340. 0x25884aefa067df4L,0x294292124aeaa9fL,0x110d796f73b4f57L,
  37341. 0x11f66f691f5b89fL,0x3c368658130ce50L,0x0e6b7fc09ca4356L },
  37342. { 0x294e413f74f811cL,0x0b60c77e36376c4L,0x3217963418c91a4L,
  37343. 0x06223af37b09fd5L,0x2ea305bc95fde52L,0x319a2d87f75781bL,
  37344. 0x011861ed1e6088aL,0x33af0ccebc05baeL,0x1c95ecb192d15ddL } },
  37345. /* 252 */
  37346. { { 0x27b37a3e0bde442L,0x10ffa19bde9cfa4L,0x1d208ed10c2ee05L,
  37347. 0x1069985e8cb4c36L,0x0d1d5cf8baf79c3L,0x0eaf3e2f9cd9e1cL,
  37348. 0x2b5e7b02d0dce9eL,0x1c317f88f4b75dcL,0x10b29fceea01ffcL },
  37349. { 0x1bcae4d62d803ffL,0x3a44ff6f0c1aa4cL,0x27abd8c1066293eL,
  37350. 0x0ab9e9b5962bc77L,0x2102f4e06d48578L,0x0dbebf9a449964bL,
  37351. 0x37121391a3127f1L,0x058d11ae4d10220L,0x0ba53bb4380a31eL } },
  37352. /* 253 */
  37353. { { 0x2e517fcca5636b0L,0x1b8085aae8571d8L,0x3d7c212e7b2d429L,
  37354. 0x1b55c5eb6116aa3L,0x398b2f3579517ceL,0x3d66c1f39d8ae16L,
  37355. 0x3ef6f042f996b5dL,0x2d227cdccaaefcdL,0x15da5d145ea4542L },
  37356. { 0x277c55eaa7f6e3fL,0x36669ea92816f07L,0x3d77458282273f4L,
  37357. 0x3eddedd23ee95b5L,0x20629f5d1db0895L,0x16600fec7121333L,
  37358. 0x20b8d0f5b1c90a3L,0x04fc90eb13ca45cL,0x0e98c10bfe872acL } },
  37359. /* 254 */
  37360. { { 0x11c4785c06c4fd6L,0x2e40974970ae767L,0x1eb1d4982f24bf4L,
  37361. 0x30ae93fbcac104dL,0x398de07ab3ab3edL,0x25bd2df556948e7L,
  37362. 0x04c815d5fc49ab0L,0x1acaf1428a580e1L,0x047db1148d01567L },
  37363. { 0x09f9cc510f3bad9L,0x2223f008a407531L,0x15ebc47b44df490L,
  37364. 0x31bce7cada245e9L,0x304e9962a20b2ebL,0x1cf756dc31638ebL,
  37365. 0x29f76c52ab7c1b5L,0x328ecad52b75a8cL,0x10859dad1eb82f4L } },
  37366. /* 255 */
  37367. { { 0x22c4128a182d1adL,0x05e5b88245b1159L,0x0272ba681647775L,
  37368. 0x3eae4b217069dc1L,0x3aefb2e07fac8b0L,0x2186ccb481eacb7L,
  37369. 0x2ed145c73530a07L,0x292758f6fb59622L,0x0bd547bcdca0a53L },
  37370. { 0x3c1382f87056b51L,0x247b6c4c3e644a9L,0x1e46d3805b42c3dL,
  37371. 0x3aff4c6a657df1fL,0x0cd3fb8aa456101L,0x3ac5ef387bf48adL,
  37372. 0x2c0c32fe391df79L,0x3bbd2d353031985L,0x11219f023be711bL } },
  37373. };
  37374. /* Multiply the base point of P521 by the scalar and return the result.
  37375. * If map is true then convert result to affine coordinates.
  37376. *
  37377. * Stripe implementation.
  37378. * Pre-generated: 2^0, 2^65, ...
  37379. * Pre-generated: products of all combinations of above.
  37380. * 8 doubles and adds (with qz=1)
  37381. *
  37382. * r Resulting point.
  37383. * k Scalar to multiply by.
  37384. * map Indicates whether to convert result to affine.
  37385. * ct Constant time required.
  37386. * heap Heap to use for allocation.
  37387. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  37388. */
  37389. static int sp_521_ecc_mulmod_base_9(sp_point_521* r, const sp_digit* k,
  37390. int map, int ct, void* heap)
  37391. {
  37392. return sp_521_ecc_mulmod_stripe_9(r, &p521_base, p521_table,
  37393. k, map, ct, heap);
  37394. }
  37395. #endif
  37396. /* Multiply the base point of P521 by the scalar and return the result.
  37397. * If map is true then convert result to affine coordinates.
  37398. *
  37399. * km Scalar to multiply by.
  37400. * r Resulting point.
  37401. * map Indicates whether to convert result to affine.
  37402. * heap Heap to use for allocation.
  37403. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  37404. */
  37405. int sp_ecc_mulmod_base_521(const mp_int* km, ecc_point* r, int map, void* heap)
  37406. {
  37407. #ifdef WOLFSSL_SP_SMALL_STACK
  37408. sp_point_521* point = NULL;
  37409. sp_digit* k = NULL;
  37410. #else
  37411. sp_point_521 point[1];
  37412. sp_digit k[9];
  37413. #endif
  37414. int err = MP_OKAY;
  37415. #ifdef WOLFSSL_SP_SMALL_STACK
  37416. point = (sp_point_521*)XMALLOC(sizeof(sp_point_521), heap,
  37417. DYNAMIC_TYPE_ECC);
  37418. if (point == NULL)
  37419. err = MEMORY_E;
  37420. if (err == MP_OKAY) {
  37421. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9, heap,
  37422. DYNAMIC_TYPE_ECC);
  37423. if (k == NULL)
  37424. err = MEMORY_E;
  37425. }
  37426. #endif
  37427. if (err == MP_OKAY) {
  37428. sp_521_from_mp(k, 9, km);
  37429. err = sp_521_ecc_mulmod_base_9(point, k, map, 1, heap);
  37430. }
  37431. if (err == MP_OKAY) {
  37432. err = sp_521_point_to_ecc_point_9(point, r);
  37433. }
  37434. #ifdef WOLFSSL_SP_SMALL_STACK
  37435. if (k != NULL)
  37436. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  37437. if (point != NULL)
  37438. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  37439. #endif
  37440. return err;
  37441. }
  37442. /* Multiply the base point of P521 by the scalar, add point a and return
  37443. * the result. If map is true then convert result to affine coordinates.
  37444. *
  37445. * km Scalar to multiply by.
  37446. * am Point to add to scalar multiply result.
  37447. * inMont Point to add is in montgomery form.
  37448. * r Resulting point.
  37449. * map Indicates whether to convert result to affine.
  37450. * heap Heap to use for allocation.
  37451. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  37452. */
  37453. int sp_ecc_mulmod_base_add_521(const mp_int* km, const ecc_point* am,
  37454. int inMont, ecc_point* r, int map, void* heap)
  37455. {
  37456. #ifdef WOLFSSL_SP_SMALL_STACK
  37457. sp_point_521* point = NULL;
  37458. sp_digit* k = NULL;
  37459. #else
  37460. sp_point_521 point[2];
  37461. sp_digit k[9 + 9 * 2 * 6];
  37462. #endif
  37463. sp_point_521* addP = NULL;
  37464. sp_digit* tmp = NULL;
  37465. int err = MP_OKAY;
  37466. #ifdef WOLFSSL_SP_SMALL_STACK
  37467. point = (sp_point_521*)XMALLOC(sizeof(sp_point_521) * 2, heap,
  37468. DYNAMIC_TYPE_ECC);
  37469. if (point == NULL)
  37470. err = MEMORY_E;
  37471. if (err == MP_OKAY) {
  37472. k = (sp_digit*)XMALLOC(
  37473. sizeof(sp_digit) * (9 + 9 * 2 * 6),
  37474. heap, DYNAMIC_TYPE_ECC);
  37475. if (k == NULL)
  37476. err = MEMORY_E;
  37477. }
  37478. #endif
  37479. if (err == MP_OKAY) {
  37480. addP = point + 1;
  37481. tmp = k + 9;
  37482. sp_521_from_mp(k, 9, km);
  37483. sp_521_point_from_ecc_point_9(addP, am);
  37484. }
  37485. if ((err == MP_OKAY) && (!inMont)) {
  37486. err = sp_521_mod_mul_norm_9(addP->x, addP->x, p521_mod);
  37487. }
  37488. if ((err == MP_OKAY) && (!inMont)) {
  37489. err = sp_521_mod_mul_norm_9(addP->y, addP->y, p521_mod);
  37490. }
  37491. if ((err == MP_OKAY) && (!inMont)) {
  37492. err = sp_521_mod_mul_norm_9(addP->z, addP->z, p521_mod);
  37493. }
  37494. if (err == MP_OKAY) {
  37495. err = sp_521_ecc_mulmod_base_9(point, k, 0, 0, heap);
  37496. }
  37497. if (err == MP_OKAY) {
  37498. sp_521_proj_point_add_9(point, point, addP, tmp);
  37499. if (map) {
  37500. sp_521_map_9(point, point, tmp);
  37501. }
  37502. err = sp_521_point_to_ecc_point_9(point, r);
  37503. }
  37504. #ifdef WOLFSSL_SP_SMALL_STACK
  37505. if (k != NULL)
  37506. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  37507. if (point)
  37508. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  37509. #endif
  37510. return err;
  37511. }
  37512. #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
  37513. defined(HAVE_ECC_VERIFY)
  37514. #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */
  37515. /* Add 1 to a. (a = a + 1)
  37516. *
  37517. * r A single precision integer.
  37518. * a A single precision integer.
  37519. */
  37520. SP_NOINLINE static void sp_521_add_one_9(sp_digit* a)
  37521. {
  37522. a[0]++;
  37523. sp_521_norm_9(a);
  37524. }
  37525. /* Read big endian unsigned byte array into r.
  37526. *
  37527. * r A single precision integer.
  37528. * size Maximum number of bytes to convert
  37529. * a Byte array.
  37530. * n Number of bytes in array to read.
  37531. */
  37532. static void sp_521_from_bin(sp_digit* r, int size, const byte* a, int n)
  37533. {
  37534. int i;
  37535. int j = 0;
  37536. word32 s = 0;
  37537. r[0] = 0;
  37538. for (i = n-1; i >= 0; i--) {
  37539. r[j] |= (((sp_digit)a[i]) << s);
  37540. if (s >= 50U) {
  37541. r[j] &= 0x3ffffffffffffffL;
  37542. s = 58U - s;
  37543. if (j + 1 >= size) {
  37544. break;
  37545. }
  37546. r[++j] = (sp_digit)a[i] >> s;
  37547. s = 8U - s;
  37548. }
  37549. else {
  37550. s += 8U;
  37551. }
  37552. }
  37553. for (j++; j < size; j++) {
  37554. r[j] = 0;
  37555. }
  37556. }
  37557. /* Generates a scalar that is in the range 1..order-1.
  37558. *
  37559. * rng Random number generator.
  37560. * k Scalar value.
  37561. * returns RNG failures, MEMORY_E when memory allocation fails and
  37562. * MP_OKAY on success.
  37563. */
  37564. static int sp_521_ecc_gen_k_9(WC_RNG* rng, sp_digit* k)
  37565. {
  37566. int err;
  37567. byte buf[66];
  37568. do {
  37569. err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));
  37570. if (err == 0) {
  37571. buf[0] &= 0x1;
  37572. sp_521_from_bin(k, 9, buf, (int)sizeof(buf));
  37573. if (sp_521_cmp_9(k, p521_order2) <= 0) {
  37574. sp_521_add_one_9(k);
  37575. break;
  37576. }
  37577. }
  37578. }
  37579. while (err == 0);
  37580. return err;
  37581. }
  37582. /* Makes a random EC key pair.
  37583. *
  37584. * rng Random number generator.
  37585. * priv Generated private value.
  37586. * pub Generated public point.
  37587. * heap Heap to use for allocation.
  37588. * returns ECC_INF_E when the point does not have the correct order, RNG
  37589. * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.
  37590. */
  37591. int sp_ecc_make_key_521(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)
  37592. {
  37593. #ifdef WOLFSSL_SP_SMALL_STACK
  37594. sp_point_521* point = NULL;
  37595. sp_digit* k = NULL;
  37596. #else
  37597. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  37598. sp_point_521 point[2];
  37599. #else
  37600. sp_point_521 point[1];
  37601. #endif
  37602. sp_digit k[9];
  37603. #endif
  37604. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  37605. sp_point_521* infinity = NULL;
  37606. #endif
  37607. int err = MP_OKAY;
  37608. (void)heap;
  37609. #ifdef WOLFSSL_SP_SMALL_STACK
  37610. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  37611. point = (sp_point_521*)XMALLOC(sizeof(sp_point_521) * 2, heap, DYNAMIC_TYPE_ECC);
  37612. #else
  37613. point = (sp_point_521*)XMALLOC(sizeof(sp_point_521), heap, DYNAMIC_TYPE_ECC);
  37614. #endif
  37615. if (point == NULL)
  37616. err = MEMORY_E;
  37617. if (err == MP_OKAY) {
  37618. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9, heap,
  37619. DYNAMIC_TYPE_ECC);
  37620. if (k == NULL)
  37621. err = MEMORY_E;
  37622. }
  37623. #endif
  37624. if (err == MP_OKAY) {
  37625. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  37626. infinity = point + 1;
  37627. #endif
  37628. err = sp_521_ecc_gen_k_9(rng, k);
  37629. }
  37630. if (err == MP_OKAY) {
  37631. err = sp_521_ecc_mulmod_base_9(point, k, 1, 1, NULL);
  37632. }
  37633. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  37634. if (err == MP_OKAY) {
  37635. err = sp_521_ecc_mulmod_9(infinity, point, p521_order, 1, 1, NULL);
  37636. }
  37637. if (err == MP_OKAY) {
  37638. if (sp_521_iszero_9(point->x) || sp_521_iszero_9(point->y)) {
  37639. err = ECC_INF_E;
  37640. }
  37641. }
  37642. #endif
  37643. if (err == MP_OKAY) {
  37644. err = sp_521_to_mp(k, priv);
  37645. }
  37646. if (err == MP_OKAY) {
  37647. err = sp_521_point_to_ecc_point_9(point, pub);
  37648. }
  37649. #ifdef WOLFSSL_SP_SMALL_STACK
  37650. if (k != NULL)
  37651. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  37652. if (point != NULL) {
  37653. /* point is not sensitive, so no need to zeroize */
  37654. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  37655. }
  37656. #endif
  37657. return err;
  37658. }
  37659. #ifdef WOLFSSL_SP_NONBLOCK
  37660. typedef struct sp_ecc_key_gen_521_ctx {
  37661. int state;
  37662. sp_521_ecc_mulmod_9_ctx mulmod_ctx;
  37663. sp_digit k[9];
  37664. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  37665. sp_point_521 point[2];
  37666. #else
  37667. sp_point_521 point[1];
  37668. #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN */
  37669. } sp_ecc_key_gen_521_ctx;
  37670. int sp_ecc_make_key_521_nb(sp_ecc_ctx_t* sp_ctx, WC_RNG* rng, mp_int* priv,
  37671. ecc_point* pub, void* heap)
  37672. {
  37673. int err = FP_WOULDBLOCK;
  37674. sp_ecc_key_gen_521_ctx* ctx = (sp_ecc_key_gen_521_ctx*)sp_ctx->data;
  37675. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  37676. sp_point_521* infinity = ctx->point + 1;
  37677. #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN */
  37678. typedef char ctx_size_test[sizeof(sp_ecc_key_gen_521_ctx)
  37679. >= sizeof(*sp_ctx) ? -1 : 1];
  37680. (void)sizeof(ctx_size_test);
  37681. switch (ctx->state) {
  37682. case 0:
  37683. err = sp_521_ecc_gen_k_9(rng, ctx->k);
  37684. if (err == MP_OKAY) {
  37685. err = FP_WOULDBLOCK;
  37686. ctx->state = 1;
  37687. }
  37688. break;
  37689. case 1:
  37690. err = sp_521_ecc_mulmod_base_9_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx,
  37691. ctx->point, ctx->k, 1, 1, heap);
  37692. if (err == MP_OKAY) {
  37693. err = FP_WOULDBLOCK;
  37694. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  37695. XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
  37696. ctx->state = 2;
  37697. #else
  37698. ctx->state = 3;
  37699. #endif
  37700. }
  37701. break;
  37702. #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
  37703. case 2:
  37704. err = sp_521_ecc_mulmod_9_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx,
  37705. infinity, ctx->point, p521_order, 1, 1);
  37706. if (err == MP_OKAY) {
  37707. if (sp_521_iszero_9(ctx->point->x) ||
  37708. sp_521_iszero_9(ctx->point->y)) {
  37709. err = ECC_INF_E;
  37710. }
  37711. else {
  37712. err = FP_WOULDBLOCK;
  37713. ctx->state = 3;
  37714. }
  37715. }
  37716. break;
  37717. #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN */
  37718. case 3:
  37719. err = sp_521_to_mp(ctx->k, priv);
  37720. if (err == MP_OKAY) {
  37721. err = sp_521_point_to_ecc_point_9(ctx->point, pub);
  37722. }
  37723. break;
  37724. }
  37725. if (err != FP_WOULDBLOCK) {
  37726. XMEMSET(ctx, 0, sizeof(sp_ecc_key_gen_521_ctx));
  37727. }
  37728. return err;
  37729. }
  37730. #endif /* WOLFSSL_SP_NONBLOCK */
  37731. #ifdef HAVE_ECC_DHE
  37732. /* Write r as big endian to byte array.
  37733. * Fixed length number of bytes written: 66
  37734. *
  37735. * r A single precision integer.
  37736. * a Byte array.
  37737. */
  37738. static void sp_521_to_bin_9(sp_digit* r, byte* a)
  37739. {
  37740. int i;
  37741. int j;
  37742. int s = 0;
  37743. int b;
  37744. for (i=0; i<8; i++) {
  37745. r[i+1] += r[i] >> 58;
  37746. r[i] &= 0x3ffffffffffffffL;
  37747. }
  37748. j = 528 / 8 - 1;
  37749. a[j] = 0;
  37750. for (i=0; i<9 && j>=0; i++) {
  37751. b = 0;
  37752. /* lint allow cast of mismatch sp_digit and int */
  37753. a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
  37754. b += 8 - s;
  37755. if (j < 0) {
  37756. break;
  37757. }
  37758. while (b < 58) {
  37759. a[j--] = (byte)(r[i] >> b);
  37760. b += 8;
  37761. if (j < 0) {
  37762. break;
  37763. }
  37764. }
  37765. s = 8 - (b - 58);
  37766. if (j >= 0) {
  37767. a[j] = 0;
  37768. }
  37769. if (s != 0) {
  37770. j++;
  37771. }
  37772. }
  37773. }
  37774. /* Multiply the point by the scalar and serialize the X ordinate.
  37775. * The number is 0 padded to maximum size on output.
  37776. *
  37777. * priv Scalar to multiply the point by.
  37778. * pub Point to multiply.
  37779. * out Buffer to hold X ordinate.
  37780. * outLen On entry, size of the buffer in bytes.
  37781. * On exit, length of data in buffer in bytes.
  37782. * heap Heap to use for allocation.
  37783. * returns BUFFER_E if the buffer is to small for output size,
  37784. * MEMORY_E when memory allocation fails and MP_OKAY on success.
  37785. */
  37786. int sp_ecc_secret_gen_521(const mp_int* priv, const ecc_point* pub, byte* out,
  37787. word32* outLen, void* heap)
  37788. {
  37789. #ifdef WOLFSSL_SP_SMALL_STACK
  37790. sp_point_521* point = NULL;
  37791. sp_digit* k = NULL;
  37792. #else
  37793. sp_point_521 point[1];
  37794. sp_digit k[9];
  37795. #endif
  37796. int err = MP_OKAY;
  37797. if (*outLen < 65U) {
  37798. err = BUFFER_E;
  37799. }
  37800. #ifdef WOLFSSL_SP_SMALL_STACK
  37801. if (err == MP_OKAY) {
  37802. point = (sp_point_521*)XMALLOC(sizeof(sp_point_521), heap,
  37803. DYNAMIC_TYPE_ECC);
  37804. if (point == NULL)
  37805. err = MEMORY_E;
  37806. }
  37807. if (err == MP_OKAY) {
  37808. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9, heap,
  37809. DYNAMIC_TYPE_ECC);
  37810. if (k == NULL)
  37811. err = MEMORY_E;
  37812. }
  37813. #endif
  37814. if (err == MP_OKAY) {
  37815. sp_521_from_mp(k, 9, priv);
  37816. sp_521_point_from_ecc_point_9(point, pub);
  37817. err = sp_521_ecc_mulmod_9(point, point, k, 1, 1, heap);
  37818. }
  37819. if (err == MP_OKAY) {
  37820. sp_521_to_bin_9(point->x, out);
  37821. *outLen = 66;
  37822. }
  37823. #ifdef WOLFSSL_SP_SMALL_STACK
  37824. if (k != NULL)
  37825. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  37826. if (point != NULL)
  37827. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  37828. #endif
  37829. return err;
  37830. }
  37831. #ifdef WOLFSSL_SP_NONBLOCK
  37832. typedef struct sp_ecc_sec_gen_521_ctx {
  37833. int state;
  37834. union {
  37835. sp_521_ecc_mulmod_9_ctx mulmod_ctx;
  37836. };
  37837. sp_digit k[9];
  37838. sp_point_521 point;
  37839. } sp_ecc_sec_gen_521_ctx;
  37840. int sp_ecc_secret_gen_521_nb(sp_ecc_ctx_t* sp_ctx, const mp_int* priv,
  37841. const ecc_point* pub, byte* out, word32* outLen, void* heap)
  37842. {
  37843. int err = FP_WOULDBLOCK;
  37844. sp_ecc_sec_gen_521_ctx* ctx = (sp_ecc_sec_gen_521_ctx*)sp_ctx->data;
  37845. typedef char ctx_size_test[sizeof(sp_ecc_sec_gen_521_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  37846. (void)sizeof(ctx_size_test);
  37847. if (*outLen < 32U) {
  37848. err = BUFFER_E;
  37849. }
  37850. switch (ctx->state) {
  37851. case 0:
  37852. sp_521_from_mp(ctx->k, 9, priv);
  37853. sp_521_point_from_ecc_point_9(&ctx->point, pub);
  37854. ctx->state = 1;
  37855. break;
  37856. case 1:
  37857. err = sp_521_ecc_mulmod_9_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx,
  37858. &ctx->point, &ctx->point, ctx->k, 1, 1, heap);
  37859. if (err == MP_OKAY) {
  37860. sp_521_to_bin_9(ctx->point.x, out);
  37861. *outLen = 66;
  37862. }
  37863. break;
  37864. }
  37865. if (err == MP_OKAY && ctx->state != 1) {
  37866. err = FP_WOULDBLOCK;
  37867. }
  37868. if (err != FP_WOULDBLOCK) {
  37869. XMEMSET(ctx, 0, sizeof(sp_ecc_sec_gen_521_ctx));
  37870. }
  37871. return err;
  37872. }
  37873. #endif /* WOLFSSL_SP_NONBLOCK */
  37874. #endif /* HAVE_ECC_DHE */
  37875. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  37876. SP_NOINLINE static void sp_521_rshift_9(sp_digit* r, const sp_digit* a,
  37877. byte n)
  37878. {
  37879. int i;
  37880. #ifdef WOLFSSL_SP_SMALL
  37881. for (i=0; i<8; i++) {
  37882. r[i] = ((a[i] >> n) | (a[i + 1] << (58 - n))) & 0x3ffffffffffffffL;
  37883. }
  37884. #else
  37885. for (i=0; i<8; i += 8) {
  37886. r[i+0] = (a[i+0] >> n) | ((a[i+1] << (58 - n)) & 0x3ffffffffffffffL);
  37887. r[i+1] = (a[i+1] >> n) | ((a[i+2] << (58 - n)) & 0x3ffffffffffffffL);
  37888. r[i+2] = (a[i+2] >> n) | ((a[i+3] << (58 - n)) & 0x3ffffffffffffffL);
  37889. r[i+3] = (a[i+3] >> n) | ((a[i+4] << (58 - n)) & 0x3ffffffffffffffL);
  37890. r[i+4] = (a[i+4] >> n) | ((a[i+5] << (58 - n)) & 0x3ffffffffffffffL);
  37891. r[i+5] = (a[i+5] >> n) | ((a[i+6] << (58 - n)) & 0x3ffffffffffffffL);
  37892. r[i+6] = (a[i+6] >> n) | ((a[i+7] << (58 - n)) & 0x3ffffffffffffffL);
  37893. r[i+7] = (a[i+7] >> n) | ((a[i+8] << (58 - n)) & 0x3ffffffffffffffL);
  37894. }
  37895. #endif /* WOLFSSL_SP_SMALL */
  37896. r[8] = a[8] >> n;
  37897. }
  37898. #endif
  37899. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  37900. /* Multiply a by scalar b into r. (r = a * b)
  37901. *
  37902. * r A single precision integer.
  37903. * a A single precision integer.
  37904. * b A scalar.
  37905. */
  37906. SP_NOINLINE static void sp_521_mul_d_9(sp_digit* r, const sp_digit* a,
  37907. sp_digit b)
  37908. {
  37909. #ifdef WOLFSSL_SP_SMALL
  37910. sp_int128 tb = b;
  37911. sp_int128 t = 0;
  37912. int i;
  37913. for (i = 0; i < 9; i++) {
  37914. t += tb * a[i];
  37915. r[i] = (sp_digit)(t & 0x3ffffffffffffffL);
  37916. t >>= 58;
  37917. }
  37918. r[9] = (sp_digit)t;
  37919. #else
  37920. sp_int128 tb = b;
  37921. sp_int128 t[9];
  37922. t[ 0] = tb * a[ 0];
  37923. t[ 1] = tb * a[ 1];
  37924. t[ 2] = tb * a[ 2];
  37925. t[ 3] = tb * a[ 3];
  37926. t[ 4] = tb * a[ 4];
  37927. t[ 5] = tb * a[ 5];
  37928. t[ 6] = tb * a[ 6];
  37929. t[ 7] = tb * a[ 7];
  37930. t[ 8] = tb * a[ 8];
  37931. r[ 0] = (sp_digit) (t[ 0] & 0x3ffffffffffffffL);
  37932. r[ 1] = (sp_digit)((t[ 0] >> 58) + (t[ 1] & 0x3ffffffffffffffL));
  37933. r[ 2] = (sp_digit)((t[ 1] >> 58) + (t[ 2] & 0x3ffffffffffffffL));
  37934. r[ 3] = (sp_digit)((t[ 2] >> 58) + (t[ 3] & 0x3ffffffffffffffL));
  37935. r[ 4] = (sp_digit)((t[ 3] >> 58) + (t[ 4] & 0x3ffffffffffffffL));
  37936. r[ 5] = (sp_digit)((t[ 4] >> 58) + (t[ 5] & 0x3ffffffffffffffL));
  37937. r[ 6] = (sp_digit)((t[ 5] >> 58) + (t[ 6] & 0x3ffffffffffffffL));
  37938. r[ 7] = (sp_digit)((t[ 6] >> 58) + (t[ 7] & 0x3ffffffffffffffL));
  37939. r[ 8] = (sp_digit)((t[ 7] >> 58) + (t[ 8] & 0x3ffffffffffffffL));
  37940. r[ 9] = (sp_digit) (t[ 8] >> 58);
  37941. #endif /* WOLFSSL_SP_SMALL */
  37942. }
  37943. SP_NOINLINE static void sp_521_lshift_18(sp_digit* r, const sp_digit* a,
  37944. byte n)
  37945. {
  37946. #ifdef WOLFSSL_SP_SMALL
  37947. int i;
  37948. r[18] = a[17] >> (58 - n);
  37949. for (i=17; i>0; i--) {
  37950. r[i] = ((a[i] << n) | (a[i-1] >> (58 - n))) & 0x3ffffffffffffffL;
  37951. }
  37952. #else
  37953. sp_int_digit s;
  37954. sp_int_digit t;
  37955. s = (sp_int_digit)a[17];
  37956. r[18] = s >> (58U - n);
  37957. s = (sp_int_digit)(a[17]); t = (sp_int_digit)(a[16]);
  37958. r[17] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37959. s = (sp_int_digit)(a[16]); t = (sp_int_digit)(a[15]);
  37960. r[16] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37961. s = (sp_int_digit)(a[15]); t = (sp_int_digit)(a[14]);
  37962. r[15] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37963. s = (sp_int_digit)(a[14]); t = (sp_int_digit)(a[13]);
  37964. r[14] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37965. s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);
  37966. r[13] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37967. s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);
  37968. r[12] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37969. s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);
  37970. r[11] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37971. s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);
  37972. r[10] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37973. s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);
  37974. r[9] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37975. s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);
  37976. r[8] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37977. s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);
  37978. r[7] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37979. s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);
  37980. r[6] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37981. s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);
  37982. r[5] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37983. s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);
  37984. r[4] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37985. s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);
  37986. r[3] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37987. s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);
  37988. r[2] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37989. s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);
  37990. r[1] = ((s << n) | (t >> (58U - n))) & 0x3ffffffffffffffUL;
  37991. #endif /* WOLFSSL_SP_SMALL */
  37992. r[0] = (a[0] << n) & 0x3ffffffffffffffL;
  37993. }
  37994. /* Divide d in a and put remainder into r (m*d + r = a)
  37995. * m is not calculated as it is not needed at this time.
  37996. *
  37997. * Simplified based on top word of divisor being (1 << 58) - 1
  37998. *
  37999. * a Number to be divided.
  38000. * d Number to divide with.
  38001. * m Multiplier result.
  38002. * r Remainder from the division.
  38003. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  38004. */
  38005. static int sp_521_div_9(const sp_digit* a, const sp_digit* d,
  38006. const sp_digit* m, sp_digit* r)
  38007. {
  38008. int i;
  38009. sp_digit r1;
  38010. sp_digit mask;
  38011. #ifdef WOLFSSL_SP_SMALL_STACK
  38012. sp_digit* t1 = NULL;
  38013. #else
  38014. sp_digit t1[4 * 9 + 3];
  38015. #endif
  38016. sp_digit* t2 = NULL;
  38017. sp_digit* sd = NULL;
  38018. int err = MP_OKAY;
  38019. (void)m;
  38020. #ifdef WOLFSSL_SP_SMALL_STACK
  38021. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 9 + 3), NULL,
  38022. DYNAMIC_TYPE_TMP_BUFFER);
  38023. if (t1 == NULL)
  38024. err = MEMORY_E;
  38025. #endif
  38026. (void)m;
  38027. if (err == MP_OKAY) {
  38028. t2 = t1 + 18 + 1;
  38029. sd = t2 + 9 + 1;
  38030. sp_521_mul_d_9(sd, d, (sp_digit)1 << 1);
  38031. sp_521_lshift_18(t1, a, 1);
  38032. t1[9 + 9] += t1[9 + 9 - 1] >> 58;
  38033. t1[9 + 9 - 1] &= 0x3ffffffffffffffL;
  38034. for (i=8; i>=0; i--) {
  38035. r1 = t1[9 + i];
  38036. sp_521_mul_d_9(t2, sd, r1);
  38037. (void)sp_521_sub_9(&t1[i], &t1[i], t2);
  38038. t1[9 + i] -= t2[9];
  38039. sp_521_norm_9(&t1[i + 1]);
  38040. mask = ~((t1[9 + i] - 1) >> 63);
  38041. sp_521_cond_sub_9(t1 + i, t1 + i, sd, mask);
  38042. sp_521_norm_9(&t1[i + 1]);
  38043. }
  38044. sp_521_norm_9(t1);
  38045. sp_521_rshift_9(r, t1, 1);
  38046. }
  38047. #ifdef WOLFSSL_SP_SMALL_STACK
  38048. if (t1 != NULL)
  38049. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  38050. #endif
  38051. return err;
  38052. }
  38053. /* Reduce a modulo m into r. (r = a mod m)
  38054. *
  38055. * r A single precision number that is the reduced result.
  38056. * a A single precision number that is to be reduced.
  38057. * m A single precision number that is the modulus to reduce with.
  38058. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  38059. */
  38060. static int sp_521_mod_9(sp_digit* r, const sp_digit* a, const sp_digit* m)
  38061. {
  38062. return sp_521_div_9(a, m, NULL, r);
  38063. }
  38064. #endif
  38065. #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
  38066. /* Multiply two number mod the order of P521 curve. (r = a * b mod order)
  38067. *
  38068. * r Result of the multiplication.
  38069. * a First operand of the multiplication.
  38070. * b Second operand of the multiplication.
  38071. */
  38072. static void sp_521_mont_mul_order_9(sp_digit* r, const sp_digit* a, const sp_digit* b)
  38073. {
  38074. sp_521_mul_9(r, a, b);
  38075. sp_521_mont_reduce_order_9(r, p521_order, p521_mp_order);
  38076. }
  38077. #if defined(HAVE_ECC_SIGN) || (defined(HAVE_ECC_VERIFY) && defined(WOLFSSL_SP_SMALL))
  38078. #ifdef WOLFSSL_SP_SMALL
  38079. /* Order-2 for the P521 curve. */
  38080. static const uint64_t p521_order_minus_2[9] = {
  38081. 0xbb6fb71e91386407U,0x3bb5c9b8899c47aeU,0x7fcc0148f709a5d0U,
  38082. 0x51868783bf2f966bU,0xfffffffffffffffaU,0xffffffffffffffffU,
  38083. 0xffffffffffffffffU,0xffffffffffffffffU,0x00000000000001ffU
  38084. };
  38085. #else
  38086. /* The low half of the order-2 of the P521 curve. */
  38087. static const uint64_t p521_order_low[5] = {
  38088. 0xbb6fb71e91386407U,0x3bb5c9b8899c47aeU,0x7fcc0148f709a5d0U,
  38089. 0x51868783bf2f966bU,0xfffffffffffffffaU
  38090. };
  38091. #endif /* WOLFSSL_SP_SMALL */
  38092. /* Square number mod the order of P521 curve. (r = a * a mod order)
  38093. *
  38094. * r Result of the squaring.
  38095. * a Number to square.
  38096. */
  38097. static void sp_521_mont_sqr_order_9(sp_digit* r, const sp_digit* a)
  38098. {
  38099. sp_521_sqr_9(r, a);
  38100. sp_521_mont_reduce_order_9(r, p521_order, p521_mp_order);
  38101. }
  38102. #ifndef WOLFSSL_SP_SMALL
  38103. /* Square number mod the order of P521 curve a number of times.
  38104. * (r = a ^ n mod order)
  38105. *
  38106. * r Result of the squaring.
  38107. * a Number to square.
  38108. */
  38109. static void sp_521_mont_sqr_n_order_9(sp_digit* r, const sp_digit* a, int n)
  38110. {
  38111. int i;
  38112. sp_521_mont_sqr_order_9(r, a);
  38113. for (i=1; i<n; i++) {
  38114. sp_521_mont_sqr_order_9(r, r);
  38115. }
  38116. }
  38117. #endif /* !WOLFSSL_SP_SMALL */
  38118. /* Invert the number, in Montgomery form, modulo the order of the P521 curve.
  38119. * (r = 1 / a mod order)
  38120. *
  38121. * r Inverse result.
  38122. * a Number to invert.
  38123. * td Temporary data.
  38124. */
  38125. #ifdef WOLFSSL_SP_NONBLOCK
  38126. typedef struct sp_521_mont_inv_order_9_ctx {
  38127. int state;
  38128. int i;
  38129. } sp_521_mont_inv_order_9_ctx;
  38130. static int sp_521_mont_inv_order_9_nb(sp_ecc_ctx_t* sp_ctx, sp_digit* r, const sp_digit* a,
  38131. sp_digit* t)
  38132. {
  38133. int err = FP_WOULDBLOCK;
  38134. sp_521_mont_inv_order_9_ctx* ctx = (sp_521_mont_inv_order_9_ctx*)sp_ctx;
  38135. typedef char ctx_size_test[sizeof(sp_521_mont_inv_order_9_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  38136. (void)sizeof(ctx_size_test);
  38137. switch (ctx->state) {
  38138. case 0:
  38139. XMEMCPY(t, a, sizeof(sp_digit) * 9);
  38140. ctx->i = 519;
  38141. ctx->state = 1;
  38142. break;
  38143. case 1:
  38144. sp_521_mont_sqr_order_9(t, t);
  38145. ctx->state = 2;
  38146. break;
  38147. case 2:
  38148. if ((p521_order_minus_2[ctx->i / 64] & ((sp_int_digit)1 << (ctx->i % 64))) != 0) {
  38149. sp_521_mont_mul_order_9(t, t, a);
  38150. }
  38151. ctx->i--;
  38152. ctx->state = (ctx->i == 0) ? 3 : 1;
  38153. break;
  38154. case 3:
  38155. XMEMCPY(r, t, sizeof(sp_digit) * 9U);
  38156. err = MP_OKAY;
  38157. break;
  38158. }
  38159. return err;
  38160. }
  38161. #endif /* WOLFSSL_SP_NONBLOCK */
  38162. static void sp_521_mont_inv_order_9(sp_digit* r, const sp_digit* a,
  38163. sp_digit* td)
  38164. {
  38165. #ifdef WOLFSSL_SP_SMALL
  38166. sp_digit* t = td;
  38167. int i;
  38168. XMEMCPY(t, a, sizeof(sp_digit) * 9);
  38169. for (i=519; i>=0; i--) {
  38170. sp_521_mont_sqr_order_9(t, t);
  38171. if ((p521_order_minus_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
  38172. sp_521_mont_mul_order_9(t, t, a);
  38173. }
  38174. }
  38175. XMEMCPY(r, t, sizeof(sp_digit) * 9U);
  38176. #else
  38177. sp_digit* t = td;
  38178. sp_digit* t2 = td + 2 * 9;
  38179. sp_digit* t3 = td + 4 * 9;
  38180. int i;
  38181. /* t = a^2 */
  38182. sp_521_mont_sqr_order_9(t, a);
  38183. /* t = a^3 = t * a */
  38184. sp_521_mont_mul_order_9(t, t, a);
  38185. /* t= a^c = t ^ 2 ^ 2 */
  38186. sp_521_mont_sqr_n_order_9(t2, t, 2);
  38187. /* t = a^f = t2 * t */
  38188. sp_521_mont_mul_order_9(t, t2, t);
  38189. /* t3 = a^1e */
  38190. sp_521_mont_sqr_order_9(t3, t);
  38191. /* t3 = a^1f = t3 * a */
  38192. sp_521_mont_mul_order_9(t3, t3, a);
  38193. /* t2= a^f0 = t ^ 2 ^ 4 */
  38194. sp_521_mont_sqr_n_order_9(t2, t, 4);
  38195. /* t = a^ff = t2 * t */
  38196. sp_521_mont_mul_order_9(t, t2, t);
  38197. /* t2= a^ff00 = t ^ 2 ^ 8 */
  38198. sp_521_mont_sqr_n_order_9(t2, t, 8);
  38199. /* t3= a^ffff = t2 * t */
  38200. sp_521_mont_mul_order_9(t, t2, t);
  38201. /* t2= a^ffff0000 = t ^ 2 ^ 16 */
  38202. sp_521_mont_sqr_n_order_9(t2, t, 16);
  38203. /* t = a^ffffffff = t2 * t */
  38204. sp_521_mont_mul_order_9(t, t2, t);
  38205. /* t2= a^ffffffff00000000 = t ^ 2 ^ 32 */
  38206. sp_521_mont_sqr_n_order_9(t2, t, 32);
  38207. /* t = a^ffffffffffffffff = t2 * t */
  38208. sp_521_mont_mul_order_9(t, t2, t);
  38209. /* t2= a^ffffffffffffffff0000000000000000 = t ^ 2 ^ 64 */
  38210. sp_521_mont_sqr_n_order_9(t2, t, 64);
  38211. /* t = a^ffffffffffffffffffffffffffffffff = t2 * t */
  38212. sp_521_mont_mul_order_9(t, t2, t);
  38213. /* t2= a^ffffffffffffffffffffffffffffffff00000000000000000000000000000000 = t ^ 2 ^ 128 */
  38214. sp_521_mont_sqr_n_order_9(t2, t, 128);
  38215. /* t = a^ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff = t2 * t */
  38216. sp_521_mont_mul_order_9(t, t2, t);
  38217. /* t2 = a^1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0 */
  38218. sp_521_mont_sqr_n_order_9(t2, t, 5);
  38219. /* t2 = a^1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff = t * t3 */
  38220. sp_521_mont_mul_order_9(t2, t2, t3);
  38221. for (i=259; i>=1; i--) {
  38222. sp_521_mont_sqr_order_9(t2, t2);
  38223. if ((p521_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
  38224. sp_521_mont_mul_order_9(t2, t2, a);
  38225. }
  38226. }
  38227. sp_521_mont_sqr_order_9(t2, t2);
  38228. sp_521_mont_mul_order_9(r, t2, a);
  38229. #endif /* WOLFSSL_SP_SMALL */
  38230. }
  38231. #endif /* HAVE_ECC_SIGN || (HAVE_ECC_VERIFY && WOLFSSL_SP_SMALL) */
  38232. #endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */
  38233. #ifdef HAVE_ECC_SIGN
  38234. #ifndef SP_ECC_MAX_SIG_GEN
  38235. #define SP_ECC_MAX_SIG_GEN 64
  38236. #endif
  38237. /* Calculate second signature value S from R, k and private value.
  38238. *
  38239. * s = (r * x + e) / k
  38240. *
  38241. * s Signature value.
  38242. * r First signature value.
  38243. * k Ephemeral private key.
  38244. * x Private key as a number.
  38245. * e Hash of message as a number.
  38246. * tmp Temporary storage for intermediate numbers.
  38247. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  38248. */
  38249. static int sp_521_calc_s_9(sp_digit* s, const sp_digit* r, sp_digit* k,
  38250. sp_digit* x, const sp_digit* e, sp_digit* tmp)
  38251. {
  38252. int err;
  38253. sp_digit carry;
  38254. sp_int64 c;
  38255. sp_digit* kInv = k;
  38256. /* Conv k to Montgomery form (mod order) */
  38257. sp_521_mul_9(k, k, p521_norm_order);
  38258. err = sp_521_mod_9(k, k, p521_order);
  38259. if (err == MP_OKAY) {
  38260. sp_521_norm_9(k);
  38261. /* kInv = 1/k mod order */
  38262. sp_521_mont_inv_order_9(kInv, k, tmp);
  38263. sp_521_norm_9(kInv);
  38264. /* s = r * x + e */
  38265. sp_521_mul_9(x, x, r);
  38266. err = sp_521_mod_9(x, x, p521_order);
  38267. }
  38268. if (err == MP_OKAY) {
  38269. sp_521_norm_9(x);
  38270. carry = sp_521_add_9(s, e, x);
  38271. sp_521_cond_sub_9(s, s, p521_order, 0 - carry);
  38272. sp_521_norm_9(s);
  38273. c = sp_521_cmp_9(s, p521_order);
  38274. sp_521_cond_sub_9(s, s, p521_order,
  38275. (sp_digit)0 - (sp_digit)(c >= 0));
  38276. sp_521_norm_9(s);
  38277. /* s = s * k^-1 mod order */
  38278. sp_521_mont_mul_order_9(s, s, kInv);
  38279. sp_521_norm_9(s);
  38280. }
  38281. return err;
  38282. }
  38283. /* Sign the hash using the private key.
  38284. * e = [hash, 521 bits] from binary
  38285. * r = (k.G)->x mod order
  38286. * s = (r * x + e) / k mod order
  38287. * The hash is truncated to the first 521 bits.
  38288. *
  38289. * hash Hash to sign.
  38290. * hashLen Length of the hash data.
  38291. * rng Random number generator.
  38292. * priv Private part of key - scalar.
  38293. * rm First part of result as an mp_int.
  38294. * sm Sirst part of result as an mp_int.
  38295. * heap Heap to use for allocation.
  38296. * returns RNG failures, MEMORY_E when memory allocation fails and
  38297. * MP_OKAY on success.
  38298. */
  38299. int sp_ecc_sign_521(const byte* hash, word32 hashLen, WC_RNG* rng,
  38300. const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap)
  38301. {
  38302. #ifdef WOLFSSL_SP_SMALL_STACK
  38303. sp_digit* e = NULL;
  38304. sp_point_521* point = NULL;
  38305. #else
  38306. sp_digit e[7 * 2 * 9];
  38307. sp_point_521 point[1];
  38308. #endif
  38309. sp_digit* x = NULL;
  38310. sp_digit* k = NULL;
  38311. sp_digit* r = NULL;
  38312. sp_digit* tmp = NULL;
  38313. sp_digit* s = NULL;
  38314. sp_int64 c;
  38315. int err = MP_OKAY;
  38316. int i;
  38317. (void)heap;
  38318. #ifdef WOLFSSL_SP_SMALL_STACK
  38319. if (err == MP_OKAY) {
  38320. point = (sp_point_521*)XMALLOC(sizeof(sp_point_521), heap,
  38321. DYNAMIC_TYPE_ECC);
  38322. if (point == NULL)
  38323. err = MEMORY_E;
  38324. }
  38325. if (err == MP_OKAY) {
  38326. e = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 9, heap,
  38327. DYNAMIC_TYPE_ECC);
  38328. if (e == NULL)
  38329. err = MEMORY_E;
  38330. }
  38331. #endif
  38332. if (err == MP_OKAY) {
  38333. x = e + 2 * 9;
  38334. k = e + 4 * 9;
  38335. r = e + 6 * 9;
  38336. tmp = e + 8 * 9;
  38337. s = e;
  38338. if (hashLen > 66U) {
  38339. hashLen = 66U;
  38340. }
  38341. }
  38342. for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {
  38343. /* New random point. */
  38344. if (km == NULL || mp_iszero(km)) {
  38345. err = sp_521_ecc_gen_k_9(rng, k);
  38346. }
  38347. else {
  38348. sp_521_from_mp(k, 9, km);
  38349. mp_zero(km);
  38350. }
  38351. if (err == MP_OKAY) {
  38352. err = sp_521_ecc_mulmod_base_9(point, k, 1, 1, heap);
  38353. }
  38354. if (err == MP_OKAY) {
  38355. /* r = point->x mod order */
  38356. XMEMCPY(r, point->x, sizeof(sp_digit) * 9U);
  38357. sp_521_norm_9(r);
  38358. c = sp_521_cmp_9(r, p521_order);
  38359. sp_521_cond_sub_9(r, r, p521_order,
  38360. (sp_digit)0 - (sp_digit)(c >= 0));
  38361. sp_521_norm_9(r);
  38362. if (!sp_521_iszero_9(r)) {
  38363. /* x is modified in calculation of s. */
  38364. sp_521_from_mp(x, 9, priv);
  38365. /* s ptr == e ptr, e is modified in calculation of s. */
  38366. sp_521_from_bin(e, 9, hash, (int)hashLen);
  38367. /* Take 521 leftmost bits of hash. */
  38368. if (hashLen == 66U) {
  38369. sp_521_rshift_9(e, e, 7);
  38370. e[8] |= ((sp_digit)hash[0]) << 49;
  38371. }
  38372. err = sp_521_calc_s_9(s, r, k, x, e, tmp);
  38373. /* Check that signature is usable. */
  38374. if ((err == MP_OKAY) && (!sp_521_iszero_9(s))) {
  38375. break;
  38376. }
  38377. }
  38378. }
  38379. #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
  38380. i = 1;
  38381. #endif
  38382. }
  38383. if (i == 0) {
  38384. err = RNG_FAILURE_E;
  38385. }
  38386. if (err == MP_OKAY) {
  38387. err = sp_521_to_mp(r, rm);
  38388. }
  38389. if (err == MP_OKAY) {
  38390. err = sp_521_to_mp(s, sm);
  38391. }
  38392. #ifdef WOLFSSL_SP_SMALL_STACK
  38393. if (e != NULL)
  38394. #endif
  38395. {
  38396. ForceZero(e, sizeof(sp_digit) * 7 * 2 * 9);
  38397. #ifdef WOLFSSL_SP_SMALL_STACK
  38398. XFREE(e, heap, DYNAMIC_TYPE_ECC);
  38399. #endif
  38400. }
  38401. #ifdef WOLFSSL_SP_SMALL_STACK
  38402. if (point != NULL)
  38403. #endif
  38404. {
  38405. ForceZero(point, sizeof(sp_point_521));
  38406. #ifdef WOLFSSL_SP_SMALL_STACK
  38407. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  38408. #endif
  38409. }
  38410. return err;
  38411. }
  38412. #ifdef WOLFSSL_SP_NONBLOCK
  38413. typedef struct sp_ecc_sign_521_ctx {
  38414. int state;
  38415. union {
  38416. sp_521_ecc_mulmod_9_ctx mulmod_ctx;
  38417. sp_521_mont_inv_order_9_ctx mont_inv_order_ctx;
  38418. };
  38419. sp_digit e[2*9];
  38420. sp_digit x[2*9];
  38421. sp_digit k[2*9];
  38422. sp_digit r[2*9];
  38423. sp_digit tmp[3 * 2*9];
  38424. sp_point_521 point;
  38425. sp_digit* s;
  38426. sp_digit* kInv;
  38427. int i;
  38428. } sp_ecc_sign_521_ctx;
  38429. int sp_ecc_sign_521_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng,
  38430. mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap)
  38431. {
  38432. int err = FP_WOULDBLOCK;
  38433. sp_ecc_sign_521_ctx* ctx = (sp_ecc_sign_521_ctx*)sp_ctx->data;
  38434. typedef char ctx_size_test[sizeof(sp_ecc_sign_521_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  38435. (void)sizeof(ctx_size_test);
  38436. switch (ctx->state) {
  38437. case 0: /* INIT */
  38438. ctx->s = ctx->e;
  38439. ctx->kInv = ctx->k;
  38440. ctx->i = SP_ECC_MAX_SIG_GEN;
  38441. ctx->state = 1;
  38442. break;
  38443. case 1: /* GEN */
  38444. /* New random point. */
  38445. if (km == NULL || mp_iszero(km)) {
  38446. err = sp_521_ecc_gen_k_9(rng, ctx->k);
  38447. }
  38448. else {
  38449. sp_521_from_mp(ctx->k, 9, km);
  38450. mp_zero(km);
  38451. }
  38452. XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
  38453. ctx->state = 2;
  38454. break;
  38455. case 2: /* MULMOD */
  38456. err = sp_521_ecc_mulmod_9_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx,
  38457. &ctx->point, &p521_base, ctx->k, 1, 1, heap);
  38458. if (err == MP_OKAY) {
  38459. ctx->state = 3;
  38460. }
  38461. break;
  38462. case 3: /* MODORDER */
  38463. {
  38464. sp_int64 c;
  38465. /* r = point->x mod order */
  38466. XMEMCPY(ctx->r, ctx->point.x, sizeof(sp_digit) * 9U);
  38467. sp_521_norm_9(ctx->r);
  38468. c = sp_521_cmp_9(ctx->r, p521_order);
  38469. sp_521_cond_sub_9(ctx->r, ctx->r, p521_order,
  38470. (sp_digit)0 - (sp_digit)(c >= 0));
  38471. sp_521_norm_9(ctx->r);
  38472. if (hashLen > 66U) {
  38473. hashLen = 66U;
  38474. }
  38475. sp_521_from_mp(ctx->x, 9, priv);
  38476. sp_521_from_bin(ctx->e, 9, hash, (int)hashLen);
  38477. if (hashLen == 66U) {
  38478. sp_521_rshift_9(ctx->e, ctx->e, 7);
  38479. ctx->e[8] |= ((sp_digit)hash[0]) << 49;
  38480. }
  38481. ctx->state = 4;
  38482. break;
  38483. }
  38484. case 4: /* KMODORDER */
  38485. /* Conv k to Montgomery form (mod order) */
  38486. sp_521_mul_9(ctx->k, ctx->k, p521_norm_order);
  38487. err = sp_521_mod_9(ctx->k, ctx->k, p521_order);
  38488. if (err == MP_OKAY) {
  38489. sp_521_norm_9(ctx->k);
  38490. XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
  38491. ctx->state = 5;
  38492. }
  38493. break;
  38494. case 5: /* KINV */
  38495. /* kInv = 1/k mod order */
  38496. err = sp_521_mont_inv_order_9_nb((sp_ecc_ctx_t*)&ctx->mont_inv_order_ctx, ctx->kInv, ctx->k, ctx->tmp);
  38497. if (err == MP_OKAY) {
  38498. XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
  38499. ctx->state = 6;
  38500. }
  38501. break;
  38502. case 6: /* KINVNORM */
  38503. sp_521_norm_9(ctx->kInv);
  38504. ctx->state = 7;
  38505. break;
  38506. case 7: /* R */
  38507. /* s = r * x + e */
  38508. sp_521_mul_9(ctx->x, ctx->x, ctx->r);
  38509. ctx->state = 8;
  38510. break;
  38511. case 8: /* S1 */
  38512. err = sp_521_mod_9(ctx->x, ctx->x, p521_order);
  38513. if (err == MP_OKAY)
  38514. ctx->state = 9;
  38515. break;
  38516. case 9: /* S2 */
  38517. {
  38518. sp_digit carry;
  38519. sp_int64 c;
  38520. sp_521_norm_9(ctx->x);
  38521. carry = sp_521_add_9(ctx->s, ctx->e, ctx->x);
  38522. sp_521_cond_sub_9(ctx->s, ctx->s,
  38523. p521_order, 0 - carry);
  38524. sp_521_norm_9(ctx->s);
  38525. c = sp_521_cmp_9(ctx->s, p521_order);
  38526. sp_521_cond_sub_9(ctx->s, ctx->s, p521_order,
  38527. (sp_digit)0 - (sp_digit)(c >= 0));
  38528. sp_521_norm_9(ctx->s);
  38529. /* s = s * k^-1 mod order */
  38530. sp_521_mont_mul_order_9(ctx->s, ctx->s, ctx->kInv);
  38531. sp_521_norm_9(ctx->s);
  38532. /* Check that signature is usable. */
  38533. if (sp_521_iszero_9(ctx->s) == 0) {
  38534. ctx->state = 10;
  38535. break;
  38536. }
  38537. #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
  38538. ctx->i = 1;
  38539. #endif
  38540. /* not usable gen, try again */
  38541. ctx->i--;
  38542. if (ctx->i == 0) {
  38543. err = RNG_FAILURE_E;
  38544. }
  38545. ctx->state = 1;
  38546. break;
  38547. }
  38548. case 10: /* RES */
  38549. err = sp_521_to_mp(ctx->r, rm);
  38550. if (err == MP_OKAY) {
  38551. err = sp_521_to_mp(ctx->s, sm);
  38552. }
  38553. break;
  38554. }
  38555. if (err == MP_OKAY && ctx->state != 10) {
  38556. err = FP_WOULDBLOCK;
  38557. }
  38558. if (err != FP_WOULDBLOCK) {
  38559. XMEMSET(ctx->e, 0, sizeof(sp_digit) * 2U * 9U);
  38560. XMEMSET(ctx->x, 0, sizeof(sp_digit) * 2U * 9U);
  38561. XMEMSET(ctx->k, 0, sizeof(sp_digit) * 2U * 9U);
  38562. XMEMSET(ctx->r, 0, sizeof(sp_digit) * 2U * 9U);
  38563. XMEMSET(ctx->tmp, 0, sizeof(sp_digit) * 3U * 2U * 9U);
  38564. }
  38565. return err;
  38566. }
  38567. #endif /* WOLFSSL_SP_NONBLOCK */
  38568. #endif /* HAVE_ECC_SIGN */
  38569. #ifndef WOLFSSL_SP_SMALL
  38570. static const char sp_521_tab64_9[64] = {
  38571. 64, 1, 59, 2, 60, 48, 54, 3,
  38572. 61, 40, 49, 28, 55, 34, 43, 4,
  38573. 62, 52, 38, 41, 50, 19, 29, 21,
  38574. 56, 31, 35, 12, 44, 15, 23, 5,
  38575. 63, 58, 47, 53, 39, 27, 33, 42,
  38576. 51, 37, 18, 20, 30, 11, 14, 22,
  38577. 57, 46, 26, 32, 36, 17, 10, 13,
  38578. 45, 25, 16, 9, 24, 8, 7, 6};
  38579. static int sp_521_num_bits_58_9(sp_digit v)
  38580. {
  38581. v |= v >> 1;
  38582. v |= v >> 2;
  38583. v |= v >> 4;
  38584. v |= v >> 8;
  38585. v |= v >> 16;
  38586. v |= v >> 32;
  38587. return sp_521_tab64_9[((uint64_t)((v - (v >> 1))*0x07EDD5E59A4E28C2)) >> 58];
  38588. }
  38589. static int sp_521_num_bits_9(const sp_digit* a)
  38590. {
  38591. int i;
  38592. int r = 0;
  38593. for (i = 8; i >= 0; i--) {
  38594. if (a[i] != 0) {
  38595. r = sp_521_num_bits_58_9(a[i]);
  38596. r += i * 58;
  38597. break;
  38598. }
  38599. }
  38600. return r;
  38601. }
  38602. /* Non-constant time modular inversion.
  38603. *
  38604. * @param [out] r Resulting number.
  38605. * @param [in] a Number to invert.
  38606. * @param [in] m Modulus.
  38607. * @return MP_OKAY on success.
  38608. * @return MEMEORY_E when dynamic memory allocation fails.
  38609. */
  38610. static int sp_521_mod_inv_9(sp_digit* r, const sp_digit* a, const sp_digit* m)
  38611. {
  38612. int err = MP_OKAY;
  38613. #ifdef WOLFSSL_SP_SMALL_STACK
  38614. sp_digit* u = NULL;
  38615. #else
  38616. sp_digit u[9 * 4];
  38617. #endif
  38618. sp_digit* v = NULL;
  38619. sp_digit* b = NULL;
  38620. sp_digit* d = NULL;
  38621. int ut;
  38622. int vt;
  38623. #ifdef WOLFSSL_SP_SMALL_STACK
  38624. u = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9 * 4, NULL,
  38625. DYNAMIC_TYPE_ECC);
  38626. if (u == NULL)
  38627. err = MEMORY_E;
  38628. #endif
  38629. if (err == MP_OKAY) {
  38630. v = u + 9;
  38631. b = u + 2 * 9;
  38632. d = u + 3 * 9;
  38633. XMEMCPY(u, m, sizeof(sp_digit) * 9);
  38634. XMEMCPY(v, a, sizeof(sp_digit) * 9);
  38635. ut = sp_521_num_bits_9(u);
  38636. vt = sp_521_num_bits_9(v);
  38637. XMEMSET(b, 0, sizeof(sp_digit) * 9);
  38638. if ((v[0] & 1) == 0) {
  38639. sp_521_rshift1_9(v, v);
  38640. XMEMCPY(d, m, sizeof(sp_digit) * 9);
  38641. d[0]++;
  38642. sp_521_rshift1_9(d, d);
  38643. vt--;
  38644. while ((v[0] & 1) == 0) {
  38645. sp_521_rshift1_9(v, v);
  38646. if (d[0] & 1)
  38647. sp_521_add_9(d, d, m);
  38648. sp_521_rshift1_9(d, d);
  38649. vt--;
  38650. }
  38651. }
  38652. else {
  38653. XMEMSET(d+1, 0, sizeof(sp_digit) * (9 - 1));
  38654. d[0] = 1;
  38655. }
  38656. while (ut > 1 && vt > 1) {
  38657. if ((ut > vt) || ((ut == vt) &&
  38658. (sp_521_cmp_9(u, v) >= 0))) {
  38659. sp_521_sub_9(u, u, v);
  38660. sp_521_norm_9(u);
  38661. sp_521_sub_9(b, b, d);
  38662. sp_521_norm_9(b);
  38663. if (b[8] < 0)
  38664. sp_521_add_9(b, b, m);
  38665. sp_521_norm_9(b);
  38666. ut = sp_521_num_bits_9(u);
  38667. do {
  38668. sp_521_rshift1_9(u, u);
  38669. if (b[0] & 1)
  38670. sp_521_add_9(b, b, m);
  38671. sp_521_rshift1_9(b, b);
  38672. ut--;
  38673. }
  38674. while (ut > 0 && (u[0] & 1) == 0);
  38675. }
  38676. else {
  38677. sp_521_sub_9(v, v, u);
  38678. sp_521_norm_9(v);
  38679. sp_521_sub_9(d, d, b);
  38680. sp_521_norm_9(d);
  38681. if (d[8] < 0)
  38682. sp_521_add_9(d, d, m);
  38683. sp_521_norm_9(d);
  38684. vt = sp_521_num_bits_9(v);
  38685. do {
  38686. sp_521_rshift1_9(v, v);
  38687. if (d[0] & 1)
  38688. sp_521_add_9(d, d, m);
  38689. sp_521_rshift1_9(d, d);
  38690. vt--;
  38691. }
  38692. while (vt > 0 && (v[0] & 1) == 0);
  38693. }
  38694. }
  38695. if (ut == 1)
  38696. XMEMCPY(r, b, sizeof(sp_digit) * 9);
  38697. else
  38698. XMEMCPY(r, d, sizeof(sp_digit) * 9);
  38699. }
  38700. #ifdef WOLFSSL_SP_SMALL_STACK
  38701. if (u != NULL)
  38702. XFREE(u, NULL, DYNAMIC_TYPE_ECC);
  38703. #endif
  38704. return err;
  38705. }
  38706. #endif /* WOLFSSL_SP_SMALL */
  38707. /* Add point p1 into point p2. Handles p1 == p2 and result at infinity.
  38708. *
  38709. * p1 First point to add and holds result.
  38710. * p2 Second point to add.
  38711. * tmp Temporary storage for intermediate numbers.
  38712. */
  38713. static void sp_521_add_points_9(sp_point_521* p1, const sp_point_521* p2,
  38714. sp_digit* tmp)
  38715. {
  38716. sp_521_proj_point_add_9(p1, p1, p2, tmp);
  38717. if (sp_521_iszero_9(p1->z)) {
  38718. if (sp_521_iszero_9(p1->x) && sp_521_iszero_9(p1->y)) {
  38719. sp_521_proj_point_dbl_9(p1, p2, tmp);
  38720. }
  38721. else {
  38722. /* Y ordinate is not used from here - don't set. */
  38723. p1->x[0] = 0;
  38724. p1->x[1] = 0;
  38725. p1->x[2] = 0;
  38726. p1->x[3] = 0;
  38727. p1->x[4] = 0;
  38728. p1->x[5] = 0;
  38729. p1->x[6] = 0;
  38730. p1->x[7] = 0;
  38731. p1->x[8] = 0;
  38732. XMEMCPY(p1->z, p521_norm_mod, sizeof(p521_norm_mod));
  38733. }
  38734. }
  38735. }
  38736. /* Calculate the verification point: [e/s]G + [r/s]Q
  38737. *
  38738. * p1 Calculated point.
  38739. * p2 Public point and temporary.
  38740. * s Second part of signature as a number.
  38741. * u1 Temporary number.
  38742. * u2 Temporary number.
  38743. * heap Heap to use for allocation.
  38744. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  38745. */
  38746. static int sp_521_calc_vfy_point_9(sp_point_521* p1, sp_point_521* p2,
  38747. sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap)
  38748. {
  38749. int err;
  38750. #ifndef WOLFSSL_SP_SMALL
  38751. err = sp_521_mod_inv_9(s, s, p521_order);
  38752. if (err == MP_OKAY)
  38753. #endif /* !WOLFSSL_SP_SMALL */
  38754. {
  38755. sp_521_mul_9(s, s, p521_norm_order);
  38756. err = sp_521_mod_9(s, s, p521_order);
  38757. }
  38758. if (err == MP_OKAY) {
  38759. sp_521_norm_9(s);
  38760. #ifdef WOLFSSL_SP_SMALL
  38761. {
  38762. sp_521_mont_inv_order_9(s, s, tmp);
  38763. sp_521_mont_mul_order_9(u1, u1, s);
  38764. sp_521_mont_mul_order_9(u2, u2, s);
  38765. }
  38766. #else
  38767. {
  38768. sp_521_mont_mul_order_9(u1, u1, s);
  38769. sp_521_mont_mul_order_9(u2, u2, s);
  38770. }
  38771. #endif /* WOLFSSL_SP_SMALL */
  38772. {
  38773. err = sp_521_ecc_mulmod_base_9(p1, u1, 0, 0, heap);
  38774. }
  38775. }
  38776. if ((err == MP_OKAY) && sp_521_iszero_9(p1->z)) {
  38777. p1->infinity = 1;
  38778. }
  38779. if (err == MP_OKAY) {
  38780. err = sp_521_ecc_mulmod_9(p2, p2, u2, 0, 0, heap);
  38781. }
  38782. if ((err == MP_OKAY) && sp_521_iszero_9(p2->z)) {
  38783. p2->infinity = 1;
  38784. }
  38785. if (err == MP_OKAY) {
  38786. sp_521_add_points_9(p1, p2, tmp);
  38787. }
  38788. return err;
  38789. }
  38790. #ifdef HAVE_ECC_VERIFY
  38791. /* Verify the signature values with the hash and public key.
  38792. * e = Truncate(hash, 521)
  38793. * u1 = e/s mod order
  38794. * u2 = r/s mod order
  38795. * r == (u1.G + u2.Q)->x mod order
  38796. * Optimization: Leave point in projective form.
  38797. * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')
  38798. * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'
  38799. * The hash is truncated to the first 521 bits.
  38800. *
  38801. * hash Hash to sign.
  38802. * hashLen Length of the hash data.
  38803. * rng Random number generator.
  38804. * priv Private part of key - scalar.
  38805. * rm First part of result as an mp_int.
  38806. * sm Sirst part of result as an mp_int.
  38807. * heap Heap to use for allocation.
  38808. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  38809. */
  38810. int sp_ecc_verify_521(const byte* hash, word32 hashLen, const mp_int* pX,
  38811. const mp_int* pY, const mp_int* pZ, const mp_int* rm, const mp_int* sm,
  38812. int* res, void* heap)
  38813. {
  38814. #ifdef WOLFSSL_SP_SMALL_STACK
  38815. sp_digit* u1 = NULL;
  38816. sp_point_521* p1 = NULL;
  38817. #else
  38818. sp_digit u1[18 * 9];
  38819. sp_point_521 p1[2];
  38820. #endif
  38821. sp_digit* u2 = NULL;
  38822. sp_digit* s = NULL;
  38823. sp_digit* tmp = NULL;
  38824. sp_point_521* p2 = NULL;
  38825. sp_digit carry;
  38826. sp_int64 c = 0;
  38827. int err = MP_OKAY;
  38828. #ifdef WOLFSSL_SP_SMALL_STACK
  38829. if (err == MP_OKAY) {
  38830. p1 = (sp_point_521*)XMALLOC(sizeof(sp_point_521) * 2, heap,
  38831. DYNAMIC_TYPE_ECC);
  38832. if (p1 == NULL)
  38833. err = MEMORY_E;
  38834. }
  38835. if (err == MP_OKAY) {
  38836. u1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 9, heap,
  38837. DYNAMIC_TYPE_ECC);
  38838. if (u1 == NULL)
  38839. err = MEMORY_E;
  38840. }
  38841. #endif
  38842. if (err == MP_OKAY) {
  38843. u2 = u1 + 2 * 9;
  38844. s = u1 + 4 * 9;
  38845. tmp = u1 + 6 * 9;
  38846. p2 = p1 + 1;
  38847. if (hashLen > 66U) {
  38848. hashLen = 66U;
  38849. }
  38850. sp_521_from_bin(u1, 9, hash, (int)hashLen);
  38851. sp_521_from_mp(u2, 9, rm);
  38852. sp_521_from_mp(s, 9, sm);
  38853. sp_521_from_mp(p2->x, 9, pX);
  38854. sp_521_from_mp(p2->y, 9, pY);
  38855. sp_521_from_mp(p2->z, 9, pZ);
  38856. if (hashLen == 66U) {
  38857. sp_521_rshift_9(u1, u1, 7);
  38858. u1[8] |= ((sp_digit)hash[0]) << 49;
  38859. }
  38860. err = sp_521_calc_vfy_point_9(p1, p2, s, u1, u2, tmp, heap);
  38861. }
  38862. if (err == MP_OKAY) {
  38863. /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
  38864. /* Reload r and convert to Montgomery form. */
  38865. sp_521_from_mp(u2, 9, rm);
  38866. err = sp_521_mod_mul_norm_9(u2, u2, p521_mod);
  38867. }
  38868. if (err == MP_OKAY) {
  38869. /* u1 = r.z'.z' mod prime */
  38870. sp_521_mont_sqr_9(p1->z, p1->z, p521_mod, p521_mp_mod);
  38871. sp_521_mont_mul_9(u1, u2, p1->z, p521_mod, p521_mp_mod);
  38872. *res = (int)(sp_521_cmp_9(p1->x, u1) == 0);
  38873. if (*res == 0) {
  38874. /* Reload r and add order. */
  38875. sp_521_from_mp(u2, 9, rm);
  38876. carry = sp_521_add_9(u2, u2, p521_order);
  38877. /* Carry means result is greater than mod and is not valid. */
  38878. if (carry == 0) {
  38879. sp_521_norm_9(u2);
  38880. /* Compare with mod and if greater or equal then not valid. */
  38881. c = sp_521_cmp_9(u2, p521_mod);
  38882. }
  38883. }
  38884. if ((*res == 0) && (c < 0)) {
  38885. /* Convert to Montogomery form */
  38886. err = sp_521_mod_mul_norm_9(u2, u2, p521_mod);
  38887. if (err == MP_OKAY) {
  38888. /* u1 = (r + 1*order).z'.z' mod prime */
  38889. {
  38890. sp_521_mont_mul_9(u1, u2, p1->z, p521_mod, p521_mp_mod);
  38891. }
  38892. *res = (sp_521_cmp_9(p1->x, u1) == 0);
  38893. }
  38894. }
  38895. }
  38896. #ifdef WOLFSSL_SP_SMALL_STACK
  38897. if (u1 != NULL)
  38898. XFREE(u1, heap, DYNAMIC_TYPE_ECC);
  38899. if (p1 != NULL)
  38900. XFREE(p1, heap, DYNAMIC_TYPE_ECC);
  38901. #endif
  38902. return err;
  38903. }
  38904. #ifdef WOLFSSL_SP_NONBLOCK
  38905. typedef struct sp_ecc_verify_521_ctx {
  38906. int state;
  38907. union {
  38908. sp_521_ecc_mulmod_9_ctx mulmod_ctx;
  38909. sp_521_mont_inv_order_9_ctx mont_inv_order_ctx;
  38910. sp_521_proj_point_dbl_9_ctx dbl_ctx;
  38911. sp_521_proj_point_add_9_ctx add_ctx;
  38912. };
  38913. sp_digit u1[2*9];
  38914. sp_digit u2[2*9];
  38915. sp_digit s[2*9];
  38916. sp_digit tmp[2*9 * 6];
  38917. sp_point_521 p1;
  38918. sp_point_521 p2;
  38919. } sp_ecc_verify_521_ctx;
  38920. int sp_ecc_verify_521_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash,
  38921. word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ,
  38922. const mp_int* rm, const mp_int* sm, int* res, void* heap)
  38923. {
  38924. int err = FP_WOULDBLOCK;
  38925. sp_ecc_verify_521_ctx* ctx = (sp_ecc_verify_521_ctx*)sp_ctx->data;
  38926. typedef char ctx_size_test[sizeof(sp_ecc_verify_521_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  38927. (void)sizeof(ctx_size_test);
  38928. switch (ctx->state) {
  38929. case 0: /* INIT */
  38930. if (hashLen > 66U) {
  38931. hashLen = 66U;
  38932. }
  38933. sp_521_from_bin(ctx->u1, 9, hash, (int)hashLen);
  38934. sp_521_from_mp(ctx->u2, 9, rm);
  38935. sp_521_from_mp(ctx->s, 9, sm);
  38936. sp_521_from_mp(ctx->p2.x, 9, pX);
  38937. sp_521_from_mp(ctx->p2.y, 9, pY);
  38938. sp_521_from_mp(ctx->p2.z, 9, pZ);
  38939. if (hashLen == 66U) {
  38940. sp_521_rshift_9(ctx->u1, ctx->u1, 7);
  38941. ctx->u1[8] |= ((sp_digit)hash[0]) << 49;
  38942. }
  38943. ctx->state = 1;
  38944. break;
  38945. case 1: /* NORMS0 */
  38946. sp_521_mul_9(ctx->s, ctx->s, p521_norm_order);
  38947. err = sp_521_mod_9(ctx->s, ctx->s, p521_order);
  38948. if (err == MP_OKAY)
  38949. ctx->state = 2;
  38950. break;
  38951. case 2: /* NORMS1 */
  38952. sp_521_norm_9(ctx->s);
  38953. XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
  38954. ctx->state = 3;
  38955. break;
  38956. case 3: /* NORMS2 */
  38957. err = sp_521_mont_inv_order_9_nb((sp_ecc_ctx_t*)&ctx->mont_inv_order_ctx, ctx->s, ctx->s, ctx->tmp);
  38958. if (err == MP_OKAY) {
  38959. ctx->state = 4;
  38960. }
  38961. break;
  38962. case 4: /* NORMS3 */
  38963. sp_521_mont_mul_order_9(ctx->u1, ctx->u1, ctx->s);
  38964. ctx->state = 5;
  38965. break;
  38966. case 5: /* NORMS4 */
  38967. sp_521_mont_mul_order_9(ctx->u2, ctx->u2, ctx->s);
  38968. XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
  38969. ctx->state = 6;
  38970. break;
  38971. case 6: /* MULBASE */
  38972. err = sp_521_ecc_mulmod_9_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx, &ctx->p1, &p521_base, ctx->u1, 0, 0, heap);
  38973. if (err == MP_OKAY) {
  38974. if (sp_521_iszero_9(ctx->p1.z)) {
  38975. ctx->p1.infinity = 1;
  38976. }
  38977. XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
  38978. ctx->state = 7;
  38979. }
  38980. break;
  38981. case 7: /* MULMOD */
  38982. err = sp_521_ecc_mulmod_9_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx, &ctx->p2, &ctx->p2, ctx->u2, 0, 0, heap);
  38983. if (err == MP_OKAY) {
  38984. if (sp_521_iszero_9(ctx->p2.z)) {
  38985. ctx->p2.infinity = 1;
  38986. }
  38987. XMEMSET(&ctx->add_ctx, 0, sizeof(ctx->add_ctx));
  38988. ctx->state = 8;
  38989. }
  38990. break;
  38991. case 8: /* ADD */
  38992. err = sp_521_proj_point_add_9_nb((sp_ecc_ctx_t*)&ctx->add_ctx, &ctx->p1, &ctx->p1, &ctx->p2, ctx->tmp);
  38993. if (err == MP_OKAY)
  38994. ctx->state = 9;
  38995. break;
  38996. case 9: /* MONT */
  38997. /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
  38998. /* Reload r and convert to Montgomery form. */
  38999. sp_521_from_mp(ctx->u2, 9, rm);
  39000. err = sp_521_mod_mul_norm_9(ctx->u2, ctx->u2, p521_mod);
  39001. if (err == MP_OKAY)
  39002. ctx->state = 10;
  39003. break;
  39004. case 10: /* SQR */
  39005. /* u1 = r.z'.z' mod prime */
  39006. sp_521_mont_sqr_9(ctx->p1.z, ctx->p1.z, p521_mod, p521_mp_mod);
  39007. ctx->state = 11;
  39008. break;
  39009. case 11: /* MUL */
  39010. sp_521_mont_mul_9(ctx->u1, ctx->u2, ctx->p1.z, p521_mod, p521_mp_mod);
  39011. ctx->state = 12;
  39012. break;
  39013. case 12: /* RES */
  39014. {
  39015. sp_int64 c = 0;
  39016. err = MP_OKAY; /* math okay, now check result */
  39017. *res = (int)(sp_521_cmp_9(ctx->p1.x, ctx->u1) == 0);
  39018. if (*res == 0) {
  39019. sp_digit carry;
  39020. /* Reload r and add order. */
  39021. sp_521_from_mp(ctx->u2, 9, rm);
  39022. carry = sp_521_add_9(ctx->u2, ctx->u2, p521_order);
  39023. /* Carry means result is greater than mod and is not valid. */
  39024. if (carry == 0) {
  39025. sp_521_norm_9(ctx->u2);
  39026. /* Compare with mod and if greater or equal then not valid. */
  39027. c = sp_521_cmp_9(ctx->u2, p521_mod);
  39028. }
  39029. }
  39030. if ((*res == 0) && (c < 0)) {
  39031. /* Convert to Montogomery form */
  39032. err = sp_521_mod_mul_norm_9(ctx->u2, ctx->u2, p521_mod);
  39033. if (err == MP_OKAY) {
  39034. /* u1 = (r + 1*order).z'.z' mod prime */
  39035. sp_521_mont_mul_9(ctx->u1, ctx->u2, ctx->p1.z, p521_mod,
  39036. p521_mp_mod);
  39037. *res = (int)(sp_521_cmp_9(ctx->p1.x, ctx->u1) == 0);
  39038. }
  39039. }
  39040. break;
  39041. }
  39042. } /* switch */
  39043. if (err == MP_OKAY && ctx->state != 12) {
  39044. err = FP_WOULDBLOCK;
  39045. }
  39046. return err;
  39047. }
  39048. #endif /* WOLFSSL_SP_NONBLOCK */
  39049. #endif /* HAVE_ECC_VERIFY */
  39050. #ifdef HAVE_ECC_CHECK_KEY
  39051. /* Check that the x and y ordinates are a valid point on the curve.
  39052. *
  39053. * point EC point.
  39054. * heap Heap to use if dynamically allocating.
  39055. * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
  39056. * not on the curve and MP_OKAY otherwise.
  39057. */
  39058. static int sp_521_ecc_is_point_9(const sp_point_521* point,
  39059. void* heap)
  39060. {
  39061. #ifdef WOLFSSL_SP_SMALL_STACK
  39062. sp_digit* t1 = NULL;
  39063. #else
  39064. sp_digit t1[9 * 4];
  39065. #endif
  39066. sp_digit* t2 = NULL;
  39067. int err = MP_OKAY;
  39068. #ifdef WOLFSSL_SP_SMALL_STACK
  39069. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9 * 4, heap, DYNAMIC_TYPE_ECC);
  39070. if (t1 == NULL)
  39071. err = MEMORY_E;
  39072. #endif
  39073. (void)heap;
  39074. if (err == MP_OKAY) {
  39075. t2 = t1 + 2 * 9;
  39076. /* y^2 - x^3 - a.x = b */
  39077. sp_521_sqr_9(t1, point->y);
  39078. (void)sp_521_mod_9(t1, t1, p521_mod);
  39079. sp_521_sqr_9(t2, point->x);
  39080. (void)sp_521_mod_9(t2, t2, p521_mod);
  39081. sp_521_mul_9(t2, t2, point->x);
  39082. (void)sp_521_mod_9(t2, t2, p521_mod);
  39083. sp_521_mont_sub_9(t1, t1, t2, p521_mod);
  39084. /* y^2 - x^3 + 3.x = b, when a = -3 */
  39085. sp_521_mont_add_9(t1, t1, point->x, p521_mod);
  39086. sp_521_mont_add_9(t1, t1, point->x, p521_mod);
  39087. sp_521_mont_add_9(t1, t1, point->x, p521_mod);
  39088. if (sp_521_cmp_9(t1, p521_b) != 0) {
  39089. err = MP_VAL;
  39090. }
  39091. }
  39092. #ifdef WOLFSSL_SP_SMALL_STACK
  39093. if (t1 != NULL)
  39094. XFREE(t1, heap, DYNAMIC_TYPE_ECC);
  39095. #endif
  39096. return err;
  39097. }
  39098. /* Check that the x and y ordinates are a valid point on the curve.
  39099. *
  39100. * pX X ordinate of EC point.
  39101. * pY Y ordinate of EC point.
  39102. * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
  39103. * not on the curve and MP_OKAY otherwise.
  39104. */
  39105. int sp_ecc_is_point_521(const mp_int* pX, const mp_int* pY)
  39106. {
  39107. #ifdef WOLFSSL_SP_SMALL_STACK
  39108. sp_point_521* pub = NULL;
  39109. #else
  39110. sp_point_521 pub[1];
  39111. #endif
  39112. const byte one[1] = { 1 };
  39113. int err = MP_OKAY;
  39114. #ifdef WOLFSSL_SP_SMALL_STACK
  39115. pub = (sp_point_521*)XMALLOC(sizeof(sp_point_521), NULL,
  39116. DYNAMIC_TYPE_ECC);
  39117. if (pub == NULL)
  39118. err = MEMORY_E;
  39119. #endif
  39120. if (err == MP_OKAY) {
  39121. sp_521_from_mp(pub->x, 9, pX);
  39122. sp_521_from_mp(pub->y, 9, pY);
  39123. sp_521_from_bin(pub->z, 9, one, (int)sizeof(one));
  39124. err = sp_521_ecc_is_point_9(pub, NULL);
  39125. }
  39126. #ifdef WOLFSSL_SP_SMALL_STACK
  39127. if (pub != NULL)
  39128. XFREE(pub, NULL, DYNAMIC_TYPE_ECC);
  39129. #endif
  39130. return err;
  39131. }
  39132. /* Check that the private scalar generates the EC point (px, py), the point is
  39133. * on the curve and the point has the correct order.
  39134. *
  39135. * pX X ordinate of EC point.
  39136. * pY Y ordinate of EC point.
  39137. * privm Private scalar that generates EC point.
  39138. * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
  39139. * not on the curve, ECC_INF_E if the point does not have the correct order,
  39140. * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and
  39141. * MP_OKAY otherwise.
  39142. */
  39143. int sp_ecc_check_key_521(const mp_int* pX, const mp_int* pY,
  39144. const mp_int* privm, void* heap)
  39145. {
  39146. #ifdef WOLFSSL_SP_SMALL_STACK
  39147. sp_digit* priv = NULL;
  39148. sp_point_521* pub = NULL;
  39149. #else
  39150. sp_digit priv[9];
  39151. sp_point_521 pub[2];
  39152. #endif
  39153. sp_point_521* p = NULL;
  39154. const byte one[1] = { 1 };
  39155. int err = MP_OKAY;
  39156. /* Quick check the lengs of public key ordinates and private key are in
  39157. * range. Proper check later.
  39158. */
  39159. if (((mp_count_bits(pX) > 521) ||
  39160. (mp_count_bits(pY) > 521) ||
  39161. ((privm != NULL) && (mp_count_bits(privm) > 521)))) {
  39162. err = ECC_OUT_OF_RANGE_E;
  39163. }
  39164. #ifdef WOLFSSL_SP_SMALL_STACK
  39165. if (err == MP_OKAY) {
  39166. pub = (sp_point_521*)XMALLOC(sizeof(sp_point_521) * 2, heap,
  39167. DYNAMIC_TYPE_ECC);
  39168. if (pub == NULL)
  39169. err = MEMORY_E;
  39170. }
  39171. if (err == MP_OKAY && privm) {
  39172. priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9, heap,
  39173. DYNAMIC_TYPE_ECC);
  39174. if (priv == NULL)
  39175. err = MEMORY_E;
  39176. }
  39177. #endif
  39178. if (err == MP_OKAY) {
  39179. p = pub + 1;
  39180. sp_521_from_mp(pub->x, 9, pX);
  39181. sp_521_from_mp(pub->y, 9, pY);
  39182. sp_521_from_bin(pub->z, 9, one, (int)sizeof(one));
  39183. if (privm)
  39184. sp_521_from_mp(priv, 9, privm);
  39185. /* Check point at infinitiy. */
  39186. if ((sp_521_iszero_9(pub->x) != 0) &&
  39187. (sp_521_iszero_9(pub->y) != 0)) {
  39188. err = ECC_INF_E;
  39189. }
  39190. }
  39191. /* Check range of X and Y */
  39192. if ((err == MP_OKAY) &&
  39193. ((sp_521_cmp_9(pub->x, p521_mod) >= 0) ||
  39194. (sp_521_cmp_9(pub->y, p521_mod) >= 0))) {
  39195. err = ECC_OUT_OF_RANGE_E;
  39196. }
  39197. if (err == MP_OKAY) {
  39198. /* Check point is on curve */
  39199. err = sp_521_ecc_is_point_9(pub, heap);
  39200. }
  39201. if (err == MP_OKAY) {
  39202. /* Point * order = infinity */
  39203. err = sp_521_ecc_mulmod_9(p, pub, p521_order, 1, 1, heap);
  39204. }
  39205. /* Check result is infinity */
  39206. if ((err == MP_OKAY) && ((sp_521_iszero_9(p->x) == 0) ||
  39207. (sp_521_iszero_9(p->y) == 0))) {
  39208. err = ECC_INF_E;
  39209. }
  39210. if (privm) {
  39211. if (err == MP_OKAY) {
  39212. /* Base * private = point */
  39213. err = sp_521_ecc_mulmod_base_9(p, priv, 1, 1, heap);
  39214. }
  39215. /* Check result is public key */
  39216. if ((err == MP_OKAY) &&
  39217. ((sp_521_cmp_9(p->x, pub->x) != 0) ||
  39218. (sp_521_cmp_9(p->y, pub->y) != 0))) {
  39219. err = ECC_PRIV_KEY_E;
  39220. }
  39221. }
  39222. #ifdef WOLFSSL_SP_SMALL_STACK
  39223. if (pub != NULL)
  39224. XFREE(pub, heap, DYNAMIC_TYPE_ECC);
  39225. if (priv != NULL)
  39226. XFREE(priv, heap, DYNAMIC_TYPE_ECC);
  39227. #endif
  39228. return err;
  39229. }
  39230. #endif
  39231. #ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL
  39232. /* Add two projective EC points together.
  39233. * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)
  39234. *
  39235. * pX First EC point's X ordinate.
  39236. * pY First EC point's Y ordinate.
  39237. * pZ First EC point's Z ordinate.
  39238. * qX Second EC point's X ordinate.
  39239. * qY Second EC point's Y ordinate.
  39240. * qZ Second EC point's Z ordinate.
  39241. * rX Resultant EC point's X ordinate.
  39242. * rY Resultant EC point's Y ordinate.
  39243. * rZ Resultant EC point's Z ordinate.
  39244. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  39245. */
  39246. int sp_ecc_proj_add_point_521(mp_int* pX, mp_int* pY, mp_int* pZ,
  39247. mp_int* qX, mp_int* qY, mp_int* qZ,
  39248. mp_int* rX, mp_int* rY, mp_int* rZ)
  39249. {
  39250. #ifdef WOLFSSL_SP_SMALL_STACK
  39251. sp_digit* tmp = NULL;
  39252. sp_point_521* p = NULL;
  39253. #else
  39254. sp_digit tmp[2 * 9 * 6];
  39255. sp_point_521 p[2];
  39256. #endif
  39257. sp_point_521* q = NULL;
  39258. int err = MP_OKAY;
  39259. #ifdef WOLFSSL_SP_SMALL_STACK
  39260. if (err == MP_OKAY) {
  39261. p = (sp_point_521*)XMALLOC(sizeof(sp_point_521) * 2, NULL,
  39262. DYNAMIC_TYPE_ECC);
  39263. if (p == NULL)
  39264. err = MEMORY_E;
  39265. }
  39266. if (err == MP_OKAY) {
  39267. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 9 * 6, NULL,
  39268. DYNAMIC_TYPE_ECC);
  39269. if (tmp == NULL) {
  39270. err = MEMORY_E;
  39271. }
  39272. }
  39273. #endif
  39274. if (err == MP_OKAY) {
  39275. q = p + 1;
  39276. sp_521_from_mp(p->x, 9, pX);
  39277. sp_521_from_mp(p->y, 9, pY);
  39278. sp_521_from_mp(p->z, 9, pZ);
  39279. sp_521_from_mp(q->x, 9, qX);
  39280. sp_521_from_mp(q->y, 9, qY);
  39281. sp_521_from_mp(q->z, 9, qZ);
  39282. p->infinity = sp_521_iszero_9(p->x) &
  39283. sp_521_iszero_9(p->y);
  39284. q->infinity = sp_521_iszero_9(q->x) &
  39285. sp_521_iszero_9(q->y);
  39286. sp_521_proj_point_add_9(p, p, q, tmp);
  39287. }
  39288. if (err == MP_OKAY) {
  39289. err = sp_521_to_mp(p->x, rX);
  39290. }
  39291. if (err == MP_OKAY) {
  39292. err = sp_521_to_mp(p->y, rY);
  39293. }
  39294. if (err == MP_OKAY) {
  39295. err = sp_521_to_mp(p->z, rZ);
  39296. }
  39297. #ifdef WOLFSSL_SP_SMALL_STACK
  39298. if (tmp != NULL)
  39299. XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
  39300. if (p != NULL)
  39301. XFREE(p, NULL, DYNAMIC_TYPE_ECC);
  39302. #endif
  39303. return err;
  39304. }
  39305. /* Double a projective EC point.
  39306. * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)
  39307. *
  39308. * pX EC point's X ordinate.
  39309. * pY EC point's Y ordinate.
  39310. * pZ EC point's Z ordinate.
  39311. * rX Resultant EC point's X ordinate.
  39312. * rY Resultant EC point's Y ordinate.
  39313. * rZ Resultant EC point's Z ordinate.
  39314. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  39315. */
  39316. int sp_ecc_proj_dbl_point_521(mp_int* pX, mp_int* pY, mp_int* pZ,
  39317. mp_int* rX, mp_int* rY, mp_int* rZ)
  39318. {
  39319. #ifdef WOLFSSL_SP_SMALL_STACK
  39320. sp_digit* tmp = NULL;
  39321. sp_point_521* p = NULL;
  39322. #else
  39323. sp_digit tmp[2 * 9 * 2];
  39324. sp_point_521 p[1];
  39325. #endif
  39326. int err = MP_OKAY;
  39327. #ifdef WOLFSSL_SP_SMALL_STACK
  39328. if (err == MP_OKAY) {
  39329. p = (sp_point_521*)XMALLOC(sizeof(sp_point_521), NULL,
  39330. DYNAMIC_TYPE_ECC);
  39331. if (p == NULL)
  39332. err = MEMORY_E;
  39333. }
  39334. if (err == MP_OKAY) {
  39335. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 9 * 2, NULL,
  39336. DYNAMIC_TYPE_ECC);
  39337. if (tmp == NULL)
  39338. err = MEMORY_E;
  39339. }
  39340. #endif
  39341. if (err == MP_OKAY) {
  39342. sp_521_from_mp(p->x, 9, pX);
  39343. sp_521_from_mp(p->y, 9, pY);
  39344. sp_521_from_mp(p->z, 9, pZ);
  39345. p->infinity = sp_521_iszero_9(p->x) &
  39346. sp_521_iszero_9(p->y);
  39347. sp_521_proj_point_dbl_9(p, p, tmp);
  39348. }
  39349. if (err == MP_OKAY) {
  39350. err = sp_521_to_mp(p->x, rX);
  39351. }
  39352. if (err == MP_OKAY) {
  39353. err = sp_521_to_mp(p->y, rY);
  39354. }
  39355. if (err == MP_OKAY) {
  39356. err = sp_521_to_mp(p->z, rZ);
  39357. }
  39358. #ifdef WOLFSSL_SP_SMALL_STACK
  39359. if (tmp != NULL)
  39360. XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
  39361. if (p != NULL)
  39362. XFREE(p, NULL, DYNAMIC_TYPE_ECC);
  39363. #endif
  39364. return err;
  39365. }
  39366. /* Map a projective EC point to affine in place.
  39367. * pZ will be one.
  39368. *
  39369. * pX EC point's X ordinate.
  39370. * pY EC point's Y ordinate.
  39371. * pZ EC point's Z ordinate.
  39372. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  39373. */
  39374. int sp_ecc_map_521(mp_int* pX, mp_int* pY, mp_int* pZ)
  39375. {
  39376. #ifdef WOLFSSL_SP_SMALL_STACK
  39377. sp_digit* tmp = NULL;
  39378. sp_point_521* p = NULL;
  39379. #else
  39380. sp_digit tmp[2 * 9 * 5];
  39381. sp_point_521 p[1];
  39382. #endif
  39383. int err = MP_OKAY;
  39384. #ifdef WOLFSSL_SP_SMALL_STACK
  39385. if (err == MP_OKAY) {
  39386. p = (sp_point_521*)XMALLOC(sizeof(sp_point_521), NULL,
  39387. DYNAMIC_TYPE_ECC);
  39388. if (p == NULL)
  39389. err = MEMORY_E;
  39390. }
  39391. if (err == MP_OKAY) {
  39392. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 9 * 5, NULL,
  39393. DYNAMIC_TYPE_ECC);
  39394. if (tmp == NULL)
  39395. err = MEMORY_E;
  39396. }
  39397. #endif
  39398. if (err == MP_OKAY) {
  39399. sp_521_from_mp(p->x, 9, pX);
  39400. sp_521_from_mp(p->y, 9, pY);
  39401. sp_521_from_mp(p->z, 9, pZ);
  39402. p->infinity = sp_521_iszero_9(p->x) &
  39403. sp_521_iszero_9(p->y);
  39404. sp_521_map_9(p, p, tmp);
  39405. }
  39406. if (err == MP_OKAY) {
  39407. err = sp_521_to_mp(p->x, pX);
  39408. }
  39409. if (err == MP_OKAY) {
  39410. err = sp_521_to_mp(p->y, pY);
  39411. }
  39412. if (err == MP_OKAY) {
  39413. err = sp_521_to_mp(p->z, pZ);
  39414. }
  39415. #ifdef WOLFSSL_SP_SMALL_STACK
  39416. if (tmp != NULL)
  39417. XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
  39418. if (p != NULL)
  39419. XFREE(p, NULL, DYNAMIC_TYPE_ECC);
  39420. #endif
  39421. return err;
  39422. }
  39423. #endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */
  39424. #ifdef HAVE_COMP_KEY
  39425. /* Square root power for the P521 curve. */
  39426. static const uint64_t p521_sqrt_power[9] = {
  39427. 0x0000000000000000,0x0000000000000000,0x0000000000000000,
  39428. 0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000,
  39429. 0x0000000000000080
  39430. };
  39431. /* Find the square root of a number mod the prime of the curve.
  39432. *
  39433. * y The number to operate on and the result.
  39434. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  39435. */
  39436. static int sp_521_mont_sqrt_9(sp_digit* y)
  39437. {
  39438. #ifdef WOLFSSL_SP_SMALL_STACK
  39439. sp_digit* t = NULL;
  39440. #else
  39441. sp_digit t[2 * 9];
  39442. #endif
  39443. int err = MP_OKAY;
  39444. #ifdef WOLFSSL_SP_SMALL_STACK
  39445. t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 9, NULL, DYNAMIC_TYPE_ECC);
  39446. if (t == NULL)
  39447. err = MEMORY_E;
  39448. #endif
  39449. if (err == MP_OKAY) {
  39450. {
  39451. int i;
  39452. XMEMCPY(t, y, sizeof(sp_digit) * 9);
  39453. for (i=518; i>=0; i--) {
  39454. sp_521_mont_sqr_9(t, t, p521_mod, p521_mp_mod);
  39455. if (p521_sqrt_power[i / 64] & ((sp_digit)1 << (i % 64)))
  39456. sp_521_mont_mul_9(t, t, y, p521_mod, p521_mp_mod);
  39457. }
  39458. XMEMCPY(y, t, sizeof(sp_digit) * 9);
  39459. }
  39460. }
  39461. #ifdef WOLFSSL_SP_SMALL_STACK
  39462. if (t != NULL)
  39463. XFREE(t, NULL, DYNAMIC_TYPE_ECC);
  39464. #endif
  39465. return err;
  39466. }
  39467. /* Uncompress the point given the X ordinate.
  39468. *
  39469. * xm X ordinate.
  39470. * odd Whether the Y ordinate is odd.
  39471. * ym Calculated Y ordinate.
  39472. * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
  39473. */
  39474. int sp_ecc_uncompress_521(mp_int* xm, int odd, mp_int* ym)
  39475. {
  39476. #ifdef WOLFSSL_SP_SMALL_STACK
  39477. sp_digit* x = NULL;
  39478. #else
  39479. sp_digit x[4 * 9];
  39480. #endif
  39481. sp_digit* y = NULL;
  39482. int err = MP_OKAY;
  39483. #ifdef WOLFSSL_SP_SMALL_STACK
  39484. x = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 9, NULL, DYNAMIC_TYPE_ECC);
  39485. if (x == NULL)
  39486. err = MEMORY_E;
  39487. #endif
  39488. if (err == MP_OKAY) {
  39489. y = x + 2 * 9;
  39490. sp_521_from_mp(x, 9, xm);
  39491. err = sp_521_mod_mul_norm_9(x, x, p521_mod);
  39492. }
  39493. if (err == MP_OKAY) {
  39494. /* y = x^3 */
  39495. {
  39496. sp_521_mont_sqr_9(y, x, p521_mod, p521_mp_mod);
  39497. sp_521_mont_mul_9(y, y, x, p521_mod, p521_mp_mod);
  39498. }
  39499. /* y = x^3 - 3x */
  39500. sp_521_mont_sub_9(y, y, x, p521_mod);
  39501. sp_521_mont_sub_9(y, y, x, p521_mod);
  39502. sp_521_mont_sub_9(y, y, x, p521_mod);
  39503. /* y = x^3 - 3x + b */
  39504. err = sp_521_mod_mul_norm_9(x, p521_b, p521_mod);
  39505. }
  39506. if (err == MP_OKAY) {
  39507. sp_521_mont_add_9(y, y, x, p521_mod);
  39508. /* y = sqrt(x^3 - 3x + b) */
  39509. err = sp_521_mont_sqrt_9(y);
  39510. }
  39511. if (err == MP_OKAY) {
  39512. XMEMSET(y + 9, 0, 9U * sizeof(sp_digit));
  39513. sp_521_mont_reduce_9(y, p521_mod, p521_mp_mod);
  39514. if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) {
  39515. sp_521_mont_sub_9(y, p521_mod, y, p521_mod);
  39516. }
  39517. err = sp_521_to_mp(y, ym);
  39518. }
  39519. #ifdef WOLFSSL_SP_SMALL_STACK
  39520. if (x != NULL)
  39521. XFREE(x, NULL, DYNAMIC_TYPE_ECC);
  39522. #endif
  39523. return err;
  39524. }
  39525. #endif
  39526. #endif /* WOLFSSL_SP_521 */
  39527. #ifdef WOLFCRYPT_HAVE_SAKKE
  39528. #ifdef WOLFSSL_SP_1024
  39529. /* Point structure to use. */
  39530. typedef struct sp_point_1024 {
  39531. /* X ordinate of point. */
  39532. sp_digit x[2 * 18];
  39533. /* Y ordinate of point. */
  39534. sp_digit y[2 * 18];
  39535. /* Z ordinate of point. */
  39536. sp_digit z[2 * 18];
  39537. /* Indicates point is at infinity. */
  39538. int infinity;
  39539. } sp_point_1024;
  39540. #ifndef WOLFSSL_SP_SMALL
  39541. /* Multiply a and b into r. (r = a * b)
  39542. *
  39543. * r A single precision integer.
  39544. * a A single precision integer.
  39545. * b A single precision integer.
  39546. */
  39547. SP_NOINLINE static void sp_1024_mul_9(sp_digit* r, const sp_digit* a,
  39548. const sp_digit* b)
  39549. {
  39550. sp_int128 t0;
  39551. sp_int128 t1;
  39552. sp_digit t[9];
  39553. t0 = ((sp_int128)a[ 0]) * b[ 0];
  39554. t1 = ((sp_int128)a[ 0]) * b[ 1]
  39555. + ((sp_int128)a[ 1]) * b[ 0];
  39556. t[ 0] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39557. t0 = ((sp_int128)a[ 0]) * b[ 2]
  39558. + ((sp_int128)a[ 1]) * b[ 1]
  39559. + ((sp_int128)a[ 2]) * b[ 0];
  39560. t[ 1] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39561. t1 = ((sp_int128)a[ 0]) * b[ 3]
  39562. + ((sp_int128)a[ 1]) * b[ 2]
  39563. + ((sp_int128)a[ 2]) * b[ 1]
  39564. + ((sp_int128)a[ 3]) * b[ 0];
  39565. t[ 2] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39566. t0 = ((sp_int128)a[ 0]) * b[ 4]
  39567. + ((sp_int128)a[ 1]) * b[ 3]
  39568. + ((sp_int128)a[ 2]) * b[ 2]
  39569. + ((sp_int128)a[ 3]) * b[ 1]
  39570. + ((sp_int128)a[ 4]) * b[ 0];
  39571. t[ 3] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39572. t1 = ((sp_int128)a[ 0]) * b[ 5]
  39573. + ((sp_int128)a[ 1]) * b[ 4]
  39574. + ((sp_int128)a[ 2]) * b[ 3]
  39575. + ((sp_int128)a[ 3]) * b[ 2]
  39576. + ((sp_int128)a[ 4]) * b[ 1]
  39577. + ((sp_int128)a[ 5]) * b[ 0];
  39578. t[ 4] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39579. t0 = ((sp_int128)a[ 0]) * b[ 6]
  39580. + ((sp_int128)a[ 1]) * b[ 5]
  39581. + ((sp_int128)a[ 2]) * b[ 4]
  39582. + ((sp_int128)a[ 3]) * b[ 3]
  39583. + ((sp_int128)a[ 4]) * b[ 2]
  39584. + ((sp_int128)a[ 5]) * b[ 1]
  39585. + ((sp_int128)a[ 6]) * b[ 0];
  39586. t[ 5] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39587. t1 = ((sp_int128)a[ 0]) * b[ 7]
  39588. + ((sp_int128)a[ 1]) * b[ 6]
  39589. + ((sp_int128)a[ 2]) * b[ 5]
  39590. + ((sp_int128)a[ 3]) * b[ 4]
  39591. + ((sp_int128)a[ 4]) * b[ 3]
  39592. + ((sp_int128)a[ 5]) * b[ 2]
  39593. + ((sp_int128)a[ 6]) * b[ 1]
  39594. + ((sp_int128)a[ 7]) * b[ 0];
  39595. t[ 6] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39596. t0 = ((sp_int128)a[ 0]) * b[ 8]
  39597. + ((sp_int128)a[ 1]) * b[ 7]
  39598. + ((sp_int128)a[ 2]) * b[ 6]
  39599. + ((sp_int128)a[ 3]) * b[ 5]
  39600. + ((sp_int128)a[ 4]) * b[ 4]
  39601. + ((sp_int128)a[ 5]) * b[ 3]
  39602. + ((sp_int128)a[ 6]) * b[ 2]
  39603. + ((sp_int128)a[ 7]) * b[ 1]
  39604. + ((sp_int128)a[ 8]) * b[ 0];
  39605. t[ 7] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39606. t1 = ((sp_int128)a[ 1]) * b[ 8]
  39607. + ((sp_int128)a[ 2]) * b[ 7]
  39608. + ((sp_int128)a[ 3]) * b[ 6]
  39609. + ((sp_int128)a[ 4]) * b[ 5]
  39610. + ((sp_int128)a[ 5]) * b[ 4]
  39611. + ((sp_int128)a[ 6]) * b[ 3]
  39612. + ((sp_int128)a[ 7]) * b[ 2]
  39613. + ((sp_int128)a[ 8]) * b[ 1];
  39614. t[ 8] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39615. t0 = ((sp_int128)a[ 2]) * b[ 8]
  39616. + ((sp_int128)a[ 3]) * b[ 7]
  39617. + ((sp_int128)a[ 4]) * b[ 6]
  39618. + ((sp_int128)a[ 5]) * b[ 5]
  39619. + ((sp_int128)a[ 6]) * b[ 4]
  39620. + ((sp_int128)a[ 7]) * b[ 3]
  39621. + ((sp_int128)a[ 8]) * b[ 2];
  39622. r[ 9] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39623. t1 = ((sp_int128)a[ 3]) * b[ 8]
  39624. + ((sp_int128)a[ 4]) * b[ 7]
  39625. + ((sp_int128)a[ 5]) * b[ 6]
  39626. + ((sp_int128)a[ 6]) * b[ 5]
  39627. + ((sp_int128)a[ 7]) * b[ 4]
  39628. + ((sp_int128)a[ 8]) * b[ 3];
  39629. r[10] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39630. t0 = ((sp_int128)a[ 4]) * b[ 8]
  39631. + ((sp_int128)a[ 5]) * b[ 7]
  39632. + ((sp_int128)a[ 6]) * b[ 6]
  39633. + ((sp_int128)a[ 7]) * b[ 5]
  39634. + ((sp_int128)a[ 8]) * b[ 4];
  39635. r[11] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39636. t1 = ((sp_int128)a[ 5]) * b[ 8]
  39637. + ((sp_int128)a[ 6]) * b[ 7]
  39638. + ((sp_int128)a[ 7]) * b[ 6]
  39639. + ((sp_int128)a[ 8]) * b[ 5];
  39640. r[12] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39641. t0 = ((sp_int128)a[ 6]) * b[ 8]
  39642. + ((sp_int128)a[ 7]) * b[ 7]
  39643. + ((sp_int128)a[ 8]) * b[ 6];
  39644. r[13] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39645. t1 = ((sp_int128)a[ 7]) * b[ 8]
  39646. + ((sp_int128)a[ 8]) * b[ 7];
  39647. r[14] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39648. t0 = ((sp_int128)a[ 8]) * b[ 8];
  39649. r[15] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39650. r[16] = t0 & 0x1ffffffffffffffL;
  39651. r[17] = (sp_digit)(t0 >> 57);
  39652. XMEMCPY(r, t, sizeof(t));
  39653. }
  39654. /* Square a and put result in r. (r = a * a)
  39655. *
  39656. * r A single precision integer.
  39657. * a A single precision integer.
  39658. */
  39659. SP_NOINLINE static void sp_1024_sqr_9(sp_digit* r, const sp_digit* a)
  39660. {
  39661. sp_int128 t0;
  39662. sp_int128 t1;
  39663. sp_digit t[9];
  39664. t0 = ((sp_int128)a[ 0]) * a[ 0];
  39665. t1 = (((sp_int128)a[ 0]) * a[ 1]) * 2;
  39666. t[ 0] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39667. t0 = (((sp_int128)a[ 0]) * a[ 2]) * 2
  39668. + ((sp_int128)a[ 1]) * a[ 1];
  39669. t[ 1] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39670. t1 = (((sp_int128)a[ 0]) * a[ 3]
  39671. + ((sp_int128)a[ 1]) * a[ 2]) * 2;
  39672. t[ 2] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39673. t0 = (((sp_int128)a[ 0]) * a[ 4]
  39674. + ((sp_int128)a[ 1]) * a[ 3]) * 2
  39675. + ((sp_int128)a[ 2]) * a[ 2];
  39676. t[ 3] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39677. t1 = (((sp_int128)a[ 0]) * a[ 5]
  39678. + ((sp_int128)a[ 1]) * a[ 4]
  39679. + ((sp_int128)a[ 2]) * a[ 3]) * 2;
  39680. t[ 4] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39681. t0 = (((sp_int128)a[ 0]) * a[ 6]
  39682. + ((sp_int128)a[ 1]) * a[ 5]
  39683. + ((sp_int128)a[ 2]) * a[ 4]) * 2
  39684. + ((sp_int128)a[ 3]) * a[ 3];
  39685. t[ 5] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39686. t1 = (((sp_int128)a[ 0]) * a[ 7]
  39687. + ((sp_int128)a[ 1]) * a[ 6]
  39688. + ((sp_int128)a[ 2]) * a[ 5]
  39689. + ((sp_int128)a[ 3]) * a[ 4]) * 2;
  39690. t[ 6] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39691. t0 = (((sp_int128)a[ 0]) * a[ 8]
  39692. + ((sp_int128)a[ 1]) * a[ 7]
  39693. + ((sp_int128)a[ 2]) * a[ 6]
  39694. + ((sp_int128)a[ 3]) * a[ 5]) * 2
  39695. + ((sp_int128)a[ 4]) * a[ 4];
  39696. t[ 7] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39697. t1 = (((sp_int128)a[ 1]) * a[ 8]
  39698. + ((sp_int128)a[ 2]) * a[ 7]
  39699. + ((sp_int128)a[ 3]) * a[ 6]
  39700. + ((sp_int128)a[ 4]) * a[ 5]) * 2;
  39701. t[ 8] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39702. t0 = (((sp_int128)a[ 2]) * a[ 8]
  39703. + ((sp_int128)a[ 3]) * a[ 7]
  39704. + ((sp_int128)a[ 4]) * a[ 6]) * 2
  39705. + ((sp_int128)a[ 5]) * a[ 5];
  39706. r[ 9] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39707. t1 = (((sp_int128)a[ 3]) * a[ 8]
  39708. + ((sp_int128)a[ 4]) * a[ 7]
  39709. + ((sp_int128)a[ 5]) * a[ 6]) * 2;
  39710. r[10] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39711. t0 = (((sp_int128)a[ 4]) * a[ 8]
  39712. + ((sp_int128)a[ 5]) * a[ 7]) * 2
  39713. + ((sp_int128)a[ 6]) * a[ 6];
  39714. r[11] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39715. t1 = (((sp_int128)a[ 5]) * a[ 8]
  39716. + ((sp_int128)a[ 6]) * a[ 7]) * 2;
  39717. r[12] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39718. t0 = (((sp_int128)a[ 6]) * a[ 8]) * 2
  39719. + ((sp_int128)a[ 7]) * a[ 7];
  39720. r[13] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39721. t1 = (((sp_int128)a[ 7]) * a[ 8]) * 2;
  39722. r[14] = t0 & 0x1ffffffffffffffL; t1 += t0 >> 57;
  39723. t0 = ((sp_int128)a[ 8]) * a[ 8];
  39724. r[15] = t1 & 0x1ffffffffffffffL; t0 += t1 >> 57;
  39725. r[16] = t0 & 0x1ffffffffffffffL;
  39726. r[17] = (sp_digit)(t0 >> 57);
  39727. XMEMCPY(r, t, sizeof(t));
  39728. }
  39729. /* Add b to a into r. (r = a + b)
  39730. *
  39731. * r A single precision integer.
  39732. * a A single precision integer.
  39733. * b A single precision integer.
  39734. */
  39735. SP_NOINLINE static int sp_1024_add_9(sp_digit* r, const sp_digit* a,
  39736. const sp_digit* b)
  39737. {
  39738. r[ 0] = a[ 0] + b[ 0];
  39739. r[ 1] = a[ 1] + b[ 1];
  39740. r[ 2] = a[ 2] + b[ 2];
  39741. r[ 3] = a[ 3] + b[ 3];
  39742. r[ 4] = a[ 4] + b[ 4];
  39743. r[ 5] = a[ 5] + b[ 5];
  39744. r[ 6] = a[ 6] + b[ 6];
  39745. r[ 7] = a[ 7] + b[ 7];
  39746. r[ 8] = a[ 8] + b[ 8];
  39747. return 0;
  39748. }
  39749. /* Add b to a into r. (r = a + b)
  39750. *
  39751. * r A single precision integer.
  39752. * a A single precision integer.
  39753. * b A single precision integer.
  39754. */
  39755. SP_NOINLINE static int sp_1024_add_18(sp_digit* r, const sp_digit* a,
  39756. const sp_digit* b)
  39757. {
  39758. int i;
  39759. for (i = 0; i < 16; i += 8) {
  39760. r[i + 0] = a[i + 0] + b[i + 0];
  39761. r[i + 1] = a[i + 1] + b[i + 1];
  39762. r[i + 2] = a[i + 2] + b[i + 2];
  39763. r[i + 3] = a[i + 3] + b[i + 3];
  39764. r[i + 4] = a[i + 4] + b[i + 4];
  39765. r[i + 5] = a[i + 5] + b[i + 5];
  39766. r[i + 6] = a[i + 6] + b[i + 6];
  39767. r[i + 7] = a[i + 7] + b[i + 7];
  39768. }
  39769. r[16] = a[16] + b[16];
  39770. r[17] = a[17] + b[17];
  39771. return 0;
  39772. }
  39773. /* Sub b from a into r. (r = a - b)
  39774. *
  39775. * r A single precision integer.
  39776. * a A single precision integer.
  39777. * b A single precision integer.
  39778. */
  39779. SP_NOINLINE static int sp_1024_sub_18(sp_digit* r, const sp_digit* a,
  39780. const sp_digit* b)
  39781. {
  39782. int i;
  39783. for (i = 0; i < 16; i += 8) {
  39784. r[i + 0] = a[i + 0] - b[i + 0];
  39785. r[i + 1] = a[i + 1] - b[i + 1];
  39786. r[i + 2] = a[i + 2] - b[i + 2];
  39787. r[i + 3] = a[i + 3] - b[i + 3];
  39788. r[i + 4] = a[i + 4] - b[i + 4];
  39789. r[i + 5] = a[i + 5] - b[i + 5];
  39790. r[i + 6] = a[i + 6] - b[i + 6];
  39791. r[i + 7] = a[i + 7] - b[i + 7];
  39792. }
  39793. r[16] = a[16] - b[16];
  39794. r[17] = a[17] - b[17];
  39795. return 0;
  39796. }
  39797. /* Multiply a and b into r. (r = a * b)
  39798. *
  39799. * r A single precision integer.
  39800. * a A single precision integer.
  39801. * b A single precision integer.
  39802. */
  39803. SP_NOINLINE static void sp_1024_mul_18(sp_digit* r, const sp_digit* a,
  39804. const sp_digit* b)
  39805. {
  39806. sp_digit* z0 = r;
  39807. sp_digit z1[18];
  39808. sp_digit* a1 = z1;
  39809. sp_digit b1[9];
  39810. sp_digit* z2 = r + 18;
  39811. (void)sp_1024_add_9(a1, a, &a[9]);
  39812. (void)sp_1024_add_9(b1, b, &b[9]);
  39813. sp_1024_mul_9(z2, &a[9], &b[9]);
  39814. sp_1024_mul_9(z0, a, b);
  39815. sp_1024_mul_9(z1, a1, b1);
  39816. (void)sp_1024_sub_18(z1, z1, z2);
  39817. (void)sp_1024_sub_18(z1, z1, z0);
  39818. (void)sp_1024_add_18(r + 9, r + 9, z1);
  39819. }
  39820. /* Square a and put result in r. (r = a * a)
  39821. *
  39822. * r A single precision integer.
  39823. * a A single precision integer.
  39824. */
  39825. SP_NOINLINE static void sp_1024_sqr_18(sp_digit* r, const sp_digit* a)
  39826. {
  39827. sp_digit* z0 = r;
  39828. sp_digit z1[18];
  39829. sp_digit* a1 = z1;
  39830. sp_digit* z2 = r + 18;
  39831. (void)sp_1024_add_9(a1, a, &a[9]);
  39832. sp_1024_sqr_9(z2, &a[9]);
  39833. sp_1024_sqr_9(z0, a);
  39834. sp_1024_sqr_9(z1, a1);
  39835. (void)sp_1024_sub_18(z1, z1, z2);
  39836. (void)sp_1024_sub_18(z1, z1, z0);
  39837. (void)sp_1024_add_18(r + 9, r + 9, z1);
  39838. }
  39839. #else
  39840. /* Multiply a and b into r. (r = a * b)
  39841. *
  39842. * r A single precision integer.
  39843. * a A single precision integer.
  39844. * b A single precision integer.
  39845. */
  39846. SP_NOINLINE static void sp_1024_mul_18(sp_digit* r, const sp_digit* a,
  39847. const sp_digit* b)
  39848. {
  39849. int i;
  39850. int imax;
  39851. int k;
  39852. sp_uint128 c;
  39853. sp_uint128 lo;
  39854. c = ((sp_uint128)a[17]) * b[17];
  39855. r[35] = (sp_digit)(c >> 57);
  39856. c &= 0x1ffffffffffffffL;
  39857. for (k = 33; k >= 0; k--) {
  39858. if (k >= 18) {
  39859. i = k - 17;
  39860. imax = 17;
  39861. }
  39862. else {
  39863. i = 0;
  39864. imax = k;
  39865. }
  39866. lo = 0;
  39867. for (; i <= imax; i++) {
  39868. lo += ((sp_uint128)a[i]) * b[k - i];
  39869. }
  39870. c += lo >> 57;
  39871. r[k + 2] += (sp_digit)(c >> 57);
  39872. r[k + 1] = (sp_digit)(c & 0x1ffffffffffffffL);
  39873. c = lo & 0x1ffffffffffffffL;
  39874. }
  39875. r[0] = (sp_digit)c;
  39876. }
  39877. /* Square a and put result in r. (r = a * a)
  39878. *
  39879. * r A single precision integer.
  39880. * a A single precision integer.
  39881. */
  39882. SP_NOINLINE static void sp_1024_sqr_18(sp_digit* r, const sp_digit* a)
  39883. {
  39884. int i;
  39885. int imax;
  39886. int k;
  39887. sp_uint128 c;
  39888. sp_uint128 t;
  39889. c = ((sp_uint128)a[17]) * a[17];
  39890. r[35] = (sp_digit)(c >> 57);
  39891. c = (c & 0x1ffffffffffffffL) << 57;
  39892. for (k = 33; k >= 0; k--) {
  39893. i = (k + 1) / 2;
  39894. if ((k & 1) == 0) {
  39895. c += ((sp_uint128)a[i]) * a[i];
  39896. i++;
  39897. }
  39898. if (k < 17) {
  39899. imax = k;
  39900. }
  39901. else {
  39902. imax = 17;
  39903. }
  39904. t = 0;
  39905. for (; i <= imax; i++) {
  39906. t += ((sp_uint128)a[i]) * a[k - i];
  39907. }
  39908. c += t * 2;
  39909. r[k + 2] += (sp_digit) (c >> 114);
  39910. r[k + 1] = (sp_digit)((c >> 57) & 0x1ffffffffffffffL);
  39911. c = (c & 0x1ffffffffffffffL) << 57;
  39912. }
  39913. r[0] = (sp_digit)(c >> 57);
  39914. }
  39915. #endif /* !WOLFSSL_SP_SMALL */
  39916. /* The modulus (prime) of the curve P1024. */
  39917. static const sp_digit p1024_mod[18] = {
  39918. 0x06d807afea85febL,0x0ef88563d6743b3L,0x008e2615f6c2031L,0x1ead2e3e3ff9c7dL,
  39919. 0x1c3c09aa9f94d6aL,0x02954153e79e290L,0x07386dabfd2a0c6L,0x1a8a2558b9acad0L,
  39920. 0x0e26c6487326b4cL,0x0b693fa53335368L,0x06ce7fdf222864dL,0x01aa634b3961cf2L,
  39921. 0x07e2fc0f1b22873L,0x19f00d177a05559L,0x0d20986fa6b8d62L,0x0caf482d819c339L,
  39922. 0x1da65c61198dad0L,0x04cbd5d8f852b1fL
  39923. };
  39924. /* The Montgomery normalizer for modulus of the curve P1024. */
  39925. static const sp_digit p1024_norm_mod[18] = {
  39926. 0x1927f850157a015L,0x11077a9c298bc4cL,0x1f71d9ea093dfceL,0x0152d1c1c006382L,
  39927. 0x03c3f655606b295L,0x1d6abeac1861d6fL,0x18c7925402d5f39L,0x0575daa7465352fL,
  39928. 0x11d939b78cd94b3L,0x1496c05acccac97L,0x19318020ddd79b2L,0x1e559cb4c69e30dL,
  39929. 0x181d03f0e4dd78cL,0x060ff2e885faaa6L,0x12df6790594729dL,0x1350b7d27e63cc6L,
  39930. 0x0259a39ee67252fL,0x03342a2707ad4e0L
  39931. };
  39932. /* The Montgomery multiplier for modulus of the curve P1024. */
  39933. static sp_digit p1024_mp_mod = 0x10420077c8f2f3d;
  39934. #if defined(WOLFSSL_SP_SMALL) || defined(HAVE_ECC_CHECK_KEY)
  39935. /* The order of the curve P1024. */
  39936. static const sp_digit p1024_order[18] = {
  39937. 0x19b601ebfaa17fbL,0x0bbe2158f59d0ecL,0x082389857db080cL,0x17ab4b8f8ffe71fL,
  39938. 0x070f026aa7e535aL,0x10a55054f9e78a4L,0x01ce1b6aff4a831L,0x06a289562e6b2b4L,
  39939. 0x0389b1921cc9ad3L,0x0ada4fe94ccd4daL,0x11b39ff7c88a193L,0x186a98d2ce5873cL,
  39940. 0x09f8bf03c6c8a1cL,0x167c0345de81556L,0x0b48261be9ae358L,0x032bd20b60670ceL,
  39941. 0x1f69971846636b4L,0x0132f5763e14ac7L
  39942. };
  39943. #endif
  39944. /* The base point of curve P1024. */
  39945. static const sp_point_1024 p1024_base = {
  39946. /* X ordinate */
  39947. {
  39948. 0x00dc8abeae63895L,0x023624b3f04bcc4L,0x0e96d8fdcfb203bL,
  39949. 0x1900e51b0fdd22cL,0x1a66910dd5cfb4cL,0x106f3a53e0a8a6dL,
  39950. 0x1cb869c0b0ce5e9L,0x19666f90ca916e5L,0x09760af765dd5bcL,
  39951. 0x0c5ecf3a0367448L,0x17c8b36e77e955cL,0x172061613c2087aL,
  39952. 0x00f6ce2308ab10dL,0x1b7fbe5fdaf6db6L,0x1b1a71a62cbc812L,
  39953. 0x16a5456345fac15L,0x1ad0a7990053ed9L,0x029fe04f7199614L,
  39954. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  39955. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  39956. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  39957. (sp_digit)0, (sp_digit)0, (sp_digit)0
  39958. },
  39959. /* Y ordinate */
  39960. {
  39961. 0x1573fd71bef16d7L,0x0dab83533ee6f3aL,0x156b56ed18dab6eL,
  39962. 0x0fd3973353017b5L,0x05a4d5f213515adL,0x0554c4a496cbcfeL,
  39963. 0x0bf82b1bc7a0059L,0x0d995ad2d6b6ecaL,0x170dae117ad547cL,
  39964. 0x0b67f8654f0195cL,0x06333e68502cb90L,0x0bcbe1bcabecd6bL,
  39965. 0x14654ec2b9e7f7fL,0x0f0a08bc7af534fL,0x0641a58f5de3608L,
  39966. 0x1426ba7d0402c05L,0x1f1f9f1f0533634L,0x0054124831fb004L,
  39967. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  39968. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  39969. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  39970. (sp_digit)0, (sp_digit)0, (sp_digit)0
  39971. },
  39972. /* Z ordinate */
  39973. {
  39974. 0x000000000000001L,0x000000000000000L,0x000000000000000L,
  39975. 0x000000000000000L,0x000000000000000L,0x000000000000000L,
  39976. 0x000000000000000L,0x000000000000000L,0x000000000000000L,
  39977. 0x000000000000000L,0x000000000000000L,0x000000000000000L,
  39978. 0x000000000000000L,0x000000000000000L,0x000000000000000L,
  39979. 0x000000000000000L,0x000000000000000L,0x000000000000000L,
  39980. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  39981. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  39982. (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
  39983. (sp_digit)0, (sp_digit)0, (sp_digit)0
  39984. },
  39985. /* infinity */
  39986. 0
  39987. };
  39988. /* Normalize the values in each word to 57 bits.
  39989. *
  39990. * a Array of sp_digit to normalize.
  39991. */
  39992. static void sp_1024_norm_18(sp_digit* a)
  39993. {
  39994. #ifdef WOLFSSL_SP_SMALL
  39995. int i;
  39996. for (i = 0; i < 17; i++) {
  39997. a[i+1] += a[i] >> 57;
  39998. a[i] &= 0x1ffffffffffffffL;
  39999. }
  40000. #else
  40001. int i;
  40002. for (i = 0; i < 16; i += 8) {
  40003. a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL;
  40004. a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL;
  40005. a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL;
  40006. a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL;
  40007. a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL;
  40008. a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL;
  40009. a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL;
  40010. a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL;
  40011. }
  40012. a[17] += a[16] >> 57; a[16] &= 0x1ffffffffffffffL;
  40013. #endif /* WOLFSSL_SP_SMALL */
  40014. }
  40015. /* Multiply a by scalar b into r. (r = a * b)
  40016. *
  40017. * r A single precision integer.
  40018. * a A single precision integer.
  40019. * b A scalar.
  40020. */
  40021. SP_NOINLINE static void sp_1024_mul_d_18(sp_digit* r, const sp_digit* a,
  40022. sp_digit b)
  40023. {
  40024. #ifdef WOLFSSL_SP_SMALL
  40025. sp_int128 tb = b;
  40026. sp_int128 t = 0;
  40027. int i;
  40028. for (i = 0; i < 18; i++) {
  40029. t += tb * a[i];
  40030. r[i] = (sp_digit)(t & 0x1ffffffffffffffL);
  40031. t >>= 57;
  40032. }
  40033. r[18] = (sp_digit)t;
  40034. #else
  40035. sp_int128 tb = b;
  40036. sp_int128 t = 0;
  40037. sp_digit t2;
  40038. sp_int128 p[4];
  40039. int i;
  40040. for (i = 0; i < 16; i += 4) {
  40041. p[0] = tb * a[i + 0];
  40042. p[1] = tb * a[i + 1];
  40043. p[2] = tb * a[i + 2];
  40044. p[3] = tb * a[i + 3];
  40045. t += p[0];
  40046. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  40047. t >>= 57;
  40048. r[i + 0] = (sp_digit)t2;
  40049. t += p[1];
  40050. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  40051. t >>= 57;
  40052. r[i + 1] = (sp_digit)t2;
  40053. t += p[2];
  40054. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  40055. t >>= 57;
  40056. r[i + 2] = (sp_digit)t2;
  40057. t += p[3];
  40058. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  40059. t >>= 57;
  40060. r[i + 3] = (sp_digit)t2;
  40061. }
  40062. t += tb * a[16];
  40063. r[16] = (sp_digit)(t & 0x1ffffffffffffffL);
  40064. t >>= 57;
  40065. t += tb * a[17];
  40066. r[17] = (sp_digit)(t & 0x1ffffffffffffffL);
  40067. t >>= 57;
  40068. r[18] = (sp_digit)(t & 0x1ffffffffffffffL);
  40069. #endif /* WOLFSSL_SP_SMALL */
  40070. }
  40071. /* Multiply a by scalar b into r. (r = a * b)
  40072. *
  40073. * r A single precision integer.
  40074. * a A single precision integer.
  40075. * b A scalar.
  40076. */
  40077. SP_NOINLINE static void sp_1024_mul_d_36(sp_digit* r, const sp_digit* a,
  40078. sp_digit b)
  40079. {
  40080. #ifdef WOLFSSL_SP_SMALL
  40081. sp_int128 tb = b;
  40082. sp_int128 t = 0;
  40083. int i;
  40084. for (i = 0; i < 36; i++) {
  40085. t += tb * a[i];
  40086. r[i] = (sp_digit)(t & 0x1ffffffffffffffL);
  40087. t >>= 57;
  40088. }
  40089. r[36] = (sp_digit)t;
  40090. #else
  40091. sp_int128 tb = b;
  40092. sp_int128 t = 0;
  40093. sp_digit t2;
  40094. sp_int128 p[4];
  40095. int i;
  40096. for (i = 0; i < 36; i += 4) {
  40097. p[0] = tb * a[i + 0];
  40098. p[1] = tb * a[i + 1];
  40099. p[2] = tb * a[i + 2];
  40100. p[3] = tb * a[i + 3];
  40101. t += p[0];
  40102. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  40103. t >>= 57;
  40104. r[i + 0] = (sp_digit)t2;
  40105. t += p[1];
  40106. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  40107. t >>= 57;
  40108. r[i + 1] = (sp_digit)t2;
  40109. t += p[2];
  40110. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  40111. t >>= 57;
  40112. r[i + 2] = (sp_digit)t2;
  40113. t += p[3];
  40114. t2 = (sp_digit)(t & 0x1ffffffffffffffL);
  40115. t >>= 57;
  40116. r[i + 3] = (sp_digit)t2;
  40117. }
  40118. r[36] = (sp_digit)(t & 0x1ffffffffffffffL);
  40119. #endif /* WOLFSSL_SP_SMALL */
  40120. }
  40121. #ifdef WOLFSSL_SP_SMALL
  40122. /* Conditionally add a and b using the mask m.
  40123. * m is -1 to add and 0 when not.
  40124. *
  40125. * r A single precision number representing conditional add result.
  40126. * a A single precision number to add with.
  40127. * b A single precision number to add.
  40128. * m Mask value to apply.
  40129. */
  40130. static void sp_1024_cond_add_18(sp_digit* r, const sp_digit* a,
  40131. const sp_digit* b, const sp_digit m)
  40132. {
  40133. int i;
  40134. for (i = 0; i < 18; i++) {
  40135. r[i] = a[i] + (b[i] & m);
  40136. }
  40137. }
  40138. #endif /* WOLFSSL_SP_SMALL */
  40139. #ifndef WOLFSSL_SP_SMALL
  40140. /* Conditionally add a and b using the mask m.
  40141. * m is -1 to add and 0 when not.
  40142. *
  40143. * r A single precision number representing conditional add result.
  40144. * a A single precision number to add with.
  40145. * b A single precision number to add.
  40146. * m Mask value to apply.
  40147. */
  40148. static void sp_1024_cond_add_18(sp_digit* r, const sp_digit* a,
  40149. const sp_digit* b, const sp_digit m)
  40150. {
  40151. int i;
  40152. for (i = 0; i < 16; i += 8) {
  40153. r[i + 0] = a[i + 0] + (b[i + 0] & m);
  40154. r[i + 1] = a[i + 1] + (b[i + 1] & m);
  40155. r[i + 2] = a[i + 2] + (b[i + 2] & m);
  40156. r[i + 3] = a[i + 3] + (b[i + 3] & m);
  40157. r[i + 4] = a[i + 4] + (b[i + 4] & m);
  40158. r[i + 5] = a[i + 5] + (b[i + 5] & m);
  40159. r[i + 6] = a[i + 6] + (b[i + 6] & m);
  40160. r[i + 7] = a[i + 7] + (b[i + 7] & m);
  40161. }
  40162. r[16] = a[16] + (b[16] & m);
  40163. r[17] = a[17] + (b[17] & m);
  40164. }
  40165. #endif /* !WOLFSSL_SP_SMALL */
  40166. #ifdef WOLFSSL_SP_SMALL
  40167. /* Sub b from a into r. (r = a - b)
  40168. *
  40169. * r A single precision integer.
  40170. * a A single precision integer.
  40171. * b A single precision integer.
  40172. */
  40173. SP_NOINLINE static int sp_1024_sub_18(sp_digit* r, const sp_digit* a,
  40174. const sp_digit* b)
  40175. {
  40176. int i;
  40177. for (i = 0; i < 18; i++) {
  40178. r[i] = a[i] - b[i];
  40179. }
  40180. return 0;
  40181. }
  40182. #endif
  40183. #ifdef WOLFSSL_SP_SMALL
  40184. /* Add b to a into r. (r = a + b)
  40185. *
  40186. * r A single precision integer.
  40187. * a A single precision integer.
  40188. * b A single precision integer.
  40189. */
  40190. SP_NOINLINE static int sp_1024_add_18(sp_digit* r, const sp_digit* a,
  40191. const sp_digit* b)
  40192. {
  40193. int i;
  40194. for (i = 0; i < 18; i++) {
  40195. r[i] = a[i] + b[i];
  40196. }
  40197. return 0;
  40198. }
  40199. #endif /* WOLFSSL_SP_SMALL */
  40200. SP_NOINLINE static void sp_1024_rshift_18(sp_digit* r, const sp_digit* a,
  40201. byte n)
  40202. {
  40203. int i;
  40204. #ifdef WOLFSSL_SP_SMALL
  40205. for (i=0; i<17; i++) {
  40206. r[i] = ((a[i] >> n) | (a[i + 1] << (57 - n))) & 0x1ffffffffffffffL;
  40207. }
  40208. #else
  40209. for (i=0; i<16; i += 8) {
  40210. r[i+0] = (a[i+0] >> n) | ((a[i+1] << (57 - n)) & 0x1ffffffffffffffL);
  40211. r[i+1] = (a[i+1] >> n) | ((a[i+2] << (57 - n)) & 0x1ffffffffffffffL);
  40212. r[i+2] = (a[i+2] >> n) | ((a[i+3] << (57 - n)) & 0x1ffffffffffffffL);
  40213. r[i+3] = (a[i+3] >> n) | ((a[i+4] << (57 - n)) & 0x1ffffffffffffffL);
  40214. r[i+4] = (a[i+4] >> n) | ((a[i+5] << (57 - n)) & 0x1ffffffffffffffL);
  40215. r[i+5] = (a[i+5] >> n) | ((a[i+6] << (57 - n)) & 0x1ffffffffffffffL);
  40216. r[i+6] = (a[i+6] >> n) | ((a[i+7] << (57 - n)) & 0x1ffffffffffffffL);
  40217. r[i+7] = (a[i+7] >> n) | ((a[i+8] << (57 - n)) & 0x1ffffffffffffffL);
  40218. }
  40219. r[16] = (a[16] >> n) | ((a[17] << (57 - n)) & 0x1ffffffffffffffL);
  40220. #endif /* WOLFSSL_SP_SMALL */
  40221. r[17] = a[17] >> n;
  40222. }
  40223. static WC_INLINE sp_digit sp_1024_div_word_18(sp_digit d1, sp_digit d0,
  40224. sp_digit div)
  40225. {
  40226. #ifdef SP_USE_DIVTI3
  40227. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  40228. return d / div;
  40229. #elif defined(__x86_64__) || defined(__i386__)
  40230. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  40231. sp_uint64 lo = (sp_uint64)d;
  40232. sp_digit hi = (sp_digit)(d >> 64);
  40233. __asm__ __volatile__ (
  40234. "idiv %2"
  40235. : "+a" (lo)
  40236. : "d" (hi), "r" (div)
  40237. : "cc"
  40238. );
  40239. return (sp_digit)lo;
  40240. #elif !defined(__aarch64__) && !defined(SP_DIV_WORD_USE_DIV)
  40241. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  40242. sp_digit dv = (div >> 1) + 1;
  40243. sp_digit t1 = (sp_digit)(d >> 57);
  40244. sp_digit t0 = (sp_digit)(d & 0x1ffffffffffffffL);
  40245. sp_digit t2;
  40246. sp_digit sign;
  40247. sp_digit r;
  40248. int i;
  40249. sp_int128 m;
  40250. r = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  40251. t1 -= dv & (0 - r);
  40252. for (i = 55; i >= 1; i--) {
  40253. t1 += t1 + (((sp_uint64)t0 >> 56) & 1);
  40254. t0 <<= 1;
  40255. t2 = (sp_digit)(((sp_uint64)(dv - t1)) >> 63);
  40256. r += r + t2;
  40257. t1 -= dv & (0 - t2);
  40258. t1 += t2;
  40259. }
  40260. r += r + 1;
  40261. m = d - ((sp_int128)r * div);
  40262. r += (sp_digit)(m >> 57);
  40263. m = d - ((sp_int128)r * div);
  40264. r += (sp_digit)(m >> 114) - (sp_digit)(d >> 114);
  40265. m = d - ((sp_int128)r * div);
  40266. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  40267. m *= sign;
  40268. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  40269. r += sign * t2;
  40270. m = d - ((sp_int128)r * div);
  40271. sign = (sp_digit)(0 - ((sp_uint64)m >> 63)) * 2 + 1;
  40272. m *= sign;
  40273. t2 = (sp_digit)(((sp_uint64)(div - m)) >> 63);
  40274. r += sign * t2;
  40275. return r;
  40276. #else
  40277. sp_int128 d = ((sp_int128)d1 << 57) + d0;
  40278. sp_digit r = 0;
  40279. sp_digit t;
  40280. sp_digit dv = (div >> 26) + 1;
  40281. t = (sp_digit)(d >> 52);
  40282. t = (t / dv) << 26;
  40283. r += t;
  40284. d -= (sp_int128)t * div;
  40285. t = (sp_digit)(d >> 21);
  40286. t = t / (dv << 5);
  40287. r += t;
  40288. d -= (sp_int128)t * div;
  40289. t = (sp_digit)d;
  40290. t = t / div;
  40291. r += t;
  40292. d -= (sp_int128)t * div;
  40293. return r;
  40294. #endif
  40295. }
  40296. static WC_INLINE sp_digit sp_1024_word_div_word_18(sp_digit d, sp_digit div)
  40297. {
  40298. #if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \
  40299. defined(SP_DIV_WORD_USE_DIV)
  40300. return d / div;
  40301. #else
  40302. return (sp_digit)((sp_uint64)(div - d) >> 63);
  40303. #endif
  40304. }
  40305. /* Divide d in a and put remainder into r (m*d + r = a)
  40306. * m is not calculated as it is not needed at this time.
  40307. *
  40308. * Full implementation.
  40309. *
  40310. * a Number to be divided.
  40311. * d Number to divide with.
  40312. * m Multiplier result.
  40313. * r Remainder from the division.
  40314. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  40315. */
  40316. static int sp_1024_div_18(const sp_digit* a, const sp_digit* d,
  40317. const sp_digit* m, sp_digit* r)
  40318. {
  40319. int i;
  40320. #ifndef WOLFSSL_SP_DIV_64
  40321. #endif
  40322. sp_digit dv;
  40323. sp_digit r1;
  40324. #ifdef WOLFSSL_SP_SMALL_STACK
  40325. sp_digit* t1 = NULL;
  40326. #else
  40327. sp_digit t1[4 * 18 + 3];
  40328. #endif
  40329. sp_digit* t2 = NULL;
  40330. sp_digit* sd = NULL;
  40331. int err = MP_OKAY;
  40332. (void)m;
  40333. #ifdef WOLFSSL_SP_SMALL_STACK
  40334. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 18 + 3), NULL,
  40335. DYNAMIC_TYPE_TMP_BUFFER);
  40336. if (t1 == NULL)
  40337. err = MEMORY_E;
  40338. #endif
  40339. (void)m;
  40340. if (err == MP_OKAY) {
  40341. t2 = t1 + 36 + 1;
  40342. sd = t2 + 18 + 1;
  40343. sp_1024_mul_d_18(sd, d, (sp_digit)1 << 2);
  40344. sp_1024_mul_d_36(t1, a, (sp_digit)1 << 2);
  40345. dv = sd[17];
  40346. t1[18 + 18] += t1[18 + 18 - 1] >> 57;
  40347. t1[18 + 18 - 1] &= 0x1ffffffffffffffL;
  40348. for (i=18; i>=0; i--) {
  40349. r1 = sp_1024_div_word_18(t1[18 + i], t1[18 + i - 1], dv);
  40350. sp_1024_mul_d_18(t2, sd, r1);
  40351. (void)sp_1024_sub_18(&t1[i], &t1[i], t2);
  40352. sp_1024_norm_18(&t1[i]);
  40353. t1[18 + i] -= t2[18];
  40354. t1[18 + i] += t1[18 + i - 1] >> 57;
  40355. t1[18 + i - 1] &= 0x1ffffffffffffffL;
  40356. r1 = sp_1024_div_word_18(-t1[18 + i], -t1[18 + i - 1], dv);
  40357. r1 -= t1[18 + i];
  40358. sp_1024_mul_d_18(t2, sd, r1);
  40359. (void)sp_1024_add_18(&t1[i], &t1[i], t2);
  40360. t1[18 + i] += t1[18 + i - 1] >> 57;
  40361. t1[18 + i - 1] &= 0x1ffffffffffffffL;
  40362. }
  40363. t1[18 - 1] += t1[18 - 2] >> 57;
  40364. t1[18 - 2] &= 0x1ffffffffffffffL;
  40365. r1 = sp_1024_word_div_word_18(t1[18 - 1], dv);
  40366. sp_1024_mul_d_18(t2, sd, r1);
  40367. sp_1024_sub_18(t1, t1, t2);
  40368. XMEMCPY(r, t1, sizeof(*r) * 36U);
  40369. for (i=0; i<17; i++) {
  40370. r[i+1] += r[i] >> 57;
  40371. r[i] &= 0x1ffffffffffffffL;
  40372. }
  40373. sp_1024_cond_add_18(r, r, sd, r[17] >> 63);
  40374. sp_1024_norm_18(r);
  40375. sp_1024_rshift_18(r, r, 2);
  40376. }
  40377. #ifdef WOLFSSL_SP_SMALL_STACK
  40378. if (t1 != NULL)
  40379. XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  40380. #endif
  40381. return err;
  40382. }
  40383. /* Reduce a modulo m into r. (r = a mod m)
  40384. *
  40385. * r A single precision number that is the reduced result.
  40386. * a A single precision number that is to be reduced.
  40387. * m A single precision number that is the modulus to reduce with.
  40388. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
  40389. */
  40390. static int sp_1024_mod_18(sp_digit* r, const sp_digit* a, const sp_digit* m)
  40391. {
  40392. return sp_1024_div_18(a, m, NULL, r);
  40393. }
  40394. /* Multiply a number by Montgomery normalizer mod modulus (prime).
  40395. *
  40396. * r The resulting Montgomery form number.
  40397. * a The number to convert.
  40398. * m The modulus (prime).
  40399. * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise.
  40400. */
  40401. static int sp_1024_mod_mul_norm_18(sp_digit* r, const sp_digit* a,
  40402. const sp_digit* m)
  40403. {
  40404. sp_1024_mul_18(r, a, p1024_norm_mod);
  40405. return sp_1024_mod_18(r, r, m);
  40406. }
  40407. #ifdef WOLFCRYPT_HAVE_SAKKE
  40408. /* Create a new point.
  40409. *
  40410. * heap [in] Buffer to allocate dynamic memory from.
  40411. * sp [in] Data for point - only if not allocating.
  40412. * p [out] New point.
  40413. * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise.
  40414. */
  40415. static int sp_1024_point_new_ex_18(void* heap, sp_point_1024* sp,
  40416. sp_point_1024** p)
  40417. {
  40418. int ret = MP_OKAY;
  40419. (void)heap;
  40420. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  40421. defined(WOLFSSL_SP_SMALL_STACK)
  40422. (void)sp;
  40423. *p = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap, DYNAMIC_TYPE_ECC);
  40424. #else
  40425. *p = sp;
  40426. #endif
  40427. if (*p == NULL) {
  40428. ret = MEMORY_E;
  40429. }
  40430. return ret;
  40431. }
  40432. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  40433. defined(WOLFSSL_SP_SMALL_STACK)
  40434. /* Allocate memory for point and return error. */
  40435. #define sp_1024_point_new_18(heap, sp, p) sp_1024_point_new_ex_18((heap), NULL, &(p))
  40436. #else
  40437. /* Set pointer to data and return no error. */
  40438. #define sp_1024_point_new_18(heap, sp, p) sp_1024_point_new_ex_18((heap), &(sp), &(p))
  40439. #endif
  40440. #endif /* WOLFCRYPT_HAVE_SAKKE */
  40441. #ifdef WOLFCRYPT_HAVE_SAKKE
  40442. /* Free the point.
  40443. *
  40444. * p [in,out] Point to free.
  40445. * clear [in] Indicates whether to zeroize point.
  40446. * heap [in] Buffer from which dynamic memory was allocate from.
  40447. */
  40448. static void sp_1024_point_free_18(sp_point_1024* p, int clear, void* heap)
  40449. {
  40450. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  40451. defined(WOLFSSL_SP_SMALL_STACK)
  40452. /* If valid pointer then clear point data if requested and free data. */
  40453. if (p != NULL) {
  40454. if (clear != 0) {
  40455. XMEMSET(p, 0, sizeof(*p));
  40456. }
  40457. XFREE(p, heap, DYNAMIC_TYPE_ECC);
  40458. }
  40459. #else
  40460. /* Clear point data if requested. */
  40461. if ((p != NULL) && (clear != 0)) {
  40462. XMEMSET(p, 0, sizeof(*p));
  40463. }
  40464. #endif
  40465. (void)heap;
  40466. }
  40467. #endif /* WOLFCRYPT_HAVE_SAKKE */
  40468. /* Convert an mp_int to an array of sp_digit.
  40469. *
  40470. * r A single precision integer.
  40471. * size Maximum number of bytes to convert
  40472. * a A multi-precision integer.
  40473. */
  40474. static void sp_1024_from_mp(sp_digit* r, int size, const mp_int* a)
  40475. {
  40476. #if DIGIT_BIT == 57
  40477. int i;
  40478. sp_digit j = (sp_digit)0 - (sp_digit)a->used;
  40479. int o = 0;
  40480. for (i = 0; i < size; i++) {
  40481. sp_digit mask = (sp_digit)0 - (j >> 56);
  40482. r[i] = a->dp[o] & mask;
  40483. j++;
  40484. o += (int)(j >> 56);
  40485. }
  40486. #elif DIGIT_BIT > 57
  40487. unsigned int i;
  40488. int j = 0;
  40489. word32 s = 0;
  40490. r[0] = 0;
  40491. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  40492. r[j] |= ((sp_digit)a->dp[i] << s);
  40493. r[j] &= 0x1ffffffffffffffL;
  40494. s = 57U - s;
  40495. if (j + 1 >= size) {
  40496. break;
  40497. }
  40498. /* lint allow cast of mismatch word32 and mp_digit */
  40499. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  40500. while ((s + 57U) <= (word32)DIGIT_BIT) {
  40501. s += 57U;
  40502. r[j] &= 0x1ffffffffffffffL;
  40503. if (j + 1 >= size) {
  40504. break;
  40505. }
  40506. if (s < (word32)DIGIT_BIT) {
  40507. /* lint allow cast of mismatch word32 and mp_digit */
  40508. r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
  40509. }
  40510. else {
  40511. r[++j] = (sp_digit)0;
  40512. }
  40513. }
  40514. s = (word32)DIGIT_BIT - s;
  40515. }
  40516. for (j++; j < size; j++) {
  40517. r[j] = 0;
  40518. }
  40519. #else
  40520. unsigned int i;
  40521. int j = 0;
  40522. int s = 0;
  40523. r[0] = 0;
  40524. for (i = 0; i < (unsigned int)a->used && j < size; i++) {
  40525. r[j] |= ((sp_digit)a->dp[i]) << s;
  40526. if (s + DIGIT_BIT >= 57) {
  40527. r[j] &= 0x1ffffffffffffffL;
  40528. if (j + 1 >= size) {
  40529. break;
  40530. }
  40531. s = 57 - s;
  40532. if (s == DIGIT_BIT) {
  40533. r[++j] = 0;
  40534. s = 0;
  40535. }
  40536. else {
  40537. r[++j] = a->dp[i] >> s;
  40538. s = DIGIT_BIT - s;
  40539. }
  40540. }
  40541. else {
  40542. s += DIGIT_BIT;
  40543. }
  40544. }
  40545. for (j++; j < size; j++) {
  40546. r[j] = 0;
  40547. }
  40548. #endif
  40549. }
  40550. /* Convert a point of type ecc_point to type sp_point_1024.
  40551. *
  40552. * p Point of type sp_point_1024 (result).
  40553. * pm Point of type ecc_point.
  40554. */
  40555. static void sp_1024_point_from_ecc_point_18(sp_point_1024* p,
  40556. const ecc_point* pm)
  40557. {
  40558. XMEMSET(p->x, 0, sizeof(p->x));
  40559. XMEMSET(p->y, 0, sizeof(p->y));
  40560. XMEMSET(p->z, 0, sizeof(p->z));
  40561. sp_1024_from_mp(p->x, 18, pm->x);
  40562. sp_1024_from_mp(p->y, 18, pm->y);
  40563. sp_1024_from_mp(p->z, 18, pm->z);
  40564. p->infinity = 0;
  40565. }
  40566. /* Convert an array of sp_digit to an mp_int.
  40567. *
  40568. * a A single precision integer.
  40569. * r A multi-precision integer.
  40570. */
  40571. static int sp_1024_to_mp(const sp_digit* a, mp_int* r)
  40572. {
  40573. int err;
  40574. err = mp_grow(r, (1024 + DIGIT_BIT - 1) / DIGIT_BIT);
  40575. if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
  40576. #if DIGIT_BIT == 57
  40577. XMEMCPY(r->dp, a, sizeof(sp_digit) * 18);
  40578. r->used = 18;
  40579. mp_clamp(r);
  40580. #elif DIGIT_BIT < 57
  40581. int i;
  40582. int j = 0;
  40583. int s = 0;
  40584. r->dp[0] = 0;
  40585. for (i = 0; i < 18; i++) {
  40586. r->dp[j] |= (mp_digit)(a[i] << s);
  40587. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  40588. s = DIGIT_BIT - s;
  40589. r->dp[++j] = (mp_digit)(a[i] >> s);
  40590. while (s + DIGIT_BIT <= 57) {
  40591. s += DIGIT_BIT;
  40592. r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  40593. if (s == SP_WORD_SIZE) {
  40594. r->dp[j] = 0;
  40595. }
  40596. else {
  40597. r->dp[j] = (mp_digit)(a[i] >> s);
  40598. }
  40599. }
  40600. s = 57 - s;
  40601. }
  40602. r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT;
  40603. mp_clamp(r);
  40604. #else
  40605. int i;
  40606. int j = 0;
  40607. int s = 0;
  40608. r->dp[0] = 0;
  40609. for (i = 0; i < 18; i++) {
  40610. r->dp[j] |= ((mp_digit)a[i]) << s;
  40611. if (s + 57 >= DIGIT_BIT) {
  40612. #if DIGIT_BIT != 32 && DIGIT_BIT != 64
  40613. r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
  40614. #endif
  40615. s = DIGIT_BIT - s;
  40616. r->dp[++j] = a[i] >> s;
  40617. s = 57 - s;
  40618. }
  40619. else {
  40620. s += 57;
  40621. }
  40622. }
  40623. r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT;
  40624. mp_clamp(r);
  40625. #endif
  40626. }
  40627. return err;
  40628. }
  40629. /* Convert a point of type sp_point_1024 to type ecc_point.
  40630. *
  40631. * p Point of type sp_point_1024.
  40632. * pm Point of type ecc_point (result).
  40633. * returns MEMORY_E when allocation of memory in ecc_point fails otherwise
  40634. * MP_OKAY.
  40635. */
  40636. static int sp_1024_point_to_ecc_point_18(const sp_point_1024* p, ecc_point* pm)
  40637. {
  40638. int err;
  40639. err = sp_1024_to_mp(p->x, pm->x);
  40640. if (err == MP_OKAY) {
  40641. err = sp_1024_to_mp(p->y, pm->y);
  40642. }
  40643. if (err == MP_OKAY) {
  40644. err = sp_1024_to_mp(p->z, pm->z);
  40645. }
  40646. return err;
  40647. }
  40648. /* Compare a with b in constant time.
  40649. *
  40650. * a A single precision integer.
  40651. * b A single precision integer.
  40652. * return -ve, 0 or +ve if a is less than, equal to or greater than b
  40653. * respectively.
  40654. */
  40655. static sp_digit sp_1024_cmp_18(const sp_digit* a, const sp_digit* b)
  40656. {
  40657. sp_digit r = 0;
  40658. #ifdef WOLFSSL_SP_SMALL
  40659. int i;
  40660. for (i=17; i>=0; i--) {
  40661. r |= (a[i] - b[i]) & ~(((sp_digit)0 - r) >> 56);
  40662. }
  40663. #else
  40664. int i;
  40665. r |= (a[17] - b[17]) & (0 - (sp_digit)1);
  40666. r |= (a[16] - b[16]) & ~(((sp_digit)0 - r) >> 56);
  40667. for (i = 8; i >= 0; i -= 8) {
  40668. r |= (a[i + 7] - b[i + 7]) & ~(((sp_digit)0 - r) >> 56);
  40669. r |= (a[i + 6] - b[i + 6]) & ~(((sp_digit)0 - r) >> 56);
  40670. r |= (a[i + 5] - b[i + 5]) & ~(((sp_digit)0 - r) >> 56);
  40671. r |= (a[i + 4] - b[i + 4]) & ~(((sp_digit)0 - r) >> 56);
  40672. r |= (a[i + 3] - b[i + 3]) & ~(((sp_digit)0 - r) >> 56);
  40673. r |= (a[i + 2] - b[i + 2]) & ~(((sp_digit)0 - r) >> 56);
  40674. r |= (a[i + 1] - b[i + 1]) & ~(((sp_digit)0 - r) >> 56);
  40675. r |= (a[i + 0] - b[i + 0]) & ~(((sp_digit)0 - r) >> 56);
  40676. }
  40677. #endif /* WOLFSSL_SP_SMALL */
  40678. return r;
  40679. }
  40680. /* Conditionally subtract b from a using the mask m.
  40681. * m is -1 to subtract and 0 when not.
  40682. *
  40683. * r A single precision number representing condition subtract result.
  40684. * a A single precision number to subtract from.
  40685. * b A single precision number to subtract.
  40686. * m Mask value to apply.
  40687. */
  40688. static void sp_1024_cond_sub_18(sp_digit* r, const sp_digit* a,
  40689. const sp_digit* b, const sp_digit m)
  40690. {
  40691. #ifdef WOLFSSL_SP_SMALL
  40692. int i;
  40693. for (i = 0; i < 18; i++) {
  40694. r[i] = a[i] - (b[i] & m);
  40695. }
  40696. #else
  40697. int i;
  40698. for (i = 0; i < 16; i += 8) {
  40699. r[i + 0] = a[i + 0] - (b[i + 0] & m);
  40700. r[i + 1] = a[i + 1] - (b[i + 1] & m);
  40701. r[i + 2] = a[i + 2] - (b[i + 2] & m);
  40702. r[i + 3] = a[i + 3] - (b[i + 3] & m);
  40703. r[i + 4] = a[i + 4] - (b[i + 4] & m);
  40704. r[i + 5] = a[i + 5] - (b[i + 5] & m);
  40705. r[i + 6] = a[i + 6] - (b[i + 6] & m);
  40706. r[i + 7] = a[i + 7] - (b[i + 7] & m);
  40707. }
  40708. r[16] = a[16] - (b[16] & m);
  40709. r[17] = a[17] - (b[17] & m);
  40710. #endif /* WOLFSSL_SP_SMALL */
  40711. }
  40712. /* Mul a by scalar b and add into r. (r += a * b)
  40713. *
  40714. * r A single precision integer.
  40715. * a A single precision integer.
  40716. * b A scalar.
  40717. */
  40718. SP_NOINLINE static void sp_1024_mul_add_18(sp_digit* r, const sp_digit* a,
  40719. const sp_digit b)
  40720. {
  40721. #ifdef WOLFSSL_SP_SMALL
  40722. sp_int128 tb = b;
  40723. sp_int128 t[4];
  40724. int i;
  40725. t[0] = 0;
  40726. for (i = 0; i < 16; i += 4) {
  40727. t[0] += (tb * a[i+0]) + r[i+0];
  40728. t[1] = (tb * a[i+1]) + r[i+1];
  40729. t[2] = (tb * a[i+2]) + r[i+2];
  40730. t[3] = (tb * a[i+3]) + r[i+3];
  40731. r[i+0] = t[0] & 0x1ffffffffffffffL;
  40732. t[1] += t[0] >> 57;
  40733. r[i+1] = t[1] & 0x1ffffffffffffffL;
  40734. t[2] += t[1] >> 57;
  40735. r[i+2] = t[2] & 0x1ffffffffffffffL;
  40736. t[3] += t[2] >> 57;
  40737. r[i+3] = t[3] & 0x1ffffffffffffffL;
  40738. t[0] = t[3] >> 57;
  40739. }
  40740. t[0] += (tb * a[16]) + r[16];
  40741. t[1] = (tb * a[17]) + r[17];
  40742. r[16] = t[0] & 0x1ffffffffffffffL;
  40743. t[1] += t[0] >> 57;
  40744. r[17] = t[1] & 0x1ffffffffffffffL;
  40745. r[18] += (sp_digit)(t[1] >> 57);
  40746. #else
  40747. sp_int128 tb = b;
  40748. sp_int128 t[8];
  40749. int i;
  40750. t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL);
  40751. for (i = 0; i < 16; i += 8) {
  40752. t[1] = tb * a[i+1];
  40753. r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
  40754. t[2] = tb * a[i+2];
  40755. r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
  40756. t[3] = tb * a[i+3];
  40757. r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));
  40758. t[4] = tb * a[i+4];
  40759. r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));
  40760. t[5] = tb * a[i+5];
  40761. r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));
  40762. t[6] = tb * a[i+6];
  40763. r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL));
  40764. t[7] = tb * a[i+7];
  40765. r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL));
  40766. t[0] = tb * a[i+8];
  40767. r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL));
  40768. }
  40769. t[1] = tb * a[17];
  40770. r[17] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
  40771. r[18] += (sp_digit)(t[1] >> 57);
  40772. #endif /* WOLFSSL_SP_SMALL */
  40773. }
  40774. /* Shift the result in the high 1024 bits down to the bottom.
  40775. *
  40776. * r A single precision number.
  40777. * a A single precision number.
  40778. */
  40779. static void sp_1024_mont_shift_18(sp_digit* r, const sp_digit* a)
  40780. {
  40781. #ifdef WOLFSSL_SP_SMALL
  40782. int i;
  40783. sp_uint64 n;
  40784. n = a[17] >> 55;
  40785. for (i = 0; i < 17; i++) {
  40786. n += (sp_uint64)a[18 + i] << 2;
  40787. r[i] = n & 0x1ffffffffffffffL;
  40788. n >>= 57;
  40789. }
  40790. n += (sp_uint64)a[35] << 2;
  40791. r[17] = n;
  40792. #else
  40793. sp_uint64 n;
  40794. int i;
  40795. n = (sp_uint64)a[17];
  40796. n = n >> 55U;
  40797. for (i = 0; i < 16; i += 8) {
  40798. n += (sp_uint64)a[i+18] << 2U; r[i+0] = n & 0x1ffffffffffffffUL; n >>= 57U;
  40799. n += (sp_uint64)a[i+19] << 2U; r[i+1] = n & 0x1ffffffffffffffUL; n >>= 57U;
  40800. n += (sp_uint64)a[i+20] << 2U; r[i+2] = n & 0x1ffffffffffffffUL; n >>= 57U;
  40801. n += (sp_uint64)a[i+21] << 2U; r[i+3] = n & 0x1ffffffffffffffUL; n >>= 57U;
  40802. n += (sp_uint64)a[i+22] << 2U; r[i+4] = n & 0x1ffffffffffffffUL; n >>= 57U;
  40803. n += (sp_uint64)a[i+23] << 2U; r[i+5] = n & 0x1ffffffffffffffUL; n >>= 57U;
  40804. n += (sp_uint64)a[i+24] << 2U; r[i+6] = n & 0x1ffffffffffffffUL; n >>= 57U;
  40805. n += (sp_uint64)a[i+25] << 2U; r[i+7] = n & 0x1ffffffffffffffUL; n >>= 57U;
  40806. }
  40807. n += (sp_uint64)a[34] << 2U; r[16] = n & 0x1ffffffffffffffUL; n >>= 57U;
  40808. n += (sp_uint64)a[35] << 2U; r[17] = n;
  40809. #endif /* WOLFSSL_SP_SMALL */
  40810. XMEMSET(&r[18], 0, sizeof(*r) * 18U);
  40811. }
  40812. /* Reduce the number back to 1024 bits using Montgomery reduction.
  40813. *
  40814. * a A single precision number to reduce in place.
  40815. * m The single precision number representing the modulus.
  40816. * mp The digit representing the negative inverse of m mod 2^n.
  40817. */
  40818. static void sp_1024_mont_reduce_18(sp_digit* a, const sp_digit* m, sp_digit mp)
  40819. {
  40820. int i;
  40821. sp_digit mu;
  40822. sp_digit over;
  40823. sp_1024_norm_18(a + 18);
  40824. if (mp != 1) {
  40825. for (i=0; i<17; i++) {
  40826. mu = (a[i] * mp) & 0x1ffffffffffffffL;
  40827. sp_1024_mul_add_18(a+i, m, mu);
  40828. a[i+1] += a[i] >> 57;
  40829. }
  40830. mu = (a[i] * mp) & 0x7fffffffffffffL;
  40831. sp_1024_mul_add_18(a+i, m, mu);
  40832. a[i+1] += a[i] >> 57;
  40833. a[i] &= 0x1ffffffffffffffL;
  40834. }
  40835. else {
  40836. for (i=0; i<17; i++) {
  40837. mu = a[i] & 0x1ffffffffffffffL;
  40838. sp_1024_mul_add_18(a+i, m, mu);
  40839. a[i+1] += a[i] >> 57;
  40840. }
  40841. mu = a[i] & 0x7fffffffffffffL;
  40842. sp_1024_mul_add_18(a+i, m, mu);
  40843. a[i+1] += a[i] >> 57;
  40844. a[i] &= 0x1ffffffffffffffL;
  40845. }
  40846. sp_1024_mont_shift_18(a, a);
  40847. over = a[17] - m[17];
  40848. sp_1024_cond_sub_18(a, a, m, ~((over - 1) >> 63));
  40849. sp_1024_norm_18(a);
  40850. }
  40851. /* Multiply two Montgomery form numbers mod the modulus (prime).
  40852. * (r = a * b mod m)
  40853. *
  40854. * r Result of multiplication.
  40855. * a First number to multiply in Montgomery form.
  40856. * b Second number to multiply in Montgomery form.
  40857. * m Modulus (prime).
  40858. * mp Montgomery multiplier.
  40859. */
  40860. SP_NOINLINE static void sp_1024_mont_mul_18(sp_digit* r, const sp_digit* a,
  40861. const sp_digit* b, const sp_digit* m, sp_digit mp)
  40862. {
  40863. sp_1024_mul_18(r, a, b);
  40864. sp_1024_mont_reduce_18(r, m, mp);
  40865. }
  40866. /* Square the Montgomery form number. (r = a * a mod m)
  40867. *
  40868. * r Result of squaring.
  40869. * a Number to square in Montgomery form.
  40870. * m Modulus (prime).
  40871. * mp Montgomery multiplier.
  40872. */
  40873. SP_NOINLINE static void sp_1024_mont_sqr_18(sp_digit* r, const sp_digit* a,
  40874. const sp_digit* m, sp_digit mp)
  40875. {
  40876. sp_1024_sqr_18(r, a);
  40877. sp_1024_mont_reduce_18(r, m, mp);
  40878. }
  40879. /* Mod-2 for the P1024 curve. */
  40880. static const uint8_t p1024_mod_minus_2[] = {
  40881. 6,0x06, 7,0x0f, 7,0x0b, 6,0x0c, 7,0x1e, 9,0x09, 7,0x0c, 7,0x1f,
  40882. 6,0x16, 6,0x06, 7,0x0e, 8,0x10, 6,0x03, 8,0x11, 6,0x0d, 7,0x14,
  40883. 9,0x12, 6,0x0f, 7,0x04, 9,0x0d, 6,0x00, 7,0x13, 6,0x01, 6,0x07,
  40884. 8,0x0d, 8,0x00, 6,0x06, 9,0x17, 6,0x14, 6,0x15, 6,0x11, 6,0x0b,
  40885. 9,0x0c, 6,0x1e, 13,0x14, 7,0x0e, 6,0x1d, 12,0x0a, 6,0x0b, 8,0x07,
  40886. 6,0x18, 6,0x0f, 6,0x10, 8,0x1c, 7,0x16, 7,0x02, 6,0x01, 6,0x13,
  40887. 10,0x15, 7,0x06, 8,0x14, 6,0x0c, 6,0x19, 7,0x10, 6,0x19, 6,0x19,
  40888. 9,0x16, 7,0x19, 6,0x1f, 6,0x17, 6,0x12, 8,0x02, 6,0x01, 6,0x04,
  40889. 6,0x15, 7,0x16, 6,0x04, 6,0x1f, 6,0x09, 7,0x06, 7,0x13, 7,0x09,
  40890. 6,0x0d, 10,0x18, 6,0x06, 6,0x11, 6,0x04, 6,0x01, 6,0x13, 8,0x06,
  40891. 6,0x0d, 8,0x13, 7,0x08, 6,0x08, 6,0x05, 7,0x0c, 7,0x0e, 7,0x15,
  40892. 6,0x05, 7,0x14, 10,0x19, 6,0x10, 6,0x16, 6,0x15, 7,0x1f, 6,0x14,
  40893. 6,0x0a, 10,0x11, 6,0x01, 7,0x05, 7,0x08, 8,0x0a, 7,0x1e, 7,0x1c,
  40894. 6,0x1c, 7,0x09, 10,0x18, 7,0x1c, 10,0x06, 6,0x0a, 6,0x07, 6,0x19,
  40895. 7,0x06, 6,0x0d, 7,0x0f, 7,0x0b, 7,0x05, 6,0x11, 6,0x1c, 7,0x1f,
  40896. 6,0x1e, 7,0x18, 6,0x1e, 6,0x00, 6,0x03, 6,0x02, 7,0x10, 6,0x0b,
  40897. 6,0x1b, 7,0x10, 6,0x00, 8,0x11, 7,0x1b, 6,0x18, 6,0x01, 7,0x0c,
  40898. 7,0x1d, 7,0x13, 6,0x08, 7,0x1b, 8,0x13, 7,0x16, 13,0x1d, 7,0x1f,
  40899. 6,0x0a, 6,0x01, 7,0x1f, 6,0x14, 1,0x01
  40900. };
  40901. /* Invert the number, in Montgomery form, modulo the modulus (prime) of the
  40902. * P1024 curve. (r = 1 / a mod m)
  40903. *
  40904. * r Inverse result.
  40905. * a Number to invert.
  40906. * td Temporary data.
  40907. */
  40908. static void sp_1024_mont_inv_18(sp_digit* r, const sp_digit* a,
  40909. sp_digit* td)
  40910. {
  40911. sp_digit* t = &td[32 * 2 * 18];
  40912. int i;
  40913. int j;
  40914. sp_digit* table[32];
  40915. for (i = 0; i < 32; i++) {
  40916. table[i] = &td[2 * 18 * i];
  40917. }
  40918. XMEMCPY(table[0], a, sizeof(sp_digit) * 18);
  40919. for (i = 1; i < 6; i++) {
  40920. sp_1024_mont_sqr_18(table[0], table[0], p1024_mod, p1024_mp_mod);
  40921. }
  40922. for (i = 1; i < 32; i++) {
  40923. sp_1024_mont_mul_18(table[i], table[i-1], a, p1024_mod, p1024_mp_mod);
  40924. }
  40925. XMEMCPY(t, table[p1024_mod_minus_2[1]], sizeof(sp_digit) * 18);
  40926. for (i = 2; i < (int)sizeof(p1024_mod_minus_2) - 2; i += 2) {
  40927. for (j = 0; j < p1024_mod_minus_2[i]; j++) {
  40928. sp_1024_mont_sqr_18(t, t, p1024_mod, p1024_mp_mod);
  40929. }
  40930. sp_1024_mont_mul_18(t, t, table[p1024_mod_minus_2[i+1]], p1024_mod,
  40931. p1024_mp_mod);
  40932. }
  40933. sp_1024_mont_sqr_18(t, t, p1024_mod, p1024_mp_mod);
  40934. sp_1024_mont_mul_18(r, t, a, p1024_mod, p1024_mp_mod);
  40935. }
  40936. /* Map the Montgomery form projective coordinate point to an affine point.
  40937. *
  40938. * r Resulting affine coordinate point.
  40939. * p Montgomery form projective coordinate point.
  40940. * t Temporary ordinate data.
  40941. */
  40942. static void sp_1024_map_18(sp_point_1024* r, const sp_point_1024* p,
  40943. sp_digit* t)
  40944. {
  40945. sp_digit* t1 = t;
  40946. sp_digit* t2 = t + 2*18;
  40947. sp_int64 n;
  40948. sp_1024_mont_inv_18(t1, p->z, t + 2*18);
  40949. sp_1024_mont_sqr_18(t2, t1, p1024_mod, p1024_mp_mod);
  40950. sp_1024_mont_mul_18(t1, t2, t1, p1024_mod, p1024_mp_mod);
  40951. /* x /= z^2 */
  40952. sp_1024_mont_mul_18(r->x, p->x, t2, p1024_mod, p1024_mp_mod);
  40953. XMEMSET(r->x + 18, 0, sizeof(sp_digit) * 18U);
  40954. sp_1024_mont_reduce_18(r->x, p1024_mod, p1024_mp_mod);
  40955. /* Reduce x to less than modulus */
  40956. n = sp_1024_cmp_18(r->x, p1024_mod);
  40957. sp_1024_cond_sub_18(r->x, r->x, p1024_mod, ~(n >> 56));
  40958. sp_1024_norm_18(r->x);
  40959. /* y /= z^3 */
  40960. sp_1024_mont_mul_18(r->y, p->y, t1, p1024_mod, p1024_mp_mod);
  40961. XMEMSET(r->y + 18, 0, sizeof(sp_digit) * 18U);
  40962. sp_1024_mont_reduce_18(r->y, p1024_mod, p1024_mp_mod);
  40963. /* Reduce y to less than modulus */
  40964. n = sp_1024_cmp_18(r->y, p1024_mod);
  40965. sp_1024_cond_sub_18(r->y, r->y, p1024_mod, ~(n >> 56));
  40966. sp_1024_norm_18(r->y);
  40967. XMEMSET(r->z, 0, sizeof(r->z) / 2);
  40968. r->z[0] = 1;
  40969. }
  40970. /* Add two Montgomery form numbers (r = a + b % m).
  40971. *
  40972. * r Result of addition.
  40973. * a First number to add in Montgomery form.
  40974. * b Second number to add in Montgomery form.
  40975. * m Modulus (prime).
  40976. */
  40977. static void sp_1024_mont_add_18(sp_digit* r, const sp_digit* a, const sp_digit* b,
  40978. const sp_digit* m)
  40979. {
  40980. sp_digit over;
  40981. (void)sp_1024_add_18(r, a, b);
  40982. sp_1024_norm_18(r);
  40983. over = r[17] - m[17];
  40984. sp_1024_cond_sub_18(r, r, m, ~((over - 1) >> 63));
  40985. sp_1024_norm_18(r);
  40986. }
  40987. /* Double a Montgomery form number (r = a + a % m).
  40988. *
  40989. * r Result of doubling.
  40990. * a Number to double in Montgomery form.
  40991. * m Modulus (prime).
  40992. */
  40993. static void sp_1024_mont_dbl_18(sp_digit* r, const sp_digit* a, const sp_digit* m)
  40994. {
  40995. sp_digit over;
  40996. (void)sp_1024_add_18(r, a, a);
  40997. sp_1024_norm_18(r);
  40998. over = r[17] - m[17];
  40999. sp_1024_cond_sub_18(r, r, m, ~((over - 1) >> 63));
  41000. sp_1024_norm_18(r);
  41001. }
  41002. /* Triple a Montgomery form number (r = a + a + a % m).
  41003. *
  41004. * r Result of Tripling.
  41005. * a Number to triple in Montgomery form.
  41006. * m Modulus (prime).
  41007. */
  41008. static void sp_1024_mont_tpl_18(sp_digit* r, const sp_digit* a, const sp_digit* m)
  41009. {
  41010. sp_digit over;
  41011. (void)sp_1024_add_18(r, a, a);
  41012. sp_1024_norm_18(r);
  41013. over = r[17] - m[17];
  41014. sp_1024_cond_sub_18(r, r, m, ~((over - 1) >> 63));
  41015. sp_1024_norm_18(r);
  41016. (void)sp_1024_add_18(r, r, a);
  41017. sp_1024_norm_18(r);
  41018. over = r[17] - m[17];
  41019. sp_1024_cond_sub_18(r, r, m, ~((over - 1) >> 63));
  41020. sp_1024_norm_18(r);
  41021. }
  41022. /* Subtract two Montgomery form numbers (r = a - b % m).
  41023. *
  41024. * r Result of subtration.
  41025. * a Number to subtract from in Montgomery form.
  41026. * b Number to subtract with in Montgomery form.
  41027. * m Modulus (prime).
  41028. */
  41029. static void sp_1024_mont_sub_18(sp_digit* r, const sp_digit* a, const sp_digit* b,
  41030. const sp_digit* m)
  41031. {
  41032. (void)sp_1024_sub_18(r, a, b);
  41033. sp_1024_norm_18(r);
  41034. sp_1024_cond_add_18(r, r, m, r[17] >> 55);
  41035. sp_1024_norm_18(r);
  41036. }
  41037. /* Shift number left one bit.
  41038. * Bottom bit is lost.
  41039. *
  41040. * r Result of shift.
  41041. * a Number to shift.
  41042. */
  41043. SP_NOINLINE static void sp_1024_rshift1_18(sp_digit* r, const sp_digit* a)
  41044. {
  41045. #ifdef WOLFSSL_SP_SMALL
  41046. int i;
  41047. for (i=0; i<17; i++) {
  41048. r[i] = (a[i] >> 1) + ((a[i + 1] << 56) & 0x1ffffffffffffffL);
  41049. }
  41050. #else
  41051. r[0] = (a[0] >> 1) + ((a[1] << 56) & 0x1ffffffffffffffL);
  41052. r[1] = (a[1] >> 1) + ((a[2] << 56) & 0x1ffffffffffffffL);
  41053. r[2] = (a[2] >> 1) + ((a[3] << 56) & 0x1ffffffffffffffL);
  41054. r[3] = (a[3] >> 1) + ((a[4] << 56) & 0x1ffffffffffffffL);
  41055. r[4] = (a[4] >> 1) + ((a[5] << 56) & 0x1ffffffffffffffL);
  41056. r[5] = (a[5] >> 1) + ((a[6] << 56) & 0x1ffffffffffffffL);
  41057. r[6] = (a[6] >> 1) + ((a[7] << 56) & 0x1ffffffffffffffL);
  41058. r[7] = (a[7] >> 1) + ((a[8] << 56) & 0x1ffffffffffffffL);
  41059. r[8] = (a[8] >> 1) + ((a[9] << 56) & 0x1ffffffffffffffL);
  41060. r[9] = (a[9] >> 1) + ((a[10] << 56) & 0x1ffffffffffffffL);
  41061. r[10] = (a[10] >> 1) + ((a[11] << 56) & 0x1ffffffffffffffL);
  41062. r[11] = (a[11] >> 1) + ((a[12] << 56) & 0x1ffffffffffffffL);
  41063. r[12] = (a[12] >> 1) + ((a[13] << 56) & 0x1ffffffffffffffL);
  41064. r[13] = (a[13] >> 1) + ((a[14] << 56) & 0x1ffffffffffffffL);
  41065. r[14] = (a[14] >> 1) + ((a[15] << 56) & 0x1ffffffffffffffL);
  41066. r[15] = (a[15] >> 1) + ((a[16] << 56) & 0x1ffffffffffffffL);
  41067. r[16] = (a[16] >> 1) + ((a[17] << 56) & 0x1ffffffffffffffL);
  41068. #endif
  41069. r[17] = a[17] >> 1;
  41070. }
  41071. /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)
  41072. *
  41073. * r Result of division by 2.
  41074. * a Number to divide.
  41075. * m Modulus (prime).
  41076. */
  41077. static void sp_1024_mont_div2_18(sp_digit* r, const sp_digit* a,
  41078. const sp_digit* m)
  41079. {
  41080. sp_1024_cond_add_18(r, a, m, 0 - (a[0] & 1));
  41081. sp_1024_norm_18(r);
  41082. sp_1024_rshift1_18(r, r);
  41083. }
  41084. /* Double the Montgomery form projective point p.
  41085. *
  41086. * r Result of doubling point.
  41087. * p Point to double.
  41088. * t Temporary ordinate data.
  41089. */
  41090. static void sp_1024_proj_point_dbl_18(sp_point_1024* r, const sp_point_1024* p,
  41091. sp_digit* t)
  41092. {
  41093. sp_digit* t1 = t;
  41094. sp_digit* t2 = t + 2*18;
  41095. sp_digit* x;
  41096. sp_digit* y;
  41097. sp_digit* z;
  41098. x = r->x;
  41099. y = r->y;
  41100. z = r->z;
  41101. /* Put infinity into result. */
  41102. if (r != p) {
  41103. r->infinity = p->infinity;
  41104. }
  41105. /* T1 = Z * Z */
  41106. sp_1024_mont_sqr_18(t1, p->z, p1024_mod, p1024_mp_mod);
  41107. /* Z = Y * Z */
  41108. sp_1024_mont_mul_18(z, p->y, p->z, p1024_mod, p1024_mp_mod);
  41109. /* Z = 2Z */
  41110. sp_1024_mont_dbl_18(z, z, p1024_mod);
  41111. /* T2 = X - T1 */
  41112. sp_1024_mont_sub_18(t2, p->x, t1, p1024_mod);
  41113. /* T1 = X + T1 */
  41114. sp_1024_mont_add_18(t1, p->x, t1, p1024_mod);
  41115. /* T2 = T1 * T2 */
  41116. sp_1024_mont_mul_18(t2, t1, t2, p1024_mod, p1024_mp_mod);
  41117. /* T1 = 3T2 */
  41118. sp_1024_mont_tpl_18(t1, t2, p1024_mod);
  41119. /* Y = 2Y */
  41120. sp_1024_mont_dbl_18(y, p->y, p1024_mod);
  41121. /* Y = Y * Y */
  41122. sp_1024_mont_sqr_18(y, y, p1024_mod, p1024_mp_mod);
  41123. /* T2 = Y * Y */
  41124. sp_1024_mont_sqr_18(t2, y, p1024_mod, p1024_mp_mod);
  41125. /* T2 = T2/2 */
  41126. sp_1024_mont_div2_18(t2, t2, p1024_mod);
  41127. /* Y = Y * X */
  41128. sp_1024_mont_mul_18(y, y, p->x, p1024_mod, p1024_mp_mod);
  41129. /* X = T1 * T1 */
  41130. sp_1024_mont_sqr_18(x, t1, p1024_mod, p1024_mp_mod);
  41131. /* X = X - Y */
  41132. sp_1024_mont_sub_18(x, x, y, p1024_mod);
  41133. /* X = X - Y */
  41134. sp_1024_mont_sub_18(x, x, y, p1024_mod);
  41135. /* Y = Y - X */
  41136. sp_1024_mont_sub_18(y, y, x, p1024_mod);
  41137. /* Y = Y * T1 */
  41138. sp_1024_mont_mul_18(y, y, t1, p1024_mod, p1024_mp_mod);
  41139. /* Y = Y - T2 */
  41140. sp_1024_mont_sub_18(y, y, t2, p1024_mod);
  41141. }
  41142. #ifdef WOLFSSL_SP_NONBLOCK
  41143. typedef struct sp_1024_proj_point_dbl_18_ctx {
  41144. int state;
  41145. sp_digit* t1;
  41146. sp_digit* t2;
  41147. sp_digit* x;
  41148. sp_digit* y;
  41149. sp_digit* z;
  41150. } sp_1024_proj_point_dbl_18_ctx;
  41151. /* Double the Montgomery form projective point p.
  41152. *
  41153. * r Result of doubling point.
  41154. * p Point to double.
  41155. * t Temporary ordinate data.
  41156. */
  41157. static int sp_1024_proj_point_dbl_18_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
  41158. const sp_point_1024* p, sp_digit* t)
  41159. {
  41160. int err = FP_WOULDBLOCK;
  41161. sp_1024_proj_point_dbl_18_ctx* ctx = (sp_1024_proj_point_dbl_18_ctx*)sp_ctx->data;
  41162. typedef char ctx_size_test[sizeof(sp_1024_proj_point_dbl_18_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  41163. (void)sizeof(ctx_size_test);
  41164. switch (ctx->state) {
  41165. case 0:
  41166. ctx->t1 = t;
  41167. ctx->t2 = t + 2*18;
  41168. ctx->x = r->x;
  41169. ctx->y = r->y;
  41170. ctx->z = r->z;
  41171. /* Put infinity into result. */
  41172. if (r != p) {
  41173. r->infinity = p->infinity;
  41174. }
  41175. ctx->state = 1;
  41176. break;
  41177. case 1:
  41178. /* T1 = Z * Z */
  41179. sp_1024_mont_sqr_18(ctx->t1, p->z, p1024_mod, p1024_mp_mod);
  41180. ctx->state = 2;
  41181. break;
  41182. case 2:
  41183. /* Z = Y * Z */
  41184. sp_1024_mont_mul_18(ctx->z, p->y, p->z, p1024_mod, p1024_mp_mod);
  41185. ctx->state = 3;
  41186. break;
  41187. case 3:
  41188. /* Z = 2Z */
  41189. sp_1024_mont_dbl_18(ctx->z, ctx->z, p1024_mod);
  41190. ctx->state = 4;
  41191. break;
  41192. case 4:
  41193. /* T2 = X - T1 */
  41194. sp_1024_mont_sub_18(ctx->t2, p->x, ctx->t1, p1024_mod);
  41195. ctx->state = 5;
  41196. break;
  41197. case 5:
  41198. /* T1 = X + T1 */
  41199. sp_1024_mont_add_18(ctx->t1, p->x, ctx->t1, p1024_mod);
  41200. ctx->state = 6;
  41201. break;
  41202. case 6:
  41203. /* T2 = T1 * T2 */
  41204. sp_1024_mont_mul_18(ctx->t2, ctx->t1, ctx->t2, p1024_mod, p1024_mp_mod);
  41205. ctx->state = 7;
  41206. break;
  41207. case 7:
  41208. /* T1 = 3T2 */
  41209. sp_1024_mont_tpl_18(ctx->t1, ctx->t2, p1024_mod);
  41210. ctx->state = 8;
  41211. break;
  41212. case 8:
  41213. /* Y = 2Y */
  41214. sp_1024_mont_dbl_18(ctx->y, p->y, p1024_mod);
  41215. ctx->state = 9;
  41216. break;
  41217. case 9:
  41218. /* Y = Y * Y */
  41219. sp_1024_mont_sqr_18(ctx->y, ctx->y, p1024_mod, p1024_mp_mod);
  41220. ctx->state = 10;
  41221. break;
  41222. case 10:
  41223. /* T2 = Y * Y */
  41224. sp_1024_mont_sqr_18(ctx->t2, ctx->y, p1024_mod, p1024_mp_mod);
  41225. ctx->state = 11;
  41226. break;
  41227. case 11:
  41228. /* T2 = T2/2 */
  41229. sp_1024_mont_div2_18(ctx->t2, ctx->t2, p1024_mod);
  41230. ctx->state = 12;
  41231. break;
  41232. case 12:
  41233. /* Y = Y * X */
  41234. sp_1024_mont_mul_18(ctx->y, ctx->y, p->x, p1024_mod, p1024_mp_mod);
  41235. ctx->state = 13;
  41236. break;
  41237. case 13:
  41238. /* X = T1 * T1 */
  41239. sp_1024_mont_sqr_18(ctx->x, ctx->t1, p1024_mod, p1024_mp_mod);
  41240. ctx->state = 14;
  41241. break;
  41242. case 14:
  41243. /* X = X - Y */
  41244. sp_1024_mont_sub_18(ctx->x, ctx->x, ctx->y, p1024_mod);
  41245. ctx->state = 15;
  41246. break;
  41247. case 15:
  41248. /* X = X - Y */
  41249. sp_1024_mont_sub_18(ctx->x, ctx->x, ctx->y, p1024_mod);
  41250. ctx->state = 16;
  41251. break;
  41252. case 16:
  41253. /* Y = Y - X */
  41254. sp_1024_mont_sub_18(ctx->y, ctx->y, ctx->x, p1024_mod);
  41255. ctx->state = 17;
  41256. break;
  41257. case 17:
  41258. /* Y = Y * T1 */
  41259. sp_1024_mont_mul_18(ctx->y, ctx->y, ctx->t1, p1024_mod, p1024_mp_mod);
  41260. ctx->state = 18;
  41261. break;
  41262. case 18:
  41263. /* Y = Y - T2 */
  41264. sp_1024_mont_sub_18(ctx->y, ctx->y, ctx->t2, p1024_mod);
  41265. ctx->state = 19;
  41266. /* fall-through */
  41267. case 19:
  41268. err = MP_OKAY;
  41269. break;
  41270. }
  41271. if (err == MP_OKAY && ctx->state != 19) {
  41272. err = FP_WOULDBLOCK;
  41273. }
  41274. return err;
  41275. }
  41276. #endif /* WOLFSSL_SP_NONBLOCK */
  41277. /* Compare two numbers to determine if they are equal.
  41278. * Constant time implementation.
  41279. *
  41280. * a First number to compare.
  41281. * b Second number to compare.
  41282. * returns 1 when equal and 0 otherwise.
  41283. */
  41284. static int sp_1024_cmp_equal_18(const sp_digit* a, const sp_digit* b)
  41285. {
  41286. return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) |
  41287. (a[3] ^ b[3]) | (a[4] ^ b[4]) | (a[5] ^ b[5]) |
  41288. (a[6] ^ b[6]) | (a[7] ^ b[7]) | (a[8] ^ b[8]) |
  41289. (a[9] ^ b[9]) | (a[10] ^ b[10]) | (a[11] ^ b[11]) |
  41290. (a[12] ^ b[12]) | (a[13] ^ b[13]) | (a[14] ^ b[14]) |
  41291. (a[15] ^ b[15]) | (a[16] ^ b[16]) | (a[17] ^ b[17])) == 0;
  41292. }
  41293. /* Returns 1 if the number of zero.
  41294. * Implementation is constant time.
  41295. *
  41296. * a Number to check.
  41297. * returns 1 if the number is zero and 0 otherwise.
  41298. */
  41299. static int sp_1024_iszero_18(const sp_digit* a)
  41300. {
  41301. return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] |
  41302. a[8] | a[9] | a[10] | a[11] | a[12] | a[13] | a[14] | a[15] |
  41303. a[16] | a[17]) == 0;
  41304. }
  41305. /* Add two Montgomery form projective points.
  41306. *
  41307. * r Result of addition.
  41308. * p First point to add.
  41309. * q Second point to add.
  41310. * t Temporary ordinate data.
  41311. */
  41312. static void sp_1024_proj_point_add_18(sp_point_1024* r,
  41313. const sp_point_1024* p, const sp_point_1024* q, sp_digit* t)
  41314. {
  41315. sp_digit* t6 = t;
  41316. sp_digit* t1 = t + 2*18;
  41317. sp_digit* t2 = t + 4*18;
  41318. sp_digit* t3 = t + 6*18;
  41319. sp_digit* t4 = t + 8*18;
  41320. sp_digit* t5 = t + 10*18;
  41321. /* U1 = X1*Z2^2 */
  41322. sp_1024_mont_sqr_18(t1, q->z, p1024_mod, p1024_mp_mod);
  41323. sp_1024_mont_mul_18(t3, t1, q->z, p1024_mod, p1024_mp_mod);
  41324. sp_1024_mont_mul_18(t1, t1, p->x, p1024_mod, p1024_mp_mod);
  41325. /* U2 = X2*Z1^2 */
  41326. sp_1024_mont_sqr_18(t2, p->z, p1024_mod, p1024_mp_mod);
  41327. sp_1024_mont_mul_18(t4, t2, p->z, p1024_mod, p1024_mp_mod);
  41328. sp_1024_mont_mul_18(t2, t2, q->x, p1024_mod, p1024_mp_mod);
  41329. /* S1 = Y1*Z2^3 */
  41330. sp_1024_mont_mul_18(t3, t3, p->y, p1024_mod, p1024_mp_mod);
  41331. /* S2 = Y2*Z1^3 */
  41332. sp_1024_mont_mul_18(t4, t4, q->y, p1024_mod, p1024_mp_mod);
  41333. /* Check double */
  41334. if ((~p->infinity) & (~q->infinity) &
  41335. sp_1024_cmp_equal_18(t2, t1) &
  41336. sp_1024_cmp_equal_18(t4, t3)) {
  41337. sp_1024_proj_point_dbl_18(r, p, t);
  41338. }
  41339. else {
  41340. sp_digit* x = t6;
  41341. sp_digit* y = t1;
  41342. sp_digit* z = t2;
  41343. /* H = U2 - U1 */
  41344. sp_1024_mont_sub_18(t2, t2, t1, p1024_mod);
  41345. /* R = S2 - S1 */
  41346. sp_1024_mont_sub_18(t4, t4, t3, p1024_mod);
  41347. /* X3 = R^2 - H^3 - 2*U1*H^2 */
  41348. sp_1024_mont_sqr_18(t5, t2, p1024_mod, p1024_mp_mod);
  41349. sp_1024_mont_mul_18(y, t1, t5, p1024_mod, p1024_mp_mod);
  41350. sp_1024_mont_mul_18(t5, t5, t2, p1024_mod, p1024_mp_mod);
  41351. /* Z3 = H*Z1*Z2 */
  41352. sp_1024_mont_mul_18(z, p->z, t2, p1024_mod, p1024_mp_mod);
  41353. sp_1024_mont_mul_18(z, z, q->z, p1024_mod, p1024_mp_mod);
  41354. sp_1024_mont_sqr_18(x, t4, p1024_mod, p1024_mp_mod);
  41355. sp_1024_mont_sub_18(x, x, t5, p1024_mod);
  41356. sp_1024_mont_mul_18(t5, t5, t3, p1024_mod, p1024_mp_mod);
  41357. sp_1024_mont_dbl_18(t3, y, p1024_mod);
  41358. sp_1024_mont_sub_18(x, x, t3, p1024_mod);
  41359. /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
  41360. sp_1024_mont_sub_18(y, y, x, p1024_mod);
  41361. sp_1024_mont_mul_18(y, y, t4, p1024_mod, p1024_mp_mod);
  41362. sp_1024_mont_sub_18(y, y, t5, p1024_mod);
  41363. {
  41364. int i;
  41365. sp_digit maskp = 0 - (q->infinity & (!p->infinity));
  41366. sp_digit maskq = 0 - (p->infinity & (!q->infinity));
  41367. sp_digit maskt = ~(maskp | maskq);
  41368. sp_digit inf = (sp_digit)(p->infinity & q->infinity);
  41369. for (i = 0; i < 18; i++) {
  41370. r->x[i] = (p->x[i] & maskp) | (q->x[i] & maskq) |
  41371. (x[i] & maskt);
  41372. }
  41373. for (i = 0; i < 18; i++) {
  41374. r->y[i] = (p->y[i] & maskp) | (q->y[i] & maskq) |
  41375. (y[i] & maskt);
  41376. }
  41377. for (i = 0; i < 18; i++) {
  41378. r->z[i] = (p->z[i] & maskp) | (q->z[i] & maskq) |
  41379. (z[i] & maskt);
  41380. }
  41381. r->z[0] |= inf;
  41382. r->infinity = (word32)inf;
  41383. }
  41384. }
  41385. }
  41386. #ifdef WOLFSSL_SP_NONBLOCK
  41387. typedef struct sp_1024_proj_point_add_18_ctx {
  41388. int state;
  41389. sp_1024_proj_point_dbl_18_ctx dbl_ctx;
  41390. const sp_point_1024* ap[2];
  41391. sp_point_1024* rp[2];
  41392. sp_digit* t1;
  41393. sp_digit* t2;
  41394. sp_digit* t3;
  41395. sp_digit* t4;
  41396. sp_digit* t5;
  41397. sp_digit* t6;
  41398. sp_digit* x;
  41399. sp_digit* y;
  41400. sp_digit* z;
  41401. } sp_1024_proj_point_add_18_ctx;
  41402. /* Add two Montgomery form projective points.
  41403. *
  41404. * r Result of addition.
  41405. * p First point to add.
  41406. * q Second point to add.
  41407. * t Temporary ordinate data.
  41408. */
  41409. static int sp_1024_proj_point_add_18_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
  41410. const sp_point_1024* p, const sp_point_1024* q, sp_digit* t)
  41411. {
  41412. int err = FP_WOULDBLOCK;
  41413. sp_1024_proj_point_add_18_ctx* ctx = (sp_1024_proj_point_add_18_ctx*)sp_ctx->data;
  41414. /* Ensure only the first point is the same as the result. */
  41415. if (q == r) {
  41416. const sp_point_1024* a = p;
  41417. p = q;
  41418. q = a;
  41419. }
  41420. typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_18_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  41421. (void)sizeof(ctx_size_test);
  41422. switch (ctx->state) {
  41423. case 0: /* INIT */
  41424. ctx->t6 = t;
  41425. ctx->t1 = t + 2*18;
  41426. ctx->t2 = t + 4*18;
  41427. ctx->t3 = t + 6*18;
  41428. ctx->t4 = t + 8*18;
  41429. ctx->t5 = t + 10*18;
  41430. ctx->x = ctx->t6;
  41431. ctx->y = ctx->t1;
  41432. ctx->z = ctx->t2;
  41433. ctx->state = 1;
  41434. break;
  41435. case 1:
  41436. /* U1 = X1*Z2^2 */
  41437. sp_1024_mont_sqr_18(ctx->t1, q->z, p1024_mod, p1024_mp_mod);
  41438. ctx->state = 2;
  41439. break;
  41440. case 2:
  41441. sp_1024_mont_mul_18(ctx->t3, ctx->t1, q->z, p1024_mod, p1024_mp_mod);
  41442. ctx->state = 3;
  41443. break;
  41444. case 3:
  41445. sp_1024_mont_mul_18(ctx->t1, ctx->t1, p->x, p1024_mod, p1024_mp_mod);
  41446. ctx->state = 4;
  41447. break;
  41448. case 4:
  41449. /* U2 = X2*Z1^2 */
  41450. sp_1024_mont_sqr_18(ctx->t2, p->z, p1024_mod, p1024_mp_mod);
  41451. ctx->state = 5;
  41452. break;
  41453. case 5:
  41454. sp_1024_mont_mul_18(ctx->t4, ctx->t2, p->z, p1024_mod, p1024_mp_mod);
  41455. ctx->state = 6;
  41456. break;
  41457. case 6:
  41458. sp_1024_mont_mul_18(ctx->t2, ctx->t2, q->x, p1024_mod, p1024_mp_mod);
  41459. ctx->state = 7;
  41460. break;
  41461. case 7:
  41462. /* S1 = Y1*Z2^3 */
  41463. sp_1024_mont_mul_18(ctx->t3, ctx->t3, p->y, p1024_mod, p1024_mp_mod);
  41464. ctx->state = 8;
  41465. break;
  41466. case 8:
  41467. /* S2 = Y2*Z1^3 */
  41468. sp_1024_mont_mul_18(ctx->t4, ctx->t4, q->y, p1024_mod, p1024_mp_mod);
  41469. ctx->state = 9;
  41470. break;
  41471. case 9:
  41472. /* Check double */
  41473. if ((~p->infinity) & (~q->infinity) &
  41474. sp_1024_cmp_equal_18(ctx->t2, ctx->t1) &
  41475. sp_1024_cmp_equal_18(ctx->t4, ctx->t3)) {
  41476. XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx));
  41477. sp_1024_proj_point_dbl_18(r, p, t);
  41478. ctx->state = 25;
  41479. }
  41480. else {
  41481. ctx->state = 10;
  41482. }
  41483. break;
  41484. case 10:
  41485. /* H = U2 - U1 */
  41486. sp_1024_mont_sub_18(ctx->t2, ctx->t2, ctx->t1, p1024_mod);
  41487. ctx->state = 11;
  41488. break;
  41489. case 11:
  41490. /* R = S2 - S1 */
  41491. sp_1024_mont_sub_18(ctx->t4, ctx->t4, ctx->t3, p1024_mod);
  41492. ctx->state = 12;
  41493. break;
  41494. case 12:
  41495. /* X3 = R^2 - H^3 - 2*U1*H^2 */
  41496. sp_1024_mont_sqr_18(ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod);
  41497. ctx->state = 13;
  41498. break;
  41499. case 13:
  41500. sp_1024_mont_mul_18(ctx->y, ctx->t1, ctx->t5, p1024_mod, p1024_mp_mod);
  41501. ctx->state = 14;
  41502. break;
  41503. case 14:
  41504. sp_1024_mont_mul_18(ctx->t5, ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod);
  41505. ctx->state = 15;
  41506. break;
  41507. case 15:
  41508. /* Z3 = H*Z1*Z2 */
  41509. sp_1024_mont_mul_18(ctx->z, p->z, ctx->t2, p1024_mod, p1024_mp_mod);
  41510. ctx->state = 16;
  41511. break;
  41512. case 16:
  41513. sp_1024_mont_mul_18(ctx->z, ctx->z, q->z, p1024_mod, p1024_mp_mod);
  41514. ctx->state = 17;
  41515. break;
  41516. case 17:
  41517. sp_1024_mont_sqr_18(ctx->x, ctx->t4, p1024_mod, p1024_mp_mod);
  41518. ctx->state = 18;
  41519. break;
  41520. case 18:
  41521. sp_1024_mont_sub_18(ctx->x, ctx->x, ctx->t5, p1024_mod);
  41522. ctx->state = 19;
  41523. break;
  41524. case 19:
  41525. sp_1024_mont_mul_18(ctx->t5, ctx->t5, ctx->t3, p1024_mod, p1024_mp_mod);
  41526. ctx->state = 20;
  41527. break;
  41528. case 20:
  41529. sp_1024_mont_dbl_18(ctx->t3, ctx->y, p1024_mod);
  41530. sp_1024_mont_sub_18(ctx->x, ctx->x, ctx->t3, p1024_mod);
  41531. ctx->state = 21;
  41532. break;
  41533. case 21:
  41534. /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
  41535. sp_1024_mont_sub_18(ctx->y, ctx->y, ctx->x, p1024_mod);
  41536. ctx->state = 22;
  41537. break;
  41538. case 22:
  41539. sp_1024_mont_mul_18(ctx->y, ctx->y, ctx->t4, p1024_mod, p1024_mp_mod);
  41540. ctx->state = 23;
  41541. break;
  41542. case 23:
  41543. sp_1024_mont_sub_18(ctx->y, ctx->y, ctx->t5, p1024_mod);
  41544. ctx->state = 24;
  41545. break;
  41546. case 24:
  41547. {
  41548. {
  41549. int i;
  41550. sp_digit maskp = 0 - (q->infinity & (!p->infinity));
  41551. sp_digit maskq = 0 - (p->infinity & (!q->infinity));
  41552. sp_digit maskt = ~(maskp | maskq);
  41553. sp_digit inf = (sp_digit)(p->infinity & q->infinity);
  41554. for (i = 0; i < 18; i++) {
  41555. r->x[i] = (p->x[i] & maskp) | (q->x[i] & maskq) |
  41556. (ctx->x[i] & maskt);
  41557. }
  41558. for (i = 0; i < 18; i++) {
  41559. r->y[i] = (p->y[i] & maskp) | (q->y[i] & maskq) |
  41560. (ctx->y[i] & maskt);
  41561. }
  41562. for (i = 0; i < 18; i++) {
  41563. r->z[i] = (p->z[i] & maskp) | (q->z[i] & maskq) |
  41564. (ctx->z[i] & maskt);
  41565. }
  41566. r->z[0] |= inf;
  41567. r->infinity = (word32)inf;
  41568. }
  41569. ctx->state = 25;
  41570. break;
  41571. }
  41572. case 25:
  41573. err = MP_OKAY;
  41574. break;
  41575. }
  41576. if (err == MP_OKAY && ctx->state != 25) {
  41577. err = FP_WOULDBLOCK;
  41578. }
  41579. return err;
  41580. }
  41581. #endif /* WOLFSSL_SP_NONBLOCK */
  41582. #ifdef WOLFSSL_SP_SMALL
  41583. /* Multiply the point by the scalar and return the result.
  41584. * If map is true then convert result to affine coordinates.
  41585. *
  41586. * Small implementation using add and double that is cache attack resistant but
  41587. * allocates memory rather than use large stacks.
  41588. * 1024 adds and doubles.
  41589. *
  41590. * r Resulting point.
  41591. * g Point to multiply.
  41592. * k Scalar to multiply by.
  41593. * map Indicates whether to convert result to affine.
  41594. * ct Constant time required.
  41595. * heap Heap to use for allocation.
  41596. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  41597. */
  41598. static int sp_1024_ecc_mulmod_18(sp_point_1024* r, const sp_point_1024* g,
  41599. const sp_digit* k, int map, int ct, void* heap)
  41600. {
  41601. #ifdef WOLFSSL_SP_SMALL_STACK
  41602. sp_point_1024* t = NULL;
  41603. sp_digit* tmp = NULL;
  41604. #else
  41605. sp_point_1024 t[3];
  41606. sp_digit tmp[2 * 18 * 37];
  41607. #endif
  41608. sp_digit n;
  41609. int i;
  41610. int c;
  41611. int y;
  41612. int err = MP_OKAY;
  41613. /* Implementation is constant time. */
  41614. (void)ct;
  41615. (void)heap;
  41616. #ifdef WOLFSSL_SP_SMALL_STACK
  41617. t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 3, heap,
  41618. DYNAMIC_TYPE_ECC);
  41619. if (t == NULL)
  41620. err = MEMORY_E;
  41621. if (err == MP_OKAY) {
  41622. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 18 * 37, heap,
  41623. DYNAMIC_TYPE_ECC);
  41624. if (tmp == NULL)
  41625. err = MEMORY_E;
  41626. }
  41627. #endif
  41628. if (err == MP_OKAY) {
  41629. XMEMSET(t, 0, sizeof(sp_point_1024) * 3);
  41630. /* t[0] = {0, 0, 1} * norm */
  41631. t[0].infinity = 1;
  41632. /* t[1] = {g->x, g->y, g->z} * norm */
  41633. err = sp_1024_mod_mul_norm_18(t[1].x, g->x, p1024_mod);
  41634. }
  41635. if (err == MP_OKAY)
  41636. err = sp_1024_mod_mul_norm_18(t[1].y, g->y, p1024_mod);
  41637. if (err == MP_OKAY)
  41638. err = sp_1024_mod_mul_norm_18(t[1].z, g->z, p1024_mod);
  41639. if (err == MP_OKAY) {
  41640. i = 17;
  41641. c = 55;
  41642. n = k[i--] << (57 - c);
  41643. for (; ; c--) {
  41644. if (c == 0) {
  41645. if (i == -1)
  41646. break;
  41647. n = k[i--];
  41648. c = 57;
  41649. }
  41650. y = (n >> 56) & 1;
  41651. n <<= 1;
  41652. sp_1024_proj_point_add_18(&t[y^1], &t[0], &t[1], tmp);
  41653. XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) +
  41654. ((size_t)&t[1] & addr_mask[y])),
  41655. sizeof(sp_point_1024));
  41656. sp_1024_proj_point_dbl_18(&t[2], &t[2], tmp);
  41657. XMEMCPY((void*)(((size_t)&t[0] & addr_mask[y^1]) +
  41658. ((size_t)&t[1] & addr_mask[y])), &t[2],
  41659. sizeof(sp_point_1024));
  41660. }
  41661. if (map != 0) {
  41662. sp_1024_map_18(r, &t[0], tmp);
  41663. }
  41664. else {
  41665. XMEMCPY(r, &t[0], sizeof(sp_point_1024));
  41666. }
  41667. }
  41668. #ifdef WOLFSSL_SP_SMALL_STACK
  41669. if (tmp != NULL)
  41670. #endif
  41671. {
  41672. ForceZero(tmp, sizeof(sp_digit) * 2 * 18 * 37);
  41673. #ifdef WOLFSSL_SP_SMALL_STACK
  41674. XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
  41675. #endif
  41676. }
  41677. #ifdef WOLFSSL_SP_SMALL_STACK
  41678. if (t != NULL)
  41679. #endif
  41680. {
  41681. ForceZero(t, sizeof(sp_point_1024) * 3);
  41682. #ifdef WOLFSSL_SP_SMALL_STACK
  41683. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  41684. #endif
  41685. }
  41686. return err;
  41687. }
  41688. #ifdef WOLFSSL_SP_NONBLOCK
  41689. typedef struct sp_1024_ecc_mulmod_18_ctx {
  41690. int state;
  41691. union {
  41692. sp_1024_proj_point_dbl_18_ctx dbl_ctx;
  41693. sp_1024_proj_point_add_18_ctx add_ctx;
  41694. };
  41695. sp_point_1024 t[3];
  41696. sp_digit tmp[2 * 18 * 37];
  41697. sp_digit n;
  41698. int i;
  41699. int c;
  41700. int y;
  41701. } sp_1024_ecc_mulmod_18_ctx;
  41702. static int sp_1024_ecc_mulmod_18_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
  41703. const sp_point_1024* g, const sp_digit* k, int map, int ct, void* heap)
  41704. {
  41705. int err = FP_WOULDBLOCK;
  41706. sp_1024_ecc_mulmod_18_ctx* ctx = (sp_1024_ecc_mulmod_18_ctx*)sp_ctx->data;
  41707. typedef char ctx_size_test[sizeof(sp_1024_ecc_mulmod_18_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
  41708. (void)sizeof(ctx_size_test);
  41709. /* Implementation is constant time. */
  41710. (void)ct;
  41711. switch (ctx->state) {
  41712. case 0: /* INIT */
  41713. XMEMSET(ctx->t, 0, sizeof(sp_point_1024) * 3);
  41714. ctx->i = 17;
  41715. ctx->c = 55;
  41716. ctx->n = k[ctx->i--] << (57 - ctx->c);
  41717. /* t[0] = {0, 0, 1} * norm */
  41718. ctx->t[0].infinity = 1;
  41719. ctx->state = 1;
  41720. break;
  41721. case 1: /* T1X */
  41722. /* t[1] = {g->x, g->y, g->z} * norm */
  41723. err = sp_1024_mod_mul_norm_18(ctx->t[1].x, g->x, p1024_mod);
  41724. ctx->state = 2;
  41725. break;
  41726. case 2: /* T1Y */
  41727. err = sp_1024_mod_mul_norm_18(ctx->t[1].y, g->y, p1024_mod);
  41728. ctx->state = 3;
  41729. break;
  41730. case 3: /* T1Z */
  41731. err = sp_1024_mod_mul_norm_18(ctx->t[1].z, g->z, p1024_mod);
  41732. ctx->state = 4;
  41733. break;
  41734. case 4: /* ADDPREP */
  41735. if (ctx->c == 0) {
  41736. if (ctx->i == -1) {
  41737. ctx->state = 7;
  41738. break;
  41739. }
  41740. ctx->n = k[ctx->i--];
  41741. ctx->c = 57;
  41742. }
  41743. ctx->y = (ctx->n >> 56) & 1;
  41744. ctx->n <<= 1;
  41745. XMEMSET(&ctx->add_ctx, 0, sizeof(ctx->add_ctx));
  41746. ctx->state = 5;
  41747. break;
  41748. case 5: /* ADD */
  41749. err = sp_1024_proj_point_add_18_nb((sp_ecc_ctx_t*)&ctx->add_ctx,
  41750. &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp);
  41751. if (err == MP_OKAY) {
  41752. XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) +
  41753. ((size_t)&ctx->t[1] & addr_mask[ctx->y])),
  41754. sizeof(sp_point_1024));
  41755. XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx));
  41756. ctx->state = 6;
  41757. }
  41758. break;
  41759. case 6: /* DBL */
  41760. err = sp_1024_proj_point_dbl_18_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2],
  41761. &ctx->t[2], ctx->tmp);
  41762. if (err == MP_OKAY) {
  41763. XMEMCPY((void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) +
  41764. ((size_t)&ctx->t[1] & addr_mask[ctx->y])), &ctx->t[2],
  41765. sizeof(sp_point_1024));
  41766. ctx->state = 4;
  41767. ctx->c--;
  41768. }
  41769. break;
  41770. case 7: /* MAP */
  41771. if (map != 0) {
  41772. sp_1024_map_18(r, &ctx->t[0], ctx->tmp);
  41773. }
  41774. else {
  41775. XMEMCPY(r, &ctx->t[0], sizeof(sp_point_1024));
  41776. }
  41777. err = MP_OKAY;
  41778. break;
  41779. }
  41780. if (err == MP_OKAY && ctx->state != 7) {
  41781. err = FP_WOULDBLOCK;
  41782. }
  41783. if (err != FP_WOULDBLOCK) {
  41784. ForceZero(ctx->tmp, sizeof(ctx->tmp));
  41785. ForceZero(ctx->t, sizeof(ctx->t));
  41786. }
  41787. (void)heap;
  41788. return err;
  41789. }
  41790. #endif /* WOLFSSL_SP_NONBLOCK */
  41791. #else
  41792. /* A table entry for pre-computed points. */
  41793. typedef struct sp_table_entry_1024 {
  41794. sp_digit x[18];
  41795. sp_digit y[18];
  41796. } sp_table_entry_1024;
  41797. /* Conditionally copy a into r using the mask m.
  41798. * m is -1 to copy and 0 when not.
  41799. *
  41800. * r A single precision number to copy over.
  41801. * a A single precision number to copy.
  41802. * m Mask value to apply.
  41803. */
  41804. static void sp_1024_cond_copy_18(sp_digit* r, const sp_digit* a, const sp_digit m)
  41805. {
  41806. sp_digit t[18];
  41807. #ifdef WOLFSSL_SP_SMALL
  41808. int i;
  41809. for (i = 0; i < 18; i++) {
  41810. t[i] = r[i] ^ a[i];
  41811. }
  41812. for (i = 0; i < 18; i++) {
  41813. r[i] ^= t[i] & m;
  41814. }
  41815. #else
  41816. t[ 0] = r[ 0] ^ a[ 0];
  41817. t[ 1] = r[ 1] ^ a[ 1];
  41818. t[ 2] = r[ 2] ^ a[ 2];
  41819. t[ 3] = r[ 3] ^ a[ 3];
  41820. t[ 4] = r[ 4] ^ a[ 4];
  41821. t[ 5] = r[ 5] ^ a[ 5];
  41822. t[ 6] = r[ 6] ^ a[ 6];
  41823. t[ 7] = r[ 7] ^ a[ 7];
  41824. t[ 8] = r[ 8] ^ a[ 8];
  41825. t[ 9] = r[ 9] ^ a[ 9];
  41826. t[10] = r[10] ^ a[10];
  41827. t[11] = r[11] ^ a[11];
  41828. t[12] = r[12] ^ a[12];
  41829. t[13] = r[13] ^ a[13];
  41830. t[14] = r[14] ^ a[14];
  41831. t[15] = r[15] ^ a[15];
  41832. t[16] = r[16] ^ a[16];
  41833. t[17] = r[17] ^ a[17];
  41834. r[ 0] ^= t[ 0] & m;
  41835. r[ 1] ^= t[ 1] & m;
  41836. r[ 2] ^= t[ 2] & m;
  41837. r[ 3] ^= t[ 3] & m;
  41838. r[ 4] ^= t[ 4] & m;
  41839. r[ 5] ^= t[ 5] & m;
  41840. r[ 6] ^= t[ 6] & m;
  41841. r[ 7] ^= t[ 7] & m;
  41842. r[ 8] ^= t[ 8] & m;
  41843. r[ 9] ^= t[ 9] & m;
  41844. r[10] ^= t[10] & m;
  41845. r[11] ^= t[11] & m;
  41846. r[12] ^= t[12] & m;
  41847. r[13] ^= t[13] & m;
  41848. r[14] ^= t[14] & m;
  41849. r[15] ^= t[15] & m;
  41850. r[16] ^= t[16] & m;
  41851. r[17] ^= t[17] & m;
  41852. #endif /* WOLFSSL_SP_SMALL */
  41853. }
  41854. /* Double the Montgomery form projective point p a number of times.
  41855. *
  41856. * r Result of repeated doubling of point.
  41857. * p Point to double.
  41858. * n Number of times to double
  41859. * t Temporary ordinate data.
  41860. */
  41861. static void sp_1024_proj_point_dbl_n_18(sp_point_1024* p, int i,
  41862. sp_digit* t)
  41863. {
  41864. sp_digit* w = t;
  41865. sp_digit* a = t + 2*18;
  41866. sp_digit* b = t + 4*18;
  41867. sp_digit* t1 = t + 6*18;
  41868. sp_digit* t2 = t + 8*18;
  41869. sp_digit* x;
  41870. sp_digit* y;
  41871. sp_digit* z;
  41872. volatile int n = i;
  41873. x = p->x;
  41874. y = p->y;
  41875. z = p->z;
  41876. /* Y = 2*Y */
  41877. sp_1024_mont_dbl_18(y, y, p1024_mod);
  41878. /* W = Z^4 */
  41879. sp_1024_mont_sqr_18(w, z, p1024_mod, p1024_mp_mod);
  41880. sp_1024_mont_sqr_18(w, w, p1024_mod, p1024_mp_mod);
  41881. #ifndef WOLFSSL_SP_SMALL
  41882. while (--n > 0)
  41883. #else
  41884. while (--n >= 0)
  41885. #endif
  41886. {
  41887. /* A = 3*(X^2 - W) */
  41888. sp_1024_mont_sqr_18(t1, x, p1024_mod, p1024_mp_mod);
  41889. sp_1024_mont_sub_18(t1, t1, w, p1024_mod);
  41890. sp_1024_mont_tpl_18(a, t1, p1024_mod);
  41891. /* B = X*Y^2 */
  41892. sp_1024_mont_sqr_18(t1, y, p1024_mod, p1024_mp_mod);
  41893. sp_1024_mont_mul_18(b, t1, x, p1024_mod, p1024_mp_mod);
  41894. /* X = A^2 - 2B */
  41895. sp_1024_mont_sqr_18(x, a, p1024_mod, p1024_mp_mod);
  41896. sp_1024_mont_dbl_18(t2, b, p1024_mod);
  41897. sp_1024_mont_sub_18(x, x, t2, p1024_mod);
  41898. /* B = 2.(B - X) */
  41899. sp_1024_mont_sub_18(t2, b, x, p1024_mod);
  41900. sp_1024_mont_dbl_18(b, t2, p1024_mod);
  41901. /* Z = Z*Y */
  41902. sp_1024_mont_mul_18(z, z, y, p1024_mod, p1024_mp_mod);
  41903. /* t1 = Y^4 */
  41904. sp_1024_mont_sqr_18(t1, t1, p1024_mod, p1024_mp_mod);
  41905. #ifdef WOLFSSL_SP_SMALL
  41906. if (n != 0)
  41907. #endif
  41908. {
  41909. /* W = W*Y^4 */
  41910. sp_1024_mont_mul_18(w, w, t1, p1024_mod, p1024_mp_mod);
  41911. }
  41912. /* y = 2*A*(B - X) - Y^4 */
  41913. sp_1024_mont_mul_18(y, b, a, p1024_mod, p1024_mp_mod);
  41914. sp_1024_mont_sub_18(y, y, t1, p1024_mod);
  41915. }
  41916. #ifndef WOLFSSL_SP_SMALL
  41917. /* A = 3*(X^2 - W) */
  41918. sp_1024_mont_sqr_18(t1, x, p1024_mod, p1024_mp_mod);
  41919. sp_1024_mont_sub_18(t1, t1, w, p1024_mod);
  41920. sp_1024_mont_tpl_18(a, t1, p1024_mod);
  41921. /* B = X*Y^2 */
  41922. sp_1024_mont_sqr_18(t1, y, p1024_mod, p1024_mp_mod);
  41923. sp_1024_mont_mul_18(b, t1, x, p1024_mod, p1024_mp_mod);
  41924. /* X = A^2 - 2B */
  41925. sp_1024_mont_sqr_18(x, a, p1024_mod, p1024_mp_mod);
  41926. sp_1024_mont_dbl_18(t2, b, p1024_mod);
  41927. sp_1024_mont_sub_18(x, x, t2, p1024_mod);
  41928. /* B = 2.(B - X) */
  41929. sp_1024_mont_sub_18(t2, b, x, p1024_mod);
  41930. sp_1024_mont_dbl_18(b, t2, p1024_mod);
  41931. /* Z = Z*Y */
  41932. sp_1024_mont_mul_18(z, z, y, p1024_mod, p1024_mp_mod);
  41933. /* t1 = Y^4 */
  41934. sp_1024_mont_sqr_18(t1, t1, p1024_mod, p1024_mp_mod);
  41935. /* y = 2*A*(B - X) - Y^4 */
  41936. sp_1024_mont_mul_18(y, b, a, p1024_mod, p1024_mp_mod);
  41937. sp_1024_mont_sub_18(y, y, t1, p1024_mod);
  41938. #endif /* WOLFSSL_SP_SMALL */
  41939. /* Y = Y/2 */
  41940. sp_1024_mont_div2_18(y, y, p1024_mod);
  41941. }
  41942. /* Double the Montgomery form projective point p a number of times.
  41943. *
  41944. * r Result of repeated doubling of point.
  41945. * p Point to double.
  41946. * n Number of times to double
  41947. * t Temporary ordinate data.
  41948. */
  41949. static void sp_1024_proj_point_dbl_n_store_18(sp_point_1024* r,
  41950. const sp_point_1024* p, int n, int m, sp_digit* t)
  41951. {
  41952. sp_digit* w = t;
  41953. sp_digit* a = t + 2*18;
  41954. sp_digit* b = t + 4*18;
  41955. sp_digit* t1 = t + 6*18;
  41956. sp_digit* t2 = t + 8*18;
  41957. sp_digit* x = r[2*m].x;
  41958. sp_digit* y = r[(1<<n)*m].y;
  41959. sp_digit* z = r[2*m].z;
  41960. int i;
  41961. int j;
  41962. for (i=0; i<18; i++) {
  41963. x[i] = p->x[i];
  41964. }
  41965. for (i=0; i<18; i++) {
  41966. y[i] = p->y[i];
  41967. }
  41968. for (i=0; i<18; i++) {
  41969. z[i] = p->z[i];
  41970. }
  41971. /* Y = 2*Y */
  41972. sp_1024_mont_dbl_18(y, y, p1024_mod);
  41973. /* W = Z^4 */
  41974. sp_1024_mont_sqr_18(w, z, p1024_mod, p1024_mp_mod);
  41975. sp_1024_mont_sqr_18(w, w, p1024_mod, p1024_mp_mod);
  41976. j = m;
  41977. for (i=1; i<=n; i++) {
  41978. j *= 2;
  41979. /* A = 3*(X^2 - W) */
  41980. sp_1024_mont_sqr_18(t1, x, p1024_mod, p1024_mp_mod);
  41981. sp_1024_mont_sub_18(t1, t1, w, p1024_mod);
  41982. sp_1024_mont_tpl_18(a, t1, p1024_mod);
  41983. /* B = X*Y^2 */
  41984. sp_1024_mont_sqr_18(t1, y, p1024_mod, p1024_mp_mod);
  41985. sp_1024_mont_mul_18(b, t1, x, p1024_mod, p1024_mp_mod);
  41986. x = r[j].x;
  41987. /* X = A^2 - 2B */
  41988. sp_1024_mont_sqr_18(x, a, p1024_mod, p1024_mp_mod);
  41989. sp_1024_mont_dbl_18(t2, b, p1024_mod);
  41990. sp_1024_mont_sub_18(x, x, t2, p1024_mod);
  41991. /* B = 2.(B - X) */
  41992. sp_1024_mont_sub_18(t2, b, x, p1024_mod);
  41993. sp_1024_mont_dbl_18(b, t2, p1024_mod);
  41994. /* Z = Z*Y */
  41995. sp_1024_mont_mul_18(r[j].z, z, y, p1024_mod, p1024_mp_mod);
  41996. z = r[j].z;
  41997. /* t1 = Y^4 */
  41998. sp_1024_mont_sqr_18(t1, t1, p1024_mod, p1024_mp_mod);
  41999. if (i != n) {
  42000. /* W = W*Y^4 */
  42001. sp_1024_mont_mul_18(w, w, t1, p1024_mod, p1024_mp_mod);
  42002. }
  42003. /* y = 2*A*(B - X) - Y^4 */
  42004. sp_1024_mont_mul_18(y, b, a, p1024_mod, p1024_mp_mod);
  42005. sp_1024_mont_sub_18(y, y, t1, p1024_mod);
  42006. /* Y = Y/2 */
  42007. sp_1024_mont_div2_18(r[j].y, y, p1024_mod);
  42008. r[j].infinity = 0;
  42009. }
  42010. }
  42011. /* Add two Montgomery form projective points.
  42012. *
  42013. * ra Result of addition.
  42014. * rs Result of subtraction.
  42015. * p First point to add.
  42016. * q Second point to add.
  42017. * t Temporary ordinate data.
  42018. */
  42019. static void sp_1024_proj_point_add_sub_18(sp_point_1024* ra,
  42020. sp_point_1024* rs, const sp_point_1024* p, const sp_point_1024* q,
  42021. sp_digit* t)
  42022. {
  42023. sp_digit* t1 = t;
  42024. sp_digit* t2 = t + 2*18;
  42025. sp_digit* t3 = t + 4*18;
  42026. sp_digit* t4 = t + 6*18;
  42027. sp_digit* t5 = t + 8*18;
  42028. sp_digit* t6 = t + 10*18;
  42029. sp_digit* xa = ra->x;
  42030. sp_digit* ya = ra->y;
  42031. sp_digit* za = ra->z;
  42032. sp_digit* xs = rs->x;
  42033. sp_digit* ys = rs->y;
  42034. sp_digit* zs = rs->z;
  42035. XMEMCPY(xa, p->x, sizeof(p->x) / 2);
  42036. XMEMCPY(ya, p->y, sizeof(p->y) / 2);
  42037. XMEMCPY(za, p->z, sizeof(p->z) / 2);
  42038. ra->infinity = 0;
  42039. rs->infinity = 0;
  42040. /* U1 = X1*Z2^2 */
  42041. sp_1024_mont_sqr_18(t1, q->z, p1024_mod, p1024_mp_mod);
  42042. sp_1024_mont_mul_18(t3, t1, q->z, p1024_mod, p1024_mp_mod);
  42043. sp_1024_mont_mul_18(t1, t1, xa, p1024_mod, p1024_mp_mod);
  42044. /* U2 = X2*Z1^2 */
  42045. sp_1024_mont_sqr_18(t2, za, p1024_mod, p1024_mp_mod);
  42046. sp_1024_mont_mul_18(t4, t2, za, p1024_mod, p1024_mp_mod);
  42047. sp_1024_mont_mul_18(t2, t2, q->x, p1024_mod, p1024_mp_mod);
  42048. /* S1 = Y1*Z2^3 */
  42049. sp_1024_mont_mul_18(t3, t3, ya, p1024_mod, p1024_mp_mod);
  42050. /* S2 = Y2*Z1^3 */
  42051. sp_1024_mont_mul_18(t4, t4, q->y, p1024_mod, p1024_mp_mod);
  42052. /* H = U2 - U1 */
  42053. sp_1024_mont_sub_18(t2, t2, t1, p1024_mod);
  42054. /* RS = S2 + S1 */
  42055. sp_1024_mont_add_18(t6, t4, t3, p1024_mod);
  42056. /* R = S2 - S1 */
  42057. sp_1024_mont_sub_18(t4, t4, t3, p1024_mod);
  42058. /* Z3 = H*Z1*Z2 */
  42059. /* ZS = H*Z1*Z2 */
  42060. sp_1024_mont_mul_18(za, za, q->z, p1024_mod, p1024_mp_mod);
  42061. sp_1024_mont_mul_18(za, za, t2, p1024_mod, p1024_mp_mod);
  42062. XMEMCPY(zs, za, sizeof(p->z)/2);
  42063. /* X3 = R^2 - H^3 - 2*U1*H^2 */
  42064. /* XS = RS^2 - H^3 - 2*U1*H^2 */
  42065. sp_1024_mont_sqr_18(xa, t4, p1024_mod, p1024_mp_mod);
  42066. sp_1024_mont_sqr_18(xs, t6, p1024_mod, p1024_mp_mod);
  42067. sp_1024_mont_sqr_18(t5, t2, p1024_mod, p1024_mp_mod);
  42068. sp_1024_mont_mul_18(ya, t1, t5, p1024_mod, p1024_mp_mod);
  42069. sp_1024_mont_mul_18(t5, t5, t2, p1024_mod, p1024_mp_mod);
  42070. sp_1024_mont_sub_18(xa, xa, t5, p1024_mod);
  42071. sp_1024_mont_sub_18(xs, xs, t5, p1024_mod);
  42072. sp_1024_mont_dbl_18(t1, ya, p1024_mod);
  42073. sp_1024_mont_sub_18(xa, xa, t1, p1024_mod);
  42074. sp_1024_mont_sub_18(xs, xs, t1, p1024_mod);
  42075. /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
  42076. /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */
  42077. sp_1024_mont_sub_18(ys, ya, xs, p1024_mod);
  42078. sp_1024_mont_sub_18(ya, ya, xa, p1024_mod);
  42079. sp_1024_mont_mul_18(ya, ya, t4, p1024_mod, p1024_mp_mod);
  42080. sp_1024_mont_sub_18(t6, p1024_mod, t6, p1024_mod);
  42081. sp_1024_mont_mul_18(ys, ys, t6, p1024_mod, p1024_mp_mod);
  42082. sp_1024_mont_mul_18(t5, t5, t3, p1024_mod, p1024_mp_mod);
  42083. sp_1024_mont_sub_18(ya, ya, t5, p1024_mod);
  42084. sp_1024_mont_sub_18(ys, ys, t5, p1024_mod);
  42085. }
  42086. /* Structure used to describe recoding of scalar multiplication. */
  42087. typedef struct ecc_recode_1024 {
  42088. /* Index into pre-computation table. */
  42089. uint8_t i;
  42090. /* Use the negative of the point. */
  42091. uint8_t neg;
  42092. } ecc_recode_1024;
  42093. /* The index into pre-computation table to use. */
  42094. static const uint8_t recode_index_18_7[130] = {
  42095. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  42096. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  42097. 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  42098. 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  42099. 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49,
  42100. 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,
  42101. 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
  42102. 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
  42103. 0, 1,
  42104. };
  42105. /* Whether to negate y-ordinate. */
  42106. static const uint8_t recode_neg_18_7[130] = {
  42107. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  42108. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  42109. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  42110. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  42111. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  42112. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  42113. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  42114. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  42115. 0, 0,
  42116. };
  42117. /* Recode the scalar for multiplication using pre-computed values and
  42118. * subtraction.
  42119. *
  42120. * k Scalar to multiply by.
  42121. * v Vector of operations to perform.
  42122. */
  42123. static void sp_1024_ecc_recode_7_18(const sp_digit* k, ecc_recode_1024* v)
  42124. {
  42125. int i;
  42126. int j;
  42127. uint8_t y;
  42128. int carry = 0;
  42129. int o;
  42130. sp_digit n;
  42131. j = 0;
  42132. n = k[j];
  42133. o = 0;
  42134. for (i=0; i<147; i++) {
  42135. y = (int8_t)n;
  42136. if (o + 7 < 57) {
  42137. y &= 0x7f;
  42138. n >>= 7;
  42139. o += 7;
  42140. }
  42141. else if (o + 7 == 57) {
  42142. n >>= 7;
  42143. if (++j < 18)
  42144. n = k[j];
  42145. o = 0;
  42146. }
  42147. else if (++j < 18) {
  42148. n = k[j];
  42149. y |= (uint8_t)((n << (57 - o)) & 0x7f);
  42150. o -= 50;
  42151. n >>= o;
  42152. }
  42153. y += (uint8_t)carry;
  42154. v[i].i = recode_index_18_7[y];
  42155. v[i].neg = recode_neg_18_7[y];
  42156. carry = (y >> 7) + v[i].neg;
  42157. }
  42158. }
  42159. /* Multiply the point by the scalar and return the result.
  42160. * If map is true then convert result to affine coordinates.
  42161. *
  42162. * Window technique of 7 bits. (Add-Sub variation.)
  42163. * Calculate 0..64 times the point. Use function that adds and
  42164. * subtracts the same two points.
  42165. * Recode to add or subtract one of the computed points.
  42166. * Double to push up.
  42167. * NOT a sliding window.
  42168. *
  42169. * r Resulting point.
  42170. * g Point to multiply.
  42171. * k Scalar to multiply by.
  42172. * map Indicates whether to convert result to affine.
  42173. * ct Constant time required.
  42174. * heap Heap to use for allocation.
  42175. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  42176. */
  42177. static int sp_1024_ecc_mulmod_win_add_sub_18(sp_point_1024* r, const sp_point_1024* g,
  42178. const sp_digit* k, int map, int ct, void* heap)
  42179. {
  42180. #ifdef WOLFSSL_SP_SMALL_STACK
  42181. sp_point_1024* t = NULL;
  42182. sp_digit* tmp = NULL;
  42183. #else
  42184. sp_point_1024 t[65+2];
  42185. sp_digit tmp[2 * 18 * 37];
  42186. #endif
  42187. sp_point_1024* rt = NULL;
  42188. sp_point_1024* p = NULL;
  42189. sp_digit* negy;
  42190. int i;
  42191. ecc_recode_1024 v[147];
  42192. int err = MP_OKAY;
  42193. /* Constant time used for cache attack resistance implementation. */
  42194. (void)ct;
  42195. (void)heap;
  42196. #ifdef WOLFSSL_SP_SMALL_STACK
  42197. t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) *
  42198. (65+2), heap, DYNAMIC_TYPE_ECC);
  42199. if (t == NULL)
  42200. err = MEMORY_E;
  42201. if (err == MP_OKAY) {
  42202. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 18 * 37,
  42203. heap, DYNAMIC_TYPE_ECC);
  42204. if (tmp == NULL)
  42205. err = MEMORY_E;
  42206. }
  42207. #endif
  42208. if (err == MP_OKAY) {
  42209. rt = t + 65;
  42210. p = t + 65+1;
  42211. /* t[0] = {0, 0, 1} * norm */
  42212. XMEMSET(&t[0], 0, sizeof(t[0]));
  42213. t[0].infinity = 1;
  42214. /* t[1] = {g->x, g->y, g->z} * norm */
  42215. err = sp_1024_mod_mul_norm_18(t[1].x, g->x, p1024_mod);
  42216. }
  42217. if (err == MP_OKAY) {
  42218. err = sp_1024_mod_mul_norm_18(t[1].y, g->y, p1024_mod);
  42219. }
  42220. if (err == MP_OKAY) {
  42221. err = sp_1024_mod_mul_norm_18(t[1].z, g->z, p1024_mod);
  42222. }
  42223. if (err == MP_OKAY) {
  42224. t[1].infinity = 0;
  42225. /* t[2] ... t[64] */
  42226. sp_1024_proj_point_dbl_n_store_18(t, &t[ 1], 6, 1, tmp);
  42227. sp_1024_proj_point_add_18(&t[ 3], &t[ 2], &t[ 1], tmp);
  42228. sp_1024_proj_point_dbl_18(&t[ 6], &t[ 3], tmp);
  42229. sp_1024_proj_point_add_sub_18(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp);
  42230. sp_1024_proj_point_dbl_18(&t[10], &t[ 5], tmp);
  42231. sp_1024_proj_point_add_sub_18(&t[11], &t[ 9], &t[10], &t[ 1], tmp);
  42232. sp_1024_proj_point_dbl_18(&t[12], &t[ 6], tmp);
  42233. sp_1024_proj_point_dbl_18(&t[14], &t[ 7], tmp);
  42234. sp_1024_proj_point_add_sub_18(&t[15], &t[13], &t[14], &t[ 1], tmp);
  42235. sp_1024_proj_point_dbl_18(&t[18], &t[ 9], tmp);
  42236. sp_1024_proj_point_add_sub_18(&t[19], &t[17], &t[18], &t[ 1], tmp);
  42237. sp_1024_proj_point_dbl_18(&t[20], &t[10], tmp);
  42238. sp_1024_proj_point_dbl_18(&t[22], &t[11], tmp);
  42239. sp_1024_proj_point_add_sub_18(&t[23], &t[21], &t[22], &t[ 1], tmp);
  42240. sp_1024_proj_point_dbl_18(&t[24], &t[12], tmp);
  42241. sp_1024_proj_point_dbl_18(&t[26], &t[13], tmp);
  42242. sp_1024_proj_point_add_sub_18(&t[27], &t[25], &t[26], &t[ 1], tmp);
  42243. sp_1024_proj_point_dbl_18(&t[28], &t[14], tmp);
  42244. sp_1024_proj_point_dbl_18(&t[30], &t[15], tmp);
  42245. sp_1024_proj_point_add_sub_18(&t[31], &t[29], &t[30], &t[ 1], tmp);
  42246. sp_1024_proj_point_dbl_18(&t[34], &t[17], tmp);
  42247. sp_1024_proj_point_add_sub_18(&t[35], &t[33], &t[34], &t[ 1], tmp);
  42248. sp_1024_proj_point_dbl_18(&t[36], &t[18], tmp);
  42249. sp_1024_proj_point_dbl_18(&t[38], &t[19], tmp);
  42250. sp_1024_proj_point_add_sub_18(&t[39], &t[37], &t[38], &t[ 1], tmp);
  42251. sp_1024_proj_point_dbl_18(&t[40], &t[20], tmp);
  42252. sp_1024_proj_point_dbl_18(&t[42], &t[21], tmp);
  42253. sp_1024_proj_point_add_sub_18(&t[43], &t[41], &t[42], &t[ 1], tmp);
  42254. sp_1024_proj_point_dbl_18(&t[44], &t[22], tmp);
  42255. sp_1024_proj_point_dbl_18(&t[46], &t[23], tmp);
  42256. sp_1024_proj_point_add_sub_18(&t[47], &t[45], &t[46], &t[ 1], tmp);
  42257. sp_1024_proj_point_dbl_18(&t[48], &t[24], tmp);
  42258. sp_1024_proj_point_dbl_18(&t[50], &t[25], tmp);
  42259. sp_1024_proj_point_add_sub_18(&t[51], &t[49], &t[50], &t[ 1], tmp);
  42260. sp_1024_proj_point_dbl_18(&t[52], &t[26], tmp);
  42261. sp_1024_proj_point_dbl_18(&t[54], &t[27], tmp);
  42262. sp_1024_proj_point_add_sub_18(&t[55], &t[53], &t[54], &t[ 1], tmp);
  42263. sp_1024_proj_point_dbl_18(&t[56], &t[28], tmp);
  42264. sp_1024_proj_point_dbl_18(&t[58], &t[29], tmp);
  42265. sp_1024_proj_point_add_sub_18(&t[59], &t[57], &t[58], &t[ 1], tmp);
  42266. sp_1024_proj_point_dbl_18(&t[60], &t[30], tmp);
  42267. sp_1024_proj_point_dbl_18(&t[62], &t[31], tmp);
  42268. sp_1024_proj_point_add_sub_18(&t[63], &t[61], &t[62], &t[ 1], tmp);
  42269. negy = t[0].y;
  42270. sp_1024_ecc_recode_7_18(k, v);
  42271. i = 146;
  42272. XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_1024));
  42273. for (--i; i>=0; i--) {
  42274. sp_1024_proj_point_dbl_n_18(rt, 7, tmp);
  42275. XMEMCPY(p, &t[v[i].i], sizeof(sp_point_1024));
  42276. sp_1024_mont_sub_18(negy, p1024_mod, p->y, p1024_mod);
  42277. sp_1024_norm_18(negy);
  42278. sp_1024_cond_copy_18(p->y, negy, (sp_digit)0 - v[i].neg);
  42279. sp_1024_proj_point_add_18(rt, rt, p, tmp);
  42280. }
  42281. if (map != 0) {
  42282. sp_1024_map_18(r, rt, tmp);
  42283. }
  42284. else {
  42285. XMEMCPY(r, rt, sizeof(sp_point_1024));
  42286. }
  42287. }
  42288. #ifdef WOLFSSL_SP_SMALL_STACK
  42289. if (t != NULL)
  42290. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  42291. if (tmp != NULL)
  42292. XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
  42293. #endif
  42294. return err;
  42295. }
  42296. #ifdef FP_ECC
  42297. #endif /* FP_ECC */
  42298. /* Add two Montgomery form projective points. The second point has a q value of
  42299. * one.
  42300. * Only the first point can be the same pointer as the result point.
  42301. *
  42302. * r Result of addition.
  42303. * p First point to add.
  42304. * q Second point to add.
  42305. * t Temporary ordinate data.
  42306. */
  42307. static void sp_1024_proj_point_add_qz1_18(sp_point_1024* r,
  42308. const sp_point_1024* p, const sp_point_1024* q, sp_digit* t)
  42309. {
  42310. sp_digit* t2 = t;
  42311. sp_digit* t3 = t + 2*18;
  42312. sp_digit* t6 = t + 4*18;
  42313. sp_digit* t1 = t + 6*18;
  42314. sp_digit* t4 = t + 8*18;
  42315. sp_digit* t5 = t + 10*18;
  42316. /* Calculate values to subtract from P->x and P->y. */
  42317. /* U2 = X2*Z1^2 */
  42318. sp_1024_mont_sqr_18(t2, p->z, p1024_mod, p1024_mp_mod);
  42319. sp_1024_mont_mul_18(t4, t2, p->z, p1024_mod, p1024_mp_mod);
  42320. sp_1024_mont_mul_18(t2, t2, q->x, p1024_mod, p1024_mp_mod);
  42321. /* S2 = Y2*Z1^3 */
  42322. sp_1024_mont_mul_18(t4, t4, q->y, p1024_mod, p1024_mp_mod);
  42323. if ((~p->infinity) & (~q->infinity) &
  42324. sp_1024_cmp_equal_18(p->x, t2) &
  42325. sp_1024_cmp_equal_18(p->y, t4)) {
  42326. sp_1024_proj_point_dbl_18(r, p, t);
  42327. }
  42328. else {
  42329. sp_digit* x = t2;
  42330. sp_digit* y = t3;
  42331. sp_digit* z = t6;
  42332. /* H = U2 - X1 */
  42333. sp_1024_mont_sub_18(t2, t2, p->x, p1024_mod);
  42334. /* R = S2 - Y1 */
  42335. sp_1024_mont_sub_18(t4, t4, p->y, p1024_mod);
  42336. /* Z3 = H*Z1 */
  42337. sp_1024_mont_mul_18(z, p->z, t2, p1024_mod, p1024_mp_mod);
  42338. /* X3 = R^2 - H^3 - 2*X1*H^2 */
  42339. sp_1024_mont_sqr_18(t1, t2, p1024_mod, p1024_mp_mod);
  42340. sp_1024_mont_mul_18(t3, p->x, t1, p1024_mod, p1024_mp_mod);
  42341. sp_1024_mont_mul_18(t1, t1, t2, p1024_mod, p1024_mp_mod);
  42342. sp_1024_mont_sqr_18(t2, t4, p1024_mod, p1024_mp_mod);
  42343. sp_1024_mont_sub_18(t2, t2, t1, p1024_mod);
  42344. sp_1024_mont_dbl_18(t5, t3, p1024_mod);
  42345. sp_1024_mont_sub_18(x, t2, t5, p1024_mod);
  42346. /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */
  42347. sp_1024_mont_sub_18(t3, t3, x, p1024_mod);
  42348. sp_1024_mont_mul_18(t3, t3, t4, p1024_mod, p1024_mp_mod);
  42349. sp_1024_mont_mul_18(t1, t1, p->y, p1024_mod, p1024_mp_mod);
  42350. sp_1024_mont_sub_18(y, t3, t1, p1024_mod);
  42351. {
  42352. int i;
  42353. sp_digit maskp = 0 - (q->infinity & (!p->infinity));
  42354. sp_digit maskq = 0 - (p->infinity & (!q->infinity));
  42355. sp_digit maskt = ~(maskp | maskq);
  42356. sp_digit inf = (sp_digit)(p->infinity & q->infinity);
  42357. for (i = 0; i < 18; i++) {
  42358. r->x[i] = (p->x[i] & maskp) | (q->x[i] & maskq) |
  42359. (x[i] & maskt);
  42360. }
  42361. for (i = 0; i < 18; i++) {
  42362. r->y[i] = (p->y[i] & maskp) | (q->y[i] & maskq) |
  42363. (y[i] & maskt);
  42364. }
  42365. for (i = 0; i < 18; i++) {
  42366. r->z[i] = (p->z[i] & maskp) | (q->z[i] & maskq) |
  42367. (z[i] & maskt);
  42368. }
  42369. r->z[0] |= inf;
  42370. r->infinity = (word32)inf;
  42371. }
  42372. }
  42373. }
  42374. #if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL)
  42375. /* Convert the projective point to affine.
  42376. * Ordinates are in Montgomery form.
  42377. *
  42378. * a Point to convert.
  42379. * t Temporary data.
  42380. */
  42381. static void sp_1024_proj_to_affine_18(sp_point_1024* a, sp_digit* t)
  42382. {
  42383. sp_digit* t1 = t;
  42384. sp_digit* t2 = t + 2 * 18;
  42385. sp_digit* tmp = t + 4 * 18;
  42386. sp_1024_mont_inv_18(t1, a->z, tmp);
  42387. sp_1024_mont_sqr_18(t2, t1, p1024_mod, p1024_mp_mod);
  42388. sp_1024_mont_mul_18(t1, t2, t1, p1024_mod, p1024_mp_mod);
  42389. sp_1024_mont_mul_18(a->x, a->x, t2, p1024_mod, p1024_mp_mod);
  42390. sp_1024_mont_mul_18(a->y, a->y, t1, p1024_mod, p1024_mp_mod);
  42391. XMEMCPY(a->z, p1024_norm_mod, sizeof(p1024_norm_mod));
  42392. }
  42393. /* Generate the pre-computed table of points for the base point.
  42394. *
  42395. * width = 8
  42396. * 256 entries
  42397. * 128 bits between
  42398. *
  42399. * a The base point.
  42400. * table Place to store generated point data.
  42401. * tmp Temporary data.
  42402. * heap Heap to use for allocation.
  42403. */
  42404. static int sp_1024_gen_stripe_table_18(const sp_point_1024* a,
  42405. sp_table_entry_1024* table, sp_digit* tmp, void* heap)
  42406. {
  42407. #ifdef WOLFSSL_SP_SMALL_STACK
  42408. sp_point_1024* t = NULL;
  42409. #else
  42410. sp_point_1024 t[3];
  42411. #endif
  42412. sp_point_1024* s1 = NULL;
  42413. sp_point_1024* s2 = NULL;
  42414. int i;
  42415. int j;
  42416. int err = MP_OKAY;
  42417. (void)heap;
  42418. #ifdef WOLFSSL_SP_SMALL_STACK
  42419. t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 3, heap,
  42420. DYNAMIC_TYPE_ECC);
  42421. if (t == NULL)
  42422. err = MEMORY_E;
  42423. #endif
  42424. if (err == MP_OKAY) {
  42425. s1 = t + 1;
  42426. s2 = t + 2;
  42427. err = sp_1024_mod_mul_norm_18(t->x, a->x, p1024_mod);
  42428. }
  42429. if (err == MP_OKAY) {
  42430. err = sp_1024_mod_mul_norm_18(t->y, a->y, p1024_mod);
  42431. }
  42432. if (err == MP_OKAY) {
  42433. err = sp_1024_mod_mul_norm_18(t->z, a->z, p1024_mod);
  42434. }
  42435. if (err == MP_OKAY) {
  42436. t->infinity = 0;
  42437. sp_1024_proj_to_affine_18(t, tmp);
  42438. XMEMCPY(s1->z, p1024_norm_mod, sizeof(p1024_norm_mod));
  42439. s1->infinity = 0;
  42440. XMEMCPY(s2->z, p1024_norm_mod, sizeof(p1024_norm_mod));
  42441. s2->infinity = 0;
  42442. /* table[0] = {0, 0, infinity} */
  42443. XMEMSET(&table[0], 0, sizeof(sp_table_entry_1024));
  42444. /* table[1] = Affine version of 'a' in Montgomery form */
  42445. XMEMCPY(table[1].x, t->x, sizeof(table->x));
  42446. XMEMCPY(table[1].y, t->y, sizeof(table->y));
  42447. for (i=1; i<8; i++) {
  42448. sp_1024_proj_point_dbl_n_18(t, 128, tmp);
  42449. sp_1024_proj_to_affine_18(t, tmp);
  42450. XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));
  42451. XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));
  42452. }
  42453. for (i=1; i<8; i++) {
  42454. XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));
  42455. XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));
  42456. for (j=(1<<i)+1; j<(1<<(i+1)); j++) {
  42457. XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));
  42458. XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));
  42459. sp_1024_proj_point_add_qz1_18(t, s1, s2, tmp);
  42460. sp_1024_proj_to_affine_18(t, tmp);
  42461. XMEMCPY(table[j].x, t->x, sizeof(table->x));
  42462. XMEMCPY(table[j].y, t->y, sizeof(table->y));
  42463. }
  42464. }
  42465. }
  42466. #ifdef WOLFSSL_SP_SMALL_STACK
  42467. if (t != NULL)
  42468. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  42469. #endif
  42470. return err;
  42471. }
  42472. #endif /* FP_ECC | !WOLFSSL_SP_SMALL */
  42473. /* Multiply the point by the scalar and return the result.
  42474. * If map is true then convert result to affine coordinates.
  42475. *
  42476. * Stripe implementation.
  42477. * Pre-generated: 2^0, 2^128, ...
  42478. * Pre-generated: products of all combinations of above.
  42479. * 8 doubles and adds (with qz=1)
  42480. *
  42481. * r Resulting point.
  42482. * k Scalar to multiply by.
  42483. * table Pre-computed table.
  42484. * map Indicates whether to convert result to affine.
  42485. * ct Constant time required.
  42486. * heap Heap to use for allocation.
  42487. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  42488. */
  42489. static int sp_1024_ecc_mulmod_stripe_18(sp_point_1024* r, const sp_point_1024* g,
  42490. const sp_table_entry_1024* table, const sp_digit* k, int map,
  42491. int ct, void* heap)
  42492. {
  42493. #ifdef WOLFSSL_SP_SMALL_STACK
  42494. sp_point_1024* rt = NULL;
  42495. sp_digit* t = NULL;
  42496. #else
  42497. sp_point_1024 rt[2];
  42498. sp_digit t[2 * 18 * 37];
  42499. #endif
  42500. sp_point_1024* p = NULL;
  42501. int i;
  42502. int j;
  42503. int y;
  42504. int x;
  42505. int err = MP_OKAY;
  42506. (void)g;
  42507. /* Constant time used for cache attack resistance implementation. */
  42508. (void)ct;
  42509. (void)heap;
  42510. #ifdef WOLFSSL_SP_SMALL_STACK
  42511. rt = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 2, heap,
  42512. DYNAMIC_TYPE_ECC);
  42513. if (rt == NULL)
  42514. err = MEMORY_E;
  42515. if (err == MP_OKAY) {
  42516. t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 18 * 37, heap,
  42517. DYNAMIC_TYPE_ECC);
  42518. if (t == NULL)
  42519. err = MEMORY_E;
  42520. }
  42521. #endif
  42522. if (err == MP_OKAY) {
  42523. p = rt + 1;
  42524. XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod));
  42525. XMEMCPY(rt->z, p1024_norm_mod, sizeof(p1024_norm_mod));
  42526. y = 0;
  42527. x = 127;
  42528. for (j=0; j<8; j++) {
  42529. y |= (int)(((k[x / 57] >> (x % 57)) & 1) << j);
  42530. x += 128;
  42531. }
  42532. XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));
  42533. XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));
  42534. rt->infinity = !y;
  42535. for (i=126; i>=0; i--) {
  42536. y = 0;
  42537. x = i;
  42538. for (j=0; j<8; j++) {
  42539. y |= (int)(((k[x / 57] >> (x % 57)) & 1) << j);
  42540. x += 128;
  42541. }
  42542. sp_1024_proj_point_dbl_18(rt, rt, t);
  42543. XMEMCPY(p->x, table[y].x, sizeof(table[y].x));
  42544. XMEMCPY(p->y, table[y].y, sizeof(table[y].y));
  42545. p->infinity = !y;
  42546. sp_1024_proj_point_add_qz1_18(rt, rt, p, t);
  42547. }
  42548. if (map != 0) {
  42549. sp_1024_map_18(r, rt, t);
  42550. }
  42551. else {
  42552. XMEMCPY(r, rt, sizeof(sp_point_1024));
  42553. }
  42554. }
  42555. #ifdef WOLFSSL_SP_SMALL_STACK
  42556. if (t != NULL)
  42557. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  42558. if (rt != NULL)
  42559. XFREE(rt, heap, DYNAMIC_TYPE_ECC);
  42560. #endif
  42561. return err;
  42562. }
  42563. #ifdef FP_ECC
  42564. #ifndef FP_ENTRIES
  42565. #define FP_ENTRIES 16
  42566. #endif
  42567. /* Cache entry - holds precomputation tables for a point. */
  42568. typedef struct sp_cache_1024_t {
  42569. /* X ordinate of point that table was generated from. */
  42570. sp_digit x[18];
  42571. /* Y ordinate of point that table was generated from. */
  42572. sp_digit y[18];
  42573. /* Precomputation table for point. */
  42574. sp_table_entry_1024 table[256];
  42575. /* Count of entries in table. */
  42576. uint32_t cnt;
  42577. /* Point and table set in entry. */
  42578. int set;
  42579. } sp_cache_1024_t;
  42580. /* Cache of tables. */
  42581. static THREAD_LS_T sp_cache_1024_t sp_cache_1024[FP_ENTRIES];
  42582. /* Index of last entry in cache. */
  42583. static THREAD_LS_T int sp_cache_1024_last = -1;
  42584. /* Cache has been initialized. */
  42585. static THREAD_LS_T int sp_cache_1024_inited = 0;
  42586. #ifndef HAVE_THREAD_LS
  42587. #ifndef WOLFSSL_MUTEX_INITIALIZER
  42588. static volatile int initCacheMutex_1024 = 0;
  42589. #endif
  42590. static wolfSSL_Mutex sp_cache_1024_lock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(sp_cache_1024_lock);
  42591. #endif
  42592. /* Get the cache entry for the point.
  42593. *
  42594. * g [in] Point scalar multiplying.
  42595. * cache [out] Cache table to use.
  42596. */
  42597. static void sp_ecc_get_cache_1024(const sp_point_1024* g, sp_cache_1024_t** cache)
  42598. {
  42599. int i;
  42600. int j;
  42601. uint32_t least;
  42602. if (sp_cache_1024_inited == 0) {
  42603. for (i=0; i<FP_ENTRIES; i++) {
  42604. sp_cache_1024[i].set = 0;
  42605. }
  42606. sp_cache_1024_inited = 1;
  42607. }
  42608. /* Compare point with those in cache. */
  42609. for (i=0; i<FP_ENTRIES; i++) {
  42610. if (!sp_cache_1024[i].set)
  42611. continue;
  42612. if (sp_1024_cmp_equal_18(g->x, sp_cache_1024[i].x) &
  42613. sp_1024_cmp_equal_18(g->y, sp_cache_1024[i].y)) {
  42614. sp_cache_1024[i].cnt++;
  42615. break;
  42616. }
  42617. }
  42618. /* No match. */
  42619. if (i == FP_ENTRIES) {
  42620. /* Find empty entry. */
  42621. i = (sp_cache_1024_last + 1) % FP_ENTRIES;
  42622. for (; i != sp_cache_1024_last; i=(i+1)%FP_ENTRIES) {
  42623. if (!sp_cache_1024[i].set) {
  42624. break;
  42625. }
  42626. }
  42627. /* Evict least used. */
  42628. if (i == sp_cache_1024_last) {
  42629. least = sp_cache_1024[0].cnt;
  42630. for (j=1; j<FP_ENTRIES; j++) {
  42631. if (sp_cache_1024[j].cnt < least) {
  42632. i = j;
  42633. least = sp_cache_1024[i].cnt;
  42634. }
  42635. }
  42636. }
  42637. XMEMCPY(sp_cache_1024[i].x, g->x, sizeof(sp_cache_1024[i].x));
  42638. XMEMCPY(sp_cache_1024[i].y, g->y, sizeof(sp_cache_1024[i].y));
  42639. sp_cache_1024[i].set = 1;
  42640. sp_cache_1024[i].cnt = 1;
  42641. }
  42642. *cache = &sp_cache_1024[i];
  42643. sp_cache_1024_last = i;
  42644. }
  42645. #endif /* FP_ECC */
  42646. /* Multiply the base point of P1024 by the scalar and return the result.
  42647. * If map is true then convert result to affine coordinates.
  42648. *
  42649. * r Resulting point.
  42650. * g Point to multiply.
  42651. * k Scalar to multiply by.
  42652. * map Indicates whether to convert result to affine.
  42653. * ct Constant time required.
  42654. * heap Heap to use for allocation.
  42655. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  42656. */
  42657. static int sp_1024_ecc_mulmod_18(sp_point_1024* r, const sp_point_1024* g,
  42658. const sp_digit* k, int map, int ct, void* heap)
  42659. {
  42660. #ifndef FP_ECC
  42661. return sp_1024_ecc_mulmod_win_add_sub_18(r, g, k, map, ct, heap);
  42662. #else
  42663. #ifdef WOLFSSL_SP_SMALL_STACK
  42664. sp_digit* tmp;
  42665. #else
  42666. sp_digit tmp[2 * 18 * 38];
  42667. #endif
  42668. sp_cache_1024_t* cache;
  42669. int err = MP_OKAY;
  42670. #ifdef WOLFSSL_SP_SMALL_STACK
  42671. tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 18 * 38, heap, DYNAMIC_TYPE_ECC);
  42672. if (tmp == NULL) {
  42673. err = MEMORY_E;
  42674. }
  42675. #endif
  42676. #ifndef HAVE_THREAD_LS
  42677. if (err == MP_OKAY) {
  42678. #ifndef WOLFSSL_MUTEX_INITIALIZER
  42679. if (initCacheMutex_1024 == 0) {
  42680. wc_InitMutex(&sp_cache_1024_lock);
  42681. initCacheMutex_1024 = 1;
  42682. }
  42683. #endif
  42684. if (wc_LockMutex(&sp_cache_1024_lock) != 0) {
  42685. err = BAD_MUTEX_E;
  42686. }
  42687. }
  42688. #endif /* HAVE_THREAD_LS */
  42689. if (err == MP_OKAY) {
  42690. sp_ecc_get_cache_1024(g, &cache);
  42691. if (cache->cnt == 2)
  42692. sp_1024_gen_stripe_table_18(g, cache->table, tmp, heap);
  42693. #ifndef HAVE_THREAD_LS
  42694. wc_UnLockMutex(&sp_cache_1024_lock);
  42695. #endif /* HAVE_THREAD_LS */
  42696. if (cache->cnt < 2) {
  42697. err = sp_1024_ecc_mulmod_win_add_sub_18(r, g, k, map, ct, heap);
  42698. }
  42699. else {
  42700. err = sp_1024_ecc_mulmod_stripe_18(r, g, cache->table, k,
  42701. map, ct, heap);
  42702. }
  42703. }
  42704. #ifdef WOLFSSL_SP_SMALL_STACK
  42705. XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
  42706. #endif
  42707. return err;
  42708. #endif
  42709. }
  42710. #endif
  42711. /* Multiply the point by the scalar and return the result.
  42712. * If map is true then convert result to affine coordinates.
  42713. *
  42714. * km Scalar to multiply by.
  42715. * p Point to multiply.
  42716. * r Resulting point.
  42717. * map Indicates whether to convert result to affine.
  42718. * heap Heap to use for allocation.
  42719. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  42720. */
  42721. int sp_ecc_mulmod_1024(const mp_int* km, const ecc_point* gm, ecc_point* r,
  42722. int map, void* heap)
  42723. {
  42724. #ifdef WOLFSSL_SP_SMALL_STACK
  42725. sp_point_1024* point = NULL;
  42726. sp_digit* k = NULL;
  42727. #else
  42728. sp_point_1024 point[1];
  42729. sp_digit k[18];
  42730. #endif
  42731. int err = MP_OKAY;
  42732. #ifdef WOLFSSL_SP_SMALL_STACK
  42733. point = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap,
  42734. DYNAMIC_TYPE_ECC);
  42735. if (point == NULL)
  42736. err = MEMORY_E;
  42737. if (err == MP_OKAY) {
  42738. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18, heap,
  42739. DYNAMIC_TYPE_ECC);
  42740. if (k == NULL)
  42741. err = MEMORY_E;
  42742. }
  42743. #endif
  42744. if (err == MP_OKAY) {
  42745. sp_1024_from_mp(k, 18, km);
  42746. sp_1024_point_from_ecc_point_18(point, gm);
  42747. err = sp_1024_ecc_mulmod_18(point, point, k, map, 1, heap);
  42748. }
  42749. if (err == MP_OKAY) {
  42750. err = sp_1024_point_to_ecc_point_18(point, r);
  42751. }
  42752. #ifdef WOLFSSL_SP_SMALL_STACK
  42753. if (k != NULL)
  42754. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  42755. if (point != NULL)
  42756. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  42757. #endif
  42758. return err;
  42759. }
  42760. #ifdef WOLFSSL_SP_SMALL
  42761. /* Multiply the base point of P1024 by the scalar and return the result.
  42762. * If map is true then convert result to affine coordinates.
  42763. *
  42764. * r Resulting point.
  42765. * k Scalar to multiply by.
  42766. * map Indicates whether to convert result to affine.
  42767. * heap Heap to use for allocation.
  42768. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  42769. */
  42770. static int sp_1024_ecc_mulmod_base_18(sp_point_1024* r, const sp_digit* k,
  42771. int map, int ct, void* heap)
  42772. {
  42773. /* No pre-computed values. */
  42774. return sp_1024_ecc_mulmod_18(r, &p1024_base, k, map, ct, heap);
  42775. }
  42776. #ifdef WOLFSSL_SP_NONBLOCK
  42777. static int sp_1024_ecc_mulmod_base_18_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
  42778. const sp_digit* k, int map, int ct, void* heap)
  42779. {
  42780. /* No pre-computed values. */
  42781. return sp_1024_ecc_mulmod_18_nb(sp_ctx, r, &p1024_base, k, map, ct, heap);
  42782. }
  42783. #endif /* WOLFSSL_SP_NONBLOCK */
  42784. #else
  42785. /* Striping precomputation table.
  42786. * 8 points combined into a table of 256 points.
  42787. * Distance of 128 between points.
  42788. */
  42789. static const sp_table_entry_1024 p1024_table[256] = {
  42790. /* 0 */
  42791. { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  42792. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  42793. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  42794. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
  42795. /* 1 */
  42796. { { 0x19c7ec6e0162bc2L,0x0637188544944dfL,0x17c27926760777bL,
  42797. 0x10da6b0430bab33L,0x10c5f8db9a96ea2L,0x1ae83300d763e9bL,
  42798. 0x15fe39cb9265633L,0x0b585ce52fa7d23L,0x18621db92da9f2fL,
  42799. 0x1936433ad2b3cf6L,0x0e177cb15aab052L,0x09a98d427f32466L,
  42800. 0x13ffa8ec11b88e7L,0x0f9fcff7890a58bL,0x19ed13a80e1a89cL,
  42801. 0x0692d7b36369d81L,0x00bafe528dceecdL,0x046fffcb50e24fcL },
  42802. { 0x0a4753ac03c0c83L,0x14e8c55e6e6badaL,0x0e23ddd6d925a39L,
  42803. 0x157eb1e6a5c7073L,0x1d0bc15c803f949L,0x194c612fb8133cdL,
  42804. 0x05dba16fd745a3fL,0x1687edd7b318d8fL,0x120618af445e3e1L,
  42805. 0x1eaacc72a732049L,0x1ca0ed413fb6799L,0x17fae1b0ea2f608L,
  42806. 0x1f3f5addbe450caL,0x1c65a66523eb145L,0x071242000dfbcc1L,
  42807. 0x1b06e9c291a78d6L,0x1f3e256d3294fcfL,0x01550903def1e00L } },
  42808. /* 2 */
  42809. { { 0x15b6dae01900955L,0x04e60e75a32b6d4L,0x041f9cbfa56e977L,
  42810. 0x0f40818668a18f1L,0x1952ea6ea1ae544L,0x04b982c88c89b83L,
  42811. 0x1443d53fdcd0db4L,0x0e149b600e97b49L,0x0fd5306f1916440L,
  42812. 0x05cff39c5922916L,0x036b59e127dd885L,0x143161b9a5c828dL,
  42813. 0x015e1ad49287b29L,0x0ddd150d56ebf8dL,0x088cde66b18ea07L,
  42814. 0x07790026f38b702L,0x161f402b2f0b0e5L,0x0461f593f85f89dL },
  42815. { 0x04ad3e1e513696fL,0x05d2e0c640ffd4dL,0x04d8f00cf44c0d4L,
  42816. 0x022f4a63783c5f8L,0x1aed610d53da6e7L,0x0ffab3a17632480L,
  42817. 0x144ab4cfa37dfa6L,0x1d7c955ae7c7bddL,0x0d983b465180f4dL,
  42818. 0x09b2934a817985aL,0x1e66aea24635fe6L,0x096ce01f8f34fc4L,
  42819. 0x1640bfd8c20ffe8L,0x0e9320debda2006L,0x098872f0e887485L,
  42820. 0x03d06f307288586L,0x110ace6500bb140L,0x03dfa0b1f128e21L } },
  42821. /* 3 */
  42822. { { 0x0174f88e3fd589eL,0x00bc86fcba5018eL,0x0f8cf9c1527f6d4L,
  42823. 0x1e2b249e69a12c4L,0x19b65ac58d091efL,0x14e167f77bce56fL,
  42824. 0x00af34b310988fdL,0x1bb02fb2064a59bL,0x1acf4f4d9a5f1ddL,
  42825. 0x030931aa808db5eL,0x112434bb4503274L,0x1d189b6d0da53eeL,
  42826. 0x16776b0fcc64092L,0x0f8b575b112f778L,0x0ef60a83a3007a7L,
  42827. 0x1c66ec506ce8309L,0x107757574e28956L,0x04c38f6e3382d3fL },
  42828. { 0x10b76d5776535f7L,0x06b01131ad9dc5eL,0x0b667485bd91485L,
  42829. 0x0eaa2b7eeb8184bL,0x1e9f1675fd4df3aL,0x1439f3925312de2L,
  42830. 0x17128f0d7bedd01L,0x115deb93467765cL,0x1a971b35e806b19L,
  42831. 0x1ae0652d1e34876L,0x17762638788d067L,0x199d2ab5b3c951aL,
  42832. 0x07248d34164cecbL,0x02e057b71767a20L,0x1e03ffc6aece045L,
  42833. 0x1daae7e97dd0438L,0x1add14df768c272L,0x01cbf68851b8b1bL } },
  42834. /* 4 */
  42835. { { 0x13e0bb2755c2a27L,0x1217cacac2e2267L,0x183c64a179834e3L,
  42836. 0x00ec4e7a1e8d627L,0x193c569ac3ecd0cL,0x08c0c53c0078428L,
  42837. 0x0d8efc139d2ad0dL,0x1fd24b15471092cL,0x08456617cb8c894L,
  42838. 0x1e31555157cb4d0L,0x08a02d6919a3662L,0x0b1d5325e9f4cd8L,
  42839. 0x193f401e99bc9dfL,0x0261c6072ed85beL,0x137dacf81853f87L,
  42840. 0x16c31aa622a3859L,0x0a41c7575ece143L,0x020123cc2efc9ccL },
  42841. { 0x1a251788f055746L,0x100200558f3707dL,0x13eeb0a49a5f16eL,
  42842. 0x12b69e8e81c3632L,0x1bb7ba547715211L,0x109cd2128048e84L,
  42843. 0x0a9f9e99d2186e6L,0x1dd75082767e6a7L,0x0afe771922443ceL,
  42844. 0x023469b1c23dde8L,0x1e7fd8f69250b45L,0x0383a84b68acc3eL,
  42845. 0x0d75ff46301563aL,0x159401649e1387eL,0x171c011081c8243L,
  42846. 0x05ce8d1e19b9790L,0x180ca4372fbfa03L,0x00d37e8f3645bceL } },
  42847. /* 5 */
  42848. { { 0x07a901a8d5116a3L,0x021ca597afa3fcbL,0x114983aebcec2e1L,
  42849. 0x0ec199f819c735aL,0x0c3f53f21e1be61L,0x088ddb5603f1e96L,
  42850. 0x0c30b760e38387bL,0x1708a8ea60e382bL,0x170dd4748920fe5L,
  42851. 0x1105f16f238c4b6L,0x1eb629649db1f06L,0x1987910ddc0e787L,
  42852. 0x176e831ac4026a1L,0x16280eb2cfedb79L,0x16a15d09a8d746aL,
  42853. 0x069ca15d3120a81L,0x15065dde0a4abd7L,0x014dbea6e0ab0a3L },
  42854. { 0x0b3c2cbcbf4e20bL,0x1aa47ac662262a2L,0x0d516c32b07c70fL,
  42855. 0x0a01f00c4273013L,0x066905e00c0f02bL,0x080c4673095c480L,
  42856. 0x1daca3c563b5e0dL,0x1c1803b88b07eaaL,0x129803272a45492L,
  42857. 0x1d2b11d07fc9221L,0x08ac00a7437105dL,0x08b24f01d0f5a25L,
  42858. 0x030d53f272b4125L,0x12180f468f5e7c8L,0x1f41e62eb9ba900L,
  42859. 0x024d83cbe7e5f46L,0x17e9342c31022b4L,0x02e84940129c124L } },
  42860. /* 6 */
  42861. { { 0x03a2b7eff2f780dL,0x134106bebb58eacL,0x011e1bdd2bb0d34L,
  42862. 0x0421047fd7c7865L,0x1b5e7bf40fd4221L,0x147c66913f20bf7L,
  42863. 0x0efb1443526da95L,0x16ea779cfac2f03L,0x19cfe3f222f3718L,
  42864. 0x1a2744fecef360fL,0x1154fcfeb26d55fL,0x108dcde60179e39L,
  42865. 0x029f0ae6b19d2d0L,0x125c5df04bb6415L,0x0e96a9f98f6fd78L,
  42866. 0x0678e9958fe8b2eL,0x05dc6eb623784ddL,0x00513721a0a17f7L },
  42867. { 0x081339facaa9a08L,0x18882a9237670c0L,0x05c184e4dd1d03cL,
  42868. 0x06485e05c312590L,0x1b5de98a8d8d410L,0x1df4a92415fe901L,
  42869. 0x0092627be51ad6aL,0x0f571a431726ed3L,0x1d5268e8966617cL,
  42870. 0x1173aa8c5be95c8L,0x11e5cffa359f0e5L,0x0a145602f8a258bL,
  42871. 0x1cc1a2946942e31L,0x098e3841b7a72f5L,0x1ee79428e644339L,
  42872. 0x015a15e9edd696eL,0x0ec68cbb175da12L,0x00ca4be30dc931bL } },
  42873. /* 7 */
  42874. { { 0x120b0c6417659a8L,0x15ce3c965947fb4L,0x0602da1de5ff1deL,
  42875. 0x03ceeb26c6ab6ceL,0x1561b1864caf58cL,0x07a4a328aadedb2L,
  42876. 0x02c80b9938d55e0L,0x0c1d615936e4535L,0x188594d782571bdL,
  42877. 0x0e6049cf1fd3c7cL,0x0d20c0ab0b4de57L,0x1ec1721e2888f71L,
  42878. 0x013ce4b3c1505fbL,0x0acdae0c5630874L,0x1a80888e693c9ebL,
  42879. 0x038f6bf4672e6f9L,0x1a6e578730b8dffL,0x04b5c8dc5a8bdfbL },
  42880. { 0x1a991f49aac087cL,0x17ba7367ed946e0L,0x1e697dd8035b398L,
  42881. 0x09f22ff39211adfL,0x1de52dbfd781cd0L,0x0b90c03bcb7afb1L,
  42882. 0x04df79f6d9380bbL,0x02c1e10edecdf48L,0x13271ee643ca1f7L,
  42883. 0x1cd902c3e255c51L,0x05c41ce520411f2L,0x121ab318b86f974L,
  42884. 0x0a6f20e125df9a1L,0x1a794816865b739L,0x18b73ee8c508813L,
  42885. 0x186a285a51972f9L,0x09ddf261b8aa3d3L,0x039f9e98ae7fe12L } },
  42886. /* 8 */
  42887. { { 0x186855be6fd3673L,0x1b857ce90a5bdaeL,0x1e437311b34cc26L,
  42888. 0x0ab2aa21bd1a665L,0x18c1251ce553c01L,0x060de4aba3504b1L,
  42889. 0x0ea3f35f3a96e17L,0x0f89ff428d0005dL,0x110a3cb7022fcd7L,
  42890. 0x14ccefde27502f1L,0x1683413be9d5badL,0x0f3db9dabfb066eL,
  42891. 0x03251fd56e4d902L,0x015262f8a40c920L,0x0d0416fa1d8ce92L,
  42892. 0x1caf062e1a26036L,0x1fa93998b0f7247L,0x04449a7b221b5d0L },
  42893. { 0x09f43b04713eabcL,0x1eec8d666e28bf8L,0x18efbc4f29f1329L,
  42894. 0x144b1030964fb54L,0x195dc2698b2e5a7L,0x1978a605465b096L,
  42895. 0x04d70d1a5d68b87L,0x1c63e5371dbc2e5L,0x0c3cbfd6ed40bc1L,
  42896. 0x1fa359f899311edL,0x16f9b7ec2dda074L,0x068aadb48689822L,
  42897. 0x18a8e43d985e31cL,0x05eeda7553e31f8L,0x153d631572c820dL,
  42898. 0x0d3b362d4187094L,0x0e174eacca246fdL,0x0068c4c5d8a9aa4L } },
  42899. /* 9 */
  42900. { { 0x0a73461e35ef043L,0x1b3ec9a4b5ab227L,0x1cef43e0e8f041eL,
  42901. 0x10a3a5386bac582L,0x11b1c1a4fad4b03L,0x1a1dcf1fa144153L,
  42902. 0x1d50d74af3d9952L,0x1838ef62b54557bL,0x15cb38a80dabe3dL,
  42903. 0x0fed0575240b39dL,0x05ad379ee43af85L,0x1c4a5791e7b10d3L,
  42904. 0x1637c4e42484f87L,0x0bd3d7ec56f681eL,0x132e4eb97b7999bL,
  42905. 0x1472301bb2b4543L,0x060a55cfd2546fbL,0x015ed58ee237c17L },
  42906. { 0x04de22bfa6fed61L,0x0c552e646eca73dL,0x17c41c488bd7291L,
  42907. 0x1fcb5fe6ee7c6e5L,0x0a738e6d06a4b44L,0x18f89b5e1685d3aL,
  42908. 0x0a444691c38757cL,0x10aefff2675c205L,0x08b380a50310c78L,
  42909. 0x19e01143c1fe2d6L,0x1a249511c9741a7L,0x1c2cb5908443d8cL,
  42910. 0x0fcfda6e8a878f0L,0x1c66955d4d1d78dL,0x1b43ab8060fb4ddL,
  42911. 0x0c82a659b7ac104L,0x120b3234661cbeeL,0x01a9f5c495ce080L } },
  42912. /* 10 */
  42913. { { 0x0fdcad610b5521eL,0x0da202973817864L,0x00363ff69270684L,
  42914. 0x1597e6d75ac604dL,0x0c10a2d7cdb9654L,0x1873f03dac6708aL,
  42915. 0x0a04c79747df798L,0x0ff197c7afacec1L,0x1eb35866b6480d7L,
  42916. 0x0394679bf81b10cL,0x0197b50aa29d5d6L,0x1e3b20d450e1babL,
  42917. 0x04a51f906b283f1L,0x0a1d90543cf11fdL,0x079dd53cab1ba0dL,
  42918. 0x02ddc9e16c6f370L,0x07d57fbc0d48400L,0x046d103b8f310dbL },
  42919. { 0x0855004ecce65ecL,0x0868fdba40c2f1eL,0x0f29e1e5eb49db4L,
  42920. 0x00efca955ac97cfL,0x1e0df0ff43444dbL,0x0843520bdb5864dL,
  42921. 0x1568e3f1095b015L,0x171f2a58877fae9L,0x0501e005a01c4edL,
  42922. 0x08b96fe252bf194L,0x0339394d75bb8f5L,0x1cb818ca1231b68L,
  42923. 0x07857561fcbaef1L,0x1a5112637428a2fL,0x103828b91a14da8L,
  42924. 0x007f8d351c44e1dL,0x15fb3f52247242bL,0x04317aaf161df5eL } },
  42925. /* 11 */
  42926. { { 0x16a390f226049feL,0x152bc6e5de4fd96L,0x12925d8d3edf324L,
  42927. 0x0c7bd4b1274a5fdL,0x0a49e9162b340cbL,0x0f20f9d1cf99c51L,
  42928. 0x1f9009acb7cf652L,0x1458e38f9b60cb4L,0x04a9b84a0468281L,
  42929. 0x1f75a81b98f7765L,0x0244d1db2edc958L,0x13537294cf19cdaL,
  42930. 0x1b808fd9f10cf97L,0x1057e2dcda26c61L,0x096f9a79836984fL,
  42931. 0x1ce9ea5b9cfbc7dL,0x1903a5d6864dc1eL,0x038d594489de403L },
  42932. { 0x1618fc43b5b60adL,0x1af18250618c267L,0x0732f100cc082beL,
  42933. 0x07b63818cda4470L,0x06112a8d33cf895L,0x0b3d434e4ca726dL,
  42934. 0x134a75eab8b0f46L,0x1f7851aa926b6f5L,0x18075bd136c9a57L,
  42935. 0x0e01b9f4e4213fcL,0x12863464c897d72L,0x1a2688580318597L,
  42936. 0x07fbb3a72773777L,0x0cb16e0c75f2f6aL,0x1022019c10df524L,
  42937. 0x1e6b9e7383c125bL,0x06503e9c6f715ffL,0x046843ddb2f1b05L } },
  42938. /* 12 */
  42939. { { 0x02123023fdc1844L,0x113f7882f562b5fL,0x181bc5a28d21bb2L,
  42940. 0x1bc3af499643074L,0x1ef5d43e295f807L,0x1812e3b92353193L,
  42941. 0x138fab850c8171dL,0x0ea97bf8f95e690L,0x0ec939895df52c0L,
  42942. 0x1732afb6bd4e560L,0x17f8822ebb76c20L,0x0fc8a4fbce6330bL,
  42943. 0x1c313de1ea79c81L,0x0627b65d986707dL,0x0ec833677e56e27L,
  42944. 0x1f603e55dbe3debL,0x1ecfc1e0a891a8cL,0x0112f69a531f6dbL },
  42945. { 0x013154dbabb1a85L,0x06d738f352b2d1fL,0x155aad2c403f4f6L,
  42946. 0x1dd78f1c35a642fL,0x08e73d37d44d934L,0x0f21e5810a990daL,
  42947. 0x02416ef242fe880L,0x1427847e3a04ea0L,0x02a2e5000c86691L,
  42948. 0x0595d693032c20eL,0x1072bcc009ad802L,0x05e8a4ed9cc22baL,
  42949. 0x0715932ffb1712cL,0x153a657900e261fL,0x014de91e25384f5L,
  42950. 0x192fc05adebbe18L,0x07ba8fb7602c2b1L,0x03095b072e8443eL } },
  42951. /* 13 */
  42952. { { 0x1d495cfba245d6bL,0x065dbd1671ffb77L,0x0b037fd7fbb973cL,
  42953. 0x119e518d4649b45L,0x0308a56b90c914fL,0x0b901a397eda86aL,
  42954. 0x127a40f6fdde44fL,0x1039f4bd9230455L,0x10dde73c83aea3eL,
  42955. 0x02dd4b13314489cL,0x1d922f29ab2f4d5L,0x0edd3140d0754a5L,
  42956. 0x0ca378ed52ff6f2L,0x042d60ec929b69dL,0x0f2129cd4f0b152L,
  42957. 0x082cf95fea5b401L,0x06e3971f81c3768L,0x007b99a70e96bccL },
  42958. { 0x1bb5c836596067eL,0x0a70c9c60cc0357L,0x059ce72c3730cf9L,
  42959. 0x1a84806bf3050bbL,0x1fef90952b53f43L,0x07ab8d1c6298fc6L,
  42960. 0x09e1e43efa3936cL,0x04134183da54739L,0x02fecc1d6606f26L,
  42961. 0x0e44858b95be5a5L,0x129bef32ede1a27L,0x0105fce7dc93867L,
  42962. 0x17fcb66c48d1b11L,0x0370a2b9ac85be8L,0x0fab6164d5ac29aL,
  42963. 0x061f6ebad05880aL,0x149b2ae55fac54dL,0x033b1b5397c5774L } },
  42964. /* 14 */
  42965. { { 0x18063bcb91d6beaL,0x11d17491f65cb31L,0x064b189eb29ab89L,
  42966. 0x14ef5f3cfd3af61L,0x04aafebbc6ed001L,0x02ad48490a56679L,
  42967. 0x126768d592e59e0L,0x14a01333639c04eL,0x1e413a4e1e46a06L,
  42968. 0x02e89fb1728f7f3L,0x01f4d26ea10efa8L,0x104a63062b3c6bdL,
  42969. 0x1a546019230a633L,0x1bfe8e793011f45L,0x1cbf54e6c41dc86L,
  42970. 0x15e708d6aa857fbL,0x165b314f4f81c18L,0x00437cc3b305644L },
  42971. { 0x07019548cbb9850L,0x05b98510696463bL,0x015d4cd59c31884L,
  42972. 0x0a064975d48109aL,0x076ee9b43ecdc59L,0x07fd32303fe2f96L,
  42973. 0x118f3ce4f403d10L,0x1cfc0222f2c5b82L,0x0f00b82519c7725L,
  42974. 0x0f3039b2de8e8c3L,0x015530b3dcaab0dL,0x1fbddf4692fbe7bL,
  42975. 0x0cf646ad11b4dd0L,0x0fbdc756eb89134L,0x01b7f941f082beeL,
  42976. 0x0a934c612d3a9f8L,0x01076b7df1c7245L,0x0340fca01f30d74L } },
  42977. /* 15 */
  42978. { { 0x0ad5163c9a0623bL,0x014abb3fd5c6a3eL,0x03b206bdf1f36feL,
  42979. 0x11d2cdab8459956L,0x10d4e41c469e38cL,0x159ace1a2186a97L,
  42980. 0x0049d0981d68a94L,0x082485ba7c6677aL,0x0cda3f6359fed23L,
  42981. 0x0f99b986bea97fdL,0x1d5bc1d9030fbd3L,0x0438377bcaf8bffL,
  42982. 0x0aeb8bb3364783cL,0x15684202ec3c251L,0x0d8af507b1f14cfL,
  42983. 0x1a95e96fe2847f3L,0x10a5543145c7075L,0x0064ef4a55d302cL },
  42984. { 0x0d7273595d5682bL,0x0214197613b76c7L,0x1b562cda8349c47L,
  42985. 0x090931511fa3e95L,0x0480f45162ab40cL,0x0e7ff12c647e312L,
  42986. 0x0d6762f23292edeL,0x0bb2156b078e034L,0x0aee31a733fd5d1L,
  42987. 0x152acbde489199eL,0x072b92db0f8f080L,0x085853270110203L,
  42988. 0x1df47c8199e5130L,0x195007490700141L,0x1d6b8ee435a3963L,
  42989. 0x06164d3c5be834eL,0x196b8d2eca5871cL,0x0399ee5075d8ef1L } },
  42990. /* 16 */
  42991. { { 0x1b495d04b59213aL,0x1901cc6b810077aL,0x0698ad9dc707299L,
  42992. 0x08573d619697961L,0x0cdba21226adeedL,0x044868f5aa23aa4L,
  42993. 0x11ad0386aff37c2L,0x070a4a132c6d31cL,0x1e1bff0b082e9c1L,
  42994. 0x0c4f266a884cd38L,0x0326f326e4731e8L,0x0fb826fd897c46cL,
  42995. 0x01d1519f6e9bd4dL,0x07c19281e81ab29L,0x1ba8ad2fd7db5e3L,
  42996. 0x06339c86020631bL,0x1d7c3132494ef4cL,0x01559dea3878fd3L },
  42997. { 0x153b680922c9fbbL,0x13ee4078b6368abL,0x04d6eb05bbf21a7L,
  42998. 0x0908da3b370688aL,0x12d62c214326a3bL,0x14956ada8bff71dL,
  42999. 0x0b04da416be882cL,0x11a54ae2634595bL,0x0cd904d8febdbcaL,
  43000. 0x1f6d4379f9b2fd9L,0x1ec82371faa8737L,0x150948bcef80e12L,
  43001. 0x0ccf5d118e89a35L,0x0fb74cf420bd031L,0x1e821f4f03012a0L,
  43002. 0x055a5888e096174L,0x0296f8a27d13ea2L,0x049d25a0b2613e9L } },
  43003. /* 17 */
  43004. { { 0x0271bc11f1efb7aL,0x1347319fe6606eaL,0x03c6c47d42a2b93L,
  43005. 0x1f5e0ec1133b379L,0x043d0e035430398L,0x11ea60a2f1217daL,
  43006. 0x0b425cfb09467dbL,0x01f56e1ef217537L,0x0de612ad5f9add1L,
  43007. 0x01bf2a70a74a15aL,0x095b4f76e2da2aeL,0x0678358548102ebL,
  43008. 0x10f0c80f94e85b2L,0x04c6da7cfc7fb61L,0x09f73752dfcfedeL,
  43009. 0x0712b458c089e8bL,0x163f3abb2f6fe3dL,0x01a16706b99773bL },
  43010. { 0x1261394cf491b1fL,0x1776b8c84f1caf5L,0x156a7f936fab72aL,
  43011. 0x1a927ac09bb9880L,0x1ce5ebef17a6611L,0x0c4e5add222d1d0L,
  43012. 0x0101ba0b8a1638eL,0x0ab72de850507ebL,0x099877b99a156cfL,
  43013. 0x1c83533270b3507L,0x074d4eca5db44ebL,0x1e4e6d8c34039d4L,
  43014. 0x13b0f55d86efc16L,0x0759a600ed82621L,0x1980a00f2d2c9a6L,
  43015. 0x07d8a71a0fef055L,0x12043ac3bcb43beL,0x022afa579f0ab7eL } },
  43016. /* 18 */
  43017. { { 0x057f262754ec21cL,0x06a64f1d0dd1c60L,0x034445b07fa4fabL,
  43018. 0x09d599156c74042L,0x0a6f32cae4ea4e9L,0x1cbae718e0064d7L,
  43019. 0x087a572d88e761aL,0x116ca9abb19429dL,0x1230d31f45067fcL,
  43020. 0x05dc865b1aaff65L,0x007b3b705cba392L,0x01519600ce6ef1fL,
  43021. 0x01e162d01228838L,0x02d78a2e0cd8170L,0x0b70d503821e81bL,
  43022. 0x180cde09b916f6eL,0x1b7f70ef2148de3L,0x0278a412189804fL },
  43023. { 0x0004fce6e2055e2L,0x123f543619033afL,0x16557e76aa8a278L,
  43024. 0x1f9d6fec769d797L,0x063784a0d15f212L,0x1b0128af662e0fcL,
  43025. 0x0a5514ece002dd5L,0x033d726038714d4L,0x00f16ba18a13cddL,
  43026. 0x189e928c43e1692L,0x08d6166a504fda0L,0x0bcdfc7faf8bf32L,
  43027. 0x1416e0ee0542340L,0x1fd6d55833c5759L,0x02111c47cef9eecL,
  43028. 0x05fecf203f45905L,0x10bc950db304d66L,0x03a6ae96a1e008bL } },
  43029. /* 19 */
  43030. { { 0x1002dc02b5bfe11L,0x1a086a96990f3d1L,0x1d9659e6ea241ccL,
  43031. 0x08d0b646dc2b241L,0x146f60400e248c1L,0x038bf8467d5aca1L,
  43032. 0x115da7d5ebedd03L,0x08e1b756518cc08L,0x10fa099689cdc32L,
  43033. 0x0f0157161187682L,0x185553916fbdd10L,0x13059c9af6de1b2L,
  43034. 0x075e62d22e9688aL,0x1e965d147d6f7d6L,0x1f1d27ebc544a9aL,
  43035. 0x0b4d6f10d1cc57cL,0x02988048d81ae9fL,0x0358d2a2162c2bdL },
  43036. { 0x15ab9ad43242066L,0x178da966651574fL,0x1b1e623b71382bfL,
  43037. 0x02068361ab63687L,0x150aab370d0c00fL,0x13254ca6b45c7bdL,
  43038. 0x1a13a6a3939bfceL,0x0b8330671f6fe34L,0x18bc0e748351a0fL,
  43039. 0x0567966ed62228aL,0x14e6657a7fddacbL,0x167e2c7260ab829L,
  43040. 0x05888d837654a01L,0x19193bd8b561f75L,0x076eefee1366a69L,
  43041. 0x0e2f132264d23c2L,0x0c8597717aeabb6L,0x026109a9345d8a5L } },
  43042. /* 20 */
  43043. { { 0x06fe0a695532833L,0x111476b13683397L,0x0f659279cef6af2L,
  43044. 0x15e0789818455deL,0x15169b452083a87L,0x083544f4aa73ae9L,
  43045. 0x13e415dd427b9d1L,0x12293964edc55d5L,0x108275d77fa409fL,
  43046. 0x0f5b79ef85deb5cL,0x080b2f904c9c118L,0x184363893163290L,
  43047. 0x08361fee5935f3fL,0x087028f9bb6345dL,0x039c10a8632ef65L,
  43048. 0x03d16470950f263L,0x134292abead80ddL,0x032b89e14ae1be1L },
  43049. { 0x0cca8e9ceb77b9aL,0x1f39391db4a34eeL,0x1b9a8075aca0be5L,
  43050. 0x1ab57d9bfd8ed57L,0x09290d703925203L,0x18a21c44a240411L,
  43051. 0x11f0fe64c5092c0L,0x04e08413be2f9a8L,0x17c6f2059c855c8L,
  43052. 0x0bebc312b607034L,0x16dbf904b653136L,0x0b23329883bab53L,
  43053. 0x01c89e21a319a64L,0x03501f87091a455L,0x05bfab35a412d43L,
  43054. 0x0d276ab82a2ad4cL,0x0384e36d1b57cc7L,0x035874cb61dd71eL } },
  43055. /* 21 */
  43056. { { 0x0789fabcceced00L,0x1f38d72dbd53319L,0x09a4b77af37cc8dL,
  43057. 0x016c3b5b1f0f65cL,0x135f803cb724512L,0x128786f08f2f246L,
  43058. 0x0ae4bed37d75e63L,0x07ac1dcd16979a5L,0x198ab2f5c1ce336L,
  43059. 0x0dd1ced3e6a1323L,0x15cbae0fd3ecfc5L,0x1d11cade11b634cL,
  43060. 0x1e172562c20f77dL,0x052c787a0ba1bb0L,0x1475b8af8d27fe2L,
  43061. 0x1e769c09b4e3709L,0x1f8368f03429e9fL,0x020115102b3c111L },
  43062. { 0x07bbd0583847375L,0x0b5b11fa28d7829L,0x09352cb1fc60eb9L,
  43063. 0x168a4b731ac331eL,0x0e0884b5ee323f5L,0x0963bb54ec69cd0L,
  43064. 0x1055340175fdbecL,0x179ae38907ce117L,0x18ca6fd28742541L,
  43065. 0x179ee66fc1cbeedL,0x14c494fb33c90c2L,0x0210b1b0371b701L,
  43066. 0x0171391f68c743aL,0x19ddb2bf9fa4759L,0x191f8c524ebfe20L,
  43067. 0x0f3ec3a2bdacc0fL,0x15610159b11e082L,0x01890bce5925354L } },
  43068. /* 22 */
  43069. { { 0x14cc3ca07615ac2L,0x12f32090d6ac0d4L,0x05be9e61ade6161L,
  43070. 0x173abc1e3b5c8ecL,0x1d9457ea395a40eL,0x1432ecd48a19321L,
  43071. 0x0ba32379b5a8fe8L,0x1960ee3b72c2029L,0x077a7cce6976a87L,
  43072. 0x1ef21708a1d07b0L,0x0f3027664f64d29L,0x0d2731d8987bc40L,
  43073. 0x183a25df4b92018L,0x115816b5ebbaa36L,0x169c6242b67ad1dL,
  43074. 0x04377f555e411a0L,0x1ea5238181f4312L,0x020beb63c399a88L },
  43075. { 0x0bd81b70e91e9a8L,0x0020c61b86b599eL,0x042a3aa88dcdccdL,
  43076. 0x08d8facead04bb6L,0x14c33ded8f2b09eL,0x0af1fdf144774dcL,
  43077. 0x1a22336109aec5aL,0x0c54c2ed90db9d3L,0x13f4c89226165e3L,
  43078. 0x0a7208fb031fd84L,0x1eb08323e781314L,0x0d39bfa55ac2d20L,
  43079. 0x048452199acef74L,0x09561a315d185d7L,0x0b520b4c1a04a4cL,
  43080. 0x0132a0237d0e792L,0x00aff4cbf89e833L,0x0010c4ea968a385L } },
  43081. /* 23 */
  43082. { { 0x1e419dd92599c69L,0x0110dbff6196539L,0x0f4826efeff56e5L,
  43083. 0x08c7db12b7657f3L,0x1f486f7961ea97aL,0x0a0d1cb3048a359L,
  43084. 0x104d6f471e817f4L,0x0f78f3d919f07acL,0x17f8fd42f988350L,
  43085. 0x1e5a9db8bd9e813L,0x1637359f296886bL,0x01599a292f0d0ccL,
  43086. 0x0e34b95067a6a6cL,0x0fa24ac60b79eb8L,0x0a00848dc48238fL,
  43087. 0x058e3a5bac9cdd8L,0x0fa33b2c4ab3078L,0x03ddfc55ea908bbL },
  43088. { 0x09e4aafa78b981aL,0x1a71b182764145fL,0x1ce4e5677a8de22L,
  43089. 0x064816738e188b9L,0x08383b7d70a9bddL,0x1d081324ce6bee9L,
  43090. 0x1c6ccc1a42cb8c1L,0x09044c5ab31dd25L,0x0c62d77deb4725aL,
  43091. 0x0b792de3de1d507L,0x162d97457bdfea8L,0x043a172dad1ec5bL,
  43092. 0x03a00f1906d9792L,0x15ba63a05c9442eL,0x15d888be91dae6fL,
  43093. 0x0a09e42fbb76b8eL,0x16bc2782c305788L,0x0430684b67c0938L } },
  43094. /* 24 */
  43095. { { 0x0bc337d4d79bbf9L,0x1f55c34fba7c07fL,0x0254cc41354d754L,
  43096. 0x1432df172ffe6d4L,0x15ce69092ab820dL,0x141baa4b0e9e8fbL,
  43097. 0x12e6ec65fb01011L,0x1474d19c37f274dL,0x1503456ffc5f021L,
  43098. 0x08516d8c4a07fedL,0x143e3fbc010826dL,0x02ee092cb0eaef8L,
  43099. 0x198bb8770ad635dL,0x103c729f392bb36L,0x1f20de23866c0a2L,
  43100. 0x073406c9a9995f3L,0x1201a3df411f0ddL,0x03f40722101d6fcL },
  43101. { 0x15f8a57539a1ddfL,0x073d7772432b125L,0x047605808787492L,
  43102. 0x17fa6da58838f69L,0x0aec00d92e7b871L,0x09f8d9ed1c5a820L,
  43103. 0x1e35bca09d84986L,0x066d387fd0df63eL,0x156c8b786e827acL,
  43104. 0x143fb639a43e47bL,0x1c885c677b96f05L,0x0e7ffe732831571L,
  43105. 0x14a9027c8004e84L,0x150e971479c2600L,0x197bbc6659efa6aL,
  43106. 0x106f90d2d0da7c0L,0x063737c6b08c7bdL,0x02ee55ae8cf45ecL } },
  43107. /* 25 */
  43108. { { 0x184283a9a7d772bL,0x0f292f2a04acd83L,0x002219052ad5ad2L,
  43109. 0x053ae96552a8d76L,0x003b0b1bd444816L,0x09fc35933c48569L,
  43110. 0x00f1c79ea0af323L,0x19e26a57f6bb0b5L,0x1f29f16e3fad07cL,
  43111. 0x01531dc20f0621fL,0x1c8b15acde7fbf0L,0x0ca762489e4d209L,
  43112. 0x1f3a28bdea19d8aL,0x1b6a2ae7331adb6L,0x1fcdcd462da2147L,
  43113. 0x17b56e958503139L,0x098ad40f9df8b2cL,0x0046616cf56e4eaL },
  43114. { 0x06a6866c170c84bL,0x04f45ad24d24217L,0x03834132264aee6L,
  43115. 0x10c3674846f61c0L,0x10d0189955ad347L,0x0806599e4a92285L,
  43116. 0x1db438e4885578cL,0x0a6324cb6dde064L,0x00fe8595a76d42bL,
  43117. 0x14b6f707e31a9dbL,0x18372091be24f82L,0x057de14e9974ec3L,
  43118. 0x043fdfad9b4ec90L,0x07edb4bab080434L,0x1dd642975a98391L,
  43119. 0x0146e7ea75590fdL,0x1b0d29e6be01287L,0x04c8fd6e0aad52aL } },
  43120. /* 26 */
  43121. { { 0x0bc4b0fb4844ffeL,0x1138a307c5c38c1L,0x0389338fc7cdce4L,
  43122. 0x082c6a33d915800L,0x08288b5ff0d548bL,0x0e4d383d57c215cL,
  43123. 0x1f59e7a2c3130afL,0x18740daa2a4974bL,0x0d0b1afa0f93cdeL,
  43124. 0x004aadd6fc4fc78L,0x0fa4b7ba8cb248aL,0x1f327fc0b7c90d9L,
  43125. 0x15fa6919aa0cae3L,0x17078dc5f930384L,0x1b3e6203d51d079L,
  43126. 0x123ae55da3ee861L,0x1e99296f76b7349L,0x03367c69412cf87L },
  43127. { 0x101905b226f5868L,0x174460b484f4f4dL,0x045928dfad53040L,
  43128. 0x119302c64657a11L,0x06bac53cf72253eL,0x15557b9bfc274ecL,
  43129. 0x011b8b8d49152bfL,0x05ccf90deee5940L,0x086bce50e666337L,
  43130. 0x151d4b05b4a8502L,0x06535ff06aea4fdL,0x02578264dcdcc3fL,
  43131. 0x042e56b0051957cL,0x02c93a064db2c7fL,0x1fc9a96734a5ff2L,
  43132. 0x05d76eca99d362eL,0x048aaa699dba79dL,0x02fe5062d0765b2L } },
  43133. /* 27 */
  43134. { { 0x06e25f3569a6663L,0x0bf73f3552653f1L,0x169a3462e030256L,
  43135. 0x0a4524ce604b499L,0x07387209450602bL,0x199d29cd7afb280L,
  43136. 0x0a547fbbb6cd099L,0x1341eb9ced10caeL,0x1872a360b8398aeL,
  43137. 0x01a3d4015987b61L,0x04ec8c685885618L,0x1f25dcd8dbd9a42L,
  43138. 0x085cbcf9e66fd9cL,0x15d1ff4242f852dL,0x1b35c9f5e969b90L,
  43139. 0x0342155fcce40a3L,0x0b4e09c6bb2a208L,0x032bd65f85cb9d8L },
  43140. { 0x130466fc274c8d4L,0x128bb1854ca6898L,0x0329c1e50d7d09dL,
  43141. 0x0dd712f40c42e4bL,0x161ee1304485040L,0x0bbc5df9c6ff772L,
  43142. 0x0e7a447d3eb3ea8L,0x064ecb8cc2f7357L,0x1b135499bd8f109L,
  43143. 0x075b19bd39dc8acL,0x0733c5bdfa2dab0L,0x007430fbdea7e58L,
  43144. 0x09830b9c625b32cL,0x1788729c44d68eaL,0x17d56f05cd7ab8cL,
  43145. 0x1b61b6397b3853aL,0x1bb42428c47e539L,0x01e96d209642959L } },
  43146. /* 28 */
  43147. { { 0x1702b6e871f2865L,0x1b1cf8a14906b4bL,0x0a8116d618455b2L,
  43148. 0x03e7627024650a4L,0x112206e8f3943adL,0x06acf5736110053L,
  43149. 0x1dd670a24396a8dL,0x0cf56a5fa81ed6fL,0x0f522c8de180bf5L,
  43150. 0x00f4bd9566771cbL,0x1d606713a972ec6L,0x0bd156a3a7dfc06L,
  43151. 0x0abcb50fd80d998L,0x0bf0e406f1364b6L,0x058d5f7ee75ac4eL,
  43152. 0x18ff6b0563029efL,0x06189a7822107f4L,0x001577796e01abfL },
  43153. { 0x1a7926f2c7ec9beL,0x1983f392c590095L,0x08431be9ad28a4bL,
  43154. 0x13c5798b56e9cc5L,0x1bb8c07380c0854L,0x0f8ca6da0b06dc3L,
  43155. 0x12a7357bc14a4caL,0x1a21d71b428dbb4L,0x00b5d43d215ea23L,
  43156. 0x075f7817e1a5fd7L,0x0d9342121d5e9dbL,0x06d05a69994759aL,
  43157. 0x021d2d95e2c1401L,0x1c37551404e533aL,0x0597fb30ff475b9L,
  43158. 0x124073d6226db45L,0x0b048871baac077L,0x035a23600a58ad7L } },
  43159. /* 29 */
  43160. { { 0x019eb2e25e8fe80L,0x1bc834c11c50be4L,0x065a07906124ad7L,
  43161. 0x0d31d4da8bade3dL,0x1fd02e4058ad8adL,0x0920b6add72d6a5L,
  43162. 0x1f28405b70c9ea0L,0x1231663530b4668L,0x10b4da61082a653L,
  43163. 0x05c8d96da461afdL,0x1a05f34aabe3107L,0x09079bfb9b813d2L,
  43164. 0x0112b692541a630L,0x1c51504bb82ac9bL,0x1314a057f735c4bL,
  43165. 0x0c12ab356c4746bL,0x12f30c8ebe0932bL,0x04309a125d84702L },
  43166. { 0x0902063b2231d8aL,0x11194ecd30b3394L,0x1f9c1c6a7c9ec3dL,
  43167. 0x00c07e08fd55f41L,0x1d92a1c36bcd896L,0x0a41db08c6653b7L,
  43168. 0x14988d05398adc7L,0x0b5424799bb74e0L,0x11a576437fd9b5cL,
  43169. 0x0980de1264687d1L,0x02b51040909f369L,0x0bc1a754d8052deL,
  43170. 0x00072a39960e6fbL,0x02069fd6e6c6244L,0x047550536bf284aL,
  43171. 0x0e69a53e9947bbdL,0x17c0037c5988441L,0x043199d4cce67f2L } },
  43172. /* 30 */
  43173. { { 0x013a751ecf53b40L,0x1637917bc52a169L,0x038bc4eb95b73fcL,
  43174. 0x1e1cc2e91c1eb3eL,0x172c414591f8ccbL,0x0e6e5b8556f65ceL,
  43175. 0x1f1c1acbb614932L,0x0051c016e583d5fL,0x089b24285aa7281L,
  43176. 0x13f53f05b3ce57dL,0x0e30993c29bdbeaL,0x02e61d00872eba5L,
  43177. 0x05c85730497ed7bL,0x04c3749f2d49f5aL,0x08302bf24afd750L,
  43178. 0x1875ea4d6b538d4L,0x0c90adf47c9b99dL,0x009592ff15d1016L },
  43179. { 0x1b8d78a33eea395L,0x09b0c7b19fe2e04L,0x18a49c3b3bbf1eaL,
  43180. 0x118c51da18fd042L,0x01d68939524779bL,0x176e4848edae50dL,
  43181. 0x1cefe189b863961L,0x039fc047d17fd67L,0x06279fde1025017L,
  43182. 0x09763ee2af0b96fL,0x1a1a571b5329179L,0x10f17b7821e288bL,
  43183. 0x086fc3835e42de3L,0x1f085b291588a6fL,0x039e3fa7eae9159L,
  43184. 0x015948223b05472L,0x174576b61c2aedfL,0x010b13cd4ba5665L } },
  43185. /* 31 */
  43186. { { 0x14cdabf4047f747L,0x1119ee098ad0f60L,0x0f4d0397429c0f2L,
  43187. 0x13768270d2b3cf9L,0x0f01fbd81fd0c4eL,0x15c11e8c4e84588L,
  43188. 0x002854112710a9dL,0x1c9038449427316L,0x108084e4f8e8179L,
  43189. 0x0c57cca34c720f4L,0x038df15842fcbbfL,0x087f4fa4f21e3c6L,
  43190. 0x0cb31953884e6a0L,0x01bccefececb730L,0x1fe40bf9d7e61b4L,
  43191. 0x082dc76951e23f1L,0x15efa9453787588L,0x010341f1fcc13a9L },
  43192. { 0x1582e26d0378878L,0x0a611d3ca2bc3e5L,0x02fe3d9a22ce788L,
  43193. 0x0a80a2a4e027a00L,0x00111f5d7548d4fL,0x1ffc813889e0aeaL,
  43194. 0x11730efd6949aa2L,0x00b7b4d60213692L,0x183dcc74ebc2f3aL,
  43195. 0x177b14221f7efd0L,0x183ba559716fd0aL,0x021ab25e4875a5cL,
  43196. 0x121bc3bf514f0faL,0x102bb53a3572c59L,0x1cc206a04ec21a1L,
  43197. 0x1dcb2178047f09aL,0x1959fd03aa032dcL,0x02f20b5fa93eb63L } },
  43198. /* 32 */
  43199. { { 0x0313760026cc23cL,0x0d5775ad9482c12L,0x0be3174bb85fe06L,
  43200. 0x17dcb988055244eL,0x17def07d8048e7cL,0x17c10f6de3eb773L,
  43201. 0x0ee25875a4913daL,0x148bef2cddb32d9L,0x0f81b17ea96a155L,
  43202. 0x16cf7b801f9f6abL,0x19641ba20a96cacL,0x00e55d28e300bcdL,
  43203. 0x11658c76f486fa1L,0x0581ad501a6cfe2L,0x0f992067d80f703L,
  43204. 0x153df6f673fd6ebL,0x1e3ca87554acf04L,0x027fb417643da7eL },
  43205. { 0x125627fd0a10ad5L,0x02e394b4737a298L,0x15ae01a8458dff5L,
  43206. 0x1bbca067c653037L,0x1f4f8988b92de1cL,0x13f0ee1da25a2f5L,
  43207. 0x161e3286e625b6bL,0x08ea42cdcb40ef1L,0x182d472bea51168L,
  43208. 0x1ee9c157944aa22L,0x14580975bb1327eL,0x16396caa560445dL,
  43209. 0x13a1e6210f3614eL,0x010d3a53b1e2efbL,0x172f537a4580a14L,
  43210. 0x1c533489948018cL,0x07c48cb187e0f15L,0x028f5c0c71a0128L } },
  43211. /* 33 */
  43212. { { 0x1c1d178b92100abL,0x11eb04b02dc1c8fL,0x0956dc7967437cbL,
  43213. 0x0a29f97c08254f8L,0x19fd06af3f8b667L,0x01068387451c9aaL,
  43214. 0x1ef9558c9940848L,0x0a8cd2df9a2a51cL,0x16588514b0c7b76L,
  43215. 0x06c07c62c8952daL,0x1fbc13cc932dfc3L,0x1d9f8db47aeb175L,
  43216. 0x1831d1df2f6b53eL,0x19c095b6f6f7a46L,0x18980c7ccdae595L,
  43217. 0x1e137905d5c95dcL,0x07f300abd32d244L,0x045857caa98ecb2L },
  43218. { 0x170180a2e603544L,0x19d61910d66cf5bL,0x19958901c0c8ad5L,
  43219. 0x1b7135787a742feL,0x1793225aad3e74aL,0x012b25c51e971d6L,
  43220. 0x14ad515eee813bcL,0x1d110eaca5ff85bL,0x0d2905d15e67143L,
  43221. 0x0c425a1017246b8L,0x0648671d8da95dbL,0x08426bc6f1be0dfL,
  43222. 0x1d10c64a02a8dc3L,0x060abd334ae0eb9L,0x0928d5335a93b3bL,
  43223. 0x0653b75b983911cL,0x0d08024f1b29839L,0x029b1f2a4a6d245L } },
  43224. /* 34 */
  43225. { { 0x15523b7e23fc641L,0x07397c33338318fL,0x17d6380274bff95L,
  43226. 0x1f18afebc252942L,0x116d64dcf203997L,0x1517fdd114b9265L,
  43227. 0x03b59a5ef93f52eL,0x06c7ea0fc8c14ddL,0x00afe3a5d785085L,
  43228. 0x177b66ecaa04104L,0x1f6227cb108df3bL,0x1074b870a4a6e03L,
  43229. 0x0d72a212f1496d8L,0x0ffbc7e6f12e33fL,0x1bd05192d059e0cL,
  43230. 0x00d2fd32ce00982L,0x0c3fa45c3a1c45bL,0x03199a00c1fde98L },
  43231. { 0x1c9a0cca2fbbbceL,0x1b72e55065ba21cL,0x0438d0e3b38e1dbL,
  43232. 0x1c27005b0539cc0L,0x1cd45a1b0aad148L,0x07e0f04e1f2e304L,
  43233. 0x137421d72e165efL,0x057633fef21b0b0L,0x12598b81ed81c2aL,
  43234. 0x0c5ef97815f03f1L,0x1f23bae5d973a44L,0x1b11649f2b5c0e9L,
  43235. 0x1c0c98f09d125e9L,0x105ba5939dd8966L,0x001df3929abb81eL,
  43236. 0x004de8e47a5f381L,0x173959447d6bea8L,0x049d383ae0b1405L } },
  43237. /* 35 */
  43238. { { 0x0bbefe2715b27f9L,0x0d2f11514049193L,0x0ebff56289aaa4dL,
  43239. 0x0cf8270d28bbbe4L,0x092a215354c83e1L,0x0684faa23ccde4cL,
  43240. 0x1a9a139b91c426eL,0x16d8c75ec2dab11L,0x05e896706883ab1L,
  43241. 0x009c9d01e90499bL,0x1ca4864b08f768fL,0x16f5b9edd487a05L,
  43242. 0x08791559e1ab70cL,0x16b87f858921a75L,0x0cae914101a036dL,
  43243. 0x1971e3421fca450L,0x1fdd69f9c08e5f0L,0x00d3a11562258a0L },
  43244. { 0x1a9dd2e9f40b675L,0x03301fe638f9ce1L,0x098465238d08a9fL,
  43245. 0x11da15690831273L,0x0e31ca6b8f3b615L,0x146db1d1d53ecbfL,
  43246. 0x18b92f07a197bdeL,0x01e62bf181258f8L,0x1a260788f9f5c6dL,
  43247. 0x0c19894a5b79f62L,0x16f358dad36126cL,0x112178d33536e75L,
  43248. 0x182a1175e766e14L,0x1e29e527df9bc86L,0x1fd8245fd0d816bL,
  43249. 0x1056caefed88f0fL,0x19c827c7552600cL,0x004a26b184e92acL } },
  43250. /* 36 */
  43251. { { 0x1deb63ee6ab9620L,0x07d36bc366c0467L,0x1609158c82cf7fdL,
  43252. 0x058928722a28bdbL,0x173b3f872ae5f86L,0x17cbd4ca847409dL,
  43253. 0x06d88ef6017cf94L,0x1f9ee36b8519305L,0x0b394c70e86e0ceL,
  43254. 0x1a7d8d491ded9b7L,0x1d618b6f89f9694L,0x1be70756c2d3ac9L,
  43255. 0x1127c828cbbae23L,0x1d183d456eb6f8dL,0x0777d986406267cL,
  43256. 0x076ee6d990cb302L,0x176a3cb77747994L,0x03ec4f9c1b7ec32L },
  43257. { 0x0564242c9f92b2bL,0x0353ae237195efcL,0x02ddfe669715c03L,
  43258. 0x1006292ad127cedL,0x02ce6709b6efe85L,0x176249ddff450ceL,
  43259. 0x10a35c868ec6fb9L,0x03a4ddddd5386e3L,0x1d798115e15177eL,
  43260. 0x1df9de7583452d2L,0x1688811b4ad2cb5L,0x12b6b37d3bf9bf1L,
  43261. 0x1c77640b793df09L,0x0d15e9e2e4b44bdL,0x0bf9d133833d309L,
  43262. 0x013762de8badd13L,0x0e6b53f3acb3a85L,0x0224d7c0fb1f953L } },
  43263. /* 37 */
  43264. { { 0x0fcf132a16d9377L,0x1bbd9bf0d17cf61L,0x04ba1b466b966acL,
  43265. 0x0da0277762e5c34L,0x0b5f66bad2b12e6L,0x0f55a804b9702aeL,
  43266. 0x17b0b44778700e6L,0x12783e629fb8cbeL,0x0fc3118418a9ff5L,
  43267. 0x1b9e0f670292373L,0x144d8c589415b77L,0x17aedf64bc33851L,
  43268. 0x04845cd2d730a9dL,0x09b74296824f692L,0x0322a0f1de6e0ffL,
  43269. 0x100670b46bf8fedL,0x0f5299bf1e1c95eL,0x007430be190448dL },
  43270. { 0x172060267c81b5cL,0x04ee6f39bc39e29L,0x02c2a0513f40beaL,
  43271. 0x0e4c41190654e86L,0x18ea40f53006c5aL,0x1209d2270333306L,
  43272. 0x0527e774097e625L,0x1857be701988d72L,0x1801566190a125cL,
  43273. 0x06b51dba93c9e1bL,0x004dd1ade98bc81L,0x04d0b0bab2f16c0L,
  43274. 0x188395fe66a9cfeL,0x035930fb6e56865L,0x0764862ead1a3f1L,
  43275. 0x04805941debdf3bL,0x087c507d4a85e45L,0x037a2027899367bL } },
  43276. /* 38 */
  43277. { { 0x1e1920b4febd3ffL,0x11a6c7efe95dd51L,0x1cab866a60a7298L,
  43278. 0x018deb78416fa35L,0x1aa39ca923de161L,0x063855f1026df9eL,
  43279. 0x0dc2ca8b7a6e1b6L,0x01c4e5c186ef93aL,0x080914c06e56551L,
  43280. 0x108f3d42be5db58L,0x1f1bbf6099a9badL,0x09dc612b00380edL,
  43281. 0x02b9e24063dfac3L,0x1c3d52e2b4ffa05L,0x11c334a9ee8c6a5L,
  43282. 0x1e0e81c9a3fbe67L,0x1e2903e31326895L,0x0482bb8fc3fdb38L },
  43283. { 0x199ba0da4062beeL,0x191c64a6becfca8L,0x06f078248b00639L,
  43284. 0x03625b0abfea7e5L,0x0d68ca29de9b2a8L,0x0604bfb24f9f76bL,
  43285. 0x0628192b7f0d314L,0x049032c95733b67L,0x000d59c477a5872L,
  43286. 0x0ff51cb3a62c81dL,0x1f63b85410f7402L,0x14dcbe3d9840d55L,
  43287. 0x030db9b7b4c5721L,0x13646a955b6b524L,0x120a89c1bff185dL,
  43288. 0x1ef507bc483ad59L,0x0cc0605f05227f2L,0x035114a9db2026fL } },
  43289. /* 39 */
  43290. { { 0x0452d8f74fce389L,0x11a60157d2ab249L,0x12efc3b5e094165L,
  43291. 0x166ee31c1b26ef9L,0x1fa69a4d89f4045L,0x0ad85d0883a73ecL,
  43292. 0x1b79975c2ec1dcaL,0x0f7645aa95be20fL,0x15c39a3d8a1a29cL,
  43293. 0x191b6016bcaf1d5L,0x00b400ad626544dL,0x0b7caf217dc5ee5L,
  43294. 0x11a8e65ea25e226L,0x1000e75ec8f0750L,0x071500839c69c21L,
  43295. 0x0d3022d201eb458L,0x027c3b2d5c0357fL,0x029464f5030cf1aL },
  43296. { 0x0dc86b45f26c577L,0x1a3844a1c5ea28fL,0x004de4960a9fe01L,
  43297. 0x01bc3cad3e5bfc2L,0x1a55a356e08eacaL,0x0bb10b2fca977d4L,
  43298. 0x1c7ca93602d4f92L,0x1e1a56cb0ab9abaL,0x0246704bf66cea3L,
  43299. 0x09fb20fa49191e5L,0x0615726b6c4c946L,0x059c5a33aca54d0L,
  43300. 0x105b82ed7b86d52L,0x070a8694a9b04f8L,0x04fa244ec3c0252L,
  43301. 0x16892475b17f616L,0x157cbb1556cf794L,0x01007c849b9c5e7L } },
  43302. /* 40 */
  43303. { { 0x1b22fc58388387fL,0x178b8147441e2fcL,0x0e4346de5cf33c9L,
  43304. 0x05edd922e288f95L,0x030cdbc08d5d4eaL,0x111e15970b7a4c6L,
  43305. 0x11517724a443121L,0x161d629236061b7L,0x0631deb2e14de21L,
  43306. 0x051083317f4187aL,0x1a5e70de707cfc1L,0x16d1f60d4f2b498L,
  43307. 0x1a1619dfa98a732L,0x06df164d9d22193L,0x0627faa468c1f4eL,
  43308. 0x0663f273791a407L,0x1dc3daabaf20f4aL,0x02e183f4c6e87aaL },
  43309. { 0x1c4e0c435b233daL,0x14842917b7cc2ddL,0x1486a2c091a38f4L,
  43310. 0x1352d22dcf33ba5L,0x014bcced978f40eL,0x083b160193ec363L,
  43311. 0x1cbb657a5540acaL,0x0661ffa432f50f3L,0x0c436513750e0bdL,
  43312. 0x1618a450413e262L,0x004aa0ff3f02c89L,0x02fc63250b138f3L,
  43313. 0x1e8830f42dc3d8dL,0x0583fc1fc5ab967L,0x144523df367fe49L,
  43314. 0x1f358663952a014L,0x185d0c539684c59L,0x00ef8b6fd60a1a3L } },
  43315. /* 41 */
  43316. { { 0x07bb4ac68bcacc3L,0x169a7a187ac67e6L,0x1d3f518615681b7L,
  43317. 0x088b93e1798b3f3L,0x0375c892f549199L,0x02cc1d6e2fbf632L,
  43318. 0x1421c6e1c23c4f2L,0x01f6654b98905f9L,0x1efdcdc352d6b4cL,
  43319. 0x1d9278245637d96L,0x0b53d4ce4191c52L,0x0a5f70747588b30L,
  43320. 0x082337a223162ebL,0x05e1ede9b8986f9L,0x19eb03b739ee00bL,
  43321. 0x0e2fd1672b2b248L,0x01721d3d2e81b56L,0x0394d3fa8232893L },
  43322. { 0x14ed1aa8420f90aL,0x070cf07f2642ac3L,0x0aaac2f9d2bd8daL,
  43323. 0x01194c19536c5a9L,0x1645a86776fcc48L,0x18d92679885ad2bL,
  43324. 0x16d104c6eb26f76L,0x09ddeefae3a5bd4L,0x04706d21072fcc6L,
  43325. 0x0dc9348b39ebbf8L,0x002fcfa278198caL,0x19a6e80efa8045cL,
  43326. 0x0d829232e2472d0L,0x1c6e42999f10820L,0x0e3d99cbe45b7ecL,
  43327. 0x1c33a91776b3629L,0x15c19de9f4ad44bL,0x03fb69b249196ceL } },
  43328. /* 42 */
  43329. { { 0x1d064de6e794819L,0x1b4a77c175ed09dL,0x1f82e478a01169aL,
  43330. 0x060f4879a43e02fL,0x030433e9190d31fL,0x1fee5a361379133L,
  43331. 0x04702e9222a9c2aL,0x100831b210b48c8L,0x11b934fe6bffb58L,
  43332. 0x0e8f11bf1007c24L,0x1358fe95504f6ddL,0x1aebc4767eefbe0L,
  43333. 0x0b0f91bd30e216eL,0x1b94e284d02c336L,0x0aacb5e130e5765L,
  43334. 0x1ad0dd92fc3108aL,0x06c8cb7c1f90093L,0x0168191cab14784L },
  43335. { 0x01c94074a44b4c5L,0x0343ce638164c54L,0x0a1f3ac3725ee61L,
  43336. 0x0cdc75464396a04L,0x04c256c23030112L,0x0da422e05643b1fL,
  43337. 0x1cd6d940d348395L,0x1b9552d4081e481L,0x0046d26d37cf7eeL,
  43338. 0x152d4709dc0832bL,0x112e5e0f5c30ad8L,0x1f10b3c9b51f0c0L,
  43339. 0x1a5457f5d12fbafL,0x1a98dbabc94ec80L,0x13a5ce74a787acaL,
  43340. 0x137b2429b57b93cL,0x19b5bd724fc4eaaL,0x039a609598f7cddL } },
  43341. /* 43 */
  43342. { { 0x0fe3c2e92f9b086L,0x0dc9f59fea2a24cL,0x022d700b1971190L,
  43343. 0x0389e064848f9c4L,0x079d29f68a52dcaL,0x037afa5af60becbL,
  43344. 0x0a044474bfb4250L,0x07e4c1ec7b81b37L,0x0de2b056f15472aL,
  43345. 0x18b86cf80394873L,0x08fa36dad723e46L,0x10739e6987dd45cL,
  43346. 0x011b973ee2345a2L,0x1d9268e2cdee2a3L,0x185068596f69b0aL,
  43347. 0x164032faa574678L,0x09f47bb16129d2eL,0x03e2ac54390fdf2L },
  43348. { 0x1485a523f350fecL,0x13c62b51c6a605cL,0x1a88356a9934059L,
  43349. 0x05b2db45c91de68L,0x0f647b3cb85daa0L,0x0f4a36422f62752L,
  43350. 0x1d2af03469b2835L,0x00683b1a3829f53L,0x143972cc59c8b13L,
  43351. 0x1f0fa46a1a7fdfdL,0x13a4ea06748c619L,0x0120dbbde47e6a1L,
  43352. 0x19200cf12c49f53L,0x1202197e1e17367L,0x125ad4909a47305L,
  43353. 0x12f7d7ffee968e4L,0x14844527c9f020aL,0x01a66bee53d9e21L } },
  43354. /* 44 */
  43355. { { 0x031761a59e7fe87L,0x1718d0023e6b978L,0x19a3eb8c3d8ac7aL,
  43356. 0x1b6e3b62864f205L,0x0e0038f4a666f48L,0x1eebb6baf7333c0L,
  43357. 0x13570ed16b19c0aL,0x0221a5f705141adL,0x027ce7f1d9d8c5bL,
  43358. 0x00ff0720905af4bL,0x06e612e499f0dc5L,0x0b13ac06259b2b4L,
  43359. 0x0eda5493565206eL,0x03863a560c339a1L,0x15ec2ccdd1482e4L,
  43360. 0x118284e07976b2aL,0x087f621f59ca6edL,0x03e758e6155fbdcL },
  43361. { 0x047a5bbdb7fd65bL,0x02e601b64a2be03L,0x076e7849c62b635L,
  43362. 0x09d274ff638db53L,0x1d1566a1ed1dbbfL,0x00648ca28964ae5L,
  43363. 0x149a52186e8036fL,0x15c78d985313cfeL,0x1671961500941aaL,
  43364. 0x1e7ae87e4629c71L,0x1a64a68969547efL,0x130a2f941e4d5adL,
  43365. 0x0afa89ef7e90710L,0x18d5a2a4ba1dbc7L,0x1470db4e757a8c5L,
  43366. 0x0ad1ae885e7e7cdL,0x15c25a683e0059dL,0x00fb14d4c913e76L } },
  43367. /* 45 */
  43368. { { 0x125ddace45a1c3eL,0x149b2a0fbaa2fc4L,0x1f2cdf9fe0a1cb4L,
  43369. 0x067c98f3a48ac45L,0x1c2645d68823451L,0x04015caeffd7c24L,
  43370. 0x07e80c1e3d37665L,0x198acd24fe13a67L,0x19a500a1e9fd91dL,
  43371. 0x10040c0055855ebL,0x04d68e0653977f3L,0x060f315be111b2eL,
  43372. 0x189a45a2a79e876L,0x1c45a1cc9dd780dL,0x1ea65f5bfb58551L,
  43373. 0x11ddb301cae45ceL,0x1a2aac90ffa2a37L,0x0253afed145ec02L },
  43374. { 0x09a8fbb55e74cbcL,0x19c677d58c792e8L,0x0b5a5d93b0e9cddL,
  43375. 0x17cfc15a621f847L,0x0481cc9bc5a7d35L,0x05761a73af03477L,
  43376. 0x18f13c30baa64f5L,0x059e2649fd01a94L,0x15dbb7c1699b059L,
  43377. 0x016b3a6d3f07a35L,0x159b1e8c03eba91L,0x104266675906b4bL,
  43378. 0x0e8c408496e83dcL,0x0cf7afe0b877c09L,0x0d3a18a5b8772daL,
  43379. 0x00fb0dc56ee362eL,0x19a04629cdc5835L,0x02c0cfcd711ec0bL } },
  43380. /* 46 */
  43381. { { 0x19691216aa78811L,0x1747a1081f3e1ecL,0x01c08ae79a63d93L,
  43382. 0x1c9eb059bdbbe02L,0x0ecfac1ae6001f9L,0x1c9804925304579L,
  43383. 0x0a445bbd31e1018L,0x140a4c5d5cdd7eeL,0x1ddbd0af58c4ee5L,
  43384. 0x1ad7fc8766c3de3L,0x16cd31bc93c4521L,0x0503d0cbe2e45fbL,
  43385. 0x06886c1b9a48104L,0x0f7a118fcab4921L,0x09fa0b9bd7cc822L,
  43386. 0x12b915eb0f59fa1L,0x150d65719179ac3L,0x03a2cb01e09b253L },
  43387. { 0x02475bff41ae519L,0x00fd8a57c79288eL,0x134abbecb0f4d10L,
  43388. 0x16a39b5e10e1bbfL,0x0208bb199b2d385L,0x19f9fb4298e12b4L,
  43389. 0x05da45b2277d930L,0x1758479f53248aeL,0x12339b51e86d010L,
  43390. 0x06d87469131c189L,0x0785e403fb7adc2L,0x1b9746d0fde3eedL,
  43391. 0x03914764753fd96L,0x0622e46ee682359L,0x0d0f5e3cffc8190L,
  43392. 0x1dd21dfa2cf7b70L,0x145493ccb6d4b77L,0x019812a89d9e7bdL } },
  43393. /* 47 */
  43394. { { 0x0f0046935eaaca1L,0x025bac488c8811bL,0x19979b4a553030eL,
  43395. 0x1363d3adaf966eaL,0x029c2757cb9199bL,0x139c683ac291a4eL,
  43396. 0x0909e272f46eae3L,0x113371b7d20b247L,0x1a237793e18fe18L,
  43397. 0x0138babd3a17041L,0x05e7493baf584e9L,0x00a9a9e59eef189L,
  43398. 0x11958705de40325L,0x19ecccdd51dc504L,0x03fb8786c646f64L,
  43399. 0x1be2975fdf74876L,0x01cb3bad1843facL,0x0499456d821c3abL },
  43400. { 0x1e84e80f906b872L,0x091d03c131332d5L,0x09f8ce6333ddc15L,
  43401. 0x1beab6a647b138dL,0x0554dea82fab551L,0x0ac4e6d02bc7650L,
  43402. 0x15d43bc9948f4ddL,0x1fdb1fac4850c95L,0x093f27fc5178fe1L,
  43403. 0x19f37984efc3a11L,0x0b9278dd434151eL,0x0d64bb80714250cL,
  43404. 0x0284db682b7d90cL,0x0c40c98560d0d71L,0x1cf82911fcf6adeL,
  43405. 0x04b8a61cd7aa575L,0x1e70680025bf62dL,0x00550f9e7d6e86aL } },
  43406. /* 48 */
  43407. { { 0x182219022a10453L,0x15c8e1501d085d4L,0x16565991bcef747L,
  43408. 0x09e716df8d5f76bL,0x18cfca1da58de34L,0x186d026723e1f2dL,
  43409. 0x0bb5bf36385b43dL,0x11d58886937b44cL,0x09320d87bc56e2fL,
  43410. 0x071f5040c89c72cL,0x18b7fe8ac8db027L,0x14b91cfdf61b4b0L,
  43411. 0x0b16ac78eb6b0f9L,0x184da8d7a5a9a19L,0x14658a1bfd0c415L,
  43412. 0x0075a11c46df11eL,0x05e1f93f176eed4L,0x02ac99bf04b1b2aL },
  43413. { 0x0ddf738d8fd807aL,0x0764ed589891118L,0x136d896bef0fd38L,
  43414. 0x093e25f12a2945eL,0x0c3044fdd5b7060L,0x000a47da379e11dL,
  43415. 0x195506c8cb47fd5L,0x0eac368b1ea7369L,0x1f694b24a0dd70bL,
  43416. 0x1e3214c944ac0ecL,0x1526fbb97f88b43L,0x08fed4317ec780bL,
  43417. 0x027f1929d67af34L,0x00aa8f4674b50eeL,0x1753e89abf980a3L,
  43418. 0x059684fb595e656L,0x0d34a1631bc545cL,0x04980387cd8648aL } },
  43419. /* 49 */
  43420. { { 0x0f32c5e69a9bc05L,0x00ce32c4e25b9e9L,0x197a51997e70297L,
  43421. 0x0779f6987212b93L,0x1ddb7c318ab0f29L,0x19c0245c83843b8L,
  43422. 0x166f6253a59619aL,0x0d3e335219ec0d7L,0x1cc1d58dfb6fd2dL,
  43423. 0x036e627230ec534L,0x1709dfe73920c62L,0x132cecbf150588aL,
  43424. 0x0cc3badc8d749a5L,0x088966d597fe334L,0x10f1f2ce0060e5aL,
  43425. 0x04449530f2b8764L,0x0148775f310010aL,0x0021d10a0ac3dafL },
  43426. { 0x1be9dbc3a873752L,0x049fa17a217f73dL,0x0b2306308607b85L,
  43427. 0x01c52ed3cf30394L,0x1e768c5f00ce309L,0x0bb3bf5a3135646L,
  43428. 0x05398cfa73918d3L,0x17ff138595bc1f5L,0x004f5cc1141f5b5L,
  43429. 0x0b2fb9b11146096L,0x1dc1a8301733949L,0x1fff7c90f89fe37L,
  43430. 0x09a499f1a45d07fL,0x0c6ca4001f621e0L,0x0fc4be13d39e6eeL,
  43431. 0x01adb1466b42c0eL,0x0e84bb5eaf70f97L,0x00c683a3df92685L } },
  43432. /* 50 */
  43433. { { 0x0d3c77c84601fafL,0x12df1578e0fb92cL,0x1e63445b601b251L,
  43434. 0x0dab61b279fec4cL,0x1ec6723a3996c0cL,0x1d29a497d0d6baaL,
  43435. 0x1362a59aa05100eL,0x0cbb89928445586L,0x1ddf471deed6758L,
  43436. 0x05652cbca9ea947L,0x118ed493afd9f76L,0x10e2fc4b69a765cL,
  43437. 0x1a43159daa25824L,0x019abaa011e2d6dL,0x0e2c6995163e71aL,
  43438. 0x1a4639ed0bb4ff2L,0x059981a4fdacefeL,0x0388849f6845dafL },
  43439. { 0x0aa3fc6401f161aL,0x0c2b04ba62f4389L,0x0bec5ed77e0bdcdL,
  43440. 0x0f491cc5329544aL,0x09dd847db0b82b0L,0x14e2d30011a0ab9L,
  43441. 0x1d4e3c795340114L,0x1979838a73cdb31L,0x136162b5328d3abL,
  43442. 0x0d1bc9c15427866L,0x1ea06d37b9d211dL,0x0bf698477e37ee2L,
  43443. 0x1f787e8b3e16cf3L,0x0cdbcd583fe8e14L,0x1db182edf69f9a1L,
  43444. 0x0916a0e4201410bL,0x1d431840159e7edL,0x00bc4c5ed26ce4bL } },
  43445. /* 51 */
  43446. { { 0x18483d8ae1b8cf8L,0x0a5a174d1442b66L,0x013c81292f08c8fL,
  43447. 0x1194f4d3f4ec66bL,0x1757bab24e0b222L,0x02fce5457ded45fL,
  43448. 0x0570e16c90221b3L,0x0d68ff69027a835L,0x13f1bc53cc2aabeL,
  43449. 0x1166d1f8d68acceL,0x1b02070c7aa6c7cL,0x009602c29582365L,
  43450. 0x09c6afa7ab048f3L,0x00a06e1ee718e77L,0x1a2aee956bdd8cdL,
  43451. 0x07dfd096f566fb9L,0x0b250de7648c7cfL,0x039d446e78a9ab5L },
  43452. { 0x186828806e83b39L,0x12209cfa201be9fL,0x0c3c5f6f21051deL,
  43453. 0x1ea9a2ea93f20b1L,0x12307ffe2db64f4L,0x093130d11e75357L,
  43454. 0x1fc98e4fbf5553cL,0x06a5e9ccb1421e6L,0x1a4437ce3f4ee1eL,
  43455. 0x077a153d49e6f45L,0x0f27d24e6aa4059L,0x1ad47af6b9a83bdL,
  43456. 0x11f88a3acc44223L,0x16304516bc4d350L,0x1d5b0195bee77e0L,
  43457. 0x14601cf3b71c777L,0x01e73c56af2668fL,0x02979958bd71cb5L } },
  43458. /* 52 */
  43459. { { 0x0f524c1e714f71aL,0x109314d6ec28cabL,0x0761972b6f8f06fL,
  43460. 0x10b41f6c935b231L,0x01d192d9d88bf5cL,0x1925b7cf7d35491L,
  43461. 0x046738ffa0e25bdL,0x181d87f5c4964a0L,0x14b6af9f62ae0d3L,
  43462. 0x1e75d05eb0cb126L,0x0c24acbf6db8ea3L,0x06ec64c79a52fb8L,
  43463. 0x1ef95c43bdc91daL,0x06f5a26c98603b0L,0x1034c76244d9003L,
  43464. 0x1133ffafb9d0887L,0x0c178fec3b19871L,0x03cf0a69477efacL },
  43465. { 0x18222359bb40c55L,0x1901687683d2171L,0x06a520e307d0289L,
  43466. 0x0fb0c94f1c91cd8L,0x0c6c55c92b5f24aL,0x096a843f3f8a050L,
  43467. 0x0784398b0412b38L,0x1ab361434fd8236L,0x0fd8a275fafbb3dL,
  43468. 0x1f9aa7f4d1db598L,0x0176791980a8077L,0x169b2776cbeeb42L,
  43469. 0x0b0f82fdeb3d371L,0x0f2342a2ed2e5f8L,0x0f545f918048a6fL,
  43470. 0x1e924a0bc21738eL,0x0e277cfa541672fL,0x006c761454cab36L } },
  43471. /* 53 */
  43472. { { 0x14cf73ecbeee995L,0x1c45e6a48f40600L,0x12b766ae9752cbaL,
  43473. 0x072609909ac2b4dL,0x0ab03c9a2f7d463L,0x1d5dca5d0280e94L,
  43474. 0x15dcb23dc8f7a46L,0x129910bf2eea080L,0x0b5e1d2b3c7fcb0L,
  43475. 0x0f73ccaefcb638dL,0x036aacd19126798L,0x1bbabec0f265719L,
  43476. 0x01b1243587db425L,0x0fe3a1a038128e5L,0x00ab2249b5f4efaL,
  43477. 0x14e9f182f262192L,0x0fc72522c154559L,0x043000f13e1b9a5L },
  43478. { 0x1b00ba5e7693947L,0x0320f0096031589L,0x0383a15242a191eL,
  43479. 0x1fb2ae9abdc3487L,0x1bd3ba615173dbbL,0x1f503aca9975c64L,
  43480. 0x04ae47d06f2e17cL,0x1695839848f1977L,0x00f34648e1ef901L,
  43481. 0x0c94e8f6959d977L,0x1c7aaf0f5d6ff37L,0x0dee2739e9a48e1L,
  43482. 0x0df04249535cdbcL,0x03fe59c1e6c322aL,0x17e4c30781e6049L,
  43483. 0x1780173e413682fL,0x0c14225fc31114eL,0x00102c8e59a3ca3L } },
  43484. /* 54 */
  43485. { { 0x1003721275e0af4L,0x0a0f7f3c52525f1L,0x13db45d5d215c84L,
  43486. 0x0e2d1ccb3cccd9fL,0x0e2842ee5fa1d73L,0x05eafb131f1f2a0L,
  43487. 0x0412ab7b30f5252L,0x030033bc07a48d6L,0x1f8a9e903f343d8L,
  43488. 0x1abdd252d860698L,0x1b14194789d97f2L,0x0a3eca337ecf048L,
  43489. 0x00f2119a0180c57L,0x1c10ea7a2f82e10L,0x070e819f9921ee1L,
  43490. 0x0c0a44c5f29544cL,0x1ef56cfe4897214L,0x0288ccc2fd0ef82L },
  43491. { 0x019497db18586c0L,0x00aeb637755312cL,0x1ada5f368a2c011L,
  43492. 0x10f8328b28f8d48L,0x0ed3a5069a149b2L,0x04a65a5ab1b4fd2L,
  43493. 0x1bb89c24aa9990fL,0x012ab79ce7553d3L,0x034bb2870778935L,
  43494. 0x17cafd80375a993L,0x140c8e58e3d2162L,0x04d0b74eb7f10f9L,
  43495. 0x1d9d42d58129376L,0x12e36b26f996b79L,0x137b506932b55d1L,
  43496. 0x140cf30bea1f765L,0x19acf34ce0e9006L,0x02cf57932ac52bfL } },
  43497. /* 55 */
  43498. { { 0x1407efb6ec3876fL,0x03091f87a43243dL,0x1bfefe24c0e5e03L,
  43499. 0x008b5235605576aL,0x18811b829592eaaL,0x0f9fe4e72dc26bbL,
  43500. 0x184ee1a9c68d07eL,0x10182ffbb0de1cfL,0x088ed8297655a08L,
  43501. 0x0eb6e3a40eaf333L,0x1277d8745c5e5ddL,0x191bc7ef3c3fdffL,
  43502. 0x1d2046192e36ad4L,0x13a7ed316d8a98bL,0x1766451e327e9e8L,
  43503. 0x12e3809d9249f05L,0x1fb059d1e383a64L,0x01da2287513105dL },
  43504. { 0x1b7a955c776dcdbL,0x052be40e45d239eL,0x000d415d83ecd71L,
  43505. 0x03675d86a75c50aL,0x07117be5e3e8069L,0x1667b09c019adf2L,
  43506. 0x1e45b8711f8e815L,0x1c24a79fbd6672eL,0x03decdfbaf5cb7eL,
  43507. 0x1e4bca7be7a5b82L,0x05a0327fe0518bcL,0x1c237c7b553e480L,
  43508. 0x1769f91d8a4e440L,0x05af4e2ee2e821bL,0x0df4935041b1ea3L,
  43509. 0x169443232134267L,0x014e893c8383764L,0x0253ff1866214dbL } },
  43510. /* 56 */
  43511. { { 0x18f3a702455c7c5L,0x11b74380abbaa73L,0x1491d88c98b16ddL,
  43512. 0x1c378f018fe6588L,0x115ed8772c98b11L,0x0932fa6a4757564L,
  43513. 0x0803eec134f0066L,0x1d0d6a563379f4aL,0x1c46a098193ea3fL,
  43514. 0x016399edd3ac02cL,0x12ef58625aab336L,0x05f99d1d9aa3a64L,
  43515. 0x1d02fc44b3ac09aL,0x1550bc25a94c8c7L,0x0882173c311792aL,
  43516. 0x0fac26ac4c681fcL,0x12353cbb676c50cL,0x041fd0f51b28935L },
  43517. { 0x0ac86da10ccc646L,0x031bfbd8228f4b0L,0x18c228221840b38L,
  43518. 0x12406933057779eL,0x1c0bcda023c1901L,0x0a7ebeb83fe1ce7L,
  43519. 0x0eeedfd347c546fL,0x0c1ad4c9ce888e2L,0x157bdc676c5ac9eL,
  43520. 0x0b629819bdb08b4L,0x144e5b73d028751L,0x184a932fa58fa68L,
  43521. 0x04c2c4a739f3edeL,0x1535697129a574dL,0x1a57e045004e5f9L,
  43522. 0x1f57e40ed3a9a47L,0x1e0cee007c6de98L,0x030a04bbcc98e28L } },
  43523. /* 57 */
  43524. { { 0x1db32db15156623L,0x1bfde55bd33e11eL,0x1d41bc678f09a04L,
  43525. 0x05132498c24c023L,0x06804c1c34218b0L,0x157353a4950587eL,
  43526. 0x0f987596f9c1abeL,0x0d27627a47c1a03L,0x144545b47f87f4cL,
  43527. 0x0111b71026e0d51L,0x149874f14587b35L,0x14c77b11780ec26L,
  43528. 0x161599d7201eb46L,0x14dd7879bc636c1L,0x01ca083da557f85L,
  43529. 0x068148cfdd7ac2eL,0x1882f1b8a2a3e3aL,0x031b6d63b1685afL },
  43530. { 0x0280db9b4c80af3L,0x04e68a71c4955caL,0x0b83451df772686L,
  43531. 0x10d1f3e29e4dce0L,0x00baa0b2e91aee3L,0x18a51494327b1d4L,
  43532. 0x1f2dab3607dce2dL,0x1fa61c370e18bfcL,0x1883ea1c3b10837L,
  43533. 0x0d13ca9b590244fL,0x0ca9a1628b697cbL,0x17e40751f42875dL,
  43534. 0x15dc70b1c4e2330L,0x14cb3c7a5ae2445L,0x17d9d7029e31364L,
  43535. 0x1a6d04677a1304bL,0x13f37b5c0767b67L,0x017b6deff2685f7L } },
  43536. /* 58 */
  43537. { { 0x18472fd2e4da7c7L,0x07e48d733bc9917L,0x0228f709a389c23L,
  43538. 0x00f33448486c95eL,0x11d58bff0f10dfeL,0x04b17377c896ac3L,
  43539. 0x1a829afcd77f262L,0x1825172df52be8fL,0x0734a79eaaad308L,
  43540. 0x0b9819bcfa1bdddL,0x12f639b3d53dd65L,0x1b9fcec65dd8005L,
  43541. 0x0b5319310447606L,0x0567b94ea025af6L,0x177c7782b8225f0L,
  43542. 0x0e89112c5170c77L,0x14eeced154ef87dL,0x02e5b70cba2c6aeL },
  43543. { 0x0cef197008c75edL,0x04e9f7b77557c4cL,0x180861d7a5b5f3dL,
  43544. 0x1dbb361b143adf3L,0x19576daafcec2cfL,0x13eddc1c530e7f5L,
  43545. 0x053d04000fce4daL,0x0a766f870d04770L,0x09fb66dcbb80e31L,
  43546. 0x13f175d02cc23d4L,0x118ff4d69c9dc27L,0x1b23f93c1da149dL,
  43547. 0x14d515baa4311f3L,0x10466a719e0ee04L,0x157baa9d681baf2L,
  43548. 0x0583f56c2e4705dL,0x0e52e82bbb0e1f5L,0x010a4eb1828baebL } },
  43549. /* 59 */
  43550. { { 0x01a8e6f5f9311f6L,0x11e4fdd5e0fc2f7L,0x14bad250826b25fL,
  43551. 0x1832ee9fc29f4f8L,0x0555844f04c2f51L,0x039d59ae77e8914L,
  43552. 0x067f2d4e18a8ed6L,0x134ed1dfbad97daL,0x0cdc12479ee5846L,
  43553. 0x091bf189ec0604eL,0x128a4301130a304L,0x02f57a8fc50fbaeL,
  43554. 0x08ad0ffeef9ee65L,0x00c6940fe121091L,0x1b0378509cc223eL,
  43555. 0x17ae7d78e897887L,0x06c5b26eccfb415L,0x00a7179a86583e1L },
  43556. { 0x08d2a104216946bL,0x00f83bd25ec96aaL,0x028d0da54581ba0L,
  43557. 0x1ec7432f92b32daL,0x061f77c90f1b5c2L,0x1fbd913ced1e278L,
  43558. 0x048fc707358d24fL,0x078bcc36ca14468L,0x0826b34c5f28403L,
  43559. 0x0c5c8746179a10aL,0x0d5882ba01bb15cL,0x068bc64953694beL,
  43560. 0x1e8b53cb51a2faeL,0x1ccb2bbc4605dcaL,0x077bccb253dab0bL,
  43561. 0x11e4e0fd8c0fad7L,0x04f63bf1dbad0edL,0x02c29bf016e5b0fL } },
  43562. /* 60 */
  43563. { { 0x164b06464f80ba2L,0x02af382acd22d8fL,0x0cd3c7d2d8d3a38L,
  43564. 0x1fbd190905864c5L,0x030c780aef4f7d5L,0x10f349ceaaef506L,
  43565. 0x10d2c5d02bee73eL,0x1dc59fcd4cce8c1L,0x0f66959411187c1L,
  43566. 0x1c1793bafcba6caL,0x02b390011527ac4L,0x167f757bda04394L,
  43567. 0x064e3653eaf8244L,0x02ae2fc1e1b7a68L,0x1af3a43aae7c373L,
  43568. 0x0284bb27739df59L,0x10d16658e721906L,0x0242bc1afc16bcbL },
  43569. { 0x0d525bcd2576210L,0x1c553ea8daa21eeL,0x1c5c6f60e6527cdL,
  43570. 0x07e7158c43fd2f7L,0x018408cc930d0f6L,0x07a9fb57c7960bcL,
  43571. 0x1d7909a4b21f898L,0x06e1dc8a80fb614L,0x10ec47ae5ffdb1bL,
  43572. 0x14894ee3d535225L,0x04cac8b902dd75dL,0x09a12bde76ef6dfL,
  43573. 0x1568bc63e8e0676L,0x0e000a60147ea3fL,0x065763b46041252L,
  43574. 0x10b5f21c5a7fbafL,0x128eb39a05d6c2aL,0x036013bded10f98L } },
  43575. /* 61 */
  43576. { { 0x01b7086b509e7efL,0x1763d9ebfcfc8f2L,0x1e51549ae22e210L,
  43577. 0x080a3ba1579a50bL,0x174f1ceb6e44e06L,0x1f330dc80cc6083L,
  43578. 0x11f65bb2afa6048L,0x1dc8902226c65ecL,0x11dd82b4526c52aL,
  43579. 0x128483fc9cee4eaL,0x1bbbcbf35156ff5L,0x09bb1a5cbaf97abL,
  43580. 0x1288bc9f2a7815aL,0x0bd1d9912d6a764L,0x0e72f6f1bc4342dL,
  43581. 0x09dd1d1a183ce41L,0x18f5a0b071a9b77L,0x01833de4d7917e7L },
  43582. { 0x0e589f2b7ca9326L,0x0837ed89127b1f0L,0x1485d1e95ef45e8L,
  43583. 0x1ac561105d646a8L,0x0391ffcf2614982L,0x072206bf9d7aa22L,
  43584. 0x0c1c46aa8cdeea1L,0x0a851d46f612837L,0x1a957dcb42e4a7fL,
  43585. 0x1d5b3160d356afdL,0x178e07df0da8839L,0x1019375416d7a26L,
  43586. 0x0c94e4671f42e79L,0x05849171a11b818L,0x169627c93318ffeL,
  43587. 0x1fed9a21aa4f288L,0x195bb99d316a870L,0x01c8641e554cb60L } },
  43588. /* 62 */
  43589. { { 0x0d3fa82ffc4a73fL,0x0eb1a9dea9981a8L,0x1e28992eddf4999L,
  43590. 0x1c45ae7b090140dL,0x0323b8aa81c04a6L,0x0626ad1204e7fa8L,
  43591. 0x07064c773885e31L,0x1706e95501c181fL,0x10b25a38700186bL,
  43592. 0x05bbd085578a43fL,0x0e6b56ad2637874L,0x1b4c3541822c2beL,
  43593. 0x1d96e25ce892e32L,0x0f43236891471edL,0x1ec71a2d5f22371L,
  43594. 0x1bd8ace5622c84cL,0x13a5d0d807f600bL,0x01f52003e911f2bL },
  43595. { 0x16debd0a595d0a3L,0x0bb65d7f859da6bL,0x153e6c6f6e5e9afL,
  43596. 0x0898e298e37e582L,0x021af66362b19abL,0x0a0f7b64df99dc9L,
  43597. 0x03db48f61f12632L,0x1824ab00987af3eL,0x16f1a10052a7acbL,
  43598. 0x0d5bcecaa829457L,0x1e9bc32345884d7L,0x16dbbcbc2053faeL,
  43599. 0x12f95da12b40508L,0x1ac545d0ecad607L,0x18323ee2182bdc5L,
  43600. 0x09a6816329906e2L,0x0a0a40e6c80ce00L,0x004fc150bb58a55L } },
  43601. /* 63 */
  43602. { { 0x0abe588c21366dcL,0x00527d7baed7cb0L,0x1f66b2e4fb51ca7L,
  43603. 0x1d0f42dae0e0a03L,0x18e7361bb97e744L,0x1aa679d217053d4L,
  43604. 0x041e06b36bfc8a2L,0x1cfe10f99776f7bL,0x1da6f3983663250L,
  43605. 0x16b49f75d783e04L,0x0bd30e32ebc55d9L,0x1c0fbf9533a0f37L,
  43606. 0x07f26d8dab5a984L,0x1f5d1b7cd5a6992L,0x0374859342f9c05L,
  43607. 0x09e066f773cca1dL,0x05a72aa4e24531cL,0x03be8f4c25ba9ecL },
  43608. { 0x1373239d8e62367L,0x0c245dcc10678ecL,0x0d116a725f10cd8L,
  43609. 0x1c29f2c1f8018fcL,0x140474b59a0ec9aL,0x1032eae7a0f867bL,
  43610. 0x0184297bb7a3fb3L,0x0bb63bcb49d3d01L,0x117c44ae4ae0cf7L,
  43611. 0x1d2b191b58a4685L,0x09d03f4a7fcb70bL,0x17151196425cc9fL,
  43612. 0x0d6a863016c605eL,0x103da60bf963b8dL,0x1525e15b5844b9dL,
  43613. 0x1c1cbfd21d80e81L,0x1b0599be18be256L,0x0273755f6652a56L } },
  43614. /* 64 */
  43615. { { 0x10323d3fb99cfe6L,0x0de136499a0bc4aL,0x1905f2f7edbdec2L,
  43616. 0x09134eaec0c8223L,0x10919cb09114174L,0x15fe97a6319efc8L,
  43617. 0x18b6dc57f1f1ce5L,0x15919432a251956L,0x0306724734db81aL,
  43618. 0x13d1235da6262a5L,0x1a83eafc8a591b9L,0x0be3f4b6bae1aefL,
  43619. 0x05c2f192f35bed1L,0x1fb34856d2b436dL,0x0942df77b2b1ca9L,
  43620. 0x15a5e1895e54595L,0x056f44631c16049L,0x0192e93cb027678L },
  43621. { 0x011fb554848c144L,0x11492db53d79977L,0x0384da783e69381L,
  43622. 0x0d94a7643c24b6dL,0x0e98ea1bad9bdaeL,0x17d1cafa86b02e1L,
  43623. 0x0cbd6f6e7854e7cL,0x1ae8ae1c65bd22aL,0x1810698ae46a250L,
  43624. 0x1ecaa3656cec8a2L,0x19dc8447a5e979fL,0x0faa493f05d357eL,
  43625. 0x099851df63ca29fL,0x18e871f2d4e29cdL,0x074ad5bf613552dL,
  43626. 0x012d5a3c08b3808L,0x1d3ceb3eb6efd80L,0x00cea42a371953cL } },
  43627. /* 65 */
  43628. { { 0x019ee8fb540f5e5L,0x152978273468bffL,0x16c2b6f721c61b4L,
  43629. 0x11a074ff91a4641L,0x08bcb916a83ad5aL,0x08f4202a5fc1e38L,
  43630. 0x1777c2484cfa8b9L,0x10779c7084996a5L,0x0d5c7be40310635L,
  43631. 0x0f5dcefa2c718bbL,0x0658e6f136aeff0L,0x1fc980ae4b515f6L,
  43632. 0x1484e1cd2436350L,0x00a2dc6f5625031L,0x120c8deb7dcc553L,
  43633. 0x04e40154dbb3d66L,0x1b0a3345c3dcbffL,0x00d9d67365a7229L },
  43634. { 0x143e5e990a8bdc5L,0x1dfceb183504481L,0x08d63921483a880L,
  43635. 0x1dbcfa3a0d30913L,0x1f795d3fbd17debL,0x1d851fc7d7d36baL,
  43636. 0x1abea933ad8c0e1L,0x005c02cd665ffbbL,0x0a2fe20547e764eL,
  43637. 0x0d5cc127438f982L,0x14daee54bb11795L,0x0909521a4195457L,
  43638. 0x0775bcfb537b4c1L,0x14c16272a98cf9cL,0x00a4874d08e2929L,
  43639. 0x162fd4576c38f42L,0x0141e061b64db3aL,0x029c7619f0c9785L } },
  43640. /* 66 */
  43641. { { 0x13496fea19b56cfL,0x0bbfa3ddccd668cL,0x1ea15f42a20598fL,
  43642. 0x0410506bfb1e095L,0x1d82cec7cced3daL,0x004e42bf10fd76aL,
  43643. 0x08c1db85d6e67e0L,0x105b38dc6365a0bL,0x196948d4a81487dL,
  43644. 0x175e9f96a37b32aL,0x146aa1dcf331261L,0x1e45162c814d0d0L,
  43645. 0x0841a20b753e220L,0x08560537cf8371dL,0x0facfecb3fff97aL,
  43646. 0x1c593eb5363b51dL,0x0012587d9976e08L,0x037eb014c01f4faL },
  43647. { 0x0709f8d8eb7516aL,0x0c53a5ee2cc55aaL,0x16621fa0073a0c1L,
  43648. 0x01a2f7152da469bL,0x0e90f6abfd0f9d9L,0x1f6aadd50f2a4fbL,
  43649. 0x13064925bfe0169L,0x0ea1b3ecaf4d84aL,0x03cdea49cb89625L,
  43650. 0x142d1f816ff93efL,0x039ff76e2f012edL,0x01ff30e46d6078aL,
  43651. 0x1dbb0d5055904ffL,0x10a5f46824a14c7L,0x0f4c358d2cce1b7L,
  43652. 0x1fbb2f5a69d38f8L,0x1c01f2b32bde159L,0x04267d11e63b0f2L } },
  43653. /* 67 */
  43654. { { 0x1bc11eb8b99b964L,0x006052c717e2389L,0x11275326952e38aL,
  43655. 0x057edc41f50e1f7L,0x17c88cfa37a334aL,0x0578ed772c1e86eL,
  43656. 0x1e2981780a6a3bdL,0x0c4daabc468185dL,0x161b6fdfe209e9bL,
  43657. 0x18ed6935dc70407L,0x0f058a4e4bf068eL,0x1fcc155c7e9cb5bL,
  43658. 0x1ac2bf4d5b02ac0L,0x01417f6946ccc00L,0x0b6ccfc8ccfe4ffL,
  43659. 0x0a5ce2db962196aL,0x18e09f90f84c557L,0x0143ea628e42506L },
  43660. { 0x1a582010e9867daL,0x0c4d98d43a66d2fL,0x1f17ef7b88b9851L,
  43661. 0x0bcc257b5000bc4L,0x0d3635f9e357fefL,0x092d432706df6f9L,
  43662. 0x08b958af9c391bcL,0x1a3413731081b29L,0x17eb99a1528b5e5L,
  43663. 0x0dca0b73a88145aL,0x0dff5f81b4b3108L,0x0a2ffd41308a362L,
  43664. 0x06ffcecbd76fa1fL,0x0197a29f1dd0f4bL,0x09a3e875322692aL,
  43665. 0x12b460f63c55fd9L,0x013d0fb44534bd3L,0x0009951ee6c77cfL } },
  43666. /* 68 */
  43667. { { 0x13c7785576374c2L,0x09368c239382072L,0x17208a328113981L,
  43668. 0x05e39c2627140cdL,0x0deb0c5d1fe1c1bL,0x1fc137957764196L,
  43669. 0x096269d659a6672L,0x0a99a311d03bcefL,0x0e5ce0fe0118d12L,
  43670. 0x0a154c203c85c35L,0x1c10fce6b0a33a8L,0x05210fbcb009c51L,
  43671. 0x12f639a8c54eef8L,0x0c43bca7c1e18d9L,0x0c6ce475c11529dL,
  43672. 0x18f2b94c6baa031L,0x025cefea07631d9L,0x009e5f73b5b7c55L },
  43673. { 0x1cabe0f8d3f34f3L,0x0e18e51b0bff1bcL,0x188f76509a86f6aL,
  43674. 0x0fe539220964dbdL,0x02c6cd3be9dd962L,0x1d10cb019f58b4fL,
  43675. 0x120f229cfd24bf2L,0x16f25c6fc1770b1L,0x0e4f2aca623b3fbL,
  43676. 0x080fd8f325f0051L,0x1e09aa523d91220L,0x0f6920e4c1cf234L,
  43677. 0x10e30bb83541406L,0x04cce0377bba552L,0x0821447e48b2a03L,
  43678. 0x009e0d70c6b7217L,0x167bf936b5c25faL,0x027050d6d701744L } },
  43679. /* 69 */
  43680. { { 0x0ca66708ba29c4dL,0x12067114c404a00L,0x099c5b769d4b020L,
  43681. 0x0b5777f468438b9L,0x1ed28b72689c0e4L,0x02b55a0ebaa2fe9L,
  43682. 0x075957c8846635fL,0x112967b1ee870ebL,0x093490dfb8fe50bL,
  43683. 0x120faebf4075d0bL,0x1697ade6b2d4dedL,0x092e183abcbcf61L,
  43684. 0x0da5da429aab6b1L,0x17b69792919c734L,0x0c3ce9f804310dcL,
  43685. 0x0117844de2da4caL,0x199efb0f7b6cbefL,0x0399f186ccfcce4L },
  43686. { 0x0fe1582a42a38f9L,0x16ac723985a8076L,0x0a9f7a5dacb2bb0L,
  43687. 0x0b52d383765dc5eL,0x1cecdb4af0539dbL,0x14748118caa0b47L,
  43688. 0x1507fcbdcd22b9eL,0x0a43ab1af986242L,0x15d25b75c2202aeL,
  43689. 0x154cb2d7a041ad3L,0x0da9054a6d391b7L,0x16df7a4f5b367fdL,
  43690. 0x00261f900b5c97fL,0x026ad8cf6c3aaa6L,0x0866e72d0c0c764L,
  43691. 0x0179e67abd37196L,0x00c7a43d4923ee0L,0x02b7d659cdbcd2eL } },
  43692. /* 70 */
  43693. { { 0x19165a2a3018bfaL,0x035924ffd6cc200L,0x07d954d06a6c403L,
  43694. 0x0e4bb8999377e36L,0x0bfffe60e6bd1d9L,0x0a84d5a942876a9L,
  43695. 0x167c493a64b31f9L,0x091fed8a05c99d6L,0x02f0b35731aa7d1L,
  43696. 0x0860eeef3f1d523L,0x127d174450a203aL,0x1a4ccb7cbbab75dL,
  43697. 0x0e1febce13475cfL,0x004a169841d5d8aL,0x1fa0b21aae920a6L,
  43698. 0x0431a3c3646ba52L,0x0bbb771cdbe50d8L,0x0442cc9336ca6b6L },
  43699. { 0x0847290155ccaf2L,0x0f5e3be2dbb9f04L,0x1746cb7423b619eL,
  43700. 0x1d0fa8ebb751165L,0x0694d02a960a180L,0x1fcf4b407edb5bbL,
  43701. 0x0db10fa1d6324fcL,0x0fb7b47edf495b0L,0x19400c58132fb38L,
  43702. 0x0d3c2a112a81007L,0x1f0d45ddbb3c609L,0x08dcacdb6b34552L,
  43703. 0x0026545eda03ebfL,0x07ba55a223a1d14L,0x12cfda7b45a7613L,
  43704. 0x0e32d7557263b11L,0x11970ae932cd825L,0x03cb9125350604bL } },
  43705. /* 71 */
  43706. { { 0x12923f8441f3567L,0x018b417125f8eb1L,0x09aedd9c7fff047L,
  43707. 0x0ef4bc3444972eeL,0x1addb417601746aL,0x0cdc2329eeef501L,
  43708. 0x1ffdd5e19e8f1fdL,0x1516025530ead9aL,0x01bd5fec9f19ba9L,
  43709. 0x081bcd17c1833a4L,0x0d1176ae301745dL,0x0836f207e854eecL,
  43710. 0x0da903e46d5d7f4L,0x16e89360e008b3aL,0x1156d006c74f136L,
  43711. 0x06add44ea5558c2L,0x12c4da42a68555cL,0x01ff84e0aec1042L },
  43712. { 0x00a1bcef9cb7784L,0x09cde12117982a6L,0x07f431052a9ebb1L,
  43713. 0x19ffa85788be81fL,0x0f358e15d3aa316L,0x113b41217ad2619L,
  43714. 0x1b3b802f7367b5bL,0x0ba0d3ef13ff14bL,0x18078018e05e14fL,
  43715. 0x1d9f249c5a063a0L,0x123075e45fdcb4aL,0x0cc998ae2a18bb7L,
  43716. 0x1ac3fa8920e0eeaL,0x0e3cb8b2512f662L,0x12b45acf086c3d4L,
  43717. 0x03b351e1345e4c6L,0x04c8e730fc55839L,0x023f78c02a7efd7L } },
  43718. /* 72 */
  43719. { { 0x165f3d13da285e4L,0x0a6dd1d00f1fa4cL,0x04e984852b42e9fL,
  43720. 0x0a4472ea928e708L,0x1a730b92d3b7d53L,0x168b2ed29edee7aL,
  43721. 0x1fbd0c4c364acccL,0x16c89450a8305f2L,0x1bf62221c44dce1L,
  43722. 0x1d09c2c3f150764L,0x0cb2372feb6662eL,0x1e7f6bfda89667eL,
  43723. 0x05c66217bb409e5L,0x1e6fb8d4ae19463L,0x0481e22c036da7fL,
  43724. 0x08c974478544371L,0x061f8ab28e63ae6L,0x00d35b74e5c6f04L },
  43725. { 0x16ec2b606af77aaL,0x07ae6d443f832d7L,0x10027d263158b98L,
  43726. 0x13f9755e970fa42L,0x071ab855db595b5L,0x1a4d8607dac9509L,
  43727. 0x032728338439750L,0x1b73ac30fb110fbL,0x103ee95f9154bd6L,
  43728. 0x1f29909ae8364ccL,0x1ef0c3eda993423L,0x1e1acd4996c1e94L,
  43729. 0x0f5d37367c3d22aL,0x0cbec72a8b4a967L,0x05ccb41bc3a9cd2L,
  43730. 0x07285688f8e1ee6L,0x1d000ab3034a9cbL,0x03cee80c0142887L } },
  43731. /* 73 */
  43732. { { 0x0e0033a3ac7424eL,0x15b44307ed26802L,0x1d9af2ddcbef6c1L,
  43733. 0x17e52f9b4846d52L,0x1b013c6e294a8e2L,0x11d1d6a58555c2eL,
  43734. 0x129acf4abb2621cL,0x13c195c659a2790L,0x021888f5e70ec16L,
  43735. 0x1cb19dea1544131L,0x11e4b9ed8366e1cL,0x0e4420ed3fc2d15L,
  43736. 0x06d24bed3489f2bL,0x11f59255479fe7fL,0x131c1af4d7bee22L,
  43737. 0x19c1bbbd9f47e90L,0x0367cc119a9929eL,0x043f2d6a2c6a02aL },
  43738. { 0x099aa9d7d1000a7L,0x057fe57411c19ddL,0x18a37ee0f7162e5L,
  43739. 0x0308b4831b90452L,0x1d4170542f59fe1L,0x1b8ac0d45cb87c2L,
  43740. 0x1745e24630995caL,0x181c9de8efb81a3L,0x1b50b4cf33afad7L,
  43741. 0x0dd753c80c3852dL,0x021fe6ece8a1a08L,0x063c2494b39b8eeL,
  43742. 0x0f57f4323978575L,0x00b264a576ba613L,0x052fdd357d6b894L,
  43743. 0x1d464cc116fc5e1L,0x045f4cdb5bafdceL,0x005b8928ccc8660L } },
  43744. /* 74 */
  43745. { { 0x0290ca188d5c64dL,0x16ba4d3a4929a2dL,0x14f4a803a494165L,
  43746. 0x1995ef6cd740961L,0x0cdded83082cd02L,0x18b2374895a8617L,
  43747. 0x1fe5604f3a77bfcL,0x02ac55ce18f8ebfL,0x16f6852e07e2a46L,
  43748. 0x107ebe801c027e8L,0x0a93760863a364cL,0x0df75f8c8baf634L,
  43749. 0x01e8d9fdbe4918aL,0x02385b777d8407dL,0x05d3bdccf534229L,
  43750. 0x1cba5a57440eedbL,0x16d8ecb95a769daL,0x03d1fa11d3eb4acL },
  43751. { 0x02d2ca69a929387L,0x1bac0e58e0fff9bL,0x127df946db2eaf6L,
  43752. 0x04749c263fb125dL,0x1bd87561ee8d863L,0x13f399234071f8aL,
  43753. 0x1fbfb8e965f8753L,0x016798e56f8ab03L,0x1f3e77f8aca8caeL,
  43754. 0x063ebee2f17ea57L,0x09154884d56de7fL,0x09e54580e2efba7L,
  43755. 0x0d0689621f546b2L,0x1fbc0b1f20ada99L,0x15fb484afa6bd44L,
  43756. 0x052864fac773667L,0x0f4ab019ef29680L,0x016d2fe2a8b11fdL } },
  43757. /* 75 */
  43758. { { 0x0429cf3c8a5c600L,0x006111ff19f3e31L,0x1d00295f772e9eaL,
  43759. 0x1b24b618e93ffb4L,0x0b100eb0d1ae156L,0x0a1e4084bd21fcbL,
  43760. 0x13c905a7a5173beL,0x06743ee69ca2251L,0x004387c4a419f01L,
  43761. 0x003c34580822012L,0x05aafe40d673cb0L,0x1fdc8f1aa9c7ca8L,
  43762. 0x0642a2173ef9c76L,0x0ff180a0b310cedL,0x1bc91f98780c55aL,
  43763. 0x0cb2541feb9c727L,0x0d3811792ba072bL,0x042af810cb8642aL },
  43764. { 0x1fbfb6c847314c4L,0x030aaf5a2dcb530L,0x0519ae8abeb25e4L,
  43765. 0x0b57292f02e205cL,0x0110c4feed51f97L,0x1abb33ce97ad8beL,
  43766. 0x1139deb2339c2bfL,0x18fce6cd442dd64L,0x0dd1bbcec551c65L,
  43767. 0x092830570d42cefL,0x1205d22e9f4b9edL,0x0a83571d5188f40L,
  43768. 0x036fdff078e1a2cL,0x0a43a582373c126L,0x0c7dccde6d27f1cL,
  43769. 0x1cd9e455c66fe0dL,0x1971c3521926f8fL,0x014911b67a92e83L } },
  43770. /* 76 */
  43771. { { 0x1b8d80a7d8b29dcL,0x110120475324566L,0x117aba4afa4745eL,
  43772. 0x11fb4e5f78fb625L,0x1e760c6f1f347d1L,0x11c6c8889ba5a04L,
  43773. 0x107d1cd87a3c763L,0x09cee297d3ae735L,0x1c1f9701cb4df5cL,
  43774. 0x089c76c37b96570L,0x1f87ddab4603136L,0x0b7d3c5b7f3838fL,
  43775. 0x097c70c44df8c18L,0x1868adafc1aed93L,0x199517be65f3faaL,
  43776. 0x09cbca20288b4c3L,0x1aa16b068842518L,0x03e7d61acba90f3L },
  43777. { 0x11821673c0bc53aL,0x0f6f1bf3a89b3c0L,0x17f68d95e86212dL,
  43778. 0x09743fbb307944aL,0x05da77d8096abbfL,0x19a162ce741b4feL,
  43779. 0x167c7c9ee6b9eaaL,0x1d20d9237ad2e40L,0x0ee0dab30914ecfL,
  43780. 0x1b23fddc9fa9f89L,0x0e29ebfe95f83aeL,0x0ddf3e55ac0e618L,
  43781. 0x07bb99dcc9517d0L,0x02304050a4b946cL,0x0e705f6c00d2bc5L,
  43782. 0x045419902187e25L,0x0bd7225f14f772aL,0x03671ee3f8eefc1L } },
  43783. /* 77 */
  43784. { { 0x07cd835a4397830L,0x094867a39998360L,0x0ea0a6627a31376L,
  43785. 0x12ac7b02a5ba6baL,0x087de61b7990255L,0x1271ae793c6c88fL,
  43786. 0x0396671cd031c40L,0x1425a8888c2941aL,0x163e7608ff32626L,
  43787. 0x13d1bf4e264dd54L,0x1b7145dbfff4958L,0x1f919de5439a18aL,
  43788. 0x16efc559d9cb6deL,0x020e5b4965e606aL,0x0587827917cff14L,
  43789. 0x0ab399a0b8473caL,0x16d2a731ee95c3bL,0x0428a889151e850L },
  43790. { 0x02d033586ff19e2L,0x106d50ed14301bcL,0x13f955f1fbb70b1L,
  43791. 0x083789d16165cf1L,0x1df35c67a8f6f98L,0x122315660fcda59L,
  43792. 0x182c25b84d80d1dL,0x0ad7f22172ef8f5L,0x127c7f305514359L,
  43793. 0x0a6d8ae7b18f572L,0x158509f9a6cd330L,0x10a2bf825fe54a3L,
  43794. 0x13fb887162dec82L,0x0f0a445efe67570L,0x18f9d3368ccab07L,
  43795. 0x00d394406e9c45dL,0x004597ea1a1f0aeL,0x04588acf93bdef6L } },
  43796. /* 78 */
  43797. { { 0x0f71a442f961d30L,0x0b4543d639247a5L,0x01f2c6a41b36f7eL,
  43798. 0x0c0957f24ba65bfL,0x19f04d4c00c10e2L,0x0b82ed5c388bacdL,
  43799. 0x02124035539824eL,0x0ebeeb0e86793f0L,0x02e9abade6a7a23L,
  43800. 0x13b6a3c4a560bd6L,0x01496f080b66715L,0x195b57f5ce7a994L,
  43801. 0x183405991b95b8bL,0x02c54ce191b8f69L,0x1e32198ada791e9L,
  43802. 0x058f8f958163056L,0x0596ceaa79be023L,0x005ec3219ac47baL },
  43803. { 0x0a1a8b47e734189L,0x0d64467f2fd0befL,0x1538450dd9914b1L,
  43804. 0x115f3d2ea088949L,0x130c6b3bc252230L,0x16fa3bbc58e861eL,
  43805. 0x0375cbb6b97c131L,0x068a6263b345dd1L,0x0c4e380eeacc93eL,
  43806. 0x04cd8d6546d8747L,0x123059fd75275f5L,0x04ae2aad99aeee6L,
  43807. 0x0c2611d13dc9663L,0x1ad17ee632e7074L,0x163ea84b257f99aL,
  43808. 0x059304cd310650cL,0x107da87d1f431c3L,0x0233282cc7e6c8cL } },
  43809. /* 79 */
  43810. { { 0x06c13cc6b4a5efaL,0x0cc4d8e83d932a6L,0x1b3a2f71a703120L,
  43811. 0x04584a63a82172cL,0x0ad0a100f54cfaaL,0x0ed224e5af8c046L,
  43812. 0x00f32fad494e3b9L,0x0f14c48010b7dbbL,0x1e792dacfd6255cL,
  43813. 0x01b8c83103102c7L,0x057a0fb45963062L,0x164efa51aa852ccL,
  43814. 0x1b83b75df34b549L,0x0bfddca1757893eL,0x1df24c13d837db4L,
  43815. 0x0f13fa10c63b7edL,0x00c17c38f986018L,0x00621aba55cd494L },
  43816. { 0x0eb324c1d20cad0L,0x16584c63088453bL,0x0e71bc1b4db6437L,
  43817. 0x15781b432f4dd3aL,0x107ac5ce6cd978bL,0x04bf5aaca458e02L,
  43818. 0x0538caf51c59315L,0x0785538981e9ab2L,0x0772c5046a759f0L,
  43819. 0x1eb994534d6423fL,0x15f430c122ccc39L,0x09c081ef759d51aL,
  43820. 0x13a85f1790e6003L,0x0e42cb9b411ec8cL,0x078408a9ba6d9b1L,
  43821. 0x07f48459458f4cfL,0x1b900e7a19c0902L,0x01924ccf893936aL } },
  43822. /* 80 */
  43823. { { 0x07eaed67c834915L,0x1d5355e2f5b26b3L,0x12d8975880467ddL,
  43824. 0x04d33fb384e53d7L,0x0b8d4f6c0aee24fL,0x04bb6b70f5ac3a1L,
  43825. 0x1a995fc49c43053L,0x0c92272066bedb3L,0x1668b704906b500L,
  43826. 0x0cb4d07043b7727L,0x06fcfcbe764d819L,0x0ca36933c79df20L,
  43827. 0x1bf2dbcaaafb1a8L,0x0b9d835b405ca9fL,0x1cdb190c4b3159aL,
  43828. 0x1b02a6a69b38675L,0x191e4463a5210ffL,0x02bf515a5f8c615L },
  43829. { 0x0f5e1628aa0f2f2L,0x13ae287235e5500L,0x1e6a928b10b631fL,
  43830. 0x14297544052f568L,0x0943cc2eb4f308eL,0x0ac4025480de8a3L,
  43831. 0x03df2ec497fbbbbL,0x038ca0591f33a30L,0x1e53539191580c6L,
  43832. 0x113c03493880f71L,0x090287ea9c9c5dfL,0x1c0498eb62a6f41L,
  43833. 0x0b538f1c2232edcL,0x1f183e976d11b30L,0x0bb82d135447a62L,
  43834. 0x1e60e484edc8137L,0x1c9a78c39277ff1L,0x0302405a3753c9aL } },
  43835. /* 81 */
  43836. { { 0x1087d663872ece3L,0x0df3ecaadb87c18L,0x1f1e73e56ee17caL,
  43837. 0x1bb7ff4c436a169L,0x0022ba5dbae3b58L,0x00a24e0730e9407L,
  43838. 0x15215e2b9445d06L,0x01c162650819eaaL,0x1800ed1b6b8ce0bL,
  43839. 0x0effeeabc6aef1eL,0x108dd1a695ad1cdL,0x06d31b2215cfefcL,
  43840. 0x006313c7c7d5e32L,0x1496f4f2db7fa95L,0x08442ed68bf8836L,
  43841. 0x0de4683668fa7a2L,0x0ccc5905edb40c1L,0x003ba5069cd47c4L },
  43842. { 0x0e181abe3b6c106L,0x10b1fc6f0a85b9dL,0x00bdbcd520d93afL,
  43843. 0x06758f582d9eeb7L,0x091722afaa0d206L,0x0a2aa9ae3403341L,
  43844. 0x18fddce50798445L,0x1b42e24fc717ebbL,0x132cfdf031afb41L,
  43845. 0x1449e48c3de4331L,0x119d1298b272671L,0x1c5b2c58328eea0L,
  43846. 0x1f378cdf4c96866L,0x1a03fd19244f646L,0x04a4344e981c26cL,
  43847. 0x044e7a6fa42b2aaL,0x14b9623d303bab9L,0x0040a8caa121900L } },
  43848. /* 82 */
  43849. { { 0x1236d89fb7b2108L,0x041e656bafcd57cL,0x0c56d3876844fb3L,
  43850. 0x1e062b86c5ef8e5L,0x1272fe3f552aeaeL,0x021f7408f0a076fL,
  43851. 0x0c96e675e6fda1eL,0x0e99cd6a9fa3b37L,0x1b20b0e215b1badL,
  43852. 0x05010a7adc26486L,0x0efd4bf29b3b255L,0x091b3c9beede8b3L,
  43853. 0x0ed64cf17ee363cL,0x1b156d241822fc2L,0x1d32806100a859fL,
  43854. 0x1885a593c37e6d4L,0x074e8cf9d41f691L,0x02d5f90bc61625cL },
  43855. { 0x177966bf3b3bccdL,0x1f0785f1f065523L,0x0ece31f5410c011L,
  43856. 0x1f28dfabf997070L,0x09ec0e87e77e3baL,0x10c692bcdd53c2fL,
  43857. 0x1f3fb60f155f322L,0x0c3372dcb5e4b7dL,0x14f05d15e98c71bL,
  43858. 0x00fcc8d3bf316d0L,0x1b1e072ea8e0842L,0x0cbbca9b37f638dL,
  43859. 0x1344ed14307522fL,0x0ae57eed7ae82abL,0x1e3d6fcc0d6cc7eL,
  43860. 0x173b28fccfe86c6L,0x048029f7cad5270L,0x00ad68ac3a6c8b5L } },
  43861. /* 83 */
  43862. { { 0x0de2eceaa588ae4L,0x15e2c51b8d11900L,0x04d1c48c111154bL,
  43863. 0x1bc963065ba01d5L,0x1689e843afbfa67L,0x1a71741490b1a0dL,
  43864. 0x077147e5aeef587L,0x1a32a840d080985L,0x0c7fe382742317fL,
  43865. 0x050576331a418b1L,0x0e53441c00613f8L,0x12e7fc3f7b0bf85L,
  43866. 0x11fb07435207219L,0x023729c93245b55L,0x1e95bfc8eef6ab7L,
  43867. 0x04bec1b71ba3e01L,0x163104815eb8667L,0x01fce266529740cL },
  43868. { 0x136b29732ce637eL,0x0af96fae92e6effL,0x14b62c0ab65e068L,
  43869. 0x199f7567d2343a0L,0x014eeb752e5f3bbL,0x0d3c9d306965ebbL,
  43870. 0x085135124610f35L,0x0cc44859eeb9b74L,0x0a20705e788b997L,
  43871. 0x0709660763bf099L,0x0537dad86a6c159L,0x1e08e904b6b5638L,
  43872. 0x013da312238fd97L,0x06986386cab0241L,0x04bb9a779219c9dL,
  43873. 0x1127b79571e2a38L,0x14b5dc638b4668dL,0x0323ced6b111fabL } },
  43874. /* 84 */
  43875. { { 0x09044f3b05f2b26L,0x114a5405cfbb62bL,0x18a10a43dabacd6L,
  43876. 0x0604d4b0ef1073fL,0x0e5ff9c3761cfb2L,0x08e2bb3b44935b1L,
  43877. 0x0fbfaeb9b34802cL,0x075b90aeeace540L,0x00cae074ae1bad6L,
  43878. 0x1f248d0eb84ecceL,0x177b5994076704fL,0x19438655dfeeed8L,
  43879. 0x15c57683e81da6eL,0x0fcc6c23a8424eaL,0x166959278e4ba73L,
  43880. 0x13165f5af305ec9L,0x097f7c3bdb7a37bL,0x00ff04fca784302L },
  43881. { 0x1a7eaae7648cc63L,0x11288b3e7d38a24L,0x08f194fd15644faL,
  43882. 0x170342dd0df9172L,0x1c864674d957619L,0x0b2ccd063f40259L,
  43883. 0x08ca3f2204d2858L,0x13c6cdd52d214caL,0x1415329604bc902L,
  43884. 0x1cf0cca57155695L,0x0a3149fc42fbd7bL,0x0b0d8cf7f0c13c5L,
  43885. 0x1a844cc25d73dcbL,0x1a759b29fb0d21fL,0x0903c0b5d39fba9L,
  43886. 0x17969e66ace0dbaL,0x06aeec7694cfd83L,0x026f4abc36db129L } },
  43887. /* 85 */
  43888. { { 0x067d3153deac2f7L,0x03bc55b0ecd4724L,0x1e582adecb56821L,
  43889. 0x0d9fbe9ef3e76edL,0x11ab8f4b00b3005L,0x1bce80e8380f0a9L,
  43890. 0x14dc41fe5235671L,0x180f9329d7904ceL,0x01104d4ee48bad4L,
  43891. 0x0c6705adfe4e82cL,0x0a2634c27ea02deL,0x044b59667d5f8f9L,
  43892. 0x1c5b2f31750244fL,0x126bdf1a6a8f46fL,0x080ad0cf926e9aeL,
  43893. 0x04eb42ec1e98f7bL,0x00c37e36a7e4435L,0x00e4a20c5f31b4cL },
  43894. { 0x1a2131309dc1414L,0x1b2fe21e49a9ba1L,0x01eb7d7de738181L,
  43895. 0x150ba99f94dfe64L,0x03e995ab6f18b1fL,0x1598017ae213973L,
  43896. 0x1fc5848682792a0L,0x04d056cba372e28L,0x04993c20c20a7feL,
  43897. 0x0e4e5cc7338b393L,0x0b59cffad102826L,0x13c24a36978ab40L,
  43898. 0x14a05338ea3f3faL,0x1d84fb65baede23L,0x10d1824f2d0112dL,
  43899. 0x1d584cecfb43100L,0x1ba97851422098cL,0x0308dfdd95aa91aL } },
  43900. /* 86 */
  43901. { { 0x1baa55ef00ad2a1L,0x1d42f0a51486bdeL,0x1da3a4ac5a50a7bL,
  43902. 0x1a23d9026076948L,0x08bd27b267111bcL,0x101e0307212b814L,
  43903. 0x0212bca33ca8f66L,0x04176f91a5be631L,0x1e2ea1462e3aaebL,
  43904. 0x1a9ac0221dc2ebbL,0x191209553ba6f4cL,0x1d3dcd54331f03dL,
  43905. 0x04c26c5944eb2eeL,0x01558b3e3d2d540L,0x1f8869683bcb696L,
  43906. 0x0531cb45568ec05L,0x08d169cb3b83370L,0x0437362a20759d5L },
  43907. { 0x1e033210b793d9bL,0x1d6f08eedaf6776L,0x0a49a24c2d93de7L,
  43908. 0x1bfc9fa365ee7fbL,0x12a4dc8806aad97L,0x0bb6ba839d2d8ecL,
  43909. 0x09b022be32f62f2L,0x00cc1695762c79cL,0x19c8300a9dcb1fbL,
  43910. 0x1ad2ca66d4ad9e9L,0x1f5f52cdfab21ccL,0x174441ddf5563f2L,
  43911. 0x06f3e828c8a3d2eL,0x02d5bbc0992c648L,0x0a2d85f20c985beL,
  43912. 0x1705ae4b2e32518L,0x06dcd7196bc3233L,0x041c33f5c8cfd09L } },
  43913. /* 87 */
  43914. { { 0x14fe73e22474edbL,0x131ca0d4270d73bL,0x06b671b75b8ca9dL,
  43915. 0x0a29f17eba4e065L,0x12267b9000c4a41L,0x0927d71e71751beL,
  43916. 0x06de049d4c05447L,0x00cf829b0a84c74L,0x020c8401b1ae0b2L,
  43917. 0x195008d840fa4feL,0x048fee5671b7e3cL,0x18f9001c3a0c3d0L,
  43918. 0x1824259a9aa328dL,0x1bf7b61bac3b51bL,0x0f5327c8eb6a2d6L,
  43919. 0x0713e047ed6dd52L,0x19e89f5414dffb6L,0x025935dd1731459L },
  43920. { 0x10b1cb45d318454L,0x1ba4feba1b65b69L,0x1c995a29d18448eL,
  43921. 0x063909fa3c62218L,0x08403d55c85de12L,0x0fd5fc52fc6b730L,
  43922. 0x17380e56db84e6cL,0x021fcdad18679fdL,0x11d90381f94b911L,
  43923. 0x054754096e6375bL,0x00104dfa4328afcL,0x180f9144b8b4b3dL,
  43924. 0x1a5d84663cbeb5fL,0x0885b53e004e129L,0x023e35402c541ceL,
  43925. 0x03ccb0c0fb49882L,0x1c602c3d9c3cb90L,0x026b4bde2964b0aL } },
  43926. /* 88 */
  43927. { { 0x0db1ef0efa8fb40L,0x10e2dadd1cc4e70L,0x0c560274677ca40L,
  43928. 0x06982433c351adfL,0x14ef05e26b787b7L,0x0bcb71320bf0b40L,
  43929. 0x1086d124d0b6e3eL,0x06c5f0f14bd7f08L,0x1e71916d7e94a45L,
  43930. 0x00c5dd1d708cb49L,0x1d2fa55da2013a6L,0x0e99f0849f15d8cL,
  43931. 0x1d466ce6ab0a260L,0x049003c5ede49dcL,0x1c3c68ecfc56a63L,
  43932. 0x10b4f3a21fa1a70L,0x180a61241d9e4e7L,0x03b6543d0f36466L },
  43933. { 0x157fb56e02e48b7L,0x0a589e604f4e321L,0x10d4901a73c3ef4L,
  43934. 0x1858760353b6be4L,0x06956dadf878165L,0x0b05b472a4f3e27L,
  43935. 0x1194fcbfa54e2efL,0x1372a5f0ad60b3bL,0x0d3f60225b377feL,
  43936. 0x10639945ff48462L,0x0a8b4ef23d7cb5aL,0x08864884a0a19cdL,
  43937. 0x0a3d3b3ce5f7213L,0x00b3ba890bf0933L,0x1ee2529d6d790ffL,
  43938. 0x1c6ea2b24e0c46fL,0x1be152607532be3L,0x013f3f96336d1dbL } },
  43939. /* 89 */
  43940. { { 0x18f65ade6a15883L,0x1f3463357ed99b1L,0x1aaf4fc4b797529L,
  43941. 0x006f70f020c40f6L,0x04acf6d31c6ff95L,0x1f3c61606a26593L,
  43942. 0x0603858eb1807caL,0x13638c798b42c6dL,0x03e92cfe895c934L,
  43943. 0x19c706c20f63910L,0x075d90b57ea585dL,0x0d8387c051d2c2dL,
  43944. 0x06b16d54092aa77L,0x1836fa6cc9ee2b2L,0x071ae5e82c9fed5L,
  43945. 0x0be813d3222e19dL,0x128ea8e42be53c8L,0x00174b21bc19232L },
  43946. { 0x1540addae78ea1fL,0x0dba6bdb3874b48L,0x1107dc01a099468L,
  43947. 0x14faea418ff326cL,0x09ce12e18f97d6eL,0x1041a107d535013L,
  43948. 0x110d89642b2a1e4L,0x11ef49070c6eac2L,0x007c6149ef38140L,
  43949. 0x19dfac26bc29a03L,0x06c0426aeedbddcL,0x093fea5141350ecL,
  43950. 0x182e00ae3ce4eb2L,0x10bc77fd043c0f6L,0x144e9fa19306c94L,
  43951. 0x00c5f983cc5453aL,0x07dedb8b94e1919L,0x039cfa9ed278b29L } },
  43952. /* 90 */
  43953. { { 0x05f4a88924adc5fL,0x0360b540c7ab6bdL,0x04a5de57e552559L,
  43954. 0x1ba338a8001d892L,0x005912b42b48753L,0x1d24a30b7d11b59L,
  43955. 0x14199acf597cfa1L,0x0814e2e940208bfL,0x1b635031312a5e1L,
  43956. 0x1ce25a254b5c311L,0x0e75966ac00f569L,0x018c704de634f46L,
  43957. 0x0c6f7090cdc72f3L,0x08375f125a739c8L,0x091416966b1b0daL,
  43958. 0x08274734fe0db77L,0x084839991e1c58cL,0x0010611ffd10707L },
  43959. { 0x00e4adaafc74661L,0x1e7b193bfe03289L,0x13dadb739e64deeL,
  43960. 0x06f62c374282093L,0x09610fb25b8d6b5L,0x0ef3b49110c218dL,
  43961. 0x018c37a7b27477fL,0x097a657f49a85b0L,0x13885702a6244dfL,
  43962. 0x0f6e8f6a2ac96fdL,0x17d16fed3806e33L,0x1da50dc42b601c3L,
  43963. 0x076a937e6a8f4bdL,0x00987b91c049aa4L,0x0a087e10549e2eaL,
  43964. 0x09f158db88d2471L,0x0ef2207b119fd8bL,0x03b73dfa9fc934eL } },
  43965. /* 91 */
  43966. { { 0x112842827ebd187L,0x19055db2d56ddafL,0x1969c8961a5634cL,
  43967. 0x131e130d576084eL,0x0ebff503da3f33fL,0x0fb8d2a08c03d3dL,
  43968. 0x1c92c971ddb2a09L,0x16981bcf7dbfefbL,0x1da8b0f42165f1fL,
  43969. 0x19ffb9bb98f9d71L,0x075f9c64f829497L,0x15476d67748c99aL,
  43970. 0x17aa1f37828df84L,0x13b99d63dd425c4L,0x0606885b9e58333L,
  43971. 0x101da9a8dad56a1L,0x1091ec12c257cbbL,0x03cf3d69395cb77L },
  43972. { 0x0d970dc8f30caaeL,0x15e7885375f7a1eL,0x18fb1c5185b6172L,
  43973. 0x16a33c7530c7830L,0x04cb13d61c50db0L,0x0a3db4f9cdc4b1bL,
  43974. 0x0c3337d9f607c89L,0x16ee2af5773acfbL,0x0ccca25ba889491L,
  43975. 0x144903e3d13f06eL,0x1a3ef83f50ca07dL,0x1ee6ae41d812695L,
  43976. 0x09cdfd7beda5d91L,0x0501cf19597b0c8L,0x0363f707b0408c9L,
  43977. 0x000bba787acbdb6L,0x09432c916c84fe5L,0x03fc61bd62605f5L } },
  43978. /* 92 */
  43979. { { 0x1ec1e5443ac05e5L,0x126d266c69c1299L,0x102e22fe78af692L,
  43980. 0x016a7023b90db11L,0x03c3aba434d71ddL,0x0b08df32a820695L,
  43981. 0x13e80af102526d8L,0x186385a84dc4f34L,0x0535a5aa23b065aL,
  43982. 0x1545197e2975448L,0x17b29e7f76b48b6L,0x0bfa556764deb4bL,
  43983. 0x1bf37cd81e911f0L,0x0868b5c62ed673eL,0x1d625383839139eL,
  43984. 0x14e9e2bcd15dbc9L,0x02fafe04999fc92L,0x00ebb81d54b873eL },
  43985. { 0x0a4c81d3f0062a9L,0x1595c6cb5105d54L,0x037e192f44078c7L,
  43986. 0x0488276c28cdbb3L,0x09a555f8ba05f59L,0x05a968a8d33d06fL,
  43987. 0x0ac8eb30bc25cb9L,0x03756bb55d8e309L,0x0ce08b43e7c7f69L,
  43988. 0x1072985bb6213faL,0x1481a7908faf714L,0x13d069be299cfa6L,
  43989. 0x15446305ac6b5e3L,0x1f1a66e09ee5f94L,0x07d6beda0b2cb87L,
  43990. 0x12df3a9588ba222L,0x071c5ef63cd47f2L,0x00516207649e104L } },
  43991. /* 93 */
  43992. { { 0x1bc384faf5747dbL,0x0b04360355c3584L,0x00ba79f0551ceebL,
  43993. 0x02ab2ef57f480d1L,0x1a81deb02d5326dL,0x05b088831d4d02eL,
  43994. 0x1ae426a1b929d49L,0x1742805f0f49565L,0x17d0721d4d5c600L,
  43995. 0x117ecd4f944fedfL,0x1399b7b379bc1c6L,0x04efb573f4e7ebbL,
  43996. 0x1f6c474bab62171L,0x1b776819b696e24L,0x0a0974f7005f87dL,
  43997. 0x0bc8772e2eb809bL,0x07e6c297e3d54b0L,0x0177da2a32b64e4L },
  43998. { 0x0712b008b21c064L,0x17f212538314f52L,0x0d026dd3c2bf461L,
  43999. 0x06fd93cc52c86b6L,0x04c60d086965aa4L,0x182bd56ed0a339eL,
  44000. 0x1bd802d9599c2fcL,0x02cfe0bd08079d0L,0x0c05073a904401aL,
  44001. 0x158f31c14a7303fL,0x00c949a73dc1185L,0x0837d19cfa7440fL,
  44002. 0x137577053d29411L,0x05533186e9c56c6L,0x1410d436e9a3ecfL,
  44003. 0x0ec17d97d5fe3d2L,0x1e49f5166d51d2dL,0x019ba9967231448L } },
  44004. /* 94 */
  44005. { { 0x11118533a00bb9bL,0x1fdd722fb33429fL,0x0a1752bb8934b4bL,
  44006. 0x1606830add35c23L,0x0731349f18ba1e1L,0x0b8adad4d640bc1L,
  44007. 0x14bab04f7f52951L,0x14f4bee8478bb55L,0x130a483b9535b76L,
  44008. 0x174d6d27fc39f4dL,0x18b611c8e841564L,0x12f71db589c02acL,
  44009. 0x1a39d8fa70b9354L,0x0068ac4fb0db220L,0x0817c2855075d59L,
  44010. 0x11210c532846fe1L,0x0bffd8b00346bb2L,0x00c9515aeea6699L },
  44011. { 0x1576628365ced07L,0x1997d82ef0e8fb1L,0x06f2fd029ea80a7L,
  44012. 0x11376a148eda2f7L,0x195a62781b1b2a0L,0x07e0cdc9c4d5ddbL,
  44013. 0x01ce54b3fd83ecdL,0x1ade757292470fbL,0x0a8f053e66920ccL,
  44014. 0x1796ea5b1d4da78L,0x03b78547a084a4fL,0x181610717f43356L,
  44015. 0x0c9ffc11beafba0L,0x0ae6043c15ead3dL,0x10bc318162ff656L,
  44016. 0x06374d0da9147f1L,0x068c33abaaf1d9bL,0x0319711449de061L } },
  44017. /* 95 */
  44018. { { 0x0851d2015a1cccaL,0x114863f2915e18eL,0x155463aac14d3bfL,
  44019. 0x0f790bc42e16e83L,0x01cf8b29ae65619L,0x0a423c57098a0f0L,
  44020. 0x162b8b8b2d64d9aL,0x111d6af761f8637L,0x0decef5d6c264e7L,
  44021. 0x1d42b664e5cb6c3L,0x05a04c9e460f69bL,0x1040707af2d45b6L,
  44022. 0x1f1d0c6fedf03f3L,0x05355ecdac522b7L,0x1e5bc6495626016L,
  44023. 0x13d4e673ea58b07L,0x145cf6ded8fda7eL,0x03461ece0ae8e66L },
  44024. { 0x1e26265e6b392b7L,0x0ecdfbbaeca84b3L,0x13535d9453df3b0L,
  44025. 0x041bce5c39c2d57L,0x1adfb033d86f59bL,0x122be6533721e68L,
  44026. 0x16a8b6cd10d0017L,0x0636cf4f22cad03L,0x1c32e7babf01147L,
  44027. 0x137f0b769d8f4b0L,0x18a63bd8f49b981L,0x1bb0a835badb249L,
  44028. 0x1f9982f9719bea0L,0x02f83b5677ca806L,0x0f4e5ad721db98fL,
  44029. 0x0e8f4abc255cb64L,0x0a509efbb362ec6L,0x047902af7119943L } },
  44030. /* 96 */
  44031. { { 0x04ab9e3b82c1af0L,0x0f4f3f965713225L,0x10298061f51bf19L,
  44032. 0x0bc72766c69fd55L,0x019bacce27d3f33L,0x153308ce4fbe004L,
  44033. 0x0ba54fdd062d6e2L,0x113ff528aae6e55L,0x0937d78048db385L,
  44034. 0x086436fb78fde0eL,0x1af6268bc2833b4L,0x1f446ce873d6915L,
  44035. 0x0b3f17d2d8ae5d5L,0x008ecc4a081d350L,0x02d9e8bc8cfda29L,
  44036. 0x17e0cffd9d16643L,0x02e0422540f2319L,0x0094964649a0699L },
  44037. { 0x1eb55870386463dL,0x1e15901b8ecbffaL,0x15c42e06716b52eL,
  44038. 0x0d9e095a82366c8L,0x06939ec10cbb42dL,0x0c23f3aec0ce3b3L,
  44039. 0x0cb921d16b04e80L,0x1009ee0960438e4L,0x12c9e58a0acb057L,
  44040. 0x091dc59dab0f14aL,0x137c01e7e6e8d65L,0x1f843d552c50670L,
  44041. 0x0f8aea2b9078231L,0x1868e131d17562aL,0x0ce400201d7b5dcL,
  44042. 0x0527559689dabf6L,0x16492546ac2f011L,0x03e3c3b15f5c10bL } },
  44043. /* 97 */
  44044. { { 0x0f7d6fb067902b6L,0x11d21e8b9acc05cL,0x0c4965d07776ca0L,
  44045. 0x0e8067f2b80c59fL,0x08589b8c6e391b0L,0x1148791c18e851bL,
  44046. 0x07ceb8d1d352548L,0x0729b5629ac445cL,0x18f00fcde53f08dL,
  44047. 0x0cc8bd7383f947aL,0x0a82e81a3981f15L,0x07cfafc3f0482cdL,
  44048. 0x004d6a328f60271L,0x0c4866953e12aaaL,0x082c82834b8c992L,
  44049. 0x1c139e440f289d9L,0x01d5c98dc0752f4L,0x034a01a826c26f4L },
  44050. { 0x0b7b366e5407206L,0x1aa6786c47d467cL,0x1523dc9cb9bc7b3L,
  44051. 0x05035688d0dfdfcL,0x0e474408d653137L,0x0839bfa965af872L,
  44052. 0x141c67909ace992L,0x15e4aed83369301L,0x191f346280f272cL,
  44053. 0x0730527a34798e4L,0x1a8ca642113625eL,0x001972a2b0570eeL,
  44054. 0x0514b1adbf8a557L,0x1de9a1f7d58d79bL,0x1607cd08baffe4bL,
  44055. 0x061c265f3f6036fL,0x146ad850e06ba6bL,0x036d4f013de2fcaL } },
  44056. /* 98 */
  44057. { { 0x1eee4c25c9490ceL,0x1625186fb41c090L,0x1f8292a4da3aa5bL,
  44058. 0x149784c5e7cd8c0L,0x060c34ffd8b0492L,0x0f99e6842351082L,
  44059. 0x1d84bdffde990a3L,0x002218aa0884304L,0x09d25fce9149bcdL,
  44060. 0x12b08e6e7e309eeL,0x1dfa225fd47395cL,0x1e629d18116a2b3L,
  44061. 0x1575e7538f3fa3bL,0x08e42010750ab08L,0x00ab42b4782a546L,
  44062. 0x11cbe1a44d1759eL,0x112a04c6ac4058bL,0x03b9da05cd9a8acL },
  44063. { 0x0ff2cdc3631cfd2L,0x06169c03b9bde00L,0x05a8ce2949c0531L,
  44064. 0x1b665957bdac00cL,0x070b17cad0e3306L,0x19a9f719b39c755L,
  44065. 0x0eb4fcbd2aa35e7L,0x1c0e25ed5b2aedeL,0x0e427985289b2bcL,
  44066. 0x0ec7ca6ed496518L,0x0751d76124b7641L,0x0b949a2bc97b312L,
  44067. 0x0b254eabbd3e06aL,0x0076a89e2392ea7L,0x1eab9b0c4e52b3bL,
  44068. 0x1a26efc1f30b377L,0x175dc125546833fL,0x0095a31c2e2b627L } },
  44069. /* 99 */
  44070. { { 0x10dbebd932951deL,0x0cea12d534e4a40L,0x1013b2cbc2365a5L,
  44071. 0x1844a17058bf893L,0x1aec4e1dac74f0cL,0x04cd66cb521cd29L,
  44072. 0x0cebf0cf2ae6a41L,0x1165f99bccca9b3L,0x0f4af285c3863aeL,
  44073. 0x1b99b9f237f5fc4L,0x159cb0f26adfb48L,0x0261fc240418ea3L,
  44074. 0x0f52f3e56ec1c51L,0x12532540d6c1201L,0x1c58fc8d226adeaL,
  44075. 0x0662e143f6cc3b3L,0x01717c69be10e55L,0x030e0c9af3ec46aL },
  44076. { 0x0722d9b3492ae43L,0x04eca829c782d17L,0x1620802aad8c7beL,
  44077. 0x01d749622f5cefcL,0x1a461cb82872c12L,0x09c7932e1219641L,
  44078. 0x1f700c56cd0d32eL,0x11a0b7e558b1898L,0x0d2e501dd596b37L,
  44079. 0x028364fe5c48618L,0x0bd185f0d87c32aL,0x0e30b46b975c7a1L,
  44080. 0x11f3fc013821f7bL,0x0592476fde881afL,0x1272b81d18a2bd6L,
  44081. 0x10ee71ac843a091L,0x19475e3da392ca1L,0x013d686f938e9edL } },
  44082. /* 100 */
  44083. { { 0x03bda79305b5aedL,0x1ea522ccc6b53cfL,0x074c3dfadc00b19L,
  44084. 0x1c28fa388990abcL,0x089540edc18a7e9L,0x15fe901f54cb0c6L,
  44085. 0x110de94ef8829f9L,0x18d9290fcc9d982L,0x17297920734ef85L,
  44086. 0x106a738eaf0f5eaL,0x0ac79935235adbeL,0x1c0acdc401a9fb4L,
  44087. 0x1a5a5366a1782a1L,0x0d239b9c151e386L,0x18083a3f8fef4acL,
  44088. 0x16ccbafdf180cffL,0x02fec686fdeeacfL,0x02ecdaf13b6e8aaL },
  44089. { 0x037c5a5cb3e472eL,0x1ec939850a02f1bL,0x0b96d1261560854L,
  44090. 0x1be73410a201332L,0x15c6c56018f00ccL,0x01aa071311be08dL,
  44091. 0x0c611063b50204dL,0x0d7fdef97e0fcfeL,0x0ecd92366bf4857L,
  44092. 0x1badf0d5e4a648dL,0x1de379285889d86L,0x0fa78b8d79711c2L,
  44093. 0x075ab71858c52e5L,0x1fb71cfcae61c16L,0x09cd7f384b0b0a0L,
  44094. 0x0b32c98fc1de5acL,0x166e071deb1835aL,0x0127c48e6e5dc63L } },
  44095. /* 101 */
  44096. { { 0x0ef60bf6778c1e2L,0x0e01e806adf2e12L,0x01b8bc06827ffd2L,
  44097. 0x095c12dcb1d8233L,0x1077984c59a728aL,0x0652d2d55de76dbL,
  44098. 0x038f7ed1cef4a1cL,0x195192518c29bc6L,0x13fae7f9a4f67abL,
  44099. 0x1e15975f610d4e7L,0x1c358a7366d77a0L,0x14b38c1631bf5f4L,
  44100. 0x1e4049b54cadeaeL,0x16e98871eaff7bdL,0x18c8733f3baf1d9L,
  44101. 0x115eaee91dfc71eL,0x012fe9c32b118eeL,0x0431d61e7ea16fbL },
  44102. { 0x036fca7b85a2fe2L,0x1868477214ee305L,0x08245070e513cf9L,
  44103. 0x0cce4e541519374L,0x1968bd06306a810L,0x1e301ef34d0aaafL,
  44104. 0x193eae1bdf91c54L,0x0992e0cc295deadL,0x1c0dc36b898780bL,
  44105. 0x1b2bff11d0e9931L,0x05ea190d548b250L,0x0feddbfdecf203fL,
  44106. 0x146daa17a0d9189L,0x02d667def5df18eL,0x07f0779bc5e4402L,
  44107. 0x02859c1b4dc651fL,0x05a1c9d53dbe1e7L,0x01f1f8d8f45c339L } },
  44108. /* 102 */
  44109. { { 0x1ea15c07b7fbf05L,0x188db0f8d1c415bL,0x056b477346f264bL,
  44110. 0x155a1efd1793bbbL,0x1ca7ab7931f5b7fL,0x12adf3149b72f5fL,
  44111. 0x19550c3d05f7066L,0x17e3ede9c86879bL,0x0971f5e6582f044L,
  44112. 0x1e1dc7221446204L,0x0b167ee01fd5d5cL,0x05bb0316b1e0c35L,
  44113. 0x0097a3b0d3a64eeL,0x01ca582c37bd053L,0x0cd45f62e17b320L,
  44114. 0x07e0d340b28e97fL,0x02589ad5977a79cL,0x04090476c380540L },
  44115. { 0x093509914c4ce37L,0x1dc21d0d5245308L,0x0091603563a3cd2L,
  44116. 0x1366eb71750c00eL,0x0d3bde836db42c4L,0x0919db561b2a927L,
  44117. 0x051bd548786d192L,0x15d78f98baac9bbL,0x19c14b035bfb5b6L,
  44118. 0x1915d0c00a360d1L,0x0beef21c8853d5fL,0x0fef69242ec816cL,
  44119. 0x01cb4d6df13acfdL,0x11300548aff886dL,0x16459fd98389881L,
  44120. 0x14332f58fb53b03L,0x1c26e8e260cb6e7L,0x0221c1fdc406f59L } },
  44121. /* 103 */
  44122. { { 0x107f01de44f9af6L,0x00d26c658fd0e70L,0x0fb3edf7524cd8eL,
  44123. 0x144d51073fccb7cL,0x1ec789d8d0b8435L,0x062f0ff7307c8a9L,
  44124. 0x0a073897fa940afL,0x17008ef818afc89L,0x1349e9f83230ba5L,
  44125. 0x0a17997ef0c06ecL,0x0e7abd928f44737L,0x109d7d6e1075160L,
  44126. 0x04f12742cb80ef8L,0x190501311447306L,0x14eddfd1055b315L,
  44127. 0x074b39aa8fbcce4L,0x0459829a6eca601L,0x04577384786aa42L },
  44128. { 0x0f22d9c32c54409L,0x1fd233af5d5620cL,0x04a218a12606a7aL,
  44129. 0x1ed6751c1921c5dL,0x1d77641ed0201f6L,0x0b82bae4b980b65L,
  44130. 0x13807e49bcbc1c0L,0x0089308091ffd81L,0x0bf696211f319d3L,
  44131. 0x05ae422648d4462L,0x03ef3b800c2a09dL,0x0a4bc9edaa42988L,
  44132. 0x0c29d67d1ebed67L,0x010e9a9b57bf23eL,0x0ca5017e8c1f6e3L,
  44133. 0x100bead6d88d577L,0x1a0f059a7e3033eL,0x04b87b0ff304b52L } },
  44134. /* 104 */
  44135. { { 0x1c53d231bec8e4aL,0x0d60a1ad301a60dL,0x076942791936202L,
  44136. 0x1b1491046a9dc10L,0x125864b6496ae1fL,0x06834fd0d74c319L,
  44137. 0x09ad2eb284fa5d3L,0x1486e7198b163b1L,0x15fa71f58e76b9dL,
  44138. 0x08cdf4463f58b7dL,0x03c4feb5390a772L,0x0ce24933f3dbeb9L,
  44139. 0x15a10d8bd74583bL,0x0bc85dbf5e71008L,0x0ade377d9b5d815L,
  44140. 0x0abf5262d5dbc90L,0x0a7e0d8fb2d75f8L,0x02025adca2d3ee6L },
  44141. { 0x1ee682a517a15c7L,0x067de77c401017cL,0x04e5441a8d52ab9L,
  44142. 0x042e1fd7cf9dc58L,0x13d0c54b5de6019L,0x08495bac4f1cfebL,
  44143. 0x1f97c6571c4d632L,0x0f396fdaa7e14f7L,0x12bd9242af61cc9L,
  44144. 0x09778b629cafbecL,0x0b0729c2ccbc263L,0x04daa5a30b821a9L,
  44145. 0x0a942d6195a5875L,0x128058561499582L,0x0bf48c3f896a5e6L,
  44146. 0x04a78bf43e95cacL,0x00260f55af220daL,0x03fd508dac18a30L } },
  44147. /* 105 */
  44148. { { 0x0ba4f0c6e402149L,0x0660ecb1e608cd8L,0x106a9949d1d8d61L,
  44149. 0x0b92ae2be4ee81bL,0x1f89fb0e3f77ff7L,0x0df1ffd9791a569L,
  44150. 0x1fa09545640cbbeL,0x127f93f643a0846L,0x1eb2eff38a153edL,
  44151. 0x0ea9d7008020e89L,0x19516dfc6f60a22L,0x0f9c872a7d4b9e5L,
  44152. 0x14d85e75c8dd4a2L,0x120df0e1806972eL,0x1080cb7ae4fb588L,
  44153. 0x1ce023ca7e4be04L,0x0bfb9957636c3a4L,0x00a5b1d2976cc7fL },
  44154. { 0x010b55371c43336L,0x1ea5311d24125bbL,0x0b800a18146c677L,
  44155. 0x191ebe3db6f72f4L,0x1b67daad86abbb9L,0x0ffd7db3d2bebbcL,
  44156. 0x0f18e2b3941b735L,0x0a10bb53f2b1358L,0x0081cbaa875a3d1L,
  44157. 0x19a9ec7f49a3769L,0x0d87c687e680b40L,0x126e74cb38e3655L,
  44158. 0x0b4f5df8a1b0cb0L,0x15bead0edbf0718L,0x03973c1df131d07L,
  44159. 0x0e3591e08d938e5L,0x05532dd0bc7f7c1L,0x001242c39c1b693L } },
  44160. /* 106 */
  44161. { { 0x140dd2375a4cd8dL,0x05219cbde5d3c66L,0x1610963587d44cbL,
  44162. 0x13b43d1cd0618b9L,0x1d65d40a0a7ec05L,0x1a86bb03d478b88L,
  44163. 0x0b90a1a79957bd0L,0x1a17319cde0b307L,0x17b61391d9d8bebL,
  44164. 0x1294f12d8dd2ea4L,0x1ccba47dacb3d8eL,0x18d47f476c528deL,
  44165. 0x0cc3ef0ed2bd66eL,0x0f845a3b1cbca87L,0x16838bbba40232dL,
  44166. 0x1790ffad7c84b2cL,0x1ae78ed513c1177L,0x033cc676fff2896L },
  44167. { 0x1e3f8fd1b97c5c6L,0x1d59f3c61d99fa4L,0x104903d656e8e7eL,
  44168. 0x12bafa86ec884e8L,0x19c44777174225bL,0x0b5922c4059fe63L,
  44169. 0x1861370eb2a0ccaL,0x0e4ab227bee2e69L,0x1a4db23d39c9344L,
  44170. 0x15d9b99e8a10508L,0x0833e7cd822f733L,0x19ec619fc27f73aL,
  44171. 0x115f30874ca618aL,0x0f8002d2baf8359L,0x0ff276d41bbf9feL,
  44172. 0x0f883155d4f1803L,0x195f9179255f78eL,0x01f53d7692974b1L } },
  44173. /* 107 */
  44174. { { 0x0617e045b06ae25L,0x00a46e5aba877ccL,0x1c398130ae8af2bL,
  44175. 0x16ed6f12eb23d45L,0x051da18100c19f6L,0x02b82dbcdcdb683L,
  44176. 0x16fc7cc896faf25L,0x0da61686be6b800L,0x1440b4482bc24d8L,
  44177. 0x1c784cb6b1b9bbbL,0x15b1587112d370aL,0x1dcc6120d332cbfL,
  44178. 0x0408aa1ec1e9405L,0x1e97944a8cff849L,0x1d19e5fbbcc91a8L,
  44179. 0x0befc02d86ecb78L,0x04462d2569fd070L,0x0354569ce029280L },
  44180. { 0x05f020d46be7282L,0x0d7f6909c078972L,0x16f75769ab42501L,
  44181. 0x08ff17cc3c99b94L,0x196b8178c2d6f18L,0x06fcaa100994a9aL,
  44182. 0x0ad3634ec79edeaL,0x0aceaf8c37672aeL,0x0d749b57b80cc3bL,
  44183. 0x0c87fc99bd9fff6L,0x0ed94c517725365L,0x0c0c466bcae6737L,
  44184. 0x17f763feba70c1cL,0x0630db994e17396L,0x1cfcb291da39093L,
  44185. 0x0b19aeefa5f4d54L,0x1aadee4dbaac5cbL,0x00d0c08bcce7d70L } },
  44186. /* 108 */
  44187. { { 0x16ff62f77575ed0L,0x0a7d4be8ed4cdb7L,0x1beda7bf5fd863cL,
  44188. 0x17bb850c665ce55L,0x186c5834c45ab4cL,0x1baeec587106a42L,
  44189. 0x112634e5c0468e5L,0x1b002619011e826L,0x12d408ebaf5115eL,
  44190. 0x083502e01306f6cL,0x0dcd88672ae4471L,0x118dd0d2750d3cbL,
  44191. 0x1fcc7736174cf50L,0x0aec4e51a738922L,0x1eef260bdc6a87eL,
  44192. 0x0ffa49774f8d4c0L,0x1a8f3a515e7212bL,0x03e96ee3ac9187aL },
  44193. { 0x105816d4ed2cae8L,0x15e3edce001bb9eL,0x039991ac235133dL,
  44194. 0x0297380301847d3L,0x0f9179c1f9ee6c6L,0x0cb445708e4d09fL,
  44195. 0x1c29e96d851fa3bL,0x0eaf5fd6c91a0ccL,0x0d670333c176852L,
  44196. 0x04eecb4bafcf479L,0x1c8a34de9a2b7aaL,0x1abc8a99630d76aL,
  44197. 0x0f063dd55021a05L,0x065b6579a4080acL,0x152af9e4b753c21L,
  44198. 0x13aece189b0a4f0L,0x0ba845969dc6e72L,0x02d297c3d58dfa0L } },
  44199. /* 109 */
  44200. { { 0x1019e9109ecacbdL,0x0011ebdc4def576L,0x1c2d5c1cdc79951L,
  44201. 0x082d91c42ef98a3L,0x01259ab514832b0L,0x11b0ea58d533414L,
  44202. 0x170a9b8403e488fL,0x04dcb27ddd3c752L,0x1699b6bbd16c10eL,
  44203. 0x0a43c39ca39d09fL,0x053716c9d261f2bL,0x00ea4ab3c5d3e38L,
  44204. 0x1dc3d47ad257dc0L,0x0ea93bc9c224c24L,0x1f56e660f7c9e2bL,
  44205. 0x00540ee1c7d91ddL,0x1fe2ae5844676bdL,0x00bf813b21f382fL },
  44206. { 0x1a4010d29abea1fL,0x1cb4a9203d6266eL,0x04a410cc862d8daL,
  44207. 0x162c7aa6952d4c0L,0x0cc20565f221fc3L,0x142abb82dd0adf6L,
  44208. 0x0134c48e3953658L,0x1c8362884af0f10L,0x196fbf304a89a9fL,
  44209. 0x053f83625f32158L,0x0883a1b8ac217b2L,0x0f85fe94b23bba3L,
  44210. 0x13a4a343b88f7f2L,0x1d8b9ea6e0bd83aL,0x101eef9a12c7a22L,
  44211. 0x03aee7599d4887bL,0x17edb15c88d4c44L,0x00778184d29f2caL } },
  44212. /* 110 */
  44213. { { 0x1c25721fa8e5b60L,0x09c56b48e05d927L,0x0dd82c28892191aL,
  44214. 0x04fbc2d0efc8da9L,0x0721c630863f9acL,0x13fd81281ddb779L,
  44215. 0x0f4e7e306677c2dL,0x1b4f183dae5c0f5L,0x1cf9deb7bb32f0dL,
  44216. 0x1fb9378361e44f9L,0x022cb465c8896abL,0x022e9e28beb96e0L,
  44217. 0x0c457c4f378f5a6L,0x0e229e32270737cL,0x1a4b2022ef6a910L,
  44218. 0x06ac2af7c64db4dL,0x12aa9bc3fd95d77L,0x01e9db6635d9bdbL },
  44219. { 0x06f12cc9722c880L,0x1b5739435b444b7L,0x026eb4bebfb0e86L,
  44220. 0x14877717df74398L,0x17c3f4c3ad64ad7L,0x09d48dd2d7b5004L,
  44221. 0x0fdacabf2c3670dL,0x1219427f956d399L,0x1699a1391f2abc1L,
  44222. 0x0deaaa111d123f2L,0x18603e55223668bL,0x17fe24899879c40L,
  44223. 0x1e87d3a365ba9e7L,0x1d2652f11494bd5L,0x0f86db10153e8e3L,
  44224. 0x034896720c47acfL,0x0e71fa67c5778f4L,0x0174a3721e3daa2L } },
  44225. /* 111 */
  44226. { { 0x180fddfc60934aeL,0x13f7f8b21036894L,0x1e5905bb5d68b0fL,
  44227. 0x06b9a165b9eebcfL,0x1faad87bfac60cfL,0x04f2eeeee25f670L,
  44228. 0x1c6b9d4fea1f261L,0x0978baa2d465837L,0x1565dbea814732bL,
  44229. 0x03f5f1d672434b5L,0x09d35b36e5da500L,0x04e0cbc9cf7c819L,
  44230. 0x013aac4ebc3f5cdL,0x01eb61d0ba423e0L,0x1e81da99d8b80d1L,
  44231. 0x0cefad21b192a8cL,0x0c2768d78d61edaL,0x004cbe72a80c0ecL },
  44232. { 0x097746c965a0b81L,0x0c5f372f096fd49L,0x0f11c57d0dfd22dL,
  44233. 0x0f6acb88b2aae76L,0x1582797ce425e90L,0x12a3a7a7a1fa890L,
  44234. 0x012b3976be9be3aL,0x10655d71f7c27bcL,0x0ed7f95f0e8a07cL,
  44235. 0x1009537331604ffL,0x1ba6e31d0b3c5cfL,0x0b35c514388b7f2L,
  44236. 0x145cf4e2f38ea57L,0x1c80d00ca3aca0dL,0x045acb9f74f00b7L,
  44237. 0x17311cf49bdd4e1L,0x1e650b272b52fa9L,0x04b7cf84fe848bfL } },
  44238. /* 112 */
  44239. { { 0x0e8aac42c310a96L,0x0c181fbd1539a3cL,0x00f48e58881ccaaL,
  44240. 0x1db2a8250188d95L,0x0cabe911ad131e6L,0x0db6342bc8fe2f1L,
  44241. 0x021e1432ddfae10L,0x19d5ff27bd47a79L,0x106541f1df1007bL,
  44242. 0x17394e12ae6f8feL,0x1c4c5cc8f8e5c93L,0x14835a9a1183c1eL,
  44243. 0x1fa35e22bfa2de7L,0x04d81992d4c8955L,0x145353a814048aeL,
  44244. 0x1c157173ca3e80cL,0x0a5423c7aad79d3L,0x038ccc713205c7fL },
  44245. { 0x0140fcdceb6ed78L,0x079bb8c29a28b20L,0x196ba358373194fL,
  44246. 0x0d3b58abf008a16L,0x0e05686cce6c1a7L,0x1892b1454b5496dL,
  44247. 0x05094bf911d8849L,0x184e8f796a149e7L,0x0f0ec6ff2fc531fL,
  44248. 0x0be1a23887f4ff8L,0x021e0e71e4b3ff2L,0x049004df6033f69L,
  44249. 0x1cd804c290552c5L,0x1ae46539a000d14L,0x1977e81d0ad6b60L,
  44250. 0x0956386f03e2eddL,0x0acca6b85f03dfaL,0x041c4ca0d058699L } },
  44251. /* 113 */
  44252. { { 0x0f062a2de067dffL,0x193485e5c00b160L,0x04341c1e8af753cL,
  44253. 0x11f5c94723319b3L,0x132ad8145afc63bL,0x0cefd8b4278dbddL,
  44254. 0x16122c28b738bc6L,0x0c444c1c2fe91e4L,0x17393db00c2d5e8L,
  44255. 0x1447c2a19c678b8L,0x1e50a40ab3d48a7L,0x1970d06b5e7a00cL,
  44256. 0x12b8a2614c19157L,0x09a7623617d537cL,0x1ea04d413fe57d4L,
  44257. 0x08e099e00c4ddf6L,0x025454b3d05b37aL,0x00fdfed18934a76L },
  44258. { 0x1ebb657c8f69c77L,0x013c5d1efc47d7eL,0x15c707ede2d24aaL,
  44259. 0x14238e34668c76aL,0x089958b0d2066a1L,0x0eb3d3086440a18L,
  44260. 0x1ee3ee5d71f833eL,0x0c3b54ba410e606L,0x15ee5005d40bf58L,
  44261. 0x0073673bedd34d4L,0x10f2cf258b31d0cL,0x0c5299f080ab127L,
  44262. 0x1a225c9d700ac98L,0x1c8f23f4053f7b1L,0x0be12fbf86121a6L,
  44263. 0x0f17e373afbd718L,0x19e67788915c0e2L,0x027ca4465621378L } },
  44264. /* 114 */
  44265. { { 0x10dfcd4dd51b8ceL,0x1c93c1b11874030L,0x1c70d9665588215L,
  44266. 0x17c595d0efdb8ffL,0x07967608905ead4L,0x1c493650e192ecfL,
  44267. 0x02938f8e7b776f4L,0x149b52590d0bedeL,0x1e16f800af47a0fL,
  44268. 0x05a6dadf2fb0555L,0x1504be60e14f4d4L,0x04a136f2f1386ccL,
  44269. 0x184e0e72b264b62L,0x12aae15df52b002L,0x0a4b846aef52407L,
  44270. 0x0431e6f08334e2eL,0x1926e0b5aaae174L,0x03447034247bcb5L },
  44271. { 0x1fef641313b8f64L,0x08dbdca163a3166L,0x0ddd70362af6bbcL,
  44272. 0x015e8083520cf9fL,0x0935210f608ea5fL,0x08bd0411eadec13L,
  44273. 0x0b4856ae413f09eL,0x13f0bb763fc8ba4L,0x0c3d5e5094d3615L,
  44274. 0x15da9470e9cdc79L,0x12a0a3d12b3bc2bL,0x15be418af4a9babL,
  44275. 0x1378f95f4424209L,0x1499be9baba15a1L,0x133f6df447e9f66L,
  44276. 0x02fd9acd418138cL,0x06556e55b8f9bb8L,0x00b91e3f1f26209L } },
  44277. /* 115 */
  44278. { { 0x06486d8dc8b43f3L,0x1073093204f344dL,0x10df66d1800ff0fL,
  44279. 0x0ac509d8f631138L,0x0a9dbaea3a85033L,0x1c499e2d1b32e23L,
  44280. 0x05241efda5077a5L,0x05a3dab4a20d268L,0x1664a7b7a8cb800L,
  44281. 0x01fbb723076852cL,0x01ae8c7d3afc9d8L,0x1a83e58714ff87cL,
  44282. 0x19cf1db08a296ceL,0x06f3d1db1560c7bL,0x1da2c1b2467a20bL,
  44283. 0x0f96a2bcefa53b7L,0x13a21978baa4e94L,0x0425faa15bb184cL },
  44284. { 0x1decda9e364f21eL,0x079a280972abf60L,0x0121623e438435bL,
  44285. 0x17c76209717448dL,0x03aef57a9f6dda4L,0x193f54b5fbd1a37L,
  44286. 0x19b1c840a67fba0L,0x08b5533e90fb52bL,0x024ff813ed2cdf6L,
  44287. 0x0edd96945ea0a5cL,0x0406bf2be869874L,0x173539bd7b480caL,
  44288. 0x15e41039e47d9f4L,0x02856fa157a0d9cL,0x07a79278fa79aebL,
  44289. 0x0fe469e42675c68L,0x1534968c0f3cb15L,0x01c1fc13ded0340L } },
  44290. /* 116 */
  44291. { { 0x0c46a216583ff4cL,0x02d14a56b84f397L,0x073f013284a9399L,
  44292. 0x0922c14fcbb8cddL,0x169c762e82f128fL,0x16dc73dfd913d8aL,
  44293. 0x1da23e031e58f0bL,0x1994fb5fc0c9341L,0x0b7e417542d14b8L,
  44294. 0x1062e29c36f205fL,0x014a1876de4cc4eL,0x1cd3f7fc0e37e1aL,
  44295. 0x16210e9903b902cL,0x1b81f5dc30f234aL,0x17de2dbebbe1d3bL,
  44296. 0x1d475ecd128fdbaL,0x0256fe865475af5L,0x01d890f8aa1fca3L },
  44297. { 0x126e847659275e9L,0x00e7eb687e7282dL,0x0ff62a8fc7bd1d6L,
  44298. 0x0bc909cc1cabeb9L,0x1e9698e41e7be31L,0x1823c26c78d107fL,
  44299. 0x16cf89751b6a5eaL,0x0134a4db6eb0699L,0x01fd408d98d08a0L,
  44300. 0x00025902dae540bL,0x18eecd9792efa3fL,0x024aeb376ddeb67L,
  44301. 0x17c2fac737f50ccL,0x0939ca8d782fd40L,0x12ccd9e7b840b4bL,
  44302. 0x0a2be551ca817fdL,0x083673446fb2a6aL,0x02a82f0e89b9486L } },
  44303. /* 117 */
  44304. { { 0x03014a1d15e68a6L,0x18593326e9af286L,0x10b40eb59fe5be7L,
  44305. 0x1da58289083186eL,0x0d41a3cb74818c0L,0x0f9f4f628c08b48L,
  44306. 0x04e19972320ff12L,0x139364c18c2584fL,0x0f6086faeced04eL,
  44307. 0x1d96675febe23acL,0x10c4ce40a5ff629L,0x09d012e03590967L,
  44308. 0x07508b3762ca826L,0x0c1d46ff4fcbb54L,0x15663a575609c52L,
  44309. 0x1a6906a1a4cd3b3L,0x17c85cb89cb0f6fL,0x030bec06a52ba18L },
  44310. { 0x0ef267e70022b67L,0x1b5da9bb45ca526L,0x159b49e1118a014L,
  44311. 0x087048723262a74L,0x1df78c4a49054d4L,0x10f1ad4688f0b92L,
  44312. 0x18c766c94a9c756L,0x01c0f0cd90102e3L,0x00a8501db1b38a0L,
  44313. 0x16c995c673b811bL,0x1dd8263b6bdf40bL,0x1b5772600dd345aL,
  44314. 0x04bbfeb0363aee5L,0x0710d9c5fd7fe46L,0x0a381a41dee59e1L,
  44315. 0x108e2923f8b3fb9L,0x00b3f624f550e93L,0x028ab7a843e68bcL } },
  44316. /* 118 */
  44317. { { 0x0234e220206e8d0L,0x17aea3f8ad7992cL,0x0a2758e2543fd7dL,
  44318. 0x12fa892be95f56eL,0x08da80a966ec4d0L,0x1c51b5d6c4862ebL,
  44319. 0x1717f92a8248193L,0x062f33c4afc1e9aL,0x044c677ae24495eL,
  44320. 0x101c3d9d2dc71a9L,0x1e43d1d68a1ee5cL,0x198b8783e5eee06L,
  44321. 0x1b41a7fa4154895L,0x18058045dc3407cL,0x191cf2ff351d162L,
  44322. 0x1c3342939907174L,0x1ba78ed5f7aac9bL,0x0292a2cce599bb2L },
  44323. { 0x0739679a21b54c4L,0x167155b24bece84L,0x0a4b212219000a7L,
  44324. 0x1fd3f4f3b3e29e3L,0x06c208dbae48dcfL,0x11fb4f0a5c88e12L,
  44325. 0x0e0e16ac3efcb6bL,0x176301590fda3dbL,0x0146fd718188586L,
  44326. 0x0875b2a2a33e5e8L,0x0e5020599f3fb88L,0x18356e7a34c1544L,
  44327. 0x00881c1cbedb125L,0x1be181196f34298L,0x0f23463f8d31c4cL,
  44328. 0x09d078d8c0e1cdeL,0x14507e365bab4afL,0x0117853f6ee7c15L } },
  44329. /* 119 */
  44330. { { 0x062791fea7f1b7fL,0x0c62eee7f84ea71L,0x070ce71f716270fL,
  44331. 0x0e84edd1810d855L,0x09fe1d564dad401L,0x1408648548c7acfL,
  44332. 0x13712e35e59c0aaL,0x05dd6f5106c954bL,0x0fc4c23bbe7afa7L,
  44333. 0x0ddae4f25643484L,0x0e404da831f9bd3L,0x0002938431a46fcL,
  44334. 0x0794b324a2855d7L,0x1143d038f23ade3L,0x0d0c8f3262a3719L,
  44335. 0x113d272b45336bfL,0x046e186c3ee0c03L,0x03cfc0f378b39a6L },
  44336. { 0x1f2c1f3364f3c4eL,0x1956289b3f0a5c1L,0x13f164cf90f54daL,
  44337. 0x0a21b2c3fc894dbL,0x1e3f2aae34e5947L,0x153f928411a7673L,
  44338. 0x084932e4b802af7L,0x0743df749e14f23L,0x0c2086fd21192d5L,
  44339. 0x160687e5a8e457bL,0x06cb2b703c6d7ffL,0x111f025b7c3291aL,
  44340. 0x0adedbdd45b07a3L,0x0b812c4d20439d3L,0x189ed92f0a849a3L,
  44341. 0x0dd0b77edc7502fL,0x00073ee56636d38L,0x02217669bcef3e0L } },
  44342. /* 120 */
  44343. { { 0x0cd1ae68a2f90a6L,0x1ea0eb7ad68665aL,0x031100752e3bc9dL,
  44344. 0x09b06ecc62d4705L,0x15e1124be817a13L,0x15caf20a15bac6fL,
  44345. 0x078f897ef1a77f5L,0x19d46193ebfae95L,0x15ac0f163d89663L,
  44346. 0x154f77b86731c36L,0x043a9763b55510cL,0x1fe1311284f4f4dL,
  44347. 0x05eaaced585de23L,0x09f0c232bad69b5L,0x024e440d4529b07L,
  44348. 0x0add07b22c586feL,0x11e5c10add9e33dL,0x0428bb5b9835534L },
  44349. { 0x12110fa28a21e38L,0x11bceabb9ea9c51L,0x0efcb40837125edL,
  44350. 0x072c30679ba6d2fL,0x05fa85165917759L,0x155ae936b822fd7L,
  44351. 0x16dc0ce43ca69e1L,0x18d5817b461b89eL,0x1cca0240adcc615L,
  44352. 0x10f8b81628a36c8L,0x11cb429cb3be1e3L,0x0e1016cd37439d6L,
  44353. 0x1d7e61aa0a84840L,0x0334ab05bcd847cL,0x03adc78e20582f9L,
  44354. 0x0b2184726b85b29L,0x0b3d7fd83c09431L,0x04558aa5db72bb4L } },
  44355. /* 121 */
  44356. { { 0x0686003353c4a96L,0x03074482e6c1a94L,0x0d923d9be331397L,
  44357. 0x113f599f3d7ab22L,0x032639e5b6b80b9L,0x0556f5de0e0fd77L,
  44358. 0x080b4bd8e5b489eL,0x06a014f2da03130L,0x018ab548f3a4748L,
  44359. 0x0682b61d98d871fL,0x09a374059144b6bL,0x0db29607e7782b7L,
  44360. 0x0bd8f206c520383L,0x0f8bbcdb6b27653L,0x0acd2a24c68d87aL,
  44361. 0x05c45b04d21f8a5L,0x0a9342bb8e09292L,0x00dfe6ec2700581L },
  44362. { 0x10b9a4375a365d9L,0x0f0af046c7d8198L,0x0f5f5d0b7e0f52bL,
  44363. 0x09bc630e85392eaL,0x1360ace0cf7309dL,0x134b21891471091L,
  44364. 0x1694c410f48e3ddL,0x12ff855b7dbf21eL,0x041d64cb77b5f93L,
  44365. 0x100598562236808L,0x0190b48c5c83f94L,0x045b735440eb879L,
  44366. 0x12041eae47fcc01L,0x14643b5242b71d8L,0x0d81ac516191155L,
  44367. 0x0af7e3438f08446L,0x0f19b766d1f2277L,0x012dbc51dfbdceaL } },
  44368. /* 122 */
  44369. { { 0x0835718156707ceL,0x011cc218a7c8548L,0x016a2f95f6f66f7L,
  44370. 0x0b5ac7497002f91L,0x15aacffdd4bba22L,0x0aa3912e738dc30L,
  44371. 0x14f757c9991d5caL,0x1ae1501e3ee9e15L,0x0010538a3fc352eL,
  44372. 0x0532022a101e365L,0x11ea20cc31ced3eL,0x1dcc05b95836565L,
  44373. 0x0fed2b17c7b3433L,0x1eb194e397024ceL,0x1eb70de7e1a0692L,
  44374. 0x112b6712f328c6dL,0x0f0dc5650c892b7L,0x03855cab832d28eL },
  44375. { 0x0778ec47b585d93L,0x09b085319ff2723L,0x15393a80c46b29bL,
  44376. 0x177ac8005e43b42L,0x191cb7a9af22190L,0x141bebcf319d63eL,
  44377. 0x1ba2bb44f0c7fb9L,0x02db4940fae2c2dL,0x0d78a27323afcd6L,
  44378. 0x0334b72dd0a6b4aL,0x1d535d37d610830L,0x009c4ef1c792e66L,
  44379. 0x0c55b5a5c2e85e5L,0x051d65ae182ad50L,0x0223b68c4f7d4e2L,
  44380. 0x0bbbcb12d596a54L,0x0befc8842a084c8L,0x02ff64fbca8eef3L } },
  44381. /* 123 */
  44382. { { 0x0bc2c7cfe519f99L,0x15ec072a081a9afL,0x100a28e623cf8e5L,
  44383. 0x0bac037b435bdb2L,0x14ce64ac1c03b73L,0x1201487e98101b0L,
  44384. 0x025f560dfafa404L,0x073955d43474aa8L,0x1dce73d25b0b881L,
  44385. 0x0f6a095f658485cL,0x0a7fdf58f6acf0dL,0x0fb20c5b60e3320L,
  44386. 0x1642a4c11d55543L,0x127e488493be97aL,0x06495351dfe9914L,
  44387. 0x0c318f625d36e4fL,0x1957ad2ae22d84cL,0x00546ab31e74768L },
  44388. { 0x1ac51630a21fde1L,0x1aeeb3481ec24a1L,0x07b97f758a073f3L,
  44389. 0x00ef493468da493L,0x0875c06f4dedc6fL,0x1dc023235ed1601L,
  44390. 0x00dbf438383d8d1L,0x08420b02d36bccfL,0x0c961912ade8a80L,
  44391. 0x19ff505549d9e99L,0x0e3b6c315daf177L,0x1addb1a6fc8f3e2L,
  44392. 0x19cce5e7cb7971aL,0x0e9015a0755c2b9L,0x087f49a2292d0d0L,
  44393. 0x0df22bb084aafc7L,0x09f872fabd5b3a8L,0x04adc9a49b55231L } },
  44394. /* 124 */
  44395. { { 0x198a70199f951deL,0x0f2cb782c6da2ccL,0x107bcf40f74e3ebL,
  44396. 0x1a676283a69a8f3L,0x0cfe8a406e928d5L,0x077d1ecd232c005L,
  44397. 0x1c9bb4422b4bf07L,0x13ec972d243c026L,0x0b9b6a6b68e83bbL,
  44398. 0x0f8f36e092172a2L,0x03d9d8bd9659acaL,0x012cbc20b683a7fL,
  44399. 0x1a16011e1ca34ddL,0x128aaa0dea7489cL,0x08859b7ba9371a0L,
  44400. 0x0c248df00615990L,0x07dbdc7ae1d31d1L,0x01712f7a8b10d7dL },
  44401. { 0x133cf8fdd8e7357L,0x1d10c75676edc12L,0x0c741e134ab0cceL,
  44402. 0x0de50095c4d1c7cL,0x17e7ad7e1c927f3L,0x1fbc5000a19e913L,
  44403. 0x09eb82d0073c161L,0x16b3bf9e06d5400L,0x0c9e46c8b1d9a46L,
  44404. 0x136f2430f944699L,0x1b68bc6e2810f6aL,0x01cbe5a176adbaaL,
  44405. 0x0419defb5634623L,0x10e9643a0cf85b7L,0x03916cd57b0df34L,
  44406. 0x1d0a47b7e072f6eL,0x1d6f0862a8dac7cL,0x043cbcf53f0a0f9L } },
  44407. /* 125 */
  44408. { { 0x17e7b3f7f1c747fL,0x1260ee37319b4cdL,0x1dc2cdcb6e80546L,
  44409. 0x09a7dca9fc84e7fL,0x133cae0fca6d223L,0x0b7886097e47066L,
  44410. 0x073e49cca14e177L,0x12390de7f7be035L,0x05322677fe36caeL,
  44411. 0x0d3801997f7f522L,0x128ca33a2bc85ceL,0x0eeded4e63e8593L,
  44412. 0x1f66a96813c0256L,0x06d976d46343d9eL,0x113faf4652aac4aL,
  44413. 0x08365bc61b8b5ddL,0x016c052236a9792L,0x01f64c401611ea6L },
  44414. { 0x19e760c4072f74dL,0x1586f55aca02c87L,0x090326c0270b9e3L,
  44415. 0x00716b35cbb67bdL,0x0b4daa0647e875fL,0x079bc47a075a1b1L,
  44416. 0x0be2e69a93e4824L,0x0addfd7d35fdb7fL,0x1f87f96a59867e2L,
  44417. 0x137f691bad5b575L,0x09e0a8ff6c4f2c7L,0x0e3ce1f44c422feL,
  44418. 0x0cfd4c0dbe5102cL,0x181a394bae95837L,0x19f9e014df309a0L,
  44419. 0x1b4651b7ebc5656L,0x1142f633f3aba25L,0x01f498af477d764L } },
  44420. /* 126 */
  44421. { { 0x055cfa5239a9ea9L,0x1e34805f19d3149L,0x0d2e72d90af483cL,
  44422. 0x0c0175ce30eb3ddL,0x13410f843316c54L,0x1894db43a53b6afL,
  44423. 0x07c7048ed40ba43L,0x1195b91f350250aL,0x1f57b764a1b6240L,
  44424. 0x0b7600f8d403bbdL,0x1b3bc87c3771704L,0x08f9cb4d4b4ee8dL,
  44425. 0x0706e955ba3c49dL,0x1a2ebcd80f0aedfL,0x034421d8a7031e6L,
  44426. 0x045ae224f0610efL,0x19122585dc78c6aL,0x017681506853413L },
  44427. { 0x10434164daa2682L,0x16995809acb12a9L,0x0d2af619c25c389L,
  44428. 0x17dcef5c5c89390L,0x1af6c16911a19d2L,0x0b082a1cdea94d1L,
  44429. 0x03f84db32970173L,0x06ac6e14b37b8d8L,0x0ca420d27b93d51L,
  44430. 0x03986a2aaa6228dL,0x0963265b37afcb6L,0x13214a1f340bd7aL,
  44431. 0x1a7b0f01510cb1bL,0x08e90bf0b4d464bL,0x0bdd7a0b30db4d0L,
  44432. 0x054c3e22ed114eaL,0x1dd1db01394a09bL,0x00a313c2254f7ebL } },
  44433. /* 127 */
  44434. { { 0x1ca3aed232803cfL,0x01cc5cd4b7f9a35L,0x15fdd2ade22f079L,
  44435. 0x00fcd1809b95eceL,0x1cb7cd20c3a53e0L,0x0345e52fcb4e0caL,
  44436. 0x0c0cbca2d969b70L,0x029c79403a63b0cL,0x09b733b8187808eL,
  44437. 0x0eb826cf7f30c5fL,0x1cd50ac06e51b6dL,0x033df7dbbb7e4edL,
  44438. 0x0b903275cee057eL,0x0407bde33e8c179L,0x11db050f3717ddeL,
  44439. 0x0a0e5ade07a7ef0L,0x028035f5557a9baL,0x03d65abdb5a014bL },
  44440. { 0x041356944e6b07cL,0x02664f0e39a2ee9L,0x136389cee7ed147L,
  44441. 0x13711c69f880e88L,0x1152776dfe49607L,0x0114ce3be8c267fL,
  44442. 0x0a25db440cee71dL,0x04053414d08ef7eL,0x059ffdf10ee8f04L,
  44443. 0x10b8a36225dab6bL,0x141b0bee6ba1553L,0x05b7b27cf9ab063L,
  44444. 0x063c96b607b2cb8L,0x1aa4f154419c0e2L,0x12887501abb4945L,
  44445. 0x1f7bbdf2f1238eeL,0x16cae9807c78675L,0x0352d02dcb1b1a8L } },
  44446. /* 128 */
  44447. { { 0x0e71ea66a8f4f33L,0x037e326f547a549L,0x14b3fba21187cbfL,
  44448. 0x1c112a9a11a6ac4L,0x068ab76659b0a83L,0x07c6822deb4611aL,
  44449. 0x19eb900a04d5e40L,0x08230383380a570L,0x0986a516918764cL,
  44450. 0x180efd709abae92L,0x1a6b9564d9dedf2L,0x004a8db936322e4L,
  44451. 0x19c40097c8f6d17L,0x12ce203dc6f3424L,0x14a762ddb7c00c8L,
  44452. 0x16bec812355b22fL,0x08ca7f46d214a7aL,0x034402a5a387672L },
  44453. { 0x0d168aa51a5b86cL,0x1f26c4abbb923f8L,0x01dbc5c80ca490dL,
  44454. 0x1b2c8f4a9d5d088L,0x0405622c0a7ac87L,0x13cf978f2cbd258L,
  44455. 0x055b7b7bf971bc2L,0x1ed5e7de1849aaaL,0x1917fb04eef047cL,
  44456. 0x1c93ccfaa5b109bL,0x1a8cbcc52f82e0dL,0x0cb6188cd6190ebL,
  44457. 0x0e7e218978e157cL,0x06f2c3d7e946486L,0x01defb6e43f0eebL,
  44458. 0x0219bba65ae3917L,0x0533b432200ca8eL,0x00010fa0ceca7b7L } },
  44459. /* 129 */
  44460. { { 0x191122c43519d26L,0x1d60ea0528c2290L,0x07a5522ee27ef6bL,
  44461. 0x182d0897f398deeL,0x178e8d559ef3375L,0x05f0e2f3bc4fbc8L,
  44462. 0x1790013d666d87eL,0x193011193345977L,0x18939a260893206L,
  44463. 0x0d725fffe698428L,0x12cffb823fabfa8L,0x0133fe295578cc9L,
  44464. 0x0c2a841ef961f38L,0x0bf80edb06c1ca6L,0x1aeddcdd7eb62b4L,
  44465. 0x04a24df868aecdbL,0x19f1e716b05a425L,0x03cc2ac4014f0f6L },
  44466. { 0x0cb3aaa95106473L,0x17d20ad30ed0251L,0x0d894e558f0257eL,
  44467. 0x032a62570ffa792L,0x1f885c76baa4809L,0x063c6ab63f3ac15L,
  44468. 0x11035c3db6ad88cL,0x10d19c60a38ee8eL,0x06dbebd14ffdb61L,
  44469. 0x07020fd0c87204bL,0x031199bb98b8aacL,0x1c54e9e667ad742L,
  44470. 0x04fe7b9b6693d57L,0x036941be803556eL,0x01d07abebdcbdb0L,
  44471. 0x048ee63198bcd22L,0x08d9c5026096569L,0x04aec11e18e87d8L } },
  44472. /* 130 */
  44473. { { 0x0eebd86140528a5L,0x0615d29cbcde435L,0x0e293b0512afc9aL,
  44474. 0x1b054fafdb63793L,0x0e0118d81efabb0L,0x00aac778963868aL,
  44475. 0x19cf8c581c5a287L,0x1ba67c8516fc96fL,0x06317663783aec9L,
  44476. 0x0b97fdf709561aeL,0x1c2feef05eca914L,0x10e0e83f02546fbL,
  44477. 0x1be2888f9c4212fL,0x1ab652ae9ee765eL,0x00a3906a77056a9L,
  44478. 0x1b607e63231d972L,0x1547ede02856aeaL,0x00713846abc32a7L },
  44479. { 0x070cc53cde20f88L,0x013962fad881c91L,0x0679772c76fe4ceL,
  44480. 0x136e5ae982a085cL,0x0aaaaa554b3de21L,0x1435d30b624d459L,
  44481. 0x05a5402110f96eeL,0x023dcd79ae4419eL,0x159ffac6ba89abdL,
  44482. 0x01890bdf88ab1ceL,0x0a2bcbcd32e948aL,0x07ce0e4f520dc9aL,
  44483. 0x1f69017766f27f0L,0x1d40891f342163cL,0x0a5cee32cd1a6f5L,
  44484. 0x01b7a9181e68d48L,0x078fc5784a62399L,0x0069ed59dfd94cbL } },
  44485. /* 131 */
  44486. { { 0x18376e6ce29c3ccL,0x083f6780b65e347L,0x065978e533872c1L,
  44487. 0x1ee78a1a83bd7ffL,0x0d16ce3d24fc526L,0x0098a0a76ead2a1L,
  44488. 0x0181aecdef76647L,0x151c6885de5c675L,0x12ae90337c0629dL,
  44489. 0x1fd76322c955998L,0x0e265f60ae15ed5L,0x1973466e62ec352L,
  44490. 0x029086751fad6c8L,0x0c60b8cb412caefL,0x1a5cd5ea07a5fecL,
  44491. 0x13ed3c9e914277eL,0x026a1387c2e5cb8L,0x02985a775ac3a5aL },
  44492. { 0x1f275a1bab7b5aeL,0x0ee2681d2bdfa74L,0x112a9171416eedaL,
  44493. 0x0682d5880592e9bL,0x0ed985dc726369fL,0x0a2350b9af273c5L,
  44494. 0x0c0a8152361e737L,0x14d099d60d33c2dL,0x0f73f6fa4789b11L,
  44495. 0x150620fd95273c2L,0x1da40a4ea6da5daL,0x1c01e075156563eL,
  44496. 0x1b844d66c1814ccL,0x184a9100b26592aL,0x08c89c6de539f58L,
  44497. 0x149b3c0a5a9c87bL,0x17f5278b2e708b6L,0x0484a12a940632bL } },
  44498. /* 132 */
  44499. { { 0x069a14d0d5b4c2fL,0x1e2cdae45324e69L,0x0ceac38df528ae3L,
  44500. 0x11222206fd2b7d9L,0x14e35322fda1a76L,0x1c7d7e2c08702d4L,
  44501. 0x1398a8937304a85L,0x088b858c7651c7bL,0x1995c3f179452c4L,
  44502. 0x0998761a16a28b0L,0x16982ad3be04a4dL,0x04a5175d3827404L,
  44503. 0x06e2e3caf885493L,0x1b24dfa392e8d30L,0x13b17c7510246acL,
  44504. 0x066678fa15f7ee0L,0x0f527bd1d62bd8bL,0x0282b8088e7f30bL },
  44505. { 0x0084acef534356bL,0x0ef02a5a587de68L,0x18173b81370677cL,
  44506. 0x106c36f1c20435fL,0x0f78d38b64bde68L,0x052f2751927e63fL,
  44507. 0x0665bfacdcb3bacL,0x09dde09f966cb02L,0x07dce5d505eb0abL,
  44508. 0x114dac411c62c37L,0x18c65ef36000dc7L,0x08a2900d739fbcbL,
  44509. 0x0bd18e67ab8bf5eL,0x1cfb1fd6a1984b4L,0x1062ed09a9f413bL,
  44510. 0x1c459438fe2476bL,0x19f485b848225dcL,0x047f859b7eaa073L } },
  44511. /* 133 */
  44512. { { 0x1f2e2f43ff42cffL,0x0cfce8e1a98be4cL,0x0e4aae86d5168f0L,
  44513. 0x0a95f53465b6e92L,0x17dcd43684232b0L,0x07cc8a85c2aea36L,
  44514. 0x088622b0d788117L,0x00baf9e458fe003L,0x1057d35aeed4083L,
  44515. 0x0d2528caa9e67e6L,0x195e4e4f8ae4e49L,0x05606845d84ebcaL,
  44516. 0x1e3ac53958a2033L,0x1cf4d8b1cd84802L,0x19863598a01468dL,
  44517. 0x1cf5f6941b813f8L,0x03e9e0e857f6748L,0x038d9477762bbebL },
  44518. { 0x142b0cd99726bf8L,0x051dc8e10479e24L,0x039ec1663aa84a4L,
  44519. 0x1f44b52251fae52L,0x0037d7dac6a7791L,0x1141bd9699ed926L,
  44520. 0x18a83087bfac1c3L,0x04f7ee1b2ddc7b5L,0x143ed8191850760L,
  44521. 0x175855426a56bf1L,0x14407fa316dd312L,0x14dd5a4dd7bb78eL,
  44522. 0x086b78aa4edbfb2L,0x108acc245d40903L,0x0e9713b252aa3cbL,
  44523. 0x052b41a21b3b67dL,0x05ace7fec476318L,0x0394a388d1986c9L } },
  44524. /* 134 */
  44525. { { 0x0e4590432bbd495L,0x1a6e8df2a4b9ffeL,0x18757670fd38cc3L,
  44526. 0x10b374e40800d7dL,0x02c2c76840ee607L,0x1f445f60ca7e9faL,
  44527. 0x00842839dac4ba7L,0x18e2f9bbbb7d856L,0x0689d436b00811eL,
  44528. 0x1535d1b9425f4f2L,0x0e56c801f504529L,0x13e61e23ce89578L,
  44529. 0x08e9396402f8cdfL,0x175a3142e2ff5f6L,0x18344de29d45d0fL,
  44530. 0x125c7337f0f058dL,0x15f3965e170beb2L,0x0000e1cec2c00feL },
  44531. { 0x0805cb9da4a0912L,0x05bb522085e527aL,0x0e3bb1c7596f49fL,
  44532. 0x16902d0935de7b9L,0x08b24635780fbb2L,0x02273477b538135L,
  44533. 0x1d2a0558972204bL,0x1c8c49846589af4L,0x081a770374b1631L,
  44534. 0x0727bf8edc8be17L,0x1197f47d87b6541L,0x009397bcdc7a3a0L,
  44535. 0x01d7131fcfb1048L,0x056d238ab1be706L,0x1a65c988b936f0aL,
  44536. 0x0e8a1eea618b959L,0x113a0160dccee28L,0x0489973385dc8d7L } },
  44537. /* 135 */
  44538. { { 0x057efe27996099dL,0x1a26dd037304640L,0x1d0342561622dc8L,
  44539. 0x0cf3cb5dd3d6950L,0x108a2fade53daf0L,0x1f383564ab054d4L,
  44540. 0x091a9fd2f84c441L,0x1ccdabe7b365060L,0x0a5f8e8da27cca3L,
  44541. 0x1a8ee5326147949L,0x08c43bcc77f5e3aL,0x0f845940e7ca99fL,
  44542. 0x14a40da68392e0cL,0x1a869c7e08178b4L,0x16b80d45aec1f31L,
  44543. 0x193bae07d07c575L,0x0d1ea93c066b4d3L,0x03e8581f2bcca07L },
  44544. { 0x1e7ea304dd94c63L,0x180e2b9c5859d2fL,0x1e328539ad2d5fbL,
  44545. 0x1d4a6a64ed2a694L,0x1c22d00607622cdL,0x035904d7b4b503bL,
  44546. 0x0ad29ccf06219f5L,0x0992ca99976c4d8L,0x0a098d3a1a84f3cL,
  44547. 0x0cb7cf696b9a5baL,0x0c086975547240dL,0x1a5e3d8a247fbfaL,
  44548. 0x05b2c1aa39e2ba7L,0x1c759493fcb9349L,0x064a9bf4b9d743bL,
  44549. 0x1ca1df574e25c32L,0x060a606b43a9b83L,0x018d8bc17ed5aefL } },
  44550. /* 136 */
  44551. { { 0x18dba454034db92L,0x1bc80c79a6e26c3L,0x1cbb7dd530ce8e5L,
  44552. 0x159aac75111a009L,0x1b5ffad1eaa5954L,0x0c5edc514eb644dL,
  44553. 0x16d1ea2b7d956c3L,0x0b7eff7085b19b7L,0x1b72e3a0380d320L,
  44554. 0x19ad8593e563e54L,0x182f2f62951d770L,0x0e33d749a4bfff8L,
  44555. 0x180c50fca6736f7L,0x00600c801ec80e1L,0x007e1347f6b3deeL,
  44556. 0x17782eb9ecb1eadL,0x11f57a7e6345cefL,0x037e07df29f03f6L },
  44557. { 0x16d116bb81b0e5fL,0x0e952956429dc24L,0x0b50c9ce1fc360bL,
  44558. 0x09752258b26afc4L,0x09d5dcc13e332a8L,0x06c2e9c5b8e321aL,
  44559. 0x135383260bba50eL,0x1c72172aa797effL,0x12cb39bbc38fed5L,
  44560. 0x1633e4e2d621481L,0x08485efc1f69568L,0x0b5b4173c9ddd7eL,
  44561. 0x028ee9e0c655ac0L,0x045db71f885d896L,0x011ba4573cebb95L,
  44562. 0x0aa7e95ce4d3916L,0x1c8cb266012aa0eL,0x0380c9ad0d4a647L } },
  44563. /* 137 */
  44564. { { 0x058d41da4626deaL,0x1b3650adc81cfefL,0x0290c593996c97bL,
  44565. 0x1ae919f99f33502L,0x0f142fa99fe6daaL,0x038bcb3d5cd35e9L,
  44566. 0x08e6e932e85a175L,0x0ec25a6166cd787L,0x01f46a5dc8bf450L,
  44567. 0x03472948a10d607L,0x01881966ee8712eL,0x0a5db4d31720f4dL,
  44568. 0x14e54537072b4b5L,0x0f480b2fa81cee6L,0x15177f10a81ea7aL,
  44569. 0x1d6615071ffe7afL,0x00041991e5a3b5cL,0x0364b0f644b4e53L },
  44570. { 0x03bdc1bc4e7eb46L,0x162abacb63da438L,0x1f359abf5d375aeL,
  44571. 0x0acad9cde69f322L,0x124971755635510L,0x17fd969e8fda861L,
  44572. 0x08af7f699e0f98fL,0x1ef7af3e3e7ddf5L,0x0a4efbe5417af9eL,
  44573. 0x077b2312d2adbd2L,0x1cc8e069c4cc11bL,0x14ff72ac4b4622dL,
  44574. 0x1a0b027e96db2a2L,0x041959de3505521L,0x17eab01163f9749L,
  44575. 0x0ff34a46831beb5L,0x153c05a89cbc49eL,0x0418441ec34f125L } },
  44576. /* 138 */
  44577. { { 0x19b1c6202557389L,0x0e74bd6f7e05e4aL,0x19fe0cc3ce0d7f9L,
  44578. 0x1e2d9f703d12777L,0x104428fd27e0c6aL,0x0f30c137b2732deL,
  44579. 0x047294f7a4916deL,0x1261146278290fcL,0x065cec3b9445bceL,
  44580. 0x1de018a6b3f6a4fL,0x0dac90c1e08d48cL,0x1b5f275a63a4d3eL,
  44581. 0x10c780890cd78e5L,0x0f22f7f4f93415bL,0x12ebfa9c0570d3eL,
  44582. 0x198d826ba9749cdL,0x18c43a378a47e3fL,0x011bb7cbfcb31c7L },
  44583. { 0x06e1ec0ae575b99L,0x065a7c0dcb86e05L,0x00934e9ce51df85L,
  44584. 0x03f646b53be0147L,0x1bf629440b4b9c8L,0x0b2ebd468a88afaL,
  44585. 0x0f8ef3f4d6d0c78L,0x0f6ba25fd4565dcL,0x0629984a6f5182eL,
  44586. 0x121f179e1b2e847L,0x09c244c3cdb9c93L,0x1401fa68a803326L,
  44587. 0x0ebaf96dce698b4L,0x11b3aaaa11e27e8L,0x0c95e12982e82b8L,
  44588. 0x0c942a37b585b60L,0x0968ab4190a2154L,0x046230b30b5f881L } },
  44589. /* 139 */
  44590. { { 0x1fca2582d1f36a5L,0x1695944a62f96f7L,0x16e10f3b613c3b7L,
  44591. 0x05b61c77366b4b9L,0x0719a112290f898L,0x11b16b667075780L,
  44592. 0x1f91f43995f90e6L,0x028aa2d4abac4d2L,0x0269e1f778e6365L,
  44593. 0x11ef6e5ea8134deL,0x108c0110715f157L,0x06398e0aaf1bd9dL,
  44594. 0x131e489eabdb83fL,0x1cafe6da0def7dbL,0x076c00482d9e33cL,
  44595. 0x059912119f239ffL,0x162cbebc6f455f5L,0x00aaf53115a6308L },
  44596. { 0x0be2f1f876fa42eL,0x143a4bfd6f773caL,0x03d4e32196bead7L,
  44597. 0x09bf00b360d25ceL,0x0b5a7ac916e99b8L,0x031e958675b0374L,
  44598. 0x026833b48cd5cb5L,0x1be5a1e4c465534L,0x12529998c3861fbL,
  44599. 0x08c4453e0df1885L,0x08a714362ab78dcL,0x16f07626a67b362L,
  44600. 0x18ff029708dbcf9L,0x0d41f7c41e53a37L,0x0ca111296804e87L,
  44601. 0x095751d209a3095L,0x0c32fe84b3dbcbdL,0x047ab879212c82cL } },
  44602. /* 140 */
  44603. { { 0x0b66c8a2ca9c508L,0x0df6134eb5bc06fL,0x099a23ab5800b71L,
  44604. 0x0e93ae4c282dac2L,0x0e472e6f61841b9L,0x13d43b20f207366L,
  44605. 0x05e82b68909907eL,0x1e88b73fa679873L,0x1b25e8fa97c15dcL,
  44606. 0x09267590974b14eL,0x11cb19f6cf65580L,0x1a56f834f088751L,
  44607. 0x066dd027ff8e2deL,0x1f3d15e34a5584eL,0x1c31d8fe26815f5L,
  44608. 0x0c4255b17e44d9eL,0x01d4cb268e7c8a2L,0x01e8b8f43d96226L },
  44609. { 0x02ac16e8ce49820L,0x122f1606226e49cL,0x0449cfa1631093bL,
  44610. 0x188c64f9f21d8cfL,0x06159c1f918cb25L,0x0a2e59a1f1c3b5eL,
  44611. 0x0d1fadadb8380ddL,0x082c9707356ba24L,0x172e09274a300d5L,
  44612. 0x1559473440e08b4L,0x003fffadd6a10c9L,0x05946b2241be94bL,
  44613. 0x103209f4a30a580L,0x073549c03ff7416L,0x1b8472ad46005aeL,
  44614. 0x09d8f7338d8e185L,0x00416105af1ab9dL,0x011a74c7c1a66c8L } },
  44615. /* 141 */
  44616. { { 0x143520814db9cdaL,0x1ee23cb56f6487fL,0x09bebd162db6673L,
  44617. 0x0ae87d546308755L,0x01735d813f1f741L,0x02caeac8af0c973L,
  44618. 0x0f234d10688b42bL,0x06ce0977ecf8089L,0x12f960471be23a2L,
  44619. 0x01931c40ae8eaabL,0x008c2ddac776533L,0x073e183914cf282L,
  44620. 0x0c833c910df2e54L,0x032dc26fab58a0dL,0x1c0aded19f2667eL,
  44621. 0x0d2a03604a3f443L,0x093de5b52609621L,0x035109871e71d0fL },
  44622. { 0x01b67a04b3ca1a7L,0x176a98060674069L,0x0da24cb3c1eabd0L,
  44623. 0x02b84b86b44599aL,0x0dd04d0636523a8L,0x1c9d1df66e9cac4L,
  44624. 0x0d4c1cf68d40acbL,0x0ee98bc1879abcbL,0x0ef9f5486132687L,
  44625. 0x0c3ff7e0f3a1149L,0x0b0a7a89397b7bbL,0x13e067093e34db3L,
  44626. 0x1240f2390508abcL,0x1fc9a1a9d84d914L,0x0bad5419e441cb1L,
  44627. 0x170e02054c703cdL,0x0303ee0740996feL,0x01a7837d54e2694L } },
  44628. /* 142 */
  44629. { { 0x09dc79f2348f005L,0x02eb8efa49058c3L,0x1f29b7b992926d7L,
  44630. 0x09d0549f69fa36aL,0x1957836621b7f73L,0x143ecb31be5c1a5L,
  44631. 0x1b2af24d0406df4L,0x1c62b21f1580725L,0x0280dc3737f75f4L,
  44632. 0x19b7a87b530d631L,0x160c129955a36a2L,0x0553b2610e14e9eL,
  44633. 0x12fc8895cc80d79L,0x048a49cfb68bd8cL,0x0756e79260e4be9L,
  44634. 0x1056b5e6c04fba8L,0x11a452d79e25caaL,0x03b26a3d8fa08aeL },
  44635. { 0x1f22303a2ee8b9cL,0x1b969c2efe6a42eL,0x060c4204e8dc6e7L,
  44636. 0x167bce83ead6857L,0x1303bb5be28c523L,0x0dfcd7842bb12d7L,
  44637. 0x16cd249bca66ab2L,0x01c437d58101a88L,0x06a523a02d6ba2cL,
  44638. 0x18150d8bfe71432L,0x1a88d78c0307ab8L,0x06d4f69526228a2L,
  44639. 0x08c0cc89f745437L,0x0076c46f69e05cfL,0x0dff1c01206413dL,
  44640. 0x12e709e4d36ac79L,0x01009a1d53a321bL,0x00e06ece191851cL } },
  44641. /* 143 */
  44642. { { 0x1aa1f67c46a7d9aL,0x0199a5f6fc8e67fL,0x09d11e90bcb991dL,
  44643. 0x02483ff5528b067L,0x135efe6b6798005L,0x059201b84bcd421L,
  44644. 0x047717c184fd7c2L,0x1f8d7645f9ac9e4L,0x0e1b8b2a3a0572cL,
  44645. 0x0f075a0bca850a5L,0x12eca4fadb35306L,0x164a8e144bffcc6L,
  44646. 0x09a3d15a0a31a04L,0x1f97f6f4d20fbd6L,0x0e52803bfb617b2L,
  44647. 0x142b83eb03ebf03L,0x1bcaa3996b09ef4L,0x0296c5f1cd83020L },
  44648. { 0x11536f6fd631a2fL,0x173f859a8d46e5eL,0x031e6c49884a47eL,
  44649. 0x1e57a1e86ba34b2L,0x12b0ea7052d4875L,0x1d5c4f4d76db69cL,
  44650. 0x064b02f42af72e0L,0x1b504f420c513fcL,0x06566a960102a0bL,
  44651. 0x104181be701b40aL,0x1b5e7d618e50176L,0x136db7951bf2617L,
  44652. 0x06efdaa3f597201L,0x091b5c494490094L,0x1f0b9ceccdee659L,
  44653. 0x11b4623a7c71c51L,0x05d70787f41880eL,0x0367fb1b3ed7252L } },
  44654. /* 144 */
  44655. { { 0x13d0433f89a8bb4L,0x02619c9dcc7b8deL,0x1b200d1c28b5085L,
  44656. 0x0fcbb4113d056c2L,0x1bf5fda698fcc75L,0x1e9a662a11aa77bL,
  44657. 0x174346217094e7aL,0x1945c41650b7d8bL,0x0e71bbbe1782a1bL,
  44658. 0x0cef6984dc2a778L,0x1265e6265fe9aa5L,0x1f51b03e788a2e4L,
  44659. 0x1760c1115250cf8L,0x167c22f554d1da8L,0x1fb446f26c3bdf7L,
  44660. 0x0c10192673c4773L,0x1e7c93e9c5c2825L,0x00e96410bb09f60L },
  44661. { 0x181347d987cfc93L,0x101ddf8c3fc0839L,0x1274494328c411dL,
  44662. 0x01760ab7e67f4d7L,0x1a3af87c480091eL,0x02a055defcaf8d1L,
  44663. 0x0116f89a1ddc050L,0x05b331bee61affcL,0x0b398135fb723bcL,
  44664. 0x01187c60af5f623L,0x1860c17d558702bL,0x1e99b4c148ffc11L,
  44665. 0x04e16d4bfc7c0fbL,0x1a30bf490374ae1L,0x1830839d058d255L,
  44666. 0x1c56c72e330d295L,0x122fe2693122131L,0x012a4371b0529bbL } },
  44667. /* 145 */
  44668. { { 0x18795ca53572806L,0x04a24b2b4b470b0L,0x125cfecc8ebacb2L,
  44669. 0x0c81378fac29385L,0x079121b3fb15de2L,0x0655ddd4866d396L,
  44670. 0x10495b4be853881L,0x08f979b4def22c0L,0x025086261b435f9L,
  44671. 0x1b4361c61417588L,0x05b58bc69e472f6L,0x1da2c3444cd8a20L,
  44672. 0x06271d74a66b1c7L,0x012143d2133c033L,0x193c3ced7ffb686L,
  44673. 0x054e997ca07ff77L,0x1f1d7f7f0beb948L,0x03a8d91ac044249L },
  44674. { 0x197b9d6e9c9be68L,0x05ae233e886366aL,0x10f5dd8acbd05e5L,
  44675. 0x1543689c235119bL,0x0aa8eca86d94a63L,0x11ec3ffd85dddcdL,
  44676. 0x01d77d2c3cb4325L,0x1136ea60c58bb8eL,0x0fed726ac499339L,
  44677. 0x0d3031c2bfce66fL,0x10e4a9d7e31d997L,0x1b2abb8ce594443L,
  44678. 0x02b66ecc8dcd264L,0x0c522c5d38027f9L,0x0af594fec6aa6b8L,
  44679. 0x1bcf9d52c89bf17L,0x075a9378e802ba0L,0x00a266096e51636L } },
  44680. /* 146 */
  44681. { { 0x13a0a1d2989aa3aL,0x19141acf37326acL,0x032f4cb9ccbb60fL,
  44682. 0x0a78796493d2716L,0x189ea6acf4c464cL,0x167e194ba852fc7L,
  44683. 0x0e02519f96efcd1L,0x0db937f573a6f65L,0x0f8eb74533b339cL,
  44684. 0x1f00fdf1dbb36f7L,0x150953bdaba89cfL,0x1be4f7cc3621662L,
  44685. 0x01dd818488555c3L,0x1df38a7cb87db6cL,0x063da4f686bce92L,
  44686. 0x17072aebe402f3aL,0x151dc08fc6b2465L,0x043a76799b5c254L },
  44687. { 0x04af83ebbb3f6beL,0x07ddc845da11eb1L,0x02eb5e1cd49fd5eL,
  44688. 0x114c5c0884ac476L,0x1e236f79c3659bdL,0x1f93531481d8b3fL,
  44689. 0x04b3d5690c31b94L,0x056444a8f5c75aeL,0x1b73890d776eb27L,
  44690. 0x0da7b859eb146fcL,0x184ec14fab92b25L,0x0271cfe42e9d3e1L,
  44691. 0x1998dbae175b4f5L,0x0228c2403aa4167L,0x1fbc570ada6ef79L,
  44692. 0x15e329e4f2ca595L,0x14fa0a3ef2bb6bcL,0x018fdc2c0e72631L } },
  44693. /* 147 */
  44694. { { 0x18306d1615cd607L,0x04fd5551961d31cL,0x016ddde44c75a03L,
  44695. 0x146ce11601d0f4eL,0x1445297f1031013L,0x13cdab40a7d070cL,
  44696. 0x0fb51c31560ea9aL,0x1a60607397e962dL,0x118a7ca8daaaaf8L,
  44697. 0x198acf3ae6db452L,0x039ce348e053ebcL,0x0e311a1e9f3fbd4L,
  44698. 0x09dcdff032eb352L,0x1ea419c5d85bb30L,0x17541e996ea3aa4L,
  44699. 0x0a16830089b04abL,0x054844a223e4a4aL,0x04c1918000c70cfL },
  44700. { 0x0a2102757f3d5a6L,0x12b24374656e694L,0x006c09547cefff3L,
  44701. 0x1f26bd7be32b207L,0x0083aa6eb26cc64L,0x1267a0b0308948eL,
  44702. 0x0c6d73662299a23L,0x03ab0387ee7baa7L,0x078c804a977fc62L,
  44703. 0x0c3a1987d6e517dL,0x02369320f33c08cL,0x143b4f348e0fee0L,
  44704. 0x1f4a915eb5c4122L,0x08091b304d47069L,0x1ab4a828b7855f7L,
  44705. 0x1650a8bde8764cbL,0x0aad0a22ade188dL,0x0455df1cf491706L } },
  44706. /* 148 */
  44707. { { 0x04469053a2d2f01L,0x018c9aee3342e5aL,0x0efc75d2809f49fL,
  44708. 0x1eb6a1d83ad5211L,0x1f3c2e2601da350L,0x1b77490e9eea2f1L,
  44709. 0x05e73d9b84742e0L,0x068fc07211e8e97L,0x119e7c5b998b878L,
  44710. 0x1a0e9ff5e9e8ef4L,0x1a3a347bd8166e9L,0x12726ce9c48ec78L,
  44711. 0x073e7e67f69b9ffL,0x1774f1240ebea9fL,0x0f66131a6370c9aL,
  44712. 0x1d14ea5e47db567L,0x095f95e31b06f8fL,0x0078ada6861e85dL },
  44713. { 0x12f6635790a8d85L,0x1fdd7712cad78c7L,0x1b1892d44a1d46fL,
  44714. 0x166468e2bba2b6fL,0x0bc5441d7639b6aL,0x082c19866ea94c9L,
  44715. 0x18d8152003a93dbL,0x02643dfaea5edadL,0x1c0b7ffe5192906L,
  44716. 0x1452c12f7544c66L,0x16ea488a60899adL,0x036177a0d765d9dL,
  44717. 0x004bb6b0cb678a9L,0x057c754c5921b6eL,0x0a816ef3dea679fL,
  44718. 0x07d63725a1cdce3L,0x1dbbf8d0471f599L,0x028aed9bc101c2eL } },
  44719. /* 149 */
  44720. { { 0x043eaaa6f5bef22L,0x0934c101a438977L,0x0139e8ebdb1a54bL,
  44721. 0x0d351928063c989L,0x1001899a18d434cL,0x07520631f2eba0aL,
  44722. 0x01c8548e36ef3faL,0x1d194d991a52cf3L,0x073db6aee04acbdL,
  44723. 0x1b49946dbfcc9e7L,0x1e6efeb5178cd2fL,0x1926f83e2c6147eL,
  44724. 0x1f9b00a6de8c51eL,0x096c15e1a483992L,0x1167f25279ab2d0L,
  44725. 0x09c76b20366da1dL,0x002cb09b7109cf3L,0x016f0243f0d5fa6L },
  44726. { 0x0b722f38dd9d484L,0x049c9be3bdd660cL,0x03c64f64ae2a0cdL,
  44727. 0x011c7f584ab1b77L,0x145f4a7d80d78d5L,0x1e614ef82804c0bL,
  44728. 0x027e341caffb61dL,0x1aecf57f1e58615L,0x092c567ea9a0820L,
  44729. 0x12d5897451d2b9cL,0x0bebafc155486d0L,0x1e4d729d4bd382cL,
  44730. 0x143d71e546ee1c4L,0x01f45f0e8f20a4cL,0x07ab82c96060ee1L,
  44731. 0x094608922f905dfL,0x06e6813a4577387L,0x037b56038e6217cL } },
  44732. /* 150 */
  44733. { { 0x18822ad4dd6e3b1L,0x070e656b10434e9L,0x0114b2b37a03f1eL,
  44734. 0x15508d3fc7cf087L,0x067e8ef2121cc14L,0x1a3a2447479ed3fL,
  44735. 0x0c7d36e0f45b934L,0x02e7743bb30f30cL,0x1dfab59770a4c4cL,
  44736. 0x18509831f6e380fL,0x075805b363fca07L,0x0617798ab7928c9L,
  44737. 0x005760412a22672L,0x1947d77b0150ce3L,0x1faab671c6757c4L,
  44738. 0x15f6a4f972d3decL,0x0cbf342530e719bL,0x0371612667fad41L },
  44739. { 0x113024badaf8793L,0x1e67881ae4a4731L,0x1ade54d402fe512L,
  44740. 0x0c3a22cecbd340cL,0x1fd93c787991a94L,0x172a4acad6ed974L,
  44741. 0x1973c174b00dfa4L,0x0e59628b6313e07L,0x181ae48ca95aa1fL,
  44742. 0x01f938109ad3727L,0x1bd68926ca9f548L,0x120005afe546579L,
  44743. 0x086c6745b00687aL,0x0328398297be991L,0x037163cf6a2a1d6L,
  44744. 0x0230b7c7171085dL,0x1916b48bf34dbf1L,0x02d7bfe86cbe047L } },
  44745. /* 151 */
  44746. { { 0x1f9b950f4a224a5L,0x022ba6628139d2aL,0x0cc190fc7f55064L,
  44747. 0x161ca1ef0669f02L,0x09581712996801bL,0x048e9b4336ba01cL,
  44748. 0x1bf9f6e69017690L,0x0d1e3c6f3be2d48L,0x08d04a93f83bf91L,
  44749. 0x126419a995905e5L,0x0cd2c7dca87042bL,0x12efb032bb6933aL,
  44750. 0x1ffba14b5d8fbc9L,0x1b6d7a3b65759efL,0x16dcbd183fbc089L,
  44751. 0x160c497291bfdb6L,0x0ae5185c925b6dfL,0x013d4e1c0cb04eaL },
  44752. { 0x1c37346f12a93afL,0x1b83e2a9b31a6b9L,0x035526064f440a2L,
  44753. 0x19de436d3b1df4bL,0x0788a0e24f83a5cL,0x189e4c02e5d851dL,
  44754. 0x1e130040c5e0596L,0x1e5fd441cb056e6L,0x1df9713a0e50361L,
  44755. 0x0a24d07e866116cL,0x1d4b9df178b86ccL,0x0d7b6ce0899e306L,
  44756. 0x15733e177a6e44dL,0x047716118096ef4L,0x17c6525a2d259a4L,
  44757. 0x110dfb3760a823eL,0x04495182c716acdL,0x00e34834a7def49L } },
  44758. /* 152 */
  44759. { { 0x1b67d173a880026L,0x07850092ecaf92eL,0x1544fdb2de92271L,
  44760. 0x02b977b94a520a0L,0x172bcbd33eb231dL,0x0ad01d7c67fe4ccL,
  44761. 0x1f0bf2d3bd352b5L,0x14b289a8f94450cL,0x196d885480ead1aL,
  44762. 0x152be7c65e45822L,0x16112c01795681dL,0x1c323a31412fbfcL,
  44763. 0x0852923c745e9e7L,0x1faed99ccabd137L,0x0fb43234219ede5L,
  44764. 0x1a4784aa6811cc7L,0x1391596e5d5689aL,0x03dc609eb528261L },
  44765. { 0x1c43aad52fb6901L,0x189fc8b65129d97L,0x0c29456ab718700L,
  44766. 0x0cfeaefb8428eb0L,0x1723c0ddc93d192L,0x1cfb6d137297477L,
  44767. 0x0ddb4bc783ae0faL,0x07332f3bd05e300L,0x143e28ecbb08349L,
  44768. 0x116a8ee51ce1c73L,0x018ea6a38fdad66L,0x1474973664e0dccL,
  44769. 0x02d2f8915d4cf1dL,0x08283c893729a45L,0x14e0fe979d78f81L,
  44770. 0x1f6535dff9cae41L,0x0d01d6d53cc8fd2L,0x0071e1f7b34b7a6L } },
  44771. /* 153 */
  44772. { { 0x1c337c121ee1d83L,0x047b6bc3dbbc41dL,0x1f304e3e933a5f8L,
  44773. 0x0f40691cb17ee13L,0x055e672dbaf7764L,0x0f62ee827c5d5e5L,
  44774. 0x048603b4a4675f5L,0x15f19cc97fe67d3L,0x0ac09fc5724b059L,
  44775. 0x03418fcee2f195dL,0x0899dd196bdaa54L,0x1ccd92fe3ff04d4L,
  44776. 0x16bc6087fd3c5efL,0x15476e358a8af06L,0x1e7b4a6c68e717aL,
  44777. 0x111707bb02d761cL,0x11c6cc13769bc37L,0x023184c71e04952L },
  44778. { 0x06408c7c8bd0fa7L,0x12188e735ef249dL,0x0420a0fbdefb45dL,
  44779. 0x0f336bb271c62bcL,0x05a49a6b8213cc7L,0x14f268d7bf8ac0aL,
  44780. 0x1275b403f6c3f94L,0x0a4aba71eef9ccdL,0x0b4f7ccc01bd4b9L,
  44781. 0x0cbada4d7b8fcc3L,0x167f2f3593402a3L,0x0a094b4775ae256L,
  44782. 0x042b5c89f11860eL,0x1d1f118fb6cbb02L,0x032ea4bfb431965L,
  44783. 0x1c23cb02298662fL,0x05ae2e74c066698L,0x03fc7e849d1a45cL } },
  44784. /* 154 */
  44785. { { 0x04592cac19428afL,0x10e409d184332f9L,0x004b8c2ef5fc64aL,
  44786. 0x0706d8d77284b13L,0x198e498710db072L,0x16b7a5ce3d20f4aL,
  44787. 0x0b1122bfc5e79baL,0x07ce1f1f372eb0cL,0x06b3b02376f2198L,
  44788. 0x0ec1f4dcc7328a9L,0x149aa35d4486289L,0x10353ade3b4c765L,
  44789. 0x05a5a81f7495082L,0x12343a38c6fbc68L,0x01f63335e7b9567L,
  44790. 0x0d92a40c194aecfL,0x131427a84ffa847L,0x043db2628f321a8L },
  44791. { 0x1f46f654b30d3c4L,0x0262e11da778a43L,0x1d998f2935a337bL,
  44792. 0x139e7f6adb676e8L,0x0fd7d46a1df3426L,0x14d45eea789ce20L,
  44793. 0x15f4a8edf1f1da9L,0x069dcad6993975bL,0x1b28ff342ac9423L,
  44794. 0x0237efd3c378ed1L,0x145272dc0320b80L,0x1f02a12ccb2f9cbL,
  44795. 0x09fcff4bddca30eL,0x024929342251030L,0x0087ce03cbd979dL,
  44796. 0x177a1cb6caa59a8L,0x0f577ea9c2a042dL,0x0464a933e6ce031L } },
  44797. /* 155 */
  44798. { { 0x055032e5fc1abb1L,0x0d7aa097f23a1b3L,0x1580a7c17bd4885L,
  44799. 0x0bb83237d3facaeL,0x008639b0b0e7332L,0x1f3339bd59e32f6L,
  44800. 0x155559d41fd4470L,0x15ac717df8790c2L,0x15d0188cf42f0c4L,
  44801. 0x01d180e6c4b0c36L,0x180fdecb19d07a1L,0x1819f479a3a008aL,
  44802. 0x1d4a40672ef7545L,0x02dcf46efb0957fL,0x048b5d15865f27dL,
  44803. 0x0b37f68a646fb0fL,0x016bf132e3a4b2dL,0x0457d0db9dc2535L },
  44804. { 0x13596eae793ac70L,0x077c7777b6e8835L,0x1e89c108b901325L,
  44805. 0x1dd3cbaec724d69L,0x1512aadfc8c71dcL,0x01cbaf9a97e5b87L,
  44806. 0x0ec4c6dee84e2a2L,0x1a2af3227200b18L,0x19692092a97740fL,
  44807. 0x0d6ca2d8b05834bL,0x0d0e20420deac86L,0x0389e2e976e378cL,
  44808. 0x01ab1b80eb76ee1L,0x187622c53088dfeL,0x0b4cc96f20aeb21L,
  44809. 0x15b91ddcc024e62L,0x13cb4118b1ab240L,0x0339088c895ad04L } },
  44810. /* 156 */
  44811. { { 0x1e99306f55cf9bfL,0x029845235cb6cc8L,0x187679e9977e6c1L,
  44812. 0x038e6379775c783L,0x04d58a61453cb15L,0x03a6610a5f2913dL,
  44813. 0x00358e76b248a5fL,0x1be9a1ef48b045cL,0x1afeb1d51c62b03L,
  44814. 0x18ee1d25d50c596L,0x11c5e37cadd3c2eL,0x114d12d6d466fe7L,
  44815. 0x141dce055ffcd32L,0x152715c3f4af6a2L,0x16773a65fef1dadL,
  44816. 0x0cf83cbd8cfe3f4L,0x1fe052368accc03L,0x03e431c8b2a7251L },
  44817. { 0x1e94b5eca7388cfL,0x005306019ae9c2aL,0x1e2d85be16e85f3L,
  44818. 0x1e2024530136d36L,0x1cfd0a79705d02eL,0x0f71a92b2d37400L,
  44819. 0x076b7add2a5b5f4L,0x01eb91065da84f7L,0x096ea8528e6d533L,
  44820. 0x06c43158c692774L,0x0e3b567fe4e7dccL,0x1344020c04a539aL,
  44821. 0x182303b3ff690fcL,0x0ea95a34e316c45L,0x0b4b64ff10b5e93L,
  44822. 0x008700df1bf4519L,0x1ad502360906092L,0x0192c13ac7e742aL } },
  44823. /* 157 */
  44824. { { 0x120e45f359e8c60L,0x1dc529b2650c375L,0x01c77fe384431c6L,
  44825. 0x069927caf00562aL,0x1829d0d8074e91dL,0x1541fd601937005L,
  44826. 0x08278f064896189L,0x10470f4c9abf653L,0x1caaa3d34e5ac5cL,
  44827. 0x16b42f2d6d16d14L,0x08099faca5943a3L,0x1632ec7005e724eL,
  44828. 0x0edf6b1aeaf7184L,0x12f3092e91faee8L,0x01ca86af87e8d1cL,
  44829. 0x1875fac50ff3a19L,0x05649aa93d2ac57L,0x00d273538aded3bL },
  44830. { 0x0126ede554d1267L,0x0a2998e6815a40dL,0x013338c7ec74dfeL,
  44831. 0x1612fb8025ae15eL,0x16c7b6c5cf410b0L,0x048842c9870e8b9L,
  44832. 0x18e3e40bfb9071aL,0x1be6937494ef3f6L,0x0a16c5821acd6f8L,
  44833. 0x19dc1e09703b567L,0x140cef94074537eL,0x08a441e5a5b4d71L,
  44834. 0x0d99df18800593dL,0x0ff599d31ba9293L,0x1bbd15b28c8d472L,
  44835. 0x1b915b22687783eL,0x032c74857db35b9L,0x042b53e49c2da74L } },
  44836. /* 158 */
  44837. { { 0x007d0020d0a5583L,0x180eef6d232c550L,0x0590d364e6f8bc4L,
  44838. 0x014e18106d2380fL,0x1e81e540a0cb678L,0x05645c605a6fcadL,
  44839. 0x188e5b2ef34d175L,0x16caf8a5da0a8eaL,0x1cac2dca41805ceL,
  44840. 0x0af7355bc9a212aL,0x17bcc493268a9a4L,0x0c5f18258ce86cdL,
  44841. 0x1b7dbb7c3bbd3b9L,0x1115dcadd55b278L,0x118edd0f039154fL,
  44842. 0x14c624811fd7589L,0x0403ca773122a4dL,0x031444842631b6dL },
  44843. { 0x057fd538cb8d208L,0x1c004aa1f836a52L,0x0553cbbfcaadea3L,
  44844. 0x17ee4a2fcf6cdbcL,0x19389d2cfddb28eL,0x0dc46700a4ff337L,
  44845. 0x10fdde7a1dcff61L,0x1808a5c1216174aL,0x1deb9b5cfb0b03fL,
  44846. 0x089a245362f6bbdL,0x07cf3e3ff00dc8cL,0x08dab83698946c1L,
  44847. 0x138fa59be92bc9cL,0x06d81348f3379dfL,0x07e23e44e5afd7fL,
  44848. 0x1bfc7e3d8b3a801L,0x158c29034562ad9L,0x03cec09162d6d26L } },
  44849. /* 159 */
  44850. { { 0x0d4e4ceaa529507L,0x1040a3a32ae800aL,0x08e13c3f11d015aL,
  44851. 0x146887971d81a61L,0x17f1728d8a8203eL,0x1077a919e317d84L,
  44852. 0x074fa28e373f6d4L,0x0a141f21abaf959L,0x128a7b0bf873ceaL,
  44853. 0x08ad71d363620e5L,0x05c76a84e04b074L,0x174ac49aa0fd46aL,
  44854. 0x097e98f42f25d4bL,0x0b5209b8c8ed694L,0x0796ddfff5ac7a6L,
  44855. 0x1ee0fa8d8424b6dL,0x17ac7d2b42420c4L,0x01559d7cac0a12aL },
  44856. { 0x0ca074c6a5372a6L,0x1dc1f2b1495d3c3L,0x1b71ddd073d5ca3L,
  44857. 0x02a41de93ae8ab2L,0x01e4647270b4ceaL,0x1c562e8a397f1a3L,
  44858. 0x101c7d35af598feL,0x0c28dca59938217L,0x128794efe371a34L,
  44859. 0x042838c13b7f43bL,0x155dce6fbd6ad29L,0x13fe7e2b902bdb5L,
  44860. 0x058f8395c324c2dL,0x005b542a8c44a87L,0x0200f86eb90265aL,
  44861. 0x04bdc9ea7c45915L,0x1caaf233f61039dL,0x003ed961a928204L } },
  44862. /* 160 */
  44863. { { 0x1f3b8db037d4703L,0x1846fe2fa445ce3L,0x0c3e11c7500ba0dL,
  44864. 0x04b45f55d23f750L,0x1404fc1ea55ee8dL,0x16ab28e172df882L,
  44865. 0x1d7e591f5409ea8L,0x17e6f4a7818fd75L,0x07adf0bb295b30aL,
  44866. 0x13170ff6b2649ddL,0x1063038bbd29e16L,0x13b29a59a09efffL,
  44867. 0x175ea0af02139ddL,0x07f7cd67929fdd5L,0x1856a9df20403a8L,
  44868. 0x040d2e98a709b90L,0x159cb28682d9fe5L,0x0045b6547e7beebL },
  44869. { 0x04e5bea036c3b5aL,0x130813fcf95a5f0L,0x15c0a5e5f03ce1cL,
  44870. 0x17050f3d4753f94L,0x007f0ddf1656180L,0x1870438a99c4ddbL,
  44871. 0x1ff1e668488f19eL,0x0321a3011d93b12L,0x09470711a916edfL,
  44872. 0x07a97958390b88cL,0x0ca7ff462222dbeL,0x058a998df200bb1L,
  44873. 0x05eb24877fef1e2L,0x1aa3ca92e201b0bL,0x1851a2bf6a548ccL,
  44874. 0x17411ac454842d0L,0x1d25d043b0774faL,0x01619bd810698d3L } },
  44875. /* 161 */
  44876. { { 0x12305bcea22fa65L,0x01f7a68acfb1d3dL,0x01f4fcd648fef86L,
  44877. 0x0d823aeea668e7bL,0x0a054cffb27fb30L,0x0c2b0cb8173f359L,
  44878. 0x14714f3a7e5f2bcL,0x0b706aa04869cfaL,0x1a63e3d82f356acL,
  44879. 0x13dbe556bb22898L,0x179abe99c7f2761L,0x1dbc560f9aefdd0L,
  44880. 0x10ffda51933b985L,0x14a16e1b03eacc5L,0x18862a6c43b28e6L,
  44881. 0x1ab942fe7b9dca0L,0x1c93d94e8d106b7L,0x0284d931a76c418L },
  44882. { 0x1b9414e48caed54L,0x1c63665fa8f4bd8L,0x123537a6c961de9L,
  44883. 0x1923dc7af148d11L,0x030ee64c0024137L,0x0c86bc5347c91a7L,
  44884. 0x1a42d5cc956f220L,0x09883d1c0bf7500L,0x050038d84ec354fL,
  44885. 0x0c7816b6fd2940bL,0x1e401f32d8ff6acL,0x01f7d315c8ab88fL,
  44886. 0x025d0e319d29d48L,0x0136db8ca5622e9L,0x0d61ee741bcd5d4L,
  44887. 0x0ee4ee6773c4058L,0x152224839922c31L,0x00ac96ad3aa5dc3L } },
  44888. /* 162 */
  44889. { { 0x178d9a2cf7453f0L,0x1c4cd76c1e0f82bL,0x1b4f82a0ae9ebfeL,
  44890. 0x15d47aa1035cca0L,0x010aa38b32c84e1L,0x1be820cd6a94604L,
  44891. 0x1907ec7f6c082f4L,0x1ecf1ad97c3a0d9L,0x0d287f0f02e74b7L,
  44892. 0x0e692bae21dd811L,0x03cbcfe069c6cfdL,0x03eb8c67cfe8da5L,
  44893. 0x1cc4fc580ee65bbL,0x1dbd83d29972fe0L,0x12abceb35554e7eL,
  44894. 0x05a5b6b5288e387L,0x17cb958bdf44cc2L,0x00b0a5edebbd13bL },
  44895. { 0x01f0230ed0ab04dL,0x03d803710417526L,0x118f10b16d7eb8dL,
  44896. 0x1fbc03326b3e217L,0x05dd0825b0539e6L,0x076d0b6c4dea73bL,
  44897. 0x128ca48983fbeefL,0x0bf1554eab9cc55L,0x0ed762fa95ec82cL,
  44898. 0x0f326008c3283b4L,0x15891724b8d2326L,0x14ee63d4dad0afbL,
  44899. 0x0b07b447360db88L,0x0b8eb87f7780095L,0x1e246c2e4d5ae50L,
  44900. 0x04145cd160c5007L,0x1283a54a53ab79cL,0x0244b2b63d80583L } },
  44901. /* 163 */
  44902. { { 0x03649ba71353c25L,0x193d089fb3f1272L,0x0ce8707ae78d45fL,
  44903. 0x18f1c537f2217a6L,0x0743f15d94e1c05L,0x0d16f8427f3ecbaL,
  44904. 0x0ef86721d242243L,0x16304807f4ea6ceL,0x17ebf5db41baea1L,
  44905. 0x1f0571a920c0756L,0x161cff0bd430ff3L,0x15ace0cc39b23a2L,
  44906. 0x19a51e8c2c16851L,0x100b084cc014b46L,0x09fa95b9f46a737L,
  44907. 0x18930562a791351L,0x1cb6d41b78906e3L,0x00415d974eb3b4eL },
  44908. { 0x180ef46c4d6615fL,0x14ee080dcc14e30L,0x1b003ec9932bf18L,
  44909. 0x0c21d98589bc445L,0x1eea2c4dc5457e0L,0x0e2d964ae72ccf8L,
  44910. 0x043e410cfe9ca3eL,0x0a7dc06a8c59ac6L,0x084c57c3bce2e22L,
  44911. 0x047618d4b6c3f22L,0x1f8e4e914b169dbL,0x0281408f646a617L,
  44912. 0x18c018545ec592bL,0x0e0bc6233dec5f0L,0x08c016de538041dL,
  44913. 0x0a9e6908e328c5cL,0x0422665e237622aL,0x01b228d23480e48L } },
  44914. /* 164 */
  44915. { { 0x1802d1819893e71L,0x12ec5a9cd10410bL,0x08048c0bb3f285dL,
  44916. 0x166cb7eb3bf8d5dL,0x0d232a808d4cf51L,0x140213c3ba0eb90L,
  44917. 0x0e7b2b0d0facc63L,0x194aa7d965fce8eL,0x0aeca79a81a8b07L,
  44918. 0x04ff9912b7a559dL,0x175ca4fe8747dc2L,0x135dec55342cbd2L,
  44919. 0x12aa08ddc226056L,0x0dbddaa52f3bb11L,0x0f55b9e4feafb0cL,
  44920. 0x17dfe914412ace8L,0x0f1749cdb12eb0eL,0x0382983d234dc7eL },
  44921. { 0x08e4c04e488310bL,0x137192992e6bdbdL,0x02c1260fbeb049cL,
  44922. 0x1805bb7226ba1fbL,0x17b9685c796e552L,0x0f9251877651fbbL,
  44923. 0x125e66dd9ba26c5L,0x0d8f84e6dac91dfL,0x03d619685a8021cL,
  44924. 0x119f13c505978f5L,0x1a61e6d9db5ac3fL,0x063235e9c17d2b8L,
  44925. 0x1136c4ee55a0747L,0x0cf2f9dcd17d5afL,0x12bf9b9a4e2e3fdL,
  44926. 0x1a2403c229b4873L,0x0ecc9595ec36a6aL,0x0407bcde82bf315L } },
  44927. /* 165 */
  44928. { { 0x0ef42a760af09b3L,0x0b75ec99eff0a1eL,0x0783b617aaa0f00L,
  44929. 0x1f9d547792e419eL,0x17106f97d4f5e99L,0x134569390b5ce95L,
  44930. 0x1947d97cd30db25L,0x1bd51f70578b618L,0x020f42f1cf2fda4L,
  44931. 0x198d596690fb2cfL,0x1ddb1e84f45863aL,0x004470cc57cb6f4L,
  44932. 0x10cad08e0bec441L,0x011600c06412ed3L,0x1be7ff664a641e4L,
  44933. 0x116a0ec477b4055L,0x119de84f4f3f5c5L,0x02fad2ed26c127fL },
  44934. { 0x137257e7e8311dcL,0x0a7a8a336789b2bL,0x1916c172886b7beL,
  44935. 0x1805c9566f4e7c2L,0x0579165b38ea9b3L,0x0580d23bb07564cL,
  44936. 0x156137ff7411f09L,0x1b4311a9fa27f72L,0x0faac38b825548bL,
  44937. 0x13cd3782cf4ee56L,0x1dc83c2689c03c6L,0x0aa9f714fc91307L,
  44938. 0x0847a1fad58cbbaL,0x0d5eb5af1c50ccbL,0x1c5bb084615951dL,
  44939. 0x120f6ea227a63e6L,0x0891391e7814212L,0x0298ce40086e0acL } },
  44940. /* 166 */
  44941. { { 0x120136e6b61c3afL,0x0796f03da5db411L,0x19fce0325fc0750L,
  44942. 0x00d5186274ca3bdL,0x0011ca10a978ba7L,0x0fa22d9162c3eb1L,
  44943. 0x1139922ee8862acL,0x1f318bd5e0fca08L,0x15549f02a442fccL,
  44944. 0x0b23a379ec0249eL,0x093d85e70116449L,0x143157b9110e85aL,
  44945. 0x0aded38f8f1600fL,0x091d75a32e5c300L,0x0715e2a92fe6e42L,
  44946. 0x1d429ac7fdc6a3cL,0x1f0f3c9c5acebb9L,0x01e8998a6f88d27L },
  44947. { 0x1cc662db4513d1eL,0x05462eaaca95ef2L,0x08ff9fe1b42b79eL,
  44948. 0x08f409e18bd146fL,0x0e25d06cca2d12aL,0x09b038a6334b721L,
  44949. 0x1872d49851a62c8L,0x0bde9a4e03713edL,0x1aafd617780efd9L,
  44950. 0x16b9d6262ddb483L,0x01d2b10836cd6b9L,0x1bc9e4ea3f4093dL,
  44951. 0x16a1fa2edd11631L,0x1bfebca6d94fb99L,0x0be4a993101a192L,
  44952. 0x198ece79643a7c4L,0x0adeae904e62043L,0x033f9454fd99163L } },
  44953. /* 167 */
  44954. { { 0x017b258ca148ab5L,0x0cbb7d9e30028beL,0x1a6323ca37e6e68L,
  44955. 0x09d1a8a02fd44c0L,0x0578a42287b2cc7L,0x1f63991b92b9948L,
  44956. 0x0ef120757b8945eL,0x1fdae823f9e3a91L,0x146217e6b487f5cL,
  44957. 0x1803d62a0f5c70dL,0x115e9b816803232L,0x1a57a5f3f533883L,
  44958. 0x1b40941cad1f954L,0x1c14a84e9b85eaeL,0x1b297bb921e1e70L,
  44959. 0x1f73c9826eaa4b9L,0x1b2e8ef7fa4fd3eL,0x02ff848ba0de8deL },
  44960. { 0x11912a4579c6632L,0x0d227dc51040abcL,0x0e114d58e74eec6L,
  44961. 0x177879379de9f2fL,0x119e6410e57e2bcL,0x0becd689159f95fL,
  44962. 0x1fd987c0627684dL,0x098ceaae776f3cbL,0x1444e5c98ef2f3cL,
  44963. 0x17b0f1002688398L,0x08d9beb1d758d75L,0x190c590a9e461bfL,
  44964. 0x1e0ad0850b9fc47L,0x17b906196025721L,0x14ef27573a53d90L,
  44965. 0x074c6cfdf5ccb4eL,0x046c27d30d3b037L,0x03340809d14b90bL } },
  44966. /* 168 */
  44967. { { 0x185d913e84509dfL,0x05f6ee799c9bb09L,0x174cd08e8523a5eL,
  44968. 0x07dd196af25be84L,0x11c4553c43fa0aeL,0x1f8ea4780a9b4e9L,
  44969. 0x09128173c22ef7eL,0x0675bfe97cd2888L,0x001635f81a35ddaL,
  44970. 0x02e44a4f3b7d5beL,0x1ff37859cdde0c2L,0x0a5944a9f1a497aL,
  44971. 0x06413ec985fd8cbL,0x1d481366310b453L,0x18786dfcb6e5d05L,
  44972. 0x1ffbc72c5dcaca1L,0x11fbee0a346d3beL,0x01d9adb9785efd5L },
  44973. { 0x1f8de9f535c3749L,0x0f907c56ece245fL,0x0def23e3d98c8f0L,
  44974. 0x0bd1e75c9352eb6L,0x1d5e26282529e47L,0x03178ee197886a8L,
  44975. 0x0f8d96b034a5d9eL,0x0c4278f26710a99L,0x148f004ef4b67e4L,
  44976. 0x11bd0a872e88770L,0x11de374a0a2283eL,0x14cd9f6e7e9a92eL,
  44977. 0x130780495296830L,0x0bb05b4a4fa2200L,0x0dd726608cf1c26L,
  44978. 0x1f3390681994a4bL,0x0853f62e40bc771L,0x023e850f5e6cae3L } },
  44979. /* 169 */
  44980. { { 0x06f4fff652811f1L,0x05549b177980113L,0x0955432e832baabL,
  44981. 0x1400fea8ced870fL,0x002f2673a350142L,0x0e3732e3fe88151L,
  44982. 0x18f6576bb95c0cfL,0x03cc0d05d860c94L,0x146cf0bb0462b25L,
  44983. 0x1018652aed49b73L,0x0983c90d0996d43L,0x0576d369d1eb90fL,
  44984. 0x0c7ad7770a9637bL,0x169d0ad3300fdacL,0x057a5847c851fdbL,
  44985. 0x0742c0b68fabc53L,0x05ccb0ca9b38321L,0x047a5b0a524cad4L },
  44986. { 0x0a8ec194b4eb3c1L,0x04d6210191d382dL,0x0c893db31aaa315L,
  44987. 0x168bf34b4601a92L,0x0897abbb0e53b9bL,0x166be8723778880L,
  44988. 0x0d623fa1cf95f5eL,0x1a2f9f99fca1ef9L,0x00ea53d65c85557L,
  44989. 0x0ecf5a239447971L,0x17b7eb03ada2a3fL,0x08e010c07419565L,
  44990. 0x0900feb06c58221L,0x12f2e55634a3234L,0x1246ba60133d6fcL,
  44991. 0x0bd5db0ab30b13fL,0x001ed9378b173c4L,0x047ca168129264cL } },
  44992. /* 170 */
  44993. { { 0x11ec3028e845808L,0x15ffd5bbd5fe28fL,0x12e7e365f71f0c0L,
  44994. 0x087558b2964d5faL,0x074d94dc3d3a83cL,0x12c88e71dba5e8bL,
  44995. 0x0b3491192dcdf2aL,0x1fcc524aee70e38L,0x1419f24853b4440L,
  44996. 0x0d35079f02956beL,0x0a035a11b21b037L,0x13f5f0649e84c8aL,
  44997. 0x0807cf117aa2568L,0x06ee4edbe3a568fL,0x1bf2175589b7a82L,
  44998. 0x1d6a6a4c406e72cL,0x0cbe0ad57c3f3b1L,0x01c1801294a4e0dL },
  44999. { 0x0ef5a405e744723L,0x1e7ba8d704240d0L,0x0333fb07ddbf6d6L,
  45000. 0x03f566ff8d57f5bL,0x08fedb78fba5d83L,0x09f9885f1cf1246L,
  45001. 0x17092973eb57eb6L,0x1eae8ffb63d227aL,0x1052a47c94518b7L,
  45002. 0x11046b63e7da193L,0x172e71c394e2fa7L,0x0eb2b762f22d626L,
  45003. 0x005b3106c736352L,0x0104dd8351603c4L,0x11412b74b50a81bL,
  45004. 0x1c0696a4b68e3a7L,0x1a5c9f4b368822cL,0x00af8c3cb75a0c2L } },
  45005. /* 171 */
  45006. { { 0x14dea060aee4684L,0x10f833e6dede404L,0x0526c64c4c650acL,
  45007. 0x03034fb74d4873cL,0x1c2ae80fea4bdd4L,0x011ee163109b831L,
  45008. 0x046c6d62c259c4aL,0x108e887aa2b064cL,0x02e16f83113c203L,
  45009. 0x071026b15ecc969L,0x16f35bd064e22c3L,0x1a3a3a6ef18e933L,
  45010. 0x0fc5ddae73492deL,0x0ca5b12cceadebaL,0x01b29a35204f54aL,
  45011. 0x18558323b39ec1dL,0x038562179eaf3e9L,0x030a378f9cff709L },
  45012. { 0x106d33e078e2aa6L,0x17bfbcef74932deL,0x1e076a903a11a4eL,
  45013. 0x11373480fdaadc1L,0x0de9951905fbbb8L,0x16dd1cee7a256e7L,
  45014. 0x1dd2dfdc7e34c24L,0x1d6ceb6bb4a8462L,0x07456a251a5f605L,
  45015. 0x018ea57c3d1cd4fL,0x0c001816d1d2f64L,0x17e56ccb5523b68L,
  45016. 0x156631eeb4bda5dL,0x111bbe2c2e8d1efL,0x1742ffc0a0527bdL,
  45017. 0x0cbbc5c35e9d2d0L,0x050e0ea087582a4L,0x04aaa1fcf035e80L } },
  45018. /* 172 */
  45019. { { 0x1cbc6f485d7c6efL,0x00426b1d8de127bL,0x1a22fe32e98b2b6L,
  45020. 0x0d68ab8325bf219L,0x174fc6ed98e4b68L,0x11003bb0a35c6abL,
  45021. 0x094a5c388e279ebL,0x1eaa48388f2c384L,0x17d2215103884e5L,
  45022. 0x16906710bf14139L,0x067d453c99d3e35L,0x00aae18023b7c62L,
  45023. 0x19fcfb760e85459L,0x0f46150cefd5baeL,0x1f52c9e5518d8aaL,
  45024. 0x0d31896da7f1494L,0x0ffa5c87104ee5dL,0x036da1a3c15d14bL },
  45025. { 0x04864935c3f0d95L,0x1edc1273a444a83L,0x1d89acbcf912245L,
  45026. 0x0856feae97ee7fbL,0x0f732723c60edc5L,0x1688a65f0e04d15L,
  45027. 0x0bfe5f4d19a75f2L,0x0392c8cc0146435L,0x0b94e2bbaed0cd6L,
  45028. 0x1370d20ef623a87L,0x1a6436c6a27d621L,0x1ad9e4eb2d27437L,
  45029. 0x00c0e0dddfc39e4L,0x0cce452088e7dbcL,0x070c143c2bf35ffL,
  45030. 0x18dc99d7ff5b6dcL,0x0944f3981b096d2L,0x003d3c8f395713dL } },
  45031. /* 173 */
  45032. { { 0x10e90471e9f0300L,0x09d6cde66fc8273L,0x0277fc14c1e3809L,
  45033. 0x1d5d1268c4a3805L,0x04846845f1ef092L,0x0d6a5a1648548d5L,
  45034. 0x19ec8651bb683c7L,0x029e0eca1e667beL,0x1c6e988db0b15a0L,
  45035. 0x17063375aa1787cL,0x0d8c478300de3dcL,0x1b555d0d2a1aba9L,
  45036. 0x0db35f1c8f548baL,0x0a268d6a3400b1cL,0x11c74c84a78c85aL,
  45037. 0x09bbd32a3759080L,0x0ac03cc29f385e9L,0x036b5661722a1f6L },
  45038. { 0x1999e9557b2d299L,0x1e6cdf1eb90e6f5L,0x013eed32d110e8aL,
  45039. 0x13b80c1f545cc07L,0x0c987cdeae17770L,0x1b7df6ba787369cL,
  45040. 0x1effe688df3e041L,0x108d35e2a26f307L,0x06c3f7a1d323f95L,
  45041. 0x110e567b6db21ccL,0x004d3e59c0f648fL,0x131f70727eecf9bL,
  45042. 0x1c2e82522207558L,0x1c92553e0dad945L,0x109ea2ade1e6705L,
  45043. 0x129243b66f1e502L,0x0eed5a451b1ff28L,0x03ce8c1091e9e23L } },
  45044. /* 174 */
  45045. { { 0x03edff9109d5589L,0x0975a014da24c8dL,0x14c2d2d52b7f7b5L,
  45046. 0x0344f7fece27d73L,0x07f0f4604f9214cL,0x1287142640bf73bL,
  45047. 0x188deeb7e360f0eL,0x1838bb807932804L,0x15f29581b966647L,
  45048. 0x05b5044c50343f9L,0x01f3b0c58d145c4L,0x174ac5cea3115cfL,
  45049. 0x0745e2c3fb2001dL,0x1b3e99caaaea70dL,0x1a10bbaff2b37aeL,
  45050. 0x0b01743415f3978L,0x1c850590a2b3e88L,0x039882248d3c266L },
  45051. { 0x0ca2cdf2648d676L,0x0f652a78d8958a2L,0x1250a60387ae6a1L,
  45052. 0x1235915512373b5L,0x0719e195f30d370L,0x181bcbb983955beL,
  45053. 0x19fdae9463208bdL,0x04f58121c295800L,0x10e6cfc708dcd29L,
  45054. 0x1ac44f110f3ed31L,0x0a902e0dc71f193L,0x17c51ef0f193695L,
  45055. 0x0bd84caf3f1f9daL,0x0f070ec97bc576bL,0x0909370f0e7741eL,
  45056. 0x00132d017cbf624L,0x14ff41b214d0bdcL,0x03547c7e4a8c062L } },
  45057. /* 175 */
  45058. { { 0x0a1ed6353235132L,0x119f8acedd445b1L,0x1148a47bf76076cL,
  45059. 0x0f64a2235d0ac4aL,0x1d701bd8c750529L,0x1a7a2edac90d7c8L,
  45060. 0x1cffed34175ca5dL,0x070dc7a98bde31cL,0x0897d985f899b30L,
  45061. 0x14e187de44d8aacL,0x0b468d344c60722L,0x0d744446641c792L,
  45062. 0x0201ceed02292e8L,0x0c1f984fe7922a6L,0x03f468c9e917dd1L,
  45063. 0x0ea70eb4c20595aL,0x1d7db4f45d2cb9cL,0x023a96c60ed941fL },
  45064. { 0x14d6cead5dff4d5L,0x0afeda2d413fa28L,0x18313f1c4d79d33L,
  45065. 0x1037caef1c20e14L,0x18dc6b08dec0bb7L,0x1e124b138f0966aL,
  45066. 0x062b2dd94226d52L,0x064dbbe58c6c321L,0x1fd6ebac6675288L,
  45067. 0x1516812e1284578L,0x0b36a1373f07c3aL,0x0d508aa217c0278L,
  45068. 0x0d1a8868011c783L,0x17d792a29c82344L,0x0c2a23590c4caaaL,
  45069. 0x168e092d0aaee50L,0x152569491ca8744L,0x01d328c79bafdc2L } },
  45070. /* 176 */
  45071. { { 0x0a8ed50224042a0L,0x071d8122978f355L,0x1d31da084761b2dL,
  45072. 0x13de9aba7fdb94bL,0x122d46e54e0fe3fL,0x0233ba99d471522L,
  45073. 0x1406d6663887fc5L,0x072292d8a1deb25L,0x069104c2f83a677L,
  45074. 0x03385e5a395df80L,0x020ec940c5def4aL,0x180afa4e25451d5L,
  45075. 0x17b439c994c5d8bL,0x0e6d0d7fa0f7c98L,0x0e3dbee60074ea3L,
  45076. 0x1f041ad0ddd6ae0L,0x017e80c5cd0fbfbL,0x02a0561b1f6e12cL },
  45077. { 0x11969a9fe7f43dfL,0x09c04160dcf2653L,0x1f621670a45f999L,
  45078. 0x0b2d5488095b2ceL,0x1f1297dabaca954L,0x1753ef074ec2affL,
  45079. 0x0fe387d8625ec8aL,0x1bf2ddb99fa6de2L,0x0627d307016e200L,
  45080. 0x14f839b64c4c452L,0x0979825fc8c749cL,0x0437ec090ea52bcL,
  45081. 0x094019b299af7f2L,0x135a58eceb34130L,0x1375e8c76677824L,
  45082. 0x02bd3d88f9ecc35L,0x14f4de9f2b36ebeL,0x00bed99767d0b4bL } },
  45083. /* 177 */
  45084. { { 0x1ef69196cf40599L,0x086fd806010753aL,0x19eff2abd9e5fa8L,
  45085. 0x0711bbacf07b4b5L,0x055bcfcd0d663caL,0x025e3f2d10fc7f1L,
  45086. 0x018cba70fd4e38dL,0x09a6bec563aa91cL,0x1654f242543c6e6L,
  45087. 0x1aad3d3134c9b13L,0x1f17dec3d04c931L,0x1ef2744301e7476L,
  45088. 0x111e81675b05697L,0x129a147ab67c2fdL,0x14a2c09b4f36cd7L,
  45089. 0x1f6f1c7542b22a5L,0x05da8470255f7a3L,0x02305e80dd0ca22L },
  45090. { 0x034dc23c24d8077L,0x05ac0263906965eL,0x0445bd747ffa0bdL,
  45091. 0x0124f079c5453b5L,0x15904af3578af52L,0x1508c8714fa8d5dL,
  45092. 0x177c11b15c35fdeL,0x0a294a45f74ae37L,0x1bf4e2a06ae89bbL,
  45093. 0x0cd9ae62cf9a226L,0x0a0d9c9b30955deL,0x130b5f9d82ef860L,
  45094. 0x0b7c36cbd094a4eL,0x1ae9c83bd6d7beeL,0x0f892f3b4c6de1dL,
  45095. 0x08436a5ad209e5aL,0x18dc5ca26691f95L,0x03e9a161e0b9a43L } },
  45096. /* 178 */
  45097. { { 0x1cf2c0a11fd127fL,0x1b5dc08cf262f72L,0x0949bbd5ab0d9b4L,
  45098. 0x1dca860ceac4356L,0x0c3e961930cfeaeL,0x1e7338976f13e95L,
  45099. 0x130f5904d44ebe3L,0x130c2b38c360ebeL,0x1d447efe959069dL,
  45100. 0x1c6b7b4753b5754L,0x17186c3d6f4592bL,0x08dc3d11773158bL,
  45101. 0x161ba92320dbab4L,0x1c4c4c32b0c5c58L,0x02dfa0a83abecf1L,
  45102. 0x0c17618f5798581L,0x1a710f09b6e20d1L,0x02df057d3472631L },
  45103. { 0x0ab6d381bbbf49cL,0x0e724c60381ff41L,0x0d77843d098cf82L,
  45104. 0x03b4b48a65d94b1L,0x1618f7b7d9cc658L,0x07bff383f0c43b7L,
  45105. 0x01af81066978c94L,0x0d376353d21bcd7L,0x0584a7deb373591L,
  45106. 0x0759a44a8a4ed96L,0x11a8cec3aeaee0eL,0x016185f1152428aL,
  45107. 0x070a2db0190067fL,0x031f379f5ef06ffL,0x081beb6e946c1b3L,
  45108. 0x1b81543224f73d2L,0x0aee4eb5e87fe80L,0x00f37e67aea6f18L } },
  45109. /* 179 */
  45110. { { 0x17dff66aa8ac924L,0x0d698e14c59f45aL,0x0ca597ec20301baL,
  45111. 0x1a3b2b927fa281cL,0x0a180caa7dab211L,0x06f6b4b6b46c214L,
  45112. 0x1187c6a4a502288L,0x065502a2ea671beL,0x1ff5604ae60eae9L,
  45113. 0x00dcf24bed72605L,0x0ea5ff7898ba264L,0x1349e21093068aeL,
  45114. 0x0f64724f1ded69dL,0x1542d0afc7fd011L,0x114de5357c70b93L,
  45115. 0x00fba98c4d9d202L,0x03780440cd6bf09L,0x022916a30aeed54L },
  45116. { 0x095f079ebfbe7c5L,0x10ef6c2779a2344L,0x1adb5286ae58c3aL,
  45117. 0x04a14618d0e2d53L,0x0043bbaa1a4a5d2L,0x0872faad0b318e0L,
  45118. 0x0155af441d40940L,0x0337ffc7d3a7b18L,0x131b30b18077724L,
  45119. 0x07fbf78425c114bL,0x0df5d7c868630e4L,0x0c6aacb771f0018L,
  45120. 0x0a45e3bceb18d0aL,0x11f85846dd60ed1L,0x0f16b1470e3a430L,
  45121. 0x03f8de3743544bfL,0x0ba09d5256bdda7L,0x01a3280d4b6bf20L } },
  45122. /* 180 */
  45123. { { 0x0be448ccc2b0f1dL,0x1a2e4d6261b81c3L,0x19767f25aeff8faL,
  45124. 0x12b5c4ffb4a70feL,0x1bc18089cef3c4eL,0x050c50d0047bbb0L,
  45125. 0x0cdc7cdd282108bL,0x0a9dd105084a76eL,0x1cb6fc6d87cc093L,
  45126. 0x044f60db0a4b6b5L,0x10a6e5278c97121L,0x14a4f7bd82cd525L,
  45127. 0x0edcea281315c6cL,0x1d108aa7caa2277L,0x041873cd1a0faccL,
  45128. 0x081771f64df31a7L,0x16dc3b08aa806c9L,0x03e0ea167f2aa64L },
  45129. { 0x06e703fdc110aa7L,0x1bcebf9b171bc3bL,0x1d756ab728f2adeL,
  45130. 0x12c17c66e7a4b38L,0x06c4e8ff2a6eca7L,0x1b82dffa3a25258L,
  45131. 0x12d4eca10b33bceL,0x1703475eb555c60L,0x17bbfa2011b2d31L,
  45132. 0x05d375d25f7446cL,0x1597395972e0e71L,0x0d2db5efd9d05a6L,
  45133. 0x07e695974524808L,0x14a7cc1b963e667L,0x0468c9bbf5bacf3L,
  45134. 0x1274c1467699e70L,0x19014203f43fffaL,0x0018f4c1439e18eL } },
  45135. /* 181 */
  45136. { { 0x1efecfc765a17ffL,0x19c4468948532a7L,0x111a4e3680e2827L,
  45137. 0x1b42d35a8d7e4cbL,0x03a62fe84bb6145L,0x04305299e7c10a1L,
  45138. 0x0e31158b7d5c6afL,0x0eb7e5521f502b8L,0x145ba1d6e17eda8L,
  45139. 0x0cec40d4a37d2f0L,0x0f9e12e43d68edeL,0x06f9621fea54d83L,
  45140. 0x04a4f4fd360910aL,0x07169dd061c60ffL,0x1e9861f0c603f16L,
  45141. 0x06b847c5fe0a162L,0x11c3a00059b943aL,0x024a69b22d14662L },
  45142. { 0x18426b64ba021f8L,0x04841bcb6f5b61cL,0x0e55f8db1d8b453L,
  45143. 0x14ea39e42cda5caL,0x19b24a198f556ecL,0x1061576d650f000L,
  45144. 0x09ccd1e21f6912cL,0x1af27da999bfe83L,0x18d717c445c7c0cL,
  45145. 0x02431a548dfb804L,0x051be4ed66eebf3L,0x1673cac49e2b43eL,
  45146. 0x0d303f8443dd38bL,0x05f8827e4b6a0d5L,0x1c19609ad9c3c0dL,
  45147. 0x001ea0a07f3da52L,0x0f3768e1f47b342L,0x01e7ee62f5dea63L } },
  45148. /* 182 */
  45149. { { 0x16c2a86b523e13dL,0x0522c1490685029L,0x11e39d5c4a58405L,
  45150. 0x0cfd6a37d47aa56L,0x07b0e9190574606L,0x144474384fbc30cL,
  45151. 0x1f3500a2bb621a1L,0x1e6f35013afb295L,0x050c6032fe2129aL,
  45152. 0x0f25f394c1e2041L,0x0c6eedeacefa39dL,0x06596c318e51306L,
  45153. 0x013f59c4a4d31a0L,0x16a7b0f11b6ec2dL,0x15c5c576fb38d17L,
  45154. 0x1d7af74f5599a3cL,0x0a1138c58da64a1L,0x04494b6879e8d77L },
  45155. { 0x165288fcca82c97L,0x160968a13f46e58L,0x1c1d30fb76a49b1L,
  45156. 0x1dd5403d7ccd529L,0x10f5e86d94600e1L,0x02b5188a55e73e1L,
  45157. 0x10b09d075c0832dL,0x0d1560b54264f3eL,0x070b60fafd42384L,
  45158. 0x0c77f6098c69cf3L,0x1fc6b22482cc628L,0x1751b0733c07d60L,
  45159. 0x0e3c81a30101e3cL,0x066333ec32fc499L,0x1a181f2ba2f29f7L,
  45160. 0x142599dc35cf344L,0x0543182e64ccac0L,0x04919d17b958d26L } },
  45161. /* 183 */
  45162. { { 0x17e8df60acbee17L,0x0ace12e127e6e38L,0x021f953ff2c03c2L,
  45163. 0x15a50a22d68de13L,0x1ba1fa51b993decL,0x190c1f05fd527c5L,
  45164. 0x1dde6724927bf43L,0x043f27966b12d08L,0x1284bfb7f2322d4L,
  45165. 0x066384d6a157804L,0x1c89d26ec758550L,0x1674e2f878d58d3L,
  45166. 0x05bb9c5eeb76f50L,0x123c1dafc590f4cL,0x1870f9d63ec66baL,
  45167. 0x035900990d736a5L,0x091aca59092f297L,0x015d9353490f6c1L },
  45168. { 0x0a3443515f81416L,0x13973d57fadda4cL,0x13780c5c987021bL,
  45169. 0x18b81439fc7a3ecL,0x1368340131c0786L,0x1cda66aa17526c5L,
  45170. 0x09fc4bddc9ce868L,0x1b829fcfdc397deL,0x1ee7fc09e16bb27L,
  45171. 0x06e660ba0872ee3L,0x199d08650ecf770L,0x16c07e63836f468L,
  45172. 0x19c22c107092934L,0x1ccfcb3580c36f6L,0x06c224e8dfba2e9L,
  45173. 0x1a9bc1e77f96849L,0x108bae614472e92L,0x049be59fc70cb75L } },
  45174. /* 184 */
  45175. { { 0x1c0e77c16fbfdceL,0x1a664e4c6a6602bL,0x15c9095cb483a80L,
  45176. 0x1800335079cec0dL,0x115971629861b55L,0x107ebdc05d1401fL,
  45177. 0x0aa883d05077416L,0x1d910cb2276961bL,0x0e6685746aa3848L,
  45178. 0x168ad2d1f0242e9L,0x031dd0eda417745L,0x16fb0315e575038L,
  45179. 0x14d2b74b78cec31L,0x0a1f1794406c78cL,0x0c1f073299676c9L,
  45180. 0x09180637074fb3fL,0x01186537fdc1f10L,0x026abdd83bc2c35L },
  45181. { 0x04b768a53b396b6L,0x1926249da8ed65eL,0x07ae8c2b86cef22L,
  45182. 0x0b28a28f8a67ca2L,0x179fe3ce893bbd9L,0x0905ea366430188L,
  45183. 0x18580d2c2859cfeL,0x107665225d6d64aL,0x0bc69a2a49d168dL,
  45184. 0x04a4f3d7786e894L,0x0d066a1c9a6786dL,0x08ef7e426ed64c2L,
  45185. 0x09a4f9714706c58L,0x1dcdba2ff2ad8c8L,0x17cf2158f5badd5L,
  45186. 0x1f5c76a6cb65211L,0x0a80e257e4355fcL,0x00833e08c4bcf95L } },
  45187. /* 185 */
  45188. { { 0x045508432bf8883L,0x0943537e83333e4L,0x1e3ddf08cd751d5L,
  45189. 0x145e945929ae161L,0x1118acf5678e60dL,0x0dc86cd2346c566L,
  45190. 0x044133a4e0c2efdL,0x149d49638e9da9dL,0x0ac67316d27776eL,
  45191. 0x0c56bae1b0dd589L,0x0f520a64489146eL,0x0440a614875d864L,
  45192. 0x0e3292d5a526440L,0x0ff678de1d22299L,0x19ee2e36d21a52dL,
  45193. 0x0d5bdc9c0a2dd8cL,0x125b3aa595fa430L,0x03f27b848f9a74bL },
  45194. { 0x13816e9b7f70919L,0x10b768b5801fa9fL,0x1fd1de326795d94L,
  45195. 0x10614a30208d8d9L,0x05e728dbe6a5abeL,0x0677eb77b7a4f32L,
  45196. 0x1cfddbf75cfab2bL,0x187d8729cdf186fL,0x173320802b6407fL,
  45197. 0x04747bd4b312e5eL,0x048d8df2afec026L,0x13be80fe6b35065L,
  45198. 0x05ccbfae50258baL,0x1f128c09ff80d77L,0x1c72e87efabab3bL,
  45199. 0x19b6b38d3e2c307L,0x0bd512c58ad9eadL,0x015724e6a366674L } },
  45200. /* 186 */
  45201. { { 0x039b0e3c40849f2L,0x15266d22084c609L,0x0a67951fd92544dL,
  45202. 0x08f537758cc2a6bL,0x13547af692e4bdcL,0x03d3a50cad0b232L,
  45203. 0x08aca17b2cc662dL,0x05a4f0aa7f93bcdL,0x1471c038a0e2ba5L,
  45204. 0x15d0dc41ade5d49L,0x1d4369bcc7b2884L,0x07ed0056658da97L,
  45205. 0x113c64c8c4d146eL,0x1769094b864e009L,0x1a14c3eb4c3c4b7L,
  45206. 0x1bca336eb7ff738L,0x1b723c0ad3e8918L,0x00c074ea9539bb8L },
  45207. { 0x116542f29ab77b0L,0x08ece7bd7731461L,0x1a14d4f0bd03750L,
  45208. 0x089615c99e08980L,0x15fc266f638dc7eL,0x17f5bed04920c2cL,
  45209. 0x05e618e7699c7f4L,0x054ad0b1daabd47L,0x17a694f3158f383L,
  45210. 0x0a119e3698b6c18L,0x0b2c98c28d69eeaL,0x0fbbe3fee2765f9L,
  45211. 0x0559eee2f3fef8fL,0x0ab6832545cda29L,0x173f3f346d3e46cL,
  45212. 0x1d6822ef0cd845eL,0x1b412bc25663777L,0x010e5379e6c55c2L } },
  45213. /* 187 */
  45214. { { 0x0162b13a3e66635L,0x10515954fbb5787L,0x08c11b6ccd587bcL,
  45215. 0x0ef005771b568e7L,0x0699b44c0840bd7L,0x1103f8adb5d7af5L,
  45216. 0x004171b8464006cL,0x009cbbc2d52f216L,0x122b12f15db67f0L,
  45217. 0x02fd6a2c5012e92L,0x1da54f7c2845086L,0x0537e8a06981799L,
  45218. 0x001c277bff4c421L,0x14054f0c07ba020L,0x0aa8ad1b9102d30L,
  45219. 0x1b29eecfbd1eb08L,0x0353de20ab805e8L,0x02d7fac2c90113bL },
  45220. { 0x05acd20a8458e40L,0x0abec0a4b995ec0L,0x04c57c729cb5695L,
  45221. 0x192a56a6478e0e8L,0x0494fadf7f2e269L,0x1e93332e2c92ab3L,
  45222. 0x0a19454edeb3469L,0x0d74dbe0c7b0dfcL,0x11e91db1357d53bL,
  45223. 0x0caddc4f49f5680L,0x0786bca58eff9a4L,0x1385104f110c7aeL,
  45224. 0x123b859b6ffab2bL,0x1b814ee8bbc1b34L,0x0611585b9a545d3L,
  45225. 0x1b0938f30f0ecf7L,0x17764fb4f1d5907L,0x01f55bf0e446c54L } },
  45226. /* 188 */
  45227. { { 0x13a94b652e5718bL,0x17d2a7a6770f4e3L,0x198d54fbb7ab8ebL,
  45228. 0x16be759434ca9d3L,0x0d083316f2541e1L,0x1fca876b894a448L,
  45229. 0x0f929e596bd8fedL,0x179b1f93c1b8e9cL,0x0b4ee48d2eaf79eL,
  45230. 0x02c543545bbc3f3L,0x1d887fdf33abc29L,0x1dffbecf301bb18L,
  45231. 0x02f91067278228eL,0x183f1b149086a3aL,0x1c78a7647d8d406L,
  45232. 0x1714a882ec38cf2L,0x144c0ccc65f03a3L,0x01a48ed279c704aL },
  45233. { 0x106d046cb062eaeL,0x0db9aae843bb6b3L,0x0148a48c574bb9fL,
  45234. 0x05880577b701bd0L,0x06ed33374078566L,0x0b4769afc9a92e1L,
  45235. 0x02c79b3a85359f5L,0x0eb22d42312cd11L,0x00fbd52055dc716L,
  45236. 0x19e883bf22baef9L,0x0c402bb0248cd60L,0x1a02d9b0a7129d2L,
  45237. 0x05432263682f9e1L,0x0dd267ebf75e9b9L,0x13160e100745cacL,
  45238. 0x02fbc6efb573aaeL,0x018aeaa695880d5L,0x006421efeb568adL } },
  45239. /* 189 */
  45240. { { 0x15811ffc9373300L,0x099954cfee18022L,0x0070d4f2d95470eL,
  45241. 0x152d507a4fc3377L,0x12ee3f1a774b924L,0x06ab63e5fe47e5dL,
  45242. 0x0bde6bc9e3b1004L,0x17edfbcd05fc157L,0x07566d0727339aeL,
  45243. 0x09ad6aeb8902edbL,0x0f9a51c1472742fL,0x0901a7460cf96b7L,
  45244. 0x14572d7530577dbL,0x1036c29e96387faL,0x0afed77a1856bb3L,
  45245. 0x11daee33339960bL,0x169eeefc96bea0aL,0x016e6234e9afb6fL },
  45246. { 0x0a6cd06c65f0e77L,0x03cc05eb8d8a566L,0x1e2cf24f3003773L,
  45247. 0x075d197eaf6c443L,0x16f8e63fddfcd5bL,0x10995bde494b9fbL,
  45248. 0x1278ba61228d01bL,0x034998b3407aa3dL,0x19c9d32bb3a3308L,
  45249. 0x009082940742335L,0x000ca86ef9ca540L,0x0ae449270891856L,
  45250. 0x0eb6bba0ffdbfc6L,0x0054a40174b9506L,0x0762f1fd830293fL,
  45251. 0x14171ec588398b3L,0x1fc820c96ee312dL,0x02d0d32ede6defcL } },
  45252. /* 190 */
  45253. { { 0x1ba691a42485684L,0x08b5c94e23864dfL,0x05c798a8146584cL,
  45254. 0x0cbfe933b569603L,0x05238efff3245aaL,0x0eaa8ae177c3fa5L,
  45255. 0x0b2b305b71aeb32L,0x196b4fe44fc5b7bL,0x18dedaac4a9bbaeL,
  45256. 0x1984536973e4c42L,0x1cbf0b9a25564ffL,0x050a2efc0c2298dL,
  45257. 0x06300b1bee3655fL,0x09e0bdaa531f468L,0x05d098afb4339e4L,
  45258. 0x0806f94957c6b89L,0x1d9f4b44a17bc4eL,0x02d74a84cf7f2fdL },
  45259. { 0x02e5ee7804f7455L,0x124cb9103334109L,0x10c5de578cccd06L,
  45260. 0x19c91df9db2fa49L,0x19fbc21c12f4123L,0x11d1d77439c6c90L,
  45261. 0x09b6eecef718419L,0x0ea6c07b1850b27L,0x1926227f2e3c1acL,
  45262. 0x15495602f55728cL,0x05bc2ff5a04ab3fL,0x1089f85505b8b6bL,
  45263. 0x1a63522b273ce7eL,0x09433c4a9c20240L,0x1621a220d8222c5L,
  45264. 0x0f95843ff6f984cL,0x0980ca331612f4aL,0x02088333f51f6e9L } },
  45265. /* 191 */
  45266. { { 0x1830357c2d04b63L,0x0d1a6fa494d0c40L,0x1b688b46577cff1L,
  45267. 0x13968648e78e77eL,0x0997f13814df2f8L,0x0b027a1a2d7f2e7L,
  45268. 0x02b97638fd7e62eL,0x1e75af285d2a182L,0x0cefd5447eed25fL,
  45269. 0x1b4728f0739e066L,0x0b5646ad53e932fL,0x020a256c3918b63L,
  45270. 0x13b5abf7608bbc1L,0x00f3cb24ddc9948L,0x0332f9f6c48c6f8L,
  45271. 0x0db73a1507d2208L,0x1ea3dde426f90a9L,0x00e675b229a6f88L },
  45272. { 0x1210c4f0c6d0f55L,0x0fb0dce339e4e96L,0x0466a738feedb2bL,
  45273. 0x192760c7c9baff3L,0x145a93be135f494L,0x0977be2c05ed9e0L,
  45274. 0x0eda9361c8cc83dL,0x1dce9b0edd11029L,0x14f6f723ac7a97dL,
  45275. 0x0f15c781f1e6c19L,0x0bc20ab9c809c1fL,0x05a9bbf490dcc2cL,
  45276. 0x198d3a17c6e88ecL,0x1cc00b8d6cb2e42L,0x1bdac898b967950L,
  45277. 0x16406156c50bb77L,0x0a33cf451954d48L,0x00f8ba919a7512fL } },
  45278. /* 192 */
  45279. { { 0x08a765b3467ea91L,0x119777e96ce22c0L,0x11b673caf1bcfd1L,
  45280. 0x006b30275cf6ebbL,0x044cbd8defc8d24L,0x092b1111f65904fL,
  45281. 0x1866966e8438c85L,0x1eff429b2687e3dL,0x1df97c21bfb0c48L,
  45282. 0x073144875186a1bL,0x1b8a919451d70b1L,0x03c824cce54b650L,
  45283. 0x1c31aab3b8291f0L,0x10be91764e37ed2L,0x13c2eb6dc9de96bL,
  45284. 0x125c37b11db0722L,0x02bd0b05d1b6a23L,0x0265c57c832c49eL },
  45285. { 0x0b02057bb4b1953L,0x045a27acbfb7751L,0x166d79904b21338L,
  45286. 0x1b679a92330a9ebL,0x0e42bb5d1913262L,0x073fb04813b1723L,
  45287. 0x105b20d57239b5eL,0x0311df55048716dL,0x0d0173790e550f6L,
  45288. 0x0c57a3172bebbc7L,0x0b57a1c56d1c504L,0x0d8683bd49f342dL,
  45289. 0x12280ca61090059L,0x1ba632d0954abe1L,0x0201050bebba000L,
  45290. 0x01f43b620a24ea0L,0x0fc8c1db931ff08L,0x024352e12ebcc3cL } },
  45291. /* 193 */
  45292. { { 0x121e213941b4f36L,0x07d8a7c01da7c82L,0x08b94a952ea2eabL,
  45293. 0x151fc8f2d9fbe3cL,0x18dbacb6acfabbbL,0x0efd28d703c46daL,
  45294. 0x05bbb7e635cdb06L,0x0362ab850d46b4eL,0x0be7d46769c8646L,
  45295. 0x05b1c07b1d3252fL,0x1064527d8249894L,0x0fa145bf8b66296L,
  45296. 0x15cef466ac0919aL,0x14c35576622a6d2L,0x09273b64fe92891L,
  45297. 0x0eb5aa12162e2e3L,0x054602f1d6cc1faL,0x02e934fc4bc7260L },
  45298. { 0x074030c14920419L,0x0ec34484b439c9dL,0x1313badc3e98211L,
  45299. 0x1bb3f8b79703732L,0x158f8f2dabcaa06L,0x0e29550329ca13fL,
  45300. 0x06ea8d7217d9ec7L,0x068b4fb1ae45922L,0x14041005caec2d8L,
  45301. 0x0c345223d4729a3L,0x18602e37944b0edL,0x0dca4222d1d609dL,
  45302. 0x0b2317cd8a4daa6L,0x108b26fb605eaedL,0x0eb5f2687506175L,
  45303. 0x04d0759db944c3bL,0x10f0fe4b5ac09b0L,0x04564ccad136caaL } },
  45304. /* 194 */
  45305. { { 0x0c8dc9b2640a39dL,0x1859c76f064fcd9L,0x06f687b2e82887fL,
  45306. 0x1a101a082ee9e8dL,0x149946048a902ccL,0x1b558af4ab7d197L,
  45307. 0x1d248d23e173e5dL,0x0cf843f8ddc00cdL,0x135b1ebfefeeef3L,
  45308. 0x0022c0e2309f2f6L,0x1fa39ba9ae81c5eL,0x14652a1ae7db97bL,
  45309. 0x161da48889ddfcaL,0x0dd7fde8e4ba3c9L,0x0ebab9f3a19f233L,
  45310. 0x02591a4ce863e39L,0x04d682550458979L,0x0063e0eee6bf50fL },
  45311. { 0x1aa30cc1ce963a7L,0x17b266262fd6f29L,0x0be0a0a2befdcd4L,
  45312. 0x0d9442420e57354L,0x05a576dc64273c5L,0x1ae3be556ebb2a4L,
  45313. 0x1ce6d865ab0fa42L,0x18841a87d3fa355L,0x1fc392062cd05cbL,
  45314. 0x00b1c392607f97eL,0x0ae360aba087985L,0x12867f4f47e19e6L,
  45315. 0x0df644ca925f58fL,0x0c8c53afd75f8e9L,0x01d84603018558cL,
  45316. 0x04882f3136bdad7L,0x1abbf342445ad41L,0x0127fe4d70efb19L } },
  45317. /* 195 */
  45318. { { 0x1fcdc0593c7cb2bL,0x01dcaac8029fdc4L,0x0f3d8608d0f3049L,
  45319. 0x1ecd8314c6c03bdL,0x0c913287364546eL,0x1c4618d2948380fL,
  45320. 0x1df5f0d6e009be5L,0x0510a570c5525a3L,0x11809cb050aa797L,
  45321. 0x0bea33e51e59002L,0x11df027bd6e51a2L,0x1885e4483309e41L,
  45322. 0x0df35bb206c3372L,0x14e0a05aed029f0L,0x15beccef09b1b42L,
  45323. 0x072d0c39f981996L,0x1a41c3cf9ef299bL,0x044f269e8a0310dL },
  45324. { 0x15e80e7a45a9be3L,0x152bc039ab7dee9L,0x18bae59ef0bf136L,
  45325. 0x1c8f9a2dc6030daL,0x1f30ce9ba702679L,0x0327a865178e012L,
  45326. 0x0759bc4816d187eL,0x13cffadaf2f0a0cL,0x047edc4f68a0880L,
  45327. 0x0d60224cd269d71L,0x119929b47e76a17L,0x1d09af5074e3f08L,
  45328. 0x0ceaac33f19f30cL,0x0a431155f49c15dL,0x1a07ac87c0ce0c6L,
  45329. 0x16b8f606f4975eeL,0x0fbd156a90899a1L,0x033ae9f37f378e8L } },
  45330. /* 196 */
  45331. { { 0x1767ffd707193e5L,0x05548c081ac72ecL,0x07fcca363bdf91eL,
  45332. 0x10db77b34eac69fL,0x1e215686913a0eeL,0x0ced1c1bcd94b43L,
  45333. 0x0d34a40fd042a27L,0x16bb3f1af723626L,0x09fe74229bd82efL,
  45334. 0x1ab45b11c01e3bcL,0x068d434f494d136L,0x0b60e4892fd127dL,
  45335. 0x16a169e23b559c3L,0x062da634e2396a1L,0x11fd4c4261918cbL,
  45336. 0x0f1113edaeb3b07L,0x04ba91cf1db1e49L,0x02fbfc97f30578dL },
  45337. { 0x18a1cc60545167eL,0x1170157fd447078L,0x1d450ca9ef3d57bL,
  45338. 0x054ea210cc499bfL,0x00511af77382da4L,0x178a11f44a608faL,
  45339. 0x14abaa93938c4aaL,0x06b187a6de1ec7bL,0x1fc5c9550d76606L,
  45340. 0x0929b989bf53f55L,0x135660e6e543d80L,0x0c0281cc688454bL,
  45341. 0x0ef2ac704595a0fL,0x023587b9c82f11cL,0x1215e2912eb3039L,
  45342. 0x0f00699a840dd88L,0x18d367b1aaaa5bdL,0x012df676c8515a2L } },
  45343. /* 197 */
  45344. { { 0x19a73820c33a8fbL,0x1b6688792ee0e83L,0x0fe31b520adb3efL,
  45345. 0x180f7f08949ff8eL,0x199162f03e51f18L,0x009c08d3b2891b2L,
  45346. 0x06282b1669d3850L,0x1632af4d0cbcaa0L,0x1e1ec51bde3ca09L,
  45347. 0x0063f59d4b0129fL,0x0ff451f780fe12fL,0x1da2a5f7b613d07L,
  45348. 0x1dcea15ec1c0540L,0x05930983b5d2976L,0x0e5c81bcf4c3b55L,
  45349. 0x0e75537af75d1d0L,0x163f20d86920963L,0x00530b525e1d85fL },
  45350. { 0x075f3ed6e1339c9L,0x150395fc5805310L,0x120af3366d1debeL,
  45351. 0x1e0194a98fbf5fdL,0x18bc31ae4713158L,0x06fe45224881789L,
  45352. 0x15352be63c560c4L,0x18993de40eab3d2L,0x1e8021af9c527a0L,
  45353. 0x140093bbd0c9011L,0x1d4e31fec08dddbL,0x0e9fd193d2a2c6bL,
  45354. 0x0d15cc90975df19L,0x1bd288ae0143fd7L,0x0b188f7e81ca3c3L,
  45355. 0x1741321b7f7cc1fL,0x04ca8d40fd40311L,0x043b68aa703e323L } },
  45356. /* 198 */
  45357. { { 0x1a4d6d2c2d3ea8aL,0x1340dd421300769L,0x0037901c19c8dafL,
  45358. 0x1cd4faf4f78a7e2L,0x1d5e1a83e3e5b6fL,0x04be153734ca7caL,
  45359. 0x040441f2b3489d8L,0x04825b31b754cf2L,0x0ddfc4461102e0eL,
  45360. 0x00aede16a499395L,0x03992ea50d9a592L,0x163465657f20fc7L,
  45361. 0x05d928e28b4960eL,0x1503be4f6d22ba9L,0x1587401cbdd6ce4L,
  45362. 0x028ac4eec1976ffL,0x100af235d1b0f4bL,0x01820611df3b68bL },
  45363. { 0x10dc55b4efa9a70L,0x120a7a9f4330858L,0x044c27e289ff537L,
  45364. 0x0a0ccc3a787b2b8L,0x00eb513e505109aL,0x1e99c5e5514ca53L,
  45365. 0x19c7cfb9054dc79L,0x1689fa28bf88ca3L,0x051bbf838cbc313L,
  45366. 0x01cf03c0f5c90a8L,0x05ad1052fd6b1ecL,0x031117c1a919d0dL,
  45367. 0x15dd8f2b6f2d667L,0x15c53fc55f49d97L,0x1dd4717077f479fL,
  45368. 0x0e97d0c567bb321L,0x1a21eb1ad58a32aL,0x02a436bcd0f5de4L } },
  45369. /* 199 */
  45370. { { 0x12e34ffa1359e13L,0x0c6df940cb028e5L,0x08f48d592d7880bL,
  45371. 0x0c85ed5825d2bc0L,0x1653725dfb1340bL,0x123356aa1dd4295L,
  45372. 0x1ca2e06bb735a34L,0x0cb7ef00448a8f8L,0x1559f8a119569fbL,
  45373. 0x02dbd316fd91764L,0x01d5027bb579494L,0x0510533ede220e2L,
  45374. 0x013db6f8c79c899L,0x19e53cd4d3eb493L,0x08582c0c3adfeceL,
  45375. 0x0813595733771f6L,0x18bd2012568d28bL,0x01c078d87ad622fL },
  45376. { 0x0b99e6be6a0068fL,0x1e79564539ba9e0L,0x1522cbebadf12d9L,
  45377. 0x126804c1874d934L,0x0c0f739e7f417f9L,0x04a4ed4772b42aeL,
  45378. 0x1bbffc22d443de0L,0x17762ee1f851ab8L,0x0b4f5abeefd96a7L,
  45379. 0x03d889b79332d15L,0x0e0292d80773e68L,0x0c282c57d98c5f6L,
  45380. 0x16ee6b83b3cc803L,0x1460bf759a4c7dcL,0x1dfbf0baa6c3f5aL,
  45381. 0x0167cb0696b7542L,0x05e929044f55b11L,0x0255f6ef6f5eb94L } },
  45382. /* 200 */
  45383. { { 0x155e1b9700ef376L,0x12ecd3366d5ff99L,0x15d51fa1d91b55bL,
  45384. 0x1401ef26d367b84L,0x00c52e2928f44b8L,0x14d9c90461958f5L,
  45385. 0x08e7569e37848dcL,0x0d68308a33564daL,0x123f6b4b7e0ce4aL,
  45386. 0x1afb7c5565954fcL,0x0f1153881929648L,0x006837e60c5d771L,
  45387. 0x1b94dff6f937efdL,0x0553fd0335d6341L,0x02cdd170cd92c7aL,
  45388. 0x1f61e0c2cee559cL,0x0d346f08d08d1e3L,0x0351055d98c7099L },
  45389. { 0x08310166a85cbc7L,0x084a349a7cd53f5L,0x02239de3c6cf426L,
  45390. 0x1e448f6f3384422L,0x054484ce7ea4ff8L,0x0c61b2598b8eb8aL,
  45391. 0x05160a500e5253eL,0x02cbb5223e72fbeL,0x0a6b58093094391L,
  45392. 0x0fca84d0ba11c5eL,0x1460860825d635dL,0x004348f24ba1fd6L,
  45393. 0x14af8a315eae0c6L,0x15d6825b874a334L,0x1c911f6b9ebe28dL,
  45394. 0x0dffc8982bcffe0L,0x1775184668aa545L,0x022f1a9d3df9b5cL } },
  45395. /* 201 */
  45396. { { 0x005676493092f71L,0x15b617adc96b8bbL,0x126f8b22db17ad9L,
  45397. 0x1441806c7d3b662L,0x03cd7097f62f583L,0x1c8b56344566998L,
  45398. 0x06c3a174303e3aeL,0x1a237ee8c590983L,0x1c76ed5f97c4a6aL,
  45399. 0x045c45d688cf9b4L,0x00dc6faf942e0fbL,0x0a110cce0d4cb37L,
  45400. 0x03f8373d2c0cc69L,0x152d017da98e3adL,0x0e6874138734e8cL,
  45401. 0x0667dd04e8ef1b4L,0x136edfc5bbb75daL,0x00aca0f92653cdeL },
  45402. { 0x0e8c0f8a77dd512L,0x1acd38ee1b2fb21L,0x133421d4e18aa46L,
  45403. 0x1ba4e5f595d01a2L,0x0027cb5a1624230L,0x17cf81f751f60b2L,
  45404. 0x0523705c02d6707L,0x1e3a823824e1b46L,0x1801ee448c4181aL,
  45405. 0x0f942accf1d4805L,0x1ec2f43426bff7bL,0x1f2d166e0048bacL,
  45406. 0x00e6f836b8d839dL,0x1e9900e49db183fL,0x0740aed4e0b9622L,
  45407. 0x083d2c6db14d6f4L,0x10370b7db769686L,0x0368be1a508c7d6L } },
  45408. /* 202 */
  45409. { { 0x1608841c181c99bL,0x0e480e43dee57e7L,0x111cdc836afad97L,
  45410. 0x0ca6eea2b768c16L,0x0a96c2774c79c39L,0x007a206a23f9170L,
  45411. 0x00eb4365484c0abL,0x141066164d7920bL,0x0e25e977a928904L,
  45412. 0x0f57fecc2e2858cL,0x16f2de96b57da87L,0x00339146fdab9e9L,
  45413. 0x101e9850b6cbcd0L,0x185c7302bc236ecL,0x04cbe406b20652aL,
  45414. 0x1c51772e50ae268L,0x14e4ce9f149f56eL,0x00d5cdad21f4f0eL },
  45415. { 0x06dab92314fa7a3L,0x1787823c7fcb190L,0x1c4e41367f6f312L,
  45416. 0x1625808bfc999c2L,0x1d8f6d7dac20a2eL,0x1db7fd227e2a3c7L,
  45417. 0x1dd6221b9cb1729L,0x1aaff48a536dfadL,0x14df1d1b192a820L,
  45418. 0x0c097cf93c4f8a4L,0x0bc20eaaed4f48fL,0x073654075665308L,
  45419. 0x10b151250226485L,0x198fb5eab18e704L,0x0db98d384a53455L,
  45420. 0x0cd5f64526c3b28L,0x1ed8c4281c43ca9L,0x01259a4ab610d59L } },
  45421. /* 203 */
  45422. { { 0x1bdcb86659824e2L,0x067242709f3a624L,0x0899aef87ba9b71L,
  45423. 0x0e3c7d88af49803L,0x0f5a8e4b47b2b8eL,0x19a986bf458af01L,
  45424. 0x1480ba07adb9b8cL,0x13f59746d3c2f48L,0x081241431d70e4cL,
  45425. 0x0c857a59f095f5cL,0x1c148c47d21bf70L,0x03c253f6579ca64L,
  45426. 0x0bb70f6c089f6c4L,0x1ff5a23bdf3143fL,0x13c62ec51e61428L,
  45427. 0x1a081f9fbf62337L,0x1f9925c292fda80L,0x01096b2f2bf1e2dL },
  45428. { 0x1adb386ca15cf08L,0x1256240f0b97591L,0x1e4d350b430137eL,
  45429. 0x06e8809b8f3a3b7L,0x0932bfcdd9cf607L,0x14154c30284220fL,
  45430. 0x073026ba4432871L,0x0612a51f8308358L,0x0e6a120aedbbed6L,
  45431. 0x07070f618667928L,0x12e953962efcbe5L,0x169f3f54882bfd0L,
  45432. 0x07ecee7ce5c66d0L,0x17d3439d062c78fL,0x07c4d21e8750fadL,
  45433. 0x0f56f2d8d8b4073L,0x047e6ef9aaae672L,0x03357d2aa4d2e12L } },
  45434. /* 204 */
  45435. { { 0x05aaba8c980e91dL,0x07a84b564c77d6dL,0x182a368c998aa4fL,
  45436. 0x0001028a7d61321L,0x1d71de8401d2153L,0x0cd00915d8699f1L,
  45437. 0x0e39d197db600f8L,0x118b205fe98f150L,0x174e2afb7193134L,
  45438. 0x04993abce7d82bdL,0x1a9908eb40fe3e9L,0x048ab1ff4814ec3L,
  45439. 0x1977a87e30b7d4cL,0x04e426935af4e06L,0x0658e834717b6ebL,
  45440. 0x17e1bd95107347aL,0x1dfbc6f2f35ebf6L,0x000f7831886ac55L },
  45441. { 0x1f903163ecdcbb0L,0x16b9413e0e4aa95L,0x00c255d724c0678L,
  45442. 0x132d3072613ca4eL,0x1cd082df0dc1c5aL,0x0bf028f7cfc07fbL,
  45443. 0x06d57364541d77eL,0x189e50dfffd398cL,0x1352db38f80f24cL,
  45444. 0x0cdccf61b291d71L,0x0a32a042c412a7bL,0x1fce60a4075a213L,
  45445. 0x0e769400f5c2700L,0x170622961517712L,0x1c0a90756574e67L,
  45446. 0x0616e156ebad5efL,0x002341080990db7L,0x00727affeaf4689L } },
  45447. /* 205 */
  45448. { { 0x11c64440ff14c38L,0x1acfd576708f95eL,0x169c8abd8cc2696L,
  45449. 0x15055e49dd548c0L,0x0b9a1159ddc9f65L,0x142757fa7725ff7L,
  45450. 0x0ab38918f41d9d3L,0x1971197c3c01c17L,0x17ca568ead5fabdL,
  45451. 0x0c06a9262bf5cceL,0x195cb3a6fa61cefL,0x1b9ae60170bd388L,
  45452. 0x1240f54176918a1L,0x1ad8a11b2491098L,0x0d3c5abdf8c93feL,
  45453. 0x1b2f881bb4a0248L,0x02008833421a133L,0x019ea08b0843b78L },
  45454. { 0x131a36b9878e5ecL,0x1f190a348c1193aL,0x08cf428c1191778L,
  45455. 0x0f542e6cb3a2bf3L,0x1925d4fe734c1b8L,0x11587a56104a517L,
  45456. 0x172f10f25968709L,0x000eb39207c88faL,0x092af215e052393L,
  45457. 0x1fdb6af8fac9f9aL,0x10ed2f0f376d7ffL,0x05397fbaa810cb2L,
  45458. 0x0b198d76c09d03aL,0x00793dacc7be6d3L,0x0d6333f01e4288bL,
  45459. 0x09fb974aaf50919L,0x0665922052d76c5L,0x0169ef3d523db5aL } },
  45460. /* 206 */
  45461. { { 0x0de746265add3b7L,0x0479ad5f9261555L,0x072b8695f64f962L,
  45462. 0x1c58edef7fa82a9L,0x1e3202b30e22e18L,0x0e878533f944755L,
  45463. 0x0b462de699ae874L,0x1d21c156e925103L,0x17d424086c7adb0L,
  45464. 0x186196294210997L,0x11dfc563e6827a1L,0x06e5d804ab130b0L,
  45465. 0x1ca5098777422a9L,0x0bb3002c5f21462L,0x1fcdf3d16de5591L,
  45466. 0x0c512d8ff8c632aL,0x0a68b7023ddd631L,0x023801ddb2d8e09L },
  45467. { 0x19401c1c91c1c96L,0x0e6fc93d094b86cL,0x185f0f0a441ea97L,
  45468. 0x0f47fc8e2075725L,0x0ee998ee26fce8fL,0x1d20fc58684eaf2L,
  45469. 0x0941abe98881238L,0x0a56380254b44d9L,0x12c6f734c99b572L,
  45470. 0x049ebcfa897bff0L,0x0241bab3b866984L,0x07020ada3d4c5e6L,
  45471. 0x16eff35f216bff8L,0x00d6911230e3ac2L,0x083f7a1b81fa5e3L,
  45472. 0x1d0365994d942d6L,0x0e6ab4d6d2d633fL,0x039effa82583516L } },
  45473. /* 207 */
  45474. { { 0x1615805d8e20fb8L,0x039f2415a99f845L,0x00055aa15329f1aL,
  45475. 0x19966d2422a40beL,0x07f092b787fec6aL,0x02ff260fd1e0766L,
  45476. 0x1c4496cd991fba1L,0x0dfa8f03d0bf163L,0x0c65268398b0f1aL,
  45477. 0x175c6366e5c75c9L,0x1c3ab6397db54b3L,0x1c4791b269b8267L,
  45478. 0x1d428ac45a31883L,0x0ddfe54290a76adL,0x196b84fddf2924bL,
  45479. 0x00bf7be8227fc0fL,0x13563e4a0d272abL,0x03aa2685bb8a47aL },
  45480. { 0x1e8d13480797aceL,0x0b55057c36cbf27L,0x1a23bd69a3f085bL,
  45481. 0x0b3f364d09b7e14L,0x0999d2fc18b26f4L,0x011caaa97f7e7d4L,
  45482. 0x0de0356be360989L,0x15f1e2468d3ec74L,0x12933454fdcd4feL,
  45483. 0x1400c5bd39dae84L,0x07c9db9554b062eL,0x0e7bfe4d763935eL,
  45484. 0x1006dd4f44c5d47L,0x0f9cdd24cf7a4a0L,0x1b293cab63c4be5L,
  45485. 0x1eb34aecfedb9ecL,0x149ba8773f17922L,0x0110040f560f216L } },
  45486. /* 208 */
  45487. { { 0x043d573ba37a0baL,0x018de6e8bb6fb18L,0x13f31081c3dc169L,
  45488. 0x1ccf85a21206645L,0x0bf8bcfa5cabd30L,0x03d8859b164aef6L,
  45489. 0x179935d9f49dddeL,0x01cc25922bcdd80L,0x19e669631ce69c3L,
  45490. 0x1e4eec7b417131aL,0x087c4a57ff30e09L,0x1cf31455b944f20L,
  45491. 0x044b5d500a06a8eL,0x06c06b62c70073cL,0x17c43321dd1bf1eL,
  45492. 0x0dfb048c0a77d22L,0x133844e328b219fL,0x03102a0d608de9bL },
  45493. { 0x17fd382509e5a29L,0x06be85a19298f07L,0x0d5334e20ee61d2L,
  45494. 0x0917f762f51ee92L,0x05f2d2c5c6b8ac7L,0x058dc1d230b5330L,
  45495. 0x0996acf6598946fL,0x0b19eea62085fdcL,0x0c70d73fbdb2250L,
  45496. 0x108ea1a78616aabL,0x01876152c966cc4L,0x00db88567efb0c4L,
  45497. 0x05e86a4949ffe46L,0x0b0776d6262e42cL,0x03890801377322cL,
  45498. 0x02cac30099cceadL,0x09791f3855a4214L,0x03f9bc0cc7c995fL } },
  45499. /* 209 */
  45500. { { 0x0374bdadfa6639aL,0x0a46a0155b9c8cdL,0x08d91c0c78b432fL,
  45501. 0x19a0b33a3eb8bdeL,0x00d38443b49ee2bL,0x09c9746942f5b07L,
  45502. 0x14e3f6efaa4bc9aL,0x0d1228abf7f7178L,0x0ae259ff1e469b7L,
  45503. 0x0e7658fa0ef2b41L,0x1bc1c6654b46bb0L,0x0303cf7ee88d90eL,
  45504. 0x06282ad2f11ce25L,0x15d277b3e5c9d6cL,0x01ea8fa3e8f34c5L,
  45505. 0x16c11f9cd1409caL,0x0d0ced74170a61bL,0x036f38b59fb5608L },
  45506. { 0x0e58d04172d6dc5L,0x166f331cbe32e6aL,0x1860327ad3a2fb4L,
  45507. 0x10ebf45db6f5cefL,0x091e67385627546L,0x0e4597259819275L,
  45508. 0x0a21d808ea1588dL,0x16b3bedad8551f2L,0x0ec2c185ff6f5e8L,
  45509. 0x04970959d6aba45L,0x0ed3cb552bbef1eL,0x0891dd0d1042f5dL,
  45510. 0x11b1d9bd5b14915L,0x17f806fbd1362fbL,0x16c77bb97334598L,
  45511. 0x1eee9d7933e2f72L,0x1b0909836163fe1L,0x028fc84185d9e92L } },
  45512. /* 210 */
  45513. { { 0x1376fa1f2922461L,0x0d8e18b286868a4L,0x10cc376182376ecL,
  45514. 0x166d71320d25723L,0x1f5600523e612c4L,0x1512a2f0cbbd85eL,
  45515. 0x0f63be2bffdc18dL,0x1759b4fa4f022e4L,0x00b0bc4bb81bde7L,
  45516. 0x058405976952bc7L,0x0834345c6cb808fL,0x119f2837735cb7bL,
  45517. 0x1bc14a65c5f6df3L,0x00ceecc742eec0eL,0x081be4dfe6320b7L,
  45518. 0x17cf18c26e8fea4L,0x1e79e13a2c25f5bL,0x02f7690c70551a5L },
  45519. { 0x156575401d4dc0bL,0x12f93fab35d83f0L,0x0faee088975686bL,
  45520. 0x182313d8d7d30bdL,0x0cce4d9d5f3ad21L,0x1b2dac8bed28c67L,
  45521. 0x1dc732128b4fb5aL,0x0f4ff3102eb1ff4L,0x150d6ae122ac69aL,
  45522. 0x1bf9858e3734236L,0x08e9816f42ec4f2L,0x1d9bae7e480f180L,
  45523. 0x0ce5f0a9969a10fL,0x1ec7ac034628ac6L,0x1691b8749afd856L,
  45524. 0x1a6115e65d50f22L,0x054eaf74e810287L,0x0460a5d03531321L } },
  45525. /* 211 */
  45526. { { 0x0877895b17ee201L,0x15238c472bd3b86L,0x1d8e5e08915b016L,
  45527. 0x019387743a3387cL,0x14389ebe0be6f8cL,0x13fddb7f42fa7fdL,
  45528. 0x1b1914e2f333833L,0x0850edd5654ca4cL,0x15c9ac690cf9a38L,
  45529. 0x1ae79d8e6647cc0L,0x1ef9aa73da1f7a7L,0x01f90706b82bf42L,
  45530. 0x1b150ef2ebfcfc1L,0x04252973043587eL,0x1347ae27e5fb366L,
  45531. 0x0077482dcdf4561L,0x05ee2bd15993eccL,0x0322e052ef55d8bL },
  45532. { 0x14c420550aa7e31L,0x06f8617c28ed2ecL,0x0424f1c9b9aabb2L,
  45533. 0x0c4c337f3532c8dL,0x0253fbd572dbdc3L,0x184f030da130707L,
  45534. 0x1b16e5f0967ee31L,0x1d3f57ef9779bb5L,0x1b4d5e8b1e4b703L,
  45535. 0x18372b7039a77eeL,0x1293e47d57e2946L,0x11747eacb91a05aL,
  45536. 0x12816d1d947f860L,0x0e73d89b4117a3eL,0x1410908330d8559L,
  45537. 0x0cfedc8ddcbde63L,0x091b2a65f706835L,0x013f4ffa0697d36L } },
  45538. /* 212 */
  45539. { { 0x1251893d7e952e7L,0x182c1e39adf8c3aL,0x064a5bf8124456cL,
  45540. 0x1100da5f94e656bL,0x1b885ed92745185L,0x0faaf638d5bb500L,
  45541. 0x0ea72f73a765db6L,0x0567b4c164091e5L,0x16977c086592b13L,
  45542. 0x16e54e584c828ebL,0x0aac8f4622b896dL,0x1e7fc4155e7bb38L,
  45543. 0x0f5aad74d09f469L,0x1154f59dede8fbeL,0x1c04310f57bf970L,
  45544. 0x004c118bdbf4426L,0x176ada2217b5787L,0x027f772b39ed64bL },
  45545. { 0x0e18d52b5d3d780L,0x0dae9838b33a218L,0x01b969d0855936bL,
  45546. 0x1d1ad7770c641a7L,0x0d263dd15d8c290L,0x0c231b4c0d21919L,
  45547. 0x0b2c4cf439f2a62L,0x1fea270f09b4a33L,0x0832e3fabdddc81L,
  45548. 0x013c2ca18ccd21dL,0x12af3cc9d0c58ffL,0x017ae9f29f4eb69L,
  45549. 0x1d5694a6279fa01L,0x05b2bd1261453a1L,0x1a897ab074aa223L,
  45550. 0x0c3fefdde4a07d0L,0x00eed11a5d304c5L,0x027f40c73ce4f6fL } },
  45551. /* 213 */
  45552. { { 0x0252c9d7fc1c7ffL,0x0a0cecfd44d6880L,0x09290193a732a6fL,
  45553. 0x1087285d9992742L,0x0749695b384cbcbL,0x08b2df802610fecL,
  45554. 0x04409a720767d08L,0x09bc464ac51bbc0L,0x1ec9374575a9b00L,
  45555. 0x199a35ffb6e7e10L,0x16992d34dcb1f7eL,0x15a7e40929c5589L,
  45556. 0x15e867c150cecb7L,0x015b91ec2b1620dL,0x194c8c4a64e573bL,
  45557. 0x0cb2f9235bf8afdL,0x1fce06f1161f10bL,0x040c8aa94dba69fL },
  45558. { 0x0c124316ed9d4eeL,0x1d0aa344d7f80c7L,0x127caa268fd0f7fL,
  45559. 0x05a8cfdf6495746L,0x039102e22db1e8eL,0x1784158c6f51aa0L,
  45560. 0x1751d08aae14f94L,0x1dce2614583da6dL,0x1ca60e86d0295d1L,
  45561. 0x15634043e3fad69L,0x0f3b3f7a1919639L,0x18428c3a24ca1f0L,
  45562. 0x10bd38509972e66L,0x13319144ff77a0aL,0x0b71e543c60fceaL,
  45563. 0x0ee044ea8a97cf2L,0x0f32744c11b1136L,0x03e835e63f47537L } },
  45564. /* 214 */
  45565. { { 0x12859427090212fL,0x1bea62a90f42244L,0x108af8b6ee49a46L,
  45566. 0x1b7b03f10098070L,0x0c89bc36317721eL,0x078026e09b65f75L,
  45567. 0x02ae13dc6d82deeL,0x09a4d2265a09c43L,0x1b0e2496ee6cc81L,
  45568. 0x196718bbafd6e0aL,0x0f02119b488f142L,0x154c98c25f1705cL,
  45569. 0x0ba4b653559721cL,0x03e9ece8acd3a8fL,0x0350918d0ceab57L,
  45570. 0x079543cc373a5d0L,0x192149f655ffc67L,0x0245a95cce87ce5L },
  45571. { 0x1915399efdc05beL,0x06d8c09f04af4d1L,0x0ba7376cff6b79cL,
  45572. 0x04340128a288f0cL,0x03920ea3a2b0316L,0x1dc7f5a593cc061L,
  45573. 0x05b52b14e53c688L,0x1342c7ee4ac7cacL,0x0aa0ff93fb71421L,
  45574. 0x137cb6949eb123aL,0x04baa1f73f89db4L,0x1e5e8e071a2bba4L,
  45575. 0x05f418168eab27bL,0x19954c4d72c6419L,0x127c4ef8dc1088aL,
  45576. 0x1095b46d287217fL,0x0ecf16e26060d06L,0x00be06f43cec63bL } },
  45577. /* 215 */
  45578. { { 0x0a5f453dcc01958L,0x02caa0e7441c9deL,0x0285587d6db5f65L,
  45579. 0x0cfc5a6d78bcc6aL,0x05ac3a6c291c3c8L,0x000366fb63f6c25L,
  45580. 0x1b0ede44f102f66L,0x153ef17610eace3L,0x11c928f6eb43e89L,
  45581. 0x0f946f9d70f50f6L,0x0e96c6e492cad7fL,0x0e0a3422dc0ac57L,
  45582. 0x17167ed3e3491d2L,0x0de058230476015L,0x175fd678a473dedL,
  45583. 0x1336e61ca02d318L,0x1d70c7c350df5c7L,0x034315cf1056370L },
  45584. { 0x0c6f4e79ffa1f64L,0x1548d50f121a4abL,0x183336dd48cbfb5L,
  45585. 0x0e0645ac0fd341dL,0x062fef87bfc90b3L,0x1fe79a14a405692L,
  45586. 0x18e3ff08525a70aL,0x138dca423c14a73L,0x02a59ec2612a514L,
  45587. 0x0aff1096b835a99L,0x1ec423a67210a46L,0x1d46bb900905eefL,
  45588. 0x0bbd92d29874ceaL,0x15750af752d3018L,0x01c4272b50b7296L,
  45589. 0x1ec93ad58778e93L,0x06cc64e1c40290aL,0x02849fd16a8fc6fL } },
  45590. /* 216 */
  45591. { { 0x0cf32804c2d553bL,0x15f111dcb3614e2L,0x12708a5a452b706L,
  45592. 0x0b3332ed92aad4aL,0x176e83f3d8c9f8bL,0x02f62be1162bdebL,
  45593. 0x187d53ca50aadf2L,0x091de680fcadc58L,0x1f005e8caf213dbL,
  45594. 0x186429ef9934c63L,0x12235f2b02952d1L,0x17dac16ea03dcdeL,
  45595. 0x06714a4bd9b6bd6L,0x1704c44a7808188L,0x1e4a8014a16f0edL,
  45596. 0x1e495d80ce835ebL,0x03832f16426ef7eL,0x0097ce226b63bd2L },
  45597. { 0x151e96483313a1cL,0x0e9ed19e2c59b8cL,0x1d4b1eb1011263bL,
  45598. 0x0e1b96bdd09db77L,0x0dd422f8866ca6fL,0x10f6177605747abL,
  45599. 0x148f041def15019L,0x07cda732275a844L,0x1d105e1e858e7cbL,
  45600. 0x1e49cbfe4bcdda2L,0x0752a4265ed6491L,0x1147d12a5fce644L,
  45601. 0x074e9462410ef62L,0x0cbc07a06846ac1L,0x18443b1932fb43dL,
  45602. 0x1634627af844e11L,0x118d186d8667679L,0x0017baf2713570eL } },
  45603. /* 217 */
  45604. { { 0x1637ebf47f307d7L,0x02535680a0a3b8dL,0x1594b816a031ad9L,
  45605. 0x07fda0f66305467L,0x1696e597c8f1a0fL,0x1fe00f604f73fc9L,
  45606. 0x1cee736a9fb0f1fL,0x112a93f11fdf1e6L,0x1c88d1961c3bb89L,
  45607. 0x09527f4efe553dbL,0x1e7b88eb92ac836L,0x0c83ebd9634a25fL,
  45608. 0x1fe32fb47df5aeaL,0x12e842e073b491bL,0x11d568a5a971080L,
  45609. 0x12e47b9224ab04dL,0x141580b985f9bceL,0x03958dab331cb0cL },
  45610. { 0x1708a08790e5558L,0x1b0208344d7c04eL,0x0e2908c4ed7e614L,
  45611. 0x04ab493a35d0bcfL,0x0c371b0be6ba129L,0x07370caf3b62585L,
  45612. 0x0688561413ce64eL,0x19d1ba82844c15dL,0x1d8b04e9b968485L,
  45613. 0x0a625d2c43f7f21L,0x1a399fc47179cfeL,0x1c519ed73388224L,
  45614. 0x087a0a966292623L,0x06501769f968555L,0x18ed546c999dca9L,
  45615. 0x16b6ad1dd1c9c5aL,0x1adcdebb2992e78L,0x02ef8c90b70b912L } },
  45616. /* 218 */
  45617. { { 0x0027e1e8df2e7e3L,0x1e6346c6d03ef10L,0x09a52d2b9a52c60L,
  45618. 0x1e794c5d119c6b7L,0x12efed2c896d97dL,0x1e84279ef2389daL,
  45619. 0x048ef401b10389aL,0x1603d36e377f903L,0x09991c7b61aacc6L,
  45620. 0x08649b247b2b420L,0x1587461fd1d4919L,0x16237ffa7944270L,
  45621. 0x0ffa191418610f2L,0x0aaf2984cb48afdL,0x01cb5e63c48db7aL,
  45622. 0x14916c2797dd543L,0x0327f7b44ea66a2L,0x0229132e170544eL },
  45623. { 0x0d5ec7925430010L,0x1c37ff5e8486025L,0x13fc82a74fd72b1L,
  45624. 0x0547db8cbf4bf3eL,0x0cf3eb11fcbf411L,0x12db80441241ce0L,
  45625. 0x02ae2e375b53a2aL,0x01dc44e3bfb6eadL,0x0e43ec373b74456L,
  45626. 0x0757c930e7ba94bL,0x06b838fea5b66deL,0x1a5bb84bbfaa301L,
  45627. 0x146bab77110b312L,0x1af678f235c7bc5L,0x07fb2a81a7bf236L,
  45628. 0x17bc3832a575cc1L,0x15543e302ed5f4dL,0x00a5815fc8f03c2L } },
  45629. /* 219 */
  45630. { { 0x071c768b87e5b57L,0x03c7bfa98d2ab96L,0x1e2fdd65f7202f3L,
  45631. 0x1a273c2ebe9ff27L,0x0b94ca6cb28e026L,0x1cfbfe35c1db93eL,
  45632. 0x145c0babf8ec801L,0x0d85594a9bd9e77L,0x017c4133c6af0dcL,
  45633. 0x150f332e67af1afL,0x046920d154171afL,0x17a1cc2017134cdL,
  45634. 0x06c17d03882633aL,0x0d067c864b36338L,0x0b75931ebbffef8L,
  45635. 0x1548c9b08f7cfa1L,0x0a5d49bcdfbaea2L,0x042f03f3a1663e8L },
  45636. { 0x1aae0a60bc25bcaL,0x12af8f227b27611L,0x1b62d81eddcdba3L,
  45637. 0x0da600b213c3cd2L,0x0cbc4990aa90a74L,0x0717ae83958e669L,
  45638. 0x03b24343f9b1b1aL,0x183241d8be0a7c5L,0x179b21fb4f0040cL,
  45639. 0x19bade9fe625163L,0x177be786eb1f769L,0x1af26b81f1a7ebeL,
  45640. 0x102cacd318dc315L,0x14937b8e388be0bL,0x00bce69bca08f13L,
  45641. 0x1264671b6b177daL,0x030e5b492317db6L,0x004b201cfc6a4faL } },
  45642. /* 220 */
  45643. { { 0x1774f1656999ebaL,0x17143d8ef318290L,0x1c9b782c99a4f63L,
  45644. 0x127f128543b035eL,0x0a03e13c3744693L,0x1139e7de7b5b0afL,
  45645. 0x1715b4c3030d653L,0x1449fa674ad8ce4L,0x1a57534ada8be97L,
  45646. 0x0c921533e115128L,0x06f6d674317125eL,0x0d998d484ed09caL,
  45647. 0x0cd426bf59d7cd7L,0x1374df5948a04bdL,0x05b8fa5650128b1L,
  45648. 0x0cda08e71fd30b9L,0x056bcbb3e0eaad6L,0x0313587e931de2fL },
  45649. { 0x1217dbae1a1ec42L,0x173edd5ad662823L,0x0c7a194cc746a9aL,
  45650. 0x007a6024df6fc35L,0x1ee61851b845307L,0x144aa2140324f06L,
  45651. 0x1d8ca201bd28fa9L,0x09e977c875b96adL,0x0036b9bdabcaff9L,
  45652. 0x0ca0f32de831bdfL,0x1e7511a1bceaec3L,0x025955ad5fad042L,
  45653. 0x1eff7e153414869L,0x15c37ecb4d1dc48L,0x1e4a30e23109b3bL,
  45654. 0x13c016adcd50222L,0x0c1933e71359639L,0x004ddeeecd0bdb5L } },
  45655. /* 221 */
  45656. { { 0x1e39c1de4fd3673L,0x06ce8d32e4703baL,0x0771ca271ffbe20L,
  45657. 0x1c6a53a4008e4b8L,0x1c747af35b6735eL,0x177efae0fc79769L,
  45658. 0x070e573ce663e44L,0x0bbdae44c30930bL,0x123793a2f0e6979L,
  45659. 0x1355c6b4358e953L,0x0057788aa20b922L,0x0df9f3b71afc019L,
  45660. 0x1202267547be77dL,0x04e0876e04437d9L,0x00fb532d89a1f51L,
  45661. 0x0cdd53e387c2ef9L,0x124e6d5d7f05af3L,0x0175500dc68f7d6L },
  45662. { 0x047fb701f357c74L,0x02e2554f1dbca2fL,0x1ccdba16a4164c2L,
  45663. 0x1f7c0489929e130L,0x03b5660df53808fL,0x1caf6b48eeefc9dL,
  45664. 0x083522dd8ddefceL,0x1e72372236f7672L,0x07ccf08bf86a13cL,
  45665. 0x1f6c7cbf500c72cL,0x090d0de31546514L,0x1bd3c1a5ab4d63dL,
  45666. 0x0f9b96259a8e6adL,0x1778beeefe15924L,0x1fe72165baf3abbL,
  45667. 0x17751ed296886aaL,0x06b48cd150f07d5L,0x001698ef4da60ccL } },
  45668. /* 222 */
  45669. { { 0x0bb9e1ede79499dL,0x147fc7e87e156d3L,0x03a069f64d5bdb2L,
  45670. 0x1fd1e0c64f7d81fL,0x1b300bebbc3d1c9L,0x1e0c0dc02e390b9L,
  45671. 0x074040108282104L,0x1ad3d342cfde195L,0x0076c909d1aeeddL,
  45672. 0x050ccbfc71d4539L,0x1fde9e9ded0a799L,0x17e8b929a7d279cL,
  45673. 0x07e6d48407aac0fL,0x148c90f3f9bb4a5L,0x076ef5bd599e78aL,
  45674. 0x1f533e47fc1e7dcL,0x165c7917566cbf9L,0x04b2c3079707a6bL },
  45675. { 0x134702b7fa5f79cL,0x1ea132d796936f3L,0x0e61b1cf833a4c2L,
  45676. 0x1a9dc8945a8b7b1L,0x156c8a1a7dbe7beL,0x06fc076094f0124L,
  45677. 0x0966dbf7016b1dfL,0x15ee14d7456b139L,0x0fc484021999825L,
  45678. 0x09425aa3d11f85bL,0x084290a282a2bc7L,0x16625655edb163bL,
  45679. 0x1a33935ee3b1eb1L,0x077fd3767828a21L,0x1899531e81fac9aL,
  45680. 0x1dc982ddc810dacL,0x0527a7bc5014549L,0x0328408190fd4c5L } },
  45681. /* 223 */
  45682. { { 0x1f0e460b67ed9b2L,0x107e861b6c9e924L,0x0fa6231d7870336L,
  45683. 0x06c297819376b2cL,0x1a768605757bbe9L,0x16e2a24d4dc400cL,
  45684. 0x16616a2df8abd23L,0x0993cefdb3d6a34L,0x0dd025274ebbf02L,
  45685. 0x0c5b1440aa2e31bL,0x16bb4120036e816L,0x027303c54474737L,
  45686. 0x1c550cb4f27fc20L,0x1a903463ee337eaL,0x1a7e856b49c0cbeL,
  45687. 0x151459341795d02L,0x12f60606f213a7cL,0x04c14a8234c3132L },
  45688. { 0x03746002e11c128L,0x1d72e8736e53f1fL,0x1b8b65548992037L,
  45689. 0x051016e287c8802L,0x126b881cf65f88fL,0x1c357f651e946a2L,
  45690. 0x1e563e71677477eL,0x09ea910c18498e9L,0x0d06ea43c9cb69fL,
  45691. 0x1a1e4d7399a7676L,0x0b3358d4ca5c4d4L,0x0806be74d818b98L,
  45692. 0x0cb372653ba95ffL,0x1128291e9700d0eL,0x089fac8c5443f7eL,
  45693. 0x19a21ddca71c54cL,0x14beadfc8a0ca23L,0x025bf370d9f3c7aL } },
  45694. /* 224 */
  45695. { { 0x1c9076fdb5f928bL,0x085db5b9a3e763cL,0x1e62b003b107989L,
  45696. 0x153b2c338ea96ceL,0x19e4343f900d20bL,0x0c9aebf6a160682L,
  45697. 0x00738f7ce7a1514L,0x1584c722304c9eeL,0x0ce8f2554e1f87aL,
  45698. 0x0eeb3c4b2fc8d55L,0x1458fe8c914e7ffL,0x1e589759d32b2d9L,
  45699. 0x0aa94f9ea55c815L,0x1792722aebc6461L,0x17709a9eacabfd3L,
  45700. 0x05045e1dac81239L,0x058954a420b00caL,0x00308e262e994bbL },
  45701. { 0x192001ca9e81829L,0x199900451416678L,0x17863e77b66f7b4L,
  45702. 0x1b6f11200617fafL,0x1577a5dd6793ac0L,0x169e15dd806c8e9L,
  45703. 0x0405385e88e9e00L,0x00fff2bf119f6a9L,0x17cd1bf4bc71b6eL,
  45704. 0x11d925011ac4645L,0x0cd6e2904481d8bL,0x00bd880ada6136aL,
  45705. 0x0ce916a1b52481cL,0x0280bcfa2ae3a08L,0x1344822ef80c9c6L,
  45706. 0x1fca02bcd82ef67L,0x166509a24c090cbL,0x04103ca948e0842L } },
  45707. /* 225 */
  45708. { { 0x12d3cff1c7d353eL,0x1f666bef0671daeL,0x1d7db2a1d8d7579L,
  45709. 0x004bf35a7d69620L,0x005cb5aeda8404eL,0x1910d0b5cb1f449L,
  45710. 0x0b292797b836027L,0x069ac990bb3d483L,0x06a46c4e934442aL,
  45711. 0x037fcbf1e7b2ad2L,0x19707b9505f5f2bL,0x1353dd7f3898ecaL,
  45712. 0x1988da638868100L,0x1b5a39634adb0e9L,0x1fc45c5900ad1abL,
  45713. 0x00bc63fbca2ca16L,0x0a794f8f273be0cL,0x03a43d81b5441a2L },
  45714. { 0x060e5759c3e2370L,0x0c0c9fc02438cd4L,0x1cf29b8be6a8675L,
  45715. 0x12c288e336741b7L,0x1effec21b6c7e95L,0x08675fd4824e3a6L,
  45716. 0x178562e8192c8fdL,0x1e5625045809343L,0x0b654b7d9b1d527L,
  45717. 0x03842ce87fe8218L,0x1d299d3c1511af1L,0x0a37475bb32a6f8L,
  45718. 0x0be33533b5e5532L,0x13f20ce7251f6b6L,0x146e5e4bcbd1340L,
  45719. 0x14d3e5b09dd054bL,0x1ddcc76b123db6fL,0x041a7c2e290fd1dL } },
  45720. /* 226 */
  45721. { { 0x09347c12ce9b31aL,0x029157f1fd9db99L,0x0d354bfe43f4762L,
  45722. 0x0c5634103a979dfL,0x0a411f0853b1738L,0x0db01d29c608dd1L,
  45723. 0x15d05e256e4f050L,0x10c532773556217L,0x1ccbbd046099129L,
  45724. 0x14fd7d8775055d2L,0x111888d598625d9L,0x11386cfff4a9a90L,
  45725. 0x1d1c3478da4a63bL,0x15301a7be5d6ae8L,0x06c4e4714ce489eL,
  45726. 0x1ea2a1cdae0bfccL,0x14cdd14b660f74fL,0x031cec58529995aL },
  45727. { 0x0423162162217cdL,0x12515408e14737dL,0x186085d9b700b83L,
  45728. 0x1208d40dded1b39L,0x1de921015126373L,0x014c69a2775118eL,
  45729. 0x15fa4181f23c845L,0x1c24fe4e574c7b2L,0x1e7ce80cca5e8caL,
  45730. 0x00b75f1127bd31fL,0x13969e259cf8d16L,0x1444a6d757a89bdL,
  45731. 0x0ee3bf77af13756L,0x15e7cc5e3226b0dL,0x1ea58b182cafdb8L,
  45732. 0x000467616b3e653L,0x02cb0769a1aabb5L,0x02048189b063aa0L } },
  45733. /* 227 */
  45734. { { 0x0d2873a1670433fL,0x0a6fb12a49efe42L,0x066a03f3e27b24eL,
  45735. 0x01b652ec2dd60b4L,0x19e63046e39e431L,0x14e54f283a16e4eL,
  45736. 0x07437cc6b632077L,0x1a30d557f29f6f6L,0x036cda27a1b3c82L,
  45737. 0x18d177a1cb816c2L,0x0ff77118204a67eL,0x091ba472c470501L,
  45738. 0x137b3c9353e4b2bL,0x097dc53496d9617L,0x06011d356d6cc5cL,
  45739. 0x04af1f370f47610L,0x1c8d85909861e95L,0x040334776f9bd15L },
  45740. { 0x0edcd35b39a0249L,0x1866a597c575771L,0x1791c88f7c16bc8L,
  45741. 0x15c1d26fe852b62L,0x0cbc9162bb66982L,0x04ee5080ce95b94L,
  45742. 0x01ed17144aba73dL,0x1d22369234ec61eL,0x148d4f34ca03874L,
  45743. 0x0fe87532265ba19L,0x1e6b87e56cc30f0L,0x1a9bdb16c15827eL,
  45744. 0x1f61ead81c40362L,0x04c61e944f418a7L,0x1485c0bb5803751L,
  45745. 0x03e66bf96383384L,0x0e9592329fc3a9cL,0x00233baa40def36L } },
  45746. /* 228 */
  45747. { { 0x03de56e39233c96L,0x0204e4039bf57f7L,0x06f4806af1a21a3L,
  45748. 0x165690c40b595c2L,0x0f19056c0f2cea9L,0x0e1520f191c3f0bL,
  45749. 0x0fa1ba9d4d96a97L,0x09aed8535982569L,0x0a01fcab78d6329L,
  45750. 0x0edf4458655cf92L,0x11b96fd05301520L,0x1127972d6f54eccL,
  45751. 0x117664e097fe111L,0x09fe7ad4db24fadL,0x1ffd8d2865908b9L,
  45752. 0x1312ab2f1937a16L,0x056b5feb38e3c22L,0x001c524fd8419e2L },
  45753. { 0x1e3818c13e93257L,0x15e4ed3093a0d9aL,0x0925f2ab01ac533L,
  45754. 0x067b54222c9edd2L,0x0de2034a82278e3L,0x0dd31873e62b2f2L,
  45755. 0x1bef6edf7257c28L,0x1ad03bb3e46cd2aL,0x1c63e6319bb132dL,
  45756. 0x11158117e12099bL,0x12064dfa2fac71bL,0x129bb1927158470L,
  45757. 0x0aa6bb564483b19L,0x037c8c03daa67d6L,0x1e367cc69f35138L,
  45758. 0x151cc3ba8737751L,0x060660c2a787f74L,0x025dbb711090dabL } },
  45759. /* 229 */
  45760. { { 0x0151e8ae6354817L,0x04a75781c5a1c3dL,0x1a2216562618cf5L,
  45761. 0x0e3b975824990d8L,0x00edad067215382L,0x0072eb7a43d7c66L,
  45762. 0x1fd56b4cc147f94L,0x1aa14e23637adc8L,0x0a68709a78c746aL,
  45763. 0x1f8b931320179afL,0x023bebecc304c09L,0x008380d8e92f8daL,
  45764. 0x0edcc3e2da9ef1cL,0x04970839e863a76L,0x084add0c317e5b8L,
  45765. 0x1d6041e27279e55L,0x18b245840162107L,0x04421e92fbdbb7cL },
  45766. { 0x01501dcedb2a83eL,0x147d815dc6b9227L,0x196764977d8af3fL,
  45767. 0x1e8556df8612040L,0x00f09dfd3c715dcL,0x0c857539e0282adL,
  45768. 0x1d278499d17638dL,0x0c6a705e9b0edfeL,0x0fc69feefa920c6L,
  45769. 0x10b0108cfeb88e5L,0x070ef641d713577L,0x17a27bdad7e4843L,
  45770. 0x0b6263a1163800cL,0x1e93261bc63f507L,0x1672630d6f5e561L,
  45771. 0x0e76aadc45c8ae2L,0x14971bf2a2dfa73L,0x00281fc9cc49ae4L } },
  45772. /* 230 */
  45773. { { 0x1addc6671dad4f6L,0x124448125f50db2L,0x038bd8174f748e3L,
  45774. 0x1d61b2d713f6ed9L,0x0601b2cb13d5f5dL,0x11e92a705add1abL,
  45775. 0x03a9f8df524760fL,0x175d10c08464819L,0x1374182f3e91c99L,
  45776. 0x161657cd43d6c8cL,0x0c102bd5d3ca549L,0x1da328800146962L,
  45777. 0x1e06df42e75b9bcL,0x05e8844ea6662bdL,0x16ed4008ba3b141L,
  45778. 0x1d5b618a62ef5bbL,0x0f9690d31d29ecfL,0x039abbc7f0bb334L },
  45779. { 0x186ee3e843c1137L,0x0217d1f85b9e687L,0x1e762ac838e8f07L,
  45780. 0x082c485f5c1ceacL,0x19b092e46f95f1fL,0x11b5603dc4708e1L,
  45781. 0x00b9858a500f930L,0x064cc20be825b58L,0x174dc28a7862e06L,
  45782. 0x08c7fd979d91e46L,0x0905f01d17fefc8L,0x1408980ae23c230L,
  45783. 0x14cefbe4de49b55L,0x0bdfb88396332dbL,0x13c19d873130076L,
  45784. 0x1a1f165940db58aL,0x0a1fc599daa7450L,0x029731bd30d18c1L } },
  45785. /* 231 */
  45786. { { 0x01700f16bebc6dbL,0x1a2edfca81ec924L,0x14f17454e46529aL,
  45787. 0x0bcb5a55798e2b9L,0x0b7b466f942a1c0L,0x09c8c59b541219dL,
  45788. 0x19b3ae904efb6e8L,0x194d314ac4921e9L,0x1bb720da6f3f1f3L,
  45789. 0x08b6a0eb1a38d59L,0x14889cc0f4d8248L,0x18008c774d3dc01L,
  45790. 0x0d62845fd17fd4cL,0x0056e4e3d6304f2L,0x1ebef298d80ecb2L,
  45791. 0x129577e2df9348bL,0x09841007f7fc4bcL,0x03e48b5a7d3a58bL },
  45792. { 0x1026f9178bac2d4L,0x1404c1300d43ae0L,0x1db801cf590228bL,
  45793. 0x09f983f7115a5e4L,0x0a6b291f443610cL,0x16307e2b93dc116L,
  45794. 0x1522c19154cb223L,0x006a3c91133db35L,0x1841b48b5f543f1L,
  45795. 0x16658df6ac8e775L,0x0b7c3e773d6a2e9L,0x0041668fbb69f89L,
  45796. 0x02cb44c5213a7caL,0x0293e062550d666L,0x08f3d41dceda0a0L,
  45797. 0x1924d546e9820e0L,0x07c733d10006b74L,0x00ff9c8b7bbd468L } },
  45798. /* 232 */
  45799. { { 0x0218fe4f997939dL,0x0fdddbc8ac1d9d5L,0x176a1fdd582cf53L,
  45800. 0x02bb525931674f6L,0x06666f4aa9c0280L,0x074eebf0f5a556aL,
  45801. 0x0c1d8bac5e94453L,0x0dde8d4cd49df1eL,0x1900b45c6810e54L,
  45802. 0x1d7912c25d7826eL,0x0721c9721350bfdL,0x044b1c9907bc798L,
  45803. 0x01170d88b23093fL,0x1603b722317d6f2L,0x174506f86584b92L,
  45804. 0x069b5e91ae68c65L,0x0c9c1b1f759925eL,0x00cf68d2b0395c8L },
  45805. { 0x0f7fcde6c735473L,0x04733b001de1f4eL,0x12f3ec666ee2aaeL,
  45806. 0x033599997a2430fL,0x10f65459bb73044L,0x09314110a57f9e5L,
  45807. 0x082e1abb2068dbeL,0x121550596653f3aL,0x182f3f90f5773ccL,
  45808. 0x17b0735fb112bf0L,0x0d12fef51d8b7d2L,0x0253b72e0ea7e31L,
  45809. 0x097c22c18e3948bL,0x0bdf4bd6e374907L,0x0d8dfe4e4f58821L,
  45810. 0x1a3abd1ae70588dL,0x199f6625ccbf1feL,0x03798f07cb4340aL } },
  45811. /* 233 */
  45812. { { 0x05afe5582b8f204L,0x020db69ac5aa562L,0x1efeb357d7b6b01L,
  45813. 0x1627379b26e427cL,0x16dbcbb01914c70L,0x09ae90b8a5a2c0cL,
  45814. 0x07c83a4a5f4d47bL,0x00b1ec8106ed47cL,0x1150a8a9d2f3cd7L,
  45815. 0x19b7400ee6ecfb6L,0x13ad9573d5b60beL,0x00192554b442b4aL,
  45816. 0x023b089f0376105L,0x0215b3746886857L,0x1ba3521246c81e7L,
  45817. 0x0de8a95e35c7a1dL,0x1e6137e4c284155L,0x043af198431ec53L },
  45818. { 0x080fddcaf6c0accL,0x08f335d8f3e046eL,0x0b860a1616b756bL,
  45819. 0x004eb8fb4db8e2fL,0x126b9e15bdc5434L,0x02fd287a5a64296L,
  45820. 0x12cc97c287efda8L,0x03b8df03c8f02f7L,0x02cbd432870ff2eL,
  45821. 0x112480b33e3fbfeL,0x16b2ded6169b122L,0x15a88ccd80afa08L,
  45822. 0x0fe6d7d63d2e972L,0x0713a0a263a6c3eL,0x09612bbdc19f61cL,
  45823. 0x1fbd765942af516L,0x009495c5bfb75f0L,0x02d5d82c0f9c370L } },
  45824. /* 234 */
  45825. { { 0x1e62d2bf0c97f57L,0x02438cb179463c5L,0x119d1ed42aec3f8L,
  45826. 0x0689f413db8a914L,0x0b05a96ef6b26e0L,0x1357417ea26371dL,
  45827. 0x02677b6c00cb1c3L,0x184517a8057afc9L,0x043f2e9639b7c11L,
  45828. 0x161fe0767489b8bL,0x0e2f240bf43e303L,0x0754f9578758ed3L,
  45829. 0x1206924cc99d9cbL,0x0130480a7445444L,0x0b9e782945186a9L,
  45830. 0x07d018fe955172cL,0x0bc4ef0210a8b1bL,0x0382a23400dff72L },
  45831. { 0x0b3d713121901c1L,0x11313ff56aa557dL,0x0a16f022e88fa42L,
  45832. 0x0a6dd844fcc9edaL,0x06c191ab8d99301L,0x04e7164cd0b55c8L,
  45833. 0x0ea021ac73d6fd9L,0x1e0b240ceb2cd7cL,0x018836279ccba2cL,
  45834. 0x00abdc3f7fa9a43L,0x1262592c88ebc8bL,0x09e0155cf4af7f5L,
  45835. 0x0063218a80cd0fdL,0x0fc478a76d6edcaL,0x07b67f4e112ede7L,
  45836. 0x0a06d8367c7a96eL,0x06b6c634a13d620L,0x037ab5767dc3405L } },
  45837. /* 235 */
  45838. { { 0x01dc803d9205c5dL,0x0afbeb3891c94d8L,0x1ff6766d9595a25L,
  45839. 0x1da76359fc7bd77L,0x0094eeffb844395L,0x0c8ff582194590bL,
  45840. 0x141d598c7fea08aL,0x00a1bbccdcc321bL,0x175b03c55e8577cL,
  45841. 0x048e72fc8b91203L,0x0229023aece8fdbL,0x1f140b14272d345L,
  45842. 0x179a6e06761d376L,0x1db8e94479d2ca2L,0x130c30040c0a715L,
  45843. 0x017381087e85168L,0x0add8e6aff8730eL,0x03db5f408a76b22L },
  45844. { 0x0c38e4a3d3aa54eL,0x19ca1ec1ea84d1fL,0x188490e55788408L,
  45845. 0x0fea3a7a89f0954L,0x1eca4e372910471L,0x1d2aef316922163L,
  45846. 0x086d6316948f617L,0x0d18deb99b50a3bL,0x0044bcaa8200014L,
  45847. 0x1a80f34700b8170L,0x064d679a82b3b3dL,0x0d5b581de165e10L,
  45848. 0x08fd964f0133ddaL,0x0985c86c4bd776eL,0x1048bad236b3439L,
  45849. 0x143bc98bf5adf70L,0x0742284ec1ed700L,0x0437cd41aede52aL } },
  45850. /* 236 */
  45851. { { 0x01d9055450cc69fL,0x18a5e64f6fcc787L,0x19dfb9fae80543aL,
  45852. 0x0f331f1ca637729L,0x1b16eef05f7a673L,0x0e2f0aac41c2718L,
  45853. 0x14aaaee4a1c8f61L,0x0e9fca3c68b97b2L,0x0c5d0ee287e2416L,
  45854. 0x0e0a3778800c178L,0x0e7a4b9fd6f8b3fL,0x075f6cad7a7c1eeL,
  45855. 0x1e5168e289501abL,0x1c77082558aa96eL,0x0c111d65037f8c6L,
  45856. 0x1522685246c0788L,0x1869306f114c460L,0x02dfd4fd781da8fL },
  45857. { 0x023f52c107b258eL,0x1415deb31a0ee15L,0x1b6208f3fc6a627L,
  45858. 0x08e336923ea9479L,0x0433dfb8f45b779L,0x09287744c6110c1L,
  45859. 0x1d9543e77647312L,0x08aa185455c9f42L,0x1f7aa1ce42c327fL,
  45860. 0x1d0ad6b2c1d8f20L,0x03569686feb6784L,0x14511c3f7b9b354L,
  45861. 0x16915f7f879b1caL,0x03f40d0f57c941dL,0x0034a5b04393832L,
  45862. 0x0b7b009fb94ac21L,0x0da6acc96161275L,0x00d8933554147f7L } },
  45863. /* 237 */
  45864. { { 0x0bc0a00774ee49cL,0x1b42965b11beba7L,0x12b177e4e28dddbL,
  45865. 0x116df7f77bf80a8L,0x145f2eaec3388ecL,0x16749bc25645e6bL,
  45866. 0x1e84ea7159826c7L,0x0e2cadf6d58fbd1L,0x15f8ded74a532b8L,
  45867. 0x186a145d5444f84L,0x09fca042debb0aaL,0x1c3dfdd96698876L,
  45868. 0x0b9e89c2db26426L,0x1c90884822218dbL,0x1604162ab12f174L,
  45869. 0x1ec1d24dee6d09fL,0x023452fa691471eL,0x019a8bfed90c6bdL },
  45870. { 0x1c33f46593c4a36L,0x0eb8c1b58d4f754L,0x107509defbb2b1aL,
  45871. 0x1cfc9e2f38ab441L,0x146d88a23e8ca24L,0x03817c2b9b99b4eL,
  45872. 0x155d1c73ac731ccL,0x18516309b2e6bddL,0x17f4517a20704ceL,
  45873. 0x1894e8c6b831529L,0x115c6ec75df871fL,0x061306a1b1640f4L,
  45874. 0x1f61fab8ef774acL,0x1aeec00d93d948cL,0x0d1647e9f13304eL,
  45875. 0x12567cfcc4ab628L,0x149349937b85a35L,0x018fd631e9863baL } },
  45876. /* 238 */
  45877. { { 0x0e8cf1b04913fb6L,0x009a80bb4d35997L,0x0dc5e0f987c1f90L,
  45878. 0x13c4fe5ffcf21d7L,0x0daf89bf1e5107fL,0x06f3468925d33ffL,
  45879. 0x0afb86248038796L,0x1552c4e6546dbebL,0x072cc37cfacbeb4L,
  45880. 0x062fd4b749e2d3bL,0x08c5f3798ce4eecL,0x1ccf06165ad8985L,
  45881. 0x041be5b96a97f65L,0x19867336a57e1a8L,0x103613c2fd02981L,
  45882. 0x0d6112d4374f326L,0x1f53ee182540762L,0x000ed9aedbd5865L },
  45883. { 0x00fbc2dac0efee2L,0x175e6eb8edda2b7L,0x18f866da6afa101L,
  45884. 0x026fc03045ce57bL,0x11458b4c49cb7e6L,0x1e2eb1e5dc600e0L,
  45885. 0x19dd9082d211da1L,0x030308fbf428a98L,0x0bede911dd1839dL,
  45886. 0x1cee4e493c6f823L,0x0f58ae2068cdb06L,0x10f327cef5b8529L,
  45887. 0x0543ce3ba77f096L,0x1bb2777e3d64833L,0x111973c521a57f5L,
  45888. 0x19b63c1841e1735L,0x01d636e8d28a6e2L,0x03db5d4c66baa9aL } },
  45889. /* 239 */
  45890. { { 0x11d9e03c1881ab4L,0x12eaad98b464465L,0x151ca08d9338670L,
  45891. 0x01e2c35449505a7L,0x01ebb2c99599439L,0x163d3abc1c5e007L,
  45892. 0x0882a3f577f32f7L,0x0909ba407849feeL,0x15ec173b30efeffL,
  45893. 0x0f8e9598b21459aL,0x0f679415ba04fe6L,0x0575816633e380dL,
  45894. 0x04fd223b1592917L,0x0c6848f6b57071cL,0x151923af404167aL,
  45895. 0x1cf30d662d1c94cL,0x1082211447f3375L,0x023f4080cb8f5a2L },
  45896. { 0x045d45abc8c290dL,0x089aac087d99d38L,0x02491beefcbe8cfL,
  45897. 0x1670b8f9b2575e0L,0x0161985cacff3f1L,0x0443a462d8a8767L,
  45898. 0x173231bb829fcaaL,0x0873b11191cbd11L,0x04dd735f2ccb864L,
  45899. 0x00f09db9e207b79L,0x0897ffcffb5a473L,0x162e4afdcb8ff87L,
  45900. 0x13f32db1354cb43L,0x016ff969d532a7cL,0x1298e5113d63428L,
  45901. 0x0cd2ef1c7e31151L,0x07b39646ccef3e8L,0x03c2d8c81706e74L } },
  45902. /* 240 */
  45903. { { 0x0ce2361a92f9a20L,0x0e543ceb22a077eL,0x0a1474035f16defL,
  45904. 0x185d2f924da8e73L,0x18da6a8b067ac8dL,0x028db495751fff3L,
  45905. 0x05069a0a2fd518fL,0x020ede388f2e2aaL,0x0f4bcbef63977d8L,
  45906. 0x0de24a4aa0de73dL,0x1d019b45c10695dL,0x0b7b0eeabd5fc03L,
  45907. 0x1d59e7ae80d282dL,0x1c1559b7b71083eL,0x14758d2a95b8598L,
  45908. 0x1b088cbdd1ded73L,0x02799a2160ace4eL,0x032abe1b3dbb896L },
  45909. { 0x01b0268d75b6e52L,0x09b2008c68744abL,0x0cc1a8bac6bac20L,
  45910. 0x0cda1211299fea6L,0x15fc1d484e46222L,0x118316dd9a8913dL,
  45911. 0x0b7164d97a81d5eL,0x10e995946f7acdcL,0x1220d7d23b90958L,
  45912. 0x007e9c9c62239dfL,0x1cdc299e1f693e7L,0x1799a0afe9715bfL,
  45913. 0x0c1173f33aef0aeL,0x092d135a102f3a2L,0x0beeff6e347c296L,
  45914. 0x1a509526c9e92e4L,0x0b4c891ae778227L,0x00ae20682507045L } },
  45915. /* 241 */
  45916. { { 0x1af169a2a0e18d1L,0x0e00ba60193e14dL,0x08fdef098b3a65cL,
  45917. 0x1b031fe6f3b0346L,0x0cd3c3302099db8L,0x0d02a9b31fb31eaL,
  45918. 0x091c3bd4c970c04L,0x0e139ae17b9f301L,0x1e64452d11c9ed0L,
  45919. 0x1dfa1fa5633b709L,0x1b029aba170a96bL,0x0aa08e0921892f7L,
  45920. 0x07491e6ba92faaeL,0x157d4c8a055cbd4L,0x1c9955d0157d4deL,
  45921. 0x1ad7ff92b5b766cL,0x037646343b9d119L,0x03c474a504e9a0fL },
  45922. { 0x13a6fe59c53461aL,0x044bf0471db7682L,0x0bcc1da364e5d7bL,
  45923. 0x0d98427a9f51ebaL,0x05b0147c9bd6bffL,0x1dc0b4ac863da08L,
  45924. 0x1e3a4828d8a2df1L,0x11f8cd410dcb79cL,0x13dd4d2824dec1dL,
  45925. 0x08567a260cee674L,0x0b61d7610d69fa2L,0x0f83d4c70364cc6L,
  45926. 0x17f0dcc12859016L,0x037c6a31d912cbcL,0x17be8e646984ad1L,
  45927. 0x0cf108430baf182L,0x093df55ec37119fL,0x048d8ce633c06f5L } },
  45928. /* 242 */
  45929. { { 0x1f2709dcb5d8b80L,0x0b0c17e1ab30775L,0x0644157be5a40eeL,
  45930. 0x1bc8f8868570e7bL,0x154f8867d1ea4b4L,0x06bbf7e625c9226L,
  45931. 0x1d58e4ec68b2bf6L,0x0ac0d1a49cfd183L,0x15f5fabb6499730L,
  45932. 0x192462802a11ba7L,0x178ad4fce3a44e0L,0x11d6f76d017d86dL,
  45933. 0x17d8f313b5ed07eL,0x17e969c94b2409eL,0x1228c69eeda81a6L,
  45934. 0x1864b80db091c10L,0x1af6867fb2fe4f0L,0x01e15d41a0339a1L },
  45935. { 0x162d7759d3ad63bL,0x055cbacf0758fd5L,0x098ce217845cfe7L,
  45936. 0x1dc4165f3ce0665L,0x09eca947f22cafcL,0x146c46da94dd3f2L,
  45937. 0x055849255085988L,0x08901d447d87247L,0x01b8907e7d43706L,
  45938. 0x1bfd22aab1f2722L,0x060a7aca92c3e92L,0x0148900c0f25995L,
  45939. 0x0c246991ced0a72L,0x1a468435c666ed0L,0x02bb84cde88c96cL,
  45940. 0x04a7eacddaa13ecL,0x1d83d30e091147fL,0x00fd313d2e0839dL } },
  45941. /* 243 */
  45942. { { 0x11222a242478fd4L,0x06378b385900050L,0x013e0d671b7ab3dL,
  45943. 0x12f7279b79ee376L,0x030db60b618e282L,0x0d9d94cb70dd719L,
  45944. 0x15777c5ff4ed259L,0x0ff4b0c738d78e0L,0x0c3ea92ed4b817dL,
  45945. 0x0415953691d8452L,0x048a2b705c043a4L,0x1c8c41d13b2f08eL,
  45946. 0x1703ff77c9753b9L,0x15df3072e7bf27cL,0x03805f5b0fe0914L,
  45947. 0x0bdb73c86597970L,0x03e150a5acdc0a4L,0x033dc5e82a3cc3aL },
  45948. { 0x06079b4f4797cf7L,0x04cc5681fef0173L,0x18e9532abbc78c7L,
  45949. 0x1deec92e22b546eL,0x0f29b1a764d9a1fL,0x136549be706e39dL,
  45950. 0x1a9e19986c20fedL,0x0c37e9ae9fc65f6L,0x125f6ef09df00a5L,
  45951. 0x1e21c1fc18e88acL,0x1304314daf78dcaL,0x1f3f10598cb6dabL,
  45952. 0x13451a99b8d4945L,0x15d608d240fa478L,0x029282850058735L,
  45953. 0x150493b29a9dbe3L,0x0df65363165a467L,0x03a14bd54d264d7L } },
  45954. /* 244 */
  45955. { { 0x09758a4e21124baL,0x0c0cc543ffde962L,0x1744f598e2a266fL,
  45956. 0x102bef7eec8bf79L,0x04e6d57e94645ffL,0x130edcafd339b7eL,
  45957. 0x051287ab991d64bL,0x0e8f2aeb81997bfL,0x0a3d1304725b31dL,
  45958. 0x040ef912655ad73L,0x1f4a6468a21fc9eL,0x0b2144d588b31b7L,
  45959. 0x12d8661d4a23d07L,0x0500a07b972c4c2L,0x0cde0a8ded704eeL,
  45960. 0x09d201f28333c7fL,0x112722aa0591bc1L,0x044d55bdd6aadddL },
  45961. { 0x1345a96d656bdc7L,0x0e457f0bb669dc5L,0x02d8cb59310d0efL,
  45962. 0x0ef3705683ad2a3L,0x1fb0cf82fcf364aL,0x00943dc83d9a277L,
  45963. 0x043bfcf4320f144L,0x0b9d3e4d4b2699bL,0x1e5f5aaf207082bL,
  45964. 0x15b963af673e0b2L,0x042a06fa61b3593L,0x131ffe2a6d55d2bL,
  45965. 0x03a8263d5efeef4L,0x0a574395822b012L,0x081da1a502f853dL,
  45966. 0x09af57dcf7993c6L,0x146d496a27dc1bcL,0x00016e14baca055L } },
  45967. /* 245 */
  45968. { { 0x0533937b69d60c3L,0x1f2a97f4b93aaf7L,0x1e37031c9698982L,
  45969. 0x1d9565cf85623f6L,0x0e2322cb6982c27L,0x13827ba5e776ecfL,
  45970. 0x1859654ac67b448L,0x10a5be9850b0a94L,0x0ba40b5bf7b1924L,
  45971. 0x05e54a8008cfa95L,0x1f472f96b761bffL,0x0df7b3a1e582e8cL,
  45972. 0x14b8d4ebc99bf53L,0x02d4098b9e14b71L,0x0cd7dd81257e3d0L,
  45973. 0x0424518b3d1ace6L,0x0730b53d324e054L,0x026ab229a9e1dedL },
  45974. { 0x122f8007e5c0877L,0x1a1f30654d3b239L,0x1d2e8b049c59206L,
  45975. 0x0fda626d84463e9L,0x18db30de0959685L,0x08475e574131911L,
  45976. 0x08c7994beb50266L,0x092171a30295e1aL,0x02680c54b09cbc3L,
  45977. 0x0a2b179a5f9dfc7L,0x14242c24ad657ffL,0x1948bc2bf868530L,
  45978. 0x11bc378168e6f39L,0x022d2543b80ba8cL,0x085506a41a512ceL,
  45979. 0x19169598dae9505L,0x062adc9bab3b155L,0x00f97c4e73b9836L } },
  45980. /* 246 */
  45981. { { 0x053ef419affefdfL,0x1f672a67c92b5c1L,0x0bcad113920c175L,
  45982. 0x1f974a8e3e6ee00L,0x15cbe015b189755L,0x05c214e44241e5eL,
  45983. 0x1d874953df1a5a8L,0x0ae310a17a8c3e7L,0x17ba210890a2471L,
  45984. 0x0d5de176c977586L,0x1b2afa5977b224dL,0x0e4978aad095f6aL,
  45985. 0x0f6a7a74929da23L,0x177a5d236c5d1cbL,0x026c9ebf2e436dcL,
  45986. 0x06cddba469fc132L,0x147bdf3c16476f4L,0x004e404bf8bf286L },
  45987. { 0x004b14060050c07L,0x1418c21d471bf35L,0x06caed57907f0a7L,
  45988. 0x1459cc1c7597285L,0x1b9d82f4ed2fea5L,0x1e9bfd6e3d8ff9eL,
  45989. 0x1d4e523afb30da1L,0x124f22a7c65d960L,0x06a60054f570756L,
  45990. 0x038e6864003acddL,0x1ce1bcc248b7c4eL,0x0b3d066af6f82f4L,
  45991. 0x09394151864e9fcL,0x09a6dc448e9359dL,0x1f36dc644a8088bL,
  45992. 0x0606ccce5f9e8b3L,0x16c5a3f268d44ffL,0x037889f69b488f0L } },
  45993. /* 247 */
  45994. { { 0x0a9df591836f1c9L,0x08cfaa119183ea9L,0x1c0577b4a16be99L,
  45995. 0x155ec4feeb080d8L,0x0ce0417d0a1545cL,0x089a21d70888f75L,
  45996. 0x12f2feca2f7da98L,0x0b1bd3de156a5b7L,0x1e9dc181b7813e6L,
  45997. 0x18ed5edcc893912L,0x16638c8a0531642L,0x0cddb269dcfcbe0L,
  45998. 0x1ab99ba4bf5c3b9L,0x1e0daaf3a75c276L,0x0aa183eca4668d0L,
  45999. 0x03fed535bb69329L,0x1e21b7220dff681L,0x0331b511de8d0c1L },
  46000. { 0x15d5a2d20587283L,0x01164f783fe2eefL,0x15543bdb78e02ceL,
  46001. 0x0e4ba2ce3a2f0d7L,0x1cdb1def163cf90L,0x017e253a5fcb8f8L,
  46002. 0x153dd5d27a0c021L,0x1961c5db78e4ff0L,0x1bb27bbdabce24aL,
  46003. 0x0d8ce7602df6846L,0x0848fbdf2412f30L,0x1e37b13305b755bL,
  46004. 0x0e65f6e63202429L,0x172cfe9924e9b0bL,0x07ca7d68de27ea3L,
  46005. 0x0f1402c174775fdL,0x0f80f2d3b61af53L,0x03d77663b39e153L } },
  46006. /* 248 */
  46007. { { 0x1a4757cdc43b0dbL,0x12742cc08ce56f9L,0x0fd9185b0558f62L,
  46008. 0x189ea67d2ff012bL,0x19cfc5ad3e2a07bL,0x14029654c121b39L,
  46009. 0x1b198629ae8eb35L,0x12b7ac1cb211439L,0x1ae3841a502b1b6L,
  46010. 0x036ff890c850cadL,0x0afab2b4c7f66e6L,0x044998e51ef65beL,
  46011. 0x180cf0a9927d893L,0x0c35227561c7539L,0x057c0f2a10e6a01L,
  46012. 0x1f10bdbcfefe02cL,0x0454824990827a1L,0x0147620035bc53bL },
  46013. { 0x1820c2ea2fe0009L,0x1d2e9789c3a74f0L,0x115314936d4b846L,
  46014. 0x0cffdbca532ea44L,0x1b2500d44d47742L,0x14922580e9a0cd4L,
  46015. 0x186e73822924861L,0x1c1742d2047ba37L,0x0242c3e5432a301L,
  46016. 0x1ab7bdd384833c4L,0x14a8271d2a33126L,0x1083aedf2873e15L,
  46017. 0x0b621fb60e99cd1L,0x1e1cbb1a76ed7f0L,0x1fc2a1015afb952L,
  46018. 0x1815e8ca7f0c1feL,0x1c36bd4876f2011L,0x009a7a663864a92L } },
  46019. /* 249 */
  46020. { { 0x021a3ece938dff4L,0x00d3da4353cd1cbL,0x1e5f7a5414ddf44L,
  46021. 0x13ccbb0fb7e589dL,0x173b8cfaf318409L,0x0148b75c4e3ffd9L,
  46022. 0x09d91a2ea9417a1L,0x0574f21fa129d7dL,0x1679df6d4e59289L,
  46023. 0x011998e7e7f6ba0L,0x13bf4a6203fc848L,0x1bbba0688a0217eL,
  46024. 0x0b342858c87ca78L,0x12baa43d16584f6L,0x12c1246797adb70L,
  46025. 0x1a8e2a0ceb42bd7L,0x0f409d2e74f7381L,0x03751bc14c1e9ebL },
  46026. { 0x05c094b4e5cc40aL,0x11fb50d79befde3L,0x1a77e409b911e8bL,
  46027. 0x0b27101ea7decefL,0x1f644aa9b7878c9L,0x10461e25518583bL,
  46028. 0x198ee83145a0cbcL,0x060f804ef5ccb1aL,0x0ef0b3c38ae1d91L,
  46029. 0x0179bd3b4ae1f52L,0x130715a8317834cL,0x0b8841979f3fc00L,
  46030. 0x1d568a0e7c9fd49L,0x0c94322a3836adcL,0x069c2722c8977fdL,
  46031. 0x11ad0a4fa88cb1bL,0x07d47c558da87c0L,0x0303773735da778L } },
  46032. /* 250 */
  46033. { { 0x0d99fc757c621f6L,0x12060bff41ea401L,0x1e867bc666c0a4bL,
  46034. 0x05cc58eccc37bf8L,0x0673875378a0410L,0x1d32d78b66d1b87L,
  46035. 0x18826f2065d3478L,0x18c32e84091ef1fL,0x1c83a058abf5981L,
  46036. 0x135921a4e44b816L,0x0cbc7a74699e2bcL,0x1361fe535c53311L,
  46037. 0x181d7cf5ec472bfL,0x19346eec50a1f1cL,0x113fdda7275f916L,
  46038. 0x0ece62cd9b4aabfL,0x1076044cdf0a4aaL,0x024edd37bf48a43L },
  46039. { 0x0e47fb2a758e37aL,0x198eb96c757b310L,0x17e5be708842bdaL,
  46040. 0x0f21df86566a55aL,0x01e4b2640093f72L,0x18abcaa1ae4cee2L,
  46041. 0x0d5d6fea1e38016L,0x0b3338a41481cceL,0x1ca68259487eea7L,
  46042. 0x14fbdc0f8951a45L,0x1f3060aa8b38d40L,0x0e97d5abc58b4a8L,
  46043. 0x1b55682cdfa11d8L,0x05df47334d781a4L,0x14e52afe1baffaaL,
  46044. 0x1d71e7b570f05eaL,0x18c458bf797ebc8L,0x0244853d24dbef3L } },
  46045. /* 251 */
  46046. { { 0x12996898da995f6L,0x15573f630ab77ebL,0x1030d5aa0b574e7L,
  46047. 0x03826b79fcd2b20L,0x0f595c78b2046b2L,0x02fda0753905b20L,
  46048. 0x0eff00a093beb9fL,0x17d2fb1fa981db6L,0x112f0290579f24eL,
  46049. 0x17e23e78c3f535cL,0x07f49de275708c5L,0x16d9124c7d99843L,
  46050. 0x128b6d30a6233a6L,0x04d99b40411b1a5L,0x11dd15b28d4b897L,
  46051. 0x00cb72711ad9481L,0x076f8e55b0b3c92L,0x02e0ba3a58121cdL },
  46052. { 0x088e7c28aaccab5L,0x13c1b5567682decL,0x1df733b03d94600L,
  46053. 0x1824b8510430b70L,0x07fdc54c93cadc1L,0x1c4519a2efaa053L,
  46054. 0x1e8b13cf21b8b09L,0x19e7d0e88d3c741L,0x1c59daa47273983L,
  46055. 0x031e245a54b6c52L,0x14af3f0b962454cL,0x170f09c85187871L,
  46056. 0x0cf0c4fd5390e78L,0x0a0f3002c805149L,0x094e872dfe4b6deL,
  46057. 0x01f4f2acf2482d9L,0x08c35f6f31db1abL,0x02eb3af5a3dac20L } },
  46058. /* 252 */
  46059. { { 0x0ee1a77870c6025L,0x111dbc8d16fe557L,0x0310e1ad9313f12L,
  46060. 0x1bcb5ce562f61ccL,0x1eefa212d5d5b17L,0x01c5cb36fe44564L,
  46061. 0x0bb313fabbefb50L,0x00e133586ad1c5aL,0x0548ea612012af2L,
  46062. 0x1ff6cedc4e1890cL,0x1a47138399ccc53L,0x0c9f5f0601c0383L,
  46063. 0x1c6773c3be009bbL,0x00410cfd43c0280L,0x06c1bff8335bb7bL,
  46064. 0x166def80abc0ff0L,0x0a382b63f9ce080L,0x0017e65d7854ff6L },
  46065. { 0x191d4d1b47cac61L,0x08b43d5c370964cL,0x17b0ae53c108ba7L,
  46066. 0x1291cc91cb18d0aL,0x0f89ac57ca40051L,0x13c966cdd48fd97L,
  46067. 0x078553d0648186fL,0x03305a443977a1eL,0x0062eb13bfc4440L,
  46068. 0x1d4be194cbc87eeL,0x05b651819e992fcL,0x0600da46eeb49cfL,
  46069. 0x15ed7f0f23c46ddL,0x1da7b1ebc339626L,0x189cfca08614770L,
  46070. 0x01edea1475c19a4L,0x145800e58fceac6L,0x02b78f22b09c22aL } },
  46071. /* 253 */
  46072. { { 0x1ccb3f632c24f3bL,0x18e3f836c0bf300L,0x02edaa899dda67aL,
  46073. 0x1c108babc11b8c8L,0x181a79a87838affL,0x140cd879a7f658fL,
  46074. 0x092e1a8b8a0b4f9L,0x0738972ef9d046fL,0x10f46b3db876364L,
  46075. 0x032faa04bcb824bL,0x021d8a1e46f90e9L,0x16d868331d8dafcL,
  46076. 0x17093d94bb00220L,0x14eb48592bd9c31L,0x0ab46921004b858L,
  46077. 0x069c605d93b6a41L,0x0f8afee2fc685dcL,0x0488e8c9b12a806L },
  46078. { 0x1b1bd58f5e5af5bL,0x1131dbdb5115389L,0x1137cebcab729f2L,
  46079. 0x134088417b56d7dL,0x0ba36c1116651e5L,0x0121881da2459daL,
  46080. 0x1b2ecf18aff37fdL,0x101bc2b894be352L,0x0be0ad8a1e4d1f9L,
  46081. 0x095e8a71b339d1dL,0x00ebda484ab3760L,0x1738aec12b9c806L,
  46082. 0x0a107f5ca58f6daL,0x044b51d83ef8c41L,0x18ecfc2e40f98f2L,
  46083. 0x10fbdea090a89b0L,0x0655e5019b9c098L,0x015f3a27f507a9cL } },
  46084. /* 254 */
  46085. { { 0x14cd05f5b50f324L,0x0f5920f51e3d102L,0x0971ffe39adee6cL,
  46086. 0x1dd8081104950b1L,0x10cba9bdd83902fL,0x0e4f0f3959324a6L,
  46087. 0x16e07405dbe42caL,0x1f80ba9d6059d75L,0x0874405b1372b8bL,
  46088. 0x0209440bcf568c8L,0x08f74fb0ad23357L,0x14ee7e9aa067a89L,
  46089. 0x0d564c3a0984499L,0x1a17401dd9bd9c6L,0x1d462ca03a6525fL,
  46090. 0x1fbc980f68f4171L,0x07ac710e3c53568L,0x039afaa17e75687L },
  46091. { 0x0a9a17138380039L,0x17f0bfba68ce465L,0x04fb32f06a2eb7eL,
  46092. 0x13fc052e0b25a87L,0x130e9b363c5dbf3L,0x1ea4a522a95ad5cL,
  46093. 0x0b10dfb98c0c8abL,0x13104d535ae7e05L,0x198c53562993562L,
  46094. 0x0434fc3b9a15d9cL,0x04008393e6de683L,0x0349a68f1353aeaL,
  46095. 0x1acfa856376361dL,0x045603f2786f6adL,0x1bc72f501fb9cfeL,
  46096. 0x0b75bf58fa07e13L,0x19e25d697cb4d47L,0x00f4c264e8a5e9cL } },
  46097. /* 255 */
  46098. { { 0x16d05614850c817L,0x12d8c9a44c096e3L,0x055179632efac22L,
  46099. 0x1497cc3cb4e4e7aL,0x17aeb8e18900b5fL,0x0d1ea5d5044348eL,
  46100. 0x1f4f799999abf4dL,0x0b871458332afd8L,0x0a0648e8f668d6fL,
  46101. 0x1cfe4963d6e0ba3L,0x045b0210c1970c7L,0x1440c3cd5cd2474L,
  46102. 0x162aa47e7336370L,0x0f7fb6c231361b9L,0x0fb4b51503097cbL,
  46103. 0x12925300904999bL,0x0014b5bfce0039aL,0x03623a52b3b4a17L },
  46104. { 0x0eb9a417d88e3a1L,0x09e4462423a151dL,0x0344ff9844c4417L,
  46105. 0x16350d3d17cb3bdL,0x0a75d90a148f5b6L,0x0a3009bd455e2cdL,
  46106. 0x13364bc326f1d88L,0x12487f54e8f8704L,0x081763a186a5d0bL,
  46107. 0x1e1a0de4de5d75eL,0x04c583dd174776eL,0x0a5b6eb9cbe9c30L,
  46108. 0x0cd50de4c2a53ceL,0x1aebb2b68af5733L,0x12954a97b6265b1L,
  46109. 0x00b69c9feae2389L,0x0ce215e985a3c53L,0x03592c4aa7d0dd1L } },
  46110. };
  46111. /* Multiply the base point of P1024 by the scalar and return the result.
  46112. * If map is true then convert result to affine coordinates.
  46113. *
  46114. * Stripe implementation.
  46115. * Pre-generated: 2^0, 2^128, ...
  46116. * Pre-generated: products of all combinations of above.
  46117. * 8 doubles and adds (with qz=1)
  46118. *
  46119. * r Resulting point.
  46120. * k Scalar to multiply by.
  46121. * map Indicates whether to convert result to affine.
  46122. * ct Constant time required.
  46123. * heap Heap to use for allocation.
  46124. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  46125. */
  46126. static int sp_1024_ecc_mulmod_base_18(sp_point_1024* r, const sp_digit* k,
  46127. int map, int ct, void* heap)
  46128. {
  46129. return sp_1024_ecc_mulmod_stripe_18(r, &p1024_base, p1024_table,
  46130. k, map, ct, heap);
  46131. }
  46132. #endif
  46133. /* Multiply the base point of P1024 by the scalar and return the result.
  46134. * If map is true then convert result to affine coordinates.
  46135. *
  46136. * km Scalar to multiply by.
  46137. * r Resulting point.
  46138. * map Indicates whether to convert result to affine.
  46139. * heap Heap to use for allocation.
  46140. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  46141. */
  46142. int sp_ecc_mulmod_base_1024(const mp_int* km, ecc_point* r, int map, void* heap)
  46143. {
  46144. #ifdef WOLFSSL_SP_SMALL_STACK
  46145. sp_point_1024* point = NULL;
  46146. sp_digit* k = NULL;
  46147. #else
  46148. sp_point_1024 point[1];
  46149. sp_digit k[18];
  46150. #endif
  46151. int err = MP_OKAY;
  46152. #ifdef WOLFSSL_SP_SMALL_STACK
  46153. point = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap,
  46154. DYNAMIC_TYPE_ECC);
  46155. if (point == NULL)
  46156. err = MEMORY_E;
  46157. if (err == MP_OKAY) {
  46158. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18, heap,
  46159. DYNAMIC_TYPE_ECC);
  46160. if (k == NULL)
  46161. err = MEMORY_E;
  46162. }
  46163. #endif
  46164. if (err == MP_OKAY) {
  46165. sp_1024_from_mp(k, 18, km);
  46166. err = sp_1024_ecc_mulmod_base_18(point, k, map, 1, heap);
  46167. }
  46168. if (err == MP_OKAY) {
  46169. err = sp_1024_point_to_ecc_point_18(point, r);
  46170. }
  46171. #ifdef WOLFSSL_SP_SMALL_STACK
  46172. if (k != NULL)
  46173. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  46174. if (point != NULL)
  46175. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  46176. #endif
  46177. return err;
  46178. }
  46179. /* Multiply the base point of P1024 by the scalar, add point a and return
  46180. * the result. If map is true then convert result to affine coordinates.
  46181. *
  46182. * km Scalar to multiply by.
  46183. * am Point to add to scalar multiply result.
  46184. * inMont Point to add is in montgomery form.
  46185. * r Resulting point.
  46186. * map Indicates whether to convert result to affine.
  46187. * heap Heap to use for allocation.
  46188. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  46189. */
  46190. int sp_ecc_mulmod_base_add_1024(const mp_int* km, const ecc_point* am,
  46191. int inMont, ecc_point* r, int map, void* heap)
  46192. {
  46193. #ifdef WOLFSSL_SP_SMALL_STACK
  46194. sp_point_1024* point = NULL;
  46195. sp_digit* k = NULL;
  46196. #else
  46197. sp_point_1024 point[2];
  46198. sp_digit k[18 + 18 * 2 * 37];
  46199. #endif
  46200. sp_point_1024* addP = NULL;
  46201. sp_digit* tmp = NULL;
  46202. int err = MP_OKAY;
  46203. #ifdef WOLFSSL_SP_SMALL_STACK
  46204. point = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 2, heap,
  46205. DYNAMIC_TYPE_ECC);
  46206. if (point == NULL)
  46207. err = MEMORY_E;
  46208. if (err == MP_OKAY) {
  46209. k = (sp_digit*)XMALLOC(
  46210. sizeof(sp_digit) * (18 + 18 * 2 * 37),
  46211. heap, DYNAMIC_TYPE_ECC);
  46212. if (k == NULL)
  46213. err = MEMORY_E;
  46214. }
  46215. #endif
  46216. if (err == MP_OKAY) {
  46217. addP = point + 1;
  46218. tmp = k + 18;
  46219. sp_1024_from_mp(k, 18, km);
  46220. sp_1024_point_from_ecc_point_18(addP, am);
  46221. }
  46222. if ((err == MP_OKAY) && (!inMont)) {
  46223. err = sp_1024_mod_mul_norm_18(addP->x, addP->x, p1024_mod);
  46224. }
  46225. if ((err == MP_OKAY) && (!inMont)) {
  46226. err = sp_1024_mod_mul_norm_18(addP->y, addP->y, p1024_mod);
  46227. }
  46228. if ((err == MP_OKAY) && (!inMont)) {
  46229. err = sp_1024_mod_mul_norm_18(addP->z, addP->z, p1024_mod);
  46230. }
  46231. if (err == MP_OKAY) {
  46232. err = sp_1024_ecc_mulmod_base_18(point, k, 0, 0, heap);
  46233. }
  46234. if (err == MP_OKAY) {
  46235. sp_1024_proj_point_add_18(point, point, addP, tmp);
  46236. if (map) {
  46237. sp_1024_map_18(point, point, tmp);
  46238. }
  46239. err = sp_1024_point_to_ecc_point_18(point, r);
  46240. }
  46241. #ifdef WOLFSSL_SP_SMALL_STACK
  46242. if (k != NULL)
  46243. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  46244. if (point)
  46245. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  46246. #endif
  46247. return err;
  46248. }
  46249. #ifndef WOLFSSL_SP_SMALL
  46250. /* Generate a pre-computation table for the point.
  46251. *
  46252. * gm Point to generate table for.
  46253. * table Buffer to hold pre-computed points table.
  46254. * len Length of table.
  46255. * heap Heap to use for allocation.
  46256. * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is
  46257. * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise.
  46258. */
  46259. int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len,
  46260. void* heap)
  46261. {
  46262. #ifdef WOLFSSL_SP_SMALL_STACK
  46263. sp_point_1024* point = NULL;
  46264. sp_digit* t = NULL;
  46265. #else
  46266. sp_point_1024 point[1];
  46267. sp_digit t[38 * 2 * 18];
  46268. #endif
  46269. int err = MP_OKAY;
  46270. if ((gm == NULL) || (len == NULL)) {
  46271. err = BAD_FUNC_ARG;
  46272. }
  46273. if ((err == MP_OKAY) && (table == NULL)) {
  46274. *len = sizeof(sp_table_entry_1024) * 256;
  46275. err = LENGTH_ONLY_E;
  46276. }
  46277. if ((err == MP_OKAY) && (*len < (int)(sizeof(sp_table_entry_1024) * 256))) {
  46278. err = BUFFER_E;
  46279. }
  46280. #ifdef WOLFSSL_SP_SMALL_STACK
  46281. if (err == MP_OKAY) {
  46282. point = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap,
  46283. DYNAMIC_TYPE_ECC);
  46284. if (point == NULL)
  46285. err = MEMORY_E;
  46286. }
  46287. if (err == MP_OKAY) {
  46288. t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 38 * 2 * 18, heap,
  46289. DYNAMIC_TYPE_ECC);
  46290. if (t == NULL)
  46291. err = MEMORY_E;
  46292. }
  46293. #endif
  46294. if (err == MP_OKAY) {
  46295. sp_1024_point_from_ecc_point_18(point, gm);
  46296. err = sp_1024_gen_stripe_table_18(point,
  46297. (sp_table_entry_1024*)table, t, heap);
  46298. }
  46299. if (err == 0) {
  46300. *len = sizeof(sp_table_entry_1024) * 256;
  46301. }
  46302. #ifdef WOLFSSL_SP_SMALL_STACK
  46303. if (t != NULL)
  46304. XFREE(t, heap, DYNAMIC_TYPE_ECC);
  46305. if (point != NULL)
  46306. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  46307. #endif
  46308. return err;
  46309. }
  46310. #else
  46311. /* Generate a pre-computation table for the point.
  46312. *
  46313. * gm Point to generate table for.
  46314. * table Buffer to hold pre-computed points table.
  46315. * len Length of table.
  46316. * heap Heap to use for allocation.
  46317. * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is
  46318. * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise.
  46319. */
  46320. int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len,
  46321. void* heap)
  46322. {
  46323. int err = 0;
  46324. if ((gm == NULL) || (len == NULL)) {
  46325. err = BAD_FUNC_ARG;
  46326. }
  46327. if ((err == 0) && (table == NULL)) {
  46328. *len = 0;
  46329. err = LENGTH_ONLY_E;
  46330. }
  46331. if ((err == 0) && (*len != 0)) {
  46332. err = BUFFER_E;
  46333. }
  46334. if (err == 0) {
  46335. *len = 0;
  46336. }
  46337. (void)heap;
  46338. return err;
  46339. }
  46340. #endif
  46341. /* Multiply the point by the scalar and return the result.
  46342. * If map is true then convert result to affine coordinates.
  46343. *
  46344. * km Scalar to multiply by.
  46345. * gm Point to multiply.
  46346. * table Pre-computed points.
  46347. * r Resulting point.
  46348. * map Indicates whether to convert result to affine.
  46349. * heap Heap to use for allocation.
  46350. * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
  46351. */
  46352. int sp_ecc_mulmod_table_1024(const mp_int* km, const ecc_point* gm, byte* table,
  46353. ecc_point* r, int map, void* heap)
  46354. {
  46355. #ifdef WOLFSSL_SP_SMALL_STACK
  46356. sp_point_1024* point = NULL;
  46357. sp_digit* k = NULL;
  46358. #else
  46359. sp_point_1024 point[1];
  46360. sp_digit k[18];
  46361. #endif
  46362. int err = MP_OKAY;
  46363. #ifdef WOLFSSL_SP_SMALL_STACK
  46364. point = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap,
  46365. DYNAMIC_TYPE_ECC);
  46366. if (point == NULL) {
  46367. err = MEMORY_E;
  46368. }
  46369. if (err == MP_OKAY) {
  46370. k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18, heap, DYNAMIC_TYPE_ECC);
  46371. if (k == NULL)
  46372. err = MEMORY_E;
  46373. }
  46374. #endif
  46375. if (err == MP_OKAY) {
  46376. sp_1024_from_mp(k, 18, km);
  46377. sp_1024_point_from_ecc_point_18(point, gm);
  46378. #ifndef WOLFSSL_SP_SMALL
  46379. err = sp_1024_ecc_mulmod_stripe_18(point, point,
  46380. (const sp_table_entry_1024*)table, k, map, 0, heap);
  46381. #else
  46382. (void)table;
  46383. err = sp_1024_ecc_mulmod_18(point, point, k, map, 0, heap);
  46384. #endif
  46385. }
  46386. if (err == MP_OKAY) {
  46387. err = sp_1024_point_to_ecc_point_18(point, r);
  46388. }
  46389. #ifdef WOLFSSL_SP_SMALL_STACK
  46390. if (k != NULL)
  46391. XFREE(k, heap, DYNAMIC_TYPE_ECC);
  46392. if (point != NULL)
  46393. XFREE(point, heap, DYNAMIC_TYPE_ECC);
  46394. #endif
  46395. return err;
  46396. }
  46397. /* Multiply p* in projective coordinates by q*.
  46398. *
  46399. * r.x = p.x - (p.y * q.y)
  46400. * r.y = (p.x * q.y) + p.y
  46401. *
  46402. * px [in,out] A single precision integer - X ordinate of number to multiply.
  46403. * py [in,out] A single precision integer - Y ordinate of number to multiply.
  46404. * q [in] A single precision integer - multiplier.
  46405. * t [in] Two single precision integers - temps.
  46406. */
  46407. static void sp_1024_proj_mul_qx1_18(sp_digit* px, sp_digit* py,
  46408. const sp_digit* q, sp_digit* t)
  46409. {
  46410. sp_digit* t1 = t;
  46411. sp_digit* t2 = t + 2 * 18;
  46412. /* t1 = p.x * q.y */
  46413. sp_1024_mont_mul_18(t1, px, q, p1024_mod, p1024_mp_mod);
  46414. /* t2 = p.y * q.y */
  46415. sp_1024_mont_mul_18(t2, py, q, p1024_mod, p1024_mp_mod);
  46416. /* r.x = p.x - (p.y * q.y) */
  46417. sp_1024_mont_sub_18(px, px, t2, p1024_mod);
  46418. /* r.y = (p.x * q.y) + p.y */
  46419. sp_1024_mont_add_18(py, t1, py, p1024_mod);
  46420. }
  46421. /* Square p* in projective coordinates.
  46422. *
  46423. * px' = (p.x + p.y) * (p.x - p.y) = p.x^2 - p.y^2
  46424. * py' = 2 * p.x * p.y
  46425. *
  46426. * px [in,out] A single precision integer - X ordinate of number to square.
  46427. * py [in,out] A single precision integer - Y ordinate of number to square.
  46428. * t [in] Two single precision integers - temps.
  46429. */
  46430. static void sp_1024_proj_sqr_18(sp_digit* px, sp_digit* py, sp_digit* t)
  46431. {
  46432. sp_digit* t1 = t;
  46433. sp_digit* t2 = t + 2 * 18;
  46434. /* t1 = p.x + p.y */
  46435. sp_1024_mont_add_18(t1, px, py, p1024_mod);
  46436. /* t2 = p.x - p.y */
  46437. sp_1024_mont_sub_18(t2, px, py, p1024_mod);
  46438. /* r.y = p.x * p.y */
  46439. sp_1024_mont_mul_18(py, px, py, p1024_mod, p1024_mp_mod);
  46440. /* r.x = (p.x + p.y) * (p.x - p.y) */
  46441. sp_1024_mont_mul_18(px, t1, t2, p1024_mod, p1024_mp_mod);
  46442. /* r.y = (p.x * p.y) * 2 */
  46443. sp_1024_mont_dbl_18(py, py, p1024_mod);
  46444. }
  46445. #ifdef WOLFSSL_SP_SMALL
  46446. /* Perform the modular exponentiation in Fp* for SAKKE.
  46447. *
  46448. * Simple square and multiply when expontent bit is one algorithm.
  46449. * Square and multiply performed in Fp*.
  46450. *
  46451. * base [in] Base. MP integer.
  46452. * exp [in] Exponent. MP integer.
  46453. * res [out] Result. MP integer.
  46454. * returns 0 on success and MEMORY_E if memory allocation fails.
  46455. */
  46456. int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res)
  46457. {
  46458. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  46459. defined(WOLFSSL_SP_SMALL_STACK)
  46460. sp_digit* td;
  46461. sp_digit* t;
  46462. sp_digit* tx;
  46463. sp_digit* ty;
  46464. sp_digit* b;
  46465. sp_digit* e;
  46466. #else
  46467. sp_digit t[36 * 2 * 18];
  46468. sp_digit tx[2 * 18];
  46469. sp_digit ty[2 * 18];
  46470. sp_digit b[2 * 18];
  46471. sp_digit e[2 * 18];
  46472. #endif
  46473. sp_digit* r;
  46474. int err = MP_OKAY;
  46475. int bits;
  46476. int i;
  46477. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  46478. defined(WOLFSSL_SP_SMALL_STACK)
  46479. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 40 * 18 * 2, NULL,
  46480. DYNAMIC_TYPE_TMP_BUFFER);
  46481. if (td == NULL) {
  46482. err = MEMORY_E;
  46483. }
  46484. #endif
  46485. if (err == MP_OKAY) {
  46486. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  46487. defined(WOLFSSL_SP_SMALL_STACK)
  46488. t = td;
  46489. tx = td + 36 * 18 * 2;
  46490. ty = td + 37 * 18 * 2;
  46491. b = td + 38 * 18 * 2;
  46492. e = td + 39 * 18 * 2;
  46493. #endif
  46494. r = ty;
  46495. bits = mp_count_bits(exp);
  46496. sp_1024_from_mp(b, 18, base);
  46497. sp_1024_from_mp(e, 18, exp);
  46498. XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 18);
  46499. sp_1024_mul_18(b, b, p1024_norm_mod);
  46500. err = sp_1024_mod_18(b, b, p1024_mod);
  46501. }
  46502. if (err == MP_OKAY) {
  46503. XMEMCPY(ty, b, sizeof(sp_digit) * 18);
  46504. for (i = bits - 2; i >= 0; i--) {
  46505. sp_1024_proj_sqr_18(tx, ty, t);
  46506. if ((e[i / 57] >> (i % 57)) & 1) {
  46507. sp_1024_proj_mul_qx1_18(tx, ty, b, t);
  46508. }
  46509. }
  46510. }
  46511. if (err == MP_OKAY) {
  46512. sp_1024_mont_inv_18(tx, tx, t);
  46513. XMEMSET(tx + 18, 0, sizeof(sp_digit) * 18);
  46514. sp_1024_mont_reduce_18(tx, p1024_mod, p1024_mp_mod);
  46515. XMEMSET(ty + 18, 0, sizeof(sp_digit) * 18);
  46516. sp_1024_mont_reduce_18(ty, p1024_mod, p1024_mp_mod);
  46517. sp_1024_mul_18(r, tx, ty);
  46518. err = sp_1024_mod_18(r, r, p1024_mod);
  46519. }
  46520. if (err == MP_OKAY) {
  46521. err = sp_1024_to_mp(r, res);
  46522. }
  46523. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  46524. defined(WOLFSSL_SP_SMALL_STACK)
  46525. if (td != NULL) {
  46526. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  46527. }
  46528. #endif
  46529. return err;
  46530. }
  46531. #else
  46532. /* Pre-computed table for exponentiating g.
  46533. * Striping: 8 points at a distance of (128 combined for
  46534. * a total of 256 points.
  46535. */
  46536. static const sp_digit sp_1024_g_table[256][18] = {
  46537. { 0x000000000000000L, 0x000000000000000L, 0x000000000000000L,
  46538. 0x000000000000000L, 0x000000000000000L, 0x000000000000000L,
  46539. 0x000000000000000L, 0x000000000000000L, 0x000000000000000L,
  46540. 0x000000000000000L, 0x000000000000000L, 0x000000000000000L,
  46541. 0x000000000000000L, 0x000000000000000L, 0x000000000000000L,
  46542. 0x000000000000000L, 0x000000000000000L, 0x000000000000000L },
  46543. { 0x10a46d2335c1685L, 0x0f4b8f0803d2c0bL, 0x0f7d0f2929cfab2L,
  46544. 0x0b04c848ea81d1eL, 0x136576d12646f81L, 0x1f8d7d9d7a4dda5L,
  46545. 0x1479b6278b451caL, 0x0f84f7d10585fa2L, 0x1addedc858f8871L,
  46546. 0x16c2cdf8b563637L, 0x10686cb63ab9635L, 0x1400c383e61a1ceL,
  46547. 0x1a9b67e0966faf7L, 0x1e9da7beb36de84L, 0x09f263887c47019L,
  46548. 0x16442c2a574058eL, 0x0f4afd58891e86cL, 0x02cf49e3535e9ddL },
  46549. { 0x14dd36f71dd4594L, 0x0e64f805778f372L, 0x113a867d94c2ef2L,
  46550. 0x127ea412513d4b4L, 0x0f5c14188588aa9L, 0x09ccfd4ba9bca64L,
  46551. 0x1aad4462f5e4b04L, 0x0a5737a75fbeb96L, 0x1813d1cb22ecb96L,
  46552. 0x0a2b133a01c4c09L, 0x1c466d2b210c73fL, 0x152214301d6ca3eL,
  46553. 0x179f7bfa2edd9f6L, 0x0854e86c89ca368L, 0x00dcf4c5bc618c5L,
  46554. 0x0a572be33841adfL, 0x003be85ac6a9b6aL, 0x031f78c3dba7b17L },
  46555. { 0x0376b7f016f45e7L, 0x1edab95f6417c3eL, 0x1d07390a6d80706L,
  46556. 0x058f5fb03ae725eL, 0x1241098b6fdbf0aL, 0x107c67ded20d8fbL,
  46557. 0x0f1356d01d1d2edL, 0x17d267c1a836661L, 0x1ae182830733fa3L,
  46558. 0x07694cd87ae3668L, 0x0cd538fe6183228L, 0x130c2aab3882ffeL,
  46559. 0x1c129f85cbb1360L, 0x03b42fdf55865b1L, 0x06658cda0bb3125L,
  46560. 0x059b4a0bd1d85d6L, 0x02390dcc794ddacL, 0x027f33c8e78c96dL },
  46561. { 0x0a423d505e8733cL, 0x02f328eab8be0caL, 0x1a23a586cc8b321L,
  46562. 0x0db683039846f8fL, 0x113bd7210c4471cL, 0x00bd8480643af13L,
  46563. 0x1abda77f7a7b6cbL, 0x14c8614dbcbd119L, 0x1aaa7a61a7b81ceL,
  46564. 0x1296813119fcc6aL, 0x1bf74181a26a6baL, 0x0f9cb95895576abL,
  46565. 0x148e95076130cfaL, 0x074d0f297d26d88L, 0x01005c0c255c311L,
  46566. 0x1b3a431843ec234L, 0x097555d1ffebe78L, 0x00224150c2b0ed9L },
  46567. { 0x1758ac273d486d8L, 0x0fca330e6e0f3f3L, 0x07f08622ad3e05aL,
  46568. 0x05e66e6c60e4793L, 0x1d8c2260a0e54f0L, 0x18de302b05f712dL,
  46569. 0x1fad4a3f0c1f114L, 0x06fade43e34fc89L, 0x1c8e4499c57128dL,
  46570. 0x11d829f6bd97522L, 0x09e810ca8f488a5L, 0x0a9a6a8b2cd0818L,
  46571. 0x1fd73557e95b518L, 0x034903bd3370d24L, 0x0d09c083499ff66L,
  46572. 0x1b689f426a1a7ceL, 0x09f1a9c3f2568ccL, 0x0419d07fc6f6dfcL },
  46573. { 0x0c419c7ab376b76L, 0x14a7993e8786654L, 0x078aa4314534edcL,
  46574. 0x1d4c4aeb4dcad77L, 0x098c0a88931ba51L, 0x00b5152b7f703d8L,
  46575. 0x0982c12f96bbad3L, 0x0e1ca266a17cdd6L, 0x1339edad6a1d5c2L,
  46576. 0x1b376acf4edd6e8L, 0x0efa20b741bb03cL, 0x139196230fb6842L,
  46577. 0x01d8a1058a22d63L, 0x115ba2788ff64afL, 0x1c170300fdcfa9aL,
  46578. 0x02340e83faa35e9L, 0x05f2e2df95a85f8L, 0x034959e71f5924bL },
  46579. { 0x0e6cb72d2a127b4L, 0x03752c7c940b786L, 0x118d1e8dd8599a9L,
  46580. 0x03c1572ddc87d9eL, 0x12edbe8c163d9a0L, 0x127332e40a2e36dL,
  46581. 0x14be4bd09b2b937L, 0x0622e9a1680e9c4L, 0x054c240d77d2af8L,
  46582. 0x00fd1cb9eb2949bL, 0x05247282751a556L, 0x0a66a8a4c8780b7L,
  46583. 0x11d41283278c4e8L, 0x181b0f92996b219L, 0x1bc27c9911e40e1L,
  46584. 0x0bfc0ee83236313L, 0x0d6c0cf0aaf81deL, 0x0199f21857a0021L },
  46585. { 0x1f04de4cf26d3b7L, 0x1b9835a9fbcdf2eL, 0x117c6022d9915e9L,
  46586. 0x090a06e6c148027L, 0x0b061037ef291eaL, 0x0489dd8ffe4ebe8L,
  46587. 0x0161f6741376597L, 0x0ab29146f5fe277L, 0x0b5443483fe3ee7L,
  46588. 0x1e10f3a023189c3L, 0x041397377ad630fL, 0x10c4cae59aa5674L,
  46589. 0x0115aaa40894fe1L, 0x02cf523175cd38dL, 0x1ac0a8e2b71bf95L,
  46590. 0x123a37631a2ea95L, 0x108ae1276362f77L, 0x00874598eeb5debL },
  46591. { 0x07f03e53ed9f1afL, 0x0923bab33b0b35cL, 0x18c1d33856e00ebL,
  46592. 0x004d63d0b671b9aL, 0x1af99c151877e2bL, 0x012a3d58b2a68b8L,
  46593. 0x17bd65e0ba7924eL, 0x098db8ff8f84daaL, 0x19038f95d2fbeb5L,
  46594. 0x12c86ff01b601abL, 0x0dbab93f70fdfffL, 0x18a9e6bc35119f9L,
  46595. 0x12da0a5568cb1fbL, 0x0db7aaab9e470edL, 0x0b0281a6a1ce4fdL,
  46596. 0x12b5670c8d665cfL, 0x0bcfd261c832a84L, 0x03242a926066e62L },
  46597. { 0x0bfb3e2c4a6ff2aL, 0x01fdd1ad321450dL, 0x1fc226bfdd08aa8L,
  46598. 0x1574bb7b2710844L, 0x12a182cb2337883L, 0x100f829c0c3574eL,
  46599. 0x079eae7c1d93526L, 0x0b724823fd722f6L, 0x0700b1903570cbbL,
  46600. 0x0a8c0eadc8a5f3eL, 0x1110dc660460b57L, 0x1a48ae97332e26bL,
  46601. 0x15632d28b232758L, 0x1d1c1f84d328547L, 0x08cf600901e2eb3L,
  46602. 0x16892ca8d4c1801L, 0x03ca4061c7a2df8L, 0x00fbb79f9791a2bL },
  46603. { 0x0a2c14344c436b0L, 0x182ab0fb4e43d4dL, 0x05ed7db6cb7de41L,
  46604. 0x03daad75046be62L, 0x1d0afa4885761f4L, 0x0e738f7c18a327bL,
  46605. 0x1d222a67ca454ebL, 0x07564f7ed2622d6L, 0x0a98a5a8c9bb944L,
  46606. 0x1c3c0131772fef4L, 0x1e4f74604ab2ddfL, 0x0999b909792474dL,
  46607. 0x0ff1d4995aaf92aL, 0x0276c4ce9e12b15L, 0x14a94e3f67f0cf0L,
  46608. 0x14e4d805195289dL, 0x005d0f367bb049eL, 0x0024927fd9e8847L },
  46609. { 0x0548e3dc673562fL, 0x19812f175724603L, 0x0cad7871a5df4ecL,
  46610. 0x08dd7caaf7cc3faL, 0x01d6e18e424e206L, 0x0bf4adbb39c8e02L,
  46611. 0x06e312e3aee3853L, 0x1a695d16fa84132L, 0x0f8a0df66e01290L,
  46612. 0x0bf1251c92f2fa7L, 0x1ecb2c54209cab2L, 0x0e5c4a0e4cc2f34L,
  46613. 0x029062fa49b40b0L, 0x19e29de76d6cf0cL, 0x0509e661e029e13L,
  46614. 0x1084cb15056ed3eL, 0x03508cd849cc146L, 0x026fe7404e1c057L },
  46615. { 0x1069cb2d527b780L, 0x0d00acbbc986ea2L, 0x002f89f4098f54bL,
  46616. 0x0d765a36562198cL, 0x154adf3c34102c2L, 0x187fa3a6329311aL,
  46617. 0x1b9f35a244e0917L, 0x11507f5198b9522L, 0x11e10f139d15c8dL,
  46618. 0x0b9ee1740ee2b59L, 0x1b2c11713b66ebcL, 0x0fb08fa02450ff9L,
  46619. 0x139f3a532f307fdL, 0x110a9e111252b8aL, 0x0a2902167a7a077L,
  46620. 0x17a478ac4b2bbc8L, 0x002dc7daff89339L, 0x00683ac845c5034L },
  46621. { 0x10af2a7de085f2aL, 0x06927df4cd972c3L, 0x0985672904ee23fL,
  46622. 0x090ab3f0a31181aL, 0x1622da0d1f02a2eL, 0x051b0ac1dcb010fL,
  46623. 0x11a0970170bd5b7L, 0x17c02919e38f221L, 0x0392f2896272695L,
  46624. 0x01e85dad46b277bL, 0x14891073f2f14a2L, 0x19d8a4c22fcbde1L,
  46625. 0x19f04928e9f5dafL, 0x1c9f97155b43095L, 0x0304544a0fdd134L,
  46626. 0x01bfdf7ddafdae0L, 0x15af2cde215a436L, 0x0127d4b0e178429L },
  46627. { 0x167db3f616df7f6L, 0x02bec7dec819303L, 0x0a41ba0b551190cL,
  46628. 0x0ad12c87b62e9b5L, 0x0c89a0602284f34L, 0x013e890c58c8efeL,
  46629. 0x14516ead1abd35bL, 0x13cb4afe90d9312L, 0x0c03214e9cc942fL,
  46630. 0x19f0e47a0ca80acL, 0x0dd67ce6b50eac9L, 0x16ffca1dc2e719dL,
  46631. 0x1c8f4d7d4e5e1b8L, 0x1aab01f9fb1ad8fL, 0x14be9823bfddf8dL,
  46632. 0x16dc2403ec3a2eeL, 0x11494d7a03d4a6fL, 0x01b8e611efe2780L },
  46633. { 0x09b115dda90c351L, 0x0b75f9b26ce0314L, 0x080bd942cc6db46L,
  46634. 0x08deaec85eef512L, 0x08100127cc28c16L, 0x06403dee27bf1b0L,
  46635. 0x103ca20db342371L, 0x0a62501e2adc004L, 0x03f9a6d7899cb39L,
  46636. 0x0524a699d40101cL, 0x05fa47a1f4d1d10L, 0x1a0e4dbbc4948adL,
  46637. 0x0d7640c30e70d97L, 0x0dd37363037b52cL, 0x0f04fa00f0b03a1L,
  46638. 0x1af1e661ed4f5e3L, 0x17f3e602e4fc9f4L, 0x0495b5e5006407dL },
  46639. { 0x03d5c835f00822eL, 0x12b895c58b78917L, 0x07124ac28cc03a0L,
  46640. 0x1b4f9832a903865L, 0x1bb1413f6b4e32aL, 0x09651385f74e770L,
  46641. 0x0454fb7edeea92aL, 0x1f39a8e55f5d477L, 0x0e8f09e7e00f0c0L,
  46642. 0x070ec392e6f5db8L, 0x0eb8212a6d8eda9L, 0x03707fab1ecbfc5L,
  46643. 0x1aa3b62759f4014L, 0x1c8718446bf62f6L, 0x09df8c66abdb99dL,
  46644. 0x10e3842b5b0603eL, 0x09de7db4b98cf33L, 0x038ffb164a7817cL },
  46645. { 0x04c71022a4a84d9L, 0x12566af5e38f355L, 0x0297c73595e38bbL,
  46646. 0x1fffe2414a76235L, 0x09e6503383f5ef9L, 0x0220c05262cc708L,
  46647. 0x0a30787a7e64328L, 0x0d717065a8deb30L, 0x0753f28a033af53L,
  46648. 0x176e258db6a7b45L, 0x19a4a9cb3347c24L, 0x1efba444c865dbbL,
  46649. 0x1ea3d2661cd3aa0L, 0x1ee1beed1c6ddb1L, 0x1bdad33c7867f1bL,
  46650. 0x174d2d83166a109L, 0x073e6a83fe9df1bL, 0x0207ea3f3afcac1L },
  46651. { 0x188b746267140a4L, 0x1fe0f755b797dadL, 0x0239a6189521b6eL,
  46652. 0x025d6ddf85bb3d9L, 0x0ac8ff8869beebaL, 0x110ca867e110a54L,
  46653. 0x1eda6575725bad6L, 0x06f2671380a82e3L, 0x02d85d4521b4683L,
  46654. 0x06b45042089a12eL, 0x1004e7b1b085d05L, 0x172fee60109bca5L,
  46655. 0x061f578aa320cf0L, 0x1cdb57218d60b51L, 0x1529a5462e7eacfL,
  46656. 0x1c50cd1b04223b0L, 0x18c0b334d98dffbL, 0x02d8e08abf31c99L },
  46657. { 0x0edaab172b6bb8fL, 0x12769017e496148L, 0x0f17f9a531ce371L,
  46658. 0x1f96a9b9c9e8574L, 0x032420dc316dc65L, 0x16e7ca6596b351bL,
  46659. 0x0b2745b9c1b9c15L, 0x15050138ec949e6L, 0x1ab18d830ea6edcL,
  46660. 0x1e8d67340e32fabL, 0x059471f684b0413L, 0x1acd8ef234903f2L,
  46661. 0x14785e67a30ac3bL, 0x0d07eac8db568e7L, 0x0718d13934ff113L,
  46662. 0x015679c2c9002dcL, 0x0f484de9cb833e5L, 0x04b1d5c1d53ab77L },
  46663. { 0x04b47d8df4ea5a3L, 0x1440aae7f22ff4aL, 0x156228f0d592595L,
  46664. 0x1dcf933c2ba2dcfL, 0x155071bc84e55b3L, 0x02bee71ff71026fL,
  46665. 0x155c1c401bca410L, 0x159fd18721b774eL, 0x03645bcb63319adL,
  46666. 0x0c4f4583e105fecL, 0x1425a5f5f655e20L, 0x0643733e9c771caL,
  46667. 0x01a60cfb6a037d1L, 0x01b9c16d008d929L, 0x107701d99652aaaL,
  46668. 0x13109913723fb07L, 0x1586b82b899076bL, 0x0221a407e5f22e2L },
  46669. { 0x0ffffb49114221aL, 0x027971f42bd3d7cL, 0x03903e951e1d2bbL,
  46670. 0x03adf2c2a485c5aL, 0x1bfe9b77ef3e6b3L, 0x01d4355914b29bfL,
  46671. 0x0ab1b0aa743cbedL, 0x0f6482509da48aeL, 0x1a3868917e721baL,
  46672. 0x1f7be00608bd3c6L, 0x1241c74c5816b36L, 0x153c0cb51dd2702L,
  46673. 0x18c442be82c2dadL, 0x1b6b95ac6ad89c6L, 0x0c0f9b66db0892fL,
  46674. 0x006e373a6ab9f1dL, 0x1ebab6d1eb0a170L, 0x04b88c54467fd53L },
  46675. { 0x19c59a2cdecb5d8L, 0x1e40dd49d34335fL, 0x160411dd3efe020L,
  46676. 0x154040e16849c1bL, 0x0fbfb781e779a3cL, 0x1950e24e9a97dd8L,
  46677. 0x19406a2c36080fbL, 0x1e570b0c6f62967L, 0x15ba70a498a882fL,
  46678. 0x13980419d8377d2L, 0x100bd040bfb8aa8L, 0x05331404474b485L,
  46679. 0x0685c3fc72e4e76L, 0x1f297573edd15d1L, 0x03d17d9553f9d8fL,
  46680. 0x070f8616a80b44eL, 0x082d56a177aa573L, 0x00be03bc6a5b8fdL },
  46681. { 0x06dff1d2735e37bL, 0x0272b32b762b907L, 0x12767aeea5e3262L,
  46682. 0x117413e78945eb5L, 0x15b0437740fa451L, 0x1d1765461fd0bbfL,
  46683. 0x0f50286877b3659L, 0x094ed1794e00a51L, 0x1f224952b18691cL,
  46684. 0x1709622f436afeaL, 0x16455cde1669a85L, 0x061341ff9c1cf41L,
  46685. 0x1ba96cc9a3723f4L, 0x0d691d1c2d46dbcL, 0x0fd7611b744ab80L,
  46686. 0x1dacd3ffd8743c5L, 0x0c6d6ce84e1a452L, 0x0090ceae42b8ff2L },
  46687. { 0x1eaa67f262969ebL, 0x159ce9781f3b9a1L, 0x19455eec2424e8eL,
  46688. 0x1b1a2a04e9cc24fL, 0x0580bdbd0f82b0eL, 0x1a1f35ffffe56c7L,
  46689. 0x04759474f41d6a5L, 0x11029097b631758L, 0x095cd9990eb24c3L,
  46690. 0x0b530e83fd633e3L, 0x03dd8a8139ae1c8L, 0x1ac3974af990861L,
  46691. 0x0dd234a07a2865dL, 0x1d03c9fc9e14b58L, 0x18a7b39dbe4a0e4L,
  46692. 0x0de84e16afc3e17L, 0x0301314a82f7e62L, 0x01646bd596b2bf9L },
  46693. { 0x1cf58920825e4d6L, 0x0f552b77c1da233L, 0x17604c4042377d4L,
  46694. 0x0b1ba12c7ec7cccL, 0x1df6436a229f89fL, 0x0f5dd3c6258a6ecL,
  46695. 0x1ce06676b91a751L, 0x1d6231556eeb49bL, 0x1da8978bd29e37fL,
  46696. 0x0e76ad556516bf7L, 0x03417719f5aa29aL, 0x1e1aeff09468d93L,
  46697. 0x0eed8cd59a7474bL, 0x08e9cc7dea21459L, 0x0882c46c3f47357L,
  46698. 0x09888b2c027b729L, 0x15896eb705a1b40L, 0x0114ce93ba584ecL },
  46699. { 0x19cd58dc64397e6L, 0x0c78f5fb6e98f2dL, 0x0384fa7c76cab06L,
  46700. 0x0f1f9b8d18b0cdbL, 0x053c01fd405ae28L, 0x0edafb52594066fL,
  46701. 0x1e2837258fcb504L, 0x117dabaa3137d89L, 0x0336fd13d916ee9L,
  46702. 0x092d8d98216fa47L, 0x158a46b3801d39aL, 0x16904a62fd2a19eL,
  46703. 0x0b821c446be8d38L, 0x185b2c9a63d68e9L, 0x1283541c71104d7L,
  46704. 0x0d84d2e36e6dea5L, 0x18eaf9ffa5727b4L, 0x010d633bc8c9b30L },
  46705. { 0x1420e3f2d7fbcd2L, 0x11239cbdefe0c55L, 0x0fe137d752d049cL,
  46706. 0x0c700f6fa692406L, 0x133c36256fcd423L, 0x19140a6fe0cd84dL,
  46707. 0x066e04f5bcdd683L, 0x138e12f14b206f8L, 0x14f3989970ff27bL,
  46708. 0x0070d22b0ad21c4L, 0x0d25a8f980bdd3fL, 0x086364c39439ff4L,
  46709. 0x1bee0164cdc3f1cL, 0x13fbdf4fb09108eL, 0x10b86ecc118fb93L,
  46710. 0x074ac02befcf125L, 0x1d8663d88d62448L, 0x0074760f387316cL },
  46711. { 0x08ccc298a0878ddL, 0x00baeb320038d54L, 0x0082945cd85e66bL,
  46712. 0x1dbab1462b20689L, 0x08d221a1316d023L, 0x0e2471983c2dea4L,
  46713. 0x09dc6dd2cf79e56L, 0x0a685dc070498cfL, 0x159ef6cdde0b914L,
  46714. 0x01857144d91bf48L, 0x11e93125760c95eL, 0x02fda0ee6ccdc30L,
  46715. 0x06a294a32567b12L, 0x0326c1932c0c964L, 0x0c4f96ddaa83d5aL,
  46716. 0x0e7fbc5457a25e9L, 0x035d850c1c01b6bL, 0x0329d3cafae881bL },
  46717. { 0x1e2898550dcb199L, 0x1c72f3fd015b067L, 0x1f0f25d80f42cd6L,
  46718. 0x1a4fe2636b794faL, 0x02b12d52b0e5288L, 0x1b92e39d53826f7L,
  46719. 0x0c44f881ac76076L, 0x0c6162507358ba3L, 0x014f970cbdb45d7L,
  46720. 0x0cbfc9f59092f47L, 0x15ce73b9f6a89b2L, 0x1a7e3fde41d37aeL,
  46721. 0x147c6a42b146ecbL, 0x13fd87e8fcca508L, 0x103692f4a27ad3cL,
  46722. 0x0f2ec2230da6334L, 0x15e083f65a5fb9dL, 0x0186fe23dea2233L },
  46723. { 0x0fc5ae29eaadfe8L, 0x13f2a5a6a74095eL, 0x0b7e2d4cd584940L,
  46724. 0x08ad4d4429560e0L, 0x1059068ea2b9c20L, 0x018887d8d1efbd1L,
  46725. 0x038728d452c8662L, 0x1096f7c466d896fL, 0x017073ce63e2f69L,
  46726. 0x1708a5316efbd63L, 0x064afc1f5f0f221L, 0x1c17d635c5124ecL,
  46727. 0x15251849395da69L, 0x003d1d504c1d78bL, 0x03f88626b14a935L,
  46728. 0x04a022a6b8fb55cL, 0x0cfe16fe872397fL, 0x02b952c8faa6109L },
  46729. { 0x166841909a5553aL, 0x0a18c193b99de24L, 0x12c8fbbf5a40fc1L,
  46730. 0x17e4424da9f39d6L, 0x0fed9578bd3cbf9L, 0x01836c36cb38e01L,
  46731. 0x13f96ee965f3b28L, 0x0ed6e0bdac27aceL, 0x1f1d3622b67f33fL,
  46732. 0x0de79e308e5c618L, 0x119f7394f46aa45L, 0x1253f2115687470L,
  46733. 0x1d8d15767a902feL, 0x0857e83db71f24cL, 0x02c643a050b6d72L,
  46734. 0x1349c2418df78d9L, 0x03c80c865532491L, 0x032e165f0ec6416L },
  46735. { 0x04cda20a660bb63L, 0x01d8543743122b4L, 0x13d9ae83bb5c9f7L,
  46736. 0x0acf3ba2b0ec8e5L, 0x08452d4479c162eL, 0x1fabcf5b44213b8L,
  46737. 0x05dc20a6f1acd04L, 0x10725d42bd92a02L, 0x15e34e300477381L,
  46738. 0x01e51a4b9f0e978L, 0x13c7708a6f4f7a3L, 0x1e3729defda74b8L,
  46739. 0x0ddfae7a1a783efL, 0x0d04cc29236db9cL, 0x173d2ad0d4f5cb8L,
  46740. 0x111724a675ab141L, 0x166d80550160e78L, 0x0418a206a9dd3bfL },
  46741. { 0x03e2e32f611b2daL, 0x13714e87d23567aL, 0x0fa2082cf035741L,
  46742. 0x0c3a7c89e1d12feL, 0x1fd27a66c45c28eL, 0x0f428bc94ebfb36L,
  46743. 0x1e375cd6e182840L, 0x035d47f9d307bc0L, 0x1c9977db5638ce1L,
  46744. 0x0441c17a429b59dL, 0x11e8f1932b7f181L, 0x1eff0428f6e2fc1L,
  46745. 0x0c1b411e3e3cd17L, 0x0c2fda36f4ab31eL, 0x1c467295ce6b23eL,
  46746. 0x0502a70a7339b79L, 0x1664a985a70e15aL, 0x028261d4536afa2L },
  46747. { 0x0b55283b8fa53c7L, 0x07f9c284a3a7180L, 0x10710df3897e617L,
  46748. 0x01cb4253da469a4L, 0x0abcc6742983243L, 0x140f70b569c4ab5L,
  46749. 0x09c0a8b700075fbL, 0x17698478d6cce16L, 0x0b35e567ea6e8a3L,
  46750. 0x03859e7534b39f5L, 0x1ea70f9b8a3ab2fL, 0x09bcaa6f6fb50b4L,
  46751. 0x056de937dc2ae68L, 0x1c2182112f6561fL, 0x1f71482fcba9b27L,
  46752. 0x0d5ba7195efa0efL, 0x1d2c27af0b169f5L, 0x024b7234ce38e90L },
  46753. { 0x014fc829fa93467L, 0x1bb420759530a5dL, 0x1ebd20cf826f0b8L,
  46754. 0x046d0d7b98cb379L, 0x01f3216abc85975L, 0x0040dc205fe8404L,
  46755. 0x1e4ef118ef6985fL, 0x18b7a03f50d7608L, 0x05a21ece62cd640L,
  46756. 0x1dfb52a1101eae2L, 0x103b7254459ede5L, 0x195eecb744d19d6L,
  46757. 0x09aeab51f9d67aaL, 0x186b431d45d06cfL, 0x1c1a54b052c857aL,
  46758. 0x0896a6a99b9b7cbL, 0x1e84f2b5ccfcb37L, 0x0099c48b98981bfL },
  46759. { 0x068064045003cd1L, 0x00bde2257156377L, 0x067f7a394c53f6bL,
  46760. 0x138f9d52b8979a8L, 0x18f37e0181e34ebL, 0x04c8645dabbb169L,
  46761. 0x129efb3133ec098L, 0x1de178927f2a146L, 0x068074172543304L,
  46762. 0x1607e5935e45515L, 0x0a6d18ed17fa96bL, 0x0a5cabf7b7593cfL,
  46763. 0x060485dff44bb29L, 0x06f523cb2878605L, 0x178e8080b144135L,
  46764. 0x1e68ba59df412d2L, 0x1bd4c8102b46da1L, 0x021175ab9f9c19fL },
  46765. { 0x0592eb6a6ad3f47L, 0x10fb6cb8a5d0756L, 0x04641ca05166c21L,
  46766. 0x04c9d4b006af83dL, 0x14b12723cf7c94eL, 0x1db9b53929bb562L,
  46767. 0x0f373ca9ae9076bL, 0x15b913d12419740L, 0x0f2e20cb45b0fd3L,
  46768. 0x1752d2a6b302cffL, 0x0fea2e2277e2f09L, 0x0fc2cd47e57fdccL,
  46769. 0x1c747312e140f1cL, 0x193cccff84ff5e4L, 0x1f4ac15f466e709L,
  46770. 0x05b8d53f776996fL, 0x182cfba27d7a0daL, 0x01b42a0e7961292L },
  46771. { 0x10d3c9e22799d37L, 0x1bef2d67d199d28L, 0x063c203de56c6d9L,
  46772. 0x155f91bf849cd5cL, 0x0e842dc269b53c2L, 0x033ff43cbaa0db0L,
  46773. 0x161df569bcabeb0L, 0x1e5a04114077a0fL, 0x034b473f0654be2L,
  46774. 0x13e08157a8af11fL, 0x16fe74ab06bd239L, 0x14836d427a01601L,
  46775. 0x0a97e94c11e264fL, 0x0352c37a0b34bc3L, 0x1e49fa427633cb6L,
  46776. 0x14acc0e77f0d38fL, 0x134b89778802241L, 0x02cd2dfac911309L },
  46777. { 0x1d1c91e81347191L, 0x00d5e75cb4cb974L, 0x1d9ea751a9fc61bL,
  46778. 0x19b54fa72e0f110L, 0x191b9aa0da93cfcL, 0x0e9e36045f74f8eL,
  46779. 0x00402099ff5e3e3L, 0x1f7f270c1a12845L, 0x06a6a71aadadb47L,
  46780. 0x055035bd30ab7c5L, 0x0c1780e6122f267L, 0x046e5555226b543L,
  46781. 0x19b13f3bd136ddcL, 0x05662fa6bbf3f03L, 0x133f4da342d72f9L,
  46782. 0x1c1f009b48bf130L, 0x19cf14ef618d3d3L, 0x0233ab260a1f5bcL },
  46783. { 0x1725904b6fff5d7L, 0x199d7c96e23a946L, 0x15d5b482e2a80dfL,
  46784. 0x028775d873212baL, 0x08a2b9b032235fcL, 0x09ae30d17f5a57bL,
  46785. 0x1d21987140c6253L, 0x1e759256d45d50eL, 0x08eb48b15011bc6L,
  46786. 0x147f09463cf6e59L, 0x06f032974a801a8L, 0x0e645e2b70a13eeL,
  46787. 0x0c7a036218f3167L, 0x07c0f04f7f46b94L, 0x1f143641a3ce72dL,
  46788. 0x03c062ee7e02cf6L, 0x0d50d0f7adbed6aL, 0x04506f70b2774c2L },
  46789. { 0x04991bf47366e6fL, 0x026cff4361802a8L, 0x1d46903338dae02L,
  46790. 0x0c7e32c3c429898L, 0x00445e43bbb46aaL, 0x0f10afab53c2fcaL,
  46791. 0x002376e346d5f24L, 0x118d51c8a7d8fddL, 0x1c0367ef8bbaa1eL,
  46792. 0x086c8f8f1f0c084L, 0x13f439f8828b0ccL, 0x1908aa9984eff2fL,
  46793. 0x1d7b628403f1e80L, 0x1ff050be744dde0L, 0x1c001cddde2a598L,
  46794. 0x17da53d3b633f83L, 0x0232ce7fe7db6f6L, 0x03d825ae9774be7L },
  46795. { 0x1546bc782c5faf8L, 0x1a62f475c084badL, 0x01879de1478069cL,
  46796. 0x07d2adaa3e7aacdL, 0x03c3c37c833a101L, 0x00a476639a8b98eL,
  46797. 0x1bd0581dce3ef83L, 0x0ae5d8de177c377L, 0x00aa2ac6ecfa518L,
  46798. 0x194816bb371d6f8L, 0x154227188b5b8c1L, 0x16474dbb005f9a9L,
  46799. 0x15338863723ae21L, 0x146c0c1172a32d2L, 0x01a5deb61446682L,
  46800. 0x04e589e29a0646fL, 0x11c515b081c9c7bL, 0x00e354ad264cdf1L },
  46801. { 0x0b14ad5c2821363L, 0x00c11a68bef0e53L, 0x0b1332b7a1220a7L,
  46802. 0x1304913c4f5debaL, 0x1081d927f412ab3L, 0x05d68fc964e04c7L,
  46803. 0x07ec5be1ef7d1d7L, 0x0ede955b570343bL, 0x0475a7923b75f3bL,
  46804. 0x0ee856b6dddd47fL, 0x1d85912dc2ad166L, 0x1102697b35e306dL,
  46805. 0x0eba9abda32a464L, 0x132b12fdae48913L, 0x06392f933b21c27L,
  46806. 0x10f39a967233c10L, 0x0c9a5c09c8414f6L, 0x039384501185432L },
  46807. { 0x133c0b1f34a466cL, 0x1704e3fcea2dd27L, 0x1fb838a1e17286eL,
  46808. 0x0d21101103ae1e1L, 0x1b043da3824c714L, 0x037a197120b6155L,
  46809. 0x0f871ccf69c4f3bL, 0x0ca56b20c9392f2L, 0x0db62d5b0b35c93L,
  46810. 0x0af5b711f2e0d95L, 0x02d73aec5ad454dL, 0x10d3ee12d2399fdL,
  46811. 0x1b61a85bd59e081L, 0x1d7081fbe432fcfL, 0x119fa77c5a74f33L,
  46812. 0x0a2272a4b88e6e6L, 0x1217db55c0b4369L, 0x03a48e3a639932eL },
  46813. { 0x12ed5bf80d2b94dL, 0x16319dd25930598L, 0x1633588866846e2L,
  46814. 0x175d70591d590d8L, 0x19ef9ced317ccf6L, 0x15e6ad16fd94f72L,
  46815. 0x0c8076a9f626390L, 0x1b927c52b90b2e9L, 0x069e75784d9fc5aL,
  46816. 0x162384f809551ddL, 0x0a7cdf2174f2e75L, 0x1c4ba7ba957a3fbL,
  46817. 0x010b3ba22ee5487L, 0x03746e5d807ea58L, 0x19a19932d64524fL,
  46818. 0x0d6ed6e653f5779L, 0x0416829d1c26890L, 0x045e7e9f2ba0bb4L },
  46819. { 0x0882734d3c8c314L, 0x0597888c3841983L, 0x1f0f01a2e85a57cL,
  46820. 0x10ef248f0f726feL, 0x1f9922275365e0dL, 0x0ffea78aa93f2f0L,
  46821. 0x18e24281a59209fL, 0x15bab167be45eb0L, 0x183446b896af20eL,
  46822. 0x0ebcb85a83a312bL, 0x034819008a9a442L, 0x115ece3d86f3b3dL,
  46823. 0x09057fe91ed1e5fL, 0x0944820c37aa128L, 0x0e4cab7c5376a05L,
  46824. 0x126f17af0021c3bL, 0x1493e18d1e4905aL, 0x029e56e7bde9bd5L },
  46825. { 0x1b5edf75e53d0ffL, 0x1303644455fb38dL, 0x03e04881b457621L,
  46826. 0x0bc456d466c9236L, 0x1173b317b301834L, 0x04f2cad5d33ca5dL,
  46827. 0x093463079619df7L, 0x0a69c20c904472cL, 0x061752e59da55ddL,
  46828. 0x0c5a755cf2143ceL, 0x19e12d247cafb40L, 0x13a43cf2853d95eL,
  46829. 0x0510f262243dcdbL, 0x1328762e1b4a0a4L, 0x06a5d8041bc642aL,
  46830. 0x0208cea854b5d6dL, 0x0b169bd75e9c32dL, 0x048424cb25fc631L },
  46831. { 0x1390cf65a93c661L, 0x031324edaf82b58L, 0x0a7694685e20612L,
  46832. 0x1ecee5bd3525527L, 0x1c71487c1b0cbb8L, 0x11211f3733ff5ebL,
  46833. 0x10be3e6d0e0b539L, 0x1e52dfb4a1d76b4L, 0x0c921b3376089a4L,
  46834. 0x0e996bdc3af628bL, 0x1b4b2b1040492d2L, 0x04138843f6f57b0L,
  46835. 0x0bf6b7de33f6862L, 0x149e49341f0ca4dL, 0x171330337b863c3L,
  46836. 0x01a45a9db7abc11L, 0x1e8c2b75be47358L, 0x01ebfb7fd23466bL },
  46837. { 0x07b290cdffbd5d1L, 0x0ced34b819c6ff5L, 0x0c2243fbb72675dL,
  46838. 0x0a85b9cd1cacd01L, 0x12ae4d82bc690afL, 0x0cadb0428cef95dL,
  46839. 0x087d1584919fdfcL, 0x066cb346859b078L, 0x055771bf5556516L,
  46840. 0x1e3449aaa45d2b1L, 0x06480e524bc8e97L, 0x11c73938c02f6a8L,
  46841. 0x14511e601956752L, 0x0e8b52aa9f83276L, 0x152afb8c0fe7ae4L,
  46842. 0x09cf87c3189fa44L, 0x0e640994d6ffd43L, 0x047d8969fb6ef3aL },
  46843. { 0x06381a2293cb7a4L, 0x104f85c3dbf26b6L, 0x008c1e2b0fbd14fL,
  46844. 0x00af195d229e425L, 0x116ba4dde89ffadL, 0x1ac0502515b4b53L,
  46845. 0x04c1c51a06853dbL, 0x11226b1f2f6985eL, 0x1878969962932fbL,
  46846. 0x0eec28513452d7bL, 0x1c7db7f88e7e0caL, 0x1a5c9e8e933b5eeL,
  46847. 0x17867ca0e95f20fL, 0x1bacc0f64db21f3L, 0x0ac725f9e163b34L,
  46848. 0x068a77d28d4b233L, 0x1b14f9303a206ffL, 0x01fe63398bae91bL },
  46849. { 0x09debd5df21f920L, 0x1870fe0a00dc828L, 0x0ff656992abfebdL,
  46850. 0x0a586f424448539L, 0x1deb926bf212085L, 0x19f8ee0ea649fa3L,
  46851. 0x0f1184bcf93027eL, 0x1a4ac10b4b2b6a3L, 0x02a2f5d62f10fdbL,
  46852. 0x06eb167ef8659e1L, 0x10928dac3c952d8L, 0x00baac8c256e2a8L,
  46853. 0x0fa1f5249cc3a5aL, 0x1f3150c45f5f186L, 0x10a64e493b1a40dL,
  46854. 0x10d0aebe1f7595eL, 0x034d41345dcb3faL, 0x03228a37ee38a8eL },
  46855. { 0x0ec633aba1924f9L, 0x1789b00319370f6L, 0x1eb1f943f05eee9L,
  46856. 0x13de7b1c00406eaL, 0x11dc5a74ca53191L, 0x0a095c4aa2d3552L,
  46857. 0x14001b887563f4cL, 0x1860378600af763L, 0x0f1789c696ed1a9L,
  46858. 0x17969afcc2c7d24L, 0x1426e6065efa15eL, 0x0eaa53544cba869L,
  46859. 0x07c058fa801dc07L, 0x0a5d0a6765681dfL, 0x01429d24b5c2a7dL,
  46860. 0x0bbb4db8f0a0ad8L, 0x12e2a7ca4a94d00L, 0x022469eb955fdcfL },
  46861. { 0x056f14529b33989L, 0x1a8de54d740ad6eL, 0x184d2c1d10521a0L,
  46862. 0x1479b3e67767e8aL, 0x1ff6e4a3955ce42L, 0x07554889d6f2762L,
  46863. 0x1bf7f4eab1c5694L, 0x01418c3d932accdL, 0x1108a28b8f6a447L,
  46864. 0x0177ac272a42264L, 0x16c58b438bccdd0L, 0x063f68def979704L,
  46865. 0x0c96f2fd893dcd1L, 0x12c9463c1040bc7L, 0x18f11653631759cL,
  46866. 0x0613e50b467bf32L, 0x1a572497175d92aL, 0x03b440a3ce5b80cL },
  46867. { 0x043a11491767eedL, 0x0dcd6c95fb2edddL, 0x13800e978869784L,
  46868. 0x025466a82bd1445L, 0x0a9ead626360442L, 0x195772e162b1da2L,
  46869. 0x1875d2f01899282L, 0x0baeb71aaeb17e5L, 0x11cff0ee7d08a26L,
  46870. 0x1c8a70ed85b8953L, 0x0497412c61a4b45L, 0x1e98ad99d02b86bL,
  46871. 0x1c9fff0e3ade253L, 0x0ed5f68cd23c920L, 0x1eb941942e741bbL,
  46872. 0x1c300ce26a4c0b3L, 0x026f37600fb532cL, 0x03387580e2f2d43L },
  46873. { 0x173c0af73cdbb43L, 0x07662bf9218d6efL, 0x1504a868e1173c2L,
  46874. 0x052449bbe322f00L, 0x1eac7eff69a104fL, 0x16899121a979c6dL,
  46875. 0x0d1dbf0eced39f0L, 0x1e14d3d28616bc9L, 0x07d932340975a46L,
  46876. 0x049c4cf2eb27767L, 0x0849436c8d17a60L, 0x1264fe96f2d6f70L,
  46877. 0x154bb90b1f23552L, 0x08897beb1774e60L, 0x0eab8c87ea723d6L,
  46878. 0x02cd45a1e5f3039L, 0x127b77f03660075L, 0x028242973b1aeffL },
  46879. { 0x10f3ce5a2f392faL, 0x003b57636483c17L, 0x1a4a12eaabd8c9bL,
  46880. 0x0797d1d3275a03bL, 0x0d950908b01b16dL, 0x09d79c38982e121L,
  46881. 0x0a68319bf585ce1L, 0x04eee6a281da788L, 0x18a31b12a1fabf0L,
  46882. 0x029800102c598bbL, 0x1f67f2a71f7ae68L, 0x0d37d0ccfa6157fL,
  46883. 0x08e9a9e13fd05efL, 0x1c8f574e179d398L, 0x0339b10fd326866L,
  46884. 0x1f160a1a19dcec3L, 0x0c4fb24dc405240L, 0x04c97f0a8fbf486L },
  46885. { 0x054db3138f197aaL, 0x16b4ec3c397cc22L, 0x1ec113c2a0a2937L,
  46886. 0x1d463c918d2f684L, 0x1d98efec9821e1aL, 0x0659d771c6584feL,
  46887. 0x155cc82e13ea120L, 0x0d774b769508e8eL, 0x0a9be080acd50e9L,
  46888. 0x0228f4e77881aa8L, 0x1b9d7f1104c9731L, 0x1d30714bc67ac4dL,
  46889. 0x19a2b0abd26eea5L, 0x0db04154b990df5L, 0x0af30ab2a4b9212L,
  46890. 0x173f63b902d1532L, 0x1e0134ecf4b9c8eL, 0x02d345fd4262db8L },
  46891. { 0x0ff3b45ff0a2bfbL, 0x0fffcaa817c585aL, 0x02156c70309b441L,
  46892. 0x161a773a0829bcbL, 0x026d3917ed16865L, 0x0d9e0717ad12298L,
  46893. 0x03cb9a88bd24fd3L, 0x0c290e2a915c483L, 0x06ab363a8509befL,
  46894. 0x0e50f1d5c65ddf6L, 0x03726100468e5a4L, 0x1c141ab94aeee3cL,
  46895. 0x0581897bc1ff982L, 0x042d6af3f5a0582L, 0x0cdedf12f092918L,
  46896. 0x0c51fa2b91f414cL, 0x03956ce6ef7bef1L, 0x03c567efccfaf7aL },
  46897. { 0x1bf7f15f8520189L, 0x1015063bfb0e222L, 0x1ae77e88b86e550L,
  46898. 0x0e3e94690e73db8L, 0x0814cc52d2d6026L, 0x14f891e6c99c94aL,
  46899. 0x0dbdf79da849017L, 0x1c1c460dd415c6dL, 0x053815218b83a58L,
  46900. 0x0315dbb5020918dL, 0x0894f2fcc6f9c66L, 0x06646fbd0c3fd1bL,
  46901. 0x1690ae48902dfc5L, 0x05d53769792e49fL, 0x02d28a59af2e3c2L,
  46902. 0x19292de215c1f21L, 0x1668cb4b48cb061L, 0x0056c96b9e83ad1L },
  46903. { 0x1b95fedc2ca548aL, 0x063104066c4d5dfL, 0x152cd19b0a011deL,
  46904. 0x07a97d12057d322L, 0x13e681edea3be09L, 0x1a00b0c23dbcca8L,
  46905. 0x1ffa3c8aa3d2c0bL, 0x1ec7de5969a95d6L, 0x19adc5151b3aed5L,
  46906. 0x00e67e8cc6188b1L, 0x0b05ee8f5f623fbL, 0x09a68c84212fb85L,
  46907. 0x1794b90bcf08fa6L, 0x05a854f5af5fc05L, 0x06a99ac6de2d2e8L,
  46908. 0x079da349fd2684fL, 0x1ae8ef4dcaf075bL, 0x04addec50385374L },
  46909. { 0x1f92495e614bbd0L, 0x1d443dc11f1b1acL, 0x07b3f06f5a9dd59L,
  46910. 0x0f1d06b885c48f9L, 0x0ade066a2bfaaf4L, 0x0b699b18a77a705L,
  46911. 0x18e241caea98d70L, 0x01ff48538e3c5e1L, 0x0cac1e5d0bd07d9L,
  46912. 0x0ff9af528a7ae02L, 0x014ff301553b05aL, 0x0d6e546b28ff126L,
  46913. 0x002aebe487ab1d8L, 0x0fdce790f14fd83L, 0x037f3d6828435b7L,
  46914. 0x0f4555a28e0b3e4L, 0x119480dc66fb886L, 0x01bad4427e092d4L },
  46915. { 0x18cbe2e1217f7eaL, 0x10f1543ae36d58bL, 0x1b006f6c6950685L,
  46916. 0x01c9fae795eee0fL, 0x113a0d86678864aL, 0x0983345d75e3326L,
  46917. 0x1654100c97e6723L, 0x0cf727db3925e38L, 0x1fdf36763541e06L,
  46918. 0x0cbfdd85c8d33b1L, 0x09a7a981e72683fL, 0x19003d55188e4d5L,
  46919. 0x01afa63c55c7303L, 0x07e8956def63ae4L, 0x1a20e2807373789L,
  46920. 0x0a6f33fc1bb4e32L, 0x0ec66bb093b3841L, 0x01346c0c58465c2L },
  46921. { 0x1dae35841580555L, 0x19733a39e881db9L, 0x004efb3306ad3f0L,
  46922. 0x05649dd3bc48182L, 0x1fa8e066da4099fL, 0x1c6bf71bd865adcL,
  46923. 0x00502d6b8139190L, 0x0f0fefa62c856e4L, 0x186ef4edb339e4aL,
  46924. 0x0f3bf769d3ec1baL, 0x1eb4def5c1f0ba9L, 0x06741f2f2313107L,
  46925. 0x0a2e7a208e816b6L, 0x021aa8b57126014L, 0x17cafd445c7f8f1L,
  46926. 0x074ac7d7276669eL, 0x04b8419ed4b01b5L, 0x0458139ae02b652L },
  46927. { 0x09bb464e1019195L, 0x0601379fe1460dcL, 0x19b8aff0ec84779L,
  46928. 0x15237bf25f58241L, 0x0d995bc9ec71bc5L, 0x048fff242ebd5a0L,
  46929. 0x189965f19da3b99L, 0x185b2aa5a335f79L, 0x1bae6c7fe8e1b76L,
  46930. 0x13ec140ebf1d68dL, 0x126be57a625cd05L, 0x0499141903047c2L,
  46931. 0x1bc3006c0dd1f00L, 0x0c3b9ea67ab8ffeL, 0x0d50362ccbb3df9L,
  46932. 0x0a084b0454f05faL, 0x1fe5ab45c3f0436L, 0x020071d5025a6c2L },
  46933. { 0x13216495e46e4a2L, 0x176b21209b03a23L, 0x0ec7183b1df4de8L,
  46934. 0x07cbc1585ccb244L, 0x05107ab75e13aacL, 0x0129eded0be20deL,
  46935. 0x08a5996c8bb25cfL, 0x137fe70cf714a02L, 0x1fed660d50621a9L,
  46936. 0x1e14283644fe1faL, 0x0d42e7c591469e8L, 0x0064cf96b0de7daL,
  46937. 0x19967185b127c3eL, 0x0509804de403e3bL, 0x0bc7d3427055f51L,
  46938. 0x143306c5eec8f5bL, 0x0394a42b9acf3a6L, 0x0098e1ed146d370L },
  46939. { 0x0785ff1a7da83baL, 0x0da12e827a21b25L, 0x06f7b00fe04bd05L,
  46940. 0x1501ebe944f8113L, 0x1da251b9c58d411L, 0x1d97991e996b087L,
  46941. 0x020f266ed141334L, 0x1fa33188897e984L, 0x060c261af730e83L,
  46942. 0x106526fe5816dc8L, 0x1e0e2e77c79f201L, 0x1f2f898d21921feL,
  46943. 0x175d75f1546b79cL, 0x0e58747f898a8a6L, 0x105d8569f01d3c4L,
  46944. 0x01fe17241558365L, 0x0e9de8098ad44aaL, 0x038e8d2351a2a2eL },
  46945. { 0x0178f76fa1b382eL, 0x07661bb96ed06bbL, 0x0cab175344c2836L,
  46946. 0x091ae4c45954b55L, 0x0a3bed0627d38baL, 0x1e7667e2a086db6L,
  46947. 0x18f5fd8de9621e4L, 0x0823ecbb5fadccbL, 0x1c3b44a8560a456L,
  46948. 0x1a3d9d427bc2a05L, 0x1f6b75793583d83L, 0x12182fa76dab049L,
  46949. 0x1f325fc13ad8ccfL, 0x1b247d5c804755eL, 0x114b52cfa435c58L,
  46950. 0x0159672c9fe7449L, 0x121b95cc416533dL, 0x0366934cf88b3faL },
  46951. { 0x18c0b3b12f4f3acL, 0x0e7f14ce8defd96L, 0x13e0c3cdcc9ac0fL,
  46952. 0x06f8b51904a8006L, 0x0d8f144222dd689L, 0x0ba17975b849e86L,
  46953. 0x16b76249e569d61L, 0x0bdc2be505810f5L, 0x07bbdc74916ab7bL,
  46954. 0x187f205d2c565daL, 0x105faf8aeb0e6f4L, 0x134d8c3409781bcL,
  46955. 0x0df27355694b4b1L, 0x18558cb7c99c61aL, 0x0232597a3c0dd08L,
  46956. 0x1704df45df970d9L, 0x1c219eee274c7eeL, 0x0193e031fed1a2eL },
  46957. { 0x1399eff5b47cd53L, 0x0c34e8ca1d77f55L, 0x11ec500aa19aefaL,
  46958. 0x156384b42dcc9d9L, 0x022de271c3e7c2aL, 0x16b52fe210b5bc8L,
  46959. 0x0ccdb9637f320d9L, 0x0f9a2b2a13db502L, 0x0370400f2130bfbL,
  46960. 0x1f2702cc9da43c0L, 0x0e87f8e7cf34886L, 0x0565dd969f0e0c4L,
  46961. 0x166c27b83b72aa2L, 0x0d2fd2df8d7a624L, 0x0c06bc9e90aa52fL,
  46962. 0x0225935f7504491L, 0x056eb6b9d2a3670L, 0x001078ce8e06fb4L },
  46963. { 0x1051a86a4dbba20L, 0x075e36d8ef2e29bL, 0x086799496102d86L,
  46964. 0x1ba579989b34f01L, 0x10285a249440302L, 0x04313474ff811e8L,
  46965. 0x0451cee4dfb8ce9L, 0x19fc6fdc5e499acL, 0x079fbbfd3a3d057L,
  46966. 0x1dd0b69e66ef7e7L, 0x0163b16c8c5c9d7L, 0x1d7ce41875b722cL,
  46967. 0x068b4f6bba47699L, 0x18c503b81313a1cL, 0x128458152c024abL,
  46968. 0x11ec133a121d759L, 0x144f757e1ff0c88L, 0x03cf39390580282L },
  46969. { 0x12acf252820a239L, 0x1cba75573598831L, 0x1ae92302877ec68L,
  46970. 0x12b47dcf55ac3faL, 0x1980446dd2453c3L, 0x0b33b7aa422ad05L,
  46971. 0x1d6867ca765ef78L, 0x10be4a59418f126L, 0x1e961af3e7743a9L,
  46972. 0x063ce2b3366dec6L, 0x0e153b2f14e3e5cL, 0x0e75424d0a38294L,
  46973. 0x052a9f558c58daaL, 0x1de8af02f4daddaL, 0x0864e74debdfe0fL,
  46974. 0x140ad4890f24e71L, 0x06de428b2b59511L, 0x0000e9e71b80ac2L },
  46975. { 0x0be36b9e145b1d7L, 0x1c9c5004e2b326bL, 0x19f79f03db6fcf8L,
  46976. 0x0d8687ea725cac5L, 0x190897b1951044eL, 0x17bcbe52d5b15c6L,
  46977. 0x0a392c687dc2d44L, 0x0bb239baea8ea1eL, 0x1b4c80e2fffb816L,
  46978. 0x0f69ce3aca68159L, 0x0a92755a0cfb719L, 0x0979e6d27431982L,
  46979. 0x0afcd2c404e7369L, 0x08ea00ca1a6609aL, 0x16179181c6f57f0L,
  46980. 0x0f4080aeb208ff8L, 0x084b3280360790bL, 0x025dc637e2057e3L },
  46981. { 0x120e2ddfd0f8796L, 0x05206d899e4ef18L, 0x1b02a4da71b9a5aL,
  46982. 0x0cc00e4e77fd46cL, 0x0cb8143937e5b6dL, 0x15e0029cf276784L,
  46983. 0x0d4f121ffa7367fL, 0x1d7d715e8880333L, 0x02f124e3b293519L,
  46984. 0x10610c564164e0bL, 0x075bc9c27716421L, 0x0a8a6daa0a5359aL,
  46985. 0x1959120bfc5696dL, 0x087fd348601faefL, 0x10ca09e668fa234L,
  46986. 0x0bb13a9f39f4ad8L, 0x0782e8fea9e9a13L, 0x01b4cd440db53bfL },
  46987. { 0x1ca33721eb1c64dL, 0x19d16f8e940aa2dL, 0x06cd94dc41bfa73L,
  46988. 0x029ef97e9b6fc5dL, 0x0058b37f06c1715L, 0x1a74e2e5ef20b71L,
  46989. 0x0e9d60b14e9fa20L, 0x00529b7bfc5d358L, 0x1795ec6cbc5e67cL,
  46990. 0x011e12f8a135406L, 0x134835aa353e7e3L, 0x14a9a76f846bdc5L,
  46991. 0x003d7a4d52838daL, 0x1c0e5a39dcf0476L, 0x10c72ab2a51d7a5L,
  46992. 0x0a30ee4e3e73cbdL, 0x18b1df08e9f8253L, 0x0279d258190457fL },
  46993. { 0x17b81071ed095f8L, 0x1bfd36d1136a707L, 0x014abecdb4748f8L,
  46994. 0x1c0fb1c623161f3L, 0x03e0f16eb114634L, 0x0f761bdcb1a54bfL,
  46995. 0x087049152ee7108L, 0x0f969d9abb7ae56L, 0x0f96038686df20dL,
  46996. 0x1a9acfeefc37051L, 0x1553e96b1222aa7L, 0x0957a2093be9887L,
  46997. 0x1eb020607a56d71L, 0x1d01192f098a959L, 0x0ba136d26f87061L,
  46998. 0x0f70089e49e94a5L, 0x1fd9e525c030b5aL, 0x036c3a2235368bcL },
  46999. { 0x09d07aabe9a42f5L, 0x098b61bc0e66469L, 0x09b6771a7a847f5L,
  47000. 0x1f11fdd234e34ebL, 0x18d44f124e19e0dL, 0x174a724ce15a6e7L,
  47001. 0x1330817db7e48c6L, 0x1d64ff750ed9e51L, 0x06e1a0f01f57f7cL,
  47002. 0x01f8f9a79fe9dbaL, 0x17129d0b07484f8L, 0x04e0fbd70b0141dL,
  47003. 0x1faf0848bc5caacL, 0x03d63ace87aebc8L, 0x13f14c45fd452b4L,
  47004. 0x01e7b2b472e6920L, 0x00995a4aca97bb7L, 0x01e79c264ffce2bL },
  47005. { 0x00506bace1fc9e3L, 0x10ba133b581ccb8L, 0x0e379cafdecd25cL,
  47006. 0x10f36413ee56943L, 0x0e26a8e1ca8602aL, 0x1279cd482c05c86L,
  47007. 0x18b847bcce6dff8L, 0x1e96d8bb322c526L, 0x151174e1a577b24L,
  47008. 0x1c07e5a82f228f4L, 0x05ebec520c86f7cL, 0x0d76e8fcba55e9bL,
  47009. 0x05be99a60809980L, 0x0a2af41042a92ebL, 0x15829949920a367L,
  47010. 0x00ee11918a80bb0L, 0x1263c67e73c7103L, 0x0159244287739efL },
  47011. { 0x173cde68541159fL, 0x1260c27da085910L, 0x18647cb2871de08L,
  47012. 0x0d51647c800f450L, 0x06b2344a52c207dL, 0x1694a2838d01085L,
  47013. 0x131b36c3961f2d7L, 0x172d8ad71df021fL, 0x11248c58f62d843L,
  47014. 0x1c81b1eba6334baL, 0x03dfcb99b19bd92L, 0x0883824d797cc69L,
  47015. 0x0373ce49e8b2f9dL, 0x140d86f85603f95L, 0x118874549219d63L,
  47016. 0x0943942116a9a3aL, 0x01517261ece7441L, 0x049c59de6351d61L },
  47017. { 0x1e4a16be4ded340L, 0x0fd954074401b54L, 0x181b735ceb2e399L,
  47018. 0x09554caf532e112L, 0x09101b061c3a043L, 0x05db2679827e2c2L,
  47019. 0x0b7d7983ed86b68L, 0x0bf031855d9eaa8L, 0x17402057656f76dL,
  47020. 0x0b35bc849299ecbL, 0x195795d35bad7edL, 0x036b4ab6896f5c8L,
  47021. 0x1b93747ea560f7aL, 0x196d672b3cb80bcL, 0x1a0f01a2b9f83a3L,
  47022. 0x0e683308e8c0f09L, 0x16b24e8c9ed1530L, 0x0367fac52ecf44eL },
  47023. { 0x08c01b003e51f68L, 0x0f9128e97f3eb28L, 0x142c26f62017874L,
  47024. 0x1407c82b6fef331L, 0x007d9798255e907L, 0x029c4b68a4233ebL,
  47025. 0x143d01570ec7a6dL, 0x1b86a002027013eL, 0x0fbbb2fa6d0233fL,
  47026. 0x1b405857f8c105cL, 0x101370e34c5f802L, 0x088999918fbf63aL,
  47027. 0x066ec13f84133d5L, 0x023717243fd423fL, 0x18eceb30cfe0f60L,
  47028. 0x0d5ee78c4ff8a90L, 0x1275f67f8aaeb93L, 0x02ff2564798dbc9L },
  47029. { 0x01aa4bf8b6f401eL, 0x18951d6ae3f6a2cL, 0x1c99bec1ed28176L,
  47030. 0x09384579a8f6030L, 0x09371c95fdd11f0L, 0x123757aa2a53ea3L,
  47031. 0x05b4019b157ee66L, 0x0b830c6f8f8ffdfL, 0x0bafc1d346b83e9L,
  47032. 0x0e1c2c9805da16eL, 0x17b0acd39f9c495L, 0x1f6163099dd1bb1L,
  47033. 0x0249a2786469c9cL, 0x10087973c6e6062L, 0x1de9080a43657c8L,
  47034. 0x17b5b0dc4a992d2L, 0x14820931c89eb2aL, 0x0409bb8b2090e02L },
  47035. { 0x066b25e9c5a8edfL, 0x1c461083c53d6b1L, 0x0df521dbbb7db84L,
  47036. 0x12c4e88c2ebe04eL, 0x1385382a242fa7fL, 0x1b8df79f167decdL,
  47037. 0x02a4aeb6b5ec40bL, 0x068ac5579f4cefaL, 0x0573ebd1751fdffL,
  47038. 0x1fb2c293e12863cL, 0x1c5bbb11f2a25b5L, 0x1360cec4593dc19L,
  47039. 0x02f8f2c0758ccd7L, 0x1300428a98fe2c4L, 0x1a316ea48cacdfaL,
  47040. 0x08dfc9af766c305L, 0x198bf24735cd2f1L, 0x03ce140774e696dL },
  47041. { 0x1cc8203f2b48122L, 0x0248b582562475eL, 0x13727f12217aa30L,
  47042. 0x0f0582003959e0cL, 0x076de250ab83899L, 0x0d5c10399cf390bL,
  47043. 0x12cb85ea96baa38L, 0x06049a51940d782L, 0x0570c5bb7816b62L,
  47044. 0x02891ae67735b03L, 0x0fe27c60fab909bL, 0x078d38cc4e96365L,
  47045. 0x06b51e38bc3e3afL, 0x19f2071df058221L, 0x0f96f909b6f1639L,
  47046. 0x1e8107f3baaf16bL, 0x14f9fd9f79152c8L, 0x03ac039d254f1ffL },
  47047. { 0x127b0578691ca22L, 0x15feb09d150db3eL, 0x0e16b1e5504fc81L,
  47048. 0x14eaa6cc0fd097aL, 0x08a0e24cc5d18a2L, 0x03a6de970b36f3eL,
  47049. 0x010e95b55d430f1L, 0x065bde8898226cdL, 0x114646e53cf4b84L,
  47050. 0x1e0681854fecbc1L, 0x132090a5fb880d2L, 0x017ffaf7cd8f7b4L,
  47051. 0x1608c7f3ff3d0b1L, 0x1a7ea6229690b23L, 0x1a784101b949666L,
  47052. 0x1a65bf7573f4293L, 0x0a89342a7fa8661L, 0x01f9f1a2c7d7b35L },
  47053. { 0x1ec35af951597aaL, 0x1ea5624efb275a8L, 0x16726fd3bfd6d9dL,
  47054. 0x12a2b4526a04ed9L, 0x1d9bb9c3423eca4L, 0x10f84e4534b2a9fL,
  47055. 0x17e63e67ba77fb7L, 0x06571f452ac333cL, 0x1b763875835292cL,
  47056. 0x19a76ee7e20740dL, 0x157a7d9515f6561L, 0x047c618f1a57b05L,
  47057. 0x0cc1433d67c8ee3L, 0x1e418a5773bd972L, 0x038bd8d5b67e01cL,
  47058. 0x052bc883ddbc454L, 0x0ef1e9e17ed6c48L, 0x0320690621a614aL },
  47059. { 0x09a0b8e3284d513L, 0x01aa2f98a829d27L, 0x101d16b354a81d3L,
  47060. 0x183bca1b6f66dceL, 0x0549fc46d80bdcfL, 0x1f83d446cea3ee1L,
  47061. 0x15308a6dbbc4cc0L, 0x0e69c8c3594da95L, 0x1ca8e351dfc9f1bL,
  47062. 0x1e204a6aba30732L, 0x00accc3ccb4d9e2L, 0x096c50ae85d16c6L,
  47063. 0x11876c29c369a07L, 0x0895e8bd6ff2958L, 0x06a98e7ce791826L,
  47064. 0x00b831dc81acc69L, 0x016b968902ac72eL, 0x007ce0e54606c94L },
  47065. { 0x0bbaab367433df3L, 0x129a38ae9b1460fL, 0x03625fc31732daaL,
  47066. 0x16cbc811f227464L, 0x1537345172c918cL, 0x06e504a5b1c42a6L,
  47067. 0x04c99cc4e668c2dL, 0x1119e4ace601476L, 0x15ea60dfa6608b3L,
  47068. 0x056ba583d9486feL, 0x009e275da53e6d6L, 0x1b716cc61f63064L,
  47069. 0x10c65e3eaf48593L, 0x1f3931fc1eda3fbL, 0x19bfccd8e527244L,
  47070. 0x1048137359d8dcdL, 0x0c534bd9ba7098aL, 0x03f18e097a2e9b7L },
  47071. { 0x0281d680dfd2dd7L, 0x165801255b0ec5fL, 0x017e510c7e5c7beL,
  47072. 0x152b39677973860L, 0x0ffbb406660c8dfL, 0x14d086feeafe186L,
  47073. 0x1f46de918c6f9e5L, 0x0ec66dc613dbc27L, 0x176b3bfadfc9470L,
  47074. 0x148c92eee639111L, 0x1c35cc55b13b87eL, 0x1c821c566e8ee83L,
  47075. 0x13efc4d93c4f64eL, 0x1e27dd97435f496L, 0x1f286ef14edf80fL,
  47076. 0x174c15832d9ea66L, 0x1574de41a307e23L, 0x00d10ce229936a9L },
  47077. { 0x1cf7ef8aa4db0bcL, 0x18c033db64cb1feL, 0x019cf62864bcb88L,
  47078. 0x05ffb8eee384c72L, 0x02fc0edbc0cec2eL, 0x063021ccbe471adL,
  47079. 0x00481e3843b060bL, 0x11dfa1bc5965619L, 0x14d6c457f69e57fL,
  47080. 0x09f34d92da9f8e1L, 0x08cc2b13e272e25L, 0x06532aacd7cc845L,
  47081. 0x0d437442d192ff2L, 0x1f534a01b9e6a81L, 0x00c198bc1339642L,
  47082. 0x17f26d582a6fdf0L, 0x12fe02bcf77b6d0L, 0x00bd554ccde480cL },
  47083. { 0x13d56438e55db2eL, 0x0f7219dca342886L, 0x03956e2118be0d7L,
  47084. 0x0bd42fc4f834288L, 0x1d95f7a9a6ff3b3L, 0x0b396791fcce1b6L,
  47085. 0x11701c85ff766f7L, 0x04be801583dba40L, 0x094b55c874ff06bL,
  47086. 0x1225072872524dfL, 0x097a46d0eda04c2L, 0x1bc2429f2d8bd12L,
  47087. 0x0c0f97fa9778bedL, 0x12dfe93387a2b52L, 0x1d823be8a3f61aeL,
  47088. 0x0e97876965b1f7cL, 0x04afbd5ff8c2264L, 0x03594157852f9d9L },
  47089. { 0x0fc025f6341a595L, 0x01c6b5222f1463cL, 0x18f7ad11a109647L,
  47090. 0x06eaa8f066e57adL, 0x083e16c43f9466dL, 0x13d65a488a0a698L,
  47091. 0x1ed905176519a56L, 0x162205bbe131fa5L, 0x02a2b2d2d0bfd87L,
  47092. 0x0f4df2e2ca2a844L, 0x1e2fd2a0091779aL, 0x1ad16460d61ddc6L,
  47093. 0x06c2be9f3d80b0bL, 0x04016122bb52a2eL, 0x104b7ed0a7459edL,
  47094. 0x12ec427cc884e56L, 0x0bfb664f529ee8dL, 0x036a7ae91aa3837L },
  47095. { 0x1c8f2b600ba9f88L, 0x003f03ddb685f9aL, 0x150acee0796ff72L,
  47096. 0x1d4f58f03c1424dL, 0x137dcba6335ce6cL, 0x04b2439f184737fL,
  47097. 0x10d340a3729898fL, 0x04ce5d74afd1030L, 0x1a9e3d59f79b78aL,
  47098. 0x17853ee9783d751L, 0x1919e093417dd34L, 0x02e0022dbd6dc1fL,
  47099. 0x1258f37580b2085L, 0x1a0385d9ce152f4L, 0x05df6439e2f5e95L,
  47100. 0x10368aa3f90e573L, 0x0ad6eda93c440dbL, 0x0255785a7eb2e9aL },
  47101. { 0x1ef25063514c7afL, 0x13ed6de0c0f56cdL, 0x1a1e3e8fb162c27L,
  47102. 0x0a2e770d0bde795L, 0x121d32ddd8dbfabL, 0x0ce233592487e04L,
  47103. 0x16f6d3bbce1ae2fL, 0x1b7839baa5f40c3L, 0x064de989a25bc04L,
  47104. 0x17cc1b5c2b9431bL, 0x16a0122f912a801L, 0x1c9c12e0318e234L,
  47105. 0x17b2c11fb116dedL, 0x1390f66cb95762bL, 0x1afcea45136b786L,
  47106. 0x029aff338a4d7adL, 0x137a1d4165b1c2eL, 0x045965e9cc15e31L },
  47107. { 0x0ec1bf28a52e991L, 0x1017b67cea17614L, 0x04c318d3a9142e8L,
  47108. 0x078aec5739060faL, 0x087c2a2d3fc257bL, 0x0ca4455e994c68aL,
  47109. 0x01b4b2853c69e8cL, 0x1138e1952760d74L, 0x19aa3f4b3ee405eL,
  47110. 0x03277599aef7573L, 0x17d5e00efc75333L, 0x016a8ac2d7fba2aL,
  47111. 0x06086e33f6041ecL, 0x18121e7a91efc07L, 0x1333560e669e723L,
  47112. 0x190630d85049d0eL, 0x070220eeaec8fc5L, 0x02bf141823edf1bL },
  47113. { 0x060b698fbcdf666L, 0x0354cc5f5d8e937L, 0x16ea012610daf74L,
  47114. 0x1ca457911a80895L, 0x08423b20d76bf75L, 0x1cc53932ae25cd9L,
  47115. 0x1d8059703d2494cL, 0x0b4eda9e56e1946L, 0x1469899252030faL,
  47116. 0x159bf43db02a382L, 0x1bdcc54f786cbe5L, 0x19195aa9de0bdf2L,
  47117. 0x0aa93617b05ecbbL, 0x1e5d10bef5944e8L, 0x1528b5ceb03ef55L,
  47118. 0x0c0c7a1a796ac33L, 0x1a6e8bee9d4c91dL, 0x02789701bb4b7feL },
  47119. { 0x0cfa42215f1a610L, 0x12e2a9bc328cd26L, 0x1151ce0e04d2012L,
  47120. 0x0896509c54248d4L, 0x146d1320fa15b48L, 0x14507d1b2326328L,
  47121. 0x0013bedaea231c2L, 0x0d4e9cf9dcf2789L, 0x18c34d22cb95ae1L,
  47122. 0x0cf6c4ffce0ea6eL, 0x0219b4c8094dc67L, 0x056537ac8894c34L,
  47123. 0x0cf277bab145b23L, 0x14a245817c44749L, 0x1487b2dcf9a71baL,
  47124. 0x15f643492dd52b6L, 0x191a8f78ea75858L, 0x041e9199f589337L },
  47125. { 0x063328867b478d7L, 0x10d70a8517e4e0eL, 0x0cc06348906e87bL,
  47126. 0x111279ad2c0b6d5L, 0x08117a8769f1f28L, 0x139ebb8aceb3305L,
  47127. 0x17c2ba0480465c3L, 0x164a51fde0127eaL, 0x1b3978db8d854dfL,
  47128. 0x15a1f7b7a2ecfddL, 0x192ffb56fb8e5f5L, 0x1eb2d7eedb5a2fbL,
  47129. 0x0e3d40754ca01e0L, 0x1c7437799459140L, 0x147961a3b6d848bL,
  47130. 0x14ab7044d6d5f6fL, 0x021463532152f40L, 0x039b1789f62d18bL },
  47131. { 0x12eb27c73c0c430L, 0x0532fd28e1b2bbcL, 0x1b3b48653c6e330L,
  47132. 0x110296928ea14b9L, 0x0b6fbbf41894568L, 0x1543045df8540d2L,
  47133. 0x1e578ddbd3d63c2L, 0x1abb26c3ad0730eL, 0x1b6510cd8e3a8d0L,
  47134. 0x1f17edfdb60d22aL, 0x04553abb2247e58L, 0x0e2bfead1ec8592L,
  47135. 0x172f2b399e0eb1eL, 0x04f85f85f3d7ce6L, 0x060da547f0e6eb2L,
  47136. 0x04151e10c3b2521L, 0x0add9b16f02da0aL, 0x01788349fd1c607L },
  47137. { 0x1a6ce910c06ded2L, 0x0421797ec843d83L, 0x1f5aa7d8d69be5dL,
  47138. 0x023dac0c4dc8d17L, 0x169ee54804b6189L, 0x0b51008fd97c4f9L,
  47139. 0x0ceb272f4444f72L, 0x13cceb359fc21acL, 0x164ba66fc8faa62L,
  47140. 0x1435724a3f9c141L, 0x10e81756736a669L, 0x162811d45edd051L,
  47141. 0x04af3953c87c7afL, 0x0ed54f2792a8e47L, 0x1bc65016d4f49e6L,
  47142. 0x0f9b63dfed1a95aL, 0x0432775dbdd9643L, 0x04c2fc1f227f3d0L },
  47143. { 0x1603c16eaf45294L, 0x188b06125aba8c4L, 0x0060e75ad4b5c04L,
  47144. 0x05db28668098224L, 0x14f41b687079cf0L, 0x0560f0862d8145bL,
  47145. 0x13c38f70fc1da72L, 0x044b58bdd47f164L, 0x0ee6684bae34c5cL,
  47146. 0x092cf31cd5e2295L, 0x14b347a77d17329L, 0x1926348879f560fL,
  47147. 0x0992c003b307019L, 0x06c65e17347eed5L, 0x1e0729cb67c5e70L,
  47148. 0x18f3377e2b4de3cL, 0x0f154d779d550dcL, 0x0064472a007f4b1L },
  47149. { 0x0f71a6ae8f44357L, 0x1a5fb1d1e55b542L, 0x16796baf1a03dd6L,
  47150. 0x0914ea7de466993L, 0x075e3c8ececaf08L, 0x07c69d71400a608L,
  47151. 0x0cabaee7568e3ddL, 0x124eb3108c9701cL, 0x17b328e6ff2bc37L,
  47152. 0x1dd8fd7f76870cbL, 0x1ab25568cc196baL, 0x1b1f245b79d0ce9L,
  47153. 0x05987b907a8c19fL, 0x1d9d166bc60bd74L, 0x01ddcbe27ccd89cL,
  47154. 0x19dadd75d4033f5L, 0x1154e5de4993a25L, 0x04712b05c578883L },
  47155. { 0x0d3746c3141aba6L, 0x083cfdd5967cf2bL, 0x00c673749f1d168L,
  47156. 0x053bfb2a1d6c705L, 0x1a9408ff2223763L, 0x0b008c0f058ae69L,
  47157. 0x0ee9d26a00802c4L, 0x1aa4e33b6bb4707L, 0x16078340a651046L,
  47158. 0x094ea6f4ba91d8fL, 0x00d1723828a2ae2L, 0x158415be138e808L,
  47159. 0x052331d61161275L, 0x09c8e5285a0d593L, 0x0488c548c331df1L,
  47160. 0x13453117c19251fL, 0x0e5fef3d92b92fdL, 0x02c802f91419279L },
  47161. { 0x1b1750c3c4c1c74L, 0x1d56074b37dbcb5L, 0x16499b165cfef9cL,
  47162. 0x04750cad6d0b4ebL, 0x10446cde8c97f93L, 0x19c4bf95b821d8aL,
  47163. 0x1cac952245bdcffL, 0x1cd227ba0396316L, 0x0d0a751f1488c0dL,
  47164. 0x08bab8a42ac652cL, 0x050c0512998f686L, 0x015961c10c312eeL,
  47165. 0x0cf39ead9c2df19L, 0x0b9c16d080407e0L, 0x18a8ce00216b1b8L,
  47166. 0x15d1bd2f230a264L, 0x16ee4495936b43bL, 0x02bd3c7136bc1efL },
  47167. { 0x01b346f40dbddd8L, 0x0d493ca0861d60bL, 0x1e0c621b3cecad2L,
  47168. 0x0467727bd718a84L, 0x00df579d72df323L, 0x077a804e46acfaaL,
  47169. 0x0190f975e99f708L, 0x18788d67230cfe1L, 0x0ecfa2445ad96adL,
  47170. 0x0c7ac4d8622a268L, 0x124c0782105f5d9L, 0x1ed588a9c511cddL,
  47171. 0x0fac0f462d6ca5eL, 0x046c501b20c8824L, 0x14d6dfa14901f60L,
  47172. 0x1b50f698a674fedL, 0x0e83251e4128f6aL, 0x00e51b862c0e239L },
  47173. { 0x0bd5171a801b68aL, 0x143ce7e8ccc59caL, 0x0afd0458c809cc4L,
  47174. 0x09eb603fb6920b5L, 0x1cda128bb5fe87fL, 0x1e98fbbc6f291d4L,
  47175. 0x130d42fc586871eL, 0x05b6bbd9fa04720L, 0x0224b2882e188f1L,
  47176. 0x0e9400efcced73aL, 0x119ed4233473483L, 0x187b810cfc7395aL,
  47177. 0x002b4250726c311L, 0x177ec801b8d08b9L, 0x0f4ec0e0efd1938L,
  47178. 0x0b754a7a089143bL, 0x07932db52f4e626L, 0x012c259a62619d6L },
  47179. { 0x0b863892aeec688L, 0x1a05d22fdf2919eL, 0x07dff582d7e2979L,
  47180. 0x1890e9227a845ceL, 0x1a17d80d455d185L, 0x02a29202615d9b7L,
  47181. 0x0995cfc9c6152b0L, 0x190edba608b5173L, 0x02e42c3e162ee7cL,
  47182. 0x013338326fb63e8L, 0x1f754771f2d2200L, 0x157c30f12fc0b24L,
  47183. 0x0ef2d5737c6b3faL, 0x1fa8d4ffff35691L, 0x001eeaabed809a7L,
  47184. 0x14935c3906a8ad3L, 0x085acddb6ff951cL, 0x03f4089ba1fcd58L },
  47185. { 0x1722a8b830a88b1L, 0x0c75467088bf0d6L, 0x02e01026d1f6464L,
  47186. 0x06d88da3a67c05aL, 0x0589669cb53812dL, 0x1866af17e84ed87L,
  47187. 0x1114e6117341856L, 0x19618382ab4470dL, 0x1da774de5f5ff43L,
  47188. 0x183b5cc71c8e066L, 0x1c7bfd4013ca1aeL, 0x08d95dd817fd2faL,
  47189. 0x0732a1ad9423e0bL, 0x1cb6d2117229c33L, 0x16caffbf8327e04L,
  47190. 0x1f522c6ed8344c7L, 0x1a6001c7918ba56L, 0x021b5c6326fc242L },
  47191. { 0x0117e9d8ab764bcL, 0x10f4a503befc244L, 0x174c3063baf77e9L,
  47192. 0x1ff928a3b8b4eecL, 0x071a347a548916aL, 0x1da0ef80d297198L,
  47193. 0x10a198cee577ac8L, 0x0d1bafad1928791L, 0x1e4f9d41e18d970L,
  47194. 0x0c845c846493cceL, 0x10523b51ce528deL, 0x0a2f9aa3ca7fcc2L,
  47195. 0x1e0243dcb6e5018L, 0x0bcaa202a83003aL, 0x1f697ff97737988L,
  47196. 0x196ccdef921c2a6L, 0x1e11df7aae40768L, 0x02933654f36df4aL },
  47197. { 0x0ddee6d1386b3dbL, 0x057ad3e1c72a042L, 0x1103ac13d277e79L,
  47198. 0x11fbcb49fb66830L, 0x10257cfc2138a1eL, 0x1eb8609f3734921L,
  47199. 0x07fc0d4671b8c67L, 0x1d11e69c2e90d86L, 0x0f1e298fd940ce1L,
  47200. 0x1dc658e8a4b06beL, 0x104d1cacbceffdbL, 0x016828ddf1fe40fL,
  47201. 0x0b7bd3e220899a2L, 0x1135f513bef61b1L, 0x0d32d9ea5d41139L,
  47202. 0x0e0741e6568929fL, 0x02bc17a09201fc6L, 0x020f992dcce6c25L },
  47203. { 0x12ed513ce2843a4L, 0x024c70039457e18L, 0x0089361933979d2L,
  47204. 0x094c40107751de5L, 0x0bed338d3406470L, 0x1f3d9c2c82f0ecaL,
  47205. 0x1eee4a95e32d418L, 0x083304edb2c513cL, 0x0dfe2dc47f17b73L,
  47206. 0x091a90f8ed644a2L, 0x1b4a348d002a9d6L, 0x00bd4ec374867b6L,
  47207. 0x0d9bfd07ddc6477L, 0x1216547ec4a3dd3L, 0x030d1a003cb8eb0L,
  47208. 0x031fa93de8ce1d7L, 0x09e7db3d37bd9aaL, 0x02b5987db72c675L },
  47209. { 0x1ecdcaacd80a428L, 0x0916e4399644883L, 0x1e60eb69107debeL,
  47210. 0x092496011441b10L, 0x12e81c3a3bed9a4L, 0x1c03e99091a99e5L,
  47211. 0x0bb2f0d3901d597L, 0x11a17f5df4a3e5fL, 0x178b634a5ade8a8L,
  47212. 0x0705bfc4a1c9548L, 0x088dde42ec73631L, 0x09f5f0e4095c612L,
  47213. 0x1585d3cd83dea9bL, 0x03291d3c9f6fc0fL, 0x10365a563e23147L,
  47214. 0x0fe0fc8e5f7162fL, 0x146899081e5dccfL, 0x009a9e62bac5ee8L },
  47215. { 0x0a5649739bf6e18L, 0x05ad1324dc4e394L, 0x128373a2e39d67aL,
  47216. 0x02408e08191b286L, 0x0a7b8e82d935bf5L, 0x1c094a1559d0b23L,
  47217. 0x1ca5fc560fb589fL, 0x057082d4fc0e5acL, 0x149685d86cd39e4L,
  47218. 0x13cbfe3cac6edd6L, 0x03e4a055739b7a2L, 0x0ae1f146c46b4abL,
  47219. 0x0052877ae575f4eL, 0x1358b75ede34e7eL, 0x07307c63d064ea6L,
  47220. 0x1cf131a3be87976L, 0x158723a830e5a21L, 0x01f610c2efa28efL },
  47221. { 0x1d4c7d71f0bc2d7L, 0x163663728ea095cL, 0x164e827e03d9a60L,
  47222. 0x0a08f5c13925c05L, 0x17f351f9b7dd2d2L, 0x1c285f1a818a4f9L,
  47223. 0x14b21a75273871dL, 0x13ac048559625e1L, 0x0ba188c567bc28bL,
  47224. 0x1203090835e02a8L, 0x012c7e35f50ca63L, 0x15cfa712a3c161bL,
  47225. 0x1b8bc97607b4a67L, 0x0a4bd5395a93e2bL, 0x0f7599af24f17cdL,
  47226. 0x08f46be3bd19873L, 0x1e53087dc5ce9d4L, 0x044d9ab5b5108d5L },
  47227. { 0x16db0afdfdcc837L, 0x005d55438dbd4f6L, 0x1f2470752dc83eeL,
  47228. 0x0f5b593cb882757L, 0x0b8657a3f5b56bfL, 0x00eca72b32516d4L,
  47229. 0x0d96046c13dc839L, 0x1d4c7c23a4c6e86L, 0x0ee628ecef426daL,
  47230. 0x08b0ce4e58b16e1L, 0x1605fe1d92190c0L, 0x0e04ab09790d39eL,
  47231. 0x0f00bf7928e1bb9L, 0x0e30777296613e7L, 0x0b70be53bcea03bL,
  47232. 0x09ea4fc24057d0fL, 0x126656f18e08a0dL, 0x01ce27886abe2e8L },
  47233. { 0x1a9b68ce88aecd3L, 0x1848c528c554ed9L, 0x16b52f53b951556L,
  47234. 0x0e040d1b09db839L, 0x011ac72d79b68b6L, 0x0d053c3ed640684L,
  47235. 0x18a0db479b4d6a0L, 0x0899083d3d477a2L, 0x0a7bc1775894c44L,
  47236. 0x15b1b92f8d50901L, 0x1dd9fb1f53155bcL, 0x1767a8dfea377d8L,
  47237. 0x0d73f7e3392817eL, 0x0d7692627ef2df4L, 0x195e73d131b25ddL,
  47238. 0x1f79817342e0f6dL, 0x100cff164789069L, 0x020a5aa16a48a95L },
  47239. { 0x1c31e58606e173bL, 0x1a70dc873389d19L, 0x144b7aec82bd6dfL,
  47240. 0x0e0a241ce084bf6L, 0x1013e4ecc788c61L, 0x03736b9f782b014L,
  47241. 0x1a42a7e74d6b207L, 0x05dc263d11f28a0L, 0x1708f9b3244af08L,
  47242. 0x1726b360dd15754L, 0x1d29b9d036ca72cL, 0x0491a308600f5e3L,
  47243. 0x18ed556a6c74ab9L, 0x13868bd30999c77L, 0x023d6ffd23988f8L,
  47244. 0x10a2a78e6c5f52cL, 0x12a43977874444eL, 0x02933c6b57005c5L },
  47245. { 0x1ff1c59df36aeb4L, 0x1329e5495e055aeL, 0x125a49e97e054b5L,
  47246. 0x085bfa923e1c07eL, 0x0571f89b8509d41L, 0x19a24292c616295L,
  47247. 0x07824af5860124cL, 0x00c3467d29e7efbL, 0x0fab418d32c1bf9L,
  47248. 0x1ce24872d52b4aeL, 0x0465bbdb4b5fffcL, 0x00ea1ef291521c8L,
  47249. 0x12d3053b4f3ecd4L, 0x0eccba64a5ac7cdL, 0x08bda0ae3ba10a9L,
  47250. 0x19d4c474b383b7eL, 0x0dd045ac614c8efL, 0x038205d2de08677L },
  47251. { 0x0364f81515a1a96L, 0x11a818c2193f016L, 0x19406b64f53cc69L,
  47252. 0x024e76c2e61412cL, 0x12cda9d29d7694fL, 0x0a60bbc4436c3b6L,
  47253. 0x1a5ac78069d08a0L, 0x00c69244ed70cceL, 0x02fd4f0c65b25f0L,
  47254. 0x0939a4ffd94a625L, 0x18362b7874cdbd9L, 0x07d1cfc70c1d83fL,
  47255. 0x01b774c31eaf9a2L, 0x01b2bc254be95b9L, 0x1d3aa8feb0f9609L,
  47256. 0x06491fe5bfe9ce1L, 0x1c13d281e1afe87L, 0x04821d36b05e8e4L },
  47257. { 0x111a0fe766c7937L, 0x0f6ae55de1df18aL, 0x0333802222b06cbL,
  47258. 0x1ac2c401e65582cL, 0x14a2ea06928754bL, 0x1f0837dc00e41e9L,
  47259. 0x136522b5e80ea72L, 0x10132d610459dbfL, 0x1c3c3463ae40698L,
  47260. 0x1897526facbfb31L, 0x14e0d10324abe7eL, 0x0b8c9d1b42a8591L,
  47261. 0x02db4e801a79bc8L, 0x0f1abcd94abb8fdL, 0x0ab41e1ef4b04e0L,
  47262. 0x1588dc8b8ebbfffL, 0x135b0760a3cb73eL, 0x0131b15a41d092fL },
  47263. { 0x1c68d28eefc3e89L, 0x1743bb4f4f73892L, 0x0e1abd792dd4b43L,
  47264. 0x05970d6667160f7L, 0x1f552bacdb70907L, 0x06d0f4fe9e90757L,
  47265. 0x1c51697bacac530L, 0x10a723ed11489f2L, 0x121fbd3101e06d4L,
  47266. 0x0f27952df54e6a4L, 0x0351929efc87691L, 0x11900a9aa8e2f6cL,
  47267. 0x11bee0f2e9193f8L, 0x00a1c939ad6729eL, 0x11ad7ba4b09958fL,
  47268. 0x0b375390dc1652dL, 0x15e452fe23109ffL, 0x0174a95902aae49L },
  47269. { 0x0846bcad75f886eL, 0x12edf6a1efe2c15L, 0x16d801ec6e1b9a2L,
  47270. 0x126abfe56a207c8L, 0x0263ecc9580e2ecL, 0x0f2f19de3817935L,
  47271. 0x081d8a0d6ce1860L, 0x0da04a227d8d824L, 0x1a5c26e3a7fbd85L,
  47272. 0x17c1fd9ceb75e58L, 0x094fca9134bea23L, 0x1e66a763f52ef55L,
  47273. 0x1117559a307c14eL, 0x1849bbf07fb0250L, 0x0bc09ccaf365ac2L,
  47274. 0x1de0d4b82912db6L, 0x04b1c0a84c9eb53L, 0x0091b680b981bc7L },
  47275. { 0x1481c8fc084373bL, 0x123b432304bd76bL, 0x1e8184ef0d2ca6bL,
  47276. 0x19269785602601bL, 0x0e2be7e23712714L, 0x008400432923148L,
  47277. 0x115d9553eee7fb4L, 0x105e1d816708462L, 0x165baf594330a32L,
  47278. 0x1eef0d438377c0bL, 0x11c9f6e9d4c3a4eL, 0x1acce9992b96fa5L,
  47279. 0x052438906dbb0c5L, 0x08a32c79d9fe69bL, 0x05fc3a466206507L,
  47280. 0x18fd5cc2deaaad9L, 0x16e353c2d854b9eL, 0x00152400a31065aL },
  47281. { 0x1d6d23d506ccd38L, 0x10e2a482cdd5308L, 0x109da74047148a6L,
  47282. 0x0db05126fae2f93L, 0x03835083e87e1b4L, 0x0d612c7aeb1dddcL,
  47283. 0x1347fc29ed09eabL, 0x1fb33564d7b3e2aL, 0x0dec0ffbf8ec955L,
  47284. 0x14abe33a4fe5c40L, 0x0577b87804537bbL, 0x096e6d3e8d8e647L,
  47285. 0x0091eb2599192a6L, 0x117461ed2182233L, 0x155b462f8b6a21eL,
  47286. 0x0ebe7489c584b86L, 0x1e031390414b55fL, 0x00ec5ef37c790bfL },
  47287. { 0x1cd39f8a2028924L, 0x078ce583765cf81L, 0x12df5bc16119b95L,
  47288. 0x0cb40c0eed0c577L, 0x110fec10dbe0671L, 0x0ddb2e49cbe4bd5L,
  47289. 0x0e8e3d084e099bcL, 0x1cc829bd9974ce5L, 0x1594d4d43f88b05L,
  47290. 0x0c9fabd564a6a68L, 0x10a9aafec5d8e1eL, 0x16b76df8cab4e9fL,
  47291. 0x04ee8d2139d8196L, 0x1b069d136e1bae4L, 0x0e4ee1ee6c02808L,
  47292. 0x0413d66dda6b9bdL, 0x1c1f565b28bcc83L, 0x01a4e34a1e30809L },
  47293. { 0x1b394444de6c88aL, 0x16238a380103f68L, 0x0288870ade03570L,
  47294. 0x0810a1327d6de8bL, 0x1aef0c18749f756L, 0x1e38782005d2bcdL,
  47295. 0x1fafcb5d0a4e1cdL, 0x0a78b51c5d8428cL, 0x0243a666e5337f4L,
  47296. 0x0c8f8e3f685ea85L, 0x1cfa43d2f47e472L, 0x1d14be1c253674fL,
  47297. 0x170738963596089L, 0x138c1564e869d0bL, 0x05f170a73e10b54L,
  47298. 0x0aed24232a53210L, 0x0faa32f327e8725L, 0x002b2c3d5c4e16cL },
  47299. { 0x08562ed1ce4733dL, 0x1fbe5cc728a2200L, 0x087ea6ad1ae57ebL,
  47300. 0x1d6c351826be060L, 0x16b3597689494c5L, 0x01697b2be4a81b1L,
  47301. 0x1c0f9afa1323cabL, 0x1761cb669b137a4L, 0x1c4ad918f7e872aL,
  47302. 0x1544f4fe2029770L, 0x0bb8fcc642d47b0L, 0x086edffe4a9f859L,
  47303. 0x08883e097258fd1L, 0x07d8aa1c379e06bL, 0x12ab8018f4283a4L,
  47304. 0x01ed98870ec97edL, 0x1de815f15653f1dL, 0x00dc3f976dc366dL },
  47305. { 0x1792bbb2b0b15b1L, 0x05ad3e735d3bc9aL, 0x1f67763cdde68f9L,
  47306. 0x1b8531a3dff759fL, 0x047031c6005450bL, 0x0b4033071faaab6L,
  47307. 0x14b081dc3c1ea57L, 0x0a99c7d09c05a20L, 0x1b050791e7aa8ccL,
  47308. 0x0b10f39dd1911d1L, 0x06e534e58ca6413L, 0x168efd700adb0f7L,
  47309. 0x08edfca0cc8df9cL, 0x0b895065712186fL, 0x0122a64dd2fd05aL,
  47310. 0x1cb3d7c7e78ef11L, 0x023b22b87b1c4a3L, 0x0470113e21f4adeL },
  47311. { 0x00e22a83210964dL, 0x0aefaff82b77580L, 0x087f6bc7ab5f733L,
  47312. 0x00cf9b95c6042e7L, 0x0bdcc90cd02833eL, 0x125a7a8e62ba65cL,
  47313. 0x00a621bb29c50c8L, 0x1d7a01cc075767fL, 0x1b98ece1b0c1a8dL,
  47314. 0x14523721bc6130eL, 0x077436985979748L, 0x113296fde1c58dfL,
  47315. 0x13bda9f306b3ae3L, 0x1c50426d9d1e0b5L, 0x053a5417a689b4cL,
  47316. 0x00d78a51cb326a7L, 0x16e848ecb114ea2L, 0x00a58ad5aa02a2eL },
  47317. { 0x16d86c9664c59a2L, 0x115f0b07ebd5287L, 0x15a641cb2e38f7fL,
  47318. 0x1302ed4fc067f36L, 0x0587080b5f2325dL, 0x0ea702bcd06a73aL,
  47319. 0x0a38693b837bc35L, 0x1dd815b3ff590f6L, 0x1d6f18d2f3f09b4L,
  47320. 0x044b57394974ec3L, 0x0254f58251d8f33L, 0x0f5031f7f3f5951L,
  47321. 0x094b63d701dbee9L, 0x03f53917ef90707L, 0x0ad5c7f2ee9b8c1L,
  47322. 0x0abeb9cafc394c2L, 0x02e1e16ac76009aL, 0x03a15df6c621c4fL },
  47323. { 0x1ea86dcc1dc2c73L, 0x1feade0b21d5f91L, 0x087c9363287d2eeL,
  47324. 0x01196b958e0ff1fL, 0x14e66a7dde68a6eL, 0x1bd6bc3eaa6325aL,
  47325. 0x0ae51e276e88aa6L, 0x0229b11aa81c6c9L, 0x0c8c2e02d1f72e0L,
  47326. 0x041302ba371513cL, 0x0d6ecd2c61f1f53L, 0x1bfdd71fc193cd8L,
  47327. 0x087d11e415ed8b3L, 0x1c32e3fcdb5e1a7L, 0x1b305f2ce422efeL,
  47328. 0x1ad36e2fa39cdc3L, 0x124151e3308f7cdL, 0x04bdead0a5ae4a0L },
  47329. { 0x01c62fe81e82861L, 0x0a5b6eea1620770L, 0x156f997a4795c0fL,
  47330. 0x08b5777fbafca5cL, 0x072a45f4b8b4937L, 0x0794ec5a78afa96L,
  47331. 0x19d7f3a10d6a154L, 0x12d3beed736b05bL, 0x052e84c5fa20c8bL,
  47332. 0x1bbe9688545057aL, 0x06ef6329804f0ebL, 0x13744df060be071L,
  47333. 0x080cec8b9ab0d9bL, 0x1fd5ed0c7829f42L, 0x10930a9358cd9ebL,
  47334. 0x1745ca1ea77c94cL, 0x069f892c58c864fL, 0x018be3698a4662aL },
  47335. { 0x03525b02cb7d42bL, 0x005e49887d65706L, 0x008bfc81023d549L,
  47336. 0x1fc1821d411aba4L, 0x118eb23d6b01402L, 0x12950cbfdf7b453L,
  47337. 0x035ba8051ad6904L, 0x102b35f9c90221cL, 0x0e9a1d27f022de1L,
  47338. 0x0dcb68b6e1fa4edL, 0x0b8fd7bef90021bL, 0x0c83d9978239f83L,
  47339. 0x19525f8636f9d70L, 0x013b1e182481113L, 0x0418c2cdda5e5abL,
  47340. 0x07e2f398690783bL, 0x0fd451651f0ee3dL, 0x03572cb9cced05cL },
  47341. { 0x1b13bc7bff4d2eeL, 0x0a1149858b9ec2bL, 0x0f541e524db081dL,
  47342. 0x14bdfaab7d6c4a9L, 0x0e0c33891d5f232L, 0x10fca26037a542aL,
  47343. 0x01edf3cb16d6639L, 0x0998ac90c3ffabfL, 0x0ee261fb15a2afaL,
  47344. 0x07fb91316cbd3baL, 0x06b88b5b3c01eacL, 0x0a69a68de428351L,
  47345. 0x1f97b6497e28880L, 0x1d157ffe47f39dfL, 0x1469c9a2a1656cbL,
  47346. 0x170573df39e7de2L, 0x072a84ee5f1e744L, 0x033248246de31ffL },
  47347. { 0x1b7bb781e8b760dL, 0x185ec12d56d5048L, 0x167fead489bf51eL,
  47348. 0x0d7ff8291d02927L, 0x029be3db4a6dd22L, 0x185585ad0197c55L,
  47349. 0x121a0c636f1c0d2L, 0x08db9997f6afacaL, 0x08506ab379c581eL,
  47350. 0x089b53714187671L, 0x1e4d5b3db2031c2L, 0x06efded63d0c916L,
  47351. 0x0183f0f1c9fa176L, 0x0b55f6ee964e0e6L, 0x0ec37925bc149b4L,
  47352. 0x10e747c1d31c552L, 0x1ec6f2d7ada0f13L, 0x0275c9dae79fd24L },
  47353. { 0x189f7e5e11fae32L, 0x0ba7ae2011fa8deL, 0x137d2470fdbf44fL,
  47354. 0x0eaaa4f36e36002L, 0x05ba00681d849a5L, 0x1e51655dcf444b8L,
  47355. 0x19dbe0888906704L, 0x0555f776d0bfa66L, 0x1931c3f5275878aL,
  47356. 0x15777f7f79ea8b9L, 0x097322f629a1e04L, 0x1b67b33e182c313L,
  47357. 0x06a19d48b682cffL, 0x14e362705fab2a0L, 0x00105c95817888fL,
  47358. 0x03990a7cf03bd0dL, 0x168cdf5c90bc700L, 0x015ac16c9be021fL },
  47359. { 0x1165c8281abc2aeL, 0x1c07af15b4f6550L, 0x0f481fffd9be9ccL,
  47360. 0x0ca8eeca0d812f6L, 0x157fa21c5d60382L, 0x06deeaee5d64f9dL,
  47361. 0x1cca9e1d436d326L, 0x0390bc42207b3dfL, 0x1ceed172c2f11c4L,
  47362. 0x071c9324f1a4604L, 0x0e4dae0c7b77eeaL, 0x1a0dea10c946e39L,
  47363. 0x0de93acfcd915c3L, 0x19f97bd57f4719eL, 0x1f3ba692fb8435eL,
  47364. 0x095fb83b1d691d6L, 0x0c04fa49ce3fa57L, 0x03c30a884c316daL },
  47365. { 0x1e3f4807ae72c21L, 0x150a27e8786d29fL, 0x07a3e30e91518c6L,
  47366. 0x08a369e3578eddcL, 0x17cdbb24379ae09L, 0x1eafe6951d21cbeL,
  47367. 0x1bd69e8533ffa0aL, 0x19f77c9da25e84fL, 0x09b0a43ee284d3cL,
  47368. 0x1dbc5c9c776370fL, 0x1013919ee3a1ed5L, 0x180a686e984031aL,
  47369. 0x055428deb50c8adL, 0x01d7d167b21b9b0L, 0x0a55be6d3603b03L,
  47370. 0x038d0daa3f27875L, 0x0259f9a28ab8416L, 0x02a05b5dbb5e4e0L },
  47371. { 0x0e1734c321d315dL, 0x0b3096c3702e802L, 0x0516eea336053bdL,
  47372. 0x1359b8f135d5f5cL, 0x1877570f1fb07a4L, 0x1e29ef3510f4d6aL,
  47373. 0x063acb92a0dfae6L, 0x08a86db65263ac5L, 0x143afbc78ea362fL,
  47374. 0x14b9ecbd55fb2c2L, 0x1f6af832493580aL, 0x11e0f95be1d3b9cL,
  47375. 0x0175020538f69d9L, 0x0230e694f05a82dL, 0x083a060f6df468dL,
  47376. 0x0a1edc3850eecbcL, 0x08c2ca2586752ddL, 0x044be558a49701cL },
  47377. { 0x1ed38130d8bab8aL, 0x09b26521c10052cL, 0x1cb101605057047L,
  47378. 0x14f5912ce80d0f7L, 0x197411a086ad0d3L, 0x019b8e22494082dL,
  47379. 0x00c79d2612c47ceL, 0x1c0e1a5db081a35L, 0x0d883628b6c912fL,
  47380. 0x07c7bfd8a7d4469L, 0x1ca9373c2b24f91L, 0x13554d849f4cac9L,
  47381. 0x03bf6cd94982f62L, 0x10528c16d5c835dL, 0x1ae4e94b208b99cL,
  47382. 0x0e7545fe8fb5861L, 0x0c5dc62c4a4fff6L, 0x0325803b1a3b587L },
  47383. { 0x03f533eb3c9a404L, 0x1bfb9dbf7cca90fL, 0x18a5b094da4ec76L,
  47384. 0x080e71dda98fe27L, 0x0e26cad07ce7f4cL, 0x162e78e67e9d99eL,
  47385. 0x1380761e124d407L, 0x19e7f1f813bb810L, 0x0217cab32c39b5aL,
  47386. 0x16d785dcf7aaa8eL, 0x1dbd5b8485ea550L, 0x1625846e0055f78L,
  47387. 0x1fb070a29380178L, 0x0bb654b205a961cL, 0x15a38db8e49454dL,
  47388. 0x01d084aab284833L, 0x18c291fb82c09e5L, 0x03ee91753330c76L },
  47389. { 0x1fe844b49cbb3bfL, 0x063822ab17d92bfL, 0x14de7d6a116b783L,
  47390. 0x0dca24eff83cddcL, 0x10635718956d7f2L, 0x0abf9a163aea5c9L,
  47391. 0x1d0ace685224a5aL, 0x0e519e9d66505caL, 0x16b0d3ddd83247bL,
  47392. 0x1d4fb19900d211bL, 0x100f04505292159L, 0x088f6ded522c82cL,
  47393. 0x10dac6f79060afdL, 0x1e9dcec14afca49L, 0x12b7c3da17fe52eL,
  47394. 0x0e912b91f31f8a3L, 0x0c89559c88ab13bL, 0x0189bbe332f8c7eL },
  47395. { 0x1c5de097dcfb35fL, 0x0654f80e61b7c1aL, 0x0175d5db2d8cb73L,
  47396. 0x15ef6966eafd27dL, 0x109a19b50c2dd48L, 0x1ff303cecae6a7dL,
  47397. 0x16b49d4bb4565c6L, 0x0de8731019e4b2dL, 0x0e52efb5369e90aL,
  47398. 0x004bb3181e9f305L, 0x0d93eaa541c3811L, 0x076c0ac49ba5f9eL,
  47399. 0x0400d5e467d8f99L, 0x0647a29259ad4c1L, 0x02805e78a274090L,
  47400. 0x1b57bde8a8478c9L, 0x0713a5fd695587eL, 0x01ed66286508f29L },
  47401. { 0x13e4f946499ae4cL, 0x0e5f0b829e293e5L, 0x13a6f9e0ba2a91bL,
  47402. 0x11b0903c8b00febL, 0x0a286fd0b6c64d2L, 0x0e6da4f9af228c5L,
  47403. 0x0fabfdedee6eb7cL, 0x1f7e7f6c4215d84L, 0x00a9ba385b9bfd2L,
  47404. 0x08d06a9c403f9d0L, 0x091012c5eca10b9L, 0x0d0ff3bb3e14f56L,
  47405. 0x14f3e9df646fd57L, 0x106f8ca6e68f7edL, 0x1a77c15774b7de9L,
  47406. 0x114637da7e587c0L, 0x0f7469b75612324L, 0x04334a4f0b4a3a2L },
  47407. { 0x09a0da53f4ab07aL, 0x17999faa537df9dL, 0x0486c8f3ca40b35L,
  47408. 0x1d091c7ab01925dL, 0x13b218abc9581c3L, 0x165a6bc9d78fdeeL,
  47409. 0x00e80e1663a8419L, 0x16aa002729d3218L, 0x13b664b1e7d0877L,
  47410. 0x1ced8ddeba63848L, 0x1510d538b577435L, 0x08366653b7050a5L,
  47411. 0x107b96d4800d2b8L, 0x014aee237d42275L, 0x1dfb138de9415a7L,
  47412. 0x062ef85a706e729L, 0x198dc3884ff5b08L, 0x02ba1a95c458fd2L },
  47413. { 0x12193f70d5d7ce9L, 0x0fe9305a43f57f6L, 0x0d65ef997f40f06L,
  47414. 0x00f04e1aacf8895L, 0x1aa70198dd9da86L, 0x0cc2efc54276005L,
  47415. 0x0a360bb09f924a1L, 0x03b32d995e1bc40L, 0x14e7648c761c220L,
  47416. 0x0b19ade048e0cf5L, 0x08e9a7c359e0aeaL, 0x0681a528c9264a7L,
  47417. 0x01099f68733f204L, 0x14cb008d222290dL, 0x14ea5397f2f3025L,
  47418. 0x147427109abb1f0L, 0x04f2418c624d3b6L, 0x01f218d7903571eL },
  47419. { 0x167d93983d381f1L, 0x00d57686019e1fcL, 0x134151041da0d94L,
  47420. 0x10a1274da77e75eL, 0x192f2900a86d159L, 0x185baaa1d703a0eL,
  47421. 0x1b5bffacabe98dbL, 0x08da1214d47548aL, 0x1336a4fdaaefdb6L,
  47422. 0x08dff220d4a17beL, 0x0a8fb6147b907bfL, 0x0d0c23d26b8aff8L,
  47423. 0x0653bbb3434f1c9L, 0x16c4b61566abbb3L, 0x0efe907c9a4c6eaL,
  47424. 0x19de3141f77a30dL, 0x1351c3d7d82a203L, 0x036d69f8af13326L },
  47425. { 0x1940b7d12ec35a1L, 0x0e2db73efd89468L, 0x031bc4cc8755886L,
  47426. 0x14678b1d6c5984fL, 0x19903c435e76904L, 0x0cb50c8a8487aaeL,
  47427. 0x12e9c186f249b0fL, 0x0372e953e071815L, 0x17a4140217198b2L,
  47428. 0x034accefc4ac637L, 0x1cbc76faf404a6cL, 0x0c27be751b86a2fL,
  47429. 0x08672375c51109aL, 0x09c1e9698472c22L, 0x1fe0df159642e92L,
  47430. 0x1aabff87dcf8c17L, 0x03fc87a539027d2L, 0x0121c74ea2fa8bdL },
  47431. { 0x0a453088815af3cL, 0x18d1979e4df6ae2L, 0x17265ed9777f957L,
  47432. 0x0825ca3d6b5de39L, 0x063f249061c61d9L, 0x19f118de86d62a7L,
  47433. 0x18041bc510a7342L, 0x163ee6f8785e3b4L, 0x17150e04b6bbc4fL,
  47434. 0x02da6448df140e5L, 0x118cf35dc07d6c8L, 0x1e8c54a26921e36L,
  47435. 0x1368f1f7f28b33eL, 0x1ea0b5b3eeda3e3L, 0x1e56ecfd2b69446L,
  47436. 0x01ccf3a552f9bfeL, 0x00100a8b7b29620L, 0x009f9c808d7f187L },
  47437. { 0x1d296ef7bd0c827L, 0x08879a514ffa31eL, 0x01a072694569418L,
  47438. 0x0a4d1794eff0f26L, 0x198045dfde8d804L, 0x0072c265dc18124L,
  47439. 0x18188fe435c41a3L, 0x016550719504c76L, 0x0293bb5e7535c5dL,
  47440. 0x1754ceaab20a888L, 0x046b406ef680173L, 0x017f49b1a031fc6L,
  47441. 0x001cf2b8662497eL, 0x0c625d4599eebbdL, 0x0adef26f01d6dcfL,
  47442. 0x036165308cda8e4L, 0x1b617a7ce24cbdaL, 0x022c6a5b5b40381L },
  47443. { 0x026a20e4d54d8b2L, 0x0b4b726990506c5L, 0x0163e653dc00169L,
  47444. 0x185eca9350d316bL, 0x1694d00d7a4adc3L, 0x02015e8c09740c9L,
  47445. 0x190411ae6c001ccL, 0x041c21428934366L, 0x1eae95ea5992302L,
  47446. 0x17e174d8da41061L, 0x0d72d61727ae28fL, 0x06332f08e0c9fcbL,
  47447. 0x108f27d49f21ae0L, 0x17b92ab5b47785bL, 0x136c068c967bc60L,
  47448. 0x1f2b8015c08aec4L, 0x191628e3b065668L, 0x02f89fafd5b7ddfL },
  47449. { 0x06ed9ae3a9b0dc6L, 0x0def4b7c41f643eL, 0x1e23aa2cd9deba8L,
  47450. 0x1934cdc757d4cd7L, 0x08217ffddefa6abL, 0x06f82e626998bdbL,
  47451. 0x19d3bdd0723c8a4L, 0x1943e1fbe2efa22L, 0x1fdf0ece7c35989L,
  47452. 0x176c96fb5ce2416L, 0x04f99956fc729c3L, 0x05204b9d9338e6eL,
  47453. 0x02e803e69c90acbL, 0x0bb89d0d1be4f1dL, 0x1685d35f028f14cL,
  47454. 0x005ec6a1b8acadeL, 0x0a211625a4405f8L, 0x010cb24aed1bdd2L },
  47455. { 0x0cb2fd313142680L, 0x148ebb2e8a67a00L, 0x1aaf7f899a7aae7L,
  47456. 0x1015c4578b8d419L, 0x0b6ec250beefce5L, 0x1c78ff9e15bcc36L,
  47457. 0x123b212b6c68b5cL, 0x16b2e137850a2ddL, 0x1f36931298e8f7dL,
  47458. 0x0477e35cad8cbfcL, 0x04254a6aaa90131L, 0x197a2882a9613feL,
  47459. 0x03427f34352c3c8L, 0x090c4be099f7bdeL, 0x19522801285e503L,
  47460. 0x1f4c4b54188fad9L, 0x1082971cea73d56L, 0x049d687580223afL },
  47461. { 0x00b6967988a9963L, 0x03bfbb28af46ebdL, 0x0e18edad43c9879L,
  47462. 0x0ba67245bcc4e9cL, 0x087a5b3d63a9b8dL, 0x0171919e1c69fdbL,
  47463. 0x1333c63dbc2704cL, 0x1ee4a980b87c05fL, 0x1c04ed0b726e662L,
  47464. 0x0ab235c0a1ff03cL, 0x0a51232405b2307L, 0x1897f047af2fdf1L,
  47465. 0x0fbccde451e5674L, 0x020bf56f02c37b9L, 0x1b9623717f22355L,
  47466. 0x1a3f2572a4412aeL, 0x0344408dd425844L, 0x039fc61f87520e0L },
  47467. { 0x1534fc85df763ddL, 0x013f99d638c1b44L, 0x185dba3c5680ec5L,
  47468. 0x099641111c1b6b7L, 0x057caea61d39094L, 0x0fbdf9bc0264d6cL,
  47469. 0x0a33ea96110a146L, 0x02ac4ddd9e25275L, 0x1749e0d98ea36a0L,
  47470. 0x1ffb6d71990f6e6L, 0x17ba98a2de4733bL, 0x0aa45a2dc6c32c7L,
  47471. 0x1cb15ae206a14e0L, 0x1e5192f251702c7L, 0x0d06a283c9a1d17L,
  47472. 0x0a370f9f3a80e42L, 0x175dfed25d97caaL, 0x00084571cd6df6eL },
  47473. { 0x0d178f3a9e88f63L, 0x0d88f55863992aaL, 0x0f9b8987629aa81L,
  47474. 0x1d1a172390ee74aL, 0x09bb004d24db7daL, 0x118485ef085839fL,
  47475. 0x07227f22fbf9d53L, 0x0342d5e0b32198dL, 0x0ddc838039d5951L,
  47476. 0x1fb2dcca362ed7eL, 0x192fa07b8296670L, 0x1c6df675362ff77L,
  47477. 0x15445dad0088891L, 0x0a84bf0f864d56bL, 0x01693877ff11aafL,
  47478. 0x0a4671090113759L, 0x1df348bb42fa0c4L, 0x0403e036c7589e0L },
  47479. { 0x0a969ec98ee0ef6L, 0x0aa41c5dbdbd780L, 0x124a80be3f6eea7L,
  47480. 0x1516e0aaf848909L, 0x00ad1af27bdb201L, 0x064afdf2c9a1f23L,
  47481. 0x074ed4ea6a50a66L, 0x01d2e9b67bdb50cL, 0x1ce1525c9ed399cL,
  47482. 0x0dab440fb9084deL, 0x1df456660846922L, 0x1675de1e4eb411fL,
  47483. 0x17fa2f358b5df76L, 0x01cd831a49f8c07L, 0x160ed4eab13ff3fL,
  47484. 0x133f84d258c4c2eL, 0x061b2fdfa36b553L, 0x00b2126364cb03dL },
  47485. { 0x1d65c55dd2744a9L, 0x060e17f1d7a0c2eL, 0x1a67bfa2c224951L,
  47486. 0x0b53bed23465905L, 0x1be9967430b7ab2L, 0x1968914c1c22a84L,
  47487. 0x1c9caf3b349632bL, 0x019115c8131798eL, 0x0d43961414b8efaL,
  47488. 0x07fb3dcf6b26896L, 0x195790b9fcd0111L, 0x188a8b61d3d753cL,
  47489. 0x14f03ded283d16fL, 0x16665c2e23a51f0L, 0x14e946e8f26b7feL,
  47490. 0x063627bfcd782e4L, 0x18adddaf4b9fb58L, 0x02aa27301527a23L },
  47491. { 0x17c5313baa80b4fL, 0x138b7b1dee477c4L, 0x0b6ded0b16a0048L,
  47492. 0x12110661195c4e8L, 0x0d341ab1e9d9e1eL, 0x0a2c381a96461f9L,
  47493. 0x1676058f41403b6L, 0x0530693bae78521L, 0x02053c5e01f6c7dL,
  47494. 0x1883a2365a1019eL, 0x022f4827426bc60L, 0x1cdd64f28d02ed9L,
  47495. 0x1e19b1b540d0f70L, 0x114ca5a1b905aceL, 0x1b14f3e02dfb370L,
  47496. 0x01e8583499b9c5bL, 0x061dd7d3edd1ed6L, 0x02b9accae7120e9L },
  47497. { 0x04ba3fba0237056L, 0x160b219d599c46eL, 0x0ef49c7b1849a15L,
  47498. 0x07c60637d9803ddL, 0x0118a1f5abdeb03L, 0x100799a777220cbL,
  47499. 0x01dcfb125d0856dL, 0x1fa36e30b9e110dL, 0x17b0c46cd7c1b7dL,
  47500. 0x0a1d96d25262f44L, 0x096612ec7fe5374L, 0x09c9939e68cbb73L,
  47501. 0x00eace64c9ac390L, 0x1b456ccd7c394deL, 0x05503097308a085L,
  47502. 0x0d22f77a7610315L, 0x0f0e468ed5f049aL, 0x0442a436f9f622fL },
  47503. { 0x0942c934bdff464L, 0x138cf92d3da28b5L, 0x1c2cc96f8c90f6cL,
  47504. 0x1633fc667399600L, 0x041ee8ff2055a31L, 0x17c6f7d6534d741L,
  47505. 0x1cf19d81f742157L, 0x0213c492c1e3436L, 0x1bcb0e8a271d368L,
  47506. 0x0f08d513442f35cL, 0x1742ac617ab864aL, 0x0dc81f03f239316L,
  47507. 0x0f994fc5031a0b9L, 0x188ceb70268745eL, 0x0933830cf605a5fL,
  47508. 0x1f3ae5210650f55L, 0x02dc5dd4d3ec91fL, 0x018e767f46a55cbL },
  47509. { 0x17bfd9afc8b21e8L, 0x09959d8ca1b6fa1L, 0x0b524870da83977L,
  47510. 0x1b47a1f521fcb20L, 0x1bb523bd8e9de84L, 0x06b4bacb31f356aL,
  47511. 0x0d672600288febbL, 0x1e2201381b369f7L, 0x1839aa7bdc9d20fL,
  47512. 0x0817b36f66b7d1eL, 0x1b53ef1545b2a7dL, 0x0becd8e85588901L,
  47513. 0x05ff3252f865ffaL, 0x1aece59e95be3caL, 0x15bc749cbfbf015L,
  47514. 0x09d8623610c77adL, 0x1b35d8f3cf09a6aL, 0x034b0da356d12a3L },
  47515. { 0x07b587ecb35e2acL, 0x0aa35abd78a6ce8L, 0x096f6ca281307b5L,
  47516. 0x08e13aa9e1d942fL, 0x1c6f400ea1f91d4L, 0x0670c853738cfecL,
  47517. 0x0ff49392e23b7eeL, 0x0bbf2f03dba48dcL, 0x1d67120e6b655afL,
  47518. 0x13c168ec9a09e53L, 0x18828a5c1fe8876L, 0x1e64a9d08246d2fL,
  47519. 0x1e36051f9f1eb51L, 0x19e72df49712a6cL, 0x0fde53f76bb10adL,
  47520. 0x155b31353465d9aL, 0x0121964e22f0781L, 0x03531d48629baa9L },
  47521. { 0x0554e003d7acbbbL, 0x0b3455ba7b0843bL, 0x19c8e231466cb00L,
  47522. 0x087d729a9fc9452L, 0x0cd6d2f60166771L, 0x1b87bf84351e6f8L,
  47523. 0x0f9f3e1960085ecL, 0x142cb110182b49aL, 0x1d6ed58165ba3f4L,
  47524. 0x1e63c09ae5238eeL, 0x0fc1d3a11295daaL, 0x0366dd4a05d5013L,
  47525. 0x070e021ed3a53a8L, 0x030bf8b2e105c98L, 0x0d7342e309fe24aL,
  47526. 0x052c34a8ec88d04L, 0x10effc89ffd8255L, 0x028f6a51168a8ecL },
  47527. { 0x1d6963a449701b4L, 0x0c8d1dd93e5791bL, 0x1856d5ca597faa3L,
  47528. 0x0bb6a17efa7df37L, 0x0e643b9b75a7a05L, 0x15aeaf7eb3a4076L,
  47529. 0x1225fca9834b5b3L, 0x0bed1f86418bdafL, 0x041c53cf628ce68L,
  47530. 0x114b88fb88330afL, 0x1c84e08d403b303L, 0x04c0d853fc90f50L,
  47531. 0x0ae1ef9712af0a9L, 0x0968b4dfc9ef9f9L, 0x0a5e4f0357dbec7L,
  47532. 0x124add6f5fc4ce9L, 0x0e54173d94ae9f4L, 0x016b4a8de15c5aeL },
  47533. { 0x1007d9f904e222eL, 0x19247c37a7084eeL, 0x1a2e3d0a7bb8ccfL,
  47534. 0x0b9f8eea31a9329L, 0x0b0f42f12957341L, 0x1a1a8cb73ff51d0L,
  47535. 0x1c6831e572df709L, 0x0ab04151ecce23cL, 0x183d95d9c2b874fL,
  47536. 0x05b26bc73870b13L, 0x0d4fd62e4a9d0b5L, 0x116288f6bcdb248L,
  47537. 0x0cbcf931a032204L, 0x13d7913405d6b98L, 0x0ee4fe5d7134226L,
  47538. 0x075dc8c92098370L, 0x1f0a24eba02165bL, 0x032e2473c704662L },
  47539. { 0x01c73cede222c22L, 0x1ec66fe7511da0dL, 0x0c52c850ec195a0L,
  47540. 0x1eb3f9d8ee06039L, 0x11204cef284adf8L, 0x19a883fd8e2c0e1L,
  47541. 0x02303d534fbba51L, 0x025b7ecfe169a63L, 0x176a3f2d110f18dL,
  47542. 0x004fd1403e9f009L, 0x1c2918979fb380eL, 0x0fdb6512ba5de0dL,
  47543. 0x0908b0553ad8286L, 0x17922a22f0837a4L, 0x1668f2f88a03e9bL,
  47544. 0x1745a805aaf0b51L, 0x06ff63dd9ffd438L, 0x01b5ae6963d3591L },
  47545. { 0x1ff4e20545679a7L, 0x005a0a29063a843L, 0x1fea6d167361936L,
  47546. 0x1390b5e3472146aL, 0x0d935a5ea19eaf3L, 0x0d33c506a3aebccL,
  47547. 0x1a041d140660de0L, 0x088e9072ef21985L, 0x1c6a21d112f4122L,
  47548. 0x08742fc9b528d1bL, 0x00547baa9d37e23L, 0x054f279f3389feaL,
  47549. 0x11376a9ab614e18L, 0x0911c4ffa2ac9efL, 0x1117a2863dcf2bdL,
  47550. 0x03b91a4f992c1eeL, 0x1d80692f4c539a5L, 0x0046be0a26d9cdfL },
  47551. { 0x09c0d963ecca773L, 0x148c96a4610ab40L, 0x15d36daf59061faL,
  47552. 0x0854cf19bfe1d99L, 0x11587b7e7731237L, 0x1852633d4b36c5eL,
  47553. 0x05ef7cf06840584L, 0x148f98dd070bf9cL, 0x195e95bb8a8de7aL,
  47554. 0x1f0f45ac4c18471L, 0x1c90fb8d1da528fL, 0x18857619a57e032L,
  47555. 0x040f9b2b49f3fe9L, 0x039b3e8fdac8293L, 0x1b851ed30e17a2fL,
  47556. 0x095b23a60a15d6bL, 0x0028e2c38790400L, 0x02f9554775d5b81L },
  47557. { 0x008d4641266524bL, 0x19c406850cfb371L, 0x017b6841bafedefL,
  47558. 0x07cc85ba8d4b54dL, 0x0682e4d60a69e8dL, 0x05a9a6779a4e30eL,
  47559. 0x19ee09bdbb8ec3fL, 0x1ecfb57424e0bd6L, 0x12babb27e18be05L,
  47560. 0x0cd7e5d4716c2e8L, 0x1cb46b8b674e1a5L, 0x05cc3d4de0dddb9L,
  47561. 0x14866e5ae859dc5L, 0x015e69e3e1413c5L, 0x12fa0bf67fc0d00L,
  47562. 0x1e449d10958ecf0L, 0x149a316498083c9L, 0x031280d4c5a37fcL },
  47563. { 0x03f7d9aad264086L, 0x119edd2f0725eabL, 0x000a3234f59f29aL,
  47564. 0x108dcc9633d04a6L, 0x00aa4536a288dacL, 0x0a9f567d1e48cb9L,
  47565. 0x0af4e04c326c3b5L, 0x0eec4500dc05d51L, 0x052fbf54dceccfeL,
  47566. 0x0cd4718a7868db8L, 0x1484cf566c5d06fL, 0x003934dfd514a33L,
  47567. 0x00b5c4eb10fd741L, 0x08fced2f68d67bdL, 0x17a9619e1266dceL,
  47568. 0x0a6355754989381L, 0x065cc9c5f73a1f3L, 0x024bd8aff7e9fe3L },
  47569. { 0x056cbaaf45568e9L, 0x0d07f638c9537c5L, 0x174e6ac94e6bd24L,
  47570. 0x109586fb53b7607L, 0x02a0f5b4c86522fL, 0x0e29cfc6466dd10L,
  47571. 0x1c0ba0427f1d68aL, 0x17f39a0da639521L, 0x18f31f0443e216dL,
  47572. 0x0d534565d1f5ec8L, 0x0343490b001fd26L, 0x1f7f0d536f9c550L,
  47573. 0x04d6308edcdd8dfL, 0x03400965202e9f4L, 0x1a841c76be8cff8L,
  47574. 0x06fcd85dd7a27dbL, 0x0b7b7ae7e5c2ff6L, 0x00c6a35364f28a6L },
  47575. { 0x08cbb22a78b7802L, 0x0eed924be5d7a43L, 0x1cf90aba2b741d1L,
  47576. 0x15699d69c989d65L, 0x0325fd40ac0abcdL, 0x1639a29706c192dL,
  47577. 0x1c6e5b3f815c44eL, 0x056e80f4f116282L, 0x070eb06036da7a5L,
  47578. 0x1859b7cec28bb56L, 0x0274a5f0a553ceaL, 0x1391b9ae0b5a282L,
  47579. 0x0d7bb5e751370deL, 0x103738461f86daeL, 0x04c143517e4f506L,
  47580. 0x1fdf221aa9f14fdL, 0x04069e6f8e45a38L, 0x02a822300e9fb17L },
  47581. { 0x1c5c91006cb9cc9L, 0x03a6ba0e8000a68L, 0x18f8448dbee1508L,
  47582. 0x1c535abf04f9b0cL, 0x0951fc8339721ffL, 0x068a278e90fdfd1L,
  47583. 0x0b9ac73781b9d00L, 0x0cd2084b2d722f2L, 0x03365c8e529ad51L,
  47584. 0x1110742cd777f4cL, 0x14c625c30abb8f8L, 0x07b73fe20179796L,
  47585. 0x16f532973f477caL, 0x0d15e80d9383a0bL, 0x15e7e4e848462b2L,
  47586. 0x1afb7e684a4127bL, 0x04f563a8ff7c6f5L, 0x006d189fe6bd876L },
  47587. { 0x1125a8c15aa2557L, 0x0eb8600449f4e1bL, 0x06519ee2a08f288L,
  47588. 0x08f960085490e27L, 0x09e2ce180d3e9a7L, 0x0d75611695fa7feL,
  47589. 0x01983554c683412L, 0x0009a534c2de07aL, 0x0473d50d61f1b7fL,
  47590. 0x178765de51ef286L, 0x166fa8270a3c9ceL, 0x1d41f0e08cc9c52L,
  47591. 0x01731083ef6d7c2L, 0x0a0e12aa56fd727L, 0x058b40d4250309aL,
  47592. 0x0521c882ce82142L, 0x0cc620230d81e82L, 0x031b185f46da0a5L },
  47593. { 0x18d52228a7d2e41L, 0x1ac11f5b17c3cdfL, 0x0f75b100b625279L,
  47594. 0x0dbc58b35a369a6L, 0x09b9dc38883e04dL, 0x1b86265f9f9c7a2L,
  47595. 0x081167665f462d2L, 0x0da3ed36418279dL, 0x1ca3d702558e260L,
  47596. 0x0a7ecbb930e8dbcL, 0x1abea16850dbe8fL, 0x1d317688780ead5L,
  47597. 0x0ce558f6be369b3L, 0x1c5647c4fe728c3L, 0x196a9cbac3351e3L,
  47598. 0x09d60d00e9e6fabL, 0x0ed295845c06854L, 0x018354c38f8b344L },
  47599. { 0x0451e9d634ec136L, 0x193e50737b2c7deL, 0x054b036d04807b7L,
  47600. 0x018b7fdccf537c0L, 0x1a2d602387b6ef2L, 0x17dc4c9a94191c4L,
  47601. 0x10b79839593631eL, 0x05695e457801593L, 0x128e6f63182a9d2L,
  47602. 0x03ae380fa99380dL, 0x1063e2081d7e470L, 0x051a37d54a23edaL,
  47603. 0x176e72a13df9fa6L, 0x1bfa600e2a8f3d0L, 0x12756224c18856dL,
  47604. 0x0f9a8e3574e6327L, 0x0376443ebe058e5L, 0x01419d620f4081fL },
  47605. { 0x0564b868da5ec5cL, 0x0ced40e046d923fL, 0x1c2e315e9ca2b0fL,
  47606. 0x0f3a687b853af83L, 0x1dc603393512afeL, 0x1d0ca0da1c7267fL,
  47607. 0x01125f5689c0373L, 0x1cdabe647f04e64L, 0x11b87a58e1393c6L,
  47608. 0x05b45e8825d5218L, 0x1071691c8ad35fbL, 0x152e40d6bf55813L,
  47609. 0x169976327ef42faL, 0x043bc3ecf0ee5e6L, 0x1700645956ea790L,
  47610. 0x06a717ab38eafbcL, 0x103673020ed0bcfL, 0x009066a2a524eb1L },
  47611. { 0x1fdb8f4cab0f9eeL, 0x01f7816672c7775L, 0x01056a341996f00L,
  47612. 0x0d372aeee936d4dL, 0x0721ab5c642ed3aL, 0x1278699ef243f82L,
  47613. 0x17737bcbfce0086L, 0x1e57a2deab053b7L, 0x12ef05b4b0e93dfL,
  47614. 0x10fd50905e4d760L, 0x0b8b0b519fea4b7L, 0x1ec8bd667c68cdbL,
  47615. 0x168f0103cb758daL, 0x0df01218533d6cfL, 0x10152f0547da4eaL,
  47616. 0x066ddaad3092dd6L, 0x03e8ef1677e7019L, 0x0010e7e8b3fef75L },
  47617. { 0x073715fdf5c36f3L, 0x1ef1beb25692a2eL, 0x1443cb3ddc4dc0eL,
  47618. 0x0e1e732790aa6d1L, 0x104ae4ca1e5ec7bL, 0x1dd8c5fed8b3bb1L,
  47619. 0x0f568363dc5f8f4L, 0x16aa4ce0e7ecc68L, 0x1faeb52ef156008L,
  47620. 0x0bd6afc91252387L, 0x1b8e47b4aad46aeL, 0x1caf32e860595f0L,
  47621. 0x17fd0ae28adc0c7L, 0x1fc76ace6447d40L, 0x04a2eda01f08b7eL,
  47622. 0x12b46bbdb8463d6L, 0x18e71edcd9ca205L, 0x003932da3639e7bL },
  47623. { 0x1dd99f0bd66232fL, 0x157c4e2013b8b39L, 0x17e96e183f13166L,
  47624. 0x14f5287e775f04dL, 0x123c428d239ea8aL, 0x19dcad07070d8d2L,
  47625. 0x1d4ed57a838e9a5L, 0x03fd47339544aaeL, 0x0f8adf72f06957bL,
  47626. 0x1c4f9a09de9a181L, 0x1c9f43e290ea5c0L, 0x18115b5ef2de667L,
  47627. 0x1b49c12aa2cd9c0L, 0x1d056374b6e6524L, 0x110203b76237bb9L,
  47628. 0x1e97b1e8eaeba0cL, 0x16c6e9d667d0cc2L, 0x01b62baa598e8a4L },
  47629. { 0x120046ef323d84bL, 0x088913f3c4e27c8L, 0x1d3a486e01569a6L,
  47630. 0x1500f32e9c961d5L, 0x140f8c796339844L, 0x16f7a4e482a3353L,
  47631. 0x192e8706343df35L, 0x18aa52fb4d69647L, 0x11c09dff3c41800L,
  47632. 0x02483ad9bf7b3bbL, 0x10e9014144f7b5bL, 0x05d2d6162e0b529L,
  47633. 0x14c48af5ae3d674L, 0x04ac116f603c224L, 0x193653d030054cbL,
  47634. 0x0bd6b45bb5bcb82L, 0x04efc8a8ac9a297L, 0x0037dfc308ca34aL },
  47635. { 0x165338e3f45aa97L, 0x1ac640e8207f596L, 0x166c3f7be2e760eL,
  47636. 0x15c9ae82f80bfdeL, 0x130a1a237beb071L, 0x12de81cc15b0fadL,
  47637. 0x1afcd317ca8abedL, 0x14bc815793ab97eL, 0x0422c326df06612L,
  47638. 0x090f34ecab8d714L, 0x02c42c8f4d0d3b2L, 0x12af3b40f266f91L,
  47639. 0x013619cf4d96d2eL, 0x0caf77d0c19ea35L, 0x0fa3c3b6746594fL,
  47640. 0x0b56254fb082340L, 0x1ea5e64295304bbL, 0x02f4e507e8f87d4L },
  47641. { 0x1d54571197c5dc4L, 0x1205ff3c54ad12dL, 0x1bf3ff6c3acb8b6L,
  47642. 0x181a2e8cf8cbf73L, 0x0758c6a3e952dc2L, 0x01a54d60fe4e3deL,
  47643. 0x12d5bf1e558b350L, 0x1164dc6df7cc3ecL, 0x06adc4b9e1e8472L,
  47644. 0x18b2fe9d47cd645L, 0x04e9140f8f804dfL, 0x0a26cac8f1c6f79L,
  47645. 0x17064ddc77eacc5L, 0x1b49b48a699c8b8L, 0x0909299d6cc6371L,
  47646. 0x0be68d363e38e6cL, 0x0f88cc2045b4995L, 0x04a031159e341b5L },
  47647. { 0x110ccb70d997973L, 0x0b12ee9fc788aa3L, 0x13556e5eaf54ecaL,
  47648. 0x14ce7c294b19e18L, 0x1d262246c6321e0L, 0x041d8882a0d7ce9L,
  47649. 0x14a9379b61d51bfL, 0x16c8fd2fb51e02cL, 0x00f82b3a6ad9802L,
  47650. 0x0d5203ad74e2259L, 0x1d778b3b4afdddaL, 0x151492f481b55e7L,
  47651. 0x083c23ba9c1ef1eL, 0x18c851641707c30L, 0x178cda362a66293L,
  47652. 0x17ae3c56939199fL, 0x1b6b9f49824bde6L, 0x0405d8b323c2df6L },
  47653. { 0x1e575fefd145cb5L, 0x172b0d62f344182L, 0x033e1e4ec9cc557L,
  47654. 0x1c267646708c3ceL, 0x02a7ba079f1553dL, 0x18437d17dcf061dL,
  47655. 0x12e4f0eff5aa0f9L, 0x17b6d750a011769L, 0x10b66d78976f82dL,
  47656. 0x0ad37fb2a75a4ffL, 0x1748dc7c82cc89fL, 0x1384a9c539b99acL,
  47657. 0x03cb118ff979ea4L, 0x062c0005b24bacbL, 0x031de725a566377L,
  47658. 0x0b46b2a20f23022L, 0x150edfc154863b8L, 0x003bdd2f5209091L },
  47659. { 0x13a38d3cdd86f61L, 0x10a228281505585L, 0x171601b409c90c4L,
  47660. 0x111465e21e3225dL, 0x0e80c76001dc1f9L, 0x127459dd8e98e88L,
  47661. 0x127bb51bb1f97d1L, 0x0efaad35e6d357eL, 0x09d286ea72cdadeL,
  47662. 0x1f38106a2d6ac90L, 0x148db98a66b9fcaL, 0x137ba7eab80f57cL,
  47663. 0x1a52350e80c9317L, 0x17f83ac3409c4caL, 0x1ce594c24049972L,
  47664. 0x0fa42b6790365e8L, 0x0e2baf7581d9bc7L, 0x03590036fa2c8d1L },
  47665. { 0x0fe50a8965b1bc1L, 0x1a9b54b15da7ed9L, 0x14cc0039fe664c7L,
  47666. 0x0aa7aa24bdaae31L, 0x12125caf84728f2L, 0x1fb3cf27c530c26L,
  47667. 0x1016953c69c04d5L, 0x0eae153e8182a63L, 0x110d0cb976fa8b7L,
  47668. 0x03b7a0f4ee09674L, 0x15e9d49d57e252dL, 0x1c20c4ae8348b91L,
  47669. 0x18c917b16cd6c12L, 0x1c6b5850131537dL, 0x10e3a0c93445b98L,
  47670. 0x115f9092a818065L, 0x150855b911c6686L, 0x02990bf535e935aL },
  47671. { 0x0840473259f52b4L, 0x0d4e5f3108a367eL, 0x017b2b2f49ba5a3L,
  47672. 0x1bc94a86892c9d7L, 0x181a4ff7ab7daa2L, 0x040af7b6e1dc241L,
  47673. 0x0c78681ea5acd07L, 0x15189f5d3d187a9L, 0x10f938d1e42ce9eL,
  47674. 0x193ed661ae60297L, 0x180727a681bc1e9L, 0x1b9694dacb43903L,
  47675. 0x136044a9a6a9e08L, 0x195e94adfc7168bL, 0x1e06c4a6624f743L,
  47676. 0x01585411a66f3f2L, 0x0ef64bd60016183L, 0x001c3498f6cd6dfL },
  47677. { 0x0d7abb3d09885a5L, 0x095b3f1aadd83e8L, 0x033d4dbaebb7b67L,
  47678. 0x10d339c9ac77847L, 0x111594cd61ca2e7L, 0x18b5691aa7fa238L,
  47679. 0x1d711572f9c240cL, 0x080830cf3fa93ffL, 0x075bacd750f9c6cL,
  47680. 0x1bf6e4414b9390dL, 0x05a21f97bd40bd9L, 0x06cf7e641c1d04bL,
  47681. 0x0f8bbdccb2459e9L, 0x1bb3431ec0e71b7L, 0x031b6e06e825ff2L,
  47682. 0x0e9179a7443adabL, 0x0200e4967cdb4a8L, 0x016557ba48a820eL },
  47683. { 0x0f980066ed20424L, 0x0751191238aa2a2L, 0x0695e06a321acf9L,
  47684. 0x0af5cb6e164d1daL, 0x156d398248d0ab7L, 0x198fd2365459901L,
  47685. 0x173ca73a39a04b7L, 0x1bd7213a465b24bL, 0x1302c8f78f56723L,
  47686. 0x0b92eb4d5d64b7cL, 0x091f295f4685c04L, 0x0a23831457cecadL,
  47687. 0x11ad50d9d96bb5dL, 0x18582a8c5ab722fL, 0x163fe44dba21b89L,
  47688. 0x06c3d8f8e3e7a13L, 0x1d865a1bbe29350L, 0x0436bfa9922ff1dL },
  47689. { 0x1f16eb6b0bf719aL, 0x1a84c45e1ec89ccL, 0x19489b3406d2da5L,
  47690. 0x0921131a39f5ca1L, 0x087ec666d3e3ac5L, 0x1522dc26d1dcedcL,
  47691. 0x0c16160c01913efL, 0x0266d3e77b306abL, 0x10fb239a8579bccL,
  47692. 0x1ada29cb715ec08L, 0x1ceebc90663f493L, 0x0db7106faa3a00fL,
  47693. 0x02eae75b1668a67L, 0x1edb041e3477753L, 0x00db1697ff97e50L,
  47694. 0x1ff0aa5929a1efbL, 0x0dd5a4c3c6fcbc1L, 0x034152af1c3605aL },
  47695. { 0x0f235a4587495aaL, 0x101361a63922ee4L, 0x1316dd691b8c89dL,
  47696. 0x0bd987cbcfad5c1L, 0x14296629890d396L, 0x03b9138d899a178L,
  47697. 0x09a2f22649f9a2aL, 0x0342a87e4fc4649L, 0x06c44768449cdc2L,
  47698. 0x1e3fea78a296856L, 0x0c28c7fd2c11726L, 0x0d410a5eec22598L,
  47699. 0x12c6fdd7a6415d4L, 0x1da63e48d6b9b82L, 0x0235c3373b30eadL,
  47700. 0x0720ba59be036edL, 0x1cd054f2542e40dL, 0x001113fd37f7f26L },
  47701. { 0x005efd9b751948bL, 0x176a37efe912e8cL, 0x18253cb22c8a3bfL,
  47702. 0x1f2def8bcb96251L, 0x14cbeca09d1090bL, 0x04658204ace8225L,
  47703. 0x13f38872557e638L, 0x135783e4f3ad1f4L, 0x0b021e14e0710aeL,
  47704. 0x068b74fc408b3faL, 0x1708baef27c6959L, 0x0dbfc6841dd5eb4L,
  47705. 0x15d5c4e8435f371L, 0x147fdd40cb8f5c8L, 0x14dd5e193f157f0L,
  47706. 0x18fa0684fca9afbL, 0x178446e6a6215ebL, 0x02a3f124d14934bL },
  47707. { 0x106868aa1ffda27L, 0x166e63caae7a823L, 0x0784298fcf62d39L,
  47708. 0x153bcbce15eca2aL, 0x193428235b4127eL, 0x17bea89e9604dd7L,
  47709. 0x100946326760ea8L, 0x19d418b763bbbddL, 0x07ffddf8403dcf1L,
  47710. 0x0bf2694b0b7ef6dL, 0x1595a5e4ca87c39L, 0x01d06323a9c7a48L,
  47711. 0x01c220218b7475eL, 0x05e592829a3cdf5L, 0x184cb9bf3ad7242L,
  47712. 0x183d638d0b9d478L, 0x0eac42dc745bfe6L, 0x022d20e60695847L },
  47713. { 0x0a9b2c74dbbf0e1L, 0x1cb17d0be7b871fL, 0x1d617bad319907fL,
  47714. 0x05537d62fdb83d4L, 0x0285741a4f5412dL, 0x07e88f964f27a95L,
  47715. 0x0613a4f7df69261L, 0x0eb655f7bb81be6L, 0x096323d252421e3L,
  47716. 0x03df0f224efbc0fL, 0x1807b4f5626fab2L, 0x137a51ffedba28aL,
  47717. 0x148a0f298c0f0bdL, 0x0c4734a216992ceL, 0x0b0abd8d8b5e9dfL,
  47718. 0x1b40550980d6d6dL, 0x0c8ba850ac9d087L, 0x00943b1e4a17720L },
  47719. { 0x1a80f07acbac178L, 0x100221a5847b714L, 0x1451c3fb7b49f30L,
  47720. 0x070cc2aecfd2c63L, 0x0b088548b2115daL, 0x174701be3afae26L,
  47721. 0x05d496ca7484e68L, 0x179fd3fb4cd1710L, 0x13f1d8d88c1de7eL,
  47722. 0x03b2b2f0190c091L, 0x195586c72657cedL, 0x1631627d6e360e6L,
  47723. 0x1399b3a0eb2160cL, 0x1907e6ba3f46d28L, 0x049b5c97a3287e6L,
  47724. 0x0c6fed4fc00cf68L, 0x0d21e8204b768bbL, 0x03af4b5e67e27baL },
  47725. { 0x09d1fdc0d19716eL, 0x0282c3e1c22928cL, 0x1b47aa61f4ab7d6L,
  47726. 0x06d80e2a1ec9508L, 0x0d6fd5b712b6bf8L, 0x09faafc8ec2ea32L,
  47727. 0x044a6a5e220d93dL, 0x090c01077b102a1L, 0x1a7672683ea876fL,
  47728. 0x005973d60ad9244L, 0x1be3490b47664baL, 0x00539e7bc92530bL,
  47729. 0x1cb14876279c57bL, 0x0572db43ff017c1L, 0x1ae065abae93f92L,
  47730. 0x0a47b150de136baL, 0x149d88f566ba16eL, 0x0184d374d5d1344L },
  47731. { 0x127ee50bdfbe97aL, 0x1f387dc628626f7L, 0x0c05ff827d70697L,
  47732. 0x0b7da6d98b98f7dL, 0x1550ed3a8fa15a8L, 0x084340e061d66dbL,
  47733. 0x1732f1607be1faeL, 0x1d142b666c5893aL, 0x00fbb17141fa264L,
  47734. 0x13fc6c7c70f7744L, 0x133f58870ad8f49L, 0x1cfaa77cfdfba63L,
  47735. 0x1fdb2a358a924dbL, 0x1aeb4560ea1743bL, 0x13fa9573e59cf1dL,
  47736. 0x16405c6b2f1fae2L, 0x189eeb366535769L, 0x0022c12c56bac9bL },
  47737. { 0x1f71a74a042dbdfL, 0x02c2babbcefd12eL, 0x0e9c34b9995cb50L,
  47738. 0x0b945d125c1ccd9L, 0x0f0e6b5f285d674L, 0x03b3e1fab546f78L,
  47739. 0x1ae7383ba14768cL, 0x0853180acb08668L, 0x0b35fce26d6b3c7L,
  47740. 0x044adff9cbbbf00L, 0x03da9b9edb621b0L, 0x10869e052097079L,
  47741. 0x1b2e84ec34bee14L, 0x0b6884c8bfba48aL, 0x07eb302eabd98f2L,
  47742. 0x1805200970eafc8L, 0x158a2b880e56f86L, 0x029fa51f04adbb9L },
  47743. { 0x1bb08ce89fc48e7L, 0x062bbd7d5ad7588L, 0x0fe283072d6ae98L,
  47744. 0x14f2eaf96de0d79L, 0x163191607d2efaeL, 0x1bdbd4f136c858bL,
  47745. 0x1cafd0aa86ad8adL, 0x1e071dd819a50bbL, 0x1d35947f5f3a8f7L,
  47746. 0x1e46e077e0e5adaL, 0x0332831161173e5L, 0x1312493c4de5fd7L,
  47747. 0x0d483ed89a16e8dL, 0x08ec8839be13273L, 0x17a67c04e8fc515L,
  47748. 0x1aac70a02ac5c60L, 0x036aaf98d746908L, 0x0054cf329eb91e9L },
  47749. { 0x1536f46abbc0559L, 0x1833dcd50d0b011L, 0x08a4305a06d7058L,
  47750. 0x0226f1d20e453faL, 0x0b793a2d61254beL, 0x12a96de307fabd5L,
  47751. 0x028da9bcb7e2d19L, 0x13535a63127182eL, 0x1c5cd9abe29b74dL,
  47752. 0x1ba3939fbc24291L, 0x1aa4e83438c18f3L, 0x03c68491c7b1824L,
  47753. 0x0e8323ddfafe202L, 0x19931cf3ecb9a1fL, 0x0c955227dda1dd4L,
  47754. 0x1efd52ca1f862eaL, 0x1c0b595dbd13eebL, 0x01d4ae5a28087e5L },
  47755. { 0x14e68cb39d7ff2eL, 0x0e5a5e0eae247caL, 0x11ddc5a50e2a374L,
  47756. 0x012395b19c05525L, 0x12cd08d27965c0bL, 0x0815ed062bcc559L,
  47757. 0x14860696f0f0e9aL, 0x1b6a8ba124aa30dL, 0x0f0077cdbd27e64L,
  47758. 0x0abe5524668496dL, 0x1e8e80914caacc0L, 0x073683995746545L,
  47759. 0x014744aee6a5fb6L, 0x06dd49ed00b816eL, 0x05e13c5216ed0dbL,
  47760. 0x0e58726b2fecc65L, 0x0455d713c1ddad6L, 0x01b3691170185b9L },
  47761. { 0x10b4875573ea5b2L, 0x1200dd486d226eaL, 0x0995e8680c403f3L,
  47762. 0x0b9e2288c0f6a7fL, 0x0538bf49722a80aL, 0x15669085c75f82dL,
  47763. 0x141f6b850451f4cL, 0x00ecd24e258f6b5L, 0x06dc5fee73f48caL,
  47764. 0x0768a4c95c53c6cL, 0x0cc51774bc5d666L, 0x1bc2bf2e371c9d1L,
  47765. 0x1dadf1b36843408L, 0x12c995bf02af536L, 0x0224ff52eddb9cfL,
  47766. 0x17fb48850e2a7a6L, 0x125173dccd20661L, 0x048395d4cbcef7eL },
  47767. { 0x14de4dd9620ea39L, 0x0b24fe418e77423L, 0x0ec734ea710fefcL,
  47768. 0x1e7e7be3aa161d1L, 0x0f0ec9b36a38286L, 0x0e04f1a7683959cL,
  47769. 0x0890a9b93261dcaL, 0x175d47d158d15a2L, 0x06ae0e22bfbdfa5L,
  47770. 0x10b8f67d8507ac9L, 0x0a21b5ae1c7e355L, 0x1d526bc237b4676L,
  47771. 0x007f0f153f6b19bL, 0x1eb6017726c0ad2L, 0x0a23d19f982365dL,
  47772. 0x02ca8fd1e47b36dL, 0x02926ac9652439dL, 0x046c9635e9aaa36L },
  47773. { 0x1e0d7ceabeb0ff7L, 0x1a92a1f07217c59L, 0x089b7a021267ef8L,
  47774. 0x1e39a89786afa36L, 0x035cfee19ece2e1L, 0x1fac0e0922d6de2L,
  47775. 0x0e51e1d3ba103e4L, 0x01522d4ef397b41L, 0x0abcc815afa57aeL,
  47776. 0x1d6f616f85310d8L, 0x0940ae07e42f725L, 0x1bc2a77bcc7b7cdL,
  47777. 0x1f78884c2554bf9L, 0x05ddaa385447ed5L, 0x014fbd4c2a94ac7L,
  47778. 0x04fd5f00a72d852L, 0x1c08d43d8988dd8L, 0x02725f60bae0d72L },
  47779. { 0x18483a2fcc09676L, 0x0251f8cf54d4a5fL, 0x1bcf5c0a977515fL,
  47780. 0x05087fcfb14d0a5L, 0x16e35158e7915fdL, 0x0ba3783225dd4c0L,
  47781. 0x1c2d6346e57427bL, 0x0bc8ee08b037215L, 0x10bd4bc6bd4fd13L,
  47782. 0x16e7033da7419d2L, 0x1a3cc3fd5aa6869L, 0x1001d858c7fc581L,
  47783. 0x0598f508a8a9c80L, 0x1949409d224e105L, 0x1fa06880ae532ccL,
  47784. 0x0eceec8fc7a51d8L, 0x12472e67d1ab487L, 0x03d2551fab7cef6L },
  47785. { 0x19ef1bae27a0045L, 0x096a7d92165a82aL, 0x0390e73e3493720L,
  47786. 0x0b367f38a84748fL, 0x0ffa1fcf97544fcL, 0x11641dad6340995L,
  47787. 0x12eddd3e3fb80d2L, 0x14d2d98c81f9a7eL, 0x0775dce9db0512eL,
  47788. 0x1ee50cee6e71c0fL, 0x1acfcea74ff9559L, 0x1e8434324e9f83dL,
  47789. 0x1428d69b1238e0bL, 0x0fe84efc0acc97dL, 0x06ad77d23f3af7aL,
  47790. 0x0d38bb93bf49f68L, 0x1e10cbd7dc8c0a2L, 0x03014153dfbf856L },
  47791. { 0x007e538dceea2e7L, 0x191641e21030ebeL, 0x03e53c7d9458e28L,
  47792. 0x178eeed420ced05L, 0x15e6b405f21b69fL, 0x13db21631d1a0bdL,
  47793. 0x051013267c96246L, 0x19a70d25950595aL, 0x0f1e82ffe00869bL,
  47794. 0x185b8a70b7f2335L, 0x1d0be4640644e30L, 0x0da01f4a2d5cbf6L,
  47795. 0x0cd8c73a43e9016L, 0x1de2e1b92aa87bdL, 0x130e7b4b5a901f7L,
  47796. 0x17ce1c8f4ea72d1L, 0x1423fd286d94a5fL, 0x02fa574e391e35cL },
  47797. { 0x16a2dda53f4d561L, 0x0a2e80b6d0cc96cL, 0x07eff752c144a1bL,
  47798. 0x1b3e432bd489340L, 0x037661b325488a0L, 0x12f701620a8d855L,
  47799. 0x0205ee6311c7be7L, 0x015497950dd50cbL, 0x1bbcadb877a68fcL,
  47800. 0x059a324b5b9b354L, 0x1a6350559870b62L, 0x098d9202841865dL,
  47801. 0x152f2752aff5b3bL, 0x088726ce511a939L, 0x092aa00bd9339cdL,
  47802. 0x14a072734fe4d59L, 0x1d29cd3e291401aL, 0x049500a11ee2357L },
  47803. { 0x1f24be11c2f7dbdL, 0x04807dbea93fd74L, 0x16ee1923c4a36a3L,
  47804. 0x04902832832c7c4L, 0x1a6756fb9ab713eL, 0x06c85ef43fbe80bL,
  47805. 0x1aaf49d37617816L, 0x12b047fdcf504acL, 0x09f6230d7742401L,
  47806. 0x02bcf96565af237L, 0x09898c5a9321f81L, 0x1487b33610ae544L,
  47807. 0x03e488789e9ca19L, 0x0a0361dec36e15dL, 0x18255fbe582d6e6L,
  47808. 0x0a2b6de58851712L, 0x19b90748706161cL, 0x007e47f0f554465L },
  47809. { 0x0ae1bedfeb90f2dL, 0x1dd9e52458aacb4L, 0x1e73d93a58d7ce4L,
  47810. 0x01f17ceb8457cc5L, 0x1e6f7529354c241L, 0x165598debf5381aL,
  47811. 0x1cfff09921a3858L, 0x0fd62723ce190c1L, 0x1df367c751d8983L,
  47812. 0x0a85b5a15f994a0L, 0x03d1b9e304c63f8L, 0x1b57458962c12bdL,
  47813. 0x0e701afbf32b3f1L, 0x0f443a62e3667aeL, 0x11b72f8eb49d4c1L,
  47814. 0x125ba7250bca2bbL, 0x09f3c954d86d998L, 0x01685d4316fe9bcL },
  47815. { 0x0cd8ee8b472e1afL, 0x0a7575bb55de675L, 0x0fe34364fef7acdL,
  47816. 0x0ffcdf8e0d36a41L, 0x04ee2f39fccd60dL, 0x00f28f549a9eef5L,
  47817. 0x19ddd7ac2497a6aL, 0x0d3dc669b43a26cL, 0x0c1d28c9fd5354dL,
  47818. 0x0bb8baac952f6aaL, 0x18d9fedfdc3606eL, 0x1d9552675cf4ba7L,
  47819. 0x19e23cfbb77be7eL, 0x04a4bb40932678fL, 0x0d88d6c344a7d2aL,
  47820. 0x0edb4e0a6eb4813L, 0x1fcccf64c7548a3L, 0x04b1e438926a0edL },
  47821. { 0x0e290cbde36a814L, 0x180cab99d895addL, 0x019fddff83866f6L,
  47822. 0x1a52e419d41d75bL, 0x1029ec720a7d19fL, 0x08c88f21a6bb28cL,
  47823. 0x1fd8215abfc5eedL, 0x00da144bb35b014L, 0x0ffca86aff848c1L,
  47824. 0x1f45efca1d6ba4eL, 0x180a138f9a5aed4L, 0x0615dddc842bf73L,
  47825. 0x1e2ecf3c633eb66L, 0x070060604ec7ddcL, 0x15efab1c7693fe9L,
  47826. 0x18fdf652d7cb2baL, 0x1bd1751fbada8ceL, 0x01681f59e7faaebL },
  47827. { 0x116925f04f2ec1dL, 0x0793b068a3f7175L, 0x1812ab676782a1eL,
  47828. 0x167ee206b6885beL, 0x0cb95d5b891df44L, 0x147691e1413959cL,
  47829. 0x1cf8dbc53bed57bL, 0x0bde7888c1e2761L, 0x0889f9bd76bd733L,
  47830. 0x04f73b8fbaadd37L, 0x0613fbb4866db22L, 0x0e6fd85dc822c4dL,
  47831. 0x0263efcd372d44cL, 0x131bc135dca1c2dL, 0x19ade9f6424c86dL,
  47832. 0x0c36f849f14f27dL, 0x0d9a3ca8d24a7cfL, 0x042172060e2a5d6L },
  47833. { 0x0268ed6a661d843L, 0x1466527ad9866adL, 0x1b444c4785dc08cL,
  47834. 0x098cd2b2ce2dcdfL, 0x17b2e280690decbL, 0x1f21685ed62dfb2L,
  47835. 0x128be09fe0b287bL, 0x00d8aa9d81594bfL, 0x1ac5276c1dde455L,
  47836. 0x1fa65847183ba89L, 0x1db66b321e5f32dL, 0x10281b2665a5195L,
  47837. 0x17285a409fd5964L, 0x1111e849e635714L, 0x0a3f025ddcf0a95L,
  47838. 0x1fcd85aa4cd58a2L, 0x128a596b7cbbc31L, 0x0073198cd656489L },
  47839. { 0x1cd2fadf0360ac2L, 0x1306f142f302d5aL, 0x1c43896e6c521adL,
  47840. 0x1b55358aa9058d9L, 0x126c070e9d5fa38L, 0x0662969efe78dc2L,
  47841. 0x11fd40de6a5acffL, 0x143c6cb385217f9L, 0x15b1a3db569d3e6L,
  47842. 0x00a945acdbda16aL, 0x17be92708a801adL, 0x00313699c76d269L,
  47843. 0x04b3abaf3290f38L, 0x1fc1c4f15839de0L, 0x0968d6c9e96888bL,
  47844. 0x14f8416f53aa3ffL, 0x05a4939ecef28e1L, 0x04441ced10c3938L },
  47845. { 0x0b66c30701ce29aL, 0x178932c4c0ea82bL, 0x1030417e7c84eb2L,
  47846. 0x0c6e7c7a27a9b5fL, 0x1a2ee3cafee571eL, 0x101c2d73934e437L,
  47847. 0x1a6b3d732992b74L, 0x1de42fe4eae6001L, 0x0c934db470e7273L,
  47848. 0x14a7a7b9aadb3bbL, 0x08dae5bf0146010L, 0x03b760a432163f5L,
  47849. 0x10e9eaef528f88bL, 0x0db40dc81abc8dcL, 0x0570da7cdfecbafL,
  47850. 0x0439273a14a3a88L, 0x026fc59cca71d2eL, 0x03209467f50fa86L },
  47851. { 0x03678a2e8f5b0b5L, 0x1124e69a0782cf8L, 0x11064f29f3b171fL,
  47852. 0x0d79075f3082880L, 0x1aa8bbb0075ca34L, 0x01187bf9cf8019fL,
  47853. 0x1cd14f463c3b7ceL, 0x0eaf1bfe019a891L, 0x1849228c0d51aa4L,
  47854. 0x0a7138418649468L, 0x0e9a1a3c4b3f4f7L, 0x13b71167440d8cdL,
  47855. 0x19016dae0109104L, 0x1129f1beec32e82L, 0x1a61c6d1667a417L,
  47856. 0x0265c6459e184f9L, 0x1da014f54da174aL, 0x049b1a504ded5e5L },
  47857. { 0x0826b27a9a2e304L, 0x10c3360d2609231L, 0x00c888e05c4315fL,
  47858. 0x0b5308f9fd22757L, 0x0b5f46fd7e9b6b8L, 0x1c733694b2ae789L,
  47859. 0x17aadca555cae00L, 0x103c9974c02df52L, 0x0bbc11071b9dedaL,
  47860. 0x1f8004d1f8e7b0fL, 0x09ddecdcf833ee5L, 0x0139a273ac76a6eL,
  47861. 0x1a4f87d78e302f9L, 0x1a0243b18f6b396L, 0x1308ac8d881de8eL,
  47862. 0x1ddcf8811865b3bL, 0x17e4b4c5bf226deL, 0x013365a33de031aL },
  47863. { 0x1aa4154b56363e8L, 0x1e83c1e0d526db7L, 0x1778ae79965d2d3L,
  47864. 0x1df4009708286b1L, 0x119911a65b34ae3L, 0x1b5fbc67a259767L,
  47865. 0x17255572aa0ce94L, 0x03ac0dc3d7310e1L, 0x0e3c3287d09f351L,
  47866. 0x0597a75ceae79b2L, 0x13a2498eae3279aL, 0x051d86d56c2382aL,
  47867. 0x0ba1b7d12015488L, 0x098adc6b84995feL, 0x11ceb05fb9ed6f1L,
  47868. 0x055e6f05fa1a3eeL, 0x0e1bcb029a83c8fL, 0x0258ead0da922a7L },
  47869. { 0x0fe517463d52c0cL, 0x0a92f0c4604ce89L, 0x158cd838e558dcdL,
  47870. 0x1559f4b486b8c42L, 0x197e810788b3f1cL, 0x0f040548091d053L,
  47871. 0x16b6ae8c7dad6c5L, 0x191afbcbc25f947L, 0x03287361b0df511L,
  47872. 0x064006a32babea7L, 0x043cf5481fb245fL, 0x0de261dd41c6210L,
  47873. 0x133ea5a2ec0d4e5L, 0x1f355de85dfbf70L, 0x02fd865bf01dd8aL,
  47874. 0x1a8559063fb9c24L, 0x127e07439fab622L, 0x040c35c9fa84725L },
  47875. { 0x019d15409312867L, 0x01602dfd7beda63L, 0x19a07d7d7769f81L,
  47876. 0x0f49f87b05839e2L, 0x0e68b8fe50aa505L, 0x1a6b22769876b2eL,
  47877. 0x0125fb2c0702efaL, 0x038f6bb88890638L, 0x1351e6a009b7d9bL,
  47878. 0x1dc31dceca3be48L, 0x196244175044292L, 0x19e886b016f5574L,
  47879. 0x1690be357e30086L, 0x13da90a7589ce03L, 0x10ead5c4afffc68L,
  47880. 0x137f4f39f8dae45L, 0x12a4743de57f34aL, 0x005fcbf4be4f715L },
  47881. { 0x0ec4ec8dda19e96L, 0x10c7536183745cbL, 0x04ad97da4629533L,
  47882. 0x161b341b32fd06cL, 0x02fdcc091ac6f68L, 0x1e1f09cc534bd23L,
  47883. 0x05cc1973897c656L, 0x00c312dd9b56727L, 0x19eb81a0f32f128L,
  47884. 0x1eba0b70e96e3efL, 0x11e5dab51cd6674L, 0x15353ebde873c45L,
  47885. 0x0b9e69d94e3de37L, 0x054e85e435bd605L, 0x1dbc4839afea780L,
  47886. 0x1847eaed50e1aacL, 0x0bb3bd91bb4feaaL, 0x047f2a4161f2055L },
  47887. { 0x1ae67c2ce9a4d1eL, 0x15c01a78e901c42L, 0x1ce89741864930fL,
  47888. 0x1a611f6838b8d91L, 0x071c294e803de0aL, 0x17586d4cb0fade7L,
  47889. 0x1a2db71881e37c0L, 0x11f90fdea2b6c95L, 0x169679f1e50b4d1L,
  47890. 0x0e004d0a90ccfa1L, 0x1212f83d90297f1L, 0x176247b56acd4faL,
  47891. 0x0c64275d2c4c918L, 0x05696f6b533e08aL, 0x12d723656a44ee7L,
  47892. 0x077ec313da316d6L, 0x03f4aeb6206b42dL, 0x01c946334dde45eL },
  47893. { 0x04bea4adacb4b64L, 0x115227930bcd0efL, 0x0539ea444a900fdL,
  47894. 0x1ba6de663de7559L, 0x007b85c490448fbL, 0x10dbbda130215e2L,
  47895. 0x1a6116b62965884L, 0x01a62ce949ecf9dL, 0x17fae8bbe4e3b2fL,
  47896. 0x00efb6ed3e49875L, 0x1bea6309674351aL, 0x13cd7d4383fb5bdL,
  47897. 0x0b21d405d11b14dL, 0x19c493aa1dd56e4L, 0x1c73793c077fe4dL,
  47898. 0x1a1b30386b67de0L, 0x0f61704d2e19150L, 0x0366644479aa89aL },
  47899. { 0x0d36f0e7ad7504cL, 0x1932ffbcaceeefcL, 0x1b7bfb799eaaf28L,
  47900. 0x1d75d7e65e1b9a3L, 0x014edcfc1276f4cL, 0x16c75bb412d3730L,
  47901. 0x138782e306a0a66L, 0x034624049521371L, 0x0cb8fd98b9cbd35L,
  47902. 0x04209bc7d58f45fL, 0x143d74e5cf2b3e9L, 0x09084b3aa4a82fdL,
  47903. 0x0374b91393a17e1L, 0x0d651e74a9eadc2L, 0x103e0563de4ac84L,
  47904. 0x1af7a06bfe22191L, 0x0f96afa6357ad4eL, 0x0178a8cc05937d7L },
  47905. { 0x08631da29d2d439L, 0x1dde15e01ccaa86L, 0x1e49b016dd6c487L,
  47906. 0x016d9c8fd87cb52L, 0x1d88c6586d6cf4cL, 0x1aad0bdd550bb3cL,
  47907. 0x16a140c76e79fccL, 0x1bf0703c7b015deL, 0x1c71db29015a31bL,
  47908. 0x1c7b5ba4a4c7ebeL, 0x17cfe44efbbbd98L, 0x04e3e956cf6689dL,
  47909. 0x10fd22df11e6173L, 0x102e27491d10163L, 0x1ae6483def80e24L,
  47910. 0x095543843210b51L, 0x1656c805ce8beb5L, 0x01aa582db8562c6L },
  47911. { 0x171e2367a9170e9L, 0x16216a656a866b8L, 0x093cf37733ec07bL,
  47912. 0x074cd95c35ff7d0L, 0x165c7d01a73e8ceL, 0x1ecb8f5b89c53fcL,
  47913. 0x09cac001638fd70L, 0x0dea4b235865fe1L, 0x0a32fb5bcbbbce7L,
  47914. 0x1920d5c54fc0d0cL, 0x14cccbb29a18c3cL, 0x13f88905e277e63L,
  47915. 0x17a4681be2847afL, 0x12af7e7cb0cb710L, 0x0b31c1664e3e4cbL,
  47916. 0x1f5847cfb5970e1L, 0x1a1d41be893cf09L, 0x0246e2ae2571a91L },
  47917. { 0x0623826a5092193L, 0x161b1344c4b8647L, 0x1abc9727ad0791bL,
  47918. 0x01078fa48a5e26aL, 0x17d00e384178064L, 0x090a8e4c16f7b3cL,
  47919. 0x021a4e0badb9e94L, 0x0042a9c20ef15ebL, 0x0187070758a51cfL,
  47920. 0x0f5d4fbb8989e2cL, 0x1ee5cee85564133L, 0x1e963a1af674bacL,
  47921. 0x118b8af2cd851c9L, 0x0c35c6b10cf94ebL, 0x0ee70cf2e5333feL,
  47922. 0x118d10e4bc49772L, 0x021405ce4c566e3L, 0x02fb5476e85b6e0L },
  47923. { 0x1704ca58f9a8690L, 0x14bb317bb5203c1L, 0x1631a48040a0fcdL,
  47924. 0x0d79c7499ff7825L, 0x04aab26d4cd58f1L, 0x122bd43c0233250L,
  47925. 0x05e500173eee93aL, 0x072a6f2a367714bL, 0x14ca2b9e44fe1f7L,
  47926. 0x0214566ef992bcbL, 0x168d083a890f6f9L, 0x0c57e879c03cc91L,
  47927. 0x01f27db490cce65L, 0x05fdbe784207821L, 0x01e5f4c55b32dc2L,
  47928. 0x029773666901ab5L, 0x1ac2e12e07a9eb8L, 0x00e532839653fc3L },
  47929. { 0x1b321cf2b9d25a0L, 0x1fee52053a36dfdL, 0x0c39678da2d59abL,
  47930. 0x08fb000d1f8382aL, 0x1647dd6856ed1eaL, 0x1bc6d44dba6c7f2L,
  47931. 0x0ce44765ad41e26L, 0x0be736ea487177cL, 0x0ef8d443e0d858cL,
  47932. 0x0e96da4cb23551aL, 0x14ef47999d50f13L, 0x0180d130130aff5L,
  47933. 0x1249facabad0d71L, 0x0a7cd0c94fbd7f9L, 0x0cc1e841577b070L,
  47934. 0x1fec9594cc7323fL, 0x0eeac44fd9135ffL, 0x0231657db65d69eL },
  47935. { 0x060a647de3237ddL, 0x19ae6415c3a020bL, 0x1d6777e957e257dL,
  47936. 0x1ce4d72295ef0f3L, 0x1c93e29815ef043L, 0x18c1988c3a9c9e8L,
  47937. 0x084ae868af9d1bbL, 0x0fe9cfd1bf84b53L, 0x1dfefc97da9c391L,
  47938. 0x043ae8185175f20L, 0x1748d69ccb4732fL, 0x0ffdb3754da61eeL,
  47939. 0x0b65f4857606feeL, 0x089fc1e0553c27dL, 0x03e744c8c557889L,
  47940. 0x1d5fba5f6ee307dL, 0x0082a291503b546L, 0x00949e4c6366c9bL },
  47941. { 0x078125149d53b77L, 0x1a01ecb757d63b9L, 0x1f6d28dadc469aaL,
  47942. 0x110fcee3836faf8L, 0x13b375228238c70L, 0x03a986a4afb55f9L,
  47943. 0x0446ac2c0a27232L, 0x13d9507970dcef6L, 0x1be1c0fb8a1bd18L,
  47944. 0x067d97d8d74ebe3L, 0x108f1525030fa16L, 0x1c82e95b220fa0bL,
  47945. 0x05064e714216e79L, 0x1efeb0a7d0523f8L, 0x11a622f1a4a7353L,
  47946. 0x11f63db64b09872L, 0x0ba73e4b5f3e46fL, 0x029dbcd50b4754aL },
  47947. { 0x16fafce44bbb6a1L, 0x0ddd033c10b9410L, 0x0cc2a7764e6b4e9L,
  47948. 0x1be33df5fdde3c9L, 0x1b4ec014022eaf3L, 0x16339c7f6ad5e73L,
  47949. 0x02689925a3b9944L, 0x00a462330d253fdL, 0x00d539d8d47397cL,
  47950. 0x0005e2a11a2cb62L, 0x01fd614d1984759L, 0x120793abb41f725L,
  47951. 0x17c83af2a804099L, 0x1940a8f0f2f7a4cL, 0x10044132277006cL,
  47952. 0x0593a2a1f6952b0L, 0x03340a6f7d5f387L, 0x041486b68ab6174L },
  47953. { 0x04637c6d8546946L, 0x1a51cb4f62bfd7cL, 0x06935e2401fb684L,
  47954. 0x1c1b8f7013a846bL, 0x0d6784a9b42557fL, 0x056daff31572969L,
  47955. 0x1f29689c532982fL, 0x02398411bcc6755L, 0x02380ed5ced9678L,
  47956. 0x135aaf4ed990b30L, 0x0b40b299d48d69bL, 0x1df3667f41c237dL,
  47957. 0x06f06a2a0851cc6L, 0x1623d9e7fe911f1L, 0x0aa613803cccb87L,
  47958. 0x05c288b3e52f741L, 0x1b06fa1d969ee95L, 0x0283778d59827d5L },
  47959. { 0x1b4eb2735bff163L, 0x05cb7f54fd4c208L, 0x0cfe77ac9f39c4cL,
  47960. 0x0b3ba387aacd59dL, 0x073075aaa2daf1aL, 0x038dac7a84853f5L,
  47961. 0x0b670da9abce78cL, 0x02d451ac67bbee7L, 0x0dd354cacbdc89aL,
  47962. 0x1f51a11ea6e5e1eL, 0x11d348de764b477L, 0x0adf1ddacecadddL,
  47963. 0x03fa8feb1fe14a4L, 0x1cc7e5e3fd5f3baL, 0x069c1b8501333e2L,
  47964. 0x18cf0d99a5f7feeL, 0x144daaf3fdb4d85L, 0x020adbedf8a9001L },
  47965. { 0x10105867d8377a7L, 0x11eb465c019394bL, 0x0a27c0e930c81a2L,
  47966. 0x1b2791e521facfaL, 0x09e5a2b84bc7095L, 0x15cf9db897d09e7L,
  47967. 0x1530bf1ab1b183fL, 0x00219b46db2dc1cL, 0x14549975186320aL,
  47968. 0x098c648cbf80788L, 0x1130ff9a4d9423eL, 0x1df30be0d15403bL,
  47969. 0x10a2b5511c769a2L, 0x1a0917029a91677L, 0x1d750fc01a597b6L,
  47970. 0x03ab3f9c1f5f982L, 0x19d525dc9bdec83L, 0x00f618a78d7ac43L },
  47971. { 0x063feef2c8310c2L, 0x10a6d22bf1fba03L, 0x03f394d1a21ea9fL,
  47972. 0x1ec6fd858a72562L, 0x1542f8dfcde4a38L, 0x0f0b88a83b99905L,
  47973. 0x06f18d04c0be7dfL, 0x0de031638c75c97L, 0x0f001c46edd2f9eL,
  47974. 0x1dd854b937667d0L, 0x06e675dd1b831f4L, 0x0defeb0eb5d9526L,
  47975. 0x1c96939c82e0c8bL, 0x1ef2d3325d9978bL, 0x0afe9add944d748L,
  47976. 0x00bbce326d968a5L, 0x188ad5cc08f2dc1L, 0x00bf48e893fffabL },
  47977. { 0x092ced3b7e051caL, 0x06a7e8ce3bb6a5fL, 0x0d480219e12f191L,
  47978. 0x0f9d3ad66391569L, 0x1289e9c73ea6622L, 0x150cf71ca924d1eL,
  47979. 0x16bb15142799744L, 0x01d4f7a8d25186cL, 0x1354997e477963eL,
  47980. 0x0bb2cabdaccb996L, 0x012bae47528ed83L, 0x1d483bd67c5132bL,
  47981. 0x0d572571df6e653L, 0x18c570fce53e4c7L, 0x1dee5fbcc068e3eL,
  47982. 0x141aa2c53ef84c7L, 0x001df242282afc4L, 0x008c79da59eee86L },
  47983. { 0x0a0a0a87ad4762bL, 0x1c26d462c68babaL, 0x058133ddb6186bbL,
  47984. 0x0cfcc1b3162dfe9L, 0x1ecc1dbac0be878L, 0x0b0a3d41b1bffd9L,
  47985. 0x11b970912982577L, 0x00b47c2f068b610L, 0x1735eb686e77a4cL,
  47986. 0x1e0c5a7efbac34aL, 0x06342c6f7f94bd6L, 0x181a00e2b7422acL,
  47987. 0x1ac2dd617f878ecL, 0x10db0b880edede8L, 0x1d64f08874ad8c4L,
  47988. 0x0e048459d14f289L, 0x1273b9b536a44f1L, 0x000e8533e4681f3L },
  47989. { 0x19642361e46533cL, 0x1bcc87dc461573dL, 0x145a90b12863a51L,
  47990. 0x1bb078f48a0336bL, 0x0cb663e37135e81L, 0x1606b1ba534deeaL,
  47991. 0x03699ed9fb36f9dL, 0x01407aa8a4223cdL, 0x1596cceb5d2e865L,
  47992. 0x0ab96fe95781d9bL, 0x192e87eaf5654b3L, 0x08ad69db0ad2a46L,
  47993. 0x12c950d5d47f47dL, 0x043717c22d6c5abL, 0x1aec1132b74b7e9L,
  47994. 0x011cdbaa4f6878aL, 0x00fc9adba24997cL, 0x00db12d833ed319L },
  47995. { 0x0dfaa7b4fd8446dL, 0x19780d7b7f5f5a2L, 0x0e23fa20e2d7006L,
  47996. 0x1f7752eb177e888L, 0x07156bc9f33c434L, 0x0484c595cb8e5d4L,
  47997. 0x11775ac9179707dL, 0x1af0fb96a685683L, 0x0db1f80c634d852L,
  47998. 0x0b7192c1219ed1aL, 0x008194fdf7c309bL, 0x0cf86c1966cbecdL,
  47999. 0x029826656ac4ca5L, 0x1f834bb4190fd56L, 0x01d98e44fd729beL,
  48000. 0x0e6dc2a72f2434eL, 0x08dbdf143288400L, 0x0199f654b0cfe4aL },
  48001. { 0x1337948ac775d81L, 0x128c7ea0edde511L, 0x093ef3f3a520e30L,
  48002. 0x0ca8e07fcec478fL, 0x13fb3b5baad3623L, 0x0e00f8159d09d20L,
  48003. 0x0598576cd5969fdL, 0x123ae4811b8a46bL, 0x15a17f8e51d616eL,
  48004. 0x060b775e592dcccL, 0x1a33c4ce4dd0fa4L, 0x0e95ca96c94fe6bL,
  48005. 0x0a65cd449d987daL, 0x1bf3d8aeaabd991L, 0x1344d3dd9420a94L,
  48006. 0x00e8c9a4b8e85e5L, 0x135ae9d9c074ccfL, 0x0397e1088439468L },
  48007. { 0x106b203f96004c8L, 0x1cae7a2c02affd4L, 0x019d57cd642760fL,
  48008. 0x17caa191ddaefabL, 0x15a060814a9ea6fL, 0x14103148e46654aL,
  48009. 0x1e179287fb9e2f3L, 0x0cdd735bc0d347bL, 0x1fbbdcf0c7d3de6L,
  48010. 0x1451c8dae99b6a8L, 0x1e34a170bff0f08L, 0x1bc65ef62cb6ec1L,
  48011. 0x04561770401ee48L, 0x0ef7fcd001c01ecL, 0x1f8d69395cfd922L,
  48012. 0x14d8dc344e71d42L, 0x12d238ef17c8840L, 0x02404a37c588f6cL },
  48013. { 0x0c747a8fd71f119L, 0x12e2f29f59b4ac2L, 0x1e198a6161e8679L,
  48014. 0x135631ade81c5ecL, 0x0630b8c048a4889L, 0x157c4950d4c8126L,
  48015. 0x15892125d4258b2L, 0x1a9910d3575c41fL, 0x03b72b04d6c2b7dL,
  48016. 0x13baf5b04c97be8L, 0x0701b9f41b9a138L, 0x06c3c977a00e011L,
  48017. 0x0b4ba846e4cb3b4L, 0x032326cf50d7333L, 0x1e14e7f0070bac9L,
  48018. 0x15f8ff0de57cd83L, 0x10216e8e8aecf68L, 0x046d5b0fee39c34L },
  48019. { 0x0a5c903d54d1d45L, 0x014bf7fa7cdd121L, 0x1480d351e2d2b35L,
  48020. 0x161188c4345b116L, 0x1486540235b2ba2L, 0x0f997369e91cdd9L,
  48021. 0x1f708779dabb644L, 0x0050eff179e7e0dL, 0x1802714c19ec515L,
  48022. 0x0822275d2c83806L, 0x108a7cc773255e8L, 0x0f57702d3fdb0d2L,
  48023. 0x152caf080e5ece7L, 0x05ebe778aadf450L, 0x0e5fb84fac86c53L,
  48024. 0x0d2193bdef5a2cfL, 0x1e7e03ca879118fL, 0x037bbf316fccd94L },
  48025. { 0x071bdede40bbf59L, 0x1d229b200d56b51L, 0x00d5cd5073445deL,
  48026. 0x0c96e3605e2eabcL, 0x0813359f3465b46L, 0x1c75639175b889dL,
  48027. 0x1ced65e4aa3f5bcL, 0x17e2354025ffe77L, 0x099aafabff85c3fL,
  48028. 0x0f0517783606621L, 0x15755ddcedecea4L, 0x1cedacd30814629L,
  48029. 0x132e5a8be6ae5e2L, 0x00e7aac04309b03L, 0x0fb440bb9b5d5e3L,
  48030. 0x1e1d64689c01ed1L, 0x180799d78868184L, 0x031c0ce48e1e967L },
  48031. { 0x05392e17884b073L, 0x1d0fe758933f565L, 0x17c241c0e29e7b0L,
  48032. 0x19c988f6e07a0feL, 0x1bf96b91cb2ac07L, 0x1527dffcb332770L,
  48033. 0x19403afd5d624abL, 0x008b557e723f5bcL, 0x0c5b3376f171d12L,
  48034. 0x1fb0628d069ec0dL, 0x0b3f9e5daa112c7L, 0x19357b4c24b4216L,
  48035. 0x134ebd453ee131cL, 0x0825b5e0f07e0b6L, 0x0be32af0340c669L,
  48036. 0x1368fc87417ce14L, 0x1eec80afeec55e4L, 0x033ea46894132ebL },
  48037. { 0x08d59a7ea2d56d6L, 0x15e8713a4053183L, 0x16c2b9cd9b375c6L,
  48038. 0x140e409d78d7a23L, 0x177e6293fbb639cL, 0x1d461ec4d12173fL,
  48039. 0x1e6a37b9f28add6L, 0x0208e5bb87ac945L, 0x084229df47561a0L,
  48040. 0x0fb1642e2db24eaL, 0x15ac6d37249f365L, 0x0240bdcc0b2dfbaL,
  48041. 0x10abf29401fe8bbL, 0x0868e0c21f7e552L, 0x0c077d75240343cL,
  48042. 0x087ea59e2275251L, 0x1c7a3d7ebc31f0eL, 0x013ca871c741c26L },
  48043. { 0x0b21ff0e1d0fa79L, 0x1e8198245aef4f5L, 0x1a24bf8dd32d2e7L,
  48044. 0x149d643ed699268L, 0x0925e7e7bb4827fL, 0x0a6298a338b7bcdL,
  48045. 0x1b77c510afcd9f7L, 0x11240e72a99a5d2L, 0x14e0141ae8502aaL,
  48046. 0x170070d4777b664L, 0x1a1245620336be3L, 0x14b8d2c5008cab9L,
  48047. 0x185d15dfbfff3abL, 0x0fb4279299ae627L, 0x0796f629fc11032L,
  48048. 0x04b575d008a7f76L, 0x171a1c99813ff22L, 0x02a7fbc423cd92eL },
  48049. { 0x1c6ee30de40b068L, 0x1232df379d28f13L, 0x1813e8ec87da489L,
  48050. 0x1b8083022bc4948L, 0x0df90d2b50a5a5aL, 0x186007f1942a20cL,
  48051. 0x0238eedd3963f72L, 0x1938d1e36769458L, 0x1339df0810ccd9eL,
  48052. 0x0a9b16e5bc3754fL, 0x1178c72556bab64L, 0x003b16d4d8d6512L,
  48053. 0x1c3678a427d6a2cL, 0x14649816034f416L, 0x08407985e1d5400L,
  48054. 0x1650d159b52cb3fL, 0x0fe4e4e4573ee30L, 0x0456dd6c29f8c18L },
  48055. { 0x00ae11f0969d524L, 0x1ed7bf9cde63c83L, 0x1d99f307f30bd0bL,
  48056. 0x05c466da9e79d8cL, 0x0e1c0f7f456b9cfL, 0x027d873550faef4L,
  48057. 0x12ca336f0ab4826L, 0x1de81219f4c368cL, 0x140d86f301243f3L,
  48058. 0x0d8b66666af43f3L, 0x1c5a30c09b35065L, 0x0d9702d80e60807L,
  48059. 0x1358407a1ddbe38L, 0x0b8bf0d78a75c37L, 0x12f25b3d622d3e0L,
  48060. 0x0e3836eb8834ccdL, 0x05ff342c1aa027eL, 0x039c9801b604a2fL },
  48061. { 0x14f757d22cdaf42L, 0x1ac8efa0c0d55caL, 0x0067d5453c95e22L,
  48062. 0x11e31fab791730dL, 0x022ceb9169642e0L, 0x07b4c2c95982e88L,
  48063. 0x072b85c5640f9a9L, 0x15497afad3ac22fL, 0x0dacdfd5dd29c01L,
  48064. 0x02eeead6c888466L, 0x0b1ec592b23c55cL, 0x09c36a48c65e869L,
  48065. 0x1b731fc44761a51L, 0x104b0d98a2dcf30L, 0x1abc88f3d584d23L,
  48066. 0x133a7385152cee7L, 0x1e25bd10182aa7cL, 0x045e376257214b2L },
  48067. { 0x096e5c0e7f2a32bL, 0x04006049c451868L, 0x0df10078d833fd5L,
  48068. 0x1976c0a94c0dfc8L, 0x0457aa6e6655fc9L, 0x14d95ba8870c304L,
  48069. 0x1698682b3f288acL, 0x194e64907c6a36fL, 0x1e31471ee6be6c8L,
  48070. 0x0b2a18e45b2e4d0L, 0x0b0ee5235972ef9L, 0x18435d365551f93L,
  48071. 0x0daa60aa6ad308fL, 0x0c17e06a6b53ef8L, 0x11e935ca11365aaL,
  48072. 0x112ab56025858b0L, 0x0152b3c8f71dcebL, 0x04742a1bedf4e3fL },
  48073. };
  48074. /* Perform the modular exponentiation in Fp* for SAKKE.
  48075. *
  48076. * Base is fixed to be the g parameter - a precomputed table is used.
  48077. *
  48078. * Striping: 128 points at a distance of 8 combined.
  48079. * Total of 256 points in table.
  48080. * Square and multiply performed in Fp*.
  48081. *
  48082. * base [in] Base. MP integer.
  48083. * exp [in] Exponent. MP integer.
  48084. * res [out] Result. MP integer.
  48085. * returns 0 on success, MP_READ_E if there are too many bytes in an array
  48086. * and MEMORY_E if memory allocation fails.
  48087. */
  48088. int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res)
  48089. {
  48090. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  48091. defined(WOLFSSL_SP_SMALL_STACK)
  48092. sp_digit* td;
  48093. sp_digit* t;
  48094. sp_digit* tx;
  48095. sp_digit* ty;
  48096. #else
  48097. sp_digit t[36 * 2 * 18];
  48098. sp_digit tx[2 * 18];
  48099. sp_digit ty[2 * 18];
  48100. #endif
  48101. sp_digit* r = NULL;
  48102. unsigned char e[128];
  48103. int err = MP_OKAY;
  48104. int i;
  48105. int y;
  48106. (void)base;
  48107. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  48108. defined(WOLFSSL_SP_SMALL_STACK)
  48109. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 38 * 18 * 2, NULL,
  48110. DYNAMIC_TYPE_TMP_BUFFER);
  48111. if (td == NULL) {
  48112. err = MEMORY_E;
  48113. }
  48114. #endif
  48115. if (err == MP_OKAY) {
  48116. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  48117. defined(WOLFSSL_SP_SMALL_STACK)
  48118. t = td;
  48119. tx = td + 36 * 18 * 2;
  48120. ty = td + 37 * 18 * 2;
  48121. #endif
  48122. r = ty;
  48123. (void)mp_to_unsigned_bin_len(exp, e, 128);
  48124. XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 18);
  48125. y = e[112] >> 7;
  48126. y |= (e[96] >> 7) << 1;
  48127. y |= (e[80] >> 7) << 2;
  48128. y |= (e[64] >> 7) << 3;
  48129. y |= (e[48] >> 7) << 4;
  48130. y |= (e[32] >> 7) << 5;
  48131. y |= (e[16] >> 7) << 6;
  48132. y |= (e[0] >> 7) << 7;
  48133. XMEMCPY(ty, sp_1024_g_table[y], sizeof(sp_digit) * 18);
  48134. for (i = 126; i >= 0; i--) {
  48135. y = (e[127 - (i / 8)] >> (i & 0x7)) & 1;
  48136. y |= ((e[111 - (i / 8)] >> (i & 0x7)) & 1) << 1;
  48137. y |= ((e[95 - (i / 8)] >> (i & 0x7)) & 1) << 2;
  48138. y |= ((e[79 - (i / 8)] >> (i & 0x7)) & 1) << 3;
  48139. y |= ((e[63 - (i / 8)] >> (i & 0x7)) & 1) << 4;
  48140. y |= ((e[47 - (i / 8)] >> (i & 0x7)) & 1) << 5;
  48141. y |= ((e[31 - (i / 8)] >> (i & 0x7)) & 1) << 6;
  48142. y |= ((e[15 - (i / 8)] >> (i & 0x7)) & 1) << 7;
  48143. sp_1024_proj_sqr_18(tx, ty, t);
  48144. sp_1024_proj_mul_qx1_18(tx, ty, sp_1024_g_table[y], t);
  48145. }
  48146. }
  48147. if (err == MP_OKAY) {
  48148. sp_1024_mont_inv_18(tx, tx, t);
  48149. sp_1024_mont_mul_18(r, tx, ty, p1024_mod, p1024_mp_mod);
  48150. XMEMSET(r + 18, 0, sizeof(sp_digit) * 18);
  48151. sp_1024_mont_reduce_18(r, p1024_mod, p1024_mp_mod);
  48152. err = sp_1024_to_mp(r, res);
  48153. }
  48154. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  48155. defined(WOLFSSL_SP_SMALL_STACK)
  48156. if (td != NULL) {
  48157. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  48158. }
  48159. #endif
  48160. return err;
  48161. }
  48162. #endif /* WOLFSSL_SP_SMALL */
  48163. /* Multiply p* by q* in projective coordinates.
  48164. *
  48165. * p.x' = (p.x * q.x) - (p.y * q.y)
  48166. * p.y' = (p.x * q.y) + (p.y * q.x)
  48167. * But applying Karatsuba:
  48168. * v0 = p.x * q.x
  48169. * v1 = p.y * q.y
  48170. * p.x' = v0 - v1
  48171. * p.y' = (px + py) * (qx + qy) - v0 - v1
  48172. *
  48173. * px [in,out] A single precision integer - X ordinate of number to multiply.
  48174. * py [in,out] A single precision integer - Y ordinate of number to multiply.
  48175. * qx [in] A single precision integer - X ordinate of number of
  48176. * multiplier.
  48177. * qy [in] A single precision integer - Y ordinate of number of
  48178. * multiplier.
  48179. * t [in] Two single precision integers - temps.
  48180. */
  48181. static void sp_1024_proj_mul_18(sp_digit* px, sp_digit* py,
  48182. const sp_digit* qx, const sp_digit* qy, sp_digit* t)
  48183. {
  48184. sp_digit* t1 = t;
  48185. sp_digit* t2 = t + 2 * 18;
  48186. /* t1 = px + py */
  48187. sp_1024_mont_add_18(t1, px, py, p1024_mod);
  48188. /* t2 = qx + qy */
  48189. sp_1024_mont_add_18(t2, qx, qy, p1024_mod);
  48190. /* t2 = (px + py) * (qx + qy) */
  48191. sp_1024_mont_mul_18(t2, t1, t2, p1024_mod, p1024_mp_mod);
  48192. /* t1 = py * qy */
  48193. sp_1024_mont_mul_18(t1, py, qy, p1024_mod, p1024_mp_mod);
  48194. /* t2 = (px + py) * (qx + qy) - (py * qy) */
  48195. sp_1024_mont_sub_18(t2, t2, t1, p1024_mod);
  48196. /* px = px * qx */
  48197. sp_1024_mont_mul_18(px, px, qx, p1024_mod, p1024_mp_mod);
  48198. /* py = (px + py) * (qx + qy) - (py * qy) - (px * qx) */
  48199. sp_1024_mont_sub_18(py, t2, px, p1024_mod);
  48200. /* px = (px * qx) - (py * qy)*/
  48201. sp_1024_mont_sub_18(px, px, t1, p1024_mod);
  48202. }
  48203. #ifndef WOLFSSL_SP_SMALL
  48204. /*
  48205. * Convert point from projective to affine but keep in Montgomery form.
  48206. *
  48207. * p [in,out] Point to convert.
  48208. * t [in] Temporary numbers: 2.
  48209. */
  48210. static void sp_1024_mont_map_18(sp_point_1024* p, sp_digit* t)
  48211. {
  48212. sp_digit* t1 = t;
  48213. sp_digit* t2 = t + 2 * 18;
  48214. sp_1024_mont_inv_18(t1, p->z, t2);
  48215. sp_1024_mont_sqr_18(t2, t1, p1024_mod, p1024_mp_mod);
  48216. sp_1024_mont_mul_18(t1, t2, t1, p1024_mod, p1024_mp_mod);
  48217. sp_1024_mont_mul_18(p->x, p->x, t2, p1024_mod, p1024_mp_mod);
  48218. sp_1024_mont_mul_18(p->y, p->y, t1, p1024_mod, p1024_mp_mod);
  48219. XMEMCPY(p->z, p1024_norm_mod, sizeof(sp_digit) * 18);
  48220. }
  48221. #endif /* WOLFSSL_SP_SMALL */
  48222. /*
  48223. * Calculate gradient of line through P, P and [-2]P, accumulate line and
  48224. * double P.
  48225. *
  48226. * Calculations:
  48227. * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2)
  48228. * r.x = l * (p.x + q.x * p.z^2) - 2 * p.y^2
  48229. * r.y = 2 * p.y * p.z^3 * q.y (= p'.z * p.z^2 * q.y)
  48230. * v* = v*^2 * r*
  48231. * p'.x = l^2 - 8 * p.y^2 * p.x
  48232. * p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4
  48233. * p'.z = 2 * p.y * p.z
  48234. *
  48235. * @param [in,out] vx X-ordinate of projective value in F*.
  48236. * @param [in,out] vy Y-ordinate of projective value in F*.
  48237. * @param [in,out] p ECC point - point on E(F_p^2) to double.
  48238. * @param [in] q ECC point - second point on E(F_P^2).
  48239. * @param [in] t SP temporaries (6 used).
  48240. */
  48241. static void sp_1024_accumulate_line_dbl_18(sp_digit* vx, sp_digit* vy,
  48242. sp_point_1024* p, const sp_point_1024* q, sp_digit* t)
  48243. {
  48244. sp_digit* t1 = t + 0 * 18;
  48245. sp_digit* pz2 = t + 2 * 18;
  48246. sp_digit* rx = t + 4 * 18;
  48247. sp_digit* ry = t + 6 * 18;
  48248. sp_digit* l = t + 8 * 18;
  48249. sp_digit* ty = t + 10 * 18;
  48250. /* v = v^2 */
  48251. sp_1024_proj_sqr_18(vx, vy, t);
  48252. /* pz2 = p.z^2 */
  48253. sp_1024_mont_sqr_18(pz2, p->z, p1024_mod, p1024_mp_mod);
  48254. /* t1 = p.x + p.z^2 */
  48255. sp_1024_mont_add_18(ty, p->x, pz2, p1024_mod);
  48256. /* l = p.x - p.z^2 */
  48257. sp_1024_mont_sub_18(l, p->x, pz2, p1024_mod);
  48258. /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */
  48259. sp_1024_mont_mul_18(t1, l, ty, p1024_mod, p1024_mp_mod);
  48260. /* l = 3 * (p.x^2 - p.z^4) */
  48261. sp_1024_mont_tpl_18(l, t1, p1024_mod);
  48262. /* t1 = q.x * p.z^2 */
  48263. sp_1024_mont_mul_18(t1, q->x, pz2, p1024_mod, p1024_mp_mod);
  48264. /* t1 = p.x + q.x * p.z^2 */
  48265. sp_1024_mont_add_18(t1, p->x, t1, p1024_mod);
  48266. /* r.x = l * (p.x + q.x * p.z^2) */
  48267. sp_1024_mont_mul_18(rx, l, t1, p1024_mod, p1024_mp_mod);
  48268. /* r.y = 2 * p.y */
  48269. sp_1024_mont_dbl_18(ry, p->y, p1024_mod);
  48270. /* ty = 4 * p.y ^ 2 */
  48271. sp_1024_mont_sqr_18(ty, ry, p1024_mod, p1024_mp_mod);
  48272. /* t1 = 2 * p.y ^ 2 */
  48273. sp_1024_mont_div2_18(t1, ty, p1024_mod);
  48274. /* r.x -= 2 * (p.y ^ 2) */
  48275. sp_1024_mont_sub_18(rx, rx, t1, p1024_mod);
  48276. /* p'.z = p.y * 2 * p.z */
  48277. sp_1024_mont_mul_18(p->z, p->z, ry, p1024_mod, p1024_mp_mod);
  48278. /* r.y = p'.z * p.z^2 */
  48279. sp_1024_mont_mul_18(t1, p->z, pz2, p1024_mod, p1024_mp_mod);
  48280. /* r.y = p'.z * p.z^2 * q.y */
  48281. sp_1024_mont_mul_18(ry, t1, q->y, p1024_mod, p1024_mp_mod);
  48282. /* v = v^2 * r */
  48283. sp_1024_proj_mul_18(vx, vy, rx, ry, t);
  48284. /* Double point using previously calculated values
  48285. * l = 3 * (p.x - p.z^2).(p.x + p.z^2)
  48286. * ty = 4 * p.y^2
  48287. * p'.z = 2 * p.y * p.z
  48288. */
  48289. /* t1 = (4 * p.y^2) ^ 2 = 16 * p.y^4 */
  48290. sp_1024_mont_sqr_18(t1, ty, p1024_mod, p1024_mp_mod);
  48291. /* t1 = 16 * p.y^4 / 2 = 8 * p.y^4 */
  48292. sp_1024_mont_div2_18(t1, t1, p1024_mod);
  48293. /* p'.y = 4 * p.y^2 * p.x */
  48294. sp_1024_mont_mul_18(p->y, ty, p->x, p1024_mod, p1024_mp_mod);
  48295. /* p'.x = l^2 */
  48296. sp_1024_mont_sqr_18(p->x, l, p1024_mod, p1024_mp_mod);
  48297. /* p'.x = l^2 - 4 * p.y^2 * p.x */
  48298. sp_1024_mont_sub_18(p->x, p->x, p->y, p1024_mod);
  48299. /* p'.x = l^2 - 8 * p.y^2 * p.x */
  48300. sp_1024_mont_sub_18(p->x, p->x, p->y, p1024_mod);
  48301. /* p'.y = 4 * p.y^2 * p.x - p.x' */
  48302. sp_1024_mont_sub_18(ty, p->y, p->x, p1024_mod);
  48303. /* p'.y = (4 * p.y^2 * p.x - p'.x) * l */
  48304. sp_1024_mont_mul_18(p->y, ty, l, p1024_mod, p1024_mp_mod);
  48305. /* p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 */
  48306. sp_1024_mont_sub_18(p->y, p->y, t1, p1024_mod);
  48307. }
  48308. #ifdef WOLFSSL_SP_SMALL
  48309. /*
  48310. * Calculate gradient of line through C, P and -C-P, accumulate line and
  48311. * add P to C.
  48312. *
  48313. * Calculations:
  48314. * r.x = (q.x + p.x) * c.y - (q.x * c.z^2 + c.x) * p.y * c.z
  48315. * r.y = (c.x - p.x * c.z^2) * q.y * c.z
  48316. * v* = v* * r*
  48317. * r = p.y * c.z^3 - c.y
  48318. * c'.x = r^2 + h^3 - 2 * c.x * h^2
  48319. * c'.y = r * (c'.x - c.x * h^2) - c.y * h^3
  48320. * c'.z = (c.x - p.x * c.z^2) * c.z
  48321. *
  48322. * @param [in,out] vx X-ordinate of projective value in F*.
  48323. * @param [in,out] vy Y-ordinate of projective value in F*.
  48324. * @param [in,out] c ECC point - current point on E(F_p^2) to be added
  48325. * to.
  48326. * @param [in] p ECC point - point on E(F_p^2) to add.
  48327. * @param [in] q ECC point - second point on E(F_P^2).
  48328. * @param [in] qx_px SP that is a constant value across adds.
  48329. * @param [in] t SP temporaries (6 used).
  48330. */
  48331. static void sp_1024_accumulate_line_add_one_18(sp_digit* vx, sp_digit* vy,
  48332. sp_point_1024* c, sp_point_1024* p, sp_point_1024* q, sp_digit* qx_px,
  48333. sp_digit* t)
  48334. {
  48335. sp_digit* t1 = t;
  48336. sp_digit* t2 = t + 2 * 18;
  48337. sp_digit* rx = t + 4 * 18;
  48338. sp_digit* ry = t + 6 * 18;
  48339. sp_digit* h = t + 8 * 18;
  48340. sp_digit* r = t + 10 * 18;
  48341. /* r.x = (q.x + p.x) * c.y */
  48342. sp_1024_mont_mul_18(rx, qx_px, c->y, p1024_mod, p1024_mp_mod);
  48343. /* t2 = c.z^2 */
  48344. sp_1024_mont_sqr_18(t2, c->z, p1024_mod, p1024_mp_mod);
  48345. /* t1 = q.x * c.z^2 */
  48346. sp_1024_mont_mul_18(t1, q->x, t2, p1024_mod, p1024_mp_mod);
  48347. /* t1 = q.x * c.z^2 + c.x */
  48348. sp_1024_mont_add_18(h, t1, c->x, p1024_mod);
  48349. /* r = p.y * c.z */
  48350. sp_1024_mont_mul_18(ry, p->y, c->z, p1024_mod, p1024_mp_mod);
  48351. /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */
  48352. sp_1024_mont_mul_18(t1, h, ry, p1024_mod, p1024_mp_mod);
  48353. /* r = p.y * c.z * c.z^2 = p.y * c.z^3 */
  48354. sp_1024_mont_mul_18(r, ry, t2, p1024_mod, p1024_mp_mod);
  48355. /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */
  48356. sp_1024_mont_sub_18(rx, rx, t1, p1024_mod);
  48357. /* t1 = p.x * c.z^2 */
  48358. sp_1024_mont_mul_18(t1, p->x, t2, p1024_mod, p1024_mp_mod);
  48359. /* h = c.x - p.x * c.z^2 */
  48360. sp_1024_mont_sub_18(h, c->x, t1, p1024_mod);
  48361. /* c'.z = (c.x - p.x * c.z^2) * c.z */
  48362. sp_1024_mont_mul_18(c->z, h, c->z, p1024_mod, p1024_mp_mod);
  48363. /* r.y = (c.x - p.x * c.z^2) * c.z * q.y */
  48364. sp_1024_mont_mul_18(ry, c->z, q->y, p1024_mod, p1024_mp_mod);
  48365. /* v = v * r */
  48366. sp_1024_proj_mul_18(vx, vy, rx, ry, t);
  48367. /* Add p to c using previously calculated values.
  48368. * h = c.x - p.x * c.z^2
  48369. * r = p.y * c.z^3
  48370. * c'.z = (c.x - p.x * c.z^2) * c.z
  48371. */
  48372. /* r = p.y * c.z^3 - c.y */
  48373. sp_1024_mont_sub_18(r, r, c->y, p1024_mod);
  48374. /* t1 = r^2 */
  48375. sp_1024_mont_sqr_18(t1, r, p1024_mod, p1024_mp_mod);
  48376. /* t2 = h^2 */
  48377. sp_1024_mont_sqr_18(rx, h, p1024_mod, p1024_mp_mod);
  48378. /* ry = c.x * h^2 */
  48379. sp_1024_mont_mul_18(ry, c->x, rx, p1024_mod, p1024_mp_mod);
  48380. /* t2 = h^3 */
  48381. sp_1024_mont_mul_18(t2, rx, h, p1024_mod, p1024_mp_mod);
  48382. /* c->x = r^2 + h^3 */
  48383. sp_1024_mont_add_18(c->x, t1, t2, p1024_mod);
  48384. /* t1 = 2 * c.x * h^2 */
  48385. sp_1024_mont_dbl_18(t1, ry, p1024_mod);
  48386. /* c'.x = r^2 + h^3 - 2 * c.x * h^2 */
  48387. sp_1024_mont_sub_18(c->x, c->x, t1, p1024_mod);
  48388. /* ry = c'.x - c.x * h^2 */
  48389. sp_1024_mont_sub_18(t1, c->x, ry, p1024_mod);
  48390. /* ry = r * (c'.x - c.x * h^2) */
  48391. sp_1024_mont_mul_18(ry, t1, r, p1024_mod, p1024_mp_mod);
  48392. /* t2 = c.y * h^3 */
  48393. sp_1024_mont_mul_18(t1, t2, c->y, p1024_mod, p1024_mp_mod);
  48394. /* c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 */
  48395. sp_1024_mont_sub_18(c->y, ry, t1, p1024_mod);
  48396. }
  48397. /*
  48398. * Calculate r = pairing <P, Q>.
  48399. *
  48400. * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q.
  48401. *
  48402. * @param [in] key SAKKE key.
  48403. * @param [in] p First point on E(F_p)[q].
  48404. * @param [in] q Second point on E(F_p)[q].
  48405. * @param [in] r Result of calculation.
  48406. * @return 0 on success.
  48407. * @return MEMORY_E when dynamic memory allocation fails.
  48408. * @return Other -ve value on internal failure.
  48409. */
  48410. int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res)
  48411. {
  48412. int err = MP_OKAY;
  48413. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  48414. defined(WOLFSSL_SP_SMALL_STACK)
  48415. sp_digit* td = NULL;
  48416. sp_digit* t;
  48417. sp_digit* vx;
  48418. sp_digit* vy;
  48419. sp_digit* qx_px;
  48420. #else
  48421. sp_digit t[36 * 2 * 18];
  48422. sp_digit vx[2 * 18];
  48423. sp_digit vy[2 * 18];
  48424. sp_digit qx_px[2 * 18];
  48425. sp_point_1024 pd;
  48426. sp_point_1024 qd;
  48427. sp_point_1024 cd;
  48428. #endif
  48429. sp_point_1024* p = NULL;
  48430. sp_point_1024* q = NULL;
  48431. sp_point_1024* c = NULL;
  48432. sp_digit* r = NULL;
  48433. int i;
  48434. err = sp_1024_point_new_18(NULL, pd, p);
  48435. if (err == MP_OKAY) {
  48436. err = sp_1024_point_new_18(NULL, qd, q);
  48437. }
  48438. if (err == MP_OKAY) {
  48439. err = sp_1024_point_new_18(NULL, cd, c);
  48440. }
  48441. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  48442. defined(WOLFSSL_SP_SMALL_STACK)
  48443. if (err == MP_OKAY) {
  48444. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 39 * 18 * 2, NULL,
  48445. DYNAMIC_TYPE_TMP_BUFFER);
  48446. if (td == NULL) {
  48447. err = MEMORY_E;
  48448. }
  48449. }
  48450. #endif
  48451. if (err == MP_OKAY) {
  48452. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  48453. defined(WOLFSSL_SP_SMALL_STACK)
  48454. t = td;
  48455. vx = td + 36 * 18 * 2;
  48456. vy = td + 37 * 18 * 2;
  48457. qx_px = td + 38 * 18 * 2;
  48458. #endif
  48459. r = vy;
  48460. sp_1024_point_from_ecc_point_18(p, pm);
  48461. sp_1024_point_from_ecc_point_18(q, qm);
  48462. err = sp_1024_mod_mul_norm_18(p->x, p->x, p1024_mod);
  48463. }
  48464. if (err == MP_OKAY) {
  48465. err = sp_1024_mod_mul_norm_18(p->y, p->y, p1024_mod);
  48466. }
  48467. if (err == MP_OKAY) {
  48468. err = sp_1024_mod_mul_norm_18(p->z, p->z, p1024_mod);
  48469. }
  48470. if (err == MP_OKAY) {
  48471. err = sp_1024_mod_mul_norm_18(q->x, q->x, p1024_mod);
  48472. }
  48473. if (err == MP_OKAY) {
  48474. err = sp_1024_mod_mul_norm_18(q->y, q->y, p1024_mod);
  48475. }
  48476. if (err == MP_OKAY) {
  48477. XMEMCPY(c, p, sizeof(sp_point_1024));
  48478. XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 18);
  48479. vx[0] = 1;
  48480. XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 18);
  48481. sp_1024_mont_add_18(qx_px, q->x, p->x, p1024_mod);
  48482. for (i = 1020; i >= 0; i--) {
  48483. /* Accumulate line into v and double point. */
  48484. sp_1024_accumulate_line_dbl_18(vx, vy, c, q, t);
  48485. if ((i > 0) && ((p1024_order[i / 57] >> (i % 57)) & 1)) {
  48486. /* Accumulate line into v and add P into C. */
  48487. sp_1024_accumulate_line_add_one_18(vx, vy, c, p, q, qx_px, t);
  48488. }
  48489. }
  48490. /* Final exponentiation */
  48491. sp_1024_proj_sqr_18(vx, vy, t);
  48492. sp_1024_proj_sqr_18(vx, vy, t);
  48493. /* Convert from PF_p[q] to F_p */
  48494. sp_1024_mont_inv_18(vx, vx, t);
  48495. sp_1024_mont_mul_18(r, vx, vy, p1024_mod, p1024_mp_mod);
  48496. XMEMSET(r + 18, 0, sizeof(sp_digit) * 18);
  48497. sp_1024_mont_reduce_18(r, p1024_mod, p1024_mp_mod);
  48498. err = sp_1024_to_mp(r, res);
  48499. }
  48500. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  48501. defined(WOLFSSL_SP_SMALL_STACK)
  48502. if (td != NULL) {
  48503. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  48504. }
  48505. #endif
  48506. sp_1024_point_free_18(c, 1, NULL);
  48507. sp_1024_point_free_18(q, 1, NULL);
  48508. sp_1024_point_free_18(p, 1, NULL);
  48509. return err;
  48510. }
  48511. #else
  48512. /*
  48513. * Calculate gradient of line through C, P and -C-P, accumulate line and
  48514. * add P to C.
  48515. *
  48516. * Both C and P have z ordinates to use in the calculation.
  48517. *
  48518. * Calculations:
  48519. * r.x = (q.x * c.z^2 + c.x) * p.y * c.z - (q.x * p.z^2 + p.x) * c.y * p.z
  48520. * r.y = (p.x * c.z^2 - c.x * p.z^2) * q.y * p.z * c.z
  48521. * v* = v* * r*
  48522. * h = p.x * c.z^2 - c.x * p.z^2
  48523. * r = p.y * c.z^3 - c.y * p.z^3
  48524. * c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2
  48525. * c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3
  48526. * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z
  48527. *
  48528. * @param [in,out] vx X-ordinate of projective value in F*.
  48529. * @param [in,out] vy Y-ordinate of projective value in F*.
  48530. * @param [in,out] c ECC point - current point on E(F_p^2) to be added
  48531. * to.
  48532. * @param [in,out] p ECC point - point on E(F_p^2) to add.
  48533. * @param [in,out] q ECC point - second point on E(F_P^2).
  48534. * @param [in,out] t SP temporaries (6 used).
  48535. * @param [in,out] neg Indicates to use negative P.
  48536. * @return 0 on success.
  48537. * @return MEMORY_E when dynamic memory allocation fails.
  48538. * @return Other -ve value on internal failure.
  48539. */
  48540. static void sp_1024_accumulate_line_add_n_18(sp_digit* vx, sp_digit* vy,
  48541. const sp_point_1024* p, const sp_point_1024* q,
  48542. sp_point_1024* c, sp_digit* t, int neg)
  48543. {
  48544. sp_digit* t1 = t;
  48545. sp_digit* t2 = t + 2 * 18;
  48546. sp_digit* rx = t + 4 * 18;
  48547. sp_digit* ry = t + 6 * 18;
  48548. sp_digit* h = t + 8 * 18;
  48549. sp_digit* r = t + 10 * 18;
  48550. /* h = p.z^2 */
  48551. sp_1024_mont_sqr_18(h, p->z, p1024_mod, p1024_mp_mod);
  48552. /* rx = q.x * p.z^2 */
  48553. sp_1024_mont_mul_18(rx, q->x, h, p1024_mod, p1024_mp_mod);
  48554. /* rx = q.x * p.z^2 + p.x */
  48555. sp_1024_mont_add_18(t2, rx, p->x, p1024_mod);
  48556. /* c.y = c.y * p.z */
  48557. sp_1024_mont_mul_18(t1, c->y, p->z, p1024_mod, p1024_mp_mod);
  48558. /* r.x = (q.x * p.z^2 + p.x) * c.y * p.z */
  48559. sp_1024_mont_mul_18(rx, t2, t1, p1024_mod, p1024_mp_mod);
  48560. /* c.y = c.y * p.z^3 */
  48561. sp_1024_mont_mul_18(c->y, t1, h, p1024_mod, p1024_mp_mod);
  48562. /* t2 = c.z^2 */
  48563. sp_1024_mont_sqr_18(t2, c->z, p1024_mod, p1024_mp_mod);
  48564. /* t1 = q.x * c.z^2 */
  48565. sp_1024_mont_mul_18(t1, q->x, t2, p1024_mod, p1024_mp_mod);
  48566. /* t1 = q.x * c.z^2 + c.x */
  48567. sp_1024_mont_add_18(t1, t1, c->x, p1024_mod);
  48568. /* c.x = c.x * p.z^2 */
  48569. sp_1024_mont_mul_18(c->x, c->x, h, p1024_mod, p1024_mp_mod);
  48570. /* r = p.y * c.z */
  48571. sp_1024_mont_mul_18(r, p->y, c->z, p1024_mod, p1024_mp_mod);
  48572. if (neg) {
  48573. /* r = -p.y * c.z */
  48574. sp_1024_mont_sub_18(r, p1024_mod, r, p1024_mod);
  48575. }
  48576. /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */
  48577. sp_1024_mont_mul_18(ry, t1, r, p1024_mod, p1024_mp_mod);
  48578. /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */
  48579. sp_1024_mont_sub_18(rx, ry, rx, p1024_mod);
  48580. /* t1 = p.x * c.z^2 */
  48581. sp_1024_mont_mul_18(t1, p->x, t2, p1024_mod, p1024_mp_mod);
  48582. /* h = p.x * c.z^2 - c.x * p.z^2 */
  48583. sp_1024_mont_sub_18(h, t1, c->x, p1024_mod);
  48584. /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z */
  48585. sp_1024_mont_mul_18(t1, h, c->z, p1024_mod, p1024_mp_mod);
  48586. /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z */
  48587. sp_1024_mont_mul_18(c->z, t1, p->z, p1024_mod, p1024_mp_mod);
  48588. /* r.y = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z * q.y */
  48589. sp_1024_mont_mul_18(ry, c->z, q->y, p1024_mod, p1024_mp_mod);
  48590. /* r = p.y * c.z^3 */
  48591. sp_1024_mont_mul_18(t1, r, t2, p1024_mod, p1024_mp_mod);
  48592. /* r = p.y * c.z^3 - c.y * p.z^3 */
  48593. sp_1024_mont_sub_18(r, t1, c->y, p1024_mod);
  48594. /* v = v * r */
  48595. sp_1024_proj_mul_18(vx, vy, rx, ry, t);
  48596. /* Add p to c using previously calculated values.
  48597. * h = p.x * c.z^2 - c.x * p.z^2
  48598. * r = p.y * c.z^3 - c.y * p.z^3
  48599. * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z
  48600. */
  48601. /* t1 = r^2 */
  48602. sp_1024_mont_sqr_18(t1, r, p1024_mod, p1024_mp_mod);
  48603. /* t2 = h^2 */
  48604. sp_1024_mont_sqr_18(rx, h, p1024_mod, p1024_mp_mod);
  48605. /* ry = c.x * p.z^2 * h^2 */
  48606. sp_1024_mont_mul_18(ry, rx, c->x, p1024_mod, p1024_mp_mod);
  48607. /* t2 = h^3 */
  48608. sp_1024_mont_mul_18(t2, rx, h, p1024_mod, p1024_mp_mod);
  48609. /* c'.x = r^2 - h^3 */
  48610. sp_1024_mont_sub_18(c->x, t1, t2, p1024_mod);
  48611. /* t1 = 2 * c.x * p.z^2 * h^2 */
  48612. sp_1024_mont_dbl_18(t1, ry, p1024_mod);
  48613. /* c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 */
  48614. sp_1024_mont_sub_18(c->x, c->x, t1, p1024_mod);
  48615. /* ry = c.x * p.z^2 * h^2 - c'.x */
  48616. sp_1024_mont_sub_18(t1, ry, c->x, p1024_mod);
  48617. /* ry = r * (c.x * p.z^2 * h^2 - c'.x) */
  48618. sp_1024_mont_mul_18(ry, t1, r, p1024_mod, p1024_mp_mod);
  48619. /* t2 = c.y * p.z^3 * h^3 */
  48620. sp_1024_mont_mul_18(t1, t2, c->y, p1024_mod, p1024_mp_mod);
  48621. /* c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 */
  48622. sp_1024_mont_sub_18(c->y, ry, t1, p1024_mod);
  48623. }
  48624. /*
  48625. * Perform n accumulate doubles and doubles of P.
  48626. *
  48627. * py = 2 * p.y
  48628. *
  48629. * For each double:
  48630. * Calculate gradient of line through P, P and [-2]P, accumulate line and
  48631. * double P.
  48632. *
  48633. * Calculations:
  48634. * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2)
  48635. * r.x = l * (p.x + q.x * p.z^2) - py^2 / 2
  48636. * r.y = py * p.z^3 * q.y (= p'.z * p.z^2 * q.y)
  48637. * v* = v*^2 * r*
  48638. * p'.x = l^2 - 2 * py^2 * p.x
  48639. * py' = (py^2 * p.x - p'.x) * l - py^4 (= 2 * p'.y)
  48640. * p'.z = py * p.z
  48641. *
  48642. * Finally:
  48643. * p'.y = py' / 2
  48644. *
  48645. * @param [in,out] vx X-ordinate of projective value in F*.
  48646. * @param [in,out] vy Y-ordinate of projective value in F*.
  48647. * @param [in,out] p ECC point - point on E(F_p^2) to double.
  48648. * @param [in] q ECC point - second point on E(F_P^2).
  48649. * @param [in] n Number of times to double.
  48650. * @param [in] t SP temporaries (6 used).
  48651. */
  48652. static void sp_1024_accumulate_line_dbl_n_18(sp_digit* vx, sp_digit* vy,
  48653. sp_point_1024* p, const sp_point_1024* q, int n, sp_digit* t)
  48654. {
  48655. sp_digit* t1 = t + 0 * 18;
  48656. sp_digit* pz2 = t + 2 * 18;
  48657. sp_digit* rx = t + 4 * 18;
  48658. sp_digit* ry = t + 6 * 18;
  48659. sp_digit* l = t + 8 * 18;
  48660. sp_digit* ty = t + 10 * 18;
  48661. int i;
  48662. /* py = 2 * p.y */
  48663. sp_1024_mont_dbl_18(p->y, p->y, p1024_mod);
  48664. for (i = 0; i < n; i++) {
  48665. /* v = v^2 */
  48666. sp_1024_proj_sqr_18(vx, vy, t);
  48667. /* pz2 = p.z^2 */
  48668. sp_1024_mont_sqr_18(pz2, p->z, p1024_mod, p1024_mp_mod);
  48669. /* t1 = p.x + p.z^2 */
  48670. sp_1024_mont_add_18(t1, p->x, pz2, p1024_mod);
  48671. /* l = p.x - p.z^2 */
  48672. sp_1024_mont_sub_18(l, p->x, pz2, p1024_mod);
  48673. /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */
  48674. sp_1024_mont_mul_18(ty, l, t1, p1024_mod, p1024_mp_mod);
  48675. /* l = 3 * (p.x^2 - p.z^4) */
  48676. sp_1024_mont_tpl_18(l, ty, p1024_mod);
  48677. /* t1 = q.x * p.z^2 */
  48678. sp_1024_mont_mul_18(t1, q->x, pz2, p1024_mod, p1024_mp_mod);
  48679. /* t1 = p.x + q.x * p.z^2 */
  48680. sp_1024_mont_add_18(t1, p->x, t1, p1024_mod);
  48681. /* r.x = l * (p.x + q.x * p.z^2) */
  48682. sp_1024_mont_mul_18(rx, l, t1, p1024_mod, p1024_mp_mod);
  48683. /* ty = py ^ 2 */
  48684. sp_1024_mont_sqr_18(ty, p->y, p1024_mod, p1024_mp_mod);
  48685. /* t1 = py ^ 2 / 2 */
  48686. sp_1024_mont_div2_18(t1, ty, p1024_mod);
  48687. /* r.x -= py ^ 2 / 2 */
  48688. sp_1024_mont_sub_18(rx, rx, t1, p1024_mod);
  48689. /* p'.z = py * pz */
  48690. sp_1024_mont_mul_18(p->z, p->z, p->y, p1024_mod, p1024_mp_mod);
  48691. /* r.y = p'.z * p.z^2 */
  48692. sp_1024_mont_mul_18(t1, p->z, pz2, p1024_mod, p1024_mp_mod);
  48693. /* r.y = p'.z * p.z^2 * q.y */
  48694. sp_1024_mont_mul_18(ry, t1, q->y, p1024_mod, p1024_mp_mod);
  48695. /* v = v^2 * r */
  48696. sp_1024_proj_mul_18(vx, vy, rx, ry, t);
  48697. /* Double point using previously calculated values
  48698. * l = 3 * (p.x - p.z^2).(p.x + p.z^2)
  48699. * ty = py^2
  48700. * p'.z = py * p.z
  48701. */
  48702. /* t1 = py^2 ^ 2 = py^4 */
  48703. sp_1024_mont_sqr_18(t1, ty, p1024_mod, p1024_mp_mod);
  48704. /* py' = py^2 * p. x */
  48705. sp_1024_mont_mul_18(p->y, ty, p->x, p1024_mod, p1024_mp_mod);
  48706. /* p'.x = l^2 */
  48707. sp_1024_mont_sqr_18(p->x, l, p1024_mod, p1024_mp_mod);
  48708. /* p'.x = l^2 - py^2 * p.x */
  48709. sp_1024_mont_sub_18(p->x, p->x, p->y, p1024_mod);
  48710. /* p'.x = l^2 - 2 * p.y^2 * p.x */
  48711. sp_1024_mont_sub_18(p->x, p->x, p->y, p1024_mod);
  48712. /* py' = py^2 * p.x - p.x' */
  48713. sp_1024_mont_sub_18(ty, p->y, p->x, p1024_mod);
  48714. /* py' = (p.y^2 * p.x - p'.x) * l */
  48715. sp_1024_mont_mul_18(p->y, ty, l, p1024_mod, p1024_mp_mod);
  48716. /* py' = (p.y^2 * p.x - p'.x) * l * 2 */
  48717. sp_1024_mont_dbl_18(p->y, p->y, p1024_mod);
  48718. /* py' = (p.y^2 * p.x - p'.x) * l * 2 - p.y^4 */
  48719. sp_1024_mont_sub_18(p->y, p->y, t1, p1024_mod);
  48720. }
  48721. /* p'.y = py' / 2 */
  48722. sp_1024_mont_div2_18(p->y, p->y, p1024_mod);
  48723. }
  48724. /* Operations to perform based on order - 1.
  48725. * Sliding window. Start at bottom and stop when bottom bit is one.
  48726. * Subtract if top bit in window is one.
  48727. * Width of 6 bits.
  48728. * Pairs: #dbls, add/subtract window value
  48729. */
  48730. static const signed char sp_1024_order_op[] = {
  48731. 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9,
  48732. -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6,
  48733. -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8,
  48734. 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7,
  48735. -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6,
  48736. -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7,
  48737. -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7,
  48738. -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7,
  48739. -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6,
  48740. 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6,
  48741. -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6,
  48742. -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10,
  48743. 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7,
  48744. -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7,
  48745. 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6,
  48746. -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12,
  48747. 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8,
  48748. -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10,
  48749. -3, 1,
  48750. };
  48751. /*
  48752. * Calculate r = pairing <P, Q>.
  48753. *
  48754. * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q.
  48755. *
  48756. * Sliding window. Start at bottom and stop when bottom bit is one.
  48757. * Subtract if top bit in window is one.
  48758. * Width of 6 bits.
  48759. *
  48760. * @param [in] pm First point on E(F_p)[q].
  48761. * @param [in] qm Second point on E(F_p)[q].
  48762. * @param [in] res Result of calculation.
  48763. * @return 0 on success.
  48764. * @return MEMORY_E when dynamic memory allocation fails.
  48765. */
  48766. int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res)
  48767. {
  48768. int err;
  48769. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  48770. defined(WOLFSSL_SP_SMALL_STACK)
  48771. sp_digit* td = NULL;
  48772. sp_digit* t;
  48773. sp_digit* vx;
  48774. sp_digit* vy;
  48775. sp_digit (*pre_vx)[36];
  48776. sp_digit (*pre_vy)[36];
  48777. sp_digit (*pre_nvy)[36];
  48778. sp_point_1024* pre_p;
  48779. #else
  48780. sp_digit t[36 * 2 * 18];
  48781. sp_digit vx[2 * 18];
  48782. sp_digit vy[2 * 18];
  48783. sp_digit pre_vx[16][36];
  48784. sp_digit pre_vy[16][36];
  48785. sp_digit pre_nvy[16][36];
  48786. sp_point_1024 pre_p[16];
  48787. sp_point_1024 pd;
  48788. sp_point_1024 qd;
  48789. sp_point_1024 cd;
  48790. #endif
  48791. sp_point_1024* p = NULL;
  48792. sp_point_1024* q = NULL;
  48793. sp_point_1024* c = NULL;
  48794. sp_digit* r = NULL;
  48795. int i;
  48796. int j;
  48797. err = sp_1024_point_new_18(NULL, pd, p);
  48798. if (err == MP_OKAY) {
  48799. err = sp_1024_point_new_18(NULL, qd, q);
  48800. }
  48801. if (err == MP_OKAY) {
  48802. err = sp_1024_point_new_18(NULL, cd, c);
  48803. }
  48804. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  48805. defined(WOLFSSL_SP_SMALL_STACK)
  48806. if (err == MP_OKAY) {
  48807. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 86 * 18 * 2 + 16 * sizeof(sp_point_1024), NULL,
  48808. DYNAMIC_TYPE_TMP_BUFFER);
  48809. if (td == NULL) {
  48810. err = MEMORY_E;
  48811. }
  48812. }
  48813. #endif
  48814. if (err == MP_OKAY) {
  48815. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  48816. defined(WOLFSSL_SP_SMALL_STACK)
  48817. t = td;
  48818. vx = td + 36 * 18 * 2;
  48819. vy = td + 37 * 18 * 2;
  48820. pre_vx = (sp_digit(*)[36])(td + 38 * 18 * 2);
  48821. pre_vy = (sp_digit(*)[36])(td + 54 * 18 * 2);
  48822. pre_nvy = (sp_digit(*)[36])(td + 70 * 18 * 2);
  48823. pre_p = (sp_point_1024*)(td + 86 * 18 * 2);
  48824. #endif
  48825. r = vy;
  48826. sp_1024_point_from_ecc_point_18(p, pm);
  48827. sp_1024_point_from_ecc_point_18(q, qm);
  48828. err = sp_1024_mod_mul_norm_18(p->x, p->x, p1024_mod);
  48829. }
  48830. if (err == MP_OKAY) {
  48831. err = sp_1024_mod_mul_norm_18(p->y, p->y, p1024_mod);
  48832. }
  48833. if (err == MP_OKAY) {
  48834. err = sp_1024_mod_mul_norm_18(p->z, p->z, p1024_mod);
  48835. }
  48836. if (err == MP_OKAY) {
  48837. err = sp_1024_mod_mul_norm_18(q->x, q->x, p1024_mod);
  48838. }
  48839. if (err == MP_OKAY) {
  48840. err = sp_1024_mod_mul_norm_18(q->y, q->y, p1024_mod);
  48841. }
  48842. if (err == MP_OKAY) {
  48843. /* Generate pre-computation table: 1, 3, ... , 31 */
  48844. XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024));
  48845. XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 18);
  48846. pre_vx[0][0] = 1;
  48847. XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 18);
  48848. sp_1024_mont_sub_18(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod);
  48849. /* [2]P for adding */
  48850. XMEMCPY(c, p, sizeof(sp_point_1024));
  48851. XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 18);
  48852. vx[0] = 1;
  48853. XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 18);
  48854. sp_1024_accumulate_line_dbl_18(vx, vy, c, q, t);
  48855. /* 3, 5, ... */
  48856. for (i = 1; i < 16; i++) {
  48857. XMEMCPY(&pre_p[i], &pre_p[i-1], sizeof(sp_point_1024));
  48858. XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 18);
  48859. XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 18);
  48860. sp_1024_proj_mul_18(pre_vx[i], pre_vy[i], vx, vy, t);
  48861. sp_1024_accumulate_line_add_n_18(pre_vx[i], pre_vy[i], c,
  48862. q, &pre_p[i], t, 0);
  48863. sp_1024_mont_sub_18(pre_nvy[i], p1024_mod, pre_vy[i], p1024_mod);
  48864. }
  48865. j = sp_1024_order_op[0] / 2;
  48866. XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024));
  48867. XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 18);
  48868. XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 18);
  48869. /* Accumulate line into v and double point n times. */
  48870. sp_1024_accumulate_line_dbl_n_18(vx, vy, c, q,
  48871. sp_1024_order_op[1], t);
  48872. for (i = 2; i < 290; i += 2) {
  48873. j = sp_1024_order_op[i];
  48874. if (j > 0) {
  48875. j /= 2;
  48876. /* Accumulate line into v and add P into C. */
  48877. sp_1024_proj_mul_18(vx, vy, pre_vx[j], pre_vy[j], t);
  48878. sp_1024_accumulate_line_add_n_18(vx, vy, &pre_p[j], q, c,
  48879. t, 0);
  48880. }
  48881. else {
  48882. j = -j / 2;
  48883. /* Accumulate line into v and add P into C. */
  48884. sp_1024_proj_mul_18(vx, vy, pre_vx[j], pre_nvy[j], t);
  48885. sp_1024_accumulate_line_add_n_18(vx, vy, &pre_p[j], q, c,
  48886. t, 1);
  48887. }
  48888. /* Accumulate line into v and double point n times. */
  48889. sp_1024_accumulate_line_dbl_n_18(vx, vy, c, q,
  48890. sp_1024_order_op[i + 1], t);
  48891. }
  48892. /* Final exponentiation */
  48893. sp_1024_proj_sqr_18(vx, vy, t);
  48894. sp_1024_proj_sqr_18(vx, vy, t);
  48895. /* Convert from PF_p[q] to F_p */
  48896. sp_1024_mont_inv_18(vx, vx, t);
  48897. sp_1024_mont_mul_18(r, vx, vy, p1024_mod, p1024_mp_mod);
  48898. XMEMSET(r + 18, 0, sizeof(sp_digit) * 18);
  48899. sp_1024_mont_reduce_18(r, p1024_mod, p1024_mp_mod);
  48900. err = sp_1024_to_mp(r, res);
  48901. }
  48902. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  48903. defined(WOLFSSL_SP_SMALL_STACK)
  48904. if (td != NULL) {
  48905. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  48906. }
  48907. #endif
  48908. sp_1024_point_free_18(c, 1, NULL);
  48909. sp_1024_point_free_18(q, 1, NULL);
  48910. sp_1024_point_free_18(p, 1, NULL);
  48911. return err;
  48912. }
  48913. #endif /* WOLFSSL_SP_SMALL */
  48914. #ifdef WOLFSSL_SP_SMALL
  48915. /*
  48916. * Generate table for pairing.
  48917. *
  48918. * Small implementation does not use a table - returns 0 length.
  48919. *
  48920. * pm [in] Point to generate table for.
  48921. * table [in] Generated table.
  48922. * len [in,out] On in, the size of the buffer.
  48923. * On out, length of table generated.
  48924. * @return 0 on success.
  48925. * LENGTH_ONLY_E when table is NULL and only length returned.
  48926. * BUFFER_E when len is too small.
  48927. */
  48928. int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table,
  48929. word32* len)
  48930. {
  48931. int err = 0;
  48932. if (table == NULL) {
  48933. *len = 0;
  48934. err = LENGTH_ONLY_E;
  48935. }
  48936. else if (*len != 0) {
  48937. err = BUFFER_E;
  48938. }
  48939. (void)*pm;
  48940. return err;
  48941. }
  48942. /*
  48943. * Calculate r = pairing <P, Q>.
  48944. *
  48945. * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q.
  48946. *
  48947. * Small implementation does not use a table - use the normal implementation.
  48948. *
  48949. * @param [in] pm First point on E(F_p)[q].
  48950. * @param [in] qm Second point on E(F_p)[q].
  48951. * @param [in] res Result of calculation.
  48952. * @param [in] table Precomputed table of values.
  48953. * @param [in] len Length of precomputed table of values in bytes.
  48954. * @return 0 on success.
  48955. * @return MEMORY_E when dynamic memory allocation fails.
  48956. */
  48957. int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm,
  48958. mp_int* res, const byte* table, word32 len)
  48959. {
  48960. (void)table;
  48961. (void)len;
  48962. return sp_Pairing_1024(pm, qm, res);
  48963. }
  48964. #else
  48965. /*
  48966. * Calc l and c for the point when doubling p.
  48967. *
  48968. * l = 3 * (p.x^2 - 1) / (2 * p.y)
  48969. * c = l * p.x - p.y
  48970. *
  48971. * @param [out] lr Gradient result - table entry.
  48972. * @param [out] cr Constant result - table entry.
  48973. * @param [in] px X-ordinate of point to double.
  48974. * @param [in] py Y-ordinate of point to double.
  48975. * @param [in] t SP temporaries (3 used).
  48976. */
  48977. static void sp_1024_accum_dbl_calc_lc_18(sp_digit* lr, sp_digit* cr,
  48978. const sp_digit* px, const sp_digit* py, sp_digit* t)
  48979. {
  48980. sp_digit* t1 = t + 33 * 2 * 18;
  48981. sp_digit* t2 = t + 34 * 2 * 18;
  48982. sp_digit* l = t + 35 * 2 * 18;
  48983. /* l = 1 / 2 * p.y */
  48984. sp_1024_mont_dbl_18(l, py, p1024_mod);
  48985. sp_1024_mont_inv_18(l, l, t);
  48986. /* t1 = p.x^2 */
  48987. sp_1024_mont_sqr_18(t1, px, p1024_mod, p1024_mp_mod);
  48988. /* t1 = p.x - 1 */
  48989. sp_1024_mont_sub_18(t1, t1, p1024_norm_mod, p1024_mod);
  48990. /* t1 = 3 * (p.x^2 - 1) */
  48991. sp_1024_mont_dbl_18(t2, t1, p1024_mod);
  48992. sp_1024_mont_add_18(t1, t1, t2, p1024_mod);
  48993. /* t1 = 3 * (p.x^2 - 1) / (2 * p.y) */
  48994. sp_1024_mont_mul_18(l, l, t1, p1024_mod, p1024_mp_mod);
  48995. /* t2 = l * p.x */
  48996. sp_1024_mont_mul_18(t2, l, px, p1024_mod, p1024_mp_mod);
  48997. /* c = t2 = l * p.x - p.y */
  48998. sp_1024_mont_sub_18(t2, t2, py, p1024_mod);
  48999. XMEMCPY(lr, l, sizeof(sp_digit) * 18);
  49000. XMEMCPY(cr, t2, sizeof(sp_digit) * 18);
  49001. }
  49002. /*
  49003. * Calc l and c when adding p and c.
  49004. *
  49005. * l = (c.y - p.y) / (c.x - p.x)
  49006. * c = (p.x * c.y - cx * p.y) / (cx - p.x)
  49007. *
  49008. * @param [out] lr Gradient result - table entry.
  49009. * @param [out] cr Constant result - table entry.
  49010. * @param [in] px X-ordinate of point to add.
  49011. * @param [in] py Y-ordinate of point to add.
  49012. * @param [in] cx X-ordinate of current point.
  49013. * @param [in] cy Y-ordinate of current point.
  49014. * @param [in] t SP temporaries (3 used).
  49015. */
  49016. static void sp_1024_accum_add_calc_lc_18(sp_digit* lr, sp_digit* cr,
  49017. const sp_digit* px, const sp_digit* py, const sp_digit* cx,
  49018. const sp_digit* cy, sp_digit* t)
  49019. {
  49020. sp_digit* t1 = t + 33 * 2 * 18;
  49021. sp_digit* c = t + 34 * 2 * 18;
  49022. sp_digit* l = t + 35 * 2 * 18;
  49023. /* l = 1 / (c.x - p.x) */
  49024. sp_1024_mont_sub_18(l, cx, px, p1024_mod);
  49025. sp_1024_mont_inv_18(l, l, t);
  49026. /* c = p.x * c.y */
  49027. sp_1024_mont_mul_18(c, px, cy, p1024_mod, p1024_mp_mod);
  49028. /* t1 = c.x * p.y */
  49029. sp_1024_mont_mul_18(t1, cx, py, p1024_mod, p1024_mp_mod);
  49030. /* c = (p.x * c.y) - (c.x * p.y) */
  49031. sp_1024_mont_sub_18(c, c, t1, p1024_mod);
  49032. /* c = ((p.x * c.y) - (c.x * p.y)) / (c.x - p.x) */
  49033. sp_1024_mont_mul_18(c, c, l, p1024_mod, p1024_mp_mod);
  49034. /* t1 = c.y - p.y */
  49035. sp_1024_mont_sub_18(t1, cy, py, p1024_mod);
  49036. /* l = (c.y - p.y) / (c.x - p.x) */
  49037. sp_1024_mont_mul_18(l, t1, l, p1024_mod, p1024_mp_mod);
  49038. XMEMCPY(lr, l, sizeof(sp_digit) * 18);
  49039. XMEMCPY(cr, c, sizeof(sp_digit) * 18);
  49040. }
  49041. /*
  49042. * Calculate vx and vy given gradient l and constant c and point q.
  49043. *
  49044. * l is a the gradient and is multiplied by q->x.
  49045. * c is a the constant that is added to the multiplicative result.
  49046. * q->y is the y-ordinate in result to multiply.
  49047. *
  49048. * if dbl
  49049. * v* = v*^2
  49050. * r.x = l * q.x + c
  49051. * r.y = q->y
  49052. * v* = v* * r*
  49053. *
  49054. * @param [in,out] vx X-ordinate of projective value in F*.
  49055. * @param [in,out] vy Y-ordinate of projective value in F*.
  49056. * @param [in] l Gradient to multiply with.
  49057. * @param [in] c Constant to add with.
  49058. * @param [in] q ECC point - second point on E(F_P^2).
  49059. * @param [in] t SP temporaries (3 used).
  49060. * @param [in] dbl Indicates whether this is for doubling. Otherwise
  49061. * adding.
  49062. */
  49063. static void sp_1024_accumulate_line_lc_18(sp_digit* vx, sp_digit* vy,
  49064. const sp_digit* l, const sp_digit* c, const sp_point_1024* q,
  49065. sp_digit* t, int dbl)
  49066. {
  49067. sp_digit* rx = t + 4 * 2 * 18;
  49068. /* v = v^2 */
  49069. if (dbl) {
  49070. sp_1024_proj_sqr_18(vx, vy, t);
  49071. }
  49072. /* rx = l * q.x + c */
  49073. sp_1024_mont_mul_18(rx, l, q->x, p1024_mod, p1024_mp_mod);
  49074. sp_1024_mont_add_18(rx, rx, c, p1024_mod);
  49075. /* v = v^2 * r */
  49076. sp_1024_proj_mul_18(vx, vy, rx, q->y, t);
  49077. }
  49078. /* Operations to perform based on order - 1.
  49079. * Sliding window. Start at bottom and stop when bottom bit is one.
  49080. * Subtract if top bit in window is one.
  49081. * Width of 6 bits.
  49082. * Pairs: #dbls, add/subtract window value
  49083. */
  49084. static const signed char sp_1024_order_op_pre[] = {
  49085. 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9,
  49086. -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6,
  49087. -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8,
  49088. 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7,
  49089. -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6,
  49090. -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7,
  49091. -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7,
  49092. -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7,
  49093. -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6,
  49094. 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6,
  49095. -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6,
  49096. -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10,
  49097. 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7,
  49098. -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7,
  49099. 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6,
  49100. -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12,
  49101. 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8,
  49102. -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10,
  49103. -3, 1,
  49104. };
  49105. /*
  49106. * Generate table for pairing.
  49107. *
  49108. * Calculate the graident (l) and constant (c) at each step of the way.
  49109. * Sliding window. Start at bottom and stop when bottom bit is one.
  49110. * Subtract if top bit in window is one.
  49111. * Width of 6 bits.
  49112. *
  49113. * pm [in] Point to generate table for.
  49114. * table [in] Generated table.
  49115. * len [in,out] On in, the size of the buffer.
  49116. * On out, length of table generated.
  49117. * @return 0 on success.
  49118. * LENGTH_ONLY_E when table is NULL and only length returned.
  49119. * BUFFER_E when len is too small.
  49120. * MEMORY_E when dynamic memory allocation fauls.
  49121. */
  49122. int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table,
  49123. word32* len)
  49124. {
  49125. int err = 0;
  49126. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  49127. defined(WOLFSSL_SP_SMALL_STACK)
  49128. sp_digit* td = NULL;
  49129. sp_digit* t;
  49130. sp_point_1024* pre_p;
  49131. #else
  49132. sp_digit t[36 * 2 * 18];
  49133. sp_point_1024 pre_p[16];
  49134. sp_point_1024 pd;
  49135. sp_point_1024 cd;
  49136. sp_point_1024 negd;
  49137. #endif
  49138. sp_point_1024* p = NULL;
  49139. sp_point_1024* c = NULL;
  49140. sp_point_1024* neg = NULL;
  49141. int i;
  49142. int j;
  49143. int k;
  49144. sp_table_entry_1024* precomp = (sp_table_entry_1024*)table;
  49145. if (table == NULL) {
  49146. *len = sizeof(sp_table_entry_1024) * 1167;
  49147. err = LENGTH_ONLY_E;
  49148. }
  49149. if ((err == MP_OKAY) &&
  49150. (*len < (int)(sizeof(sp_table_entry_1024) * 1167))) {
  49151. err = BUFFER_E;
  49152. }
  49153. if (err == MP_OKAY) {
  49154. err = sp_1024_point_new_18(NULL, pd, p);
  49155. }
  49156. if (err == MP_OKAY) {
  49157. err = sp_1024_point_new_18(NULL, cd, c);
  49158. }
  49159. if (err == MP_OKAY) {
  49160. err = sp_1024_point_new_18(NULL, negd, neg);
  49161. }
  49162. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  49163. defined(WOLFSSL_SP_SMALL_STACK)
  49164. if (err == MP_OKAY) {
  49165. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 18 * 2 + 16 *
  49166. sizeof(sp_point_1024), NULL, DYNAMIC_TYPE_TMP_BUFFER);
  49167. if (td == NULL) {
  49168. err = MEMORY_E;
  49169. }
  49170. }
  49171. #endif
  49172. if (err == MP_OKAY) {
  49173. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  49174. defined(WOLFSSL_SP_SMALL_STACK)
  49175. t = td;
  49176. pre_p = (sp_point_1024*)(td + 36 * 18 * 2);
  49177. #endif
  49178. sp_1024_point_from_ecc_point_18(p, pm);
  49179. err = sp_1024_mod_mul_norm_18(p->x, p->x, p1024_mod);
  49180. }
  49181. if (err == MP_OKAY) {
  49182. err = sp_1024_mod_mul_norm_18(p->y, p->y, p1024_mod);
  49183. }
  49184. if (err == MP_OKAY) {
  49185. XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod));
  49186. neg->infinity = 0;
  49187. c->infinity = 0;
  49188. /* Generate pre-computation table: 1, 3, ... , 31 */
  49189. XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024));
  49190. /* [2]P for adding */
  49191. sp_1024_proj_point_dbl_18(c, p, t);
  49192. /* 1, 3, ... */
  49193. for (i = 1; i < 16; i++) {
  49194. sp_1024_proj_point_add_18(&pre_p[i], &pre_p[i-1], c, t);
  49195. sp_1024_mont_map_18(&pre_p[i], t);
  49196. }
  49197. k = 0;
  49198. j = sp_1024_order_op_pre[0] / 2;
  49199. XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024));
  49200. for (j = 0; j < sp_1024_order_op_pre[1]; j++) {
  49201. sp_1024_accum_dbl_calc_lc_18(precomp[k].x, precomp[k].y, c->x,
  49202. c->y, t);
  49203. k++;
  49204. sp_1024_proj_point_dbl_18(c, c, t);
  49205. sp_1024_mont_map_18(c, t);
  49206. }
  49207. for (i = 2; i < 290; i += 2) {
  49208. j = sp_1024_order_op_pre[i];
  49209. if (j > 0) {
  49210. sp_1024_accum_add_calc_lc_18(precomp[k].x, precomp[k].y,
  49211. pre_p[j/2].x, pre_p[j/2].y, c->x, c->y, t);
  49212. k++;
  49213. sp_1024_proj_point_add_18(c, c, &pre_p[j/2], t);
  49214. sp_1024_mont_map_18(c, t);
  49215. }
  49216. else {
  49217. XMEMCPY(neg->x, pre_p[-j / 2].x, sizeof(pre_p->x));
  49218. sp_1024_mont_sub_18(neg->y, p1024_mod, pre_p[-j / 2].y,
  49219. p1024_mod);
  49220. XMEMCPY(neg->z, pre_p[-j / 2].z, sizeof(pre_p->z));
  49221. sp_1024_accum_add_calc_lc_18(precomp[k].x, precomp[k].y,
  49222. neg->x, neg->y, c->x, c->y, t);
  49223. k++;
  49224. sp_1024_proj_point_add_18(c, c, neg, t);
  49225. sp_1024_mont_map_18(c, t);
  49226. }
  49227. for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) {
  49228. sp_1024_accum_dbl_calc_lc_18(precomp[k].x, precomp[k].y, c->x,
  49229. c->y, t);
  49230. k++;
  49231. sp_1024_proj_point_dbl_18(c, c, t);
  49232. sp_1024_mont_map_18(c, t);
  49233. }
  49234. }
  49235. *len = sizeof(sp_table_entry_1024) * 1167;
  49236. }
  49237. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  49238. defined(WOLFSSL_SP_SMALL_STACK)
  49239. if (td != NULL) {
  49240. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  49241. }
  49242. #endif
  49243. sp_1024_point_free_18(neg, 1, NULL);
  49244. sp_1024_point_free_18(c, 1, NULL);
  49245. sp_1024_point_free_18(p, 1, NULL);
  49246. return err;
  49247. }
  49248. /*
  49249. * Calculate r = pairing <P, Q>.
  49250. *
  49251. * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q.
  49252. *
  49253. * Sliding window. Start at bottom and stop when bottom bit is one.
  49254. * Subtract if top bit in window is one.
  49255. * Width of 6 bits.
  49256. * Pre-generate values in window (1, 3, ...) - only V.
  49257. * Table contains all gradient l and a constant for each point on the path.
  49258. *
  49259. * @param [in] pm First point on E(F_p)[q].
  49260. * @param [in] qm Second point on E(F_p)[q].
  49261. * @param [in] res Result of calculation.
  49262. * @param [in] table Precomputed table of values.
  49263. * @param [in] len Length of precomputed table of values in bytes.
  49264. * @return 0 on success.
  49265. * @return MEMORY_E when dynamic memory allocation fails.
  49266. */
  49267. int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm,
  49268. mp_int* res, const byte* table, word32 len)
  49269. {
  49270. int err = 0;
  49271. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  49272. defined(WOLFSSL_SP_SMALL_STACK)
  49273. sp_digit* td = NULL;
  49274. sp_digit* t;
  49275. sp_digit* vx;
  49276. sp_digit* vy;
  49277. sp_digit (*pre_vx)[36];
  49278. sp_digit (*pre_vy)[36];
  49279. sp_digit (*pre_nvy)[36];
  49280. #else
  49281. sp_digit t[36 * 2 * 18];
  49282. sp_digit vx[2 * 18];
  49283. sp_digit vy[2 * 18];
  49284. sp_digit pre_vx[16][36];
  49285. sp_digit pre_vy[16][36];
  49286. sp_digit pre_nvy[16][36];
  49287. sp_point_1024 pd;
  49288. sp_point_1024 qd;
  49289. sp_point_1024 cd;
  49290. #endif
  49291. sp_point_1024* p = NULL;
  49292. sp_point_1024* q = NULL;
  49293. sp_point_1024* c = NULL;
  49294. sp_digit* r = NULL;
  49295. int i;
  49296. int j;
  49297. int k;
  49298. const sp_table_entry_1024* precomp = (const sp_table_entry_1024*)table;
  49299. if (len < (int)(sizeof(sp_table_entry_1024) * 1167)) {
  49300. err = BUFFER_E;
  49301. }
  49302. if (err == MP_OKAY) {
  49303. err = sp_1024_point_new_18(NULL, pd, p);
  49304. }
  49305. if (err == MP_OKAY) {
  49306. err = sp_1024_point_new_18(NULL, qd, q);
  49307. }
  49308. if (err == MP_OKAY) {
  49309. err = sp_1024_point_new_18(NULL, cd, c);
  49310. }
  49311. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  49312. defined(WOLFSSL_SP_SMALL_STACK)
  49313. if (err == MP_OKAY) {
  49314. td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 86 * 18 * 2, NULL,
  49315. DYNAMIC_TYPE_TMP_BUFFER);
  49316. if (td == NULL) {
  49317. err = MEMORY_E;
  49318. }
  49319. }
  49320. #endif
  49321. if (err == MP_OKAY) {
  49322. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  49323. defined(WOLFSSL_SP_SMALL_STACK)
  49324. t = td;
  49325. vx = td + 36 * 18 * 2;
  49326. vy = td + 37 * 18 * 2;
  49327. pre_vx = (sp_digit(*)[36])(td + 38 * 18 * 2);
  49328. pre_vy = (sp_digit(*)[36])(td + 54 * 18 * 2);
  49329. pre_nvy = (sp_digit(*)[36])(td + 70 * 18 * 2);
  49330. #endif
  49331. r = vy;
  49332. sp_1024_point_from_ecc_point_18(p, pm);
  49333. sp_1024_point_from_ecc_point_18(q, qm);
  49334. err = sp_1024_mod_mul_norm_18(p->x, p->x, p1024_mod);
  49335. }
  49336. if (err == MP_OKAY) {
  49337. err = sp_1024_mod_mul_norm_18(p->y, p->y, p1024_mod);
  49338. }
  49339. if (err == MP_OKAY) {
  49340. err = sp_1024_mod_mul_norm_18(p->z, p->z, p1024_mod);
  49341. }
  49342. if (err == MP_OKAY) {
  49343. err = sp_1024_mod_mul_norm_18(q->x, q->x, p1024_mod);
  49344. }
  49345. if (err == MP_OKAY) {
  49346. err = sp_1024_mod_mul_norm_18(q->y, q->y, p1024_mod);
  49347. }
  49348. if (err == MP_OKAY) {
  49349. /* Generate pre-computation table: 1, 3, ... , 31 */
  49350. XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 18);
  49351. pre_vx[0][0] = 1;
  49352. XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 18);
  49353. sp_1024_mont_sub_18(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod);
  49354. /* [2]P for adding */
  49355. XMEMCPY(c, p, sizeof(sp_point_1024));
  49356. XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 18);
  49357. vx[0] = 1;
  49358. XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 18);
  49359. sp_1024_accumulate_line_dbl_18(vx, vy, c, q, t);
  49360. /* 3, 5, ... */
  49361. for (i = 1; i < 16; i++) {
  49362. XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 18);
  49363. XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 18);
  49364. sp_1024_proj_mul_18(pre_vx[i], pre_vy[i], vx, vy, t);
  49365. sp_1024_accumulate_line_add_n_18(pre_vx[i], pre_vy[i], c,
  49366. q, p, t, 0);
  49367. sp_1024_mont_sub_18(pre_nvy[i], p1024_mod, pre_vy[i],
  49368. p1024_mod);
  49369. }
  49370. XMEMCPY(c->z, p1024_norm_mod, sizeof(sp_digit) * 18);
  49371. c->infinity = 0;
  49372. j = sp_1024_order_op_pre[0] / 2;
  49373. XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 18);
  49374. XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 18);
  49375. k = 0;
  49376. for (j = 0; j < sp_1024_order_op_pre[1]; j++) {
  49377. /* Accumulate line into v and double point. */
  49378. sp_1024_accumulate_line_lc_18(vx, vy, precomp[k].x,
  49379. precomp[k].y, q, t, 1);
  49380. k++;
  49381. }
  49382. for (i = 2; i < 290; i += 2) {
  49383. sp_1024_accumulate_line_lc_18(vx, vy, precomp[k].x,
  49384. precomp[k].y, q, t, 0);
  49385. k++;
  49386. j = sp_1024_order_op_pre[i];
  49387. if (j > 0) {
  49388. j /= 2;
  49389. /* Accumulate line into v. */
  49390. sp_1024_proj_mul_18(vx, vy, pre_vx[j], pre_vy[j], t);
  49391. }
  49392. else {
  49393. j = -j / 2;
  49394. /* Accumulate line into v. */
  49395. sp_1024_proj_mul_18(vx, vy, pre_vx[j], pre_nvy[j], t);
  49396. }
  49397. for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) {
  49398. /* Accumulate line into v and double point. */
  49399. sp_1024_accumulate_line_lc_18(vx, vy, precomp[k].x,
  49400. precomp[k].y, q, t, 1);
  49401. k++;
  49402. }
  49403. }
  49404. /* Final exponentiation */
  49405. sp_1024_proj_sqr_18(vx, vy, t);
  49406. sp_1024_proj_sqr_18(vx, vy, t);
  49407. /* Convert from PF_p[q] to F_p */
  49408. sp_1024_mont_inv_18(vx, vx, t);
  49409. sp_1024_mont_mul_18(r, vx, vy, p1024_mod, p1024_mp_mod);
  49410. XMEMSET(r + 18, 0, sizeof(sp_digit) * 18);
  49411. sp_1024_mont_reduce_18(r, p1024_mod, p1024_mp_mod);
  49412. err = sp_1024_to_mp(r, res);
  49413. }
  49414. #if (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_MALLOC)) || \
  49415. defined(WOLFSSL_SP_SMALL_STACK)
  49416. if (td != NULL) {
  49417. XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  49418. }
  49419. #endif
  49420. sp_1024_point_free_18(c, 1, NULL);
  49421. sp_1024_point_free_18(q, 1, NULL);
  49422. sp_1024_point_free_18(p, 1, NULL);
  49423. return err;
  49424. }
  49425. #endif /* WOLFSSL_SP_SMALL */
  49426. #ifdef HAVE_ECC_CHECK_KEY
  49427. /* Read big endian unsigned byte array into r.
  49428. *
  49429. * r A single precision integer.
  49430. * size Maximum number of bytes to convert
  49431. * a Byte array.
  49432. * n Number of bytes in array to read.
  49433. */
  49434. static void sp_1024_from_bin(sp_digit* r, int size, const byte* a, int n)
  49435. {
  49436. int i;
  49437. int j = 0;
  49438. word32 s = 0;
  49439. r[0] = 0;
  49440. for (i = n-1; i >= 0; i--) {
  49441. r[j] |= (((sp_digit)a[i]) << s);
  49442. if (s >= 49U) {
  49443. r[j] &= 0x1ffffffffffffffL;
  49444. s = 57U - s;
  49445. if (j + 1 >= size) {
  49446. break;
  49447. }
  49448. r[++j] = (sp_digit)a[i] >> s;
  49449. s = 8U - s;
  49450. }
  49451. else {
  49452. s += 8U;
  49453. }
  49454. }
  49455. for (j++; j < size; j++) {
  49456. r[j] = 0;
  49457. }
  49458. }
  49459. /* Check that the x and y ordinates are a valid point on the curve.
  49460. *
  49461. * point EC point.
  49462. * heap Heap to use if dynamically allocating.
  49463. * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
  49464. * not on the curve and MP_OKAY otherwise.
  49465. */
  49466. static int sp_1024_ecc_is_point_18(const sp_point_1024* point,
  49467. void* heap)
  49468. {
  49469. #ifdef WOLFSSL_SP_SMALL_STACK
  49470. sp_digit* t1 = NULL;
  49471. #else
  49472. sp_digit t1[18 * 4];
  49473. #endif
  49474. sp_digit* t2 = NULL;
  49475. sp_int64 n;
  49476. int err = MP_OKAY;
  49477. #ifdef WOLFSSL_SP_SMALL_STACK
  49478. t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 4, heap, DYNAMIC_TYPE_ECC);
  49479. if (t1 == NULL)
  49480. err = MEMORY_E;
  49481. #endif
  49482. (void)heap;
  49483. if (err == MP_OKAY) {
  49484. t2 = t1 + 2 * 18;
  49485. /* y^2 - x^3 - a.x = b */
  49486. sp_1024_sqr_18(t1, point->y);
  49487. (void)sp_1024_mod_18(t1, t1, p1024_mod);
  49488. sp_1024_sqr_18(t2, point->x);
  49489. (void)sp_1024_mod_18(t2, t2, p1024_mod);
  49490. sp_1024_mul_18(t2, t2, point->x);
  49491. (void)sp_1024_mod_18(t2, t2, p1024_mod);
  49492. sp_1024_mont_sub_18(t1, t1, t2, p1024_mod);
  49493. /* y^2 - x^3 + 3.x = b, when a = -3 */
  49494. sp_1024_mont_add_18(t1, t1, point->x, p1024_mod);
  49495. sp_1024_mont_add_18(t1, t1, point->x, p1024_mod);
  49496. sp_1024_mont_add_18(t1, t1, point->x, p1024_mod);
  49497. n = sp_1024_cmp_18(t1, p1024_mod);
  49498. sp_1024_cond_sub_18(t1, t1, p1024_mod, ~(n >> 56));
  49499. sp_1024_norm_18(t1);
  49500. if (!sp_1024_iszero_18(t1)) {
  49501. err = MP_VAL;
  49502. }
  49503. }
  49504. #ifdef WOLFSSL_SP_SMALL_STACK
  49505. if (t1 != NULL)
  49506. XFREE(t1, heap, DYNAMIC_TYPE_ECC);
  49507. #endif
  49508. return err;
  49509. }
  49510. /* Check that the x and y ordinates are a valid point on the curve.
  49511. *
  49512. * pX X ordinate of EC point.
  49513. * pY Y ordinate of EC point.
  49514. * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
  49515. * not on the curve and MP_OKAY otherwise.
  49516. */
  49517. int sp_ecc_is_point_1024(const mp_int* pX, const mp_int* pY)
  49518. {
  49519. #ifdef WOLFSSL_SP_SMALL_STACK
  49520. sp_point_1024* pub = NULL;
  49521. #else
  49522. sp_point_1024 pub[1];
  49523. #endif
  49524. const byte one[1] = { 1 };
  49525. int err = MP_OKAY;
  49526. #ifdef WOLFSSL_SP_SMALL_STACK
  49527. pub = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), NULL,
  49528. DYNAMIC_TYPE_ECC);
  49529. if (pub == NULL)
  49530. err = MEMORY_E;
  49531. #endif
  49532. if (err == MP_OKAY) {
  49533. sp_1024_from_mp(pub->x, 18, pX);
  49534. sp_1024_from_mp(pub->y, 18, pY);
  49535. sp_1024_from_bin(pub->z, 18, one, (int)sizeof(one));
  49536. err = sp_1024_ecc_is_point_18(pub, NULL);
  49537. }
  49538. #ifdef WOLFSSL_SP_SMALL_STACK
  49539. if (pub != NULL)
  49540. XFREE(pub, NULL, DYNAMIC_TYPE_ECC);
  49541. #endif
  49542. return err;
  49543. }
  49544. /* Check that the private scalar generates the EC point (px, py), the point is
  49545. * on the curve and the point has the correct order.
  49546. *
  49547. * pX X ordinate of EC point.
  49548. * pY Y ordinate of EC point.
  49549. * privm Private scalar that generates EC point.
  49550. * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
  49551. * not on the curve, ECC_INF_E if the point does not have the correct order,
  49552. * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and
  49553. * MP_OKAY otherwise.
  49554. */
  49555. int sp_ecc_check_key_1024(const mp_int* pX, const mp_int* pY,
  49556. const mp_int* privm, void* heap)
  49557. {
  49558. #ifdef WOLFSSL_SP_SMALL_STACK
  49559. sp_digit* priv = NULL;
  49560. sp_point_1024* pub = NULL;
  49561. #else
  49562. sp_digit priv[18];
  49563. sp_point_1024 pub[2];
  49564. #endif
  49565. sp_point_1024* p = NULL;
  49566. const byte one[1] = { 1 };
  49567. int err = MP_OKAY;
  49568. /* Quick check the lengs of public key ordinates and private key are in
  49569. * range. Proper check later.
  49570. */
  49571. if (((mp_count_bits(pX) > 1024) ||
  49572. (mp_count_bits(pY) > 1024) ||
  49573. ((privm != NULL) && (mp_count_bits(privm) > 1024)))) {
  49574. err = ECC_OUT_OF_RANGE_E;
  49575. }
  49576. #ifdef WOLFSSL_SP_SMALL_STACK
  49577. if (err == MP_OKAY) {
  49578. pub = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 2, heap,
  49579. DYNAMIC_TYPE_ECC);
  49580. if (pub == NULL)
  49581. err = MEMORY_E;
  49582. }
  49583. if (err == MP_OKAY && privm) {
  49584. priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18, heap,
  49585. DYNAMIC_TYPE_ECC);
  49586. if (priv == NULL)
  49587. err = MEMORY_E;
  49588. }
  49589. #endif
  49590. if (err == MP_OKAY) {
  49591. p = pub + 1;
  49592. sp_1024_from_mp(pub->x, 18, pX);
  49593. sp_1024_from_mp(pub->y, 18, pY);
  49594. sp_1024_from_bin(pub->z, 18, one, (int)sizeof(one));
  49595. if (privm)
  49596. sp_1024_from_mp(priv, 18, privm);
  49597. /* Check point at infinitiy. */
  49598. if ((sp_1024_iszero_18(pub->x) != 0) &&
  49599. (sp_1024_iszero_18(pub->y) != 0)) {
  49600. err = ECC_INF_E;
  49601. }
  49602. }
  49603. /* Check range of X and Y */
  49604. if ((err == MP_OKAY) &&
  49605. ((sp_1024_cmp_18(pub->x, p1024_mod) >= 0) ||
  49606. (sp_1024_cmp_18(pub->y, p1024_mod) >= 0))) {
  49607. err = ECC_OUT_OF_RANGE_E;
  49608. }
  49609. if (err == MP_OKAY) {
  49610. /* Check point is on curve */
  49611. err = sp_1024_ecc_is_point_18(pub, heap);
  49612. }
  49613. if (err == MP_OKAY) {
  49614. /* Point * order = infinity */
  49615. err = sp_1024_ecc_mulmod_18(p, pub, p1024_order, 1, 1, heap);
  49616. }
  49617. /* Check result is infinity */
  49618. if ((err == MP_OKAY) && ((sp_1024_iszero_18(p->x) == 0) ||
  49619. (sp_1024_iszero_18(p->y) == 0))) {
  49620. err = ECC_INF_E;
  49621. }
  49622. if (privm) {
  49623. if (err == MP_OKAY) {
  49624. /* Base * private = point */
  49625. err = sp_1024_ecc_mulmod_base_18(p, priv, 1, 1, heap);
  49626. }
  49627. /* Check result is public key */
  49628. if ((err == MP_OKAY) &&
  49629. ((sp_1024_cmp_18(p->x, pub->x) != 0) ||
  49630. (sp_1024_cmp_18(p->y, pub->y) != 0))) {
  49631. err = ECC_PRIV_KEY_E;
  49632. }
  49633. }
  49634. #ifdef WOLFSSL_SP_SMALL_STACK
  49635. if (pub != NULL)
  49636. XFREE(pub, heap, DYNAMIC_TYPE_ECC);
  49637. if (priv != NULL)
  49638. XFREE(priv, heap, DYNAMIC_TYPE_ECC);
  49639. #endif
  49640. return err;
  49641. }
  49642. #endif
  49643. #endif /* WOLFSSL_SP_1024 */
  49644. #endif /* WOLFCRYPT_HAVE_SAKKE */
  49645. #endif /* WOLFSSL_HAVE_SP_ECC */
  49646. #endif /* SP_WORD_SIZE == 64 */
  49647. #endif /* !WOLFSSL_SP_ASM */
  49648. #endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH | WOLFSSL_HAVE_SP_ECC */