what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

dfc0.c

dfc0.c
Posted Dec 21, 1999

dfc0.c

tags | encryption
SHA-256 | cf08a9a161d8bc43583a1860fba2cd713ef85d8376fe9bfbf31186c1a5953df3

dfc0.c

Change Mirror Download

/* This is an independent implementation of the DFC encryption */
/* algorithm designed by a team at CNRS and France Telecom and */
/* submitted as a candidate in the US NIST Advanced Encryption */
/* Standard (AES) programme. */
/* */
/* Copyright in this implementation is held by Dr B R Gladman but */
/* I hereby give permission for its free direct or derivative use */
/* subject to acknowledgment of its origin and compliance with any */
/* constraints that the designers of DFC place on the use of this */
/* algorithm. */
/* */
/* This implementation is intended as a reference implementation */
/* and has not been optimised for speed (however, a small assembler */
/* coded section is used to improve the speed of multiple length */
/* multiplication and addition). */
/* */
/* My thanks go to Serge Vaudenay of the Ecole Normale Superieure */
/* for providing test vectors. This implementation has also been */
/* tested with an independent implementation by Dr Russell Bradford */
/* (Department of Mathematical Sciences, University of Bath, Bath, */
/* UK) and checks out. My thanks go to Russell for his help in */
/* comparing our implementations and finding bugs (and for help in */
/* resolving 'endian' issues before test vectors became available). */
/* */
/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 27th July 1998 */
/* */

