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
160 uint32_t xlow, xhigh, ylow, yhigh;
161 uint32_t slow, shigh;
163 uint8_t li_out = (rounds - 31) * 8;
166 __asm__ __volatile__ (
169 "ld __tmp_reg__,Z+\n"
170 "std %A0,__tmp_reg__\n"
171 "ld __tmp_reg__,Z+\n"
172 "std %B0,__tmp_reg__\n"
173 "ld __tmp_reg__,Z+\n"
174 "std %C0,__tmp_reg__\n"
175 "ld __tmp_reg__,Z+\n"
176 "std %D0,__tmp_reg__\n"
177 "ld __tmp_reg__,Z+\n"
178 "std %A1,__tmp_reg__\n"
179 "ld __tmp_reg__,Z+\n"
180 "std %B1,__tmp_reg__\n"
181 "ld __tmp_reg__,Z+\n"
182 "std %C1,__tmp_reg__\n"
183 "ld __tmp_reg__,Z+\n"
184 "std %D1,__tmp_reg__\n"
187 "ld __tmp_reg__,Z+\n"
188 "st X+,__tmp_reg__\n"
191 :
"=Q"(slow),
"=Q"(shigh)
192 :
"z"(k),
"x"(l),
"Q"(li_out)
198 __asm__ __volatile__ (
215 :
"=r"(xlow),
"=r"(xhigh),
"=r"(ylow),
"=r"(yhigh)
220 __asm__ __volatile__ (
221 "mov r23,__zero_reg__\n"
227 "mov __tmp_reg__,%A0\n"
235 "mov %D1,__tmp_reg__\n"
246 "ldd __tmp_reg__,%A4\n"
247 "eor %A0,__tmp_reg__\n"
248 "ldd __tmp_reg__,%B4\n"
249 "eor %B0,__tmp_reg__\n"
250 "ldd __tmp_reg__,%C4\n"
251 "eor %C0,__tmp_reg__\n"
252 "ldd __tmp_reg__,%D4\n"
253 "eor %D0,__tmp_reg__\n"
254 "ldd __tmp_reg__,%A5\n"
255 "eor %A1,__tmp_reg__\n"
256 "ldd __tmp_reg__,%B5\n"
257 "eor %B1,__tmp_reg__\n"
258 "ldd __tmp_reg__,%C5\n"
259 "eor %C1,__tmp_reg__\n"
260 "ldd __tmp_reg__,%D5\n"
261 "eor %D1,__tmp_reg__\n"
272 "adc %A2,__zero_reg__\n"
283 "adc %A2,__zero_reg__\n"
292 "adc %A2,__zero_reg__\n"
305 "mov __tmp_reg__,r23\n"
307 "cp __tmp_reg__,%9\n"
335 "adc %B8,__zero_reg__\n"
370 "sbc %B8,__zero_reg__\n"
375 "adc %B8,__zero_reg__\n"
388 "sbc %B8,__zero_reg__\n"
401 "adc %A2,__zero_reg__\n"
411 "adc %A2,__zero_reg__\n"
421 "adc %A2,__zero_reg__\n"
464 :
"+r"(xlow),
"+r"(xhigh),
"+r"(ylow),
"+r"(yhigh),
465 "+Q"(slow),
"+Q"(shigh),
"+Q"(li_in),
"+Q"(li_out)
466 :
"z"(l),
"r"(rounds)
467 :
"r23",
"r24",
"r25"
471 __asm__ __volatile__ (
488 : :
"r"(xlow),
"r"(xhigh),
"r"(ylow),
"r"(yhigh),
"z"(output)
495 uint8_t li_out = rounds - 31;
500 unpack64(y, input + 8);
503 memcpy(l, k + 1, li_out *
sizeof(uint64_t));
507 for (round = rounds - 1; round > 0; --round, ++i) {
509 x = (rightRotate8_64(x) + y) ^ s;
510 y = leftRotate3_64(y) ^ x;
513 l[li_out] = (s + rightRotate8_64(l[li_in])) ^ i;
514 s = leftRotate3_64(s) ^ l[li_out];
515 li_in = (li_in + 1) & 0x03;
516 li_out = (li_out + 1) & 0x03;
520 x = (rightRotate8_64(x) + y) ^ s;
521 y = leftRotate3_64(y) ^ x;
523 pack64(output + 8, y);
SpeckTiny()
Constructs a tiny-memory Speck block cipher with no initial key.
size_t blockSize() const
Size of a single block processed by this cipher, in bytes.
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
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.
void decryptBlock(uint8_t *output, const uint8_t *input)
Decrypts a single block using this cipher.
void clear()
Clears all security-sensitive state from this block cipher.