设计简单的块加密算法

来源:互联网 发布:淘宝网兼职刷单 编辑:程序博客网 时间:2024/05/14 20:42

这是一篇笔记,是kruglinski写的一篇密码学方面的笔记,转载请注明出处和作者,我发现一些CSDN的朋友拿去了就成了原创,强!国人的原创能力还真的不错啊!

这几天一直在思考密码学方面的东东,打算实现几个可以在驱动中使用的加密类,选定AES-256,TWOFISH-256和CAST-256算法,打算使用“工厂模式”来包装类的创建逻辑,这样在外部使用一个固定的接口,就可以使用不同的算法实现,这样在将来修改算法时外部调用代码不需要修改一行,改变的是实现而不是接口。别告诉我驱动里不可以使用C++,玩玩DriverWorks吧!

那么首先要设计这个基类,考虑再三,我觉得不能定义一个纯虚基类(抽像类),而是实现一个简单的xor加密的基类CCipher,然后由它派生出三种不同实现的块加密算法。最后由一个“工厂模式”来创建类的实例,外部只使用该“工厂模式”得到一个CCipher的指针,调用可“覆盖”(overrideble)的加密解密操作,便可以使用不同算法实现来对数据进行加密解密,根据这几天对密码学方面的研究,设计了这么一个简单的xor算法,主要还是运用了一点密码学经典理论“混乱和扩散”。

1. 简单的轮密钥变形/扩展算法
我将一个256 bit密钥按照8bit进行分组,分成32个基本运算单元(字节),然后按照8*4比例的矩阵进行简单变形构成15轮子密钥(加上原始密钥共16轮)。

假如初始密钥为:
12345678abcdefghijklmopqrstuvwxy
即:
1234
5678
abcd
efgh
ijkl
mopq
rstu
vwxy

置转成
15aeimrv26bfjosw37cgkptx48dhlquy

15ae
imrv
26bf
josw
37cg
kptx
48dh
lquy

向左移动8bit得到:
5aeimrv26bfjosw37cgkptx48dhlquy1

5aei
mrv2
6bfj
osw3
7cgk
ptx4
8dhl
quy1
构成第二轮子密钥,第三轮使用相同的算法由第二轮密钥计算得到,然后是第四轮,第五轮...加上初使密钥共十六轮子密钥。

2. 混乱和扩散
我设计了三组box,是由非常简单的算法生成的,前两组就是使用一个初使的256字节数组存储0,1,2,3,...,255,然后用随机数打乱它们生成s_box,再用生成的s_box计算生成反查表log_box,两组box具有互质特性,即:

p==log_box[s_box[p]]或者p==s_box[log_box[p]]也可。

还有一组p_box是用来将数据的bit位打乱,两两bit位相互交换,它的作用是将像10011001B这样的数据置换成01100110B,它具有这样的性质:
p=p_box[p_box[p]];

加密轮,每个加密轮使用p_box将128bit数据两两bit互换,然后使用s_box对数据进行非线性替换,然后交换左右两组数据(高8字节和低8字节),并将当前256bit的“轮密钥”分成两部分,128bit数据与128bit密钥左部进行xor操作,然后再次使用p_box将128bit数据两两bit进行交换,然后再使用反查表log_box再次进行数据的非线性替换,再交换左右两组数据,并与128位的密钥右部进行xor操作,致此一轮加密完成。

解密轮,就是加密轮的反向操作,但有一点需要注意的是应该先使用s_box进行查表,因为两组box是互质的,别忘记了这个特性认为加密最后使用了log_box,所以解密就要先使用log_box,那就理解错了,简单的数学概念。

3. 加密和解密
加密/解密就是用16个不同的轮密钥,调用轮函数16次进行加密/解密。算法非常简单主要就是和子密钥进行xor操作,但是运用了密码学的一些思想后,发现这个算法比我上大学时写的一个直接用密钥xor每个数据字节的算法要安全很多,呵呵!但比起成熟的块加密算法肯定是不行的。

