2010-04-07 Jb Evain <jbevain@novell.com>
[mcs.git] / class / corlib / System.Security.Cryptography / RIPEMD160Managed.cs
blob634d9accbef05d8e954716bacbafc5389ad4abbe
1 //
2 // RIPEMD160Managed.cs: Implements the RIPEMD-160 hash algorithm
3 //
4 // Author:
5 // Pieter Philippaerts (Pieter@mentalis.org)
6 //
7 // References:
8 // - http://www.esat.kuleuven.ac.be/~cosicart/ps/AB-9601/
9 //
10 // (C) 2003 The Mentalis.org Team (http://www.mentalis.org/)
11 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 #if !MOONLIGHT
35 using System.Runtime.InteropServices;
37 namespace System.Security.Cryptography {
38 /// <summary>
39 /// Computes the <see cref="RIPEMD160"/> hash for the input data.
40 /// </summary>
41 [ComVisible (true)]
42 public class RIPEMD160Managed : RIPEMD160 { // not 'sealed' according to preliminary docs; this may change though
43 /// <summary>
44 /// Initializes a new instance of the <see cref="RIPEMD160Managed"/> class. This class cannot be inherited.
45 /// </summary>
46 public RIPEMD160Managed() {
47 _X = new uint[16];
48 _HashValue = new uint[5];
49 _ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];
50 Initialize();
52 /// <summary>
53 /// Initializes an instance of <see cref="RIPEMD160Managed"/>.
54 /// </summary>
55 /// <exception cref="ObjectDisposedException">The RIPEMD160Managed instance has been disposed.</exception>
56 public override void Initialize() {
57 _HashValue[0] = 0x67452301;
58 _HashValue[1] = 0xefcdab89;
59 _HashValue[2] = 0x98badcfe;
60 _HashValue[3] = 0x10325476;
61 _HashValue[4] = 0xc3d2e1f0;
62 _Length = 0;
63 _ProcessingBufferCount = 0;
64 Array.Clear (_X, 0, _X.Length);
65 Array.Clear (_ProcessingBuffer, 0, _ProcessingBuffer.Length);
67 /// <summary>
68 /// Routes data written to the object into the <see cref="RIPEMD160"/> hash algorithm for computing the hash.
69 /// </summary>
70 /// <param name="array">The array of data bytes.</param>
71 /// <param name="ibStart">The offset into the byte array from which to begin using data.</param>
72 /// <param name="cbSize">The number of bytes in the array to use as data.</param>
73 /// <exception cref="ObjectDisposedException">The <see cref="RIPEMD160Managed"/> instance has been disposed.</exception>
74 protected override void HashCore(byte[] rgb, int ibStart, int cbSize) {
75 int i;
76 State = 1;
78 _Length += (uint)cbSize; // global length
80 if (_ProcessingBufferCount != 0) {
81 if (cbSize < (BLOCK_SIZE_BYTES - _ProcessingBufferCount)) {
82 System.Buffer.BlockCopy (rgb, ibStart, _ProcessingBuffer, _ProcessingBufferCount, cbSize);
83 _ProcessingBufferCount += cbSize;
84 return;
85 } else {
86 i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);
87 System.Buffer.BlockCopy (rgb, ibStart, _ProcessingBuffer, _ProcessingBufferCount, i);
88 ProcessBlock (_ProcessingBuffer, 0);
89 _ProcessingBufferCount = 0;
90 ibStart += i;
91 cbSize -= i;
95 for (i = 0; i < cbSize - cbSize % BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) {
96 ProcessBlock (rgb, ibStart + i);
99 if (cbSize % BLOCK_SIZE_BYTES != 0) {
100 System.Buffer.BlockCopy (rgb, cbSize - cbSize % BLOCK_SIZE_BYTES + ibStart, _ProcessingBuffer, 0, cbSize % BLOCK_SIZE_BYTES);
101 _ProcessingBufferCount = cbSize % BLOCK_SIZE_BYTES;
104 /// <summary>
105 /// Returns the computed <see cref="RIPEMD160"/> hash as an array of bytes after all data has been written to the object.
106 /// </summary>
107 /// <returns>The computed hash value.</returns>
108 /// <exception cref="ObjectDisposedException">The <see cref="RIPEMD160Managed"/> instance has been disposed.</exception>
109 protected override byte[] HashFinal() {
110 CompressFinal(_Length);
111 byte[] hash = new byte[20];
112 if (!BitConverter.IsLittleEndian) {
113 for (int i = 0; i < 5; i++) {
114 for (int j = 0; j < 4; j++) {
115 hash [i*4+j] = (byte)(_HashValue [i] >> j*8);
118 } else {
119 Buffer.BlockCopy (_HashValue, 0, hash, 0, 20);
121 return hash;
123 /// <summary>
124 /// Finalizes the RIPEMD160Managed.
125 /// </summary>
126 ~RIPEMD160Managed() {
127 Dispose(false);
130 /// <summary>
131 /// Processes one block of data.
132 /// </summary>
133 /// <param name="buffer">The buffer with the data.</param>
134 /// <param name="offset">The offset in the buffer.</param>
135 private void ProcessBlock (byte[] buffer, int offset)
137 if (!BitConverter.IsLittleEndian) {
138 for (int i=0; i < _X.Length; i++) {
139 _X [i] = (uint)(buffer [offset])
140 | (((uint)(buffer [offset+1])) << 8)
141 | (((uint)(buffer [offset+2])) << 16)
142 | (((uint)(buffer [offset+3])) << 24);
143 offset += 4;
145 } else {
146 Buffer.BlockCopy (buffer, offset, _X, 0, 64);
148 Compress();
151 private void Compress() {
152 uint aa = _HashValue[0], bb = _HashValue[1], cc = _HashValue[2], dd = _HashValue[3], ee = _HashValue[4];
153 uint aaa = _HashValue[0], bbb = _HashValue[1], ccc = _HashValue[2], ddd = _HashValue[3], eee = _HashValue[4];
154 /* round 1 */
155 FF(ref aa, bb, ref cc, dd, ee, _X[ 0], 11);
156 FF(ref ee, aa, ref bb, cc, dd, _X[ 1], 14);
157 FF(ref dd, ee, ref aa, bb, cc, _X[ 2], 15);
158 FF(ref cc, dd, ref ee, aa, bb, _X[ 3], 12);
159 FF(ref bb, cc, ref dd, ee, aa, _X[ 4], 5);
160 FF(ref aa, bb, ref cc, dd, ee, _X[ 5], 8);
161 FF(ref ee, aa, ref bb, cc, dd, _X[ 6], 7);
162 FF(ref dd, ee, ref aa, bb, cc, _X[ 7], 9);
163 FF(ref cc, dd, ref ee, aa, bb, _X[ 8], 11);
164 FF(ref bb, cc, ref dd, ee, aa, _X[ 9], 13);
165 FF(ref aa, bb, ref cc, dd, ee, _X[10], 14);
166 FF(ref ee, aa, ref bb, cc, dd, _X[11], 15);
167 FF(ref dd, ee, ref aa, bb, cc, _X[12], 6);
168 FF(ref cc, dd, ref ee, aa, bb, _X[13], 7);
169 FF(ref bb, cc, ref dd, ee, aa, _X[14], 9);
170 FF(ref aa, bb, ref cc, dd, ee, _X[15], 8);
171 /* round 2 */
172 GG(ref ee, aa, ref bb, cc, dd, _X[ 7], 7);
173 GG(ref dd, ee, ref aa, bb, cc, _X[ 4], 6);
174 GG(ref cc, dd, ref ee, aa, bb, _X[13], 8);
175 GG(ref bb, cc, ref dd, ee, aa, _X[ 1], 13);
176 GG(ref aa, bb, ref cc, dd, ee, _X[10], 11);
177 GG(ref ee, aa, ref bb, cc, dd, _X[ 6], 9);
178 GG(ref dd, ee, ref aa, bb, cc, _X[15], 7);
179 GG(ref cc, dd, ref ee, aa, bb, _X[ 3], 15);
180 GG(ref bb, cc, ref dd, ee, aa, _X[12], 7);
181 GG(ref aa, bb, ref cc, dd, ee, _X[ 0], 12);
182 GG(ref ee, aa, ref bb, cc, dd, _X[ 9], 15);
183 GG(ref dd, ee, ref aa, bb, cc, _X[ 5], 9);
184 GG(ref cc, dd, ref ee, aa, bb, _X[ 2], 11);
185 GG(ref bb, cc, ref dd, ee, aa, _X[14], 7);
186 GG(ref aa, bb, ref cc, dd, ee, _X[11], 13);
187 GG(ref ee, aa, ref bb, cc, dd, _X[ 8], 12);
188 /* round 3 */
189 HH(ref dd, ee, ref aa, bb, cc, _X[ 3], 11);
190 HH(ref cc, dd, ref ee, aa, bb, _X[10], 13);
191 HH(ref bb, cc, ref dd, ee, aa, _X[14], 6);
192 HH(ref aa, bb, ref cc, dd, ee, _X[ 4], 7);
193 HH(ref ee, aa, ref bb, cc, dd, _X[ 9], 14);
194 HH(ref dd, ee, ref aa, bb, cc, _X[15], 9);
195 HH(ref cc, dd, ref ee, aa, bb, _X[ 8], 13);
196 HH(ref bb, cc, ref dd, ee, aa, _X[ 1], 15);
197 HH(ref aa, bb, ref cc, dd, ee, _X[ 2], 14);
198 HH(ref ee, aa, ref bb, cc, dd, _X[ 7], 8);
199 HH(ref dd, ee, ref aa, bb, cc, _X[ 0], 13);
200 HH(ref cc, dd, ref ee, aa, bb, _X[ 6], 6);
201 HH(ref bb, cc, ref dd, ee, aa, _X[13], 5);
202 HH(ref aa, bb, ref cc, dd, ee, _X[11], 12);
203 HH(ref ee, aa, ref bb, cc, dd, _X[ 5], 7);
204 HH(ref dd, ee, ref aa, bb, cc, _X[12], 5);
205 /* round 4 */
206 II(ref cc, dd, ref ee, aa, bb, _X[ 1], 11);
207 II(ref bb, cc, ref dd, ee, aa, _X[ 9], 12);
208 II(ref aa, bb, ref cc, dd, ee, _X[11], 14);
209 II(ref ee, aa, ref bb, cc, dd, _X[10], 15);
210 II(ref dd, ee, ref aa, bb, cc, _X[ 0], 14);
211 II(ref cc, dd, ref ee, aa, bb, _X[ 8], 15);
212 II(ref bb, cc, ref dd, ee, aa, _X[12], 9);
213 II(ref aa, bb, ref cc, dd, ee, _X[ 4], 8);
214 II(ref ee, aa, ref bb, cc, dd, _X[13], 9);
215 II(ref dd, ee, ref aa, bb, cc, _X[ 3], 14);
216 II(ref cc, dd, ref ee, aa, bb, _X[ 7], 5);
217 II(ref bb, cc, ref dd, ee, aa, _X[15], 6);
218 II(ref aa, bb, ref cc, dd, ee, _X[14], 8);
219 II(ref ee, aa, ref bb, cc, dd, _X[ 5], 6);
220 II(ref dd, ee, ref aa, bb, cc, _X[ 6], 5);
221 II(ref cc, dd, ref ee, aa, bb, _X[ 2], 12);
222 /* round 5 */
223 JJ(ref bb, cc, ref dd, ee, aa, _X[ 4], 9);
224 JJ(ref aa, bb, ref cc, dd, ee, _X[ 0], 15);
225 JJ(ref ee, aa, ref bb, cc, dd, _X[ 5], 5);
226 JJ(ref dd, ee, ref aa, bb, cc, _X[ 9], 11);
227 JJ(ref cc, dd, ref ee, aa, bb, _X[ 7], 6);
228 JJ(ref bb, cc, ref dd, ee, aa, _X[12], 8);
229 JJ(ref aa, bb, ref cc, dd, ee, _X[ 2], 13);
230 JJ(ref ee, aa, ref bb, cc, dd, _X[10], 12);
231 JJ(ref dd, ee, ref aa, bb, cc, _X[14], 5);
232 JJ(ref cc, dd, ref ee, aa, bb, _X[ 1], 12);
233 JJ(ref bb, cc, ref dd, ee, aa, _X[ 3], 13);
234 JJ(ref aa, bb, ref cc, dd, ee, _X[ 8], 14);
235 JJ(ref ee, aa, ref bb, cc, dd, _X[11], 11);
236 JJ(ref dd, ee, ref aa, bb, cc, _X[ 6], 8);
237 JJ(ref cc, dd, ref ee, aa, bb, _X[15], 5);
238 JJ(ref bb, cc, ref dd, ee, aa, _X[13], 6);
239 /* parallel round 1 */
240 JJJ(ref aaa, bbb, ref ccc, ddd, eee, _X[ 5], 8);
241 JJJ(ref eee, aaa, ref bbb, ccc, ddd, _X[14], 9);
242 JJJ(ref ddd, eee, ref aaa, bbb, ccc, _X[ 7], 9);
243 JJJ(ref ccc, ddd, ref eee, aaa, bbb, _X[ 0], 11);
244 JJJ(ref bbb, ccc, ref ddd, eee, aaa, _X[ 9], 13);
245 JJJ(ref aaa, bbb, ref ccc, ddd, eee, _X[ 2], 15);
246 JJJ(ref eee, aaa, ref bbb, ccc, ddd, _X[11], 15);
247 JJJ(ref ddd, eee, ref aaa, bbb, ccc, _X[ 4], 5);
248 JJJ(ref ccc, ddd, ref eee, aaa, bbb, _X[13], 7);
249 JJJ(ref bbb, ccc, ref ddd, eee, aaa, _X[ 6], 7);
250 JJJ(ref aaa, bbb, ref ccc, ddd, eee, _X[15], 8);
251 JJJ(ref eee, aaa, ref bbb, ccc, ddd, _X[ 8], 11);
252 JJJ(ref ddd, eee, ref aaa, bbb, ccc, _X[ 1], 14);
253 JJJ(ref ccc, ddd, ref eee, aaa, bbb, _X[10], 14);
254 JJJ(ref bbb, ccc, ref ddd, eee, aaa, _X[ 3], 12);
255 JJJ(ref aaa, bbb, ref ccc, ddd, eee, _X[12], 6);
256 /* parallel round 2 */
257 III(ref eee, aaa, ref bbb, ccc, ddd, _X[ 6], 9);
258 III(ref ddd, eee, ref aaa, bbb, ccc, _X[11], 13);
259 III(ref ccc, ddd, ref eee, aaa, bbb, _X[ 3], 15);
260 III(ref bbb, ccc, ref ddd, eee, aaa, _X[ 7], 7);
261 III(ref aaa, bbb, ref ccc, ddd, eee, _X[ 0], 12);
262 III(ref eee, aaa, ref bbb, ccc, ddd, _X[13], 8);
263 III(ref ddd, eee, ref aaa, bbb, ccc, _X[ 5], 9);
264 III(ref ccc, ddd, ref eee, aaa, bbb, _X[10], 11);
265 III(ref bbb, ccc, ref ddd, eee, aaa, _X[14], 7);
266 III(ref aaa, bbb, ref ccc, ddd, eee, _X[15], 7);
267 III(ref eee, aaa, ref bbb, ccc, ddd, _X[ 8], 12);
268 III(ref ddd, eee, ref aaa, bbb, ccc, _X[12], 7);
269 III(ref ccc, ddd, ref eee, aaa, bbb, _X[ 4], 6);
270 III(ref bbb, ccc, ref ddd, eee, aaa, _X[ 9], 15);
271 III(ref aaa, bbb, ref ccc, ddd, eee, _X[ 1], 13);
272 III(ref eee, aaa, ref bbb, ccc, ddd, _X[ 2], 11);
273 /* parallel round 3 */
274 HHH(ref ddd, eee, ref aaa, bbb, ccc, _X[15], 9);
275 HHH(ref ccc, ddd, ref eee, aaa, bbb, _X[ 5], 7);
276 HHH(ref bbb, ccc, ref ddd, eee, aaa, _X[ 1], 15);
277 HHH(ref aaa, bbb, ref ccc, ddd, eee, _X[ 3], 11);
278 HHH(ref eee, aaa, ref bbb, ccc, ddd, _X[ 7], 8);
279 HHH(ref ddd, eee, ref aaa, bbb, ccc, _X[14], 6);
280 HHH(ref ccc, ddd, ref eee, aaa, bbb, _X[ 6], 6);
281 HHH(ref bbb, ccc, ref ddd, eee, aaa, _X[ 9], 14);
282 HHH(ref aaa, bbb, ref ccc, ddd, eee, _X[11], 12);
283 HHH(ref eee, aaa, ref bbb, ccc, ddd, _X[ 8], 13);
284 HHH(ref ddd, eee, ref aaa, bbb, ccc, _X[12], 5);
285 HHH(ref ccc, ddd, ref eee, aaa, bbb, _X[ 2], 14);
286 HHH(ref bbb, ccc, ref ddd, eee, aaa, _X[10], 13);
287 HHH(ref aaa, bbb, ref ccc, ddd, eee, _X[ 0], 13);
288 HHH(ref eee, aaa, ref bbb, ccc, ddd, _X[ 4], 7);
289 HHH(ref ddd, eee, ref aaa, bbb, ccc, _X[13], 5);
290 /* parallel round 4 */
291 GGG(ref ccc, ddd, ref eee, aaa, bbb, _X[ 8], 15);
292 GGG(ref bbb, ccc, ref ddd, eee, aaa, _X[ 6], 5);
293 GGG(ref aaa, bbb, ref ccc, ddd, eee, _X[ 4], 8);
294 GGG(ref eee, aaa, ref bbb, ccc, ddd, _X[ 1], 11);
295 GGG(ref ddd, eee, ref aaa, bbb, ccc, _X[ 3], 14);
296 GGG(ref ccc, ddd, ref eee, aaa, bbb, _X[11], 14);
297 GGG(ref bbb, ccc, ref ddd, eee, aaa, _X[15], 6);
298 GGG(ref aaa, bbb, ref ccc, ddd, eee, _X[ 0], 14);
299 GGG(ref eee, aaa, ref bbb, ccc, ddd, _X[ 5], 6);
300 GGG(ref ddd, eee, ref aaa, bbb, ccc, _X[12], 9);
301 GGG(ref ccc, ddd, ref eee, aaa, bbb, _X[ 2], 12);
302 GGG(ref bbb, ccc, ref ddd, eee, aaa, _X[13], 9);
303 GGG(ref aaa, bbb, ref ccc, ddd, eee, _X[ 9], 12);
304 GGG(ref eee, aaa, ref bbb, ccc, ddd, _X[ 7], 5);
305 GGG(ref ddd, eee, ref aaa, bbb, ccc, _X[10], 15);
306 GGG(ref ccc, ddd, ref eee, aaa, bbb, _X[14], 8);
307 /* parallel round 5 */
308 FFF(ref bbb, ccc, ref ddd, eee, aaa, _X[12], 8);
309 FFF(ref aaa, bbb, ref ccc, ddd, eee, _X[15], 5);
310 FFF(ref eee, aaa, ref bbb, ccc, ddd, _X[10], 12);
311 FFF(ref ddd, eee, ref aaa, bbb, ccc, _X[ 4], 9);
312 FFF(ref ccc, ddd, ref eee, aaa, bbb, _X[ 1], 12);
313 FFF(ref bbb, ccc, ref ddd, eee, aaa, _X[ 5], 5);
314 FFF(ref aaa, bbb, ref ccc, ddd, eee, _X[ 8], 14);
315 FFF(ref eee, aaa, ref bbb, ccc, ddd, _X[ 7], 6);
316 FFF(ref ddd, eee, ref aaa, bbb, ccc, _X[ 6], 8);
317 FFF(ref ccc, ddd, ref eee, aaa, bbb, _X[ 2], 13);
318 FFF(ref bbb, ccc, ref ddd, eee, aaa, _X[13], 6);
319 FFF(ref aaa, bbb, ref ccc, ddd, eee, _X[14], 5);
320 FFF(ref eee, aaa, ref bbb, ccc, ddd, _X[ 0], 15);
321 FFF(ref ddd, eee, ref aaa, bbb, ccc, _X[ 3], 13);
322 FFF(ref ccc, ddd, ref eee, aaa, bbb, _X[ 9], 11);
323 FFF(ref bbb, ccc, ref ddd, eee, aaa, _X[11], 11);
324 /* combine results */
325 ddd += cc + _HashValue[1]; /* final result for _HashValue[0] */
326 _HashValue[1] = _HashValue[2] + dd + eee;
327 _HashValue[2] = _HashValue[3] + ee + aaa;
328 _HashValue[3] = _HashValue[4] + aa + bbb;
329 _HashValue[4] = _HashValue[0] + bb + ccc;
330 _HashValue[0] = ddd;
332 private void CompressFinal(ulong length) {
333 uint lswlen = (uint)(length & 0xFFFFFFFF);
334 uint mswlen = (uint)(length >> 32);
335 // clear _X
336 Array.Clear(_X, 0, _X.Length);
337 // put bytes from _ProcessingBuffer into _X
338 int ptr = 0;
339 for (uint i = 0; i < (lswlen & 63); i++) {
340 // byte i goes into word X[i div 4] at pos. 8*(i mod 4)
341 _X[i >> 2] ^= ((uint)_ProcessingBuffer[ptr++]) << (int)(8 * (i & 3));
343 // append the bit m_n == 1
344 _X[(lswlen >> 2) & 15] ^= (uint)1 << (int)(8 * (lswlen & 3) + 7);
345 if ((lswlen & 63) > 55) {
346 // length goes to next block
347 Compress();
348 Array.Clear(_X, 0, _X.Length);
350 // append length in bits
351 _X[14] = lswlen << 3;
352 _X[15] = (lswlen >> 29) | (mswlen << 3);
353 Compress();
356 // the following methods should be inlined by the compiler
357 private uint ROL(uint x, int n) {
358 return (((x) << (n)) | ((x) >> (32-(n))));
360 private uint F(uint x, uint y, uint z) {
361 return ((x) ^ (y) ^ (z)) ;
363 private uint G(uint x, uint y, uint z) {
364 return (((x) & (y)) | (~(x) & (z)));
366 private uint H(uint x, uint y, uint z) {
367 return (((x) | ~(y)) ^ (z));
369 private uint I(uint x, uint y, uint z) {
370 return (((x) & (z)) | ((y) & ~(z)));
372 private uint J(uint x, uint y, uint z) {
373 return ((x) ^ ((y) | ~(z)));
375 private void FF(ref uint a, uint b, ref uint c, uint d, uint e, uint x, int s) {
376 a += F(b, c, d) + x;
377 a = ROL(a, s) + e;
378 c = ROL(c, 10);
380 private void GG(ref uint a, uint b, ref uint c, uint d, uint e, uint x, int s) {
381 a += G(b, c, d) + x + 0x5a827999;
382 a = ROL(a, s) + e;
383 c = ROL(c, 10);
385 private void HH(ref uint a, uint b, ref uint c, uint d, uint e, uint x, int s) {
386 a += H(b, c, d) + x + 0x6ed9eba1;
387 a = ROL(a, s) + e;
388 c = ROL(c, 10);
390 private void II(ref uint a, uint b, ref uint c, uint d, uint e, uint x, int s) {
391 a += I(b, c, d) + x + 0x8f1bbcdc;
392 a = ROL(a, s) + e;
393 c = ROL(c, 10);
395 private void JJ(ref uint a, uint b, ref uint c, uint d, uint e, uint x, int s) {
396 a += J(b, c, d) + x + 0xa953fd4e;
397 a = ROL(a, s) + e;
398 c = ROL(c, 10);
400 private void FFF(ref uint a, uint b, ref uint c, uint d, uint e, uint x, int s) {
401 a += F(b, c, d) + x;
402 a = ROL(a, s) + e;
403 c = ROL(c, 10);
405 private void GGG(ref uint a, uint b, ref uint c, uint d, uint e, uint x, int s) {
406 a += G(b, c, d) + x + 0x7a6d76e9;
407 a = ROL(a, s) + e;
408 c = ROL(c, 10);
410 private void HHH(ref uint a, uint b, ref uint c, uint d, uint e, uint x, int s) {
411 a += H(b, c, d) + x + 0x6d703ef3;
412 a = ROL(a, s) + e;
413 c = ROL(c, 10);
415 private void III(ref uint a, uint b, ref uint c, uint d, uint e, uint x, int s) {
416 a += I(b, c, d) + x + 0x5c4dd124;
417 a = ROL(a, s) + e;
418 c = ROL(c, 10);
420 private void JJJ(ref uint a, uint b, ref uint c, uint d, uint e, uint x, int s) {
421 a += J(b, c, d) + x + 0x50a28be6;
422 a = ROL(a, s) + e;
423 c = ROL(c, 10);
426 /// <summary>
427 /// A buffer that holds the extra data.
428 /// </summary>
429 private byte[] _ProcessingBuffer;
430 /// <summary>
431 /// The X vectors.
432 /// </summary>
433 private uint[] _X;
434 /// <summary>
435 /// The current value of the hash.
436 /// </summary>
437 private uint[] _HashValue;
438 /// <summary>
439 /// The number of bytes hashed.
440 /// </summary>
441 private ulong _Length;
443 private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.
445 private const int BLOCK_SIZE_BYTES = 64;
449 #endif