#define fastrand_max ucw_fastrand_max
#define fastrand_max_u64 ucw_fastrand_max_u64
#define fastrand_mem ucw_fastrand_mem
+#define fastrand_double ucw_fastrand_double
+#define strongrand_close ucw_strongrand_close
+#define strongrand_reset ucw_strongrand_reset
+#define strongrand_mem ucw_strongrand_mem
+#define strongrand_std_open ucw_strongrand_std_open
+#define strongrand_getrandom_mem_try ucw_strongrand_getrandom_mem_try
#endif
/* random-fast.c */
/**
* Generate a seed for fastrand_set_seed().
*
- * We currently mix these things (you can add more if needed):
+ * Since glibc 2.25 and kernel 3.17, we use getrandom() syscall
+ * to read kernel's urandom.
+ *
+ * Otherwise we mix these things:
* -- current time
* -- process id to deal with frequent fork() or startups
* -- counter to deal with multiple contexts, for example in threaded application
/** Generate @size random bytes. **/
void fastrand_mem(struct fastrand *c, void *ptr, size_t size);
+/** Uniformly generate a random number from range [0.0, 1.0) + possible inaccuracies from basic floating point operations. **/
+double fastrand_double(struct fastrand *c);
+
+/* random-strong.c */
+
+/**
+ * Context structure for a strong random generator.
+ * Useful for things like generating random ids or cryptography.
+ * The library is generally thread-safe, but each context must be used by at most one thread at one time.
+ *
+ * Also be careful with fork(). Unless said otherwise, it's forbidden to use the context
+ * in a forked child, we can even assert changes of pid. See strongrand_reset() if you
+ * need that.
+ **/
+struct strongrand {
+ const char *name; /* (mandatory) Context name for logging. */
+ void (*read)(struct strongrand *sr, byte *ptr, int size); /* (mandatory) Generate @size random bytes. */
+ void (*close)(struct strongrand *sr); /* Called from strongrand_close(). */
+ void (*reset)(struct strongrand *sr); /* Called from strongrand_reset(). */
+};
+
+/** Close a previously opened context. **/
+void strongrand_close(struct strongrand *c);
+
+/**
+ * If you want to use the same context in multiple forked subprocesses, you must
+ * call this function after the fork() to flush any buffered randomness.
+ * Some future back-ends could use it for even more things, for example
+ * to re-connect somewhere.
+ **/
+void strongrand_reset(struct strongrand *sr);
+
+/** Generate @size random bytes. **/
+void strongrand_mem(struct strongrand *c, void *ptr, size_t size);
+
+/**
+ * Open kernel's random generator.
+ * Requires exactly one of these flags, among others:
+ * -- STRONGRAND_STD_URANDOM
+ * -- STRONGRAND_STD_RANDOM
+ *
+ * Since glibc 2.25 and kernel 3.17, we use getrandom() syscall,
+ * otherwise we open and read from "/dev/[u]random" device.
+ *
+ * @buf_size can be 0 for unbuffered reading.
+ *
+ * STRONGRAND_STD_x_RESET flags are only useful for buffered reading.
+ *
+ * If at least one of the following conditions are met, strongrand_reset()
+ * after fork() is not necessary:
+ * -- zero @buf_size
+ * -- STRONGRAND_STD_AUTO_RESET flag
+ * -- no read since open or last reset (empty buffer)
+ **/
+struct strongrand *strongrand_std_open(uint flags, uint buf_size);
+
+enum strongrand_std_flags {
+ STRONGRAND_STD_URANDOM = 0x1, // Use kernel's "urandom" source.
+ STRONGRAND_STD_RANDOM = 0x2, // Use kernel's "random" source.
+ STRONGRAND_STD_DELAYED = 0x4, // Delay non-trivial initializations like opening file descriptor to first read.
+ STRONGRAND_STD_AUTO_RESET = 0x8, // Automatically do strongrand_reset() after changes of getpid(); adds overhead to each read.
+ STRONGRAND_STD_ASSERT_RESET = 0x10, // Assert correct usage of strongrand_reset() after changes of getpid(); for debugging.
+};
+
+// Internals
+bool strongrand_getrandom_mem_try(void *buf, size_t size);
+
#endif