2 // RIPEMD160Managed.cs: Implements the RIPEMD-160 hash algorithm
5 // Pieter Philippaerts (Pieter@mentalis.org)
7 // (C) 2003 The Mentalis.org Team (http://www.mentalis.org/)
10 // - http://www.esat.kuleuven.ac.be/~cosicart/ps/AB-9601/
14 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39 using System
.Runtime
.InteropServices
;
41 namespace System
.Security
.Cryptography
{
43 /// Computes the <see cref="RIPEMD160"/> hash for the input data.
45 public class RIPEMD160Managed
: RIPEMD160
{ // not 'sealed' according to preliminary docs; this may change though
47 /// Initializes a new instance of the <see cref="RIPEMD160Managed"/> class. This class cannot be inherited.
49 public RIPEMD160Managed() {
51 _HashValue
= new uint[5];
52 _ProcessingBuffer
= new byte[BLOCK_SIZE_BYTES
];
56 /// Initializes an instance of <see cref="RIPEMD160Managed"/>.
58 /// <exception cref="ObjectDisposedException">The RIPEMD160Managed instance has been disposed.</exception>
59 public override void Initialize() {
60 _HashValue
[0] = 0x67452301;
61 _HashValue
[1] = 0xefcdab89;
62 _HashValue
[2] = 0x98badcfe;
63 _HashValue
[3] = 0x10325476;
64 _HashValue
[4] = 0xc3d2e1f0;
66 _ProcessingBufferCount
= 0;
69 /// Routes data written to the object into the <see cref="RIPEMD160"/> hash algorithm for computing the hash.
71 /// <param name="array">The array of data bytes.</param>
72 /// <param name="ibStart">The offset into the byte array from which to begin using data.</param>
73 /// <param name="cbSize">The number of bytes in the array to use as data.</param>
74 /// <exception cref="ObjectDisposedException">The <see cref="RIPEMD160Managed"/> instance has been disposed.</exception>
75 protected override void HashCore(byte[] array
, int ibStart
, int cbSize
) {
79 _Length
+= (uint)cbSize
; // global length
81 if (_ProcessingBufferCount
!= 0) {
82 if (cbSize
< (BLOCK_SIZE_BYTES
- _ProcessingBufferCount
)) {
83 System
.Buffer
.BlockCopy (array
, ibStart
, _ProcessingBuffer
, _ProcessingBufferCount
, cbSize
);
84 _ProcessingBufferCount
+= cbSize
;
87 i
= (BLOCK_SIZE_BYTES
- _ProcessingBufferCount
);
88 System
.Buffer
.BlockCopy (array
, ibStart
, _ProcessingBuffer
, _ProcessingBufferCount
, i
);
89 ProcessBlock (_ProcessingBuffer
, 0);
90 _ProcessingBufferCount
= 0;
96 for (i
=0; i
<cbSize
-cbSize
%BLOCK_SIZE_BYTES
; i
+= BLOCK_SIZE_BYTES
) {
97 ProcessBlock (array
, ibStart
+i
);
100 if (cbSize
%BLOCK_SIZE_BYTES
!= 0) {
101 System
.Buffer
.BlockCopy (array
, cbSize
-cbSize
%BLOCK_SIZE_BYTES
+ibStart
, _ProcessingBuffer
, 0, cbSize
%BLOCK_SIZE_BYTES
);
102 _ProcessingBufferCount
= cbSize
%BLOCK_SIZE_BYTES
;
106 /// Returns the computed <see cref="RIPEMD160"/> hash as an array of bytes after all data has been written to the object.
108 /// <returns>The computed hash value.</returns>
109 /// <exception cref="ObjectDisposedException">The <see cref="RIPEMD160Managed"/> instance has been disposed.</exception>
110 protected override byte[] HashFinal() {
111 CompressFinal(_Length
);
112 byte[] hash
= new byte[20];
113 System
.Buffer
.BlockCopy(_HashValue
, 0, hash
, 0, 20);
117 /// Releases the resources used by the <see cref="RIPEMD160Managed"/>.
119 /// <param name="disposing"><b>true</b> to release both managed and unmanaged resources; <b>false</b> to release only unmanaged resources.</param>
120 protected override void Dispose(bool disposing
) {
124 /// Finalizes the RIPEMD160Managed.
126 ~
RIPEMD160Managed() {
131 /// Processes one block of data.
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
) {
136 System
.Buffer
.BlockCopy(buffer
, offset
, _X
, 0, 64);
140 private void Compress() {
141 uint aa
= _HashValue
[0], bb
= _HashValue
[1], cc
= _HashValue
[2], dd
= _HashValue
[3], ee
= _HashValue
[4];
142 uint aaa
= _HashValue
[0], bbb
= _HashValue
[1], ccc
= _HashValue
[2], ddd
= _HashValue
[3], eee
= _HashValue
[4];
144 FF(ref aa
, bb
, ref cc
, dd
, ee
, _X
[ 0], 11);
145 FF(ref ee
, aa
, ref bb
, cc
, dd
, _X
[ 1], 14);
146 FF(ref dd
, ee
, ref aa
, bb
, cc
, _X
[ 2], 15);
147 FF(ref cc
, dd
, ref ee
, aa
, bb
, _X
[ 3], 12);
148 FF(ref bb
, cc
, ref dd
, ee
, aa
, _X
[ 4], 5);
149 FF(ref aa
, bb
, ref cc
, dd
, ee
, _X
[ 5], 8);
150 FF(ref ee
, aa
, ref bb
, cc
, dd
, _X
[ 6], 7);
151 FF(ref dd
, ee
, ref aa
, bb
, cc
, _X
[ 7], 9);
152 FF(ref cc
, dd
, ref ee
, aa
, bb
, _X
[ 8], 11);
153 FF(ref bb
, cc
, ref dd
, ee
, aa
, _X
[ 9], 13);
154 FF(ref aa
, bb
, ref cc
, dd
, ee
, _X
[10], 14);
155 FF(ref ee
, aa
, ref bb
, cc
, dd
, _X
[11], 15);
156 FF(ref dd
, ee
, ref aa
, bb
, cc
, _X
[12], 6);
157 FF(ref cc
, dd
, ref ee
, aa
, bb
, _X
[13], 7);
158 FF(ref bb
, cc
, ref dd
, ee
, aa
, _X
[14], 9);
159 FF(ref aa
, bb
, ref cc
, dd
, ee
, _X
[15], 8);
161 GG(ref ee
, aa
, ref bb
, cc
, dd
, _X
[ 7], 7);
162 GG(ref dd
, ee
, ref aa
, bb
, cc
, _X
[ 4], 6);
163 GG(ref cc
, dd
, ref ee
, aa
, bb
, _X
[13], 8);
164 GG(ref bb
, cc
, ref dd
, ee
, aa
, _X
[ 1], 13);
165 GG(ref aa
, bb
, ref cc
, dd
, ee
, _X
[10], 11);
166 GG(ref ee
, aa
, ref bb
, cc
, dd
, _X
[ 6], 9);
167 GG(ref dd
, ee
, ref aa
, bb
, cc
, _X
[15], 7);
168 GG(ref cc
, dd
, ref ee
, aa
, bb
, _X
[ 3], 15);
169 GG(ref bb
, cc
, ref dd
, ee
, aa
, _X
[12], 7);
170 GG(ref aa
, bb
, ref cc
, dd
, ee
, _X
[ 0], 12);
171 GG(ref ee
, aa
, ref bb
, cc
, dd
, _X
[ 9], 15);
172 GG(ref dd
, ee
, ref aa
, bb
, cc
, _X
[ 5], 9);
173 GG(ref cc
, dd
, ref ee
, aa
, bb
, _X
[ 2], 11);
174 GG(ref bb
, cc
, ref dd
, ee
, aa
, _X
[14], 7);
175 GG(ref aa
, bb
, ref cc
, dd
, ee
, _X
[11], 13);
176 GG(ref ee
, aa
, ref bb
, cc
, dd
, _X
[ 8], 12);
178 HH(ref dd
, ee
, ref aa
, bb
, cc
, _X
[ 3], 11);
179 HH(ref cc
, dd
, ref ee
, aa
, bb
, _X
[10], 13);
180 HH(ref bb
, cc
, ref dd
, ee
, aa
, _X
[14], 6);
181 HH(ref aa
, bb
, ref cc
, dd
, ee
, _X
[ 4], 7);
182 HH(ref ee
, aa
, ref bb
, cc
, dd
, _X
[ 9], 14);
183 HH(ref dd
, ee
, ref aa
, bb
, cc
, _X
[15], 9);
184 HH(ref cc
, dd
, ref ee
, aa
, bb
, _X
[ 8], 13);
185 HH(ref bb
, cc
, ref dd
, ee
, aa
, _X
[ 1], 15);
186 HH(ref aa
, bb
, ref cc
, dd
, ee
, _X
[ 2], 14);
187 HH(ref ee
, aa
, ref bb
, cc
, dd
, _X
[ 7], 8);
188 HH(ref dd
, ee
, ref aa
, bb
, cc
, _X
[ 0], 13);
189 HH(ref cc
, dd
, ref ee
, aa
, bb
, _X
[ 6], 6);
190 HH(ref bb
, cc
, ref dd
, ee
, aa
, _X
[13], 5);
191 HH(ref aa
, bb
, ref cc
, dd
, ee
, _X
[11], 12);
192 HH(ref ee
, aa
, ref bb
, cc
, dd
, _X
[ 5], 7);
193 HH(ref dd
, ee
, ref aa
, bb
, cc
, _X
[12], 5);
195 II(ref cc
, dd
, ref ee
, aa
, bb
, _X
[ 1], 11);
196 II(ref bb
, cc
, ref dd
, ee
, aa
, _X
[ 9], 12);
197 II(ref aa
, bb
, ref cc
, dd
, ee
, _X
[11], 14);
198 II(ref ee
, aa
, ref bb
, cc
, dd
, _X
[10], 15);
199 II(ref dd
, ee
, ref aa
, bb
, cc
, _X
[ 0], 14);
200 II(ref cc
, dd
, ref ee
, aa
, bb
, _X
[ 8], 15);
201 II(ref bb
, cc
, ref dd
, ee
, aa
, _X
[12], 9);
202 II(ref aa
, bb
, ref cc
, dd
, ee
, _X
[ 4], 8);
203 II(ref ee
, aa
, ref bb
, cc
, dd
, _X
[13], 9);
204 II(ref dd
, ee
, ref aa
, bb
, cc
, _X
[ 3], 14);
205 II(ref cc
, dd
, ref ee
, aa
, bb
, _X
[ 7], 5);
206 II(ref bb
, cc
, ref dd
, ee
, aa
, _X
[15], 6);
207 II(ref aa
, bb
, ref cc
, dd
, ee
, _X
[14], 8);
208 II(ref ee
, aa
, ref bb
, cc
, dd
, _X
[ 5], 6);
209 II(ref dd
, ee
, ref aa
, bb
, cc
, _X
[ 6], 5);
210 II(ref cc
, dd
, ref ee
, aa
, bb
, _X
[ 2], 12);
212 JJ(ref bb
, cc
, ref dd
, ee
, aa
, _X
[ 4], 9);
213 JJ(ref aa
, bb
, ref cc
, dd
, ee
, _X
[ 0], 15);
214 JJ(ref ee
, aa
, ref bb
, cc
, dd
, _X
[ 5], 5);
215 JJ(ref dd
, ee
, ref aa
, bb
, cc
, _X
[ 9], 11);
216 JJ(ref cc
, dd
, ref ee
, aa
, bb
, _X
[ 7], 6);
217 JJ(ref bb
, cc
, ref dd
, ee
, aa
, _X
[12], 8);
218 JJ(ref aa
, bb
, ref cc
, dd
, ee
, _X
[ 2], 13);
219 JJ(ref ee
, aa
, ref bb
, cc
, dd
, _X
[10], 12);
220 JJ(ref dd
, ee
, ref aa
, bb
, cc
, _X
[14], 5);
221 JJ(ref cc
, dd
, ref ee
, aa
, bb
, _X
[ 1], 12);
222 JJ(ref bb
, cc
, ref dd
, ee
, aa
, _X
[ 3], 13);
223 JJ(ref aa
, bb
, ref cc
, dd
, ee
, _X
[ 8], 14);
224 JJ(ref ee
, aa
, ref bb
, cc
, dd
, _X
[11], 11);
225 JJ(ref dd
, ee
, ref aa
, bb
, cc
, _X
[ 6], 8);
226 JJ(ref cc
, dd
, ref ee
, aa
, bb
, _X
[15], 5);
227 JJ(ref bb
, cc
, ref dd
, ee
, aa
, _X
[13], 6);
228 /* parallel round 1 */
229 JJJ(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[ 5], 8);
230 JJJ(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[14], 9);
231 JJJ(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[ 7], 9);
232 JJJ(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[ 0], 11);
233 JJJ(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[ 9], 13);
234 JJJ(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[ 2], 15);
235 JJJ(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[11], 15);
236 JJJ(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[ 4], 5);
237 JJJ(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[13], 7);
238 JJJ(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[ 6], 7);
239 JJJ(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[15], 8);
240 JJJ(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[ 8], 11);
241 JJJ(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[ 1], 14);
242 JJJ(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[10], 14);
243 JJJ(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[ 3], 12);
244 JJJ(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[12], 6);
245 /* parallel round 2 */
246 III(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[ 6], 9);
247 III(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[11], 13);
248 III(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[ 3], 15);
249 III(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[ 7], 7);
250 III(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[ 0], 12);
251 III(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[13], 8);
252 III(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[ 5], 9);
253 III(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[10], 11);
254 III(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[14], 7);
255 III(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[15], 7);
256 III(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[ 8], 12);
257 III(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[12], 7);
258 III(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[ 4], 6);
259 III(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[ 9], 15);
260 III(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[ 1], 13);
261 III(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[ 2], 11);
262 /* parallel round 3 */
263 HHH(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[15], 9);
264 HHH(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[ 5], 7);
265 HHH(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[ 1], 15);
266 HHH(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[ 3], 11);
267 HHH(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[ 7], 8);
268 HHH(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[14], 6);
269 HHH(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[ 6], 6);
270 HHH(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[ 9], 14);
271 HHH(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[11], 12);
272 HHH(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[ 8], 13);
273 HHH(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[12], 5);
274 HHH(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[ 2], 14);
275 HHH(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[10], 13);
276 HHH(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[ 0], 13);
277 HHH(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[ 4], 7);
278 HHH(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[13], 5);
279 /* parallel round 4 */
280 GGG(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[ 8], 15);
281 GGG(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[ 6], 5);
282 GGG(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[ 4], 8);
283 GGG(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[ 1], 11);
284 GGG(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[ 3], 14);
285 GGG(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[11], 14);
286 GGG(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[15], 6);
287 GGG(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[ 0], 14);
288 GGG(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[ 5], 6);
289 GGG(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[12], 9);
290 GGG(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[ 2], 12);
291 GGG(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[13], 9);
292 GGG(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[ 9], 12);
293 GGG(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[ 7], 5);
294 GGG(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[10], 15);
295 GGG(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[14], 8);
296 /* parallel round 5 */
297 FFF(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[12], 8);
298 FFF(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[15], 5);
299 FFF(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[10], 12);
300 FFF(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[ 4], 9);
301 FFF(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[ 1], 12);
302 FFF(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[ 5], 5);
303 FFF(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[ 8], 14);
304 FFF(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[ 7], 6);
305 FFF(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[ 6], 8);
306 FFF(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[ 2], 13);
307 FFF(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[13], 6);
308 FFF(ref aaa
, bbb
, ref ccc
, ddd
, eee
, _X
[14], 5);
309 FFF(ref eee
, aaa
, ref bbb
, ccc
, ddd
, _X
[ 0], 15);
310 FFF(ref ddd
, eee
, ref aaa
, bbb
, ccc
, _X
[ 3], 13);
311 FFF(ref ccc
, ddd
, ref eee
, aaa
, bbb
, _X
[ 9], 11);
312 FFF(ref bbb
, ccc
, ref ddd
, eee
, aaa
, _X
[11], 11);
313 /* combine results */
314 ddd
+= cc
+ _HashValue
[1]; /* final result for _HashValue[0] */
315 _HashValue
[1] = _HashValue
[2] + dd
+ eee
;
316 _HashValue
[2] = _HashValue
[3] + ee
+ aaa
;
317 _HashValue
[3] = _HashValue
[4] + aa
+ bbb
;
318 _HashValue
[4] = _HashValue
[0] + bb
+ ccc
;
321 private void CompressFinal(ulong length
) {
322 uint lswlen
= (uint)(length
& 0xFFFFFFFF);
323 uint mswlen
= (uint)(length
>> 32);
325 Array
.Clear(_X
, 0, _X
.Length
);
326 // put bytes from _ProcessingBuffer into _X
328 for (uint i
= 0; i
< (lswlen
& 63); i
++) {
329 // byte i goes into word X[i div 4] at pos. 8*(i mod 4)
330 _X
[i
>> 2] ^
= ((uint)_ProcessingBuffer
[ptr
++]) << (int)(8 * (i
& 3));
332 // append the bit m_n == 1
333 _X
[(lswlen
>> 2) & 15] ^
= (uint)1 << (int)(8 * (lswlen
& 3) + 7);
334 if ((lswlen
& 63) > 55) {
335 // length goes to next block
337 Array
.Clear(_X
, 0, _X
.Length
);
339 // append length in bits
340 _X
[14] = lswlen
<< 3;
341 _X
[15] = (lswlen
>> 29) | (mswlen
<< 3);
345 // the following methods should be inlined by the compiler
346 private uint ROL(uint x
, int n
) {
347 return (((x
) << (n
)) | ((x
) >> (32-(n
))));
349 private uint F(uint x
, uint y
, uint z
) {
350 return ((x
) ^
(y
) ^
(z
)) ;
352 private uint G(uint x
, uint y
, uint z
) {
353 return (((x
) & (y
)) | (~
(x
) & (z
)));
355 private uint H(uint x
, uint y
, uint z
) {
356 return (((x
) | ~
(y
)) ^
(z
));
358 private uint I(uint x
, uint y
, uint z
) {
359 return (((x
) & (z
)) | ((y
) & ~
(z
)));
361 private uint J(uint x
, uint y
, uint z
) {
362 return ((x
) ^
((y
) | ~
(z
)));
364 private void FF(ref uint a
, uint b
, ref uint c
, uint d
, uint e
, uint x
, int s
) {
369 private void GG(ref uint a
, uint b
, ref uint c
, uint d
, uint e
, uint x
, int s
) {
370 a
+= G(b
, c
, d
) + x
+ 0x5a827999;
374 private void HH(ref uint a
, uint b
, ref uint c
, uint d
, uint e
, uint x
, int s
) {
375 a
+= H(b
, c
, d
) + x
+ 0x6ed9eba1;
379 private void II(ref uint a
, uint b
, ref uint c
, uint d
, uint e
, uint x
, int s
) {
380 a
+= I(b
, c
, d
) + x
+ 0x8f1bbcdc;
384 private void JJ(ref uint a
, uint b
, ref uint c
, uint d
, uint e
, uint x
, int s
) {
385 a
+= J(b
, c
, d
) + x
+ 0xa953fd4e;
389 private void FFF(ref uint a
, uint b
, ref uint c
, uint d
, uint e
, uint x
, int s
) {
394 private void GGG(ref uint a
, uint b
, ref uint c
, uint d
, uint e
, uint x
, int s
) {
395 a
+= G(b
, c
, d
) + x
+ 0x7a6d76e9;
399 private void HHH(ref uint a
, uint b
, ref uint c
, uint d
, uint e
, uint x
, int s
) {
400 a
+= H(b
, c
, d
) + x
+ 0x6d703ef3;
404 private void III(ref uint a
, uint b
, ref uint c
, uint d
, uint e
, uint x
, int s
) {
405 a
+= I(b
, c
, d
) + x
+ 0x5c4dd124;
409 private void JJJ(ref uint a
, uint b
, ref uint c
, uint d
, uint e
, uint x
, int s
) {
410 a
+= J(b
, c
, d
) + x
+ 0x50a28be6;
416 /// A buffer that holds the extra data.
418 private byte[] _ProcessingBuffer
;
424 /// The current value of the hash.
426 private uint[] _HashValue
;
428 /// The number of bytes hashed.
430 private ulong _Length
;
432 private int _ProcessingBufferCount
; // Counts how much data we have stored that still needs processed.
434 private const int BLOCK_SIZE_BYTES
= 64;