chacha20.c 7.6 KB

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