]>
Commit | Line | Data |
---|---|---|
0739bbb6 AP |
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 | ||
abe2d3e8 DR |
7 | #ifndef SECP256K1_MODULE_ECDH_MAIN_H |
8 | #define SECP256K1_MODULE_ECDH_MAIN_H | |
0739bbb6 | 9 | |
4e646080 | 10 | #include "include/secp256k1_ecdh.h" |
0739bbb6 AP |
11 | #include "ecmult_const_impl.h" |
12 | ||
eb45ef33 TR |
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; | |
b00be650 | 15 | secp256k1_sha256 sha; |
c8fbc3c3 | 16 | (void)data; |
b00be650 KF |
17 | |
18 | secp256k1_sha256_initialize(&sha); | |
19 | secp256k1_sha256_write(&sha, &version, 1); | |
eb45ef33 | 20 | secp256k1_sha256_write(&sha, x32, 32); |
b00be650 KF |
21 | secp256k1_sha256_finalize(&sha, output); |
22 | ||
23 | return 1; | |
24 | } | |
25 | ||
26 | const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256 = ecdh_hash_function_sha256; | |
27 | const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default = ecdh_hash_function_sha256; | |
28 | ||
c8fbc3c3 | 29 | 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) { |
0739bbb6 AP |
30 | int ret = 0; |
31 | int overflow = 0; | |
dd891e0e PW |
32 | secp256k1_gej res; |
33 | secp256k1_ge pt; | |
34 | secp256k1_scalar s; | |
34a67c77 GM |
35 | unsigned char x[32]; |
36 | unsigned char y[32]; | |
37 | ||
6f8ae2f3 | 38 | VERIFY_CHECK(ctx != NULL); |
b00be650 | 39 | ARG_CHECK(output != NULL); |
0739bbb6 AP |
40 | ARG_CHECK(point != NULL); |
41 | ARG_CHECK(scalar != NULL); | |
34a67c77 | 42 | |
b00be650 KF |
43 | if (hashfp == NULL) { |
44 | hashfp = secp256k1_ecdh_hash_function_default; | |
45 | } | |
0739bbb6 AP |
46 | |
47 | secp256k1_pubkey_load(ctx, &pt, point); | |
48 | secp256k1_scalar_set_b32(&s, scalar, &overflow); | |
0739bbb6 | 49 | |
34a67c77 GM |
50 | overflow |= secp256k1_scalar_is_zero(&s); |
51 | secp256k1_scalar_cmov(&s, &secp256k1_scalar_one, overflow); | |
52 | ||
53 | secp256k1_ecmult_const(&res, &pt, &s, 256); | |
54 | secp256k1_ge_set_gej(&pt, &res); | |
55 | ||
56 | /* Compute a hash of the point */ | |
57 | secp256k1_fe_normalize(&pt.x); | |
58 | secp256k1_fe_normalize(&pt.y); | |
59 | secp256k1_fe_get_b32(x, &pt.x); | |
60 | secp256k1_fe_get_b32(y, &pt.y); | |
61 | ||
62 | ret = hashfp(output, x, y, data); | |
63 | ||
64 | memset(x, 0, 32); | |
65 | memset(y, 0, 32); | |
0739bbb6 | 66 | secp256k1_scalar_clear(&s); |
34a67c77 GM |
67 | |
68 | return !!ret & !overflow; | |
0739bbb6 AP |
69 | } |
70 | ||
abe2d3e8 | 71 | #endif /* SECP256K1_MODULE_ECDH_MAIN_H */ |