summaryrefslogtreecommitdiff
path: root/frontend/beta/js/Clipperz/Crypto
authorGiulio Cesare Solaroli <giulio.cesare@clipperz.com>2011-10-02 23:56:18 (UTC)
committer Giulio Cesare Solaroli <giulio.cesare@clipperz.com>2011-10-02 23:56:18 (UTC)
commitef68436ac04da078ffdcacd7e1f785473a303d45 (patch) (unidiff)
treec403752d66a2c4775f00affd4fa8431b29c5b68c /frontend/beta/js/Clipperz/Crypto
parent597ecfbc0249d83e1b856cbd558340c01237a360 (diff)
downloadclipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.zip
clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.gz
clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.bz2
First version of the newly restructured repository
Diffstat (limited to 'frontend/beta/js/Clipperz/Crypto') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/beta/js/Clipperz/Crypto/AES.js836
-rw-r--r--frontend/beta/js/Clipperz/Crypto/Base.js1852
-rw-r--r--frontend/beta/js/Clipperz/Crypto/BigInt.js1760
-rw-r--r--frontend/beta/js/Clipperz/Crypto/BigInt_scoped.js1649
-rw-r--r--frontend/beta/js/Clipperz/Crypto/ECC.js960
-rw-r--r--frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/Curve.js461
-rw-r--r--frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js526
-rw-r--r--frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/Point.js67
-rw-r--r--frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/Value.js377
-rw-r--r--frontend/beta/js/Clipperz/Crypto/PRNG.js854
-rw-r--r--frontend/beta/js/Clipperz/Crypto/RSA.js151
-rw-r--r--frontend/beta/js/Clipperz/Crypto/SHA.js296
-rw-r--r--frontend/beta/js/Clipperz/Crypto/SRP.js331
13 files changed, 10120 insertions, 0 deletions
diff --git a/frontend/beta/js/Clipperz/Crypto/AES.js b/frontend/beta/js/Clipperz/Crypto/AES.js
new file mode 100644
index 0000000..a60df5c
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/Crypto/AES.js
@@ -0,0 +1,836 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
30 throw "Clipperz.Crypto.AES depends on Clipperz.ByteArray!";
31}
32
33 //Dependency commented to avoid a circular reference
34//try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) {
35 //throw "Clipperz.Crypto.AES depends on Clipperz.Crypto.PRNG!";
36//}
37
38if (typeof(Clipperz.Crypto.AES) == 'undefined') { Clipperz.Crypto.AES = {}; }
39
40//#############################################################################
41
42Clipperz.Crypto.AES.DeferredExecutionContext = function(args) {
43 args = args || {};
44
45 this._key = args.key;
46 this._message = args.message;
47 this._result = args.message.clone();
48 this._nonce = args.nonce;
49 this._messageLength = this._message.length();
50
51 this._messageArray = this._message.arrayValues();
52 this._resultArray = this._result.arrayValues();
53 this._nonceArray = this._nonce.arrayValues();
54
55 this._executionStep = 0;
56
57 return this;
58}
59
60Clipperz.Crypto.AES.DeferredExecutionContext.prototype = MochiKit.Base.update(null, {
61
62 'key': function() {
63 return this._key;
64 },
65
66 'message': function() {
67 return this._message;
68 },
69
70 'messageLength': function() {
71 return this._messageLength;
72 },
73
74 'result': function() {
75 return new Clipperz.ByteArray(this.resultArray());
76 },
77
78 'nonce': function() {
79 return this._nonce;
80 },
81
82 'messageArray': function() {
83 return this._messageArray;
84 },
85
86 'resultArray': function() {
87 return this._resultArray;
88 },
89
90 'nonceArray': function() {
91 return this._nonceArray;
92 },
93
94 'elaborationChunkSize': function() {
95 return Clipperz.Crypto.AES.DeferredExecution.chunkSize;
96 },
97
98 'executionStep': function() {
99 return this._executionStep;
100 },
101
102 'setExecutionStep': function(aValue) {
103 this._executionStep = aValue;
104 },
105
106 'pause': function(aValue) {
107 return MochiKit.Async.wait(Clipperz.Crypto.AES.DeferredExecution.pauseTime, aValue);
108 },
109
110 //-----------------------------------------------------------------------------
111 __syntaxFix__: "syntax fix"
112
113});
114
115//#############################################################################
116
117Clipperz.Crypto.AES.Key = function(args) {
118 args = args || {};
119
120 this._key = args.key;
121 this._keySize = args.keySize || this.key().length();
122
123 if (this.keySize() == 128/8) {
124 this._b = 176;
125 this._numberOfRounds = 10;
126 } else if (this.keySize() == 256/8) {
127 this._b = 240;
128 this._numberOfRounds = 14;
129 } else {
130 MochiKit.Logging.logError("AES unsupported key size: " + (this.keySize() * 8) + " bits");
131 throw Clipperz.Crypto.AES.exception.UnsupportedKeySize;
132 }
133
134 this._stretchedKey = null;
135
136 return this;
137}
138
139Clipperz.Crypto.AES.Key.prototype = MochiKit.Base.update(null, {
140
141 'asString': function() {
142 return "Clipperz.Crypto.AES.Key (" + this.key().toHexString() + ")";
143 },
144
145 //-----------------------------------------------------------------------------
146
147 'key': function() {
148 return this._key;
149 },
150
151 'keySize': function() {
152 return this._keySize;
153 },
154
155 'b': function() {
156 return this._b;
157 },
158
159 'numberOfRounds': function() {
160 return this._numberOfRounds;
161 },
162 //=========================================================================
163
164 'keyScheduleCore': function(aWord, aRoundConstantsIndex) {
165 varresult;
166 var sbox;
167
168 sbox = Clipperz.Crypto.AES.sbox();
169
170 result = [sbox[aWord[1]] ^ Clipperz.Crypto.AES.roundConstants()[aRoundConstantsIndex],
171 sbox[aWord[2]],
172 sbox[aWord[3]],
173 sbox[aWord[0]]];
174
175 return result;
176 },
177
178 //-----------------------------------------------------------------------------
179
180 'xorWithPreviousStretchValues': function(aKey, aWord, aPreviousWordIndex) {
181 varresult;
182 var i,c;
183
184 result = [];
185 c = 4;
186 for (i=0; i<c; i++) {
187 result[i] = aWord[i] ^ aKey.byteAtIndex(aPreviousWordIndex + i);
188 }
189
190 return result;
191 },
192
193 //-----------------------------------------------------------------------------
194
195 'sboxShakeup': function(aWord) {
196 var result;
197 var sbox;
198 var i,c;
199
200 result = [];
201 sbox = Clipperz.Crypto.AES.sbox();
202 c =4;
203 for (i=0; i<c; i++) {
204 result[i] = sbox[aWord[i]];
205 }
206
207 return result;
208 },
209
210 //-----------------------------------------------------------------------------
211
212 'stretchKey': function(aKey) {
213 varcurrentWord;
214 varkeyLength;
215 varpreviousStretchIndex;
216 var i,c;
217
218 keyLength = aKey.length();
219 previousStretchIndex = keyLength - this.keySize();
220
221 currentWord = [aKey.byteAtIndex(keyLength - 4),
222 aKey.byteAtIndex(keyLength - 3),
223 aKey.byteAtIndex(keyLength - 2),
224 aKey.byteAtIndex(keyLength - 1)];
225 currentWord = this.keyScheduleCore(currentWord, keyLength / this.keySize());
226
227 if (this.keySize() == 256/8) {
228 c = 8;
229 } else if (this.keySize() == 128/8){
230 c = 4;
231 }
232
233 for (i=0; i<c; i++) {
234 if (i == 4) {
235 //fifth streatch word
236 currentWord = this.sboxShakeup(currentWord);
237 }
238
239 currentWord = this.xorWithPreviousStretchValues(aKey, currentWord, previousStretchIndex + (i*4));
240 aKey.appendBytes(currentWord);
241 }
242
243 return aKey;
244 },
245
246 //-----------------------------------------------------------------------------
247
248 'stretchedKey': function() {
249 if (this._stretchedKey == null) {
250 var stretchedKey;
251
252 stretchedKey = this.key().clone();
253
254 while (stretchedKey.length() < this.keySize()) {
255 stretchedKey.appendByte(0);
256 }
257
258 while (stretchedKey.length() < this.b()) {
259 stretchedKey = this.stretchKey(stretchedKey);
260 }
261
262 this._stretchedKey = stretchedKey.split(0, this.b());
263 }
264
265 return this._stretchedKey;
266 },
267
268 //=========================================================================
269 __syntaxFix__: "syntax fix"
270});
271
272//#############################################################################
273
274Clipperz.Crypto.AES.State = function(args) {
275 args = args || {};
276
277 this._data = args.block;
278 this._key = args.key;
279
280 return this;
281}
282
283Clipperz.Crypto.AES.State.prototype = MochiKit.Base.update(null, {
284
285 'key': function() {
286 return this._key;
287 },
288
289 //-----------------------------------------------------------------------------
290
291 'data': function() {
292 return this._data;
293 },
294
295 'setData': function(aValue) {
296 this._data = aValue;
297 },
298
299 //=========================================================================
300
301 'addRoundKey': function(aRoundNumber) {
302 //each byte of the state is combined with the round key; each round key is derived from the cipher key using a key schedule.
303 vardata;
304 varstretchedKey;
305 varfirstStretchedKeyIndex;
306 var i,c;
307
308 data = this.data();
309 stretchedKey = this.key().stretchedKey();
310 firstStretchedKeyIndex = aRoundNumber * (128/8);
311 c = 128/8;
312 for (i=0; i<c; i++) {
313 data[i] = data[i] ^ stretchedKey.byteAtIndex(firstStretchedKeyIndex + i);
314 }
315 },
316
317 //-----------------------------------------------------------------------------
318
319 'subBytes': function() {
320 // a non-linear substitution step where each byte is replaced with another according to a lookup table.
321 var i,c;
322 vardata;
323 var sbox;
324
325 data = this.data();
326 sbox = Clipperz.Crypto.AES.sbox();
327
328 c = 16;
329 for (i=0; i<c; i++) {
330 data[i] = sbox[data[i]];
331 }
332 },
333
334 //-----------------------------------------------------------------------------
335
336 'shiftRows': function() {
337 //a transposition step where each row of the state is shifted cyclically a certain number of steps.
338 varnewValue;
339 vardata;
340 varshiftMapping;
341 vari,c;
342
343 newValue = new Array(16);
344 data = this.data();
345 shiftMapping = Clipperz.Crypto.AES.shiftRowMapping();
346 // [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
347 c = 16;
348 for (i=0; i<c; i++) {
349 newValue[i] = data[shiftMapping[i]];
350 }
351 for (i=0; i<c; i++) {
352 data[i] = newValue[i];
353 }
354 },
355
356 //-----------------------------------------------------------------------------
357/*
358 'mixColumnsWithValues': function(someValues) {
359 varresult;
360 vara;
361 var i,c;
362
363 c = 4;
364 result = [];
365 a = [];
366 for (i=0; i<c; i++) {
367 a[i] = [];
368 a[i][1] = someValues[i]
369 if ((a[i][1] & 0x80) == 0x80) {
370 a[i][2] = (a[i][1] << 1) ^ 0x11b;
371 } else {
372 a[i][2] = a[i][1] << 1;
373 }
374
375 a[i][3] = a[i][2] ^ a[i][1];
376 }
377
378 for (i=0; i<c; i++) {
379 varx;
380
381 x = Clipperz.Crypto.AES.mixColumnsMatrix()[i];
382 result[i] = a[0][x[0]] ^ a[1][x[1]] ^ a[2][x[2]] ^ a[3][x[3]];
383 }
384
385 return result;
386 },
387
388 'mixColumns': function() {
389 //a mixing operation which operates on the columns of the state, combining the four bytes in each column using a linear transformation.
390 var data;
391 var i, c;
392
393 data = this.data();
394 c = 4;
395 for(i=0; i<c; i++) {
396 varblockIndex;
397 var mixedValues;
398
399 blockIndex = i * 4;
400 mixedValues = this.mixColumnsWithValues([data[blockIndex + 0],
401 data[blockIndex + 1],
402 data[blockIndex + 2],
403 data[blockIndex + 3]]);
404 data[blockIndex + 0] = mixedValues[0];
405 data[blockIndex + 1] = mixedValues[1];
406 data[blockIndex + 2] = mixedValues[2];
407 data[blockIndex + 3] = mixedValues[3];
408 }
409 },
410*/
411
412 'mixColumns': function() {
413 //a mixing operation which operates on the columns of the state, combining the four bytes in each column using a linear transformation.
414 var data;
415 var i, c;
416 var a_1;
417 var a_2;
418
419 a_1 = new Array(4);
420 a_2 = new Array(4);
421
422 data = this.data();
423 c = 4;
424 for(i=0; i<c; i++) {
425 varblockIndex;
426 var ii, cc;
427
428 blockIndex = i * 4;
429
430 cc = 4;
431 for (ii=0; ii<cc; ii++) {
432 var value;
433
434 value = data[blockIndex + ii];
435 a_1[ii] = value;
436 a_2[ii] = (value & 0x80) ? ((value << 1) ^ 0x011b) : (value << 1);
437 }
438
439 data[blockIndex + 0] = a_2[0] ^ a_1[1] ^ a_2[1] ^ a_1[2] ^ a_1[3];
440 data[blockIndex + 1] = a_1[0] ^ a_2[1] ^ a_1[2] ^ a_2[2] ^ a_1[3];
441 data[blockIndex + 2] = a_1[0] ^ a_1[1] ^ a_2[2] ^ a_1[3] ^ a_2[3];
442 data[blockIndex + 3] = a_1[0] ^ a_2[0] ^ a_1[1] ^ a_1[2] ^ a_2[3];
443 }
444 },
445
446 //=========================================================================
447
448 'spinRound': function(aRoundNumber) {
449 this.addRoundKey(aRoundNumber);
450 this.subBytes();
451 this.shiftRows();
452 this.mixColumns();
453 },
454
455 'spinLastRound': function() {
456 this.addRoundKey(this.key().numberOfRounds() - 1);
457 this.subBytes();
458 this.shiftRows();
459 this.addRoundKey(this.key().numberOfRounds());
460 },
461
462 //=========================================================================
463
464 'encrypt': function() {
465 vari,c;
466
467 c = this.key().numberOfRounds() - 1;
468 for (i=0; i<c; i++) {
469 this.spinRound(i);
470 }
471
472 this.spinLastRound();
473 },
474
475 //=========================================================================
476 __syntaxFix__: "syntax fix"
477});
478
479//#############################################################################
480
481Clipperz.Crypto.AES.VERSION = "0.1";
482Clipperz.Crypto.AES.NAME = "Clipperz.Crypto.AES";
483
484MochiKit.Base.update(Clipperz.Crypto.AES, {
485
486 //http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-AES.html
487 //http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
488 //http://en.wikipedia.org/wiki/Rijndael_key_schedule
489 //http://en.wikipedia.org/wiki/Rijndael_S-box
490
491 '__repr__': function () {
492 return "[" + this.NAME + " " + this.VERSION + "]";
493 },
494
495 'toString': function () {
496 return this.__repr__();
497 },
498
499 //=============================================================================
500
501 '_sbox': null,
502 'sbox': function() {
503 if (Clipperz.Crypto.AES._sbox == null) {
504 Clipperz.Crypto.AES._sbox = [
5050x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
5060xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
5070xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
5080x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
5090x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
5100x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
5110xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
5120x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
5130xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
5140x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
5150xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
5160xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
5170xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
5180x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
5190xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
5200x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
521 ];
522 }
523
524 return Clipperz.Crypto.AES._sbox;
525 },
526
527 //-----------------------------------------------------------------------------
528 //
529 // 0 4 8 12 0 4 812
530 // 1 5 9 13 => 5 9 131
531 // 2 6 10 14 10 14 26
532 // 3 7 11 15 15 3 711
533 //
534 '_shiftRowMapping': null,
535 'shiftRowMapping': function() {
536 if (Clipperz.Crypto.AES._shiftRowMapping == null) {
537 Clipperz.Crypto.AES._shiftRowMapping = [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
538 }
539
540 return Clipperz.Crypto.AES._shiftRowMapping;
541 },
542
543 //-----------------------------------------------------------------------------
544
545 '_mixColumnsMatrix': null,
546 'mixColumnsMatrix': function() {
547 if (Clipperz.Crypto.AES._mixColumnsMatrix == null) {
548 Clipperz.Crypto.AES._mixColumnsMatrix = [[2, 3, 1 ,1],
549 [1, 2, 3, 1],
550 [1, 1, 2, 3],
551 [3, 1, 1, 2] ];
552 }
553
554 return Clipperz.Crypto.AES._mixColumnsMatrix;
555 },
556
557 '_roundConstants': null,
558 'roundConstants': function() {
559 if (Clipperz.Crypto.AES._roundConstants == null) {
560 Clipperz.Crypto.AES._roundConstants = [ , 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154];
561 // Clipperz.Crypto.AES._roundConstants = [ , 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a];
562 }
563
564 return Clipperz.Crypto.AES._roundConstants;
565 },
566
567 //=============================================================================
568
569 'incrementNonce': function(aNonce) {
570//Clipperz.Profile.start("Clipperz.Crypto.AES.incrementNonce");
571 var i;
572 var done;
573
574 done = false;
575 i = aNonce.length - 1;
576
577 while ((i>=0) && (done == false)) {
578 var currentByteValue;
579
580 currentByteValue = aNonce[i];
581
582 if (currentByteValue == 0xff) {
583 aNonce[i] = 0;
584 if (i>= 0) {
585 i --;
586 } else {
587 done = true;
588 }
589 } else {
590 aNonce[i] = currentByteValue + 1;
591 done = true;
592 }
593 }
594//Clipperz.Profile.stop("Clipperz.Crypto.AES.incrementNonce");
595 },
596
597 //-----------------------------------------------------------------------------
598
599 'encryptBlock': function(aKey, aBlock) {
600 varresult;
601 varstate;
602
603 state = new Clipperz.Crypto.AES.State({block:aBlock, key:aKey});
604//is(state.data(), 'before');
605 state.encrypt();
606 result = state.data();
607
608 return result;
609 },
610
611 //-----------------------------------------------------------------------------
612
613 'encryptBlocks': function(aKey, aMessage, aNonce) {
614 varresult;
615 var nonce;
616 var self;
617 varmessageIndex;
618 varmessageLength;
619 var blockSize;
620
621 self = Clipperz.Crypto.AES;
622 blockSize = 128/8;
623 messageLength = aMessage.length;
624 nonce = aNonce;
625
626 result = aMessage;
627 messageIndex = 0;
628 while (messageIndex < messageLength) {
629 var encryptedBlock;
630 var i,c;
631
632 self.incrementNonce(nonce);
633 encryptedBlock = self.encryptBlock(aKey, nonce);
634
635 if ((messageLength - messageIndex) > blockSize) {
636 c = blockSize;
637 } else {
638 c = messageLength - messageIndex;
639 }
640
641 for (i=0; i<c; i++) {
642 result[messageIndex + i] = result[messageIndex + i] ^ encryptedBlock[i];
643 }
644
645 messageIndex += blockSize;
646 }
647
648 return result;
649 },
650
651 //-----------------------------------------------------------------------------
652
653 'encrypt': function(aKey, someData, aNonce) {
654 var result;
655 var nonce;
656 varencryptedData;
657 var key;
658
659 key = new Clipperz.Crypto.AES.Key({key:aKey});
660 nonce = aNonce ? aNonce.clone() : Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8);
661
662 encryptedData = Clipperz.Crypto.AES.encryptBlocks(key, someData.arrayValues(), nonce.arrayValues());
663
664 result = nonce.appendBytes(encryptedData);
665
666 return result;
667 },
668
669 //-----------------------------------------------------------------------------
670
671 'decrypt': function(aKey, someData) {
672 var result;
673 var nonce;
674 var encryptedData;
675 var decryptedData;
676 vardataIterator;
677 var key;
678
679 key = new Clipperz.Crypto.AES.Key({key:aKey});
680
681 encryptedData = someData.arrayValues();
682 nonce = encryptedData.slice(0, (128/8));
683 encryptedData = encryptedData.slice(128/8);
684 decryptedData = Clipperz.Crypto.AES.encryptBlocks(key, encryptedData, nonce);
685
686 result = new Clipperz.ByteArray(decryptedData);
687
688 return result;
689 },
690
691 //=============================================================================
692
693 'deferredEncryptExecutionChunk': function(anExecutionContext) {
694 varresult;
695 var nonce;
696 var self;
697 varmessageIndex;
698 varmessageLength;
699 var blockSize;
700 var executionLimit;
701
702 self = Clipperz.Crypto.AES;
703 blockSize = 128/8;
704 messageLength = anExecutionContext.messageArray().length;
705 nonce = anExecutionContext.nonceArray();
706 result = anExecutionContext.resultArray();
707
708 messageIndex = anExecutionContext.executionStep();
709 executionLimit = messageIndex + anExecutionContext.elaborationChunkSize();
710 executionLimit = Math.min(executionLimit, messageLength);
711
712 while (messageIndex < executionLimit) {
713 var encryptedBlock;
714 var i,c;
715
716 self.incrementNonce(nonce);
717 encryptedBlock = self.encryptBlock(anExecutionContext.key(), nonce);
718
719 if ((executionLimit - messageIndex) > blockSize) {
720 c = blockSize;
721 } else {
722 c = executionLimit - messageIndex;
723 }
724
725 for (i=0; i<c; i++) {
726 result[messageIndex + i] = result[messageIndex + i] ^ encryptedBlock[i];
727 }
728
729 messageIndex += blockSize;
730 }
731 anExecutionContext.setExecutionStep(messageIndex);
732
733 return anExecutionContext;
734 },
735
736 //-----------------------------------------------------------------------------
737
738 'deferredEncryptBlocks': function(anExecutionContext) {
739 vardeferredResult;
740 varmessageSize;
741 var i,c;
742 var now;
743
744 messageSize = anExecutionContext.messageLength();
745
746 deferredResult = new MochiKit.Async.Deferred();
747//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncryptBlocks - START: " + res); return res;});
748 // deferredResult.addCallback(MochiKit.Base.method(anExecutionContext, 'pause'));
749
750 c = Math.ceil(messageSize / anExecutionContext.elaborationChunkSize());
751 for (i=0; i<c; i++) {
752//deferredResult.addBoth(function(res) {now = new Date(); return res;});
753//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncryptBlocks - : (" + i + ") - " + res); return res;});
754 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptExecutionChunk);
755//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("[" + (new Date() - now) + "]Clipperz.Crypto.AES.deferredEncryptBlocks"); return res;});
756//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncryptBlocks - : (" + i + ") -- " + res); return res;});
757 deferredResult.addCallback(MochiKit.Base.method(anExecutionContext, 'pause'));
758//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncryptBlocks - : (" + i + ") --- " + res); return res;});
759 }
760//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncryptBlocks - END: " + res); return res;});
761
762 deferredResult.callback(anExecutionContext);
763
764 return deferredResult;
765 },
766
767 //-----------------------------------------------------------------------------
768
769 'deferredEncrypt': function(aKey, someData, aNonce) {
770 var deferredResult;
771 varexecutionContext;
772 var result;
773 var nonce;
774 var key;
775
776 key = new Clipperz.Crypto.AES.Key({key:aKey});
777 nonce = aNonce ? aNonce.clone() : Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8);
778
779 executionContext = new Clipperz.Crypto.AES.DeferredExecutionContext({key:key, message:someData, nonce:nonce});
780
781 deferredResult = new MochiKit.Async.Deferred();
782//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncrypt - 1: " + res); return res;});
783 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptBlocks);
784//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncrypt - 2: " + res); return res;});
785 deferredResult.addCallback(function(anExecutionContext) {
786 var result;
787
788 result = anExecutionContext.nonce().clone();
789 result.appendBytes(anExecutionContext.resultArray());
790
791 return result;
792 });
793//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncrypt - 3: " + res); return res;});
794 deferredResult.callback(executionContext)
795
796 return deferredResult;
797 },
798
799 //-----------------------------------------------------------------------------
800
801 'deferredDecrypt': function(aKey, someData) {
802 var deferredResult
803 var nonce;
804 var message;
805 var key;
806
807 key = new Clipperz.Crypto.AES.Key({key:aKey});
808 nonce = someData.split(0, (128/8));
809 message = someData.split(128/8);
810 executionContext = new Clipperz.Crypto.AES.DeferredExecutionContext({key:key, message:message, nonce:nonce});
811
812 deferredResult = new MochiKit.Async.Deferred();
813 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptBlocks);
814 deferredResult.addCallback(function(anExecutionContext) {
815 return anExecutionContext.result();
816 });
817 deferredResult.callback(executionContext);
818
819 return deferredResult;
820 },
821
822 //-----------------------------------------------------------------------------
823 __syntaxFix__: "syntax fix"
824
825});
826
827//#############################################################################
828
829Clipperz.Crypto.AES.DeferredExecution = {
830 'chunkSize': 4096, // 1024 4096 8192 1638432768;
831 'pauseTime': 0.2
832}
833
834Clipperz.Crypto.AES.exception = {
835 'UnsupportedKeySize': new MochiKit.Base.NamedError("Clipperz.Crypto.AES.exception.UnsupportedKeySize")
836};
diff --git a/frontend/beta/js/Clipperz/Crypto/Base.js b/frontend/beta/js/Clipperz/Crypto/Base.js
new file mode 100644
index 0000000..b69dcc8
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/Crypto/Base.js
@@ -0,0 +1,1852 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29try { if (typeof(Clipperz.Base) == 'undefined') { throw ""; }} catch (e) {
30 throw "Clipperz.Crypto.Base depends on Clipperz.Base!";
31}
32
33if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
34if (typeof(Clipperz.Crypto.Base) == 'undefined') { Clipperz.Crypto.Base = {}; }
35
36Clipperz.Crypto.Base.VERSION = "0.1";
37Clipperz.Crypto.Base.NAME = "Clipperz.Crypto.Base";
38
39//#############################################################################
40 //Downloaded on March 30, 2006 from http://anmar.eu.org/projects/jssha2/files/jssha2-0.3.zip (jsSha2/sha256.js)
41//#############################################################################
42
43/* A JavaScript implementation of the Secure Hash Algorithm, SHA-256
44 * Version 0.3 Copyright Angel Marin 2003-2004 - http://anmar.eu.org/
45 * Distributed under the BSD License
46 * Some bits taken from Paul Johnston's SHA-1 implementation
47 */
48var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
49function safe_add (x, y) {
50 var lsw = (x & 0xFFFF) + (y & 0xFFFF);
51 var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
52 return (msw << 16) | (lsw & 0xFFFF);
53}
54function S (X, n) {return ( X >>> n ) | (X << (32 - n));}
55function R (X, n) {return ( X >>> n );}
56function Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
57function Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
58function Sigma0256(x) {return (S(x, 2) ^ S(x, 13) ^ S(x, 22));}
59function Sigma1256(x) {return (S(x, 6) ^ S(x, 11) ^ S(x, 25));}
60function Gamma0256(x) {return (S(x, 7) ^ S(x, 18) ^ R(x, 3));}
61function Gamma1256(x) {return (S(x, 17) ^ S(x, 19) ^ R(x, 10));}
62function core_sha256 (m, l) {
63 var K = new Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2);
64 var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
65 var W = new Array(64);
66 var a, b, c, d, e, f, g, h, i, j;
67 var T1, T2;
68 /* append padding */
69 m[l >> 5] |= 0x80 << (24 - l % 32);
70 m[((l + 64 >> 9) << 4) + 15] = l;
71 for ( var i = 0; i<m.length; i+=16 ) {
72 a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7];
73 for ( var j = 0; j<64; j++) {
74 if (j < 16) W[j] = m[j + i];
75 else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
76 T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
77 T2 = safe_add(Sigma0256(a), Maj(a, b, c));
78 h = g; g = f; f = e; e = safe_add(d, T1); d = c; c = b; b = a; a = safe_add(T1, T2);
79 }
80 HASH[0] = safe_add(a, HASH[0]); HASH[1] = safe_add(b, HASH[1]); HASH[2] = safe_add(c, HASH[2]); HASH[3] = safe_add(d, HASH[3]); HASH[4] = safe_add(e, HASH[4]); HASH[5] = safe_add(f, HASH[5]); HASH[6] = safe_add(g, HASH[6]); HASH[7] = safe_add(h, HASH[7]);
81 }
82 return HASH;
83}
84function str2binb (str) {
85 var bin = Array();
86 var mask = (1 << chrsz) - 1;
87 for(var i = 0; i < str.length * chrsz; i += chrsz)
88 bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32);
89 return bin;
90}
91function binb2hex (binarray) {
92 var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
93 var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
94 var str = "";
95 for (var i = 0; i < binarray.length * 4; i++) {
96 str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF);
97 }
98 return str;
99}
100function hex_sha256(s){return binb2hex(core_sha256(str2binb(s),s.length * chrsz));}
101
102
103
104//#############################################################################
105 //Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (entropy.js)
106//#############################################################################
107
108 // Entropy collection utilities
109
110 /*Start by declaring static storage and initialise
111 the entropy vector from the time we come through
112 here. */
113
114 var entropyData = new Array(); // Collected entropy data
115 var edlen = 0; // Keyboard array data length
116
117 addEntropyTime(); // Start entropy collection with page load time
118 ce(); // Roll milliseconds into initial entropy
119
120 //Add a byte to the entropy vector
121
122 function addEntropyByte(b) {
123 entropyData[edlen++] = b;
124 }
125
126 /*Capture entropy. When the user presses a key or performs
127 various other events for which we can request
128 notification, add the time in 255ths of a second to the
129 entropyData array. The name of the function is short
130 so it doesn't bloat the form object declarations in
131 which it appears in various "onXXX" events. */
132
133 function ce() {
134 addEntropyByte(Math.floor((((new Date).getMilliseconds()) * 255) / 999));
135 }
136
137 //Add a 32 bit quantity to the entropy vector
138
139 function addEntropy32(w) {
140 var i;
141
142 for (i = 0; i < 4; i++) {
143 addEntropyByte(w & 0xFF);
144 w >>= 8;
145 }
146 }
147
148 /*Add the current time and date (milliseconds since the epoch,
149 truncated to 32 bits) to the entropy vector. */
150
151 function addEntropyTime() {
152 addEntropy32((new Date()).getTime());
153 }
154
155 /* Start collection of entropy from mouse movements. The
156 argument specifies the number of entropy items to be
157 obtained from mouse motion, after which mouse motion
158 will be ignored. Note that you can re-enable mouse
159 motion collection at any time if not already underway. */
160
161 var mouseMotionCollect = 0;
162 var oldMoveHandler; // For saving and restoring mouse move handler in IE4
163
164 function mouseMotionEntropy(maxsamp) {
165 if (mouseMotionCollect <= 0) {
166 mouseMotionCollect = maxsamp;
167 if ((document.implementation.hasFeature("Events", "2.0")) &&
168 document.addEventListener) {
169 // Browser supports Document Object Model (DOM) 2 events
170 document.addEventListener("mousemove", mouseMoveEntropy, false);
171 } else {
172 if (document.attachEvent) {
173 // Internet Explorer 5 and above event model
174 document.attachEvent("onmousemove", mouseMoveEntropy);
175 } else {
176 //Internet Explorer 4 event model
177 oldMoveHandler = document.onmousemove;
178 document.onmousemove = mouseMoveEntropy;
179 }
180 }
181//dump("Mouse enable", mouseMotionCollect);
182 }
183 }
184
185 /*Collect entropy from mouse motion events. Note that
186 this is craftily coded to work with either DOM2 or Internet
187 Explorer style events. Note that we don't use every successive
188 mouse movement event. Instead, we XOR the three bytes collected
189 from the mouse and use that to determine how many subsequent
190 mouse movements we ignore before capturing the next one. */
191
192 var mouseEntropyTime = 0; // Delay counter for mouse entropy collection
193
194 function mouseMoveEntropy(e) {
195 if (!e) {
196 e = window.event; // Internet Explorer event model
197 }
198 if (mouseMotionCollect > 0) {
199 if (mouseEntropyTime-- <= 0) {
200 addEntropyByte(e.screenX & 0xFF);
201 addEntropyByte(e.screenY & 0xFF);
202 ce();
203 mouseMotionCollect--;
204 mouseEntropyTime = (entropyData[edlen - 3] ^ entropyData[edlen - 2] ^
205 entropyData[edlen - 1]) % 19;
206//dump("Mouse Move", byteArrayToHex(entropyData.slice(-3)));
207 }
208 if (mouseMotionCollect <= 0) {
209 if (document.removeEventListener) {
210 document.removeEventListener("mousemove", mouseMoveEntropy, false);
211 } else if (document.detachEvent) {
212 document.detachEvent("onmousemove", mouseMoveEntropy);
213 } else {
214 document.onmousemove = oldMoveHandler;
215 }
216//dump("Spung!", 0);
217 }
218 }
219 }
220
221 /*Compute a 32 byte key value from the entropy vector.
222 We compute the value by taking the MD5 sum of the even
223 and odd bytes respectively of the entropy vector, then
224 concatenating the two MD5 sums. */
225
226 function keyFromEntropy() {
227 var i, k = new Array(32);
228
229 if (edlen == 0) {
230 alert("Blooie! Entropy vector void at call to keyFromEntropy.");
231 }
232//dump("Entropy bytes", edlen);
233
234 md5_init();
235 for (i = 0; i < edlen; i += 2) {
236 md5_update(entropyData[i]);
237 }
238 md5_finish();
239 for (i = 0; i < 16; i++) {
240 k[i] = digestBits[i];
241 }
242
243 md5_init();
244 for (i = 1; i < edlen; i += 2) {
245 md5_update(entropyData[i]);
246 }
247 md5_finish();
248 for (i = 0; i < 16; i++) {
249 k[i + 16] = digestBits[i];
250 }
251
252//dump("keyFromEntropy", byteArrayToHex(k));
253 return k;
254 }
255
256//#############################################################################
257 //Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (aesprng.js)
258//#############################################################################
259
260
261 // AES based pseudorandom number generator
262
263 /* Constructor. Called with an array of 32 byte (0-255) values
264 containing the initial seed. */
265
266 function AESprng(seed) {
267 this.key = new Array();
268 this.key = seed;
269 this.itext = hexToByteArray("9F489613248148F9C27945C6AE62EECA3E3367BB14064E4E6DC67A9F28AB3BD1");
270 this.nbytes = 0; // Bytes left in buffer
271
272 this.next = AESprng_next;
273 this.nextbits = AESprng_nextbits;
274 this.nextInt = AESprng_nextInt;
275 this.round = AESprng_round;
276
277 /* Encrypt the initial text with the seed key
278 three times, feeding the output of the encryption
279 back into the key for the next round. */
280
281 bsb = blockSizeInBits;
282 blockSizeInBits = 256;
283 var i, ct;
284 for (i = 0; i < 3; i++) {
285 this.key = rijndaelEncrypt(this.itext, this.key, "ECB");
286 }
287
288 /* Now make between one and four additional
289 key-feedback rounds, with the number determined
290 by bits from the result of the first three
291 rounds. */
292
293 var n = 1 + (this.key[3] & 2) + (this.key[9] & 1);
294 for (i = 0; i < n; i++) {
295 this.key = rijndaelEncrypt(this.itext, this.key, "ECB");
296 }
297 blockSizeInBits = bsb;
298 }
299
300 function AESprng_round() {
301 bsb = blockSizeInBits;
302 blockSizeInBits = 256;
303 this.key = rijndaelEncrypt(this.itext, this.key, "ECB");
304 this.nbytes = 32;
305 blockSizeInBits = bsb;
306 }
307
308 //Return next byte from the generator
309
310 function AESprng_next() {
311 if (this.nbytes <= 0) {
312 this.round();
313 }
314 return(this.key[--this.nbytes]);
315 }
316
317 //Return n bit integer value (up to maximum integer size)
318
319 function AESprng_nextbits(n) {
320 var i, w = 0, nbytes = Math.floor((n + 7) / 8);
321
322 for (i = 0; i < nbytes; i++) {
323 w = (w << 8) | this.next();
324 }
325 return w & ((1 << n) - 1);
326 }
327
328 // Return integer between 0 and n inclusive
329
330 function AESprng_nextInt(n) {
331 var p = 1, nb = 0;
332
333 // Determine smallest p, 2^p > n
334 // nb = log_2 p
335
336 while (n >= p) {
337 p <<= 1;
338 nb++;
339 }
340 p--;
341
342 /* Generate values from 0 through n by first generating
343 values v from 0 to (2^p)-1, then discarding any results v > n.
344 For the rationale behind this (and why taking
345 values mod (n + 1) is biased toward smaller values, see
346 Ferguson and Schneier, "Practical Cryptography",
347 ISBN 0-471-22357-3, section 10.8). */
348
349 while (true) {
350 var v = this.nextbits(nb) & p;
351
352 if (v <= n) {
353 return v;
354 }
355 }
356 }
357
358//#############################################################################
359 //Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (md5.js)
360//#############################################################################
361
362/*
363 * md5.jvs 1.0b 27/06/96
364 *
365 * Javascript implementation of the RSA Data Security, Inc. MD5
366 * Message-Digest Algorithm.
367 *
368 * Copyright (c) 1996 Henri Torgemane. All Rights Reserved.
369 *
370 * Permission to use, copy, modify, and distribute this software
371 * and its documentation for any purposes and without
372 * fee is hereby granted provided that this copyright notice
373 * appears in all copies.
374 *
375 * Of course, this soft is provided "as is" without express or implied
376 * warranty of any kind.
377
378 This version contains some trivial reformatting modifications
379 by John Walker.
380
381 */
382
383function array(n) {
384 for (i = 0; i < n; i++) {
385 this[i] = 0;
386 }
387 this.length = n;
388}
389
390/* Some basic logical functions had to be rewritten because of a bug in
391 * Javascript.. Just try to compute 0xffffffff >> 4 with it..
392 * Of course, these functions are slower than the original would be, but
393 * at least, they work!
394 */
395
396function integer(n) {
397 return n % (0xffffffff + 1);
398}
399
400function shr(a, b) {
401 a = integer(a);
402 b = integer(b);
403 if (a - 0x80000000 >= 0) {
404 a = a % 0x80000000;
405 a >>= b;
406 a += 0x40000000 >> (b - 1);
407 } else {
408 a >>= b;
409 }
410 return a;
411}
412
413function shl1(a) {
414 a = a % 0x80000000;
415 if (a & 0x40000000 == 0x40000000) {
416 a -= 0x40000000;
417 a *= 2;
418 a += 0x80000000;
419 } else {
420 a *= 2;
421 }
422 return a;
423}
424
425function shl(a, b) {
426 a = integer(a);
427 b = integer(b);
428 for (var i = 0; i < b; i++) {
429 a = shl1(a);
430 }
431 return a;
432}
433
434function and(a, b) {
435 a = integer(a);
436 b = integer(b);
437 var t1 = a - 0x80000000;
438 var t2 = b - 0x80000000;
439 if (t1 >= 0) {
440 if (t2 >= 0) {
441 return ((t1 & t2) + 0x80000000);
442 } else {
443 return (t1 & b);
444 }
445 } else {
446 if (t2 >= 0) {
447 return (a & t2);
448 } else {
449 return (a & b);
450 }
451 }
452}
453
454function or(a, b) {
455 a = integer(a);
456 b = integer(b);
457 var t1 = a - 0x80000000;
458 var t2 = b - 0x80000000;
459 if (t1 >= 0) {
460 if (t2 >= 0) {
461 return ((t1 | t2) + 0x80000000);
462 } else {
463 return ((t1 | b) + 0x80000000);
464 }
465 } else {
466 if (t2 >= 0) {
467 return ((a | t2) + 0x80000000);
468 } else {
469 return (a | b);
470 }
471 }
472}
473
474function xor(a, b) {
475 a = integer(a);
476 b = integer(b);
477 var t1 = a - 0x80000000;
478 var t2 = b - 0x80000000;
479 if (t1 >= 0) {
480 if (t2 >= 0) {
481 return (t1 ^ t2);
482 } else {
483 return ((t1 ^ b) + 0x80000000);
484 }
485 } else {
486 if (t2 >= 0) {
487 return ((a ^ t2) + 0x80000000);
488 } else {
489 return (a ^ b);
490 }
491 }
492}
493
494function not(a) {
495 a = integer(a);
496 return 0xffffffff - a;
497}
498
499/* Here begin the real algorithm */
500
501var state = new array(4);
502var count = new array(2);
503 count[0] = 0;
504 count[1] = 0;
505var buffer = new array(64);
506var transformBuffer = new array(16);
507var digestBits = new array(16);
508
509var S11 = 7;
510var S12 = 12;
511var S13 = 17;
512var S14 = 22;
513var S21 = 5;
514var S22 = 9;
515var S23 = 14;
516var S24 = 20;
517var S31 = 4;
518var S32 = 11;
519var S33 = 16;
520var S34 = 23;
521var S41 = 6;
522var S42 = 10;
523var S43 = 15;
524var S44 = 21;
525
526function F(x, y, z) {
527 return or(and(x, y), and(not(x), z));
528}
529
530function G(x, y, z) {
531 return or(and(x, z), and(y, not(z)));
532}
533
534function H(x, y, z) {
535 return xor(xor(x, y), z);
536}
537
538function I(x, y, z) {
539 return xor(y ,or(x , not(z)));
540}
541
542function rotateLeft(a, n) {
543 return or(shl(a, n), (shr(a, (32 - n))));
544}
545
546function FF(a, b, c, d, x, s, ac) {
547 a = a + F(b, c, d) + x + ac;
548 a = rotateLeft(a, s);
549 a = a + b;
550 return a;
551}
552
553function GG(a, b, c, d, x, s, ac) {
554 a = a + G(b, c, d) + x + ac;
555 a = rotateLeft(a, s);
556 a = a + b;
557 return a;
558}
559
560function HH(a, b, c, d, x, s, ac) {
561 a = a + H(b, c, d) + x + ac;
562 a = rotateLeft(a, s);
563 a = a + b;
564 return a;
565}
566
567function II(a, b, c, d, x, s, ac) {
568 a = a + I(b, c, d) + x + ac;
569 a = rotateLeft(a, s);
570 a = a + b;
571 return a;
572}
573
574function transform(buf, offset) {
575 var a = 0, b = 0, c = 0, d = 0;
576 var x = transformBuffer;
577
578 a = state[0];
579 b = state[1];
580 c = state[2];
581 d = state[3];
582
583 for (i = 0; i < 16; i++) {
584 x[i] = and(buf[i * 4 + offset], 0xFF);
585 for (j = 1; j < 4; j++) {
586 x[i] += shl(and(buf[i * 4 + j + offset] ,0xFF), j * 8);
587 }
588 }
589
590 /* Round 1 */
591 a = FF( a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
592 d = FF( d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
593 c = FF( c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
594 b = FF( b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
595 a = FF( a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
596 d = FF( d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
597 c = FF( c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
598 b = FF( b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
599 a = FF( a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
600 d = FF( d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
601 c = FF( c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
602 b = FF( b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
603 a = FF( a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
604 d = FF( d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
605 c = FF( c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
606 b = FF( b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
607
608 /* Round 2 */
609 a = GG( a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
610 d = GG( d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
611 c = GG( c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
612 b = GG( b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
613 a = GG( a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
614 d = GG( d, a, b, c, x[10], S22, 0x2441453); /* 22 */
615 c = GG( c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
616 b = GG( b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
617 a = GG( a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
618 d = GG( d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
619 c = GG( c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
620 b = GG( b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
621 a = GG( a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
622 d = GG( d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
623 c = GG( c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
624 b = GG( b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
625
626 /* Round 3 */
627 a = HH( a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
628 d = HH( d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
629 c = HH( c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
630 b = HH( b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
631 a = HH( a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
632 d = HH( d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
633 c = HH( c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
634 b = HH( b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
635 a = HH( a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
636 d = HH( d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
637 c = HH( c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
638 b = HH( b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
639 a = HH( a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
640 d = HH( d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
641 c = HH( c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
642 b = HH( b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
643
644 /* Round 4 */
645 a = II( a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
646 d = II( d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
647 c = II( c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
648 b = II( b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
649 a = II( a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
650 d = II( d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
651 c = II( c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
652 b = II( b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
653 a = II( a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
654 d = II( d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
655 c = II( c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
656 b = II( b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
657 a = II( a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
658 d = II( d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
659 c = II( c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
660 b = II( b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
661
662 state[0] += a;
663 state[1] += b;
664 state[2] += c;
665 state[3] += d;
666
667}
668
669function md5_init() {
670 count[0] = count[1] = 0;
671 state[0] = 0x67452301;
672 state[1] = 0xefcdab89;
673 state[2] = 0x98badcfe;
674 state[3] = 0x10325476;
675 for (i = 0; i < digestBits.length; i++) {
676 digestBits[i] = 0;
677 }
678}
679
680function md5_update(b) {
681 var index, i;
682
683 index = and(shr(count[0],3) , 0x3F);
684 if (count[0] < 0xFFFFFFFF - 7) {
685 count[0] += 8;
686 } else {
687 count[1]++;
688 count[0] -= 0xFFFFFFFF + 1;
689 count[0] += 8;
690 }
691 buffer[index] = and(b, 0xff);
692 if (index >= 63) {
693 transform(buffer, 0);
694 }
695}
696
697function md5_finish() {
698 var bits = new array(8);
699 var padding;
700 var i = 0, index = 0, padLen = 0;
701
702 for (i = 0; i < 4; i++) {
703 bits[i] = and(shr(count[0], (i * 8)), 0xFF);
704 }
705 for (i = 0; i < 4; i++) {
706 bits[i + 4] = and(shr(count[1], (i * 8)), 0xFF);
707 }
708 index = and(shr(count[0], 3), 0x3F);
709 padLen = (index < 56) ? (56 - index) : (120 - index);
710 padding = new array(64);
711 padding[0] = 0x80;
712 for (i = 0; i < padLen; i++) {
713 md5_update(padding[i]);
714 }
715 for (i = 0; i < 8; i++) {
716 md5_update(bits[i]);
717 }
718
719 for (i = 0; i < 4; i++) {
720 for (j = 0; j < 4; j++) {
721 digestBits[i * 4 + j] = and(shr(state[i], (j * 8)) , 0xFF);
722 }
723 }
724}
725
726/* End of the MD5 algorithm */
727
728//#############################################################################
729 //Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (aes.js)
730//#############################################################################
731
732
733/* rijndael.js Rijndael Reference Implementation
734
735 This is a modified version of the software described below,
736 produced in September 2003 by John Walker for use in the
737 JavsScrypt browser-based encryption package. The principal
738 changes are replacing the original getRandomBytes function with
739 one which calls our pseudorandom generator (which must
740 be instantiated and seeded before the first call on getRandomBytes),
741 and changing keySizeInBits to 256. Some code not required by the
742 JavsScrypt application has been commented out. Please see
743 http://www.fourmilab.ch/javascrypt/ for further information on
744 JavaScrypt.
745
746 The following is the original copyright and application
747 information.
748
749 Copyright (c) 2001 Fritz Schneider
750
751 This software is provided as-is, without express or implied warranty.
752 Permission to use, copy, modify, distribute or sell this software, with or
753 without fee, for any purpose and by any individual or organization, is hereby
754 granted, provided that the above copyright notice and this paragraph appear
755 in all copies. Distribution as a part of an application or binary must
756 include the above copyright notice in the documentation and/or other materials
757 provided with the application or distribution.
758
759 As the above disclaimer notes, you are free to use this code however you
760 want. However, I would request that you send me an email
761 (fritz /at/ cs /dot/ ucsd /dot/ edu) to say hi if you find this code useful
762 or instructional. Seeing that people are using the code acts as
763 encouragement for me to continue development. If you *really* want to thank
764 me you can buy the book I wrote with Thomas Powell, _JavaScript:
765 _The_Complete_Reference_ :)
766
767 This code is an UNOPTIMIZED REFERENCE implementation of Rijndael.
768 If there is sufficient interest I can write an optimized (word-based,
769 table-driven) version, although you might want to consider using a
770 compiled language if speed is critical to your application. As it stands,
771 one run of the monte carlo test (10,000 encryptions) can take up to
772 several minutes, depending upon your processor. You shouldn't expect more
773 than a few kilobytes per second in throughput.
774
775 Also note that there is very little error checking in these functions.
776 Doing proper error checking is always a good idea, but the ideal
777 implementation (using the instanceof operator and exceptions) requires
778 IE5+/NS6+, and I've chosen to implement this code so that it is compatible
779 with IE4/NS4.
780
781 And finally, because JavaScript doesn't have an explicit byte/char data
782 type (although JavaScript 2.0 most likely will), when I refer to "byte"
783 in this code I generally mean "32 bit integer with value in the interval
784 [0,255]" which I treat as a byte.
785
786 See http://www-cse.ucsd.edu/~fritz/rijndael.html for more documentation
787 of the (very simple) API provided by this code.
788
789 Fritz Schneider
790 fritz at cs.ucsd.edu
791
792*/
793
794
795// Rijndael parameters -- Valid values are 128, 192, or 256
796
797var keySizeInBits = 256;
798var blockSizeInBits = 128;
799
800//
801// Note: in the following code the two dimensional arrays are indexed as
802// you would probably expect, as array[row][column]. The state arrays
803// are 2d arrays of the form state[4][Nb].
804
805
806// The number of rounds for the cipher, indexed by [Nk][Nb]
807var roundsArray = [ ,,,,[,,,,10,, 12,, 14],,
808 [,,,,12,, 12,, 14],,
809 [,,,,14,, 14,, 14] ];
810
811// The number of bytes to shift by in shiftRow, indexed by [Nb][row]
812var shiftOffsets = [ ,,,,[,1, 2, 3],,[,1, 2, 3],,[,1, 3, 4] ];
813
814// The round constants used in subkey expansion
815var Rcon = [
8160x01, 0x02, 0x04, 0x08, 0x10, 0x20,
8170x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
8180xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc,
8190x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4,
8200xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 ];
821
822// Precomputed lookup table for the SBox
823var SBox = [
824 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171,
825118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164,
826114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113,
827216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226,
828235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214,
829179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203,
830190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69,
831249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245,
832188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68,
83323, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42,
834144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73,
835 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109,
836141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37,
837 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
838181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225,
839248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
840140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187,
841 22 ];
842
843// Precomputed lookup table for the inverse SBox
844var SBoxInverse = [
845 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215,
846251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222,
847233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66,
848250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73,
849109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92,
850204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21,
851 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247,
852228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2,
853193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220,
854234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173,
855 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29,
856 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75,
857198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168,
858 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81,
859127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160,
860224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
861 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12,
862125 ];
863
864// This method circularly shifts the array left by the number of elements
865// given in its parameter. It returns the resulting array and is used for
866// the ShiftRow step. Note that shift() and push() could be used for a more
867// elegant solution, but they require IE5.5+, so I chose to do it manually.
868
869function cyclicShiftLeft(theArray, positions) {
870 var temp = theArray.slice(0, positions);
871 theArray = theArray.slice(positions).concat(temp);
872 return theArray;
873}
874
875// Cipher parameters ... do not change these
876var Nk = keySizeInBits / 32;
877var Nb = blockSizeInBits / 32;
878var Nr = roundsArray[Nk][Nb];
879
880// Multiplies the element "poly" of GF(2^8) by x. See the Rijndael spec.
881
882function xtime(poly) {
883 poly <<= 1;
884 return ((poly & 0x100) ? (poly ^ 0x11B) : (poly));
885}
886
887// Multiplies the two elements of GF(2^8) together and returns the result.
888// See the Rijndael spec, but should be straightforward: for each power of
889// the indeterminant that has a 1 coefficient in x, add y times that power
890// to the result. x and y should be bytes representing elements of GF(2^8)
891
892function mult_GF256(x, y) {
893 var bit, result = 0;
894
895 for (bit = 1; bit < 256; bit *= 2, y = xtime(y)) {
896 if (x & bit)
897 result ^= y;
898 }
899 return result;
900}
901
902// Performs the substitution step of the cipher. State is the 2d array of
903// state information (see spec) and direction is string indicating whether
904// we are performing the forward substitution ("encrypt") or inverse
905// substitution (anything else)
906
907function byteSub(state, direction) {
908 var S;
909 if (direction == "encrypt") // Point S to the SBox we're using
910 S = SBox;
911 else
912 S = SBoxInverse;
913 for (var i = 0; i < 4; i++) // Substitute for every byte in state
914 for (var j = 0; j < Nb; j++)
915 state[i][j] = S[state[i][j]];
916}
917
918// Performs the row shifting step of the cipher.
919
920function shiftRow(state, direction) {
921 for (var i=1; i<4; i++) // Row 0 never shifts
922 if (direction == "encrypt")
923 state[i] = cyclicShiftLeft(state[i], shiftOffsets[Nb][i]);
924 else
925 state[i] = cyclicShiftLeft(state[i], Nb - shiftOffsets[Nb][i]);
926
927}
928
929// Performs the column mixing step of the cipher. Most of these steps can
930// be combined into table lookups on 32bit values (at least for encryption)
931// to greatly increase the speed.
932
933function mixColumn(state, direction) {
934 var b = []; // Result of matrix multiplications
935 for (var j = 0; j < Nb; j++) { // Go through each column...
936 for (var i = 0; i < 4; i++) { // and for each row in the column...
937 if (direction == "encrypt")
938 b[i] = mult_GF256(state[i][j], 2) ^ // perform mixing
939 mult_GF256(state[(i+1)%4][j], 3) ^
940 state[(i+2)%4][j] ^
941 state[(i+3)%4][j];
942 else
943 b[i] = mult_GF256(state[i][j], 0xE) ^
944 mult_GF256(state[(i+1)%4][j], 0xB) ^
945 mult_GF256(state[(i+2)%4][j], 0xD) ^
946 mult_GF256(state[(i+3)%4][j], 9);
947 }
948 for (var i = 0; i < 4; i++) // Place result back into column
949 state[i][j] = b[i];
950 }
951}
952
953// Adds the current round key to the state information. Straightforward.
954
955function addRoundKey(state, roundKey) {
956 for (var j = 0; j < Nb; j++) { // Step through columns...
957 state[0][j] ^= (roundKey[j] & 0xFF); // and XOR
958 state[1][j] ^= ((roundKey[j]>>8) & 0xFF);
959 state[2][j] ^= ((roundKey[j]>>16) & 0xFF);
960 state[3][j] ^= ((roundKey[j]>>24) & 0xFF);
961 }
962}
963
964// This function creates the expanded key from the input (128/192/256-bit)
965// key. The parameter key is an array of bytes holding the value of the key.
966// The returned value is an array whose elements are the 32-bit words that
967// make up the expanded key.
968
969function keyExpansion(key) {
970 var expandedKey = new Array();
971 var temp;
972
973 // in case the key size or parameters were changed...
974 Nk = keySizeInBits / 32;
975 Nb = blockSizeInBits / 32;
976 Nr = roundsArray[Nk][Nb];
977
978 for (var j=0; j < Nk; j++) // Fill in input key first
979 expandedKey[j] =
980 (key[4*j]) | (key[4*j+1]<<8) | (key[4*j+2]<<16) | (key[4*j+3]<<24);
981
982 // Now walk down the rest of the array filling in expanded key bytes as
983 // per Rijndael's spec
984 for (j = Nk; j < Nb * (Nr + 1); j++) { // For each word of expanded key
985 temp = expandedKey[j - 1];
986 if (j % Nk == 0)
987 temp = ( (SBox[(temp>>8) & 0xFF]) |
988 (SBox[(temp>>16) & 0xFF]<<8) |
989 (SBox[(temp>>24) & 0xFF]<<16) |
990 (SBox[temp & 0xFF]<<24) ) ^ Rcon[Math.floor(j / Nk) - 1];
991 else if (Nk > 6 && j % Nk == 4)
992 temp = (SBox[(temp>>24) & 0xFF]<<24) |
993 (SBox[(temp>>16) & 0xFF]<<16) |
994 (SBox[(temp>>8) & 0xFF]<<8) |
995 (SBox[temp & 0xFF]);
996 expandedKey[j] = expandedKey[j-Nk] ^ temp;
997 }
998 return expandedKey;
999}
1000
1001// Rijndael's round functions...
1002
1003function Round(state, roundKey) {
1004 byteSub(state, "encrypt");
1005 shiftRow(state, "encrypt");
1006 mixColumn(state, "encrypt");
1007 addRoundKey(state, roundKey);
1008}
1009
1010function InverseRound(state, roundKey) {
1011 addRoundKey(state, roundKey);
1012 mixColumn(state, "decrypt");
1013 shiftRow(state, "decrypt");
1014 byteSub(state, "decrypt");
1015}
1016
1017function FinalRound(state, roundKey) {
1018 byteSub(state, "encrypt");
1019 shiftRow(state, "encrypt");
1020 addRoundKey(state, roundKey);
1021}
1022
1023function InverseFinalRound(state, roundKey){
1024 addRoundKey(state, roundKey);
1025 shiftRow(state, "decrypt");
1026 byteSub(state, "decrypt");
1027}
1028
1029// encrypt is the basic encryption function. It takes parameters
1030// block, an array of bytes representing a plaintext block, and expandedKey,
1031// an array of words representing the expanded key previously returned by
1032// keyExpansion(). The ciphertext block is returned as an array of bytes.
1033
1034function encrypt(block, expandedKey) {
1035 var i;
1036 if (!block || block.length*8 != blockSizeInBits)
1037 return;
1038 if (!expandedKey)
1039 return;
1040
1041 block = packBytes(block);
1042 addRoundKey(block, expandedKey);
1043 for (i=1; i<Nr; i++)
1044 Round(block, expandedKey.slice(Nb*i, Nb*(i+1)));
1045 FinalRound(block, expandedKey.slice(Nb*Nr));
1046 return unpackBytes(block);
1047}
1048
1049// decrypt is the basic decryption function. It takes parameters
1050// block, an array of bytes representing a ciphertext block, and expandedKey,
1051// an array of words representing the expanded key previously returned by
1052// keyExpansion(). The decrypted block is returned as an array of bytes.
1053
1054function decrypt(block, expandedKey) {
1055 var i;
1056 if (!block || block.length*8 != blockSizeInBits)
1057 return;
1058 if (!expandedKey)
1059 return;
1060
1061 block = packBytes(block);
1062 InverseFinalRound(block, expandedKey.slice(Nb*Nr));
1063 for (i = Nr - 1; i>0; i--)
1064 InverseRound(block, expandedKey.slice(Nb*i, Nb*(i+1)));
1065 addRoundKey(block, expandedKey);
1066 return unpackBytes(block);
1067}
1068
1069/* !NEEDED
1070// This method takes a byte array (byteArray) and converts it to a string by
1071// applying String.fromCharCode() to each value and concatenating the result.
1072// The resulting string is returned. Note that this function SKIPS zero bytes
1073// under the assumption that they are padding added in formatPlaintext().
1074// Obviously, do not invoke this method on raw data that can contain zero
1075// bytes. It is really only appropriate for printable ASCII/Latin-1
1076// values. Roll your own function for more robust functionality :)
1077
1078function byteArrayToString(byteArray) {
1079 var result = "";
1080 for(var i=0; i<byteArray.length; i++)
1081 if (byteArray[i] != 0)
1082 result += String.fromCharCode(byteArray[i]);
1083 return result;
1084}
1085*/
1086
1087// This function takes an array of bytes (byteArray) and converts them
1088// to a hexadecimal string. Array element 0 is found at the beginning of
1089// the resulting string, high nibble first. Consecutive elements follow
1090// similarly, for example [16, 255] --> "10ff". The function returns a
1091// string.
1092
1093function byteArrayToHex(byteArray) {
1094 var result = "";
1095 if (!byteArray)
1096 return;
1097 for (var i=0; i<byteArray.length; i++)
1098 result += ((byteArray[i]<16) ? "0" : "") + byteArray[i].toString(16);
1099
1100 return result;
1101}
1102
1103// This function converts a string containing hexadecimal digits to an
1104// array of bytes. The resulting byte array is filled in the order the
1105// values occur in the string, for example "10FF" --> [16, 255]. This
1106// function returns an array.
1107
1108function hexToByteArray(hexString) {
1109 var byteArray = [];
1110 if (hexString.length % 2) // must have even length
1111 return;
1112 if (hexString.indexOf("0x") == 0 || hexString.indexOf("0X") == 0)
1113 hexString = hexString.substring(2);
1114 for (var i = 0; i<hexString.length; i += 2)
1115 byteArray[Math.floor(i/2)] = parseInt(hexString.slice(i, i+2), 16);
1116 return byteArray;
1117}
1118
1119// This function packs an array of bytes into the four row form defined by
1120// Rijndael. It assumes the length of the array of bytes is divisible by
1121// four. Bytes are filled in according to the Rijndael spec (starting with
1122// column 0, row 0 to 3). This function returns a 2d array.
1123
1124function packBytes(octets) {
1125 var state = new Array();
1126 if (!octets || octets.length % 4)
1127 return;
1128
1129 state[0] = new Array(); state[1] = new Array();
1130 state[2] = new Array(); state[3] = new Array();
1131 for (var j=0; j<octets.length; j+= 4) {
1132 state[0][j/4] = octets[j];
1133 state[1][j/4] = octets[j+1];
1134 state[2][j/4] = octets[j+2];
1135 state[3][j/4] = octets[j+3];
1136 }
1137 return state;
1138}
1139
1140// This function unpacks an array of bytes from the four row format preferred
1141// by Rijndael into a single 1d array of bytes. It assumes the input "packed"
1142// is a packed array. Bytes are filled in according to the Rijndael spec.
1143// This function returns a 1d array of bytes.
1144
1145function unpackBytes(packed) {
1146 var result = new Array();
1147 for (var j=0; j<packed[0].length; j++) {
1148 result[result.length] = packed[0][j];
1149 result[result.length] = packed[1][j];
1150 result[result.length] = packed[2][j];
1151 result[result.length] = packed[3][j];
1152 }
1153 return result;
1154}
1155
1156// This function takes a prospective plaintext (string or array of bytes)
1157// and pads it with pseudorandom bytes if its length is not a multiple of the block
1158// size. If plaintext is a string, it is converted to an array of bytes
1159// in the process. The type checking can be made much nicer using the
1160// instanceof operator, but this operator is not available until IE5.0 so I
1161// chose to use the heuristic below.
1162
1163function formatPlaintext(plaintext) {
1164 var bpb = blockSizeInBits / 8; // bytes per block
1165 var fillWithRandomBits;
1166 var i;
1167
1168 // if primitive string or String instance
1169 if ((!((typeof plaintext == "object") &&
1170 ((typeof (plaintext[0])) == "number"))) &&
1171 ((typeof plaintext == "string") || plaintext.indexOf))
1172 {
1173 plaintext = plaintext.split("");
1174 // Unicode issues here (ignoring high byte)
1175 for (i=0; i<plaintext.length; i++) {
1176 plaintext[i] = plaintext[i].charCodeAt(0) & 0xFF;
1177 }
1178 }
1179
1180 i = plaintext.length % bpb;
1181 if (i > 0) {
1182//alert("adding " + (bpb - 1) + " bytes");
1183 // plaintext = plaintext.concat(getRandomBytes(bpb - i));
1184 {
1185 varpaddingBytes;
1186 var ii,cc;
1187
1188 paddingBytes = new Array();
1189 cc = bpb - i;
1190 for (ii=0; ii<cc; ii++) {
1191 paddingBytes[ii] = cc;
1192 }
1193
1194//is("cc", cc);
1195//is(getRandomBytes(bpb - i) + "", paddingBytes + "");
1196 plaintext = plaintext.concat(paddingBytes);
1197 }
1198 }
1199
1200 return plaintext;
1201}
1202
1203// Returns an array containing "howMany" random bytes.
1204
1205function getRandomBytes(howMany) {
1206 var i, bytes = new Array();
1207
1208//alert("getting some random bytes");
1209 for (i = 0; i < howMany; i++) {
1210 bytes[i] = prng.nextInt(255);
1211 }
1212 return bytes;
1213}
1214
1215// rijndaelEncrypt(plaintext, key, mode)
1216// Encrypts the plaintext using the given key and in the given mode.
1217// The parameter "plaintext" can either be a string or an array of bytes.
1218// The parameter "key" must be an array of key bytes. If you have a hex
1219// string representing the key, invoke hexToByteArray() on it to convert it
1220// to an array of bytes. The third parameter "mode" is a string indicating
1221// the encryption mode to use, either "ECB" or "CBC". If the parameter is
1222// omitted, ECB is assumed.
1223//
1224// An array of bytes representing the cihpertext is returned. To convert
1225// this array to hex, invoke byteArrayToHex() on it.
1226
1227function rijndaelEncrypt(plaintext, key, mode) {
1228 var expandedKey, i, aBlock;
1229 var bpb = blockSizeInBits / 8; // bytes per block
1230 var ct; // ciphertext
1231
1232 if (!plaintext || !key)
1233 return;
1234 if (key.length*8 != keySizeInBits)
1235 return;
1236 if (mode == "CBC") {
1237 ct = getRandomBytes(bpb); // get IV
1238//dump("IV", byteArrayToHex(ct));
1239 } else {
1240 mode = "ECB";
1241 ct = new Array();
1242 }
1243
1244 // convert plaintext to byte array and pad with zeros if necessary.
1245 plaintext = formatPlaintext(plaintext);
1246
1247 expandedKey = keyExpansion(key);
1248
1249 for (var block = 0; block < plaintext.length / bpb; block++) {
1250 aBlock = plaintext.slice(block * bpb, (block + 1) * bpb);
1251 if (mode == "CBC") {
1252 for (var i = 0; i < bpb; i++) {
1253 aBlock[i] ^= ct[(block * bpb) + i];
1254 }
1255 }
1256 ct = ct.concat(encrypt(aBlock, expandedKey));
1257 }
1258
1259 return ct;
1260}
1261
1262// rijndaelDecrypt(ciphertext, key, mode)
1263// Decrypts the using the given key and mode. The parameter "ciphertext"
1264// must be an array of bytes. The parameter "key" must be an array of key
1265// bytes. If you have a hex string representing the ciphertext or key,
1266// invoke hexToByteArray() on it to convert it to an array of bytes. The
1267// parameter "mode" is a string, either "CBC" or "ECB".
1268//
1269// An array of bytes representing the plaintext is returned. To convert
1270// this array to a hex string, invoke byteArrayToHex() on it. To convert it
1271// to a string of characters, you can use byteArrayToString().
1272
1273function rijndaelDecrypt(ciphertext, key, mode) {
1274 var expandedKey;
1275 var bpb = blockSizeInBits / 8; // bytes per block
1276 var pt = new Array(); // plaintext array
1277 var aBlock; // a decrypted block
1278 var block; // current block number
1279
1280 if (!ciphertext || !key || typeof ciphertext == "string")
1281 return;
1282 if (key.length*8 != keySizeInBits)
1283 return;
1284 if (!mode) {
1285 mode = "ECB"; // assume ECB if mode omitted
1286 }
1287
1288 expandedKey = keyExpansion(key);
1289
1290 // work backwards to accomodate CBC mode
1291 for (block=(ciphertext.length / bpb)-1; block>0; block--) {
1292 aBlock =
1293 decrypt(ciphertext.slice(block*bpb,(block+1)*bpb), expandedKey);
1294 if (mode == "CBC")
1295 for (var i=0; i<bpb; i++)
1296 pt[(block-1)*bpb + i] = aBlock[i] ^ ciphertext[(block-1)*bpb + i];
1297 else
1298 pt = aBlock.concat(pt);
1299 }
1300
1301 // do last block if ECB (skips the IV in CBC)
1302 if (mode == "ECB")
1303 pt = decrypt(ciphertext.slice(0, bpb), expandedKey).concat(pt);
1304
1305 return pt;
1306}
1307
1308//#############################################################################
1309 //Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (utf-8.js)
1310//#############################################################################
1311
1312
1313 /*Encoding and decoding of Unicode character strings as
1314 UTF-8 byte streams. */
1315
1316 //UNICODE_TO_UTF8 -- Encode Unicode argument string as UTF-8 return value
1317
1318 function unicode_to_utf8(s) {
1319 var utf8 = "";
1320
1321 for (var n = 0; n < s.length; n++) {
1322 var c = s.charCodeAt(n);
1323
1324 if (c <= 0x7F) {
1325 // 0x00 - 0x7F: Emit as single byte, unchanged
1326 utf8 += String.fromCharCode(c);
1327 } else if ((c >= 0x80) && (c <= 0x7FF)) {
1328 // 0x80 - 0x7FF: Output as two byte code, 0xC0 in first byte
1329 // 0x80 in second byte
1330 utf8 += String.fromCharCode((c >> 6) | 0xC0);
1331 utf8 += String.fromCharCode((c & 0x3F) | 0x80);
1332 } else {
1333 // 0x800 - 0xFFFF: Output as three bytes, 0xE0 in first byte
1334 // 0x80 in second byte
1335 // 0x80 in third byte
1336 utf8 += String.fromCharCode((c >> 12) | 0xE0);
1337 utf8 += String.fromCharCode(((c >> 6) & 0x3F) | 0x80);
1338 utf8 += String.fromCharCode((c & 0x3F) | 0x80);
1339 }
1340 }
1341 return utf8;
1342 }
1343
1344 //UTF8_TO_UNICODE -- Decode UTF-8 argument into Unicode string return value
1345
1346 function utf8_to_unicode(utf8) {
1347 var s = "", i = 0, b1, b2, b2;
1348
1349 while (i < utf8.length) {
1350 b1 = utf8.charCodeAt(i);
1351 if (b1 < 0x80) { // One byte code: 0x00 0x7F
1352 s += String.fromCharCode(b1);
1353 i++;
1354 } else if((b1 >= 0xC0) && (b1 < 0xE0)) {// Two byte code: 0x80 - 0x7FF
1355 b2 = utf8.charCodeAt(i + 1);
1356 s += String.fromCharCode(((b1 & 0x1F) << 6) | (b2 & 0x3F));
1357 i += 2;
1358 } else { // Three byte code: 0x800 - 0xFFFF
1359 b2 = utf8.charCodeAt(i + 1);
1360 b3 = utf8.charCodeAt(i + 2);
1361 s += String.fromCharCode(((b1 & 0xF) << 12) |
1362 ((b2 & 0x3F) << 6) |
1363 (b3 & 0x3F));
1364 i += 3;
1365 }
1366 }
1367 return s;
1368 }
1369
1370 /*ENCODE_UTF8 -- Encode string as UTF8 only if it contains
1371 a character of 0x9D (Unicode OPERATING
1372 SYSTEM COMMAND) or a character greater
1373 than 0xFF. This permits all strings
1374 consisting exclusively of 8 bit
1375 graphic characters to be encoded as
1376 themselves. We choose 0x9D as the sentinel
1377 character as opposed to one of the more
1378 logical PRIVATE USE characters because 0x9D
1379 is not overloaded by the regrettable
1380 "Windows-1252" character set. Now such characters
1381 don't belong in JavaScript strings, but you never
1382 know what somebody is going to paste into a
1383 text box, so this choice keeps Windows-encoded
1384 strings from bloating to UTF-8 encoding. */
1385
1386 function encode_utf8(s) {
1387 var i, necessary = false;
1388
1389 for (i = 0; i < s.length; i++) {
1390 if ((s.charCodeAt(i) == 0x9D) ||
1391 (s.charCodeAt(i) > 0xFF)) {
1392 necessary = true;
1393 break;
1394 }
1395 }
1396 if (!necessary) {
1397 return s;
1398 }
1399 return String.fromCharCode(0x9D) + unicode_to_utf8(s);
1400 }
1401
1402 /* DECODE_UTF8 -- Decode a string encoded with encode_utf8
1403 above. If the string begins with the
1404 sentinel character 0x9D (OPERATING
1405 SYSTEM COMMAND), then we decode the
1406 balance as a UTF-8 stream. Otherwise,
1407 the string is output unchanged, as
1408 it's guaranteed to contain only 8 bit
1409 characters excluding 0x9D. */
1410
1411 function decode_utf8(s) {
1412 if ((s.length > 0) && (s.charCodeAt(0) == 0x9D)) {
1413 return utf8_to_unicode(s.substring(1));
1414 }
1415 return s;
1416 }
1417
1418
1419//#############################################################################
1420 //Downloaded on April 26, 2006 from http://pajhome.org.uk/crypt/md5/md5.js
1421//#############################################################################
1422
1423/*
1424 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
1425 * Digest Algorithm, as defined in RFC 1321.
1426 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
1427 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
1428 * Distributed under the BSD License
1429 * See http://pajhome.org.uk/crypt/md5 for more info.
1430 */
1431
1432/*
1433 * Configurable variables. You may need to tweak these to be compatible with
1434 * the server-side, but the defaults work in most cases.
1435 */
1436var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
1437var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
1438var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
1439
1440/*
1441 * These are the functions you'll usually want to call
1442 * They take string arguments and return either hex or base-64 encoded strings
1443 */
1444function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
1445function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
1446function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
1447function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
1448function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
1449function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
1450
1451/*
1452 * Perform a simple self-test to see if the VM is working
1453 */
1454function md5_vm_test()
1455{
1456 return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
1457}
1458
1459/*
1460 * Calculate the MD5 of an array of little-endian words, and a bit length
1461 */
1462function core_md5(x, len)
1463{
1464 /* append padding */
1465 x[len >> 5] |= 0x80 << ((len) % 32);
1466 x[(((len + 64) >>> 9) << 4) + 14] = len;
1467
1468 var a = 1732584193;
1469 var b = -271733879;
1470 var c = -1732584194;
1471 var d = 271733878;
1472
1473 for(var i = 0; i < x.length; i += 16)
1474 {
1475 var olda = a;
1476 var oldb = b;
1477 var oldc = c;
1478 var oldd = d;
1479
1480 a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
1481 d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
1482 c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
1483 b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
1484 a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
1485 d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
1486 c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
1487 b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
1488 a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
1489 d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
1490 c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
1491 b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
1492 a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
1493 d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
1494 c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
1495 b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
1496
1497 a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
1498 d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
1499 c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
1500 b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
1501 a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
1502 d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
1503 c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
1504 b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
1505 a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
1506 d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
1507 c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
1508 b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
1509 a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
1510 d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
1511 c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
1512 b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
1513
1514 a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
1515 d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
1516 c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
1517 b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
1518 a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
1519 d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
1520 c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
1521 b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
1522 a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
1523 d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
1524 c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
1525 b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
1526 a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
1527 d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
1528 c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
1529 b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
1530
1531 a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
1532 d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
1533 c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
1534 b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
1535 a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
1536 d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
1537 c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
1538 b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
1539 a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
1540 d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
1541 c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
1542 b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
1543 a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
1544 d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
1545 c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
1546 b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
1547
1548 a = safe_add(a, olda);
1549 b = safe_add(b, oldb);
1550 c = safe_add(c, oldc);
1551 d = safe_add(d, oldd);
1552 }
1553 return Array(a, b, c, d);
1554
1555}
1556
1557/*
1558 * These functions implement the four basic operations the algorithm uses.
1559 */
1560function md5_cmn(q, a, b, x, s, t)
1561{
1562 return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
1563}
1564function md5_ff(a, b, c, d, x, s, t)
1565{
1566 return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
1567}
1568function md5_gg(a, b, c, d, x, s, t)
1569{
1570 return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
1571}
1572function md5_hh(a, b, c, d, x, s, t)
1573{
1574 return md5_cmn(b ^ c ^ d, a, b, x, s, t);
1575}
1576function md5_ii(a, b, c, d, x, s, t)
1577{
1578 return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
1579}
1580
1581/*
1582 * Calculate the HMAC-MD5, of a key and some data
1583 */
1584function core_hmac_md5(key, data)
1585{
1586 var bkey = str2binl(key);
1587 if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
1588
1589 var ipad = Array(16), opad = Array(16);
1590 for(var i = 0; i < 16; i++)
1591 {
1592 ipad[i] = bkey[i] ^ 0x36363636;
1593 opad[i] = bkey[i] ^ 0x5C5C5C5C;
1594 }
1595
1596 var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
1597 return core_md5(opad.concat(hash), 512 + 128);
1598}
1599
1600/*
1601 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
1602 * to work around bugs in some JS interpreters.
1603 */
1604function safe_add(x, y)
1605{
1606 var lsw = (x & 0xFFFF) + (y & 0xFFFF);
1607 var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
1608 return (msw << 16) | (lsw & 0xFFFF);
1609}
1610
1611/*
1612 * Bitwise rotate a 32-bit number to the left.
1613 */
1614function bit_rol(num, cnt)
1615{
1616 return (num << cnt) | (num >>> (32 - cnt));
1617}
1618
1619/*
1620 * Convert a string to an array of little-endian words
1621 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
1622 */
1623function str2binl(str)
1624{
1625 var bin = Array();
1626 var mask = (1 << chrsz) - 1;
1627 for(var i = 0; i < str.length * chrsz; i += chrsz)
1628 bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
1629 return bin;
1630}
1631
1632/*
1633 * Convert an array of little-endian words to a string
1634 */
1635function binl2str(bin)
1636{
1637 var str = "";
1638 var mask = (1 << chrsz) - 1;
1639 for(var i = 0; i < bin.length * 32; i += chrsz)
1640 str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
1641 return str;
1642}
1643
1644/*
1645 * Convert an array of little-endian words to a hex string.
1646 */
1647function binl2hex(binarray)
1648{
1649 var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
1650 var str = "";
1651 for(var i = 0; i < binarray.length * 4; i++)
1652 {
1653 str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
1654 hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
1655 }
1656 return str;
1657}
1658
1659/*
1660 * Convert an array of little-endian words to a base-64 string
1661 */
1662function binl2b64(binarray)
1663{
1664 var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1665 var str = "";
1666 for(var i = 0; i < binarray.length * 4; i += 3)
1667 {
1668 var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)
1669 | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
1670 | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
1671 for(var j = 0; j < 4; j++)
1672 {
1673 if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
1674 else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
1675 }
1676 }
1677 return str;
1678}
1679
1680
1681//#############################################################################
1682//#############################################################################
1683//#############################################################################
1684
1685
1686
1687MochiKit.Base.update(Clipperz.Crypto.Base, {
1688
1689 '__repr__': function () {
1690 return "[" + this.NAME + " " + this.VERSION + "]";
1691 },
1692
1693 'toString': function () {
1694 return this.__repr__();
1695 },
1696
1697 //-----------------------------------------------------------------------------
1698
1699 'encryptUsingSecretKey': function (aKey, aMessage) {
1700//Clipperz.Profile.start("Clipperz.Crypto.Base.encryptUsingSecretKey");
1701 var result;
1702 var plaintext;
1703 varheader;
1704 varkey;
1705
1706 key = hexToByteArray(Clipperz.Crypto.Base.computeHashValue(aKey));
1707
1708 addEntropyTime();
1709 prng = new AESprng(keyFromEntropy());
1710
1711 plaintext = encode_utf8(aMessage);
1712
1713 header = Clipperz.Base.byteArrayToString(hexToByteArray(Clipperz.Crypto.Base.computeMD5HashValue(plaintext)));
1714
1715 // Add message length in bytes to header
1716 i = plaintext.length;
1717 header += String.fromCharCode(i >>> 24);
1718 header += String.fromCharCode(i >>> 16);
1719 header += String.fromCharCode(i >>> 8);
1720 header += String.fromCharCode(i & 0xFF);
1721
1722 //The format of the actual message passed to rijndaelEncrypt
1723 //is:
1724 //
1725 // Bytes Content
1726 // 0-15 MD5 signature of plaintext
1727 // 16-19 Length of plaintext, big-endian order
1728 // 20-end Plaintext
1729 //
1730 //Note that this message will be padded with zero bytes
1731 //to an integral number of AES blocks (blockSizeInBits / 8).
1732 //This does not include the initial vector for CBC
1733 //encryption, which is added internally by rijndaelEncrypt.
1734 result = byteArrayToHex(rijndaelEncrypt(header + plaintext, key, "CBC"));
1735
1736 delete prng;
1737
1738//Clipperz.Profile.stop("Clipperz.Crypto.Base.encryptUsingSecretKey");
1739 return result;
1740 },
1741
1742 //.............................................................................
1743
1744 'decryptUsingSecretKey': function (aKey, aMessage) {
1745//Clipperz.Profile.start("Clipperz.Crypto.Base.decryptUsingSecretKey");
1746 varkey;
1747 var decryptedText;
1748 vartextLength;
1749 varheader;
1750 varheaderDigest;
1751 var plaintext;
1752 var i;
1753
1754 key = hexToByteArray(Clipperz.Crypto.Base.computeHashValue(aKey));
1755
1756 decryptedText = rijndaelDecrypt(hexToByteArray(aMessage), key, "CBC");
1757
1758 header = decryptedText.slice(0, 20);
1759 decryptedText = decryptedText.slice(20);
1760
1761 headerDigest = byteArrayToHex(header.slice(0,16));
1762 textLength = (header[16] << 24) | (header[17] << 16) | (header[18] << 8) | header[19];
1763
1764 if ((textLength < 0) || (textLength > decryptedText.length)) {
1765 // jslog.warning("Message (length " + decryptedText.length + ") truncated. " + textLength + " characters expected.");
1766 //Try to sauve qui peut by setting length to entire message
1767 textLength = decryptedText.length;
1768 }
1769
1770 plainText = "";
1771
1772 for (i=0; i<textLength; i++) {
1773 plainText += String.fromCharCode(decryptedText[i]);
1774 }
1775
1776 if (Clipperz.Crypto.Base.computeMD5HashValue(plainText) != headerDigest) {
1777 // jslog.warning("Message corrupted. Checksum of decrypted message does not match.");
1778 throw Clipperz.Crypto.Base.exception.CorruptedMessage;
1779 // throw new Error("Message corrupted. Checksum of decrypted message does not match. Parsed result: " + decode_utf8(plainText));
1780 }
1781
1782 // That's it; plug plaintext into the result field
1783
1784 result = decode_utf8(plainText);
1785
1786//Clipperz.Profile.stop("Clipperz.Crypto.Base.decryptUsingSecretKey");
1787 return result;
1788 },
1789
1790 //-----------------------------------------------------------------------------
1791
1792 'computeHashValue': function (aMessage) {
1793//Clipperz.Profile.start("Clipperz.Crypto.Base.computeHashValue");
1794 varresult;
1795
1796 result = hex_sha256(aMessage);
1797//Clipperz.Profile.stop("Clipperz.Crypto.Base.computeHashValue");
1798
1799 return result;
1800 },
1801
1802 //.........................................................................
1803
1804 'computeMD5HashValue': function (aMessage) {
1805 varresult;
1806//Clipperz.Profile.start("Clipperz.Crypto.Base.computeMD5HashValue");
1807 result = hex_md5(aMessage);
1808//Clipperz.Profile.stop("Clipperz.Crypto.Base.computeMD5HashValue");
1809
1810 return result;
1811 },
1812
1813 //-----------------------------------------------------------------------------
1814
1815 'generateRandomSeed': function () {
1816//Clipperz.Profile.start("Clipperz.Crypto.Base.generateRandomSeed");
1817 varresult;
1818 var seed;
1819 var prng;
1820 var charA;
1821 var i;
1822
1823 addEntropyTime();
1824
1825 seed = keyFromEntropy();
1826 prng = new AESprng(seed);
1827
1828 result = "";
1829 charA = ("A").charCodeAt(0);
1830
1831 for (i = 0; i < 64; i++) {
1832 result += String.fromCharCode(charA + prng.nextInt(25));
1833 }
1834
1835 delete prng;
1836
1837 result = Clipperz.Crypto.Base.computeHashValue(result);
1838
1839//Clipperz.Profile.stop("Clipperz.Crypto.Base.generateRandomSeed");
1840 return result;
1841 },
1842
1843 //-----------------------------------------------------------------------------
1844
1845 'exception': {
1846 'CorruptedMessage': new MochiKit.Base.NamedError("Clipperz.Crypto.Base.exception.CorruptedMessage")
1847 },
1848
1849 //.........................................................................
1850 __syntaxFix__: "syntax fix"
1851});
1852
diff --git a/frontend/beta/js/Clipperz/Crypto/BigInt.js b/frontend/beta/js/Clipperz/Crypto/BigInt.js
new file mode 100644
index 0000000..d4d05d2
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/Crypto/BigInt.js
@@ -0,0 +1,1760 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
30if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
31
32//#############################################################################
33 //Downloaded on March 05, 2007 from http://www.leemon.com/crypto/BigInt.js
34//#############################################################################
35
36
37////////////////////////////////////////////////////////////////////////////////////////
38// Big Integer Library v. 5.0
39// Created 2000, last modified 2006
40// Leemon Baird
41// www.leemon.com
42//
43// This file is public domain. You can use it for any purpose without restriction.
44// I do not guarantee that it is correct, so use it at your own risk. If you use
45// it for something interesting, I'd appreciate hearing about it. If you find
46// any bugs or make any improvements, I'd appreciate hearing about those too.
47// It would also be nice if my name and address were left in the comments.
48// But none of that is required.
49//
50// This code defines a bigInt library for arbitrary-precision integers.
51// A bigInt is an array of integers storing the value in chunks of bpe bits,
52// little endian (buff[0] is the least significant word).
53// Negative bigInts are stored two's complement.
54// Some functions assume their parameters have at least one leading zero element.
55// Functions with an underscore at the end of the name have unpredictable behavior in case of overflow,
56// so the caller must make sure overflow won't happen.
57// For each function where a parameter is modified, that same
58// variable must not be used as another argument too.
59// So, you cannot square x by doing multMod_(x,x,n).
60// You must use squareMod_(x,n) instead, or do y=dup(x); multMod_(x,y,n).
61//
62// These functions are designed to avoid frequent dynamic memory allocation in the inner loop.
63// For most functions, if it needs a BigInt as a local variable it will actually use
64// a global, and will only allocate to it when it's not the right size. This ensures
65// that when a function is called repeatedly with same-sized parameters, it only allocates
66// memory on the first call.
67//
68// Note that for cryptographic purposes, the calls to Math.random() must
69// be replaced with calls to a better pseudorandom number generator.
70//
71// In the following, "bigInt" means a bigInt with at least one leading zero element,
72// and "integer" means a nonnegative integer less than radix. In some cases, integer
73// can be negative. Negative bigInts are 2s complement.
74//
75// The following functions do not modify their inputs, but dynamically allocate memory every time they are called:
76//
77// function bigInt2str(x,base) //convert a bigInt into a string in a given base, from base 2 up to base 95
78// function dup(x) //returns a copy of bigInt x
79// function findPrimes(n) //return array of all primes less than integer n
80// function int2bigInt(t,n,m) //convert integer t to a bigInt with at least n bits and m array elements
81// function int2bigInt(s,b,n,m) //convert string s in base b to a bigInt with at least n bits and m array elements
82// function trim(x,k) //return a copy of x with exactly k leading zero elements
83//
84// The following functions do not modify their inputs, so there is never a problem with the result being too big:
85//
86// function bitSize(x) //returns how many bits long the bigInt x is, not counting leading zeros
87// function equals(x,y) //is the bigInt x equal to the bigint y?
88// function equalsInt(x,y) //is bigint x equal to integer y?
89// function greater(x,y) //is x>y? (x and y are nonnegative bigInts)
90// function greaterShift(x,y,shift)//is (x <<(shift*bpe)) > y?
91// function isZero(x) //is the bigInt x equal to zero?
92// function millerRabin(x,b) //does one round of Miller-Rabin base integer b say that bigInt x is possibly prime (as opposed to definitely composite)?
93// function modInt(x,n) //return x mod n for bigInt x and integer n.
94// function negative(x) //is bigInt x negative?
95//
96// The following functions do not modify their inputs, but allocate memory and call functions with underscores
97//
98// function add(x,y) //return (x+y) for bigInts x and y.
99// function addInt(x,n) //return (x+n) where x is a bigInt and n is an integer.
100// function expand(x,n) //return a copy of x with at least n elements, adding leading zeros if needed
101// function inverseMod(x,n) //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null
102// function mod(x,n) //return a new bigInt equal to (x mod n) for bigInts x and n.
103// function mult(x,y) //return x*y for bigInts x and y. This is faster when y<x.
104// function multMod(x,y,n) //return (x*y mod n) for bigInts x,y,n. For greater speed, let y<x.
105// function powMod(x,y,n) //return (x**y mod n) where x,y,n are bigInts and ** is exponentiation. 0**0=1. Faster for odd n.
106// function randTruePrime(k) //return a new, random, k-bit, true prime using Maurer's algorithm.
107// function sub(x,y) //return (x-y) for bigInts x and y. Negative answers will be 2s complement
108//
109// The following functions write a bigInt result to one of the parameters, but
110// the result is never bigger than the original, so there can't be overflow problems:
111//
112// function divInt_(x,n) //do x=floor(x/n) for bigInt x and integer n, and return the remainder
113// function GCD_(x,y) //set x to the greatest common divisor of bigInts x and y, (y is destroyed).
114// function halve_(x) //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement
115// function mod_(x,n) //do x=x mod n for bigInts x and n.
116// function rightShift_(x,n) //right shift bigInt x by n bits. 0 <= n < bpe.
117//
118// The following functions write a bigInt result to one of the parameters. The caller is responsible for
119// ensuring it is large enough to hold the result.
120//
121// function addInt_(x,n) //do x=x+n where x is a bigInt and n is an integer
122// function add_(x,y) //do x=x+y for bigInts x and y
123// function addShift_(x,y,ys) //do x=x+(y<<(ys*bpe))
124// function copy_(x,y) //do x=y on bigInts x and y
125// function copyInt_(x,n) //do x=n on bigInt x and integer n
126// function carry_(x) //do carries and borrows so each element of the bigInt x fits in bpe bits.
127// function divide_(x,y,q,r) //divide_ x by y giving quotient q and remainder r
128// function eGCD_(x,y,d,a,b) //sets a,b,d to positive big integers such that d = GCD_(x,y) = a*x-b*y
129// function inverseMod_(x,n) //do x=x**(-1) mod n, for bigInts x and n. Returns 1 (0) if inverse does (doesn't) exist
130// function inverseModInt_(x,n) //return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse
131// function leftShift_(x,n) //left shift bigInt x by n bits. n<bpe.
132// function linComb_(x,y,a,b) //do x=a*x+b*y for bigInts x and y and integers a and b
133// function linCombShift_(x,y,b,ys) //do x=x+b*(y<<(ys*bpe)) for bigInts x and y, and integers b and ys
134// function mont_(x,y,n,np) //Montgomery multiplication (see comments where the function is defined)
135// function mult_(x,y) //do x=x*y for bigInts x and y.
136// function multInt_(x,n) //do x=x*n where x is a bigInt and n is an integer.
137// function multMod_(x,y,n) //do x=x*y mod n for bigInts x,y,n.
138// function powMod_(x,y,n) //do x=x**y mod n, where x,y,n are bigInts (n is odd) and ** is exponentiation. 0**0=1.
139// function randBigInt_(b,n,s) //do b = an n-bit random BigInt. if s=1, then nth bit (most significant bit) is set to 1. n>=1.
140// function randTruePrime_(ans,k) //do ans = a random k-bit true random prime (not just probable prime) with 1 in the msb.
141// function squareMod_(x,n) //do x=x*x mod n for bigInts x,n
142// function sub_(x,y) //do x=x-y for bigInts x and y. Negative answers will be 2s complement.
143// function subShift_(x,y,ys) //do x=x-(y<<(ys*bpe)). Negative answers will be 2s complement.
144//
145// The following functions are based on algorithms from the _Handbook of Applied Cryptography_
146// powMod_() = algorithm 14.94, Montgomery exponentiation
147// eGCD_,inverseMod_() = algorithm 14.61, Binary extended GCD_
148// GCD_() = algorothm 14.57, Lehmer's algorithm
149// mont_() = algorithm 14.36, Montgomery multiplication
150// divide_() = algorithm 14.20 Multiple-precision division
151// squareMod_() = algorithm 14.16 Multiple-precision squaring
152// randTruePrime_() = algorithm 4.62, Maurer's algorithm
153// millerRabin() = algorithm 4.24, Miller-Rabin algorithm
154//
155// Profiling shows:
156// randTruePrime_() spends:
157// 10% of its time in calls to powMod_()
158// 85% of its time in calls to millerRabin()
159// millerRabin() spends:
160// 99% of its time in calls to powMod_() (always with a base of 2)
161// powMod_() spends:
162// 94% of its time in calls to mont_() (almost always with x==y)
163//
164// This suggests there are several ways to speed up this library slightly:
165// - convert powMod_ to use a Montgomery form of k-ary window (or maybe a Montgomery form of sliding window)
166// -- this should especially focus on being fast when raising 2 to a power mod n
167// - convert randTruePrime_() to use a minimum r of 1/3 instead of 1/2 with the appropriate change to the test
168// - tune the parameters in randTruePrime_(), including c, m, and recLimit
169// - speed up the single loop in mont_() that takes 95% of the runtime, perhaps by reducing checking
170// within the loop when all the parameters are the same length.
171//
172// There are several ideas that look like they wouldn't help much at all:
173// - replacing trial division in randTruePrime_() with a sieve (that speeds up something taking almost no time anyway)
174// - increase bpe from 15 to 30 (that would help if we had a 32*32->64 multiplier, but not with JavaScript's 32*32->32)
175// - speeding up mont_(x,y,n,np) when x==y by doing a non-modular, non-Montgomery square
176// followed by a Montgomery reduction. The intermediate answer will be twice as long as x, so that
177// method would be slower. This is unfortunate because the code currently spends almost all of its time
178// doing mont_(x,x,...), both for randTruePrime_() and powMod_(). A faster method for Montgomery squaring
179// would have a large impact on the speed of randTruePrime_() and powMod_(). HAC has a couple of poorly-worded
180// sentences that seem to imply it's faster to do a non-modular square followed by a single
181// Montgomery reduction, but that's obviously wrong.
182////////////////////////////////////////////////////////////////////////////////////////
183
184//globals
185bpe=0; //bits stored per array element
186mask=0; //AND this with an array element to chop it down to bpe bits
187radix=mask+1; //equals 2^bpe. A single 1 bit to the left of the last bit of mask.
188
189//the digits for converting to different bases
190digitsStr='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_=!@#$%^&*()[]{}|;:,.<>/?`~ \\\'\"+-';
191
192//initialize the global variables
193for (bpe=0; (1<<(bpe+1)) > (1<<bpe); bpe++); //bpe=number of bits in the mantissa on this platform
194bpe>>=1; //bpe=number of bits in one element of the array representing the bigInt
195mask=(1<<bpe)-1; //AND the mask with an integer to get its bpe least significant bits
196radix=mask+1; //2^bpe. a single 1 bit to the left of the first bit of mask
197one=int2bigInt(1,1,1); //constant used in powMod_()
198
199//the following global variables are scratchpad memory to
200//reduce dynamic memory allocation in the inner loop
201t=new Array(0);
202ss=t; //used in mult_()
203s0=t; //used in multMod_(), squareMod_()
204s1=t; //used in powMod_(), multMod_(), squareMod_()
205s2=t; //used in powMod_(), multMod_()
206s3=t; //used in powMod_()
207s4=t; s5=t; //used in mod_()
208s6=t; //used in bigInt2str()
209s7=t; //used in powMod_()
210T=t; //used in GCD_()
211sa=t; //used in mont_()
212mr_x1=t; mr_r=t; mr_a=t; //used in millerRabin()
213eg_v=t; eg_u=t; eg_A=t; eg_B=t; eg_C=t; eg_D=t; //used in eGCD_(), inverseMod_()
214md_q1=t; md_q2=t; md_q3=t; md_r=t; md_r1=t; md_r2=t; md_tt=t; //used in mod_()
215
216primes=t; pows=t; s_i=t; s_i2=t; s_R=t; s_rm=t; s_q=t; s_n1=t;
217 s_a=t; s_r2=t; s_n=t; s_b=t; s_d=t; s_x1=t; s_x2=t, s_aa=t; //used in randTruePrime_()
218
219////////////////////////////////////////////////////////////////////////////////////////
220
221//return array of all primes less than integer n
222function findPrimes(n) {
223 var i,s,p,ans;
224 s=new Array(n);
225 for (i=0;i<n;i++)
226 s[i]=0;
227 s[0]=2;
228 p=0; //first p elements of s are primes, the rest are a sieve
229 for(;s[p]<n;) { //s[p] is the pth prime
230 for(i=s[p]*s[p]; i<n; i+=s[p]) //mark multiples of s[p]
231 s[i]=1;
232 p++;
233 s[p]=s[p-1]+1;
234 for(; s[p]<n && s[s[p]]; s[p]++); //find next prime (where s[p]==0)
235 }
236 ans=new Array(p);
237 for(i=0;i<p;i++)
238 ans[i]=s[i];
239 return ans;
240}
241
242//does a single round of Miller-Rabin base b consider x to be a possible prime?
243//x is a bigInt, and b is an integer
244function millerRabin(x,b) {
245 var i,j,k,s;
246
247 if (mr_x1.length!=x.length) {
248 mr_x1=dup(x);
249 mr_r=dup(x);
250 mr_a=dup(x);
251 }
252
253 copyInt_(mr_a,b);
254 copy_(mr_r,x);
255 copy_(mr_x1,x);
256
257 addInt_(mr_r,-1);
258 addInt_(mr_x1,-1);
259
260 //s=the highest power of two that divides mr_r
261 k=0;
262 for (i=0;i<mr_r.length;i++)
263 for (j=1;j<mask;j<<=1)
264 if (x[i] & j) {
265 s=(k<mr_r.length+bpe ? k : 0);
266 i=mr_r.length;
267 j=mask;
268 } else
269 k++;
270
271 if (s)
272 rightShift_(mr_r,s);
273
274 powMod_(mr_a,mr_r,x);
275
276 if (!equalsInt(mr_a,1) && !equals(mr_a,mr_x1)) {
277 j=1;
278 while (j<=s-1 && !equals(mr_a,mr_x1)) {
279 squareMod_(mr_a,x);
280 if (equalsInt(mr_a,1)) {
281 return 0;
282 }
283 j++;
284 }
285 if (!equals(mr_a,mr_x1)) {
286 return 0;
287 }
288 }
289 return 1;
290}
291
292//returns how many bits long the bigInt is, not counting leading zeros.
293function bitSize(x) {
294 var j,z,w;
295 for (j=x.length-1; (x[j]==0) && (j>0); j--);
296 for (z=0,w=x[j]; w; (w>>=1),z++);
297 z+=bpe*j;
298 return z;
299}
300
301//return a copy of x with at least n elements, adding leading zeros if needed
302function expand(x,n) {
303 var ans=int2bigInt(0,(x.length>n ? x.length : n)*bpe,0);
304 copy_(ans,x);
305 return ans;
306}
307
308//return a k-bit true random prime using Maurer's algorithm.
309function randTruePrime(k) {
310 var ans=int2bigInt(0,k,0);
311 randTruePrime_(ans,k);
312 return trim(ans,1);
313}
314
315//return a new bigInt equal to (x mod n) for bigInts x and n.
316function mod(x,n) {
317 var ans=dup(x);
318 mod_(ans,n);
319 return trim(ans,1);
320}
321
322//return (x+n) where x is a bigInt and n is an integer.
323function addInt(x,n) {
324 var ans=expand(x,x.length+1);
325 addInt_(ans,n);
326 return trim(ans,1);
327}
328
329//return x*y for bigInts x and y. This is faster when y<x.
330function mult(x,y) {
331 var ans=expand(x,x.length+y.length);
332 mult_(ans,y);
333 return trim(ans,1);
334}
335
336//return (x**y mod n) where x,y,n are bigInts and ** is exponentiation. 0**0=1. Faster for odd n.
337function powMod(x,y,n) {
338 var ans=expand(x,n.length);
339 powMod_(ans,trim(y,2),trim(n,2),0); //this should work without the trim, but doesn't
340 return trim(ans,1);
341}
342
343//return (x-y) for bigInts x and y. Negative answers will be 2s complement
344function sub(x,y) {
345 var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1));
346 sub_(ans,y);
347 return trim(ans,1);
348}
349
350//return (x+y) for bigInts x and y.
351function add(x,y) {
352 var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1));
353 add_(ans,y);
354 return trim(ans,1);
355}
356
357//return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null
358function inverseMod(x,n) {
359 var ans=expand(x,n.length);
360 var s;
361 s=inverseMod_(ans,n);
362 return s ? trim(ans,1) : null;
363}
364
365//return (x*y mod n) for bigInts x,y,n. For greater speed, let y<x.
366function multMod(x,y,n) {
367 var ans=expand(x,n.length);
368 multMod_(ans,y,n);
369 return trim(ans,1);
370}
371
372//generate a k-bit true random prime using Maurer's algorithm,
373//and put it into ans. The bigInt ans must be large enough to hold it.
374function randTruePrime_(ans,k) {
375 var c,m,pm,dd,j,r,B,divisible,z,zz,recSize;
376
377 if (primes.length==0)
378 primes=findPrimes(30000); //check for divisibility by primes <=30000
379
380 if (pows.length==0) {
381 pows=new Array(512);
382 for (j=0;j<512;j++) {
383 pows[j]=Math.pow(2,j/511.-1.);
384 }
385 }
386
387 //c and m should be tuned for a particular machine and value of k, to maximize speed
388 //this was: c=primes[primes.length-1]/k/k; //check using all the small primes. (c=0.1 in HAC)
389 c=0.1;
390 m=20; //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
391 recLimit=20; /*must be at least 2 (was 29)*/ //stop recursion when k <=recLimit
392
393 if (s_i2.length!=ans.length) {
394 s_i2=dup(ans);
395 s_R =dup(ans);
396 s_n1=dup(ans);
397 s_r2=dup(ans);
398 s_d =dup(ans);
399 s_x1=dup(ans);
400 s_x2=dup(ans);
401 s_b =dup(ans);
402 s_n =dup(ans);
403 s_i =dup(ans);
404 s_rm=dup(ans);
405 s_q =dup(ans);
406 s_a =dup(ans);
407 s_aa=dup(ans);
408 }
409
410 if (k <= recLimit) { //generate small random primes by trial division up to its square root
411 pm=(1<<((k+2)>>1))-1; //pm is binary number with all ones, just over sqrt(2^k)
412 copyInt_(ans,0);
413 for (dd=1;dd;) {
414 dd=0;
415 ans[0]= 1 | (1<<(k-1)) | Math.floor(Math.random()*(1<<k)); //random, k-bit, odd integer, with msb 1
416 for (j=1;(j<primes.length) && ((primes[j]&pm)==primes[j]);j++) { //trial division by all primes 3...sqrt(2^k)
417 if (0==(ans[0]%primes[j])) {
418 dd=1;
419 break;
420 }
421 }
422 }
423 carry_(ans);
424 return;
425 }
426
427 B=c*k*k; //try small primes up to B (or all the primes[] array if the largest is less than B).
428 if (k>2*m) //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
429 for (r=1; k-k*r<=m; )
430 r=pows[Math.floor(Math.random()*512)]; //r=Math.pow(2,Math.random()-1);
431 else
432 r=.5;
433
434 //simulation suggests the more complex algorithm using r=.333 is only slightly faster.
435
436 recSize=Math.floor(r*k)+1;
437
438 randTruePrime_(s_q,recSize);
439 copyInt_(s_i2,0);
440 s_i2[Math.floor((k-2)/bpe)] |= (1<<((k-2)%bpe)); //s_i2=2^(k-2)
441 divide_(s_i2,s_q,s_i,s_rm); //s_i=floor((2^(k-1))/(2q))
442
443 z=bitSize(s_i);
444
445 for (;;) {
446 for (;;) { //generate z-bit numbers until one falls in the range [0,s_i-1]
447 randBigInt_(s_R,z,0);
448 if (greater(s_i,s_R))
449 break;
450 } //now s_R is in the range [0,s_i-1]
451 addInt_(s_R,1); //now s_R is in the range [1,s_i]
452 add_(s_R,s_i); //now s_R is in the range [s_i+1,2*s_i]
453
454 copy_(s_n,s_q);
455 mult_(s_n,s_R);
456 multInt_(s_n,2);
457 addInt_(s_n,1); //s_n=2*s_R*s_q+1
458
459 copy_(s_r2,s_R);
460 multInt_(s_r2,2); //s_r2=2*s_R
461
462 //check s_n for divisibility by small primes up to B
463 for (divisible=0,j=0; (j<primes.length) && (primes[j]<B); j++)
464 if (modInt(s_n,primes[j])==0) {
465 divisible=1;
466 break;
467 }
468
469 if (!divisible) //if it passes small primes check, then try a single Miller-Rabin base 2
470 if (!millerRabin(s_n,2)) //this line represents 75% of the total runtime for randTruePrime_
471 divisible=1;
472
473 if (!divisible) { //if it passes that test, continue checking s_n
474 addInt_(s_n,-3);
475 for (j=s_n.length-1;(s_n[j]==0) && (j>0); j--); //strip leading zeros
476 for (zz=0,w=s_n[j]; w; (w>>=1),zz++);
477 zz+=bpe*j; //zz=number of bits in s_n, ignoring leading zeros
478 for (;;) { //generate z-bit numbers until one falls in the range [0,s_n-1]
479 randBigInt_(s_a,zz,0);
480 if (greater(s_n,s_a))
481 break;
482 } //now s_a is in the range [0,s_n-1]
483 addInt_(s_n,3); //now s_a is in the range [0,s_n-4]
484 addInt_(s_a,2); //now s_a is in the range [2,s_n-2]
485 copy_(s_b,s_a);
486 copy_(s_n1,s_n);
487 addInt_(s_n1,-1);
488 powMod_(s_b,s_n1,s_n); //s_b=s_a^(s_n-1) modulo s_n
489 addInt_(s_b,-1);
490 if (isZero(s_b)) {
491 copy_(s_b,s_a);
492 powMod_(s_b,s_r2,s_n);
493 addInt_(s_b,-1);
494 copy_(s_aa,s_n);
495 copy_(s_d,s_b);
496 GCD_(s_d,s_n); //if s_b and s_n are relatively prime, then s_n is a prime
497 if (equalsInt(s_d,1)) {
498 copy_(ans,s_aa);
499 return; //if we've made it this far, then s_n is absolutely guaranteed to be prime
500 }
501 }
502 }
503 }
504}
505
506//set b to an n-bit random BigInt. If s=1, then nth bit (most significant bit) is set to 1.
507//array b must be big enough to hold the result. Must have n>=1
508function randBigInt_(b,n,s) {
509 var i,a;
510 for (i=0;i<b.length;i++)
511 b[i]=0;
512 a=Math.floor((n-1)/bpe)+1; //# array elements to hold the BigInt
513 for (i=0;i<a;i++) {
514 b[i]=Math.floor(Math.random()*(1<<(bpe-1)));
515 }
516 b[a-1] &= (2<<((n-1)%bpe))-1;
517 if (s)
518 b[a-1] |= (1<<((n-1)%bpe));
519}
520
521//set x to the greatest common divisor of x and y.
522//x,y are bigInts with the same number of elements. y is destroyed.
523function GCD_(x,y) {
524 var i,xp,yp,A,B,C,D,q,sing;
525 if (T.length!=x.length)
526 T=dup(x);
527
528 sing=1;
529 while (sing) { //while y has nonzero elements other than y[0]
530 sing=0;
531 for (i=1;i<y.length;i++) //check if y has nonzero elements other than 0
532 if (y[i]) {
533 sing=1;
534 break;
535 }
536 if (!sing) break; //quit when y all zero elements except possibly y[0]
537
538 for (i=x.length;!x[i] && i>=0;i--); //find most significant element of x
539 xp=x[i];
540 yp=y[i];
541 A=1; B=0; C=0; D=1;
542 while ((yp+C) && (yp+D)) {
543 q =Math.floor((xp+A)/(yp+C));
544 qp=Math.floor((xp+B)/(yp+D));
545 if (q!=qp)
546 break;
547 t= A-q*C; A=C; C=t; // do (A,B,xp, C,D,yp) = (C,D,yp, A,B,xp) - q*(0,0,0, C,D,yp)
548 t= B-q*D; B=D; D=t;
549 t=xp-q*yp; xp=yp; yp=t;
550 }
551 if (B) {
552 copy_(T,x);
553 linComb_(x,y,A,B); //x=A*x+B*y
554 linComb_(y,T,D,C); //y=D*y+C*T
555 } else {
556 mod_(x,y);
557 copy_(T,x);
558 copy_(x,y);
559 copy_(y,T);
560 }
561 }
562 if (y[0]==0)
563 return;
564 t=modInt(x,y[0]);
565 copyInt_(x,y[0]);
566 y[0]=t;
567 while (y[0]) {
568 x[0]%=y[0];
569 t=x[0]; x[0]=y[0]; y[0]=t;
570 }
571}
572
573//do x=x**(-1) mod n, for bigInts x and n.
574//If no inverse exists, it sets x to zero and returns 0, else it returns 1.
575//The x array must be at least as large as the n array.
576function inverseMod_(x,n) {
577 var k=1+2*Math.max(x.length,n.length);
578
579 if(!(x[0]&1) && !(n[0]&1)) { //if both inputs are even, then inverse doesn't exist
580 copyInt_(x,0);
581 return 0;
582 }
583
584 if (eg_u.length!=k) {
585 eg_u=new Array(k);
586 eg_v=new Array(k);
587 eg_A=new Array(k);
588 eg_B=new Array(k);
589 eg_C=new Array(k);
590 eg_D=new Array(k);
591 }
592
593 copy_(eg_u,x);
594 copy_(eg_v,n);
595 copyInt_(eg_A,1);
596 copyInt_(eg_B,0);
597 copyInt_(eg_C,0);
598 copyInt_(eg_D,1);
599 for (;;) {
600 while(!(eg_u[0]&1)) { //while eg_u is even
601 halve_(eg_u);
602 if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if eg_A==eg_B==0 mod 2
603 halve_(eg_A);
604 halve_(eg_B);
605 } else {
606 add_(eg_A,n); halve_(eg_A);
607 sub_(eg_B,x); halve_(eg_B);
608 }
609 }
610
611 while (!(eg_v[0]&1)) { //while eg_v is even
612 halve_(eg_v);
613 if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if eg_C==eg_D==0 mod 2
614 halve_(eg_C);
615 halve_(eg_D);
616 } else {
617 add_(eg_C,n); halve_(eg_C);
618 sub_(eg_D,x); halve_(eg_D);
619 }
620 }
621
622 if (!greater(eg_v,eg_u)) { //eg_v <= eg_u
623 sub_(eg_u,eg_v);
624 sub_(eg_A,eg_C);
625 sub_(eg_B,eg_D);
626 } else { //eg_v > eg_u
627 sub_(eg_v,eg_u);
628 sub_(eg_C,eg_A);
629 sub_(eg_D,eg_B);
630 }
631
632 if (equalsInt(eg_u,0)) {
633 if (negative(eg_C)) //make sure answer is nonnegative
634 add_(eg_C,n);
635 copy_(x,eg_C);
636
637 if (!equalsInt(eg_v,1)) { //if GCD_(x,n)!=1, then there is no inverse
638 copyInt_(x,0);
639 return 0;
640 }
641 return 1;
642 }
643 }
644}
645
646//return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse
647function inverseModInt_(x,n) {
648 var a=1,b=0,t;
649 for (;;) {
650 if (x==1) return a;
651 if (x==0) return 0;
652 b-=a*Math.floor(n/x);
653 n%=x;
654
655 if (n==1) return b; //to avoid negatives, change this b to n-b, and each -= to +=
656 if (n==0) return 0;
657 a-=b*Math.floor(x/n);
658 x%=n;
659 }
660}
661
662//Given positive bigInts x and y, change the bigints v, a, and b to positive bigInts such that:
663// v = GCD_(x,y) = a*x-b*y
664//The bigInts v, a, b, must have exactly as many elements as the larger of x and y.
665function eGCD_(x,y,v,a,b) {
666 var g=0;
667 var k=Math.max(x.length,y.length);
668 if (eg_u.length!=k) {
669 eg_u=new Array(k);
670 eg_A=new Array(k);
671 eg_B=new Array(k);
672 eg_C=new Array(k);
673 eg_D=new Array(k);
674 }
675 while(!(x[0]&1) && !(y[0]&1)) { //while x and y both even
676 halve_(x);
677 halve_(y);
678 g++;
679 }
680 copy_(eg_u,x);
681 copy_(v,y);
682 copyInt_(eg_A,1);
683 copyInt_(eg_B,0);
684 copyInt_(eg_C,0);
685 copyInt_(eg_D,1);
686 for (;;) {
687 while(!(eg_u[0]&1)) { //while u is even
688 halve_(eg_u);
689 if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if A==B==0 mod 2
690 halve_(eg_A);
691 halve_(eg_B);
692 } else {
693 add_(eg_A,y); halve_(eg_A);
694 sub_(eg_B,x); halve_(eg_B);
695 }
696 }
697
698 while (!(v[0]&1)) { //while v is even
699 halve_(v);
700 if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if C==D==0 mod 2
701 halve_(eg_C);
702 halve_(eg_D);
703 } else {
704 add_(eg_C,y); halve_(eg_C);
705 sub_(eg_D,x); halve_(eg_D);
706 }
707 }
708
709 if (!greater(v,eg_u)) { //v<=u
710 sub_(eg_u,v);
711 sub_(eg_A,eg_C);
712 sub_(eg_B,eg_D);
713 } else { //v>u
714 sub_(v,eg_u);
715 sub_(eg_C,eg_A);
716 sub_(eg_D,eg_B);
717 }
718 if (equalsInt(eg_u,0)) {
719 if (negative(eg_C)) { //make sure a (C)is nonnegative
720 add_(eg_C,y);
721 sub_(eg_D,x);
722 }
723 multInt_(eg_D,-1); ///make sure b (D) is nonnegative
724 copy_(a,eg_C);
725 copy_(b,eg_D);
726 leftShift_(v,g);
727 return;
728 }
729 }
730}
731
732
733//is bigInt x negative?
734function negative(x) {
735 return ((x[x.length-1]>>(bpe-1))&1);
736}
737
738
739//is (x << (shift*bpe)) > y?
740//x and y are nonnegative bigInts
741//shift is a nonnegative integer
742function greaterShift(x,y,shift) {
743 var kx=x.length, ky=y.length;
744 k=((kx+shift)<ky) ? (kx+shift) : ky;
745 for (i=ky-1-shift; i<kx && i>=0; i++)
746 if (x[i]>0)
747 return 1; //if there are nonzeros in x to the left of the first column of y, then x is bigger
748 for (i=kx-1+shift; i<ky; i++)
749 if (y[i]>0)
750 return 0; //if there are nonzeros in y to the left of the first column of x, then x is not bigger
751 for (i=k-1; i>=shift; i--)
752 if (x[i-shift]>y[i]) return 1;
753 else if (x[i-shift]<y[i]) return 0;
754 return 0;
755}
756
757//is x > y? (x and y both nonnegative)
758function greater(x,y) {
759 var i;
760 var k=(x.length<y.length) ? x.length : y.length;
761
762 for (i=x.length;i<y.length;i++)
763 if (y[i])
764 return 0; //y has more digits
765
766 for (i=y.length;i<x.length;i++)
767 if (x[i])
768 return 1; //x has more digits
769
770 for (i=k-1;i>=0;i--)
771 if (x[i]>y[i])
772 return 1;
773 else if (x[i]<y[i])
774 return 0;
775 return 0;
776}
777
778//divide_ x by y giving quotient q and remainder r. (q=floor(x/y), r=x mod y). All 4 are bigints.
779//x must have at least one leading zero element.
780//y must be nonzero.
781//q and r must be arrays that are exactly the same length as x.
782//the x array must have at least as many elements as y.
783function divide_(x,y,q,r) {
784 var kx, ky;
785 var i,j,y1,y2,c,a,b;
786 copy_(r,x);
787 for (ky=y.length;y[ky-1]==0;ky--); //kx,ky is number of elements in x,y, not including leading zeros
788 for (kx=r.length;r[kx-1]==0 && kx>ky;kx--);
789
790 //normalize: ensure the most significant element of y has its highest bit set
791 b=y[ky-1];
792 for (a=0; b; a++)
793 b>>=1;
794 a=bpe-a; //a is how many bits to shift so that the high order bit of y is leftmost in its array element
795 leftShift_(y,a); //multiply both by 1<<a now, then divide_ both by that at the end
796 leftShift_(r,a);
797
798 copyInt_(q,0); // q=0
799 while (!greaterShift(y,r,kx-ky)) { // while (leftShift_(y,kx-ky) <= r) {
800 subShift_(r,y,kx-ky); // r=r-leftShift_(y,kx-ky)
801 q[kx-ky]++; // q[kx-ky]++;
802 } // }
803
804 for (i=kx-1; i>=ky; i--) {
805 if (r[i]==y[ky-1])
806 q[i-ky]=mask;
807 else
808 q[i-ky]=Math.floor((r[i]*radix+r[i-1])/y[ky-1]);
809
810 //The following for(;;) loop is equivalent to the commented while loop,
811 //except that the uncommented version avoids overflow.
812 //The commented loop comes from HAC, which assumes r[-1]==y[-1]==0
813 // while (q[i-ky]*(y[ky-1]*radix+y[ky-2]) > r[i]*radix*radix+r[i-1]*radix+r[i-2])
814 // q[i-ky]--;
815 for (;;) {
816 y2=(ky>1 ? y[ky-2] : 0)*q[i-ky];
817 c=y2>>bpe;
818 y2=y2 & mask;
819 y1=c+q[i-ky]*y[ky-1];
820 c=y1>>bpe;
821 y1=y1 & mask;
822
823 if (c==r[i] ? y1==r[i-1] ? y2>(i>1 ? r[i-2] : 0) : y1>r[i-1] : c>r[i])
824 q[i-ky]--;
825 else
826 break;
827 }
828
829 linCombShift_(r,y,-q[i-ky],i-ky); //r=r-q[i-ky]*leftShift_(y,i-ky)
830 if (negative(r)) {
831 addShift_(r,y,i-ky); //r=r+leftShift_(y,i-ky)
832 q[i-ky]--;
833 }
834 }
835
836 rightShift_(y,a); //undo the normalization step
837 rightShift_(r,a); //undo the normalization step
838}
839
840//do carries and borrows so each element of the bigInt x fits in bpe bits.
841function carry_(x) {
842 var i,k,c,b;
843 k=x.length;
844 c=0;
845 for (i=0;i<k;i++) {
846 c+=x[i];
847 b=0;
848 if (c<0) {
849 b=-(c>>bpe);
850 c+=b*radix;
851 }
852 x[i]=c & mask;
853 c=(c>>bpe)-b;
854 }
855}
856
857//return x mod n for bigInt x and integer n.
858function modInt(x,n) {
859 var i,c=0;
860 for (i=x.length-1; i>=0; i--)
861 c=(c*radix+x[i])%n;
862 return c;
863}
864
865//convert the integer t into a bigInt with at least the given number of bits.
866//the returned array stores the bigInt in bpe-bit chunks, little endian (buff[0] is least significant word)
867//Pad the array with leading zeros so that it has at least minSize elements.
868//There will always be at least one leading 0 element.
869function int2bigInt(t,bits,minSize) {
870 var i,k;
871 k=Math.ceil(bits/bpe)+1;
872 k=minSize>k ? minSize : k;
873 buff=new Array(k);
874 copyInt_(buff,t);
875 return buff;
876}
877
878//return the bigInt given a string representation in a given base.
879//Pad the array with leading zeros so that it has at least minSize elements.
880//If base=-1, then it reads in a space-separated list of array elements in decimal.
881//The array will always have at least one leading zero, unless base=-1.
882function str2bigInt(s,base,minSize) {
883 var d, i, j, x, y, kk;
884 var k=s.length;
885 if (base==-1) { //comma-separated list of array elements in decimal
886 x=new Array(0);
887 for (;;) {
888 y=new Array(x.length+1);
889 for (i=0;i<x.length;i++)
890 y[i+1]=x[i];
891 y[0]=parseInt(s,10);
892 x=y;
893 d=s.indexOf(',',0);
894 if (d<1)
895 break;
896 s=s.substring(d+1);
897 if (s.length==0)
898 break;
899 }
900 if (x.length<minSize) {
901 y=new Array(minSize);
902 copy_(y,x);
903 return y;
904 }
905 return x;
906 }
907
908 x=int2bigInt(0,base*k,0);
909 for (i=0;i<k;i++) {
910 d=digitsStr.indexOf(s.substring(i,i+1),0);
911 if (base<=36 && d>=36) //convert lowercase to uppercase if base<=36
912 d-=26;
913 if (d<base && d>=0) { //ignore illegal characters
914 multInt_(x,base);
915 addInt_(x,d);
916 }
917 }
918
919 for (k=x.length;k>0 && !x[k-1];k--); //strip off leading zeros
920 k=minSize>k+1 ? minSize : k+1;
921 y=new Array(k);
922 kk=k<x.length ? k : x.length;
923 for (i=0;i<kk;i++)
924 y[i]=x[i];
925 for (;i<k;i++)
926 y[i]=0;
927 return y;
928}
929
930//is bigint x equal to integer y?
931//y must have less than bpe bits
932function equalsInt(x,y) {
933 var i;
934 if (x[0]!=y)
935 return 0;
936 for (i=1;i<x.length;i++)
937 if (x[i])
938 return 0;
939 return 1;
940}
941
942//are bigints x and y equal?
943//this works even if x and y are different lengths and have arbitrarily many leading zeros
944function equals(x,y) {
945 var i;
946 var k=x.length<y.length ? x.length : y.length;
947 for (i=0;i<k;i++)
948 if (x[i]!=y[i])
949 return 0;
950 if (x.length>y.length) {
951 for (;i<x.length;i++)
952 if (x[i])
953 return 0;
954 } else {
955 for (;i<y.length;i++)
956 if (y[i])
957 return 0;
958 }
959 return 1;
960}
961
962//is the bigInt x equal to zero?
963function isZero(x) {
964 var i;
965 for (i=0;i<x.length;i++)
966 if (x[i])
967 return 0;
968 return 1;
969}
970
971//convert a bigInt into a string in a given base, from base 2 up to base 95.
972//Base -1 prints the contents of the array representing the number.
973function bigInt2str(x,base) {
974 var i,t,s="";
975
976 if (s6.length!=x.length)
977 s6=dup(x);
978 else
979 copy_(s6,x);
980
981 if (base==-1) { //return the list of array contents
982 for (i=x.length-1;i>0;i--)
983 s+=x[i]+',';
984 s+=x[0];
985 }
986 else { //return it in the given base
987 while (!isZero(s6)) {
988 t=divInt_(s6,base); //t=s6 % base; s6=floor(s6/base);
989 s=digitsStr.substring(t,t+1)+s;
990 }
991 }
992 if (s.length==0)
993 s="0";
994 return s;
995}
996
997//returns a duplicate of bigInt x
998function dup(x) {
999 var i;
1000 buff=new Array(x.length);
1001 copy_(buff,x);
1002 return buff;
1003}
1004
1005//do x=y on bigInts x and y. x must be an array at least as big as y (not counting the leading zeros in y).
1006function copy_(x,y) {
1007 var i;
1008 var k=x.length<y.length ? x.length : y.length;
1009 for (i=0;i<k;i++)
1010 x[i]=y[i];
1011 for (i=k;i<x.length;i++)
1012 x[i]=0;
1013}
1014
1015//do x=y on bigInt x and integer y.
1016function copyInt_(x,n) {
1017 var i,c;
1018 for (c=n,i=0;i<x.length;i++) {
1019 x[i]=c & mask;
1020 c>>=bpe;
1021 }
1022}
1023
1024//do x=x+n where x is a bigInt and n is an integer.
1025//x must be large enough to hold the result.
1026function addInt_(x,n) {
1027 var i,k,c,b;
1028 x[0]+=n;
1029 k=x.length;
1030 c=0;
1031 for (i=0;i<k;i++) {
1032 c+=x[i];
1033 b=0;
1034 if (c<0) {
1035 b=-(c>>bpe);
1036 c+=b*radix;
1037 }
1038 x[i]=c & mask;
1039 c=(c>>bpe)-b;
1040 if (!c) return; //stop carrying as soon as the carry_ is zero
1041 }
1042}
1043
1044//right shift bigInt x by n bits. 0 <= n < bpe.
1045function rightShift_(x,n) {
1046 var i;
1047 var k=Math.floor(n/bpe);
1048 if (k) {
1049 for (i=0;i<x.length-k;i++) //right shift x by k elements
1050 x[i]=x[i+k];
1051 for (;i<x.length;i++)
1052 x[i]=0;
1053 n%=bpe;
1054 }
1055 for (i=0;i<x.length-1;i++) {
1056 x[i]=mask & ((x[i+1]<<(bpe-n)) | (x[i]>>n));
1057 }
1058 x[i]>>=n;
1059}
1060
1061//do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement
1062function halve_(x) {
1063 var i;
1064 for (i=0;i<x.length-1;i++) {
1065 x[i]=mask & ((x[i+1]<<(bpe-1)) | (x[i]>>1));
1066 }
1067 x[i]=(x[i]>>1) | (x[i] & (radix>>1)); //most significant bit stays the same
1068}
1069
1070//left shift bigInt x by n bits.
1071function leftShift_(x,n) {
1072 var i;
1073 var k=Math.floor(n/bpe);
1074 if (k) {
1075 for (i=x.length; i>=k; i--) //left shift x by k elements
1076 x[i]=x[i-k];
1077 for (;i>=0;i--)
1078 x[i]=0;
1079 n%=bpe;
1080 }
1081 if (!n)
1082 return;
1083 for (i=x.length-1;i>0;i--) {
1084 x[i]=mask & ((x[i]<<n) | (x[i-1]>>(bpe-n)));
1085 }
1086 x[i]=mask & (x[i]<<n);
1087}
1088
1089//do x=x*n where x is a bigInt and n is an integer.
1090//x must be large enough to hold the result.
1091function multInt_(x,n) {
1092 var i,k,c,b;
1093 if (!n)
1094 return;
1095 k=x.length;
1096 c=0;
1097 for (i=0;i<k;i++) {
1098 c+=x[i]*n;
1099 b=0;
1100 if (c<0) {
1101 b=-(c>>bpe);
1102 c+=b*radix;
1103 }
1104 x[i]=c & mask;
1105 c=(c>>bpe)-b;
1106 }
1107}
1108
1109//do x=floor(x/n) for bigInt x and integer n, and return the remainder
1110function divInt_(x,n) {
1111 var i,r=0,s;
1112 for (i=x.length-1;i>=0;i--) {
1113 s=r*radix+x[i];
1114 x[i]=Math.floor(s/n);
1115 r=s%n;
1116 }
1117 return r;
1118}
1119
1120//do the linear combination x=a*x+b*y for bigInts x and y, and integers a and b.
1121//x must be large enough to hold the answer.
1122function linComb_(x,y,a,b) {
1123 var i,c,k,kk;
1124 k=x.length<y.length ? x.length : y.length;
1125 kk=x.length;
1126 for (c=0,i=0;i<k;i++) {
1127 c+=a*x[i]+b*y[i];
1128 x[i]=c & mask;
1129 c>>=bpe;
1130 }
1131 for (i=k;i<kk;i++) {
1132 c+=a*x[i];
1133 x[i]=c & mask;
1134 c>>=bpe;
1135 }
1136}
1137
1138//do the linear combination x=a*x+b*(y<<(ys*bpe)) for bigInts x and y, and integers a, b and ys.
1139//x must be large enough to hold the answer.
1140function linCombShift_(x,y,b,ys) {
1141 var i,c,k,kk;
1142 k=x.length<ys+y.length ? x.length : ys+y.length;
1143 kk=x.length;
1144 for (c=0,i=ys;i<k;i++) {
1145 c+=x[i]+b*y[i-ys];
1146 x[i]=c & mask;
1147 c>>=bpe;
1148 }
1149 for (i=k;c && i<kk;i++) {
1150 c+=x[i];
1151 x[i]=c & mask;
1152 c>>=bpe;
1153 }
1154}
1155
1156//do x=x+(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
1157//x must be large enough to hold the answer.
1158function addShift_(x,y,ys) {
1159 var i,c,k,kk;
1160 k=x.length<ys+y.length ? x.length : ys+y.length;
1161 kk=x.length;
1162 for (c=0,i=ys;i<k;i++) {
1163 c+=x[i]+y[i-ys];
1164 x[i]=c & mask;
1165 c>>=bpe;
1166 }
1167 for (i=k;c && i<kk;i++) {
1168 c+=x[i];
1169 x[i]=c & mask;
1170 c>>=bpe;
1171 }
1172}
1173
1174//do x=x-(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
1175//x must be large enough to hold the answer.
1176function subShift_(x,y,ys) {
1177 var i,c,k,kk;
1178 k=x.length<ys+y.length ? x.length : ys+y.length;
1179 kk=x.length;
1180 for (c=0,i=ys;i<k;i++) {
1181 c+=x[i]-y[i-ys];
1182 x[i]=c & mask;
1183 c>>=bpe;
1184 }
1185 for (i=k;c && i<kk;i++) {
1186 c+=x[i];
1187 x[i]=c & mask;
1188 c>>=bpe;
1189 }
1190}
1191
1192//do x=x-y for bigInts x and y.
1193//x must be large enough to hold the answer.
1194//negative answers will be 2s complement
1195function sub_(x,y) {
1196 var i,c,k,kk;
1197 k=x.length<y.length ? x.length : y.length;
1198 for (c=0,i=0;i<k;i++) {
1199 c+=x[i]-y[i];
1200 x[i]=c & mask;
1201 c>>=bpe;
1202 }
1203 for (i=k;c && i<x.length;i++) {
1204 c+=x[i];
1205 x[i]=c & mask;
1206 c>>=bpe;
1207 }
1208}
1209
1210//do x=x+y for bigInts x and y.
1211//x must be large enough to hold the answer.
1212function add_(x,y) {
1213 var i,c,k,kk;
1214 k=x.length<y.length ? x.length : y.length;
1215 for (c=0,i=0;i<k;i++) {
1216 c+=x[i]+y[i];
1217 x[i]=c & mask;
1218 c>>=bpe;
1219 }
1220 for (i=k;c && i<x.length;i++) {
1221 c+=x[i];
1222 x[i]=c & mask;
1223 c>>=bpe;
1224 }
1225}
1226
1227//do x=x*y for bigInts x and y. This is faster when y<x.
1228function mult_(x,y) {
1229 var i;
1230 if (ss.length!=2*x.length)
1231 ss=new Array(2*x.length);
1232 copyInt_(ss,0);
1233 for (i=0;i<y.length;i++)
1234 if (y[i])
1235 linCombShift_(ss,x,y[i],i); //ss=1*ss+y[i]*(x<<(i*bpe))
1236 copy_(x,ss);
1237}
1238
1239//do x=x mod n for bigInts x and n.
1240function mod_(x,n) {
1241 if (s4.length!=x.length)
1242 s4=dup(x);
1243 else
1244 copy_(s4,x);
1245 if (s5.length!=x.length)
1246 s5=dup(x);
1247 divide_(s4,n,s5,x); //x = remainder of s4 / n
1248}
1249
1250//do x=x*y mod n for bigInts x,y,n.
1251//for greater speed, let y<x.
1252function multMod_(x,y,n) {
1253 var i;
1254 if (s0.length!=2*x.length)
1255 s0=new Array(2*x.length);
1256 copyInt_(s0,0);
1257 for (i=0;i<y.length;i++)
1258 if (y[i])
1259 linCombShift_(s0,x,y[i],i); //s0=1*s0+y[i]*(x<<(i*bpe))
1260 mod_(s0,n);
1261 copy_(x,s0);
1262}
1263
1264//do x=x*x mod n for bigInts x,n.
1265function squareMod_(x,n) {
1266 var i,j,d,c,kx,kn,k;
1267 for (kx=x.length; kx>0 && !x[kx-1]; kx--); //ignore leading zeros in x
1268 k=kx>n.length ? 2*kx : 2*n.length; //k=# elements in the product, which is twice the elements in the larger of x and n
1269 if (s0.length!=k)
1270 s0=new Array(k);
1271 copyInt_(s0,0);
1272 for (i=0;i<kx;i++) {
1273 c=s0[2*i]+x[i]*x[i];
1274 s0[2*i]=c & mask;
1275 c>>=bpe;
1276 for (j=i+1;j<kx;j++) {
1277 c=s0[i+j]+2*x[i]*x[j]+c;
1278 s0[i+j]=(c & mask);
1279 c>>=bpe;
1280 }
1281 s0[i+kx]=c;
1282 }
1283 mod_(s0,n);
1284 copy_(x,s0);
1285}
1286
1287//return x with exactly k leading zero elements
1288function trim(x,k) {
1289 var i,y;
1290 for (i=x.length; i>0 && !x[i-1]; i--);
1291 y=new Array(i+k);
1292 copy_(y,x);
1293 return y;
1294}
1295
1296//do x=x**y mod n, where x,y,n are bigInts and ** is exponentiation. 0**0=1.
1297//this is faster when n is odd. x usually needs to have as many elements as n.
1298function powMod_(x,y,n) {
1299 var k1,k2,kn,np;
1300 if(s7.length!=n.length)
1301 s7=dup(n);
1302
1303 //for even modulus, use a simple square-and-multiply algorithm,
1304 //rather than using the more complex Montgomery algorithm.
1305 if ((n[0]&1)==0) {
1306 copy_(s7,x);
1307 copyInt_(x,1);
1308 while(!equalsInt(y,0)) {
1309 if (y[0]&1)
1310 multMod_(x,s7,n);
1311 divInt_(y,2);
1312 squareMod_(s7,n);
1313 }
1314 return;
1315 }
1316
1317 //calculate np from n for the Montgomery multiplications
1318 copyInt_(s7,0);
1319 for (kn=n.length;kn>0 && !n[kn-1];kn--);
1320 np=radix-inverseModInt_(modInt(n,radix),radix);
1321 s7[kn]=1;
1322 multMod_(x ,s7,n); // x = x * 2**(kn*bp) mod n
1323
1324 if (s3.length!=x.length)
1325 s3=dup(x);
1326 else
1327 copy_(s3,x);
1328
1329 for (k1=y.length-1;k1>0 & !y[k1]; k1--); //k1=first nonzero element of y
1330 if (y[k1]==0) { //anything to the 0th power is 1
1331 copyInt_(x,1);
1332 return;
1333 }
1334 for (k2=1<<(bpe-1);k2 && !(y[k1] & k2); k2>>=1); //k2=position of first 1 bit in y[k1]
1335 for (;;) {
1336 if (!(k2>>=1)) { //look at next bit of y
1337 k1--;
1338 if (k1<0) {
1339 mont_(x,one,n,np);
1340 return;
1341 }
1342 k2=1<<(bpe-1);
1343 }
1344 mont_(x,x,n,np);
1345
1346 if (k2 & y[k1]) //if next bit is a 1
1347 mont_(x,s3,n,np);
1348 }
1349}
1350
1351//do x=x*y*Ri mod n for bigInts x,y,n,
1352// where Ri = 2**(-kn*bpe) mod n, and kn is the
1353// number of elements in the n array, not
1354// counting leading zeros.
1355//x must be large enough to hold the answer.
1356//It's OK if x and y are the same variable.
1357//must have:
1358// x,y < n
1359// n is odd
1360// np = -(n^(-1)) mod radix
1361function mont_(x,y,n,np) {
1362 var i,j,c,ui,t;
1363 var kn=n.length;
1364 var ky=y.length;
1365
1366 if (sa.length!=kn)
1367 sa=new Array(kn);
1368
1369 for (;kn>0 && n[kn-1]==0;kn--); //ignore leading zeros of n
1370 //this function sometimes gives wrong answers when the next line is uncommented
1371 //for (;ky>0 && y[ky-1]==0;ky--); //ignore leading zeros of y
1372
1373 copyInt_(sa,0);
1374
1375 //the following loop consumes 95% of the runtime for randTruePrime_() and powMod_() for large keys
1376 for (i=0; i<kn; i++) {
1377 t=sa[0]+x[i]*y[0];
1378 ui=((t & mask) * np) & mask; //the inner "& mask" is needed on Macintosh MSIE, but not windows MSIE
1379 c=(t+ui*n[0]) >> bpe;
1380 t=x[i];
1381
1382 //do sa=(sa+x[i]*y+ui*n)/b where b=2**bpe
1383 for (j=1;j<ky;j++) {
1384 c+=sa[j]+t*y[j]+ui*n[j];
1385 sa[j-1]=c & mask;
1386 c>>=bpe;
1387 }
1388 for (;j<kn;j++) {
1389 c+=sa[j]+ui*n[j];
1390 sa[j-1]=c & mask;
1391 c>>=bpe;
1392 }
1393 sa[j-1]=c & mask;
1394 }
1395
1396 if (!greater(n,sa))
1397 sub_(sa,n);
1398 copy_(x,sa);
1399}
1400
1401
1402
1403
1404//#############################################################################
1405//#############################################################################
1406//#############################################################################
1407//#############################################################################
1408//#############################################################################
1409//#############################################################################
1410//#############################################################################
1411
1412
1413
1414
1415
1416//#############################################################################
1417
1418Clipperz.Crypto.BigInt = function (aValue, aBase) {
1419 varbase;
1420 varvalue;
1421
1422 if (typeof(aValue) == 'object') {
1423 this._internalValue = aValue;
1424 } else {
1425 if (typeof(aValue) == 'undefined') {
1426 value = "0";
1427 } else {
1428 value = aValue + "";
1429 }
1430
1431 if (typeof(aBase) == 'undefined') {
1432 base = 10;
1433 } else {
1434 base = aBase;
1435 }
1436
1437 this._internalValue = str2bigInt(value, base, 1, 1);
1438 }
1439
1440 return this;
1441}
1442
1443//=============================================================================
1444
1445MochiKit.Base.update(Clipperz.Crypto.BigInt.prototype, {
1446
1447 'clone': function() {
1448 return new Clipperz.Crypto.BigInt(this.internalValue());
1449 },
1450
1451 //-------------------------------------------------------------------------
1452
1453 'internalValue': function () {
1454 return this._internalValue;
1455 },
1456
1457 //-------------------------------------------------------------------------
1458
1459 'isBigInt': true,
1460
1461 //-------------------------------------------------------------------------
1462
1463 'toString': function(aBase) {
1464 return this.asString(aBase);
1465 },
1466
1467 //-------------------------------------------------------------------------
1468
1469 'asString': function (aBase, minimumLength) {
1470 varresult;
1471 varbase;
1472
1473 if (typeof(aBase) == 'undefined') {
1474 base = 10;
1475 } else {
1476 base = aBase;
1477 }
1478
1479 result = bigInt2str(this.internalValue(), base).toLowerCase();
1480
1481 if ((typeof(minimumLength) != 'undefined') && (result.length < minimumLength)) {
1482 var i, c;
1483 //MochiKit.Logging.logDebug(">>> FIXING BigInt.asString length issue")
1484 c = (minimumLength - result.length);
1485 for (i=0; i<c; i++) {
1486 result = '0' + result;
1487 }
1488 }
1489
1490 return result;
1491 },
1492
1493 //-------------------------------------------------------------------------
1494
1495 'asByteArray': function() {
1496 return new Clipperz.ByteArray("0x" + this.asString(16), 16);
1497 },
1498
1499 //-------------------------------------------------------------------------
1500
1501 'equals': function (aValue) {
1502 var result;
1503
1504 if (aValue.isBigInt) {
1505 result = equals(this.internalValue(), aValue.internalValue());
1506 } else if (typeof(aValue) == "number") {
1507 result = equalsInt(this.internalValue(), aValue);
1508 } else {
1509 throw Clipperz.Crypt.BigInt.exception.UnknownType;
1510 }
1511
1512 return result;
1513 },
1514
1515 //-------------------------------------------------------------------------
1516
1517 'compare': function(aValue) {
1518/*
1519 var result;
1520 var thisAsString;
1521 var aValueAsString;
1522
1523 thisAsString = this.asString(10);
1524 aValueAsString = aValue.asString(10);
1525
1526 result = MochiKit.Base.compare(thisAsString.length, aValueAsString.length);
1527 if (result == 0) {
1528 result = MochiKit.Base.compare(thisAsString, aValueAsString);
1529 }
1530
1531 return result;
1532*/
1533 var result;
1534
1535 if (equals(this.internalValue(), aValue.internalValue())) {
1536 result = 0;
1537 } else if (greater(this.internalValue(), aValue.internalValue())) {
1538 result = 1;
1539 } else {
1540 result = -1;
1541 }
1542
1543 return result;
1544 },
1545
1546 //-------------------------------------------------------------------------
1547
1548 'add': function (aValue) {
1549 var result;
1550
1551 if (aValue.isBigInt) {
1552 result = add(this.internalValue(), aValue.internalValue());
1553 } else {
1554 result = addInt(this.internalValue(), aValue);
1555 }
1556
1557 return new Clipperz.Crypto.BigInt(result);
1558 },
1559
1560 //-------------------------------------------------------------------------
1561
1562 'subtract': function (aValue) {
1563 var result;
1564 var value;
1565
1566 if (aValue.isBigInt) {
1567 value = aValue;
1568 } else {
1569 value = new Clipperz.Crypto.BigInt(aValue);
1570 }
1571
1572 result = sub(this.internalValue(), value.internalValue());
1573
1574 return new Clipperz.Crypto.BigInt(result);
1575 },
1576
1577 //-------------------------------------------------------------------------
1578
1579 'multiply': function (aValue, aModule) {
1580 var result;
1581 var value;
1582
1583 if (aValue.isBigInt) {
1584 value = aValue;
1585 } else {
1586 value = new Clipperz.Crypto.BigInt(aValue);
1587 }
1588
1589 if (typeof(aModule) == 'undefined') {
1590 result = mult(this.internalValue(), value.internalValue());
1591 } else {
1592 if (greater(this.internalValue(), value.internalValue())) {
1593 result = multMod(this.internalValue(), value.internalValue(), aModule);
1594 } else {
1595 result = multMod(value.internalValue(), this.internalValue(), aModule);
1596 }
1597 }
1598
1599 return new Clipperz.Crypto.BigInt(result);
1600 },
1601
1602 //-------------------------------------------------------------------------
1603
1604 'module': function (aModule) {
1605 varresult;
1606 var module;
1607
1608 if (aModule.isBigInt) {
1609 module = aModule;
1610 } else {
1611 module = new Clipperz.Crypto.BigInt(aModule);
1612 }
1613
1614 result = mod(this.internalValue(), module.internalValue());
1615
1616 return new Clipperz.Crypto.BigInt(result);
1617 },
1618
1619 //-------------------------------------------------------------------------
1620
1621 'powerModule': function(aValue, aModule) {
1622 varresult;
1623 varvalue;
1624 var module;
1625
1626 if (aValue.isBigInt) {
1627 value = aValue;
1628 } else {
1629 value = new Clipperz.Crypto.BigInt(aValue);
1630 }
1631
1632 if (aModule.isBigInt) {
1633 module = aModule;
1634 } else {
1635 module = new Clipperz.Crypto.BigInt(aModule);
1636 }
1637
1638 if (aValue == -1) {
1639 result = inverseMod(this.internalValue(), module.internalValue());
1640 } else {
1641 result = powMod(this.internalValue(), value.internalValue(), module.internalValue());
1642 }
1643
1644 return new Clipperz.Crypto.BigInt(result);
1645 },
1646
1647 //-------------------------------------------------------------------------
1648
1649 'xor': function(aValue) {
1650 var result;
1651 varthisByteArray;
1652 var aValueByteArray;
1653 var xorArray;
1654
1655 thisByteArray = new Clipperz.ByteArray("0x" + this.asString(16), 16);
1656 aValueByteArray = new Clipperz.ByteArray("0x" + aValue.asString(16), 16);
1657 xorArray = thisByteArray.xorMergeWithBlock(aValueByteArray, 'right');
1658 result = new Clipperz.Crypto.BigInt(xorArray.toHexString(), 16);
1659
1660 return result;
1661 },
1662
1663 //-------------------------------------------------------------------------
1664
1665 'shiftLeft': function(aNumberOfBitsToShift) {
1666 var result;
1667 var internalResult;
1668 var wholeByteToShift;
1669 var bitsLeftToShift;
1670
1671 wholeByteToShift = Math.floor(aNumberOfBitsToShift / 8);
1672 bitsLeftToShift = aNumberOfBitsToShift % 8;
1673
1674 if (wholeByteToShift == 0) {
1675 internalResult = this.internalValue();
1676 } else {
1677 var hexValue;
1678 var i,c;
1679
1680 hexValue = this.asString(16);
1681 c = wholeByteToShift;
1682 for (i=0; i<c; i++) {
1683 hexValue += "00";
1684 }
1685 internalResult = str2bigInt(hexValue, 16, 1, 1);
1686 }
1687
1688 if (bitsLeftToShift > 0) {
1689 leftShift_(internalResult, bitsLeftToShift);
1690 }
1691 result = new Clipperz.Crypto.BigInt(internalResult);
1692
1693 return result;
1694 },
1695
1696 //-------------------------------------------------------------------------
1697
1698 'bitSize': function() {
1699 return bitSize(this.internalValue());
1700 },
1701
1702 //-------------------------------------------------------------------------
1703
1704 'isBitSet': function(aBitPosition) {
1705 var result;
1706
1707 if (this.asByteArray().bitAtIndex(aBitPosition) == 0) {
1708 result = false;
1709 } else {
1710 result = true;
1711 };
1712
1713 return result;
1714 },
1715
1716 //-------------------------------------------------------------------------
1717 __syntaxFix__: "syntax fix"
1718
1719});
1720
1721//#############################################################################
1722
1723Clipperz.Crypto.BigInt.randomPrime = function(aBitSize) {
1724 return new Clipperz.Crypto.BigInt(randTruePrime(aBitSize));
1725}
1726
1727//#############################################################################
1728//#############################################################################
1729
1730Clipperz.Crypto.BigInt.ZERO = new Clipperz.Crypto.BigInt(0);
1731
1732//#############################################################################
1733
1734Clipperz.Crypto.BigInt.equals = function(a, b) {
1735 return a.equals(b);
1736}
1737
1738Clipperz.Crypto.BigInt.add = function(a, b) {
1739 return a.add(b);
1740}
1741
1742Clipperz.Crypto.BigInt.subtract = function(a, b) {
1743 return a.subtract(b);
1744}
1745
1746Clipperz.Crypto.BigInt.multiply = function(a, b, module) {
1747 return a.multiply(b, module);
1748}
1749
1750Clipperz.Crypto.BigInt.module = function(a, module) {
1751 return a.module(module);
1752}
1753
1754Clipperz.Crypto.BigInt.powerModule = function(a, b, module) {
1755 return a.powerModule(b, module);
1756}
1757
1758Clipperz.Crypto.BigInt.exception = {
1759 UnknownType: new MochiKit.Base.NamedError("Clipperz.Crypto.BigInt.exception.UnknownType")
1760}
diff --git a/frontend/beta/js/Clipperz/Crypto/BigInt_scoped.js b/frontend/beta/js/Clipperz/Crypto/BigInt_scoped.js
new file mode 100644
index 0000000..e91e823
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/Crypto/BigInt_scoped.js
@@ -0,0 +1,1649 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
30if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
31
32if (typeof(Leemon) == 'undefined') { Leemon = {}; }
33if (typeof(Baird.Crypto) == 'undefined') { Baird.Crypto = {}; }
34if (typeof(Baird.Crypto.BigInt) == 'undefined') { Baird.Crypto.BigInt = {}; }
35
36
37//#############################################################################
38 //Downloaded on March 05, 2007 from http://www.leemon.com/crypto/BigInt.js
39//#############################################################################
40
41////////////////////////////////////////////////////////////////////////////////////////
42// Big Integer Library v. 5.0
43// Created 2000, last modified 2006
44// Leemon Baird
45// www.leemon.com
46//
47// This file is public domain. You can use it for any purpose without restriction.
48// I do not guarantee that it is correct, so use it at your own risk. If you use
49// it for something interesting, I'd appreciate hearing about it. If you find
50// any bugs or make any improvements, I'd appreciate hearing about those too.
51// It would also be nice if my name and address were left in the comments.
52// But none of that is required.
53//
54// This code defines a bigInt library for arbitrary-precision integers.
55// A bigInt is an array of integers storing the value in chunks of bpe bits,
56// little endian (buff[0] is the least significant word).
57// Negative bigInts are stored two's complement.
58// Some functions assume their parameters have at least one leading zero element.
59// Functions with an underscore at the end of the name have unpredictable behavior in case of overflow,
60// so the caller must make sure overflow won't happen.
61// For each function where a parameter is modified, that same
62// variable must not be used as another argument too.
63// So, you cannot square x by doing multMod_(x,x,n).
64// You must use squareMod_(x,n) instead, or do y=dup(x); multMod_(x,y,n).
65//
66// These functions are designed to avoid frequent dynamic memory allocation in the inner loop.
67// For most functions, if it needs a BigInt as a local variable it will actually use
68// a global, and will only allocate to it when it's not the right size. This ensures
69// that when a function is called repeatedly with same-sized parameters, it only allocates
70// memory on the first call.
71//
72// Note that for cryptographic purposes, the calls to Math.random() must
73// be replaced with calls to a better pseudorandom number generator.
74//
75// In the following, "bigInt" means a bigInt with at least one leading zero element,
76// and "integer" means a nonnegative integer less than radix. In some cases, integer
77// can be negative. Negative bigInts are 2s complement.
78//
79// The following functions do not modify their inputs, but dynamically allocate memory every time they are called:
80//
81// function bigInt2str(x,base) //convert a bigInt into a string in a given base, from base 2 up to base 95
82// function dup(x) //returns a copy of bigInt x
83// function findPrimes(n) //return array of all primes less than integer n
84// function int2bigInt(t,n,m) //convert integer t to a bigInt with at least n bits and m array elements
85// function str2bigInt(s,b,n,m) //convert string s in base b to a bigInt with at least n bits and m array elements
86// function trim(x,k) //return a copy of x with exactly k leading zero elements
87//
88// The following functions do not modify their inputs, so there is never a problem with the result being too big:
89//
90// function bitSize(x) //returns how many bits long the bigInt x is, not counting leading zeros
91// function equals(x,y) //is the bigInt x equal to the bigint y?
92// function equalsInt(x,y) //is bigint x equal to integer y?
93// function greater(x,y) //is x>y? (x and y are nonnegative bigInts)
94// function greaterShift(x,y,shift)//is (x <<(shift*bpe)) > y?
95// function isZero(x) //is the bigInt x equal to zero?
96// function millerRabin(x,b) //does one round of Miller-Rabin base integer b say that bigInt x is possibly prime (as opposed to definitely composite)?
97// function modInt(x,n) //return x mod n for bigInt x and integer n.
98// function negative(x) //is bigInt x negative?
99//
100// The following functions do not modify their inputs, but allocate memory and call functions with underscores
101//
102// function add(x,y) //return (x+y) for bigInts x and y.
103// function addInt(x,n) //return (x+n) where x is a bigInt and n is an integer.
104// function expand(x,n) //return a copy of x with at least n elements, adding leading zeros if needed
105// function inverseMod(x,n) //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null
106// function mod(x,n) //return a new bigInt equal to (x mod n) for bigInts x and n.
107// function mult(x,y) //return x*y for bigInts x and y. This is faster when y<x.
108// function multMod(x,y,n) //return (x*y mod n) for bigInts x,y,n. For greater speed, let y<x.
109// function powMod(x,y,n) //return (x**y mod n) where x,y,n are bigInts and ** is exponentiation. 0**0=1. Faster for odd n.
110// function randTruePrime(k) //return a new, random, k-bit, true prime using Maurer's algorithm.
111// function sub(x,y) //return (x-y) for bigInts x and y. Negative answers will be 2s complement
112//
113// The following functions write a bigInt result to one of the parameters, but
114// the result is never bigger than the original, so there can't be overflow problems:
115//
116// function divInt_(x,n) //do x=floor(x/n) for bigInt x and integer n, and return the remainder
117// function GCD_(x,y) //set x to the greatest common divisor of bigInts x and y, (y is destroyed).
118// function halve_(x) //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement
119// function mod_(x,n) //do x=x mod n for bigInts x and n.
120// function rightShift_(x,n) //right shift bigInt x by n bits. 0 <= n < bpe.
121//
122// The following functions write a bigInt result to one of the parameters. The caller is responsible for
123// ensuring it is large enough to hold the result.
124//
125// function addInt_(x,n) //do x=x+n where x is a bigInt and n is an integer
126// function add_(x,y) //do x=x+y for bigInts x and y
127// function addShift_(x,y,ys) //do x=x+(y<<(ys*bpe))
128// function copy_(x,y) //do x=y on bigInts x and y
129// function copyInt_(x,n) //do x=n on bigInt x and integer n
130// function carry_(x) //do carries and borrows so each element of the bigInt x fits in bpe bits.
131// function divide_(x,y,q,r) //divide_ x by y giving quotient q and remainder r
132// function eGCD_(x,y,d,a,b) //sets a,b,d to positive big integers such that d = GCD_(x,y) = a*x-b*y
133// function inverseMod_(x,n) //do x=x**(-1) mod n, for bigInts x and n. Returns 1 (0) if inverse does (doesn't) exist
134// function inverseModInt_(x,n) //return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse
135// function leftShift_(x,n) //left shift bigInt x by n bits. n<bpe.
136// function linComb_(x,y,a,b) //do x=a*x+b*y for bigInts x and y and integers a and b
137// function linCombShift_(x,y,b,ys) //do x=x+b*(y<<(ys*bpe)) for bigInts x and y, and integers b and ys
138// function mont_(x,y,n,np) //Montgomery multiplication (see comments where the function is defined)
139// function mult_(x,y) //do x=x*y for bigInts x and y.
140// function multInt_(x,n) //do x=x*n where x is a bigInt and n is an integer.
141// function multMod_(x,y,n) //do x=x*y mod n for bigInts x,y,n.
142// function powMod_(x,y,n) //do x=x**y mod n, where x,y,n are bigInts (n is odd) and ** is exponentiation. 0**0=1.
143// function randBigInt_(b,n,s) //do b = an n-bit random BigInt. if s=1, then nth bit (most significant bit) is set to 1. n>=1.
144// function randTruePrime_(ans,k) //do ans = a random k-bit true random prime (not just probable prime) with 1 in the msb.
145// function squareMod_(x,n) //do x=x*x mod n for bigInts x,n
146// function sub_(x,y) //do x=x-y for bigInts x and y. Negative answers will be 2s complement.
147// function subShift_(x,y,ys) //do x=x-(y<<(ys*bpe)). Negative answers will be 2s complement.
148//
149// The following functions are based on algorithms from the _Handbook of Applied Cryptography_
150// powMod_() = algorithm 14.94, Montgomery exponentiation
151// eGCD_,inverseMod_() = algorithm 14.61, Binary extended GCD_
152// GCD_() = algorothm 14.57, Lehmer's algorithm
153// mont_() = algorithm 14.36, Montgomery multiplication
154// divide_() = algorithm 14.20 Multiple-precision division
155// squareMod_() = algorithm 14.16 Multiple-precision squaring
156// randTruePrime_() = algorithm 4.62, Maurer's algorithm
157// millerRabin() = algorithm 4.24, Miller-Rabin algorithm
158//
159// Profiling shows:
160// randTruePrime_() spends:
161// 10% of its time in calls to powMod_()
162// 85% of its time in calls to millerRabin()
163// millerRabin() spends:
164// 99% of its time in calls to powMod_() (always with a base of 2)
165// powMod_() spends:
166// 94% of its time in calls to mont_() (almost always with x==y)
167//
168// This suggests there are several ways to speed up this library slightly:
169// - convert powMod_ to use a Montgomery form of k-ary window (or maybe a Montgomery form of sliding window)
170// -- this should especially focus on being fast when raising 2 to a power mod n
171// - convert randTruePrime_() to use a minimum r of 1/3 instead of 1/2 with the appropriate change to the test
172// - tune the parameters in randTruePrime_(), including c, m, and recLimit
173// - speed up the single loop in mont_() that takes 95% of the runtime, perhaps by reducing checking
174// within the loop when all the parameters are the same length.
175//
176// There are several ideas that look like they wouldn't help much at all:
177// - replacing trial division in randTruePrime_() with a sieve (that speeds up something taking almost no time anyway)
178// - increase bpe from 15 to 30 (that would help if we had a 32*32->64 multiplier, but not with JavaScript's 32*32->32)
179// - speeding up mont_(x,y,n,np) when x==y by doing a non-modular, non-Montgomery square
180// followed by a Montgomery reduction. The intermediate answer will be twice as long as x, so that
181// method would be slower. This is unfortunate because the code currently spends almost all of its time
182// doing mont_(x,x,...), both for randTruePrime_() and powMod_(). A faster method for Montgomery squaring
183// would have a large impact on the speed of randTruePrime_() and powMod_(). HAC has a couple of poorly-worded
184// sentences that seem to imply it's faster to do a non-modular square followed by a single
185// Montgomery reduction, but that's obviously wrong.
186////////////////////////////////////////////////////////////////////////////////////////
187
188//
189 //The whole library has been moved into the Baird.Crypto.BigInt scope by Giulio Cesare Solaroli <giulio.cesare@clipperz.com>
190//
191Baird.Crypto.BigInt.VERSION = "5.0";
192Baird.Crypto.BigInt.NAME = "Baird.Crypto.BigInt";
193
194MochiKit.Base.update(Baird.Crypto.BigInt, {
195 //globals
196 'bpe': 0, //bits stored per array element
197 'mask': 0, //AND this with an array element to chop it down to bpe bits
198 'radix': Baird.Crypto.BigInt.mask + 1,//equals 2^bpe. A single 1 bit to the left of the last bit of mask.
199
200 //the digits for converting to different bases
201 'digitsStr': '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_=!@#$%^&*()[]{}|;:,.<>/?`~ \\\'\"+-',
202
203//initialize the global variables
204for (bpe=0; (1<<(bpe+1)) > (1<<bpe); bpe++); //bpe=number of bits in the mantissa on this platform
205bpe>>=1; //bpe=number of bits in one element of the array representing the bigInt
206mask=(1<<bpe)-1; //AND the mask with an integer to get its bpe least significant bits
207radix=mask+1; //2^bpe. a single 1 bit to the left of the first bit of mask
208one=int2bigInt(1,1,1); //constant used in powMod_()
209
210//the following global variables are scratchpad memory to
211//reduce dynamic memory allocation in the inner loop
212t=new Array(0);
213ss=t; //used in mult_()
214s0=t; //used in multMod_(), squareMod_()
215s1=t; //used in powMod_(), multMod_(), squareMod_()
216s2=t; //used in powMod_(), multMod_()
217s3=t; //used in powMod_()
218s4=t; s5=t; //used in mod_()
219s6=t; //used in bigInt2str()
220s7=t; //used in powMod_()
221T=t; //used in GCD_()
222sa=t; //used in mont_()
223mr_x1=t; mr_r=t; mr_a=t; //used in millerRabin()
224eg_v=t; eg_u=t; eg_A=t; eg_B=t; eg_C=t; eg_D=t; //used in eGCD_(), inverseMod_()
225md_q1=t; md_q2=t; md_q3=t; md_r=t; md_r1=t; md_r2=t; md_tt=t; //used in mod_()
226
227primes=t; pows=t; s_i=t; s_i2=t; s_R=t; s_rm=t; s_q=t; s_n1=t;
228 s_a=t; s_r2=t; s_n=t; s_b=t; s_d=t; s_x1=t; s_x2=t, s_aa=t; //used in randTruePrime_()
229
230////////////////////////////////////////////////////////////////////////////////////////
231
232 //return array of all primes less than integer n
233 'findPrimes': function(n) {
234 var i,s,p,ans;
235 s=new Array(n);
236 for (i=0;i<n;i++)
237 s[i]=0;
238 s[0]=2;
239 p=0; //first p elements of s are primes, the rest are a sieve
240 for(;s[p]<n;) { //s[p] is the pth prime
241 for(i=s[p]*s[p]; i<n; i+=s[p]) //mark multiples of s[p]
242 s[i]=1;
243 p++;
244 s[p]=s[p-1]+1;
245 for(; s[p]<n && s[s[p]]; s[p]++); //find next prime (where s[p]==0)
246 }
247 ans=new Array(p);
248 for(i=0;i<p;i++)
249 ans[i]=s[i];
250 return ans;
251 },
252
253 //does a single round of Miller-Rabin base b consider x to be a possible prime?
254 //x is a bigInt, and b is an integer
255 'millerRabin': function(x,b) {
256 var i,j,k,s;
257
258 if (mr_x1.length!=x.length) {
259 mr_x1=dup(x);
260 mr_r=dup(x);
261 mr_a=dup(x);
262 }
263
264 copyInt_(mr_a,b);
265 copy_(mr_r,x);
266 copy_(mr_x1,x);
267
268 addInt_(mr_r,-1);
269 addInt_(mr_x1,-1);
270
271 //s=the highest power of two that divides mr_r
272 k=0;
273 for (i=0;i<mr_r.length;i++)
274 for (j=1;j<mask;j<<=1)
275 if (x[i] & j) {
276 s=(k<mr_r.length+bpe ? k : 0);
277 i=mr_r.length;
278 j=mask;
279 } else
280 k++;
281
282 if (s)
283 rightShift_(mr_r,s);
284
285 powMod_(mr_a,mr_r,x);
286
287 if (!equalsInt(mr_a,1) && !equals(mr_a,mr_x1)) {
288 j=1;
289 while (j<=s-1 && !equals(mr_a,mr_x1)) {
290 squareMod_(mr_a,x);
291 if (equalsInt(mr_a,1)) {
292 return 0;
293 }
294 j++;
295 }
296 if (!equals(mr_a,mr_x1)) {
297 return 0;
298 }
299 }
300
301 return 1;
302 },
303
304 //returns how many bits long the bigInt is, not counting leading zeros.
305 'bitSize': function(x) {
306 var j,z,w;
307 for (j=x.length-1; (x[j]==0) && (j>0); j--);
308 for (z=0,w=x[j]; w; (w>>=1),z++);
309 z+=bpe*j;
310 return z;
311 },
312
313 //return a copy of x with at least n elements, adding leading zeros if needed
314 'expand': function(x,n) {
315 var ans=int2bigInt(0,(x.length>n ? x.length : n)*bpe,0);
316 copy_(ans,x);
317 return ans;
318 },
319
320 //return a k-bit true random prime using Maurer's algorithm.
321 'randTruePrime': function(k) {
322 var ans=int2bigInt(0,k,0);
323 randTruePrime_(ans,k);
324 return trim(ans,1);
325 },
326
327 //return a new bigInt equal to (x mod n) for bigInts x and n.
328 'mod': function(x,n) {
329 var ans=dup(x);
330 mod_(ans,n);
331 return trim(ans,1);
332 },
333
334 //return (x+n) where x is a bigInt and n is an integer.
335 'addInt': function(x,n) {
336 var ans=expand(x,x.length+1);
337 addInt_(ans,n);
338 return trim(ans,1);
339 },
340
341 //return x*y for bigInts x and y. This is faster when y<x.
342 'mult': function(x,y) {
343 var ans=expand(x,x.length+y.length);
344 mult_(ans,y);
345 return trim(ans,1);
346 },
347
348 //return (x**y mod n) where x,y,n are bigInts and ** is exponentiation. 0**0=1. Faster for odd n.
349 'powMod': function(x,y,n) {
350 var ans=expand(x,n.length);
351 powMod_(ans,trim(y,2),trim(n,2),0); //this should work without the trim, but doesn't
352 return trim(ans,1);
353 },
354
355 //return (x-y) for bigInts x and y. Negative answers will be 2s complement
356 'sub': function(x,y) {
357 var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1));
358 sub_(ans,y);
359 return trim(ans,1);
360 },
361
362 //return (x+y) for bigInts x and y.
363 'add': function(x,y) {
364 var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1));
365 add_(ans,y);
366 return trim(ans,1);
367 },
368
369 //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null
370 'inverseMod': function(x,n) {
371 var ans=expand(x,n.length);
372 var s;
373 s=inverseMod_(ans,n);
374 return s ? trim(ans,1) : null;
375 },
376
377 //return (x*y mod n) for bigInts x,y,n. For greater speed, let y<x.
378 'multMod': function(x,y,n) {
379 var ans=expand(x,n.length);
380 multMod_(ans,y,n);
381 return trim(ans,1);
382 },
383
384 //generate a k-bit true random prime using Maurer's algorithm,
385 //and put it into ans. The bigInt ans must be large enough to hold it.
386 'randTruePrime_': function(ans,k) {
387 var c,m,pm,dd,j,r,B,divisible,z,zz,recSize;
388
389 if (primes.length==0)
390 primes=findPrimes(30000); //check for divisibility by primes <=30000
391
392 if (pows.length==0) {
393 pows=new Array(512);
394 for (j=0;j<512;j++) {
395 pows[j]=Math.pow(2,j/511.-1.);
396 }
397 }
398
399 //c and m should be tuned for a particular machine and value of k, to maximize speed
400 //this was: c=primes[primes.length-1]/k/k; //check using all the small primes. (c=0.1 in HAC)
401 c=0.1;
402 m=20; //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
403 recLimit=20; /*must be at least 2 (was 29)*/ //stop recursion when k <=recLimit
404
405 if (s_i2.length!=ans.length) {
406 s_i2=dup(ans);
407 s_R =dup(ans);
408 s_n1=dup(ans);
409 s_r2=dup(ans);
410 s_d =dup(ans);
411 s_x1=dup(ans);
412 s_x2=dup(ans);
413 s_b =dup(ans);
414 s_n =dup(ans);
415 s_i =dup(ans);
416 s_rm=dup(ans);
417 s_q =dup(ans);
418 s_a =dup(ans);
419 s_aa=dup(ans);
420 }
421
422 if (k <= recLimit) { //generate small random primes by trial division up to its square root
423 pm=(1<<((k+2)>>1))-1; //pm is binary number with all ones, just over sqrt(2^k)
424 copyInt_(ans,0);
425 for (dd=1;dd;) {
426 dd=0;
427 ans[0]= 1 | (1<<(k-1)) | Math.floor(Math.random()*(1<<k)); //random, k-bit, odd integer, with msb 1
428 for (j=1;(j<primes.length) && ((primes[j]&pm)==primes[j]);j++) { //trial division by all primes 3...sqrt(2^k)
429 if (0==(ans[0]%primes[j])) {
430 dd=1;
431 break;
432 }
433 }
434 }
435 carry_(ans);
436 return;
437 }
438
439 B=c*k*k; //try small primes up to B (or all the primes[] array if the largest is less than B).
440 if (k>2*m) //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
441 for (r=1; k-k*r<=m; )
442 r=pows[Math.floor(Math.random()*512)]; //r=Math.pow(2,Math.random()-1);
443 else
444 r=.5;
445
446 //simulation suggests the more complex algorithm using r=.333 is only slightly faster.
447
448 recSize=Math.floor(r*k)+1;
449
450 randTruePrime_(s_q,recSize);
451 copyInt_(s_i2,0);
452 s_i2[Math.floor((k-2)/bpe)] |= (1<<((k-2)%bpe)); //s_i2=2^(k-2)
453 divide_(s_i2,s_q,s_i,s_rm); //s_i=floor((2^(k-1))/(2q))
454
455 z=bitSize(s_i);
456
457 for (;;) {
458 for (;;) { //generate z-bit numbers until one falls in the range [0,s_i-1]
459 randBigInt_(s_R,z,0);
460 if (greater(s_i,s_R))
461 break;
462 } //now s_R is in the range [0,s_i-1]
463 addInt_(s_R,1); //now s_R is in the range [1,s_i]
464 add_(s_R,s_i); //now s_R is in the range [s_i+1,2*s_i]
465
466 copy_(s_n,s_q);
467 mult_(s_n,s_R);
468 multInt_(s_n,2);
469 addInt_(s_n,1); //s_n=2*s_R*s_q+1
470
471 copy_(s_r2,s_R);
472 multInt_(s_r2,2); //s_r2=2*s_R
473
474 //check s_n for divisibility by small primes up to B
475 for (divisible=0,j=0; (j<primes.length) && (primes[j]<B); j++)
476 if (modInt(s_n,primes[j])==0) {
477 divisible=1;
478 break;
479 }
480
481 if (!divisible) //if it passes small primes check, then try a single Miller-Rabin base 2
482 if (!millerRabin(s_n,2)) //this line represents 75% of the total runtime for randTruePrime_
483 divisible=1;
484
485 if (!divisible) { //if it passes that test, continue checking s_n
486 addInt_(s_n,-3);
487 for (j=s_n.length-1;(s_n[j]==0) && (j>0); j--); //strip leading zeros
488 for (zz=0,w=s_n[j]; w; (w>>=1),zz++);
489 zz+=bpe*j; //zz=number of bits in s_n, ignoring leading zeros
490 for (;;) { //generate z-bit numbers until one falls in the range [0,s_n-1]
491 randBigInt_(s_a,zz,0);
492 if (greater(s_n,s_a))
493 break;
494 } //now s_a is in the range [0,s_n-1]
495 addInt_(s_n,3); //now s_a is in the range [0,s_n-4]
496 addInt_(s_a,2); //now s_a is in the range [2,s_n-2]
497 copy_(s_b,s_a);
498 copy_(s_n1,s_n);
499 addInt_(s_n1,-1);
500 powMod_(s_b,s_n1,s_n); //s_b=s_a^(s_n-1) modulo s_n
501 addInt_(s_b,-1);
502 if (isZero(s_b)) {
503 copy_(s_b,s_a);
504 powMod_(s_b,s_r2,s_n);
505 addInt_(s_b,-1);
506 copy_(s_aa,s_n);
507 copy_(s_d,s_b);
508 GCD_(s_d,s_n); //if s_b and s_n are relatively prime, then s_n is a prime
509 if (equalsInt(s_d,1)) {
510 copy_(ans,s_aa);
511 return; //if we've made it this far, then s_n is absolutely guaranteed to be prime
512 }
513 }
514 }
515 }
516 },
517
518 //set b to an n-bit random BigInt. If s=1, then nth bit (most significant bit) is set to 1.
519 //array b must be big enough to hold the result. Must have n>=1
520 'randBigInt_': function(b,n,s) {
521 var i,a;
522 for (i=0;i<b.length;i++)
523 b[i]=0;
524 a=Math.floor((n-1)/bpe)+1; //# array elements to hold the BigInt
525 for (i=0;i<a;i++) {
526 b[i]=Math.floor(Math.random()*(1<<(bpe-1)));
527 }
528 b[a-1] &= (2<<((n-1)%bpe))-1;
529 if (s)
530 b[a-1] |= (1<<((n-1)%bpe));
531 },
532
533 //set x to the greatest common divisor of x and y.
534 //x,y are bigInts with the same number of elements. y is destroyed.
535 'GCD_': function(x,y) {
536 var i,xp,yp,A,B,C,D,q,sing;
537 if (T.length!=x.length)
538 T=dup(x);
539
540 sing=1;
541 while (sing) { //while y has nonzero elements other than y[0]
542 sing=0;
543 for (i=1;i<y.length;i++) //check if y has nonzero elements other than 0
544 if (y[i]) {
545 sing=1;
546 break;
547 }
548 if (!sing) break; //quit when y all zero elements except possibly y[0]
549
550 for (i=x.length;!x[i] && i>=0;i--); //find most significant element of x
551 xp=x[i];
552 yp=y[i];
553 A=1; B=0; C=0; D=1;
554 while ((yp+C) && (yp+D)) {
555 q =Math.floor((xp+A)/(yp+C));
556 qp=Math.floor((xp+B)/(yp+D));
557 if (q!=qp)
558 break;
559 t= A-q*C; A=C; C=t; // do (A,B,xp, C,D,yp) = (C,D,yp, A,B,xp) - q*(0,0,0, C,D,yp)
560 t= B-q*D; B=D; D=t;
561 t=xp-q*yp; xp=yp; yp=t;
562 }
563 if (B) {
564 copy_(T,x);
565 linComb_(x,y,A,B); //x=A*x+B*y
566 linComb_(y,T,D,C); //y=D*y+C*T
567 } else {
568 mod_(x,y);
569 copy_(T,x);
570 copy_(x,y);
571 copy_(y,T);
572 }
573 }
574 if (y[0]==0)
575 return;
576 t=modInt(x,y[0]);
577 copyInt_(x,y[0]);
578 y[0]=t;
579 while (y[0]) {
580 x[0]%=y[0];
581 t=x[0]; x[0]=y[0]; y[0]=t;
582 }
583 },
584
585//do x=x**(-1) mod n, for bigInts x and n.
586//If no inverse exists, it sets x to zero and returns 0, else it returns 1.
587//The x array must be at least as large as the n array.
588function inverseMod_(x,n) {
589 var k=1+2*Math.max(x.length,n.length);
590
591 if(!(x[0]&1) && !(n[0]&1)) { //if both inputs are even, then inverse doesn't exist
592 copyInt_(x,0);
593 return 0;
594 }
595
596 if (eg_u.length!=k) {
597 eg_u=new Array(k);
598 eg_v=new Array(k);
599 eg_A=new Array(k);
600 eg_B=new Array(k);
601 eg_C=new Array(k);
602 eg_D=new Array(k);
603 }
604
605 copy_(eg_u,x);
606 copy_(eg_v,n);
607 copyInt_(eg_A,1);
608 copyInt_(eg_B,0);
609 copyInt_(eg_C,0);
610 copyInt_(eg_D,1);
611 for (;;) {
612 while(!(eg_u[0]&1)) { //while eg_u is even
613 halve_(eg_u);
614 if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if eg_A==eg_B==0 mod 2
615 halve_(eg_A);
616 halve_(eg_B);
617 } else {
618 add_(eg_A,n); halve_(eg_A);
619 sub_(eg_B,x); halve_(eg_B);
620 }
621 }
622
623 while (!(eg_v[0]&1)) { //while eg_v is even
624 halve_(eg_v);
625 if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if eg_C==eg_D==0 mod 2
626 halve_(eg_C);
627 halve_(eg_D);
628 } else {
629 add_(eg_C,n); halve_(eg_C);
630 sub_(eg_D,x); halve_(eg_D);
631 }
632 }
633
634 if (!greater(eg_v,eg_u)) { //eg_v <= eg_u
635 sub_(eg_u,eg_v);
636 sub_(eg_A,eg_C);
637 sub_(eg_B,eg_D);
638 } else { //eg_v > eg_u
639 sub_(eg_v,eg_u);
640 sub_(eg_C,eg_A);
641 sub_(eg_D,eg_B);
642 }
643
644 if (equalsInt(eg_u,0)) {
645 if (negative(eg_C)) //make sure answer is nonnegative
646 add_(eg_C,n);
647 copy_(x,eg_C);
648
649 if (!equalsInt(eg_v,1)) { //if GCD_(x,n)!=1, then there is no inverse
650 copyInt_(x,0);
651 return 0;
652 }
653 return 1;
654 }
655 }
656}
657
658//return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse
659function inverseModInt_(x,n) {
660 var a=1,b=0,t;
661 for (;;) {
662 if (x==1) return a;
663 if (x==0) return 0;
664 b-=a*Math.floor(n/x);
665 n%=x;
666
667 if (n==1) return b; //to avoid negatives, change this b to n-b, and each -= to +=
668 if (n==0) return 0;
669 a-=b*Math.floor(x/n);
670 x%=n;
671 }
672}
673
674//Given positive bigInts x and y, change the bigints v, a, and b to positive bigInts such that:
675// v = GCD_(x,y) = a*x-b*y
676//The bigInts v, a, b, must have exactly as many elements as the larger of x and y.
677function eGCD_(x,y,v,a,b) {
678 var g=0;
679 var k=Math.max(x.length,y.length);
680 if (eg_u.length!=k) {
681 eg_u=new Array(k);
682 eg_A=new Array(k);
683 eg_B=new Array(k);
684 eg_C=new Array(k);
685 eg_D=new Array(k);
686 }
687 while(!(x[0]&1) && !(y[0]&1)) { //while x and y both even
688 halve_(x);
689 halve_(y);
690 g++;
691 }
692 copy_(eg_u,x);
693 copy_(v,y);
694 copyInt_(eg_A,1);
695 copyInt_(eg_B,0);
696 copyInt_(eg_C,0);
697 copyInt_(eg_D,1);
698 for (;;) {
699 while(!(eg_u[0]&1)) { //while u is even
700 halve_(eg_u);
701 if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if A==B==0 mod 2
702 halve_(eg_A);
703 halve_(eg_B);
704 } else {
705 add_(eg_A,y); halve_(eg_A);
706 sub_(eg_B,x); halve_(eg_B);
707 }
708 }
709
710 while (!(v[0]&1)) { //while v is even
711 halve_(v);
712 if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if C==D==0 mod 2
713 halve_(eg_C);
714 halve_(eg_D);
715 } else {
716 add_(eg_C,y); halve_(eg_C);
717 sub_(eg_D,x); halve_(eg_D);
718 }
719 }
720
721 if (!greater(v,eg_u)) { //v<=u
722 sub_(eg_u,v);
723 sub_(eg_A,eg_C);
724 sub_(eg_B,eg_D);
725 } else { //v>u
726 sub_(v,eg_u);
727 sub_(eg_C,eg_A);
728 sub_(eg_D,eg_B);
729 }
730 if (equalsInt(eg_u,0)) {
731 if (negative(eg_C)) { //make sure a (C)is nonnegative
732 add_(eg_C,y);
733 sub_(eg_D,x);
734 }
735 multInt_(eg_D,-1); ///make sure b (D) is nonnegative
736 copy_(a,eg_C);
737 copy_(b,eg_D);
738 leftShift_(v,g);
739 return;
740 }
741 }
742}
743
744
745//is bigInt x negative?
746function negative(x) {
747 return ((x[x.length-1]>>(bpe-1))&1);
748}
749
750
751//is (x << (shift*bpe)) > y?
752//x and y are nonnegative bigInts
753//shift is a nonnegative integer
754function greaterShift(x,y,shift) {
755 var kx=x.length, ky=y.length;
756 k=((kx+shift)<ky) ? (kx+shift) : ky;
757 for (i=ky-1-shift; i<kx && i>=0; i++)
758 if (x[i]>0)
759 return 1; //if there are nonzeros in x to the left of the first column of y, then x is bigger
760 for (i=kx-1+shift; i<ky; i++)
761 if (y[i]>0)
762 return 0; //if there are nonzeros in y to the left of the first column of x, then x is not bigger
763 for (i=k-1; i>=shift; i--)
764 if (x[i-shift]>y[i]) return 1;
765 else if (x[i-shift]<y[i]) return 0;
766 return 0;
767}
768
769//is x > y? (x and y both nonnegative)
770function greater(x,y) {
771 var i;
772 var k=(x.length<y.length) ? x.length : y.length;
773
774 for (i=x.length;i<y.length;i++)
775 if (y[i])
776 return 0; //y has more digits
777
778 for (i=y.length;i<x.length;i++)
779 if (x[i])
780 return 1; //x has more digits
781
782 for (i=k-1;i>=0;i--)
783 if (x[i]>y[i])
784 return 1;
785 else if (x[i]<y[i])
786 return 0;
787 return 0;
788}
789
790//divide_ x by y giving quotient q and remainder r. (q=floor(x/y), r=x mod y). All 4 are bigints.
791//x must have at least one leading zero element.
792//y must be nonzero.
793//q and r must be arrays that are exactly the same length as x.
794//the x array must have at least as many elements as y.
795function divide_(x,y,q,r) {
796 var kx, ky;
797 var i,j,y1,y2,c,a,b;
798 copy_(r,x);
799 for (ky=y.length;y[ky-1]==0;ky--); //kx,ky is number of elements in x,y, not including leading zeros
800 for (kx=r.length;r[kx-1]==0 && kx>ky;kx--);
801
802 //normalize: ensure the most significant element of y has its highest bit set
803 b=y[ky-1];
804 for (a=0; b; a++)
805 b>>=1;
806 a=bpe-a; //a is how many bits to shift so that the high order bit of y is leftmost in its array element
807 leftShift_(y,a); //multiply both by 1<<a now, then divide_ both by that at the end
808 leftShift_(r,a);
809
810 copyInt_(q,0); // q=0
811 while (!greaterShift(y,r,kx-ky)) { // while (leftShift_(y,kx-ky) <= r) {
812 subShift_(r,y,kx-ky); // r=r-leftShift_(y,kx-ky)
813 q[kx-ky]++; // q[kx-ky]++;
814 } // }
815
816 for (i=kx-1; i>=ky; i--) {
817 if (r[i]==y[ky-1])
818 q[i-ky]=mask;
819 else
820 q[i-ky]=Math.floor((r[i]*radix+r[i-1])/y[ky-1]);
821
822 //The following for(;;) loop is equivalent to the commented while loop,
823 //except that the uncommented version avoids overflow.
824 //The commented loop comes from HAC, which assumes r[-1]==y[-1]==0
825 // while (q[i-ky]*(y[ky-1]*radix+y[ky-2]) > r[i]*radix*radix+r[i-1]*radix+r[i-2])
826 // q[i-ky]--;
827 for (;;) {
828 y2=(ky>1 ? y[ky-2] : 0)*q[i-ky];
829 c=y2>>bpe;
830 y2=y2 & mask;
831 y1=c+q[i-ky]*y[ky-1];
832 c=y1>>bpe;
833 y1=y1 & mask;
834
835 if (c==r[i] ? y1==r[i-1] ? y2>(i>1 ? r[i-2] : 0) : y1>r[i-1] : c>r[i])
836 q[i-ky]--;
837 else
838 break;
839 }
840
841 linCombShift_(r,y,-q[i-ky],i-ky); //r=r-q[i-ky]*leftShift_(y,i-ky)
842 if (negative(r)) {
843 addShift_(r,y,i-ky); //r=r+leftShift_(y,i-ky)
844 q[i-ky]--;
845 }
846 }
847
848 rightShift_(y,a); //undo the normalization step
849 rightShift_(r,a); //undo the normalization step
850}
851
852//do carries and borrows so each element of the bigInt x fits in bpe bits.
853function carry_(x) {
854 var i,k,c,b;
855 k=x.length;
856 c=0;
857 for (i=0;i<k;i++) {
858 c+=x[i];
859 b=0;
860 if (c<0) {
861 b=-(c>>bpe);
862 c+=b*radix;
863 }
864 x[i]=c & mask;
865 c=(c>>bpe)-b;
866 }
867}
868
869//return x mod n for bigInt x and integer n.
870function modInt(x,n) {
871 var i,c=0;
872 for (i=x.length-1; i>=0; i--)
873 c=(c*radix+x[i])%n;
874 return c;
875}
876
877//convert the integer t into a bigInt with at least the given number of bits.
878//the returned array stores the bigInt in bpe-bit chunks, little endian (buff[0] is least significant word)
879//Pad the array with leading zeros so that it has at least minSize elements.
880//There will always be at least one leading 0 element.
881function int2bigInt(t,bits,minSize) {
882 var i,k;
883 k=Math.ceil(bits/bpe)+1;
884 k=minSize>k ? minSize : k;
885 buff=new Array(k);
886 copyInt_(buff,t);
887 return buff;
888}
889
890//return the bigInt given a string representation in a given base.
891//Pad the array with leading zeros so that it has at least minSize elements.
892//If base=-1, then it reads in a space-separated list of array elements in decimal.
893//The array will always have at least one leading zero, unless base=-1.
894function str2bigInt(s,base,minSize) {
895 var d, i, j, x, y, kk;
896 var k=s.length;
897 if (base==-1) { //comma-separated list of array elements in decimal
898 x=new Array(0);
899 for (;;) {
900 y=new Array(x.length+1);
901 for (i=0;i<x.length;i++)
902 y[i+1]=x[i];
903 y[0]=parseInt(s,10);
904 x=y;
905 d=s.indexOf(',',0);
906 if (d<1)
907 break;
908 s=s.substring(d+1);
909 if (s.length==0)
910 break;
911 }
912 if (x.length<minSize) {
913 y=new Array(minSize);
914 copy_(y,x);
915 return y;
916 }
917 return x;
918 }
919
920 x=int2bigInt(0,base*k,0);
921 for (i=0;i<k;i++) {
922 d=digitsStr.indexOf(s.substring(i,i+1),0);
923 if (base<=36 && d>=36) //convert lowercase to uppercase if base<=36
924 d-=26;
925 if (d<base && d>=0) { //ignore illegal characters
926 multInt_(x,base);
927 addInt_(x,d);
928 }
929 }
930
931 for (k=x.length;k>0 && !x[k-1];k--); //strip off leading zeros
932 k=minSize>k+1 ? minSize : k+1;
933 y=new Array(k);
934 kk=k<x.length ? k : x.length;
935 for (i=0;i<kk;i++)
936 y[i]=x[i];
937 for (;i<k;i++)
938 y[i]=0;
939 return y;
940}
941
942//is bigint x equal to integer y?
943//y must have less than bpe bits
944function equalsInt(x,y) {
945 var i;
946 if (x[0]!=y)
947 return 0;
948 for (i=1;i<x.length;i++)
949 if (x[i])
950 return 0;
951 return 1;
952}
953
954//are bigints x and y equal?
955//this works even if x and y are different lengths and have arbitrarily many leading zeros
956function equals(x,y) {
957 var i;
958 var k=x.length<y.length ? x.length : y.length;
959 for (i=0;i<k;i++)
960 if (x[i]!=y[i])
961 return 0;
962 if (x.length>y.length) {
963 for (;i<x.length;i++)
964 if (x[i])
965 return 0;
966 } else {
967 for (;i<y.length;i++)
968 if (y[i])
969 return 0;
970 }
971 return 1;
972}
973
974//is the bigInt x equal to zero?
975function isZero(x) {
976 var i;
977 for (i=0;i<x.length;i++)
978 if (x[i])
979 return 0;
980 return 1;
981}
982
983//convert a bigInt into a string in a given base, from base 2 up to base 95.
984//Base -1 prints the contents of the array representing the number.
985function bigInt2str(x,base) {
986 var i,t,s="";
987
988 if (s6.length!=x.length)
989 s6=dup(x);
990 else
991 copy_(s6,x);
992
993 if (base==-1) { //return the list of array contents
994 for (i=x.length-1;i>0;i--)
995 s+=x[i]+',';
996 s+=x[0];
997 }
998 else { //return it in the given base
999 while (!isZero(s6)) {
1000 t=divInt_(s6,base); //t=s6 % base; s6=floor(s6/base);
1001 s=digitsStr.substring(t,t+1)+s;
1002 }
1003 }
1004 if (s.length==0)
1005 s="0";
1006 return s;
1007}
1008
1009//returns a duplicate of bigInt x
1010function dup(x) {
1011 var i;
1012 buff=new Array(x.length);
1013 copy_(buff,x);
1014 return buff;
1015}
1016
1017//do x=y on bigInts x and y. x must be an array at least as big as y (not counting the leading zeros in y).
1018function copy_(x,y) {
1019 var i;
1020 var k=x.length<y.length ? x.length : y.length;
1021 for (i=0;i<k;i++)
1022 x[i]=y[i];
1023 for (i=k;i<x.length;i++)
1024 x[i]=0;
1025}
1026
1027//do x=y on bigInt x and integer y.
1028function copyInt_(x,n) {
1029 var i,c;
1030 for (c=n,i=0;i<x.length;i++) {
1031 x[i]=c & mask;
1032 c>>=bpe;
1033 }
1034}
1035
1036//do x=x+n where x is a bigInt and n is an integer.
1037//x must be large enough to hold the result.
1038function addInt_(x,n) {
1039 var i,k,c,b;
1040 x[0]+=n;
1041 k=x.length;
1042 c=0;
1043 for (i=0;i<k;i++) {
1044 c+=x[i];
1045 b=0;
1046 if (c<0) {
1047 b=-(c>>bpe);
1048 c+=b*radix;
1049 }
1050 x[i]=c & mask;
1051 c=(c>>bpe)-b;
1052 if (!c) return; //stop carrying as soon as the carry_ is zero
1053 }
1054}
1055
1056//right shift bigInt x by n bits. 0 <= n < bpe.
1057function rightShift_(x,n) {
1058 var i;
1059 var k=Math.floor(n/bpe);
1060 if (k) {
1061 for (i=0;i<x.length-k;i++) //right shift x by k elements
1062 x[i]=x[i+k];
1063 for (;i<x.length;i++)
1064 x[i]=0;
1065 n%=bpe;
1066 }
1067 for (i=0;i<x.length-1;i++) {
1068 x[i]=mask & ((x[i+1]<<(bpe-n)) | (x[i]>>n));
1069 }
1070 x[i]>>=n;
1071}
1072
1073//do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement
1074function halve_(x) {
1075 var i;
1076 for (i=0;i<x.length-1;i++) {
1077 x[i]=mask & ((x[i+1]<<(bpe-1)) | (x[i]>>1));
1078 }
1079 x[i]=(x[i]>>1) | (x[i] & (radix>>1)); //most significant bit stays the same
1080}
1081
1082//left shift bigInt x by n bits.
1083function leftShift_(x,n) {
1084 var i;
1085 var k=Math.floor(n/bpe);
1086 if (k) {
1087 for (i=x.length; i>=k; i--) //left shift x by k elements
1088 x[i]=x[i-k];
1089 for (;i>=0;i--)
1090 x[i]=0;
1091 n%=bpe;
1092 }
1093 if (!n)
1094 return;
1095 for (i=x.length-1;i>0;i--) {
1096 x[i]=mask & ((x[i]<<n) | (x[i-1]>>(bpe-n)));
1097 }
1098 x[i]=mask & (x[i]<<n);
1099}
1100
1101//do x=x*n where x is a bigInt and n is an integer.
1102//x must be large enough to hold the result.
1103function multInt_(x,n) {
1104 var i,k,c,b;
1105 if (!n)
1106 return;
1107 k=x.length;
1108 c=0;
1109 for (i=0;i<k;i++) {
1110 c+=x[i]*n;
1111 b=0;
1112 if (c<0) {
1113 b=-(c>>bpe);
1114 c+=b*radix;
1115 }
1116 x[i]=c & mask;
1117 c=(c>>bpe)-b;
1118 }
1119}
1120
1121//do x=floor(x/n) for bigInt x and integer n, and return the remainder
1122function divInt_(x,n) {
1123 var i,r=0,s;
1124 for (i=x.length-1;i>=0;i--) {
1125 s=r*radix+x[i];
1126 x[i]=Math.floor(s/n);
1127 r=s%n;
1128 }
1129 return r;
1130}
1131
1132//do the linear combination x=a*x+b*y for bigInts x and y, and integers a and b.
1133//x must be large enough to hold the answer.
1134function linComb_(x,y,a,b) {
1135 var i,c,k,kk;
1136 k=x.length<y.length ? x.length : y.length;
1137 kk=x.length;
1138 for (c=0,i=0;i<k;i++) {
1139 c+=a*x[i]+b*y[i];
1140 x[i]=c & mask;
1141 c>>=bpe;
1142 }
1143 for (i=k;i<kk;i++) {
1144 c+=a*x[i];
1145 x[i]=c & mask;
1146 c>>=bpe;
1147 }
1148}
1149
1150//do the linear combination x=a*x+b*(y<<(ys*bpe)) for bigInts x and y, and integers a, b and ys.
1151//x must be large enough to hold the answer.
1152function linCombShift_(x,y,b,ys) {
1153 var i,c,k,kk;
1154 k=x.length<ys+y.length ? x.length : ys+y.length;
1155 kk=x.length;
1156 for (c=0,i=ys;i<k;i++) {
1157 c+=x[i]+b*y[i-ys];
1158 x[i]=c & mask;
1159 c>>=bpe;
1160 }
1161 for (i=k;c && i<kk;i++) {
1162 c+=x[i];
1163 x[i]=c & mask;
1164 c>>=bpe;
1165 }
1166}
1167
1168//do x=x+(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
1169//x must be large enough to hold the answer.
1170function addShift_(x,y,ys) {
1171 var i,c,k,kk;
1172 k=x.length<ys+y.length ? x.length : ys+y.length;
1173 kk=x.length;
1174 for (c=0,i=ys;i<k;i++) {
1175 c+=x[i]+y[i-ys];
1176 x[i]=c & mask;
1177 c>>=bpe;
1178 }
1179 for (i=k;c && i<kk;i++) {
1180 c+=x[i];
1181 x[i]=c & mask;
1182 c>>=bpe;
1183 }
1184}
1185
1186//do x=x-(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
1187//x must be large enough to hold the answer.
1188function subShift_(x,y,ys) {
1189 var i,c,k,kk;
1190 k=x.length<ys+y.length ? x.length : ys+y.length;
1191 kk=x.length;
1192 for (c=0,i=ys;i<k;i++) {
1193 c+=x[i]-y[i-ys];
1194 x[i]=c & mask;
1195 c>>=bpe;
1196 }
1197 for (i=k;c && i<kk;i++) {
1198 c+=x[i];
1199 x[i]=c & mask;
1200 c>>=bpe;
1201 }
1202}
1203
1204//do x=x-y for bigInts x and y.
1205//x must be large enough to hold the answer.
1206//negative answers will be 2s complement
1207function sub_(x,y) {
1208 var i,c,k,kk;
1209 k=x.length<y.length ? x.length : y.length;
1210 for (c=0,i=0;i<k;i++) {
1211 c+=x[i]-y[i];
1212 x[i]=c & mask;
1213 c>>=bpe;
1214 }
1215 for (i=k;c && i<x.length;i++) {
1216 c+=x[i];
1217 x[i]=c & mask;
1218 c>>=bpe;
1219 }
1220}
1221
1222//do x=x+y for bigInts x and y.
1223//x must be large enough to hold the answer.
1224function add_(x,y) {
1225 var i,c,k,kk;
1226 k=x.length<y.length ? x.length : y.length;
1227 for (c=0,i=0;i<k;i++) {
1228 c+=x[i]+y[i];
1229 x[i]=c & mask;
1230 c>>=bpe;
1231 }
1232 for (i=k;c && i<x.length;i++) {
1233 c+=x[i];
1234 x[i]=c & mask;
1235 c>>=bpe;
1236 }
1237}
1238
1239//do x=x*y for bigInts x and y. This is faster when y<x.
1240function mult_(x,y) {
1241 var i;
1242 if (ss.length!=2*x.length)
1243 ss=new Array(2*x.length);
1244 copyInt_(ss,0);
1245 for (i=0;i<y.length;i++)
1246 if (y[i])
1247 linCombShift_(ss,x,y[i],i); //ss=1*ss+y[i]*(x<<(i*bpe))
1248 copy_(x,ss);
1249}
1250
1251//do x=x mod n for bigInts x and n.
1252function mod_(x,n) {
1253 if (s4.length!=x.length)
1254 s4=dup(x);
1255 else
1256 copy_(s4,x);
1257 if (s5.length!=x.length)
1258 s5=dup(x);
1259 divide_(s4,n,s5,x); //x = remainder of s4 / n
1260}
1261
1262//do x=x*y mod n for bigInts x,y,n.
1263//for greater speed, let y<x.
1264function multMod_(x,y,n) {
1265 var i;
1266 if (s0.length!=2*x.length)
1267 s0=new Array(2*x.length);
1268 copyInt_(s0,0);
1269 for (i=0;i<y.length;i++)
1270 if (y[i])
1271 linCombShift_(s0,x,y[i],i); //s0=1*s0+y[i]*(x<<(i*bpe))
1272 mod_(s0,n);
1273 copy_(x,s0);
1274}
1275
1276//do x=x*x mod n for bigInts x,n.
1277function squareMod_(x,n) {
1278 var i,j,d,c,kx,kn,k;
1279 for (kx=x.length; kx>0 && !x[kx-1]; kx--); //ignore leading zeros in x
1280 k=kx>n.length ? 2*kx : 2*n.length; //k=# elements in the product, which is twice the elements in the larger of x and n
1281 if (s0.length!=k)
1282 s0=new Array(k);
1283 copyInt_(s0,0);
1284 for (i=0;i<kx;i++) {
1285 c=s0[2*i]+x[i]*x[i];
1286 s0[2*i]=c & mask;
1287 c>>=bpe;
1288 for (j=i+1;j<kx;j++) {
1289 c=s0[i+j]+2*x[i]*x[j]+c;
1290 s0[i+j]=(c & mask);
1291 c>>=bpe;
1292 }
1293 s0[i+kx]=c;
1294 }
1295 mod_(s0,n);
1296 copy_(x,s0);
1297}
1298
1299//return x with exactly k leading zero elements
1300function trim(x,k) {
1301 var i,y;
1302 for (i=x.length; i>0 && !x[i-1]; i--);
1303 y=new Array(i+k);
1304 copy_(y,x);
1305 return y;
1306}
1307
1308//do x=x**y mod n, where x,y,n are bigInts and ** is exponentiation. 0**0=1.
1309//this is faster when n is odd. x usually needs to have as many elements as n.
1310function powMod_(x,y,n) {
1311 var k1,k2,kn,np;
1312 if(s7.length!=n.length)
1313 s7=dup(n);
1314
1315 //for even modulus, use a simple square-and-multiply algorithm,
1316 //rather than using the more complex Montgomery algorithm.
1317 if ((n[0]&1)==0) {
1318 copy_(s7,x);
1319 copyInt_(x,1);
1320 while(!equalsInt(y,0)) {
1321 if (y[0]&1)
1322 multMod_(x,s7,n);
1323 divInt_(y,2);
1324 squareMod_(s7,n);
1325 }
1326 return;
1327 }
1328
1329 //calculate np from n for the Montgomery multiplications
1330 copyInt_(s7,0);
1331 for (kn=n.length;kn>0 && !n[kn-1];kn--);
1332 np=radix-inverseModInt_(modInt(n,radix),radix);
1333 s7[kn]=1;
1334 multMod_(x ,s7,n); // x = x * 2**(kn*bp) mod n
1335
1336 if (s3.length!=x.length)
1337 s3=dup(x);
1338 else
1339 copy_(s3,x);
1340
1341 for (k1=y.length-1;k1>0 & !y[k1]; k1--); //k1=first nonzero element of y
1342 if (y[k1]==0) { //anything to the 0th power is 1
1343 copyInt_(x,1);
1344 return;
1345 }
1346 for (k2=1<<(bpe-1);k2 && !(y[k1] & k2); k2>>=1); //k2=position of first 1 bit in y[k1]
1347 for (;;) {
1348 if (!(k2>>=1)) { //look at next bit of y
1349 k1--;
1350 if (k1<0) {
1351 mont_(x,one,n,np);
1352 return;
1353 }
1354 k2=1<<(bpe-1);
1355 }
1356 mont_(x,x,n,np);
1357
1358 if (k2 & y[k1]) //if next bit is a 1
1359 mont_(x,s3,n,np);
1360 }
1361}
1362
1363//do x=x*y*Ri mod n for bigInts x,y,n,
1364// where Ri = 2**(-kn*bpe) mod n, and kn is the
1365// number of elements in the n array, not
1366// counting leading zeros.
1367//x must be large enough to hold the answer.
1368//It's OK if x and y are the same variable.
1369//must have:
1370// x,y < n
1371// n is odd
1372// np = -(n^(-1)) mod radix
1373function mont_(x,y,n,np) {
1374 var i,j,c,ui,t;
1375 var kn=n.length;
1376 var ky=y.length;
1377
1378 if (sa.length!=kn)
1379 sa=new Array(kn);
1380
1381 for (;kn>0 && n[kn-1]==0;kn--); //ignore leading zeros of n
1382 //this function sometimes gives wrong answers when the next line is uncommented
1383 //for (;ky>0 && y[ky-1]==0;ky--); //ignore leading zeros of y
1384
1385 copyInt_(sa,0);
1386
1387 //the following loop consumes 95% of the runtime for randTruePrime_() and powMod_() for large keys
1388 for (i=0; i<kn; i++) {
1389 t=sa[0]+x[i]*y[0];
1390 ui=((t & mask) * np) & mask; //the inner "& mask" is needed on Macintosh MSIE, but not windows MSIE
1391 c=(t+ui*n[0]) >> bpe;
1392 t=x[i];
1393
1394 //do sa=(sa+x[i]*y+ui*n)/b where b=2**bpe
1395 for (j=1;j<ky;j++) {
1396 c+=sa[j]+t*y[j]+ui*n[j];
1397 sa[j-1]=c & mask;
1398 c>>=bpe;
1399 }
1400 for (;j<kn;j++) {
1401 c+=sa[j]+ui*n[j];
1402 sa[j-1]=c & mask;
1403 c>>=bpe;
1404 }
1405 sa[j-1]=c & mask;
1406 }
1407
1408 if (!greater(n,sa))
1409 sub_(sa,n);
1410 copy_(x,sa);
1411}
1412
1413
1414
1415
1416//#############################################################################
1417//#############################################################################
1418//#############################################################################
1419//#############################################################################
1420//#############################################################################
1421//#############################################################################
1422//#############################################################################
1423
1424
1425
1426
1427
1428//#############################################################################
1429
1430Clipperz.Crypto.BigInt = function (aValue, aBase) {
1431 varbase;
1432 varvalue;
1433
1434 if (typeof(aValue) == 'object') {
1435 this._internalValue = aValue;
1436 } else {
1437 if (typeof(aValue) == 'undefined') {
1438 value = "0";
1439 } else {
1440 value = aValue + "";
1441 }
1442
1443 if (typeof(aBase) == 'undefined') {
1444 base = 10;
1445 } else {
1446 base = aBase;
1447 }
1448
1449 this._internalValue = str2bigInt(value, base, 1, 1);
1450 }
1451
1452 return this;
1453}
1454
1455//=============================================================================
1456
1457MochiKit.Base.update(Clipperz.Crypto.BigInt.prototype, {
1458
1459 //-------------------------------------------------------------------------
1460
1461 'internalValue': function () {
1462 return this._internalValue;
1463 },
1464
1465 //-------------------------------------------------------------------------
1466
1467 'isBigInt': true,
1468
1469 //-------------------------------------------------------------------------
1470
1471 'toString': function(aBase) {
1472 return this.asString(aBase);
1473 },
1474
1475 //-------------------------------------------------------------------------
1476
1477 'asString': function (aBase) {
1478 varbase;
1479
1480 if (typeof(aBase) == 'undefined') {
1481 base = 10;
1482 } else {
1483 base = aBase;
1484 }
1485
1486 return bigInt2str(this.internalValue(), base).toLowerCase();
1487 },
1488
1489 //-------------------------------------------------------------------------
1490
1491 'equals': function (aValue) {
1492 var result;
1493
1494 if (aValue.isBigInt) {
1495 result = equals(this.internalValue(), aValue.internalValue());
1496 } else if (typeof(aValue) == "number") {
1497 result = equalsInt(this.internalValue(), aValue);
1498 } else {
1499 throw Clipperz.Crypt.BigInt.exception.UnknownType;
1500 }
1501
1502 return result;
1503 },
1504
1505 //-------------------------------------------------------------------------
1506
1507 'add': function (aValue) {
1508 var result;
1509
1510 if (aValue.isBigInt) {
1511 result = add(this.internalValue(), aValue.internalValue());
1512 } else {
1513 result = addInt(this.internalValue(), aValue);
1514 }
1515
1516 return new Clipperz.Crypto.BigInt(result);
1517 },
1518
1519 //-------------------------------------------------------------------------
1520
1521 'subtract': function (aValue) {
1522 var result;
1523 var value;
1524
1525 if (aValue.isBigInt) {
1526 value = aValue;
1527 } else {
1528 value = new Clipperz.Crypto.BigInt(aValue);
1529 }
1530
1531 result = sub(this.internalValue(), value.internalValue());
1532
1533 return new Clipperz.Crypto.BigInt(result);
1534 },
1535
1536 //-------------------------------------------------------------------------
1537
1538 'multiply': function (aValue, aModule) {
1539 var result;
1540 var value;
1541
1542 if (aValue.isBigInt) {
1543 value = aValue;
1544 } else {
1545 value = new Clipperz.Crypto.BigInt(aValue);
1546 }
1547
1548 if (typeof(aModule) == 'undefined') {
1549 result = mult(this.internalValue(), value.internalValue());
1550 } else {
1551 result = multMod(this.internalValue(), value.internalValue(), aModule);
1552 }
1553
1554 return new Clipperz.Crypto.BigInt(result);
1555 },
1556
1557 //-------------------------------------------------------------------------
1558
1559 'module': function (aModule) {
1560 varresult;
1561 var module;
1562
1563 if (aModule.isBigInt) {
1564 module = aModule;
1565 } else {
1566 module = new Clipperz.Crypto.BigInt(aModule);
1567 }
1568
1569 result = mod(this.internalValue(), module.internalValue());
1570
1571 return new Clipperz.Crypto.BigInt(result);
1572 },
1573
1574 //-------------------------------------------------------------------------
1575
1576 'powerModule': function(aValue, aModule) {
1577 varresult;
1578 varvalue;
1579 var module;
1580
1581 if (aValue.isBigInt) {
1582 value = aValue;
1583 } else {
1584 value = new Clipperz.Crypto.BigInt(aValue);
1585 }
1586
1587 if (aModule.isBigInt) {
1588 module = aModule;
1589 } else {
1590 module = new Clipperz.Crypto.BigInt(aModule);
1591 }
1592
1593 if (aValue == -1) {
1594 result = inverseMod(this.internalValue(), module.internalValue());
1595 } else {
1596 result = powMod(this.internalValue(), value.internalValue(), module.internalValue());
1597 }
1598
1599 return new Clipperz.Crypto.BigInt(result);
1600 },
1601
1602 //-------------------------------------------------------------------------
1603
1604 'bitSize': function() {
1605 return bitSize(this.internalValue());
1606 },
1607
1608 //-------------------------------------------------------------------------
1609 __syntaxFix__: "syntax fix"
1610
1611});
1612
1613//#############################################################################
1614
1615Clipperz.Crypto.BigInt.randomPrime = function(aBitSize) {
1616 return new Clipperz.Crypto.BigInt(randTruePrime(aBitSize));
1617}
1618
1619//#############################################################################
1620//#############################################################################
1621//#############################################################################
1622
1623Clipperz.Crypto.BigInt.equals = function(a, b) {
1624 return a.equals(b);
1625}
1626
1627Clipperz.Crypto.BigInt.add = function(a, b) {
1628 return a.add(b);
1629}
1630
1631Clipperz.Crypto.BigInt.subtract = function(a, b) {
1632 return a.subtract(b);
1633}
1634
1635Clipperz.Crypto.BigInt.multiply = function(a, b, module) {
1636 return a.multiply(b, module);
1637}
1638
1639Clipperz.Crypto.BigInt.module = function(a, module) {
1640 return a.module(module);
1641}
1642
1643Clipperz.Crypto.BigInt.powerModule = function(a, b, module) {
1644 return a.powerModule(b, module);
1645}
1646
1647Clipperz.Crypto.BigInt.exception = {
1648 UnknownType: new MochiKit.Base.NamedError("Clipperz.Crypto.BigInt.exception.UnknownType")
1649}
diff --git a/frontend/beta/js/Clipperz/Crypto/ECC.js b/frontend/beta/js/Clipperz/Crypto/ECC.js
new file mode 100644
index 0000000..c3dcec3
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/Crypto/ECC.js
@@ -0,0 +1,960 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29/*
30try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
31 throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!";
32}
33
34if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; }
35
36
37//#############################################################################
38
39Clipperz.Crypto.ECC.BinaryField = {};
40
41//#############################################################################
42
43Clipperz.Crypto.ECC.BinaryField.AbstractValue = function(aValue, aBase) {
44 return this;
45}
46
47Clipperz.Crypto.ECC.BinaryField.AbstractValue.prototype = MochiKit.Base.update(null, {
48
49 'asString': function(aBase) {
50 throw Clipperz.Base.exception.AbstractMethod;
51 },
52
53 'isZero': function() {
54 throw Clipperz.Base.exception.AbstractMethod;
55 },
56
57 'shiftLeft': function(aNumberOfBitsToShift) {
58 throw Clipperz.Base.exception.AbstractMethod;
59 },
60
61 'bitSize': function() {
62 throw Clipperz.Base.exception.AbstractMethod;
63 },
64
65 'isBitSet': function(aBitPosition) {
66 throw Clipperz.Base.exception.AbstractMethod;
67 },
68
69 'xor': function(aValue) {
70 throw Clipperz.Base.exception.AbstractMethod;
71 },
72
73 'compare': function(aValue) {
74 throw Clipperz.Base.exception.AbstractMethod;
75 },
76
77 //-----------------------------------------------------------------------------
78 __syntaxFix__: "syntax fix"
79});
80
81//*****************************************************************************
82/ *
83Clipperz.Crypto.ECC.BinaryField.BigIntValue = function(aValue, aBase) {
84 this._value = new Clipperz.Crypto.BigInt(aValue, aBase);
85 return this;
86}
87
88Clipperz.Crypto.ECC.BinaryField.BigIntValue.prototype = MochiKit.Base.update(new Clipperz.Crypto.ECC.BinaryField.AbstractValue(), {
89
90 'value': function() {
91 return this._value;
92 },
93
94 //-----------------------------------------------------------------------------
95
96 'isZero': function() {
97 return (this.value().compare(Clipperz.Crypto.ECC.BinaryField.BigIntValue.O) == 0);
98 },
99
100 //-----------------------------------------------------------------------------
101
102 'asString': function(aBase) {
103 return this.value().asString(aBase);
104 },
105
106 //-----------------------------------------------------------------------------
107
108 'shiftLeft': function(aNumberOfBitsToShift) {
109 return new Clipperz.Crypto.ECC.BinaryField.BigIntValue(this.value().shiftLeft(aNumberOfBitsToShift));
110 },
111
112 //-----------------------------------------------------------------------------
113
114 'bitSize': function() {
115 return this.value().bitSize();
116 },
117
118 //-----------------------------------------------------------------------------
119
120 'isBitSet': function(aBitPosition) {
121 return this.value().isBitSet(aBitPosition);
122 },
123
124 //-----------------------------------------------------------------------------
125
126 'xor': function(aValue) {
127 return new Clipperz.Crypto.ECC.BinaryField.BigIntValue(this.value().xor(aValue.value()));
128 },
129
130 //-----------------------------------------------------------------------------
131
132 'compare': function(aValue) {
133 return this.value().compare(aValue.value());
134 },
135
136 //-----------------------------------------------------------------------------
137 __syntaxFix__: "syntax fix"
138});
139
140Clipperz.Crypto.ECC.BinaryField.BigIntValue.O = new Clipperz.Crypto.BigInt(0);
141Clipperz.Crypto.ECC.BinaryField.BigIntValue.I = new Clipperz.Crypto.BigInt(1);
142* /
143//*****************************************************************************
144
145Clipperz.Crypto.ECC.BinaryField.WordArrayValue = function(aValue, aBase) {
146 if (aValue.constructor == String) {
147 varvalue;
148 varstringLength;
149 var numberOfWords;
150 vari,c;
151
152 if (aBase != 16) {
153 throw Clipperz.Crypto.ECC.BinaryField.WordArrayValue.exception.UnsupportedBase;
154 }
155
156 value = aValue.replace(/ /g, '');
157 stringLength = value.length;
158 numberOfWords = Math.ceil(stringLength / 8);
159 this._value = new Array(numberOfWords);
160
161 c = numberOfWords;
162 for (i=0; i<c; i++) {
163 varword;
164
165 if (i < (c-1)) {
166 word = parseInt(value.substr(stringLength-((i+1)*8), 8), 16);
167 } else {
168 word = parseInt(value.substr(0, stringLength-(i*8)), 16);
169 }
170
171 this._value[i] = word;
172 }
173 } else if (aValue.constructor == Array) {
174 var itemsToCopy;
175
176 itemsToCopy = aValue.length;
177 while (aValue[itemsToCopy - 1] == 0) {
178 itemsToCopy --;
179 }
180
181 this._value = aValue.slice(0, itemsToCopy);
182 } else if (aValue.constructor == Number) {
183 this._value = [aValue];
184 } else {
185 // throw Clipperz.Crypto.ECC.BinaryField.WordArrayValue.exception.UnsupportedConstructorValueType;
186 }
187
188 return this;
189}
190
191Clipperz.Crypto.ECC.BinaryField.WordArrayValue.prototype = MochiKit.Base.update(new Clipperz.Crypto.ECC.BinaryField.AbstractValue(), {
192
193 'value': function() {
194 return this._value;
195 },
196
197 //-----------------------------------------------------------------------------
198
199 'wordSize': function() {
200 return this._value.length
201 },
202
203 //-----------------------------------------------------------------------------
204
205 'clone': function() {
206 return new Clipperz.Crypto.ECC.BinaryField.WordArrayValue(this._value.slice(0));
207 },
208
209 //-----------------------------------------------------------------------------
210
211 'isZero': function() {
212 return (this.compare(Clipperz.Crypto.ECC.BinaryField.WordArrayValue.O) == 0);
213 },
214
215 //-----------------------------------------------------------------------------
216
217 'asString': function(aBase) {
218 varresult;
219 var i,c;
220
221 if (aBase != 16) {
222 throw Clipperz.Crypto.ECC.BinaryField.WordArrayValue.exception.UnsupportedBase;
223 }
224
225 result = "";
226 c = this.wordSize();
227 for (i=0; i<c; i++) {
228 varwordAsString;
229
230 // wordAsString = ("00000000" + this.value()[i].toString(16));
231 wordAsString = ("00000000" + this._value[i].toString(16));
232 wordAsString = wordAsString.substring(wordAsString.length - 8);
233 result = wordAsString + result;
234 }
235
236 result = result.replace(/^(00)* SPACEs THAT SHOULD BE REMOVED TO FIX THIS REGEX /, "");
237
238 if (result == "") {
239 result = "0";
240 }
241
242 return result;
243 },
244
245 //-----------------------------------------------------------------------------
246
247 'shiftLeft': function(aNumberOfBitsToShift) {
248 return new Clipperz.Crypto.ECC.BinaryField.WordArrayValue(Clipperz.Crypto.ECC.BinaryField.WordArrayValue.shiftLeft(this._value, aNumberOfBitsToShift));
249 },
250
251 //-----------------------------------------------------------------------------
252
253 'bitSize': function() {
254 return Clipperz.Crypto.ECC.BinaryField.WordArrayValue.bitSize(this._value);
255 },
256
257 //-----------------------------------------------------------------------------
258
259 'isBitSet': function(aBitPosition) {
260 return Clipperz.Crypto.ECC.BinaryField.WordArrayValue.isBitSet(this._value, aBitPosition);
261 },
262
263 //-----------------------------------------------------------------------------
264
265 'xor': function(aValue) {
266 return new Clipperz.Crypto.ECC.BinaryField.WordArrayValue(Clipperz.Crypto.ECC.BinaryField.WordArrayValue.xor(this._value, aValue._value));
267 },
268
269 //-----------------------------------------------------------------------------
270
271 'compare': function(aValue) {
272 return Clipperz.Crypto.ECC.BinaryField.WordArrayValue.compare(this._value, aValue._value);
273 },
274
275 //-----------------------------------------------------------------------------
276 __syntaxFix__: "syntax fix"
277});
278
279Clipperz.Crypto.ECC.BinaryField.WordArrayValue.O = new Clipperz.Crypto.ECC.BinaryField.WordArrayValue('0', 16);
280Clipperz.Crypto.ECC.BinaryField.WordArrayValue.I = new Clipperz.Crypto.ECC.BinaryField.WordArrayValue('1', 16);
281
282Clipperz.Crypto.ECC.BinaryField.WordArrayValue.xor = function(a, b) {
283 var result;
284 var resultSize;
285 var i,c;
286
287 resultSize = Math.max(a.length, b.length);
288
289 result = new Array(resultSize);
290 c = resultSize;
291 for (i=0; i<c; i++) {
292 // resultValue[i] = (((this.value()[i] || 0) ^ (aValue.value()[i] || 0)) >>> 0);
293 result[i] = (((a[i] || 0) ^ (b[i] || 0)) >>> 0);
294 }
295
296 return result;
297};
298
299Clipperz.Crypto.ECC.BinaryField.WordArrayValue.shiftLeft = function(aWordArray, aNumberOfBitsToShift) {
300 var numberOfWordsToShift;
301 varnumberOfBitsToShift;
302 var result;
303 varoverflowValue;
304 vari,c;
305
306 numberOfWordsToShift = Math.floor(aNumberOfBitsToShift / 32);
307 numberOfBitsToShift = aNumberOfBitsToShift % 32;
308
309 result = new Array(aWordArray.length + numberOfWordsToShift);
310
311 c = numberOfWordsToShift;
312 for (i=0; i<c; i++) {
313 result[i] = 0;
314 }
315
316 overflowValue = 0;
317 nextOverflowValue = 0;
318
319 c = aWordArray.length;
320 for (i=0; i<c; i++) {
321 varvalue;
322 varresultWord;
323
324 // value = this.value()[i];
325 value = aWordArray[i];
326
327 if (numberOfBitsToShift > 0) {
328 var nextOverflowValue;
329
330 nextOverflowValue = (value >>> (32 - numberOfBitsToShift));
331 value = value & (0xffffffff >>> numberOfBitsToShift);
332 resultWord = (((value << numberOfBitsToShift) | overflowValue) >>> 0);
333 } else {
334 resultWord = value;
335 }
336
337 result[i+numberOfWordsToShift] = resultWord;
338 overflowValue = nextOverflowValue;
339 }
340
341 if (overflowValue != 0) {
342 result[aWordArray.length + numberOfWordsToShift] = overflowValue;
343 }
344
345 return result;
346};
347
348Clipperz.Crypto.ECC.BinaryField.WordArrayValue.bitSize = function(aWordArray) {
349 varresult;
350 varnotNullElements;
351 var mostValuableWord;
352 var matchingBitsInMostImportantWord;
353 var mask;
354 var i,c;
355
356 notNullElements = aWordArray.length;
357
358 if ((aWordArray.length == 1) && (aWordArray[0] == 0)) {
359 result = 0;
360 } else {
361 while((aWordArray[notNullElements - 1] == 0) && (notNullElements > 0)) {
362 notNullElements --;
363 }
364
365 result = (notNullElements - 1) * 32;
366 mostValuableWord = aWordArray[notNullElements - 1];
367
368 matchingBits = 32;
369 mask = 0x80000000;
370
371 while ((matchingBits > 0) && ((mostValuableWord & mask) == 0)) {
372 matchingBits --;
373 mask >>>= 1;
374 }
375
376 result += matchingBits;
377 }
378
379 return result;
380};
381
382Clipperz.Crypto.ECC.BinaryField.WordArrayValue.isBitSet = function(aWordArray, aBitPosition) {
383 var result;
384 varbyteIndex;
385 var bitIndexInSelectedByte;
386
387 byteIndex = Math.floor(aBitPosition / 32);
388 bitIndexInSelectedByte = aBitPosition % 32;
389
390 if (byteIndex <= aWordArray.length) {
391 result = ((aWordArray[byteIndex] & (1 << bitIndexInSelectedByte)) != 0);
392 } else {
393 result = false;
394 }
395
396 return result;
397};
398
399Clipperz.Crypto.ECC.BinaryField.WordArrayValue.compare = function(a,b) {
400 varresult;
401 var i,c;
402
403 result = MochiKit.Base.compare(a.length, b.length);
404
405 c = a.length;
406 for (i=0; (i<c) && (result==0); i++) {
407//console.log("compare[" + c + " - " + i + " - 1] " + this.value()[c-i-1] + ", " + aValue.value()[c-i-1]);
408 // result = MochiKit.Base.compare(this.value()[c-i-1], aValue.value()[c-i-1]);
409 result = MochiKit.Base.compare(a[c-i-1], b[c-i-1]);
410 }
411
412 return result;
413};
414
415
416Clipperz.Crypto.ECC.BinaryField.WordArrayValue['exception']= {
417 'UnsupportedBase': new MochiKit.Base.NamedError("Clipperz.Crypto.ECC.BinaryField.WordArrayValue.exception.UnsupportedBase"),
418 'UnsupportedConstructorValueType':new MochiKit.Base.NamedError("Clipperz.Crypto.ECC.BinaryField.WordArrayValue.exception.UnsupportedConstructorValueType")
419};
420
421//*****************************************************************************
422
423 //Clipperz.Crypto.ECC.BinaryField.Value =Clipperz.Crypto.ECC.BinaryField.BigIntValue;
424 Clipperz.Crypto.ECC.BinaryField.Value =Clipperz.Crypto.ECC.BinaryField.WordArrayValue;
425
426//#############################################################################
427
428Clipperz.Crypto.ECC.BinaryField.Point = function(args) {
429 args = args || {};
430 this._x = args.x;
431 this._y = args.y;
432
433 return this;
434}
435
436Clipperz.Crypto.ECC.BinaryField.Point.prototype = MochiKit.Base.update(null, {
437
438 'asString': function() {
439 return "Clipperz.Crypto.ECC.BinaryField.Point (" + this.x() + ", " + this.y() + ")";
440 },
441
442 //-----------------------------------------------------------------------------
443
444 'x': function() {
445 return this._x;
446 },
447
448 'y': function() {
449 return this._y;
450 },
451
452 //-----------------------------------------------------------------------------
453
454 'isZero': function() {
455 return (this.x().isZero() && this.y().isZero())
456 },
457
458 //-----------------------------------------------------------------------------
459 __syntaxFix__: "syntax fix"
460});
461
462//#############################################################################
463
464Clipperz.Crypto.ECC.BinaryField.FiniteField = function(args) {
465 args = args || {};
466 this._modulus = args.modulus;
467
468 return this;
469}
470
471Clipperz.Crypto.ECC.BinaryField.FiniteField.prototype = MochiKit.Base.update(null, {
472
473 'asString': function() {
474 return "Clipperz.Crypto.ECC.BinaryField.FiniteField (" + this.modulus().asString() + ")";
475 },
476
477 //-----------------------------------------------------------------------------
478
479 'modulus': function() {
480 return this._modulus;
481 },
482
483 //-----------------------------------------------------------------------------
484
485 '_module': function(aValue) {
486 varresult;
487 var modulusComparison;
488//console.log(">>> binaryField.finiteField.(standard)module");
489
490 modulusComparison = Clipperz.Crypto.ECC.BinaryField.WordArrayValue.compare(aValue, this.modulus()._value);
491
492 if (modulusComparison < 0) {
493 result = aValue;
494 } else if (modulusComparison == 0) {
495 result = [0];
496 } else {
497 var modulusBitSize;
498 var resultBitSize;
499
500 result = aValue;
501
502 modulusBitSize = this.modulus().bitSize();
503 resultBitSize = Clipperz.Crypto.ECC.BinaryField.WordArrayValue.bitSize(result);
504 while (resultBitSize >= modulusBitSize) {
505 result = Clipperz.Crypto.ECC.BinaryField.WordArrayValue.xor(result, Clipperz.Crypto.ECC.BinaryField.WordArrayValue.shiftLeft(this.modulus()._value, resultBitSize - modulusBitSize));
506 resultBitSize = Clipperz.Crypto.ECC.BinaryField.WordArrayValue.bitSize(result);
507 }
508 }
509//console.log("<<< binaryField.finiteField.(standard)module");
510
511 return result;
512 },
513
514 'module': function(aValue) {
515 return new Clipperz.Crypto.ECC.BinaryField.Value(this._module(aValue._value));
516 },
517
518 //-----------------------------------------------------------------------------
519
520 '_add': function(a, b) {
521 return Clipperz.Crypto.ECC.BinaryField.WordArrayValue.xor(a, b);
522 },
523
524 'add': function(a, b) {
525 return new Clipperz.Crypto.ECC.BinaryField.Value(this._add(a._value, b._value));
526 },
527
528 //-----------------------------------------------------------------------------
529
530 'negate': function(aValue) {
531 return aValue.clone();
532 },
533
534 //-----------------------------------------------------------------------------
535/ *
536 'multiply': function(a, b) {
537 var result;
538 var valueToXor;
539 var i,c;
540
541 result = Clipperz.Crypto.ECC.BinaryField.Value.O;
542 valueToXor = b;
543 c = a.bitSize();
544 for (i=0; i<c; i++) {
545 if (a.isBitSet(i) === true) {
546 result = result.xor(valueToXor);
547 }
548 valueToXor = valueToXor.shiftLeft(1);
549 }
550 result = this.module(result);
551
552 return result;
553 },
554* /
555
556 '_multiply': function(a, b) {
557 var result;
558 var valueToXor;
559 var i,c;
560
561 result = [0];
562 valueToXor = b;
563 c = Clipperz.Crypto.ECC.BinaryField.WordArrayValue.bitSize(a);
564 for (i=0; i<c; i++) {
565 if (Clipperz.Crypto.ECC.BinaryField.WordArrayValue.isBitSet(a, i) === true) {
566 result = Clipperz.Crypto.ECC.BinaryField.WordArrayValue.xor(result, valueToXor);
567 }
568 valueToXor = Clipperz.Crypto.ECC.BinaryField.WordArrayValue.shiftLeft(valueToXor, 1);
569 }
570 result = this._module(result);
571
572 return result;
573 },
574
575 'multiply': function(a, b) {
576 return new Clipperz.Crypto.ECC.BinaryField.Value(this._multiply(a._value, b._value));
577 },
578
579 //-----------------------------------------------------------------------------
580 //
581 //Guide to Elliptic Curve Cryptography
582 //Darrel Hankerson, Alfred Menezes, Scott Vanstone
583 //- Pag: 49, Alorithm 2.34
584 //
585 //-----------------------------------------------------------------------------
586/ *
587 'square': function(aValue) {
588 varresult;
589 vart;
590 var i,c;
591
592 result = [0];
593 t = Math.max(a)
594 c = 32;
595 for (i=0; i<c; i++) {
596 var ii, cc;
597
598 cc =
599 }
600
601
602
603
604 return result;
605 },
606 * /
607 //-----------------------------------------------------------------------------
608
609 'inverse': function(aValue) {
610 varresult;
611 var b, c;
612 var u, v;
613
614 b = Clipperz.Crypto.ECC.BinaryField.Value.I;
615 c = Clipperz.Crypto.ECC.BinaryField.Value.O;
616 u = this.module(aValue);
617 v = this.modulus();
618
619 while (u.bitSize() > 1) {
620 varbitDifferenceSize;
621
622 bitDifferenceSize = u.bitSize() - v.bitSize();
623 if (bitDifferenceSize < 0) {
624 var swap;
625
626 swap = u;
627 u = v;
628 v = swap;
629
630 swap = c;
631 c = b;
632 b = swap;
633
634 bitDifferenceSize = -bitDifferenceSize;
635 }
636
637 u = this.add(u, v.shiftLeft(bitDifferenceSize));
638 b = this.add(b, c.shiftLeft(bitDifferenceSize))
639 }
640
641 result = this.module(b);
642
643 return result;
644 },
645
646 //-----------------------------------------------------------------------------
647 __syntaxFix__: "syntax fix"
648});
649
650//#############################################################################
651
652Clipperz.Crypto.ECC.BinaryField.Curve = function(args) {
653 args = args || {};
654
655 this._modulus = args.modulus;
656
657 this._a = args.a;
658 this._b = args.b;
659 this._G = args.G;
660 this._r = args.r;
661 this._h = args.h;
662
663 this._finiteField = null;
664
665 return this;
666}
667
668Clipperz.Crypto.ECC.BinaryField.Curve.prototype = MochiKit.Base.update(null, {
669
670 'asString': function() {
671 return "Clipperz.Crypto.ECC.BinaryField.Curve";
672 },
673
674 //-----------------------------------------------------------------------------
675
676 'modulus': function() {
677 return this._modulus;
678 },
679
680 'a': function() {
681 return this._a;
682 },
683
684 'b': function() {
685 return this._b;
686 },
687
688 'G': function() {
689 return this._G;
690 },
691
692 'r': function() {
693 return this._r;
694 },
695
696 'h': function() {
697 return this._h;
698 },
699
700 //-----------------------------------------------------------------------------
701
702 'finiteField': function() {
703 if (this._finiteField == null) {
704 this._finiteField = new Clipperz.Crypto.ECC.BinaryField.FiniteField({modulus:this.modulus()})
705 }
706
707 return this._finiteField;
708 },
709
710 //-----------------------------------------------------------------------------
711
712 'negate': function(aPointA) {
713 var result;
714
715 result = new Clipperz.Crypto.ECC.Point({x:aPointA.x(), y:this.finiteField().add(aPointA.y(), aPointA.x())})
716
717 return result;
718 },
719
720 //-----------------------------------------------------------------------------
721
722 'add': function(aPointA, aPointB) {
723 var result;
724
725//console.log(">>> ECC.BinaryField.Curve.add");
726 if (aPointA.isZero()) {
727//console.log("--- pointA == zero");
728 result = aPointB;
729 } else if (aPointB.isZero()) {
730//console.log("--- pointB == zero");
731 result = aPointA;
732 } else if ((aPointA.x().compare(aPointB.x()) == 0) &&
733 ((aPointA.y().compare(aPointB.y()) != 0) || aPointB.x().isZero()))
734 {
735//console.log("compare A.x - B.x: ", aPointA.x().compare(aPointB.x()));
736//console.log("compare A.y - B.y: ", (aPointA.y().compare(aPointB.y()) != 0));
737//console.log("compare B.x.isZero(): ", aPointB.x().isZero());
738
739//console.log("--- result = zero");
740 result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
741 } else {
742//console.log("--- result = ELSE");
743 varf2m;
744 var x, y;
745 var lambda;
746
747 f2m = this.finiteField();
748
749 if (aPointA.x().compare(aPointB.x()) != 0) {
750//console.log(" a.x != b.x");
751 lambda =f2m.multiply(
752 f2m.add(aPointA.y(), aPointB.y()),
753 f2m.inverse(f2m.add(aPointA.x(), aPointB.x()))
754 );
755 x = f2m.add(this.a(), f2m.multiply(lambda, lambda));
756 x = f2m.add(x, lambda);
757 x = f2m.add(x, aPointA.x());
758 x = f2m.add(x, aPointB.x());
759 } else {
760//console.log(" a.x == b.x");
761 lambda = f2m.add(aPointB.x(), f2m.multiply(aPointB.y(), f2m.inverse(aPointB.x())));
762//console.log(" lambda: " + lambda.asString(16));
763 x = f2m.add(this.a(), f2m.multiply(lambda, lambda));
764//console.log(" x (step 1): " + x.asString(16));
765 x = f2m.add(x, lambda);
766//console.log(" x (step 2): " + x.asString(16));
767 }
768
769 y = f2m.multiply(f2m.add(aPointB.x(), x), lambda);
770//console.log(" y (step 1): " + y.asString(16));
771 y = f2m.add(y, x);
772//console.log(" y (step 2): " + y.asString(16));
773 y = f2m.add(y, aPointB.y());
774//console.log(" y (step 3): " + y.asString(16));
775
776 result = new Clipperz.Crypto.ECC.BinaryField.Point({x:x, y:y})
777 }
778//console.log("<<< ECC.BinaryField.Curve.add");
779
780 return result;
781 },
782
783 //-----------------------------------------------------------------------------
784
785 'multiply': function(aValue, aPoint) {
786 var result;
787
788console.profile();
789 result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
790
791 if (aValue.isZero() == false) {
792 var k, Q;
793 var i;
794 var countIndex; countIndex = 0;
795
796 if (aValue.compare(Clipperz.Crypto.ECC.BinaryField.WordArrayValue.O) > 0) {
797 k = aValue;
798 Q = aPoint;
799 } else {
800MochiKit.Logging.logError("The Clipperz.Crypto.ECC.BinaryFields.Value does not work with negative values!!!!");
801 k = aValue.negate();
802 Q = this.negate(aPoint);
803 }
804
805//console.log("k: " + k.toString(16));
806//console.log("k.bitSize: " + k.bitSize());
807 for (i=k.bitSize()-1; i>=0; i--) {
808 result = this.add(result, result);
809 if (k.isBitSet(i)) {
810 result = this.add(result, Q);
811 }
812
813 // if (countIndex==100) {console.log("multiply.break"); break;} else countIndex++;
814 }
815 }
816console.profileEnd();
817
818 return result;
819 },
820
821 //-----------------------------------------------------------------------------
822 __syntaxFix__: "syntax fix"
823});
824
825//#############################################################################
826
827//#############################################################################
828/ *
829Clipperz.Crypto.ECC.Key = function(args) {
830 args = args || {};
831
832 return this;
833}
834
835Clipperz.Crypto.ECC.Key.prototype = MochiKit.Base.update(null, {
836
837 'asString': function() {
838 return "Clipperz.Crypto.ECC.Key";
839 },
840
841 //-----------------------------------------------------------------------------
842 __syntaxFix__: "syntax fix"
843});
844* /
845//#############################################################################
846
847
848//#############################################################################
849
850Clipperz.Crypto.ECC.StandardCurves = {};
851
852MochiKit.Base.update(Clipperz.Crypto.ECC.StandardCurves, {
853/ *
854 '_K571': null,
855 'K571': function() {
856 if (Clipperz.Crypto.ECC.StandardCurves._K571 == null) {
857 Clipperz.Crypto.ECC.StandardCurves._K571 = new Clipperz.Crypto.ECC.Curve.Koblitz({
858 exadecimalForm: '80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425',
859 a: new Clipperz.Crypto.BigInt(0),
860 G: new Clipperz.Crypto.ECC.Point({
861 x: new Clipperz.Crypto.BigInt('26eb7a859923fbc82189631f8103fe4ac9ca2970012d5d46024804801841ca44370958493b205e647da304db4ceb08cbbd1ba39494776fb988b47174dca88c7e2945283a01c8972', 16),
862 y: new Clipperz.Crypto.BigInt('349dc807f4fbf374f4aeade3bca95314dd58cec9f307a54ffc61efc006d8a2c9d4979c0ac44aea74fbebbb9f772aedcb620b01a7ba7af1b320430c8591984f601cd4c143ef1c7a3', 16)
863 }),
864 n: new Clipperz.Crypto.BigInt('1932268761508629172347675945465993672149463664853217499328617625725759571144780212268133978522706711834706712800825351461273674974066617311929682421617092503555733685276673', 16),
865 h: new Clipperz.Crypto.BigInt(4)
866 });
867 }
868
869 return Clipperz.Crypto.ECC.StandardCurves._K571;
870 },
871* /
872 //-----------------------------------------------------------------------------
873
874 '_B571': null,
875 'B571': function() { //f(z) = z^571 + z^10 + z^5 + z^2 + 1
876 if (Clipperz.Crypto.ECC.StandardCurves._B571 == null) {
877 Clipperz.Crypto.ECC.StandardCurves._B571 = new Clipperz.Crypto.ECC.BinaryField.Curve({
878 modulus: new Clipperz.Crypto.ECC.BinaryField.Value('80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425', 16),
879 a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
880 b: new Clipperz.Crypto.ECC.BinaryField.Value('02f40e7e2221f295de297117b7f3d62f5c6a97ffcb8ceff1cd6ba8ce4a9a18ad84ffabbd8efa59332be7ad6756a66e294afd185a78ff12aa520e4de739baca0c7ffeff7f2955727a', 16),
881 G: new Clipperz.Crypto.ECC.BinaryField.Point({
882 x: new Clipperz.Crypto.ECC.BinaryField.Value('0303001d34b856296c16c0d40d3cd7750a93d1d2955fa80aa5f40fc8db7b2abdbde53950f4c0d293cdd711a35b67fb1499ae60038614f1394abfa3b4c850d927e1e7769c8eec2d19', 16),
883 y: new Clipperz.Crypto.ECC.BinaryField.Value('037bf27342da639b6dccfffeb73d69d78c6c27a6009cbbca1980f8533921e8a684423e43bab08a576291af8f461bb2a8b3531d2f0485c19b16e2f1516e23dd3c1a4827af1b8ac15b', 16)
884 }),
885 // r: new Clipperz.Crypto.ECC.BinaryField.Value('3864537523017258344695351890931987344298927329706434998657235251451519142289560424536143999389415773083133881121926944486246872462816813070234528288303332411393191105285703', 10),
886 r: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16),
887 h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
888
889 // S: new Clipperz.Crypto.ECC.BinaryField.Value('2aa058f73a0e33ab486b0f610410c53a7f132310', 10),
890 // n: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16),
891 });
892
893 //-----------------------------------------------------------------------------
894 //
895 //Guide to Elliptic Curve Cryptography
896 //Darrel Hankerson, Alfred Menezes, Scott Vanstone
897 //- Pag: 56, Alorithm 2.45 (with a typo!!!)
898 //
899 //-----------------------------------------------------------------------------
900 //
901 // http://www.milw0rm.com/papers/136
902 //
903 // -------------------------------------------------------------------------
904 // Polynomial Reduction Algorithm Modulo f571
905 // -------------------------------------------------------------------------
906 //
907 // Input: Polynomial p(x) of degree 1140 or less, stored as
908 // an array of 2T machinewords.
909 // Output: p(x) mod f571(x)
910 //
911 // FOR i = T-1, ..., 0 DO
912 // SET X := P[i+T]
913 // P[i] := P[i] ^ (X<<5) ^ (X<<7) ^ (X<<10) ^ (X<<15)
914 // P[i+1] := P[i+1] ^ (X>>17) ^ (X>>22) ^ (X>>25) ^ (X>>27)
915 //
916 // SET X := P[T-1] >> 27
917 // P[0] := P[0] ^ X ^ (X<<2) ^ (X<<5) ^ (X<<10)
918 // P[T-1] := P[T-1] & 0x07ffffff
919 //
920 // RETURN P[T-1],...,P[0]
921 //
922 // -------------------------------------------------------------------------
923 //
924 Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module = function(aValue) {
925 varresult;
926 varC, T;
927 var i;
928
929//console.log(">>> binaryField.finiteField.(improved)module");
930 // C = aValue.value().slice(0);
931 C = aValue._value.slice(0);
932 for (i=35; i>=18; i--) {
933 T = C[i];
934 C[i-18] = (((C[i-18] ^ (T<<5) ^ (T<<7) ^ (T<<10) ^ (T<<15)) & 0xffffffff) >>> 0);
935 C[i-17] = ((C[i-17] ^ (T>>>27) ^ (T>>>25) ^ (T>>>22) ^ (T>>>17)) >>> 0);
936 }
937 T = (C[17] >>> 27);
938 C[0] = ((C[0] ^ T ^ ((T<<2) ^ (T<<5) ^ (T<<10)) & 0xffffffff) >>> 0);
939 C[17] = (C[17] & 0x07ffffff);
940
941 for(i=18; i<=35; i++) {
942 C[i] = 0;
943 }
944
945 result = new Clipperz.Crypto.ECC.BinaryField.WordArrayValue(C);
946//console.log("<<< binaryField.finiteField.(improved)module");
947
948 return result;
949 };
950 }
951
952 return Clipperz.Crypto.ECC.StandardCurves._B571;
953 },
954
955 //-----------------------------------------------------------------------------
956 __syntaxFix__: "syntax fix"
957});
958
959//#############################################################################
960*/
diff --git a/frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/Curve.js b/frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/Curve.js
new file mode 100644
index 0000000..042ca6c
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/Curve.js
@@ -0,0 +1,461 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
30 throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!";
31}
32if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; }
33if (typeof(Clipperz.Crypto.ECC.BinaryField) == 'undefined') { Clipperz.Crypto.ECC.BinaryField = {}; }
34
35Clipperz.Crypto.ECC.BinaryField.Curve = function(args) {
36 args = args || {};
37
38 this._modulus = args.modulus;
39
40 this._a = args.a;
41 this._b = args.b;
42 this._G = args.G;
43 this._r = args.r;
44 this._h = args.h;
45
46 this._finiteField = null;
47
48 return this;
49}
50
51Clipperz.Crypto.ECC.BinaryField.Curve.prototype = MochiKit.Base.update(null, {
52
53 'asString': function() {
54 return "Clipperz.Crypto.ECC.BinaryField.Curve";
55 },
56
57 //-----------------------------------------------------------------------------
58
59 'modulus': function() {
60 return this._modulus;
61 },
62
63 'a': function() {
64 return this._a;
65 },
66
67 'b': function() {
68 return this._b;
69 },
70
71 'G': function() {
72 return this._G;
73 },
74
75 'r': function() {
76 return this._r;
77 },
78
79 'h': function() {
80 return this._h;
81 },
82
83 //-----------------------------------------------------------------------------
84
85 'finiteField': function() {
86 if (this._finiteField == null) {
87 this._finiteField = new Clipperz.Crypto.ECC.BinaryField.FiniteField({modulus:this.modulus()})
88 }
89
90 return this._finiteField;
91 },
92
93 //-----------------------------------------------------------------------------
94
95 'negate': function(aPointA) {
96 var result;
97
98 result = new Clipperz.Crypto.ECC.Point({x:aPointA.x(), y:this.finiteField().add(aPointA.y(), aPointA.x())})
99
100 return result;
101 },
102
103 //-----------------------------------------------------------------------------
104
105 'add': function(aPointA, aPointB) {
106 var result;
107
108//console.log(">>> ECC.BinaryField.Curve.add");
109 if (aPointA.isZero()) {
110//console.log("--- pointA == zero");
111 result = aPointB;
112 } else if (aPointB.isZero()) {
113//console.log("--- pointB == zero");
114 result = aPointA;
115 } else if ((aPointA.x().compare(aPointB.x()) == 0) && ((aPointA.y().compare(aPointB.y()) != 0) || aPointB.x().isZero())) {
116//console.log("compare A.x - B.x: ", aPointA.x().compare(aPointB.x()));
117//console.log("compare A.y - B.y: ", (aPointA.y().compare(aPointB.y()) != 0));
118//console.log("compare B.x.isZero(): ", aPointB.x().isZero());
119
120//console.log("--- result = zero");
121 result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
122 } else {
123//console.log("--- result = ELSE");
124 varf2m;
125 var x, y;
126 var lambda;
127 var aX, aY, bX, bY;
128
129 aX = aPointA.x()._value;
130 aY = aPointA.y()._value;
131 bX = aPointB.x()._value;
132 bY = aPointB.y()._value;
133
134 f2m = this.finiteField();
135
136 if (aPointA.x().compare(aPointB.x()) != 0) {
137//console.log(" a.x != b.x");
138 lambda =f2m._fastMultiply(
139 f2m._add(aY, bY),
140 f2m._inverse(f2m._add(aX, bX))
141 );
142 x = f2m._add(this.a()._value, f2m._square(lambda));
143 f2m._overwriteAdd(x, lambda);
144 f2m._overwriteAdd(x, aX);
145 f2m._overwriteAdd(x, bX);
146 } else {
147//console.log(" a.x == b.x");
148 lambda = f2m._add(bX, f2m._fastMultiply(bY, f2m._inverse(bX)));
149//console.log(" lambda: " + lambda.asString(16));
150 x = f2m._add(this.a()._value, f2m._square(lambda));
151//console.log(" x (step 1): " + x.asString(16));
152 f2m._overwriteAdd(x, lambda);
153//console.log(" x (step 2): " + x.asString(16));
154 }
155
156 y = f2m._fastMultiply(f2m._add(bX, x), lambda);
157//console.log(" y (step 1): " + y.asString(16));
158 f2m._overwriteAdd(y, x);
159//console.log(" y (step 2): " + y.asString(16));
160 f2m._overwriteAdd(y, bY);
161//console.log(" y (step 3): " + y.asString(16));
162
163 result = new Clipperz.Crypto.ECC.BinaryField.Point({x:new Clipperz.Crypto.ECC.BinaryField.Value(x), y:new Clipperz.Crypto.ECC.BinaryField.Value(y)})
164 }
165//console.log("<<< ECC.BinaryField.Curve.add");
166
167 return result;
168 },
169
170 //-----------------------------------------------------------------------------
171
172 'overwriteAdd': function(aPointA, aPointB) {
173 if (aPointA.isZero()) {
174 // result = aPointB;
175 aPointA._x._value = aPointB._x._value;
176 aPointA._y._value = aPointB._y._value;
177 } else if (aPointB.isZero()) {
178 // result = aPointA;
179 } else if ((aPointA.x().compare(aPointB.x()) == 0) && ((aPointA.y().compare(aPointB.y()) != 0) || aPointB.x().isZero())) {
180 // result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
181 aPointA._x = Clipperz.Crypto.ECC.BinaryField.Value.O;
182 aPointA._y = Clipperz.Crypto.ECC.BinaryField.Value.O;
183 } else {
184 varf2m;
185 var x, y;
186 var lambda;
187 var aX, aY, bX, bY;
188
189 aX = aPointA.x()._value;
190 aY = aPointA.y()._value;
191 bX = aPointB.x()._value;
192 bY = aPointB.y()._value;
193
194 f2m = this.finiteField();
195
196 if (aPointA.x().compare(aPointB.x()) != 0) {
197//console.log(" a.x != b.x");
198 lambda =f2m._fastMultiply(
199 f2m._add(aY, bY),
200 f2m._inverse(f2m._add(aX, bX))
201 );
202 x = f2m._add(this.a()._value, f2m._square(lambda));
203 f2m._overwriteAdd(x, lambda);
204 f2m._overwriteAdd(x, aX);
205 f2m._overwriteAdd(x, bX);
206 } else {
207//console.log(" a.x == b.x");
208 lambda = f2m._add(bX, f2m._fastMultiply(bY, f2m._inverse(bX)));
209//console.log(" lambda: " + lambda.asString(16));
210 x = f2m._add(this.a()._value, f2m._square(lambda));
211//console.log(" x (step 1): " + x.asString(16));
212 f2m._overwriteAdd(x, lambda);
213//console.log(" x (step 2): " + x.asString(16));
214 }
215
216 y = f2m._fastMultiply(f2m._add(bX, x), lambda);
217//console.log(" y (step 1): " + y.asString(16));
218 f2m._overwriteAdd(y, x);
219//console.log(" y (step 2): " + y.asString(16));
220 f2m._overwriteAdd(y, bY);
221//console.log(" y (step 3): " + y.asString(16));
222
223 // result = new Clipperz.Crypto.ECC.BinaryField.Point({x:new Clipperz.Crypto.ECC.BinaryField.Value(x), y:new Clipperz.Crypto.ECC.BinaryField.Value(y)})
224 aPointA._x._value = x;
225 aPointA._y._value = y;
226
227 }
228//console.log("<<< ECC.BinaryField.Curve.add");
229
230 return result;
231 },
232
233 //-----------------------------------------------------------------------------
234
235 'multiply': function(aValue, aPoint) {
236 var result;
237
238//console.profile();
239 result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
240
241 if (aValue.isZero() == false) {
242 var k, Q;
243 var i;
244 var countIndex; countIndex = 0;
245
246 if (aValue.compare(Clipperz.Crypto.ECC.BinaryField.Value.O) > 0) {
247 k = aValue;
248 Q = aPoint;
249 } else {
250MochiKit.Logging.logError("The Clipperz.Crypto.ECC.BinaryFields.Value does not work with negative values!!!!");
251 k = aValue.negate();
252 Q = this.negate(aPoint);
253 }
254
255//console.log("k: " + k.toString(16));
256//console.log("k.bitSize: " + k.bitSize());
257 for (i=k.bitSize()-1; i>=0; i--) {
258 result = this.add(result, result);
259 // this.overwriteAdd(result, result);
260 if (k.isBitSet(i)) {
261 result = this.add(result, Q);
262 // this.overwriteAdd(result, Q);
263 }
264
265 // if (countIndex==100) {console.log("multiply.break"); break;} else countIndex++;
266 }
267 }
268//console.profileEnd();
269
270 return result;
271 },
272
273 //-----------------------------------------------------------------------------
274 __syntaxFix__: "syntax fix"
275});
276
277
278//#############################################################################
279
280Clipperz.Crypto.ECC.StandardCurves = {};
281
282MochiKit.Base.update(Clipperz.Crypto.ECC.StandardCurves, {
283/*
284 '_K571': null,
285 'K571': function() {
286 if (Clipperz.Crypto.ECC.StandardCurves._K571 == null) {
287 Clipperz.Crypto.ECC.StandardCurves._K571 = new Clipperz.Crypto.ECC.Curve.Koblitz({
288 exadecimalForm: '80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425',
289 a: new Clipperz.Crypto.BigInt(0),
290 G: new Clipperz.Crypto.ECC.Point({
291 x: new Clipperz.Crypto.BigInt('26eb7a859923fbc82189631f8103fe4ac9ca2970012d5d46024804801841ca44370958493b205e647da304db4ceb08cbbd1ba39494776fb988b47174dca88c7e2945283a01c8972', 16),
292 y: new Clipperz.Crypto.BigInt('349dc807f4fbf374f4aeade3bca95314dd58cec9f307a54ffc61efc006d8a2c9d4979c0ac44aea74fbebbb9f772aedcb620b01a7ba7af1b320430c8591984f601cd4c143ef1c7a3', 16)
293 }),
294 n: new Clipperz.Crypto.BigInt('1932268761508629172347675945465993672149463664853217499328617625725759571144780212268133978522706711834706712800825351461273674974066617311929682421617092503555733685276673', 16),
295 h: new Clipperz.Crypto.BigInt(4)
296 });
297 }
298
299 return Clipperz.Crypto.ECC.StandardCurves._K571;
300 },
301*/
302 //-----------------------------------------------------------------------------
303
304 '_B571': null,
305 'B571': function() { //f(z) = z^571 + z^10 + z^5 + z^2 + 1
306 if (Clipperz.Crypto.ECC.StandardCurves._B571 == null) {
307 Clipperz.Crypto.ECC.StandardCurves._B571 = new Clipperz.Crypto.ECC.BinaryField.Curve({
308 modulus: new Clipperz.Crypto.ECC.BinaryField.Value('80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425', 16),
309 a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
310 b: new Clipperz.Crypto.ECC.BinaryField.Value('02f40e7e2221f295de297117b7f3d62f5c6a97ffcb8ceff1cd6ba8ce4a9a18ad84ffabbd8efa59332be7ad6756a66e294afd185a78ff12aa520e4de739baca0c7ffeff7f2955727a', 16),
311 G: new Clipperz.Crypto.ECC.BinaryField.Point({
312 x: new Clipperz.Crypto.ECC.BinaryField.Value('0303001d 34b85629 6c16c0d4 0d3cd775 0a93d1d2 955fa80a a5f40fc8 db7b2abd bde53950 f4c0d293 cdd711a3 5b67fb14 99ae6003 8614f139 4abfa3b4 c850d927 e1e7769c 8eec2d19', 16),
313 y: new Clipperz.Crypto.ECC.BinaryField.Value('037bf273 42da639b 6dccfffe b73d69d7 8c6c27a6 009cbbca 1980f853 3921e8a6 84423e43 bab08a57 6291af8f 461bb2a8 b3531d2f 0485c19b 16e2f151 6e23dd3c 1a4827af 1b8ac15b', 16)
314 }),
315 r: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff e661ce18 ff559873 08059b18 6823851e c7dd9ca1 161de93d 5174d66e 8382e9bb 2fe84e47', 16),
316 h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
317
318 // S: new Clipperz.Crypto.ECC.BinaryField.Value('2aa058f73a0e33ab486b0f610410c53a7f132310', 10),
319 // n: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16),
320 });
321
322 //-----------------------------------------------------------------------------
323 //
324 //Guide to Elliptic Curve Cryptography
325 //Darrel Hankerson, Alfred Menezes, Scott Vanstone
326 //- Pag: 56, Alorithm 2.45 (with a typo!!!)
327 //
328 //-----------------------------------------------------------------------------
329 //
330 // http://www.milw0rm.com/papers/136
331 //
332 // -------------------------------------------------------------------------
333 // Polynomial Reduction Algorithm Modulo f571
334 // -------------------------------------------------------------------------
335 //
336 // Input: Polynomial p(x) of degree 1140 or less, stored as
337 // an array of 2T machinewords.
338 // Output: p(x) mod f571(x)
339 //
340 // FOR i = T-1, ..., 0 DO
341 // SET X := P[i+T]
342 // P[i] := P[i] ^ (X<<5) ^ (X<<7) ^ (X<<10) ^ (X<<15)
343 // P[i+1] := P[i+1] ^ (X>>17) ^ (X>>22) ^ (X>>25) ^ (X>>27)
344 //
345 // SET X := P[T-1] >> 27
346 // P[0] := P[0] ^ X ^ (X<<2) ^ (X<<5) ^ (X<<10)
347 // P[T-1] := P[T-1] & 0x07ffffff
348 //
349 // RETURN P[T-1],...,P[0]
350 //
351 // -------------------------------------------------------------------------
352 //
353 Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().slowModule = Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module;
354 Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module = function(aValue) {
355 varresult;
356
357 if (aValue.bitSize() > 1140) {
358 MochiKit.Logging.logWarning("ECC.StandarCurves.B571.finiteField().module: falling back to default implementation");
359 result = Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().slowModule(aValue);
360 } else {
361 varC, T;
362 var i;
363
364//console.log(">>> binaryField.finiteField.(improved)module");
365 // C = aValue.value().slice(0);
366 C = aValue._value.slice(0);
367 for (i=35; i>=18; i--) {
368 T = C[i];
369 C[i-18] = (((C[i-18] ^ (T<<5) ^ (T<<7) ^ (T<<10) ^ (T<<15)) & 0xffffffff) >>> 0);
370 C[i-17] = ((C[i-17] ^ (T>>>27) ^ (T>>>25) ^ (T>>>22) ^ (T>>>17)) >>> 0);
371 }
372 T = (C[17] >>> 27);
373 C[0] = ((C[0] ^ T ^ ((T<<2) ^ (T<<5) ^ (T<<10)) & 0xffffffff) >>> 0);
374 C[17] = (C[17] & 0x07ffffff);
375
376 for(i=18; i<=35; i++) {
377 C[i] = 0;
378 }
379
380 result = new Clipperz.Crypto.ECC.BinaryField.Value(C);
381//console.log("<<< binaryField.finiteField.(improved)module");
382 }
383
384 return result;
385 };
386 }
387
388 return Clipperz.Crypto.ECC.StandardCurves._B571;
389 },
390
391 //-----------------------------------------------------------------------------
392
393 '_B283': null,
394 'B283': function() { //f(z) = z^283 + z^12 + z^7 + z^5 + 1
395 if (Clipperz.Crypto.ECC.StandardCurves._B283 == null) {
396 Clipperz.Crypto.ECC.StandardCurves._B283 = new Clipperz.Crypto.ECC.BinaryField.Curve({
397 // modulus: new Clipperz.Crypto.ECC.BinaryField.Value('10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
398 modulus: new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
399 a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
400 b: new Clipperz.Crypto.ECC.BinaryField.Value('027b680a c8b8596d a5a4af8a 19a0303f ca97fd76 45309fa2 a581485a f6263e31 3b79a2f5', 16),
401 G: new Clipperz.Crypto.ECC.BinaryField.Point({
402 x: new Clipperz.Crypto.ECC.BinaryField.Value('05f93925 8db7dd90 e1934f8c 70b0dfec 2eed25b8 557eac9c 80e2e198 f8cdbecd 86b12053', 16),
403 y: new Clipperz.Crypto.ECC.BinaryField.Value('03676854 fe24141c b98fe6d4 b20d02b4 516ff702 350eddb0 826779c8 13f0df45 be8112f4', 16)
404 }),
405 r: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffff ffffffff ffffffff ffffffff ffffef90 399660fc 938a9016 5b042a7c efadb307', 16),
406 h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
407
408 // S: new Clipperz.Crypto.ECC.BinaryField.Value('2aa058f73a0e33ab486b0f610410c53a7f132310', 10),
409 // n: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16),
410 });
411
412 //-----------------------------------------------------------------------------
413 //
414 //Guide to Elliptic Curve Cryptography
415 //Darrel Hankerson, Alfred Menezes, Scott Vanstone
416 //- Pag: 56, Alorithm 2.43
417 //
418 //-----------------------------------------------------------------------------
419 Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().slowModule = Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().module;
420 Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().module = function(aValue) {
421 varresult;
422
423 if (aValue.bitSize() > 564) {
424 MochiKit.Logging.logWarning("ECC.StandarCurves.B283.finiteField().module: falling back to default implementation");
425 result = Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().slowModule(aValue);
426 } else {
427 varC, T;
428 var i;
429
430//console.log(">>> binaryField.finiteField.(improved)module");
431 C = aValue._value.slice(0);
432 for (i=17; i>=9; i--) {
433 T = C[i];
434 C[i-9] = (((C[i-9] ^ (T<<5) ^ (T<<10) ^ (T<<12) ^ (T<<17)) & 0xffffffff) >>> 0);
435 C[i-8] = ((C[i-8] ^ (T>>>27) ^ (T>>>22) ^ (T>>>20) ^ (T>>>15)) >>> 0);
436 }
437 T = (C[8] >>> 27);
438 C[0] = ((C[0] ^ T ^ ((T<<5) ^ (T<<7) ^ (T<<12)) & 0xffffffff) >>> 0);
439 C[8] = (C[8] & 0x07ffffff);
440
441 for(i=9; i<=17; i++) {
442 C[i] = 0;
443 }
444
445 result = new Clipperz.Crypto.ECC.BinaryField.Value(C);
446//console.log("<<< binaryField.finiteField.(improved)module");
447 }
448
449 return result;
450 };
451 }
452
453 return Clipperz.Crypto.ECC.StandardCurves._B283;
454 },
455
456 //-----------------------------------------------------------------------------
457 __syntaxFix__: "syntax fix"
458});
459
460//#############################################################################
461
diff --git a/frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js b/frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js
new file mode 100644
index 0000000..3ddf2ec
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js
@@ -0,0 +1,526 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
30 throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!";
31}
32if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; }
33if (typeof(Clipperz.Crypto.ECC.BinaryField) == 'undefined') { Clipperz.Crypto.ECC.BinaryField = {}; }
34
35Clipperz.Crypto.ECC.BinaryField.FiniteField = function(args) {
36 args = args || {};
37 this._modulus = args.modulus;
38
39 return this;
40}
41
42Clipperz.Crypto.ECC.BinaryField.FiniteField.prototype = MochiKit.Base.update(null, {
43
44 'asString': function() {
45 return "Clipperz.Crypto.ECC.BinaryField.FiniteField (" + this.modulus().asString() + ")";
46 },
47
48 //-----------------------------------------------------------------------------
49
50 'modulus': function() {
51 return this._modulus;
52 },
53
54 //-----------------------------------------------------------------------------
55
56 '_module': function(aValue) {
57 varresult;
58 var modulusComparison;
59//console.log(">>> binaryField.finiteField.(standard)module");
60
61 modulusComparison = Clipperz.Crypto.ECC.BinaryField.Value._compare(aValue, this.modulus()._value);
62
63 if (modulusComparison < 0) {
64 result = aValue;
65 } else if (modulusComparison == 0) {
66 result = [0];
67 } else {
68 var modulusBitSize;
69 var resultBitSize;
70
71 result = aValue;
72
73 modulusBitSize = this.modulus().bitSize();
74 resultBitSize = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(result);
75 while (resultBitSize >= modulusBitSize) {
76 Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor(result, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(this.modulus()._value, resultBitSize - modulusBitSize));
77 resultBitSize = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(result);
78 }
79 }
80//console.log("<<< binaryField.finiteField.(standard)module");
81
82 return result;
83 },
84
85 'module': function(aValue) {
86 return new Clipperz.Crypto.ECC.BinaryField.Value(this._module(aValue._value.slice(0)));
87 },
88
89 //-----------------------------------------------------------------------------
90
91 '_add': function(a, b) {
92 return Clipperz.Crypto.ECC.BinaryField.Value._xor(a, b);
93 },
94
95 '_overwriteAdd': function(a, b) {
96 Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor(a, b);
97 },
98
99 'add': function(a, b) {
100 return new Clipperz.Crypto.ECC.BinaryField.Value(this._add(a._value, b._value));
101 },
102
103 //-----------------------------------------------------------------------------
104
105 'negate': function(aValue) {
106 return aValue.clone();
107 },
108
109 //-----------------------------------------------------------------------------
110
111 '_multiply': function(a, b) {
112 var result;
113 var valueToXor;
114 var i,c;
115
116 result = [0];
117 valueToXor = b;
118 c = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(a);
119 for (i=0; i<c; i++) {
120 if (Clipperz.Crypto.ECC.BinaryField.Value._isBitSet(a, i) === true) {
121 Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor(result, valueToXor);
122 }
123 valueToXor = Clipperz.Crypto.ECC.BinaryField.Value._overwriteShiftLeft(valueToXor, 1);
124 }
125 result = this._module(result);
126
127 return result;
128 },
129
130 'multiply': function(a, b) {
131 return new Clipperz.Crypto.ECC.BinaryField.Value(this._multiply(a._value, b._value));
132 },
133
134 //-----------------------------------------------------------------------------
135
136 '_fastMultiply': function(a, b) {
137 var result;
138 var B;
139 var i,c;
140
141 result = [0];
142 B = b.slice(0); //Is this array copy avoidable?
143 c = 32;
144 for (i=0; i<c; i++) {
145 var ii, cc;
146
147 cc = a.length;
148 for (ii=0; ii<cc; ii++) {
149 if (((a[ii] >>> i) & 0x01) == 1) {
150 Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor(result, B, ii);
151 }
152 }
153
154 if (i < (c-1)) {
155 B = Clipperz.Crypto.ECC.BinaryField.Value._overwriteShiftLeft(B, 1);
156 }
157 }
158 result = this._module(result);
159
160 return result;
161 },
162
163 'fastMultiply': function(a, b) {
164 return new Clipperz.Crypto.ECC.BinaryField.Value(this._fastMultiply(a._value, b._value));
165 },
166
167 //-----------------------------------------------------------------------------
168 //
169 //Guide to Elliptic Curve Cryptography
170 //Darrel Hankerson, Alfred Menezes, Scott Vanstone
171 //- Pag: 49, Alorithm 2.34
172 //
173 //-----------------------------------------------------------------------------
174
175 '_square': function(aValue) {
176 var result;
177 var value;
178 var c,i;
179 var precomputedValues;
180
181 value = aValue;
182 result = new Array(value.length * 2);
183 precomputedValues = Clipperz.Crypto.ECC.BinaryField.FiniteField.squarePrecomputedBytes;
184
185 c = value.length;
186 for (i=0; i<c; i++) {
187 result[i*2] = precomputedValues[(value[i] & 0x000000ff)];
188 result[i*2] |= ((precomputedValues[(value[i] & 0x0000ff00) >>> 8]) << 16);
189
190 result[i*2 + 1] = precomputedValues[(value[i] & 0x00ff0000) >>> 16];
191 result[i*2 + 1] |= ((precomputedValues[(value[i] & 0xff000000) >>> 24]) << 16);
192 }
193
194 return this._module(result);
195 },
196
197 'square': function(aValue) {
198 return new Clipperz.Crypto.ECC.BinaryField.Value(this._square(aValue._value));
199 },
200
201 //-----------------------------------------------------------------------------
202
203 '_inverse': function(aValue) {
204 varresult;
205 var b, c;
206 var u, v;
207
208 // b = Clipperz.Crypto.ECC.BinaryField.Value.I._value;
209 b = [1];
210 // c = Clipperz.Crypto.ECC.BinaryField.Value.O._value;
211 c = [0];
212 u = this._module(aValue);
213 v = this.modulus()._value.slice(0);
214
215 while (Clipperz.Crypto.ECC.BinaryField.Value._bitSize(u) > 1) {
216 varbitDifferenceSize;
217
218 bitDifferenceSize = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(u) - Clipperz.Crypto.ECC.BinaryField.Value._bitSize(v);
219 if (bitDifferenceSize < 0) {
220 var swap;
221
222 swap = u;
223 u = v;
224 v = swap;
225
226 swap = c;
227 c = b;
228 b = swap;
229
230 bitDifferenceSize = -bitDifferenceSize;
231 }
232
233 u = this._add(u, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(v, bitDifferenceSize));
234 b = this._add(b, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(c, bitDifferenceSize));
235 // this._overwriteAdd(u, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(v, bitDifferenceSize));
236 // this._overwriteAdd(b, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(c, bitDifferenceSize));
237 }
238
239 result = this._module(b);
240
241 return result;
242 },
243
244 'inverse': function(aValue) {
245 return new Clipperz.Crypto.ECC.BinaryField.Value(this._inverse(aValue._value));
246 },
247
248 //-----------------------------------------------------------------------------
249 __syntaxFix__: "syntax fix"
250});
251
252
253Clipperz.Crypto.ECC.BinaryField.FiniteField.squarePrecomputedBytes = [
254 0x0000, // 0 = 0000 0000 -> 0000 0000 0000 0000
255 0x0001, // 1 = 0000 0001 -> 0000 0000 0000 0001
256 0x0004, // 2 = 0000 0010 -> 0000 0000 0000 0100
257 0x0005, // 3 = 0000 0011 -> 0000 0000 0000 0101
258 0x0010, // 4 = 0000 0100 -> 0000 0000 0001 0000
259 0x0011, // 5 = 0000 0101 -> 0000 0000 0001 0001
260 0x0014, // 6 = 0000 0110 -> 0000 0000 0001 0100
261 0x0015, // 7 = 0000 0111 -> 0000 0000 0001 0101
262 0x0040, // 8 = 0000 1000 -> 0000 0000 0100 0000
263 0x0041, // 9 = 0000 1001 -> 0000 0000 0100 0001
264 0x0044, // 10 = 0000 1010 -> 0000 0000 0100 0100
265 0x0045, // 11 = 0000 1011 -> 0000 0000 0100 0101
266 0x0050, // 12 = 0000 1100 -> 0000 0000 0101 0000
267 0x0051, // 13 = 0000 1101 -> 0000 0000 0101 0001
268 0x0054, // 14 = 0000 1110 -> 0000 0000 0101 0100
269 0x0055, // 15 = 0000 1111 -> 0000 0000 0101 0101
270
271 0x0100, // 16 = 0001 0000 -> 0000 0001 0000 0000
272 0x0101, // 17 = 0001 0001 -> 0000 0001 0000 0001
273 0x0104, // 18 = 0001 0010 -> 0000 0001 0000 0100
274 0x0105, // 19 = 0001 0011 -> 0000 0001 0000 0101
275 0x0110, // 20 = 0001 0100 -> 0000 0001 0001 0000
276 0x0111, // 21 = 0001 0101 -> 0000 0001 0001 0001
277 0x0114, // 22 = 0001 0110 -> 0000 0001 0001 0100
278 0x0115, // 23 = 0001 0111 -> 0000 0001 0001 0101
279 0x0140, // 24 = 0001 1000 -> 0000 0001 0100 0000
280 0x0141, // 25 = 0001 1001 -> 0000 0001 0100 0001
281 0x0144, // 26 = 0001 1010 -> 0000 0001 0100 0100
282 0x0145, // 27 = 0001 1011 -> 0000 0001 0100 0101
283 0x0150, // 28 = 0001 1100 -> 0000 0001 0101 0000
284 0x0151, // 28 = 0001 1101 -> 0000 0001 0101 0001
285 0x0154, // 30 = 0001 1110 -> 0000 0001 0101 0100
286 0x0155, // 31 = 0001 1111 -> 0000 0001 0101 0101
287
288 0x0400, // 32 = 0010 0000 -> 0000 0100 0000 0000
289 0x0401, // 33 = 0010 0001 -> 0000 0100 0000 0001
290 0x0404, // 34 = 0010 0010 -> 0000 0100 0000 0100
291 0x0405, // 35 = 0010 0011 -> 0000 0100 0000 0101
292 0x0410, // 36 = 0010 0100 -> 0000 0100 0001 0000
293 0x0411, // 37 = 0010 0101 -> 0000 0100 0001 0001
294 0x0414, // 38 = 0010 0110 -> 0000 0100 0001 0100
295 0x0415, // 39 = 0010 0111 -> 0000 0100 0001 0101
296 0x0440, // 40 = 0010 1000 -> 0000 0100 0100 0000
297 0x0441, // 41 = 0010 1001 -> 0000 0100 0100 0001
298 0x0444, // 42 = 0010 1010 -> 0000 0100 0100 0100
299 0x0445, // 43 = 0010 1011 -> 0000 0100 0100 0101
300 0x0450, // 44 = 0010 1100 -> 0000 0100 0101 0000
301 0x0451, // 45 = 0010 1101 -> 0000 0100 0101 0001
302 0x0454, // 46 = 0010 1110 -> 0000 0100 0101 0100
303 0x0455, // 47 = 0010 1111 -> 0000 0100 0101 0101
304
305 0x0500, // 48 = 0011 0000 -> 0000 0101 0000 0000
306 0x0501, // 49 = 0011 0001 -> 0000 0101 0000 0001
307 0x0504, // 50 = 0011 0010 -> 0000 0101 0000 0100
308 0x0505, // 51 = 0011 0011 -> 0000 0101 0000 0101
309 0x0510, // 52 = 0011 0100 -> 0000 0101 0001 0000
310 0x0511, // 53 = 0011 0101 -> 0000 0101 0001 0001
311 0x0514, // 54 = 0011 0110 -> 0000 0101 0001 0100
312 0x0515, // 55 = 0011 0111 -> 0000 0101 0001 0101
313 0x0540, // 56 = 0011 1000 -> 0000 0101 0100 0000
314 0x0541, // 57 = 0011 1001 -> 0000 0101 0100 0001
315 0x0544, // 58 = 0011 1010 -> 0000 0101 0100 0100
316 0x0545, // 59 = 0011 1011 -> 0000 0101 0100 0101
317 0x0550, // 60 = 0011 1100 -> 0000 0101 0101 0000
318 0x0551, // 61 = 0011 1101 -> 0000 0101 0101 0001
319 0x0554, // 62 = 0011 1110 -> 0000 0101 0101 0100
320 0x0555, // 63 = 0011 1111 -> 0000 0101 0101 0101
321
322 0x1000, // 64 = 0100 0000 -> 0001 0000 0000 0000
323 0x1001, // 65 = 0100 0001 -> 0001 0000 0000 0001
324 0x1004, // 66 = 0100 0010 -> 0001 0000 0000 0100
325 0x1005, // 67 = 0100 0011 -> 0001 0000 0000 0101
326 0x1010, // 68 = 0100 0100 -> 0001 0000 0001 0000
327 0x1011, // 69 = 0100 0101 -> 0001 0000 0001 0001
328 0x1014, // 70 = 0100 0110 -> 0001 0000 0001 0100
329 0x1015, // 71 = 0100 0111 -> 0001 0000 0001 0101
330 0x1040, // 72 = 0100 1000 -> 0001 0000 0100 0000
331 0x1041, // 73 = 0100 1001 -> 0001 0000 0100 0001
332 0x1044, // 74 = 0100 1010 -> 0001 0000 0100 0100
333 0x1045, // 75 = 0100 1011 -> 0001 0000 0100 0101
334 0x1050, // 76 = 0100 1100 -> 0001 0000 0101 0000
335 0x1051, // 77 = 0100 1101 -> 0001 0000 0101 0001
336 0x1054, // 78 = 0100 1110 -> 0001 0000 0101 0100
337 0x1055, // 79 = 0100 1111 -> 0001 0000 0101 0101
338
339 0x1100, // 80 = 0101 0000 -> 0001 0001 0000 0000
340 0x1101, // 81 = 0101 0001 -> 0001 0001 0000 0001
341 0x1104, // 82 = 0101 0010 -> 0001 0001 0000 0100
342 0x1105, // 83 = 0101 0011 -> 0001 0001 0000 0101
343 0x1110, // 84 = 0101 0100 -> 0001 0001 0001 0000
344 0x1111, // 85 = 0101 0101 -> 0001 0001 0001 0001
345 0x1114, // 86 = 0101 0110 -> 0001 0001 0001 0100
346 0x1115, // 87 = 0101 0111 -> 0001 0001 0001 0101
347 0x1140, // 88 = 0101 1000 -> 0001 0001 0100 0000
348 0x1141, // 89 = 0101 1001 -> 0001 0001 0100 0001
349 0x1144, // 90 = 0101 1010 -> 0001 0001 0100 0100
350 0x1145, // 91 = 0101 1011 -> 0001 0001 0100 0101
351 0x1150, // 92 = 0101 1100 -> 0001 0001 0101 0000
352 0x1151, // 93 = 0101 1101 -> 0001 0001 0101 0001
353 0x1154, // 94 = 0101 1110 -> 0001 0001 0101 0100
354 0x1155, // 95 = 0101 1111 -> 0001 0001 0101 0101
355
356 0x1400, // 96 = 0110 0000 -> 0001 0100 0000 0000
357 0x1401, // 97 = 0110 0001 -> 0001 0100 0000 0001
358 0x1404, // 98 = 0110 0010 -> 0001 0100 0000 0100
359 0x1405, // 99 = 0110 0011 -> 0001 0100 0000 0101
360 0x1410, //100 = 0110 0100 -> 0001 0100 0001 0000
361 0x1411, //101 = 0110 0101 -> 0001 0100 0001 0001
362 0x1414, //102 = 0110 0110 -> 0001 0100 0001 0100
363 0x1415, //103 = 0110 0111 -> 0001 0100 0001 0101
364 0x1440, //104 = 0110 1000 -> 0001 0100 0100 0000
365 0x1441, //105 = 0110 1001 -> 0001 0100 0100 0001
366 0x1444, //106 = 0110 1010 -> 0001 0100 0100 0100
367 0x1445, //107 = 0110 1011 -> 0001 0100 0100 0101
368 0x1450, //108 = 0110 1100 -> 0001 0100 0101 0000
369 0x1451, //109 = 0110 1101 -> 0001 0100 0101 0001
370 0x1454, //110 = 0110 1110 -> 0001 0100 0101 0100
371 0x1455, //111 = 0110 1111 -> 0001 0100 0101 0101
372
373 0x1500, //112 = 0111 0000 -> 0001 0101 0000 0000
374 0x1501, //113 = 0111 0001 -> 0001 0101 0000 0001
375 0x1504, //114 = 0111 0010 -> 0001 0101 0000 0100
376 0x1505, //115 = 0111 0011 -> 0001 0101 0000 0101
377 0x1510, //116 = 0111 0100 -> 0001 0101 0001 0000
378 0x1511, //117 = 0111 0101 -> 0001 0101 0001 0001
379 0x1514, //118 = 0111 0110 -> 0001 0101 0001 0100
380 0x1515, //119 = 0111 0111 -> 0001 0101 0001 0101
381 0x1540, //120 = 0111 1000 -> 0001 0101 0100 0000
382 0x1541, //121 = 0111 1001 -> 0001 0101 0100 0001
383 0x1544, //122 = 0111 1010 -> 0001 0101 0100 0100
384 0x1545, //123 = 0111 1011 -> 0001 0101 0100 0101
385 0x1550, //124 = 0111 1100 -> 0001 0101 0101 0000
386 0x1551, //125 = 0111 1101 -> 0001 0101 0101 0001
387 0x1554, //126 = 0111 1110 -> 0001 0101 0101 0100
388 0x1555, //127 = 0111 1111 -> 0001 0101 0101 0101
389
390 0x4000, //128 = 1000 0000 -> 0100 0000 0000 0000
391 0x4001, //129 = 1000 0001 -> 0100 0000 0000 0001
392 0x4004, //130 = 1000 0010 -> 0100 0000 0000 0100
393 0x4005, //131 = 1000 0011 -> 0100 0000 0000 0101
394 0x4010, //132 = 1000 0100 -> 0100 0000 0001 0000
395 0x4011, //133 = 1000 0101 -> 0100 0000 0001 0001
396 0x4014, //134 = 1000 0110 -> 0100 0000 0001 0100
397 0x4015, //135 = 1000 0111 -> 0100 0000 0001 0101
398 0x4040, //136 = 1000 1000 -> 0100 0000 0100 0000
399 0x4041, //137 = 1000 1001 -> 0100 0000 0100 0001
400 0x4044, //138 = 1000 1010 -> 0100 0000 0100 0100
401 0x4045, //139 = 1000 1011 -> 0100 0000 0100 0101
402 0x4050, //140 = 1000 1100 -> 0100 0000 0101 0000
403 0x4051, //141 = 1000 1101 -> 0100 0000 0101 0001
404 0x4054, //142 = 1000 1110 -> 0100 0000 0101 0100
405 0x4055, //143 = 1000 1111 -> 0100 0000 0101 0101
406
407 0x4100, //144 = 1001 0000 -> 0100 0001 0000 0000
408 0x4101, //145 = 1001 0001 -> 0100 0001 0000 0001
409 0x4104, //146 = 1001 0010 -> 0100 0001 0000 0100
410 0x4105, //147 = 1001 0011 -> 0100 0001 0000 0101
411 0x4110, //148 = 1001 0100 -> 0100 0001 0001 0000
412 0x4111, //149 = 1001 0101 -> 0100 0001 0001 0001
413 0x4114, //150 = 1001 0110 -> 0100 0001 0001 0100
414 0x4115, //151 = 1001 0111 -> 0100 0001 0001 0101
415 0x4140, //152 = 1001 1000 -> 0100 0001 0100 0000
416 0x4141, //153 = 1001 1001 -> 0100 0001 0100 0001
417 0x4144, //154 = 1001 1010 -> 0100 0001 0100 0100
418 0x4145, //155 = 1001 1011 -> 0100 0001 0100 0101
419 0x4150, //156 = 1001 1100 -> 0100 0001 0101 0000
420 0x4151, //157 = 1001 1101 -> 0100 0001 0101 0001
421 0x4154, //158 = 1001 1110 -> 0100 0001 0101 0100
422 0x4155, //159 = 1001 1111 -> 0100 0001 0101 0101
423
424 0x4400, //160 = 1010 0000 -> 0100 0100 0000 0000
425 0x4401, //161 = 1010 0001 -> 0100 0100 0000 0001
426 0x4404, //162 = 1010 0010 -> 0100 0100 0000 0100
427 0x4405, //163 = 1010 0011 -> 0100 0100 0000 0101
428 0x4410, //164 = 1010 0100 -> 0100 0100 0001 0000
429 0x4411, //165 = 1010 0101 -> 0100 0100 0001 0001
430 0x4414, //166 = 1010 0110 -> 0100 0100 0001 0100
431 0x4415, //167 = 1010 0111 -> 0100 0100 0001 0101
432 0x4440, //168 = 1010 1000 -> 0100 0100 0100 0000
433 0x4441, //169 = 1010 1001 -> 0100 0100 0100 0001
434 0x4444, //170 = 1010 1010 -> 0100 0100 0100 0100
435 0x4445, //171 = 1010 1011 -> 0100 0100 0100 0101
436 0x4450, //172 = 1010 1100 -> 0100 0100 0101 0000
437 0x4451, //173 = 1010 1101 -> 0100 0100 0101 0001
438 0x4454, //174 = 1010 1110 -> 0100 0100 0101 0100
439 0x4455, //175 = 1010 1111 -> 0100 0100 0101 0101
440
441 0x4500, //176 = 1011 0000 -> 0100 0101 0000 0000
442 0x4501, //177 = 1011 0001 -> 0100 0101 0000 0001
443 0x4504, //178 = 1011 0010 -> 0100 0101 0000 0100
444 0x4505, //179 = 1011 0011 -> 0100 0101 0000 0101
445 0x4510, //180 = 1011 0100 -> 0100 0101 0001 0000
446 0x4511, //181 = 1011 0101 -> 0100 0101 0001 0001
447 0x4514, //182 = 1011 0110 -> 0100 0101 0001 0100
448 0x4515, //183 = 1011 0111 -> 0100 0101 0001 0101
449 0x4540, //184 = 1011 1000 -> 0100 0101 0100 0000
450 0x4541, //185 = 1011 1001 -> 0100 0101 0100 0001
451 0x4544, //186 = 1011 1010 -> 0100 0101 0100 0100
452 0x4545, //187 = 1011 1011 -> 0100 0101 0100 0101
453 0x4550, //188 = 1011 1100 -> 0100 0101 0101 0000
454 0x4551, //189 = 1011 1101 -> 0100 0101 0101 0001
455 0x4554, //190 = 1011 1110 -> 0100 0101 0101 0100
456 0x4555, //191 = 1011 1111 -> 0100 0101 0101 0101
457
458 0x5000, //192 = 1100 0000 -> 0101 0000 0000 0000
459 0x5001, //193 = 1100 0001 -> 0101 0000 0000 0001
460 0x5004, //194 = 1100 0010 -> 0101 0000 0000 0100
461 0x5005, //195 = 1100 0011 -> 0101 0000 0000 0101
462 0x5010, //196 = 1100 0100 -> 0101 0000 0001 0000
463 0x5011, //197 = 1100 0101 -> 0101 0000 0001 0001
464 0x5014, //198 = 1100 0110 -> 0101 0000 0001 0100
465 0x5015, //199 = 1100 0111 -> 0101 0000 0001 0101
466 0x5040, //200 = 1100 1000 -> 0101 0000 0100 0000
467 0x5041, //201 = 1100 1001 -> 0101 0000 0100 0001
468 0x5044, //202 = 1100 1010 -> 0101 0000 0100 0100
469 0x5045, //203 = 1100 1011 -> 0101 0000 0100 0101
470 0x5050, //204 = 1100 1100 -> 0101 0000 0101 0000
471 0x5051, //205 = 1100 1101 -> 0101 0000 0101 0001
472 0x5054, //206 = 1100 1110 -> 0101 0000 0101 0100
473 0x5055, //207 = 1100 1111 -> 0101 0000 0101 0101
474
475 0x5100, //208 = 1101 0000 -> 0101 0001 0000 0000
476 0x5101, //209 = 1101 0001 -> 0101 0001 0000 0001
477 0x5104, //210 = 1101 0010 -> 0101 0001 0000 0100
478 0x5105, //211 = 1101 0011 -> 0101 0001 0000 0101
479 0x5110, //212 = 1101 0100 -> 0101 0001 0001 0000
480 0x5111, //213 = 1101 0101 -> 0101 0001 0001 0001
481 0x5114, //214 = 1101 0110 -> 0101 0001 0001 0100
482 0x5115, //215 = 1101 0111 -> 0101 0001 0001 0101
483 0x5140, //216 = 1101 1000 -> 0101 0001 0100 0000
484 0x5141, //217 = 1101 1001 -> 0101 0001 0100 0001
485 0x5144, //218 = 1101 1010 -> 0101 0001 0100 0100
486 0x5145, //219 = 1101 1011 -> 0101 0001 0100 0101
487 0x5150, //220 = 1101 1100 -> 0101 0001 0101 0000
488 0x5151, //221 = 1101 1101 -> 0101 0001 0101 0001
489 0x5154, //222 = 1101 1110 -> 0101 0001 0101 0100
490 0x5155, //223 = 1101 1111 -> 0101 0001 0101 0101
491
492 0x5400, //224 = 1110 0000 -> 0101 0100 0000 0000
493 0x5401, //225 = 1110 0001 -> 0101 0100 0000 0001
494 0x5404, //226 = 1110 0010 -> 0101 0100 0000 0100
495 0x5405, //227 = 1110 0011 -> 0101 0100 0000 0101
496 0x5410, //228 = 1110 0100 -> 0101 0100 0001 0000
497 0x5411, //229 = 1110 0101 -> 0101 0100 0001 0001
498 0x5414, //230 = 1110 0110 -> 0101 0100 0001 0100
499 0x5415, //231 = 1110 0111 -> 0101 0100 0001 0101
500 0x5440, //232 = 1110 1000 -> 0101 0100 0100 0000
501 0x5441, //233 = 1110 1001 -> 0101 0100 0100 0001
502 0x5444, //234 = 1110 1010 -> 0101 0100 0100 0100
503 0x5445, //235 = 1110 1011 -> 0101 0100 0100 0101
504 0x5450, //236 = 1110 1100 -> 0101 0100 0101 0000
505 0x5451, //237 = 1110 1101 -> 0101 0100 0101 0001
506 0x5454, //238 = 1110 1110 -> 0101 0100 0101 0100
507 0x5455, //239 = 1110 1111 -> 0101 0100 0101 0101
508
509 0x5500, //240 = 1111 0000 -> 0101 0101 0000 0000
510 0x5501, //241 = 1111 0001 -> 0101 0101 0000 0001
511 0x5504, //242 = 1111 0010 -> 0101 0101 0000 0100
512 0x5505, //243 = 1111 0011 -> 0101 0101 0000 0101
513 0x5510, //244 = 1111 0100 -> 0101 0101 0001 0000
514 0x5511, //245 = 1111 0101 -> 0101 0101 0001 0001
515 0x5514, //246 = 1111 0110 -> 0101 0101 0001 0100
516 0x5515, //247 = 1111 0111 -> 0101 0101 0001 0101
517 0x5540, //248 = 1111 1000 -> 0101 0101 0100 0000
518 0x5541, //249 = 1111 1001 -> 0101 0101 0100 0001
519 0x5544, //250 = 1111 1010 -> 0101 0101 0100 0100
520 0x5545, //251 = 1111 1011 -> 0101 0101 0100 0101
521 0x5550, //252 = 1111 1100 -> 0101 0101 0101 0000
522 0x5551, //253 = 1111 1101 -> 0101 0101 0101 0001
523 0x5554, //254 = 1111 1110 -> 0101 0101 0101 0100
524 0x5555 //255 = 1111 1111 -> 0101 0101 0101 0101
525
526]
diff --git a/frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/Point.js b/frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/Point.js
new file mode 100644
index 0000000..f0739bc
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/Point.js
@@ -0,0 +1,67 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
30 throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!";
31}
32if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; }
33if (typeof(Clipperz.Crypto.ECC.BinaryField) == 'undefined') { Clipperz.Crypto.ECC.BinaryField = {}; }
34
35Clipperz.Crypto.ECC.BinaryField.Point = function(args) {
36 args = args || {};
37 this._x = args.x;
38 this._y = args.y;
39
40 return this;
41}
42
43Clipperz.Crypto.ECC.BinaryField.Point.prototype = MochiKit.Base.update(null, {
44
45 'asString': function() {
46 return "Clipperz.Crypto.ECC.BinaryField.Point (" + this.x() + ", " + this.y() + ")";
47 },
48
49 //-----------------------------------------------------------------------------
50
51 'x': function() {
52 return this._x;
53 },
54
55 'y': function() {
56 return this._y;
57 },
58
59 //-----------------------------------------------------------------------------
60
61 'isZero': function() {
62 return (this.x().isZero() && this.y().isZero())
63 },
64
65 //-----------------------------------------------------------------------------
66 __syntaxFix__: "syntax fix"
67});
diff --git a/frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/Value.js b/frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/Value.js
new file mode 100644
index 0000000..10d055e
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/Crypto/ECC/BinaryField/Value.js
@@ -0,0 +1,377 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
30 throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!";
31}
32if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; }
33if (typeof(Clipperz.Crypto.ECC.BinaryField) == 'undefined') { Clipperz.Crypto.ECC.BinaryField = {}; }
34
35Clipperz.Crypto.ECC.BinaryField.Value = function(aValue, aBase) {
36 if (aValue.constructor == String) {
37 varvalue;
38 varstringLength;
39 var numberOfWords;
40 vari,c;
41
42 if (aBase != 16) {
43 throw Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedBase;
44 }
45
46 value = aValue.replace(/ /g, '');
47 stringLength = value.length;
48 numberOfWords = Math.ceil(stringLength / 8);
49 this._value = new Array(numberOfWords);
50
51 c = numberOfWords;
52 for (i=0; i<c; i++) {
53 varword;
54
55 if (i < (c-1)) {
56 word = parseInt(value.substr(stringLength-((i+1)*8), 8), 16);
57 } else {
58 word = parseInt(value.substr(0, stringLength-(i*8)), 16);
59 }
60
61 this._value[i] = word;
62 }
63 } else if (aValue.constructor == Array) {
64 var itemsToCopy;
65
66 itemsToCopy = aValue.length;
67 while (aValue[itemsToCopy - 1] == 0) {
68 itemsToCopy --;
69 }
70
71 this._value = aValue.slice(0, itemsToCopy);
72 } else if (aValue.constructor == Number) {
73 this._value = [aValue];
74 } else {
75 // throw Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedConstructorValueType;
76 }
77
78 return this;
79}
80
81Clipperz.Crypto.ECC.BinaryField.Value.prototype = MochiKit.Base.update(null, {
82
83 'value': function() {
84 return this._value;
85 },
86
87 //-----------------------------------------------------------------------------
88
89 'wordSize': function() {
90 return this._value.length
91 },
92
93 //-----------------------------------------------------------------------------
94
95 'clone': function() {
96 return new Clipperz.Crypto.ECC.BinaryField.Value(this._value.slice(0));
97 },
98
99 //-----------------------------------------------------------------------------
100
101 'isZero': function() {
102 return (this.compare(Clipperz.Crypto.ECC.BinaryField.Value.O) == 0);
103 },
104
105 //-----------------------------------------------------------------------------
106
107 'asString': function(aBase) {
108 varresult;
109 var i,c;
110
111 if (aBase != 16) {
112 throw Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedBase;
113 }
114
115 result = "";
116 c = this.wordSize();
117 for (i=0; i<c; i++) {
118 varwordAsString;
119
120 // wordAsString = ("00000000" + this.value()[i].toString(16));
121 wordAsString = ("00000000" + this._value[i].toString(16));
122 wordAsString = wordAsString.substring(wordAsString.length - 8);
123 result = wordAsString + result;
124 }
125
126 result = result.replace(/^(00)*/, "");
127
128 if (result == "") {
129 result = "0";
130 }
131
132 return result;
133 },
134
135 //-----------------------------------------------------------------------------
136
137 'shiftLeft': function(aNumberOfBitsToShift) {
138 return new Clipperz.Crypto.ECC.BinaryField.Value(Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(this._value, aNumberOfBitsToShift));
139 },
140
141 //-----------------------------------------------------------------------------
142
143 'bitSize': function() {
144 return Clipperz.Crypto.ECC.BinaryField.Value._bitSize(this._value);
145 },
146
147 //-----------------------------------------------------------------------------
148
149 'isBitSet': function(aBitPosition) {
150 return Clipperz.Crypto.ECC.BinaryField.Value._isBitSet(this._value, aBitPosition);
151 },
152
153 //-----------------------------------------------------------------------------
154
155 'xor': function(aValue) {
156 return new Clipperz.Crypto.ECC.BinaryField.Value(Clipperz.Crypto.ECC.BinaryField.Value._xor(this._value, aValue._value));
157 },
158
159 //-----------------------------------------------------------------------------
160
161 'compare': function(aValue) {
162 return Clipperz.Crypto.ECC.BinaryField.Value._compare(this._value, aValue._value);
163 },
164
165 //-----------------------------------------------------------------------------
166 __syntaxFix__: "syntax fix"
167});
168
169Clipperz.Crypto.ECC.BinaryField.Value.O = new Clipperz.Crypto.ECC.BinaryField.Value('0', 16);
170Clipperz.Crypto.ECC.BinaryField.Value.I = new Clipperz.Crypto.ECC.BinaryField.Value('1', 16);
171
172Clipperz.Crypto.ECC.BinaryField.Value._xor = function(a, b, aFirstItemOffset) {
173 var result;
174 var resultSize;
175 var i,c;
176 var firstItemOffset;
177
178 firstItemOffset = aFirstItemOffset || 0;
179 resultSize = Math.max((a.length - firstItemOffset), b.length) + firstItemOffset;
180
181 result = new Array(resultSize);
182
183 c = firstItemOffset;
184 for (i=0; i<c; i++) {
185 result[i] = a[i];
186 }
187
188 c = resultSize;
189 for (i=firstItemOffset; i<c; i++) {
190 result[i] = (((a[i] || 0) ^ (b[i - firstItemOffset] || 0)) >>> 0);
191 }
192
193 return result;
194};
195
196Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor = function(a, b, aFirstItemOffset) {
197 var i,c;
198 var firstItemOffset;
199
200 firstItemOffset = aFirstItemOffset || 0;
201
202 c = Math.max((a.length - firstItemOffset), b.length) + firstItemOffset;
203 for (i=firstItemOffset; i<c; i++) {
204 a[i] = (((a[i] || 0) ^ (b[i - firstItemOffset] || 0)) >>> 0);
205 }
206};
207
208Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft = function(aWordArray, aNumberOfBitsToShift) {
209 var numberOfWordsToShift;
210 varnumberOfBitsToShift;
211 var result;
212 varoverflowValue;
213 vari,c;
214
215 numberOfWordsToShift = Math.floor(aNumberOfBitsToShift / 32);
216 numberOfBitsToShift = aNumberOfBitsToShift % 32;
217
218 result = new Array(aWordArray.length + numberOfWordsToShift);
219
220 c = numberOfWordsToShift;
221 for (i=0; i<c; i++) {
222 result[i] = 0;
223 }
224
225 overflowValue = 0;
226 nextOverflowValue = 0;
227
228 c = aWordArray.length;
229 for (i=0; i<c; i++) {
230 varvalue;
231 varresultWord;
232
233 // value = this.value()[i];
234 value = aWordArray[i];
235
236 if (numberOfBitsToShift > 0) {
237 var nextOverflowValue;
238
239 nextOverflowValue = (value >>> (32 - numberOfBitsToShift));
240 value = value & (0xffffffff >>> numberOfBitsToShift);
241 resultWord = (((value << numberOfBitsToShift) | overflowValue) >>> 0);
242 } else {
243 resultWord = value;
244 }
245
246 result[i+numberOfWordsToShift] = resultWord;
247 overflowValue = nextOverflowValue;
248 }
249
250 if (overflowValue != 0) {
251 result[aWordArray.length + numberOfWordsToShift] = overflowValue;
252 }
253
254 return result;
255};
256
257Clipperz.Crypto.ECC.BinaryField.Value._overwriteShiftLeft = function(aWordArray, aNumberOfBitsToShift) {
258 var numberOfWordsToShift;
259 varnumberOfBitsToShift;
260 var result;
261 varoverflowValue;
262 vari,c;
263
264 numberOfWordsToShift = Math.floor(aNumberOfBitsToShift / 32);
265 numberOfBitsToShift = aNumberOfBitsToShift % 32;
266
267 result = new Array(aWordArray.length + numberOfWordsToShift);
268
269 c = numberOfWordsToShift;
270 for (i=0; i<c; i++) {
271 result[i] = 0;
272 }
273
274 overflowValue = 0;
275 nextOverflowValue = 0;
276
277 c = aWordArray.length;
278 for (i=0; i<c; i++) {
279 varvalue;
280 varresultWord;
281
282 // value = this.value()[i];
283 value = aWordArray[i];
284
285 if (numberOfBitsToShift > 0) {
286 var nextOverflowValue;
287
288 nextOverflowValue = (value >>> (32 - numberOfBitsToShift));
289 value = value & (0xffffffff >>> numberOfBitsToShift);
290 resultWord = (((value << numberOfBitsToShift) | overflowValue) >>> 0);
291 } else {
292 resultWord = value;
293 }
294
295 result[i+numberOfWordsToShift] = resultWord;
296 overflowValue = nextOverflowValue;
297 }
298
299 if (overflowValue != 0) {
300 result[aWordArray.length + numberOfWordsToShift] = overflowValue;
301 }
302
303 return result;
304};
305
306Clipperz.Crypto.ECC.BinaryField.Value._bitSize = function(aWordArray) {
307 varresult;
308 varnotNullElements;
309 var mostValuableWord;
310 var matchingBitsInMostImportantWord;
311 var mask;
312 var i,c;
313
314 notNullElements = aWordArray.length;
315
316 if ((aWordArray.length == 1) && (aWordArray[0] == 0)) {
317 result = 0;
318 } else {
319 while((aWordArray[notNullElements - 1] == 0) && (notNullElements > 0)) {
320 notNullElements --;
321 }
322
323 result = (notNullElements - 1) * 32;
324 mostValuableWord = aWordArray[notNullElements - 1];
325
326 matchingBits = 32;
327 mask = 0x80000000;
328
329 while ((matchingBits > 0) && ((mostValuableWord & mask) == 0)) {
330 matchingBits --;
331 mask >>>= 1;
332 }
333
334 result += matchingBits;
335 }
336
337 return result;
338};
339
340Clipperz.Crypto.ECC.BinaryField.Value._isBitSet = function(aWordArray, aBitPosition) {
341 var result;
342 varbyteIndex;
343 var bitIndexInSelectedByte;
344
345 byteIndex = Math.floor(aBitPosition / 32);
346 bitIndexInSelectedByte = aBitPosition % 32;
347
348 if (byteIndex <= aWordArray.length) {
349 result = ((aWordArray[byteIndex] & (1 << bitIndexInSelectedByte)) != 0);
350 } else {
351 result = false;
352 }
353
354 return result;
355};
356
357Clipperz.Crypto.ECC.BinaryField.Value._compare = function(a,b) {
358 varresult;
359 var i,c;
360
361 result = MochiKit.Base.compare(a.length, b.length);
362
363 c = a.length;
364 for (i=0; (i<c) && (result==0); i++) {
365//console.log("compare[" + c + " - " + i + " - 1] " + this.value()[c-i-1] + ", " + aValue.value()[c-i-1]);
366 // result = MochiKit.Base.compare(this.value()[c-i-1], aValue.value()[c-i-1]);
367 result = MochiKit.Base.compare(a[c-i-1], b[c-i-1]);
368 }
369
370 return result;
371};
372
373
374Clipperz.Crypto.ECC.BinaryField.Value['exception']= {
375 'UnsupportedBase': new MochiKit.Base.NamedError("Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedBase"),
376 'UnsupportedConstructorValueType':new MochiKit.Base.NamedError("Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedConstructorValueType")
377};
diff --git a/frontend/beta/js/Clipperz/Crypto/PRNG.js b/frontend/beta/js/Clipperz/Crypto/PRNG.js
new file mode 100644
index 0000000..770ceb1
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/Crypto/PRNG.js
@@ -0,0 +1,854 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
30 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
31}
32
33try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) {
34 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!";
35}
36
37try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) {
38 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!";
39}
40
41if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; }
42
43//#############################################################################
44
45Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) {
46 args = args || {};
47 //MochiKit.Base.bindMethods(this);
48
49 this._stack = new Clipperz.ByteArray();
50 this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256;
51 return this;
52}
53
54Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, {
55
56 'toString': function() {
57 return "Clipperz.Crypto.PRNG.EntropyAccumulator";
58 },
59
60 //-------------------------------------------------------------------------
61
62 'stack': function() {
63 return this._stack;
64 },
65
66 'setStack': function(aValue) {
67 this._stack = aValue;
68 },
69
70 'resetStack': function() {
71 this.stack().reset();
72 },
73
74 'maxStackLengthBeforeHashing': function() {
75 return this._maxStackLengthBeforeHashing;
76 },
77
78 //-------------------------------------------------------------------------
79
80 'addRandomByte': function(aValue) {
81 this.stack().appendByte(aValue);
82
83 if (this.stack().length() > this.maxStackLengthBeforeHashing()) {
84 this.setStack(Clipperz.Crypto.SHA.sha_d256(this.stack()));
85 }
86 },
87
88 //-------------------------------------------------------------------------
89 __syntaxFix__: "syntax fix"
90});
91
92//#############################################################################
93
94Clipperz.Crypto.PRNG.RandomnessSource = function(args) {
95 args = args || {};
96 MochiKit.Base.bindMethods(this);
97
98 this._generator = args.generator || null;
99 this._sourceId = args.sourceId || null;
100 this._boostMode = args.boostMode || false;
101
102 this._nextPoolIndex = 0;
103
104 return this;
105}
106
107Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, {
108
109 'generator': function() {
110 return this._generator;
111 },
112
113 'setGenerator': function(aValue) {
114 this._generator = aValue;
115 },
116
117 //-------------------------------------------------------------------------
118
119 'boostMode': function() {
120 return this._boostMode;
121 },
122
123 'setBoostMode': function(aValue) {
124 this._boostMode = aValue;
125 },
126
127 //-------------------------------------------------------------------------
128
129 'sourceId': function() {
130 return this._sourceId;
131 },
132
133 'setSourceId': function(aValue) {
134 this._sourceId = aValue;
135 },
136
137 //-------------------------------------------------------------------------
138
139 'nextPoolIndex': function() {
140 return this._nextPoolIndex;
141 },
142
143 'incrementNextPoolIndex': function() {
144 this._nextPoolIndex = ((this._nextPoolIndex + 1) % this.generator().numberOfEntropyAccumulators());
145 },
146
147 //-------------------------------------------------------------------------
148
149 'updateGeneratorWithValue': function(aRandomValue) {
150 if (this.generator() != null) {
151 this.generator().addRandomByte(this.sourceId(), this.nextPoolIndex(), aRandomValue);
152 this.incrementNextPoolIndex();
153 }
154 },
155
156 //-------------------------------------------------------------------------
157 __syntaxFix__: "syntax fix"
158});
159
160//#############################################################################
161
162Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) {
163 args = args || {};
164 //MochiKit.Base.bindMethods(this);
165
166 this._intervalTime = args.intervalTime || 1000;
167
168 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
169
170 this.collectEntropy();
171 return this;
172}
173
174Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
175
176 'intervalTime': function() {
177 return this._intervalTime;
178 },
179
180 //-------------------------------------------------------------------------
181
182 'collectEntropy': function() {
183 varnow;
184 varentropyByte;
185 var intervalTime;
186 now = new Date();
187 entropyByte = (now.getTime() & 0xff);
188
189 intervalTime = this.intervalTime();
190 if (this.boostMode() == true) {
191 intervalTime = intervalTime / 9;
192 }
193
194 this.updateGeneratorWithValue(entropyByte);
195 setTimeout(this.collectEntropy, intervalTime);
196 },
197
198 //-------------------------------------------------------------------------
199
200 'numberOfRandomBits': function() {
201 return 5;
202 },
203
204 //-------------------------------------------------------------------------
205
206 'pollingFrequency': function() {
207 return 10;
208 },
209
210 //-------------------------------------------------------------------------
211 __syntaxFix__: "syntax fix"
212});
213
214//*****************************************************************************
215
216Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) {
217 args = args || {};
218
219 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
220
221 this._numberOfBitsToCollectAtEachEvent = 4;
222 this._randomBitsCollector = 0;
223 this._numberOfRandomBitsCollected = 0;
224
225 MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy');
226
227 return this;
228}
229
230Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
231
232 //-------------------------------------------------------------------------
233
234 'numberOfBitsToCollectAtEachEvent': function() {
235 return this._numberOfBitsToCollectAtEachEvent;
236 },
237
238 //-------------------------------------------------------------------------
239
240 'randomBitsCollector': function() {
241 return this._randomBitsCollector;
242 },
243
244 'setRandomBitsCollector': function(aValue) {
245 this._randomBitsCollector = aValue;
246 },
247
248 'appendRandomBitsToRandomBitsCollector': function(aValue) {
249 var collectedBits;
250 var numberOfRandomBitsCollected;
251
252 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
253 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
254 this.setRandomBitsCollector(collectetBits);
255 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent();
256
257 if (numberOfRandomBitsCollected == 8) {
258 this.updateGeneratorWithValue(collectetBits);
259 numberOfRandomBitsCollected = 0;
260 this.setRandomBitsCollector(0);
261 }
262
263 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
264 },
265
266 //-------------------------------------------------------------------------
267
268 'numberOfRandomBitsCollected': function() {
269 return this._numberOfRandomBitsCollected;
270 },
271
272 'setNumberOfRandomBitsCollected': function(aValue) {
273 this._numberOfRandomBitsCollected = aValue;
274 },
275
276 //-------------------------------------------------------------------------
277
278 'collectEntropy': function(anEvent) {
279 var mouseLocation;
280 var randomBit;
281 var mask;
282
283 mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent());
284
285 mouseLocation = anEvent.mouse().client;
286 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask);
287 this.appendRandomBitsToRandomBitsCollector(randomBit)
288 },
289
290 //-------------------------------------------------------------------------
291
292 'numberOfRandomBits': function() {
293 return 1;
294 },
295
296 //-------------------------------------------------------------------------
297
298 'pollingFrequency': function() {
299 return 10;
300 },
301
302 //-------------------------------------------------------------------------
303 __syntaxFix__: "syntax fix"
304});
305
306//*****************************************************************************
307
308Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) {
309 args = args || {};
310 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
311
312 this._randomBitsCollector = 0;
313 this._numberOfRandomBitsCollected = 0;
314
315 MochiKit.Signal.connect(document, 'onkeypress', this, 'collectEntropy');
316
317 return this;
318}
319
320Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
321
322 //-------------------------------------------------------------------------
323
324 'randomBitsCollector': function() {
325 return this._randomBitsCollector;
326 },
327
328 'setRandomBitsCollector': function(aValue) {
329 this._randomBitsCollector = aValue;
330 },
331
332 'appendRandomBitToRandomBitsCollector': function(aValue) {
333 var collectedBits;
334 var numberOfRandomBitsCollected;
335
336 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
337 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
338 this.setRandomBitsCollector(collectetBits);
339 numberOfRandomBitsCollected ++;
340
341 if (numberOfRandomBitsCollected == 8) {
342 this.updateGeneratorWithValue(collectetBits);
343 numberOfRandomBitsCollected = 0;
344 this.setRandomBitsCollector(0);
345 }
346
347 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
348 },
349
350 //-------------------------------------------------------------------------
351
352 'numberOfRandomBitsCollected': function() {
353 return this._numberOfRandomBitsCollected;
354 },
355
356 'setNumberOfRandomBitsCollected': function(aValue) {
357 this._numberOfRandomBitsCollected = aValue;
358 },
359
360 //-------------------------------------------------------------------------
361
362 'collectEntropy': function(anEvent) {
363/*
364 var mouseLocation;
365 var randomBit;
366
367 mouseLocation = anEvent.mouse().client;
368
369 randomBit = ((mouseLocation.x ^ mouseLocation.y) & 0x1);
370 this.appendRandomBitToRandomBitsCollector(randomBit);
371*/
372 },
373
374 //-------------------------------------------------------------------------
375
376 'numberOfRandomBits': function() {
377 return 1;
378 },
379
380 //-------------------------------------------------------------------------
381
382 'pollingFrequency': function() {
383 return 10;
384 },
385
386 //-------------------------------------------------------------------------
387 __syntaxFix__: "syntax fix"
388});
389
390//#############################################################################
391
392Clipperz.Crypto.PRNG.Fortuna = function(args) {
393 vari,c;
394
395 args = args || {};
396
397 this._key = args.seed || null;
398 if (this._key == null) {
399 this._counter = 0;
400 this._key = new Clipperz.ByteArray();
401 } else {
402 this._counter = 1;
403 }
404
405 this._aesKey = null;
406
407 this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64;
408 this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32;
409
410 this._accumulators = [];
411 c = this.numberOfEntropyAccumulators();
412 for (i=0; i<c; i++) {
413 this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator());
414 }
415
416 this._randomnessSources = [];
417 this._reseedCounter = 0;
418
419 return this;
420}
421
422Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, {
423
424 'toString': function() {
425 return "Clipperz.Crypto.PRNG.Fortuna";
426 },
427
428 //-------------------------------------------------------------------------
429
430 'key': function() {
431 return this._key;
432 },
433
434 'setKey': function(aValue) {
435 this._key = aValue;
436 this._aesKey = null;
437 },
438
439 'aesKey': function() {
440 if (this._aesKey == null) {
441 this._aesKey = new Clipperz.Crypto.AES.Key({key:this.key()});
442 }
443
444 return this._aesKey;
445 },
446
447 'accumulators': function() {
448 return this._accumulators;
449 },
450
451 'firstPoolReseedLevel': function() {
452 return this._firstPoolReseedLevel;
453 },
454
455 //-------------------------------------------------------------------------
456
457 'reseedCounter': function() {
458 return this._reseedCounter;
459 },
460
461 'incrementReseedCounter': function() {
462 this._reseedCounter = this._reseedCounter +1;
463 },
464
465 //-------------------------------------------------------------------------
466
467 'reseed': function() {
468 varnewKeySeed;
469 var reseedCounter;
470 varreseedCounterMask;
471 var i, c;
472
473 newKeySeed = this.key();
474 this.incrementReseedCounter();
475 reseedCounter = this.reseedCounter();
476
477 c = this.numberOfEntropyAccumulators();
478 reseedCounterMask = 0xffffffff >>> (32 - c);
479 for (i=0; i<c; i++) {
480 if ((i == 0) || ((reseedCounter & (reseedCounterMask >>> (c - i))) == 0)) {
481 newKeySeed.appendBlock(this.accumulators()[i].stack());
482 this.accumulators()[i].resetStack();
483 }
484 }
485
486 if (reseedCounter == 1) {
487 c = this.randomnessSources().length;
488 for (i=0; i<c; i++) {
489 this.randomnessSources()[i].setBoostMode(false);
490 }
491 }
492
493 this.setKey(Clipperz.Crypto.SHA.sha_d256(newKeySeed));
494 if (reseedCounter == 1) {
495MochiKit.Logging.logDebug("### PRNG.readyToGenerateRandomBytes");
496 MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes');
497 }
498 MochiKit.Signal.signal(this, 'reseeded');
499 },
500
501 //-------------------------------------------------------------------------
502
503 'isReadyToGenerateRandomValues': function() {
504 return this.reseedCounter() != 0;
505 },
506
507 //-------------------------------------------------------------------------
508
509 'entropyLevel': function() {
510 return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel());
511 },
512
513 //-------------------------------------------------------------------------
514
515 'counter': function() {
516 return this._counter;
517 },
518
519 'incrementCounter': function() {
520 this._counter += 1;
521 },
522
523 'counterBlock': function() {
524 var result;
525
526 result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0);
527
528 return result;
529 },
530
531 //-------------------------------------------------------------------------
532
533 'getRandomBlock': function() {
534 var result;
535
536 result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues()));
537 this.incrementCounter();
538
539 return result;
540 },
541
542 //-------------------------------------------------------------------------
543
544 'getRandomBytes': function(aSize) {
545 var result;
546
547 if (this.isReadyToGenerateRandomValues()) {
548 var i,c;
549 var newKey;
550
551 result = new Clipperz.ByteArray();
552
553 c = Math.ceil(aSize / (128 / 8));
554 for (i=0; i<c; i++) {
555 result.appendBlock(this.getRandomBlock());
556 }
557
558 if (result.length() != aSize) {
559 result = result.split(0, aSize);
560 }
561
562 newKey = this.getRandomBlock().appendBlock(this.getRandomBlock());
563 this.setKey(newKey);
564 } else {
565MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
566 throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy;
567 }
568
569 return result;
570 },
571
572 //-------------------------------------------------------------------------
573
574 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) {
575 varselectedAccumulator;
576
577 selectedAccumulator = this.accumulators()[aPoolId];
578 selectedAccumulator.addRandomByte(aRandomValue);
579
580 if (aPoolId == 0) {
581 MochiKit.Signal.signal(this, 'addedRandomByte')
582 if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) {
583 this.reseed();
584 }
585 }
586 },
587
588 //-------------------------------------------------------------------------
589
590 'numberOfEntropyAccumulators': function() {
591 return this._numberOfEntropyAccumulators;
592 },
593
594 //-------------------------------------------------------------------------
595
596 'randomnessSources': function() {
597 return this._randomnessSources;
598 },
599
600 'addRandomnessSource': function(aRandomnessSource) {
601 aRandomnessSource.setGenerator(this);
602 aRandomnessSource.setSourceId(this.randomnessSources().length);
603 this.randomnessSources().push(aRandomnessSource);
604
605 if (this.isReadyToGenerateRandomValues() == false) {
606 aRandomnessSource.setBoostMode(true);
607 }
608 },
609
610 //-------------------------------------------------------------------------
611
612 'deferredEntropyCollection': function(aValue) {
613 var result;
614
615//MochiKit.Logging.logDebug(">>> PRNG.deferredEntropyCollection");
616
617 if (this.isReadyToGenerateRandomValues()) {
618//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 1");
619 result = aValue;
620 } else {
621//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 2");
622 var deferredResult;
623
624 Clipperz.NotificationCenter.notify(this, 'updatedProgressState', 'collectingEntropy', true);
625
626 deferredResult = new MochiKit.Async.Deferred();
627 // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.1 - PRNG.deferredEntropyCollection - 1: " + res); return res;});
628 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue));
629 // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.2 - PRNG.deferredEntropyCollection - 2: " + res); return res;});
630 MochiKit.Signal.connect(this,
631 'readyToGenerateRandomBytes',
632 deferredResult,
633 'callback');
634
635 result = deferredResult;
636 }
637//MochiKit.Logging.logDebug("<<< PRNG.deferredEntropyCollection - result: " + result);
638
639 return result;
640 },
641
642 //-------------------------------------------------------------------------
643
644 'fastEntropyAccumulationForTestingPurpose': function() {
645 while (! this.isReadyToGenerateRandomValues()) {
646 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256));
647 }
648 },
649
650 //-------------------------------------------------------------------------
651
652 'dump': function(appendToDoc) {
653 var tbl;
654 var i,c;
655
656 tbl = document.createElement("table");
657 tbl.border = 0;
658 with (tbl.style) {
659 border = "1px solid lightgrey";
660 fontFamily = 'Helvetica, Arial, sans-serif';
661 fontSize = '8pt';
662 //borderCollapse = "collapse";
663 }
664 var hdr = tbl.createTHead();
665 var hdrtr = hdr.insertRow(0);
666 // document.createElement("tr");
667 {
668 var ntd;
669
670 ntd = hdrtr.insertCell(0);
671 ntd.style.borderBottom = "1px solid lightgrey";
672 ntd.style.borderRight = "1px solid lightgrey";
673 ntd.appendChild(document.createTextNode("#"));
674
675 ntd = hdrtr.insertCell(1);
676 ntd.style.borderBottom = "1px solid lightgrey";
677 ntd.style.borderRight = "1px solid lightgrey";
678 ntd.appendChild(document.createTextNode("s"));
679
680 ntd = hdrtr.insertCell(2);
681 ntd.colSpan = this.firstPoolReseedLevel();
682 ntd.style.borderBottom = "1px solid lightgrey";
683 ntd.style.borderRight = "1px solid lightgrey";
684 ntd.appendChild(document.createTextNode("base values"));
685
686 ntd = hdrtr.insertCell(3);
687 ntd.colSpan = 20;
688 ntd.style.borderBottom = "1px solid lightgrey";
689 ntd.appendChild(document.createTextNode("extra values"));
690
691 }
692
693 c = this.accumulators().length;
694 for (i=0; i<c ; i++) {
695 varcurrentAccumulator;
696 var bdytr;
697 var bdytd;
698 var ii, cc;
699
700 currentAccumulator = this.accumulators()[i]
701
702 bdytr = tbl.insertRow(true);
703
704 bdytd = bdytr.insertCell(0);
705 bdytd.style.borderRight = "1px solid lightgrey";
706 bdytd.style.color = "lightgrey";
707 bdytd.appendChild(document.createTextNode("" + i));
708
709 bdytd = bdytr.insertCell(1);
710 bdytd.style.borderRight = "1px solid lightgrey";
711 bdytd.style.color = "gray";
712 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length()));
713
714
715 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel());
716 for (ii=0; ii<cc; ii++) {
717 var cellText;
718
719 bdytd = bdytr.insertCell(ii + 2);
720
721 if (ii < currentAccumulator.stack().length()) {
722 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii));
723 } else {
724 cellText = "_";
725 }
726
727 if (ii == (this.firstPoolReseedLevel() - 1)) {
728 bdytd.style.borderRight = "1px solid lightgrey";
729 }
730
731 bdytd.appendChild(document.createTextNode(cellText));
732 }
733
734 }
735
736
737 if (appendToDoc) {
738 var ne = document.createElement("div");
739 ne.id = "entropyGeneratorStatus";
740 with (ne.style) {
741 fontFamily = "Courier New, monospace";
742 fontSize = "12px";
743 lineHeight = "16px";
744 borderTop = "1px solid black";
745 padding = "10px";
746 }
747 if (document.getElementById(ne.id)) {
748 MochiKit.DOM.swapDOM(ne.id, ne);
749 } else {
750 document.body.appendChild(ne);
751 }
752 ne.appendChild(tbl);
753 }
754
755 return tbl;
756 },
757
758 //-----------------------------------------------------------------------------
759 __syntaxFix__: "syntax fix"
760});
761
762//#############################################################################
763
764Clipperz.Crypto.PRNG.Random = function(args) {
765 args = args || {};
766 //MochiKit.Base.bindMethods(this);
767
768 return this;
769}
770
771Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
772
773 'toString': function() {
774 return "Clipperz.Crypto.PRNG.Random";
775 },
776
777 //-------------------------------------------------------------------------
778
779 'getRandomBytes': function(aSize) {
780//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes");
781 varresult;
782 var i,c;
783
784 result = new Clipperz.ByteArray()
785 c = aSize || 1;
786 for (i=0; i<c; i++) {
787 result.appendByte((Math.random()*255) & 0xff);
788 }
789
790//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes");
791 return result;
792 },
793
794 //-------------------------------------------------------------------------
795 __syntaxFix__: "syntax fix"
796});
797
798//#############################################################################
799
800_clipperz_crypt_prng_defaultPRNG = null;
801
802Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
803 if (_clipperz_crypt_prng_defaultPRNG == null) {
804 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna();
805
806 //.............................................................
807 //
808 // TimeRandomnessSource
809 //
810 //.............................................................
811 {
812 var newRandomnessSource;
813
814 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111});
815 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
816 }
817
818 //.............................................................
819 //
820 // MouseRandomnessSource
821 //
822 //.............................................................
823 {
824 varnewRandomnessSource;
825
826 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource();
827 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
828 }
829
830 //.............................................................
831 //
832 // KeyboardRandomnessSource
833 //
834 //.............................................................
835 {
836 varnewRandomnessSource;
837
838 newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource();
839 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
840 }
841
842 }
843
844 return _clipperz_crypt_prng_defaultPRNG;
845};
846
847//#############################################################################
848
849Clipperz.Crypto.PRNG.exception = {
850 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy")
851};
852
853
854MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator);
diff --git a/frontend/beta/js/Clipperz/Crypto/RSA.js b/frontend/beta/js/Clipperz/Crypto/RSA.js
new file mode 100644
index 0000000..4dad8f7
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/Crypto/RSA.js
@@ -0,0 +1,151 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) {
30 throw "Clipperz.Crypto.RSA depends on Clipperz.Crypto.BigInt!";
31}
32
33if (typeof(Clipperz.Crypto.RSA) == 'undefined') { Clipperz.Crypto.RSA = {}; }
34
35Clipperz.Crypto.RSA.VERSION = "0.1";
36Clipperz.Crypto.RSA.NAME = "Clipperz.RSA";
37
38//#############################################################################
39
40MochiKit.Base.update(Clipperz.Crypto.RSA, {
41
42 //-------------------------------------------------------------------------
43
44 'publicKeyWithValues': function (e, d, n) {
45 varresult;
46
47 result = {};
48
49 if (e.isBigInt) {
50 result.e = e;
51 } else {
52 result.e = new Clipperz.Crypto.BigInt(e, 16);
53 }
54
55 if (d.isBigInt) {
56 result.d = d;
57 } else {
58 result.d = new Clipperz.Crypto.BigInt(d, 16);
59 }
60
61 if (n.isBigInt) {
62 result.n = n;
63 } else {
64 result.n = new Clipperz.Crypto.BigInt(n, 16);
65 }
66
67 return result;
68 },
69
70 'privateKeyWithValues': function(e, d, n) {
71 return Clipperz.Crypto.RSA.publicKeyWithValues(e, d, n);
72 },
73
74 //-----------------------------------------------------------------------------
75
76 'encryptUsingPublicKey': function (aKey, aMessage) {
77 varmessageValue;
78 varresult;
79
80 messageValue = new Clipperz.Crypto.BigInt(aMessage, 16);
81 result = messageValue.powerModule(aKey.e, aKey.n);
82
83 return result.asString(16);
84 },
85
86 //.............................................................................
87
88 'decryptUsingPublicKey': function (aKey, aMessage) {
89 return Clipperz.Crypto.RSA.encryptUsingPublicKey(aKey, aMessage);
90 },
91
92 //-----------------------------------------------------------------------------
93
94 'encryptUsingPrivateKey': function (aKey, aMessage) {
95 varmessageValue;
96 varresult;
97
98 messageValue = new Clipperz.Crypto.BigInt(aMessage, 16);
99 result = messageValue.powerModule(aKey.d, aKey.n);
100
101 return result.asString(16);
102 },
103
104 //.............................................................................
105
106 'decryptUsingPrivateKey': function (aKey, aMessage) {
107 return Clipperz.Crypto.RSA.encryptUsingPrivateKey(aKey, aMessage);
108 },
109
110 //-----------------------------------------------------------------------------
111
112 'generatePublicKey': function(aNumberOfBits) {
113 varresult;
114 vare;
115 vard;
116 varn;
117
118 e = new Clipperz.Crypto.BigInt("10001", 16);
119
120 {
121 var p, q;
122 varphi;
123
124 do {
125 p = Clipperz.Crypto.BigInt.randomPrime(aNumberOfBits);
126 } while (p.module(e).equals(1));
127
128 do {
129 q = Clipperz.Crypto.BigInt.randomPrime(aNumberOfBits);
130 } while ((q.equals(p)) || (q.module(e).equals(1)));
131
132 n = p.multiply(q);
133 phi = (p.subtract(1).multiply(q.subtract(1)));
134 d = e.powerModule(-1, phi);
135 }
136
137 result = Clipperz.Crypto.RSA.publicKeyWithValues(e, d, n);
138
139 return result;
140 },
141
142 //-------------------------------------------------------------------------
143
144 __syntaxFix__: "syntax fix"
145
146 //-------------------------------------------------------------------------
147
148});
149
150//#############################################################################
151
diff --git a/frontend/beta/js/Clipperz/Crypto/SHA.js b/frontend/beta/js/Clipperz/Crypto/SHA.js
new file mode 100644
index 0000000..bb50b4f
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/Crypto/SHA.js
@@ -0,0 +1,296 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
30 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
31}
32
33if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
34if (typeof(Clipperz.Crypto.SHA) == 'undefined') { Clipperz.Crypto.SHA = {}; }
35
36Clipperz.Crypto.SHA.VERSION = "0.3";
37Clipperz.Crypto.SHA.NAME = "Clipperz.Crypto.SHA";
38
39MochiKit.Base.update(Clipperz.Crypto.SHA, {
40
41 '__repr__': function () {
42 return "[" + this.NAME + " " + this.VERSION + "]";
43 },
44
45 'toString': function () {
46 return this.__repr__();
47 },
48
49 //-----------------------------------------------------------------------------
50
51 'rotateRight': function(aValue, aNumberOfBits) {
52//Clipperz.Profile.start("Clipperz.Crypto.SHA.rotateRight");
53 var result;
54
55 result = (aValue >>> aNumberOfBits) | (aValue << (32 - aNumberOfBits));
56
57//Clipperz.Profile.stop("Clipperz.Crypto.SHA.rotateRight");
58 return result;
59 },
60
61 'shiftRight': function(aValue, aNumberOfBits) {
62//Clipperz.Profile.start("Clipperz.Crypto.SHA.shiftRight");
63 var result;
64
65 result = aValue >>> aNumberOfBits;
66
67//Clipperz.Profile.stop("Clipperz.Crypto.SHA.shiftRight");
68 return result;
69 },
70
71 //-----------------------------------------------------------------------------
72
73 'safeAdd': function() {
74//Clipperz.Profile.start("Clipperz.Crypto.SHA.safeAdd");
75 varresult;
76 vari, c;
77
78 result = arguments[0];
79 c = arguments.length;
80 for (i=1; i<c; i++) {
81 varlowerBytesSum;
82
83 lowerBytesSum = (result & 0xffff) + (arguments[i] & 0xffff);
84 result = (((result >> 16) + (arguments[i] >> 16) + (lowerBytesSum >> 16)) << 16) | (lowerBytesSum & 0xffff);
85 }
86
87//Clipperz.Profile.stop("Clipperz.Crypto.SHA.safeAdd");
88 return result;
89 },
90
91 //-----------------------------------------------------------------------------
92
93 'sha256_array': function(aValue) {
94//Clipperz.Profile.start("Clipperz.Crypto.SHA.sha256_array");
95 varresult;
96 varmessage;
97 var h0, h1, h2, h3, h4, h5, h6, h7;
98 vark;
99 varmessageLength;
100 varmessageLengthInBits;
101 var_i, _c;
102 var charBits;
103 var rotateRight;
104 var shiftRight;
105 var safeAdd;
106 varbytesPerBlock;
107 var currentMessageIndex;
108
109 bytesPerBlock = 512/8;
110 rotateRight = Clipperz.Crypto.SHA.rotateRight;
111 shiftRight = Clipperz.Crypto.SHA.shiftRight;
112 safeAdd = Clipperz.Crypto.SHA.safeAdd;
113
114 charBits = 8;
115
116 h0 = 0x6a09e667;
117 h1 = 0xbb67ae85;
118 h2 = 0x3c6ef372;
119 h3 = 0xa54ff53a;
120 h4 = 0x510e527f;
121 h5 = 0x9b05688c;
122 h6 = 0x1f83d9ab;
123 h7 = 0x5be0cd19;
124
125 k = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
126 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
127 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
128 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
129 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
130 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
131 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
132 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
133
134 message = aValue;
135 messageLength = message.length;
136
137 //Pre-processing:
138 message.push(0x80); //append a single "1" bit to message
139
140 _c = (512 - (((messageLength + 1) * charBits) % 512) - 64) / charBits;
141 for (_i=0; _i<_c; _i++) {
142 message.push(0x00); //append "0" bits until message length ≡ 448 ≡ -64 (mod 512)
143 }
144 messageLengthInBits = messageLength * charBits;
145 message.push(0x00); //the 4 most high byte are alway 0 as message length is represented with a 32bit value;
146 message.push(0x00);
147 message.push(0x00);
148 message.push(0x00);
149 message.push((messageLengthInBits >> 24)& 0xff);
150 message.push((messageLengthInBits >> 16)& 0xff);
151 message.push((messageLengthInBits >> 8) & 0xff);
152 message.push( messageLengthInBits & 0xff);
153
154 currentMessageIndex = 0;
155 while(currentMessageIndex < message.length) {
156 varw;
157 vara, b, c, d, e, f, g, h;
158
159 w = Array(64);
160
161 _c = 16;
162 for (_i=0; _i<_c; _i++) {
163 var _j;
164
165 _j = currentMessageIndex + _i*4;
166 w[_i] = (message[_j] << 24) | (message[_j + 1] << 16) | (message[_j + 2] << 8) | (message[_j + 3] << 0);
167 }
168
169 _c = 64;
170 for (_i=16; _i<_c; _i++) {
171 vars0, s1;
172
173 s0 = (rotateRight(w[_i-15], 7)) ^ (rotateRight(w[_i-15], 18)) ^ (shiftRight(w[_i-15], 3));
174 s1 = (rotateRight(w[_i-2], 17)) ^ (rotateRight(w[_i-2], 19)) ^ (shiftRight(w[_i-2], 10));
175 w[_i] = safeAdd(w[_i-16], s0, w[_i-7], s1);
176 }
177
178 a=h0; b=h1; c=h2; d=h3; e=h4; f=h5; g=h6; h=h7;
179
180 _c = 64;
181 for (_i=0; _i<_c; _i++) {
182 var s0, s1, ch, maj, t1, t2;
183
184 s0 = (rotateRight(a, 2)) ^ (rotateRight(a, 13)) ^ (rotateRight(a, 22));
185 maj = (a & b) ^ (a & c) ^ (b & c);
186 t2 = safeAdd(s0, maj);
187 s1 = (rotateRight(e, 6)) ^ (rotateRight(e, 11)) ^ (rotateRight(e, 25));
188 ch = (e & f) ^ ((~e) & g);
189 t1 = safeAdd(h, s1, ch, k[_i], w[_i]);
190
191 h = g;
192 g = f;
193 f = e;
194 e = safeAdd(d, t1);
195 d = c;
196 c = b;
197 b = a;
198 a = safeAdd(t1, t2);
199 }
200
201 h0 = safeAdd(h0, a);
202 h1 = safeAdd(h1, b);
203 h2 = safeAdd(h2, c);
204 h3 = safeAdd(h3, d);
205 h4 = safeAdd(h4, e);
206 h5 = safeAdd(h5, f);
207 h6 = safeAdd(h6, g);
208 h7 = safeAdd(h7, h);
209
210 currentMessageIndex += bytesPerBlock;
211 }
212
213 result = new Array(256/8);
214 result[0] = (h0 >> 24)& 0xff;
215 result[1] = (h0 >> 16)& 0xff;
216 result[2] = (h0 >> 8)& 0xff;
217 result[3] = h0 & 0xff;
218
219 result[4] = (h1 >> 24)& 0xff;
220 result[5] = (h1 >> 16)& 0xff;
221 result[6] = (h1 >> 8)& 0xff;
222 result[7] = h1 & 0xff;
223
224 result[8] = (h2 >> 24)& 0xff;
225 result[9] = (h2 >> 16)& 0xff;
226 result[10] = (h2 >> 8)& 0xff;
227 result[11] = h2 & 0xff;
228
229 result[12] = (h3 >> 24)& 0xff;
230 result[13] = (h3 >> 16)& 0xff;
231 result[14] = (h3 >> 8)& 0xff;
232 result[15] = h3 & 0xff;
233
234 result[16] = (h4 >> 24)& 0xff;
235 result[17] = (h4 >> 16)& 0xff;
236 result[18] = (h4 >> 8)& 0xff;
237 result[19] = h4 & 0xff;
238
239 result[20] = (h5 >> 24)& 0xff;
240 result[21] = (h5 >> 16)& 0xff;
241 result[22] = (h5 >> 8)& 0xff;
242 result[23] = h5 & 0xff;
243
244 result[24] = (h6 >> 24)& 0xff;
245 result[25] = (h6 >> 16)& 0xff;
246 result[26] = (h6 >> 8)& 0xff;
247 result[27] = h6 & 0xff;
248
249 result[28] = (h7 >> 24)& 0xff;
250 result[29] = (h7 >> 16)& 0xff;
251 result[30] = (h7 >> 8)& 0xff;
252 result[31] = h7 & 0xff;
253
254//Clipperz.Profile.stop("Clipperz.Crypto.SHA.sha256_array");
255 return result;
256 },
257
258 //-----------------------------------------------------------------------------
259
260 'sha256': function(aValue) {
261//Clipperz.Profile.start("Clipperz.Crypto.SHA.sha256");
262 var result;
263 var resultArray;
264 varvalueArray;
265
266 valueArray = aValue.arrayValues();
267 resultArray = Clipperz.Crypto.SHA.sha256_array(valueArray);
268
269 result = new Clipperz.ByteArray(resultArray);
270
271//Clipperz.Profile.stop("Clipperz.Crypto.SHA.sha256");
272 return result;
273 },
274
275 //-----------------------------------------------------------------------------
276
277 'sha_d256': function(aValue) {
278//Clipperz.Profile.start("Clipperz.Crypto.SHA.sha_d256");
279 var result;
280 var resultArray;
281 varvalueArray;
282
283 valueArray = aValue.arrayValues();
284 resultArray = Clipperz.Crypto.SHA.sha256_array(valueArray);
285 resultArray = Clipperz.Crypto.SHA.sha256_array(resultArray);
286
287 result = new Clipperz.ByteArray(resultArray);
288
289//Clipperz.Profile.stop("Clipperz.Crypto.SHA.sha256");
290 return result;
291 },
292
293 //-----------------------------------------------------------------------------
294 __syntaxFix__: "syntax fix"
295
296});
diff --git a/frontend/beta/js/Clipperz/Crypto/SRP.js b/frontend/beta/js/Clipperz/Crypto/SRP.js
new file mode 100644
index 0000000..0eef6ec
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/Crypto/SRP.js
@@ -0,0 +1,331 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
30 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
31}
32
33try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) {
34 throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!";
35}
36
37try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) {
38 throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!";
39}
40
41if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; }
42
43Clipperz.Crypto.SRP.VERSION = "0.1";
44Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP";
45
46//#############################################################################
47
48MochiKit.Base.update(Clipperz.Crypto.SRP, {
49
50 '_n': null,
51 '_g': null,
52 //-------------------------------------------------------------------------
53
54 'n': function() {
55 if (Clipperz.Crypto.SRP._n == null) {
56 Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16);
57 }
58
59 return Clipperz.Crypto.SRP._n;
60 },
61
62 //-------------------------------------------------------------------------
63
64 'g': function() {
65 if (Clipperz.Crypto.SRP._g == null) {
66 Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); //eventually 5 (as suggested on the Diffi-Helmann documentation)
67 }
68
69 return Clipperz.Crypto.SRP._g;
70 },
71
72 //-----------------------------------------------------------------------------
73
74 'exception': {
75 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue")
76 },
77
78 //-------------------------------------------------------------------------
79 __syntaxFix__: "syntax fix"
80
81});
82
83//#############################################################################
84//
85 // S R P C o n n e c t i o n version 1.0
86//
87//=============================================================================
88Clipperz.Crypto.SRP.Connection = function (args) {
89 args = args || {};
90
91 this._C = args.C;
92 this._P = args.P;
93 this.hash = args.hash;
94
95 this._a = null;
96 this._A = null;
97
98 this._s = null;
99 this._B = null;
100
101 this._x = null;
102
103 this._u = null;
104 this._K = null;
105 this._M1 = null;
106 this._M2 = null;
107
108 this._sessionKey = null;
109
110 return this;
111}
112
113Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
114
115 'toString': function () {
116 return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription();
117 },
118
119 //-------------------------------------------------------------------------
120
121 'C': function () {
122 return this._C;
123 },
124
125 //-------------------------------------------------------------------------
126
127 'P': function () {
128 return this._P;
129 },
130
131 //-------------------------------------------------------------------------
132
133 'a': function () {
134 if (this._a == null) {
135 this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16);
136 // this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10);
137//MochiKit.Logging.logDebug("SRP a: " + this._a);
138 }
139
140 return this._a;
141 },
142
143 //-------------------------------------------------------------------------
144
145 'A': function () {
146 if (this._A == null) {
147 //Warning: this value should be strictly greater than zero: how should we perform this check?
148 this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n());
149
150 if (this._A.equals(0)) {
151MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0.");
152 throw Clipperz.Crypto.SRP.exception.InvalidValue;
153 }
154//MochiKit.Logging.logDebug("SRP A: " + this._A);
155 }
156
157 return this._A;
158 },
159
160 //-------------------------------------------------------------------------
161
162 's': function () {
163 return this._s;
164//MochiKit.Logging.logDebug("SRP s: " + this._S);
165 },
166
167 'set_s': function(aValue) {
168 this._s = aValue;
169 },
170
171 //-------------------------------------------------------------------------
172
173 'B': function () {
174 return this._B;
175 },
176
177 'set_B': function(aValue) {
178 //Warning: this value should be strictly greater than zero: how should we perform this check?
179 if (! aValue.equals(0)) {
180 this._B = aValue;
181//MochiKit.Logging.logDebug("SRP B: " + this._B);
182 } else {
183MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0.");
184 throw Clipperz.Crypto.SRP.exception.InvalidValue;
185 }
186 },
187
188 //-------------------------------------------------------------------------
189
190 'x': function () {
191 if (this._x == null) {
192 this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16);
193//MochiKit.Logging.logDebug("SRP x: " + this._x);
194 }
195
196 return this._x;
197 },
198
199 //-------------------------------------------------------------------------
200
201 'u': function () {
202 if (this._u == null) {
203 this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.B().asString()), 16);
204//MochiKit.Logging.logDebug("SRP u: " + this._u);
205 }
206
207 return this._u;
208 },
209
210 //-------------------------------------------------------------------------
211
212 'S': function () {
213 if (this._S == null) {
214 var bigint;
215 varsrp;
216
217 bigint = Clipperz.Crypto.BigInt;
218 srp = Clipperz.Crypto.SRP;
219
220 this._S =bigint.powerModule(
221 bigint.subtract(this.B(), bigint.powerModule(srp.g(), this.x(), srp.n())),
222 bigint.add(this.a(), bigint.multiply(this.u(), this.x())),
223 srp.n()
224 )
225//MochiKit.Logging.logDebug("SRP S: " + this._S);
226 }
227
228 return this._S;
229 },
230
231 //-------------------------------------------------------------------------
232
233 'K': function () {
234 if (this._K == null) {
235 this._K = this.stringHash(this.S().asString());
236//MochiKit.Logging.logDebug("SRP K: " + this._K);
237 }
238
239 return this._K;
240 },
241
242 //-------------------------------------------------------------------------
243
244 'M1': function () {
245 if (this._M1 == null) {
246 this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K());
247//MochiKit.Logging.logDebug("SRP M1: " + this._M1);
248 }
249
250 return this._M1;
251 },
252
253 //-------------------------------------------------------------------------
254
255 'M2': function () {
256 if (this._M2 == null) {
257 this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K());
258//MochiKit.Logging.logDebug("SRP M2: " + this._M2);
259 }
260
261 return this._M2;
262 },
263
264 //=========================================================================
265
266 'serverSideCredentialsWithSalt': function(aSalt) {
267 var result;
268 var s, x, v;
269
270 s = aSalt;
271 x = this.stringHash(s + this.P());
272 v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n());
273
274 result = {};
275 result['C'] = this.C();
276 result['s'] = s;
277 result['v'] = v.asString(16);
278
279 return result;
280 },
281
282 'serverSideCredentials': function() {
283 var result;
284 var s;
285
286 s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
287
288 result = this.serverSideCredentialsWithSalt(s);
289
290 return result;
291 },
292
293 //=========================================================================
294/*
295 'computeServerSide_S': function(b) {
296 var result;
297 var v;
298 var bigint;
299 varsrp;
300
301 bigint = Clipperz.Crypto.BigInt;
302 srp = Clipperz.Crypto.SRP;
303
304 v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16);
305 // _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n());
306 result = bigint.powerModule(
307 bigint.multiply(
308 this.A(),
309 bigint.powerModule(v, this.u(), srp.n())
310 ), new Clipperz.Crypto.BigInt(b, 10), srp.n()
311 );
312
313 return result;
314 },
315*/
316 //=========================================================================
317
318 'stringHash': function(aValue) {
319 varresult;
320
321 result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2);
322
323 return result;
324 },
325
326 //=========================================================================
327 __syntaxFix__: "syntax fix"
328
329});
330
331//#############################################################################