4. 性能
每个数据byte与密钥byte的异或操作可以事先计算好一个256x256的矩阵xor_box,用state[i]=xor_box[state[i]][m_Subkey[index]],这样整个算法里就只有查表操作,因为有类似5 xor 9=9 xor 5这样的对称性,所以其实不需要256*256这么大的空间,可以用对称矩阵来存储((256+1)*256/2)。只是开发的前期为了可读性,我在算法里没有使用过多的代码优化技巧,加密/解密的16循环和轮操作里的循环都可以直接展开,加密/解密一步完成,因为轮函数比AES的轮函数简单很多,所以能想象到它的速度肯定是超过AES的。

5. 安全性/作用
本人不对该算法保证任何安全性,纯粹是做为编程时的一种缺省实现,顺便练习一下对块加密算法设计和理解程度,而且这个算法没有使用相关的加密操作模式(ECB,FCB...)。但这个算法的结构和很多经典的块加密算法很相像,对像我这样的密码学小鸟很有学习意义,如果完全理解了这个算法再看CAST、TWOFISH之类的算法时就会有似曾相识的感觉,呵呵!

6. 源代码,注意有三个“方法”是虚的,应该理解我为什么这么做吧。至于虚析构函数这是VC++的习惯,很有用,但在块加密算法包装类里我想应该作用不大。

// Cipher.h: interface for the CCipher class.
/********************************************************************
 created: 2007/01/25
 created: 25:1:2007   20:48
 filename:  C:/VcWork/crypto/Cipher.h
 file path: C:/VcWork/crypto
 file base: Cipher
 file ext: h
 author:  kruglinski(kruglinski@sohu.com)
 
 purpose: 类定义文件
 
   CCipher做为块加密算法基类,缺省提供简单的异或(xor)加密

   密钥长度:  256 位
   块长度:  128 位
*********************************************************************/

//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CIPHER_H__AB99010A_CF36_404D_8D95_B2EB8240B182__INCLUDED_)
#define AFX_CIPHER_H__AB99010A_CF36_404D_8D95_B2EB8240B182__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CCipher 
{
protected:
 unsigned char m_key[32];
 unsigned char m_SubKey[520];
 int m_KeyLength;

 void EnRound(unsigned char state[],int round);
 void DeRound(unsigned char state[],int round);
public:
 virtual void KeyExpand(void);
 virtual void Decrypt(unsigned char *c,unsigned char *p);
 virtual void Encrypt(unsigned char *p,unsigned char *c);
 void SetKey(unsigned char *pKey);
 CCipher();
 CCipher(unsigned char *pKey);
 virtual ~CCipher();

};

#endif // !defined(AFX_CIPHER_H__AB99010A_CF36_404D_8D95_B2EB8240B182__INCLUDED_)

// Cipher.cpp: implementation of the CCipher class.
/********************************************************************
 created: 2007/01/25
 created: 25:1:2007   20:48
 filename:  C:/VcWork/crypto/Cipher.cpp
 file path: C:/VcWork/crypto
 file base: Cipher
 file ext: cpp
 author:  kruglinski
 
 purpose: 类实现文件
 
   CCipher做为块加密算法基类,缺省提供简单的异或(xor)加密

   密钥长度:  256 位
   块长度:  128 位
*********************************************************************/

//////////////////////////////////////////////////////////////////////

