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++];
203 #define quarterRound(a, b, c, d) \
206 uint32_t _a = (a) + _b; \
207 uint32_t _d = leftRotate((d) ^ _a, 16); \
208 uint32_t _c = (c) + _d; \
209 _b = leftRotate12(_b ^ _c); \
211 (d) = _d = leftRotate(_d ^ _a, 8); \
214 (b) = leftRotate7(_b ^ _c); \
236 for (posn = 0; posn < 16; ++posn)
237 output[posn] = le32toh(input[posn]);
240 for (; rounds >= 2; rounds -= 2) {
242 quarterRound(output[0], output[4], output[8], output[12]);
243 quarterRound(output[1], output[5], output[9], output[13]);
244 quarterRound(output[2], output[6], output[10], output[14]);
245 quarterRound(output[3], output[7], output[11], output[15]);
248 quarterRound(output[0], output[5], output[10], output[15]);
249 quarterRound(output[1], output[6], output[11], output[12]);
250 quarterRound(output[2], output[7], output[8], output[13]);
251 quarterRound(output[3], output[4], output[9], output[14]);
256 for (posn = 0; posn < 16; ++posn)
257 output[posn] = htole32(output[posn] + le32toh(input[posn]));
size_t ivSize() const
Size of the initialization vector for this cipher, in bytes.
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
size_t keySize() const
Default size of the key for this cipher, in bytes.
bool setIV(const uint8_t *iv, size_t len)
Sets the initialization vector to use for future encryption and decryption operations.
bool setCounter(const uint8_t *counter, size_t len)
Sets the starting counter for encryption.
ChaCha(uint8_t numRounds=20)
Constructs a new ChaCha stream cipher.
void decrypt(uint8_t *output, const uint8_t *input, size_t len)
Decrypts an input buffer and writes the plaintext to an output buffer.
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.
static void hashCore(uint32_t *output, const uint32_t *input, uint8_t rounds)
Executes the ChaCha hash core on an input memory block.