2 * Copyright (c) 2002, 2003 Bob Deblier
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * \brief Multi-precision integer routines.
22 * \author Bob Deblier <bob.deblier@pandora.be>
26 #define BEECRYPT_DLL_EXPORT
32 #include "beecrypt/mp.h"
33 #include "beecrypt/mpopt.h"
36 void mpzero(size_t size
, mpw
* data
)
44 void mpfill(size_t size
, mpw
* data
, mpw fill
)
52 int mpodd(size_t size
, const mpw
* data
)
54 return (int)(data
[size
-1] & 0x1);
59 int mpeven(size_t size
, const mpw
* data
)
61 return !(int)(data
[size
-1] & 0x1);
66 int mpz(size_t size
, const mpw
* data
)
76 int mpnz(size_t size
, const mpw
* data
)
86 int mpeq(size_t size
, const mpw
* xdata
, const mpw
* ydata
)
103 int mpeqx(size_t xsize
, const mpw
* xdata
, size_t ysize
, const mpw
* ydata
)
107 register size_t diff
= xsize
- ysize
;
108 return mpeq(ysize
, xdata
+diff
, ydata
) && mpz(diff
, xdata
);
110 else if (xsize
< ysize
)
112 register size_t diff
= ysize
- xsize
;
113 return mpeq(xsize
, ydata
+diff
, xdata
) && mpz(diff
, ydata
);
116 return mpeq(xsize
, xdata
, ydata
);
121 int mpne(size_t size
, const mpw
* xdata
, const mpw
* ydata
)
125 if (*xdata
== *ydata
)
138 int mpnex(size_t xsize
, const mpw
* xdata
, size_t ysize
, const mpw
* ydata
)
142 register size_t diff
= xsize
- ysize
;
143 return mpnz(diff
, xdata
) || mpne(ysize
, xdata
+diff
, ydata
);
145 else if (xsize
< ysize
)
147 register size_t diff
= ysize
- xsize
;
148 return mpnz(diff
, ydata
) || mpne(xsize
, ydata
+diff
, xdata
);
151 return mpne(xsize
, xdata
, ydata
);
156 int mpgt(size_t size
, const mpw
* xdata
, const mpw
* ydata
)
171 int mpgtx(size_t xsize
, const mpw
* xdata
, size_t ysize
, const mpw
* ydata
)
175 register size_t diff
= xsize
- ysize
;
176 return mpnz(diff
, xdata
) || mpgt(ysize
, xdata
+ diff
, ydata
);
178 else if (xsize
< ysize
)
180 register size_t diff
= ysize
- xsize
;
181 return mpz(diff
, ydata
) && mpgt(xsize
, xdata
, ydata
+ diff
);
184 return mpgt(xsize
, xdata
, ydata
);
189 int mplt(size_t size
, const mpw
* xdata
, const mpw
* ydata
)
204 int mpltx(size_t xsize
, const mpw
* xdata
, size_t ysize
, const mpw
* ydata
)
208 register size_t diff
= xsize
- ysize
;
209 return mpz(diff
, xdata
) && mplt(ysize
, xdata
+diff
, ydata
);
211 else if (xsize
< ysize
)
213 register size_t diff
= ysize
- xsize
;
214 return mpnz(diff
, ydata
) || mplt(xsize
, xdata
, ydata
+diff
);
217 return mplt(xsize
, xdata
, ydata
);
222 int mpge(size_t size
, const mpw
* xdata
, const mpw
* ydata
)
237 int mpgex(size_t xsize
, const mpw
* xdata
, size_t ysize
, const mpw
* ydata
)
241 register size_t diff
= xsize
- ysize
;
242 return mpnz(diff
, xdata
) || mpge(ysize
, xdata
+diff
, ydata
);
244 else if (xsize
< ysize
)
246 register size_t diff
= ysize
- xsize
;
247 return mpz(diff
, ydata
) && mpge(xsize
, xdata
, ydata
+diff
);
250 return mpge(xsize
, xdata
, ydata
);
255 int mple(size_t size
, const mpw
* xdata
, const mpw
* ydata
)
270 int mplex(size_t xsize
, const mpw
* xdata
, size_t ysize
, const mpw
* ydata
)
274 register size_t diff
= xsize
- ysize
;
275 return mpz(diff
, xdata
) && mple(ysize
, xdata
+ diff
, ydata
);
277 else if (xsize
< ysize
)
279 register size_t diff
= ysize
- xsize
;
280 return mpnz(diff
, ydata
) || mple(xsize
, xdata
, ydata
+diff
);
283 return mple(xsize
, xdata
, ydata
);
288 int mpisone(size_t size
, const mpw
* data
)
303 int mpistwo(size_t size
, const mpw
* data
)
318 int mpeqmone(size_t size
, const mpw
* xdata
, const mpw
* ydata
)
323 if (*(--xdata
)+1 == *(--ydata
))
326 if (*(--xdata
) != *(--ydata
))
335 int mpleone(size_t size
, const mpw
* data
)
351 int mpmsbset(size_t size
, const mpw
* data
)
353 return (int)((*data
) >> (MP_WBITS
-1));
358 int mplsbset(size_t size
, const mpw
* data
)
360 return (int)(data
[size
-1] & 0x1);
365 void mpsetmsb(size_t size
, mpw
* data
)
372 void mpsetlsb(size_t size
, mpw
* data
)
374 data
[size
-1] |= MP_LSBMASK
;
379 void mpclrmsb(size_t size
, mpw
* data
)
381 *data
&= ~ MP_MSBMASK
;
386 void mpclrlsb(size_t size
, mpw
* data
)
388 data
[size
-1] &= ~ MP_LSBMASK
;
393 void mpand(size_t size
, mpw
* xdata
, const mpw
* ydata
)
396 xdata
[size
] &= ydata
[size
];
401 void mpor(size_t size
, mpw
* xdata
, const mpw
* ydata
)
404 xdata
[size
] |= ydata
[size
];
409 void mpxor(size_t size
, mpw
* xdata
, const mpw
* ydata
)
412 xdata
[size
] ^= ydata
[size
];
417 void mpnot(size_t size
, mpw
* data
)
420 data
[size
] = ~data
[size
];
425 void mpsetw(size_t size
, mpw
* xdata
, mpw y
)
434 void mpsetx(size_t xsize
, mpw
* xdata
, size_t ysize
, const mpw
* ydata
)
436 while (xsize
> ysize
)
441 while (ysize
> xsize
)
447 *(xdata
++) = *(ydata
++);
452 int mpaddw(size_t size
, mpw
* xdata
, mpw y
)
454 register mpw load
, temp
;
455 register int carry
= 0;
462 carry
= (load
> temp
);
464 while (--size
&& carry
)
469 carry
= (load
> temp
);
476 int mpadd(size_t size
, mpw
* xdata
, const mpw
* ydata
)
478 register mpw load
, temp
;
479 register int carry
= 0;
488 temp
= carry
? (load
+ temp
+ 1) : (load
+ temp
);
490 carry
= carry
? (load
>= temp
) : (load
> temp
);
497 int mpaddx(size_t xsize
, mpw
* xdata
, size_t ysize
, const mpw
* ydata
)
501 register size_t diff
= xsize
- ysize
;
502 return mpaddw(diff
, xdata
, (mpw
) mpadd(ysize
, xdata
+diff
, ydata
));
506 register size_t diff
= ysize
- xsize
;
507 return mpadd(xsize
, xdata
, ydata
+diff
);
513 int mpsubw(size_t size
, mpw
* xdata
, mpw y
)
515 register mpw load
, temp
;
516 register int carry
= 0;
523 carry
= (load
< temp
);
525 while (--size
&& carry
)
530 carry
= (load
< temp
);
537 int mpsub(size_t size
, mpw
* xdata
, const mpw
* ydata
)
539 register mpw load
, temp
;
540 register int carry
= 0;
549 temp
= carry
? (load
- temp
- 1) : (load
- temp
);
551 carry
= carry
? (load
<= temp
) : (load
< temp
);
558 int mpsubx(size_t xsize
, mpw
* xdata
, size_t ysize
, const mpw
* ydata
)
562 register size_t diff
= xsize
- ysize
;
563 return mpsubw(diff
, xdata
, (mpw
) mpsub(ysize
, xdata
+diff
, ydata
));
567 register size_t diff
= ysize
- xsize
;
568 return mpsub(xsize
, xdata
, ydata
+diff
);
574 void mpneg(size_t size
, mpw
* data
)
577 mpaddw(size
, data
, 1);
582 mpw
mpsetmul(size_t size
, mpw
* result
, const mpw
* data
, mpw y
)
586 register mpw carry
= 0;
596 *(--result
) = (mpw
) temp
;
597 carry
= (mpw
)(temp
>> MP_WBITS
);
600 register mpw temp
, load
, carry
= 0;
601 register mphw ylo
, yhi
;
604 yhi
= (mphw
) (y
>> MP_HWBITS
);
611 register mphw xlo
, xhi
;
612 register mpw rlo
, rhi
;
614 xlo
= (mphw
) (temp
= *(--data
));
615 xhi
= (mphw
) (temp
>> MP_HWBITS
);
617 rlo
= (mpw
) xlo
* ylo
;
618 rhi
= (mpw
) xhi
* yhi
;
620 temp
= (mpw
) xhi
* ylo
;
621 rlo
+= (temp
<< MP_HWBITS
);
622 rhi
+= (temp
>> MP_HWBITS
) + (load
> rlo
);
624 temp
= (mpw
) xlo
* yhi
;
625 rlo
+= (temp
<< MP_HWBITS
);
626 rhi
+= (temp
>> MP_HWBITS
) + (load
> rlo
);
629 carry
= rhi
+ (load
> temp
);
638 mpw
mpaddmul(size_t size
, mpw
* result
, const mpw
* data
, mpw y
)
642 register mpw carry
= 0;
653 *result
= (mpw
) temp
;
654 carry
= (mpw
)(temp
>> MP_WBITS
);
657 register mpw temp
, load
, carry
= 0;
658 register mphw ylo
, yhi
;
661 yhi
= (mphw
) (y
>> MP_HWBITS
);
668 register mphw xlo
, xhi
;
669 register mpw rlo
, rhi
;
671 xlo
= (mphw
) (temp
= *(--data
));
672 xhi
= (mphw
) (temp
>> MP_HWBITS
);
674 rlo
= (mpw
) xlo
* ylo
;
675 rhi
= (mpw
) xhi
* yhi
;
677 temp
= (mpw
) xhi
* ylo
;
678 rlo
+= (temp
<< MP_HWBITS
);
679 rhi
+= (temp
>> MP_HWBITS
) + (load
> rlo
);
681 temp
= (mpw
) xlo
* yhi
;
682 rlo
+= (temp
<< MP_HWBITS
);
683 rhi
+= (temp
>> MP_HWBITS
) + (load
> rlo
);
689 carry
= (load
> rhi
);
693 carry
+= rhi
+ (load
> rlo
);
701 void mpmul(mpw
* result
, size_t xsize
, const mpw
* xdata
, size_t ysize
, const mpw
* ydata
)
703 /* preferred passing of parameters is x the larger of the two numbers */
711 rc
= mpsetmul(xsize
, result
, xdata
, *(--ydata
));
716 rc
= mpaddmul(xsize
, result
, xdata
, *(--ydata
));
727 rc
= mpsetmul(ysize
, result
, ydata
, *(--xdata
));
732 rc
= mpaddmul(ysize
, result
, ydata
, *(--xdata
));
739 #ifndef ASM_MPADDSQRTRC
740 void mpaddsqrtrc(size_t size
, mpw
* result
, const mpw
* data
)
744 register mpw load
, carry
= 0;
746 result
+= (size
<< 1);
750 temp
= load
= data
[size
];
754 *result
= (mpw
) temp
;
757 *result
= (mpw
) temp
;
758 carry
= (mpw
)(temp
>> MP_WBITS
);
761 register mpw temp
, load
, carry
= 0;
763 result
+= (size
<< 1);
767 register mphw xlo
, xhi
;
768 register mpw rlo
, rhi
;
770 xlo
= (mphw
) (temp
= data
[size
]);
771 xhi
= (mphw
) (temp
>> MP_HWBITS
);
773 rlo
= (mpw
) xlo
* xlo
;
774 rhi
= (mpw
) xhi
* xhi
;
775 temp
= (mpw
) xhi
* xlo
;
777 rlo
+= (temp
<< MP_HWBITS
);
778 rhi
+= (temp
>> MP_HWBITS
) + (load
> rlo
);
780 rlo
+= (temp
<< MP_HWBITS
);
781 rhi
+= (temp
>> MP_HWBITS
) + (load
> rlo
);
791 carry
= (load
> rhi
);
795 carry
+= (load
> rhi
);
802 void mpsqr(mpw
* result
, size_t size
, const mpw
* data
)
805 register size_t n
= size
-1;
812 rc
= mpsetmul(n
, result
, data
, data
[n
]);
816 rc
= mpaddmul(n
, result
, data
, data
[n
]);
823 mpmultwo(size
<< 1, result
);
825 mpaddsqrtrc(size
, result
, data
);
830 size_t mpsize(size_t size
, const mpw
* data
)
844 size_t mpbits(size_t size
, const mpw
* data
)
846 return MP_WORDS_TO_BITS(size
) - mpmszcnt(size
, data
);
851 size_t mpnorm(size_t size
, mpw
* data
)
853 register size_t shift
= mpmszcnt(size
, data
);
854 mplshift(size
, data
, shift
);
860 void mpdivtwo(size_t size
, mpw
* data
)
862 register mpw temp
, carry
= 0;
867 *(data
++) = (temp
>> 1) | carry
;
868 carry
= (temp
<< (MP_WBITS
-1));
873 #ifndef ASM_MPSDIVTWO
874 void mpsdivtwo(size_t size
, mpw
* data
)
876 int carry
= mpmsbset(size
, data
);
877 mpdivtwo(size
, data
);
879 mpsetmsb(size
, data
);
884 int mpmultwo(size_t size
, mpw
* data
)
886 register mpw temp
, carry
= 0;
892 *data
= (temp
<< 1) | carry
;
893 carry
= (temp
>> (MP_WBITS
-1));
900 size_t mpmszcnt(size_t size
, const mpw
* data
)
902 register size_t zbits
= 0;
903 register size_t i
= 0;
907 register mpw temp
= data
[i
++];
910 while (!(temp
& MP_MSBMASK
))
925 size_t mplszcnt(size_t size
, const mpw
* data
)
927 register size_t zbits
= 0;
931 register mpw temp
= data
[size
];
934 while (!(temp
& MP_LSBMASK
))
949 void mplshift(size_t size
, mpw
* data
, size_t count
)
951 register size_t words
= MP_BITS_TO_WORDS(count
);
955 register short lbits
= (short) (count
& (MP_WBITS
-1));
957 /* first do the shifting, then do the moving */
960 register mpw temp
, carry
= 0;
961 register short rbits
= MP_WBITS
- lbits
;
962 register size_t i
= size
;
967 data
[i
] = (temp
<< lbits
) | carry
;
968 carry
= (temp
>> rbits
);
973 mpmove(size
-words
, data
, data
+words
);
974 mpzero(words
, data
+size
-words
);
983 void mprshift(size_t size
, mpw
* data
, size_t count
)
985 register size_t words
= MP_BITS_TO_WORDS(count
);
989 register short rbits
= (short) (count
& (MP_WBITS
-1));
991 /* first do the shifting, then do the moving */
994 register mpw temp
, carry
= 0;
995 register short lbits
= MP_WBITS
- rbits
;
996 register size_t i
= 0;
998 while (i
< size
-words
)
1001 data
[i
++] = (temp
>> rbits
) | carry
;
1002 carry
= (temp
<< lbits
);
1007 mpmove(size
-words
, data
+words
, data
);
1008 mpzero(words
, data
);
1016 #ifndef ASM_MPRSHIFTLSZ
1017 size_t mprshiftlsz(size_t size
, mpw
* data
)
1019 register mpw
* slide
= data
+size
-1;
1020 register size_t zwords
= 0; /* counter for 'all zero bit' words */
1021 register short lbits
, rbits
= 0; /* counter for 'least significant zero' bits */
1022 register mpw temp
, carry
= 0;
1026 /* count 'all zero' words and move src pointer */
1029 /* test if we have a non-zero word */
1030 if ((carry
= *(slide
--)))
1032 /* count 'least signification zero bits and set zbits counter */
1033 while (!(carry
& MP_LSBMASK
))
1043 if ((rbits
== 0) && (zwords
== 0))
1046 /* prepare right-shifting of data */
1047 lbits
= MP_WBITS
- rbits
;
1053 *(data
--) = (temp
<< lbits
) | carry
;
1054 carry
= (temp
>> rbits
);
1057 /* store the final carry */
1060 /* store the return value in size */
1061 size
= MP_WORDS_TO_BITS(zwords
) + rbits
;
1063 /* zero the (zwords) most significant words */
1071 /* try an alternate version here, with descending sizes */
1072 /* also integrate lszcnt and rshift properly into one function */
1076 * need workspace of (size) words
1078 void mpgcd_w(size_t size
, const mpw
* xdata
, const mpw
* ydata
, mpw
* result
, mpw
* wksp
)
1080 register size_t shift
, temp
;
1082 if (mpge(size
, xdata
, ydata
))
1084 mpcopy(size
, wksp
, xdata
);
1085 mpcopy(size
, result
, ydata
);
1089 mpcopy(size
, wksp
, ydata
);
1090 mpcopy(size
, result
, xdata
);
1093 /* get the smallest returned values, and set shift to that */
1095 shift
= mprshiftlsz(size
, wksp
);
1096 temp
= mprshiftlsz(size
, result
);
1101 while (mpnz(size
, wksp
))
1103 mprshiftlsz(size
, wksp
);
1104 mprshiftlsz(size
, result
);
1106 if (mpge(size
, wksp
, result
))
1107 mpsub(size
, wksp
, result
);
1109 mpsub(size
, result
, wksp
);
1111 /* slide past zero words in both operands by increasing pointers and decreasing size */
1112 if ((*wksp
== 0) && (*result
== 0))
1120 /* figure out if we need to slide the result pointer back */
1121 if ((temp
= MP_BITS_TO_WORDS(shift
)))
1127 mplshift(size
, result
, shift
);
1131 #ifndef ASM_MPEXTGCD_W
1132 /* needs workspace of (6*size+6) words */
1133 /* used to compute the modular inverse */
1134 int mpextgcd_w(size_t size
, const mpw
* xdata
, const mpw
* ydata
, mpw
* result
, mpw
* wksp
)
1137 * For computing a modular inverse, pass the modulus as xdata and the number
1138 * to be inverted as ydata.
1140 * Fact: if a element of Zn, then a is invertible if and only if gcd(a,n) = 1
1141 * Hence: if n is even, then a must be odd, otherwise the gcd(a,n) >= 2
1143 * The calling routine must guarantee this condition.
1146 register size_t sizep
= size
+1;
1150 mpw
* vdata
= udata
+sizep
;
1151 mpw
* adata
= vdata
+sizep
;
1152 mpw
* bdata
= adata
+sizep
;
1153 mpw
* cdata
= bdata
+sizep
;
1154 mpw
* ddata
= cdata
+sizep
;
1156 mpsetx(sizep
, udata
, size
, xdata
);
1157 mpsetx(sizep
, vdata
, size
, ydata
);
1158 mpzero(sizep
, bdata
);
1159 mpsetw(sizep
, ddata
, 1);
1161 if ((full
= mpeven(sizep
, udata
)))
1163 mpsetw(sizep
, adata
, 1);
1164 mpzero(sizep
, cdata
);
1169 while (mpeven(sizep
, udata
))
1171 mpdivtwo(sizep
, udata
);
1173 if (mpodd(sizep
, bdata
) || (full
&& mpodd(sizep
, adata
)))
1175 if (full
) mpaddx(sizep
, adata
, size
, ydata
);
1176 mpsubx(sizep
, bdata
, size
, xdata
);
1179 if (full
) mpsdivtwo(sizep
, adata
);
1180 mpsdivtwo(sizep
, bdata
);
1182 while (mpeven(sizep
, vdata
))
1184 mpdivtwo(sizep
, vdata
);
1186 if (mpodd(sizep
, ddata
) || (full
&& mpodd(sizep
, cdata
)))
1188 if (full
) mpaddx(sizep
, cdata
, size
, ydata
);
1189 mpsubx(sizep
, ddata
, size
, xdata
);
1192 if (full
) mpsdivtwo(sizep
, cdata
);
1193 mpsdivtwo(sizep
, ddata
);
1195 if (mpge(sizep
, udata
, vdata
))
1197 mpsub(sizep
, udata
, vdata
);
1198 if (full
) mpsub(sizep
, adata
, cdata
);
1199 mpsub(sizep
, bdata
, ddata
);
1203 mpsub(sizep
, vdata
, udata
);
1204 if (full
) mpsub(sizep
, cdata
, adata
);
1205 mpsub(sizep
, ddata
, bdata
);
1207 if (mpz(sizep
, udata
))
1209 if (mpisone(sizep
, vdata
))
1213 if (*ddata
& MP_MSBMASK
)
1215 /* keep adding the modulus until we get a carry */
1216 while (!mpaddx(sizep
, ddata
, size
, xdata
));
1220 /* in some computations, d ends up > x, hence:
1221 * keep subtracting n from d until d < x
1223 while (mpgtx(sizep
, ddata
, size
, xdata
))
1224 mpsubx(sizep
, ddata
, size
, xdata
);
1226 mpsetx(size
, result
, sizep
, ddata
);
1237 mpw
mppndiv(mpw xhi
, mpw xlo
, mpw y
)
1239 register mpw result
= 0;
1240 register short count
= MP_WBITS
;
1241 register int carry
= 0;
1245 if (carry
| (xhi
>= y
))
1250 carry
= (xhi
>> (MP_WBITS
-1));
1252 xhi
|= (xlo
>> (MP_WBITS
-1));
1256 if (carry
| (xhi
>= y
))
1266 void mpmod(mpw
* result
, size_t xsize
, const mpw
* xdata
, size_t ysize
, const mpw
* ydata
, mpw
* workspace
)
1268 /* result size xsize, workspace size 2*ysize+1 */
1270 mpw
* rdata
= result
;
1271 mpw
* ynorm
= workspace
+ysize
+1;
1272 size_t shift
, qsize
= xsize
-ysize
;
1274 mpcopy(ysize
, ynorm
, ydata
);
1275 shift
= mpnorm(ysize
, ynorm
);
1277 mpcopy(xsize
, rdata
, xdata
);
1278 if (mpge(ysize
, rdata
, ynorm
))
1279 mpsub(ysize
, rdata
, ynorm
);
1283 q
= mppndiv(rdata
[0], rdata
[1], msw
);
1285 *workspace
= mpsetmul(ysize
, workspace
+1, ynorm
, q
);
1287 while (mplt(ysize
+1, rdata
, workspace
))
1289 mpsubx(ysize
+1, workspace
, ysize
, ynorm
);
1292 mpsub(ysize
+1, rdata
, workspace
);
1295 /* de-normalization steps */
1298 mpdivtwo(ysize
, ynorm
);
1299 if (mpge(ysize
, rdata
, ynorm
))
1300 mpsub(ysize
, rdata
, ynorm
);
1305 #ifndef ASM_MPNDIVMOD
1306 void mpndivmod(mpw
* result
, size_t xsize
, const mpw
* xdata
, size_t ysize
, const mpw
* ydata
, register mpw
* workspace
)
1308 /* result must be xsize+1 in length */
1309 /* workspace must be ysize+1 in length */
1310 /* expect ydata to be normalized */
1313 size_t qsize
= xsize
-ysize
;
1315 *result
= (mpge(ysize
, xdata
, ydata
) ? 1 : 0);
1316 mpcopy(xsize
, result
+1, xdata
);
1319 (void) mpsub(ysize
, result
+1, ydata
);
1325 q
= mppndiv(result
[0], result
[1], msw
);
1327 *workspace
= mpsetmul(ysize
, workspace
+1, ydata
, q
);
1329 while (mplt(ysize
+1, result
, workspace
))
1331 mpsubx(ysize
+1, workspace
, ysize
, ydata
);
1334 mpsub(ysize
+1, result
, workspace
);
1340 void mpprint(size_t size
, const mpw
* data
)
1342 mpfprint(stdout
, size
, data
);
1345 void mpprintln(size_t size
, const mpw
* data
)
1347 mpfprintln(stdout
, size
, data
);
1350 void mpfprint(FILE* f
, size_t size
, const mpw
* data
)
1352 if (data
== (mpw
*) 0)
1360 #if (MP_WBITS == 32)
1361 fprintf(f
, "%08x", (unsigned) *(data
++));
1362 #elif (MP_WBITS == 64)
1364 fprintf(f
, "%016I64x", *(data
++));
1365 # elif SIZEOF_UNSIGNED_LONG == 8
1366 fprintf(f
, "%016lx", *(data
++));
1368 fprintf(f
, "%016llx", *(data
++));
1377 void mpfprintln(FILE* f
, size_t size
, const mpw
* data
)
1379 if (data
== (mpw
*) 0)
1387 #if (MP_WBITS == 32)
1388 fprintf(f
, "%08x", *(data
++));
1389 #elif (MP_WBITS == 64)
1391 fprintf(f
, "%016I64x", *(data
++));
1392 # elif SIZEOF_UNSIGNED_LONG == 8
1393 fprintf(f
, "%016lx", *(data
++));
1395 fprintf(f
, "%016llx", *(data
++));
1405 int i2osp(byte
*osdata
, size_t ossize
, const mpw
* idata
, size_t isize
)
1408 size_t max_bytes
= MP_WORDS_TO_BYTES(isize
);
1410 size_t significant_bytes
= (mpbits(isize
, idata
) + 7) >> 3;
1412 /* verify that ossize is large enough to contain the significant bytes */
1413 if (ossize
>= significant_bytes
)
1415 /* looking good; check if we have more space than significant bytes */
1416 if (ossize
> significant_bytes
)
1417 { /* fill most significant bytes with zero */
1418 memset(osdata
, 0, ossize
- significant_bytes
);
1419 osdata
+= ossize
- significant_bytes
;
1421 if (significant_bytes
)
1422 { /* fill remaining bytes with endian-adjusted data */
1423 #if !WORDS_BIGENDIAN
1424 mpw w
= idata
[--isize
];
1427 /* fill right-to-left; much easier than left-to-right */
1430 osdata
[--significant_bytes
] = (byte
)(w
>> shift
);
1432 if (shift
== MP_WBITS
)
1437 } while (significant_bytes
);
1439 /* just copy data past zero bytes */
1440 memcpy(osdata
, ((byte
*) idata
) + (max_bytes
- significant_bytes
), significant_bytes
);
1448 int os2ip(mpw
* idata
, size_t isize
, const byte
* osdata
, size_t ossize
)
1452 /* skip non-significant leading zero bytes */
1453 while (!(*osdata
) && ossize
)
1459 required
= MP_BYTES_TO_WORDS(ossize
+ MP_WBYTES
- 1);
1461 if (isize
>= required
)
1463 /* yes, we have enough space and can proceed */
1465 /* adjust counter so that the loop will start by skipping the proper
1466 * amount of leading bytes in the first significant word
1468 byte b
= (ossize
% MP_WBYTES
);
1470 if (isize
> required
)
1471 { /* fill initials words with zero */
1472 mpzero(isize
-required
, idata
);
1473 idata
+= isize
-required
;
1498 int hs2ip(mpw
* idata
, size_t isize
, const char* hsdata
, size_t hssize
)
1500 size_t required
= MP_NIBBLES_TO_WORDS(hssize
+ MP_WNIBBLES
- 1);
1502 if (isize
>= required
)
1507 if (isize
> required
)
1508 { /* fill initial words with zero */
1509 for (i
= required
; i
< isize
; i
++)
1515 register size_t chunk
= hssize
& (MP_WNIBBLES
- 1);
1518 if (chunk
== 0) chunk
= MP_WNIBBLES
;
1520 for (i
= 0; i
< chunk
; i
++)
1524 if (ch
>= '0' && ch
<= '9')
1526 else if (ch
>= 'A' && ch
<= 'F')
1527 w
+= (ch
- 'A') + 10;
1528 else if (ch
>= 'a' && ch
<= 'f')
1529 w
+= (ch
- 'a') + 10;