#include "stdafx.h"
#include "FDatatype.h"
//====================================
//
//将一个字节的第j位复制到另一个字节的第k位
//@参数src :源字节
//@参数from:源位数
//@参数des :目的字节
//@参数to:目的位数
//====================================
PRIVATE void bitCopy(unsigned char* src,int from,unsigned char* des,int to)
{
unsigned char mask=0x01;
unsigned char temp;
temp=(mask<<from)&*src;
if(from < to) temp = temp<<(to-from);
else temp=temp>>(from-to);//)&(mask<<to);
*des |=temp;
}
//=====================================================
//@param orgKey: input key
//@param newIp: the buffer for permutated key
//@param map:mapping src to des buffer
//@param mapSize: the length of the buffer map in bytes
//=====================================================
PRIVATE void initPermutation(unsigned char* orgKey, int orgKeyLen,unsigned char* newIPKey, int newIPKeyLen,unsigned char* map,size_t mapSize)
{
int from;
int to;
int srcByteID;
int desByteID;
orgKeyLen -=1;
newIPKeyLen -=1;
for(size_t i=0;i<mapSize;i++){
srcByteID = orgKeyLen-((map[i]-1)>>3);//among which byte;
from=(map[i]-1)%8;//at which bit;
desByteID = newIPKeyLen-(i>>3);
to=i%8;
bitCopy(orgKey+srcByteID,from,newIPKey+desByteID,to);
}
}
//将输入64位对象分成左右两个部分。
PRIVATE void split2LR(INPUTPAR lInput,INPUTPAR rInput,KEY theKey)
{
/*for(size_t i=0;i<63;i++){
if(i<32) lInput[3-((i>>3)%4)] = theKey[7-(i>>3)];
else rInput[3-((i>>3)%4)] = theKey[7-(i>>3)];
}*/
memcpy(lInput,theKey,4);
memcpy(rInput,theKey+4,4);
}
//====================================
//
//
//Cipher function:f(R,K)
//====================================
PRIVATE void f(
INPUTPAR rPrev,
KEYN keyn,
unsigned char* eFunction,
SelectionArray selectFunc,
SelectPermutation theP
)
{
int from;
int to;
int srcByteID;
int desByteID;
KEYN elizedR;
INPUTPAR tempR;
//input R is processed by E function,
//buffer elizedR stores the aftermath.
memset(elizedR,0,6);
for(size_t i=0;i<ELength;i++){
srcByteID = 3-((eFunction[i]-1)>>3);//among which byte;
from=(eFunction[i]-1)%8;//at which bit;
desByteID = 5-(i>>3);
to=i%8;
bitCopy(
rPrev+srcByteID,//from byte
from,//bit number
elizedR+desByteID,//to byte
to//to bit number
);
}
// elized buffer XORs keyFunc
for(i=0;i<KeyNLength;i++) elizedR[i] ^= keyn[i];
//B blocks are converted by a set of selection functions Ss.
//doSelection(elizedR,selectFunc,rPrev);
for(i=0;i<8;i++)
doSFun(elizedR,rPrev,selectFunc[i],i);
//selected result has to be permuted in accordance with P
memset(tempR,0,4);
for(i=0;i<PLength;i++){
srcByteID = 3-((theP[i]-1)>>3);//among which byte;
from=(theP[i]-1)%8;//at which bit;
desByteID = 3-(i>>3);
to=i%8;
bitCopy(
rPrev+srcByteID,//from byte
from,//bit number
tempR+desByteID,//to byte
to//to bit number
);
}
memcpy(rPrev,tempR,4);
}
//selection functions are to interpret input blocks inputBs
PRIVATE void doSFun(KEYN inputBs,INPUTPAR rPrev,Selection sFuncs,BlockNo blockNo)
{
int start = 6*(8-blockNo);
int byteNo;//in which byte the specified bit is located
int shift;// in which bit the specified bit populated
unsigned char sOutput=(unsigned char)0x00;
unsigned char row=0;
unsigned char col=0;
for(int i=0;i<6;i++){
start -= 1;
byteNo = 5- (start>>3);
shift = start%8;
bitCopy(inputBs+byteNo,shift,&sOutput,5-i);
}
row = ((sOutput&0x20)>>4)|((sOutput&0x01));
col = ((sOutput&0x1e)>>1);
if((blockNo%2)==0){
blockNo >>=1;
rPrev[blockNo] &= 0x0f;
rPrev[blockNo] |=(sFuncs[row][col]<<4);
}else{
blockNo >>=1;
rPrev[blockNo] &= 0xf0;
rPrev[blockNo] |=sFuncs[row][col];
}
}
// cihper and decipher function,integerating relevant components
PUBLIC void enCiphering(DATA input,DATA output,INITP initP,
INITP inInitP,CHOICEP1 pChoice1,
CHOICEP2 pChoice2,EFUNC E,SelectionArray sFuncs,
KEY key,CIPHERP cipherP,LSHCTRL lshftCtrl,KEYNSET keyNSet)
{
INPUTPAR lPart;
INPUTPAR rPart;
INPUTPAR templPart;
//INPUTPAR temprPart;
Buffer aBuffer;
/*KEY backOrigKey;
//backup tempKey
memcpy(backOrigKey,key,8);*/
Zero(aBuffer);
//ciphering
initPermutation(input,8,aBuffer,8,initP,64);
memcpy(input,aBuffer,8);
split2LR(lPart,rPart,input);
for(int i=0;i<16;i++){
memcpy(templPart,rPart,4);
f(rPart,keyNSet[i],E,sFuncs,cipherP);
for(int j=0;j<4;j++) rPart[j] ^= lPart[j];
memcpy(lPart,templPart,4);
}
//making preoutput
memcpy(output,rPart,4);
memcpy(output+4,lPart,4);
Zero(aBuffer);
initPermutation(output,8,aBuffer,8,inInitP,64);
memcpy(output,aBuffer,8);
}
PUBLIC void deCiphering(DATA input,DATA output,INITP initP,
INITP inInitP,CHOICEP1 pChoice1,
CHOICEP2 pChoice2,EFUNC E,SelectionArray sFuncs,
KEY key,CIPHERP cipherP,LSHCTRL lshftCtrl,KEYNSET keyNSet)
{
INPUTPAR lPart;
INPUTPAR rPart;
INPUTPAR templPart;
Buffer aBuffer;
/*KEY backOrigKey;
//backup tempKey
memcpy(backOrigKey,key,8);*/
Zero(aBuffer);
//ciphering
initPermutation(input,8,aBuffer,8,initP,64);
memcpy(input,aBuffer,8);
split2LR(lPart,rPart,input);
//============================
for(int i=0;i<16;i++){
memcpy(templPart,rPart,4);
f(rPart,keyNSet[15-i],E,sFuncs,cipherP);
for(int j=0;j<4;j++) rPart[j] ^= lPart[j];
memcpy(lPart,templPart,4);
}
//making preoutput
memcpy(output,rPart,4);
memcpy(output+4,lPart,4);
Zero(aBuffer);
initPermutation(output,8,aBuffer,8,inInitP,64);
memcpy(output,aBuffer,8);
}
PRIVATE void leftShift(unsigned char* object, int size,int bits)
{
int lastIndex = size-1;
unsigned char mask = 0x80;
unsigned char clean_mask=0xff;
mask >>=7-((bits-1) % 8);
clean_mask >>=7-((bits-1) % 8);
unsigned char CR = (object[0] & mask)>>((bits-1)% 8);
unsigned char CL;
mask =0x80;
for(int i=0;i<lastIndex;i++){
CL = (object[lastIndex-i] &mask) >>7;
object[lastIndex-i] <<=1;
object[lastIndex-i] |=CR;
CR= CL;
}
object[0] <<=1;
object[0] |=CR;
object[0] &= clean_mask;
}
PRIVATE void splitKey(KEY oldKey,INPUTPAR lKey, INPUTPAR rKey,unsigned char* pChoice1,int choiceSize)
{
memset(lKey,0,4);
memset(rKey,0,4);
initPermutation(oldKey,8,lKey,4,pChoice1,28);
initPermutation(oldKey,8,rKey,4,pChoice1+28,28);
}
PRIVATE void combineKeys(INPUTPAR C,INPUTPAR D,CMBKEY output)
{
unsigned char mask = 0xf0;
unsigned char CR;
memcpy(output,C,sizeof(INPUTPAR));
for(int i=0;i<3;i++){
output[i] <<= 4;
CR = (output[i+1]&mask)>>4;
output[i] |= CR;
}
output[i] <<=4;//对第3个字节左移4位,这样该字节的最后4位为0
memcpy(output+4,D+1,3);//将D后三个字节拷贝到output[4.5.6]
output[i] |=D[0];//D的第一个字节第四位有数据并入到output[3]低4位。
}
PUBLIC ENCDLL_API void keyShedule(KEY theInpuKey,KEYNSET keyNSet)
{
INPUTPAR lkN;
INPUTPAR rkN;
CMBKEY tempKey;//input to pChoice2
memset(keyNSet,0,sizeof(KEYNSET));
splitKey(theInpuKey,lkN,rkN,pChoice1,56);
for(int i=0;i<16;i++){
for(int k=0;k<lshftCtrl[i];k++){
leftShift(lkN,4,28);
leftShift(rkN,4,28);
}
combineKeys(lkN,rkN,tempKey);
//memset(keyNSet[i],0,sizeof(KEYN));
initPermutation(tempKey,7,keyNSet[i],6,pChoice2,48);
}
}
typedef unsigned char Selection[4][16];
typedef Selection SelectionArray[8];
#define PLength 32
//字符数组第一个字节是63-56 ……
unsigned char initP[64]={
58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7
};
unsigned char inInitP[64]={
40,8,48,16,56,24,64,32,
39,7,47,15,55,23,63,31,
38,6,46,14,54,22,62,30,
37,5,45,13,53,21,61,29,
36,4,44,12,52,20,60,28,
35,3,43,11,51,19,59,27,
34,2,42,10,50,18,58,26,
33,1,41,9,49,17,57,25
};
unsigned char pChoice1[56]={
57,49,41,33,25,17,9,
1,58,50,42,34,26,18,
10,2,59,51,43,35,27,
19,11,3,60,52,44,36,
63,55,47,39,31,23,15,
7,62,54,46,38,30,22,
14,6,61,53,45,37,29,
21,13,5,28,20,12,4
};
unsigned char E[48]={
32,1,2,3,4,5,
4,5,6,7,8, 9,
8,9,10,11,12,13,
12,13,14,15,16,17,
16,17,18,19,20,21,
20,21,22,23,24,25,
24,25,26,27,28,29,
28,29,30,31,32,1
};
SelectionArray sFuncs={
14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,
0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,
4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,
15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13,
15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,
3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,
0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,
13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9,
10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,
13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,
13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12,
7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,
13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,
10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,
3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14,
2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,
14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,
4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3,
12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,
10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,
9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13,
4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,
13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,
1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12,
13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,
1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,
7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11
};
unsigned char cipherP[PLength]={
16,7,20,21
,29,12,28,17
,1,15,23,26
,5,18,31,10
,2,8,24,14
,32,27,3,9
,19,13,30,6
,22,11,4,25
};
unsigned char pChoice2[48]={
14,17,11,24,1,5
,3,28,15,6,21,10
,23,19,12,4,26,8
,16,7,27,20,13,2
,41,52,31,37,47,55
,30,40,51,45,33,48
,44,49,39,56,34,53
,46,42,50,36,29,32
};
unsigned char lshftCtrl[16]={
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};
unsigned char PI_SUBST[256] = {
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
};
测试程序: