1# Generate random bytes with OpenSSL
2#
3# These functions interface to the OpenSSL random number generators. They
4# can generate crypto secure random numbers in R.
5#
6#' @title Generate random bytes and numbers with OpenSSL
7#' @aliases rand_num
8#' @rdname rand_bytes
9#' @description this set of functions generates random bytes or numbers from OpenSSL. This
10#' provides a cryptographically secure alternative to R's default random number generator.
11#' \code{rand_bytes} generates \code{n} random cryptographically secure bytes
12#' @useDynLib openssl R_RAND_bytes
13#' @param n number of random bytes or numbers to generate
14#' @references OpenSSL manual: \url{https://www.openssl.org/docs/man1.1.1/man3/RAND_bytes.html}
15#' @examples rnd <- rand_bytes(10)
16#' as.numeric(rnd)
17#' as.character(rnd)
18#' as.logical(rawToBits(rnd))
19#'
20#' # bytes range from 0 to 255
21#' rnd <- rand_bytes(100000)
22#' hist(as.numeric(rnd), breaks=-1:255)
23#'
24#' # Generate random doubles between 0 and 1
25#' rand_num(5)
26#'
27#' # Use CDF to map [0,1] into random draws from a distribution
28#' x <- qnorm(rand_num(1000), mean=100, sd=15)
29#' hist(x)
30#'
31#' y <- qbinom(rand_num(1000), size=10, prob=0.3)
32#' hist(y)
33#' @export
34rand_bytes <- function(n = 1){
35  if(!is.numeric(n)){
36    stop("Please provide a numeric value for n")
37  }
38  .Call(R_RAND_bytes, n)
39}
40
41#' @rdname rand_bytes
42#' @export
43rand_num <- function(n = 1){
44  # 64 bit double requires 8 bytes.
45  x <- matrix(as.numeric(rand_bytes(n*8)), ncol = 8)
46  as.numeric(x %*% 256^-(1:8))
47}
48