// RSA, a suite of routines for performing RSA public-key computations in
// JavaScript.
//
// Requires BigInt.js and Barrett.js.
//
// Copyright 1998-2005 David Shapiro.
//
// You may use, re-use, abuse, copy, and modify this code to your liking, but
// please keep this header.
//
// Thanks!
// 
// Dave Shapiro
// dave@ohdave.com 

function RSAKeyPair(encryptionExponent, modulus) 
{
	this.e = biFromHex(encryptionExponent);
	this.m = biFromHex(modulus);
	// chunkSize needs to be the same as the number of octets in the key.
	this.chunkSize = 2 * (biHighIndex(this.m)+1);
	this.radix = 16;
	this.barrett = new BarrettMu(this.m);
}

function twoDigit(n)
{
	return (n < 10 ? "0" : "") + String(n);
}

function encryptedString(key, s)
	// Altered by Rob Saunders (rob@robsaunders.net). New routine pads the
	// string after it has been converted to an array. This fixes an
	// incompatibility with Flash MX's ActionScript.
{
	var a = new Array();
	var sl = s.length;
	var i = 0;
	var j = 0;
	
	//Generate PKCS#1 v1.5 type 2 padding
	a[0] = 0;
	a[1] = 2;
	var padsize = key.chunkSize - 3 - sl;
	for (j = 2 ; j < padsize+2 ; j++) {
		a[j] = Math.round((Math.random()*255));
		if (a[j] == 0) a[j] = 1;
	}
	a[j++] = 0;
	
	//Add the message
	while (i < sl) {
		a[j++] = s.charCodeAt(i);
		i++;
	}
	
	var al = a.length;
	
	var result = "";
	var j, k, block, tmp;
	for (i = 0; i < al; i += key.chunkSize) {
		block = new BigInt();
		tmp = new BigInt();
		j = 0;
		for (k = i; k < i + key.chunkSize; k++) {
			if (k == i) {
				block = biFromNumber(a[k]);
			} else {
				block = biShiftLeft(block, 8);
				tmp = biFromNumber(a[k]);
				block = biAdd(block, tmp);
			}
		}
		var crypt = key.barrett.powMod(block, key.e);
		var text = key.radix == 16 ? biToHex(crypt) : biToString(crypt, key.radix);
		result += text;
	}
	
    return result;
}