## CHAM Block Cipher

### Introduction

CHAM: A Family of Lightweight Block Ciphers for Resource-Constrained Devices was published in December 2017 at the 20th Annual International Conference on Information Security and Cryptology held in South Korea.

CHAM consists of three ciphers, CHAM-64/128, CHAM-128/128, and CHAM-128/256 which are based on the Generalized Feistel Network (GFN) structure.

This post will focus on CHAM-128/128 which is the 128-bit block cipher with 128-bit key variant operating on 4 branches of 32 bits each. The only operations used are 32-bit modular addition, Rotation and XOR (ARX)

The design of CHAM draws inspiration from Speck and Simon block ciphers by the NSA. A cursory glance of the algorithm would suggest CHAM is not ideal for hardware due to its use of modular addition which is inefficient to implement on hardware.

Take this quote from the designers of the permutation function Keccak:

..the designer of an adder must choose between complexity (area, consumption) or gate delay (latency): It is either compact or fast, but not at the same time

Here are parameters for all 3 variants. N is the block length, K is the key length, R is the number of rounds, W is the width of a word and K/W is the number of words per key.

### Key schedule

For the 128-bit version, there are 8 round keys of 32-bits each, or 32-bytes in total.

```void cham128_setkey(void *in, void *out)
{
int i;
uint32_t *k=(uint32_t*)in;
uint32_t *rk=(uint32_t*)out;

for (i=0; i<KW; i++) {
rk[i] = k[i] ^ ROTL32(k[i], 1) ^ ROTL32(k[i], 8);
rk[(i + KW) ^ 1]	= k[i] ^ ROTL32(k[i], 1) ^ ROTL32(k[i], 11);
}
}
```

The assembly may not be completely optimized here, but it’s best I can do at the moment.

```%define K 128   ; key length
%define N 128   ; block length
%define R 80    ; number of rounds
%define W 32    ; word length
%define KW K/W  ; number of words per key

cham128_setkeyx:
_cham128_setkeyx:
mov    esi, [esp+32+4]  ; k  = in
mov    edi, [esp+32+8]  ; rk = out
xor    eax, eax         ; i  = 0
sk_l0:
mov    ebx, [esi+eax*4] ; ebx = k[i]
mov    ecx, ebx         ; ecx = k[i]
mov    edx, ebx         ; edx = k[i]
rol    ebx, 1           ; ROTL32(k[i], 1)
rol    ecx, 8           ; ROTL32(k[i], 8)
xor    edx, ebx         ; k[i] ^ ROTL32(k[i], 1)
xor    edx, ecx
mov    [edi+eax*4], edx ; rk[i] = edx
xor    edx, ecx         ; reset edx
rol    ecx, 3           ; k[i] ^ ROTL32(k[i], 11)
xor    edx, ecx
lea    ebx, [eax+KW]
xor    ebx, 1
mov    [edi+ebx*4], edx ; rk[(i + KW) ^ 1] = edx
inc    al
cmp    al, KW
jnz    sk_l0
ret
```

### Encryption

There are 80 rounds in total, which is significantly more than the 32 used for Speck.

```void cham128_encrypt(void *keys, void *data)
{
int i;
uint32_t x0, x1, x2, x3;
uint32_t t;
uint32_t *rk=(uint32_t*)keys;
uint32_t *x=(uint32_t*)data;

x0 = x[0]; x1 = x[1];
x2 = x[2]; x3 = x[3];

for (i=0; i<R; i++)
{
if ((i & 1) == 0) {
x0 = ROTL32((x0 ^ i) + (ROTL32(x1, 1) ^ rk[i & 7]), 8);
} else {
x0 = ROTL32((x0 ^ i) + (ROTL32(x1, 8) ^ rk[i & 7]), 1);
}
XCHG(x0, x1);
XCHG(x1, x2);
XCHG(x2, x3);
}
x[0] = x0; x[1] = x1;
x[2] = x2; x[3] = x3;
}
```

Only the encryption here, since if you were to implement with CTR mode, decryption isn’t necessary.

```%define x0 ebp
%define x1 ebx
%define x2 edx
%define x3 esi
%define rk edi

cham128_encryptx:
_cham128_encryptx:
mov    esi, [esp+32+8] ; x = data
push   esi
lodsd
xchg   eax, x0
lodsd
xchg   eax, x1
lodsd
xchg   eax, x2
lodsd
xchg   eax, x3
xor    eax, eax ; i = 0
; initialize sub keys
enc_l0:
mov    edi, [esp+32+8] ; k = keys
jmp    enc_lx
enc_l1:
test   al, 7    ; i & 7
jz     enc_l0
enc_lx:
push   eax      ; save i
mov    cx, 0x0108
test   al, 1    ; if ((i & 1)==0)
jnz    enc_l2

xchg   cl, ch
enc_l2:
xor    x0, eax          ; x0 ^= i
mov    eax, x1
rol    eax, cl          ;
xor    eax, [edi]       ; ROTL32(x1, r0) ^ *rk++
scasd
xchg   cl, ch
rol    x0, cl

xchg   x0, x1          ; XCHG(x0, x1);
xchg   x1, x2          ; XCHG(x1, x2);
xchg   x2, x3          ; XCHG(x2, x3);

pop    eax      ; restore i
inc    al       ; i++
cmp    al, R    ; i<R
jnz    enc_l1

pop    edi
xchg   eax, x0
stosd           ; x[0] = x0;
xchg   eax, x1
stosd           ; x[1] = x1;
xchg   eax, x2
stosd           ; x[2] = x2;
xchg   eax, x3
stosd           ; x[3] = x3;
ret
```

The total size of assembly at moment is 128 bytes, although I will try optimize more later.

### Summary

CHAM is a relatively new block cipher clearly influenced by block ciphers Speck and Simon. Although the strong variants of Speck and Simon remain unbroken, that hasn’t prevented some in the cryptographic community being cynical about the intentions of the NSA.

Orr Dunkelman, a computer science professor at the University of Haifa commented. “I don’t trust the designers” and “There are quite a lot of people in NSA who think their job is to subvert standards. My job is to secure standards.”

Daniel Bernstein also commented: NSA says:We need a “generalist” cipher that works well everywhere, so here are 20 incompatible Simon+Speck variants https://eprint.iacr.org/2015/585

As most of the attacks appear ad-hominem, is it fair to dismiss Speck and Simon even when the rationale behind the designs have been published?

When asked if it could beat Simon and Speck encryption, NSA officials are reported to have said: “We firmly believe they are secure.” which neither confirms nor denies NSA can break these type of ciphers.

Then again, if the NSA are capable of breaking Speck and Simon, they may also know how to break other ARX designs like ChaCha, LEA and CHAM?

A final vote on whether Speck/Simon are accepted as part of an ISO standard takes place in February 2018.