#include "Cipher.h"
#include <string.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
static unsigned char s_box[256]=
{0xB5,0x3D,0xFF,0x06,0x2A,0x1C,0x0C,0xD2,0x9F,0xB9,0x0D,0x47,0x01,0x62,0x93,0x6F
,0x5E,0x72,0x09,0xD5,0x3C,0x65,0x9A,0xD7,0xCF,0x31,0xB1,0x49,0x8E,0xE0,0x9E,0x46
,0x58,0x69,0x5C,0x29,0x40,0xA8,0xD1,0xFB,0x59,0x4E,0x53,0x67,0x20,0x19,0xD6,0xF0
,0xCB,0x2D,0xB3,0xCA,0x91,0xC0,0x14,0x94,0xE1,0x1B,0x7A,0x66,0x7E,0x15,0xFA,0xF9
,0xA3,0x9C,0x0B,0x6C,0xDF,0x0E,0xD0,0x8A,0x23,0x22,0xF7,0x52,0x45,0x8B,0x39,0x24
,0xA0,0x55,0xB4,0x98,0xAF,0x37,0x08,0x4C,0x63,0x17,0x4D,0x85,0x4B,0x92,0x9D,0x6E
,0x10,0x68,0xEF,0x18,0x1E,0xA2,0x2E,0x0F,0x5B,0xB7,0x96,0xA6,0x7F,0x5A,0xBD,0x04
,0x34,0x99,0x2B,0x8D,0x1F,0xC7,0x74,0xDB,0xC2,0x86,0xE6,0x3F,0x13,0x41,0x61,0xA5
,0x6A,0x32,0x8C,0xFC,0x07,0xAC,0x00,0x28,0xB6,0x97,0x27,0xA9,0xA7,0xD8,0xDA,0x4A
,0xDC,0xF2,0x02,0xC4,0xCD,0x88,0x3A,0x70,0x8F,0x79,0x3B,0x44,0x87,0xE8,0xE7,0xB2
,0x26,0xF8,0xAE,0xE4,0xB8,0x56,0x95,0xB0,0x77,0x64,0x21,0x16,0xC8,0x80,0xC6,0x60
,0xF3,0xED,0xBE,0xFD,0x5F,0x03,0xC1,0x12,0x73,0x2C,0xEA,0xF4,0xEE,0x89,0x38,0xFE
,0xDD,0x75,0x05,0x0A,0xF6,0xE3,0xEB,0xA1,0x90,0xD9,0xBB,0x50,0x6D,0x51,0xCC,0x43
,0xE2,0x33,0xBA,0xA4,0xE5,0x4F,0xAD,0x6B,0x7C,0x7B,0xF1,0xBF,0xAA,0x78,0xCE,0xEC
,0xAB,0x36,0x1D,0x42,0xDE,0x3E,0xF5,0x25,0xD4,0x84,0x48,0x35,0xBC,0x82,0x54,0xC3
,0xC5,0x83,0x9B,0x1A,0xE9,0x76,0xD3,0x81,0x30,0x11,0x71,0x5D,0xC9,0x2F,0x57,0x7D
};

