Mercurial > dropbear
comparison bn_s_mp_exptmod.c @ 190:d8254fc979e9 libtommath-orig LTM_0.35
Initial import of libtommath 0.35
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 06 May 2005 08:59:30 +0000 |
parents | d29b64170cf0 |
children |
comparison
equal
deleted
inserted
replaced
142:d29b64170cf0 | 190:d8254fc979e9 |
---|---|
19 #define TAB_SIZE 32 | 19 #define TAB_SIZE 32 |
20 #else | 20 #else |
21 #define TAB_SIZE 256 | 21 #define TAB_SIZE 256 |
22 #endif | 22 #endif |
23 | 23 |
24 int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) | 24 int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) |
25 { | 25 { |
26 mp_int M[TAB_SIZE], res, mu; | 26 mp_int M[TAB_SIZE], res, mu; |
27 mp_digit buf; | 27 mp_digit buf; |
28 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; | 28 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; |
29 int (*redux)(mp_int*,mp_int*,mp_int*); | |
29 | 30 |
30 /* find window size */ | 31 /* find window size */ |
31 x = mp_count_bits (X); | 32 x = mp_count_bits (X); |
32 if (x <= 7) { | 33 if (x <= 7) { |
33 winsize = 2; | 34 winsize = 2; |
68 } | 69 } |
69 } | 70 } |
70 | 71 |
71 /* create mu, used for Barrett reduction */ | 72 /* create mu, used for Barrett reduction */ |
72 if ((err = mp_init (&mu)) != MP_OKAY) { | 73 if ((err = mp_init (&mu)) != MP_OKAY) { |
73 goto __M; | 74 goto LBL_M; |
74 } | 75 } |
75 if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { | 76 |
76 goto __MU; | 77 if (redmode == 0) { |
77 } | 78 if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { |
79 goto LBL_MU; | |
80 } | |
81 redux = mp_reduce; | |
82 } else { | |
83 if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { | |
84 goto LBL_MU; | |
85 } | |
86 redux = mp_reduce_2k_l; | |
87 } | |
78 | 88 |
79 /* create M table | 89 /* create M table |
80 * | 90 * |
81 * The M table contains powers of the base, | 91 * The M table contains powers of the base, |
82 * e.g. M[x] = G**x mod P | 92 * e.g. M[x] = G**x mod P |
83 * | 93 * |
84 * The first half of the table is not | 94 * The first half of the table is not |
85 * computed though accept for M[0] and M[1] | 95 * computed though accept for M[0] and M[1] |
86 */ | 96 */ |
87 if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { | 97 if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { |
88 goto __MU; | 98 goto LBL_MU; |
89 } | 99 } |
90 | 100 |
91 /* compute the value at M[1<<(winsize-1)] by squaring | 101 /* compute the value at M[1<<(winsize-1)] by squaring |
92 * M[1] (winsize-1) times | 102 * M[1] (winsize-1) times |
93 */ | 103 */ |
94 if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { | 104 if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { |
95 goto __MU; | 105 goto LBL_MU; |
96 } | 106 } |
97 | 107 |
98 for (x = 0; x < (winsize - 1); x++) { | 108 for (x = 0; x < (winsize - 1); x++) { |
109 /* square it */ | |
99 if ((err = mp_sqr (&M[1 << (winsize - 1)], | 110 if ((err = mp_sqr (&M[1 << (winsize - 1)], |
100 &M[1 << (winsize - 1)])) != MP_OKAY) { | 111 &M[1 << (winsize - 1)])) != MP_OKAY) { |
101 goto __MU; | 112 goto LBL_MU; |
102 } | 113 } |
103 if ((err = mp_reduce (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { | 114 |
104 goto __MU; | 115 /* reduce modulo P */ |
116 if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { | |
117 goto LBL_MU; | |
105 } | 118 } |
106 } | 119 } |
107 | 120 |
108 /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) | 121 /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) |
109 * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) | 122 * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) |
110 */ | 123 */ |
111 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { | 124 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { |
112 if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { | 125 if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { |
113 goto __MU; | 126 goto LBL_MU; |
114 } | 127 } |
115 if ((err = mp_reduce (&M[x], P, &mu)) != MP_OKAY) { | 128 if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { |
116 goto __MU; | 129 goto LBL_MU; |
117 } | 130 } |
118 } | 131 } |
119 | 132 |
120 /* setup result */ | 133 /* setup result */ |
121 if ((err = mp_init (&res)) != MP_OKAY) { | 134 if ((err = mp_init (&res)) != MP_OKAY) { |
122 goto __MU; | 135 goto LBL_MU; |
123 } | 136 } |
124 mp_set (&res, 1); | 137 mp_set (&res, 1); |
125 | 138 |
126 /* set initial mode and bit cnt */ | 139 /* set initial mode and bit cnt */ |
127 mode = 0; | 140 mode = 0; |
157 } | 170 } |
158 | 171 |
159 /* if the bit is zero and mode == 1 then we square */ | 172 /* if the bit is zero and mode == 1 then we square */ |
160 if (mode == 1 && y == 0) { | 173 if (mode == 1 && y == 0) { |
161 if ((err = mp_sqr (&res, &res)) != MP_OKAY) { | 174 if ((err = mp_sqr (&res, &res)) != MP_OKAY) { |
162 goto __RES; | 175 goto LBL_RES; |
163 } | 176 } |
164 if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { | 177 if ((err = redux (&res, P, &mu)) != MP_OKAY) { |
165 goto __RES; | 178 goto LBL_RES; |
166 } | 179 } |
167 continue; | 180 continue; |
168 } | 181 } |
169 | 182 |
170 /* else we add it to the window */ | 183 /* else we add it to the window */ |
174 if (bitcpy == winsize) { | 187 if (bitcpy == winsize) { |
175 /* ok window is filled so square as required and multiply */ | 188 /* ok window is filled so square as required and multiply */ |
176 /* square first */ | 189 /* square first */ |
177 for (x = 0; x < winsize; x++) { | 190 for (x = 0; x < winsize; x++) { |
178 if ((err = mp_sqr (&res, &res)) != MP_OKAY) { | 191 if ((err = mp_sqr (&res, &res)) != MP_OKAY) { |
179 goto __RES; | 192 goto LBL_RES; |
180 } | 193 } |
181 if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { | 194 if ((err = redux (&res, P, &mu)) != MP_OKAY) { |
182 goto __RES; | 195 goto LBL_RES; |
183 } | 196 } |
184 } | 197 } |
185 | 198 |
186 /* then multiply */ | 199 /* then multiply */ |
187 if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { | 200 if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { |
188 goto __RES; | 201 goto LBL_RES; |
189 } | 202 } |
190 if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { | 203 if ((err = redux (&res, P, &mu)) != MP_OKAY) { |
191 goto __RES; | 204 goto LBL_RES; |
192 } | 205 } |
193 | 206 |
194 /* empty window and reset */ | 207 /* empty window and reset */ |
195 bitcpy = 0; | 208 bitcpy = 0; |
196 bitbuf = 0; | 209 bitbuf = 0; |
201 /* if bits remain then square/multiply */ | 214 /* if bits remain then square/multiply */ |
202 if (mode == 2 && bitcpy > 0) { | 215 if (mode == 2 && bitcpy > 0) { |
203 /* square then multiply if the bit is set */ | 216 /* square then multiply if the bit is set */ |
204 for (x = 0; x < bitcpy; x++) { | 217 for (x = 0; x < bitcpy; x++) { |
205 if ((err = mp_sqr (&res, &res)) != MP_OKAY) { | 218 if ((err = mp_sqr (&res, &res)) != MP_OKAY) { |
206 goto __RES; | 219 goto LBL_RES; |
207 } | 220 } |
208 if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { | 221 if ((err = redux (&res, P, &mu)) != MP_OKAY) { |
209 goto __RES; | 222 goto LBL_RES; |
210 } | 223 } |
211 | 224 |
212 bitbuf <<= 1; | 225 bitbuf <<= 1; |
213 if ((bitbuf & (1 << winsize)) != 0) { | 226 if ((bitbuf & (1 << winsize)) != 0) { |
214 /* then multiply */ | 227 /* then multiply */ |
215 if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { | 228 if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { |
216 goto __RES; | 229 goto LBL_RES; |
217 } | 230 } |
218 if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { | 231 if ((err = redux (&res, P, &mu)) != MP_OKAY) { |
219 goto __RES; | 232 goto LBL_RES; |
220 } | 233 } |
221 } | 234 } |
222 } | 235 } |
223 } | 236 } |
224 | 237 |
225 mp_exch (&res, Y); | 238 mp_exch (&res, Y); |
226 err = MP_OKAY; | 239 err = MP_OKAY; |
227 __RES:mp_clear (&res); | 240 LBL_RES:mp_clear (&res); |
228 __MU:mp_clear (&mu); | 241 LBL_MU:mp_clear (&mu); |
229 __M: | 242 LBL_M: |
230 mp_clear(&M[1]); | 243 mp_clear(&M[1]); |
231 for (x = 1<<(winsize-1); x < (1 << winsize); x++) { | 244 for (x = 1<<(winsize-1); x < (1 << winsize); x++) { |
232 mp_clear (&M[x]); | 245 mp_clear (&M[x]); |
233 } | 246 } |
234 return err; | 247 return err; |