📄 haval.cpp
字号:
// haval.cpp - modified by Wei Dai from Yuliang Zheng's HAVAL.c
// distributed with Yuliang Zheng's permission
/*
* Reference:
* Y. Zheng, J. Pieprzyk and J. Seberry:
* ``HAVAL --- a one-way hashing algorithm with variable
* length of output'', Advances in Cryptology --- AUSCRYPT'92,
* Lecture Notes in Computer Science, Springer-Verlag, 1993.
*
* Author: Yuliang Zheng
* Department of Computer Science
* University of Wollongong
* Wollongong, NSW 2522, Australia
* Email: yuliang@cs.uow.edu.au
* Voice: +61 42 21 4331 (office)
*/
#include "pch.h"
#include "haval.h"
NAMESPACE_BEGIN(CryptoPP)
HAVAL::HAVAL(unsigned int digestSize, unsigned int pass)
: IteratedHash<word32>(DATASIZE, DIGESTSIZE),
digestSize(digestSize), pass(pass)
{
assert(digestSize >= 16 && digestSize <= 32 && digestSize%4==0);
assert(pass >= 3 && pass <= 5);
Init();
}
void HAVAL::Init()
{
countLo = countHi = 0;
digest[0] = 0x243F6A88;
digest[1] = 0x85A308D3;
digest[2] = 0x13198A2E;
digest[3] = 0x03707344;
digest[4] = 0xA4093822;
digest[5] = 0x299F31D0;
digest[6] = 0x082EFA98;
digest[7] = 0xEC4E6C89;
}
inline void HAVAL::vTransform(word32 *buf, const word32 *in)
{
if (pass==3)
HAVAL3::Transform(buf, in);
else if (pass==4)
HAVAL4::Transform(buf, in);
else
HAVAL5::Transform(buf, in);
}
void HAVAL::HashBlock(const word32 *input)
{
#ifdef IS_LITTLE_ENDIAN
vTransform(digest, input);
#else
byteReverse(data.ptr, input, (unsigned int)DATASIZE);
vTransform(digest, data);
#endif
}
void HAVAL::Final (byte *hash)
{
PadLastBlock(118, 1); // first byte of padding for HAVAL is 1 instead of 0x80
CorrectEndianess(data, data, 120);
data[29] &= 0xffff;
data[29] |= ((word32)digestSize<<25) | ((word32)pass<<19) | ((word32)VERSION<<16);
data[30] = countLo;
data[31] = countHi;
vTransform(digest, data);
Tailor(digestSize*8);
CorrectEndianess(digest, digest, digestSize);
memcpy(hash, digest, digestSize);
Init(); // reinit for next use
}
// tailor the last output
void HAVAL::Tailor(unsigned int FPTLEN)
{
word32 temp;
switch (FPTLEN)
{
case 128:
temp = (digest[7] & 0x000000FF) |
(digest[6] & 0xFF000000) |
(digest[5] & 0x00FF0000) |
(digest[4] & 0x0000FF00);
digest[0] += rotr(temp, 8U);
temp = (digest[7] & 0x0000FF00) |
(digest[6] & 0x000000FF) |
(digest[5] & 0xFF000000) |
(digest[4] & 0x00FF0000);
digest[1] += rotr(temp, 16U);
temp = (digest[7] & 0x00FF0000) |
(digest[6] & 0x0000FF00) |
(digest[5] & 0x000000FF) |
(digest[4] & 0xFF000000);
digest[2] += rotr(temp, 24U);
temp = (digest[7] & 0xFF000000) |
(digest[6] & 0x00FF0000) |
(digest[5] & 0x0000FF00) |
(digest[4] & 0x000000FF);
digest[3] += temp;
break;
case 160:
temp = (digest[7] & (word32)0x3F) |
(digest[6] & ((word32)0x7F << 25)) |
(digest[5] & ((word32)0x3F << 19));
digest[0] += rotr(temp, 19U);
temp = (digest[7] & ((word32)0x3F << 6)) |
(digest[6] & (word32)0x3F) |
(digest[5] & ((word32)0x7F << 25));
digest[1] += rotr(temp, 25U);
temp = (digest[7] & ((word32)0x7F << 12)) |
(digest[6] & ((word32)0x3F << 6)) |
(digest[5] & (word32)0x3F);
digest[2] += temp;
temp = (digest[7] & ((word32)0x3F << 19)) |
(digest[6] & ((word32)0x7F << 12)) |
(digest[5] & ((word32)0x3F << 6));
digest[3] += temp >> 6;
temp = (digest[7] & ((word32)0x7F << 25)) |
(digest[6] & ((word32)0x3F << 19)) |
(digest[5] & ((word32)0x7F << 12));
digest[4] += temp >> 12;
break;
case 192:
temp = (digest[7] & (word32)0x1F) |
(digest[6] & ((word32)0x3F << 26));
digest[0] += rotr(temp, 26U);
temp = (digest[7] & ((word32)0x1F << 5)) |
(digest[6] & (word32)0x1F);
digest[1] += temp;
temp = (digest[7] & ((word32)0x3F << 10)) |
(digest[6] & ((word32)0x1F << 5));
digest[2] += temp >> 5;
temp = (digest[7] & ((word32)0x1F << 16)) |
(digest[6] & ((word32)0x3F << 10));
digest[3] += temp >> 10;
temp = (digest[7] & ((word32)0x1F << 21)) |
(digest[6] & ((word32)0x1F << 16));
digest[4] += temp >> 16;
temp = (digest[7] & ((word32)0x3F << 26)) |
(digest[6] & ((word32)0x1F << 21));
digest[5] += temp >> 21;
break;
case 224:
digest[0] += (digest[7] >> 27) & 0x1F;
digest[1] += (digest[7] >> 22) & 0x1F;
digest[2] += (digest[7] >> 18) & 0x0F;
digest[3] += (digest[7] >> 13) & 0x1F;
digest[4] += (digest[7] >> 9) & 0x0F;
digest[5] += (digest[7] >> 4) & 0x1F;
digest[6] += digest[7] & 0x0F;
break;
case 256:
break;
default:
assert(false);
}
}
/*
#define f_1(x6, x5, x4, x3, x2, x1, x0) \
((x1) & ((x0) ^ (x4)) ^ (x2) & (x5) ^ \
(x3) & (x6) ^ (x0))
*/
#define f_1(x6, x5, x4, x3, x2, x1, x0) \
((x1&(x0^x4)) ^ (x2&x5) ^ (x3&x6) ^ x0)
/*
#define f_2(x6, x5, x4, x3, x2, x1, x0) \
((x2) & ((x1) & ~(x3) ^ (x4) & (x5) ^ (x6) ^ (x0)) ^ \
(x4) & ((x1) ^ (x5)) ^ (x3) & (x5) ^ (x0))
*/
#define f_2(x6, x5, x4, x3, x2, x1, x0) \
(((x4&x5)|x2) ^ (x0|x2) ^ (x2&((x1&~x3)^x6)) ^ (x3&x5) ^ (x1&x4))
/*
#define f_3(x6, x5, x4, x3, x2, x1, x0) \
((x3) & ((x1) & (x2) ^ (x6) ^ (x0)) ^ \
(x1) & (x4) ^ (x2) & (x5) ^ (x0))
*/
#define f_3(x6, x5, x4, x3, x2, x1, x0) \
((x3 & ((x1&x2) ^ x6 ^ x0)) ^ (x1&x4) ^ (x2&x5) ^ x0)
/*
#define f_4(x6, x5, x4, x3, x2, x1, x0) \
((x4) & ((x5) & ~(x2) ^ (x3) & ~(x6) ^ (x1) ^ (x6) ^ (x0)) ^ \
(x3) & ((x1) & (x2) ^ (x5) ^ (x6)) ^ \
(x2) & (x6) ^ (x0))
*/
#define f_4(x6, x5, x4, x3, x2, x1, x0) \
((((~x2&x5)^(x3|x6)^x1^x0)&x4) ^ (((x1&x2)^x5^x6)&x3) ^ (x2&x6) ^ x0)
/*
#define f_5(x6, x5, x4, x3, x2, x1, x0) \
((x0) & ((x1) & (x2) & (x3) ^ ~(x5)) ^ \
(x1) & (x4) ^ (x2) & (x5) ^ (x3) & (x6))
*/
#define f_5(x6, x5, x4, x3, x2, x1, x0) \
((((x0&x2&x3)^x4)&x1) ^ ((x0^x2)&x5) ^ (x3&x6) ^ x0)
/*
* Permutations phi_{i,j}, i=3,4,5, j=1,...,i.
*
* PASS = 3:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -