PageSourceSearch

https://cas.xacxxy.com/cas/js/login/security.js

js xacxxy.com collected 2026-10-08 20:58:53 UTC 19,078 bytes, 697 lines download raw bytes

1/*
2 * RSA, a suite of routines for performing RSA public-key computations in JavaScript.
3 * Copyright 1998-2005 David Shapiro.
4 * Dave Shapiro
5 * [email protected] 
6 * changed by Fuchun, 2010-05-06
7 * [email protected]
8 */
9
10(function($w) {
11
12if(typeof $w.RSAUtils === 'undefined')
13	var RSAUtils = $w.RSAUtils = {};
14
15var biRadixBase = 2;
16var biRadixBits = 16;
17var bitsPerDigit = biRadixBits;
18var biRadix = 1 << 16; // = 2^16 = 65536
19var biHalfRadix = biRadix >>> 1;
20var biRadixSquared = biRadix * biRadix;
21var maxDigitVal = biRadix - 1;
22var maxInteger = 9999999999999998;
23
24//maxDigits:
25//Change this to accommodate your largest number size. Use setMaxDigits()
26//to change it!
27//
28//In general, if you're working with numbers of size N bits, you'll need 2*N
29//bits of storage. Each digit holds 16 bits. So, a 1024-bit key will need
30//
31//1024 * 2 / 16 = 128 digits of storage.
32//
33var maxDigits;
34var ZERO_ARRAY;
35var bigZero, bigOne;
36
37var BigInt = $w.BigInt = function(flag) {
38	if (typeof flag == "boolean" && flag == true) {
39		this.digits = null;
40	} else {
41		this.digits = ZERO_ARRAY.slice(0);
42	}
43	this.isNeg = false;
44};
45
46RSAUtils.setMaxDigits = function(value) {
47	maxDigits = value;
48	ZERO_ARRAY = new Array(maxDigits);
49	for (var iza = 0; iza < ZERO_ARRAY.length; iza++) ZERO_ARRAY[iza] = 0;
50	bigZero = new BigInt();
51	bigOne = new BigInt();
52	bigOne.digits[0] = 1;
53};
54RSAUtils.setMaxDigits(20);
55
56//The maximum number of digits in base 10 you can convert to an
57//integer without JavaScript throwing up on you.
58var dpl10 = 15;
59
60RSAUtils.biFromNumber = function(i) {
61	var result = new BigInt();
62	result.isNeg = i < 0;
63	i = Math.abs(i);
64	var j = 0;
65	while (i > 0) {
66		result.digits[j++] = i & maxDigitVal;
67		i = Math.floor(i / biRadix);
68	}
69	return result;
70};
71
72//lr10 = 10 ^ dpl10
73var lr10 = RSAUtils.biFromNumber(1000000000000000);
74
75RSAUtils.biFromDecimal = function(s) {
76	var isNeg = s.charAt(0) == '-';
77	var i = isNeg ? 1 : 0;
78	var result;
79	// Skip leading zeros.
80	while (i < s.length && s.charAt(i) == '0') ++i;
81	if (i == s.length) {
82		result = new BigInt();
83	}
84	else {
85		var digitCount = s.length - i;
86		var fgl = digitCount % dpl10;
87		if (fgl == 0) fgl = dpl10;
88		result = RSAUtils.biFromNumber(Number(s.substr(i, fgl)));
89		i += fgl;
90		while (i < s.length) {
91			result = RSAUtils.biAdd(RSAUtils.biMultiply(result, lr10),
92					RSAUtils.biFromNumber(Number(s.substr(i, dpl10))));
93			i += dpl10;
94		}
95		result.isNeg = isNeg;
96	}
97	return result;
98};
99
100RSAUtils.biCopy = function(bi) {
101	var result = new BigInt(true);
102	result.digits = bi.digits.slice(0);
103	result.isNeg = bi.isNeg;
104	return result;
105};
106
107RSAUtils.reverseStr = function(s) {
108	var result = "";
109	for (var i = s.length - 1; i > -1; --i) {
110		result += s.charAt(i);
111	}
112	return result;
113};
114
115var hexatrigesimalToChar = [
116	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
117	'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
118	'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
119	'u', 'v', 'w', 'x', 'y', 'z'
120];
121
122RSAUtils.biToString = function(x, radix) { // 2 <= radix <= 36
123	var b = new BigInt();
124	b.digits[0] = radix;
125	var qr = RSAUtils.biDivideModulo(x, b);
126	var result = hexatrigesimalToChar[qr[1].digits[0]];
127	while (RSAUtils.biCompare(qr[0], bigZero) == 1) {
128		qr = RSAUtils.biDivideModulo(qr[0], b);
129		digit = qr[1].digits[0];
130		result += hexatrigesimalToChar[qr[1].digits[0]];
131	}
132	return (x.isNeg ? "-" : "") + RSAUtils.reverseStr(result);
133};
134
135RSAUtils.biToDecimal = function(x) {
136	var b = new BigInt();
137	b.digits[0] = 10;
138	var qr = RSAUtils.biDivideModulo(x, b);
139	var result = String(qr[1].digits[0]);
140	while (RSAUtils.biCompare(qr[0], bigZero) == 1) {
141		qr = RSAUtils.biDivideModulo(qr[0], b);
142		result += String(qr[1].digits[0]);
143	}
144	return (x.isNeg ? "-" : "") + RSAUtils.reverseStr(result);
145};
146
147var hexToChar = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
148        'a', 'b', 'c', 'd', 'e', 'f'];
149
150RSAUtils.digitToHex = function(n) {
151	var mask = 0xf;
152	var result = "";
153	for (i = 0; i < 4; ++i) {
154		result += hexToChar[n & mask];
155		n >>>= 4;
156	}
157	return RSAUtils.reverseStr(result);
158};
159
160RSAUtils.biToHex = function(x) {
161	var result = "";
162	var n = RSAUtils.biHighIndex(x);
163	for (var i = RSAUtils.biHighIndex(x); i > -1; --i) {
164		result += RSAUtils.digitToHex(x.digits[i]);
165	}
166	return result;
167};
168
169RSAUtils.charToHex = function(c) {
170	var ZERO = 48;
171	var NINE = ZERO + 9;
172	var littleA = 97;
173	var littleZ = littleA + 25;
174	var bigA = 65;
175	var bigZ = 65 + 25;
176	var result;
177
178	if (c >= ZERO && c <= NINE) {
179		result = c - ZERO;
180	} else if (c >= bigA && c <= bigZ) {
181		result = 10 + c - bigA;
182	} else if (c >= littleA && c <= littleZ) {
183		result = 10 + c - littleA;
184	} else {
185		result = 0;
186	}
187	return result;
188};
189
190RSAUtils.hexToDigit = function(s) {
191	var result = 0;
192	var sl = Math.min(s.length, 4);
193	for (var i = 0; i < sl; ++i) {
194		result <<= 4;
195		result |= RSAUtils.charToHex(s.charCodeAt(i));
196	}
197	return result;
198};
199
200RSAUtils.biFromHex = function(s) {
201	var result = new BigInt();
202	var sl = s.length;
203	for (var i = sl, j = 0; i > 0; i -= 4, ++j) {
204		result.digits[j] = RSAUtils.hexToDigit(s.substr(Math.max(i - 4, 0), Math.min(i, 4)));
205	}
206	return result;
207};
208
209RSAUtils.biFromString = function(s, radix) {
210	var isNeg = s.charAt(0) == '-';
211	var istop = isNeg ? 1 : 0;
212	var result = new BigInt();
213	var place = new BigInt();
214	place.digits[0] = 1; // radix^0
215	for (var i = s.length - 1; i >= istop; i--) {
216		var c = s.charCodeAt(i);
217		var digit = RSAUtils.charToHex(c);
218		var biDigit = RSAUtils.biMultiplyDigit(place, digit);
219		result = RSAUtils.biAdd(result, biDigit);
220		place = RSAUtils.biMultiplyDigit(place, radix);
221	}
222	result.isNeg = isNeg;
223	return result;
224};
225
226RSAUtils.biDump = function(b) {
227	return (b.isNeg ? "-" : "") + b.digits.join(" ");
228};
229
230RSAUtils.biAdd = function(x, y) {
231	var result;
232
233	if (x.isNeg != y.isNeg) {
234		y.isNeg = !y.isNeg;
235		result = RSAUtils.biSubtract(x, y);
236		y.isNeg = !y.isNeg;
237	}
238	else {
239		result = new BigInt();
240		var c = 0;
241		var n;
242		for (var i = 0; i < x.digits.length; ++i) {
243			n = x.digits[i] + y.digits[i] + c;
244			result.digits[i] = n % biRadix;
245			c = Number(n >= biRadix);
246		}
247		result.isNeg = x.isNeg;
248	}
249	return result;
250};
251
252RSAUtils.biSubtract = function(x, y) {
253	var result;
254	if (x.isNeg != y.isNeg) {
255		y.isNeg = !y.isNeg;
256		result = RSAUtils.biAdd(x, y);
257		y.isNeg = !y.isNeg;
258	} else {
259		result = new BigInt();
260		var n, c;
261		c = 0;
262		for (var i = 0; i < x.digits.length; ++i) {
263			n = x.digits[i] - y.digits[i] + c;
264			result.digits[i] = n % biRadix;
265			// Stupid non-conforming modulus operation.
266			if (result.digits[i] < 0) result.digits[i] += biRadix;
267			c = 0 - Number(n < 0);
268		}
269		// Fix up the negative sign, if any.
270		if (c == -1) {
271			c = 0;
272			for (var i = 0; i < x.digits.length; ++i) {
273				n = 0 - result.digits[i] + c;
274				result.digits[i] = n % biRadix;
275				// Stupid non-conforming modulus operation.
276				if (result.digits[i] < 0) result.digits[i] += biRadix;
277				c = 0 - Number(n < 0);
278			}
279			// Result is opposite sign of arguments.
280			result.isNeg = !x.isNeg;
281		} else {
282			// Result is same sign.
283			result.isNeg = x.isNeg;
284		}
285	}
286	return result;
287};
288
289RSAUtils.biHighIndex = function(x) {
290	var result = x.digits.length - 1;
291	while (result > 0 && x.digits[result] == 0) --result;
292	return result;
293};
294
295RSAUtils.biNumBits = function(x) {
296	var n = RSAUtils.biHighIndex(x);
297	var d = x.digits[n];
298	var m = (n + 1) * bitsPerDigit;
299	var result;
300	for (result = m; result > m - bitsPerDigit; --result) {
301		if ((d & 0x8000) != 0) break;
302		d <<= 1;
303	}
304	return result;
305};
306
307RSAUtils.biMultiply = function(x, y) {
308	var result = new BigInt();
309	var c;
310	var n = RSAUtils.biHighIndex(x);
311	var t = RSAUtils.biHighIndex(y);
312	var u, uv, k;
313
314	for (var i = 0; i <= t; ++i) {
315		c = 0;
316		k = i;
317		for (j = 0; j <= n; ++j, ++k) {
318			uv = result.digits[k] + x.digits[j] * y.digits[i] + c;
319			result.digits[k] = uv & maxDigitVal;
320			c = uv >>> biRadixBits;
321			//c = Math.floor(uv / biRadix);
322		}
323		result.digits[i + n + 1] = c;
324	}
325	// Someone give me a logical xor, please.
326	result.isNeg = x.isNeg != y.isNeg;
327	return result;
328};
329
330RSAUtils.biMultiplyDigit = function(x, y) {
331	var n, c, uv;
332
333	result = new BigInt();
334	n = RSAUtils.biHighIndex(x);
335	c = 0;
336	for (var j = 0; j <= n; ++j) {
337		uv = result.digits[j] + x.digits[j] * y + c;
338		result.digits[j] = uv & maxDigitVal;
339		c = uv >>> biRadixBits;
340		//c = Math.floor(uv / biRadix);
341	}
342	result.digits[1 + n] = c;
343	return result;
344};
345
346RSAUtils.arrayCopy = function(src, srcStart, dest, destStart, n) {
347	var m = Math.min(srcStart + n, src.length);
348	for (var i = srcStart, j = destStart; i < m; ++i, ++j) {
349		dest[j] = src[i];
350	}
351};
352
353var highBitMasks = [0x0000, 0x8000, 0xC000, 0xE000, 0xF000, 0xF800,
354        0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0,
355        0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF];
356
357RSAUtils.biShiftLeft = function(x, n) {
358	var digitCount = Math.floor(n / bitsPerDigit);
359	var result = new BigInt();
360	RSAUtils.arrayCopy(x.digits, 0, result.digits, digitCount,
361	          result.digits.length - digitCount);
362	var bits = n % bitsPerDigit;
363	var rightBits = bitsPerDigit - bits;
364	for (var i = result.digits.length - 1, i1 = i - 1; i > 0; --i, --i1) {
365		result.digits[i] = ((result.digits[i] << bits) & maxDigitVal) |
366		                   ((result.digits[i1] & highBitMasks[bits]) >>>
367		                    (rightBits));
368	}
369	result.digits[0] = ((result.digits[i] << bits) & maxDigitVal);
370	result.isNeg = x.isNeg;
371	return result;
372};
373
374var lowBitMasks = [0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F,
375        0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF,
376        0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF];
377
378RSAUtils.biShiftRight = function(x, n) {
379	var digitCount = Math.floor(n / bitsPerDigit);
380	var result = new BigInt();
381	RSAUtils.arrayCopy(x.digits, digitCount, result.digits, 0,
382	          x.digits.length - digitCount);
383	var bits = n % bitsPerDigit;
384	var leftBits = bitsPerDigit - bits;
385	for (var i = 0, i1 = i + 1; i < result.digits.length - 1; ++i, ++i1) {
386		result.digits[i] = (result.digits[i] >>> bits) |
387		                   ((result.digits[i1] & lowBitMasks[bits]) << leftBits);
388	}
389	result.digits[result.digits.length - 1] >>>= bits;
390	result.isNeg = x.isNeg;
391	return result;
392};
393
394RSAUtils.biMultiplyByRadixPower = function(x, n) {
395	var result = new BigInt();
396	RSAUtils.arrayCopy(x.digits, 0, result.digits, n, result.digits.length - n);
397	return result;
398};
399
400RSAUtils.biDivideByRadixPower = function(x, n) {
401	var result = new BigInt();
402	RSAUtils.arrayCopy(x.digits, n, result.digits, 0, result.digits.length - n);
403	return result;
404};
405
406RSAUtils.biModuloByRadixPower = function(x, n) {
407	var result = new BigInt();
408	RSAUtils.arrayCopy(x.digits, 0, result.digits, 0, n);
409	return result;
410};
411
412RSAUtils.biCompare = function(x, y) {
413	if (x.isNeg != y.isNeg) {
414		return 1 - 2 * Number(x.isNeg);
415	}
416	for (var i = x.digits.length - 1; i >= 0; --i) {
417		if (x.digits[i] != y.digits[i]) {
418			if (x.isNeg) {
419				return 1 - 2 * Number(x.digits[i] > y.digits[i]);
420			} else {
421				return 1 - 2 * Number(x.digits[i] < y.digits[i]);
422			}
423		}
424	}
425	return 0;
426};
427
428RSAUtils.biDivideModulo = function(x, y) {
429	var nb = RSAUtils.biNumBits(x);
430	var tb = RSAUtils.biNumBits(y);
431	var origYIsNeg = y.isNeg;
432	var q, r;
433	if (nb < tb) {
434		// |x| < |y|
435		if (x.isNeg) {
436			q = RSAUtils.biCopy(bigOne);
437			q.isNeg = !y.isNeg;
438			x.isNeg = false;
439			y.isNeg = false;
440			r = biSubtract(y, x);
441			// Restore signs, 'cause they're references.
442			x.isNeg = true;
443			y.isNeg = origYIsNeg;
444		} else {
445			q = new BigInt();
446			r = RSAUtils.biCopy(x);
447		}
448		return [q, r];
449	}
450
451	q = new BigInt();
452	r = x;
453
454	// Normalize Y.
455	var t = Math.ceil(tb / bitsPerDigit) - 1;
456	var lambda = 0;
457	while (y.digits[t] < biHalfRadix) {
458		y = RSAUtils.biShiftLeft(y, 1);
459		++lambda;
460		++tb;
461		t = Math.ceil(tb / bitsPerDigit) - 1;
462	}
463	// Shift r over to keep the quotient constant. We'll shift the
464	// remainder back at the end.
465	r = RSAUtils.biShiftLeft(r, lambda);
466	nb += lambda; // Update the bit count for x.
467	var n = Math.ceil(nb / bitsPerDigit) - 1;
468
469	var b = RSAUtils.biMultiplyByRadixPower(y, n - t);
470	while (RSAUtils.biCompare(r, b) != -1) {
471		++q.digits[n - t];
472		r = RSAUtils.biSubtract(r, b);
473	}
474	for (var i = n; i > t; --i) {
475    var ri = (i >= r.digits.length) ? 0 : r.digits[i];
476    var ri1 = (i - 1 >= r.digits.length) ? 0 : r.digits[i - 1];
477    var ri2 = (i - 2 >= r.digits.length) ? 0 : r.digits[i - 2];
478    var yt = (t >= y.digits.length) ? 0 : y.digits[t];
479    var yt1 = (t - 1 >= y.digits.length) ? 0 : y.digits[t - 1];
480		if (ri == yt) {
481			q.digits[i - t - 1] = maxDigitVal;
482		} else {
483			q.digits[i - t - 1] = Math.floor((ri * biRadix + ri1) / yt);
484		}
485
486		var c1 = q.digits[i - t - 1] * ((yt * biRadix) + yt1);
487		var c2 = (ri * biRadixSquared) + ((ri1 * biRadix) + ri2);
488		while (c1 > c2) {
489			--q.digits[i - t - 1];
490			c1 = q.digits[i - t - 1] * ((yt * biRadix) | yt1);
491			c2 = (ri * biRadix * biRadix) + ((ri1 * biRadix) + ri2);
492		}
493
494		b = RSAUtils.biMultiplyByRadixPower(y, i - t - 1);
495		r = RSAUtils.biSubtract(r, RSAUtils.biMultiplyDigit(b, q.digits[i - t - 1]));
496		if (r.isNeg) {
497			r = RSAUtils.biAdd(r, b);
498			--q.digits[i - t - 1];
499		}
500	}
501	r = RSAUtils.biShiftRight(r, lambda);
502	// Fiddle with the signs and stuff to make sure that 0 <= r < y.
503	q.isNeg = x.isNeg != origYIsNeg;
504	if (x.isNeg) {
505		if (origYIsNeg) {
506			q = RSAUtils.biAdd(q, bigOne);
507		} else {
508			q = RSAUtils.biSubtract(q, bigOne);
509		}
510		y = RSAUtils.biShiftRight(y, lambda);
511		r = RSAUtils.biSubtract(y, r);
512	}
513	// Check for the unbelievably stupid degenerate case of r == -0.
514	if (r.digits[0] == 0 && RSAUtils.biHighIndex(r) == 0) r.isNeg = false;
515
516	return [q, r];
517};
518
519RSAUtils.biDivide = function(x, y) {
520	return RSAUtils.biDivideModulo(x, y)[0];
521};
522
523RSAUtils.biModulo = function(x, y) {
524	return RSAUtils.biDivideModulo(x, y)[1];
525};
526
527RSAUtils.biMultiplyMod = function(x, y, m) {
528	return RSAUtils.biModulo(RSAUtils.biMultiply(x, y), m);
529};
530
531RSAUtils.biPow = function(x, y) {
532	var result = bigOne;
533	var a = x;
534	while (true) {
535		if ((y & 1) != 0) result = RSAUtils.biMultiply(result, a);
536		y >>= 1;
537		if (y == 0) break;
538		a = RSAUtils.biMultiply(a, a);
539	}
540	return result;
541};
542
543RSAUtils.biPowMod = function(x, y, m) {
544	var result = bigOne;
545	var a = x;
546	var k = y;
547	while (true) {
548		if ((k.digits[0] & 1) != 0) result = RSAUtils.biMultiplyMod(result, a, m);
549		k = RSAUtils.biShiftRight(k, 1);
550		if (k.digits[0] == 0 && RSAUtils.biHighIndex(k) == 0) break;
551		a = RSAUtils.biMultiplyMod(a, a, m);
552	}
553	return result;
554};
555
556
557$w.BarrettMu = function(m) {
558	this.modulus = RSAUtils.biCopy(m);
559	this.k = RSAUtils.biHighIndex(this.modulus) + 1;
560	var b2k = new BigInt();
561	b2k.digits[2 * this.k] = 1; // b2k = b^(2k)
562	this.mu = RSAUtils.biDivide(b2k, this.modulus);
563	this.bkplus1 = new BigInt();
564	this.bkplus1.digits[this.k + 1] = 1; // bkplus1 = b^(k+1)
565	this.modulo = BarrettMu_modulo;
566	this.multiplyMod = BarrettMu_multiplyMod;
567	this.powMod = BarrettMu_powMod;
568};
569
570function BarrettMu_modulo(x) {
571	var $dmath = RSAUtils;
572	var q1 = $dmath.biDivideByRadixPower(x, this.k - 1);
573	var q2 = $dmath.biMultiply(q1, this.mu);
574	var q3 = $dmath.biDivideByRadixPower(q2, this.k + 1);
575	var r1 = $dmath.biModuloByRadixPower(x, this.k + 1);
576	var r2term = $dmath.biMultiply(q3, this.modulus);
577	var r2 = $dmath.biModuloByRadixPower(r2term, this.k + 1);
578	var r = $dmath.biSubtract(r1, r2);
579	if (r.isNeg) {
580		r = $dmath.biAdd(r, this.bkplus1);
581	}
582	var rgtem = $dmath.biCompare(r, this.modulus) >= 0;
583	while (rgtem) {
584		r = $dmath.biSubtract(r, this.modulus);
585		rgtem = $dmath.biCompare(r, this.modulus) >= 0;
586	}
587	return r;
588}
589
590function BarrettMu_multiplyMod(x, y) {
591	/*
592	x = this.modulo(x);
593	y = this.modulo(y);
594	*/
595	var xy = RSAUtils.biMultiply(x, y);
596	return this.modulo(xy);
597}
598
599function BarrettMu_powMod(x, y) {
600	var result = new BigInt();
601	result.digits[0] = 1;
602	var a = x;
603	var k = y;
604	while (true) {
605		if ((k.digits[0] & 1) != 0) result = this.multiplyMod(result, a);
606		k = RSAUtils.biShiftRight(k, 1);
607		if (k.digits[0] == 0 && RSAUtils.biHighIndex(k) == 0) break;
608		a = this.multiplyMod(a, a);
609	}
610	return result;
611}
612
613var RSAKeyPair = function(encryptionExponent, decryptionExponent, modulus) {
614	var $dmath = RSAUtils;
615	this.e = $dmath.biFromHex(encryptionExponent);
616	this.d = $dmath.biFromHex(decryptionExponent);
617	this.m = $dmath.biFromHex(modulus);
618	// We can do two bytes per digit, so
619	// chunkSize = 2 * (number of digits in modulus - 1).
620	// Since biHighIndex returns the high index, not the number of digits, 1 has
621	// already been subtracted.
622	this.chunkSize = 2 * $dmath.biHighIndex(this.m);
623	this.radix = 16;
624	this.barrett = new $w.BarrettMu(this.m);
625};
626
627RSAUtils.getKeyPair = function(encryptionExponent, decryptionExponent, modulus) {
628	return new RSAKeyPair(encryptionExponent, decryptionExponent, modulus);
629};
630
631if(typeof $w.twoDigit === 'undefined') {
632	$w.twoDigit = function(n) {
633		return (n < 10 ? "0" : "") + String(n);
634	};
635}
636
637// Altered by Rob Saunders ([email protected]). New routine pads the
638// string after it has been converted to an array. This fixes an
639// incompatibility with Flash MX's ActionScript.
640RSAUtils.encryptedString = function(key, s) {
641	var a = [];
642	var sl = s.length;
643	var i = 0;
644	while (i < sl) {
645		a[i] = s.charCodeAt(i);
646		i++;
647	}
648
649	while (a.length % key.chunkSize != 0) {
650		a[i++] = 0;
651	}
652
653	var al = a.length;
654	var result = "";
655	var j, k, block;
656	for (i = 0; i < al; i += key.chunkSize) {
657		block = new BigInt();
658		j = 0;
659		for (k = i; k < i + key.chunkSize; ++j) {
660			block.digits[j] = a[k++];
661			block.digits[j] += a[k++] << 8;
662		}
663		var crypt = key.barrett.powMod(block, key.e);
664		var text = key.radix == 16 ? RSAUtils.biToHex(crypt) : RSAUtils.biToString(crypt, key.radix);
665		result += text + " ";
666	}
667	return result.substring(0, result.length - 1); // Remove last space.
668};
669
670RSAUtils.decryptedString = function(key, s) {
671	var blocks = s.split(" ");
672	var result = "";
673	var i, j, block;
674	for (i = 0; i < blocks.length; ++i) {
675		var bi;
676		if (key.radix == 16) {
677			bi = RSAUtils.biFromHex(blocks[i]);
678		}
679		else {
680			bi = RSAUtils.biFromString(blocks[i], key.radix);
681		}
682		block = key.barrett.powMod(bi, key.d);
683		for (j = 0; j <= RSAUtils.biHighIndex(block); ++j) {
684			result += String.fromCharCode(block.digits[j] & 255,
685			                              block.digits[j] >> 8);
686		}
687	}
688	// Remove trailing null, if any.
689	if (result.charCodeAt(result.length - 1) == 0) {
690		result = result.substring(0, result.length - 1);
691	}
692	return result;
693};
694
695RSAUtils.setMaxDigits(130);
696
697})(window);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.