mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-08 17:07:03 +03:00
Experiments with RSA encryption
This commit is contained in:
parent
bbcbfdc150
commit
777d014403
36 changed files with 2272 additions and 7995 deletions
152
vendors/jsbn/rsa-async.js
vendored
Normal file
152
vendors/jsbn/rsa-async.js
vendored
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
// Copyright (c) 2011 Kevin M Burns Jr.
|
||||
// All Rights Reserved.
|
||||
// See "LICENSE" for details.
|
||||
//
|
||||
// Extension to jsbn which adds facilities for asynchronous RSA key generation
|
||||
// Primarily created to avoid execution timeout on mobile devices
|
||||
//
|
||||
// http://www-cs-students.stanford.edu/~tjw/jsbn/
|
||||
//
|
||||
// ---
|
||||
|
||||
(function(){
|
||||
|
||||
// Generate a new random private key B bits long, using public expt E
|
||||
var RSAGenerateAsync = function (B, E, callback) {
|
||||
//var rng = new SeededRandom();
|
||||
var rng = new SecureRandom();
|
||||
var qs = B >> 1;
|
||||
this.e = parseInt(E, 16);
|
||||
var ee = new BigInteger(E, 16);
|
||||
var rsa = this;
|
||||
// These functions have non-descript names because they were originally for(;;) loops.
|
||||
// I don't know about cryptography to give them better names than loop1-4.
|
||||
var loop1 = function() {
|
||||
var loop4 = function() {
|
||||
if (rsa.p.compareTo(rsa.q) <= 0) {
|
||||
var t = rsa.p;
|
||||
rsa.p = rsa.q;
|
||||
rsa.q = t;
|
||||
}
|
||||
var p1 = rsa.p.subtract(BigInteger.ONE);
|
||||
var q1 = rsa.q.subtract(BigInteger.ONE);
|
||||
var phi = p1.multiply(q1);
|
||||
if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
|
||||
rsa.n = rsa.p.multiply(rsa.q);
|
||||
rsa.d = ee.modInverse(phi);
|
||||
rsa.dmp1 = rsa.d.mod(p1);
|
||||
rsa.dmq1 = rsa.d.mod(q1);
|
||||
rsa.coeff = rsa.q.modInverse(rsa.p);
|
||||
setTimeout(function(){callback()},0); // escape
|
||||
} else {
|
||||
setTimeout(loop1,0);
|
||||
}
|
||||
};
|
||||
var loop3 = function() {
|
||||
rsa.q = nbi();
|
||||
rsa.q.fromNumberAsync(qs, 1, rng, function(){
|
||||
rsa.q.subtract(BigInteger.ONE).gcda(ee, function(r){
|
||||
if (r.compareTo(BigInteger.ONE) == 0 && rsa.q.isProbablePrime(10)) {
|
||||
setTimeout(loop4,0);
|
||||
} else {
|
||||
setTimeout(loop3,0);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
var loop2 = function() {
|
||||
rsa.p = nbi();
|
||||
rsa.p.fromNumberAsync(B - qs, 1, rng, function(){
|
||||
rsa.p.subtract(BigInteger.ONE).gcda(ee, function(r){
|
||||
if (r.compareTo(BigInteger.ONE) == 0 && rsa.p.isProbablePrime(10)) {
|
||||
setTimeout(loop3,0);
|
||||
} else {
|
||||
setTimeout(loop2,0);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
setTimeout(loop2,0);
|
||||
};
|
||||
setTimeout(loop1,0);
|
||||
};
|
||||
RSAKey.prototype.generateAsync = RSAGenerateAsync;
|
||||
|
||||
// Public API method
|
||||
var bnGCDAsync = function (a, callback) {
|
||||
var x = (this.s < 0) ? this.negate() : this.clone();
|
||||
var y = (a.s < 0) ? a.negate() : a.clone();
|
||||
if (x.compareTo(y) < 0) {
|
||||
var t = x;
|
||||
x = y;
|
||||
y = t;
|
||||
}
|
||||
var i = x.getLowestSetBit(),
|
||||
g = y.getLowestSetBit();
|
||||
if (g < 0) {
|
||||
callback(x);
|
||||
return;
|
||||
}
|
||||
if (i < g) g = i;
|
||||
if (g > 0) {
|
||||
x.rShiftTo(g, x);
|
||||
y.rShiftTo(g, y);
|
||||
}
|
||||
// Workhorse of the algorithm, gets called 200 - 800 times per 512 bit keygen.
|
||||
var gcda1 = function() {
|
||||
if ((i = x.getLowestSetBit()) > 0){ x.rShiftTo(i, x); }
|
||||
if ((i = y.getLowestSetBit()) > 0){ y.rShiftTo(i, y); }
|
||||
if (x.compareTo(y) >= 0) {
|
||||
x.subTo(y, x);
|
||||
x.rShiftTo(1, x);
|
||||
} else {
|
||||
y.subTo(x, y);
|
||||
y.rShiftTo(1, y);
|
||||
}
|
||||
if(!(x.signum() > 0)) {
|
||||
if (g > 0) y.lShiftTo(g, y);
|
||||
setTimeout(function(){callback(y)},0); // escape
|
||||
} else {
|
||||
setTimeout(gcda1,0);
|
||||
}
|
||||
};
|
||||
setTimeout(gcda1,10);
|
||||
};
|
||||
BigInteger.prototype.gcda = bnGCDAsync;
|
||||
|
||||
// (protected) alternate constructor
|
||||
var bnpFromNumberAsync = function (a,b,c,callback) {
|
||||
if("number" == typeof b) {
|
||||
if(a < 2) {
|
||||
this.fromInt(1);
|
||||
} else {
|
||||
this.fromNumber(a,c);
|
||||
if(!this.testBit(a-1)){
|
||||
this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);
|
||||
}
|
||||
if(this.isEven()) {
|
||||
this.dAddOffset(1,0);
|
||||
}
|
||||
var bnp = this;
|
||||
var bnpfn1 = function(){
|
||||
bnp.dAddOffset(2,0);
|
||||
if(bnp.bitLength() > a) bnp.subTo(BigInteger.ONE.shiftLeft(a-1),bnp);
|
||||
if(bnp.isProbablePrime(b)) {
|
||||
setTimeout(function(){callback()},0); // escape
|
||||
} else {
|
||||
setTimeout(bnpfn1,0);
|
||||
}
|
||||
};
|
||||
setTimeout(bnpfn1,0);
|
||||
}
|
||||
} else {
|
||||
var x = new Array(), t = a&7;
|
||||
x.length = (a>>3)+1;
|
||||
b.nextBytes(x);
|
||||
if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;
|
||||
this.fromString(x,256);
|
||||
}
|
||||
};
|
||||
BigInteger.prototype.fromNumberAsync = bnpFromNumberAsync;
|
||||
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue