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.