Advertisement
FlyFar

libs/ChaCha20/chacha20.cpp

Mar 24th, 2024
564
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.85 KB | Cybersecurity | 0 0
  1. #include <stdint.h>
  2. #include <string.h>
  3. #include "chacha20.h"
  4.  
  5. static inline void u32t8le(uint32_t v, uint8_t p[4]) {
  6.     p[0] = v & 0xff;
  7.     p[1] = (v >> 8) & 0xff;
  8.     p[2] = (v >> 16) & 0xff;
  9.     p[3] = (v >> 24) & 0xff;
  10. }
  11.  
  12. static inline uint32_t u8t32le(uint8_t p[4]) {
  13.     uint32_t value = p[3];
  14.  
  15.     value = (value << 8) | p[2];
  16.     value = (value << 8) | p[1];
  17.     value = (value << 8) | p[0];
  18.  
  19.     return value;
  20. }
  21.  
  22. static inline uint32_t rotl32(uint32_t x, int n) {
  23.     // http://blog.regehr.org/archives/1063
  24.     return x << n | (x >> (-n & 31));
  25. }
  26.  
  27. // https://tools.ietf.org/html/rfc7539#section-2.1
  28. static void chacha20_quarterround(uint32_t *x, int a, int b, int c, int d) {
  29.     x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 16);
  30.     x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 12);
  31.     x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a],  8);
  32.     x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c],  7);
  33. }
  34.  
  35. static void chacha20_serialize(uint32_t in[16], uint8_t output[64]) {
  36.     int i;
  37.     for (i = 0; i < 16; i++) {
  38.         u32t8le(in[i], output + (i << 2));
  39.     }
  40. }
  41.  
  42. static void chacha20_block(uint32_t in[16], uint8_t out[64], int num_rounds) {
  43.     int i;
  44.     uint32_t x[16];
  45.  
  46.     memcpy(x, in, sizeof(uint32_t) * 16);
  47.  
  48.     for (i = num_rounds; i > 0; i -= 2) {
  49.         chacha20_quarterround(x, 0, 4,  8, 12);
  50.         chacha20_quarterround(x, 1, 5,  9, 13);
  51.         chacha20_quarterround(x, 2, 6, 10, 14);
  52.         chacha20_quarterround(x, 3, 7, 11, 15);
  53.         chacha20_quarterround(x, 0, 5, 10, 15);
  54.         chacha20_quarterround(x, 1, 6, 11, 12);
  55.         chacha20_quarterround(x, 2, 7,  8, 13);
  56.         chacha20_quarterround(x, 3, 4,  9, 14);
  57.     }
  58.  
  59.     for (i = 0; i < 16; i++) {
  60.         x[i] += in[i];
  61.     }
  62.  
  63.     chacha20_serialize(x, out);
  64. }
  65.  
  66. // https://tools.ietf.org/html/rfc7539#section-2.3
  67. static void chacha20_init_state(uint32_t s[16], uint8_t key[32], uint32_t counter, uint8_t nonce[12]) {
  68.     int i;
  69.  
  70.     // refer: https://dxr.mozilla.org/mozilla-beta/source/security/nss/lib/freebl/chacha20.c
  71.     // convert magic number to string: "expand 32-byte k"
  72.     s[0] = 0x61707865;
  73.     s[1] = 0x3320646e;
  74.     s[2] = 0x79622d32;
  75.     s[3] = 0x6b206574;
  76.  
  77.     for (i = 0; i < 8; i++) {
  78.         s[4 + i] = u8t32le(key + i * 4);
  79.     }
  80.  
  81.     s[12] = counter;
  82.  
  83.     for (i = 0; i < 3; i++) {
  84.         s[13 + i] = u8t32le(nonce + i * 4);
  85.     }
  86. }
  87.  
  88. void ChaCha20XOR(uint8_t key[32], uint32_t counter, uint8_t nonce[12], uint8_t *in, uint8_t *out, int inlen) {
  89.     int i, j;
  90.  
  91.     uint32_t s[16];
  92.     uint8_t block[64];
  93.  
  94.     chacha20_init_state(s, key, counter, nonce);
  95.  
  96.     for (i = 0; i < inlen; i += 64) {
  97.         chacha20_block(s, block, 20);
  98.         s[12]++;
  99.  
  100.         for (j = i; j < i + 64; j++) {
  101.             if (j >= inlen) {
  102.                 break;
  103.             }
  104.             out[j] = in[j] ^ block[j - i];
  105.         }
  106.     }
  107. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement