rsasync-rails 13.2.11.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,2 @@
1
+ //= require jsbn-rails
2
+ //= require rsasync
@@ -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
+ })();