RC5分組密碼算法是1994由麻薩諸塞技術研究所的Ronald L. Rivest教授發明的,并由RSA實驗室分析。它是參數可變的分組密碼算法,三個可變的參數是:分組大小、密鑰大小和加密輪數。在此算法中使用了三種運算:異或、加和循環。
簡介
RC5是種比較新的算法,Rivest設計了RC5的一種特殊的實現方式,因此RC5算法有一個面向字的結構:RC5-w/r/b,這里w是字長其值可以是16、32或64對于不同的字長明文和密文塊的分組長度為2w位,r是加密輪數,b是密鑰字節長度。由于RC5一個分組長度可變的密碼算法,為了便于說明在本文中主要是針對64位的分組w=32進行處理的,下面詳細說明了RC5加密解密的處理過程:
加密解密
1、創建密鑰組
RC5算法加密時使用了2r+2個密鑰相關的的32位字: ,這里r表示加密的輪數。創建這個密鑰組的過程是非常復雜的但也是直接的,首先將密鑰字節拷貝到32位字的數組L中(此時要注意處理器是little-endian順序還是big-endian順序),如果需要,最后一個字可以用零填充。然后利用線性同余發生器模2初始化數組S:
對于i=1到2(r+1)-1: (本應模 ,本文中令w=32)
其中對于16位字32位分組的RC5,P=0xb7e1 Q=0x9e37
對于32位字和64位分組的RC5,P=0xb7e15163 Q=0x9e3779b9
對于64位字和128位分組,P=0xb7151628aed2a6b Q=0x9e3779b97f4a7c15
最后將L與S混合,混合過程如下:
i=j=0
A=B=0
處理3n次(這里n是2(r+1)和c中的最大值,其中c表示輸入的密鑰字的個數)
2、加密處理
在創建完密鑰組后開始進行對明文的加密,加密時,首先將明文分組劃分為兩個32位字:A和B(在假設處理器字節順序是little-endian、w=32的情況下,第一個明文字節進入A的最低字節,第四個明文字節進入A的最高字節,第五個明文字節進入B的最低字節,以此類推),其中操作符《《《表示循環左移,加運算是模 (本應模 ,本文中令w=32)的。
輸出的密文是在寄存器A和B中的內容
3、解密處理
解密也是很容易的,把密文分組劃分為兩個字:A和B(存儲方式和加密一樣),這里符合》》》是循環右移,減運算也是模 (本應模 ,本文中令w=32)的。
RSA試驗室花費了相當的時間來分析64位分組的RC5算法,在5輪后統計特性看起來非常好。在8輪后,每一個明文位至少影響一個循環。對于5輪的RC5,差分攻擊需要 個選擇明文;對10輪需要 個;對于12輪需要 個;對15輪需要 個。而對于64位的分組只有 個可能的明文,所以對于15輪或以上的RC5的差分攻擊是失敗的。在6輪后線性分析就是安全的了,Rivest推薦至少12輪,甚至可能是16輪。這個輪數可以進行選擇。
RC5 分組密鑰算法 C語言實現
[cpp] view plain copy/*RC5 C代碼實現
w/r/b=32/12/16
基本的RC5 3種算法組成,即密鑰擴展算法、加密算法和解密算法。故RC5的C語言實現也由以下幾個部分構成。
1、 參數的定義
*/
#include 《stdlib.h》
#include 《stdio.h》
#include 《string.h》
#include 《math.h》
int w=32;//字長 32bit 4字節
int r=12;//12;//加密輪數12
int b=16;//主密鑰(字節為單位8bit)個數 這里有16個
int t=26;//2*r+2=12*2+2=26
int c=4; //主密鑰個數*8/w = 16*8/32
typedef unsigned long int FOURBYTEINT;//四字節
typedef unsigned short int TWOBYTEINT;//2字節
typedef unsigned char BYTE;
void InitialKey(unsigned char* KeyK,int b);
void generateChildKey(unsigned char* KeyK,FOURBYTEINT* ChildKeyS);
void Encipher(FOURBYTEINT* In,FOURBYTEINT* Out,FOURBYTEINT* S);
void Decipher(FOURBYTEINT* In,FOURBYTEINT* Out,FOURBYTEINT* S);
#define NoOfData 4
/**2、循環移位函數
由于在生成子密鑰,加密,解密過程中都要進行循環移位,故要首先定義循環以為函數。
* 循環左移和右移函數
* x : 被循環的數
* y : 將要循環的位數
*/
#define ROTL(x,y) (((x)《《(y&(w-1))) | ((x)》》(w-(y&(w-1)))))
#define ROTR(x,y) (((x)》》(y&(w-1))) | ((x)《《(w-(y&(w-1)))))
/**3、 初始密鑰產生函數
生成一個初始的長度為b字節的密鑰。
產生初始密鑰的函數
*/
void InitialKey(unsigned char* KeyK,int b)
{
int i,j;
int intiSeed=3;
for( i=0;i《b;i++)//初始化
{
KeyK[i]=0;
}
KeyK[0]=intiSeed;
printf(“初始主密鑰(16字節共128位):%.2lx ”,KeyK[0]);
for(j=1;j《b;j++)//生成
{
KeyK[j] = (BYTE)( (int)pow(3,j)%(255-j) ); //pow(x,y) x^y: 2^3=8
printf(“%.2X ”,KeyK[j]);
//KeyK[j] = (BYTE) ( ((int)(pow(double(3),j))%(255-j)));
}
printf(“\n”);
}
/**4、 密鑰擴展函數
由于需加密r輪,每輪需要兩個子密鑰,所以需要密鑰擴展函數根據初始密鑰來擴展出2r+2個子密鑰。
產生子密鑰的函數
*/
void generateChildKey(unsigned char* KeyK,FOURBYTEINT* ChildKeyS)
{
//const double e = 2.718281828459;
//const double Phia = 1.618033988749;
int PW = 0xB7E15163;//0xb7e1;
int QW = 0x9E3779B9;//0x9e37;//genggai
int i;
int u =w/8;// b/8;
FOURBYTEINT A,B,X,Y;
FOURBYTEINT L[4]; //c=16*8/32
A=B=X=Y=0;
//初始化數組S
ChildKeyS[0]=PW;
printf(“\n初始子密鑰(沒有主密鑰的參與):\n%.8X ”, ChildKeyS[0]);
for (i=1;i《t;i++) //t=26
{
if(i%13==0)printf(“\n”);
ChildKeyS[i]=(ChildKeyS[i-1]+ QW);
printf(“%.8X ”, ChildKeyS[i]);
}
printf(“\n”);
//將K數組轉換為L數組
for(i=0;i《c;i++)//初始化L數組c=8
{
L[i]=0;
}
for (i=b-1;i!=-1; i--)//b=16 轉換主密鑰數組(16個 單位為8bit)為L數組(8個單位為16bit),數組L每一元素長為16bit,數組K每一元素長為8bit
{
L[i/u] = (L[i/u]《《8)+KeyK[i];
}
printf(“\n把主密鑰變換為4字節單位:\n”);
for (i=0;i《c;i++)//16進制輸出gaidong
{
printf(“%.8X ”,L[i]);
}
printf(“\n\n”);
//產生子密鑰,存儲在ChildKeyS中
for(i=0;i《3*t;i++)
{
X = ChildKeyS[A] = ROTL(ChildKeyS[A]+X+Y,3);
A = (A+1) % t;
Y = L[B] = ROTL(L[B]+X+Y,(X+Y));
B = (B+1) % c;
}
printf(“生成的子密鑰(初始主密鑰參與和初始子密鑰也參與):”);
for (i=0;i《t;i++)//16進制輸出
{
if(i%13==0)printf(“\n”);
printf(“%.8X ”,ChildKeyS[i]);
}
printf(“\n\n”);
}
/**5、 加密函數
加密函數
*/
void Encipher(FOURBYTEINT * In,FOURBYTEINT * Out,FOURBYTEINT* S)
{
FOURBYTEINT X,Y; //定義兩個16位存儲器
int i,j;
for(j=0;j《NoOfData;j+=2)
{
X = In[j]+S[0]; //In[j]+S[0];
Y = In[j+1]+S[1]; //In[j+1]+S[1];
for( i=1;i《=r;i++)
{
X=ROTL((X^Y),Y) + S[2*i]; // X=ROTL((X^Y),Y) + S[2*i]; 異或,循環移位,相加 //ROTL(x,y) (((x)《《(y&(w-1))) | ((x)》》(w-(y&(w-1)))))
Y=ROTL((Y^X),X) + S[2*i+1]; //Y=ROTL((Y^X),X) + S[2*i+1];
}
Out[j]=X;
Out[j+1]=Y; //密文
}
}
/**6、 解密函數
解密函數
*/
void Decipher(FOURBYTEINT* In,FOURBYTEINT* Out,FOURBYTEINT* S)
{
int i=0,j;
FOURBYTEINT X,Y;
for(j=0;j《NoOfData;j+=2)
{
X = In[j];
Y = In[j+1];
for(i=r;i》0;i--)
{
Y = ROTR(Y-S[2*i+1],X)^X; //Y = ROTR(Y-S[2*i+1],X)^X;相減,循環移位,異或 //ROTR(x,y) (((x)》》(y&(w-1))) | ((x)《《(w-(y&(w-1)))))
X = ROTR(X-S[2*i],Y)^Y; // X = ROTR(X-S[2*i],Y)^Y;
}
Out[j]=X - S[0]; //Out[j]=X - S[0];
Out[j+1]=Y - S[1]; //明文 Out[j+1]=Y - S[1];
}
}
/**7、 主函數測試
主函數
*/
int main(void)
{
int k;
FOURBYTEINT ChildKeyS[2*12+2]; // r=12 子密鑰個數為26
FOURBYTEINT ChildKey1[26]; //
BYTE KeyK[16]; //8bit=byte 16=b 主密鑰共16字節
FOURBYTEINT Source[]={0xfffff2fe,0x56211681,0xee111560,0x44575555}; //測試明文
FOURBYTEINT Dest[NoOfData]; //用來存儲密文
FOURBYTEINT Data[NoOfData]={0}; //用來存儲解密后的密文
InitialKey(KeyK,b);//生成初始密鑰
generateChildKey(KeyK,ChildKeyS); //根據初始密鑰生成子密鑰
printf(“加密以前的明文:”);
for (k=0;k《NoOfData;k++)
{
if (k%2==0)
{
printf(“ ”);
}
printf(“%.8X ”,Source[k]); //16進制輸出
}
printf(“\n”);
for(k=0;k《26;k++)
{ //************************************有問題
ChildKey1[k]=ChildKeyS[k];//如果此處自定義簡單的數值為加密密鑰,則可以解密出密文
}
Encipher(Source,Dest,ChildKey1); //加密
printf(“\n”);
printf(“加密以后的密文:”);
for (k=0;k《NoOfData;k++)
{
if (k%2==0)
{
printf(“ ”);
}
printf(“%.8X ”,Dest[k]);
}
printf(“\n”);
Decipher(Dest,Data,ChildKey1); //解密
printf(“解密以后的明文:”);
for (k=0;k《NoOfData;k++)
{
if (k%2==0)
{
printf(“ ”);
}
printf(“%.8X ”,Data[k]);
}
printf(“\n”);
//printf(“sizeof unsigned short int: %d”,sizeof(unsigned short int));
// system(“pause\n”);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*RC5 C代碼實現
w/r/b=16/12/16
基本的RC5 3種算法組成,即密鑰擴展算法、加密算法和解密算法。故RC5的C語言實現也由以下幾個部分構成。
1、 參數的定義
*/
#include 《stdlib.h》
#include 《stdio.h》
#include 《string.h》
#include 《math.h》
int w=16;//字長
int r=10;//12;//輪數12
int b=16;//密鑰字節個數
int t=26;//2*r+2=12*2+2=26
int c=8; //b*8/w = 16*8/16
//typedef unsigned long int FOURBYTEINT;//四字節
typedef unsigned short int TWOBYTEINT;//2字節
typedef unsigned char BYTE;
void InitialKey(unsigned char* KeyK,int b);
void generateChildKey(unsigned char* KeyK,TWOBYTEINT* ChildKeyS);
void Encipher(TWOBYTEINT* In,TWOBYTEINT* Out,TWOBYTEINT* S);
void Decipher(TWOBYTEINT* In,TWOBYTEINT* Out,TWOBYTEINT* S);
#define NoOfData 4
/**2、循環移位函數
由于在生成子密鑰,加密,解密過程中都要進行循環移位,故要首先定義循環以為函數。
* 循環左移和右移函數
* x : 被循環的數
* y : 將要循環的位數
*/
#define ROTL(x,y) (((x)《《(y&(w-1))) | ((x)》》(w-(y&(w-1)))))
#define ROTR(x,y) (((x)》》(y&(w-1))) | ((x)《《(w-(y&(w-1)))))
/**3、 初始密鑰產生函數
生成一個初始的長度為b字節的密鑰。
產生初始密鑰的函數
*/
void InitialKey(unsigned char* KeyK,int b)
{
int i,j;
int intiSeed=3;
for( i=0;i《b;i++)//初始化
{
KeyK[i]=0;
}
KeyK[0]=intiSeed;
printf(“初始主密鑰(16字節共128位):%.2lx ”,KeyK[0]);
for(j=1;j《b;j++)//生成
{
KeyK[j] = (BYTE)( (int)pow(3,j)%(255-j) ); //pow(x,y) x^y: 2^3=8
printf(“%.2X ”,KeyK[j]);
//KeyK[j] = (BYTE) ( ((int)(pow(double(3),j))%(255-j)));
}
printf(“\n”);
}
/**4、 密鑰擴展函數
由于需加密r輪,每輪需要兩個子密鑰,所以需要密鑰擴展函數根據初始密鑰來擴展出2r+2個子密鑰。
產生子密鑰的函數
*/
void generateChildKey(unsigned char* KeyK,TWOBYTEINT* ChildKeyS)
{
//const double e = 2.718281828459;
//const double Phia = 1.618033988749;
int PW = 0xb7e1;
int QW = 0x9e37;//genggai
int i;
int u = w/8;
TWOBYTEINT A,B,X,Y;
TWOBYTEINT L[8]; //c=b*8/w=8
A=B=X=Y=0;
//初始化數組S
ChildKeyS[0]=PW;
printf(“\n初始子密鑰(沒有主密鑰的參與):\n%.4lx ”, ChildKeyS[0]);
for (i=1;i《t;i++) //t=26
{
if(i%13==0)printf(“\n”);
ChildKeyS[i]=(ChildKeyS[i-1]+ QW);
printf(“%.4X ”, ChildKeyS[i]);
}
printf(“\n”);
//將K數組轉換為L數組
for(i=0;i《c;i++)//初始化L數組c=8
{
L[i]=0;
}
for (i=b-1;i!=-1; i--)//b=16 轉換主密鑰數組(16個 單位為8bit)為L數組(8個單位為16bit),數組L每一元素長為16bit,數組K每一元素長為8bit
{
L[i/u] = (L[i/u]《《8)+KeyK[i];
}
printf(“\n把主密鑰變換為2字節單位:\n”);
for (i=0;i《c;i++)//16進制輸出gaidong
{
printf(“%.4X ”,L[i]);
}
printf(“\n\n”);
//產生子密鑰,存儲在ChildKeyS中
for(i=0;i《3*t;i++)
{
X = ChildKeyS[A] = ROTL(ChildKeyS[A]+X+Y,3);
A = (A+1) % t;
Y = L[B] = ROTL(L[B]+X+Y,(X+Y));
B = (B+1) % c;
}
printf(“生成的子密鑰(初始主密鑰參與和初始子密鑰也參與):”);
for (i=0;i《t;i++)//16進制輸出
{
if(i%13==0)printf(“\n”);
printf(“%.4X ”,ChildKeyS[i]);
}
printf(“\n\n”);
}
/**5、 加密函數
加密函數
*/
void Encipher(TWOBYTEINT * In,TWOBYTEINT * Out,TWOBYTEINT* S)
{
TWOBYTEINT X,Y; //定義兩個16位存儲器
int i,j;
for(j=0;j《NoOfData;j+=2)
{
X = In[j]+S[0]; //In[j]+S[0];
Y = In[j+1]+S[1]; //In[j+1]+S[1];
for( i=1;i《=r;i++)
{
X=ROTL((X^Y),Y) + S[2*i]; // X=ROTL((X^Y),Y) + S[2*i]; 異或,循環移位,相加 //ROTL(x,y) (((x)《《(y&(w-1))) | ((x)》》(w-(y&(w-1)))))
Y=ROTL((Y^X),X) + S[2*i+1]; //Y=ROTL((Y^X),X) + S[2*i+1];
}
Out[j]=X;
Out[j+1]=Y; //密文
}
}
/**6、 解密函數
解密函數
*/
void Decipher(TWOBYTEINT* In,TWOBYTEINT* Out,TWOBYTEINT* S)
{
int i=0,j;
TWOBYTEINT X,Y;
for(j=0;j《NoOfData;j+=2)
{
X = In[j];
Y = In[j+1];
for(i=r;i》0;i--)
{
//***********重要*****************一定要強制轉換為unsigned short int 否則循環右移出錯
Y = ROTR((unsigned short int)(Y-S[2*i+1]),X)^X; //Y = ROTR(Y-S[2*i+1],X)^X;相減,循環移位,異或 //ROTR(x,y) (((x)》》(y&(w-1))) | ((x)《《(w-(y&(w-1)))))
X = ROTR((unsigned short int)(X-S[2*i]),Y)^Y; // X = ROTR(X-S[2*i],Y)^Y;
}
Out[j]=X - S[0]; //Out[j]=X - S[0];
Out[j+1]=Y - S[1]; //明文 Out[j+1]=Y - S[1];
}
}
/**7、 主函數測試
主函數
*/
int main(void)
{
unsigned int aa=0xffffFFF1;
unsigned int bb=0xffffFFF2;
unsigned int cc;
int k;
TWOBYTEINT ChildKeyS[2*12+2]; // r=12 子密鑰個數為26
TWOBYTEINT ChildKey1[26]; //
BYTE KeyK[16]; //8bit=byte 16=b 主密鑰共16字節
TWOBYTEINT Source[]={25142,1681,11561,5555}; //測試明文
TWOBYTEINT Dest[NoOfData]; //用來存儲密文
TWOBYTEINT Data[NoOfData]={0}; //用來存儲解密后的密文
InitialKey(KeyK,b);//生成初始密鑰
generateChildKey(KeyK,ChildKeyS); //根據初始密鑰生成子密鑰
printf(“加密以前的明文:”);
for (k=0;k《NoOfData;k++)
{
printf(“%.4lX ”,Source[k]); //16進制輸出
}
printf(“\n”);
for(k=0;k《26;k++)
{ //************************************有問題
ChildKey1[k]=ChildKeyS[k];//如果此處自定義簡單的數值為加密密鑰,則可以解密出密文
// printf(“%.4lX ”,ChildKey1[k]);
}
Encipher(Source,Dest,ChildKey1); //加密
printf(“\n”);
printf(“加密以后的密文:”);
for (k=0;k《NoOfData;k++)
{
printf(“%.4lX ”,Dest[k]);
}
printf(“\n”);
Decipher(Dest,Data,ChildKey1); //解密
printf(“解密以后的明文:”);
for (k=0;k《NoOfData;k++)
{
printf(“%.4lX ”,Data[k]);
}
printf(“\n”);
cc=aa+bb;
// printf(“\n%16X\n”,cc);
// printf(“%8X\n”,(cc-aa));
//printf(“sizeof unsigned short int: %d”,sizeof(unsigned short int));
// system(“pause\n”);
}
評論
查看更多