d7061e496aefe0651c256c73a5a67918308301c8
[mono.git] / mcs / class / corlib / System.Security.Cryptography / SHA1CryptoServiceProvider.cs
1 //\r
2 // System.Security.Cryptography SHA1CryptoServiceProvider Class implementation\r
3 //\r
4 // Author:\r
5 //   Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)\r
6 //\r
7 // Copyright 2001 by Matthew S. Ford.\r
8 //\r
9 \r
10 \r
11 using System.Security.Cryptography;\r
12 \r
13 namespace System.Security.Cryptography {\r
14 \r
15         /// <summary>\r
16         /// C# implementation of the SHA1 cryptographic hash function.\r
17         /// LAMESPEC?: Basically the same thing as SHA1Managed except for how its implemented.\r
18         /// </summary>\r
19         public sealed class SHA1CryptoServiceProvider : SHA1 {\r
20                 private const int BLOCK_SIZE_BYTES =  64;\r
21                 private const int HASH_SIZE_BYTES  =  20;\r
22                 private const int HASH_SIZE_BITS   = 160;\r
23                 [CLSCompliant(false)] private uint[] _H;  // these are my chaining variables\r
24                 [CLSCompliant(false)] private uint count;\r
25                 private byte[] _ProcessingBuffer;   // Used to start data when passed less than a block worth.\r
26                 private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.\r
27         \r
28                 /// <summary>\r
29                 /// Creates a new SHA1CryptoServiceProvider.\r
30                 /// </summary>\r
31                 public SHA1CryptoServiceProvider () {\r
32                         _H = new uint[5];\r
33                         HashSizeValue = HASH_SIZE_BITS;\r
34                         _ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];\r
35                         \r
36                         Initialize();\r
37                 }\r
38 \r
39                 /// <summary>\r
40                 /// Drives the hashing function.\r
41                 /// </summary>\r
42                 /// <param name="rgb">Byte array containing the data to hash.</param>\r
43                 /// <param name="start">Where in the input buffer to start.</param>\r
44                 /// <param name="size">Size in bytes of the data in the buffer to hash.</param>\r
45                 protected override void HashCore (byte[] rgb, int start, int size) {\r
46                         int i;\r
47                         State = 1;\r
48 \r
49                         if (_ProcessingBufferCount != 0) {\r
50                                 if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount)) {\r
51                                         System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);\r
52                                         _ProcessingBufferCount += size;\r
53                                         return;\r
54                                 }\r
55                                 else {\r
56                                         i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);\r
57                                         System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);\r
58                                         ProcessBlock (_ProcessingBuffer, 0);\r
59                                         _ProcessingBufferCount = 0;\r
60                                         start += i;\r
61                                         size -= i;\r
62                                 }\r
63                         }\r
64 \r
65                         for (i=0; i<size-size%BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) {\r
66                                 ProcessBlock (rgb, start+i);\r
67                         }\r
68 \r
69                         if (size%BLOCK_SIZE_BYTES != 0) {\r
70                                 System.Buffer.BlockCopy (rgb, size-size%BLOCK_SIZE_BYTES+start, _ProcessingBuffer, 0, size%BLOCK_SIZE_BYTES);\r
71                                 _ProcessingBufferCount = size%BLOCK_SIZE_BYTES;\r
72                         }\r
73                 }\r
74         \r
75                 /// <summary>\r
76                 /// This finalizes the hash.  Takes the data from the chaining variables and returns it.\r
77                 /// </summary>\r
78                 protected override byte[] HashFinal () {\r
79                         byte[] hash = new byte[20];\r
80                         int i, j;\r
81 \r
82                         ProcessFinalBlock(_ProcessingBuffer, 0, _ProcessingBufferCount);\r
83 \r
84                         for (i=0; i<5; i++) {\r
85                                 for (j=0; j<4; j++) {\r
86                                         hash[i*4+j] = (byte)(_H[i] >> (8*(3-j)));\r
87                                 }\r
88                         }\r
89 \r
90                         State = 0;\r
91                         return hash;\r
92                 }\r
93 \r
94                 \r
95                 /// <summary>\r
96                 /// Resets the class after use.  Called automatically after hashing is done.\r
97                 /// </summary>\r
98                 public override void Initialize () {\r
99                         count = 0;\r
100                         _ProcessingBufferCount = 0;\r
101 \r
102                         _H[0] = 0x67452301;\r
103                         _H[1] = 0xefcdab89;\r
104                         _H[2] = 0x98badcfe;\r
105                         _H[3] = 0x10325476;\r
106                         _H[4] = 0xC3D2E1F0;\r
107                 }\r
108 \r
109                 /// <summary>\r
110                 /// This is the meat of the hash function.  It is what processes each block one at a time.\r
111                 /// </summary>\r
112                 /// <param name="inputBuffer">Byte array to process data from.</param>\r
113                 /// <param name="inputOffset">Where in the byte array to start processing.</param>\r
114                 private void ProcessBlock(byte[] inputBuffer, int inputOffset) {\r
115                         uint[] buff = new uint[80];\r
116                         uint a, b, c, d, e;\r
117                         int i;\r
118 \r
119                         count += BLOCK_SIZE_BYTES;\r
120                 \r
121                         for (i=0; i<16; i++) {\r
122                                 buff[i] = ((uint)(inputBuffer[inputOffset+4*i]) << 24)\r
123                                         | ((uint)(inputBuffer[inputOffset+4*i+1]) << 16)\r
124                                         | ((uint)(inputBuffer[inputOffset+4*i+2]) <<  8)\r
125                                         | ((uint)(inputBuffer[inputOffset+4*i+3]));\r
126                         }\r
127 \r
128                         for (i=16; i<80; i++) {\r
129                                 buff[i] = ((buff[i-3] ^ buff[i-8] ^ buff[i-14] ^ buff[i-16]) << 1)\r
130                                         | ((buff[i-3] ^ buff[i-8] ^ buff[i-14] ^ buff[i-16]) >> 31);\r
131                         }\r
132                 \r
133                         a = _H[0];\r
134                         b = _H[1];\r
135                         c = _H[2];\r
136                         d = _H[3];\r
137                         e = _H[4];\r
138 \r
139 \r
140                         // This function was unrolled because it seems to be doubling our performance with current compiler/VM.\r
141                         // Possibly roll up if this changes.\r
142         \r
143                         // ---- Round 1 --------\r
144   \r
145                         e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[0];\r
146                         b = (b << 30) | (b >> 2);\r
147 \r
148                         d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[1];\r
149                         a = (a << 30) | (a >> 2);\r
150 \r
151                         c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[2];\r
152                         e = (e << 30) | (e >> 2);\r
153 \r
154                         b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[3];\r
155                         d = (d << 30) | (d >> 2);\r
156 \r
157                         a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[4];\r
158                         c = (c << 30) | (c >> 2);\r
159 \r
160                         e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[5];\r
161                         b = (b << 30) | (b >> 2);\r
162 \r
163                         d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[6];\r
164                         a = (a << 30) | (a >> 2);\r
165 \r
166                         c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[7];\r
167                         e = (e << 30) | (e >> 2);\r
168 \r
169                         b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[8];\r
170                         d = (d << 30) | (d >> 2);\r
171 \r
172                         a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[9];\r
173                         c = (c << 30) | (c >> 2);\r
174 \r
175                         e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[10];\r
176                         b = (b << 30) | (b >> 2);\r
177 \r
178                         d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[11];\r
179                         a = (a << 30) | (a >> 2);\r
180 \r
181                         c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[12];\r
182                         e = (e << 30) | (e >> 2);\r
183 \r
184                         b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[13];\r
185                         d = (d << 30) | (d >> 2);\r
186 \r
187                         a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[14];\r
188                         c = (c << 30) | (c >> 2);\r
189 \r
190                         e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[15];\r
191                         b = (b << 30) | (b >> 2);\r
192 \r
193                         d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[16];\r
194                         a = (a << 30) | (a >> 2);\r
195 \r
196                         c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[17];\r
197                         e = (e << 30) | (e >> 2);\r
198 \r
199                         b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[18];\r
200                         d = (d << 30) | (d >> 2);\r
201 \r
202                         a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[19];\r
203                         c = (c << 30) | (c >> 2);\r
204 \r
205 \r
206 \r
207                         // ---- Round 2 --------\r
208   \r
209                         e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[20];\r
210                         b = (b << 30) | (b >> 2);\r
211 \r
212                         d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[21];\r
213                         a = (a << 30) | (a >> 2);\r
214 \r
215                         c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[22];\r
216                         e = (e << 30) | (e >> 2);\r
217 \r
218                         b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[23];\r
219                         d = (d << 30) | (d >> 2);\r
220 \r
221                         a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[24];\r
222                         c = (c << 30) | (c >> 2);\r
223 \r
224                         e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[25];\r
225                         b = (b << 30) | (b >> 2);\r
226 \r
227                         d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[26];\r
228                         a = (a << 30) | (a >> 2);\r
229 \r
230                         c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[27];\r
231                         e = (e << 30) | (e >> 2);\r
232 \r
233                         b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[28];\r
234                         d = (d << 30) | (d >> 2);\r
235 \r
236                         a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[29];\r
237                         c = (c << 30) | (c >> 2);\r
238 \r
239                         e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[30];\r
240                         b = (b << 30) | (b >> 2);\r
241 \r
242                         d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[31];\r
243                         a = (a << 30) | (a >> 2);\r
244 \r
245                         c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[32];\r
246                         e = (e << 30) | (e >> 2);\r
247 \r
248                         b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[33];\r
249                         d = (d << 30) | (d >> 2);\r
250 \r
251                         a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[34];\r
252                         c = (c << 30) | (c >> 2);\r
253 \r
254                         e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[35];\r
255                         b = (b << 30) | (b >> 2);\r
256 \r
257                         d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[36];\r
258                         a = (a << 30) | (a >> 2);\r
259 \r
260                         c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[37];\r
261                         e = (e << 30) | (e >> 2);\r
262 \r
263                         b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[38];\r
264                         d = (d << 30) | (d >> 2);\r
265 \r
266                         a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[39];\r
267                         c = (c << 30) | (c >> 2);\r
268 \r
269 \r
270 \r
271                         // ---- Round 3 --------\r
272   \r
273                         e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[40];\r
274                         b = (b << 30) | (b >> 2);\r
275 \r
276                         d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[41];\r
277                         a = (a << 30) | (a >> 2);\r
278 \r
279                         c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[42];\r
280                         e = (e << 30) | (e >> 2);\r
281 \r
282                         b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[43];\r
283                         d = (d << 30) | (d >> 2);\r
284 \r
285                         a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[44];\r
286                         c = (c << 30) | (c >> 2);\r
287 \r
288                         e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[45];\r
289                         b = (b << 30) | (b >> 2);\r
290 \r
291                         d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[46];\r
292                         a = (a << 30) | (a >> 2);\r
293 \r
294                         c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[47];\r
295                         e = (e << 30) | (e >> 2);\r
296 \r
297                         b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[48];\r
298                         d = (d << 30) | (d >> 2);\r
299 \r
300                         a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[49];\r
301                         c = (c << 30) | (c >> 2);\r
302 \r
303                         e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[50];\r
304                         b = (b << 30) | (b >> 2);\r
305 \r
306                         d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[51];\r
307                         a = (a << 30) | (a >> 2);\r
308 \r
309                         c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[52];\r
310                         e = (e << 30) | (e >> 2);\r
311 \r
312                         b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[53];\r
313                         d = (d << 30) | (d >> 2);\r
314 \r
315                         a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[54];\r
316                         c = (c << 30) | (c >> 2);\r
317 \r
318                         e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[55];\r
319                         b = (b << 30) | (b >> 2);\r
320 \r
321                         d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[56];\r
322                         a = (a << 30) | (a >> 2);\r
323 \r
324                         c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[57];\r
325                         e = (e << 30) | (e >> 2);\r
326 \r
327                         b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[58];\r
328                         d = (d << 30) | (d >> 2);\r
329 \r
330                         a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[59];\r
331                         c = (c << 30) | (c >> 2);\r
332 \r
333 \r
334 \r
335                         // ---- Round 4 --------\r
336   \r
337                         e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[60];\r
338                         b = (b << 30) | (b >> 2);\r
339 \r
340                         d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[61];\r
341                         a = (a << 30) | (a >> 2);\r
342 \r
343                         c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[62];\r
344                         e = (e << 30) | (e >> 2);\r
345 \r
346                         b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[63];\r
347                         d = (d << 30) | (d >> 2);\r
348 \r
349                         a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[64];\r
350                         c = (c << 30) | (c >> 2);\r
351 \r
352                         e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[65];\r
353                         b = (b << 30) | (b >> 2);\r
354 \r
355                         d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[66];\r
356                         a = (a << 30) | (a >> 2);\r
357 \r
358                         c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[67];\r
359                         e = (e << 30) | (e >> 2);\r
360 \r
361                         b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[68];\r
362                         d = (d << 30) | (d >> 2);\r
363 \r
364                         a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[69];\r
365                         c = (c << 30) | (c >> 2);\r
366 \r
367                         e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[70];\r
368                         b = (b << 30) | (b >> 2);\r
369 \r
370                         d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[71];\r
371                         a = (a << 30) | (a >> 2);\r
372 \r
373                         c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[72];\r
374                         e = (e << 30) | (e >> 2);\r
375 \r
376                         b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[73];\r
377                         d = (d << 30) | (d >> 2);\r
378 \r
379                         a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[74];\r
380                         c = (c << 30) | (c >> 2);\r
381 \r
382                         e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[75];\r
383                         b = (b << 30) | (b >> 2);\r
384 \r
385                         d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[76];\r
386                         a = (a << 30) | (a >> 2);\r
387 \r
388                         c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[77];\r
389                         e = (e << 30) | (e >> 2);\r
390 \r
391                         b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[78];\r
392                         d = (d << 30) | (d >> 2);\r
393 \r
394                         a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[79];\r
395                         c = (c << 30) | (c >> 2);\r
396 \r
397 \r
398                         _H[0] += a;\r
399                         _H[1] += b;\r
400                         _H[2] += c;\r
401                         _H[3] += d;\r
402                         _H[4] += e;\r
403                 }\r
404         \r
405                 /// <summary>\r
406                 /// Pads and then processes the final block.\r
407                 /// Non-standard.\r
408                 /// </summary>\r
409                 /// <param name="inputBuffer">Buffer to grab data from.</param>\r
410                 /// <param name="inputOffset">Position in buffer in bytes to get data from.</param>\r
411                 /// <param name="inputCount">How much data in bytes in the buffer to use.</param>\r
412                 private void ProcessFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) {\r
413                         byte[] fooBuffer;\r
414                         int paddingSize;\r
415                         int i;\r
416                         uint size;\r
417 \r
418                         paddingSize = (int)(56 - (inputCount + count) % BLOCK_SIZE_BYTES);\r
419 \r
420                         if (paddingSize < 1)\r
421                                 paddingSize += BLOCK_SIZE_BYTES;\r
422 \r
423                         fooBuffer = new byte[inputCount+paddingSize+8];\r
424 \r
425                         for (i=0; i<inputCount; i++) {\r
426                                 fooBuffer[i] = inputBuffer[i+inputOffset];\r
427                         }\r
428 \r
429                         fooBuffer[inputCount] = 0x80;\r
430                         for (i=inputCount+1; i<inputCount+paddingSize; i++) {\r
431                                 fooBuffer[i] = 0x00;\r
432                         }\r
433 \r
434                         size = (uint)(count+inputCount);\r
435                         size *= 8;  // I deal in bytes.  They algorythm deals in bits.\r
436 \r
437                         fooBuffer[inputCount+paddingSize]   = 0x00;\r
438                         fooBuffer[inputCount+paddingSize+1] = 0x00;\r
439                         fooBuffer[inputCount+paddingSize+2] = 0x00;\r
440                         fooBuffer[inputCount+paddingSize+3] = 0x00;\r
441 \r
442                         fooBuffer[inputCount+paddingSize+4] = (byte)((size) >> 24);\r
443                         fooBuffer[inputCount+paddingSize+5] = (byte)((size) >> 16);\r
444                         fooBuffer[inputCount+paddingSize+6] = (byte)((size) >>  8);\r
445                         fooBuffer[inputCount+paddingSize+7] = (byte)((size) >>  0);\r
446 \r
447                         ProcessBlock(fooBuffer, 0);\r
448 \r
449                         if (inputCount+paddingSize+8 == 128) {\r
450                                 ProcessBlock(fooBuffer, 64);\r
451                         }\r
452                 }\r
453         }\r
454 }\r
455 \r