PluginProbe
Contact Forms by Cimatti / 1.9.2
Contact Forms by Cimatti v1.9.2
2.3.6 2.3.5 2.3.0 2.2.32 2.2.4 2.2.0 2.1.2 2.1.1 trunk 1.0 1.1 1.2 1.2.1 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 All 62 releases
contact-forms / phpseclib-crypt / Hash.php

Hash.php in Contact Forms by Cimatti 1.9.2, at phpseclib-crypt/Hash.php

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