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