Bitcoin Core 31.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
tests_impl.h
Go to the documentation of this file.
1/***********************************************************************
2 * Copyright (c) 2013-2015 Pieter Wuille *
3 * Distributed under the MIT software license, see the accompanying *
4 * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5 ***********************************************************************/
6
7#ifndef SECP256K1_MODULE_RECOVERY_TESTS_H
8#define SECP256K1_MODULE_RECOVERY_TESTS_H
9
10#include "../../unit_test.h"
11
12static 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) {
13 (void) msg32;
14 (void) key32;
15 (void) algo16;
16 (void) data;
17
18 /* On the first run, return 0 to force a second run */
19 if (counter == 0) {
20 memset(nonce32, 0, 32);
21 return 1;
22 }
23 /* On the second run, return an overflow to force a third run */
24 if (counter == 1) {
25 memset(nonce32, 0xff, 32);
26 return 1;
27 }
28 /* On the next run, return a valid nonce, but flip a coin as to whether or not to fail signing. */
29 memset(nonce32, 1, 32);
30 return testrand_bits(1);
31}
32
34 /* Setup contexts that just count errors */
35 secp256k1_pubkey pubkey;
39 unsigned char privkey[32] = { 1 };
40 unsigned char message[32] = { 2 };
41 int recid = 0;
42 unsigned char sig[74];
43 unsigned char zero_privkey[32] = { 0 };
44 unsigned char over_privkey[32] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
45 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
46 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
47 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
48
49 /* Construct and verify corresponding public key. */
52
53 /* Check bad contexts and NULLs for signing */
59 /* This will fail or succeed randomly, and in either case will not ARG_CHECK failure */
61 /* These will all fail, but not in ARG_CHECK way */
64 /* This one will succeed. */
66
67 /* Check signing with a goofy nonce function */
68
69 /* Check bad contexts and NULLs for recovery */
74
75 /* Check NULLs for conversion */
80
81 /* Check NULLs for de/serialization */
87
92 /* overflow in signature will not result in calling illegal_callback */
93 memcpy(sig, over_privkey, 32);
95}
96
98 unsigned char extra[32] = {0x00};
99 unsigned char privkey[32];
100 unsigned char message[32];
103 unsigned char sig[74];
104 secp256k1_pubkey pubkey;
106 int recid = 0;
107
108 /* Generate a random key and message. */
109 {
110 secp256k1_scalar msg, key;
114 secp256k1_scalar_get_b32(message, &msg);
115 }
116
117 /* Construct and verify corresponding public key. */
120
121 /* Serialize/parse compact and verify/recover. */
122 extra[0] = 0;
124 CHECK(secp256k1_ecdsa_sign(CTX, &signature[0], message, privkey, NULL, NULL) == 1);
127 extra[31] = 1;
129 extra[31] = 0;
130 extra[0] = 1;
134 CHECK(secp256k1_memcmp_var(&signature[4], &signature[0], 64) == 0);
135 CHECK(secp256k1_ecdsa_verify(CTX, &signature[4], message, &pubkey) == 1);
136 memset(&rsignature[4], 0, sizeof(rsignature[4]));
139 CHECK(secp256k1_ecdsa_verify(CTX, &signature[4], message, &pubkey) == 1);
140 /* Parse compact (with recovery id) and recover. */
143 CHECK(secp256k1_memcmp_var(&pubkey, &recpubkey, sizeof(pubkey)) == 0);
144 /* Serialize/destroy/parse signature and verify again. */
146 sig[testrand_bits(6)] += 1 + testrand_int(255);
149 CHECK(secp256k1_ecdsa_verify(CTX, &signature[4], message, &pubkey) == 0);
150 /* Recover again */
151 CHECK(secp256k1_ecdsa_recover(CTX, &recpubkey, &rsignature[4], message) == 0 ||
152 secp256k1_memcmp_var(&pubkey, &recpubkey, sizeof(pubkey)) != 0);
153}
154
155/* Tests several edge cases. */
157 const unsigned char msg32[32] = {
158 'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
159 'a', ' ', 'v', 'e', 'r', 'y', ' ', 's',
160 'e', 'c', 'r', 'e', 't', ' ', 'm', 'e',
161 's', 's', 'a', 'g', 'e', '.', '.', '.'
162 };
163 const unsigned char sig64[64] = {
164 /* Generated by signing the above message with nonce 'This is the nonce we will use...'
165 * and secret key 0 (which is not valid), resulting in recid 1. */
166 0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8,
167 0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96,
168 0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63,
169 0x17, 0x9A, 0x7D, 0xD1, 0x7B, 0xD2, 0x35, 0x32,
170 0x4B, 0x1B, 0x7D, 0xF3, 0x4C, 0xE1, 0xF6, 0x8E,
171 0x69, 0x4F, 0xF6, 0xF1, 0x1A, 0xC7, 0x51, 0xDD,
172 0x7D, 0xD7, 0x3E, 0x38, 0x7E, 0xE4, 0xFC, 0x86,
173 0x6E, 0x1B, 0xE8, 0xEC, 0xC7, 0xDD, 0x95, 0x57
174 };
175 secp256k1_pubkey pubkey;
176 /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */
177 const unsigned char sigb64[64] = {
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
186 };
190 int recid;
191
200
201 for (recid = 0; recid < 4; recid++) {
202 int i;
203 int recid2;
204 /* (4,4) encoded in DER. */
205 unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04};
206 unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01};
207 unsigned char sigcder_zs[7] = {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x00};
208 unsigned char sigbderalt1[39] = {
209 0x30, 0x25, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04,
214 };
215 unsigned char sigbderalt2[39] = {
216 0x30, 0x25, 0x02, 0x01, 0x04, 0x02, 0x20, 0x00,
217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
221 };
222 unsigned char sigbderalt3[40] = {
223 0x30, 0x26, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00,
224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04,
228 };
229 unsigned char sigbderalt4[40] = {
230 0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 0x00,
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 };
236 /* (order + r,4) encoded in DER. */
237 unsigned char sigbderlong[40] = {
238 0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF,
239 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
240 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC,
241 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E,
242 0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04
243 };
248 for (recid2 = 0; recid2 < 4; recid2++) {
252 /* Verifying with (order + r,4) should always fail. */
255 }
256 /* DER parsing tests. */
257 /* Zero length r/s. */
260 /* Leading zeros. */
265 sigbderalt3[4] = 1;
268 sigbderalt4[7] = 1;
271 /* Damage signature. */
272 sigbder[7]++;
275 sigbder[7]--;
278 for(i = 0; i < 8; i++) {
279 int c;
280 unsigned char orig = sigbder[i];
281 /*Try every single-byte change.*/
282 for (c = 0; c < 256; c++) {
283 if (c == orig ) {
284 continue;
285 }
286 sigbder[i] = c;
288 }
289 sigbder[i] = orig;
290 }
291 }
292
293 /* Test r/s equal to zero */
294 {
295 /* (1,1) encoded in DER. */
296 unsigned char sigcder[8] = {0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01};
297 unsigned char sigc64[64] = {
298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
306 };
312 sigcder[4] = 0;
313 sigc64[31] = 0;
318 sigcder[4] = 1;
319 sigcder[7] = 0;
320 sigc64[31] = 1;
321 sigc64[63] = 0;
326 }
327}
328
329/* --- Test registry --- */
332
338
339#endif /* SECP256K1_MODULE_RECOVERY_TESTS_H */
#define CHECK(cond)
Unconditional failure on condition failure.
Definition util.h:35
static void test_ecdsa_recovery_end_to_end_internal(void)
Definition tests_impl.h:97
static void test_ecdsa_recovery_api_internal(void)
Definition tests_impl.h:33
static const struct tf_test_entry tests_recovery[]
Definition tests_impl.h:333
static void test_ecdsa_recovery_edge_cases(void)
Definition tests_impl.h:156
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)
Definition tests_impl.h:12
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar *a)
Convert a scalar to a byte array.
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
Definition util.h:269
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(const secp256k1_context *ctx, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
Verify an elliptic curve secret key.
Definition secp256k1.c:588
SECP256K1_API int secp256k1_ecdsa_sign(const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, const unsigned char *msghash32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void *ndata) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Create an ECDSA signature.
Definition secp256k1.c:574
SECP256K1_API int secp256k1_ecdsa_signature_parse_der(const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, const unsigned char *input, size_t inputlen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a DER ECDSA signature.
Definition secp256k1.c:377
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compute the public key for a secret key.
Definition secp256k1.c:612
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(const secp256k1_context *ctx, const secp256k1_ecdsa_signature *sig, const unsigned char *msghash32, const secp256k1_pubkey *pubkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Verify an ECDSA signature.
Definition secp256k1.c:458
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact(const secp256k1_context *ctx, unsigned char *output64, int *recid, const secp256k1_ecdsa_recoverable_signature *sig) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Serialize an ECDSA signature in compact format (64 bytes + recovery id).
Definition main_impl.h:60
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context *ctx, secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *input64, int recid) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a compact ECDSA signature (64 bytes + recovery id).
Definition main_impl.h:38
SECP256K1_API int secp256k1_ecdsa_sign_recoverable(const secp256k1_context *ctx, secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *msghash32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void *ndata) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Create a recoverable ECDSA signature.
Definition main_impl.h:123
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, const secp256k1_ecdsa_recoverable_signature *sigin) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Convert a recoverable signature into a normal signature.
Definition main_impl.h:74
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *msghash32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Recover an ECDSA public key from a signature.
Definition main_impl.h:137
Opaque data structure that holds a parsed ECDSA signature, supporting pubkey recovery.
Opaque data structure that holds a parsed ECDSA signature.
Definition secp256k1.h:74
Opaque data structure that holds a parsed and valid public key.
Definition secp256k1.h:61
A scalar modulo the group order of the secp256k1 curve.
Definition scalar_4x64.h:13
Definition unit_test.h:51
static SECP256K1_INLINE uint64_t testrand_bits(int bits)
Generate a pseudorandom number in the range [0..2**bits-1].
static uint32_t testrand_int(uint32_t range)
Generate a pseudorandom number in the range [0..range-1].
#define CHECK_ILLEGAL(ctx, expr)
Definition tests.c:79
static secp256k1_context * CTX
Definition tests.c:42
static secp256k1_context * STATIC_CTX
Definition tests.c:43
static void testutil_random_scalar_order_test(secp256k1_scalar *num)
Definition testutil.h:120
#define REPEAT_TEST_MULT(fn, multiplier)
Definition unit_test.h:35
#define CASE1(name)
Definition unit_test.h:25
#define REPEAT_TEST(fn)
Definition unit_test.h:34
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
Definition time.h:73