1 /***********************************************************************
2 * Copyright (c) 2020 Gregory Maxwell *
3 * Distributed under the MIT software license, see the accompanying *
4 * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5 ***********************************************************************/
7 #include <valgrind/memcheck.h>
10 #include "include/secp256k1.h"
11 #include "assumptions.h"
14 #ifdef ENABLE_MODULE_ECDH
15 # include "include/secp256k1_ecdh.h"
18 #ifdef ENABLE_MODULE_RECOVERY
19 # include "include/secp256k1_recovery.h"
22 #ifdef ENABLE_MODULE_EXTRAKEYS
23 # include "include/secp256k1_extrakeys.h"
26 #ifdef ENABLE_MODULE_SCHNORRSIG
27 #include "include/secp256k1_schnorrsig.h"
30 void run_tests(secp256k1_context *ctx, unsigned char *key);
33 secp256k1_context* ctx;
34 unsigned char key[32];
37 if (!RUNNING_ON_VALGRIND) {
38 fprintf(stderr, "This test can only usefully be run inside valgrind.\n");
39 fprintf(stderr, "Usage: libtool --mode=execute valgrind ./valgrind_ctime_test\n");
42 ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN
43 | SECP256K1_CONTEXT_VERIFY
44 | SECP256K1_CONTEXT_DECLASSIFY);
45 /** In theory, testing with a single secret input should be sufficient:
46 * If control flow depended on secrets the tool would generate an error.
48 for (i = 0; i < 32; i++) {
54 /* Test context randomisation. Do this last because it leaves the context
56 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
57 ret = secp256k1_context_randomize(ctx, key);
58 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
61 secp256k1_context_destroy(ctx);
65 void run_tests(secp256k1_context *ctx, unsigned char *key) {
66 secp256k1_ecdsa_signature signature;
67 secp256k1_pubkey pubkey;
69 size_t outputlen = 33;
72 unsigned char msg[32];
73 unsigned char sig[74];
74 unsigned char spubkey[33];
75 #ifdef ENABLE_MODULE_RECOVERY
76 secp256k1_ecdsa_recoverable_signature recoverable_signature;
79 #ifdef ENABLE_MODULE_EXTRAKEYS
80 secp256k1_keypair keypair;
83 for (i = 0; i < 32; i++) {
88 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
89 ret = secp256k1_ec_pubkey_create(ctx, &pubkey, key);
90 VALGRIND_MAKE_MEM_DEFINED(&pubkey, sizeof(secp256k1_pubkey));
91 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
93 CHECK(secp256k1_ec_pubkey_serialize(ctx, spubkey, &outputlen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);
96 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
97 ret = secp256k1_ecdsa_sign(ctx, &signature, msg, key, NULL, NULL);
98 VALGRIND_MAKE_MEM_DEFINED(&signature, sizeof(secp256k1_ecdsa_signature));
99 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
101 CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature));
103 #ifdef ENABLE_MODULE_ECDH
105 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
106 ret = secp256k1_ecdh(ctx, msg, &pubkey, key, NULL, NULL);
107 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
111 #ifdef ENABLE_MODULE_RECOVERY
112 /* Test signing a recoverable signature. */
113 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
114 ret = secp256k1_ecdsa_sign_recoverable(ctx, &recoverable_signature, msg, key, NULL, NULL);
115 VALGRIND_MAKE_MEM_DEFINED(&recoverable_signature, sizeof(recoverable_signature));
116 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
118 CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &recoverable_signature));
119 CHECK(recid >= 0 && recid <= 3);
122 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
123 ret = secp256k1_ec_seckey_verify(ctx, key);
124 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
127 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
128 ret = secp256k1_ec_seckey_negate(ctx, key);
129 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
132 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
133 VALGRIND_MAKE_MEM_UNDEFINED(msg, 32);
134 ret = secp256k1_ec_seckey_tweak_add(ctx, key, msg);
135 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
138 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
139 VALGRIND_MAKE_MEM_UNDEFINED(msg, 32);
140 ret = secp256k1_ec_seckey_tweak_mul(ctx, key, msg);
141 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
144 /* Test keypair_create and keypair_xonly_tweak_add. */
145 #ifdef ENABLE_MODULE_EXTRAKEYS
146 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
147 ret = secp256k1_keypair_create(ctx, &keypair, key);
148 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
151 /* The tweak is not treated as a secret in keypair_tweak_add */
152 VALGRIND_MAKE_MEM_DEFINED(msg, 32);
153 ret = secp256k1_keypair_xonly_tweak_add(ctx, &keypair, msg);
154 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
157 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
158 VALGRIND_MAKE_MEM_UNDEFINED(&keypair, sizeof(keypair));
159 ret = secp256k1_keypair_sec(ctx, key, &keypair);
160 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
164 #ifdef ENABLE_MODULE_SCHNORRSIG
165 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
166 ret = secp256k1_keypair_create(ctx, &keypair, key);
167 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
169 ret = secp256k1_schnorrsig_sign(ctx, sig, msg, &keypair, NULL, NULL);
170 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));