(function () {

	if (BigInt == undefined)
		throw 'bigint.js not loaded';

	window.rsa = {};

	window.rsa.generateKeys = function (keyLength) {
		if (typeof keyLength != 'number' || keyLength < 16)
			throw 'Invalid parameter';

		// generate primes, and check for difference must be > 2^(keyLength / 4)
		do {
			var p = BigInt.randomPrime(keyLength / 2);
			var q = BigInt.randomPrime(keyLength / 2);
			var delta = BigInt.sub(p, q);
		} while (delta.bitLength() <= keyLength / 4);

		var one = BigInt.fromInt(1);

		var n = BigInt.mult(p, q);
		var phi = BigInt.mult(BigInt.sub(p, one), BigInt.sub(q, one));

		var e = BigInt.fromInt(65537);
		var euResult = BigInt.extendedEuclidean(phi, e);
		var d = euResult.y;
		if (d.lessThanZero())
			d = BigInt.add(d, phi);

		// checking
		if (BigInt.mod(BigInt.mult(e, d), phi).compareTo(one) != 0)
			throw 'Something wrong';

		return {
			publicKey: { n: n, e: e },
			privateKey: { n: n, d: d }
		};
	};

	window.rsa.encrypt = function (message, publicKey) {
		if (!(message instanceof BigInt) || publicKey == undefined || !(publicKey.n instanceof BigInt) || !(publicKey.e instanceof BigInt))
			throw 'Invalid parameters';

		if (message.compareTo(publicKey.n) > 0)
			throw 'Cannot encrypt message which is greater than key';

		return BigInt.modPow(message, publicKey.e, publicKey.n);
	};

	window.rsa.decrypt = function (cypher, privateKey) {
		if (!(cypher instanceof BigInt) || typeof privateKey == 'undefined' || !(privateKey.n instanceof BigInt) || !(privateKey.d instanceof BigInt))
			throw 'Invalid parameters';

		if (cypher.compareTo(privateKey.n) > 0)
			throw 'Invalid cypher';

		return BigInt.modPow(cypher, privateKey.d, privateKey.n);
	};

})();
@@ -339,32 +339,49 @@
 me(keyLength / 2
+, random.SHA2PRNG
 );%0A%09%09%09var q = Bi
@@ -410,16 +410,33 @@
 ngth / 2
+, random.SHA2PRNG
 );%0A%09%09%09va
@@ -445,30 +445,28 @@
 delta = 
-BigInt.sub(p, 
+p.substract(
 q);%0A%09%09%7D 
@@ -520,124 +520,94 @@
 var 
-one = BigInt.fromInt(1);%0A%0A%09%09var n = BigInt.mult(p, q);%0A%09%09var phi = BigInt.mult(BigInt.sub(p, one), BigInt.sub(q, one
+n = p.multiply(q);%0A%09%09var phi = p.substract(BigInt.ONE).multiply(q.substract(BigInt.ONE
 ));%0A
@@ -725,22 +725,34 @@
  (d.
-lessThanZero()
+compareTo(BigInt.ZERO) %3C 0
 )%0A%09%09
@@ -760,22 +760,14 @@
 d = 
-BigInt
+d
 .add(
-d, 
 phi)
@@ -793,62 +793,50 @@
 if (
-BigInt.mod(BigInt.mult(e, d), phi).compareTo(one) != 0
+!e.multiply(d).mod(phi).equals(BigInt.ONE)
 )%0A%09%09
@@ -1276,30 +1276,31 @@
 %09return 
-BigInt
+message
 .modPow(
 message,
@@ -1291,25 +1291,16 @@
 .modPow(
-message, 
 publicKe
@@ -1637,22 +1637,22 @@
 urn 
-BigInt
+cypher
 .modPow(
 cyph
@@ -1647,24 +1647,16 @@
 .modPow(
-cypher, 
 privateK

Change for new implementation