static unsigned char log_box[256]=
{0x86,0x0C,0x92,0xB5,0x6F,0xC2,0x03,0x84,0x56,0x12,0xC3,0x42,0x06,0x0A,0x45,0x67
,0x60,0xF9,0xB7,0x7C,0x36,0x3D,0xAB,0x59,0x63,0x2D,0xF3,0x39,0x05,0xE2,0x64,0x74
,0x2C,0xAA,0x49,0x48,0x4F,0xE7,0xA0,0x8A,0x87,0x23,0x04,0x72,0xB9,0x31,0x66,0xFD
,0xF8,0x19,0x81,0xD1,0x70,0xEB,0xE1,0x55,0xBE,0x4E,0x96,0x9A,0x14,0x01,0xE5,0x7B
,0x24,0x7D,0xE3,0xCF,0x9B,0x4C,0x1F,0x0B,0xEA,0x1B,0x8F,0x5C,0x57,0x5A,0x29,0xD5
,0xCB,0xCD,0x4B,0x2A,0xEE,0x51,0xA5,0xFE,0x20,0x28,0x6D,0x68,0x22,0xFB,0x10,0xB4
,0xAF,0x7E,0x0D,0x58,0xA9,0x15,0x3B,0x2B,0x61,0x21,0x80,0xD7,0x43,0xCC,0x5F,0x0F
,0x97,0xFA,0x11,0xB8,0x76,0xC1,0xF5,0xA8,0xDD,0x99,0x3A,0xD9,0xD8,0xFF,0x3C,0x6C
,0xAD,0xF7,0xED,0xF1,0xE9,0x5B,0x79,0x9C,0x95,0xBD,0x47,0x4D,0x82,0x73,0x1C,0x98
,0xC8,0x34,0x5D,0x0E,0x37,0xA6,0x6A,0x89,0x53,0x71,0x16,0xF2,0x41,0x5E,0x1E,0x08
,0x50,0xC7,0x65,0x40,0xD3,0x7F,0x6B,0x8C,0x25,0x8B,0xDC,0xE0,0x85,0xD6,0xA2,0x54
,0xA7,0x1A,0x9F,0x32,0x52,0x00,0x88,0x69,0xA4,0x09,0xD2,0xCA,0xEC,0x6E,0xB2,0xDB
,0x35,0xB6,0x78,0xEF,0x93,0xF0,0xAE,0x75,0xAC,0xFC,0x33,0x30,0xCE,0x94,0xDE,0x18
,0x46,0x26,0x07,0xF6,0xE8,0x13,0x2E,0x17,0x8D,0xC9,0x8E,0x77,0x90,0xC0,0xE4,0x44
,0x1D,0x38,0xD0,0xC5,0xA3,0xD4,0x7A,0x9E,0x9D,0xF4,0xBA,0xC6,0xDF,0xB1,0xBC,0x62
,0x2F,0xDA,0x91,0xB0,0xBB,0xE6,0xC4,0x4A,0xA1,0x3F,0x3E,0x27,0x83,0xB3,0xBF,0x02
};

static unsigned char p_box[256]=
{0x00,0x02,0x01,0x03,0x08,0x0A,0x09,0x0B,0x04,0x06,0x05,0x07,0x0C,0x0E,0x0D,0x0F
,0x20,0x22,0x21,0x23,0x28,0x2A,0x29,0x2B,0x24,0x26,0x25,0x27,0x2C,0x2E,0x2D,0x2F
,0x10,0x12,0x11,0x13,0x18,0x1A,0x19,0x1B,0x14,0x16,0x15,0x17,0x1C,0x1E,0x1D,0x1F
,0x30,0x32,0x31,0x33,0x38,0x3A,0x39,0x3B,0x34,0x36,0x35,0x37,0x3C,0x3E,0x3D,0x3F
,0x80,0x82,0x81,0x83,0x88,0x8A,0x89,0x8B,0x84,0x86,0x85,0x87,0x8C,0x8E,0x8D,0x8F
,0xA0,0xA2,0xA1,0xA3,0xA8,0xAA,0xA9,0xAB,0xA4,0xA6,0xA5,0xA7,0xAC,0xAE,0xAD,0xAF
,0x90,0x92,0x91,0x93,0x98,0x9A,0x99,0x9B,0x94,0x96,0x95,0x97,0x9C,0x9E,0x9D,0x9F
,0xB0,0xB2,0xB1,0xB3,0xB8,0xBA,0xB9,0xBB,0xB4,0xB6,0xB5,0xB7,0xBC,0xBE,0xBD,0xBF
,0x40,0x42,0x41,0x43,0x48,0x4A,0x49,0x4B,0x44,0x46,0x45,0x47,0x4C,0x4E,0x4D,0x4F
,0x60,0x62,0x61,0x63,0x68,0x6A,0x69,0x6B,0x64,0x66,0x65,0x67,0x6C,0x6E,0x6D,0x6F
,0x50,0x52,0x51,0x53,0x58,0x5A,0x59,0x5B,0x54,0x56,0x55,0x57,0x5C,0x5E,0x5D,0x5F
,0x70,0x72,0x71,0x73,0x78,0x7A,0x79,0x7B,0x74,0x76,0x75,0x77,0x7C,0x7E,0x7D,0x7F
,0xC0,0xC2,0xC1,0xC3,0xC8,0xCA,0xC9,0xCB,0xC4,0xC6,0xC5,0xC7,0xCC,0xCE,0xCD,0xCF
,0xE0,0xE2,0xE1,0xE3,0xE8,0xEA,0xE9,0xEB,0xE4,0xE6,0xE5,0xE7,0xEC,0xEE,0xED,0xEF
,0xD0,0xD2,0xD1,0xD3,0xD8,0xDA,0xD9,0xDB,0xD4,0xD6,0xD5,0xD7,0xDC,0xDE,0xDD,0xDF
,0xF0,0xF2,0xF1,0xF3,0xF8,0xFA,0xF9,0xFB,0xF4,0xF6,0xF5,0xF7,0xFC,0xFE,0xFD,0xFF
};

