## Light Message Authentication Code (LightMAC)

### Introduction

A Message Authentication Code (MAC) enables two parties using a shared secret key to authenticate messages exchanged between them. Some MACs are constructed from cryptographic hash algorithms like SHA-3 or BLAKE2 while others are constructed from block ciphers. LightMAC is a MAC mode for block ciphers. It was designed by Atul Luykx, Bart Preneel, Elmar Tischhauser, Kan Yasuda and published in 2016. LightMAC is incredibly simple to implement, but does not compromise on security or performance. It is ideal for resource constrained environments and also where high performance is required.

$\begin{array}{l} \\\hline \textbf{Algorithm 1: }\text{LightMAC} _{K_1,K_2}(M) \\\hline \quad\textbf{Input: } K_1, K_2\in \{0, 1\}^k,\: M\in \{0,1\}^{\leq 2^s(n-s)}\\ \quad\textbf{Output: } T\in\{0, 1\}^t\\ \textbf{\scriptsize{1}}\;\; V\leftarrow 0^n\in\{0, 1\}^n\\ \textbf{\scriptsize{2}}\;\; M[1]M[2]\cdots M[\ell]\xleftarrow{n-s}M\\ \textbf{\scriptsize{3}}\;\; \textbf{for } i = 1\textbf{ to } \ell - 1\textbf{ do}\\ \textbf{\scriptsize{4}}\;\; \mid V\leftarrow V\oplus E_{K_1}(i_s M[i])\\ \textbf{\scriptsize{5}}\;\; \textbf{end}\\ \textbf{\scriptsize{6}}\;\; V\leftarrow V\oplus (M[\ell]10^\ast)\\ \textbf{\scriptsize{7}}\;\; T\leftarrow \lfloor E_{K_2}(V)\rfloor_t\\ \textbf{\scriptsize{8}}\;\; \textbf{return } T \\\hline \end{array}$

The following list describes some of the symbols used above.

• Cipher
• $E$ should be a cipher with a block size of at least 64-bits.

• Block length.
• $n$ denotes the block length in bytes. PRESENT supports 64-bits, AES supports 128-bits.

• Key length.
• $K_1, K_2$ denote two 128-bit keys if using PRESENT-128 or AES-128.

• Protected counter sum.
• $s$ denotes a counter between 8 and 64-bits in size, but should not exceed $n/2$.

• Message
• $M$ denotes a message with a length not exceeding $2^{s}(n-s)$

• Tag
• $T$ denotes a tag of at least 64-bits and not exceeding $n$.

• Variable
• $V$ is an intermediate/local variable initialized to zero and used to temporarily store the tag of $n$ bytes.

If we use the block cipher PRESENT-64/128 as an example, $K_1, K_2$ would be two 128-bit keys. If $s$ is a 1 byte counter and $n$ is 8-byte block size, our message should not exceed $2^{8}(8-1)$ or 1,792 bytes. This would be sufficient for authenticating small network packets. It also allows us to use the same encryption algorithm that might be used in Counter (CTR) mode, thus significantly reducing the overall amount of ROM required. The following table shows some example parameters, including PRESENT-64/128.

Cipher (E) Block Length (N) Cipher Key Length MAC Key Length (K) Counter Length (S) Tag Length (T) Max Message
PRESENT 64-bits 128-bits 256-bits 8-bits 64-bits 1,792 bytes
SPECK 64-bits 128-bits 256-bits 8-bits 64-bits 1,792 bytes
AES 128-bits 128-bits 256-bits 32-bits 128-bits 48 GB

### Compact code

The value of MSG_LEN is $(n - s)$.

void lightmac(void *data, u32 len, void *tag, void *key) {
int  i;
u8   m[BLK_LEN], v[TAG_LEN];
u8   *t=(u8*)tag, *k=(u8*)key, *p=(u8*)data;

union {
u8  b[8];
u64 q;
} s;

// 1. zero initialize V
for(i=0;i<TAG_LEN;i++) v[i] = 0;

// 2. set protected counter sum to 1
s.q = 1;

// 3. while we have blocks of data equal to (n - s)
while (len >= MSG_LEN) {
// 4. add counter s to M in big endian byte order
for(i=0;i<CTR_LEN;i++) {
m[CTR_LEN-i-1] = s.b[i];
}
// 5. add data to M
for(i=0;i<MSG_LEN;i++) {
m[CTR_LEN+i] = p[i];
}
// 6. encrypt M with K1
ENC(k, m);
// 7. update V
for(i=0;i<TAG_LEN;i++) v[i] ^= m[i];
// 8. decrease length and advance data pointer
len -= MSG_LEN;
p += MSG_LEN;
// 9. update counter
s.q++;
}
// 10. absorb any data less than (n - s)
for(i=0;i<len;i++) v[i] ^= p[i];