Hash散列算法详细解析(六)

 

关键词whirlpool                                          

 

      Whirlpool算法被列入了ISO标准。主要原因是因为其强大的安全度。第一点,Whirlpool使用了和AES加密标准相同的转化技术,只不过,AES使用的模函数为:f(x) = x^8 + x^4 + x^3 + x + 1, 即0x11B;而Whirlpool使用的是:f(x) = x^8 + x^4 + x^3 + x^2 + 1, 即0x11D。第二点,Whirlpool的输出是512位的。为了加快计算速度,Whirlpool使用的所有表格都已经时间计算好了。Whirlpool在历史上共有3个版本,根据最新的2003年版本,我们把目前的Whirlpool算法叫做Whirlpool 3.0。

      以下是其具体代码实现。

#ifndef Goodzzp_WhirlPool_05_10_22_13
#define Goodzzp_WhirlPool_05_10_22_13

//whirlPool 3.0(2003,3)
//program by Goodzzp
//05,10,22
//referred:
//http://planeta.terra.com.br/informatica/paulobarreto/whirlpool.zip
//this document revised at 2003,5

#include "define.h"

//...begin whirlpool 3.0
#define R 10
#define LL(v)   (v##i64)

class WhirlPool
{
public:
 //输出结果的长度(字节)
 static UI32 OutDataLength()
 {
  return 512/8;
 }
 //WhirlPool变换函数
 //out:输出,长度为64,要求事先已经分配了内存
 //in:输入
 //length:输入值的长度
 //说明:Whirlpool使用256位来表示数据长度。
 void Hash(UI8 *out,const UI8 *in,UI32 length)
 {
  UI32 i = length>>6,j=(length&0x3f),k;
  //对数据64 64个字节的计算
  for(k=0;k  {
   StepTransform((UI8 *)(in + k * 64),64,length);
  }
  //最后计算尾数
  StepTransform((UI8 *)(in + 64 * i),j,length);
  //拷贝输出
  for(i=0;i<8;i++) //反转
  {
   m_state[i] = ((m_state[i]&0xff) << 56) | ((m_state[i]&0xff00) << 40) |
    ((m_state[i]&0xff0000) << 24) | ((m_state[i]&0xff000000) << 8) |
    ((m_state[i]&0xff00000000) >> 8) | ((m_state[i]&0xff0000000000) >> 24) |
    ((m_state[i]&0xff000000000000) >> 40) | ((m_state[i]&0xff00000000000000) >> 56);;
  }
  memcpy(out,m_state,64);
  //恢复初始值
  m_state[0] = 0;
  m_state[1] = 0;
  m_state[2] = 0;
  m_state[3] = 0;
  m_state[4] = 0;
  m_state[5] = 0;
  m_state[6] = 0;
  m_state[7] = 0;
 }
 WhirlPool() //initialize data
 {
  m_state[0] = 0;
  m_state[1] = 0;
  m_state[2] = 0;
  m_state[3] = 0;
  m_state[4] = 0;
  m_state[5] = 0;
  m_state[6] = 0;
  m_state[7] = 0;
 }
private:
 //每步的变换函数
 //输入:
 //  data:   要处理的数据块(不大于64字节)
 //  dataBlockLen: 数据块的长度
 //  dataTotalLen: 要处理的所有数据块的总长度
 //输出结果保存在m_state里面
 void StepTransform(UI8 *data,UI32 dataBlockLen, UI32 dataTotalLen)
 {
  UI8 buffer[64];
  UI32 len=dataTotalLen*8;
  
  memset(buffer,0,64);//清空数据为0
  memcpy(buffer,data,dataBlockLen);//拷贝数据到缓冲
  
  if(dataBlockLen <64) //需要增加数据
  {
   if(dataBlockLen<32)//当前数据是最后若干个,而且不需要增加一次变换
   {
    //添加1和0
    buffer[dataBlockLen]=0x80;
    //添加长度
    buffer[63]=(UI8)(len&0xff);
    len>>=8;
    buffer[62]=(UI8)(len&0xff);
    len>>=8;
    buffer[61]=(UI8)(len&0xff);
    len>>=8;
    buffer[60]=(UI8)(len&0xff);
    len>>=8;
    buffer[59]=(UI8)(len&0xff);
    //变换
    FirstTransform((UI32*)buffer);
    CoreTransform();
   }
   else if(dataBlockLen>=32)
   {
    //添加1和0
    buffer[dataBlockLen]=0x80;
    //变换
    FirstTransform((UI32*)buffer);
    CoreTransform();
    //添加长度
    memset(buffer,0,64);
    buffer[63]=(UI8)(len&0xff);
    len>>=8;
    buffer[62]=(UI8)(len&0xff);
    len>>=8;
    buffer[61]=(UI8)(len&0xff);
    len>>=8;
    buffer[60]=(UI8)(len&0xff);
    len>>=8;
    buffer[59]=(UI8)(len&0xff);
    //变换
    FirstTransform((UI32*)buffer);
    CoreTransform();
   }
  }
  else if(dataBlockLen == 64)
  {
   //变换
   FirstTransform((UI32*)buffer);
   CoreTransform();
  }
 }

 //把64字节的原始数据data进行初步转化到m_data中去
 void FirstTransform(UI32 *data)
 {
  //拷贝
  memcpy(m_data,data,64);
 }
 
 //核心变换
 void CoreTransform()
 {
  UI32 i, r;
  UI64 K[8];        /* the round key */
  UI64 block[8];    /* mu(buffer) */
  UI64 state[8];    /* the cipher state */
  UI64 L[8];
  UI8 *buffer = m_data;
  /*
   * map the buffer to a block:
   */
  for (i = 0; i < 8; i++, buffer += 8) {
   block[i] =
    (((UI64)buffer[0]        ) << 56) ^
    (((UI64)buffer[1] & 0xffL) << 48) ^
    (((UI64)buffer[2] & 0xffL) << 40) ^
    (((UI64)buffer[3] & 0xffL) << 32) ^
    (((UI64)buffer[4] & 0xffL) << 24) ^
    (((UI64)buffer[5] & 0xffL) << 16) ^
    (((UI64)buffer[6] & 0xffL) <<  8) ^
    (((UI64)buffer[7] & 0xffL)      );
  }
  /*
   * compute and apply K^0 to the cipher state:
   */
  state[0] = block[0] ^ (K[0] = m_state[0]);
  state[1] = block[1] ^ (K[1] = m_state[1]);
  state[2] = block[2] ^ (K[2] = m_state[2]);
  state[3] = block[3] ^ (K[3] = m_state[3]);
  state[4] = block[4] ^ (K[4] = m_state[4]);
  state[5] = block[5] ^ (K[5] = m_state[5]);
  state[6] = block[6] ^ (K[6] = m_state[6]);
  state[7] = block[7] ^ (K[7] = m_state[7]);
  /*
   * iterate over all rounds:
   */
  for (r = 1; r <= R; r++) {
   /*
    * compute K^r from K^{r-1}:
    */
   L[0] =
    C0[(UI32)(K[0] >> 56)       ] ^
    C1[(UI32)(K[7] >> 48) & 0xff] ^
    C2[(UI32)(K[6] >> 40) & 0xff] ^
    C3[(UI32)(K[5] >> 32) & 0xff] ^
    C4[(UI32)(K[4] >> 24) & 0xff] ^
    C5[(UI32)(K[3] >> 16) & 0xff] ^
    C6[(UI32)(K[2] >>  8) & 0xff] ^
    C7[(UI32)(K[1]      ) & 0xff] ^
    rc[r];
   L[1] =
    C0[(UI32)(K[1] >> 56)       ] ^
    C1[(UI32)(K[0] >> 48) & 0xff] ^
    C2[(UI32)(K[7] >> 40) & 0xff] ^
    C3[(UI32)(K[6] >> 32) & 0xff] ^
    C4[(UI32)(K[5] >> 24) & 0xff] ^
    C5[(UI32)(K[4] >> 16) & 0xff] ^
    C6[(UI32)(K[3] >>  8) & 0xff] ^
    C7[(UI32)(K[2]      ) & 0xff];
   L[2] =
    C0[(UI32)(K[2] >> 56)       ] ^
    C1[(UI32)(K[1] >> 48) & 0xff] ^
    C2[(UI32)(K[0] >> 40) & 0xff] ^
    C3[(UI32)(K[7] >> 32) & 0xff] ^
    C4[(UI32)(K[6] >> 24) & 0xff] ^
    C5[(UI32)(K[5] >> 16) & 0xff] ^
    C6[(UI32)(K[4] >>  8) & 0xff] ^
    C7[(UI32)(K[3]      ) & 0xff];
   L[3] =
    C0[(UI32)(K[3] >> 56)       ] ^
    C1[(UI32)(K[2] >> 48) & 0xff] ^
    C2[(UI32)(K[1] >> 40) & 0xff] ^
    C3[(UI32)(K[0] >> 32) & 0xff] ^
    C4[(UI32)(K[7] >> 24) & 0xff] ^
    C5[(UI32)(K[6] >> 16) & 0xff] ^
    C6[(UI32)(K[5] >>  8) & 0xff] ^
    C7[(UI32)(K[4]      ) & 0xff];
   L[4] =
    C0[(UI32)(K[4] >> 56)       ] ^
    C1[(UI32)(K[3] >> 48) & 0xff] ^
    C2[(UI32)(K[2] >> 40) & 0xff] ^
    C3[(UI32)(K[1] >> 32) & 0xff] ^
    C4[(UI32)(K[0] >> 24) & 0xff] ^
    C5[(UI32)(K[7] >> 16) & 0xff] ^
    C6[(UI32)(K[6] >>  8) & 0xff] ^
    C7[(UI32)(K[5]      ) & 0xff];
   L[5] =
    C0[(UI32)(K[5] >> 56)       ] ^
    C1[(UI32)(K[4] >> 48) & 0xff] ^
    C2[(UI32)(K[3] >> 40) & 0xff] ^
    C3[(UI32)(K[2] >> 32) & 0xff] ^
    C4[(UI32)(K[1] >> 24) & 0xff] ^
    C5[(UI32)(K[0] >> 16) & 0xff] ^
    C6[(UI32)(K[7] >>  8) & 0xff] ^
    C7[(UI32)(K[6]      ) & 0xff];
   L[6] =
    C0[(UI32)(K[6] >> 56)       ] ^
    C1[(UI32)(K[5] >> 48) & 0xff] ^
    C2[(UI32)(K[4] >> 40) & 0xff] ^
    C3[(UI32)(K[3] >> 32) & 0xff] ^
    C4[(UI32)(K[2] >> 24) & 0xff] ^
    C5[(UI32)(K[1] >> 16) & 0xff] ^
    C6[(UI32)(K[0] >>  8) & 0xff] ^
    C7[(UI32)(K[7]      ) & 0xff];
   L[7] =
    C0[(UI32)(K[7] >> 56)       ] ^
    C1[(UI32)(K[6] >> 48) & 0xff] ^
    C2[(UI32)(K[5] >> 40) & 0xff] ^
    C3[(UI32)(K[4] >> 32) & 0xff] ^
    C4[(UI32)(K[3] >> 24) & 0xff] ^
    C5[(UI32)(K[2] >> 16) & 0xff] ^
    C6[(UI32)(K[1] >>  8) & 0xff] ^
    C7[(UI32)(K[0]      ) & 0xff];
   K[0] = L[0];
   K[1] = L[1];
   K[2] = L[2];
   K[3] = L[3];
   K[4] = L[4];
   K[5] = L[5];
   K[6] = L[6];
   K[7] = L[7];
   /*
    * apply the r-th round transformation:
    */
   L[0] =
    C0[(UI32)(state[0] >> 56)       ] ^
    C1[(UI32)(state[7] >> 48) & 0xff] ^
    C2[(UI32)(state[6] >> 40) & 0xff] ^
    C3[(UI32)(state[5] >> 32) & 0xff] ^
    C4[(UI32)(state[4] >> 24) & 0xff] ^
    C5[(UI32)(state[3] >> 16) & 0xff] ^
    C6[(UI32)(state[2] >>  8) & 0xff] ^
    C7[(UI32)(state[1]      ) & 0xff] ^
    K[0];
   L[1] =
    C0[(UI32)(state[1] >> 56)       ] ^
    C1[(UI32)(state[0] >> 48) & 0xff] ^
    C2[(UI32)(state[7] >> 40) & 0xff] ^
    C3[(UI32)(state[6] >> 32) & 0xff] ^
    C4[(UI32)(state[5] >> 24) & 0xff] ^
    C5[(UI32)(state[4] >> 16) & 0xff] ^
    C6[(UI32)(state[3] >>  8) & 0xff] ^
    C7[(UI32)(state[2]      ) & 0xff] ^
    K[1];
   L[2] =
    C0[(UI32)(state[2] >> 56)       ] ^
    C1[(UI32)(state[1] >> 48) & 0xff] ^
    C2[(UI32)(state[0] >> 40) & 0xff] ^
    C3[(UI32)(state[7] >> 32) & 0xff] ^
    C4[(UI32)(state[6] >> 24) & 0xff] ^
    C5[(UI32)(state[5] >> 16) & 0xff] ^
    C6[(UI32)(state[4] >>  8) & 0xff] ^
    C7[(UI32)(state[3]      ) & 0xff] ^
    K[2];
   L[3] =
    C0[(UI32)(state[3] >> 56)       ] ^
    C1[(UI32)(state[2] >> 48) & 0xff] ^
    C2[(UI32)(state[1] >> 40) & 0xff] ^
    C3[(UI32)(state[0] >> 32) & 0xff] ^
    C4[(UI32)(state[7] >> 24) & 0xff] ^
    C5[(UI32)(state[6] >> 16) & 0xff] ^
    C6[(UI32)(state[5] >>  8) & 0xff] ^
    C7[(UI32)(state[4]      ) & 0xff] ^
    K[3];
   L[4] =
    C0[(UI32)(state[4] >> 56)       ] ^
    C1[(UI32)(state[3] >> 48) & 0xff] ^
    C2[(UI32)(state[2] >> 40) & 0xff] ^
    C3[(UI32)(state[1] >> 32) & 0xff] ^
    C4[(UI32)(state[0] >> 24) & 0xff] ^
    C5[(UI32)(state[7] >> 16) & 0xff] ^
    C6[(UI32)(state[6] >>  8) & 0xff] ^
    C7[(UI32)(state[5]      ) & 0xff] ^
    K[4];
   L[5] =
    C0[(UI32)(state[5] >> 56)       ] ^
    C1[(UI32)(state[4] >> 48) & 0xff] ^
    C2[(UI32)(state[3] >> 40) & 0xff] ^
    C3[(UI32)(state[2] >> 32) & 0xff] ^
    C4[(UI32)(state[1] >> 24) & 0xff] ^
    C5[(UI32)(state[0] >> 16) & 0xff] ^
    C6[(UI32)(state[7] >>  8) & 0xff] ^
    C7[(UI32)(state[6]      ) & 0xff] ^
    K[5];
   L[6] =
    C0[(UI32)(state[6] >> 56)       ] ^
    C1[(UI32)(state[5] >> 48) & 0xff] ^
    C2[(UI32)(state[4] >> 40) & 0xff] ^
    C3[(UI32)(state[3] >> 32) & 0xff] ^
    C4[(UI32)(state[2] >> 24) & 0xff] ^
    C5[(UI32)(state[1] >> 16) & 0xff] ^
    C6[(UI32)(state[0] >>  8) & 0xff] ^
    C7[(UI32)(state[7]      ) & 0xff] ^
    K[6];
   L[7] =
    C0[(UI32)(state[7] >> 56)       ] ^
    C1[(UI32)(state[6] >> 48) & 0xff] ^
    C2[(UI32)(state[5] >> 40) & 0xff] ^
    C3[(UI32)(state[4] >> 32) & 0xff] ^
    C4[(UI32)(state[3] >> 24) & 0xff] ^
    C5[(UI32)(state[2] >> 16) & 0xff] ^
    C6[(UI32)(state[1] >>  8) & 0xff] ^
    C7[(UI32)(state[0]      ) & 0xff] ^<

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值