📄 smartea.h
字号:
/***
* (c)Coryrights Reserved.
*
* SmartEA.h
* - SEA(Smart Encryption Algorithm)的运算部件
*
* superStar, 2004.2
***/
static int rounds[3] = { /* 加密轮数(分别对应3种密钥长度) */
ROUNDMIN, ROUNDMED, ROUNDMAX
};
static int keyLen[3] = {16, 24, 32}; /* 密钥长度,单位:字节 */
static BYTE logRuler[8] = { /* 字节上关于每一比特位的逻辑尺 */
0x80, 0x40, 0x20, 0x10,
0x08, 0x04, 0x02, 0x01
};
static int direction[16][2] = { /* 转移控制方向增量 */
{-1, 0},{-1,-1},{0, -1},{1,-1},
{ 2, 0},{ 2, 1},{2, 2},{1, 2},
{ 0, 2},{-1, 2},{-2, 2},{-2,1},
{-2,-3},{-1,-3},{ 0,-3},{1,-3}
};
/**
* BOOL AskKeys(KEYINFO *ck);
* - 选择密钥长度及输入用户密钥。
* - 如果输入密钥成功,则返回TRUE,
* 否则返回FALSE。
* - 本函数中使用全局变量
* - keyInput(type: WINDOWHANDLE)
* - message(type: WINDOWHANDLE)
* - keyPanel(type: WINDOWHANDLE)
* - key128Item(type: WINDOWHANDLE)
* - key192Item(type: WINDOWHANDLE)
* - key256Item(type: WINDOWHANDLE)
* - keyLen(type: int[])
* - rounds(type: int[])
**/
BOOL
AskKeys(KEYINFO *ck)
{
int i, retLen;
WINDOWHANDLE *pPanel_Key[4];
char *userKeyType[3] = {
"key-16Bytes]",
"key-24Bytes]",
"key-32Bytes]"
};
BYTE ch;
ASKKEYSTART:
pPanel_Key[0] = &keyPanel;
pPanel_Key[1] = &key128Item;
pPanel_Key[2] = &key192Item;
pPanel_Key[3] = &key256Item;
if (-1 == (i = Panel(pPanel_Key, 4))) /* 密钥长度选择 */
{
return FALSE;
}
ck->keyType = i;
ck->seedKey = (BYTE *) /* 为种子密钥申请空间 */
malloc(keyLen[ck->keyType]
* sizeof(BYTE));
if (NULL == ck->seedKey)
{
strcpy(message.displayStr, "[!]\n\n No enough memory for user key \n");
Message(&message);
getch();
FreeMessage(&message);
return FALSE;
}
/* 输入用户密钥 */
keyInput.retStrLen = keyLen[ck->keyType];
if (ENCRYPT == ck->flag)
{
strcpy(keyInput.title, "[ENCRYPT: ");
}
else if (DECRYPT == ck->flag)
{
strcpy(keyInput.title, "[DECRYPT: ");
}
strcat(keyInput.title, userKeyType[i]);
if (FALSE == Window(&keyInput))
{
FreeWindow(&keyInput);
return FALSE;
}
retLen = keyInput.retStrLen;
CopyTo(ck->seedKey, keyInput.retStr, retLen);
FreeWindow(&keyInput);
/* 如果没有输入任何密钥,则给出提示 */
if (0 == retLen)
{
strcpy(message.displayStr, "[!]\n\n Need to input user key \n");
Message(&message);
getch();
FreeMessage(&message);
goto ASKKEYSTART;
}
/* 如果输入密钥的长度达到选定的长度 */
else if (retLen == keyLen[ck->keyType])
{
return TRUE;
}
/* 如果实际输入的密钥长度不够,则余下部分交
* 替填入已输入密钥各个字节循环移位后的值,
* 以构造出达到选定长度的新密钥 */
else if (retLen < keyLen[ck->keyType])
{
for (i=retLen;
i<keyLen[ck->keyType];
i++)
{
ch = ck->seedKey[i%retLen];
ck->seedKey[i] = (ch >> i%8) | (ch << (8-i%8));
}
return TRUE;
}
}
/**
* BOOL ExpandKeys(KEYINFO *ck);
* - 根据种子密钥(及用户密钥)扩展轮子密钥
* - 本函数中使用全局变量
* - message(type: WINDOWHANDLE)
* - keyLen(type: int[])
* - rounds(type: int[])
**/
BOOL
ExpandKeys(KEYINFO *ck)
{
int i, j, t;
BYTE bTmp[8], tmp;
ck->childKey /* 为轮子密钥申请空间 */
= (BYTE *) malloc(rounds[ck->keyType]
* 8 * sizeof(BYTE));
if (NULL == ck->childKey)
{
strcpy(message.displayStr, "[!]\n\n No enough memory for child key \n");
Message(&message);
getch();
FreeMessage(&message);
return FALSE;
}
t = keyLen[ck->keyType]/8; /* 扩展出轮子密钥 */
for (i=0; i<t; i++)
{
for (j=0; j<8; j++)
{
ck->childKey[i*8+j] = ck->seedKey[i*8+j];
}
}
for (i=t;
i<rounds[ck->keyType]; /* 这里要求加密轮数至少大于t */
i++)
{
for (j=0; j<8; j++)
{
bTmp[j] = ck->seedKey[(i%t)*8+j]
+ ck->seedKey[((i+1)%t)*8+j];
}
Brown(bTmp);
for (j=0; j<8; j++)
{
ck->childKey[i*8+j]
= ck->seedKey[(i%t)*8+j]
= bTmp[j];
}
}
for (i=0; i<4; i++) /* 扩展出白化子密钥 */
{
for (j=0; j<8; j++)
{
bTmp[j] = ck->seedKey[(i%t)*8+j]
+ ck->seedKey[((i+1)%t)*8+j];
}
Brown(bTmp);
for (j=0; j<8; j++)
{
if (i < 2)
{
ck->kw0[i*8+j]
= ck->seedKey[(i%t)*8+j]
= bTmp[j];
}
else if (i >= 2)
{
ck->kw1[(i-2)*8+j]
= ck->seedKey[(i%t)*8+j]
= bTmp[j];
}
}
}
if (ENCRYPT == ck->flag); /* 判断是否要颠倒轮子密钥顺序 */
else if (DECRYPT == ck->flag)
{
t = rounds[ck->keyType]; /* 颠倒轮子密钥 */
for (i=0; i<t/2; i++)
{
for (j=0; j<8; j++)
{
tmp = ck->childKey[i*8+j];
ck->childKey[i*8+j]
= ck->childKey[(t-1-i)*8+j];
ck->childKey[(t-1-i)*8+j] = tmp;
}
}
for (i=0; i<16; i++) /* 颠倒白化子密钥 */
{
tmp = ck->kw0[i];
ck->kw0[i] = ck->kw1[i];
ck->kw1[i] = tmp;
}
}
return TRUE;
}
/** BOOL Key(KEYINFO *ck);
* - 输入用户密钥以及扩展出轮子密钥,白化子密钥
* - 如果成功返回TRUE,否则返回FALSE
**/
BOOL
Key(KEYINFO *ck)
{
/* 得到密钥 */
if (FALSE == AskKeys(ck))
{
return FALSE;
}
/* 密钥扩展,得到轮子密钥 */
if (FALSE == ExpandKeys(ck))
{
return FALSE;
}
return TRUE;
}
/**
* void FreeKey(KEYINFO *ck);
* - 释放密钥
**/
void
FreeKey(KEYINFO *ck)
{
if (NULL != ck->seedKey)
{
free(ck->seedKey);
ck->seedKey = NULL;
}
if (NULL != ck->childKey)
{
free(ck->childKey);
ck->childKey = NULL;
}
}
/**
* void Brown(BYTE* data);
* - SmartEA 算法之Brown函数,该函数对8x8位
* 矩阵作伪布朗运动,转移次数32次
* - 本函数中使用全局变量
* - logRuler(type: int[])
* - direction(type: int[])
**/
void
Brown(BYTE* data)
{
int curx, cury, curDir, i;
/* 根据data(8字节)的头3位和
* 尾3位确定跳转的初始位置 */
curx = data[0] >> 5;
cury = data[7] & 0x07;
for (i=0; i<32; i++) /* 伪布朗运动(跳转次数32) */
{
data[curx] ^= logRuler[cury]; /* 对当前点的比特作取反操作 */
curDir = /* 得到转移方向控制组的4比特值 */
(i%2) ? (data[(i/2)%8] & 0x0f)
: (data[(i/2)%8] >> 4);
/* 根据curDir的值查表得到x,y方向
* 的增量,并计算出新位置的下标 */
curx += direction[curDir][0];
cury += direction[curDir][1];
if (curx < 0 || curx > 7) /* 如果越界,则在边界处进行反射 */
{
curx = (curx + 8) % 8;
}
if (cury < 0 || cury > 7)
{
cury = (cury + 8) % 8;
}
}
}
/**
* void Feistel(BYTE* data, KEYINFO *ck);
* - rounds[ck.keyType]轮Feistel网络加密(或解密)
* - 本函数中使用全局变量
* - rounds(type: int[])
**/
void
Feistel(BYTE* data, KEYINFO *ck)
{
int rds, i;
BYTE tmp, bTmp[8];
for (rds=0; rds<rounds[ck->keyType]; rds++)
{
for (i=0; i<8; i++) /* 明文与轮子密钥模256加 */
{
bTmp[i] = data[i+8]
+ ck->childKey[rds*8+i];
}
Brown(bTmp);
/* Feistel结构下的异或和交换操作,注
* 意只交换除最后一轮外的其他轮 */
if (rds < (rounds[ck->keyType]- 1))
{
for (i=0; i<8; i++ ) /* 交换左、右部分(非最后一轮) */
{
tmp = data[i+8];
data[i+8] = bTmp[i] ^ data[i];
data[i] = tmp;
}
}
else
{
for (i=0; i<8; i++ )
{
data[i] ^= bTmp[i]; /* Feistel网络的最后一轮不交换左、右部分 */
}
}
}
}
/**
* void SEA(BYTE* data, KEYINFO *ck);
* - SEA算法主体函数
**/
void
SEA(BYTE* data, KEYINFO *ck)
{
int i;
BYTE bTmp[8];
/* 1. 初始白化,和kw0相异或 */
for(i=0; i<16; i++)
{
data[i] ^= ck->kw0[i];
}
/* 2. 前向混合 */
for(i=0; i<8; i++) /* data左半部分和右半部分按字节加 */
{
bTmp[i] = data[i] + data[i + 8];
}
Brown(bTmp);
/* 对data左半部分加上bTmp, 右半部分减去bTmp. 均按字节操作 */
for(i=0; i<8; i++)
{
data[i] += bTmp[i]; /* 左半部分加上bTmp */
data[i + 8] = (data[i+8]>=bTmp[i]) ?
(data[i+8]-bTmp[i]) : (256-(bTmp[i]-data[i+8]));
/* 右半部分减去bTmp */
}
Feistel(data, ck);
/* 3. 后向混合 */
for(i=0; i<8; i++) /* data左半部分和右半部分按字节加 */
{
bTmp[i] = data[i] + data[i + 8];
}
Brown(bTmp);
/* 对data左半部分减去bTmp, 右半部分加上bTmp. 均按字节操作 */
for(i=0; i<8; i++)
{
/* 左半部分减去bTmp */
data[i] = (data[i]>=bTmp[i]) ?
(data[i]-bTmp[i]) : (256-(bTmp[i]-data[i]));
data[i+8] += bTmp[i]; /* 右半部分加上bTmp */
}
/* 4. 末尾白化,和kw1相异或 */
for(i=0; i<16; i++)
{
data[i] ^= ck->kw1[i];
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -