├── .gitignore ├── 2048-badkeys.txt ├── 2048-keys.txt ├── 256-badkeys.txt ├── 256-keys.txt ├── 4096-badkeys.txt ├── 4096-keys.txt ├── README ├── cpucracked-20K.txt ├── gpucracked-20K.txt ├── grademe.py ├── parallel ├── Makefile ├── src │ ├── cuda_utils.h │ ├── integer.cu │ ├── integer.h │ ├── main.cpp │ ├── rsa.cpp │ └── rsa.h └── test │ ├── integer_test.c │ └── test.h ├── report.pdf └── sequential ├── Makefile ├── main.c ├── mygmp.c ├── mygmp.h ├── rsa.c └── rsa.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.gch 2 | *.o 3 | main 4 | tags 5 | .srclist 6 | -------------------------------------------------------------------------------- /2048-badkeys.txt: -------------------------------------------------------------------------------- 1 | 101729567975165968194243372948294952658979208561791202914124475539454327462756335220104830170446764871180560434788573319712415758602593627068725807232918128202686695064262392525373713225155237522188216609841483481155996683567334029328722817221828626893901342166030206837228996586276972653561871734043789977713 2 | 102225365136349088891318209586025680847391252677906980023116414333618552375629242240186989756565790476172340408725075566806749747361549969354349280469798626375543399754000803256134866770265898500196620085191832514741715593223621603447910567456584226486667515086634918431310261043369110070503514445640714017747 3 | 108127175408463303926389342324774772424052491147476321552077065581607640102268717883847860574520130199479139838104704191962731552910500926935834141815645705262395732215322816524680876828471150277770516071220938992079293420354748437542834774103113428127436088202156413608782422672231378310090921575130376183219 4 | 108717964483324964985432725581688649758161952994118857689180967294526985182497032448370544833616761445835618641988483063955619616475989983064421514925465533168366642871507226415133140494524013699209467252200207801141032220689940377117109064734193908168037815058772500625569103108901146165143781930808484245153 5 | 113551792350016666053188940748619958405553588950302984676442971792517967122223760963052054465069807866641838566230124145094788299338900587251903460645872749486429523239302967157706605563270657715843443737981866687652950910356923631710112893081116899390694741724971032134775616646338658762249854960146491949023 6 | 114166543522627901604699837980719690160649273502276761120106252055462040213217862722460395769886989411143014225737638035647945826252768676408102346213860217385232477723547765882118063417968901181291569172073765218641851680658938448365248068549391584018884300270322429481343027632965779755973900648360993819669 7 | 118951938313908832746165661254462193683927489840659874985734772445705784693666519418493460864722012504001709116178165387366998816308930318781868659482256250390459709533407846900316309884967153949351541014702700651816323878443742563095951810321463605861773033376016777869424684774111990990985261126878375911771 8 | 119033618743133405920323442120225745467169676011053596831522934249976819213998602882040417742323483061915249503683109054580567475387240085404422272634768202338763943319858707806368623389773490357747859994167909473026009730273714992188657789755589779892191740413899463781982125886131423127318028071195752553179 9 | 123817085171994984961696255659180470568506793196297705603557235642398565733355430175866984580714266218366186263915735126466886702196974443391515529005782751989949763018092478054078060795891882090925363905942448438294370247375464647022243738355153722605130270772777168338781585742810450482918849641847807457413 10 | 129217574528693754303127923817623067829018887730907379090950753181173887204373673505141356865221848786164693709564919730719409467301105324640605697968041192954066711622501911905991736981272456230760309165242440190477342537344540294936925953954379342208312468698636481747343871211751649000900395152588138178237 11 | 144729792019848488199812150741476027248539799554911432306268150392220907475825993437783350384559890021243145099198029081359836872201644170718168705908874835210277271559452841638944894270275715759873768989660715763511683008960911016688485234271859221378556642338606338678907629239171078353711437872605597614601 12 | 153307556437070111105580630587149659766208847296249223001538120283208548223249258697819921367857620300972291016021329613457886677071068852600443154736296970922373569018429671749214419571562555448869777349506468604488072178777753293095786156200627285866317801162471689894506113341977740607829318937996224763251 13 | 173262226504477542152912118435024863367997118377583208267235063609935592076511171976605450370662825797469468769555884089517769543383371694528858479140533472676388723206290992010698396266680487634365410723652235621183333113144976736253003036670847099081918259394908146624061917357080388209541667601188368081301 14 | 66080598453642449085840161125301683199293882599230685548366399241974921081754971705203639491524894263533111159344105880765759342594560165653718968806665240000492314025498822572865018221342920509175012234823716932380817538625147833119909943945838151174817737330532543970177198255735165223081935603630840313227 15 | 71048121598960085267072722111945980115230961069662480152678033271007538354859753500186061811101588028547034614643696832735206628747952859332163623045186892437509857449800422807283647134883315773120566201032530556844624333841577993422690178926486304485391842811388111910235904532211500139662137883716809477859 16 | 73728476890278361599996164500116293208171689442907162250131500577797044361178227305889589020513638523675039765398334292421441264959426146550179256583497633335006221198430952506619987349586128153117931344550959673768640213621060462704389518990729970183308504590867142300543140249574073873588309798866375037299 17 | 77214502086728714708500920890707803668861067372248235014339943281343075097157875261790684222773420698806229179962512039550961374406946605931980109946163576993379827763871400575601774883123054128149641003464812391978068674594893402933120059455030567306847278340393751886835213803231921088380445267952228133787 18 | 80463600377110088721962572790650358806370807934904692812064597607077184280503076852275368051564985508958388645455042793409044647042198946147996368650865293822240756214372779606582104320410490421319582753624175425024118219540736674974281992034982368869989676067704743986970724121676904613494084592342903744147 19 | 88470782186870527571417308012505979185174440462050976305045052379119223984379686856459639159108707272379021231474655897627602385643345142458772765544994136737229631393523869441283136468182048676337301416450749339932190184593532445102921437238434526530470207027546175167714317364679861474129578901441845608493 20 | 89628573797555392870739096180843437913081964880370721309002200647716477500266791855195775678378974828372099076515548681851326281141615125400012917422199087936112108835059243877897552942551115420958195671600991755278956161049676292093477599987565233511996042597461375936790686401440900972869706138417536124219 21 | 91059908706879911458794061841519210162983962523676489974093118292186184799335203608726643468117600532810209202072836138610640690791553784506889917133995468150423292245747190697759881114329501643480904989329555359383257960778514449084689353359169897748570990010449367578340789380658868907657326500474677364221 22 | 92991325506704464911838440066379601527501098825717562407196567387945936870884800160424729263067915612211944741128900052492075922002400239974280528944517316006393852916411577380057715751193969588355227045101918332508252245113066525129475414077899406260030091944200860394745972616413165042590247674821892579537 23 | 99727321738999727685754539572377401858952113159155710746466573639668806307458016167350287295939590137532083893425225897887593948435600525055608697451244357386903199016743966985582525206491138077742505901246633107007911101875600685781515996233747607294451622509737085758258101034333048624653359336596865892987 24 | -------------------------------------------------------------------------------- /256-badkeys.txt: -------------------------------------------------------------------------------- 1 | 110481581939680876247921538049920034591337405732714115956185282595440202638336794741487363826860596779754728054738471752353674036944588325192442020978745799557974825499457071867667225467303381750756497642991574655965063948194595478368252053500918041631555925654831295072059921567968676649103811663440057321039 2 | 128182741665291820322656796248978208243367051286813645391474130585568135198058785689511536071041748853925908775838514399436733508141083269189188913182758517454842599560395987316240775411672632520419385834735381358172007292301712104679764970999210541210787726251389977834027094826037796415947048208655429648079 3 | 128398948582499097520109847311663353528473755755694174497428868733057810276894641985654115434564975189399161523285856850966111500837733851389494191497589921501396438173330436610677149487173023800059783046464379401794833434194188332672653221496561249379224836419262974594335465273867529498827292589250866196409 4 | 139780597747098422625219564097215912348897638071254805156843707224903380732405990347072630029448927590015968726144046196899257272518028220788287111415305897487583126561091275712470559736034035492393099070971886531204397639332180761665843257516969733682768546094647213050821243022642409484095298847681311824851 5 | -------------------------------------------------------------------------------- /256-keys.txt: -------------------------------------------------------------------------------- 1 | 70710198269415428006442463192820967065019701942115840848228875094327832797799644434206462690659840734685423649321724921162576664631788579412069130182196177183547562590164164045624072252447126792280931145569652525594243558087118494041030620068692242651531941057793886813388395762644406525339567352209726135201 2 | 62908401188936291904076326557488180348036186448923787102133181596109174503092594225606651233140831186502912286926641394337035604987206840144184021371657082488516581079602262586144055612336848246118457524099803697885805575628053437318807492137347232534447678810298533081891353192501324170981277559163655592979 3 | 79370455021872061302732916409486544215354977904772856073153649258526001378225845962192335132947437260623980666197362132837438893794287474192426939893275332138914853694519107493997875768969290521353001744728890925617287650967463701500066819614296045410981768119532516070088562423228478127379929375579800709153 4 | 130490140106028090780299331696171960201880429499413037977002202923529573887254488028640170712330171888049273967747443220926878855626980910860443350150585375550770042762352549425642969332268859913444602033283564747779232239854814274134152024392494107904134036679124106582584876849474898176681254700399974001217 5 | 96498836214787370428712589312972327126780297142377284142135117595614670508780814283923258721692889861592288734308077877098404503784214817843564148135740346241850801588261222081859215977522302150832569886992287708679960428847063880115846638775477554943477731414269435165285258731335988244778882614981720941989 6 | 88588378269049169747813727477968901876957313097831291501446813240327590352916964650855883727363071906576063739750982534444621556230997245169908161314073793129173148109127709929803499521714040724452928238265603906501069097499429914181971484712164056247079007621609857809483172907408730480107035877587721917859 7 | 104810417200416024082458369492244814527250355217628026280505970322669172589685343541599688270553756964745263552623608159345586619205248940472425341621358208534285287837874823620838984651143039101288825356101264476144753657811798639729753451668747339007994165051620084799402183647670700335764327023891573079289 8 | 88393365357373979816514391711824309542974362733285361630177918087189650423313222168840518363048111086238669655048120613760803127511233323821145241384415251600393503166664605598846346611239545066547619888825123811636200320259783605393075759880023868214099729921596907202347710871766608407507281138918546321277 9 | 92371455794820366764324581558924227538471754727561907658467509773384209556857329716391002823909539260981705997859750231930483678716351762726128216970810049131669339330646380670811878579616850609511815044528450603086822612666701076631091970284791036513209486324385479131701841374357266860994435989641265237513 10 | 84138444932674957458210575440575730834977753543671091117733348926073398513670411832213314338259968707392465071050973015563955352115475386336371531010021059813308821201886324639561847181595041332827990903289246970489252471618417826412952026170584579472539363438579089188538848388120816733591836981285631426939 11 | 90138750130893851648696525098121294346885826952519652974195578679516076467419904029496037893417819280398309086074168102421766947563569827419387345138595345555147000723309624012876268159643128088152834892088984531062274792277041563297794156147371780073535526139557305150601058128040234280899499515816832554411 12 | 153107205074331569782143307712824423958777896554033975876999803688409767147455277617977045807331175218554812748364027109436573506843459358523075823558727294819717483405342925835400182456695498503110129366661592601527747125836790991023133626545061956371994743703314610694479705322697827896451371689156340499259 13 | 126573921928428923295909052731519242001709733814501889777008410638802178483520025976740355075899705231117805115383276737286998814863703578952313106083061170446420627342884588285725693143951874640826520896992444608556836086108188599972052176843391930959605412006568514221870255904321533783903006514867576504221 14 | 92709274141404270728734368664797850812255561098933519954465816255810038575863102346435647770503299488825157574422972962569538228788687371780417546066763332277314843285506436353077801865329778189955707593390706075241566326845922277711596569630291149712704411329541848274347680090961228591437999780600631633949 15 | 81544784740504191261864971670462858024369697104052509320083744027055340064290998648107336643713860286958295218728293402384277259135330520795000605948598807859620754900408687495329713790346599621962524448173768757701643661140793729936867882239544015125146194646415266805054607264773772171028876705266667050131 16 | 116955607923004876141215782207303050978621333737240491849569045648423100199529166076377729039719254350806173513521412593212948164978014184550564817198425669212678141752537646363624187772738917068433044239138006045358861726579158971849125863096324192389078436909257926860269070711716219429598836859302493445979 17 | 141050170683732870703275826660237514435005339290278208566732830601203756784850788322647648139180490230261089962798280962839797473793187589466832119888452849353225352753601012069318909818445291549339539142510062037956915970913667130244290774302836185153460431834070272309662967683046896862786989170795709946041 18 | 126251704540905709968979436138075218032723738399302534348421215671040384818288226958579381639950888972542721006958387824822309409685607883478222988855702978346999684390521143134660413278908637419109147509598818355632209104182367872292502287478369916311257172922401026459824447903614246642040872242742206537531 19 | 64887440791811946183074107303933729726894835259440293746348844490819321430896762034070703287380365778756568851447964209280396819278020533579225298620431407818059132295058766467990622173032867412033703039259824343198802017743669962109124922981723060580021998869375843961508137337544470685533480217637368975807 20 | 107607874134735893810792964295270239898152483271887520993810199724550746500437568954728087385640687018950123558110490754221905308885288809077552070272699364584407939328012598855443997817815241934109496677693287777359268796650375302013546135568521189478094323521669219823446274275396372458240271147250573926393 21 | 89244850704999750404517560031380580099140754148558051735457486840126104769051239212270577218184591193011158788957081758290151687608530402635069988175023017802285275778728659587883247870713527651522472622020892318912695672404784101540809734485058035727180401696040942533084835382335248281806217291038803011369 22 | 75794350664458061251078330492648356005417407311468160243764907825652091162960149286150335806379036480571194635915156898506761909358946993709714676562221648306017365098346034393838021702069491196332136315015876089388150467746198139034555738068204732112594057039812240027827102995558372154364055460632336485713 23 | 163197576934191000401224347766776080681268562043086399882070346045048834025641016172849961847224906143893696104044776046757941490302942831951117942118080099470201174271635571783182359234148369575001166210996790609040880244467367379665153840095062585350404987540338126451642678703971420579567273101480664856973 24 | 101373109120461950606740609691762310272543608712216224506968036650630943462249189513207268931990486745192729160371757113037658682929248537204644880675628968545229529351033252397144992427011650549150458645643493392248866855028322169640486983055100263947469672564735018823642079436393723879243301948829576858573 25 | 84392226627773778215215510378286993236821389433097589587965101753294003570429400550599591654227146492173151057879241327530130572017302730011168526440699692875798627135170522383095309582603243690622008719776321701323457191053499949007568326954887950620759031801943247235966444642135932397749601191541679937253 26 | 64814441623685149116817951650016615578169819928943343800813606800064949584639848988489740685324036433198988054089341389527649541602666952612412162134043445365140584319927013711497156209108743227941560384181858125654479391591313346707230905118345531466963508030668296096879889485863240961366504225178372052499 27 | 64750820140376768705204981099091679873395468038069988524089699184287974193267766108308427531787728054161362661207409763231840351390510529039004664517318382799720380365396864495115868456842181084717380379655307491227355659617193993294402208591644945326614080754846310403045039528890052024088163566607934774659 28 | 102817227601078716783442783939288003515957022285588541157683156775416276367728927559785362449647207930699603156824934198836246690804234003531374778822540436801570156642290299756190038405942643696059880130063024186754184160416646041933715758604761688766236660670307172967414377280757286603388875237774872277053 29 | 91001359869441918390495139392230079367292922415141571422116282173645283482249328218861690462989786746860553284214648009441223869256914760439207394534962256539596636153515191024393125188570908207518645106672250545907593221741730684165555630749576457270896337837717124560630439169167474986949253135422557696351 30 | 67391526686764494094096918480488483753084827695345303320930971074336557067987169835560612100867064405110770264762225264507121465930650487986641293160493856030386113781208047917381424817243481861376503846508608041958236054793117133294159983453191005174863572074444114428378684511834656071934464981060607654079 31 | 96650462287866596794067099348285470831501679065811529889023417722413073986793238587164907741743486277835157557696952185552554128246083794664053866513954708215023390900074296682550673043549813041308239587791320782247835496612130615881081708926541286653770376388312897113285995371207788973624307626194905384851 32 | 86706312355925559219058651459747283525694050333565866931932392753544873214392790757511859659698386483372284032232148172008472060249960822055432544985125995784981825507169042216196644435709737101436140847874309355796780127926500845805357127488733521269483089056237627253695995181308675993351237294278259530109 33 | 67985880249824301303448161297586090540894509834790628083752090289437896348994290214145157364754112257387740662659859425012888904661141566648588407258181491770105392271866589311904596309321504173929514275522045678173758525338728661104064177829754070607419895368170930956538352322327315487125709497847471936743 34 | 156085922785503685682185028327373278404989657002333540663779658418048865591737447624276052987639632283654632443623246325393391861355115616727174646311942727386691456801551880466262739170841231263616363441059413097413231049091793299960368895287181148307753571688160231831929742043755265069367701558325841888063 35 | 117449683833785835620919683810627219692056641131225404588370416382729162696223467216014740111323791521899637492544107541465134085882529330997620082193530247795062338623260070276440570051017549559732285834349251713016541326976613432014338443959631301070921635132250018966792276013588649797101865774194115348067 36 | 148981184113433294625816287540655322902715380532951171387089042798711276253669532919290022117150664654444493016372819792093699131740149629640862821111649371869256569267494744622242771519190969357425229237434946887442192056232838210562729648825285357971166081083811667905826606891167370685009714675107183710163 37 | 88784148500138225152492950950620873259980429925803206098399962352080922308898620098888184325742854224469981443049695260690500115742608229504461761341233859667337681451436446474817344931053147921724912104218794811135898564615927017166575920904192904875349519921458759883239655258838236518680529097070524818019 38 | 83753204133892707964271487347331797824555779022754175406778740625284806552706999387902768276034641540292849369770784834836136486155394532555359117022467715690693010271072557435716166257241586281836041327369395303583701799642153329581152730372427705281268545064289451920327436773656186677065885075809602165347 39 | 95587728677400879719567781196864083897434641066256960679311680037428168111768694453035126694039421469577385044234931605444859763984092012163346341342355620102524590741089007137403297477018152827661922659791103928492687584892844493268110054319078396631452878183562614864320877946112897427683946573006555510531 40 | 144758009789377295632819413938200288146495171700971626257636388306590242535732318032978359782279757671154620678716847410096833109645873875030677610400096698250160322120667691755203972588434426385317140656170268596099961916778834843578986662705821185251958835439813307925201416874264144001978793098842236085929 41 | 77091541331684911795898096427840175936726769693579492312523665932294201496655544625177845454666462490054830301189907451788725501808226363538157948128915862413390944862014081928647612047417773108587494826607588327070655865298318998771293322520141727800493820774237052431539153283817092415147002344535806723633 42 | 101465641463588361279915490011743547627397584410906627475643980897399684989165993253984844039530445020958716359003418153130337194522831608297199526711425656828153948552347184914614522886250668947125159270682658005246950976045755765582454061964666979243766124396083108867842975318143451410673978220074341420017 43 | 90325309280310573700337637098052774727376666091512347850198988325228631528547718133680323084086443094479558742527552640132841846329814895471194113507461414993178266313076825021607784628612945743717970217221961628046190204213115243823392915669762218132944740482828347861362828217823182791041044452267538640207 44 | 127026784501949869037055784806232278532075692408335657730134185627922252051619192204722387118335437470146543016610074977591018356680295706484657939404907638969032981766908699139876570154956016524342642192647161808260352169091145202740266422733019689212723388134958744931559519746816983067998275948489418918607 45 | 109985080473971703677827212366056678561481069374930516491479588364758047446524481712320035082831194994074143133078096110432679225676806096709693391958074763153175406457791253733840025564412287822189156420553889983901174954752336014324638844282765876413212611560022899751953500263051131595831982937644271537543 46 | 115724668423184161718018649781221678134054803961584984161901523087914538905998610889584470176455919988265716713905756072798725426069879266973723249558070389728976729348809570804044147338367488268805382569697519717624456833062433971427803917508499810317464800905666942491241379482217692324459740956235250400567 47 | 154866026842492591507666151493515654397631678538041654308283655389754608665962090343196548191209693641478436086297781198353400084713396125471201716732793507059281077424779763467440502786250130543206174613866342686555040198560560628524724414917088321122263965082005779798598287395089811346028215076872098315583 48 | 69203177924158580682980608330270819562357750602020994998802111249526836732674455222857626817765979562591313139956222972732780739490461894508227092989128450406692996533278841657043835701303608604172831065201415629643223972479708373204178034575720464148655865860855903714688959749002896715943981457609180018287 49 | 83527012776257290655143774692218402580727203188325877564637798332331662500370259101602517534034168061257822727558227480574295794476352992356441839239165964578152944534661272746428817297541952967696141698708395697779539098479634163625117172671653096557931048465651900194334596350807622651461263156127879380933 50 | 93892624098983981494131520589175128840469310983089967644997901677277251855234575728404844935889655193423391231353363914558654004854679564545050156695655252841250070047135011361075839682444828537457400356880369270521616032485341868041171271437894482119871990369248510254726231113274469128904966511820344005779 51 | 126966636112701756868049684405265726107785913185627378169428235578606613602660482118015943693309247761180039487097596600009238726375804363329059728709644069738527661601535230353040967816126632354319553986896518565169692573288802751561402256381388320020692206278312128092539148901902249974454697373305037847083 52 | 126145405469175362142147118459966570099568637836229146772466183490510993581364869326004729615403863435064998462054330468329715068812029512292923830887509470278410771421484303589610156736619326201267594292658177224155337656000489562381508855402214216904637598031482317997248606315554837384249041214542718402071 53 | 61533418852887315365047593167468297090857927420084293505045313738811314587035136311428618168327702332869208092279710281866109243703092373460916034170677699128618898398803291850780904111088288610018170615952785081786033015549017957440626190527769488846121097099761067704346597856575527155039943688040609300151 54 | 84550055381094087728068094042076543537585246301606140360999962316471219617668328598216424763966428236130466985100009850436279916433777873970286032859931968632270449001613142345714967642371035951617281862522666827928653152403288469953346503474425133275965453178054556142040688246514013469254871944247137589503 55 | 108476641729182057877068430272172900186694000606233254113481256698507891682164215476311862056201377994819586397142252607390917821056872434061626320641862603718052397139413186413558485891132936368981325830327406855465362393484781516662844025043249856013235000215493684369966768737279967002057153034603156796529 56 | 97855184867523609869108179025177051558687065547987815143017412615228829543040901063585297056100134226071809305541144296004700040511867136052279308862538725840272413564117512506841536293063993365042614657286654848678672254283357396001746456597671407598408101297205895199170935543792618459133857250365811151527 57 | 133701256979494055450775276839092620808998797111288741321415286681524270013691823992301483406409160551173717626404842309583199637705145747763856862726977673065162372995534174777254398947930041064864095669066536389675601762305869857282328524950388582480970637344175013194687842244203461672501218524240627967299 58 | 145648055781664178719209478127852891708840625665801188786190065396390134732066544733626563332273295176798080360073191844325220061269158476512542794643633602681310454550424005968410335314328353520759247852780686859920195588886743333891364714103874939234873074648657063013427417815147183750072572279813993693307 59 | 84448298665815995281069359074283041854388705553153906812645198507648606986545464066475062236713513681047915173381844438691155992091441179898924698420516089132253622785668836001538381718000510257015291776334353272687236255582184584232424155122285466976838039930941497342454996659207624563801554040334687687131 60 | 152403345386153405094409152195268332185491900954360874772067712749302375753940832012831707722237198002911534737161746098096079042364770019484499173172070323562897124827504138175817903092181057075579596780575898204358152049588199914694539783235329510895799208731895456066997636553851343974696592037319798966551 61 | 127476494111699023066965516912408064810855264722958640064917887163909329567578903066909501165349788202180609725733189601606163972569303626179225306881836671312561180732854918641366331910995922454363607218771640825779935080162767261570245635510936849346730382272971327301056000685688579133866761625405815866917 62 | 156647097333169706986225067091472054681821201117732021135464864145003282522435331612792381321769603282421271410890833814306395774706882248222885899986426688759529386557520129260408766241620663499833967759431979136121402474138264247433423930320196107983546608121820658900658041989638054661463331840516205424747 63 | 118596708661230361886852103738712907243546316541252995771006910632700920720599289501974264153832496874532748669129239563970937589278665322432380994152662991117746213576739799255295772565057120964174642373055576371139716456818927973053177426892240307773169312181016923425007219246102208843092213161960664673769 64 | 133220952165955576744583244225952500418550958655833427625625250776703240825706871645339649810713648459645314971077323638814117680807319758274743635985741007447214587615647481256609598745468199583343963673577811753436552658765220575197885687662156472370891318276144640732306171498833123618076255347032726452639 65 | 138771076972149271216064284713806008865492429116333457501252031214226110169128423729413637337824687270856399079266775799005408448020449170493248741901542488349891191527379816280207160432863300711674662274037444174369313515756495196191920110732148334116364848286877033501231082886613827729146935283930156367631 66 | 128182741665291820322656796248978208243367051286813645391474130585568135198058785689511536071041748853925908775838514399436733508141083269189188913182758517454842599560395987316240775411672632520419385834735381358172007292301712104679764970999210541210787726251389977834027094826037796415947048208655429648079 67 | 110481581939680876247921538049920034591337405732714115956185282595440202638336794741487363826860596779754728054738471752353674036944588325192442020978745799557974825499457071867667225467303381750756497642991574655965063948194595478368252053500918041631555925654831295072059921567968676649103811663440057321039 68 | 81734298676708217470093407776433907103336538042595403317423555352294021308807942354329743892983736717530310348489612122125339512078722942613604308133704408342658900512726536708264658267680339904595578578067482229350533860078217537630028713969823183577350598713051601527192889587808112851517892804224676790889 69 | 113595113060316941568331539473893324117481598279910356668457376962953017377819205395955228369996090290145090622612019617033153186493648787447595450207508372699837580235386951339234854120128594623393682346065540190638967914510422386674339895780106711109241242818392834219557297765825500519693370790218052139219 70 | 117758723811421263441834170917771812192457302372740111625004831974818033637263653788894583252266879388277565489635464948750788420256712276348176593070342329031425697768676458053933809553936799095595025548091450244040133158942028961036649615937988839187679783792549858488512362443894784124375348642812761309977 71 | 87529875983359444479913538164124834474777341197830102533176577016998841437490760996380146456194226836093189663160895886126708796571711939320798194596616865235650702234900878447763770397486847575525913206398505891453183703726896300876463365873695081040362809279518331634888509280857396692345146823981093093573 72 | 80018850515100593848114861787662474832142286674858324330869314565010924040700181104254201330838835398739249290072421955958465042481007413701774986349888842797968798100071882425304977005392767819718383226731867937455285715434418931197723126043510491736936938230315821057598747643731062595306122424895540869111 73 | 102534722700412054112843767491848642074853696633800178842593340319744425918882406963389855760144104074255088989353604116995848305800665689502915944946021146086407192367274965284254990339280899756587854776968824977517931602354460517562319482010469164266675886164469350185217902362807180072417309648422106100353 74 | 106466645042769311807013306828963111574954944237898324722428215424742355026561084962276794991147471602283399679931873473613051191424113867194829343703944615922901292371358437502770804675574321967948946692362941349128955176200297630126893110796588296833125018207377240255860716374483892267003339613722454198371 75 | 115241641067652704893468389810548164514309844216616464320898246709257258148716890152722620481180523974092427781454347325059678714261745285920190176021730559052564699125976655778423005552559488561927690647673510556819303281131423133073115304164556920667000548267530968469736709526413460153061057411453480362943 76 | 94283365182448015134304197912560545772750153379660341940999979324329042767010099943064926663020310309301403314641106555109046684896360106886503250795658949132516753378231944393657234394824426838575835017212716863811830972207992607586792258535492624649745625452367801751462202227796445289330461323769253225959 77 | 90192468899028225375362771580988224972970184698282093471564302450132235131692954070469055538995583127571844078516312288361337849549298085900770968533540107597166195737597020953334474798686646187458797301753028333638823537327051895670786181980457408379222768503545630697123999495763764395016488694214246840283 78 | 99570167292259297337305482613851879478867010423286398671997101171762069889533304268509469504303850085632528352060457631780673675904934863298494892700117157353508589536524647588438938854848779415627716303083924083692865964689713248122009655299578598295440438776445588495168192235724376871392231818065627319571 79 | 109126873299363013006939340679120238062966002425776930913885802229812189897732321057618359498333035046008979867274927476676441971890332282401165304024668599768051064034609683914082556679428838778442341181431464263134266641654793517133617768227165730219981170133126982178767844247311085521217985319955638843803 80 | 108764069447945404774349539598765117082259575397185131204094004421318510187104972569763487161719325973383107183385177275940275300027043092144637635961813495939430440309836605156606383705693413585516019026440962126840250509633857916608603860812931860119075545431742235383479442589451721069334737280089036900833 81 | 75619676551697230726057393727007151614469280206656007937026781943422392101352211107954375280586558949206049702044041664818300952654402902653837758944383572932888629828803372190243195518048577761650865469650342450604109199903662755291035715042265853133682664083501766470096732157420204665210112828620824643447 82 | 76372952013120591051107390857606241880484493196179530408256953737736039351552588295679150887958583520113875255751333131835575908920171935299390128490946838627638473168570012537871851246495181995461796169061808489895019951486701050503660305252145456732092412863826889350309799348378191411034231198221571998511 83 | 96902673948618095813391058692626468569459996995656851246449382400155560725833513474947113685553989509983062745608832954866176758797887555112974439682996190305358674085719609994819141945162874853437948912978820905404603134315822469081767921752077252133572557858864927816573045497951583573005679774457040849607 84 | 56416141557077938357974460477409953082555480094866504913239796926250382042539116401870429775882686452895161975177662210268640851020406652336486039307047675090633742937694114438763550983494659756659167192875046681355679590533302800624981845536905634698131033463255110091695597562654712506391474117709253381323 85 | 152541884045404010278526278531328706452240701489215782295699882488085233416440553533804523907878877864940510657415574889167126394017347780012663620834478052296480499972952965087726697069761887656539640577066266591388364205163268514248482663714547774872620091573766726917294938624424212882425617828813029930593 86 | 118110901605611869372208471070730847990058831764041179833057150583010893254963918585212422957809702315231284600045422621957179988630234426425382712792432734187058859965089685246153281320094605286472770469789730755538926813507016298482074626975674437792126146997330288651827760002099883342980519546736127913463 87 | 69542219888399621446041050812324524351866012970699086269343448012744796592860492194457950162454065123921780589145326767927622417946500580459101200847960256323264024484070561463303967132734266825192844019216648673342323427329185034046190904853819536337971336123965225598441066160260700142474532621685974444939 88 | 101581490575131819697651436805355949263753783999999286893754858749051704538194954910052644461419061469381463998008836301798201349694092487196346434622078160767429523127740447618496893367512962838463307680318713691992706052336111501947073997475786160061172990425812590185806394259763959069599974645533010036013 89 | 58349241837258217062250225037573116226369971159860171990543563522118736940873871061090652235288129637539958417105346927312060467746331660620892077331467207305612890883414148716939226394928159383666182322825728672092765179045899779370594200010948694345976082663745872035995577657385323621341917964965557109079 90 | 85469813877930521034928101656034739223123554365803943547885311583246542085757092513904722003218235218309300813567617097187835506699450801789124270363955015626098223902847137214062394795739189294890469402828529978591277368798017463349143058813697781276863303626191307179688084378151471094255348496724394093841 91 | 63462406207649906614199882896121176067234353582162869717875167849415825497106840539172623161129597884033264130612533469504423179449794615430137323656034333349535704906399330196505240221245568723162431660227393467233551137561780459575619420191924461203790256041971801607672743445370059764635291308367647690987 92 | 83921660503288583491155694726978821214569780663271999359161501806605300677229065413588028851059796591129171138850341604261231909912637880733184383529757678038135148621245123278710885727985095138958036603895121862761468426163245758447773390059555873113010241901043111509854122022663347291989704017202548241173 93 | 150941486750884388285623683687343390008345676124661556528036230762415607317296974634144752137571822794633268602602319379789661111484213254605811898510528449784083004439468592730350037894885779654880292237029283004989028399016546770610012622869922007076151122116097351917049850894916799124466247397873128731661 94 | 98626646202421951526052004916662344179110971779688343762526231317616474238796579015658534759329661058474246528417676663198269564483853800113449033976707788298364320738439458942143650025288583930668199627905028456404417882492775480449958816989643702969756101208573304927869325571099522523731233815044642159121 95 | 54129221768700777521395701863001460330015488144686467322806117216593268369330391400571958267589573633114177820537720098208226450122141656824632024067988112117232736404961346234970589699975794840149443309380504860144903207893774342080498429746274827160155121453635495041449665618507065948955662031964069263181 96 | 85833744310476717532342569822692674156832057479225448482382540309984878290387383160905397435923266722003946071308461664580471014347351540324134702896858810466411355439190090029913998835130548415948504653207154509743274139691424806996982263634386975252134517833930381124381945993578540130340878988705508387229 97 | 56447754247213222062587063678265171984864410746562473367384960503378369766968529567999029322504688215710702496863559872048517028765171586210078335805537944874677025611070676498748403148670537630419178153427581834257689224582446638453127338889533204854019272059843486268246582865983139463176034348079925115867 98 | 151720329696865576885631631535377379229485329041442994711386690131623141978077474285465824649345648904184876155737432667378640547668354086830172945372055204075225422033424537942838251507114807792835003805867934659778330942803348612718879440110863184405563102550349780475017237774147811063631349005192777600563 99 | 96970876655813120260334663319314907165988877177583763817040231549035533447108992787523130486486129758469737208673760887650389562429200104951513523723144179933050132755546934465381904223779710137422506084284718893106570672308388208443713766345321649804719576622632694552805813619570511719728175747213218705723 100 | 100504619478079336150156634973289608851721459536779962363005553975178469302407385937607359569609709735286979945769182256501835019814056561589092323985504615748693923754881823549476346145837870561095458174160079501420835290845140694833749755252377767450568956580455259422898236255958152765448394754723493878337 101 | 105163562139368634555018859088906008797288199794433648504742076996608378203466119921452126964663941985527306693142220908239468473271404166764414055623004917070242958680938984849087149256876871532736227211690494008031508482816244927926320373129142129013474670537457034409750408902622868225164762841207100369873 102 | 80626632023015412246461783511881589841590620978436164275437390762197339219944223583706378513634121029725369205710678965059960410965126706476371787472523580674292514506652702638298506848268776990104198035155289706774220832756018608048739514000148058899075788967255029980420527947727007504642023202740746577293 103 | 97545362030104310897706186932128722229154517886679837850784256003974366699024813184835329194379849877470600821537122547841295018585664404937823310639355366675653851319256566464764761234837653349792242222012159513093825657776520388779203788706004771914730337998958840607499221831079276686055934335721715029017 104 | 127915273334638043479148289703625999634019703896322427622480532692447543560142787102102133452359681846821388181199597563144269572998775690648148385459856224339725546797563899031259546366390541835261211057183927646735739815279863494740702373490272139112118557323418165326422188261436421839230454305075520816219 105 | 70029665340427842444950114845788605387966555928718070028696333270287551800188486826125927366522356873068880613433535466320752926902446394110982152166348955772109745862230688403991878773358130236101879624057008787158199673358989291180712893927614300952038420167099006705709457551607531700639645245317356539903 106 | 60825055995448095207506394516913405208320849037679996944933405020421568390299997718024254304753415406753321539890494609480514131442912367641678533171243841672391568283043397731344722783211721773141043431525607302070193116599588020224191770736119168146695685522265543534857789492414762053436663167862835726397 107 | 108394114626972983250026170278431672622604268320689716944760369969197472154250003474725778514413394147061106996430680318205518907666711348528651809489622328079922544345795074172369455746403566954416983511516054784108221492265015898199696178120206116603714573723080660508321392673299207905237660281164028913329 108 | 95250983719393605497992535627000907475351300458483968575817915327148432391924153372784592900917457199884369703028732331607655655085165566390008500550863170266996167543393230978583149805367728273570151621084368237874216836253347062296018044064044403733155590833903587688489169252637465588130044832084245705431 109 | 100469322118814460624999051959198460967270776502303249400915191880222912282874113525776369327122479048387521527319458527938186221013701543671880432844133730376357726683440096542001227875670089646515151474136381154744329456990400704107611668986737414628095446673145165524128055673822527451266296118408774745273 110 | 51914015178264531033799122295859050521921542032405587057754939210195575874990245854579817087717366177046829437353808717439831663789226183494880933463513125223256596507298943491219574674618729172787314245174155242310093057922874955733478331358300994986173830122216955136254068471562651876858484545890840167177 111 | 75599817204681043558126288155138418486412270754771168604871442136430621504532353059593283071860009907818772529310820728684404393686441284554477980985606282361805269316471427344992887961412500287347648786930263190174916136476723540571130615179992713538924425006581275850395740806504395005928952598803481678553 112 | 77669583585692753896892933245997593873243755156675179686439132424289232541911970185499280197373613698159889142986477859562552714814918560335886410934900586222228394330101282489182507316082799084967362428402999896845708745014961283092333396117519162038391195741649416225601737350738457382705117649952074780067 113 | 151451114208558080907631650332671358415683321798154225249364788783917542987877538983484116428346538984656183025226778305221242163897494377231717038787977839784950951306493789601945250225466739408102779666092063575217158972752102907466961993268956586996820084044339802296005244172207352481867086872896899984167 114 | 101026564960274111526613939075897373306441889517152101849672205330436197595151671647575715928750841316647892140387246623774740911109579464861749973368680184064307723174931259662822909540782448025846025025984715585217524780626839486146597601217867091508273990293105973441457238198632742431269793091775736526909 115 | 80125378848260570886828421865749823478347945842869503514826962034674060617245279324250013526543065897102912178604414798794739961594393771664422025526321246309750546462856681521646747258369551591034963647591607466056386055665040152906918193539288624103328527416570435794095049596065808285825758881401915919387 116 | 126566285992708035234994171594271972664551038037398450490607027192972968066187370813777076845649896282766311788939085136843007277974516911199295510807951547887199896700177790062420874817899357314902094778310418849352682881232391537503581747089553667791834272127526461219689260257781134048727862432713147744531 117 | 148734424066274868092156702607711831993631759985313319995298533722233250774797801452509044270631496552027996601790218560482357009735620916098633678804101425568966063872907217108621151982935027097044579767879603384233065266665976641295013500695479088958799977521993782363135624976941981393165292527630434031293 118 | 60977695167556742451885631344627782836976780472871773230362103123070163907632897025918447107643901352066597618043882319606771369039203304469849456543900793787497143824978666325019250253837621821503670048640880452842644940113234862592664558033217219847259824481551914950087908412500999827123423666026087164913 119 | 87002189966810576526917630805667201972993431823021910171298279220513493798098868099802172962813743648075789867790410363725398711324945962356388853600508563870871900260906769303020004835627669984150965260898972454333300773461234423546475382773428618841765024051577852373832811984350320230329741909233013193893 120 | 119738938697679551893302953779183120536260754143956006204571894104605293017565700913652944743293774224342577011959087396362760018844904329228853787271219182467411642422573493090658297118826575304274074734039339639637728843355335071612749548962177061461731971492612150465262783572803320258068786520883846788813 121 | 105141939359696219774884395746746803359232354292966259401204951506862322804339431883613719474051679842224754614497749605531726506331373384740917532155330797744343203386013016900973260679881197913879703724565925663226087067345637689067066083647359911953975886092780251185835422406513483343572961266364363155603 122 | 81458019273308975265038954588982930466182044639261388839263868653665869297776375108718859275539660439650868079998368407647775260326374502933932619492397893778241684765512183489135094956725115410140359078780595169050637549894203790693639465193482196491694123876710538744778527475067429971639718218435294727007 123 | 131859800237530517922605228466938917749170510855983898536450789034944817803890481207346780368461284329764300131692661464134740592155155640633160340042098126965561000238934159841465502490019248551762916573620191710136483317247246234676198553322758409584499688979404046700318093756162407912149449547568133982221 124 | 84546643821012277422469726127721431430149311763169923932157531682432335099381129569300798278552528783118153839088471836544033635498150860798488898849071371151606031623496415419731396415154646773576234806643640950649635654503733302195585051145994314343467666889815037367945676405587392395756743208110169390349 125 | 86942069523305422567761488306072548981390160660006654460115417611225917084816102602685655380852569417876947621824781428108567642218792154161181121687117641321287538344618794801899992699232595230172690550449916257698904243265339845772749981573527684866969650312000488224886365279970824895338121874401028185129 126 | 102718979639218698517144295788520361540232017078859286855348044767889116257621931444205149230964130950879316192254270611257166581575458299128874543485974364041566199035086358066502528975801300887591083297783068482900191955918586193264879297207562585850585757513576114381081019175758941515438630887498399720457 127 | 80865339574566971377580680044166693473183945364086161137532087909476019249763050416041262332694221041980579087625148200871511631931898241439896934137843469453679616258984336021787633525596105638520690503393062361812900288700116258737928933351239928106389674897445093766910514655307284472454395146815309046571 128 | 103929071107465691743583734139690121758690879096996021998639179437302859821285098627951934999576262234037913031570335428301294109196521529632524505769501422746223799738589557967678508215779107276017223508144007928917543335590087184749019210797451791832039913225763622744860004489410617808260236776557769860691 129 | 63722974107479835212678957333312252277127511625072987515637303647985205592477839216475040501526340810348212466720544860621203937302223007366885749810857720774931644782405712250593805679368228959505374590400739259789938215650960679729508540579777874024303695220358123384040073136362941154179903073853751348783 130 | 66119908256246872840346469642645062989731759913873588474030503700804705495561024519975528094343901547467616100230679316095407944437525712944273055795048243896236893018767076707915788318671201270288408715366214924470797660419807123448417099118234051711625154620677360553397603216260948991060854303857217880523 131 | 98140783264890998181718543434991845176671830302345160388311036515210710932709483311290176809741880893538677014608783672415369942593264232274831233489386100104896256508225364550697776091353806839123804114799081769231137617459340377190008163322227363967523633136322815774684353089778892176016017152848628763831 132 | 91633595944474051830555614879901569286595909254862942387176499441155099644781506440259193334898299333022545082504222952684192524753187798533029704501190833740472912371398833421796982875830043976656062569546508813437743969760104295261813508203018521690300946175934944345038597808124644822110937756139545904009 133 | 106581535619534944725872261762838174220510736640384147766237984305106144424638110006716610389549134064799070779940065510640874503012985059624237426257527560466716896753479821612118231803140829584091209641389006238882846574489854123508650165688426257342084373344541356722515104434664100581799598541021634715553 134 | 101388744666137739915029556551819592422132155211197003433642258589203048485860518632689669104445849695710419546880535326981697562489237706073755960237102965661709206596737497799615119908790598439401703344347213418966005979032656225107536931115576641364684980910628637422477883886577206745375907034869767454741 135 | 103501017067806460950178494777149185345041900113609311220054689544128849643099326230371409460095629709823753087840673845279351606553273816754977348120194046813161042346512363145199854360174420502972318985442076579408012365716629960295023218930250187491470524393318294990716642748116192187311334031783632081429 136 | 93210146525274624491512206943454638307990610407011384465633356851224324242254212741432623653145852438732140740534235418465112692756569229401775636441255632940925238540021913406902121173756100197083840432184967591350398166362385888522388824113059711934449671379310142524911876878836836015612428711263952538757 137 | 81187728441644276204749598325928293796124077558138354453792763221680069510690526681200283361461214521063569840459510165819629088105686139030409533177629942145420480281168590417506088874073814071711889031424597844247673885983378396996853491890245168329326971919895554010631683329412272139569141386628872535511 138 | 129833136059258508456345794380651084159886178316513341179865261640337732420012003851581499661940583749280143623548124933160774504619256272117092134108713208479288764870934100401825751470843525331545152252615566129164545030956736584303522306545911620694633414916943631045667967933227206206647911915158287304249 139 | 103519313565465305871748965227773130617825444842023223954828314102955082298232228734677473018614792769283635268217187889396735071087787118975640982764053698772491175825187901925853693814880181217900466772121934912060319851866403999524035376173574223067666128978668735772966095286931569521488968220043342111031 140 | 51096779109490439250475386008377057374199512613272486326123777964441710482191128447777147930020914724177018757421237351784046902138316784201994340982076716267869663479834216569903573472869372066964597375225394944074153975807302446651528872025243005383213042588937281101834139026685516590949828801466519640151 141 | 97618684518725134014321249621712025313642276201669511861105579033549926907549460945952730479028037005720509226203813597305664079598193795463519818440334690834276453890762943132859834104327341367569721005995205845140852013077507651854618314451178885752091796308641430265558046660225076402469319468082912467959 142 | 86538247132461779460443668699788908491867837403497954118008277138613748561436368417603948305183184978027510387722075701927996506923388494289441307927118819226051177749187660740717456182362615692653846705898648366995469083205638970110434998308915232491240577294179414137890234027254413159920434829827915054887 143 | 62839000145217830305724278007262110249689296244350549017888026867799688826101447526854615991054473722644166834942188970644331886955608799697264168232041564581202510197763551262343808243245520973281964338099693249883867263615919743148084373818377551412594079344258553475614002455553885325319236845772043991909 144 | 81986542822726067568530251557551766305153720356560735985233364736652101613568373552868608471561716609661712170393108820943508511026638497697368997486730205506624199499158932430943128816956376112090294894047455950391880899836428037997258906284540869062222057539263519043328860276863409474499657676896442096839 145 | 62866480587365857816256775266359789251813889382940457100861084383831410766729294240387384366686173329668125820669418515316854096997408331625372519139626476346601352137595736220354415164064005042951485879132255700503256968243693282268985695461653756455832130653701940473033230580121659887414012091527398663171 146 | 100164626185593453312364648032367476327692803884767487043514559091641391654266326718402984597633406760612188363376361661019969895798048329509897229446286763080897385070544412183719110647446270127243199839862022848110439565284364484852263561409440866321604831286839547602976547227456530826930933492595217822257 147 | 114879308565557224759417281267717557837602018800763827025075855927078317591177166689177534344672028029494138683071728322783842241260006967002306731356552242333085295700872140344258738386226270793552515018905273068511501186506287866815877991499775493900149659360663259915101118150357172138900804127613769750633 148 | 76908434932412014123623969935555730736313341861930122384378077815193363643284164277503827308293071796463762941016519373185154648636353774928489495393841084873329466590628698401313986038079874372524258391995203549903687976603639565521013396814232035714362076870409067043830784982419313986245226029854509679881 149 | 104350643115793805533269065679181815733875239250837917339189668836430284211337100932245988974857890890582992335326449203747557488211125180926263825836550768923226317498374997101216491722820065180674502908692348491102765598311181213966286270023114083114025487530117720371999251526548240477395658407009588628437 150 | 65764717768996272690962081439160871547340499499057727795047119514605118567923662433286429578875142040063009239232530653472946148781572930540069617621845087812603217922463179829222062180245284270250068257194348949672055144742842387017084369084933552786784400396317447267872011804810365560114418225129211455637 151 | 113465757940822012868212544648807334948504490799148196137065407499017729884988672806332809705724123941573390787330706296409341287246833410898605094228601371987540597562238943637348225936739040612254009593606551523019512849010930120329105659033440944072938142376546375673071799717682869781430702051659687430563 152 | 70897424137372678580383993638974433559788474230587960182682337163510711152711137856894281107804932014818236549725979272374214946847172200470328833767757977220781534179250966707453224332095456415137592544902657850856400229315979069348573839642074365978240873023539512754412848983636935525831276547123880077989 153 | 91534230211269874910645669267984810167851899200528751623481507738027165579767125312567571264427962179994501345046555443181834871395409171454025066799449371623799851347108473559481512025798984556812958762821527639518948954920217205770837465975341589920099776477717075685826964047367556278661711950886341833153 154 | 62721202406687855170570461509652148434374534980984883863461972842467376610788606463957993118221229827755374689271689436594043025661659485242465425568726403180678988993519172517289052197931724563065354296856075191752151561634328671996209157049123678158065024533682294020284170307384475286003388494107744944661 155 | 102373430006934960489334323262552482161382071288115587226947922863114790981482336545109569532510956892733672375846860471547616153061728352308875892967072674194838515544978597281666216270453808983406254314494675429485415101235954862487124732168966374555686764401923583828562811477738455421296074469197762055751 156 | 160450596359849338014117295976745452921775656126187320938143092910081605844512895987627959070885365832518773915000951073697676720953067356428003686511816917773528218523827357887301462803139545124134018808961013339314314165189984760170163330119807805230006300485996204599834306268544442233328319362359107766059 157 | 109683112239784938541757924399289138569261180032714157050101358321516751006281341451440896317195751997742987325969677066087652006208291421339660064542141080333330149314360636358396196763208499863045541359497088687935439137898551758438916022832856400585989893495567992770477711819633410526154948036449873950031 158 | 146821747764575598349514485841687576655188743381841196282388944572099991703663809120464767505463637638568738090223750260969750491919800548166802113068632681013378079356301281615771533364650574712453149304629596720757092913595743975859653407079543125526019017065409103244396029027887059883157069830367513564859 159 | 106102751617885649162916808335373037116693704003239242586937469434559388354800151667769590377690419192839523729143575129077734410531407112877154140044272083169283219740577566579771336054661791599605078055295700459169583595613140753056919713367001498859171012263297365715858196411974867267197024077639570967351 160 | 57437167677766741312945245116446040830908390389287823893169411754880615815259195398352985823750690429817794368848621094942923079454394397409005111952248445359909372373257828156891975846079780414456387188010299645200001523798966289418253551986313050231503498210619998992960863730664574078888075894876364116903 161 | 82033948342096783657165999157984943511069501167232237987860006731066839816440666960725566804100188720724212007097171208649459655865122008070297342545583160926231529336747312869235067484042628602425706441291043290630943891720920647592203454836247058950327035448356224066271949357557810673410403401722425472583 162 | 116885687888067225740409201809182770788212291952031224279426087567911087132591186032288815482834838625399981397807213351192936905999067178423004596866130523510255306796036707759223173933820741606720296528099877909497105477731398916324126212214412150044282633826937045173444799953763785774104854064599531892539 163 | 67008963915235721273983387594849195983643557787070195710492160254801199798402818872498361911584256608555683773774474036364017906128947503251016226268165450289085945637064437511769126105913274762922043574596062027476138419814228665422546908796879429045235495354223770398177465411609334294800171899070712774387 164 | 64811949806203711588952861154736414946889849337189363563945037205567668631158016823090615410712277365177626482241124097083529315423909596359841213515775092111232467282891996737740953984294841911914428277407975289516166934983640096711063950577684782344866963797413791630113890533775772356639253173078225421839 165 | 75841334827685090287242877104322833936740624144107188770682155976670199696106790918554851181215526116182520373280002187201089951238470448642084599534763945148835337864117682376875676483959569546995639031457186750326894513264670993715339869095243626325539628137775073267111210937504082070444815214698531139371 166 | 134822905208397114408545095667991800409152951586693853027024800213833011689320819398454718726902548382000545821005558656569763657069247499896284942566454153957139510785662119300636871912960829669117857348522280693532813404931202536783978408430462325011570253075466930180784502467680609244604970719031869602047 167 | 55216658658638569537037322581323729298606522093646178355173192521493037878720239632928970929933964852236252122830207948049808214965425288409900367282398538723996861750198954131129396031273604902811989758247416381264984952175378148679857536235308984330885008618117757050257668885391332005128712856509698290017 168 | 139224933286079983409846984146601169446030943036231398208365996878882262009626790371436132749177317553746842512282645720744374048623238860230822879013788528163105237294523806051398087027349453618050266973911857348224252890268346263615922017121866203858605570800799947885749379249116449337447483579355530349297 169 | 114124665895366388835654964571352908746985123881661041878135037536836483470843985559393459409400812490144787606150997723390003063810925196438571137789599119329238615892631006787120181074412318824608156895401348998976271555983208008096561092053611103948730197678815878984717850291411977012313214619428306868977 170 | 119513575039314269183480980772317014592535324329945651513731663729323603826237796962534069706178080426529188161572345613054475767904100376023083111592384481455994370200128585895638310648615915145267083200048608990723204310383002294570356618845656756068942658098566882961326450652574309402127681229912937758551 171 | 139343155966888876667157552168688204739896826812977825665899703780514746184282315024693866640254619145198807632314919135446323230977651184431206026246793273471990045877916587052720843508045786855539550828168430396181603265095997991387786388471101591885838488905401879163441900851733099511593428064729093374559 172 | 92252213743329102075566887969239558829271315666155322136108723948868507236860124753021805593062182762463835582296280364682060025246884226200938759423100868799315115645129981996676129661939419675725018220430064516996305941530499495955060343613022156891168185971686317825660328843366734866312876901005140808309 173 | 77330473135191702884927574553233759780525074363674197698179569185223511362980059776089140369947526324587620813759547793132222756334914292219071892390464534853702691098073254003991776712112695856440889566760865418415373121895135824457683027391739757332005945644199448956820129497683372306316399022842798042457 174 | 91611220058926202916841870585002551517193238870583828332272632810607341203606605773430994214177476412178313399796725109208187787161442035985009209586610213749991182010424506977342090665907662623105917158852141250563418129743251858350320405941721861899744040267279793190268062255940503297733920278312595513381 175 | 68335705050669103303511859723624350456198693967368509706799044096814058866768512105513344169195146827120542542843087173554704156209993247228390225034571351322222180656312904542771613602348124524912918827519522475273869870969831130300442806549896170747276911879825482921853048359897379939425028481596444709763 176 | 121534165888007361551759553384092125776735290266130462474118830205212846080108958075011653836067387627012641176204652654453768066371283863277158195608938293910501981252392212832557597311093583600238316716936797065326293739590537215467382167755297252866506903421372779266549445414844899709701372041414239296043 177 | 78611636029931293816481813878570565126391567458715695439658341488356651053696153579213149366892564606009959603581717283960098157347290645411131155525138790055420726553098727255933101221059302996685804792911871817784455468391200089052681729562705857221172613046903788613287124399095933995596212092443343617367 178 | 131780356328435774199784562999399100179698362235143329430267633854315270487432044979740962515743968318414431691556949773388162526380424714454543758921679350370272581708721036899038753242536119650197844092342160816814493265742137519924748699302007416367449616728143544235624047880920682918160636545275735907051 179 | 165392913100130766516187327800293567541645568595823726128701934914868100784484432797556808444457746943302631590846478892865783979653188803426490832559801009500727112555060088957927678594366137399444078266796132079013598530417924088631581914038615501474916921766633920841715818141464665833063901898668526254073 180 | 139780597747098422625219564097215912348897638071254805156843707224903380732405990347072630029448927590015968726144046196899257272518028220788287111415305897487583126561091275712470559736034035492393099070971886531204397639332180761665843257516969733682768546094647213050821243022642409484095298847681311824851 181 | 128398948582499097520109847311663353528473755755694174497428868733057810276894641985654115434564975189399161523285856850966111500837733851389494191497589921501396438173330436610677149487173023800059783046464379401794833434194188332672653221496561249379224836419262974594335465273867529498827292589250866196409 182 | 99595291283295988670873678193472748382313673345162988310895064315754410096083294033429519090611159380763323862859763562650429484440252927898111252653301533232294267825490025429179893426491032454071477158088004149663072623080695651973483714448366160857266751737708482792105608280536278983041283350424560894117 183 | 112807123469652865877844490337634033101119759952328917064637926901072114193900034440757156371557434939836220396126924005387152005128035504476529601893224927764462099672290334983022498636093900538794651546089317423527311580226230884399400009904268064162800051796749129887948138172810493790724550640956365249171 184 | 108300489815595714604133538716571619094995505299020745552741960873829951789102170264982552931475287244762630444307701067406576244102300926199490638656728305099303779671767293342363827310169296877029082209178455885506727108452278945000013824982757587105089346963259685705109757859639056220902646663210248957319 185 | 113341205299090747544381042455991214860808531017186839408700019414895257289362794362824474658492062747447851247438302510248544401301566923821525820590005463721216155122233721877041916658646826367315947166593400606922800589439166047418641605628147535937573218553219060549173414596186361518851957198534021822261 186 | 75993487624719079115419621819031287602741566096997458090147028622815276913497699106041612411991365730027779209119294901438936103527365683351485662867206780682634047345521247464678776204955552436627347613640100112060957678082755081782562809368843162114359854339680555282817822443441850576948900977857921494013 187 | 98236071901058463317457866279676421996388271686429501902783893001460651074098713471820022953586092157310194969070346704833563829561135525579795000891643780156964924291020517137915746763533879601635708513893530770330358644035849875988011013948304378569607975560539493509749309411598631005312961407264748581347 188 | 135866882179442535108220255306545659348270164328009772035551687975951742653820502841587132990443756280660384160530494686056879369680493450511513137331380080057241017878104463756471387905929752811923328620004552480091629055383749207675774573800596463281988425360260486410955923841687614034779909159320632284713 189 | 70877981075631929876197318746806881564981498003536766354898101457406173024291182446375244105016287320595092228290697932739822703155878277124962614366291498792288658227273594733340892730770774777101574010755506304731205770170432846868072072950835323739945323271769251580677127699928102532994707774557479921921 190 | 72403258849804598892507183598662704654933604789754125040526378248556510921236749036859961183230108141283365993060473042872730818213736595049147673020067582036632208167541141302361018053513553449559102463757102318633015542850149056262957348600860565086647797982380843649354993438647280981645622638758210308289 191 | 98615541488520055735252844839728462205865905131323018746437005837991991247022924962246736132805494969497170412554004725225737921725074089999424005656373121632983846922293388775855047495353377710993101680526067170477186064648410443798682821809597282539934727058121204928178225031545575411154498924463345845023 192 | 75214297264529019762303043324756972324549173922414391699808515935971264525104238697400367732840238009611235244615857537954689548381585033807270722851384684929109865613882709058698335860241598520867763766569229444387481718012475700140863971913775618991676086932932583051134160886028358208612053233856860445973 193 | 114767503376668562127203558089204308348361477001685240394312646669064761230775369354386675668422696261451596326524872797167095381371064678658598132381142308117170649341327611750238943150879639384883556239835636428590066017195895060504608886463089052785342740605039537959343222187199705646666750120080167523669 194 | 118424076776490696324040098832506522882722738198309521792053434588112448753818496345591775452419071181342448571071628454344863084654876478069643497456549783747444024363953650574856764528426074592302994893611772390926132589277499846660242666836170736003949722763531080919358010544064129524766397289858232339099 195 | 92078141818277062679507804073205738375276279517678121454887045505960674504058158771293572670214074486618635740315744376142828068111076616781348984401429074942493982103258484510750438392440044024121645859397617828699662366467481517166939446419645145531150806679797534766972293645457979944693401590410563398731 196 | 81985737014834244528016156730591781249179448287884100983906651677534511633000392521151563080493953629366736567226661745570167567671221960952237155682674353302697011292132579571601019459971947069207623432097207147086558721066223455477213156532299459595943559870509305550066715618040945678257783613747971061419 197 | 77520173492226369995464281718087637153734911021657600576388045395368406173992590177809372580939594394750549224938911138894815778771294944967583214351977187804398168422030668569424058758401752900464799308188265712376947557293085890333822750238476026718490178246442349737062170478792262471254001885558529035129 198 | 104238184395181937012306772326548792363507412470619470542632618073395285607684199806683590053663161446507727021976251193862367854931058074417242223540335460241564304352203898118779584089038325309625201647178982791358401477712867574515547594740206467032616833439309012511091659746625652445980960375406930735197 199 | 130361299040737677906383354945177428463085582683675775014466507218134364682279028657885159632140453915411163146800095891630176973138900561126656439248915057981066825566172472588115033944714328623156495164020608172070178559232439264486535373190384777174349123084657708798250043727056669103081607291830872099389 200 | 160460956519715634339355387042438655625122378154823642960738234809954448377459259766257059100101006654335596633464394115680879199101004478186010266083956486091527355723611565964849489665038111403114413528070882049035700745529993002338411717647130954662121215066202754522984117292184948399026195278142658763771 201 | 95394648792826293976149280133116934380655776734759032823572429828353655229028009096846579984744855695890235611943817252550572711637891872488645634051903284114417423020744490826869468915836521522662332772349182324651015045282289668590931013427600646208291532696940180942277888686329958357277390717227019069261 202 | 61449517848425416265573985559042443487462285017070462259717127520779363299698521627838422651025941044959737203934682254086303767890740871783429714635530916298546323611228122877587471443482644211570824082912702839006957396716756456281073556119818846320612346893003135737445450002528570629158365790228638171863 203 | 57346598754609736932722675503026741585827016828381418588434565889131716730963606178778989116303954677775902511750538570708951438155055570326606517675703436752511750311748022587905447241922102942557170766060775630860806223589234508653305280029066561700224048020653241645496984959433771025377580360820931274243 204 | 115673141667371703340412006900090656792354337968915289265587323418650406136708310784726811787757095560079912911645981993652832636049499995650054035369327120813990139202182270149058959024577242208218542797455050230106346578262826613743965962249410942636131817107389711779757640990427243238551704520704453292287 205 | 84783646890971803020697166877053893858681552245016590541846474968967202940293343251822981403738765064365010404126229362019406737540704245007584139049337682908034360515402859281541861207747756695861352382763808415485575632804335560476598060022742323130760504905728350637624557331295026529821437300580395668439 206 | 129775461523490791183277520176078537782904044262328824091169449804300542949462207294888476282445174455126648973900855256875289233723717116345135891460578760287406112497314708928468612493498193939297723783792083273124053932916710225302492026595958544692409163552722162914829780328993639917314496746331335345377 207 | 101777438365904402006681396102072891527942005807193649063027936257749310342452205945493285431300819820483423315341925969718435104285058476665977682017641733448141176001048198831497118778127761586395917665893186335935160164120319965771692673210910730288351434630026317787979009590766560234867225731349446525813 208 | 158385234111884477409822029084553561399455533063295666763851679667624496960231955545663278076983145698186792283978414008003467780113771534779018484063801308428486996276231291488790643890913991057342481905418366747002299838944696857117567488707950787052189513423571789593037366588511722313828997504371929135443 209 | 85360134469718347700451563563803701771757486981941177088497254409194947931146633333616649709057397716286335400072891628063550292987842783218844546521750950151973932723469136336647550172002933328980880478077601160652084258686364466455841834713265451465169709859002528882616237051079992697993123670102146556737 210 | 52904247298466773292381382358738380983884964100982895174656613005727617792757557093298664907343882876790392157039376669793661786766832752137357099239152071502213241614242040395332939005445286717455460011263801494108940578262605527072377816920792147013538404494587454970956963786829518540393056100129998490517 211 | 62667490543819663425176353881227792891469851642357361579436528485070243125922894157720237991259937354977123343923953676717892631409820893457794320445200286695468723417167509276767624455227432568982118650400955120503350731373537564163691419200527102956576820106053981674354327102661155774966121437876089883063 212 | 89533130108150342843723393236804883461206821406902707797164079247682643313768087790855374748923628610354030187385180814305261891955311319411713999284478269185563642384509915279683345285856692078551330040180688426258236761818219212511001464923073971933196555511206339571825144031453220962064390299345888696263 213 | 137700758119572156237174083922562316555992376538745697911426143182020783410842514383875255397132798493176032477602714709039406088646494665086590138698586693096052348086164217019102399867526192683839941417567581171741978048167558689348840821874263220061464930195394942155854413628277970736732057996439742131227 214 | 83377162172914404299330083526864847101027170539562879905900500334267135791371386907197753918680009295183796510065391927255618235601284633557851894192681464068691855080236081045029199279041517034037972930705238111290124477782297212592428335222193761207922942580165082796722792033450643945565891552111410819081 215 | 122906684342080425888044667488490027142399840181917145784417281288835464003128486572921832475403146737741946248614914843600086900995459674739867095134045152505992982153093729276040728424311594752852678133442775991827096047561829333861189135903143855546147688474934928926008079242722783788609029982509848944847 216 | 61523309429517033211090296803402821880858007574557841456769856279957070197578882961238440767009933835938912339221435868329694558092987837100183560399926421095475959353999690350155539132524471714257080974720394810069462087337550458293267494421560899989264808020413266589715280619089632358039704116206194417651 217 | 96827777462527896749885201882413834149924640986765492346083221719236450220210421230324934126091609949714396075648637695763039389638118186674985199694317551634018296728642701190650419149565727962189314463123765713821255780559646169482709351370700587983676707583630982886081661693741085590735343246187136849199 218 | 85585681467920343508366980948473359271629371543478906560174411459590846455319807075372445567277769705217927216383234698455634640152023384655458609660015171600602968977426036425491520551672895526118511760916235655389376523618571692859526714774716927633531030904956008977078407110472182978698144408442551668753 219 | 130008186781269028428765109532746562694997142488727849415702810963790542013860905434160931171211641070738993292466799622028734988808820502439948344347657359370146378797105620959097941167057481467268793113018961519796486881492177363490990126964308122363614484425957873128966818898143256490850685681006040630477 220 | 70656173160972569045388433520799876910092971638671659004235892638771521433322681696012719203088391746872509173462037427256707310041230907360481121383692759504468339236013476343503836961642798037058084889989627662214704270829931044912891765187370876584638415507687736860332775379305212430455731040081315260821 221 | 97533977213114688697332818052947227589409970205189702924738141837620912753914431541978697728938046557651379225675192483039557929828733897708868872322254522033807094767256765405751637898803534637741004575058505977300650846232071443776300316350978522065138057860550818602464918332033712117513093078918271218857 222 | 48395214492915680588057602433243074753611047785888416734873196298360109275626658634834754893735995787687686552288000462445433341783973930008895148101096449949170790698450779098226502220365618317039915712295171708620085650712286310404757997762687794065320941243571580610153893699462989248246111309198456015267 223 | 85943288717501191688861558858062186743325463037678979109808271669407596806095841878964931922319926762835258270993659072461632036386588066760729783583893537204004951813982852898915121228168241421237865985197388910211070569326694305009052104354715146242499740397191587476869982156302738560217910562358439516463 224 | 90235071716769539768171818737709745663435580036014299488457135920794408930810102703468417011644135056265921653520449409200059427225689480086942604976239807077962840058306704084199162931710664553621751627123417897992690235337197627136917286585017613843961450182710040986459639523342303569225492668708278749321 225 | 62184801919922607149075591093433213599715360370009682188697163422394160673654066896240958077324213764396752433781904619773098553088960992873524775298686762000119372087586819566852876694577169307439867015599067019172576026562153871371154839177133070870503233799524223907474464019643168038146790328401307309449 226 | 90274229849331584149566197736811006954051872308186672345315974204108392995379469811143034322983406632398531723795061421517648962913386799824860872749742103424108299966321224973982782412078541696634905597513454101551456402028713470587277461725829015643460364743060859428717999727684218474613669219197329548177 227 | 92751409108470572509000165821357014327512330888677043344838300041288718214478827801114804131045694007366275751266543715149934066242938724320847428157989559455607619118745381962133016708675047254650506084170317535342937323918803849740804952109379157924469728871706158637017084751629438926615665626527981726431 228 | 118422731867860221481594889736527964149410961927552271178691014619080992711597629933028317922566537104347063641738617932804190626657602835210826897533489104412861493380524368580036052059843669715912938240897478987961240684770999667724894534142131442525916918392848584280367068122801257982691692017827749777333 229 | 128257929883019049930867432020100238895029876550387877992700594772710991195389597087259298069062563737495159595429823796623549507500909069774549349364819262625893388596173511883102007174231253262392942858199905493776930236741202964723983224875855102041042702863030746955996973226968142953147143029886602906921 230 | 98490663645729068345326302656256687241448673958671409595910463325527301820856772385948572733063805083008667286055836372231782282974768574313133864908154031536671779653074257914396200175493324859939699003872029552781625394949750626738042456972574495266759121590621883706358282069328523485308276864330550685589 231 | 151811051868148206333657221732681933737007652698315871400798289036254766365338868457195503294759424346014571918891396014671162327952461494945380643466178432371210836260280282855724357234333558990794482307583631985963410968812652401511847001281376690787316464013892416896181011134740133010636024417861876336219 232 | 66150181266105595960088038170422041642111026963051001340877524765742246091184942943890627712743241572426583328997969957074234986012072513175678153512117043637959433153635410277165298871280296621526254510869364766687660615377236467980137022786432884965747746000369445016417274805214680847402964316386357839209 233 | 133858157696143811747616047314146645888238075230369826444555721174751689871357140108926595782374371576077559259763985013370067050233567948667749323857226983695397050353954001738196766298873883578585198467063502369589839426149081714602989952184280549929016785347833177314551284153533871087963884660486718960353 234 | 60211129122672726207658241560531794236102366550718930620924481093464685457593544866916190386932456065541737812446313277140264077362110479367546881851831179940155364470409014292269548722247464188658813515884358729274199146215402886961108676561472371333283953126563482688033678934084647761104550199870409792893 235 | 108443877379623734737545857016809474875953641890356710393046071101695911174644432832993213811649872107946917901172580316372745738133740708590462376381356158080128172316542418744488025852926401002893109839494242333600312379138550887357770376129746994902259275752107127180435701767164913336146310361728278348367 236 | 86327383935426777666650300897779324898486707183029025272829321879412492201935574447081442282352851830047292894238652887387518166645954762368052552800670437265174539314624769461169397769950399518262036054180181192764428076650130914908954577434286316236374052729355829247902957724984666782463697629438980160731 237 | 100742628349033405561882882347170485735399877338780612328015963115369236764288704066330798435706605163634416499892872658410476836525249623289791654462573492563735018080503460545100736890809755644389336932362092159702997455658185593528345241244443573989601827335786641815265144377593850676690391559101942828113 238 | 74688265340288593060077284163220762725554642260091503829565044853765712831902027933928573811067001980200253319793065602177622930951811815306343971590360342465581229049989484633120369552893880408829576361735328615368900325340865468155071364674529049568635039725583326560417369646465762793993997899969782982301 239 | 58545521565925099916837991177441496110383139491353114411475982369034696707801742999529225836153975114510016154517369990735118617589868674559547072039746298011383426953455689402615759110079617064400170634893784993579265270425330076017971192971115502714665193699371088353100844663698622968731296381468980018007 240 | 90471888776931777906010868854044399455357221947704796651646359122327128532371553218361018298788078475386344073904011344941890055763486298775891266496957576859181139049078224218408998730962775832592395309656762803420384841074781355168305962390774394169406949040545442794893121341153492259673239745352661136311 241 | 110520263997619922311181654031367724879892335235193112420200218080170674672506627172145229673213338637394404670017793030427507051225885103033013339297286190905455713016371542887517561739884485356764783913029802194907494614562537795098608749175837030198935779196180232725853099270149678145866581959995691238243 242 | 74101986306337745146670550050154126208464448276002464815971929230885688205710485008935896122905946502939258754807427727791797998673569104742303006875789730779542732737378879282428389812487349971779788579190986381032942623917739587137317589651198077762731760680949426944780226925022657563345806473410829905729 243 | 114891216000562586945250529958477746318903444525459080151511282078830433220049774257874505634684133307965212207394399882758020492708019365243370257148338837059717394251457888955676617082746508706351354634332243325971829491798352697943189575114498535822070778043227779852921346363234859067837829014856514030947 244 | 71524479228571628778314122298144481605213393578467048023489460564594443788290663394169042982027110067312709800305061883258616289441296372419759648489844473617684290343274901127385621410464429859576718793146678314377270960605401823508015690429873722390104557184877609307614198568432200399529091691609368627173 245 | 158444256385596584045650518761751931692969707501216053202445287306448137147439235318964295843360177407137628087314382949350630680404957777633751365989091782388164128892386551796188904133651330335611021458035643717175976073620577865390212997173016045482260686150614667383416086123970168146810955186581798024893 246 | 129429927855460065484117606644743740436539730551890540602447446375484148329682123935766801215154631124946359753319167736416750227306649981698149081147405855432791608232335593872667794291181347638114081153395825768304907659871568428620016324719459711614781549382165011891387501784946313972536258217788907483759 247 | 49420581561813315696477214039069290126768523092399094462559940348395619975687914226627789079248372842240227059134528391557393661398216299572854964388132419140347878518416780065037105911993750013596274613804952693246713281131418423939225813433858635322171698678078677421868924894008986443320586992390570942339 248 | 120654623963674430211910746097916849191989961532617958902223353011242958068602289278850093799476398536862980357085278621539999594387506968364095081805200930044366836337171533380471906491714538016137976746753307101638127524202529362680348853901127322565370048140694952487015824862470419589374649952272258806329 249 | 138673381099122528403839629235741229002550005574710041738027215374789243063379015195445615943047219062821782756534840977898460597149887897503939141918916738177727872017989832656550689963311788348536017217330778902500563782286048070138622483674484956635738196718199113047850166298733771646281101937076300126467 250 | 128183956391328180212744980395037386354822793246032311757429951273760868576692999870917724871537367521550218533284438872565283999878083000689551219845015527952268698951659811139297241274193977659968329936326643247566073166025194514505266129872284839914388133221808731167634206733139529855111835490955537721143 251 | 132112811023986099963202508999038126413322750057211751581163593930515344867623179081763692373668134984375087867658857380579258576439122442534467232316932304815000150304971019184346566924154803105870342406988599998383014740978806234160018763006770677635636800139627298309185532457025884523302837319042473174147 252 | 90559325516755092914825932983336074940531288064896760993431282026893864863459035478082092516013523240030643684699724947053443359698108889144072527959630890280027671904648003686097982232033311998245996649320783716613605414501669414019418648927287498576663859769470588101601253845308331562359885444177229655137 253 | 66773933295197798424496142594409683694953523699411135050173897846578484545431400219923515380989400719233139174842505501632677184741601296212752735931029265913582122870770092642242635088176130659943412430993700940241934487850599719932871795005315832482997749260884268859309084602124774668234991027712099737861 254 | 97022361254153811989421561245017049483317949928352455068617723101736443827530714326485184056201706550578585354539673712920974214784085834097405898379205667713249065837926326578774889919941269158581267172509345411077159776188451814474404134407434866633073003577812044830839048909384159676959010958841802823461 255 | 102058479788329955493657776097197496374959953575738396195331368301163835921249399135633981571620760856312145702389617439555097781771174308083561194329771764321987442172253376162372098192536540149349965509610686095948133838433972407640580124834575867920702561884929306018006932776685253920512003974028617827653 256 | 106383689639402634462101279089929734192265709351169096519365049450026561783147320795119878697189638850036589651577217347191339831327252266466524561767707077069231459574109233679893767268665280381522887192484297367971708795054528683580269199569945161530042427514517314944133876190985363818909840413638613968259 257 | -------------------------------------------------------------------------------- /4096-badkeys.txt: -------------------------------------------------------------------------------- 1 | 102515797993281277236432700206817176474271936522143867167046744600309447067581286440915160418167650601275138346697227599301369402602151218252304545052660551854352733833508534369488741559682579320012167633317477602221396192188131795669205089444988328585821653479081346692328102035513730379027666872808042176631 2 | 102910060425861784779792064187506821427812087295528095574738514885563162284611560367246257007383156869631044024923723004703881617353687019751205649246793392112233477854385421661601778530690583481888003761598691567516748660018461259819515600547187924356796889153610349688483664079178968725405659656114173079391 3 | 104062941593878999157744070503138963050542637303488273547841888389127858932402180488859146177147550624506286765855522150046463026319215723778425202462034246741864033560027942221503002560206319587589154248014801244088375840583229435791699293056524432798667779405007301565076457671532433071532348399726483089613 4 | 104571518879626542066718946689141633482334778527856717644288623072432363733473585643695752957257469807524315983002211508941476723943988883486963161089579632791564002240075263670381654555978415843985239265813157378093925713546997594723011979133620890981684146620670774430738026847081695880967875362608688933423 5 | 104765793067047843356303731720780155149760817385620330236724279267594849443112611876191865775161273381233905489864906518749408978114132003783715621405699185664310448296470380243579476568150870760664966245440706527136750967200678561009547031411691103235648205251897918670516341814825870731707711104535102671217 6 | 105117725537141047603358972511640063399547241723738544932444662492173722733971452674657823136588290050509145786743465287182541291093498060615292816904309882593515821334305291327521075792643671859338518321981317946554725899800330954266461804683826673661395608706583559596193738469723696142681371688778026432033 7 | 105295606594987845165255858828666891311408201961435430991188102424045497929542336182424207328950562170924295496350513410307787346730516730050009710861322413053852638186405221406796308078935391416550932837237157124623340695404051178988645174302001452495755054625501378826266696651329364661521057200246338023581 8 | 105320409800470740763170286700214675957266369073132911226584546739179204309690310618967494499300971146650877848372796501792328123424066368376088778167536407868496255223763321951444852086367469192783292337272304472591142248005824184787420888226641383722486443334792505234047597818709205351089968231559751277497 9 | 106373029552372682810952263802442131383014610706893689159811205883745177747265178421505430829323330044927180169902550451577262933981053523033506506047634577035063355793477839648752563642889375155564120764390667946341412291652614842169732296826339914600055730041272581829947153918059862423716505648406589386891 10 | 108253048351123936283471706740919838018629859027241028260915353374637211988570237867134975331502860384708934660910979982359371099417246511988276307076977648473988438345649668097586336764226893102851579367457759065836264724022529611344842235658833909900185541675291990395702150433741597914618555195083502143361 11 | 108575285941130159075894184482527684311359002046319438766195463450455740211838797843299740722811050693602257703890407909794503432098337795478505116757818207557466161995593007626838887798533220406316322467279659311492486550664311061256184680188803189721913485002881418648055626815746648375354533662940902187339 12 | 109388091573181422462833609764454547465774273715497131249740992865834470315739412152415345738332399456613682178671662139368582845627553203549182284688298913987017225793231108735185078853105008208300715368770603074553180255761253270375591134673174329374868378272682846285106078437198811462108301561643136385899 13 | 114637737101360931121010153811828800728103048873411829993719554985096803176266106238419344318454844941162553803439009958135221450521072325184125967349425701565823742418273249217689650177670831274780413162240966370662182228619473369149672443048357620121503444065512020550671243930756529377144065480027412949101 14 | 117084230197473146777091654920329765976619879347283092224324030929709388465571359156307525375641628479019738106826316490581056997839120494246817581623682940444776038966276950284085387334822980101045580871731833965948638081395315187673893118180606811434430440366987658255470502966510402212656922946811702216371 15 | 117236936922160407038064846191476527956119938662134348997748890738090359622002277768579786944466295836154129196616560582497151514168161736453766603511577771559729948214687478390843235783670330594291231029352017950861879472884307396238228778046909009074129733201081629564648537223217032870068364791873550135167 16 | 118375339839303665927915810570233633666052169945933263274301650458089925690324414660710972322451295707882833141335830032110095762753076634746849363204427919541004140337468568355206375577290435080688395851701680383646099154810203522871302990040415272111288627009103340066448180773619951958936183585179422188309 17 | 120179378912191096699555841395772866393428098893962696357673558385941069510671810908965389739994099244830373877241358171724829657015925034438295444114053599622667137174279840164761768193341291625353466413571045670533420455344765427697174307904155464661722946054428550138956845390692422987719767962128583841879 18 | 121382499762018828935479056019174776359614053798920088886171944151749854650535441979508266659117782467194119879042365283478437781314426033111342236354986645917208041086164021416066079359003752730439362819074468333348577265258763639751290481645524252317390153896954285696392459395748073170663107132768363388931 19 | 125872886612891135616726721611793735698204640858983520953960078906440685787822008447897232444940660037791134304628746734060573220869640598851586813832199442883657716665441187969890391072671728469161264874232136931341369911367427405356769694618589432266974307421879346481224664770179782874981713315575596797331 20 | 129326747822253535058313134202023951453820931472970866194532396068826944456955973362483654831649601870573699687216325946678265853319392524941767380720363839731342971987055920156979211341705949485145340055863949543332364470169084534518299769696176166738802340477815109109118391602863337934525148558997711948021 21 | 131973220263665439943232150023767427493844406959075616923978821642493742343745642140385888122001043380147622744168639848973824436054199039195546157094529548121784189176677813411270426288925846014003774109898956888901460724429830272775827658877141327082478874038918151109055074249540676936158534899656888257103 22 | 136421867620353130399484841360275797427828919077383604522927080542251739863368298847318940479872288905530663239757755178674414935397667050019698995582577350889665228803621791396590983729388076786989112059043153754720269490238253395664538864672251291014637984376897471137920878076540484351004707269261480137533 23 | 138074144380086564454734418854111041002864188480283776372797014154909058818453256499324346638904619663881455482122176777717463781499337351757911925588460221036455874478131722360889640930126931582157258222453820329441539032571463450784385059055236191882213810775853781759477991480869052351492687068905741618231 24 | 140037154451508263722667423235514798007108919658713837531125159272327133360759971061582198095903275418276428183921540701585005634348925410874632228537486697328887381191614961774654919799860935103024305134229160867658338261391383685243370308265050638017226636394334568181464067471525458366887129960724158518349 25 | 140530241704560021988417808085678314746705748812292465558578989027692624900331069839285015936422110490435856634501644955121893488713424084468701649615506657939264941862777285031796454462520371966261402354087621989533993665876494974122119939241924173183071929766396096631433057219931016476426822920362012142507 26 | 148957172982008695649414517948233617953134706465681867364753765356869696377380055453528639159157329344871100348218521390834007744081082297365000358009823369030207468190519584360382672877506805143602988055122424582314723748098762548816480565780937350614199412185768064011099464954758633968330101695971827446563 27 | 158539398130781595960162714052792706251967897236748423462721854102212304058470627029186816357470113728949208492684281314342025363739783552571688280382909930380170658060617627671198608629018975214965034230168742038230123329728668595089187856979344117219439033688896369739213809969989280056223086607317374238493 28 | 159731456105712584889078745218966158968116874545502217597047382283437684984566814616180900628775816334217255232870695895933484929084495863262853725906071396294146415388607098843905084163169994380303326854175089987890457415287147010387845401925665294610208338536282766223261364460252896893033330574859738093703 29 | 161073566367903448923634503501443713953334948892774677965974980442603692436627877297959123153055924960866308868567187377104106548450945405107422321577435475779930350940692995836585880649835459529147498995095516638267803933685775601878061547157589311309953640438209105788850979844897468897110303472674508153697 30 | 163093141529367770252075298550534728800084678735089109497098132363673060250999797087656091741702154640161861288695809125263828561969800270394509247214785909559891040053024869954985038607887113811296760087019798701112665511267420033055813549864838297792525464351788085506117154000658713418115957552906197139653 31 | 48184963931784109084247182230840634777171259169941654231458169576986396162378827524423642653638757165218345030422655123079459959449929401159755942860381102197512276337015948668996185605454957693103190380067127402069811655725213048887890080304011527559052167314081845453680330478875587238916793302306321197479 32 | 62553665668304463381576069606930708971229201849297655942358659962234226150753643577344710672225949422379029601829801669923502736507475865249418166677067163091671896639025896811996265062682020094874004818305140144410745577169792064488356581809964966218302001803653246107163889991300220057906513621561350680669 33 | 62625354256463267499982641494768210931869678138396940120250687941315166222525051286465171290450698316902860162154134621500879835613589273692051012445046153749606669997706135042221531155195609099690527035438341894003349726552778326087325857264831694386648078943643587872220547635417560939227662049807936405043 34 | 64560188022061510363316177893009189370559112811247400321597549410655467037711947892205821730889145900624731698451797585631131530279457033760364426331879141414561430116602609794248597956252995588713206340103415002309038802185144898259450462262774141592959792562663090303864539333592808546570047216563327041259 35 | 70439205889832070993742574727672395675865124600858241095676391011257305953277612914514670513422252829593579668007728621091736956555855810465183223704703110787233563321998198499122407326142734468353140885211655836486419351642004405957510442456021820356820259295945423819163072436518589465008418675833145920521 36 | 70447704489395526548330391606046026677133004452784555847681865249642246142343696222803772948687072378751154545322417181915151277131637223103125790841789292284548411352463169186092807737102239522043151959922947812622673264961072684710230408012382035710188631128189513554480284000955191624741581562444349115083 37 | 74377674780533678791215403963086085245194074011406805363858386148218492518200205117301367115930274307905691601380900585937279639712611844404416921510014372828142313089541835767737521982172254576107727208214555398976860519502723004528559884207556653146300867841185547531319614527916511483160531207613950448819 38 | 75722239053945892370066387470989842509676261802338531645340591070675734511824224659707978370718278772868207061171193552137431572307861240275958205296438106359842650375841381092810432583708534365755070218790264009130943381019260195016588813850529481693289606561513675340165702163407208103643510936227759800223 39 | 75781582872461298447864325665380853604291828910123881697895997594448549576165532252795009043918738936434846327266446044686574525996036094779715976913950926385224309262261111550066952876199540604181964612376493613754106993464685279105720891359597280452219841796573861502810666413515865621772816915555866349527 40 | 77487262163158136295779851458536104742181964632692324462778574345224632506246371116650751738774569085497364713743481413677751116827880694864315327319585846230022582122400355474034722023554874936425736311731736920312785221519419497693553498971705980270318871352045997064304427991516545896856453389155565920603 41 | 78391282597988074299570524769100952311617178760612944414019128892250588547071269190755940356560095886057110839654370989780071098353232009841759570102540609303884754536123964896042547376769023125847763708304467437095534635136160490170556563887855449159977827632596617347003133328500803990609824301936615190681 42 | 79960903176557136666837644501474843955489166071110382548805544186103439436916124607636585859570831014973681262383270355354259977734100537754312993761260389040134179288234520754806823649621467038462361862113376166103480810630400047858090508651842393961727442931254207365211060392179478279950243880080536960159 43 | 81049753652895593453231396435041378334397003156037369492234061476172274287584615938826389562986284913738246387494827546739397215968631521671268984242806591552876588643174527192537875245399710149646288877692546868283780577775921797036839575403484800651696043510642751926268619157228506409591350597337464349887 44 | 82516873673245997657843671590193580984396656569232186177072596566464512408116790546428159543508887094898027852344557171021658606470160114425754947797191254911636704500664746873793768506981904552714513049654088185399493856327643901090163825418858200174594161166309861528802048741952578963323009451713665237419 45 | 85685560898153751147770173015019128945505634661019967009999266346770544934630226794970580806986890106344199113315329866389828864005697081835300930653975135187251579270131785855803190953895748722406698831080382947348426987849703062103265194866184497031806428041411317922937429737227554660992921975969827345101 46 | 86001204375139247936718213501173282023248918159542877980239108430589031373013118570589863481332215321315999650278322860497885106000679738922828432957366632627170809641454615822836771717508949941202397032968934831005981648864901925033720504980805577427143951196243813463300865756264309015162024303842985204973 47 | 87563691382017194736349638560495904887453555149769329115282763258546485673262052241483776556674142521957027135857431981847570138271184491031524806182268445501082675765223153652516424861166279141964363625374289258705109338006804725884137297952510152023005128281021899844863932438604967927229671517269166420299 48 | 88144498553698481697754040913184958849004253179394197137351420556655622608664867906706767336279223255266085215631718151054178750205956971947410433695779254783769476142653541428341710552012281541230608596385375883088746598598866314534924409362644822754685887605506393905377137164191151991991061475840152159613 49 | 90888242235815501912471205125233416929876802917165902660624856138376769364690187444767493959158361175539735266692046094650114148378122892954327934420917301190946634714462560438832438305018311558411939849740665033959044542989372312069030467522254276259583727199052124046283302559357502663677927523655288698621 50 | 92107909143973142162132765065630456383034934332479993407882779533101605779241492441039281680563152034560613511871196826715459446336371128502298722987012056635358008309383751978594197726509650215166906423998016421794531890736214446869126836993210713754170385013530475049404664388085542929728158591712948123091 51 | 92448245879242512557472047937115923566191744149184393604229840631434600151803807033480502468249659173016609924452906020623030193815935552596550765896521992918236385901309915464144429894868298784525684316901758698268782459752910314742248628338331517736712157711559644974709750427356557311828154611911080396863 52 | 93658572174155177551592710288671080298094418635701220387478502044438273492342912758722127322547458031049104907257958797101793473217058885392452207161609960912819011257006737275167900670043549078261615869963463463706710048570807581412374031449534408109828492570846679466375640974719103360414346589647432097547 53 | 98084724011736316113315414294108584568284623675162334518240738842483907812296963000749609918020347064784298948950363403726152341598753136342432994599911452738462225874840468581907096256827466872034818127957115613221059825314932072854491571408134311213843593912641140090631731181201580171605874361664563935927 54 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Mitchell Rosen, Christopher Wu 2 | 3 | To run: 4 | cd into parallel/ or sequential/ 5 | make 6 | ./main keyfile numkeys [outputfile] 7 | 8 | To clean: 9 | make clean 10 | 11 | Performance 12 | CPU time on 255x10:/tmp -- 3636.81s 13 | GPU time on 255x10:/tmp -- 1161.11s 14 | 15 | Note: cpucracked-20K.txt and gpucracked-20K.txt are sorted for diff 16 | -------------------------------------------------------------------------------- /grademe.py: -------------------------------------------------------------------------------- 1 | #Use this script to verify the correctness of your key-breaking software 2 | #The script expects as input two files. The first first is a list of known bad keys (we've provided you some for 3 | #the short key files) and your candidate list of broken moduli (e) and corresponding private key (d). 4 | #The format of the first file is a string, decimal representation of an RSA moduli 5 | #The format of the second file is n:d, where n and d are string, decimal representation of an RSA moduli 6 | #and its corresponing private key d, delinated by a colon. 7 | #This scripts checks that you have both found the total number of broken moduli, and correctly computed 8 | #the private key (thus showing you know how to factor n). 9 | 10 | import sys, random 11 | 12 | 13 | #Open the known badkeys file 14 | bk = open(sys.argv[1]) 15 | #Open facroted keys file 16 | f = open(sys.argv[2]) 17 | 18 | e = 65537 19 | 20 | badkeys = [] 21 | keys = {} 22 | #Get a list of the known bad keys 23 | for n in bk: 24 | badkeys.append(n[:-1]) 25 | 26 | #Parse the keys file as modulus:d, and throw them into a dictory 27 | for l in f: 28 | nd = l.split(":") 29 | if nd[0] not in keys: 30 | keys[nd[0]] = nd[1][:-1] 31 | 32 | #Check to see if we've found all the keys 33 | missing = 0 34 | for n in badkeys: 35 | if n not in keys: 36 | missing += 1 37 | print "Missing", missing, "bad keys." 38 | 39 | #Check for correctness 40 | incorrect = 0 41 | for n,d in keys.iteritems(): 42 | pt = random.randint(1,int(n)) 43 | c = pow(pt,e,int(n)) 44 | m = pow(c,int(d),int(n)) 45 | if pt != m: 46 | incorrect += 1 47 | 48 | print "Cracked", len(keys) - incorrect, "of", len(keys), "keys." 49 | -------------------------------------------------------------------------------- /parallel/Makefile: -------------------------------------------------------------------------------- 1 | NVCC=nvcc 2 | GPP=g++ 3 | SOURCEDIR=src/ 4 | 5 | NVFLAGS=-O3 -gencode arch=compute_20,code=sm_20 -gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35 6 | LDFLAGS=-L. -L/usr/local/cuda/lib64 -L/home/clupo/gmp/lib -lcudart -lgmp -I. 7 | GPPFLAGS=-O3 -Wno-write-strings -I/home/clupo/gmp/include -I/usr/local/cuda/include 8 | 9 | all: main 10 | 11 | main: main.o rsa.o integer.o 12 | $(GPP) $(LDFLAGS) $^ -o $@ 13 | 14 | main.o: $(SOURCEDIR)main.cpp 15 | $(GPP) $(GPPFLAGS) -c $< -o $@ 16 | 17 | rsa.o: $(SOURCEDIR)rsa.cpp 18 | $(GPP) $(GPPFLAGS) -c $< -o $@ 19 | 20 | integer.o: $(SOURCEDIR)integer.cu $(SOURCEDIR)integer.h 21 | $(NVCC) $(NVFLAGS) -c $< -o $@ 22 | 23 | clean: 24 | rm -f *.o main 25 | -------------------------------------------------------------------------------- /parallel/src/cuda_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef CUDA_UTILS_H_ 2 | #define CUDA_UTILS_H_ 3 | 4 | #define cudaSafe(ans) { cudaAssert((ans), __FILE__, __LINE__); } 5 | 6 | inline void cudaAssert(cudaError_t code, char *file, int line, bool abort=true) { 7 | if (code != cudaSuccess) { 8 | fprintf(stderr,"cudaAssert: %s %s %d\n", cudaGetErrorString(code), file, line); 9 | if (abort) 10 | exit(code); 11 | } 12 | } 13 | 14 | #endif // CUDA_UTILS_H_ 15 | -------------------------------------------------------------------------------- /parallel/src/integer.cu: -------------------------------------------------------------------------------- 1 | #include "integer.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | __device__ void gcd(volatile uint32_t *x, volatile uint32_t *y); 8 | __device__ void shiftR1(volatile uint32_t *x); 9 | __device__ void shiftL1(volatile uint32_t *x); 10 | __device__ int geq(volatile uint32_t *x, volatile uint32_t *y); 11 | __device__ void cuSubtract(volatile uint32_t *x, volatile uint32_t *y, volatile uint32_t *z); 12 | 13 | /** 14 | * Kernel function. 15 | * See "PARIS: A Parallel RSA-Prime Inspection Tool" by Joseph White 16 | */ 17 | __global__ void cuda_factorKeys(const integer *keys, uint16_t *notCoprime, int tileRow, int tileCol, int tileDim, int numKeys) { 18 | /** 19 | * shared memory for keys 20 | * each block has 16 warps, for 16 gcd calculations 21 | * create 2 blocks for shared memory with same dimensions as block size to store the keys in 22 | */ 23 | __shared__ volatile uint32_t y[BLOCK_DIM][BLOCK_DIM][32]; 24 | __shared__ volatile uint32_t z[BLOCK_DIM][BLOCK_DIM][32]; 25 | 26 | /* determine key indexes */ 27 | int keyX = tileCol * tileDim + blockIdx.x * BLOCK_DIM + threadIdx.y; 28 | int keyY = tileRow * tileDim + blockIdx.y * BLOCK_DIM + threadIdx.z; 29 | 30 | /* only continue w/ warp if we need to to run this comparison */ 31 | if (keyX < numKeys && keyY < numKeys && keyX > keyY) { 32 | /* each thread loads its corresponding int into shared memory */ 33 | y[threadIdx.y][threadIdx.z][threadIdx.x] = keys[keyX].ints[threadIdx.x]; 34 | z[threadIdx.y][threadIdx.z][threadIdx.x] = keys[keyY].ints[threadIdx.x]; 35 | 36 | /* run gcd */ 37 | gcd(y[threadIdx.y][threadIdx.z], z[threadIdx.y][threadIdx.z]); 38 | 39 | if (threadIdx.x == 31) { 40 | /* turn gcd=1 to 0 */ 41 | z[threadIdx.y][threadIdx.z][threadIdx.x] -= 1; 42 | 43 | /* check if any ints in the warp's shared memory are > 0, which means gcd > 1 44 | * update notCoprime */ 45 | if (__any(z[threadIdx.y][threadIdx.z][threadIdx.x])) { 46 | int notCoprimeBlockNdx = blockIdx.y * gridDim.x + blockIdx.x; 47 | notCoprime[notCoprimeBlockNdx] |= 1 << threadIdx.z * BLOCK_DIM + threadIdx.y; 48 | } 49 | } 50 | } 51 | } 52 | 53 | void cudaWrapper(dim3 gridDim, dim3 blockDim, integer* d_keys, uint16_t* d_notCoprime, 54 | int tileRow, int tileCol, int tileDim, int numKeys) { 55 | cuda_factorKeys<<>>(d_keys, d_notCoprime, tileRow, tileCol, tileDim, numKeys); 56 | } 57 | 58 | /** 59 | * Binary GCD algo 60 | */ 61 | __device__ void gcd(volatile uint32_t *x, volatile uint32_t *y) { 62 | int tid = threadIdx.x; 63 | 64 | while (__any(x[tid])) { 65 | while ((x[31] & 1) == 0) 66 | shiftR1(x); 67 | 68 | while ((y[31] & 1) == 0) 69 | shiftR1(y); 70 | 71 | if (geq(x, y)) { 72 | cuSubtract(x, y, x); 73 | shiftR1(x); 74 | } 75 | else { 76 | cuSubtract(y, x, y); 77 | shiftR1(y); 78 | } 79 | } 80 | } 81 | 82 | __device__ void shiftR1(volatile uint32_t *x) { 83 | int tid = threadIdx.x; 84 | uint32_t prevX = tid ? x[tid-1] : 0; 85 | x[tid] = (x[tid] >> 1) | (prevX << 31); 86 | } 87 | 88 | __device__ void shiftL1(volatile uint32_t *x) { 89 | int tid = threadIdx.x; 90 | uint32_t nextX = tid != 31 ? x[tid+1] : 0; 91 | x[tid] = (x[tid] << 1) | (nextX >> 31); 92 | } 93 | 94 | __device__ int geq(volatile uint32_t *x, volatile uint32_t *y) { 95 | /* shared memory to hold the position at which the int of x >= int of y */ 96 | __shared__ unsigned int pos[BLOCK_DIM][BLOCK_DIM]; 97 | int tid = threadIdx.x; 98 | 99 | if (tid == 0) 100 | pos[threadIdx.y][threadIdx.z] = 31; 101 | 102 | if (x[tid] != y[tid]) 103 | atomicMin(&pos[threadIdx.y][threadIdx.z], tid); 104 | 105 | return x[pos[threadIdx.y][threadIdx.z]] >= y[pos[threadIdx.y][threadIdx.z]]; 106 | } 107 | 108 | __device__ void cuSubtract(volatile uint32_t *x, volatile uint32_t *y, volatile uint32_t *z) { 109 | /* shared memory to hold underflow flags */ 110 | __shared__ unsigned char s_borrow[BLOCK_DIM][BLOCK_DIM][32]; 111 | unsigned char *borrow = s_borrow[threadIdx.y][threadIdx.z]; 112 | int tid = threadIdx.x; 113 | 114 | /* set LSB's borrow to 0 */ 115 | if (tid == 0) 116 | borrow[31] = 0; 117 | 118 | uint32_t t; 119 | t = x[tid] - y[tid]; 120 | 121 | /* set the previous int's underflow flag if the subtraction answer is bigger than the subtractee */ 122 | if(tid) 123 | borrow[tid - 1] = (t > x[tid]); 124 | 125 | /* keep processing until there's no flags */ 126 | while (__any(borrow[tid])) { 127 | if (borrow[tid]) 128 | t--; 129 | 130 | /* have to set flag if the new sub answer is 0xFFFFFFFF becuase of an underflow */ 131 | if (tid) 132 | borrow[tid - 1] = (t == 0xFFFFFFFFu && borrow[tid]); 133 | } 134 | 135 | z[tid] = t; 136 | } 137 | -------------------------------------------------------------------------------- /parallel/src/integer.h: -------------------------------------------------------------------------------- 1 | #ifndef INTEGER_H_ 2 | #define INTEGER_H_ 3 | 4 | #include 5 | 6 | #define BLOCK_DIM 4 7 | 8 | #define N 32 // Set integer width at compile time to avoid other inefficiencies 9 | 10 | typedef struct integer { uint32_t ints[N]; } integer; 11 | 12 | void cudaWrapper(dim3 gridDim, dim3 blockDim, integer* d_keys, uint16_t* d_notCoprime, int tileRow, int tileCol, int tileDim, int numKeys); 13 | 14 | #endif // INTEGER_H_ 15 | -------------------------------------------------------------------------------- /parallel/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "cuda_utils.h" 11 | #include "integer.h" 12 | #include "rsa.h" 13 | 14 | #define TILE_DIM 512 15 | #define BLKS_PER_TILE TILE_DIM/BLOCK_DIM 16 | #define WARP_DIM 32 17 | #define NUM_TILES(N) (N-1)/TILE_DIM+1 18 | 19 | using namespace std; 20 | 21 | static int X_MASKS[BLOCK_DIM] = { 0x1111, 0x2222, 0x4444, 0x8888 }; 22 | static int Y_MASKS[BLOCK_DIM] = { 0x000F, 0x00F0, 0x0F00, 0xF000 }; 23 | 24 | static int *cracked = NULL; 25 | static int crackedLen = 0; 26 | static mpz_t n1, n2, p, q1, q2, d1, d2; 27 | 28 | inline bool checkIfCrackedAlready(int n) { 29 | for (int i = 0; i < crackedLen; ++i) { 30 | if (n == cracked[i]) 31 | return true; 32 | } 33 | 34 | return false; 35 | } 36 | 37 | /** 38 | * Helper function to read keys from txt file using GMP library 39 | */ 40 | inline void getKeysFromFile(const char *filename, integer *keys, int num) { 41 | FILE *f = fopen(filename, "r"); 42 | mpz_t n; 43 | mpz_init(n); 44 | 45 | for (int i = 0; i < num; ++i) { 46 | mpz_inp_str(n, f, 10); 47 | mpz_export(keys[i].ints, NULL, 1, sizeof(uint32_t), 0, 0, n); 48 | } 49 | 50 | fclose(f); 51 | } 52 | 53 | inline void printUsage(char* progname); 54 | inline void init(integer** keys, uint16_t** notCoprime, integer** d_keys, uint16_t** d_notCoprime, const char* filename, const int numKeys); 55 | void calculatePrivateKeys(integer *array, uint16_t* notCoprime, int tileRow, int tileCol, FILE *stream); 56 | 57 | int main(int argc, char **argv) { 58 | if (argc < 3) 59 | printUsage(argv[0]); 60 | 61 | int numKeys = atoi(argv[2]); 62 | 63 | integer *keys, *d_keys; 64 | uint16_t *notCoprime, *d_notCoprime; 65 | 66 | cracked = (int *) malloc(numKeys * sizeof(int)); 67 | mpz_inits(n1, n2, p, q1, q2, d1, d2, NULL); 68 | 69 | init(&keys, ¬Coprime, &d_keys, &d_notCoprime, argv[1], numKeys); 70 | 71 | dim3 gridDim(TILE_DIM / BLOCK_DIM, TILE_DIM / BLOCK_DIM); 72 | dim3 blockDim(WARP_DIM, BLOCK_DIM, BLOCK_DIM); 73 | int num_tiles = NUM_TILES(numKeys); 74 | 75 | FILE *outputStream = argc == 4 ? fopen(argv[3], "w") : stdout; 76 | 77 | /** 78 | * Group key pairs into square tiles to fit GPU resource usage limits. 79 | * For each tile: clear out the bit matrix, run GCD kernel, calculate private keys. 80 | */ 81 | for (int i = 0; i < num_tiles; ++i) { 82 | for (int j = i; j < num_tiles; ++j) { 83 | cudaSafe(cudaMemset(d_notCoprime, 0, BLKS_PER_TILE * BLKS_PER_TILE * sizeof(uint16_t))); 84 | 85 | cudaWrapper(gridDim, blockDim, d_keys, d_notCoprime, i, j, TILE_DIM, numKeys); 86 | cudaSafe(cudaPeekAtLastError()); 87 | cudaSafe(cudaDeviceSynchronize()); 88 | 89 | cudaSafe(cudaMemcpy(notCoprime, 90 | d_notCoprime, 91 | BLKS_PER_TILE * BLKS_PER_TILE * sizeof(uint16_t), 92 | cudaMemcpyDeviceToHost)); 93 | 94 | calculatePrivateKeys(keys, notCoprime, i, j, outputStream); 95 | } 96 | } 97 | 98 | cudaSafe(cudaFree(d_keys)); 99 | cudaSafe(cudaFree(d_notCoprime)); 100 | 101 | free(keys); 102 | free(notCoprime); 103 | free(cracked); 104 | 105 | if (argc == 4) 106 | fclose(outputStream); 107 | 108 | return 0; 109 | } 110 | 111 | /** 112 | * Perform boilerplate initialization: read keys from file, allocate 113 | * host/device keys, host/device notCoprime, memcpy keys to device. 114 | */ 115 | inline void init(integer** keys, 116 | uint16_t** notCoprime, 117 | integer** d_keys, 118 | uint16_t** d_notCoprime, 119 | const char* filename, 120 | const int numKeys) { 121 | *keys = (integer*) malloc(numKeys * sizeof(integer)); 122 | getKeysFromFile(filename, *keys, numKeys); 123 | 124 | *notCoprime = (uint16_t*) malloc(BLKS_PER_TILE * BLKS_PER_TILE * sizeof(uint16_t)); 125 | 126 | cudaSafe(cudaMalloc((void **) d_keys, numKeys * sizeof(integer))); 127 | cudaSafe(cudaMemcpy(*d_keys, *keys, numKeys * sizeof(integer), cudaMemcpyHostToDevice)); 128 | 129 | cudaSafe(cudaMalloc((void **) d_notCoprime, BLKS_PER_TILE * BLKS_PER_TILE * sizeof(uint16_t))); 130 | } 131 | 132 | void calculatePrivateKeys(integer* keys, uint16_t* notCoprime, int tileRow, int tileCol, FILE *stream) { 133 | for (int i = 0; i < BLKS_PER_TILE; ++i) { 134 | for (int j = 0; j < BLKS_PER_TILE; ++j) { 135 | uint16_t notCoprimeBlock = notCoprime[i * BLKS_PER_TILE + j]; 136 | 137 | if (notCoprimeBlock) { 138 | for (int y = 0; y < BLOCK_DIM; ++y) { 139 | if (notCoprimeBlock & Y_MASKS[y]) { 140 | for (int x = 0; x < BLOCK_DIM; ++x) { 141 | if (notCoprimeBlock & Y_MASKS[y] & X_MASKS[x]) { 142 | int n1Ndx = tileRow * TILE_DIM + i * BLOCK_DIM + y; 143 | int n2Ndx = tileCol * TILE_DIM + j * BLOCK_DIM + x; 144 | bool crackedN1 = checkIfCrackedAlready(n1Ndx); 145 | bool crackedN2 = checkIfCrackedAlready(n2Ndx); 146 | 147 | if (!crackedN1 || !crackedN2) { 148 | mpz_import(n1, N, 1, sizeof(uint32_t), 0, 0, keys[n1Ndx].ints); 149 | mpz_import(n2, N, 1, sizeof(uint32_t), 0, 0, keys[n2Ndx].ints); 150 | 151 | mpz_gcd(p, n1, n2); 152 | 153 | if (!crackedN1) { 154 | mpz_divexact(q1, n1, p); 155 | rsa_compute_d(d1, n1, p, q1); 156 | mpz_out_str(stream, 10, n1); 157 | fputc(':', stream); 158 | mpz_out_str(stream, 10, d1); 159 | fputc('\n', stream); 160 | 161 | cracked[crackedLen++] = n1Ndx; 162 | } 163 | 164 | if (!crackedN2) { 165 | mpz_divexact(q2, n2, p); 166 | rsa_compute_d(d2, n2, p, q2); 167 | mpz_out_str(stream, 10, n2); 168 | fputc(':', stream); 169 | mpz_out_str(stream, 10, d2); 170 | fputc('\n', stream); 171 | 172 | cracked[crackedLen++] = n2Ndx; 173 | } 174 | } 175 | } 176 | } 177 | } 178 | } 179 | } 180 | } 181 | } 182 | } 183 | 184 | inline void printUsage(char* progname) { 185 | cerr << "Usage: " << progname << " keyfile numkeys [outputfile]" << endl; 186 | exit(EXIT_FAILURE); 187 | } 188 | -------------------------------------------------------------------------------- /parallel/src/rsa.cpp: -------------------------------------------------------------------------------- 1 | #include "rsa.h" 2 | 3 | #include 4 | #include 5 | 6 | // Compute private key d, given n, p, and q. Assume e = 2^16+1 7 | int rsa_compute_d(mpz_t d, const mpz_t n, const mpz_t p, const mpz_t q) { 8 | mpz_t e, phi_n, gcd; 9 | mpz_inits(e, phi_n, gcd, '\0'); 10 | 11 | rsa_phi(phi_n, p, q); 12 | mpz_set_ui(e, 65537); 13 | 14 | if (mpz_invert(d, e, phi_n) == 0) 15 | exit(EXIT_FAILURE); 16 | 17 | mpz_clears(phi_n, gcd, '\0'); 18 | return 0; 19 | } 20 | 21 | // Calculate euler's totient of n, assuming n = p*q. Then, 22 | // phi(n) = phi(p)phi(q) = (p-1)(q-1) 23 | void rsa_phi(mpz_t phi_n, const mpz_t p, const mpz_t q) { 24 | mpz_t p_minus_one, q_minus_one; 25 | mpz_inits(p_minus_one, q_minus_one, '\0'); 26 | 27 | mpz_sub_ui(p_minus_one, p, 1); 28 | mpz_sub_ui(q_minus_one, q, 1); 29 | mpz_mul(phi_n, p_minus_one, q_minus_one); 30 | 31 | mpz_clears(p_minus_one, q_minus_one, '\0'); 32 | } 33 | -------------------------------------------------------------------------------- /parallel/src/rsa.h: -------------------------------------------------------------------------------- 1 | #ifndef RSA_H_ 2 | #define RSA_H_ 3 | 4 | #include 5 | 6 | int rsa_compute_d(mpz_t d, const mpz_t n, const mpz_t p, const mpz_t q); 7 | void rsa_phi(mpz_t phi_n, const mpz_t p, const mpz_t q); 8 | 9 | 10 | #endif // RSA_H_ 11 | -------------------------------------------------------------------------------- /parallel/test/integer_test.c: -------------------------------------------------------------------------------- 1 | #include "src/integer.h" 2 | #include "test/test.h" 3 | 4 | bool test_integer_copy() { 5 | TEST_INIT 6 | 7 | integer num = integer_fromInt(500); 8 | integer num2; 9 | integer_copy(copy, num); 10 | ASSERT(integer_eq(num, num2)) 11 | 12 | TEST_RETURN 13 | } 14 | 15 | void main() { 16 | TEST_MAIN_INIT 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /parallel/test/test.h: -------------------------------------------------------------------------------- 1 | #ifndef TEST_TEST_H_ 2 | #define TEST_TEST_H_ 3 | 4 | #include 5 | 6 | #define TEST_MAIN_INIT int __num_tests_failed = 0, __num_tests_run = 0; 7 | 8 | #define RUN_TEST(func) { \ 9 | if (!func()) { \ 10 | fprintf(stderr, "TEST " #func " FAILED\n"); \ 11 | __num_tests_failed++; \ 12 | } \ 13 | __num_tests_run++; \ 14 | } 15 | 16 | #define TEST_INIT int __ret = 1; 17 | 18 | #define TEST_RETURN return __ret; 19 | 20 | #define ASSERT(func) { \ 21 | if (!func()) { \ 22 | fprintf(stderr, "ASSERT " #func " FAILED\n"); \ 23 | __ret = 0; \ 24 | } \ 25 | } 26 | 27 | #endif // TEST_TEST_H_ 28 | -------------------------------------------------------------------------------- /report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchellwrosen/rsa-crack-cuda/2b3c5e5c0563f8fbe1b52ef44e78cfc1fc0fd0d6/report.pdf -------------------------------------------------------------------------------- /sequential/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -std=c99 -O3 3 | LDFLAGS=-Wall -L/home/clupo/gmp/lib 4 | 5 | INC=-I. -I/home/clupo/gmp/include 6 | LIBS=-lgmp 7 | 8 | all: main 9 | 10 | main: main.o mygmp.o rsa.o 11 | $(CC) $(LDFLAGS) $(INC) $(LIBS) $^ -o $@ 12 | 13 | %.o: %.c 14 | $(CC) $(INC) $(CFLAGS) -c $< -o $@ 15 | 16 | clean: 17 | @rm -f *.o *.gch main 18 | -------------------------------------------------------------------------------- /sequential/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "rsa.h" 5 | #include "mygmp.h" 6 | 7 | static int *cracked = NULL; 8 | static int crackedLen = 0; 9 | 10 | void printUsage(char* progname); 11 | 12 | int checkIfCrackedAlready(int n) { 13 | for (int i = 0; i < crackedLen; ++i) { 14 | if (n == cracked[i]) 15 | return 1; 16 | } 17 | 18 | return 0; 19 | } 20 | 21 | int main(int argc, char** argv) { 22 | if (argc < 3) 23 | printUsage(argv[0]); 24 | 25 | int numKeys = atoi(argv[2]); 26 | mpz_t* keys = mpz_reads(argv[1], numKeys); 27 | 28 | FILE *stream = argc == 4 ? fopen(argv[3], "w") : stdout; 29 | 30 | mpz_t gcd, q1, q2, d1, d2; 31 | mpz_inits(gcd, q1, q2, d1, d2, NULL); 32 | 33 | cracked = malloc(numKeys * sizeof(int)); 34 | 35 | for (int i = 0; i < numKeys-1; ++i) { 36 | for (int j = i+1; j < numKeys; ++j) { 37 | mpz_gcd(gcd, keys[i], keys[j]); 38 | if (mpz_cmp_ui(gcd, 1) != 0) { 39 | int crackedN1 = checkIfCrackedAlready(i); 40 | int crackedN2 = checkIfCrackedAlready(j); 41 | 42 | if (!crackedN1 || !crackedN2) { 43 | if (!crackedN1) { 44 | mpz_divexact(q1, keys[i], gcd); 45 | rsa_compute_d(d1, keys[i], gcd, q1); 46 | mpz_out_str(stream, 10, keys[i]); 47 | fputc(':', stream); 48 | mpz_out_str(stream, 10, d1); 49 | fputc('\n', stream); 50 | 51 | cracked[crackedLen++] = i; 52 | } 53 | 54 | if (!crackedN2) { 55 | mpz_divexact(q2, keys[j], gcd); 56 | rsa_compute_d(d2, keys[j], gcd, q2); 57 | mpz_out_str(stream, 10, keys[j]); 58 | fputc(':', stream); 59 | mpz_out_str(stream, 10, d2); 60 | fputc('\n', stream); 61 | 62 | cracked[crackedLen++] = j; 63 | } 64 | } 65 | } 66 | } 67 | } 68 | 69 | free(keys); 70 | free(cracked); 71 | 72 | if (argc == 4) 73 | fclose(stream); 74 | 75 | return 0; 76 | } 77 | 78 | void printUsage(char* progname) { 79 | fprintf(stderr, "Usage: %s keyfile numkeys [outputfile]\n", progname); 80 | exit(EXIT_FAILURE); 81 | } 82 | -------------------------------------------------------------------------------- /sequential/mygmp.c: -------------------------------------------------------------------------------- 1 | #include "mygmp.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | // 5 Integer Functions 8 | // 5.1 Initialization Functions 9 | 10 | // 5.9 Number Theoretic Functions 11 | Primality mpz_primality(mpz_t n) { 12 | return mpz_probab_prime_p(n, 25); 13 | } 14 | 15 | // 5.12 Input and Output Functions 16 | size_t mpz_read(const char* path, mpz_t n) { 17 | FILE* file = fopen(path, "r"); 18 | if (file == NULL) 19 | return -1; 20 | 21 | size_t nbytes = mpz_fread(file, n); 22 | if ((fclose(file) != 0)) 23 | return -1; 24 | 25 | return nbytes; 26 | } 27 | 28 | size_t mpz_write(const char* path, const mpz_t n) { 29 | FILE* file = fopen(path, "w"); 30 | if (file == NULL) 31 | return -1; 32 | 33 | size_t nbytes = mpz_fwrite(file, n); 34 | if ((fclose(file) != 0)) 35 | return -1; 36 | 37 | return nbytes; 38 | } 39 | 40 | mpz_t* mpz_reads(const char* path, int n) { 41 | FILE* file = fopen(path, "r"); 42 | if (file == NULL) 43 | return NULL; 44 | 45 | mpz_t* ints = (mpz_t*) calloc(n, sizeof(mpz_t)); 46 | for (int i = 0; i < n; ++i) 47 | gmp_fscanf(file, "%Zd\n", ints[i]); 48 | 49 | fclose(file); 50 | return ints; 51 | } 52 | 53 | size_t mpz_fread(FILE* stream, mpz_t n) { 54 | return mpz_inp_str(n, stream, 10); 55 | } 56 | 57 | size_t mpz_fwrite(FILE* stream, const mpz_t n) { 58 | return mpz_out_raw(stream, n); 59 | } 60 | 61 | size_t mpz_print(const mpz_t n) { 62 | return mpz_printb(n, 10); 63 | } 64 | 65 | size_t mpz_printb(const mpz_t n, int base) { 66 | size_t nbytes = mpz_out_str(stdout, base, n); 67 | fprintf(stdout, "\n"); 68 | return nbytes+1; 69 | } 70 | 71 | // 9 Random Number Functions 72 | // 9.1 Random State Initialization 73 | // 9.2 Random State Seeding 74 | void gmp_rand_init_seed(gmp_randstate_t rstate, unsigned long int seed) { 75 | gmp_randinit_default(rstate); 76 | gmp_randseed_ui(rstate, seed); 77 | } 78 | 79 | void gmp_genprime(mpz_t n, gmp_randstate_t rstate, mp_bitcnt_t bitcount) { 80 | do { 81 | mpz_urandomb(n, rstate, bitcount); 82 | } while (mpz_primality(n) != PRIME); 83 | } 84 | -------------------------------------------------------------------------------- /sequential/mygmp.h: -------------------------------------------------------------------------------- 1 | #ifndef GMP_H_ 2 | #define GMP_H_ 3 | 4 | #include 5 | #include 6 | 7 | typedef enum 8 | { COMPOSITE = 0 9 | , PROB_PRIME = 1 10 | , PRIME = 2 11 | } Primality; 12 | 13 | // 5 Integer Functions 14 | 15 | // 5.9 Number Theoretic Functions 16 | Primality mpz_primality(mpz_t n); 17 | 18 | // 5.12 Input and Output Functions 19 | size_t mpz_read(const char* path, mpz_t n); 20 | size_t mpz_write(const char* path, const mpz_t n); 21 | 22 | // Read keys from a file, decimal format, one per line. 23 | mpz_t* mpz_reads(const char* path, int n); 24 | 25 | // Read/write a single key from a stream, in raw format. 26 | size_t mpz_fread(FILE* stream, mpz_t n); 27 | size_t mpz_fwrite(FILE* stream, const mpz_t n); 28 | 29 | size_t mpz_print(const mpz_t n); 30 | size_t mpz_printb(const mpz_t n, int base); 31 | 32 | // 9 Random Number Functions 33 | // 9.1 Random State Initialization 34 | // 9.2 Random State Seeding 35 | // Combine initialization and seed. 36 | void gmp_rand_init_seed(gmp_randstate_t rstate, unsigned long int seed); 37 | 38 | // Generate a prime number. 39 | void gmp_genprime(mpz_t n, gmp_randstate_t rstate, mp_bitcnt_t bitcount); 40 | 41 | #endif // GMP_H_ 42 | -------------------------------------------------------------------------------- /sequential/rsa.c: -------------------------------------------------------------------------------- 1 | #include "rsa.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "mygmp.h" 7 | 8 | int rsa_keygen(mpz_t n, mpz_t e, mpz_t d, mp_bitcnt_t bitcount); 9 | void rsa_generate_npq(mpz_t n, mpz_t p, mpz_t q, mp_bitcnt_t bitcount); 10 | void rsa_phi(mpz_t phi_n, const mpz_t p, const mpz_t q); 11 | 12 | int rsa_keygen512(mpz_t n, mpz_t e, mpz_t d) { 13 | return rsa_keygen(n, e, d, 512); 14 | } 15 | 16 | int rsa_keygen(mpz_t n, mpz_t e, mpz_t d, mp_bitcnt_t bitcount) { 17 | mpz_t p, q; 18 | mpz_inits(p, q, '\0'); 19 | 20 | rsa_generate_npq(n, p, q, bitcount); 21 | int ret = rsa_compute_keys(e, d, n, p, q); 22 | 23 | mpz_clears(p, q, '\0'); 24 | return ret; 25 | } 26 | 27 | void rsa_generate_npq(mpz_t n, mpz_t p, mpz_t q, mp_bitcnt_t bitcount) { 28 | // Initialize random generator. 29 | gmp_randstate_t rstate; 30 | gmp_rand_init_seed(rstate, time(NULL)); 31 | 32 | // Generate p,q. 33 | gmp_genprime(p, rstate, bitcount); 34 | gmp_genprime(q, rstate, bitcount); 35 | 36 | // n = p*q 37 | mpz_mul(n, p, q); 38 | } 39 | 40 | int rsa_compute_d(mpz_t d, const mpz_t n, const mpz_t p, const mpz_t q) { 41 | mpz_t e, phi_n, gcd; 42 | mpz_inits(e, phi_n, gcd, '\0'); 43 | 44 | rsa_phi(phi_n, p, q); 45 | mpz_set_ui(e, 65537); 46 | 47 | if (mpz_invert(d, e, phi_n) == 0) 48 | exit(EXIT_FAILURE); 49 | 50 | mpz_clears(phi_n, gcd, '\0'); 51 | return 0; 52 | } 53 | 54 | 55 | int rsa_compute_keys(mpz_t e, mpz_t d, const mpz_t n, const mpz_t p, const mpz_t q) { 56 | mpz_t phi_n, gcd; 57 | mpz_inits(phi_n, gcd, '\0'); 58 | 59 | rsa_phi(phi_n, p, q); 60 | 61 | // choose e s.t. 1 < e < phi_n; gcd(e,n) = 1 62 | mpz_set_ui(e, 65537); // Good starting value for e 63 | while (1) { 64 | if (mpz_cmp(e, phi_n) >= 0) { // Have we exhausted all es? 65 | mpz_clears(phi_n, gcd, '\0'); 66 | return -1; 67 | } 68 | 69 | mpz_gcd(gcd, e, n); 70 | if (mpz_cmp_ui(gcd, 1) == 0) // Have we found an e? 71 | break; 72 | 73 | mpz_nextprime(e, e); // Bump e to the next prime and try again. 74 | } 75 | 76 | // There will always be an inverse of e mod phi(n) unless the above code is 77 | // incorrect, so just do something dumb, like halt execution. 78 | if (mpz_invert(d, e, phi_n) == 0) 79 | exit(EXIT_FAILURE); 80 | 81 | mpz_clears(phi_n, gcd, '\0'); 82 | return 0; 83 | } 84 | 85 | // Calculate euler's totient of n, assuming n = p*q. Then, 86 | // phi(n) = phi(p)phi(q) = (p-1)(q-1) 87 | void rsa_phi(mpz_t phi_n, const mpz_t p, const mpz_t q) { 88 | mpz_t p_minus_one, q_minus_one; 89 | mpz_inits(p_minus_one, q_minus_one, '\0'); 90 | 91 | mpz_sub_ui(p_minus_one, p, 1); 92 | mpz_sub_ui(q_minus_one, q, 1); 93 | mpz_mul(phi_n, p_minus_one, q_minus_one); 94 | 95 | mpz_clears(p_minus_one, q_minus_one, '\0'); 96 | } 97 | 98 | void rsa_encrypt(mpz_t c, const mpz_t m, const mpz_t e, const mpz_t n) { 99 | mpz_powm(c, m, e, n); 100 | } 101 | 102 | void rsa_decrypt(mpz_t m, const mpz_t c, const mpz_t d, const mpz_t n) { 103 | mpz_powm(m, c, d, n); 104 | } 105 | -------------------------------------------------------------------------------- /sequential/rsa.h: -------------------------------------------------------------------------------- 1 | #ifndef RSA_H_ 2 | #define RSA_H_ 3 | 4 | #include "mygmp.h" 5 | 6 | // Compute modulus n, encryption exponent e, and decryption exponent d. 7 | // Returns 0 on success, -1 on failure. 8 | int rsa_keygen512(mpz_t n, mpz_t e, mpz_t d); 9 | 10 | // Compute encryption/decryption keys e and d, given the prime factors 11 | // p and q of n. 12 | int rsa_compute_keys(mpz_t e, mpz_t d, const mpz_t n, const mpz_t p, const mpz_t q); 13 | 14 | // Compute private key d, given n, p, and q. Assume e = 2^16+1 15 | int rsa_compute_d(mpz_t d, const mpz_t n, const mpz_t p, const mpz_t q); 16 | 17 | // c = m^e mod n 18 | void rsa_encrypt(mpz_t c, const mpz_t m, const mpz_t e, const mpz_t n); 19 | 20 | // m = c^d mod n 21 | void rsa_decrypt(mpz_t m, const mpz_t c, const mpz_t d, const mpz_t n); 22 | 23 | void rsa_phi(mpz_t phi_n, const mpz_t p, const mpz_t q); 24 | 25 | #endif // RSA_H_ 26 | --------------------------------------------------------------------------------