No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / heimdal / lib / hcrypto / imath / imath.c
blob96b732117f613ce70184be27b7d89e0f78386da2
1 /*
2 Name: imath.c
3 Purpose: Arbitrary precision integer arithmetic routines.
4 Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/>
5 Info: $Id: imath.c,v 1.1 2008/03/22 09:42:41 mlelstv Exp $
7 Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.
9 Permission is hereby granted, free of charge, to any person
10 obtaining a copy of this software and associated documentation files
11 (the "Software"), to deal in the Software without restriction,
12 including without limitation the rights to use, copy, modify, merge,
13 publish, distribute, sublicense, and/or sell copies of the Software,
14 and to permit persons to whom the Software is furnished to do so,
15 subject to the following conditions:
17 The above copyright notice and this permission notice shall be
18 included in all copies or substantial portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
24 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
30 #include "imath.h"
32 #if DEBUG
33 #include <stdio.h>
34 #endif
36 #include <stdlib.h>
37 #include <string.h>
38 #include <ctype.h>
40 #include <assert.h>
42 #if DEBUG
43 #define static
44 #endif
46 /* {{{ Constants */
48 const mp_result MP_OK = 0; /* no error, all is well */
49 const mp_result MP_FALSE = 0; /* boolean false */
50 const mp_result MP_TRUE = -1; /* boolean true */
51 const mp_result MP_MEMORY = -2; /* out of memory */
52 const mp_result MP_RANGE = -3; /* argument out of range */
53 const mp_result MP_UNDEF = -4; /* result undefined */
54 const mp_result MP_TRUNC = -5; /* output truncated */
55 const mp_result MP_BADARG = -6; /* invalid null argument */
57 const mp_sign MP_NEG = 1; /* value is strictly negative */
58 const mp_sign MP_ZPOS = 0; /* value is non-negative */
60 static const char *s_unknown_err = "unknown result code";
61 static const char *s_error_msg[] = {
62 "error code 0",
63 "boolean true",
64 "out of memory",
65 "argument out of range",
66 "result undefined",
67 "output truncated",
68 "invalid null argument",
69 NULL
72 /* }}} */
74 /* Argument checking macros
75 Use CHECK() where a return value is required; NRCHECK() elsewhere */
76 #define CHECK(TEST) assert(TEST)
77 #define NRCHECK(TEST) assert(TEST)
79 /* {{{ Logarithm table for computing output sizes */
81 /* The ith entry of this table gives the value of log_i(2).
83 An integer value n requires ceil(log_i(n)) digits to be represented
84 in base i. Since it is easy to compute lg(n), by counting bits, we
85 can compute log_i(n) = lg(n) * log_i(2).
87 The use of this table eliminates a dependency upon linkage against
88 the standard math libraries.
90 static const double s_log2[] = {
91 0.000000000, 0.000000000, 1.000000000, 0.630929754, /* 0 1 2 3 */
92 0.500000000, 0.430676558, 0.386852807, 0.356207187, /* 4 5 6 7 */
93 0.333333333, 0.315464877, 0.301029996, 0.289064826, /* 8 9 10 11 */
94 0.278942946, 0.270238154, 0.262649535, 0.255958025, /* 12 13 14 15 */
95 0.250000000, 0.244650542, 0.239812467, 0.235408913, /* 16 17 18 19 */
96 0.231378213, 0.227670249, 0.224243824, 0.221064729, /* 20 21 22 23 */
97 0.218104292, 0.215338279, 0.212746054, 0.210309918, /* 24 25 26 27 */
98 0.208014598, 0.205846832, 0.203795047, 0.201849087, /* 28 29 30 31 */
99 0.200000000, 0.198239863, 0.196561632, 0.194959022, /* 32 33 34 35 */
100 0.193426404, 0.191958720, 0.190551412, 0.189200360, /* 36 37 38 39 */
101 0.187901825, 0.186652411, 0.185449023, 0.184288833, /* 40 41 42 43 */
102 0.183169251, 0.182087900, 0.181042597, 0.180031327, /* 44 45 46 47 */
103 0.179052232, 0.178103594, 0.177183820, 0.176291434, /* 48 49 50 51 */
104 0.175425064, 0.174583430, 0.173765343, 0.172969690, /* 52 53 54 55 */
105 0.172195434, 0.171441601, 0.170707280, 0.169991616, /* 56 57 58 59 */
106 0.169293808, 0.168613099, 0.167948779, 0.167300179, /* 60 61 62 63 */
107 0.166666667
110 /* }}} */
111 /* {{{ Various macros */
113 /* Return the number of digits needed to represent a static value */
114 #define MP_VALUE_DIGITS(V) \
115 ((sizeof(V)+(sizeof(mp_digit)-1))/sizeof(mp_digit))
117 /* Round precision P to nearest word boundary */
118 #define ROUND_PREC(P) ((mp_size)(2*(((P)+1)/2)))
120 /* Set array P of S digits to zero */
121 #define ZERO(P, S) \
122 do{mp_size i__=(S)*sizeof(mp_digit);mp_digit *p__=(P);memset(p__,0,i__);}while(0)
124 /* Copy S digits from array P to array Q */
125 #define COPY(P, Q, S) \
126 do{mp_size i__=(S)*sizeof(mp_digit);mp_digit *p__=(P),*q__=(Q);\
127 memcpy(q__,p__,i__);}while(0)
129 /* Reverse N elements of type T in array A */
130 #define REV(T, A, N) \
131 do{T *u_=(A),*v_=u_+(N)-1;while(u_<v_){T xch=*u_;*u_++=*v_;*v_--=xch;}}while(0)
133 #if TRACEABLE_CLAMP
134 #define CLAMP(Z) s_clamp(Z)
135 #else
136 #define CLAMP(Z) \
137 do{mp_int z_=(Z);mp_size uz_=MP_USED(z_);mp_digit *dz_=MP_DIGITS(z_)+uz_-1;\
138 while(uz_ > 1 && (*dz_-- == 0)) --uz_;MP_USED(z_)=uz_;}while(0)
139 #endif
141 #define MIN(A, B) ((B)<(A)?(B):(A))
142 #define MAX(A, B) ((B)>(A)?(B):(A))
143 #define SWAP(T, A, B) do{T t_=(A);A=(B);B=t_;}while(0)
145 #define TEMP(K) (temp + (K))
146 #define SETUP(E, C) \
147 do{if((res = (E)) != MP_OK) goto CLEANUP; ++(C);}while(0)
149 #define CMPZ(Z) \
150 (((Z)->used==1&&(Z)->digits[0]==0)?0:((Z)->sign==MP_NEG)?-1:1)
152 #define UMUL(X, Y, Z) \
153 do{mp_size ua_=MP_USED(X),ub_=MP_USED(Y);mp_size o_=ua_+ub_;\
154 ZERO(MP_DIGITS(Z),o_);\
155 (void) s_kmul(MP_DIGITS(X),MP_DIGITS(Y),MP_DIGITS(Z),ua_,ub_);\
156 MP_USED(Z)=o_;CLAMP(Z);}while(0)
158 #define USQR(X, Z) \
159 do{mp_size ua_=MP_USED(X),o_=ua_+ua_;ZERO(MP_DIGITS(Z),o_);\
160 (void) s_ksqr(MP_DIGITS(X),MP_DIGITS(Z),ua_);MP_USED(Z)=o_;CLAMP(Z);}while(0)
162 #define UPPER_HALF(W) ((mp_word)((W) >> MP_DIGIT_BIT))
163 #define LOWER_HALF(W) ((mp_digit)(W))
164 #define HIGH_BIT_SET(W) ((W) >> (MP_WORD_BIT - 1))
165 #define ADD_WILL_OVERFLOW(W, V) ((MP_WORD_MAX - (V)) < (W))
167 /* }}} */
168 /* {{{ Default configuration settings */
170 /* Default number of digits allocated to a new mp_int */
171 #if IMATH_TEST
172 mp_size default_precision = MP_DEFAULT_PREC;
173 #else
174 static const mp_size default_precision = MP_DEFAULT_PREC;
175 #endif
177 /* Minimum number of digits to invoke recursive multiply */
178 #if IMATH_TEST
179 mp_size multiply_threshold = MP_MULT_THRESH;
180 #else
181 static const mp_size multiply_threshold = MP_MULT_THRESH;
182 #endif
184 /* }}} */
186 /* Allocate a buffer of (at least) num digits, or return
187 NULL if that couldn't be done. */
188 static mp_digit *s_alloc(mp_size num);
190 /* Release a buffer of digits allocated by s_alloc(). */
191 static void s_free(void *ptr);
193 /* Insure that z has at least min digits allocated, resizing if
194 necessary. Returns true if successful, false if out of memory. */
195 static int s_pad(mp_int z, mp_size min);
197 /* Normalize by removing leading zeroes (except when z = 0) */
198 #if TRACEABLE_CLAMP
199 static void s_clamp(mp_int z);
200 #endif
202 /* Fill in a "fake" mp_int on the stack with a given value */
203 static void s_fake(mp_int z, int value, mp_digit vbuf[]);
205 /* Compare two runs of digits of given length, returns <0, 0, >0 */
206 static int s_cdig(mp_digit *da, mp_digit *db, mp_size len);
208 /* Pack the unsigned digits of v into array t */
209 static int s_vpack(int v, mp_digit t[]);
211 /* Compare magnitudes of a and b, returns <0, 0, >0 */
212 static int s_ucmp(mp_int a, mp_int b);
214 /* Compare magnitudes of a and v, returns <0, 0, >0 */
215 static int s_vcmp(mp_int a, int v);
217 /* Unsigned magnitude addition; assumes dc is big enough.
218 Carry out is returned (no memory allocated). */
219 static mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc,
220 mp_size size_a, mp_size size_b);
222 /* Unsigned magnitude subtraction. Assumes dc is big enough. */
223 static void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc,
224 mp_size size_a, mp_size size_b);
226 /* Unsigned recursive multiplication. Assumes dc is big enough. */
227 static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
228 mp_size size_a, mp_size size_b);
230 /* Unsigned magnitude multiplication. Assumes dc is big enough. */
231 static void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc,
232 mp_size size_a, mp_size size_b);
234 /* Unsigned recursive squaring. Assumes dc is big enough. */
235 static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a);
237 /* Unsigned magnitude squaring. Assumes dc is big enough. */
238 static void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a);
240 /* Single digit addition. Assumes a is big enough. */
241 static void s_dadd(mp_int a, mp_digit b);
243 /* Single digit multiplication. Assumes a is big enough. */
244 static void s_dmul(mp_int a, mp_digit b);
246 /* Single digit multiplication on buffers; assumes dc is big enough. */
247 static void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc,
248 mp_size size_a);
250 /* Single digit division. Replaces a with the quotient,
251 returns the remainder. */
252 static mp_digit s_ddiv(mp_int a, mp_digit b);
254 /* Quick division by a power of 2, replaces z (no allocation) */
255 static void s_qdiv(mp_int z, mp_size p2);
257 /* Quick remainder by a power of 2, replaces z (no allocation) */
258 static void s_qmod(mp_int z, mp_size p2);
260 /* Quick multiplication by a power of 2, replaces z.
261 Allocates if necessary; returns false in case this fails. */
262 static int s_qmul(mp_int z, mp_size p2);
264 /* Quick subtraction from a power of 2, replaces z.
265 Allocates if necessary; returns false in case this fails. */
266 static int s_qsub(mp_int z, mp_size p2);
268 /* Return maximum k such that 2^k divides z. */
269 static int s_dp2k(mp_int z);
271 /* Return k >= 0 such that z = 2^k, or -1 if there is no such k. */
272 static int s_isp2(mp_int z);
274 /* Set z to 2^k. May allocate; returns false in case this fails. */
275 static int s_2expt(mp_int z, int k);
277 /* Normalize a and b for division, returns normalization constant */
278 static int s_norm(mp_int a, mp_int b);
280 /* Compute constant mu for Barrett reduction, given modulus m, result
281 replaces z, m is untouched. */
282 static mp_result s_brmu(mp_int z, mp_int m);
284 /* Reduce a modulo m, using Barrett's algorithm. */
285 static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2);
287 /* Modular exponentiation, using Barrett reduction */
288 static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c);
290 /* Unsigned magnitude division. Assumes |a| > |b|. Allocates
291 temporaries; overwrites a with quotient, b with remainder. */
292 static mp_result s_udiv(mp_int a, mp_int b);
294 /* Compute the number of digits in radix r required to represent the
295 given value. Does not account for sign flags, terminators, etc. */
296 static int s_outlen(mp_int z, mp_size r);
298 /* Guess how many digits of precision will be needed to represent a
299 radix r value of the specified number of digits. Returns a value
300 guaranteed to be no smaller than the actual number required. */
301 static mp_size s_inlen(int len, mp_size r);
303 /* Convert a character to a digit value in radix r, or
304 -1 if out of range */
305 static int s_ch2val(char c, int r);
307 /* Convert a digit value to a character */
308 static char s_val2ch(int v, int caps);
310 /* Take 2's complement of a buffer in place */
311 static void s_2comp(unsigned char *buf, int len);
313 /* Convert a value to binary, ignoring sign. On input, *limpos is the
314 bound on how many bytes should be written to buf; on output, *limpos
315 is set to the number of bytes actually written. */
316 static mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad);
318 #if DEBUG
319 /* Dump a representation of the mp_int to standard output */
320 void s_print(char *tag, mp_int z);
321 void s_print_buf(char *tag, mp_digit *buf, mp_size num);
322 #endif
324 /* {{{ mp_int_init(z) */
326 mp_result mp_int_init(mp_int z)
328 if(z == NULL)
329 return MP_BADARG;
331 z->single = 0;
332 z->digits = &(z->single);
333 z->alloc = 1;
334 z->used = 1;
335 z->sign = MP_ZPOS;
337 return MP_OK;
340 /* }}} */
342 /* {{{ mp_int_alloc() */
344 mp_int mp_int_alloc(void)
346 mp_int out = malloc(sizeof(mpz_t));
348 if(out != NULL)
349 mp_int_init(out);
351 return out;
354 /* }}} */
356 /* {{{ mp_int_init_size(z, prec) */
358 mp_result mp_int_init_size(mp_int z, mp_size prec)
360 CHECK(z != NULL);
362 if(prec == 0)
363 prec = default_precision;
364 else if(prec == 1)
365 return mp_int_init(z);
366 else
367 prec = (mp_size) ROUND_PREC(prec);
369 if((MP_DIGITS(z) = s_alloc(prec)) == NULL)
370 return MP_MEMORY;
372 z->digits[0] = 0;
373 MP_USED(z) = 1;
374 MP_ALLOC(z) = prec;
375 MP_SIGN(z) = MP_ZPOS;
377 return MP_OK;
380 /* }}} */
382 /* {{{ mp_int_init_copy(z, old) */
384 mp_result mp_int_init_copy(mp_int z, mp_int old)
386 mp_result res;
387 mp_size uold;
389 CHECK(z != NULL && old != NULL);
391 uold = MP_USED(old);
392 if(uold == 1) {
393 mp_int_init(z);
395 else {
396 mp_size target = MAX(uold, default_precision);
398 if((res = mp_int_init_size(z, target)) != MP_OK)
399 return res;
402 MP_USED(z) = uold;
403 MP_SIGN(z) = MP_SIGN(old);
404 COPY(MP_DIGITS(old), MP_DIGITS(z), uold);
406 return MP_OK;
409 /* }}} */
411 /* {{{ mp_int_init_value(z, value) */
413 mp_result mp_int_init_value(mp_int z, int value)
415 mpz_t vtmp;
416 mp_digit vbuf[MP_VALUE_DIGITS(value)];
418 s_fake(&vtmp, value, vbuf);
419 return mp_int_init_copy(z, &vtmp);
422 /* }}} */
424 /* {{{ mp_int_set_value(z, value) */
426 mp_result mp_int_set_value(mp_int z, int value)
428 mpz_t vtmp;
429 mp_digit vbuf[MP_VALUE_DIGITS(value)];
431 s_fake(&vtmp, value, vbuf);
432 return mp_int_copy(&vtmp, z);
435 /* }}} */
437 /* {{{ mp_int_clear(z) */
439 void mp_int_clear(mp_int z)
441 if(z == NULL)
442 return;
444 if(MP_DIGITS(z) != NULL) {
445 if((void *) MP_DIGITS(z) != (void *) z)
446 s_free(MP_DIGITS(z));
448 MP_DIGITS(z) = NULL;
452 /* }}} */
454 /* {{{ mp_int_free(z) */
456 void mp_int_free(mp_int z)
458 NRCHECK(z != NULL);
460 mp_int_clear(z);
461 free(z); /* note: NOT s_free() */
464 /* }}} */
466 /* {{{ mp_int_copy(a, c) */
468 mp_result mp_int_copy(mp_int a, mp_int c)
470 CHECK(a != NULL && c != NULL);
472 if(a != c) {
473 mp_size ua = MP_USED(a);
474 mp_digit *da, *dc;
476 if(!s_pad(c, ua))
477 return MP_MEMORY;
479 da = MP_DIGITS(a); dc = MP_DIGITS(c);
480 COPY(da, dc, ua);
482 MP_USED(c) = ua;
483 MP_SIGN(c) = MP_SIGN(a);
486 return MP_OK;
489 /* }}} */
491 /* {{{ mp_int_swap(a, c) */
493 void mp_int_swap(mp_int a, mp_int c)
495 if(a != c) {
496 mpz_t tmp = *a;
498 *a = *c;
499 *c = tmp;
503 /* }}} */
505 /* {{{ mp_int_zero(z) */
507 void mp_int_zero(mp_int z)
509 NRCHECK(z != NULL);
511 z->digits[0] = 0;
512 MP_USED(z) = 1;
513 MP_SIGN(z) = MP_ZPOS;
516 /* }}} */
518 /* {{{ mp_int_abs(a, c) */
520 mp_result mp_int_abs(mp_int a, mp_int c)
522 mp_result res;
524 CHECK(a != NULL && c != NULL);
526 if((res = mp_int_copy(a, c)) != MP_OK)
527 return res;
529 MP_SIGN(c) = MP_ZPOS;
530 return MP_OK;
533 /* }}} */
535 /* {{{ mp_int_neg(a, c) */
537 mp_result mp_int_neg(mp_int a, mp_int c)
539 mp_result res;
541 CHECK(a != NULL && c != NULL);
543 if((res = mp_int_copy(a, c)) != MP_OK)
544 return res;
546 if(CMPZ(c) != 0)
547 MP_SIGN(c) = 1 - MP_SIGN(a);
549 return MP_OK;
552 /* }}} */
554 /* {{{ mp_int_add(a, b, c) */
556 mp_result mp_int_add(mp_int a, mp_int b, mp_int c)
558 mp_size ua, ub, uc, max;
560 CHECK(a != NULL && b != NULL && c != NULL);
562 ua = MP_USED(a); ub = MP_USED(b); uc = MP_USED(c);
563 max = MAX(ua, ub);
565 if(MP_SIGN(a) == MP_SIGN(b)) {
566 /* Same sign -- add magnitudes, preserve sign of addends */
567 mp_digit carry;
569 if(!s_pad(c, max))
570 return MP_MEMORY;
572 carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub);
573 uc = max;
575 if(carry) {
576 if(!s_pad(c, max + 1))
577 return MP_MEMORY;
579 c->digits[max] = carry;
580 ++uc;
583 MP_USED(c) = uc;
584 MP_SIGN(c) = MP_SIGN(a);
587 else {
588 /* Different signs -- subtract magnitudes, preserve sign of greater */
589 mp_int x, y;
590 int cmp = s_ucmp(a, b); /* magnitude comparision, sign ignored */
592 /* Set x to max(a, b), y to min(a, b) to simplify later code */
593 if(cmp >= 0) {
594 x = a; y = b;
596 else {
597 x = b; y = a;
600 if(!s_pad(c, MP_USED(x)))
601 return MP_MEMORY;
603 /* Subtract smaller from larger */
604 s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y));
605 MP_USED(c) = MP_USED(x);
606 CLAMP(c);
608 /* Give result the sign of the larger */
609 MP_SIGN(c) = MP_SIGN(x);
612 return MP_OK;
615 /* }}} */
617 /* {{{ mp_int_add_value(a, value, c) */
619 mp_result mp_int_add_value(mp_int a, int value, mp_int c)
621 mpz_t vtmp;
622 mp_digit vbuf[MP_VALUE_DIGITS(value)];
624 s_fake(&vtmp, value, vbuf);
626 return mp_int_add(a, &vtmp, c);
629 /* }}} */
631 /* {{{ mp_int_sub(a, b, c) */
633 mp_result mp_int_sub(mp_int a, mp_int b, mp_int c)
635 mp_size ua, ub, uc, max;
637 CHECK(a != NULL && b != NULL && c != NULL);
639 ua = MP_USED(a); ub = MP_USED(b); uc = MP_USED(c);
640 max = MAX(ua, ub);
642 if(MP_SIGN(a) != MP_SIGN(b)) {
643 /* Different signs -- add magnitudes and keep sign of a */
644 mp_digit carry;
646 if(!s_pad(c, max))
647 return MP_MEMORY;
649 carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub);
650 uc = max;
652 if(carry) {
653 if(!s_pad(c, max + 1))
654 return MP_MEMORY;
656 c->digits[max] = carry;
657 ++uc;
660 MP_USED(c) = uc;
661 MP_SIGN(c) = MP_SIGN(a);
664 else {
665 /* Same signs -- subtract magnitudes */
666 mp_int x, y;
667 mp_sign osign;
668 int cmp = s_ucmp(a, b);
670 if(!s_pad(c, max))
671 return MP_MEMORY;
673 if(cmp >= 0) {
674 x = a; y = b; osign = MP_ZPOS;
676 else {
677 x = b; y = a; osign = MP_NEG;
680 if(MP_SIGN(a) == MP_NEG && cmp != 0)
681 osign = 1 - osign;
683 s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y));
684 MP_USED(c) = MP_USED(x);
685 CLAMP(c);
687 MP_SIGN(c) = osign;
690 return MP_OK;
693 /* }}} */
695 /* {{{ mp_int_sub_value(a, value, c) */
697 mp_result mp_int_sub_value(mp_int a, int value, mp_int c)
699 mpz_t vtmp;
700 mp_digit vbuf[MP_VALUE_DIGITS(value)];
702 s_fake(&vtmp, value, vbuf);
704 return mp_int_sub(a, &vtmp, c);
707 /* }}} */
709 /* {{{ mp_int_mul(a, b, c) */
711 mp_result mp_int_mul(mp_int a, mp_int b, mp_int c)
713 mp_digit *out;
714 mp_size osize, ua, ub, p = 0;
715 mp_sign osign;
717 CHECK(a != NULL && b != NULL && c != NULL);
719 /* If either input is zero, we can shortcut multiplication */
720 if(mp_int_compare_zero(a) == 0 || mp_int_compare_zero(b) == 0) {
721 mp_int_zero(c);
722 return MP_OK;
725 /* Output is positive if inputs have same sign, otherwise negative */
726 osign = (MP_SIGN(a) == MP_SIGN(b)) ? MP_ZPOS : MP_NEG;
728 /* If the output is not identical to any of the inputs, we'll write
729 the results directly; otherwise, allocate a temporary space. */
730 ua = MP_USED(a); ub = MP_USED(b);
731 osize = MAX(ua, ub);
732 osize = 4 * ((osize + 1) / 2);
734 if(c == a || c == b) {
735 p = ROUND_PREC(osize);
736 p = MAX(p, default_precision);
738 if((out = s_alloc(p)) == NULL)
739 return MP_MEMORY;
741 else {
742 if(!s_pad(c, osize))
743 return MP_MEMORY;
745 out = MP_DIGITS(c);
747 ZERO(out, osize);
749 if(!s_kmul(MP_DIGITS(a), MP_DIGITS(b), out, ua, ub))
750 return MP_MEMORY;
752 /* If we allocated a new buffer, get rid of whatever memory c was
753 already using, and fix up its fields to reflect that.
755 if(out != MP_DIGITS(c)) {
756 if((void *) MP_DIGITS(c) != (void *) c)
757 s_free(MP_DIGITS(c));
758 MP_DIGITS(c) = out;
759 MP_ALLOC(c) = p;
762 MP_USED(c) = osize; /* might not be true, but we'll fix it ... */
763 CLAMP(c); /* ... right here */
764 MP_SIGN(c) = osign;
766 return MP_OK;
769 /* }}} */
771 /* {{{ mp_int_mul_value(a, value, c) */
773 mp_result mp_int_mul_value(mp_int a, int value, mp_int c)
775 mpz_t vtmp;
776 mp_digit vbuf[MP_VALUE_DIGITS(value)];
778 s_fake(&vtmp, value, vbuf);
780 return mp_int_mul(a, &vtmp, c);
783 /* }}} */
785 /* {{{ mp_int_mul_pow2(a, p2, c) */
787 mp_result mp_int_mul_pow2(mp_int a, int p2, mp_int c)
789 mp_result res;
790 CHECK(a != NULL && c != NULL && p2 >= 0);
792 if((res = mp_int_copy(a, c)) != MP_OK)
793 return res;
795 if(s_qmul(c, (mp_size) p2))
796 return MP_OK;
797 else
798 return MP_MEMORY;
801 /* }}} */
803 /* {{{ mp_int_sqr(a, c) */
805 mp_result mp_int_sqr(mp_int a, mp_int c)
807 mp_digit *out;
808 mp_size osize, p = 0;
810 CHECK(a != NULL && c != NULL);
812 /* Get a temporary buffer big enough to hold the result */
813 osize = (mp_size) 4 * ((MP_USED(a) + 1) / 2);
814 if(a == c) {
815 p = ROUND_PREC(osize);
816 p = MAX(p, default_precision);
818 if((out = s_alloc(p)) == NULL)
819 return MP_MEMORY;
821 else {
822 if(!s_pad(c, osize))
823 return MP_MEMORY;
825 out = MP_DIGITS(c);
827 ZERO(out, osize);
829 s_ksqr(MP_DIGITS(a), out, MP_USED(a));
831 /* Get rid of whatever memory c was already using, and fix up its
832 fields to reflect the new digit array it's using
834 if(out != MP_DIGITS(c)) {
835 if((void *) MP_DIGITS(c) != (void *) c)
836 s_free(MP_DIGITS(c));
837 MP_DIGITS(c) = out;
838 MP_ALLOC(c) = p;
841 MP_USED(c) = osize; /* might not be true, but we'll fix it ... */
842 CLAMP(c); /* ... right here */
843 MP_SIGN(c) = MP_ZPOS;
845 return MP_OK;
848 /* }}} */
850 /* {{{ mp_int_div(a, b, q, r) */
852 mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r)
854 int cmp, last = 0, lg;
855 mp_result res = MP_OK;
856 mpz_t temp[2];
857 mp_int qout, rout;
858 mp_sign sa = MP_SIGN(a), sb = MP_SIGN(b);
860 CHECK(a != NULL && b != NULL && q != r);
862 if(CMPZ(b) == 0)
863 return MP_UNDEF;
864 else if((cmp = s_ucmp(a, b)) < 0) {
865 /* If |a| < |b|, no division is required:
866 q = 0, r = a
868 if(r && (res = mp_int_copy(a, r)) != MP_OK)
869 return res;
871 if(q)
872 mp_int_zero(q);
874 return MP_OK;
876 else if(cmp == 0) {
877 /* If |a| = |b|, no division is required:
878 q = 1 or -1, r = 0
880 if(r)
881 mp_int_zero(r);
883 if(q) {
884 mp_int_zero(q);
885 q->digits[0] = 1;
887 if(sa != sb)
888 MP_SIGN(q) = MP_NEG;
891 return MP_OK;
894 /* When |a| > |b|, real division is required. We need someplace to
895 store quotient and remainder, but q and r are allowed to be NULL
896 or to overlap with the inputs.
898 if((lg = s_isp2(b)) < 0) {
899 if(q && b != q && (res = mp_int_copy(a, q)) == MP_OK) {
900 qout = q;
902 else {
903 qout = TEMP(last);
904 SETUP(mp_int_init_copy(TEMP(last), a), last);
907 if(r && a != r && (res = mp_int_copy(b, r)) == MP_OK) {
908 rout = r;
910 else {
911 rout = TEMP(last);
912 SETUP(mp_int_init_copy(TEMP(last), b), last);
915 if((res = s_udiv(qout, rout)) != MP_OK) goto CLEANUP;
917 else {
918 if(q && (res = mp_int_copy(a, q)) != MP_OK) goto CLEANUP;
919 if(r && (res = mp_int_copy(a, r)) != MP_OK) goto CLEANUP;
921 if(q) s_qdiv(q, (mp_size) lg); qout = q;
922 if(r) s_qmod(r, (mp_size) lg); rout = r;
925 /* Recompute signs for output */
926 if(rout) {
927 MP_SIGN(rout) = sa;
928 if(CMPZ(rout) == 0)
929 MP_SIGN(rout) = MP_ZPOS;
931 if(qout) {
932 MP_SIGN(qout) = (sa == sb) ? MP_ZPOS : MP_NEG;
933 if(CMPZ(qout) == 0)
934 MP_SIGN(qout) = MP_ZPOS;
937 if(q && (res = mp_int_copy(qout, q)) != MP_OK) goto CLEANUP;
938 if(r && (res = mp_int_copy(rout, r)) != MP_OK) goto CLEANUP;
940 CLEANUP:
941 while(--last >= 0)
942 mp_int_clear(TEMP(last));
944 return res;
947 /* }}} */
949 /* {{{ mp_int_mod(a, m, c) */
951 mp_result mp_int_mod(mp_int a, mp_int m, mp_int c)
953 mp_result res;
954 mpz_t tmp;
955 mp_int out;
957 if(m == c) {
958 mp_int_init(&tmp);
959 out = &tmp;
961 else {
962 out = c;
965 if((res = mp_int_div(a, m, NULL, out)) != MP_OK)
966 goto CLEANUP;
968 if(CMPZ(out) < 0)
969 res = mp_int_add(out, m, c);
970 else
971 res = mp_int_copy(out, c);
973 CLEANUP:
974 if(out != c)
975 mp_int_clear(&tmp);
977 return res;
980 /* }}} */
982 /* {{{ mp_int_div_value(a, value, q, r) */
984 mp_result mp_int_div_value(mp_int a, int value, mp_int q, int *r)
986 mpz_t vtmp, rtmp;
987 mp_digit vbuf[MP_VALUE_DIGITS(value)];
988 mp_result res;
990 mp_int_init(&rtmp);
991 s_fake(&vtmp, value, vbuf);
993 if((res = mp_int_div(a, &vtmp, q, &rtmp)) != MP_OK)
994 goto CLEANUP;
996 if(r)
997 (void) mp_int_to_int(&rtmp, r); /* can't fail */
999 CLEANUP:
1000 mp_int_clear(&rtmp);
1001 return res;
1004 /* }}} */
1006 /* {{{ mp_int_div_pow2(a, p2, q, r) */
1008 mp_result mp_int_div_pow2(mp_int a, int p2, mp_int q, mp_int r)
1010 mp_result res = MP_OK;
1012 CHECK(a != NULL && p2 >= 0 && q != r);
1014 if(q != NULL && (res = mp_int_copy(a, q)) == MP_OK)
1015 s_qdiv(q, (mp_size) p2);
1017 if(res == MP_OK && r != NULL && (res = mp_int_copy(a, r)) == MP_OK)
1018 s_qmod(r, (mp_size) p2);
1020 return res;
1023 /* }}} */
1025 /* {{{ mp_int_expt(a, b, c) */
1027 mp_result mp_int_expt(mp_int a, int b, mp_int c)
1029 mpz_t t;
1030 mp_result res;
1031 unsigned int v = abs(b);
1033 CHECK(b >= 0 && c != NULL);
1035 if((res = mp_int_init_copy(&t, a)) != MP_OK)
1036 return res;
1038 (void) mp_int_set_value(c, 1);
1039 while(v != 0) {
1040 if(v & 1) {
1041 if((res = mp_int_mul(c, &t, c)) != MP_OK)
1042 goto CLEANUP;
1045 v >>= 1;
1046 if(v == 0) break;
1048 if((res = mp_int_sqr(&t, &t)) != MP_OK)
1049 goto CLEANUP;
1052 CLEANUP:
1053 mp_int_clear(&t);
1054 return res;
1057 /* }}} */
1059 /* {{{ mp_int_expt_value(a, b, c) */
1061 mp_result mp_int_expt_value(int a, int b, mp_int c)
1063 mpz_t t;
1064 mp_result res;
1065 unsigned int v = abs(b);
1067 CHECK(b >= 0 && c != NULL);
1069 if((res = mp_int_init_value(&t, a)) != MP_OK)
1070 return res;
1072 (void) mp_int_set_value(c, 1);
1073 while(v != 0) {
1074 if(v & 1) {
1075 if((res = mp_int_mul(c, &t, c)) != MP_OK)
1076 goto CLEANUP;
1079 v >>= 1;
1080 if(v == 0) break;
1082 if((res = mp_int_sqr(&t, &t)) != MP_OK)
1083 goto CLEANUP;
1086 CLEANUP:
1087 mp_int_clear(&t);
1088 return res;
1091 /* }}} */
1093 /* {{{ mp_int_compare(a, b) */
1095 int mp_int_compare(mp_int a, mp_int b)
1097 mp_sign sa;
1099 CHECK(a != NULL && b != NULL);
1101 sa = MP_SIGN(a);
1102 if(sa == MP_SIGN(b)) {
1103 int cmp = s_ucmp(a, b);
1105 /* If they're both zero or positive, the normal comparison
1106 applies; if both negative, the sense is reversed. */
1107 if(sa == MP_ZPOS)
1108 return cmp;
1109 else
1110 return -cmp;
1113 else {
1114 if(sa == MP_ZPOS)
1115 return 1;
1116 else
1117 return -1;
1121 /* }}} */
1123 /* {{{ mp_int_compare_unsigned(a, b) */
1125 int mp_int_compare_unsigned(mp_int a, mp_int b)
1127 NRCHECK(a != NULL && b != NULL);
1129 return s_ucmp(a, b);
1132 /* }}} */
1134 /* {{{ mp_int_compare_zero(z) */
1136 int mp_int_compare_zero(mp_int z)
1138 NRCHECK(z != NULL);
1140 if(MP_USED(z) == 1 && z->digits[0] == 0)
1141 return 0;
1142 else if(MP_SIGN(z) == MP_ZPOS)
1143 return 1;
1144 else
1145 return -1;
1148 /* }}} */
1150 /* {{{ mp_int_compare_value(z, value) */
1152 int mp_int_compare_value(mp_int z, int value)
1154 mp_sign vsign = (value < 0) ? MP_NEG : MP_ZPOS;
1155 int cmp;
1157 CHECK(z != NULL);
1159 if(vsign == MP_SIGN(z)) {
1160 cmp = s_vcmp(z, value);
1162 if(vsign == MP_ZPOS)
1163 return cmp;
1164 else
1165 return -cmp;
1167 else {
1168 if(value < 0)
1169 return 1;
1170 else
1171 return -1;
1175 /* }}} */
1177 /* {{{ mp_int_exptmod(a, b, m, c) */
1179 mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c)
1181 mp_result res;
1182 mp_size um;
1183 mpz_t temp[3];
1184 mp_int s;
1185 int last = 0;
1187 CHECK(a != NULL && b != NULL && c != NULL && m != NULL);
1189 /* Zero moduli and negative exponents are not considered. */
1190 if(CMPZ(m) == 0)
1191 return MP_UNDEF;
1192 if(CMPZ(b) < 0)
1193 return MP_RANGE;
1195 um = MP_USED(m);
1196 SETUP(mp_int_init_size(TEMP(0), 2 * um), last);
1197 SETUP(mp_int_init_size(TEMP(1), 2 * um), last);
1199 if(c == b || c == m) {
1200 SETUP(mp_int_init_size(TEMP(2), 2 * um), last);
1201 s = TEMP(2);
1203 else {
1204 s = c;
1207 if((res = mp_int_mod(a, m, TEMP(0))) != MP_OK) goto CLEANUP;
1209 if((res = s_brmu(TEMP(1), m)) != MP_OK) goto CLEANUP;
1211 if((res = s_embar(TEMP(0), b, m, TEMP(1), s)) != MP_OK)
1212 goto CLEANUP;
1214 res = mp_int_copy(s, c);
1216 CLEANUP:
1217 while(--last >= 0)
1218 mp_int_clear(TEMP(last));
1220 return res;
1223 /* }}} */
1225 /* {{{ mp_int_exptmod_evalue(a, value, m, c) */
1227 mp_result mp_int_exptmod_evalue(mp_int a, int value, mp_int m, mp_int c)
1229 mpz_t vtmp;
1230 mp_digit vbuf[MP_VALUE_DIGITS(value)];
1232 s_fake(&vtmp, value, vbuf);
1234 return mp_int_exptmod(a, &vtmp, m, c);
1237 /* }}} */
1239 /* {{{ mp_int_exptmod_bvalue(v, b, m, c) */
1241 mp_result mp_int_exptmod_bvalue(int value, mp_int b,
1242 mp_int m, mp_int c)
1244 mpz_t vtmp;
1245 mp_digit vbuf[MP_VALUE_DIGITS(value)];
1247 s_fake(&vtmp, value, vbuf);
1249 return mp_int_exptmod(&vtmp, b, m, c);
1252 /* }}} */
1254 /* {{{ mp_int_exptmod_known(a, b, m, mu, c) */
1256 mp_result mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c)
1258 mp_result res;
1259 mp_size um;
1260 mpz_t temp[2];
1261 mp_int s;
1262 int last = 0;
1264 CHECK(a && b && m && c);
1266 /* Zero moduli and negative exponents are not considered. */
1267 if(CMPZ(m) == 0)
1268 return MP_UNDEF;
1269 if(CMPZ(b) < 0)
1270 return MP_RANGE;
1272 um = MP_USED(m);
1273 SETUP(mp_int_init_size(TEMP(0), 2 * um), last);
1275 if(c == b || c == m) {
1276 SETUP(mp_int_init_size(TEMP(1), 2 * um), last);
1277 s = TEMP(1);
1279 else {
1280 s = c;
1283 if((res = mp_int_mod(a, m, TEMP(0))) != MP_OK) goto CLEANUP;
1285 if((res = s_embar(TEMP(0), b, m, mu, s)) != MP_OK)
1286 goto CLEANUP;
1288 res = mp_int_copy(s, c);
1290 CLEANUP:
1291 while(--last >= 0)
1292 mp_int_clear(TEMP(last));
1294 return res;
1297 /* }}} */
1299 /* {{{ mp_int_redux_const(m, c) */
1301 mp_result mp_int_redux_const(mp_int m, mp_int c)
1303 CHECK(m != NULL && c != NULL && m != c);
1305 return s_brmu(c, m);
1308 /* }}} */
1310 /* {{{ mp_int_invmod(a, m, c) */
1312 mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c)
1314 mp_result res;
1315 mp_sign sa;
1316 int last = 0;
1317 mpz_t temp[2];
1319 CHECK(a != NULL && m != NULL && c != NULL);
1321 if(CMPZ(a) == 0 || CMPZ(m) <= 0)
1322 return MP_RANGE;
1324 sa = MP_SIGN(a); /* need this for the result later */
1326 for(last = 0; last < 2; ++last)
1327 mp_int_init(TEMP(last));
1329 if((res = mp_int_egcd(a, m, TEMP(0), TEMP(1), NULL)) != MP_OK)
1330 goto CLEANUP;
1332 if(mp_int_compare_value(TEMP(0), 1) != 0) {
1333 res = MP_UNDEF;
1334 goto CLEANUP;
1337 /* It is first necessary to constrain the value to the proper range */
1338 if((res = mp_int_mod(TEMP(1), m, TEMP(1))) != MP_OK)
1339 goto CLEANUP;
1341 /* Now, if 'a' was originally negative, the value we have is
1342 actually the magnitude of the negative representative; to get the
1343 positive value we have to subtract from the modulus. Otherwise,
1344 the value is okay as it stands.
1346 if(sa == MP_NEG)
1347 res = mp_int_sub(m, TEMP(1), c);
1348 else
1349 res = mp_int_copy(TEMP(1), c);
1351 CLEANUP:
1352 while(--last >= 0)
1353 mp_int_clear(TEMP(last));
1355 return res;
1358 /* }}} */
1360 /* {{{ mp_int_gcd(a, b, c) */
1362 /* Binary GCD algorithm due to Josef Stein, 1961 */
1363 mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c)
1365 int ca, cb, k = 0;
1366 mpz_t u, v, t;
1367 mp_result res;
1369 CHECK(a != NULL && b != NULL && c != NULL);
1371 ca = CMPZ(a);
1372 cb = CMPZ(b);
1373 if(ca == 0 && cb == 0)
1374 return MP_UNDEF;
1375 else if(ca == 0)
1376 return mp_int_abs(b, c);
1377 else if(cb == 0)
1378 return mp_int_abs(a, c);
1380 mp_int_init(&t);
1381 if((res = mp_int_init_copy(&u, a)) != MP_OK)
1382 goto U;
1383 if((res = mp_int_init_copy(&v, b)) != MP_OK)
1384 goto V;
1386 MP_SIGN(&u) = MP_ZPOS; MP_SIGN(&v) = MP_ZPOS;
1388 { /* Divide out common factors of 2 from u and v */
1389 int div2_u = s_dp2k(&u), div2_v = s_dp2k(&v);
1391 k = MIN(div2_u, div2_v);
1392 s_qdiv(&u, (mp_size) k);
1393 s_qdiv(&v, (mp_size) k);
1396 if(mp_int_is_odd(&u)) {
1397 if((res = mp_int_neg(&v, &t)) != MP_OK)
1398 goto CLEANUP;
1400 else {
1401 if((res = mp_int_copy(&u, &t)) != MP_OK)
1402 goto CLEANUP;
1405 for(;;) {
1406 s_qdiv(&t, s_dp2k(&t));
1408 if(CMPZ(&t) > 0) {
1409 if((res = mp_int_copy(&t, &u)) != MP_OK)
1410 goto CLEANUP;
1412 else {
1413 if((res = mp_int_neg(&t, &v)) != MP_OK)
1414 goto CLEANUP;
1417 if((res = mp_int_sub(&u, &v, &t)) != MP_OK)
1418 goto CLEANUP;
1420 if(CMPZ(&t) == 0)
1421 break;
1424 if((res = mp_int_abs(&u, c)) != MP_OK)
1425 goto CLEANUP;
1426 if(!s_qmul(c, (mp_size) k))
1427 res = MP_MEMORY;
1429 CLEANUP:
1430 mp_int_clear(&v);
1431 V: mp_int_clear(&u);
1432 U: mp_int_clear(&t);
1434 return res;
1437 /* }}} */
1439 /* {{{ mp_int_egcd(a, b, c, x, y) */
1441 /* This is the binary GCD algorithm again, but this time we keep track
1442 of the elementary matrix operations as we go, so we can get values
1443 x and y satisfying c = ax + by.
1445 mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c,
1446 mp_int x, mp_int y)
1448 int k, last = 0, ca, cb;
1449 mpz_t temp[8];
1450 mp_result res;
1452 CHECK(a != NULL && b != NULL && c != NULL &&
1453 (x != NULL || y != NULL));
1455 ca = CMPZ(a);
1456 cb = CMPZ(b);
1457 if(ca == 0 && cb == 0)
1458 return MP_UNDEF;
1459 else if(ca == 0) {
1460 if((res = mp_int_abs(b, c)) != MP_OK) return res;
1461 mp_int_zero(x); (void) mp_int_set_value(y, 1); return MP_OK;
1463 else if(cb == 0) {
1464 if((res = mp_int_abs(a, c)) != MP_OK) return res;
1465 (void) mp_int_set_value(x, 1); mp_int_zero(y); return MP_OK;
1468 /* Initialize temporaries:
1469 A:0, B:1, C:2, D:3, u:4, v:5, ou:6, ov:7 */
1470 for(last = 0; last < 4; ++last)
1471 mp_int_init(TEMP(last));
1472 TEMP(0)->digits[0] = 1;
1473 TEMP(3)->digits[0] = 1;
1475 SETUP(mp_int_init_copy(TEMP(4), a), last);
1476 SETUP(mp_int_init_copy(TEMP(5), b), last);
1478 /* We will work with absolute values here */
1479 MP_SIGN(TEMP(4)) = MP_ZPOS;
1480 MP_SIGN(TEMP(5)) = MP_ZPOS;
1482 { /* Divide out common factors of 2 from u and v */
1483 int div2_u = s_dp2k(TEMP(4)), div2_v = s_dp2k(TEMP(5));
1485 k = MIN(div2_u, div2_v);
1486 s_qdiv(TEMP(4), k);
1487 s_qdiv(TEMP(5), k);
1490 SETUP(mp_int_init_copy(TEMP(6), TEMP(4)), last);
1491 SETUP(mp_int_init_copy(TEMP(7), TEMP(5)), last);
1493 for(;;) {
1494 while(mp_int_is_even(TEMP(4))) {
1495 s_qdiv(TEMP(4), 1);
1497 if(mp_int_is_odd(TEMP(0)) || mp_int_is_odd(TEMP(1))) {
1498 if((res = mp_int_add(TEMP(0), TEMP(7), TEMP(0))) != MP_OK)
1499 goto CLEANUP;
1500 if((res = mp_int_sub(TEMP(1), TEMP(6), TEMP(1))) != MP_OK)
1501 goto CLEANUP;
1504 s_qdiv(TEMP(0), 1);
1505 s_qdiv(TEMP(1), 1);
1508 while(mp_int_is_even(TEMP(5))) {
1509 s_qdiv(TEMP(5), 1);
1511 if(mp_int_is_odd(TEMP(2)) || mp_int_is_odd(TEMP(3))) {
1512 if((res = mp_int_add(TEMP(2), TEMP(7), TEMP(2))) != MP_OK)
1513 goto CLEANUP;
1514 if((res = mp_int_sub(TEMP(3), TEMP(6), TEMP(3))) != MP_OK)
1515 goto CLEANUP;
1518 s_qdiv(TEMP(2), 1);
1519 s_qdiv(TEMP(3), 1);
1522 if(mp_int_compare(TEMP(4), TEMP(5)) >= 0) {
1523 if((res = mp_int_sub(TEMP(4), TEMP(5), TEMP(4))) != MP_OK) goto CLEANUP;
1524 if((res = mp_int_sub(TEMP(0), TEMP(2), TEMP(0))) != MP_OK) goto CLEANUP;
1525 if((res = mp_int_sub(TEMP(1), TEMP(3), TEMP(1))) != MP_OK) goto CLEANUP;
1527 else {
1528 if((res = mp_int_sub(TEMP(5), TEMP(4), TEMP(5))) != MP_OK) goto CLEANUP;
1529 if((res = mp_int_sub(TEMP(2), TEMP(0), TEMP(2))) != MP_OK) goto CLEANUP;
1530 if((res = mp_int_sub(TEMP(3), TEMP(1), TEMP(3))) != MP_OK) goto CLEANUP;
1533 if(CMPZ(TEMP(4)) == 0) {
1534 if(x && (res = mp_int_copy(TEMP(2), x)) != MP_OK) goto CLEANUP;
1535 if(y && (res = mp_int_copy(TEMP(3), y)) != MP_OK) goto CLEANUP;
1536 if(c) {
1537 if(!s_qmul(TEMP(5), k)) {
1538 res = MP_MEMORY;
1539 goto CLEANUP;
1542 res = mp_int_copy(TEMP(5), c);
1545 break;
1549 CLEANUP:
1550 while(--last >= 0)
1551 mp_int_clear(TEMP(last));
1553 return res;
1556 /* }}} */
1558 /* {{{ mp_int_divisible_value(a, v) */
1560 int mp_int_divisible_value(mp_int a, int v)
1562 int rem = 0;
1564 if(mp_int_div_value(a, v, NULL, &rem) != MP_OK)
1565 return 0;
1567 return rem == 0;
1570 /* }}} */
1572 /* {{{ mp_int_is_pow2(z) */
1574 int mp_int_is_pow2(mp_int z)
1576 CHECK(z != NULL);
1578 return s_isp2(z);
1581 /* }}} */
1583 /* {{{ mp_int_sqrt(a, c) */
1585 mp_result mp_int_sqrt(mp_int a, mp_int c)
1587 mp_result res = MP_OK;
1588 mpz_t temp[2];
1589 int last = 0;
1591 CHECK(a != NULL && c != NULL);
1593 /* The square root of a negative value does not exist in the integers. */
1594 if(MP_SIGN(a) == MP_NEG)
1595 return MP_UNDEF;
1597 SETUP(mp_int_init_copy(TEMP(last), a), last);
1598 SETUP(mp_int_init(TEMP(last)), last);
1600 for(;;) {
1601 if((res = mp_int_sqr(TEMP(0), TEMP(1))) != MP_OK)
1602 goto CLEANUP;
1604 if(mp_int_compare_unsigned(a, TEMP(1)) == 0) break;
1606 if((res = mp_int_copy(a, TEMP(1))) != MP_OK)
1607 goto CLEANUP;
1608 if((res = mp_int_div(TEMP(1), TEMP(0), TEMP(1), NULL)) != MP_OK)
1609 goto CLEANUP;
1610 if((res = mp_int_add(TEMP(0), TEMP(1), TEMP(1))) != MP_OK)
1611 goto CLEANUP;
1612 if((res = mp_int_div_pow2(TEMP(1), 1, TEMP(1), NULL)) != MP_OK)
1613 goto CLEANUP;
1615 if(mp_int_compare_unsigned(TEMP(0), TEMP(1)) == 0) break;
1616 if((res = mp_int_sub_value(TEMP(0), 1, TEMP(0))) != MP_OK) goto CLEANUP;
1617 if(mp_int_compare_unsigned(TEMP(0), TEMP(1)) == 0) break;
1619 if((res = mp_int_copy(TEMP(1), TEMP(0))) != MP_OK) goto CLEANUP;
1622 res = mp_int_copy(TEMP(0), c);
1624 CLEANUP:
1625 while(--last >= 0)
1626 mp_int_clear(TEMP(last));
1628 return res;
1631 /* }}} */
1633 /* {{{ mp_int_to_int(z, out) */
1635 mp_result mp_int_to_int(mp_int z, int *out)
1637 unsigned int uv = 0;
1638 mp_size uz;
1639 mp_digit *dz;
1640 mp_sign sz;
1642 CHECK(z != NULL);
1644 /* Make sure the value is representable as an int */
1645 sz = MP_SIGN(z);
1646 if((sz == MP_ZPOS && mp_int_compare_value(z, INT_MAX) > 0) ||
1647 mp_int_compare_value(z, INT_MIN) < 0)
1648 return MP_RANGE;
1650 uz = MP_USED(z);
1651 dz = MP_DIGITS(z) + uz - 1;
1653 while(uz > 0) {
1654 uv <<= MP_DIGIT_BIT/2;
1655 uv = (uv << (MP_DIGIT_BIT/2)) | *dz--;
1656 --uz;
1659 if(out)
1660 *out = (sz == MP_NEG) ? -(int)uv : (int)uv;
1662 return MP_OK;
1665 /* }}} */
1667 /* {{{ mp_int_to_string(z, radix, str, limit) */
1669 mp_result mp_int_to_string(mp_int z, mp_size radix,
1670 char *str, int limit)
1672 mp_result res;
1673 int cmp = 0;
1675 CHECK(z != NULL && str != NULL && limit >= 2);
1677 if(radix < MP_MIN_RADIX || radix > MP_MAX_RADIX)
1678 return MP_RANGE;
1680 if(CMPZ(z) == 0) {
1681 *str++ = s_val2ch(0, 1);
1683 else {
1684 mpz_t tmp;
1685 char *h, *t;
1687 if((res = mp_int_init_copy(&tmp, z)) != MP_OK)
1688 return res;
1690 if(MP_SIGN(z) == MP_NEG) {
1691 *str++ = '-';
1692 --limit;
1694 h = str;
1696 /* Generate digits in reverse order until finished or limit reached */
1697 for(/* */; limit > 0; --limit) {
1698 mp_digit d;
1700 if((cmp = CMPZ(&tmp)) == 0)
1701 break;
1703 d = s_ddiv(&tmp, (mp_digit)radix);
1704 *str++ = s_val2ch(d, 1);
1706 t = str - 1;
1708 /* Put digits back in correct output order */
1709 while(h < t) {
1710 char tc = *h;
1711 *h++ = *t;
1712 *t-- = tc;
1715 mp_int_clear(&tmp);
1718 *str = '\0';
1719 if(cmp == 0)
1720 return MP_OK;
1721 else
1722 return MP_TRUNC;
1725 /* }}} */
1727 /* {{{ mp_int_string_len(z, radix) */
1729 mp_result mp_int_string_len(mp_int z, mp_size radix)
1731 int len;
1733 CHECK(z != NULL);
1735 if(radix < MP_MIN_RADIX || radix > MP_MAX_RADIX)
1736 return MP_RANGE;
1738 len = s_outlen(z, radix) + 1; /* for terminator */
1740 /* Allow for sign marker on negatives */
1741 if(MP_SIGN(z) == MP_NEG)
1742 len += 1;
1744 return len;
1747 /* }}} */
1749 /* {{{ mp_int_read_string(z, radix, *str) */
1751 /* Read zero-terminated string into z */
1752 mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str)
1754 return mp_int_read_cstring(z, radix, str, NULL);
1758 /* }}} */
1760 /* {{{ mp_int_read_cstring(z, radix, *str, **end) */
1762 mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **end)
1764 int ch;
1766 CHECK(z != NULL && str != NULL);
1768 if(radix < MP_MIN_RADIX || radix > MP_MAX_RADIX)
1769 return MP_RANGE;
1771 /* Skip leading whitespace */
1772 while(isspace((int)*str))
1773 ++str;
1775 /* Handle leading sign tag (+/-, positive default) */
1776 switch(*str) {
1777 case '-':
1778 MP_SIGN(z) = MP_NEG;
1779 ++str;
1780 break;
1781 case '+':
1782 ++str; /* fallthrough */
1783 default:
1784 MP_SIGN(z) = MP_ZPOS;
1785 break;
1788 /* Skip leading zeroes */
1789 while((ch = s_ch2val(*str, radix)) == 0)
1790 ++str;
1792 /* Make sure there is enough space for the value */
1793 if(!s_pad(z, s_inlen(strlen(str), radix)))
1794 return MP_MEMORY;
1796 MP_USED(z) = 1; z->digits[0] = 0;
1798 while(*str != '\0' && ((ch = s_ch2val(*str, radix)) >= 0)) {
1799 s_dmul(z, (mp_digit)radix);
1800 s_dadd(z, (mp_digit)ch);
1801 ++str;
1804 CLAMP(z);
1806 /* Override sign for zero, even if negative specified. */
1807 if(CMPZ(z) == 0)
1808 MP_SIGN(z) = MP_ZPOS;
1810 if(end != NULL)
1811 *end = (char *)str;
1813 /* Return a truncation error if the string has unprocessed
1814 characters remaining, so the caller can tell if the whole string
1815 was done */
1816 if(*str != '\0')
1817 return MP_TRUNC;
1818 else
1819 return MP_OK;
1822 /* }}} */
1824 /* {{{ mp_int_count_bits(z) */
1826 mp_result mp_int_count_bits(mp_int z)
1828 mp_size nbits = 0, uz;
1829 mp_digit d;
1831 CHECK(z != NULL);
1833 uz = MP_USED(z);
1834 if(uz == 1 && z->digits[0] == 0)
1835 return 1;
1837 --uz;
1838 nbits = uz * MP_DIGIT_BIT;
1839 d = z->digits[uz];
1841 while(d != 0) {
1842 d >>= 1;
1843 ++nbits;
1846 return nbits;
1849 /* }}} */
1851 /* {{{ mp_int_to_binary(z, buf, limit) */
1853 mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit)
1855 static const int PAD_FOR_2C = 1;
1857 mp_result res;
1858 int limpos = limit;
1860 CHECK(z != NULL && buf != NULL);
1862 res = s_tobin(z, buf, &limpos, PAD_FOR_2C);
1864 if(MP_SIGN(z) == MP_NEG)
1865 s_2comp(buf, limpos);
1867 return res;
1870 /* }}} */
1872 /* {{{ mp_int_read_binary(z, buf, len) */
1874 mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len)
1876 mp_size need, i;
1877 unsigned char *tmp;
1878 mp_digit *dz;
1880 CHECK(z != NULL && buf != NULL && len > 0);
1882 /* Figure out how many digits are needed to represent this value */
1883 need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT;
1884 if(!s_pad(z, need))
1885 return MP_MEMORY;
1887 mp_int_zero(z);
1889 /* If the high-order bit is set, take the 2's complement before
1890 reading the value (it will be restored afterward) */
1891 if(buf[0] >> (CHAR_BIT - 1)) {
1892 MP_SIGN(z) = MP_NEG;
1893 s_2comp(buf, len);
1896 dz = MP_DIGITS(z);
1897 for(tmp = buf, i = len; i > 0; --i, ++tmp) {
1898 s_qmul(z, (mp_size) CHAR_BIT);
1899 *dz |= *tmp;
1902 /* Restore 2's complement if we took it before */
1903 if(MP_SIGN(z) == MP_NEG)
1904 s_2comp(buf, len);
1906 return MP_OK;
1909 /* }}} */
1911 /* {{{ mp_int_binary_len(z) */
1913 mp_result mp_int_binary_len(mp_int z)
1915 mp_result res = mp_int_count_bits(z);
1916 int bytes = mp_int_unsigned_len(z);
1918 if(res <= 0)
1919 return res;
1921 bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT;
1923 /* If the highest-order bit falls exactly on a byte boundary, we
1924 need to pad with an extra byte so that the sign will be read
1925 correctly when reading it back in. */
1926 if(bytes * CHAR_BIT == res)
1927 ++bytes;
1929 return bytes;
1932 /* }}} */
1934 /* {{{ mp_int_to_unsigned(z, buf, limit) */
1936 mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit)
1938 static const int NO_PADDING = 0;
1940 CHECK(z != NULL && buf != NULL);
1942 return s_tobin(z, buf, &limit, NO_PADDING);
1945 /* }}} */
1947 /* {{{ mp_int_read_unsigned(z, buf, len) */
1949 mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len)
1951 mp_size need, i;
1952 unsigned char *tmp;
1953 mp_digit *dz;
1955 CHECK(z != NULL && buf != NULL && len > 0);
1957 /* Figure out how many digits are needed to represent this value */
1958 need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT;
1959 if(!s_pad(z, need))
1960 return MP_MEMORY;
1962 mp_int_zero(z);
1964 dz = MP_DIGITS(z);
1965 for(tmp = buf, i = len; i > 0; --i, ++tmp) {
1966 (void) s_qmul(z, CHAR_BIT);
1967 *dz |= *tmp;
1970 return MP_OK;
1973 /* }}} */
1975 /* {{{ mp_int_unsigned_len(z) */
1977 mp_result mp_int_unsigned_len(mp_int z)
1979 mp_result res = mp_int_count_bits(z);
1980 int bytes;
1982 if(res <= 0)
1983 return res;
1985 bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT;
1987 return bytes;
1990 /* }}} */
1992 /* {{{ mp_error_string(res) */
1994 const char *mp_error_string(mp_result res)
1996 int ix;
1997 if(res > 0)
1998 return s_unknown_err;
2000 res = -res;
2001 for(ix = 0; ix < res && s_error_msg[ix] != NULL; ++ix)
2004 if(s_error_msg[ix] != NULL)
2005 return s_error_msg[ix];
2006 else
2007 return s_unknown_err;
2010 /* }}} */
2012 /*------------------------------------------------------------------------*/
2013 /* Private functions for internal use. These make assumptions. */
2015 /* {{{ s_alloc(num) */
2017 static mp_digit *s_alloc(mp_size num)
2019 mp_digit *out = malloc(num * sizeof(mp_digit));
2021 assert(out != NULL); /* for debugging */
2022 #if DEBUG > 1
2024 mp_digit v = (mp_digit) 0xdeadbeef;
2025 int ix;
2027 for(ix = 0; ix < num; ++ix)
2028 out[ix] = v;
2030 #endif
2032 return out;
2035 /* }}} */
2037 /* {{{ s_realloc(old, osize, nsize) */
2039 static mp_digit *s_realloc(mp_digit *old, mp_size osize, mp_size nsize)
2041 #if DEBUG > 1
2042 mp_digit *new = s_alloc(nsize);
2043 int ix;
2045 for(ix = 0; ix < nsize; ++ix)
2046 new[ix] = (mp_digit) 0xdeadbeef;
2048 memcpy(new, old, osize * sizeof(mp_digit));
2049 #else
2050 mp_digit *new = realloc(old, nsize * sizeof(mp_digit));
2052 assert(new != NULL); /* for debugging */
2053 #endif
2054 return new;
2057 /* }}} */
2059 /* {{{ s_free(ptr) */
2061 static void s_free(void *ptr)
2063 free(ptr);
2066 /* }}} */
2068 /* {{{ s_pad(z, min) */
2070 static int s_pad(mp_int z, mp_size min)
2072 if(MP_ALLOC(z) < min) {
2073 mp_size nsize = ROUND_PREC(min);
2074 mp_digit *tmp;
2076 if((void *)z->digits == (void *)z) {
2077 if((tmp = s_alloc(nsize)) == NULL)
2078 return 0;
2080 COPY(MP_DIGITS(z), tmp, MP_USED(z));
2082 else if((tmp = s_realloc(MP_DIGITS(z), MP_ALLOC(z), nsize)) == NULL)
2083 return 0;
2085 MP_DIGITS(z) = tmp;
2086 MP_ALLOC(z) = nsize;
2089 return 1;
2092 /* }}} */
2094 /* {{{ s_clamp(z) */
2096 #if TRACEABLE_CLAMP
2097 static void s_clamp(mp_int z)
2099 mp_size uz = MP_USED(z);
2100 mp_digit *zd = MP_DIGITS(z) + uz - 1;
2102 while(uz > 1 && (*zd-- == 0))
2103 --uz;
2105 MP_USED(z) = uz;
2107 #endif
2109 /* }}} */
2111 /* {{{ s_fake(z, value, vbuf) */
2113 static void s_fake(mp_int z, int value, mp_digit vbuf[])
2115 mp_size uv = (mp_size) s_vpack(value, vbuf);
2117 z->used = uv;
2118 z->alloc = MP_VALUE_DIGITS(value);
2119 z->sign = (value < 0) ? MP_NEG : MP_ZPOS;
2120 z->digits = vbuf;
2123 /* }}} */
2125 /* {{{ s_cdig(da, db, len) */
2127 static int s_cdig(mp_digit *da, mp_digit *db, mp_size len)
2129 mp_digit *dat = da + len - 1, *dbt = db + len - 1;
2131 for(/* */; len != 0; --len, --dat, --dbt) {
2132 if(*dat > *dbt)
2133 return 1;
2134 else if(*dat < *dbt)
2135 return -1;
2138 return 0;
2141 /* }}} */
2143 /* {{{ s_vpack(v, t[]) */
2145 static int s_vpack(int v, mp_digit t[])
2147 unsigned int uv = (unsigned int)((v < 0) ? -v : v);
2148 int ndig = 0;
2150 if(uv == 0)
2151 t[ndig++] = 0;
2152 else {
2153 while(uv != 0) {
2154 t[ndig++] = (mp_digit) uv;
2155 uv >>= MP_DIGIT_BIT/2;
2156 uv >>= MP_DIGIT_BIT/2;
2160 return ndig;
2163 /* }}} */
2165 /* {{{ s_ucmp(a, b) */
2167 static int s_ucmp(mp_int a, mp_int b)
2169 mp_size ua = MP_USED(a), ub = MP_USED(b);
2171 if(ua > ub)
2172 return 1;
2173 else if(ub > ua)
2174 return -1;
2175 else
2176 return s_cdig(MP_DIGITS(a), MP_DIGITS(b), ua);
2179 /* }}} */
2181 /* {{{ s_vcmp(a, v) */
2183 static int s_vcmp(mp_int a, int v)
2185 mp_digit vdig[MP_VALUE_DIGITS(v)];
2186 int ndig = 0;
2187 mp_size ua = MP_USED(a);
2189 ndig = s_vpack(v, vdig);
2191 if(ua > ndig)
2192 return 1;
2193 else if(ua < ndig)
2194 return -1;
2195 else
2196 return s_cdig(MP_DIGITS(a), vdig, ndig);
2199 /* }}} */
2201 /* {{{ s_uadd(da, db, dc, size_a, size_b) */
2203 static mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc,
2204 mp_size size_a, mp_size size_b)
2206 mp_size pos;
2207 mp_word w = 0;
2209 /* Insure that da is the longer of the two to simplify later code */
2210 if(size_b > size_a) {
2211 SWAP(mp_digit *, da, db);
2212 SWAP(mp_size, size_a, size_b);
2215 /* Add corresponding digits until the shorter number runs out */
2216 for(pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) {
2217 w = w + (mp_word) *da + (mp_word) *db;
2218 *dc = LOWER_HALF(w);
2219 w = UPPER_HALF(w);
2222 /* Propagate carries as far as necessary */
2223 for(/* */; pos < size_a; ++pos, ++da, ++dc) {
2224 w = w + *da;
2226 *dc = LOWER_HALF(w);
2227 w = UPPER_HALF(w);
2230 /* Return carry out */
2231 return (mp_digit)w;
2234 /* }}} */
2236 /* {{{ s_usub(da, db, dc, size_a, size_b) */
2238 static void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc,
2239 mp_size size_a, mp_size size_b)
2241 mp_size pos;
2242 mp_word w = 0;
2244 /* We assume that |a| >= |b| so this should definitely hold */
2245 assert(size_a >= size_b);
2247 /* Subtract corresponding digits and propagate borrow */
2248 for(pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) {
2249 w = ((mp_word)MP_DIGIT_MAX + 1 + /* MP_RADIX */
2250 (mp_word)*da) - w - (mp_word)*db;
2252 *dc = LOWER_HALF(w);
2253 w = (UPPER_HALF(w) == 0);
2256 /* Finish the subtraction for remaining upper digits of da */
2257 for(/* */; pos < size_a; ++pos, ++da, ++dc) {
2258 w = ((mp_word)MP_DIGIT_MAX + 1 + /* MP_RADIX */
2259 (mp_word)*da) - w;
2261 *dc = LOWER_HALF(w);
2262 w = (UPPER_HALF(w) == 0);
2265 /* If there is a borrow out at the end, it violates the precondition */
2266 assert(w == 0);
2269 /* }}} */
2271 /* {{{ s_kmul(da, db, dc, size_a, size_b) */
2273 static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
2274 mp_size size_a, mp_size size_b)
2276 mp_size bot_size;
2278 /* Make sure b is the smaller of the two input values */
2279 if(size_b > size_a) {
2280 SWAP(mp_digit *, da, db);
2281 SWAP(mp_size, size_a, size_b);
2284 /* Insure that the bottom is the larger half in an odd-length split;
2285 the code below relies on this being true.
2287 bot_size = (size_a + 1) / 2;
2289 /* If the values are big enough to bother with recursion, use the
2290 Karatsuba algorithm to compute the product; otherwise use the
2291 normal multiplication algorithm
2293 if(multiply_threshold &&
2294 size_a >= multiply_threshold &&
2295 size_b > bot_size) {
2297 mp_digit *t1, *t2, *t3, carry;
2299 mp_digit *a_top = da + bot_size;
2300 mp_digit *b_top = db + bot_size;
2302 mp_size at_size = size_a - bot_size;
2303 mp_size bt_size = size_b - bot_size;
2304 mp_size buf_size = 2 * bot_size;
2306 /* Do a single allocation for all three temporary buffers needed;
2307 each buffer must be big enough to hold the product of two
2308 bottom halves, and one buffer needs space for the completed
2309 product; twice the space is plenty.
2311 if((t1 = s_alloc(4 * buf_size)) == NULL) return 0;
2312 t2 = t1 + buf_size;
2313 t3 = t2 + buf_size;
2314 ZERO(t1, 4 * buf_size);
2316 /* t1 and t2 are initially used as temporaries to compute the inner product
2317 (a1 + a0)(b1 + b0) = a1b1 + a1b0 + a0b1 + a0b0
2319 carry = s_uadd(da, a_top, t1, bot_size, at_size); /* t1 = a1 + a0 */
2320 t1[bot_size] = carry;
2322 carry = s_uadd(db, b_top, t2, bot_size, bt_size); /* t2 = b1 + b0 */
2323 t2[bot_size] = carry;
2325 (void) s_kmul(t1, t2, t3, bot_size + 1, bot_size + 1); /* t3 = t1 * t2 */
2327 /* Now we'll get t1 = a0b0 and t2 = a1b1, and subtract them out so that
2328 we're left with only the pieces we want: t3 = a1b0 + a0b1
2330 ZERO(t1, buf_size);
2331 ZERO(t2, buf_size);
2332 (void) s_kmul(da, db, t1, bot_size, bot_size); /* t1 = a0 * b0 */
2333 (void) s_kmul(a_top, b_top, t2, at_size, bt_size); /* t2 = a1 * b1 */
2335 /* Subtract out t1 and t2 to get the inner product */
2336 s_usub(t3, t1, t3, buf_size + 2, buf_size);
2337 s_usub(t3, t2, t3, buf_size + 2, buf_size);
2339 /* Assemble the output value */
2340 COPY(t1, dc, buf_size);
2341 carry = s_uadd(t3, dc + bot_size, dc + bot_size,
2342 buf_size + 1, buf_size);
2343 assert(carry == 0);
2345 carry = s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size,
2346 buf_size, buf_size);
2347 assert(carry == 0);
2349 s_free(t1); /* note t2 and t3 are just internal pointers to t1 */
2351 else {
2352 s_umul(da, db, dc, size_a, size_b);
2355 return 1;
2358 /* }}} */
2360 /* {{{ s_umul(da, db, dc, size_a, size_b) */
2362 static void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc,
2363 mp_size size_a, mp_size size_b)
2365 mp_size a, b;
2366 mp_word w;
2368 for(a = 0; a < size_a; ++a, ++dc, ++da) {
2369 mp_digit *dct = dc;
2370 mp_digit *dbt = db;
2372 if(*da == 0)
2373 continue;
2375 w = 0;
2376 for(b = 0; b < size_b; ++b, ++dbt, ++dct) {
2377 w = (mp_word)*da * (mp_word)*dbt + w + (mp_word)*dct;
2379 *dct = LOWER_HALF(w);
2380 w = UPPER_HALF(w);
2383 *dct = (mp_digit)w;
2387 /* }}} */
2389 /* {{{ s_ksqr(da, dc, size_a) */
2391 static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a)
2393 if(multiply_threshold && size_a > multiply_threshold) {
2394 mp_size bot_size = (size_a + 1) / 2;
2395 mp_digit *a_top = da + bot_size;
2396 mp_digit *t1, *t2, *t3, carry;
2397 mp_size at_size = size_a - bot_size;
2398 mp_size buf_size = 2 * bot_size;
2400 if((t1 = s_alloc(4 * buf_size)) == NULL) return 0;
2401 t2 = t1 + buf_size;
2402 t3 = t2 + buf_size;
2403 ZERO(t1, 4 * buf_size);
2405 (void) s_ksqr(da, t1, bot_size); /* t1 = a0 ^ 2 */
2406 (void) s_ksqr(a_top, t2, at_size); /* t2 = a1 ^ 2 */
2408 (void) s_kmul(da, a_top, t3, bot_size, at_size); /* t3 = a0 * a1 */
2410 /* Quick multiply t3 by 2, shifting left (can't overflow) */
2412 int i, top = bot_size + at_size;
2413 mp_word w, save = 0;
2415 for(i = 0; i < top; ++i) {
2416 w = t3[i];
2417 w = (w << 1) | save;
2418 t3[i] = LOWER_HALF(w);
2419 save = UPPER_HALF(w);
2421 t3[i] = LOWER_HALF(save);
2424 /* Assemble the output value */
2425 COPY(t1, dc, 2 * bot_size);
2426 carry = s_uadd(t3, dc + bot_size, dc + bot_size,
2427 buf_size + 1, buf_size);
2428 assert(carry == 0);
2430 carry = s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size,
2431 buf_size, buf_size);
2432 assert(carry == 0);
2434 s_free(t1); /* note that t2 and t2 are internal pointers only */
2437 else {
2438 s_usqr(da, dc, size_a);
2441 return 1;
2444 /* }}} */
2446 /* {{{ s_usqr(da, dc, size_a) */
2448 static void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a)
2450 mp_size i, j;
2451 mp_word w;
2453 for(i = 0; i < size_a; ++i, dc += 2, ++da) {
2454 mp_digit *dct = dc, *dat = da;
2456 if(*da == 0)
2457 continue;
2459 /* Take care of the first digit, no rollover */
2460 w = (mp_word)*dat * (mp_word)*dat + (mp_word)*dct;
2461 *dct = LOWER_HALF(w);
2462 w = UPPER_HALF(w);
2463 ++dat; ++dct;
2465 for(j = i + 1; j < size_a; ++j, ++dat, ++dct) {
2466 mp_word t = (mp_word)*da * (mp_word)*dat;
2467 mp_word u = w + (mp_word)*dct, ov = 0;
2469 /* Check if doubling t will overflow a word */
2470 if(HIGH_BIT_SET(t))
2471 ov = 1;
2473 w = t + t;
2475 /* Check if adding u to w will overflow a word */
2476 if(ADD_WILL_OVERFLOW(w, u))
2477 ov = 1;
2479 w += u;
2481 *dct = LOWER_HALF(w);
2482 w = UPPER_HALF(w);
2483 if(ov) {
2484 w += MP_DIGIT_MAX; /* MP_RADIX */
2485 ++w;
2489 w = w + *dct;
2490 *dct = (mp_digit)w;
2491 while((w = UPPER_HALF(w)) != 0) {
2492 ++dct; w = w + *dct;
2493 *dct = LOWER_HALF(w);
2496 assert(w == 0);
2500 /* }}} */
2502 /* {{{ s_dadd(a, b) */
2504 static void s_dadd(mp_int a, mp_digit b)
2506 mp_word w = 0;
2507 mp_digit *da = MP_DIGITS(a);
2508 mp_size ua = MP_USED(a);
2510 w = (mp_word)*da + b;
2511 *da++ = LOWER_HALF(w);
2512 w = UPPER_HALF(w);
2514 for(ua -= 1; ua > 0; --ua, ++da) {
2515 w = (mp_word)*da + w;
2517 *da = LOWER_HALF(w);
2518 w = UPPER_HALF(w);
2521 if(w) {
2522 *da = (mp_digit)w;
2523 MP_USED(a) += 1;
2527 /* }}} */
2529 /* {{{ s_dmul(a, b) */
2531 static void s_dmul(mp_int a, mp_digit b)
2533 mp_word w = 0;
2534 mp_digit *da = MP_DIGITS(a);
2535 mp_size ua = MP_USED(a);
2537 while(ua > 0) {
2538 w = (mp_word)*da * b + w;
2539 *da++ = LOWER_HALF(w);
2540 w = UPPER_HALF(w);
2541 --ua;
2544 if(w) {
2545 *da = (mp_digit)w;
2546 MP_USED(a) += 1;
2550 /* }}} */
2552 /* {{{ s_dbmul(da, b, dc, size_a) */
2554 static void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a)
2556 mp_word w = 0;
2558 while(size_a > 0) {
2559 w = (mp_word)*da++ * (mp_word)b + w;
2561 *dc++ = LOWER_HALF(w);
2562 w = UPPER_HALF(w);
2563 --size_a;
2566 if(w)
2567 *dc = LOWER_HALF(w);
2570 /* }}} */
2572 /* {{{ s_ddiv(da, d, dc, size_a) */
2574 static mp_digit s_ddiv(mp_int a, mp_digit b)
2576 mp_word w = 0, qdigit;
2577 mp_size ua = MP_USED(a);
2578 mp_digit *da = MP_DIGITS(a) + ua - 1;
2580 for(/* */; ua > 0; --ua, --da) {
2581 w = (w << MP_DIGIT_BIT) | *da;
2583 if(w >= b) {
2584 qdigit = w / b;
2585 w = w % b;
2587 else {
2588 qdigit = 0;
2591 *da = (mp_digit)qdigit;
2594 CLAMP(a);
2595 return (mp_digit)w;
2598 /* }}} */
2600 /* {{{ s_qdiv(z, p2) */
2602 static void s_qdiv(mp_int z, mp_size p2)
2604 mp_size ndig = p2 / MP_DIGIT_BIT, nbits = p2 % MP_DIGIT_BIT;
2605 mp_size uz = MP_USED(z);
2607 if(ndig) {
2608 mp_size mark;
2609 mp_digit *to, *from;
2611 if(ndig >= uz) {
2612 mp_int_zero(z);
2613 return;
2616 to = MP_DIGITS(z); from = to + ndig;
2618 for(mark = ndig; mark < uz; ++mark)
2619 *to++ = *from++;
2621 MP_USED(z) = uz - ndig;
2624 if(nbits) {
2625 mp_digit d = 0, *dz, save;
2626 mp_size up = MP_DIGIT_BIT - nbits;
2628 uz = MP_USED(z);
2629 dz = MP_DIGITS(z) + uz - 1;
2631 for(/* */; uz > 0; --uz, --dz) {
2632 save = *dz;
2634 *dz = (*dz >> nbits) | (d << up);
2635 d = save;
2638 CLAMP(z);
2641 if(MP_USED(z) == 1 && z->digits[0] == 0)
2642 MP_SIGN(z) = MP_ZPOS;
2645 /* }}} */
2647 /* {{{ s_qmod(z, p2) */
2649 static void s_qmod(mp_int z, mp_size p2)
2651 mp_size start = p2 / MP_DIGIT_BIT + 1, rest = p2 % MP_DIGIT_BIT;
2652 mp_size uz = MP_USED(z);
2653 mp_digit mask = (1 << rest) - 1;
2655 if(start <= uz) {
2656 MP_USED(z) = start;
2657 z->digits[start - 1] &= mask;
2658 CLAMP(z);
2662 /* }}} */
2664 /* {{{ s_qmul(z, p2) */
2666 static int s_qmul(mp_int z, mp_size p2)
2668 mp_size uz, need, rest, extra, i;
2669 mp_digit *from, *to, d;
2671 if(p2 == 0)
2672 return 1;
2674 uz = MP_USED(z);
2675 need = p2 / MP_DIGIT_BIT; rest = p2 % MP_DIGIT_BIT;
2677 /* Figure out if we need an extra digit at the top end; this occurs
2678 if the topmost `rest' bits of the high-order digit of z are not
2679 zero, meaning they will be shifted off the end if not preserved */
2680 extra = 0;
2681 if(rest != 0) {
2682 mp_digit *dz = MP_DIGITS(z) + uz - 1;
2684 if((*dz >> (MP_DIGIT_BIT - rest)) != 0)
2685 extra = 1;
2688 if(!s_pad(z, uz + need + extra))
2689 return 0;
2691 /* If we need to shift by whole digits, do that in one pass, then
2692 to back and shift by partial digits.
2694 if(need > 0) {
2695 from = MP_DIGITS(z) + uz - 1;
2696 to = from + need;
2698 for(i = 0; i < uz; ++i)
2699 *to-- = *from--;
2701 ZERO(MP_DIGITS(z), need);
2702 uz += need;
2705 if(rest) {
2706 d = 0;
2707 for(i = need, from = MP_DIGITS(z) + need; i < uz; ++i, ++from) {
2708 mp_digit save = *from;
2710 *from = (*from << rest) | (d >> (MP_DIGIT_BIT - rest));
2711 d = save;
2714 d >>= (MP_DIGIT_BIT - rest);
2715 if(d != 0) {
2716 *from = d;
2717 uz += extra;
2721 MP_USED(z) = uz;
2722 CLAMP(z);
2724 return 1;
2727 /* }}} */
2729 /* {{{ s_qsub(z, p2) */
2731 /* Compute z = 2^p2 - |z|; requires that 2^p2 >= |z|
2732 The sign of the result is always zero/positive.
2734 static int s_qsub(mp_int z, mp_size p2)
2736 mp_digit hi = (1 << (p2 % MP_DIGIT_BIT)), *zp;
2737 mp_size tdig = (p2 / MP_DIGIT_BIT), pos;
2738 mp_word w = 0;
2740 if(!s_pad(z, tdig + 1))
2741 return 0;
2743 for(pos = 0, zp = MP_DIGITS(z); pos < tdig; ++pos, ++zp) {
2744 w = ((mp_word) MP_DIGIT_MAX + 1) - w - (mp_word)*zp;
2746 *zp = LOWER_HALF(w);
2747 w = UPPER_HALF(w) ? 0 : 1;
2750 w = ((mp_word) MP_DIGIT_MAX + 1 + hi) - w - (mp_word)*zp;
2751 *zp = LOWER_HALF(w);
2753 assert(UPPER_HALF(w) != 0); /* no borrow out should be possible */
2755 MP_SIGN(z) = MP_ZPOS;
2756 CLAMP(z);
2758 return 1;
2761 /* }}} */
2763 /* {{{ s_dp2k(z) */
2765 static int s_dp2k(mp_int z)
2767 int k = 0;
2768 mp_digit *dp = MP_DIGITS(z), d;
2770 if(MP_USED(z) == 1 && *dp == 0)
2771 return 1;
2773 while(*dp == 0) {
2774 k += MP_DIGIT_BIT;
2775 ++dp;
2778 d = *dp;
2779 while((d & 1) == 0) {
2780 d >>= 1;
2781 ++k;
2784 return k;
2787 /* }}} */
2789 /* {{{ s_isp2(z) */
2791 static int s_isp2(mp_int z)
2793 mp_size uz = MP_USED(z), k = 0;
2794 mp_digit *dz = MP_DIGITS(z), d;
2796 while(uz > 1) {
2797 if(*dz++ != 0)
2798 return -1;
2799 k += MP_DIGIT_BIT;
2800 --uz;
2803 d = *dz;
2804 while(d > 1) {
2805 if(d & 1)
2806 return -1;
2807 ++k; d >>= 1;
2810 return (int) k;
2813 /* }}} */
2815 /* {{{ s_2expt(z, k) */
2817 static int s_2expt(mp_int z, int k)
2819 mp_size ndig, rest;
2820 mp_digit *dz;
2822 ndig = (k + MP_DIGIT_BIT) / MP_DIGIT_BIT;
2823 rest = k % MP_DIGIT_BIT;
2825 if(!s_pad(z, ndig))
2826 return 0;
2828 dz = MP_DIGITS(z);
2829 ZERO(dz, ndig);
2830 *(dz + ndig - 1) = (1 << rest);
2831 MP_USED(z) = ndig;
2833 return 1;
2836 /* }}} */
2838 /* {{{ s_norm(a, b) */
2840 static int s_norm(mp_int a, mp_int b)
2842 mp_digit d = b->digits[MP_USED(b) - 1];
2843 int k = 0;
2845 while(d < (mp_digit) (1 << (MP_DIGIT_BIT - 1))) { /* d < (MP_RADIX / 2) */
2846 d <<= 1;
2847 ++k;
2850 /* These multiplications can't fail */
2851 if(k != 0) {
2852 (void) s_qmul(a, (mp_size) k);
2853 (void) s_qmul(b, (mp_size) k);
2856 return k;
2859 /* }}} */
2861 /* {{{ s_brmu(z, m) */
2863 static mp_result s_brmu(mp_int z, mp_int m)
2865 mp_size um = MP_USED(m) * 2;
2867 if(!s_pad(z, um))
2868 return MP_MEMORY;
2870 s_2expt(z, MP_DIGIT_BIT * um);
2871 return mp_int_div(z, m, z, NULL);
2874 /* }}} */
2876 /* {{{ s_reduce(x, m, mu, q1, q2) */
2878 static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2)
2880 mp_size um = MP_USED(m), umb_p1, umb_m1;
2882 umb_p1 = (um + 1) * MP_DIGIT_BIT;
2883 umb_m1 = (um - 1) * MP_DIGIT_BIT;
2885 if(mp_int_copy(x, q1) != MP_OK)
2886 return 0;
2888 /* Compute q2 = floor((floor(x / b^(k-1)) * mu) / b^(k+1)) */
2889 s_qdiv(q1, umb_m1);
2890 UMUL(q1, mu, q2);
2891 s_qdiv(q2, umb_p1);
2893 /* Set x = x mod b^(k+1) */
2894 s_qmod(x, umb_p1);
2896 /* Now, q is a guess for the quotient a / m.
2897 Compute x - q * m mod b^(k+1), replacing x. This may be off
2898 by a factor of 2m, but no more than that.
2900 UMUL(q2, m, q1);
2901 s_qmod(q1, umb_p1);
2902 (void) mp_int_sub(x, q1, x); /* can't fail */
2904 /* The result may be < 0; if it is, add b^(k+1) to pin it in the
2905 proper range. */
2906 if((CMPZ(x) < 0) && !s_qsub(x, umb_p1))
2907 return 0;
2909 /* If x > m, we need to back it off until it is in range.
2910 This will be required at most twice. */
2911 if(mp_int_compare(x, m) >= 0) {
2912 (void) mp_int_sub(x, m, x);
2913 if(mp_int_compare(x, m) >= 0)
2914 (void) mp_int_sub(x, m, x);
2917 /* At this point, x has been properly reduced. */
2918 return 1;
2921 /* }}} */
2923 /* {{{ s_embar(a, b, m, mu, c) */
2925 /* Perform modular exponentiation using Barrett's method, where mu is
2926 the reduction constant for m. Assumes a < m, b > 0. */
2927 static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c)
2929 mp_digit *db, *dbt, umu, d;
2930 mpz_t temp[3];
2931 mp_result res;
2932 int last = 0;
2934 umu = MP_USED(mu); db = MP_DIGITS(b); dbt = db + MP_USED(b) - 1;
2936 while(last < 3) {
2937 SETUP(mp_int_init_size(TEMP(last), 4 * umu), last);
2938 ZERO(MP_DIGITS(TEMP(last - 1)), MP_ALLOC(TEMP(last - 1)));
2941 (void) mp_int_set_value(c, 1);
2943 /* Take care of low-order digits */
2944 while(db < dbt) {
2945 int i;
2947 for(d = *db, i = MP_DIGIT_BIT; i > 0; --i, d >>= 1) {
2948 if(d & 1) {
2949 /* The use of a second temporary avoids allocation */
2950 UMUL(c, a, TEMP(0));
2951 if(!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) {
2952 res = MP_MEMORY; goto CLEANUP;
2954 mp_int_copy(TEMP(0), c);
2958 USQR(a, TEMP(0));
2959 assert(MP_SIGN(TEMP(0)) == MP_ZPOS);
2960 if(!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) {
2961 res = MP_MEMORY; goto CLEANUP;
2963 assert(MP_SIGN(TEMP(0)) == MP_ZPOS);
2964 mp_int_copy(TEMP(0), a);
2969 ++db;
2972 /* Take care of highest-order digit */
2973 d = *dbt;
2974 for(;;) {
2975 if(d & 1) {
2976 UMUL(c, a, TEMP(0));
2977 if(!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) {
2978 res = MP_MEMORY; goto CLEANUP;
2980 mp_int_copy(TEMP(0), c);
2983 d >>= 1;
2984 if(!d) break;
2986 USQR(a, TEMP(0));
2987 if(!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) {
2988 res = MP_MEMORY; goto CLEANUP;
2990 (void) mp_int_copy(TEMP(0), a);
2993 CLEANUP:
2994 while(--last >= 0)
2995 mp_int_clear(TEMP(last));
2997 return res;
3000 /* }}} */
3002 /* {{{ s_udiv(a, b) */
3004 /* Precondition: a >= b and b > 0
3005 Postcondition: a' = a / b, b' = a % b
3007 static mp_result s_udiv(mp_int a, mp_int b)
3009 mpz_t q, r, t;
3010 mp_size ua, ub, qpos = 0;
3011 mp_digit *da, btop;
3012 mp_result res = MP_OK;
3013 int k, skip = 0;
3015 /* Force signs to positive */
3016 MP_SIGN(a) = MP_ZPOS;
3017 MP_SIGN(b) = MP_ZPOS;
3019 /* Normalize, per Knuth */
3020 k = s_norm(a, b);
3022 ua = MP_USED(a); ub = MP_USED(b); btop = b->digits[ub - 1];
3023 if((res = mp_int_init_size(&q, ua)) != MP_OK) return res;
3024 if((res = mp_int_init_size(&t, ua + 1)) != MP_OK) goto CLEANUP;
3026 da = MP_DIGITS(a);
3027 r.digits = da + ua - 1; /* The contents of r are shared with a */
3028 r.used = 1;
3029 r.sign = MP_ZPOS;
3030 r.alloc = MP_ALLOC(a);
3031 ZERO(t.digits, t.alloc);
3033 /* Solve for quotient digits, store in q.digits in reverse order */
3034 while(r.digits >= da) {
3035 assert(qpos <= q.alloc);
3037 if(s_ucmp(b, &r) > 0) {
3038 r.digits -= 1;
3039 r.used += 1;
3041 if(++skip > 1 && qpos > 0)
3042 q.digits[qpos++] = 0;
3044 CLAMP(&r);
3046 else {
3047 mp_word pfx = r.digits[r.used - 1];
3048 mp_word qdigit;
3050 if(r.used > 1 && pfx <= btop) {
3051 pfx <<= MP_DIGIT_BIT / 2;
3052 pfx <<= MP_DIGIT_BIT / 2;
3053 pfx |= r.digits[r.used - 2];
3056 qdigit = pfx / btop;
3057 if(qdigit > MP_DIGIT_MAX) {
3058 if(qdigit & MP_DIGIT_MAX)
3059 qdigit = MP_DIGIT_MAX;
3060 else
3061 qdigit = 1;
3064 s_dbmul(MP_DIGITS(b), (mp_digit) qdigit, t.digits, ub);
3065 t.used = ub + 1; CLAMP(&t);
3066 while(s_ucmp(&t, &r) > 0) {
3067 --qdigit;
3068 (void) mp_int_sub(&t, b, &t); /* cannot fail */
3071 s_usub(r.digits, t.digits, r.digits, r.used, t.used);
3072 CLAMP(&r);
3074 q.digits[qpos++] = (mp_digit) qdigit;
3075 ZERO(t.digits, t.used);
3076 skip = 0;
3080 /* Put quotient digits in the correct order, and discard extra zeroes */
3081 q.used = qpos;
3082 REV(mp_digit, q.digits, qpos);
3083 CLAMP(&q);
3085 /* Denormalize the remainder */
3086 CLAMP(a);
3087 if(k != 0)
3088 s_qdiv(a, k);
3090 mp_int_copy(a, b); /* ok: 0 <= r < b */
3091 mp_int_copy(&q, a); /* ok: q <= a */
3093 mp_int_clear(&t);
3094 CLEANUP:
3095 mp_int_clear(&q);
3096 return res;
3099 /* }}} */
3101 /* {{{ s_outlen(z, r) */
3103 /* Precondition: 2 <= r < 64 */
3104 static int s_outlen(mp_int z, mp_size r)
3106 mp_result bits;
3107 double raw;
3109 bits = mp_int_count_bits(z);
3110 raw = (double)bits * s_log2[r];
3112 return (int)(raw + 0.999999);
3115 /* }}} */
3117 /* {{{ s_inlen(len, r) */
3119 static mp_size s_inlen(int len, mp_size r)
3121 double raw = (double)len / s_log2[r];
3122 mp_size bits = (mp_size)(raw + 0.5);
3124 return (mp_size)((bits + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT);
3127 /* }}} */
3129 /* {{{ s_ch2val(c, r) */
3131 static int s_ch2val(char c, int r)
3133 int out;
3135 if(isdigit((unsigned char) c))
3136 out = c - '0';
3137 else if(r > 10 && isalpha((unsigned char) c))
3138 out = toupper((unsigned char)c) - 'A' + 10;
3139 else
3140 return -1;
3142 return (out >= r) ? -1 : out;
3145 /* }}} */
3147 /* {{{ s_val2ch(v, caps) */
3149 static char s_val2ch(int v, int caps)
3151 assert(v >= 0);
3153 if(v < 10)
3154 return v + '0';
3155 else {
3156 char out = (v - 10) + 'a';
3158 if(caps)
3159 return toupper((unsigned char)out);
3160 else
3161 return out;
3165 /* }}} */
3167 /* {{{ s_2comp(buf, len) */
3169 static void s_2comp(unsigned char *buf, int len)
3171 int i;
3172 unsigned short s = 1;
3174 for(i = len - 1; i >= 0; --i) {
3175 unsigned char c = ~buf[i];
3177 s = c + s;
3178 c = s & UCHAR_MAX;
3179 s >>= CHAR_BIT;
3181 buf[i] = c;
3184 /* last carry out is ignored */
3187 /* }}} */
3189 /* {{{ s_tobin(z, buf, *limpos) */
3191 static mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad)
3193 mp_size uz;
3194 mp_digit *dz;
3195 int pos = 0, limit = *limpos;
3197 uz = MP_USED(z); dz = MP_DIGITS(z);
3198 while(uz > 0 && pos < limit) {
3199 mp_digit d = *dz++;
3200 int i;
3202 for(i = sizeof(mp_digit); i > 0 && pos < limit; --i) {
3203 buf[pos++] = (unsigned char)d;
3204 d >>= CHAR_BIT;
3206 /* Don't write leading zeroes */
3207 if(d == 0 && uz == 1)
3208 i = 0; /* exit loop without signaling truncation */
3211 /* Detect truncation (loop exited with pos >= limit) */
3212 if(i > 0) break;
3214 --uz;
3217 if(pad != 0 && (buf[pos - 1] >> (CHAR_BIT - 1))) {
3218 if(pos < limit)
3219 buf[pos++] = 0;
3220 else
3221 uz = 1;
3224 /* Digits are in reverse order, fix that */
3225 REV(unsigned char, buf, pos);
3227 /* Return the number of bytes actually written */
3228 *limpos = pos;
3230 return (uz == 0) ? MP_OK : MP_TRUNC;
3233 /* }}} */
3235 /* {{{ s_print(tag, z) */
3237 #if DEBUG
3238 void s_print(char *tag, mp_int z)
3240 int i;
3242 fprintf(stderr, "%s: %c ", tag,
3243 (MP_SIGN(z) == MP_NEG) ? '-' : '+');
3245 for(i = MP_USED(z) - 1; i >= 0; --i)
3246 fprintf(stderr, "%0*X", (int)(MP_DIGIT_BIT / 4), z->digits[i]);
3248 fputc('\n', stderr);
3252 void s_print_buf(char *tag, mp_digit *buf, mp_size num)
3254 int i;
3256 fprintf(stderr, "%s: ", tag);
3258 for(i = num - 1; i >= 0; --i)
3259 fprintf(stderr, "%0*X", (int)(MP_DIGIT_BIT / 4), buf[i]);
3261 fputc('\n', stderr);
3263 #endif
3265 /* }}} */
3267 /* HERE THERE BE DRAGONS */