[Title] Add packaging/nettle.spec to build nettle on OBS system
[external/nettle.git] / testsuite / yarrow-test.c
1 #include "testutils.h"
2 #include "yarrow.h"
3 #include "knuth-lfib.h"
4
5 #include "macros.h"
6
7 #include <assert.h>
8 #include <errno.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12
13 /* Lagged fibonacci sequence as described in Knuth 3.6 */
14
15 struct knuth_lfib_ctx lfib;
16
17 static int
18 get_event(FILE *f, struct sha256_ctx *hash,
19           unsigned *key, unsigned *time)
20 {
21   static int t = 0;
22   uint8_t buf[1];
23   
24   int c = getc(f);
25   if (c == EOF)
26     return 0;
27
28   buf[0] = c;
29   sha256_update(hash, sizeof(buf), buf);
30     
31   *key = c;
32
33   t += (knuth_lfib_get(&lfib) % 10000);
34   *time = t;
35
36   return 1;
37 }
38
39 static FILE *
40 open_file(const char *name)
41 {
42   /* Tries opening the file in $srcdir, if set, otherwise the current
43    * working directory */
44
45   const char *srcdir = getenv("srcdir");
46   if (srcdir && srcdir[0])
47     {
48       /* Leaks this name, but that doesn't matter. */
49       char *buf = xalloc(strlen(name) + strlen(srcdir) + 10);
50       sprintf(buf, "%s/%s", srcdir, name);
51       name = buf;
52     }
53
54   /* Opens the file in text mode. */
55   return fopen(name, "r");
56 }
57
58 int
59 test_main(void)
60 {
61   FILE *input;
62   
63   struct yarrow256_ctx yarrow;
64   struct yarrow_key_event_ctx estimator;
65
66   struct yarrow_source sources[2];
67
68   struct sha256_ctx output_hash;
69   struct sha256_ctx input_hash;
70   uint8_t digest[SHA256_DIGEST_SIZE];
71
72   uint8_t seed_file[YARROW256_SEED_FILE_SIZE];
73
74   const uint8_t *expected_output
75     = decode_hex_dup("dd304aacac3dc95e 70d684a642967c89"
76                      "58501f7c8eb88b79 43b2ffccde6f0f79");
77
78   const uint8_t *expected_input
79     = decode_hex_dup("e0596cf006025506 65d1195f32a87e4a"
80                      "5c354910dfbd0a31 e2105b262f5ce3d8");
81
82   const uint8_t *expected_seed_file
83     = decode_hex_dup("b03518f32b1084dd 983e6a445d47bb6f"
84                      "13bb7b998740d570 503d6aaa62e28901");
85   
86   unsigned c; unsigned t;
87
88   unsigned processed = 0;
89   unsigned output = 0;
90
91   unsigned i;
92   
93   static const char zeroes[100];
94
95   yarrow256_init(&yarrow, 2, sources);
96   
97   yarrow_key_event_init(&estimator);
98   sha256_init(&input_hash);
99   sha256_init(&output_hash);
100
101   knuth_lfib_init(&lfib, 31416);
102
103   /* Fake input to source 0 */
104   yarrow256_update(&yarrow, 0, 200, sizeof(zeroes), zeroes);
105
106   if (verbose)
107     printf("source 0 entropy: %d\n",
108            sources[0].estimate[YARROW_SLOW]);
109   
110   assert(!yarrow256_is_seeded(&yarrow));
111
112   input = open_file("gold-bug.txt");
113
114   if (!input)
115     {
116       fprintf(stderr, "Couldn't open `gold-bug.txt', errno = %d\n",
117               errno);
118       return EXIT_FAILURE;
119     }
120   
121   while (get_event(input, &input_hash, &c, &t))
122     {
123       uint8_t buf[8];
124
125       processed++;
126       
127       WRITE_UINT32(buf, c);
128       WRITE_UINT32(buf + 4, t);
129       yarrow256_update(&yarrow, 1,
130                        yarrow_key_event_estimate(&estimator, c, t),
131                        sizeof(buf), buf);
132
133       if (yarrow256_is_seeded(&yarrow))
134         {
135           static const unsigned sizes[4] = { 1, 16, 500, 37 };
136           unsigned size = sizes[processed % 4];
137           
138           uint8_t buf[500];
139
140           if (verbose && !output)
141             printf("Generator was seeded after %d events\n",
142                    processed);
143           
144           yarrow256_random(&yarrow, size, buf);
145
146           sha256_update(&output_hash, size, buf);
147
148           if (verbose)
149             {
150               printf("%02x ", buf[0]);
151               if (! (processed % 16))
152                 printf("\n");
153             }
154           output += size;
155         }
156     }
157
158   if (verbose)
159     {
160       printf("\n");
161       
162       for (i = 0; i<2; i++)
163         printf("source %d, (fast, slow) entropy: (%d, %d)\n",
164                i,
165                sources[i].estimate[YARROW_FAST],
166                sources[i].estimate[YARROW_SLOW]); 
167       
168       printf("Processed input: %d octets\n", processed);
169       printf("         sha256:");
170     }
171
172   sha256_digest(&input_hash, sizeof(digest), digest);
173
174   if (verbose)
175     {
176       print_hex(sizeof(digest), digest);
177       printf("\n");
178     }
179   
180   if (memcmp(digest, expected_input, sizeof(digest)))
181     {
182       fprintf(stderr, "Failed.\n");
183       return EXIT_FAILURE;
184     }
185
186   yarrow256_random(&yarrow, sizeof(seed_file), seed_file);
187   if (verbose)
188     {
189       printf("New seed file: ");
190       print_hex(sizeof(seed_file), seed_file);
191       printf("\n");
192     }
193
194   if (memcmp(seed_file, expected_seed_file, sizeof(seed_file)))
195     {
196       fprintf(stderr, "Failed.\n");
197       return EXIT_FAILURE;
198     }
199   
200   if (verbose)
201     {
202       printf("Generated output: %d octets\n", output);
203       printf("          sha256:");
204     }
205   
206   sha256_digest(&output_hash, sizeof(digest), digest);
207
208   if (verbose)
209     {
210       print_hex(sizeof(digest), digest);
211       printf("\n");
212     }
213   
214   if (memcmp(digest, expected_output, sizeof(digest)))
215     {
216       fprintf(stderr, "Failed.\n");
217       return EXIT_FAILURE;
218     }
219   
220   return EXIT_SUCCESS;
221 }