|  | 
|  | 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 | +} | 
0 commit comments