diff options
| author | djm <> | 2008-09-06 12:17:54 +0000 |
|---|---|---|
| committer | djm <> | 2008-09-06 12:17:54 +0000 |
| commit | 6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda (patch) | |
| tree | 7ccc28afe1789ea3dbedf72365f955d5b8e105b5 /src/lib/libcrypto/bn/bn_sqrt.c | |
| parent | 89181603212b41e95cde36b1be5a146ce8fb2935 (diff) | |
| download | openbsd-6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda.tar.gz openbsd-6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda.tar.bz2 openbsd-6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda.zip | |
resolve conflicts
Diffstat (limited to 'src/lib/libcrypto/bn/bn_sqrt.c')
| -rw-r--r-- | src/lib/libcrypto/bn/bn_sqrt.c | 76 |
1 files changed, 41 insertions, 35 deletions
diff --git a/src/lib/libcrypto/bn/bn_sqrt.c b/src/lib/libcrypto/bn/bn_sqrt.c index e2a1105dc8..6beaf9e5e5 100644 --- a/src/lib/libcrypto/bn/bn_sqrt.c +++ b/src/lib/libcrypto/bn/bn_sqrt.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* crypto/bn/bn_mod.c */ | 1 | /* crypto/bn/bn_sqrt.c */ |
| 2 | /* Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> | 2 | /* Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> |
| 3 | * and Bodo Moeller for the OpenSSL project. */ | 3 | * and Bodo Moeller for the OpenSSL project. */ |
| 4 | /* ==================================================================== | 4 | /* ==================================================================== |
| @@ -65,14 +65,12 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
| 65 | * using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course | 65 | * using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course |
| 66 | * in Algebraic Computational Number Theory", algorithm 1.5.1). | 66 | * in Algebraic Computational Number Theory", algorithm 1.5.1). |
| 67 | * 'p' must be prime! | 67 | * 'p' must be prime! |
| 68 | * If 'a' is not a square, this is not necessarily detected by | ||
| 69 | * the algorithms; a bogus result must be expected in this case. | ||
| 70 | */ | 68 | */ |
| 71 | { | 69 | { |
| 72 | BIGNUM *ret = in; | 70 | BIGNUM *ret = in; |
| 73 | int err = 1; | 71 | int err = 1; |
| 74 | int r; | 72 | int r; |
| 75 | BIGNUM *b, *q, *t, *x, *y; | 73 | BIGNUM *A, *b, *q, *t, *x, *y; |
| 76 | int e, i, j; | 74 | int e, i, j; |
| 77 | 75 | ||
| 78 | if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) | 76 | if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) |
| @@ -85,9 +83,11 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
| 85 | goto end; | 83 | goto end; |
| 86 | if (!BN_set_word(ret, BN_is_bit_set(a, 0))) | 84 | if (!BN_set_word(ret, BN_is_bit_set(a, 0))) |
| 87 | { | 85 | { |
| 88 | BN_free(ret); | 86 | if (ret != in) |
| 87 | BN_free(ret); | ||
| 89 | return NULL; | 88 | return NULL; |
| 90 | } | 89 | } |
| 90 | bn_check_top(ret); | ||
| 91 | return ret; | 91 | return ret; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| @@ -103,23 +103,16 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
| 103 | goto end; | 103 | goto end; |
| 104 | if (!BN_set_word(ret, BN_is_one(a))) | 104 | if (!BN_set_word(ret, BN_is_one(a))) |
| 105 | { | 105 | { |
| 106 | BN_free(ret); | 106 | if (ret != in) |
| 107 | BN_free(ret); | ||
| 107 | return NULL; | 108 | return NULL; |
| 108 | } | 109 | } |
| 110 | bn_check_top(ret); | ||
| 109 | return ret; | 111 | return ret; |
| 110 | } | 112 | } |
| 111 | 113 | ||
| 112 | #if 0 /* if BN_mod_sqrt is used with correct input, this just wastes time */ | ||
| 113 | r = BN_kronecker(a, p, ctx); | ||
| 114 | if (r < -1) return NULL; | ||
| 115 | if (r == -1) | ||
| 116 | { | ||
| 117 | BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); | ||
| 118 | return(NULL); | ||
| 119 | } | ||
| 120 | #endif | ||
| 121 | |||
| 122 | BN_CTX_start(ctx); | 114 | BN_CTX_start(ctx); |
| 115 | A = BN_CTX_get(ctx); | ||
| 123 | b = BN_CTX_get(ctx); | 116 | b = BN_CTX_get(ctx); |
| 124 | q = BN_CTX_get(ctx); | 117 | q = BN_CTX_get(ctx); |
| 125 | t = BN_CTX_get(ctx); | 118 | t = BN_CTX_get(ctx); |
| @@ -131,6 +124,9 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
| 131 | ret = BN_new(); | 124 | ret = BN_new(); |
| 132 | if (ret == NULL) goto end; | 125 | if (ret == NULL) goto end; |
| 133 | 126 | ||
| 127 | /* A = a mod p */ | ||
| 128 | if (!BN_nnmod(A, a, p, ctx)) goto end; | ||
| 129 | |||
| 134 | /* now write |p| - 1 as 2^e*q where q is odd */ | 130 | /* now write |p| - 1 as 2^e*q where q is odd */ |
| 135 | e = 1; | 131 | e = 1; |
| 136 | while (!BN_is_bit_set(p, e)) | 132 | while (!BN_is_bit_set(p, e)) |
| @@ -149,9 +145,9 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
| 149 | if (!BN_rshift(q, p, 2)) goto end; | 145 | if (!BN_rshift(q, p, 2)) goto end; |
| 150 | q->neg = 0; | 146 | q->neg = 0; |
| 151 | if (!BN_add_word(q, 1)) goto end; | 147 | if (!BN_add_word(q, 1)) goto end; |
| 152 | if (!BN_mod_exp(ret, a, q, p, ctx)) goto end; | 148 | if (!BN_mod_exp(ret, A, q, p, ctx)) goto end; |
| 153 | err = 0; | 149 | err = 0; |
| 154 | goto end; | 150 | goto vrfy; |
| 155 | } | 151 | } |
| 156 | 152 | ||
| 157 | if (e == 2) | 153 | if (e == 2) |
| @@ -182,15 +178,8 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
| 182 | * November 1992.) | 178 | * November 1992.) |
| 183 | */ | 179 | */ |
| 184 | 180 | ||
| 185 | /* make sure that a is reduced modulo p */ | ||
| 186 | if (a->neg || BN_ucmp(a, p) >= 0) | ||
| 187 | { | ||
| 188 | if (!BN_nnmod(x, a, p, ctx)) goto end; | ||
| 189 | a = x; /* use x as temporary variable */ | ||
| 190 | } | ||
| 191 | |||
| 192 | /* t := 2*a */ | 181 | /* t := 2*a */ |
| 193 | if (!BN_mod_lshift1_quick(t, a, p)) goto end; | 182 | if (!BN_mod_lshift1_quick(t, A, p)) goto end; |
| 194 | 183 | ||
| 195 | /* b := (2*a)^((|p|-5)/8) */ | 184 | /* b := (2*a)^((|p|-5)/8) */ |
| 196 | if (!BN_rshift(q, p, 3)) goto end; | 185 | if (!BN_rshift(q, p, 3)) goto end; |
| @@ -205,12 +194,12 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
| 205 | if (!BN_sub_word(t, 1)) goto end; | 194 | if (!BN_sub_word(t, 1)) goto end; |
| 206 | 195 | ||
| 207 | /* x = a*b*t */ | 196 | /* x = a*b*t */ |
| 208 | if (!BN_mod_mul(x, a, b, p, ctx)) goto end; | 197 | if (!BN_mod_mul(x, A, b, p, ctx)) goto end; |
| 209 | if (!BN_mod_mul(x, x, t, p, ctx)) goto end; | 198 | if (!BN_mod_mul(x, x, t, p, ctx)) goto end; |
| 210 | 199 | ||
| 211 | if (!BN_copy(ret, x)) goto end; | 200 | if (!BN_copy(ret, x)) goto end; |
| 212 | err = 0; | 201 | err = 0; |
| 213 | goto end; | 202 | goto vrfy; |
| 214 | } | 203 | } |
| 215 | 204 | ||
| 216 | /* e > 2, so we really have to use the Tonelli/Shanks algorithm. | 205 | /* e > 2, so we really have to use the Tonelli/Shanks algorithm. |
| @@ -297,11 +286,11 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
| 297 | /* x := a^((q-1)/2) */ | 286 | /* x := a^((q-1)/2) */ |
| 298 | if (BN_is_zero(t)) /* special case: p = 2^e + 1 */ | 287 | if (BN_is_zero(t)) /* special case: p = 2^e + 1 */ |
| 299 | { | 288 | { |
| 300 | if (!BN_nnmod(t, a, p, ctx)) goto end; | 289 | if (!BN_nnmod(t, A, p, ctx)) goto end; |
| 301 | if (BN_is_zero(t)) | 290 | if (BN_is_zero(t)) |
| 302 | { | 291 | { |
| 303 | /* special case: a == 0 (mod p) */ | 292 | /* special case: a == 0 (mod p) */ |
| 304 | if (!BN_zero(ret)) goto end; | 293 | BN_zero(ret); |
| 305 | err = 0; | 294 | err = 0; |
| 306 | goto end; | 295 | goto end; |
| 307 | } | 296 | } |
| @@ -310,11 +299,11 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
| 310 | } | 299 | } |
| 311 | else | 300 | else |
| 312 | { | 301 | { |
| 313 | if (!BN_mod_exp(x, a, t, p, ctx)) goto end; | 302 | if (!BN_mod_exp(x, A, t, p, ctx)) goto end; |
| 314 | if (BN_is_zero(x)) | 303 | if (BN_is_zero(x)) |
| 315 | { | 304 | { |
| 316 | /* special case: a == 0 (mod p) */ | 305 | /* special case: a == 0 (mod p) */ |
| 317 | if (!BN_zero(ret)) goto end; | 306 | BN_zero(ret); |
| 318 | err = 0; | 307 | err = 0; |
| 319 | goto end; | 308 | goto end; |
| 320 | } | 309 | } |
| @@ -322,10 +311,10 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
| 322 | 311 | ||
| 323 | /* b := a*x^2 (= a^q) */ | 312 | /* b := a*x^2 (= a^q) */ |
| 324 | if (!BN_mod_sqr(b, x, p, ctx)) goto end; | 313 | if (!BN_mod_sqr(b, x, p, ctx)) goto end; |
| 325 | if (!BN_mod_mul(b, b, a, p, ctx)) goto end; | 314 | if (!BN_mod_mul(b, b, A, p, ctx)) goto end; |
| 326 | 315 | ||
| 327 | /* x := a*x (= a^((q+1)/2)) */ | 316 | /* x := a*x (= a^((q+1)/2)) */ |
| 328 | if (!BN_mod_mul(x, x, a, p, ctx)) goto end; | 317 | if (!BN_mod_mul(x, x, A, p, ctx)) goto end; |
| 329 | 318 | ||
| 330 | while (1) | 319 | while (1) |
| 331 | { | 320 | { |
| @@ -342,7 +331,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
| 342 | { | 331 | { |
| 343 | if (!BN_copy(ret, x)) goto end; | 332 | if (!BN_copy(ret, x)) goto end; |
| 344 | err = 0; | 333 | err = 0; |
| 345 | goto end; | 334 | goto vrfy; |
| 346 | } | 335 | } |
| 347 | 336 | ||
| 348 | 337 | ||
| @@ -373,6 +362,22 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
| 373 | e = i; | 362 | e = i; |
| 374 | } | 363 | } |
| 375 | 364 | ||
| 365 | vrfy: | ||
| 366 | if (!err) | ||
| 367 | { | ||
| 368 | /* verify the result -- the input might have been not a square | ||
| 369 | * (test added in 0.9.8) */ | ||
| 370 | |||
| 371 | if (!BN_mod_sqr(x, ret, p, ctx)) | ||
| 372 | err = 1; | ||
| 373 | |||
| 374 | if (!err && 0 != BN_cmp(x, A)) | ||
| 375 | { | ||
| 376 | BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); | ||
| 377 | err = 1; | ||
| 378 | } | ||
| 379 | } | ||
| 380 | |||
| 376 | end: | 381 | end: |
| 377 | if (err) | 382 | if (err) |
| 378 | { | 383 | { |
| @@ -383,5 +388,6 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
| 383 | ret = NULL; | 388 | ret = NULL; |
| 384 | } | 389 | } |
| 385 | BN_CTX_end(ctx); | 390 | BN_CTX_end(ctx); |
| 391 | bn_check_top(ret); | ||
| 386 | return ret; | 392 | return ret; |
| 387 | } | 393 | } |
