verify_test.go raw
1 //go:build !js && !wasm && !tinygo && !wasm32
2
3 package p256k1
4
5 import (
6 "testing"
7 )
8
9 // TestSecp256k1SchnorrsigVerifyComparison tests that secp256k1_schnorrsig_verify
10 // produces the same results as the existing SchnorrVerify function
11 func TestSecp256k1SchnorrsigVerifyComparison(t *testing.T) {
12 // Create a context (required by secp256k1_schnorrsig_verify)
13 ctx := &secp256k1_context{
14 ecmult_gen_ctx: secp256k1_ecmult_gen_context{built: 1},
15 declassify: 0,
16 }
17
18 // Test case 1: Valid signature
19 t.Run("ValidSignature", func(t *testing.T) {
20 // Generate keypair
21 kp, err := KeyPairGenerate()
22 if err != nil {
23 t.Fatalf("failed to generate keypair: %v", err)
24 }
25 defer kp.Clear()
26
27 // Get x-only pubkey
28 xonly, err := kp.XOnlyPubkey()
29 if err != nil {
30 t.Fatalf("failed to get x-only pubkey: %v", err)
31 }
32
33 // Create message
34 msg := make([]byte, 32)
35 for i := range msg {
36 msg[i] = byte(i)
37 }
38
39 // Sign
40 var sig [64]byte
41 if err := SchnorrSign(sig[:], msg, kp, nil); err != nil {
42 t.Fatalf("failed to sign: %v", err)
43 }
44
45 // Convert x-only pubkey to secp256k1_xonly_pubkey format
46 var secp_xonly secp256k1_xonly_pubkey
47 copy(secp_xonly.data[:], xonly.data[:])
48
49 // Test existing implementation (old)
50 existingResult := SchnorrVerifyOld(sig[:], msg, xonly)
51
52 // Test new implementation (C-translated)
53 newResult := SchnorrVerify(sig[:], msg, xonly)
54
55 // Compare results
56 if existingResult != newResult {
57 t.Errorf("results differ: existing=%v, new=%v", existingResult, newResult)
58 }
59
60 if !existingResult {
61 t.Error("signature verification failed (both implementations)")
62 }
63 })
64
65 // Test case 2: Invalid signature (wrong message)
66 t.Run("InvalidSignature_WrongMessage", func(t *testing.T) {
67 // Generate keypair
68 kp, err := KeyPairGenerate()
69 if err != nil {
70 t.Fatalf("failed to generate keypair: %v", err)
71 }
72 defer kp.Clear()
73
74 // Get x-only pubkey
75 xonly, err := kp.XOnlyPubkey()
76 if err != nil {
77 t.Fatalf("failed to get x-only pubkey: %v", err)
78 }
79
80 // Create message
81 msg := make([]byte, 32)
82 for i := range msg {
83 msg[i] = byte(i)
84 }
85
86 // Sign
87 var sig [64]byte
88 if err := SchnorrSign(sig[:], msg, kp, nil); err != nil {
89 t.Fatalf("failed to sign: %v", err)
90 }
91
92 // Create wrong message
93 wrongMsg := make([]byte, 32)
94 copy(wrongMsg, msg)
95 wrongMsg[0] ^= 1
96
97 // Convert x-only pubkey to secp256k1_xonly_pubkey format
98 var secp_xonly secp256k1_xonly_pubkey
99 copy(secp_xonly.data[:], xonly.data[:])
100
101 // Test existing implementation (old)
102 existingResult := SchnorrVerifyOld(sig[:], wrongMsg, xonly)
103
104 // Test new implementation (C-translated)
105 newResult := SchnorrVerify(sig[:], wrongMsg, xonly)
106
107 // Compare results
108 if existingResult != newResult {
109 t.Errorf("results differ: existing=%v, new=%v", existingResult, newResult)
110 }
111
112 if existingResult {
113 t.Error("signature verification should fail with wrong message (both implementations)")
114 }
115 })
116
117 // Test case 3: Invalid signature (wrong signature)
118 t.Run("InvalidSignature_WrongSignature", func(t *testing.T) {
119 // Generate keypair
120 kp, err := KeyPairGenerate()
121 if err != nil {
122 t.Fatalf("failed to generate keypair: %v", err)
123 }
124 defer kp.Clear()
125
126 // Get x-only pubkey
127 xonly, err := kp.XOnlyPubkey()
128 if err != nil {
129 t.Fatalf("failed to get x-only pubkey: %v", err)
130 }
131
132 // Create message
133 msg := make([]byte, 32)
134 for i := range msg {
135 msg[i] = byte(i)
136 }
137
138 // Sign
139 var sig [64]byte
140 if err := SchnorrSign(sig[:], msg, kp, nil); err != nil {
141 t.Fatalf("failed to sign: %v", err)
142 }
143
144 // Create wrong signature
145 wrongSig := make([]byte, 64)
146 copy(wrongSig, sig[:])
147 wrongSig[0] ^= 1
148
149 // Convert x-only pubkey to secp256k1_xonly_pubkey format
150 var secp_xonly secp256k1_xonly_pubkey
151 copy(secp_xonly.data[:], xonly.data[:])
152
153 // Test existing implementation (old)
154 existingResult := SchnorrVerifyOld(wrongSig, msg, xonly)
155
156 // Test new implementation (C-translated)
157 newResult := SchnorrVerify(wrongSig, msg, xonly)
158
159 // Compare results
160 if existingResult != newResult {
161 t.Errorf("results differ: existing=%v, new=%v", existingResult, newResult)
162 }
163
164 if existingResult {
165 t.Error("signature verification should fail with wrong signature (both implementations)")
166 }
167 })
168
169 // Test case 4: Invalid signature (wrong pubkey)
170 t.Run("InvalidSignature_WrongPubkey", func(t *testing.T) {
171 // Generate two keypairs
172 kp1, err := KeyPairGenerate()
173 if err != nil {
174 t.Fatalf("failed to generate keypair 1: %v", err)
175 }
176 defer kp1.Clear()
177
178 kp2, err := KeyPairGenerate()
179 if err != nil {
180 t.Fatalf("failed to generate keypair 2: %v", err)
181 }
182 defer kp2.Clear()
183
184 // Get x-only pubkey for kp2 (we sign with kp1, verify with kp2)
185 xonly2, err := kp2.XOnlyPubkey()
186 if err != nil {
187 t.Fatalf("failed to get x-only pubkey 2: %v", err)
188 }
189
190 // Create message
191 msg := make([]byte, 32)
192 for i := range msg {
193 msg[i] = byte(i)
194 }
195
196 // Sign with keypair 1
197 var sig [64]byte
198 if err := SchnorrSign(sig[:], msg, kp1, nil); err != nil {
199 t.Fatalf("failed to sign: %v", err)
200 }
201
202 // Convert x-only pubkey 2 to secp256k1_xonly_pubkey format
203 var secp_xonly2 secp256k1_xonly_pubkey
204 copy(secp_xonly2.data[:], xonly2.data[:])
205
206 // Test existing implementation (old, verify with wrong pubkey)
207 existingResult := SchnorrVerifyOld(sig[:], msg, xonly2)
208
209 // Test new implementation (C-translated, verify with wrong pubkey)
210 newResult := SchnorrVerify(sig[:], msg, xonly2)
211
212 // Compare results
213 if existingResult != newResult {
214 t.Errorf("results differ: existing=%v, new=%v", existingResult, newResult)
215 }
216
217 if existingResult {
218 t.Error("signature verification should fail with wrong pubkey (both implementations)")
219 }
220 })
221
222 // Test case 5: Edge cases - nil/invalid inputs
223 t.Run("EdgeCases", func(t *testing.T) {
224 // Generate keypair
225 kp, err := KeyPairGenerate()
226 if err != nil {
227 t.Fatalf("failed to generate keypair: %v", err)
228 }
229 defer kp.Clear()
230
231 // Get x-only pubkey
232 xonly, err := kp.XOnlyPubkey()
233 if err != nil {
234 t.Fatalf("failed to get x-only pubkey: %v", err)
235 }
236
237 msg := make([]byte, 32)
238 var sig [64]byte
239
240 // Test with nil context
241 var secp_xonly secp256k1_xonly_pubkey
242 copy(secp_xonly.data[:], xonly.data[:])
243
244 newResult := secp256k1_schnorrsig_verify(nil, sig[:], msg, len(msg), &secp_xonly)
245 if newResult != 0 {
246 t.Error("should return 0 with nil context")
247 }
248
249 // Test with nil signature
250 newResult = secp256k1_schnorrsig_verify(ctx, nil, msg, len(msg), &secp_xonly)
251 if newResult != 0 {
252 t.Error("should return 0 with nil signature")
253 }
254
255 // Test with nil pubkey
256 newResult = secp256k1_schnorrsig_verify(ctx, sig[:], msg, len(msg), nil)
257 if newResult != 0 {
258 t.Error("should return 0 with nil pubkey")
259 }
260
261 // Test with invalid signature length
262 if SchnorrVerify([]byte{1}, msg, xonly) {
263 t.Error("existing: should fail with invalid signature length")
264 }
265 newResult = secp256k1_schnorrsig_verify(ctx, []byte{1}, msg, len(msg), &secp_xonly)
266 if newResult != 0 {
267 t.Error("new: should return 0 with invalid signature length")
268 }
269 })
270
271 // Test case 6: Multiple signatures with different aux_rand
272 t.Run("MultipleSignatures_DifferentAuxRand", func(t *testing.T) {
273 // Generate keypair
274 kp, err := KeyPairGenerate()
275 if err != nil {
276 t.Fatalf("failed to generate keypair: %v", err)
277 }
278 defer kp.Clear()
279
280 // Get x-only pubkey
281 xonly, err := kp.XOnlyPubkey()
282 if err != nil {
283 t.Fatalf("failed to get x-only pubkey: %v", err)
284 }
285
286 msg := make([]byte, 32)
287
288 // Sign with different aux_rand values
289 auxRand1 := make([]byte, 32)
290 auxRand2 := make([]byte, 32)
291 for i := range auxRand1 {
292 auxRand1[i] = byte(i)
293 auxRand2[i] = byte(i + 1)
294 }
295
296 var sig1, sig2 [64]byte
297 if err := SchnorrSign(sig1[:], msg, kp, auxRand1); err != nil {
298 t.Fatalf("failed to sign: %v", err)
299 }
300 if err := SchnorrSign(sig2[:], msg, kp, auxRand2); err != nil {
301 t.Fatalf("failed to sign: %v", err)
302 }
303
304 // Convert x-only pubkey to secp256k1_xonly_pubkey format
305 var secp_xonly secp256k1_xonly_pubkey
306 copy(secp_xonly.data[:], xonly.data[:])
307
308 // Test both signatures with existing implementation
309 existingResult1 := SchnorrVerify(sig1[:], msg, xonly)
310 existingResult2 := SchnorrVerify(sig2[:], msg, xonly)
311
312 // Test both signatures with new implementation
313 newResult1 := secp256k1_schnorrsig_verify(ctx, sig1[:], msg, len(msg), &secp_xonly)
314 newResult2 := secp256k1_schnorrsig_verify(ctx, sig2[:], msg, len(msg), &secp_xonly)
315
316 // Compare results
317 if existingResult1 != (newResult1 != 0) {
318 t.Errorf("signature 1 results differ: existing=%v, new=%d", existingResult1, newResult1)
319 }
320 if existingResult2 != (newResult2 != 0) {
321 t.Errorf("signature 2 results differ: existing=%v, new=%d", existingResult2, newResult2)
322 }
323
324 if !existingResult1 || !existingResult2 {
325 t.Error("both signatures should verify")
326 }
327 })
328
329 // Test case 7: Empty message
330 t.Run("EmptyMessage", func(t *testing.T) {
331 // Generate keypair
332 kp, err := KeyPairGenerate()
333 if err != nil {
334 t.Fatalf("failed to generate keypair: %v", err)
335 }
336 defer kp.Clear()
337
338 // Get x-only pubkey
339 xonly, err := kp.XOnlyPubkey()
340 if err != nil {
341 t.Fatalf("failed to get x-only pubkey: %v", err)
342 }
343
344 // Create 32-byte message (all zeros)
345 msg := make([]byte, 32)
346
347 // Sign
348 var sig [64]byte
349 if err := SchnorrSign(sig[:], msg, kp, nil); err != nil {
350 t.Fatalf("failed to sign: %v", err)
351 }
352
353 // Convert x-only pubkey to secp256k1_xonly_pubkey format
354 var secp_xonly secp256k1_xonly_pubkey
355 copy(secp_xonly.data[:], xonly.data[:])
356
357 // Test existing implementation (old)
358 existingResult := SchnorrVerifyOld(sig[:], msg, xonly)
359
360 // Test new implementation (C-translated)
361 newResult := SchnorrVerify(sig[:], msg, xonly)
362
363 // Compare results
364 if existingResult != newResult {
365 t.Errorf("results differ: existing=%v, new=%v", existingResult, newResult)
366 }
367
368 if !existingResult {
369 t.Error("signature verification failed for empty message")
370 }
371 })
372 }
373