Defined ntru_poly_create_from_seed() and ntru_poly_create_from_data() constructors...
[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(sizeof(uint16_t) * t->N);
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 START_TEST(test_ntru_ke)
769 {
770 chunk_t pub_key, cipher_text, i_shared_secret, r_shared_secret;
771 diffie_hellman_t *i_ntru, *r_ntru;
772 char buf[10];
773 int n, len;
774 status_t status;
775
776 len = snprintf(buf, sizeof(buf), "%N", diffie_hellman_group_names,
777 params[_i].group);
778 ck_assert(len == 8);
779 ck_assert(streq(buf, params[_i].group_name));
780
781 for (n = 0; n < countof(parameter_sets); n++)
782 {
783 lib->settings->set_str(lib->settings,
784 "libstrongswan.plugins.ntru.parameter_set",
785 parameter_sets[n]);
786
787 i_ntru = lib->crypto->create_dh(lib->crypto, params[_i].group);
788 ck_assert(i_ntru != NULL);
789 ck_assert(i_ntru->get_dh_group(i_ntru) == params[_i].group);
790
791 i_ntru->get_my_public_value(i_ntru, &pub_key);
792 ck_assert(pub_key.len > 0);
793
794 r_ntru = lib->crypto->create_dh(lib->crypto, params[_i].group);
795 ck_assert(r_ntru != NULL);
796
797 r_ntru->set_other_public_value(r_ntru, pub_key);
798 r_ntru->get_my_public_value(r_ntru, &cipher_text);
799 ck_assert(cipher_text.len > 0);
800
801 status = r_ntru->get_shared_secret(r_ntru, &r_shared_secret);
802 ck_assert(status == SUCCESS);
803 ck_assert(r_shared_secret.len > 0);
804
805 i_ntru->set_other_public_value(i_ntru, cipher_text);
806 status = i_ntru->get_shared_secret(i_ntru, &i_shared_secret);
807
808 if (status == SUCCESS)
809 {
810 ck_assert(chunk_equals(i_shared_secret, r_shared_secret));
811 }
812 else
813 {
814 ck_assert(i_shared_secret.len == 0);
815 }
816
817 chunk_clear(&i_shared_secret);
818 chunk_clear(&r_shared_secret);
819 chunk_free(&pub_key);
820 chunk_free(&cipher_text);
821 i_ntru->destroy(i_ntru);
822 r_ntru->destroy(r_ntru);
823 }
824 }
825 END_TEST
826
827 START_TEST(test_ntru_retransmission)
828 {
829 diffie_hellman_t *i_ntru;
830 chunk_t pub_key1, pub_key2;
831
832 i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_256_BIT);
833 i_ntru->get_my_public_value(i_ntru, &pub_key1);
834 i_ntru->get_my_public_value(i_ntru, &pub_key2);
835 ck_assert(chunk_equals(pub_key1, pub_key2));
836
837 chunk_free(&pub_key1);
838 chunk_free(&pub_key2);
839 i_ntru->destroy(i_ntru);
840 }
841 END_TEST
842
843 chunk_t oid_tests[] = {
844 { NULL, 0 },
845 chunk_from_chars(0x00),
846 chunk_from_chars(0x01),
847 chunk_from_chars(0x02),
848 chunk_from_chars(0x02, 0x03, 0x00, 0x03, 0x10),
849 chunk_from_chars(0x01, 0x04, 0x00, 0x03, 0x10),
850 chunk_from_chars(0x01, 0x03, 0x00, 0x03, 0x10),
851 chunk_from_chars(0x01, 0x03, 0xff, 0x03, 0x10),
852 };
853
854 START_TEST(test_ntru_pubkey_oid)
855 {
856 diffie_hellman_t *r_ntru;
857 chunk_t cipher_text;
858
859 r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
860 r_ntru->set_other_public_value(r_ntru, oid_tests[_i]);
861 r_ntru->get_my_public_value(r_ntru, &cipher_text);
862 ck_assert(cipher_text.len == 0);
863 r_ntru->destroy(r_ntru);
864 }
865 END_TEST
866
867 START_TEST(test_ntru_wrong_set)
868 {
869 diffie_hellman_t *i_ntru, *r_ntru;
870 chunk_t pub_key, cipher_text;
871
872 lib->settings->set_str(lib->settings,
873 "libstrongswan.plugins.ntru.parameter_set",
874 "x9_98_bandwidth");
875 i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT);
876 i_ntru->get_my_public_value(i_ntru, &pub_key);
877
878 lib->settings->set_str(lib->settings,
879 "libstrongswan.plugins.ntru.parameter_set",
880 "optimum");
881 r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT);
882 r_ntru->set_other_public_value(r_ntru, pub_key);
883 r_ntru->get_my_public_value(r_ntru, &cipher_text);
884 ck_assert(cipher_text.len == 0);
885
886 chunk_free(&pub_key);
887 chunk_free(&cipher_text);
888 i_ntru->destroy(i_ntru);
889 r_ntru->destroy(r_ntru);
890 }
891 END_TEST
892
893 START_TEST(test_ntru_ciphertext)
894 {
895 char buf_00[604], buf_ff[604];
896
897 chunk_t test[] = {
898 chunk_empty,
899 chunk_from_chars(0x00),
900 chunk_create(buf_00, sizeof(buf_00)),
901 chunk_create(buf_ff, sizeof(buf_ff)),
902 };
903
904 diffie_hellman_t *i_ntru;
905 chunk_t pub_key, shared_secret;
906 int i;
907
908 memset(buf_00, 0x00, sizeof(buf_00));
909 memset(buf_ff, 0xff, sizeof(buf_ff));
910
911 for (i = 0; i < countof(test); i++)
912 {
913 i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
914 i_ntru->get_my_public_value(i_ntru, &pub_key);
915 i_ntru->set_other_public_value(i_ntru, test[i]);
916 ck_assert(i_ntru->get_shared_secret(i_ntru, &shared_secret) != SUCCESS);
917 ck_assert(shared_secret.len == 0);
918
919 chunk_free(&pub_key);
920 i_ntru->destroy(i_ntru);
921 }
922 }
923 END_TEST
924
925 START_TEST(test_ntru_wrong_ciphertext)
926 {
927 diffie_hellman_t *i_ntru, *r_ntru, *m_ntru;
928 chunk_t pub_key_i, pub_key_m, cipher_text, shared_secret;
929
930 i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
931 r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
932 m_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
933
934 i_ntru->get_my_public_value(i_ntru, &pub_key_i);
935 m_ntru->get_my_public_value(m_ntru, &pub_key_m);
936 r_ntru->set_other_public_value(r_ntru, pub_key_m);
937 r_ntru->get_my_public_value(r_ntru, &cipher_text);
938 i_ntru->set_other_public_value(i_ntru, cipher_text);
939 ck_assert(i_ntru->get_shared_secret(i_ntru, &shared_secret) != SUCCESS);
940 ck_assert(shared_secret.len == 0);
941
942 chunk_free(&pub_key_i);
943 chunk_free(&pub_key_m);
944 chunk_free(&cipher_text);
945 i_ntru->destroy(i_ntru);
946 m_ntru->destroy(m_ntru);
947 r_ntru->destroy(r_ntru);
948 }
949 END_TEST
950
951 Suite *ntru_suite_create()
952 {
953 Suite *s;
954 TCase *tc;
955
956 s = suite_create("ntru");
957
958 tc = tcase_create("drbg_strength");
959 tcase_add_loop_test(tc, test_ntru_drbg_strength, 0, countof(strengths));
960 suite_add_tcase(s, tc);
961
962 tc = tcase_create("drbg");
963 tcase_add_loop_test(tc, test_ntru_drbg, 0, countof(drbg_tests));
964 suite_add_tcase(s, tc);
965
966 tc = tcase_create("drgb_reseed");
967 tcase_add_test(tc, test_ntru_drbg_reseed);
968 suite_add_tcase(s, tc);
969
970 tc = tcase_create("mgf1");
971 tcase_add_loop_test(tc, test_ntru_mgf1, 0, countof(mgf1_tests));
972 suite_add_tcase(s, tc);
973
974 tc = tcase_create("trits");
975 tcase_add_loop_test(tc, test_ntru_trits, 0, countof(mgf1_tests));
976 suite_add_tcase(s, tc);
977
978 tc = tcase_create("poly");
979 tcase_add_loop_test(tc, test_ntru_poly, 0, countof(mgf1_tests));
980 suite_add_tcase(s, tc);
981
982 tc = tcase_create("ring_mult");
983 tcase_add_loop_test(tc, test_ntru_ring_mult, 0, countof(ring_mult_tests));
984 suite_add_tcase(s, tc);
985
986 tc = tcase_create("ke");
987 tcase_add_loop_test(tc, test_ntru_ke, 0, countof(params));
988 suite_add_tcase(s, tc);
989
990 tc = tcase_create("retransmission");
991 tcase_add_test(tc, test_ntru_retransmission);
992 suite_add_tcase(s, tc);
993
994 tc = tcase_create("pubkey_oid");
995 tcase_add_loop_test(tc, test_ntru_pubkey_oid, 0, countof(oid_tests));
996 suite_add_tcase(s, tc);
997
998 tc = tcase_create("wrong_set");
999 tcase_add_test(tc, test_ntru_wrong_set);
1000 suite_add_tcase(s, tc);
1001
1002 tc = tcase_create("ciphertext");
1003 tcase_add_test(tc, test_ntru_ciphertext);
1004 suite_add_tcase(s, tc);
1005
1006 tc = tcase_create("wrong_ciphertext");
1007 tcase_add_test(tc, test_ntru_wrong_ciphertext);
1008 suite_add_tcase(s, tc);
1009 return s;
1010 }