Mercurial > vba-linux
view src/win32/7zip/7z/CPP/7zip/Crypto/Sha1.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line source
1 // Crypto/Sha1.cpp2 // This file is based on public domain3 // Steve Reid and Wei Dai's code from Crypto++5 #include "StdAfx.h"7 #include "Sha1.h"8 extern "C"9 {10 #include "../../../C/RotateDefs.h"11 }13 namespace NCrypto {14 namespace NSha1 {16 // define it for speed optimization17 // #define _SHA1_UNROLL19 static const unsigned kNumW =20 #ifdef _SHA1_UNROLL21 16;22 #else23 80;24 #endif27 #define w0(i) (W[(i)] = data[(i)])29 #ifdef _SHA1_UNROLL30 #define w1(i) (W[(i)&15] = rotlFixed(W[((i)-3)&15] ^ W[((i)-8)&15] ^ W[((i)-14)&15] ^ W[((i)-16)&15], 1))31 #else32 #define w1(i) (W[(i)] = rotlFixed(W[(i)-3] ^ W[(i)-8] ^ W[(i)-14] ^ W[(i)-16], 1))33 #endif35 #define f1(x,y,z) (z^(x&(y^z)))36 #define f2(x,y,z) (x^y^z)37 #define f3(x,y,z) ((x&y)|(z&(x|y)))38 #define f4(x,y,z) (x^y^z)40 #define RK1(a,b,c,d,e,i, f, w, k) e += f(b,c,d) + w(i) + k + rotlFixed(a,5); b = rotlFixed(b,30);42 #define R0(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w0, 0x5A827999)43 #define R1(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w1, 0x5A827999)44 #define R2(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f2, w1, 0x6ED9EBA1)45 #define R3(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f3, w1, 0x8F1BBCDC)46 #define R4(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f4, w1, 0xCA62C1D6)48 #define RX_1_4(rx1, rx4, i) rx1(a,b,c,d,e,i); rx4(e,a,b,c,d,i+1); rx4(d,e,a,b,c,i+2); rx4(c,d,e,a,b,i+3); rx4(b,c,d,e,a,i+4);49 #define RX_5(rx, i) RX_1_4(rx, rx, i);51 void CContextBase::Init()52 {53 _state[0] = 0x67452301;54 _state[1] = 0xEFCDAB89;55 _state[2] = 0x98BADCFE;56 _state[3] = 0x10325476;57 _state[4] = 0xC3D2E1F0;58 _count = 0;59 }61 void CContextBase::GetBlockDigest(UInt32 *data, UInt32 *destDigest, bool returnRes)62 {63 UInt32 a, b, c, d, e;64 UInt32 W[kNumW];66 a = _state[0];67 b = _state[1];68 c = _state[2];69 d = _state[3];70 e = _state[4];71 #ifdef _SHA1_UNROLL72 RX_5(R0, 0); RX_5(R0, 5); RX_5(R0, 10);73 #else74 int i;75 for (i = 0; i < 15; i += 5) { RX_5(R0, i); }76 #endif78 RX_1_4(R0, R1, 15);81 #ifdef _SHA1_UNROLL82 RX_5(R2, 20); RX_5(R2, 25); RX_5(R2, 30); RX_5(R2, 35);83 RX_5(R3, 40); RX_5(R3, 45); RX_5(R3, 50); RX_5(R3, 55);84 RX_5(R4, 60); RX_5(R4, 65); RX_5(R4, 70); RX_5(R4, 75);85 #else86 i = 20;87 for (; i < 40; i += 5) { RX_5(R2, i); }88 for (; i < 60; i += 5) { RX_5(R3, i); }89 for (; i < 80; i += 5) { RX_5(R4, i); }90 #endif92 destDigest[0] = _state[0] + a;93 destDigest[1] = _state[1] + b;94 destDigest[2] = _state[2] + c;95 destDigest[3] = _state[3] + d;96 destDigest[4] = _state[4] + e;98 if (returnRes)99 for (int i = 0 ; i < 16; i++)100 data[i] = W[kNumW - 16 + i];102 // Wipe variables103 // a = b = c = d = e = 0;104 }106 void CContextBase::PrepareBlock(UInt32 *block, unsigned size) const107 {108 unsigned curBufferPos = size & 0xF;109 block[curBufferPos++] = 0x80000000;110 while (curBufferPos != (16 - 2))111 block[curBufferPos++] = 0;112 const UInt64 lenInBits = (_count << 9) + ((UInt64)size << 5);113 block[curBufferPos++] = (UInt32)(lenInBits >> 32);114 block[curBufferPos++] = (UInt32)(lenInBits);115 }117 void CContext::Update(Byte *data, size_t size, bool rar350Mode)118 {119 bool returnRes = false;120 unsigned curBufferPos = _count2;121 while (size-- > 0)122 {123 int pos = (int)(curBufferPos & 3);124 if (pos == 0)125 _buffer[curBufferPos >> 2] = 0;126 _buffer[curBufferPos >> 2] |= ((UInt32)*data++) << (8 * (3 - pos));127 if (++curBufferPos == kBlockSize)128 {129 curBufferPos = 0;130 CContextBase::UpdateBlock(_buffer, returnRes);131 if (returnRes)132 for (int i = 0; i < kBlockSizeInWords; i++)133 {134 UInt32 d = _buffer[i];135 data[i * 4 + 0 - kBlockSize] = (Byte)(d);136 data[i * 4 + 1 - kBlockSize] = (Byte)(d >> 8);137 data[i * 4 + 2 - kBlockSize] = (Byte)(d >> 16);138 data[i * 4 + 3 - kBlockSize] = (Byte)(d >> 24);139 }140 returnRes = rar350Mode;141 }142 }143 _count2 = curBufferPos;144 }146 void CContext::Final(Byte *digest)147 {148 const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 3);149 unsigned curBufferPos = _count2;150 int pos = (int)(curBufferPos & 3);151 curBufferPos >>= 2;152 if (pos == 0)153 _buffer[curBufferPos] = 0;154 _buffer[curBufferPos++] |= ((UInt32)0x80) << (8 * (3 - pos));156 while (curBufferPos != (16 - 2))157 {158 curBufferPos &= 0xF;159 if (curBufferPos == 0)160 UpdateBlock();161 _buffer[curBufferPos++] = 0;162 }163 _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32);164 _buffer[curBufferPos++] = (UInt32)(lenInBits);165 UpdateBlock();167 int i;168 for (i = 0; i < kDigestSizeInWords; i++)169 {170 UInt32 state = _state[i] & 0xFFFFFFFF;171 *digest++ = (Byte)(state >> 24);172 *digest++ = (Byte)(state >> 16);173 *digest++ = (Byte)(state >> 8);174 *digest++ = (Byte)(state);175 }176 Init();177 }179 ///////////////////////////180 // Words version182 void CContext32::Update(const UInt32 *data, size_t size)183 {184 while (size-- > 0)185 {186 _buffer[_count2++] = *data++;187 if (_count2 == kBlockSizeInWords)188 {189 _count2 = 0;190 UpdateBlock();191 }192 }193 }195 void CContext32::Final(UInt32 *digest)196 {197 const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 5);198 unsigned curBufferPos = _count2;199 _buffer[curBufferPos++] = 0x80000000;200 while (curBufferPos != (16 - 2))201 {202 curBufferPos &= 0xF;203 if (curBufferPos == 0)204 UpdateBlock();205 _buffer[curBufferPos++] = 0;206 }207 _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32);208 _buffer[curBufferPos++] = (UInt32)(lenInBits);209 GetBlockDigest(_buffer, digest);210 Init();211 }213 }}