CCipher::CCipher():m_KeyLength(0)
{
 memset(m_key,0,sizeof(m_key));
 memset(m_SubKey,0,sizeof(m_SubKey));
}

CCipher::CCipher(unsigned char *pKey)
{
 memset(m_SubKey,0,sizeof(m_SubKey));
 memcpy(m_key,pKey,32);
 KeyExpand();
}

CCipher::~CCipher()
{

}

void CCipher::SetKey(unsigned char *pKey)
{
 memcpy(m_key,pKey,32);
 KeyExpand();
}

void CCipher::EnRound(unsigned char state[],int round)
{
 for(int i=0;i<16;i++)
 {
  state[i]=p_box[state[i]];
  state[i]=s_box[state[i]];
 }

 for(int shift=0;shift<8;shift++)
 {
  unsigned char tmp=state[shift];
  state[shift]=state[8+shift];
  state[8+shift]=tmp;
 }

 for(i=0;i<16;i++)
 {
  state[i]^=m_SubKey[round*32+i];
 }

 for(i=0;i<16;i++)
 {
  state[i]=p_box[state[i]];
  state[i]=log_box[state[i]];
 }

 for(shift=0;shift<8;shift++)
 {
  unsigned char tmp=state[shift];
  state[shift]=state[8+shift];
  state[8+shift]=tmp;
 }

 for(i=16;i<32;i++)
 {
  state[i-16]^=m_SubKey[round*32+i];
 }
}

void CCipher::DeRound(unsigned char state[],int round)
{
 for(int i=16;i<32;i++)
 {
  state[i-16]^=m_SubKey[(15-round)*32+i];
 }

 for(int shift=0;shift<8;shift++)
 {
  unsigned char tmp=state[shift];
  state[shift]=state[8+shift];
  state[8+shift]=tmp;
 }

 for(i=0;i<16;i++)
 {
  state[i]=s_box[state[i]];
  state[i]=p_box[state[i]];
 }

 for(i=0;i<16;i++)
 {
  state[i]^=m_SubKey[(15-round)*32+i];
 }

 for(shift=0;shift<8;shift++)
 {
  unsigned char tmp=state[shift];
  state[shift]=state[8+shift];
  state[8+shift]=tmp;
 }

 for(i=0;i<16;i++)
 {
  state[i]=log_box[state[i]];
  state[i]=p_box[state[i]];
 }
}

void CCipher::Encrypt(unsigned char *p, unsigned char *c)
{
 unsigned char state[16]={0};
 memcpy(state,p,16);

 for(int round=0;round<16;round++)
  EnRound(state,round);

 memcpy(c,state,16);
}

void CCipher::Decrypt(unsigned char *c, unsigned char *p)
{
 unsigned char state[16]={0};
 memcpy(state,c,16);

 for(int round=0;round<16;round++)
  DeRound(state,round);

 memcpy(p,state,16);
}

