1
2
3
4
5 package schnorr
6
7 import (
8 "bytes"
9 "errors"
10 "math/rand"
11 "testing"
12 "time"
13
14 "github.com/decred/dcrd/crypto/blake256"
15 "github.com/decred/dcrd/dcrec/secp256k1/v4"
16 )
17
18
19
20 func TestSignatureParsing(t *testing.T) {
21 tests := []struct {
22 name string
23 sig string
24 err error
25 }{{
26 name: "valid signature 1",
27 sig: "c6ec70969d8367538c442f8e13eb20ff0c9143690f31cd3a384da54dd29ec0aa" +
28 "4b78a1b0d6b4186195d42a85614d3befd9f12ed26542d0dd1045f38c98b4a405",
29 err: nil,
30 }, {
31 name: "valid signature 2",
32 sig: "adc21db084fa1765f9372c2021fb298720f3d13e6d844e2dff751a2d46a69277" +
33 "0b989e316f7faf308a5f4a7343c0569465287cf6bff457250d6dacbb361f6e63",
34 err: nil,
35 }, {
36 name: "empty",
37 sig: "",
38 err: ErrSigTooShort,
39 }, {
40 name: "too short by one byte",
41 sig: "adc21db084fa1765f9372c2021fb298720f3d13e6d844e2dff751a2d46a69277" +
42 "0b989e316f7faf308a5f4a7343c0569465287cf6bff457250d6dacbb361f6e",
43 err: ErrSigTooShort,
44 }, {
45 name: "too long by one byte",
46 sig: "adc21db084fa1765f9372c2021fb298720f3d13e6d844e2dff751a2d46a69277" +
47 "0b989e316f7faf308a5f4a7343c0569465287cf6bff457250d6dacbb361f6e6300",
48 err: ErrSigTooLong,
49 }, {
50 name: "r == p",
51 sig: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f" +
52 "181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d09",
53 err: ErrSigRTooBig,
54 }, {
55 name: "r > p",
56 sig: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30" +
57 "181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d09",
58 err: ErrSigRTooBig,
59 }, {
60 name: "s == n",
61 sig: "4e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41" +
62 "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
63 err: ErrSigSTooBig,
64 }, {
65 name: "s > n",
66 sig: "4e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41" +
67 "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142",
68 err: ErrSigSTooBig,
69 }}
70
71 for _, test := range tests {
72 _, err := ParseSignature(hexToBytes(test.sig))
73 if !errors.Is(err, test.err) {
74 t.Errorf("%s mismatched err -- got %v, want %v", test.name, err,
75 test.err)
76 continue
77 }
78 }
79 }
80
81
82
83
84
85 func TestSchnorrSignAndVerify(t *testing.T) {
86 tests := []struct {
87 name string
88 key string
89 msg string
90 hash string
91 nonce string
92 rfc6979 bool
93 expected string
94 }{{
95 name: "key 0x1, blake256(0x01020304), rfc6979 nonce",
96 key: "0000000000000000000000000000000000000000000000000000000000000001",
97 msg: "01020304",
98 hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7",
99 nonce: "d4e18f08eb87073cb2a6707def02007315f7349c3c132590a0088fefece557ef",
100 rfc6979: true,
101 expected: "4c68976afe187ff0167919ad181cb30f187e2af1c8233b2cbebbbe0fc97fff61" +
102 "e9ae2d0e306497236d4e328dc1a34244045745e87da69d806859348bc2a74525",
103 }, {
104 name: "key 0x1, blake256(0x01020304), random nonce",
105 key: "0000000000000000000000000000000000000000000000000000000000000001",
106 msg: "01020304",
107 hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7",
108 nonce: "a6df66500afeb7711d4c8e2220960855d940a5ed57260d2c98fbf6066cca283e",
109 rfc6979: false,
110 expected: "b073759a96a835b09b79e7b93c37fdbe48fb82b000c4a0e1404ba5d1fbc15d0a" +
111 "299d614b02dec30f8261ae43d09a224b233f3221405c9ffd3d2b00a3d2188fd4",
112 }, {
113 name: "key 0x2, blake256(0x01020304), rfc6979 nonce",
114 key: "0000000000000000000000000000000000000000000000000000000000000002",
115 msg: "01020304",
116 hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7",
117 nonce: "341682d3064ec802646be9c4a0fd97f8480807fcac3179e97098b8597de909dc",
118 rfc6979: true,
119 expected: "c6deb3a26c08842612bfd4411a91c90f64cfea2206c758cd1352ff2b93cc3611" +
120 "c9ffe5dd240f52d3ee199e29373030a5d795b674cd4da991fd07f5edefc3817d",
121 }, {
122 name: "key 0x2, blake256(0x01020304), random nonce",
123 key: "0000000000000000000000000000000000000000000000000000000000000002",
124 msg: "01020304",
125 hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7",
126 nonce: "679a6d36e7fe6c02d7668af86d78186e8f9ccc04371ac1c8c37939d1f5cae07a",
127 rfc6979: false,
128 expected: "4a090d82f48ca12d9e7aa24b5dcc187ee0db2920496f671d63e86036aaa7997e" +
129 "16d33ae10eade4db33dda17873948b4803d6eb9b10781616880a6f66ba2d1b78",
130 }, {
131 name: "key 0x1, blake256(0x0102030405), rfc6979 nonce",
132 key: "0000000000000000000000000000000000000000000000000000000000000001",
133 msg: "0102030405",
134 hash: "dc063eba3c8d52a159e725c1a161506f6cb6b53478ad5ef3f08d534efa871d9f",
135 nonce: "cfbabebb15824ff3cfa5f4080a8608aaa9db891541851b27275c61db9d6d7e1c",
136 rfc6979: true,
137 expected: "461646005002d673c2e903f3c9ff2c2455e60810445ee486b9c36152287bc41a" +
138 "1b54733190ed128e466c5263a404f17344b73426d7faf00325c7a0af04be6cfe",
139 }, {
140 name: "key 0x1, blake256(0x0102030405), random nonce",
141 key: "0000000000000000000000000000000000000000000000000000000000000001",
142 msg: "0102030405",
143 hash: "dc063eba3c8d52a159e725c1a161506f6cb6b53478ad5ef3f08d534efa871d9f",
144 nonce: "65f880c892fdb6e7f74f76b18c7c942cfd037ef9cf97c39c36e08bbc36b41616",
145 rfc6979: false,
146 expected: "72e5666f4e9d1099447b825cf737ee32112f17a67e2ca7017ae098da31dfbb8b" +
147 "c19f5a4f815e9737f1b635075c50b3fa28dbbbebfcb98749b9f3c7b0fa748422",
148 }, {
149 name: "key 0x2, blake256(0x0102030405), rfc6979 nonce",
150 key: "0000000000000000000000000000000000000000000000000000000000000002",
151 msg: "0102030405",
152 hash: "dc063eba3c8d52a159e725c1a161506f6cb6b53478ad5ef3f08d534efa871d9f",
153 nonce: "f7a8f640df67ba21b619eb742a73cbfc58739153b8772d5b2f8781f33d45e554",
154 rfc6979: true,
155 expected: "f3632492a72eb8e175b93e1eb31ef382e49f3f3fe385892523beaef9171aa15d" +
156 "441e1a94ab9b1dafa93e0d48d08c26513d53449197e761c74bebb2fae97525c3",
157 }, {
158 name: "key 0x2, blake256(0x0102030405), random nonce",
159 key: "0000000000000000000000000000000000000000000000000000000000000002",
160 msg: "0102030405",
161 hash: "dc063eba3c8d52a159e725c1a161506f6cb6b53478ad5ef3f08d534efa871d9f",
162 nonce: "026ece4cfb704733dd5eef7898e44c33bd5a0d749eb043f48705e40fa9e9afa0",
163 rfc6979: false,
164 expected: "3c4c5a2f217ea758113fd4e89eb756314dfad101a300f48e5bd764d3b6e0f8bf" +
165 "c29f43beed7d84348386152f1c43fc606d0887fa5b6f5c0b7875687f53b344f0",
166 }, {
167 name: "random key 1, blake256(0x01), rfc6979 nonce",
168 key: "a1becef2069444a9dc6331c3247e113c3ee142edda683db8643f9cb0af7cbe33",
169 msg: "01",
170 hash: "4a6c419a1e25c85327115c4ace586decddfe2990ed8f3d4d801871158338501d",
171 nonce: "c23097718bd90c10ba2e99abff92f21c0eec71796712a772f0ce10f2b1bc6f5f",
172 rfc6979: true,
173 expected: "0b89d1fb10635e4a5da463c7339fd0f8d2e7d205a8288d4f973635beb8b59f7f" +
174 "e7c69c94ac665d14c105c2b4ba3b4c59a7819f8ecfe0d9f5f0c93a9f6d7ef447",
175 }, {
176 name: "random key 2, blake256(0x02), rfc6979 nonce",
177 key: "59930b76d4b15767ec0e8c8e5812aa2e57db30c6af7963e2a6295ba02af5416b",
178 msg: "02",
179 hash: "49af37ab5270015fe25276ea5a3bb159d852943df23919522a202205fb7d175c",
180 nonce: "342d8326464a0b5866091126e2aa29a960eba8e47dba7bef355b18b3f9011793",
181 rfc6979: true,
182 expected: "533e99ee9c838af4cc0280b0223ab0560e7e2083694bd5b0cab3c0cb80bc2e1e" +
183 "cf4f777f046a18b7f8eb2c29325945025e6d5a145176b1a1de9aca7d882ca5d2",
184 }, {
185 name: "random key 3, blake256(0x03), rfc6979 nonce",
186 key: "c5b205c36bb7497d242e96ec19a2a4f086d8daa919135cf490d2b7c0230f0e91",
187 msg: "03",
188 hash: "b706d561742ad3671703c247eb927ee8a386369c79644131cdeb2c5c26bf6c5d",
189 nonce: "710a4f1a3bee3567b53bd4dd0c9c0e55d76981a5ed488223ca0583bf8a563951",
190 rfc6979: true,
191 expected: "95c966fd6435d505a492548370b29a3c40efc3fefa3e1d997b3e2788cc33836e" +
192 "84a19d1d32c98f266f57f12c4363c0d9d432ca76985c6b7cb21c9970e14c75d8",
193 }, {
194 name: "random key 4, blake256(0x04), rfc6979 nonce",
195 key: "65b46d4eb001c649a86309286aaf94b18386effe62c2e1586d9b1898ccf0099b",
196 msg: "04",
197 hash: "4c6eb9e38415034f4c93d3304d10bef38bf0ad420eefd0f72f940f11c5857786",
198 nonce: "cb4727000027551b8c2c3b717696dcff46f9ad088050571cb8634038003fc136",
199 rfc6979: true,
200 expected: "327f4e1dc74948df95dba34f26b63317568325316742fc8276be8cd2544a105c" +
201 "ecd401dcd37834c2c007bb3402130fcac0cca549326b81727097d4420e73268c",
202 }, {
203 name: "random key 5, blake256(0x05), rfc6979 nonce",
204 key: "915cb9ba4675de06a182088b182abcf79fa8ac989328212c6b866fa3ec2338f9",
205 msg: "05",
206 hash: "bdd15db13448905791a70b68137445e607cca06cc71c7a58b9b2e84a06c54d08",
207 nonce: "665a2ba74200aaee038de3248c1acb8d92ca9c0a89ff63d140755834e04d55e8",
208 rfc6979: true,
209 expected: "b3ac51091150852794914e12f12b8db00ec517ca8eeca0175a20e62b1a413a5c" +
210 "f942de4435ff6016a3faf233100b82c66d2e6efa423b2df0f3f1ee115dfc39f5",
211 }, {
212 name: "random key 6, blake256(0x06), rfc6979 nonce",
213 key: "93e9d81d818f08ba1f850c6dfb82256b035b42f7d43c1fe090804fb009aca441",
214 msg: "06",
215 hash: "19b7506ad9c189a9f8b063d2aee15953d335f5c88480f8515d7d848e7771c4ae",
216 nonce: "b817c907f71b11359bc2857e39f0f13d3a2cbaaadb722665ea73d7edf38c4342",
217 rfc6979: true,
218 expected: "01bfb35cf41d809d572d1d891eb474e2c0decf67ebb0f1432edce06b75d73fe0" +
219 "36a1015a13c6bcf50a94b87f5ef2725cf892c40e0e0fbaa5ca33e02dc6d3f19d",
220 }, {
221 name: "random key 7, blake256(0x07), rfc6979 nonce",
222 key: "c249bbd5f533672b7dcd514eb1256854783531c2b85fe60bf4ce6ea1f26afc2b",
223 msg: "07",
224 hash: "53d661e71e47a0a7e416591200175122d83f8af31be6a70af7417ad6f54d0038",
225 nonce: "7eaa64ba668b3c77b0586695645707236f165a76ed7a53a04c833048995f8bc7",
226 rfc6979: true,
227 expected: "cb5bd3805bdd0a2e4daf58b30aa26b48c81ca59421ca320ad983c1eef672ad52" +
228 "5be5b6de8c0c343830bb803e0384a3942404485e8797cb48ac9ea332831fb5ad",
229 }, {
230 name: "random key 8, blake256(0x08), rfc6979 nonce",
231 key: "ec0be92fcec66cf1f97b5c39f83dfd4ddcad0dad468d3685b5eec556c6290bcc",
232 msg: "08",
233 hash: "9bff7982eab6f7883322edf7bdc86a23c87ca1c07906fbb1584f57b197dc6253",
234 nonce: "63e12aa7d19a413577fbf6a0896f13040befb5b675f9238a09b9db400d9f454a",
235 rfc6979: true,
236 expected: "9fbd427ddaef7c7ab87e5555c1faca398695e423ce44e5fc648b9203e38b69a0" +
237 "47f0752e1d421e24b3eb8666c9a966b86fd49438dda1a4987cb77f3147b8fa6a",
238 }, {
239 name: "random key 9, blake256(0x09), rfc6979 nonce",
240 key: "6847b071a7cba6a85099b26a9c3e57a964e4990620e1e1c346fecc4472c4d834",
241 msg: "09",
242 hash: "4c2231813064f8500edae05b40195416bd543fd3e76c16d6efb10c816d92e8b6",
243 nonce: "95adf9b15f485dc961061053838dbd0fb1fa8663ac344d78f3833acb5fdbfdc6",
244 rfc6979: true,
245 expected: "cd9e9100f0fc8b631b40c4d93437eaf608e25ab6ad295d8b6460289ce571fb1e" +
246 "a91d3c16da2fb15ce0090702df4d824dc167a205af5824579a3e587646bf4251",
247 }, {
248 name: "random key 10, blake256(0x0a), rfc6979 nonce",
249 key: "b7548540f52fe20c161a0d623097f827608c56023f50442cc00cc50ad674f6b5",
250 msg: "0a",
251 hash: "e81db4f0d76e02805155441f50c861a8f86374f3ae34c7a3ff4111d3a634ecb1",
252 nonce: "014c6f95c371ba1dd62e759229b65a7ffced18680f34789a204e1044926722ff",
253 rfc6979: true,
254 expected: "c379f1c2a35b2f9712a5573fb59c4c29dfdc54cef833dc211716248d5c7e28e1" +
255 "6e180f905cd4459551eed45b2f85b4222d21d66eb2374d9f340920b42ff9807e",
256 }}
257
258 for _, test := range tests {
259 privKey := hexToModNScalar(test.key)
260 msg := hexToBytes(test.msg)
261 hash := hexToBytes(test.hash)
262 nonce := hexToModNScalar(test.nonce)
263 wantSig := hexToBytes(test.expected)
264
265
266
267
268
269
270
271 calcHash := blake256.Sum256(msg)
272 if !bytes.Equal(calcHash[:], hash) {
273 t.Errorf("%s: mismatched test hash -- expected: %x, given: %x",
274 test.name, calcHash[:], hash)
275 continue
276 }
277 if test.rfc6979 {
278 privKeyBytes := hexToBytes(test.key)
279 nonceBytes := hexToBytes(test.nonce)
280 calcNonce := secp256k1.NonceRFC6979(privKeyBytes, hash,
281 rfc6979ExtraDataV0[:], nil, 0)
282 calcNonceBytes := calcNonce.Bytes()
283 if !bytes.Equal(calcNonceBytes[:], nonceBytes) {
284 t.Errorf("%s: mismatched test nonce -- expected: %x, given: %x",
285 test.name, calcNonceBytes, nonceBytes)
286 continue
287 }
288 }
289
290
291 gotSig, err := schnorrSign(privKey, nonce, hash)
292 if err != nil {
293 t.Errorf("%s: unexpected error when signing: %v", test.name, err)
294 continue
295 }
296
297
298 gotSigBytes := gotSig.Serialize()
299 if !bytes.Equal(gotSigBytes, wantSig) {
300 t.Errorf("%s: unexpected signature -- got %x, want %x", test.name,
301 gotSigBytes, wantSig)
302 continue
303 }
304
305
306 pubKey := secp256k1.NewPrivateKey(hexToModNScalar(test.key)).PubKey()
307 err = schnorrVerify(gotSig, hash, pubKey)
308 if err != nil {
309 t.Errorf("%s: signature failed to verify: %v", test.name, err)
310 continue
311 }
312 }
313 }
314
315
316
317
318
319 func TestSchnorrSignAndVerifyRandom(t *testing.T) {
320
321 seed := time.Now().Unix()
322 rng := rand.New(rand.NewSource(seed))
323 defer func(t *testing.T, seed int64) {
324 if t.Failed() {
325 t.Logf("random seed: %d", seed)
326 }
327 }(t, seed)
328
329 for i := 0; i < 100; i++ {
330
331 var buf [32]byte
332 if _, err := rng.Read(buf[:]); err != nil {
333 t.Fatalf("failed to read random private key: %v", err)
334 }
335 var privKeyScalar secp256k1.ModNScalar
336 privKeyScalar.SetBytes(&buf)
337 privKey := secp256k1.NewPrivateKey(&privKeyScalar)
338
339
340 var hash [32]byte
341 if _, err := rng.Read(hash[:]); err != nil {
342 t.Fatalf("failed to read random hash: %v", err)
343 }
344
345
346
347
348 sig, err := Sign(privKey, hash[:])
349 if err != nil {
350 t.Fatalf("failed to sign\nprivate key: %x\nhash: %x",
351 privKey.Serialize(), hash)
352 }
353 pubKey := privKey.PubKey()
354 if !sig.Verify(hash[:], pubKey) {
355 t.Fatalf("failed to verify signature\nsig: %x\nhash: %x\n"+
356 "private key: %x\npublic key: %x", sig.Serialize(), hash,
357 privKey.Serialize(), pubKey.SerializeCompressed())
358 }
359
360
361
362 goodSigBytes := sig.Serialize()
363 badSigBytes := make([]byte, len(goodSigBytes))
364 copy(badSigBytes, goodSigBytes)
365 randByte := rng.Intn(len(badSigBytes))
366 randBit := rng.Intn(7)
367 badSigBytes[randByte] ^= 1 << randBit
368 badSig, err := ParseSignature(badSigBytes)
369 if err != nil {
370 t.Fatalf("failed to create bad signature: %v", err)
371 }
372 if badSig.Verify(hash[:], pubKey) {
373 t.Fatalf("verified bad signature\nsig: %x\nhash: %x\n"+
374 "private key: %x\npublic key: %x", badSig.Serialize(), hash,
375 privKey.Serialize(), pubKey.SerializeCompressed())
376 }
377
378
379
380 badHash := make([]byte, len(hash))
381 copy(badHash, hash[:])
382 randByte = rng.Intn(len(badHash))
383 randBit = rng.Intn(7)
384 badHash[randByte] ^= 1 << randBit
385 if sig.Verify(badHash[:], pubKey) {
386 t.Fatalf("verified signature for bad hash\nsig: %x\nhash: %x\n"+
387 "pubkey: %x", sig.Serialize(), badHash,
388 pubKey.SerializeCompressed())
389 }
390 }
391 }
392
393
394
395
396
397 func TestVerifyErrors(t *testing.T) {
398 tests := []struct {
399 name string
400 sigR string
401 sigS string
402 hash string
403 pubX string
404 pubY string
405 err error
406 }{{
407
408
409 name: "hash too long",
410 sigR: "4c68976afe187ff0167919ad181cb30f187e2af1c8233b2cbebbbe0fc97fff61",
411 sigS: "e77c69035738000caed6ab0ce1eabe5f7e105498f84d0e8982e87ee4da21948e",
412 hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b700",
413 pubX: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
414 pubY: "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
415 err: ErrInvalidHashLen,
416 }, {
417
418
419 name: "hash too short",
420 sigR: "938de23d0785c7d4775f47bbcadaa2a56447dd98029c8196f2bbed0ab4b8457f",
421 sigS: "7de65bf205e14f81e5f75ad2fd80ea715a391f7b51e10fa43f0a1961039b1a6c",
422 hash: "0e0f08e2ee912478b77004ec62845b5e01418f03837b76cbdc8b1fb0480322",
423 pubX: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
424 pubY: "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
425 err: ErrInvalidHashLen,
426 }, {
427
428
429 name: "pubkey not on the curve, signature valid for secp256r1 instead",
430 sigR: "c6c62660176b3daa90dbf4d7e21d9406ce93895771a16c7c5c91258a9b522174",
431 sigS: "f5b5583956a6b30e18ff5e865c77a8c4adf47b147d11ea3822b4de63c9f7b909",
432 hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7",
433 pubX: "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
434 pubY: "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
435 err: ErrPubKeyNotOnCurve,
436 }, {
437
438
439
440 name: "r == field prime",
441 sigR: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
442 sigS: "e9ae2d0e306497236d4e328dc1a34244045745e87da69d806859348bc2a74525",
443 hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7",
444 pubX: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
445 pubY: "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
446 err: ErrSigRTooBig,
447 }, {
448
449
450
451 name: "r > field prime (prime + 1)",
452 sigR: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
453 sigS: "e9ae2d0e306497236d4e328dc1a34244045745e87da69d806859348bc2a74525",
454 hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7",
455 pubX: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
456 pubY: "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
457 err: ErrSigRTooBig,
458 }, {
459
460
461
462 name: "s == group order",
463 sigR: "4c68976afe187ff0167919ad181cb30f187e2af1c8233b2cbebbbe0fc97fff61",
464 sigS: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
465 hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7",
466 pubX: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
467 pubY: "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
468 err: ErrSigSTooBig,
469 }, {
470
471
472
473 name: "s > group order and still 32 bytes (order + 1)",
474 sigR: "4c68976afe187ff0167919ad181cb30f187e2af1c8233b2cbebbbe0fc97fff61",
475 sigS: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142",
476 hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7",
477 pubX: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
478 pubY: "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
479 err: ErrSigSTooBig,
480 }, {
481
482
483
484
485
486
487 name: "calculated R point at infinity",
488 sigR: "4c68976afe187ff0167919ad181cb30f187e2af1c8233b2cbebbbe0fc97fff61",
489 sigS: "14cc9e0544dd8fe6baa7c20fd2a141d0ee60114c419377efc850a49bd5c1ed36",
490 hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7",
491 pubX: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
492 pubY: "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
493 err: ErrSigRNotOnCurve,
494 }, {
495
496
497 name: "odd R",
498 sigR: "2c2c71f7bf3e183238b1f20d856e068dc6d37805c8b2d872d0f23d906bc95789",
499 sigS: "eb7670ca6ff95c1d5c6785bc72e0781f27c9778758317d82d3053fdbcc9c17b0",
500 hash: "ccf8c53a7631aad469d412963d495c729ff219dd2ae9a0c4de4bd1b4c777d49c",
501 pubX: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
502 pubY: "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
503 err: ErrSigRYIsOdd,
504 }, {
505
506
507
508 name: "mismatched R",
509 sigR: "4c68976afe187ff0167919ad181cb30f187e2af1c8233b2cbebbbe0fc97fff61",
510 sigS: "e9ae2d0e306497236d4e328dc1a34244045745e87da69d806859348bc2a74525",
511 hash: "d4f9aea8c329f57a81397f0418269a8bd495957ea56ae0af0dfa886fb5977046",
512 pubX: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
513 pubY: "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
514 err: ErrUnequalRValues,
515 }}
516
517
518
519
520
521
522 for _, test := range tests {
523
524 hash := hexToBytes(test.hash)
525 pubX, pubY := hexToFieldVal(test.pubX), hexToFieldVal(test.pubY)
526 pubKey := secp256k1.NewPublicKey(pubX, pubY)
527
528
529
530
531 sig, err := ParseSignature(hexToBytes(test.sigR + test.sigS))
532 if err != nil {
533 if !errors.Is(err, test.err) {
534 t.Errorf("%s: mismatched err -- got %v, want %v", test.name, err,
535 test.err)
536 }
537
538 continue
539 }
540
541
542 err = schnorrVerify(sig, hash, pubKey)
543 if !errors.Is(err, test.err) {
544 t.Errorf("%s: mismatched err -- got %v, want %v", test.name, err,
545 test.err)
546 continue
547 }
548 }
549 }
550
View as plain text