23 #include "SpeckSmall.h"
25 #include "utility/RotateUtil.h"
26 #include "utility/EndianUtil.h"
64 #define USE_AVR_INLINE_ASM 1
68 #define pack64(data, value) \
70 uint64_t v = htobe64((value)); \
71 memcpy((data), &v, sizeof(uint64_t)); \
73 #define unpack64(value, data) \
75 memcpy(&(value), (data), sizeof(uint64_t)); \
76 (value) = be64toh((value)); \
89 SpeckSmall::~SpeckSmall()
100 #if USE_AVR_INLINE_ASM
103 uint8_t mb = (rounds - 31) * 8;
104 __asm__ __volatile__ (
116 "ld __tmp_reg__,Z+\n"
117 "st X+,__tmp_reg__\n"
121 "sbc %B1,__zero_reg__\n"
127 "adc %B1,__zero_reg__\n"
152 "sbc %B1,__zero_reg__\n"
156 "adc %B1,__zero_reg__\n"
169 "sbc %B1,__zero_reg__\n"
181 "adc r16,__zero_reg__\n"
191 "adc r16,__zero_reg__\n"
201 "adc r16,__zero_reg__\n"
220 "adc %B1,__zero_reg__\n"
235 :
"r8",
"r9",
"r10",
"r11",
"r12",
"r13",
"r14",
"r15",
236 "r16",
"r17",
"r18",
"r19",
"r20",
"r21",
"r22",
"r23",
243 uint8_t m = rounds - 30;
245 uint8_t li_out = m - 1;
247 memcpy(l, k + 1, (m - 1) *
sizeof(uint64_t));
248 for (uint8_t i = 0; i < (rounds - 1); ++i) {
249 l[li_out] = (s + rightRotate8_64(l[li_in])) ^ i;
250 s = leftRotate3_64(s) ^ l[li_out];
251 li_in = (li_in + 1) & 0x03;
252 li_out = (li_out + 1) & 0x03;
263 #if USE_AVR_INLINE_ASM
267 uint8_t li_in = ((r + 3) & 0x03) * 8;
268 uint8_t li_out = ((((r - 31) & 0x03) * 8) + li_in) & 0x1F;
269 __asm__ __volatile__ (
273 "ld __tmp_reg__,X+\n"
274 "st Z+,__tmp_reg__\n"
280 "adc r31,__zero_reg__\n"
282 "st X+,__tmp_reg__\n"
283 "ldd __tmp_reg__,Z+1\n"
284 "st X+,__tmp_reg__\n"
285 "ldd __tmp_reg__,Z+2\n"
286 "st X+,__tmp_reg__\n"
287 "ldd __tmp_reg__,Z+3\n"
288 "st X+,__tmp_reg__\n"
289 "ldd __tmp_reg__,Z+4\n"
290 "st X+,__tmp_reg__\n"
291 "ldd __tmp_reg__,Z+5\n"
292 "st X+,__tmp_reg__\n"
293 "ldd __tmp_reg__,Z+6\n"
294 "st X+,__tmp_reg__\n"
295 "ldd __tmp_reg__,Z+7\n"
296 "st X+,__tmp_reg__\n"
298 "sbc r31,__zero_reg__\n"
361 "ld __tmp_reg__,-X\n"
362 "eor __tmp_reg__,r15\n"
377 "mov r8,__tmp_reg__\n"
422 "adc r31,__zero_reg__\n"
432 "sbc r31,__zero_reg__\n"
490 "adc r31,__zero_reg__\n"
500 "sbc r31,__zero_reg__\n"
537 : :
"x"(this->l),
"z"(l),
"r"(input),
"Q"(output),
"Q"(li_out),
"Q"(r),
"Q"(li_in)
538 :
"r8",
"r9",
"r10",
"r11",
"r12",
"r13",
"r14",
"r15",
539 "r16",
"r17",
"r18",
"r19",
"r20",
"r21",
"r22",
"r23",
"memory"
546 uint8_t li_in = (rounds + 3) & 0x03;
547 uint8_t li_out = ((rounds - 31) + li_in) & 0x03;
550 for (round = li_in; round != li_out; round = (round + 1) & 0x03)
551 l[round] = this->l[round];
556 unpack64(y, input + 8);
560 for (uint8_t round = rounds - 1; round > 0; --round) {
562 y = rightRotate3_64(x ^ y);
563 x = leftRotate8_64((x ^ s) - y);
566 li_in = (li_in + 3) & 0x03;
567 li_out = (li_out + 3) & 0x03;
568 s = rightRotate3_64(s ^ l[li_out]);
569 l[li_in] = leftRotate8_64((l[li_out] ^ (round - 1)) - s);
573 y = rightRotate3_64(x ^ y);
574 x = leftRotate8_64((x ^ s) - y);
578 pack64(output + 8, y);
SpeckSmall()
Constructs a small-memory Speck block cipher with no initial key.
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
void clear()
Clears all security-sensitive state from this block cipher.
void decryptBlock(uint8_t *output, const uint8_t *input)
Decrypts a single block using this cipher.
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
void clear()
Clears all security-sensitive state from this block cipher.