转WG联合国 也就是台服CSOL
#include "StdAfx.h"
#include "IceKey.h"
/* Structure of a single round subkey */
struct TIceSubKey
{
DWORD dwValue[3];
};
/* The S-boxes */
static BOOL g_bIceSBoxesInitialised = FALSE;
static DWORD g_pdwIceSBox[4][1024];
/* Modulo values for the S-boxes */
static CONST INT g_piIceSMod[4][4] = {
{333, 313, 505, 369},
{379, 375, 319, 391},
{361, 445, 451, 397},
{397, 425, 395, 505}
};
/* XOR values for the S-boxes */
static CONST INT g_piIceSXor[4][4] = {
{0x83, 0x85, 0x9b, 0xcd},
{0xcc, 0xa7, 0xad, 0x41},
{0x4b, 0x2e, 0xd4, 0x33},
{0xea, 0xcb, 0x2e, 0x04}
};
/* Permutation values for the P-box */
static CONST DWORD g_pdwIcePBox[32] = {
0x00000001, 0x00000080, 0x00000400, 0x00002000,
0x00080000, 0x00200000, 0x01000000, 0x40000000,
0x00000008, 0x00000020, 0x00000100, 0x00004000,
0x00010000, 0x00800000, 0x04000000, 0x20000000,
0x00000004, 0x00000010, 0x00000200, 0x00008000,
0x00020000, 0x00400000, 0x08000000, 0x10000000,
0x00000002, 0x00000040, 0x00000800, 0x00001000,
0x00040000, 0x00100000, 0x02000000, 0x80000000
};
/* The key rotation schedule */
static CONST INT g_piIceKeyRotation[16] = {
0, 1, 2, 3, 2, 1, 3, 0,
1, 3, 2, 0, 3, 1, 0, 2
};
/*
* 8-bit Galois Field multiplication of a by b, modulo m.
* Just like arithmetic multiplication, except that additions and
* subtractions are replaced by XOR.
*/
static DWORD GFMultiply(DWORD a, DWORD b, DWORD m)
{
DWORD res = 0;
while (b)
{
if (b & 1)
res ^= a;
a <<= 1;
b >>= 1;
if (a >= 256)
a ^= m;
}
return res;
}
/*
* Galois Field exponentiation.
* Raise the base to the power of 7, modulo m.
*/
static DWORD GFExp7(DWORD b, DWORD m)
{
DWORD x;
if (b == 0)
return 0;
x = GFMultiply(b, b, m);
x = GFMultiply(b, x, m);
x = GFMultiply(x, x, m);
return GFMultiply(b, x, m);
}
/*
* Carry out the ICE 32-bit P-box permutation.
*/
static DWORD IcePerm32(DWORD x)
{
DWORD res = 0;
CONST DWORD *pbox = g_pdwIcePBox;
while (x) {
if (x & 1)
res |= *pbox;
pbox++;
x >>= 1;
}
return res;
}
/*
* Initialize the ICE S-boxes.
* This only has to be done once.
*/
static VOID IceSBoxesInitialize()
{
INT i;
for (i = 0; i < 1024; ++i)
{
INT col = (i >> 1) & 0xff;
INT row = (i & 0x1) | ((i & 0x200) >> 8);
DWORD x;
x = GFExp7(col ^ g_piIceSXor[0][row], g_piIceSMod[0][row]) << 24;
g_pdwIceSBox[0] = IcePerm32(x);
x = GFExp7(col ^ g_piIceSXor[1][row], g_piIceSMod[1][row]) << 16;
g_pdwIceSBox[1] = IcePerm32(x);
x = GFExp7(col ^ g_piIceSXor[2][row], g_piIceSMod[2][row]) << 8;
g_pdwIceSBox[2] = IcePerm32(x);
x = GFExp7(col ^ g_piIceSXor[3][row], g_piIceSMod[3][row]);
g_pdwIceSBox[3] = IcePerm32(x);
}
}
static DWORD IceFunction(DWORD dwValue, CONST TIceSubKey *sk)
{
DWORD tl, tr; /* Expanded 40-bit values */
DWORD al, ar; /* Salted expanded 40-bit values */
/* Left half expansion */
tl = ((dwValue >> 16) & 0x3ff) | (((dwValue >> 14) | (dwValue << 18)) & 0xffc00);
/* Right half expansion */
tr = (dwValue & 0x3ff) | ((dwValue << 2) & 0xffc00);
/* Perform the salt permutation */
// al = (tr & sk->val[2]) | (tl & ~sk->val[2]);
// ar = (tl & sk->val[2]) | (tr & ~sk->val[2]);
al = sk->dwValue[2] & (tl ^ tr);
ar = al ^ tr;
al ^= tl;
/* XOR with the subkey */
al ^= sk->dwValue[0];
ar ^= sk->dwValue[1];
/* S-box lookup and permutation */
return
g_pdwIceSBox[0][al >> 10] | g_pdwIceSBox[1][al & 0x3ff] |
g_pdwIceSBox[2][ar >> 10] | g_pdwIceSBox[3][ar & 0x3ff];
}
CIceKey::CIceKey(INT n)
: m_iSize(0)
, m_iRounds(0)
{
if (!g_bIceSBoxesInitialised) {
IceSBoxesInitialize();
g_bIceSBoxesInitialised = 1;
}
if (n < 1)
{
m_iSize = 1;
m_iRounds = 8;
}
else
{
m_iSize = n;
m_iRounds = n * 16;
}
m_pKeySchedule = new TIceSubKey[m_iRounds];
}
CIceKey::~CIceKey()
{
INT i, j;
for (i = 0; i < m_iRounds; ++i)
for (j = 0; j < 3; ++j)
m_pKeySchedule.dwValue[j] = 0;
m_iRounds = m_iSize = 0;
delete[] m_pKeySchedule;