/* The EES string is as follows (the abstract contains an error in
the last line of this sequence which changes KC and KD):

0xb7e15162, 0x8aed2a6a, 0xbf715880, 0x9cf4f3c7,
0x62e7160f, 0x38b4da56, 0xa784d904, 0x5190cfef,
0x324e7738, 0x926cfbe5, 0xf4bf8d8d, 0x8c31d763,
0xda06c80a, 0xbb1185eb, 0x4f7c7b57, 0x57f59584,

0x90cfd47d, 0x7c19bb42, 0x158d9554, 0xf7b46bce,
0xd55c4d79, 0xfd5f24d6, 0x613c31c3, 0x839a2ddf,
0x8a9a276b, 0xcfbfa1c8, 0x77c56284, 0xdab79cd4,
0xc2b3293d, 0x20e9e5ea, 0xf02ac60a, 0xcc93ed87,

0x4422a52e, 0xcb238fee, 0xe5ab6add, 0x835fd1a0,
0x753d0a8f, 0x78e537d2, 0xb95bb79d, 0x8dcaec64,
0x2c1e9f23, 0xb829b5c2, 0x780bf387, 0x37df8bb3,
0x00d01334, 0xa0d0bd86, 0x45cbfa73, 0xa6160ffe,

0x393c48cb, 0xbbca060f, 0x0ff8ec6d, 0x31beb5cc,
0xeed7f2f0, 0xbb088017, 0x163bc60d, 0xf45a0ecb,
0x1bcd289b, 0x06cbbfea, 0x21ad08e1, 0x847f3f73,
0x78d56ced, 0x94640d6e, 0xf0d3d37b, 0xe67008e1,

0x86d1bf27, 0x5b9b241d, 0xeb64749a, 0x47dfdfb9,

Where:

EES = RT(0) | RT(1) | ... | RT(63) | KD | KC

Note that the abstract describing DFC is written
in big endian notation with the most significant
digits of a sequence of digits placed at the low
index positions in arrays. This format is used
here and is only converted to machine format at
the point that maths is done on any numbers in
the round function.

The key input is thus treated as an array of 32
bit words numbered from 0..3, 0..5 or 0..7
depending on key length. The first (leftmost)
bit of this key string as defined in the DFC
abstract is the most significant bit of word 0
and the rightmost bit of this string is the least
signicant bit of the highest numbered key word.

The input and output blocks for the cipher are
also treated as arrays of 32 bit words numbered
from 0..3. The most significant bit of word 0 is
the 1st (leftmost) bit of the 128 bit input string
and the least significant bit of word 3 is the
last (rightmost) bit.

Here are some key, input and encrypted output
values for reference purposes:
-----------------------------------------------
key :00..03:00000000 00000000 00000000 00000000
inpt:00..03:00000000 00000000 00000000 00000000
oupt:00..03:f12dd230 7064907f 3b61da94 1efb2184
-----------------------------------------------
key :00..03:00000000 00000000 00000000 00000000
key :04..05:00000000 00000000
inpt:00..03:00000000 00000000 00000000 00000000
oupt:00..03:7af7efb2 1aa1c246 fa6a4d6b c24fe909
-----------------------------------------------
key :00..03:00000000 00000000 00000000 00000000
key :04..07:00000000 00000000 00000000 00000000
inpt:00..03:00000000 00000000 00000000 00000000
oupt:00..03:0205d713 3ed37cee 091c36f2 4a74592a
-----------------------------------------------
key :00..03:00000000 00000000 00000000 00000000
inpt:00..03:00010203 04050607 08090a0b 0c0d0e0f
oupt:00..03:63042070 9e777ff6 cb1c6523 1362c5e3
-----------------------------------------------
key :00..03:00000000 00000000 00000000 00000000
key :04..05:00000000 00000000
inpt:00..03:00010203 04050607 08090a0b 0c0d0e0f
oupt:00..03:7072a955 ccedbc49 03417213 c051f7ba
-----------------------------------------------
key :00..03:00000000 00000000 00000000 00000000
key :04..07:00000000 00000000 00000000 00000000
inpt:00..03:00010203 04050607 08090a0b 0c0d0e0f
oupt:00..03:10fdbad1 0fa262f6 4147a00f 4306b11c
-----------------------------------------------
key :00..03:00010203 04050607 08090a0b 0c0d0e0f
inpt:00..03:00000000 00000000 00000000 00000000
oupt:00..03:f33e6473 dc94928e c887ed51 950f1b35
-----------------------------------------------
key :00..03:00010203 04050607 08090a0b f4f5f6f7
key :04..05:f8f9fafb fcfdfeff
inpt:00..03:00000000 00000000 00000000 00000000
oupt:00..03:cf0ce273 b1daae5d 1687caa4 003663d4
-----------------------------------------------
key :00..03:00010203 04050607 08090a0b 0c0d0e0f
key :04..07:f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff
inpt:00..03:00000000 00000000 00000000 00000000
oupt:00..03:5ceeeb6b 73b79f6b 5cc20f41 96b1d7b3
-----------------------------------------------
key :00..03:00010203 04050607 08090a0b 0c0d0e0f
inpt:00..03:00010203 04050607 08090a0b 0c0d0e0f
oupt:00..03:dc853213 a1e283ca 3afc6f04 e7c1bf08
-----------------------------------------------
key :00..03:00010203 04050607 08090a0b f4f5f6f7
key :04..05:f8f9fafb fcfdfeff
inpt:00..03:00010203 04050607 08090a0b 0c0d0e0f
oupt:00..03:94ca0910 5c4fd5c6 51297e50 3fdd47db
-----------------------------------------------
key :00..03:00010203 04050607 08090a0b 0c0d0e0f
key :04..07:f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff
inpt:00..03:00010203 04050607 08090a0b 0c0d0e0f
oupt:00..03:1c042426 df34fcec 01eab9a7 5e5c15ec
-----------------------------------------------
key :00..03:01234567 89012345 67890123 45678901
inpt:00..03:00000000 00000000 00000000 00000000
oupt:00..03:bb46bb6a c0093c1d f5675766 16077eef
-----------------------------------------------
key :00..03:01234567 89012345 67890123 45678901
key :04..05:23456789 01234567
inpt:00..03:00000000 00000000 00000000 00000000
oupt:00..03:6a650210 5c23c62a b01e6b32 4dcdf664
-----------------------------------------------
key :00..03:01234567 89012345 67890123 45678901
key :04..07:23456789 01234567 89012345 67890123
inpt:00..03:00000000 00000000 00000000 00000000
oupt:00..03:68bf42dc f20d4ec7 aa081c03 822c6dba
-----------------------------------------------
*/

#include "../std_defs.h"

static char *alg_name = "DFC";

char *cipher_name()
{
return alg_name;
};

/* The following arrays are all stored in big endian */
/* format with 32 bit words at lower array positions */
/* being more significant in multi-word values */

