mpi.c 183 KB

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