PluginProbe
ManageWP Worker / 4.9.25
ManageWP Worker v4.9.25
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 / src / PHPSecLib / Crypt / Hash.php

Hash.php in ManageWP Worker 4.9.25, at src/PHPSecLib/Crypt/Hash.php

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