Skip to content

Instantly share code, notes, and snippets.

@dchest
Created September 24, 2012 18:36
Show Gist options
  • Select an option

  • Save dchest/3777526 to your computer and use it in GitHub Desktop.

Select an option

Save dchest/3777526 to your computer and use it in GitHub Desktop.
FourDolphins!
#include <stdint.h>
#include <stdio.h>
/* Permutations of {0, ..., 15} */
static const uint8_t SIGMA[14][16] = {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }
};
/* Constants */
static const uint32_t CST[16] = {
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917
};
#define NROUNDS 14
#define ROTR(x, n) (((x)<<(32-n)) | ((x)>>(n)))
#define ROTL(x, n) (((x)>>(32-n)) | ((x)<<(n)))
void
FourDolphins_Encrypt(uint32_t k[16], uint32_t src[16], uint32_t dst[16])
{
uint32_t v[16];
int i;
for (i = 0; i < 16; i++)
v[i] = src[i];
#define GE(a, b, c, d, e) do { \
v[a] += (k[SIGMA[i][e]] ^ CST[SIGMA[i][e+1]]) + v[b]; \
v[d] = ROTR(v[d] ^ v[a], 16); \
v[c] += v[d]; \
v[b] = ROTR(v[b] ^ v[c], 12); \
v[a] += (k[SIGMA[i][e+1]] ^ CST[SIGMA[i][e]]) + v[b]; \
v[d] = ROTR(v[d] ^ v[a], 8); \
v[c] += v[d]; \
v[b] = ROTR(v[b] ^ v[c], 7); \
} while (0)
for (i = 0; i < NROUNDS; i++) {
GE(0, 4, 8, 12, 0);
GE(1, 5, 9, 13, 2);
GE(2, 6, 10, 14, 4);
GE(3, 7, 11, 15, 6);
GE(3, 4, 9, 14, 14);
GE(2, 7, 8, 13, 12);
GE(0, 5, 10, 15, 8);
GE(1, 6, 11, 12, 10);
}
#undef GE
for (i = 0; i < 16; i++)
dst[i] = v[i];
}
void
FourDolphins_Decrypt(uint32_t k[16], uint32_t src[16], uint32_t dst[16])
{
uint32_t v[16];
int i;
for (i = 0; i < 16; i++)
v[i] = src[i];
#define GD(a, b, c, d, e) do { \
v[b] = ROTL(v[b], 7) ^ v[c]; \
v[c] -= v[d]; \
v[d] = ROTL(v[d], 8) ^ v[a]; \
v[a] -= (k[SIGMA[i][e+1]] ^ CST[SIGMA[i][e]]) + v[b]; \
v[b] = ROTL(v[b], 12) ^ v[c]; \
v[c] -= v[d]; \
v[d] = ROTL(v[d], 16) ^ v[a]; \
v[a] -= (k[SIGMA[i][e]] ^ CST[SIGMA[i][e+1]]) + v[b]; \
} while (0)
for (i = NROUNDS-1; i >= 0; i--) {
GD(1, 6, 11, 12, 10);
GD(0, 5, 10, 15, 8);
GD(2, 7, 8, 13, 12);
GD(3, 4, 9, 14, 14);
GD(3, 7, 11, 15, 6);
GD(2, 6, 10, 14, 4);
GD(1, 5, 9, 13, 2);
GD(0, 4, 8, 12, 0);
}
#undef GD
for (i = 0; i < 16; i++)
dst[i] = v[i];
}
void
print16(uint32_t *v)
{
int i;
for (i = 0; i < 16; i++)
printf("%u ", v[i]);
printf("\n");
}
int
main(void)
{
uint32_t k[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
uint32_t src[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
uint32_t dst[16] = {0};
printf("original:\n");
print16(src);
FourDolphins_Encrypt(k, src, dst);
printf("\nencrypted:\n");
print16(dst);
FourDolphins_Decrypt(k, dst, dst);
printf("\ndecrypted:\n");
print16(dst);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment