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 **********************************************************************/
7 #include <valgrind/memcheck.h>
8 #include "include/secp256k1.h"
9 #include "assumptions.h"
12 #if ENABLE_MODULE_ECDH
13 # include "include/secp256k1_ecdh.h"
16 #if ENABLE_MODULE_RECOVERY
17 # include "include/secp256k1_recovery.h"
21 secp256k1_context* ctx;
22 secp256k1_ecdsa_signature signature;
23 secp256k1_pubkey pubkey;
25 size_t outputlen = 33;
28 unsigned char msg[32];
29 unsigned char key[32];
30 unsigned char sig[74];
31 unsigned char spubkey[33];
32 #if ENABLE_MODULE_RECOVERY
33 secp256k1_ecdsa_recoverable_signature recoverable_signature;
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");
43 /** In theory, testing with a single secret input should be sufficient:
44 * If control flow depended on secrets the tool would generate an error.
46 for (i = 0; i < 32; i++) {
49 for (i = 0; i < 32; i++) {
53 ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_DECLASSIFY);
56 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
57 ret = secp256k1_ec_pubkey_create(ctx, &pubkey, key);
58 VALGRIND_MAKE_MEM_DEFINED(&pubkey, sizeof(secp256k1_pubkey));
59 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
61 CHECK(secp256k1_ec_pubkey_serialize(ctx, spubkey, &outputlen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);
64 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
65 ret = secp256k1_ecdsa_sign(ctx, &signature, msg, key, NULL, NULL);
66 VALGRIND_MAKE_MEM_DEFINED(&signature, sizeof(secp256k1_ecdsa_signature));
67 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
69 CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature));
71 #if ENABLE_MODULE_ECDH
73 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
74 ret = secp256k1_ecdh(ctx, msg, &pubkey, key, NULL, NULL);
75 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
79 #if ENABLE_MODULE_RECOVERY
80 /* Test signing a recoverable signature. */
81 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
82 ret = secp256k1_ecdsa_sign_recoverable(ctx, &recoverable_signature, msg, key, NULL, NULL);
83 VALGRIND_MAKE_MEM_DEFINED(&recoverable_signature, sizeof(recoverable_signature));
84 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
86 CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &recoverable_signature));
87 CHECK(recid >= 0 && recid <= 3);
90 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
91 ret = secp256k1_ec_seckey_verify(ctx, key);
92 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
95 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
96 ret = secp256k1_ec_seckey_negate(ctx, key);
97 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
100 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
101 VALGRIND_MAKE_MEM_UNDEFINED(msg, 32);
102 ret = secp256k1_ec_seckey_tweak_add(ctx, key, msg);
103 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
106 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
107 VALGRIND_MAKE_MEM_UNDEFINED(msg, 32);
108 ret = secp256k1_ec_seckey_tweak_mul(ctx, key, msg);
109 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
112 /* Test context randomisation. Do this last because it leaves the context tainted. */
113 VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
114 ret = secp256k1_context_randomize(ctx, key);
115 VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
118 secp256k1_context_destroy(ctx);