mpi.c 209 KB

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