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