/ src / secp256k1 / src / ctime_tests.c
ctime_tests.c
  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: valgrind ./ctime_tests (or with Autotools: 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  }