github.com/ethereum/go-ethereum@v1.16.1/crypto/secp256k1/libsecp256k1/src/modules/ecdh/tests_impl.h (about)

     1  /***********************************************************************
     2   * Copyright (c) 2015 Andrew Poelstra                                  *
     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  #ifndef SECP256K1_MODULE_ECDH_TESTS_H
     8  #define SECP256K1_MODULE_ECDH_TESTS_H
     9  
    10  static int ecdh_hash_function_test_fail(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) {
    11      (void)output;
    12      (void)x;
    13      (void)y;
    14      (void)data;
    15      return 0;
    16  }
    17  
    18  static int ecdh_hash_function_custom(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) {
    19      (void)data;
    20      /* Save x and y as uncompressed public key */
    21      output[0] = 0x04;
    22      memcpy(output + 1, x, 32);
    23      memcpy(output + 33, y, 32);
    24      return 1;
    25  }
    26  
    27  static void test_ecdh_api(void) {
    28      secp256k1_pubkey point;
    29      unsigned char res[32];
    30      unsigned char s_one[32] = { 0 };
    31      s_one[31] = 1;
    32  
    33      CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_one) == 1);
    34  
    35      /* Check all NULLs are detected */
    36      CHECK(secp256k1_ecdh(CTX, res, &point, s_one, NULL, NULL) == 1);
    37      CHECK_ILLEGAL(CTX, secp256k1_ecdh(CTX, NULL, &point, s_one, NULL, NULL));
    38      CHECK_ILLEGAL(CTX, secp256k1_ecdh(CTX, res, NULL, s_one, NULL, NULL));
    39      CHECK_ILLEGAL(CTX, secp256k1_ecdh(CTX, res, &point, NULL, NULL, NULL));
    40      CHECK(secp256k1_ecdh(CTX, res, &point, s_one, NULL, NULL) == 1);
    41  }
    42  
    43  static void test_ecdh_generator_basepoint(void) {
    44      unsigned char s_one[32] = { 0 };
    45      secp256k1_pubkey point[2];
    46      int i;
    47  
    48      s_one[31] = 1;
    49      /* Check against pubkey creation when the basepoint is the generator */
    50      for (i = 0; i < 2 * COUNT; ++i) {
    51          secp256k1_sha256 sha;
    52          unsigned char s_b32[32];
    53          unsigned char output_ecdh[65];
    54          unsigned char output_ser[32];
    55          unsigned char point_ser[65];
    56          size_t point_ser_len = sizeof(point_ser);
    57          secp256k1_scalar s;
    58  
    59          testutil_random_scalar_order(&s);
    60          secp256k1_scalar_get_b32(s_b32, &s);
    61  
    62          CHECK(secp256k1_ec_pubkey_create(CTX, &point[0], s_one) == 1);
    63          CHECK(secp256k1_ec_pubkey_create(CTX, &point[1], s_b32) == 1);
    64  
    65          /* compute using ECDH function with custom hash function */
    66          CHECK(secp256k1_ecdh(CTX, output_ecdh, &point[0], s_b32, ecdh_hash_function_custom, NULL) == 1);
    67          /* compute "explicitly" */
    68          CHECK(secp256k1_ec_pubkey_serialize(CTX, point_ser, &point_ser_len, &point[1], SECP256K1_EC_UNCOMPRESSED) == 1);
    69          /* compare */
    70          CHECK(secp256k1_memcmp_var(output_ecdh, point_ser, 65) == 0);
    71  
    72          /* compute using ECDH function with default hash function */
    73          CHECK(secp256k1_ecdh(CTX, output_ecdh, &point[0], s_b32, NULL, NULL) == 1);
    74          /* compute "explicitly" */
    75          CHECK(secp256k1_ec_pubkey_serialize(CTX, point_ser, &point_ser_len, &point[1], SECP256K1_EC_COMPRESSED) == 1);
    76          secp256k1_sha256_initialize(&sha);
    77          secp256k1_sha256_write(&sha, point_ser, point_ser_len);
    78          secp256k1_sha256_finalize(&sha, output_ser);
    79          /* compare */
    80          CHECK(secp256k1_memcmp_var(output_ecdh, output_ser, 32) == 0);
    81      }
    82  }
    83  
    84  static void test_bad_scalar(void) {
    85      unsigned char s_zero[32] = { 0 };
    86      unsigned char s_overflow[32] = {
    87          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    88          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
    89          0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
    90          0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41
    91      };
    92      unsigned char s_rand[32] = { 0 };
    93      unsigned char output[32];
    94      secp256k1_scalar rand;
    95      secp256k1_pubkey point;
    96  
    97      /* Create random point */
    98      testutil_random_scalar_order(&rand);
    99      secp256k1_scalar_get_b32(s_rand, &rand);
   100      CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_rand) == 1);
   101  
   102      /* Try to multiply it by bad values */
   103      CHECK(secp256k1_ecdh(CTX, output, &point, s_zero, NULL, NULL) == 0);
   104      CHECK(secp256k1_ecdh(CTX, output, &point, s_overflow, NULL, NULL) == 0);
   105      /* ...and a good one */
   106      s_overflow[31] -= 1;
   107      CHECK(secp256k1_ecdh(CTX, output, &point, s_overflow, NULL, NULL) == 1);
   108  
   109      /* Hash function failure results in ecdh failure */
   110      CHECK(secp256k1_ecdh(CTX, output, &point, s_overflow, ecdh_hash_function_test_fail, NULL) == 0);
   111  }
   112  
   113  /** Test that ECDH(sG, 1/s) == ECDH((1/s)G, s) == ECDH(G, 1) for a few random s. */
   114  static void test_result_basepoint(void) {
   115      secp256k1_pubkey point;
   116      secp256k1_scalar rand;
   117      unsigned char s[32];
   118      unsigned char s_inv[32];
   119      unsigned char out[32];
   120      unsigned char out_inv[32];
   121      unsigned char out_base[32];
   122      int i;
   123  
   124      unsigned char s_one[32] = { 0 };
   125      s_one[31] = 1;
   126      CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_one) == 1);
   127      CHECK(secp256k1_ecdh(CTX, out_base, &point, s_one, NULL, NULL) == 1);
   128  
   129      for (i = 0; i < 2 * COUNT; i++) {
   130          testutil_random_scalar_order(&rand);
   131          secp256k1_scalar_get_b32(s, &rand);
   132          secp256k1_scalar_inverse(&rand, &rand);
   133          secp256k1_scalar_get_b32(s_inv, &rand);
   134  
   135          CHECK(secp256k1_ec_pubkey_create(CTX, &point, s) == 1);
   136          CHECK(secp256k1_ecdh(CTX, out, &point, s_inv, NULL, NULL) == 1);
   137          CHECK(secp256k1_memcmp_var(out, out_base, 32) == 0);
   138  
   139          CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_inv) == 1);
   140          CHECK(secp256k1_ecdh(CTX, out_inv, &point, s, NULL, NULL) == 1);
   141          CHECK(secp256k1_memcmp_var(out_inv, out_base, 32) == 0);
   142      }
   143  }
   144  
   145  static void run_ecdh_tests(void) {
   146      test_ecdh_api();
   147      test_ecdh_generator_basepoint();
   148      test_bad_scalar();
   149      test_result_basepoint();
   150  }
   151  
   152  #endif /* SECP256K1_MODULE_ECDH_TESTS_H */