23 #include "SpeckTiny.h"
25 #include "utility/RotateUtil.h"
26 #include "utility/EndianUtil.h"
67 #define USE_AVR_INLINE_ASM 1
81 SpeckTiny::~SpeckTiny()
98 #define pack64(data, value) \
100 uint64_t v = htobe64((value)); \
101 memcpy((data), &v, sizeof(uint64_t)); \
103 #define unpack64(value, data) \
105 memcpy(&(value), (data), sizeof(uint64_t)); \
106 (value) = be64toh((value)); \
111 #if USE_AVR_INLINE_ASM
115 }
else if (len == 24) {
117 }
else if (len == 16) {
125 __asm__ __volatile__ (
127 "ld __tmp_reg__,-Z\n"
128 "st X+,__tmp_reg__\n"
131 : :
"x"(k),
"z"(key + len),
"r"(len)
137 unpack64(k[2], key + 8);
138 unpack64(k[1], key + 16);
139 unpack64(k[0], key + 24);
140 }
else if (len == 24) {
143 unpack64(k[1], key + 8);
144 unpack64(k[0], key + 16);
145 }
else if (len == 16) {
148 unpack64(k[0], key + 8);
158 #if USE_AVR_INLINE_ASM
162 uint8_t mb = (r - 31) * 8;
163 __asm__ __volatile__ (
169 "ld __tmp_reg__,X+\n"
170 "st Z+,__tmp_reg__\n"
203 "ld __tmp_reg__,Z+\n"
204 "eor __tmp_reg__,r9\n"
219 "mov r8,__tmp_reg__\n"
228 "adc r16, __zero_reg__\n"
237 "adc r16, __zero_reg__\n"
246 "adc r16, __zero_reg__\n"
255 "mov __tmp_reg__,r25\n"
258 "cp __tmp_reg__,r24\n"
288 "adc r31,__zero_reg__\n"
307 "sbc r31,__zero_reg__\n"
309 "adc r31,__zero_reg__\n"
319 "sbc r31,__zero_reg__\n"
328 "adc r16, __zero_reg__\n"
337 "adc r16, __zero_reg__\n"
346 "adc r16, __zero_reg__\n"
406 : :
"x"(k),
"z"(l),
"r"(input),
"Q"(output),
"Q"(mb),
"Q"(r)
407 :
"r8",
"r9",
"r10",
"r11",
"r12",
"r13",
"r14",
"r15",
408 "r16",
"r17",
"r18",
"r19",
"r20",
"r21",
"r22",
"r23",
"memory"
416 uint8_t li_out = rounds - 31;
421 unpack64(y, input + 8);
424 memcpy(l, k + 1, li_out *
sizeof(uint64_t));
428 for (round = rounds - 1; round > 0; --round, ++i) {
430 x = (rightRotate8_64(x) + y) ^ s;
431 y = leftRotate3_64(y) ^ x;
434 l[li_out] = (s + rightRotate8_64(l[li_in])) ^ i;
435 s = leftRotate3_64(s) ^ l[li_out];
436 li_in = (li_in + 1) & 0x03;
437 li_out = (li_out + 1) & 0x03;
441 x = (rightRotate8_64(x) + y) ^ s;
442 y = leftRotate3_64(y) ^ x;
444 pack64(output + 8, y);
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
void decryptBlock(uint8_t *output, const uint8_t *input)
Decrypts a single block using this cipher.
SpeckTiny()
Constructs a tiny-memory Speck block cipher with no initial key.
void clear()
Clears all security-sensitive state from this block cipher.
void encryptBlock(uint8_t *output, const uint8_t *input)
Encrypts a single block using this cipher.
size_t keySize() const
Default size of the key for this block cipher, in bytes.
size_t blockSize() const
Size of a single block processed by this cipher, in bytes.