25 #include "utility/RotateUtil.h" 
   26 #include "utility/EndianUtil.h" 
   27 #include "utility/ProgMemUtil.h" 
   89     static const char tag128[] PROGMEM = 
"expand 16-byte k";
 
   90     static const char tag256[] PROGMEM = 
"expand 32-byte k";
 
   92         memcpy_P(block, tag128, 16);
 
   93         memcpy(block + 16, key, len);
 
   94         memcpy(block + 32, key, len);
 
   96             memset(block + 16 + len, 0, 16 - len);
 
   97             memset(block + 32 + len, 0, 16 - len);
 
  102         memcpy_P(block, tag256, 16);
 
  103         memcpy(block + 16, key, len);
 
  105             memset(block + 16 + len, 0, 32 - len);
 
  117         memset(block + 48, 0, 8);
 
  118         memcpy(block + 56, iv, len);
 
  121     } 
else if (len == 12) {
 
  122         memset(block + 48, 0, 4);
 
  123         memcpy(block + 52, iv, len);
 
  149     if (len == 4 || len == 8) {
 
  150         memcpy(block + 48, counter, len);
 
  163             hashCore((uint32_t *)stream, (
const uint32_t *)block, rounds);
 
  173                 temp += block[index];
 
  174                 block[index] = (uint8_t)temp;
 
  179         uint8_t templen = 64 - posn;
 
  183         while (templen > 0) {
 
  184             *output++ = *input++ ^ stream[posn++];
 
  207 void ChaCha::keystreamBlock(uint32_t *output)
 
  210     hashCore(output, (
const uint32_t *)block, rounds);
 
  226 #define quarterRound(a, b, c, d)    \ 
  229         uint32_t _a = (a) + _b; \ 
  230         uint32_t _d = leftRotate((d) ^ _a, 16); \ 
  231         uint32_t _c = (c) + _d; \ 
  232         _b = leftRotate12(_b ^ _c); \ 
  234         (d) = _d = leftRotate(_d ^ _a, 8); \ 
  237         (b) = leftRotate7(_b ^ _c); \ 
  259     for (posn = 0; posn < 16; ++posn)
 
  260         output[posn] = le32toh(input[posn]);
 
  263     for (; rounds >= 2; rounds -= 2) {
 
  265         quarterRound(output[0], output[4], output[8],  output[12]);
 
  266         quarterRound(output[1], output[5], output[9],  output[13]);
 
  267         quarterRound(output[2], output[6], output[10], output[14]);
 
  268         quarterRound(output[3], output[7], output[11], output[15]);
 
  271         quarterRound(output[0], output[5], output[10], output[15]);
 
  272         quarterRound(output[1], output[6], output[11], output[12]);
 
  273         quarterRound(output[2], output[7], output[8],  output[13]);
 
  274         quarterRound(output[3], output[4], output[9],  output[14]);
 
  279     for (posn = 0; posn < 16; ++posn)
 
  280         output[posn] = htole32(output[posn] + le32toh(input[posn]));
 
void decrypt(uint8_t *output, const uint8_t *input, size_t len)
Decrypts an input buffer and writes the plaintext to an output buffer.
static void hashCore(uint32_t *output, const uint32_t *input, uint8_t rounds)
Executes the ChaCha hash core on an input memory block.
ChaCha(uint8_t numRounds=20)
Constructs a new ChaCha stream cipher.
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
bool setIV(const uint8_t *iv, size_t len)
Sets the initialization vector to use for future encryption and decryption operations.
size_t keySize() const
Default size of the key for this cipher, in bytes.
size_t ivSize() const
Size of the initialization vector for this cipher, in bytes.
bool setCounter(const uint8_t *counter, size_t len)
Sets the starting counter for encryption.
void encrypt(uint8_t *output, const uint8_t *input, size_t len)
Encrypts an input buffer and writes the ciphertext to an output buffer.
void clear()
Clears all security-sensitive state from this cipher.