xref: /netbsd-src/crypto/external/bsd/openssl/dist/test/igetest.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*
2  * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <openssl/crypto.h>
11 #include <openssl/aes.h>
12 #include <openssl/rand.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <assert.h>
16 #include "e_os.h"
17 
18 #define TEST_SIZE       128
19 #define BIG_TEST_SIZE 10240
20 
21 static void hexdump(FILE *f, const char *title, const unsigned char *s, int l)
22 {
23     int n = 0;
24 
25     fprintf(f, "%s", title);
26     for (; n < l; ++n) {
27         if ((n % 16) == 0)
28             fprintf(f, "\n%04x", n);
29         fprintf(f, " %02x", s[n]);
30     }
31     fprintf(f, "\n");
32 }
33 
34 #define MAX_VECTOR_SIZE 64
35 
36 struct ige_test {
37     const unsigned char key[16];
38     const unsigned char iv[32];
39     const unsigned char in[MAX_VECTOR_SIZE];
40     const unsigned char out[MAX_VECTOR_SIZE];
41     const size_t length;
42     const int encrypt;
43 };
44 
45 static struct ige_test const ige_test_vectors[] = {
46     {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
47       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key */
48      {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
49       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
50       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
51       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* iv */
52      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* in */
56      {0x1a, 0x85, 0x19, 0xa6, 0x55, 0x7b, 0xe6, 0x52,
57       0xe9, 0xda, 0x8e, 0x43, 0xda, 0x4e, 0xf4, 0x45,
58       0x3c, 0xf4, 0x56, 0xb4, 0xca, 0x48, 0x8a, 0xa3,
59       0x83, 0xc7, 0x9c, 0x98, 0xb3, 0x47, 0x97, 0xcb}, /* out */
60      32, AES_ENCRYPT},          /* test vector 0 */
61 
62     {{0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
63       0x61, 0x6e, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65}, /* key */
64      {0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
65       0x6e, 0x20, 0x6f, 0x66, 0x20, 0x49, 0x47, 0x45,
66       0x20, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f,
67       0x72, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53}, /* iv */
68      {0x4c, 0x2e, 0x20, 0x4c, 0x65, 0x74, 0x27, 0x73,
69       0x20, 0x68, 0x6f, 0x70, 0x65, 0x20, 0x42, 0x65,
70       0x6e, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x74,
71       0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x21, 0x0a}, /* in */
72      {0x99, 0x70, 0x64, 0x87, 0xa1, 0xcd, 0xe6, 0x13,
73       0xbc, 0x6d, 0xe0, 0xb6, 0xf2, 0x4b, 0x1c, 0x7a,
74       0xa4, 0x48, 0xc8, 0xb9, 0xc3, 0x40, 0x3e, 0x34,
75       0x67, 0xa8, 0xca, 0xd8, 0x93, 0x40, 0xf5, 0x3b}, /* out */
76      32, AES_DECRYPT},          /* test vector 1 */
77 };
78 
79 struct bi_ige_test {
80     const unsigned char key1[32];
81     const unsigned char key2[32];
82     const unsigned char iv[64];
83     const unsigned char in[MAX_VECTOR_SIZE];
84     const unsigned char out[MAX_VECTOR_SIZE];
85     const size_t keysize;
86     const size_t length;
87     const int encrypt;
88 };
89 
90 static struct bi_ige_test const bi_ige_test_vectors[] = {
91     {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
92       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key1 */
93      {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
94       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* key2 */
95      {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
96       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
97       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
98       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
99       0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
100       0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
101       0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
102       0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}, /* iv */
103      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* in */
107      {0x14, 0x40, 0x6f, 0xae, 0xa2, 0x79, 0xf2, 0x56,
108       0x1f, 0x86, 0xeb, 0x3b, 0x7d, 0xff, 0x53, 0xdc,
109       0x4e, 0x27, 0x0c, 0x03, 0xde, 0x7c, 0xe5, 0x16,
110       0x6a, 0x9c, 0x20, 0x33, 0x9d, 0x33, 0xfe, 0x12}, /* out */
111      16, 32, AES_ENCRYPT},      /* test vector 0 */
112     {{0x58, 0x0a, 0x06, 0xe9, 0x97, 0x07, 0x59, 0x5c,
113       0x9e, 0x19, 0xd2, 0xa7, 0xbb, 0x40, 0x2b, 0x7a,
114       0xc7, 0xd8, 0x11, 0x9e, 0x4c, 0x51, 0x35, 0x75,
115       0x64, 0x28, 0x0f, 0x23, 0xad, 0x74, 0xac, 0x37}, /* key1 */
116      {0xd1, 0x80, 0xa0, 0x31, 0x47, 0xa3, 0x11, 0x13,
117       0x86, 0x26, 0x9e, 0x6d, 0xff, 0xaf, 0x72, 0x74,
118       0x5b, 0xa2, 0x35, 0x81, 0xd2, 0xa6, 0x3d, 0x21,
119       0x67, 0x7b, 0x58, 0xa8, 0x18, 0xf9, 0x72, 0xe4}, /* key2 */
120      {0x80, 0x3d, 0xbd, 0x4c, 0xe6, 0x7b, 0x06, 0xa9,
121       0x53, 0x35, 0xd5, 0x7e, 0x71, 0xc1, 0x70, 0x70,
122       0x74, 0x9a, 0x00, 0x28, 0x0c, 0xbf, 0x6c, 0x42,
123       0x9b, 0xa4, 0xdd, 0x65, 0x11, 0x77, 0x7c, 0x67,
124       0xfe, 0x76, 0x0a, 0xf0, 0xd5, 0xc6, 0x6e, 0x6a,
125       0xe7, 0x5e, 0x4c, 0xf2, 0x7e, 0x9e, 0xf9, 0x20,
126       0x0e, 0x54, 0x6f, 0x2d, 0x8a, 0x8d, 0x7e, 0xbd,
127       0x48, 0x79, 0x37, 0x99, 0xff, 0x27, 0x93, 0xa3}, /* iv */
128      {0xf1, 0x54, 0x3d, 0xca, 0xfe, 0xb5, 0xef, 0x1c,
129       0x4f, 0xa6, 0x43, 0xf6, 0xe6, 0x48, 0x57, 0xf0,
130       0xee, 0x15, 0x7f, 0xe3, 0xe7, 0x2f, 0xd0, 0x2f,
131       0x11, 0x95, 0x7a, 0x17, 0x00, 0xab, 0xa7, 0x0b,
132       0xbe, 0x44, 0x09, 0x9c, 0xcd, 0xac, 0xa8, 0x52,
133       0xa1, 0x8e, 0x7b, 0x75, 0xbc, 0xa4, 0x92, 0x5a,
134       0xab, 0x46, 0xd3, 0x3a, 0xa0, 0xd5, 0x35, 0x1c,
135       0x55, 0xa4, 0xb3, 0xa8, 0x40, 0x81, 0xa5, 0x0b}, /* in */
136      {0x42, 0xe5, 0x28, 0x30, 0x31, 0xc2, 0xa0, 0x23,
137       0x68, 0x49, 0x4e, 0xb3, 0x24, 0x59, 0x92, 0x79,
138       0xc1, 0xa5, 0xcc, 0xe6, 0x76, 0x53, 0xb1, 0xcf,
139       0x20, 0x86, 0x23, 0xe8, 0x72, 0x55, 0x99, 0x92,
140       0x0d, 0x16, 0x1c, 0x5a, 0x2f, 0xce, 0xcb, 0x51,
141       0xe2, 0x67, 0xfa, 0x10, 0xec, 0xcd, 0x3d, 0x67,
142       0xa5, 0xe6, 0xf7, 0x31, 0x26, 0xb0, 0x0d, 0x76,
143       0x5e, 0x28, 0xdc, 0x7f, 0x01, 0xc5, 0xa5, 0x4c}, /* out */
144      32, 64, AES_ENCRYPT},      /* test vector 1 */
145 
146 };
147 
148 static int run_test_vectors(void)
149 {
150     unsigned int n;
151     int errs = 0;
152 
153     for (n = 0; n < OSSL_NELEM(ige_test_vectors); ++n) {
154         const struct ige_test *const v = &ige_test_vectors[n];
155         AES_KEY key;
156         unsigned char buf[MAX_VECTOR_SIZE];
157         unsigned char iv[AES_BLOCK_SIZE * 2];
158 
159         assert(v->length <= MAX_VECTOR_SIZE);
160 
161         if (v->encrypt == AES_ENCRYPT)
162             AES_set_encrypt_key(v->key, 8 * sizeof(v->key), &key);
163         else
164             AES_set_decrypt_key(v->key, 8 * sizeof(v->key), &key);
165         memcpy(iv, v->iv, sizeof(iv));
166         AES_ige_encrypt(v->in, buf, v->length, &key, iv, v->encrypt);
167 
168         if (memcmp(v->out, buf, v->length)) {
169             printf("IGE test vector %d failed\n", n);
170             hexdump(stdout, "key", v->key, sizeof(v->key));
171             hexdump(stdout, "iv", v->iv, sizeof(v->iv));
172             hexdump(stdout, "in", v->in, v->length);
173             hexdump(stdout, "expected", v->out, v->length);
174             hexdump(stdout, "got", buf, v->length);
175 
176             ++errs;
177         }
178 
179         /* try with in == out */
180         memcpy(iv, v->iv, sizeof(iv));
181         memcpy(buf, v->in, v->length);
182         AES_ige_encrypt(buf, buf, v->length, &key, iv, v->encrypt);
183 
184         if (memcmp(v->out, buf, v->length)) {
185             printf("IGE test vector %d failed (with in == out)\n", n);
186             hexdump(stdout, "key", v->key, sizeof(v->key));
187             hexdump(stdout, "iv", v->iv, sizeof(v->iv));
188             hexdump(stdout, "in", v->in, v->length);
189             hexdump(stdout, "expected", v->out, v->length);
190             hexdump(stdout, "got", buf, v->length);
191 
192             ++errs;
193         }
194     }
195 
196     for (n = 0; n < OSSL_NELEM(bi_ige_test_vectors); ++n) {
197         const struct bi_ige_test *const v = &bi_ige_test_vectors[n];
198         AES_KEY key1;
199         AES_KEY key2;
200         unsigned char buf[MAX_VECTOR_SIZE];
201 
202         assert(v->length <= MAX_VECTOR_SIZE);
203 
204         if (v->encrypt == AES_ENCRYPT) {
205             AES_set_encrypt_key(v->key1, 8 * v->keysize, &key1);
206             AES_set_encrypt_key(v->key2, 8 * v->keysize, &key2);
207         } else {
208             AES_set_decrypt_key(v->key1, 8 * v->keysize, &key1);
209             AES_set_decrypt_key(v->key2, 8 * v->keysize, &key2);
210         }
211 
212         AES_bi_ige_encrypt(v->in, buf, v->length, &key1, &key2, v->iv,
213                            v->encrypt);
214 
215         if (memcmp(v->out, buf, v->length)) {
216             printf("Bidirectional IGE test vector %d failed\n", n);
217             hexdump(stdout, "key 1", v->key1, sizeof(v->key1));
218             hexdump(stdout, "key 2", v->key2, sizeof(v->key2));
219             hexdump(stdout, "iv", v->iv, sizeof(v->iv));
220             hexdump(stdout, "in", v->in, v->length);
221             hexdump(stdout, "expected", v->out, v->length);
222             hexdump(stdout, "got", buf, v->length);
223 
224             ++errs;
225         }
226     }
227 
228     return errs;
229 }
230 
231 int main(int argc, char **argv)
232 {
233     unsigned char rkey[16];
234     unsigned char rkey2[16];
235     AES_KEY key;
236     AES_KEY key2;
237     unsigned char plaintext[BIG_TEST_SIZE];
238     unsigned char ciphertext[BIG_TEST_SIZE];
239     unsigned char checktext[BIG_TEST_SIZE];
240     unsigned char iv[AES_BLOCK_SIZE * 4];
241     unsigned char saved_iv[AES_BLOCK_SIZE * 4];
242     int err = 0;
243     unsigned int n;
244     unsigned matches;
245 
246     assert(BIG_TEST_SIZE >= TEST_SIZE);
247 
248     RAND_bytes(rkey, sizeof(rkey));
249     RAND_bytes(plaintext, sizeof(plaintext));
250     RAND_bytes(iv, sizeof(iv));
251     memcpy(saved_iv, iv, sizeof(saved_iv));
252 
253     /* Forward IGE only... */
254 
255     /* Straight encrypt/decrypt */
256     AES_set_encrypt_key(rkey, 8 * sizeof(rkey), &key);
257     AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, iv, AES_ENCRYPT);
258 
259     AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key);
260     memcpy(iv, saved_iv, sizeof(iv));
261     AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
262 
263     if (memcmp(checktext, plaintext, TEST_SIZE)) {
264         printf("Encrypt+decrypt doesn't match\n");
265         hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
266         hexdump(stdout, "Checktext", checktext, TEST_SIZE);
267         ++err;
268     }
269 
270     /* Now check encrypt chaining works */
271     AES_set_encrypt_key(rkey, 8 * sizeof(rkey), &key);
272     memcpy(iv, saved_iv, sizeof(iv));
273     AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
274                     AES_ENCRYPT);
275     AES_ige_encrypt(plaintext + TEST_SIZE / 2,
276                     ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
277                     &key, iv, AES_ENCRYPT);
278 
279     AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key);
280     memcpy(iv, saved_iv, sizeof(iv));
281     AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
282 
283     if (memcmp(checktext, plaintext, TEST_SIZE)) {
284         printf("Chained encrypt+decrypt doesn't match\n");
285         hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
286         hexdump(stdout, "Checktext", checktext, TEST_SIZE);
287         ++err;
288     }
289 
290     /* And check decrypt chaining */
291     AES_set_encrypt_key(rkey, 8 * sizeof(rkey), &key);
292     memcpy(iv, saved_iv, sizeof(iv));
293     AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
294                     AES_ENCRYPT);
295     AES_ige_encrypt(plaintext + TEST_SIZE / 2,
296                     ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
297                     &key, iv, AES_ENCRYPT);
298 
299     AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key);
300     memcpy(iv, saved_iv, sizeof(iv));
301     AES_ige_encrypt(ciphertext, checktext, TEST_SIZE / 2, &key, iv,
302                     AES_DECRYPT);
303     AES_ige_encrypt(ciphertext + TEST_SIZE / 2,
304                     checktext + TEST_SIZE / 2, TEST_SIZE / 2, &key, iv,
305                     AES_DECRYPT);
306 
307     if (memcmp(checktext, plaintext, TEST_SIZE)) {
308         printf("Chained encrypt+chained decrypt doesn't match\n");
309         hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
310         hexdump(stdout, "Checktext", checktext, TEST_SIZE);
311         ++err;
312     }
313 
314     /* make sure garble extends forwards only */
315     AES_set_encrypt_key(rkey, 8 * sizeof(rkey),&key);
316     memcpy(iv, saved_iv, sizeof(iv));
317     AES_ige_encrypt(plaintext, ciphertext, sizeof(plaintext), &key, iv,
318                     AES_ENCRYPT);
319 
320     /* corrupt halfway through */
321     ++ciphertext[sizeof(ciphertext) / 2];
322     AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key);
323     memcpy(iv, saved_iv, sizeof(iv));
324     AES_ige_encrypt(ciphertext, checktext, sizeof(checktext), &key, iv,
325                     AES_DECRYPT);
326 
327     matches = 0;
328     for (n = 0; n < sizeof(checktext); ++n)
329         if (checktext[n] == plaintext[n])
330             ++matches;
331 
332     if (matches > sizeof(checktext) / 2 + sizeof(checktext) / 100) {
333         printf("More than 51%% matches after garbling\n");
334         ++err;
335     }
336 
337     if (matches < sizeof(checktext) / 2) {
338         printf("Garble extends backwards!\n");
339         ++err;
340     }
341 
342     /* Bi-directional IGE */
343 
344     /*
345      * Note that we don't have to recover the IV, because chaining isn't
346      */
347     /* possible with biIGE, so the IV is not updated. */
348 
349     RAND_bytes(rkey2, sizeof(rkey2));
350 
351     /* Straight encrypt/decrypt */
352     AES_set_encrypt_key(rkey, 8 * sizeof(rkey), &key);
353     AES_set_encrypt_key(rkey2, 8 * sizeof(rkey2), &key2);
354     AES_bi_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, &key2, iv,
355                        AES_ENCRYPT);
356 
357     AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key);
358     AES_set_decrypt_key(rkey2, 8 * sizeof(rkey2), &key2);
359     AES_bi_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, &key2, iv,
360                        AES_DECRYPT);
361 
362     if (memcmp(checktext, plaintext, TEST_SIZE)) {
363         printf("Encrypt+decrypt doesn't match\n");
364         hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
365         hexdump(stdout, "Checktext", checktext, TEST_SIZE);
366         ++err;
367     }
368 
369     /* make sure garble extends both ways */
370     AES_set_encrypt_key(rkey, 8 * sizeof(rkey), &key);
371     AES_set_encrypt_key(rkey2, 8 * sizeof(rkey2), &key2);
372     AES_ige_encrypt(plaintext, ciphertext, sizeof(plaintext), &key, iv,
373                     AES_ENCRYPT);
374 
375     /* corrupt halfway through */
376     ++ciphertext[sizeof(ciphertext) / 2];
377     AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key);
378     AES_set_decrypt_key(rkey2, 8 * sizeof(rkey2), &key2);
379     AES_ige_encrypt(ciphertext, checktext, sizeof(checktext), &key, iv,
380                     AES_DECRYPT);
381 
382     matches = 0;
383     for (n = 0; n < sizeof(checktext); ++n)
384         if (checktext[n] == plaintext[n])
385             ++matches;
386 
387     if (matches > sizeof(checktext) / 100) {
388         printf("More than 1%% matches after bidirectional garbling\n");
389         ++err;
390     }
391 
392     /* make sure garble extends both ways (2) */
393     AES_set_encrypt_key(rkey, 8 * sizeof(rkey), &key);
394     AES_set_encrypt_key(rkey2, 8 * sizeof(rkey2), &key2);
395     AES_ige_encrypt(plaintext, ciphertext, sizeof(plaintext), &key, iv,
396                     AES_ENCRYPT);
397 
398     /* corrupt right at the end */
399     ++ciphertext[sizeof(ciphertext) - 1];
400     AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key);
401     AES_set_decrypt_key(rkey2, 8 * sizeof(rkey2), &key2);
402     AES_ige_encrypt(ciphertext, checktext, sizeof(checktext), &key, iv,
403                     AES_DECRYPT);
404 
405     matches = 0;
406     for (n = 0; n < sizeof(checktext); ++n)
407         if (checktext[n] == plaintext[n])
408             ++matches;
409 
410     if (matches > sizeof(checktext) / 100) {
411         printf("More than 1%% matches after bidirectional garbling (2)\n");
412         ++err;
413     }
414 
415     /* make sure garble extends both ways (3) */
416     AES_set_encrypt_key(rkey, 8 * sizeof(rkey), &key);
417     AES_set_encrypt_key(rkey2, 8 * sizeof(rkey2), &key2);
418     AES_ige_encrypt(plaintext, ciphertext, sizeof(plaintext), &key, iv,
419                     AES_ENCRYPT);
420 
421     /* corrupt right at the start */
422     ++ciphertext[0];
423     AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key);
424     AES_set_decrypt_key(rkey2, 8 * sizeof(rkey2), &key2);
425     AES_ige_encrypt(ciphertext, checktext, sizeof(checktext), &key, iv,
426                     AES_DECRYPT);
427 
428     matches = 0;
429     for (n = 0; n < sizeof(checktext); ++n)
430         if (checktext[n] == plaintext[n])
431             ++matches;
432 
433     if (matches > sizeof(checktext) / 100) {
434         printf("More than 1%% matches after bidirectional garbling (3)\n");
435         ++err;
436     }
437 
438     err += run_test_vectors();
439 
440     return err;
441 }
442