RedPike is a classified UK government block cipher with a 64-bit block size and 64-bit key length, designed by GCHQ for confidential communications. It uses basic operations (add, XOR, left shift) with no lookup tables and minimal code. This C# implementation faithfully recreates the cipher with 16 rounds.
This code is derived from a supposed reference implementation originally posted in the now defunct cypherpunk mailing list available here.
using System.Diagnostics.CodeAnalysis;
// ReSharper disable InconsistentNaming
namespace RedPike;
/// <summary>
/// RedPike cipher implementation.
/// </summary>
public static class Cipher
{
private const uint CONST = 0x9E3779B9;
private const int ROUNDS = 16;
private static uint ROTL(uint X, uint R)
{
uint r = R & 31;
return (X << (int)r) | (X >> (int)(32 - r));
}
private static uint ROTR(uint X, uint R)
{
uint r = R & 31;
return (X >> (int)r) | (X << (int)(32 - r));
}
public static void Encrypt(uint[] x, uint[] k)
{
uint rk0 = k[0];
uint rk1 = k[1];
for (int 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;
}
// swap via deconstruction
(x[0], x[1]) = (x[1], x[0]);
}
[SuppressMessage("ReSharper", "RedundantCast")]
public static void Decrypt(uint[] x, uint[] k)
{
uint[] dk = new uint[2];
dk[0] = k[1] - unchecked(CONST * (uint)(ROUNDS + 1));
dk[1] = k[0] + unchecked(CONST * (uint)(ROUNDS + 1));
Encrypt(x, dk);
}
}
- Namespace:
RedPike
- Class:
Cipher
(static) - Methods:
Encrypt(uint[] x, uint[] k)
: Encrypts a 64-bit blockx
(twouint
s) with a 64-bit keyk
(twouint
s).Decrypt(uint[] x, uint[] k)
: Decrypts the block using the same key.
uint[] data = { 0x12345678, 0x9ABCDEF0 };
uint[] key = { 0xFEDCBA98, 0x76543210 };
Cipher.Encrypt(data, key); // Encrypts data in place
Cipher.Decrypt(data, key); // Decrypts back to original