added crypto-random-bytes
This commit is contained in:
parent
a729c028a6
commit
d988055a49
|
@ -4,7 +4,8 @@
|
||||||
racket/flonum
|
racket/flonum
|
||||||
racket/fixnum
|
racket/fixnum
|
||||||
racket/unsafe/ops
|
racket/unsafe/ops
|
||||||
racket/require))
|
racket/require
|
||||||
|
racket/random))
|
||||||
|
|
||||||
@(define math-eval (make-base-eval))
|
@(define math-eval (make-base-eval))
|
||||||
@(interaction-eval #:eval math-eval (require racket/math))
|
@(interaction-eval #:eval math-eval (require racket/math))
|
||||||
|
@ -835,6 +836,8 @@ both in binary and as integers.
|
||||||
@; ------------------------------------------------------------------------
|
@; ------------------------------------------------------------------------
|
||||||
@subsection{Random Numbers}
|
@subsection{Random Numbers}
|
||||||
|
|
||||||
|
@margin-note{When security is a concern, use @racket[crypto-random-bytes] instead of @racket[random].}
|
||||||
|
|
||||||
@defproc*[([(random [k (integer-in 1 4294967087)]
|
@defproc*[([(random [k (integer-in 1 4294967087)]
|
||||||
[rand-gen pseudo-random-generator?
|
[rand-gen pseudo-random-generator?
|
||||||
(current-pseudo-random-generator)])
|
(current-pseudo-random-generator)])
|
||||||
|
@ -855,7 +858,6 @@ internal state for generating numbers. The random number generator
|
||||||
uses a 54-bit version of L'Ecuyer's MRG32k3a algorithm
|
uses a 54-bit version of L'Ecuyer's MRG32k3a algorithm
|
||||||
@cite["L'Ecuyer02"].}
|
@cite["L'Ecuyer02"].}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(random-seed [k (integer-in 1 (sub1 (expt 2 31)))])
|
@defproc[(random-seed [k (integer-in 1 (sub1 (expt 2 31)))])
|
||||||
void?]{
|
void?]{
|
||||||
|
|
||||||
|
@ -923,6 +925,28 @@ range @racket[0] to @racket[4294944442], inclusive; at least one of
|
||||||
the first three integers is non-zero; and at least one of the last
|
the first three integers is non-zero; and at least one of the last
|
||||||
three integers is non-zero. Otherwise, the result is @racket[#f].}
|
three integers is non-zero. Otherwise, the result is @racket[#f].}
|
||||||
|
|
||||||
|
@; ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@subsection{System-Provided Randomness}
|
||||||
|
|
||||||
|
@defmodule[racket/random]{The @racketmodname[racket/random] module
|
||||||
|
provides an interface to randomness from the underlying operating
|
||||||
|
system. Use @racket[crypto-random-bytes]
|
||||||
|
instead of @racket[random] wherever security is a concern.}
|
||||||
|
|
||||||
|
@defproc[(crypto-random-bytes [n exact-positive-integer?])
|
||||||
|
bytes?]{
|
||||||
|
|
||||||
|
Returns @racket[n] random bytes. On Unix systems, the bytes are
|
||||||
|
obtained from @filepath{/dev/urandom}, while Windows uses
|
||||||
|
the @tt{RtlGenRand} system function.
|
||||||
|
|
||||||
|
@examples[
|
||||||
|
(eval:alts (crypto-random-bytes 14) #"\0\1\1\2\3\5\b\r\25\"7Y\220\351")
|
||||||
|
]
|
||||||
|
|
||||||
|
@history[#:added "6.2.900.17"]}
|
||||||
|
|
||||||
@; ------------------------------------------------------------------------
|
@; ------------------------------------------------------------------------
|
||||||
@subsection{Number--String Conversions}
|
@subsection{Number--String Conversions}
|
||||||
|
|
||||||
|
|
15
racket/collects/racket/private/unix-rand.rkt
Normal file
15
racket/collects/racket/private/unix-rand.rkt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#lang racket/base
|
||||||
|
(provide crypto-random-unix-bytes)
|
||||||
|
|
||||||
|
(define (check-urandom-exists)
|
||||||
|
(unless (file-exists? "/dev/urandom")
|
||||||
|
(raise (make-exn:fail:filesystem
|
||||||
|
"crypto-random-bytes: \"/dev/urandom\" does not exist"
|
||||||
|
(current-continuation-marks)))))
|
||||||
|
|
||||||
|
; (: crypto-random-unix-bytes (-> Positive-Integer Bytes))
|
||||||
|
(define (crypto-random-unix-bytes n)
|
||||||
|
(check-urandom-exists)
|
||||||
|
(call-with-input-file* "/dev/urandom"
|
||||||
|
(lambda (port)
|
||||||
|
(read-bytes n port))))
|
22
racket/collects/racket/private/windows-rand.rkt
Normal file
22
racket/collects/racket/private/windows-rand.rkt
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#lang racket/base
|
||||||
|
(provide crypto-random-windows-bytes)
|
||||||
|
|
||||||
|
(require ffi/unsafe
|
||||||
|
ffi/unsafe/define)
|
||||||
|
|
||||||
|
(define-ffi-definer define-advapi (and (eq? (system-type) 'windows) (ffi-lib "Advapi32.dll"))
|
||||||
|
#:default-make-fail make-not-available)
|
||||||
|
|
||||||
|
; supposed to be the same csprng as CryptGenRand, but with less overhead
|
||||||
|
; see Microsoft security dev Michael Howard: http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx
|
||||||
|
; this is for Windows XP and later only, but I doubt that's a problem
|
||||||
|
(define-advapi SystemFunction036 (_fun _pointer _ulong -> _bool))
|
||||||
|
|
||||||
|
; (: crypto-random-windows-bytes (-> Positive-Integer Bytes))
|
||||||
|
(define (crypto-random-windows-bytes n)
|
||||||
|
(define rand-bytes-buf (make-bytes n))
|
||||||
|
(if (SystemFunction036 rand-bytes-buf n)
|
||||||
|
rand-bytes-buf
|
||||||
|
(raise (make-exn:fail
|
||||||
|
"crypto-random-windows: SystemFunction036 failed to generate bytes"
|
||||||
|
(current-continuation-marks)))))
|
14
racket/collects/racket/random.rkt
Normal file
14
racket/collects/racket/random.rkt
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require "private/unix-rand.rkt" "private/windows-rand.rkt" racket/contract/base)
|
||||||
|
(provide (contract-out [crypto-random-bytes (-> exact-nonnegative-integer? bytes?)]))
|
||||||
|
|
||||||
|
; (: crypto-random-bytes (-> Positive-Integer Bytes))
|
||||||
|
; returns n random bytes from the os.
|
||||||
|
(define (crypto-random-bytes n)
|
||||||
|
(case (system-type 'os)
|
||||||
|
[(unix macosx) (crypto-random-unix-bytes n)]
|
||||||
|
[(windows) (crypto-random-windows-bytes n)]
|
||||||
|
[else (raise (make-exn:fail:unsupported
|
||||||
|
"not supported on the current platform"
|
||||||
|
(current-continuation-marks)))]))
|
Loading…
Reference in New Issue
Block a user