-
Notifications
You must be signed in to change notification settings - Fork 2
/
safeprime.go
64 lines (50 loc) · 1.37 KB
/
safeprime.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
// +build !android,!ios,!windows,cgo
// Package safeprime is a small wrapper around openssl's BN_generate_prime_ex for generating safe primes.
package safeprime
import (
"errors"
"math/big"
"github.com/rainycape/dl"
)
var bnNew func() uintptr
var bnFree func(uintptr)
var bnGenPrime func(uintptr, int, int, uintptr, uintptr, uintptr) int
var bnToHex func(uintptr) string
// Generate uses openssl's BN_generate_prime_ex to generate a new safe prime of the given size.
func Generate(bitsize int) (*big.Int, error) {
openssl, err := linkOpenssl()
if err != nil {
return nil, err
}
defer openssl.Close()
bignum := bnNew()
if bignum == 0 {
return nil, errors.New("BN_new could not allocate new bignum")
}
defer bnFree(bignum)
if r := bnGenPrime(bignum, bitsize, 1, 0, 0, 0); r != 1 {
return nil, errors.New("BN_generate_prime_ex failed")
}
x := new(big.Int)
x.SetString(bnToHex(bignum), 16)
return x, nil
}
func linkOpenssl() (*dl.DL, error) {
openssl, err := dl.Open("libssl", 0)
if err != nil {
return nil, err
}
if err = openssl.Sym("BN_new", &bnNew); err != nil {
return nil, err
}
if err = openssl.Sym("BN_clear_free", &bnFree); err != nil {
return nil, err
}
if err = openssl.Sym("BN_generate_prime_ex", &bnGenPrime); err != nil {
return nil, err
}
if err = openssl.Sym("BN_bn2hex", &bnToHex); err != nil {
return nil, err
}
return openssl, nil
}