rsasync-rails 13.2.11.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rsasync-rails.rb +11 -0
- data/lib/rsasync-rails/engine.rb +6 -0
- data/lib/rsasync-rails/railtie.rb +6 -0
- data/lib/rsasync-rails/version.rb +5 -0
- data/vendor/assets/javascripts/base64.js +71 -0
- data/vendor/assets/javascripts/jsbn.js +559 -0
- data/vendor/assets/javascripts/jsbn2.js +656 -0
- data/vendor/assets/javascripts/prng4.js +45 -0
- data/vendor/assets/javascripts/rng.js +68 -0
- data/vendor/assets/javascripts/rsa.js +112 -0
- data/vendor/assets/javascripts/rsa2.js +132 -0
- data/vendor/assets/javascripts/rsasync-rails.js +2 -0
- data/vendor/assets/javascripts/rsasync.js +152 -0
- data/vendor/assets/javascripts/ssh-format-rails.coffee +139 -0
- metadata +125 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
// prng4.js - uses Arcfour as a PRNG
|
2
|
+
|
3
|
+
function Arcfour() {
|
4
|
+
this.i = 0;
|
5
|
+
this.j = 0;
|
6
|
+
this.S = new Array();
|
7
|
+
}
|
8
|
+
|
9
|
+
// Initialize arcfour context from key, an array of ints, each from [0..255]
|
10
|
+
function ARC4init(key) {
|
11
|
+
var i, j, t;
|
12
|
+
for(i = 0; i < 256; ++i)
|
13
|
+
this.S[i] = i;
|
14
|
+
j = 0;
|
15
|
+
for(i = 0; i < 256; ++i) {
|
16
|
+
j = (j + this.S[i] + key[i % key.length]) & 255;
|
17
|
+
t = this.S[i];
|
18
|
+
this.S[i] = this.S[j];
|
19
|
+
this.S[j] = t;
|
20
|
+
}
|
21
|
+
this.i = 0;
|
22
|
+
this.j = 0;
|
23
|
+
}
|
24
|
+
|
25
|
+
function ARC4next() {
|
26
|
+
var t;
|
27
|
+
this.i = (this.i + 1) & 255;
|
28
|
+
this.j = (this.j + this.S[this.i]) & 255;
|
29
|
+
t = this.S[this.i];
|
30
|
+
this.S[this.i] = this.S[this.j];
|
31
|
+
this.S[this.j] = t;
|
32
|
+
return this.S[(t + this.S[this.i]) & 255];
|
33
|
+
}
|
34
|
+
|
35
|
+
Arcfour.prototype.init = ARC4init;
|
36
|
+
Arcfour.prototype.next = ARC4next;
|
37
|
+
|
38
|
+
// Plug in your RNG constructor here
|
39
|
+
function prng_newstate() {
|
40
|
+
return new Arcfour();
|
41
|
+
}
|
42
|
+
|
43
|
+
// Pool size must be a multiple of 4 and greater than 32.
|
44
|
+
// An array of bytes the size of the pool will be passed to init()
|
45
|
+
var rng_psize = 256;
|
@@ -0,0 +1,68 @@
|
|
1
|
+
// Random number generator - requires a PRNG backend, e.g. prng4.js
|
2
|
+
|
3
|
+
// For best results, put code like
|
4
|
+
// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
|
5
|
+
// in your main HTML document.
|
6
|
+
|
7
|
+
var rng_state;
|
8
|
+
var rng_pool;
|
9
|
+
var rng_pptr;
|
10
|
+
|
11
|
+
// Mix in a 32-bit integer into the pool
|
12
|
+
function rng_seed_int(x) {
|
13
|
+
rng_pool[rng_pptr++] ^= x & 255;
|
14
|
+
rng_pool[rng_pptr++] ^= (x >> 8) & 255;
|
15
|
+
rng_pool[rng_pptr++] ^= (x >> 16) & 255;
|
16
|
+
rng_pool[rng_pptr++] ^= (x >> 24) & 255;
|
17
|
+
if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;
|
18
|
+
}
|
19
|
+
|
20
|
+
// Mix in the current time (w/milliseconds) into the pool
|
21
|
+
function rng_seed_time() {
|
22
|
+
rng_seed_int(new Date().getTime());
|
23
|
+
}
|
24
|
+
|
25
|
+
// Initialize the pool with junk if needed.
|
26
|
+
if(rng_pool == null) {
|
27
|
+
rng_pool = new Array();
|
28
|
+
rng_pptr = 0;
|
29
|
+
var t;
|
30
|
+
if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) {
|
31
|
+
// Extract entropy (256 bits) from NS4 RNG if available
|
32
|
+
var z = window.crypto.random(32);
|
33
|
+
for(t = 0; t < z.length; ++t)
|
34
|
+
rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
|
35
|
+
}
|
36
|
+
while(rng_pptr < rng_psize) { // extract some randomness from Math.random()
|
37
|
+
t = Math.floor(65536 * Math.random());
|
38
|
+
rng_pool[rng_pptr++] = t >>> 8;
|
39
|
+
rng_pool[rng_pptr++] = t & 255;
|
40
|
+
}
|
41
|
+
rng_pptr = 0;
|
42
|
+
rng_seed_time();
|
43
|
+
//rng_seed_int(window.screenX);
|
44
|
+
//rng_seed_int(window.screenY);
|
45
|
+
}
|
46
|
+
|
47
|
+
function rng_get_byte() {
|
48
|
+
if(rng_state == null) {
|
49
|
+
rng_seed_time();
|
50
|
+
rng_state = prng_newstate();
|
51
|
+
rng_state.init(rng_pool);
|
52
|
+
for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
|
53
|
+
rng_pool[rng_pptr] = 0;
|
54
|
+
rng_pptr = 0;
|
55
|
+
//rng_pool = null;
|
56
|
+
}
|
57
|
+
// TODO: allow reseeding after first request
|
58
|
+
return rng_state.next();
|
59
|
+
}
|
60
|
+
|
61
|
+
function rng_get_bytes(ba) {
|
62
|
+
var i;
|
63
|
+
for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
|
64
|
+
}
|
65
|
+
|
66
|
+
function SecureRandom() {}
|
67
|
+
|
68
|
+
SecureRandom.prototype.nextBytes = rng_get_bytes;
|
@@ -0,0 +1,112 @@
|
|
1
|
+
// Depends on jsbn.js and rng.js
|
2
|
+
|
3
|
+
// Version 1.1: support utf-8 encoding in pkcs1pad2
|
4
|
+
|
5
|
+
// convert a (hex) string to a bignum object
|
6
|
+
function parseBigInt(str,r) {
|
7
|
+
return new BigInteger(str,r);
|
8
|
+
}
|
9
|
+
|
10
|
+
function linebrk(s,n) {
|
11
|
+
var ret = "";
|
12
|
+
var i = 0;
|
13
|
+
while(i + n < s.length) {
|
14
|
+
ret += s.substring(i,i+n) + "\n";
|
15
|
+
i += n;
|
16
|
+
}
|
17
|
+
return ret + s.substring(i,s.length);
|
18
|
+
}
|
19
|
+
|
20
|
+
function byte2Hex(b) {
|
21
|
+
if(b < 0x10)
|
22
|
+
return "0" + b.toString(16);
|
23
|
+
else
|
24
|
+
return b.toString(16);
|
25
|
+
}
|
26
|
+
|
27
|
+
// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
|
28
|
+
function pkcs1pad2(s,n) {
|
29
|
+
if(n < s.length + 11) { // TODO: fix for utf-8
|
30
|
+
alert("Message too long for RSA");
|
31
|
+
return null;
|
32
|
+
}
|
33
|
+
var ba = new Array();
|
34
|
+
var i = s.length - 1;
|
35
|
+
while(i >= 0 && n > 0) {
|
36
|
+
var c = s.charCodeAt(i--);
|
37
|
+
if(c < 128) { // encode using utf-8
|
38
|
+
ba[--n] = c;
|
39
|
+
}
|
40
|
+
else if((c > 127) && (c < 2048)) {
|
41
|
+
ba[--n] = (c & 63) | 128;
|
42
|
+
ba[--n] = (c >> 6) | 192;
|
43
|
+
}
|
44
|
+
else {
|
45
|
+
ba[--n] = (c & 63) | 128;
|
46
|
+
ba[--n] = ((c >> 6) & 63) | 128;
|
47
|
+
ba[--n] = (c >> 12) | 224;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
ba[--n] = 0;
|
51
|
+
var rng = new SecureRandom();
|
52
|
+
var x = new Array();
|
53
|
+
while(n > 2) { // random non-zero pad
|
54
|
+
x[0] = 0;
|
55
|
+
while(x[0] == 0) rng.nextBytes(x);
|
56
|
+
ba[--n] = x[0];
|
57
|
+
}
|
58
|
+
ba[--n] = 2;
|
59
|
+
ba[--n] = 0;
|
60
|
+
return new BigInteger(ba);
|
61
|
+
}
|
62
|
+
|
63
|
+
// "empty" RSA key constructor
|
64
|
+
function RSAKey() {
|
65
|
+
this.n = null;
|
66
|
+
this.e = 0;
|
67
|
+
this.d = null;
|
68
|
+
this.p = null;
|
69
|
+
this.q = null;
|
70
|
+
this.dmp1 = null;
|
71
|
+
this.dmq1 = null;
|
72
|
+
this.coeff = null;
|
73
|
+
}
|
74
|
+
|
75
|
+
// Set the public key fields N and e from hex strings
|
76
|
+
function RSASetPublic(N,E) {
|
77
|
+
if(N != null && E != null && N.length > 0 && E.length > 0) {
|
78
|
+
this.n = parseBigInt(N,16);
|
79
|
+
this.e = parseInt(E,16);
|
80
|
+
}
|
81
|
+
else
|
82
|
+
alert("Invalid RSA public key");
|
83
|
+
}
|
84
|
+
|
85
|
+
// Perform raw public operation on "x": return x^e (mod n)
|
86
|
+
function RSADoPublic(x) {
|
87
|
+
return x.modPowInt(this.e, this.n);
|
88
|
+
}
|
89
|
+
|
90
|
+
// Return the PKCS#1 RSA encryption of "text" as an even-length hex string
|
91
|
+
function RSAEncrypt(text) {
|
92
|
+
var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
|
93
|
+
if(m == null) return null;
|
94
|
+
var c = this.doPublic(m);
|
95
|
+
if(c == null) return null;
|
96
|
+
var h = c.toString(16);
|
97
|
+
if((h.length & 1) == 0) return h; else return "0" + h;
|
98
|
+
}
|
99
|
+
|
100
|
+
// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
|
101
|
+
//function RSAEncryptB64(text) {
|
102
|
+
// var h = this.encrypt(text);
|
103
|
+
// if(h) return hex2b64(h); else return null;
|
104
|
+
//}
|
105
|
+
|
106
|
+
// protected
|
107
|
+
RSAKey.prototype.doPublic = RSADoPublic;
|
108
|
+
|
109
|
+
// public
|
110
|
+
RSAKey.prototype.setPublic = RSASetPublic;
|
111
|
+
RSAKey.prototype.encrypt = RSAEncrypt;
|
112
|
+
//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
|
@@ -0,0 +1,132 @@
|
|
1
|
+
// Depends on rsa.js and jsbn2.js
|
2
|
+
|
3
|
+
// Version 1.1: support utf-8 decoding in pkcs1unpad2
|
4
|
+
|
5
|
+
// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
|
6
|
+
function pkcs1unpad2(d,n) {
|
7
|
+
var b = d.toByteArray();
|
8
|
+
var i = 0;
|
9
|
+
while(i < b.length && b[i] == 0) ++i;
|
10
|
+
if(b.length-i != n-1 || b[i] != 2)
|
11
|
+
return null;
|
12
|
+
++i;
|
13
|
+
while(b[i] != 0)
|
14
|
+
if(++i >= b.length) return null;
|
15
|
+
var ret = "";
|
16
|
+
while(++i < b.length) {
|
17
|
+
var c = b[i] & 255;
|
18
|
+
if(c < 128) { // utf-8 decode
|
19
|
+
ret += String.fromCharCode(c);
|
20
|
+
}
|
21
|
+
else if((c > 191) && (c < 224)) {
|
22
|
+
ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63));
|
23
|
+
++i;
|
24
|
+
}
|
25
|
+
else {
|
26
|
+
ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63));
|
27
|
+
i += 2;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
return ret;
|
31
|
+
}
|
32
|
+
|
33
|
+
// Set the private key fields N, e, and d from hex strings
|
34
|
+
function RSASetPrivate(N,E,D) {
|
35
|
+
if(N != null && E != null && N.length > 0 && E.length > 0) {
|
36
|
+
this.n = parseBigInt(N,16);
|
37
|
+
this.e = parseInt(E,16);
|
38
|
+
this.d = parseBigInt(D,16);
|
39
|
+
}
|
40
|
+
else
|
41
|
+
alert("Invalid RSA private key");
|
42
|
+
}
|
43
|
+
|
44
|
+
// Set the private key fields N, e, d and CRT params from hex strings
|
45
|
+
function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) {
|
46
|
+
if(N != null && E != null && N.length > 0 && E.length > 0) {
|
47
|
+
this.n = parseBigInt(N,16);
|
48
|
+
this.e = parseInt(E,16);
|
49
|
+
this.d = parseBigInt(D,16);
|
50
|
+
this.p = parseBigInt(P,16);
|
51
|
+
this.q = parseBigInt(Q,16);
|
52
|
+
this.dmp1 = parseBigInt(DP,16);
|
53
|
+
this.dmq1 = parseBigInt(DQ,16);
|
54
|
+
this.coeff = parseBigInt(C,16);
|
55
|
+
}
|
56
|
+
else
|
57
|
+
alert("Invalid RSA private key");
|
58
|
+
}
|
59
|
+
|
60
|
+
// Generate a new random private key B bits long, using public expt E
|
61
|
+
function RSAGenerate(B,E) {
|
62
|
+
var rng = new SecureRandom();
|
63
|
+
var qs = B>>1;
|
64
|
+
this.e = parseInt(E,16);
|
65
|
+
var ee = new BigInteger(E,16);
|
66
|
+
for(;;) {
|
67
|
+
for(;;) {
|
68
|
+
this.p = new BigInteger(B-qs,1,rng);
|
69
|
+
if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;
|
70
|
+
}
|
71
|
+
for(;;) {
|
72
|
+
this.q = new BigInteger(qs,1,rng);
|
73
|
+
if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;
|
74
|
+
}
|
75
|
+
if(this.p.compareTo(this.q) <= 0) {
|
76
|
+
var t = this.p;
|
77
|
+
this.p = this.q;
|
78
|
+
this.q = t;
|
79
|
+
}
|
80
|
+
var p1 = this.p.subtract(BigInteger.ONE);
|
81
|
+
var q1 = this.q.subtract(BigInteger.ONE);
|
82
|
+
var phi = p1.multiply(q1);
|
83
|
+
if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
|
84
|
+
this.n = this.p.multiply(this.q);
|
85
|
+
this.d = ee.modInverse(phi);
|
86
|
+
this.dmp1 = this.d.mod(p1);
|
87
|
+
this.dmq1 = this.d.mod(q1);
|
88
|
+
this.coeff = this.q.modInverse(this.p);
|
89
|
+
break;
|
90
|
+
}
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
// Perform raw private operation on "x": return x^d (mod n)
|
95
|
+
function RSADoPrivate(x) {
|
96
|
+
if(this.p == null || this.q == null)
|
97
|
+
return x.modPow(this.d, this.n);
|
98
|
+
|
99
|
+
// TODO: re-calculate any missing CRT params
|
100
|
+
var xp = x.mod(this.p).modPow(this.dmp1, this.p);
|
101
|
+
var xq = x.mod(this.q).modPow(this.dmq1, this.q);
|
102
|
+
|
103
|
+
while(xp.compareTo(xq) < 0)
|
104
|
+
xp = xp.add(this.p);
|
105
|
+
return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
|
106
|
+
}
|
107
|
+
|
108
|
+
// Return the PKCS#1 RSA decryption of "ctext".
|
109
|
+
// "ctext" is an even-length hex string and the output is a plain string.
|
110
|
+
function RSADecrypt(ctext) {
|
111
|
+
var c = parseBigInt(ctext, 16);
|
112
|
+
var m = this.doPrivate(c);
|
113
|
+
if(m == null) return null;
|
114
|
+
return pkcs1unpad2(m, (this.n.bitLength()+7)>>3);
|
115
|
+
}
|
116
|
+
|
117
|
+
// Return the PKCS#1 RSA decryption of "ctext".
|
118
|
+
// "ctext" is a Base64-encoded string and the output is a plain string.
|
119
|
+
//function RSAB64Decrypt(ctext) {
|
120
|
+
// var h = b64tohex(ctext);
|
121
|
+
// if(h) return this.decrypt(h); else return null;
|
122
|
+
//}
|
123
|
+
|
124
|
+
// protected
|
125
|
+
RSAKey.prototype.doPrivate = RSADoPrivate;
|
126
|
+
|
127
|
+
// public
|
128
|
+
RSAKey.prototype.setPrivate = RSASetPrivate;
|
129
|
+
RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
|
130
|
+
RSAKey.prototype.generate = RSAGenerate;
|
131
|
+
RSAKey.prototype.decrypt = RSADecrypt;
|
132
|
+
//RSAKey.prototype.b64_decrypt = RSAB64Decrypt;
|
@@ -0,0 +1,152 @@
|
|
1
|
+
// Copyright (c) 2011 Kevin M Burns Jr.
|
2
|
+
// All Rights Reserved.
|
3
|
+
// See "LICENSE" for details.
|
4
|
+
//
|
5
|
+
// Extension to jsbn which adds facilities for asynchronous RSA key generation
|
6
|
+
// Primarily created to avoid execution timeout on mobile devices
|
7
|
+
//
|
8
|
+
// http://www-cs-students.stanford.edu/~tjw/jsbn/
|
9
|
+
//
|
10
|
+
// ---
|
11
|
+
|
12
|
+
(function(){
|
13
|
+
|
14
|
+
// Generate a new random private key B bits long, using public expt E
|
15
|
+
var RSAGenerateAsync = function (B, E, callback) {
|
16
|
+
//var rng = new SeededRandom();
|
17
|
+
var rng = new SecureRandom();
|
18
|
+
var qs = B >> 1;
|
19
|
+
this.e = parseInt(E, 16);
|
20
|
+
var ee = new BigInteger(E, 16);
|
21
|
+
var rsa = this;
|
22
|
+
// These functions have non-descript names because they were originally for(;;) loops.
|
23
|
+
// I don't know about cryptography to give them better names than loop1-4.
|
24
|
+
var loop1 = function() {
|
25
|
+
var loop4 = function() {
|
26
|
+
if (rsa.p.compareTo(rsa.q) <= 0) {
|
27
|
+
var t = rsa.p;
|
28
|
+
rsa.p = rsa.q;
|
29
|
+
rsa.q = t;
|
30
|
+
}
|
31
|
+
var p1 = rsa.p.subtract(BigInteger.ONE);
|
32
|
+
var q1 = rsa.q.subtract(BigInteger.ONE);
|
33
|
+
var phi = p1.multiply(q1);
|
34
|
+
if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
|
35
|
+
rsa.n = rsa.p.multiply(rsa.q);
|
36
|
+
rsa.d = ee.modInverse(phi);
|
37
|
+
rsa.dmp1 = rsa.d.mod(p1);
|
38
|
+
rsa.dmq1 = rsa.d.mod(q1);
|
39
|
+
rsa.coeff = rsa.q.modInverse(rsa.p);
|
40
|
+
setTimeout(function(){callback()},0); // escape
|
41
|
+
} else {
|
42
|
+
setTimeout(loop1,0);
|
43
|
+
}
|
44
|
+
};
|
45
|
+
var loop3 = function() {
|
46
|
+
rsa.q = nbi();
|
47
|
+
rsa.q.fromNumberAsync(qs, 1, rng, function(){
|
48
|
+
rsa.q.subtract(BigInteger.ONE).gcda(ee, function(r){
|
49
|
+
if (r.compareTo(BigInteger.ONE) == 0 && rsa.q.isProbablePrime(10)) {
|
50
|
+
setTimeout(loop4,0);
|
51
|
+
} else {
|
52
|
+
setTimeout(loop3,0);
|
53
|
+
}
|
54
|
+
});
|
55
|
+
});
|
56
|
+
};
|
57
|
+
var loop2 = function() {
|
58
|
+
rsa.p = nbi();
|
59
|
+
rsa.p.fromNumberAsync(B - qs, 1, rng, function(){
|
60
|
+
rsa.p.subtract(BigInteger.ONE).gcda(ee, function(r){
|
61
|
+
if (r.compareTo(BigInteger.ONE) == 0 && rsa.p.isProbablePrime(10)) {
|
62
|
+
setTimeout(loop3,0);
|
63
|
+
} else {
|
64
|
+
setTimeout(loop2,0);
|
65
|
+
}
|
66
|
+
});
|
67
|
+
});
|
68
|
+
};
|
69
|
+
setTimeout(loop2,0);
|
70
|
+
};
|
71
|
+
setTimeout(loop1,0);
|
72
|
+
};
|
73
|
+
RSAKey.prototype.generateAsync = RSAGenerateAsync;
|
74
|
+
|
75
|
+
// Public API method
|
76
|
+
var bnGCDAsync = function (a, callback) {
|
77
|
+
var x = (this.s < 0) ? this.negate() : this.clone();
|
78
|
+
var y = (a.s < 0) ? a.negate() : a.clone();
|
79
|
+
if (x.compareTo(y) < 0) {
|
80
|
+
var t = x;
|
81
|
+
x = y;
|
82
|
+
y = t;
|
83
|
+
}
|
84
|
+
var i = x.getLowestSetBit(),
|
85
|
+
g = y.getLowestSetBit();
|
86
|
+
if (g < 0) {
|
87
|
+
callback(x);
|
88
|
+
return;
|
89
|
+
}
|
90
|
+
if (i < g) g = i;
|
91
|
+
if (g > 0) {
|
92
|
+
x.rShiftTo(g, x);
|
93
|
+
y.rShiftTo(g, y);
|
94
|
+
}
|
95
|
+
// Workhorse of the algorithm, gets called 200 - 800 times per 512 bit keygen.
|
96
|
+
var gcda1 = function() {
|
97
|
+
if ((i = x.getLowestSetBit()) > 0){ x.rShiftTo(i, x); }
|
98
|
+
if ((i = y.getLowestSetBit()) > 0){ y.rShiftTo(i, y); }
|
99
|
+
if (x.compareTo(y) >= 0) {
|
100
|
+
x.subTo(y, x);
|
101
|
+
x.rShiftTo(1, x);
|
102
|
+
} else {
|
103
|
+
y.subTo(x, y);
|
104
|
+
y.rShiftTo(1, y);
|
105
|
+
}
|
106
|
+
if(!(x.signum() > 0)) {
|
107
|
+
if (g > 0) y.lShiftTo(g, y);
|
108
|
+
setTimeout(function(){callback(y)},0); // escape
|
109
|
+
} else {
|
110
|
+
setTimeout(gcda1,0);
|
111
|
+
}
|
112
|
+
};
|
113
|
+
setTimeout(gcda1,10);
|
114
|
+
};
|
115
|
+
BigInteger.prototype.gcda = bnGCDAsync;
|
116
|
+
|
117
|
+
// (protected) alternate constructor
|
118
|
+
var bnpFromNumberAsync = function (a,b,c,callback) {
|
119
|
+
if("number" == typeof b) {
|
120
|
+
if(a < 2) {
|
121
|
+
this.fromInt(1);
|
122
|
+
} else {
|
123
|
+
this.fromNumber(a,c);
|
124
|
+
if(!this.testBit(a-1)){
|
125
|
+
this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);
|
126
|
+
}
|
127
|
+
if(this.isEven()) {
|
128
|
+
this.dAddOffset(1,0);
|
129
|
+
}
|
130
|
+
var bnp = this;
|
131
|
+
var bnpfn1 = function(){
|
132
|
+
bnp.dAddOffset(2,0);
|
133
|
+
if(bnp.bitLength() > a) bnp.subTo(BigInteger.ONE.shiftLeft(a-1),bnp);
|
134
|
+
if(bnp.isProbablePrime(b)) {
|
135
|
+
setTimeout(function(){callback()},0); // escape
|
136
|
+
} else {
|
137
|
+
setTimeout(bnpfn1,0);
|
138
|
+
}
|
139
|
+
};
|
140
|
+
setTimeout(bnpfn1,0);
|
141
|
+
}
|
142
|
+
} else {
|
143
|
+
var x = new Array(), t = a&7;
|
144
|
+
x.length = (a>>3)+1;
|
145
|
+
b.nextBytes(x);
|
146
|
+
if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;
|
147
|
+
this.fromString(x,256);
|
148
|
+
}
|
149
|
+
};
|
150
|
+
BigInteger.prototype.fromNumberAsync = bnpFromNumberAsync;
|
151
|
+
|
152
|
+
})();
|