-
Notifications
You must be signed in to change notification settings - Fork 0
/
key.go
71 lines (64 loc) · 1.55 KB
/
key.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
67
68
69
70
71
package ecc
import (
"bytes"
"crypto/ecdsa"
"crypto/sha512"
"io"
"golang.org/x/crypto/hkdf"
"golang.org/x/crypto/scrypt"
)
// GenerateKey generates ECDSA key from specified Curve.
func GenerateKey(c *Curve, rr io.Reader) (*ecdsa.PrivateKey, error) {
return ecdsa.GenerateKey(c.Curve(), rr)
}
func GenerateCoolKey(c *Curve, rr io.Reader) (*ecdsa.PrivateKey, error) {
for {
priv, err := ecdsa.GenerateKey(c.Curve(), rr)
if err != nil {
return nil, err
}
short, err := MarshalShortPrivateKey(priv)
if err != nil {
return nil, err
}
if bytes.IndexAny(short, "_-+/") >= 0 {
continue
}
short, err = MarshalShortPublicKey(&priv.PublicKey)
if err != nil {
return nil, err
}
if bytes.IndexAny(short, "_-+/") < 0 {
return priv, nil
}
}
}
func GenerateKeyFromData(c *Curve, data []byte, salt []byte) (*ecdsa.PrivateKey, error) {
return GenerateKey(c, hkdf.New(sha512.New, data, salt, nil))
}
type SCryptOpts struct {
Curve *Curve
N int
R int
P int
Salt []byte
}
func NewDefaultSCryptOpts() *SCryptOpts {
return &SCryptOpts{
Curve: LookupCurve("secp521r1"),
N: 1<<20,
R: 8,
P: 1,
Salt: nil,
}
}
func GenerateKeyFromPassword(password []byte, scryptOpts *SCryptOpts) (*ecdsa.PrivateKey, error) {
if scryptOpts == nil {
scryptOpts = NewDefaultSCryptOpts()
}
key, err := scrypt.Key(password, scryptOpts.Salt, scryptOpts.N, scryptOpts.R, scryptOpts.P, 1048576)
if err != nil {
return nil, err
}
return GenerateKeyFromData(scryptOpts.Curve, key, scryptOpts.Salt)
}