diff options
author | beck <> | 2000-03-19 11:13:58 +0000 |
---|---|---|
committer | beck <> | 2000-03-19 11:13:58 +0000 |
commit | 796d609550df3a33fc11468741c5d2f6d3df4c11 (patch) | |
tree | 6c6d539061caa20372dad0ac4ddb1dfae2fbe7fe /src/lib/libcrypto/bn/bn_mont.c | |
parent | 5be3114c1fd7e0dfea1e38d3abb4cbba75244419 (diff) | |
download | openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.tar.gz openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.tar.bz2 openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.zip |
OpenSSL 0.9.5 merge
*warning* this bumps shared lib minors for libssl and libcrypto from 2.1 to 2.2
if you are using the ssl26 packages for ssh and other things to work you will
need to get new ones (see ~beck/libsslsnap/<arch>) on cvs or ~beck/src-patent.tar.gz on cvs
Diffstat (limited to 'src/lib/libcrypto/bn/bn_mont.c')
-rw-r--r-- | src/lib/libcrypto/bn/bn_mont.c | 313 |
1 files changed, 122 insertions, 191 deletions
diff --git a/src/lib/libcrypto/bn/bn_mont.c b/src/lib/libcrypto/bn/bn_mont.c index ee0f410c22..7bb0b91223 100644 --- a/src/lib/libcrypto/bn/bn_mont.c +++ b/src/lib/libcrypto/bn/bn_mont.c | |||
@@ -57,25 +57,27 @@ | |||
57 | */ | 57 | */ |
58 | 58 | ||
59 | /* | 59 | /* |
60 | * Details about Montgomery multiplication algorithms can be found at: | 60 | * Details about Montgomery multiplication algorithms can be found at |
61 | * http://www.ece.orst.edu/ISL/Publications.html | 61 | * http://security.ece.orst.edu/publications.html, e.g. |
62 | * http://www.ece.orst.edu/ISL/Koc/papers/j37acmon.pdf | 62 | * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and |
63 | * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf | ||
63 | */ | 64 | */ |
64 | 65 | ||
65 | #include <stdio.h> | 66 | #include <stdio.h> |
66 | #include "cryptlib.h" | 67 | #include "cryptlib.h" |
67 | #include "bn_lcl.h" | 68 | #include "bn_lcl.h" |
68 | 69 | ||
69 | #define MONT_WORD | 70 | #define MONT_WORD /* use the faster word-based algorithm */ |
70 | 71 | ||
71 | int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b, | 72 | int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b, |
72 | BN_MONT_CTX *mont, BN_CTX *ctx) | 73 | BN_MONT_CTX *mont, BN_CTX *ctx) |
73 | { | 74 | { |
74 | BIGNUM *tmp,*tmp2; | 75 | BIGNUM *tmp,*tmp2; |
75 | 76 | ||
76 | tmp= &(ctx->bn[ctx->tos]); | 77 | BN_CTX_start(ctx); |
77 | tmp2= &(ctx->bn[ctx->tos]); | 78 | tmp = BN_CTX_get(ctx); |
78 | ctx->tos+=2; | 79 | tmp2 = BN_CTX_get(ctx); |
80 | if (tmp == NULL || tmp2 == NULL) goto err; | ||
79 | 81 | ||
80 | bn_check_top(tmp); | 82 | bn_check_top(tmp); |
81 | bn_check_top(tmp2); | 83 | bn_check_top(tmp2); |
@@ -99,7 +101,7 @@ int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b, | |||
99 | } | 101 | } |
100 | /* reduce from aRR to aR */ | 102 | /* reduce from aRR to aR */ |
101 | if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err; | 103 | if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err; |
102 | ctx->tos-=2; | 104 | BN_CTX_end(ctx); |
103 | return(1); | 105 | return(1); |
104 | err: | 106 | err: |
105 | return(0); | 107 | return(0); |
@@ -108,160 +110,123 @@ err: | |||
108 | int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont, | 110 | int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont, |
109 | BN_CTX *ctx) | 111 | BN_CTX *ctx) |
110 | { | 112 | { |
111 | #ifdef BN_RECURSION_MONT | 113 | int retn=0; |
112 | if (mont->use_word) | ||
113 | #endif | ||
114 | { | ||
115 | BIGNUM *n,*r; | ||
116 | BN_ULONG *ap,*np,*rp,n0,v,*nrp; | ||
117 | int al,nl,max,i,x,ri; | ||
118 | int retn=0; | ||
119 | 114 | ||
120 | r= &(ctx->bn[ctx->tos]); | 115 | #ifdef MONT_WORD |
116 | BIGNUM *n,*r; | ||
117 | BN_ULONG *ap,*np,*rp,n0,v,*nrp; | ||
118 | int al,nl,max,i,x,ri; | ||
121 | 119 | ||
122 | if (!BN_copy(r,a)) goto err1; | 120 | BN_CTX_start(ctx); |
123 | n= &(mont->N); | 121 | if ((r = BN_CTX_get(ctx)) == NULL) goto err; |
124 | 122 | ||
125 | ap=a->d; | 123 | if (!BN_copy(r,a)) goto err; |
126 | /* mont->ri is the size of mont->N in bits/words */ | 124 | n= &(mont->N); |
127 | al=ri=mont->ri/BN_BITS2; | ||
128 | 125 | ||
129 | nl=n->top; | 126 | ap=a->d; |
130 | if ((al == 0) || (nl == 0)) { r->top=0; return(1); } | 127 | /* mont->ri is the size of mont->N in bits (rounded up |
128 | to the word size) */ | ||
129 | al=ri=mont->ri/BN_BITS2; | ||
130 | |||
131 | nl=n->top; | ||
132 | if ((al == 0) || (nl == 0)) { r->top=0; return(1); } | ||
131 | 133 | ||
132 | max=(nl+al+1); /* allow for overflow (no?) XXX */ | 134 | max=(nl+al+1); /* allow for overflow (no?) XXX */ |
133 | if (bn_wexpand(r,max) == NULL) goto err1; | 135 | if (bn_wexpand(r,max) == NULL) goto err; |
134 | if (bn_wexpand(ret,max) == NULL) goto err1; | 136 | if (bn_wexpand(ret,max) == NULL) goto err; |
135 | 137 | ||
136 | r->neg=a->neg^n->neg; | 138 | r->neg=a->neg^n->neg; |
137 | np=n->d; | 139 | np=n->d; |
138 | rp=r->d; | 140 | rp=r->d; |
139 | nrp= &(r->d[nl]); | 141 | nrp= &(r->d[nl]); |
140 | 142 | ||
141 | /* clear the top words of T */ | 143 | /* clear the top words of T */ |
142 | #if 1 | 144 | #if 1 |
143 | for (i=r->top; i<max; i++) /* memset? XXX */ | 145 | for (i=r->top; i<max; i++) /* memset? XXX */ |
144 | r->d[i]=0; | 146 | r->d[i]=0; |
145 | #else | 147 | #else |
146 | memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); | 148 | memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); |
147 | #endif | 149 | #endif |
148 | 150 | ||
149 | r->top=max; | 151 | r->top=max; |
150 | n0=mont->n0; | 152 | n0=mont->n0; |
151 | 153 | ||
152 | #ifdef BN_COUNT | 154 | #ifdef BN_COUNT |
153 | printf("word BN_from_montgomery %d * %d\n",nl,nl); | 155 | printf("word BN_from_montgomery %d * %d\n",nl,nl); |
154 | #endif | 156 | #endif |
155 | for (i=0; i<nl; i++) | 157 | for (i=0; i<nl; i++) |
156 | { | 158 | { |
157 | v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2); | 159 | v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2); |
158 | nrp++; | 160 | nrp++; |
159 | rp++; | 161 | rp++; |
160 | if (((nrp[-1]+=v)&BN_MASK2) >= v) | 162 | if (((nrp[-1]+=v)&BN_MASK2) >= v) |
161 | continue; | 163 | continue; |
162 | else | ||
163 | { | ||
164 | if (((++nrp[0])&BN_MASK2) != 0) continue; | ||
165 | if (((++nrp[1])&BN_MASK2) != 0) continue; | ||
166 | for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ; | ||
167 | } | ||
168 | } | ||
169 | bn_fix_top(r); | ||
170 | |||
171 | /* mont->ri will be a multiple of the word size */ | ||
172 | #if 0 | ||
173 | BN_rshift(ret,r,mont->ri); | ||
174 | #else | ||
175 | x=ri; | ||
176 | rp=ret->d; | ||
177 | ap= &(r->d[x]); | ||
178 | if (r->top < x) | ||
179 | al=0; | ||
180 | else | 164 | else |
181 | al=r->top-x; | ||
182 | ret->top=al; | ||
183 | al-=4; | ||
184 | for (i=0; i<al; i+=4) | ||
185 | { | 165 | { |
186 | BN_ULONG t1,t2,t3,t4; | 166 | if (((++nrp[0])&BN_MASK2) != 0) continue; |
187 | 167 | if (((++nrp[1])&BN_MASK2) != 0) continue; | |
188 | t1=ap[i+0]; | 168 | for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ; |
189 | t2=ap[i+1]; | ||
190 | t3=ap[i+2]; | ||
191 | t4=ap[i+3]; | ||
192 | rp[i+0]=t1; | ||
193 | rp[i+1]=t2; | ||
194 | rp[i+2]=t3; | ||
195 | rp[i+3]=t4; | ||
196 | } | 169 | } |
197 | al+=4; | ||
198 | for (; i<al; i++) | ||
199 | rp[i]=ap[i]; | ||
200 | #endif | ||
201 | |||
202 | if (BN_ucmp(ret, &(mont->N)) >= 0) | ||
203 | { | ||
204 | BN_usub(ret,ret,&(mont->N)); /* XXX */ | ||
205 | } | ||
206 | retn=1; | ||
207 | err1: | ||
208 | return(retn); | ||
209 | } | 170 | } |
210 | #ifdef BN_RECURSION_MONT | 171 | bn_fix_top(r); |
211 | else /* bignum version */ | 172 | |
173 | /* mont->ri will be a multiple of the word size */ | ||
174 | #if 0 | ||
175 | BN_rshift(ret,r,mont->ri); | ||
176 | #else | ||
177 | x=ri; | ||
178 | rp=ret->d; | ||
179 | ap= &(r->d[x]); | ||
180 | if (r->top < x) | ||
181 | al=0; | ||
182 | else | ||
183 | al=r->top-x; | ||
184 | ret->top=al; | ||
185 | al-=4; | ||
186 | for (i=0; i<al; i+=4) | ||
212 | { | 187 | { |
213 | BIGNUM *t1,*t2,*t3; | 188 | BN_ULONG t1,t2,t3,t4; |
214 | int j,i; | 189 | |
215 | 190 | t1=ap[i+0]; | |
216 | #ifdef BN_COUNT | 191 | t2=ap[i+1]; |
217 | printf("number BN_from_montgomery\n"); | 192 | t3=ap[i+2]; |
218 | #endif | 193 | t4=ap[i+3]; |
219 | 194 | rp[i+0]=t1; | |
220 | t1= &(ctx->bn[ctx->tos]); | 195 | rp[i+1]=t2; |
221 | t2= &(ctx->bn[ctx->tos+1]); | 196 | rp[i+2]=t3; |
222 | t3= &(ctx->bn[ctx->tos+2]); | 197 | rp[i+3]=t4; |
223 | |||
224 | i=mont->Ni.top; | ||
225 | bn_wexpand(ret,i); /* perhaps only i*2 */ | ||
226 | bn_wexpand(t1,i*4); /* perhaps only i*2 */ | ||
227 | bn_wexpand(t2,i*2); /* perhaps only i */ | ||
228 | |||
229 | bn_mul_low_recursive(t2->d,a->d,mont->Ni.d,i,t1->d); | ||
230 | |||
231 | BN_zero(t3); | ||
232 | BN_set_bit(t3,mont->N.top*BN_BITS2); | ||
233 | bn_sub_words(t3->d,t3->d,a->d,i); | ||
234 | bn_mul_high(ret->d,t2->d,mont->N.d,t3->d,i,t1->d); | ||
235 | |||
236 | /* hmm... if a is between i and 2*i, things are bad */ | ||
237 | if (a->top > i) | ||
238 | { | ||
239 | j=(int)(bn_add_words(ret->d,ret->d,&(a->d[i]),i)); | ||
240 | if (j) /* overflow */ | ||
241 | bn_sub_words(ret->d,ret->d,mont->N.d,i); | ||
242 | } | ||
243 | ret->top=i; | ||
244 | bn_fix_top(ret); | ||
245 | if (a->d[0]) | ||
246 | BN_add_word(ret,1); /* Always? */ | ||
247 | else /* Very very rare */ | ||
248 | { | ||
249 | for (i=1; i<mont->N.top-1; i++) | ||
250 | { | ||
251 | if (a->d[i]) | ||
252 | { | ||
253 | BN_add_word(ret,1); /* Always? */ | ||
254 | break; | ||
255 | } | ||
256 | } | ||
257 | } | ||
258 | |||
259 | if (BN_ucmp(ret,&(mont->N)) >= 0) | ||
260 | BN_usub(ret,ret,&(mont->N)); | ||
261 | |||
262 | return(1); | ||
263 | } | 198 | } |
199 | al+=4; | ||
200 | for (; i<al; i++) | ||
201 | rp[i]=ap[i]; | ||
264 | #endif | 202 | #endif |
203 | #else /* !MONT_WORD */ | ||
204 | BIGNUM *t1,*t2; | ||
205 | |||
206 | BN_CTX_start(ctx); | ||
207 | t1 = BN_CTX_get(ctx); | ||
208 | t2 = BN_CTX_get(ctx); | ||
209 | if (t1 == NULL || t2 == NULL) goto err; | ||
210 | |||
211 | if (!BN_copy(t1,a)) goto err; | ||
212 | BN_mask_bits(t1,mont->ri); | ||
213 | |||
214 | if (!BN_mul(t2,t1,&mont->Ni,ctx)) goto err; | ||
215 | BN_mask_bits(t2,mont->ri); | ||
216 | |||
217 | if (!BN_mul(t1,t2,&mont->N,ctx)) goto err; | ||
218 | if (!BN_add(t2,a,t1)) goto err; | ||
219 | BN_rshift(ret,t2,mont->ri); | ||
220 | #endif /* MONT_WORD */ | ||
221 | |||
222 | if (BN_ucmp(ret, &(mont->N)) >= 0) | ||
223 | { | ||
224 | BN_usub(ret,ret,&(mont->N)); | ||
225 | } | ||
226 | retn=1; | ||
227 | err: | ||
228 | BN_CTX_end(ctx); | ||
229 | return(retn); | ||
265 | } | 230 | } |
266 | 231 | ||
267 | BN_MONT_CTX *BN_MONT_CTX_new(void) | 232 | BN_MONT_CTX *BN_MONT_CTX_new(void) |
@@ -278,7 +243,6 @@ BN_MONT_CTX *BN_MONT_CTX_new(void) | |||
278 | 243 | ||
279 | void BN_MONT_CTX_init(BN_MONT_CTX *ctx) | 244 | void BN_MONT_CTX_init(BN_MONT_CTX *ctx) |
280 | { | 245 | { |
281 | ctx->use_word=0; | ||
282 | ctx->ri=0; | 246 | ctx->ri=0; |
283 | BN_init(&(ctx->RR)); | 247 | BN_init(&(ctx->RR)); |
284 | BN_init(&(ctx->N)); | 248 | BN_init(&(ctx->N)); |
@@ -306,85 +270,53 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) | |||
306 | R= &(mont->RR); /* grab RR as a temp */ | 270 | R= &(mont->RR); /* grab RR as a temp */ |
307 | BN_copy(&(mont->N),mod); /* Set N */ | 271 | BN_copy(&(mont->N),mod); /* Set N */ |
308 | 272 | ||
309 | #ifdef BN_RECURSION_MONT | 273 | #ifdef MONT_WORD |
310 | if (mont->N.top < BN_MONT_CTX_SET_SIZE_WORD) | ||
311 | #endif | ||
312 | { | 274 | { |
313 | BIGNUM tmod; | 275 | BIGNUM tmod; |
314 | BN_ULONG buf[2]; | 276 | BN_ULONG buf[2]; |
315 | 277 | ||
316 | mont->use_word=1; | ||
317 | |||
318 | mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; | 278 | mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; |
319 | BN_zero(R); | 279 | BN_zero(R); |
320 | BN_set_bit(R,BN_BITS2); | 280 | BN_set_bit(R,BN_BITS2); /* R */ |
321 | /* I was bad, this modification of a passed variable was | ||
322 | * breaking the multithreaded stuff :-( | ||
323 | * z=mod->top; | ||
324 | * mod->top=1; */ | ||
325 | 281 | ||
326 | buf[0]=mod->d[0]; | 282 | buf[0]=mod->d[0]; /* tmod = N mod word size */ |
327 | buf[1]=0; | 283 | buf[1]=0; |
328 | tmod.d=buf; | 284 | tmod.d=buf; |
329 | tmod.top=1; | 285 | tmod.top=1; |
330 | tmod.max=mod->max; | 286 | tmod.max=2; |
331 | tmod.neg=mod->neg; | 287 | tmod.neg=mod->neg; |
332 | 288 | /* Ri = R^-1 mod N*/ | |
333 | if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL) | 289 | if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL) |
334 | goto err; | 290 | goto err; |
335 | BN_lshift(&Ri,&Ri,BN_BITS2); /* R*Ri */ | 291 | BN_lshift(&Ri,&Ri,BN_BITS2); /* R*Ri */ |
336 | if (!BN_is_zero(&Ri)) | 292 | if (!BN_is_zero(&Ri)) |
337 | { | ||
338 | #if 1 | ||
339 | BN_sub_word(&Ri,1); | 293 | BN_sub_word(&Ri,1); |
340 | #else | 294 | else /* if N mod word size == 1 */ |
341 | BN_usub(&Ri,&Ri,BN_value_one()); /* R*Ri - 1 */ | 295 | BN_set_word(&Ri,BN_MASK2); /* Ri-- (mod word size) */ |
342 | #endif | 296 | BN_div(&Ri,NULL,&Ri,&tmod,ctx); /* Ni = (R*Ri-1)/N, |
343 | } | 297 | * keep only least significant word: */ |
344 | else | ||
345 | { | ||
346 | /* This is not common..., 1 in BN_MASK2, | ||
347 | * It happens when buf[0] was == 1. So for 8 bit, | ||
348 | * this is 1/256, 16bit, 1 in 2^16 etc. | ||
349 | */ | ||
350 | BN_set_word(&Ri,BN_MASK2); | ||
351 | } | ||
352 | BN_div(&Ri,NULL,&Ri,&tmod,ctx); | ||
353 | mont->n0=Ri.d[0]; | 298 | mont->n0=Ri.d[0]; |
354 | BN_free(&Ri); | 299 | BN_free(&Ri); |
355 | /* mod->top=z; */ | ||
356 | } | 300 | } |
357 | #ifdef BN_RECURSION_MONT | 301 | #else /* !MONT_WORD */ |
358 | else | 302 | { /* bignum version */ |
359 | { | 303 | mont->ri=BN_num_bits(mod); |
360 | mont->use_word=0; | ||
361 | mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; | ||
362 | #if 1 | ||
363 | BN_zero(R); | 304 | BN_zero(R); |
364 | BN_set_bit(R,mont->ri); | 305 | BN_set_bit(R,mont->ri); /* R = 2^ri */ |
365 | #else | 306 | /* Ri = R^-1 mod N*/ |
366 | BN_lshift(R,BN_value_one(),mont->ri); /* R */ | ||
367 | #endif | ||
368 | if ((BN_mod_inverse(&Ri,R,mod,ctx)) == NULL) | 307 | if ((BN_mod_inverse(&Ri,R,mod,ctx)) == NULL) |
369 | goto err; | 308 | goto err; |
370 | BN_lshift(&Ri,&Ri,mont->ri); /* R*Ri */ | 309 | BN_lshift(&Ri,&Ri,mont->ri); /* R*Ri */ |
371 | #if 1 | ||
372 | BN_sub_word(&Ri,1); | 310 | BN_sub_word(&Ri,1); |
373 | #else | 311 | /* Ni = (R*Ri-1) / N */ |
374 | BN_usub(&Ri,&Ri,BN_value_one()); /* R*Ri - 1 */ | ||
375 | #endif | ||
376 | BN_div(&(mont->Ni),NULL,&Ri,mod,ctx); | 312 | BN_div(&(mont->Ni),NULL,&Ri,mod,ctx); |
377 | BN_free(&Ri); | 313 | BN_free(&Ri); |
378 | } | 314 | } |
379 | #endif | 315 | #endif |
380 | 316 | ||
381 | /* setup RR for conversions */ | 317 | /* setup RR for conversions */ |
382 | #if 1 | ||
383 | BN_zero(&(mont->RR)); | 318 | BN_zero(&(mont->RR)); |
384 | BN_set_bit(&(mont->RR),mont->ri*2); | 319 | BN_set_bit(&(mont->RR),mont->ri*2); |
385 | #else | ||
386 | BN_lshift(mont->RR,BN_value_one(),mont->ri*2); | ||
387 | #endif | ||
388 | BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx); | 320 | BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx); |
389 | 321 | ||
390 | return(1); | 322 | return(1); |
@@ -399,7 +331,6 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) | |||
399 | BN_copy(&(to->RR),&(from->RR)); | 331 | BN_copy(&(to->RR),&(from->RR)); |
400 | BN_copy(&(to->N),&(from->N)); | 332 | BN_copy(&(to->N),&(from->N)); |
401 | BN_copy(&(to->Ni),&(from->Ni)); | 333 | BN_copy(&(to->Ni),&(from->Ni)); |
402 | to->use_word=from->use_word; | ||
403 | to->ri=from->ri; | 334 | to->ri=from->ri; |
404 | to->n0=from->n0; | 335 | to->n0=from->n0; |
405 | return(to); | 336 | return(to); |