KLEIN — The Light-weight crypto method that hides its operation

The AES block cipher method is well used in operations, but it gives away its secrets within side channel attacks. With this an intruder…

Photo by Markus Spiske on Unsplash

KLEIN — The Light-weight crypto method that hides its operation

The AES block cipher method is well used in operations, but it gives away its secrets within side-channel attacks. With this, an intruder can listen to the electrical noise, or the radio emissions and derive the AES key. So something that should take trillions and trillions of years to find a key, can be computed in less than 30 minutes. Here is Dr Owen Lo cracking an AES key live:

Another problem with AES, is that it requires a fair amount of memory, battery consumption and CPU utilization, so is not fit for limited processor devices (such as sensors). For this, we turn to lightweight cryptography method. In this, we move from a 128-bit (16 bytes) block size, to a smaller one, such as for a 64-bit (8 bytes).

KLEIN is used to create block-cipher-based hash functions and message authentication codes (MACs), and is well-suited to resource-constrained devices [paper]:

It uses a fixed 64-bit block and has a 64, 80 or 96-bit encryption key (KLEIN64, KLEIN80 and KLEIN96). Within each round, it uses a SubNibbles round, and which has 16 identical s-boxes (substitution boxes), and where each of the bytes in a round is fed into these in parallel. Each of the S-boxes are the same and help protect against side channels, as each of the bytes will go through an identical box.

We start with a KEY and the PLAINTEXT. The method is then:

sk[1] <- KEY;
STATE <- PLAINTEXT;
for i = 1 to NR do
AddRoundKey(STATE; sk[i]);
SubNibbles(STATE);
RotateNibbles(STATE);
MixNibbles(STATE);
sk[i+1] = KeySchedule(sk[i]; i);
end for
CIPHERTEXT <- AddRoundKey(STATE; sk[NR+1]);

Each state has 16 bytes (the size of the block). The number of rounds is variable, but it is typically 12 rounds for KLEIN64 (64-bit encryption key), 16 rounds for KLEIN80 (80-bit encryption key) and 20 rounds for KLEIN96 (96-bit encryption key):

klein64 = klein.KLEIN(nr=12, size=64)
klein80 = klein.KLEIN(nr=16, size=80)
klein96 = klein.KLEIN(nr=20, size=96)

The AddRoundKey() method splits the key into 16 bytes chunks for each round, and the RotateNibble() does a bit rotate on the current state:

def rotateNibbles(self, state):
 return (state << 16) & 0xFFFFFFFFFFFFFFFF | (state >> 48)

And the MixNibbles() does a scrambling function on the state.

For limited devices, we could thus use a 64-bit encryption key, and which has 12 rounds, but for increased security we can move up to the 96-bit version.

The 4-bit S-box is:

Input  0 1 2 3 4 5 6 7 8 9 A B C D E F
Output 7 4 A 9 1 F B 0 C 3 2 6 8 E D 5

When decrypting, we can just reverse all of the functions in the rounds. Here is the code:

Here is my demo:

https://asecuritysite.com/light/klein