// Array used to convert decimal to hex
var dechex = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');

function hexdec (a)
{
	// Converts hex to decimal
	if (a>='0' && a<='9')
	{
		return a.charCodeAt(0) - '0'.charCodeAt(0);
	}
	else if (a>='A' && a<='F')
	{
		return a.charCodeAt(0) - 'A'.charCodeAt(0) + 10;
	}
	else if (a>='a' && a<='f')
	{
		return a.charCodeAt(0) - 'a'.charCodeAt(0) + 10;
	}
}

function combine_hex_strings (a, b, mode)
{
	if (a.length==b.length)
	{
		var c = "";
		for (var i=0; i<a.length; i++)
		{
			if (mode==0)
			{
				// Add strings together
				c += dechex[ ( hexdec(a.charAt(i)) + hexdec(b.charAt(i)) ) % 16];
			}
			else if (mode==1)
			{
				// XOR strings together
				c += dechex[ ( hexdec(a.charAt(i)) ^ hexdec(b.charAt(i)) ) % 16];
			}
			else if (mode==2)
			{
				// Subtract string $b from string $a
				c += dechex[ ( hexdec(a.charAt(i)) - hexdec(b.charAt(i)) + 16 ) % 16];
			}
		}
		return c.toUpperCase();
	}
	else
	{
		return null;
	}
}


function convert_to_hex_string (a)
{
	var b = "";
	var temp = 0;
	for (var i=0; i<a.length; i++)
	{
		temp = a.charCodeAt(i);
		b += dechex[parseInt(temp/16)] + dechex[temp%16];
	}
	return b.toUpperCase();
}


function hash_hex_string (a)
{
	if (a.length>=8 && a.length%8==0)
	{
		var str = new Array('F', 'F', 'F', 'F', 'F', 'F', 'F', 'F');
		index = 0;
		lastVal = new Array(0, 0, 0, 0);
		for (var i=0; i<a.length; i++)
		{
			lastVal[i%4] = (lastVal[i%4] ^ hexdec(a.charAt(i))) % 16;
		}
		for (var i=0; i<a.length; i++)
		{
			currentVal = (hexdec(a.charAt(i)) * hexdec(str[i%8])) % 16;
			str[i%8] = dechex[currentVal ^ lastVal[i%4]];
			lastVal[currentVal%4] = currentVal;
		}
		return str.join("").toUpperCase();
	}
	else
	{
		return null;
	}
}

function substr_replace(initial, insert, position, length)
{
	return new String(initial.substring(0, position) + insert + initial.substring(position+length, initial.length));
}

function generate_pseudo_key (password)
{
	// Generates a one-way 32-byte string from the password. (in hex, so 64 chars)
	if (password.length>0)
	{
		// Create standard password block
		var pseudo = convert_to_hex_string(password);
		pseudo = substr_replace("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", pseudo, 0, pseudo.length);
		
		// Scramble 'pseudo' using hashes of itself, repeatedly
		for (var i=0; i<8; i++)
		{
			pseudo = substr_replace(pseudo, hash_hex_string(pseudo), 56-i*8, 8);
		}
		return pseudo;
	}
	else
	{
		return null;
	}
}

