forked from FactomProject/FactomCode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkey.go
More file actions
118 lines (98 loc) · 2.89 KB
/
key.go
File metadata and controls
118 lines (98 loc) · 2.89 KB
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
package common
import (
"crypto/rand"
"encoding/hex"
"errors"
"github.com/FactomProject/ed25519"
)
// Verifyer objects can Verify signed messages
type Verifyer interface {
Verify(msg []byte) bool
}
// Signer object can Sign msg
type Signer interface {
Sign(msg []byte) Signature
}
// PrivateKey contains Public/Private key pair
type PrivateKey struct {
Key *[ed25519.PrivateKeySize]byte
Pub PublicKey
}
func (pk PrivateKey) Public() []byte {
return (*pk.Pub.Key)[:]
}
func (pk *PrivateKey) AllocateNew() {
pk.Key = new([64]byte)
pk.Pub.Key = new([32]byte)
}
// Create a new private key from a hex string
func NewPrivateKeyFromHex(s string) (pk PrivateKey, err error) {
privKeybytes, err := hex.DecodeString(s)
if privKeybytes == nil || len(privKeybytes) != ed25519.PrivateKeySize {
return pk, errors.New("Invalid private key input string!")
}
pk.AllocateNew()
copy(pk.Key[:], privKeybytes)
copy(pk.Pub.Key[:], privKeybytes[32:])
return
}
// PublicKey contains only Public part of Public/Private key pair
type PublicKey struct {
Key *[ed25519.PublicKeySize]byte
}
func (pk *PublicKey) MarshalText() ([]byte, error) {
return []byte(pk.String()), nil
}
func (pk *PublicKey) UnmarshalText(b []byte) error {
p, err := hex.DecodeString(string(b))
if err != nil {
return err
}
pk.Key = new([32]byte)
copy(pk.Key[:], p)
return nil
}
func (pk PublicKey) String() string {
return hex.EncodeToString((*pk.Key)[:])
}
func PubKeyFromString(instr string) (pk PublicKey) {
p, _ := hex.DecodeString(instr)
pk.Key = new([32]byte)
copy(pk.Key[:], p)
return
}
// Sign signs msg with PrivateKey and return Signature
func (pk PrivateKey) Sign(msg []byte) (sig Signature) {
sig.Pub = pk.Pub
sig.Sig = ed25519.Sign(pk.Key, msg)
return
}
// Sign signs msg with PrivateKey and return Signature
func (pk PrivateKey) MarshalSign(msg BinaryMarshallable) (sig Signature) {
data, _ := msg.MarshalBinary()
return pk.Sign(data)
}
// Verify returns true iff sig is a valid signature of msg by PublicKey.
func (sig Signature) Verify(msg []byte) bool {
return ed25519.VerifyCanonical(sig.Pub.Key, msg, sig.Sig)
}
//Generate creates new PrivateKey / PublciKey pair or returns error
func (pk *PrivateKey) GenerateKey() (err error) {
pk.Pub.Key, pk.Key, err = ed25519.GenerateKey(rand.Reader)
return err
}
func (k PublicKey) Verify(msg []byte, sig *[ed25519.SignatureSize]byte) bool {
return ed25519.VerifyCanonical(k.Key, msg, sig)
}
// Verify returns true iff sig is a valid signature of message by publicKey.
func Verify(publicKey *[ed25519.PublicKeySize]byte, message []byte, sig *[ed25519.SignatureSize]byte) bool {
return ed25519.VerifyCanonical(publicKey, message, sig)
}
// Verify returns true iff sig is a valid signature of message by publicKey.
func VerifySlice(p []byte, message []byte, s []byte) bool {
sig := new([64]byte)
pub := new([32]byte)
copy(sig[:], s)
copy(pub[:], p)
return Verify(pub, message, sig)
}