]> Git Repo - secp256k1.git/blob - src/valgrind_ctime_test.c
Constant-time behaviour test using valgrind memtest.
[secp256k1.git] / src / valgrind_ctime_test.c
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 "util.h"
10
11 #if ENABLE_MODULE_ECDH
12 # include "include/secp256k1_ecdh.h"
13 #endif
14
15 int main(void) {
16     secp256k1_context* ctx;
17     secp256k1_ecdsa_signature signature;
18     secp256k1_pubkey pubkey;
19     size_t siglen = 74;
20     size_t outputlen = 33;
21     int i;
22     int ret;
23     unsigned char msg[32];
24     unsigned char key[32];
25     unsigned char sig[74];
26     unsigned char spubkey[33];
27
28     if (!RUNNING_ON_VALGRIND) {
29         fprintf(stderr, "This test can only usefully be run inside valgrind.\n");
30         fprintf(stderr, "Usage: libtool --mode=execute valgrind ./valgrind_ctime_test\n");
31         exit(1);
32     }
33
34     /** In theory, testing with a single secret input should be sufficient:
35      *  If control flow depended on secrets the tool would generate an error.
36      */
37     for (i = 0; i < 32; i++) {
38         key[i] = i + 65;
39     }
40     for (i = 0; i < 32; i++) {
41         msg[i] = i + 1;
42     }
43
44     ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_DECLASSIFY);
45
46     /* Test keygen. */
47     VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
48     ret = secp256k1_ec_pubkey_create(ctx, &pubkey, key);
49     VALGRIND_MAKE_MEM_DEFINED(&pubkey, sizeof(secp256k1_pubkey));
50     VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
51     CHECK(ret);
52     CHECK(secp256k1_ec_pubkey_serialize(ctx, spubkey, &outputlen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);
53
54     /* Test signing. */
55     VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
56     ret = secp256k1_ecdsa_sign(ctx, &signature, msg, key, NULL, NULL);
57     VALGRIND_MAKE_MEM_DEFINED(&signature, sizeof(secp256k1_ecdsa_signature));
58     VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
59     CHECK(ret);
60     CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature));
61
62 #if ENABLE_MODULE_ECDH
63     /* Test ECDH. */
64     VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
65     ret = secp256k1_ecdh(ctx, msg, &pubkey, key, NULL, NULL);
66     VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
67     CHECK(ret == 1);
68 #endif
69
70     VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
71     ret = secp256k1_ec_seckey_verify(ctx, key);
72     VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
73     CHECK(ret == 1);
74
75     VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
76     ret = secp256k1_ec_privkey_negate(ctx, key);
77     VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
78     CHECK(ret == 1);
79
80     VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
81     VALGRIND_MAKE_MEM_UNDEFINED(msg, 32);
82     ret = secp256k1_ec_privkey_tweak_add(ctx, key, msg);
83     VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
84     CHECK(ret == 1);
85
86     VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
87     VALGRIND_MAKE_MEM_UNDEFINED(msg, 32);
88     ret = secp256k1_ec_privkey_tweak_mul(ctx, key, msg);
89     VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
90     CHECK(ret == 1);
91
92     /* Test context randomisation. Do this last because it leaves the context tainted. */
93     VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
94     ret = secp256k1_context_randomize(ctx, key);
95     VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
96     CHECK(ret);
97
98     secp256k1_context_destroy(ctx);
99     return 0;
100 }
This page took 0.029051 seconds and 4 git commands to generate.