Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

beecrypt/mp32.c

Go to the documentation of this file.
00001 
00007 /*
00008  * Copyright (c) 1997, 1998, 1999, 2000 Virtual Unlimited B.V.
00009  *
00010  * Author: Bob Deblier <bob@virtualunlimited.com>
00011  *
00012  * This library is free software; you can redistribute it and/or
00013  * modify it under the terms of the GNU Lesser General Public
00014  * License as published by the Free Software Foundation; either
00015  * version 2.1 of the License, or (at your option) any later version.
00016  *
00017  * This library is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  * Lesser General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU Lesser General Public
00023  * License along with this library; if not, write to the Free Software
00024  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025  *
00026  */
00027 
00028 #include "system.h"
00029 #include "beecrypt.h"
00030 #include "mp32opt.h"
00031 #include "mp32.h"
00032 #include "debug.h"
00033 
00034 #ifndef ASM_MP32ZERO
00035 /*@-boundswrite@*/
00036 void mp32zero(register uint32 xsize, register uint32* xdata)
00037 {
00038         while (xsize--)
00039                 *(xdata++) = 0;
00040 }
00041 /*@=boundswrite@*/
00042 #endif
00043 
00044 #ifndef ASM_MP32FILL
00045 /*@-boundswrite@*/
00046 void mp32fill(register uint32 xsize, register uint32* xdata, register uint32 val)
00047 {
00048         while (xsize--)
00049                 *(xdata++) = val;
00050 }
00051 /*@=boundswrite@*/
00052 #endif
00053 
00054 #ifndef ASM_MP32ODD
00055 /*@-boundsread@*/
00056 int mp32odd(register uint32 xsize, register const uint32* xdata)
00057 {
00058         return (xdata[xsize-1] & 0x1);
00059 }
00060 /*@=boundsread@*/
00061 #endif
00062 
00063 #ifndef ASM_MP32EVEN
00064 /*@-boundsread@*/
00065 int mp32even(register uint32 xsize, register const uint32* xdata)
00066 {
00067         return !(xdata[xsize-1] & 0x1);
00068 }
00069 /*@=boundsread@*/
00070 #endif
00071 
00072 #ifndef ASM_MP32Z
00073 /*@-boundsread@*/
00074 int mp32z(register uint32 xsize, register const uint32* xdata)
00075 {
00076         while (xsize--)
00077                 if (*(xdata++))
00078                         return 0;
00079         return 1;
00080 }
00081 /*@=boundsread@*/
00082 #endif
00083 
00084 #ifndef ASM_MP32NZ
00085 /*@-boundsread@*/
00086 int mp32nz(register uint32 xsize, register const uint32* xdata)
00087 {
00088         while (xsize--)
00089                 if (*(xdata++))
00090                         return 1;
00091         return 0;
00092 }
00093 /*@=boundsread@*/
00094 #endif
00095 
00096 #ifndef ASM_MP32EQ
00097 /*@-boundsread@*/
00098 int mp32eq(register uint32 size, register const uint32* xdata, register const uint32* ydata)
00099 {
00100         while (size--)
00101         {
00102                 if (*xdata == *ydata)
00103                 {
00104                         xdata++;
00105                         ydata++;
00106                 }
00107                 else
00108                         return 0;
00109         }
00110 
00111         return 1;
00112 }
00113 /*@=boundsread@*/
00114 #endif
00115 
00116 #ifndef ASM_MP32EQX
00117 int mp32eqx(register uint32 xsize, register const uint32* xdata, register uint32 ysize, register const uint32* ydata)
00118 {
00119         if (xsize > ysize)
00120         {
00121                 register int diff = xsize - ysize;
00122                 return mp32eq(ysize, xdata + diff, ydata) && mp32z(diff, xdata);
00123         }
00124         else if (xsize < ysize)
00125         {
00126                 register int diff = ysize - xsize;
00127                 return mp32eq(xsize, ydata + diff, xdata) && mp32z(diff, ydata);
00128         }
00129         else
00130                 return mp32eq(xsize, xdata, ydata);
00131 }
00132 #endif
00133 
00134 #ifndef ASM_MP32NE
00135 /*@-boundsread@*/
00136 int mp32ne(register uint32 size, register const uint32* xdata, register const uint32* ydata)
00137 {
00138         while (size--)
00139         {
00140                 if (*xdata == *ydata)
00141                 {
00142                         xdata++;
00143                         ydata++;
00144                 }
00145                 else
00146                         return 1;
00147         }
00148 
00149         return 0;
00150 }
00151 /*@=boundsread@*/
00152 #endif
00153 
00154 #ifndef ASM_MP32NEX
00155 int mp32nex(register uint32 xsize, register const uint32* xdata, register uint32 ysize, register const uint32*ydata)
00156 {
00157         if (xsize > ysize)
00158         {
00159                 register int diff = xsize - ysize;
00160                 return mp32nz(diff, xdata) || mp32ne(ysize, xdata + diff, ydata);
00161         }
00162         else if (xsize < ysize)
00163         {
00164                 register int diff = ysize - xsize;
00165                 return mp32nz(diff, ydata) || mp32ne(xsize, ydata + diff, xdata);
00166         }
00167         else
00168                 return mp32ne(xsize, xdata, ydata);
00169 }
00170 #endif
00171 
00172 #ifndef ASM_MP32GT
00173 /*@-boundsread@*/
00174 int mp32gt(register uint32 size, register const uint32* xdata, register const uint32* ydata)
00175 {
00176         while (size--)
00177         {
00178                 if (*xdata < *ydata)
00179                         return 0;
00180                 if (*xdata > *ydata)
00181                         return 1;
00182                 xdata++; ydata++;
00183         }
00184         return 0;
00185 }
00186 /*@=boundsread@*/
00187 #endif
00188 
00189 #ifndef ASM_MP32GTX
00190 int mp32gtx(register uint32 xsize, register const uint32* xdata, register uint32 ysize, register const uint32* ydata)
00191 {
00192         if (xsize > ysize)
00193         {
00194                 register uint32 diff = xsize - ysize;
00195                 return mp32nz(diff, xdata) || mp32gt(ysize, xdata + diff, ydata);
00196         }
00197         else if (xsize < ysize)
00198         {
00199                 register uint32 diff = ysize - xsize;
00200                 return mp32z(diff, ydata) && mp32gt(xsize, xdata, ydata + diff);
00201         }
00202         else
00203                 return mp32gt(xsize, xdata, ydata);
00204 }
00205 #endif
00206 
00207 #ifndef ASM_MP32LT
00208 /*@-boundsread@*/
00209 int mp32lt(register uint32 size, register const uint32* xdata, register const uint32* ydata)
00210 {
00211         while (size--)
00212         {
00213                 if (*xdata > *ydata)
00214                         return 0;
00215                 if (*xdata < *ydata)
00216                         return 1;
00217                 xdata++; ydata++;
00218         }
00219         return 0;
00220 }
00221 /*@=boundsread@*/
00222 #endif
00223 
00224 #ifndef ASM_MP32LTX
00225 int mp32ltx(register uint32 xsize, register const uint32* xdata, register uint32 ysize, register const uint32* ydata)
00226 {
00227         if (xsize > ysize)
00228         {
00229                 register uint32 diff = xsize - ysize;
00230                 return mp32z(diff, xdata) && mp32lt(ysize, xdata + diff, ydata);
00231         }
00232         else if (xsize < ysize)
00233         {
00234                 register uint32 diff = ysize - xsize;
00235                 return mp32nz(diff, ydata) || mp32lt(xsize, xdata, ydata + diff);
00236         }
00237         else
00238                 return mp32lt(xsize, xdata, ydata);
00239 }
00240 #endif
00241 
00242 #ifndef ASM_MP32GE
00243 /*@-boundsread@*/
00244 int mp32ge(register uint32 size, register const uint32* xdata, register const uint32* ydata)
00245 {
00246         while (size--)
00247         {
00248                 if (*xdata < *ydata)
00249                         return 0;
00250                 if (*xdata > *ydata)
00251                         return 1;
00252                 xdata++; ydata++;
00253         }
00254         return 1;
00255 }
00256 /*@=boundsread@*/
00257 #endif
00258 
00259 #ifndef ASM_MP32GEX
00260 /*@-boundsread@*/
00261 int mp32gex(register uint32 xsize, register const uint32* xdata, register uint32 ysize, register const uint32* ydata)
00262 {
00263         if (xsize > ysize)
00264         {
00265                 register uint32 diff = xsize - ysize;
00266                 return mp32nz(diff, xdata) || mp32ge(ysize, xdata + diff, ydata);
00267         }
00268         else if (xsize < ysize)
00269         {
00270                 register uint32 diff = ysize - xsize;
00271                 return mp32z(diff, ydata) && mp32ge(xsize, xdata, ydata + diff);
00272         }
00273         else
00274                 return mp32ge(xsize, xdata, ydata);
00275 }
00276 /*@=boundsread@*/
00277 #endif
00278 
00279 #ifndef ASM_MP32LE
00280 /*@-boundsread@*/
00281 int mp32le(register uint32 size, register const uint32* xdata, register const uint32* ydata)
00282 {
00283         while (size--)
00284         {
00285                 if (*xdata < *ydata)
00286                         return 1;
00287                 if (*xdata > *ydata)
00288                         return 0;
00289                 xdata++; ydata++;
00290         }
00291         return 1;
00292 }
00293 /*@=boundsread@*/
00294 #endif
00295 
00296 #ifndef ASM_MP32LEX
00297 /*@-boundsread@*/
00298 int mp32lex(register uint32 xsize, register const uint32* xdata, register uint32 ysize, register const uint32* ydata)
00299 {
00300         if (xsize > ysize)
00301         {
00302                 register uint32 diff = xsize - ysize;
00303                 return mp32z(diff, xdata) && mp32le(ysize, xdata + diff, ydata);
00304         }
00305         else if (xsize < ysize)
00306         {
00307                 register uint32 diff = ysize - xsize;
00308                 return mp32nz(diff, ydata) || mp32le(xsize, xdata, ydata + diff);
00309         }
00310         else
00311                 return mp32le(xsize, xdata, ydata);
00312 }
00313 /*@=boundsread@*/
00314 #endif
00315 
00316 
00317 #ifndef ASM_MP32ISONE
00318 /*@-boundsread@*/
00319 int mp32isone(register uint32 xsize, register const uint32* xdata)
00320 {
00321         xdata += xsize;
00322         if (*(--xdata) == 1)
00323         {
00324                 while (--xsize)
00325                         if (*(--xdata))
00326                                 return 0;
00327                 return 1;
00328         }
00329         return 0;
00330 }
00331 /*@=boundsread@*/
00332 #endif
00333 
00334 #ifndef ASM_MP32ISTWO
00335 /*@-boundsread@*/
00336 int mp32istwo(register uint32 xsize, register const uint32* xdata)
00337 {
00338         xdata += xsize;
00339         if (*(--xdata) == 2)
00340         {
00341                 while (--xsize)
00342                         if (*(--xdata))
00343                                 return 0;
00344                 return 1;
00345         }
00346         return 0;
00347 }
00348 /*@=boundsread@*/
00349 #endif
00350 
00351 #ifndef ASM_MP32EQMONE
00352 /*@-boundsread@*/
00353 int mp32eqmone(register uint32 size, register const uint32* xdata, register const uint32* ydata)
00354 {
00355     xdata += size;
00356     ydata += size;
00357 
00358     if (*(--xdata)+1 == *(--ydata))
00359     {
00360         while (--size)
00361             if (*(--xdata) != *(--ydata))
00362                 return 0;
00363         return 1;
00364     }
00365     return 0;
00366 }
00367 /*@=boundsread@*/
00368 #endif
00369 
00370 #ifndef ASM_MP32LEONE
00371 /*@-boundsread@*/
00372 int mp32leone(register uint32 xsize, register const uint32* xdata)
00373 {
00374         xdata += xsize;
00375         if (*(--xdata) > 1)
00376                 return 0;
00377         else
00378         {
00379                 while (--xsize)
00380                         if (*(--xdata))
00381                                 return 0;
00382                 return 1;
00383         }
00384 }
00385 /*@=boundsread@*/
00386 #endif
00387 
00388 #ifndef ASM_MP32MSBSET
00389 int mp32msbset(/*@unused@*/ register uint32 xsize, register const uint32* xdata)
00390 {
00391 /*@-boundsread@*/
00392         return ((*xdata) & 0x80000000);
00393 /*@=boundsread@*/
00394 }
00395 #endif
00396 
00397 #ifndef ASM_MP32LSBSET
00398 int mp32lsbset(register uint32 xsize, register const uint32* xdata)
00399 {
00400 /*@-boundsread@*/
00401     return xdata[xsize-1] & 0x1;
00402 /*@=boundsread@*/
00403 }
00404 #endif
00405 
00406 #ifndef ASM_MP32SETMSB
00407 void mp32setmsb(/*@unused@*/ register uint32 xsize, register uint32* xdata)
00408 {
00409 /*@-boundsread@*/
00410         *xdata |= 0x80000000;
00411 /*@=boundsread@*/
00412 }
00413 #endif
00414 
00415 #ifndef ASM_MP32SETLSB
00416 void mp32setlsb(register uint32 xsize, register uint32* xdata)
00417 {
00418 /*@-boundsread@*/
00419         xdata[xsize-1] |= 0x00000001;
00420 /*@=boundsread@*/
00421 }
00422 #endif
00423 
00424 #ifndef ASM_MP32CLRMSB
00425 void mp32clrmsb(/*@unused@*/ register uint32 xsize, register uint32* xdata)
00426 {
00427 /*@-boundsread@*/
00428         *xdata &= 0x7fffffff;
00429 /*@=boundsread@*/
00430 }
00431 #endif
00432 
00433 #ifndef ASM_MP32CLRLSB
00434 void mp32clrlsb(register uint32 xsize, register uint32* xdata)
00435 {
00436 /*@-boundsread@*/
00437     xdata[xsize-1] &= 0xfffffffe;
00438 /*@=boundsread@*/
00439 }
00440 #endif
00441 
00442 #ifndef ASM_MP32XOR
00443 void mp32xor(register uint32 size, register uint32* xdata, register const uint32* ydata)
00444 {
00445         do
00446         {
00447                 --size;
00448 /*@-boundsread@*/
00449                 xdata[size] ^= ydata[size];
00450 /*@=boundsread@*/
00451         } while (size);
00452 }
00453 #endif
00454 
00455 #ifndef ASM_MP32NOT
00456 /*@-boundswrite@*/
00457 void mp32not(register uint32 xsize, register uint32* xdata)
00458 {
00459         do
00460         {
00461                 --xsize;
00462                 xdata[xsize] = ~xdata[xsize];
00463         } while (xsize);
00464 }
00465 /*@=boundswrite@*/
00466 #endif
00467 
00468 #ifndef ASM_MP32SETW
00469 /*@-boundswrite@*/
00470 void mp32setw(register uint32 xsize, register uint32* xdata, register uint32 y)
00471 {
00472         while (--xsize)
00473                 *(xdata++) = 0;
00474         *(xdata++) = y;
00475 }
00476 /*@=boundswrite@*/
00477 #endif
00478 
00479 #ifndef ASM_MP32SETX
00480 /*@-boundswrite@*/
00481 void mp32setx(register uint32 xsize, register uint32* xdata, register uint32 ysize, register const uint32* ydata)
00482 {
00483         while (xsize > ysize)
00484         {
00485                 xsize--;
00486                 *(xdata++) = 0;
00487         }
00488         while (ysize > xsize)
00489         {
00490                 ysize--;
00491                 ydata++;
00492         }
00493         while (xsize--)
00494                 *(xdata++) = *(ydata++);
00495 }
00496 /*@=boundswrite@*/
00497 #endif
00498 
00499 #ifndef ASM_MP32ADDW
00500 /*@-boundswrite@*/
00501 uint32 mp32addw(register uint32 xsize, register uint32* xdata, register uint32 y)
00502 {
00503         register uint64 temp;
00504         register uint32 carry = 0;
00505 
00506         xdata += xsize;
00507         temp = *(--xdata);
00508         temp += y;
00509         *xdata = (uint32) temp;
00510         while (--xsize && (carry = (uint32) (temp >> 32)))
00511         {
00512                 temp = *(--xdata);
00513                 temp += carry;
00514                 *xdata = (uint32) temp;
00515         }
00516         return (uint32)(temp >> 32);
00517 }
00518 /*@=boundswrite@*/
00519 #endif
00520 
00521 #ifndef ASM_MP32ADD
00522 /*@-boundswrite@*/
00523 uint32 mp32add(register uint32 size, register uint32* xdata, register const uint32* ydata)
00524 {
00525         register uint64 temp;
00526         register uint32 carry = 0;
00527 
00528         xdata += size;
00529         ydata += size;
00530 
00531         while (size--)
00532         {
00533                 temp = *(--xdata);
00534                 temp += *(--ydata);
00535                 temp += carry;
00536                 *xdata = (uint32) temp;
00537                 carry = (uint32) (temp >> 32);
00538         }
00539         return carry;
00540 }
00541 /*@=boundswrite@*/
00542 #endif
00543 
00544 #ifndef ASM_MP32ADDX
00545 uint32 mp32addx(register uint32 xsize, register uint32* xdata, register uint32 ysize, register const uint32* ydata)
00546 {
00547         if (xsize > ysize)
00548         {
00549                 register uint32 diff = xsize - ysize;
00550                 register uint32 carry = mp32add(ysize, xdata + diff, ydata);
00551                 return mp32addw(diff, xdata, carry);
00552         }
00553         else
00554         {
00555                 register int diff = ysize - xsize;
00556                 return mp32add(xsize, xdata, ydata + diff);
00557         }
00558 }
00559 #endif
00560 
00561 #ifndef ASM_MP32SUBW
00562 /*@-boundswrite@*/
00563 uint32 mp32subw(register uint32 xsize, register uint32* xdata, register uint32 y)
00564 {
00565         register uint64 temp;
00566         register uint32 carry = 0;
00567 
00568         xdata += xsize;
00569         temp = *(--xdata);
00570         temp -= y;
00571         *xdata = (uint32) temp;
00572         carry = (temp >> 32) ? 1 : 0;
00573         while (--xsize && carry)
00574         {
00575                 temp = *(--xdata);
00576                 temp -= carry;
00577                 *xdata = (uint32) temp;
00578                 carry = (temp >> 32) ? 1 : 0;
00579         }
00580         return carry;
00581 }
00582 /*@=boundswrite@*/
00583 #endif
00584 
00585 #ifndef ASM_MP32SUB
00586 /*@-boundswrite@*/
00587 uint32 mp32sub(register uint32 size, register uint32* xdata, register const uint32* ydata)
00588 {
00589         register uint64 temp;
00590         register uint32 carry = 0;
00591 
00592         xdata += size;
00593         ydata += size;
00594 
00595         while (size--)
00596         {
00597                 temp = *(--xdata);
00598                 temp -= *(--ydata);
00599                 temp -= carry;
00600                 *xdata = (uint32) temp;
00601                 carry = (temp >> 32) != 0;
00602         }
00603         return carry;
00604 }
00605 /*@=boundswrite@*/
00606 #endif
00607 
00608 #ifndef ASM_MP32SUBX
00609 uint32 mp32subx(register uint32 xsize, register uint32* xdata, register uint32 ysize, register const uint32* ydata)
00610 {
00611         if (xsize > ysize)
00612         {
00613                 register uint32 diff = xsize - ysize;
00614                 register uint32 carry = mp32sub(ysize, xdata + diff, ydata);
00615                 return mp32subw(diff, xdata, carry);
00616         }
00617         else
00618         {
00619                 register uint32 diff = ysize - xsize;
00620                 return mp32sub(xsize, xdata, ydata + diff);
00621         }
00622 }
00623 #endif
00624 
00625 #ifndef ASM_MP32NEG
00626 void mp32neg(register uint32 xsize, register uint32* xdata)
00627 {
00628         mp32not(xsize, xdata);
00629         (void) mp32addw(xsize, xdata, 1);
00630 }
00631 #endif
00632 
00633 #ifndef ASM_MP32SETMUL
00634 /*@-boundswrite@*/
00635 uint32 mp32setmul(register uint32 size, register uint32* result, register const uint32* xdata, register uint32 y)
00636 {
00637         register uint64 temp;
00638         register uint32 carry = 0;
00639 
00640         xdata  += size;
00641         result += size;
00642 
00643         while (size--)
00644         {
00645                 temp = *(--xdata);
00646                 temp *= y;
00647                 temp += carry;
00648                 *(--result) = (uint32) temp;
00649                 carry = (uint32) (temp >> 32);
00650         }
00651         return carry;
00652 }
00653 /*@=boundswrite@*/
00654 #endif
00655 
00656 #ifndef ASM_MP32ADDMUL
00657 /*@-boundswrite@*/
00658 uint32 mp32addmul(register uint32 size, register uint32* result, register const uint32* xdata, register uint32 y)
00659 {
00660         register uint64 temp;
00661         register uint32 carry = 0;
00662 
00663         xdata  += size;
00664         result += size;
00665 
00666         while (size--)
00667         {
00668                 temp = *(--xdata);
00669                 temp *= y;
00670                 temp += carry;
00671                 temp += *(--result);
00672                 *result = (uint32) temp;
00673                 carry = (uint32) (temp >> 32);
00674         }
00675         return carry;
00676 }
00677 /*@=boundswrite@*/
00678 #endif
00679 
00680 #ifndef ASM_MP32MUL
00681 /*@-boundswrite@*/
00682 void mp32mul(uint32* result, uint32 xsize, const uint32* xdata, uint32 ysize, const uint32* ydata)
00683 {
00684         /*@-mods@*/
00685         /* preferred passing of parameters is x the larger of the two numbers */
00686         if (xsize >= ysize)
00687         {
00688                 register uint32 rc;
00689 
00690                 result += ysize;
00691                 ydata += ysize;
00692 
00693                 rc = mp32setmul(xsize, result, xdata, *(--ydata));
00694                 *(--result) = rc;
00695 
00696                 while (--ysize)
00697                 {
00698                         rc = mp32addmul(xsize, result, xdata, *(--ydata));
00699                         *(--result) = rc;
00700                 }
00701         }
00702         else
00703         {
00704                 register uint32 rc;
00705 
00706                 result += xsize;
00707                 xdata += xsize;
00708 
00709                 rc = mp32setmul(ysize, result, ydata, *(--xdata));
00710                 *(--result) = rc;
00711 
00712                 while (--xsize)
00713                 {
00714                         rc = mp32addmul(ysize, result, ydata, *(--xdata));
00715                         *(--result) = rc;
00716                 }
00717         }
00718         /*@=mods@*/
00719 }
00720 /*@=boundswrite@*/
00721 #endif
00722 
00723 #ifndef ASM_MP32ADDSQRTRC
00724 /*@-boundswrite@*/
00725 uint32 mp32addsqrtrc(register uint32 size, register uint32* result, register const uint32* xdata)
00726 {
00727         register uint64 temp;
00728         register uint32 n, carry = 0;
00729 
00730         result += size*2;
00731 
00732         while (size--)
00733         {
00734                 temp = n = xdata[size];
00735                 temp *= n;
00736                 temp += carry;
00737                 temp += *(--result);
00738                 *result = (uint32) temp;
00739                 temp >>= 32;
00740                 temp += *(--result);
00741                 *result = (uint32) temp;
00742                 carry = (uint32) (temp >> 32);
00743         }
00744         return carry;
00745 }
00746 /*@=boundswrite@*/
00747 #endif
00748 
00749 #ifndef ASM_MP32SQR
00750 /*@-boundswrite@*/
00751 void mp32sqr(register uint32* result, register uint32 xsize, register const uint32* xdata)
00752 {
00753         register uint32 carry;
00754         register uint32 n = xsize-1;
00755 
00756         /*@-mods@*/
00757         result += xsize;
00758         result[n] = 0;
00759 
00760         if (n)
00761         {
00762                 carry = mp32setmul(n, result, xdata, xdata[n]);
00763                 *(--result) = carry;
00764                 while (--n)
00765                 {
00766                         carry = mp32addmul(n, result, xdata, xdata[n]);
00767                         *(--result) = carry;
00768                 }
00769         }
00770 
00771         *(--result) = 0;
00772 
00773         (void) mp32multwo(xsize*2, result);
00774 
00775         (void) mp32addsqrtrc(xsize, result, xdata);
00776         /*@=mods@*/
00777 }
00778 /*@=boundswrite@*/
00779 #endif
00780 
00781 #ifndef ASM_MP32SIZE
00782 uint32 mp32size(register uint32 xsize, register const uint32* xdata)
00783 {
00784         while (xsize)
00785         {
00786 /*@-boundsread@*/
00787                 if (*xdata)
00788                         return xsize;
00789 /*@=boundsread@*/
00790                 xdata++;
00791                 xsize--;
00792         }
00793         return 0;
00794 }
00795 #endif
00796 
00797 #ifndef ASM_MP32NORM
00798 uint32 mp32norm(register uint32 xsize, register uint32* xdata)
00799 {
00800         register uint32 shift = mp32mszcnt(xsize, xdata);
00801         mp32lshift(xsize, xdata, shift);
00802         return shift;
00803 }
00804 #endif
00805 
00806 #ifndef ASM_MP32DIVPOWTWO
00807 /* need to eliminate this function, as it is not aptly named */
00808 uint32 mp32divpowtwo(register uint32 xsize, register uint32* xdata)
00809 {
00810         return mp32rshiftlsz(xsize, xdata);
00811 }
00812 #endif
00813 
00814 #ifndef ASM_MP32DIVTWO
00815 /*@-boundswrite@*/
00816 void mp32divtwo(register uint32 xsize, register uint32* xdata)
00817 {
00818         register uint32 temp;
00819         register uint32 carry = 0;
00820 
00821         while (xsize--)
00822         {
00823                 temp = *xdata;
00824                 *(xdata++) = (temp >> 1) | carry;
00825                 carry = (temp << 31);
00826         }
00827 }
00828 /*@=boundswrite@*/
00829 #endif
00830 
00831 #ifndef ASM_MP32SDIVTWO
00832 void mp32sdivtwo(register uint32 xsize, register uint32* xdata)
00833 {
00834         mp32divtwo(xsize, xdata);
00835 /*@-boundsread@*/
00836         if (*xdata & 0x40000000)
00837                 *xdata |= 0x80000000;
00838 /*@=boundsread@*/
00839 }
00840 #endif
00841 
00842 #ifndef ASM_MP32MULTWO
00843 /*@-boundswrite@*/
00844 uint32 mp32multwo(register uint32 xsize, register uint32* xdata)
00845 {
00846         register uint32 temp;
00847         register uint32 carry = 0;
00848 
00849         xdata += xsize;
00850         while (xsize--)
00851         {
00852                 temp = *(--xdata);
00853                 *xdata = (temp << 1) | carry;
00854                 carry = (temp >> 31);
00855         }
00856         return carry;
00857 }
00858 /*@=boundswrite@*/
00859 #endif
00860 
00861 #ifndef ASM_MP32MSZCNT
00862 uint32 mp32mszcnt(register uint32 xsize, register const uint32* xdata)
00863 {
00864         register uint32 zbits = 0;
00865         register uint32 i = 0;
00866 
00867         while (i < xsize)
00868         {
00869 /*@-boundsread@*/
00870                 register uint32 temp = xdata[i++];
00871 /*@=boundsread@*/
00872                 if (temp)
00873                 {
00874                         while (!(temp & 0x80000000))
00875                         {
00876                                 zbits++;
00877                                 temp <<= 1;
00878                         }
00879                         break;
00880                 }
00881                 else
00882                         zbits += 32;
00883         }
00884         return zbits;
00885 }
00886 #endif
00887 
00888 #ifndef ASM_MP32LSZCNT
00889 uint32 mp32lszcnt(register uint32 xsize, register const uint32* xdata)
00890 {
00891         register uint32 zbits = 0;
00892 
00893         while (xsize--)
00894         {
00895 /*@-boundsread@*/
00896                 register uint32 temp = xdata[xsize];
00897 /*@=boundsread@*/
00898                 if (temp)
00899                 {
00900                         while (!(temp & 0x1))
00901                         {
00902                                 zbits++;
00903                                 temp >>= 1;
00904                         }
00905                         break;
00906                 }
00907                 else
00908                         zbits += 32;
00909         }
00910         return zbits;
00911 }
00912 #endif
00913 
00914 #ifndef ASM_MP32LSHIFT
00915 /*@-boundswrite@*/
00916 void mp32lshift(register uint32 xsize, register uint32* xdata, uint32 count)
00917 {
00918         register uint32 words = count >> 5;
00919 
00920         if (words < xsize)
00921         {
00922                 register uint8  lbits = (uint8) (count & 0x1f);
00923 
00924                 /* first do the shifting, then do the moving */
00925                 if (lbits != 0)
00926                 {
00927                         register uint32 temp;
00928                         register uint32 carry = 0;
00929                         register uint8  rbits = 32-lbits;
00930                         register uint32 i = xsize;
00931 
00932                         while (i > words)
00933                         {
00934                                 temp = xdata[--i];
00935                                 xdata[i] = (temp << lbits) | carry;
00936                                 carry = (temp >> rbits);
00937                         }
00938                 }
00939                 if (words)
00940                 {
00941                         mp32move(xsize-words, xdata, xdata+words);
00942                         mp32zero(words, xdata+xsize-words);
00943                 }
00944         }
00945         else
00946                 mp32zero(xsize, xdata);
00947 }
00948 /*@=boundswrite@*/
00949 #endif
00950 
00951 #ifndef ASM_MP32RSHIFT
00952 /*@-boundswrite@*/
00953 void mp32rshift(register uint32 xsize, register uint32* xdata, uint32 count)
00954 {
00955         register uint32 words = count >> 5;
00956 
00957         if (words < xsize)
00958         {
00959                 register uint8 rbits = (uint8) (count & 0x1f);
00960 
00961                 /* first do the shifting, then do the moving */
00962                 if (rbits != 0)
00963                 {
00964                         register uint32 temp;
00965                         register uint32 carry = 0;
00966                         register uint8  lbits = 32-rbits;
00967                         register uint32 i = 0;
00968 
00969                         while (i < xsize-words)
00970                         {
00971                                 temp = xdata[i];
00972                                 xdata[i++] = (temp >> rbits) | carry;
00973                                 carry = (temp << lbits);
00974                         }
00975                 }
00976                 if (words)
00977                 {
00978                         mp32move(xsize-words, xdata+words, xdata);
00979                         mp32zero(words, xdata);
00980                 }
00981         }
00982         else
00983                 mp32zero(xsize, xdata);
00984 }
00985 /*@=boundswrite@*/
00986 #endif
00987 
00988 #ifndef ASM_MP32RSHIFTLSZ
00989 /* x must be != 0 */
00990 /*@-boundswrite@*/
00991 uint32 mp32rshiftlsz(register uint32 xsize, register uint32* xdata)
00992 {
00993         register uint32* slide = xdata+xsize-1;
00994         register uint32  zwords = 0; /* counter for 'all zero bit' words */
00995         register uint32  lbits, rbits = 0; /* counter for 'least significant zero' bits */
00996         register uint32  temp, carry = 0;
00997 
00998         xdata = slide;
00999 
01000         /* count 'all zero' words and move src pointer */
01001         while (xsize--)
01002         {
01003                 /* test if we a non-zero word */
01004                 if ((carry = *(slide--)))
01005                 {
01006                         /* count 'least signification zero bits and set zbits counter */
01007                         while (!(carry & 0x1))
01008                         {
01009                                 carry >>= 1;
01010                                 rbits++;
01011                         }
01012                         break;
01013                 }
01014                 zwords++;
01015         }
01016 
01017         /* shouldn't happen, but let's test anyway */
01018         if (xsize == 0)
01019                 return 0;
01020 
01021         /* prepare right-shifting of data */
01022         lbits = 32-rbits;
01023 
01024         /* shift data */
01025         while (xsize--)
01026         {
01027                 temp = *(slide--);
01028                 *(xdata--) = (temp << lbits) | carry;
01029                 carry = (temp >> rbits);
01030         }
01031 
01032         /* store the final carry */
01033         *(xdata--) = carry;
01034 
01035         /* store the return value in temp */
01036         temp = (zwords << 5) + rbits;
01037 
01038         /* zero the (zwords) most significant words */
01039         while (zwords--)
01040                 *(xdata--) = 0;
01041 
01042         return temp;
01043 }
01044 /*@=boundswrite@*/
01045 #endif
01046 
01047 /* try an alternate version here, with descending sizes */
01048 /* also integrate lszcnt and rshift properly into one function */
01049 #ifndef ASM_MP32GCD_W
01050 /*@-boundswrite@*/
01055 void mp32gcd_w(uint32 size, const uint32* xdata, const uint32* ydata, uint32* result, uint32* wksp)
01056 {
01057         register uint32 shift = 0;
01058         register uint32 temp;
01059 
01060         if (mp32ge(size, xdata, ydata))
01061         {
01062                 mp32copy(size, wksp, xdata);
01063                 mp32copy(size, result, ydata);
01064         }
01065         else
01066         {
01067                 mp32copy(size, wksp, ydata);
01068                 mp32copy(size, result, xdata);
01069         }
01070                 
01071         /* get the smallest returned values, and set shift to that */
01072 
01073         shift = mp32rshiftlsz(size, wksp);
01074 
01075         temp = mp32rshiftlsz(size, result);
01076 
01077         if (shift > temp)
01078                 shift = temp;
01079 
01080         while (mp32nz(size, wksp))
01081         {
01082                 (void) mp32rshiftlsz(size, wksp);
01083                 (void) mp32rshiftlsz(size, result);
01084 
01085                 if (mp32ge(size, wksp, result))
01086                         (void) mp32sub(size, wksp, result);
01087                 else
01088                         (void) mp32sub(size, result, wksp);
01089 
01090                 /* slide past zero words in both operands by increasing pointers and decreasing size */
01091                 if ((*wksp == 0) && (*result == 0))
01092                 {
01093                         size--;
01094                         wksp++;
01095                         result++;
01096                 }
01097         }
01098 
01099         /* figure out if we need to slide the result pointer back */
01100         if ((temp = shift >> 5))
01101         {
01102                 size += temp;
01103                 result -= temp;
01104         }
01105 
01106         mp32lshift(size, result, shift);
01107 }
01108 /*@=boundswrite@*/
01109 #endif
01110 
01111 #ifndef ASM_MP32NMODW
01112 /*@-boundswrite@*/
01113 uint32 mp32nmodw(uint32* result, uint32 xsize, const uint32* xdata, uint32 y, uint32* wksp)
01114 {
01115         /* result size xsize, wksp size xsize+1 */
01116         register uint64 temp;
01117         register uint32 q;
01118         uint32 qsize = xsize-1;
01119         uint32* rdata = result;
01120 
01121         mp32copy(xsize, rdata, xdata);
01122         /*
01123                 if (*rdata >= y)
01124                         *rdata -= y;
01125         */
01126         if (mp32ge(1, rdata, &y))
01127                 (void) mp32sub(1, rdata, &y);
01128 
01129         while (qsize--)
01130         {
01131                 /* fprintf(stderr, "result = "); MP32println(stderr, xsize+1, result); */
01132                 /* get the two high words of r into temp */
01133                 temp = rdata[0];
01134                 temp <<= 32;
01135                 temp += rdata[1];
01136                 /* fprintf(stderr, "q = %016llx / %08lx\n", temp, msw); */
01137                 temp /= y;
01138                 /*
01139                         temp *= y;
01140                         wksp[0] = (uint32) (temp >> 32);
01141                         wksp[1] = (uint32) (temp);
01142                 */
01143                 q = (uint32) temp;
01144 
01145                 /* fprintf(stderr, "q = %08x\n", q); */
01146                 /*@-evalorder@*/
01147                 *wksp = mp32setmul(1, wksp+1, &y, q);
01148                 /*@=evalorder@*/
01149 
01150                 /* fprintf(stderr, "mplt "); mp32print(2, rdata); fprintf(stderr, " < "); mp32println(stderr, 2, wksp); */
01151                 while (mp32lt(2, rdata, wksp))
01152                 {
01153                         /* fprintf(stderr, "mp32lt! "); mp32print(2, rdata); fprintf(stderr, " < "); mp32println(stderr, 2, wksp); */
01154                         /* fprintf(stderr, "decreasing q\n"); */
01155                         (void) mp32subx(2, wksp, 1, &y);
01156                         /* q--; */
01157                 }
01158                 /* fprintf(stderr, "subtracting\n"); */
01159                 (void) mp32sub(2, rdata, wksp);
01160                 rdata++;
01161         }
01162 
01163         return *rdata;
01164 }
01165 /*@=boundswrite@*/
01166 #endif
01167 
01168 #ifndef ASM_MP32NMOD
01169 /*@-boundswrite@*/
01170 void mp32nmod(uint32* result, uint32 xsize, const uint32* xdata, uint32 ysize, const uint32* ydata, uint32* wksp)
01171 {
01172         /* result size xsize, wksp size xsize+1 */
01173         register uint64 temp;
01174         register uint32 q;
01175         uint32 msw = *ydata;
01176         uint32 qsize = xsize-ysize;
01177         uint32* rdata = result;
01178 
01179         mp32copy(xsize, rdata, xdata);
01180         if (mp32ge(ysize, rdata, ydata))
01181                 (void) mp32sub(ysize, rdata, ydata);
01182 
01183         while (qsize--)
01184         {
01185                 /* fprintf(stderr, "result = "); mp32println(stderr, xsize+1, result); */
01186                 /* get the two high words of r into temp */
01187                 temp = rdata[0];
01188                 temp <<= 32;
01189                 temp += rdata[1];
01190                 /* fprintf(stderr, "q = %016llx / %08lx\n", temp, msw); */
01191                 temp /= msw;
01192                 q = (uint32) temp;
01193 
01194                 /* fprintf(stderr, "q = %08x\n", q); */
01195                 /*@-evalorder@*/
01196                 *wksp = mp32setmul(ysize, wksp+1, ydata, q);
01197                 /*@=evalorder@*/
01198 
01199                 /* fprintf(stderr, "mp32lt "); mp32print(ysize+1, rdata); fprintf(stderr, " < "); mp32println(stderr, ysize+1, wksp); */
01200                 while (mp32lt(ysize+1, rdata, wksp))
01201                 {
01202                         /* fprintf(stderr, "mp32lt! "); mp32print(ysize+1, rdata); fprintf(stderr, " < "); mp32println(stderr, ysize+1, wksp); */
01203                         /* fprintf(stderr, "decreasing q\n"); */
01204                         (void) mp32subx(ysize+1, wksp, ysize, ydata);
01205                         q--;
01206                 }
01207                 /* fprintf(stderr, "subtracting\n"); */
01208                 (void) mp32sub(ysize+1, rdata, wksp);
01209                 rdata++;
01210         }
01211 }
01212 /*@=boundswrite@*/
01213 #endif
01214 
01215 #ifndef ASM_MP32NDIVMOD
01216 /*@-boundswrite@*/
01217 void mp32ndivmod(uint32* result, uint32 xsize, const uint32* xdata, uint32 ysize, const uint32* ydata, register uint32* wksp)
01218 {
01219         /* result must be xsize+1 in length */
01220         /* wksp must be ysize+1 in length */
01221         /* expect ydata to be normalized */
01222         register uint64 temp;
01223         register uint32 q;
01224         uint32 msw = *ydata;
01225         uint32 qsize = xsize-ysize;
01226 
01227         mp32copy(xsize, result+1, xdata);
01228         /*@-compdef@*/ /* LCL: result+1 undefined */
01229         if (mp32ge(ysize, result+1, ydata))
01230         {
01231                 /* fprintf(stderr, "subtracting\n"); */
01232                 (void) mp32sub(ysize, result+1, ydata);
01233                 *(result++) = 1;
01234         }
01235         else
01236                 *(result++) = 0;
01237         /*@=compdef@*/
01238 
01239         /*@-usedef@*/   /* LCL: result[0] is set */
01240         while (qsize--)
01241         {
01242                 /* fprintf(stderr, "result = "); mp32println(stderr, xsize+1, result); */
01243                 /* get the two high words of r into temp */
01244                 temp = result[0];
01245                 temp <<= 32;
01246                 temp += result[1];
01247                 /* fprintf(stderr, "q = %016llx / %08lx\n", temp, msw); */
01248                 temp /= msw;
01249                 q = (uint32) temp;
01250 
01251                 /* fprintf(stderr, "q = %08x\n", q); */
01252 
01253                 /*@-evalorder@*/
01254                 *wksp = mp32setmul(ysize, wksp+1, ydata, q);
01255                 /*@=evalorder@*/
01256 
01257                 /* fprintf(stderr, "mp32lt "); mp32print(ysize+1, result); fprintf(stderr, " < "); mp32println(stderr, ysize+1, wksp); */
01258                 while (mp32lt(ysize+1, result, wksp))
01259                 {
01260                         /* fprintf(stderr, "mp32lt! "); mp32print(ysize+1, result); fprintf(stderr, " < "); mp32println(stderr, ysize+1, wksp); */
01261                         /* fprintf(stderr, "decreasing q\n"); */
01262                         (void) mp32subx(ysize+1, wksp, ysize, ydata);
01263                         q--;
01264                 }
01265                 /* fprintf(stderr, "subtracting\n"); */
01266                 (void) mp32sub(ysize+1, result, wksp);
01267                 *(result++) = q;
01268         }
01269         /*@=usedef@*/
01270 }
01271 /*@=boundswrite@*/
01272 #endif
01273 
01274 /*
01275 #ifndef ASM_MP32UNPACK
01276 void mp32unpack(uint32 size, uint8* bytes, const uint32* bits)
01277 {
01278         register uint32 temp;
01279         register int i;
01280         
01281         while (size--)
01282         {
01283                 temp = *(bits++);
01284 
01285                 for (i = 0; i < 31; i++)
01286                 {
01287                         bytes
01288                 }
01289         }
01290 }
01291 #endif
01292 */
01293 
01294 #ifndef ASM_MP32PRINT
01295 /*@-boundsread@*/
01296 void mp32print(register FILE * fp, register uint32 xsize, register const uint32* xdata)
01297 {
01298         if (xdata == NULL)
01299                 return;
01300         if (fp == NULL)
01301                 fp = stderr;
01302         while (xsize--)
01303                 fprintf(fp, "%08x", *(xdata++));
01304         (void) fflush(fp);
01305 }
01306 /*@=boundsread@*/
01307 #endif
01308 
01309 #ifndef ASM_MP32PRINTLN
01310 /*@-boundsread@*/
01311 void mp32println(register FILE * fp, register uint32 xsize, register const uint32* xdata)
01312 {
01313         if (xdata == NULL)
01314                 return;
01315         if (fp == NULL)
01316                 fp = stderr;
01317         while (xsize--)
01318                 fprintf(fp, "%08x", *(xdata++));
01319         fprintf(fp, "\n");
01320         (void) fflush(fp);
01321 }
01322 /*@=boundsread@*/
01323 #endif

Generated on Tue Sep 17 15:56:37 2002 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002