-
Notifications
You must be signed in to change notification settings - Fork 0
/
x25519_go1.20.go
74 lines (64 loc) · 1.84 KB
/
x25519_go1.20.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
72
73
74
//go:build go1.20
package x25519
import (
"crypto/ecdh"
cryptorand "crypto/rand"
"io"
)
// ECDH returns pub as a [crypto/ecdh.PublicKey].
func (pub PublicKey) ECDH() (*ecdh.PublicKey, error) {
c := ecdh.X25519()
return c.NewPublicKey(pub)
}
// ECDH returns priv as a [crypto/ecdh.PrivateKey].
func (priv PrivateKey) ECDH() (*ecdh.PrivateKey, error) {
c := ecdh.X25519()
return c.NewPrivateKey(priv[:SeedSize])
}
// GenerateKey generates a public/private key pair using entropy from rand.
// If rand is nil, crypto/rand.Reader will be used.
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
if rand == nil {
rand = cryptorand.Reader
}
c := ecdh.X25519()
priv, err := c.GenerateKey(rand)
if err != nil {
return nil, nil, err
}
pub := priv.PublicKey()
pubBytes := pub.Bytes()
privBytes := priv.Bytes()
privBytes = append(privBytes, pubBytes...)
return PublicKey(pubBytes), PrivateKey(privBytes), nil
}
// NewKeyFromSeed calculates a private key from a seed. It will panic if
// len(seed) is not SeedSize. This function is provided for interoperability
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
// package.
func NewKeyFromSeed(seed []byte) PrivateKey {
c := ecdh.X25519()
priv, err := c.NewPrivateKey(seed)
if err != nil {
panic(err)
}
pub := priv.PublicKey()
pubBytes := pub.Bytes()
privBytes := priv.Bytes()
privBytes = append(privBytes, pubBytes...)
return PrivateKey(privBytes)
}
// X25519 returns the result of the scalar multiplication (scalar * point),
// according to RFC 7748, Section 5. scalar, point and the return value are slices of 32 bytes.
func X25519(scalar, point []byte) ([]byte, error) {
c := ecdh.X25519()
priv, err := c.NewPrivateKey(scalar)
if err != nil {
return nil, err
}
pub, err := c.NewPublicKey(point)
if err != nil {
return nil, err
}
return priv.ECDH(pub)
}