annotate libtommath/bn_s_mp_exptmod_fast.c @ 1801:4983a6bc1f51

fuzz: fix crash in newtcpdirect(), don't close the channel too early
author Matt Johnston <matt@ucc.asn.au>
date Fri, 05 Mar 2021 22:51:11 +0800
parents 1051e4eea25a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1692
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
1 #include "tommath_private.h"
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
2 #ifdef BN_S_MP_EXPTMOD_FAST_C
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
4 /* SPDX-License-Identifier: Unlicense */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
5
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
6 /* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
7 *
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
8 * Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
9 * The value of k changes based on the size of the exponent.
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
10 *
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
11 * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
12 */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
13
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
14 #ifdef MP_LOW_MEM
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
15 # define TAB_SIZE 32
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
16 # define MAX_WINSIZE 5
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
17 #else
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
18 # define TAB_SIZE 256
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
19 # define MAX_WINSIZE 0
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
20 #endif
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
21
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
22 mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode)
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
23 {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
24 mp_int M[TAB_SIZE], res;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
25 mp_digit buf, mp;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
26 int bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
27 mp_err err;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
28
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
29 /* use a pointer to the reduction algorithm. This allows us to use
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
30 * one of many reduction algorithms without modding the guts of
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
31 * the code with if statements everywhere.
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
32 */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
33 mp_err(*redux)(mp_int *x, const mp_int *n, mp_digit rho);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
34
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
35 /* find window size */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
36 x = mp_count_bits(X);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
37 if (x <= 7) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
38 winsize = 2;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
39 } else if (x <= 36) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
40 winsize = 3;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
41 } else if (x <= 140) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
42 winsize = 4;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
43 } else if (x <= 450) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
44 winsize = 5;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
45 } else if (x <= 1303) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
46 winsize = 6;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
47 } else if (x <= 3529) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
48 winsize = 7;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
49 } else {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
50 winsize = 8;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
51 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
52
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
53 winsize = MAX_WINSIZE ? MP_MIN(MAX_WINSIZE, winsize) : winsize;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
54
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
55 /* init M array */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
56 /* init first cell */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
57 if ((err = mp_init_size(&M[1], P->alloc)) != MP_OKAY) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
58 return err;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
59 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
60
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
61 /* now init the second half of the array */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
62 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
63 if ((err = mp_init_size(&M[x], P->alloc)) != MP_OKAY) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
64 for (y = 1<<(winsize-1); y < x; y++) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
65 mp_clear(&M[y]);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
66 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
67 mp_clear(&M[1]);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
68 return err;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
69 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
70 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
71
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
72 /* determine and setup reduction code */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
73 if (redmode == 0) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
74 if (MP_HAS(MP_MONTGOMERY_SETUP)) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
75 /* now setup montgomery */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
76 if ((err = mp_montgomery_setup(P, &mp)) != MP_OKAY) goto LBL_M;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
77 } else {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
78 err = MP_VAL;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
79 goto LBL_M;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
80 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
81
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
82 /* automatically pick the comba one if available (saves quite a few calls/ifs) */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
83 if (MP_HAS(S_MP_MONTGOMERY_REDUCE_FAST) &&
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
84 (((P->used * 2) + 1) < MP_WARRAY) &&
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
85 (P->used < MP_MAXFAST)) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
86 redux = s_mp_montgomery_reduce_fast;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
87 } else if (MP_HAS(MP_MONTGOMERY_REDUCE)) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
88 /* use slower baseline Montgomery method */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
89 redux = mp_montgomery_reduce;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
90 } else {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
91 err = MP_VAL;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
92 goto LBL_M;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
93 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
94 } else if (redmode == 1) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
95 if (MP_HAS(MP_DR_SETUP) && MP_HAS(MP_DR_REDUCE)) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
96 /* setup DR reduction for moduli of the form B**k - b */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
97 mp_dr_setup(P, &mp);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
98 redux = mp_dr_reduce;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
99 } else {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
100 err = MP_VAL;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
101 goto LBL_M;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
102 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
103 } else if (MP_HAS(MP_REDUCE_2K_SETUP) && MP_HAS(MP_REDUCE_2K)) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
104 /* setup DR reduction for moduli of the form 2**k - b */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
105 if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) goto LBL_M;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
106 redux = mp_reduce_2k;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
107 } else {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
108 err = MP_VAL;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
109 goto LBL_M;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
110 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
111
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
112 /* setup result */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
113 if ((err = mp_init_size(&res, P->alloc)) != MP_OKAY) goto LBL_M;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
114
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
115 /* create M table
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
116 *
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
117
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
118 *
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
119 * The first half of the table is not computed though accept for M[0] and M[1]
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
120 */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
121
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
122 if (redmode == 0) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
123 if (MP_HAS(MP_MONTGOMERY_CALC_NORMALIZATION)) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
124 /* now we need R mod m */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
125 if ((err = mp_montgomery_calc_normalization(&res, P)) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
126
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
127 /* now set M[1] to G * R mod m */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
128 if ((err = mp_mulmod(G, &res, P, &M[1])) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
129 } else {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
130 err = MP_VAL;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
131 goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
132 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
133 } else {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
134 mp_set(&res, 1uL);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
135 if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
136 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
137
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
138 /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
139 if ((err = mp_copy(&M[1], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
140
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
141 for (x = 0; x < (winsize - 1); x++) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
142 if ((err = mp_sqr(&M[(size_t)1 << (winsize - 1)], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
143 if ((err = redux(&M[(size_t)1 << (winsize - 1)], P, mp)) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
144 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
145
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
146 /* create upper table */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
147 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
148 if ((err = mp_mul(&M[x - 1], &M[1], &M[x])) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
149 if ((err = redux(&M[x], P, mp)) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
150 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
151
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
152 /* set initial mode and bit cnt */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
153 mode = 0;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
154 bitcnt = 1;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
155 buf = 0;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
156 digidx = X->used - 1;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
157 bitcpy = 0;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
158 bitbuf = 0;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
159
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
160 for (;;) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
161 /* grab next digit as required */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
162 if (--bitcnt == 0) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
163 /* if digidx == -1 we are out of digits so break */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
164 if (digidx == -1) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
165 break;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
166 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
167 /* read next digit and reset bitcnt */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
168 buf = X->dp[digidx--];
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
169 bitcnt = (int)MP_DIGIT_BIT;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
170 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
171
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
172 /* grab the next msb from the exponent */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
173 y = (mp_digit)(buf >> (MP_DIGIT_BIT - 1)) & 1uL;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
174 buf <<= (mp_digit)1;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
175
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
176 /* if the bit is zero and mode == 0 then we ignore it
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
177 * These represent the leading zero bits before the first 1 bit
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
178 * in the exponent. Technically this opt is not required but it
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
179 * does lower the # of trivial squaring/reductions used
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
180 */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
181 if ((mode == 0) && (y == 0)) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
182 continue;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
183 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
184
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
185 /* if the bit is zero and mode == 1 then we square */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
186 if ((mode == 1) && (y == 0)) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
187 if ((err = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
188 if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
189 continue;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
190 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
191
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
192 /* else we add it to the window */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
193 bitbuf |= (y << (winsize - ++bitcpy));
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
194 mode = 2;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
195
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
196 if (bitcpy == winsize) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
197 /* ok window is filled so square as required and multiply */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
198 /* square first */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
199 for (x = 0; x < winsize; x++) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
200 if ((err = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
201 if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
202 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
203
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
204 /* then multiply */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
205 if ((err = mp_mul(&res, &M[bitbuf], &res)) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
206 if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
207
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
208 /* empty window and reset */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
209 bitcpy = 0;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
210 bitbuf = 0;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
211 mode = 1;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
212 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
213 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
214
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
215 /* if bits remain then square/multiply */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
216 if ((mode == 2) && (bitcpy > 0)) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
217 /* square then multiply if the bit is set */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
218 for (x = 0; x < bitcpy; x++) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
219 if ((err = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
220 if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
221
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
222 /* get next bit of the window */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
223 bitbuf <<= 1;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
224 if ((bitbuf & (1 << winsize)) != 0) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
225 /* then multiply */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
226 if ((err = mp_mul(&res, &M[1], &res)) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
227 if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
228 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
229 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
230 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
231
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
232 if (redmode == 0) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
233 /* fixup result if Montgomery reduction is used
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
234 * recall that any value in a Montgomery system is
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
235 * actually multiplied by R mod n. So we have
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
236 * to reduce one more time to cancel out the factor
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
237 * of R.
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
238 */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
239 if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
240 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
241
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
242 /* swap res with Y */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
243 mp_exch(&res, Y);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
244 err = MP_OKAY;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
245 LBL_RES:
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
246 mp_clear(&res);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
247 LBL_M:
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
248 mp_clear(&M[1]);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
249 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
250 mp_clear(&M[x]);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
251 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
252 return err;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
253 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
254 #endif