<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * CodeIgniter
 *
 * An open source application development framework for PHP 4.3.2 or newer
 *
 * @package		CodeIgniter
 * @author		ExpressionEngine Dev Team
 * @copyright	Copyright (c) 2006, EllisLab, Inc.
 * @license		http://codeigniter.com/user_guide/license.html
 * @link		http://codeigniter.com
 * @since		Version 1.0
 * @filesource
 */

// ------------------------------------------------------------------------

/**
 * SHA1 Encoding Class
 *
 * Purpose: Provides 160 bit hashing using The Secure Hash Algorithm
 * developed at the National Institute of Standards and Technology. The 40
 * character SHA1 message hash is computationally infeasible to crack.
 *
 * This class is a fallback for servers that are not running PHP greater than
 * 4.3, or do not have the MHASH library.
 *
 * This class is based on two scripts:
 *
 * Marcus Campbell's PHP implementation (GNU license)
 * http://www.tecknik.net/sha-1/
 *
 * ...which is based on Paul Johnston's JavaScript version
 * (BSD license). http://pajhome.org.uk/
 *
 * I encapsulated the functions and wrote one additional method to fix
 * a hex conversion bug. - Rick Ellis
 *
 * @package		CodeIgniter
 * @subpackage	Libraries
 * @category	Encryption
 * @author		ExpressionEngine Dev Team
 * @link		http://codeigniter.com/user_guide/general/encryption.html
 */
class CI_SHA {

	function CI_SHA()
	{
		log_message('debug', "SHA1 Class Initialized");
	}

	/**
	 * Generate the Hash
	 *
	 * @access	public
	 * @param	string
	 * @return	string
	 */	
	function generate($str)
	{
		$n = ((strlen($str) + 8) >> 6) + 1;

		for ($i = 0; $i < $n * 16; $i++)
		{
			$x[$i] = 0;
		}

		for ($i = 0; $i < strlen($str); $i++)
		{
			$x[$i >> 2] |= ord(substr($str, $i, 1)) << (24 - ($i % 4) * 8);
		}

		$x[$i >> 2] |= 0x80 << (24 - ($i % 4) * 8);

		$x[$n * 16 - 1] = strlen($str) * 8;

		$a =  1732584193;
		$b = -271733879;
		$c = -1732584194;
		$d =  271733878;
		$e = -1009589776;

		for ($i = 0; $i < sizeof($x); $i += 16)
		{
			$olda = $a;
			$oldb = $b;
			$oldc = $c;
			$oldd = $d;
			$olde = $e;

			for($j = 0; $j < 80; $j++)
			{
				if ($j < 16)
				{
					$w[$j] = $x[$i + $j];
				}
				else
				{
					$w[$j] = $this->_rol($w[$j - 3] ^ $w[$j - 8] ^ $w[$j - 14] ^ $w[$j - 16], 1);
				}

				$t = $this->_safe_add($this->_safe_add($this->_rol($a, 5), $this->_ft($j, $b, $c, $d)), $this->_safe_add($this->_safe_add($e, $w[$j]), $this->_kt($j)));

				$e = $d;
				$d = $c;
				$c = $this->_rol($b, 30);
				$b = $a;
				$a = $t;
			}

			$a = $this->_safe_add($a, $olda);
			$b = $this->_safe_add($b, $oldb);
			$c = $this->_safe_add($c, $oldc);
			$d = $this->_safe_add($d, $oldd);
			$e = $this->_safe_add($e, $olde);
		}

		return $this->_hex($a).$this->_hex($b).$this->_hex($c).$this->_hex($d).$this->_hex($e);
	}
  	
	// --------------------------------------------------------------------

	/**
	 * Convert a decimal to hex
	 *
	 * @access	private
	 * @param	string
	 * @return	string
	 */	
	function _hex($str)
	{
		$str = dechex($str);

		if (strlen($str) == 7)
		{
			$str = '0'.$str;
		}

		return $str;
	}
  	
	// --------------------------------------------------------------------

	/**
	 *  Return result based on iteration
	 *
	 * @access	private
	 * @return	string
	 */	
	function _ft($t, $b, $c, $d)
	{
		if ($t < 20)
			return ($b & $c) | ((~$b) & $d);
		if ($t < 40)
			return $b ^ $c ^ $d;
		if ($t < 60)
			return ($b & $c) | ($b & $d) | ($c & $d);

		return $b ^ $c ^ $d;
	}

	// --------------------------------------------------------------------

	/**
	 * Determine the additive constant
	 *
	 * @access	private
	 * @return	string
	 */	
	function _kt($t)
	{
		if ($t < 20)
		{
			return 1518500249;
		}
		else if ($t < 40)
		{
			return 1859775393;
		}
		else if ($t < 60)
		{
			return -1894007588;
		}
		else
		{
			return -899497514;
		}
	}
  	
	// --------------------------------------------------------------------

	/**
	 * Add integers, wrapping at 2^32
	 *
	 * @access	private
	 * @return	string
	 */	
	function _safe_add($x, $y)
	{
		$lsw = ($x & 0xFFFF) + ($y & 0xFFFF);
		$msw = ($x >> 16) + ($y >> 16) + ($lsw >> 16);

		return ($msw << 16) | ($lsw & 0xFFFF);
	}
  	
	// --------------------------------------------------------------------

	/**
	 * Bitwise rotate a 32-bit number
	 *
	 * @access	private
	 * @return	integer
	 */	
	function _rol($num, $cnt)
	{
		return ($num << $cnt) | $this->_zero_fill($num, 32 - $cnt);
	}

	// --------------------------------------------------------------------

	/**
	 * Pad string with zero
	 *
	 * @access	private
	 * @return	string
	 */	
	function _zero_fill($a, $b)
	{
		$bin = decbin($a);

		if (strlen($bin) < $b)
		{
			$bin = 0;
		}
		else
		{
			$bin = substr($bin, 0, strlen($bin) - $b);
		}

		for ($i=0; $i < $b; $i++)
		{
			$bin = "0".$bin;
		}

		return bindec($bin);
	}
}
// END CI_SHA

/* End of file Sha1.php */
/* Location: ./system/libraries/Sha1.php */