void CCipher::KeyExpand()
{
 memcpy(m_SubKey,m_key,32);

 for(int round=1;round<16;round++)
 {
  //置转
  for(int c=0;c<4;c++)
  {
   for(int i=0;i<8;i++)
   {
    m_SubKey[round*32+c*8+i]=m_SubKey[(round-1)*32+i*4+c];
   }
  }

  //移位,替换
  unsigned char tmp=s_box[p_box[m_SubKey[round*32]]];
  for(int shift=0;shift<31;shift++)
  {
   m_SubKey[round*32+shift]=s_box[p_box[m_SubKey[round*32+shift+1]]];
  }
  m_SubKey[round*32+shift]=tmp;
 }
}

 

7. 测试

测试代码:

#include <iostream>
#include "Cipher.h"

using namespace std;

void test(void)
{
 char *Key="123456789abcdefghijklmopqrstuvwx";
 CCipher cipher((unsigned char*)Key);
 
 unsigned char ciphertext[16]={0},Deciphertext[20]={0};
 
 char *plaintext="测试一下这个算法";
 
 printf("加密操作:/n");
 cipher.Encrypt((unsigned char*)plaintext,ciphertext);
 
 printf("解密操作:/n");
 cipher.Decrypt(ciphertext,Deciphertext);
}

int main(void)
{
 test();
 return 0;
}
加上些调试信息,使用"123456789abcdefghijklmopqrstuvwx"做为主Key,使用"测试一下这个算法"做为明文进行加密解密测试,得出如下结果:

加密操作:
Round 0:
Plaintext:      B2E2CAD4D2BBCFC2D5E2B8F6CBE3B7A8
Round key:      3132333435363738396162636465666768696A6B6C6D6F707172737475767778
Ciphertext:     A3AE89B2AB929CDAF9E07687140818AF

Round 1:
Plaintext:      A3AE89B2AB929CDAF9E07687140818AF
Round key:      7A148FCD87BEEA2D1B023B3AE7ED2CCA66F27988B2FDF4E191C44470F3735FB3
Ciphertext:     A95D6EA24C72B44034FB6E7F42120E42

Round 2:
Plaintext:      A95D6EA24C72B44034FB6E7F42120E42
Round key:      52FBBF7999EF1A59413DCE835790FD244F948EC130B660CC9EC0E3DFBAF38D03
Ciphertext:     36DEA3351F041BBF26C0038344E8DF8A

Round 3:
Plaintext:      36DEA3351F041BBF26C0038344E8DF8A
Round key:      2E8C164ACB5AC781ECFA105B86DD1AA5A851578BDCA439C1956CCF056DC306F8
Ciphertext:     8F03CC3CD5533E476809E328DFAF502D

Round 4:
Plaintext:      8F03CC3CD5533E476809E328DFAF502D
Round key:      A1AA22AFBC96E745567654AE63870A4E5058A8161443B9AC0BB04D8A050DE9E0
Ciphertext:     4AFF490B4D4D44DB4A9856D2DEB6917E

Round 5:
Plaintext:      4AFF490B4D4D44DB4A9856D2DEB6917E
Round key:      1364C42659D20D37B72C52B8FC349372BF771CAF74DAAD6E2792D84E4B0EE2B4
Ciphertext:     3512DB09591A5E8E4B921362D52BC44B

Round 6:
Plaintext:      3512DB09591A5E8E4B921362D52BC44B
Round key:      953FC9A57349288F368EE1F43E68629093F818209DDE3331661FED6EE8D8C229
Ciphertext:     118FB49B63EB15BB5AFFAB8EBD14B441

Round 7:
Plaintext:      118FB49B63EB15BB5AFFAB8EBD14B441
Round key:      FD1B1518BD79E5F9008BCDE982F0DEEB3CBAF240CACE754D2430105EB3E89A96
Ciphertext:     B90E958977E55CB5DA417B066C88A344

Round 8:
Plaintext:      B90E958977E55CB5DA417B066C88A344
Round key:      61B59C7EE3CF8DFBC18AC5C751CBE553F1CC8283EA58A240D3AD6B6ADA80B757
Ciphertext:     CB24C2F187B3C67A874C315A89ACB34B

