-
Notifications
You must be signed in to change notification settings - Fork 10
/
signature.go
125 lines (112 loc) · 3.62 KB
/
signature.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Package signature provides support for digital signature algorithms.
package signature // import "chainspace.io/chainspace-go/internal/crypto/signature"
import (
"crypto/rand"
"fmt"
"golang.org/x/crypto/ed25519"
)
// The various digital signature schemes that are currently supported.
const (
Ed25519 Algorithm = iota + 1
)
// Algorithm represents a digital signature algorithm.
type Algorithm uint8
func AlgorithmFromString(s string) (Algorithm, error) {
switch s {
case Ed25519.String():
return Ed25519, nil
default:
return 0, fmt.Errorf("signature: unknown digitaly signature algorithm: %v", s)
}
}
func (s Algorithm) String() string {
switch s {
case Ed25519:
return "ed25519"
}
return ""
}
// KeyPair represents the combined public/private keypair for a digital
// signature algorithm.
type KeyPair interface {
Algorithm() Algorithm
PrivateKey() PrivateKey
PublicKey() PublicKey
Sign(data []byte) (sig []byte)
Value() []byte
Verify(data []byte, sig []byte) bool
}
// PrivateKey represents the private key for a digital signature algorithm. It
// can be used to sign data that can be verified by holders of the corresponding
// public key.
type PrivateKey interface {
Algorithm() Algorithm
Sign(data []byte) (sig []byte)
Value() []byte
}
// PublicKey represents the public key for a digital signature algorithm. It can
// be used to verify data that has been signed by the corresponding private key.
type PublicKey interface {
Algorithm() Algorithm
Value() []byte
Verify(data []byte, sig []byte) bool
}
// GenKeyPair generates a new keypair for the given digital signature algorithm.
// It uses crypto/rand's Reader behind the scenes as the source of randomness.
func GenKeyPair(s Algorithm) (KeyPair, error) {
switch s {
case Ed25519:
pub, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, err
}
return &ed25519KeyPair{
priv: ed25519PrivKey(priv),
pub: ed25519PubKey(pub),
}, nil
default:
return nil, fmt.Errorf("signature: unknown digital signature algorithm: %s", s)
}
}
// LoadKeyPair deserialises the given value into a type representing the
// combined public/private keypair for the given digital signature algorithm.
func LoadKeyPair(s Algorithm, value []byte) (KeyPair, error) {
switch s {
case Ed25519:
if len(value) != 96 {
return nil, fmt.Errorf("signature: the length of an Ed25519 keypair should be 96 bytes, got a key with length: %d", len(value))
}
return ed25519KeyPair{
priv: value[32:],
pub: value[:32],
}, nil
default:
return nil, fmt.Errorf("signature: unknown digital signature algorithm: %s", s)
}
}
// LoadPrivateKey deserialises the given value into a type implementing the
// PrivateKey interface for the given digital signature algorithm.
func LoadPrivateKey(s Algorithm, value []byte) (PrivateKey, error) {
switch s {
case Ed25519:
if len(value) != 64 {
return nil, fmt.Errorf("signature: the length of an Ed25519 private key should be 64 bytes, got a key with length: %d", len(value))
}
return ed25519PrivKey(value), nil
default:
return nil, fmt.Errorf("signature: unknown digital signature algorithm: %s", s)
}
}
// LoadPublicKey deserialises the given value into a type implementing the
// PublicKey interface for the given digital signature algorithm.
func LoadPublicKey(s Algorithm, value []byte) (PublicKey, error) {
switch s {
case Ed25519:
if len(value) != 32 {
return nil, fmt.Errorf("signature: the length of an Ed25519 public key should be 32 bytes, got a key with length: %d", len(value))
}
return ed25519PubKey(value), nil
default:
return nil, fmt.Errorf("signature: unknown digital signature algorithm: %s", s)
}
}