OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* crypto/bn/bn_exp.c */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
||
3 | * All rights reserved. |
||
4 | * |
||
5 | * This package is an SSL implementation written |
||
6 | * by Eric Young (eay@cryptsoft.com). |
||
7 | * The implementation was written so as to conform with Netscapes SSL. |
||
8 | * |
||
9 | * This library is free for commercial and non-commercial use as long as |
||
10 | * the following conditions are aheared to. The following conditions |
||
11 | * apply to all code found in this distribution, be it the RC4, RSA, |
||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
||
13 | * included with this distribution is covered by the same copyright terms |
||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
||
15 | * |
||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in |
||
17 | * the code are not to be removed. |
||
18 | * If this package is used in a product, Eric Young should be given attribution |
||
19 | * as the author of the parts of the library used. |
||
20 | * This can be in the form of a textual message at program startup or |
||
21 | * in documentation (online or textual) provided with the package. |
||
22 | * |
||
23 | * Redistribution and use in source and binary forms, with or without |
||
24 | * modification, are permitted provided that the following conditions |
||
25 | * are met: |
||
26 | * 1. Redistributions of source code must retain the copyright |
||
27 | * notice, this list of conditions and the following disclaimer. |
||
28 | * 2. Redistributions in binary form must reproduce the above copyright |
||
29 | * notice, this list of conditions and the following disclaimer in the |
||
30 | * documentation and/or other materials provided with the distribution. |
||
31 | * 3. All advertising materials mentioning features or use of this software |
||
32 | * must display the following acknowledgement: |
||
33 | * "This product includes cryptographic software written by |
||
34 | * Eric Young (eay@cryptsoft.com)" |
||
35 | * The word 'cryptographic' can be left out if the rouines from the library |
||
36 | * being used are not cryptographic related :-). |
||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from |
||
38 | * the apps directory (application code) you must include an acknowledgement: |
||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
||
40 | * |
||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
||
51 | * SUCH DAMAGE. |
||
52 | * |
||
53 | * The licence and distribution terms for any publically available version or |
||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be |
||
55 | * copied and put under another distribution licence |
||
56 | * [including the GNU Public Licence.] |
||
57 | */ |
||
58 | /* ==================================================================== |
||
59 | * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. |
||
60 | * |
||
61 | * Redistribution and use in source and binary forms, with or without |
||
62 | * modification, are permitted provided that the following conditions |
||
63 | * are met: |
||
64 | * |
||
65 | * 1. Redistributions of source code must retain the above copyright |
||
66 | * notice, this list of conditions and the following disclaimer. |
||
67 | * |
||
68 | * 2. Redistributions in binary form must reproduce the above copyright |
||
69 | * notice, this list of conditions and the following disclaimer in |
||
70 | * the documentation and/or other materials provided with the |
||
71 | * distribution. |
||
72 | * |
||
73 | * 3. All advertising materials mentioning features or use of this |
||
74 | * software must display the following acknowledgment: |
||
75 | * "This product includes software developed by the OpenSSL Project |
||
76 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" |
||
77 | * |
||
78 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
||
79 | * endorse or promote products derived from this software without |
||
80 | * prior written permission. For written permission, please contact |
||
81 | * openssl-core@openssl.org. |
||
82 | * |
||
83 | * 5. Products derived from this software may not be called "OpenSSL" |
||
84 | * nor may "OpenSSL" appear in their names without prior written |
||
85 | * permission of the OpenSSL Project. |
||
86 | * |
||
87 | * 6. Redistributions of any form whatsoever must retain the following |
||
88 | * acknowledgment: |
||
89 | * "This product includes software developed by the OpenSSL Project |
||
90 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" |
||
91 | * |
||
92 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
||
93 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||
94 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||
95 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
||
96 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||
97 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||
98 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||
99 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
||
100 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||
101 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||
102 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
||
103 | * OF THE POSSIBILITY OF SUCH DAMAGE. |
||
104 | * ==================================================================== |
||
105 | * |
||
106 | * This product includes cryptographic software written by Eric Young |
||
107 | * (eay@cryptsoft.com). This product includes software written by Tim |
||
108 | * Hudson (tjh@cryptsoft.com). |
||
109 | * |
||
110 | */ |
||
111 | |||
112 | |||
113 | #include <stdio.h> |
||
114 | #include "bn_lcl.h" |
||
115 | |||
116 | #define TABLE_SIZE 32 |
||
117 | |||
118 | /* slow but works */ |
||
119 | int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) |
||
120 | { |
||
121 | BIGNUM *t; |
||
122 | int r=0; |
||
123 | |||
124 | bn_check_top(a); |
||
125 | bn_check_top(b); |
||
126 | bn_check_top(m); |
||
127 | |||
128 | BN_CTX_start(ctx); |
||
129 | if ((t = BN_CTX_get(ctx)) == NULL) goto err; |
||
130 | if (a == b) |
||
131 | { if (!BN_sqr(t,a,ctx)) goto err; } |
||
132 | else |
||
133 | { if (!BN_mul(t,a,b,ctx)) goto err; } |
||
134 | if (!BN_mod(ret,t,m,ctx)) goto err; |
||
135 | r=1; |
||
136 | err: |
||
137 | BN_CTX_end(ctx); |
||
138 | return(r); |
||
139 | } |
||
140 | |||
141 | int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, |
||
142 | BN_CTX *ctx) |
||
143 | { |
||
144 | int ret; |
||
145 | |||
146 | bn_check_top(a); |
||
147 | bn_check_top(p); |
||
148 | bn_check_top(m); |
||
149 | |||
150 | #ifdef MONT_MUL_MOD |
||
151 | /* I have finally been able to take out this pre-condition of |
||
152 | * the top bit being set. It was caused by an error in BN_div |
||
153 | * with negatives. There was also another problem when for a^b%m |
||
154 | * a >= m. eay 07-May-97 */ |
||
155 | /* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */ |
||
156 | |||
157 | if (BN_is_odd(m)) |
||
158 | { |
||
159 | if (a->top == 1) |
||
160 | { |
||
161 | BN_ULONG A = a->d[0]; |
||
162 | ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL); |
||
163 | } |
||
164 | else |
||
165 | ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL); |
||
166 | } |
||
167 | else |
||
168 | #endif |
||
169 | #ifdef RECP_MUL_MOD |
||
170 | { ret=BN_mod_exp_recp(r,a,p,m,ctx); } |
||
171 | #else |
||
172 | { ret=BN_mod_exp_simple(r,a,p,m,ctx); } |
||
173 | #endif |
||
174 | |||
175 | return(ret); |
||
176 | } |
||
177 | |||
178 | |||
179 | #ifdef RECP_MUL_MOD |
||
180 | int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, |
||
181 | const BIGNUM *m, BN_CTX *ctx) |
||
182 | { |
||
183 | int i,j,bits,ret=0,wstart,wend,window,wvalue; |
||
184 | int start=1,ts=0; |
||
185 | BIGNUM *aa; |
||
186 | BIGNUM val[TABLE_SIZE]; |
||
187 | BN_RECP_CTX recp; |
||
188 | |||
189 | bits=BN_num_bits(p); |
||
190 | |||
191 | if (bits == 0) |
||
192 | { |
||
193 | BN_one(r); |
||
194 | return(1); |
||
195 | } |
||
196 | |||
197 | BN_CTX_start(ctx); |
||
198 | if ((aa = BN_CTX_get(ctx)) == NULL) goto err; |
||
199 | |||
200 | BN_RECP_CTX_init(&recp); |
||
201 | if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err; |
||
202 | |||
203 | BN_init(&(val[0])); |
||
204 | ts=1; |
||
205 | |||
206 | if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */ |
||
207 | |||
208 | window = BN_window_bits_for_exponent_size(bits); |
||
209 | if (window > 1) |
||
210 | { |
||
211 | if (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx)) |
||
212 | goto err; /* 2 */ |
||
213 | j=1<<(window-1); |
||
214 | for (i=1; i<j; i++) |
||
215 | { |
||
216 | BN_init(&val[i]); |
||
217 | if (!BN_mod_mul_reciprocal(&(val[i]),&(val[i-1]),aa,&recp,ctx)) |
||
218 | goto err; |
||
219 | } |
||
220 | ts=i; |
||
221 | } |
||
222 | |||
223 | start=1; /* This is used to avoid multiplication etc |
||
224 | * when there is only the value '1' in the |
||
225 | * buffer. */ |
||
226 | wvalue=0; /* The 'value' of the window */ |
||
227 | wstart=bits-1; /* The top bit of the window */ |
||
228 | wend=0; /* The bottom bit of the window */ |
||
229 | |||
230 | if (!BN_one(r)) goto err; |
||
231 | |||
232 | for (;;) |
||
233 | { |
||
234 | if (BN_is_bit_set(p,wstart) == 0) |
||
235 | { |
||
236 | if (!start) |
||
237 | if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx)) |
||
238 | goto err; |
||
239 | if (wstart == 0) break; |
||
240 | wstart--; |
||
241 | continue; |
||
242 | } |
||
243 | /* We now have wstart on a 'set' bit, we now need to work out |
||
244 | * how bit a window to do. To do this we need to scan |
||
245 | * forward until the last set bit before the end of the |
||
246 | * window */ |
||
247 | j=wstart; |
||
248 | wvalue=1; |
||
249 | wend=0; |
||
250 | for (i=1; i<window; i++) |
||
251 | { |
||
252 | if (wstart-i < 0) break; |
||
253 | if (BN_is_bit_set(p,wstart-i)) |
||
254 | { |
||
255 | wvalue<<=(i-wend); |
||
256 | wvalue|=1; |
||
257 | wend=i; |
||
258 | } |
||
259 | } |
||
260 | |||
261 | /* wend is the size of the current window */ |
||
262 | j=wend+1; |
||
263 | /* add the 'bytes above' */ |
||
264 | if (!start) |
||
265 | for (i=0; i<j; i++) |
||
266 | { |
||
267 | if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx)) |
||
268 | goto err; |
||
269 | } |
||
270 | |||
271 | /* wvalue will be an odd number < 2^window */ |
||
272 | if (!BN_mod_mul_reciprocal(r,r,&(val[wvalue>>1]),&recp,ctx)) |
||
273 | goto err; |
||
274 | |||
275 | /* move the 'window' down further */ |
||
276 | wstart-=wend+1; |
||
277 | wvalue=0; |
||
278 | start=0; |
||
279 | if (wstart < 0) break; |
||
280 | } |
||
281 | ret=1; |
||
282 | err: |
||
283 | BN_CTX_end(ctx); |
||
284 | for (i=0; i<ts; i++) |
||
285 | BN_clear_free(&(val[i])); |
||
286 | BN_RECP_CTX_free(&recp); |
||
287 | return(ret); |
||
288 | } |
||
289 | #else |
||
290 | |||
291 | /* The old fallback, simple version :-) */ |
||
292 | int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, |
||
293 | const BIGNUM *m, BN_CTX *ctx) |
||
294 | { |
||
295 | int i,j,bits,ret=0,wstart,wend,window,wvalue,ts=0; |
||
296 | int start=1; |
||
297 | BIGNUM *d; |
||
298 | BIGNUM val[TABLE_SIZE]; |
||
299 | |||
300 | bits=BN_num_bits(p); |
||
301 | |||
302 | if (bits == 0) |
||
303 | { |
||
304 | BN_one(r); |
||
305 | return(1); |
||
306 | } |
||
307 | |||
308 | BN_CTX_start(ctx); |
||
309 | if ((d = BN_CTX_get(ctx)) == NULL) goto err; |
||
310 | |||
311 | BN_init(&(val[0])); |
||
312 | ts=1; |
||
313 | if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */ |
||
314 | |||
315 | window = BN_window_bits_for_exponent_size(bits); |
||
316 | if (window > 1) |
||
317 | { |
||
318 | if (!BN_mod_mul(d,&(val[0]),&(val[0]),m,ctx)) |
||
319 | goto err; /* 2 */ |
||
320 | j=1<<(window-1); |
||
321 | for (i=1; i<j; i++) |
||
322 | { |
||
323 | BN_init(&(val[i])); |
||
324 | if (!BN_mod_mul(&(val[i]),&(val[i-1]),d,m,ctx)) |
||
325 | goto err; |
||
326 | } |
||
327 | ts=i; |
||
328 | } |
||
329 | |||
330 | start=1; /* This is used to avoid multiplication etc |
||
331 | * when there is only the value '1' in the |
||
332 | * buffer. */ |
||
333 | wvalue=0; /* The 'value' of the window */ |
||
334 | wstart=bits-1; /* The top bit of the window */ |
||
335 | wend=0; /* The bottom bit of the window */ |
||
336 | |||
337 | if (!BN_one(r)) goto err; |
||
338 | |||
339 | for (;;) |
||
340 | { |
||
341 | if (BN_is_bit_set(p,wstart) == 0) |
||
342 | { |
||
343 | if (!start) |
||
344 | if (!BN_mod_mul(r,r,r,m,ctx)) |
||
345 | goto err; |
||
346 | if (wstart == 0) break; |
||
347 | wstart--; |
||
348 | continue; |
||
349 | } |
||
350 | /* We now have wstart on a 'set' bit, we now need to work out |
||
351 | * how bit a window to do. To do this we need to scan |
||
352 | * forward until the last set bit before the end of the |
||
353 | * window */ |
||
354 | j=wstart; |
||
355 | wvalue=1; |
||
356 | wend=0; |
||
357 | for (i=1; i<window; i++) |
||
358 | { |
||
359 | if (wstart-i < 0) break; |
||
360 | if (BN_is_bit_set(p,wstart-i)) |
||
361 | { |
||
362 | wvalue<<=(i-wend); |
||
363 | wvalue|=1; |
||
364 | wend=i; |
||
365 | } |
||
366 | } |
||
367 | |||
368 | /* wend is the size of the current window */ |
||
369 | j=wend+1; |
||
370 | /* add the 'bytes above' */ |
||
371 | if (!start) |
||
372 | for (i=0; i<j; i++) |
||
373 | { |
||
374 | if (!BN_mod_mul(r,r,r,m,ctx)) |
||
375 | goto err; |
||
376 | } |
||
377 | |||
378 | /* wvalue will be an odd number < 2^window */ |
||
379 | if (!BN_mod_mul(r,r,&(val[wvalue>>1]),m,ctx)) |
||
380 | goto err; |
||
381 | |||
382 | /* move the 'window' down further */ |
||
383 | wstart-=wend+1; |
||
384 | wvalue=0; |
||
385 | start=0; |
||
386 | if (wstart < 0) break; |
||
387 | } |
||
388 | ret=1; |
||
389 | err: |
||
390 | BN_CTX_end(ctx); |
||
391 | for (i=0; i<ts; i++) |
||
392 | BN_clear_free(&(val[i])); |
||
393 | return(ret); |
||
394 | } |
||
395 | #endif |