1 /* Start: bn_cutoffs.c */
2 #include "tommath_private.h"
3 #ifdef BN_CUTOFFS_C
4 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5 /* SPDX-License-Identifier: Unlicense */
6 
7 #ifndef MP_FIXED_CUTOFFS
8 #include "tommath_cutoffs.h"
9 int KARATSUBA_MUL_CUTOFF = MP_DEFAULT_KARATSUBA_MUL_CUTOFF,
10     KARATSUBA_SQR_CUTOFF = MP_DEFAULT_KARATSUBA_SQR_CUTOFF,
11     TOOM_MUL_CUTOFF = MP_DEFAULT_TOOM_MUL_CUTOFF,
12     TOOM_SQR_CUTOFF = MP_DEFAULT_TOOM_SQR_CUTOFF;
13 #endif
14 
15 #endif
16 
17 /* End: bn_cutoffs.c */
18 
19 /* Start: bn_deprecated.c */
20 #include "tommath_private.h"
21 #ifdef BN_DEPRECATED_C
22 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
23 /* SPDX-License-Identifier: Unlicense */
24 
25 #ifdef BN_MP_GET_BIT_C
mp_get_bit(const mp_int * a,int b)26 int mp_get_bit(const mp_int *a, int b)
27 {
28    if (b < 0) {
29       return MP_VAL;
30    }
31    return (s_mp_get_bit(a, (unsigned int)b) == MP_YES) ? MP_YES : MP_NO;
32 }
33 #endif
34 #ifdef BN_MP_JACOBI_C
mp_jacobi(const mp_int * a,const mp_int * n,int * c)35 mp_err mp_jacobi(const mp_int *a, const mp_int *n, int *c)
36 {
37    if (a->sign == MP_NEG) {
38       return MP_VAL;
39    }
40    if (mp_cmp_d(n, 0uL) != MP_GT) {
41       return MP_VAL;
42    }
43    return mp_kronecker(a, n, c);
44 }
45 #endif
46 #ifdef BN_MP_PRIME_RANDOM_EX_C
mp_prime_random_ex(mp_int * a,int t,int size,int flags,private_mp_prime_callback cb,void * dat)47 mp_err mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_prime_callback cb, void *dat)
48 {
49    return s_mp_prime_random_ex(a, t, size, flags, cb, dat);
50 }
51 #endif
52 #ifdef BN_MP_RAND_DIGIT_C
mp_rand_digit(mp_digit * r)53 mp_err mp_rand_digit(mp_digit *r)
54 {
55    mp_err err = s_mp_rand_source(r, sizeof(mp_digit));
56    *r &= MP_MASK;
57    return err;
58 }
59 #endif
60 #ifdef BN_FAST_MP_INVMOD_C
fast_mp_invmod(const mp_int * a,const mp_int * b,mp_int * c)61 mp_err fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c)
62 {
63    return s_mp_invmod_fast(a, b, c);
64 }
65 #endif
66 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
fast_mp_montgomery_reduce(mp_int * x,const mp_int * n,mp_digit rho)67 mp_err fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho)
68 {
69    return s_mp_montgomery_reduce_fast(x, n, rho);
70 }
71 #endif
72 #ifdef BN_FAST_S_MP_MUL_DIGS_C
fast_s_mp_mul_digs(const mp_int * a,const mp_int * b,mp_int * c,int digs)73 mp_err fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
74 {
75    return s_mp_mul_digs_fast(a, b, c, digs);
76 }
77 #endif
78 #ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
fast_s_mp_mul_high_digs(const mp_int * a,const mp_int * b,mp_int * c,int digs)79 mp_err fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
80 {
81    return s_mp_mul_high_digs_fast(a, b, c, digs);
82 }
83 #endif
84 #ifdef BN_FAST_S_MP_SQR_C
fast_s_mp_sqr(const mp_int * a,mp_int * b)85 mp_err fast_s_mp_sqr(const mp_int *a, mp_int *b)
86 {
87    return s_mp_sqr_fast(a, b);
88 }
89 #endif
90 #ifdef BN_MP_BALANCE_MUL_C
mp_balance_mul(const mp_int * a,const mp_int * b,mp_int * c)91 mp_err mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c)
92 {
93    return s_mp_balance_mul(a, b, c);
94 }
95 #endif
96 #ifdef BN_MP_EXPTMOD_FAST_C
mp_exptmod_fast(const mp_int * G,const mp_int * X,const mp_int * P,mp_int * Y,int redmode)97 mp_err mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode)
98 {
99    return s_mp_exptmod_fast(G, X, P, Y, redmode);
100 }
101 #endif
102 #ifdef BN_MP_INVMOD_SLOW_C
mp_invmod_slow(const mp_int * a,const mp_int * b,mp_int * c)103 mp_err mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c)
104 {
105    return s_mp_invmod_slow(a, b, c);
106 }
107 #endif
108 #ifdef BN_MP_KARATSUBA_MUL_C
mp_karatsuba_mul(const mp_int * a,const mp_int * b,mp_int * c)109 mp_err mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c)
110 {
111    return s_mp_karatsuba_mul(a, b, c);
112 }
113 #endif
114 #ifdef BN_MP_KARATSUBA_SQR_C
mp_karatsuba_sqr(const mp_int * a,mp_int * b)115 mp_err mp_karatsuba_sqr(const mp_int *a, mp_int *b)
116 {
117    return s_mp_karatsuba_sqr(a, b);
118 }
119 #endif
120 #ifdef BN_MP_TOOM_MUL_C
mp_toom_mul(const mp_int * a,const mp_int * b,mp_int * c)121 mp_err mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c)
122 {
123    return s_mp_toom_mul(a, b, c);
124 }
125 #endif
126 #ifdef BN_MP_TOOM_SQR_C
mp_toom_sqr(const mp_int * a,mp_int * b)127 mp_err mp_toom_sqr(const mp_int *a, mp_int *b)
128 {
129    return s_mp_toom_sqr(a, b);
130 }
131 #endif
132 #ifdef S_MP_REVERSE_C
bn_reverse(unsigned char * s,int len)133 void bn_reverse(unsigned char *s, int len)
134 {
135    if (len > 0) {
136       s_mp_reverse(s, (size_t)len);
137    }
138 }
139 #endif
140 #ifdef BN_MP_TC_AND_C
mp_tc_and(const mp_int * a,const mp_int * b,mp_int * c)141 mp_err mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c)
142 {
143    return mp_and(a, b, c);
144 }
145 #endif
146 #ifdef BN_MP_TC_OR_C
mp_tc_or(const mp_int * a,const mp_int * b,mp_int * c)147 mp_err mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c)
148 {
149    return mp_or(a, b, c);
150 }
151 #endif
152 #ifdef BN_MP_TC_XOR_C
mp_tc_xor(const mp_int * a,const mp_int * b,mp_int * c)153 mp_err mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c)
154 {
155    return mp_xor(a, b, c);
156 }
157 #endif
158 #ifdef BN_MP_TC_DIV_2D_C
mp_tc_div_2d(const mp_int * a,int b,mp_int * c)159 mp_err mp_tc_div_2d(const mp_int *a, int b, mp_int *c)
160 {
161    return mp_signed_rsh(a, b, c);
162 }
163 #endif
164 #ifdef BN_MP_INIT_SET_INT_C
mp_init_set_int(mp_int * a,unsigned long b)165 mp_err mp_init_set_int(mp_int *a, unsigned long b)
166 {
167    return mp_init_u32(a, (uint32_t)b);
168 }
169 #endif
170 #ifdef BN_MP_SET_INT_C
mp_set_int(mp_int * a,unsigned long b)171 mp_err mp_set_int(mp_int *a, unsigned long b)
172 {
173    mp_set_u32(a, (uint32_t)b);
174    return MP_OKAY;
175 }
176 #endif
177 #ifdef BN_MP_SET_LONG_C
mp_set_long(mp_int * a,unsigned long b)178 mp_err mp_set_long(mp_int *a, unsigned long b)
179 {
180    mp_set_u64(a, b);
181    return MP_OKAY;
182 }
183 #endif
184 #ifdef BN_MP_SET_LONG_LONG_C
mp_set_long_long(mp_int * a,unsigned long long b)185 mp_err mp_set_long_long(mp_int *a, unsigned long long b)
186 {
187    mp_set_u64(a, b);
188    return MP_OKAY;
189 }
190 #endif
191 #ifdef BN_MP_GET_INT_C
mp_get_int(const mp_int * a)192 unsigned long mp_get_int(const mp_int *a)
193 {
194    return (unsigned long)mp_get_mag_u32(a);
195 }
196 #endif
197 #ifdef BN_MP_GET_LONG_C
mp_get_long(const mp_int * a)198 unsigned long mp_get_long(const mp_int *a)
199 {
200    return (unsigned long)mp_get_mag_ul(a);
201 }
202 #endif
203 #ifdef BN_MP_GET_LONG_LONG_C
mp_get_long_long(const mp_int * a)204 unsigned long long mp_get_long_long(const mp_int *a)
205 {
206    return mp_get_mag_ull(a);
207 }
208 #endif
209 #ifdef BN_MP_PRIME_IS_DIVISIBLE_C
mp_prime_is_divisible(const mp_int * a,mp_bool * result)210 mp_err mp_prime_is_divisible(const mp_int *a, mp_bool *result)
211 {
212    return s_mp_prime_is_divisible(a, result);
213 }
214 #endif
215 #ifdef BN_MP_EXPT_D_EX_C
mp_expt_d_ex(const mp_int * a,mp_digit b,mp_int * c,int fast)216 mp_err mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast)
217 {
218    (void)fast;
219    if (b > MP_MIN(MP_DIGIT_MAX, UINT32_MAX)) {
220       return MP_VAL;
221    }
222    return mp_expt_u32(a, (uint32_t)b, c);
223 }
224 #endif
225 #ifdef BN_MP_EXPT_D_C
mp_expt_d(const mp_int * a,mp_digit b,mp_int * c)226 mp_err mp_expt_d(const mp_int *a, mp_digit b, mp_int *c)
227 {
228    if (b > MP_MIN(MP_DIGIT_MAX, UINT32_MAX)) {
229       return MP_VAL;
230    }
231    return mp_expt_u32(a, (uint32_t)b, c);
232 }
233 #endif
234 #ifdef BN_MP_N_ROOT_EX_C
mp_n_root_ex(const mp_int * a,mp_digit b,mp_int * c,int fast)235 mp_err mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast)
236 {
237    (void)fast;
238    if (b > MP_MIN(MP_DIGIT_MAX, UINT32_MAX)) {
239       return MP_VAL;
240    }
241    return mp_root_u32(a, (uint32_t)b, c);
242 }
243 #endif
244 #ifdef BN_MP_N_ROOT_C
mp_n_root(const mp_int * a,mp_digit b,mp_int * c)245 mp_err mp_n_root(const mp_int *a, mp_digit b, mp_int *c)
246 {
247    if (b > MP_MIN(MP_DIGIT_MAX, UINT32_MAX)) {
248       return MP_VAL;
249    }
250    return mp_root_u32(a, (uint32_t)b, c);
251 }
252 #endif
253 #ifdef BN_MP_UNSIGNED_BIN_SIZE_C
mp_unsigned_bin_size(const mp_int * a)254 int mp_unsigned_bin_size(const mp_int *a)
255 {
256    return (int)mp_ubin_size(a);
257 }
258 #endif
259 #ifdef BN_MP_READ_UNSIGNED_BIN_C
mp_read_unsigned_bin(mp_int * a,const unsigned char * b,int c)260 mp_err mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c)
261 {
262    return mp_from_ubin(a, b, (size_t) c);
263 }
264 #endif
265 #ifdef BN_MP_TO_UNSIGNED_BIN_C
mp_to_unsigned_bin(const mp_int * a,unsigned char * b)266 mp_err mp_to_unsigned_bin(const mp_int *a, unsigned char *b)
267 {
268    return mp_to_ubin(a, b, SIZE_MAX, NULL);
269 }
270 #endif
271 #ifdef BN_MP_TO_UNSIGNED_BIN_N_C
mp_to_unsigned_bin_n(const mp_int * a,unsigned char * b,unsigned long * outlen)272 mp_err mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen)
273 {
274    size_t n = mp_ubin_size(a);
275    if (*outlen < (unsigned long)n) {
276       return MP_VAL;
277    }
278    *outlen = (unsigned long)n;
279    return mp_to_ubin(a, b, n, NULL);
280 }
281 #endif
282 #ifdef BN_MP_SIGNED_BIN_SIZE_C
mp_signed_bin_size(const mp_int * a)283 int mp_signed_bin_size(const mp_int *a)
284 {
285    return (int)mp_sbin_size(a);
286 }
287 #endif
288 #ifdef BN_MP_READ_SIGNED_BIN_C
mp_read_signed_bin(mp_int * a,const unsigned char * b,int c)289 mp_err mp_read_signed_bin(mp_int *a, const unsigned char *b, int c)
290 {
291    return mp_from_sbin(a, b, (size_t) c);
292 }
293 #endif
294 #ifdef BN_MP_TO_SIGNED_BIN_C
mp_to_signed_bin(const mp_int * a,unsigned char * b)295 mp_err mp_to_signed_bin(const mp_int *a, unsigned char *b)
296 {
297    return mp_to_sbin(a, b, SIZE_MAX, NULL);
298 }
299 #endif
300 #ifdef BN_MP_TO_SIGNED_BIN_N_C
mp_to_signed_bin_n(const mp_int * a,unsigned char * b,unsigned long * outlen)301 mp_err mp_to_signed_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen)
302 {
303    size_t n = mp_sbin_size(a);
304    if (*outlen < (unsigned long)n) {
305       return MP_VAL;
306    }
307    *outlen = (unsigned long)n;
308    return mp_to_sbin(a, b, n, NULL);
309 }
310 #endif
311 #ifdef BN_MP_TORADIX_N_C
mp_toradix_n(const mp_int * a,char * str,int radix,int maxlen)312 mp_err mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen)
313 {
314    if (maxlen < 0) {
315       return MP_VAL;
316    }
317    return mp_to_radix(a, str, (size_t)maxlen, NULL, radix);
318 }
319 #endif
320 #ifdef BN_MP_TORADIX_C
mp_toradix(const mp_int * a,char * str,int radix)321 mp_err mp_toradix(const mp_int *a, char *str, int radix)
322 {
323    return mp_to_radix(a, str, SIZE_MAX, NULL, radix);
324 }
325 #endif
326 #ifdef BN_MP_IMPORT_C
mp_import(mp_int * rop,size_t count,int order,size_t size,int endian,size_t nails,const void * op)327 mp_err mp_import(mp_int *rop, size_t count, int order, size_t size, int endian, size_t nails,
328                  const void *op)
329 {
330    return mp_unpack(rop, count, order, size, endian, nails, op);
331 }
332 #endif
333 #ifdef BN_MP_EXPORT_C
mp_export(void * rop,size_t * countp,int order,size_t size,int endian,size_t nails,const mp_int * op)334 mp_err mp_export(void *rop, size_t *countp, int order, size_t size,
335                  int endian, size_t nails, const mp_int *op)
336 {
337    return mp_pack(rop, SIZE_MAX, countp, order, size, endian, nails, op);
338 }
339 #endif
340 #endif
341 
342 /* End: bn_deprecated.c */
343 
344 /* Start: bn_mp_2expt.c */
345 #include "tommath_private.h"
346 #ifdef BN_MP_2EXPT_C
347 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
348 /* SPDX-License-Identifier: Unlicense */
349 
350 /* computes a = 2**b
351  *
352  * Simple algorithm which zeroes the int, grows it then just sets one bit
353  * as required.
354  */
mp_2expt(mp_int * a,int b)355 mp_err mp_2expt(mp_int *a, int b)
356 {
357    mp_err    err;
358 
359    /* zero a as per default */
360    mp_zero(a);
361 
362    /* grow a to accomodate the single bit */
363    if ((err = mp_grow(a, (b / MP_DIGIT_BIT) + 1)) != MP_OKAY) {
364       return err;
365    }
366 
367    /* set the used count of where the bit will go */
368    a->used = (b / MP_DIGIT_BIT) + 1;
369 
370    /* put the single bit in its place */
371    a->dp[b / MP_DIGIT_BIT] = (mp_digit)1 << (mp_digit)(b % MP_DIGIT_BIT);
372 
373    return MP_OKAY;
374 }
375 #endif
376 
377 /* End: bn_mp_2expt.c */
378 
379 /* Start: bn_mp_abs.c */
380 #include "tommath_private.h"
381 #ifdef BN_MP_ABS_C
382 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
383 /* SPDX-License-Identifier: Unlicense */
384 
385 /* b = |a|
386  *
387  * Simple function copies the input and fixes the sign to positive
388  */
mp_abs(const mp_int * a,mp_int * b)389 mp_err mp_abs(const mp_int *a, mp_int *b)
390 {
391    mp_err     err;
392 
393    /* copy a to b */
394    if (a != b) {
395       if ((err = mp_copy(a, b)) != MP_OKAY) {
396          return err;
397       }
398    }
399 
400    /* force the sign of b to positive */
401    b->sign = MP_ZPOS;
402 
403    return MP_OKAY;
404 }
405 #endif
406 
407 /* End: bn_mp_abs.c */
408 
409 /* Start: bn_mp_add.c */
410 #include "tommath_private.h"
411 #ifdef BN_MP_ADD_C
412 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
413 /* SPDX-License-Identifier: Unlicense */
414 
415 /* high level addition (handles signs) */
mp_add(const mp_int * a,const mp_int * b,mp_int * c)416 mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c)
417 {
418    mp_sign sa, sb;
419    mp_err err;
420 
421    /* get sign of both inputs */
422    sa = a->sign;
423    sb = b->sign;
424 
425    /* handle two cases, not four */
426    if (sa == sb) {
427       /* both positive or both negative */
428       /* add their magnitudes, copy the sign */
429       c->sign = sa;
430       err = s_mp_add(a, b, c);
431    } else {
432       /* one positive, the other negative */
433       /* subtract the one with the greater magnitude from */
434       /* the one of the lesser magnitude.  The result gets */
435       /* the sign of the one with the greater magnitude. */
436       if (mp_cmp_mag(a, b) == MP_LT) {
437          c->sign = sb;
438          err = s_mp_sub(b, a, c);
439       } else {
440          c->sign = sa;
441          err = s_mp_sub(a, b, c);
442       }
443    }
444    return err;
445 }
446 
447 #endif
448 
449 /* End: bn_mp_add.c */
450 
451 /* Start: bn_mp_add_d.c */
452 #include "tommath_private.h"
453 #ifdef BN_MP_ADD_D_C
454 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
455 /* SPDX-License-Identifier: Unlicense */
456 
457 /* single digit addition */
mp_add_d(const mp_int * a,mp_digit b,mp_int * c)458 mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c)
459 {
460    mp_err     err;
461    int ix, oldused;
462    mp_digit *tmpa, *tmpc;
463 
464    /* grow c as required */
465    if (c->alloc < (a->used + 1)) {
466       if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) {
467          return err;
468       }
469    }
470 
471    /* if a is negative and |a| >= b, call c = |a| - b */
472    if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) {
473       mp_int a_ = *a;
474       /* temporarily fix sign of a */
475       a_.sign = MP_ZPOS;
476 
477       /* c = |a| - b */
478       err = mp_sub_d(&a_, b, c);
479 
480       /* fix sign  */
481       c->sign = MP_NEG;
482 
483       /* clamp */
484       mp_clamp(c);
485 
486       return err;
487    }
488 
489    /* old number of used digits in c */
490    oldused = c->used;
491 
492    /* source alias */
493    tmpa    = a->dp;
494 
495    /* destination alias */
496    tmpc    = c->dp;
497 
498    /* if a is positive */
499    if (a->sign == MP_ZPOS) {
500       /* add digits, mu is carry */
501       mp_digit mu = b;
502       for (ix = 0; ix < a->used; ix++) {
503          *tmpc   = *tmpa++ + mu;
504          mu      = *tmpc >> MP_DIGIT_BIT;
505          *tmpc++ &= MP_MASK;
506       }
507       /* set final carry */
508       ix++;
509       *tmpc++  = mu;
510 
511       /* setup size */
512       c->used = a->used + 1;
513    } else {
514       /* a was negative and |a| < b */
515       c->used  = 1;
516 
517       /* the result is a single digit */
518       if (a->used == 1) {
519          *tmpc++  =  b - a->dp[0];
520       } else {
521          *tmpc++  =  b;
522       }
523 
524       /* setup count so the clearing of oldused
525        * can fall through correctly
526        */
527       ix       = 1;
528    }
529 
530    /* sign always positive */
531    c->sign = MP_ZPOS;
532 
533    /* now zero to oldused */
534    MP_ZERO_DIGITS(tmpc, oldused - ix);
535    mp_clamp(c);
536 
537    return MP_OKAY;
538 }
539 
540 #endif
541 
542 /* End: bn_mp_add_d.c */
543 
544 /* Start: bn_mp_addmod.c */
545 #include "tommath_private.h"
546 #ifdef BN_MP_ADDMOD_C
547 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
548 /* SPDX-License-Identifier: Unlicense */
549 
550 /* d = a + b (mod c) */
mp_addmod(const mp_int * a,const mp_int * b,const mp_int * c,mp_int * d)551 mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d)
552 {
553    mp_err  err;
554    mp_int  t;
555 
556    if ((err = mp_init(&t)) != MP_OKAY) {
557       return err;
558    }
559 
560    if ((err = mp_add(a, b, &t)) != MP_OKAY) {
561       goto LBL_ERR;
562    }
563    err = mp_mod(&t, c, d);
564 
565 LBL_ERR:
566    mp_clear(&t);
567    return err;
568 }
569 #endif
570 
571 /* End: bn_mp_addmod.c */
572 
573 /* Start: bn_mp_and.c */
574 #include "tommath_private.h"
575 #ifdef BN_MP_AND_C
576 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
577 /* SPDX-License-Identifier: Unlicense */
578 
579 /* two complement and */
mp_and(const mp_int * a,const mp_int * b,mp_int * c)580 mp_err mp_and(const mp_int *a, const mp_int *b, mp_int *c)
581 {
582    int used = MP_MAX(a->used, b->used) + 1, i;
583    mp_err err;
584    mp_digit ac = 1, bc = 1, cc = 1;
585    mp_sign csign = ((a->sign == MP_NEG) && (b->sign == MP_NEG)) ? MP_NEG : MP_ZPOS;
586 
587    if (c->alloc < used) {
588       if ((err = mp_grow(c, used)) != MP_OKAY) {
589          return err;
590       }
591    }
592 
593    for (i = 0; i < used; i++) {
594       mp_digit x, y;
595 
596       /* convert to two complement if negative */
597       if (a->sign == MP_NEG) {
598          ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK);
599          x = ac & MP_MASK;
600          ac >>= MP_DIGIT_BIT;
601       } else {
602          x = (i >= a->used) ? 0uL : a->dp[i];
603       }
604 
605       /* convert to two complement if negative */
606       if (b->sign == MP_NEG) {
607          bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK);
608          y = bc & MP_MASK;
609          bc >>= MP_DIGIT_BIT;
610       } else {
611          y = (i >= b->used) ? 0uL : b->dp[i];
612       }
613 
614       c->dp[i] = x & y;
615 
616       /* convert to to sign-magnitude if negative */
617       if (csign == MP_NEG) {
618          cc += ~c->dp[i] & MP_MASK;
619          c->dp[i] = cc & MP_MASK;
620          cc >>= MP_DIGIT_BIT;
621       }
622    }
623 
624    c->used = used;
625    c->sign = csign;
626    mp_clamp(c);
627    return MP_OKAY;
628 }
629 #endif
630 
631 /* End: bn_mp_and.c */
632 
633 /* Start: bn_mp_clamp.c */
634 #include "tommath_private.h"
635 #ifdef BN_MP_CLAMP_C
636 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
637 /* SPDX-License-Identifier: Unlicense */
638 
639 /* trim unused digits
640  *
641  * This is used to ensure that leading zero digits are
642  * trimed and the leading "used" digit will be non-zero
643  * Typically very fast.  Also fixes the sign if there
644  * are no more leading digits
645  */
mp_clamp(mp_int * a)646 void mp_clamp(mp_int *a)
647 {
648    /* decrease used while the most significant digit is
649     * zero.
650     */
651    while ((a->used > 0) && (a->dp[a->used - 1] == 0u)) {
652       --(a->used);
653    }
654 
655    /* reset the sign flag if used == 0 */
656    if (a->used == 0) {
657       a->sign = MP_ZPOS;
658    }
659 }
660 #endif
661 
662 /* End: bn_mp_clamp.c */
663 
664 /* Start: bn_mp_clear.c */
665 #include "tommath_private.h"
666 #ifdef BN_MP_CLEAR_C
667 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
668 /* SPDX-License-Identifier: Unlicense */
669 
670 /* clear one (frees)  */
mp_clear(mp_int * a)671 void mp_clear(mp_int *a)
672 {
673    /* only do anything if a hasn't been freed previously */
674    if (a->dp != NULL) {
675       /* free ram */
676       MP_FREE_DIGITS(a->dp, a->alloc);
677 
678       /* reset members to make debugging easier */
679       a->dp    = NULL;
680       a->alloc = a->used = 0;
681       a->sign  = MP_ZPOS;
682    }
683 }
684 #endif
685 
686 /* End: bn_mp_clear.c */
687 
688 /* Start: bn_mp_clear_multi.c */
689 #include "tommath_private.h"
690 #ifdef BN_MP_CLEAR_MULTI_C
691 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
692 /* SPDX-License-Identifier: Unlicense */
693 
694 #include <stdarg.h>
695 
mp_clear_multi(mp_int * mp,...)696 void mp_clear_multi(mp_int *mp, ...)
697 {
698    mp_int *next_mp = mp;
699    va_list args;
700    va_start(args, mp);
701    while (next_mp != NULL) {
702       mp_clear(next_mp);
703       next_mp = va_arg(args, mp_int *);
704    }
705    va_end(args);
706 }
707 #endif
708 
709 /* End: bn_mp_clear_multi.c */
710 
711 /* Start: bn_mp_cmp.c */
712 #include "tommath_private.h"
713 #ifdef BN_MP_CMP_C
714 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
715 /* SPDX-License-Identifier: Unlicense */
716 
717 /* compare two ints (signed)*/
mp_cmp(const mp_int * a,const mp_int * b)718 mp_ord mp_cmp(const mp_int *a, const mp_int *b)
719 {
720    /* compare based on sign */
721    if (a->sign != b->sign) {
722       if (a->sign == MP_NEG) {
723          return MP_LT;
724       } else {
725          return MP_GT;
726       }
727    }
728 
729    /* compare digits */
730    if (a->sign == MP_NEG) {
731       /* if negative compare opposite direction */
732       return mp_cmp_mag(b, a);
733    } else {
734       return mp_cmp_mag(a, b);
735    }
736 }
737 #endif
738 
739 /* End: bn_mp_cmp.c */
740 
741 /* Start: bn_mp_cmp_d.c */
742 #include "tommath_private.h"
743 #ifdef BN_MP_CMP_D_C
744 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
745 /* SPDX-License-Identifier: Unlicense */
746 
747 /* compare a digit */
mp_cmp_d(const mp_int * a,mp_digit b)748 mp_ord mp_cmp_d(const mp_int *a, mp_digit b)
749 {
750    /* compare based on sign */
751    if (a->sign == MP_NEG) {
752       return MP_LT;
753    }
754 
755    /* compare based on magnitude */
756    if (a->used > 1) {
757       return MP_GT;
758    }
759 
760    /* compare the only digit of a to b */
761    if (a->dp[0] > b) {
762       return MP_GT;
763    } else if (a->dp[0] < b) {
764       return MP_LT;
765    } else {
766       return MP_EQ;
767    }
768 }
769 #endif
770 
771 /* End: bn_mp_cmp_d.c */
772 
773 /* Start: bn_mp_cmp_mag.c */
774 #include "tommath_private.h"
775 #ifdef BN_MP_CMP_MAG_C
776 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
777 /* SPDX-License-Identifier: Unlicense */
778 
779 /* compare maginitude of two ints (unsigned) */
mp_cmp_mag(const mp_int * a,const mp_int * b)780 mp_ord mp_cmp_mag(const mp_int *a, const mp_int *b)
781 {
782    int     n;
783    const mp_digit *tmpa, *tmpb;
784 
785    /* compare based on # of non-zero digits */
786    if (a->used > b->used) {
787       return MP_GT;
788    }
789 
790    if (a->used < b->used) {
791       return MP_LT;
792    }
793 
794    /* alias for a */
795    tmpa = a->dp + (a->used - 1);
796 
797    /* alias for b */
798    tmpb = b->dp + (a->used - 1);
799 
800    /* compare based on digits  */
801    for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
802       if (*tmpa > *tmpb) {
803          return MP_GT;
804       }
805 
806       if (*tmpa < *tmpb) {
807          return MP_LT;
808       }
809    }
810    return MP_EQ;
811 }
812 #endif
813 
814 /* End: bn_mp_cmp_mag.c */
815 
816 /* Start: bn_mp_cnt_lsb.c */
817 #include "tommath_private.h"
818 #ifdef BN_MP_CNT_LSB_C
819 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
820 /* SPDX-License-Identifier: Unlicense */
821 
822 static const int lnz[16] = {
823    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
824 };
825 
826 /* Counts the number of lsbs which are zero before the first zero bit */
mp_cnt_lsb(const mp_int * a)827 int mp_cnt_lsb(const mp_int *a)
828 {
829    int x;
830    mp_digit q, qq;
831 
832    /* easy out */
833    if (MP_IS_ZERO(a)) {
834       return 0;
835    }
836 
837    /* scan lower digits until non-zero */
838    for (x = 0; (x < a->used) && (a->dp[x] == 0u); x++) {}
839    q = a->dp[x];
840    x *= MP_DIGIT_BIT;
841 
842    /* now scan this digit until a 1 is found */
843    if ((q & 1u) == 0u) {
844       do {
845          qq  = q & 15u;
846          x  += lnz[qq];
847          q >>= 4;
848       } while (qq == 0u);
849    }
850    return x;
851 }
852 
853 #endif
854 
855 /* End: bn_mp_cnt_lsb.c */
856 
857 /* Start: bn_mp_complement.c */
858 #include "tommath_private.h"
859 #ifdef BN_MP_COMPLEMENT_C
860 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
861 /* SPDX-License-Identifier: Unlicense */
862 
863 /* b = ~a */
mp_complement(const mp_int * a,mp_int * b)864 mp_err mp_complement(const mp_int *a, mp_int *b)
865 {
866    mp_err err = mp_neg(a, b);
867    return (err == MP_OKAY) ? mp_sub_d(b, 1uL, b) : err;
868 }
869 #endif
870 
871 /* End: bn_mp_complement.c */
872 
873 /* Start: bn_mp_copy.c */
874 #include "tommath_private.h"
875 #ifdef BN_MP_COPY_C
876 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
877 /* SPDX-License-Identifier: Unlicense */
878 
879 /* copy, b = a */
mp_copy(const mp_int * a,mp_int * b)880 mp_err mp_copy(const mp_int *a, mp_int *b)
881 {
882    int n;
883    mp_digit *tmpa, *tmpb;
884    mp_err err;
885 
886    /* if dst == src do nothing */
887    if (a == b) {
888       return MP_OKAY;
889    }
890 
891    /* grow dest */
892    if (b->alloc < a->used) {
893       if ((err = mp_grow(b, a->used)) != MP_OKAY) {
894          return err;
895       }
896    }
897 
898    /* zero b and copy the parameters over */
899    /* pointer aliases */
900 
901    /* source */
902    tmpa = a->dp;
903 
904    /* destination */
905    tmpb = b->dp;
906 
907    /* copy all the digits */
908    for (n = 0; n < a->used; n++) {
909       *tmpb++ = *tmpa++;
910    }
911 
912    /* clear high digits */
913    MP_ZERO_DIGITS(tmpb, b->used - n);
914 
915    /* copy used count and sign */
916    b->used = a->used;
917    b->sign = a->sign;
918    return MP_OKAY;
919 }
920 #endif
921 
922 /* End: bn_mp_copy.c */
923 
924 /* Start: bn_mp_count_bits.c */
925 #include "tommath_private.h"
926 #ifdef BN_MP_COUNT_BITS_C
927 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
928 /* SPDX-License-Identifier: Unlicense */
929 
930 /* returns the number of bits in an int */
mp_count_bits(const mp_int * a)931 int mp_count_bits(const mp_int *a)
932 {
933    int     r;
934    mp_digit q;
935 
936    /* shortcut */
937    if (MP_IS_ZERO(a)) {
938       return 0;
939    }
940 
941    /* get number of digits and add that */
942    r = (a->used - 1) * MP_DIGIT_BIT;
943 
944    /* take the last digit and count the bits in it */
945    q = a->dp[a->used - 1];
946    while (q > 0u) {
947       ++r;
948       q >>= 1u;
949    }
950    return r;
951 }
952 #endif
953 
954 /* End: bn_mp_count_bits.c */
955 
956 /* Start: bn_mp_decr.c */
957 #include "tommath_private.h"
958 #ifdef BN_MP_DECR_C
959 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
960 /* SPDX-License-Identifier: Unlicense */
961 
962 /* Decrement "a" by one like "a--". Changes input! */
mp_decr(mp_int * a)963 mp_err mp_decr(mp_int *a)
964 {
965    if (MP_IS_ZERO(a)) {
966       mp_set(a,1uL);
967       a->sign = MP_NEG;
968       return MP_OKAY;
969    } else if (a->sign == MP_NEG) {
970       mp_err err;
971       a->sign = MP_ZPOS;
972       if ((err = mp_incr(a)) != MP_OKAY) {
973          return err;
974       }
975       /* There is no -0 in LTM */
976       if (!MP_IS_ZERO(a)) {
977          a->sign = MP_NEG;
978       }
979       return MP_OKAY;
980    } else if (a->dp[0] > 1uL) {
981       a->dp[0]--;
982       if (a->dp[0] == 0u) {
983          mp_zero(a);
984       }
985       return MP_OKAY;
986    } else {
987       return mp_sub_d(a, 1uL,a);
988    }
989 }
990 #endif
991 
992 /* End: bn_mp_decr.c */
993 
994 /* Start: bn_mp_div.c */
995 #include "tommath_private.h"
996 #ifdef BN_MP_DIV_C
997 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
998 /* SPDX-License-Identifier: Unlicense */
999 
1000 #ifdef BN_MP_DIV_SMALL
1001 
1002 /* slower bit-bang division... also smaller */
mp_div(const mp_int * a,const mp_int * b,mp_int * c,mp_int * d)1003 mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
1004 {
1005    mp_int ta, tb, tq, q;
1006    int     n, n2;
1007    mp_err err;
1008 
1009    /* is divisor zero ? */
1010    if (MP_IS_ZERO(b)) {
1011       return MP_VAL;
1012    }
1013 
1014    /* if a < b then q=0, r = a */
1015    if (mp_cmp_mag(a, b) == MP_LT) {
1016       if (d != NULL) {
1017          err = mp_copy(a, d);
1018       } else {
1019          err = MP_OKAY;
1020       }
1021       if (c != NULL) {
1022          mp_zero(c);
1023       }
1024       return err;
1025    }
1026 
1027    /* init our temps */
1028    if ((err = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) {
1029       return err;
1030    }
1031 
1032 
1033    mp_set(&tq, 1uL);
1034    n = mp_count_bits(a) - mp_count_bits(b);
1035    if ((err = mp_abs(a, &ta)) != MP_OKAY)                         goto LBL_ERR;
1036    if ((err = mp_abs(b, &tb)) != MP_OKAY)                         goto LBL_ERR;
1037    if ((err = mp_mul_2d(&tb, n, &tb)) != MP_OKAY)                 goto LBL_ERR;
1038    if ((err = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)                 goto LBL_ERR;
1039 
1040    while (n-- >= 0) {
1041       if (mp_cmp(&tb, &ta) != MP_GT) {
1042          if ((err = mp_sub(&ta, &tb, &ta)) != MP_OKAY)            goto LBL_ERR;
1043          if ((err = mp_add(&q, &tq, &q)) != MP_OKAY)              goto LBL_ERR;
1044       }
1045       if ((err = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY)        goto LBL_ERR;
1046       if ((err = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)        goto LBL_ERR;
1047    }
1048 
1049    /* now q == quotient and ta == remainder */
1050    n  = a->sign;
1051    n2 = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
1052    if (c != NULL) {
1053       mp_exch(c, &q);
1054       c->sign  = MP_IS_ZERO(c) ? MP_ZPOS : n2;
1055    }
1056    if (d != NULL) {
1057       mp_exch(d, &ta);
1058       d->sign = MP_IS_ZERO(d) ? MP_ZPOS : n;
1059    }
1060 LBL_ERR:
1061    mp_clear_multi(&ta, &tb, &tq, &q, NULL);
1062    return err;
1063 }
1064 
1065 #else
1066 
1067 /* integer signed division.
1068  * c*b + d == a [e.g. a/b, c=quotient, d=remainder]
1069  * HAC pp.598 Algorithm 14.20
1070  *
1071  * Note that the description in HAC is horribly
1072  * incomplete.  For example, it doesn't consider
1073  * the case where digits are removed from 'x' in
1074  * the inner loop.  It also doesn't consider the
1075  * case that y has fewer than three digits, etc..
1076  *
1077  * The overall algorithm is as described as
1078  * 14.20 from HAC but fixed to treat these cases.
1079 */
mp_div(const mp_int * a,const mp_int * b,mp_int * c,mp_int * d)1080 mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
1081 {
1082    mp_int  q, x, y, t1, t2;
1083    int     n, t, i, norm;
1084    mp_sign neg;
1085    mp_err  err;
1086 
1087    /* is divisor zero ? */
1088    if (MP_IS_ZERO(b)) {
1089       return MP_VAL;
1090    }
1091 
1092    /* if a < b then q=0, r = a */
1093    if (mp_cmp_mag(a, b) == MP_LT) {
1094       if (d != NULL) {
1095          err = mp_copy(a, d);
1096       } else {
1097          err = MP_OKAY;
1098       }
1099       if (c != NULL) {
1100          mp_zero(c);
1101       }
1102       return err;
1103    }
1104 
1105    if ((err = mp_init_size(&q, a->used + 2)) != MP_OKAY) {
1106       return err;
1107    }
1108    q.used = a->used + 2;
1109 
1110    if ((err = mp_init(&t1)) != MP_OKAY)                           goto LBL_Q;
1111 
1112    if ((err = mp_init(&t2)) != MP_OKAY)                           goto LBL_T1;
1113 
1114    if ((err = mp_init_copy(&x, a)) != MP_OKAY)                    goto LBL_T2;
1115 
1116    if ((err = mp_init_copy(&y, b)) != MP_OKAY)                    goto LBL_X;
1117 
1118    /* fix the sign */
1119    neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
1120    x.sign = y.sign = MP_ZPOS;
1121 
1122    /* normalize both x and y, ensure that y >= b/2, [b == 2**MP_DIGIT_BIT] */
1123    norm = mp_count_bits(&y) % MP_DIGIT_BIT;
1124    if (norm < (MP_DIGIT_BIT - 1)) {
1125       norm = (MP_DIGIT_BIT - 1) - norm;
1126       if ((err = mp_mul_2d(&x, norm, &x)) != MP_OKAY)             goto LBL_Y;
1127       if ((err = mp_mul_2d(&y, norm, &y)) != MP_OKAY)             goto LBL_Y;
1128    } else {
1129       norm = 0;
1130    }
1131 
1132    /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
1133    n = x.used - 1;
1134    t = y.used - 1;
1135 
1136    /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
1137    /* y = y*b**{n-t} */
1138    if ((err = mp_lshd(&y, n - t)) != MP_OKAY)                     goto LBL_Y;
1139 
1140    while (mp_cmp(&x, &y) != MP_LT) {
1141       ++(q.dp[n - t]);
1142       if ((err = mp_sub(&x, &y, &x)) != MP_OKAY)                  goto LBL_Y;
1143    }
1144 
1145    /* reset y by shifting it back down */
1146    mp_rshd(&y, n - t);
1147 
1148    /* step 3. for i from n down to (t + 1) */
1149    for (i = n; i >= (t + 1); i--) {
1150       if (i > x.used) {
1151          continue;
1152       }
1153 
1154       /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
1155        * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
1156       if (x.dp[i] == y.dp[t]) {
1157          q.dp[(i - t) - 1] = ((mp_digit)1 << (mp_digit)MP_DIGIT_BIT) - (mp_digit)1;
1158       } else {
1159          mp_word tmp;
1160          tmp = (mp_word)x.dp[i] << (mp_word)MP_DIGIT_BIT;
1161          tmp |= (mp_word)x.dp[i - 1];
1162          tmp /= (mp_word)y.dp[t];
1163          if (tmp > (mp_word)MP_MASK) {
1164             tmp = MP_MASK;
1165          }
1166          q.dp[(i - t) - 1] = (mp_digit)(tmp & (mp_word)MP_MASK);
1167       }
1168 
1169       /* while (q{i-t-1} * (yt * b + y{t-1})) >
1170                xi * b**2 + xi-1 * b + xi-2
1171 
1172          do q{i-t-1} -= 1;
1173       */
1174       q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] + 1uL) & (mp_digit)MP_MASK;
1175       do {
1176          q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & (mp_digit)MP_MASK;
1177 
1178          /* find left hand */
1179          mp_zero(&t1);
1180          t1.dp[0] = ((t - 1) < 0) ? 0u : y.dp[t - 1];
1181          t1.dp[1] = y.dp[t];
1182          t1.used = 2;
1183          if ((err = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) goto LBL_Y;
1184 
1185          /* find right hand */
1186          t2.dp[0] = ((i - 2) < 0) ? 0u : x.dp[i - 2];
1187          t2.dp[1] = x.dp[i - 1]; /* i >= 1 always holds */
1188          t2.dp[2] = x.dp[i];
1189          t2.used = 3;
1190       } while (mp_cmp_mag(&t1, &t2) == MP_GT);
1191 
1192       /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
1193       if ((err = mp_mul_d(&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) goto LBL_Y;
1194 
1195       if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY)           goto LBL_Y;
1196 
1197       if ((err = mp_sub(&x, &t1, &x)) != MP_OKAY)                 goto LBL_Y;
1198 
1199       /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
1200       if (x.sign == MP_NEG) {
1201          if ((err = mp_copy(&y, &t1)) != MP_OKAY)                 goto LBL_Y;
1202          if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY)        goto LBL_Y;
1203          if ((err = mp_add(&x, &t1, &x)) != MP_OKAY)              goto LBL_Y;
1204 
1205          q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & MP_MASK;
1206       }
1207    }
1208 
1209    /* now q is the quotient and x is the remainder
1210     * [which we have to normalize]
1211     */
1212 
1213    /* get sign before writing to c */
1214    x.sign = (x.used == 0) ? MP_ZPOS : a->sign;
1215 
1216    if (c != NULL) {
1217       mp_clamp(&q);
1218       mp_exch(&q, c);
1219       c->sign = neg;
1220    }
1221 
1222    if (d != NULL) {
1223       if ((err = mp_div_2d(&x, norm, &x, NULL)) != MP_OKAY)       goto LBL_Y;
1224       mp_exch(&x, d);
1225    }
1226 
1227    err = MP_OKAY;
1228 
1229 LBL_Y:
1230    mp_clear(&y);
1231 LBL_X:
1232    mp_clear(&x);
1233 LBL_T2:
1234    mp_clear(&t2);
1235 LBL_T1:
1236    mp_clear(&t1);
1237 LBL_Q:
1238    mp_clear(&q);
1239    return err;
1240 }
1241 
1242 #endif
1243 
1244 #endif
1245 
1246 /* End: bn_mp_div.c */
1247 
1248 /* Start: bn_mp_div_2.c */
1249 #include "tommath_private.h"
1250 #ifdef BN_MP_DIV_2_C
1251 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1252 /* SPDX-License-Identifier: Unlicense */
1253 
1254 /* b = a/2 */
mp_div_2(const mp_int * a,mp_int * b)1255 mp_err mp_div_2(const mp_int *a, mp_int *b)
1256 {
1257    int     x, oldused;
1258    mp_digit r, rr, *tmpa, *tmpb;
1259    mp_err err;
1260 
1261    /* copy */
1262    if (b->alloc < a->used) {
1263       if ((err = mp_grow(b, a->used)) != MP_OKAY) {
1264          return err;
1265       }
1266    }
1267 
1268    oldused = b->used;
1269    b->used = a->used;
1270 
1271    /* source alias */
1272    tmpa = a->dp + b->used - 1;
1273 
1274    /* dest alias */
1275    tmpb = b->dp + b->used - 1;
1276 
1277    /* carry */
1278    r = 0;
1279    for (x = b->used - 1; x >= 0; x--) {
1280       /* get the carry for the next iteration */
1281       rr = *tmpa & 1u;
1282 
1283       /* shift the current digit, add in carry and store */
1284       *tmpb-- = (*tmpa-- >> 1) | (r << (MP_DIGIT_BIT - 1));
1285 
1286       /* forward carry to next iteration */
1287       r = rr;
1288    }
1289 
1290    /* zero excess digits */
1291    MP_ZERO_DIGITS(b->dp + b->used, oldused - b->used);
1292 
1293    b->sign = a->sign;
1294    mp_clamp(b);
1295    return MP_OKAY;
1296 }
1297 #endif
1298 
1299 /* End: bn_mp_div_2.c */
1300 
1301 /* Start: bn_mp_div_2d.c */
1302 #include "tommath_private.h"
1303 #ifdef BN_MP_DIV_2D_C
1304 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1305 /* SPDX-License-Identifier: Unlicense */
1306 
1307 /* shift right by a certain bit count (store quotient in c, optional remainder in d) */
mp_div_2d(const mp_int * a,int b,mp_int * c,mp_int * d)1308 mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d)
1309 {
1310    mp_digit D, r, rr;
1311    int     x;
1312    mp_err err;
1313 
1314    /* if the shift count is <= 0 then we do no work */
1315    if (b <= 0) {
1316       err = mp_copy(a, c);
1317       if (d != NULL) {
1318          mp_zero(d);
1319       }
1320       return err;
1321    }
1322 
1323    /* copy */
1324    if ((err = mp_copy(a, c)) != MP_OKAY) {
1325       return err;
1326    }
1327    /* 'a' should not be used after here - it might be the same as d */
1328 
1329    /* get the remainder */
1330    if (d != NULL) {
1331       if ((err = mp_mod_2d(a, b, d)) != MP_OKAY) {
1332          return err;
1333       }
1334    }
1335 
1336    /* shift by as many digits in the bit count */
1337    if (b >= MP_DIGIT_BIT) {
1338       mp_rshd(c, b / MP_DIGIT_BIT);
1339    }
1340 
1341    /* shift any bit count < MP_DIGIT_BIT */
1342    D = (mp_digit)(b % MP_DIGIT_BIT);
1343    if (D != 0u) {
1344       mp_digit *tmpc, mask, shift;
1345 
1346       /* mask */
1347       mask = ((mp_digit)1 << D) - 1uL;
1348 
1349       /* shift for lsb */
1350       shift = (mp_digit)MP_DIGIT_BIT - D;
1351 
1352       /* alias */
1353       tmpc = c->dp + (c->used - 1);
1354 
1355       /* carry */
1356       r = 0;
1357       for (x = c->used - 1; x >= 0; x--) {
1358          /* get the lower  bits of this word in a temp */
1359          rr = *tmpc & mask;
1360 
1361          /* shift the current word and mix in the carry bits from the previous word */
1362          *tmpc = (*tmpc >> D) | (r << shift);
1363          --tmpc;
1364 
1365          /* set the carry to the carry bits of the current word found above */
1366          r = rr;
1367       }
1368    }
1369    mp_clamp(c);
1370    return MP_OKAY;
1371 }
1372 #endif
1373 
1374 /* End: bn_mp_div_2d.c */
1375 
1376 /* Start: bn_mp_div_3.c */
1377 #include "tommath_private.h"
1378 #ifdef BN_MP_DIV_3_C
1379 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1380 /* SPDX-License-Identifier: Unlicense */
1381 
1382 /* divide by three (based on routine from MPI and the GMP manual) */
mp_div_3(const mp_int * a,mp_int * c,mp_digit * d)1383 mp_err mp_div_3(const mp_int *a, mp_int *c, mp_digit *d)
1384 {
1385    mp_int   q;
1386    mp_word  w, t;
1387    mp_digit b;
1388    mp_err   err;
1389    int      ix;
1390 
1391    /* b = 2**MP_DIGIT_BIT / 3 */
1392    b = ((mp_word)1 << (mp_word)MP_DIGIT_BIT) / (mp_word)3;
1393 
1394    if ((err = mp_init_size(&q, a->used)) != MP_OKAY) {
1395       return err;
1396    }
1397 
1398    q.used = a->used;
1399    q.sign = a->sign;
1400    w = 0;
1401    for (ix = a->used - 1; ix >= 0; ix--) {
1402       w = (w << (mp_word)MP_DIGIT_BIT) | (mp_word)a->dp[ix];
1403 
1404       if (w >= 3u) {
1405          /* multiply w by [1/3] */
1406          t = (w * (mp_word)b) >> (mp_word)MP_DIGIT_BIT;
1407 
1408          /* now subtract 3 * [w/3] from w, to get the remainder */
1409          w -= t+t+t;
1410 
1411          /* fixup the remainder as required since
1412           * the optimization is not exact.
1413           */
1414          while (w >= 3u) {
1415             t += 1u;
1416             w -= 3u;
1417          }
1418       } else {
1419          t = 0;
1420       }
1421       q.dp[ix] = (mp_digit)t;
1422    }
1423 
1424    /* [optional] store the remainder */
1425    if (d != NULL) {
1426       *d = (mp_digit)w;
1427    }
1428 
1429    /* [optional] store the quotient */
1430    if (c != NULL) {
1431       mp_clamp(&q);
1432       mp_exch(&q, c);
1433    }
1434    mp_clear(&q);
1435 
1436    return err;
1437 }
1438 
1439 #endif
1440 
1441 /* End: bn_mp_div_3.c */
1442 
1443 /* Start: bn_mp_div_d.c */
1444 #include "tommath_private.h"
1445 #ifdef BN_MP_DIV_D_C
1446 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1447 /* SPDX-License-Identifier: Unlicense */
1448 
1449 /* single digit division (based on routine from MPI) */
mp_div_d(const mp_int * a,mp_digit b,mp_int * c,mp_digit * d)1450 mp_err mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d)
1451 {
1452    mp_int  q;
1453    mp_word w;
1454    mp_digit t;
1455    mp_err err;
1456    int ix;
1457 
1458    /* cannot divide by zero */
1459    if (b == 0u) {
1460       return MP_VAL;
1461    }
1462 
1463    /* quick outs */
1464    if ((b == 1u) || MP_IS_ZERO(a)) {
1465       if (d != NULL) {
1466          *d = 0;
1467       }
1468       if (c != NULL) {
1469          return mp_copy(a, c);
1470       }
1471       return MP_OKAY;
1472    }
1473 
1474    /* power of two ? */
1475    if ((b & (b - 1u)) == 0u) {
1476       ix = 1;
1477       while ((ix < MP_DIGIT_BIT) && (b != (((mp_digit)1)<<ix))) {
1478          ix++;
1479       }
1480       if (d != NULL) {
1481          *d = a->dp[0] & (((mp_digit)1<<(mp_digit)ix) - 1uL);
1482       }
1483       if (c != NULL) {
1484          return mp_div_2d(a, ix, c, NULL);
1485       }
1486       return MP_OKAY;
1487    }
1488 
1489    /* three? */
1490    if (MP_HAS(MP_DIV_3) && (b == 3u)) {
1491       return mp_div_3(a, c, d);
1492    }
1493 
1494    /* no easy answer [c'est la vie].  Just division */
1495    if ((err = mp_init_size(&q, a->used)) != MP_OKAY) {
1496       return err;
1497    }
1498 
1499    q.used = a->used;
1500    q.sign = a->sign;
1501    w = 0;
1502    for (ix = a->used - 1; ix >= 0; ix--) {
1503       w = (w << (mp_word)MP_DIGIT_BIT) | (mp_word)a->dp[ix];
1504 
1505       if (w >= b) {
1506          t = (mp_digit)(w / b);
1507          w -= (mp_word)t * (mp_word)b;
1508       } else {
1509          t = 0;
1510       }
1511       q.dp[ix] = t;
1512    }
1513 
1514    if (d != NULL) {
1515       *d = (mp_digit)w;
1516    }
1517 
1518    if (c != NULL) {
1519       mp_clamp(&q);
1520       mp_exch(&q, c);
1521    }
1522    mp_clear(&q);
1523 
1524    return err;
1525 }
1526 
1527 #endif
1528 
1529 /* End: bn_mp_div_d.c */
1530 
1531 /* Start: bn_mp_dr_is_modulus.c */
1532 #include "tommath_private.h"
1533 #ifdef BN_MP_DR_IS_MODULUS_C
1534 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1535 /* SPDX-License-Identifier: Unlicense */
1536 
1537 /* determines if a number is a valid DR modulus */
mp_dr_is_modulus(const mp_int * a)1538 mp_bool mp_dr_is_modulus(const mp_int *a)
1539 {
1540    int ix;
1541 
1542    /* must be at least two digits */
1543    if (a->used < 2) {
1544       return MP_NO;
1545    }
1546 
1547    /* must be of the form b**k - a [a <= b] so all
1548     * but the first digit must be equal to -1 (mod b).
1549     */
1550    for (ix = 1; ix < a->used; ix++) {
1551       if (a->dp[ix] != MP_MASK) {
1552          return MP_NO;
1553       }
1554    }
1555    return MP_YES;
1556 }
1557 
1558 #endif
1559 
1560 /* End: bn_mp_dr_is_modulus.c */
1561 
1562 /* Start: bn_mp_dr_reduce.c */
1563 #include "tommath_private.h"
1564 #ifdef BN_MP_DR_REDUCE_C
1565 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1566 /* SPDX-License-Identifier: Unlicense */
1567 
1568 /* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
1569  *
1570  * Based on algorithm from the paper
1571  *
1572  * "Generating Efficient Primes for Discrete Log Cryptosystems"
1573  *                 Chae Hoon Lim, Pil Joong Lee,
1574  *          POSTECH Information Research Laboratories
1575  *
1576  * The modulus must be of a special format [see manual]
1577  *
1578  * Has been modified to use algorithm 7.10 from the LTM book instead
1579  *
1580  * Input x must be in the range 0 <= x <= (n-1)**2
1581  */
mp_dr_reduce(mp_int * x,const mp_int * n,mp_digit k)1582 mp_err mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k)
1583 {
1584    mp_err      err;
1585    int i, m;
1586    mp_word  r;
1587    mp_digit mu, *tmpx1, *tmpx2;
1588 
1589    /* m = digits in modulus */
1590    m = n->used;
1591 
1592    /* ensure that "x" has at least 2m digits */
1593    if (x->alloc < (m + m)) {
1594       if ((err = mp_grow(x, m + m)) != MP_OKAY) {
1595          return err;
1596       }
1597    }
1598 
1599    /* top of loop, this is where the code resumes if
1600     * another reduction pass is required.
1601     */
1602 top:
1603    /* aliases for digits */
1604    /* alias for lower half of x */
1605    tmpx1 = x->dp;
1606 
1607    /* alias for upper half of x, or x/B**m */
1608    tmpx2 = x->dp + m;
1609 
1610    /* set carry to zero */
1611    mu = 0;
1612 
1613    /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
1614    for (i = 0; i < m; i++) {
1615       r         = ((mp_word)*tmpx2++ * (mp_word)k) + *tmpx1 + mu;
1616       *tmpx1++  = (mp_digit)(r & MP_MASK);
1617       mu        = (mp_digit)(r >> ((mp_word)MP_DIGIT_BIT));
1618    }
1619 
1620    /* set final carry */
1621    *tmpx1++ = mu;
1622 
1623    /* zero words above m */
1624    MP_ZERO_DIGITS(tmpx1, (x->used - m) - 1);
1625 
1626    /* clamp, sub and return */
1627    mp_clamp(x);
1628 
1629    /* if x >= n then subtract and reduce again
1630     * Each successive "recursion" makes the input smaller and smaller.
1631     */
1632    if (mp_cmp_mag(x, n) != MP_LT) {
1633       if ((err = s_mp_sub(x, n, x)) != MP_OKAY) {
1634          return err;
1635       }
1636       goto top;
1637    }
1638    return MP_OKAY;
1639 }
1640 #endif
1641 
1642 /* End: bn_mp_dr_reduce.c */
1643 
1644 /* Start: bn_mp_dr_setup.c */
1645 #include "tommath_private.h"
1646 #ifdef BN_MP_DR_SETUP_C
1647 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1648 /* SPDX-License-Identifier: Unlicense */
1649 
1650 /* determines the setup value */
mp_dr_setup(const mp_int * a,mp_digit * d)1651 void mp_dr_setup(const mp_int *a, mp_digit *d)
1652 {
1653    /* the casts are required if MP_DIGIT_BIT is one less than
1654     * the number of bits in a mp_digit [e.g. MP_DIGIT_BIT==31]
1655     */
1656    *d = (mp_digit)(((mp_word)1 << (mp_word)MP_DIGIT_BIT) - (mp_word)a->dp[0]);
1657 }
1658 
1659 #endif
1660 
1661 /* End: bn_mp_dr_setup.c */
1662 
1663 /* Start: bn_mp_error_to_string.c */
1664 #include "tommath_private.h"
1665 #ifdef BN_MP_ERROR_TO_STRING_C
1666 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1667 /* SPDX-License-Identifier: Unlicense */
1668 
1669 /* return a char * string for a given code */
mp_error_to_string(mp_err code)1670 const char *mp_error_to_string(mp_err code)
1671 {
1672    switch (code) {
1673    case MP_OKAY:
1674       return "Successful";
1675    case MP_ERR:
1676       return "Unknown error";
1677    case MP_MEM:
1678       return "Out of heap";
1679    case MP_VAL:
1680       return "Value out of range";
1681    case MP_ITER:
1682       return "Max. iterations reached";
1683    case MP_BUF:
1684       return "Buffer overflow";
1685    default:
1686       return "Invalid error code";
1687    }
1688 }
1689 
1690 #endif
1691 
1692 /* End: bn_mp_error_to_string.c */
1693 
1694 /* Start: bn_mp_exch.c */
1695 #include "tommath_private.h"
1696 #ifdef BN_MP_EXCH_C
1697 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1698 /* SPDX-License-Identifier: Unlicense */
1699 
1700 /* swap the elements of two integers, for cases where you can't simply swap the
1701  * mp_int pointers around
1702  */
mp_exch(mp_int * a,mp_int * b)1703 void mp_exch(mp_int *a, mp_int *b)
1704 {
1705    mp_int  t;
1706 
1707    t  = *a;
1708    *a = *b;
1709    *b = t;
1710 }
1711 #endif
1712 
1713 /* End: bn_mp_exch.c */
1714 
1715 /* Start: bn_mp_expt_u32.c */
1716 #include "tommath_private.h"
1717 #ifdef BN_MP_EXPT_U32_C
1718 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1719 /* SPDX-License-Identifier: Unlicense */
1720 
1721 /* calculate c = a**b  using a square-multiply algorithm */
mp_expt_u32(const mp_int * a,uint32_t b,mp_int * c)1722 mp_err mp_expt_u32(const mp_int *a, uint32_t b, mp_int *c)
1723 {
1724    mp_err err;
1725 
1726    mp_int  g;
1727 
1728    if ((err = mp_init_copy(&g, a)) != MP_OKAY) {
1729       return err;
1730    }
1731 
1732    /* set initial result */
1733    mp_set(c, 1uL);
1734 
1735    while (b > 0u) {
1736       /* if the bit is set multiply */
1737       if ((b & 1u) != 0u) {
1738          if ((err = mp_mul(c, &g, c)) != MP_OKAY) {
1739             goto LBL_ERR;
1740          }
1741       }
1742 
1743       /* square */
1744       if (b > 1u) {
1745          if ((err = mp_sqr(&g, &g)) != MP_OKAY) {
1746             goto LBL_ERR;
1747          }
1748       }
1749 
1750       /* shift to next bit */
1751       b >>= 1;
1752    }
1753 
1754    err = MP_OKAY;
1755 
1756 LBL_ERR:
1757    mp_clear(&g);
1758    return err;
1759 }
1760 
1761 #endif
1762 
1763 /* End: bn_mp_expt_u32.c */
1764 
1765 /* Start: bn_mp_exptmod.c */
1766 #include "tommath_private.h"
1767 #ifdef BN_MP_EXPTMOD_C
1768 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1769 /* SPDX-License-Identifier: Unlicense */
1770 
1771 /* this is a shell function that calls either the normal or Montgomery
1772  * exptmod functions.  Originally the call to the montgomery code was
1773  * embedded in the normal function but that wasted alot of stack space
1774  * for nothing (since 99% of the time the Montgomery code would be called)
1775  */
mp_exptmod(const mp_int * G,const mp_int * X,const mp_int * P,mp_int * Y)1776 mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y)
1777 {
1778    int dr;
1779 
1780    /* modulus P must be positive */
1781    if (P->sign == MP_NEG) {
1782       return MP_VAL;
1783    }
1784 
1785    /* if exponent X is negative we have to recurse */
1786    if (X->sign == MP_NEG) {
1787       mp_int tmpG, tmpX;
1788       mp_err err;
1789 
1790       if (!MP_HAS(MP_INVMOD)) {
1791          return MP_VAL;
1792       }
1793 
1794       if ((err = mp_init_multi(&tmpG, &tmpX, NULL)) != MP_OKAY) {
1795          return err;
1796       }
1797 
1798       /* first compute 1/G mod P */
1799       if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
1800          goto LBL_ERR;
1801       }
1802 
1803       /* now get |X| */
1804       if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
1805          goto LBL_ERR;
1806       }
1807 
1808       /* and now compute (1/G)**|X| instead of G**X [X < 0] */
1809       err = mp_exptmod(&tmpG, &tmpX, P, Y);
1810 LBL_ERR:
1811       mp_clear_multi(&tmpG, &tmpX, NULL);
1812       return err;
1813    }
1814 
1815    /* modified diminished radix reduction */
1816    if (MP_HAS(MP_REDUCE_IS_2K_L) && MP_HAS(MP_REDUCE_2K_L) && MP_HAS(S_MP_EXPTMOD) &&
1817        (mp_reduce_is_2k_l(P) == MP_YES)) {
1818       return s_mp_exptmod(G, X, P, Y, 1);
1819    }
1820 
1821    /* is it a DR modulus? default to no */
1822    dr = (MP_HAS(MP_DR_IS_MODULUS) && (mp_dr_is_modulus(P) == MP_YES)) ? 1 : 0;
1823 
1824    /* if not, is it a unrestricted DR modulus? */
1825    if (MP_HAS(MP_REDUCE_IS_2K) && (dr == 0)) {
1826       dr = (mp_reduce_is_2k(P) == MP_YES) ? 2 : 0;
1827    }
1828 
1829    /* if the modulus is odd or dr != 0 use the montgomery method */
1830    if (MP_HAS(S_MP_EXPTMOD_FAST) && (MP_IS_ODD(P) || (dr != 0))) {
1831       return s_mp_exptmod_fast(G, X, P, Y, dr);
1832    } else if (MP_HAS(S_MP_EXPTMOD)) {
1833       /* otherwise use the generic Barrett reduction technique */
1834       return s_mp_exptmod(G, X, P, Y, 0);
1835    } else {
1836       /* no exptmod for evens */
1837       return MP_VAL;
1838    }
1839 }
1840 
1841 #endif
1842 
1843 /* End: bn_mp_exptmod.c */
1844 
1845 /* Start: bn_mp_exteuclid.c */
1846 #include "tommath_private.h"
1847 #ifdef BN_MP_EXTEUCLID_C
1848 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1849 /* SPDX-License-Identifier: Unlicense */
1850 
1851 /* Extended euclidean algorithm of (a, b) produces
1852    a*u1 + b*u2 = u3
1853  */
mp_exteuclid(const mp_int * a,const mp_int * b,mp_int * U1,mp_int * U2,mp_int * U3)1854 mp_err mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
1855 {
1856    mp_int u1, u2, u3, v1, v2, v3, t1, t2, t3, q, tmp;
1857    mp_err err;
1858 
1859    if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
1860       return err;
1861    }
1862 
1863    /* initialize, (u1,u2,u3) = (1,0,a) */
1864    mp_set(&u1, 1uL);
1865    if ((err = mp_copy(a, &u3)) != MP_OKAY)                        goto LBL_ERR;
1866 
1867    /* initialize, (v1,v2,v3) = (0,1,b) */
1868    mp_set(&v2, 1uL);
1869    if ((err = mp_copy(b, &v3)) != MP_OKAY)                        goto LBL_ERR;
1870 
1871    /* loop while v3 != 0 */
1872    while (!MP_IS_ZERO(&v3)) {
1873       /* q = u3/v3 */
1874       if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY)          goto LBL_ERR;
1875 
1876       /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
1877       if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY)               goto LBL_ERR;
1878       if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY)              goto LBL_ERR;
1879       if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY)               goto LBL_ERR;
1880       if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY)              goto LBL_ERR;
1881       if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY)               goto LBL_ERR;
1882       if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY)              goto LBL_ERR;
1883 
1884       /* (u1,u2,u3) = (v1,v2,v3) */
1885       if ((err = mp_copy(&v1, &u1)) != MP_OKAY)                   goto LBL_ERR;
1886       if ((err = mp_copy(&v2, &u2)) != MP_OKAY)                   goto LBL_ERR;
1887       if ((err = mp_copy(&v3, &u3)) != MP_OKAY)                   goto LBL_ERR;
1888 
1889       /* (v1,v2,v3) = (t1,t2,t3) */
1890       if ((err = mp_copy(&t1, &v1)) != MP_OKAY)                   goto LBL_ERR;
1891       if ((err = mp_copy(&t2, &v2)) != MP_OKAY)                   goto LBL_ERR;
1892       if ((err = mp_copy(&t3, &v3)) != MP_OKAY)                   goto LBL_ERR;
1893    }
1894 
1895    /* make sure U3 >= 0 */
1896    if (u3.sign == MP_NEG) {
1897       if ((err = mp_neg(&u1, &u1)) != MP_OKAY)                    goto LBL_ERR;
1898       if ((err = mp_neg(&u2, &u2)) != MP_OKAY)                    goto LBL_ERR;
1899       if ((err = mp_neg(&u3, &u3)) != MP_OKAY)                    goto LBL_ERR;
1900    }
1901 
1902    /* copy result out */
1903    if (U1 != NULL) {
1904       mp_exch(U1, &u1);
1905    }
1906    if (U2 != NULL) {
1907       mp_exch(U2, &u2);
1908    }
1909    if (U3 != NULL) {
1910       mp_exch(U3, &u3);
1911    }
1912 
1913    err = MP_OKAY;
1914 LBL_ERR:
1915    mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
1916    return err;
1917 }
1918 #endif
1919 
1920 /* End: bn_mp_exteuclid.c */
1921 
1922 /* Start: bn_mp_fread.c */
1923 #include "tommath_private.h"
1924 #ifdef BN_MP_FREAD_C
1925 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1926 /* SPDX-License-Identifier: Unlicense */
1927 
1928 #ifndef MP_NO_FILE
1929 /* read a bigint from a file stream in ASCII */
mp_fread(mp_int * a,int radix,FILE * stream)1930 mp_err mp_fread(mp_int *a, int radix, FILE *stream)
1931 {
1932    mp_err err;
1933    mp_sign neg;
1934 
1935    /* if first digit is - then set negative */
1936    int ch = fgetc(stream);
1937    if (ch == (int)'-') {
1938       neg = MP_NEG;
1939       ch = fgetc(stream);
1940    } else {
1941       neg = MP_ZPOS;
1942    }
1943 
1944    /* no digits, return error */
1945    if (ch == EOF) {
1946       return MP_ERR;
1947    }
1948 
1949    /* clear a */
1950    mp_zero(a);
1951 
1952    do {
1953       int y;
1954       unsigned pos = (unsigned)(ch - (int)'(');
1955       if (mp_s_rmap_reverse_sz < pos) {
1956          break;
1957       }
1958 
1959       y = (int)mp_s_rmap_reverse[pos];
1960 
1961       if ((y == 0xff) || (y >= radix)) {
1962          break;
1963       }
1964 
1965       /* shift up and add */
1966       if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) {
1967          return err;
1968       }
1969       if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) {
1970          return err;
1971       }
1972    } while ((ch = fgetc(stream)) != EOF);
1973 
1974    if (a->used != 0) {
1975       a->sign = neg;
1976    }
1977 
1978    return MP_OKAY;
1979 }
1980 #endif
1981 
1982 #endif
1983 
1984 /* End: bn_mp_fread.c */
1985 
1986 /* Start: bn_mp_from_sbin.c */
1987 #include "tommath_private.h"
1988 #ifdef BN_MP_FROM_SBIN_C
1989 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1990 /* SPDX-License-Identifier: Unlicense */
1991 
1992 /* read signed bin, big endian, first byte is 0==positive or 1==negative */
mp_from_sbin(mp_int * a,const unsigned char * buf,size_t size)1993 mp_err mp_from_sbin(mp_int *a, const unsigned char *buf, size_t size)
1994 {
1995    mp_err err;
1996 
1997    /* read magnitude */
1998    if ((err = mp_from_ubin(a, buf + 1, size - 1u)) != MP_OKAY) {
1999       return err;
2000    }
2001 
2002    /* first byte is 0 for positive, non-zero for negative */
2003    if (buf[0] == (unsigned char)0) {
2004       a->sign = MP_ZPOS;
2005    } else {
2006       a->sign = MP_NEG;
2007    }
2008 
2009    return MP_OKAY;
2010 }
2011 #endif
2012 
2013 /* End: bn_mp_from_sbin.c */
2014 
2015 /* Start: bn_mp_from_ubin.c */
2016 #include "tommath_private.h"
2017 #ifdef BN_MP_FROM_UBIN_C
2018 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2019 /* SPDX-License-Identifier: Unlicense */
2020 
2021 /* reads a unsigned char array, assumes the msb is stored first [big endian] */
mp_from_ubin(mp_int * a,const unsigned char * buf,size_t size)2022 mp_err mp_from_ubin(mp_int *a, const unsigned char *buf, size_t size)
2023 {
2024    mp_err err;
2025 
2026    /* make sure there are at least two digits */
2027    if (a->alloc < 2) {
2028       if ((err = mp_grow(a, 2)) != MP_OKAY) {
2029          return err;
2030       }
2031    }
2032 
2033    /* zero the int */
2034    mp_zero(a);
2035 
2036    /* read the bytes in */
2037    while (size-- > 0u) {
2038       if ((err = mp_mul_2d(a, 8, a)) != MP_OKAY) {
2039          return err;
2040       }
2041 
2042 #ifndef MP_8BIT
2043       a->dp[0] |= *buf++;
2044       a->used += 1;
2045 #else
2046       a->dp[0] = (*buf & MP_MASK);
2047       a->dp[1] |= ((*buf++ >> 7) & 1u);
2048       a->used += 2;
2049 #endif
2050    }
2051    mp_clamp(a);
2052    return MP_OKAY;
2053 }
2054 #endif
2055 
2056 /* End: bn_mp_from_ubin.c */
2057 
2058 /* Start: bn_mp_fwrite.c */
2059 #include "tommath_private.h"
2060 #ifdef BN_MP_FWRITE_C
2061 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2062 /* SPDX-License-Identifier: Unlicense */
2063 
2064 #ifndef MP_NO_FILE
mp_fwrite(const mp_int * a,int radix,FILE * stream)2065 mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream)
2066 {
2067    char *buf;
2068    mp_err err;
2069    int len;
2070    size_t written;
2071 
2072    /* TODO: this function is not in this PR */
2073    if (MP_HAS(MP_RADIX_SIZE_OVERESTIMATE)) {
2074       /* if ((err = mp_radix_size_overestimate(&t, base, &len)) != MP_OKAY)      goto LBL_ERR; */
2075    } else {
2076       if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
2077          return err;
2078       }
2079    }
2080 
2081    buf = (char *) MP_MALLOC((size_t)len);
2082    if (buf == NULL) {
2083       return MP_MEM;
2084    }
2085 
2086    if ((err = mp_to_radix(a, buf, (size_t)len, &written, radix)) != MP_OKAY) {
2087       goto LBL_ERR;
2088    }
2089 
2090    if (fwrite(buf, written, 1uL, stream) != 1uL) {
2091       err = MP_ERR;
2092       goto LBL_ERR;
2093    }
2094    err = MP_OKAY;
2095 
2096 
2097 LBL_ERR:
2098    MP_FREE_BUFFER(buf, (size_t)len);
2099    return err;
2100 }
2101 #endif
2102 
2103 #endif
2104 
2105 /* End: bn_mp_fwrite.c */
2106 
2107 /* Start: bn_mp_gcd.c */
2108 #include "tommath_private.h"
2109 #ifdef BN_MP_GCD_C
2110 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2111 /* SPDX-License-Identifier: Unlicense */
2112 
2113 /* Greatest Common Divisor using the binary method */
mp_gcd(const mp_int * a,const mp_int * b,mp_int * c)2114 mp_err mp_gcd(const mp_int *a, const mp_int *b, mp_int *c)
2115 {
2116    mp_int  u, v;
2117    int     k, u_lsb, v_lsb;
2118    mp_err err;
2119 
2120    /* either zero than gcd is the largest */
2121    if (MP_IS_ZERO(a)) {
2122       return mp_abs(b, c);
2123    }
2124    if (MP_IS_ZERO(b)) {
2125       return mp_abs(a, c);
2126    }
2127 
2128    /* get copies of a and b we can modify */
2129    if ((err = mp_init_copy(&u, a)) != MP_OKAY) {
2130       return err;
2131    }
2132 
2133    if ((err = mp_init_copy(&v, b)) != MP_OKAY) {
2134       goto LBL_U;
2135    }
2136 
2137    /* must be positive for the remainder of the algorithm */
2138    u.sign = v.sign = MP_ZPOS;
2139 
2140    /* B1.  Find the common power of two for u and v */
2141    u_lsb = mp_cnt_lsb(&u);
2142    v_lsb = mp_cnt_lsb(&v);
2143    k     = MP_MIN(u_lsb, v_lsb);
2144 
2145    if (k > 0) {
2146       /* divide the power of two out */
2147       if ((err = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
2148          goto LBL_V;
2149       }
2150 
2151       if ((err = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
2152          goto LBL_V;
2153       }
2154    }
2155 
2156    /* divide any remaining factors of two out */
2157    if (u_lsb != k) {
2158       if ((err = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
2159          goto LBL_V;
2160       }
2161    }
2162 
2163    if (v_lsb != k) {
2164       if ((err = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
2165          goto LBL_V;
2166       }
2167    }
2168 
2169    while (!MP_IS_ZERO(&v)) {
2170       /* make sure v is the largest */
2171       if (mp_cmp_mag(&u, &v) == MP_GT) {
2172          /* swap u and v to make sure v is >= u */
2173          mp_exch(&u, &v);
2174       }
2175 
2176       /* subtract smallest from largest */
2177       if ((err = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
2178          goto LBL_V;
2179       }
2180 
2181       /* Divide out all factors of two */
2182       if ((err = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
2183          goto LBL_V;
2184       }
2185    }
2186 
2187    /* multiply by 2**k which we divided out at the beginning */
2188    if ((err = mp_mul_2d(&u, k, c)) != MP_OKAY) {
2189       goto LBL_V;
2190    }
2191    c->sign = MP_ZPOS;
2192    err = MP_OKAY;
2193 LBL_V:
2194    mp_clear(&u);
2195 LBL_U:
2196    mp_clear(&v);
2197    return err;
2198 }
2199 #endif
2200 
2201 /* End: bn_mp_gcd.c */
2202 
2203 /* Start: bn_mp_get_double.c */
2204 #include "tommath_private.h"
2205 #ifdef BN_MP_GET_DOUBLE_C
2206 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2207 /* SPDX-License-Identifier: Unlicense */
2208 
mp_get_double(const mp_int * a)2209 double mp_get_double(const mp_int *a)
2210 {
2211    int i;
2212    double d = 0.0, fac = 1.0;
2213    for (i = 0; i < MP_DIGIT_BIT; ++i) {
2214       fac *= 2.0;
2215    }
2216    for (i = a->used; i --> 0;) {
2217       d = (d * fac) + (double)a->dp[i];
2218    }
2219    return (a->sign == MP_NEG) ? -d : d;
2220 }
2221 #endif
2222 
2223 /* End: bn_mp_get_double.c */
2224 
2225 /* Start: bn_mp_get_i32.c */
2226 #include "tommath_private.h"
2227 #ifdef BN_MP_GET_I32_C
2228 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2229 /* SPDX-License-Identifier: Unlicense */
2230 
MP_GET_SIGNED(mp_get_i32,mp_get_mag_u32,int32_t,uint32_t)2231 MP_GET_SIGNED(mp_get_i32, mp_get_mag_u32, int32_t, uint32_t)
2232 #endif
2233 
2234 /* End: bn_mp_get_i32.c */
2235 
2236 /* Start: bn_mp_get_i64.c */
2237 #include "tommath_private.h"
2238 #ifdef BN_MP_GET_I64_C
2239 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2240 /* SPDX-License-Identifier: Unlicense */
2241 
2242 MP_GET_SIGNED(mp_get_i64, mp_get_mag_u64, int64_t, uint64_t)
2243 #endif
2244 
2245 /* End: bn_mp_get_i64.c */
2246 
2247 /* Start: bn_mp_get_l.c */
2248 #include "tommath_private.h"
2249 #ifdef BN_MP_GET_L_C
2250 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2251 /* SPDX-License-Identifier: Unlicense */
2252 
2253 MP_GET_SIGNED(mp_get_l, mp_get_mag_ul, long, unsigned long)
2254 #endif
2255 
2256 /* End: bn_mp_get_l.c */
2257 
2258 /* Start: bn_mp_get_ll.c */
2259 #include "tommath_private.h"
2260 #ifdef BN_MP_GET_LL_C
2261 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2262 /* SPDX-License-Identifier: Unlicense */
2263 
2264 MP_GET_SIGNED(mp_get_ll, mp_get_mag_ull, long long, unsigned long long)
2265 #endif
2266 
2267 /* End: bn_mp_get_ll.c */
2268 
2269 /* Start: bn_mp_get_mag_u32.c */
2270 #include "tommath_private.h"
2271 #ifdef BN_MP_GET_MAG_U32_C
2272 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2273 /* SPDX-License-Identifier: Unlicense */
2274 
2275 MP_GET_MAG(mp_get_mag_u32, uint32_t)
2276 #endif
2277 
2278 /* End: bn_mp_get_mag_u32.c */
2279 
2280 /* Start: bn_mp_get_mag_u64.c */
2281 #include "tommath_private.h"
2282 #ifdef BN_MP_GET_MAG_U64_C
2283 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2284 /* SPDX-License-Identifier: Unlicense */
2285 
2286 MP_GET_MAG(mp_get_mag_u64, uint64_t)
2287 #endif
2288 
2289 /* End: bn_mp_get_mag_u64.c */
2290 
2291 /* Start: bn_mp_get_mag_ul.c */
2292 #include "tommath_private.h"
2293 #ifdef BN_MP_GET_MAG_UL_C
2294 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2295 /* SPDX-License-Identifier: Unlicense */
2296 
2297 MP_GET_MAG(mp_get_mag_ul, unsigned long)
2298 #endif
2299 
2300 /* End: bn_mp_get_mag_ul.c */
2301 
2302 /* Start: bn_mp_get_mag_ull.c */
2303 #include "tommath_private.h"
2304 #ifdef BN_MP_GET_MAG_ULL_C
2305 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2306 /* SPDX-License-Identifier: Unlicense */
2307 
2308 MP_GET_MAG(mp_get_mag_ull, unsigned long long)
2309 #endif
2310 
2311 /* End: bn_mp_get_mag_ull.c */
2312 
2313 /* Start: bn_mp_grow.c */
2314 #include "tommath_private.h"
2315 #ifdef BN_MP_GROW_C
2316 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2317 /* SPDX-License-Identifier: Unlicense */
2318 
2319 /* grow as required */
2320 mp_err mp_grow(mp_int *a, int size)
2321 {
2322    int     i;
2323    mp_digit *tmp;
2324 
2325    /* if the alloc size is smaller alloc more ram */
2326    if (a->alloc < size) {
2327       /* reallocate the array a->dp
2328        *
2329        * We store the return in a temporary variable
2330        * in case the operation failed we don't want
2331        * to overwrite the dp member of a.
2332        */
2333       tmp = (mp_digit *) MP_REALLOC(a->dp,
2334                                     (size_t)a->alloc * sizeof(mp_digit),
2335                                     (size_t)size * sizeof(mp_digit));
2336       if (tmp == NULL) {
2337          /* reallocation failed but "a" is still valid [can be freed] */
2338          return MP_MEM;
2339       }
2340 
2341       /* reallocation succeeded so set a->dp */
2342       a->dp = tmp;
2343 
2344       /* zero excess digits */
2345       i        = a->alloc;
2346       a->alloc = size;
2347       MP_ZERO_DIGITS(a->dp + i, a->alloc - i);
2348    }
2349    return MP_OKAY;
2350 }
2351 #endif
2352 
2353 /* End: bn_mp_grow.c */
2354 
2355 /* Start: bn_mp_incr.c */
2356 #include "tommath_private.h"
2357 #ifdef BN_MP_INCR_C
2358 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2359 /* SPDX-License-Identifier: Unlicense */
2360 
2361 /* Increment "a" by one like "a++". Changes input! */
mp_incr(mp_int * a)2362 mp_err mp_incr(mp_int *a)
2363 {
2364    if (MP_IS_ZERO(a)) {
2365       mp_set(a,1uL);
2366       return MP_OKAY;
2367    } else if (a->sign == MP_NEG) {
2368       mp_err err;
2369       a->sign = MP_ZPOS;
2370       if ((err = mp_decr(a)) != MP_OKAY) {
2371          return err;
2372       }
2373       /* There is no -0 in LTM */
2374       if (!MP_IS_ZERO(a)) {
2375          a->sign = MP_NEG;
2376       }
2377       return MP_OKAY;
2378    } else if (a->dp[0] < MP_DIGIT_MAX) {
2379       a->dp[0]++;
2380       return MP_OKAY;
2381    } else {
2382       return mp_add_d(a, 1uL,a);
2383    }
2384 }
2385 #endif
2386 
2387 /* End: bn_mp_incr.c */
2388 
2389 /* Start: bn_mp_init.c */
2390 #include "tommath_private.h"
2391 #ifdef BN_MP_INIT_C
2392 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2393 /* SPDX-License-Identifier: Unlicense */
2394 
2395 /* init a new mp_int */
mp_init(mp_int * a)2396 mp_err mp_init(mp_int *a)
2397 {
2398    /* allocate memory required and clear it */
2399    a->dp = (mp_digit *) MP_CALLOC((size_t)MP_PREC, sizeof(mp_digit));
2400    if (a->dp == NULL) {
2401       return MP_MEM;
2402    }
2403 
2404    /* set the used to zero, allocated digits to the default precision
2405     * and sign to positive */
2406    a->used  = 0;
2407    a->alloc = MP_PREC;
2408    a->sign  = MP_ZPOS;
2409 
2410    return MP_OKAY;
2411 }
2412 #endif
2413 
2414 /* End: bn_mp_init.c */
2415 
2416 /* Start: bn_mp_init_copy.c */
2417 #include "tommath_private.h"
2418 #ifdef BN_MP_INIT_COPY_C
2419 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2420 /* SPDX-License-Identifier: Unlicense */
2421 
2422 /* creates "a" then copies b into it */
mp_init_copy(mp_int * a,const mp_int * b)2423 mp_err mp_init_copy(mp_int *a, const mp_int *b)
2424 {
2425    mp_err     err;
2426 
2427    if ((err = mp_init_size(a, b->used)) != MP_OKAY) {
2428       return err;
2429    }
2430 
2431    if ((err = mp_copy(b, a)) != MP_OKAY) {
2432       mp_clear(a);
2433    }
2434 
2435    return err;
2436 }
2437 #endif
2438 
2439 /* End: bn_mp_init_copy.c */
2440 
2441 /* Start: bn_mp_init_i32.c */
2442 #include "tommath_private.h"
2443 #ifdef BN_MP_INIT_I32_C
2444 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2445 /* SPDX-License-Identifier: Unlicense */
2446 
MP_INIT_INT(mp_init_i32,mp_set_i32,int32_t)2447 MP_INIT_INT(mp_init_i32, mp_set_i32, int32_t)
2448 #endif
2449 
2450 /* End: bn_mp_init_i32.c */
2451 
2452 /* Start: bn_mp_init_i64.c */
2453 #include "tommath_private.h"
2454 #ifdef BN_MP_INIT_I64_C
2455 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2456 /* SPDX-License-Identifier: Unlicense */
2457 
2458 MP_INIT_INT(mp_init_i64, mp_set_i64, int64_t)
2459 #endif
2460 
2461 /* End: bn_mp_init_i64.c */
2462 
2463 /* Start: bn_mp_init_l.c */
2464 #include "tommath_private.h"
2465 #ifdef BN_MP_INIT_L_C
2466 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2467 /* SPDX-License-Identifier: Unlicense */
2468 
2469 MP_INIT_INT(mp_init_l, mp_set_l, long)
2470 #endif
2471 
2472 /* End: bn_mp_init_l.c */
2473 
2474 /* Start: bn_mp_init_ll.c */
2475 #include "tommath_private.h"
2476 #ifdef BN_MP_INIT_LL_C
2477 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2478 /* SPDX-License-Identifier: Unlicense */
2479 
2480 MP_INIT_INT(mp_init_ll, mp_set_ll, long long)
2481 #endif
2482 
2483 /* End: bn_mp_init_ll.c */
2484 
2485 /* Start: bn_mp_init_multi.c */
2486 #include "tommath_private.h"
2487 #ifdef BN_MP_INIT_MULTI_C
2488 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2489 /* SPDX-License-Identifier: Unlicense */
2490 
2491 #include <stdarg.h>
2492 
2493 mp_err mp_init_multi(mp_int *mp, ...)
2494 {
2495    mp_err err = MP_OKAY;      /* Assume ok until proven otherwise */
2496    int n = 0;                 /* Number of ok inits */
2497    mp_int *cur_arg = mp;
2498    va_list args;
2499 
2500    va_start(args, mp);        /* init args to next argument from caller */
2501    while (cur_arg != NULL) {
2502       if (mp_init(cur_arg) != MP_OKAY) {
2503          /* Oops - error! Back-track and mp_clear what we already
2504             succeeded in init-ing, then return error.
2505          */
2506          va_list clean_args;
2507 
2508          /* now start cleaning up */
2509          cur_arg = mp;
2510          va_start(clean_args, mp);
2511          while (n-- != 0) {
2512             mp_clear(cur_arg);
2513             cur_arg = va_arg(clean_args, mp_int *);
2514          }
2515          va_end(clean_args);
2516          err = MP_MEM;
2517          break;
2518       }
2519       n++;
2520       cur_arg = va_arg(args, mp_int *);
2521    }
2522    va_end(args);
2523    return err;                /* Assumed ok, if error flagged above. */
2524 }
2525 
2526 #endif
2527 
2528 /* End: bn_mp_init_multi.c */
2529 
2530 /* Start: bn_mp_init_set.c */
2531 #include "tommath_private.h"
2532 #ifdef BN_MP_INIT_SET_C
2533 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2534 /* SPDX-License-Identifier: Unlicense */
2535 
2536 /* initialize and set a digit */
mp_init_set(mp_int * a,mp_digit b)2537 mp_err mp_init_set(mp_int *a, mp_digit b)
2538 {
2539    mp_err err;
2540    if ((err = mp_init(a)) != MP_OKAY) {
2541       return err;
2542    }
2543    mp_set(a, b);
2544    return err;
2545 }
2546 #endif
2547 
2548 /* End: bn_mp_init_set.c */
2549 
2550 /* Start: bn_mp_init_size.c */
2551 #include "tommath_private.h"
2552 #ifdef BN_MP_INIT_SIZE_C
2553 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2554 /* SPDX-License-Identifier: Unlicense */
2555 
2556 /* init an mp_init for a given size */
mp_init_size(mp_int * a,int size)2557 mp_err mp_init_size(mp_int *a, int size)
2558 {
2559    size = MP_MAX(MP_MIN_PREC, size);
2560 
2561    /* alloc mem */
2562    a->dp = (mp_digit *) MP_CALLOC((size_t)size, sizeof(mp_digit));
2563    if (a->dp == NULL) {
2564       return MP_MEM;
2565    }
2566 
2567    /* set the members */
2568    a->used  = 0;
2569    a->alloc = size;
2570    a->sign  = MP_ZPOS;
2571 
2572    return MP_OKAY;
2573 }
2574 #endif
2575 
2576 /* End: bn_mp_init_size.c */
2577 
2578 /* Start: bn_mp_init_u32.c */
2579 #include "tommath_private.h"
2580 #ifdef BN_MP_INIT_U32_C
2581 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2582 /* SPDX-License-Identifier: Unlicense */
2583 
MP_INIT_INT(mp_init_u32,mp_set_u32,uint32_t)2584 MP_INIT_INT(mp_init_u32, mp_set_u32, uint32_t)
2585 #endif
2586 
2587 /* End: bn_mp_init_u32.c */
2588 
2589 /* Start: bn_mp_init_u64.c */
2590 #include "tommath_private.h"
2591 #ifdef BN_MP_INIT_U64_C
2592 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2593 /* SPDX-License-Identifier: Unlicense */
2594 
2595 MP_INIT_INT(mp_init_u64, mp_set_u64, uint64_t)
2596 #endif
2597 
2598 /* End: bn_mp_init_u64.c */
2599 
2600 /* Start: bn_mp_init_ul.c */
2601 #include "tommath_private.h"
2602 #ifdef BN_MP_INIT_UL_C
2603 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2604 /* SPDX-License-Identifier: Unlicense */
2605 
2606 MP_INIT_INT(mp_init_ul, mp_set_ul, unsigned long)
2607 #endif
2608 
2609 /* End: bn_mp_init_ul.c */
2610 
2611 /* Start: bn_mp_init_ull.c */
2612 #include "tommath_private.h"
2613 #ifdef BN_MP_INIT_ULL_C
2614 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2615 /* SPDX-License-Identifier: Unlicense */
2616 
2617 MP_INIT_INT(mp_init_ull, mp_set_ull, unsigned long long)
2618 #endif
2619 
2620 /* End: bn_mp_init_ull.c */
2621 
2622 /* Start: bn_mp_invmod.c */
2623 #include "tommath_private.h"
2624 #ifdef BN_MP_INVMOD_C
2625 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2626 /* SPDX-License-Identifier: Unlicense */
2627 
2628 /* hac 14.61, pp608 */
2629 mp_err mp_invmod(const mp_int *a, const mp_int *b, mp_int *c)
2630 {
2631    /* b cannot be negative and has to be >1 */
2632    if ((b->sign == MP_NEG) || (mp_cmp_d(b, 1uL) != MP_GT)) {
2633       return MP_VAL;
2634    }
2635 
2636    /* if the modulus is odd we can use a faster routine instead */
2637    if (MP_HAS(S_MP_INVMOD_FAST) && MP_IS_ODD(b)) {
2638       return s_mp_invmod_fast(a, b, c);
2639    }
2640 
2641    return MP_HAS(S_MP_INVMOD_SLOW)
2642           ? s_mp_invmod_slow(a, b, c)
2643           : MP_VAL;
2644 }
2645 #endif
2646 
2647 /* End: bn_mp_invmod.c */
2648 
2649 /* Start: bn_mp_is_square.c */
2650 #include "tommath_private.h"
2651 #ifdef BN_MP_IS_SQUARE_C
2652 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2653 /* SPDX-License-Identifier: Unlicense */
2654 
2655 /* Check if remainders are possible squares - fast exclude non-squares */
2656 static const char rem_128[128] = {
2657    0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
2658    0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
2659    1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
2660    1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
2661    0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
2662    1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
2663    1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
2664    1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
2665 };
2666 
2667 static const char rem_105[105] = {
2668    0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
2669    0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
2670    0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
2671    1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
2672    0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
2673    1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
2674    1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
2675 };
2676 
2677 /* Store non-zero to ret if arg is square, and zero if not */
mp_is_square(const mp_int * arg,mp_bool * ret)2678 mp_err mp_is_square(const mp_int *arg, mp_bool *ret)
2679 {
2680    mp_err        err;
2681    mp_digit      c;
2682    mp_int        t;
2683    unsigned long r;
2684 
2685    /* Default to Non-square :) */
2686    *ret = MP_NO;
2687 
2688    if (arg->sign == MP_NEG) {
2689       return MP_VAL;
2690    }
2691 
2692    if (MP_IS_ZERO(arg)) {
2693       return MP_OKAY;
2694    }
2695 
2696    /* First check mod 128 (suppose that MP_DIGIT_BIT is at least 7) */
2697    if (rem_128[127u & arg->dp[0]] == (char)1) {
2698       return MP_OKAY;
2699    }
2700 
2701    /* Next check mod 105 (3*5*7) */
2702    if ((err = mp_mod_d(arg, 105uL, &c)) != MP_OKAY) {
2703       return err;
2704    }
2705    if (rem_105[c] == (char)1) {
2706       return MP_OKAY;
2707    }
2708 
2709 
2710    if ((err = mp_init_u32(&t, 11u*13u*17u*19u*23u*29u*31u)) != MP_OKAY) {
2711       return err;
2712    }
2713    if ((err = mp_mod(arg, &t, &t)) != MP_OKAY) {
2714       goto LBL_ERR;
2715    }
2716    r = mp_get_u32(&t);
2717    /* Check for other prime modules, note it's not an ERROR but we must
2718     * free "t" so the easiest way is to goto LBL_ERR.  We know that err
2719     * is already equal to MP_OKAY from the mp_mod call
2720     */
2721    if (((1uL<<(r%11uL)) & 0x5C4uL) != 0uL)         goto LBL_ERR;
2722    if (((1uL<<(r%13uL)) & 0x9E4uL) != 0uL)         goto LBL_ERR;
2723    if (((1uL<<(r%17uL)) & 0x5CE8uL) != 0uL)        goto LBL_ERR;
2724    if (((1uL<<(r%19uL)) & 0x4F50CuL) != 0uL)       goto LBL_ERR;
2725    if (((1uL<<(r%23uL)) & 0x7ACCA0uL) != 0uL)      goto LBL_ERR;
2726    if (((1uL<<(r%29uL)) & 0xC2EDD0CuL) != 0uL)     goto LBL_ERR;
2727    if (((1uL<<(r%31uL)) & 0x6DE2B848uL) != 0uL)    goto LBL_ERR;
2728 
2729    /* Final check - is sqr(sqrt(arg)) == arg ? */
2730    if ((err = mp_sqrt(arg, &t)) != MP_OKAY) {
2731       goto LBL_ERR;
2732    }
2733    if ((err = mp_sqr(&t, &t)) != MP_OKAY) {
2734       goto LBL_ERR;
2735    }
2736 
2737    *ret = (mp_cmp_mag(&t, arg) == MP_EQ) ? MP_YES : MP_NO;
2738 LBL_ERR:
2739    mp_clear(&t);
2740    return err;
2741 }
2742 #endif
2743 
2744 /* End: bn_mp_is_square.c */
2745 
2746 /* Start: bn_mp_iseven.c */
2747 #include "tommath_private.h"
2748 #ifdef BN_MP_ISEVEN_C
2749 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2750 /* SPDX-License-Identifier: Unlicense */
2751 
mp_iseven(const mp_int * a)2752 mp_bool mp_iseven(const mp_int *a)
2753 {
2754    return MP_IS_EVEN(a) ? MP_YES : MP_NO;
2755 }
2756 #endif
2757 
2758 /* End: bn_mp_iseven.c */
2759 
2760 /* Start: bn_mp_isodd.c */
2761 #include "tommath_private.h"
2762 #ifdef BN_MP_ISODD_C
2763 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2764 /* SPDX-License-Identifier: Unlicense */
2765 
mp_isodd(const mp_int * a)2766 mp_bool mp_isodd(const mp_int *a)
2767 {
2768    return MP_IS_ODD(a) ? MP_YES : MP_NO;
2769 }
2770 #endif
2771 
2772 /* End: bn_mp_isodd.c */
2773 
2774 /* Start: bn_mp_kronecker.c */
2775 #include "tommath_private.h"
2776 #ifdef BN_MP_KRONECKER_C
2777 
2778 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2779 /* SPDX-License-Identifier: Unlicense */
2780 
2781 /*
2782    Kronecker symbol (a|p)
2783    Straightforward implementation of algorithm 1.4.10 in
2784    Henri Cohen: "A Course in Computational Algebraic Number Theory"
2785 
2786    @book{cohen2013course,
2787      title={A course in computational algebraic number theory},
2788      author={Cohen, Henri},
2789      volume={138},
2790      year={2013},
2791      publisher={Springer Science \& Business Media}
2792     }
2793  */
mp_kronecker(const mp_int * a,const mp_int * p,int * c)2794 mp_err mp_kronecker(const mp_int *a, const mp_int *p, int *c)
2795 {
2796    mp_int a1, p1, r;
2797    mp_err err;
2798    int v, k;
2799 
2800    static const int table[8] = {0, 1, 0, -1, 0, -1, 0, 1};
2801 
2802    if (MP_IS_ZERO(p)) {
2803       if ((a->used == 1) && (a->dp[0] == 1u)) {
2804          *c = 1;
2805       } else {
2806          *c = 0;
2807       }
2808       return MP_OKAY;
2809    }
2810 
2811    if (MP_IS_EVEN(a) && MP_IS_EVEN(p)) {
2812       *c = 0;
2813       return MP_OKAY;
2814    }
2815 
2816    if ((err = mp_init_copy(&a1, a)) != MP_OKAY) {
2817       return err;
2818    }
2819    if ((err = mp_init_copy(&p1, p)) != MP_OKAY) {
2820       goto LBL_KRON_0;
2821    }
2822 
2823    v = mp_cnt_lsb(&p1);
2824    if ((err = mp_div_2d(&p1, v, &p1, NULL)) != MP_OKAY) {
2825       goto LBL_KRON_1;
2826    }
2827 
2828    if ((v & 1) == 0) {
2829       k = 1;
2830    } else {
2831       k = table[a->dp[0] & 7u];
2832    }
2833 
2834    if (p1.sign == MP_NEG) {
2835       p1.sign = MP_ZPOS;
2836       if (a1.sign == MP_NEG) {
2837          k = -k;
2838       }
2839    }
2840 
2841    if ((err = mp_init(&r)) != MP_OKAY) {
2842       goto LBL_KRON_1;
2843    }
2844 
2845    for (;;) {
2846       if (MP_IS_ZERO(&a1)) {
2847          if (mp_cmp_d(&p1, 1uL) == MP_EQ) {
2848             *c = k;
2849             goto LBL_KRON;
2850          } else {
2851             *c = 0;
2852             goto LBL_KRON;
2853          }
2854       }
2855 
2856       v = mp_cnt_lsb(&a1);
2857       if ((err = mp_div_2d(&a1, v, &a1, NULL)) != MP_OKAY) {
2858          goto LBL_KRON;
2859       }
2860 
2861       if ((v & 1) == 1) {
2862          k = k * table[p1.dp[0] & 7u];
2863       }
2864 
2865       if (a1.sign == MP_NEG) {
2866          /*
2867           * Compute k = (-1)^((a1)*(p1-1)/4) * k
2868           * a1.dp[0] + 1 cannot overflow because the MSB
2869           * of the type mp_digit is not set by definition
2870           */
2871          if (((a1.dp[0] + 1u) & p1.dp[0] & 2u) != 0u) {
2872             k = -k;
2873          }
2874       } else {
2875          /* compute k = (-1)^((a1-1)*(p1-1)/4) * k */
2876          if ((a1.dp[0] & p1.dp[0] & 2u) != 0u) {
2877             k = -k;
2878          }
2879       }
2880 
2881       if ((err = mp_copy(&a1, &r)) != MP_OKAY) {
2882          goto LBL_KRON;
2883       }
2884       r.sign = MP_ZPOS;
2885       if ((err = mp_mod(&p1, &r, &a1)) != MP_OKAY) {
2886          goto LBL_KRON;
2887       }
2888       if ((err = mp_copy(&r, &p1)) != MP_OKAY) {
2889          goto LBL_KRON;
2890       }
2891    }
2892 
2893 LBL_KRON:
2894    mp_clear(&r);
2895 LBL_KRON_1:
2896    mp_clear(&p1);
2897 LBL_KRON_0:
2898    mp_clear(&a1);
2899 
2900    return err;
2901 }
2902 
2903 #endif
2904 
2905 /* End: bn_mp_kronecker.c */
2906 
2907 /* Start: bn_mp_lcm.c */
2908 #include "tommath_private.h"
2909 #ifdef BN_MP_LCM_C
2910 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2911 /* SPDX-License-Identifier: Unlicense */
2912 
2913 /* computes least common multiple as |a*b|/(a, b) */
mp_lcm(const mp_int * a,const mp_int * b,mp_int * c)2914 mp_err mp_lcm(const mp_int *a, const mp_int *b, mp_int *c)
2915 {
2916    mp_err  err;
2917    mp_int  t1, t2;
2918 
2919 
2920    if ((err = mp_init_multi(&t1, &t2, NULL)) != MP_OKAY) {
2921       return err;
2922    }
2923 
2924    /* t1 = get the GCD of the two inputs */
2925    if ((err = mp_gcd(a, b, &t1)) != MP_OKAY) {
2926       goto LBL_T;
2927    }
2928 
2929    /* divide the smallest by the GCD */
2930    if (mp_cmp_mag(a, b) == MP_LT) {
2931       /* store quotient in t2 such that t2 * b is the LCM */
2932       if ((err = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
2933          goto LBL_T;
2934       }
2935       err = mp_mul(b, &t2, c);
2936    } else {
2937       /* store quotient in t2 such that t2 * a is the LCM */
2938       if ((err = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
2939          goto LBL_T;
2940       }
2941       err = mp_mul(a, &t2, c);
2942    }
2943 
2944    /* fix the sign to positive */
2945    c->sign = MP_ZPOS;
2946 
2947 LBL_T:
2948    mp_clear_multi(&t1, &t2, NULL);
2949    return err;
2950 }
2951 #endif
2952 
2953 /* End: bn_mp_lcm.c */
2954 
2955 /* Start: bn_mp_log_u32.c */
2956 #include "tommath_private.h"
2957 #ifdef BN_MP_LOG_U32_C
2958 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
2959 /* SPDX-License-Identifier: Unlicense */
2960 
2961 /* Compute log_{base}(a) */
s_pow(mp_word base,mp_word exponent)2962 static mp_word s_pow(mp_word base, mp_word exponent)
2963 {
2964    mp_word result = 1uLL;
2965    while (exponent != 0u) {
2966       if ((exponent & 1u) == 1u) {
2967          result *= base;
2968       }
2969       exponent >>= 1;
2970       base *= base;
2971    }
2972 
2973    return result;
2974 }
2975 
s_digit_ilogb(mp_digit base,mp_digit n)2976 static mp_digit s_digit_ilogb(mp_digit base, mp_digit n)
2977 {
2978    mp_word bracket_low = 1uLL, bracket_mid, bracket_high, N;
2979    mp_digit ret, high = 1uL, low = 0uL, mid;
2980 
2981    if (n < base) {
2982       return 0uL;
2983    }
2984    if (n == base) {
2985       return 1uL;
2986    }
2987 
2988    bracket_high = (mp_word) base ;
2989    N = (mp_word) n;
2990 
2991    while (bracket_high < N) {
2992       low = high;
2993       bracket_low = bracket_high;
2994       high <<= 1;
2995       bracket_high *= bracket_high;
2996    }
2997 
2998    while (((mp_digit)(high - low)) > 1uL) {
2999       mid = (low + high) >> 1;
3000       bracket_mid = bracket_low * s_pow(base, (mp_word)(mid - low));
3001 
3002       if (N < bracket_mid) {
3003          high = mid ;
3004          bracket_high = bracket_mid ;
3005       }
3006       if (N > bracket_mid) {
3007          low = mid ;
3008          bracket_low = bracket_mid ;
3009       }
3010       if (N == bracket_mid) {
3011          return (mp_digit) mid;
3012       }
3013    }
3014 
3015    if (bracket_high == N) {
3016       ret = high;
3017    } else {
3018       ret = low;
3019    }
3020 
3021    return ret;
3022 }
3023 
3024 /* TODO: output could be "int" because the output of mp_radix_size is int, too,
3025          as is the output of mp_bitcount.
3026          With the same problem: max size is INT_MAX * MP_DIGIT not INT_MAX only!
3027 */
mp_log_u32(const mp_int * a,uint32_t base,uint32_t * c)3028 mp_err mp_log_u32(const mp_int *a, uint32_t base, uint32_t *c)
3029 {
3030    mp_err err;
3031    mp_ord cmp;
3032    uint32_t high, low, mid;
3033    mp_int bracket_low, bracket_high, bracket_mid, t, bi_base;
3034 
3035    err = MP_OKAY;
3036 
3037    if (a->sign == MP_NEG) {
3038       return MP_VAL;
3039    }
3040 
3041    if (MP_IS_ZERO(a)) {
3042       return MP_VAL;
3043    }
3044 
3045    if (base < 2u) {
3046       return MP_VAL;
3047    }
3048 
3049    /* A small shortcut for bases that are powers of two. */
3050    if ((base & (base - 1u)) == 0u) {
3051       int y, bit_count;
3052       for (y=0; (y < 7) && ((base & 1u) == 0u); y++) {
3053          base >>= 1;
3054       }
3055       bit_count = mp_count_bits(a) - 1;
3056       *c = (uint32_t)(bit_count/y);
3057       return MP_OKAY;
3058    }
3059 
3060    if (a->used == 1) {
3061       *c = (uint32_t)s_digit_ilogb(base, a->dp[0]);
3062       return err;
3063    }
3064 
3065    cmp = mp_cmp_d(a, base);
3066    if ((cmp == MP_LT) || (cmp == MP_EQ)) {
3067       *c = cmp == MP_EQ;
3068       return err;
3069    }
3070 
3071    if ((err =
3072            mp_init_multi(&bracket_low, &bracket_high,
3073                          &bracket_mid, &t, &bi_base, NULL)) != MP_OKAY) {
3074       return err;
3075    }
3076 
3077    low = 0u;
3078    mp_set(&bracket_low, 1uL);
3079    high = 1u;
3080 
3081    mp_set(&bracket_high, base);
3082 
3083    /*
3084        A kind of Giant-step/baby-step algorithm.
3085        Idea shamelessly stolen from https://programmingpraxis.com/2010/05/07/integer-logarithms/2/
3086        The effect is asymptotic, hence needs benchmarks to test if the Giant-step should be skipped
3087        for small n.
3088     */
3089    while (mp_cmp(&bracket_high, a) == MP_LT) {
3090       low = high;
3091       if ((err = mp_copy(&bracket_high, &bracket_low)) != MP_OKAY) {
3092          goto LBL_ERR;
3093       }
3094       high <<= 1;
3095       if ((err = mp_sqr(&bracket_high, &bracket_high)) != MP_OKAY) {
3096          goto LBL_ERR;
3097       }
3098    }
3099    mp_set(&bi_base, base);
3100 
3101    while ((high - low) > 1u) {
3102       mid = (high + low) >> 1;
3103 
3104       if ((err = mp_expt_u32(&bi_base, (uint32_t)(mid - low), &t)) != MP_OKAY) {
3105          goto LBL_ERR;
3106       }
3107       if ((err = mp_mul(&bracket_low, &t, &bracket_mid)) != MP_OKAY) {
3108          goto LBL_ERR;
3109       }
3110       cmp = mp_cmp(a, &bracket_mid);
3111       if (cmp == MP_LT) {
3112          high = mid;
3113          mp_exch(&bracket_mid, &bracket_high);
3114       }
3115       if (cmp == MP_GT) {
3116          low = mid;
3117          mp_exch(&bracket_mid, &bracket_low);
3118       }
3119       if (cmp == MP_EQ) {
3120          *c = mid;
3121          goto LBL_END;
3122       }
3123    }
3124 
3125    *c = (mp_cmp(&bracket_high, a) == MP_EQ) ? high : low;
3126 
3127 LBL_END:
3128 LBL_ERR:
3129    mp_clear_multi(&bracket_low, &bracket_high, &bracket_mid,
3130                   &t, &bi_base, NULL);
3131    return err;
3132 }
3133 
3134 
3135 #endif
3136 
3137 /* End: bn_mp_log_u32.c */
3138 
3139 /* Start: bn_mp_lshd.c */
3140 #include "tommath_private.h"
3141 #ifdef BN_MP_LSHD_C
3142 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3143 /* SPDX-License-Identifier: Unlicense */
3144 
3145 /* shift left a certain amount of digits */
mp_lshd(mp_int * a,int b)3146 mp_err mp_lshd(mp_int *a, int b)
3147 {
3148    int x;
3149    mp_err err;
3150    mp_digit *top, *bottom;
3151 
3152    /* if its less than zero return */
3153    if (b <= 0) {
3154       return MP_OKAY;
3155    }
3156    /* no need to shift 0 around */
3157    if (MP_IS_ZERO(a)) {
3158       return MP_OKAY;
3159    }
3160 
3161    /* grow to fit the new digits */
3162    if (a->alloc < (a->used + b)) {
3163       if ((err = mp_grow(a, a->used + b)) != MP_OKAY) {
3164          return err;
3165       }
3166    }
3167 
3168    /* increment the used by the shift amount then copy upwards */
3169    a->used += b;
3170 
3171    /* top */
3172    top = a->dp + a->used - 1;
3173 
3174    /* base */
3175    bottom = (a->dp + a->used - 1) - b;
3176 
3177    /* much like mp_rshd this is implemented using a sliding window
3178     * except the window goes the otherway around.  Copying from
3179     * the bottom to the top.  see bn_mp_rshd.c for more info.
3180     */
3181    for (x = a->used - 1; x >= b; x--) {
3182       *top-- = *bottom--;
3183    }
3184 
3185    /* zero the lower digits */
3186    MP_ZERO_DIGITS(a->dp, b);
3187 
3188    return MP_OKAY;
3189 }
3190 #endif
3191 
3192 /* End: bn_mp_lshd.c */
3193 
3194 /* Start: bn_mp_mod.c */
3195 #include "tommath_private.h"
3196 #ifdef BN_MP_MOD_C
3197 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3198 /* SPDX-License-Identifier: Unlicense */
3199 
3200 /* c = a mod b, 0 <= c < b if b > 0, b < c <= 0 if b < 0 */
mp_mod(const mp_int * a,const mp_int * b,mp_int * c)3201 mp_err mp_mod(const mp_int *a, const mp_int *b, mp_int *c)
3202 {
3203    mp_int  t;
3204    mp_err  err;
3205 
3206    if ((err = mp_init_size(&t, b->used)) != MP_OKAY) {
3207       return err;
3208    }
3209 
3210    if ((err = mp_div(a, b, NULL, &t)) != MP_OKAY) {
3211       goto LBL_ERR;
3212    }
3213 
3214    if (MP_IS_ZERO(&t) || (t.sign == b->sign)) {
3215       err = MP_OKAY;
3216       mp_exch(&t, c);
3217    } else {
3218       err = mp_add(b, &t, c);
3219    }
3220 
3221 LBL_ERR:
3222    mp_clear(&t);
3223    return err;
3224 }
3225 #endif
3226 
3227 /* End: bn_mp_mod.c */
3228 
3229 /* Start: bn_mp_mod_2d.c */
3230 #include "tommath_private.h"
3231 #ifdef BN_MP_MOD_2D_C
3232 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3233 /* SPDX-License-Identifier: Unlicense */
3234 
3235 /* calc a value mod 2**b */
mp_mod_2d(const mp_int * a,int b,mp_int * c)3236 mp_err mp_mod_2d(const mp_int *a, int b, mp_int *c)
3237 {
3238    int x;
3239    mp_err err;
3240 
3241    /* if b is <= 0 then zero the int */
3242    if (b <= 0) {
3243       mp_zero(c);
3244       return MP_OKAY;
3245    }
3246 
3247    /* if the modulus is larger than the value than return */
3248    if (b >= (a->used * MP_DIGIT_BIT)) {
3249       return mp_copy(a, c);
3250    }
3251 
3252    /* copy */
3253    if ((err = mp_copy(a, c)) != MP_OKAY) {
3254       return err;
3255    }
3256 
3257    /* zero digits above the last digit of the modulus */
3258    x = (b / MP_DIGIT_BIT) + (((b % MP_DIGIT_BIT) == 0) ? 0 : 1);
3259    MP_ZERO_DIGITS(c->dp + x, c->used - x);
3260 
3261    /* clear the digit that is not completely outside/inside the modulus */
3262    c->dp[b / MP_DIGIT_BIT] &=
3263       ((mp_digit)1 << (mp_digit)(b % MP_DIGIT_BIT)) - (mp_digit)1;
3264    mp_clamp(c);
3265    return MP_OKAY;
3266 }
3267 #endif
3268 
3269 /* End: bn_mp_mod_2d.c */
3270 
3271 /* Start: bn_mp_mod_d.c */
3272 #include "tommath_private.h"
3273 #ifdef BN_MP_MOD_D_C
3274 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3275 /* SPDX-License-Identifier: Unlicense */
3276 
mp_mod_d(const mp_int * a,mp_digit b,mp_digit * c)3277 mp_err mp_mod_d(const mp_int *a, mp_digit b, mp_digit *c)
3278 {
3279    return mp_div_d(a, b, NULL, c);
3280 }
3281 #endif
3282 
3283 /* End: bn_mp_mod_d.c */
3284 
3285 /* Start: bn_mp_montgomery_calc_normalization.c */
3286 #include "tommath_private.h"
3287 #ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
3288 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3289 /* SPDX-License-Identifier: Unlicense */
3290 
3291 /*
3292  * shifts with subtractions when the result is greater than b.
3293  *
3294  * The method is slightly modified to shift B unconditionally upto just under
3295  * the leading bit of b.  This saves alot of multiple precision shifting.
3296  */
mp_montgomery_calc_normalization(mp_int * a,const mp_int * b)3297 mp_err mp_montgomery_calc_normalization(mp_int *a, const mp_int *b)
3298 {
3299    int    x, bits;
3300    mp_err err;
3301 
3302    /* how many bits of last digit does b use */
3303    bits = mp_count_bits(b) % MP_DIGIT_BIT;
3304 
3305    if (b->used > 1) {
3306       if ((err = mp_2expt(a, ((b->used - 1) * MP_DIGIT_BIT) + bits - 1)) != MP_OKAY) {
3307          return err;
3308       }
3309    } else {
3310       mp_set(a, 1uL);
3311       bits = 1;
3312    }
3313 
3314 
3315    /* now compute C = A * B mod b */
3316    for (x = bits - 1; x < (int)MP_DIGIT_BIT; x++) {
3317       if ((err = mp_mul_2(a, a)) != MP_OKAY) {
3318          return err;
3319       }
3320       if (mp_cmp_mag(a, b) != MP_LT) {
3321          if ((err = s_mp_sub(a, b, a)) != MP_OKAY) {
3322             return err;
3323          }
3324       }
3325    }
3326 
3327    return MP_OKAY;
3328 }
3329 #endif
3330 
3331 /* End: bn_mp_montgomery_calc_normalization.c */
3332 
3333 /* Start: bn_mp_montgomery_reduce.c */
3334 #include "tommath_private.h"
3335 #ifdef BN_MP_MONTGOMERY_REDUCE_C
3336 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3337 /* SPDX-License-Identifier: Unlicense */
3338 
3339 /* computes xR**-1 == x (mod N) via Montgomery Reduction */
mp_montgomery_reduce(mp_int * x,const mp_int * n,mp_digit rho)3340 mp_err mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho)
3341 {
3342    int      ix, digs;
3343    mp_err   err;
3344    mp_digit mu;
3345 
3346    /* can the fast reduction [comba] method be used?
3347     *
3348     * Note that unlike in mul you're safely allowed *less*
3349     * than the available columns [255 per default] since carries
3350     * are fixed up in the inner loop.
3351     */
3352    digs = (n->used * 2) + 1;
3353    if ((digs < MP_WARRAY) &&
3354        (x->used <= MP_WARRAY) &&
3355        (n->used < MP_MAXFAST)) {
3356       return s_mp_montgomery_reduce_fast(x, n, rho);
3357    }
3358 
3359    /* grow the input as required */
3360    if (x->alloc < digs) {
3361       if ((err = mp_grow(x, digs)) != MP_OKAY) {
3362          return err;
3363       }
3364    }
3365    x->used = digs;
3366 
3367    for (ix = 0; ix < n->used; ix++) {
3368       /* mu = ai * rho mod b
3369        *
3370        * The value of rho must be precalculated via
3371        * montgomery_setup() such that
3372        * it equals -1/n0 mod b this allows the
3373        * following inner loop to reduce the
3374        * input one digit at a time
3375        */
3376       mu = (mp_digit)(((mp_word)x->dp[ix] * (mp_word)rho) & MP_MASK);
3377 
3378       /* a = a + mu * m * b**i */
3379       {
3380          int iy;
3381          mp_digit *tmpn, *tmpx, u;
3382          mp_word r;
3383 
3384          /* alias for digits of the modulus */
3385          tmpn = n->dp;
3386 
3387          /* alias for the digits of x [the input] */
3388          tmpx = x->dp + ix;
3389 
3390          /* set the carry to zero */
3391          u = 0;
3392 
3393          /* Multiply and add in place */
3394          for (iy = 0; iy < n->used; iy++) {
3395             /* compute product and sum */
3396             r       = ((mp_word)mu * (mp_word)*tmpn++) +
3397                       (mp_word)u + (mp_word)*tmpx;
3398 
3399             /* get carry */
3400             u       = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
3401 
3402             /* fix digit */
3403             *tmpx++ = (mp_digit)(r & (mp_word)MP_MASK);
3404          }
3405          /* At this point the ix'th digit of x should be zero */
3406 
3407 
3408          /* propagate carries upwards as required*/
3409          while (u != 0u) {
3410             *tmpx   += u;
3411             u        = *tmpx >> MP_DIGIT_BIT;
3412             *tmpx++ &= MP_MASK;
3413          }
3414       }
3415    }
3416 
3417    /* at this point the n.used'th least
3418     * significant digits of x are all zero
3419     * which means we can shift x to the
3420     * right by n.used digits and the
3421     * residue is unchanged.
3422     */
3423 
3424    /* x = x/b**n.used */
3425    mp_clamp(x);
3426    mp_rshd(x, n->used);
3427 
3428    /* if x >= n then x = x - n */
3429    if (mp_cmp_mag(x, n) != MP_LT) {
3430       return s_mp_sub(x, n, x);
3431    }
3432 
3433    return MP_OKAY;
3434 }
3435 #endif
3436 
3437 /* End: bn_mp_montgomery_reduce.c */
3438 
3439 /* Start: bn_mp_montgomery_setup.c */
3440 #include "tommath_private.h"
3441 #ifdef BN_MP_MONTGOMERY_SETUP_C
3442 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3443 /* SPDX-License-Identifier: Unlicense */
3444 
3445 /* setups the montgomery reduction stuff */
mp_montgomery_setup(const mp_int * n,mp_digit * rho)3446 mp_err mp_montgomery_setup(const mp_int *n, mp_digit *rho)
3447 {
3448    mp_digit x, b;
3449 
3450    /* fast inversion mod 2**k
3451     *
3452     * Based on the fact that
3453     *
3454     * XA = 1 (mod 2**n)  =>  (X(2-XA)) A = 1 (mod 2**2n)
3455     *                    =>  2*X*A - X*X*A*A = 1
3456     *                    =>  2*(1) - (1)     = 1
3457     */
3458    b = n->dp[0];
3459 
3460    if ((b & 1u) == 0u) {
3461       return MP_VAL;
3462    }
3463 
3464    x = (((b + 2u) & 4u) << 1) + b; /* here x*a==1 mod 2**4 */
3465    x *= 2u - (b * x);              /* here x*a==1 mod 2**8 */
3466 #if !defined(MP_8BIT)
3467    x *= 2u - (b * x);              /* here x*a==1 mod 2**16 */
3468 #endif
3469 #if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
3470    x *= 2u - (b * x);              /* here x*a==1 mod 2**32 */
3471 #endif
3472 #ifdef MP_64BIT
3473    x *= 2u - (b * x);              /* here x*a==1 mod 2**64 */
3474 #endif
3475 
3476    /* rho = -1/m mod b */
3477    *rho = (mp_digit)(((mp_word)1 << (mp_word)MP_DIGIT_BIT) - x) & MP_MASK;
3478 
3479    return MP_OKAY;
3480 }
3481 #endif
3482 
3483 /* End: bn_mp_montgomery_setup.c */
3484 
3485 /* Start: bn_mp_mul.c */
3486 #include "tommath_private.h"
3487 #ifdef BN_MP_MUL_C
3488 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3489 /* SPDX-License-Identifier: Unlicense */
3490 
3491 /* high level multiplication (handles sign) */
mp_mul(const mp_int * a,const mp_int * b,mp_int * c)3492 mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c)
3493 {
3494    mp_err err;
3495    int min_len = MP_MIN(a->used, b->used),
3496        max_len = MP_MAX(a->used, b->used),
3497        digs = a->used + b->used + 1;
3498    mp_sign neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
3499 
3500    if (MP_HAS(S_MP_BALANCE_MUL) &&
3501        /* Check sizes. The smaller one needs to be larger than the Karatsuba cut-off.
3502         * The bigger one needs to be at least about one MP_KARATSUBA_MUL_CUTOFF bigger
3503         * to make some sense, but it depends on architecture, OS, position of the
3504         * stars... so YMMV.
3505         * Using it to cut the input into slices small enough for fast_s_mp_mul_digs
3506         * was actually slower on the author's machine, but YMMV.
3507         */
3508        (min_len >= MP_KARATSUBA_MUL_CUTOFF) &&
3509        ((max_len / 2) >= MP_KARATSUBA_MUL_CUTOFF) &&
3510        /* Not much effect was observed below a ratio of 1:2, but again: YMMV. */
3511        (max_len >= (2 * min_len))) {
3512       err = s_mp_balance_mul(a,b,c);
3513    } else if (MP_HAS(S_MP_TOOM_MUL) &&
3514               (min_len >= MP_TOOM_MUL_CUTOFF)) {
3515       err = s_mp_toom_mul(a, b, c);
3516    } else if (MP_HAS(S_MP_KARATSUBA_MUL) &&
3517               (min_len >= MP_KARATSUBA_MUL_CUTOFF)) {
3518       err = s_mp_karatsuba_mul(a, b, c);
3519    } else if (MP_HAS(S_MP_MUL_DIGS_FAST) &&
3520               /* can we use the fast multiplier?
3521                *
3522                * The fast multiplier can be used if the output will
3523                * have less than MP_WARRAY digits and the number of
3524                * digits won't affect carry propagation
3525                */
3526               (digs < MP_WARRAY) &&
3527               (min_len <= MP_MAXFAST)) {
3528       err = s_mp_mul_digs_fast(a, b, c, digs);
3529    } else if (MP_HAS(S_MP_MUL_DIGS)) {
3530       err = s_mp_mul_digs(a, b, c, digs);
3531    } else {
3532       err = MP_VAL;
3533    }
3534    c->sign = (c->used > 0) ? neg : MP_ZPOS;
3535    return err;
3536 }
3537 #endif
3538 
3539 /* End: bn_mp_mul.c */
3540 
3541 /* Start: bn_mp_mul_2.c */
3542 #include "tommath_private.h"
3543 #ifdef BN_MP_MUL_2_C
3544 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3545 /* SPDX-License-Identifier: Unlicense */
3546 
3547 /* b = a*2 */
mp_mul_2(const mp_int * a,mp_int * b)3548 mp_err mp_mul_2(const mp_int *a, mp_int *b)
3549 {
3550    int     x, oldused;
3551    mp_err err;
3552 
3553    /* grow to accomodate result */
3554    if (b->alloc < (a->used + 1)) {
3555       if ((err = mp_grow(b, a->used + 1)) != MP_OKAY) {
3556          return err;
3557       }
3558    }
3559 
3560    oldused = b->used;
3561    b->used = a->used;
3562 
3563    {
3564       mp_digit r, rr, *tmpa, *tmpb;
3565 
3566       /* alias for source */
3567       tmpa = a->dp;
3568 
3569       /* alias for dest */
3570       tmpb = b->dp;
3571 
3572       /* carry */
3573       r = 0;
3574       for (x = 0; x < a->used; x++) {
3575 
3576          /* get what will be the *next* carry bit from the
3577           * MSB of the current digit
3578           */
3579          rr = *tmpa >> (mp_digit)(MP_DIGIT_BIT - 1);
3580 
3581          /* now shift up this digit, add in the carry [from the previous] */
3582          *tmpb++ = ((*tmpa++ << 1uL) | r) & MP_MASK;
3583 
3584          /* copy the carry that would be from the source
3585           * digit into the next iteration
3586           */
3587          r = rr;
3588       }
3589 
3590       /* new leading digit? */
3591       if (r != 0u) {
3592          /* add a MSB which is always 1 at this point */
3593          *tmpb = 1;
3594          ++(b->used);
3595       }
3596 
3597       /* now zero any excess digits on the destination
3598        * that we didn't write to
3599        */
3600       MP_ZERO_DIGITS(b->dp + b->used, oldused - b->used);
3601    }
3602    b->sign = a->sign;
3603    return MP_OKAY;
3604 }
3605 #endif
3606 
3607 /* End: bn_mp_mul_2.c */
3608 
3609 /* Start: bn_mp_mul_2d.c */
3610 #include "tommath_private.h"
3611 #ifdef BN_MP_MUL_2D_C
3612 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3613 /* SPDX-License-Identifier: Unlicense */
3614 
3615 /* shift left by a certain bit count */
mp_mul_2d(const mp_int * a,int b,mp_int * c)3616 mp_err mp_mul_2d(const mp_int *a, int b, mp_int *c)
3617 {
3618    mp_digit d;
3619    mp_err   err;
3620 
3621    /* copy */
3622    if (a != c) {
3623       if ((err = mp_copy(a, c)) != MP_OKAY) {
3624          return err;
3625       }
3626    }
3627 
3628    if (c->alloc < (c->used + (b / MP_DIGIT_BIT) + 1)) {
3629       if ((err = mp_grow(c, c->used + (b / MP_DIGIT_BIT) + 1)) != MP_OKAY) {
3630          return err;
3631       }
3632    }
3633 
3634    /* shift by as many digits in the bit count */
3635    if (b >= MP_DIGIT_BIT) {
3636       if ((err = mp_lshd(c, b / MP_DIGIT_BIT)) != MP_OKAY) {
3637          return err;
3638       }
3639    }
3640 
3641    /* shift any bit count < MP_DIGIT_BIT */
3642    d = (mp_digit)(b % MP_DIGIT_BIT);
3643    if (d != 0u) {
3644       mp_digit *tmpc, shift, mask, r, rr;
3645       int x;
3646 
3647       /* bitmask for carries */
3648       mask = ((mp_digit)1 << d) - (mp_digit)1;
3649 
3650       /* shift for msbs */
3651       shift = (mp_digit)MP_DIGIT_BIT - d;
3652 
3653       /* alias */
3654       tmpc = c->dp;
3655 
3656       /* carry */
3657       r    = 0;
3658       for (x = 0; x < c->used; x++) {
3659          /* get the higher bits of the current word */
3660          rr = (*tmpc >> shift) & mask;
3661 
3662          /* shift the current word and OR in the carry */
3663          *tmpc = ((*tmpc << d) | r) & MP_MASK;
3664          ++tmpc;
3665 
3666          /* set the carry to the carry bits of the current word */
3667          r = rr;
3668       }
3669 
3670       /* set final carry */
3671       if (r != 0u) {
3672          c->dp[(c->used)++] = r;
3673       }
3674    }
3675    mp_clamp(c);
3676    return MP_OKAY;
3677 }
3678 #endif
3679 
3680 /* End: bn_mp_mul_2d.c */
3681 
3682 /* Start: bn_mp_mul_d.c */
3683 #include "tommath_private.h"
3684 #ifdef BN_MP_MUL_D_C
3685 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3686 /* SPDX-License-Identifier: Unlicense */
3687 
3688 /* multiply by a digit */
mp_mul_d(const mp_int * a,mp_digit b,mp_int * c)3689 mp_err mp_mul_d(const mp_int *a, mp_digit b, mp_int *c)
3690 {
3691    mp_digit u, *tmpa, *tmpc;
3692    mp_word  r;
3693    mp_err   err;
3694    int      ix, olduse;
3695 
3696    /* make sure c is big enough to hold a*b */
3697    if (c->alloc < (a->used + 1)) {
3698       if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) {
3699          return err;
3700       }
3701    }
3702 
3703    /* get the original destinations used count */
3704    olduse = c->used;
3705 
3706    /* set the sign */
3707    c->sign = a->sign;
3708 
3709    /* alias for a->dp [source] */
3710    tmpa = a->dp;
3711 
3712    /* alias for c->dp [dest] */
3713    tmpc = c->dp;
3714 
3715    /* zero carry */
3716    u = 0;
3717 
3718    /* compute columns */
3719    for (ix = 0; ix < a->used; ix++) {
3720       /* compute product and carry sum for this term */
3721       r       = (mp_word)u + ((mp_word)*tmpa++ * (mp_word)b);
3722 
3723       /* mask off higher bits to get a single digit */
3724       *tmpc++ = (mp_digit)(r & (mp_word)MP_MASK);
3725 
3726       /* send carry into next iteration */
3727       u       = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
3728    }
3729 
3730    /* store final carry [if any] and increment ix offset  */
3731    *tmpc++ = u;
3732    ++ix;
3733 
3734    /* now zero digits above the top */
3735    MP_ZERO_DIGITS(tmpc, olduse - ix);
3736 
3737    /* set used count */
3738    c->used = a->used + 1;
3739    mp_clamp(c);
3740 
3741    return MP_OKAY;
3742 }
3743 #endif
3744 
3745 /* End: bn_mp_mul_d.c */
3746 
3747 /* Start: bn_mp_mulmod.c */
3748 #include "tommath_private.h"
3749 #ifdef BN_MP_MULMOD_C
3750 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3751 /* SPDX-License-Identifier: Unlicense */
3752 
3753 /* d = a * b (mod c) */
mp_mulmod(const mp_int * a,const mp_int * b,const mp_int * c,mp_int * d)3754 mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d)
3755 {
3756    mp_err err;
3757    mp_int t;
3758 
3759    if ((err = mp_init_size(&t, c->used)) != MP_OKAY) {
3760       return err;
3761    }
3762 
3763    if ((err = mp_mul(a, b, &t)) != MP_OKAY) {
3764       goto LBL_ERR;
3765    }
3766    err = mp_mod(&t, c, d);
3767 
3768 LBL_ERR:
3769    mp_clear(&t);
3770    return err;
3771 }
3772 #endif
3773 
3774 /* End: bn_mp_mulmod.c */
3775 
3776 /* Start: bn_mp_neg.c */
3777 #include "tommath_private.h"
3778 #ifdef BN_MP_NEG_C
3779 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3780 /* SPDX-License-Identifier: Unlicense */
3781 
3782 /* b = -a */
mp_neg(const mp_int * a,mp_int * b)3783 mp_err mp_neg(const mp_int *a, mp_int *b)
3784 {
3785    mp_err err;
3786    if (a != b) {
3787       if ((err = mp_copy(a, b)) != MP_OKAY) {
3788          return err;
3789       }
3790    }
3791 
3792    if (!MP_IS_ZERO(b)) {
3793       b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
3794    } else {
3795       b->sign = MP_ZPOS;
3796    }
3797 
3798    return MP_OKAY;
3799 }
3800 #endif
3801 
3802 /* End: bn_mp_neg.c */
3803 
3804 /* Start: bn_mp_or.c */
3805 #include "tommath_private.h"
3806 #ifdef BN_MP_OR_C
3807 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3808 /* SPDX-License-Identifier: Unlicense */
3809 
3810 /* two complement or */
mp_or(const mp_int * a,const mp_int * b,mp_int * c)3811 mp_err mp_or(const mp_int *a, const mp_int *b, mp_int *c)
3812 {
3813    int used = MP_MAX(a->used, b->used) + 1, i;
3814    mp_err err;
3815    mp_digit ac = 1, bc = 1, cc = 1;
3816    mp_sign csign = ((a->sign == MP_NEG) || (b->sign == MP_NEG)) ? MP_NEG : MP_ZPOS;
3817 
3818    if (c->alloc < used) {
3819       if ((err = mp_grow(c, used)) != MP_OKAY) {
3820          return err;
3821       }
3822    }
3823 
3824    for (i = 0; i < used; i++) {
3825       mp_digit x, y;
3826 
3827       /* convert to two complement if negative */
3828       if (a->sign == MP_NEG) {
3829          ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK);
3830          x = ac & MP_MASK;
3831          ac >>= MP_DIGIT_BIT;
3832       } else {
3833          x = (i >= a->used) ? 0uL : a->dp[i];
3834       }
3835 
3836       /* convert to two complement if negative */
3837       if (b->sign == MP_NEG) {
3838          bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK);
3839          y = bc & MP_MASK;
3840          bc >>= MP_DIGIT_BIT;
3841       } else {
3842          y = (i >= b->used) ? 0uL : b->dp[i];
3843       }
3844 
3845       c->dp[i] = x | y;
3846 
3847       /* convert to to sign-magnitude if negative */
3848       if (csign == MP_NEG) {
3849          cc += ~c->dp[i] & MP_MASK;
3850          c->dp[i] = cc & MP_MASK;
3851          cc >>= MP_DIGIT_BIT;
3852       }
3853    }
3854 
3855    c->used = used;
3856    c->sign = csign;
3857    mp_clamp(c);
3858    return MP_OKAY;
3859 }
3860 #endif
3861 
3862 /* End: bn_mp_or.c */
3863 
3864 /* Start: bn_mp_pack.c */
3865 #include "tommath_private.h"
3866 #ifdef BN_MP_PACK_C
3867 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3868 /* SPDX-License-Identifier: Unlicense */
3869 
3870 /* based on gmp's mpz_export.
3871  * see http://gmplib.org/manual/Integer-Import-and-Export.html
3872  */
mp_pack(void * rop,size_t maxcount,size_t * written,mp_order order,size_t size,mp_endian endian,size_t nails,const mp_int * op)3873 mp_err mp_pack(void *rop, size_t maxcount, size_t *written, mp_order order, size_t size,
3874                mp_endian endian, size_t nails, const mp_int *op)
3875 {
3876    mp_err err;
3877    size_t odd_nails, nail_bytes, i, j, count;
3878    unsigned char odd_nail_mask;
3879 
3880    mp_int t;
3881 
3882    count = mp_pack_count(op, nails, size);
3883 
3884    if (count > maxcount) {
3885       return MP_BUF;
3886    }
3887 
3888    if ((err = mp_init_copy(&t, op)) != MP_OKAY) {
3889       return err;
3890    }
3891 
3892    if (endian == MP_NATIVE_ENDIAN) {
3893       MP_GET_ENDIANNESS(endian);
3894    }
3895 
3896    odd_nails = (nails % 8u);
3897    odd_nail_mask = 0xff;
3898    for (i = 0u; i < odd_nails; ++i) {
3899       odd_nail_mask ^= (unsigned char)(1u << (7u - i));
3900    }
3901    nail_bytes = nails / 8u;
3902 
3903    for (i = 0u; i < count; ++i) {
3904       for (j = 0u; j < size; ++j) {
3905          unsigned char *byte = (unsigned char *)rop +
3906                                (((order == MP_LSB_FIRST) ? i : ((count - 1u) - i)) * size) +
3907                                ((endian == MP_LITTLE_ENDIAN) ? j : ((size - 1u) - j));
3908 
3909          if (j >= (size - nail_bytes)) {
3910             *byte = 0;
3911             continue;
3912          }
3913 
3914          *byte = (unsigned char)((j == ((size - nail_bytes) - 1u)) ? (t.dp[0] & odd_nail_mask) : (t.dp[0] & 0xFFuL));
3915 
3916          if ((err = mp_div_2d(&t, (j == ((size - nail_bytes) - 1u)) ? (int)(8u - odd_nails) : 8, &t, NULL)) != MP_OKAY) {
3917             goto LBL_ERR;
3918          }
3919 
3920       }
3921    }
3922 
3923    if (written != NULL) {
3924       *written = count;
3925    }
3926    err = MP_OKAY;
3927 
3928 LBL_ERR:
3929    mp_clear(&t);
3930    return err;
3931 }
3932 
3933 #endif
3934 
3935 /* End: bn_mp_pack.c */
3936 
3937 /* Start: bn_mp_pack_count.c */
3938 #include "tommath_private.h"
3939 #ifdef BN_MP_PACK_COUNT_C
3940 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3941 /* SPDX-License-Identifier: Unlicense */
3942 
mp_pack_count(const mp_int * a,size_t nails,size_t size)3943 size_t mp_pack_count(const mp_int *a, size_t nails, size_t size)
3944 {
3945    size_t bits = (size_t)mp_count_bits(a);
3946    return ((bits / ((size * 8u) - nails)) + (((bits % ((size * 8u) - nails)) != 0u) ? 1u : 0u));
3947 }
3948 
3949 #endif
3950 
3951 /* End: bn_mp_pack_count.c */
3952 
3953 /* Start: bn_mp_prime_fermat.c */
3954 #include "tommath_private.h"
3955 #ifdef BN_MP_PRIME_FERMAT_C
3956 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3957 /* SPDX-License-Identifier: Unlicense */
3958 
3959 /* performs one Fermat test.
3960  *
3961  * If "a" were prime then b**a == b (mod a) since the order of
3962  * the multiplicative sub-group would be phi(a) = a-1.  That means
3963  * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a).
3964  *
3965  * Sets result to 1 if the congruence holds, or zero otherwise.
3966  */
mp_prime_fermat(const mp_int * a,const mp_int * b,mp_bool * result)3967 mp_err mp_prime_fermat(const mp_int *a, const mp_int *b, mp_bool *result)
3968 {
3969    mp_int  t;
3970    mp_err  err;
3971 
3972    /* default to composite  */
3973    *result = MP_NO;
3974 
3975    /* ensure b > 1 */
3976    if (mp_cmp_d(b, 1uL) != MP_GT) {
3977       return MP_VAL;
3978    }
3979 
3980    /* init t */
3981    if ((err = mp_init(&t)) != MP_OKAY) {
3982       return err;
3983    }
3984 
3985    /* compute t = b**a mod a */
3986    if ((err = mp_exptmod(b, a, a, &t)) != MP_OKAY) {
3987       goto LBL_T;
3988    }
3989 
3990    /* is it equal to b? */
3991    if (mp_cmp(&t, b) == MP_EQ) {
3992       *result = MP_YES;
3993    }
3994 
3995    err = MP_OKAY;
3996 LBL_T:
3997    mp_clear(&t);
3998    return err;
3999 }
4000 #endif
4001 
4002 /* End: bn_mp_prime_fermat.c */
4003 
4004 /* Start: bn_mp_prime_frobenius_underwood.c */
4005 #include "tommath_private.h"
4006 #ifdef BN_MP_PRIME_FROBENIUS_UNDERWOOD_C
4007 
4008 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4009 /* SPDX-License-Identifier: Unlicense */
4010 
4011 /*
4012  *  See file bn_mp_prime_is_prime.c or the documentation in doc/bn.tex for the details
4013  */
4014 #ifndef LTM_USE_ONLY_MR
4015 
4016 #ifdef MP_8BIT
4017 /*
4018  * floor of positive solution of
4019  * (2^16)-1 = (a+4)*(2*a+5)
4020  * TODO: Both values are smaller than N^(1/4), would have to use a bigint
4021  *       for a instead but any a biger than about 120 are already so rare that
4022  *       it is possible to ignore them and still get enough pseudoprimes.
4023  *       But it is still a restriction of the set of available pseudoprimes
4024  *       which makes this implementation less secure if used stand-alone.
4025  */
4026 #define LTM_FROBENIUS_UNDERWOOD_A 177
4027 #else
4028 #define LTM_FROBENIUS_UNDERWOOD_A 32764
4029 #endif
mp_prime_frobenius_underwood(const mp_int * N,mp_bool * result)4030 mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result)
4031 {
4032    mp_int T1z, T2z, Np1z, sz, tz;
4033 
4034    int a, ap2, length, i, j;
4035    mp_err err;
4036 
4037    *result = MP_NO;
4038 
4039    if ((err = mp_init_multi(&T1z, &T2z, &Np1z, &sz, &tz, NULL)) != MP_OKAY) {
4040       return err;
4041    }
4042 
4043    for (a = 0; a < LTM_FROBENIUS_UNDERWOOD_A; a++) {
4044       /* TODO: That's ugly! No, really, it is! */
4045       if ((a==2) || (a==4) || (a==7) || (a==8) || (a==10) ||
4046           (a==14) || (a==18) || (a==23) || (a==26) || (a==28)) {
4047          continue;
4048       }
4049       /* (32764^2 - 4) < 2^31, no bigint for >MP_8BIT needed) */
4050       mp_set_u32(&T1z, (uint32_t)a);
4051 
4052       if ((err = mp_sqr(&T1z, &T1z)) != MP_OKAY)                  goto LBL_FU_ERR;
4053 
4054       if ((err = mp_sub_d(&T1z, 4uL, &T1z)) != MP_OKAY)           goto LBL_FU_ERR;
4055 
4056       if ((err = mp_kronecker(&T1z, N, &j)) != MP_OKAY)           goto LBL_FU_ERR;
4057 
4058       if (j == -1) {
4059          break;
4060       }
4061 
4062       if (j == 0) {
4063          /* composite */
4064          goto LBL_FU_ERR;
4065       }
4066    }
4067    /* Tell it a composite and set return value accordingly */
4068    if (a >= LTM_FROBENIUS_UNDERWOOD_A) {
4069       err = MP_ITER;
4070       goto LBL_FU_ERR;
4071    }
4072    /* Composite if N and (a+4)*(2*a+5) are not coprime */
4073    mp_set_u32(&T1z, (uint32_t)((a+4)*((2*a)+5)));
4074 
4075    if ((err = mp_gcd(N, &T1z, &T1z)) != MP_OKAY)                  goto LBL_FU_ERR;
4076 
4077    if (!((T1z.used == 1) && (T1z.dp[0] == 1u)))                   goto LBL_FU_ERR;
4078 
4079    ap2 = a + 2;
4080    if ((err = mp_add_d(N, 1uL, &Np1z)) != MP_OKAY)                goto LBL_FU_ERR;
4081 
4082    mp_set(&sz, 1uL);
4083    mp_set(&tz, 2uL);
4084    length = mp_count_bits(&Np1z);
4085 
4086    for (i = length - 2; i >= 0; i--) {
4087       /*
4088        * temp = (sz*(a*sz+2*tz))%N;
4089        * tz   = ((tz-sz)*(tz+sz))%N;
4090        * sz   = temp;
4091        */
4092       if ((err = mp_mul_2(&tz, &T2z)) != MP_OKAY)                 goto LBL_FU_ERR;
4093 
4094       /* a = 0 at about 50% of the cases (non-square and odd input) */
4095       if (a != 0) {
4096          if ((err = mp_mul_d(&sz, (mp_digit)a, &T1z)) != MP_OKAY) goto LBL_FU_ERR;
4097          if ((err = mp_add(&T1z, &T2z, &T2z)) != MP_OKAY)         goto LBL_FU_ERR;
4098       }
4099 
4100       if ((err = mp_mul(&T2z, &sz, &T1z)) != MP_OKAY)             goto LBL_FU_ERR;
4101       if ((err = mp_sub(&tz, &sz, &T2z)) != MP_OKAY)              goto LBL_FU_ERR;
4102       if ((err = mp_add(&sz, &tz, &sz)) != MP_OKAY)               goto LBL_FU_ERR;
4103       if ((err = mp_mul(&sz, &T2z, &tz)) != MP_OKAY)              goto LBL_FU_ERR;
4104       if ((err = mp_mod(&tz, N, &tz)) != MP_OKAY)                 goto LBL_FU_ERR;
4105       if ((err = mp_mod(&T1z, N, &sz)) != MP_OKAY)                goto LBL_FU_ERR;
4106       if (s_mp_get_bit(&Np1z, (unsigned int)i) == MP_YES) {
4107          /*
4108           *  temp = (a+2) * sz + tz
4109           *  tz   = 2 * tz - sz
4110           *  sz   = temp
4111           */
4112          if (a == 0) {
4113             if ((err = mp_mul_2(&sz, &T1z)) != MP_OKAY)           goto LBL_FU_ERR;
4114          } else {
4115             if ((err = mp_mul_d(&sz, (mp_digit)ap2, &T1z)) != MP_OKAY) goto LBL_FU_ERR;
4116          }
4117          if ((err = mp_add(&T1z, &tz, &T1z)) != MP_OKAY)          goto LBL_FU_ERR;
4118          if ((err = mp_mul_2(&tz, &T2z)) != MP_OKAY)              goto LBL_FU_ERR;
4119          if ((err = mp_sub(&T2z, &sz, &tz)) != MP_OKAY)           goto LBL_FU_ERR;
4120          mp_exch(&sz, &T1z);
4121       }
4122    }
4123 
4124    mp_set_u32(&T1z, (uint32_t)((2 * a) + 5));
4125    if ((err = mp_mod(&T1z, N, &T1z)) != MP_OKAY)                  goto LBL_FU_ERR;
4126    if (MP_IS_ZERO(&sz) && (mp_cmp(&tz, &T1z) == MP_EQ)) {
4127       *result = MP_YES;
4128    }
4129 
4130 LBL_FU_ERR:
4131    mp_clear_multi(&tz, &sz, &Np1z, &T2z, &T1z, NULL);
4132    return err;
4133 }
4134 
4135 #endif
4136 #endif
4137 
4138 /* End: bn_mp_prime_frobenius_underwood.c */
4139 
4140 /* Start: bn_mp_prime_is_prime.c */
4141 #include "tommath_private.h"
4142 #ifdef BN_MP_PRIME_IS_PRIME_C
4143 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4144 /* SPDX-License-Identifier: Unlicense */
4145 
4146 /* portable integer log of two with small footprint */
s_floor_ilog2(int value)4147 static unsigned int s_floor_ilog2(int value)
4148 {
4149    unsigned int r = 0;
4150    while ((value >>= 1) != 0) {
4151       r++;
4152    }
4153    return r;
4154 }
4155 
4156 
mp_prime_is_prime(const mp_int * a,int t,mp_bool * result)4157 mp_err mp_prime_is_prime(const mp_int *a, int t, mp_bool *result)
4158 {
4159    mp_int  b;
4160    int     ix, p_max = 0, size_a, len;
4161    mp_bool res;
4162    mp_err  err;
4163    unsigned int fips_rand, mask;
4164 
4165    /* default to no */
4166    *result = MP_NO;
4167 
4168    /* Some shortcuts */
4169    /* N > 3 */
4170    if (a->used == 1) {
4171       if ((a->dp[0] == 0u) || (a->dp[0] == 1u)) {
4172          *result = MP_NO;
4173          return MP_OKAY;
4174       }
4175       if (a->dp[0] == 2u) {
4176          *result = MP_YES;
4177          return MP_OKAY;
4178       }
4179    }
4180 
4181    /* N must be odd */
4182    if (MP_IS_EVEN(a)) {
4183       return MP_OKAY;
4184    }
4185    /* N is not a perfect square: floor(sqrt(N))^2 != N */
4186    if ((err = mp_is_square(a, &res)) != MP_OKAY) {
4187       return err;
4188    }
4189    if (res != MP_NO) {
4190       return MP_OKAY;
4191    }
4192 
4193    /* is the input equal to one of the primes in the table? */
4194    for (ix = 0; ix < PRIVATE_MP_PRIME_TAB_SIZE; ix++) {
4195       if (mp_cmp_d(a, s_mp_prime_tab[ix]) == MP_EQ) {
4196          *result = MP_YES;
4197          return MP_OKAY;
4198       }
4199    }
4200 #ifdef MP_8BIT
4201    /* The search in the loop above was exhaustive in this case */
4202    if ((a->used == 1) && (PRIVATE_MP_PRIME_TAB_SIZE >= 31)) {
4203       return MP_OKAY;
4204    }
4205 #endif
4206 
4207    /* first perform trial division */
4208    if ((err = s_mp_prime_is_divisible(a, &res)) != MP_OKAY) {
4209       return err;
4210    }
4211 
4212    /* return if it was trivially divisible */
4213    if (res == MP_YES) {
4214       return MP_OKAY;
4215    }
4216 
4217    /*
4218        Run the Miller-Rabin test with base 2 for the BPSW test.
4219     */
4220    if ((err = mp_init_set(&b, 2uL)) != MP_OKAY) {
4221       return err;
4222    }
4223 
4224    if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
4225       goto LBL_B;
4226    }
4227    if (res == MP_NO) {
4228       goto LBL_B;
4229    }
4230    /*
4231       Rumours have it that Mathematica does a second M-R test with base 3.
4232       Other rumours have it that their strong L-S test is slightly different.
4233       It does not hurt, though, beside a bit of extra runtime.
4234    */
4235    b.dp[0]++;
4236    if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
4237       goto LBL_B;
4238    }
4239    if (res == MP_NO) {
4240       goto LBL_B;
4241    }
4242 
4243    /*
4244     * Both, the Frobenius-Underwood test and the the Lucas-Selfridge test are quite
4245     * slow so if speed is an issue, define LTM_USE_ONLY_MR to use M-R tests with
4246     * bases 2, 3 and t random bases.
4247     */
4248 #ifndef LTM_USE_ONLY_MR
4249    if (t >= 0) {
4250       /*
4251        * Use a Frobenius-Underwood test instead of the Lucas-Selfridge test for
4252        * MP_8BIT (It is unknown if the Lucas-Selfridge test works with 16-bit
4253        * integers but the necesssary analysis is on the todo-list).
4254        */
4255 #if defined (MP_8BIT) || defined (LTM_USE_FROBENIUS_TEST)
4256       err = mp_prime_frobenius_underwood(a, &res);
4257       if ((err != MP_OKAY) && (err != MP_ITER)) {
4258          goto LBL_B;
4259       }
4260       if (res == MP_NO) {
4261          goto LBL_B;
4262       }
4263 #else
4264       if ((err = mp_prime_strong_lucas_selfridge(a, &res)) != MP_OKAY) {
4265          goto LBL_B;
4266       }
4267       if (res == MP_NO) {
4268          goto LBL_B;
4269       }
4270 #endif
4271    }
4272 #endif
4273 
4274    /* run at least one Miller-Rabin test with a random base */
4275    if (t == 0) {
4276       t = 1;
4277    }
4278 
4279    /*
4280       Only recommended if the input range is known to be < 3317044064679887385961981
4281 
4282       It uses the bases necessary for a deterministic M-R test if the input is
4283       smaller than  3317044064679887385961981
4284       The caller has to check the size.
4285       TODO: can be made a bit finer grained but comparing is not free.
4286    */
4287    if (t < 0) {
4288       /*
4289           Sorenson, Jonathan; Webster, Jonathan (2015).
4290            "Strong Pseudoprimes to Twelve Prime Bases".
4291        */
4292       /* 0x437ae92817f9fc85b7e5 = 318665857834031151167461 */
4293       if ((err =   mp_read_radix(&b, "437ae92817f9fc85b7e5", 16)) != MP_OKAY) {
4294          goto LBL_B;
4295       }
4296 
4297       if (mp_cmp(a, &b) == MP_LT) {
4298          p_max = 12;
4299       } else {
4300          /* 0x2be6951adc5b22410a5fd = 3317044064679887385961981 */
4301          if ((err = mp_read_radix(&b, "2be6951adc5b22410a5fd", 16)) != MP_OKAY) {
4302             goto LBL_B;
4303          }
4304 
4305          if (mp_cmp(a, &b) == MP_LT) {
4306             p_max = 13;
4307          } else {
4308             err = MP_VAL;
4309             goto LBL_B;
4310          }
4311       }
4312 
4313       /* we did bases 2 and 3  already, skip them */
4314       for (ix = 2; ix < p_max; ix++) {
4315          mp_set(&b, s_mp_prime_tab[ix]);
4316          if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
4317             goto LBL_B;
4318          }
4319          if (res == MP_NO) {
4320             goto LBL_B;
4321          }
4322       }
4323    }
4324    /*
4325        Do "t" M-R tests with random bases between 3 and "a".
4326        See Fips 186.4 p. 126ff
4327    */
4328    else if (t > 0) {
4329       /*
4330        * The mp_digit's have a defined bit-size but the size of the
4331        * array a.dp is a simple 'int' and this library can not assume full
4332        * compliance to the current C-standard (ISO/IEC 9899:2011) because
4333        * it gets used for small embeded processors, too. Some of those MCUs
4334        * have compilers that one cannot call standard compliant by any means.
4335        * Hence the ugly type-fiddling in the following code.
4336        */
4337       size_a = mp_count_bits(a);
4338       mask = (1u << s_floor_ilog2(size_a)) - 1u;
4339       /*
4340          Assuming the General Rieman hypothesis (never thought to write that in a
4341          comment) the upper bound can be lowered to  2*(log a)^2.
4342          E. Bach, "Explicit bounds for primality testing and related problems,"
4343          Math. Comp. 55 (1990), 355-380.
4344 
4345             size_a = (size_a/10) * 7;
4346             len = 2 * (size_a * size_a);
4347 
4348          E.g.: a number of size 2^2048 would be reduced to the upper limit
4349 
4350             floor(2048/10)*7 = 1428
4351             2 * 1428^2       = 4078368
4352 
4353          (would have been ~4030331.9962 with floats and natural log instead)
4354          That number is smaller than 2^28, the default bit-size of mp_digit.
4355       */
4356 
4357       /*
4358         How many tests, you might ask? Dana Jacobsen of Math::Prime::Util fame
4359         does exactly 1. In words: one. Look at the end of _GMP_is_prime() in
4360         Math-Prime-Util-GMP-0.50/primality.c if you do not believe it.
4361 
4362         The function mp_rand() goes to some length to use a cryptographically
4363         good PRNG. That also means that the chance to always get the same base
4364         in the loop is non-zero, although very low.
4365         If the BPSW test and/or the addtional Frobenious test have been
4366         performed instead of just the Miller-Rabin test with the bases 2 and 3,
4367         a single extra test should suffice, so such a very unlikely event
4368         will not do much harm.
4369 
4370         To preemptivly answer the dangling question: no, a witness does not
4371         need to be prime.
4372       */
4373       for (ix = 0; ix < t; ix++) {
4374          /* mp_rand() guarantees the first digit to be non-zero */
4375          if ((err = mp_rand(&b, 1)) != MP_OKAY) {
4376             goto LBL_B;
4377          }
4378          /*
4379           * Reduce digit before casting because mp_digit might be bigger than
4380           * an unsigned int and "mask" on the other side is most probably not.
4381           */
4382          fips_rand = (unsigned int)(b.dp[0] & (mp_digit) mask);
4383 #ifdef MP_8BIT
4384          /*
4385           * One 8-bit digit is too small, so concatenate two if the size of
4386           * unsigned int allows for it.
4387           */
4388          if ((MP_SIZEOF_BITS(unsigned int)/2) >= MP_SIZEOF_BITS(mp_digit)) {
4389             if ((err = mp_rand(&b, 1)) != MP_OKAY) {
4390                goto LBL_B;
4391             }
4392             fips_rand <<= MP_SIZEOF_BITS(mp_digit);
4393             fips_rand |= (unsigned int) b.dp[0];
4394             fips_rand &= mask;
4395          }
4396 #endif
4397          if (fips_rand > (unsigned int)(INT_MAX - MP_DIGIT_BIT)) {
4398             len = INT_MAX / MP_DIGIT_BIT;
4399          } else {
4400             len = (((int)fips_rand + MP_DIGIT_BIT) / MP_DIGIT_BIT);
4401          }
4402          /*  Unlikely. */
4403          if (len < 0) {
4404             ix--;
4405             continue;
4406          }
4407          /*
4408           * As mentioned above, one 8-bit digit is too small and
4409           * although it can only happen in the unlikely case that
4410           * an "unsigned int" is smaller than 16 bit a simple test
4411           * is cheap and the correction even cheaper.
4412           */
4413 #ifdef MP_8BIT
4414          /* All "a" < 2^8 have been caught before */
4415          if (len == 1) {
4416             len++;
4417          }
4418 #endif
4419          if ((err = mp_rand(&b, len)) != MP_OKAY) {
4420             goto LBL_B;
4421          }
4422          /*
4423           * That number might got too big and the witness has to be
4424           * smaller than "a"
4425           */
4426          len = mp_count_bits(&b);
4427          if (len >= size_a) {
4428             len = (len - size_a) + 1;
4429             if ((err = mp_div_2d(&b, len, &b, NULL)) != MP_OKAY) {
4430                goto LBL_B;
4431             }
4432          }
4433          /* Although the chance for b <= 3 is miniscule, try again. */
4434          if (mp_cmp_d(&b, 3uL) != MP_GT) {
4435             ix--;
4436             continue;
4437          }
4438          if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
4439             goto LBL_B;
4440          }
4441          if (res == MP_NO) {
4442             goto LBL_B;
4443          }
4444       }
4445    }
4446 
4447    /* passed the test */
4448    *result = MP_YES;
4449 LBL_B:
4450    mp_clear(&b);
4451    return err;
4452 }
4453 
4454 #endif
4455 
4456 /* End: bn_mp_prime_is_prime.c */
4457 
4458 /* Start: bn_mp_prime_miller_rabin.c */
4459 #include "tommath_private.h"
4460 #ifdef BN_MP_PRIME_MILLER_RABIN_C
4461 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4462 /* SPDX-License-Identifier: Unlicense */
4463 
4464 /* Miller-Rabin test of "a" to the base of "b" as described in
4465  * HAC pp. 139 Algorithm 4.24
4466  *
4467  * Sets result to 0 if definitely composite or 1 if probably prime.
4468  * Randomly the chance of error is no more than 1/4 and often
4469  * very much lower.
4470  */
mp_prime_miller_rabin(const mp_int * a,const mp_int * b,mp_bool * result)4471 mp_err mp_prime_miller_rabin(const mp_int *a, const mp_int *b, mp_bool *result)
4472 {
4473    mp_int  n1, y, r;
4474    mp_err  err;
4475    int     s, j;
4476 
4477    /* default */
4478    *result = MP_NO;
4479 
4480    /* ensure b > 1 */
4481    if (mp_cmp_d(b, 1uL) != MP_GT) {
4482       return MP_VAL;
4483    }
4484 
4485    /* get n1 = a - 1 */
4486    if ((err = mp_init_copy(&n1, a)) != MP_OKAY) {
4487       return err;
4488    }
4489    if ((err = mp_sub_d(&n1, 1uL, &n1)) != MP_OKAY) {
4490       goto LBL_N1;
4491    }
4492 
4493    /* set 2**s * r = n1 */
4494    if ((err = mp_init_copy(&r, &n1)) != MP_OKAY) {
4495       goto LBL_N1;
4496    }
4497 
4498    /* count the number of least significant bits
4499     * which are zero
4500     */
4501    s = mp_cnt_lsb(&r);
4502 
4503    /* now divide n - 1 by 2**s */
4504    if ((err = mp_div_2d(&r, s, &r, NULL)) != MP_OKAY) {
4505       goto LBL_R;
4506    }
4507 
4508    /* compute y = b**r mod a */
4509    if ((err = mp_init(&y)) != MP_OKAY) {
4510       goto LBL_R;
4511    }
4512    if ((err = mp_exptmod(b, &r, a, &y)) != MP_OKAY) {
4513       goto LBL_Y;
4514    }
4515 
4516    /* if y != 1 and y != n1 do */
4517    if ((mp_cmp_d(&y, 1uL) != MP_EQ) && (mp_cmp(&y, &n1) != MP_EQ)) {
4518       j = 1;
4519       /* while j <= s-1 and y != n1 */
4520       while ((j <= (s - 1)) && (mp_cmp(&y, &n1) != MP_EQ)) {
4521          if ((err = mp_sqrmod(&y, a, &y)) != MP_OKAY) {
4522             goto LBL_Y;
4523          }
4524 
4525          /* if y == 1 then composite */
4526          if (mp_cmp_d(&y, 1uL) == MP_EQ) {
4527             goto LBL_Y;
4528          }
4529 
4530          ++j;
4531       }
4532 
4533       /* if y != n1 then composite */
4534       if (mp_cmp(&y, &n1) != MP_EQ) {
4535          goto LBL_Y;
4536       }
4537    }
4538 
4539    /* probably prime now */
4540    *result = MP_YES;
4541 LBL_Y:
4542    mp_clear(&y);
4543 LBL_R:
4544    mp_clear(&r);
4545 LBL_N1:
4546    mp_clear(&n1);
4547    return err;
4548 }
4549 #endif
4550 
4551 /* End: bn_mp_prime_miller_rabin.c */
4552 
4553 /* Start: bn_mp_prime_next_prime.c */
4554 #include "tommath_private.h"
4555 #ifdef BN_MP_PRIME_NEXT_PRIME_C
4556 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4557 /* SPDX-License-Identifier: Unlicense */
4558 
4559 /* finds the next prime after the number "a" using "t" trials
4560  * of Miller-Rabin.
4561  *
4562  * bbs_style = 1 means the prime must be congruent to 3 mod 4
4563  */
mp_prime_next_prime(mp_int * a,int t,int bbs_style)4564 mp_err mp_prime_next_prime(mp_int *a, int t, int bbs_style)
4565 {
4566    int      x, y;
4567    mp_ord   cmp;
4568    mp_err   err;
4569    mp_bool  res = MP_NO;
4570    mp_digit res_tab[PRIVATE_MP_PRIME_TAB_SIZE], step, kstep;
4571    mp_int   b;
4572 
4573    /* force positive */
4574    a->sign = MP_ZPOS;
4575 
4576    /* simple algo if a is less than the largest prime in the table */
4577    if (mp_cmp_d(a, s_mp_prime_tab[PRIVATE_MP_PRIME_TAB_SIZE-1]) == MP_LT) {
4578       /* find which prime it is bigger than "a" */
4579       for (x = 0; x < PRIVATE_MP_PRIME_TAB_SIZE; x++) {
4580          cmp = mp_cmp_d(a, s_mp_prime_tab[x]);
4581          if (cmp == MP_EQ) {
4582             continue;
4583          }
4584          if (cmp != MP_GT) {
4585             if ((bbs_style == 1) && ((s_mp_prime_tab[x] & 3u) != 3u)) {
4586                /* try again until we get a prime congruent to 3 mod 4 */
4587                continue;
4588             } else {
4589                mp_set(a, s_mp_prime_tab[x]);
4590                return MP_OKAY;
4591             }
4592          }
4593       }
4594       /* fall through to the sieve */
4595    }
4596 
4597    /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */
4598    if (bbs_style == 1) {
4599       kstep   = 4;
4600    } else {
4601       kstep   = 2;
4602    }
4603 
4604    /* at this point we will use a combination of a sieve and Miller-Rabin */
4605 
4606    if (bbs_style == 1) {
4607       /* if a mod 4 != 3 subtract the correct value to make it so */
4608       if ((a->dp[0] & 3u) != 3u) {
4609          if ((err = mp_sub_d(a, (a->dp[0] & 3u) + 1u, a)) != MP_OKAY) {
4610             return err;
4611          }
4612       }
4613    } else {
4614       if (MP_IS_EVEN(a)) {
4615          /* force odd */
4616          if ((err = mp_sub_d(a, 1uL, a)) != MP_OKAY) {
4617             return err;
4618          }
4619       }
4620    }
4621 
4622    /* generate the restable */
4623    for (x = 1; x < PRIVATE_MP_PRIME_TAB_SIZE; x++) {
4624       if ((err = mp_mod_d(a, s_mp_prime_tab[x], res_tab + x)) != MP_OKAY) {
4625          return err;
4626       }
4627    }
4628 
4629    /* init temp used for Miller-Rabin Testing */
4630    if ((err = mp_init(&b)) != MP_OKAY) {
4631       return err;
4632    }
4633 
4634    for (;;) {
4635       /* skip to the next non-trivially divisible candidate */
4636       step = 0;
4637       do {
4638          /* y == 1 if any residue was zero [e.g. cannot be prime] */
4639          y     =  0;
4640 
4641          /* increase step to next candidate */
4642          step += kstep;
4643 
4644          /* compute the new residue without using division */
4645          for (x = 1; x < PRIVATE_MP_PRIME_TAB_SIZE; x++) {
4646             /* add the step to each residue */
4647             res_tab[x] += kstep;
4648 
4649             /* subtract the modulus [instead of using division] */
4650             if (res_tab[x] >= s_mp_prime_tab[x]) {
4651                res_tab[x]  -= s_mp_prime_tab[x];
4652             }
4653 
4654             /* set flag if zero */
4655             if (res_tab[x] == 0u) {
4656                y = 1;
4657             }
4658          }
4659       } while ((y == 1) && (step < (((mp_digit)1 << MP_DIGIT_BIT) - kstep)));
4660 
4661       /* add the step */
4662       if ((err = mp_add_d(a, step, a)) != MP_OKAY) {
4663          goto LBL_ERR;
4664       }
4665 
4666       /* if didn't pass sieve and step == MP_MAX then skip test */
4667       if ((y == 1) && (step >= (((mp_digit)1 << MP_DIGIT_BIT) - kstep))) {
4668          continue;
4669       }
4670 
4671       if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) {
4672          goto LBL_ERR;
4673       }
4674       if (res == MP_YES) {
4675          break;
4676       }
4677    }
4678 
4679    err = MP_OKAY;
4680 LBL_ERR:
4681    mp_clear(&b);
4682    return err;
4683 }
4684 
4685 #endif
4686 
4687 /* End: bn_mp_prime_next_prime.c */
4688 
4689 /* Start: bn_mp_prime_rabin_miller_trials.c */
4690 #include "tommath_private.h"
4691 #ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C
4692 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4693 /* SPDX-License-Identifier: Unlicense */
4694 
4695 static const struct {
4696    int k, t;
4697 } sizes[] = {
4698    {    80, -1 }, /* Use deterministic algorithm for size <= 80 bits */
4699    {    81, 37 }, /* max. error = 2^(-96)*/
4700    {    96, 32 }, /* max. error = 2^(-96)*/
4701    {   128, 40 }, /* max. error = 2^(-112)*/
4702    {   160, 35 }, /* max. error = 2^(-112)*/
4703    {   256, 27 }, /* max. error = 2^(-128)*/
4704    {   384, 16 }, /* max. error = 2^(-128)*/
4705    {   512, 18 }, /* max. error = 2^(-160)*/
4706    {   768, 11 }, /* max. error = 2^(-160)*/
4707    {   896, 10 }, /* max. error = 2^(-160)*/
4708    {  1024, 12 }, /* max. error = 2^(-192)*/
4709    {  1536, 8  }, /* max. error = 2^(-192)*/
4710    {  2048, 6  }, /* max. error = 2^(-192)*/
4711    {  3072, 4  }, /* max. error = 2^(-192)*/
4712    {  4096, 5  }, /* max. error = 2^(-256)*/
4713    {  5120, 4  }, /* max. error = 2^(-256)*/
4714    {  6144, 4  }, /* max. error = 2^(-256)*/
4715    {  8192, 3  }, /* max. error = 2^(-256)*/
4716    {  9216, 3  }, /* max. error = 2^(-256)*/
4717    { 10240, 2  }  /* For bigger keysizes use always at least 2 Rounds */
4718 };
4719 
4720 /* returns # of RM trials required for a given bit size */
mp_prime_rabin_miller_trials(int size)4721 int mp_prime_rabin_miller_trials(int size)
4722 {
4723    int x;
4724 
4725    for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) {
4726       if (sizes[x].k == size) {
4727          return sizes[x].t;
4728       } else if (sizes[x].k > size) {
4729          return (x == 0) ? sizes[0].t : sizes[x - 1].t;
4730       }
4731    }
4732    return sizes[x-1].t;
4733 }
4734 
4735 
4736 #endif
4737 
4738 /* End: bn_mp_prime_rabin_miller_trials.c */
4739 
4740 /* Start: bn_mp_prime_rand.c */
4741 #include "tommath_private.h"
4742 #ifdef BN_MP_PRIME_RAND_C
4743 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4744 /* SPDX-License-Identifier: Unlicense */
4745 
4746 /* makes a truly random prime of a given size (bits),
4747  *
4748  * Flags are as follows:
4749  *
4750  *   MP_PRIME_BBS      - make prime congruent to 3 mod 4
4751  *   MP_PRIME_SAFE     - make sure (p-1)/2 is prime as well (implies MP_PRIME_BBS)
4752  *   MP_PRIME_2MSB_ON  - make the 2nd highest bit one
4753  *
4754  * You have to supply a callback which fills in a buffer with random bytes.  "dat" is a parameter you can
4755  * have passed to the callback (e.g. a state or something).  This function doesn't use "dat" itself
4756  * so it can be NULL
4757  *
4758  */
4759 
4760 /* This is possibly the mother of all prime generation functions, muahahahahaha! */
s_mp_prime_random_ex(mp_int * a,int t,int size,int flags,private_mp_prime_callback cb,void * dat)4761 mp_err s_mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_prime_callback cb, void *dat)
4762 {
4763    unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb;
4764    int bsize, maskOR_msb_offset;
4765    mp_bool res;
4766    mp_err err;
4767 
4768    /* sanity check the input */
4769    if ((size <= 1) || (t <= 0)) {
4770       return MP_VAL;
4771    }
4772 
4773    /* MP_PRIME_SAFE implies MP_PRIME_BBS */
4774    if ((flags & MP_PRIME_SAFE) != 0) {
4775       flags |= MP_PRIME_BBS;
4776    }
4777 
4778    /* calc the byte size */
4779    bsize = (size>>3) + ((size&7)?1:0);
4780 
4781    /* we need a buffer of bsize bytes */
4782    tmp = (unsigned char *) MP_MALLOC((size_t)bsize);
4783    if (tmp == NULL) {
4784       return MP_MEM;
4785    }
4786 
4787    /* calc the maskAND value for the MSbyte*/
4788    maskAND = ((size&7) == 0) ? 0xFFu : (unsigned char)(0xFFu >> (8 - (size & 7)));
4789 
4790    /* calc the maskOR_msb */
4791    maskOR_msb        = 0;
4792    maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0;
4793    if ((flags & MP_PRIME_2MSB_ON) != 0) {
4794       maskOR_msb       |= (unsigned char)(0x80 >> ((9 - size) & 7));
4795    }
4796 
4797    /* get the maskOR_lsb */
4798    maskOR_lsb         = 1u;
4799    if ((flags & MP_PRIME_BBS) != 0) {
4800       maskOR_lsb     |= 3u;
4801    }
4802 
4803    do {
4804       /* read the bytes */
4805       if (cb(tmp, bsize, dat) != bsize) {
4806          err = MP_VAL;
4807          goto error;
4808       }
4809 
4810       /* work over the MSbyte */
4811       tmp[0]    &= maskAND;
4812       tmp[0]    |= (unsigned char)(1 << ((size - 1) & 7));
4813 
4814       /* mix in the maskORs */
4815       tmp[maskOR_msb_offset]   |= maskOR_msb;
4816       tmp[bsize-1]             |= maskOR_lsb;
4817 
4818       /* read it in */
4819       /* TODO: casting only for now until all lengths have been changed to the type "size_t"*/
4820       if ((err = mp_from_ubin(a, tmp, (size_t)bsize)) != MP_OKAY) {
4821          goto error;
4822       }
4823 
4824       /* is it prime? */
4825       if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) {
4826          goto error;
4827       }
4828       if (res == MP_NO) {
4829          continue;
4830       }
4831 
4832       if ((flags & MP_PRIME_SAFE) != 0) {
4833          /* see if (a-1)/2 is prime */
4834          if ((err = mp_sub_d(a, 1uL, a)) != MP_OKAY) {
4835             goto error;
4836          }
4837          if ((err = mp_div_2(a, a)) != MP_OKAY) {
4838             goto error;
4839          }
4840 
4841          /* is it prime? */
4842          if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) {
4843             goto error;
4844          }
4845       }
4846    } while (res == MP_NO);
4847 
4848    if ((flags & MP_PRIME_SAFE) != 0) {
4849       /* restore a to the original value */
4850       if ((err = mp_mul_2(a, a)) != MP_OKAY) {
4851          goto error;
4852       }
4853       if ((err = mp_add_d(a, 1uL, a)) != MP_OKAY) {
4854          goto error;
4855       }
4856    }
4857 
4858    err = MP_OKAY;
4859 error:
4860    MP_FREE_BUFFER(tmp, (size_t)bsize);
4861    return err;
4862 }
4863 
s_mp_rand_cb(unsigned char * dst,int len,void * dat)4864 static int s_mp_rand_cb(unsigned char *dst, int len, void *dat)
4865 {
4866    (void)dat;
4867    if (len <= 0) {
4868       return len;
4869    }
4870    if (s_mp_rand_source(dst, (size_t)len) != MP_OKAY) {
4871       return 0;
4872    }
4873    return len;
4874 }
4875 
mp_prime_rand(mp_int * a,int t,int size,int flags)4876 mp_err mp_prime_rand(mp_int *a, int t, int size, int flags)
4877 {
4878    return s_mp_prime_random_ex(a, t, size, flags, s_mp_rand_cb, NULL);
4879 }
4880 
4881 #endif
4882 
4883 /* End: bn_mp_prime_rand.c */
4884 
4885 /* Start: bn_mp_prime_strong_lucas_selfridge.c */
4886 #include "tommath_private.h"
4887 #ifdef BN_MP_PRIME_STRONG_LUCAS_SELFRIDGE_C
4888 
4889 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4890 /* SPDX-License-Identifier: Unlicense */
4891 
4892 /*
4893  *  See file bn_mp_prime_is_prime.c or the documentation in doc/bn.tex for the details
4894  */
4895 #ifndef LTM_USE_ONLY_MR
4896 
4897 /*
4898  *  8-bit is just too small. You can try the Frobenius test
4899  *  but that frobenius test can fail, too, for the same reason.
4900  */
4901 #ifndef MP_8BIT
4902 
4903 /*
4904  * multiply bigint a with int d and put the result in c
4905  * Like mp_mul_d() but with a signed long as the small input
4906  */
s_mp_mul_si(const mp_int * a,int32_t d,mp_int * c)4907 static mp_err s_mp_mul_si(const mp_int *a, int32_t d, mp_int *c)
4908 {
4909    mp_int t;
4910    mp_err err;
4911 
4912    if ((err = mp_init(&t)) != MP_OKAY) {
4913       return err;
4914    }
4915 
4916    /*
4917     * mp_digit might be smaller than a long, which excludes
4918     * the use of mp_mul_d() here.
4919     */
4920    mp_set_i32(&t, d);
4921    err = mp_mul(a, &t, c);
4922    mp_clear(&t);
4923    return err;
4924 }
4925 /*
4926     Strong Lucas-Selfridge test.
4927     returns MP_YES if it is a strong L-S prime, MP_NO if it is composite
4928 
4929     Code ported from  Thomas Ray Nicely's implementation of the BPSW test
4930     at http://www.trnicely.net/misc/bpsw.html
4931 
4932     Freeware copyright (C) 2016 Thomas R. Nicely <http://www.trnicely.net>.
4933     Released into the public domain by the author, who disclaims any legal
4934     liability arising from its use
4935 
4936     The multi-line comments are made by Thomas R. Nicely and are copied verbatim.
4937     Additional comments marked "CZ" (without the quotes) are by the code-portist.
4938 
4939     (If that name sounds familiar, he is the guy who found the fdiv bug in the
4940      Pentium (P5x, I think) Intel processor)
4941 */
mp_prime_strong_lucas_selfridge(const mp_int * a,mp_bool * result)4942 mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result)
4943 {
4944    /* CZ TODO: choose better variable names! */
4945    mp_int Dz, gcd, Np1, Uz, Vz, U2mz, V2mz, Qmz, Q2mz, Qkdz, T1z, T2z, T3z, T4z, Q2kdz;
4946    /* CZ TODO: Some of them need the full 32 bit, hence the (temporary) exclusion of MP_8BIT */
4947    int32_t D, Ds, J, sign, P, Q, r, s, u, Nbits;
4948    mp_err err;
4949    mp_bool oddness;
4950 
4951    *result = MP_NO;
4952    /*
4953    Find the first element D in the sequence {5, -7, 9, -11, 13, ...}
4954    such that Jacobi(D,N) = -1 (Selfridge's algorithm). Theory
4955    indicates that, if N is not a perfect square, D will "nearly
4956    always" be "small." Just in case, an overflow trap for D is
4957    included.
4958    */
4959 
4960    if ((err = mp_init_multi(&Dz, &gcd, &Np1, &Uz, &Vz, &U2mz, &V2mz, &Qmz, &Q2mz, &Qkdz, &T1z, &T2z, &T3z, &T4z, &Q2kdz,
4961                             NULL)) != MP_OKAY) {
4962       return err;
4963    }
4964 
4965    D = 5;
4966    sign = 1;
4967 
4968    for (;;) {
4969       Ds   = sign * D;
4970       sign = -sign;
4971       mp_set_u32(&Dz, (uint32_t)D);
4972       if ((err = mp_gcd(a, &Dz, &gcd)) != MP_OKAY)                goto LBL_LS_ERR;
4973 
4974       /* if 1 < GCD < N then N is composite with factor "D", and
4975          Jacobi(D,N) is technically undefined (but often returned
4976          as zero). */
4977       if ((mp_cmp_d(&gcd, 1uL) == MP_GT) && (mp_cmp(&gcd, a) == MP_LT)) {
4978          goto LBL_LS_ERR;
4979       }
4980       if (Ds < 0) {
4981          Dz.sign = MP_NEG;
4982       }
4983       if ((err = mp_kronecker(&Dz, a, &J)) != MP_OKAY)            goto LBL_LS_ERR;
4984 
4985       if (J == -1) {
4986          break;
4987       }
4988       D += 2;
4989 
4990       if (D > (INT_MAX - 2)) {
4991          err = MP_VAL;
4992          goto LBL_LS_ERR;
4993       }
4994    }
4995 
4996 
4997 
4998    P = 1;              /* Selfridge's choice */
4999    Q = (1 - Ds) / 4;   /* Required so D = P*P - 4*Q */
5000 
5001    /* NOTE: The conditions (a) N does not divide Q, and
5002       (b) D is square-free or not a perfect square, are included by
5003       some authors; e.g., "Prime numbers and computer methods for
5004       factorization," Hans Riesel (2nd ed., 1994, Birkhauser, Boston),
5005       p. 130. For this particular application of Lucas sequences,
5006       these conditions were found to be immaterial. */
5007 
5008    /* Now calculate N - Jacobi(D,N) = N + 1 (even), and calculate the
5009       odd positive integer d and positive integer s for which
5010       N + 1 = 2^s*d (similar to the step for N - 1 in Miller's test).
5011       The strong Lucas-Selfridge test then returns N as a strong
5012       Lucas probable prime (slprp) if any of the following
5013       conditions is met: U_d=0, V_d=0, V_2d=0, V_4d=0, V_8d=0,
5014       V_16d=0, ..., etc., ending with V_{2^(s-1)*d}=V_{(N+1)/2}=0
5015       (all equalities mod N). Thus d is the highest index of U that
5016       must be computed (since V_2m is independent of U), compared
5017       to U_{N+1} for the standard Lucas-Selfridge test; and no
5018       index of V beyond (N+1)/2 is required, just as in the
5019       standard Lucas-Selfridge test. However, the quantity Q^d must
5020       be computed for use (if necessary) in the latter stages of
5021       the test. The result is that the strong Lucas-Selfridge test
5022       has a running time only slightly greater (order of 10 %) than
5023       that of the standard Lucas-Selfridge test, while producing
5024       only (roughly) 30 % as many pseudoprimes (and every strong
5025       Lucas pseudoprime is also a standard Lucas pseudoprime). Thus
5026       the evidence indicates that the strong Lucas-Selfridge test is
5027       more effective than the standard Lucas-Selfridge test, and a
5028       Baillie-PSW test based on the strong Lucas-Selfridge test
5029       should be more reliable. */
5030 
5031    if ((err = mp_add_d(a, 1uL, &Np1)) != MP_OKAY)                 goto LBL_LS_ERR;
5032    s = mp_cnt_lsb(&Np1);
5033 
5034    /* CZ
5035     * This should round towards zero because
5036     * Thomas R. Nicely used GMP's mpz_tdiv_q_2exp()
5037     * and mp_div_2d() is equivalent. Additionally:
5038     * dividing an even number by two does not produce
5039     * any leftovers.
5040     */
5041    if ((err = mp_div_2d(&Np1, s, &Dz, NULL)) != MP_OKAY)          goto LBL_LS_ERR;
5042    /* We must now compute U_d and V_d. Since d is odd, the accumulated
5043       values U and V are initialized to U_1 and V_1 (if the target
5044       index were even, U and V would be initialized instead to U_0=0
5045       and V_0=2). The values of U_2m and V_2m are also initialized to
5046       U_1 and V_1; the FOR loop calculates in succession U_2 and V_2,
5047       U_4 and V_4, U_8 and V_8, etc. If the corresponding bits
5048       (1, 2, 3, ...) of t are on (the zero bit having been accounted
5049       for in the initialization of U and V), these values are then
5050       combined with the previous totals for U and V, using the
5051       composition formulas for addition of indices. */
5052 
5053    mp_set(&Uz, 1uL);    /* U=U_1 */
5054    mp_set(&Vz, (mp_digit)P);    /* V=V_1 */
5055    mp_set(&U2mz, 1uL);  /* U_1 */
5056    mp_set(&V2mz, (mp_digit)P);  /* V_1 */
5057 
5058    mp_set_i32(&Qmz, Q);
5059    if ((err = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY)                  goto LBL_LS_ERR;
5060    /* Initializes calculation of Q^d */
5061    mp_set_i32(&Qkdz, Q);
5062 
5063    Nbits = mp_count_bits(&Dz);
5064 
5065    for (u = 1; u < Nbits; u++) { /* zero bit off, already accounted for */
5066       /* Formulas for doubling of indices (carried out mod N). Note that
5067        * the indices denoted as "2m" are actually powers of 2, specifically
5068        * 2^(ul-1) beginning each loop and 2^ul ending each loop.
5069        *
5070        * U_2m = U_m*V_m
5071        * V_2m = V_m*V_m - 2*Q^m
5072        */
5073 
5074       if ((err = mp_mul(&U2mz, &V2mz, &U2mz)) != MP_OKAY)         goto LBL_LS_ERR;
5075       if ((err = mp_mod(&U2mz, a, &U2mz)) != MP_OKAY)             goto LBL_LS_ERR;
5076       if ((err = mp_sqr(&V2mz, &V2mz)) != MP_OKAY)                goto LBL_LS_ERR;
5077       if ((err = mp_sub(&V2mz, &Q2mz, &V2mz)) != MP_OKAY)         goto LBL_LS_ERR;
5078       if ((err = mp_mod(&V2mz, a, &V2mz)) != MP_OKAY)             goto LBL_LS_ERR;
5079 
5080       /* Must calculate powers of Q for use in V_2m, also for Q^d later */
5081       if ((err = mp_sqr(&Qmz, &Qmz)) != MP_OKAY)                  goto LBL_LS_ERR;
5082 
5083       /* prevents overflow */ /* CZ  still necessary without a fixed prealloc'd mem.? */
5084       if ((err = mp_mod(&Qmz, a, &Qmz)) != MP_OKAY)               goto LBL_LS_ERR;
5085       if ((err = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY)               goto LBL_LS_ERR;
5086 
5087       if (s_mp_get_bit(&Dz, (unsigned int)u) == MP_YES) {
5088          /* Formulas for addition of indices (carried out mod N);
5089           *
5090           * U_(m+n) = (U_m*V_n + U_n*V_m)/2
5091           * V_(m+n) = (V_m*V_n + D*U_m*U_n)/2
5092           *
5093           * Be careful with division by 2 (mod N)!
5094           */
5095          if ((err = mp_mul(&U2mz, &Vz, &T1z)) != MP_OKAY)         goto LBL_LS_ERR;
5096          if ((err = mp_mul(&Uz, &V2mz, &T2z)) != MP_OKAY)         goto LBL_LS_ERR;
5097          if ((err = mp_mul(&V2mz, &Vz, &T3z)) != MP_OKAY)         goto LBL_LS_ERR;
5098          if ((err = mp_mul(&U2mz, &Uz, &T4z)) != MP_OKAY)         goto LBL_LS_ERR;
5099          if ((err = s_mp_mul_si(&T4z, Ds, &T4z)) != MP_OKAY)      goto LBL_LS_ERR;
5100          if ((err = mp_add(&T1z, &T2z, &Uz)) != MP_OKAY)          goto LBL_LS_ERR;
5101          if (MP_IS_ODD(&Uz)) {
5102             if ((err = mp_add(&Uz, a, &Uz)) != MP_OKAY)           goto LBL_LS_ERR;
5103          }
5104          /* CZ
5105           * This should round towards negative infinity because
5106           * Thomas R. Nicely used GMP's mpz_fdiv_q_2exp().
5107           * But mp_div_2() does not do so, it is truncating instead.
5108           */
5109          oddness = MP_IS_ODD(&Uz) ? MP_YES : MP_NO;
5110          if ((err = mp_div_2(&Uz, &Uz)) != MP_OKAY)               goto LBL_LS_ERR;
5111          if ((Uz.sign == MP_NEG) && (oddness != MP_NO)) {
5112             if ((err = mp_sub_d(&Uz, 1uL, &Uz)) != MP_OKAY)       goto LBL_LS_ERR;
5113          }
5114          if ((err = mp_add(&T3z, &T4z, &Vz)) != MP_OKAY)          goto LBL_LS_ERR;
5115          if (MP_IS_ODD(&Vz)) {
5116             if ((err = mp_add(&Vz, a, &Vz)) != MP_OKAY)           goto LBL_LS_ERR;
5117          }
5118          oddness = MP_IS_ODD(&Vz) ? MP_YES : MP_NO;
5119          if ((err = mp_div_2(&Vz, &Vz)) != MP_OKAY)               goto LBL_LS_ERR;
5120          if ((Vz.sign == MP_NEG) && (oddness != MP_NO)) {
5121             if ((err = mp_sub_d(&Vz, 1uL, &Vz)) != MP_OKAY)       goto LBL_LS_ERR;
5122          }
5123          if ((err = mp_mod(&Uz, a, &Uz)) != MP_OKAY)              goto LBL_LS_ERR;
5124          if ((err = mp_mod(&Vz, a, &Vz)) != MP_OKAY)              goto LBL_LS_ERR;
5125 
5126          /* Calculating Q^d for later use */
5127          if ((err = mp_mul(&Qkdz, &Qmz, &Qkdz)) != MP_OKAY)       goto LBL_LS_ERR;
5128          if ((err = mp_mod(&Qkdz, a, &Qkdz)) != MP_OKAY)          goto LBL_LS_ERR;
5129       }
5130    }
5131 
5132    /* If U_d or V_d is congruent to 0 mod N, then N is a prime or a
5133       strong Lucas pseudoprime. */
5134    if (MP_IS_ZERO(&Uz) || MP_IS_ZERO(&Vz)) {
5135       *result = MP_YES;
5136       goto LBL_LS_ERR;
5137    }
5138 
5139    /* NOTE: Ribenboim ("The new book of prime number records," 3rd ed.,
5140       1995/6) omits the condition V0 on p.142, but includes it on
5141       p. 130. The condition is NECESSARY; otherwise the test will
5142       return false negatives---e.g., the primes 29 and 2000029 will be
5143       returned as composite. */
5144 
5145    /* Otherwise, we must compute V_2d, V_4d, V_8d, ..., V_{2^(s-1)*d}
5146       by repeated use of the formula V_2m = V_m*V_m - 2*Q^m. If any of
5147       these are congruent to 0 mod N, then N is a prime or a strong
5148       Lucas pseudoprime. */
5149 
5150    /* Initialize 2*Q^(d*2^r) for V_2m */
5151    if ((err = mp_mul_2(&Qkdz, &Q2kdz)) != MP_OKAY)                goto LBL_LS_ERR;
5152 
5153    for (r = 1; r < s; r++) {
5154       if ((err = mp_sqr(&Vz, &Vz)) != MP_OKAY)                    goto LBL_LS_ERR;
5155       if ((err = mp_sub(&Vz, &Q2kdz, &Vz)) != MP_OKAY)            goto LBL_LS_ERR;
5156       if ((err = mp_mod(&Vz, a, &Vz)) != MP_OKAY)                 goto LBL_LS_ERR;
5157       if (MP_IS_ZERO(&Vz)) {
5158          *result = MP_YES;
5159          goto LBL_LS_ERR;
5160       }
5161       /* Calculate Q^{d*2^r} for next r (final iteration irrelevant). */
5162       if (r < (s - 1)) {
5163          if ((err = mp_sqr(&Qkdz, &Qkdz)) != MP_OKAY)             goto LBL_LS_ERR;
5164          if ((err = mp_mod(&Qkdz, a, &Qkdz)) != MP_OKAY)          goto LBL_LS_ERR;
5165          if ((err = mp_mul_2(&Qkdz, &Q2kdz)) != MP_OKAY)          goto LBL_LS_ERR;
5166       }
5167    }
5168 LBL_LS_ERR:
5169    mp_clear_multi(&Q2kdz, &T4z, &T3z, &T2z, &T1z, &Qkdz, &Q2mz, &Qmz, &V2mz, &U2mz, &Vz, &Uz, &Np1, &gcd, &Dz, NULL);
5170    return err;
5171 }
5172 #endif
5173 #endif
5174 #endif
5175 
5176 /* End: bn_mp_prime_strong_lucas_selfridge.c */
5177 
5178 /* Start: bn_mp_radix_size.c */
5179 #include "tommath_private.h"
5180 #ifdef BN_MP_RADIX_SIZE_C
5181 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5182 /* SPDX-License-Identifier: Unlicense */
5183 
5184 /* returns size of ASCII representation */
mp_radix_size(const mp_int * a,int radix,int * size)5185 mp_err mp_radix_size(const mp_int *a, int radix, int *size)
5186 {
5187    mp_err  err;
5188    int digs;
5189    mp_int   t;
5190    mp_digit d;
5191 
5192    *size = 0;
5193 
5194    /* make sure the radix is in range */
5195    if ((radix < 2) || (radix > 64)) {
5196       return MP_VAL;
5197    }
5198 
5199    if (MP_IS_ZERO(a)) {
5200       *size = 2;
5201       return MP_OKAY;
5202    }
5203 
5204    /* special case for binary */
5205    if (radix == 2) {
5206       *size = (mp_count_bits(a) + ((a->sign == MP_NEG) ? 1 : 0) + 1);
5207       return MP_OKAY;
5208    }
5209 
5210    /* digs is the digit count */
5211    digs = 0;
5212 
5213    /* if it's negative add one for the sign */
5214    if (a->sign == MP_NEG) {
5215       ++digs;
5216    }
5217 
5218    /* init a copy of the input */
5219    if ((err = mp_init_copy(&t, a)) != MP_OKAY) {
5220       return err;
5221    }
5222 
5223    /* force temp to positive */
5224    t.sign = MP_ZPOS;
5225 
5226    /* fetch out all of the digits */
5227    while (!MP_IS_ZERO(&t)) {
5228       if ((err = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
5229          goto LBL_ERR;
5230       }
5231       ++digs;
5232    }
5233 
5234    /* return digs + 1, the 1 is for the NULL byte that would be required. */
5235    *size = digs + 1;
5236    err = MP_OKAY;
5237 
5238 LBL_ERR:
5239    mp_clear(&t);
5240    return err;
5241 }
5242 
5243 #endif
5244 
5245 /* End: bn_mp_radix_size.c */
5246 
5247 /* Start: bn_mp_radix_smap.c */
5248 #include "tommath_private.h"
5249 #ifdef BN_MP_RADIX_SMAP_C
5250 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5251 /* SPDX-License-Identifier: Unlicense */
5252 
5253 /* chars used in radix conversions */
5254 const char *const mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
5255 const uint8_t mp_s_rmap_reverse[] = {
5256    0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, /* ()*+,-./ */
5257    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */
5258    0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 89:;<=>? */
5259    0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, /* @ABCDEFG */
5260    0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, /* HIJKLMNO */
5261    0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, /* PQRSTUVW */
5262    0x21, 0x22, 0x23, 0xff, 0xff, 0xff, 0xff, 0xff, /* XYZ[\]^_ */
5263    0xff, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, /* `abcdefg */
5264    0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, /* hijklmno */
5265    0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, /* pqrstuvw */
5266    0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, /* xyz{|}~. */
5267 };
5268 const size_t mp_s_rmap_reverse_sz = sizeof(mp_s_rmap_reverse);
5269 #endif
5270 
5271 /* End: bn_mp_radix_smap.c */
5272 
5273 /* Start: bn_mp_rand.c */
5274 #include "tommath_private.h"
5275 #ifdef BN_MP_RAND_C
5276 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5277 /* SPDX-License-Identifier: Unlicense */
5278 
5279 mp_err(*s_mp_rand_source)(void *out, size_t size) = s_mp_rand_platform;
5280 
mp_rand_source(mp_err (* source)(void * out,size_t size))5281 void mp_rand_source(mp_err(*source)(void *out, size_t size))
5282 {
5283    s_mp_rand_source = (source == NULL) ? s_mp_rand_platform : source;
5284 }
5285 
mp_rand(mp_int * a,int digits)5286 mp_err mp_rand(mp_int *a, int digits)
5287 {
5288    int i;
5289    mp_err err;
5290 
5291    mp_zero(a);
5292 
5293    if (digits <= 0) {
5294       return MP_OKAY;
5295    }
5296 
5297    if ((err = mp_grow(a, digits)) != MP_OKAY) {
5298       return err;
5299    }
5300 
5301    if ((err = s_mp_rand_source(a->dp, (size_t)digits * sizeof(mp_digit))) != MP_OKAY) {
5302       return err;
5303    }
5304 
5305    /* TODO: We ensure that the highest digit is nonzero. Should this be removed? */
5306    while ((a->dp[digits - 1] & MP_MASK) == 0u) {
5307       if ((err = s_mp_rand_source(a->dp + digits - 1, sizeof(mp_digit))) != MP_OKAY) {
5308          return err;
5309       }
5310    }
5311 
5312    a->used = digits;
5313    for (i = 0; i < digits; ++i) {
5314       a->dp[i] &= MP_MASK;
5315    }
5316 
5317    return MP_OKAY;
5318 }
5319 #endif
5320 
5321 /* End: bn_mp_rand.c */
5322 
5323 /* Start: bn_mp_read_radix.c */
5324 #include "tommath_private.h"
5325 #ifdef BN_MP_READ_RADIX_C
5326 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5327 /* SPDX-License-Identifier: Unlicense */
5328 
5329 #define MP_TOUPPER(c) ((((c) >= 'a') && ((c) <= 'z')) ? (((c) + 'A') - 'a') : (c))
5330 
5331 /* read a string [ASCII] in a given radix */
mp_read_radix(mp_int * a,const char * str,int radix)5332 mp_err mp_read_radix(mp_int *a, const char *str, int radix)
5333 {
5334    mp_err   err;
5335    int      y;
5336    mp_sign  neg;
5337    unsigned pos;
5338    char     ch;
5339 
5340    /* zero the digit bignum */
5341    mp_zero(a);
5342 
5343    /* make sure the radix is ok */
5344    if ((radix < 2) || (radix > 64)) {
5345       return MP_VAL;
5346    }
5347 
5348    /* if the leading digit is a
5349     * minus set the sign to negative.
5350     */
5351    if (*str == '-') {
5352       ++str;
5353       neg = MP_NEG;
5354    } else {
5355       neg = MP_ZPOS;
5356    }
5357 
5358    /* set the integer to the default of zero */
5359    mp_zero(a);
5360 
5361    /* process each digit of the string */
5362    while (*str != '\0') {
5363       /* if the radix <= 36 the conversion is case insensitive
5364        * this allows numbers like 1AB and 1ab to represent the same  value
5365        * [e.g. in hex]
5366        */
5367       ch = (radix <= 36) ? (char)MP_TOUPPER((int)*str) : *str;
5368       pos = (unsigned)(ch - '(');
5369       if (mp_s_rmap_reverse_sz < pos) {
5370          break;
5371       }
5372       y = (int)mp_s_rmap_reverse[pos];
5373 
5374       /* if the char was found in the map
5375        * and is less than the given radix add it
5376        * to the number, otherwise exit the loop.
5377        */
5378       if ((y == 0xff) || (y >= radix)) {
5379          break;
5380       }
5381       if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) {
5382          return err;
5383       }
5384       if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) {
5385          return err;
5386       }
5387       ++str;
5388    }
5389 
5390    /* if an illegal character was found, fail. */
5391    if (!((*str == '\0') || (*str == '\r') || (*str == '\n'))) {
5392       mp_zero(a);
5393       return MP_VAL;
5394    }
5395 
5396    /* set the sign only if a != 0 */
5397    if (!MP_IS_ZERO(a)) {
5398       a->sign = neg;
5399    }
5400    return MP_OKAY;
5401 }
5402 #endif
5403 
5404 /* End: bn_mp_read_radix.c */
5405 
5406 /* Start: bn_mp_reduce.c */
5407 #include "tommath_private.h"
5408 #ifdef BN_MP_REDUCE_C
5409 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5410 /* SPDX-License-Identifier: Unlicense */
5411 
5412 /* reduces x mod m, assumes 0 < x < m**2, mu is
5413  * precomputed via mp_reduce_setup.
5414  * From HAC pp.604 Algorithm 14.42
5415  */
mp_reduce(mp_int * x,const mp_int * m,const mp_int * mu)5416 mp_err mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu)
5417 {
5418    mp_int  q;
5419    mp_err  err;
5420    int     um = m->used;
5421 
5422    /* q = x */
5423    if ((err = mp_init_copy(&q, x)) != MP_OKAY) {
5424       return err;
5425    }
5426 
5427    /* q1 = x / b**(k-1)  */
5428    mp_rshd(&q, um - 1);
5429 
5430    /* according to HAC this optimization is ok */
5431    if ((mp_digit)um > ((mp_digit)1 << (MP_DIGIT_BIT - 1))) {
5432       if ((err = mp_mul(&q, mu, &q)) != MP_OKAY) {
5433          goto CLEANUP;
5434       }
5435    } else if (MP_HAS(S_MP_MUL_HIGH_DIGS)) {
5436       if ((err = s_mp_mul_high_digs(&q, mu, &q, um)) != MP_OKAY) {
5437          goto CLEANUP;
5438       }
5439    } else if (MP_HAS(S_MP_MUL_HIGH_DIGS_FAST)) {
5440       if ((err = s_mp_mul_high_digs_fast(&q, mu, &q, um)) != MP_OKAY) {
5441          goto CLEANUP;
5442       }
5443    } else {
5444       err = MP_VAL;
5445       goto CLEANUP;
5446    }
5447 
5448    /* q3 = q2 / b**(k+1) */
5449    mp_rshd(&q, um + 1);
5450 
5451    /* x = x mod b**(k+1), quick (no division) */
5452    if ((err = mp_mod_2d(x, MP_DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
5453       goto CLEANUP;
5454    }
5455 
5456    /* q = q * m mod b**(k+1), quick (no division) */
5457    if ((err = s_mp_mul_digs(&q, m, &q, um + 1)) != MP_OKAY) {
5458       goto CLEANUP;
5459    }
5460 
5461    /* x = x - q */
5462    if ((err = mp_sub(x, &q, x)) != MP_OKAY) {
5463       goto CLEANUP;
5464    }
5465 
5466    /* If x < 0, add b**(k+1) to it */
5467    if (mp_cmp_d(x, 0uL) == MP_LT) {
5468       mp_set(&q, 1uL);
5469       if ((err = mp_lshd(&q, um + 1)) != MP_OKAY) {
5470          goto CLEANUP;
5471       }
5472       if ((err = mp_add(x, &q, x)) != MP_OKAY) {
5473          goto CLEANUP;
5474       }
5475    }
5476 
5477    /* Back off if it's too big */
5478    while (mp_cmp(x, m) != MP_LT) {
5479       if ((err = s_mp_sub(x, m, x)) != MP_OKAY) {
5480          goto CLEANUP;
5481       }
5482    }
5483 
5484 CLEANUP:
5485    mp_clear(&q);
5486 
5487    return err;
5488 }
5489 #endif
5490 
5491 /* End: bn_mp_reduce.c */
5492 
5493 /* Start: bn_mp_reduce_2k.c */
5494 #include "tommath_private.h"
5495 #ifdef BN_MP_REDUCE_2K_C
5496 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5497 /* SPDX-License-Identifier: Unlicense */
5498 
5499 /* reduces a modulo n where n is of the form 2**p - d */
mp_reduce_2k(mp_int * a,const mp_int * n,mp_digit d)5500 mp_err mp_reduce_2k(mp_int *a, const mp_int *n, mp_digit d)
5501 {
5502    mp_int q;
5503    mp_err err;
5504    int    p;
5505 
5506    if ((err = mp_init(&q)) != MP_OKAY) {
5507       return err;
5508    }
5509 
5510    p = mp_count_bits(n);
5511 top:
5512    /* q = a/2**p, a = a mod 2**p */
5513    if ((err = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
5514       goto LBL_ERR;
5515    }
5516 
5517    if (d != 1u) {
5518       /* q = q * d */
5519       if ((err = mp_mul_d(&q, d, &q)) != MP_OKAY) {
5520          goto LBL_ERR;
5521       }
5522    }
5523 
5524    /* a = a + q */
5525    if ((err = s_mp_add(a, &q, a)) != MP_OKAY) {
5526       goto LBL_ERR;
5527    }
5528 
5529    if (mp_cmp_mag(a, n) != MP_LT) {
5530       if ((err = s_mp_sub(a, n, a)) != MP_OKAY) {
5531          goto LBL_ERR;
5532       }
5533       goto top;
5534    }
5535 
5536 LBL_ERR:
5537    mp_clear(&q);
5538    return err;
5539 }
5540 
5541 #endif
5542 
5543 /* End: bn_mp_reduce_2k.c */
5544 
5545 /* Start: bn_mp_reduce_2k_l.c */
5546 #include "tommath_private.h"
5547 #ifdef BN_MP_REDUCE_2K_L_C
5548 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5549 /* SPDX-License-Identifier: Unlicense */
5550 
5551 /* reduces a modulo n where n is of the form 2**p - d
5552    This differs from reduce_2k since "d" can be larger
5553    than a single digit.
5554 */
mp_reduce_2k_l(mp_int * a,const mp_int * n,const mp_int * d)5555 mp_err mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d)
5556 {
5557    mp_int q;
5558    mp_err err;
5559    int    p;
5560 
5561    if ((err = mp_init(&q)) != MP_OKAY) {
5562       return err;
5563    }
5564 
5565    p = mp_count_bits(n);
5566 top:
5567    /* q = a/2**p, a = a mod 2**p */
5568    if ((err = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
5569       goto LBL_ERR;
5570    }
5571 
5572    /* q = q * d */
5573    if ((err = mp_mul(&q, d, &q)) != MP_OKAY) {
5574       goto LBL_ERR;
5575    }
5576 
5577    /* a = a + q */
5578    if ((err = s_mp_add(a, &q, a)) != MP_OKAY) {
5579       goto LBL_ERR;
5580    }
5581 
5582    if (mp_cmp_mag(a, n) != MP_LT) {
5583       if ((err = s_mp_sub(a, n, a)) != MP_OKAY) {
5584          goto LBL_ERR;
5585       }
5586       goto top;
5587    }
5588 
5589 LBL_ERR:
5590    mp_clear(&q);
5591    return err;
5592 }
5593 
5594 #endif
5595 
5596 /* End: bn_mp_reduce_2k_l.c */
5597 
5598 /* Start: bn_mp_reduce_2k_setup.c */
5599 #include "tommath_private.h"
5600 #ifdef BN_MP_REDUCE_2K_SETUP_C
5601 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5602 /* SPDX-License-Identifier: Unlicense */
5603 
5604 /* determines the setup value */
mp_reduce_2k_setup(const mp_int * a,mp_digit * d)5605 mp_err mp_reduce_2k_setup(const mp_int *a, mp_digit *d)
5606 {
5607    mp_err err;
5608    mp_int tmp;
5609    int    p;
5610 
5611    if ((err = mp_init(&tmp)) != MP_OKAY) {
5612       return err;
5613    }
5614 
5615    p = mp_count_bits(a);
5616    if ((err = mp_2expt(&tmp, p)) != MP_OKAY) {
5617       mp_clear(&tmp);
5618       return err;
5619    }
5620 
5621    if ((err = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {
5622       mp_clear(&tmp);
5623       return err;
5624    }
5625 
5626    *d = tmp.dp[0];
5627    mp_clear(&tmp);
5628    return MP_OKAY;
5629 }
5630 #endif
5631 
5632 /* End: bn_mp_reduce_2k_setup.c */
5633 
5634 /* Start: bn_mp_reduce_2k_setup_l.c */
5635 #include "tommath_private.h"
5636 #ifdef BN_MP_REDUCE_2K_SETUP_L_C
5637 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5638 /* SPDX-License-Identifier: Unlicense */
5639 
5640 /* determines the setup value */
mp_reduce_2k_setup_l(const mp_int * a,mp_int * d)5641 mp_err mp_reduce_2k_setup_l(const mp_int *a, mp_int *d)
5642 {
5643    mp_err err;
5644    mp_int tmp;
5645 
5646    if ((err = mp_init(&tmp)) != MP_OKAY) {
5647       return err;
5648    }
5649 
5650    if ((err = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) {
5651       goto LBL_ERR;
5652    }
5653 
5654    if ((err = s_mp_sub(&tmp, a, d)) != MP_OKAY) {
5655       goto LBL_ERR;
5656    }
5657 
5658 LBL_ERR:
5659    mp_clear(&tmp);
5660    return err;
5661 }
5662 #endif
5663 
5664 /* End: bn_mp_reduce_2k_setup_l.c */
5665 
5666 /* Start: bn_mp_reduce_is_2k.c */
5667 #include "tommath_private.h"
5668 #ifdef BN_MP_REDUCE_IS_2K_C
5669 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5670 /* SPDX-License-Identifier: Unlicense */
5671 
5672 /* determines if mp_reduce_2k can be used */
mp_reduce_is_2k(const mp_int * a)5673 mp_bool mp_reduce_is_2k(const mp_int *a)
5674 {
5675    int ix, iy, iw;
5676    mp_digit iz;
5677 
5678    if (a->used == 0) {
5679       return MP_NO;
5680    } else if (a->used == 1) {
5681       return MP_YES;
5682    } else if (a->used > 1) {
5683       iy = mp_count_bits(a);
5684       iz = 1;
5685       iw = 1;
5686 
5687       /* Test every bit from the second digit up, must be 1 */
5688       for (ix = MP_DIGIT_BIT; ix < iy; ix++) {
5689          if ((a->dp[iw] & iz) == 0u) {
5690             return MP_NO;
5691          }
5692          iz <<= 1;
5693          if (iz > MP_DIGIT_MAX) {
5694             ++iw;
5695             iz = 1;
5696          }
5697       }
5698       return MP_YES;
5699    } else {
5700       return MP_YES;
5701    }
5702 }
5703 
5704 #endif
5705 
5706 /* End: bn_mp_reduce_is_2k.c */
5707 
5708 /* Start: bn_mp_reduce_is_2k_l.c */
5709 #include "tommath_private.h"
5710 #ifdef BN_MP_REDUCE_IS_2K_L_C
5711 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5712 /* SPDX-License-Identifier: Unlicense */
5713 
5714 /* determines if reduce_2k_l can be used */
mp_reduce_is_2k_l(const mp_int * a)5715 mp_bool mp_reduce_is_2k_l(const mp_int *a)
5716 {
5717    int ix, iy;
5718 
5719    if (a->used == 0) {
5720       return MP_NO;
5721    } else if (a->used == 1) {
5722       return MP_YES;
5723    } else if (a->used > 1) {
5724       /* if more than half of the digits are -1 we're sold */
5725       for (iy = ix = 0; ix < a->used; ix++) {
5726          if (a->dp[ix] == MP_DIGIT_MAX) {
5727             ++iy;
5728          }
5729       }
5730       return (iy >= (a->used/2)) ? MP_YES : MP_NO;
5731    } else {
5732       return MP_NO;
5733    }
5734 }
5735 
5736 #endif
5737 
5738 /* End: bn_mp_reduce_is_2k_l.c */
5739 
5740 /* Start: bn_mp_reduce_setup.c */
5741 #include "tommath_private.h"
5742 #ifdef BN_MP_REDUCE_SETUP_C
5743 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5744 /* SPDX-License-Identifier: Unlicense */
5745 
5746 /* pre-calculate the value required for Barrett reduction
5747  * For a given modulus "b" it calulates the value required in "a"
5748  */
mp_reduce_setup(mp_int * a,const mp_int * b)5749 mp_err mp_reduce_setup(mp_int *a, const mp_int *b)
5750 {
5751    mp_err err;
5752    if ((err = mp_2expt(a, b->used * 2 * MP_DIGIT_BIT)) != MP_OKAY) {
5753       return err;
5754    }
5755    return mp_div(a, b, a, NULL);
5756 }
5757 #endif
5758 
5759 /* End: bn_mp_reduce_setup.c */
5760 
5761 /* Start: bn_mp_root_u32.c */
5762 #include "tommath_private.h"
5763 #ifdef BN_MP_ROOT_U32_C
5764 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5765 /* SPDX-License-Identifier: Unlicense */
5766 
5767 /* find the n'th root of an integer
5768  *
5769  * Result found such that (c)**b <= a and (c+1)**b > a
5770  *
5771  * This algorithm uses Newton's approximation
5772  * x[i+1] = x[i] - f(x[i])/f'(x[i])
5773  * which will find the root in log(N) time where
5774  * each step involves a fair bit.
5775  */
mp_root_u32(const mp_int * a,uint32_t b,mp_int * c)5776 mp_err mp_root_u32(const mp_int *a, uint32_t b, mp_int *c)
5777 {
5778    mp_int t1, t2, t3, a_;
5779    mp_ord cmp;
5780    int    ilog2;
5781    mp_err err;
5782 
5783    /* input must be positive if b is even */
5784    if (((b & 1u) == 0u) && (a->sign == MP_NEG)) {
5785       return MP_VAL;
5786    }
5787 
5788    if ((err = mp_init_multi(&t1, &t2, &t3, NULL)) != MP_OKAY) {
5789       return err;
5790    }
5791 
5792    /* if a is negative fudge the sign but keep track */
5793    a_ = *a;
5794    a_.sign = MP_ZPOS;
5795 
5796    /* Compute seed: 2^(log_2(n)/b + 2)*/
5797    ilog2 = mp_count_bits(a);
5798 
5799    /*
5800      If "b" is larger than INT_MAX it is also larger than
5801      log_2(n) because the bit-length of the "n" is measured
5802      with an int and hence the root is always < 2 (two).
5803    */
5804    if (b > (uint32_t)(INT_MAX/2)) {
5805       mp_set(c, 1uL);
5806       c->sign = a->sign;
5807       err = MP_OKAY;
5808       goto LBL_ERR;
5809    }
5810 
5811    /* "b" is smaller than INT_MAX, we can cast safely */
5812    if (ilog2 < (int)b) {
5813       mp_set(c, 1uL);
5814       c->sign = a->sign;
5815       err = MP_OKAY;
5816       goto LBL_ERR;
5817    }
5818    ilog2 =  ilog2 / ((int)b);
5819    if (ilog2 == 0) {
5820       mp_set(c, 1uL);
5821       c->sign = a->sign;
5822       err = MP_OKAY;
5823       goto LBL_ERR;
5824    }
5825    /* Start value must be larger than root */
5826    ilog2 += 2;
5827    if ((err = mp_2expt(&t2,ilog2)) != MP_OKAY)                    goto LBL_ERR;
5828    do {
5829       /* t1 = t2 */
5830       if ((err = mp_copy(&t2, &t1)) != MP_OKAY)                   goto LBL_ERR;
5831 
5832       /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
5833 
5834       /* t3 = t1**(b-1) */
5835       if ((err = mp_expt_u32(&t1, b - 1u, &t3)) != MP_OKAY)       goto LBL_ERR;
5836 
5837       /* numerator */
5838       /* t2 = t1**b */
5839       if ((err = mp_mul(&t3, &t1, &t2)) != MP_OKAY)               goto LBL_ERR;
5840 
5841       /* t2 = t1**b - a */
5842       if ((err = mp_sub(&t2, &a_, &t2)) != MP_OKAY)               goto LBL_ERR;
5843 
5844       /* denominator */
5845       /* t3 = t1**(b-1) * b  */
5846       if ((err = mp_mul_d(&t3, b, &t3)) != MP_OKAY)               goto LBL_ERR;
5847 
5848       /* t3 = (t1**b - a)/(b * t1**(b-1)) */
5849       if ((err = mp_div(&t2, &t3, &t3, NULL)) != MP_OKAY)         goto LBL_ERR;
5850 
5851       if ((err = mp_sub(&t1, &t3, &t2)) != MP_OKAY)               goto LBL_ERR;
5852 
5853       /*
5854           Number of rounds is at most log_2(root). If it is more it
5855           got stuck, so break out of the loop and do the rest manually.
5856        */
5857       if (ilog2-- == 0) {
5858          break;
5859       }
5860    }  while (mp_cmp(&t1, &t2) != MP_EQ);
5861 
5862    /* result can be off by a few so check */
5863    /* Loop beneath can overshoot by one if found root is smaller than actual root */
5864    for (;;) {
5865       if ((err = mp_expt_u32(&t1, b, &t2)) != MP_OKAY)            goto LBL_ERR;
5866       cmp = mp_cmp(&t2, &a_);
5867       if (cmp == MP_EQ) {
5868          err = MP_OKAY;
5869          goto LBL_ERR;
5870       }
5871       if (cmp == MP_LT) {
5872          if ((err = mp_add_d(&t1, 1uL, &t1)) != MP_OKAY)          goto LBL_ERR;
5873       } else {
5874          break;
5875       }
5876    }
5877    /* correct overshoot from above or from recurrence */
5878    for (;;) {
5879       if ((err = mp_expt_u32(&t1, b, &t2)) != MP_OKAY)            goto LBL_ERR;
5880       if (mp_cmp(&t2, &a_) == MP_GT) {
5881          if ((err = mp_sub_d(&t1, 1uL, &t1)) != MP_OKAY)          goto LBL_ERR;
5882       } else {
5883          break;
5884       }
5885    }
5886 
5887    /* set the result */
5888    mp_exch(&t1, c);
5889 
5890    /* set the sign of the result */
5891    c->sign = a->sign;
5892 
5893    err = MP_OKAY;
5894 
5895 LBL_ERR:
5896    mp_clear_multi(&t1, &t2, &t3, NULL);
5897    return err;
5898 }
5899 
5900 #endif
5901 
5902 /* End: bn_mp_root_u32.c */
5903 
5904 /* Start: bn_mp_rshd.c */
5905 #include "tommath_private.h"
5906 #ifdef BN_MP_RSHD_C
5907 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5908 /* SPDX-License-Identifier: Unlicense */
5909 
5910 /* shift right a certain amount of digits */
mp_rshd(mp_int * a,int b)5911 void mp_rshd(mp_int *a, int b)
5912 {
5913    int     x;
5914    mp_digit *bottom, *top;
5915 
5916    /* if b <= 0 then ignore it */
5917    if (b <= 0) {
5918       return;
5919    }
5920 
5921    /* if b > used then simply zero it and return */
5922    if (a->used <= b) {
5923       mp_zero(a);
5924       return;
5925    }
5926 
5927    /* shift the digits down */
5928 
5929    /* bottom */
5930    bottom = a->dp;
5931 
5932    /* top [offset into digits] */
5933    top = a->dp + b;
5934 
5935    /* this is implemented as a sliding window where
5936     * the window is b-digits long and digits from
5937     * the top of the window are copied to the bottom
5938     *
5939     * e.g.
5940 
5941     b-2 | b-1 | b0 | b1 | b2 | ... | bb |   ---->
5942                 /\                   |      ---->
5943                  \-------------------/      ---->
5944     */
5945    for (x = 0; x < (a->used - b); x++) {
5946       *bottom++ = *top++;
5947    }
5948 
5949    /* zero the top digits */
5950    MP_ZERO_DIGITS(bottom, a->used - x);
5951 
5952    /* remove excess digits */
5953    a->used -= b;
5954 }
5955 #endif
5956 
5957 /* End: bn_mp_rshd.c */
5958 
5959 /* Start: bn_mp_sbin_size.c */
5960 #include "tommath_private.h"
5961 #ifdef BN_MP_SBIN_SIZE_C
5962 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5963 /* SPDX-License-Identifier: Unlicense */
5964 
5965 /* get the size for an signed equivalent */
mp_sbin_size(const mp_int * a)5966 size_t mp_sbin_size(const mp_int *a)
5967 {
5968    return 1u + mp_ubin_size(a);
5969 }
5970 #endif
5971 
5972 /* End: bn_mp_sbin_size.c */
5973 
5974 /* Start: bn_mp_set.c */
5975 #include "tommath_private.h"
5976 #ifdef BN_MP_SET_C
5977 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5978 /* SPDX-License-Identifier: Unlicense */
5979 
5980 /* set to a digit */
mp_set(mp_int * a,mp_digit b)5981 void mp_set(mp_int *a, mp_digit b)
5982 {
5983    a->dp[0] = b & MP_MASK;
5984    a->sign  = MP_ZPOS;
5985    a->used  = (a->dp[0] != 0u) ? 1 : 0;
5986    MP_ZERO_DIGITS(a->dp + a->used, a->alloc - a->used);
5987 }
5988 #endif
5989 
5990 /* End: bn_mp_set.c */
5991 
5992 /* Start: bn_mp_set_double.c */
5993 #include "tommath_private.h"
5994 #ifdef BN_MP_SET_DOUBLE_C
5995 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
5996 /* SPDX-License-Identifier: Unlicense */
5997 
5998 #if defined(__STDC_IEC_559__) || defined(__GCC_IEC_559)
mp_set_double(mp_int * a,double b)5999 mp_err mp_set_double(mp_int *a, double b)
6000 {
6001    uint64_t frac;
6002    int exp;
6003    mp_err err;
6004    union {
6005       double   dbl;
6006       uint64_t bits;
6007    } cast;
6008    cast.dbl = b;
6009 
6010    exp = (int)((unsigned)(cast.bits >> 52) & 0x7FFu);
6011    frac = (cast.bits & ((1uLL << 52) - 1uLL)) | (1uLL << 52);
6012 
6013    if (exp == 0x7FF) { /* +-inf, NaN */
6014       return MP_VAL;
6015    }
6016    exp -= 1023 + 52;
6017 
6018    mp_set_u64(a, frac);
6019 
6020    err = (exp < 0) ? mp_div_2d(a, -exp, a, NULL) : mp_mul_2d(a, exp, a);
6021    if (err != MP_OKAY) {
6022       return err;
6023    }
6024 
6025    if (((cast.bits >> 63) != 0uLL) && !MP_IS_ZERO(a)) {
6026       a->sign = MP_NEG;
6027    }
6028 
6029    return MP_OKAY;
6030 }
6031 #else
6032 /* pragma message() not supported by several compilers (in mostly older but still used versions) */
6033 #  ifdef _MSC_VER
6034 #    pragma message("mp_set_double implementation is only available on platforms with IEEE754 floating point format")
6035 #  else
6036 #    warning "mp_set_double implementation is only available on platforms with IEEE754 floating point format"
6037 #  endif
6038 #endif
6039 #endif
6040 
6041 /* End: bn_mp_set_double.c */
6042 
6043 /* Start: bn_mp_set_i32.c */
6044 #include "tommath_private.h"
6045 #ifdef BN_MP_SET_I32_C
6046 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6047 /* SPDX-License-Identifier: Unlicense */
6048 
MP_SET_SIGNED(mp_set_i32,mp_set_u32,int32_t,uint32_t)6049 MP_SET_SIGNED(mp_set_i32, mp_set_u32, int32_t, uint32_t)
6050 #endif
6051 
6052 /* End: bn_mp_set_i32.c */
6053 
6054 /* Start: bn_mp_set_i64.c */
6055 #include "tommath_private.h"
6056 #ifdef BN_MP_SET_I64_C
6057 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6058 /* SPDX-License-Identifier: Unlicense */
6059 
6060 MP_SET_SIGNED(mp_set_i64, mp_set_u64, int64_t, uint64_t)
6061 #endif
6062 
6063 /* End: bn_mp_set_i64.c */
6064 
6065 /* Start: bn_mp_set_l.c */
6066 #include "tommath_private.h"
6067 #ifdef BN_MP_SET_L_C
6068 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6069 /* SPDX-License-Identifier: Unlicense */
6070 
6071 MP_SET_SIGNED(mp_set_l, mp_set_ul, long, unsigned long)
6072 #endif
6073 
6074 /* End: bn_mp_set_l.c */
6075 
6076 /* Start: bn_mp_set_ll.c */
6077 #include "tommath_private.h"
6078 #ifdef BN_MP_SET_LL_C
6079 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6080 /* SPDX-License-Identifier: Unlicense */
6081 
6082 MP_SET_SIGNED(mp_set_ll, mp_set_ull, long long, unsigned long long)
6083 #endif
6084 
6085 /* End: bn_mp_set_ll.c */
6086 
6087 /* Start: bn_mp_set_u32.c */
6088 #include "tommath_private.h"
6089 #ifdef BN_MP_SET_U32_C
6090 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6091 /* SPDX-License-Identifier: Unlicense */
6092 
6093 MP_SET_UNSIGNED(mp_set_u32, uint32_t)
6094 #endif
6095 
6096 /* End: bn_mp_set_u32.c */
6097 
6098 /* Start: bn_mp_set_u64.c */
6099 #include "tommath_private.h"
6100 #ifdef BN_MP_SET_U64_C
6101 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6102 /* SPDX-License-Identifier: Unlicense */
6103 
6104 MP_SET_UNSIGNED(mp_set_u64, uint64_t)
6105 #endif
6106 
6107 /* End: bn_mp_set_u64.c */
6108 
6109 /* Start: bn_mp_set_ul.c */
6110 #include "tommath_private.h"
6111 #ifdef BN_MP_SET_UL_C
6112 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6113 /* SPDX-License-Identifier: Unlicense */
6114 
6115 MP_SET_UNSIGNED(mp_set_ul, unsigned long)
6116 #endif
6117 
6118 /* End: bn_mp_set_ul.c */
6119 
6120 /* Start: bn_mp_set_ull.c */
6121 #include "tommath_private.h"
6122 #ifdef BN_MP_SET_ULL_C
6123 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6124 /* SPDX-License-Identifier: Unlicense */
6125 
6126 MP_SET_UNSIGNED(mp_set_ull, unsigned long long)
6127 #endif
6128 
6129 /* End: bn_mp_set_ull.c */
6130 
6131 /* Start: bn_mp_shrink.c */
6132 #include "tommath_private.h"
6133 #ifdef BN_MP_SHRINK_C
6134 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6135 /* SPDX-License-Identifier: Unlicense */
6136 
6137 /* shrink a bignum */
6138 mp_err mp_shrink(mp_int *a)
6139 {
6140    mp_digit *tmp;
6141    int alloc = MP_MAX(MP_MIN_PREC, a->used);
6142    if (a->alloc != alloc) {
6143       if ((tmp = (mp_digit *) MP_REALLOC(a->dp,
6144                                          (size_t)a->alloc * sizeof(mp_digit),
6145                                          (size_t)alloc * sizeof(mp_digit))) == NULL) {
6146          return MP_MEM;
6147       }
6148       a->dp    = tmp;
6149       a->alloc = alloc;
6150    }
6151    return MP_OKAY;
6152 }
6153 #endif
6154 
6155 /* End: bn_mp_shrink.c */
6156 
6157 /* Start: bn_mp_signed_rsh.c */
6158 #include "tommath_private.h"
6159 #ifdef BN_MP_SIGNED_RSH_C
6160 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6161 /* SPDX-License-Identifier: Unlicense */
6162 
6163 /* shift right by a certain bit count with sign extension */
mp_signed_rsh(const mp_int * a,int b,mp_int * c)6164 mp_err mp_signed_rsh(const mp_int *a, int b, mp_int *c)
6165 {
6166    mp_err res;
6167    if (a->sign == MP_ZPOS) {
6168       return mp_div_2d(a, b, c, NULL);
6169    }
6170 
6171    res = mp_add_d(a, 1uL, c);
6172    if (res != MP_OKAY) {
6173       return res;
6174    }
6175 
6176    res = mp_div_2d(c, b, c, NULL);
6177    return (res == MP_OKAY) ? mp_sub_d(c, 1uL, c) : res;
6178 }
6179 #endif
6180 
6181 /* End: bn_mp_signed_rsh.c */
6182 
6183 /* Start: bn_mp_sqr.c */
6184 #include "tommath_private.h"
6185 #ifdef BN_MP_SQR_C
6186 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6187 /* SPDX-License-Identifier: Unlicense */
6188 
6189 /* computes b = a*a */
mp_sqr(const mp_int * a,mp_int * b)6190 mp_err mp_sqr(const mp_int *a, mp_int *b)
6191 {
6192    mp_err err;
6193    if (MP_HAS(S_MP_TOOM_SQR) && /* use Toom-Cook? */
6194        (a->used >= MP_TOOM_SQR_CUTOFF)) {
6195       err = s_mp_toom_sqr(a, b);
6196    } else if (MP_HAS(S_MP_KARATSUBA_SQR) &&  /* Karatsuba? */
6197               (a->used >= MP_KARATSUBA_SQR_CUTOFF)) {
6198       err = s_mp_karatsuba_sqr(a, b);
6199    } else if (MP_HAS(S_MP_SQR_FAST) && /* can we use the fast comba multiplier? */
6200               (((a->used * 2) + 1) < MP_WARRAY) &&
6201               (a->used < (MP_MAXFAST / 2))) {
6202       err = s_mp_sqr_fast(a, b);
6203    } else if (MP_HAS(S_MP_SQR)) {
6204       err = s_mp_sqr(a, b);
6205    } else {
6206       err = MP_VAL;
6207    }
6208    b->sign = MP_ZPOS;
6209    return err;
6210 }
6211 #endif
6212 
6213 /* End: bn_mp_sqr.c */
6214 
6215 /* Start: bn_mp_sqrmod.c */
6216 #include "tommath_private.h"
6217 #ifdef BN_MP_SQRMOD_C
6218 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6219 /* SPDX-License-Identifier: Unlicense */
6220 
6221 /* c = a * a (mod b) */
mp_sqrmod(const mp_int * a,const mp_int * b,mp_int * c)6222 mp_err mp_sqrmod(const mp_int *a, const mp_int *b, mp_int *c)
6223 {
6224    mp_err  err;
6225    mp_int  t;
6226 
6227    if ((err = mp_init(&t)) != MP_OKAY) {
6228       return err;
6229    }
6230 
6231    if ((err = mp_sqr(a, &t)) != MP_OKAY) {
6232       goto LBL_ERR;
6233    }
6234    err = mp_mod(&t, b, c);
6235 
6236 LBL_ERR:
6237    mp_clear(&t);
6238    return err;
6239 }
6240 #endif
6241 
6242 /* End: bn_mp_sqrmod.c */
6243 
6244 /* Start: bn_mp_sqrt.c */
6245 #include "tommath_private.h"
6246 #ifdef BN_MP_SQRT_C
6247 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6248 /* SPDX-License-Identifier: Unlicense */
6249 
6250 /* this function is less generic than mp_n_root, simpler and faster */
mp_sqrt(const mp_int * arg,mp_int * ret)6251 mp_err mp_sqrt(const mp_int *arg, mp_int *ret)
6252 {
6253    mp_err err;
6254    mp_int t1, t2;
6255 
6256    /* must be positive */
6257    if (arg->sign == MP_NEG) {
6258       return MP_VAL;
6259    }
6260 
6261    /* easy out */
6262    if (MP_IS_ZERO(arg)) {
6263       mp_zero(ret);
6264       return MP_OKAY;
6265    }
6266 
6267    if ((err = mp_init_copy(&t1, arg)) != MP_OKAY) {
6268       return err;
6269    }
6270 
6271    if ((err = mp_init(&t2)) != MP_OKAY) {
6272       goto E2;
6273    }
6274 
6275    /* First approx. (not very bad for large arg) */
6276    mp_rshd(&t1, t1.used/2);
6277 
6278    /* t1 > 0  */
6279    if ((err = mp_div(arg, &t1, &t2, NULL)) != MP_OKAY) {
6280       goto E1;
6281    }
6282    if ((err = mp_add(&t1, &t2, &t1)) != MP_OKAY) {
6283       goto E1;
6284    }
6285    if ((err = mp_div_2(&t1, &t1)) != MP_OKAY) {
6286       goto E1;
6287    }
6288    /* And now t1 > sqrt(arg) */
6289    do {
6290       if ((err = mp_div(arg, &t1, &t2, NULL)) != MP_OKAY) {
6291          goto E1;
6292       }
6293       if ((err = mp_add(&t1, &t2, &t1)) != MP_OKAY) {
6294          goto E1;
6295       }
6296       if ((err = mp_div_2(&t1, &t1)) != MP_OKAY) {
6297          goto E1;
6298       }
6299       /* t1 >= sqrt(arg) >= t2 at this point */
6300    } while (mp_cmp_mag(&t1, &t2) == MP_GT);
6301 
6302    mp_exch(&t1, ret);
6303 
6304 E1:
6305    mp_clear(&t2);
6306 E2:
6307    mp_clear(&t1);
6308    return err;
6309 }
6310 
6311 #endif
6312 
6313 /* End: bn_mp_sqrt.c */
6314 
6315 /* Start: bn_mp_sqrtmod_prime.c */
6316 #include "tommath_private.h"
6317 #ifdef BN_MP_SQRTMOD_PRIME_C
6318 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6319 /* SPDX-License-Identifier: Unlicense */
6320 
6321 /* Tonelli-Shanks algorithm
6322  * https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm
6323  * https://gmplib.org/list-archives/gmp-discuss/2013-April/005300.html
6324  *
6325  */
6326 
mp_sqrtmod_prime(const mp_int * n,const mp_int * prime,mp_int * ret)6327 mp_err mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret)
6328 {
6329    mp_err err;
6330    int legendre;
6331    mp_int t1, C, Q, S, Z, M, T, R, two;
6332    mp_digit i;
6333 
6334    /* first handle the simple cases */
6335    if (mp_cmp_d(n, 0uL) == MP_EQ) {
6336       mp_zero(ret);
6337       return MP_OKAY;
6338    }
6339    if (mp_cmp_d(prime, 2uL) == MP_EQ)                            return MP_VAL; /* prime must be odd */
6340    if ((err = mp_kronecker(n, prime, &legendre)) != MP_OKAY)        return err;
6341    if (legendre == -1)                                           return MP_VAL; /* quadratic non-residue mod prime */
6342 
6343    if ((err = mp_init_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL)) != MP_OKAY) {
6344       return err;
6345    }
6346 
6347    /* SPECIAL CASE: if prime mod 4 == 3
6348     * compute directly: err = n^(prime+1)/4 mod prime
6349     * Handbook of Applied Cryptography algorithm 3.36
6350     */
6351    if ((err = mp_mod_d(prime, 4uL, &i)) != MP_OKAY)               goto cleanup;
6352    if (i == 3u) {
6353       if ((err = mp_add_d(prime, 1uL, &t1)) != MP_OKAY)           goto cleanup;
6354       if ((err = mp_div_2(&t1, &t1)) != MP_OKAY)                  goto cleanup;
6355       if ((err = mp_div_2(&t1, &t1)) != MP_OKAY)                  goto cleanup;
6356       if ((err = mp_exptmod(n, &t1, prime, ret)) != MP_OKAY)      goto cleanup;
6357       err = MP_OKAY;
6358       goto cleanup;
6359    }
6360 
6361    /* NOW: Tonelli-Shanks algorithm */
6362 
6363    /* factor out powers of 2 from prime-1, defining Q and S as: prime-1 = Q*2^S */
6364    if ((err = mp_copy(prime, &Q)) != MP_OKAY)                    goto cleanup;
6365    if ((err = mp_sub_d(&Q, 1uL, &Q)) != MP_OKAY)                 goto cleanup;
6366    /* Q = prime - 1 */
6367    mp_zero(&S);
6368    /* S = 0 */
6369    while (MP_IS_EVEN(&Q)) {
6370       if ((err = mp_div_2(&Q, &Q)) != MP_OKAY)                    goto cleanup;
6371       /* Q = Q / 2 */
6372       if ((err = mp_add_d(&S, 1uL, &S)) != MP_OKAY)               goto cleanup;
6373       /* S = S + 1 */
6374    }
6375 
6376    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
6377    mp_set_u32(&Z, 2u);
6378    /* Z = 2 */
6379    for (;;) {
6380       if ((err = mp_kronecker(&Z, prime, &legendre)) != MP_OKAY)     goto cleanup;
6381       if (legendre == -1) break;
6382       if ((err = mp_add_d(&Z, 1uL, &Z)) != MP_OKAY)               goto cleanup;
6383       /* Z = Z + 1 */
6384    }
6385 
6386    if ((err = mp_exptmod(&Z, &Q, prime, &C)) != MP_OKAY)         goto cleanup;
6387    /* C = Z ^ Q mod prime */
6388    if ((err = mp_add_d(&Q, 1uL, &t1)) != MP_OKAY)                goto cleanup;
6389    if ((err = mp_div_2(&t1, &t1)) != MP_OKAY)                    goto cleanup;
6390    /* t1 = (Q + 1) / 2 */
6391    if ((err = mp_exptmod(n, &t1, prime, &R)) != MP_OKAY)         goto cleanup;
6392    /* R = n ^ ((Q + 1) / 2) mod prime */
6393    if ((err = mp_exptmod(n, &Q, prime, &T)) != MP_OKAY)          goto cleanup;
6394    /* T = n ^ Q mod prime */
6395    if ((err = mp_copy(&S, &M)) != MP_OKAY)                       goto cleanup;
6396    /* M = S */
6397    mp_set_u32(&two, 2u);
6398 
6399    for (;;) {
6400       if ((err = mp_copy(&T, &t1)) != MP_OKAY)                    goto cleanup;
6401       i = 0;
6402       for (;;) {
6403          if (mp_cmp_d(&t1, 1uL) == MP_EQ) break;
6404          if ((err = mp_exptmod(&t1, &two, prime, &t1)) != MP_OKAY) goto cleanup;
6405          i++;
6406       }
6407       if (i == 0u) {
6408          if ((err = mp_copy(&R, ret)) != MP_OKAY)                  goto cleanup;
6409          err = MP_OKAY;
6410          goto cleanup;
6411       }
6412       if ((err = mp_sub_d(&M, i, &t1)) != MP_OKAY)                goto cleanup;
6413       if ((err = mp_sub_d(&t1, 1uL, &t1)) != MP_OKAY)             goto cleanup;
6414       if ((err = mp_exptmod(&two, &t1, prime, &t1)) != MP_OKAY)   goto cleanup;
6415       /* t1 = 2 ^ (M - i - 1) */
6416       if ((err = mp_exptmod(&C, &t1, prime, &t1)) != MP_OKAY)     goto cleanup;
6417       /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
6418       if ((err = mp_sqrmod(&t1, prime, &C)) != MP_OKAY)           goto cleanup;
6419       /* C = (t1 * t1) mod prime */
6420       if ((err = mp_mulmod(&R, &t1, prime, &R)) != MP_OKAY)       goto cleanup;
6421       /* R = (R * t1) mod prime */
6422       if ((err = mp_mulmod(&T, &C, prime, &T)) != MP_OKAY)        goto cleanup;
6423       /* T = (T * C) mod prime */
6424       mp_set(&M, i);
6425       /* M = i */
6426    }
6427 
6428 cleanup:
6429    mp_clear_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL);
6430    return err;
6431 }
6432 
6433 #endif
6434 
6435 /* End: bn_mp_sqrtmod_prime.c */
6436 
6437 /* Start: bn_mp_sub.c */
6438 #include "tommath_private.h"
6439 #ifdef BN_MP_SUB_C
6440 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6441 /* SPDX-License-Identifier: Unlicense */
6442 
6443 /* high level subtraction (handles signs) */
mp_sub(const mp_int * a,const mp_int * b,mp_int * c)6444 mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
6445 {
6446    mp_sign sa = a->sign, sb = b->sign;
6447    mp_err err;
6448 
6449    if (sa != sb) {
6450       /* subtract a negative from a positive, OR */
6451       /* subtract a positive from a negative. */
6452       /* In either case, ADD their magnitudes, */
6453       /* and use the sign of the first number. */
6454       c->sign = sa;
6455       err = s_mp_add(a, b, c);
6456    } else {
6457       /* subtract a positive from a positive, OR */
6458       /* subtract a negative from a negative. */
6459       /* First, take the difference between their */
6460       /* magnitudes, then... */
6461       if (mp_cmp_mag(a, b) != MP_LT) {
6462          /* Copy the sign from the first */
6463          c->sign = sa;
6464          /* The first has a larger or equal magnitude */
6465          err = s_mp_sub(a, b, c);
6466       } else {
6467          /* The result has the *opposite* sign from */
6468          /* the first number. */
6469          c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
6470          /* The second has a larger magnitude */
6471          err = s_mp_sub(b, a, c);
6472       }
6473    }
6474    return err;
6475 }
6476 
6477 #endif
6478 
6479 /* End: bn_mp_sub.c */
6480 
6481 /* Start: bn_mp_sub_d.c */
6482 #include "tommath_private.h"
6483 #ifdef BN_MP_SUB_D_C
6484 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6485 /* SPDX-License-Identifier: Unlicense */
6486 
6487 /* single digit subtraction */
mp_sub_d(const mp_int * a,mp_digit b,mp_int * c)6488 mp_err mp_sub_d(const mp_int *a, mp_digit b, mp_int *c)
6489 {
6490    mp_digit *tmpa, *tmpc;
6491    mp_err    err;
6492    int       ix, oldused;
6493 
6494    /* grow c as required */
6495    if (c->alloc < (a->used + 1)) {
6496       if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) {
6497          return err;
6498       }
6499    }
6500 
6501    /* if a is negative just do an unsigned
6502     * addition [with fudged signs]
6503     */
6504    if (a->sign == MP_NEG) {
6505       mp_int a_ = *a;
6506       a_.sign = MP_ZPOS;
6507       err     = mp_add_d(&a_, b, c);
6508       c->sign = MP_NEG;
6509 
6510       /* clamp */
6511       mp_clamp(c);
6512 
6513       return err;
6514    }
6515 
6516    /* setup regs */
6517    oldused = c->used;
6518    tmpa    = a->dp;
6519    tmpc    = c->dp;
6520 
6521    /* if a <= b simply fix the single digit */
6522    if (((a->used == 1) && (a->dp[0] <= b)) || (a->used == 0)) {
6523       if (a->used == 1) {
6524          *tmpc++ = b - *tmpa;
6525       } else {
6526          *tmpc++ = b;
6527       }
6528       ix      = 1;
6529 
6530       /* negative/1digit */
6531       c->sign = MP_NEG;
6532       c->used = 1;
6533    } else {
6534       mp_digit mu = b;
6535 
6536       /* positive/size */
6537       c->sign = MP_ZPOS;
6538       c->used = a->used;
6539 
6540       /* subtract digits, mu is carry */
6541       for (ix = 0; ix < a->used; ix++) {
6542          *tmpc    = *tmpa++ - mu;
6543          mu       = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u);
6544          *tmpc++ &= MP_MASK;
6545       }
6546    }
6547 
6548    /* zero excess digits */
6549    MP_ZERO_DIGITS(tmpc, oldused - ix);
6550 
6551    mp_clamp(c);
6552    return MP_OKAY;
6553 }
6554 
6555 #endif
6556 
6557 /* End: bn_mp_sub_d.c */
6558 
6559 /* Start: bn_mp_submod.c */
6560 #include "tommath_private.h"
6561 #ifdef BN_MP_SUBMOD_C
6562 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6563 /* SPDX-License-Identifier: Unlicense */
6564 
6565 /* d = a - b (mod c) */
mp_submod(const mp_int * a,const mp_int * b,const mp_int * c,mp_int * d)6566 mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d)
6567 {
6568    mp_err err;
6569    mp_int t;
6570 
6571    if ((err = mp_init(&t)) != MP_OKAY) {
6572       return err;
6573    }
6574 
6575    if ((err = mp_sub(a, b, &t)) != MP_OKAY) {
6576       goto LBL_ERR;
6577    }
6578    err = mp_mod(&t, c, d);
6579 
6580 LBL_ERR:
6581    mp_clear(&t);
6582    return err;
6583 }
6584 #endif
6585 
6586 /* End: bn_mp_submod.c */
6587 
6588 /* Start: bn_mp_to_radix.c */
6589 #include "tommath_private.h"
6590 #ifdef BN_MP_TO_RADIX_C
6591 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6592 /* SPDX-License-Identifier: Unlicense */
6593 
6594 /* stores a bignum as a ASCII string in a given radix (2..64)
6595  *
6596  * Stores upto "size - 1" chars and always a NULL byte, puts the number of characters
6597  * written, including the '\0', in "written".
6598  */
mp_to_radix(const mp_int * a,char * str,size_t maxlen,size_t * written,int radix)6599 mp_err mp_to_radix(const mp_int *a, char *str, size_t maxlen, size_t *written, int radix)
6600 {
6601    size_t  digs;
6602    mp_err  err;
6603    mp_int  t;
6604    mp_digit d;
6605    char   *_s = str;
6606 
6607    /* check range of radix and size*/
6608    if (maxlen < 2u) {
6609       return MP_BUF;
6610    }
6611    if ((radix < 2) || (radix > 64)) {
6612       return MP_VAL;
6613    }
6614 
6615    /* quick out if its zero */
6616    if (MP_IS_ZERO(a)) {
6617       *str++ = '0';
6618       *str = '\0';
6619       if (written != NULL) {
6620          *written = 2u;
6621       }
6622       return MP_OKAY;
6623    }
6624 
6625    if ((err = mp_init_copy(&t, a)) != MP_OKAY) {
6626       return err;
6627    }
6628 
6629    /* if it is negative output a - */
6630    if (t.sign == MP_NEG) {
6631       /* we have to reverse our digits later... but not the - sign!! */
6632       ++_s;
6633 
6634       /* store the flag and mark the number as positive */
6635       *str++ = '-';
6636       t.sign = MP_ZPOS;
6637 
6638       /* subtract a char */
6639       --maxlen;
6640    }
6641    digs = 0u;
6642    while (!MP_IS_ZERO(&t)) {
6643       if (--maxlen < 1u) {
6644          /* no more room */
6645          err = MP_BUF;
6646          goto LBL_ERR;
6647       }
6648       if ((err = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
6649          goto LBL_ERR;
6650       }
6651       *str++ = mp_s_rmap[d];
6652       ++digs;
6653    }
6654    /* reverse the digits of the string.  In this case _s points
6655     * to the first digit [exluding the sign] of the number
6656     */
6657    s_mp_reverse((unsigned char *)_s, digs);
6658 
6659    /* append a NULL so the string is properly terminated */
6660    *str = '\0';
6661    digs++;
6662 
6663    if (written != NULL) {
6664       *written = (a->sign == MP_NEG) ? (digs + 1u): digs;
6665    }
6666 
6667 LBL_ERR:
6668    mp_clear(&t);
6669    return err;
6670 }
6671 
6672 #endif
6673 
6674 /* End: bn_mp_to_radix.c */
6675 
6676 /* Start: bn_mp_to_sbin.c */
6677 #include "tommath_private.h"
6678 #ifdef BN_MP_TO_SBIN_C
6679 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6680 /* SPDX-License-Identifier: Unlicense */
6681 
6682 /* store in signed [big endian] format */
mp_to_sbin(const mp_int * a,unsigned char * buf,size_t maxlen,size_t * written)6683 mp_err mp_to_sbin(const mp_int *a, unsigned char *buf, size_t maxlen, size_t *written)
6684 {
6685    mp_err err;
6686    if (maxlen == 0u) {
6687       return MP_BUF;
6688    }
6689    if ((err = mp_to_ubin(a, buf + 1, maxlen - 1u, written)) != MP_OKAY) {
6690       return err;
6691    }
6692    if (written != NULL) {
6693       (*written)++;
6694    }
6695    buf[0] = (a->sign == MP_ZPOS) ? (unsigned char)0 : (unsigned char)1;
6696    return MP_OKAY;
6697 }
6698 #endif
6699 
6700 /* End: bn_mp_to_sbin.c */
6701 
6702 /* Start: bn_mp_to_ubin.c */
6703 #include "tommath_private.h"
6704 #ifdef BN_MP_TO_UBIN_C
6705 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6706 /* SPDX-License-Identifier: Unlicense */
6707 
6708 /* store in unsigned [big endian] format */
mp_to_ubin(const mp_int * a,unsigned char * buf,size_t maxlen,size_t * written)6709 mp_err mp_to_ubin(const mp_int *a, unsigned char *buf, size_t maxlen, size_t *written)
6710 {
6711    size_t  x, count;
6712    mp_err  err;
6713    mp_int  t;
6714 
6715    count = mp_ubin_size(a);
6716    if (count > maxlen) {
6717       return MP_BUF;
6718    }
6719 
6720    if ((err = mp_init_copy(&t, a)) != MP_OKAY) {
6721       return err;
6722    }
6723 
6724    for (x = count; x --> 0u;) {
6725 #ifndef MP_8BIT
6726       buf[x] = (unsigned char)(t.dp[0] & 255u);
6727 #else
6728       buf[x] = (unsigned char)(t.dp[0] | ((t.dp[1] & 1u) << 7));
6729 #endif
6730       if ((err = mp_div_2d(&t, 8, &t, NULL)) != MP_OKAY) {
6731          goto LBL_ERR;
6732       }
6733    }
6734 
6735    if (written != NULL) {
6736       *written = count;
6737    }
6738 
6739 LBL_ERR:
6740    mp_clear(&t);
6741    return err;
6742 }
6743 #endif
6744 
6745 /* End: bn_mp_to_ubin.c */
6746 
6747 /* Start: bn_mp_ubin_size.c */
6748 #include "tommath_private.h"
6749 #ifdef BN_MP_UBIN_SIZE_C
6750 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6751 /* SPDX-License-Identifier: Unlicense */
6752 
6753 /* get the size for an unsigned equivalent */
mp_ubin_size(const mp_int * a)6754 size_t mp_ubin_size(const mp_int *a)
6755 {
6756    size_t size = (size_t)mp_count_bits(a);
6757    return (size / 8u) + (((size & 7u) != 0u) ? 1u : 0u);
6758 }
6759 #endif
6760 
6761 /* End: bn_mp_ubin_size.c */
6762 
6763 /* Start: bn_mp_unpack.c */
6764 #include "tommath_private.h"
6765 #ifdef BN_MP_UNPACK_C
6766 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6767 /* SPDX-License-Identifier: Unlicense */
6768 
6769 /* based on gmp's mpz_import.
6770  * see http://gmplib.org/manual/Integer-Import-and-Export.html
6771  */
mp_unpack(mp_int * rop,size_t count,mp_order order,size_t size,mp_endian endian,size_t nails,const void * op)6772 mp_err mp_unpack(mp_int *rop, size_t count, mp_order order, size_t size,
6773                  mp_endian endian, size_t nails, const void *op)
6774 {
6775    mp_err err;
6776    size_t odd_nails, nail_bytes, i, j;
6777    unsigned char odd_nail_mask;
6778 
6779    mp_zero(rop);
6780 
6781    if (endian == MP_NATIVE_ENDIAN) {
6782       MP_GET_ENDIANNESS(endian);
6783    }
6784 
6785    odd_nails = (nails % 8u);
6786    odd_nail_mask = 0xff;
6787    for (i = 0; i < odd_nails; ++i) {
6788       odd_nail_mask ^= (unsigned char)(1u << (7u - i));
6789    }
6790    nail_bytes = nails / 8u;
6791 
6792    for (i = 0; i < count; ++i) {
6793       for (j = 0; j < (size - nail_bytes); ++j) {
6794          unsigned char byte = *((const unsigned char *)op +
6795                                 (((order == MP_MSB_FIRST) ? i : ((count - 1u) - i)) * size) +
6796                                 ((endian == MP_BIG_ENDIAN) ? (j + nail_bytes) : (((size - 1u) - j) - nail_bytes)));
6797 
6798          if ((err = mp_mul_2d(rop, (j == 0u) ? (int)(8u - odd_nails) : 8, rop)) != MP_OKAY) {
6799             return err;
6800          }
6801 
6802          rop->dp[0] |= (j == 0u) ? (mp_digit)(byte & odd_nail_mask) : (mp_digit)byte;
6803          rop->used  += 1;
6804       }
6805    }
6806 
6807    mp_clamp(rop);
6808 
6809    return MP_OKAY;
6810 }
6811 
6812 #endif
6813 
6814 /* End: bn_mp_unpack.c */
6815 
6816 /* Start: bn_mp_xor.c */
6817 #include "tommath_private.h"
6818 #ifdef BN_MP_XOR_C
6819 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6820 /* SPDX-License-Identifier: Unlicense */
6821 
6822 /* two complement xor */
mp_xor(const mp_int * a,const mp_int * b,mp_int * c)6823 mp_err mp_xor(const mp_int *a, const mp_int *b, mp_int *c)
6824 {
6825    int used = MP_MAX(a->used, b->used) + 1, i;
6826    mp_err err;
6827    mp_digit ac = 1, bc = 1, cc = 1;
6828    mp_sign csign = (a->sign != b->sign) ? MP_NEG : MP_ZPOS;
6829 
6830    if (c->alloc < used) {
6831       if ((err = mp_grow(c, used)) != MP_OKAY) {
6832          return err;
6833       }
6834    }
6835 
6836    for (i = 0; i < used; i++) {
6837       mp_digit x, y;
6838 
6839       /* convert to two complement if negative */
6840       if (a->sign == MP_NEG) {
6841          ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK);
6842          x = ac & MP_MASK;
6843          ac >>= MP_DIGIT_BIT;
6844       } else {
6845          x = (i >= a->used) ? 0uL : a->dp[i];
6846       }
6847 
6848       /* convert to two complement if negative */
6849       if (b->sign == MP_NEG) {
6850          bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK);
6851          y = bc & MP_MASK;
6852          bc >>= MP_DIGIT_BIT;
6853       } else {
6854          y = (i >= b->used) ? 0uL : b->dp[i];
6855       }
6856 
6857       c->dp[i] = x ^ y;
6858 
6859       /* convert to to sign-magnitude if negative */
6860       if (csign == MP_NEG) {
6861          cc += ~c->dp[i] & MP_MASK;
6862          c->dp[i] = cc & MP_MASK;
6863          cc >>= MP_DIGIT_BIT;
6864       }
6865    }
6866 
6867    c->used = used;
6868    c->sign = csign;
6869    mp_clamp(c);
6870    return MP_OKAY;
6871 }
6872 #endif
6873 
6874 /* End: bn_mp_xor.c */
6875 
6876 /* Start: bn_mp_zero.c */
6877 #include "tommath_private.h"
6878 #ifdef BN_MP_ZERO_C
6879 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6880 /* SPDX-License-Identifier: Unlicense */
6881 
6882 /* set to zero */
mp_zero(mp_int * a)6883 void mp_zero(mp_int *a)
6884 {
6885    a->sign = MP_ZPOS;
6886    a->used = 0;
6887    MP_ZERO_DIGITS(a->dp, a->alloc);
6888 }
6889 #endif
6890 
6891 /* End: bn_mp_zero.c */
6892 
6893 /* Start: bn_prime_tab.c */
6894 #include "tommath_private.h"
6895 #ifdef BN_PRIME_TAB_C
6896 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6897 /* SPDX-License-Identifier: Unlicense */
6898 
6899 const mp_digit ltm_prime_tab[] = {
6900    0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
6901    0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
6902    0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
6903    0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
6904 #ifndef MP_8BIT
6905    0x0083,
6906    0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
6907    0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
6908    0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
6909    0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
6910 
6911    0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
6912    0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
6913    0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
6914    0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
6915    0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
6916    0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
6917    0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
6918    0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
6919 
6920    0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
6921    0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
6922    0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
6923    0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
6924    0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
6925    0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
6926    0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
6927    0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
6928 
6929    0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
6930    0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
6931    0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
6932    0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
6933    0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
6934    0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
6935    0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
6936    0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
6937 #endif
6938 };
6939 
6940 #if defined(__GNUC__) && __GNUC__ >= 4
6941 #pragma GCC diagnostic push
6942 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
6943 const mp_digit *s_mp_prime_tab = ltm_prime_tab;
6944 #pragma GCC diagnostic pop
6945 #elif defined(_MSC_VER) && _MSC_VER >= 1500
6946 #pragma warning(push)
6947 #pragma warning(disable: 4996)
6948 const mp_digit *s_mp_prime_tab = ltm_prime_tab;
6949 #pragma warning(pop)
6950 #else
6951 const mp_digit *s_mp_prime_tab = ltm_prime_tab;
6952 #endif
6953 
6954 #endif
6955 
6956 /* End: bn_prime_tab.c */
6957 
6958 /* Start: bn_s_mp_add.c */
6959 #include "tommath_private.h"
6960 #ifdef BN_S_MP_ADD_C
6961 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
6962 /* SPDX-License-Identifier: Unlicense */
6963 
6964 /* low level addition, based on HAC pp.594, Algorithm 14.7 */
s_mp_add(const mp_int * a,const mp_int * b,mp_int * c)6965 mp_err s_mp_add(const mp_int *a, const mp_int *b, mp_int *c)
6966 {
6967    const mp_int *x;
6968    mp_err err;
6969    int     olduse, min, max;
6970 
6971    /* find sizes, we let |a| <= |b| which means we have to sort
6972     * them.  "x" will point to the input with the most digits
6973     */
6974    if (a->used > b->used) {
6975       min = b->used;
6976       max = a->used;
6977       x = a;
6978    } else {
6979       min = a->used;
6980       max = b->used;
6981       x = b;
6982    }
6983 
6984    /* init result */
6985    if (c->alloc < (max + 1)) {
6986       if ((err = mp_grow(c, max + 1)) != MP_OKAY) {
6987          return err;
6988       }
6989    }
6990 
6991    /* get old used digit count and set new one */
6992    olduse = c->used;
6993    c->used = max + 1;
6994 
6995    {
6996       mp_digit u, *tmpa, *tmpb, *tmpc;
6997       int i;
6998 
6999       /* alias for digit pointers */
7000 
7001       /* first input */
7002       tmpa = a->dp;
7003 
7004       /* second input */
7005       tmpb = b->dp;
7006 
7007       /* destination */
7008       tmpc = c->dp;
7009 
7010       /* zero the carry */
7011       u = 0;
7012       for (i = 0; i < min; i++) {
7013          /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
7014          *tmpc = *tmpa++ + *tmpb++ + u;
7015 
7016          /* U = carry bit of T[i] */
7017          u = *tmpc >> (mp_digit)MP_DIGIT_BIT;
7018 
7019          /* take away carry bit from T[i] */
7020          *tmpc++ &= MP_MASK;
7021       }
7022 
7023       /* now copy higher words if any, that is in A+B
7024        * if A or B has more digits add those in
7025        */
7026       if (min != max) {
7027          for (; i < max; i++) {
7028             /* T[i] = X[i] + U */
7029             *tmpc = x->dp[i] + u;
7030 
7031             /* U = carry bit of T[i] */
7032             u = *tmpc >> (mp_digit)MP_DIGIT_BIT;
7033 
7034             /* take away carry bit from T[i] */
7035             *tmpc++ &= MP_MASK;
7036          }
7037       }
7038 
7039       /* add carry */
7040       *tmpc++ = u;
7041 
7042       /* clear digits above oldused */
7043       MP_ZERO_DIGITS(tmpc, olduse - c->used);
7044    }
7045 
7046    mp_clamp(c);
7047    return MP_OKAY;
7048 }
7049 #endif
7050 
7051 /* End: bn_s_mp_add.c */
7052 
7053 /* Start: bn_s_mp_balance_mul.c */
7054 #include "tommath_private.h"
7055 #ifdef BN_S_MP_BALANCE_MUL_C
7056 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
7057 /* SPDX-License-Identifier: Unlicense */
7058 
7059 /* single-digit multiplication with the smaller number as the single-digit */
s_mp_balance_mul(const mp_int * a,const mp_int * b,mp_int * c)7060 mp_err s_mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c)
7061 {
7062    int count, len_a, len_b, nblocks, i, j, bsize;
7063    mp_int a0, tmp, A, B, r;
7064    mp_err err;
7065 
7066    len_a = a->used;
7067    len_b = b->used;
7068 
7069    nblocks = MP_MAX(a->used, b->used) / MP_MIN(a->used, b->used);
7070    bsize = MP_MIN(a->used, b->used) ;
7071 
7072    if ((err = mp_init_size(&a0, bsize + 2)) != MP_OKAY) {
7073       return err;
7074    }
7075    if ((err = mp_init_multi(&tmp, &r, NULL)) != MP_OKAY) {
7076       mp_clear(&a0);
7077       return err;
7078    }
7079 
7080    /* Make sure that A is the larger one*/
7081    if (len_a < len_b) {
7082       B = *a;
7083       A = *b;
7084    } else {
7085       A = *a;
7086       B = *b;
7087    }
7088 
7089    for (i = 0, j=0; i < nblocks; i++) {
7090       /* Cut a slice off of a */
7091       a0.used = 0;
7092       for (count = 0; count < bsize; count++) {
7093          a0.dp[count] = A.dp[ j++ ];
7094          a0.used++;
7095       }
7096       mp_clamp(&a0);
7097       /* Multiply with b */
7098       if ((err = mp_mul(&a0, &B, &tmp)) != MP_OKAY) {
7099          goto LBL_ERR;
7100       }
7101       /* Shift tmp to the correct position */
7102       if ((err = mp_lshd(&tmp, bsize * i)) != MP_OKAY) {
7103          goto LBL_ERR;
7104       }
7105       /* Add to output. No carry needed */
7106       if ((err = mp_add(&r, &tmp, &r)) != MP_OKAY) {
7107          goto LBL_ERR;
7108       }
7109    }
7110    /* The left-overs; there are always left-overs */
7111    if (j < A.used) {
7112       a0.used = 0;
7113       for (count = 0; j < A.used; count++) {
7114          a0.dp[count] = A.dp[ j++ ];
7115          a0.used++;
7116       }
7117       mp_clamp(&a0);
7118       if ((err = mp_mul(&a0, &B, &tmp)) != MP_OKAY) {
7119          goto LBL_ERR;
7120       }
7121       if ((err = mp_lshd(&tmp, bsize * i)) != MP_OKAY) {
7122          goto LBL_ERR;
7123       }
7124       if ((err = mp_add(&r, &tmp, &r)) != MP_OKAY) {
7125          goto LBL_ERR;
7126       }
7127    }
7128 
7129    mp_exch(&r,c);
7130 LBL_ERR:
7131    mp_clear_multi(&a0, &tmp, &r,NULL);
7132    return err;
7133 }
7134 #endif
7135 
7136 /* End: bn_s_mp_balance_mul.c */
7137 
7138 /* Start: bn_s_mp_exptmod.c */
7139 #include "tommath_private.h"
7140 #ifdef BN_S_MP_EXPTMOD_C
7141 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
7142 /* SPDX-License-Identifier: Unlicense */
7143 
7144 #ifdef MP_LOW_MEM
7145 #   define TAB_SIZE 32
7146 #   define MAX_WINSIZE 5
7147 #else
7148 #   define TAB_SIZE 256
7149 #   define MAX_WINSIZE 0
7150 #endif
7151 
s_mp_exptmod(const mp_int * G,const mp_int * X,const mp_int * P,mp_int * Y,int redmode)7152 mp_err s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode)
7153 {
7154    mp_int  M[TAB_SIZE], res, mu;
7155    mp_digit buf;
7156    mp_err   err;
7157    int      bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
7158    mp_err(*redux)(mp_int *x, const mp_int *m, const mp_int *mu);
7159 
7160    /* find window size */
7161    x = mp_count_bits(X);
7162    if (x <= 7) {
7163       winsize = 2;
7164    } else if (x <= 36) {
7165       winsize = 3;
7166    } else if (x <= 140) {
7167       winsize = 4;
7168    } else if (x <= 450) {
7169       winsize = 5;
7170    } else if (x <= 1303) {
7171       winsize = 6;
7172    } else if (x <= 3529) {
7173       winsize = 7;
7174    } else {
7175       winsize = 8;
7176    }
7177 
7178    winsize = MAX_WINSIZE ? MP_MIN(MAX_WINSIZE, winsize) : winsize;
7179 
7180    /* init M array */
7181    /* init first cell */
7182    if ((err = mp_init(&M[1])) != MP_OKAY) {
7183       return err;
7184    }
7185 
7186    /* now init the second half of the array */
7187    for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
7188       if ((err = mp_init(&M[x])) != MP_OKAY) {
7189          for (y = 1<<(winsize-1); y < x; y++) {
7190             mp_clear(&M[y]);
7191          }
7192          mp_clear(&M[1]);
7193          return err;
7194       }
7195    }
7196 
7197    /* create mu, used for Barrett reduction */
7198    if ((err = mp_init(&mu)) != MP_OKAY)                           goto LBL_M;
7199 
7200    if (redmode == 0) {
7201       if ((err = mp_reduce_setup(&mu, P)) != MP_OKAY)             goto LBL_MU;
7202       redux = mp_reduce;
7203    } else {
7204       if ((err = mp_reduce_2k_setup_l(P, &mu)) != MP_OKAY)        goto LBL_MU;
7205       redux = mp_reduce_2k_l;
7206    }
7207 
7208    /* create M table
7209     *
7210     * The M table contains powers of the base,
7211     * e.g. M[x] = G**x mod P
7212     *
7213     * The first half of the table is not
7214     * computed though accept for M[0] and M[1]
7215     */
7216    if ((err = mp_mod(G, P, &M[1])) != MP_OKAY)                    goto LBL_MU;
7217 
7218    /* compute the value at M[1<<(winsize-1)] by squaring
7219     * M[1] (winsize-1) times
7220     */
7221    if ((err = mp_copy(&M[1], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) goto LBL_MU;
7222 
7223    for (x = 0; x < (winsize - 1); x++) {
7224       /* square it */
7225       if ((err = mp_sqr(&M[(size_t)1 << (winsize - 1)],
7226                         &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) goto LBL_MU;
7227 
7228       /* reduce modulo P */
7229       if ((err = redux(&M[(size_t)1 << (winsize - 1)], P, &mu)) != MP_OKAY) goto LBL_MU;
7230    }
7231 
7232    /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
7233     * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
7234     */
7235    for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
7236       if ((err = mp_mul(&M[x - 1], &M[1], &M[x])) != MP_OKAY)     goto LBL_MU;
7237       if ((err = redux(&M[x], P, &mu)) != MP_OKAY)                goto LBL_MU;
7238    }
7239 
7240    /* setup result */
7241    if ((err = mp_init(&res)) != MP_OKAY)                          goto LBL_MU;
7242    mp_set(&res, 1uL);
7243 
7244    /* set initial mode and bit cnt */
7245    mode   = 0;
7246    bitcnt = 1;
7247    buf    = 0;
7248    digidx = X->used - 1;
7249    bitcpy = 0;
7250    bitbuf = 0;
7251 
7252    for (;;) {
7253       /* grab next digit as required */
7254       if (--bitcnt == 0) {
7255          /* if digidx == -1 we are out of digits */
7256          if (digidx == -1) {
7257             break;
7258          }
7259          /* read next digit and reset the bitcnt */
7260          buf    = X->dp[digidx--];
7261          bitcnt = (int)MP_DIGIT_BIT;
7262       }
7263 
7264       /* grab the next msb from the exponent */
7265       y     = (buf >> (mp_digit)(MP_DIGIT_BIT - 1)) & 1uL;
7266       buf <<= (mp_digit)1;
7267 
7268       /* if the bit is zero and mode == 0 then we ignore it
7269        * These represent the leading zero bits before the first 1 bit
7270        * in the exponent.  Technically this opt is not required but it
7271        * does lower the # of trivial squaring/reductions used
7272        */
7273       if ((mode == 0) && (y == 0)) {
7274          continue;
7275       }
7276 
7277       /* if the bit is zero and mode == 1 then we square */
7278       if ((mode == 1) && (y == 0)) {
7279          if ((err = mp_sqr(&res, &res)) != MP_OKAY)               goto LBL_RES;
7280          if ((err = redux(&res, P, &mu)) != MP_OKAY)              goto LBL_RES;
7281          continue;
7282       }
7283 
7284       /* else we add it to the window */
7285       bitbuf |= (y << (winsize - ++bitcpy));
7286       mode    = 2;
7287 
7288       if (bitcpy == winsize) {
7289          /* ok window is filled so square as required and multiply  */
7290          /* square first */
7291          for (x = 0; x < winsize; x++) {
7292             if ((err = mp_sqr(&res, &res)) != MP_OKAY)            goto LBL_RES;
7293             if ((err = redux(&res, P, &mu)) != MP_OKAY)           goto LBL_RES;
7294          }
7295 
7296          /* then multiply */
7297          if ((err = mp_mul(&res, &M[bitbuf], &res)) != MP_OKAY)  goto LBL_RES;
7298          if ((err = redux(&res, P, &mu)) != MP_OKAY)             goto LBL_RES;
7299 
7300          /* empty window and reset */
7301          bitcpy = 0;
7302          bitbuf = 0;
7303          mode   = 1;
7304       }
7305    }
7306 
7307    /* if bits remain then square/multiply */
7308    if ((mode == 2) && (bitcpy > 0)) {
7309       /* square then multiply if the bit is set */
7310       for (x = 0; x < bitcpy; x++) {
7311          if ((err = mp_sqr(&res, &res)) != MP_OKAY)               goto LBL_RES;
7312          if ((err = redux(&res, P, &mu)) != MP_OKAY)              goto LBL_RES;
7313 
7314          bitbuf <<= 1;
7315          if ((bitbuf & (1 << winsize)) != 0) {
7316             /* then multiply */
7317             if ((err = mp_mul(&res, &M[1], &res)) != MP_OKAY)     goto LBL_RES;
7318             if ((err = redux(&res, P, &mu)) != MP_OKAY)           goto LBL_RES;
7319          }
7320       }
7321    }
7322 
7323    mp_exch(&res, Y);
7324    err = MP_OKAY;
7325 LBL_RES:
7326    mp_clear(&res);
7327 LBL_MU:
7328    mp_clear(&mu);
7329 LBL_M:
7330    mp_clear(&M[1]);
7331    for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
7332       mp_clear(&M[x]);
7333    }
7334    return err;
7335 }
7336 #endif
7337 
7338 /* End: bn_s_mp_exptmod.c */
7339 
7340 /* Start: bn_s_mp_exptmod_fast.c */
7341 #include "tommath_private.h"
7342 #ifdef BN_S_MP_EXPTMOD_FAST_C
7343 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
7344 /* SPDX-License-Identifier: Unlicense */
7345 
7346 /* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
7347  *
7348  * Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
7349  * The value of k changes based on the size of the exponent.
7350  *
7351  * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
7352  */
7353 
7354 #ifdef MP_LOW_MEM
7355 #   define TAB_SIZE 32
7356 #   define MAX_WINSIZE 5
7357 #else
7358 #   define TAB_SIZE 256
7359 #   define MAX_WINSIZE 0
7360 #endif
7361 
s_mp_exptmod_fast(const mp_int * G,const mp_int * X,const mp_int * P,mp_int * Y,int redmode)7362 mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode)
7363 {
7364    mp_int  M[TAB_SIZE], res;
7365    mp_digit buf, mp;
7366    int     bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
7367    mp_err   err;
7368 
7369    /* use a pointer to the reduction algorithm.  This allows us to use
7370     * one of many reduction algorithms without modding the guts of
7371     * the code with if statements everywhere.
7372     */
7373    mp_err(*redux)(mp_int *x, const mp_int *n, mp_digit rho);
7374 
7375    /* find window size */
7376    x = mp_count_bits(X);
7377    if (x <= 7) {
7378       winsize = 2;
7379    } else if (x <= 36) {
7380       winsize = 3;
7381    } else if (x <= 140) {
7382       winsize = 4;
7383    } else if (x <= 450) {
7384       winsize = 5;
7385    } else if (x <= 1303) {
7386       winsize = 6;
7387    } else if (x <= 3529) {
7388       winsize = 7;
7389    } else {
7390       winsize = 8;
7391    }
7392 
7393    winsize = MAX_WINSIZE ? MP_MIN(MAX_WINSIZE, winsize) : winsize;
7394 
7395    /* init M array */
7396    /* init first cell */
7397    if ((err = mp_init_size(&M[1], P->alloc)) != MP_OKAY) {
7398       return err;
7399    }
7400 
7401    /* now init the second half of the array */
7402    for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
7403       if ((err = mp_init_size(&M[x], P->alloc)) != MP_OKAY) {
7404          for (y = 1<<(winsize-1); y < x; y++) {
7405             mp_clear(&M[y]);
7406          }
7407          mp_clear(&M[1]);
7408          return err;
7409       }
7410    }
7411 
7412    /* determine and setup reduction code */
7413    if (redmode == 0) {
7414       if (MP_HAS(MP_MONTGOMERY_SETUP)) {
7415          /* now setup montgomery  */
7416          if ((err = mp_montgomery_setup(P, &mp)) != MP_OKAY)      goto LBL_M;
7417       } else {
7418          err = MP_VAL;
7419          goto LBL_M;
7420       }
7421 
7422       /* automatically pick the comba one if available (saves quite a few calls/ifs) */
7423       if (MP_HAS(S_MP_MONTGOMERY_REDUCE_FAST) &&
7424           (((P->used * 2) + 1) < MP_WARRAY) &&
7425           (P->used < MP_MAXFAST)) {
7426          redux = s_mp_montgomery_reduce_fast;
7427       } else if (MP_HAS(MP_MONTGOMERY_REDUCE)) {
7428          /* use slower baseline Montgomery method */
7429          redux = mp_montgomery_reduce;
7430       } else {
7431          err = MP_VAL;
7432          goto LBL_M;
7433       }
7434    } else if (redmode == 1) {
7435       if (MP_HAS(MP_DR_SETUP) && MP_HAS(MP_DR_REDUCE)) {
7436          /* setup DR reduction for moduli of the form B**k - b */
7437          mp_dr_setup(P, &mp);
7438          redux = mp_dr_reduce;
7439       } else {
7440          err = MP_VAL;
7441          goto LBL_M;
7442       }
7443    } else if (MP_HAS(MP_REDUCE_2K_SETUP) && MP_HAS(MP_REDUCE_2K)) {
7444       /* setup DR reduction for moduli of the form 2**k - b */
7445       if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY)          goto LBL_M;
7446       redux = mp_reduce_2k;
7447    } else {
7448       err = MP_VAL;
7449       goto LBL_M;
7450    }
7451 
7452    /* setup result */
7453    if ((err = mp_init_size(&res, P->alloc)) != MP_OKAY)           goto LBL_M;
7454 
7455    /* create M table
7456     *
7457 
7458     *
7459     * The first half of the table is not computed though accept for M[0] and M[1]
7460     */
7461 
7462    if (redmode == 0) {
7463       if (MP_HAS(MP_MONTGOMERY_CALC_NORMALIZATION)) {
7464          /* now we need R mod m */
7465          if ((err = mp_montgomery_calc_normalization(&res, P)) != MP_OKAY) goto LBL_RES;
7466 
7467          /* now set M[1] to G * R mod m */
7468          if ((err = mp_mulmod(G, &res, P, &M[1])) != MP_OKAY)     goto LBL_RES;
7469       } else {
7470          err = MP_VAL;
7471          goto LBL_RES;
7472       }
7473    } else {
7474       mp_set(&res, 1uL);
7475       if ((err = mp_mod(G, P, &M[1])) != MP_OKAY)                 goto LBL_RES;
7476    }
7477 
7478    /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
7479    if ((err = mp_copy(&M[1], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) goto LBL_RES;
7480 
7481    for (x = 0; x < (winsize - 1); x++) {
7482       if ((err = mp_sqr(&M[(size_t)1 << (winsize - 1)], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) goto LBL_RES;
7483       if ((err = redux(&M[(size_t)1 << (winsize - 1)], P, mp)) != MP_OKAY) goto LBL_RES;
7484    }
7485 
7486    /* create upper table */
7487    for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
7488       if ((err = mp_mul(&M[x - 1], &M[1], &M[x])) != MP_OKAY)     goto LBL_RES;
7489       if ((err = redux(&M[x], P, mp)) != MP_OKAY)                 goto LBL_RES;
7490    }
7491 
7492    /* set initial mode and bit cnt */
7493    mode   = 0;
7494    bitcnt = 1;
7495    buf    = 0;
7496    digidx = X->used - 1;
7497    bitcpy = 0;
7498    bitbuf = 0;
7499 
7500    for (;;) {
7501       /* grab next digit as required */
7502       if (--bitcnt == 0) {
7503          /* if digidx == -1 we are out of digits so break */
7504          if (digidx == -1) {
7505             break;
7506          }
7507          /* read next digit and reset bitcnt */
7508          buf    = X->dp[digidx--];
7509          bitcnt = (int)MP_DIGIT_BIT;
7510       }
7511 
7512       /* grab the next msb from the exponent */
7513       y     = (mp_digit)(buf >> (MP_DIGIT_BIT - 1)) & 1uL;
7514       buf <<= (mp_digit)1;
7515 
7516       /* if the bit is zero and mode == 0 then we ignore it
7517        * These represent the leading zero bits before the first 1 bit
7518        * in the exponent.  Technically this opt is not required but it
7519        * does lower the # of trivial squaring/reductions used
7520        */
7521       if ((mode == 0) && (y == 0)) {
7522          continue;
7523       }
7524 
7525       /* if the bit is zero and mode == 1 then we square */
7526       if ((mode == 1) && (y == 0)) {
7527          if ((err = mp_sqr(&res, &res)) != MP_OKAY)               goto LBL_RES;
7528          if ((err = redux(&res, P, mp)) != MP_OKAY)               goto LBL_RES;
7529          continue;
7530       }
7531 
7532       /* else we add it to the window */
7533       bitbuf |= (y << (winsize - ++bitcpy));
7534       mode    = 2;
7535 
7536       if (bitcpy == winsize) {
7537          /* ok window is filled so square as required and multiply  */
7538          /* square first */
7539          for (x = 0; x < winsize; x++) {
7540             if ((err = mp_sqr(&res, &res)) != MP_OKAY)            goto LBL_RES;
7541             if ((err = redux(&res, P, mp)) != MP_OKAY)            goto LBL_RES;
7542          }
7543 
7544          /* then multiply */
7545          if ((err = mp_mul(&res, &M[bitbuf], &res)) != MP_OKAY)   goto LBL_RES;
7546          if ((err = redux(&res, P, mp)) != MP_OKAY)               goto LBL_RES;
7547 
7548          /* empty window and reset */
7549          bitcpy = 0;
7550          bitbuf = 0;
7551          mode   = 1;
7552       }
7553    }
7554 
7555    /* if bits remain then square/multiply */
7556    if ((mode == 2) && (bitcpy > 0)) {
7557       /* square then multiply if the bit is set */
7558       for (x = 0; x < bitcpy; x++) {
7559          if ((err = mp_sqr(&res, &res)) != MP_OKAY)               goto LBL_RES;
7560          if ((err = redux(&res, P, mp)) != MP_OKAY)               goto LBL_RES;
7561 
7562          /* get next bit of the window */
7563          bitbuf <<= 1;
7564          if ((bitbuf & (1 << winsize)) != 0) {
7565             /* then multiply */
7566             if ((err = mp_mul(&res, &M[1], &res)) != MP_OKAY)     goto LBL_RES;
7567             if ((err = redux(&res, P, mp)) != MP_OKAY)            goto LBL_RES;
7568          }
7569       }
7570    }
7571 
7572    if (redmode == 0) {
7573       /* fixup result if Montgomery reduction is used
7574        * recall that any value in a Montgomery system is
7575        * actually multiplied by R mod n.  So we have
7576        * to reduce one more time to cancel out the factor
7577        * of R.
7578        */
7579       if ((err = redux(&res, P, mp)) != MP_OKAY)                  goto LBL_RES;
7580    }
7581 
7582    /* swap res with Y */
7583    mp_exch(&res, Y);
7584    err = MP_OKAY;
7585 LBL_RES:
7586    mp_clear(&res);
7587 LBL_M:
7588    mp_clear(&M[1]);
7589    for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
7590       mp_clear(&M[x]);
7591    }
7592    return err;
7593 }
7594 #endif
7595 
7596 /* End: bn_s_mp_exptmod_fast.c */
7597 
7598 /* Start: bn_s_mp_get_bit.c */
7599 #include "tommath_private.h"
7600 #ifdef BN_S_MP_GET_BIT_C
7601 
7602 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
7603 /* SPDX-License-Identifier: Unlicense */
7604 
7605 /* Get bit at position b and return MP_YES if the bit is 1, MP_NO if it is 0 */
s_mp_get_bit(const mp_int * a,unsigned int b)7606 mp_bool s_mp_get_bit(const mp_int *a, unsigned int b)
7607 {
7608    mp_digit bit;
7609    int limb = (int)(b / MP_DIGIT_BIT);
7610 
7611    if (limb >= a->used) {
7612       return MP_NO;
7613    }
7614 
7615    bit = (mp_digit)1 << (b % MP_DIGIT_BIT);
7616    return ((a->dp[limb] & bit) != 0u) ? MP_YES : MP_NO;
7617 }
7618 
7619 #endif
7620 
7621 /* End: bn_s_mp_get_bit.c */
7622 
7623 /* Start: bn_s_mp_invmod_fast.c */
7624 #include "tommath_private.h"
7625 #ifdef BN_S_MP_INVMOD_FAST_C
7626 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
7627 /* SPDX-License-Identifier: Unlicense */
7628 
7629 /* computes the modular inverse via binary extended euclidean algorithm,
7630  * that is c = 1/a mod b
7631  *
7632  * Based on slow invmod except this is optimized for the case where b is
7633  * odd as per HAC Note 14.64 on pp. 610
7634  */
s_mp_invmod_fast(const mp_int * a,const mp_int * b,mp_int * c)7635 mp_err s_mp_invmod_fast(const mp_int *a, const mp_int *b, mp_int *c)
7636 {
7637    mp_int  x, y, u, v, B, D;
7638    mp_sign neg;
7639    mp_err  err;
7640 
7641    /* 2. [modified] b must be odd   */
7642    if (MP_IS_EVEN(b)) {
7643       return MP_VAL;
7644    }
7645 
7646    /* init all our temps */
7647    if ((err = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
7648       return err;
7649    }
7650 
7651    /* x == modulus, y == value to invert */
7652    if ((err = mp_copy(b, &x)) != MP_OKAY)                         goto LBL_ERR;
7653 
7654    /* we need y = |a| */
7655    if ((err = mp_mod(a, b, &y)) != MP_OKAY)                       goto LBL_ERR;
7656 
7657    /* if one of x,y is zero return an error! */
7658    if (MP_IS_ZERO(&x) || MP_IS_ZERO(&y)) {
7659       err = MP_VAL;
7660       goto LBL_ERR;
7661    }
7662 
7663    /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
7664    if ((err = mp_copy(&x, &u)) != MP_OKAY)                        goto LBL_ERR;
7665    if ((err = mp_copy(&y, &v)) != MP_OKAY)                        goto LBL_ERR;
7666    mp_set(&D, 1uL);
7667 
7668 top:
7669    /* 4.  while u is even do */
7670    while (MP_IS_EVEN(&u)) {
7671       /* 4.1 u = u/2 */
7672       if ((err = mp_div_2(&u, &u)) != MP_OKAY)                    goto LBL_ERR;
7673 
7674       /* 4.2 if B is odd then */
7675       if (MP_IS_ODD(&B)) {
7676          if ((err = mp_sub(&B, &x, &B)) != MP_OKAY)               goto LBL_ERR;
7677       }
7678       /* B = B/2 */
7679       if ((err = mp_div_2(&B, &B)) != MP_OKAY)                    goto LBL_ERR;
7680    }
7681 
7682    /* 5.  while v is even do */
7683    while (MP_IS_EVEN(&v)) {
7684       /* 5.1 v = v/2 */
7685       if ((err = mp_div_2(&v, &v)) != MP_OKAY)                    goto LBL_ERR;
7686 
7687       /* 5.2 if D is odd then */
7688       if (MP_IS_ODD(&D)) {
7689          /* D = (D-x)/2 */
7690          if ((err = mp_sub(&D, &x, &D)) != MP_OKAY)               goto LBL_ERR;
7691       }
7692       /* D = D/2 */
7693       if ((err = mp_div_2(&D, &D)) != MP_OKAY)                    goto LBL_ERR;
7694    }
7695 
7696    /* 6.  if u >= v then */
7697    if (mp_cmp(&u, &v) != MP_LT) {
7698       /* u = u - v, B = B - D */
7699       if ((err = mp_sub(&u, &v, &u)) != MP_OKAY)                  goto LBL_ERR;
7700 
7701       if ((err = mp_sub(&B, &D, &B)) != MP_OKAY)                  goto LBL_ERR;
7702    } else {
7703       /* v - v - u, D = D - B */
7704       if ((err = mp_sub(&v, &u, &v)) != MP_OKAY)                  goto LBL_ERR;
7705 
7706       if ((err = mp_sub(&D, &B, &D)) != MP_OKAY)                  goto LBL_ERR;
7707    }
7708 
7709    /* if not zero goto step 4 */
7710    if (!MP_IS_ZERO(&u)) {
7711       goto top;
7712    }
7713 
7714    /* now a = C, b = D, gcd == g*v */
7715 
7716    /* if v != 1 then there is no inverse */
7717    if (mp_cmp_d(&v, 1uL) != MP_EQ) {
7718       err = MP_VAL;
7719       goto LBL_ERR;
7720    }
7721 
7722    /* b is now the inverse */
7723    neg = a->sign;
7724    while (D.sign == MP_NEG) {
7725       if ((err = mp_add(&D, b, &D)) != MP_OKAY)                   goto LBL_ERR;
7726    }
7727 
7728    /* too big */
7729    while (mp_cmp_mag(&D, b) != MP_LT) {
7730       if ((err = mp_sub(&D, b, &D)) != MP_OKAY)                   goto LBL_ERR;
7731    }
7732 
7733    mp_exch(&D, c);
7734    c->sign = neg;
7735    err = MP_OKAY;
7736 
7737 LBL_ERR:
7738    mp_clear_multi(&x, &y, &u, &v, &B, &D, NULL);
7739    return err;
7740 }
7741 #endif
7742 
7743 /* End: bn_s_mp_invmod_fast.c */
7744 
7745 /* Start: bn_s_mp_invmod_slow.c */
7746 #include "tommath_private.h"
7747 #ifdef BN_S_MP_INVMOD_SLOW_C
7748 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
7749 /* SPDX-License-Identifier: Unlicense */
7750 
7751 /* hac 14.61, pp608 */
s_mp_invmod_slow(const mp_int * a,const mp_int * b,mp_int * c)7752 mp_err s_mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c)
7753 {
7754    mp_int  x, y, u, v, A, B, C, D;
7755    mp_err  err;
7756 
7757    /* b cannot be negative */
7758    if ((b->sign == MP_NEG) || MP_IS_ZERO(b)) {
7759       return MP_VAL;
7760    }
7761 
7762    /* init temps */
7763    if ((err = mp_init_multi(&x, &y, &u, &v,
7764                             &A, &B, &C, &D, NULL)) != MP_OKAY) {
7765       return err;
7766    }
7767 
7768    /* x = a, y = b */
7769    if ((err = mp_mod(a, b, &x)) != MP_OKAY)                       goto LBL_ERR;
7770    if ((err = mp_copy(b, &y)) != MP_OKAY)                         goto LBL_ERR;
7771 
7772    /* 2. [modified] if x,y are both even then return an error! */
7773    if (MP_IS_EVEN(&x) && MP_IS_EVEN(&y)) {
7774       err = MP_VAL;
7775       goto LBL_ERR;
7776    }
7777 
7778    /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
7779    if ((err = mp_copy(&x, &u)) != MP_OKAY)                        goto LBL_ERR;
7780    if ((err = mp_copy(&y, &v)) != MP_OKAY)                        goto LBL_ERR;
7781    mp_set(&A, 1uL);
7782    mp_set(&D, 1uL);
7783 
7784 top:
7785    /* 4.  while u is even do */
7786    while (MP_IS_EVEN(&u)) {
7787       /* 4.1 u = u/2 */
7788       if ((err = mp_div_2(&u, &u)) != MP_OKAY)                    goto LBL_ERR;
7789 
7790       /* 4.2 if A or B is odd then */
7791       if (MP_IS_ODD(&A) || MP_IS_ODD(&B)) {
7792          /* A = (A+y)/2, B = (B-x)/2 */
7793          if ((err = mp_add(&A, &y, &A)) != MP_OKAY)               goto LBL_ERR;
7794          if ((err = mp_sub(&B, &x, &B)) != MP_OKAY)               goto LBL_ERR;
7795       }
7796       /* A = A/2, B = B/2 */
7797       if ((err = mp_div_2(&A, &A)) != MP_OKAY)                    goto LBL_ERR;
7798       if ((err = mp_div_2(&B, &B)) != MP_OKAY)                    goto LBL_ERR;
7799    }
7800 
7801    /* 5.  while v is even do */
7802    while (MP_IS_EVEN(&v)) {
7803       /* 5.1 v = v/2 */
7804       if ((err = mp_div_2(&v, &v)) != MP_OKAY)                    goto LBL_ERR;
7805 
7806       /* 5.2 if C or D is odd then */
7807       if (MP_IS_ODD(&C) || MP_IS_ODD(&D)) {
7808          /* C = (C+y)/2, D = (D-x)/2 */
7809          if ((err = mp_add(&C, &y, &C)) != MP_OKAY)               goto LBL_ERR;
7810          if ((err = mp_sub(&D, &x, &D)) != MP_OKAY)               goto LBL_ERR;
7811       }
7812       /* C = C/2, D = D/2 */
7813       if ((err = mp_div_2(&C, &C)) != MP_OKAY)                    goto LBL_ERR;
7814       if ((err = mp_div_2(&D, &D)) != MP_OKAY)                    goto LBL_ERR;
7815    }
7816 
7817    /* 6.  if u >= v then */
7818    if (mp_cmp(&u, &v) != MP_LT) {
7819       /* u = u - v, A = A - C, B = B - D */
7820       if ((err = mp_sub(&u, &v, &u)) != MP_OKAY)                  goto LBL_ERR;
7821 
7822       if ((err = mp_sub(&A, &C, &A)) != MP_OKAY)                  goto LBL_ERR;
7823 
7824       if ((err = mp_sub(&B, &D, &B)) != MP_OKAY)                  goto LBL_ERR;
7825    } else {
7826       /* v - v - u, C = C - A, D = D - B */
7827       if ((err = mp_sub(&v, &u, &v)) != MP_OKAY)                  goto LBL_ERR;
7828 
7829       if ((err = mp_sub(&C, &A, &C)) != MP_OKAY)                  goto LBL_ERR;
7830 
7831       if ((err = mp_sub(&D, &B, &D)) != MP_OKAY)                  goto LBL_ERR;
7832    }
7833 
7834    /* if not zero goto step 4 */
7835    if (!MP_IS_ZERO(&u)) {
7836       goto top;
7837    }
7838 
7839    /* now a = C, b = D, gcd == g*v */
7840 
7841    /* if v != 1 then there is no inverse */
7842    if (mp_cmp_d(&v, 1uL) != MP_EQ) {
7843       err = MP_VAL;
7844       goto LBL_ERR;
7845    }
7846 
7847    /* if its too low */
7848    while (mp_cmp_d(&C, 0uL) == MP_LT) {
7849       if ((err = mp_add(&C, b, &C)) != MP_OKAY)                   goto LBL_ERR;
7850    }
7851 
7852    /* too big */
7853    while (mp_cmp_mag(&C, b) != MP_LT) {
7854       if ((err = mp_sub(&C, b, &C)) != MP_OKAY)                   goto LBL_ERR;
7855    }
7856 
7857    /* C is now the inverse */
7858    mp_exch(&C, c);
7859    err = MP_OKAY;
7860 LBL_ERR:
7861    mp_clear_multi(&x, &y, &u, &v, &A, &B, &C, &D, NULL);
7862    return err;
7863 }
7864 #endif
7865 
7866 /* End: bn_s_mp_invmod_slow.c */
7867 
7868 /* Start: bn_s_mp_karatsuba_mul.c */
7869 #include "tommath_private.h"
7870 #ifdef BN_S_MP_KARATSUBA_MUL_C
7871 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
7872 /* SPDX-License-Identifier: Unlicense */
7873 
7874 /* c = |a| * |b| using Karatsuba Multiplication using
7875  * three half size multiplications
7876  *
7877  * Let B represent the radix [e.g. 2**MP_DIGIT_BIT] and
7878  * let n represent half of the number of digits in
7879  * the min(a,b)
7880  *
7881  * a = a1 * B**n + a0
7882  * b = b1 * B**n + b0
7883  *
7884  * Then, a * b =>
7885    a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0
7886  *
7887  * Note that a1b1 and a0b0 are used twice and only need to be
7888  * computed once.  So in total three half size (half # of
7889  * digit) multiplications are performed, a0b0, a1b1 and
7890  * (a1+b1)(a0+b0)
7891  *
7892  * Note that a multiplication of half the digits requires
7893  * 1/4th the number of single precision multiplications so in
7894  * total after one call 25% of the single precision multiplications
7895  * are saved.  Note also that the call to mp_mul can end up back
7896  * in this function if the a0, a1, b0, or b1 are above the threshold.
7897  * This is known as divide-and-conquer and leads to the famous
7898  * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than
7899  * the standard O(N**2) that the baseline/comba methods use.
7900  * Generally though the overhead of this method doesn't pay off
7901  * until a certain size (N ~ 80) is reached.
7902  */
s_mp_karatsuba_mul(const mp_int * a,const mp_int * b,mp_int * c)7903 mp_err s_mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c)
7904 {
7905    mp_int  x0, x1, y0, y1, t1, x0y0, x1y1;
7906    int     B;
7907    mp_err  err = MP_MEM; /* default the return code to an error */
7908 
7909    /* min # of digits */
7910    B = MP_MIN(a->used, b->used);
7911 
7912    /* now divide in two */
7913    B = B >> 1;
7914 
7915    /* init copy all the temps */
7916    if (mp_init_size(&x0, B) != MP_OKAY) {
7917       goto LBL_ERR;
7918    }
7919    if (mp_init_size(&x1, a->used - B) != MP_OKAY) {
7920       goto X0;
7921    }
7922    if (mp_init_size(&y0, B) != MP_OKAY) {
7923       goto X1;
7924    }
7925    if (mp_init_size(&y1, b->used - B) != MP_OKAY) {
7926       goto Y0;
7927    }
7928 
7929    /* init temps */
7930    if (mp_init_size(&t1, B * 2) != MP_OKAY) {
7931       goto Y1;
7932    }
7933    if (mp_init_size(&x0y0, B * 2) != MP_OKAY) {
7934       goto T1;
7935    }
7936    if (mp_init_size(&x1y1, B * 2) != MP_OKAY) {
7937       goto X0Y0;
7938    }
7939 
7940    /* now shift the digits */
7941    x0.used = y0.used = B;
7942    x1.used = a->used - B;
7943    y1.used = b->used - B;
7944 
7945    {
7946       int x;
7947       mp_digit *tmpa, *tmpb, *tmpx, *tmpy;
7948 
7949       /* we copy the digits directly instead of using higher level functions
7950        * since we also need to shift the digits
7951        */
7952       tmpa = a->dp;
7953       tmpb = b->dp;
7954 
7955       tmpx = x0.dp;
7956       tmpy = y0.dp;
7957       for (x = 0; x < B; x++) {
7958          *tmpx++ = *tmpa++;
7959          *tmpy++ = *tmpb++;
7960       }
7961 
7962       tmpx = x1.dp;
7963       for (x = B; x < a->used; x++) {
7964          *tmpx++ = *tmpa++;
7965       }
7966 
7967       tmpy = y1.dp;
7968       for (x = B; x < b->used; x++) {
7969          *tmpy++ = *tmpb++;
7970       }
7971    }
7972 
7973    /* only need to clamp the lower words since by definition the
7974     * upper words x1/y1 must have a known number of digits
7975     */
7976    mp_clamp(&x0);
7977    mp_clamp(&y0);
7978 
7979    /* now calc the products x0y0 and x1y1 */
7980    /* after this x0 is no longer required, free temp [x0==t2]! */
7981    if (mp_mul(&x0, &y0, &x0y0) != MP_OKAY) {
7982       goto X1Y1;          /* x0y0 = x0*y0 */
7983    }
7984    if (mp_mul(&x1, &y1, &x1y1) != MP_OKAY) {
7985       goto X1Y1;          /* x1y1 = x1*y1 */
7986    }
7987 
7988    /* now calc x1+x0 and y1+y0 */
7989    if (s_mp_add(&x1, &x0, &t1) != MP_OKAY) {
7990       goto X1Y1;          /* t1 = x1 - x0 */
7991    }
7992    if (s_mp_add(&y1, &y0, &x0) != MP_OKAY) {
7993       goto X1Y1;          /* t2 = y1 - y0 */
7994    }
7995    if (mp_mul(&t1, &x0, &t1) != MP_OKAY) {
7996       goto X1Y1;          /* t1 = (x1 + x0) * (y1 + y0) */
7997    }
7998 
7999    /* add x0y0 */
8000    if (mp_add(&x0y0, &x1y1, &x0) != MP_OKAY) {
8001       goto X1Y1;          /* t2 = x0y0 + x1y1 */
8002    }
8003    if (s_mp_sub(&t1, &x0, &t1) != MP_OKAY) {
8004       goto X1Y1;          /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */
8005    }
8006 
8007    /* shift by B */
8008    if (mp_lshd(&t1, B) != MP_OKAY) {
8009       goto X1Y1;          /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
8010    }
8011    if (mp_lshd(&x1y1, B * 2) != MP_OKAY) {
8012       goto X1Y1;          /* x1y1 = x1y1 << 2*B */
8013    }
8014 
8015    if (mp_add(&x0y0, &t1, &t1) != MP_OKAY) {
8016       goto X1Y1;          /* t1 = x0y0 + t1 */
8017    }
8018    if (mp_add(&t1, &x1y1, c) != MP_OKAY) {
8019       goto X1Y1;          /* t1 = x0y0 + t1 + x1y1 */
8020    }
8021 
8022    /* Algorithm succeeded set the return code to MP_OKAY */
8023    err = MP_OKAY;
8024 
8025 X1Y1:
8026    mp_clear(&x1y1);
8027 X0Y0:
8028    mp_clear(&x0y0);
8029 T1:
8030    mp_clear(&t1);
8031 Y1:
8032    mp_clear(&y1);
8033 Y0:
8034    mp_clear(&y0);
8035 X1:
8036    mp_clear(&x1);
8037 X0:
8038    mp_clear(&x0);
8039 LBL_ERR:
8040    return err;
8041 }
8042 #endif
8043 
8044 /* End: bn_s_mp_karatsuba_mul.c */
8045 
8046 /* Start: bn_s_mp_karatsuba_sqr.c */
8047 #include "tommath_private.h"
8048 #ifdef BN_S_MP_KARATSUBA_SQR_C
8049 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
8050 /* SPDX-License-Identifier: Unlicense */
8051 
8052 /* Karatsuba squaring, computes b = a*a using three
8053  * half size squarings
8054  *
8055  * See comments of karatsuba_mul for details.  It
8056  * is essentially the same algorithm but merely
8057  * tuned to perform recursive squarings.
8058  */
s_mp_karatsuba_sqr(const mp_int * a,mp_int * b)8059 mp_err s_mp_karatsuba_sqr(const mp_int *a, mp_int *b)
8060 {
8061    mp_int  x0, x1, t1, t2, x0x0, x1x1;
8062    int     B;
8063    mp_err  err = MP_MEM;
8064 
8065    /* min # of digits */
8066    B = a->used;
8067 
8068    /* now divide in two */
8069    B = B >> 1;
8070 
8071    /* init copy all the temps */
8072    if (mp_init_size(&x0, B) != MP_OKAY)
8073       goto LBL_ERR;
8074    if (mp_init_size(&x1, a->used - B) != MP_OKAY)
8075       goto X0;
8076 
8077    /* init temps */
8078    if (mp_init_size(&t1, a->used * 2) != MP_OKAY)
8079       goto X1;
8080    if (mp_init_size(&t2, a->used * 2) != MP_OKAY)
8081       goto T1;
8082    if (mp_init_size(&x0x0, B * 2) != MP_OKAY)
8083       goto T2;
8084    if (mp_init_size(&x1x1, (a->used - B) * 2) != MP_OKAY)
8085       goto X0X0;
8086 
8087    {
8088       int x;
8089       mp_digit *dst, *src;
8090 
8091       src = a->dp;
8092 
8093       /* now shift the digits */
8094       dst = x0.dp;
8095       for (x = 0; x < B; x++) {
8096          *dst++ = *src++;
8097       }
8098 
8099       dst = x1.dp;
8100       for (x = B; x < a->used; x++) {
8101          *dst++ = *src++;
8102       }
8103    }
8104 
8105    x0.used = B;
8106    x1.used = a->used - B;
8107 
8108    mp_clamp(&x0);
8109 
8110    /* now calc the products x0*x0 and x1*x1 */
8111    if (mp_sqr(&x0, &x0x0) != MP_OKAY)
8112       goto X1X1;           /* x0x0 = x0*x0 */
8113    if (mp_sqr(&x1, &x1x1) != MP_OKAY)
8114       goto X1X1;           /* x1x1 = x1*x1 */
8115 
8116    /* now calc (x1+x0)**2 */
8117    if (s_mp_add(&x1, &x0, &t1) != MP_OKAY)
8118       goto X1X1;           /* t1 = x1 - x0 */
8119    if (mp_sqr(&t1, &t1) != MP_OKAY)
8120       goto X1X1;           /* t1 = (x1 - x0) * (x1 - x0) */
8121 
8122    /* add x0y0 */
8123    if (s_mp_add(&x0x0, &x1x1, &t2) != MP_OKAY)
8124       goto X1X1;           /* t2 = x0x0 + x1x1 */
8125    if (s_mp_sub(&t1, &t2, &t1) != MP_OKAY)
8126       goto X1X1;           /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */
8127 
8128    /* shift by B */
8129    if (mp_lshd(&t1, B) != MP_OKAY)
8130       goto X1X1;           /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
8131    if (mp_lshd(&x1x1, B * 2) != MP_OKAY)
8132       goto X1X1;           /* x1x1 = x1x1 << 2*B */
8133 
8134    if (mp_add(&x0x0, &t1, &t1) != MP_OKAY)
8135       goto X1X1;           /* t1 = x0x0 + t1 */
8136    if (mp_add(&t1, &x1x1, b) != MP_OKAY)
8137       goto X1X1;           /* t1 = x0x0 + t1 + x1x1 */
8138 
8139    err = MP_OKAY;
8140 
8141 X1X1:
8142    mp_clear(&x1x1);
8143 X0X0:
8144    mp_clear(&x0x0);
8145 T2:
8146    mp_clear(&t2);
8147 T1:
8148    mp_clear(&t1);
8149 X1:
8150    mp_clear(&x1);
8151 X0:
8152    mp_clear(&x0);
8153 LBL_ERR:
8154    return err;
8155 }
8156 #endif
8157 
8158 /* End: bn_s_mp_karatsuba_sqr.c */
8159 
8160 /* Start: bn_s_mp_montgomery_reduce_fast.c */
8161 #include "tommath_private.h"
8162 #ifdef BN_S_MP_MONTGOMERY_REDUCE_FAST_C
8163 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
8164 /* SPDX-License-Identifier: Unlicense */
8165 
8166 /* computes xR**-1 == x (mod N) via Montgomery Reduction
8167  *
8168  * This is an optimized implementation of montgomery_reduce
8169  * which uses the comba method to quickly calculate the columns of the
8170  * reduction.
8171  *
8172  * Based on Algorithm 14.32 on pp.601 of HAC.
8173 */
s_mp_montgomery_reduce_fast(mp_int * x,const mp_int * n,mp_digit rho)8174 mp_err s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho)
8175 {
8176    int     ix, olduse;
8177    mp_err  err;
8178    mp_word W[MP_WARRAY];
8179 
8180    if (x->used > MP_WARRAY) {
8181       return MP_VAL;
8182    }
8183 
8184    /* get old used count */
8185    olduse = x->used;
8186 
8187    /* grow a as required */
8188    if (x->alloc < (n->used + 1)) {
8189       if ((err = mp_grow(x, n->used + 1)) != MP_OKAY) {
8190          return err;
8191       }
8192    }
8193 
8194    /* first we have to get the digits of the input into
8195     * an array of double precision words W[...]
8196     */
8197    {
8198       mp_word *_W;
8199       mp_digit *tmpx;
8200 
8201       /* alias for the W[] array */
8202       _W   = W;
8203 
8204       /* alias for the digits of  x*/
8205       tmpx = x->dp;
8206 
8207       /* copy the digits of a into W[0..a->used-1] */
8208       for (ix = 0; ix < x->used; ix++) {
8209          *_W++ = *tmpx++;
8210       }
8211 
8212       /* zero the high words of W[a->used..m->used*2] */
8213       if (ix < ((n->used * 2) + 1)) {
8214          MP_ZERO_BUFFER(_W, sizeof(mp_word) * (size_t)(((n->used * 2) + 1) - ix));
8215       }
8216    }
8217 
8218    /* now we proceed to zero successive digits
8219     * from the least significant upwards
8220     */
8221    for (ix = 0; ix < n->used; ix++) {
8222       /* mu = ai * m' mod b
8223        *
8224        * We avoid a double precision multiplication (which isn't required)
8225        * by casting the value down to a mp_digit.  Note this requires
8226        * that W[ix-1] have  the carry cleared (see after the inner loop)
8227        */
8228       mp_digit mu;
8229       mu = ((W[ix] & MP_MASK) * rho) & MP_MASK;
8230 
8231       /* a = a + mu * m * b**i
8232        *
8233        * This is computed in place and on the fly.  The multiplication
8234        * by b**i is handled by offseting which columns the results
8235        * are added to.
8236        *
8237        * Note the comba method normally doesn't handle carries in the
8238        * inner loop In this case we fix the carry from the previous
8239        * column since the Montgomery reduction requires digits of the
8240        * result (so far) [see above] to work.  This is
8241        * handled by fixing up one carry after the inner loop.  The
8242        * carry fixups are done in order so after these loops the
8243        * first m->used words of W[] have the carries fixed
8244        */
8245       {
8246          int iy;
8247          mp_digit *tmpn;
8248          mp_word *_W;
8249 
8250          /* alias for the digits of the modulus */
8251          tmpn = n->dp;
8252 
8253          /* Alias for the columns set by an offset of ix */
8254          _W = W + ix;
8255 
8256          /* inner loop */
8257          for (iy = 0; iy < n->used; iy++) {
8258             *_W++ += (mp_word)mu * (mp_word)*tmpn++;
8259          }
8260       }
8261 
8262       /* now fix carry for next digit, W[ix+1] */
8263       W[ix + 1] += W[ix] >> (mp_word)MP_DIGIT_BIT;
8264    }
8265 
8266    /* now we have to propagate the carries and
8267     * shift the words downward [all those least
8268     * significant digits we zeroed].
8269     */
8270    {
8271       mp_digit *tmpx;
8272       mp_word *_W, *_W1;
8273 
8274       /* nox fix rest of carries */
8275 
8276       /* alias for current word */
8277       _W1 = W + ix;
8278 
8279       /* alias for next word, where the carry goes */
8280       _W = W + ++ix;
8281 
8282       for (; ix < ((n->used * 2) + 1); ix++) {
8283          *_W++ += *_W1++ >> (mp_word)MP_DIGIT_BIT;
8284       }
8285 
8286       /* copy out, A = A/b**n
8287        *
8288        * The result is A/b**n but instead of converting from an
8289        * array of mp_word to mp_digit than calling mp_rshd
8290        * we just copy them in the right order
8291        */
8292 
8293       /* alias for destination word */
8294       tmpx = x->dp;
8295 
8296       /* alias for shifted double precision result */
8297       _W = W + n->used;
8298 
8299       for (ix = 0; ix < (n->used + 1); ix++) {
8300          *tmpx++ = *_W++ & (mp_word)MP_MASK;
8301       }
8302 
8303       /* zero oldused digits, if the input a was larger than
8304        * m->used+1 we'll have to clear the digits
8305        */
8306       MP_ZERO_DIGITS(tmpx, olduse - ix);
8307    }
8308 
8309    /* set the max used and clamp */
8310    x->used = n->used + 1;
8311    mp_clamp(x);
8312 
8313    /* if A >= m then A = A - m */
8314    if (mp_cmp_mag(x, n) != MP_LT) {
8315       return s_mp_sub(x, n, x);
8316    }
8317    return MP_OKAY;
8318 }
8319 #endif
8320 
8321 /* End: bn_s_mp_montgomery_reduce_fast.c */
8322 
8323 /* Start: bn_s_mp_mul_digs.c */
8324 #include "tommath_private.h"
8325 #ifdef BN_S_MP_MUL_DIGS_C
8326 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
8327 /* SPDX-License-Identifier: Unlicense */
8328 
8329 /* multiplies |a| * |b| and only computes upto digs digits of result
8330  * HAC pp. 595, Algorithm 14.12  Modified so you can control how
8331  * many digits of output are created.
8332  */
s_mp_mul_digs(const mp_int * a,const mp_int * b,mp_int * c,int digs)8333 mp_err s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
8334 {
8335    mp_int  t;
8336    mp_err  err;
8337    int     pa, pb, ix, iy;
8338    mp_digit u;
8339    mp_word r;
8340    mp_digit tmpx, *tmpt, *tmpy;
8341 
8342    /* can we use the fast multiplier? */
8343    if ((digs < MP_WARRAY) &&
8344        (MP_MIN(a->used, b->used) < MP_MAXFAST)) {
8345       return s_mp_mul_digs_fast(a, b, c, digs);
8346    }
8347 
8348    if ((err = mp_init_size(&t, digs)) != MP_OKAY) {
8349       return err;
8350    }
8351    t.used = digs;
8352 
8353    /* compute the digits of the product directly */
8354    pa = a->used;
8355    for (ix = 0; ix < pa; ix++) {
8356       /* set the carry to zero */
8357       u = 0;
8358 
8359       /* limit ourselves to making digs digits of output */
8360       pb = MP_MIN(b->used, digs - ix);
8361 
8362       /* setup some aliases */
8363       /* copy of the digit from a used within the nested loop */
8364       tmpx = a->dp[ix];
8365 
8366       /* an alias for the destination shifted ix places */
8367       tmpt = t.dp + ix;
8368 
8369       /* an alias for the digits of b */
8370       tmpy = b->dp;
8371 
8372       /* compute the columns of the output and propagate the carry */
8373       for (iy = 0; iy < pb; iy++) {
8374          /* compute the column as a mp_word */
8375          r       = (mp_word)*tmpt +
8376                    ((mp_word)tmpx * (mp_word)*tmpy++) +
8377                    (mp_word)u;
8378 
8379          /* the new column is the lower part of the result */
8380          *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK);
8381 
8382          /* get the carry word from the result */
8383          u       = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
8384       }
8385       /* set carry if it is placed below digs */
8386       if ((ix + iy) < digs) {
8387          *tmpt = u;
8388       }
8389    }
8390 
8391    mp_clamp(&t);
8392    mp_exch(&t, c);
8393 
8394    mp_clear(&t);
8395    return MP_OKAY;
8396 }
8397 #endif
8398 
8399 /* End: bn_s_mp_mul_digs.c */
8400 
8401 /* Start: bn_s_mp_mul_digs_fast.c */
8402 #include "tommath_private.h"
8403 #ifdef BN_S_MP_MUL_DIGS_FAST_C
8404 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
8405 /* SPDX-License-Identifier: Unlicense */
8406 
8407 /* Fast (comba) multiplier
8408  *
8409  * This is the fast column-array [comba] multiplier.  It is
8410  * designed to compute the columns of the product first
8411  * then handle the carries afterwards.  This has the effect
8412  * of making the nested loops that compute the columns very
8413  * simple and schedulable on super-scalar processors.
8414  *
8415  * This has been modified to produce a variable number of
8416  * digits of output so if say only a half-product is required
8417  * you don't have to compute the upper half (a feature
8418  * required for fast Barrett reduction).
8419  *
8420  * Based on Algorithm 14.12 on pp.595 of HAC.
8421  *
8422  */
s_mp_mul_digs_fast(const mp_int * a,const mp_int * b,mp_int * c,int digs)8423 mp_err s_mp_mul_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs)
8424 {
8425    int      olduse, pa, ix, iz;
8426    mp_err   err;
8427    mp_digit W[MP_WARRAY];
8428    mp_word  _W;
8429 
8430    /* grow the destination as required */
8431    if (c->alloc < digs) {
8432       if ((err = mp_grow(c, digs)) != MP_OKAY) {
8433          return err;
8434       }
8435    }
8436 
8437    /* number of output digits to produce */
8438    pa = MP_MIN(digs, a->used + b->used);
8439 
8440    /* clear the carry */
8441    _W = 0;
8442    for (ix = 0; ix < pa; ix++) {
8443       int      tx, ty;
8444       int      iy;
8445       mp_digit *tmpx, *tmpy;
8446 
8447       /* get offsets into the two bignums */
8448       ty = MP_MIN(b->used-1, ix);
8449       tx = ix - ty;
8450 
8451       /* setup temp aliases */
8452       tmpx = a->dp + tx;
8453       tmpy = b->dp + ty;
8454 
8455       /* this is the number of times the loop will iterrate, essentially
8456          while (tx++ < a->used && ty-- >= 0) { ... }
8457        */
8458       iy = MP_MIN(a->used-tx, ty+1);
8459 
8460       /* execute loop */
8461       for (iz = 0; iz < iy; ++iz) {
8462          _W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
8463 
8464       }
8465 
8466       /* store term */
8467       W[ix] = (mp_digit)_W & MP_MASK;
8468 
8469       /* make next carry */
8470       _W = _W >> (mp_word)MP_DIGIT_BIT;
8471    }
8472 
8473    /* setup dest */
8474    olduse  = c->used;
8475    c->used = pa;
8476 
8477    {
8478       mp_digit *tmpc;
8479       tmpc = c->dp;
8480       for (ix = 0; ix < pa; ix++) {
8481          /* now extract the previous digit [below the carry] */
8482          *tmpc++ = W[ix];
8483       }
8484 
8485       /* clear unused digits [that existed in the old copy of c] */
8486       MP_ZERO_DIGITS(tmpc, olduse - ix);
8487    }
8488    mp_clamp(c);
8489    return MP_OKAY;
8490 }
8491 #endif
8492 
8493 /* End: bn_s_mp_mul_digs_fast.c */
8494 
8495 /* Start: bn_s_mp_mul_high_digs.c */
8496 #include "tommath_private.h"
8497 #ifdef BN_S_MP_MUL_HIGH_DIGS_C
8498 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
8499 /* SPDX-License-Identifier: Unlicense */
8500 
8501 /* multiplies |a| * |b| and does not compute the lower digs digits
8502  * [meant to get the higher part of the product]
8503  */
s_mp_mul_high_digs(const mp_int * a,const mp_int * b,mp_int * c,int digs)8504 mp_err s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
8505 {
8506    mp_int   t;
8507    int      pa, pb, ix, iy;
8508    mp_err   err;
8509    mp_digit u;
8510    mp_word  r;
8511    mp_digit tmpx, *tmpt, *tmpy;
8512 
8513    /* can we use the fast multiplier? */
8514    if (MP_HAS(S_MP_MUL_HIGH_DIGS_FAST)
8515        && ((a->used + b->used + 1) < MP_WARRAY)
8516        && (MP_MIN(a->used, b->used) < MP_MAXFAST)) {
8517       return s_mp_mul_high_digs_fast(a, b, c, digs);
8518    }
8519 
8520    if ((err = mp_init_size(&t, a->used + b->used + 1)) != MP_OKAY) {
8521       return err;
8522    }
8523    t.used = a->used + b->used + 1;
8524 
8525    pa = a->used;
8526    pb = b->used;
8527    for (ix = 0; ix < pa; ix++) {
8528       /* clear the carry */
8529       u = 0;
8530 
8531       /* left hand side of A[ix] * B[iy] */
8532       tmpx = a->dp[ix];
8533 
8534       /* alias to the address of where the digits will be stored */
8535       tmpt = &(t.dp[digs]);
8536 
8537       /* alias for where to read the right hand side from */
8538       tmpy = b->dp + (digs - ix);
8539 
8540       for (iy = digs - ix; iy < pb; iy++) {
8541          /* calculate the double precision result */
8542          r       = (mp_word)*tmpt +
8543                    ((mp_word)tmpx * (mp_word)*tmpy++) +
8544                    (mp_word)u;
8545 
8546          /* get the lower part */
8547          *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK);
8548 
8549          /* carry the carry */
8550          u       = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
8551       }
8552       *tmpt = u;
8553    }
8554    mp_clamp(&t);
8555    mp_exch(&t, c);
8556    mp_clear(&t);
8557    return MP_OKAY;
8558 }
8559 #endif
8560 
8561 /* End: bn_s_mp_mul_high_digs.c */
8562 
8563 /* Start: bn_s_mp_mul_high_digs_fast.c */
8564 #include "tommath_private.h"
8565 #ifdef BN_S_MP_MUL_HIGH_DIGS_FAST_C
8566 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
8567 /* SPDX-License-Identifier: Unlicense */
8568 
8569 /* this is a modified version of fast_s_mul_digs that only produces
8570  * output digits *above* digs.  See the comments for fast_s_mul_digs
8571  * to see how it works.
8572  *
8573  * This is used in the Barrett reduction since for one of the multiplications
8574  * only the higher digits were needed.  This essentially halves the work.
8575  *
8576  * Based on Algorithm 14.12 on pp.595 of HAC.
8577  */
s_mp_mul_high_digs_fast(const mp_int * a,const mp_int * b,mp_int * c,int digs)8578 mp_err s_mp_mul_high_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs)
8579 {
8580    int     olduse, pa, ix, iz;
8581    mp_err   err;
8582    mp_digit W[MP_WARRAY];
8583    mp_word  _W;
8584 
8585    /* grow the destination as required */
8586    pa = a->used + b->used;
8587    if (c->alloc < pa) {
8588       if ((err = mp_grow(c, pa)) != MP_OKAY) {
8589          return err;
8590       }
8591    }
8592 
8593    /* number of output digits to produce */
8594    pa = a->used + b->used;
8595    _W = 0;
8596    for (ix = digs; ix < pa; ix++) {
8597       int      tx, ty, iy;
8598       mp_digit *tmpx, *tmpy;
8599 
8600       /* get offsets into the two bignums */
8601       ty = MP_MIN(b->used-1, ix);
8602       tx = ix - ty;
8603 
8604       /* setup temp aliases */
8605       tmpx = a->dp + tx;
8606       tmpy = b->dp + ty;
8607 
8608       /* this is the number of times the loop will iterrate, essentially its
8609          while (tx++ < a->used && ty-- >= 0) { ... }
8610        */
8611       iy = MP_MIN(a->used-tx, ty+1);
8612 
8613       /* execute loop */
8614       for (iz = 0; iz < iy; iz++) {
8615          _W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
8616       }
8617 
8618       /* store term */
8619       W[ix] = (mp_digit)_W & MP_MASK;
8620 
8621       /* make next carry */
8622       _W = _W >> (mp_word)MP_DIGIT_BIT;
8623    }
8624 
8625    /* setup dest */
8626    olduse  = c->used;
8627    c->used = pa;
8628 
8629    {
8630       mp_digit *tmpc;
8631 
8632       tmpc = c->dp + digs;
8633       for (ix = digs; ix < pa; ix++) {
8634          /* now extract the previous digit [below the carry] */
8635          *tmpc++ = W[ix];
8636       }
8637 
8638       /* clear unused digits [that existed in the old copy of c] */
8639       MP_ZERO_DIGITS(tmpc, olduse - ix);
8640    }
8641    mp_clamp(c);
8642    return MP_OKAY;
8643 }
8644 #endif
8645 
8646 /* End: bn_s_mp_mul_high_digs_fast.c */
8647 
8648 /* Start: bn_s_mp_prime_is_divisible.c */
8649 #include "tommath_private.h"
8650 #ifdef BN_S_MP_PRIME_IS_DIVISIBLE_C
8651 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
8652 /* SPDX-License-Identifier: Unlicense */
8653 
8654 /* determines if an integers is divisible by one
8655  * of the first PRIME_SIZE primes or not
8656  *
8657  * sets result to 0 if not, 1 if yes
8658  */
s_mp_prime_is_divisible(const mp_int * a,mp_bool * result)8659 mp_err s_mp_prime_is_divisible(const mp_int *a, mp_bool *result)
8660 {
8661    int      ix;
8662    mp_err   err;
8663    mp_digit res;
8664 
8665    /* default to not */
8666    *result = MP_NO;
8667 
8668    for (ix = 0; ix < PRIVATE_MP_PRIME_TAB_SIZE; ix++) {
8669       /* what is a mod LBL_prime_tab[ix] */
8670       if ((err = mp_mod_d(a, s_mp_prime_tab[ix], &res)) != MP_OKAY) {
8671          return err;
8672       }
8673 
8674       /* is the residue zero? */
8675       if (res == 0u) {
8676          *result = MP_YES;
8677          return MP_OKAY;
8678       }
8679    }
8680 
8681    return MP_OKAY;
8682 }
8683 #endif
8684 
8685 /* End: bn_s_mp_prime_is_divisible.c */
8686 
8687 /* Start: bn_s_mp_rand_jenkins.c */
8688 #include "tommath_private.h"
8689 #ifdef BN_S_MP_RAND_JENKINS_C
8690 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
8691 /* SPDX-License-Identifier: Unlicense */
8692 
8693 /* Bob Jenkins' http://burtleburtle.net/bob/rand/smallprng.html */
8694 /* Chosen for speed and a good "mix" */
8695 typedef struct {
8696    uint64_t a;
8697    uint64_t b;
8698    uint64_t c;
8699    uint64_t d;
8700 } ranctx;
8701 
8702 static ranctx jenkins_x;
8703 
8704 #define rot(x,k) (((x)<<(k))|((x)>>(64-(k))))
s_rand_jenkins_val(void)8705 static uint64_t s_rand_jenkins_val(void)
8706 {
8707    uint64_t e = jenkins_x.a - rot(jenkins_x.b, 7);
8708    jenkins_x.a = jenkins_x.b ^ rot(jenkins_x.c, 13);
8709    jenkins_x.b = jenkins_x.c + rot(jenkins_x.d, 37);
8710    jenkins_x.c = jenkins_x.d + e;
8711    jenkins_x.d = e + jenkins_x.a;
8712    return jenkins_x.d;
8713 }
8714 
s_mp_rand_jenkins_init(uint64_t seed)8715 void s_mp_rand_jenkins_init(uint64_t seed)
8716 {
8717    uint64_t i;
8718    jenkins_x.a = 0xf1ea5eedULL;
8719    jenkins_x.b = jenkins_x.c = jenkins_x.d = seed;
8720    for (i = 0uLL; i < 20uLL; ++i) {
8721       (void)s_rand_jenkins_val();
8722    }
8723 }
8724 
s_mp_rand_jenkins(void * p,size_t n)8725 mp_err s_mp_rand_jenkins(void *p, size_t n)
8726 {
8727    char *q = (char *)p;
8728    while (n > 0u) {
8729       int i;
8730       uint64_t x = s_rand_jenkins_val();
8731       for (i = 0; (i < 8) && (n > 0u); ++i, --n) {
8732          *q++ = (char)(x & 0xFFuLL);
8733          x >>= 8;
8734       }
8735    }
8736    return MP_OKAY;
8737 }
8738 
8739 #endif
8740 
8741 /* End: bn_s_mp_rand_jenkins.c */
8742 
8743 /* Start: bn_s_mp_rand_platform.c */
8744 #include "tommath_private.h"
8745 #ifdef BN_S_MP_RAND_PLATFORM_C
8746 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
8747 /* SPDX-License-Identifier: Unlicense */
8748 
8749 /* First the OS-specific special cases
8750  * - *BSD
8751  * - Windows
8752  */
8753 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
8754 #define BN_S_READ_ARC4RANDOM_C
s_read_arc4random(void * p,size_t n)8755 static mp_err s_read_arc4random(void *p, size_t n)
8756 {
8757    arc4random_buf(p, n);
8758    return MP_OKAY;
8759 }
8760 #endif
8761 
8762 #if defined(_WIN32) || defined(_WIN32_WCE)
8763 #define BN_S_READ_WINCSP_C
8764 
8765 #ifndef _WIN32_WINNT
8766 #define _WIN32_WINNT 0x0400
8767 #endif
8768 #ifdef _WIN32_WCE
8769 #define UNDER_CE
8770 #define ARM
8771 #endif
8772 
8773 #define WIN32_LEAN_AND_MEAN
8774 #include <windows.h>
8775 #include <wincrypt.h>
8776 
s_read_wincsp(void * p,size_t n)8777 static mp_err s_read_wincsp(void *p, size_t n)
8778 {
8779    static HCRYPTPROV hProv = 0;
8780    if (hProv == 0) {
8781       HCRYPTPROV h = 0;
8782       if (!CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL,
8783                                (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) &&
8784           !CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL,
8785                                CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) {
8786          return MP_ERR;
8787       }
8788       hProv = h;
8789    }
8790    return CryptGenRandom(hProv, (DWORD)n, (BYTE *)p) == TRUE ? MP_OKAY : MP_ERR;
8791 }
8792 #endif /* WIN32 */
8793 
8794 #if !defined(BN_S_READ_WINCSP_C) && defined(__linux__) && defined(__GLIBC_PREREQ)
8795 #if __GLIBC_PREREQ(2, 25)
8796 #define BN_S_READ_GETRANDOM_C
8797 #include <sys/random.h>
8798 #include <errno.h>
8799 
s_read_getrandom(void * p,size_t n)8800 static mp_err s_read_getrandom(void *p, size_t n)
8801 {
8802    char *q = (char *)p;
8803    while (n > 0u) {
8804       ssize_t ret = getrandom(q, n, 0);
8805       if (ret < 0) {
8806          if (errno == EINTR) {
8807             continue;
8808          }
8809          return MP_ERR;
8810       }
8811       q += ret;
8812       n -= (size_t)ret;
8813    }
8814    return MP_OKAY;
8815 }
8816 #endif
8817 #endif
8818 
8819 /* We assume all platforms besides windows provide "/dev/urandom".
8820  * In case yours doesn't, define MP_NO_DEV_URANDOM at compile-time.
8821  */
8822 #if !defined(BN_S_READ_WINCSP_C) && !defined(MP_NO_DEV_URANDOM)
8823 #define BN_S_READ_URANDOM_C
8824 #ifndef MP_DEV_URANDOM
8825 #define MP_DEV_URANDOM "/dev/urandom"
8826 #endif
8827 #include <fcntl.h>
8828 #include <errno.h>
8829 #include <unistd.h>
8830 
s_read_urandom(void * p,size_t n)8831 static mp_err s_read_urandom(void *p, size_t n)
8832 {
8833    int fd;
8834    char *q = (char *)p;
8835 
8836    do {
8837       fd = open(MP_DEV_URANDOM, O_RDONLY);
8838    } while ((fd == -1) && (errno == EINTR));
8839    if (fd == -1) return MP_ERR;
8840 
8841    while (n > 0u) {
8842       ssize_t ret = read(fd, p, n);
8843       if (ret < 0) {
8844          if (errno == EINTR) {
8845             continue;
8846          }
8847          close(fd);
8848          return MP_ERR;
8849       }
8850       q += ret;
8851       n -= (size_t)ret;
8852    }
8853 
8854    close(fd);
8855    return MP_OKAY;
8856 }
8857 #endif
8858 
8859 #if defined(MP_PRNG_ENABLE_LTM_RNG)
8860 #define BN_S_READ_LTM_RNG
8861 unsigned long (*ltm_rng)(unsigned char *out, unsigned long outlen, void (*callback)(void));
8862 void (*ltm_rng_callback)(void);
8863 
s_read_ltm_rng(void * p,size_t n)8864 static mp_err s_read_ltm_rng(void *p, size_t n)
8865 {
8866    unsigned long res;
8867    if (ltm_rng == NULL) return MP_ERR;
8868    res = ltm_rng(p, n, ltm_rng_callback);
8869    if (res != n) return MP_ERR;
8870    return MP_OKAY;
8871 }
8872 #endif
8873 
8874 mp_err s_read_arc4random(void *p, size_t n);
8875 mp_err s_read_wincsp(void *p, size_t n);
8876 mp_err s_read_getrandom(void *p, size_t n);
8877 mp_err s_read_urandom(void *p, size_t n);
8878 mp_err s_read_ltm_rng(void *p, size_t n);
8879 
s_mp_rand_platform(void * p,size_t n)8880 mp_err s_mp_rand_platform(void *p, size_t n)
8881 {
8882    mp_err err = MP_ERR;
8883    if ((err != MP_OKAY) && MP_HAS(S_READ_ARC4RANDOM)) err = s_read_arc4random(p, n);
8884    if ((err != MP_OKAY) && MP_HAS(S_READ_WINCSP))     err = s_read_wincsp(p, n);
8885    if ((err != MP_OKAY) && MP_HAS(S_READ_GETRANDOM))  err = s_read_getrandom(p, n);
8886    if ((err != MP_OKAY) && MP_HAS(S_READ_URANDOM))    err = s_read_urandom(p, n);
8887    if ((err != MP_OKAY) && MP_HAS(S_READ_LTM_RNG))    err = s_read_ltm_rng(p, n);
8888    return err;
8889 }
8890 
8891 #endif
8892 
8893 /* End: bn_s_mp_rand_platform.c */
8894 
8895 /* Start: bn_s_mp_reverse.c */
8896 #include "tommath_private.h"
8897 #ifdef BN_S_MP_REVERSE_C
8898 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
8899 /* SPDX-License-Identifier: Unlicense */
8900 
8901 /* reverse an array, used for radix code */
s_mp_reverse(unsigned char * s,size_t len)8902 void s_mp_reverse(unsigned char *s, size_t len)
8903 {
8904    size_t   ix, iy;
8905    unsigned char t;
8906 
8907    ix = 0u;
8908    iy = len - 1u;
8909    while (ix < iy) {
8910       t     = s[ix];
8911       s[ix] = s[iy];
8912       s[iy] = t;
8913       ++ix;
8914       --iy;
8915    }
8916 }
8917 #endif
8918 
8919 /* End: bn_s_mp_reverse.c */
8920 
8921 /* Start: bn_s_mp_sqr.c */
8922 #include "tommath_private.h"
8923 #ifdef BN_S_MP_SQR_C
8924 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
8925 /* SPDX-License-Identifier: Unlicense */
8926 
8927 /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
s_mp_sqr(const mp_int * a,mp_int * b)8928 mp_err s_mp_sqr(const mp_int *a, mp_int *b)
8929 {
8930    mp_int   t;
8931    int      ix, iy, pa;
8932    mp_err   err;
8933    mp_word  r;
8934    mp_digit u, tmpx, *tmpt;
8935 
8936    pa = a->used;
8937    if ((err = mp_init_size(&t, (2 * pa) + 1)) != MP_OKAY) {
8938       return err;
8939    }
8940 
8941    /* default used is maximum possible size */
8942    t.used = (2 * pa) + 1;
8943 
8944    for (ix = 0; ix < pa; ix++) {
8945       /* first calculate the digit at 2*ix */
8946       /* calculate double precision result */
8947       r = (mp_word)t.dp[2*ix] +
8948           ((mp_word)a->dp[ix] * (mp_word)a->dp[ix]);
8949 
8950       /* store lower part in result */
8951       t.dp[ix+ix] = (mp_digit)(r & (mp_word)MP_MASK);
8952 
8953       /* get the carry */
8954       u           = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
8955 
8956       /* left hand side of A[ix] * A[iy] */
8957       tmpx        = a->dp[ix];
8958 
8959       /* alias for where to store the results */
8960       tmpt        = t.dp + ((2 * ix) + 1);
8961 
8962       for (iy = ix + 1; iy < pa; iy++) {
8963          /* first calculate the product */
8964          r       = (mp_word)tmpx * (mp_word)a->dp[iy];
8965 
8966          /* now calculate the double precision result, note we use
8967           * addition instead of *2 since it's easier to optimize
8968           */
8969          r       = (mp_word)*tmpt + r + r + (mp_word)u;
8970 
8971          /* store lower part */
8972          *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK);
8973 
8974          /* get carry */
8975          u       = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
8976       }
8977       /* propagate upwards */
8978       while (u != 0uL) {
8979          r       = (mp_word)*tmpt + (mp_word)u;
8980          *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK);
8981          u       = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
8982       }
8983    }
8984 
8985    mp_clamp(&t);
8986    mp_exch(&t, b);
8987    mp_clear(&t);
8988    return MP_OKAY;
8989 }
8990 #endif
8991 
8992 /* End: bn_s_mp_sqr.c */
8993 
8994 /* Start: bn_s_mp_sqr_fast.c */
8995 #include "tommath_private.h"
8996 #ifdef BN_S_MP_SQR_FAST_C
8997 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
8998 /* SPDX-License-Identifier: Unlicense */
8999 
9000 /* the jist of squaring...
9001  * you do like mult except the offset of the tmpx [one that
9002  * starts closer to zero] can't equal the offset of tmpy.
9003  * So basically you set up iy like before then you min it with
9004  * (ty-tx) so that it never happens.  You double all those
9005  * you add in the inner loop
9006 
9007 After that loop you do the squares and add them in.
9008 */
9009 
s_mp_sqr_fast(const mp_int * a,mp_int * b)9010 mp_err s_mp_sqr_fast(const mp_int *a, mp_int *b)
9011 {
9012    int       olduse, pa, ix, iz;
9013    mp_digit  W[MP_WARRAY], *tmpx;
9014    mp_word   W1;
9015    mp_err    err;
9016 
9017    /* grow the destination as required */
9018    pa = a->used + a->used;
9019    if (b->alloc < pa) {
9020       if ((err = mp_grow(b, pa)) != MP_OKAY) {
9021          return err;
9022       }
9023    }
9024 
9025    /* number of output digits to produce */
9026    W1 = 0;
9027    for (ix = 0; ix < pa; ix++) {
9028       int      tx, ty, iy;
9029       mp_word  _W;
9030       mp_digit *tmpy;
9031 
9032       /* clear counter */
9033       _W = 0;
9034 
9035       /* get offsets into the two bignums */
9036       ty = MP_MIN(a->used-1, ix);
9037       tx = ix - ty;
9038 
9039       /* setup temp aliases */
9040       tmpx = a->dp + tx;
9041       tmpy = a->dp + ty;
9042 
9043       /* this is the number of times the loop will iterrate, essentially
9044          while (tx++ < a->used && ty-- >= 0) { ... }
9045        */
9046       iy = MP_MIN(a->used-tx, ty+1);
9047 
9048       /* now for squaring tx can never equal ty
9049        * we halve the distance since they approach at a rate of 2x
9050        * and we have to round because odd cases need to be executed
9051        */
9052       iy = MP_MIN(iy, ((ty-tx)+1)>>1);
9053 
9054       /* execute loop */
9055       for (iz = 0; iz < iy; iz++) {
9056          _W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
9057       }
9058 
9059       /* double the inner product and add carry */
9060       _W = _W + _W + W1;
9061 
9062       /* even columns have the square term in them */
9063       if (((unsigned)ix & 1u) == 0u) {
9064          _W += (mp_word)a->dp[ix>>1] * (mp_word)a->dp[ix>>1];
9065       }
9066 
9067       /* store it */
9068       W[ix] = (mp_digit)_W & MP_MASK;
9069 
9070       /* make next carry */
9071       W1 = _W >> (mp_word)MP_DIGIT_BIT;
9072    }
9073 
9074    /* setup dest */
9075    olduse  = b->used;
9076    b->used = a->used+a->used;
9077 
9078    {
9079       mp_digit *tmpb;
9080       tmpb = b->dp;
9081       for (ix = 0; ix < pa; ix++) {
9082          *tmpb++ = W[ix] & MP_MASK;
9083       }
9084 
9085       /* clear unused digits [that existed in the old copy of c] */
9086       MP_ZERO_DIGITS(tmpb, olduse - ix);
9087    }
9088    mp_clamp(b);
9089    return MP_OKAY;
9090 }
9091 #endif
9092 
9093 /* End: bn_s_mp_sqr_fast.c */
9094 
9095 /* Start: bn_s_mp_sub.c */
9096 #include "tommath_private.h"
9097 #ifdef BN_S_MP_SUB_C
9098 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
9099 /* SPDX-License-Identifier: Unlicense */
9100 
9101 /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
s_mp_sub(const mp_int * a,const mp_int * b,mp_int * c)9102 mp_err s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
9103 {
9104    int    olduse, min, max;
9105    mp_err err;
9106 
9107    /* find sizes */
9108    min = b->used;
9109    max = a->used;
9110 
9111    /* init result */
9112    if (c->alloc < max) {
9113       if ((err = mp_grow(c, max)) != MP_OKAY) {
9114          return err;
9115       }
9116    }
9117    olduse = c->used;
9118    c->used = max;
9119 
9120    {
9121       mp_digit u, *tmpa, *tmpb, *tmpc;
9122       int i;
9123 
9124       /* alias for digit pointers */
9125       tmpa = a->dp;
9126       tmpb = b->dp;
9127       tmpc = c->dp;
9128 
9129       /* set carry to zero */
9130       u = 0;
9131       for (i = 0; i < min; i++) {
9132          /* T[i] = A[i] - B[i] - U */
9133          *tmpc = (*tmpa++ - *tmpb++) - u;
9134 
9135          /* U = carry bit of T[i]
9136           * Note this saves performing an AND operation since
9137           * if a carry does occur it will propagate all the way to the
9138           * MSB.  As a result a single shift is enough to get the carry
9139           */
9140          u = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u);
9141 
9142          /* Clear carry from T[i] */
9143          *tmpc++ &= MP_MASK;
9144       }
9145 
9146       /* now copy higher words if any, e.g. if A has more digits than B  */
9147       for (; i < max; i++) {
9148          /* T[i] = A[i] - U */
9149          *tmpc = *tmpa++ - u;
9150 
9151          /* U = carry bit of T[i] */
9152          u = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u);
9153 
9154          /* Clear carry from T[i] */
9155          *tmpc++ &= MP_MASK;
9156       }
9157 
9158       /* clear digits above used (since we may not have grown result above) */
9159       MP_ZERO_DIGITS(tmpc, olduse - c->used);
9160    }
9161 
9162    mp_clamp(c);
9163    return MP_OKAY;
9164 }
9165 
9166 #endif
9167 
9168 /* End: bn_s_mp_sub.c */
9169 
9170 /* Start: bn_s_mp_toom_mul.c */
9171 #include "tommath_private.h"
9172 #ifdef BN_S_MP_TOOM_MUL_C
9173 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
9174 /* SPDX-License-Identifier: Unlicense */
9175 
9176 /* multiplication using the Toom-Cook 3-way algorithm
9177  *
9178  * Much more complicated than Karatsuba but has a lower
9179  * asymptotic running time of O(N**1.464).  This algorithm is
9180  * only particularly useful on VERY large inputs
9181  * (we're talking 1000s of digits here...).
9182 */
9183 
9184 /*
9185    This file contains code from J. Arndt's book  "Matters Computational"
9186    and the accompanying FXT-library with permission of the author.
9187 */
9188 
9189 /*
9190    Setup from
9191 
9192      Chung, Jaewook, and M. Anwar Hasan. "Asymmetric squaring formulae."
9193      18th IEEE Symposium on Computer Arithmetic (ARITH'07). IEEE, 2007.
9194 
9195    The interpolation from above needed one temporary variable more
9196    than the interpolation here:
9197 
9198      Bodrato, Marco, and Alberto Zanoni. "What about Toom-Cook matrices optimality."
9199      Centro Vito Volterra Universita di Roma Tor Vergata (2006)
9200 */
9201 
s_mp_toom_mul(const mp_int * a,const mp_int * b,mp_int * c)9202 mp_err s_mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c)
9203 {
9204    mp_int S1, S2, T1, a0, a1, a2, b0, b1, b2;
9205    int B, count;
9206    mp_err err;
9207 
9208    /* init temps */
9209    if ((err = mp_init_multi(&S1, &S2, &T1, NULL)) != MP_OKAY) {
9210       return err;
9211    }
9212 
9213    /* B */
9214    B = MP_MIN(a->used, b->used) / 3;
9215 
9216    /** a = a2 * x^2 + a1 * x + a0; */
9217    if ((err = mp_init_size(&a0, B)) != MP_OKAY)                   goto LBL_ERRa0;
9218 
9219    for (count = 0; count < B; count++) {
9220       a0.dp[count] = a->dp[count];
9221       a0.used++;
9222    }
9223    mp_clamp(&a0);
9224    if ((err = mp_init_size(&a1, B)) != MP_OKAY)                   goto LBL_ERRa1;
9225    for (; count < (2 * B); count++) {
9226       a1.dp[count - B] = a->dp[count];
9227       a1.used++;
9228    }
9229    mp_clamp(&a1);
9230    if ((err = mp_init_size(&a2, B + (a->used - (3 * B)))) != MP_OKAY) goto LBL_ERRa2;
9231    for (; count < a->used; count++) {
9232       a2.dp[count - (2 * B)] = a->dp[count];
9233       a2.used++;
9234    }
9235    mp_clamp(&a2);
9236 
9237    /** b = b2 * x^2 + b1 * x + b0; */
9238    if ((err = mp_init_size(&b0, B)) != MP_OKAY)                   goto LBL_ERRb0;
9239    for (count = 0; count < B; count++) {
9240       b0.dp[count] = b->dp[count];
9241       b0.used++;
9242    }
9243    mp_clamp(&b0);
9244    if ((err = mp_init_size(&b1, B)) != MP_OKAY)                   goto LBL_ERRb1;
9245    for (; count < (2 * B); count++) {
9246       b1.dp[count - B] = b->dp[count];
9247       b1.used++;
9248    }
9249    mp_clamp(&b1);
9250    if ((err = mp_init_size(&b2, B + (b->used - (3 * B)))) != MP_OKAY) goto LBL_ERRb2;
9251    for (; count < b->used; count++) {
9252       b2.dp[count - (2 * B)] = b->dp[count];
9253       b2.used++;
9254    }
9255    mp_clamp(&b2);
9256 
9257    /** \\ S1 = (a2+a1+a0) * (b2+b1+b0); */
9258    /** T1 = a2 + a1; */
9259    if ((err = mp_add(&a2, &a1, &T1)) != MP_OKAY)                  goto LBL_ERR;
9260 
9261    /** S2 = T1 + a0; */
9262    if ((err = mp_add(&T1, &a0, &S2)) != MP_OKAY)                  goto LBL_ERR;
9263 
9264    /** c = b2 + b1; */
9265    if ((err = mp_add(&b2, &b1, c)) != MP_OKAY)                    goto LBL_ERR;
9266 
9267    /** S1 = c + b0; */
9268    if ((err = mp_add(c, &b0, &S1)) != MP_OKAY)                    goto LBL_ERR;
9269 
9270    /** S1 = S1 * S2; */
9271    if ((err = mp_mul(&S1, &S2, &S1)) != MP_OKAY)                  goto LBL_ERR;
9272 
9273    /** \\S2 = (4*a2+2*a1+a0) * (4*b2+2*b1+b0); */
9274    /** T1 = T1 + a2; */
9275    if ((err = mp_add(&T1, &a2, &T1)) != MP_OKAY)                  goto LBL_ERR;
9276 
9277    /** T1 = T1 << 1; */
9278    if ((err = mp_mul_2(&T1, &T1)) != MP_OKAY)                     goto LBL_ERR;
9279 
9280    /** T1 = T1 + a0; */
9281    if ((err = mp_add(&T1, &a0, &T1)) != MP_OKAY)                  goto LBL_ERR;
9282 
9283    /** c = c + b2; */
9284    if ((err = mp_add(c, &b2, c)) != MP_OKAY)                      goto LBL_ERR;
9285 
9286    /** c = c << 1; */
9287    if ((err = mp_mul_2(c, c)) != MP_OKAY)                         goto LBL_ERR;
9288 
9289    /** c = c + b0; */
9290    if ((err = mp_add(c, &b0, c)) != MP_OKAY)                      goto LBL_ERR;
9291 
9292    /** S2 = T1 * c; */
9293    if ((err = mp_mul(&T1, c, &S2)) != MP_OKAY)                    goto LBL_ERR;
9294 
9295    /** \\S3 = (a2-a1+a0) * (b2-b1+b0); */
9296    /** a1 = a2 - a1; */
9297    if ((err = mp_sub(&a2, &a1, &a1)) != MP_OKAY)                  goto LBL_ERR;
9298 
9299    /** a1 = a1 + a0; */
9300    if ((err = mp_add(&a1, &a0, &a1)) != MP_OKAY)                  goto LBL_ERR;
9301 
9302    /** b1 = b2 - b1; */
9303    if ((err = mp_sub(&b2, &b1, &b1)) != MP_OKAY)                  goto LBL_ERR;
9304 
9305    /** b1 = b1 + b0; */
9306    if ((err = mp_add(&b1, &b0, &b1)) != MP_OKAY)                  goto LBL_ERR;
9307 
9308    /** a1 = a1 * b1; */
9309    if ((err = mp_mul(&a1, &b1, &a1)) != MP_OKAY)                  goto LBL_ERR;
9310 
9311    /** b1 = a2 * b2; */
9312    if ((err = mp_mul(&a2, &b2, &b1)) != MP_OKAY)                  goto LBL_ERR;
9313 
9314    /** \\S2 = (S2 - S3)/3; */
9315    /** S2 = S2 - a1; */
9316    if ((err = mp_sub(&S2, &a1, &S2)) != MP_OKAY)                  goto LBL_ERR;
9317 
9318    /** S2 = S2 / 3; \\ this is an exact division  */
9319    if ((err = mp_div_3(&S2, &S2, NULL)) != MP_OKAY)               goto LBL_ERR;
9320 
9321    /** a1 = S1 - a1; */
9322    if ((err = mp_sub(&S1, &a1, &a1)) != MP_OKAY)                  goto LBL_ERR;
9323 
9324    /** a1 = a1 >> 1; */
9325    if ((err = mp_div_2(&a1, &a1)) != MP_OKAY)                     goto LBL_ERR;
9326 
9327    /** a0 = a0 * b0; */
9328    if ((err = mp_mul(&a0, &b0, &a0)) != MP_OKAY)                  goto LBL_ERR;
9329 
9330    /** S1 = S1 - a0; */
9331    if ((err = mp_sub(&S1, &a0, &S1)) != MP_OKAY)                  goto LBL_ERR;
9332 
9333    /** S2 = S2 - S1; */
9334    if ((err = mp_sub(&S2, &S1, &S2)) != MP_OKAY)                  goto LBL_ERR;
9335 
9336    /** S2 = S2 >> 1; */
9337    if ((err = mp_div_2(&S2, &S2)) != MP_OKAY)                     goto LBL_ERR;
9338 
9339    /** S1 = S1 - a1; */
9340    if ((err = mp_sub(&S1, &a1, &S1)) != MP_OKAY)                  goto LBL_ERR;
9341 
9342    /** S1 = S1 - b1; */
9343    if ((err = mp_sub(&S1, &b1, &S1)) != MP_OKAY)                  goto LBL_ERR;
9344 
9345    /** T1 = b1 << 1; */
9346    if ((err = mp_mul_2(&b1, &T1)) != MP_OKAY)                     goto LBL_ERR;
9347 
9348    /** S2 = S2 - T1; */
9349    if ((err = mp_sub(&S2, &T1, &S2)) != MP_OKAY)                  goto LBL_ERR;
9350 
9351    /** a1 = a1 - S2; */
9352    if ((err = mp_sub(&a1, &S2, &a1)) != MP_OKAY)                  goto LBL_ERR;
9353 
9354 
9355    /** P = b1*x^4+ S2*x^3+ S1*x^2+ a1*x + a0; */
9356    if ((err = mp_lshd(&b1, 4 * B)) != MP_OKAY)                    goto LBL_ERR;
9357    if ((err = mp_lshd(&S2, 3 * B)) != MP_OKAY)                    goto LBL_ERR;
9358    if ((err = mp_add(&b1, &S2, &b1)) != MP_OKAY)                  goto LBL_ERR;
9359    if ((err = mp_lshd(&S1, 2 * B)) != MP_OKAY)                    goto LBL_ERR;
9360    if ((err = mp_add(&b1, &S1, &b1)) != MP_OKAY)                  goto LBL_ERR;
9361    if ((err = mp_lshd(&a1, 1 * B)) != MP_OKAY)                    goto LBL_ERR;
9362    if ((err = mp_add(&b1, &a1, &b1)) != MP_OKAY)                  goto LBL_ERR;
9363    if ((err = mp_add(&b1, &a0, c)) != MP_OKAY)                    goto LBL_ERR;
9364 
9365    /** a * b - P */
9366 
9367 
9368 LBL_ERR:
9369    mp_clear(&b2);
9370 LBL_ERRb2:
9371    mp_clear(&b1);
9372 LBL_ERRb1:
9373    mp_clear(&b0);
9374 LBL_ERRb0:
9375    mp_clear(&a2);
9376 LBL_ERRa2:
9377    mp_clear(&a1);
9378 LBL_ERRa1:
9379    mp_clear(&a0);
9380 LBL_ERRa0:
9381    mp_clear_multi(&S1, &S2, &T1, NULL);
9382    return err;
9383 }
9384 
9385 #endif
9386 
9387 /* End: bn_s_mp_toom_mul.c */
9388 
9389 /* Start: bn_s_mp_toom_sqr.c */
9390 #include "tommath_private.h"
9391 #ifdef BN_S_MP_TOOM_SQR_C
9392 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
9393 /* SPDX-License-Identifier: Unlicense */
9394 
9395 /* squaring using Toom-Cook 3-way algorithm */
9396 
9397 /*
9398    This file contains code from J. Arndt's book  "Matters Computational"
9399    and the accompanying FXT-library with permission of the author.
9400 */
9401 
9402 /* squaring using Toom-Cook 3-way algorithm */
9403 /*
9404    Setup and interpolation from algorithm SQR_3 in
9405 
9406      Chung, Jaewook, and M. Anwar Hasan. "Asymmetric squaring formulae."
9407      18th IEEE Symposium on Computer Arithmetic (ARITH'07). IEEE, 2007.
9408 
9409 */
s_mp_toom_sqr(const mp_int * a,mp_int * b)9410 mp_err s_mp_toom_sqr(const mp_int *a, mp_int *b)
9411 {
9412    mp_int S0, a0, a1, a2;
9413    mp_digit *tmpa, *tmpc;
9414    int B, count;
9415    mp_err err;
9416 
9417 
9418    /* init temps */
9419    if ((err = mp_init(&S0)) != MP_OKAY) {
9420       return err;
9421    }
9422 
9423    /* B */
9424    B = a->used / 3;
9425 
9426    /** a = a2 * x^2 + a1 * x + a0; */
9427    if ((err = mp_init_size(&a0, B)) != MP_OKAY)                   goto LBL_ERRa0;
9428 
9429    a0.used = B;
9430    if ((err = mp_init_size(&a1, B)) != MP_OKAY)                   goto LBL_ERRa1;
9431    a1.used = B;
9432    if ((err = mp_init_size(&a2, B + (a->used - (3 * B)))) != MP_OKAY) goto LBL_ERRa2;
9433 
9434    tmpa = a->dp;
9435    tmpc = a0.dp;
9436    for (count = 0; count < B; count++) {
9437       *tmpc++ = *tmpa++;
9438    }
9439    tmpc = a1.dp;
9440    for (; count < (2 * B); count++) {
9441       *tmpc++ = *tmpa++;
9442    }
9443    tmpc = a2.dp;
9444    for (; count < a->used; count++) {
9445       *tmpc++ = *tmpa++;
9446       a2.used++;
9447    }
9448    mp_clamp(&a0);
9449    mp_clamp(&a1);
9450    mp_clamp(&a2);
9451 
9452    /** S0 = a0^2;  */
9453    if ((err = mp_sqr(&a0, &S0)) != MP_OKAY)                       goto LBL_ERR;
9454 
9455    /** \\S1 = (a2 + a1 + a0)^2 */
9456    /** \\S2 = (a2 - a1 + a0)^2  */
9457    /** \\S1 = a0 + a2; */
9458    /** a0 = a0 + a2; */
9459    if ((err = mp_add(&a0, &a2, &a0)) != MP_OKAY)                  goto LBL_ERR;
9460    /** \\S2 = S1 - a1; */
9461    /** b = a0 - a1; */
9462    if ((err = mp_sub(&a0, &a1, b)) != MP_OKAY)                    goto LBL_ERR;
9463    /** \\S1 = S1 + a1; */
9464    /** a0 = a0 + a1; */
9465    if ((err = mp_add(&a0, &a1, &a0)) != MP_OKAY)                  goto LBL_ERR;
9466    /** \\S1 = S1^2;  */
9467    /** a0 = a0^2; */
9468    if ((err = mp_sqr(&a0, &a0)) != MP_OKAY)                       goto LBL_ERR;
9469    /** \\S2 = S2^2;  */
9470    /** b = b^2; */
9471    if ((err = mp_sqr(b, b)) != MP_OKAY)                           goto LBL_ERR;
9472 
9473    /** \\ S3 = 2 * a1 * a2  */
9474    /** \\S3 = a1 * a2;  */
9475    /** a1 = a1 * a2; */
9476    if ((err = mp_mul(&a1, &a2, &a1)) != MP_OKAY)                  goto LBL_ERR;
9477    /** \\S3 = S3 << 1;  */
9478    /** a1 = a1 << 1; */
9479    if ((err = mp_mul_2(&a1, &a1)) != MP_OKAY)                     goto LBL_ERR;
9480 
9481    /** \\S4 = a2^2;  */
9482    /** a2 = a2^2; */
9483    if ((err = mp_sqr(&a2, &a2)) != MP_OKAY)                       goto LBL_ERR;
9484 
9485    /** \\ tmp = (S1 + S2)/2  */
9486    /** \\tmp = S1 + S2; */
9487    /** b = a0 + b; */
9488    if ((err = mp_add(&a0, b, b)) != MP_OKAY)                      goto LBL_ERR;
9489    /** \\tmp = tmp >> 1; */
9490    /** b = b >> 1; */
9491    if ((err = mp_div_2(b, b)) != MP_OKAY)                         goto LBL_ERR;
9492 
9493    /** \\ S1 = S1 - tmp - S3  */
9494    /** \\S1 = S1 - tmp; */
9495    /** a0 = a0 - b; */
9496    if ((err = mp_sub(&a0, b, &a0)) != MP_OKAY)                    goto LBL_ERR;
9497    /** \\S1 = S1 - S3;  */
9498    /** a0 = a0 - a1; */
9499    if ((err = mp_sub(&a0, &a1, &a0)) != MP_OKAY)                  goto LBL_ERR;
9500 
9501    /** \\S2 = tmp - S4 -S0  */
9502    /** \\S2 = tmp - S4;  */
9503    /** b = b - a2; */
9504    if ((err = mp_sub(b, &a2, b)) != MP_OKAY)                      goto LBL_ERR;
9505    /** \\S2 = S2 - S0;  */
9506    /** b = b - S0; */
9507    if ((err = mp_sub(b, &S0, b)) != MP_OKAY)                      goto LBL_ERR;
9508 
9509 
9510    /** \\P = S4*x^4 + S3*x^3 + S2*x^2 + S1*x + S0; */
9511    /** P = a2*x^4 + a1*x^3 + b*x^2 + a0*x + S0; */
9512 
9513    if ((err = mp_lshd(&a2, 4 * B)) != MP_OKAY)                    goto LBL_ERR;
9514    if ((err = mp_lshd(&a1, 3 * B)) != MP_OKAY)                    goto LBL_ERR;
9515    if ((err = mp_lshd(b, 2 * B)) != MP_OKAY)                      goto LBL_ERR;
9516    if ((err = mp_lshd(&a0, 1 * B)) != MP_OKAY)                    goto LBL_ERR;
9517    if ((err = mp_add(&a2, &a1, &a2)) != MP_OKAY)                  goto LBL_ERR;
9518    if ((err = mp_add(&a2, b, b)) != MP_OKAY)                      goto LBL_ERR;
9519    if ((err = mp_add(b, &a0, b)) != MP_OKAY)                      goto LBL_ERR;
9520    if ((err = mp_add(b, &S0, b)) != MP_OKAY)                      goto LBL_ERR;
9521    /** a^2 - P  */
9522 
9523 
9524 LBL_ERR:
9525    mp_clear(&a2);
9526 LBL_ERRa2:
9527    mp_clear(&a1);
9528 LBL_ERRa1:
9529    mp_clear(&a0);
9530 LBL_ERRa0:
9531    mp_clear(&S0);
9532 
9533    return err;
9534 }
9535 
9536 #endif
9537 
9538 /* End: bn_s_mp_toom_sqr.c */
9539 
9540 
9541 /* EOF */
9542