Multos Forums

   

Speck block cipher

RankRankRank

Total Posts: 74

Joined 2012-02-21

PM

In the world of IoT, devices using ultra low bandwidth communications methods may struggle to use conventional ciphers because of the block size for the cipher being bigger than the maximum allowed message. Thankfully there is a solution in the form on Speck, a lightweight block cipher with a range of block sizes and key lengths.

Here is an implementation you can try in MULTOS for the 8 byte block, 16 byte key variant. The 8 bytes of plaintext data are represented in two DWORDs, pl and pr. The ciphertext likewise as cl and cr. The original key is an array of four DWORDs. The key schedule k is an array of 34 DWORDs.

// Implementation of Speck 64/128
// C++ implementation at https://github.com/GSongHashrate/SimonSpeck/blob/927c51db1b48d6c9c50990a3367d894293366037/Speck.cpp

// Block size = 64 bits
// Word length = 32 bits
#define WORD_LEN 32
// Number of rounds = 27
#define NUM_ROUNDS 27
// Key length = 128 bits
#define NUM_KEY_WORDS 4

// For encryption
#define ROR8(x)  ((x >> 8) | (x << (WORD_LEN-8)))
#define ROL3(x)  ((x << 3) | (x >> (WORD_LEN-3)))

// For decryption
#define ROR3(x)  (((x) >> 3) | ((x) << (WORD_LEN-3)))
#define ROL8(x)  (((x) << 8) | ((x) >> (WORD_LEN-8)))

// Generate key schedule k from key. This is used backwards for decryption.
void getSpeckKeySchedule(DWORD *keyDWORD *k)
{
 DWORD i
;
 
DWORD l[34] {0};

 
k[0] key[0];

 for(
i=0;i<NUM_KEY_WORDS-1;i++)
  
l[i] key[i+1];

 for(
i=0;i<=NUM_ROUNDS-2;i++)
 
{
  l[i
+NUM_KEY_WORDS-1] = (k[i] ROR8(l[i])) ^ i;
  
k[i+1] ROL3(k[i]) ^ l[i+NUM_KEY_WORDS-1];
 
}
}


void speckEncrypt
(DWORD plDWORD prDWORD *clDWORD *crDWORD *k)
{
 DWORD i
;

 for(
0NUM_ROUNDSi++)
 
{
  pl 
= (ROR8(pl) + pr) ^ k[i];
  
pr ROL3(pr) ^ pl;
 
}

 
*cl pl;
 *
cr pr;
}

void speckDecrypt
(DWORD clDWORD crDWORD *plDWORD *prDWORD *k)
{
 DWORD i
;

 for(
1<= NUM_ROUNDSi++)
 
{
  cr 
ROR3(cl^cr);
  
cl ROL8((cl k[NUM_ROUNDS i]) - cr);
 
}
 
*pl cl;
 *
pr cr;