a46f5742ce49596660f38b9e8d971039d52bfe94
[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 <utils/test.h>
24
25 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_drbg_create, ntru_drbg_t*,
26 u_int32_t strength, chunk_t pers_str, rng_t *entropy)
27
28 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_mgf1_create, ntru_mgf1_t*,
29 hash_algorithm_t alg, chunk_t seed, bool hash_seed)
30
31 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_trits_create, ntru_trits_t*,
32 size_t len, hash_algorithm_t alg, chunk_t seed)
33
34 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_poly_create_from_seed, ntru_poly_t*,
35 hash_algorithm_t alg, chunk_t seed, uint8_t c_bits,
36 uint16_t N, uint16_t q, uint32_t indices_len_p,
37 uint32_t indices_len_m, bool is_product_form)
38
39 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_poly_create_from_data, ntru_poly_t*,
40 u_int16_t *data, uint16_t N, uint16_t q,
41 uint32_t indices_len_p, uint32_t indices_len_m,
42 bool is_product_form)
43
44 /**
45 * NTRU parameter sets to test
46 */
47 static struct {
48 diffie_hellman_group_t group;
49 char *group_name;
50 } params[] = {
51 { NTRU_112_BIT, "NTRU_112" },
52 { NTRU_128_BIT, "NTRU_128" },
53 { NTRU_192_BIT, "NTRU_192" },
54 { NTRU_256_BIT, "NTRU_256" }
55 };
56
57 /**
58 * NTRU parameter set selection
59 */
60 char *parameter_sets[] = {
61 "x9_98_speed", "x9_98_bandwidth", "x9_98_balance", "optimum"
62 };
63
64 typedef struct {
65 u_int32_t requested;
66 u_int32_t standard;
67 }strength_t;
68
69 strength_t strengths[] = {
70 { 80, 112 },
71 { 112, 112 },
72 { 120, 128 },
73 { 128, 128 },
74 { 150, 192 },
75 { 192, 192 },
76 { 200, 256 },
77 { 256, 256 },
78 { 512, 0 }
79 };
80
81 START_TEST(test_ntru_drbg_strength)
82 {
83 ntru_drbg_t *drbg;
84 rng_t *entropy;
85
86 entropy = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
87 ck_assert(entropy != NULL);
88
89 drbg = ntru_drbg_create(strengths[_i].requested, chunk_empty, entropy);
90 if (strengths[_i].standard)
91 {
92 ck_assert(drbg != NULL);
93 ck_assert(drbg->get_strength(drbg) == strengths[_i].standard);
94 drbg->destroy(drbg);
95 }
96 else
97 {
98 ck_assert(drbg == NULL);
99 }
100 entropy->destroy(entropy);
101 }
102 END_TEST
103
104 typedef struct {
105 chunk_t pers_str;
106 chunk_t entropy;
107 chunk_t out;
108 } drbg_test_t;
109
110 /**
111 * NIST SP 800-90A Deterministic Random Generator Validation System (DRBGVS)
112 */
113 drbg_test_t drbg_tests[] = {
114 /* SHA-256 test case 1 - count 0 */
115 { { NULL, 0 },
116 chunk_from_chars(0x06, 0x03, 0x2c, 0xd5, 0xee, 0xd3, 0x3f, 0x39,
117 0x26, 0x5f, 0x49, 0xec, 0xb1, 0x42, 0xc5, 0x11,
118 0xda, 0x9a, 0xff, 0x2a, 0xf7, 0x12, 0x03, 0xbf,
119 0xfa, 0xf3, 0x4a, 0x9c, 0xa5, 0xbd, 0x9c, 0x0d,
120 0x0e, 0x66, 0xf7, 0x1e, 0xdc, 0x43, 0xe4, 0x2a,
121 0x45, 0xad, 0x3c, 0x6f, 0xc6, 0xcd, 0xc4, 0xdf,
122 0x01, 0x92, 0x0a, 0x4e, 0x66, 0x9e, 0xd3, 0xa8,
123 0x5a, 0xe8, 0xa3, 0x3b, 0x35, 0xa7, 0x4a, 0xd7,
124 0xfb, 0x2a, 0x6b, 0xb4, 0xcf, 0x39, 0x5c, 0xe0,
125 0x03, 0x34, 0xa9, 0xc9, 0xa5, 0xa5, 0xd5, 0x52),
126 chunk_from_chars(0x76, 0xfc, 0x79, 0xfe, 0x9b, 0x50, 0xbe, 0xcc,
127 0xc9, 0x91, 0xa1, 0x1b, 0x56, 0x35, 0x78, 0x3a,
128 0x83, 0x53, 0x6a, 0xdd, 0x03, 0xc1, 0x57, 0xfb,
129 0x30, 0x64, 0x5e, 0x61, 0x1c, 0x28, 0x98, 0xbb,
130 0x2b, 0x1b, 0xc2, 0x15, 0x00, 0x02, 0x09, 0x20,
131 0x8c, 0xd5, 0x06, 0xcb, 0x28, 0xda, 0x2a, 0x51,
132 0xbd, 0xb0, 0x38, 0x26, 0xaa, 0xf2, 0xbd, 0x23,
133 0x35, 0xd5, 0x76, 0xd5, 0x19, 0x16, 0x08, 0x42,
134 0xe7, 0x15, 0x8a, 0xd0, 0x94, 0x9d, 0x1a, 0x9e,
135 0xc3, 0xe6, 0x6e, 0xa1, 0xb1, 0xa0, 0x64, 0xb0,
136 0x05, 0xde, 0x91, 0x4e, 0xac, 0x2e, 0x9d, 0x4f,
137 0x2d, 0x72, 0xa8, 0x61, 0x6a, 0x80, 0x22, 0x54,
138 0x22, 0x91, 0x82, 0x50, 0xff, 0x66, 0xa4, 0x1b,
139 0xd2, 0xf8, 0x64, 0xa6, 0xa3, 0x8c, 0xc5, 0xb6,
140 0x49, 0x9d, 0xc4, 0x3f, 0x7f, 0x2b, 0xd0, 0x9e,
141 0x1e, 0x0f, 0x8f, 0x58, 0x85, 0x93, 0x51, 0x24)
142 },
143 /* SHA-256 test case 3 - count 0 */
144 { chunk_from_chars(0xf2, 0xe5, 0x8f, 0xe6, 0x0a, 0x3a, 0xfc, 0x59,
145 0xda, 0xd3, 0x75, 0x95, 0x41, 0x5f, 0xfd, 0x31,
146 0x8c, 0xcf, 0x69, 0xd6, 0x77, 0x80, 0xf6, 0xfa,
147 0x07, 0x97, 0xdc, 0x9a, 0xa4, 0x3e, 0x14, 0x4c),
148 chunk_from_chars(0xfa, 0x0e, 0xe1, 0xfe, 0x39, 0xc7, 0xc3, 0x90,
149 0xaa, 0x94, 0x15, 0x9d, 0x0d, 0xe9, 0x75, 0x64,
150 0x34, 0x2b, 0x59, 0x17, 0x77, 0xf3, 0xe5, 0xf6,
151 0xa4, 0xba, 0x2a, 0xea, 0x34, 0x2e, 0xc8, 0x40,
152 0xdd, 0x08, 0x20, 0x65, 0x5c, 0xb2, 0xff, 0xdb,
153 0x0d, 0xa9, 0xe9, 0x31, 0x0a, 0x67, 0xc9, 0xe5,
154 0xe0, 0x62, 0x9b, 0x6d, 0x79, 0x75, 0xdd, 0xfa,
155 0x96, 0xa3, 0x99, 0x64, 0x87, 0x40, 0xe6, 0x0f,
156 0x1f, 0x95, 0x57, 0xdc, 0x58, 0xb3, 0xd7, 0x41,
157 0x5f, 0x9b, 0xa9, 0xd4, 0xdb, 0xb5, 0x01, 0xf6),
158 chunk_from_chars(0xf9, 0x2d, 0x4c, 0xf9, 0x9a, 0x53, 0x5b, 0x20,
159 0x22, 0x2a, 0x52, 0xa6, 0x8d, 0xb0, 0x4c, 0x5a,
160 0xf6, 0xf5, 0xff, 0xc7, 0xb6, 0x6a, 0x47, 0x3a,
161 0x37, 0xa2, 0x56, 0xbd, 0x8d, 0x29, 0x8f, 0x9b,
162 0x4a, 0xa4, 0xaf, 0x7e, 0x8d, 0x18, 0x1e, 0x02,
163 0x36, 0x79, 0x03, 0xf9, 0x3b, 0xdb, 0x74, 0x4c,
164 0x6c, 0x2f, 0x3f, 0x34, 0x72, 0x62, 0x6b, 0x40,
165 0xce, 0x9b, 0xd6, 0xa7, 0x0e, 0x7b, 0x8f, 0x93,
166 0x99, 0x2a, 0x16, 0xa7, 0x6f, 0xab, 0x6b, 0x5f,
167 0x16, 0x25, 0x68, 0xe0, 0x8e, 0xe6, 0xc3, 0xe8,
168 0x04, 0xae, 0xfd, 0x95, 0x2d, 0xdd, 0x3a, 0xcb,
169 0x79, 0x1c, 0x50, 0xf2, 0xad, 0x69, 0xe9, 0xa0,
170 0x40, 0x28, 0xa0, 0x6a, 0x9c, 0x01, 0xd3, 0xa6,
171 0x2a, 0xca, 0x2a, 0xaf, 0x6e, 0xfe, 0x69, 0xed,
172 0x97, 0xa0, 0x16, 0x21, 0x3a, 0x2d, 0xd6, 0x42,
173 0xb4, 0x88, 0x67, 0x64, 0x07, 0x2d, 0x9c, 0xbe)
174 },
175 /* SHA-256 test case 5 - count 0 */
176 { { NULL, 0 },
177 chunk_from_chars(0xff, 0x0c, 0xdd, 0x55, 0x5c, 0x60, 0x46, 0x47,
178 0x60, 0xb2, 0x89, 0xb7, 0xbc, 0x1f, 0x81, 0x1a,
179 0x41, 0xff, 0xf7, 0x2d, 0xe5, 0x90, 0x83, 0x85,
180 0x8c, 0x02, 0x0a, 0x10, 0x53, 0xbd, 0xc7, 0x4a,
181 0x7b, 0xc0, 0x99, 0x28, 0x5a, 0xd5, 0x62, 0x19,
182 0x93, 0xb6, 0x39, 0xc4, 0xa9, 0x4c, 0x37, 0x6b,
183 0x14, 0xfc, 0x6c, 0x9b, 0x17, 0x8d, 0xb6, 0x44,
184 0xa8, 0xcd, 0x71, 0x30, 0xa4, 0xcf, 0x05, 0x16,
185 0x78, 0xc8, 0xf4, 0xfa, 0x8f, 0x24, 0xc2, 0x7b,
186 0x0a, 0x53, 0x13, 0x38, 0xa5, 0xce, 0x85, 0x89),
187 chunk_from_chars(0x2f, 0x26, 0x20, 0x34, 0x7b, 0xdd, 0xca, 0xa2,
188 0x94, 0x36, 0x85, 0x34, 0x6b, 0xbf, 0x31, 0xc4,
189 0x40, 0x81, 0xf8, 0x66, 0x5f, 0x3d, 0xdb, 0x2b,
190 0x42, 0xae, 0x14, 0x16, 0xa7, 0x4c, 0x4b, 0x77,
191 0xfa, 0xb3, 0xfa, 0x19, 0xae, 0xec, 0xc5, 0x47,
192 0xe7, 0x6c, 0x8c, 0xbe, 0x6a, 0xd1, 0xf1, 0x00,
193 0xa3, 0xfc, 0x8b, 0x2c, 0xe2, 0xa1, 0xea, 0x3a,
194 0x3d, 0xd7, 0xcf, 0xad, 0x46, 0xc1, 0xb2, 0x78,
195 0x30, 0xb9, 0x40, 0xba, 0x18, 0xd0, 0x9e, 0x9b,
196 0x7f, 0xa9, 0x02, 0xbb, 0x76, 0x06, 0x69, 0xb1,
197 0x73, 0x5c, 0xc7, 0xb7, 0xbd, 0x39, 0x05, 0x2d,
198 0xa7, 0xf2, 0x62, 0x6f, 0xa8, 0x70, 0x00, 0xcf,
199 0xfa, 0xda, 0x41, 0x00, 0x19, 0xd0, 0x53, 0x38,
200 0x6a, 0xd8, 0x08, 0xbd, 0x3c, 0x0c, 0xfc, 0xf5,
201 0x6b, 0x91, 0x87, 0x9e, 0xb8, 0xd3, 0xf9, 0x32,
202 0xee, 0x2d, 0x18, 0x5e, 0x54, 0xf3, 0x1b, 0x74)
203 },
204 /* SHA-256 test case 7 - count 0 */
205 { chunk_from_chars(0x40, 0x93, 0x3f, 0xdc, 0xce, 0x41, 0x59, 0xb0,
206 0x95, 0x51, 0x11, 0xf8, 0x44, 0x47, 0x1b, 0x0d,
207 0xb8, 0x5b, 0x73, 0xbd, 0xd2, 0xb7, 0x8c, 0x46,
208 0x8d, 0xd3, 0x9e, 0x2a, 0x9b, 0x29, 0xae, 0xf2),
209 chunk_from_chars(0x28, 0xba, 0x1a, 0x66, 0x16, 0x32, 0xef, 0xc8,
210 0xec, 0xce, 0xd5, 0xf5, 0x1b, 0x79, 0x13, 0x00,
211 0xfb, 0x3b, 0x55, 0xb0, 0x5d, 0x04, 0x17, 0x08,
212 0x63, 0x8d, 0xe4, 0xbe, 0xb7, 0x57, 0xa9, 0xe5,
213 0x76, 0x82, 0x87, 0x96, 0xaf, 0xf0, 0x7f, 0x55,
214 0x79, 0x5c, 0xb5, 0x47, 0x13, 0xc7, 0x7e, 0xd4,
215 0xa5, 0xf5, 0x42, 0xb0, 0x4a, 0xaa, 0x5d, 0xbc,
216 0x93, 0x1e, 0x47, 0x01, 0x9f, 0xeb, 0x38, 0x96,
217 0x26, 0x16, 0xc5, 0x7a, 0xf0, 0x9b, 0x7c, 0x1d,
218 0xf8, 0x3f, 0x2b, 0x86, 0x0f, 0xf7, 0x65, 0x86),
219 chunk_from_chars(0x65, 0xe5, 0xaa, 0x47, 0xb3, 0x85, 0xf1, 0xea,
220 0x42, 0xb2, 0x31, 0xb9, 0xfe, 0x74, 0x42, 0x53,
221 0xb8, 0x59, 0x88, 0x59, 0xd7, 0x01, 0x1e, 0x52,
222 0x5f, 0x5a, 0x2a, 0x1a, 0xd3, 0x2a, 0x97, 0x2a,
223 0x85, 0x08, 0x02, 0xc6, 0x0a, 0x2b, 0xe1, 0x9b,
224 0xe2, 0x70, 0x06, 0x3a, 0x3c, 0xfb, 0xea, 0xae,
225 0x95, 0x4f, 0x10, 0xb1, 0x22, 0x35, 0x2d, 0xe6,
226 0xa0, 0x8a, 0xc4, 0x10, 0xe0, 0x99, 0x16, 0x53,
227 0xaa, 0xb2, 0x71, 0xb3, 0x60, 0xfe, 0x91, 0x91,
228 0xcf, 0x5a, 0xdd, 0xcc, 0xcc, 0xed, 0x8c, 0x4a,
229 0xcf, 0xb6, 0x14, 0x57, 0x04, 0x99, 0x92, 0x98,
230 0x8f, 0xd7, 0xa9, 0xac, 0xca, 0x1f, 0x1b, 0xca,
231 0x35, 0xf1, 0x47, 0x58, 0x13, 0x69, 0x4a, 0x39,
232 0x98, 0x8e, 0x5f, 0xac, 0x9f, 0x4a, 0xc0, 0x57,
233 0x22, 0x86, 0xbc, 0x46, 0x25, 0x82, 0xad, 0x0a,
234 0xf7, 0x8a, 0xb3, 0xb8, 0x5e, 0xc1, 0x7a, 0x25)
235 }
236 };
237
238 START_TEST(test_ntru_drbg)
239 {
240 ntru_drbg_t *drbg;
241 rng_t *entropy;
242 chunk_t out;
243
244 out = chunk_alloc(128);
245 entropy = test_rng_create(drbg_tests[_i].entropy);
246 drbg = ntru_drbg_create(256, drbg_tests[_i].pers_str, entropy);
247 ck_assert(drbg != NULL);
248 ck_assert(drbg->reseed(drbg));
249 ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
250 ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
251 ck_assert(chunk_equals(out, drbg_tests[_i].out));
252 drbg->destroy(drbg);
253 entropy->destroy(entropy);
254 chunk_free(&out);
255 }
256 END_TEST
257
258 START_TEST(test_ntru_drbg_reseed)
259 {
260 ntru_drbg_t *drbg;
261 rng_t *entropy;
262 chunk_t out;
263
264 lib->settings->set_int(lib->settings,
265 "libstrongswan.plugins.ntru.max_drbg_requests", 2);
266 out = chunk_alloc(128);
267 entropy = test_rng_create(drbg_tests[0].entropy);
268 drbg = ntru_drbg_create(256, chunk_empty, entropy);
269
270 /* bad output parameters */
271 ck_assert(!drbg->generate(drbg, 256, 0, out.ptr));
272 ck_assert(!drbg->generate(drbg, 256, 128, NULL));
273
274 /* no reseeding occurs */
275 ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
276 ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
277
278 /* consuming remaining entropy */
279 ck_assert(entropy->get_bytes(entropy, 32, out.ptr));
280
281 /* no entropy available for automatic reseeding */
282 ck_assert(!drbg->generate(drbg, 256, 128, out.ptr));
283 drbg->destroy(drbg);
284
285 /* no entropy available for DRBG instantiation */
286 drbg = ntru_drbg_create(256, chunk_empty, entropy);
287 ck_assert(drbg == NULL);
288 entropy->destroy(entropy);
289
290 /* one automatic reseeding occurs */
291 entropy = test_rng_create(drbg_tests[0].entropy);
292 drbg = ntru_drbg_create(256, chunk_empty, entropy);
293 ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
294 ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
295 ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
296
297 /* no entropy left */
298 ck_assert(!entropy->get_bytes(entropy, 32, out.ptr));
299
300 drbg->destroy(drbg);
301 entropy->destroy(entropy);
302 chunk_free(&out);
303 lib->settings->set_int(lib->settings,
304 "libstrongswan.plugins.ntru.max_drbg_requests", 2000);
305 }
306 END_TEST
307
308 typedef struct {
309 uint8_t c_bits;
310 uint16_t N;
311 uint16_t q;
312 bool is_product_form;
313 uint32_t indices_len;
314 uint32_t indices_size;
315 uint16_t *indices;
316 } poly_test_t;
317
318 typedef struct {
319 hash_algorithm_t alg;
320 size_t hash_size;
321 size_t ml1, ml2, ml3, seed_len;
322 chunk_t seed;
323 chunk_t hashed_seed;
324 chunk_t mask;
325 chunk_t trits;
326 poly_test_t poly_test[2];
327 } mgf1_test_t;
328
329 uint16_t indices_ees439ep1[] = {
330 367, 413, 16, 214, 114, 128, 42, 268, 346, 329, 119, 303, 208, 287, 150,
331 3, 45, 321, 110, 109, 272, 430, 80, 305, 51, 381, 322, 140, 207, 315,
332 206, 186, 56, 5, 273, 177, 44, 100, 205, 210, 98, 191, 8, 336
333 };
334
335 uint16_t indices_ees613ep1[] = {
336 245, 391, 251, 428, 301, 2, 176, 296, 461, 224, 590, 215, 250, 91, 395,
337 363, 58, 537, 278, 291, 247, 33, 140, 447, 172, 514, 424, 412, 95, 94,
338 281, 159, 196, 302, 277, 63, 404, 150, 608, 315, 195, 334, 207, 376, 398,
339 0, 309, 486, 516, 86, 267, 139, 130, 38, 141, 258, 21, 341, 526, 388,
340 194, 116, 138, 524, 547, 383, 542, 406, 270, 438, 240, 445, 527, 168, 320,
341 186, 327, 212, 543, 82, 606, 131, 294, 392, 477, 430, 583, 142, 253, 434,
342 134, 458, 559, 414, 162, 407, 580, 577, 191, 109, 554, 523, 32, 62, 297,
343 283, 268, 54, 539, 5
344 };
345
346 uint16_t indices_ees743ep1[] = {
347 285, 62, 136, 655, 460, 35, 450, 208, 340, 212, 61, 234, 454, 52, 520,
348 399, 315, 616, 496, 88, 280, 543, 508, 237, 553, 39, 214, 253, 720, 291,
349 586, 615, 635, 596, 62, 499, 301, 176, 271, 659, 372, 185, 621, 350, 683,
350 180, 717, 509, 641, 738, 666, 171, 639, 606, 353, 706, 237, 358, 410, 423,
351 197, 501, 261, 654, 658, 701, 377, 182, 548, 287, 700, 403, 248, 137
352 };
353
354 uint16_t indices_ees1171ep1[] = {
355 514, 702, 760, 505, 262, 486, 695, 783, 533, 74, 403, 847, 170,1019, 568,
356 676,1057, 277,1021, 238, 203, 884, 124, 87, 65, 93, 131, 881,1102, 133,
357 459, 462, 92, 40, 5,1152,1158, 297, 599, 299, 7, 458, 347, 343, 173,
358 1044, 264, 871, 819, 679, 328, 438, 990, 982, 308,1135, 423, 470, 254, 295,
359 1029, 892, 759, 789, 123, 939, 749, 353,1062, 145, 562, 337, 550, 102, 549,
360 821,1098, 823, 96, 365, 135,1110, 334, 391, 638, 963, 962,1002,1069, 993,
361 983, 649,1056, 399, 385, 715, 582, 799, 161, 512, 629, 979, 250, 37, 213,
362 929, 413, 566, 336, 727, 160, 616,1170, 748, 282,1115, 325, 994, 189, 500,
363 913, 332,1118, 753, 946, 775, 59, 809, 782, 612, 909,1090, 223, 777, 940,
364 866,1032, 471, 298, 969, 192, 411, 721, 476, 910,1045,1027, 812, 352, 487,
365 215, 625, 808, 230, 602, 457, 900, 416, 985, 850, 908, 155, 670, 669,1054,
366 400,1126, 733, 647, 786, 195, 148, 362,1094, 389,1086,1166, 231, 436, 210,
367 333, 824, 785, 826, 658, 472, 639,1046,1028, 519, 422, 80, 924,1089, 547,
368 1157, 579, 2, 508,1040, 998, 902,1058, 600, 220, 805, 945, 140,1117, 179,
369 536, 191
370 };
371
372 /**
373 * MGF1 Mask Generation Function Test Vectors
374 */
375 mgf1_test_t mgf1_tests[] = {
376 { HASH_SHA1, 20, 60, 20, 15, 24,
377 chunk_from_chars(
378 0xED, 0xA5, 0xC3, 0xBC, 0xAF, 0xB3, 0x20, 0x7D,
379 0x14, 0xA1, 0x54, 0xF7, 0x8B, 0x37, 0xF2, 0x8D,
380 0x8C, 0x9B, 0xD5, 0x63, 0x57, 0x38, 0x11, 0xC2,
381 0xB5, 0xCA, 0xBF, 0x06, 0x43, 0x45, 0x19, 0xD5,
382 0xE7, 0x36, 0xD0, 0x29, 0x21, 0xDA, 0x02, 0x20,
383 0x45, 0xF6, 0x5F, 0x0F, 0x10, 0x04, 0x2A, 0xE3,
384 0x6A, 0x1D, 0xD5, 0x9F, 0x1D, 0x66, 0x44, 0x8F,
385 0xFA, 0xC6, 0xCA, 0xA4, 0x6E, 0x3B, 0x00, 0x66,
386 0xA6, 0xC9, 0x80, 0x5C, 0xF5, 0x2D, 0xD7, 0x72,
387 0xC6, 0xD4, 0x4F, 0x30, 0x72, 0xA2, 0xAD, 0xE0,
388 0x33, 0xE8, 0x55, 0xD5, 0xE6, 0xD6, 0x00, 0x1D,
389 0xA8, 0x68, 0xFF, 0x97, 0x36, 0x8A, 0xF4, 0xD6,
390 0xF1, 0xB6, 0x7E, 0x1F, 0x06, 0xCB, 0x57, 0xCB,
391 0x35, 0x38, 0xF2, 0x2D, 0xF6, 0x20),
392 chunk_from_chars(
393 0xF3, 0x9B, 0x0B, 0xB4, 0x97, 0x50, 0xB5, 0xA7,
394 0xE6, 0xBD, 0xDA, 0xD0, 0x9A, 0x52, 0xBE, 0xA0,
395 0x21, 0xC4, 0x90, 0xB6),
396 chunk_from_chars(
397 0x10, 0x43, 0x76, 0x72, 0x6C, 0xDE, 0xA0, 0x0E,
398 0x77, 0x51, 0xFB, 0x58, 0x39, 0x8A, 0x36, 0xE1,
399 0x63, 0x2B, 0xC9, 0x17, 0x56, 0x0C, 0x4B, 0x46,
400 0xA4, 0x07, 0xA4, 0x3B, 0x8E, 0x33, 0x4D, 0xD1,
401 0x65, 0xF1, 0xAC, 0xC8, 0x59, 0x21, 0x32, 0x16,
402 0x44, 0x2B, 0x7F, 0xB2, 0xA8, 0xA7, 0x26, 0x5D,
403 0xE8, 0x02, 0xBE, 0x8E, 0xDC, 0x34, 0xEB, 0x10,
404 0x76, 0x16, 0x8C, 0xDD, 0x90, 0x92, 0x3D, 0x29,
405 0x90, 0x98, 0x46, 0x11, 0x73, 0x53, 0x47, 0xB1,
406 0x2C, 0xD4, 0x83, 0x78, 0x9B, 0x93, 0x2F, 0x5B,
407 0xFC, 0x26, 0xFF, 0x42, 0x08, 0x1F, 0x70, 0x66,
408 0x40, 0x4B, 0xE7, 0x22, 0x3A, 0x56, 0x10, 0x6D,
409 0x4D, 0x29, 0x0B, 0xCE, 0xA6, 0x21, 0xB5, 0x5C,
410 0x71, 0x66, 0x2F, 0x70, 0x35, 0xD8, 0x8A, 0x92,
411 0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14),
412 chunk_from_chars(
413 1, 2, 1, 0, 0, 1, 1, 1, 2, 0, 1, 0, 1, 1, 1, 0, 2, 0, 1, 1,
414 0, 0, 0, 1, 1, 0, 2, 0, 2, 2, 1, 2, 2, 2, 1, 2, 1, 1, 0, 0,
415 2, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 2, 0, 0, 1, 0, 1, 0, 2, 0,
416 0, 1, 0, 2, 1, 0, 0, 0, 2, 0, 0, 0, 1, 2, 2, 0, 0, 2, 0, 1,
417 1, 2, 1, 1, 0, 0, 1, 1, 1, 2, 2, 1, 2, 0, 0, 2, 1, 0, 0, 1,
418 0, 1, 1, 0, 0, 0, 1, 2, 2, 0, 1, 2, 1, 2, 0, 2, 0, 0, 0, 2,
419 1, 2, 0, 0, 0, 2, 0, 0, 0, 2, 2, 1, 0, 2, 0, 1, 2, 0, 2, 1,
420 0, 2, 2, 1, 0, 2, 1, 2, 2, 0, 2, 0, 2, 1, 2, 2, 0, 2, 0, 1,
421 1, 2, 2, 2, 2, 1, 0, 1, 0, 2, 2, 0, 1, 1, 2, 2, 2, 0, 0, 1,
422 0, 2, 0, 1, 0, 2, 1, 2, 1, 0, 1, 1, 2, 0, 0, 2, 1, 1, 2, 0,
423 1, 2, 1, 1, 0, 1, 0, 2, 1, 1, 1, 2, 1, 0, 2, 0, 2, 0, 0, 2,
424 2, 1, 0, 0, 2, 2, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 2, 1, 2, 2,
425 2, 0, 0, 0, 0, 1, 0, 0, 1, 2, 1, 2, 0, 2, 1, 1, 1, 0, 2, 2,
426 1, 2, 2, 1, 0, 1, 0, 2, 2, 2, 1, 2, 1, 0, 0, 1, 0, 1, 1, 1,
427 1, 1, 2, 0, 0, 2, 1, 0, 2, 1, 2, 1, 0, 2, 2, 0, 0, 1, 2, 1,
428 2, 0, 1, 2, 1, 1, 2, 0, 2, 0, 2, 1, 1, 1, 0, 0, 0, 1, 2, 1,
429 2, 2, 1, 2, 1, 1, 2, 1, 2, 0, 2, 2, 1, 0, 0, 1, 2, 0, 1, 1,
430 2, 0, 0, 0, 1, 2, 2, 1, 2, 0, 0, 2, 1, 0, 2, 2, 2, 1, 1, 0,
431 2, 1, 2, 1, 2, 2, 1, 2, 1, 1, 0, 1, 1, 1, 1, 2, 0, 2, 2, 1,
432 0, 1, 1, 2, 1, 2, 0, 2, 1, 0, 1, 0, 1, 0, 1, 2, 0, 1, 1, 0,
433 0, 1, 1, 2, 0, 2, 2, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1,
434 0, 1, 2, 0, 1, 1, 0, 1, 2, 0, 0, 1, 2, 2, 0, 0, 2, 1, 2),
435 {
436 { 9, 439, 2048, TRUE, 9 + (8 << 8) + (5 << 16),
437 countof(indices_ees439ep1), indices_ees439ep1
438 },
439 { 11, 613, 2048, FALSE, 55,
440 countof(indices_ees613ep1), indices_ees613ep1
441 }
442 }
443 },
444 { HASH_SHA256, 32, 64, 32, 33, 40,
445 chunk_from_chars(
446 0x52, 0xC5, 0xDD, 0x1E, 0xEF, 0x76, 0x1B, 0x53,
447 0x08, 0xE4, 0x86, 0x3F, 0x91, 0x12, 0x98, 0x69,
448 0xC5, 0x9D, 0xDE, 0xF6, 0xFC, 0xFA, 0x93, 0xCE,
449 0x32, 0x52, 0x66, 0xF9, 0xC9, 0x97, 0xF6, 0x42,
450 0x00, 0x2C, 0x64, 0xED, 0x1A, 0x6B, 0x14, 0x0A,
451 0x4B, 0x04, 0xCF, 0x6D, 0x2D, 0x82, 0x0A, 0x07,
452 0xA2, 0x3B, 0xDE, 0xCE, 0x19, 0x8A, 0x39, 0x43,
453 0x16, 0x61, 0x29, 0x98, 0x68, 0xEA, 0xE5, 0xCC,
454 0x0A, 0xF8, 0xE9, 0x71, 0x26, 0xF1, 0x07, 0x36,
455 0x2C, 0x07, 0x1E, 0xEB, 0xE4, 0x28, 0xA2, 0xF4,
456 0xA8, 0x12, 0xC0, 0xC8, 0x20, 0x37, 0xF8, 0xF2,
457 0x6C, 0xAF, 0xDC, 0x6F, 0x2E, 0xD0, 0x62, 0x58,
458 0xD2, 0x37, 0x03, 0x6D, 0xFA, 0x6E, 0x1A, 0xAC,
459 0x9F, 0xCA, 0x56, 0xC6, 0xA4, 0x52, 0x41, 0xE8,
460 0x0F, 0x1B, 0x0C, 0xB9, 0xE6, 0xBA, 0xDE, 0xE1,
461 0x03, 0x5E, 0xC2, 0xE5, 0xF8, 0xF4, 0xF3, 0x46,
462 0x3A, 0x12, 0xC0, 0x1F, 0x3A, 0x00, 0xD0, 0x91,
463 0x18, 0xDD, 0x53, 0xE4, 0x22, 0xF5, 0x26, 0xA4,
464 0x54, 0xEE, 0x20, 0xF0, 0x80),
465 chunk_from_chars(
466 0x76, 0x89, 0x8B, 0x1B, 0x60, 0xEC, 0x10, 0x9D,
467 0x8F, 0x13, 0xF2, 0xFE, 0xD9, 0x85, 0xC1, 0xAB,
468 0x7E, 0xEE, 0xB1, 0x31, 0xDD, 0xF7, 0x7F, 0x0C,
469 0x7D, 0xF9, 0x6B, 0x7B, 0x19, 0x80, 0xBD, 0x28),
470 chunk_from_chars(
471 0xF1, 0x19, 0x02, 0x4F, 0xDA, 0x58, 0x05, 0x9A,
472 0x07, 0xDF, 0x61, 0x81, 0x22, 0x0E, 0x15, 0x46,
473 0xCB, 0x35, 0x3C, 0xDC, 0xAD, 0x20, 0xD9, 0x3F,
474 0x0D, 0xD1, 0xAA, 0x64, 0x66, 0x5C, 0xFA, 0x4A,
475 0xFE, 0xD6, 0x8F, 0x55, 0x57, 0x15, 0xB2, 0xA6,
476 0xA0, 0xE6, 0xA8, 0xC6, 0xBD, 0x28, 0xB4, 0xD5,
477 0x6E, 0x5B, 0x4B, 0xB0, 0x97, 0x09, 0xF5, 0xAC,
478 0x57, 0x65, 0x13, 0x97, 0x71, 0x2C, 0x45, 0x13,
479 0x3D, 0xEE, 0xFB, 0xBF, 0xFE, 0xAF, 0xBB, 0x4B,
480 0x0D, 0x5C, 0x45, 0xD4, 0x2F, 0x17, 0x92, 0x07,
481 0x66, 0x11, 0xF5, 0x46, 0xF8, 0x0C, 0x03, 0x92,
482 0xF5, 0xF5, 0xFF, 0xA4, 0xF3, 0x52, 0xF4, 0x08,
483 0x2C, 0x49, 0x32, 0x1A, 0x93, 0x51, 0x98, 0xB6,
484 0x94, 0x83, 0x39, 0xCF, 0x6B, 0x1F, 0x2F, 0xFC,
485 0x2B, 0xFF, 0x10, 0x71, 0x7D, 0x35, 0x6C, 0xEA,
486 0xC5, 0x66, 0xC7, 0x26, 0x7D, 0x9E, 0xAC, 0xDD,
487 0x35, 0xD7, 0x06, 0x3F, 0x40, 0x82, 0xDA, 0xC3,
488 0x2B, 0x3C, 0x91, 0x3A, 0x32, 0xF8, 0xB2, 0xC6,
489 0x44, 0x4D, 0xCD, 0xB6, 0x54, 0x5F, 0x81, 0x95,
490 0x59, 0xA1, 0xE5, 0x4E, 0xA5, 0x0A, 0x4A, 0x42),
491 chunk_from_chars(
492 1, 2, 2, 2, 2, 1, 2, 2, 0, 0, 2, 0, 0, 0, 0, 1, 2, 2, 2, 0,
493 2, 0, 0, 2, 2, 1, 2, 0, 0, 1, 2, 1, 0, 0, 0, 1, 0, 2, 2, 1,
494 1, 2, 0, 0, 0, 1, 2, 0, 2, 2, 1, 2, 1, 0, 1, 0, 1, 2, 1, 1,
495 1, 2, 0, 1, 0, 2, 1, 1, 0, 0, 0, 1, 2, 0, 0, 1, 2, 1, 2, 0,
496 2, 1, 1, 1, 2, 2, 2, 2, 1, 0, 0, 2, 0, 2, 0, 1, 1, 0, 2, 2,
497 2, 0, 1, 0, 2, 2, 1, 0, 1, 0, 1, 0, 0, 2, 2, 0, 0, 1, 2, 0,
498 1, 1, 1, 0, 0, 2, 0, 2, 1, 2, 2, 2, 0, 0, 2, 1, 0, 2, 0, 1,
499 0, 1, 2, 0, 1, 2, 0, 1, 0, 1, 2, 0, 2, 2, 0, 1, 2, 2, 1, 2,
500 2, 2, 0, 2, 1, 1, 1, 0, 0, 1, 0, 2, 0, 0, 1, 0, 1, 2, 0, 0,
501 1, 2, 1, 0, 2, 1, 1, 0, 0, 2, 1, 2, 2, 2, 1, 2, 1, 1, 2, 2,
502 0, 2, 0, 0, 2, 0, 0, 1, 1, 2, 0, 0, 0, 1, 2, 1, 1, 1, 1, 0,
503 0, 0, 2, 0, 2, 0, 2, 2, 1, 2, 2, 0, 0, 1, 1, 1, 0, 1, 0, 1,
504 0, 1, 2, 2, 0, 2, 1, 1, 0, 2, 1, 2, 1, 2, 1, 0, 0, 1, 0, 0,
505 1, 0, 1, 0, 2, 0, 2, 0, 0, 1, 2, 0, 2, 0, 1, 1, 0, 2, 0, 0,
506 1, 2, 1, 2, 1, 2, 1, 0, 1, 1, 2, 2, 1, 1, 0, 0, 2, 1, 2, 0,
507 1, 0, 2, 0, 0, 1, 2, 0, 2, 0, 1, 1, 2, 2, 2, 2, 0, 0, 1, 2,
508 1, 1, 1, 0, 2, 1, 2, 2, 0, 2, 0, 1, 2, 2, 0, 1, 1, 1, 0, 0,
509 2, 0, 1, 0, 1, 0, 2, 1, 2, 0, 2, 1, 2, 1, 2, 2, 0, 2, 1, 0,
510 2, 1, 2, 0, 0, 2, 0, 1, 2, 1, 1, 2, 0, 0, 0, 0, 1, 2, 0, 1,
511 2, 2, 1, 0, 0, 1, 2, 1, 2, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0,
512 2, 0, 1, 2, 1, 2, 0, 0, 0, 2, 1, 0, 0, 0, 1, 2, 2, 0, 0, 0,
513 2, 2, 1, 1, 0, 1, 0, 2, 2, 0, 2, 1, 2, 1, 0, 2, 2, 2, 0, 0,
514 0, 1, 1, 2, 1, 0, 0, 0, 0, 1, 2, 2, 1, 2, 1, 2, 0, 2, 0, 2,
515 1, 1, 1, 2, 1, 2, 1, 2, 1, 1, 0, 1, 0, 2, 0, 0, 0, 2, 1, 2,
516 2, 2, 2, 0, 1, 1, 1, 0, 1, 0, 2, 0, 2, 1, 0, 1, 2, 1, 1, 0,
517 1, 2, 1, 0, 0, 2, 1, 0, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0,
518 0, 0, 0, 1, 1, 0, 0, 2, 2, 2, 2, 2, 0, 1, 2, 0, 1, 2, 0, 1,
519 1, 0, 1, 1, 2, 2, 0, 1, 1, 0, 2, 2, 1, 1, 1, 2, 1, 2, 2, 1,
520 1, 0, 1, 0, 2, 2, 1, 0, 2, 2, 2, 2, 2, 1, 0, 2, 2, 2, 1, 2,
521 0, 2, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 1),
522 {
523 { 13, 743, 2048, TRUE, 11 + (11 << 8) + (15 << 16),
524 countof(indices_ees743ep1), indices_ees743ep1
525 },
526 { 12, 1171, 2048, FALSE, 106,
527 countof(indices_ees1171ep1), indices_ees1171ep1
528 }
529 }
530 }
531 };
532
533 START_TEST(test_ntru_mgf1)
534 {
535 ntru_mgf1_t *mgf1;
536 chunk_t mask, mask1, mask2, mask3;
537
538 mask1 = mgf1_tests[_i].mask;
539 mask2 = chunk_skip(mask1, mgf1_tests[_i].ml1);
540 mask3 = chunk_skip(mask2, mgf1_tests[_i].ml2);
541 mask1.len = mgf1_tests[_i].ml1;
542 mask2.len = mgf1_tests[_i].ml2;
543 mask3.len = mgf1_tests[_i].ml3;
544
545 mgf1 = ntru_mgf1_create(HASH_UNKNOWN, mgf1_tests[_i].seed, TRUE);
546 ck_assert(mgf1 == NULL);
547
548 mgf1 = ntru_mgf1_create(mgf1_tests[_i].alg, chunk_empty, TRUE);
549 ck_assert(mgf1 == NULL);
550
551 /* return mask in allocated chunk */
552 mgf1 = ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE);
553 ck_assert(mgf1);
554
555 /* check hash size */
556 ck_assert(mgf1->get_hash_size(mgf1) == mgf1_tests[_i].hash_size);
557
558 /* get zero number of octets */
559 ck_assert(mgf1->allocate_mask(mgf1, 0, &mask));
560 ck_assert(mask.len == 0 && mask.ptr == NULL);
561
562 /* get non-zero number of octets */
563 ck_assert(mgf1->allocate_mask(mgf1, mgf1_tests[_i].mask.len, &mask));
564 ck_assert(chunk_equals(mask, mgf1_tests[_i].mask));
565 mgf1->destroy(mgf1);
566
567 /* copy mask to pre-allocated buffer */
568 mgf1 = ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE);
569 ck_assert(mgf1);
570 ck_assert(mgf1->get_mask(mgf1, mgf1_tests[_i].mask.len, mask.ptr));
571 ck_assert(chunk_equals(mask, mgf1_tests[_i].mask));
572 mgf1->destroy(mgf1);
573
574 /* get mask in batches without hashing the seed */
575 mgf1 = ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].hashed_seed, FALSE);
576 ck_assert(mgf1);
577
578 /* first batch */
579 ck_assert(mgf1->get_mask(mgf1, mask1.len, mask.ptr));
580 mask.len = mask1.len;
581 ck_assert(chunk_equals(mask, mask1));
582
583 /* second batch */
584 ck_assert(mgf1->get_mask(mgf1, mask2.len, mask.ptr));
585 mask.len = mask2.len;
586 ck_assert(chunk_equals(mask, mask2));
587
588 /* third batch */
589 ck_assert(mgf1->get_mask(mgf1, mask3.len, mask.ptr));
590 mask.len = mask3.len;
591 ck_assert(chunk_equals(mask, mask3));
592
593 mgf1->destroy(mgf1);
594 chunk_free(&mask);
595 }
596 END_TEST
597
598 START_TEST(test_ntru_trits)
599 {
600 ntru_trits_t *mask;
601 chunk_t trits;
602
603 mask = ntru_trits_create(mgf1_tests[_i].trits.len, HASH_UNKNOWN,
604 mgf1_tests[_i].seed);
605 ck_assert(mask == NULL);
606
607 mask = ntru_trits_create(mgf1_tests[_i].trits.len, mgf1_tests[_i].alg,
608 chunk_empty);
609 ck_assert(mask == NULL);
610
611 mask = ntru_trits_create(mgf1_tests[_i].trits.len, mgf1_tests[_i].alg,
612 mgf1_tests[_i].seed);
613 ck_assert(mask);
614
615 trits = chunk_create(mask->get_trits(mask), mask->get_size(mask));
616 ck_assert(chunk_equals(trits, mgf1_tests[_i].trits));
617 mask->destroy(mask);
618
619 /* generate a multiple of 5 trits */
620 mask = ntru_trits_create(10, mgf1_tests[_i].alg, mgf1_tests[_i].seed);
621 ck_assert(mask);
622
623 trits = chunk_create(mask->get_trits(mask), mask->get_size(mask));
624 ck_assert(chunk_equals(trits, chunk_create(mgf1_tests[_i].trits.ptr, 10)));
625 mask->destroy(mask);
626 }
627 END_TEST
628
629 START_TEST(test_ntru_poly)
630 {
631 ntru_poly_t *poly;
632 uint16_t *indices;
633 chunk_t seed;
634 poly_test_t *p;
635 int j, n;
636
637 seed = mgf1_tests[_i].seed;
638 seed.len = mgf1_tests[_i].seed_len;
639
640 p = &mgf1_tests[_i].poly_test[0];
641 poly = ntru_poly_create_from_seed(HASH_UNKNOWN, seed, p->c_bits, p->N, p->q,
642 p->indices_len, p->indices_len,
643 p->is_product_form);
644 ck_assert(poly == NULL);
645
646 for (n = 0; n < 2; n++)
647 {
648 p = &mgf1_tests[_i].poly_test[n];
649 poly = ntru_poly_create_from_seed(mgf1_tests[_i].alg, seed, p->c_bits,
650 p->N, p->q, p->indices_len,
651 p->indices_len, p->is_product_form);
652 ck_assert(poly != NULL && poly->get_size(poly) == p->indices_size);
653
654 indices = poly->get_indices(poly);
655 for (j = 0; j < p->indices_size; j++)
656 {
657 ck_assert(indices[j] == p->indices[j]);
658 }
659 poly->destroy(poly);
660 }
661 }
662 END_TEST
663
664 typedef struct {
665 uint16_t N;
666 uint16_t q;
667 bool is_product_form;
668 uint32_t indices_len_p;
669 uint32_t indices_len_m;
670 uint16_t *indices;
671 uint16_t *a;
672 uint16_t *c;
673 } ring_mult_test_t;
674
675 uint16_t t1_indices[] = { 1, 6, 5, 3 };
676
677 uint16_t t1_a[] = { 1, 0, 0, 0, 0, 0, 0 };
678 uint16_t t1_c[] = { 0, 1, 0, 7, 0, 7, 1 };
679
680 uint16_t t2_a[] = { 5, 0, 0, 0, 0, 0, 0 };
681 uint16_t t2_c[] = { 0, 5, 0, 3, 0, 3, 5 };
682
683 uint16_t t3_a[] = { 4, 0, 0, 0, 0, 0, 0 };
684 uint16_t t3_c[] = { 0, 4, 0, 4, 0, 4, 4 };
685
686 uint16_t t4_a[] = { 0, 6, 0, 0, 0, 0, 0 };
687 uint16_t t4_c[] = { 6, 0, 6, 0, 2, 0, 2 };
688
689 uint16_t t5_a[] = { 4, 6, 0, 0, 0, 0, 0 };
690 uint16_t t5_c[] = { 6, 4, 6, 4, 2, 4, 6 };
691
692 uint16_t t6_a[] = { 0, 0, 3, 0, 0, 0, 0 };
693 uint16_t t6_c[] = { 5, 3, 0, 3, 0, 5, 0 };
694
695 uint16_t t7_a[] = { 4, 6, 3, 0, 0, 0, 0 };
696 uint16_t t7_c[] = { 3, 7, 6, 7, 2, 1, 6 };
697
698 uint16_t t8_a[] = { 0, 0, 0, 7, 0, 0, 0 };
699 uint16_t t8_c[] = { 0, 1, 7, 0, 7, 0, 1 };
700
701 uint16_t t9_a[] = { 4, 6, 3, 7, 0, 0, 0 };
702 uint16_t t9_c[] = { 3, 0, 5, 7, 1, 1, 7 };
703
704 uint16_t t10_a[] = { 0, 0, 0, 0, 0, 1, 0 };
705 uint16_t t10_c[] = { 0, 7, 0, 7, 1, 0, 1 };
706
707 uint16_t t11_a[] = { 4, 6, 3, 7, 0, 1, 0 };
708 uint16_t t11_c[] = { 3, 7, 5, 6, 2, 1, 0 };
709
710 uint16_t t2_indices[] = { 1, 6, 5, 2, 3 };
711
712 uint16_t t12_c[] = { 0, 1, 7, 7, 0, 1, 1 };
713 uint16_t t13_c[] = { 0, 1, 7, 7, 0, 7, 1 };
714 uint16_t t14_c[] = { 0, 1, 0, 31, 0, 31, 1 };
715 uint16_t t15_c[] = { 0, 5, 0, 2043, 0, 2043, 5 };
716 uint16_t t16_c[] = { 0, 5, 0, 32763, 0, 32763, 5 };
717
718 uint16_t t3_indices[] = { 7, 2, 3, 5, 0, 2, 3, 10, 7, 0, 8, 2 };
719
720 uint16_t t17_a[] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
721 uint16_t t17_c[] = { 7, 1, 0, 1, 1, 7, 0, 7, 7, 7, 2 };
722
723 ring_mult_test_t ring_mult_tests[] = {
724 { 7, 8, FALSE, 2, 2, t1_indices, t1_a, t1_c },
725 { 7, 8, FALSE, 2, 2, t1_indices, t2_a, t2_c },
726 { 7, 8, FALSE, 2, 2, t1_indices, t3_a, t3_c },
727 { 7, 8, FALSE, 2, 2, t1_indices, t4_a, t4_c },
728 { 7, 8, FALSE, 2, 2, t1_indices, t5_a, t5_c },
729 { 7, 8, FALSE, 2, 2, t1_indices, t6_a, t6_c },
730 { 7, 8, FALSE, 2, 2, t1_indices, t7_a, t7_c },
731 { 7, 8, FALSE, 2, 2, t1_indices, t8_a, t8_c },
732 { 7, 8, FALSE, 2, 2, t1_indices, t9_a, t9_c },
733 { 7, 8, FALSE, 2, 2, t1_indices, t10_a, t10_c },
734 { 7, 8, FALSE, 2, 2, t1_indices, t11_a, t11_c },
735 { 7, 8, FALSE, 3, 2, t2_indices, t1_a, t12_c },
736 { 7, 8, FALSE, 2, 3, t2_indices, t1_a, t13_c },
737 { 7, 32, FALSE, 2, 2, t1_indices, t1_a, t14_c },
738 { 7, 2048, FALSE, 2, 2, t1_indices, t2_a, t15_c },
739 { 7, 32768, FALSE, 2, 2, t1_indices, t2_a, t16_c },
740 { 11, 8, TRUE, 197121, 197121, t3_indices, t17_a, t17_c },
741 };
742
743 START_TEST(test_ntru_ring_mult)
744 {
745 ntru_poly_t *poly;
746 ring_mult_test_t *t;
747 uint16_t *c;
748 int i;
749
750 t = &ring_mult_tests[_i];
751 poly = ntru_poly_create_from_data(t->indices, t->N, t->q, t->indices_len_p,
752 t->indices_len_m, t->is_product_form);
753 ck_assert(poly != NULL);
754
755 c = malloc(t->N * sizeof(uint16_t));
756 poly->ring_mult(poly, t->a, c);
757
758 for (i = 0; i < t->N; i++)
759 {
760 ck_assert(c[i] == t->c[i]);
761 }
762
763 free(c);
764 poly->destroy(poly);
765 }
766 END_TEST
767
768 int array_tests[] = { 0, 11, 12, 16 };
769
770 START_TEST(test_ntru_array)
771 {
772 ntru_poly_t *poly;
773 ring_mult_test_t *t;
774 uint16_t *c;
775 int i;
776
777 t = &ring_mult_tests[array_tests[_i]];
778
779 poly = ntru_poly_create_from_data(t->indices, t->N, t->q, t->indices_len_p,
780 t->indices_len_m, t->is_product_form);
781 ck_assert(poly != NULL);
782
783 c = malloc(t->N * sizeof(uint16_t));
784 poly->get_array(poly, c);
785
786 for (i = 0; i < t->N; i++)
787 {
788 ck_assert(c[i] == t->c[i]);
789 }
790
791 free(c);
792 poly->destroy(poly);
793 }
794 END_TEST
795
796 START_TEST(test_ntru_ke)
797 {
798 chunk_t pub_key, cipher_text, i_shared_secret, r_shared_secret;
799 diffie_hellman_t *i_ntru, *r_ntru;
800 char buf[10];
801 int n, len;
802 status_t status;
803
804 len = snprintf(buf, sizeof(buf), "%N", diffie_hellman_group_names,
805 params[_i].group);
806 ck_assert(len == 8);
807 ck_assert(streq(buf, params[_i].group_name));
808
809 for (n = 0; n < countof(parameter_sets); n++)
810 {
811 lib->settings->set_str(lib->settings,
812 "libstrongswan.plugins.ntru.parameter_set",
813 parameter_sets[n]);
814
815 i_ntru = lib->crypto->create_dh(lib->crypto, params[_i].group);
816 ck_assert(i_ntru != NULL);
817 ck_assert(i_ntru->get_dh_group(i_ntru) == params[_i].group);
818
819 i_ntru->get_my_public_value(i_ntru, &pub_key);
820 ck_assert(pub_key.len > 0);
821
822 r_ntru = lib->crypto->create_dh(lib->crypto, params[_i].group);
823 ck_assert(r_ntru != NULL);
824
825 r_ntru->set_other_public_value(r_ntru, pub_key);
826 r_ntru->get_my_public_value(r_ntru, &cipher_text);
827 ck_assert(cipher_text.len > 0);
828
829 status = r_ntru->get_shared_secret(r_ntru, &r_shared_secret);
830 ck_assert(status == SUCCESS);
831 ck_assert(r_shared_secret.len > 0);
832
833 i_ntru->set_other_public_value(i_ntru, cipher_text);
834 status = i_ntru->get_shared_secret(i_ntru, &i_shared_secret);
835
836 if (status == SUCCESS)
837 {
838 ck_assert(chunk_equals(i_shared_secret, r_shared_secret));
839 }
840 else
841 {
842 ck_assert(i_shared_secret.len == 0);
843 }
844
845 chunk_clear(&i_shared_secret);
846 chunk_clear(&r_shared_secret);
847 chunk_free(&pub_key);
848 chunk_free(&cipher_text);
849 i_ntru->destroy(i_ntru);
850 r_ntru->destroy(r_ntru);
851 }
852 }
853 END_TEST
854
855 START_TEST(test_ntru_retransmission)
856 {
857 diffie_hellman_t *i_ntru;
858 chunk_t pub_key1, pub_key2;
859
860 i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_256_BIT);
861 i_ntru->get_my_public_value(i_ntru, &pub_key1);
862 i_ntru->get_my_public_value(i_ntru, &pub_key2);
863 ck_assert(chunk_equals(pub_key1, pub_key2));
864
865 chunk_free(&pub_key1);
866 chunk_free(&pub_key2);
867 i_ntru->destroy(i_ntru);
868 }
869 END_TEST
870
871 chunk_t oid_tests[] = {
872 { NULL, 0 },
873 chunk_from_chars(0x00),
874 chunk_from_chars(0x01),
875 chunk_from_chars(0x02),
876 chunk_from_chars(0x02, 0x03, 0x00, 0x03, 0x10),
877 chunk_from_chars(0x01, 0x04, 0x00, 0x03, 0x10),
878 chunk_from_chars(0x01, 0x03, 0x00, 0x03, 0x10),
879 chunk_from_chars(0x01, 0x03, 0xff, 0x03, 0x10),
880 };
881
882 START_TEST(test_ntru_pubkey_oid)
883 {
884 diffie_hellman_t *r_ntru;
885 chunk_t cipher_text;
886
887 r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
888 r_ntru->set_other_public_value(r_ntru, oid_tests[_i]);
889 r_ntru->get_my_public_value(r_ntru, &cipher_text);
890 ck_assert(cipher_text.len == 0);
891 r_ntru->destroy(r_ntru);
892 }
893 END_TEST
894
895 START_TEST(test_ntru_wrong_set)
896 {
897 diffie_hellman_t *i_ntru, *r_ntru;
898 chunk_t pub_key, cipher_text;
899
900 lib->settings->set_str(lib->settings,
901 "libstrongswan.plugins.ntru.parameter_set",
902 "x9_98_bandwidth");
903 i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT);
904 i_ntru->get_my_public_value(i_ntru, &pub_key);
905
906 lib->settings->set_str(lib->settings,
907 "libstrongswan.plugins.ntru.parameter_set",
908 "optimum");
909 r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT);
910 r_ntru->set_other_public_value(r_ntru, pub_key);
911 r_ntru->get_my_public_value(r_ntru, &cipher_text);
912 ck_assert(cipher_text.len == 0);
913
914 chunk_free(&pub_key);
915 chunk_free(&cipher_text);
916 i_ntru->destroy(i_ntru);
917 r_ntru->destroy(r_ntru);
918 }
919 END_TEST
920
921 START_TEST(test_ntru_ciphertext)
922 {
923 char buf_00[604], buf_ff[604];
924
925 chunk_t test[] = {
926 chunk_empty,
927 chunk_from_chars(0x00),
928 chunk_create(buf_00, sizeof(buf_00)),
929 chunk_create(buf_ff, sizeof(buf_ff)),
930 };
931
932 diffie_hellman_t *i_ntru;
933 chunk_t pub_key, shared_secret;
934 int i;
935
936 memset(buf_00, 0x00, sizeof(buf_00));
937 memset(buf_ff, 0xff, sizeof(buf_ff));
938
939 for (i = 0; i < countof(test); i++)
940 {
941 i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
942 i_ntru->get_my_public_value(i_ntru, &pub_key);
943 i_ntru->set_other_public_value(i_ntru, test[i]);
944 ck_assert(i_ntru->get_shared_secret(i_ntru, &shared_secret) != SUCCESS);
945 ck_assert(shared_secret.len == 0);
946
947 chunk_free(&pub_key);
948 i_ntru->destroy(i_ntru);
949 }
950 }
951 END_TEST
952
953 START_TEST(test_ntru_wrong_ciphertext)
954 {
955 diffie_hellman_t *i_ntru, *r_ntru, *m_ntru;
956 chunk_t pub_key_i, pub_key_m, cipher_text, shared_secret;
957
958 i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
959 r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
960 m_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
961
962 i_ntru->get_my_public_value(i_ntru, &pub_key_i);
963 m_ntru->get_my_public_value(m_ntru, &pub_key_m);
964 r_ntru->set_other_public_value(r_ntru, pub_key_m);
965 r_ntru->get_my_public_value(r_ntru, &cipher_text);
966 i_ntru->set_other_public_value(i_ntru, cipher_text);
967 ck_assert(i_ntru->get_shared_secret(i_ntru, &shared_secret) != SUCCESS);
968 ck_assert(shared_secret.len == 0);
969
970 chunk_free(&pub_key_i);
971 chunk_free(&pub_key_m);
972 chunk_free(&cipher_text);
973 i_ntru->destroy(i_ntru);
974 m_ntru->destroy(m_ntru);
975 r_ntru->destroy(r_ntru);
976 }
977 END_TEST
978
979 Suite *ntru_suite_create()
980 {
981 Suite *s;
982 TCase *tc;
983
984 s = suite_create("ntru");
985
986 tc = tcase_create("drbg_strength");
987 tcase_add_loop_test(tc, test_ntru_drbg_strength, 0, countof(strengths));
988 suite_add_tcase(s, tc);
989
990 tc = tcase_create("drbg");
991 tcase_add_loop_test(tc, test_ntru_drbg, 0, countof(drbg_tests));
992 suite_add_tcase(s, tc);
993
994 tc = tcase_create("drgb_reseed");
995 tcase_add_test(tc, test_ntru_drbg_reseed);
996 suite_add_tcase(s, tc);
997
998 tc = tcase_create("mgf1");
999 tcase_add_loop_test(tc, test_ntru_mgf1, 0, countof(mgf1_tests));
1000 suite_add_tcase(s, tc);
1001
1002 tc = tcase_create("trits");
1003 tcase_add_loop_test(tc, test_ntru_trits, 0, countof(mgf1_tests));
1004 suite_add_tcase(s, tc);
1005
1006 tc = tcase_create("poly");
1007 tcase_add_loop_test(tc, test_ntru_poly, 0, countof(mgf1_tests));
1008 suite_add_tcase(s, tc);
1009
1010 tc = tcase_create("ring_mult");
1011 tcase_add_loop_test(tc, test_ntru_ring_mult, 0, countof(ring_mult_tests));
1012 suite_add_tcase(s, tc);
1013
1014 tc = tcase_create("array");
1015 tcase_add_loop_test(tc, test_ntru_array, 0, countof(array_tests));
1016 suite_add_tcase(s, tc);
1017
1018 tc = tcase_create("ke");
1019 tcase_add_loop_test(tc, test_ntru_ke, 0, countof(params));
1020 suite_add_tcase(s, tc);
1021
1022 tc = tcase_create("retransmission");
1023 tcase_add_test(tc, test_ntru_retransmission);
1024 suite_add_tcase(s, tc);
1025
1026 tc = tcase_create("pubkey_oid");
1027 tcase_add_loop_test(tc, test_ntru_pubkey_oid, 0, countof(oid_tests));
1028 suite_add_tcase(s, tc);
1029
1030 tc = tcase_create("wrong_set");
1031 tcase_add_test(tc, test_ntru_wrong_set);
1032 suite_add_tcase(s, tc);
1033
1034 tc = tcase_create("ciphertext");
1035 tcase_add_test(tc, test_ntru_ciphertext);
1036 suite_add_tcase(s, tc);
1037
1038 tc = tcase_create("wrong_ciphertext");
1039 tcase_add_test(tc, test_ntru_wrong_ciphertext);
1040 suite_add_tcase(s, tc);
1041 return s;
1042 }