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$ */