2 * Copyright (c) 2013, Kenneth MacKay
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 #include "src/shared/ecc.h"
41 static void vli_print(uint8_t *vli, size_t size)
44 printf("%02X ", vli[size - 1]);
49 #define PAIR_COUNT 200
51 static void test_multi(void)
53 uint8_t public1[64], public2[64];
54 uint8_t private1[32], private2[32];
55 uint8_t shared1[32], shared2[32];
59 g_print("Testing %u random private key pairs", PAIR_COUNT);
61 for (i = 0; i < PAIR_COUNT; i++) {
62 if (g_test_verbose()) {
67 ecc_make_key(public1, private1);
68 ecc_make_key(public2, private2);
70 ecdh_shared_secret(public1, private2, shared1);
71 ecdh_shared_secret(public2, private1, shared2);
73 if (memcmp(shared1, shared2, sizeof(shared1)) != 0) {
74 printf("Shared secrets are not identical!\n");
75 printf("Shared secret 1 = ");
76 vli_print(shared1, sizeof(shared1));
78 printf("Shared secret 2 = ");
79 vli_print(shared2, sizeof(shared2));
81 printf("Private key 1 = ");
82 vli_print(private1, sizeof(private1));
84 printf("Private key 2 = ");
85 vli_print(private2, sizeof(private2));
87 g_assert_not_reached();
95 static void print_buf(const char *label, uint8_t *buf, size_t len)
101 for (i = 0; i < len; i++)
102 printf("%02x", buf[i]);
107 static int test_sample(uint8_t priv_a[32], uint8_t priv_b[32],
108 uint8_t pub_a[64], uint8_t pub_b[64],
111 uint8_t dhkey_a[32], dhkey_b[32];
114 ecdh_shared_secret(pub_b, priv_a, dhkey_a);
115 ecdh_shared_secret(pub_a, priv_b, dhkey_b);
117 if (g_test_verbose()) {
118 print_buf("DHKey ", dhkey, 32);
119 print_buf("DHKey A", dhkey_a, 32);
120 print_buf("DHKey B", dhkey_b, 32);
123 if (memcmp(dhkey_a, dhkey, 32)) {
124 if (g_test_verbose())
125 printf("DHKey A doesn't match!\n");
128 if (g_test_verbose())
129 printf("DHKey A matches :)\n");
132 if (memcmp(dhkey_b, dhkey, 32)) {
133 if (g_test_verbose())
134 printf("DHKey B doesn't match!\n");
137 if (g_test_verbose())
138 printf("DHKey B matches :)\n");
144 static void test_sample_1(void)
146 uint8_t priv_a[32] = { 0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
147 0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
148 0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
149 0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
151 uint8_t priv_b[32] = { 0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
152 0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
153 0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
154 0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55,
156 uint8_t pub_a[64] = { 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
157 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
158 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
159 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
161 0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
162 0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
163 0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
164 0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
166 uint8_t pub_b[64] = { 0x90, 0xa1, 0xaa, 0x2f, 0xb2, 0x77, 0x90, 0x55,
167 0x9f, 0xa6, 0x15, 0x86, 0xfd, 0x8a, 0xb5, 0x47,
168 0x00, 0x4c, 0x9e, 0xf1, 0x84, 0x22, 0x59, 0x09,
169 0x96, 0x1d, 0xaf, 0x1f, 0xf0, 0xf0, 0xa1, 0x1e,
171 0x4a, 0x21, 0xb1, 0x15, 0xf9, 0xaf, 0x89, 0x5f,
172 0x76, 0x36, 0x8e, 0xe2, 0x30, 0x11, 0x2d, 0x47,
173 0x60, 0x51, 0xb8, 0x9a, 0x3a, 0x70, 0x56, 0x73,
174 0x37, 0xad, 0x9d, 0x42, 0x3e, 0xf3, 0x55, 0x4c,
176 uint8_t dhkey[32] = { 0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86,
177 0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99,
178 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
179 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec,
183 fails = test_sample(priv_a, priv_b, pub_a, pub_b, dhkey);
185 g_assert(fails == 0);
188 static void test_sample_2(void)
190 uint8_t priv_a[32] = { 0x63, 0x76, 0x45, 0xd0, 0xf7, 0x73, 0xac, 0xb7,
191 0xff, 0xdd, 0x03, 0x72, 0xb9, 0x72, 0x85, 0xb4,
192 0x41, 0xb6, 0x5d, 0x0c, 0x5d, 0x54, 0x84, 0x60,
193 0x1a, 0xa3, 0x9a, 0x3c, 0x69, 0x16, 0xa5, 0x06,
195 uint8_t priv_b[32] = { 0xba, 0x30, 0x55, 0x50, 0x19, 0xa2, 0xca, 0xa3,
196 0xa5, 0x29, 0x08, 0xc6, 0xb5, 0x03, 0x88, 0x7e,
197 0x03, 0x2b, 0x50, 0x73, 0xd4, 0x2e, 0x50, 0x97,
198 0x64, 0xcd, 0x72, 0x0d, 0x67, 0xa0, 0x9a, 0x52,
200 uint8_t pub_a[64] = { 0xdd, 0x78, 0x5c, 0x74, 0x03, 0x9b, 0x7e, 0x98,
201 0xcb, 0x94, 0x87, 0x4a, 0xad, 0xfa, 0xf8, 0xd5,
202 0x43, 0x3e, 0x5c, 0xaf, 0xea, 0xb5, 0x4c, 0xf4,
203 0x9e, 0x80, 0x79, 0x57, 0x7b, 0xa4, 0x31, 0x2c,
205 0x4f, 0x5d, 0x71, 0x43, 0x77, 0x43, 0xf8, 0xea,
206 0xd4, 0x3e, 0xbd, 0x17, 0x91, 0x10, 0x21, 0xd0,
207 0x1f, 0x87, 0x43, 0x8e, 0x40, 0xe2, 0x52, 0xcd,
208 0xbe, 0xdf, 0x98, 0x38, 0x18, 0x12, 0x95, 0x91,
210 uint8_t pub_b[64] = { 0xcc, 0x00, 0x65, 0xe1, 0xf5, 0x6c, 0x0d, 0xcf,
211 0xec, 0x96, 0x47, 0x20, 0x66, 0xc9, 0xdb, 0x84,
212 0x81, 0x75, 0xa8, 0x4d, 0xc0, 0xdf, 0xc7, 0x9d,
213 0x1b, 0x3f, 0x3d, 0xf2, 0x3f, 0xe4, 0x65, 0xf4,
215 0x79, 0xb2, 0xec, 0xd8, 0xca, 0x55, 0xa1, 0xa8,
216 0x43, 0x4d, 0x6b, 0xca, 0x10, 0xb0, 0xc2, 0x01,
217 0xc2, 0x33, 0x4e, 0x16, 0x24, 0xc4, 0xef, 0xee,
218 0x99, 0xd8, 0xbb, 0xbc, 0x48, 0xd0, 0x01, 0x02,
220 uint8_t dhkey[32] = { 0x69, 0xeb, 0x21, 0x32, 0xf2, 0xc6, 0x05, 0x41,
221 0x60, 0x19, 0xcd, 0x5e, 0x94, 0xe1, 0xe6, 0x5f,
222 0x33, 0x07, 0xe3, 0x38, 0x4b, 0x68, 0xe5, 0x62,
223 0x3f, 0x88, 0x6d, 0x2f, 0x3a, 0x84, 0x85, 0xab,
227 fails = test_sample(priv_a, priv_b, pub_a, pub_b, dhkey);
229 g_assert(fails == 0);
232 static void test_sample_3(void)
234 uint8_t priv_a[32] = { 0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
235 0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
236 0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
237 0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
239 uint8_t pub_a[64] = { 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
240 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
241 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
242 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
244 0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
245 0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
246 0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
247 0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
249 uint8_t dhkey[32] = { 0x2d, 0xab, 0x00, 0x48, 0xcb, 0xb3, 0x7b, 0xda,
250 0x55, 0x7b, 0x8b, 0x72, 0xa8, 0x57, 0x87, 0xc3,
251 0x87, 0x27, 0x99, 0x32, 0xfc, 0x79, 0x5f, 0xae,
252 0x7c, 0x1c, 0xf9, 0x49, 0xe6, 0xd7, 0xaa, 0x70,
256 fails = test_sample(priv_a, priv_a, pub_a, pub_a, dhkey);
258 g_assert(fails == 0);
261 int main(int argc, char *argv[])
263 g_test_init(&argc, &argv, NULL);
265 g_test_add_func("/ecdh/multi", test_multi);
267 g_test_add_func("/ecdh/sample/1", test_sample_1);
268 g_test_add_func("/ecdh/sample/2", test_sample_2);
269 g_test_add_func("/ecdh/sample/3", test_sample_3);