Mercurial > dropbear
comparison libtommath/bn_mp_rand.c @ 1733:d529a52b2f7c coverity coverity
merge coverity from main
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 26 Jun 2020 21:07:34 +0800 |
parents | 1051e4eea25a |
children | 34d9d3c022ce |
comparison
equal
deleted
inserted
replaced
1643:b59623a64678 | 1733:d529a52b2f7c |
---|---|
1 #include <tommath_private.h> | 1 #include "tommath_private.h" |
2 #ifdef BN_MP_RAND_C | 2 #ifdef BN_MP_RAND_C |
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis | 3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */ |
4 * | 4 /* SPDX-License-Identifier: Unlicense */ |
5 * LibTomMath is a library that provides multiple-precision | |
6 * integer arithmetic as well as number theoretic functionality. | |
7 * | |
8 * The library was designed directly after the MPI library by | |
9 * Michael Fromberger but has been written from scratch with | |
10 * additional optimizations in place. | |
11 * | |
12 * The library is free for all purposes without any express | |
13 * guarantee it works. | |
14 * | |
15 * Tom St Denis, [email protected], http://libtom.org | |
16 */ | |
17 | 5 |
18 #if MP_GEN_RANDOM_MAX == 0xffffffff | 6 mp_err(*s_mp_rand_source)(void *out, size_t size) = s_mp_rand_platform; |
19 #define MP_GEN_RANDOM_SHIFT 32 | |
20 #elif MP_GEN_RANDOM_MAX == 32767 | |
21 /* SHRT_MAX */ | |
22 #define MP_GEN_RANDOM_SHIFT 15 | |
23 #elif MP_GEN_RANDOM_MAX == 2147483647 | |
24 /* INT_MAX */ | |
25 #define MP_GEN_RANDOM_SHIFT 31 | |
26 #elif !defined(MP_GEN_RANDOM_SHIFT) | |
27 #error Thou shalt define their own valid MP_GEN_RANDOM_SHIFT | |
28 #endif | |
29 | 7 |
30 /* makes a pseudo-random int of a given size */ | 8 void mp_rand_source(mp_err(*source)(void *out, size_t size)) |
31 static mp_digit s_gen_random(void) | |
32 { | 9 { |
33 mp_digit d = 0, msk = 0; | 10 s_mp_rand_source = (source == NULL) ? s_mp_rand_platform : source; |
34 do { | |
35 d <<= MP_GEN_RANDOM_SHIFT; | |
36 d |= ((mp_digit) MP_GEN_RANDOM()); | |
37 msk <<= MP_GEN_RANDOM_SHIFT; | |
38 msk |= (MP_MASK & MP_GEN_RANDOM_MAX); | |
39 } while ((MP_MASK & msk) != MP_MASK); | |
40 d &= MP_MASK; | |
41 return d; | |
42 } | 11 } |
43 | 12 |
44 int | 13 mp_err mp_rand(mp_int *a, int digits) |
45 mp_rand (mp_int * a, int digits) | |
46 { | 14 { |
47 int res; | 15 int i; |
48 mp_digit d; | 16 mp_err err; |
49 | 17 |
50 mp_zero (a); | 18 mp_zero(a); |
51 if (digits <= 0) { | |
52 return MP_OKAY; | |
53 } | |
54 | 19 |
55 /* first place a random non-zero digit */ | 20 if (digits <= 0) { |
56 do { | 21 return MP_OKAY; |
57 d = s_gen_random(); | 22 } |
58 } while (d == 0); | |
59 | 23 |
60 if ((res = mp_add_d (a, d, a)) != MP_OKAY) { | 24 if ((err = mp_grow(a, digits)) != MP_OKAY) { |
61 return res; | 25 return err; |
62 } | 26 } |
63 | 27 |
64 while (--digits > 0) { | 28 if ((err = s_mp_rand_source(a->dp, (size_t)digits * sizeof(mp_digit))) != MP_OKAY) { |
65 if ((res = mp_lshd (a, 1)) != MP_OKAY) { | 29 return err; |
66 return res; | 30 } |
67 } | |
68 | 31 |
69 if ((res = mp_add_d (a, s_gen_random(), a)) != MP_OKAY) { | 32 /* TODO: We ensure that the highest digit is nonzero. Should this be removed? */ |
70 return res; | 33 while ((a->dp[digits - 1] & MP_MASK) == 0u) { |
71 } | 34 if ((err = s_mp_rand_source(a->dp + digits - 1, sizeof(mp_digit))) != MP_OKAY) { |
72 } | 35 return err; |
36 } | |
37 } | |
73 | 38 |
74 return MP_OKAY; | 39 a->used = digits; |
40 for (i = 0; i < digits; ++i) { | |
41 a->dp[i] &= MP_MASK; | |
42 } | |
43 | |
44 return MP_OKAY; | |
75 } | 45 } |
76 #endif | 46 #endif |
77 | |
78 /* ref: $Format:%D$ */ | |
79 /* git commit: $Format:%H$ */ | |
80 /* commit time: $Format:%ai$ */ |