annotate 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
rev   line source
rlm@1 1 // Crypto/Sha1.cpp
rlm@1 2 // This file is based on public domain
rlm@1 3 // Steve Reid and Wei Dai's code from Crypto++
rlm@1 4
rlm@1 5 #include "StdAfx.h"
rlm@1 6
rlm@1 7 #include "Sha1.h"
rlm@1 8 extern "C"
rlm@1 9 {
rlm@1 10 #include "../../../C/RotateDefs.h"
rlm@1 11 }
rlm@1 12
rlm@1 13 namespace NCrypto {
rlm@1 14 namespace NSha1 {
rlm@1 15
rlm@1 16 // define it for speed optimization
rlm@1 17 // #define _SHA1_UNROLL
rlm@1 18
rlm@1 19 static const unsigned kNumW =
rlm@1 20 #ifdef _SHA1_UNROLL
rlm@1 21 16;
rlm@1 22 #else
rlm@1 23 80;
rlm@1 24 #endif
rlm@1 25
rlm@1 26
rlm@1 27 #define w0(i) (W[(i)] = data[(i)])
rlm@1 28
rlm@1 29 #ifdef _SHA1_UNROLL
rlm@1 30 #define w1(i) (W[(i)&15] = rotlFixed(W[((i)-3)&15] ^ W[((i)-8)&15] ^ W[((i)-14)&15] ^ W[((i)-16)&15], 1))
rlm@1 31 #else
rlm@1 32 #define w1(i) (W[(i)] = rotlFixed(W[(i)-3] ^ W[(i)-8] ^ W[(i)-14] ^ W[(i)-16], 1))
rlm@1 33 #endif
rlm@1 34
rlm@1 35 #define f1(x,y,z) (z^(x&(y^z)))
rlm@1 36 #define f2(x,y,z) (x^y^z)
rlm@1 37 #define f3(x,y,z) ((x&y)|(z&(x|y)))
rlm@1 38 #define f4(x,y,z) (x^y^z)
rlm@1 39
rlm@1 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);
rlm@1 41
rlm@1 42 #define R0(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w0, 0x5A827999)
rlm@1 43 #define R1(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w1, 0x5A827999)
rlm@1 44 #define R2(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f2, w1, 0x6ED9EBA1)
rlm@1 45 #define R3(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f3, w1, 0x8F1BBCDC)
rlm@1 46 #define R4(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f4, w1, 0xCA62C1D6)
rlm@1 47
rlm@1 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);
rlm@1 49 #define RX_5(rx, i) RX_1_4(rx, rx, i);
rlm@1 50
rlm@1 51 void CContextBase::Init()
rlm@1 52 {
rlm@1 53 _state[0] = 0x67452301;
rlm@1 54 _state[1] = 0xEFCDAB89;
rlm@1 55 _state[2] = 0x98BADCFE;
rlm@1 56 _state[3] = 0x10325476;
rlm@1 57 _state[4] = 0xC3D2E1F0;
rlm@1 58 _count = 0;
rlm@1 59 }
rlm@1 60
rlm@1 61 void CContextBase::GetBlockDigest(UInt32 *data, UInt32 *destDigest, bool returnRes)
rlm@1 62 {
rlm@1 63 UInt32 a, b, c, d, e;
rlm@1 64 UInt32 W[kNumW];
rlm@1 65
rlm@1 66 a = _state[0];
rlm@1 67 b = _state[1];
rlm@1 68 c = _state[2];
rlm@1 69 d = _state[3];
rlm@1 70 e = _state[4];
rlm@1 71 #ifdef _SHA1_UNROLL
rlm@1 72 RX_5(R0, 0); RX_5(R0, 5); RX_5(R0, 10);
rlm@1 73 #else
rlm@1 74 int i;
rlm@1 75 for (i = 0; i < 15; i += 5) { RX_5(R0, i); }
rlm@1 76 #endif
rlm@1 77
rlm@1 78 RX_1_4(R0, R1, 15);
rlm@1 79
rlm@1 80
rlm@1 81 #ifdef _SHA1_UNROLL
rlm@1 82 RX_5(R2, 20); RX_5(R2, 25); RX_5(R2, 30); RX_5(R2, 35);
rlm@1 83 RX_5(R3, 40); RX_5(R3, 45); RX_5(R3, 50); RX_5(R3, 55);
rlm@1 84 RX_5(R4, 60); RX_5(R4, 65); RX_5(R4, 70); RX_5(R4, 75);
rlm@1 85 #else
rlm@1 86 i = 20;
rlm@1 87 for (; i < 40; i += 5) { RX_5(R2, i); }
rlm@1 88 for (; i < 60; i += 5) { RX_5(R3, i); }
rlm@1 89 for (; i < 80; i += 5) { RX_5(R4, i); }
rlm@1 90 #endif
rlm@1 91
rlm@1 92 destDigest[0] = _state[0] + a;
rlm@1 93 destDigest[1] = _state[1] + b;
rlm@1 94 destDigest[2] = _state[2] + c;
rlm@1 95 destDigest[3] = _state[3] + d;
rlm@1 96 destDigest[4] = _state[4] + e;
rlm@1 97
rlm@1 98 if (returnRes)
rlm@1 99 for (int i = 0 ; i < 16; i++)
rlm@1 100 data[i] = W[kNumW - 16 + i];
rlm@1 101
rlm@1 102 // Wipe variables
rlm@1 103 // a = b = c = d = e = 0;
rlm@1 104 }
rlm@1 105
rlm@1 106 void CContextBase::PrepareBlock(UInt32 *block, unsigned size) const
rlm@1 107 {
rlm@1 108 unsigned curBufferPos = size & 0xF;
rlm@1 109 block[curBufferPos++] = 0x80000000;
rlm@1 110 while (curBufferPos != (16 - 2))
rlm@1 111 block[curBufferPos++] = 0;
rlm@1 112 const UInt64 lenInBits = (_count << 9) + ((UInt64)size << 5);
rlm@1 113 block[curBufferPos++] = (UInt32)(lenInBits >> 32);
rlm@1 114 block[curBufferPos++] = (UInt32)(lenInBits);
rlm@1 115 }
rlm@1 116
rlm@1 117 void CContext::Update(Byte *data, size_t size, bool rar350Mode)
rlm@1 118 {
rlm@1 119 bool returnRes = false;
rlm@1 120 unsigned curBufferPos = _count2;
rlm@1 121 while (size-- > 0)
rlm@1 122 {
rlm@1 123 int pos = (int)(curBufferPos & 3);
rlm@1 124 if (pos == 0)
rlm@1 125 _buffer[curBufferPos >> 2] = 0;
rlm@1 126 _buffer[curBufferPos >> 2] |= ((UInt32)*data++) << (8 * (3 - pos));
rlm@1 127 if (++curBufferPos == kBlockSize)
rlm@1 128 {
rlm@1 129 curBufferPos = 0;
rlm@1 130 CContextBase::UpdateBlock(_buffer, returnRes);
rlm@1 131 if (returnRes)
rlm@1 132 for (int i = 0; i < kBlockSizeInWords; i++)
rlm@1 133 {
rlm@1 134 UInt32 d = _buffer[i];
rlm@1 135 data[i * 4 + 0 - kBlockSize] = (Byte)(d);
rlm@1 136 data[i * 4 + 1 - kBlockSize] = (Byte)(d >> 8);
rlm@1 137 data[i * 4 + 2 - kBlockSize] = (Byte)(d >> 16);
rlm@1 138 data[i * 4 + 3 - kBlockSize] = (Byte)(d >> 24);
rlm@1 139 }
rlm@1 140 returnRes = rar350Mode;
rlm@1 141 }
rlm@1 142 }
rlm@1 143 _count2 = curBufferPos;
rlm@1 144 }
rlm@1 145
rlm@1 146 void CContext::Final(Byte *digest)
rlm@1 147 {
rlm@1 148 const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 3);
rlm@1 149 unsigned curBufferPos = _count2;
rlm@1 150 int pos = (int)(curBufferPos & 3);
rlm@1 151 curBufferPos >>= 2;
rlm@1 152 if (pos == 0)
rlm@1 153 _buffer[curBufferPos] = 0;
rlm@1 154 _buffer[curBufferPos++] |= ((UInt32)0x80) << (8 * (3 - pos));
rlm@1 155
rlm@1 156 while (curBufferPos != (16 - 2))
rlm@1 157 {
rlm@1 158 curBufferPos &= 0xF;
rlm@1 159 if (curBufferPos == 0)
rlm@1 160 UpdateBlock();
rlm@1 161 _buffer[curBufferPos++] = 0;
rlm@1 162 }
rlm@1 163 _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32);
rlm@1 164 _buffer[curBufferPos++] = (UInt32)(lenInBits);
rlm@1 165 UpdateBlock();
rlm@1 166
rlm@1 167 int i;
rlm@1 168 for (i = 0; i < kDigestSizeInWords; i++)
rlm@1 169 {
rlm@1 170 UInt32 state = _state[i] & 0xFFFFFFFF;
rlm@1 171 *digest++ = (Byte)(state >> 24);
rlm@1 172 *digest++ = (Byte)(state >> 16);
rlm@1 173 *digest++ = (Byte)(state >> 8);
rlm@1 174 *digest++ = (Byte)(state);
rlm@1 175 }
rlm@1 176 Init();
rlm@1 177 }
rlm@1 178
rlm@1 179 ///////////////////////////
rlm@1 180 // Words version
rlm@1 181
rlm@1 182 void CContext32::Update(const UInt32 *data, size_t size)
rlm@1 183 {
rlm@1 184 while (size-- > 0)
rlm@1 185 {
rlm@1 186 _buffer[_count2++] = *data++;
rlm@1 187 if (_count2 == kBlockSizeInWords)
rlm@1 188 {
rlm@1 189 _count2 = 0;
rlm@1 190 UpdateBlock();
rlm@1 191 }
rlm@1 192 }
rlm@1 193 }
rlm@1 194
rlm@1 195 void CContext32::Final(UInt32 *digest)
rlm@1 196 {
rlm@1 197 const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 5);
rlm@1 198 unsigned curBufferPos = _count2;
rlm@1 199 _buffer[curBufferPos++] = 0x80000000;
rlm@1 200 while (curBufferPos != (16 - 2))
rlm@1 201 {
rlm@1 202 curBufferPos &= 0xF;
rlm@1 203 if (curBufferPos == 0)
rlm@1 204 UpdateBlock();
rlm@1 205 _buffer[curBufferPos++] = 0;
rlm@1 206 }
rlm@1 207 _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32);
rlm@1 208 _buffer[curBufferPos++] = (UInt32)(lenInBits);
rlm@1 209 GetBlockDigest(_buffer, digest);
rlm@1 210 Init();
rlm@1 211 }
rlm@1 212
rlm@1 213 }}