12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067 |
- /*
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- *
- * lbn32.c - Low-level bignum routines, 32-bit version.
- *
- * NOTE: the magic constants "32" and "64" appear in many places in this
- * file, including inside identifiers. Because it is not possible to
- * ask "#ifdef" of a macro expansion, it is not possible to use the
- * preprocessor to conditionalize these properly. Thus, this file is
- * intended to be edited with textual search and replace to produce
- * alternate word size versions. Any reference to the number of bits
- * in a word must be the string "32", and that string must not appear
- * otherwise. Any reference to twice this number must appear as "64",
- * which likewise must not appear otherwise. Is that clear?
- *
- * Remember, when doubling the bit size replace the larger number (64)
- * first, then the smaller (32). When halving the bit size, do the
- * opposite. Otherwise, things will get wierd. Also, be sure to replace
- * every instance that appears. (:%s/foo/bar/g in vi)
- *
- * These routines work with a pointer to the least-significant end of
- * an array of WORD32s. The BIG(x), LITTLE(y) and BIGLTTLE(x,y) macros
- * defined in lbn.h (which expand to x on a big-edian machine and y on a
- * little-endian machine) are used to conditionalize the code to work
- * either way. If you have no assembly primitives, it doesn't matter.
- * Note that on a big-endian machine, the least-significant-end pointer
- * is ONE PAST THE END. The bytes are ptr[-1] through ptr[-len].
- * On little-endian, they are ptr[0] through ptr[len-1]. This makes
- * perfect sense if you consider pointers to point *between* bytes rather
- * than at them.
- *
- * Because the array index values are unsigned integers, ptr[-i]
- * may not work properly, since the index -i is evaluated as an unsigned,
- * and if pointers are wider, zero-extension will produce a positive
- * number rahter than the needed negative. The expression used in this
- * code, *(ptr-i) will, however, work. (The array syntax is equivalent
- * to *(ptr+-i), which is a pretty subtle difference.)
- *
- * Many of these routines will get very unhappy if fed zero-length inputs.
- * They use assert() to enforce this. An higher layer of code must make
- * sure that these aren't called with zero-length inputs.
- *
- * Any of these routines can be replaced with more efficient versions
- * elsewhere, by just #defining their names. If one of the names
- * is #defined, the C code is not compiled in and no declaration is
- * made. Use the BNINCLUDE file to do that. Typically, you compile
- * asm subroutines with the same name and just, e.g.
- * #define lbnMulAdd1_32 lbnMulAdd1_32
- *
- * If you want to write asm routines, start with lbnMulAdd1_32().
- * This is the workhorse of modular exponentiation. lbnMulN1_32() is
- * also used a fair bit, although not as much and it's defined in terms
- * of lbnMulAdd1_32 if that has a custom version. lbnMulSub1_32 and
- * lbnDiv21_32 are used in the usual division and remainder finding.
- * (Not the Montgomery reduction used in modular exponentiation, though.)
- * Once you have lbnMulAdd1_32 defined, writing the other two should
- * be pretty easy. (Just make sure you get the sign of the subtraction
- * in lbnMulSub1_32 right - it's dest = dest - source * k.)
- *
- * The only definitions that absolutely need a double-word (BNWORD64)
- * type are lbnMulAdd1_32 and lbnMulSub1_32; if those are provided,
- * the rest follows. lbnDiv21_32, however, is a lot slower unless you
- * have them, and lbnModQ_32 takes after it. That one is used quite a
- * bit for prime sieving.
- */
- #ifndef HAVE_CONFIG_H
- #define HAVE_CONFIG_H 0
- #endif
- #if HAVE_CONFIG_H
- #include "bnconfig.h"
- #endif
- /*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
- #ifndef NO_ASSERT_H
- #define NO_ASSERT_H 0
- #endif
- #ifndef NO_STRING_H
- #define NO_STRING_H 0
- #endif
- #ifndef HAVE_STRINGS_H
- #define HAVE_STRINGS_H 0
- #endif
- #if !NO_ASSERT_H
- #include <assert.h>
- #else
- #define assert(x) (void)0
- #endif
- #if !NO_STRING_H
- #include <string.h> /* For memcpy */
- #elif HAVE_STRINGS_H
- #include <strings.h>
- #endif
- #include "lbn.h"
- #include "lbn32.h"
- #include "lbnmem.h"
- #include "kludge.h"
- #ifndef BNWORD32
- #error 32-bit bignum library requires a 32-bit data type
- #endif
- /* If this is defined, include bnYield() calls */
- #if BNYIELD
- extern int (*bnYield)(void); /* From bn.c */
- #endif
- /*
- * Most of the multiply (and Montgomery reduce) routines use an outer
- * loop that iterates over one of the operands - a so-called operand
- * scanning approach. One big advantage of this is that the assembly
- * support routines are simpler. The loops can be rearranged to have
- * an outer loop that iterates over the product, a so-called product
- * scanning approach. This has the advantage of writing less data
- * and doing fewer adds to memory, so is supposedly faster. Some
- * code has been written using a product-scanning approach, but
- * it appears to be slower, so it is turned off by default. Some
- * experimentation would be appreciated.
- *
- * (The code is also annoying to get right and not very well commented,
- * one of my pet peeves about math libraries. I'm sorry.)
- */
- #ifndef PRODUCT_SCAN
- #define PRODUCT_SCAN 0
- #endif
- /*
- * Copy an array of words. <Marvin mode on> Thrilling, isn't it? </Marvin>
- * This is a good example of how the byte offsets and BIGLITTLE() macros work.
- * Another alternative would have been
- * memcpy(dest BIG(-len), src BIG(-len), len*sizeof(BNWORD32)), but I find that
- * putting operators into conditional macros is confusing.
- */
- #ifndef lbnCopy_32
- void
- lbnCopy_32(BNWORD32 *dest, BNWORD32 const *src, unsigned len)
- {
- memcpy(BIGLITTLE(dest-len,dest), BIGLITTLE(src-len,src),
- len * sizeof(*src));
- }
- #endif /* !lbnCopy_32 */
- /*
- * Fill n words with zero. This does it manually rather than calling
- * memset because it can assume alignment to make things faster while
- * memset can't. Note how big-endian numbers are naturally addressed
- * using predecrement, while little-endian is postincrement.
- */
- #ifndef lbnZero_32
- void
- lbnZero_32(BNWORD32 *num, unsigned len)
- {
- while (len--)
- BIGLITTLE(*--num,*num++) = 0;
- }
- #endif /* !lbnZero_32 */
- /*
- * Negate an array of words.
- * Negation is subtraction from zero. Negating low-order words
- * entails doing nothing until a non-zero word is hit. Once that
- * is negated, a borrow is generated and never dies until the end
- * of the number is hit. Negation with borrow, -x-1, is the same as ~x.
- * Repeat that until the end of the number.
- *
- * Doesn't return borrow out because that's pretty useless - it's
- * always set unless the input is 0, which is easy to notice in
- * normalized form.
- */
- #ifndef lbnNeg_32
- void
- lbnNeg_32(BNWORD32 *num, unsigned len)
- {
- assert(len);
- /* Skip low-order zero words */
- while (BIGLITTLE(*--num,*num) == 0) {
- if (!--len)
- return;
- LITTLE(num++;)
- }
- /* Negate the lowest-order non-zero word */
- *num = -*num;
- /* Complement all the higher-order words */
- while (--len) {
- BIGLITTLE(--num,++num);
- *num = ~*num;
- }
- }
- #endif /* !lbnNeg_32 */
- /*
- * lbnAdd1_32: add the single-word "carry" to the given number.
- * Used for minor increments and propagating the carry after
- * adding in a shorter bignum.
- *
- * Technique: If we have a double-width word, presumably the compiler
- * can add using its carry in inline code, so we just use a larger
- * accumulator to compute the carry from the first addition.
- * If not, it's more complex. After adding the first carry, which may
- * be > 1, compare the sum and the carry. If the sum wraps (causing a
- * carry out from the addition), the result will be less than each of the
- * inputs, since the wrap subtracts a number (2^32) which is larger than
- * the other input can possibly be. If the sum is >= the carry input,
- * return success immediately.
- * In either case, if there is a carry, enter a loop incrementing words
- * until one does not wrap. Since we are adding 1 each time, the wrap
- * will be to 0 and we can test for equality.
- */
- #ifndef lbnAdd1_32 /* If defined, it's provided as an asm subroutine */
- #ifdef BNWORD64
- BNWORD32
- lbnAdd1_32(BNWORD32 *num, unsigned len, BNWORD32 carry)
- {
- BNWORD64 t;
- assert(len > 0); /* Alternative: if (!len) return carry */
- t = (BNWORD64)BIGLITTLE(*--num,*num) + carry;
- BIGLITTLE(*num,*num++) = (BNWORD32)t;
- if ((t >> 32) == 0)
- return 0;
- while (--len) {
- if (++BIGLITTLE(*--num,*num++) != 0)
- return 0;
- }
- return 1;
- }
- #else /* no BNWORD64 */
- BNWORD32
- lbnAdd1_32(BNWORD32 *num, unsigned len, BNWORD32 carry)
- {
- assert(len > 0); /* Alternative: if (!len) return carry */
- if ((BIGLITTLE(*--num,*num++) += carry) >= carry)
- return 0;
- while (--len) {
- if (++BIGLITTLE(*--num,*num++) != 0)
- return 0;
- }
- return 1;
- }
- #endif
- #endif/* !lbnAdd1_32 */
- /*
- * lbnSub1_32: subtract the single-word "borrow" from the given number.
- * Used for minor decrements and propagating the borrow after
- * subtracting a shorter bignum.
- *
- * Technique: Similar to the add, above. If there is a double-length type,
- * use that to generate the first borrow.
- * If not, after subtracting the first borrow, which may be > 1, compare
- * the difference and the *negative* of the carry. If the subtract wraps
- * (causing a borrow out from the subtraction), the result will be at least
- * as large as -borrow. If the result < -borrow, then no borrow out has
- * appeared and we may return immediately, except when borrow == 0. To
- * deal with that case, use the identity that -x = ~x+1, and instead of
- * comparing < -borrow, compare for <= ~borrow.
- * Either way, if there is a borrow out, enter a loop decrementing words
- * until a non-zero word is reached.
- *
- * Note the cast of ~borrow to (BNWORD32). If the size of an int is larger
- * than BNWORD32, C rules say the number is expanded for the arithmetic, so
- * the inversion will be done on an int and the value won't be quite what
- * is expected.
- */
- #ifndef lbnSub1_32 /* If defined, it's provided as an asm subroutine */
- #ifdef BNWORD64
- BNWORD32
- lbnSub1_32(BNWORD32 *num, unsigned len, BNWORD32 borrow)
- {
- BNWORD64 t;
- assert(len > 0); /* Alternative: if (!len) return borrow */
- t = (BNWORD64)BIGLITTLE(*--num,*num) - borrow;
- BIGLITTLE(*num,*num++) = (BNWORD32)t;
- if ((t >> 32) == 0)
- return 0;
- while (--len) {
- if ((BIGLITTLE(*--num,*num++))-- != 0)
- return 0;
- }
- return 1;
- }
- #else /* no BNWORD64 */
- BNWORD32
- lbnSub1_32(BNWORD32 *num, unsigned len, BNWORD32 borrow)
- {
- assert(len > 0); /* Alternative: if (!len) return borrow */
- if ((BIGLITTLE(*--num,*num++) -= borrow) <= (BNWORD32)~borrow)
- return 0;
- while (--len) {
- if ((BIGLITTLE(*--num,*num++))-- != 0)
- return 0;
- }
- return 1;
- }
- #endif
- #endif /* !lbnSub1_32 */
- /*
- * lbnAddN_32: add two bignums of the same length, returning the carry (0 or 1).
- * One of the building blocks, along with lbnAdd1, of adding two bignums of
- * differing lengths.
- *
- * Technique: Maintain a word of carry. If there is no double-width type,
- * use the same technique as in lbnAdd1, above, to maintain the carry by
- * comparing the inputs. Adding the carry sources is used as an OR operator;
- * at most one of the two comparisons can possibly be true. The first can
- * only be true if carry == 1 and x, the result, is 0. In that case the
- * second can't possibly be true.
- */
- #ifndef lbnAddN_32
- #ifdef BNWORD64
- BNWORD32
- lbnAddN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len)
- {
- BNWORD64 t;
- assert(len > 0);
- t = (BNWORD64)BIGLITTLE(*--num1,*num1) + BIGLITTLE(*--num2,*num2++);
- BIGLITTLE(*num1,*num1++) = (BNWORD32)t;
- while (--len) {
- t = (BNWORD64)BIGLITTLE(*--num1,*num1) +
- (BNWORD64)BIGLITTLE(*--num2,*num2++) + (t >> 32);
- BIGLITTLE(*num1,*num1++) = (BNWORD32)t;
- }
- return (BNWORD32)(t>>32);
- }
- #else /* no BNWORD64 */
- BNWORD32
- lbnAddN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len)
- {
- BNWORD32 x, carry = 0;
- assert(len > 0); /* Alternative: change loop to test at start */
- do {
- x = BIGLITTLE(*--num2,*num2++);
- carry = (x += carry) < carry;
- carry += (BIGLITTLE(*--num1,*num1++) += x) < x;
- } while (--len);
- return carry;
- }
- #endif
- #endif /* !lbnAddN_32 */
- /*
- * lbnSubN_32: add two bignums of the same length, returning the carry (0 or 1).
- * One of the building blocks, along with subn1, of subtracting two bignums of
- * differing lengths.
- *
- * Technique: If no double-width type is availble, maintain a word of borrow.
- * First, add the borrow to the subtrahend (did you have to learn all those
- * awful words in elementary school, too?), and if it overflows, set the
- * borrow again. Then subtract the modified subtrahend from the next word
- * of input, using the same technique as in subn1, above.
- * Adding the borrows is used as an OR operator; at most one of the two
- * comparisons can possibly be true. The first can only be true if
- * borrow == 1 and x, the result, is 0. In that case the second can't
- * possibly be true.
- *
- * In the double-word case, (BNWORD32)-(t>>32) is subtracted, rather than
- * adding t>>32, because the shift would need to sign-extend and that's
- * not guaranteed to happen in ANSI C, even with signed types.
- */
- #ifndef lbnSubN_32
- #ifdef BNWORD64
- BNWORD32
- lbnSubN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len)
- {
- BNWORD64 t;
- assert(len > 0);
- t = (BNWORD64)BIGLITTLE(*--num1,*num1) - BIGLITTLE(*--num2,*num2++);
- BIGLITTLE(*num1,*num1++) = (BNWORD32)t;
- while (--len) {
- t = (BNWORD64)BIGLITTLE(*--num1,*num1) -
- (BNWORD64)BIGLITTLE(*--num2,*num2++) - (BNWORD32)-(t >> 32);
- BIGLITTLE(*num1,*num1++) = (BNWORD32)t;
- }
- return -(BNWORD32)(t>>32);
- }
- #else
- BNWORD32
- lbnSubN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len)
- {
- BNWORD32 x, borrow = 0;
- assert(len > 0); /* Alternative: change loop to test at start */
- do {
- x = BIGLITTLE(*--num2,*num2++);
- borrow = (x += borrow) < borrow;
- borrow += (BIGLITTLE(*--num1,*num1++) -= x) > (BNWORD32)~x;
- } while (--len);
- return borrow;
- }
- #endif
- #endif /* !lbnSubN_32 */
- #ifndef lbnCmp_32
- /*
- * lbnCmp_32: compare two bignums of equal length, returning the sign of
- * num1 - num2. (-1, 0 or +1).
- *
- * Technique: Change the little-endian pointers to big-endian pointers
- * and compare from the most-significant end until a difference if found.
- * When it is, figure out the sign of the difference and return it.
- */
- int
- lbnCmp_32(BNWORD32 const *num1, BNWORD32 const *num2, unsigned len)
- {
- BIGLITTLE(num1 -= len, num1 += len);
- BIGLITTLE(num2 -= len, num2 += len);
- while (len--) {
- if (BIGLITTLE(*num1++ != *num2++, *--num1 != *--num2)) {
- if (BIGLITTLE(num1[-1] < num2[-1], *num1 < *num2))
- return -1;
- else
- return 1;
- }
- }
- return 0;
- }
- #endif /* !lbnCmp_32 */
- /*
- * mul32_ppmmaa(ph,pl,x,y,a,b) is an optional routine that
- * computes (ph,pl) = x * y + a + b. mul32_ppmma and mul32_ppmm
- * are simpler versions. If you want to be lazy, all of these
- * can be defined in terms of the others, so here we create any
- * that have not been defined in terms of the ones that have been.
- */
- /* Define ones with fewer a's in terms of ones with more a's */
- #if !defined(mul32_ppmma) && defined(mul32_ppmmaa)
- #define mul32_ppmma(ph,pl,x,y,a) mul32_ppmmaa(ph,pl,x,y,a,0)
- #endif
- #if !defined(mul32_ppmm) && defined(mul32_ppmma)
- #define mul32_ppmm(ph,pl,x,y) mul32_ppmma(ph,pl,x,y,0)
- #endif
- /*
- * Use this definition to test the mul32_ppmm-based operations on machines
- * that do not provide mul32_ppmm. Change the final "0" to a "1" to
- * enable it.
- */
- #if !defined(mul32_ppmm) && defined(BNWORD64) && 0 /* Debugging */
- #define mul32_ppmm(ph,pl,x,y) \
- ({BNWORD64 _ = (BNWORD64)(x)*(y); (pl) = _; (ph) = _>>32;})
- #endif
- #if defined(mul32_ppmm) && !defined(mul32_ppmma)
- #define mul32_ppmma(ph,pl,x,y,a) \
- (mul32_ppmm(ph,pl,x,y), (ph) += ((pl) += (a)) < (a))
- #endif
- #if defined(mul32_ppmma) && !defined(mul32_ppmmaa)
- #define mul32_ppmmaa(ph,pl,x,y,a,b) \
- (mul32_ppmma(ph,pl,x,y,a), (ph) += ((pl) += (b)) < (b))
- #endif
- /*
- * lbnMulN1_32: Multiply an n-word input by a 1-word input and store the
- * n+1-word product. This uses either the mul32_ppmm and mul32_ppmma
- * macros, or C multiplication with the BNWORD64 type. This uses mul32_ppmma
- * if available, assuming you won't bother defining it unless you can do
- * better than the normal multiplication.
- */
- #ifndef lbnMulN1_32
- #ifdef lbnMulAdd1_32 /* If we have this asm primitive, use it. */
- void
- lbnMulN1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
- {
- lbnZero_32(out, len);
- BIGLITTLE(*(out-len-1),*(out+len)) = lbnMulAdd1_32(out, in, len, k);
- }
- #elif defined(mul32_ppmm)
- void
- lbnMulN1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
- {
- BNWORD32 carry, carryin;
- assert(len > 0);
- BIG(--out;--in;);
- mul32_ppmm(carry, *out, *in, k);
- LITTLE(out++;in++;)
- while (--len) {
- BIG(--out;--in;)
- carryin = carry;
- mul32_ppmma(carry, *out, *in, k, carryin);
- LITTLE(out++;in++;)
- }
- BIGLITTLE(*--out,*out) = carry;
- }
- #elif defined(BNWORD64)
- void
- lbnMulN1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
- {
- BNWORD64 p;
- assert(len > 0);
- p = (BNWORD64)BIGLITTLE(*--in,*in++) * k;
- BIGLITTLE(*--out,*out++) = (BNWORD32)p;
- while (--len) {
- p = (BNWORD64)BIGLITTLE(*--in,*in++) * k + (BNWORD32)(p >> 32);
- BIGLITTLE(*--out,*out++) = (BNWORD32)p;
- }
- BIGLITTLE(*--out,*out) = (BNWORD32)(p >> 32);
- }
- #else
- #error No 32x32 -> 64 multiply available for 32-bit bignum package
- #endif
- #endif /* lbnMulN1_32 */
- /*
- * lbnMulAdd1_32: Multiply an n-word input by a 1-word input and add the
- * low n words of the product to the destination. *Returns the n+1st word
- * of the product.* (That turns out to be more convenient than adding
- * it into the destination and dealing with a possible unit carry out
- * of *that*.) This uses either the mul32_ppmma and mul32_ppmmaa macros,
- * or C multiplication with the BNWORD64 type.
- *
- * If you're going to write assembly primitives, this is the one to
- * start with. It is by far the most commonly called function.
- */
- #ifndef lbnMulAdd1_32
- #if defined(mul32_ppmm)
- BNWORD32
- lbnMulAdd1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
- {
- BNWORD32 prod, carry, carryin;
- assert(len > 0);
- BIG(--out;--in;);
- carryin = *out;
- mul32_ppmma(carry, *out, *in, k, carryin);
- LITTLE(out++;in++;)
- while (--len) {
- BIG(--out;--in;);
- carryin = carry;
- mul32_ppmmaa(carry, prod, *in, k, carryin, *out);
- *out = prod;
- LITTLE(out++;in++;)
- }
- return carry;
- }
- #elif defined(BNWORD64)
- BNWORD32
- lbnMulAdd1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
- {
- BNWORD64 p;
- assert(len > 0);
- p = (BNWORD64)BIGLITTLE(*--in,*in++) * k + BIGLITTLE(*--out,*out);
- BIGLITTLE(*out,*out++) = (BNWORD32)p;
- while (--len) {
- p = (BNWORD64)BIGLITTLE(*--in,*in++) * k +
- (BNWORD32)(p >> 32) + BIGLITTLE(*--out,*out);
- BIGLITTLE(*out,*out++) = (BNWORD32)p;
- }
- return (BNWORD32)(p >> 32);
- }
- #else
- #error No 32x32 -> 64 multiply available for 32-bit bignum package
- #endif
- #endif /* lbnMulAdd1_32 */
- /*
- * lbnMulSub1_32: Multiply an n-word input by a 1-word input and subtract the
- * n-word product from the destination. Returns the n+1st word of the product.
- * This uses either the mul32_ppmm and mul32_ppmma macros, or
- * C multiplication with the BNWORD64 type.
- *
- * This is rather uglier than adding, but fortunately it's only used in
- * division which is not used too heavily.
- */
- #ifndef lbnMulSub1_32
- #if defined(mul32_ppmm)
- BNWORD32
- lbnMulSub1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
- {
- BNWORD32 prod, carry, carryin;
- assert(len > 0);
- BIG(--in;)
- mul32_ppmm(carry, prod, *in, k);
- LITTLE(in++;)
- carry += (BIGLITTLE(*--out,*out++) -= prod) > (BNWORD32)~prod;
- while (--len) {
- BIG(--in;);
- carryin = carry;
- mul32_ppmma(carry, prod, *in, k, carryin);
- LITTLE(in++;)
- carry += (BIGLITTLE(*--out,*out++) -= prod) > (BNWORD32)~prod;
- }
- return carry;
- }
- #elif defined(BNWORD64)
- BNWORD32
- lbnMulSub1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
- {
- BNWORD64 p;
- BNWORD32 carry, t;
- assert(len > 0);
- p = (BNWORD64)BIGLITTLE(*--in,*in++) * k;
- t = BIGLITTLE(*--out,*out);
- carry = (BNWORD32)(p>>32) + ((BIGLITTLE(*out,*out++)=t-(BNWORD32)p) > t);
- while (--len) {
- p = (BNWORD64)BIGLITTLE(*--in,*in++) * k + carry;
- t = BIGLITTLE(*--out,*out);
- carry = (BNWORD32)(p>>32) +
- ( (BIGLITTLE(*out,*out++)=t-(BNWORD32)p) > t );
- }
- return carry;
- }
- #else
- #error No 32x32 -> 64 multiply available for 32-bit bignum package
- #endif
- #endif /* !lbnMulSub1_32 */
- /*
- * Shift n words left "shift" bits. 0 < shift < 32. Returns the
- * carry, any bits shifted off the left-hand side (0 <= carry < 2^shift).
- */
- #ifndef lbnLshift_32
- BNWORD32
- lbnLshift_32(BNWORD32 *num, unsigned len, unsigned shift)
- {
- BNWORD32 x, carry;
- assert(shift > 0);
- assert(shift < 32);
- carry = 0;
- while (len--) {
- BIG(--num;)
- x = *num;
- *num = (x<<shift) | carry;
- LITTLE(num++;)
- carry = x >> (32-shift);
- }
- return carry;
- }
- #endif /* !lbnLshift_32 */
- /*
- * An optimized version of the above, for shifts of 1.
- * Some machines can use add-with-carry tricks for this.
- */
- #ifndef lbnDouble_32
- BNWORD32
- lbnDouble_32(BNWORD32 *num, unsigned len)
- {
- BNWORD32 x, carry;
- carry = 0;
- while (len--) {
- BIG(--num;)
- x = *num;
- *num = (x<<1) | carry;
- LITTLE(num++;)
- carry = x >> (32-1);
- }
- return carry;
- }
- #endif /* !lbnDouble_32 */
- /*
- * Shift n words right "shift" bits. 0 < shift < 32. Returns the
- * carry, any bits shifted off the right-hand side (0 <= carry < 2^shift).
- */
- #ifndef lbnRshift_32
- BNWORD32
- lbnRshift_32(BNWORD32 *num, unsigned len, unsigned shift)
- {
- BNWORD32 x, carry = 0;
- assert(shift > 0);
- assert(shift < 32);
- BIGLITTLE(num -= len, num += len);
- while (len--) {
- LITTLE(--num;)
- x = *num;
- *num = (x>>shift) | carry;
- BIG(num++;)
- carry = x << (32-shift);
- }
- return carry >> (32-shift);
- }
- #endif /* !lbnRshift_32 */
- /*
- * Multiply two numbers of the given lengths. prod and num2 may overlap,
- * provided that the low len1 bits of prod are free. (This corresponds
- * nicely to the place the result is returned from lbnMontReduce_32.)
- *
- * TODO: Use Karatsuba multiply. The overlap constraints may have
- * to get rewhacked.
- */
- #ifndef lbnMul_32
- void
- lbnMul_32(BNWORD32 *prod, BNWORD32 const *num1, unsigned len1,
- BNWORD32 const *num2, unsigned len2)
- {
- /* Special case of zero */
- if (!len1 || !len2) {
- lbnZero_32(prod, len1+len2);
- return;
- }
- /* Multiply first word */
- lbnMulN1_32(prod, num1, len1, BIGLITTLE(*--num2,*num2++));
- /*
- * Add in subsequent words, storing the most significant word,
- * which is new each time.
- */
- while (--len2) {
- BIGLITTLE(--prod,prod++);
- BIGLITTLE(*(prod-len1-1),*(prod+len1)) =
- lbnMulAdd1_32(prod, num1, len1, BIGLITTLE(*--num2,*num2++));
- }
- }
- #endif /* !lbnMul_32 */
- /*
- * lbnMulX_32 is a square multiply - both inputs are the same length.
- * It's normally just a macro wrapper around the general multiply,
- * but might be implementable in assembly more efficiently (such as
- * when product scanning).
- */
- #ifndef lbnMulX_32
- #if defined(BNWORD64) && PRODUCT_SCAN
- /*
- * Test code to see whether product scanning is any faster. It seems
- * to make the C code slower, so PRODUCT_SCAN is not defined.
- */
- static void
- lbnMulX_32(BNWORD32 *prod, BNWORD32 const *num1, BNWORD32 const *num2,
- unsigned len)
- {
- BNWORD64 x, y;
- BNWORD32 const *p1, *p2;
- unsigned carry;
- unsigned i, j;
- /* Special case of zero */
- if (!len)
- return;
- x = (BNWORD64)BIGLITTLE(num1[-1] * num2[-1], num1[0] * num2[0]);
- BIGLITTLE(*--prod, *prod++) = (BNWORD32)x;
- x >>= 32;
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = num1;
- p2 = BIGLITTLE(num2-i-1,num2+i+1);
- for (j = 0; j <= i; j++) {
- BIG(y = (BNWORD64)*--p1 * *p2++;)
- LITTLE(y = (BNWORD64)*p1++ * *--p2;)
- x += y;
- carry += (x < y);
- }
- BIGLITTLE(*--prod,*prod++) = (BNWORD32)x;
- x = (x >> 32) | (BNWORD64)carry << 32;
- }
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = BIGLITTLE(num1-i,num1+i);
- p2 = BIGLITTLE(num2-len,num2+len);
- for (j = i; j < len; j++) {
- BIG(y = (BNWORD64)*--p1 * *p2++;)
- LITTLE(y = (BNWORD64)*p1++ * *--p2;)
- x += y;
- carry += (x < y);
- }
- BIGLITTLE(*--prod,*prod++) = (BNWORD32)x;
- x = (x >> 32) | (BNWORD64)carry << 32;
- }
-
- BIGLITTLE(*--prod,*prod) = (BNWORD32)x;
- }
- #else /* !defined(BNWORD64) || !PRODUCT_SCAN */
- /* Default trivial macro definition */
- #define lbnMulX_32(prod, num1, num2, len) lbnMul_32(prod, num1, len, num2, len)
- #endif /* !defined(BNWORD64) || !PRODUCT_SCAN */
- #endif /* !lbmMulX_32 */
- #if !defined(lbnMontMul_32) && defined(BNWORD64) && PRODUCT_SCAN
- /*
- * Test code for product-scanning multiply. This seems to slow the C
- * code down rather than speed it up.
- * This does a multiply and Montgomery reduction together, using the
- * same loops. The outer loop scans across the product, twice.
- * The first pass computes the low half of the product and the
- * Montgomery multipliers. These are stored in the product array,
- * which contains no data as of yet. x and carry add up the columns
- * and propagate carries forward.
- *
- * The second half multiplies the upper half, adding in the modulus
- * times the Montgomery multipliers. The results of this multiply
- * are stored.
- */
- static void
- lbnMontMul_32(BNWORD32 *prod, BNWORD32 const *num1, BNWORD32 const *num2,
- BNWORD32 const *mod, unsigned len, BNWORD32 inv)
- {
- BNWORD64 x, y;
- BNWORD32 const *p1, *p2, *pm;
- BNWORD32 *pp;
- BNWORD32 t;
- unsigned carry;
- unsigned i, j;
- /* Special case of zero */
- if (!len)
- return;
- /*
- * This computes directly into the high half of prod, so just
- * shift the pointer and consider prod only "len" elements long
- * for the rest of the code.
- */
- BIGLITTLE(prod -= len, prod += len);
- /* Pass 1 - compute Montgomery multipliers */
- /* First iteration can have certain simplifications. */
- x = (BNWORD64)BIGLITTLE(num1[-1] * num2[-1], num1[0] * num2[0]);
- BIGLITTLE(prod[-1], prod[0]) = t = inv * (BNWORD32)x;
- y = (BNWORD64)t * BIGLITTLE(mod[-1],mod[0]);
- x += y;
- /* Note: GCC 2.6.3 has a bug if you try to eliminate "carry" */
- carry = (x < y);
- assert((BNWORD32)x == 0);
- x = x >> 32 | (BNWORD64)carry << 32;
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = num1;
- p2 = BIGLITTLE(num2-i-1,num2+i+1);
- pp = prod;
- pm = BIGLITTLE(mod-i-1,mod+i+1);
- for (j = 0; j < i; j++) {
- y = (BNWORD64)BIGLITTLE(*--p1 * *p2++, *p1++ * *--p2);
- x += y;
- carry += (x < y);
- y = (BNWORD64)BIGLITTLE(*--pp * *pm++, *pp++ * *--pm);
- x += y;
- carry += (x < y);
- }
- y = (BNWORD64)BIGLITTLE(p1[-1] * p2[0], p1[0] * p2[-1]);
- x += y;
- carry += (x < y);
- assert(BIGLITTLE(pp == prod-i, pp == prod+i));
- BIGLITTLE(pp[-1], pp[0]) = t = inv * (BNWORD32)x;
- assert(BIGLITTLE(pm == mod-1, pm == mod+1));
- y = (BNWORD64)t * BIGLITTLE(pm[0],pm[-1]);
- x += y;
- carry += (x < y);
- assert((BNWORD32)x == 0);
- x = x >> 32 | (BNWORD64)carry << 32;
- }
- /* Pass 2 - compute reduced product and store */
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = BIGLITTLE(num1-i,num1+i);
- p2 = BIGLITTLE(num2-len,num2+len);
- pm = BIGLITTLE(mod-i,mod+i);
- pp = BIGLITTLE(prod-len,prod+len);
- for (j = i; j < len; j++) {
- y = (BNWORD64)BIGLITTLE(*--p1 * *p2++, *p1++ * *--p2);
- x += y;
- carry += (x < y);
- y = (BNWORD64)BIGLITTLE(*--pm * *pp++, *pm++ * *--pp);
- x += y;
- carry += (x < y);
- }
- assert(BIGLITTLE(pm == mod-len, pm == mod+len));
- assert(BIGLITTLE(pp == prod-i, pp == prod+i));
- BIGLITTLE(pp[0],pp[-1]) = (BNWORD32)x;
- x = (x >> 32) | (BNWORD64)carry << 32;
- }
- /* Last round of second half, simplified. */
- BIGLITTLE(*(prod-len),*(prod+len-1)) = (BNWORD32)x;
- carry = (x >> 32);
- while (carry)
- carry -= lbnSubN_32(prod, mod, len);
- while (lbnCmp_32(prod, mod, len) >= 0)
- (void)lbnSubN_32(prod, mod, len);
- }
- /* Suppress later definition */
- #define lbnMontMul_32 lbnMontMul_32
- #endif
- #if !defined(lbnSquare_32) && defined(BNWORD64) && PRODUCT_SCAN
- /*
- * Trial code for product-scanning squaring. This seems to slow the C
- * code down rather than speed it up.
- */
- void
- lbnSquare_32(BNWORD32 *prod, BNWORD32 const *num, unsigned len)
- {
- BNWORD64 x, y, z;
- BNWORD32 const *p1, *p2;
- unsigned carry;
- unsigned i, j;
- /* Special case of zero */
- if (!len)
- return;
- /* Word 0 of product */
- x = (BNWORD64)BIGLITTLE(num[-1] * num[-1], num[0] * num[0]);
- BIGLITTLE(*--prod, *prod++) = (BNWORD32)x;
- x >>= 32;
- /* Words 1 through len-1 */
- for (i = 1; i < len; i++) {
- carry = 0;
- y = 0;
- p1 = num;
- p2 = BIGLITTLE(num-i-1,num+i+1);
- for (j = 0; j < (i+1)/2; j++) {
- BIG(z = (BNWORD64)*--p1 * *p2++;)
- LITTLE(z = (BNWORD64)*p1++ * *--p2;)
- y += z;
- carry += (y < z);
- }
- y += z = y;
- carry += carry + (y < z);
- if ((i & 1) == 0) {
- assert(BIGLITTLE(--p1 == p2, p1 == --p2));
- BIG(z = (BNWORD64)*p2 * *p2;)
- LITTLE(z = (BNWORD64)*p1 * *p1;)
- y += z;
- carry += (y < z);
- }
- x += y;
- carry += (x < y);
- BIGLITTLE(*--prod,*prod++) = (BNWORD32)x;
- x = (x >> 32) | (BNWORD64)carry << 32;
- }
- /* Words len through 2*len-2 */
- for (i = 1; i < len; i++) {
- carry = 0;
- y = 0;
- p1 = BIGLITTLE(num-i,num+i);
- p2 = BIGLITTLE(num-len,num+len);
- for (j = 0; j < (len-i)/2; j++) {
- BIG(z = (BNWORD64)*--p1 * *p2++;)
- LITTLE(z = (BNWORD64)*p1++ * *--p2;)
- y += z;
- carry += (y < z);
- }
- y += z = y;
- carry += carry + (y < z);
- if ((len-i) & 1) {
- assert(BIGLITTLE(--p1 == p2, p1 == --p2));
- BIG(z = (BNWORD64)*p2 * *p2;)
- LITTLE(z = (BNWORD64)*p1 * *p1;)
- y += z;
- carry += (y < z);
- }
- x += y;
- carry += (x < y);
- BIGLITTLE(*--prod,*prod++) = (BNWORD32)x;
- x = (x >> 32) | (BNWORD64)carry << 32;
- }
-
- /* Word 2*len-1 */
- BIGLITTLE(*--prod,*prod) = (BNWORD32)x;
- }
- /* Suppress later definition */
- #define lbnSquare_32 lbnSquare_32
- #endif
- /*
- * Square a number, using optimized squaring to reduce the number of
- * primitive multiples that are executed. There may not be any
- * overlap of the input and output.
- *
- * Technique: Consider the partial products in the multiplication
- * of "abcde" by itself:
- *
- * a b c d e
- * * a b c d e
- * ==================
- * ae be ce de ee
- * ad bd cd dd de
- * ac bc cc cd ce
- * ab bb bc bd be
- * aa ab ac ad ae
- *
- * Note that everything above the main diagonal:
- * ae be ce de = (abcd) * e
- * ad bd cd = (abc) * d
- * ac bc = (ab) * c
- * ab = (a) * b
- *
- * is a copy of everything below the main diagonal:
- * de
- * cd ce
- * bc bd be
- * ab ac ad ae
- *
- * Thus, the sum is 2 * (off the diagonal) + diagonal.
- *
- * This is accumulated beginning with the diagonal (which
- * consist of the squares of the digits of the input), which is then
- * divided by two, the off-diagonal added, and multiplied by two
- * again. The low bit is simply a copy of the low bit of the
- * input, so it doesn't need special care.
- *
- * TODO: Merge the shift by 1 with the squaring loop.
- * TODO: Use Karatsuba. (a*W+b)^2 = a^2 * (W^2+W) + b^2 * (W+1) - (a-b)^2 * W.
- */
- #ifndef lbnSquare_32
- void
- lbnSquare_32(BNWORD32 *prod, BNWORD32 const *num, unsigned len)
- {
- BNWORD32 t;
- BNWORD32 *prodx = prod; /* Working copy of the argument */
- BNWORD32 const *numx = num; /* Working copy of the argument */
- unsigned lenx = len; /* Working copy of the argument */
- if (!len)
- return;
- /* First, store all the squares */
- while (lenx--) {
- #ifdef mul32_ppmm
- BNWORD32 ph, pl;
- t = BIGLITTLE(*--numx,*numx++);
- mul32_ppmm(ph,pl,t,t);
- BIGLITTLE(*--prodx,*prodx++) = pl;
- BIGLITTLE(*--prodx,*prodx++) = ph;
- #elif defined(BNWORD64) /* use BNWORD64 */
- BNWORD64 p;
- t = BIGLITTLE(*--numx,*numx++);
- p = (BNWORD64)t * t;
- BIGLITTLE(*--prodx,*prodx++) = (BNWORD32)p;
- BIGLITTLE(*--prodx,*prodx++) = (BNWORD32)(p>>32);
- #else /* Use lbnMulN1_32 */
- t = BIGLITTLE(numx[-1],*numx);
- lbnMulN1_32(prodx, numx, 1, t);
- BIGLITTLE(--numx,numx++);
- BIGLITTLE(prodx -= 2, prodx += 2);
- #endif
- }
- /* Then, shift right 1 bit */
- (void)lbnRshift_32(prod, 2*len, 1);
- /* Then, add in the off-diagonal sums */
- lenx = len;
- numx = num;
- prodx = prod;
- while (--lenx) {
- t = BIGLITTLE(*--numx,*numx++);
- BIGLITTLE(--prodx,prodx++);
- t = lbnMulAdd1_32(prodx, numx, lenx, t);
- lbnAdd1_32(BIGLITTLE(prodx-lenx,prodx+lenx), lenx+1, t);
- BIGLITTLE(--prodx,prodx++);
- }
- /* Shift it back up */
- lbnDouble_32(prod, 2*len);
- /* And set the low bit appropriately */
- BIGLITTLE(prod[-1],prod[0]) |= BIGLITTLE(num[-1],num[0]) & 1;
- }
- #endif /* !lbnSquare_32 */
- /*
- * lbnNorm_32 - given a number, return a modified length such that the
- * most significant digit is non-zero. Zero-length input is okay.
- */
- #ifndef lbnNorm_32
- unsigned
- lbnNorm_32(BNWORD32 const *num, unsigned len)
- {
- BIGLITTLE(num -= len,num += len);
- while (len && BIGLITTLE(*num++,*--num) == 0)
- --len;
- return len;
- }
- #endif /* lbnNorm_32 */
- /*
- * lbnBits_32 - return the number of significant bits in the array.
- * It starts by normalizing the array. Zero-length input is okay.
- * Then assuming there's anything to it, it fetches the high word,
- * generates a bit length by multiplying the word length by 32, and
- * subtracts off 32/2, 32/4, 32/8, ... bits if the high bits are clear.
- */
- #ifndef lbnBits_32
- unsigned
- lbnBits_32(BNWORD32 const *num, unsigned len)
- {
- BNWORD32 t;
- unsigned i;
- len = lbnNorm_32(num, len);
- if (len) {
- t = BIGLITTLE(*(num-len),*(num+(len-1)));
- assert(t);
- len *= 32;
- i = 32/2;
- do {
- if (t >> i)
- t >>= i;
- else
- len -= i;
- } while ((i /= 2) != 0);
- }
- return len;
- }
- #endif /* lbnBits_32 */
- /*
- * If defined, use hand-rolled divide rather than compiler's native.
- * If the machine doesn't do it in line, the manual code is probably
- * faster, since it can assume normalization and the fact that the
- * quotient will fit into 32 bits, which a general 64-bit divide
- * in a compiler's run-time library can't do.
- */
- #ifndef BN_SLOW_DIVIDE_64
- /* Assume that divisors of more than thirty-two bits are slow */
- #define BN_SLOW_DIVIDE_64 (64 > 0x20)
- #endif
- /*
- * Return (nh<<32|nl) % d, and place the quotient digit into *q.
- * It is guaranteed that nh < d, and that d is normalized (with its high
- * bit set). If we have a double-width type, it's easy. If not, ooh,
- * yuk!
- */
- #ifndef lbnDiv21_32
- #if defined(BNWORD64) && !BN_SLOW_DIVIDE_64
- BNWORD32
- lbnDiv21_32(BNWORD32 *q, BNWORD32 nh, BNWORD32 nl, BNWORD32 d)
- {
- BNWORD64 n = (BNWORD64)nh << 32 | nl;
- /* Divisor must be normalized */
- assert(d >> (32-1) == 1);
- *q = n / d;
- return n % d;
- }
- #else
- /*
- * This is where it gets ugly.
- *
- * Do the division in two halves, using Algorithm D from section 4.3.1
- * of Knuth. Note Theorem B from that section, that the quotient estimate
- * is never more than the true quotient, and is never more than two
- * too low.
- *
- * The mapping onto conventional long division is (everything a half word):
- * _____________qh___ql_
- * dh dl ) nh.h nh.l nl.h nl.l
- * - (qh * d)
- * -----------
- * rrrr rrrr nl.l
- * - (ql * d)
- * -----------
- * rrrr rrrr
- *
- * The implicit 3/2-digit d*qh and d*ql subtractors are computed this way:
- * First, estimate a q digit so that nh/dh works. Subtracting qh*dh from
- * the (nh.h nh.l) list leaves a 1/2-word remainder r. Then compute the
- * low part of the subtractor, qh * dl. This also needs to be subtracted
- * from (nh.h nh.l nl.h) to get the final remainder. So we take the
- * remainder, which is (nh.h nh.l) - qh*dl, shift it and add in nl.h, and
- * try to subtract qh * dl from that. Since the remainder is 1/2-word
- * long, shifting and adding nl.h results in a single word r.
- * It is possible that the remainder we're working with, r, is less than
- * the product qh * dl, if we estimated qh too high. The estimation
- * technique can produce a qh that is too large (never too small), leading
- * to r which is too small. In that case, decrement the digit qh, add
- * shifted dh to r (to correct for that error), and subtract dl from the
- * product we're comparing r with. That's the "correct" way to do it, but
- * just adding dl to r instead of subtracting it from the product is
- * equivalent and a lot simpler. You just have to watch out for overflow.
- *
- * The process is repeated with (rrrr rrrr nl.l) for the low digit of the
- * quotient ql.
- *
- * The various uses of 32/2 for shifts are because of the note about
- * automatic editing of this file at the very top of the file.
- */
- #define highhalf(x) ( (x) >> 32/2 )
- #define lowhalf(x) ( (x) & (((BNWORD32)1 << 32/2)-1) )
- BNWORD32
- lbnDiv21_32(BNWORD32 *q, BNWORD32 nh, BNWORD32 nl, BNWORD32 d)
- {
- BNWORD32 dh = highhalf(d), dl = lowhalf(d);
- BNWORD32 qh, ql, prod, r;
- /* Divisor must be normalized */
- assert((d >> (32-1)) == 1);
- /* Do first half-word of division */
- qh = nh / dh;
- r = nh % dh;
- prod = qh * dl;
- /*
- * Add next half-word of numerator to remainder and correct.
- * qh may be up to two too large.
- */
- r = (r << (32/2)) | highhalf(nl);
- if (r < prod) {
- --qh; r += d;
- if (r >= d && r < prod) {
- --qh; r += d;
- }
- }
- r -= prod;
- /* Do second half-word of division */
- ql = r / dh;
- r = r % dh;
- prod = ql * dl;
- r = (r << (32/2)) | lowhalf(nl);
- if (r < prod) {
- --ql; r += d;
- if (r >= d && r < prod) {
- --ql; r += d;
- }
- }
- r -= prod;
- *q = (qh << (32/2)) | ql;
- return r;
- }
- #endif
- #endif /* lbnDiv21_32 */
- /*
- * In the division functions, the dividend and divisor are referred to
- * as "n" and "d", which stand for "numerator" and "denominator".
- *
- * The quotient is (nlen-dlen+1) digits long. It may be overlapped with
- * the high (nlen-dlen) words of the dividend, but one extra word is needed
- * on top to hold the top word.
- */
- /*
- * Divide an n-word number by a 1-word number, storing the remainder
- * and n-1 words of the n-word quotient. The high word is returned.
- * It IS legal for rem to point to the same address as n, and for
- * q to point one word higher.
- *
- * TODO: If BN_SLOW_DIVIDE_64, add a divnhalf_32 which uses 32-bit
- * dividends if the divisor is half that long.
- * TODO: Shift the dividend on the fly to avoid the last division and
- * instead have a remainder that needs shifting.
- * TODO: Use reciprocals rather than dividing.
- */
- #ifndef lbnDiv1_32
- BNWORD32
- lbnDiv1_32(BNWORD32 *q, BNWORD32 *rem, BNWORD32 const *n, unsigned len,
- BNWORD32 d)
- {
- unsigned shift;
- unsigned xlen;
- BNWORD32 r;
- BNWORD32 qhigh;
- assert(len > 0);
- assert(d);
- if (len == 1) {
- r = *n;
- *rem = r%d;
- return r/d;
- }
- shift = 0;
- r = d;
- xlen = 32/2;
- do {
- if (r >> xlen)
- r >>= xlen;
- else
- shift += xlen;
- } while ((xlen /= 2) != 0);
- assert((d >> (32-1-shift)) == 1);
- d <<= shift;
- BIGLITTLE(q -= len-1,q += len-1);
- BIGLITTLE(n -= len,n += len);
- r = BIGLITTLE(*n++,*--n);
- if (r < d) {
- qhigh = 0;
- } else {
- qhigh = r/d;
- r %= d;
- }
- xlen = len;
- while (--xlen)
- r = lbnDiv21_32(BIGLITTLE(q++,--q), r, BIGLITTLE(*n++,*--n), d);
- /*
- * Final correction for shift - shift the quotient up "shift"
- * bits, and merge in the extra bits of quotient. Then reduce
- * the final remainder mod the real d.
- */
- if (shift) {
- d >>= shift;
- qhigh = (qhigh << shift) | lbnLshift_32(q, len-1, shift);
- BIGLITTLE(q[-1],*q) |= r/d;
- r %= d;
- }
- *rem = r;
- return qhigh;
- }
- #endif
- /*
- * This function performs a "quick" modulus of a number with a divisor
- * d which is guaranteed to be at most sixteen bits, i.e. less than 65536.
- * This applies regardless of the word size the library is compiled with.
- *
- * This function is important to prime generation, for sieving.
- */
- #ifndef lbnModQ_32
- /* If there's a custom lbnMod21_32, no normalization needed */
- #ifdef lbnMod21_32
- unsigned
- lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d)
- {
- unsigned i, shift;
- BNWORD32 r;
- assert(len > 0);
- BIGLITTLE(n -= len,n += len);
- /* Try using a compare to avoid the first divide */
- r = BIGLITTLE(*n++,*--n);
- if (r >= d)
- r %= d;
- while (--len)
- r = lbnMod21_32(r, BIGLITTLE(*n++,*--n), d);
- return r;
- }
- #elif defined(BNWORD64) && !BN_SLOW_DIVIDE_64
- unsigned
- lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d)
- {
- BNWORD32 r;
- if (!--len)
- return BIGLITTLE(n[-1],n[0]) % d;
- BIGLITTLE(n -= len,n += len);
- r = BIGLITTLE(n[-1],n[0]);
- do {
- r = (BNWORD32)((((BNWORD64)r<<32) | BIGLITTLE(*n++,*--n)) % d);
- } while (--len);
- return r;
- }
- #elif 32 >= 0x20
- /*
- * If the single word size can hold 65535*65536, then this function
- * is avilable.
- */
- #ifndef highhalf
- #define highhalf(x) ( (x) >> 32/2 )
- #define lowhalf(x) ( (x) & ((1 << 32/2)-1) )
- #endif
- unsigned
- lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d)
- {
- BNWORD32 r, x;
- BIGLITTLE(n -= len,n += len);
- r = BIGLITTLE(*n++,*--n);
- while (--len) {
- x = BIGLITTLE(*n++,*--n);
- r = (r%d << 32/2) | highhalf(x);
- r = (r%d << 32/2) | lowhalf(x);
- }
- return r%d;
- }
- #else
- /* Default case - use lbnDiv21_32 */
- unsigned
- lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d)
- {
- unsigned i, shift;
- BNWORD32 r;
- BNWORD32 q;
- assert(len > 0);
- shift = 0;
- r = d;
- i = 32;
- while (i /= 2) {
- if (r >> i)
- r >>= i;
- else
- shift += i;
- }
- assert(d >> (32-1-shift) == 1);
- d <<= shift;
- BIGLITTLE(n -= len,n += len);
- r = BIGLITTLE(*n++,*--n);
- if (r >= d)
- r %= d;
- while (--len)
- r = lbnDiv21_32(&q, r, BIGLITTLE(*n++,*--n), d);
- /*
- * Final correction for shift - shift the quotient up "shift"
- * bits, and merge in the extra bits of quotient. Then reduce
- * the final remainder mod the real d.
- */
- if (shift)
- r %= d >> shift;
- return r;
- }
- #endif
- #endif /* lbnModQ_32 */
- /*
- * Reduce n mod d and return the quotient. That is, find:
- * q = n / d;
- * n = n % d;
- * d is altered during the execution of this subroutine by normalizing it.
- * It must already have its most significant word non-zero; it is shifted
- * so its most significant bit is non-zero.
- *
- * The quotient q is nlen-dlen+1 words long. To make it possible to
- * overlap the quptient with the input (you can store it in the high dlen
- * words), the high word of the quotient is *not* stored, but is returned.
- * (If all you want is the remainder, you don't care about it, anyway.)
- *
- * This uses algorithm D from Knuth (4.3.1), except that we do binary
- * (shift) normalization of the divisor. WARNING: This is hairy!
- *
- * This function is used for some modular reduction, but it is not used in
- * the modular exponentiation loops; they use Montgomery form and the
- * corresponding, more efficient, Montgomery reduction. This code
- * is needed for the conversion to Montgomery form, however, so it
- * has to be here and it might as well be reasonably efficient.
- *
- * The overall operation is as follows ("top" and "up" refer to the
- * most significant end of the number; "bottom" and "down", the least):
- *
- * - Shift the divisor up until the most significant bit is set.
- * - Shift the dividend up the same amount. This will produce the
- * correct quotient, and the remainder can be recovered by shifting
- * it back down the same number of bits. This may produce an overflow
- * word, but the word is always strictly less than the most significant
- * divisor word.
- * - Estimate the first quotient digit qhat:
- * - First take the top two words (one of which is the overflow) of the
- * dividend and divide by the top word of the divisor:
- * qhat = (nh,nm)/dh. This qhat is >= the correct quotient digit
- * and, since dh is normalized, it is at most two over.
- * - Second, correct by comparing the top three words. If
- * (dh,dl) * qhat > (nh,nm,ml), decrease qhat and try again.
- * The second iteration can be simpler because there can't be a third.
- * The computation can be simplified by subtracting dh*qhat from
- * both sides, suitably shifted. This reduces the left side to
- * dl*qhat. On the right, (nh,nm)-dh*qhat is simply the
- * remainder r from (nh,nm)%dh, so the right is (r,nl).
- * This produces qhat that is almost always correct and at
- * most (prob ~ 2/2^32) one too high.
- * - Subtract qhat times the divisor (suitably shifted) from the dividend.
- * If there is a borrow, qhat was wrong, so decrement it
- * and add the divisor back in (once).
- * - Store the final quotient digit qhat in the quotient array q.
- *
- * Repeat the quotient digit computation for successive digits of the
- * quotient until the whole quotient has been computed. Then shift the
- * divisor and the remainder down to correct for the normalization.
- *
- * TODO: Special case 2-word divisors.
- * TODO: Use reciprocals rather than dividing.
- */
- #ifndef divn_32
- BNWORD32
- lbnDiv_32(BNWORD32 *q, BNWORD32 *n, unsigned nlen, BNWORD32 *d, unsigned dlen)
- {
- BNWORD32 nh,nm,nl; /* Top three words of the dividend */
- BNWORD32 dh,dl; /* Top two words of the divisor */
- BNWORD32 qhat; /* Extimate of quotient word */
- BNWORD32 r; /* Remainder from quotient estimate division */
- BNWORD32 qhigh; /* High word of quotient */
- unsigned i; /* Temp */
- unsigned shift; /* Bits shifted by normalization */
- unsigned qlen = nlen-dlen; /* Size of quotient (less 1) */
- #ifdef mul32_ppmm
- BNWORD32 t32;
- #elif defined(BNWORD64)
- BNWORD64 t64;
- #else /* use lbnMulN1_32 */
- BNWORD32 t2[2];
- #define t2high BIGLITTLE(t2[0],t2[1])
- #define t2low BIGLITTLE(t2[1],t2[0])
- #endif
- assert(dlen);
- assert(nlen >= dlen);
- /*
- * Special cases for short divisors. The general case uses the
- * top top 2 digits of the divisor (d) to estimate a quotient digit,
- * so it breaks if there are fewer digits available. Thus, we need
- * special cases for a divisor of length 1. A divisor of length
- * 2 can have a *lot* of administrivia overhead removed removed,
- * so it's probably worth special-casing that case, too.
- */
- if (dlen == 1)
- return lbnDiv1_32(q, BIGLITTLE(n-1,n), n, nlen,
- BIGLITTLE(d[-1],d[0]));
- #if 0
- /*
- * @@@ This is not yet written... The general loop will do,
- * albeit less efficiently
- */
- if (dlen == 2) {
- /*
- * divisor two digits long:
- * use the 3/2 technique from Knuth, but we know
- * it's exact.
- */
- dh = BIGLITTLE(d[-1],d[0]);
- dl = BIGLITTLE(d[-2],d[1]);
- shift = 0;
- if ((sh & ((BNWORD32)1 << 32-1-shift)) == 0) {
- do {
- shift++;
- } while (dh & (BNWORD32)1<<32-1-shift) == 0);
- dh = dh << shift | dl >> (32-shift);
- dl <<= shift;
- }
- for (shift = 0; (dh & (BNWORD32)1 << 32-1-shift)) == 0; shift++)
- ;
- if (shift) {
- }
- dh = dh << shift | dl >> (32-shift);
- shift = 0;
- while (dh
- }
- #endif
- dh = BIGLITTLE(*(d-dlen),*(d+(dlen-1)));
- assert(dh);
- /* Normalize the divisor */
- shift = 0;
- r = dh;
- i = 32/2;
- do {
- if (r >> i)
- r >>= i;
- else
- shift += i;
- } while ((i /= 2) != 0);
- nh = 0;
- if (shift) {
- lbnLshift_32(d, dlen, shift);
- dh = BIGLITTLE(*(d-dlen),*(d+(dlen-1)));
- nh = lbnLshift_32(n, nlen, shift);
- }
- /* Assert that dh is now normalized */
- assert(dh >> (32-1));
- /* Also get the second-most significant word of the divisor */
- dl = BIGLITTLE(*(d-(dlen-1)),*(d+(dlen-2)));
- /*
- * Adjust pointers: n to point to least significant end of first
- * first subtract, and q to one the most-significant end of the
- * quotient array.
- */
- BIGLITTLE(n -= qlen,n += qlen);
- BIGLITTLE(q -= qlen,q += qlen);
- /* Fetch the most significant stored word of the dividend */
- nm = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
- /*
- * Compute the first digit of the quotient, based on the
- * first two words of the dividend (the most significant of which
- * is the overflow word h).
- */
- if (nh) {
- assert(nh < dh);
- r = lbnDiv21_32(&qhat, nh, nm, dh);
- } else if (nm >= dh) {
- qhat = nm/dh;
- r = nm % dh;
- } else { /* Quotient is zero */
- qhigh = 0;
- goto divloop;
- }
- /* Now get the third most significant word of the dividend */
- nl = BIGLITTLE(*(n-(dlen-1)),*(n+(dlen-2)));
- /*
- * Correct qhat, the estimate of quotient digit.
- * qhat can only be high, and at most two words high,
- * so the loop can be unrolled and abbreviated.
- */
- #ifdef mul32_ppmm
- mul32_ppmm(nm, t32, qhat, dl);
- if (nm > r || (nm == r && t32 > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- nm -= (t32 < dl);
- t32 -= dl;
- if (nm > r || (nm == r && t32 > nl))
- qhat--;
- }
- }
- #elif defined(BNWORD64)
- t64 = (BNWORD64)qhat * dl;
- if (t64 > ((BNWORD64)r << 32) + nl) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) > dh) {
- t64 -= dl;
- if (t64 > ((BNWORD64)r << 32) + nl)
- qhat--;
- }
- }
- #else /* Use lbnMulN1_32 */
- lbnMulN1_32(BIGLITTLE(t2+2,t2), &dl, 1, qhat);
- if (t2high > r || (t2high == r && t2low > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- t2high -= (t2low < dl);
- t2low -= dl;
- if (t2high > r || (t2high == r && t2low > nl))
- qhat--;
- }
- }
- #endif
- /* Do the multiply and subtract */
- r = lbnMulSub1_32(n, d, dlen, qhat);
- /* If there was a borrow, add back once. */
- if (r > nh) { /* Borrow? */
- (void)lbnAddN_32(n, d, dlen);
- qhat--;
- }
- /* Remember the first quotient digit. */
- qhigh = qhat;
- /* Now, the main division loop: */
- divloop:
- while (qlen--) {
- /* Advance n */
- nh = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
- BIGLITTLE(++n,--n);
- nm = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
- if (nh == dh) {
- qhat = ~(BNWORD32)0;
- /* Optimized computation of r = (nh,nm) - qhat * dh */
- r = nh + nm;
- if (r < nh)
- goto subtract;
- } else {
- assert(nh < dh);
- r = lbnDiv21_32(&qhat, nh, nm, dh);
- }
- nl = BIGLITTLE(*(n-(dlen-1)),*(n+(dlen-2)));
- #ifdef mul32_ppmm
- mul32_ppmm(nm, t32, qhat, dl);
- if (nm > r || (nm == r && t32 > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- nm -= (t32 < dl);
- t32 -= dl;
- if (nm > r || (nm == r && t32 > nl))
- qhat--;
- }
- }
- #elif defined(BNWORD64)
- t64 = (BNWORD64)qhat * dl;
- if (t64 > ((BNWORD64)r<<32) + nl) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- t64 -= dl;
- if (t64 > ((BNWORD64)r << 32) + nl)
- qhat--;
- }
- }
- #else /* Use lbnMulN1_32 */
- lbnMulN1_32(BIGLITTLE(t2+2,t2), &dl, 1, qhat);
- if (t2high > r || (t2high == r && t2low > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- t2high -= (t2low < dl);
- t2low -= dl;
- if (t2high > r || (t2high == r && t2low > nl))
- qhat--;
- }
- }
- #endif
- /*
- * As a point of interest, note that it is not worth checking
- * for qhat of 0 or 1 and installing special-case code. These
- * occur with probability 2^-32, so spending 1 cycle to check
- * for them is only worth it if we save more than 2^15 cycles,
- * and a multiply-and-subtract for numbers in the 1024-bit
- * range just doesn't take that long.
- */
- subtract:
- /*
- * n points to the least significant end of the substring
- * of n to be subtracted from. qhat is either exact or
- * one too large. If the subtract gets a borrow, it was
- * one too large and the divisor is added back in. It's
- * a dlen+1 word add which is guaranteed to produce a
- * carry out, so it can be done very simply.
- */
- r = lbnMulSub1_32(n, d, dlen, qhat);
- if (r > nh) { /* Borrow? */
- (void)lbnAddN_32(n, d, dlen);
- qhat--;
- }
- /* Store the quotient digit */
- BIGLITTLE(*q++,*--q) = qhat;
- }
- /* Tah dah! */
- if (shift) {
- lbnRshift_32(d, dlen, shift);
- lbnRshift_32(n, dlen, shift);
- }
- return qhigh;
- }
- #endif
- /*
- * Find the negative multiplicative inverse of x (x must be odd!) modulo 2^32.
- *
- * This just performs Newton's iteration until it gets the
- * inverse. The initial estimate is always correct to 3 bits, and
- * sometimes 4. The number of valid bits doubles each iteration.
- * (To prove it, assume x * y == 1 (mod 2^n), and introduce a variable
- * for the error mod 2^2n. x * y == 1 + k*2^n (mod 2^2n) and follow
- * the iteration through.)
- */
- #ifndef lbnMontInv1_32
- BNWORD32
- lbnMontInv1_32(BNWORD32 const x)
- {
- BNWORD32 y = x, z;
- assert(x & 1);
-
- while ((z = x*y) != 1)
- y *= 2 - z;
- return -y;
- }
- #endif /* !lbnMontInv1_32 */
- #if defined(BNWORD64) && PRODUCT_SCAN
- /*
- * Test code for product-scanning Montgomery reduction.
- * This seems to slow the C code down rather than speed it up.
- *
- * The first loop computes the Montgomery multipliers, storing them over
- * the low half of the number n.
- *
- * The second half multiplies the upper half, adding in the modulus
- * times the Montgomery multipliers. The results of this multiply
- * are stored.
- */
- void
- lbnMontReduce_32(BNWORD32 *n, BNWORD32 const *mod, unsigned mlen, BNWORD32 inv)
- {
- BNWORD64 x, y;
- BNWORD32 const *pm;
- BNWORD32 *pn;
- BNWORD32 t;
- unsigned carry;
- unsigned i, j;
- /* Special case of zero */
- if (!mlen)
- return;
- /* Pass 1 - compute Montgomery multipliers */
- /* First iteration can have certain simplifications. */
- t = BIGLITTLE(n[-1],n[0]);
- x = t;
- t *= inv;
- BIGLITTLE(n[-1], n[0]) = t;
- x += (BNWORD64)t * BIGLITTLE(mod[-1],mod[0]); /* Can't overflow */
- assert((BNWORD32)x == 0);
- x = x >> 32;
- for (i = 1; i < mlen; i++) {
- carry = 0;
- pn = n;
- pm = BIGLITTLE(mod-i-1,mod+i+1);
- for (j = 0; j < i; j++) {
- y = (BNWORD64)BIGLITTLE(*--pn * *pm++, *pn++ * *--pm);
- x += y;
- carry += (x < y);
- }
- assert(BIGLITTLE(pn == n-i, pn == n+i));
- y = t = BIGLITTLE(pn[-1], pn[0]);
- x += y;
- carry += (x < y);
- BIGLITTLE(pn[-1], pn[0]) = t = inv * (BNWORD32)x;
- assert(BIGLITTLE(pm == mod-1, pm == mod+1));
- y = (BNWORD64)t * BIGLITTLE(pm[0],pm[-1]);
- x += y;
- carry += (x < y);
- assert((BNWORD32)x == 0);
- x = x >> 32 | (BNWORD64)carry << 32;
- }
- BIGLITTLE(n -= mlen, n += mlen);
- /* Pass 2 - compute upper words and add to n */
- for (i = 1; i < mlen; i++) {
- carry = 0;
- pm = BIGLITTLE(mod-i,mod+i);
- pn = n;
- for (j = i; j < mlen; j++) {
- y = (BNWORD64)BIGLITTLE(*--pm * *pn++, *pm++ * *--pn);
- x += y;
- carry += (x < y);
- }
- assert(BIGLITTLE(pm == mod-mlen, pm == mod+mlen));
- assert(BIGLITTLE(pn == n+mlen-i, pn == n-mlen+i));
- y = t = BIGLITTLE(*(n-i),*(n+i-1));
- x += y;
- carry += (x < y);
- BIGLITTLE(*(n-i),*(n+i-1)) = (BNWORD32)x;
- x = (x >> 32) | (BNWORD64)carry << 32;
- }
- /* Last round of second half, simplified. */
- t = BIGLITTLE(*(n-mlen),*(n+mlen-1));
- x += t;
- BIGLITTLE(*(n-mlen),*(n+mlen-1)) = (BNWORD32)x;
- carry = (unsigned)(x >> 32);
- while (carry)
- carry -= lbnSubN_32(n, mod, mlen);
- while (lbnCmp_32(n, mod, mlen) >= 0)
- (void)lbnSubN_32(n, mod, mlen);
- }
- #define lbnMontReduce_32 lbnMontReduce_32
- #endif
- /*
- * Montgomery reduce n, modulo mod. This reduces modulo mod and divides by
- * 2^(32*mlen). Returns the result in the *top* mlen words of the argument n.
- * This is ready for another multiplication using lbnMul_32.
- *
- * Montgomery representation is a very useful way to encode numbers when
- * you're doing lots of modular reduction. What you do is pick a multiplier
- * R which is relatively prime to the modulus and very easy to divide by.
- * Since the modulus is odd, R is closen as a power of 2, so the division
- * is a shift. In fact, it's a shift of an integral number of words,
- * so the shift can be implicit - just drop the low-order words.
- *
- * Now, choose R *larger* than the modulus m, 2^(32*mlen). Then convert
- * all numbers a, b, etc. to Montgomery form M(a), M(b), etc using the
- * relationship M(a) = a*R mod m, M(b) = b*R mod m, etc. Note that:
- * - The Montgomery form of a number depends on the modulus m.
- * A fixed modulus m is assumed throughout this discussion.
- * - Since R is relaitvely prime to m, multiplication by R is invertible;
- * no information about the numbers is lost, they're just scrambled.
- * - Adding (and subtracting) numbers in this form works just as usual.
- * M(a+b) = (a+b)*R mod m = (a*R + b*R) mod m = (M(a) + M(b)) mod m
- * - Multiplying numbers in this form produces a*b*R*R. The problem
- * is to divide out the excess factor of R, modulo m as well as to
- * reduce to the given length mlen. It turns out that this can be
- * done *faster* than a normal divide, which is where the speedup
- * in Montgomery division comes from.
- *
- * Normal reduction chooses a most-significant quotient digit q and then
- * subtracts q*m from the number to be reduced. Choosing q is tricky
- * and involved (just look at lbnDiv_32 to see!) and is usually
- * imperfect, requiring a check for correction after the subtraction.
- *
- * Montgomery reduction *adds* a multiple of m to the *low-order* part
- * of the number to be reduced. This multiple is chosen to make the
- * low-order part of the number come out to zero. This can be done
- * with no trickery or error using a precomputed inverse of the modulus.
- * In this code, the "part" is one word, but any width can be used.
- *
- * Repeating this step sufficiently often results in a value which
- * is a multiple of R (a power of two, remember) but is still (since
- * the additions were to the low-order part and thus did not increase
- * the value of the number being reduced very much) still not much
- * larger than m*R. Then implicitly divide by R and subtract off
- * m until the result is in the correct range.
- *
- * Since the low-order part being cancelled is less than R, the
- * multiple of m added must have a multiplier which is at most R-1.
- * Assuming that the input is at most m*R-1, the final number is
- * at most m*(2*R-1)-1 = 2*m*R - m - 1, so subtracting m once from
- * the high-order part, equivalent to subtracting m*R from the
- * while number, produces a result which is at most m*R - m - 1,
- * which divided by R is at most m-1.
- *
- * To convert *to* Montgomery form, you need a regular remainder
- * routine, although you can just compute R*R (mod m) and do the
- * conversion using Montgomery multiplication. To convert *from*
- * Montgomery form, just Montgomery reduce the number to
- * remove the extra factor of R.
- *
- * TODO: Change to a full inverse and use Karatsuba's multiplication
- * rather than this word-at-a-time.
- */
- #ifndef lbnMontReduce_32
- void
- lbnMontReduce_32(BNWORD32 *n, BNWORD32 const *mod, unsigned const mlen,
- BNWORD32 inv)
- {
- BNWORD32 t;
- BNWORD32 c = 0;
- unsigned len = mlen;
- /* inv must be the negative inverse of mod's least significant word */
- assert((BNWORD32)(inv * BIGLITTLE(mod[-1],mod[0])) == (BNWORD32)-1);
- assert(len);
- do {
- t = lbnMulAdd1_32(n, mod, mlen, inv * BIGLITTLE(n[-1],n[0]));
- c += lbnAdd1_32(BIGLITTLE(n-mlen,n+mlen), len, t);
- BIGLITTLE(--n,++n);
- } while (--len);
- /*
- * All that adding can cause an overflow past the modulus size,
- * but it's unusual, and never by much, so a subtraction loop
- * is the right way to deal with it.
- * This subtraction happens infrequently - I've only ever seen it
- * invoked once per reduction, and then just under 22.5% of the time.
- */
- while (c)
- c -= lbnSubN_32(n, mod, mlen);
- while (lbnCmp_32(n, mod, mlen) >= 0)
- (void)lbnSubN_32(n, mod, mlen);
- }
- #endif /* !lbnMontReduce_32 */
- /*
- * A couple of helpers that you might want to implement atomically
- * in asm sometime.
- */
- #ifndef lbnMontMul_32
- /*
- * Multiply "num1" by "num2", modulo "mod", all of length "len", and
- * place the result in the high half of "prod". "inv" is the inverse
- * of the least-significant word of the modulus, modulo 2^32.
- * This uses numbers in Montgomery form. Reduce using "len" and "inv".
- *
- * This is implemented as a macro to win on compilers that don't do
- * inlining, since it's so trivial.
- */
- #define lbnMontMul_32(prod, n1, n2, mod, len, inv) \
- (lbnMulX_32(prod, n1, n2, len), lbnMontReduce_32(prod, mod, len, inv))
- #endif /* !lbnMontMul_32 */
- #ifndef lbnMontSquare_32
- /*
- * Square "n", modulo "mod", both of length "len", and place the result
- * in the high half of "prod". "inv" is the inverse of the least-significant
- * word of the modulus, modulo 2^32.
- * This uses numbers in Montgomery form. Reduce using "len" and "inv".
- *
- * This is implemented as a macro to win on compilers that don't do
- * inlining, since it's so trivial.
- */
- #define lbnMontSquare_32(prod, n, mod, len, inv) \
- (lbnSquare_32(prod, n, len), lbnMontReduce_32(prod, mod, len, inv))
-
- #endif /* !lbnMontSquare_32 */
- /*
- * Convert a number to Montgomery form - requires mlen + nlen words
- * of memory in "n".
- */
- void
- lbnToMont_32(BNWORD32 *n, unsigned nlen, BNWORD32 *mod, unsigned mlen)
- {
- /* Move n up "mlen" words */
- lbnCopy_32(BIGLITTLE(n-mlen,n+mlen), n, nlen);
- lbnZero_32(n, mlen);
- /* Do the division - dump the quotient in the high-order words */
- (void)lbnDiv_32(BIGLITTLE(n-mlen,n+mlen), n, mlen+nlen, mod, mlen);
- }
- /*
- * Convert from Montgomery form. Montgomery reduction is all that is
- * needed.
- */
- void
- lbnFromMont_32(BNWORD32 *n, BNWORD32 *mod, unsigned len)
- {
- /* Zero the high words of n */
- lbnZero_32(BIGLITTLE(n-len,n+len), len);
- lbnMontReduce_32(n, mod, len, lbnMontInv1_32(mod[BIGLITTLE(-1,0)]));
- /* Move n down len words */
- lbnCopy_32(n, BIGLITTLE(n-len,n+len), len);
- }
- /*
- * The windowed exponentiation algorithm, precomputes a table of odd
- * powers of n up to 2^k. See the comment in bnExpMod_32 below for
- * an explanation of how it actually works works.
- *
- * It takes 2^(k-1)-1 multiplies to compute the table, and (e-1)/(k+1)
- * multiplies (on average) to perform the exponentiation. To minimize
- * the sum, k must vary with e. The optimal window sizes vary with the
- * exponent length. Here are some selected values and the boundary cases.
- * (An underscore _ has been inserted into some of the numbers to ensure
- * that magic strings like 32 do not appear in this table. It should be
- * ignored.)
- *
- * At e = 1 bits, k=1 (0.000000) is best
- * At e = 2 bits, k=1 (0.500000) is best
- * At e = 4 bits, k=1 (1.500000) is best
- * At e = 8 bits, k=2 (3.333333) < k=1 (3.500000)
- * At e = 1_6 bits, k=2 (6.000000) is best
- * At e = 26 bits, k=3 (9.250000) < k=2 (9.333333)
- * At e = 3_2 bits, k=3 (10.750000) is best
- * At e = 6_4 bits, k=3 (18.750000) is best
- * At e = 82 bits, k=4 (23.200000) < k=3 (23.250000)
- * At e = 128 bits, k=4 (3_2.400000) is best
- * At e = 242 bits, k=5 (55.1_66667) < k=4 (55.200000)
- * At e = 256 bits, k=5 (57.500000) is best
- * At e = 512 bits, k=5 (100.1_66667) is best
- * At e = 674 bits, k=6 (127.142857) < k=5 (127.1_66667)
- * At e = 1024 bits, k=6 (177.142857) is best
- * At e = 1794 bits, k=7 (287.125000) < k=6 (287.142857)
- * At e = 2048 bits, k=7 (318.875000) is best
- * At e = 4096 bits, k=7 (574.875000) is best
- *
- * The numbers in parentheses are the expected number of multiplications
- * needed to do the computation. The normal russian-peasant modular
- * exponentiation technique always uses (e-1)/2. For exponents as
- * small as 192 bits (below the range of current factoring algorithms),
- * half of the multiplies are eliminated, 45.2 as opposed to the naive
- * 95.5. Counting the 191 squarings as 3/4 a multiply each (squaring
- * proper is just over half of multiplying, but the Montgomery
- * reduction in each case is also a multiply), that's 143.25
- * multiplies, for totals of 188.45 vs. 238.75 - a 21% savings.
- * For larger exponents (like 512 bits), it's 483.92 vs. 639.25, a
- * 24.3% savings. It asymptotically approaches 25%.
- *
- * Um, actually there's a slightly more accurate way to count, which
- * really is the average number of multiplies required, averaged
- * uniformly over all 2^(e-1) e-bit numbers, from 2^(e-1) to (2^e)-1.
- * It's based on the recurrence that for the last b bits, b <= k, at
- * most one multiply is needed (and none at all 1/2^b of the time),
- * while when b > k, the odds are 1/2 each way that the bit will be
- * 0 (meaning no multiplies to reduce it to the b-1-bit case) and
- * 1/2 that the bit will be 1, starting a k-bit window and requiring
- * 1 multiply beyond the b-k-bit case. Since the most significant
- * bit is always 1, a k-bit window always starts there, and that
- * multiply is by 1, so it isn't a multiply at all. Thus, the
- * number of multiplies is simply that needed for the last e-k bits.
- * This recurrence produces:
- *
- * At e = 1 bits, k=1 (0.000000) is best
- * At e = 2 bits, k=1 (0.500000) is best
- * At e = 4 bits, k=1 (1.500000) is best
- * At e = 6 bits, k=2 (2.437500) < k=1 (2.500000)
- * At e = 8 bits, k=2 (3.109375) is best
- * At e = 1_6 bits, k=2 (5.777771) is best
- * At e = 24 bits, k=3 (8.437629) < k=2 (8.444444)
- * At e = 3_2 bits, k=3 (10.437492) is best
- * At e = 6_4 bits, k=3 (18.437500) is best
- * At e = 81 bits, k=4 (22.6_40000) < k=3 (22.687500)
- * At e = 128 bits, k=4 (3_2.040000) is best
- * At e = 241 bits, k=5 (54.611111) < k=4 (54.6_40000)
- * At e = 256 bits, k=5 (57.111111) is best
- * At e = 512 bits, k=5 (99.777778) is best
- * At e = 673 bits, k=6 (126.591837) < k=5 (126.611111)
- * At e = 1024 bits, k=6 (176.734694) is best
- * At e = 1793 bits, k=7 (286.578125) < k=6 (286.591837)
- * At e = 2048 bits, k=7 (318.453125) is best
- * At e = 4096 bits, k=7 (574.453125) is best
- *
- * This has the rollover points at 6, 24, 81, 241, 673 and 1793 instead
- * of 8, 26, 82, 242, 674, and 1794. Not a very big difference.
- * (The numbers past that are k=8 at 4609 and k=9 at 11521,
- * vs. one more in each case for the approximation.)
- *
- * Given that exponents for which k>7 are useful are uncommon,
- * a fixed size table for k <= 7 is used for simplicity.
- *
- * The basic number of squarings needed is e-1, although a k-bit
- * window (for k > 1) can save, on average, k-2 of those, too.
- * That savings currently isn't counted here. It would drive the
- * crossover points slightly lower.
- * (Actually, this win is also reduced in the DoubleExpMod case,
- * meaning we'd have to split the tables. Except for that, the
- * multiplies by powers of the two bases are independent, so
- * the same logic applies to each as the single case.)
- *
- * Table entry i is the largest number of bits in an exponent to
- * process with a window size of i+1. Entry 6 is the largest
- * possible unsigned number, so the window will never be more
- * than 7 bits, requiring 2^6 = 0x40 slots.
- */
- #define BNEXPMOD_MAX_WINDOW 7
- static unsigned const bnExpModThreshTable[BNEXPMOD_MAX_WINDOW] = {
- 5, 23, 80, 240, 672, 1792, (unsigned)-1
- /* 7, 25, 81, 241, 673, 1793, (unsigned)-1 ### The old approximations */
- };
- /*
- * Perform modular exponentiation, as fast as possible! This uses
- * Montgomery reduction, optimized squaring, and windowed exponentiation.
- * The modulus "mod" MUST be odd!
- *
- * This returns 0 on success, -1 on out of memory.
- *
- * The window algorithm:
- * The idea is to keep a running product of b1 = n^(high-order bits of exp),
- * and then keep appending exponent bits to it. The following patterns
- * apply to a 3-bit window (k = 3):
- * To append 0: square
- * To append 1: square, multiply by n^1
- * To append 10: square, multiply by n^1, square
- * To append 11: square, square, multiply by n^3
- * To append 100: square, multiply by n^1, square, square
- * To append 101: square, square, square, multiply by n^5
- * To append 110: square, square, multiply by n^3, square
- * To append 111: square, square, square, multiply by n^7
- *
- * Since each pattern involves only one multiply, the longer the pattern
- * the better, except that a 0 (no multiplies) can be appended directly.
- * We precompute a table of odd powers of n, up to 2^k, and can then
- * multiply k bits of exponent at a time. Actually, assuming random
- * exponents, there is on average one zero bit between needs to
- * multiply (1/2 of the time there's none, 1/4 of the time there's 1,
- * 1/8 of the time, there's 2, 1/32 of the time, there's 3, etc.), so
- * you have to do one multiply per k+1 bits of exponent.
- *
- * The loop walks down the exponent, squaring the result buffer as
- * it goes. There is a wbits+1 bit lookahead buffer, buf, that is
- * filled with the upcoming exponent bits. (What is read after the
- * end of the exponent is unimportant, but it is filled with zero here.)
- * When the most-significant bit of this buffer becomes set, i.e.
- * (buf & tblmask) != 0, we have to decide what pattern to multiply
- * by, and when to do it. We decide, remember to do it in future
- * after a suitable number of squarings have passed (e.g. a pattern
- * of "100" in the buffer requires that we multiply by n^1 immediately;
- * a pattern of "110" calls for multiplying by n^3 after one more
- * squaring), clear the buffer, and continue.
- *
- * When we start, there is one more optimization: the result buffer
- * is implcitly one, so squaring it or multiplying by it can be
- * optimized away. Further, if we start with a pattern like "100"
- * in the lookahead window, rather than placing n into the buffer
- * and then starting to square it, we have already computed n^2
- * to compute the odd-powers table, so we can place that into
- * the buffer and save a squaring.
- *
- * This means that if you have a k-bit window, to compute n^z,
- * where z is the high k bits of the exponent, 1/2 of the time
- * it requires no squarings. 1/4 of the time, it requires 1
- * squaring, ... 1/2^(k-1) of the time, it reqires k-2 squarings.
- * And the remaining 1/2^(k-1) of the time, the top k bits are a
- * 1 followed by k-1 0 bits, so it again only requires k-2
- * squarings, not k-1. The average of these is 1. Add that
- * to the one squaring we have to do to compute the table,
- * and you'll see that a k-bit window saves k-2 squarings
- * as well as reducing the multiplies. (It actually doesn't
- * hurt in the case k = 1, either.)
- *
- * n must have mlen words allocated. Although fewer may be in use
- * when n is passed in, all are in use on exit.
- */
- int
- lbnExpMod_32(BNWORD32 *result, BNWORD32 const *n, unsigned nlen,
- BNWORD32 const *e, unsigned elen, BNWORD32 *mod, unsigned mlen)
- {
- BNWORD32 *table[1 << (BNEXPMOD_MAX_WINDOW-1)];
- /* Table of odd powers of n */
- unsigned ebits; /* Exponent bits */
- unsigned wbits; /* Window size */
- unsigned tblmask; /* Mask of exponentiation window */
- BNWORD32 bitpos; /* Mask of current look-ahead bit */
- unsigned buf; /* Buffer of exponent bits */
- unsigned multpos; /* Where to do pending multiply */
- BNWORD32 const *mult; /* What to multiply by */
- unsigned i; /* Loop counter */
- int isone; /* Flag: accum. is implicitly one */
- BNWORD32 *a, *b; /* Working buffers/accumulators */
- BNWORD32 *t; /* Pointer into the working buffers */
- BNWORD32 inv; /* mod^-1 modulo 2^32 */
- int y; /* bnYield() result */
- assert(mlen);
- assert(nlen <= mlen);
- /* First, a couple of trivial cases. */
- elen = lbnNorm_32(e, elen);
- if (!elen) {
- /* x ^ 0 == 1 */
- lbnZero_32(result, mlen);
- BIGLITTLE(result[-1],result[0]) = 1;
- return 0;
- }
- ebits = lbnBits_32(e, elen);
- if (ebits == 1) {
- /* x ^ 1 == x */
- if (n != result)
- lbnCopy_32(result, n, nlen);
- if (mlen > nlen)
- lbnZero_32(BIGLITTLE(result-nlen,result+nlen),
- mlen-nlen);
- return 0;
- }
- /* Okay, now move the exponent pointer to the most-significant word */
- e = BIGLITTLE(e-elen, e+elen-1);
- /* Look up appropriate k-1 for the exponent - tblmask = 1<<(k-1) */
- wbits = 0;
- while (ebits > bnExpModThreshTable[wbits])
- wbits++;
- /* Allocate working storage: two product buffers and the tables. */
- LBNALLOC(a, BNWORD32, 2*mlen);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD32, 2*mlen);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
- /* Convert to the appropriate table size: tblmask = 1<<(k-1) */
- tblmask = 1u << wbits;
- /* We have the result buffer available, so use it. */
- table[0] = result;
- /*
- * Okay, we now have a minimal-sized table - expand it.
- * This is allowed to fail! If so, scale back the table size
- * and proceed.
- */
- for (i = 1; i < tblmask; i++) {
- LBNALLOC(t, BNWORD32, mlen);
- if (!t) /* Out of memory! Quit the loop. */
- break;
- table[i] = t;
- }
- /* If we stopped, with i < tblmask, shrink the tables appropriately */
- while (tblmask > i) {
- wbits--;
- tblmask >>= 1;
- }
- /* Free up our overallocations */
- while (--i > tblmask)
- LBNFREE(table[i], mlen);
- /* Okay, fill in the table */
- /* Compute the necessary modular inverse */
- inv = lbnMontInv1_32(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
- /* Convert n to Montgomery form */
- /* Move n up "mlen" words into a */
- t = BIGLITTLE(a-mlen, a+mlen);
- lbnCopy_32(t, n, nlen);
- lbnZero_32(a, mlen);
- /* Do the division - lose the quotient into the high-order words */
- (void)lbnDiv_32(t, a, mlen+nlen, mod, mlen);
- /* Copy into first table entry */
- lbnCopy_32(table[0], a, mlen);
- /* Square a into b */
- lbnMontSquare_32(b, a, mod, mlen, inv);
- /* Use high half of b to initialize the table */
- t = BIGLITTLE(b-mlen, b+mlen);
- for (i = 1; i < tblmask; i++) {
- lbnMontMul_32(a, t, table[i-1], mod, mlen, inv);
- lbnCopy_32(table[i], BIGLITTLE(a-mlen, a+mlen), mlen);
- #if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
- #endif
- }
- /* We might use b = n^2 later... */
- /* Initialze the fetch pointer */
- bitpos = (BNWORD32)1 << ((ebits-1) & (32-1)); /* Initialize mask */
- /* This should point to the msbit of e */
- assert((*e & bitpos) != 0);
- /*
- * Pre-load the window. Becuase the window size is
- * never larger than the exponent size, there is no need to
- * detect running off the end of e in here.
- *
- * The read-ahead is controlled by elen and the bitpos mask.
- * Note that this is *ahead* of ebits, which tracks the
- * most significant end of the window. The purpose of this
- * initialization is to get the two wbits+1 bits apart,
- * like they should be.
- *
- * Note that bitpos and e1len together keep track of the
- * lookahead read pointer in the exponent that is used here.
- */
- buf = 0;
- for (i = 0; i <= wbits; i++) {
- buf = (buf << 1) | ((*e & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e++,e--);
- bitpos = (BNWORD32)1 << (32-1);
- elen--;
- }
- }
- assert(buf & tblmask);
- /*
- * Set the pending multiply positions to a location that will
- * never be encountered, thus ensuring that nothing will happen
- * until the need for a multiply appears and one is scheduled.
- */
- multpos = ebits; /* A NULL value */
- mult = 0; /* Force a crash if we use these */
- /*
- * Okay, now begins the real work. The first step is
- * slightly magic, so it's done outside the main loop,
- * but it's very similar to what's inside.
- */
- ebits--; /* Start processing the first bit... */
- isone = 1;
- /*
- * This is just like the multiply in the loop, except that
- * - We know the msbit of buf is set, and
- * - We have the extra value n^2 floating around.
- * So, do the usual computation, and if the result is that
- * the buffer should be multiplied by n^1 immediately
- * (which we'd normally then square), we multiply it
- * (which reduces to a copy, which reduces to setting a flag)
- * by n^2 and skip the squaring. Thus, we do the
- * multiply and the squaring in one step.
- */
- assert(buf & tblmask);
- multpos = ebits - wbits;
- while ((buf & 1) == 0) {
- buf >>= 1;
- multpos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(multpos <= ebits);
- mult = table[buf>>1];
- buf = 0;
- /* Special case: use already-computed value sitting in buffer */
- if (multpos == ebits)
- isone = 0;
- /*
- * At this point, the buffer (which is the high half of b) holds
- * either 1 (implicitly, as the "isone" flag is set), or n^2.
- */
- /*
- * The main loop. The procedure is:
- * - Advance the window
- * - If the most-significant bit of the window is set,
- * schedule a multiply for the appropriate time in the
- * future (may be immediately)
- * - Perform any pending multiples
- * - Check for termination
- * - Square the buffer
- *
- * At any given time, the acumulated product is held in
- * the high half of b.
- */
- for (;;) {
- ebits--;
- /* Advance the window */
- assert(buf < tblmask);
- buf <<= 1;
- /*
- * This reads ahead of the current exponent position
- * (controlled by ebits), so we have to be able to read
- * past the lsb of the exponents without error.
- */
- if (elen) {
- buf |= ((*e & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e++,e--);
- bitpos = (BNWORD32)1 << (32-1);
- elen--;
- }
- }
- /* Examine the window for pending multiplies */
- if (buf & tblmask) {
- multpos = ebits - wbits;
- while ((buf & 1) == 0) {
- buf >>= 1;
- multpos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(multpos <= ebits);
- mult = table[buf>>1];
- buf = 0;
- }
- /* If we have a pending multiply, do it */
- if (ebits == multpos) {
- /* Multiply by the table entry remembered previously */
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- /* Multiply by 1 is a trivial case */
- lbnCopy_32(t, mult, mlen);
- isone = 0;
- } else {
- lbnMontMul_32(a, t, mult, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
- }
- /* Are we done? */
- if (!ebits)
- break;
- /* Square the input */
- if (!isone) {
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnMontSquare_32(a, t, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
- #if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
- #endif
- } /* for (;;) */
- assert(!isone);
- assert(!buf);
- /* DONE! */
- /* Convert result out of Montgomery form */
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnCopy_32(b, t, mlen);
- lbnZero_32(t, mlen);
- lbnMontReduce_32(b, mod, mlen, inv);
- lbnCopy_32(result, t, mlen);
- /*
- * Clean up - free intermediate storage.
- * Do NOT free table[0], which is the result
- * buffer.
- */
- y = 0;
- #if BNYIELD
- yield:
- #endif
- while (--tblmask)
- LBNFREE(table[tblmask], mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
- return y; /* Success */
- }
- /*
- * Compute and return n1^e1 * n2^e2 mod "mod".
- * result may be either input buffer, or something separate.
- * It must be "mlen" words long.
- *
- * There is a current position in the exponents, which is kept in e1bits.
- * (The exponents are swapped if necessary so e1 is the longer of the two.)
- * At any given time, the value in the accumulator is
- * n1^(e1>>e1bits) * n2^(e2>>e1bits) mod "mod".
- * As e1bits is counted down, this is updated, by squaring it and doing
- * any necessary multiplies.
- * To decide on the necessary multiplies, two windows, each w1bits+1 bits
- * wide, are maintained in buf1 and buf2, which read *ahead* of the
- * e1bits position (with appropriate handling of the case when e1bits
- * drops below w1bits+1). When the most-significant bit of either window
- * becomes set, indicating that something needs to be multiplied by
- * the accumulator or it will get out of sync, the window is examined
- * to see which power of n1 or n2 to multiply by, and when (possibly
- * later, if the power is greater than 1) the multiply should take
- * place. Then the multiply and its location are remembered and the
- * window is cleared.
- *
- * If we had every power of n1 in the table, the multiply would always
- * be w1bits steps in the future. But we only keep the odd powers,
- * so instead of waiting w1bits squarings and then multiplying
- * by n1^k, we wait w1bits-k squarings and multiply by n1.
- *
- * Actually, w2bits can be less than w1bits, but the window is the same
- * size, to make it easier to keep track of where we're reading. The
- * appropriate number of low-order bits of the window are just ignored.
- */
- int
- lbnDoubleExpMod_32(BNWORD32 *result,
- BNWORD32 const *n1, unsigned n1len,
- BNWORD32 const *e1, unsigned e1len,
- BNWORD32 const *n2, unsigned n2len,
- BNWORD32 const *e2, unsigned e2len,
- BNWORD32 *mod, unsigned mlen)
- {
- BNWORD32 *table1[1 << (BNEXPMOD_MAX_WINDOW-1)];
- /* Table of odd powers of n1 */
- BNWORD32 *table2[1 << (BNEXPMOD_MAX_WINDOW-1)];
- /* Table of odd powers of n2 */
- unsigned e1bits, e2bits; /* Exponent bits */
- unsigned w1bits, w2bits; /* Window sizes */
- unsigned tblmask; /* Mask of exponentiation window */
- BNWORD32 bitpos; /* Mask of current look-ahead bit */
- unsigned buf1, buf2; /* Buffer of exponent bits */
- unsigned mult1pos, mult2pos; /* Where to do pending multiply */
- BNWORD32 const *mult1, *mult2; /* What to multiply by */
- unsigned i; /* Loop counter */
- int isone; /* Flag: accum. is implicitly one */
- BNWORD32 *a, *b; /* Working buffers/accumulators */
- BNWORD32 *t; /* Pointer into the working buffers */
- BNWORD32 inv; /* mod^-1 modulo 2^32 */
- int y; /* bnYield() result */
- assert(mlen);
- assert(n1len <= mlen);
- assert(n2len <= mlen);
- /* First, a couple of trivial cases. */
- e1len = lbnNorm_32(e1, e1len);
- e2len = lbnNorm_32(e2, e2len);
- /* Ensure that the first exponent is the longer */
- e1bits = lbnBits_32(e1, e1len);
- e2bits = lbnBits_32(e2, e2len);
- if (e1bits < e2bits) {
- i = e1len; e1len = e2len; e2len = i;
- i = e1bits; e1bits = e2bits; e2bits = i;
- t = (BNWORD32 *)n1; n1 = n2; n2 = t;
- t = (BNWORD32 *)e1; e1 = e2; e2 = t;
- }
- assert(e1bits >= e2bits);
- /* Handle a trivial case */
- if (!e2len)
- return lbnExpMod_32(result, n1, n1len, e1, e1len, mod, mlen);
- assert(e2bits);
- /* The code below fucks up if the exponents aren't at least 2 bits */
- if (e1bits == 1) {
- assert(e2bits == 1);
- LBNALLOC(a, BNWORD32, n1len+n2len);
- if (!a)
- return -1;
- lbnMul_32(a, n1, n1len, n2, n2len);
- /* Do a direct modular reduction */
- if (n1len + n2len >= mlen)
- (void)lbnDiv_32(a+mlen, a, n1len+n2len, mod, mlen);
- lbnCopy_32(result, a, mlen);
- LBNFREE(a, n1len+n2len);
- return 0;
- }
- /* Okay, now move the exponent pointers to the most-significant word */
- e1 = BIGLITTLE(e1-e1len, e1+e1len-1);
- e2 = BIGLITTLE(e2-e2len, e2+e2len-1);
- /* Look up appropriate k-1 for the exponent - tblmask = 1<<(k-1) */
- w1bits = 0;
- while (e1bits > bnExpModThreshTable[w1bits])
- w1bits++;
- w2bits = 0;
- while (e2bits > bnExpModThreshTable[w2bits])
- w2bits++;
- assert(w1bits >= w2bits);
- /* Allocate working storage: two product buffers and the tables. */
- LBNALLOC(a, BNWORD32, 2*mlen);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD32, 2*mlen);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
- /* Convert to the appropriate table size: tblmask = 1<<(k-1) */
- tblmask = 1u << w1bits;
- /* Use buf2 for its size, temporarily */
- buf2 = 1u << w2bits;
- LBNALLOC(t, BNWORD32, mlen);
- if (!t) {
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
- return -1;
- }
- table1[0] = t;
- table2[0] = result;
- /*
- * Okay, we now have some minimal-sized tables - expand them.
- * This is allowed to fail! If so, scale back the table sizes
- * and proceed. We allocate both tables at the same time
- * so if it fails partway through, they'll both be a reasonable
- * size rather than one huge and one tiny.
- * When i passes buf2 (the number of entries in the e2 window,
- * which may be less than the number of entries in the e1 window),
- * stop allocating e2 space.
- */
- for (i = 1; i < tblmask; i++) {
- LBNALLOC(t, BNWORD32, mlen);
- if (!t) /* Out of memory! Quit the loop. */
- break;
- table1[i] = t;
- if (i < buf2) {
- LBNALLOC(t, BNWORD32, mlen);
- if (!t) {
- LBNFREE(table1[i], mlen);
- break;
- }
- table2[i] = t;
- }
- }
- /* If we stopped, with i < tblmask, shrink the tables appropriately */
- while (tblmask > i) {
- w1bits--;
- tblmask >>= 1;
- }
- /* Free up our overallocations */
- while (--i > tblmask) {
- if (i < buf2)
- LBNFREE(table2[i], mlen);
- LBNFREE(table1[i], mlen);
- }
- /* And shrink the second window too, if needed */
- if (w2bits > w1bits) {
- w2bits = w1bits;
- buf2 = tblmask;
- }
- /*
- * From now on, use the w2bits variable for the difference
- * between w1bits and w2bits.
- */
- w2bits = w1bits-w2bits;
- /* Okay, fill in the tables */
- /* Compute the necessary modular inverse */
- inv = lbnMontInv1_32(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
- /* Convert n1 to Montgomery form */
- /* Move n1 up "mlen" words into a */
- t = BIGLITTLE(a-mlen, a+mlen);
- lbnCopy_32(t, n1, n1len);
- lbnZero_32(a, mlen);
- /* Do the division - lose the quotient into the high-order words */
- (void)lbnDiv_32(t, a, mlen+n1len, mod, mlen);
- /* Copy into first table entry */
- lbnCopy_32(table1[0], a, mlen);
- /* Square a into b */
- lbnMontSquare_32(b, a, mod, mlen, inv);
- /* Use high half of b to initialize the first table */
- t = BIGLITTLE(b-mlen, b+mlen);
- for (i = 1; i < tblmask; i++) {
- lbnMontMul_32(a, t, table1[i-1], mod, mlen, inv);
- lbnCopy_32(table1[i], BIGLITTLE(a-mlen, a+mlen), mlen);
- #if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
- #endif
- }
- /* Convert n2 to Montgomery form */
- t = BIGLITTLE(a-mlen, a+mlen);
- /* Move n2 up "mlen" words into a */
- lbnCopy_32(t, n2, n2len);
- lbnZero_32(a, mlen);
- /* Do the division - lose the quotient into the high-order words */
- (void)lbnDiv_32(t, a, mlen+n2len, mod, mlen);
- /* Copy into first table entry */
- lbnCopy_32(table2[0], a, mlen);
- /* Square it into a */
- lbnMontSquare_32(a, table2[0], mod, mlen, inv);
- /* Copy to b, low half */
- lbnCopy_32(b, t, mlen);
- /* Use b to initialize the second table */
- for (i = 1; i < buf2; i++) {
- lbnMontMul_32(a, b, table2[i-1], mod, mlen, inv);
- lbnCopy_32(table2[i], t, mlen);
- #if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
- #endif
- }
- /*
- * Okay, a recap: at this point, the low part of b holds
- * n2^2, the high part holds n1^2, and the tables are
- * initialized with the odd powers of n1 and n2 from 1
- * through 2*tblmask-1 and 2*buf2-1.
- *
- * We might use those squares in b later, or we might not.
- */
- /* Initialze the fetch pointer */
- bitpos = (BNWORD32)1 << ((e1bits-1) & (32-1)); /* Initialize mask */
- /* This should point to the msbit of e1 */
- assert((*e1 & bitpos) != 0);
- /*
- * Pre-load the windows. Becuase the window size is
- * never larger than the exponent size, there is no need to
- * detect running off the end of e1 in here.
- *
- * The read-ahead is controlled by e1len and the bitpos mask.
- * Note that this is *ahead* of e1bits, which tracks the
- * most significant end of the window. The purpose of this
- * initialization is to get the two w1bits+1 bits apart,
- * like they should be.
- *
- * Note that bitpos and e1len together keep track of the
- * lookahead read pointer in the exponent that is used here.
- * e2len is not decremented, it is only ever compared with
- * e1len as *that* is decremented.
- */
- buf1 = buf2 = 0;
- for (i = 0; i <= w1bits; i++) {
- buf1 = (buf1 << 1) | ((*e1 & bitpos) != 0);
- if (e1len <= e2len)
- buf2 = (buf2 << 1) | ((*e2 & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e1++,e1--);
- if (e1len <= e2len)
- BIGLITTLE(e2++,e2--);
- bitpos = (BNWORD32)1 << (32-1);
- e1len--;
- }
- }
- assert(buf1 & tblmask);
- /*
- * Set the pending multiply positions to a location that will
- * never be encountered, thus ensuring that nothing will happen
- * until the need for a multiply appears and one is scheduled.
- */
- mult1pos = mult2pos = e1bits; /* A NULL value */
- mult1 = mult2 = 0; /* Force a crash if we use these */
- /*
- * Okay, now begins the real work. The first step is
- * slightly magic, so it's done outside the main loop,
- * but it's very similar to what's inside.
- */
- isone = 1; /* Buffer is implicitly 1, so replace * by copy */
- e1bits--; /* Start processing the first bit... */
- /*
- * This is just like the multiply in the loop, except that
- * - We know the msbit of buf1 is set, and
- * - We have the extra value n1^2 floating around.
- * So, do the usual computation, and if the result is that
- * the buffer should be multiplied by n1^1 immediately
- * (which we'd normally then square), we multiply it
- * (which reduces to a copy, which reduces to setting a flag)
- * by n1^2 and skip the squaring. Thus, we do the
- * multiply and the squaring in one step.
- */
- assert(buf1 & tblmask);
- mult1pos = e1bits - w1bits;
- while ((buf1 & 1) == 0) {
- buf1 >>= 1;
- mult1pos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(mult1pos <= e1bits);
- mult1 = table1[buf1>>1];
- buf1 = 0;
- /* Special case: use already-computed value sitting in buffer */
- if (mult1pos == e1bits)
- isone = 0;
- /*
- * The first multiply by a power of n2. Similar, but
- * we might not even want to schedule a multiply if e2 is
- * shorter than e1, and the window might be shorter so
- * we have to leave the low w2bits bits alone.
- */
- if (buf2 & tblmask) {
- /* Remember low-order bits for later */
- i = buf2 & ((1u << w2bits) - 1);
- buf2 >>= w2bits;
- mult2pos = e1bits - w1bits + w2bits;
- while ((buf2 & 1) == 0) {
- buf2 >>= 1;
- mult2pos++;
- }
- assert(mult2pos <= e1bits);
- mult2 = table2[buf2>>1];
- buf2 = i;
- if (mult2pos == e1bits) {
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- lbnCopy_32(t, b, mlen); /* Copy low to high */
- isone = 0;
- } else {
- lbnMontMul_32(a, t, b, mod, mlen, inv);
- t = a; a = b; b = t;
- }
- }
- }
- /*
- * At this point, the buffer (which is the high half of b)
- * holds either 1 (implicitly, as the "isone" flag is set),
- * n1^2, n2^2 or n1^2 * n2^2.
- */
- /*
- * The main loop. The procedure is:
- * - Advance the windows
- * - If the most-significant bit of a window is set,
- * schedule a multiply for the appropriate time in the
- * future (may be immediately)
- * - Perform any pending multiples
- * - Check for termination
- * - Square the buffers
- *
- * At any given time, the acumulated product is held in
- * the high half of b.
- */
- for (;;) {
- e1bits--;
- /* Advance the windows */
- assert(buf1 < tblmask);
- buf1 <<= 1;
- assert(buf2 < tblmask);
- buf2 <<= 1;
- /*
- * This reads ahead of the current exponent position
- * (controlled by e1bits), so we have to be able to read
- * past the lsb of the exponents without error.
- */
- if (e1len) {
- buf1 |= ((*e1 & bitpos) != 0);
- if (e1len <= e2len)
- buf2 |= ((*e2 & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e1++,e1--);
- if (e1len <= e2len)
- BIGLITTLE(e2++,e2--);
- bitpos = (BNWORD32)1 << (32-1);
- e1len--;
- }
- }
- /* Examine the first window for pending multiplies */
- if (buf1 & tblmask) {
- mult1pos = e1bits - w1bits;
- while ((buf1 & 1) == 0) {
- buf1 >>= 1;
- mult1pos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(mult1pos <= e1bits);
- mult1 = table1[buf1>>1];
- buf1 = 0;
- }
- /*
- * Examine the second window for pending multiplies.
- * Window 2 can be smaller than window 1, but we
- * keep the same number of bits in buf2, so we need
- * to ignore any low-order bits in the buffer when
- * computing what to multiply by, and recompute them
- * later.
- */
- if (buf2 & tblmask) {
- /* Remember low-order bits for later */
- i = buf2 & ((1u << w2bits) - 1);
- buf2 >>= w2bits;
- mult2pos = e1bits - w1bits + w2bits;
- while ((buf2 & 1) == 0) {
- buf2 >>= 1;
- mult2pos++;
- }
- assert(mult2pos <= e1bits);
- mult2 = table2[buf2>>1];
- buf2 = i;
- }
- /* If we have a pending multiply for e1, do it */
- if (e1bits == mult1pos) {
- /* Multiply by the table entry remembered previously */
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- /* Multiply by 1 is a trivial case */
- lbnCopy_32(t, mult1, mlen);
- isone = 0;
- } else {
- lbnMontMul_32(a, t, mult1, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
- }
- /* If we have a pending multiply for e2, do it */
- if (e1bits == mult2pos) {
- /* Multiply by the table entry remembered previously */
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- /* Multiply by 1 is a trivial case */
- lbnCopy_32(t, mult2, mlen);
- isone = 0;
- } else {
- lbnMontMul_32(a, t, mult2, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
- }
- /* Are we done? */
- if (!e1bits)
- break;
- /* Square the buffer */
- if (!isone) {
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnMontSquare_32(a, t, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
- #if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
- #endif
- } /* for (;;) */
- assert(!isone);
- assert(!buf1);
- assert(!buf2);
- /* DONE! */
- /* Convert result out of Montgomery form */
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnCopy_32(b, t, mlen);
- lbnZero_32(t, mlen);
- lbnMontReduce_32(b, mod, mlen, inv);
- lbnCopy_32(result, t, mlen);
- /* Clean up - free intermediate storage */
- y = 0;
- #if BNYIELD
- yield:
- #endif
- buf2 = tblmask >> w2bits;
- while (--tblmask) {
- if (tblmask < buf2)
- LBNFREE(table2[tblmask], mlen);
- LBNFREE(table1[tblmask], mlen);
- }
- t = table1[0];
- LBNFREE(t, mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
- return y; /* Success */
- }
- /*
- * 2^exp (mod mod). This is an optimized version for use in Fermat
- * tests. The input value of n is ignored; it is returned with
- * "mlen" words valid.
- */
- int
- lbnTwoExpMod_32(BNWORD32 *n, BNWORD32 const *exp, unsigned elen,
- BNWORD32 *mod, unsigned mlen)
- {
- unsigned e; /* Copy of high words of the exponent */
- unsigned bits; /* Assorted counter of bits */
- BNWORD32 const *bitptr;
- BNWORD32 bitword, bitpos;
- BNWORD32 *a, *b, *a1;
- BNWORD32 inv;
- int y; /* Result of bnYield() */
- assert(mlen);
- bitptr = BIGLITTLE(exp-elen, exp+elen-1);
- bitword = *bitptr;
- assert(bitword);
- /* Clear n for future use. */
- lbnZero_32(n, mlen);
- bits = lbnBits_32(exp, elen);
-
- /* First, a couple of trivial cases. */
- if (bits <= 1) {
- /* 2 ^ 0 == 1, 2 ^ 1 == 2 */
- BIGLITTLE(n[-1],n[0]) = (BNWORD32)1<<elen;
- return 0;
- }
- /* Set bitpos to the most significant bit */
- bitpos = (BNWORD32)1 << ((bits-1) & (32-1));
- /* Now, count the bits in the modulus. */
- bits = lbnBits_32(mod, mlen);
- assert(bits > 1); /* a 1-bit modulus is just stupid... */
- /*
- * We start with 1<<e, where "e" is as many high bits of the
- * exponent as we can manage without going over the modulus.
- * This first loop finds "e".
- */
- e = 1;
- while (elen) {
- /* Consume the first bit */
- bitpos >>= 1;
- if (!bitpos) {
- if (!--elen)
- break;
- bitword = BIGLITTLE(*++bitptr,*--bitptr);
- bitpos = (BNWORD32)1<<(32-1);
- }
- e = (e << 1) | ((bitpos & bitword) != 0);
- if (e >= bits) { /* Overflow! Back out. */
- e >>= 1;
- break;
- }
- }
- /*
- * The bit in "bitpos" being examined by the bit buffer has NOT
- * been consumed yet. This may be past the end of the exponent,
- * in which case elen == 1.
- */
- /* Okay, now, set bit "e" in n. n is already zero. */
- inv = (BNWORD32)1 << (e & (32-1));
- e /= 32;
- BIGLITTLE(n[-e-1],n[e]) = inv;
- /*
- * The effective length of n in words is now "e+1".
- * This is used a little bit later.
- */
- if (!elen)
- return 0; /* That was easy! */
- /*
- * We have now processed the first few bits. The next step
- * is to convert this to Montgomery form for further squaring.
- */
- /* Allocate working storage: two product buffers */
- LBNALLOC(a, BNWORD32, 2*mlen);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD32, 2*mlen);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
- /* Convert n to Montgomery form */
- inv = BIGLITTLE(mod[-1],mod[0]); /* LSW of modulus */
- assert(inv & 1); /* Modulus must be odd */
- inv = lbnMontInv1_32(inv);
- /* Move n (length e+1, remember?) up "mlen" words into b */
- /* Note that we lie about a1 for a bit - it's pointing to b */
- a1 = BIGLITTLE(b-mlen,b+mlen);
- lbnCopy_32(a1, n, e+1);
- lbnZero_32(b, mlen);
- /* Do the division - dump the quotient into the high-order words */
- (void)lbnDiv_32(a1, b, mlen+e+1, mod, mlen);
- /*
- * Now do the first squaring and modular reduction to put
- * the number up in a1 where it belongs.
- */
- lbnMontSquare_32(a, b, mod, mlen, inv);
- /* Fix up a1 to point to where it should go. */
- a1 = BIGLITTLE(a-mlen,a+mlen);
- /*
- * Okay, now, a1 holds the number being accumulated, and
- * b is a scratch register. Start working:
- */
- for (;;) {
- /*
- * Is the bit set? If so, double a1 as well.
- * A modular doubling like this is very cheap.
- */
- if (bitpos & bitword) {
- /*
- * Double the number. If there was a carry out OR
- * the result is greater than the modulus, subract
- * the modulus.
- */
- if (lbnDouble_32(a1, mlen) ||
- lbnCmp_32(a1, mod, mlen) > 0)
- (void)lbnSubN_32(a1, mod, mlen);
- }
- /* Advance to the next exponent bit */
- bitpos >>= 1;
- if (!bitpos) {
- if (!--elen)
- break; /* Done! */
- bitword = BIGLITTLE(*++bitptr,*--bitptr);
- bitpos = (BNWORD32)1<<(32-1);
- }
- /*
- * The elen/bitword/bitpos bit buffer is known to be
- * non-empty, i.e. there is at least one more unconsumed bit.
- * Thus, it's safe to square the number.
- */
- lbnMontSquare_32(b, a1, mod, mlen, inv);
- /* Rename result (in b) back to a (a1, really). */
- a1 = b; b = a; a = a1;
- a1 = BIGLITTLE(a-mlen,a+mlen);
- #if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
- #endif
- }
- /* DONE! Just a little bit of cleanup... */
- /*
- * Convert result out of Montgomery form... this is
- * just a Montgomery reduction.
- */
- lbnCopy_32(a, a1, mlen);
- lbnZero_32(a1, mlen);
- lbnMontReduce_32(a, mod, mlen, inv);
- lbnCopy_32(n, a1, mlen);
- /* Clean up - free intermediate storage */
- y = 0;
- #if BNYIELD
- yield:
- #endif
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
- return y; /* Success */
- }
- /*
- * Returns a substring of the big-endian array of bytes representation
- * of the bignum array based on two parameters, the least significant
- * byte number (0 to start with the least significant byte) and the
- * length. I.e. the number returned is a representation of
- * (bn / 2^(8*lsbyte)) % 2 ^ (8*buflen).
- *
- * It is an error if the bignum is not at least buflen + lsbyte bytes
- * long.
- *
- * This code assumes that the compiler has the minimal intelligence
- * neded to optimize divides and modulo operations on an unsigned data
- * type with a power of two.
- */
- void
- lbnExtractBigBytes_32(BNWORD32 const *n, unsigned char *buf,
- unsigned lsbyte, unsigned buflen)
- {
- BNWORD32 t = 0; /* Needed to shut up uninitialized var warnings */
- unsigned shift;
- lsbyte += buflen;
- shift = (8 * lsbyte) % 32;
- lsbyte /= (32/8); /* Convert to word offset */
- BIGLITTLE(n -= lsbyte, n += lsbyte);
- if (shift)
- t = BIGLITTLE(n[-1],n[0]);
- while (buflen--) {
- if (!shift) {
- t = BIGLITTLE(*n++,*--n);
- shift = 32;
- }
- shift -= 8;
- *buf++ = (unsigned char)(t>>shift);
- }
- }
- /*
- * Merge a big-endian array of bytes into a bignum array.
- * The array had better be big enough. This is
- * equivalent to extracting the entire bignum into a
- * large byte array, copying the input buffer into the
- * middle of it, and converting back to a bignum.
- *
- * The buf is "len" bytes long, and its *last* byte is at
- * position "lsbyte" from the end of the bignum.
- *
- * Note that this is a pain to get right. Fortunately, it's hardly
- * critical for efficiency.
- */
- void
- lbnInsertBigBytes_32(BNWORD32 *n, unsigned char const *buf,
- unsigned lsbyte, unsigned buflen)
- {
- BNWORD32 t = 0; /* Shut up uninitialized varibale warnings */
- lsbyte += buflen;
- BIGLITTLE(n -= lsbyte/(32/8), n += lsbyte/(32/8));
- /* Load up leading odd bytes */
- if (lsbyte % (32/8)) {
- t = BIGLITTLE(*--n,*n++);
- t >>= (lsbyte * 8) % 32;
- }
- /* The main loop - merge into t, storing at each word boundary. */
- while (buflen--) {
- t = (t << 8) | *buf++;
- if ((--lsbyte % (32/8)) == 0)
- BIGLITTLE(*n++,*--n) = t;
- }
- /* Merge odd bytes in t into last word */
- lsbyte = (lsbyte * 8) % 32;
- if (lsbyte) {
- t <<= lsbyte;
- t |= (((BNWORD32)1 << lsbyte) - 1) & BIGLITTLE(n[0],n[-1]);
- BIGLITTLE(n[0],n[-1]) = t;
- }
- return;
- }
- /*
- * Returns a substring of the little-endian array of bytes representation
- * of the bignum array based on two parameters, the least significant
- * byte number (0 to start with the least significant byte) and the
- * length. I.e. the number returned is a representation of
- * (bn / 2^(8*lsbyte)) % 2 ^ (8*buflen).
- *
- * It is an error if the bignum is not at least buflen + lsbyte bytes
- * long.
- *
- * This code assumes that the compiler has the minimal intelligence
- * neded to optimize divides and modulo operations on an unsigned data
- * type with a power of two.
- */
- void
- lbnExtractLittleBytes_32(BNWORD32 const *n, unsigned char *buf,
- unsigned lsbyte, unsigned buflen)
- {
- BNWORD32 t = 0; /* Needed to shut up uninitialized var warnings */
- BIGLITTLE(n -= lsbyte/(32/8), n += lsbyte/(32/8));
- if (lsbyte % (32/8)) {
- t = BIGLITTLE(*--n,*n++);
- t >>= (lsbyte % (32/8)) * 8 ;
- }
- while (buflen--) {
- if ((lsbyte++ % (32/8)) == 0)
- t = BIGLITTLE(*--n,*n++);
- *buf++ = (unsigned char)t;
- t >>= 8;
- }
- }
- /*
- * Merge a little-endian array of bytes into a bignum array.
- * The array had better be big enough. This is
- * equivalent to extracting the entire bignum into a
- * large byte array, copying the input buffer into the
- * middle of it, and converting back to a bignum.
- *
- * The buf is "len" bytes long, and its first byte is at
- * position "lsbyte" from the end of the bignum.
- *
- * Note that this is a pain to get right. Fortunately, it's hardly
- * critical for efficiency.
- */
- void
- lbnInsertLittleBytes_32(BNWORD32 *n, unsigned char const *buf,
- unsigned lsbyte, unsigned buflen)
- {
- BNWORD32 t = 0; /* Shut up uninitialized varibale warnings */
- /* Move to most-significant end */
- lsbyte += buflen;
- buf += buflen;
- BIGLITTLE(n -= lsbyte/(32/8), n += lsbyte/(32/8));
- /* Load up leading odd bytes */
- if (lsbyte % (32/8)) {
- t = BIGLITTLE(*--n,*n++);
- t >>= (lsbyte * 8) % 32;
- }
- /* The main loop - merge into t, storing at each word boundary. */
- while (buflen--) {
- t = (t << 8) | *--buf;
- if ((--lsbyte % (32/8)) == 0)
- BIGLITTLE(*n++,*--n) = t;
- }
- /* Merge odd bytes in t into last word */
- lsbyte = (lsbyte * 8) % 32;
- if (lsbyte) {
- t <<= lsbyte;
- t |= (((BNWORD32)1 << lsbyte) - 1) & BIGLITTLE(n[0],n[-1]);
- BIGLITTLE(n[0],n[-1]) = t;
- }
- return;
- }
- #ifdef DEADCODE /* This was a precursor to the more flexible lbnExtractBytes */
- /*
- * Convert a big-endian array of bytes to a bignum.
- * Returns the number of words in the bignum.
- * Note the expression "32/8" for the number of bytes per word.
- * This is so the word-size adjustment will work.
- */
- unsigned
- lbnFromBytes_32(BNWORD32 *a, unsigned char const *b, unsigned blen)
- {
- BNWORD32 t;
- unsigned alen = (blen + (32/8-1))/(32/8);
- BIGLITTLE(a -= alen, a += alen);
- while (blen) {
- t = 0;
- do {
- t = t << 8 | *b++;
- } while (--blen & (32/8-1));
- BIGLITTLE(*a++,*--a) = t;
- }
- return alen;
- }
- #endif
- /*
- * Computes the GCD of a and b. Modifies both arguments; when it returns,
- * one of them is the GCD and the other is trash. The return value
- * indicates which: 0 for a, and 1 for b. The length of the retult is
- * returned in rlen. Both inputs must have one extra word of precision.
- * alen must be >= blen.
- *
- * TODO: use the binary algorithm (Knuth section 4.5.2, algorithm B).
- * This is based on taking out common powers of 2, then repeatedly:
- * gcd(2*u,v) = gcd(u,2*v) = gcd(u,v) - isolated powers of 2 can be deleted.
- * gcd(u,v) = gcd(u-v,v) - the numbers can be easily reduced.
- * It gets less reduction per step, but the steps are much faster than
- * the division case.
- */
- int
- lbnGcd_32(BNWORD32 *a, unsigned alen, BNWORD32 *b, unsigned blen,
- unsigned *rlen)
- {
- #if BNYIELD
- int y;
- #endif
- assert(alen >= blen);
- while (blen != 0) {
- (void)lbnDiv_32(BIGLITTLE(a-blen,a+blen), a, alen, b, blen);
- alen = lbnNorm_32(a, blen);
- if (alen == 0) {
- *rlen = blen;
- return 1;
- }
- (void)lbnDiv_32(BIGLITTLE(b-alen,b+alen), b, blen, a, alen);
- blen = lbnNorm_32(b, alen);
- #if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- return y;
- #endif
- }
- *rlen = alen;
- return 0;
- }
- /*
- * Invert "a" modulo "mod" using the extended Euclidean algorithm.
- * Note that this only computes one of the cosequences, and uses the
- * theorem that the signs flip every step and the absolute value of
- * the cosequence values are always bounded by the modulus to avoid
- * having to work with negative numbers.
- * gcd(a,mod) had better equal 1. Returns 1 if the GCD is NOT 1.
- * a must be one word longer than "mod". It is overwritten with the
- * result.
- * TODO: Use Richard Schroeppel's *much* faster algorithm.
- */
- int
- lbnInv_32(BNWORD32 *a, unsigned alen, BNWORD32 const *mod, unsigned mlen)
- {
- BNWORD32 *b; /* Hold a copy of mod during GCD reduction */
- BNWORD32 *p; /* Temporary for products added to t0 and t1 */
- BNWORD32 *t0, *t1; /* Inverse accumulators */
- BNWORD32 cy;
- unsigned blen, t0len, t1len, plen;
- int y;
- alen = lbnNorm_32(a, alen);
- if (!alen)
- return 1; /* No inverse */
- mlen = lbnNorm_32(mod, mlen);
- assert (alen <= mlen);
- /* Inverse of 1 is 1 */
- if (alen == 1 && BIGLITTLE(a[-1],a[0]) == 1) {
- lbnZero_32(BIGLITTLE(a-alen,a+alen), mlen-alen);
- return 0;
- }
- /* Allocate a pile of space */
- LBNALLOC(b, BNWORD32, mlen+1);
- if (b) {
- /*
- * Although products are guaranteed to always be less than the
- * modulus, it can involve multiplying two 3-word numbers to
- * get a 5-word result, requiring a 6th word to store a 0
- * temporarily. Thus, mlen + 1.
- */
- LBNALLOC(p, BNWORD32, mlen+1);
- if (p) {
- LBNALLOC(t0, BNWORD32, mlen);
- if (t0) {
- LBNALLOC(t1, BNWORD32, mlen);
- if (t1)
- goto allocated;
- LBNFREE(t0, mlen);
- }
- LBNFREE(p, mlen+1);
- }
- LBNFREE(b, mlen+1);
- }
- return -1;
- allocated:
- /* Set t0 to 1 */
- t0len = 1;
- BIGLITTLE(t0[-1],t0[0]) = 1;
-
- /* b = mod */
- lbnCopy_32(b, mod, mlen);
- /* blen = mlen (implicitly) */
-
- /* t1 = b / a; b = b % a */
- cy = lbnDiv_32(t1, b, mlen, a, alen);
- *(BIGLITTLE(t1-(mlen-alen)-1,t1+(mlen-alen))) = cy;
- t1len = lbnNorm_32(t1, mlen-alen+1);
- blen = lbnNorm_32(b, alen);
- /* while (b > 1) */
- while (blen > 1 || BIGLITTLE(b[-1],b[0]) != (BNWORD32)1) {
- /* q = a / b; a = a % b; */
- if (alen < blen || (alen == blen && lbnCmp_32(a, a, alen) < 0))
- assert(0);
- cy = lbnDiv_32(BIGLITTLE(a-blen,a+blen), a, alen, b, blen);
- *(BIGLITTLE(a-alen-1,a+alen)) = cy;
- plen = lbnNorm_32(BIGLITTLE(a-blen,a+blen), alen-blen+1);
- assert(plen);
- alen = lbnNorm_32(a, blen);
- if (!alen)
- goto failure; /* GCD not 1 */
- /* t0 += q * t1; */
- assert(plen+t1len <= mlen+1);
- lbnMul_32(p, BIGLITTLE(a-blen,a+blen), plen, t1, t1len);
- plen = lbnNorm_32(p, plen + t1len);
- assert(plen <= mlen);
- if (plen > t0len) {
- lbnZero_32(BIGLITTLE(t0-t0len,t0+t0len), plen-t0len);
- t0len = plen;
- }
- cy = lbnAddN_32(t0, p, plen);
- if (cy) {
- if (t0len > plen) {
- cy = lbnAdd1_32(BIGLITTLE(t0-plen,t0+plen),
- t0len-plen, cy);
- }
- if (cy) {
- BIGLITTLE(t0[-t0len-1],t0[t0len]) = cy;
- t0len++;
- }
- }
- /* if (a <= 1) return a ? t0 : FAIL; */
- if (alen <= 1 && BIGLITTLE(a[-1],a[0]) == (BNWORD32)1) {
- if (alen == 0)
- goto failure; /* FAIL */
- assert(t0len <= mlen);
- lbnCopy_32(a, t0, t0len);
- lbnZero_32(BIGLITTLE(a-t0len, a+t0len), mlen-t0len);
- goto success;
- }
- /* q = b / a; b = b % a; */
- if (blen < alen || (blen == alen && lbnCmp_32(b, a, alen) < 0))
- assert(0);
- cy = lbnDiv_32(BIGLITTLE(b-alen,b+alen), b, blen, a, alen);
- *(BIGLITTLE(b-blen-1,b+blen)) = cy;
- plen = lbnNorm_32(BIGLITTLE(b-alen,b+alen), blen-alen+1);
- assert(plen);
- blen = lbnNorm_32(b, alen);
- if (!blen)
- goto failure; /* GCD not 1 */
- /* t1 += q * t0; */
- assert(plen+t0len <= mlen+1);
- lbnMul_32(p, BIGLITTLE(b-alen,b+alen), plen, t0, t0len);
- plen = lbnNorm_32(p, plen + t0len);
- assert(plen <= mlen);
- if (plen > t1len) {
- lbnZero_32(BIGLITTLE(t1-t1len,t1+t1len), plen-t1len);
- t1len = plen;
- }
- cy = lbnAddN_32(t1, p, plen);
- if (cy) {
- if (t1len > plen) {
- cy = lbnAdd1_32(BIGLITTLE(t1-plen,t0+plen),
- t1len-plen, cy);
- }
- if (cy) {
- BIGLITTLE(t1[-t1len-1],t1[t1len]) = cy;
- t1len++;
- }
- }
- #if BNYIELD
- if (bnYield && (y = bnYield() < 0))
- goto yield;
- #endif
- }
- if (!blen)
- goto failure; /* gcd(a, mod) != 1 -- FAIL */
- /* return mod-t1 */
- lbnCopy_32(a, mod, mlen);
- assert(t1len <= mlen);
- cy = lbnSubN_32(a, t1, t1len);
- if (cy) {
- assert(mlen > t1len);
- cy = lbnSub1_32(BIGLITTLE(a-t1len, a+t1len), mlen-t1len, cy);
- assert(!cy);
- }
- success:
- LBNFREE(t1, mlen);
- LBNFREE(t0, mlen);
- LBNFREE(p, mlen+1);
- LBNFREE(b, mlen+1);
-
- return 0;
- failure: /* GCD is not 1 - no inverse exists! */
- y = 1;
- #if BNYIELD
- yield:
- #endif
- LBNFREE(t1, mlen);
- LBNFREE(t0, mlen);
- LBNFREE(p, mlen+1);
- LBNFREE(b, mlen+1);
-
- return y;
- }
- /*
- * Precompute powers of "a" mod "mod". Compute them every "bits"
- * for "n" steps. This is sufficient to compute powers of g with
- * exponents up to n*bits bits long, i.e. less than 2^(n*bits).
- *
- * This assumes that the caller has already initialized "array" to point
- * to "n" buffers of size "mlen".
- */
- int
- lbnBasePrecompBegin_32(BNWORD32 **array, unsigned n, unsigned bits,
- BNWORD32 const *g, unsigned glen, BNWORD32 *mod, unsigned mlen)
- {
- BNWORD32 *a, *b; /* Temporary double-width accumulators */
- BNWORD32 *a1; /* Pointer to high half of a*/
- BNWORD32 inv; /* Montgomery inverse of LSW of mod */
- BNWORD32 *t;
- unsigned i;
- glen = lbnNorm_32(g, glen);
- assert(glen);
- assert (mlen == lbnNorm_32(mod, mlen));
- assert (glen <= mlen);
- /* Allocate two temporary buffers, and the array slots */
- LBNALLOC(a, BNWORD32, mlen*2);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD32, mlen*2);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
- /* Okay, all ready */
- /* Convert n to Montgomery form */
- inv = BIGLITTLE(mod[-1],mod[0]); /* LSW of modulus */
- assert(inv & 1); /* Modulus must be odd */
- inv = lbnMontInv1_32(inv);
- /* Move g up "mlen" words into a (clearing the low mlen words) */
- a1 = BIGLITTLE(a-mlen,a+mlen);
- lbnCopy_32(a1, g, glen);
- lbnZero_32(a, mlen);
- /* Do the division - dump the quotient into the high-order words */
- (void)lbnDiv_32(a1, a, mlen+glen, mod, mlen);
- /* Copy the first value into the array */
- t = *array;
- lbnCopy_32(t, a, mlen);
- a1 = a; /* This first value is *not* shifted up */
-
- /* Now compute the remaining n-1 array entries */
- assert(bits);
- assert(n);
- while (--n) {
- i = bits;
- do {
- /* Square a1 into b1 */
- lbnMontSquare_32(b, a1, mod, mlen, inv);
- t = b; b = a; a = t;
- a1 = BIGLITTLE(a-mlen, a+mlen);
- } while (--i);
- t = *++array;
- lbnCopy_32(t, a1, mlen);
- }
- /* Hooray, we're done. */
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
- return 0;
- }
- /*
- * result = base^exp (mod mod). "array" is a an array of pointers
- * to procomputed powers of base, each 2^bits apart. (I.e. array[i]
- * is base^(2^(i*bits))).
- *
- * The algorithm consists of:
- * a = b = (powers of g to be raised to the power 2^bits-1)
- * a *= b *= (powers of g to be raised to the power 2^bits-2)
- * ...
- * a *= b *= (powers of g to be raised to the power 1)
- *
- * All we do is walk the exponent 2^bits-1 times in groups of "bits" bits,
- */
- int
- lbnBasePrecompExp_32(BNWORD32 *result, BNWORD32 const * const *array,
- unsigned bits, BNWORD32 const *exp, unsigned elen,
- BNWORD32 const *mod, unsigned mlen)
- {
- BNWORD32 *a, *b, *c, *t;
- BNWORD32 *a1, *b1;
- int anull, bnull; /* Null flags: values are implicitly 1 */
- unsigned i, j; /* Loop counters */
- unsigned mask; /* Exponent bits to examime */
- BNWORD32 const *eptr; /* Pointer into exp */
- BNWORD32 buf, curbits, nextword; /* Bit-buffer varaibles */
- BNWORD32 inv; /* Inverse of LSW of modulus */
- unsigned ewords; /* Words of exponent left */
- int bufbits; /* Number of valid bits */
- int y = 0;
- mlen = lbnNorm_32(mod, mlen);
- assert (mlen);
- elen = lbnNorm_32(exp, elen);
- if (!elen) {
- lbnZero_32(result, mlen);
- BIGLITTLE(result[-1],result[0]) = 1;
- return 0;
- }
- /*
- * This could be precomputed, but it's so cheap, and it would require
- * making the precomputation structure word-size dependent.
- */
- inv = lbnMontInv1_32(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
- assert(elen);
- /*
- * Allocate three temporary buffers. The current numbers generally
- * live in the upper halves of these buffers.
- */
- LBNALLOC(a, BNWORD32, mlen*2);
- if (a) {
- LBNALLOC(b, BNWORD32, mlen*2);
- if (b) {
- LBNALLOC(c, BNWORD32, mlen*2);
- if (c)
- goto allocated;
- LBNFREE(b, 2*mlen);
- }
- LBNFREE(a, 2*mlen);
- }
- return -1;
- allocated:
- anull = bnull = 1;
- mask = (1u<<bits) - 1;
- for (i = mask; i; --i) {
- /* Set up bit buffer for walking the exponent */
- eptr = exp;
- buf = BIGLITTLE(*--eptr, *eptr++);
- ewords = elen-1;
- bufbits = 32;
- for (j = 0; ewords || buf; j++) {
- /* Shift down current buffer */
- curbits = buf;
- buf >>= bits;
- /* If necessary, add next word */
- bufbits -= bits;
- if (bufbits < 0 && ewords > 0) {
- nextword = BIGLITTLE(*--eptr, *eptr++);
- ewords--;
- curbits |= nextword << (bufbits+bits);
- buf = nextword >> -bufbits;
- bufbits += 32;
- }
- /* If appropriate, multiply b *= array[j] */
- if ((curbits & mask) == i) {
- BNWORD32 const *d = array[j];
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (bnull) {
- lbnCopy_32(b1, d, mlen);
- bnull = 0;
- } else {
- lbnMontMul_32(c, b1, d, mod, mlen, inv);
- t = c; c = b; b = t;
- }
- #if BNYIELD
- if (bnYield && (y = bnYield() < 0))
- goto yield;
- #endif
- }
- }
- /* Multiply a *= b */
- if (!bnull) {
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (anull) {
- lbnCopy_32(a1, b1, mlen);
- anull = 0;
- } else {
- lbnMontMul_32(c, a1, b1, mod, mlen, inv);
- t = c; c = a; a = t;
- }
- }
- }
- assert(!anull); /* If it were, elen would have been 0 */
- /* Convert out of Montgomery form and return */
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- lbnCopy_32(a, a1, mlen);
- lbnZero_32(a1, mlen);
- lbnMontReduce_32(a, mod, mlen, inv);
- lbnCopy_32(result, a1, mlen);
- #if BNYIELD
- yield:
- #endif
- LBNFREE(c, 2*mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
- return y;
- }
- /*
- * result = base1^exp1 *base2^exp2 (mod mod). "array1" and "array2" are
- * arrays of pointers to procomputed powers of the corresponding bases,
- * each 2^bits apart. (I.e. array1[i] is base1^(2^(i*bits))).
- *
- * Bits must be the same in both. (It could be made adjustable, but it's
- * a bit of a pain. Just make them both equal to the larger one.)
- *
- * The algorithm consists of:
- * a = b = (powers of base1 and base2 to be raised to the power 2^bits-1)
- * a *= b *= (powers of base1 and base2 to be raised to the power 2^bits-2)
- * ...
- * a *= b *= (powers of base1 and base2 to be raised to the power 1)
- *
- * All we do is walk the exponent 2^bits-1 times in groups of "bits" bits,
- */
- int
- lbnDoubleBasePrecompExp_32(BNWORD32 *result, unsigned bits,
- BNWORD32 const * const *array1, BNWORD32 const *exp1, unsigned elen1,
- BNWORD32 const * const *array2, BNWORD32 const *exp2,
- unsigned elen2, BNWORD32 const *mod, unsigned mlen)
- {
- BNWORD32 *a, *b, *c, *t;
- BNWORD32 *a1, *b1;
- int anull, bnull; /* Null flags: values are implicitly 1 */
- unsigned i, j, k; /* Loop counters */
- unsigned mask; /* Exponent bits to examime */
- BNWORD32 const *eptr; /* Pointer into exp */
- BNWORD32 buf, curbits, nextword; /* Bit-buffer varaibles */
- BNWORD32 inv; /* Inverse of LSW of modulus */
- unsigned ewords; /* Words of exponent left */
- int bufbits; /* Number of valid bits */
- int y = 0;
- BNWORD32 const * const *array;
- mlen = lbnNorm_32(mod, mlen);
- assert (mlen);
- elen1 = lbnNorm_32(exp1, elen1);
- if (!elen1) {
- return lbnBasePrecompExp_32(result, array2, bits, exp2, elen2,
- mod, mlen);
- }
- elen2 = lbnNorm_32(exp2, elen2);
- if (!elen2) {
- return lbnBasePrecompExp_32(result, array1, bits, exp1, elen1,
- mod, mlen);
- }
- /*
- * This could be precomputed, but it's so cheap, and it would require
- * making the precomputation structure word-size dependent.
- */
- inv = lbnMontInv1_32(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
- assert(elen1);
- assert(elen2);
- /*
- * Allocate three temporary buffers. The current numbers generally
- * live in the upper halves of these buffers.
- */
- LBNALLOC(a, BNWORD32, mlen*2);
- if (a) {
- LBNALLOC(b, BNWORD32, mlen*2);
- if (b) {
- LBNALLOC(c, BNWORD32, mlen*2);
- if (c)
- goto allocated;
- LBNFREE(b, 2*mlen);
- }
- LBNFREE(a, 2*mlen);
- }
- return -1;
- allocated:
- anull = bnull = 1;
- mask = (1u<<bits) - 1;
- for (i = mask; i; --i) {
- /* Walk each exponent in turn */
- for (k = 0; k < 2; k++) {
- /* Set up the exponent for walking */
- array = k ? array2 : array1;
- eptr = k ? exp2 : exp1;
- ewords = (k ? elen2 : elen1) - 1;
- /* Set up bit buffer for walking the exponent */
- buf = BIGLITTLE(*--eptr, *eptr++);
- bufbits = 32;
- for (j = 0; ewords || buf; j++) {
- /* Shift down current buffer */
- curbits = buf;
- buf >>= bits;
- /* If necessary, add next word */
- bufbits -= bits;
- if (bufbits < 0 && ewords > 0) {
- nextword = BIGLITTLE(*--eptr, *eptr++);
- ewords--;
- curbits |= nextword << (bufbits+bits);
- buf = nextword >> -bufbits;
- bufbits += 32;
- }
- /* If appropriate, multiply b *= array[j] */
- if ((curbits & mask) == i) {
- BNWORD32 const *d = array[j];
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (bnull) {
- lbnCopy_32(b1, d, mlen);
- bnull = 0;
- } else {
- lbnMontMul_32(c, b1, d, mod, mlen, inv);
- t = c; c = b; b = t;
- }
- #if BNYIELD
- if (bnYield && (y = bnYield() < 0))
- goto yield;
- #endif
- }
- }
- }
- /* Multiply a *= b */
- if (!bnull) {
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (anull) {
- lbnCopy_32(a1, b1, mlen);
- anull = 0;
- } else {
- lbnMontMul_32(c, a1, b1, mod, mlen, inv);
- t = c; c = a; a = t;
- }
- }
- }
- assert(!anull); /* If it were, elen would have been 0 */
- /* Convert out of Montgomery form and return */
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- lbnCopy_32(a, a1, mlen);
- lbnZero_32(a1, mlen);
- lbnMontReduce_32(a, mod, mlen, inv);
- lbnCopy_32(result, a1, mlen);
- #if BNYIELD
- yield:
- #endif
- LBNFREE(c, 2*mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
- return y;
- }
|