github.com/ethereum/go-ethereum@v1.16.1/crypto/secp256k1/libsecp256k1/src/ctime_tests.c (about) 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 ***********************************************************************/ 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 11 #include "../include/secp256k1.h" 12 #include "assumptions.h" 13 #include "checkmem.h" 14 15 #if !SECP256K1_CHECKMEM_ENABLED 16 # error "This tool cannot be compiled without memory-checking interface (valgrind or msan)" 17 #endif 18 19 #ifdef ENABLE_MODULE_ECDH 20 # include "../include/secp256k1_ecdh.h" 21 #endif 22 23 #ifdef ENABLE_MODULE_RECOVERY 24 # include "../include/secp256k1_recovery.h" 25 #endif 26 27 #ifdef ENABLE_MODULE_EXTRAKEYS 28 # include "../include/secp256k1_extrakeys.h" 29 #endif 30 31 #ifdef ENABLE_MODULE_SCHNORRSIG 32 #include "../include/secp256k1_schnorrsig.h" 33 #endif 34 35 #ifdef ENABLE_MODULE_MUSIG 36 #include "../include/secp256k1_musig.h" 37 #endif 38 39 #ifdef ENABLE_MODULE_ELLSWIFT 40 #include "../include/secp256k1_ellswift.h" 41 #endif 42 43 static void run_tests(secp256k1_context *ctx, unsigned char *key); 44 45 int main(void) { 46 secp256k1_context* ctx; 47 unsigned char key[32]; 48 int ret, i; 49 50 if (!SECP256K1_CHECKMEM_RUNNING()) { 51 fprintf(stderr, "This test can only usefully be run inside valgrind because it was not compiled under msan.\n"); 52 fprintf(stderr, "Usage: libtool --mode=execute valgrind ./ctime_tests\n"); 53 return EXIT_FAILURE; 54 } 55 ctx = secp256k1_context_create(SECP256K1_CONTEXT_DECLASSIFY); 56 /** In theory, testing with a single secret input should be sufficient: 57 * If control flow depended on secrets the tool would generate an error. 58 */ 59 for (i = 0; i < 32; i++) { 60 key[i] = i + 65; 61 } 62 63 run_tests(ctx, key); 64 65 /* Test context randomisation. Do this last because it leaves the context 66 * tainted. */ 67 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 68 ret = secp256k1_context_randomize(ctx, key); 69 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 70 CHECK(ret); 71 72 secp256k1_context_destroy(ctx); 73 return EXIT_SUCCESS; 74 } 75 76 static void run_tests(secp256k1_context *ctx, unsigned char *key) { 77 secp256k1_ecdsa_signature signature; 78 secp256k1_pubkey pubkey; 79 size_t siglen = 74; 80 size_t outputlen = 33; 81 int i; 82 int ret; 83 unsigned char msg[32]; 84 unsigned char sig[74]; 85 unsigned char spubkey[33]; 86 #ifdef ENABLE_MODULE_RECOVERY 87 secp256k1_ecdsa_recoverable_signature recoverable_signature; 88 int recid; 89 #endif 90 #ifdef ENABLE_MODULE_EXTRAKEYS 91 secp256k1_keypair keypair; 92 #endif 93 #ifdef ENABLE_MODULE_ELLSWIFT 94 unsigned char ellswift[64]; 95 static const unsigned char prefix[64] = {'t', 'e', 's', 't'}; 96 #endif 97 98 for (i = 0; i < 32; i++) { 99 msg[i] = i + 1; 100 } 101 102 /* Test keygen. */ 103 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 104 ret = secp256k1_ec_pubkey_create(ctx, &pubkey, key); 105 SECP256K1_CHECKMEM_DEFINE(&pubkey, sizeof(secp256k1_pubkey)); 106 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 107 CHECK(ret); 108 CHECK(secp256k1_ec_pubkey_serialize(ctx, spubkey, &outputlen, &pubkey, SECP256K1_EC_COMPRESSED) == 1); 109 110 /* Test signing. */ 111 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 112 ret = secp256k1_ecdsa_sign(ctx, &signature, msg, key, NULL, NULL); 113 SECP256K1_CHECKMEM_DEFINE(&signature, sizeof(secp256k1_ecdsa_signature)); 114 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 115 CHECK(ret); 116 CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature)); 117 118 #ifdef ENABLE_MODULE_ECDH 119 /* Test ECDH. */ 120 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 121 ret = secp256k1_ecdh(ctx, msg, &pubkey, key, NULL, NULL); 122 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 123 CHECK(ret == 1); 124 #endif 125 126 #ifdef ENABLE_MODULE_RECOVERY 127 /* Test signing a recoverable signature. */ 128 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 129 ret = secp256k1_ecdsa_sign_recoverable(ctx, &recoverable_signature, msg, key, NULL, NULL); 130 SECP256K1_CHECKMEM_DEFINE(&recoverable_signature, sizeof(recoverable_signature)); 131 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 132 CHECK(ret); 133 CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &recoverable_signature)); 134 CHECK(recid >= 0 && recid <= 3); 135 #endif 136 137 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 138 ret = secp256k1_ec_seckey_verify(ctx, key); 139 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 140 CHECK(ret == 1); 141 142 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 143 ret = secp256k1_ec_seckey_negate(ctx, key); 144 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 145 CHECK(ret == 1); 146 147 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 148 SECP256K1_CHECKMEM_UNDEFINE(msg, 32); 149 ret = secp256k1_ec_seckey_tweak_add(ctx, key, msg); 150 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 151 CHECK(ret == 1); 152 153 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 154 SECP256K1_CHECKMEM_UNDEFINE(msg, 32); 155 ret = secp256k1_ec_seckey_tweak_mul(ctx, key, msg); 156 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 157 CHECK(ret == 1); 158 159 /* Test keypair_create and keypair_xonly_tweak_add. */ 160 #ifdef ENABLE_MODULE_EXTRAKEYS 161 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 162 ret = secp256k1_keypair_create(ctx, &keypair, key); 163 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 164 CHECK(ret == 1); 165 166 /* The tweak is not treated as a secret in keypair_tweak_add */ 167 SECP256K1_CHECKMEM_DEFINE(msg, 32); 168 ret = secp256k1_keypair_xonly_tweak_add(ctx, &keypair, msg); 169 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 170 CHECK(ret == 1); 171 172 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 173 SECP256K1_CHECKMEM_UNDEFINE(&keypair, sizeof(keypair)); 174 ret = secp256k1_keypair_sec(ctx, key, &keypair); 175 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 176 CHECK(ret == 1); 177 #endif 178 179 #ifdef ENABLE_MODULE_SCHNORRSIG 180 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 181 ret = secp256k1_keypair_create(ctx, &keypair, key); 182 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 183 CHECK(ret == 1); 184 ret = secp256k1_schnorrsig_sign32(ctx, sig, msg, &keypair, NULL); 185 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 186 CHECK(ret == 1); 187 #endif 188 189 #ifdef ENABLE_MODULE_MUSIG 190 { 191 secp256k1_pubkey pk; 192 const secp256k1_pubkey *pk_ptr[1]; 193 secp256k1_xonly_pubkey agg_pk; 194 unsigned char session_secrand[32]; 195 uint64_t nonrepeating_cnt = 0; 196 secp256k1_musig_secnonce secnonce; 197 secp256k1_musig_pubnonce pubnonce; 198 const secp256k1_musig_pubnonce *pubnonce_ptr[1]; 199 secp256k1_musig_aggnonce aggnonce; 200 secp256k1_musig_keyagg_cache cache; 201 secp256k1_musig_session session; 202 secp256k1_musig_partial_sig partial_sig; 203 unsigned char extra_input[32]; 204 205 pk_ptr[0] = &pk; 206 pubnonce_ptr[0] = &pubnonce; 207 SECP256K1_CHECKMEM_DEFINE(key, 32); 208 memcpy(session_secrand, key, sizeof(session_secrand)); 209 session_secrand[0] = session_secrand[0] + 1; 210 memcpy(extra_input, key, sizeof(extra_input)); 211 extra_input[0] = extra_input[0] + 2; 212 213 CHECK(secp256k1_keypair_create(ctx, &keypair, key)); 214 CHECK(secp256k1_keypair_pub(ctx, &pk, &keypair)); 215 CHECK(secp256k1_musig_pubkey_agg(ctx, &agg_pk, &cache, pk_ptr, 1)); 216 217 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 218 SECP256K1_CHECKMEM_UNDEFINE(session_secrand, sizeof(session_secrand)); 219 SECP256K1_CHECKMEM_UNDEFINE(extra_input, sizeof(extra_input)); 220 ret = secp256k1_musig_nonce_gen(ctx, &secnonce, &pubnonce, session_secrand, key, &pk, msg, &cache, extra_input); 221 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 222 CHECK(ret == 1); 223 ret = secp256k1_musig_nonce_gen_counter(ctx, &secnonce, &pubnonce, nonrepeating_cnt, &keypair, msg, &cache, extra_input); 224 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 225 CHECK(ret == 1); 226 227 CHECK(secp256k1_musig_nonce_agg(ctx, &aggnonce, pubnonce_ptr, 1)); 228 /* Make sure that previous tests don't undefine msg. It's not used as a secret here. */ 229 SECP256K1_CHECKMEM_DEFINE(msg, sizeof(msg)); 230 CHECK(secp256k1_musig_nonce_process(ctx, &session, &aggnonce, msg, &cache) == 1); 231 232 ret = secp256k1_keypair_create(ctx, &keypair, key); 233 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 234 CHECK(ret == 1); 235 ret = secp256k1_musig_partial_sign(ctx, &partial_sig, &secnonce, &keypair, &cache, &session); 236 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 237 CHECK(ret == 1); 238 } 239 #endif 240 241 #ifdef ENABLE_MODULE_ELLSWIFT 242 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 243 ret = secp256k1_ellswift_create(ctx, ellswift, key, NULL); 244 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 245 CHECK(ret == 1); 246 247 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 248 ret = secp256k1_ellswift_create(ctx, ellswift, key, ellswift); 249 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 250 CHECK(ret == 1); 251 252 for (i = 0; i < 2; i++) { 253 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 254 SECP256K1_CHECKMEM_DEFINE(&ellswift, sizeof(ellswift)); 255 ret = secp256k1_ellswift_xdh(ctx, msg, ellswift, ellswift, key, i, secp256k1_ellswift_xdh_hash_function_bip324, NULL); 256 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 257 CHECK(ret == 1); 258 259 SECP256K1_CHECKMEM_UNDEFINE(key, 32); 260 SECP256K1_CHECKMEM_DEFINE(&ellswift, sizeof(ellswift)); 261 ret = secp256k1_ellswift_xdh(ctx, msg, ellswift, ellswift, key, i, secp256k1_ellswift_xdh_hash_function_prefix, (void *)prefix); 262 SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); 263 CHECK(ret == 1); 264 } 265 266 #endif 267 }