1 /**********************************************************************
2  * Copyright (c) 2013-2015 Pieter Wuille                              *
3  * Distributed under the MIT software license, see the accompanying   *
4  * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
5  **********************************************************************/
6 
7 #ifndef SECP256K1_MODULE_RECOVERY_TESTS_H
8 #define SECP256K1_MODULE_RECOVERY_TESTS_H
9 
recovery_test_nonce_function(unsigned char * nonce32,const unsigned char * msg32,const unsigned char * key32,const unsigned char * algo16,void * data,unsigned int counter)10 static int recovery_test_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) {
11     (void) msg32;
12     (void) key32;
13     (void) algo16;
14     (void) data;
15 
16     /* On the first run, return 0 to force a second run */
17     if (counter == 0) {
18         memset(nonce32, 0, 32);
19         return 1;
20     }
21     /* On the second run, return an overflow to force a third run */
22     if (counter == 1) {
23         memset(nonce32, 0xff, 32);
24         return 1;
25     }
26     /* On the next run, return a valid nonce, but flip a coin as to whether or not to fail signing. */
27     memset(nonce32, 1, 32);
28     return secp256k1_rand_bits(1);
29 }
30 
test_ecdsa_recovery_api(void)31 void test_ecdsa_recovery_api(void) {
32     /* Setup contexts that just count errors */
33     secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
34     secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
35     secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
36     secp256k1_context *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
37     secp256k1_pubkey pubkey;
38     secp256k1_pubkey recpubkey;
39     secp256k1_ecdsa_signature normal_sig;
40     secp256k1_ecdsa_recoverable_signature recsig;
41     unsigned char privkey[32] = { 1 };
42     unsigned char message[32] = { 2 };
43     int32_t ecount = 0;
44     int recid = 0;
45     unsigned char sig[74];
46     unsigned char zero_privkey[32] = { 0 };
47     unsigned char over_privkey[32] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
48                                        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
49                                        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
50                                        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
51 
52     secp256k1_context_set_error_callback(none, counting_illegal_callback_fn, &ecount);
53     secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, &ecount);
54     secp256k1_context_set_error_callback(vrfy, counting_illegal_callback_fn, &ecount);
55     secp256k1_context_set_error_callback(both, counting_illegal_callback_fn, &ecount);
56     secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount);
57     secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount);
58     secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount);
59     secp256k1_context_set_illegal_callback(both, counting_illegal_callback_fn, &ecount);
60 
61     /* Construct and verify corresponding public key. */
62     CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1);
63     CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1);
64 
65     /* Check bad contexts and NULLs for signing */
66     ecount = 0;
67     CHECK(secp256k1_ecdsa_sign_recoverable(none, &recsig, message, privkey, NULL, NULL) == 0);
68     CHECK(ecount == 1);
69     CHECK(secp256k1_ecdsa_sign_recoverable(sign, &recsig, message, privkey, NULL, NULL) == 1);
70     CHECK(ecount == 1);
71     CHECK(secp256k1_ecdsa_sign_recoverable(vrfy, &recsig, message, privkey, NULL, NULL) == 0);
72     CHECK(ecount == 2);
73     CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, NULL, NULL) == 1);
74     CHECK(ecount == 2);
75     CHECK(secp256k1_ecdsa_sign_recoverable(both, NULL, message, privkey, NULL, NULL) == 0);
76     CHECK(ecount == 3);
77     CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, NULL, privkey, NULL, NULL) == 0);
78     CHECK(ecount == 4);
79     CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, NULL, NULL, NULL) == 0);
80     CHECK(ecount == 5);
81     /* This will fail or succeed randomly, and in either case will not ARG_CHECK failure */
82     secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, recovery_test_nonce_function, NULL);
83     CHECK(ecount == 5);
84     /* These will all fail, but not in ARG_CHECK way */
85     CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, zero_privkey, NULL, NULL) == 0);
86     CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, over_privkey, NULL, NULL) == 0);
87     /* This one will succeed. */
88     CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, NULL, NULL) == 1);
89     CHECK(ecount == 5);
90 
91     /* Check signing with a goofy nonce function */
92 
93     /* Check bad contexts and NULLs for recovery */
94     ecount = 0;
95     CHECK(secp256k1_ecdsa_recover(none, &recpubkey, &recsig, message) == 0);
96     CHECK(ecount == 1);
97     CHECK(secp256k1_ecdsa_recover(sign, &recpubkey, &recsig, message) == 0);
98     CHECK(ecount == 2);
99     CHECK(secp256k1_ecdsa_recover(vrfy, &recpubkey, &recsig, message) == 1);
100     CHECK(ecount == 2);
101     CHECK(secp256k1_ecdsa_recover(both, &recpubkey, &recsig, message) == 1);
102     CHECK(ecount == 2);
103     CHECK(secp256k1_ecdsa_recover(both, NULL, &recsig, message) == 0);
104     CHECK(ecount == 3);
105     CHECK(secp256k1_ecdsa_recover(both, &recpubkey, NULL, message) == 0);
106     CHECK(ecount == 4);
107     CHECK(secp256k1_ecdsa_recover(both, &recpubkey, &recsig, NULL) == 0);
108     CHECK(ecount == 5);
109 
110     /* Check NULLs for conversion */
111     CHECK(secp256k1_ecdsa_sign(both, &normal_sig, message, privkey, NULL, NULL) == 1);
112     ecount = 0;
113     CHECK(secp256k1_ecdsa_recoverable_signature_convert(both, NULL, &recsig) == 0);
114     CHECK(ecount == 1);
115     CHECK(secp256k1_ecdsa_recoverable_signature_convert(both, &normal_sig, NULL) == 0);
116     CHECK(ecount == 2);
117     CHECK(secp256k1_ecdsa_recoverable_signature_convert(both, &normal_sig, &recsig) == 1);
118 
119     /* Check NULLs for de/serialization */
120     CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, NULL, NULL) == 1);
121     ecount = 0;
122     CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, NULL, &recid, &recsig) == 0);
123     CHECK(ecount == 1);
124     CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, sig, NULL, &recsig) == 0);
125     CHECK(ecount == 2);
126     CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, sig, &recid, NULL) == 0);
127     CHECK(ecount == 3);
128     CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, sig, &recid, &recsig) == 1);
129 
130     CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, NULL, sig, recid) == 0);
131     CHECK(ecount == 4);
132     CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, NULL, recid) == 0);
133     CHECK(ecount == 5);
134     CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, sig, -1) == 0);
135     CHECK(ecount == 6);
136     CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, sig, 5) == 0);
137     CHECK(ecount == 7);
138     /* overflow in signature will fail but not affect ecount */
139     memcpy(sig, over_privkey, 32);
140     CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, sig, recid) == 0);
141     CHECK(ecount == 7);
142 
143     /* cleanup */
144     secp256k1_context_destroy(none);
145     secp256k1_context_destroy(sign);
146     secp256k1_context_destroy(vrfy);
147     secp256k1_context_destroy(both);
148 }
149 
test_ecdsa_recovery_end_to_end(void)150 void test_ecdsa_recovery_end_to_end(void) {
151     unsigned char extra[32] = {0x00};
152     unsigned char privkey[32];
153     unsigned char message[32];
154     secp256k1_ecdsa_signature signature[5];
155     secp256k1_ecdsa_recoverable_signature rsignature[5];
156     unsigned char sig[74];
157     secp256k1_pubkey pubkey;
158     secp256k1_pubkey recpubkey;
159     int recid = 0;
160 
161     /* Generate a random key and message. */
162     {
163         secp256k1_scalar msg, key;
164         random_scalar_order_test(&msg);
165         random_scalar_order_test(&key);
166         secp256k1_scalar_get_b32(privkey, &key);
167         secp256k1_scalar_get_b32(message, &msg);
168     }
169 
170     /* Construct and verify corresponding public key. */
171     CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1);
172     CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1);
173 
174     /* Serialize/parse compact and verify/recover. */
175     extra[0] = 0;
176     CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[0], message, privkey, NULL, NULL) == 1);
177     CHECK(secp256k1_ecdsa_sign(ctx, &signature[0], message, privkey, NULL, NULL) == 1);
178     CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[4], message, privkey, NULL, NULL) == 1);
179     CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[1], message, privkey, NULL, extra) == 1);
180     extra[31] = 1;
181     CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[2], message, privkey, NULL, extra) == 1);
182     extra[31] = 0;
183     extra[0] = 1;
184     CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[3], message, privkey, NULL, extra) == 1);
185     CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1);
186     CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1);
187     CHECK(memcmp(&signature[4], &signature[0], 64) == 0);
188     CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1);
189     memset(&rsignature[4], 0, sizeof(rsignature[4]));
190     CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1);
191     CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1);
192     CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1);
193     /* Parse compact (with recovery id) and recover. */
194     CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1);
195     CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 1);
196     CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0);
197     /* Serialize/destroy/parse signature and verify again. */
198     CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1);
199     sig[secp256k1_rand_bits(6)] += 1 + secp256k1_rand_int(255);
200     CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1);
201     CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1);
202     CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 0);
203     /* Recover again */
204     CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 0 ||
205           memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0);
206 }
207 
208 /* Tests several edge cases. */
test_ecdsa_recovery_edge_cases(void)209 void test_ecdsa_recovery_edge_cases(void) {
210     const unsigned char msg32[32] = {
211         'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
212         'a', ' ', 'v', 'e', 'r', 'y', ' ', 's',
213         'e', 'c', 'r', 'e', 't', ' ', 'm', 'e',
214         's', 's', 'a', 'g', 'e', '.', '.', '.'
215     };
216     const unsigned char sig64[64] = {
217         /* Generated by signing the above message with nonce 'This is the nonce we will use...'
218          * and secret key 0 (which is not valid), resulting in recid 0. */
219         0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8,
220         0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96,
221         0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63,
222         0x17, 0x9A, 0x7D, 0xD1, 0x7B, 0xD2, 0x35, 0x32,
223         0x4B, 0x1B, 0x7D, 0xF3, 0x4C, 0xE1, 0xF6, 0x8E,
224         0x69, 0x4F, 0xF6, 0xF1, 0x1A, 0xC7, 0x51, 0xDD,
225         0x7D, 0xD7, 0x3E, 0x38, 0x7E, 0xE4, 0xFC, 0x86,
226         0x6E, 0x1B, 0xE8, 0xEC, 0xC7, 0xDD, 0x95, 0x57
227     };
228     secp256k1_pubkey pubkey;
229     /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */
230     const unsigned char sigb64[64] = {
231         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
234         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
235         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
239     };
240     secp256k1_pubkey pubkeyb;
241     secp256k1_ecdsa_recoverable_signature rsig;
242     secp256k1_ecdsa_signature sig;
243     int recid;
244 
245     CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 0));
246     CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32));
247     CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 1));
248     CHECK(secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32));
249     CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 2));
250     CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32));
251     CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 3));
252     CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32));
253 
254     for (recid = 0; recid < 4; recid++) {
255         int i;
256         int recid2;
257         /* (4,4) encoded in DER. */
258         unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04};
259         unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01};
260         unsigned char sigcder_zs[7] = {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x00};
261         unsigned char sigbderalt1[39] = {
262             0x30, 0x25, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
263             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
264             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
265             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
266             0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04,
267         };
268         unsigned char sigbderalt2[39] = {
269             0x30, 0x25, 0x02, 0x01, 0x04, 0x02, 0x20, 0x00,
270             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
272             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
274         };
275         unsigned char sigbderalt3[40] = {
276             0x30, 0x26, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00,
277             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
278             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
280             0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04,
281         };
282         unsigned char sigbderalt4[40] = {
283             0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 0x00,
284             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
286             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
288         };
289         /* (order + r,4) encoded in DER. */
290         unsigned char sigbderlong[40] = {
291             0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF,
292             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
293             0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC,
294             0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E,
295             0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04
296         };
297         CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid) == 1);
298         CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 1);
299         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1);
300         CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1);
301         for (recid2 = 0; recid2 < 4; recid2++) {
302             secp256k1_pubkey pubkey2b;
303             CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid2) == 1);
304             CHECK(secp256k1_ecdsa_recover(ctx, &pubkey2b, &rsig, msg32) == 1);
305             /* Verifying with (order + r,4) should always fail. */
306             CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderlong, sizeof(sigbderlong)) == 1);
307             CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0);
308         }
309         /* DER parsing tests. */
310         /* Zero length r/s. */
311         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zr, sizeof(sigcder_zr)) == 0);
312         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zs, sizeof(sigcder_zs)) == 0);
313         /* Leading zeros. */
314         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt1, sizeof(sigbderalt1)) == 0);
315         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt2, sizeof(sigbderalt2)) == 0);
316         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 0);
317         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 0);
318         sigbderalt3[4] = 1;
319         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 1);
320         CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0);
321         sigbderalt4[7] = 1;
322         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 1);
323         CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0);
324         /* Damage signature. */
325         sigbder[7]++;
326         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1);
327         CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0);
328         sigbder[7]--;
329         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, 6) == 0);
330         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder) - 1) == 0);
331         for(i = 0; i < 8; i++) {
332             int c;
333             unsigned char orig = sigbder[i];
334             /*Try every single-byte change.*/
335             for (c = 0; c < 256; c++) {
336                 if (c == orig ) {
337                     continue;
338                 }
339                 sigbder[i] = c;
340                 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 0 || secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0);
341             }
342             sigbder[i] = orig;
343         }
344     }
345 
346     /* Test r/s equal to zero */
347     {
348         /* (1,1) encoded in DER. */
349         unsigned char sigcder[8] = {0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01};
350         unsigned char sigc64[64] = {
351             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
355             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
359         };
360         secp256k1_pubkey pubkeyc;
361         CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1);
362         CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyc, &rsig, msg32) == 1);
363         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1);
364         CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 1);
365         sigcder[4] = 0;
366         sigc64[31] = 0;
367         CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1);
368         CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0);
369         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1);
370         CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0);
371         sigcder[4] = 1;
372         sigcder[7] = 0;
373         sigc64[31] = 1;
374         sigc64[63] = 0;
375         CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1);
376         CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0);
377         CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1);
378         CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0);
379     }
380 }
381 
run_recovery_tests(void)382 void run_recovery_tests(void) {
383     int i;
384     for (i = 0; i < count; i++) {
385         test_ecdsa_recovery_api();
386     }
387     for (i = 0; i < 64*count; i++) {
388         test_ecdsa_recovery_end_to_end();
389     }
390     test_ecdsa_recovery_edge_cases();
391 }
392 
393 #endif /* SECP256K1_MODULE_RECOVERY_TESTS_H */
394