1
2
3
4
5 package rand
6
7 import (
8 "crypto/internal/fips140only"
9 "crypto/internal/randutil"
10 "errors"
11 "io"
12 "math/big"
13 )
14
15
16
17 func Prime(rand io.Reader, bits int) (*big.Int, error) {
18 if fips140only.Enabled {
19 return nil, errors.New("crypto/rand: use of Prime is not allowed in FIPS 140-only mode")
20 }
21 if bits < 2 {
22 return nil, errors.New("crypto/rand: prime size must be at least 2-bit")
23 }
24
25 randutil.MaybeReadByte(rand)
26
27 b := uint(bits % 8)
28 if b == 0 {
29 b = 8
30 }
31
32 bytes := make([]byte, (bits+7)/8)
33 p := new(big.Int)
34
35 for {
36 if _, err := io.ReadFull(rand, bytes); err != nil {
37 return nil, err
38 }
39
40
41 bytes[0] &= uint8(int(1<<b) - 1)
42
43
44
45
46 if b >= 2 {
47 bytes[0] |= 3 << (b - 2)
48 } else {
49
50 bytes[0] |= 1
51 if len(bytes) > 1 {
52 bytes[1] |= 0x80
53 }
54 }
55
56 bytes[len(bytes)-1] |= 1
57
58 p.SetBytes(bytes)
59 if p.ProbablyPrime(20) {
60 return p, nil
61 }
62 }
63 }
64
65
66
67 func Int(rand io.Reader, max *big.Int) (n *big.Int, err error) {
68 if max.Sign() <= 0 {
69 panic("crypto/rand: argument to Int is <= 0")
70 }
71 n = new(big.Int)
72 n.Sub(max, n.SetUint64(1))
73
74 bitLen := n.BitLen()
75 if bitLen == 0 {
76
77 return
78 }
79
80 k := (bitLen + 7) / 8
81
82 b := uint(bitLen % 8)
83 if b == 0 {
84 b = 8
85 }
86
87 bytes := make([]byte, k)
88
89 for {
90 _, err = io.ReadFull(rand, bytes)
91 if err != nil {
92 return nil, err
93 }
94
95
96
97 bytes[0] &= uint8(int(1<<b) - 1)
98
99 n.SetBytes(bytes)
100 if n.Cmp(max) < 0 {
101 return
102 }
103 }
104 }
105
View as plain text