X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fbn%2Fbn_rand.c;h=3873eac6896678c46fcfc925889200e134fbb26b;hp=b1163f7ec44172078a4a15564862db72ed752233;hb=395258457182fcfe4ee6f82ee9c74b5d2f3426c8;hpb=26a3a48d65c7464b400ec1de439994d7f0d25fed diff --git a/crypto/bn/bn_rand.c b/crypto/bn/bn_rand.c index b1163f7ec4..3873eac689 100644 --- a/crypto/bn/bn_rand.c +++ b/crypto/bn/bn_rand.c @@ -68,6 +68,12 @@ static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom) int ret=0,bit,bytes,mask; time_t tim; + if (bits == 0) + { + BN_zero(rnd); + return 1; + } + bytes=(bits+7)/8; bit=(bits-1)%8; mask=0xff<= 128 && i > 0) + buf[i] = buf[i-1]; + else if (c < 42) + buf[i] = 0; + else if (c < 84) + buf[i] = 255; + } + } +#endif + if (top) { if (bit == 0) @@ -134,3 +161,66 @@ int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) { return bnrand(1, rnd, bits, top, bottom); } + +#if 1 +int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom) + { + return bnrand(2, rnd, bits, top, bottom); + } +#endif + +/* random number r: min <= r < min+range */ +int BN_rand_range(BIGNUM *r, BIGNUM *min, BIGNUM *range) + { + int n; + + if (range->neg || BN_is_zero(range)) + { + BNerr(BN_F_BN_RAND_RANGE, BN_R_INVALID_RANGE); + return 0; + } + + n = BN_num_bits(range); /* n > 0 */ + + if (n == 1) + { + if (!BN_zero(r)) return 0; + } + else if (BN_is_bit_set(range, n - 2)) + { + do + { + /* range = 11..._2, so each iteration succeeds with probability > .75 */ + if (!BN_rand(r, n, 0, 0)) return 0; + } + while (BN_cmp(r, range) >= 0); + } + else + { + /* range = 10..._2, + * so 3*range (= 11..._2) is exactly one bit longer than range */ + do + { + if (!BN_rand(r, n + 1, 0, 0)) return 0; + /* If r < 3*range, use r := r MOD range + * (which is either r, r - range, or r - 2*range). + * Otherwise, iterate once more. + * Since 3*range = 11..._2, each iteration succeeds with + * probability > .75. */ + if (BN_cmp(r ,range) >= 0) + { + if (!BN_sub(r, r, range)) return 0; + if (BN_cmp(r, range) >= 0) + if (!BN_sub(r, r, range)) return 0; + } + } + while (BN_cmp(r, range) >= 0); + } + + if (min != NULL) + { + if (!BN_add(r, r, min)) return 0; + } + + return 1; + }