u4byte rt64[64] =
{
0xb7e15162, 0x8aed2a6a, 0xbf715880, 0x9cf4f3c7,
0x62e7160f, 0x38b4da56, 0xa784d904, 0x5190cfef,
0x324e7738, 0x926cfbe5, 0xf4bf8d8d, 0x8c31d763,
0xda06c80a, 0xbb1185eb, 0x4f7c7b57, 0x57f59584,

0x90cfd47d, 0x7c19bb42, 0x158d9554, 0xf7b46bce,
0xd55c4d79, 0xfd5f24d6, 0x613c31c3, 0x839a2ddf,
0x8a9a276b, 0xcfbfa1c8, 0x77c56284, 0xdab79cd4,
0xc2b3293d, 0x20e9e5ea, 0xf02ac60a, 0xcc93ed87,

0x4422a52e, 0xcb238fee, 0xe5ab6add, 0x835fd1a0,
0x753d0a8f, 0x78e537d2, 0xb95bb79d, 0x8dcaec64,
0x2c1e9f23, 0xb829b5c2, 0x780bf387, 0x37df8bb3,
0x00d01334, 0xa0d0bd86, 0x45cbfa73, 0xa6160ffe,

0x393c48cb, 0xbbca060f, 0x0ff8ec6d, 0x31beb5cc,
0xeed7f2f0, 0xbb088017, 0x163bc60d, 0xf45a0ecb,
0x1bcd289b, 0x06cbbfea, 0x21ad08e1, 0x847f3f73,
0x78d56ced, 0x94640d6e, 0xf0d3d37b, 0xe67008e1,
};

u4byte kc = 0xeb64749a;

u4byte kd2[2] =
{
0x86d1bf27, 0x5b9b241d
};

u4byte ka2[6] =
{
0xb7e15162, 0x8aed2a6a,
0xbf715880, 0x9cf4f3c7,
0x62e7160f, 0x38b4da56,
};

u4byte kb2[6] =
{
0xa784d904, 0x5190cfef,
0x324e7738, 0x926cfbe5,
0xf4bf8d8d, 0x8c31d763,
};

u4byte ks8[8] =
{ 0xda06c80a, 0xbb1185eb, 0x4f7c7b57, 0x57f59584,
0x90cfd47d, 0x7c19bb42, 0x158d9554, 0xf7b46bce,
};

u4byte l_key[32];

/* The following maths functions use data in little endian format */

/* multiply two 32 bit words to give a 64 bit result and add it to */
/* the accumulator (acc) propagating any carries produced */

#if(0)

void madd(u4byte acc[2], u4byte x[1], u4byte y[1])
{ u4byte c, s, t;
u2byte r[4];

/* compute upper and lower 32 bit products */

*(u4byte*)r = (u4byte)((u2byte*)x)[0] * ((u2byte*)y)[0];

*(u4byte*)(r + 2) = (u4byte)((u2byte*)x)[1] * ((u2byte*)y)[1];

/* compute and add intermediate products to r */

s = (u4byte)((u2byte*)x)[0] * ((u2byte*)y)[1];

t = (u4byte)((u2byte*)x)[1] * ((u2byte*)y)[0];

s += t; c = (s < t ? 1 : 0);

t = *(u4byte*)(r + 1);

s += t; c += (s < t ? 1 : 0);

*(u4byte*)(r + 1) = s;

*(r + 3) += c;

/* now add it to acc with carry propagation */

acc[0] += *(u4byte*)r; c = (acc[0] < *(u4byte*)r ? 1 : 0);

acc[1] += (t = *(u4byte*)(r + 2)) + c;

c = (acc[1] < t ? 1 : (acc[1] == t ? c : 0));

if(c && !++acc[2])

++acc[3];
};

#else

/* MFC inline assembly code speedup of madd. Note that */
/* while Microsoft C++ has a 64 bit integer type, this */
/* is (stupidly) only available in signed form and is */
/* hence messy to use here */

void madd(u4byte acc[4], u4byte x[1], u4byte y[1])
{ __asm {
__asm mov ecx,x
__asm mov edx,y
__asm mov eax,[ecx]
__asm mov ecx,[edx]
__asm mul ecx
__asm mov ebx,acc
__asm xor ecx,ecx
__asm add [ebx],eax
__asm adc [ebx+4],edx
__asm adc [ebx+8],ecx
__asm adc [ebx+12],ecx
}
};

