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