Round 9:
Plaintext:      CB24C2F187B3C67A874C315A89ACB34B
Round key:      A405AE9B4F423EE6430EA16DB89DA37F39BBF19C55703F898150E46C6A881602
Ciphertext:     1FC36CA3465C3F65BE9D82B2658BAE96

Round 10:
Plaintext:      1FC36CA3465C3F65BE9D82B2658BAE96
Round key:      4AFC1F14210B880D3262BDDBF326DF9215B4989BF97C4E0F7BE7FE7FD0873D63
Ciphertext:     A383736AAABC63AAFF0A31563764DAA2

Round 11:
Plaintext:      A383736AAABC63AAFF0A31563764DAA2
Round key:      092D1A53D312ABC9D2F231C2EEBF52F0DF61C31ED82FFA599325680F6FFEC4AC
Ciphertext:     84AD0D45A20DDB6937A4CD9555A144EF

Round 12:
Plaintext:      84AD0D45A20DDB6937A4CD9555A144EF
Round key:      423678C3DE18B29E6983A50246B12FA84CB3F80A76CD90E4EB75C519956F4B0C
Ciphertext:     1782B6F93E34529A88A918C5974D1D16

Round 13:
Plaintext:      1782B6F93E34529A88A918C5974D1D16
Round key:      823A97A72C6B961B406C2B8DCCEAB25F994D46E910BB280A5A3DAF1C7CD10132
Ciphertext:     A062563F6A3F73B5F82469A530C0ACEE

Round 14:
Plaintext:      A062563F6A3F73B5F82469A530C0ACEE
Round key:      8E6A6D2E5856EEC070874FDADBFA1DA6B7D799973C6EFF85FB3960AD1C202D9C
Ciphertext:     AA05C0EB7CDBB928095480A3442B40EA

Round 15:
Plaintext:      AA05C0EB7CDBB928095480A3442B40EA
Round key:      B8F3253F7E81208864527635E8145EE7784AD62E7DDC9EE0DD3E17A6F79D7F8B
Ciphertext:     381E28F86F5DA37E00D40CCE641624BB

解密操作:
Round 0:
Ciphertext:     381E28F86F5DA37E00D40CCE641624BB
Round key:      B8F3253F7E81208864527635E8145EE7784AD62E7DDC9EE0DD3E17A6F79D7F8B
Plaintext:      AA05C0EB7CDBB928095480A3442B40EA

Round 1:
Ciphertext:     AA05C0EB7CDBB928095480A3442B40EA
Round key:      8E6A6D2E5856EEC070874FDADBFA1DA6B7D799973C6EFF85FB3960AD1C202D9C
Plaintext:      A062563F6A3F73B5F82469A530C0ACEE

Round 2:
Ciphertext:     A062563F6A3F73B5F82469A530C0ACEE
Round key:      823A97A72C6B961B406C2B8DCCEAB25F994D46E910BB280A5A3DAF1C7CD10132
Plaintext:      1782B6F93E34529A88A918C5974D1D16

Round 3:
Ciphertext:     1782B6F93E34529A88A918C5974D1D16
Round key:      423678C3DE18B29E6983A50246B12FA84CB3F80A76CD90E4EB75C519956F4B0C
Plaintext:      84AD0D45A20DDB6937A4CD9555A144EF

Round 4:
Ciphertext:     84AD0D45A20DDB6937A4CD9555A144EF
Round key:      092D1A53D312ABC9D2F231C2EEBF52F0DF61C31ED82FFA599325680F6FFEC4AC
Plaintext:      A383736AAABC63AAFF0A31563764DAA2

Round 5:
Ciphertext:     A383736AAABC63AAFF0A31563764DAA2
Round key:      4AFC1F14210B880D3262BDDBF326DF9215B4989BF97C4E0F7BE7FE7FD0873D63
Plaintext:      1FC36CA3465C3F65BE9D82B2658BAE96