#endif

/* Where necessary this is where conversion from big endian to */
/* little endian format is performed. Since all the maths is */
/* little endian care is needed when 64 bit blocks are being */
/* used to get them in the right order by reversing the order */
/* in which these are stored. This applies to the key array */
/* which gives the two values A and B and to the constant KD. */
/* Since the input and output blocks are big endian we also */
/* have to invert the order of the 32 bit words in the 64 bit */
/* blocks being processed. */

void r_fun(u4byte outp[2], const u4byte inp[2], const u4byte key[4])
{ u4byte acc4[6], t4[6], b, t;

/* load the little endian accumulator with B - that is: */
/* acc[0] = ls = key[3]) and acc[1] = ms = key[2] */

acc4[0] = key[3]; acc4[1] = key[2]; acc4[2] = acc4[3] = 0;

/* 64 bit multiply of input x (ls = inp[1], ms = inp[1]) */
/* and A (ls = key[1], ms = key[0]). Ensure that little */
/* endian order is used for this maths */

madd(acc4, inp + 1, key + 1); /* least significant digits */
madd(acc4 + 1, inp, key + 1);
madd(acc4 + 1, inp + 1, key);
madd(acc4 + 2, inp, key); /* most significant digits */

/* we need the value in the accumulator mod 2^64 + 13 so if */
/* the accumulator value is hi * 2^64 + lo we need to find */
/* a k value such that r = hi * 2^64 + lo - k * (2^64 + 13) */
/* is 0 <= r < 2^64 + 13. We can see that k will be close */
/* to hi in value - it may equal hi but will not be greater */
/* and we can let k = hi - e with e >= 0 so that r is given */
/* by r = e * (2^64 + 13) + lo - 13 * hi. If we compute the */
/* lo - 13 * hi value, the overflow into the top 64 bits of */
/* the accumulator has to be 'zeroed' by the e * (2^64 + 13)*/
/* term and this sets the e value (in fact such an overlow */
/* is only removed when the lower word is higher than 12). */

t4[0] = t4[1] = t4[2] = 0; b = 13;

madd(t4, acc4 + 2, &b); madd(t4 + 1, acc4 + 3, &b);

/* calculate lo - 13 * hi in acc4 */

t = acc4[0]; acc4[0] -= t4[0]; b = (acc4[0] > t ? 1 : 0);

t = acc4[1]; acc4[1] -= t4[1] + b;
b = (acc4[1] > t ? 1 : (acc4[1] == t ? b : 0));

b = 13 * (t4[2] + b);

if(((acc4[0] += b) < b) && !(++acc4[1]))
{
if(acc4[0] > 12)

acc4[0] -= 13;
}

/* do the confusion permutation (t4 is big endian format) */

t4[1] = acc4[1] ^ kc; t4[0] = acc4[0] ^ rt64[acc4[1] >> 26];

t4[0] += kd2[0] + ((t4[1] += kd2[1]) < kd2[1] ? 1 : 0);

outp[0] ^= t4[0]; outp[1] ^= t4[1];
};

