Bitcoin Core 29.99.0
P2P Digital Currency
tests_impl.h
Go to the documentation of this file.
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_TESTS_H
8#define SECP256K1_MODULE_ECDH_TESTS_H
9
10static int ecdh_hash_function_test_xpassthru(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) {
11 (void)y;
12 (void)data;
13 memcpy(output, x, 32);
14 return 1;
15}
16
17static int ecdh_hash_function_test_fail(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) {
18 (void)output;
19 (void)x;
20 (void)y;
21 (void)data;
22 return 0;
23}
24
25static int ecdh_hash_function_custom(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) {
26 (void)data;
27 /* Save x and y as uncompressed public key */
28 output[0] = 0x04;
29 memcpy(output + 1, x, 32);
30 memcpy(output + 33, y, 32);
31 return 1;
32}
33
34static void test_ecdh_api(void) {
35 secp256k1_pubkey point;
36 unsigned char res[32];
37 unsigned char s_one[32] = { 0 };
38 s_one[31] = 1;
39
40 CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_one) == 1);
41
42 /* Check all NULLs are detected */
43 CHECK(secp256k1_ecdh(CTX, res, &point, s_one, NULL, NULL) == 1);
44 CHECK_ILLEGAL(CTX, secp256k1_ecdh(CTX, NULL, &point, s_one, NULL, NULL));
45 CHECK_ILLEGAL(CTX, secp256k1_ecdh(CTX, res, NULL, s_one, NULL, NULL));
46 CHECK_ILLEGAL(CTX, secp256k1_ecdh(CTX, res, &point, NULL, NULL, NULL));
47 CHECK(secp256k1_ecdh(CTX, res, &point, s_one, NULL, NULL) == 1);
48}
49
51 unsigned char s_one[32] = { 0 };
52 secp256k1_pubkey point[2];
53 int i;
54
55 s_one[31] = 1;
56 /* Check against pubkey creation when the basepoint is the generator */
57 for (i = 0; i < 2 * COUNT; ++i) {
59 unsigned char s_b32[32];
60 unsigned char output_ecdh[65];
61 unsigned char output_ser[32];
62 unsigned char point_ser[65];
63 size_t point_ser_len = sizeof(point_ser);
65
68
69 CHECK(secp256k1_ec_pubkey_create(CTX, &point[0], s_one) == 1);
70 CHECK(secp256k1_ec_pubkey_create(CTX, &point[1], s_b32) == 1);
71
72 /* compute using ECDH function with custom hash function */
73 CHECK(secp256k1_ecdh(CTX, output_ecdh, &point[0], s_b32, ecdh_hash_function_custom, NULL) == 1);
74 /* compute "explicitly" */
75 CHECK(secp256k1_ec_pubkey_serialize(CTX, point_ser, &point_ser_len, &point[1], SECP256K1_EC_UNCOMPRESSED) == 1);
76 /* compare */
77 CHECK(secp256k1_memcmp_var(output_ecdh, point_ser, 65) == 0);
78
79 /* compute using ECDH function with default hash function */
80 CHECK(secp256k1_ecdh(CTX, output_ecdh, &point[0], s_b32, NULL, NULL) == 1);
81 /* compute "explicitly" */
82 CHECK(secp256k1_ec_pubkey_serialize(CTX, point_ser, &point_ser_len, &point[1], SECP256K1_EC_COMPRESSED) == 1);
84 secp256k1_sha256_write(&sha, point_ser, point_ser_len);
85 secp256k1_sha256_finalize(&sha, output_ser);
86 /* compare */
87 CHECK(secp256k1_memcmp_var(output_ecdh, output_ser, 32) == 0);
88 }
89}
90
91static void test_bad_scalar(void) {
92 unsigned char s_zero[32] = { 0 };
93 unsigned char s_overflow[32] = {
94 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
95 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
96 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
97 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41
98 };
99 unsigned char s_rand[32] = { 0 };
100 unsigned char output[32];
101 secp256k1_scalar rand;
102 secp256k1_pubkey point;
103
104 /* Create random point */
106 secp256k1_scalar_get_b32(s_rand, &rand);
107 CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_rand) == 1);
108
109 /* Try to multiply it by bad values */
110 CHECK(secp256k1_ecdh(CTX, output, &point, s_zero, NULL, NULL) == 0);
111 CHECK(secp256k1_ecdh(CTX, output, &point, s_overflow, NULL, NULL) == 0);
112 /* ...and a good one */
113 s_overflow[31] -= 1;
114 CHECK(secp256k1_ecdh(CTX, output, &point, s_overflow, NULL, NULL) == 1);
115
116 /* Hash function failure results in ecdh failure */
117 CHECK(secp256k1_ecdh(CTX, output, &point, s_overflow, ecdh_hash_function_test_fail, NULL) == 0);
118}
119
121static void test_result_basepoint(void) {
122 secp256k1_pubkey point;
123 secp256k1_scalar rand;
124 unsigned char s[32];
125 unsigned char s_inv[32];
126 unsigned char out[32];
127 unsigned char out_inv[32];
128 unsigned char out_base[32];
129 int i;
130
131 unsigned char s_one[32] = { 0 };
132 s_one[31] = 1;
133 CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_one) == 1);
134 CHECK(secp256k1_ecdh(CTX, out_base, &point, s_one, NULL, NULL) == 1);
135
136 for (i = 0; i < 2 * COUNT; i++) {
139 secp256k1_scalar_inverse(&rand, &rand);
140 secp256k1_scalar_get_b32(s_inv, &rand);
141
142 CHECK(secp256k1_ec_pubkey_create(CTX, &point, s) == 1);
143 CHECK(secp256k1_ecdh(CTX, out, &point, s_inv, NULL, NULL) == 1);
144 CHECK(secp256k1_memcmp_var(out, out_base, 32) == 0);
145
146 CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_inv) == 1);
147 CHECK(secp256k1_ecdh(CTX, out_inv, &point, s, NULL, NULL) == 1);
148 CHECK(secp256k1_memcmp_var(out_inv, out_base, 32) == 0);
149 }
150}
151
152static void test_ecdh_wycheproof(void) {
153#include "../../wycheproof/ecdh_secp256k1_test.h"
154 int t;
156 int parsed_ok;
157 secp256k1_pubkey point;
158 const unsigned char *pk;
159 const unsigned char *sk;
160 const unsigned char *expected_shared_secret;
161 unsigned char output_ecdh[65] = { 0 };
162
163 int expected_result;
164
165 memset(&point, 0, sizeof(point));
167 parsed_ok = secp256k1_ec_pubkey_parse(CTX, &point, pk, testvectors[t].pk_len);
168
170 CHECK(parsed_ok == expected_result);
171 if (!parsed_ok) {
172 continue;
173 }
174
176 CHECK(testvectors[t].sk_len == 32);
177
178 CHECK(secp256k1_ecdh(CTX, output_ecdh, &point, sk, ecdh_hash_function_test_xpassthru, NULL) == 1);
179 expected_shared_secret = &wycheproof_ecdh_shared_secrets[testvectors[t].shared_offset];
180
181 CHECK(secp256k1_memcmp_var(output_ecdh, expected_shared_secret, testvectors[t].shared_len) == 0);
182 }
183}
184
185static void run_ecdh_tests(void) {
191}
192
193#endif /* SECP256K1_MODULE_ECDH_TESTS_H */
static void test_ecdh_api(void)
Definition: tests_impl.h:34
static void test_bad_scalar(void)
Definition: tests_impl.h:91
static int ecdh_hash_function_test_fail(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data)
Definition: tests_impl.h:17
static void test_result_basepoint(void)
Test that ECDH(sG, 1/s) == ECDH((1/s)G, s) == ECDH(G, 1) for a few random s.
Definition: tests_impl.h:121
static void run_ecdh_tests(void)
Definition: tests_impl.h:185
static void test_ecdh_generator_basepoint(void)
Definition: tests_impl.h:50
static int ecdh_hash_function_custom(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data)
Definition: tests_impl.h:25
static void test_ecdh_wycheproof(void)
Definition: tests_impl.h:152
static int ecdh_hash_function_test_xpassthru(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data)
Definition: tests_impl.h:10
static const unsigned char wycheproof_ecdh_public_keys[]
#define SECP256K1_ECDH_WYCHEPROOF_NUMBER_TESTVECTORS
static const wycheproof_ecdh_testvector testvectors[SECP256K1_ECDH_WYCHEPROOF_NUMBER_TESTVECTORS]
static const unsigned char wycheproof_ecdh_private_keys[]
static const unsigned char wycheproof_ecdh_shared_secrets[]
#define CHECK(cond)
Unconditional failure on condition failure.
Definition: util.h:35
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar *a)
Convert a scalar to a byte array.
static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *a)
Compute the inverse of a scalar (modulo the group order).
static void secp256k1_sha256_initialize(secp256k1_sha256 *hash)
static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32)
static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size)
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
Definition: util.h:255
SECP256K1_API int secp256k1_ec_pubkey_serialize(const secp256k1_context *ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey *pubkey, unsigned int flags) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Serialize a pubkey object into a serialized byte sequence.
Definition: secp256k1.c:268
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *input, size_t inputlen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a variable-length public key into the pubkey object.
Definition: secp256k1.c:250
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compute the public key for a secret key.
Definition: secp256k1.c:604
#define SECP256K1_EC_COMPRESSED
Flag to pass to secp256k1_ec_pubkey_serialize.
Definition: secp256k1.h:212
#define SECP256K1_EC_UNCOMPRESSED
Definition: secp256k1.h:213
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(const secp256k1_context *ctx, unsigned char *output, const secp256k1_pubkey *pubkey, const unsigned char *seckey, secp256k1_ecdh_hash_function hashfp, void *data) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Compute an EC Diffie-Hellman secret in constant time.
Definition: main_impl.h:30
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1.h:61
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
static int COUNT
Definition: tests.c:40
#define CHECK_ILLEGAL(ctx, expr)
Definition: tests.c:78
static secp256k1_context * CTX
Definition: tests.c:41
static void testutil_random_scalar_order(secp256k1_scalar *num)
Definition: testutil.h:129