Round 6:
Ciphertext:     1FC36CA3465C3F65BE9D82B2658BAE96
Round key:      A405AE9B4F423EE6430EA16DB89DA37F39BBF19C55703F898150E46C6A881602
Plaintext:      CB24C2F187B3C67A874C315A89ACB34B

Round 7:
Ciphertext:     CB24C2F187B3C67A874C315A89ACB34B
Round key:      61B59C7EE3CF8DFBC18AC5C751CBE553F1CC8283EA58A240D3AD6B6ADA80B757
Plaintext:      B90E958977E55CB5DA417B066C88A344

Round 8:
Ciphertext:     B90E958977E55CB5DA417B066C88A344
Round key:      FD1B1518BD79E5F9008BCDE982F0DEEB3CBAF240CACE754D2430105EB3E89A96
Plaintext:      118FB49B63EB15BB5AFFAB8EBD14B441

Round 9:
Ciphertext:     118FB49B63EB15BB5AFFAB8EBD14B441
Round key:      953FC9A57349288F368EE1F43E68629093F818209DDE3331661FED6EE8D8C229
Plaintext:      3512DB09591A5E8E4B921362D52BC44B

Round 10:
Ciphertext:     3512DB09591A5E8E4B921362D52BC44B
Round key:      1364C42659D20D37B72C52B8FC349372BF771CAF74DAAD6E2792D84E4B0EE2B4
Plaintext:      4AFF490B4D4D44DB4A9856D2DEB6917E

Round 11:
Ciphertext:     4AFF490B4D4D44DB4A9856D2DEB6917E
Round key:      A1AA22AFBC96E745567654AE63870A4E5058A8161443B9AC0BB04D8A050DE9E0
Plaintext:      8F03CC3CD5533E476809E328DFAF502D

Round 12:
Ciphertext:     8F03CC3CD5533E476809E328DFAF502D
Round key:      2E8C164ACB5AC781ECFA105B86DD1AA5A851578BDCA439C1956CCF056DC306F8
Plaintext:      36DEA3351F041BBF26C0038344E8DF8A

Round 13:
Ciphertext:     36DEA3351F041BBF26C0038344E8DF8A
Round key:      52FBBF7999EF1A59413DCE835790FD244F948EC130B660CC9EC0E3DFBAF38D03
Plaintext:      A95D6EA24C72B44034FB6E7F42120E42

Round 14:
Ciphertext:     A95D6EA24C72B44034FB6E7F42120E42
Round key:      7A148FCD87BEEA2D1B023B3AE7ED2CCA66F27988B2FDF4E191C44470F3735FB3
Plaintext:      A3AE89B2AB929CDAF9E07687140818AF

Round 15:
Ciphertext:     A3AE89B2AB929CDAF9E07687140818AF
Round key:      3132333435363738396162636465666768696A6B6C6D6F707172737475767778
Plaintext:      B2E2CAD4D2BBCFC2D5E2B8F6CBE3B7A8
Press any key to continue

B2E2CAD4D2BBCFC2D5E2B8F6CBE3B7A8就是“测试一下这个算法”字符串的十六进制形式(不包括0终止),并且可以看到我设计的这个简单的密钥扩展算法生成的16轮子密钥质量还不错,分布的很均匀,而且没有碰撞。呵呵!

8. 写在最后,我是一个密码学初学者,请广大的密码学老鸟批评指正,以便我提高密码学方面的水平。妈的,这几天时差倒过来了睡不着,乱写了些东西。在中国还玩美国时间!哈哈哈!!!

9. 联系方式,Email:kruginski@sohu.com;Blog:http://kruglinski.bokee.com/

参考资料:
google里找到的,
2002-2003年度北京大学工程硕士研究生课程-《网络与信息安全》(王昭)北京大学计算机系信息安全研究室

SP网络和Feistel密码