u4byte *set_key(u4byte key_blk[], u4byte key_len)
{ u4byte i, lk[32], rk[4];

for(i = 0; i < key_len; ++i)

lk[i] = key_blk[i]; // key_len - 1 - i];

/* pad the key with the KS array */

for(i = 0; i < 8 - key_len; ++i) /* K|KS */

lk[i + key_len] = ks8[i];

/* do the reordering of the key parameters */
/* the OAP[1]|OBP[1]|OAP[2]... sequence is */
/* at lk[0]... and the other at lk[16]... */

lk[18] = lk[5]; lk[19] = lk[2]; /* EBP */
lk[16] = lk[1]; lk[17] = lk[6]; /* EAP */
lk[ 2] = lk[4]; lk[ 3] = lk[3]; /* OBP */
lk[ 0] = lk[0]; lk[ 1] = lk[7]; /* OAP */

/* create other elements using KA and KB */

for(i = 0; i < 6; i += 2)
{
lk[i + i + 4] = lk[ 0] ^ ka2[i]; /* OAP[i] ms */
lk[i + i + 5] = lk[ 1] ^ ka2[i + 1]; /* OAP[i] ls */
lk[i + i + 6] = lk[ 2] ^ kb2[i]; /* OBP[i] ms */
lk[i + i + 7] = lk[ 3] ^ kb2[i + 1]; /* OBP[i] ls */
lk[i + i + 20] = lk[16] ^ ka2[i]; /* EAP[i] ms */
lk[i + i + 21] = lk[17] ^ ka2[i + 1]; /* EAP[i] ls */
lk[i + i + 22] = lk[18] ^ kb2[i]; /* EBP[i] ms */
lk[i + i + 23] = lk[19] ^ kb2[i + 1]; /* EBP[i] ls */
}

rk[0] = rk[1] = rk[2] = rk[3] = 0;

/* do the 4 round key mixing encryption */

for(i = 0; i < 32; i += 8)
{
r_fun(rk, rk + 2, lk); /* R2|R1 */
r_fun(rk + 2, rk, lk + 4); /* R2|R3 */
r_fun(rk, rk + 2, lk + 8); /* R4|R3 */
r_fun(rk + 2, rk, lk + 12); /* R4|R5 */

/* keep key in big endian format with */
/* the most significant 32 bit words */
/* first (lowest) in the key schedule */
/* - note that the upper and lower 64 */
/* bit blocks are in inverse order at */
/* this point in the loop */

l_key[i + 0] = rk[2]; l_key[i + 1] = rk[3];
l_key[i + 2] = rk[0]; l_key[i + 3] = rk[1];

r_fun(rk + 2, rk, lk + 16); /* R1|R2 */
r_fun(rk, rk + 2, lk + 20); /* R3|R2 */
r_fun(rk + 2, rk, lk + 24); /* R3|R4 */
r_fun(rk, rk + 2, lk + 28); /* R5|R4 */

l_key[i + 4] = rk[0]; l_key[i + 5] = rk[1];
l_key[i + 6] = rk[2]; l_key[i + 7] = rk[3];
}

return l_key;
};

void encrypt(u16byte in_blk, u16byte out_blk)
{ u16byte blk;

/* the input/output format is big endian - */
/* any reversals needed are performed when */
/* maths is done in the round function */

blk[0] = in_blk[0]; blk[1] = in_blk[1];
blk[2] = in_blk[2]; blk[3] = in_blk[3];

r_fun(blk, blk + 2, l_key + 0); /* R2|R1 */
r_fun(blk + 2, blk, l_key + 4); /* R2|R3 */
r_fun(blk, blk + 2, l_key + 8); /* R4|R3 */
r_fun(blk + 2, blk, l_key + 12); /* R4|R5 */
r_fun(blk, blk + 2, l_key + 16); /* R6|R5 */
r_fun(blk + 2, blk, l_key + 20); /* R6|R7 */
r_fun(blk, blk + 2, l_key + 24); /* R8|R7 */
r_fun(blk + 2, blk, l_key + 28); /* R8|R9 */

/* swap order to obtain the result R9|R8 */

out_blk[0] = blk[2]; out_blk[1] = blk[3];
out_blk[2] = blk[0]; out_blk[3] = blk[1];
};

void decrypt(u16byte in_blk, u16byte out_blk)
{ u16byte blk;

/* the input/output format is big endian - */
/* any reversals needed are performed when */
/* maths is done in the round function */

blk[0] = in_blk[0]; blk[1] = in_blk[1];
blk[2] = in_blk[2]; blk[3] = in_blk[3];

r_fun(blk, blk + 2, l_key + 28); /* R7|R8 */
r_fun(blk + 2, blk, l_key + 24); /* R7|R6 */
r_fun(blk, blk + 2, l_key + 20); /* R5|R6 */
r_fun(blk + 2, blk, l_key + 16); /* R5|R4 */
r_fun(blk, blk + 2, l_key + 12); /* R3|R4 */
r_fun(blk + 2, blk, l_key + 8); /* R3|R2 */
r_fun(blk, blk + 2, l_key + 4); /* R1|R2 */
r_fun(blk + 2, blk, l_key ); /* R1|R0 */

/* swap order to obtain the result R1|R0 */

out_blk[0] = blk[2]; out_blk[1] = blk[3];
out_blk[2] = blk[0]; out_blk[3] = blk[1];
};
Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    0 Files
  • 17
    Apr 17th
    0 Files
  • 18
    Apr 18th
    0 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close