LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2010 The Go Authors. All rights reserved. | 1 // Copyright 2010 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // +build darwin freebsd linux netbsd openbsd | 5 // +build darwin freebsd linux netbsd openbsd |
6 | 6 |
7 // Unix cryptographically secure pseudorandom number | 7 // Unix cryptographically secure pseudorandom number |
8 // generator. | 8 // generator. |
9 | 9 |
10 package rand | 10 package rand |
11 | 11 |
12 import ( | 12 import ( |
13 "bufio" | 13 "bufio" |
14 "crypto/aes" | 14 "crypto/aes" |
| 15 "crypto/cipher" |
15 "io" | 16 "io" |
16 "os" | 17 "os" |
17 "sync" | 18 "sync" |
18 "time" | 19 "time" |
19 ) | 20 ) |
20 | 21 |
21 // Easy implementation: read from /dev/urandom. | 22 // Easy implementation: read from /dev/urandom. |
22 // This is sufficient on Linux, OS X, and FreeBSD. | 23 // This is sufficient on Linux, OS X, and FreeBSD. |
23 | 24 |
24 func init() { Reader = &devReader{name: "/dev/urandom"} } | 25 func init() { Reader = &devReader{name: "/dev/urandom"} } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 func newReader(entropy io.Reader) io.Reader { | 60 func newReader(entropy io.Reader) io.Reader { |
60 if entropy == nil { | 61 if entropy == nil { |
61 entropy = &devReader{name: "/dev/random"} | 62 entropy = &devReader{name: "/dev/random"} |
62 } | 63 } |
63 return &reader{entropy: entropy} | 64 return &reader{entropy: entropy} |
64 } | 65 } |
65 | 66 |
66 type reader struct { | 67 type reader struct { |
67 mu sync.Mutex | 68 mu sync.Mutex |
68 budget int // number of bytes that can be generated | 69 budget int // number of bytes that can be generated |
69 » cipher *aes.Cipher | 70 » cipher cipher.Block |
70 entropy io.Reader | 71 entropy io.Reader |
71 time, seed, dst, key [aes.BlockSize]byte | 72 time, seed, dst, key [aes.BlockSize]byte |
72 } | 73 } |
73 | 74 |
74 func (r *reader) Read(b []byte) (n int, err error) { | 75 func (r *reader) Read(b []byte) (n int, err error) { |
75 r.mu.Lock() | 76 r.mu.Lock() |
76 defer r.mu.Unlock() | 77 defer r.mu.Unlock() |
77 n = len(b) | 78 n = len(b) |
78 | 79 |
79 for len(b) > 0 { | 80 for len(b) > 0 { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 r.seed[i] = r.time[i] ^ r.dst[i] | 119 r.seed[i] = r.time[i] ^ r.dst[i] |
119 } | 120 } |
120 r.cipher.Encrypt(r.seed[0:], r.seed[0:]) | 121 r.cipher.Encrypt(r.seed[0:], r.seed[0:]) |
121 | 122 |
122 m := copy(b, r.dst[0:]) | 123 m := copy(b, r.dst[0:]) |
123 b = b[m:] | 124 b = b[m:] |
124 } | 125 } |
125 | 126 |
126 return n, nil | 127 return n, nil |
127 } | 128 } |
LEFT | RIGHT |