8
8
#include <assert.h>
9
9
#include <string.h>
10
10
11
+ #include <secp256k1.h>
12
+ #include <secp256k1_ecdh.h>
13
+
11
14
#include "random.h"
12
- #include "secp256k1.h"
13
- #include "secp256k1_ecdh.h"
14
15
15
16
16
17
int main (void ) {
@@ -21,13 +22,14 @@ int main(void) {
21
22
unsigned char shared_secret1 [32 ];
22
23
unsigned char shared_secret2 [32 ];
23
24
unsigned char randomize [32 ];
25
+ int return_val ;
24
26
size_t len ;
25
27
secp256k1_pubkey pubkey1 ;
26
28
secp256k1_pubkey pubkey2 ;
27
29
28
- /* The docs in secp256k1.h above the `secp256k1_ec_pubkey_create` function
29
- * say: "pointer to a context object, initialized for signing" which is why
30
- * we create a context for signing with the SECP256K1_CONTEXT_SIGN flag.
30
+ /* The specification in secp256k1.h states that `secp256k1_ec_pubkey_create`
31
+ * needs a context object initialized for signing, which is why we create
32
+ * a context with the SECP256K1_CONTEXT_SIGN flag.
31
33
* (The docs for `secp256k1_ecdh` don't require any special context, just
32
34
* some initialized context) */
33
35
secp256k1_context * ctx = secp256k1_context_create (SECP256K1_CONTEXT_SIGN );
@@ -38,7 +40,8 @@ int main(void) {
38
40
/* Randomizing the context is recommended to protect against side-channel
39
41
* leakage See `secp256k1_context_randomize` in secp256k1.h for more
40
42
* information about it. This should never fail. */
41
- assert (secp256k1_context_randomize (ctx , randomize ));
43
+ return_val = secp256k1_context_randomize (ctx , randomize );
44
+ assert (return_val );
42
45
43
46
/*** Key Generation ***/
44
47
@@ -56,32 +59,40 @@ int main(void) {
56
59
}
57
60
58
61
/* Public key creation using a valid context with a verified secret key should never fail */
59
- assert (secp256k1_ec_pubkey_create (ctx , & pubkey1 , seckey1 ));
60
- assert (secp256k1_ec_pubkey_create (ctx , & pubkey2 , seckey2 ));
62
+ return_val = secp256k1_ec_pubkey_create (ctx , & pubkey1 , seckey1 );
63
+ assert (return_val );
64
+ return_val = secp256k1_ec_pubkey_create (ctx , & pubkey2 , seckey2 );
65
+ assert (return_val );
61
66
62
67
/* Serialize pubkey1 in a compressed form (33 bytes), should always return 1 */
63
68
len = sizeof (compressed_pubkey1 );
64
- assert (secp256k1_ec_pubkey_serialize (ctx , compressed_pubkey1 , & len , & pubkey1 , SECP256K1_EC_COMPRESSED ));
69
+ return_val = secp256k1_ec_pubkey_serialize (ctx , compressed_pubkey1 , & len , & pubkey1 , SECP256K1_EC_COMPRESSED );
70
+ assert (return_val );
65
71
/* Should be the same size as the size of the output, because we passed a 33 bytes array. */
66
72
assert (len == sizeof (compressed_pubkey1 ));
67
73
68
74
/* Serialize pubkey2 in a compressed form (33 bytes) */
69
75
len = sizeof (compressed_pubkey2 );
70
- secp256k1_ec_pubkey_serialize (ctx , compressed_pubkey2 , & len , & pubkey2 , SECP256K1_EC_COMPRESSED );
76
+ return_val = secp256k1_ec_pubkey_serialize (ctx , compressed_pubkey2 , & len , & pubkey2 , SECP256K1_EC_COMPRESSED );
77
+ assert (return_val );
78
+ /* Should be the same size as the size of the output, because we passed a 33 bytes array. */
71
79
assert (len == sizeof (compressed_pubkey2 ));
72
80
73
81
/*** Creating the shared secret ***/
74
82
75
83
/* Perform ECDH with seckey1 and pubkey2. Should never fail with a verified
76
84
* seckey and valid pubkey */
77
- assert (secp256k1_ecdh (ctx , shared_secret1 , & pubkey2 , seckey1 , NULL , NULL ));
85
+ return_val = secp256k1_ecdh (ctx , shared_secret1 , & pubkey2 , seckey1 , NULL , NULL );
86
+ assert (return_val );
78
87
79
88
/* Perform ECDH with seckey2 and pubkey1. Should never fail with a verified
80
89
* seckey and valid pubkey */
81
- assert (secp256k1_ecdh (ctx , shared_secret2 , & pubkey1 , seckey2 , NULL , NULL ));
90
+ return_val = secp256k1_ecdh (ctx , shared_secret2 , & pubkey1 , seckey2 , NULL , NULL );
91
+ assert (return_val );
82
92
83
93
/* Both parties should end up with the same shared secret */
84
- assert (memcmp (shared_secret1 , shared_secret2 , sizeof (shared_secret1 )) == 0 );
94
+ return_val = memcmp (shared_secret1 , shared_secret2 , sizeof (shared_secret1 ));
95
+ assert (return_val == 0 );
85
96
86
97
printf ("Secret Key1: " );
87
98
print_hex (seckey1 , sizeof (seckey1 ));
@@ -97,10 +108,10 @@ int main(void) {
97
108
/* This will clear everything from the context and free the memory */
98
109
secp256k1_context_destroy (ctx );
99
110
100
- /* It's best practice to try to remove secrets from memory after using them.
101
- * This is done because some bugs can allow an attacker leak memory, for
102
- * example through out of bounds array access (see Heartbleed for example).
103
- * Hence, we overwrite the secret key buffer with zeros.
111
+ /* It's best practice to try to clear secrets from memory after using them.
112
+ * This is done because some bugs can allow an attacker to leak memory, for
113
+ * example through " out of bounds" array access (see Heartbleed), Or the OS
114
+ * swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
104
115
*
105
116
* TODO: Prevent these writes from being optimized out, as any good compiler
106
117
* will remove any writes that aren't used. */
0 commit comments