Bitcoin Core 28.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_fail(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) {
11 (void)output;
12 (void)x;
13 (void)y;
14 (void)data;
15 return 0;
16}
17
18static int ecdh_hash_function_custom(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) {
19 (void)data;
20 /* Save x and y as uncompressed public key */
21 output[0] = 0x04;
22 memcpy(output + 1, x, 32);
23 memcpy(output + 33, y, 32);
24 return 1;
25}
26
27static void test_ecdh_api(void) {
28 secp256k1_pubkey point;
29 unsigned char res[32];
30 unsigned char s_one[32] = { 0 };
31 s_one[31] = 1;
32
33 CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_one) == 1);
34
35 /* Check all NULLs are detected */
36 CHECK(secp256k1_ecdh(CTX, res, &point, s_one, NULL, NULL) == 1);
37 CHECK_ILLEGAL(CTX, secp256k1_ecdh(CTX, NULL, &point, s_one, NULL, NULL));
38 CHECK_ILLEGAL(CTX, secp256k1_ecdh(CTX, res, NULL, s_one, NULL, NULL));
39 CHECK_ILLEGAL(CTX, secp256k1_ecdh(CTX, res, &point, NULL, NULL, NULL));
40 CHECK(secp256k1_ecdh(CTX, res, &point, s_one, NULL, NULL) == 1);
41}
42
44 unsigned char s_one[32] = { 0 };
45 secp256k1_pubkey point[2];
46 int i;
47
48 s_one[31] = 1;
49 /* Check against pubkey creation when the basepoint is the generator */
50 for (i = 0; i < 2 * COUNT; ++i) {
52 unsigned char s_b32[32];
53 unsigned char output_ecdh[65];
54 unsigned char output_ser[32];
55 unsigned char point_ser[65];
56 size_t point_ser_len = sizeof(point_ser);
58
61
62 CHECK(secp256k1_ec_pubkey_create(CTX, &point[0], s_one) == 1);
63 CHECK(secp256k1_ec_pubkey_create(CTX, &point[1], s_b32) == 1);
64
65 /* compute using ECDH function with custom hash function */
66 CHECK(secp256k1_ecdh(CTX, output_ecdh, &point[0], s_b32, ecdh_hash_function_custom, NULL) == 1);
67 /* compute "explicitly" */
68 CHECK(secp256k1_ec_pubkey_serialize(CTX, point_ser, &point_ser_len, &point[1], SECP256K1_EC_UNCOMPRESSED) == 1);
69 /* compare */
70 CHECK(secp256k1_memcmp_var(output_ecdh, point_ser, 65) == 0);
71
72 /* compute using ECDH function with default hash function */
73 CHECK(secp256k1_ecdh(CTX, output_ecdh, &point[0], s_b32, NULL, NULL) == 1);
74 /* compute "explicitly" */
75 CHECK(secp256k1_ec_pubkey_serialize(CTX, point_ser, &point_ser_len, &point[1], SECP256K1_EC_COMPRESSED) == 1);
77 secp256k1_sha256_write(&sha, point_ser, point_ser_len);
78 secp256k1_sha256_finalize(&sha, output_ser);
79 /* compare */
80 CHECK(secp256k1_memcmp_var(output_ecdh, output_ser, 32) == 0);
81 }
82}
83
84static void test_bad_scalar(void) {
85 unsigned char s_zero[32] = { 0 };
86 unsigned char s_overflow[32] = {
87 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
88 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
89 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
90 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41
91 };
92 unsigned char s_rand[32] = { 0 };
93 unsigned char output[32];
95 secp256k1_pubkey point;
96
97 /* Create random point */
99 secp256k1_scalar_get_b32(s_rand, &rand);
100 CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_rand) == 1);
101
102 /* Try to multiply it by bad values */
103 CHECK(secp256k1_ecdh(CTX, output, &point, s_zero, NULL, NULL) == 0);
104 CHECK(secp256k1_ecdh(CTX, output, &point, s_overflow, NULL, NULL) == 0);
105 /* ...and a good one */
106 s_overflow[31] -= 1;
107 CHECK(secp256k1_ecdh(CTX, output, &point, s_overflow, NULL, NULL) == 1);
108
109 /* Hash function failure results in ecdh failure */
110 CHECK(secp256k1_ecdh(CTX, output, &point, s_overflow, ecdh_hash_function_test_fail, NULL) == 0);
111}
112
114static void test_result_basepoint(void) {
115 secp256k1_pubkey point;
116 secp256k1_scalar rand;
117 unsigned char s[32];
118 unsigned char s_inv[32];
119 unsigned char out[32];
120 unsigned char out_inv[32];
121 unsigned char out_base[32];
122 int i;
123
124 unsigned char s_one[32] = { 0 };
125 s_one[31] = 1;
126 CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_one) == 1);
127 CHECK(secp256k1_ecdh(CTX, out_base, &point, s_one, NULL, NULL) == 1);
128
129 for (i = 0; i < 2 * COUNT; i++) {
132 secp256k1_scalar_inverse(&rand, &rand);
133 secp256k1_scalar_get_b32(s_inv, &rand);
134
135 CHECK(secp256k1_ec_pubkey_create(CTX, &point, s) == 1);
136 CHECK(secp256k1_ecdh(CTX, out, &point, s_inv, NULL, NULL) == 1);
137 CHECK(secp256k1_memcmp_var(out, out_base, 32) == 0);
138
139 CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_inv) == 1);
140 CHECK(secp256k1_ecdh(CTX, out_inv, &point, s, NULL, NULL) == 1);
141 CHECK(secp256k1_memcmp_var(out_inv, out_base, 32) == 0);
142 }
143}
144
145static void run_ecdh_tests(void) {
150}
151
152#endif /* SECP256K1_MODULE_ECDH_TESTS_H */
static void test_ecdh_api(void)
Definition: tests_impl.h:27
static void test_bad_scalar(void)
Definition: tests_impl.h:84
static int ecdh_hash_function_test_fail(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data)
Definition: tests_impl.h:10
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:114
static void run_ecdh_tests(void)
Definition: tests_impl.h:145
static void test_ecdh_generator_basepoint(void)
Definition: tests_impl.h:43
static int ecdh_hash_function_custom(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data)
Definition: tests_impl.h:18
#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_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