1
2#define TEST_NAME "randombytes"
3#include "cmptest.h"
4
5static unsigned char      x[65536];
6static unsigned long long freq[256];
7
8static int
9compat_tests(void)
10{
11    size_t i;
12
13    memset(x, 0, sizeof x);
14    randombytes(x, sizeof x);
15    for (i = 0; i < 256; ++i) {
16        freq[i] = 0;
17    }
18    for (i = 0; i < sizeof x; ++i) {
19        ++freq[255 & (int) x[i]];
20    }
21    for (i = 0; i < 256; ++i) {
22        if (!freq[i]) {
23            printf("nacl_tests failed\n");
24        }
25    }
26    return 0;
27}
28
29static int
30randombytes_tests(void)
31{
32    static const unsigned char seed[randombytes_SEEDBYTES] = {
33        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
34        0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
35        0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
36    };
37    unsigned char out[100];
38    unsigned int  f = 0U;
39    unsigned int  i;
40    uint32_t      n;
41
42#ifndef BENCHMARKS
43# ifdef __EMSCRIPTEN__
44    assert(strcmp(randombytes_implementation_name(), "js") == 0);
45# elif defined(__native_client__)
46    assert(strcmp(randombytes_implementation_name(), "nativeclient") == 0);
47# else
48    assert(strcmp(randombytes_implementation_name(), "sysrandom") == 0);
49# endif
50#endif
51    randombytes(x, 1U);
52    do {
53        n = randombytes_random();
54        f |= ((n >> 24) > 1);
55        f |= ((n >> 16) > 1) << 1;
56        f |= ((n >> 8) > 1) << 2;
57        f |= ((n) > 1) << 3;
58        f |= (n > 0x7fffffff) << 4;
59    } while (f != 0x1f);
60    randombytes_close();
61
62    for (i = 0; i < 256; ++i) {
63        freq[i] = 0;
64    }
65    for (i = 0; i < 65536; ++i) {
66        ++freq[randombytes_uniform(256)];
67    }
68    for (i = 0; i < 256; ++i) {
69        if (!freq[i]) {
70            printf("randombytes_uniform() test failed\n");
71        }
72    }
73    assert(randombytes_uniform(1U) == 0U);
74    randombytes_close();
75#ifndef __EMSCRIPTEN__
76    randombytes_set_implementation(&randombytes_salsa20_implementation);
77    assert(strcmp(randombytes_implementation_name(), "salsa20") == 0);
78#endif
79    randombytes_stir();
80    for (i = 0; i < 256; ++i) {
81        freq[i] = 0;
82    }
83    for (i = 0; i < 65536; ++i) {
84        ++freq[randombytes_uniform(256)];
85    }
86    for (i = 0; i < 256; ++i) {
87        if (!freq[i]) {
88            printf("randombytes_uniform() test failed\n");
89        }
90    }
91    memset(x, 0, sizeof x);
92    randombytes_buf(x, sizeof x);
93    for (i = 0; i < 256; ++i) {
94        freq[i] = 0;
95    }
96    for (i = 0; i < sizeof x; ++i) {
97        ++freq[255 & (int) x[i]];
98    }
99    for (i = 0; i < 256; ++i) {
100        if (!freq[i]) {
101            printf("randombytes_buf() test failed\n");
102        }
103    }
104    assert(randombytes_uniform(1U) == 0U);
105
106    randombytes_buf_deterministic(out, sizeof out, seed);
107    for (i = 0; i < sizeof out; ++i) {
108        printf("%02x", out[i]);
109    }
110    printf(" (deterministic)\n");
111
112    randombytes_close();
113
114    randombytes(x, 1U);
115    randombytes_close();
116
117    assert(randombytes_SEEDBYTES > 0);
118    assert(randombytes_seedbytes() == randombytes_SEEDBYTES);
119
120    return 0;
121}
122
123static uint32_t
124randombytes_uniform_impl(const uint32_t upper_bound)
125{
126    return upper_bound;
127}
128
129static int
130impl_tests(void)
131{
132#ifndef __native_client__
133    randombytes_implementation impl = randombytes_sysrandom_implementation;
134#else
135    randombytes_implementation impl = randombytes_nativeclient_implementation;
136#endif
137    uint32_t                   v = randombytes_random();
138
139    impl.uniform = randombytes_uniform_impl;
140    randombytes_close();
141    randombytes_set_implementation(&impl);
142    assert(randombytes_uniform(1) == 1);
143    assert(randombytes_uniform(v) == v);
144    assert(randombytes_uniform(v) == v);
145    assert(randombytes_uniform(v) == v);
146    assert(randombytes_uniform(v) == v);
147    randombytes_close();
148    impl.close = NULL;
149    randombytes_close();
150
151    return 0;
152}
153
154int
155main(void)
156{
157    compat_tests();
158    randombytes_tests();
159#ifndef __EMSCRIPTEN__
160    impl_tests();
161#endif
162    printf("OK\n");
163
164#ifndef __EMSCRIPTEN__
165    randombytes_set_implementation(&randombytes_salsa20_implementation);
166#endif
167
168    return 0;
169}
170