chacha_merged.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*
  2. chacha-merged.c version 20080118
  3. D. J. Bernstein
  4. Public domain.
  5. */
  6. #include "ecrypt_sync.h"
  7. #include "ecrypt_portable.h"
  8. #define ROTATE(v, c) (ROTL32(v, c))
  9. #define XOR(v, w) ((v) ^ (w))
  10. #define PLUS(v, w) (U32V((v) + (w)))
  11. #define PLUSONE(v) (PLUS((v), 1))
  12. #define QUARTERROUND(a, b, c, d) \
  13. a = PLUS(a, b); \
  14. d = ROTATE(XOR(d, a), 16); \
  15. c = PLUS(c, d); \
  16. b = ROTATE(XOR(b, c), 12); \
  17. a = PLUS(a, b); \
  18. d = ROTATE(XOR(d, a), 8); \
  19. c = PLUS(c, d); \
  20. b = ROTATE(XOR(b, c), 7);
  21. void ECRYPT_init(void) {
  22. return;
  23. }
  24. static const char sigma[16] = "expand 32-byte k";
  25. static const char tau[16] = "expand 16-byte k";
  26. void ECRYPT_keysetup(ECRYPT_ctx* x, const u8* k, u32 kbits, u32 ivbits) {
  27. (void)ivbits;
  28. const char* constants = (const char*)0;
  29. x->input[4] = U8TO32_LITTLE(k + 0);
  30. x->input[5] = U8TO32_LITTLE(k + 4);
  31. x->input[6] = U8TO32_LITTLE(k + 8);
  32. x->input[7] = U8TO32_LITTLE(k + 12);
  33. if(kbits == 256) { /* recommended */
  34. k += 16;
  35. constants = sigma;
  36. } else { /* kbits == 128 */
  37. constants = tau;
  38. }
  39. x->input[8] = U8TO32_LITTLE(k + 0);
  40. x->input[9] = U8TO32_LITTLE(k + 4);
  41. x->input[10] = U8TO32_LITTLE(k + 8);
  42. x->input[11] = U8TO32_LITTLE(k + 12);
  43. x->input[0] = U8TO32_LITTLE(constants + 0);
  44. x->input[1] = U8TO32_LITTLE(constants + 4);
  45. x->input[2] = U8TO32_LITTLE(constants + 8);
  46. x->input[3] = U8TO32_LITTLE(constants + 12);
  47. }
  48. void ECRYPT_ivsetup(ECRYPT_ctx* x, const u8* iv) {
  49. x->input[12] = 0;
  50. x->input[13] = 0;
  51. x->input[14] = U8TO32_LITTLE(iv + 0);
  52. x->input[15] = U8TO32_LITTLE(iv + 4);
  53. }
  54. void ECRYPT_ctrsetup(ECRYPT_ctx* x, const u8* ctr) {
  55. x->input[12] = U8TO32_LITTLE(ctr + 0);
  56. x->input[13] = U8TO32_LITTLE(ctr + 4);
  57. }
  58. void ECRYPT_encrypt_bytes(ECRYPT_ctx* x, const u8* m, u8* c, u32 bytes) {
  59. u32 x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0, x8 = 0, x9 = 0, x10 = 0,
  60. x11 = 0, x12 = 0, x13 = 0, x14 = 0, x15 = 0;
  61. u32 j0 = 0, j1 = 0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0, j7 = 0, j8 = 0, j9 = 0, j10 = 0,
  62. j11 = 0, j12 = 0, j13 = 0, j14 = 0, j15 = 0;
  63. u8* ctarget = 0;
  64. u8 tmp[64] = {0};
  65. int i = 0;
  66. if(!bytes) return;
  67. j0 = x->input[0];
  68. j1 = x->input[1];
  69. j2 = x->input[2];
  70. j3 = x->input[3];
  71. j4 = x->input[4];
  72. j5 = x->input[5];
  73. j6 = x->input[6];
  74. j7 = x->input[7];
  75. j8 = x->input[8];
  76. j9 = x->input[9];
  77. j10 = x->input[10];
  78. j11 = x->input[11];
  79. j12 = x->input[12];
  80. j13 = x->input[13];
  81. j14 = x->input[14];
  82. j15 = x->input[15];
  83. for(;;) {
  84. if(bytes < 64) {
  85. for(i = 0; i < (int)bytes; ++i) tmp[i] = m[i];
  86. m = tmp;
  87. ctarget = c;
  88. c = tmp;
  89. }
  90. x0 = j0;
  91. x1 = j1;
  92. x2 = j2;
  93. x3 = j3;
  94. x4 = j4;
  95. x5 = j5;
  96. x6 = j6;
  97. x7 = j7;
  98. x8 = j8;
  99. x9 = j9;
  100. x10 = j10;
  101. x11 = j11;
  102. x12 = j12;
  103. x13 = j13;
  104. x14 = j14;
  105. x15 = j15;
  106. for(i = 20; i > 0; i -= 2) {
  107. QUARTERROUND(x0, x4, x8, x12)
  108. QUARTERROUND(x1, x5, x9, x13)
  109. QUARTERROUND(x2, x6, x10, x14)
  110. QUARTERROUND(x3, x7, x11, x15)
  111. QUARTERROUND(x0, x5, x10, x15)
  112. QUARTERROUND(x1, x6, x11, x12)
  113. QUARTERROUND(x2, x7, x8, x13)
  114. QUARTERROUND(x3, x4, x9, x14)
  115. }
  116. x0 = PLUS(x0, j0);
  117. x1 = PLUS(x1, j1);
  118. x2 = PLUS(x2, j2);
  119. x3 = PLUS(x3, j3);
  120. x4 = PLUS(x4, j4);
  121. x5 = PLUS(x5, j5);
  122. x6 = PLUS(x6, j6);
  123. x7 = PLUS(x7, j7);
  124. x8 = PLUS(x8, j8);
  125. x9 = PLUS(x9, j9);
  126. x10 = PLUS(x10, j10);
  127. x11 = PLUS(x11, j11);
  128. x12 = PLUS(x12, j12);
  129. x13 = PLUS(x13, j13);
  130. x14 = PLUS(x14, j14);
  131. x15 = PLUS(x15, j15);
  132. x0 = XOR(x0, U8TO32_LITTLE(m + 0));
  133. x1 = XOR(x1, U8TO32_LITTLE(m + 4));
  134. x2 = XOR(x2, U8TO32_LITTLE(m + 8));
  135. x3 = XOR(x3, U8TO32_LITTLE(m + 12));
  136. x4 = XOR(x4, U8TO32_LITTLE(m + 16));
  137. x5 = XOR(x5, U8TO32_LITTLE(m + 20));
  138. x6 = XOR(x6, U8TO32_LITTLE(m + 24));
  139. x7 = XOR(x7, U8TO32_LITTLE(m + 28));
  140. x8 = XOR(x8, U8TO32_LITTLE(m + 32));
  141. x9 = XOR(x9, U8TO32_LITTLE(m + 36));
  142. x10 = XOR(x10, U8TO32_LITTLE(m + 40));
  143. x11 = XOR(x11, U8TO32_LITTLE(m + 44));
  144. x12 = XOR(x12, U8TO32_LITTLE(m + 48));
  145. x13 = XOR(x13, U8TO32_LITTLE(m + 52));
  146. x14 = XOR(x14, U8TO32_LITTLE(m + 56));
  147. x15 = XOR(x15, U8TO32_LITTLE(m + 60));
  148. j12 = PLUSONE(j12);
  149. if(!j12) {
  150. j13 = PLUSONE(j13);
  151. /* stopping at 2^70 bytes per nonce is user's responsibility */
  152. }
  153. U32TO8_LITTLE(c + 0, x0);
  154. U32TO8_LITTLE(c + 4, x1);
  155. U32TO8_LITTLE(c + 8, x2);
  156. U32TO8_LITTLE(c + 12, x3);
  157. U32TO8_LITTLE(c + 16, x4);
  158. U32TO8_LITTLE(c + 20, x5);
  159. U32TO8_LITTLE(c + 24, x6);
  160. U32TO8_LITTLE(c + 28, x7);
  161. U32TO8_LITTLE(c + 32, x8);
  162. U32TO8_LITTLE(c + 36, x9);
  163. U32TO8_LITTLE(c + 40, x10);
  164. U32TO8_LITTLE(c + 44, x11);
  165. U32TO8_LITTLE(c + 48, x12);
  166. U32TO8_LITTLE(c + 52, x13);
  167. U32TO8_LITTLE(c + 56, x14);
  168. U32TO8_LITTLE(c + 60, x15);
  169. if(bytes <= 64) {
  170. if(bytes < 64) {
  171. for(i = 0; i < (int)bytes; ++i) ctarget[i] = c[i];
  172. }
  173. x->input[12] = j12;
  174. x->input[13] = j13;
  175. return;
  176. }
  177. bytes -= 64;
  178. c += 64;
  179. m += 64;
  180. }
  181. }
  182. void ECRYPT_decrypt_bytes(ECRYPT_ctx* x, const u8* c, u8* m, u32 bytes) {
  183. ECRYPT_encrypt_bytes(x, c, m, bytes);
  184. }
  185. void ECRYPT_keystream_bytes(ECRYPT_ctx* x, u8* stream, u32 bytes) {
  186. u32 i = 0;
  187. for(i = 0; i < bytes; ++i) stream[i] = 0;
  188. ECRYPT_encrypt_bytes(x, stream, stream, bytes);
  189. }
  190. void hchacha20(ECRYPT_ctx* x, u8* c) {
  191. u32 x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0, x8 = 0, x9 = 0, x10 = 0,
  192. x11 = 0, x12 = 0, x13 = 0, x14 = 0, x15 = 0;
  193. int i = 0;
  194. x0 = x->input[0];
  195. x1 = x->input[1];
  196. x2 = x->input[2];
  197. x3 = x->input[3];
  198. x4 = x->input[4];
  199. x5 = x->input[5];
  200. x6 = x->input[6];
  201. x7 = x->input[7];
  202. x8 = x->input[8];
  203. x9 = x->input[9];
  204. x10 = x->input[10];
  205. x11 = x->input[11];
  206. x12 = x->input[12];
  207. x13 = x->input[13];
  208. x14 = x->input[14];
  209. x15 = x->input[15];
  210. for(i = 20; i > 0; i -= 2) {
  211. QUARTERROUND(x0, x4, x8, x12)
  212. QUARTERROUND(x1, x5, x9, x13)
  213. QUARTERROUND(x2, x6, x10, x14)
  214. QUARTERROUND(x3, x7, x11, x15)
  215. QUARTERROUND(x0, x5, x10, x15)
  216. QUARTERROUND(x1, x6, x11, x12)
  217. QUARTERROUND(x2, x7, x8, x13)
  218. QUARTERROUND(x3, x4, x9, x14)
  219. }
  220. U32TO8_LITTLE(c + 0, x0);
  221. U32TO8_LITTLE(c + 4, x1);
  222. U32TO8_LITTLE(c + 8, x2);
  223. U32TO8_LITTLE(c + 12, x3);
  224. U32TO8_LITTLE(c + 16, x12);
  225. U32TO8_LITTLE(c + 20, x13);
  226. U32TO8_LITTLE(c + 24, x14);
  227. U32TO8_LITTLE(c + 28, x15);
  228. }