-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.go
67 lines (59 loc) · 1.56 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package tcrsa
import (
"crypto/rand"
"fmt"
"io"
"math/big"
)
// Number of Miller-Rabin tests
const c = 20
// randInt is a function which generates a random big number, using crypto/rand
// crypto-secure Golang library.
func randInt(bitLen int) (randNum *big.Int, err error) {
randNum = big.NewInt(0)
if bitLen <= 0 {
err = fmt.Errorf("bitlen should be greater than 0, but it is %d", bitLen)
return
}
byteLen := bitLen / 8
if bitLen % 8 != 0 {
byteLen++
}
rawRand := make([]byte, byteLen)
for randNum.BitLen() == 0 || randNum.BitLen() > bitLen {
_, err = rand.Read(rawRand)
if err != nil {
return
}
randNum.SetBytes(rawRand)
// set MSBs to 0 to get a bitLen equal to bitLen param.
for bit := bitLen; bit < randNum.BitLen(); bit++ {
randNum.SetBit(randNum, bit, 0)
}
}
if randNum.BitLen() == 0 || randNum.BitLen() > bitLen {
err = fmt.Errorf("random number returned should have length at most %d, but its length is %d", bitLen, randNum.BitLen())
return
}
return
}
// generateSafePrimes generates two primes p and q, in a way that q
// is equal to (p-1)/2. The greatest prime bit length is at least bitLen bits.
func generateSafePrimes(bitLen int, randSource io.Reader) (*big.Int, *big.Int, error) {
if randSource == nil {
return big.NewInt(0), big.NewInt(0), fmt.Errorf("random source cannot be nil")
}
p := new(big.Int)
for {
q, err := rand.Prime(randSource, bitLen-1)
if err != nil {
return big.NewInt(0), big.NewInt(0), err
}
// p = 2q + 1
p.Lsh(q, 1)
p.SetBit(p,0,1)
if p.ProbablyPrime(c) {
return p, q, nil
}
}
}