PluginProbe
Contact Forms by Cimatti / 2.3.5
Contact Forms by Cimatti v2.3.5
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 2.3.5, at phpseclib-crypt/Hash.php

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