rsasync-rails 13.2.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+ })();