github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/crypto/secp256k1/libsecp256k1/src/modules/schnorr/tests_impl.h (about)

     1  /**********************************************************************
     2   * Copyright (c) 2014-2015 Pieter Wuille                              *
     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  #ifndef SECP256K1_MODULE_SCHNORR_TESTS
     8  #define SECP256K1_MODULE_SCHNORR_TESTS
     9  
    10  #include "include/secp256k1_schnorr.h"
    11  
    12  void test_schnorr_end_to_end(void) {
    13      unsigned char privkey[32];
    14      unsigned char message[32];
    15      unsigned char schnorr_signature[64];
    16      secp256k1_pubkey pubkey, recpubkey;
    17  
    18      /* Generate a random key and message. */
    19      {
    20          secp256k1_scalar key;
    21          random_scalar_order_test(&key);
    22          secp256k1_scalar_get_b32(privkey, &key);
    23          secp256k1_rand256_test(message);
    24      }
    25  
    26      /* Construct and verify corresponding public key. */
    27      CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1);
    28      CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1);
    29  
    30      /* Schnorr sign. */
    31      CHECK(secp256k1_schnorr_sign(ctx, schnorr_signature, message, privkey, NULL, NULL) == 1);
    32      CHECK(secp256k1_schnorr_verify(ctx, schnorr_signature, message, &pubkey) == 1);
    33      CHECK(secp256k1_schnorr_recover(ctx, &recpubkey, schnorr_signature, message) == 1);
    34      CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0);
    35      /* Destroy signature and verify again. */
    36      schnorr_signature[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255);
    37      CHECK(secp256k1_schnorr_verify(ctx, schnorr_signature, message, &pubkey) == 0);
    38      CHECK(secp256k1_schnorr_recover(ctx, &recpubkey, schnorr_signature, message) != 1 ||
    39            memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0);
    40  }
    41  
    42  /** Horribly broken hash function. Do not use for anything but tests. */
    43  void test_schnorr_hash(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32) {
    44      int i;
    45      for (i = 0; i < 32; i++) {
    46          h32[i] = r32[i] ^ msg32[i];
    47      }
    48  }
    49  
    50  void test_schnorr_sign_verify(void) {
    51      unsigned char msg32[32];
    52      unsigned char sig64[3][64];
    53      secp256k1_gej pubkeyj[3];
    54      secp256k1_ge pubkey[3];
    55      secp256k1_scalar nonce[3], key[3];
    56      int i = 0;
    57      int k;
    58  
    59      secp256k1_rand256_test(msg32);
    60  
    61      for (k = 0; k < 3; k++) {
    62          random_scalar_order_test(&key[k]);
    63  
    64          do {
    65              random_scalar_order_test(&nonce[k]);
    66              if (secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64[k], &key[k], &nonce[k], NULL, &test_schnorr_hash, msg32)) {
    67                  break;
    68              }
    69          } while(1);
    70  
    71          secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubkeyj[k], &key[k]);
    72          secp256k1_ge_set_gej_var(&pubkey[k], &pubkeyj[k]);
    73          CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64[k], &pubkey[k], &test_schnorr_hash, msg32));
    74  
    75          for (i = 0; i < 4; i++) {
    76              int pos = secp256k1_rand32() % 64;
    77              int mod = 1 + (secp256k1_rand32() % 255);
    78              sig64[k][pos] ^= mod;
    79              CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64[k], &pubkey[k], &test_schnorr_hash, msg32) == 0);
    80              sig64[k][pos] ^= mod;
    81          }
    82      }
    83  }
    84  
    85  void test_schnorr_threshold(void) {
    86      unsigned char msg[32];
    87      unsigned char sec[5][32];
    88      secp256k1_pubkey pub[5];
    89      unsigned char nonce[5][32];
    90      secp256k1_pubkey pubnonce[5];
    91      unsigned char sig[5][64];
    92      const unsigned char* sigs[5];
    93      unsigned char allsig[64];
    94      const secp256k1_pubkey* pubs[5];
    95      secp256k1_pubkey allpub;
    96      int n, i;
    97      int damage;
    98      int ret = 0;
    99  
   100      damage = (secp256k1_rand32() % 2) ? (1 + (secp256k1_rand32() % 4)) : 0;
   101      secp256k1_rand256_test(msg);
   102      n = 2 + (secp256k1_rand32() % 4);
   103      for (i = 0; i < n; i++) {
   104          do {
   105              secp256k1_rand256_test(sec[i]);
   106          } while (!secp256k1_ec_seckey_verify(ctx, sec[i]));
   107          CHECK(secp256k1_ec_pubkey_create(ctx, &pub[i], sec[i]));
   108          CHECK(secp256k1_schnorr_generate_nonce_pair(ctx, &pubnonce[i], nonce[i], msg, sec[i], NULL, NULL));
   109          pubs[i] = &pub[i];
   110      }
   111      if (damage == 1) {
   112          nonce[secp256k1_rand32() % n][secp256k1_rand32() % 32] ^= 1 + (secp256k1_rand32() % 255);
   113      } else if (damage == 2) {
   114          sec[secp256k1_rand32() % n][secp256k1_rand32() % 32] ^= 1 + (secp256k1_rand32() % 255);
   115      }
   116      for (i = 0; i < n; i++) {
   117          secp256k1_pubkey allpubnonce;
   118          const secp256k1_pubkey *pubnonces[4];
   119          int j;
   120          for (j = 0; j < i; j++) {
   121              pubnonces[j] = &pubnonce[j];
   122          }
   123          for (j = i + 1; j < n; j++) {
   124              pubnonces[j - 1] = &pubnonce[j];
   125          }
   126          CHECK(secp256k1_ec_pubkey_combine(ctx, &allpubnonce, pubnonces, n - 1));
   127          ret |= (secp256k1_schnorr_partial_sign(ctx, sig[i], msg, sec[i], &allpubnonce, nonce[i]) != 1) * 1;
   128          sigs[i] = sig[i];
   129      }
   130      if (damage == 3) {
   131          sig[secp256k1_rand32() % n][secp256k1_rand32() % 64] ^= 1 + (secp256k1_rand32() % 255);
   132      }
   133      ret |= (secp256k1_ec_pubkey_combine(ctx, &allpub, pubs, n) != 1) * 2;
   134      if ((ret & 1) == 0) {
   135          ret |= (secp256k1_schnorr_partial_combine(ctx, allsig, sigs, n) != 1) * 4;
   136      }
   137      if (damage == 4) {
   138          allsig[secp256k1_rand32() % 32] ^= 1 + (secp256k1_rand32() % 255);
   139      }
   140      if ((ret & 7) == 0) {
   141          ret |= (secp256k1_schnorr_verify(ctx, allsig, msg, &allpub) != 1) * 8;
   142      }
   143      CHECK((ret == 0) == (damage == 0));
   144  }
   145  
   146  void test_schnorr_recovery(void) {
   147      unsigned char msg32[32];
   148      unsigned char sig64[64];
   149      secp256k1_ge Q;
   150  
   151      secp256k1_rand256_test(msg32);
   152      secp256k1_rand256_test(sig64);
   153      secp256k1_rand256_test(sig64 + 32);
   154      if (secp256k1_schnorr_sig_recover(&ctx->ecmult_ctx, sig64, &Q, &test_schnorr_hash, msg32) == 1) {
   155          CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64, &Q, &test_schnorr_hash, msg32) == 1);
   156      }
   157  }
   158  
   159  void run_schnorr_tests(void) {
   160      int i;
   161      for (i = 0; i < 32*count; i++) {
   162          test_schnorr_end_to_end();
   163      }
   164      for (i = 0; i < 32 * count; i++) {
   165           test_schnorr_sign_verify();
   166      }
   167      for (i = 0; i < 16 * count; i++) {
   168           test_schnorr_recovery();
   169      }
   170      for (i = 0; i < 10 * count; i++) {
   171           test_schnorr_threshold();
   172      }
   173  }
   174  
   175  #endif