2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
\r
5 * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
\r
7 * Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
\r
9 * md2, md5, md5-96, sha1, sha1-96, sha256, sha384, and sha512
\r
11 * If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
\r
12 * the hash. If no valid algorithm is provided, sha1 will be used.
\r
14 * PHP versions 4 and 5
\r
16 * {@internal The variable names are the same as those in
\r
17 * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
\r
19 * Here's a short example of how to use this library:
\r
22 * include('Crypt/Hash.php');
\r
24 * $hash = new Crypt_Hash('sha1');
\r
26 * $hash->setKey('abcdefg');
\r
28 * echo base64_encode($hash->hash('abcdefg'));
\r
32 * LICENSE: This library is free software; you can redistribute it and/or
\r
33 * modify it under the terms of the GNU Lesser General Public
\r
34 * License as published by the Free Software Foundation; either
\r
35 * version 2.1 of the License, or (at your option) any later version.
\r
37 * This library is distributed in the hope that it will be useful,
\r
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
40 * Lesser General Public License for more details.
\r
42 * You should have received a copy of the GNU Lesser General Public
\r
43 * License along with this library; if not, write to the Free Software
\r
44 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
\r
48 * @package Crypt_Hash
\r
49 * @author Jim Wigginton <terrafrost@php.net>
\r
50 * @copyright MMVII Jim Wigginton
\r
51 * @license http://www.gnu.org/licenses/lgpl.txt
\r
52 * @version $Id: Hash.php,v 1.6 2009/11/23 23:37:07 terrafrost Exp $
\r
53 * @link http://phpseclib.sourceforge.net
\r
58 * @see Crypt_Hash::Crypt_Hash()
\r
61 * Toggles the internal implementation
\r
63 define('CRYPT_HASH_MODE_INTERNAL', 1);
\r
65 * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
\r
67 define('CRYPT_HASH_MODE_MHASH', 2);
\r
69 * Toggles the hash() implementation, which works on PHP 5.1.2+.
\r
71 define('CRYPT_HASH_MODE_HASH', 3);
\r
75 * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
\r
77 * @author Jim Wigginton <terrafrost@php.net>
\r
80 * @package Crypt_Hash
\r
84 * Byte-length of compression blocks / key (Internal HMAC)
\r
86 * @see Crypt_Hash::setAlgorithm()
\r
93 * Byte-length of hash output (Internal HMAC)
\r
95 * @see Crypt_Hash::setHash()
\r
104 * @see Crypt_Hash::setHash()
\r
113 * @see Crypt_Hash::setKey()
\r
120 * Outer XOR (Internal HMAC)
\r
122 * @see Crypt_Hash::setKey()
\r
129 * Inner XOR (Internal HMAC)
\r
131 * @see Crypt_Hash::setKey()
\r
138 * Default Constructor.
\r
140 * @param optional String $hash
\r
141 * @return Crypt_Hash
\r
144 function Crypt_Hash($hash = 'sha1')
\r
146 if ( !defined('CRYPT_HASH_MODE') ) {
\r
148 case extension_loaded('hash'):
\r
149 define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
\r
151 case extension_loaded('mhash'):
\r
152 define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH);
\r
155 define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL);
\r
159 $this->setHash($hash);
\r
163 * Sets the key for HMACs
\r
165 * Keys can be of any length.
\r
168 * @param String $key
\r
170 function setKey($key)
\r
176 * Sets the hash function.
\r
179 * @param String $hash
\r
181 function setHash($hash)
\r
186 $this->l = 12; // 96 / 8 = 12
\r
207 $mode = CRYPT_HASH_MODE_INTERNAL;
\r
211 $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
\r
214 $mode = CRYPT_HASH_MODE;
\r
218 case CRYPT_HASH_MODE_MHASH:
\r
222 $this->hash = MHASH_MD5;
\r
225 $this->hash = MHASH_SHA256;
\r
230 $this->hash = MHASH_SHA1;
\r
233 case CRYPT_HASH_MODE_HASH:
\r
237 $this->hash = 'md5';
\r
242 $this->hash = $hash;
\r
247 $this->hash = 'sha1';
\r
255 $this->hash = array($this, '_md2');
\r
260 $this->hash = array($this, '_md5');
\r
264 $this->hash = array($this, '_sha256');
\r
269 $this->hash = array($this, '_sha512');
\r
275 $this->hash = array($this, '_sha1');
\r
278 $this->ipad = str_repeat(chr(0x36), $this->b);
\r
279 $this->opad = str_repeat(chr(0x5C), $this->b);
\r
283 * Compute the HMAC.
\r
286 * @param String $text
\r
289 function hash($text)
\r
291 $mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
\r
293 if (!empty($this->key)) {
\r
295 case CRYPT_HASH_MODE_MHASH:
\r
296 $output = mhash($this->hash, $text, $this->key);
\r
298 case CRYPT_HASH_MODE_HASH:
\r
299 $output = hash_hmac($this->hash, $text, $this->key, true);
\r
301 case CRYPT_HASH_MODE_INTERNAL:
\r
302 /* "Applications that use keys longer than B bytes will first hash the key using H and then use the
\r
303 resultant L byte string as the actual key to HMAC."
\r
305 -- http://tools.ietf.org/html/rfc2104#section-2 */
\r
306 $key = strlen($this->key) > $this->b ? call_user_func($this->$hash, $this->key) : $this->key;
\r
308 $key = str_pad($key, $this->b, chr(0)); // step 1
\r
309 $temp = $this->ipad ^ $key; // step 2
\r
310 $temp .= $text; // step 3
\r
311 $temp = call_user_func($this->hash, $temp); // step 4
\r
312 $output = $this->opad ^ $key; // step 5
\r
313 $output.= $temp; // step 6
\r
314 $output = call_user_func($this->hash, $output); // step 7
\r
318 case CRYPT_HASH_MODE_MHASH:
\r
319 $output = mhash($this->hash, $text);
\r
321 case CRYPT_HASH_MODE_HASH:
\r
322 $output = hash($this->hash, $text, true);
\r
324 case CRYPT_HASH_MODE_INTERNAL:
\r
325 $output = call_user_func($this->hash, $text);
\r
329 return substr($output, 0, $this->l);
\r
333 * Returns the hash length (in bytes)
\r
338 function getLength()
\r
347 * @param String $text
\r
351 return pack('H*', md5($m));
\r
358 * @param String $text
\r
362 return pack('H*', sha1($m));
\r
366 * Pure-PHP implementation of MD2
\r
368 * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
\r
371 * @param String $text
\r
376 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
\r
377 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
\r
378 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
\r
379 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
\r
380 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
\r
381 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
\r
382 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
\r
383 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
\r
384 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
\r
385 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
\r
386 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
\r
387 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
\r
388 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
\r
389 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
\r
390 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
\r
391 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
\r
392 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
\r
393 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
\r
396 // Step 1. Append Padding Bytes
\r
397 $pad = 16 - (strlen($m) & 0xF);
\r
398 $m.= str_repeat(chr($pad), $pad);
\r
400 $length = strlen($m);
\r
402 // Step 2. Append Checksum
\r
403 $c = str_repeat(chr(0), 16);
\r
405 for ($i = 0; $i < $length; $i+= 16) {
\r
406 for ($j = 0; $j < 16; $j++) {
\r
407 $c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
\r
415 // Step 3. Initialize MD Buffer
\r
416 $x = str_repeat(chr(0), 48);
\r
418 // Step 4. Process Message in 16-Byte Blocks
\r
419 for ($i = 0; $i < $length; $i+= 16) {
\r
420 for ($j = 0; $j < 16; $j++) {
\r
421 $x[$j + 16] = $m[$i + $j];
\r
422 $x[$j + 32] = $x[$j + 16] ^ $x[$j];
\r
425 for ($j = 0; $j < 18; $j++) {
\r
426 for ($k = 0; $k < 48; $k++) {
\r
427 $x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
\r
428 //$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
\r
430 $t = chr(ord($t) + $j);
\r
435 return substr($x, 0, 16);
\r
439 * Pure-PHP implementation of SHA256
\r
441 * 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}.
\r
444 * @param String $text
\r
446 function _sha256($m)
\r
448 if (extension_loaded('suhosin')) {
\r
449 return pack('H*', sha256($m));
\r
452 // Initialize variables
\r
454 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
\r
456 // Initialize table of round constants
\r
457 // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
\r
459 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
\r
460 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
\r
461 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
\r
462 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
\r
463 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
\r
464 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
\r
465 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
\r
466 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
\r
470 $length = strlen($m);
\r
471 // to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
\r
472 $m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
\r
473 $m[$length] = chr(0x80);
\r
474 // we don't support hashing strings 512MB long
\r
475 $m.= pack('N2', 0, $length << 3);
\r
477 // Process the message in successive 512-bit chunks
\r
478 $chunks = str_split($m, 64);
\r
479 foreach ($chunks as $chunk) {
\r
481 for ($i = 0; $i < 16; $i++) {
\r
482 extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
\r
486 // Extend the sixteen 32-bit words into sixty-four 32-bit words
\r
487 for ($i = 16; $i < 64; $i++) {
\r
488 $s0 = $this->_rightRotate($w[$i - 15], 7) ^
\r
489 $this->_rightRotate($w[$i - 15], 18) ^
\r
490 $this->_rightShift( $w[$i - 15], 3);
\r
491 $s1 = $this->_rightRotate($w[$i - 2], 17) ^
\r
492 $this->_rightRotate($w[$i - 2], 19) ^
\r
493 $this->_rightShift( $w[$i - 2], 10);
\r
494 $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
\r
498 // Initialize hash value for this chunk
\r
499 list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
\r
502 for ($i = 0; $i < 64; $i++) {
\r
503 $s0 = $this->_rightRotate($a, 2) ^
\r
504 $this->_rightRotate($a, 13) ^
\r
505 $this->_rightRotate($a, 22);
\r
509 $t2 = $this->_add($s0, $maj);
\r
511 $s1 = $this->_rightRotate($e, 6) ^
\r
512 $this->_rightRotate($e, 11) ^
\r
513 $this->_rightRotate($e, 25);
\r
515 ($this->_not($e) & $g);
\r
516 $t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
\r
521 $e = $this->_add($d, $t1);
\r
525 $a = $this->_add($t1, $t2);
\r
528 // Add this chunk's hash to result so far
\r
530 $this->_add($hash[0], $a),
\r
531 $this->_add($hash[1], $b),
\r
532 $this->_add($hash[2], $c),
\r
533 $this->_add($hash[3], $d),
\r
534 $this->_add($hash[4], $e),
\r
535 $this->_add($hash[5], $f),
\r
536 $this->_add($hash[6], $g),
\r
537 $this->_add($hash[7], $h)
\r
541 // Produce the final hash value (big-endian)
\r
542 return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
\r
546 * Pure-PHP implementation of SHA384 and SHA512
\r
549 * @param String $text
\r
551 function _sha512($m)
\r
553 if (!class_exists('Math_BigInteger')) {
\r
554 require_once('Math/BigInteger.php');
\r
557 static $init384, $init512, $k;
\r
560 // Initialize variables
\r
561 $init384 = array( // initial values for SHA384
\r
562 'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
\r
563 '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
\r
565 $init512 = array( // initial values for SHA512
\r
566 '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
\r
567 '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
\r
570 for ($i = 0; $i < 8; $i++) {
\r
571 $init384[$i] = new Math_BigInteger($init384[$i], 16);
\r
572 $init384[$i]->setPrecision(64);
\r
573 $init512[$i] = new Math_BigInteger($init512[$i], 16);
\r
574 $init512[$i]->setPrecision(64);
\r
577 // Initialize table of round constants
\r
578 // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
\r
580 '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
\r
581 '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
\r
582 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
\r
583 '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
\r
584 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
\r
585 '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
\r
586 '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
\r
587 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
\r
588 '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
\r
589 '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
\r
590 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
\r
591 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
\r
592 '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
\r
593 '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
\r
594 '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
\r
595 '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
\r
596 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
\r
597 '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
\r
598 '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
\r
599 '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
\r
602 for ($i = 0; $i < 80; $i++) {
\r
603 $k[$i] = new Math_BigInteger($k[$i], 16);
\r
607 $hash = $this->l == 48 ? $init384 : $init512;
\r
610 $length = strlen($m);
\r
611 // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
\r
612 $m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
\r
613 $m[$length] = chr(0x80);
\r
614 // we don't support hashing strings 512MB long
\r
615 $m.= pack('N4', 0, 0, 0, $length << 3);
\r
617 // Process the message in successive 1024-bit chunks
\r
618 $chunks = str_split($m, 128);
\r
619 foreach ($chunks as $chunk) {
\r
621 for ($i = 0; $i < 16; $i++) {
\r
622 $temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256);
\r
623 $temp->setPrecision(64);
\r
627 // Extend the sixteen 32-bit words into eighty 32-bit words
\r
628 for ($i = 16; $i < 80; $i++) {
\r
630 $w[$i - 15]->bitwise_rightRotate(1),
\r
631 $w[$i - 15]->bitwise_rightRotate(8),
\r
632 $w[$i - 15]->bitwise_rightShift(7)
\r
634 $s0 = $temp[0]->bitwise_xor($temp[1]);
\r
635 $s0 = $s0->bitwise_xor($temp[2]);
\r
637 $w[$i - 2]->bitwise_rightRotate(19),
\r
638 $w[$i - 2]->bitwise_rightRotate(61),
\r
639 $w[$i - 2]->bitwise_rightShift(6)
\r
641 $s1 = $temp[0]->bitwise_xor($temp[1]);
\r
642 $s1 = $s1->bitwise_xor($temp[2]);
\r
643 $w[$i] = $w[$i - 16]->copy();
\r
644 $w[$i] = $w[$i]->add($s0);
\r
645 $w[$i] = $w[$i]->add($w[$i - 7]);
\r
646 $w[$i] = $w[$i]->add($s1);
\r
649 // Initialize hash value for this chunk
\r
650 $a = $hash[0]->copy();
\r
651 $b = $hash[1]->copy();
\r
652 $c = $hash[2]->copy();
\r
653 $d = $hash[3]->copy();
\r
654 $e = $hash[4]->copy();
\r
655 $f = $hash[5]->copy();
\r
656 $g = $hash[6]->copy();
\r
657 $h = $hash[7]->copy();
\r
660 for ($i = 0; $i < 80; $i++) {
\r
662 $a->bitwise_rightRotate(28),
\r
663 $a->bitwise_rightRotate(34),
\r
664 $a->bitwise_rightRotate(39)
\r
666 $s0 = $temp[0]->bitwise_xor($temp[1]);
\r
667 $s0 = $s0->bitwise_xor($temp[2]);
\r
669 $a->bitwise_and($b),
\r
670 $a->bitwise_and($c),
\r
671 $b->bitwise_and($c)
\r
673 $maj = $temp[0]->bitwise_xor($temp[1]);
\r
674 $maj = $maj->bitwise_xor($temp[2]);
\r
675 $t2 = $s0->add($maj);
\r
678 $e->bitwise_rightRotate(14),
\r
679 $e->bitwise_rightRotate(18),
\r
680 $e->bitwise_rightRotate(41)
\r
682 $s1 = $temp[0]->bitwise_xor($temp[1]);
\r
683 $s1 = $s1->bitwise_xor($temp[2]);
\r
685 $e->bitwise_and($f),
\r
686 $g->bitwise_and($e->bitwise_not())
\r
688 $ch = $temp[0]->bitwise_xor($temp[1]);
\r
689 $t1 = $h->add($s1);
\r
690 $t1 = $t1->add($ch);
\r
691 $t1 = $t1->add($k[$i]);
\r
692 $t1 = $t1->add($w[$i]);
\r
701 $a = $t1->add($t2);
\r
704 // Add this chunk's hash to result so far
\r
717 // Produce the final hash value (big-endian)
\r
718 // (Crypt_Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
\r
719 $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
\r
720 $hash[4]->toBytes() . $hash[5]->toBytes();
\r
721 if ($this->l != 48) {
\r
722 $temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
\r
732 * @param Integer $int
\r
733 * @param Integer $amt
\r
737 function _rightRotate($int, $amt)
\r
739 $invamt = 32 - $amt;
\r
740 $mask = (1 << $invamt) - 1;
\r
741 return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
\r
748 * @param Integer $int
\r
749 * @param Integer $amt
\r
753 function _rightShift($int, $amt)
\r
755 $mask = (1 << (32 - $amt)) - 1;
\r
756 return ($int >> $amt) & $mask;
\r
763 * @param Integer $int
\r
767 function _not($int)
\r
769 return ~$int & 0xFFFFFFFF;
\r
775 * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
\r
776 * possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster.
\r
778 * @param String $string
\r
779 * @param optional Integer $index
\r
787 if (!isset($mod)) {
\r
792 $arguments = func_get_args();
\r
793 foreach ($arguments as $argument) {
\r
794 $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
\r
797 return fmod($result, $mod);
\r
803 * Inspired by array_shift
\r
805 * @param String $string
\r
806 * @param optional Integer $index
\r
810 function _string_shift(&$string, $index = 1)
\r
812 $substr = substr($string, 0, $index);
\r
813 $string = substr($string, $index);
\r