mpi.c 215 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636
  1. /* Start: bn_error.c */
  2. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  3. *
  4. * LibTomMath is a library that provides multiple-precision
  5. * integer arithmetic as well as number theoretic functionality.
  6. *
  7. * The library was designed directly after the MPI library by
  8. * Michael Fromberger but has been written from scratch with
  9. * additional optimizations in place.
  10. *
  11. * The library is free for all purposes without any express
  12. * guarantee it works.
  13. *
  14. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  15. */
  16. #include <ltc_tommath.h>
  17. static const struct {
  18. int code;
  19. char *msg;
  20. } msgs[] = {
  21. { MP_OKAY, "Successful" },
  22. { MP_MEM, "Out of heap" },
  23. { MP_VAL, "Value out of range" }
  24. };
  25. /* return a char * string for a given code */
  26. char *mp_error_to_string(int code)
  27. {
  28. int x;
  29. /* scan the lookup table for the given message */
  30. for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) {
  31. if (msgs[x].code == code) {
  32. return msgs[x].msg;
  33. }
  34. }
  35. /* generic reply for invalid code */
  36. return "Invalid error code";
  37. }
  38. /* End: bn_error.c */
  39. /* Start: bn_fast_mp_invmod.c */
  40. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  41. *
  42. * LibTomMath is a library that provides multiple-precision
  43. * integer arithmetic as well as number theoretic functionality.
  44. *
  45. * The library was designed directly after the MPI library by
  46. * Michael Fromberger but has been written from scratch with
  47. * additional optimizations in place.
  48. *
  49. * The library is free for all purposes without any express
  50. * guarantee it works.
  51. *
  52. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  53. */
  54. #include <ltc_tommath.h>
  55. /* computes the modular inverse via binary extended euclidean algorithm,
  56. * that is c = 1/a mod b
  57. *
  58. * Based on mp_invmod except this is optimized for the case where b is
  59. * odd as per HAC Note 14.64 on pp. 610
  60. */
  61. int
  62. fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
  63. {
  64. mp_int x, y, u, v, B, D;
  65. int res, neg;
  66. /* 2. [modified] b must be odd */
  67. if (mp_iseven (b) == 1) {
  68. return MP_VAL;
  69. }
  70. /* init all our temps */
  71. if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
  72. return res;
  73. }
  74. /* x == modulus, y == value to invert */
  75. if ((res = mp_copy (b, &x)) != MP_OKAY) {
  76. goto __ERR;
  77. }
  78. /* we need y = |a| */
  79. if ((res = mp_abs (a, &y)) != MP_OKAY) {
  80. goto __ERR;
  81. }
  82. /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
  83. if ((res = mp_copy (&x, &u)) != MP_OKAY) {
  84. goto __ERR;
  85. }
  86. if ((res = mp_copy (&y, &v)) != MP_OKAY) {
  87. goto __ERR;
  88. }
  89. mp_set (&D, 1);
  90. top:
  91. /* 4. while u is even do */
  92. while (mp_iseven (&u) == 1) {
  93. /* 4.1 u = u/2 */
  94. if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
  95. goto __ERR;
  96. }
  97. /* 4.2 if B is odd then */
  98. if (mp_isodd (&B) == 1) {
  99. if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
  100. goto __ERR;
  101. }
  102. }
  103. /* B = B/2 */
  104. if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
  105. goto __ERR;
  106. }
  107. }
  108. /* 5. while v is even do */
  109. while (mp_iseven (&v) == 1) {
  110. /* 5.1 v = v/2 */
  111. if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
  112. goto __ERR;
  113. }
  114. /* 5.2 if D is odd then */
  115. if (mp_isodd (&D) == 1) {
  116. /* D = (D-x)/2 */
  117. if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
  118. goto __ERR;
  119. }
  120. }
  121. /* D = D/2 */
  122. if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
  123. goto __ERR;
  124. }
  125. }
  126. /* 6. if u >= v then */
  127. if (mp_cmp (&u, &v) != MP_LT) {
  128. /* u = u - v, B = B - D */
  129. if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
  130. goto __ERR;
  131. }
  132. if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
  133. goto __ERR;
  134. }
  135. } else {
  136. /* v - v - u, D = D - B */
  137. if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
  138. goto __ERR;
  139. }
  140. if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
  141. goto __ERR;
  142. }
  143. }
  144. /* if not zero goto step 4 */
  145. if (mp_iszero (&u) == 0) {
  146. goto top;
  147. }
  148. /* now a = C, b = D, gcd == g*v */
  149. /* if v != 1 then there is no inverse */
  150. if (mp_cmp_d (&v, 1) != MP_EQ) {
  151. res = MP_VAL;
  152. goto __ERR;
  153. }
  154. /* b is now the inverse */
  155. neg = a->sign;
  156. while (D.sign == MP_NEG) {
  157. if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
  158. goto __ERR;
  159. }
  160. }
  161. mp_exch (&D, c);
  162. c->sign = neg;
  163. res = MP_OKAY;
  164. __ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
  165. return res;
  166. }
  167. /* End: bn_fast_mp_invmod.c */
  168. /* Start: bn_fast_mp_montgomery_reduce.c */
  169. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  170. *
  171. * LibTomMath is a library that provides multiple-precision
  172. * integer arithmetic as well as number theoretic functionality.
  173. *
  174. * The library was designed directly after the MPI library by
  175. * Michael Fromberger but has been written from scratch with
  176. * additional optimizations in place.
  177. *
  178. * The library is free for all purposes without any express
  179. * guarantee it works.
  180. *
  181. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  182. */
  183. #include <ltc_tommath.h>
  184. /* computes xR**-1 == x (mod N) via Montgomery Reduction
  185. *
  186. * This is an optimized implementation of mp_montgomery_reduce
  187. * which uses the comba method to quickly calculate the columns of the
  188. * reduction.
  189. *
  190. * Based on Algorithm 14.32 on pp.601 of HAC.
  191. */
  192. int
  193. fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
  194. {
  195. int ix, res, olduse;
  196. mp_word W[MP_WARRAY];
  197. /* get old used count */
  198. olduse = x->used;
  199. /* grow a as required */
  200. if (x->alloc < n->used + 1) {
  201. if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
  202. return res;
  203. }
  204. }
  205. /* first we have to get the digits of the input into
  206. * an array of double precision words W[...]
  207. */
  208. {
  209. register mp_word *_W;
  210. register mp_digit *tmpx;
  211. /* alias for the W[] array */
  212. _W = W;
  213. /* alias for the digits of x*/
  214. tmpx = x->dp;
  215. /* copy the digits of a into W[0..a->used-1] */
  216. for (ix = 0; ix < x->used; ix++) {
  217. *_W++ = *tmpx++;
  218. }
  219. /* zero the high words of W[a->used..m->used*2] */
  220. for (; ix < n->used * 2 + 1; ix++) {
  221. *_W++ = 0;
  222. }
  223. }
  224. /* now we proceed to zero successive digits
  225. * from the least significant upwards
  226. */
  227. #ifdef LTMSSE
  228. // compute globals we'd like to have in MMX registers
  229. asm ("movl $268435455,%%eax \n\t" //mm2 == MP_MASK
  230. "movd %%eax,%%mm2 \n\t"
  231. "movd %0,%%mm3 \n\t" //mm3 = rho
  232. "movq (%1),%%mm0 \n\t" // W[ix] for ix=0
  233. ::"r"(rho),"r"(W):"%eax");
  234. #endif
  235. for (ix = 0; ix < n->used; ix++) {
  236. /* mu = ai * m' mod b
  237. *
  238. * We avoid a double precision multiplication (which isn't required)
  239. * by casting the value down to a mp_digit. Note this requires
  240. * that W[ix-1] have the carry cleared (see after the inner loop)
  241. */
  242. #ifndef LTMSSE
  243. register mp_digit mu;
  244. mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
  245. #else
  246. asm("pmuludq %mm3,%mm0 \n\t" // multiply against rho
  247. "pand %mm2,%mm0 \n\t"); // mu == mm0
  248. #endif
  249. /* a = a + mu * m * b**i
  250. *
  251. * This is computed in place and on the fly. The multiplication
  252. * by b**i is handled by offseting which columns the results
  253. * are added to.
  254. *
  255. * Note the comba method normally doesn't handle carries in the
  256. * inner loop In this case we fix the carry from the previous
  257. * column since the Montgomery reduction requires digits of the
  258. * result (so far) [see above] to work. This is
  259. * handled by fixing up one carry after the inner loop. The
  260. * carry fixups are done in order so after these loops the
  261. * first m->used words of W[] have the carries fixed
  262. */
  263. {
  264. register int iy;
  265. register mp_digit *tmpn;
  266. register mp_word *_W;
  267. /* alias for the digits of the modulus */
  268. tmpn = n->dp;
  269. /* Alias for the columns set by an offset of ix */
  270. _W = W + ix;
  271. /* inner loop */
  272. for (iy = 0; iy < n->used; iy++) {
  273. #ifndef LTMSSE
  274. *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
  275. #else
  276. // SSE version
  277. asm ("movd (%0), %%mm1 \n\t" // load right side
  278. "pmuludq %%mm0,%%mm1 \n\t" // multiply into left side
  279. "paddq (%1),%%mm1 \n\t" // add 64-bit result out
  280. "movq %%mm1,(%1)" // store result
  281. :: "r"(tmpn), "r"(_W));
  282. // update pointers
  283. ++tmpn;
  284. ++_W;
  285. #endif
  286. }
  287. }
  288. /* now fix carry for next digit, W[ix+1] */
  289. #ifndef LTMSSE
  290. W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
  291. #else
  292. asm("movq (%0),%%mm0 \n\t" // W[ix]
  293. "psrlq $28,%%mm0 \n\t" // W[ix]>>28
  294. "paddq 8(%0),%%mm0 \n\t" // W[ix+1] + W[ix]>>28
  295. "movq %%mm0,8(%0) " // store
  296. ::"r"(&W[ix]));
  297. #endif
  298. }
  299. /* now we have to propagate the carries and
  300. * shift the words downward [all those least
  301. * significant digits we zeroed].
  302. */
  303. {
  304. register mp_digit *tmpx;
  305. register mp_word *_W, *_W1;
  306. /* nox fix rest of carries */
  307. /* alias for current word */
  308. _W1 = W + ix;
  309. /* alias for next word, where the carry goes */
  310. _W = W + ++ix;
  311. /* alias for destination word */
  312. tmpx = x->dp;
  313. for (; ix <= n->used * 2 + 1; ix++) {
  314. #ifndef LTMSSE
  315. *tmpx++ = (mp_digit)(*_W1 & ((mp_word) MP_MASK));
  316. *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
  317. #else
  318. asm("movq %%mm0,%%mm1 \n\t" // copy of W[ix]
  319. "psrlq $28,%%mm0 \n\t" // >>28
  320. "pand %%mm2,%%mm1 \n\t" // & with MP_MASK
  321. "paddq (%0),%%mm0 \n\t" // += _W
  322. "movd %%mm1,(%1) \n\t" // store it
  323. ::"r"(_W),"r"(tmpx));
  324. ++_W; ++tmpx;
  325. #endif
  326. }
  327. /* zero oldused digits, if the input a was larger than
  328. * m->used+1 we'll have to clear the digits
  329. */
  330. for (ix = n->used + 1; ix < olduse; ix++) {
  331. *tmpx++ = 0;
  332. }
  333. }
  334. #ifdef LTMSSE
  335. asm("emms");
  336. #endif
  337. /* set the max used and clamp */
  338. x->used = n->used + 1;
  339. mp_clamp (x);
  340. /* if A >= m then A = A - m */
  341. if (mp_cmp_mag (x, n) != MP_LT) {
  342. return s_mp_sub (x, n, x);
  343. }
  344. return MP_OKAY;
  345. }
  346. /* End: bn_fast_mp_montgomery_reduce.c */
  347. /* Start: bn_fast_s_mp_mul_digs.c */
  348. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  349. *
  350. * LibTomMath is a library that provides multiple-precision
  351. * integer arithmetic as well as number theoretic functionality.
  352. *
  353. * The library was designed directly after the MPI library by
  354. * Michael Fromberger but has been written from scratch with
  355. * additional optimizations in place.
  356. *
  357. * The library is free for all purposes without any express
  358. * guarantee it works.
  359. *
  360. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  361. */
  362. #include <ltc_tommath.h>
  363. /* Fast (comba) multiplier
  364. *
  365. * This is the fast column-array [comba] multiplier. It is
  366. * designed to compute the columns of the product first
  367. * then handle the carries afterwards. This has the effect
  368. * of making the nested loops that compute the columns very
  369. * simple and schedulable on super-scalar processors.
  370. *
  371. * This has been modified to produce a variable number of
  372. * digits of output so if say only a half-product is required
  373. * you don't have to compute the upper half (a feature
  374. * required for fast Barrett reduction).
  375. *
  376. * Based on Algorithm 14.12 on pp.595 of HAC.
  377. *
  378. */
  379. int
  380. fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
  381. {
  382. int olduse, res, pa, ix;
  383. mp_word W[MP_WARRAY];
  384. /* grow the destination as required */
  385. if (c->alloc < digs) {
  386. if ((res = mp_grow (c, digs)) != MP_OKAY) {
  387. return res;
  388. }
  389. }
  390. /* clear temp buf (the columns) */
  391. memset (W, 0, sizeof (mp_word) * digs);
  392. /* calculate the columns */
  393. pa = a->used;
  394. for (ix = 0; ix < pa; ix++) {
  395. /* this multiplier has been modified to allow you to
  396. * control how many digits of output are produced.
  397. * So at most we want to make upto "digs" digits of output.
  398. *
  399. * this adds products to distinct columns (at ix+iy) of W
  400. * note that each step through the loop is not dependent on
  401. * the previous which means the compiler can easily unroll
  402. * the loop without scheduling problems
  403. */
  404. {
  405. #ifndef LTMSSE
  406. register mp_digit tmpx;
  407. #endif
  408. register mp_digit *tmpy;
  409. register mp_word *_W;
  410. register int iy, pb;
  411. /* alias for the the word on the left e.g. A[ix] * A[iy] */
  412. #ifndef LTMSSE
  413. tmpx = a->dp[ix];
  414. #else
  415. // SSE: now we load the left side in mm0
  416. asm (" movd %0, %%mm0 " :: "r"(a->dp[ix]));
  417. #endif
  418. /* alias for the right side */
  419. tmpy = b->dp;
  420. /* alias for the columns, each step through the loop adds a new
  421. term to each column
  422. */
  423. _W = W + ix;
  424. /* the number of digits is limited by their placement. E.g.
  425. we avoid multiplying digits that will end up above the # of
  426. digits of precision requested
  427. */
  428. pb = MIN (b->used, digs - ix);
  429. for (iy = 0; iy < pb; iy++) {
  430. #ifndef LTMSSE
  431. *_W++ += ((mp_word)tmpx) * ((mp_word)*tmpy++);
  432. #else
  433. // SSE version
  434. asm ("movd (%0), %%mm1 \n\t" // load right side
  435. "pmuludq %%mm0,%%mm1 \n\t" // multiply into left side
  436. "paddq (%1), %%mm1 \n\t" // add 64-bit result out
  437. "movq %%mm1,(%1)" // store result
  438. :: "r"(tmpy), "r"(_W));
  439. // update pointers
  440. ++tmpy;
  441. ++_W;
  442. #endif
  443. }
  444. }
  445. }
  446. /* setup dest */
  447. olduse = c->used;
  448. c->used = digs;
  449. {
  450. register mp_digit *tmpc;
  451. /* At this point W[] contains the sums of each column. To get the
  452. * correct result we must take the extra bits from each column and
  453. * carry them down
  454. *
  455. * Note that while this adds extra code to the multiplier it
  456. * saves time since the carry propagation is removed from the
  457. * above nested loop.This has the effect of reducing the work
  458. * from N*(N+N*c)==N**2 + c*N**2 to N**2 + N*c where c is the
  459. * cost of the shifting. On very small numbers this is slower
  460. * but on most cryptographic size numbers it is faster.
  461. *
  462. * In this particular implementation we feed the carries from
  463. * behind which means when the loop terminates we still have one
  464. * last digit to copy
  465. */
  466. tmpc = c->dp;
  467. #ifdef LTMSSE
  468. // mm2 has W[ix-1]
  469. asm("movq (%0),%%mm2"::"r"(W));
  470. #endif
  471. for (ix = 1; ix < digs; ix++) {
  472. #ifndef LTMSSE
  473. /* forward the carry from the previous temp */
  474. W[ix] += (W[ix - 1] >> ((mp_word) DIGIT_BIT));
  475. /* now extract the previous digit [below the carry] */
  476. *tmpc++ = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK));
  477. #else
  478. asm(
  479. "movq (%0),%%mm1 \n\t" // W[ix]
  480. "movd %%mm2,%%eax \n\t" // get 32-bit version of it W[ix-1]
  481. "psrlq $28,%%mm2 \n\t" // W[ix-1] >> DIGIT_BIT ... must be 28
  482. "andl $268435455,%%eax \n\t" // & with MP_MASK against W[ix-1]
  483. "paddq %%mm1,%%mm2 \n\t" // add them
  484. "movl %%eax,(%1) \n\t" // store it
  485. :: "r"(&W[ix]), "r"(tmpc) : "%eax");
  486. ++tmpc;
  487. #endif
  488. }
  489. #ifndef LTMSSE
  490. /* fetch the last digit */
  491. *tmpc++ = (mp_digit) (W[digs - 1] & ((mp_word) MP_MASK));
  492. #else
  493. // get last since we don't store into W[ix] anymore ;-)
  494. asm("movd %%mm2,%%eax \n\t"
  495. "andl $268435455,%%eax \n\t" // & with MP_MASK against W[ix-1]
  496. "movl %%eax,(%0)" // store it
  497. ::"r"(tmpc):"%eax");
  498. ++tmpc;
  499. #endif
  500. /* clear unused digits [that existed in the old copy of c] */
  501. for (; ix < olduse; ix++) {
  502. *tmpc++ = 0;
  503. }
  504. }
  505. #ifdef LTMSSE
  506. asm("emms");
  507. #endif
  508. mp_clamp (c);
  509. return MP_OKAY;
  510. }
  511. /* End: bn_fast_s_mp_mul_digs.c */
  512. /* Start: bn_fast_s_mp_mul_high_digs.c */
  513. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  514. *
  515. * LibTomMath is a library that provides multiple-precision
  516. * integer arithmetic as well as number theoretic functionality.
  517. *
  518. * The library was designed directly after the MPI library by
  519. * Michael Fromberger but has been written from scratch with
  520. * additional optimizations in place.
  521. *
  522. * The library is free for all purposes without any express
  523. * guarantee it works.
  524. *
  525. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  526. */
  527. #include <ltc_tommath.h>
  528. /* this is a modified version of fast_s_mp_mul_digs that only produces
  529. * output digits *above* digs. See the comments for fast_s_mp_mul_digs
  530. * to see how it works.
  531. *
  532. * This is used in the Barrett reduction since for one of the multiplications
  533. * only the higher digits were needed. This essentially halves the work.
  534. *
  535. * Based on Algorithm 14.12 on pp.595 of HAC.
  536. */
  537. int
  538. fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
  539. {
  540. int oldused, newused, res, pa, pb, ix;
  541. mp_word W[MP_WARRAY];
  542. /* calculate size of product and allocate more space if required */
  543. newused = a->used + b->used + 1;
  544. if (c->alloc < newused) {
  545. if ((res = mp_grow (c, newused)) != MP_OKAY) {
  546. return res;
  547. }
  548. }
  549. /* like the other comba method we compute the columns first */
  550. pa = a->used;
  551. pb = b->used;
  552. memset (W + digs, 0, (pa + pb + 1 - digs) * sizeof (mp_word));
  553. for (ix = 0; ix < pa; ix++) {
  554. {
  555. #ifndef LTMSSE
  556. register mp_digit tmpx;
  557. #endif
  558. register mp_digit *tmpy;
  559. register int iy;
  560. register mp_word *_W;
  561. /* work todo, that is we only calculate digits that are at "digs" or above */
  562. iy = digs - ix;
  563. /* copy of word on the left of A[ix] * B[iy] */
  564. #ifndef LTMSSE
  565. tmpx = a->dp[ix];
  566. #else
  567. //SSE we load tmpx into mm0
  568. asm (" movd %0, %%mm0 " :: "r"(a->dp[ix]));
  569. #endif
  570. /* alias for right side */
  571. tmpy = b->dp + iy;
  572. /* alias for the columns of output. Offset to be equal to or above the
  573. * smallest digit place requested
  574. */
  575. _W = W + digs;
  576. /* skip cases below zero where ix > digs */
  577. if (iy < 0) {
  578. iy = abs(iy);
  579. tmpy += iy;
  580. _W += iy;
  581. iy = 0;
  582. }
  583. /* compute column products for digits above the minimum */
  584. for (; iy < pb; iy++) {
  585. #ifndef LTMSSE
  586. *_W++ += ((mp_word) tmpx) * ((mp_word)*tmpy++);
  587. #else
  588. // SSE version
  589. asm ("movd (%0), %%mm1 \n\t" // load right side
  590. "pmuludq %%mm0,%%mm1 \n\t" // multiply into left side
  591. "paddq (%1),%%mm1 \n\t" // add 64-bit result out
  592. "movq %%mm1,(%1)" // store result
  593. :: "r"(tmpy), "r"(_W));
  594. // update pointers
  595. ++tmpy;
  596. ++_W;
  597. #endif
  598. }
  599. }
  600. }
  601. /* setup dest */
  602. oldused = c->used;
  603. c->used = newused;
  604. /* now convert the array W downto what we need
  605. *
  606. * See comments in bn_fast_s_mp_mul_digs.c
  607. */
  608. #ifdef LTMSSE
  609. // mm2 has W[ix-1]
  610. asm("movq (%0),%%mm2"::"r"(W + digs));
  611. #endif
  612. for (ix = digs + 1; ix < newused; ix++) {
  613. /* forward the carry from the previous temp */
  614. #ifndef LTMSSE
  615. W[ix] += (W[ix - 1] >> ((mp_word) DIGIT_BIT));
  616. c->dp[ix - 1] = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK));
  617. #else
  618. asm(
  619. "movd %%mm2,%%eax \n\t" // get 32-bit version of it W[ix-1]
  620. "psrlq $28,%%mm2 \n\t" // W[ix-1] >> DIGIT_BIT ... must be 28
  621. "andl $268435455,%%eax \n\t" // & with MP_MASK against W[ix-1]
  622. "paddq (%0),%%mm2 \n\t" // add them
  623. "movl %%eax,(%1) \n\t" // store it
  624. :: "r"(&W[ix]), "r"(&c->dp[ix-1]) : "%eax");
  625. #endif
  626. }
  627. #ifndef LTMSSE
  628. c->dp[newused - 1] = (mp_digit) (W[newused - 1] & ((mp_word) MP_MASK));
  629. #else
  630. // get last since we don't store into W[ix] anymore ;-)
  631. asm("movd %%mm2,%%eax\n\t"
  632. "andl $268435455,%%eax \n\t" // & with MP_MASK against W[ix-1]
  633. "movl %%eax,(%0)" // store it
  634. ::"r"(&(c->dp[newused-1])):"%eax");
  635. #endif
  636. for (; ix < oldused; ix++) {
  637. c->dp[ix] = 0;
  638. }
  639. #ifdef LTMSSE
  640. asm("emms");
  641. #endif
  642. mp_clamp (c);
  643. return MP_OKAY;
  644. }
  645. /* End: bn_fast_s_mp_mul_high_digs.c */
  646. /* Start: bn_fast_s_mp_sqr.c */
  647. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  648. *
  649. * LibTomMath is a library that provides multiple-precision
  650. * integer arithmetic as well as number theoretic functionality.
  651. *
  652. * The library was designed directly after the MPI library by
  653. * Michael Fromberger but has been written from scratch with
  654. * additional optimizations in place.
  655. *
  656. * The library is free for all purposes without any express
  657. * guarantee it works.
  658. *
  659. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  660. */
  661. #include <ltc_tommath.h>
  662. /* fast squaring
  663. *
  664. * This is the comba method where the columns of the product
  665. * are computed first then the carries are computed. This
  666. * has the effect of making a very simple inner loop that
  667. * is executed the most
  668. *
  669. * W2 represents the outer products and W the inner.
  670. *
  671. * A further optimizations is made because the inner
  672. * products are of the form "A * B * 2". The *2 part does
  673. * not need to be computed until the end which is good
  674. * because 64-bit shifts are slow!
  675. *
  676. * Based on Algorithm 14.16 on pp.597 of HAC.
  677. *
  678. */
  679. int fast_s_mp_sqr (mp_int * a, mp_int * b)
  680. {
  681. int olduse, newused, res, ix, pa;
  682. mp_word W2[MP_WARRAY], W[MP_WARRAY];
  683. /* calculate size of product and allocate as required */
  684. pa = a->used;
  685. newused = pa + pa;
  686. if (b->alloc < newused) {
  687. if ((res = mp_grow (b, newused)) != MP_OKAY) {
  688. return res;
  689. }
  690. }
  691. /* zero temp buffer (columns)
  692. * Note that there are two buffers. Since squaring requires
  693. * a outer and inner product and the inner product requires
  694. * computing a product and doubling it (a relatively expensive
  695. * op to perform n**2 times if you don't have to) the inner and
  696. * outer products are computed in different buffers. This way
  697. * the inner product can be doubled using n doublings instead of
  698. * n**2
  699. */
  700. memset (W, 0, newused * sizeof (mp_word));
  701. #ifndef LTMSSE
  702. memset (W2, 0, newused * sizeof (mp_word));
  703. #endif
  704. /* This computes the inner product. To simplify the inner N**2 loop
  705. * the multiplication by two is done afterwards in the N loop.
  706. */
  707. for (ix = 0; ix < pa; ix++) {
  708. /* compute the outer product
  709. *
  710. * Note that every outer product is computed
  711. * for a particular column only once which means that
  712. * there is no need todo a double precision addition
  713. * into the W2[] array.
  714. */
  715. #ifndef LTMSSE
  716. W2[ix + ix] = ((mp_word)a->dp[ix]) * ((mp_word)a->dp[ix]);
  717. #else
  718. asm("movd %0,%%xmm0 \n\t" // load a->dp[ix]
  719. "movdq2q %%xmm0,%%mm0 \n\t" // get 64-bit version
  720. "pmuludq %%xmm0,%%xmm0 \n\t" // square it
  721. "movdqu %%xmm0,(%1) \n\t" // store it (8-byte result, 8-byte zero)
  722. ::"r"(a->dp[ix]), "r"(&(W2[ix+ix])));
  723. #endif
  724. {
  725. #ifndef LTMSSE
  726. register mp_digit tmpx;
  727. #endif
  728. register mp_digit *tmpy;
  729. register mp_word *_W;
  730. register int iy;
  731. /* copy of left side */
  732. #ifndef LTMSSE
  733. tmpx = a->dp[ix];
  734. #else
  735. //SSE we load tmpx into mm0 [note: loaded above]
  736. // asm (" movd %0, %%mm0 " :: "r"(a->dp[ix]));
  737. #endif
  738. /* alias for right side */
  739. tmpy = a->dp + (ix + 1);
  740. /* the column to store the result in */
  741. _W = W + (ix + ix + 1);
  742. /* inner products */
  743. for (iy = ix + 1; iy < pa; iy++) {
  744. #ifndef LTMSSE
  745. *_W++ += ((mp_word)tmpx) * ((mp_word)*tmpy++);
  746. #else
  747. // SSE version
  748. asm ("movd (%0), %%mm1 \n\t" // load right side
  749. "pmuludq %%mm0,%%mm1 \n\t" // multiply into left side
  750. "paddq (%1),%%mm1 \n\t" // add 64-bit result out
  751. "movq %%mm1,(%1)" // store result
  752. :: "r"(tmpy), "r"(_W));
  753. // update pointers
  754. ++tmpy;
  755. ++_W;
  756. #endif
  757. }
  758. }
  759. }
  760. /* setup dest */
  761. olduse = b->used;
  762. b->used = newused;
  763. /* now compute digits
  764. *
  765. * We have to double the inner product sums, add in the
  766. * outer product sums, propagate carries and convert
  767. * to single precision.
  768. */
  769. {
  770. register mp_digit *tmpb;
  771. /* double first value, since the inner products are
  772. * half of what they should be
  773. */
  774. tmpb = b->dp;
  775. #ifndef LTMSSE
  776. W[0] += W[0] + W2[0];
  777. #else
  778. // mm2 has W[ix-1]
  779. asm("movq (%0),%%mm2 \n\t" // load W[0]
  780. "paddq %%mm2,%%mm2 \n\t" // W[0] + W[0]
  781. "paddq (%1),%%mm2 \n\t" // W[0] + W[0] + W2[0]
  782. ::"r"(W),"r"(W2));
  783. #endif
  784. for (ix = 1; ix < newused; ix++) {
  785. #ifndef LTMSSE
  786. /* double/add next digit */
  787. W[ix] += W[ix] + W2[ix];
  788. /* propagate carry forwards [from the previous digit] */
  789. W[ix] = W[ix] + (W[ix - 1] >> ((mp_word) DIGIT_BIT));
  790. /* store the current digit now that the carry isn't
  791. * needed
  792. */
  793. *tmpb++ = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK));
  794. #else
  795. asm( "movq (%0),%%mm0 \n\t" // load W[ix]
  796. "movd %%mm2,%%eax \n\t" // 32-bit version of W[ix-1]
  797. "paddq %%mm0,%%mm0 \n\t" // W[ix] + W[ix]
  798. "psrlq $28,%%mm2 \n\t" // W[ix-1] >> DIGIT_BIT ... must be 28
  799. "paddq (%1),%%mm0 \n\t" // W[ix] + W[ix] + W2[ix]
  800. "andl $268435455,%%eax \n\t" // & with MP_MASK against W[ix-1]
  801. "paddq %%mm0,%%mm2 \n\t" // W[ix] + W[ix] + W2[ix] + W[ix-1]>>DIGIT_BIT
  802. "movl %%eax,(%2) " // store it
  803. :: "r"(&W[ix]), "r"(&W2[ix]), "r"(tmpb):"%eax");
  804. ++tmpb;
  805. #endif
  806. }
  807. #ifndef LTMSSE
  808. /* set the last value. Note even if the carry is zero
  809. * this is required since the next step will not zero
  810. * it if b originally had a value at b->dp[2*a.used]
  811. */
  812. *tmpb++ = (mp_digit) (W[(newused) - 1] & ((mp_word) MP_MASK));
  813. #else
  814. // get last since we don't store into W[ix] anymore ;-)
  815. asm("movd %%mm2,%%eax \n\t"
  816. "andl $268435455,%%eax \n\t" // & with MP_MASK against W[ix-1]
  817. "movl %%eax,(%0) " // store it
  818. ::"r"(tmpb):"%eax");
  819. ++tmpb;
  820. #endif
  821. /* clear high digits of b if there were any originally */
  822. for (; ix < olduse; ix++) {
  823. *tmpb++ = 0;
  824. }
  825. }
  826. #ifdef LTMSSE
  827. asm("emms");
  828. #endif
  829. mp_clamp (b);
  830. return MP_OKAY;
  831. }
  832. /* End: bn_fast_s_mp_sqr.c */
  833. /* Start: bn_mp_2expt.c */
  834. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  835. *
  836. * LibTomMath is a library that provides multiple-precision
  837. * integer arithmetic as well as number theoretic functionality.
  838. *
  839. * The library was designed directly after the MPI library by
  840. * Michael Fromberger but has been written from scratch with
  841. * additional optimizations in place.
  842. *
  843. * The library is free for all purposes without any express
  844. * guarantee it works.
  845. *
  846. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  847. */
  848. #include <ltc_tommath.h>
  849. /* computes a = 2**b
  850. *
  851. * Simple algorithm which zeroes the int, grows it then just sets one bit
  852. * as required.
  853. */
  854. int
  855. mp_2expt (mp_int * a, int b)
  856. {
  857. int res;
  858. /* zero a as per default */
  859. mp_zero (a);
  860. /* grow a to accomodate the single bit */
  861. if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) {
  862. return res;
  863. }
  864. /* set the used count of where the bit will go */
  865. a->used = b / DIGIT_BIT + 1;
  866. /* put the single bit in its place */
  867. a->dp[b / DIGIT_BIT] = 1 << (b % DIGIT_BIT);
  868. return MP_OKAY;
  869. }
  870. /* End: bn_mp_2expt.c */
  871. /* Start: bn_mp_abs.c */
  872. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  873. *
  874. * LibTomMath is a library that provides multiple-precision
  875. * integer arithmetic as well as number theoretic functionality.
  876. *
  877. * The library was designed directly after the MPI library by
  878. * Michael Fromberger but has been written from scratch with
  879. * additional optimizations in place.
  880. *
  881. * The library is free for all purposes without any express
  882. * guarantee it works.
  883. *
  884. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  885. */
  886. #include <ltc_tommath.h>
  887. /* b = |a|
  888. *
  889. * Simple function copies the input and fixes the sign to positive
  890. */
  891. int
  892. mp_abs (mp_int * a, mp_int * b)
  893. {
  894. int res;
  895. /* copy a to b */
  896. if (a != b) {
  897. if ((res = mp_copy (a, b)) != MP_OKAY) {
  898. return res;
  899. }
  900. }
  901. /* force the sign of b to positive */
  902. b->sign = MP_ZPOS;
  903. return MP_OKAY;
  904. }
  905. /* End: bn_mp_abs.c */
  906. /* Start: bn_mp_add.c */
  907. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  908. *
  909. * LibTomMath is a library that provides multiple-precision
  910. * integer arithmetic as well as number theoretic functionality.
  911. *
  912. * The library was designed directly after the MPI library by
  913. * Michael Fromberger but has been written from scratch with
  914. * additional optimizations in place.
  915. *
  916. * The library is free for all purposes without any express
  917. * guarantee it works.
  918. *
  919. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  920. */
  921. #include <ltc_tommath.h>
  922. /* high level addition (handles signs) */
  923. int mp_add (mp_int * a, mp_int * b, mp_int * c)
  924. {
  925. int sa, sb, res;
  926. /* get sign of both inputs */
  927. sa = a->sign;
  928. sb = b->sign;
  929. /* handle two cases, not four */
  930. if (sa == sb) {
  931. /* both positive or both negative */
  932. /* add their magnitudes, copy the sign */
  933. c->sign = sa;
  934. res = s_mp_add (a, b, c);
  935. } else {
  936. /* one positive, the other negative */
  937. /* subtract the one with the greater magnitude from */
  938. /* the one of the lesser magnitude. The result gets */
  939. /* the sign of the one with the greater magnitude. */
  940. if (mp_cmp_mag (a, b) == MP_LT) {
  941. c->sign = sb;
  942. res = s_mp_sub (b, a, c);
  943. } else {
  944. c->sign = sa;
  945. res = s_mp_sub (a, b, c);
  946. }
  947. }
  948. return res;
  949. }
  950. /* End: bn_mp_add.c */
  951. /* Start: bn_mp_add_d.c */
  952. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  953. *
  954. * LibTomMath is a library that provides multiple-precision
  955. * integer arithmetic as well as number theoretic functionality.
  956. *
  957. * The library was designed directly after the MPI library by
  958. * Michael Fromberger but has been written from scratch with
  959. * additional optimizations in place.
  960. *
  961. * The library is free for all purposes without any express
  962. * guarantee it works.
  963. *
  964. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  965. */
  966. #include <ltc_tommath.h>
  967. /* single digit addition */
  968. int
  969. mp_add_d (mp_int * a, mp_digit b, mp_int * c)
  970. {
  971. int res, ix, oldused;
  972. mp_digit *tmpa, *tmpc, mu;
  973. /* grow c as required */
  974. if (c->alloc < a->used + 1) {
  975. if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
  976. return res;
  977. }
  978. }
  979. /* if a is negative and |a| >= b, call c = |a| - b */
  980. if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
  981. /* temporarily fix sign of a */
  982. a->sign = MP_ZPOS;
  983. /* c = |a| - b */
  984. res = mp_sub_d(a, b, c);
  985. /* fix sign */
  986. a->sign = c->sign = MP_NEG;
  987. return res;
  988. }
  989. /* old number of used digits in c */
  990. oldused = c->used;
  991. /* sign always positive */
  992. c->sign = MP_ZPOS;
  993. /* source alias */
  994. tmpa = a->dp;
  995. /* destination alias */
  996. tmpc = c->dp;
  997. /* if a is positive */
  998. if (a->sign == MP_ZPOS) {
  999. /* add digit, after this we're propagating
  1000. * the carry.
  1001. */
  1002. *tmpc = *tmpa++ + b;
  1003. mu = *tmpc >> DIGIT_BIT;
  1004. *tmpc++ &= MP_MASK;
  1005. /* now handle rest of the digits */
  1006. for (ix = 1; ix < a->used; ix++) {
  1007. *tmpc = *tmpa++ + mu;
  1008. mu = *tmpc >> DIGIT_BIT;
  1009. *tmpc++ &= MP_MASK;
  1010. }
  1011. /* set final carry */
  1012. ix++;
  1013. *tmpc++ = mu;
  1014. /* setup size */
  1015. c->used = a->used + 1;
  1016. } else {
  1017. /* a was negative and |a| < b */
  1018. c->used = 1;
  1019. /* the result is a single digit */
  1020. if (a->used == 1) {
  1021. *tmpc++ = b - a->dp[0];
  1022. } else {
  1023. *tmpc++ = b;
  1024. }
  1025. /* setup count so the clearing of oldused
  1026. * can fall through correctly
  1027. */
  1028. ix = 1;
  1029. }
  1030. /* now zero to oldused */
  1031. while (ix++ < oldused) {
  1032. *tmpc++ = 0;
  1033. }
  1034. mp_clamp(c);
  1035. return MP_OKAY;
  1036. }
  1037. /* End: bn_mp_add_d.c */
  1038. /* Start: bn_mp_addmod.c */
  1039. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1040. *
  1041. * LibTomMath is a library that provides multiple-precision
  1042. * integer arithmetic as well as number theoretic functionality.
  1043. *
  1044. * The library was designed directly after the MPI library by
  1045. * Michael Fromberger but has been written from scratch with
  1046. * additional optimizations in place.
  1047. *
  1048. * The library is free for all purposes without any express
  1049. * guarantee it works.
  1050. *
  1051. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1052. */
  1053. #include <ltc_tommath.h>
  1054. /* d = a + b (mod c) */
  1055. int
  1056. mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
  1057. {
  1058. int res;
  1059. mp_int t;
  1060. if ((res = mp_init (&t)) != MP_OKAY) {
  1061. return res;
  1062. }
  1063. if ((res = mp_add (a, b, &t)) != MP_OKAY) {
  1064. mp_clear (&t);
  1065. return res;
  1066. }
  1067. res = mp_mod (&t, c, d);
  1068. mp_clear (&t);
  1069. return res;
  1070. }
  1071. /* End: bn_mp_addmod.c */
  1072. /* Start: bn_mp_and.c */
  1073. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1074. *
  1075. * LibTomMath is a library that provides multiple-precision
  1076. * integer arithmetic as well as number theoretic functionality.
  1077. *
  1078. * The library was designed directly after the MPI library by
  1079. * Michael Fromberger but has been written from scratch with
  1080. * additional optimizations in place.
  1081. *
  1082. * The library is free for all purposes without any express
  1083. * guarantee it works.
  1084. *
  1085. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1086. */
  1087. #include <ltc_tommath.h>
  1088. /* AND two ints together */
  1089. int
  1090. mp_and (mp_int * a, mp_int * b, mp_int * c)
  1091. {
  1092. int res, ix, px;
  1093. mp_int t, *x;
  1094. if (a->used > b->used) {
  1095. if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
  1096. return res;
  1097. }
  1098. px = b->used;
  1099. x = b;
  1100. } else {
  1101. if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
  1102. return res;
  1103. }
  1104. px = a->used;
  1105. x = a;
  1106. }
  1107. for (ix = 0; ix < px; ix++) {
  1108. t.dp[ix] &= x->dp[ix];
  1109. }
  1110. /* zero digits above the last from the smallest mp_int */
  1111. for (; ix < t.used; ix++) {
  1112. t.dp[ix] = 0;
  1113. }
  1114. mp_clamp (&t);
  1115. mp_exch (c, &t);
  1116. mp_clear (&t);
  1117. return MP_OKAY;
  1118. }
  1119. /* End: bn_mp_and.c */
  1120. /* Start: bn_mp_clamp.c */
  1121. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1122. *
  1123. * LibTomMath is a library that provides multiple-precision
  1124. * integer arithmetic as well as number theoretic functionality.
  1125. *
  1126. * The library was designed directly after the MPI library by
  1127. * Michael Fromberger but has been written from scratch with
  1128. * additional optimizations in place.
  1129. *
  1130. * The library is free for all purposes without any express
  1131. * guarantee it works.
  1132. *
  1133. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1134. */
  1135. #include <ltc_tommath.h>
  1136. /* trim unused digits
  1137. *
  1138. * This is used to ensure that leading zero digits are
  1139. * trimed and the leading "used" digit will be non-zero
  1140. * Typically very fast. Also fixes the sign if there
  1141. * are no more leading digits
  1142. */
  1143. void
  1144. mp_clamp (mp_int * a)
  1145. {
  1146. /* decrease used while the most significant digit is
  1147. * zero.
  1148. */
  1149. while (a->used > 0 && a->dp[a->used - 1] == 0) {
  1150. --(a->used);
  1151. }
  1152. /* reset the sign flag if used == 0 */
  1153. if (a->used == 0) {
  1154. a->sign = MP_ZPOS;
  1155. }
  1156. }
  1157. /* End: bn_mp_clamp.c */
  1158. /* Start: bn_mp_clear.c */
  1159. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1160. *
  1161. * LibTomMath is a library that provides multiple-precision
  1162. * integer arithmetic as well as number theoretic functionality.
  1163. *
  1164. * The library was designed directly after the MPI library by
  1165. * Michael Fromberger but has been written from scratch with
  1166. * additional optimizations in place.
  1167. *
  1168. * The library is free for all purposes without any express
  1169. * guarantee it works.
  1170. *
  1171. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1172. */
  1173. #include <ltc_tommath.h>
  1174. /* clear one (frees) */
  1175. void
  1176. mp_clear (mp_int * a)
  1177. {
  1178. int i;
  1179. /* only do anything if a hasn't been freed previously */
  1180. if (a->dp != NULL) {
  1181. /* first zero the digits */
  1182. for (i = 0; i < a->used; i++) {
  1183. a->dp[i] = 0;
  1184. }
  1185. /* free ram */
  1186. XFREE(a->dp);
  1187. /* reset members to make debugging easier */
  1188. a->dp = NULL;
  1189. a->alloc = a->used = 0;
  1190. a->sign = MP_ZPOS;
  1191. }
  1192. }
  1193. /* End: bn_mp_clear.c */
  1194. /* Start: bn_mp_clear_multi.c */
  1195. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1196. *
  1197. * LibTomMath is a library that provides multiple-precision
  1198. * integer arithmetic as well as number theoretic functionality.
  1199. *
  1200. * The library was designed directly after the MPI library by
  1201. * Michael Fromberger but has been written from scratch with
  1202. * additional optimizations in place.
  1203. *
  1204. * The library is free for all purposes without any express
  1205. * guarantee it works.
  1206. *
  1207. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1208. */
  1209. #include <ltc_tommath.h>
  1210. #include <stdarg.h>
  1211. void mp_clear_multi(mp_int *mp, ...)
  1212. {
  1213. mp_int* next_mp = mp;
  1214. va_list args;
  1215. va_start(args, mp);
  1216. while (next_mp != NULL) {
  1217. mp_clear(next_mp);
  1218. next_mp = va_arg(args, mp_int*);
  1219. }
  1220. va_end(args);
  1221. }
  1222. /* End: bn_mp_clear_multi.c */
  1223. /* Start: bn_mp_cmp.c */
  1224. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1225. *
  1226. * LibTomMath is a library that provides multiple-precision
  1227. * integer arithmetic as well as number theoretic functionality.
  1228. *
  1229. * The library was designed directly after the MPI library by
  1230. * Michael Fromberger but has been written from scratch with
  1231. * additional optimizations in place.
  1232. *
  1233. * The library is free for all purposes without any express
  1234. * guarantee it works.
  1235. *
  1236. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1237. */
  1238. #include <ltc_tommath.h>
  1239. /* compare two ints (signed)*/
  1240. int
  1241. mp_cmp (mp_int * a, mp_int * b)
  1242. {
  1243. /* compare based on sign */
  1244. if (a->sign != b->sign) {
  1245. if (a->sign == MP_NEG) {
  1246. return MP_LT;
  1247. } else {
  1248. return MP_GT;
  1249. }
  1250. }
  1251. /* compare digits */
  1252. if (a->sign == MP_NEG) {
  1253. /* if negative compare opposite direction */
  1254. return mp_cmp_mag(b, a);
  1255. } else {
  1256. return mp_cmp_mag(a, b);
  1257. }
  1258. }
  1259. /* End: bn_mp_cmp.c */
  1260. /* Start: bn_mp_cmp_d.c */
  1261. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1262. *
  1263. * LibTomMath is a library that provides multiple-precision
  1264. * integer arithmetic as well as number theoretic functionality.
  1265. *
  1266. * The library was designed directly after the MPI library by
  1267. * Michael Fromberger but has been written from scratch with
  1268. * additional optimizations in place.
  1269. *
  1270. * The library is free for all purposes without any express
  1271. * guarantee it works.
  1272. *
  1273. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1274. */
  1275. #include <ltc_tommath.h>
  1276. /* compare a digit */
  1277. int mp_cmp_d(mp_int * a, mp_digit b)
  1278. {
  1279. /* compare based on sign */
  1280. if (a->sign == MP_NEG) {
  1281. return MP_LT;
  1282. }
  1283. /* compare based on magnitude */
  1284. if (a->used > 1) {
  1285. return MP_GT;
  1286. }
  1287. /* compare the only digit of a to b */
  1288. if (a->dp[0] > b) {
  1289. return MP_GT;
  1290. } else if (a->dp[0] < b) {
  1291. return MP_LT;
  1292. } else {
  1293. return MP_EQ;
  1294. }
  1295. }
  1296. /* End: bn_mp_cmp_d.c */
  1297. /* Start: bn_mp_cmp_mag.c */
  1298. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1299. *
  1300. * LibTomMath is a library that provides multiple-precision
  1301. * integer arithmetic as well as number theoretic functionality.
  1302. *
  1303. * The library was designed directly after the MPI library by
  1304. * Michael Fromberger but has been written from scratch with
  1305. * additional optimizations in place.
  1306. *
  1307. * The library is free for all purposes without any express
  1308. * guarantee it works.
  1309. *
  1310. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1311. */
  1312. #include <ltc_tommath.h>
  1313. /* compare maginitude of two ints (unsigned) */
  1314. int mp_cmp_mag (mp_int * a, mp_int * b)
  1315. {
  1316. int n;
  1317. mp_digit *tmpa, *tmpb;
  1318. /* compare based on # of non-zero digits */
  1319. if (a->used > b->used) {
  1320. return MP_GT;
  1321. }
  1322. if (a->used < b->used) {
  1323. return MP_LT;
  1324. }
  1325. /* alias for a */
  1326. tmpa = a->dp + (a->used - 1);
  1327. /* alias for b */
  1328. tmpb = b->dp + (a->used - 1);
  1329. /* compare based on digits */
  1330. for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
  1331. if (*tmpa > *tmpb) {
  1332. return MP_GT;
  1333. }
  1334. if (*tmpa < *tmpb) {
  1335. return MP_LT;
  1336. }
  1337. }
  1338. return MP_EQ;
  1339. }
  1340. /* End: bn_mp_cmp_mag.c */
  1341. /* Start: bn_mp_cnt_lsb.c */
  1342. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1343. *
  1344. * LibTomMath is a library that provides multiple-precision
  1345. * integer arithmetic as well as number theoretic functionality.
  1346. *
  1347. * The library was designed directly after the MPI library by
  1348. * Michael Fromberger but has been written from scratch with
  1349. * additional optimizations in place.
  1350. *
  1351. * The library is free for all purposes without any express
  1352. * guarantee it works.
  1353. *
  1354. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1355. */
  1356. #include <ltc_tommath.h>
  1357. static const int lnz[16] = {
  1358. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
  1359. };
  1360. /* Counts the number of lsbs which are zero before the first zero bit */
  1361. int mp_cnt_lsb(mp_int *a)
  1362. {
  1363. int x;
  1364. mp_digit q, qq;
  1365. /* easy out */
  1366. if (mp_iszero(a) == 1) {
  1367. return 0;
  1368. }
  1369. /* scan lower digits until non-zero */
  1370. for (x = 0; x < a->used && a->dp[x] == 0; x++);
  1371. q = a->dp[x];
  1372. x *= DIGIT_BIT;
  1373. /* now scan this digit until a 1 is found */
  1374. if ((q & 1) == 0) {
  1375. do {
  1376. qq = q & 15;
  1377. x += lnz[qq];
  1378. q >>= 4;
  1379. } while (qq == 0);
  1380. }
  1381. return x;
  1382. }
  1383. /* End: bn_mp_cnt_lsb.c */
  1384. /* Start: bn_mp_copy.c */
  1385. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1386. *
  1387. * LibTomMath is a library that provides multiple-precision
  1388. * integer arithmetic as well as number theoretic functionality.
  1389. *
  1390. * The library was designed directly after the MPI library by
  1391. * Michael Fromberger but has been written from scratch with
  1392. * additional optimizations in place.
  1393. *
  1394. * The library is free for all purposes without any express
  1395. * guarantee it works.
  1396. *
  1397. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1398. */
  1399. #include <ltc_tommath.h>
  1400. /* copy, b = a */
  1401. int
  1402. mp_copy (mp_int * a, mp_int * b)
  1403. {
  1404. int res, n;
  1405. /* if dst == src do nothing */
  1406. if (a == b) {
  1407. return MP_OKAY;
  1408. }
  1409. /* grow dest */
  1410. if (b->alloc < a->used) {
  1411. if ((res = mp_grow (b, a->used)) != MP_OKAY) {
  1412. return res;
  1413. }
  1414. }
  1415. /* zero b and copy the parameters over */
  1416. {
  1417. register mp_digit *tmpa, *tmpb;
  1418. /* pointer aliases */
  1419. /* source */
  1420. tmpa = a->dp;
  1421. /* destination */
  1422. tmpb = b->dp;
  1423. /* copy all the digits */
  1424. for (n = 0; n < a->used; n++) {
  1425. *tmpb++ = *tmpa++;
  1426. }
  1427. /* clear high digits */
  1428. for (; n < b->used; n++) {
  1429. *tmpb++ = 0;
  1430. }
  1431. }
  1432. /* copy used count and sign */
  1433. b->used = a->used;
  1434. b->sign = a->sign;
  1435. return MP_OKAY;
  1436. }
  1437. /* End: bn_mp_copy.c */
  1438. /* Start: bn_mp_count_bits.c */
  1439. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1440. *
  1441. * LibTomMath is a library that provides multiple-precision
  1442. * integer arithmetic as well as number theoretic functionality.
  1443. *
  1444. * The library was designed directly after the MPI library by
  1445. * Michael Fromberger but has been written from scratch with
  1446. * additional optimizations in place.
  1447. *
  1448. * The library is free for all purposes without any express
  1449. * guarantee it works.
  1450. *
  1451. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1452. */
  1453. #include <ltc_tommath.h>
  1454. /* returns the number of bits in an int */
  1455. int
  1456. mp_count_bits (mp_int * a)
  1457. {
  1458. int r;
  1459. mp_digit q;
  1460. /* shortcut */
  1461. if (a->used == 0) {
  1462. return 0;
  1463. }
  1464. /* get number of digits and add that */
  1465. r = (a->used - 1) * DIGIT_BIT;
  1466. /* take the last digit and count the bits in it */
  1467. q = a->dp[a->used - 1];
  1468. while (q > ((mp_digit) 0)) {
  1469. ++r;
  1470. q >>= ((mp_digit) 1);
  1471. }
  1472. return r;
  1473. }
  1474. /* End: bn_mp_count_bits.c */
  1475. /* Start: bn_mp_div.c */
  1476. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1477. *
  1478. * LibTomMath is a library that provides multiple-precision
  1479. * integer arithmetic as well as number theoretic functionality.
  1480. *
  1481. * The library was designed directly after the MPI library by
  1482. * Michael Fromberger but has been written from scratch with
  1483. * additional optimizations in place.
  1484. *
  1485. * The library is free for all purposes without any express
  1486. * guarantee it works.
  1487. *
  1488. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1489. */
  1490. #include <ltc_tommath.h>
  1491. /* integer signed division.
  1492. * c*b + d == a [e.g. a/b, c=quotient, d=remainder]
  1493. * HAC pp.598 Algorithm 14.20
  1494. *
  1495. * Note that the description in HAC is horribly
  1496. * incomplete. For example, it doesn't consider
  1497. * the case where digits are removed from 'x' in
  1498. * the inner loop. It also doesn't consider the
  1499. * case that y has fewer than three digits, etc..
  1500. *
  1501. * The overall algorithm is as described as
  1502. * 14.20 from HAC but fixed to treat these cases.
  1503. */
  1504. int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
  1505. {
  1506. mp_int q, x, y, t1, t2;
  1507. int res, n, t, i, norm, neg;
  1508. /* is divisor zero ? */
  1509. if (mp_iszero (b) == 1) {
  1510. return MP_VAL;
  1511. }
  1512. /* if a < b then q=0, r = a */
  1513. if (mp_cmp_mag (a, b) == MP_LT) {
  1514. if (d != NULL) {
  1515. res = mp_copy (a, d);
  1516. } else {
  1517. res = MP_OKAY;
  1518. }
  1519. if (c != NULL) {
  1520. mp_zero (c);
  1521. }
  1522. return res;
  1523. }
  1524. if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) {
  1525. return res;
  1526. }
  1527. q.used = a->used + 2;
  1528. if ((res = mp_init (&t1)) != MP_OKAY) {
  1529. goto __Q;
  1530. }
  1531. if ((res = mp_init (&t2)) != MP_OKAY) {
  1532. goto __T1;
  1533. }
  1534. if ((res = mp_init_copy (&x, a)) != MP_OKAY) {
  1535. goto __T2;
  1536. }
  1537. if ((res = mp_init_copy (&y, b)) != MP_OKAY) {
  1538. goto __X;
  1539. }
  1540. /* fix the sign */
  1541. neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
  1542. x.sign = y.sign = MP_ZPOS;
  1543. /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
  1544. norm = mp_count_bits(&y) % DIGIT_BIT;
  1545. if (norm < (int)(DIGIT_BIT-1)) {
  1546. norm = (DIGIT_BIT-1) - norm;
  1547. if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) {
  1548. goto __Y;
  1549. }
  1550. if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) {
  1551. goto __Y;
  1552. }
  1553. } else {
  1554. norm = 0;
  1555. }
  1556. /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
  1557. n = x.used - 1;
  1558. t = y.used - 1;
  1559. /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
  1560. if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
  1561. goto __Y;
  1562. }
  1563. while (mp_cmp (&x, &y) != MP_LT) {
  1564. ++(q.dp[n - t]);
  1565. if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) {
  1566. goto __Y;
  1567. }
  1568. }
  1569. /* reset y by shifting it back down */
  1570. mp_rshd (&y, n - t);
  1571. /* step 3. for i from n down to (t + 1) */
  1572. for (i = n; i >= (t + 1); i--) {
  1573. if (i > x.used) {
  1574. continue;
  1575. }
  1576. /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
  1577. * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
  1578. if (x.dp[i] == y.dp[t]) {
  1579. q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1);
  1580. } else {
  1581. mp_word tmp;
  1582. tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT);
  1583. tmp |= ((mp_word) x.dp[i - 1]);
  1584. tmp /= ((mp_word) y.dp[t]);
  1585. if (tmp > (mp_word) MP_MASK)
  1586. tmp = MP_MASK;
  1587. q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK));
  1588. }
  1589. /* while (q{i-t-1} * (yt * b + y{t-1})) >
  1590. xi * b**2 + xi-1 * b + xi-2
  1591. do q{i-t-1} -= 1;
  1592. */
  1593. q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK;
  1594. do {
  1595. q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK;
  1596. /* find left hand */
  1597. mp_zero (&t1);
  1598. t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
  1599. t1.dp[1] = y.dp[t];
  1600. t1.used = 2;
  1601. if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) {
  1602. goto __Y;
  1603. }
  1604. /* find right hand */
  1605. t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
  1606. t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
  1607. t2.dp[2] = x.dp[i];
  1608. t2.used = 3;
  1609. } while (mp_cmp_mag(&t1, &t2) == MP_GT);
  1610. /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
  1611. if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) {
  1612. goto __Y;
  1613. }
  1614. if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
  1615. goto __Y;
  1616. }
  1617. if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) {
  1618. goto __Y;
  1619. }
  1620. /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
  1621. if (x.sign == MP_NEG) {
  1622. if ((res = mp_copy (&y, &t1)) != MP_OKAY) {
  1623. goto __Y;
  1624. }
  1625. if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
  1626. goto __Y;
  1627. }
  1628. if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) {
  1629. goto __Y;
  1630. }
  1631. q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK;
  1632. }
  1633. }
  1634. /* now q is the quotient and x is the remainder
  1635. * [which we have to normalize]
  1636. */
  1637. /* get sign before writing to c */
  1638. x.sign = a->sign;
  1639. if (c != NULL) {
  1640. mp_clamp (&q);
  1641. mp_exch (&q, c);
  1642. c->sign = neg;
  1643. }
  1644. if (d != NULL) {
  1645. mp_div_2d (&x, norm, &x, NULL);
  1646. mp_exch (&x, d);
  1647. }
  1648. res = MP_OKAY;
  1649. __Y:mp_clear (&y);
  1650. __X:mp_clear (&x);
  1651. __T2:mp_clear (&t2);
  1652. __T1:mp_clear (&t1);
  1653. __Q:mp_clear (&q);
  1654. return res;
  1655. }
  1656. /* End: bn_mp_div.c */
  1657. /* Start: bn_mp_div_2.c */
  1658. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1659. *
  1660. * LibTomMath is a library that provides multiple-precision
  1661. * integer arithmetic as well as number theoretic functionality.
  1662. *
  1663. * The library was designed directly after the MPI library by
  1664. * Michael Fromberger but has been written from scratch with
  1665. * additional optimizations in place.
  1666. *
  1667. * The library is free for all purposes without any express
  1668. * guarantee it works.
  1669. *
  1670. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1671. */
  1672. #include <ltc_tommath.h>
  1673. /* b = a/2 */
  1674. int mp_div_2(mp_int * a, mp_int * b)
  1675. {
  1676. int x, res, oldused;
  1677. /* copy */
  1678. if (b->alloc < a->used) {
  1679. if ((res = mp_grow (b, a->used)) != MP_OKAY) {
  1680. return res;
  1681. }
  1682. }
  1683. oldused = b->used;
  1684. b->used = a->used;
  1685. {
  1686. register mp_digit r, rr, *tmpa, *tmpb;
  1687. /* source alias */
  1688. tmpa = a->dp + b->used - 1;
  1689. /* dest alias */
  1690. tmpb = b->dp + b->used - 1;
  1691. /* carry */
  1692. r = 0;
  1693. for (x = b->used - 1; x >= 0; x--) {
  1694. /* get the carry for the next iteration */
  1695. rr = *tmpa & 1;
  1696. /* shift the current digit, add in carry and store */
  1697. *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
  1698. /* forward carry to next iteration */
  1699. r = rr;
  1700. }
  1701. /* zero excess digits */
  1702. tmpb = b->dp + b->used;
  1703. for (x = b->used; x < oldused; x++) {
  1704. *tmpb++ = 0;
  1705. }
  1706. }
  1707. b->sign = a->sign;
  1708. mp_clamp (b);
  1709. return MP_OKAY;
  1710. }
  1711. /* End: bn_mp_div_2.c */
  1712. /* Start: bn_mp_div_2d.c */
  1713. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1714. *
  1715. * LibTomMath is a library that provides multiple-precision
  1716. * integer arithmetic as well as number theoretic functionality.
  1717. *
  1718. * The library was designed directly after the MPI library by
  1719. * Michael Fromberger but has been written from scratch with
  1720. * additional optimizations in place.
  1721. *
  1722. * The library is free for all purposes without any express
  1723. * guarantee it works.
  1724. *
  1725. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1726. */
  1727. #include <ltc_tommath.h>
  1728. /* shift right by a certain bit count (store quotient in c, optional remainder in d) */
  1729. int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
  1730. {
  1731. mp_digit D, r, rr;
  1732. int x, res;
  1733. mp_int t;
  1734. /* if the shift count is <= 0 then we do no work */
  1735. if (b <= 0) {
  1736. res = mp_copy (a, c);
  1737. if (d != NULL) {
  1738. mp_zero (d);
  1739. }
  1740. return res;
  1741. }
  1742. if ((res = mp_init (&t)) != MP_OKAY) {
  1743. return res;
  1744. }
  1745. /* get the remainder */
  1746. if (d != NULL) {
  1747. if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
  1748. mp_clear (&t);
  1749. return res;
  1750. }
  1751. }
  1752. /* copy */
  1753. if ((res = mp_copy (a, c)) != MP_OKAY) {
  1754. mp_clear (&t);
  1755. return res;
  1756. }
  1757. /* shift by as many digits in the bit count */
  1758. if (b >= (int)DIGIT_BIT) {
  1759. mp_rshd (c, b / DIGIT_BIT);
  1760. }
  1761. /* shift any bit count < DIGIT_BIT */
  1762. D = (mp_digit) (b % DIGIT_BIT);
  1763. if (D != 0) {
  1764. register mp_digit *tmpc, mask, shift;
  1765. /* mask */
  1766. mask = (((mp_digit)1) << D) - 1;
  1767. /* shift for lsb */
  1768. shift = DIGIT_BIT - D;
  1769. /* alias */
  1770. tmpc = c->dp + (c->used - 1);
  1771. /* carry */
  1772. r = 0;
  1773. for (x = c->used - 1; x >= 0; x--) {
  1774. /* get the lower bits of this word in a temp */
  1775. rr = *tmpc & mask;
  1776. /* shift the current word and mix in the carry bits from the previous word */
  1777. *tmpc = (*tmpc >> D) | (r << shift);
  1778. --tmpc;
  1779. /* set the carry to the carry bits of the current word found above */
  1780. r = rr;
  1781. }
  1782. }
  1783. mp_clamp (c);
  1784. if (d != NULL) {
  1785. mp_exch (&t, d);
  1786. }
  1787. mp_clear (&t);
  1788. return MP_OKAY;
  1789. }
  1790. /* End: bn_mp_div_2d.c */
  1791. /* Start: bn_mp_div_3.c */
  1792. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1793. *
  1794. * LibTomMath is a library that provides multiple-precision
  1795. * integer arithmetic as well as number theoretic functionality.
  1796. *
  1797. * The library was designed directly after the MPI library by
  1798. * Michael Fromberger but has been written from scratch with
  1799. * additional optimizations in place.
  1800. *
  1801. * The library is free for all purposes without any express
  1802. * guarantee it works.
  1803. *
  1804. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1805. */
  1806. #include <ltc_tommath.h>
  1807. /* divide by three (based on routine from MPI and the GMP manual) */
  1808. int
  1809. mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
  1810. {
  1811. mp_int q;
  1812. mp_word w, t;
  1813. mp_digit b;
  1814. int res, ix;
  1815. /* b = 2**DIGIT_BIT / 3 */
  1816. b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
  1817. if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
  1818. return res;
  1819. }
  1820. q.used = a->used;
  1821. q.sign = a->sign;
  1822. w = 0;
  1823. for (ix = a->used - 1; ix >= 0; ix--) {
  1824. w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
  1825. if (w >= 3) {
  1826. /* multiply w by [1/3] */
  1827. t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
  1828. /* now subtract 3 * [w/3] from w, to get the remainder */
  1829. w -= t+t+t;
  1830. /* fixup the remainder as required since
  1831. * the optimization is not exact.
  1832. */
  1833. while (w >= 3) {
  1834. t += 1;
  1835. w -= 3;
  1836. }
  1837. } else {
  1838. t = 0;
  1839. }
  1840. q.dp[ix] = (mp_digit)t;
  1841. }
  1842. /* [optional] store the remainder */
  1843. if (d != NULL) {
  1844. *d = (mp_digit)w;
  1845. }
  1846. /* [optional] store the quotient */
  1847. if (c != NULL) {
  1848. mp_clamp(&q);
  1849. mp_exch(&q, c);
  1850. }
  1851. mp_clear(&q);
  1852. return res;
  1853. }
  1854. /* End: bn_mp_div_3.c */
  1855. /* Start: bn_mp_div_d.c */
  1856. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1857. *
  1858. * LibTomMath is a library that provides multiple-precision
  1859. * integer arithmetic as well as number theoretic functionality.
  1860. *
  1861. * The library was designed directly after the MPI library by
  1862. * Michael Fromberger but has been written from scratch with
  1863. * additional optimizations in place.
  1864. *
  1865. * The library is free for all purposes without any express
  1866. * guarantee it works.
  1867. *
  1868. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1869. */
  1870. #include <ltc_tommath.h>
  1871. static int s_is_power_of_two(mp_digit b, int *p)
  1872. {
  1873. int x;
  1874. for (x = 1; x < DIGIT_BIT; x++) {
  1875. if (b == (((mp_digit)1)<<x)) {
  1876. *p = x;
  1877. return 1;
  1878. }
  1879. }
  1880. return 0;
  1881. }
  1882. /* single digit division (based on routine from MPI) */
  1883. int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
  1884. {
  1885. mp_int q;
  1886. mp_word w;
  1887. mp_digit t;
  1888. int res, ix;
  1889. /* cannot divide by zero */
  1890. if (b == 0) {
  1891. return MP_VAL;
  1892. }
  1893. /* quick outs */
  1894. if (b == 1 || mp_iszero(a) == 1) {
  1895. if (d != NULL) {
  1896. *d = 0;
  1897. }
  1898. if (c != NULL) {
  1899. return mp_copy(a, c);
  1900. }
  1901. return MP_OKAY;
  1902. }
  1903. /* power of two ? */
  1904. if (s_is_power_of_two(b, &ix) == 1) {
  1905. if (d != NULL) {
  1906. *d = a->dp[0] & ((1<<ix) - 1);
  1907. }
  1908. if (c != NULL) {
  1909. return mp_div_2d(a, ix, c, NULL);
  1910. }
  1911. return MP_OKAY;
  1912. }
  1913. /* three? */
  1914. if (b == 3) {
  1915. return mp_div_3(a, c, d);
  1916. }
  1917. /* no easy answer [c'est la vie]. Just division */
  1918. if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
  1919. return res;
  1920. }
  1921. q.used = a->used;
  1922. q.sign = a->sign;
  1923. w = 0;
  1924. for (ix = a->used - 1; ix >= 0; ix--) {
  1925. w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
  1926. if (w >= b) {
  1927. t = (mp_digit)(w / b);
  1928. w -= ((mp_word)t) * ((mp_word)b);
  1929. } else {
  1930. t = 0;
  1931. }
  1932. q.dp[ix] = (mp_digit)t;
  1933. }
  1934. if (d != NULL) {
  1935. *d = (mp_digit)w;
  1936. }
  1937. if (c != NULL) {
  1938. mp_clamp(&q);
  1939. mp_exch(&q, c);
  1940. }
  1941. mp_clear(&q);
  1942. return res;
  1943. }
  1944. /* End: bn_mp_div_d.c */
  1945. /* Start: bn_mp_dr_is_modulus.c */
  1946. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1947. *
  1948. * LibTomMath is a library that provides multiple-precision
  1949. * integer arithmetic as well as number theoretic functionality.
  1950. *
  1951. * The library was designed directly after the MPI library by
  1952. * Michael Fromberger but has been written from scratch with
  1953. * additional optimizations in place.
  1954. *
  1955. * The library is free for all purposes without any express
  1956. * guarantee it works.
  1957. *
  1958. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1959. */
  1960. #include <ltc_tommath.h>
  1961. /* determines if a number is a valid DR modulus */
  1962. int mp_dr_is_modulus(mp_int *a)
  1963. {
  1964. int ix;
  1965. /* must be at least two digits */
  1966. if (a->used < 2) {
  1967. return 0;
  1968. }
  1969. /* must be of the form b**k - a [a <= b] so all
  1970. * but the first digit must be equal to -1 (mod b).
  1971. */
  1972. for (ix = 1; ix < a->used; ix++) {
  1973. if (a->dp[ix] != MP_MASK) {
  1974. return 0;
  1975. }
  1976. }
  1977. return 1;
  1978. }
  1979. /* End: bn_mp_dr_is_modulus.c */
  1980. /* Start: bn_mp_dr_reduce.c */
  1981. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  1982. *
  1983. * LibTomMath is a library that provides multiple-precision
  1984. * integer arithmetic as well as number theoretic functionality.
  1985. *
  1986. * The library was designed directly after the MPI library by
  1987. * Michael Fromberger but has been written from scratch with
  1988. * additional optimizations in place.
  1989. *
  1990. * The library is free for all purposes without any express
  1991. * guarantee it works.
  1992. *
  1993. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  1994. */
  1995. #include <ltc_tommath.h>
  1996. /* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
  1997. *
  1998. * Based on algorithm from the paper
  1999. *
  2000. * "Generating Efficient Primes for Discrete Log Cryptosystems"
  2001. * Chae Hoon Lim, Pil Loong Lee,
  2002. * POSTECH Information Research Laboratories
  2003. *
  2004. * The modulus must be of a special format [see manual]
  2005. *
  2006. * Has been modified to use algorithm 7.10 from the LTM book instead
  2007. *
  2008. * Input x must be in the range 0 <= x <= (n-1)**2
  2009. */
  2010. int
  2011. mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
  2012. {
  2013. int err, i, m;
  2014. mp_word r;
  2015. mp_digit mu, *tmpx1, *tmpx2;
  2016. /* m = digits in modulus */
  2017. m = n->used;
  2018. /* ensure that "x" has at least 2m digits */
  2019. if (x->alloc < m + m) {
  2020. if ((err = mp_grow (x, m + m)) != MP_OKAY) {
  2021. return err;
  2022. }
  2023. }
  2024. /* top of loop, this is where the code resumes if
  2025. * another reduction pass is required.
  2026. */
  2027. top:
  2028. /* aliases for digits */
  2029. /* alias for lower half of x */
  2030. tmpx1 = x->dp;
  2031. /* alias for upper half of x, or x/B**m */
  2032. tmpx2 = x->dp + m;
  2033. /* set carry to zero */
  2034. mu = 0;
  2035. /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
  2036. for (i = 0; i < m; i++) {
  2037. r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;
  2038. *tmpx1++ = (mp_digit)(r & MP_MASK);
  2039. mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
  2040. }
  2041. /* set final carry */
  2042. *tmpx1++ = mu;
  2043. /* zero words above m */
  2044. for (i = m + 1; i < x->used; i++) {
  2045. *tmpx1++ = 0;
  2046. }
  2047. /* clamp, sub and return */
  2048. mp_clamp (x);
  2049. /* if x >= n then subtract and reduce again
  2050. * Each successive "recursion" makes the input smaller and smaller.
  2051. */
  2052. if (mp_cmp_mag (x, n) != MP_LT) {
  2053. s_mp_sub(x, n, x);
  2054. goto top;
  2055. }
  2056. return MP_OKAY;
  2057. }
  2058. /* End: bn_mp_dr_reduce.c */
  2059. /* Start: bn_mp_dr_setup.c */
  2060. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2061. *
  2062. * LibTomMath is a library that provides multiple-precision
  2063. * integer arithmetic as well as number theoretic functionality.
  2064. *
  2065. * The library was designed directly after the MPI library by
  2066. * Michael Fromberger but has been written from scratch with
  2067. * additional optimizations in place.
  2068. *
  2069. * The library is free for all purposes without any express
  2070. * guarantee it works.
  2071. *
  2072. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2073. */
  2074. #include <ltc_tommath.h>
  2075. /* determines the setup value */
  2076. void mp_dr_setup(mp_int *a, mp_digit *d)
  2077. {
  2078. /* the casts are required if DIGIT_BIT is one less than
  2079. * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
  2080. */
  2081. *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) -
  2082. ((mp_word)a->dp[0]));
  2083. }
  2084. /* End: bn_mp_dr_setup.c */
  2085. /* Start: bn_mp_exch.c */
  2086. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2087. *
  2088. * LibTomMath is a library that provides multiple-precision
  2089. * integer arithmetic as well as number theoretic functionality.
  2090. *
  2091. * The library was designed directly after the MPI library by
  2092. * Michael Fromberger but has been written from scratch with
  2093. * additional optimizations in place.
  2094. *
  2095. * The library is free for all purposes without any express
  2096. * guarantee it works.
  2097. *
  2098. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2099. */
  2100. #include <ltc_tommath.h>
  2101. /* swap the elements of two integers, for cases where you can't simply swap the
  2102. * mp_int pointers around
  2103. */
  2104. void
  2105. mp_exch (mp_int * a, mp_int * b)
  2106. {
  2107. mp_int t;
  2108. t = *a;
  2109. *a = *b;
  2110. *b = t;
  2111. }
  2112. /* End: bn_mp_exch.c */
  2113. /* Start: bn_mp_expt_d.c */
  2114. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2115. *
  2116. * LibTomMath is a library that provides multiple-precision
  2117. * integer arithmetic as well as number theoretic functionality.
  2118. *
  2119. * The library was designed directly after the MPI library by
  2120. * Michael Fromberger but has been written from scratch with
  2121. * additional optimizations in place.
  2122. *
  2123. * The library is free for all purposes without any express
  2124. * guarantee it works.
  2125. *
  2126. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2127. */
  2128. #include <ltc_tommath.h>
  2129. /* calculate c = a**b using a square-multiply algorithm */
  2130. int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
  2131. {
  2132. int res, x;
  2133. mp_int g;
  2134. if ((res = mp_init_copy (&g, a)) != MP_OKAY) {
  2135. return res;
  2136. }
  2137. /* set initial result */
  2138. mp_set (c, 1);
  2139. for (x = 0; x < (int) DIGIT_BIT; x++) {
  2140. /* square */
  2141. if ((res = mp_sqr (c, c)) != MP_OKAY) {
  2142. mp_clear (&g);
  2143. return res;
  2144. }
  2145. /* if the bit is set multiply */
  2146. if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) {
  2147. if ((res = mp_mul (c, &g, c)) != MP_OKAY) {
  2148. mp_clear (&g);
  2149. return res;
  2150. }
  2151. }
  2152. /* shift to next bit */
  2153. b <<= 1;
  2154. }
  2155. mp_clear (&g);
  2156. return MP_OKAY;
  2157. }
  2158. /* End: bn_mp_expt_d.c */
  2159. /* Start: bn_mp_exptmod.c */
  2160. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2161. *
  2162. * LibTomMath is a library that provides multiple-precision
  2163. * integer arithmetic as well as number theoretic functionality.
  2164. *
  2165. * The library was designed directly after the MPI library by
  2166. * Michael Fromberger but has been written from scratch with
  2167. * additional optimizations in place.
  2168. *
  2169. * The library is free for all purposes without any express
  2170. * guarantee it works.
  2171. *
  2172. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2173. */
  2174. #include <ltc_tommath.h>
  2175. /* this is a shell function that calls either the normal or Montgomery
  2176. * exptmod functions. Originally the call to the montgomery code was
  2177. * embedded in the normal function but that wasted alot of stack space
  2178. * for nothing (since 99% of the time the Montgomery code would be called)
  2179. */
  2180. int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
  2181. {
  2182. int dr;
  2183. /* modulus P must be positive */
  2184. if (P->sign == MP_NEG) {
  2185. return MP_VAL;
  2186. }
  2187. /* if exponent X is negative we have to recurse */
  2188. if (X->sign == MP_NEG) {
  2189. mp_int tmpG, tmpX;
  2190. int err;
  2191. /* first compute 1/G mod P */
  2192. if ((err = mp_init(&tmpG)) != MP_OKAY) {
  2193. return err;
  2194. }
  2195. if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
  2196. mp_clear(&tmpG);
  2197. return err;
  2198. }
  2199. /* now get |X| */
  2200. if ((err = mp_init(&tmpX)) != MP_OKAY) {
  2201. mp_clear(&tmpG);
  2202. return err;
  2203. }
  2204. if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
  2205. mp_clear_multi(&tmpG, &tmpX, NULL);
  2206. return err;
  2207. }
  2208. /* and now compute (1/G)**|X| instead of G**X [X < 0] */
  2209. err = mp_exptmod(&tmpG, &tmpX, P, Y);
  2210. mp_clear_multi(&tmpG, &tmpX, NULL);
  2211. return err;
  2212. }
  2213. /* is it a DR modulus? */
  2214. dr = mp_dr_is_modulus(P);
  2215. /* if not, is it a uDR modulus? */
  2216. if (dr == 0) {
  2217. dr = mp_reduce_is_2k(P) << 1;
  2218. }
  2219. /* if the modulus is odd or dr != 0 use the fast method */
  2220. if (mp_isodd (P) == 1 || dr != 0) {
  2221. return mp_exptmod_fast (G, X, P, Y, dr);
  2222. } else {
  2223. /* otherwise use the generic Barrett reduction technique */
  2224. return s_mp_exptmod (G, X, P, Y);
  2225. }
  2226. }
  2227. /* End: bn_mp_exptmod.c */
  2228. /* Start: bn_mp_exptmod_fast.c */
  2229. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2230. *
  2231. * LibTomMath is a library that provides multiple-precision
  2232. * integer arithmetic as well as number theoretic functionality.
  2233. *
  2234. * The library was designed directly after the MPI library by
  2235. * Michael Fromberger but has been written from scratch with
  2236. * additional optimizations in place.
  2237. *
  2238. * The library is free for all purposes without any express
  2239. * guarantee it works.
  2240. *
  2241. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2242. */
  2243. #include <ltc_tommath.h>
  2244. /* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
  2245. *
  2246. * Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
  2247. * The value of k changes based on the size of the exponent.
  2248. *
  2249. * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
  2250. */
  2251. #ifdef MP_LOW_MEM
  2252. #define TAB_SIZE 32
  2253. #else
  2254. #define TAB_SIZE 256
  2255. #endif
  2256. int
  2257. mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
  2258. {
  2259. mp_int M[TAB_SIZE], res;
  2260. mp_digit buf, mp;
  2261. int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
  2262. /* use a pointer to the reduction algorithm. This allows us to use
  2263. * one of many reduction algorithms without modding the guts of
  2264. * the code with if statements everywhere.
  2265. */
  2266. int (*redux)(mp_int*,mp_int*,mp_digit);
  2267. /* find window size */
  2268. x = mp_count_bits (X);
  2269. if (x <= 7) {
  2270. winsize = 2;
  2271. } else if (x <= 36) {
  2272. winsize = 3;
  2273. } else if (x <= 140) {
  2274. winsize = 4;
  2275. } else if (x <= 450) {
  2276. winsize = 5;
  2277. } else if (x <= 1303) {
  2278. winsize = 6;
  2279. } else if (x <= 3529) {
  2280. winsize = 7;
  2281. } else {
  2282. winsize = 8;
  2283. }
  2284. #ifdef MP_LOW_MEM
  2285. if (winsize > 5) {
  2286. winsize = 5;
  2287. }
  2288. #endif
  2289. /* init M array */
  2290. /* init first cell */
  2291. if ((err = mp_init(&M[1])) != MP_OKAY) {
  2292. return err;
  2293. }
  2294. /* now init the second half of the array */
  2295. for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
  2296. if ((err = mp_init(&M[x])) != MP_OKAY) {
  2297. for (y = 1<<(winsize-1); y < x; y++) {
  2298. mp_clear (&M[y]);
  2299. }
  2300. mp_clear(&M[1]);
  2301. return err;
  2302. }
  2303. }
  2304. /* determine and setup reduction code */
  2305. if (redmode == 0) {
  2306. /* now setup montgomery */
  2307. if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
  2308. goto __M;
  2309. }
  2310. /* automatically pick the comba one if available (saves quite a few calls/ifs) */
  2311. if (((P->used * 2 + 1) < MP_WARRAY) &&
  2312. P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
  2313. redux = fast_mp_montgomery_reduce;
  2314. } else {
  2315. /* use slower baseline Montgomery method */
  2316. redux = mp_montgomery_reduce;
  2317. }
  2318. } else if (redmode == 1) {
  2319. /* setup DR reduction for moduli of the form B**k - b */
  2320. mp_dr_setup(P, &mp);
  2321. redux = mp_dr_reduce;
  2322. } else {
  2323. /* setup DR reduction for moduli of the form 2**k - b */
  2324. if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
  2325. goto __M;
  2326. }
  2327. redux = mp_reduce_2k;
  2328. }
  2329. /* setup result */
  2330. if ((err = mp_init (&res)) != MP_OKAY) {
  2331. goto __M;
  2332. }
  2333. /* create M table
  2334. *
  2335. * The M table contains powers of the input base, e.g. M[x] = G^x mod P
  2336. *
  2337. * The first half of the table is not computed though accept for M[0] and M[1]
  2338. */
  2339. if (redmode == 0) {
  2340. /* now we need R mod m */
  2341. if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
  2342. goto __RES;
  2343. }
  2344. /* now set M[1] to G * R mod m */
  2345. if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
  2346. goto __RES;
  2347. }
  2348. } else {
  2349. mp_set(&res, 1);
  2350. if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
  2351. goto __RES;
  2352. }
  2353. }
  2354. /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
  2355. if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
  2356. goto __RES;
  2357. }
  2358. for (x = 0; x < (winsize - 1); x++) {
  2359. if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
  2360. goto __RES;
  2361. }
  2362. if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {
  2363. goto __RES;
  2364. }
  2365. }
  2366. /* create upper table */
  2367. for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
  2368. if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
  2369. goto __RES;
  2370. }
  2371. if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
  2372. goto __RES;
  2373. }
  2374. }
  2375. /* set initial mode and bit cnt */
  2376. mode = 0;
  2377. bitcnt = 1;
  2378. buf = 0;
  2379. digidx = X->used - 1;
  2380. bitcpy = 0;
  2381. bitbuf = 0;
  2382. for (;;) {
  2383. /* grab next digit as required */
  2384. if (--bitcnt == 0) {
  2385. /* if digidx == -1 we are out of digits so break */
  2386. if (digidx == -1) {
  2387. break;
  2388. }
  2389. /* read next digit and reset bitcnt */
  2390. buf = X->dp[digidx--];
  2391. bitcnt = (int)DIGIT_BIT;
  2392. }
  2393. /* grab the next msb from the exponent */
  2394. y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
  2395. buf <<= (mp_digit)1;
  2396. /* if the bit is zero and mode == 0 then we ignore it
  2397. * These represent the leading zero bits before the first 1 bit
  2398. * in the exponent. Technically this opt is not required but it
  2399. * does lower the # of trivial squaring/reductions used
  2400. */
  2401. if (mode == 0 && y == 0) {
  2402. continue;
  2403. }
  2404. /* if the bit is zero and mode == 1 then we square */
  2405. if (mode == 1 && y == 0) {
  2406. if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
  2407. goto __RES;
  2408. }
  2409. if ((err = redux (&res, P, mp)) != MP_OKAY) {
  2410. goto __RES;
  2411. }
  2412. continue;
  2413. }
  2414. /* else we add it to the window */
  2415. bitbuf |= (y << (winsize - ++bitcpy));
  2416. mode = 2;
  2417. if (bitcpy == winsize) {
  2418. /* ok window is filled so square as required and multiply */
  2419. /* square first */
  2420. for (x = 0; x < winsize; x++) {
  2421. if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
  2422. goto __RES;
  2423. }
  2424. if ((err = redux (&res, P, mp)) != MP_OKAY) {
  2425. goto __RES;
  2426. }
  2427. }
  2428. /* then multiply */
  2429. if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
  2430. goto __RES;
  2431. }
  2432. if ((err = redux (&res, P, mp)) != MP_OKAY) {
  2433. goto __RES;
  2434. }
  2435. /* empty window and reset */
  2436. bitcpy = 0;
  2437. bitbuf = 0;
  2438. mode = 1;
  2439. }
  2440. }
  2441. /* if bits remain then square/multiply */
  2442. if (mode == 2 && bitcpy > 0) {
  2443. /* square then multiply if the bit is set */
  2444. for (x = 0; x < bitcpy; x++) {
  2445. if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
  2446. goto __RES;
  2447. }
  2448. if ((err = redux (&res, P, mp)) != MP_OKAY) {
  2449. goto __RES;
  2450. }
  2451. /* get next bit of the window */
  2452. bitbuf <<= 1;
  2453. if ((bitbuf & (1 << winsize)) != 0) {
  2454. /* then multiply */
  2455. if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
  2456. goto __RES;
  2457. }
  2458. if ((err = redux (&res, P, mp)) != MP_OKAY) {
  2459. goto __RES;
  2460. }
  2461. }
  2462. }
  2463. }
  2464. if (redmode == 0) {
  2465. /* fixup result if Montgomery reduction is used
  2466. * recall that any value in a Montgomery system is
  2467. * actually multiplied by R mod n. So we have
  2468. * to reduce one more time to cancel out the factor
  2469. * of R.
  2470. */
  2471. if ((err = mp_montgomery_reduce (&res, P, mp)) != MP_OKAY) {
  2472. goto __RES;
  2473. }
  2474. }
  2475. /* swap res with Y */
  2476. mp_exch (&res, Y);
  2477. err = MP_OKAY;
  2478. __RES:mp_clear (&res);
  2479. __M:
  2480. mp_clear(&M[1]);
  2481. for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
  2482. mp_clear (&M[x]);
  2483. }
  2484. return err;
  2485. }
  2486. /* End: bn_mp_exptmod_fast.c */
  2487. /* Start: bn_mp_exteuclid.c */
  2488. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2489. *
  2490. * LibTomMath is a library that provides multiple-precision
  2491. * integer arithmetic as well as number theoretic functionality.
  2492. *
  2493. * The library was designed directly after the MPI library by
  2494. * Michael Fromberger but has been written from scratch with
  2495. * additional optimizations in place.
  2496. *
  2497. * The library is free for all purposes without any express
  2498. * guarantee it works.
  2499. *
  2500. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2501. */
  2502. #include <ltc_tommath.h>
  2503. /* Extended euclidean algorithm of (a, b) produces
  2504. a*u1 + b*u2 = u3
  2505. */
  2506. int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
  2507. {
  2508. mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
  2509. int err;
  2510. if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
  2511. return err;
  2512. }
  2513. /* initialize, (u1,u2,u3) = (1,0,a) */
  2514. mp_set(&u1, 1);
  2515. if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; }
  2516. /* initialize, (v1,v2,v3) = (0,1,b) */
  2517. mp_set(&v2, 1);
  2518. if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; }
  2519. /* loop while v3 != 0 */
  2520. while (mp_iszero(&v3) == MP_NO) {
  2521. /* q = u3/v3 */
  2522. if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; }
  2523. /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
  2524. if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; }
  2525. if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; }
  2526. if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; }
  2527. if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; }
  2528. if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; }
  2529. if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; }
  2530. /* (u1,u2,u3) = (v1,v2,v3) */
  2531. if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; }
  2532. if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; }
  2533. if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; }
  2534. /* (v1,v2,v3) = (t1,t2,t3) */
  2535. if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; }
  2536. if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; }
  2537. if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; }
  2538. }
  2539. /* copy result out */
  2540. if (U1 != NULL) { mp_exch(U1, &u1); }
  2541. if (U2 != NULL) { mp_exch(U2, &u2); }
  2542. if (U3 != NULL) { mp_exch(U3, &u3); }
  2543. err = MP_OKAY;
  2544. _ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
  2545. return err;
  2546. }
  2547. /* End: bn_mp_exteuclid.c */
  2548. /* Start: bn_mp_fread.c */
  2549. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2550. *
  2551. * LibTomMath is a library that provides multiple-precision
  2552. * integer arithmetic as well as number theoretic functionality.
  2553. *
  2554. * The library was designed directly after the MPI library by
  2555. * Michael Fromberger but has been written from scratch with
  2556. * additional optimizations in place.
  2557. *
  2558. * The library is free for all purposes without any express
  2559. * guarantee it works.
  2560. *
  2561. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2562. */
  2563. #include <ltc_tommath.h>
  2564. /* read a bigint from a file stream in ASCII */
  2565. int mp_fread(mp_int *a, int radix, FILE *stream)
  2566. {
  2567. int err, ch, neg, y;
  2568. /* clear a */
  2569. mp_zero(a);
  2570. /* if first digit is - then set negative */
  2571. ch = fgetc(stream);
  2572. if (ch == '-') {
  2573. neg = MP_NEG;
  2574. ch = fgetc(stream);
  2575. } else {
  2576. neg = MP_ZPOS;
  2577. }
  2578. for (;;) {
  2579. /* find y in the radix map */
  2580. for (y = 0; y < radix; y++) {
  2581. if (mp_s_rmap[y] == ch) {
  2582. break;
  2583. }
  2584. }
  2585. if (y == radix) {
  2586. break;
  2587. }
  2588. /* shift up and add */
  2589. if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) {
  2590. return err;
  2591. }
  2592. if ((err = mp_add_d(a, y, a)) != MP_OKAY) {
  2593. return err;
  2594. }
  2595. ch = fgetc(stream);
  2596. }
  2597. if (mp_cmp_d(a, 0) != MP_EQ) {
  2598. a->sign = neg;
  2599. }
  2600. return MP_OKAY;
  2601. }
  2602. /* End: bn_mp_fread.c */
  2603. /* Start: bn_mp_fwrite.c */
  2604. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2605. *
  2606. * LibTomMath is a library that provides multiple-precision
  2607. * integer arithmetic as well as number theoretic functionality.
  2608. *
  2609. * The library was designed directly after the MPI library by
  2610. * Michael Fromberger but has been written from scratch with
  2611. * additional optimizations in place.
  2612. *
  2613. * The library is free for all purposes without any express
  2614. * guarantee it works.
  2615. *
  2616. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2617. */
  2618. #include <ltc_tommath.h>
  2619. int mp_fwrite(mp_int *a, int radix, FILE *stream)
  2620. {
  2621. char *buf;
  2622. int err, len, x;
  2623. if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
  2624. return err;
  2625. }
  2626. buf = OPT_CAST(char) XMALLOC (len);
  2627. if (buf == NULL) {
  2628. return MP_MEM;
  2629. }
  2630. if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
  2631. XFREE (buf);
  2632. return err;
  2633. }
  2634. for (x = 0; x < len; x++) {
  2635. if (fputc(buf[x], stream) == EOF) {
  2636. XFREE (buf);
  2637. return MP_VAL;
  2638. }
  2639. }
  2640. XFREE (buf);
  2641. return MP_OKAY;
  2642. }
  2643. /* End: bn_mp_fwrite.c */
  2644. /* Start: bn_mp_gcd.c */
  2645. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2646. *
  2647. * LibTomMath is a library that provides multiple-precision
  2648. * integer arithmetic as well as number theoretic functionality.
  2649. *
  2650. * The library was designed directly after the MPI library by
  2651. * Michael Fromberger but has been written from scratch with
  2652. * additional optimizations in place.
  2653. *
  2654. * The library is free for all purposes without any express
  2655. * guarantee it works.
  2656. *
  2657. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2658. */
  2659. #include <ltc_tommath.h>
  2660. /* Greatest Common Divisor using the binary method */
  2661. int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
  2662. {
  2663. mp_int u, v;
  2664. int k, u_lsb, v_lsb, res;
  2665. /* either zero than gcd is the largest */
  2666. if (mp_iszero (a) == 1 && mp_iszero (b) == 0) {
  2667. return mp_abs (b, c);
  2668. }
  2669. if (mp_iszero (a) == 0 && mp_iszero (b) == 1) {
  2670. return mp_abs (a, c);
  2671. }
  2672. /* optimized. At this point if a == 0 then
  2673. * b must equal zero too
  2674. */
  2675. if (mp_iszero (a) == 1) {
  2676. mp_zero(c);
  2677. return MP_OKAY;
  2678. }
  2679. /* get copies of a and b we can modify */
  2680. if ((res = mp_init_copy (&u, a)) != MP_OKAY) {
  2681. return res;
  2682. }
  2683. if ((res = mp_init_copy (&v, b)) != MP_OKAY) {
  2684. goto __U;
  2685. }
  2686. /* must be positive for the remainder of the algorithm */
  2687. u.sign = v.sign = MP_ZPOS;
  2688. /* B1. Find the common power of two for u and v */
  2689. u_lsb = mp_cnt_lsb(&u);
  2690. v_lsb = mp_cnt_lsb(&v);
  2691. k = MIN(u_lsb, v_lsb);
  2692. if (k > 0) {
  2693. /* divide the power of two out */
  2694. if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
  2695. goto __V;
  2696. }
  2697. if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
  2698. goto __V;
  2699. }
  2700. }
  2701. /* divide any remaining factors of two out */
  2702. if (u_lsb != k) {
  2703. if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
  2704. goto __V;
  2705. }
  2706. }
  2707. if (v_lsb != k) {
  2708. if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
  2709. goto __V;
  2710. }
  2711. }
  2712. while (mp_iszero(&v) == 0) {
  2713. /* make sure v is the largest */
  2714. if (mp_cmp_mag(&u, &v) == MP_GT) {
  2715. /* swap u and v to make sure v is >= u */
  2716. mp_exch(&u, &v);
  2717. }
  2718. /* subtract smallest from largest */
  2719. if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
  2720. goto __V;
  2721. }
  2722. /* Divide out all factors of two */
  2723. if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
  2724. goto __V;
  2725. }
  2726. }
  2727. /* multiply by 2**k which we divided out at the beginning */
  2728. if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {
  2729. goto __V;
  2730. }
  2731. c->sign = MP_ZPOS;
  2732. res = MP_OKAY;
  2733. __V:mp_clear (&u);
  2734. __U:mp_clear (&v);
  2735. return res;
  2736. }
  2737. /* End: bn_mp_gcd.c */
  2738. /* Start: bn_mp_get_int.c */
  2739. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2740. *
  2741. * LibTomMath is a library that provides multiple-precision
  2742. * integer arithmetic as well as number theoretic functionality.
  2743. *
  2744. * The library was designed directly after the MPI library by
  2745. * Michael Fromberger but has been written from scratch with
  2746. * additional optimizations in place.
  2747. *
  2748. * The library is free for all purposes without any express
  2749. * guarantee it works.
  2750. *
  2751. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2752. */
  2753. #include <ltc_tommath.h>
  2754. /* get the lower 32-bits of an mp_int */
  2755. unsigned long mp_get_int(mp_int * a)
  2756. {
  2757. int i;
  2758. unsigned long res;
  2759. if (a->used == 0) {
  2760. return 0;
  2761. }
  2762. /* get number of digits of the lsb we have to read */
  2763. i = MIN(a->used,(int)((sizeof(unsigned long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1;
  2764. /* get most significant digit of result */
  2765. res = DIGIT(a,i);
  2766. while (--i >= 0) {
  2767. res = (res << DIGIT_BIT) | DIGIT(a,i);
  2768. }
  2769. /* force result to 32-bits always so it is consistent on non 32-bit platforms */
  2770. return res & 0xFFFFFFFFUL;
  2771. }
  2772. /* End: bn_mp_get_int.c */
  2773. /* Start: bn_mp_grow.c */
  2774. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2775. *
  2776. * LibTomMath is a library that provides multiple-precision
  2777. * integer arithmetic as well as number theoretic functionality.
  2778. *
  2779. * The library was designed directly after the MPI library by
  2780. * Michael Fromberger but has been written from scratch with
  2781. * additional optimizations in place.
  2782. *
  2783. * The library is free for all purposes without any express
  2784. * guarantee it works.
  2785. *
  2786. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2787. */
  2788. #include <ltc_tommath.h>
  2789. /* grow as required */
  2790. int mp_grow (mp_int * a, int size)
  2791. {
  2792. int i;
  2793. mp_digit *tmp;
  2794. /* if the alloc size is smaller alloc more ram */
  2795. if (a->alloc < size) {
  2796. /* ensure there are always at least MP_PREC digits extra on top */
  2797. size += (MP_PREC * 2) - (size % MP_PREC);
  2798. /* reallocate the array a->dp
  2799. *
  2800. * We store the return in a temporary variable
  2801. * in case the operation failed we don't want
  2802. * to overwrite the dp member of a.
  2803. */
  2804. tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size);
  2805. if (tmp == NULL) {
  2806. /* reallocation failed but "a" is still valid [can be freed] */
  2807. return MP_MEM;
  2808. }
  2809. /* reallocation succeeded so set a->dp */
  2810. a->dp = tmp;
  2811. /* zero excess digits */
  2812. i = a->alloc;
  2813. a->alloc = size;
  2814. for (; i < a->alloc; i++) {
  2815. a->dp[i] = 0;
  2816. }
  2817. }
  2818. return MP_OKAY;
  2819. }
  2820. /* End: bn_mp_grow.c */
  2821. /* Start: bn_mp_init.c */
  2822. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2823. *
  2824. * LibTomMath is a library that provides multiple-precision
  2825. * integer arithmetic as well as number theoretic functionality.
  2826. *
  2827. * The library was designed directly after the MPI library by
  2828. * Michael Fromberger but has been written from scratch with
  2829. * additional optimizations in place.
  2830. *
  2831. * The library is free for all purposes without any express
  2832. * guarantee it works.
  2833. *
  2834. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2835. */
  2836. #include <ltc_tommath.h>
  2837. /* init a new mp_int */
  2838. int mp_init (mp_int * a)
  2839. {
  2840. int i;
  2841. /* allocate memory required and clear it */
  2842. a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC);
  2843. if (a->dp == NULL) {
  2844. return MP_MEM;
  2845. }
  2846. /* set the digits to zero */
  2847. for (i = 0; i < MP_PREC; i++) {
  2848. a->dp[i] = 0;
  2849. }
  2850. /* set the used to zero, allocated digits to the default precision
  2851. * and sign to positive */
  2852. a->used = 0;
  2853. a->alloc = MP_PREC;
  2854. a->sign = MP_ZPOS;
  2855. return MP_OKAY;
  2856. }
  2857. /* End: bn_mp_init.c */
  2858. /* Start: bn_mp_init_copy.c */
  2859. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2860. *
  2861. * LibTomMath is a library that provides multiple-precision
  2862. * integer arithmetic as well as number theoretic functionality.
  2863. *
  2864. * The library was designed directly after the MPI library by
  2865. * Michael Fromberger but has been written from scratch with
  2866. * additional optimizations in place.
  2867. *
  2868. * The library is free for all purposes without any express
  2869. * guarantee it works.
  2870. *
  2871. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2872. */
  2873. #include <ltc_tommath.h>
  2874. /* creates "a" then copies b into it */
  2875. int mp_init_copy (mp_int * a, mp_int * b)
  2876. {
  2877. int res;
  2878. if ((res = mp_init (a)) != MP_OKAY) {
  2879. return res;
  2880. }
  2881. return mp_copy (b, a);
  2882. }
  2883. /* End: bn_mp_init_copy.c */
  2884. /* Start: bn_mp_init_multi.c */
  2885. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2886. *
  2887. * LibTomMath is a library that provides multiple-precision
  2888. * integer arithmetic as well as number theoretic functionality.
  2889. *
  2890. * The library was designed directly after the MPI library by
  2891. * Michael Fromberger but has been written from scratch with
  2892. * additional optimizations in place.
  2893. *
  2894. * The library is free for all purposes without any express
  2895. * guarantee it works.
  2896. *
  2897. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2898. */
  2899. #include <ltc_tommath.h>
  2900. #include <stdarg.h>
  2901. int mp_init_multi(mp_int *mp, ...)
  2902. {
  2903. mp_err res = MP_OKAY; /* Assume ok until proven otherwise */
  2904. int n = 0; /* Number of ok inits */
  2905. mp_int* cur_arg = mp;
  2906. va_list args;
  2907. va_start(args, mp); /* init args to next argument from caller */
  2908. while (cur_arg != NULL) {
  2909. if (mp_init(cur_arg) != MP_OKAY) {
  2910. /* Oops - error! Back-track and mp_clear what we already
  2911. succeeded in init-ing, then return error.
  2912. */
  2913. va_list clean_args;
  2914. /* end the current list */
  2915. va_end(args);
  2916. /* now start cleaning up */
  2917. cur_arg = mp;
  2918. va_start(clean_args, mp);
  2919. while (n--) {
  2920. mp_clear(cur_arg);
  2921. cur_arg = va_arg(clean_args, mp_int*);
  2922. }
  2923. va_end(clean_args);
  2924. res = MP_MEM;
  2925. break;
  2926. }
  2927. n++;
  2928. cur_arg = va_arg(args, mp_int*);
  2929. }
  2930. va_end(args);
  2931. return res; /* Assumed ok, if error flagged above. */
  2932. }
  2933. /* End: bn_mp_init_multi.c */
  2934. /* Start: bn_mp_init_set.c */
  2935. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2936. *
  2937. * LibTomMath is a library that provides multiple-precision
  2938. * integer arithmetic as well as number theoretic functionality.
  2939. *
  2940. * The library was designed directly after the MPI library by
  2941. * Michael Fromberger but has been written from scratch with
  2942. * additional optimizations in place.
  2943. *
  2944. * The library is free for all purposes without any express
  2945. * guarantee it works.
  2946. *
  2947. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2948. */
  2949. #include <ltc_tommath.h>
  2950. /* initialize and set a digit */
  2951. int mp_init_set (mp_int * a, mp_digit b)
  2952. {
  2953. int err;
  2954. if ((err = mp_init(a)) != MP_OKAY) {
  2955. return err;
  2956. }
  2957. mp_set(a, b);
  2958. return err;
  2959. }
  2960. /* End: bn_mp_init_set.c */
  2961. /* Start: bn_mp_init_set_int.c */
  2962. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2963. *
  2964. * LibTomMath is a library that provides multiple-precision
  2965. * integer arithmetic as well as number theoretic functionality.
  2966. *
  2967. * The library was designed directly after the MPI library by
  2968. * Michael Fromberger but has been written from scratch with
  2969. * additional optimizations in place.
  2970. *
  2971. * The library is free for all purposes without any express
  2972. * guarantee it works.
  2973. *
  2974. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  2975. */
  2976. #include <ltc_tommath.h>
  2977. /* initialize and set a digit */
  2978. int mp_init_set_int (mp_int * a, unsigned long b)
  2979. {
  2980. int err;
  2981. if ((err = mp_init(a)) != MP_OKAY) {
  2982. return err;
  2983. }
  2984. return mp_set_int(a, b);
  2985. }
  2986. /* End: bn_mp_init_set_int.c */
  2987. /* Start: bn_mp_init_size.c */
  2988. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  2989. *
  2990. * LibTomMath is a library that provides multiple-precision
  2991. * integer arithmetic as well as number theoretic functionality.
  2992. *
  2993. * The library was designed directly after the MPI library by
  2994. * Michael Fromberger but has been written from scratch with
  2995. * additional optimizations in place.
  2996. *
  2997. * The library is free for all purposes without any express
  2998. * guarantee it works.
  2999. *
  3000. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  3001. */
  3002. #include <ltc_tommath.h>
  3003. /* init an mp_init for a given size */
  3004. int mp_init_size (mp_int * a, int size)
  3005. {
  3006. /* pad size so there are always extra digits */
  3007. size += (MP_PREC * 2) - (size % MP_PREC);
  3008. /* alloc mem */
  3009. a->dp = OPT_CAST(mp_digit) XCALLOC (sizeof (mp_digit), size);
  3010. if (a->dp == NULL) {
  3011. return MP_MEM;
  3012. }
  3013. a->used = 0;
  3014. a->alloc = size;
  3015. a->sign = MP_ZPOS;
  3016. return MP_OKAY;
  3017. }
  3018. /* End: bn_mp_init_size.c */
  3019. /* Start: bn_mp_invmod.c */
  3020. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  3021. *
  3022. * LibTomMath is a library that provides multiple-precision
  3023. * integer arithmetic as well as number theoretic functionality.
  3024. *
  3025. * The library was designed directly after the MPI library by
  3026. * Michael Fromberger but has been written from scratch with
  3027. * additional optimizations in place.
  3028. *
  3029. * The library is free for all purposes without any express
  3030. * guarantee it works.
  3031. *
  3032. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  3033. */
  3034. #include <ltc_tommath.h>
  3035. /* hac 14.61, pp608 */
  3036. int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
  3037. {
  3038. mp_int x, y, u, v, A, B, C, D;
  3039. int res;
  3040. /* b cannot be negative */
  3041. if (b->sign == MP_NEG || mp_iszero(b) == 1) {
  3042. return MP_VAL;
  3043. }
  3044. /* if the modulus is odd we can use a faster routine instead */
  3045. if (mp_isodd (b) == 1) {
  3046. return fast_mp_invmod (a, b, c);
  3047. }
  3048. /* init temps */
  3049. if ((res = mp_init_multi(&x, &y, &u, &v,
  3050. &A, &B, &C, &D, NULL)) != MP_OKAY) {
  3051. return res;
  3052. }
  3053. /* x = a, y = b */
  3054. if ((res = mp_copy (a, &x)) != MP_OKAY) {
  3055. goto __ERR;
  3056. }
  3057. if ((res = mp_copy (b, &y)) != MP_OKAY) {
  3058. goto __ERR;
  3059. }
  3060. /* 2. [modified] if x,y are both even then return an error! */
  3061. if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) {
  3062. res = MP_VAL;
  3063. goto __ERR;
  3064. }
  3065. /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
  3066. if ((res = mp_copy (&x, &u)) != MP_OKAY) {
  3067. goto __ERR;
  3068. }
  3069. if ((res = mp_copy (&y, &v)) != MP_OKAY) {
  3070. goto __ERR;
  3071. }
  3072. mp_set (&A, 1);
  3073. mp_set (&D, 1);
  3074. top:
  3075. /* 4. while u is even do */
  3076. while (mp_iseven (&u) == 1) {
  3077. /* 4.1 u = u/2 */
  3078. if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
  3079. goto __ERR;
  3080. }
  3081. /* 4.2 if A or B is odd then */
  3082. if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) {
  3083. /* A = (A+y)/2, B = (B-x)/2 */
  3084. if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
  3085. goto __ERR;
  3086. }
  3087. if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
  3088. goto __ERR;
  3089. }
  3090. }
  3091. /* A = A/2, B = B/2 */
  3092. if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {
  3093. goto __ERR;
  3094. }
  3095. if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
  3096. goto __ERR;
  3097. }
  3098. }
  3099. /* 5. while v is even do */
  3100. while (mp_iseven (&v) == 1) {
  3101. /* 5.1 v = v/2 */
  3102. if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
  3103. goto __ERR;
  3104. }
  3105. /* 5.2 if C or D is odd then */
  3106. if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) {
  3107. /* C = (C+y)/2, D = (D-x)/2 */
  3108. if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
  3109. goto __ERR;
  3110. }
  3111. if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
  3112. goto __ERR;
  3113. }
  3114. }
  3115. /* C = C/2, D = D/2 */
  3116. if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {
  3117. goto __ERR;
  3118. }
  3119. if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
  3120. goto __ERR;
  3121. }
  3122. }
  3123. /* 6. if u >= v then */
  3124. if (mp_cmp (&u, &v) != MP_LT) {
  3125. /* u = u - v, A = A - C, B = B - D */
  3126. if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
  3127. goto __ERR;
  3128. }
  3129. if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {
  3130. goto __ERR;
  3131. }
  3132. if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
  3133. goto __ERR;
  3134. }
  3135. } else {
  3136. /* v - v - u, C = C - A, D = D - B */
  3137. if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
  3138. goto __ERR;
  3139. }
  3140. if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {
  3141. goto __ERR;
  3142. }
  3143. if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
  3144. goto __ERR;
  3145. }
  3146. }
  3147. /* if not zero goto step 4 */
  3148. if (mp_iszero (&u) == 0)
  3149. goto top;
  3150. /* now a = C, b = D, gcd == g*v */
  3151. /* if v != 1 then there is no inverse */
  3152. if (mp_cmp_d (&v, 1) != MP_EQ) {
  3153. res = MP_VAL;
  3154. goto __ERR;
  3155. }
  3156. /* if its too low */
  3157. while (mp_cmp_d(&C, 0) == MP_LT) {
  3158. if ((res = mp_add(&C, b, &C)) != MP_OKAY) {
  3159. goto __ERR;
  3160. }
  3161. }
  3162. /* too big */
  3163. while (mp_cmp_mag(&C, b) != MP_LT) {
  3164. if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {
  3165. goto __ERR;
  3166. }
  3167. }
  3168. /* C is now the inverse */
  3169. mp_exch (&C, c);
  3170. res = MP_OKAY;
  3171. __ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL);
  3172. return res;
  3173. }
  3174. /* End: bn_mp_invmod.c */
  3175. /* Start: bn_mp_is_square.c */
  3176. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  3177. *
  3178. * LibTomMath is a library that provides multiple-precision
  3179. * integer arithmetic as well as number theoretic functionality.
  3180. *
  3181. * The library was designed directly after the MPI library by
  3182. * Michael Fromberger but has been written from scratch with
  3183. * additional optimizations in place.
  3184. *
  3185. * The library is free for all purposes without any express
  3186. * guarantee it works.
  3187. *
  3188. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  3189. */
  3190. #include <ltc_tommath.h>
  3191. /* Check if remainders are possible squares - fast exclude non-squares */
  3192. static const char rem_128[128] = {
  3193. 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
  3194. 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
  3195. 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
  3196. 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
  3197. 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
  3198. 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
  3199. 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
  3200. 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
  3201. };
  3202. static const char rem_105[105] = {
  3203. 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
  3204. 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
  3205. 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
  3206. 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
  3207. 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
  3208. 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
  3209. 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
  3210. };
  3211. /* Store non-zero to ret if arg is square, and zero if not */
  3212. int mp_is_square(mp_int *arg,int *ret)
  3213. {
  3214. int res;
  3215. mp_digit c;
  3216. mp_int t;
  3217. unsigned long r;
  3218. /* Default to Non-square :) */
  3219. *ret = MP_NO;
  3220. if (arg->sign == MP_NEG) {
  3221. return MP_VAL;
  3222. }
  3223. /* digits used? (TSD) */
  3224. if (arg->used == 0) {
  3225. return MP_OKAY;
  3226. }
  3227. /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */
  3228. if (rem_128[127 & DIGIT(arg,0)] == 1) {
  3229. return MP_OKAY;
  3230. }
  3231. /* Next check mod 105 (3*5*7) */
  3232. if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) {
  3233. return res;
  3234. }
  3235. if (rem_105[c] == 1) {
  3236. return MP_OKAY;
  3237. }
  3238. /* product of primes less than 2^31 */
  3239. if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) {
  3240. return res;
  3241. }
  3242. if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) {
  3243. goto ERR;
  3244. }
  3245. r = mp_get_int(&t);
  3246. /* Check for other prime modules, note it's not an ERROR but we must
  3247. * free "t" so the easiest way is to goto ERR. We know that res
  3248. * is already equal to MP_OKAY from the mp_mod call
  3249. */
  3250. if ( (1L<<(r%11)) & 0x5C4L ) goto ERR;
  3251. if ( (1L<<(r%13)) & 0x9E4L ) goto ERR;
  3252. if ( (1L<<(r%17)) & 0x5CE8L ) goto ERR;
  3253. if ( (1L<<(r%19)) & 0x4F50CL ) goto ERR;
  3254. if ( (1L<<(r%23)) & 0x7ACCA0L ) goto ERR;
  3255. if ( (1L<<(r%29)) & 0xC2EDD0CL ) goto ERR;
  3256. if ( (1L<<(r%31)) & 0x6DE2B848L ) goto ERR;
  3257. /* Final check - is sqr(sqrt(arg)) == arg ? */
  3258. if ((res = mp_sqrt(arg,&t)) != MP_OKAY) {
  3259. goto ERR;
  3260. }
  3261. if ((res = mp_sqr(&t,&t)) != MP_OKAY) {
  3262. goto ERR;
  3263. }
  3264. *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO;
  3265. ERR:mp_clear(&t);
  3266. return res;
  3267. }
  3268. /* End: bn_mp_is_square.c */
  3269. /* Start: bn_mp_jacobi.c */
  3270. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  3271. *
  3272. * LibTomMath is a library that provides multiple-precision
  3273. * integer arithmetic as well as number theoretic functionality.
  3274. *
  3275. * The library was designed directly after the MPI library by
  3276. * Michael Fromberger but has been written from scratch with
  3277. * additional optimizations in place.
  3278. *
  3279. * The library is free for all purposes without any express
  3280. * guarantee it works.
  3281. *
  3282. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  3283. */
  3284. #include <ltc_tommath.h>
  3285. /* computes the jacobi c = (a | n) (or Legendre if n is prime)
  3286. * HAC pp. 73 Algorithm 2.149
  3287. */
  3288. int mp_jacobi (mp_int * a, mp_int * p, int *c)
  3289. {
  3290. mp_int a1, p1;
  3291. int k, s, r, res;
  3292. mp_digit residue;
  3293. /* if p <= 0 return MP_VAL */
  3294. if (mp_cmp_d(p, 0) != MP_GT) {
  3295. return MP_VAL;
  3296. }
  3297. /* step 1. if a == 0, return 0 */
  3298. if (mp_iszero (a) == 1) {
  3299. *c = 0;
  3300. return MP_OKAY;
  3301. }
  3302. /* step 2. if a == 1, return 1 */
  3303. if (mp_cmp_d (a, 1) == MP_EQ) {
  3304. *c = 1;
  3305. return MP_OKAY;
  3306. }
  3307. /* default */
  3308. s = 0;
  3309. /* step 3. write a = a1 * 2**k */
  3310. if ((res = mp_init_copy (&a1, a)) != MP_OKAY) {
  3311. return res;
  3312. }
  3313. if ((res = mp_init (&p1)) != MP_OKAY) {
  3314. goto __A1;
  3315. }
  3316. /* divide out larger power of two */
  3317. k = mp_cnt_lsb(&a1);
  3318. if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) {
  3319. goto __P1;
  3320. }
  3321. /* step 4. if e is even set s=1 */
  3322. if ((k & 1) == 0) {
  3323. s = 1;
  3324. } else {
  3325. /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
  3326. residue = p->dp[0] & 7;
  3327. if (residue == 1 || residue == 7) {
  3328. s = 1;
  3329. } else if (residue == 3 || residue == 5) {
  3330. s = -1;
  3331. }
  3332. }
  3333. /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */
  3334. if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) {
  3335. s = -s;
  3336. }
  3337. /* if a1 == 1 we're done */
  3338. if (mp_cmp_d (&a1, 1) == MP_EQ) {
  3339. *c = s;
  3340. } else {
  3341. /* n1 = n mod a1 */
  3342. if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) {
  3343. goto __P1;
  3344. }
  3345. if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) {
  3346. goto __P1;
  3347. }
  3348. *c = s * r;
  3349. }
  3350. /* done */
  3351. res = MP_OKAY;
  3352. __P1:mp_clear (&p1);
  3353. __A1:mp_clear (&a1);
  3354. return res;
  3355. }
  3356. /* End: bn_mp_jacobi.c */
  3357. /* Start: bn_mp_karatsuba_mul.c */
  3358. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  3359. *
  3360. * LibTomMath is a library that provides multiple-precision
  3361. * integer arithmetic as well as number theoretic functionality.
  3362. *
  3363. * The library was designed directly after the MPI library by
  3364. * Michael Fromberger but has been written from scratch with
  3365. * additional optimizations in place.
  3366. *
  3367. * The library is free for all purposes without any express
  3368. * guarantee it works.
  3369. *
  3370. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  3371. */
  3372. #include <ltc_tommath.h>
  3373. /* c = |a| * |b| using Karatsuba Multiplication using
  3374. * three half size multiplications
  3375. *
  3376. * Let B represent the radix [e.g. 2**DIGIT_BIT] and
  3377. * let n represent half of the number of digits in
  3378. * the min(a,b)
  3379. *
  3380. * a = a1 * B**n + a0
  3381. * b = b1 * B**n + b0
  3382. *
  3383. * Then, a * b =>
  3384. a1b1 * B**2n + ((a1 - a0)(b1 - b0) + a0b0 + a1b1) * B + a0b0
  3385. *
  3386. * Note that a1b1 and a0b0 are used twice and only need to be
  3387. * computed once. So in total three half size (half # of
  3388. * digit) multiplications are performed, a0b0, a1b1 and
  3389. * (a1-b1)(a0-b0)
  3390. *
  3391. * Note that a multiplication of half the digits requires
  3392. * 1/4th the number of single precision multiplications so in
  3393. * total after one call 25% of the single precision multiplications
  3394. * are saved. Note also that the call to mp_mul can end up back
  3395. * in this function if the a0, a1, b0, or b1 are above the threshold.
  3396. * This is known as divide-and-conquer and leads to the famous
  3397. * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than
  3398. * the standard O(N**2) that the baseline/comba methods use.
  3399. * Generally though the overhead of this method doesn't pay off
  3400. * until a certain size (N ~ 80) is reached.
  3401. */
  3402. int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
  3403. {
  3404. mp_int x0, x1, y0, y1, t1, x0y0, x1y1;
  3405. int B, err;
  3406. /* default the return code to an error */
  3407. err = MP_MEM;
  3408. /* min # of digits */
  3409. B = MIN (a->used, b->used);
  3410. /* now divide in two */
  3411. B = B >> 1;
  3412. /* init copy all the temps */
  3413. if (mp_init_size (&x0, B) != MP_OKAY)
  3414. goto ERR;
  3415. if (mp_init_size (&x1, a->used - B) != MP_OKAY)
  3416. goto X0;
  3417. if (mp_init_size (&y0, B) != MP_OKAY)
  3418. goto X1;
  3419. if (mp_init_size (&y1, b->used - B) != MP_OKAY)
  3420. goto Y0;
  3421. /* init temps */
  3422. if (mp_init_size (&t1, B * 2) != MP_OKAY)
  3423. goto Y1;
  3424. if (mp_init_size (&x0y0, B * 2) != MP_OKAY)
  3425. goto T1;
  3426. if (mp_init_size (&x1y1, B * 2) != MP_OKAY)
  3427. goto X0Y0;
  3428. /* now shift the digits */
  3429. x0.sign = x1.sign = a->sign;
  3430. y0.sign = y1.sign = b->sign;
  3431. x0.used = y0.used = B;
  3432. x1.used = a->used - B;
  3433. y1.used = b->used - B;
  3434. {
  3435. register int x;
  3436. register mp_digit *tmpa, *tmpb, *tmpx, *tmpy;
  3437. /* we copy the digits directly instead of using higher level functions
  3438. * since we also need to shift the digits
  3439. */
  3440. tmpa = a->dp;
  3441. tmpb = b->dp;
  3442. tmpx = x0.dp;
  3443. tmpy = y0.dp;
  3444. for (x = 0; x < B; x++) {
  3445. *tmpx++ = *tmpa++;
  3446. *tmpy++ = *tmpb++;
  3447. }
  3448. tmpx = x1.dp;
  3449. for (x = B; x < a->used; x++) {
  3450. *tmpx++ = *tmpa++;
  3451. }
  3452. tmpy = y1.dp;
  3453. for (x = B; x < b->used; x++) {
  3454. *tmpy++ = *tmpb++;
  3455. }
  3456. }
  3457. /* only need to clamp the lower words since by definition the
  3458. * upper words x1/y1 must have a known number of digits
  3459. */
  3460. mp_clamp (&x0);
  3461. mp_clamp (&y0);
  3462. /* now calc the products x0y0 and x1y1 */
  3463. /* after this x0 is no longer required, free temp [x0==t2]! */
  3464. if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY)
  3465. goto X1Y1; /* x0y0 = x0*y0 */
  3466. if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY)
  3467. goto X1Y1; /* x1y1 = x1*y1 */
  3468. /* now calc x1-x0 and y1-y0 */
  3469. if (mp_sub (&x1, &x0, &t1) != MP_OKAY)
  3470. goto X1Y1; /* t1 = x1 - x0 */
  3471. if (mp_sub (&y1, &y0, &x0) != MP_OKAY)
  3472. goto X1Y1; /* t2 = y1 - y0 */
  3473. if (mp_mul (&t1, &x0, &t1) != MP_OKAY)
  3474. goto X1Y1; /* t1 = (x1 - x0) * (y1 - y0) */
  3475. /* add x0y0 */
  3476. if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY)
  3477. goto X1Y1; /* t2 = x0y0 + x1y1 */
  3478. if (mp_sub (&x0, &t1, &t1) != MP_OKAY)
  3479. goto X1Y1; /* t1 = x0y0 + x1y1 - (x1-x0)*(y1-y0) */
  3480. /* shift by B */
  3481. if (mp_lshd (&t1, B) != MP_OKAY)
  3482. goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
  3483. if (mp_lshd (&x1y1, B * 2) != MP_OKAY)
  3484. goto X1Y1; /* x1y1 = x1y1 << 2*B */
  3485. if (mp_add (&x0y0, &t1, &t1) != MP_OKAY)
  3486. goto X1Y1; /* t1 = x0y0 + t1 */
  3487. if (mp_add (&t1, &x1y1, c) != MP_OKAY)
  3488. goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */
  3489. /* Algorithm succeeded set the return code to MP_OKAY */
  3490. err = MP_OKAY;
  3491. X1Y1:mp_clear (&x1y1);
  3492. X0Y0:mp_clear (&x0y0);
  3493. T1:mp_clear (&t1);
  3494. Y1:mp_clear (&y1);
  3495. Y0:mp_clear (&y0);
  3496. X1:mp_clear (&x1);
  3497. X0:mp_clear (&x0);
  3498. ERR:
  3499. return err;
  3500. }
  3501. /* End: bn_mp_karatsuba_mul.c */
  3502. /* Start: bn_mp_karatsuba_sqr.c */
  3503. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  3504. *
  3505. * LibTomMath is a library that provides multiple-precision
  3506. * integer arithmetic as well as number theoretic functionality.
  3507. *
  3508. * The library was designed directly after the MPI library by
  3509. * Michael Fromberger but has been written from scratch with
  3510. * additional optimizations in place.
  3511. *
  3512. * The library is free for all purposes without any express
  3513. * guarantee it works.
  3514. *
  3515. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  3516. */
  3517. #include <ltc_tommath.h>
  3518. /* Karatsuba squaring, computes b = a*a using three
  3519. * half size squarings
  3520. *
  3521. * See comments of mp_karatsuba_mul for details. It
  3522. * is essentially the same algorithm but merely
  3523. * tuned to perform recursive squarings.
  3524. */
  3525. int mp_karatsuba_sqr (mp_int * a, mp_int * b)
  3526. {
  3527. mp_int x0, x1, t1, t2, x0x0, x1x1;
  3528. int B, err;
  3529. err = MP_MEM;
  3530. /* min # of digits */
  3531. B = a->used;
  3532. /* now divide in two */
  3533. B = B >> 1;
  3534. /* init copy all the temps */
  3535. if (mp_init_size (&x0, B) != MP_OKAY)
  3536. goto ERR;
  3537. if (mp_init_size (&x1, a->used - B) != MP_OKAY)
  3538. goto X0;
  3539. /* init temps */
  3540. if (mp_init_size (&t1, a->used * 2) != MP_OKAY)
  3541. goto X1;
  3542. if (mp_init_size (&t2, a->used * 2) != MP_OKAY)
  3543. goto T1;
  3544. if (mp_init_size (&x0x0, B * 2) != MP_OKAY)
  3545. goto T2;
  3546. if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY)
  3547. goto X0X0;
  3548. {
  3549. register int x;
  3550. register mp_digit *dst, *src;
  3551. src = a->dp;
  3552. /* now shift the digits */
  3553. dst = x0.dp;
  3554. for (x = 0; x < B; x++) {
  3555. *dst++ = *src++;
  3556. }
  3557. dst = x1.dp;
  3558. for (x = B; x < a->used; x++) {
  3559. *dst++ = *src++;
  3560. }
  3561. }
  3562. x0.used = B;
  3563. x1.used = a->used - B;
  3564. mp_clamp (&x0);
  3565. /* now calc the products x0*x0 and x1*x1 */
  3566. if (mp_sqr (&x0, &x0x0) != MP_OKAY)
  3567. goto X1X1; /* x0x0 = x0*x0 */
  3568. if (mp_sqr (&x1, &x1x1) != MP_OKAY)
  3569. goto X1X1; /* x1x1 = x1*x1 */
  3570. /* now calc (x1-x0)**2 */
  3571. if (mp_sub (&x1, &x0, &t1) != MP_OKAY)
  3572. goto X1X1; /* t1 = x1 - x0 */
  3573. if (mp_sqr (&t1, &t1) != MP_OKAY)
  3574. goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */
  3575. /* add x0y0 */
  3576. if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY)
  3577. goto X1X1; /* t2 = x0x0 + x1x1 */
  3578. if (mp_sub (&t2, &t1, &t1) != MP_OKAY)
  3579. goto X1X1; /* t1 = x0x0 + x1x1 - (x1-x0)*(x1-x0) */
  3580. /* shift by B */
  3581. if (mp_lshd (&t1, B) != MP_OKAY)
  3582. goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
  3583. if (mp_lshd (&x1x1, B * 2) != MP_OKAY)
  3584. goto X1X1; /* x1x1 = x1x1 << 2*B */
  3585. if (mp_add (&x0x0, &t1, &t1) != MP_OKAY)
  3586. goto X1X1; /* t1 = x0x0 + t1 */
  3587. if (mp_add (&t1, &x1x1, b) != MP_OKAY)
  3588. goto X1X1; /* t1 = x0x0 + t1 + x1x1 */
  3589. err = MP_OKAY;
  3590. X1X1:mp_clear (&x1x1);
  3591. X0X0:mp_clear (&x0x0);
  3592. T2:mp_clear (&t2);
  3593. T1:mp_clear (&t1);
  3594. X1:mp_clear (&x1);
  3595. X0:mp_clear (&x0);
  3596. ERR:
  3597. return err;
  3598. }
  3599. /* End: bn_mp_karatsuba_sqr.c */
  3600. /* Start: bn_mp_lcm.c */
  3601. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  3602. *
  3603. * LibTomMath is a library that provides multiple-precision
  3604. * integer arithmetic as well as number theoretic functionality.
  3605. *
  3606. * The library was designed directly after the MPI library by
  3607. * Michael Fromberger but has been written from scratch with
  3608. * additional optimizations in place.
  3609. *
  3610. * The library is free for all purposes without any express
  3611. * guarantee it works.
  3612. *
  3613. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  3614. */
  3615. #include <ltc_tommath.h>
  3616. /* computes least common multiple as |a*b|/(a, b) */
  3617. int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
  3618. {
  3619. int res;
  3620. mp_int t1, t2;
  3621. if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) {
  3622. return res;
  3623. }
  3624. /* t1 = get the GCD of the two inputs */
  3625. if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
  3626. goto __T;
  3627. }
  3628. /* divide the smallest by the GCD */
  3629. if (mp_cmp_mag(a, b) == MP_LT) {
  3630. /* store quotient in t2 such that t2 * b is the LCM */
  3631. if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
  3632. goto __T;
  3633. }
  3634. res = mp_mul(b, &t2, c);
  3635. } else {
  3636. /* store quotient in t2 such that t2 * a is the LCM */
  3637. if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
  3638. goto __T;
  3639. }
  3640. res = mp_mul(a, &t2, c);
  3641. }
  3642. /* fix the sign to positive */
  3643. c->sign = MP_ZPOS;
  3644. __T:
  3645. mp_clear_multi (&t1, &t2, NULL);
  3646. return res;
  3647. }
  3648. /* End: bn_mp_lcm.c */
  3649. /* Start: bn_mp_lshd.c */
  3650. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  3651. *
  3652. * LibTomMath is a library that provides multiple-precision
  3653. * integer arithmetic as well as number theoretic functionality.
  3654. *
  3655. * The library was designed directly after the MPI library by
  3656. * Michael Fromberger but has been written from scratch with
  3657. * additional optimizations in place.
  3658. *
  3659. * The library is free for all purposes without any express
  3660. * guarantee it works.
  3661. *
  3662. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  3663. */
  3664. #include <ltc_tommath.h>
  3665. /* shift left a certain amount of digits */
  3666. int mp_lshd (mp_int * a, int b)
  3667. {
  3668. int x, res;
  3669. /* if its less than zero return */
  3670. if (b <= 0) {
  3671. return MP_OKAY;
  3672. }
  3673. /* grow to fit the new digits */
  3674. if (a->alloc < a->used + b) {
  3675. if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
  3676. return res;
  3677. }
  3678. }
  3679. {
  3680. register mp_digit *top, *bottom;
  3681. /* increment the used by the shift amount then copy upwards */
  3682. a->used += b;
  3683. /* top */
  3684. top = a->dp + a->used - 1;
  3685. /* base */
  3686. bottom = a->dp + a->used - 1 - b;
  3687. /* much like mp_rshd this is implemented using a sliding window
  3688. * except the window goes the otherway around. Copying from
  3689. * the bottom to the top. see bn_mp_rshd.c for more info.
  3690. */
  3691. for (x = a->used - 1; x >= b; x--) {
  3692. *top-- = *bottom--;
  3693. }
  3694. /* zero the lower digits */
  3695. top = a->dp;
  3696. for (x = 0; x < b; x++) {
  3697. *top++ = 0;
  3698. }
  3699. }
  3700. return MP_OKAY;
  3701. }
  3702. /* End: bn_mp_lshd.c */
  3703. /* Start: bn_mp_mod.c */
  3704. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  3705. *
  3706. * LibTomMath is a library that provides multiple-precision
  3707. * integer arithmetic as well as number theoretic functionality.
  3708. *
  3709. * The library was designed directly after the MPI library by
  3710. * Michael Fromberger but has been written from scratch with
  3711. * additional optimizations in place.
  3712. *
  3713. * The library is free for all purposes without any express
  3714. * guarantee it works.
  3715. *
  3716. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  3717. */
  3718. #include <ltc_tommath.h>
  3719. /* c = a mod b, 0 <= c < b */
  3720. int
  3721. mp_mod (mp_int * a, mp_int * b, mp_int * c)
  3722. {
  3723. mp_int t;
  3724. int res;
  3725. if ((res = mp_init (&t)) != MP_OKAY) {
  3726. return res;
  3727. }
  3728. if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
  3729. mp_clear (&t);
  3730. return res;
  3731. }
  3732. if (t.sign != b->sign) {
  3733. res = mp_add (b, &t, c);
  3734. } else {
  3735. res = MP_OKAY;
  3736. mp_exch (&t, c);
  3737. }
  3738. mp_clear (&t);
  3739. return res;
  3740. }
  3741. /* End: bn_mp_mod.c */
  3742. /* Start: bn_mp_mod_2d.c */
  3743. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  3744. *
  3745. * LibTomMath is a library that provides multiple-precision
  3746. * integer arithmetic as well as number theoretic functionality.
  3747. *
  3748. * The library was designed directly after the MPI library by
  3749. * Michael Fromberger but has been written from scratch with
  3750. * additional optimizations in place.
  3751. *
  3752. * The library is free for all purposes without any express
  3753. * guarantee it works.
  3754. *
  3755. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  3756. */
  3757. #include <ltc_tommath.h>
  3758. /* calc a value mod 2**b */
  3759. int
  3760. mp_mod_2d (mp_int * a, int b, mp_int * c)
  3761. {
  3762. int x, res;
  3763. /* if b is <= 0 then zero the int */
  3764. if (b <= 0) {
  3765. mp_zero (c);
  3766. return MP_OKAY;
  3767. }
  3768. /* if the modulus is larger than the value than return */
  3769. if (b > (int) (a->used * DIGIT_BIT)) {
  3770. res = mp_copy (a, c);
  3771. return res;
  3772. }
  3773. /* copy */
  3774. if ((res = mp_copy (a, c)) != MP_OKAY) {
  3775. return res;
  3776. }
  3777. /* zero digits above the last digit of the modulus */
  3778. for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
  3779. c->dp[x] = 0;
  3780. }
  3781. /* clear the digit that is not completely outside/inside the modulus */
  3782. c->dp[b / DIGIT_BIT] &=
  3783. (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
  3784. mp_clamp (c);
  3785. return MP_OKAY;
  3786. }
  3787. /* End: bn_mp_mod_2d.c */
  3788. /* Start: bn_mp_mod_d.c */
  3789. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  3790. *
  3791. * LibTomMath is a library that provides multiple-precision
  3792. * integer arithmetic as well as number theoretic functionality.
  3793. *
  3794. * The library was designed directly after the MPI library by
  3795. * Michael Fromberger but has been written from scratch with
  3796. * additional optimizations in place.
  3797. *
  3798. * The library is free for all purposes without any express
  3799. * guarantee it works.
  3800. *
  3801. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  3802. */
  3803. #include <ltc_tommath.h>
  3804. int
  3805. mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
  3806. {
  3807. return mp_div_d(a, b, NULL, c);
  3808. }
  3809. /* End: bn_mp_mod_d.c */
  3810. /* Start: bn_mp_montgomery_calc_normalization.c */
  3811. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  3812. *
  3813. * LibTomMath is a library that provides multiple-precision
  3814. * integer arithmetic as well as number theoretic functionality.
  3815. *
  3816. * The library was designed directly after the MPI library by
  3817. * Michael Fromberger but has been written from scratch with
  3818. * additional optimizations in place.
  3819. *
  3820. * The library is free for all purposes without any express
  3821. * guarantee it works.
  3822. *
  3823. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  3824. */
  3825. #include <ltc_tommath.h>
  3826. /* calculates a = B^n mod b for Montgomery reduction
  3827. * Where B is the base [e.g. 2^DIGIT_BIT].
  3828. * B^n mod b is computed by first computing
  3829. * A = B^(n-1) which doesn't require a reduction but a simple OR.
  3830. * then C = A * B = B^n is computed by performing upto DIGIT_BIT
  3831. * shifts with subtractions when the result is greater than b.
  3832. *
  3833. * The method is slightly modified to shift B unconditionally upto just under
  3834. * the leading bit of b. This saves alot of multiple precision shifting.
  3835. */
  3836. int
  3837. mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
  3838. {
  3839. int x, bits, res;
  3840. /* how many bits of last digit does b use */
  3841. bits = mp_count_bits (b) % DIGIT_BIT;
  3842. /* compute A = B^(n-1) * 2^(bits-1) */
  3843. if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) {
  3844. return res;
  3845. }
  3846. /* now compute C = A * B mod b */
  3847. for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
  3848. if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
  3849. return res;
  3850. }
  3851. if (mp_cmp_mag (a, b) != MP_LT) {
  3852. if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {
  3853. return res;
  3854. }
  3855. }
  3856. }
  3857. return MP_OKAY;
  3858. }
  3859. /* End: bn_mp_montgomery_calc_normalization.c */
  3860. /* Start: bn_mp_montgomery_reduce.c */
  3861. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  3862. *
  3863. * LibTomMath is a library that provides multiple-precision
  3864. * integer arithmetic as well as number theoretic functionality.
  3865. *
  3866. * The library was designed directly after the MPI library by
  3867. * Michael Fromberger but has been written from scratch with
  3868. * additional optimizations in place.
  3869. *
  3870. * The library is free for all purposes without any express
  3871. * guarantee it works.
  3872. *
  3873. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  3874. */
  3875. #include <ltc_tommath.h>
  3876. /* computes xR**-1 == x (mod N) via Montgomery Reduction */
  3877. int
  3878. mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
  3879. {
  3880. int ix, res, digs;
  3881. mp_digit mu;
  3882. /* can the fast reduction [comba] method be used?
  3883. *
  3884. * Note that unlike in mp_mul you're safely allowed *less*
  3885. * than the available columns [255 per default] since carries
  3886. * are fixed up in the inner loop.
  3887. */
  3888. digs = n->used * 2 + 1;
  3889. if ((digs < MP_WARRAY) &&
  3890. n->used <
  3891. (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
  3892. return fast_mp_montgomery_reduce (x, n, rho);
  3893. }
  3894. /* grow the input as required */
  3895. if (x->alloc < digs) {
  3896. if ((res = mp_grow (x, digs)) != MP_OKAY) {
  3897. return res;
  3898. }
  3899. }
  3900. x->used = digs;
  3901. for (ix = 0; ix < n->used; ix++) {
  3902. /* mu = ai * rho mod b
  3903. *
  3904. * The value of rho must be precalculated via
  3905. * bn_mp_montgomery_setup() such that
  3906. * it equals -1/n0 mod b this allows the
  3907. * following inner loop to reduce the
  3908. * input one digit at a time
  3909. */
  3910. mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);
  3911. /* a = a + mu * m * b**i */
  3912. {
  3913. register int iy;
  3914. register mp_digit *tmpn, *tmpx, u;
  3915. register mp_word r;
  3916. /* alias for digits of the modulus */
  3917. tmpn = n->dp;
  3918. /* alias for the digits of x [the input] */
  3919. tmpx = x->dp + ix;
  3920. /* set the carry to zero */
  3921. u = 0;
  3922. /* Multiply and add in place */
  3923. for (iy = 0; iy < n->used; iy++) {
  3924. /* compute product and sum */
  3925. r = ((mp_word)mu) * ((mp_word)*tmpn++) +
  3926. ((mp_word) u) + ((mp_word) * tmpx);
  3927. /* get carry */
  3928. u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
  3929. /* fix digit */
  3930. *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
  3931. }
  3932. /* At this point the ix'th digit of x should be zero */
  3933. /* propagate carries upwards as required*/
  3934. while (u) {
  3935. *tmpx += u;
  3936. u = *tmpx >> DIGIT_BIT;
  3937. *tmpx++ &= MP_MASK;
  3938. }
  3939. }
  3940. }
  3941. /* at this point the n.used'th least
  3942. * significant digits of x are all zero
  3943. * which means we can shift x to the
  3944. * right by n.used digits and the
  3945. * residue is unchanged.
  3946. */
  3947. /* x = x/b**n.used */
  3948. mp_clamp(x);
  3949. mp_rshd (x, n->used);
  3950. /* if x >= n then x = x - n */
  3951. if (mp_cmp_mag (x, n) != MP_LT) {
  3952. return s_mp_sub (x, n, x);
  3953. }
  3954. return MP_OKAY;
  3955. }
  3956. /* End: bn_mp_montgomery_reduce.c */
  3957. /* Start: bn_mp_montgomery_setup.c */
  3958. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  3959. *
  3960. * LibTomMath is a library that provides multiple-precision
  3961. * integer arithmetic as well as number theoretic functionality.
  3962. *
  3963. * The library was designed directly after the MPI library by
  3964. * Michael Fromberger but has been written from scratch with
  3965. * additional optimizations in place.
  3966. *
  3967. * The library is free for all purposes without any express
  3968. * guarantee it works.
  3969. *
  3970. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  3971. */
  3972. #include <ltc_tommath.h>
  3973. /* setups the montgomery reduction stuff */
  3974. int
  3975. mp_montgomery_setup (mp_int * n, mp_digit * rho)
  3976. {
  3977. mp_digit x, b;
  3978. /* fast inversion mod 2**k
  3979. *
  3980. * Based on the fact that
  3981. *
  3982. * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
  3983. * => 2*X*A - X*X*A*A = 1
  3984. * => 2*(1) - (1) = 1
  3985. */
  3986. b = n->dp[0];
  3987. if ((b & 1) == 0) {
  3988. return MP_VAL;
  3989. }
  3990. x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
  3991. x *= 2 - b * x; /* here x*a==1 mod 2**8 */
  3992. #if !defined(MP_8BIT)
  3993. x *= 2 - b * x; /* here x*a==1 mod 2**16 */
  3994. #endif
  3995. #if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
  3996. x *= 2 - b * x; /* here x*a==1 mod 2**32 */
  3997. #endif
  3998. #ifdef MP_64BIT
  3999. x *= 2 - b * x; /* here x*a==1 mod 2**64 */
  4000. #endif
  4001. /* rho = -1/m mod b */
  4002. *rho = (((mp_digit) 1 << ((mp_digit) DIGIT_BIT)) - x) & MP_MASK;
  4003. return MP_OKAY;
  4004. }
  4005. /* End: bn_mp_montgomery_setup.c */
  4006. /* Start: bn_mp_mul.c */
  4007. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4008. *
  4009. * LibTomMath is a library that provides multiple-precision
  4010. * integer arithmetic as well as number theoretic functionality.
  4011. *
  4012. * The library was designed directly after the MPI library by
  4013. * Michael Fromberger but has been written from scratch with
  4014. * additional optimizations in place.
  4015. *
  4016. * The library is free for all purposes without any express
  4017. * guarantee it works.
  4018. *
  4019. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4020. */
  4021. #include <ltc_tommath.h>
  4022. /* high level multiplication (handles sign) */
  4023. int mp_mul (mp_int * a, mp_int * b, mp_int * c)
  4024. {
  4025. int res, neg;
  4026. neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
  4027. /* use Toom-Cook? */
  4028. if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) {
  4029. res = mp_toom_mul(a, b, c);
  4030. /* use Karatsuba? */
  4031. } else if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {
  4032. res = mp_karatsuba_mul (a, b, c);
  4033. } else {
  4034. /* can we use the fast multiplier?
  4035. *
  4036. * The fast multiplier can be used if the output will
  4037. * have less than MP_WARRAY digits and the number of
  4038. * digits won't affect carry propagation
  4039. */
  4040. int digs = a->used + b->used + 1;
  4041. if ((digs < MP_WARRAY) &&
  4042. MIN(a->used, b->used) <=
  4043. (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
  4044. res = fast_s_mp_mul_digs (a, b, c, digs);
  4045. } else {
  4046. res = s_mp_mul (a, b, c);
  4047. }
  4048. }
  4049. c->sign = (c->used == 0) ? MP_ZPOS : neg;
  4050. return res;
  4051. }
  4052. /* End: bn_mp_mul.c */
  4053. /* Start: bn_mp_mul_2.c */
  4054. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4055. *
  4056. * LibTomMath is a library that provides multiple-precision
  4057. * integer arithmetic as well as number theoretic functionality.
  4058. *
  4059. * The library was designed directly after the MPI library by
  4060. * Michael Fromberger but has been written from scratch with
  4061. * additional optimizations in place.
  4062. *
  4063. * The library is free for all purposes without any express
  4064. * guarantee it works.
  4065. *
  4066. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4067. */
  4068. #include <ltc_tommath.h>
  4069. /* b = a*2 */
  4070. int mp_mul_2(mp_int * a, mp_int * b)
  4071. {
  4072. int x, res, oldused;
  4073. /* grow to accomodate result */
  4074. if (b->alloc < a->used + 1) {
  4075. if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
  4076. return res;
  4077. }
  4078. }
  4079. oldused = b->used;
  4080. b->used = a->used;
  4081. {
  4082. register mp_digit r, rr, *tmpa, *tmpb;
  4083. /* alias for source */
  4084. tmpa = a->dp;
  4085. /* alias for dest */
  4086. tmpb = b->dp;
  4087. /* carry */
  4088. r = 0;
  4089. for (x = 0; x < a->used; x++) {
  4090. /* get what will be the *next* carry bit from the
  4091. * MSB of the current digit
  4092. */
  4093. rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
  4094. /* now shift up this digit, add in the carry [from the previous] */
  4095. *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
  4096. /* copy the carry that would be from the source
  4097. * digit into the next iteration
  4098. */
  4099. r = rr;
  4100. }
  4101. /* new leading digit? */
  4102. if (r != 0) {
  4103. /* add a MSB which is always 1 at this point */
  4104. *tmpb = 1;
  4105. ++(b->used);
  4106. }
  4107. /* now zero any excess digits on the destination
  4108. * that we didn't write to
  4109. */
  4110. tmpb = b->dp + b->used;
  4111. for (x = b->used; x < oldused; x++) {
  4112. *tmpb++ = 0;
  4113. }
  4114. }
  4115. b->sign = a->sign;
  4116. return MP_OKAY;
  4117. }
  4118. /* End: bn_mp_mul_2.c */
  4119. /* Start: bn_mp_mul_2d.c */
  4120. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4121. *
  4122. * LibTomMath is a library that provides multiple-precision
  4123. * integer arithmetic as well as number theoretic functionality.
  4124. *
  4125. * The library was designed directly after the MPI library by
  4126. * Michael Fromberger but has been written from scratch with
  4127. * additional optimizations in place.
  4128. *
  4129. * The library is free for all purposes without any express
  4130. * guarantee it works.
  4131. *
  4132. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4133. */
  4134. #include <ltc_tommath.h>
  4135. /* shift left by a certain bit count */
  4136. int mp_mul_2d (mp_int * a, int b, mp_int * c)
  4137. {
  4138. mp_digit d;
  4139. int res;
  4140. /* copy */
  4141. if (a != c) {
  4142. if ((res = mp_copy (a, c)) != MP_OKAY) {
  4143. return res;
  4144. }
  4145. }
  4146. if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
  4147. if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
  4148. return res;
  4149. }
  4150. }
  4151. /* shift by as many digits in the bit count */
  4152. if (b >= (int)DIGIT_BIT) {
  4153. if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
  4154. return res;
  4155. }
  4156. }
  4157. /* shift any bit count < DIGIT_BIT */
  4158. d = (mp_digit) (b % DIGIT_BIT);
  4159. if (d != 0) {
  4160. register mp_digit *tmpc, shift, mask, r, rr;
  4161. register int x;
  4162. /* bitmask for carries */
  4163. mask = (((mp_digit)1) << d) - 1;
  4164. /* shift for msbs */
  4165. shift = DIGIT_BIT - d;
  4166. /* alias */
  4167. tmpc = c->dp;
  4168. /* carry */
  4169. r = 0;
  4170. for (x = 0; x < c->used; x++) {
  4171. /* get the higher bits of the current word */
  4172. rr = (*tmpc >> shift) & mask;
  4173. /* shift the current word and OR in the carry */
  4174. *tmpc = ((*tmpc << d) | r) & MP_MASK;
  4175. ++tmpc;
  4176. /* set the carry to the carry bits of the current word */
  4177. r = rr;
  4178. }
  4179. /* set final carry */
  4180. if (r != 0) {
  4181. c->dp[(c->used)++] = r;
  4182. }
  4183. }
  4184. mp_clamp (c);
  4185. return MP_OKAY;
  4186. }
  4187. /* End: bn_mp_mul_2d.c */
  4188. /* Start: bn_mp_mul_d.c */
  4189. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4190. *
  4191. * LibTomMath is a library that provides multiple-precision
  4192. * integer arithmetic as well as number theoretic functionality.
  4193. *
  4194. * The library was designed directly after the MPI library by
  4195. * Michael Fromberger but has been written from scratch with
  4196. * additional optimizations in place.
  4197. *
  4198. * The library is free for all purposes without any express
  4199. * guarantee it works.
  4200. *
  4201. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4202. */
  4203. #include <ltc_tommath.h>
  4204. /* multiply by a digit */
  4205. int
  4206. mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
  4207. {
  4208. mp_digit u, *tmpa, *tmpc;
  4209. mp_word r;
  4210. int ix, res, olduse;
  4211. /* make sure c is big enough to hold a*b */
  4212. if (c->alloc < a->used + 1) {
  4213. if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
  4214. return res;
  4215. }
  4216. }
  4217. /* get the original destinations used count */
  4218. olduse = c->used;
  4219. /* set the sign */
  4220. c->sign = a->sign;
  4221. /* alias for a->dp [source] */
  4222. tmpa = a->dp;
  4223. /* alias for c->dp [dest] */
  4224. tmpc = c->dp;
  4225. /* zero carry */
  4226. u = 0;
  4227. /* compute columns */
  4228. for (ix = 0; ix < a->used; ix++) {
  4229. /* compute product and carry sum for this term */
  4230. r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);
  4231. /* mask off higher bits to get a single digit */
  4232. *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
  4233. /* send carry into next iteration */
  4234. u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
  4235. }
  4236. /* store final carry [if any] */
  4237. *tmpc++ = u;
  4238. /* now zero digits above the top */
  4239. while (ix++ < olduse) {
  4240. *tmpc++ = 0;
  4241. }
  4242. /* set used count */
  4243. c->used = a->used + 1;
  4244. mp_clamp(c);
  4245. return MP_OKAY;
  4246. }
  4247. /* End: bn_mp_mul_d.c */
  4248. /* Start: bn_mp_mulmod.c */
  4249. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4250. *
  4251. * LibTomMath is a library that provides multiple-precision
  4252. * integer arithmetic as well as number theoretic functionality.
  4253. *
  4254. * The library was designed directly after the MPI library by
  4255. * Michael Fromberger but has been written from scratch with
  4256. * additional optimizations in place.
  4257. *
  4258. * The library is free for all purposes without any express
  4259. * guarantee it works.
  4260. *
  4261. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4262. */
  4263. #include <ltc_tommath.h>
  4264. /* d = a * b (mod c) */
  4265. int
  4266. mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
  4267. {
  4268. int res;
  4269. mp_int t;
  4270. if ((res = mp_init (&t)) != MP_OKAY) {
  4271. return res;
  4272. }
  4273. if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
  4274. mp_clear (&t);
  4275. return res;
  4276. }
  4277. res = mp_mod (&t, c, d);
  4278. mp_clear (&t);
  4279. return res;
  4280. }
  4281. /* End: bn_mp_mulmod.c */
  4282. /* Start: bn_mp_n_root.c */
  4283. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4284. *
  4285. * LibTomMath is a library that provides multiple-precision
  4286. * integer arithmetic as well as number theoretic functionality.
  4287. *
  4288. * The library was designed directly after the MPI library by
  4289. * Michael Fromberger but has been written from scratch with
  4290. * additional optimizations in place.
  4291. *
  4292. * The library is free for all purposes without any express
  4293. * guarantee it works.
  4294. *
  4295. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4296. */
  4297. #include <ltc_tommath.h>
  4298. /* find the n'th root of an integer
  4299. *
  4300. * Result found such that (c)**b <= a and (c+1)**b > a
  4301. *
  4302. * This algorithm uses Newton's approximation
  4303. * x[i+1] = x[i] - f(x[i])/f'(x[i])
  4304. * which will find the root in log(N) time where
  4305. * each step involves a fair bit. This is not meant to
  4306. * find huge roots [square and cube, etc].
  4307. */
  4308. int mp_n_root (mp_int * a, mp_digit b, mp_int * c)
  4309. {
  4310. mp_int t1, t2, t3;
  4311. int res, neg;
  4312. /* input must be positive if b is even */
  4313. if ((b & 1) == 0 && a->sign == MP_NEG) {
  4314. return MP_VAL;
  4315. }
  4316. if ((res = mp_init (&t1)) != MP_OKAY) {
  4317. return res;
  4318. }
  4319. if ((res = mp_init (&t2)) != MP_OKAY) {
  4320. goto __T1;
  4321. }
  4322. if ((res = mp_init (&t3)) != MP_OKAY) {
  4323. goto __T2;
  4324. }
  4325. /* if a is negative fudge the sign but keep track */
  4326. neg = a->sign;
  4327. a->sign = MP_ZPOS;
  4328. /* t2 = 2 */
  4329. mp_set (&t2, 2);
  4330. do {
  4331. /* t1 = t2 */
  4332. if ((res = mp_copy (&t2, &t1)) != MP_OKAY) {
  4333. goto __T3;
  4334. }
  4335. /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
  4336. /* t3 = t1**(b-1) */
  4337. if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) {
  4338. goto __T3;
  4339. }
  4340. /* numerator */
  4341. /* t2 = t1**b */
  4342. if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) {
  4343. goto __T3;
  4344. }
  4345. /* t2 = t1**b - a */
  4346. if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) {
  4347. goto __T3;
  4348. }
  4349. /* denominator */
  4350. /* t3 = t1**(b-1) * b */
  4351. if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) {
  4352. goto __T3;
  4353. }
  4354. /* t3 = (t1**b - a)/(b * t1**(b-1)) */
  4355. if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) {
  4356. goto __T3;
  4357. }
  4358. if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) {
  4359. goto __T3;
  4360. }
  4361. } while (mp_cmp (&t1, &t2) != MP_EQ);
  4362. /* result can be off by a few so check */
  4363. for (;;) {
  4364. if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) {
  4365. goto __T3;
  4366. }
  4367. if (mp_cmp (&t2, a) == MP_GT) {
  4368. if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) {
  4369. goto __T3;
  4370. }
  4371. } else {
  4372. break;
  4373. }
  4374. }
  4375. /* reset the sign of a first */
  4376. a->sign = neg;
  4377. /* set the result */
  4378. mp_exch (&t1, c);
  4379. /* set the sign of the result */
  4380. c->sign = neg;
  4381. res = MP_OKAY;
  4382. __T3:mp_clear (&t3);
  4383. __T2:mp_clear (&t2);
  4384. __T1:mp_clear (&t1);
  4385. return res;
  4386. }
  4387. /* End: bn_mp_n_root.c */
  4388. /* Start: bn_mp_neg.c */
  4389. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4390. *
  4391. * LibTomMath is a library that provides multiple-precision
  4392. * integer arithmetic as well as number theoretic functionality.
  4393. *
  4394. * The library was designed directly after the MPI library by
  4395. * Michael Fromberger but has been written from scratch with
  4396. * additional optimizations in place.
  4397. *
  4398. * The library is free for all purposes without any express
  4399. * guarantee it works.
  4400. *
  4401. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4402. */
  4403. #include <ltc_tommath.h>
  4404. /* b = -a */
  4405. int mp_neg (mp_int * a, mp_int * b)
  4406. {
  4407. int res;
  4408. if ((res = mp_copy (a, b)) != MP_OKAY) {
  4409. return res;
  4410. }
  4411. if (mp_iszero(b) != MP_YES) {
  4412. b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
  4413. }
  4414. return MP_OKAY;
  4415. }
  4416. /* End: bn_mp_neg.c */
  4417. /* Start: bn_mp_or.c */
  4418. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4419. *
  4420. * LibTomMath is a library that provides multiple-precision
  4421. * integer arithmetic as well as number theoretic functionality.
  4422. *
  4423. * The library was designed directly after the MPI library by
  4424. * Michael Fromberger but has been written from scratch with
  4425. * additional optimizations in place.
  4426. *
  4427. * The library is free for all purposes without any express
  4428. * guarantee it works.
  4429. *
  4430. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4431. */
  4432. #include <ltc_tommath.h>
  4433. /* OR two ints together */
  4434. int mp_or (mp_int * a, mp_int * b, mp_int * c)
  4435. {
  4436. int res, ix, px;
  4437. mp_int t, *x;
  4438. if (a->used > b->used) {
  4439. if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
  4440. return res;
  4441. }
  4442. px = b->used;
  4443. x = b;
  4444. } else {
  4445. if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
  4446. return res;
  4447. }
  4448. px = a->used;
  4449. x = a;
  4450. }
  4451. for (ix = 0; ix < px; ix++) {
  4452. t.dp[ix] |= x->dp[ix];
  4453. }
  4454. mp_clamp (&t);
  4455. mp_exch (c, &t);
  4456. mp_clear (&t);
  4457. return MP_OKAY;
  4458. }
  4459. /* End: bn_mp_or.c */
  4460. /* Start: bn_mp_prime_fermat.c */
  4461. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4462. *
  4463. * LibTomMath is a library that provides multiple-precision
  4464. * integer arithmetic as well as number theoretic functionality.
  4465. *
  4466. * The library was designed directly after the MPI library by
  4467. * Michael Fromberger but has been written from scratch with
  4468. * additional optimizations in place.
  4469. *
  4470. * The library is free for all purposes without any express
  4471. * guarantee it works.
  4472. *
  4473. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4474. */
  4475. #include <ltc_tommath.h>
  4476. /* performs one Fermat test.
  4477. *
  4478. * If "a" were prime then b**a == b (mod a) since the order of
  4479. * the multiplicative sub-group would be phi(a) = a-1. That means
  4480. * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a).
  4481. *
  4482. * Sets result to 1 if the congruence holds, or zero otherwise.
  4483. */
  4484. int mp_prime_fermat (mp_int * a, mp_int * b, int *result)
  4485. {
  4486. mp_int t;
  4487. int err;
  4488. /* default to composite */
  4489. *result = MP_NO;
  4490. /* ensure b > 1 */
  4491. if (mp_cmp_d(b, 1) != MP_GT) {
  4492. return MP_VAL;
  4493. }
  4494. /* init t */
  4495. if ((err = mp_init (&t)) != MP_OKAY) {
  4496. return err;
  4497. }
  4498. /* compute t = b**a mod a */
  4499. if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) {
  4500. goto __T;
  4501. }
  4502. /* is it equal to b? */
  4503. if (mp_cmp (&t, b) == MP_EQ) {
  4504. *result = MP_YES;
  4505. }
  4506. err = MP_OKAY;
  4507. __T:mp_clear (&t);
  4508. return err;
  4509. }
  4510. /* End: bn_mp_prime_fermat.c */
  4511. /* Start: bn_mp_prime_is_divisible.c */
  4512. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4513. *
  4514. * LibTomMath is a library that provides multiple-precision
  4515. * integer arithmetic as well as number theoretic functionality.
  4516. *
  4517. * The library was designed directly after the MPI library by
  4518. * Michael Fromberger but has been written from scratch with
  4519. * additional optimizations in place.
  4520. *
  4521. * The library is free for all purposes without any express
  4522. * guarantee it works.
  4523. *
  4524. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4525. */
  4526. #include <ltc_tommath.h>
  4527. /* determines if an integers is divisible by one
  4528. * of the first PRIME_SIZE primes or not
  4529. *
  4530. * sets result to 0 if not, 1 if yes
  4531. */
  4532. int mp_prime_is_divisible (mp_int * a, int *result)
  4533. {
  4534. int err, ix;
  4535. mp_digit res;
  4536. /* default to not */
  4537. *result = MP_NO;
  4538. for (ix = 0; ix < PRIME_SIZE; ix++) {
  4539. /* what is a mod __prime_tab[ix] */
  4540. if ((err = mp_mod_d (a, __prime_tab[ix], &res)) != MP_OKAY) {
  4541. return err;
  4542. }
  4543. /* is the residue zero? */
  4544. if (res == 0) {
  4545. *result = MP_YES;
  4546. return MP_OKAY;
  4547. }
  4548. }
  4549. return MP_OKAY;
  4550. }
  4551. /* End: bn_mp_prime_is_divisible.c */
  4552. /* Start: bn_mp_prime_is_prime.c */
  4553. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4554. *
  4555. * LibTomMath is a library that provides multiple-precision
  4556. * integer arithmetic as well as number theoretic functionality.
  4557. *
  4558. * The library was designed directly after the MPI library by
  4559. * Michael Fromberger but has been written from scratch with
  4560. * additional optimizations in place.
  4561. *
  4562. * The library is free for all purposes without any express
  4563. * guarantee it works.
  4564. *
  4565. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4566. */
  4567. #include <ltc_tommath.h>
  4568. /* performs a variable number of rounds of Miller-Rabin
  4569. *
  4570. * Probability of error after t rounds is no more than
  4571. * (1/4)^t when 1 <= t <= PRIME_SIZE
  4572. *
  4573. * Sets result to 1 if probably prime, 0 otherwise
  4574. */
  4575. int mp_prime_is_prime (mp_int * a, int t, int *result)
  4576. {
  4577. mp_int b;
  4578. int ix, err, res;
  4579. /* default to no */
  4580. *result = MP_NO;
  4581. /* valid value of t? */
  4582. if (t <= 0 || t > PRIME_SIZE) {
  4583. return MP_VAL;
  4584. }
  4585. /* is the input equal to one of the primes in the table? */
  4586. for (ix = 0; ix < PRIME_SIZE; ix++) {
  4587. if (mp_cmp_d(a, __prime_tab[ix]) == MP_EQ) {
  4588. *result = 1;
  4589. return MP_OKAY;
  4590. }
  4591. }
  4592. /* first perform trial division */
  4593. if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
  4594. return err;
  4595. }
  4596. /* return if it was trivially divisible */
  4597. if (res == MP_YES) {
  4598. return MP_OKAY;
  4599. }
  4600. /* now perform the miller-rabin rounds */
  4601. if ((err = mp_init (&b)) != MP_OKAY) {
  4602. return err;
  4603. }
  4604. for (ix = 0; ix < t; ix++) {
  4605. /* set the prime */
  4606. mp_set (&b, __prime_tab[ix]);
  4607. if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
  4608. goto __B;
  4609. }
  4610. if (res == MP_NO) {
  4611. goto __B;
  4612. }
  4613. }
  4614. /* passed the test */
  4615. *result = MP_YES;
  4616. __B:mp_clear (&b);
  4617. return err;
  4618. }
  4619. /* End: bn_mp_prime_is_prime.c */
  4620. /* Start: bn_mp_prime_miller_rabin.c */
  4621. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4622. *
  4623. * LibTomMath is a library that provides multiple-precision
  4624. * integer arithmetic as well as number theoretic functionality.
  4625. *
  4626. * The library was designed directly after the MPI library by
  4627. * Michael Fromberger but has been written from scratch with
  4628. * additional optimizations in place.
  4629. *
  4630. * The library is free for all purposes without any express
  4631. * guarantee it works.
  4632. *
  4633. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4634. */
  4635. #include <ltc_tommath.h>
  4636. /* Miller-Rabin test of "a" to the base of "b" as described in
  4637. * HAC pp. 139 Algorithm 4.24
  4638. *
  4639. * Sets result to 0 if definitely composite or 1 if probably prime.
  4640. * Randomly the chance of error is no more than 1/4 and often
  4641. * very much lower.
  4642. */
  4643. int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
  4644. {
  4645. mp_int n1, y, r;
  4646. int s, j, err;
  4647. /* default */
  4648. *result = MP_NO;
  4649. /* ensure b > 1 */
  4650. if (mp_cmp_d(b, 1) != MP_GT) {
  4651. return MP_VAL;
  4652. }
  4653. /* get n1 = a - 1 */
  4654. if ((err = mp_init_copy (&n1, a)) != MP_OKAY) {
  4655. return err;
  4656. }
  4657. if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) {
  4658. goto __N1;
  4659. }
  4660. /* set 2**s * r = n1 */
  4661. if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) {
  4662. goto __N1;
  4663. }
  4664. /* count the number of least significant bits
  4665. * which are zero
  4666. */
  4667. s = mp_cnt_lsb(&r);
  4668. /* now divide n - 1 by 2**s */
  4669. if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
  4670. goto __R;
  4671. }
  4672. /* compute y = b**r mod a */
  4673. if ((err = mp_init (&y)) != MP_OKAY) {
  4674. goto __R;
  4675. }
  4676. if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) {
  4677. goto __Y;
  4678. }
  4679. /* if y != 1 and y != n1 do */
  4680. if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) {
  4681. j = 1;
  4682. /* while j <= s-1 and y != n1 */
  4683. while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) {
  4684. if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) {
  4685. goto __Y;
  4686. }
  4687. /* if y == 1 then composite */
  4688. if (mp_cmp_d (&y, 1) == MP_EQ) {
  4689. goto __Y;
  4690. }
  4691. ++j;
  4692. }
  4693. /* if y != n1 then composite */
  4694. if (mp_cmp (&y, &n1) != MP_EQ) {
  4695. goto __Y;
  4696. }
  4697. }
  4698. /* probably prime now */
  4699. *result = MP_YES;
  4700. __Y:mp_clear (&y);
  4701. __R:mp_clear (&r);
  4702. __N1:mp_clear (&n1);
  4703. return err;
  4704. }
  4705. /* End: bn_mp_prime_miller_rabin.c */
  4706. /* Start: bn_mp_prime_next_prime.c */
  4707. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4708. *
  4709. * LibTomMath is a library that provides multiple-precision
  4710. * integer arithmetic as well as number theoretic functionality.
  4711. *
  4712. * The library was designed directly after the MPI library by
  4713. * Michael Fromberger but has been written from scratch with
  4714. * additional optimizations in place.
  4715. *
  4716. * The library is free for all purposes without any express
  4717. * guarantee it works.
  4718. *
  4719. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4720. */
  4721. #include <ltc_tommath.h>
  4722. /* finds the next prime after the number "a" using "t" trials
  4723. * of Miller-Rabin.
  4724. *
  4725. * bbs_style = 1 means the prime must be congruent to 3 mod 4
  4726. */
  4727. int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
  4728. {
  4729. int err, res, x, y;
  4730. mp_digit res_tab[PRIME_SIZE], step, kstep;
  4731. mp_int b;
  4732. /* ensure t is valid */
  4733. if (t <= 0 || t > PRIME_SIZE) {
  4734. return MP_VAL;
  4735. }
  4736. /* force positive */
  4737. a->sign = MP_ZPOS;
  4738. /* simple algo if a is less than the largest prime in the table */
  4739. if (mp_cmp_d(a, __prime_tab[PRIME_SIZE-1]) == MP_LT) {
  4740. /* find which prime it is bigger than */
  4741. for (x = PRIME_SIZE - 2; x >= 0; x--) {
  4742. if (mp_cmp_d(a, __prime_tab[x]) != MP_LT) {
  4743. if (bbs_style == 1) {
  4744. /* ok we found a prime smaller or
  4745. * equal [so the next is larger]
  4746. *
  4747. * however, the prime must be
  4748. * congruent to 3 mod 4
  4749. */
  4750. if ((__prime_tab[x + 1] & 3) != 3) {
  4751. /* scan upwards for a prime congruent to 3 mod 4 */
  4752. for (y = x + 1; y < PRIME_SIZE; y++) {
  4753. if ((__prime_tab[y] & 3) == 3) {
  4754. mp_set(a, __prime_tab[y]);
  4755. return MP_OKAY;
  4756. }
  4757. }
  4758. }
  4759. } else {
  4760. mp_set(a, __prime_tab[x + 1]);
  4761. return MP_OKAY;
  4762. }
  4763. }
  4764. }
  4765. /* at this point a maybe 1 */
  4766. if (mp_cmp_d(a, 1) == MP_EQ) {
  4767. mp_set(a, 2);
  4768. return MP_OKAY;
  4769. }
  4770. /* fall through to the sieve */
  4771. }
  4772. /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */
  4773. if (bbs_style == 1) {
  4774. kstep = 4;
  4775. } else {
  4776. kstep = 2;
  4777. }
  4778. /* at this point we will use a combination of a sieve and Miller-Rabin */
  4779. if (bbs_style == 1) {
  4780. /* if a mod 4 != 3 subtract the correct value to make it so */
  4781. if ((a->dp[0] & 3) != 3) {
  4782. if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; };
  4783. }
  4784. } else {
  4785. if (mp_iseven(a) == 1) {
  4786. /* force odd */
  4787. if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) {
  4788. return err;
  4789. }
  4790. }
  4791. }
  4792. /* generate the restable */
  4793. for (x = 1; x < PRIME_SIZE; x++) {
  4794. if ((err = mp_mod_d(a, __prime_tab[x], res_tab + x)) != MP_OKAY) {
  4795. return err;
  4796. }
  4797. }
  4798. /* init temp used for Miller-Rabin Testing */
  4799. if ((err = mp_init(&b)) != MP_OKAY) {
  4800. return err;
  4801. }
  4802. for (;;) {
  4803. /* skip to the next non-trivially divisible candidate */
  4804. step = 0;
  4805. do {
  4806. /* y == 1 if any residue was zero [e.g. cannot be prime] */
  4807. y = 0;
  4808. /* increase step to next candidate */
  4809. step += kstep;
  4810. /* compute the new residue without using division */
  4811. for (x = 1; x < PRIME_SIZE; x++) {
  4812. /* add the step to each residue */
  4813. res_tab[x] += kstep;
  4814. /* subtract the modulus [instead of using division] */
  4815. if (res_tab[x] >= __prime_tab[x]) {
  4816. res_tab[x] -= __prime_tab[x];
  4817. }
  4818. /* set flag if zero */
  4819. if (res_tab[x] == 0) {
  4820. y = 1;
  4821. }
  4822. }
  4823. } while (y == 1 && step < ((((mp_digit)1)<<DIGIT_BIT) - kstep));
  4824. /* add the step */
  4825. if ((err = mp_add_d(a, step, a)) != MP_OKAY) {
  4826. goto __ERR;
  4827. }
  4828. /* if didn't pass sieve and step == MAX then skip test */
  4829. if (y == 1 && step >= ((((mp_digit)1)<<DIGIT_BIT) - kstep)) {
  4830. continue;
  4831. }
  4832. /* is this prime? */
  4833. for (x = 0; x < t; x++) {
  4834. mp_set(&b, __prime_tab[t]);
  4835. if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
  4836. goto __ERR;
  4837. }
  4838. if (res == MP_NO) {
  4839. break;
  4840. }
  4841. }
  4842. if (res == MP_YES) {
  4843. break;
  4844. }
  4845. }
  4846. err = MP_OKAY;
  4847. __ERR:
  4848. mp_clear(&b);
  4849. return err;
  4850. }
  4851. /* End: bn_mp_prime_next_prime.c */
  4852. /* Start: bn_mp_prime_random_ex.c */
  4853. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4854. *
  4855. * LibTomMath is a library that provides multiple-precision
  4856. * integer arithmetic as well as number theoretic functionality.
  4857. *
  4858. * The library was designed directly after the MPI library by
  4859. * Michael Fromberger but has been written from scratch with
  4860. * additional optimizations in place.
  4861. *
  4862. * The library is free for all purposes without any express
  4863. * guarantee it works.
  4864. *
  4865. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4866. */
  4867. #include <ltc_tommath.h>
  4868. /* makes a truly random prime of a given size (bits),
  4869. *
  4870. * Flags are as follows:
  4871. *
  4872. * LTM_PRIME_BBS - make prime congruent to 3 mod 4
  4873. * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
  4874. * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero
  4875. * LTM_PRIME_2MSB_ON - make the 2nd highest bit one
  4876. *
  4877. * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
  4878. * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
  4879. * so it can be NULL
  4880. *
  4881. */
  4882. /* This is possibly the mother of all prime generation functions, muahahahahaha! */
  4883. int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat)
  4884. {
  4885. unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb;
  4886. int res, err, bsize, maskOR_msb_offset;
  4887. /* sanity check the input */
  4888. if (size <= 1 || t <= 0) {
  4889. return MP_VAL;
  4890. }
  4891. /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */
  4892. if (flags & LTM_PRIME_SAFE) {
  4893. flags |= LTM_PRIME_BBS;
  4894. }
  4895. /* calc the byte size */
  4896. bsize = (size>>3)+(size&7?1:0);
  4897. /* we need a buffer of bsize bytes */
  4898. tmp = OPT_CAST(unsigned char) XMALLOC(bsize);
  4899. if (tmp == NULL) {
  4900. return MP_MEM;
  4901. }
  4902. /* calc the maskAND value for the MSbyte*/
  4903. maskAND = 0xFF >> (8 - (size & 7));
  4904. /* calc the maskOR_msb */
  4905. maskOR_msb = 0;
  4906. maskOR_msb_offset = (size - 2) >> 3;
  4907. if (flags & LTM_PRIME_2MSB_ON) {
  4908. maskOR_msb |= 1 << ((size - 2) & 7);
  4909. } else if (flags & LTM_PRIME_2MSB_OFF) {
  4910. maskAND &= ~(1 << ((size - 2) & 7));
  4911. }
  4912. /* get the maskOR_lsb */
  4913. maskOR_lsb = 0;
  4914. if (flags & LTM_PRIME_BBS) {
  4915. maskOR_lsb |= 3;
  4916. }
  4917. do {
  4918. /* read the bytes */
  4919. if (cb(tmp, bsize, dat) != bsize) {
  4920. err = MP_VAL;
  4921. goto error;
  4922. }
  4923. /* work over the MSbyte */
  4924. tmp[0] &= maskAND;
  4925. tmp[0] |= 1 << ((size - 1) & 7);
  4926. /* mix in the maskORs */
  4927. tmp[maskOR_msb_offset] |= maskOR_msb;
  4928. tmp[bsize-1] |= maskOR_lsb;
  4929. /* read it in */
  4930. if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; }
  4931. /* is it prime? */
  4932. if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; }
  4933. if (flags & LTM_PRIME_SAFE) {
  4934. /* see if (a-1)/2 is prime */
  4935. if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; }
  4936. if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; }
  4937. /* is it prime? */
  4938. if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; }
  4939. }
  4940. } while (res == MP_NO);
  4941. if (flags & LTM_PRIME_SAFE) {
  4942. /* restore a to the original value */
  4943. if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; }
  4944. if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; }
  4945. }
  4946. err = MP_OKAY;
  4947. error:
  4948. XFREE(tmp);
  4949. return err;
  4950. }
  4951. /* End: bn_mp_prime_random_ex.c */
  4952. /* Start: bn_mp_radix_size.c */
  4953. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4954. *
  4955. * LibTomMath is a library that provides multiple-precision
  4956. * integer arithmetic as well as number theoretic functionality.
  4957. *
  4958. * The library was designed directly after the MPI library by
  4959. * Michael Fromberger but has been written from scratch with
  4960. * additional optimizations in place.
  4961. *
  4962. * The library is free for all purposes without any express
  4963. * guarantee it works.
  4964. *
  4965. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  4966. */
  4967. #include <ltc_tommath.h>
  4968. /* returns size of ASCII reprensentation */
  4969. int mp_radix_size (mp_int * a, int radix, int *size)
  4970. {
  4971. int res, digs;
  4972. mp_int t;
  4973. mp_digit d;
  4974. *size = 0;
  4975. /* special case for binary */
  4976. if (radix == 2) {
  4977. *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
  4978. return MP_OKAY;
  4979. }
  4980. /* make sure the radix is in range */
  4981. if (radix < 2 || radix > 64) {
  4982. return MP_VAL;
  4983. }
  4984. /* init a copy of the input */
  4985. if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
  4986. return res;
  4987. }
  4988. /* digs is the digit count */
  4989. digs = 0;
  4990. /* if it's negative add one for the sign */
  4991. if (t.sign == MP_NEG) {
  4992. ++digs;
  4993. t.sign = MP_ZPOS;
  4994. }
  4995. /* fetch out all of the digits */
  4996. while (mp_iszero (&t) == 0) {
  4997. if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
  4998. mp_clear (&t);
  4999. return res;
  5000. }
  5001. ++digs;
  5002. }
  5003. mp_clear (&t);
  5004. /* return digs + 1, the 1 is for the NULL byte that would be required. */
  5005. *size = digs + 1;
  5006. return MP_OKAY;
  5007. }
  5008. /* End: bn_mp_radix_size.c */
  5009. /* Start: bn_mp_radix_smap.c */
  5010. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5011. *
  5012. * LibTomMath is a library that provides multiple-precision
  5013. * integer arithmetic as well as number theoretic functionality.
  5014. *
  5015. * The library was designed directly after the MPI library by
  5016. * Michael Fromberger but has been written from scratch with
  5017. * additional optimizations in place.
  5018. *
  5019. * The library is free for all purposes without any express
  5020. * guarantee it works.
  5021. *
  5022. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5023. */
  5024. #include <ltc_tommath.h>
  5025. /* chars used in radix conversions */
  5026. const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
  5027. /* End: bn_mp_radix_smap.c */
  5028. /* Start: bn_mp_rand.c */
  5029. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5030. *
  5031. * LibTomMath is a library that provides multiple-precision
  5032. * integer arithmetic as well as number theoretic functionality.
  5033. *
  5034. * The library was designed directly after the MPI library by
  5035. * Michael Fromberger but has been written from scratch with
  5036. * additional optimizations in place.
  5037. *
  5038. * The library is free for all purposes without any express
  5039. * guarantee it works.
  5040. *
  5041. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5042. */
  5043. #include <ltc_tommath.h>
  5044. /* makes a pseudo-random int of a given size */
  5045. int
  5046. mp_rand (mp_int * a, int digits)
  5047. {
  5048. int res;
  5049. mp_digit d;
  5050. mp_zero (a);
  5051. if (digits <= 0) {
  5052. return MP_OKAY;
  5053. }
  5054. /* first place a random non-zero digit */
  5055. do {
  5056. d = ((mp_digit) abs (rand ()));
  5057. } while (d == 0);
  5058. if ((res = mp_add_d (a, d, a)) != MP_OKAY) {
  5059. return res;
  5060. }
  5061. while (digits-- > 0) {
  5062. if ((res = mp_lshd (a, 1)) != MP_OKAY) {
  5063. return res;
  5064. }
  5065. if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) {
  5066. return res;
  5067. }
  5068. }
  5069. return MP_OKAY;
  5070. }
  5071. /* End: bn_mp_rand.c */
  5072. /* Start: bn_mp_read_radix.c */
  5073. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5074. *
  5075. * LibTomMath is a library that provides multiple-precision
  5076. * integer arithmetic as well as number theoretic functionality.
  5077. *
  5078. * The library was designed directly after the MPI library by
  5079. * Michael Fromberger but has been written from scratch with
  5080. * additional optimizations in place.
  5081. *
  5082. * The library is free for all purposes without any express
  5083. * guarantee it works.
  5084. *
  5085. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5086. */
  5087. #include <ltc_tommath.h>
  5088. /* read a string [ASCII] in a given radix */
  5089. int mp_read_radix (mp_int * a, char *str, int radix)
  5090. {
  5091. int y, res, neg;
  5092. char ch;
  5093. /* make sure the radix is ok */
  5094. if (radix < 2 || radix > 64) {
  5095. return MP_VAL;
  5096. }
  5097. /* if the leading digit is a
  5098. * minus set the sign to negative.
  5099. */
  5100. if (*str == '-') {
  5101. ++str;
  5102. neg = MP_NEG;
  5103. } else {
  5104. neg = MP_ZPOS;
  5105. }
  5106. /* set the integer to the default of zero */
  5107. mp_zero (a);
  5108. /* process each digit of the string */
  5109. while (*str) {
  5110. /* if the radix < 36 the conversion is case insensitive
  5111. * this allows numbers like 1AB and 1ab to represent the same value
  5112. * [e.g. in hex]
  5113. */
  5114. ch = (char) ((radix < 36) ? toupper (*str) : *str);
  5115. for (y = 0; y < 64; y++) {
  5116. if (ch == mp_s_rmap[y]) {
  5117. break;
  5118. }
  5119. }
  5120. /* if the char was found in the map
  5121. * and is less than the given radix add it
  5122. * to the number, otherwise exit the loop.
  5123. */
  5124. if (y < radix) {
  5125. if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {
  5126. return res;
  5127. }
  5128. if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {
  5129. return res;
  5130. }
  5131. } else {
  5132. break;
  5133. }
  5134. ++str;
  5135. }
  5136. /* set the sign only if a != 0 */
  5137. if (mp_iszero(a) != 1) {
  5138. a->sign = neg;
  5139. }
  5140. return MP_OKAY;
  5141. }
  5142. /* End: bn_mp_read_radix.c */
  5143. /* Start: bn_mp_read_signed_bin.c */
  5144. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5145. *
  5146. * LibTomMath is a library that provides multiple-precision
  5147. * integer arithmetic as well as number theoretic functionality.
  5148. *
  5149. * The library was designed directly after the MPI library by
  5150. * Michael Fromberger but has been written from scratch with
  5151. * additional optimizations in place.
  5152. *
  5153. * The library is free for all purposes without any express
  5154. * guarantee it works.
  5155. *
  5156. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5157. */
  5158. #include <ltc_tommath.h>
  5159. /* read signed bin, big endian, first byte is 0==positive or 1==negative */
  5160. int
  5161. mp_read_signed_bin (mp_int * a, unsigned char *b, int c)
  5162. {
  5163. int res;
  5164. /* read magnitude */
  5165. if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) {
  5166. return res;
  5167. }
  5168. /* first byte is 0 for positive, non-zero for negative */
  5169. if (b[0] == 0) {
  5170. a->sign = MP_ZPOS;
  5171. } else {
  5172. a->sign = MP_NEG;
  5173. }
  5174. return MP_OKAY;
  5175. }
  5176. /* End: bn_mp_read_signed_bin.c */
  5177. /* Start: bn_mp_read_unsigned_bin.c */
  5178. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5179. *
  5180. * LibTomMath is a library that provides multiple-precision
  5181. * integer arithmetic as well as number theoretic functionality.
  5182. *
  5183. * The library was designed directly after the MPI library by
  5184. * Michael Fromberger but has been written from scratch with
  5185. * additional optimizations in place.
  5186. *
  5187. * The library is free for all purposes without any express
  5188. * guarantee it works.
  5189. *
  5190. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5191. */
  5192. #include <ltc_tommath.h>
  5193. /* reads a unsigned char array, assumes the msb is stored first [big endian] */
  5194. int
  5195. mp_read_unsigned_bin (mp_int * a, unsigned char *b, int c)
  5196. {
  5197. int res;
  5198. /* make sure there are at least two digits */
  5199. if (a->alloc < 2) {
  5200. if ((res = mp_grow(a, 2)) != MP_OKAY) {
  5201. return res;
  5202. }
  5203. }
  5204. /* zero the int */
  5205. mp_zero (a);
  5206. /* read the bytes in */
  5207. while (c-- > 0) {
  5208. if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
  5209. return res;
  5210. }
  5211. #ifndef MP_8BIT
  5212. a->dp[0] |= *b++;
  5213. a->used += 1;
  5214. #else
  5215. a->dp[0] = (*b & MP_MASK);
  5216. a->dp[1] |= ((*b++ >> 7U) & 1);
  5217. a->used += 2;
  5218. #endif
  5219. }
  5220. mp_clamp (a);
  5221. return MP_OKAY;
  5222. }
  5223. /* End: bn_mp_read_unsigned_bin.c */
  5224. /* Start: bn_mp_reduce.c */
  5225. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5226. *
  5227. * LibTomMath is a library that provides multiple-precision
  5228. * integer arithmetic as well as number theoretic functionality.
  5229. *
  5230. * The library was designed directly after the MPI library by
  5231. * Michael Fromberger but has been written from scratch with
  5232. * additional optimizations in place.
  5233. *
  5234. * The library is free for all purposes without any express
  5235. * guarantee it works.
  5236. *
  5237. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5238. */
  5239. #include <ltc_tommath.h>
  5240. /* reduces x mod m, assumes 0 < x < m**2, mu is
  5241. * precomputed via mp_reduce_setup.
  5242. * From HAC pp.604 Algorithm 14.42
  5243. */
  5244. int
  5245. mp_reduce (mp_int * x, mp_int * m, mp_int * mu)
  5246. {
  5247. mp_int q;
  5248. int res, um = m->used;
  5249. /* q = x */
  5250. if ((res = mp_init_copy (&q, x)) != MP_OKAY) {
  5251. return res;
  5252. }
  5253. /* q1 = x / b**(k-1) */
  5254. mp_rshd (&q, um - 1);
  5255. /* according to HAC this optimization is ok */
  5256. if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) {
  5257. if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) {
  5258. goto CLEANUP;
  5259. }
  5260. } else {
  5261. if ((res = s_mp_mul_high_digs (&q, mu, &q, um - 1)) != MP_OKAY) {
  5262. goto CLEANUP;
  5263. }
  5264. }
  5265. /* q3 = q2 / b**(k+1) */
  5266. mp_rshd (&q, um + 1);
  5267. /* x = x mod b**(k+1), quick (no division) */
  5268. if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
  5269. goto CLEANUP;
  5270. }
  5271. /* q = q * m mod b**(k+1), quick (no division) */
  5272. if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) {
  5273. goto CLEANUP;
  5274. }
  5275. /* x = x - q */
  5276. if ((res = mp_sub (x, &q, x)) != MP_OKAY) {
  5277. goto CLEANUP;
  5278. }
  5279. /* If x < 0, add b**(k+1) to it */
  5280. if (mp_cmp_d (x, 0) == MP_LT) {
  5281. mp_set (&q, 1);
  5282. if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)
  5283. goto CLEANUP;
  5284. if ((res = mp_add (x, &q, x)) != MP_OKAY)
  5285. goto CLEANUP;
  5286. }
  5287. /* Back off if it's too big */
  5288. while (mp_cmp (x, m) != MP_LT) {
  5289. if ((res = s_mp_sub (x, m, x)) != MP_OKAY) {
  5290. goto CLEANUP;
  5291. }
  5292. }
  5293. CLEANUP:
  5294. mp_clear (&q);
  5295. return res;
  5296. }
  5297. /* End: bn_mp_reduce.c */
  5298. /* Start: bn_mp_reduce_2k.c */
  5299. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5300. *
  5301. * LibTomMath is a library that provides multiple-precision
  5302. * integer arithmetic as well as number theoretic functionality.
  5303. *
  5304. * The library was designed directly after the MPI library by
  5305. * Michael Fromberger but has been written from scratch with
  5306. * additional optimizations in place.
  5307. *
  5308. * The library is free for all purposes without any express
  5309. * guarantee it works.
  5310. *
  5311. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5312. */
  5313. #include <ltc_tommath.h>
  5314. /* reduces a modulo n where n is of the form 2**p - d */
  5315. int
  5316. mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d)
  5317. {
  5318. mp_int q;
  5319. int p, res;
  5320. if ((res = mp_init(&q)) != MP_OKAY) {
  5321. return res;
  5322. }
  5323. p = mp_count_bits(n);
  5324. top:
  5325. /* q = a/2**p, a = a mod 2**p */
  5326. if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
  5327. goto ERR;
  5328. }
  5329. if (d != 1) {
  5330. /* q = q * d */
  5331. if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) {
  5332. goto ERR;
  5333. }
  5334. }
  5335. /* a = a + q */
  5336. if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
  5337. goto ERR;
  5338. }
  5339. if (mp_cmp_mag(a, n) != MP_LT) {
  5340. s_mp_sub(a, n, a);
  5341. goto top;
  5342. }
  5343. ERR:
  5344. mp_clear(&q);
  5345. return res;
  5346. }
  5347. /* End: bn_mp_reduce_2k.c */
  5348. /* Start: bn_mp_reduce_2k_setup.c */
  5349. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5350. *
  5351. * LibTomMath is a library that provides multiple-precision
  5352. * integer arithmetic as well as number theoretic functionality.
  5353. *
  5354. * The library was designed directly after the MPI library by
  5355. * Michael Fromberger but has been written from scratch with
  5356. * additional optimizations in place.
  5357. *
  5358. * The library is free for all purposes without any express
  5359. * guarantee it works.
  5360. *
  5361. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5362. */
  5363. #include <ltc_tommath.h>
  5364. /* determines the setup value */
  5365. int
  5366. mp_reduce_2k_setup(mp_int *a, mp_digit *d)
  5367. {
  5368. int res, p;
  5369. mp_int tmp;
  5370. if ((res = mp_init(&tmp)) != MP_OKAY) {
  5371. return res;
  5372. }
  5373. p = mp_count_bits(a);
  5374. if ((res = mp_2expt(&tmp, p)) != MP_OKAY) {
  5375. mp_clear(&tmp);
  5376. return res;
  5377. }
  5378. if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {
  5379. mp_clear(&tmp);
  5380. return res;
  5381. }
  5382. *d = tmp.dp[0];
  5383. mp_clear(&tmp);
  5384. return MP_OKAY;
  5385. }
  5386. /* End: bn_mp_reduce_2k_setup.c */
  5387. /* Start: bn_mp_reduce_is_2k.c */
  5388. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5389. *
  5390. * LibTomMath is a library that provides multiple-precision
  5391. * integer arithmetic as well as number theoretic functionality.
  5392. *
  5393. * The library was designed directly after the MPI library by
  5394. * Michael Fromberger but has been written from scratch with
  5395. * additional optimizations in place.
  5396. *
  5397. * The library is free for all purposes without any express
  5398. * guarantee it works.
  5399. *
  5400. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5401. */
  5402. #include <ltc_tommath.h>
  5403. /* determines if mp_reduce_2k can be used */
  5404. int mp_reduce_is_2k(mp_int *a)
  5405. {
  5406. int ix, iy, iz, iw;
  5407. if (a->used == 0) {
  5408. return 0;
  5409. } else if (a->used == 1) {
  5410. return 1;
  5411. } else if (a->used > 1) {
  5412. iy = mp_count_bits(a);
  5413. iz = 1;
  5414. iw = 1;
  5415. /* Test every bit from the second digit up, must be 1 */
  5416. for (ix = DIGIT_BIT; ix < iy; ix++) {
  5417. if ((a->dp[iw] & iz) == 0) {
  5418. return 0;
  5419. }
  5420. iz <<= 1;
  5421. if (iz > (int)MP_MASK) {
  5422. ++iw;
  5423. iz = 1;
  5424. }
  5425. }
  5426. }
  5427. return 1;
  5428. }
  5429. /* End: bn_mp_reduce_is_2k.c */
  5430. /* Start: bn_mp_reduce_setup.c */
  5431. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5432. *
  5433. * LibTomMath is a library that provides multiple-precision
  5434. * integer arithmetic as well as number theoretic functionality.
  5435. *
  5436. * The library was designed directly after the MPI library by
  5437. * Michael Fromberger but has been written from scratch with
  5438. * additional optimizations in place.
  5439. *
  5440. * The library is free for all purposes without any express
  5441. * guarantee it works.
  5442. *
  5443. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5444. */
  5445. #include <ltc_tommath.h>
  5446. /* pre-calculate the value required for Barrett reduction
  5447. * For a given modulus "b" it calulates the value required in "a"
  5448. */
  5449. int
  5450. mp_reduce_setup (mp_int * a, mp_int * b)
  5451. {
  5452. int res;
  5453. if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {
  5454. return res;
  5455. }
  5456. return mp_div (a, b, a, NULL);
  5457. }
  5458. /* End: bn_mp_reduce_setup.c */
  5459. /* Start: bn_mp_rshd.c */
  5460. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5461. *
  5462. * LibTomMath is a library that provides multiple-precision
  5463. * integer arithmetic as well as number theoretic functionality.
  5464. *
  5465. * The library was designed directly after the MPI library by
  5466. * Michael Fromberger but has been written from scratch with
  5467. * additional optimizations in place.
  5468. *
  5469. * The library is free for all purposes without any express
  5470. * guarantee it works.
  5471. *
  5472. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5473. */
  5474. #include <ltc_tommath.h>
  5475. /* shift right a certain amount of digits */
  5476. void mp_rshd (mp_int * a, int b)
  5477. {
  5478. int x;
  5479. /* if b <= 0 then ignore it */
  5480. if (b <= 0) {
  5481. return;
  5482. }
  5483. /* if b > used then simply zero it and return */
  5484. if (a->used <= b) {
  5485. mp_zero (a);
  5486. return;
  5487. }
  5488. {
  5489. register mp_digit *bottom, *top;
  5490. /* shift the digits down */
  5491. /* bottom */
  5492. bottom = a->dp;
  5493. /* top [offset into digits] */
  5494. top = a->dp + b;
  5495. /* this is implemented as a sliding window where
  5496. * the window is b-digits long and digits from
  5497. * the top of the window are copied to the bottom
  5498. *
  5499. * e.g.
  5500. b-2 | b-1 | b0 | b1 | b2 | ... | bb | ---->
  5501. /\ | ---->
  5502. \-------------------/ ---->
  5503. */
  5504. for (x = 0; x < (a->used - b); x++) {
  5505. *bottom++ = *top++;
  5506. }
  5507. /* zero the top digits */
  5508. for (; x < a->used; x++) {
  5509. *bottom++ = 0;
  5510. }
  5511. }
  5512. /* remove excess digits */
  5513. a->used -= b;
  5514. }
  5515. /* End: bn_mp_rshd.c */
  5516. /* Start: bn_mp_set.c */
  5517. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5518. *
  5519. * LibTomMath is a library that provides multiple-precision
  5520. * integer arithmetic as well as number theoretic functionality.
  5521. *
  5522. * The library was designed directly after the MPI library by
  5523. * Michael Fromberger but has been written from scratch with
  5524. * additional optimizations in place.
  5525. *
  5526. * The library is free for all purposes without any express
  5527. * guarantee it works.
  5528. *
  5529. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5530. */
  5531. #include <ltc_tommath.h>
  5532. /* set to a digit */
  5533. void mp_set (mp_int * a, mp_digit b)
  5534. {
  5535. mp_zero (a);
  5536. a->dp[0] = b & MP_MASK;
  5537. a->used = (a->dp[0] != 0) ? 1 : 0;
  5538. }
  5539. /* End: bn_mp_set.c */
  5540. /* Start: bn_mp_set_int.c */
  5541. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5542. *
  5543. * LibTomMath is a library that provides multiple-precision
  5544. * integer arithmetic as well as number theoretic functionality.
  5545. *
  5546. * The library was designed directly after the MPI library by
  5547. * Michael Fromberger but has been written from scratch with
  5548. * additional optimizations in place.
  5549. *
  5550. * The library is free for all purposes without any express
  5551. * guarantee it works.
  5552. *
  5553. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5554. */
  5555. #include <ltc_tommath.h>
  5556. /* set a 32-bit const */
  5557. int mp_set_int (mp_int * a, unsigned long b)
  5558. {
  5559. int x, res;
  5560. mp_zero (a);
  5561. /* set four bits at a time */
  5562. for (x = 0; x < 8; x++) {
  5563. /* shift the number up four bits */
  5564. if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
  5565. return res;
  5566. }
  5567. /* OR in the top four bits of the source */
  5568. a->dp[0] |= (b >> 28) & 15;
  5569. /* shift the source up to the next four bits */
  5570. b <<= 4;
  5571. /* ensure that digits are not clamped off */
  5572. a->used += 1;
  5573. }
  5574. mp_clamp (a);
  5575. return MP_OKAY;
  5576. }
  5577. /* End: bn_mp_set_int.c */
  5578. /* Start: bn_mp_shrink.c */
  5579. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5580. *
  5581. * LibTomMath is a library that provides multiple-precision
  5582. * integer arithmetic as well as number theoretic functionality.
  5583. *
  5584. * The library was designed directly after the MPI library by
  5585. * Michael Fromberger but has been written from scratch with
  5586. * additional optimizations in place.
  5587. *
  5588. * The library is free for all purposes without any express
  5589. * guarantee it works.
  5590. *
  5591. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5592. */
  5593. #include <ltc_tommath.h>
  5594. /* shrink a bignum */
  5595. int mp_shrink (mp_int * a)
  5596. {
  5597. mp_digit *tmp;
  5598. if (a->alloc != a->used && a->used > 0) {
  5599. if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) {
  5600. return MP_MEM;
  5601. }
  5602. a->dp = tmp;
  5603. a->alloc = a->used;
  5604. }
  5605. return MP_OKAY;
  5606. }
  5607. /* End: bn_mp_shrink.c */
  5608. /* Start: bn_mp_signed_bin_size.c */
  5609. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5610. *
  5611. * LibTomMath is a library that provides multiple-precision
  5612. * integer arithmetic as well as number theoretic functionality.
  5613. *
  5614. * The library was designed directly after the MPI library by
  5615. * Michael Fromberger but has been written from scratch with
  5616. * additional optimizations in place.
  5617. *
  5618. * The library is free for all purposes without any express
  5619. * guarantee it works.
  5620. *
  5621. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5622. */
  5623. #include <ltc_tommath.h>
  5624. /* get the size for an signed equivalent */
  5625. int mp_signed_bin_size (mp_int * a)
  5626. {
  5627. return 1 + mp_unsigned_bin_size (a);
  5628. }
  5629. /* End: bn_mp_signed_bin_size.c */
  5630. /* Start: bn_mp_sqr.c */
  5631. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5632. *
  5633. * LibTomMath is a library that provides multiple-precision
  5634. * integer arithmetic as well as number theoretic functionality.
  5635. *
  5636. * The library was designed directly after the MPI library by
  5637. * Michael Fromberger but has been written from scratch with
  5638. * additional optimizations in place.
  5639. *
  5640. * The library is free for all purposes without any express
  5641. * guarantee it works.
  5642. *
  5643. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5644. */
  5645. #include <ltc_tommath.h>
  5646. /* computes b = a*a */
  5647. int
  5648. mp_sqr (mp_int * a, mp_int * b)
  5649. {
  5650. int res;
  5651. /* use Toom-Cook? */
  5652. if (a->used >= TOOM_SQR_CUTOFF) {
  5653. res = mp_toom_sqr(a, b);
  5654. /* Karatsuba? */
  5655. } else if (a->used >= KARATSUBA_SQR_CUTOFF) {
  5656. res = mp_karatsuba_sqr (a, b);
  5657. } else {
  5658. /* can we use the fast comba multiplier? */
  5659. if ((a->used * 2 + 1) < MP_WARRAY &&
  5660. a->used <
  5661. (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {
  5662. res = fast_s_mp_sqr (a, b);
  5663. } else {
  5664. res = s_mp_sqr (a, b);
  5665. }
  5666. }
  5667. b->sign = MP_ZPOS;
  5668. return res;
  5669. }
  5670. /* End: bn_mp_sqr.c */
  5671. /* Start: bn_mp_sqrmod.c */
  5672. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5673. *
  5674. * LibTomMath is a library that provides multiple-precision
  5675. * integer arithmetic as well as number theoretic functionality.
  5676. *
  5677. * The library was designed directly after the MPI library by
  5678. * Michael Fromberger but has been written from scratch with
  5679. * additional optimizations in place.
  5680. *
  5681. * The library is free for all purposes without any express
  5682. * guarantee it works.
  5683. *
  5684. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5685. */
  5686. #include <ltc_tommath.h>
  5687. /* c = a * a (mod b) */
  5688. int
  5689. mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
  5690. {
  5691. int res;
  5692. mp_int t;
  5693. if ((res = mp_init (&t)) != MP_OKAY) {
  5694. return res;
  5695. }
  5696. if ((res = mp_sqr (a, &t)) != MP_OKAY) {
  5697. mp_clear (&t);
  5698. return res;
  5699. }
  5700. res = mp_mod (&t, b, c);
  5701. mp_clear (&t);
  5702. return res;
  5703. }
  5704. /* End: bn_mp_sqrmod.c */
  5705. /* Start: bn_mp_sqrt.c */
  5706. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5707. *
  5708. * LibTomMath is a library that provides multiple-precision
  5709. * integer arithmetic as well as number theoretic functionality.
  5710. *
  5711. * The library was designed directly after the MPI library by
  5712. * Michael Fromberger but has been written from scratch with
  5713. * additional optimizations in place.
  5714. *
  5715. * The library is free for all purposes without any express
  5716. * guarantee it works.
  5717. *
  5718. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5719. */
  5720. #include <ltc_tommath.h>
  5721. /* this function is less generic than mp_n_root, simpler and faster */
  5722. int mp_sqrt(mp_int *arg, mp_int *ret)
  5723. {
  5724. int res;
  5725. mp_int t1,t2;
  5726. /* must be positive */
  5727. if (arg->sign == MP_NEG) {
  5728. return MP_VAL;
  5729. }
  5730. /* easy out */
  5731. if (mp_iszero(arg) == MP_YES) {
  5732. mp_zero(ret);
  5733. return MP_OKAY;
  5734. }
  5735. if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) {
  5736. return res;
  5737. }
  5738. if ((res = mp_init(&t2)) != MP_OKAY) {
  5739. goto E2;
  5740. }
  5741. /* First approx. (not very bad for large arg) */
  5742. mp_rshd (&t1,t1.used/2);
  5743. /* t1 > 0 */
  5744. if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
  5745. goto E1;
  5746. }
  5747. if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
  5748. goto E1;
  5749. }
  5750. if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
  5751. goto E1;
  5752. }
  5753. /* And now t1 > sqrt(arg) */
  5754. do {
  5755. if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
  5756. goto E1;
  5757. }
  5758. if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
  5759. goto E1;
  5760. }
  5761. if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
  5762. goto E1;
  5763. }
  5764. /* t1 >= sqrt(arg) >= t2 at this point */
  5765. } while (mp_cmp_mag(&t1,&t2) == MP_GT);
  5766. mp_exch(&t1,ret);
  5767. E1: mp_clear(&t2);
  5768. E2: mp_clear(&t1);
  5769. return res;
  5770. }
  5771. /* End: bn_mp_sqrt.c */
  5772. /* Start: bn_mp_sub.c */
  5773. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5774. *
  5775. * LibTomMath is a library that provides multiple-precision
  5776. * integer arithmetic as well as number theoretic functionality.
  5777. *
  5778. * The library was designed directly after the MPI library by
  5779. * Michael Fromberger but has been written from scratch with
  5780. * additional optimizations in place.
  5781. *
  5782. * The library is free for all purposes without any express
  5783. * guarantee it works.
  5784. *
  5785. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5786. */
  5787. #include <ltc_tommath.h>
  5788. /* high level subtraction (handles signs) */
  5789. int
  5790. mp_sub (mp_int * a, mp_int * b, mp_int * c)
  5791. {
  5792. int sa, sb, res;
  5793. sa = a->sign;
  5794. sb = b->sign;
  5795. if (sa != sb) {
  5796. /* subtract a negative from a positive, OR */
  5797. /* subtract a positive from a negative. */
  5798. /* In either case, ADD their magnitudes, */
  5799. /* and use the sign of the first number. */
  5800. c->sign = sa;
  5801. res = s_mp_add (a, b, c);
  5802. } else {
  5803. /* subtract a positive from a positive, OR */
  5804. /* subtract a negative from a negative. */
  5805. /* First, take the difference between their */
  5806. /* magnitudes, then... */
  5807. if (mp_cmp_mag (a, b) != MP_LT) {
  5808. /* Copy the sign from the first */
  5809. c->sign = sa;
  5810. /* The first has a larger or equal magnitude */
  5811. res = s_mp_sub (a, b, c);
  5812. } else {
  5813. /* The result has the *opposite* sign from */
  5814. /* the first number. */
  5815. c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
  5816. /* The second has a larger magnitude */
  5817. res = s_mp_sub (b, a, c);
  5818. }
  5819. }
  5820. return res;
  5821. }
  5822. /* End: bn_mp_sub.c */
  5823. /* Start: bn_mp_sub_d.c */
  5824. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5825. *
  5826. * LibTomMath is a library that provides multiple-precision
  5827. * integer arithmetic as well as number theoretic functionality.
  5828. *
  5829. * The library was designed directly after the MPI library by
  5830. * Michael Fromberger but has been written from scratch with
  5831. * additional optimizations in place.
  5832. *
  5833. * The library is free for all purposes without any express
  5834. * guarantee it works.
  5835. *
  5836. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5837. */
  5838. #include <ltc_tommath.h>
  5839. /* single digit subtraction */
  5840. int
  5841. mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
  5842. {
  5843. mp_digit *tmpa, *tmpc, mu;
  5844. int res, ix, oldused;
  5845. /* grow c as required */
  5846. if (c->alloc < a->used + 1) {
  5847. if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
  5848. return res;
  5849. }
  5850. }
  5851. /* if a is negative just do an unsigned
  5852. * addition [with fudged signs]
  5853. */
  5854. if (a->sign == MP_NEG) {
  5855. a->sign = MP_ZPOS;
  5856. res = mp_add_d(a, b, c);
  5857. a->sign = c->sign = MP_NEG;
  5858. return res;
  5859. }
  5860. /* setup regs */
  5861. oldused = c->used;
  5862. tmpa = a->dp;
  5863. tmpc = c->dp;
  5864. /* if a <= b simply fix the single digit */
  5865. if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
  5866. if (a->used == 1) {
  5867. *tmpc++ = b - *tmpa;
  5868. } else {
  5869. *tmpc++ = b;
  5870. }
  5871. ix = 1;
  5872. /* negative/1digit */
  5873. c->sign = MP_NEG;
  5874. c->used = 1;
  5875. } else {
  5876. /* positive/size */
  5877. c->sign = MP_ZPOS;
  5878. c->used = a->used;
  5879. /* subtract first digit */
  5880. *tmpc = *tmpa++ - b;
  5881. mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
  5882. *tmpc++ &= MP_MASK;
  5883. /* handle rest of the digits */
  5884. for (ix = 1; ix < a->used; ix++) {
  5885. *tmpc = *tmpa++ - mu;
  5886. mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
  5887. *tmpc++ &= MP_MASK;
  5888. }
  5889. }
  5890. /* zero excess digits */
  5891. while (ix++ < oldused) {
  5892. *tmpc++ = 0;
  5893. }
  5894. mp_clamp(c);
  5895. return MP_OKAY;
  5896. }
  5897. /* End: bn_mp_sub_d.c */
  5898. /* Start: bn_mp_submod.c */
  5899. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5900. *
  5901. * LibTomMath is a library that provides multiple-precision
  5902. * integer arithmetic as well as number theoretic functionality.
  5903. *
  5904. * The library was designed directly after the MPI library by
  5905. * Michael Fromberger but has been written from scratch with
  5906. * additional optimizations in place.
  5907. *
  5908. * The library is free for all purposes without any express
  5909. * guarantee it works.
  5910. *
  5911. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5912. */
  5913. #include <ltc_tommath.h>
  5914. /* d = a - b (mod c) */
  5915. int
  5916. mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
  5917. {
  5918. int res;
  5919. mp_int t;
  5920. if ((res = mp_init (&t)) != MP_OKAY) {
  5921. return res;
  5922. }
  5923. if ((res = mp_sub (a, b, &t)) != MP_OKAY) {
  5924. mp_clear (&t);
  5925. return res;
  5926. }
  5927. res = mp_mod (&t, c, d);
  5928. mp_clear (&t);
  5929. return res;
  5930. }
  5931. /* End: bn_mp_submod.c */
  5932. /* Start: bn_mp_to_signed_bin.c */
  5933. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5934. *
  5935. * LibTomMath is a library that provides multiple-precision
  5936. * integer arithmetic as well as number theoretic functionality.
  5937. *
  5938. * The library was designed directly after the MPI library by
  5939. * Michael Fromberger but has been written from scratch with
  5940. * additional optimizations in place.
  5941. *
  5942. * The library is free for all purposes without any express
  5943. * guarantee it works.
  5944. *
  5945. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5946. */
  5947. #include <ltc_tommath.h>
  5948. /* store in signed [big endian] format */
  5949. int
  5950. mp_to_signed_bin (mp_int * a, unsigned char *b)
  5951. {
  5952. int res;
  5953. if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) {
  5954. return res;
  5955. }
  5956. b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1);
  5957. return MP_OKAY;
  5958. }
  5959. /* End: bn_mp_to_signed_bin.c */
  5960. /* Start: bn_mp_to_unsigned_bin.c */
  5961. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  5962. *
  5963. * LibTomMath is a library that provides multiple-precision
  5964. * integer arithmetic as well as number theoretic functionality.
  5965. *
  5966. * The library was designed directly after the MPI library by
  5967. * Michael Fromberger but has been written from scratch with
  5968. * additional optimizations in place.
  5969. *
  5970. * The library is free for all purposes without any express
  5971. * guarantee it works.
  5972. *
  5973. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  5974. */
  5975. #include <ltc_tommath.h>
  5976. /* store in unsigned [big endian] format */
  5977. int
  5978. mp_to_unsigned_bin (mp_int * a, unsigned char *b)
  5979. {
  5980. int x, res;
  5981. mp_int t;
  5982. if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
  5983. return res;
  5984. }
  5985. x = 0;
  5986. while (mp_iszero (&t) == 0) {
  5987. #ifndef MP_8BIT
  5988. b[x++] = (unsigned char) (t.dp[0] & 255);
  5989. #else
  5990. b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));
  5991. #endif
  5992. if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {
  5993. mp_clear (&t);
  5994. return res;
  5995. }
  5996. }
  5997. bn_reverse (b, x);
  5998. mp_clear (&t);
  5999. return MP_OKAY;
  6000. }
  6001. /* End: bn_mp_to_unsigned_bin.c */
  6002. /* Start: bn_mp_toom_mul.c */
  6003. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  6004. *
  6005. * LibTomMath is a library that provides multiple-precision
  6006. * integer arithmetic as well as number theoretic functionality.
  6007. *
  6008. * The library was designed directly after the MPI library by
  6009. * Michael Fromberger but has been written from scratch with
  6010. * additional optimizations in place.
  6011. *
  6012. * The library is free for all purposes without any express
  6013. * guarantee it works.
  6014. *
  6015. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  6016. */
  6017. #include <ltc_tommath.h>
  6018. /* multiplication using the Toom-Cook 3-way algorithm */
  6019. int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
  6020. {
  6021. mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2;
  6022. int res, B;
  6023. /* init temps */
  6024. if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4,
  6025. &a0, &a1, &a2, &b0, &b1,
  6026. &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
  6027. return res;
  6028. }
  6029. /* B */
  6030. B = MIN(a->used, b->used) / 3;
  6031. /* a = a2 * B**2 + a1 * B + a0 */
  6032. if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
  6033. goto ERR;
  6034. }
  6035. if ((res = mp_copy(a, &a1)) != MP_OKAY) {
  6036. goto ERR;
  6037. }
  6038. mp_rshd(&a1, B);
  6039. mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
  6040. if ((res = mp_copy(a, &a2)) != MP_OKAY) {
  6041. goto ERR;
  6042. }
  6043. mp_rshd(&a2, B*2);
  6044. /* b = b2 * B**2 + b1 * B + b0 */
  6045. if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
  6046. goto ERR;
  6047. }
  6048. if ((res = mp_copy(b, &b1)) != MP_OKAY) {
  6049. goto ERR;
  6050. }
  6051. mp_rshd(&b1, B);
  6052. mp_mod_2d(&b1, DIGIT_BIT * B, &b1);
  6053. if ((res = mp_copy(b, &b2)) != MP_OKAY) {
  6054. goto ERR;
  6055. }
  6056. mp_rshd(&b2, B*2);
  6057. /* w0 = a0*b0 */
  6058. if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) {
  6059. goto ERR;
  6060. }
  6061. /* w4 = a2 * b2 */
  6062. if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) {
  6063. goto ERR;
  6064. }
  6065. /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */
  6066. if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
  6067. goto ERR;
  6068. }
  6069. if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
  6070. goto ERR;
  6071. }
  6072. if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
  6073. goto ERR;
  6074. }
  6075. if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
  6076. goto ERR;
  6077. }
  6078. if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) {
  6079. goto ERR;
  6080. }
  6081. if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
  6082. goto ERR;
  6083. }
  6084. if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
  6085. goto ERR;
  6086. }
  6087. if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) {
  6088. goto ERR;
  6089. }
  6090. if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) {
  6091. goto ERR;
  6092. }
  6093. /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */
  6094. if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
  6095. goto ERR;
  6096. }
  6097. if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
  6098. goto ERR;
  6099. }
  6100. if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
  6101. goto ERR;
  6102. }
  6103. if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
  6104. goto ERR;
  6105. }
  6106. if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) {
  6107. goto ERR;
  6108. }
  6109. if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
  6110. goto ERR;
  6111. }
  6112. if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
  6113. goto ERR;
  6114. }
  6115. if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
  6116. goto ERR;
  6117. }
  6118. if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) {
  6119. goto ERR;
  6120. }
  6121. /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */
  6122. if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
  6123. goto ERR;
  6124. }
  6125. if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
  6126. goto ERR;
  6127. }
  6128. if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) {
  6129. goto ERR;
  6130. }
  6131. if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
  6132. goto ERR;
  6133. }
  6134. if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) {
  6135. goto ERR;
  6136. }
  6137. /* now solve the matrix
  6138. 0 0 0 0 1
  6139. 1 2 4 8 16
  6140. 1 1 1 1 1
  6141. 16 8 4 2 1
  6142. 1 0 0 0 0
  6143. using 12 subtractions, 4 shifts,
  6144. 2 small divisions and 1 small multiplication
  6145. */
  6146. /* r1 - r4 */
  6147. if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
  6148. goto ERR;
  6149. }
  6150. /* r3 - r0 */
  6151. if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
  6152. goto ERR;
  6153. }
  6154. /* r1/2 */
  6155. if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
  6156. goto ERR;
  6157. }
  6158. /* r3/2 */
  6159. if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
  6160. goto ERR;
  6161. }
  6162. /* r2 - r0 - r4 */
  6163. if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
  6164. goto ERR;
  6165. }
  6166. if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
  6167. goto ERR;
  6168. }
  6169. /* r1 - r2 */
  6170. if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
  6171. goto ERR;
  6172. }
  6173. /* r3 - r2 */
  6174. if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
  6175. goto ERR;
  6176. }
  6177. /* r1 - 8r0 */
  6178. if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
  6179. goto ERR;
  6180. }
  6181. if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
  6182. goto ERR;
  6183. }
  6184. /* r3 - 8r4 */
  6185. if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
  6186. goto ERR;
  6187. }
  6188. if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
  6189. goto ERR;
  6190. }
  6191. /* 3r2 - r1 - r3 */
  6192. if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
  6193. goto ERR;
  6194. }
  6195. if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
  6196. goto ERR;
  6197. }
  6198. if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
  6199. goto ERR;
  6200. }
  6201. /* r1 - r2 */
  6202. if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
  6203. goto ERR;
  6204. }
  6205. /* r3 - r2 */
  6206. if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
  6207. goto ERR;
  6208. }
  6209. /* r1/3 */
  6210. if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
  6211. goto ERR;
  6212. }
  6213. /* r3/3 */
  6214. if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
  6215. goto ERR;
  6216. }
  6217. /* at this point shift W[n] by B*n */
  6218. if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
  6219. goto ERR;
  6220. }
  6221. if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
  6222. goto ERR;
  6223. }
  6224. if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
  6225. goto ERR;
  6226. }
  6227. if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
  6228. goto ERR;
  6229. }
  6230. if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) {
  6231. goto ERR;
  6232. }
  6233. if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
  6234. goto ERR;
  6235. }
  6236. if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
  6237. goto ERR;
  6238. }
  6239. if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) {
  6240. goto ERR;
  6241. }
  6242. ERR:
  6243. mp_clear_multi(&w0, &w1, &w2, &w3, &w4,
  6244. &a0, &a1, &a2, &b0, &b1,
  6245. &b2, &tmp1, &tmp2, NULL);
  6246. return res;
  6247. }
  6248. /* End: bn_mp_toom_mul.c */
  6249. /* Start: bn_mp_toom_sqr.c */
  6250. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  6251. *
  6252. * LibTomMath is a library that provides multiple-precision
  6253. * integer arithmetic as well as number theoretic functionality.
  6254. *
  6255. * The library was designed directly after the MPI library by
  6256. * Michael Fromberger but has been written from scratch with
  6257. * additional optimizations in place.
  6258. *
  6259. * The library is free for all purposes without any express
  6260. * guarantee it works.
  6261. *
  6262. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  6263. */
  6264. #include <ltc_tommath.h>
  6265. /* squaring using Toom-Cook 3-way algorithm */
  6266. int
  6267. mp_toom_sqr(mp_int *a, mp_int *b)
  6268. {
  6269. mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
  6270. int res, B;
  6271. /* init temps */
  6272. if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) {
  6273. return res;
  6274. }
  6275. /* B */
  6276. B = a->used / 3;
  6277. /* a = a2 * B**2 + a1 * B + a0 */
  6278. if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
  6279. goto ERR;
  6280. }
  6281. if ((res = mp_copy(a, &a1)) != MP_OKAY) {
  6282. goto ERR;
  6283. }
  6284. mp_rshd(&a1, B);
  6285. mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
  6286. if ((res = mp_copy(a, &a2)) != MP_OKAY) {
  6287. goto ERR;
  6288. }
  6289. mp_rshd(&a2, B*2);
  6290. /* w0 = a0*a0 */
  6291. if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) {
  6292. goto ERR;
  6293. }
  6294. /* w4 = a2 * a2 */
  6295. if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) {
  6296. goto ERR;
  6297. }
  6298. /* w1 = (a2 + 2(a1 + 2a0))**2 */
  6299. if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
  6300. goto ERR;
  6301. }
  6302. if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
  6303. goto ERR;
  6304. }
  6305. if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
  6306. goto ERR;
  6307. }
  6308. if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
  6309. goto ERR;
  6310. }
  6311. if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) {
  6312. goto ERR;
  6313. }
  6314. /* w3 = (a0 + 2(a1 + 2a2))**2 */
  6315. if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
  6316. goto ERR;
  6317. }
  6318. if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
  6319. goto ERR;
  6320. }
  6321. if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
  6322. goto ERR;
  6323. }
  6324. if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
  6325. goto ERR;
  6326. }
  6327. if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) {
  6328. goto ERR;
  6329. }
  6330. /* w2 = (a2 + a1 + a0)**2 */
  6331. if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
  6332. goto ERR;
  6333. }
  6334. if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
  6335. goto ERR;
  6336. }
  6337. if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) {
  6338. goto ERR;
  6339. }
  6340. /* now solve the matrix
  6341. 0 0 0 0 1
  6342. 1 2 4 8 16
  6343. 1 1 1 1 1
  6344. 16 8 4 2 1
  6345. 1 0 0 0 0
  6346. using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
  6347. */
  6348. /* r1 - r4 */
  6349. if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
  6350. goto ERR;
  6351. }
  6352. /* r3 - r0 */
  6353. if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
  6354. goto ERR;
  6355. }
  6356. /* r1/2 */
  6357. if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
  6358. goto ERR;
  6359. }
  6360. /* r3/2 */
  6361. if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
  6362. goto ERR;
  6363. }
  6364. /* r2 - r0 - r4 */
  6365. if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
  6366. goto ERR;
  6367. }
  6368. if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
  6369. goto ERR;
  6370. }
  6371. /* r1 - r2 */
  6372. if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
  6373. goto ERR;
  6374. }
  6375. /* r3 - r2 */
  6376. if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
  6377. goto ERR;
  6378. }
  6379. /* r1 - 8r0 */
  6380. if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
  6381. goto ERR;
  6382. }
  6383. if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
  6384. goto ERR;
  6385. }
  6386. /* r3 - 8r4 */
  6387. if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
  6388. goto ERR;
  6389. }
  6390. if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
  6391. goto ERR;
  6392. }
  6393. /* 3r2 - r1 - r3 */
  6394. if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
  6395. goto ERR;
  6396. }
  6397. if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
  6398. goto ERR;
  6399. }
  6400. if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
  6401. goto ERR;
  6402. }
  6403. /* r1 - r2 */
  6404. if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
  6405. goto ERR;
  6406. }
  6407. /* r3 - r2 */
  6408. if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
  6409. goto ERR;
  6410. }
  6411. /* r1/3 */
  6412. if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
  6413. goto ERR;
  6414. }
  6415. /* r3/3 */
  6416. if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
  6417. goto ERR;
  6418. }
  6419. /* at this point shift W[n] by B*n */
  6420. if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
  6421. goto ERR;
  6422. }
  6423. if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
  6424. goto ERR;
  6425. }
  6426. if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
  6427. goto ERR;
  6428. }
  6429. if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
  6430. goto ERR;
  6431. }
  6432. if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) {
  6433. goto ERR;
  6434. }
  6435. if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
  6436. goto ERR;
  6437. }
  6438. if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
  6439. goto ERR;
  6440. }
  6441. if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) {
  6442. goto ERR;
  6443. }
  6444. ERR:
  6445. mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL);
  6446. return res;
  6447. }
  6448. /* End: bn_mp_toom_sqr.c */
  6449. /* Start: bn_mp_toradix.c */
  6450. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  6451. *
  6452. * LibTomMath is a library that provides multiple-precision
  6453. * integer arithmetic as well as number theoretic functionality.
  6454. *
  6455. * The library was designed directly after the MPI library by
  6456. * Michael Fromberger but has been written from scratch with
  6457. * additional optimizations in place.
  6458. *
  6459. * The library is free for all purposes without any express
  6460. * guarantee it works.
  6461. *
  6462. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  6463. */
  6464. #include <ltc_tommath.h>
  6465. /* stores a bignum as a ASCII string in a given radix (2..64) */
  6466. int mp_toradix (mp_int * a, char *str, int radix)
  6467. {
  6468. int res, digs;
  6469. mp_int t;
  6470. mp_digit d;
  6471. char *_s = str;
  6472. /* check range of the radix */
  6473. if (radix < 2 || radix > 64) {
  6474. return MP_VAL;
  6475. }
  6476. /* quick out if its zero */
  6477. if (mp_iszero(a) == 1) {
  6478. *str++ = '0';
  6479. *str = '\0';
  6480. return MP_OKAY;
  6481. }
  6482. if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
  6483. return res;
  6484. }
  6485. /* if it is negative output a - */
  6486. if (t.sign == MP_NEG) {
  6487. ++_s;
  6488. *str++ = '-';
  6489. t.sign = MP_ZPOS;
  6490. }
  6491. digs = 0;
  6492. while (mp_iszero (&t) == 0) {
  6493. if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
  6494. mp_clear (&t);
  6495. return res;
  6496. }
  6497. *str++ = mp_s_rmap[d];
  6498. ++digs;
  6499. }
  6500. /* reverse the digits of the string. In this case _s points
  6501. * to the first digit [exluding the sign] of the number]
  6502. */
  6503. bn_reverse ((unsigned char *)_s, digs);
  6504. /* append a NULL so the string is properly terminated */
  6505. *str = '\0';
  6506. mp_clear (&t);
  6507. return MP_OKAY;
  6508. }
  6509. /* End: bn_mp_toradix.c */
  6510. /* Start: bn_mp_toradix_n.c */
  6511. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  6512. *
  6513. * LibTomMath is a library that provides multiple-precision
  6514. * integer arithmetic as well as number theoretic functionality.
  6515. *
  6516. * The library was designed directly after the MPI library by
  6517. * Michael Fromberger but has been written from scratch with
  6518. * additional optimizations in place.
  6519. *
  6520. * The library is free for all purposes without any express
  6521. * guarantee it works.
  6522. *
  6523. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  6524. */
  6525. #include <ltc_tommath.h>
  6526. /* stores a bignum as a ASCII string in a given radix (2..64)
  6527. *
  6528. * Stores upto maxlen-1 chars and always a NULL byte
  6529. */
  6530. int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen)
  6531. {
  6532. int res, digs;
  6533. mp_int t;
  6534. mp_digit d;
  6535. char *_s = str;
  6536. /* check range of the maxlen, radix */
  6537. if (maxlen < 3 || radix < 2 || radix > 64) {
  6538. return MP_VAL;
  6539. }
  6540. /* quick out if its zero */
  6541. if (mp_iszero(a) == 1) {
  6542. *str++ = '0';
  6543. *str = '\0';
  6544. return MP_OKAY;
  6545. }
  6546. if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
  6547. return res;
  6548. }
  6549. /* if it is negative output a - */
  6550. if (t.sign == MP_NEG) {
  6551. /* we have to reverse our digits later... but not the - sign!! */
  6552. ++_s;
  6553. /* store the flag and mark the number as positive */
  6554. *str++ = '-';
  6555. t.sign = MP_ZPOS;
  6556. /* subtract a char */
  6557. --maxlen;
  6558. }
  6559. digs = 0;
  6560. while (mp_iszero (&t) == 0) {
  6561. if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
  6562. mp_clear (&t);
  6563. return res;
  6564. }
  6565. *str++ = mp_s_rmap[d];
  6566. ++digs;
  6567. if (--maxlen == 1) {
  6568. /* no more room */
  6569. break;
  6570. }
  6571. }
  6572. /* reverse the digits of the string. In this case _s points
  6573. * to the first digit [exluding the sign] of the number]
  6574. */
  6575. bn_reverse ((unsigned char *)_s, digs);
  6576. /* append a NULL so the string is properly terminated */
  6577. *str = '\0';
  6578. mp_clear (&t);
  6579. return MP_OKAY;
  6580. }
  6581. /* End: bn_mp_toradix_n.c */
  6582. /* Start: bn_mp_unsigned_bin_size.c */
  6583. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  6584. *
  6585. * LibTomMath is a library that provides multiple-precision
  6586. * integer arithmetic as well as number theoretic functionality.
  6587. *
  6588. * The library was designed directly after the MPI library by
  6589. * Michael Fromberger but has been written from scratch with
  6590. * additional optimizations in place.
  6591. *
  6592. * The library is free for all purposes without any express
  6593. * guarantee it works.
  6594. *
  6595. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  6596. */
  6597. #include <ltc_tommath.h>
  6598. /* get the size for an unsigned equivalent */
  6599. int
  6600. mp_unsigned_bin_size (mp_int * a)
  6601. {
  6602. int size = mp_count_bits (a);
  6603. return (size / 8 + ((size & 7) != 0 ? 1 : 0));
  6604. }
  6605. /* End: bn_mp_unsigned_bin_size.c */
  6606. /* Start: bn_mp_xor.c */
  6607. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  6608. *
  6609. * LibTomMath is a library that provides multiple-precision
  6610. * integer arithmetic as well as number theoretic functionality.
  6611. *
  6612. * The library was designed directly after the MPI library by
  6613. * Michael Fromberger but has been written from scratch with
  6614. * additional optimizations in place.
  6615. *
  6616. * The library is free for all purposes without any express
  6617. * guarantee it works.
  6618. *
  6619. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  6620. */
  6621. #include <ltc_tommath.h>
  6622. /* XOR two ints together */
  6623. int
  6624. mp_xor (mp_int * a, mp_int * b, mp_int * c)
  6625. {
  6626. int res, ix, px;
  6627. mp_int t, *x;
  6628. if (a->used > b->used) {
  6629. if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
  6630. return res;
  6631. }
  6632. px = b->used;
  6633. x = b;
  6634. } else {
  6635. if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
  6636. return res;
  6637. }
  6638. px = a->used;
  6639. x = a;
  6640. }
  6641. for (ix = 0; ix < px; ix++) {
  6642. t.dp[ix] ^= x->dp[ix];
  6643. }
  6644. mp_clamp (&t);
  6645. mp_exch (c, &t);
  6646. mp_clear (&t);
  6647. return MP_OKAY;
  6648. }
  6649. /* End: bn_mp_xor.c */
  6650. /* Start: bn_mp_zero.c */
  6651. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  6652. *
  6653. * LibTomMath is a library that provides multiple-precision
  6654. * integer arithmetic as well as number theoretic functionality.
  6655. *
  6656. * The library was designed directly after the MPI library by
  6657. * Michael Fromberger but has been written from scratch with
  6658. * additional optimizations in place.
  6659. *
  6660. * The library is free for all purposes without any express
  6661. * guarantee it works.
  6662. *
  6663. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  6664. */
  6665. #include <ltc_tommath.h>
  6666. /* set to zero */
  6667. void
  6668. mp_zero (mp_int * a)
  6669. {
  6670. a->sign = MP_ZPOS;
  6671. a->used = 0;
  6672. memset (a->dp, 0, sizeof (mp_digit) * a->alloc);
  6673. }
  6674. /* End: bn_mp_zero.c */
  6675. /* Start: bn_prime_sizes_tab.c */
  6676. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  6677. *
  6678. * LibTomMath is a library that provides multiple-precision
  6679. * integer arithmetic as well as number theoretic functionality.
  6680. *
  6681. * The library was designed directly after the MPI library by
  6682. * Michael Fromberger but has been written from scratch with
  6683. * additional optimizations in place.
  6684. *
  6685. * The library is free for all purposes without any express
  6686. * guarantee it works.
  6687. *
  6688. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  6689. */
  6690. #include <ltc_tommath.h>
  6691. /* this table gives the # of rabin miller trials for a prob of failure lower than 2^-96 */
  6692. static const struct {
  6693. int k, t;
  6694. } sizes[] = {
  6695. { 128, 28 },
  6696. { 256, 16 },
  6697. { 384, 10 },
  6698. { 512, 7 },
  6699. { 640, 6 },
  6700. { 768, 5 },
  6701. { 896, 4 },
  6702. { 1024, 4 },
  6703. { 1152, 3 },
  6704. { 1280, 3 },
  6705. { 1408, 3 },
  6706. { 1536, 3 },
  6707. { 1664, 3 },
  6708. { 1792, 2 } };
  6709. /* returns # of RM trials required for a given bit size */
  6710. int mp_prime_rabin_miller_trials(int size)
  6711. {
  6712. int x;
  6713. for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) {
  6714. if (sizes[x].k == size) {
  6715. return sizes[x].t;
  6716. } else if (sizes[x].k > size) {
  6717. return (x == 0) ? sizes[0].t : sizes[x - 1].t;
  6718. }
  6719. }
  6720. return 1;
  6721. }
  6722. /* End: bn_prime_sizes_tab.c */
  6723. /* Start: bn_prime_tab.c */
  6724. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  6725. *
  6726. * LibTomMath is a library that provides multiple-precision
  6727. * integer arithmetic as well as number theoretic functionality.
  6728. *
  6729. * The library was designed directly after the MPI library by
  6730. * Michael Fromberger but has been written from scratch with
  6731. * additional optimizations in place.
  6732. *
  6733. * The library is free for all purposes without any express
  6734. * guarantee it works.
  6735. *
  6736. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  6737. */
  6738. #include <ltc_tommath.h>
  6739. const mp_digit __prime_tab[] = {
  6740. 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
  6741. 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
  6742. 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
  6743. 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
  6744. #ifndef MP_8BIT
  6745. 0x0083,
  6746. 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
  6747. 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
  6748. 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
  6749. 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
  6750. 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
  6751. 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
  6752. 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
  6753. 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
  6754. 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
  6755. 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
  6756. 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
  6757. 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
  6758. 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
  6759. 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
  6760. 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
  6761. 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
  6762. 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
  6763. 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
  6764. 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
  6765. 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
  6766. 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
  6767. 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
  6768. 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
  6769. 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
  6770. 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
  6771. 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
  6772. 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
  6773. 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
  6774. #endif
  6775. };
  6776. /* End: bn_prime_tab.c */
  6777. /* Start: bn_reverse.c */
  6778. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  6779. *
  6780. * LibTomMath is a library that provides multiple-precision
  6781. * integer arithmetic as well as number theoretic functionality.
  6782. *
  6783. * The library was designed directly after the MPI library by
  6784. * Michael Fromberger but has been written from scratch with
  6785. * additional optimizations in place.
  6786. *
  6787. * The library is free for all purposes without any express
  6788. * guarantee it works.
  6789. *
  6790. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  6791. */
  6792. #include <ltc_tommath.h>
  6793. /* reverse an array, used for radix code */
  6794. void
  6795. bn_reverse (unsigned char *s, int len)
  6796. {
  6797. int ix, iy;
  6798. unsigned char t;
  6799. ix = 0;
  6800. iy = len - 1;
  6801. while (ix < iy) {
  6802. t = s[ix];
  6803. s[ix] = s[iy];
  6804. s[iy] = t;
  6805. ++ix;
  6806. --iy;
  6807. }
  6808. }
  6809. /* End: bn_reverse.c */
  6810. /* Start: bn_s_mp_add.c */
  6811. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  6812. *
  6813. * LibTomMath is a library that provides multiple-precision
  6814. * integer arithmetic as well as number theoretic functionality.
  6815. *
  6816. * The library was designed directly after the MPI library by
  6817. * Michael Fromberger but has been written from scratch with
  6818. * additional optimizations in place.
  6819. *
  6820. * The library is free for all purposes without any express
  6821. * guarantee it works.
  6822. *
  6823. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  6824. */
  6825. #include <ltc_tommath.h>
  6826. /* low level addition, based on HAC pp.594, Algorithm 14.7 */
  6827. int
  6828. s_mp_add (mp_int * a, mp_int * b, mp_int * c)
  6829. {
  6830. mp_int *x;
  6831. int olduse, res, min, max;
  6832. /* find sizes, we let |a| <= |b| which means we have to sort
  6833. * them. "x" will point to the input with the most digits
  6834. */
  6835. if (a->used > b->used) {
  6836. min = b->used;
  6837. max = a->used;
  6838. x = a;
  6839. } else {
  6840. min = a->used;
  6841. max = b->used;
  6842. x = b;
  6843. }
  6844. /* init result */
  6845. if (c->alloc < max + 1) {
  6846. if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
  6847. return res;
  6848. }
  6849. }
  6850. /* get old used digit count and set new one */
  6851. olduse = c->used;
  6852. c->used = max + 1;
  6853. {
  6854. register mp_digit u, *tmpa, *tmpb, *tmpc;
  6855. register int i;
  6856. /* alias for digit pointers */
  6857. /* first input */
  6858. tmpa = a->dp;
  6859. /* second input */
  6860. tmpb = b->dp;
  6861. /* destination */
  6862. tmpc = c->dp;
  6863. /* zero the carry */
  6864. u = 0;
  6865. for (i = 0; i < min; i++) {
  6866. /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
  6867. *tmpc = *tmpa++ + *tmpb++ + u;
  6868. /* U = carry bit of T[i] */
  6869. u = *tmpc >> ((mp_digit)DIGIT_BIT);
  6870. /* take away carry bit from T[i] */
  6871. *tmpc++ &= MP_MASK;
  6872. }
  6873. /* now copy higher words if any, that is in A+B
  6874. * if A or B has more digits add those in
  6875. */
  6876. if (min != max) {
  6877. for (; i < max; i++) {
  6878. /* T[i] = X[i] + U */
  6879. *tmpc = x->dp[i] + u;
  6880. /* U = carry bit of T[i] */
  6881. u = *tmpc >> ((mp_digit)DIGIT_BIT);
  6882. /* take away carry bit from T[i] */
  6883. *tmpc++ &= MP_MASK;
  6884. }
  6885. }
  6886. /* add carry */
  6887. *tmpc++ = u;
  6888. /* clear digits above oldused */
  6889. for (i = c->used; i < olduse; i++) {
  6890. *tmpc++ = 0;
  6891. }
  6892. }
  6893. mp_clamp (c);
  6894. return MP_OKAY;
  6895. }
  6896. /* End: bn_s_mp_add.c */
  6897. /* Start: bn_s_mp_exptmod.c */
  6898. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  6899. *
  6900. * LibTomMath is a library that provides multiple-precision
  6901. * integer arithmetic as well as number theoretic functionality.
  6902. *
  6903. * The library was designed directly after the MPI library by
  6904. * Michael Fromberger but has been written from scratch with
  6905. * additional optimizations in place.
  6906. *
  6907. * The library is free for all purposes without any express
  6908. * guarantee it works.
  6909. *
  6910. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  6911. */
  6912. #include <ltc_tommath.h>
  6913. #ifdef MP_LOW_MEM
  6914. #define TAB_SIZE 32
  6915. #else
  6916. #define TAB_SIZE 256
  6917. #endif
  6918. int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
  6919. {
  6920. mp_int M[TAB_SIZE], res, mu;
  6921. mp_digit buf;
  6922. int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
  6923. /* find window size */
  6924. x = mp_count_bits (X);
  6925. if (x <= 7) {
  6926. winsize = 2;
  6927. } else if (x <= 36) {
  6928. winsize = 3;
  6929. } else if (x <= 140) {
  6930. winsize = 4;
  6931. } else if (x <= 450) {
  6932. winsize = 5;
  6933. } else if (x <= 1303) {
  6934. winsize = 6;
  6935. } else if (x <= 3529) {
  6936. winsize = 7;
  6937. } else {
  6938. winsize = 8;
  6939. }
  6940. #ifdef MP_LOW_MEM
  6941. if (winsize > 5) {
  6942. winsize = 5;
  6943. }
  6944. #endif
  6945. /* init M array */
  6946. /* init first cell */
  6947. if ((err = mp_init(&M[1])) != MP_OKAY) {
  6948. return err;
  6949. }
  6950. /* now init the second half of the array */
  6951. for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
  6952. if ((err = mp_init(&M[x])) != MP_OKAY) {
  6953. for (y = 1<<(winsize-1); y < x; y++) {
  6954. mp_clear (&M[y]);
  6955. }
  6956. mp_clear(&M[1]);
  6957. return err;
  6958. }
  6959. }
  6960. /* create mu, used for Barrett reduction */
  6961. if ((err = mp_init (&mu)) != MP_OKAY) {
  6962. goto __M;
  6963. }
  6964. if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {
  6965. goto __MU;
  6966. }
  6967. /* create M table
  6968. *
  6969. * The M table contains powers of the base,
  6970. * e.g. M[x] = G**x mod P
  6971. *
  6972. * The first half of the table is not
  6973. * computed though accept for M[0] and M[1]
  6974. */
  6975. if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
  6976. goto __MU;
  6977. }
  6978. /* compute the value at M[1<<(winsize-1)] by squaring
  6979. * M[1] (winsize-1) times
  6980. */
  6981. if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
  6982. goto __MU;
  6983. }
  6984. for (x = 0; x < (winsize - 1); x++) {
  6985. if ((err = mp_sqr (&M[1 << (winsize - 1)],
  6986. &M[1 << (winsize - 1)])) != MP_OKAY) {
  6987. goto __MU;
  6988. }
  6989. if ((err = mp_reduce (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
  6990. goto __MU;
  6991. }
  6992. }
  6993. /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
  6994. * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
  6995. */
  6996. for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
  6997. if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
  6998. goto __MU;
  6999. }
  7000. if ((err = mp_reduce (&M[x], P, &mu)) != MP_OKAY) {
  7001. goto __MU;
  7002. }
  7003. }
  7004. /* setup result */
  7005. if ((err = mp_init (&res)) != MP_OKAY) {
  7006. goto __MU;
  7007. }
  7008. mp_set (&res, 1);
  7009. /* set initial mode and bit cnt */
  7010. mode = 0;
  7011. bitcnt = 1;
  7012. buf = 0;
  7013. digidx = X->used - 1;
  7014. bitcpy = 0;
  7015. bitbuf = 0;
  7016. for (;;) {
  7017. /* grab next digit as required */
  7018. if (--bitcnt == 0) {
  7019. /* if digidx == -1 we are out of digits */
  7020. if (digidx == -1) {
  7021. break;
  7022. }
  7023. /* read next digit and reset the bitcnt */
  7024. buf = X->dp[digidx--];
  7025. bitcnt = (int) DIGIT_BIT;
  7026. }
  7027. /* grab the next msb from the exponent */
  7028. y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1;
  7029. buf <<= (mp_digit)1;
  7030. /* if the bit is zero and mode == 0 then we ignore it
  7031. * These represent the leading zero bits before the first 1 bit
  7032. * in the exponent. Technically this opt is not required but it
  7033. * does lower the # of trivial squaring/reductions used
  7034. */
  7035. if (mode == 0 && y == 0) {
  7036. continue;
  7037. }
  7038. /* if the bit is zero and mode == 1 then we square */
  7039. if (mode == 1 && y == 0) {
  7040. if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
  7041. goto __RES;
  7042. }
  7043. if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) {
  7044. goto __RES;
  7045. }
  7046. continue;
  7047. }
  7048. /* else we add it to the window */
  7049. bitbuf |= (y << (winsize - ++bitcpy));
  7050. mode = 2;
  7051. if (bitcpy == winsize) {
  7052. /* ok window is filled so square as required and multiply */
  7053. /* square first */
  7054. for (x = 0; x < winsize; x++) {
  7055. if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
  7056. goto __RES;
  7057. }
  7058. if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) {
  7059. goto __RES;
  7060. }
  7061. }
  7062. /* then multiply */
  7063. if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
  7064. goto __RES;
  7065. }
  7066. if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) {
  7067. goto __RES;
  7068. }
  7069. /* empty window and reset */
  7070. bitcpy = 0;
  7071. bitbuf = 0;
  7072. mode = 1;
  7073. }
  7074. }
  7075. /* if bits remain then square/multiply */
  7076. if (mode == 2 && bitcpy > 0) {
  7077. /* square then multiply if the bit is set */
  7078. for (x = 0; x < bitcpy; x++) {
  7079. if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
  7080. goto __RES;
  7081. }
  7082. if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) {
  7083. goto __RES;
  7084. }
  7085. bitbuf <<= 1;
  7086. if ((bitbuf & (1 << winsize)) != 0) {
  7087. /* then multiply */
  7088. if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
  7089. goto __RES;
  7090. }
  7091. if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) {
  7092. goto __RES;
  7093. }
  7094. }
  7095. }
  7096. }
  7097. mp_exch (&res, Y);
  7098. err = MP_OKAY;
  7099. __RES:mp_clear (&res);
  7100. __MU:mp_clear (&mu);
  7101. __M:
  7102. mp_clear(&M[1]);
  7103. for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
  7104. mp_clear (&M[x]);
  7105. }
  7106. return err;
  7107. }
  7108. /* End: bn_s_mp_exptmod.c */
  7109. /* Start: bn_s_mp_mul_digs.c */
  7110. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  7111. *
  7112. * LibTomMath is a library that provides multiple-precision
  7113. * integer arithmetic as well as number theoretic functionality.
  7114. *
  7115. * The library was designed directly after the MPI library by
  7116. * Michael Fromberger but has been written from scratch with
  7117. * additional optimizations in place.
  7118. *
  7119. * The library is free for all purposes without any express
  7120. * guarantee it works.
  7121. *
  7122. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  7123. */
  7124. #include <ltc_tommath.h>
  7125. /* multiplies |a| * |b| and only computes upto digs digits of result
  7126. * HAC pp. 595, Algorithm 14.12 Modified so you can control how
  7127. * many digits of output are created.
  7128. */
  7129. int
  7130. s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
  7131. {
  7132. mp_int t;
  7133. int res, pa, pb, ix, iy;
  7134. mp_digit u;
  7135. mp_word r;
  7136. mp_digit tmpx, *tmpt, *tmpy;
  7137. /* can we use the fast multiplier? */
  7138. if (((digs) < MP_WARRAY) &&
  7139. MIN (a->used, b->used) <
  7140. (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
  7141. return fast_s_mp_mul_digs (a, b, c, digs);
  7142. }
  7143. if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
  7144. return res;
  7145. }
  7146. t.used = digs;
  7147. /* compute the digits of the product directly */
  7148. pa = a->used;
  7149. for (ix = 0; ix < pa; ix++) {
  7150. /* set the carry to zero */
  7151. u = 0;
  7152. /* limit ourselves to making digs digits of output */
  7153. pb = MIN (b->used, digs - ix);
  7154. /* setup some aliases */
  7155. /* copy of the digit from a used within the nested loop */
  7156. tmpx = a->dp[ix];
  7157. /* an alias for the destination shifted ix places */
  7158. tmpt = t.dp + ix;
  7159. /* an alias for the digits of b */
  7160. tmpy = b->dp;
  7161. /* compute the columns of the output and propagate the carry */
  7162. for (iy = 0; iy < pb; iy++) {
  7163. /* compute the column as a mp_word */
  7164. r = ((mp_word)*tmpt) +
  7165. ((mp_word)tmpx) * ((mp_word)*tmpy++) +
  7166. ((mp_word) u);
  7167. /* the new column is the lower part of the result */
  7168. *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
  7169. /* get the carry word from the result */
  7170. u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
  7171. }
  7172. /* set carry if it is placed below digs */
  7173. if (ix + iy < digs) {
  7174. *tmpt = u;
  7175. }
  7176. }
  7177. mp_clamp (&t);
  7178. mp_exch (&t, c);
  7179. mp_clear (&t);
  7180. return MP_OKAY;
  7181. }
  7182. /* End: bn_s_mp_mul_digs.c */
  7183. /* Start: bn_s_mp_mul_high_digs.c */
  7184. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  7185. *
  7186. * LibTomMath is a library that provides multiple-precision
  7187. * integer arithmetic as well as number theoretic functionality.
  7188. *
  7189. * The library was designed directly after the MPI library by
  7190. * Michael Fromberger but has been written from scratch with
  7191. * additional optimizations in place.
  7192. *
  7193. * The library is free for all purposes without any express
  7194. * guarantee it works.
  7195. *
  7196. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  7197. */
  7198. #include <ltc_tommath.h>
  7199. /* multiplies |a| * |b| and does not compute the lower digs digits
  7200. * [meant to get the higher part of the product]
  7201. */
  7202. int
  7203. s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
  7204. {
  7205. mp_int t;
  7206. int res, pa, pb, ix, iy;
  7207. mp_digit u;
  7208. mp_word r;
  7209. mp_digit tmpx, *tmpt, *tmpy;
  7210. /* can we use the fast multiplier? */
  7211. if (((a->used + b->used + 1) < MP_WARRAY)
  7212. && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
  7213. return fast_s_mp_mul_high_digs (a, b, c, digs);
  7214. }
  7215. if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) {
  7216. return res;
  7217. }
  7218. t.used = a->used + b->used + 1;
  7219. pa = a->used;
  7220. pb = b->used;
  7221. for (ix = 0; ix < pa; ix++) {
  7222. /* clear the carry */
  7223. u = 0;
  7224. /* left hand side of A[ix] * B[iy] */
  7225. tmpx = a->dp[ix];
  7226. /* alias to the address of where the digits will be stored */
  7227. tmpt = &(t.dp[digs]);
  7228. /* alias for where to read the right hand side from */
  7229. tmpy = b->dp + (digs - ix);
  7230. for (iy = digs - ix; iy < pb; iy++) {
  7231. /* calculate the double precision result */
  7232. r = ((mp_word)*tmpt) +
  7233. ((mp_word)tmpx) * ((mp_word)*tmpy++) +
  7234. ((mp_word) u);
  7235. /* get the lower part */
  7236. *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
  7237. /* carry the carry */
  7238. u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
  7239. }
  7240. *tmpt = u;
  7241. }
  7242. mp_clamp (&t);
  7243. mp_exch (&t, c);
  7244. mp_clear (&t);
  7245. return MP_OKAY;
  7246. }
  7247. /* End: bn_s_mp_mul_high_digs.c */
  7248. /* Start: bn_s_mp_sqr.c */
  7249. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  7250. *
  7251. * LibTomMath is a library that provides multiple-precision
  7252. * integer arithmetic as well as number theoretic functionality.
  7253. *
  7254. * The library was designed directly after the MPI library by
  7255. * Michael Fromberger but has been written from scratch with
  7256. * additional optimizations in place.
  7257. *
  7258. * The library is free for all purposes without any express
  7259. * guarantee it works.
  7260. *
  7261. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  7262. */
  7263. #include <ltc_tommath.h>
  7264. /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
  7265. int
  7266. s_mp_sqr (mp_int * a, mp_int * b)
  7267. {
  7268. mp_int t;
  7269. int res, ix, iy, pa;
  7270. mp_word r;
  7271. mp_digit u, tmpx, *tmpt;
  7272. pa = a->used;
  7273. if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
  7274. return res;
  7275. }
  7276. /* default used is maximum possible size */
  7277. t.used = 2*pa + 1;
  7278. for (ix = 0; ix < pa; ix++) {
  7279. /* first calculate the digit at 2*ix */
  7280. /* calculate double precision result */
  7281. r = ((mp_word) t.dp[2*ix]) +
  7282. ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
  7283. /* store lower part in result */
  7284. t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
  7285. /* get the carry */
  7286. u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
  7287. /* left hand side of A[ix] * A[iy] */
  7288. tmpx = a->dp[ix];
  7289. /* alias for where to store the results */
  7290. tmpt = t.dp + (2*ix + 1);
  7291. for (iy = ix + 1; iy < pa; iy++) {
  7292. /* first calculate the product */
  7293. r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
  7294. /* now calculate the double precision result, note we use
  7295. * addition instead of *2 since it's easier to optimize
  7296. */
  7297. r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
  7298. /* store lower part */
  7299. *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
  7300. /* get carry */
  7301. u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
  7302. }
  7303. /* propagate upwards */
  7304. while (u != ((mp_digit) 0)) {
  7305. r = ((mp_word) *tmpt) + ((mp_word) u);
  7306. *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
  7307. u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
  7308. }
  7309. }
  7310. mp_clamp (&t);
  7311. mp_exch (&t, b);
  7312. mp_clear (&t);
  7313. return MP_OKAY;
  7314. }
  7315. /* End: bn_s_mp_sqr.c */
  7316. /* Start: bn_s_mp_sub.c */
  7317. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  7318. *
  7319. * LibTomMath is a library that provides multiple-precision
  7320. * integer arithmetic as well as number theoretic functionality.
  7321. *
  7322. * The library was designed directly after the MPI library by
  7323. * Michael Fromberger but has been written from scratch with
  7324. * additional optimizations in place.
  7325. *
  7326. * The library is free for all purposes without any express
  7327. * guarantee it works.
  7328. *
  7329. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  7330. */
  7331. #include <ltc_tommath.h>
  7332. /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
  7333. int
  7334. s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
  7335. {
  7336. int olduse, res, min, max;
  7337. /* find sizes */
  7338. min = b->used;
  7339. max = a->used;
  7340. /* init result */
  7341. if (c->alloc < max) {
  7342. if ((res = mp_grow (c, max)) != MP_OKAY) {
  7343. return res;
  7344. }
  7345. }
  7346. olduse = c->used;
  7347. c->used = max;
  7348. {
  7349. register mp_digit u, *tmpa, *tmpb, *tmpc;
  7350. register int i;
  7351. /* alias for digit pointers */
  7352. tmpa = a->dp;
  7353. tmpb = b->dp;
  7354. tmpc = c->dp;
  7355. /* set carry to zero */
  7356. u = 0;
  7357. for (i = 0; i < min; i++) {
  7358. /* T[i] = A[i] - B[i] - U */
  7359. *tmpc = *tmpa++ - *tmpb++ - u;
  7360. /* U = carry bit of T[i]
  7361. * Note this saves performing an AND operation since
  7362. * if a carry does occur it will propagate all the way to the
  7363. * MSB. As a result a single shift is enough to get the carry
  7364. */
  7365. u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
  7366. /* Clear carry from T[i] */
  7367. *tmpc++ &= MP_MASK;
  7368. }
  7369. /* now copy higher words if any, e.g. if A has more digits than B */
  7370. for (; i < max; i++) {
  7371. /* T[i] = A[i] - U */
  7372. *tmpc = *tmpa++ - u;
  7373. /* U = carry bit of T[i] */
  7374. u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
  7375. /* Clear carry from T[i] */
  7376. *tmpc++ &= MP_MASK;
  7377. }
  7378. /* clear digits above used (since we may not have grown result above) */
  7379. for (i = c->used; i < olduse; i++) {
  7380. *tmpc++ = 0;
  7381. }
  7382. }
  7383. mp_clamp (c);
  7384. return MP_OKAY;
  7385. }
  7386. /* End: bn_s_mp_sub.c */
  7387. /* Start: bncore.c */
  7388. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  7389. *
  7390. * LibTomMath is a library that provides multiple-precision
  7391. * integer arithmetic as well as number theoretic functionality.
  7392. *
  7393. * The library was designed directly after the MPI library by
  7394. * Michael Fromberger but has been written from scratch with
  7395. * additional optimizations in place.
  7396. *
  7397. * The library is free for all purposes without any express
  7398. * guarantee it works.
  7399. *
  7400. * Tom St Denis, [email protected], http://math.libtomcrypt.org
  7401. */
  7402. #include <ltc_tommath.h>
  7403. /* Known optimal configurations
  7404. CPU /Compiler /MUL CUTOFF/SQR CUTOFF
  7405. -------------------------------------------------------------
  7406. Intel P4 Northwood /GCC v3.3.3 / 121/ 128/SSE patches ;-)
  7407. Intel P4 Northwood /GCC v3.3.3 / 59/ 81/profiled build
  7408. Intel P4 Northwood /GCC v3.3.3 / 59/ 80/profiled_single build
  7409. Intel P4 Northwood /ICC v8.0 / 57/ 70/profiled build
  7410. Intel P4 Northwood /ICC v8.0 / 54/ 76/profiled_single build
  7411. AMD Athlon XP /GCC v3.2 / 109/ 127/
  7412. */
  7413. int KARATSUBA_MUL_CUTOFF = 121, /* Min. number of digits before Karatsuba multiplication is used. */
  7414. KARATSUBA_SQR_CUTOFF = 128, /* Min. number of digits before Karatsuba squaring is used. */
  7415. TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */
  7416. TOOM_SQR_CUTOFF = 400;
  7417. /* End: bncore.c */
  7418. /* EOF */