990c29865bfeab6df22fe4d36f24a3b85bbb3a2c
[strongswan.git] / src / libstrongswan / tests / suites / test_ntru.c
1 /*
2 * Copyright (C) 2013-2014 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "test_suite.h"
17
18 #include <tests/utils/test_rng.h>
19 #include <plugins/ntru/ntru_drbg.h>
20 #include <plugins/ntru/ntru_mgf1.h>
21 #include <plugins/ntru/ntru_trits.h>
22 #include <plugins/ntru/ntru_poly.h>
23 #include <plugins/ntru/ntru_param_set.h>
24 #include <plugins/ntru/ntru_private_key.h>
25 #include <utils/test.h>
26
27 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_drbg_create, ntru_drbg_t*,
28 u_int32_t strength, chunk_t pers_str, rng_t *entropy)
29
30 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_mgf1_create, ntru_mgf1_t*,
31 hash_algorithm_t alg, chunk_t seed, bool hash_seed)
32
33 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_trits_create, ntru_trits_t*,
34 size_t len, hash_algorithm_t alg, chunk_t seed)
35
36 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_poly_create_from_seed, ntru_poly_t*,
37 hash_algorithm_t alg, chunk_t seed, uint8_t c_bits,
38 uint16_t N, uint16_t q, uint32_t indices_len_p,
39 uint32_t indices_len_m, bool is_product_form)
40
41 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_poly_create_from_data, ntru_poly_t*,
42 u_int16_t *data, uint16_t N, uint16_t q,
43 uint32_t indices_len_p, uint32_t indices_len_m,
44 bool is_product_form)
45
46 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_param_set_get_by_id, ntru_param_set_t* ,
47 ntru_param_set_id_t id)
48
49 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_private_key_create, ntru_private_key_t*,
50 ntru_drbg_t *drbg, ntru_param_set_t *params)
51
52 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_private_key_create_from_data, ntru_private_key_t*,
53 ntru_drbg_t *drbg, chunk_t data)
54
55 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_public_key_create_from_data, ntru_public_key_t*,
56 ntru_drbg_t *drbg, chunk_t data)
57
58 /**
59 * NTRU parameter sets to test
60 */
61 static struct {
62 diffie_hellman_group_t group;
63 char *group_name;
64 } params[] = {
65 { NTRU_112_BIT, "NTRU_112" },
66 { NTRU_128_BIT, "NTRU_128" },
67 { NTRU_192_BIT, "NTRU_192" },
68 { NTRU_256_BIT, "NTRU_256" }
69 };
70
71 /**
72 * NTRU parameter set selection
73 */
74 char *parameter_sets[] = {
75 "x9_98_speed", "x9_98_bandwidth", "x9_98_balance", "optimum"
76 };
77
78 typedef struct {
79 u_int32_t requested;
80 u_int32_t standard;
81 }strength_t;
82
83 strength_t strengths[] = {
84 { 80, 112 },
85 { 112, 112 },
86 { 120, 128 },
87 { 128, 128 },
88 { 150, 192 },
89 { 192, 192 },
90 { 200, 256 },
91 { 256, 256 },
92 { 512, 0 }
93 };
94
95 START_TEST(test_ntru_drbg_strength)
96 {
97 ntru_drbg_t *drbg;
98 rng_t *entropy;
99
100 entropy = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
101 ck_assert(entropy != NULL);
102
103 drbg = TEST_FUNCTION(ntru, ntru_drbg_create, strengths[_i].requested,
104 chunk_empty, entropy);
105 if (strengths[_i].standard)
106 {
107 ck_assert(drbg != NULL);
108 ck_assert(drbg->get_strength(drbg) == strengths[_i].standard);
109 drbg->destroy(drbg);
110 }
111 else
112 {
113 ck_assert(drbg == NULL);
114 }
115 entropy->destroy(entropy);
116 }
117 END_TEST
118
119 typedef struct {
120 chunk_t pers_str;
121 chunk_t entropy;
122 chunk_t out;
123 } drbg_test_t;
124
125 /**
126 * NIST SP 800-90A Deterministic Random Generator Validation System (DRBGVS)
127 */
128 drbg_test_t drbg_tests[] = {
129 /* SHA-256 test case 1 - count 0 */
130 { { NULL, 0 },
131 chunk_from_chars(0x06, 0x03, 0x2c, 0xd5, 0xee, 0xd3, 0x3f, 0x39,
132 0x26, 0x5f, 0x49, 0xec, 0xb1, 0x42, 0xc5, 0x11,
133 0xda, 0x9a, 0xff, 0x2a, 0xf7, 0x12, 0x03, 0xbf,
134 0xfa, 0xf3, 0x4a, 0x9c, 0xa5, 0xbd, 0x9c, 0x0d,
135 0x0e, 0x66, 0xf7, 0x1e, 0xdc, 0x43, 0xe4, 0x2a,
136 0x45, 0xad, 0x3c, 0x6f, 0xc6, 0xcd, 0xc4, 0xdf,
137 0x01, 0x92, 0x0a, 0x4e, 0x66, 0x9e, 0xd3, 0xa8,
138 0x5a, 0xe8, 0xa3, 0x3b, 0x35, 0xa7, 0x4a, 0xd7,
139 0xfb, 0x2a, 0x6b, 0xb4, 0xcf, 0x39, 0x5c, 0xe0,
140 0x03, 0x34, 0xa9, 0xc9, 0xa5, 0xa5, 0xd5, 0x52),
141 chunk_from_chars(0x76, 0xfc, 0x79, 0xfe, 0x9b, 0x50, 0xbe, 0xcc,
142 0xc9, 0x91, 0xa1, 0x1b, 0x56, 0x35, 0x78, 0x3a,
143 0x83, 0x53, 0x6a, 0xdd, 0x03, 0xc1, 0x57, 0xfb,
144 0x30, 0x64, 0x5e, 0x61, 0x1c, 0x28, 0x98, 0xbb,
145 0x2b, 0x1b, 0xc2, 0x15, 0x00, 0x02, 0x09, 0x20,
146 0x8c, 0xd5, 0x06, 0xcb, 0x28, 0xda, 0x2a, 0x51,
147 0xbd, 0xb0, 0x38, 0x26, 0xaa, 0xf2, 0xbd, 0x23,
148 0x35, 0xd5, 0x76, 0xd5, 0x19, 0x16, 0x08, 0x42,
149 0xe7, 0x15, 0x8a, 0xd0, 0x94, 0x9d, 0x1a, 0x9e,
150 0xc3, 0xe6, 0x6e, 0xa1, 0xb1, 0xa0, 0x64, 0xb0,
151 0x05, 0xde, 0x91, 0x4e, 0xac, 0x2e, 0x9d, 0x4f,
152 0x2d, 0x72, 0xa8, 0x61, 0x6a, 0x80, 0x22, 0x54,
153 0x22, 0x91, 0x82, 0x50, 0xff, 0x66, 0xa4, 0x1b,
154 0xd2, 0xf8, 0x64, 0xa6, 0xa3, 0x8c, 0xc5, 0xb6,
155 0x49, 0x9d, 0xc4, 0x3f, 0x7f, 0x2b, 0xd0, 0x9e,
156 0x1e, 0x0f, 0x8f, 0x58, 0x85, 0x93, 0x51, 0x24)
157 },
158 /* SHA-256 test case 3 - count 0 */
159 { chunk_from_chars(0xf2, 0xe5, 0x8f, 0xe6, 0x0a, 0x3a, 0xfc, 0x59,
160 0xda, 0xd3, 0x75, 0x95, 0x41, 0x5f, 0xfd, 0x31,
161 0x8c, 0xcf, 0x69, 0xd6, 0x77, 0x80, 0xf6, 0xfa,
162 0x07, 0x97, 0xdc, 0x9a, 0xa4, 0x3e, 0x14, 0x4c),
163 chunk_from_chars(0xfa, 0x0e, 0xe1, 0xfe, 0x39, 0xc7, 0xc3, 0x90,
164 0xaa, 0x94, 0x15, 0x9d, 0x0d, 0xe9, 0x75, 0x64,
165 0x34, 0x2b, 0x59, 0x17, 0x77, 0xf3, 0xe5, 0xf6,
166 0xa4, 0xba, 0x2a, 0xea, 0x34, 0x2e, 0xc8, 0x40,
167 0xdd, 0x08, 0x20, 0x65, 0x5c, 0xb2, 0xff, 0xdb,
168 0x0d, 0xa9, 0xe9, 0x31, 0x0a, 0x67, 0xc9, 0xe5,
169 0xe0, 0x62, 0x9b, 0x6d, 0x79, 0x75, 0xdd, 0xfa,
170 0x96, 0xa3, 0x99, 0x64, 0x87, 0x40, 0xe6, 0x0f,
171 0x1f, 0x95, 0x57, 0xdc, 0x58, 0xb3, 0xd7, 0x41,
172 0x5f, 0x9b, 0xa9, 0xd4, 0xdb, 0xb5, 0x01, 0xf6),
173 chunk_from_chars(0xf9, 0x2d, 0x4c, 0xf9, 0x9a, 0x53, 0x5b, 0x20,
174 0x22, 0x2a, 0x52, 0xa6, 0x8d, 0xb0, 0x4c, 0x5a,
175 0xf6, 0xf5, 0xff, 0xc7, 0xb6, 0x6a, 0x47, 0x3a,
176 0x37, 0xa2, 0x56, 0xbd, 0x8d, 0x29, 0x8f, 0x9b,
177 0x4a, 0xa4, 0xaf, 0x7e, 0x8d, 0x18, 0x1e, 0x02,
178 0x36, 0x79, 0x03, 0xf9, 0x3b, 0xdb, 0x74, 0x4c,
179 0x6c, 0x2f, 0x3f, 0x34, 0x72, 0x62, 0x6b, 0x40,
180 0xce, 0x9b, 0xd6, 0xa7, 0x0e, 0x7b, 0x8f, 0x93,
181 0x99, 0x2a, 0x16, 0xa7, 0x6f, 0xab, 0x6b, 0x5f,
182 0x16, 0x25, 0x68, 0xe0, 0x8e, 0xe6, 0xc3, 0xe8,
183 0x04, 0xae, 0xfd, 0x95, 0x2d, 0xdd, 0x3a, 0xcb,
184 0x79, 0x1c, 0x50, 0xf2, 0xad, 0x69, 0xe9, 0xa0,
185 0x40, 0x28, 0xa0, 0x6a, 0x9c, 0x01, 0xd3, 0xa6,
186 0x2a, 0xca, 0x2a, 0xaf, 0x6e, 0xfe, 0x69, 0xed,
187 0x97, 0xa0, 0x16, 0x21, 0x3a, 0x2d, 0xd6, 0x42,
188 0xb4, 0x88, 0x67, 0x64, 0x07, 0x2d, 0x9c, 0xbe)
189 },
190 /* SHA-256 test case 5 - count 0 */
191 { { NULL, 0 },
192 chunk_from_chars(0xff, 0x0c, 0xdd, 0x55, 0x5c, 0x60, 0x46, 0x47,
193 0x60, 0xb2, 0x89, 0xb7, 0xbc, 0x1f, 0x81, 0x1a,
194 0x41, 0xff, 0xf7, 0x2d, 0xe5, 0x90, 0x83, 0x85,
195 0x8c, 0x02, 0x0a, 0x10, 0x53, 0xbd, 0xc7, 0x4a,
196 0x7b, 0xc0, 0x99, 0x28, 0x5a, 0xd5, 0x62, 0x19,
197 0x93, 0xb6, 0x39, 0xc4, 0xa9, 0x4c, 0x37, 0x6b,
198 0x14, 0xfc, 0x6c, 0x9b, 0x17, 0x8d, 0xb6, 0x44,
199 0xa8, 0xcd, 0x71, 0x30, 0xa4, 0xcf, 0x05, 0x16,
200 0x78, 0xc8, 0xf4, 0xfa, 0x8f, 0x24, 0xc2, 0x7b,
201 0x0a, 0x53, 0x13, 0x38, 0xa5, 0xce, 0x85, 0x89),
202 chunk_from_chars(0x2f, 0x26, 0x20, 0x34, 0x7b, 0xdd, 0xca, 0xa2,
203 0x94, 0x36, 0x85, 0x34, 0x6b, 0xbf, 0x31, 0xc4,
204 0x40, 0x81, 0xf8, 0x66, 0x5f, 0x3d, 0xdb, 0x2b,
205 0x42, 0xae, 0x14, 0x16, 0xa7, 0x4c, 0x4b, 0x77,
206 0xfa, 0xb3, 0xfa, 0x19, 0xae, 0xec, 0xc5, 0x47,
207 0xe7, 0x6c, 0x8c, 0xbe, 0x6a, 0xd1, 0xf1, 0x00,
208 0xa3, 0xfc, 0x8b, 0x2c, 0xe2, 0xa1, 0xea, 0x3a,
209 0x3d, 0xd7, 0xcf, 0xad, 0x46, 0xc1, 0xb2, 0x78,
210 0x30, 0xb9, 0x40, 0xba, 0x18, 0xd0, 0x9e, 0x9b,
211 0x7f, 0xa9, 0x02, 0xbb, 0x76, 0x06, 0x69, 0xb1,
212 0x73, 0x5c, 0xc7, 0xb7, 0xbd, 0x39, 0x05, 0x2d,
213 0xa7, 0xf2, 0x62, 0x6f, 0xa8, 0x70, 0x00, 0xcf,
214 0xfa, 0xda, 0x41, 0x00, 0x19, 0xd0, 0x53, 0x38,
215 0x6a, 0xd8, 0x08, 0xbd, 0x3c, 0x0c, 0xfc, 0xf5,
216 0x6b, 0x91, 0x87, 0x9e, 0xb8, 0xd3, 0xf9, 0x32,
217 0xee, 0x2d, 0x18, 0x5e, 0x54, 0xf3, 0x1b, 0x74)
218 },
219 /* SHA-256 test case 7 - count 0 */
220 { chunk_from_chars(0x40, 0x93, 0x3f, 0xdc, 0xce, 0x41, 0x59, 0xb0,
221 0x95, 0x51, 0x11, 0xf8, 0x44, 0x47, 0x1b, 0x0d,
222 0xb8, 0x5b, 0x73, 0xbd, 0xd2, 0xb7, 0x8c, 0x46,
223 0x8d, 0xd3, 0x9e, 0x2a, 0x9b, 0x29, 0xae, 0xf2),
224 chunk_from_chars(0x28, 0xba, 0x1a, 0x66, 0x16, 0x32, 0xef, 0xc8,
225 0xec, 0xce, 0xd5, 0xf5, 0x1b, 0x79, 0x13, 0x00,
226 0xfb, 0x3b, 0x55, 0xb0, 0x5d, 0x04, 0x17, 0x08,
227 0x63, 0x8d, 0xe4, 0xbe, 0xb7, 0x57, 0xa9, 0xe5,
228 0x76, 0x82, 0x87, 0x96, 0xaf, 0xf0, 0x7f, 0x55,
229 0x79, 0x5c, 0xb5, 0x47, 0x13, 0xc7, 0x7e, 0xd4,
230 0xa5, 0xf5, 0x42, 0xb0, 0x4a, 0xaa, 0x5d, 0xbc,
231 0x93, 0x1e, 0x47, 0x01, 0x9f, 0xeb, 0x38, 0x96,
232 0x26, 0x16, 0xc5, 0x7a, 0xf0, 0x9b, 0x7c, 0x1d,
233 0xf8, 0x3f, 0x2b, 0x86, 0x0f, 0xf7, 0x65, 0x86),
234 chunk_from_chars(0x65, 0xe5, 0xaa, 0x47, 0xb3, 0x85, 0xf1, 0xea,
235 0x42, 0xb2, 0x31, 0xb9, 0xfe, 0x74, 0x42, 0x53,
236 0xb8, 0x59, 0x88, 0x59, 0xd7, 0x01, 0x1e, 0x52,
237 0x5f, 0x5a, 0x2a, 0x1a, 0xd3, 0x2a, 0x97, 0x2a,
238 0x85, 0x08, 0x02, 0xc6, 0x0a, 0x2b, 0xe1, 0x9b,
239 0xe2, 0x70, 0x06, 0x3a, 0x3c, 0xfb, 0xea, 0xae,
240 0x95, 0x4f, 0x10, 0xb1, 0x22, 0x35, 0x2d, 0xe6,
241 0xa0, 0x8a, 0xc4, 0x10, 0xe0, 0x99, 0x16, 0x53,
242 0xaa, 0xb2, 0x71, 0xb3, 0x60, 0xfe, 0x91, 0x91,
243 0xcf, 0x5a, 0xdd, 0xcc, 0xcc, 0xed, 0x8c, 0x4a,
244 0xcf, 0xb6, 0x14, 0x57, 0x04, 0x99, 0x92, 0x98,
245 0x8f, 0xd7, 0xa9, 0xac, 0xca, 0x1f, 0x1b, 0xca,
246 0x35, 0xf1, 0x47, 0x58, 0x13, 0x69, 0x4a, 0x39,
247 0x98, 0x8e, 0x5f, 0xac, 0x9f, 0x4a, 0xc0, 0x57,
248 0x22, 0x86, 0xbc, 0x46, 0x25, 0x82, 0xad, 0x0a,
249 0xf7, 0x8a, 0xb3, 0xb8, 0x5e, 0xc1, 0x7a, 0x25)
250 }
251 };
252
253 START_TEST(test_ntru_drbg)
254 {
255 ntru_drbg_t *drbg;
256 rng_t *entropy;
257 chunk_t out;
258
259 out = chunk_alloc(128);
260 entropy = test_rng_create(drbg_tests[_i].entropy);
261 drbg = TEST_FUNCTION(ntru, ntru_drbg_create, 256, drbg_tests[_i].pers_str,
262 entropy);
263 ck_assert(drbg != NULL);
264 ck_assert(drbg->reseed(drbg));
265 ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
266 ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
267 ck_assert(chunk_equals(out, drbg_tests[_i].out));
268 drbg->destroy(drbg);
269 entropy->destroy(entropy);
270 chunk_free(&out);
271 }
272 END_TEST
273
274 START_TEST(test_ntru_drbg_reseed)
275 {
276 ntru_drbg_t *drbg;
277 rng_t *entropy;
278 chunk_t out;
279
280 lib->settings->set_int(lib->settings,
281 "libstrongswan.plugins.ntru.max_drbg_requests", 2);
282 out = chunk_alloc(128);
283 entropy = test_rng_create(drbg_tests[0].entropy);
284 drbg = TEST_FUNCTION(ntru, ntru_drbg_create, 256, chunk_empty, entropy);
285
286 /* bad output parameters */
287 ck_assert(!drbg->generate(drbg, 256, 0, out.ptr));
288 ck_assert(!drbg->generate(drbg, 256, 128, NULL));
289
290 /* no reseeding occurs */
291 ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
292 ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
293
294 /* consuming remaining entropy */
295 ck_assert(entropy->get_bytes(entropy, 32, out.ptr));
296
297 /* no entropy available for automatic reseeding */
298 ck_assert(!drbg->generate(drbg, 256, 128, out.ptr));
299 drbg->destroy(drbg);
300
301 /* no entropy available for DRBG instantiation */
302 drbg = TEST_FUNCTION(ntru, ntru_drbg_create, 256, chunk_empty, entropy);
303 ck_assert(drbg == NULL);
304 entropy->destroy(entropy);
305
306 /* one automatic reseeding occurs */
307 entropy = test_rng_create(drbg_tests[0].entropy);
308 drbg = TEST_FUNCTION(ntru, ntru_drbg_create, 256, chunk_empty, entropy);
309 ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
310 ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
311 ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
312
313 /* no entropy left */
314 ck_assert(!entropy->get_bytes(entropy, 32, out.ptr));
315
316 drbg->destroy(drbg);
317 entropy->destroy(entropy);
318 chunk_free(&out);
319 lib->settings->set_int(lib->settings,
320 "libstrongswan.plugins.ntru.max_drbg_requests", 2000);
321 }
322 END_TEST
323
324 typedef struct {
325 uint8_t c_bits;
326 uint16_t N;
327 uint16_t q;
328 bool is_product_form;
329 uint32_t indices_len;
330 uint32_t indices_size;
331 uint16_t *indices;
332 } poly_test_t;
333
334 typedef struct {
335 hash_algorithm_t alg;
336 size_t hash_size;
337 size_t ml1, ml2, ml3, seed_len;
338 chunk_t seed;
339 chunk_t hashed_seed;
340 chunk_t mask;
341 chunk_t trits;
342 poly_test_t poly_test[2];
343 } mgf1_test_t;
344
345 uint16_t indices_ees439ep1[] = {
346 367, 413, 16, 214, 114, 128, 42, 268, 346, 329, 119, 303, 208, 287, 150,
347 3, 45, 321, 110, 109, 272, 430, 80, 305, 51, 381, 322, 140, 207, 315,
348 206, 186, 56, 5, 273, 177, 44, 100, 205, 210, 98, 191, 8, 336
349 };
350
351 uint16_t indices_ees613ep1[] = {
352 245, 391, 251, 428, 301, 2, 176, 296, 461, 224, 590, 215, 250, 91, 395,
353 363, 58, 537, 278, 291, 247, 33, 140, 447, 172, 514, 424, 412, 95, 94,
354 281, 159, 196, 302, 277, 63, 404, 150, 608, 315, 195, 334, 207, 376, 398,
355 0, 309, 486, 516, 86, 267, 139, 130, 38, 141, 258, 21, 341, 526, 388,
356 194, 116, 138, 524, 547, 383, 542, 406, 270, 438, 240, 445, 527, 168, 320,
357 186, 327, 212, 543, 82, 606, 131, 294, 392, 477, 430, 583, 142, 253, 434,
358 134, 458, 559, 414, 162, 407, 580, 577, 191, 109, 554, 523, 32, 62, 297,
359 283, 268, 54, 539, 5
360 };
361
362 uint16_t indices_ees743ep1[] = {
363 285, 62, 136, 655, 460, 35, 450, 208, 340, 212, 61, 234, 454, 52, 520,
364 399, 315, 616, 496, 88, 280, 543, 508, 237, 553, 39, 214, 253, 720, 291,
365 586, 615, 635, 596, 62, 499, 301, 176, 271, 659, 372, 185, 621, 350, 683,
366 180, 717, 509, 641, 738, 666, 171, 639, 606, 353, 706, 237, 358, 410, 423,
367 197, 501, 261, 654, 658, 701, 377, 182, 548, 287, 700, 403, 248, 137
368 };
369
370 uint16_t indices_ees1171ep1[] = {
371 514, 702, 760, 505, 262, 486, 695, 783, 533, 74, 403, 847, 170,1019, 568,
372 676,1057, 277,1021, 238, 203, 884, 124, 87, 65, 93, 131, 881,1102, 133,
373 459, 462, 92, 40, 5,1152,1158, 297, 599, 299, 7, 458, 347, 343, 173,
374 1044, 264, 871, 819, 679, 328, 438, 990, 982, 308,1135, 423, 470, 254, 295,
375 1029, 892, 759, 789, 123, 939, 749, 353,1062, 145, 562, 337, 550, 102, 549,
376 821,1098, 823, 96, 365, 135,1110, 334, 391, 638, 963, 962,1002,1069, 993,
377 983, 649,1056, 399, 385, 715, 582, 799, 161, 512, 629, 979, 250, 37, 213,
378 929, 413, 566, 336, 727, 160, 616,1170, 748, 282,1115, 325, 994, 189, 500,
379 913, 332,1118, 753, 946, 775, 59, 809, 782, 612, 909,1090, 223, 777, 940,
380 866,1032, 471, 298, 969, 192, 411, 721, 476, 910,1045,1027, 812, 352, 487,
381 215, 625, 808, 230, 602, 457, 900, 416, 985, 850, 908, 155, 670, 669,1054,
382 400,1126, 733, 647, 786, 195, 148, 362,1094, 389,1086,1166, 231, 436, 210,
383 333, 824, 785, 826, 658, 472, 639,1046,1028, 519, 422, 80, 924,1089, 547,
384 1157, 579, 2, 508,1040, 998, 902,1058, 600, 220, 805, 945, 140,1117, 179,
385 536, 191
386 };
387
388 /**
389 * MGF1 Mask Generation Function Test Vectors
390 */
391 mgf1_test_t mgf1_tests[] = {
392 { HASH_SHA1, 20, 60, 20, 15, 24,
393 chunk_from_chars(
394 0xED, 0xA5, 0xC3, 0xBC, 0xAF, 0xB3, 0x20, 0x7D,
395 0x14, 0xA1, 0x54, 0xF7, 0x8B, 0x37, 0xF2, 0x8D,
396 0x8C, 0x9B, 0xD5, 0x63, 0x57, 0x38, 0x11, 0xC2,
397 0xB5, 0xCA, 0xBF, 0x06, 0x43, 0x45, 0x19, 0xD5,
398 0xE7, 0x36, 0xD0, 0x29, 0x21, 0xDA, 0x02, 0x20,
399 0x45, 0xF6, 0x5F, 0x0F, 0x10, 0x04, 0x2A, 0xE3,
400 0x6A, 0x1D, 0xD5, 0x9F, 0x1D, 0x66, 0x44, 0x8F,
401 0xFA, 0xC6, 0xCA, 0xA4, 0x6E, 0x3B, 0x00, 0x66,
402 0xA6, 0xC9, 0x80, 0x5C, 0xF5, 0x2D, 0xD7, 0x72,
403 0xC6, 0xD4, 0x4F, 0x30, 0x72, 0xA2, 0xAD, 0xE0,
404 0x33, 0xE8, 0x55, 0xD5, 0xE6, 0xD6, 0x00, 0x1D,
405 0xA8, 0x68, 0xFF, 0x97, 0x36, 0x8A, 0xF4, 0xD6,
406 0xF1, 0xB6, 0x7E, 0x1F, 0x06, 0xCB, 0x57, 0xCB,
407 0x35, 0x38, 0xF2, 0x2D, 0xF6, 0x20),
408 chunk_from_chars(
409 0xF3, 0x9B, 0x0B, 0xB4, 0x97, 0x50, 0xB5, 0xA7,
410 0xE6, 0xBD, 0xDA, 0xD0, 0x9A, 0x52, 0xBE, 0xA0,
411 0x21, 0xC4, 0x90, 0xB6),
412 chunk_from_chars(
413 0x10, 0x43, 0x76, 0x72, 0x6C, 0xDE, 0xA0, 0x0E,
414 0x77, 0x51, 0xFB, 0x58, 0x39, 0x8A, 0x36, 0xE1,
415 0x63, 0x2B, 0xC9, 0x17, 0x56, 0x0C, 0x4B, 0x46,
416 0xA4, 0x07, 0xA4, 0x3B, 0x8E, 0x33, 0x4D, 0xD1,
417 0x65, 0xF1, 0xAC, 0xC8, 0x59, 0x21, 0x32, 0x16,
418 0x44, 0x2B, 0x7F, 0xB2, 0xA8, 0xA7, 0x26, 0x5D,
419 0xE8, 0x02, 0xBE, 0x8E, 0xDC, 0x34, 0xEB, 0x10,
420 0x76, 0x16, 0x8C, 0xDD, 0x90, 0x92, 0x3D, 0x29,
421 0x90, 0x98, 0x46, 0x11, 0x73, 0x53, 0x47, 0xB1,
422 0x2C, 0xD4, 0x83, 0x78, 0x9B, 0x93, 0x2F, 0x5B,
423 0xFC, 0x26, 0xFF, 0x42, 0x08, 0x1F, 0x70, 0x66,
424 0x40, 0x4B, 0xE7, 0x22, 0x3A, 0x56, 0x10, 0x6D,
425 0x4D, 0x29, 0x0B, 0xCE, 0xA6, 0x21, 0xB5, 0x5C,
426 0x71, 0x66, 0x2F, 0x70, 0x35, 0xD8, 0x8A, 0x92,
427 0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14),
428 chunk_from_chars(
429 1, 2, 1, 0, 0, 1, 1, 1, 2, 0, 1, 0, 1, 1, 1, 0, 2, 0, 1, 1,
430 0, 0, 0, 1, 1, 0, 2, 0, 2, 2, 1, 2, 2, 2, 1, 2, 1, 1, 0, 0,
431 2, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 2, 0, 0, 1, 0, 1, 0, 2, 0,
432 0, 1, 0, 2, 1, 0, 0, 0, 2, 0, 0, 0, 1, 2, 2, 0, 0, 2, 0, 1,
433 1, 2, 1, 1, 0, 0, 1, 1, 1, 2, 2, 1, 2, 0, 0, 2, 1, 0, 0, 1,
434 0, 1, 1, 0, 0, 0, 1, 2, 2, 0, 1, 2, 1, 2, 0, 2, 0, 0, 0, 2,
435 1, 2, 0, 0, 0, 2, 0, 0, 0, 2, 2, 1, 0, 2, 0, 1, 2, 0, 2, 1,
436 0, 2, 2, 1, 0, 2, 1, 2, 2, 0, 2, 0, 2, 1, 2, 2, 0, 2, 0, 1,
437 1, 2, 2, 2, 2, 1, 0, 1, 0, 2, 2, 0, 1, 1, 2, 2, 2, 0, 0, 1,
438 0, 2, 0, 1, 0, 2, 1, 2, 1, 0, 1, 1, 2, 0, 0, 2, 1, 1, 2, 0,
439 1, 2, 1, 1, 0, 1, 0, 2, 1, 1, 1, 2, 1, 0, 2, 0, 2, 0, 0, 2,
440 2, 1, 0, 0, 2, 2, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 2, 1, 2, 2,
441 2, 0, 0, 0, 0, 1, 0, 0, 1, 2, 1, 2, 0, 2, 1, 1, 1, 0, 2, 2,
442 1, 2, 2, 1, 0, 1, 0, 2, 2, 2, 1, 2, 1, 0, 0, 1, 0, 1, 1, 1,
443 1, 1, 2, 0, 0, 2, 1, 0, 2, 1, 2, 1, 0, 2, 2, 0, 0, 1, 2, 1,
444 2, 0, 1, 2, 1, 1, 2, 0, 2, 0, 2, 1, 1, 1, 0, 0, 0, 1, 2, 1,
445 2, 2, 1, 2, 1, 1, 2, 1, 2, 0, 2, 2, 1, 0, 0, 1, 2, 0, 1, 1,
446 2, 0, 0, 0, 1, 2, 2, 1, 2, 0, 0, 2, 1, 0, 2, 2, 2, 1, 1, 0,
447 2, 1, 2, 1, 2, 2, 1, 2, 1, 1, 0, 1, 1, 1, 1, 2, 0, 2, 2, 1,
448 0, 1, 1, 2, 1, 2, 0, 2, 1, 0, 1, 0, 1, 0, 1, 2, 0, 1, 1, 0,
449 0, 1, 1, 2, 0, 2, 2, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1,
450 0, 1, 2, 0, 1, 1, 0, 1, 2, 0, 0, 1, 2, 2, 0, 0, 2, 1, 2),
451 {
452 { 9, 439, 2048, TRUE, 9 + (8 << 8) + (5 << 16),
453 countof(indices_ees439ep1), indices_ees439ep1
454 },
455 { 11, 613, 2048, FALSE, 55,
456 countof(indices_ees613ep1), indices_ees613ep1
457 }
458 }
459 },
460 { HASH_SHA256, 32, 64, 32, 33, 40,
461 chunk_from_chars(
462 0x52, 0xC5, 0xDD, 0x1E, 0xEF, 0x76, 0x1B, 0x53,
463 0x08, 0xE4, 0x86, 0x3F, 0x91, 0x12, 0x98, 0x69,
464 0xC5, 0x9D, 0xDE, 0xF6, 0xFC, 0xFA, 0x93, 0xCE,
465 0x32, 0x52, 0x66, 0xF9, 0xC9, 0x97, 0xF6, 0x42,
466 0x00, 0x2C, 0x64, 0xED, 0x1A, 0x6B, 0x14, 0x0A,
467 0x4B, 0x04, 0xCF, 0x6D, 0x2D, 0x82, 0x0A, 0x07,
468 0xA2, 0x3B, 0xDE, 0xCE, 0x19, 0x8A, 0x39, 0x43,
469 0x16, 0x61, 0x29, 0x98, 0x68, 0xEA, 0xE5, 0xCC,
470 0x0A, 0xF8, 0xE9, 0x71, 0x26, 0xF1, 0x07, 0x36,
471 0x2C, 0x07, 0x1E, 0xEB, 0xE4, 0x28, 0xA2, 0xF4,
472 0xA8, 0x12, 0xC0, 0xC8, 0x20, 0x37, 0xF8, 0xF2,
473 0x6C, 0xAF, 0xDC, 0x6F, 0x2E, 0xD0, 0x62, 0x58,
474 0xD2, 0x37, 0x03, 0x6D, 0xFA, 0x6E, 0x1A, 0xAC,
475 0x9F, 0xCA, 0x56, 0xC6, 0xA4, 0x52, 0x41, 0xE8,
476 0x0F, 0x1B, 0x0C, 0xB9, 0xE6, 0xBA, 0xDE, 0xE1,
477 0x03, 0x5E, 0xC2, 0xE5, 0xF8, 0xF4, 0xF3, 0x46,
478 0x3A, 0x12, 0xC0, 0x1F, 0x3A, 0x00, 0xD0, 0x91,
479 0x18, 0xDD, 0x53, 0xE4, 0x22, 0xF5, 0x26, 0xA4,
480 0x54, 0xEE, 0x20, 0xF0, 0x80),
481 chunk_from_chars(
482 0x76, 0x89, 0x8B, 0x1B, 0x60, 0xEC, 0x10, 0x9D,
483 0x8F, 0x13, 0xF2, 0xFE, 0xD9, 0x85, 0xC1, 0xAB,
484 0x7E, 0xEE, 0xB1, 0x31, 0xDD, 0xF7, 0x7F, 0x0C,
485 0x7D, 0xF9, 0x6B, 0x7B, 0x19, 0x80, 0xBD, 0x28),
486 chunk_from_chars(
487 0xF1, 0x19, 0x02, 0x4F, 0xDA, 0x58, 0x05, 0x9A,
488 0x07, 0xDF, 0x61, 0x81, 0x22, 0x0E, 0x15, 0x46,
489 0xCB, 0x35, 0x3C, 0xDC, 0xAD, 0x20, 0xD9, 0x3F,
490 0x0D, 0xD1, 0xAA, 0x64, 0x66, 0x5C, 0xFA, 0x4A,
491 0xFE, 0xD6, 0x8F, 0x55, 0x57, 0x15, 0xB2, 0xA6,
492 0xA0, 0xE6, 0xA8, 0xC6, 0xBD, 0x28, 0xB4, 0xD5,
493 0x6E, 0x5B, 0x4B, 0xB0, 0x97, 0x09, 0xF5, 0xAC,
494 0x57, 0x65, 0x13, 0x97, 0x71, 0x2C, 0x45, 0x13,
495 0x3D, 0xEE, 0xFB, 0xBF, 0xFE, 0xAF, 0xBB, 0x4B,
496 0x0D, 0x5C, 0x45, 0xD4, 0x2F, 0x17, 0x92, 0x07,
497 0x66, 0x11, 0xF5, 0x46, 0xF8, 0x0C, 0x03, 0x92,
498 0xF5, 0xF5, 0xFF, 0xA4, 0xF3, 0x52, 0xF4, 0x08,
499 0x2C, 0x49, 0x32, 0x1A, 0x93, 0x51, 0x98, 0xB6,
500 0x94, 0x83, 0x39, 0xCF, 0x6B, 0x1F, 0x2F, 0xFC,
501 0x2B, 0xFF, 0x10, 0x71, 0x7D, 0x35, 0x6C, 0xEA,
502 0xC5, 0x66, 0xC7, 0x26, 0x7D, 0x9E, 0xAC, 0xDD,
503 0x35, 0xD7, 0x06, 0x3F, 0x40, 0x82, 0xDA, 0xC3,
504 0x2B, 0x3C, 0x91, 0x3A, 0x32, 0xF8, 0xB2, 0xC6,
505 0x44, 0x4D, 0xCD, 0xB6, 0x54, 0x5F, 0x81, 0x95,
506 0x59, 0xA1, 0xE5, 0x4E, 0xA5, 0x0A, 0x4A, 0x42),
507 chunk_from_chars(
508 1, 2, 2, 2, 2, 1, 2, 2, 0, 0, 2, 0, 0, 0, 0, 1, 2, 2, 2, 0,
509 2, 0, 0, 2, 2, 1, 2, 0, 0, 1, 2, 1, 0, 0, 0, 1, 0, 2, 2, 1,
510 1, 2, 0, 0, 0, 1, 2, 0, 2, 2, 1, 2, 1, 0, 1, 0, 1, 2, 1, 1,
511 1, 2, 0, 1, 0, 2, 1, 1, 0, 0, 0, 1, 2, 0, 0, 1, 2, 1, 2, 0,
512 2, 1, 1, 1, 2, 2, 2, 2, 1, 0, 0, 2, 0, 2, 0, 1, 1, 0, 2, 2,
513 2, 0, 1, 0, 2, 2, 1, 0, 1, 0, 1, 0, 0, 2, 2, 0, 0, 1, 2, 0,
514 1, 1, 1, 0, 0, 2, 0, 2, 1, 2, 2, 2, 0, 0, 2, 1, 0, 2, 0, 1,
515 0, 1, 2, 0, 1, 2, 0, 1, 0, 1, 2, 0, 2, 2, 0, 1, 2, 2, 1, 2,
516 2, 2, 0, 2, 1, 1, 1, 0, 0, 1, 0, 2, 0, 0, 1, 0, 1, 2, 0, 0,
517 1, 2, 1, 0, 2, 1, 1, 0, 0, 2, 1, 2, 2, 2, 1, 2, 1, 1, 2, 2,
518 0, 2, 0, 0, 2, 0, 0, 1, 1, 2, 0, 0, 0, 1, 2, 1, 1, 1, 1, 0,
519 0, 0, 2, 0, 2, 0, 2, 2, 1, 2, 2, 0, 0, 1, 1, 1, 0, 1, 0, 1,
520 0, 1, 2, 2, 0, 2, 1, 1, 0, 2, 1, 2, 1, 2, 1, 0, 0, 1, 0, 0,
521 1, 0, 1, 0, 2, 0, 2, 0, 0, 1, 2, 0, 2, 0, 1, 1, 0, 2, 0, 0,
522 1, 2, 1, 2, 1, 2, 1, 0, 1, 1, 2, 2, 1, 1, 0, 0, 2, 1, 2, 0,
523 1, 0, 2, 0, 0, 1, 2, 0, 2, 0, 1, 1, 2, 2, 2, 2, 0, 0, 1, 2,
524 1, 1, 1, 0, 2, 1, 2, 2, 0, 2, 0, 1, 2, 2, 0, 1, 1, 1, 0, 0,
525 2, 0, 1, 0, 1, 0, 2, 1, 2, 0, 2, 1, 2, 1, 2, 2, 0, 2, 1, 0,
526 2, 1, 2, 0, 0, 2, 0, 1, 2, 1, 1, 2, 0, 0, 0, 0, 1, 2, 0, 1,
527 2, 2, 1, 0, 0, 1, 2, 1, 2, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0,
528 2, 0, 1, 2, 1, 2, 0, 0, 0, 2, 1, 0, 0, 0, 1, 2, 2, 0, 0, 0,
529 2, 2, 1, 1, 0, 1, 0, 2, 2, 0, 2, 1, 2, 1, 0, 2, 2, 2, 0, 0,
530 0, 1, 1, 2, 1, 0, 0, 0, 0, 1, 2, 2, 1, 2, 1, 2, 0, 2, 0, 2,
531 1, 1, 1, 2, 1, 2, 1, 2, 1, 1, 0, 1, 0, 2, 0, 0, 0, 2, 1, 2,
532 2, 2, 2, 0, 1, 1, 1, 0, 1, 0, 2, 0, 2, 1, 0, 1, 2, 1, 1, 0,
533 1, 2, 1, 0, 0, 2, 1, 0, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0,
534 0, 0, 0, 1, 1, 0, 0, 2, 2, 2, 2, 2, 0, 1, 2, 0, 1, 2, 0, 1,
535 1, 0, 1, 1, 2, 2, 0, 1, 1, 0, 2, 2, 1, 1, 1, 2, 1, 2, 2, 1,
536 1, 0, 1, 0, 2, 2, 1, 0, 2, 2, 2, 2, 2, 1, 0, 2, 2, 2, 1, 2,
537 0, 2, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 1),
538 {
539 { 13, 743, 2048, TRUE, 11 + (11 << 8) + (15 << 16),
540 countof(indices_ees743ep1), indices_ees743ep1
541 },
542 { 12, 1171, 2048, FALSE, 106,
543 countof(indices_ees1171ep1), indices_ees1171ep1
544 }
545 }
546 }
547 };
548
549 START_TEST(test_ntru_mgf1)
550 {
551 ntru_mgf1_t *mgf1;
552 chunk_t mask, mask1, mask2, mask3;
553
554 mask1 = mgf1_tests[_i].mask;
555 mask2 = chunk_skip(mask1, mgf1_tests[_i].ml1);
556 mask3 = chunk_skip(mask2, mgf1_tests[_i].ml2);
557 mask1.len = mgf1_tests[_i].ml1;
558 mask2.len = mgf1_tests[_i].ml2;
559 mask3.len = mgf1_tests[_i].ml3;
560
561 mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, HASH_UNKNOWN,
562 mgf1_tests[_i].seed, TRUE);
563 ck_assert(mgf1 == NULL);
564
565 mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
566 chunk_empty, TRUE);
567 ck_assert(mgf1 == NULL);
568
569 /* return mask in allocated chunk */
570 mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
571 mgf1_tests[_i].seed, TRUE);
572 ck_assert(mgf1);
573
574 /* check hash size */
575 ck_assert(mgf1->get_hash_size(mgf1) == mgf1_tests[_i].hash_size);
576
577 /* get zero number of octets */
578 ck_assert(mgf1->allocate_mask(mgf1, 0, &mask));
579 ck_assert(mask.len == 0 && mask.ptr == NULL);
580
581 /* get non-zero number of octets */
582 ck_assert(mgf1->allocate_mask(mgf1, mgf1_tests[_i].mask.len, &mask));
583 ck_assert(chunk_equals(mask, mgf1_tests[_i].mask));
584 mgf1->destroy(mgf1);
585
586 /* copy mask to pre-allocated buffer */
587 mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
588 mgf1_tests[_i].seed, TRUE);
589 ck_assert(mgf1);
590 ck_assert(mgf1->get_mask(mgf1, mgf1_tests[_i].mask.len, mask.ptr));
591 ck_assert(chunk_equals(mask, mgf1_tests[_i].mask));
592 mgf1->destroy(mgf1);
593
594 /* get mask in batches without hashing the seed */
595 mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
596 mgf1_tests[_i].hashed_seed, FALSE);
597 ck_assert(mgf1);
598
599 /* first batch */
600 ck_assert(mgf1->get_mask(mgf1, mask1.len, mask.ptr));
601 mask.len = mask1.len;
602 ck_assert(chunk_equals(mask, mask1));
603
604 /* second batch */
605 ck_assert(mgf1->get_mask(mgf1, mask2.len, mask.ptr));
606 mask.len = mask2.len;
607 ck_assert(chunk_equals(mask, mask2));
608
609 /* third batch */
610 ck_assert(mgf1->get_mask(mgf1, mask3.len, mask.ptr));
611 mask.len = mask3.len;
612 ck_assert(chunk_equals(mask, mask3));
613
614 mgf1->destroy(mgf1);
615 chunk_free(&mask);
616 }
617 END_TEST
618
619 START_TEST(test_ntru_trits)
620 {
621 ntru_trits_t *mask;
622 chunk_t trits;
623
624 mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len,
625 HASH_UNKNOWN, mgf1_tests[_i].seed);
626 ck_assert(mask == NULL);
627
628 mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len,
629 mgf1_tests[_i].alg, chunk_empty);
630 ck_assert(mask == NULL);
631
632 mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len,
633 mgf1_tests[_i].alg, mgf1_tests[_i].seed);
634 ck_assert(mask);
635
636 trits = chunk_create(mask->get_trits(mask), mask->get_size(mask));
637 ck_assert(chunk_equals(trits, mgf1_tests[_i].trits));
638 mask->destroy(mask);
639
640 /* generate a multiple of 5 trits */
641 mask = TEST_FUNCTION(ntru, ntru_trits_create, 10, mgf1_tests[_i].alg,
642 mgf1_tests[_i].seed);
643 ck_assert(mask);
644
645 trits = chunk_create(mask->get_trits(mask), mask->get_size(mask));
646 ck_assert(chunk_equals(trits, chunk_create(mgf1_tests[_i].trits.ptr, 10)));
647 mask->destroy(mask);
648 }
649 END_TEST
650
651 START_TEST(test_ntru_poly)
652 {
653 ntru_poly_t *poly;
654 uint16_t *indices;
655 chunk_t seed;
656 poly_test_t *p;
657 int j, n;
658
659 seed = mgf1_tests[_i].seed;
660 seed.len = mgf1_tests[_i].seed_len;
661
662 p = &mgf1_tests[_i].poly_test[0];
663 poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed, HASH_UNKNOWN, seed,
664 p->c_bits, p->N, p->q, p->indices_len, p->indices_len,
665 p->is_product_form);
666 ck_assert(poly == NULL);
667
668 for (n = 0; n < 2; n++)
669 {
670 p = &mgf1_tests[_i].poly_test[n];
671 poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed,
672 mgf1_tests[_i].alg, seed, p->c_bits, p->N, p->q,
673 p->indices_len, p->indices_len, p->is_product_form);
674 ck_assert(poly != NULL && poly->get_size(poly) == p->indices_size);
675
676 indices = poly->get_indices(poly);
677 for (j = 0; j < p->indices_size; j++)
678 {
679 ck_assert(indices[j] == p->indices[j]);
680 }
681 poly->destroy(poly);
682 }
683 }
684 END_TEST
685
686 typedef struct {
687 uint16_t N;
688 uint16_t q;
689 bool is_product_form;
690 uint32_t indices_len_p;
691 uint32_t indices_len_m;
692 uint16_t *indices;
693 uint16_t *a;
694 uint16_t *c;
695 } ring_mult_test_t;
696
697 uint16_t t1_indices[] = { 1, 6, 5, 3 };
698
699 uint16_t t1_a[] = { 1, 0, 0, 0, 0, 0, 0 };
700 uint16_t t1_c[] = { 0, 1, 0, 7, 0, 7, 1 };
701
702 uint16_t t2_a[] = { 5, 0, 0, 0, 0, 0, 0 };
703 uint16_t t2_c[] = { 0, 5, 0, 3, 0, 3, 5 };
704
705 uint16_t t3_a[] = { 4, 0, 0, 0, 0, 0, 0 };
706 uint16_t t3_c[] = { 0, 4, 0, 4, 0, 4, 4 };
707
708 uint16_t t4_a[] = { 0, 6, 0, 0, 0, 0, 0 };
709 uint16_t t4_c[] = { 6, 0, 6, 0, 2, 0, 2 };
710
711 uint16_t t5_a[] = { 4, 6, 0, 0, 0, 0, 0 };
712 uint16_t t5_c[] = { 6, 4, 6, 4, 2, 4, 6 };
713
714 uint16_t t6_a[] = { 0, 0, 3, 0, 0, 0, 0 };
715 uint16_t t6_c[] = { 5, 3, 0, 3, 0, 5, 0 };
716
717 uint16_t t7_a[] = { 4, 6, 3, 0, 0, 0, 0 };
718 uint16_t t7_c[] = { 3, 7, 6, 7, 2, 1, 6 };
719
720 uint16_t t8_a[] = { 0, 0, 0, 7, 0, 0, 0 };
721 uint16_t t8_c[] = { 0, 1, 7, 0, 7, 0, 1 };
722
723 uint16_t t9_a[] = { 4, 6, 3, 7, 0, 0, 0 };
724 uint16_t t9_c[] = { 3, 0, 5, 7, 1, 1, 7 };
725
726 uint16_t t10_a[] = { 0, 0, 0, 0, 0, 1, 0 };
727 uint16_t t10_c[] = { 0, 7, 0, 7, 1, 0, 1 };
728
729 uint16_t t11_a[] = { 4, 6, 3, 7, 0, 1, 0 };
730 uint16_t t11_c[] = { 3, 7, 5, 6, 2, 1, 0 };
731
732 uint16_t t2_indices[] = { 1, 6, 5, 2, 3 };
733
734 uint16_t t12_c[] = { 0, 1, 7, 7, 0, 1, 1 };
735 uint16_t t13_c[] = { 0, 1, 7, 7, 0, 7, 1 };
736 uint16_t t14_c[] = { 0, 1, 0, 31, 0, 31, 1 };
737 uint16_t t15_c[] = { 0, 5, 0, 2043, 0, 2043, 5 };
738 uint16_t t16_c[] = { 0, 5, 0, 32763, 0, 32763, 5 };
739
740 uint16_t t3_indices[] = { 7, 2, 3, 5, 0, 2, 3, 10, 7, 0, 8, 2 };
741
742 uint16_t t17_a[] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
743 uint16_t t17_c[] = { 7, 1, 0, 1, 1, 7, 0, 7, 7, 7, 2 };
744
745 ring_mult_test_t ring_mult_tests[] = {
746 { 7, 8, FALSE, 2, 2, t1_indices, t1_a, t1_c },
747 { 7, 8, FALSE, 2, 2, t1_indices, t2_a, t2_c },
748 { 7, 8, FALSE, 2, 2, t1_indices, t3_a, t3_c },
749 { 7, 8, FALSE, 2, 2, t1_indices, t4_a, t4_c },
750 { 7, 8, FALSE, 2, 2, t1_indices, t5_a, t5_c },
751 { 7, 8, FALSE, 2, 2, t1_indices, t6_a, t6_c },
752 { 7, 8, FALSE, 2, 2, t1_indices, t7_a, t7_c },
753 { 7, 8, FALSE, 2, 2, t1_indices, t8_a, t8_c },
754 { 7, 8, FALSE, 2, 2, t1_indices, t9_a, t9_c },
755 { 7, 8, FALSE, 2, 2, t1_indices, t10_a, t10_c },
756 { 7, 8, FALSE, 2, 2, t1_indices, t11_a, t11_c },
757 { 7, 8, FALSE, 3, 2, t2_indices, t1_a, t12_c },
758 { 7, 8, FALSE, 2, 3, t2_indices, t1_a, t13_c },
759 { 7, 32, FALSE, 2, 2, t1_indices, t1_a, t14_c },
760 { 7, 2048, FALSE, 2, 2, t1_indices, t2_a, t15_c },
761 { 7, 32768, FALSE, 2, 2, t1_indices, t2_a, t16_c },
762 { 11, 8, TRUE, 197121, 197121, t3_indices, t17_a, t17_c },
763 };
764
765 START_TEST(test_ntru_ring_mult)
766 {
767 ntru_poly_t *poly;
768 ring_mult_test_t *t;
769 uint16_t *c;
770 int i;
771
772 t = &ring_mult_tests[_i];
773 poly = TEST_FUNCTION(ntru, ntru_poly_create_from_data, t->indices, t->N,
774 t->q, t->indices_len_p, t->indices_len_m,
775 t->is_product_form);
776 ck_assert(poly != NULL);
777
778 c = malloc(t->N * sizeof(uint16_t));
779 poly->ring_mult(poly, t->a, c);
780
781 for (i = 0; i < t->N; i++)
782 {
783 ck_assert(c[i] == t->c[i]);
784 }
785
786 free(c);
787 poly->destroy(poly);
788 }
789 END_TEST
790
791 int array_tests[] = { 0, 11, 12, 16 };
792
793 START_TEST(test_ntru_array)
794 {
795 ntru_poly_t *poly;
796 ring_mult_test_t *t;
797 uint16_t *c;
798 int i;
799
800 t = &ring_mult_tests[array_tests[_i]];
801
802 poly = TEST_FUNCTION(ntru, ntru_poly_create_from_data, t->indices, t->N,
803 t->q, t->indices_len_p, t->indices_len_m,
804 t->is_product_form);
805 ck_assert(poly != NULL);
806
807 c = malloc(t->N * sizeof(uint16_t));
808 poly->get_array(poly, c);
809
810 for (i = 0; i < t->N; i++)
811 {
812 ck_assert(c[i] == t->c[i]);
813 }
814
815 free(c);
816 poly->destroy(poly);
817 }
818 END_TEST
819
820 START_TEST(test_ntru_param_set)
821 {
822 ck_assert(TEST_FUNCTION(ntru, ntru_param_set_get_by_id, -1) == NULL);
823 ck_assert(TEST_FUNCTION(ntru, ntru_param_set_get_by_id, 16) == NULL);
824 }
825 END_TEST
826
827 typedef struct {
828 ntru_param_set_id_t id;
829 chunk_t entropy;
830 chunk_t encoding;
831 } privkey_test_t;
832
833 privkey_test_t privkey_tests[] = {
834 {
835 NTRU_EES401EP1,
836 chunk_from_chars(
837 0x0C, 0x2F, 0x24, 0xE1, 0xA4, 0x81, 0x26, 0xA2,
838 0x6C, 0xEA, 0xCD, 0x1A, 0xF3, 0xEB, 0x3D, 0xBF,
839 0xEA, 0xAE, 0xC3, 0x0D, 0xC1),
840 chunk_from_chars(
841 0x02, 0x03, 0x00, 0x02, 0x04, 0x3E, 0xF3, 0xCB,
842 0x7A, 0x58, 0x13, 0x75, 0xBB, 0x87, 0xF5, 0xBF,
843 0x2E, 0x18, 0xAE, 0x03, 0xAF, 0xB8, 0x33, 0x85,
844 0xD8, 0xBF, 0x8A, 0xB5, 0x8C, 0xA6, 0xDF, 0x03,
845 0x90, 0x1E, 0xE4, 0x83, 0xA4, 0x95, 0x40, 0xB5,
846 0x08, 0x92, 0x29, 0xD8, 0x83, 0xA8, 0x42, 0xB2,
847 0x69, 0xC2, 0x00, 0x8B, 0xAE, 0x80, 0x00, 0x4F,
848 0x3D, 0xDD, 0xFB, 0xDB, 0x9A, 0xD8, 0x0F, 0xFF,
849 0xBC, 0x21, 0xD5, 0xE6, 0x04, 0x9C, 0xDD, 0x3B,
850 0x2D, 0x16, 0x4B, 0xC7, 0x3D, 0xBE, 0xDE, 0xBB,
851 0x6F, 0xF4, 0x8A, 0x31, 0xCD, 0x23, 0x19, 0xC2,
852 0x3C, 0xE1, 0xE2, 0xEE, 0xE4, 0xE7, 0x2E, 0xFC,
853 0x5C, 0xDD, 0xAD, 0x0C, 0x9D, 0x98, 0xC5, 0x18,
854 0x2A, 0x80, 0x21, 0x93, 0x61, 0xC4, 0x9A, 0x16,
855 0xE8, 0x9B, 0xF7, 0x3B, 0x6D, 0x06, 0x91, 0x9E,
856 0x71, 0x59, 0xBE, 0x8E, 0x65, 0x61, 0xB2, 0x69,
857 0x9C, 0x82, 0x58, 0x0D, 0x63, 0x7A, 0x1F, 0x2A,
858 0x1C, 0x2C, 0x92, 0x8C, 0x8D, 0xCA, 0x2B, 0x45,
859 0x24, 0x79, 0xDB, 0x7F, 0x1D, 0x2F, 0xAB, 0x88,
860 0x8C, 0x1D, 0xE3, 0x15, 0x8F, 0xCD, 0x46, 0x8C,
861 0x45, 0x20, 0x88, 0x1C, 0x17, 0xE0, 0xE5, 0x89,
862 0xF4, 0x60, 0x56, 0x3C, 0x6B, 0x9F, 0x2A, 0xD9,
863 0xD0, 0xAE, 0x3B, 0xB6, 0xC2, 0xB7, 0x58, 0xC6,
864 0x6E, 0x09, 0x36, 0x21, 0x0B, 0xDD, 0xE9, 0x52,
865 0x33, 0x27, 0x39, 0xC8, 0x51, 0x59, 0x69, 0x25,
866 0xC6, 0x3D, 0x19, 0x5C, 0x5E, 0x74, 0xD0, 0x62,
867 0xD9, 0x26, 0x90, 0xC7, 0x64, 0x92, 0xA8, 0x72,
868 0xD1, 0x77, 0x1F, 0x78, 0xC5, 0x11, 0xBD, 0x5D,
869 0x3C, 0x1B, 0x1F, 0x8B, 0x5B, 0xE4, 0x5D, 0xA1,
870 0x27, 0x6D, 0x20, 0x24, 0x32, 0x53, 0xF3, 0xB0,
871 0xE6, 0x71, 0x61, 0xCC, 0xFC, 0x4A, 0x06, 0xDA,
872 0xBE, 0xD7, 0x9F, 0x2F, 0xEB, 0x44, 0xD0, 0x8A,
873 0x7D, 0x8E, 0x82, 0xF5, 0x84, 0xCF, 0x8E, 0xE5,
874 0x4B, 0xA4, 0x30, 0x77, 0xBD, 0x14, 0xB9, 0x75,
875 0x02, 0x68, 0xDF, 0x71, 0x89, 0x81, 0xF2, 0x95,
876 0xC3, 0x67, 0x6E, 0x37, 0xE4, 0xD0, 0xC9, 0x1E,
877 0x02, 0xDE, 0x2D, 0x79, 0x99, 0xE8, 0x7D, 0x5C,
878 0x99, 0xF2, 0x1A, 0xDE, 0x12, 0x9B, 0xD1, 0x83,
879 0x9B, 0x01, 0xD3, 0xEB, 0x2B, 0x8E, 0x9C, 0xA5,
880 0x19, 0xE8, 0x2E, 0xFE, 0x23, 0x6E, 0xAD, 0x8F,
881 0x3C, 0xAF, 0xB9, 0xE6, 0xDB, 0x07, 0xA4, 0x31,
882 0x02, 0x2B, 0x6A, 0xA0, 0xFB, 0x51, 0x6C, 0xD0,
883 0x26, 0xD5, 0xAD, 0x29, 0x65, 0x10, 0xCE, 0xF8,
884 0x84, 0x4D, 0x1E, 0x37, 0x92, 0xA2, 0xD1, 0xFA,
885 0xF6, 0xC0, 0x36, 0x4C, 0x23, 0x3A, 0x42, 0xAA,
886 0xB8, 0x0D, 0x4E, 0xD4, 0x40, 0x61, 0xD5, 0x36,
887 0x62, 0x23, 0x7C, 0x1C, 0x5E, 0xEA, 0x16, 0xAD,
888 0x4F, 0x30, 0xF9, 0x16, 0x99, 0xCE, 0xC5, 0x50,
889 0xAC, 0x8F, 0x6F, 0x98, 0xD7, 0xE3, 0x89, 0x6E,
890 0x3A, 0x12, 0xCE, 0xA7, 0xA4, 0x17, 0x74, 0xDC,
891 0xDB, 0xFA, 0xFF, 0xF9, 0x35, 0xD7, 0xF5, 0x77,
892 0x03, 0xF5, 0xBF, 0x81, 0x6C, 0x9F, 0x62, 0xA6,
893 0x8A, 0x5B, 0xA3, 0xEF, 0x9D, 0xC3, 0xF6, 0x3A,
894 0x6A, 0xC0, 0x42, 0x71, 0xAF, 0x90, 0xCA, 0x1D,
895 0x86, 0x78, 0xD7, 0x2C, 0xFE, 0xB6, 0x99, 0x15,
896 0x8C, 0x10, 0x42, 0x92, 0x2C, 0x05, 0x43, 0x92,
897 0x69, 0x05, 0x8D, 0x9E, 0xBC, 0xAB, 0x8F, 0x28,
898 0xAA, 0x4B, 0xFB, 0x25, 0xD9, 0xAD, 0x29, 0xFF,
899 0x33, 0x65, 0x14, 0xC3, 0x75, 0x1F, 0xCF, 0xFC,
900 0x20, 0x83, 0xBF, 0xB9, 0xA5, 0x4B, 0x7B, 0xD9,
901 0x07, 0x5C, 0xA1, 0xD1, 0x5A, 0x3E, 0x94, 0xF8,
902 0x03, 0xDE, 0xB8, 0x94, 0x11, 0x92, 0x80, 0x77,
903 0x57, 0x45, 0x1E, 0x6B, 0xA5, 0x15, 0xDB, 0x48,
904 0xB6, 0x9E, 0x02, 0xF1, 0x61, 0x4A, 0xAC, 0x1D,
905 0x49, 0xBC, 0xA9, 0x3F, 0x03, 0x50, 0xAC, 0x02,
906 0x8E, 0x84, 0xE0, 0x12, 0x37, 0x76, 0xBC, 0x4A,
907 0xF9, 0xC6, 0x74, 0x36, 0xFC, 0x92, 0x1D, 0x59,
908 0x0C, 0x04, 0xD2, 0x14, 0xB7, 0x11, 0xE9, 0xE2,
909 0xFE, 0x0C, 0xE1, 0xDA, 0x8B, 0xCA, 0x10, 0xA1,
910 0x60, 0xB6, 0x57, 0x51, 0x00, 0xD6, 0x5B, 0x55,
911 0x09, 0x60, 0xE8, 0x00, 0x40, 0x45, 0x56, 0xBA,
912 0x83, 0x1E, 0x36, 0x12, 0x59, 0x4B, 0x19, 0x00,
913 0x53, 0xAE, 0x62, 0xA6, 0x29, 0x39, 0xED, 0x87,
914 0x24, 0x37, 0x1E, 0x1B, 0xCF, 0x3F, 0x3A, 0x71,
915 0x31, 0xB5, 0x50, 0x8D, 0x4B, 0x53, 0x53, 0x75,
916 0x3F, 0x33, 0x39, 0x09, 0x2A, 0x78, 0xA8, 0x71,
917 0x3E, 0x63, 0xC5, 0x61, 0x73, 0xB6, 0xE1, 0x71,
918 0x16, 0xDA, 0x06, 0xBF, 0x3F, 0x22, 0x74, 0x89,
919 0x08, 0xD2, 0x05, 0x0B, 0x16, 0xC8, 0xF0, 0x17,
920 0x4E, 0xA2, 0x65, 0x67, 0x6D, 0x02)
921 },
922 {
923 NTRU_EES743EP1,
924 chunk_from_chars(
925 0x9B, 0xAB, 0x57, 0xDB, 0x2C, 0x60, 0x83, 0x48,
926 0x9F, 0xC9, 0x70, 0x8F, 0x69, 0xF7, 0xB4, 0xBB,
927 0x63, 0x5C, 0x9A, 0x63, 0x07, 0x80, 0x17, 0xD3,
928 0xCD, 0xB1, 0x57, 0x79, 0xFE, 0x8D, 0x81, 0x70,
929 0xEB, 0x50, 0xFA, 0x05, 0xFB, 0x97, 0xB2, 0xAB,
930 0x25, 0xED, 0xD8, 0x18, 0x1C, 0xFE, 0x96, 0x7D),
931 chunk_from_chars(
932 0x02, 0x03, 0x00, 0x06, 0x10, 0x14, 0x53, 0x73,
933 0x56, 0xF5, 0xA9, 0x34, 0xDE, 0xA6, 0x4D, 0x46,
934 0x05, 0x9E, 0x80, 0xAE, 0xB6, 0x74, 0x91, 0xFF,
935 0xFB, 0x48, 0xD3, 0x5C, 0x61, 0x12, 0x46, 0x02,
936 0x9F, 0x53, 0x45, 0x87, 0x47, 0xBD, 0x6B, 0x26,
937 0xF7, 0x36, 0xD3, 0x99, 0x1B, 0xD7, 0xEA, 0xA3,
938 0xA8, 0x94, 0xFF, 0x93, 0x46, 0x7C, 0x2C, 0x5F,
939 0x87, 0x8C, 0x38, 0xB3, 0x7B, 0xC6, 0x49, 0xE2,
940 0x88, 0xCA, 0x67, 0x89, 0xD0, 0x6D, 0x7C, 0xAE,
941 0x7C, 0x98, 0x84, 0xDA, 0x6B, 0x93, 0x92, 0xEF,
942 0x4A, 0xD1, 0x4A, 0xD2, 0x5B, 0x13, 0xF8, 0x59,
943 0x15, 0x2E, 0xBC, 0x70, 0x8D, 0x2D, 0xA9, 0x47,
944 0xA1, 0x99, 0x19, 0x3F, 0x67, 0xE8, 0x18, 0xA7,
945 0x17, 0x07, 0xB3, 0x14, 0xF6, 0x20, 0xA1, 0xD8,
946 0x33, 0xE8, 0x08, 0x6A, 0xC1, 0x39, 0x99, 0x08,
947 0xB4, 0x88, 0xEB, 0x48, 0x7D, 0xFB, 0xF5, 0xEF,
948 0x03, 0x0D, 0x25, 0xB7, 0x98, 0xF3, 0xF1, 0x15,
949 0x63, 0xE4, 0x0F, 0xFD, 0x54, 0x9F, 0x56, 0xE9,
950 0xD1, 0x44, 0xE5, 0x89, 0x66, 0x14, 0x91, 0x1C,
951 0xFD, 0xD6, 0xFD, 0x38, 0xAE, 0x39, 0xE3, 0xF7,
952 0xCD, 0x77, 0xC2, 0xEA, 0x2E, 0xE4, 0xB7, 0x2B,
953 0xBA, 0x7A, 0xD1, 0x75, 0xB8, 0x28, 0x65, 0x18,
954 0xF4, 0xC6, 0xBD, 0xD0, 0x17, 0x7E, 0xEA, 0x86,
955 0x7E, 0xFC, 0x95, 0xD6, 0x4C, 0x92, 0x01, 0xC3,
956 0xFF, 0x04, 0x9B, 0xF8, 0xD6, 0xB3, 0x8F, 0x72,
957 0xEF, 0x64, 0x09, 0x61, 0xF8, 0xE4, 0x48, 0xFC,
958 0x0D, 0xEE, 0xEF, 0xA2, 0x9F, 0x3A, 0x2B, 0x1A,
959 0xFB, 0x8B, 0xA0, 0x9C, 0x11, 0x0B, 0x97, 0x75,
960 0x30, 0x7C, 0xB8, 0x9F, 0xEE, 0x3B, 0x53, 0x85,
961 0x7D, 0xE9, 0xCB, 0xC4, 0x4D, 0xD7, 0x7F, 0x59,
962 0x10, 0x72, 0x19, 0x3A, 0xC9, 0x38, 0xFE, 0xE8,
963 0xB3, 0x06, 0x55, 0x8D, 0xA2, 0x5A, 0x3D, 0x79,
964 0x67, 0x0E, 0x90, 0xC9, 0x25, 0x6D, 0x45, 0x9C,
965 0x39, 0x79, 0x5F, 0x18, 0x35, 0x9F, 0xC1, 0x49,
966 0x08, 0x6F, 0x1C, 0x47, 0x09, 0x0D, 0x49, 0x7C,
967 0x3C, 0x7B, 0xB1, 0x09, 0x92, 0x1C, 0x4E, 0x5A,
968 0xDA, 0x74, 0x9E, 0xBB, 0x55, 0x9D, 0xBB, 0x1E,
969 0x43, 0x28, 0x62, 0xAF, 0x02, 0xB0, 0x1A, 0xEA,
970 0x13, 0x0A, 0x70, 0x0F, 0x60, 0x0F, 0x62, 0xA2,
971 0x4E, 0x1F, 0xB2, 0xEA, 0x06, 0xDD, 0x18, 0x02,
972 0x6C, 0xF3, 0x82, 0xF1, 0x80, 0x7F, 0xA7, 0x2F,
973 0xCC, 0xC6, 0x18, 0xEA, 0xFF, 0x1F, 0xAD, 0xC6,
974 0xBA, 0x0C, 0x0E, 0x04, 0xB2, 0x58, 0x1D, 0xB6,
975 0x01, 0xA3, 0x97, 0xDF, 0x7D, 0x9B, 0xB5, 0x0A,
976 0xAD, 0x30, 0x2B, 0xC5, 0x67, 0x40, 0x07, 0xF1,
977 0xD5, 0x6C, 0x11, 0x10, 0xE1, 0x69, 0x30, 0xAD,
978 0x90, 0x06, 0xDB, 0xF8, 0xEA, 0x92, 0x9B, 0x39,
979 0x57, 0x38, 0x7B, 0xE4, 0xB2, 0xA2, 0x89, 0xFD,
980 0xB1, 0x6D, 0x88, 0x41, 0x62, 0x4D, 0x18, 0xB6,
981 0x3F, 0x12, 0x81, 0xDE, 0xE6, 0xDC, 0x4A, 0x31,
982 0x61, 0x26, 0xB1, 0x4B, 0x95, 0xC1, 0x69, 0xDC,
983 0xDC, 0xAC, 0xD0, 0x15, 0xFC, 0x21, 0xC5, 0x20,
984 0x5F, 0x97, 0x76, 0x41, 0xC1, 0xF2, 0xD7, 0x95,
985 0x1D, 0x25, 0x23, 0x36, 0x86, 0xFA, 0x7E, 0xF4,
986 0x14, 0x9F, 0x9D, 0x9F, 0xB2, 0xBB, 0x25, 0x1D,
987 0xD5, 0x7A, 0x6F, 0x9E, 0xF7, 0xEF, 0x9D, 0x63,
988 0x1E, 0xD5, 0xDE, 0x6A, 0xE6, 0x46, 0x48, 0x1F,
989 0xE1, 0x0C, 0x4D, 0x82, 0xC9, 0x19, 0x3B, 0x65,
990 0xA4, 0x06, 0x13, 0xB7, 0x04, 0xB1, 0x62, 0xF7,
991 0x08, 0xAE, 0xED, 0x42, 0x6D, 0xCC, 0x6C, 0xA6,
992 0x06, 0x06, 0x41, 0x3E, 0x0C, 0x89, 0x4C, 0xBD,
993 0x00, 0x4F, 0x0E, 0xA9, 0x72, 0x06, 0x21, 0x82,
994 0xD2, 0xB6, 0x6C, 0xB0, 0xB0, 0x01, 0x5B, 0xDD,
995 0x05, 0xCE, 0x71, 0x6E, 0x00, 0x58, 0xC7, 0xA6,
996 0x5B, 0xF6, 0xFB, 0x6B, 0x62, 0xB1, 0xE8, 0x4D,
997 0xAC, 0xC0, 0x6B, 0xF4, 0x40, 0x69, 0xEE, 0x0D,
998 0xE7, 0x82, 0x61, 0x8D, 0x35, 0x01, 0x97, 0x4E,
999 0xF2, 0xCC, 0xF5, 0x7F, 0xBF, 0xE4, 0xEC, 0x9C,
1000 0xC4, 0xD2, 0xD9, 0x65, 0x78, 0x98, 0xD8, 0xB0,
1001 0xFA, 0xA8, 0xFB, 0xB0, 0xCE, 0x22, 0x5D, 0x0B,
1002 0x27, 0xDF, 0x0E, 0x63, 0x42, 0xFE, 0x89, 0x13,
1003 0x99, 0xB2, 0x02, 0x0B, 0xF6, 0x04, 0xB6, 0xAF,
1004 0x9F, 0x8C, 0xA6, 0x17, 0x0D, 0xD9, 0x5B, 0x45,
1005 0xE4, 0x08, 0x53, 0x51, 0xE0, 0xD5, 0x22, 0x72,
1006 0xBE, 0xAD, 0x74, 0x69, 0xB9, 0xFB, 0x91, 0xF8,
1007 0xC1, 0x89, 0x28, 0x71, 0x27, 0x62, 0xB1, 0xF0,
1008 0xFD, 0x78, 0xBC, 0x82, 0xFE, 0x76, 0xBE, 0x7B,
1009 0x47, 0x79, 0x32, 0x71, 0xAD, 0xD6, 0x76, 0x46,
1010 0xFB, 0x32, 0xE8, 0x4B, 0x98, 0x9A, 0xC6, 0x85,
1011 0xF2, 0xF1, 0x8A, 0xEC, 0xC2, 0x4E, 0x9B, 0x2F,
1012 0x2D, 0x6F, 0xC9, 0x9B, 0xB6, 0x14, 0x35, 0x6D,
1013 0xD6, 0x5B, 0xF3, 0x02, 0x5A, 0xE5, 0xBD, 0x00,
1014 0xF7, 0x6E, 0x51, 0xA7, 0xDB, 0x19, 0xAE, 0x01,
1015 0x01, 0x05, 0x94, 0x23, 0xF7, 0x5B, 0x07, 0x79,
1016 0xFF, 0x39, 0x58, 0x9C, 0x2A, 0xF7, 0x7E, 0x5D,
1017 0x81, 0xF9, 0x59, 0xFE, 0xB9, 0x9A, 0x96, 0x63,
1018 0x1F, 0x65, 0xF6, 0xF0, 0x3D, 0xEA, 0xD7, 0xC2,
1019 0x8A, 0xCF, 0xB5, 0x58, 0x74, 0x77, 0x23, 0xD6,
1020 0x72, 0x58, 0xA8, 0xAE, 0x31, 0x8A, 0x59, 0xEA,
1021 0x69, 0x14, 0x6A, 0x20, 0x78, 0x79, 0x28, 0x5A,
1022 0xE1, 0x76, 0x6F, 0xA6, 0x1A, 0x9E, 0x47, 0xD2,
1023 0xAF, 0x63, 0xF8, 0x06, 0xF6, 0xD8, 0xD5, 0x14,
1024 0xA8, 0xD1, 0xEE, 0x96, 0xCE, 0xBB, 0x8E, 0x22,
1025 0x69, 0x2F, 0x52, 0x06, 0xB6, 0x6F, 0xC8, 0x99,
1026 0x96, 0xEA, 0xC6, 0x1D, 0x96, 0x4C, 0x69, 0x95,
1027 0xFE, 0x74, 0x04, 0x3C, 0x55, 0xD9, 0x5F, 0xE0,
1028 0x41, 0x21, 0x43, 0x21, 0x5A, 0x50, 0x5D, 0x8B,
1029 0xE8, 0xB2, 0x51, 0x1B, 0x7C, 0x63, 0x50, 0xAE,
1030 0x97, 0x4F, 0xBA, 0x7D, 0xF2, 0xB6, 0xB6, 0x16,
1031 0x1D, 0x47, 0x9E, 0x19, 0x68, 0xD4, 0x6B, 0x2B,
1032 0x75, 0xCD, 0xAE, 0x65, 0x33, 0x38, 0xF6, 0x6D,
1033 0xC7, 0x3E, 0x46, 0x98, 0x9E, 0x98, 0x8B, 0x45,
1034 0x11, 0xA7, 0x12, 0x05, 0xB0, 0x01, 0xC3, 0x51,
1035 0xA0, 0xEE, 0x7C, 0x16, 0xD1, 0x42, 0x96, 0xC4,
1036 0xF0, 0x7B, 0x71, 0xCD, 0x50, 0x38, 0xA4, 0xB0,
1037 0x6E, 0x6F, 0xE0, 0xBD, 0xC4, 0xF7, 0x96, 0x2B,
1038 0xF1, 0x6D, 0x9F, 0xF3, 0x71, 0x89, 0xFA, 0xB4,
1039 0x44, 0xA4, 0x32, 0xDC, 0xB2, 0x55, 0x13, 0x31,
1040 0x83, 0x29, 0x66, 0x21, 0x3E, 0x89, 0xF8, 0x78,
1041 0x97, 0x9C, 0x64, 0xF9, 0x2C, 0x0A, 0x88, 0xBC,
1042 0xCA, 0x6F, 0x83, 0x42, 0xF6, 0xD7, 0x00, 0xC4,
1043 0x19, 0x52, 0xB0, 0x31, 0xA8, 0xBA, 0xE8, 0xD4,
1044 0xAD, 0x4B, 0x5D, 0xC0, 0x01, 0x20, 0x6C, 0xBB,
1045 0x1D, 0x9A, 0x1D, 0xD4, 0x19, 0xFD, 0x33, 0xAB,
1046 0xA0, 0x54, 0x50, 0x91, 0xE9, 0x75, 0x5C, 0x7E,
1047 0x7E, 0xB3, 0x24, 0x79, 0xAE, 0x10, 0x3C, 0xB4,
1048 0xB7, 0x0A, 0x1D, 0x86, 0xAD, 0x06, 0x95, 0xCB,
1049 0x84, 0x9B, 0x0E, 0x8B, 0x77, 0x7E, 0x3E, 0xD2,
1050 0xA6, 0xDF, 0xAD, 0x4E, 0xFB, 0x69, 0x23, 0xAC,
1051 0x7A, 0xCB, 0xAA, 0xB0, 0x22, 0xDD, 0xD2, 0xC6,
1052 0xC7, 0xAD, 0xD7, 0xDE, 0xEC, 0x6F, 0x08, 0x41,
1053 0x54, 0xD5, 0x52, 0xDC, 0x77, 0xE4, 0x72, 0xF9,
1054 0x16, 0xB1, 0xC9, 0xAF, 0xB1, 0x3B, 0x18, 0x99,
1055 0x20, 0x9F, 0x79, 0x63, 0x7B, 0x07, 0xC7, 0x35,
1056 0xDF, 0xBB, 0xCE, 0x66, 0x93, 0x1B, 0xF5, 0x82,
1057 0x25, 0x67, 0xC1, 0xF2, 0xF0, 0x89, 0x0F, 0xEF,
1058 0x84, 0x0D, 0x63, 0xB6, 0x7B, 0xD0, 0x40, 0x8E,
1059 0xDB, 0x94, 0xCC, 0x71, 0x3C, 0xDB, 0x36, 0x14,
1060 0x34, 0xFD, 0xA0, 0xB0, 0xC1, 0x45, 0x31, 0xF8,
1061 0x8D, 0xD8, 0x23, 0xB1, 0x05, 0x14, 0xA9, 0x55,
1062 0x3A, 0x1A, 0x37, 0x48, 0x68, 0x89, 0x3F, 0x15,
1063 0x25, 0xD4, 0x99, 0x53, 0x4C, 0x85, 0x98, 0x78,
1064 0x1D, 0x35, 0x4A, 0x83, 0x79, 0x9A, 0x29, 0x90,
1065 0x2B, 0x45, 0x76, 0x0C, 0x13, 0x80, 0x4A, 0xE0,
1066 0x40, 0xED, 0x6B, 0x2E, 0x2A, 0x43, 0xA9, 0x28,
1067 0xB0, 0x2F, 0x89, 0x01, 0x6B, 0x39, 0x8C, 0x5E,
1068 0x80, 0x61, 0xD9, 0xEE, 0x0F, 0x41, 0x75, 0xB5,
1069 0xAE, 0xB6, 0xC2, 0x42, 0x49, 0x8D, 0x89, 0xD8,
1070 0xF4, 0x78, 0x1D, 0x90, 0x46, 0x26, 0x4C, 0x56,
1071 0xB7, 0xC0, 0xD9, 0x98, 0x7B, 0x07, 0xA1, 0x20)
1072 }
1073 };
1074
1075 START_TEST(test_ntru_privkey)
1076 {
1077 rng_t *entropy;
1078 ntru_drbg_t *drbg;
1079 ntru_private_key_t *privkey;
1080 ntru_public_key_t *pubkey;
1081 ntru_param_set_t *params;
1082 uint32_t strength;
1083 chunk_t encoding, privkey_encoding, pubkey_encoding;
1084
1085 params = TEST_FUNCTION(ntru, ntru_param_set_get_by_id,
1086 privkey_tests[_i].id);
1087 strength = params->sec_strength_len * BITS_PER_BYTE;
1088 entropy = test_rng_create(privkey_tests[_i].entropy);
1089 drbg = TEST_FUNCTION(ntru, ntru_drbg_create, strength,
1090 chunk_from_str("IKE NTRU-KE"), entropy);
1091 ck_assert(drbg != NULL);
1092
1093 privkey = TEST_FUNCTION(ntru, ntru_private_key_create, drbg, params);
1094 ck_assert(privkey);
1095 ck_assert(privkey->get_id(privkey) == privkey_tests[_i].id);
1096
1097 privkey_encoding = privkey->get_encoding(privkey);
1098 encoding = privkey_tests[_i].encoding;
1099 ck_assert(chunk_equals(privkey_encoding, encoding));
1100
1101 /* load private key as a packed blob */
1102 privkey->destroy(privkey);
1103 privkey = ntru_private_key_create_from_data(drbg, chunk_empty);
1104 ck_assert(privkey == NULL);
1105
1106 encoding = chunk_clone(encoding);
1107 encoding.ptr[0] = NTRU_PUBKEY_TAG;
1108 privkey = ntru_private_key_create_from_data(drbg, encoding);
1109 ck_assert(privkey == NULL);
1110
1111 encoding.ptr[0] = NTRU_PRIVKEY_TRITS_TAG;
1112 privkey = ntru_private_key_create_from_data(drbg, encoding);
1113 if (params->is_product_form)
1114 {
1115 ck_assert(privkey == NULL);
1116 }
1117 else
1118 {
1119 ck_assert(privkey != NULL);
1120 privkey->destroy(privkey);
1121 }
1122
1123 encoding.ptr[0] = NTRU_PRIVKEY_INDICES_TAG;
1124 privkey = ntru_private_key_create_from_data(drbg, encoding);
1125 if (params->is_product_form)
1126 {
1127 ck_assert(privkey != NULL);
1128 privkey->destroy(privkey);
1129 }
1130 else
1131 {
1132 ck_assert(privkey == NULL);
1133 }
1134
1135 encoding.ptr[0] = NTRU_PRIVKEY_DEFAULT_TAG;
1136 encoding.ptr[1] = NTRU_OID_LEN - 1;
1137 privkey = ntru_private_key_create_from_data(drbg, encoding);
1138 ck_assert(privkey == NULL);
1139
1140 encoding.ptr[1] = NTRU_OID_LEN;
1141 encoding.ptr[2] = 0xff;
1142 privkey = ntru_private_key_create_from_data(drbg, encoding);
1143 ck_assert(privkey == NULL);
1144
1145 encoding.ptr[2] = params->oid[0];
1146 privkey = ntru_private_key_create_from_data(drbg, encoding);
1147 privkey_encoding = privkey->get_encoding(privkey);
1148 ck_assert(chunk_equals(privkey_encoding, encoding));
1149
1150 pubkey = privkey->get_public_key(privkey);
1151 pubkey_encoding = pubkey->get_encoding(pubkey);
1152
1153 encoding.ptr[0] = NTRU_PUBKEY_TAG;
1154 encoding.len = pubkey_encoding.len;
1155 ck_assert(chunk_equals(pubkey_encoding, encoding));
1156
1157 /* load public key as a packed blob */
1158 pubkey->destroy(pubkey);
1159 pubkey = ntru_public_key_create_from_data(drbg, encoding);
1160 pubkey_encoding = pubkey->get_encoding(pubkey);
1161 ck_assert(chunk_equals(pubkey_encoding, encoding));
1162
1163 chunk_free(&encoding);
1164 privkey->destroy(privkey);
1165 pubkey->destroy(pubkey);
1166 }
1167 END_TEST
1168
1169 START_TEST(test_ntru_ke)
1170 {
1171 chunk_t pub_key, cipher_text, i_shared_secret, r_shared_secret;
1172 diffie_hellman_t *i_ntru, *r_ntru;
1173 char buf[10];
1174 int k, n, len;
1175 status_t status;
1176
1177 k = (_i) / countof(parameter_sets);
1178 n = (_i) % countof(parameter_sets);
1179
1180 len = snprintf(buf, sizeof(buf), "%N", diffie_hellman_group_names,
1181 params[k].group);
1182 ck_assert(len == 8);
1183 ck_assert(streq(buf, params[k].group_name));
1184
1185 lib->settings->set_str(lib->settings,
1186 "libstrongswan.plugins.ntru.parameter_set", parameter_sets[n]);
1187
1188 i_ntru = lib->crypto->create_dh(lib->crypto, params[k].group);
1189 ck_assert(i_ntru != NULL);
1190 ck_assert(i_ntru->get_dh_group(i_ntru) == params[k].group);
1191
1192 i_ntru->get_my_public_value(i_ntru, &pub_key);
1193 ck_assert(pub_key.len > 0);
1194
1195 r_ntru = lib->crypto->create_dh(lib->crypto, params[k].group);
1196 ck_assert(r_ntru != NULL);
1197
1198 r_ntru->set_other_public_value(r_ntru, pub_key);
1199 r_ntru->get_my_public_value(r_ntru, &cipher_text);
1200 ck_assert(cipher_text.len > 0);
1201
1202 status = r_ntru->get_shared_secret(r_ntru, &r_shared_secret);
1203 ck_assert(status == SUCCESS);
1204 ck_assert(r_shared_secret.len > 0);
1205
1206 i_ntru->set_other_public_value(i_ntru, cipher_text);
1207 status = i_ntru->get_shared_secret(i_ntru, &i_shared_secret);
1208 ck_assert(status == SUCCESS);
1209 ck_assert(chunk_equals(i_shared_secret, r_shared_secret));
1210
1211 chunk_clear(&i_shared_secret);
1212 chunk_clear(&r_shared_secret);
1213 chunk_free(&pub_key);
1214 chunk_free(&cipher_text);
1215 i_ntru->destroy(i_ntru);
1216 r_ntru->destroy(r_ntru);
1217 }
1218 END_TEST
1219
1220 START_TEST(test_ntru_retransmission)
1221 {
1222 diffie_hellman_t *i_ntru;
1223 chunk_t pub_key1, pub_key2;
1224
1225 i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_256_BIT);
1226 i_ntru->get_my_public_value(i_ntru, &pub_key1);
1227 i_ntru->get_my_public_value(i_ntru, &pub_key2);
1228 ck_assert(chunk_equals(pub_key1, pub_key2));
1229
1230 chunk_free(&pub_key1);
1231 chunk_free(&pub_key2);
1232 i_ntru->destroy(i_ntru);
1233 }
1234 END_TEST
1235
1236 chunk_t oid_tests[] = {
1237 { NULL, 0 },
1238 chunk_from_chars(0x00),
1239 chunk_from_chars(0x01),
1240 chunk_from_chars(0x02),
1241 chunk_from_chars(0x02, 0x03, 0x00, 0x03, 0x10),
1242 chunk_from_chars(0x01, 0x04, 0x00, 0x03, 0x10),
1243 chunk_from_chars(0x01, 0x03, 0x00, 0x03, 0x10),
1244 chunk_from_chars(0x01, 0x03, 0xff, 0x03, 0x10),
1245 };
1246
1247 START_TEST(test_ntru_pubkey_oid)
1248 {
1249 diffie_hellman_t *r_ntru;
1250 chunk_t cipher_text;
1251
1252 r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
1253 r_ntru->set_other_public_value(r_ntru, oid_tests[_i]);
1254 r_ntru->get_my_public_value(r_ntru, &cipher_text);
1255 ck_assert(cipher_text.len == 0);
1256 r_ntru->destroy(r_ntru);
1257 }
1258 END_TEST
1259
1260 START_TEST(test_ntru_wrong_set)
1261 {
1262 diffie_hellman_t *i_ntru, *r_ntru;
1263 chunk_t pub_key, cipher_text;
1264
1265 lib->settings->set_str(lib->settings,
1266 "libstrongswan.plugins.ntru.parameter_set",
1267 "x9_98_bandwidth");
1268 i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT);
1269 i_ntru->get_my_public_value(i_ntru, &pub_key);
1270
1271 lib->settings->set_str(lib->settings,
1272 "libstrongswan.plugins.ntru.parameter_set",
1273 "optimum");
1274 r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT);
1275 r_ntru->set_other_public_value(r_ntru, pub_key);
1276 r_ntru->get_my_public_value(r_ntru, &cipher_text);
1277 ck_assert(cipher_text.len == 0);
1278
1279 chunk_free(&pub_key);
1280 chunk_free(&cipher_text);
1281 i_ntru->destroy(i_ntru);
1282 r_ntru->destroy(r_ntru);
1283 }
1284 END_TEST
1285
1286 START_TEST(test_ntru_ciphertext)
1287 {
1288 char buf_00[604], buf_ff[604];
1289
1290 chunk_t test[] = {
1291 chunk_empty,
1292 chunk_from_chars(0x00),
1293 chunk_create(buf_00, sizeof(buf_00)),
1294 chunk_create(buf_ff, sizeof(buf_ff)),
1295 };
1296
1297 diffie_hellman_t *i_ntru;
1298 chunk_t pub_key, shared_secret;
1299 int i;
1300
1301 memset(buf_00, 0x00, sizeof(buf_00));
1302 memset(buf_ff, 0xff, sizeof(buf_ff));
1303
1304 for (i = 0; i < countof(test); i++)
1305 {
1306 i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
1307 i_ntru->get_my_public_value(i_ntru, &pub_key);
1308 i_ntru->set_other_public_value(i_ntru, test[i]);
1309 ck_assert(i_ntru->get_shared_secret(i_ntru, &shared_secret) != SUCCESS);
1310 ck_assert(shared_secret.len == 0);
1311
1312 chunk_free(&pub_key);
1313 i_ntru->destroy(i_ntru);
1314 }
1315 }
1316 END_TEST
1317
1318 START_TEST(test_ntru_wrong_ciphertext)
1319 {
1320 diffie_hellman_t *i_ntru, *r_ntru, *m_ntru;
1321 chunk_t pub_key_i, pub_key_m, cipher_text, shared_secret;
1322
1323 i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
1324 r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
1325 m_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
1326
1327 i_ntru->get_my_public_value(i_ntru, &pub_key_i);
1328 m_ntru->get_my_public_value(m_ntru, &pub_key_m);
1329 r_ntru->set_other_public_value(r_ntru, pub_key_m);
1330 r_ntru->get_my_public_value(r_ntru, &cipher_text);
1331 i_ntru->set_other_public_value(i_ntru, cipher_text);
1332 ck_assert(i_ntru->get_shared_secret(i_ntru, &shared_secret) != SUCCESS);
1333 ck_assert(shared_secret.len == 0);
1334
1335 chunk_free(&pub_key_i);
1336 chunk_free(&pub_key_m);
1337 chunk_free(&cipher_text);
1338 i_ntru->destroy(i_ntru);
1339 m_ntru->destroy(m_ntru);
1340 r_ntru->destroy(r_ntru);
1341 }
1342 END_TEST
1343
1344 Suite *ntru_suite_create()
1345 {
1346 Suite *s;
1347 TCase *tc;
1348
1349 s = suite_create("ntru");
1350
1351 tc = tcase_create("drbg_strength");
1352 tcase_add_loop_test(tc, test_ntru_drbg_strength, 0, countof(strengths));
1353 suite_add_tcase(s, tc);
1354
1355 tc = tcase_create("drbg");
1356 tcase_add_loop_test(tc, test_ntru_drbg, 0, countof(drbg_tests));
1357 suite_add_tcase(s, tc);
1358
1359 tc = tcase_create("drgb_reseed");
1360 tcase_add_test(tc, test_ntru_drbg_reseed);
1361 suite_add_tcase(s, tc);
1362
1363 tc = tcase_create("mgf1");
1364 tcase_add_loop_test(tc, test_ntru_mgf1, 0, countof(mgf1_tests));
1365 suite_add_tcase(s, tc);
1366
1367 tc = tcase_create("trits");
1368 tcase_add_loop_test(tc, test_ntru_trits, 0, countof(mgf1_tests));
1369 suite_add_tcase(s, tc);
1370
1371 tc = tcase_create("poly");
1372 tcase_add_loop_test(tc, test_ntru_poly, 0, countof(mgf1_tests));
1373 suite_add_tcase(s, tc);
1374
1375 tc = tcase_create("ring_mult");
1376 tcase_add_loop_test(tc, test_ntru_ring_mult, 0, countof(ring_mult_tests));
1377 suite_add_tcase(s, tc);
1378
1379 tc = tcase_create("array");
1380 tcase_add_loop_test(tc, test_ntru_array, 0, countof(array_tests));
1381 suite_add_tcase(s, tc);
1382
1383 tc = tcase_create("param_set");
1384 tcase_add_test(tc, test_ntru_param_set);
1385 suite_add_tcase(s, tc);
1386
1387 tc = tcase_create("privkey");
1388 tcase_add_loop_test(tc, test_ntru_privkey, 0, countof(privkey_tests));
1389 suite_add_tcase(s, tc);
1390
1391 tc = tcase_create("ke");
1392 tcase_add_loop_test(tc, test_ntru_ke, 0,
1393 countof(params) * countof(parameter_sets));
1394 suite_add_tcase(s, tc);
1395
1396 tc = tcase_create("retransmission");
1397 tcase_add_test(tc, test_ntru_retransmission);
1398 suite_add_tcase(s, tc);
1399
1400 tc = tcase_create("pubkey_oid");
1401 tcase_add_loop_test(tc, test_ntru_pubkey_oid, 0, countof(oid_tests));
1402 suite_add_tcase(s, tc);
1403
1404 tc = tcase_create("wrong_set");
1405 tcase_add_test(tc, test_ntru_wrong_set);
1406 suite_add_tcase(s, tc);
1407
1408 tc = tcase_create("ciphertext");
1409 tcase_add_test(tc, test_ntru_ciphertext);
1410 suite_add_tcase(s, tc);
1411
1412 tc = tcase_create("wrong_ciphertext");
1413 tcase_add_test(tc, test_ntru_wrong_ciphertext);
1414 suite_add_tcase(s, tc);
1415 return s;
1416 }