-
Notifications
You must be signed in to change notification settings - Fork 5
/
crypto_test.go
158 lines (122 loc) · 4.1 KB
/
crypto_test.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package crypto_test
import (
"math/rand"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/filecoin-project/go-crypto"
)
func TestGenerateKey(t *testing.T) {
rand.Seed(time.Now().UnixNano())
sk, err := crypto.GenerateKey()
assert.NoError(t, err)
assert.Equal(t, len(sk), 32)
msg := generateMsg(32)
digest, err := crypto.Sign(sk, msg)
assert.NoError(t, err)
assert.Equal(t, len(digest), 65)
pk := crypto.PublicKey(sk)
// valid signature
assert.True(t, crypto.Verify(pk, msg, digest))
// invalid signature - different message (too short)
assert.False(t, crypto.Verify(pk, msg[3:], digest))
// invalid signature - different message
msg2 := make([]byte, 32)
copy(msg2, msg)
rand.Shuffle(len(msg2), func(i, j int) { msg2[i], msg2[j] = msg2[j], msg2[i] })
assert.False(t, crypto.Verify(pk, msg2, digest))
// invalid signature - different digest
digest2 := make([]byte, 65)
copy(digest2, digest)
rand.Shuffle(len(digest2), func(i, j int) { digest2[i], digest2[j] = digest2[j], digest2[i] })
assert.False(t, crypto.Verify(pk, msg, digest2))
// invalid signature - digest too short
assert.False(t, crypto.Verify(pk, msg, digest[3:]))
assert.False(t, crypto.Verify(pk, msg, digest[:29]))
// invalid signature - digest too long
digest3 := make([]byte, 70)
copy(digest3, digest)
assert.False(t, crypto.Verify(pk, msg, digest3))
recovered, err := crypto.EcRecover(msg, digest)
assert.NoError(t, err)
assert.Equal(t, recovered, crypto.PublicKey(sk))
}
func TestECRecoverInvalidMsgLength(t *testing.T) {
rand.Seed(time.Now().UnixNano())
sk, _ := crypto.GenerateKey()
// create three different message lengths for testing
shortMsg := generateMsg(31)
correctMsg := generateMsg(32)
longMsg := generateMsg(33)
// even though we sign the regular message, the msg length error should trigger first
digest, err := crypto.Sign(sk, correctMsg)
assert.NoError(t, err)
assert.Equal(t, len(digest), 65)
_, err = crypto.EcRecover(shortMsg, digest)
if assert.Error(t, err) {
assert.Equal(t, crypto.ErrInvalidMsgLength, err)
}
_, err = crypto.EcRecover(longMsg, digest)
if assert.Error(t, err) {
assert.Equal(t, crypto.ErrInvalidMsgLength, err)
}
_, err = crypto.EcRecover(correctMsg, digest)
assert.NoError(t, err)
}
func TestECRecoverInvalidRecoveryID(t *testing.T) {
rand.Seed(time.Now().UnixNano())
sk, _ := crypto.GenerateKey()
msg := generateMsg(32)
// even though we sign the regular message, the msg length error should trigger first
digest, err := crypto.Sign(sk, msg)
assert.NoError(t, err)
assert.Equal(t, len(digest), 65)
// valid recovery
pk, err := crypto.EcRecover(msg, digest)
assert.NoError(t, err)
assert.Equal(t, pk, crypto.PublicKey(sk))
// change the recovery ID to an invalid value
digest[64] = 4
_, err = crypto.EcRecover(msg, digest)
if assert.Error(t, err) {
assert.Contains(t, err.Error(), "secp256k1: invalid recovery ID")
}
}
func TestECRecoverInvalidSigLength(t *testing.T) {
rand.Seed(time.Now().UnixNano())
sk, _ := crypto.GenerateKey()
msg := generateMsg(32)
// even though we sign the regular message, the msg length error should trigger first
digest, err := crypto.Sign(sk, msg)
assert.NoError(t, err)
assert.Equal(t, len(digest), 65)
// valid recovery
pk, err := crypto.EcRecover(msg, digest)
assert.NoError(t, err)
assert.Equal(t, pk, crypto.PublicKey(sk))
// malform digest to be 66 bytes
digest = append(digest, 0x01)
_, err = crypto.EcRecover(msg, digest)
if assert.Error(t, err) {
assert.Contains(t, err.Error(), "secp256k1/secec: invalid compact signature")
}
// drop the recovery ID to form a 64 byte signature
digest = digest[:64]
_, err = crypto.EcRecover(msg, digest)
if assert.Error(t, err) {
assert.Contains(t, err.Error(), "secp256k1/secec: invalid compact signature")
}
// malform digest to be 32 bytes
digest = digest[:32]
_, err = crypto.EcRecover(msg, digest)
if assert.Error(t, err) {
assert.Contains(t, err.Error(), "secp256k1/secec: invalid compact signature")
}
}
func generateMsg(msgLength uint) []byte {
msg := make([]byte, msgLength)
for i := 0; i < len(msg); i++ {
msg[i] = byte(i)
}
return msg
}