Skip to content

Commit 8c9aa94

Browse files
authored
Update ecdh.c
1 parent 1aba679 commit 8c9aa94

File tree

1 file changed

+21
-29
lines changed

1 file changed

+21
-29
lines changed

examples/ecdh.c

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717

1818
#include "examples_util.h"
1919

20-
/* Identity hash function for ECDH, returns x coordinate directly */
21-
int ecdh_hash(unsigned char *output, const unsigned char *x32, const unsigned char *y32, void *data) {
22-
(void)y32;
23-
(void)data;
24-
memcpy(output, x32, 32);
20+
int extract_x_coordinate(const secp256k1_context* ctx, const secp256k1_pubkey* pubkey, unsigned char x[32]) {
21+
unsigned char serialized[33];
22+
size_t len = sizeof(serialized);
23+
24+
if (!secp256k1_ec_pubkey_serialize(ctx, serialized, &len, pubkey, SECP256K1_EC_COMPRESSED))
25+
return 0;
26+
27+
memcpy(x, serialized + 1, 32);
2528
return 1;
2629
}
2730

@@ -32,6 +35,7 @@ int main(void) {
3235
unsigned char compressed_pubkey2[33];
3336
unsigned char shared_secret1[32];
3437
unsigned char shared_secret2[32];
38+
unsigned char x1[32], x2[32];
3539
unsigned char randomize[32];
3640
int return_val;
3741
size_t len;
@@ -55,71 +59,59 @@ int main(void) {
5559
printf("Failed to generate randomness\n");
5660
return EXIT_FAILURE;
5761
}
58-
/* If the secret key is zero or out of range (greater than secp256k1's
59-
* order), we fail. Note that the probability of this occurring is negligible
60-
* with a properly functioning random number generator. */
6162
if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) {
6263
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
6364
return EXIT_FAILURE;
6465
}
6566

66-
/* Public key creation using a valid context with a verified secret key should never fail */
6767
return_val = secp256k1_ec_pubkey_create(ctx, &pubkey1, seckey1);
6868
assert(return_val);
6969
return_val = secp256k1_ec_pubkey_create(ctx, &pubkey2, seckey2);
7070
assert(return_val);
7171

72-
/* Serialize pubkey1 in a compressed form (33 bytes), should always return 1 */
7372
len = sizeof(compressed_pubkey1);
7473
return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey1, &len, &pubkey1, SECP256K1_EC_COMPRESSED);
7574
assert(return_val);
76-
/* Should be the same size as the size of the output, because we passed a 33 byte array. */
7775
assert(len == sizeof(compressed_pubkey1));
7876

79-
/* Serialize pubkey2 in a compressed form (33 bytes) */
8077
len = sizeof(compressed_pubkey2);
8178
return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey2, &len, &pubkey2, SECP256K1_EC_COMPRESSED);
8279
assert(return_val);
83-
/* Should be the same size as the size of the output, because we passed a 33 byte array. */
8480
assert(len == sizeof(compressed_pubkey2));
8581

8682
/*** Creating the shared secret ***/
87-
88-
/* Perform ECDH with seckey1 and pubkey2. Should never fail with a verified
89-
* seckey and valid pubkey */
90-
return_val = secp256k1_ecdh(ctx, shared_secret1, &pubkey2, seckey1, ecdh_hash, NULL);
83+
return_val = secp256k1_ecdh(ctx, shared_secret1, &pubkey2, seckey1, NULL, NULL);
9184
assert(return_val);
9285

93-
/* Perform ECDH with seckey2 and pubkey1. Should never fail with a verified
94-
* seckey and valid pubkey */
95-
return_val = secp256k1_ecdh(ctx, shared_secret2, &pubkey1, seckey2, ecdh_hash, NULL);
86+
return_val = secp256k1_ecdh(ctx, shared_secret2, &pubkey1, seckey2, NULL, NULL);
9687
assert(return_val);
9788

98-
/* Both parties should end up with the same shared secret */
9989
return_val = memcmp(shared_secret1, shared_secret2, sizeof(shared_secret1));
10090
assert(return_val == 0);
10191

92+
/* Извлекаем X-координату */
93+
assert(extract_x_coordinate(ctx, &pubkey1, x1));
94+
assert(extract_x_coordinate(ctx, &pubkey2, x2));
95+
10296
printf("Secret Key1: ");
10397
print_hex(seckey1, sizeof(seckey1));
10498
printf("Compressed Pubkey1: ");
10599
print_hex(compressed_pubkey1, sizeof(compressed_pubkey1));
100+
printf("X-coordinate Pubkey1: ");
101+
print_hex(x1, sizeof(x1));
102+
106103
printf("\nSecret Key2: ");
107104
print_hex(seckey2, sizeof(seckey2));
108105
printf("Compressed Pubkey2: ");
109106
print_hex(compressed_pubkey2, sizeof(compressed_pubkey2));
107+
printf("X-coordinate Pubkey2: ");
108+
print_hex(x2, sizeof(x2));
109+
110110
printf("\nShared Secret: ");
111111
print_hex(shared_secret1, sizeof(shared_secret1));
112112

113-
/* This will clear everything from the context and free the memory */
114113
secp256k1_context_destroy(ctx);
115114

116-
/* It's best practice to try to clear secrets from memory after using them.
117-
* This is done because some bugs can allow an attacker to leak memory, for
118-
* example through "out of bounds" array access (see Heartbleed), or the OS
119-
* swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
120-
*
121-
* Here we are preventing these writes from being optimized out, as any good compiler
122-
* will remove any writes that aren't used. */
123115
secure_erase(seckey1, sizeof(seckey1));
124116
secure_erase(seckey2, sizeof(seckey2));
125117
secure_erase(shared_secret1, sizeof(shared_secret1));

0 commit comments

Comments
 (0)