@@ -15,6 +15,13 @@ static int ecdh_hash_function_test_fail(unsigned char *output, const unsigned ch
15
15
return 0 ;
16
16
}
17
17
18
+ static int ecdh_xonly_hash_function_test_fail (unsigned char * output , const unsigned char * x , void * data ) {
19
+ (void )output ;
20
+ (void )x ;
21
+ (void )data ;
22
+ return 0 ;
23
+ }
24
+
18
25
static int ecdh_hash_function_custom (unsigned char * output , const unsigned char * x , const unsigned char * y , void * data ) {
19
26
(void )data ;
20
27
/* Save x and y as uncompressed public key */
@@ -24,9 +31,17 @@ static int ecdh_hash_function_custom(unsigned char *output, const unsigned char
24
31
return 1 ;
25
32
}
26
33
34
+ static int ecdh_xonly_hash_function_custom (unsigned char * output , const unsigned char * x , void * data ) {
35
+ (void )data ;
36
+ /* Output X coordinate. */
37
+ memcpy (output , x , 32 );
38
+ return 1 ;
39
+ }
40
+
27
41
static void test_ecdh_api (void ) {
28
42
secp256k1_pubkey point ;
29
43
unsigned char res [32 ];
44
+ unsigned char x32 [32 ];
30
45
unsigned char s_one [32 ] = { 0 };
31
46
s_one [31 ] = 1 ;
32
47
@@ -38,14 +53,28 @@ static void test_ecdh_api(void) {
38
53
CHECK_ILLEGAL (CTX , secp256k1_ecdh (CTX , res , NULL , s_one , NULL , NULL ));
39
54
CHECK_ILLEGAL (CTX , secp256k1_ecdh (CTX , res , & point , NULL , NULL , NULL ));
40
55
CHECK (secp256k1_ecdh (CTX , res , & point , s_one , NULL , NULL ) == 1 );
56
+
57
+ /* And the same for secp256k1_ecdh_xonly. */
58
+ memset (x32 , 131 , 32 ); /* sum(131*256^j, j=0..31) is a valid x coordinate. */
59
+ CHECK (secp256k1_ecdh_xonly (CTX , res , x32 , s_one , NULL , NULL ) == 1 );
60
+ CHECK_ILLEGAL (CTX , secp256k1_ecdh_xonly (CTX , NULL , x32 , s_one , NULL , NULL ));
61
+ CHECK_ILLEGAL (CTX , secp256k1_ecdh_xonly (CTX , res , NULL , s_one , NULL , NULL ));
62
+ CHECK_ILLEGAL (CTX , secp256k1_ecdh_xonly (CTX , res , x32 , NULL , NULL , NULL ));
63
+ CHECK (secp256k1_ecdh_xonly (CTX , res , x32 , s_one , NULL , NULL ) == 1 );
64
+ memset (x32 , 205 , 32 ); /* sum(205*256^j, j=0..31) is not a valid x coordinate. */
65
+ CHECK (secp256k1_ecdh_xonly (CTX , res , x32 , s_one , NULL , NULL ) == 0 );
41
66
}
42
67
43
68
static void test_ecdh_generator_basepoint (void ) {
44
69
unsigned char s_one [32 ] = { 0 };
70
+ unsigned char x32_g [32 ];
45
71
secp256k1_pubkey point [2 ];
46
72
int i ;
47
73
48
74
s_one [31 ] = 1 ;
75
+ CHECK (secp256k1_ec_pubkey_create (CTX , & point [0 ], s_one ) == 1 );
76
+ secp256k1_fe_get_b32 (x32_g , & secp256k1_ge_const_g .x );
77
+
49
78
/* Check against pubkey creation when the basepoint is the generator */
50
79
for (i = 0 ; i < 2 * COUNT ; ++ i ) {
51
80
secp256k1_sha256 sha ;
@@ -59,7 +88,6 @@ static void test_ecdh_generator_basepoint(void) {
59
88
random_scalar_order (& s );
60
89
secp256k1_scalar_get_b32 (s_b32 , & s );
61
90
62
- CHECK (secp256k1_ec_pubkey_create (CTX , & point [0 ], s_one ) == 1 );
63
91
CHECK (secp256k1_ec_pubkey_create (CTX , & point [1 ], s_b32 ) == 1 );
64
92
65
93
/* compute using ECDH function with custom hash function */
@@ -69,6 +97,11 @@ static void test_ecdh_generator_basepoint(void) {
69
97
/* compare */
70
98
CHECK (secp256k1_memcmp_var (output_ecdh , point_ser , 65 ) == 0 );
71
99
100
+ /* Do the same with x-only ECDH. */
101
+ CHECK (secp256k1_ecdh_xonly (CTX , output_ecdh , x32_g , s_b32 , ecdh_xonly_hash_function_custom , NULL ) == 1 );
102
+ /* compare */
103
+ CHECK (secp256k1_memcmp_var (output_ecdh , point_ser + 1 , 32 ) == 0 );
104
+
72
105
/* compute using ECDH function with default hash function */
73
106
CHECK (secp256k1_ecdh (CTX , output_ecdh , & point [0 ], s_b32 , NULL , NULL ) == 1 );
74
107
/* compute "explicitly" */
@@ -78,6 +111,15 @@ static void test_ecdh_generator_basepoint(void) {
78
111
secp256k1_sha256_finalize (& sha , output_ser );
79
112
/* compare */
80
113
CHECK (secp256k1_memcmp_var (output_ecdh , output_ser , 32 ) == 0 );
114
+
115
+ /* And the same with x-only ECDH. */
116
+ CHECK (secp256k1_ecdh_xonly (CTX , output_ecdh , x32_g , s_b32 , NULL , NULL ) == 1 );
117
+ /* compute "explicitly" */
118
+ secp256k1_sha256_initialize (& sha );
119
+ secp256k1_sha256_write (& sha , point_ser + 1 , 32 );
120
+ secp256k1_sha256_finalize (& sha , output_ser );
121
+ /* compare */
122
+ CHECK (secp256k1_memcmp_var (output_ecdh , output_ser , 32 ) == 0 );
81
123
}
82
124
}
83
125
@@ -91,13 +133,16 @@ static void test_bad_scalar(void) {
91
133
};
92
134
unsigned char s_rand [32 ] = { 0 };
93
135
unsigned char output [32 ];
136
+ unsigned char point_ser [33 ];
94
137
secp256k1_scalar rand ;
95
138
secp256k1_pubkey point ;
139
+ size_t point_ser_len = sizeof (point_ser );
96
140
97
141
/* Create random point */
98
142
random_scalar_order (& rand );
99
143
secp256k1_scalar_get_b32 (s_rand , & rand );
100
144
CHECK (secp256k1_ec_pubkey_create (CTX , & point , s_rand ) == 1 );
145
+ CHECK (secp256k1_ec_pubkey_serialize (CTX , point_ser , & point_ser_len , & point , SECP256K1_EC_COMPRESSED ) == 1 );
101
146
102
147
/* Try to multiply it by bad values */
103
148
CHECK (secp256k1_ecdh (CTX , output , & point , s_zero , NULL , NULL ) == 0 );
@@ -106,39 +151,63 @@ static void test_bad_scalar(void) {
106
151
s_overflow [31 ] -= 1 ;
107
152
CHECK (secp256k1_ecdh (CTX , output , & point , s_overflow , NULL , NULL ) == 1 );
108
153
154
+ /* And repeat for x-only. */
155
+ s_overflow [31 ] += 1 ;
156
+ CHECK (secp256k1_ecdh_xonly (CTX , output , point_ser + 1 , s_zero , NULL , NULL ) == 0 );
157
+ CHECK (secp256k1_ecdh_xonly (CTX , output , point_ser + 1 , s_overflow , NULL , NULL ) == 0 );
158
+ s_overflow [31 ] -= 1 ;
159
+ CHECK (secp256k1_ecdh_xonly (CTX , output , point_ser + 1 , s_overflow , NULL , NULL ) == 1 );
160
+
109
161
/* Hash function failure results in ecdh failure */
110
162
CHECK (secp256k1_ecdh (CTX , output , & point , s_overflow , ecdh_hash_function_test_fail , NULL ) == 0 );
163
+ CHECK (secp256k1_ecdh_xonly (CTX , output , point_ser , s_overflow , ecdh_xonly_hash_function_test_fail , NULL ) == 0 );
111
164
}
112
165
113
166
/** Test that ECDH(sG, 1/s) == ECDH((1/s)G, s) == ECDH(G, 1) for a few random s. */
114
167
static void test_result_basepoint (void ) {
115
168
secp256k1_pubkey point ;
116
169
secp256k1_scalar rand ;
170
+ unsigned char point_ser [33 ];
171
+ unsigned char x32_g [32 ];
117
172
unsigned char s [32 ];
118
173
unsigned char s_inv [32 ];
119
174
unsigned char out [32 ];
120
175
unsigned char out_inv [32 ];
121
176
unsigned char out_base [32 ];
177
+ unsigned char out_base_xonly [32 ];
178
+ size_t point_ser_len ;
122
179
int i ;
123
180
124
181
unsigned char s_one [32 ] = { 0 };
125
182
s_one [31 ] = 1 ;
183
+ secp256k1_fe_get_b32 (x32_g , & secp256k1_ge_const_g .x );
126
184
CHECK (secp256k1_ec_pubkey_create (CTX , & point , s_one ) == 1 );
127
185
CHECK (secp256k1_ecdh (CTX , out_base , & point , s_one , NULL , NULL ) == 1 );
186
+ CHECK (secp256k1_ecdh_xonly (CTX , out_base_xonly , x32_g , s_one , NULL , NULL ) == 1 );
128
187
129
188
for (i = 0 ; i < 2 * COUNT ; i ++ ) {
130
189
random_scalar_order (& rand );
131
190
secp256k1_scalar_get_b32 (s , & rand );
132
- secp256k1_scalar_inverse (& rand , & rand );
191
+ secp256k1_scalar_inverse_var (& rand , & rand );
133
192
secp256k1_scalar_get_b32 (s_inv , & rand );
134
193
135
194
CHECK (secp256k1_ec_pubkey_create (CTX , & point , s ) == 1 );
195
+ point_ser_len = sizeof (point_ser );
196
+ CHECK (secp256k1_ec_pubkey_serialize (CTX , point_ser , & point_ser_len , & point , SECP256K1_EC_COMPRESSED ));
197
+
136
198
CHECK (secp256k1_ecdh (CTX , out , & point , s_inv , NULL , NULL ) == 1 );
137
199
CHECK (secp256k1_memcmp_var (out , out_base , 32 ) == 0 );
200
+ CHECK (secp256k1_ecdh_xonly (CTX , out , point_ser + 1 , s_inv , NULL , NULL ) == 1 );
201
+ CHECK (secp256k1_memcmp_var (out , out_base_xonly , 32 ) == 0 );
138
202
139
203
CHECK (secp256k1_ec_pubkey_create (CTX , & point , s_inv ) == 1 );
140
204
CHECK (secp256k1_ecdh (CTX , out_inv , & point , s , NULL , NULL ) == 1 );
205
+ point_ser_len = sizeof (point_ser );
206
+ CHECK (secp256k1_ec_pubkey_serialize (CTX , point_ser , & point_ser_len , & point , SECP256K1_EC_COMPRESSED ));
207
+
141
208
CHECK (secp256k1_memcmp_var (out_inv , out_base , 32 ) == 0 );
209
+ CHECK (secp256k1_ecdh_xonly (CTX , out_inv , point_ser + 1 , s , NULL , NULL ) == 1 );
210
+ CHECK (secp256k1_memcmp_var (out_inv , out_base_xonly , 32 ) == 0 );
142
211
}
143
212
}
144
213
0 commit comments