Bitcoin Core  0.20.99
P2P Digital Currency
valgrind_ctime_test.c
Go to the documentation of this file.
1 /**********************************************************************
2  * Copyright (c) 2020 Gregory Maxwell *
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 #include <valgrind/memcheck.h>
8 #include "include/secp256k1.h"
9 #include "assumptions.h"
10 #include "util.h"
11 
12 #ifdef ENABLE_MODULE_ECDH
13 # include "include/secp256k1_ecdh.h"
14 #endif
15 
16 #ifdef ENABLE_MODULE_RECOVERY
18 #endif
19 
20 #ifdef ENABLE_MODULE_EXTRAKEYS
22 #endif
23 
24 #ifdef ENABLE_MODULE_SCHNORRSIG
26 #endif
27 
28 int main(void) {
30  secp256k1_ecdsa_signature signature;
31  secp256k1_pubkey pubkey;
32  size_t siglen = 74;
33  size_t outputlen = 33;
34  int i;
35  int ret;
36  unsigned char msg[32];
37  unsigned char key[32];
38  unsigned char sig[74];
39  unsigned char spubkey[33];
40 #ifdef ENABLE_MODULE_RECOVERY
41  secp256k1_ecdsa_recoverable_signature recoverable_signature;
42  int recid;
43 #endif
44 #ifdef ENABLE_MODULE_EXTRAKEYS
45  secp256k1_keypair keypair;
46 #endif
47 
48  if (!RUNNING_ON_VALGRIND) {
49  fprintf(stderr, "This test can only usefully be run inside valgrind.\n");
50  fprintf(stderr, "Usage: libtool --mode=execute valgrind ./valgrind_ctime_test\n");
51  exit(1);
52  }
53 
57  for (i = 0; i < 32; i++) {
58  key[i] = i + 65;
59  }
60  for (i = 0; i < 32; i++) {
61  msg[i] = i + 1;
62  }
63 
67 
68  /* Test keygen. */
69  VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
70  ret = secp256k1_ec_pubkey_create(ctx, &pubkey, key);
71  VALGRIND_MAKE_MEM_DEFINED(&pubkey, sizeof(secp256k1_pubkey));
72  VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
73  CHECK(ret);
74  CHECK(secp256k1_ec_pubkey_serialize(ctx, spubkey, &outputlen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);
75 
76  /* Test signing. */
77  VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
78  ret = secp256k1_ecdsa_sign(ctx, &signature, msg, key, NULL, NULL);
79  VALGRIND_MAKE_MEM_DEFINED(&signature, sizeof(secp256k1_ecdsa_signature));
80  VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
81  CHECK(ret);
82  CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature));
83 
84 #ifdef ENABLE_MODULE_ECDH
85  /* Test ECDH. */
86  VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
87  ret = secp256k1_ecdh(ctx, msg, &pubkey, key, NULL, NULL);
88  VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
89  CHECK(ret == 1);
90 #endif
91 
92 #ifdef ENABLE_MODULE_RECOVERY
93  /* Test signing a recoverable signature. */
94  VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
95  ret = secp256k1_ecdsa_sign_recoverable(ctx, &recoverable_signature, msg, key, NULL, NULL);
96  VALGRIND_MAKE_MEM_DEFINED(&recoverable_signature, sizeof(recoverable_signature));
97  VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
98  CHECK(ret);
99  CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &recoverable_signature));
100  CHECK(recid >= 0 && recid <= 3);
101 #endif
102 
103  VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
104  ret = secp256k1_ec_seckey_verify(ctx, key);
105  VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
106  CHECK(ret == 1);
107 
108  VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
109  ret = secp256k1_ec_seckey_negate(ctx, key);
110  VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
111  CHECK(ret == 1);
112 
113  VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
114  VALGRIND_MAKE_MEM_UNDEFINED(msg, 32);
115  ret = secp256k1_ec_seckey_tweak_add(ctx, key, msg);
116  VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
117  CHECK(ret == 1);
118 
119  VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
120  VALGRIND_MAKE_MEM_UNDEFINED(msg, 32);
121  ret = secp256k1_ec_seckey_tweak_mul(ctx, key, msg);
122  VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
123  CHECK(ret == 1);
124 
125  /* Test context randomisation. Do this last because it leaves the context tainted. */
126  VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
127  ret = secp256k1_context_randomize(ctx, key);
128  VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
129  CHECK(ret);
130 
131  /* Test keypair_create and keypair_xonly_tweak_add. */
132 #ifdef ENABLE_MODULE_EXTRAKEYS
133  VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
134  ret = secp256k1_keypair_create(ctx, &keypair, key);
135  VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
136  CHECK(ret == 1);
137 
138  /* The tweak is not treated as a secret in keypair_tweak_add */
139  VALGRIND_MAKE_MEM_DEFINED(msg, 32);
140  ret = secp256k1_keypair_xonly_tweak_add(ctx, &keypair, msg);
141  VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
142  CHECK(ret == 1);
143 #endif
144 
145 #ifdef ENABLE_MODULE_SCHNORRSIG
146  VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
147  ret = secp256k1_keypair_create(ctx, &keypair, key);
148  VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
149  CHECK(ret == 1);
150  ret = secp256k1_schnorrsig_sign(ctx, sig, msg, &keypair, NULL, NULL);
151  VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
152  CHECK(ret == 1);
153 #endif
154 
156  return 0;
157 }
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(secp256k1_context *ctx, const unsigned char *seed32) SECP256K1_ARG_NONNULL(1)
Updates the context randomization to protect against side-channel leakage.
Definition: secp256k1.c:728
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(const secp256k1_context *ctx, secp256k1_keypair *keypair, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compute the keypair for a secret key.
Definition: main_impl.h:171
int main(void)
Opaque data structured that holds a parsed ECDSA signature, supporting pubkey recovery.
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_negate(const secp256k1_context *ctx, unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
Negates a secret key in place.
Definition: secp256k1.c:589
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add(const secp256k1_context *ctx, secp256k1_keypair *keypair, const unsigned char *tweak32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Tweak a keypair by adding tweak32 to the secret key and updating the public key accordingly.
Definition: main_impl.h:220
SECP256K1_API int secp256k1_ec_pubkey_serialize(const secp256k1_context *ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey *pubkey, unsigned int flags) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Serialize a pubkey object into a serialized byte sequence.
Definition: secp256k1.c:295
#define SECP256K1_CONTEXT_SIGN
Definition: secp256k1.h:171
SECP256K1_API void secp256k1_context_destroy(secp256k1_context *ctx)
Destroy a secp256k1 context object (created in dynamically allocated memory).
Definition: secp256k1.c:195
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:571
#define SECP256K1_EC_COMPRESSED
Flag to pass to secp256k1_ec_pubkey_serialize.
Definition: secp256k1.h:176
#define SECP256K1_CONTEXT_DECLASSIFY
Definition: secp256k1.h:172
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 ECDSA secret key.
Definition: secp256k1.c:548
static secp256k1_context * ctx
Definition: tests.c:36
SECP256K1_API int secp256k1_ecdsa_sign(const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, const unsigned char *msg32, 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:534
SECP256K1_API int secp256k1_ecdsa_sign_recoverable(const secp256k1_context *ctx, secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *msg32, 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
Opaque data structured that holds a parsed ECDSA signature.
Definition: secp256k1.h:80
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
#define CHECK(cond)
Definition: util.h:53
Opaque data structure that holds a keypair consisting of a secret and a public key.
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_mul(const secp256k1_context *ctx, unsigned char *seckey, const unsigned char *tweak) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Tweak a secret key by multiplying it by a tweak.
Definition: secp256k1.c:680
#define SECP256K1_CONTEXT_VERIFY
Flags to pass to secp256k1_context_create, secp256k1_context_preallocated_size, and secp256k1_context...
Definition: secp256k1.h:170
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(const secp256k1_context *ctx, unsigned char *output, const secp256k1_pubkey *pubkey, const unsigned char *seckey, secp256k1_ecdh_hash_function hashfp, void *data) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Compute an EC Diffie-Hellman secret in constant time.
Definition: main_impl.h:29
SECP256K1_API int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context *ctx, unsigned char *output, size_t *outputlen, const secp256k1_ecdsa_signature *sig) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Serialize an ECDSA signature in DER format.
Definition: secp256k1.c:379
SECP256K1_API int secp256k1_schnorrsig_sign(const secp256k1_context *ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, secp256k1_nonce_function_hardened noncefp, void *ndata) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Create a Schnorr signature.
Definition: main_impl.h:127
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add(const secp256k1_context *ctx, unsigned char *seckey, const unsigned char *tweak) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Tweak a secret key by adding tweak to it.
Definition: secp256k1.c:635
SECP256K1_API secp256k1_context * secp256k1_context_create(unsigned int flags) SECP256K1_WARN_UNUSED_RESULT
Create a secp256k1 context object (in dynamically allocated memory).
Definition: secp256k1.c:151
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1.h:67