// need Leemon Baird's BigInt.js
// need xxqHttp.js

function rsaStr(s, e_str, n_str) {
	if (n_str=='' || s=='') return(s)
	var e = str2bigInt(e_str, 16)
	var n = str2bigInt(n_str, 16)
	var a = new Array();
	var i, sl = s.length;
	for (i=0; i < sl; i++) a[i] = s.charCodeAt(i).toString(16)
	a = str2bigInt(a.join(''), 16)
	var b = powMod(a, e, n)
	return(bigInt2str(b,16))
	}

function otpStr(s, k) { 
	var i, ns=s.length, nk=k.length
	var a = []
	//for (i=0; i<ns; i++) a[i] = (s.charCodeAt(i) ^ k.charCodeAt(i%nk)).toString(16) // return Hex string with double length
	for (i=0; i<ns; i++) a[i] = String.fromCharCode(s.charCodeAt(i) ^ k.charCodeAt(i%nk)) //.toString(16)
	return(a.join(''))
	}

var OTP_STR = '';
//var OTP_STR_ENC = '';

function encryptStr(s, e_str, n_str, srv_tag, srv_url) {
	if (n_str=='' || s=='') return(s)
	if (OTP_STR=='') {
		//OptStr = String.fromCharCode((10010+parseInt(Math.random()*10000)) & 65535)
		OTP_STR = Math.random().toString().substr(2) // remove '0.'
		//OTP_STR = rsaStr(OTP_STR.substring(2, OTP_STR.length))
		//OTP_STR_ENC = rsaStr(OTP_STR)
		}

	if (srv_tag == undefined) srv_tag = getSrvTag(OTP_STR, srv_url, e_str, n_str)
	s = s + srv_tag

	return(rsaStr(s, e_str, n_str))

	var e = str2bigInt(e_str, 16)
	var n = str2bigInt(n_str, 16)
	var a = new Array();
	var sl = s.length;
	var i = 0; //sl-1;
	var j = 0;
	while (i < sl) {
		a[j] = s.charCodeAt(i).toString(16)
		i++
		//if (i >= 0) a[j] += s.charCodeAt(i)<<8
		//i--
		j++
		}
	//for (i=0; i<a.length; i++) a[i] = a[i]*Math.pow(2,i); // only good for smail i (short string) !!!
	//for (i=0; i<a.length; i++) a[i] = a[i]<<i; // only good for smail i (short string) !!!
	a = str2bigInt(a.join(''), 16)

	var b = powMod(a, e, n)

	return(bigInt2str(b,16))

	var ra = new Array()
	sl = b.length
	i = b.length-1
	j = 0
	while (i >= 0) {
		ra[j] = String.fromCharCode(b[i] & 255)
		j++
		ra[j] = String.fromCharCode(b[i]>>8 & 255)
		j++
		i--
		}
	return(escape(ra.join('')))
	}

var SRV_TAG = '', SRV_TAG_LAST='';
function getSrvTag(otpstr, srv_url, e_str, n_str) {
	var dest = srv_url+'?'+escape(rsaStr(otpstr, e_str, n_str))
	var async = false
	trackState(dest, waitSrvTag, async)
	// if async is false, Firefox (without Firebug) won't call the callback function, 'waitSrvTag' here, so need to get data by hand if the SRV_TAG is ''.
	if (SRV_TAG == '') SRV_TAG = xmlhttp.responseXML.getElementsByTagName("data")[0].firstChild.nodeValue
	//SRV_TAG = otpStr(unescape(SRV_TAG), otpstr)
	//return(SRV_TAG)
	rlt_s = otpStr(unescape(SRV_TAG), otpstr)
	SRV_TAG_LAST = rlt_s
	SRV_TAG = ''
	return(rlt_s)
	}

function getSrvTag_simple() {
	return(xmlhttp.responseXML.getElementsByTagName("data")[0].firstChild.nodeValue)
	}

function askSrv(dest, async) {
	if (async==undefined) async = false
	trackState(dest, waitSrvTag, async)
	// if async is false, Firefox (without Firebug) won't call the callback function, 'waitSrvTag' here, so need to get data by hand if the SRV_TAG is ''.
	//if (SRV_TAG == '') setSrvTag() //SRV_TAG = xmlhttp.responseXML.getElementsByTagName("data")[0].firstChild.nodeValue
	var rlt_s = unescape(getSrvTag())
	return(rlt_s)
	}

function askSrv_simple(dest, async) {
	if (async==undefined) async = false
	trackState(dest, waitSrvTag, async)
	// if async is false, Firefox (without Firebug) won't call the callback function, 'waitSrvTag' here, so need to get data by hand if the SRV_TAG is ''.
	//if (SRV_TAG == '') setSrvTag() //SRV_TAG = xmlhttp.responseXML.getElementsByTagName("data")[0].firstChild.nodeValue
	var rlt_s = unescape(getSrvTag_simple())
	return(rlt_s)
	}

var xmlhttp = undefined;
function initXMLHttp(fun) {
	xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
    xmlhttp.onreadystatechange = fun;
	}

function trackState(dest, fun, async) {
	if (xmlhttp == undefined) initXMLHttp(fun)
    xmlhttp.open("GET", dest, async); 
    if (window.XMLHttpRequest) xmlhttp.send(null) 
	else xmlhttp.send();
	}

function waitSrvTag() {
	if (xmlhttp.readyState==4) {
		SRV_TAG = xmlhttp.responseXML.getElementsByTagName("data")[0].firstChild.nodeValue
		return
		}
	}



