github.com/ethereum/go-ethereum@v1.16.1/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 https://www.opensource.org/licenses/mit-license.php.* 5 ***********************************************************************/ 6 7 #ifndef SECP256K1_MODULE_ECDH_MAIN_H 8 #define SECP256K1_MODULE_ECDH_MAIN_H 9 10 #include "../../../include/secp256k1_ecdh.h" 11 #include "../../ecmult_const_impl.h" 12 13 static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char *x32, const unsigned char *y32, void *data) { 14 unsigned char version = (y32[31] & 0x01) | 0x02; 15 secp256k1_sha256 sha; 16 (void)data; 17 18 secp256k1_sha256_initialize(&sha); 19 secp256k1_sha256_write(&sha, &version, 1); 20 secp256k1_sha256_write(&sha, x32, 32); 21 secp256k1_sha256_finalize(&sha, output); 22 secp256k1_sha256_clear(&sha); 23 24 return 1; 25 } 26 27 const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256 = ecdh_hash_function_sha256; 28 const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default = ecdh_hash_function_sha256; 29 30 int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *output, const secp256k1_pubkey *point, const unsigned char *scalar, secp256k1_ecdh_hash_function hashfp, void *data) { 31 int ret = 0; 32 int overflow = 0; 33 secp256k1_gej res; 34 secp256k1_ge pt; 35 secp256k1_scalar s; 36 unsigned char x[32]; 37 unsigned char y[32]; 38 39 VERIFY_CHECK(ctx != NULL); 40 ARG_CHECK(output != NULL); 41 ARG_CHECK(point != NULL); 42 ARG_CHECK(scalar != NULL); 43 44 if (hashfp == NULL) { 45 hashfp = secp256k1_ecdh_hash_function_default; 46 } 47 48 secp256k1_pubkey_load(ctx, &pt, point); 49 secp256k1_scalar_set_b32(&s, scalar, &overflow); 50 51 overflow |= secp256k1_scalar_is_zero(&s); 52 secp256k1_scalar_cmov(&s, &secp256k1_scalar_one, overflow); 53 54 secp256k1_ecmult_const(&res, &pt, &s); 55 secp256k1_ge_set_gej(&pt, &res); 56 57 /* Compute a hash of the point */ 58 secp256k1_fe_normalize(&pt.x); 59 secp256k1_fe_normalize(&pt.y); 60 secp256k1_fe_get_b32(x, &pt.x); 61 secp256k1_fe_get_b32(y, &pt.y); 62 63 ret = hashfp(output, x, y, data); 64 65 secp256k1_memclear(x, sizeof(x)); 66 secp256k1_memclear(y, sizeof(y)); 67 secp256k1_scalar_clear(&s); 68 secp256k1_ge_clear(&pt); 69 secp256k1_gej_clear(&res); 70 71 return !!ret & !overflow; 72 } 73 74 #endif /* SECP256K1_MODULE_ECDH_MAIN_H */