1
2#define TEST_NAME "chacha20"
3#include "cmptest.h"
4
5static
6void tv(void)
7{
8    static struct {
9        const char *key_hex;
10        const char *nonce_hex;
11    } tests[]
12      = { { "0000000000000000000000000000000000000000000000000000000000000000",
13            "0000000000000000" },
14          { "0000000000000000000000000000000000000000000000000000000000000001",
15            "0000000000000000" },
16          { "0000000000000000000000000000000000000000000000000000000000000000",
17            "0000000000000001" },
18          { "0000000000000000000000000000000000000000000000000000000000000000",
19            "0100000000000000" },
20          { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
21            "0001020304050607" } };
22    unsigned char  key[crypto_stream_chacha20_KEYBYTES];
23    unsigned char  nonce[crypto_stream_chacha20_NONCEBYTES];
24    unsigned char *part;
25    unsigned char  out[160];
26    unsigned char  zero[160];
27    char           out_hex[160 * 2 + 1];
28    size_t         i = 0U;
29    size_t         plen;
30
31    memset(zero, 0, sizeof zero);
32    do {
33        sodium_hex2bin((unsigned char *)key, sizeof key, tests[i].key_hex,
34                       strlen(tests[i].key_hex), NULL, NULL, NULL);
35        sodium_hex2bin(nonce, sizeof nonce, tests[i].nonce_hex,
36                       strlen(tests[i].nonce_hex), NULL, NULL, NULL);
37        crypto_stream_chacha20(out, sizeof out, nonce, key);
38        sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
39        printf("[%s]\n", out_hex);
40        for (plen = 1U; plen < sizeof out; plen++) {
41            part = (unsigned char *) sodium_malloc(plen);
42            crypto_stream_chacha20_xor(part, out, plen, nonce, key);
43            if (memcmp(part, zero, plen) != 0) {
44                printf("Failed with length %lu\n", (unsigned long) plen);
45            }
46            sodium_free(part);
47        }
48    } while (++i < (sizeof tests) / (sizeof tests[0]));
49    assert(66 <= sizeof out);
50    for (plen = 1U; plen < 66; plen += 3) {
51        memset(out, (int) (plen & 0xff), sizeof out);
52        crypto_stream_chacha20(out, plen, nonce, key);
53        sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
54        printf("[%s]\n", out_hex);
55    }
56    randombytes_buf(out, sizeof out);
57    crypto_stream_chacha20(out, sizeof out, nonce, key);
58    sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
59    printf("[%s]\n", out_hex);
60
61    assert(crypto_stream_chacha20(out, 0U, nonce, key) == 0);
62    assert(crypto_stream_chacha20_xor(out, out, 0U, nonce, key) == 0);
63    assert(crypto_stream_chacha20_xor(out, out, 0U, nonce, key) == 0);
64    assert(crypto_stream_chacha20_xor_ic(out, out, 0U, nonce, 1U, key) == 0);
65
66    memset(out, 0x42, sizeof out);
67    crypto_stream_chacha20_xor(out, out, sizeof out, nonce, key);
68    sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
69    printf("[%s]\n", out_hex);
70
71    crypto_stream_chacha20_xor_ic(out, out, sizeof out, nonce, 0U, key);
72    sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
73    printf("[%s]\n", out_hex);
74
75    crypto_stream_chacha20_xor_ic(out, out, sizeof out, nonce, 1U, key);
76    sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
77    printf("[%s]\n", out_hex);
78}
79
80static
81void tv_ietf(void)
82{
83    static struct {
84        const char *key_hex;
85        const char *nonce_hex;
86        uint32_t    ic;
87    } tests[]
88      = { { "0000000000000000000000000000000000000000000000000000000000000000",
89            "000000000000000000000000",
90            0U },
91          { "0000000000000000000000000000000000000000000000000000000000000000",
92            "000000000000000000000000",
93            1U },
94          { "0000000000000000000000000000000000000000000000000000000000000001",
95            "000000000000000000000000",
96            1U },
97          { "00ff000000000000000000000000000000000000000000000000000000000000",
98            "000000000000000000000000",
99            2U },
100          { "0000000000000000000000000000000000000000000000000000000000000000",
101            "000000000000000000000002",
102            0U },
103          { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
104            "000000090000004a00000000",
105            1U },
106          { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
107            "000000090000004a00000000",
108            0xffffffff }};
109    unsigned char  key[crypto_stream_chacha20_KEYBYTES];
110    unsigned char  nonce[crypto_stream_chacha20_IETF_NONCEBYTES];
111    unsigned char *part;
112    unsigned char  out[160];
113    unsigned char  zero[160];
114    char           out_hex[160 * 2 + 1];
115    size_t         i = 0U;
116    size_t         plen;
117
118    memset(zero, 0, sizeof zero);
119    do {
120        sodium_hex2bin((unsigned char *)key, sizeof key, tests[i].key_hex,
121                       strlen(tests[i].key_hex), ": ", NULL, NULL);
122        sodium_hex2bin(nonce, sizeof nonce, tests[i].nonce_hex,
123                       strlen(tests[i].nonce_hex), ": ", NULL, NULL);
124        memset(out, 0, sizeof out);
125        crypto_stream_chacha20_ietf_xor_ic(out, out, sizeof out, nonce, tests[i].ic, key);
126        sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
127        printf("[%s]\n", out_hex);
128        for (plen = 1U; plen < sizeof out; plen++) {
129            part = (unsigned char *) sodium_malloc(plen);
130            crypto_stream_chacha20_ietf_xor_ic(part, out, plen, nonce, tests[i].ic, key);
131            if (memcmp(part, zero, plen) != 0) {
132                printf("Failed with length %lu\n", (unsigned long) plen);
133            }
134            sodium_free(part);
135        }
136    } while (++i < (sizeof tests) / (sizeof tests[0]));
137    assert(66 <= sizeof out);
138    for (plen = 1U; plen < 66; plen += 3) {
139        memset(out, (int) (plen & 0xff), sizeof out);
140        crypto_stream_chacha20(out, plen, nonce, key);
141        sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
142        printf("[%s]\n", out_hex);
143    }
144    randombytes_buf(out, sizeof out);
145    crypto_stream_chacha20_ietf(out, sizeof out, nonce, key);
146    sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
147    printf("[%s]\n", out_hex);
148
149    assert(crypto_stream_chacha20_ietf(out, 0U, nonce, key) == 0);
150    assert(crypto_stream_chacha20_ietf_xor(out, out, 0U, nonce, key) == 0);
151    assert(crypto_stream_chacha20_ietf_xor(out, out, 0U, nonce, key) == 0);
152    assert(crypto_stream_chacha20_ietf_xor_ic(out, out, 0U, nonce, 1U, key) == 0);
153
154    memset(out, 0x42, sizeof out);
155    crypto_stream_chacha20_ietf_xor(out, out, sizeof out, nonce, key);
156    sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
157    printf("[%s]\n", out_hex);
158
159    crypto_stream_chacha20_ietf_xor_ic(out, out, sizeof out, nonce, 0U, key);
160    sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
161    printf("[%s]\n", out_hex);
162
163    crypto_stream_chacha20_ietf_xor_ic(out, out, sizeof out, nonce, 1U, key);
164    sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
165    printf("[%s]\n", out_hex);
166}
167
168int
169main(void)
170{
171    tv();
172    tv_ietf();
173
174    assert(crypto_stream_chacha20_keybytes() > 0U);
175    assert(crypto_stream_chacha20_keybytes() == crypto_stream_chacha20_KEYBYTES);
176    assert(crypto_stream_chacha20_noncebytes() > 0U);
177    assert(crypto_stream_chacha20_noncebytes() == crypto_stream_chacha20_NONCEBYTES);
178    assert(crypto_stream_chacha20_messagebytes_max() == crypto_stream_chacha20_MESSAGEBYTES_MAX);
179    assert(crypto_stream_chacha20_ietf_keybytes() > 0U);
180    assert(crypto_stream_chacha20_ietf_keybytes() == crypto_stream_chacha20_ietf_KEYBYTES);
181    assert(crypto_stream_chacha20_ietf_noncebytes() > 0U);
182    assert(crypto_stream_chacha20_ietf_noncebytes() == crypto_stream_chacha20_ietf_NONCEBYTES);
183    assert(crypto_stream_chacha20_ietf_messagebytes_max() == crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX);
184
185    return 0;
186}
187