main_impl.h
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_impl(const secp256k1_hash_ctx *hash_ctx, 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(hash_ctx, &sha, &version, 1); 20 secp256k1_sha256_write(hash_ctx, &sha, x32, 32); 21 secp256k1_sha256_finalize(hash_ctx, &sha, output); 22 secp256k1_sha256_clear(&sha); 23 24 return 1; 25 } 26 27 static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char *x32, const unsigned char *y32, void *data) { 28 return ecdh_hash_function_sha256_impl(secp256k1_get_hash_context(secp256k1_context_static), output, x32, y32, data); 29 } 30 31 const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256 = ecdh_hash_function_sha256; 32 const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default = ecdh_hash_function_sha256; 33 34 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) { 35 int ret = 0; 36 int overflow = 0; 37 secp256k1_gej res; 38 secp256k1_ge pt; 39 secp256k1_scalar s; 40 unsigned char x[32]; 41 unsigned char y[32]; 42 43 VERIFY_CHECK(ctx != NULL); 44 ARG_CHECK(output != NULL); 45 ARG_CHECK(point != NULL); 46 ARG_CHECK(scalar != NULL); 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 if (hashfp == NULL) { 64 /* Use ctx-aware function by default */ 65 ret = ecdh_hash_function_sha256_impl(secp256k1_get_hash_context(ctx), output, x, y, data); 66 } else { 67 ret = hashfp(output, x, y, data); 68 } 69 70 secp256k1_memclear_explicit(x, sizeof(x)); 71 secp256k1_memclear_explicit(y, sizeof(y)); 72 secp256k1_scalar_clear(&s); 73 secp256k1_ge_clear(&pt); 74 secp256k1_gej_clear(&res); 75 76 return !!ret & !overflow; 77 } 78 79 #endif /* SECP256K1_MODULE_ECDH_MAIN_H */