Red PikeRed Pike - a name which is likely to derive from an area of English Lake District - is a classified UK government encryption algorithm. It was created for the NHS by CESG, but can be used in a range of applications. It is a 64-bit block cipher with a 64-bit key length. It was quoted in a paper by Ross Anderson and Markus Kuhn, and uses operations that are used in RC5. There are no s-boxes, key scheduling or look-up tables and is implemented in a few lines of code. |
Outline
So what happens if we want to make our block cipher simpler, and just implement it in just a few lines of code? This might be the case for a limited memory IoT device. One such cipher is Red Pike, and was proposed as a standard for the NHS in 1996:
the NHS’s needs should be addressed by a family of related encryption products built on the Red Pike encryption algorithm. This algorithm has recently been made available to the NHS by CESG, the National Technical Security Authority within HMG
Red Pike — a name which is likely to derive from an area of English Lake District — is a classified UK government encryption algorithm. It was created for the NHS by GCHQ, but could be used in a range of applications. Overall it is a 64-bit block cipher with a 64-bit key length. Over the last two decades, there are few referenced articles to it, but it quoted in a paper by Ross Anderson and Markus Kuhn [here]. Overall it uses simple bitwise operations, and has no S-boxes, no key scheduling, no look-up tables, and is implemented in a few lines of code.
Ross creates an interesting narrative in how the BMA was persuaded that Red Pike a study involving four academics:
In order to try and persuade the BMA that Red Pike was sound, the government commissioned a study of it by four academics [7]. This study states that Red Pike `uses the same basic operations as RC5' (p 4) in that the principal operations are add, exclusive or, and left shift. It `has no look-up tables, virtually no key schedule and requires only five lines of code' (p 4). Other hints include that `the influence of each key bit quickly cascades' (p 10) and each encryption involves of the order of 100 operations' (p 19).
Ross didn’t hold back in his criticism and in its RC5-derived roots, “RC5 may be about the worst possible algorithm choice for secret-algorithm hardware applications”, and that it was susceptible to the glitch attack.
In the end, Ross outlined that he had serious doubts about the methods, and that S-boxes should be used. So, in an era of standards in cryptography, where “rolling your own” is not seen as a good things, it is rather strange to see a method which was kept fairly secret.
A 64-bit key, unfortunately, is too small these days, and could be cracked by modern machines, but, at the time (1996), the key size would have been fairly secure. It must be remembered that in 1996, the Intel Pentium was King of the processors and a blistering clock speed of 200MHz. With processor clock speeds now of nearly 4GHz, and with GPUs contained thousands of processing elements, modern computing devices would find cracking a 64 bit key a fairly easy task.
Red Pike uses a key size of 64-bits and a buffer size of 64-bits:
/* Red Pike cipher source code */ #include <stdint.h> #include <string.h> #include <stdlib.h> #include <stdio.h> typedef uint32_t word; #define CONST 0x9E3779B9 #define ROUNDS 16 #define ROTL(X, R) (((X) << ((R) & 31)) | ((X) >> (32 - ((R) & 31)))) #define ROTR(X, R) (((X) >> ((R) & 31)) | ((X) << (32 - ((R) & 31)))) void encrypt(word * x, const word * k) { unsigned int i; word rk0 = k[0]; word rk1 = k[1]; for (i = 0; i < ROUNDS; i++) { rk0 += CONST; rk1 -= CONST; x[0] ^= rk0; x[0] += x[1]; x[0] = ROTL(x[0], x[1]); x[1] = ROTR(x[1], x[0]); x[1] -= x[0]; x[1] ^= rk1; } rk0 = x[0]; x[0] = x[1]; x[1] = rk0; } void decrypt(word * x, const word * k) { word dk[2] = { k[1] - CONST * (ROUNDS + 1), k[0] + CONST * (ROUNDS + 1) }; encrypt(x, dk); } main ( int argc, char *argv[] ) { char *key; char *buffer; char dec[100]=""; char ch[5]=""; if (argc==3) { buffer=argv[1]; key=argv[2]; } word b[2]={6,6}; word k[2]={6,6}; printf ("\nEncrypt: "); for (int i=0;i<strlen(buffer);i+=4) { b[0]=(int)buffer[i]+(int)(buffer[i+1]<<8); b[1]=(int)buffer[i+2]+(int)(buffer[i+3]<<8); k[0]=(int)key[0]+ (int)key[1]<<8; k[1]=(int)key[2]+ (int)key[3]<<8; encrypt(b,key); printf ("%x%x",b[0],b[1]); decrypt(b,key); ch[0]=b[0]& 0xff; ch[1]=(b[0]& 0xff00)>>8; ch[2]=b[1]& 0xff; ch[3]=(b[1]& 0xff00)>>8; ch[4]=0; strcat(dec,ch); } printf ("\nDecrypt: %s",dec); }
A sample run is:
PIKE Encryption Message: abcde Key: aaaa Encrypt: d3d6e4c6dae19022ea46529fe5210331 Decrypt: abcde