PluginProbe
ManageWP Worker / 3.9.28
ManageWP Worker v3.9.28
4.9.38 4.9.37 4.9.36 4.9.35 4.9.34 3.8.7 3.8.8 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.18 3.9.19 3.9.2 3.9.20 3.9.21 3.9.22 3.9.23 3.9.24 All 73 releases
worker / lib / PHPSecLib / Crypt / Hash.php

Hash.php in ManageWP Worker 3.9.28, at lib/PHPSecLib/Crypt/Hash.php

824 lines 28.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
4 /**
5 * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
6 *
7 * Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
8 *
9 * md2, md5, md5-96, sha1, sha1-96, sha256, sha384, and sha512
10 *
11 * If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
12 * the hash. If no valid algorithm is provided, sha1 will be used.
13 *
14 * PHP versions 4 and 5
15 *
16 * {@internal The variable names are the same as those in
17 * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
18 *
19 * Here's a short example of how to use this library:
20 * <code>
21 * <?php
22 * include('Crypt/Hash.php');
23 *
24 * $hash = new Crypt_Hash('sha1');
25 *
26 * $hash->setKey('abcdefg');
27 *
28 * echo base64_encode($hash->hash('abcdefg'));
29 * ?>
30 * </code>
31 *
32 * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
33 * of this software and associated documentation files (the "Software"), to deal
34 * in the Software without restriction, including without limitation the rights
35 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36 * copies of the Software, and to permit persons to whom the Software is
37 * furnished to do so, subject to the following conditions:
38 *
39 * The above copyright notice and this permission notice shall be included in
40 * all copies or substantial portions of the Software.
41 *
42 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
48 * THE SOFTWARE.
49 *
50 * @category Crypt
51 * @package Crypt_Hash
52 * @author Jim Wigginton <terrafrost@php.net>
53 * @copyright MMVII Jim Wigginton
54 * @license http://www.opensource.org/licenses/mit-license.html MIT License
55 * @link http://phpseclib.sourceforge.net
56 */
57
58 /**#@+
59 * @access private
60 * @see Crypt_Hash::Crypt_Hash()
61 */
62 /**
63 * Toggles the internal implementation
64 */
65 define('CRYPT_HASH_MODE_INTERNAL', 1);
66 /**
67 * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
68 */
69 define('CRYPT_HASH_MODE_MHASH', 2);
70 /**
71 * Toggles the hash() implementation, which works on PHP 5.1.2+.
72 */
73 define('CRYPT_HASH_MODE_HASH', 3);
74 /**#@-*/
75
76 /**
77 * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
78 *
79 * @author Jim Wigginton <terrafrost@php.net>
80 * @version 0.1.0
81 * @access public
82 * @package Crypt_Hash
83 */
84 class Crypt_Hash {
85 /**
86 * Byte-length of compression blocks / key (Internal HMAC)
87 *
88 * @see Crypt_Hash::setAlgorithm()
89 * @var Integer
90 * @access private
91 */
92 var $b;
93
94 /**
95 * Byte-length of hash output (Internal HMAC)
96 *
97 * @see Crypt_Hash::setHash()
98 * @var Integer
99 * @access private
100 */
101 var $l = false;
102
103 /**
104 * Hash Algorithm
105 *
106 * @see Crypt_Hash::setHash()
107 * @var String
108 * @access private
109 */
110 var $hash;
111
112 /**
113 * Key
114 *
115 * @see Crypt_Hash::setKey()
116 * @var String
117 * @access private
118 */
119 var $key = false;
120
121 /**
122 * Outer XOR (Internal HMAC)
123 *
124 * @see Crypt_Hash::setKey()
125 * @var String
126 * @access private
127 */
128 var $opad;
129
130 /**
131 * Inner XOR (Internal HMAC)
132 *
133 * @see Crypt_Hash::setKey()
134 * @var String
135 * @access private
136 */
137 var $ipad;
138
139 /**
140 * Default Constructor.
141 *
142 * @param optional String $hash
143 * @return Crypt_Hash
144 * @access public
145 */
146 function Crypt_Hash($hash = 'sha1')
147 {
148 if ( !defined('CRYPT_HASH_MODE') ) {
149 switch (true) {
150 case extension_loaded('hash'):
151 define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
152 break;
153 case extension_loaded('mhash'):
154 define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH);
155 break;
156 default:
157 define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL);
158 }
159 }
160
161 $this->setHash($hash);
162 }
163
164 /**
165 * Sets the key for HMACs
166 *
167 * Keys can be of any length.
168 *
169 * @access public
170 * @param optional String $key
171 */
172 function setKey($key = false)
173 {
174 $this->key = $key;
175 }
176
177 /**
178 * Sets the hash function.
179 *
180 * @access public
181 * @param String $hash
182 */
183 function setHash($hash)
184 {
185 $hash = strtolower($hash);
186 switch ($hash) {
187 case 'md5-96':
188 case 'sha1-96':
189 $this->l = 12; // 96 / 8 = 12
190 break;
191 case 'md2':
192 case 'md5':
193 $this->l = 16;
194 break;
195 case 'sha1':
196 $this->l = 20;
197 break;
198 case 'sha256':
199 $this->l = 32;
200 break;
201 case 'sha384':
202 $this->l = 48;
203 break;
204 case 'sha512':
205 $this->l = 64;
206 }
207
208 switch ($hash) {
209 case 'md2':
210 $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
211 CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
212 break;
213 case 'sha384':
214 case 'sha512':
215 $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
216 break;
217 default:
218 $mode = CRYPT_HASH_MODE;
219 }
220
221 switch ( $mode ) {
222 case CRYPT_HASH_MODE_MHASH:
223 switch ($hash) {
224 case 'md5':
225 case 'md5-96':
226 $this->hash = MHASH_MD5;
227 break;
228 case 'sha256':
229 $this->hash = MHASH_SHA256;
230 break;
231 case 'sha1':
232 case 'sha1-96':
233 default:
234 $this->hash = MHASH_SHA1;
235 }
236 return;
237 case CRYPT_HASH_MODE_HASH:
238 switch ($hash) {
239 case 'md5':
240 case 'md5-96':
241 $this->hash = 'md5';
242 return;
243 case 'md2':
244 case 'sha256':
245 case 'sha384':
246 case 'sha512':
247 $this->hash = $hash;
248 return;
249 case 'sha1':
250 case 'sha1-96':
251 default:
252 $this->hash = 'sha1';
253 }
254 return;
255 }
256
257 switch ($hash) {
258 case 'md2':
259 $this->b = 16;
260 $this->hash = array($this, '_md2');
261 break;
262 case 'md5':
263 case 'md5-96':
264 $this->b = 64;
265 $this->hash = array($this, '_md5');
266 break;
267 case 'sha256':
268 $this->b = 64;
269 $this->hash = array($this, '_sha256');
270 break;
271 case 'sha384':
272 case 'sha512':
273 $this->b = 128;
274 $this->hash = array($this, '_sha512');
275 break;
276 case 'sha1':
277 case 'sha1-96':
278 default:
279 $this->b = 64;
280 $this->hash = array($this, '_sha1');
281 }
282
283 $this->ipad = str_repeat(chr(0x36), $this->b);
284 $this->opad = str_repeat(chr(0x5C), $this->b);
285 }
286
287 /**
288 * Compute the HMAC.
289 *
290 * @access public
291 * @param String $text
292 * @return String
293 */
294 function hash($text)
295 {
296 $mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
297
298 if (!empty($this->key) || is_string($this->key)) {
299 switch ( $mode ) {
300 case CRYPT_HASH_MODE_MHASH:
301 $output = mhash($this->hash, $text, $this->key);
302 break;
303 case CRYPT_HASH_MODE_HASH:
304 $output = hash_hmac($this->hash, $text, $this->key, true);
305 break;
306 case CRYPT_HASH_MODE_INTERNAL:
307 /* "Applications that use keys longer than B bytes will first hash the key using H and then use the
308 resultant L byte string as the actual key to HMAC."
309
310 -- http://tools.ietf.org/html/rfc2104#section-2 */
311 $key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
312
313 $key = str_pad($key, $this->b, chr(0)); // step 1
314 $temp = $this->ipad ^ $key; // step 2
315 $temp .= $text; // step 3
316 $temp = call_user_func($this->hash, $temp); // step 4
317 $output = $this->opad ^ $key; // step 5
318 $output.= $temp; // step 6
319 $output = call_user_func($this->hash, $output); // step 7
320 }
321 } else {
322 switch ( $mode ) {
323 case CRYPT_HASH_MODE_MHASH:
324 $output = mhash($this->hash, $text);
325 break;
326 case CRYPT_HASH_MODE_HASH:
327 $output = hash($this->hash, $text, true);
328 break;
329 case CRYPT_HASH_MODE_INTERNAL:
330 $output = call_user_func($this->hash, $text);
331 }
332 }
333
334 return substr($output, 0, $this->l);
335 }
336
337 /**
338 * Returns the hash length (in bytes)
339 *
340 * @access public
341 * @return Integer
342 */
343 function getLength()
344 {
345 return $this->l;
346 }
347
348 /**
349 * Wrapper for MD5
350 *
351 * @access private
352 * @param String $m
353 */
354 function _md5($m)
355 {
356 return pack('H*', md5($m));
357 }
358
359 /**
360 * Wrapper for SHA1
361 *
362 * @access private
363 * @param String $m
364 */
365 function _sha1($m)
366 {
367 return pack('H*', sha1($m));
368 }
369
370 /**
371 * Pure-PHP implementation of MD2
372 *
373 * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
374 *
375 * @access private
376 * @param String $m
377 */
378 function _md2($m)
379 {
380 static $s = array(
381 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
382 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
383 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
384 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
385 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
386 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
387 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
388 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
389 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
390 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
391 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
392 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
393 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
394 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
395 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
396 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
397 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
398 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
399 );
400
401 // Step 1. Append Padding Bytes
402 $pad = 16 - (strlen($m) & 0xF);
403 $m.= str_repeat(chr($pad), $pad);
404
405 $length = strlen($m);
406
407 // Step 2. Append Checksum
408 $c = str_repeat(chr(0), 16);
409 $l = chr(0);
410 for ($i = 0; $i < $length; $i+= 16) {
411 for ($j = 0; $j < 16; $j++) {
412 // RFC1319 incorrectly states that C[j] should be set to S[c xor L]
413 //$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
414 // per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j]
415 $c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
416 $l = $c[$j];
417 }
418 }
419 $m.= $c;
420
421 $length+= 16;
422
423 // Step 3. Initialize MD Buffer
424 $x = str_repeat(chr(0), 48);
425
426 // Step 4. Process Message in 16-Byte Blocks
427 for ($i = 0; $i < $length; $i+= 16) {
428 for ($j = 0; $j < 16; $j++) {
429 $x[$j + 16] = $m[$i + $j];
430 $x[$j + 32] = $x[$j + 16] ^ $x[$j];
431 }
432 $t = chr(0);
433 for ($j = 0; $j < 18; $j++) {
434 for ($k = 0; $k < 48; $k++) {
435 $x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
436 //$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
437 }
438 $t = chr(ord($t) + $j);
439 }
440 }
441
442 // Step 5. Output
443 return substr($x, 0, 16);
444 }
445
446 /**
447 * Pure-PHP implementation of SHA256
448 *
449 * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
450 *
451 * @access private
452 * @param String $m
453 */
454 function _sha256($m)
455 {
456 if (extension_loaded('suhosin')) {
457 return pack('H*', sha256($m));
458 }
459
460 // Initialize variables
461 $hash = array(
462 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
463 );
464 // Initialize table of round constants
465 // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
466 static $k = array(
467 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
468 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
469 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
470 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
471 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
472 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
473 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
474 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
475 );
476
477 // Pre-processing
478 $length = strlen($m);
479 // to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
480 $m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
481 $m[$length] = chr(0x80);
482 // we don't support hashing strings 512MB long
483 $m.= pack('N2', 0, $length << 3);
484
485 // Process the message in successive 512-bit chunks
486 $chunks = str_split($m, 64);
487 foreach ($chunks as $chunk) {
488 $w = array();
489 for ($i = 0; $i < 16; $i++) {
490 extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
491 $w[] = $temp;
492 }
493
494 // Extend the sixteen 32-bit words into sixty-four 32-bit words
495 for ($i = 16; $i < 64; $i++) {
496 $s0 = $this->_rightRotate($w[$i - 15], 7) ^
497 $this->_rightRotate($w[$i - 15], 18) ^
498 $this->_rightShift( $w[$i - 15], 3);
499 $s1 = $this->_rightRotate($w[$i - 2], 17) ^
500 $this->_rightRotate($w[$i - 2], 19) ^
501 $this->_rightShift( $w[$i - 2], 10);
502 $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
503
504 }
505
506 // Initialize hash value for this chunk
507 list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
508
509 // Main loop
510 for ($i = 0; $i < 64; $i++) {
511 $s0 = $this->_rightRotate($a, 2) ^
512 $this->_rightRotate($a, 13) ^
513 $this->_rightRotate($a, 22);
514 $maj = ($a & $b) ^
515 ($a & $c) ^
516 ($b & $c);
517 $t2 = $this->_add($s0, $maj);
518
519 $s1 = $this->_rightRotate($e, 6) ^
520 $this->_rightRotate($e, 11) ^
521 $this->_rightRotate($e, 25);
522 $ch = ($e & $f) ^
523 ($this->_not($e) & $g);
524 $t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
525
526 $h = $g;
527 $g = $f;
528 $f = $e;
529 $e = $this->_add($d, $t1);
530 $d = $c;
531 $c = $b;
532 $b = $a;
533 $a = $this->_add($t1, $t2);
534 }
535
536 // Add this chunk's hash to result so far
537 $hash = array(
538 $this->_add($hash[0], $a),
539 $this->_add($hash[1], $b),
540 $this->_add($hash[2], $c),
541 $this->_add($hash[3], $d),
542 $this->_add($hash[4], $e),
543 $this->_add($hash[5], $f),
544 $this->_add($hash[6], $g),
545 $this->_add($hash[7], $h)
546 );
547 }
548
549 // Produce the final hash value (big-endian)
550 return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
551 }
552
553 /**
554 * Pure-PHP implementation of SHA384 and SHA512
555 *
556 * @access private
557 * @param String $m
558 */
559 function _sha512($m)
560 {
561 if (!class_exists('Math_BigInteger')) {
562 require_once('Math/BigInteger.php');
563 }
564
565 static $init384, $init512, $k;
566
567 if (!isset($k)) {
568 // Initialize variables
569 $init384 = array( // initial values for SHA384
570 'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
571 '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
572 );
573 $init512 = array( // initial values for SHA512
574 '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
575 '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
576 );
577
578 for ($i = 0; $i < 8; $i++) {
579 $init384[$i] = new Math_BigInteger($init384[$i], 16);
580 $init384[$i]->setPrecision(64);
581 $init512[$i] = new Math_BigInteger($init512[$i], 16);
582 $init512[$i]->setPrecision(64);
583 }
584
585 // Initialize table of round constants
586 // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
587 $k = array(
588 '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
589 '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
590 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
591 '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
592 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
593 '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
594 '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
595 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
596 '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
597 '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
598 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
599 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
600 '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
601 '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
602 '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
603 '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
604 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
605 '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
606 '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
607 '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
608 );
609
610 for ($i = 0; $i < 80; $i++) {
611 $k[$i] = new Math_BigInteger($k[$i], 16);
612 }
613 }
614
615 $hash = $this->l == 48 ? $init384 : $init512;
616
617 // Pre-processing
618 $length = strlen($m);
619 // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
620 $m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
621 $m[$length] = chr(0x80);
622 // we don't support hashing strings 512MB long
623 $m.= pack('N4', 0, 0, 0, $length << 3);
624
625 // Process the message in successive 1024-bit chunks
626 $chunks = str_split($m, 128);
627 foreach ($chunks as $chunk) {
628 $w = array();
629 for ($i = 0; $i < 16; $i++) {
630 $temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256);
631 $temp->setPrecision(64);
632 $w[] = $temp;
633 }
634
635 // Extend the sixteen 32-bit words into eighty 32-bit words
636 for ($i = 16; $i < 80; $i++) {
637 $temp = array(
638 $w[$i - 15]->bitwise_rightRotate(1),
639 $w[$i - 15]->bitwise_rightRotate(8),
640 $w[$i - 15]->bitwise_rightShift(7)
641 );
642 $s0 = $temp[0]->bitwise_xor($temp[1]);
643 $s0 = $s0->bitwise_xor($temp[2]);
644 $temp = array(
645 $w[$i - 2]->bitwise_rightRotate(19),
646 $w[$i - 2]->bitwise_rightRotate(61),
647 $w[$i - 2]->bitwise_rightShift(6)
648 );
649 $s1 = $temp[0]->bitwise_xor($temp[1]);
650 $s1 = $s1->bitwise_xor($temp[2]);
651 $w[$i] = $w[$i - 16]->copy();
652 $w[$i] = $w[$i]->add($s0);
653 $w[$i] = $w[$i]->add($w[$i - 7]);
654 $w[$i] = $w[$i]->add($s1);
655 }
656
657 // Initialize hash value for this chunk
658 $a = $hash[0]->copy();
659 $b = $hash[1]->copy();
660 $c = $hash[2]->copy();
661 $d = $hash[3]->copy();
662 $e = $hash[4]->copy();
663 $f = $hash[5]->copy();
664 $g = $hash[6]->copy();
665 $h = $hash[7]->copy();
666
667 // Main loop
668 for ($i = 0; $i < 80; $i++) {
669 $temp = array(
670 $a->bitwise_rightRotate(28),
671 $a->bitwise_rightRotate(34),
672 $a->bitwise_rightRotate(39)
673 );
674 $s0 = $temp[0]->bitwise_xor($temp[1]);
675 $s0 = $s0->bitwise_xor($temp[2]);
676 $temp = array(
677 $a->bitwise_and($b),
678 $a->bitwise_and($c),
679 $b->bitwise_and($c)
680 );
681 $maj = $temp[0]->bitwise_xor($temp[1]);
682 $maj = $maj->bitwise_xor($temp[2]);
683 $t2 = $s0->add($maj);
684
685 $temp = array(
686 $e->bitwise_rightRotate(14),
687 $e->bitwise_rightRotate(18),
688 $e->bitwise_rightRotate(41)
689 );
690 $s1 = $temp[0]->bitwise_xor($temp[1]);
691 $s1 = $s1->bitwise_xor($temp[2]);
692 $temp = array(
693 $e->bitwise_and($f),
694 $g->bitwise_and($e->bitwise_not())
695 );
696 $ch = $temp[0]->bitwise_xor($temp[1]);
697 $t1 = $h->add($s1);
698 $t1 = $t1->add($ch);
699 $t1 = $t1->add($k[$i]);
700 $t1 = $t1->add($w[$i]);
701
702 $h = $g->copy();
703 $g = $f->copy();
704 $f = $e->copy();
705 $e = $d->add($t1);
706 $d = $c->copy();
707 $c = $b->copy();
708 $b = $a->copy();
709 $a = $t1->add($t2);
710 }
711
712 // Add this chunk's hash to result so far
713 $hash = array(
714 $hash[0]->add($a),
715 $hash[1]->add($b),
716 $hash[2]->add($c),
717 $hash[3]->add($d),
718 $hash[4]->add($e),
719 $hash[5]->add($f),
720 $hash[6]->add($g),
721 $hash[7]->add($h)
722 );
723 }
724
725 // Produce the final hash value (big-endian)
726 // (Crypt_Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
727 $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
728 $hash[4]->toBytes() . $hash[5]->toBytes();
729 if ($this->l != 48) {
730 $temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
731 }
732
733 return $temp;
734 }
735
736 /**
737 * Right Rotate
738 *
739 * @access private
740 * @param Integer $int
741 * @param Integer $amt
742 * @see _sha256()
743 * @return Integer
744 */
745 function _rightRotate($int, $amt)
746 {
747 $invamt = 32 - $amt;
748 $mask = (1 << $invamt) - 1;
749 return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
750 }
751
752 /**
753 * Right Shift
754 *
755 * @access private
756 * @param Integer $int
757 * @param Integer $amt
758 * @see _sha256()
759 * @return Integer
760 */
761 function _rightShift($int, $amt)
762 {
763 $mask = (1 << (32 - $amt)) - 1;
764 return ($int >> $amt) & $mask;
765 }
766
767 /**
768 * Not
769 *
770 * @access private
771 * @param Integer $int
772 * @see _sha256()
773 * @return Integer
774 */
775 function _not($int)
776 {
777 return ~$int & 0xFFFFFFFF;
778 }
779
780 /**
781 * Add
782 *
783 * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
784 * possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster.
785 *
786 * @param Integer $...
787 * @return Integer
788 * @see _sha256()
789 * @access private
790 */
791 function _add()
792 {
793 static $mod;
794 if (!isset($mod)) {
795 $mod = pow(2, 32);
796 }
797
798 $result = 0;
799 $arguments = func_get_args();
800 foreach ($arguments as $argument) {
801 $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
802 }
803
804 return fmod($result, $mod);
805 }
806
807 /**
808 * String Shift
809 *
810 * Inspired by array_shift
811 *
812 * @param String $string
813 * @param optional Integer $index
814 * @return String
815 * @access private
816 */
817 function _string_shift(&$string, $index = 1)
818 {
819 $substr = substr($string, 0, $index);
820 $string = substr($string, $index);
821 return $substr;
822 }
823 }
824