"Fossies" - the Fresh Open Source Software Archive 
Member "unrar/sha1.cpp" (4 May 2022, 6323 Bytes) of package /linux/misc/unrarsrc-6.1.7.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "sha1.cpp" see the
Fossies "Dox" file reference documentation.
1 #include "rar.hpp"
2
3 /*
4 SHA-1 in C
5 By Steve Reid <steve@edmweb.com>
6 100% Public Domain
7 */
8
9 #ifndef SFX_MODULE
10 #define SHA1_UNROLL
11 #endif
12
13 /* blk0() and blk() perform the initial expand. */
14 /* I got the idea of expanding during the round function from SSLeay */
15 #ifdef LITTLE_ENDIAN
16 #define blk0(i) (block->l[i] = ByteSwap32(block->l[i]))
17 #else
18 #define blk0(i) block->l[i]
19 #endif
20 #define blk(i) (block->l[i&15] = rotl32(block->l[(i+13)&15]^block->l[(i+8)&15] \
21 ^block->l[(i+2)&15]^block->l[i&15],1))
22
23 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
24 #define R0(v,w,x,y,z,i) {z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rotl32(v,5);w=rotl32(w,30);}
25 #define R1(v,w,x,y,z,i) {z+=((w&(x^y))^y)+blk(i)+0x5A827999+rotl32(v,5);w=rotl32(w,30);}
26 #define R2(v,w,x,y,z,i) {z+=(w^x^y)+blk(i)+0x6ED9EBA1+rotl32(v,5);w=rotl32(w,30);}
27 #define R3(v,w,x,y,z,i) {z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rotl32(v,5);w=rotl32(w,30);}
28 #define R4(v,w,x,y,z,i) {z+=(w^x^y)+blk(i)+0xCA62C1D6+rotl32(v,5);w=rotl32(w,30);}
29
30 /* Hash a single 512-bit block. This is the core of the algorithm. */
31 void SHA1Transform(uint32 state[5], uint32 workspace[16], const byte buffer[64], bool inplace)
32 {
33 uint32 a, b, c, d, e;
34
35 union CHAR64LONG16
36 {
37 unsigned char c[64];
38 uint32 l[16];
39 } *block;
40
41 if (inplace)
42 block = (CHAR64LONG16*)buffer;
43 else
44 {
45 block = (CHAR64LONG16*)workspace;
46 memcpy(block, buffer, 64);
47 }
48
49 /* Copy context->state[] to working vars */
50 a = state[0];
51 b = state[1];
52 c = state[2];
53 d = state[3];
54 e = state[4];
55
56 #ifdef SHA1_UNROLL
57 /* 4 rounds of 20 operations each. Loop unrolled. */
58 R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
59 R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
60 R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
61 R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
62 R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
63 R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
64 R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
65 R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
66 R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
67 R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
68 R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
69 R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
70 R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
71 R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
72 R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
73 R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
74 R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
75 R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
76 R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
77 R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
78 #else
79 for (uint I=0;;I+=5)
80 {
81 R0(a,b,c,d,e, I+0); if (I==15) break;
82 R0(e,a,b,c,d, I+1); R0(d,e,a,b,c, I+2);
83 R0(c,d,e,a,b, I+3); R0(b,c,d,e,a, I+4);
84 }
85 R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
86 for (uint I=20;I<=35;I+=5)
87 {
88 R2(a,b,c,d,e,I+0); R2(e,a,b,c,d,I+1); R2(d,e,a,b,c,I+2);
89 R2(c,d,e,a,b,I+3); R2(b,c,d,e,a,I+4);
90 }
91 for (uint I=40;I<=55;I+=5)
92 {
93 R3(a,b,c,d,e,I+0); R3(e,a,b,c,d,I+1); R3(d,e,a,b,c,I+2);
94 R3(c,d,e,a,b,I+3); R3(b,c,d,e,a,I+4);
95 }
96 for (uint I=60;I<=75;I+=5)
97 {
98 R4(a,b,c,d,e,I+0); R4(e,a,b,c,d,I+1); R4(d,e,a,b,c,I+2);
99 R4(c,d,e,a,b,I+3); R4(b,c,d,e,a,I+4);
100 }
101 #endif
102 /* Add the working vars back into context.state[] */
103 state[0] += a;
104 state[1] += b;
105 state[2] += c;
106 state[3] += d;
107 state[4] += e;
108 }
109
110
111 /* Initialize new context */
112 void sha1_init(sha1_context* context)
113 {
114 context->count = 0;
115 /* SHA1 initialization constants */
116 context->state[0] = 0x67452301;
117 context->state[1] = 0xEFCDAB89;
118 context->state[2] = 0x98BADCFE;
119 context->state[3] = 0x10325476;
120 context->state[4] = 0xC3D2E1F0;
121 }
122
123
124 /* Run your data through this. */
125 void sha1_process( sha1_context * context, const unsigned char * data, size_t len)
126 {
127 size_t i, j = (size_t)(context->count & 63);
128 context->count += len;
129
130 if ((j + len) > 63)
131 {
132 memcpy(context->buffer+j, data, (i = 64-j));
133 uint32 workspace[16];
134 SHA1Transform(context->state, workspace, context->buffer, true);
135 for ( ; i + 63 < len; i += 64)
136 SHA1Transform(context->state, workspace, data+i, false);
137 j = 0;
138 }
139 else
140 i = 0;
141 if (len > i)
142 memcpy(context->buffer+j, data+i, len - i);
143 }
144
145
146 void sha1_process_rar29(sha1_context *context, const unsigned char *data, size_t len)
147 {
148 size_t i, j = (size_t)(context->count & 63);
149 context->count += len;
150
151 if ((j + len) > 63)
152 {
153 memcpy(context->buffer+j, data, (i = 64-j));
154 uint32 workspace[16];
155 SHA1Transform(context->state, workspace, context->buffer, true);
156 for ( ; i + 63 < len; i += 64)
157 {
158 SHA1Transform(context->state, workspace, data+i, false);
159 for (uint k = 0; k < 16; k++)
160 RawPut4(workspace[k],(void*)(data+i+k*4));
161 }
162 j = 0;
163 }
164 else
165 i = 0;
166 if (len > i)
167 memcpy(context->buffer+j, data+i, len - i);
168 }
169
170
171 /* Add padding and return the message digest. */
172 void sha1_done( sha1_context* context, uint32 digest[5])
173 {
174 uint32 workspace[16];
175 uint64 BitLength = context->count * 8;
176 uint BufPos = (uint)context->count & 0x3f;
177 context->buffer[BufPos++] = 0x80; // Padding the message with "1" bit.
178
179 if (BufPos!=56) // We need 56 bytes block followed by 8 byte length.
180 {
181 if (BufPos>56)
182 {
183 while (BufPos<64)
184 context->buffer[BufPos++] = 0;
185 BufPos=0;
186 }
187 if (BufPos==0)
188 SHA1Transform(context->state, workspace, context->buffer, true);
189 memset(context->buffer+BufPos,0,56-BufPos);
190 }
191
192 RawPutBE4((uint32)(BitLength>>32), context->buffer + 56);
193 RawPutBE4((uint32)(BitLength), context->buffer + 60);
194
195 SHA1Transform(context->state, workspace, context->buffer, true);
196
197 for (uint i = 0; i < 5; i++)
198 digest[i] = context->state[i];
199
200 /* Wipe variables */
201 sha1_init(context);
202 }
203
204