github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/crypto/secp256k1/libsecp256k1/src/modules/ecdh/main_impl.h (about)

     1  /**********************************************************************
     2   * Copyright (c) 2015 Andrew Poelstra                                 *
     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_ECDH_MAIN_
     8  #define _SECP256K1_MODULE_ECDH_MAIN_
     9  
    10  #include "include/secp256k1_ecdh.h"
    11  #include "ecmult_const_impl.h"
    12  
    13  int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *result, const secp256k1_pubkey *point, const unsigned char *scalar) {
    14      int ret = 0;
    15      int overflow = 0;
    16      secp256k1_gej res;
    17      secp256k1_ge pt;
    18      secp256k1_scalar s;
    19      VERIFY_CHECK(ctx != NULL);
    20      ARG_CHECK(result != NULL);
    21      ARG_CHECK(point != NULL);
    22      ARG_CHECK(scalar != NULL);
    23  
    24      secp256k1_pubkey_load(ctx, &pt, point);
    25      secp256k1_scalar_set_b32(&s, scalar, &overflow);
    26      if (overflow || secp256k1_scalar_is_zero(&s)) {
    27          ret = 0;
    28      } else {
    29          unsigned char x[32];
    30          unsigned char y[1];
    31          secp256k1_sha256_t sha;
    32  
    33          secp256k1_ecmult_const(&res, &pt, &s);
    34          secp256k1_ge_set_gej(&pt, &res);
    35          /* Compute a hash of the point in compressed form
    36           * Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not
    37           * expect its output to be secret and has a timing sidechannel. */
    38          secp256k1_fe_normalize(&pt.x);
    39          secp256k1_fe_normalize(&pt.y);
    40          secp256k1_fe_get_b32(x, &pt.x);
    41          y[0] = 0x02 | secp256k1_fe_is_odd(&pt.y);
    42  
    43          secp256k1_sha256_initialize(&sha);
    44          secp256k1_sha256_write(&sha, y, sizeof(y));
    45          secp256k1_sha256_write(&sha, x, sizeof(x));
    46          secp256k1_sha256_finalize(&sha, result);
    47          ret = 1;
    48      }
    49  
    50      secp256k1_scalar_clear(&s);
    51      return ret;
    52  }
    53  
    54  #endif