]> mj.ucw.cz Git - libucw.git/blob - ucw/random.h
Random: Small fixes in documentation.
[libucw.git] / ucw / random.h
1 /*
2  *      The UCW Library -- Random numbers
3  *
4  *      (c) 2020--2022 Pavel Charvat <pchar@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #ifndef _UCW_RANDOM_H
11 #define _UCW_RANDOM_H
12
13 #ifdef CONFIG_UCW_CLEAN_ABI
14 #define fastrand_new ucw_fastrand_new
15 #define fastrand_delete ucw_fastrand_delete
16 #define fastrand_set_seed ucw_fastrand_set_seed
17 #define fastrand_gen_seed_value ucw_fastrand_gen_seed_value
18 #define fastrand_gen_seed ucw_fastrand_gen_seed
19 #define fastrand_has_seed ucw_fastrand_has_seed
20 #define fastrand_reset ucw_fastrand_reset
21 #define fastrand_u32 ucw_fastrand_u32
22 #define fastrand_u64 ucw_fastrand_u64
23 #define fastrand_bits_u64 ucw_fastrand_bits_u64
24 #define fastrand_max ucw_fastrand_max
25 #define fastrand_max_u64 ucw_fastrand_max_u64
26 #define fastrand_mem ucw_fastrand_mem
27 #define fastrand_double ucw_fastrand_double
28 #define strongrand_close ucw_strongrand_close
29 #define strongrand_reset ucw_strongrand_reset
30 #define strongrand_mem ucw_strongrand_mem
31 #define strongrand_std_open ucw_strongrand_std_open
32 #define strongrand_getrandom_mem_try ucw_strongrand_getrandom_mem_try
33 #endif
34
35 /* random-fast.c */
36
37 /**
38  * Context structure for a fast pseudo-random generator.
39  * Useful for generating numbers in randomized algorithms, but not in critical things like cryptography.
40  * The library is generally thread-safe, but each context must be used by at most one thread at one time.
41  * Also be careful with fork() if you want to avoid the same numbers in subprocesses.
42  **/
43 struct fastrand;
44
45 /**
46  * Type for a seed value. Beware that some generators are only able to use the lowest 32 bits.
47  **/
48 typedef u64 fastrand_seed_t;
49
50 /**
51  * Allocate a new context. Should be paired with fastrand_delete().
52  * Don't forget to supply a seed before started to read randomness.
53  **/
54 struct fastrand *fastrand_new(void);
55 void fastrand_delete(struct fastrand *c);
56
57 /** (Re)seed the context with given value. **/
58 void fastrand_set_seed(struct fastrand *c, fastrand_seed_t seed);
59
60 /**
61  * Generate a seed for fastrand_set_seed().
62  *
63  * Since glibc 2.25 and kernel 3.17, we use getrandom() syscall
64  * to read kernel's urandom.
65  *
66  * Otherwise we mix these things:
67  * -- current time
68  * -- process id to deal with frequent fork() or startups
69  * -- counter to deal with multiple contexts, for example in threaded application
70  **/
71 fastrand_seed_t fastrand_gen_seed_value(void);
72
73 /** (Re)seed the context with fastrand_gen_seed_value(). **/
74 fastrand_seed_t fastrand_gen_seed(struct fastrand *c);
75
76 /** Is the context seeded? **/
77 bool fastrand_has_seed(struct fastrand *c);
78
79 /** Reset the context to its initial state. Useful after a fork() to assert forgotten reseed. **/
80 void fastrand_reset(struct fastrand *c);
81
82 /** Uniformly generate 32 random bits. **/
83 u32 fastrand_u32(struct fastrand *c);
84
85 /** Uniformly generate 64 random bits. **/
86 u64 fastrand_u64(struct fastrand *c);
87
88 /** Uniformly generate [0, 64] random bits. **/
89 u64 fastrand_bits_u64(struct fastrand *c, uint bits);
90
91 /** Uniformly generate [0, 8*sizeof(uint)] random bits. **/
92 static inline uint fastrand_bits(struct fastrand *c, uint bits)
93 {
94   return fastrand_bits_u64(c, bits);
95 }
96
97 /** Uniformly generate a random number from range [0, bound-1], where @bound is [1, UINT_MAX]. **/
98 uint fastrand_max(struct fastrand *c, uint bound);
99
100 /** Uniformly generate a random number from range [0, bound-1], where @bound is [1, UINT64_MAX]. **/
101 u64 fastrand_max_u64(struct fastrand *c, u64 bound);
102
103 /** Generate @size random bytes. **/
104 void fastrand_mem(struct fastrand *c, void *ptr, size_t size);
105
106 /** Uniformly generate a random number from range [0.0, 1.0) + possible inaccuracies from basic floating point operations. **/
107 double fastrand_double(struct fastrand *c);
108
109 /* random-strong.c */
110
111 /**
112  * Context structure for a strong random generator.
113  * Useful for things like generating random ids or cryptography.
114  * The library is generally thread-safe, but each context must be used by at most one thread at one time.
115  *
116  * Also be careful with fork(). Unless said otherwise, it's forbidden to use the context
117  * in a forked child, we can even assert changes of pid. See strongrand_reset() if you
118  * need that.
119  **/
120 struct strongrand {
121   const char *name;                             /* (mandatory) Context name for logging. */
122   void (*read)(struct strongrand *sr, byte *ptr, int size); /* (mandatory) Generate @size random bytes. */
123   void (*close)(struct strongrand *sr);         /* Called from strongrand_close(). */
124   void (*reset)(struct strongrand *sr);         /* Called from strongrand_reset(). */
125 };
126
127 /** Close a previously opened context. **/
128 void strongrand_close(struct strongrand *c);
129
130 /**
131  * If you want to use the same context in multiple forked subprocesses, you must
132  * call this function after the fork() to flush any buffered randomness.
133  * Some future back-ends could use it for even more things, for example
134  * to re-connect somewhere.
135  **/
136 void strongrand_reset(struct strongrand *sr);
137
138 /** Generate @size random bytes. **/
139 void strongrand_mem(struct strongrand *c, void *ptr, size_t size);
140
141 /**
142  * Open kernel's random generator.
143  * Requires exactly one of these flags, among others:
144  * -- STRONGRAND_STD_URANDOM
145  * -- STRONGRAND_STD_RANDOM
146  *
147  * Since glibc 2.25 and kernel 3.17, we use getrandom() syscall,
148  * otherwise we open and read from "/dev/[u]random" device.
149  *
150  * @buf_size can be 0 for unbuffered reading.
151  *
152  * STRONGRAND_STD_x_RESET flags are only useful for buffered reading.
153  *
154  * If at least one of the following conditions are met, strongrand_reset()
155  * after fork() is not necessary:
156  * -- zero @buf_size
157  * -- STRONGRAND_STD_AUTO_RESET flag
158  * -- no read since open or last reset (empty buffer)
159  **/
160 struct strongrand *strongrand_std_open(uint buf_size, uint flags);
161
162 enum strongrand_std_flags {
163   STRONGRAND_STD_URANDOM = 0x1,         // Use kernel's "urandom" source.
164   STRONGRAND_STD_RANDOM = 0x2,          // Use kernel's "random" source.
165   STRONGRAND_STD_DELAYED = 0x4,         // Delay non-trivial initializations like opening file descriptor to first read.
166   STRONGRAND_STD_AUTO_RESET = 0x8,      // Automatically do strongrand_reset() after changes of getpid(); adds overhead to each read.
167   STRONGRAND_STD_ASSERT_RESET = 0x10,   // Assert correct usage of strongrand_reset() after changes of getpid(); for debugging.
168 };
169
170 // Internals
171 bool strongrand_getrandom_mem_try(void *buf, size_t size);
172
173 #endif