summaryrefslogtreecommitdiff
path: root/frontend/gamma/js/Clipperz/Crypto
Unidiff
Diffstat (limited to 'frontend/gamma/js/Clipperz/Crypto') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/AES.js869
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/Base.js1852
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/BigInt.js1760
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/BigInt_scoped.js1649
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Curve.js550
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js526
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Point.js67
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Value.js386
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/ECC/StandardCurves.js239
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/PRNG.js855
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/RSA.js151
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/SHA.js301
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/SRP.js331
13 files changed, 9536 insertions, 0 deletions
diff --git a/frontend/gamma/js/Clipperz/Crypto/AES.js b/frontend/gamma/js/Clipperz/Crypto/AES.js
new file mode 100644
index 0000000..36fc731
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/AES.js
@@ -0,0 +1,869 @@
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 // this._elaborationChunkSize = 1024; // 4096; // 16384; //4096;
58 this._elaborationChunks = 10;
59 this._pauseTime = 0.02; // 0.02 //0.2;
60
61 return this;
62}
63
64Clipperz.Crypto.AES.DeferredExecutionContext.prototype = MochiKit.Base.update(null, {
65
66 'key': function() {
67 return this._key;
68 },
69
70 'message': function() {
71 return this._message;
72 },
73
74 'messageLength': function() {
75 return this._messageLength;
76 },
77
78 'result': function() {
79 return new Clipperz.ByteArray(this.resultArray());
80 },
81
82 'nonce': function() {
83 return this._nonce;
84 },
85
86 'messageArray': function() {
87 return this._messageArray;
88 },
89
90 'resultArray': function() {
91 return this._resultArray;
92 },
93
94 'nonceArray': function() {
95 return this._nonceArray;
96 },
97
98 'elaborationChunkSize': function() {
99 // return Clipperz.Crypto.AES.DeferredExecution.chunkSize;
100 // return this._elaborationChunkSize;
101 return (this._elaborationChunks * 1024);
102 },
103
104 'executionStep': function() {
105 return this._executionStep;
106 },
107
108 'setExecutionStep': function(aValue) {
109 this._executionStep = aValue;
110 },
111
112 'tuneExecutionParameters': function (anElapsedTime) {
113//var originalChunks = this._elaborationChunks;
114 if (anElapsedTime > 0) {
115 this._elaborationChunks = Math.round(this._elaborationChunks * ((anElapsedTime + 1000)/(anElapsedTime * 2)));
116 }
117//Clipperz.log("tuneExecutionParameters - elapsedTime: " + anElapsedTime + /*originalChunks,*/ " chunks # " + this._elaborationChunks + " [" + this._executionStep + " / " + this._messageLength + "]");
118 },
119
120 'pause': function(aValue) {
121 // return MochiKit.Async.wait(Clipperz.Crypto.AES.DeferredExecution.pauseTime, aValue);
122 return MochiKit.Async.wait(this._pauseTime, aValue);
123 },
124
125 'isDone': function () {
126//console.log("isDone", this.executionStep(), this.messageLength());
127 return (this._executionStep >= this._messageLength);
128 },
129
130 //-----------------------------------------------------------------------------
131 __syntaxFix__: "syntax fix"
132
133});
134
135//#############################################################################
136
137Clipperz.Crypto.AES.Key = function(args) {
138 args = args || {};
139
140 this._key = args.key;
141 this._keySize = args.keySize || this.key().length();
142
143 if (this.keySize() == 128/8) {
144 this._b = 176;
145 this._numberOfRounds = 10;
146 } else if (this.keySize() == 256/8) {
147 this._b = 240;
148 this._numberOfRounds = 14;
149 } else {
150 MochiKit.Logging.logError("AES unsupported key size: " + (this.keySize() * 8) + " bits");
151 throw Clipperz.Crypto.AES.exception.UnsupportedKeySize;
152 }
153
154 this._stretchedKey = null;
155
156 return this;
157}
158
159Clipperz.Crypto.AES.Key.prototype = MochiKit.Base.update(null, {
160
161 'asString': function() {
162 return "Clipperz.Crypto.AES.Key (" + this.key().toHexString() + ")";
163 },
164
165 //-----------------------------------------------------------------------------
166
167 'key': function() {
168 return this._key;
169 },
170
171 'keySize': function() {
172 return this._keySize;
173 },
174
175 'b': function() {
176 return this._b;
177 },
178
179 'numberOfRounds': function() {
180 return this._numberOfRounds;
181 },
182 //=========================================================================
183
184 'keyScheduleCore': function(aWord, aRoundConstantsIndex) {
185 varresult;
186 var sbox;
187
188 sbox = Clipperz.Crypto.AES.sbox();
189
190 result = [sbox[aWord[1]] ^ Clipperz.Crypto.AES.roundConstants()[aRoundConstantsIndex],
191 sbox[aWord[2]],
192 sbox[aWord[3]],
193 sbox[aWord[0]]];
194
195 return result;
196 },
197
198 //-----------------------------------------------------------------------------
199
200 'xorWithPreviousStretchValues': function(aKey, aWord, aPreviousWordIndex) {
201 varresult;
202 var i,c;
203
204 result = [];
205 c = 4;
206 for (i=0; i<c; i++) {
207 result[i] = aWord[i] ^ aKey.byteAtIndex(aPreviousWordIndex + i);
208 }
209
210 return result;
211 },
212
213 //-----------------------------------------------------------------------------
214
215 'sboxShakeup': function(aWord) {
216 var result;
217 var sbox;
218 var i,c;
219
220 result = [];
221 sbox = Clipperz.Crypto.AES.sbox();
222 c =4;
223 for (i=0; i<c; i++) {
224 result[i] = sbox[aWord[i]];
225 }
226
227 return result;
228 },
229
230 //-----------------------------------------------------------------------------
231
232 'stretchKey': function(aKey) {
233 varcurrentWord;
234 varkeyLength;
235 varpreviousStretchIndex;
236 var i,c;
237
238 keyLength = aKey.length();
239 previousStretchIndex = keyLength - this.keySize();
240
241 currentWord = [aKey.byteAtIndex(keyLength - 4),
242 aKey.byteAtIndex(keyLength - 3),
243 aKey.byteAtIndex(keyLength - 2),
244 aKey.byteAtIndex(keyLength - 1)];
245 currentWord = this.keyScheduleCore(currentWord, keyLength / this.keySize());
246
247 if (this.keySize() == 256/8) {
248 c = 8;
249 } else if (this.keySize() == 128/8){
250 c = 4;
251 }
252
253 for (i=0; i<c; i++) {
254 if (i == 4) {
255 //fifth streatch word
256 currentWord = this.sboxShakeup(currentWord);
257 }
258
259 currentWord = this.xorWithPreviousStretchValues(aKey, currentWord, previousStretchIndex + (i*4));
260 aKey.appendBytes(currentWord);
261 }
262
263 return aKey;
264 },
265
266 //-----------------------------------------------------------------------------
267
268 'stretchedKey': function() {
269 if (this._stretchedKey == null) {
270 var stretchedKey;
271
272 stretchedKey = this.key().clone();
273
274 while (stretchedKey.length() < this.keySize()) {
275 stretchedKey.appendByte(0);
276 }
277
278 while (stretchedKey.length() < this.b()) {
279 stretchedKey = this.stretchKey(stretchedKey);
280 }
281
282 this._stretchedKey = stretchedKey.split(0, this.b());
283 }
284
285 return this._stretchedKey;
286 },
287
288 //=========================================================================
289 __syntaxFix__: "syntax fix"
290});
291
292//#############################################################################
293
294Clipperz.Crypto.AES.State = function(args) {
295 args = args || {};
296
297 this._data = args.block;
298 this._key = args.key;
299
300 return this;
301}
302
303Clipperz.Crypto.AES.State.prototype = MochiKit.Base.update(null, {
304
305 'key': function() {
306 return this._key;
307 },
308
309 //-----------------------------------------------------------------------------
310
311 'data': function() {
312 return this._data;
313 },
314
315 'setData': function(aValue) {
316 this._data = aValue;
317 },
318
319 //=========================================================================
320
321 'addRoundKey': function(aRoundNumber) {
322 //each byte of the state is combined with the round key; each round key is derived from the cipher key using a key schedule.
323 vardata;
324 varstretchedKey;
325 varfirstStretchedKeyIndex;
326 var i,c;
327
328 data = this.data();
329 stretchedKey = this.key().stretchedKey();
330 firstStretchedKeyIndex = aRoundNumber * (128/8);
331 c = 128/8;
332 for (i=0; i<c; i++) {
333 data[i] = data[i] ^ stretchedKey.byteAtIndex(firstStretchedKeyIndex + i);
334 }
335 },
336
337 //-----------------------------------------------------------------------------
338
339 'subBytes': function() {
340 // a non-linear substitution step where each byte is replaced with another according to a lookup table.
341 var i,c;
342 vardata;
343 var sbox;
344
345 data = this.data();
346 sbox = Clipperz.Crypto.AES.sbox();
347
348 c = 16;
349 for (i=0; i<c; i++) {
350 data[i] = sbox[data[i]];
351 }
352 },
353
354 //-----------------------------------------------------------------------------
355
356 'shiftRows': function() {
357 //a transposition step where each row of the state is shifted cyclically a certain number of steps.
358 varnewValue;
359 vardata;
360 varshiftMapping;
361 vari,c;
362
363 newValue = new Array(16);
364 data = this.data();
365 shiftMapping = Clipperz.Crypto.AES.shiftRowMapping();
366 // [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
367 c = 16;
368 for (i=0; i<c; i++) {
369 newValue[i] = data[shiftMapping[i]];
370 }
371 for (i=0; i<c; i++) {
372 data[i] = newValue[i];
373 }
374 },
375
376 //-----------------------------------------------------------------------------
377/*
378 'mixColumnsWithValues': function(someValues) {
379 varresult;
380 vara;
381 var i,c;
382
383 c = 4;
384 result = [];
385 a = [];
386 for (i=0; i<c; i++) {
387 a[i] = [];
388 a[i][1] = someValues[i]
389 if ((a[i][1] & 0x80) == 0x80) {
390 a[i][2] = (a[i][1] << 1) ^ 0x11b;
391 } else {
392 a[i][2] = a[i][1] << 1;
393 }
394
395 a[i][3] = a[i][2] ^ a[i][1];
396 }
397
398 for (i=0; i<c; i++) {
399 varx;
400
401 x = Clipperz.Crypto.AES.mixColumnsMatrix()[i];
402 result[i] = a[0][x[0]] ^ a[1][x[1]] ^ a[2][x[2]] ^ a[3][x[3]];
403 }
404
405 return result;
406 },
407
408 'mixColumns': function() {
409 //a mixing operation which operates on the columns of the state, combining the four bytes in each column using a linear transformation.
410 var data;
411 var i, c;
412
413 data = this.data();
414 c = 4;
415 for(i=0; i<c; i++) {
416 varblockIndex;
417 var mixedValues;
418
419 blockIndex = i * 4;
420 mixedValues = this.mixColumnsWithValues([data[blockIndex + 0],
421 data[blockIndex + 1],
422 data[blockIndex + 2],
423 data[blockIndex + 3]]);
424 data[blockIndex + 0] = mixedValues[0];
425 data[blockIndex + 1] = mixedValues[1];
426 data[blockIndex + 2] = mixedValues[2];
427 data[blockIndex + 3] = mixedValues[3];
428 }
429 },
430*/
431
432 'mixColumns': function() {
433 //a mixing operation which operates on the columns of the state, combining the four bytes in each column using a linear transformation.
434 var data;
435 var i, c;
436 var a_1;
437 var a_2;
438
439 a_1 = new Array(4);
440 a_2 = new Array(4);
441
442 data = this.data();
443 c = 4;
444 for(i=0; i<c; i++) {
445 varblockIndex;
446 var ii, cc;
447
448 blockIndex = i * 4;
449
450 cc = 4;
451 for (ii=0; ii<cc; ii++) {
452 var value;
453
454 value = data[blockIndex + ii];
455 a_1[ii] = value;
456 a_2[ii] = (value & 0x80) ? ((value << 1) ^ 0x011b) : (value << 1);
457 }
458
459 data[blockIndex + 0] = a_2[0] ^ a_1[1] ^ a_2[1] ^ a_1[2] ^ a_1[3];
460 data[blockIndex + 1] = a_1[0] ^ a_2[1] ^ a_1[2] ^ a_2[2] ^ a_1[3];
461 data[blockIndex + 2] = a_1[0] ^ a_1[1] ^ a_2[2] ^ a_1[3] ^ a_2[3];
462 data[blockIndex + 3] = a_1[0] ^ a_2[0] ^ a_1[1] ^ a_1[2] ^ a_2[3];
463 }
464 },
465
466 //=========================================================================
467
468 'spinRound': function(aRoundNumber) {
469 this.addRoundKey(aRoundNumber);
470 this.subBytes();
471 this.shiftRows();
472 this.mixColumns();
473 },
474
475 'spinLastRound': function() {
476 this.addRoundKey(this.key().numberOfRounds() - 1);
477 this.subBytes();
478 this.shiftRows();
479 this.addRoundKey(this.key().numberOfRounds());
480 },
481
482 //=========================================================================
483
484 'encrypt': function() {
485 vari,c;
486
487 c = this.key().numberOfRounds() - 1;
488 for (i=0; i<c; i++) {
489 this.spinRound(i);
490 }
491
492 this.spinLastRound();
493 },
494
495 //=========================================================================
496 __syntaxFix__: "syntax fix"
497});
498
499//#############################################################################
500
501Clipperz.Crypto.AES.VERSION = "0.1";
502Clipperz.Crypto.AES.NAME = "Clipperz.Crypto.AES";
503
504MochiKit.Base.update(Clipperz.Crypto.AES, {
505
506 //http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-AES.html
507 //http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
508 //http://en.wikipedia.org/wiki/Rijndael_key_schedule
509 //http://en.wikipedia.org/wiki/Rijndael_S-box
510
511 '__repr__': function () {
512 return "[" + this.NAME + " " + this.VERSION + "]";
513 },
514
515 'toString': function () {
516 return this.__repr__();
517 },
518
519 //=============================================================================
520
521 '_sbox': null,
522 'sbox': function() {
523 if (Clipperz.Crypto.AES._sbox == null) {
524 Clipperz.Crypto.AES._sbox = [
5250x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
5260xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
5270xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
5280x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
5290x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
5300x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
5310xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
5320x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
5330xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
5340x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
5350xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
5360xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
5370xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
5380x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
5390xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
5400x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
541 ];
542 }
543
544 return Clipperz.Crypto.AES._sbox;
545 },
546
547 //-----------------------------------------------------------------------------
548 //
549 // 0 4 8 12 0 4 812
550 // 1 5 9 13 => 5 9 131
551 // 2 6 10 14 10 14 26
552 // 3 7 11 15 15 3 711
553 //
554 '_shiftRowMapping': null,
555 'shiftRowMapping': function() {
556 if (Clipperz.Crypto.AES._shiftRowMapping == null) {
557 Clipperz.Crypto.AES._shiftRowMapping = [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
558 }
559
560 return Clipperz.Crypto.AES._shiftRowMapping;
561 },
562
563 //-----------------------------------------------------------------------------
564
565 '_mixColumnsMatrix': null,
566 'mixColumnsMatrix': function() {
567 if (Clipperz.Crypto.AES._mixColumnsMatrix == null) {
568 Clipperz.Crypto.AES._mixColumnsMatrix = [[2, 3, 1 ,1],
569 [1, 2, 3, 1],
570 [1, 1, 2, 3],
571 [3, 1, 1, 2] ];
572 }
573
574 return Clipperz.Crypto.AES._mixColumnsMatrix;
575 },
576
577 '_roundConstants': null,
578 'roundConstants': function() {
579 if (Clipperz.Crypto.AES._roundConstants == null) {
580 Clipperz.Crypto.AES._roundConstants = [ , 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154];
581 // Clipperz.Crypto.AES._roundConstants = [ , 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a];
582 }
583
584 return Clipperz.Crypto.AES._roundConstants;
585 },
586
587 //=============================================================================
588
589 'incrementNonce': function(aNonce) {
590//Clipperz.Profile.start("Clipperz.Crypto.AES.incrementNonce");
591 var i;
592 var done;
593
594 done = false;
595 i = aNonce.length - 1;
596
597 while ((i>=0) && (done == false)) {
598 var currentByteValue;
599
600 currentByteValue = aNonce[i];
601
602 if (currentByteValue == 0xff) {
603 aNonce[i] = 0;
604 if (i>= 0) {
605 i --;
606 } else {
607 done = true;
608 }
609 } else {
610 aNonce[i] = currentByteValue + 1;
611 done = true;
612 }
613 }
614//Clipperz.Profile.stop("Clipperz.Crypto.AES.incrementNonce");
615 },
616
617 //-----------------------------------------------------------------------------
618
619 'encryptBlock': function(aKey, aBlock) {
620 varresult;
621 varstate;
622
623 state = new Clipperz.Crypto.AES.State({block:aBlock, key:aKey});
624//is(state.data(), 'before');
625 state.encrypt();
626 result = state.data();
627
628 return result;
629 },
630
631 //-----------------------------------------------------------------------------
632
633 'encryptBlocks': function(aKey, aMessage, aNonce) {
634 varresult;
635 var nonce;
636 var self;
637 varmessageIndex;
638 varmessageLength;
639 var blockSize;
640
641 self = Clipperz.Crypto.AES;
642 blockSize = 128/8;
643 messageLength = aMessage.length;
644 nonce = aNonce;
645
646 result = aMessage;
647 messageIndex = 0;
648 while (messageIndex < messageLength) {
649 var encryptedBlock;
650 var i,c;
651
652 self.incrementNonce(nonce);
653 encryptedBlock = self.encryptBlock(aKey, nonce);
654
655 if ((messageLength - messageIndex) > blockSize) {
656 c = blockSize;
657 } else {
658 c = messageLength - messageIndex;
659 }
660
661 for (i=0; i<c; i++) {
662 result[messageIndex + i] = result[messageIndex + i] ^ encryptedBlock[i];
663 }
664
665 messageIndex += blockSize;
666 }
667
668 return result;
669 },
670
671 //-----------------------------------------------------------------------------
672
673 'encrypt': function(aKey, someData, aNonce) {
674 var result;
675 var nonce;
676 varencryptedData;
677 var key;
678
679 key = new Clipperz.Crypto.AES.Key({key:aKey});
680 nonce = aNonce ? aNonce.clone() : Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8);
681
682 encryptedData = Clipperz.Crypto.AES.encryptBlocks(key, someData.arrayValues(), nonce.arrayValues());
683
684 result = nonce.appendBytes(encryptedData);
685
686 return result;
687 },
688
689 //-----------------------------------------------------------------------------
690
691 'decrypt': function(aKey, someData) {
692 var result;
693 var nonce;
694 var encryptedData;
695 var decryptedData;
696 vardataIterator;
697 var key;
698
699 key = new Clipperz.Crypto.AES.Key({key:aKey});
700
701 encryptedData = someData.arrayValues();
702 nonce = encryptedData.slice(0, (128/8));
703 encryptedData = encryptedData.slice(128/8);
704 decryptedData = Clipperz.Crypto.AES.encryptBlocks(key, encryptedData, nonce);
705
706 result = new Clipperz.ByteArray(decryptedData);
707
708 return result;
709 },
710
711 //=============================================================================
712
713 'deferredEncryptExecutionChunk': function(anExecutionContext) {
714 varresult;
715 var nonce;
716 var self;
717 varmessageIndex;
718 varmessageLength;
719 var blockSize;
720 var executionLimit;
721 var startTime, endTime;
722
723 self = Clipperz.Crypto.AES;
724 startTime = new Date();
725 blockSize = 128/8;
726 messageLength = anExecutionContext.messageArray().length;
727 nonce = anExecutionContext.nonceArray();
728 result = anExecutionContext.resultArray();
729
730 messageIndex = anExecutionContext.executionStep();
731 executionLimit = messageIndex + anExecutionContext.elaborationChunkSize();
732 executionLimit = Math.min(executionLimit, messageLength);
733
734 while (messageIndex < executionLimit) {
735 var encryptedBlock;
736 var i,c;
737
738 self.incrementNonce(nonce);
739 encryptedBlock = self.encryptBlock(anExecutionContext.key(), nonce);
740
741 if ((executionLimit - messageIndex) > blockSize) {
742 c = blockSize;
743 } else {
744 c = executionLimit - messageIndex;
745 }
746
747 for (i=0; i<c; i++) {
748 result[messageIndex + i] = result[messageIndex + i] ^ encryptedBlock[i];
749 }
750
751 messageIndex += blockSize;
752 }
753 anExecutionContext.setExecutionStep(messageIndex);
754 endTime = new Date();
755 anExecutionContext.tuneExecutionParameters(endTime - startTime);
756
757 return anExecutionContext;
758 },
759
760 //-----------------------------------------------------------------------------
761/*
762 'deferredEncryptBlocks': function(anExecutionContext) {
763 vardeferredResult;
764 varmessageSize;
765 var i,c;
766
767 messageSize = anExecutionContext.messageLength();
768
769 deferredResult = new Clipperz.Async.Deferred("AES.deferredEncryptBloks");
770
771 c = Math.ceil(messageSize / anExecutionContext.elaborationChunkSize());
772 for (i=0; i<c; i++) {
773 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptExecutionChunk);
774 deferredResult.addMethod(anExecutionContext, 'pause');
775 }
776
777 deferredResult.callback(anExecutionContext);
778
779 return deferredResult;
780 },
781*/
782
783 'deferredEncryptBlocks': function(anExecutionContext) {
784 vardeferredResult;
785
786 if (! anExecutionContext.isDone()) {
787 deferredResult = Clipperz.Async.callbacks("Clipperz.Crypto.AES.deferredEncryptBloks", [
788 Clipperz.Crypto.AES.deferredEncryptExecutionChunk,
789 MochiKit.Base.method(anExecutionContext, 'pause'),
790 Clipperz.Crypto.AES.deferredEncryptBlocks
791 ], {trace:false}, anExecutionContext);
792 } else {
793 deferredResult = MochiKit.Async.succeed(anExecutionContext);
794 }
795
796 return deferredResult;
797 },
798
799 //-----------------------------------------------------------------------------
800
801 'deferredEncrypt': function(aKey, someData, aNonce) {
802 var deferredResult;
803 varexecutionContext;
804 var result;
805 var nonce;
806 var key;
807
808 key = new Clipperz.Crypto.AES.Key({key:aKey});
809 nonce = aNonce ? aNonce.clone() : Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8);
810
811 executionContext = new Clipperz.Crypto.AES.DeferredExecutionContext({key:key, message:someData, nonce:nonce});
812
813 deferredResult = new Clipperz.Async.Deferred("AES.deferredEncrypt");
814//deferredResult.addCallback(function (aValue) { console.log(">>> deferredEncrypt"); return aValue; });
815 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptBlocks);
816 deferredResult.addCallback(function(anExecutionContext) {
817 var result;
818
819 result = anExecutionContext.nonce().clone();
820 result.appendBytes(anExecutionContext.resultArray());
821
822 return result;
823 });
824//deferredResult.addCallback(function (aValue) { console.log("<<< deferredEncrypt"); return aValue; });
825 deferredResult.callback(executionContext)
826
827 return deferredResult;
828 },
829
830 //-----------------------------------------------------------------------------
831
832 'deferredDecrypt': function(aKey, someData) {
833 var deferredResult
834 var nonce;
835 var message;
836 var key;
837
838 key = new Clipperz.Crypto.AES.Key({key:aKey});
839 nonce = someData.split(0, (128/8));
840 message = someData.split(128/8);
841 executionContext = new Clipperz.Crypto.AES.DeferredExecutionContext({key:key, message:message, nonce:nonce});
842
843 deferredResult = new Clipperz.Async.Deferred("AES.deferredDecrypt");
844//deferredResult.addCallback(function (aValue) { console.log(">>> deferredDecrypt"); return aValue; });
845 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptBlocks);
846 deferredResult.addCallback(function(anExecutionContext) {
847 return anExecutionContext.result();
848 });
849//deferredResult.addCallback(function (aValue) { console.log("<<< deferredDecrypt"); return aValue; });
850 deferredResult.callback(executionContext);
851
852 return deferredResult;
853 },
854
855 //-----------------------------------------------------------------------------
856 __syntaxFix__: "syntax fix"
857
858});
859
860//#############################################################################
861
862//Clipperz.Crypto.AES.DeferredExecution = {
863 // 'chunkSize': 16384, // 4096, // 1024 4096 8192 1638432768;
864 // 'pauseTime': 0.02 //0.2
865//}
866
867Clipperz.Crypto.AES.exception = {
868 'UnsupportedKeySize': new MochiKit.Base.NamedError("Clipperz.Crypto.AES.exception.UnsupportedKeySize")
869};
diff --git a/frontend/gamma/js/Clipperz/Crypto/Base.js b/frontend/gamma/js/Clipperz/Crypto/Base.js
new file mode 100644
index 0000000..b69dcc8
--- a/dev/null
+++ b/frontend/gamma/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/gamma/js/Clipperz/Crypto/BigInt.js b/frontend/gamma/js/Clipperz/Crypto/BigInt.js
new file mode 100644
index 0000000..d4d05d2
--- a/dev/null
+++ b/frontend/gamma/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/gamma/js/Clipperz/Crypto/BigInt_scoped.js b/frontend/gamma/js/Clipperz/Crypto/BigInt_scoped.js
new file mode 100644
index 0000000..e91e823
--- a/dev/null
+++ b/frontend/gamma/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/gamma/js/Clipperz/Crypto/ECC/BinaryField/Curve.js b/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Curve.js
new file mode 100644
index 0000000..2033eb4
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Curve.js
@@ -0,0 +1,550 @@
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//try { 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 'addTwice': function(aPointA) {
173 return this.add(aPointA, aPointA);
174 },
175
176 //-----------------------------------------------------------------------------
177
178 'overwriteAdd': function(aPointA, aPointB) {
179 if (aPointA.isZero()) {
180 // result = aPointB;
181 aPointA._x._value = aPointB._x._value;
182 aPointA._y._value = aPointB._y._value;
183 } else if (aPointB.isZero()) {
184 // result = aPointA;
185 } else if ((aPointA.x().compare(aPointB.x()) == 0) && ((aPointA.y().compare(aPointB.y()) != 0) || aPointB.x().isZero())) {
186 // result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
187 aPointA._x = Clipperz.Crypto.ECC.BinaryField.Value.O;
188 aPointA._y = Clipperz.Crypto.ECC.BinaryField.Value.O;
189 } else {
190 varf2m;
191 var x, y;
192 var lambda;
193 var aX, aY, bX, bY;
194
195 aX = aPointA.x()._value;
196 aY = aPointA.y()._value;
197 bX = aPointB.x()._value;
198 bY = aPointB.y()._value;
199
200 f2m = this.finiteField();
201
202 if (aPointA.x().compare(aPointB.x()) != 0) {
203//console.log(" a.x != b.x");
204 lambda =f2m._fastMultiply(
205 f2m._add(aY, bY),
206 f2m._inverse(f2m._add(aX, bX))
207 );
208 x = f2m._add(this.a()._value, f2m._square(lambda));
209 f2m._overwriteAdd(x, lambda);
210 f2m._overwriteAdd(x, aX);
211 f2m._overwriteAdd(x, bX);
212 } else {
213//console.log(" a.x == b.x");
214 lambda = f2m._add(bX, f2m._fastMultiply(bY, f2m._inverse(bX)));
215//console.log(" lambda: " + lambda.asString(16));
216 x = f2m._add(this.a()._value, f2m._square(lambda));
217//console.log(" x (step 1): " + x.asString(16));
218 f2m._overwriteAdd(x, lambda);
219//console.log(" x (step 2): " + x.asString(16));
220 }
221
222 y = f2m._fastMultiply(f2m._add(bX, x), lambda);
223//console.log(" y (step 1): " + y.asString(16));
224 f2m._overwriteAdd(y, x);
225//console.log(" y (step 2): " + y.asString(16));
226 f2m._overwriteAdd(y, bY);
227//console.log(" y (step 3): " + y.asString(16));
228
229 // result = new Clipperz.Crypto.ECC.BinaryField.Point({x:new Clipperz.Crypto.ECC.BinaryField.Value(x), y:new Clipperz.Crypto.ECC.BinaryField.Value(y)})
230 aPointA._x._value = x;
231 aPointA._y._value = y;
232
233 }
234//console.log("<<< ECC.BinaryField.Curve.add");
235
236 return result;
237 },
238
239 //-----------------------------------------------------------------------------
240
241 'multiply': function(aValue, aPoint) {
242 var result;
243
244//console.profile();
245 result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
246
247 if (aValue.isZero() == false) {
248 var k, Q;
249 var i;
250 var countIndex; countIndex = 0;
251
252 if (aValue.compare(Clipperz.Crypto.ECC.BinaryField.Value.O) > 0) {
253 k = aValue;
254 Q = aPoint;
255 } else {
256MochiKit.Logging.logError("The Clipperz.Crypto.ECC.BinaryFields.Value does not work with negative values!!!!");
257 k = aValue.negate();
258 Q = this.negate(aPoint);
259 }
260
261//console.log("k: " + k.toString(16));
262//console.log("k.bitSize: " + k.bitSize());
263 for (i=k.bitSize()-1; i>=0; i--) {
264 result = this.add(result, result);
265 // this.overwriteAdd(result, result);
266 if (k.isBitSet(i)) {
267 result = this.add(result, Q);
268 // this.overwriteAdd(result, Q);
269 }
270
271 // if (countIndex==100) {console.log("multiply.break"); break;} else countIndex++;
272 }
273 }
274//console.profileEnd();
275
276 return result;
277 },
278
279 //-----------------------------------------------------------------------------
280
281 'deferredMultiply': function(aValue, aPoint) {
282 var deferredResult;
283 var result;
284
285MochiKit.Logging.logDebug(">>> deferredMultiply - value: " + aValue + ", point: " + aPoint);
286//console.profile("ECC.Curve.multiply");
287 deferredResult = new MochiKit.Async.Deferred();
288//deferredResult.addCallback(function(res) {console.profile("ECC.Curve.deferredMultiply"); return res;} );
289//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 1: " + res); return res;});
290
291 result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
292//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 2: " + res); return res;});
293
294 if (aValue.isZero() == false) {
295 var k, Q;
296 var i;
297 var countIndex; countIndex = 0;
298
299 if (aValue.compare(Clipperz.Crypto.ECC.BinaryField.Value.O) > 0) {
300 k = aValue;
301 Q = aPoint;
302 } else {
303MochiKit.Logging.logError("The Clipperz.Crypto.ECC.BinaryFields.Value does not work with negative values!!!!");
304 k = aValue.negate();
305 Q = this.negate(aPoint);
306 }
307
308//console.log("k: " + k.toString(16));
309//console.log("k.bitSize: " + k.bitSize());
310
311//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 3: " + res); return res;});
312 for (i=k.bitSize()-1; i>=0; i--) {
313//MochiKit.Logging.logDebug("====> " + i);
314//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 4 > i = " + i + ": " + res); return res;});
315 deferredResult.addMethod(this, "addTwice");
316 //# result = this.add(result, result);
317 // this.overwriteAdd(result, result);
318 if (k.isBitSet(i)) {
319 deferredResult.addMethod(this, "add", Q);
320 //# result = this.add(result, Q);
321 // this.overwriteAdd(result, Q);
322 }
323 if (i%20 == 0) {deferredResult.addCallback(MochiKit.Async.wait, 0.1);}
324
325 // if (countIndex==100) {console.log("multiply.break"); break;} else countIndex++;
326//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 4 < i = " + i + ": " + res); return res;});
327 }
328//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 4: " + res); return res;});
329 }
330//#console.profileEnd();
331//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 5: " + res); return res;});
332//deferredResult.addBoth(function(res) {console.profileEnd(); return res;});
333//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 6: " + res); return res;});
334 deferredResult.callback(result);
335
336 //# return result;
337 return deferredResult;
338 },
339
340 //-----------------------------------------------------------------------------
341 __syntaxFix__: "syntax fix"
342});
343
344
345//#############################################################################
346
347Clipperz.Crypto.ECC.StandardCurves = {};
348
349MochiKit.Base.update(Clipperz.Crypto.ECC.StandardCurves, {
350/*
351 '_K571': null,
352 'K571': function() {
353 if (Clipperz.Crypto.ECC.StandardCurves._K571 == null) {
354 Clipperz.Crypto.ECC.StandardCurves._K571 = new Clipperz.Crypto.ECC.BinaryField.Curve({
355 modulus: new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000425', 16),
356 a: new Clipperz.Crypto.ECC.BinaryField.Value('0', 16),
357 b: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
358 G: new Clipperz.Crypto.ECC.BinaryField.Point({
359 x: new Clipperz.Crypto.ECC.BinaryField.Value('026eb7a8 59923fbc 82189631 f8103fe4 ac9ca297 0012d5d4 60248048 01841ca4 43709584 93b205e6 47da304d b4ceb08c bbd1ba39 494776fb 988b4717 4dca88c7 e2945283 a01c8972', 16),
360 y: new Clipperz.Crypto.ECC.BinaryField.Value('0349dc80 7f4fbf37 4f4aeade 3bca9531 4dd58cec 9f307a54 ffc61efc 006d8a2c 9d4979c0 ac44aea7 4fbebbb9 f772aedc b620b01a 7ba7af1b 320430c8 591984f6 01cd4c14 3ef1c7a3', 16)
361 }),
362 r: new Clipperz.Crypto.ECC.BinaryField.Value('02000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 131850e1 f19a63e4 b391a8db 917f4138 b630d84b e5d63938 1e91deb4 5cfe778f 637c1001', 16),
363 h: new Clipperz.Crypto.ECC.BinaryField.Value('4', 16)
364 });
365 }
366
367 return Clipperz.Crypto.ECC.StandardCurves._K571;
368 },
369
370
371
372 '_K283': null,
373 'K283': function() { //f(z) = z^283 + z^12 + z^7 + z^5 + 1
374 if (Clipperz.Crypto.ECC.StandardCurves._K283 == null) {
375 Clipperz.Crypto.ECC.StandardCurves._K283 = new Clipperz.Crypto.ECC.BinaryField.Curve({
376 modulus: new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
377 a: new Clipperz.Crypto.ECC.BinaryField.Value('0', 16),
378 b: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
379 G: new Clipperz.Crypto.ECC.BinaryField.Point({
380 x: new Clipperz.Crypto.ECC.BinaryField.Value('0503213f 78ca4488 3f1a3b81 62f188e5 53cd265f 23c1567a 16876913 b0c2ac24 58492836', 16),
381 y: new Clipperz.Crypto.ECC.BinaryField.Value('01ccda38 0f1c9e31 8d90f95d 07e5426f e87e45c0 e8184698 e4596236 4e341161 77dd2259', 16)
382 }),
383 r: new Clipperz.Crypto.ECC.BinaryField.Value('01ffffff ffffffff ffffffff ffffffff ffffe9ae 2ed07577 265dff7f 94451e06 1e163c61', 16),
384 h: new Clipperz.Crypto.ECC.BinaryField.Value('4', 16)
385 });
386 }
387
388 return Clipperz.Crypto.ECC.StandardCurves._K283;
389 },
390*/
391 //-----------------------------------------------------------------------------
392
393 '_B571': null,
394 'B571': function() { //f(z) = z^571 + z^10 + z^5 + z^2 + 1
395 if (Clipperz.Crypto.ECC.StandardCurves._B571 == null) {
396 Clipperz.Crypto.ECC.StandardCurves._B571 = new Clipperz.Crypto.ECC.BinaryField.Curve({
397 modulus: new Clipperz.Crypto.ECC.BinaryField.Value('80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425', 16),
398 a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
399 b: new Clipperz.Crypto.ECC.BinaryField.Value('02f40e7e2221f295de297117b7f3d62f5c6a97ffcb8ceff1cd6ba8ce4a9a18ad84ffabbd8efa59332be7ad6756a66e294afd185a78ff12aa520e4de739baca0c7ffeff7f2955727a', 16),
400 G: new Clipperz.Crypto.ECC.BinaryField.Point({
401 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),
402 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)
403 }),
404 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),
405 h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
406
407 // S: new Clipperz.Crypto.ECC.BinaryField.Value('2aa058f73a0e33ab486b0f610410c53a7f132310', 10),
408 // n: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16)
409 });
410
411 //-----------------------------------------------------------------------------
412 //
413 //Guide to Elliptic Curve Cryptography
414 //Darrel Hankerson, Alfred Menezes, Scott Vanstone
415 //- Pag: 56, Alorithm 2.45 (with a typo!!!)
416 //
417 //-----------------------------------------------------------------------------
418 //
419 // http://www.milw0rm.com/papers/136
420 //
421 // -------------------------------------------------------------------------
422 // Polynomial Reduction Algorithm Modulo f571
423 // -------------------------------------------------------------------------
424 //
425 // Input: Polynomial p(x) of degree 1140 or less, stored as
426 // an array of 2T machinewords.
427 // Output: p(x) mod f571(x)
428 //
429 // FOR i = T-1, ..., 0 DO
430 // SET X := P[i+T]
431 // P[i] := P[i] ^ (X<<5) ^ (X<<7) ^ (X<<10) ^ (X<<15)
432 // P[i+1] := P[i+1] ^ (X>>17) ^ (X>>22) ^ (X>>25) ^ (X>>27)
433 //
434 // SET X := P[T-1] >> 27
435 // P[0] := P[0] ^ X ^ (X<<2) ^ (X<<5) ^ (X<<10)
436 // P[T-1] := P[T-1] & 0x07ffffff
437 //
438 // RETURN P[T-1],...,P[0]
439 //
440 // -------------------------------------------------------------------------
441 //
442 Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().slowModule = Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module;
443 Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module = function(aValue) {
444 varresult;
445
446 if (aValue.bitSize() > 1140) {
447 MochiKit.Logging.logWarning("ECC.StandarCurves.B571.finiteField().module: falling back to default implementation");
448 result = Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().slowModule(aValue);
449 } else {
450 varC, T;
451 var i;
452
453//console.log(">>> binaryField.finiteField.(improved)module");
454 // C = aValue.value().slice(0);
455 C = aValue._value.slice(0);
456 for (i=35; i>=18; i--) {
457 T = C[i];
458 C[i-18] = (((C[i-18] ^ (T<<5) ^ (T<<7) ^ (T<<10) ^ (T<<15)) & 0xffffffff) >>> 0);
459 C[i-17] = ((C[i-17] ^ (T>>>27) ^ (T>>>25) ^ (T>>>22) ^ (T>>>17)) >>> 0);
460 }
461 T = (C[17] >>> 27);
462 C[0] = ((C[0] ^ T ^ ((T<<2) ^ (T<<5) ^ (T<<10)) & 0xffffffff) >>> 0);
463 C[17] = (C[17] & 0x07ffffff);
464
465 for(i=18; i<=35; i++) {
466 C[i] = 0;
467 }
468
469 result = new Clipperz.Crypto.ECC.BinaryField.Value(C);
470//console.log("<<< binaryField.finiteField.(improved)module");
471 }
472
473 return result;
474 };
475 }
476
477 return Clipperz.Crypto.ECC.StandardCurves._B571;
478 },
479
480 //-----------------------------------------------------------------------------
481
482 '_B283': null,
483 'B283': function() { //f(z) = z^283 + z^12 + z^7 + z^5 + 1
484 if (Clipperz.Crypto.ECC.StandardCurves._B283 == null) {
485 Clipperz.Crypto.ECC.StandardCurves._B283 = new Clipperz.Crypto.ECC.BinaryField.Curve({
486 // modulus: new Clipperz.Crypto.ECC.BinaryField.Value('10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
487 modulus: new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
488 a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
489 b: new Clipperz.Crypto.ECC.BinaryField.Value('027b680a c8b8596d a5a4af8a 19a0303f ca97fd76 45309fa2 a581485a f6263e31 3b79a2f5', 16),
490 G: new Clipperz.Crypto.ECC.BinaryField.Point({
491 x: new Clipperz.Crypto.ECC.BinaryField.Value('05f93925 8db7dd90 e1934f8c 70b0dfec 2eed25b8 557eac9c 80e2e198 f8cdbecd 86b12053', 16),
492 y: new Clipperz.Crypto.ECC.BinaryField.Value('03676854 fe24141c b98fe6d4 b20d02b4 516ff702 350eddb0 826779c8 13f0df45 be8112f4', 16)
493 }),
494 r: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffff ffffffff ffffffff ffffffff ffffef90 399660fc 938a9016 5b042a7c efadb307', 16),
495 h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
496
497 // S: new Clipperz.Crypto.ECC.BinaryField.Value('2aa058f73a0e33ab486b0f610410c53a7f132310', 10),
498 // n: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16)
499 });
500
501 //-----------------------------------------------------------------------------
502 //
503 //Guide to Elliptic Curve Cryptography
504 //Darrel Hankerson, Alfred Menezes, Scott Vanstone
505 //- Pag: 56, Alorithm 2.43
506 //
507 //-----------------------------------------------------------------------------
508 Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().slowModule = Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().module;
509 Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().module = function(aValue) {
510 varresult;
511
512 if (aValue.bitSize() > 564) {
513 MochiKit.Logging.logWarning("ECC.StandarCurves.B283.finiteField().module: falling back to default implementation");
514 result = Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().slowModule(aValue);
515 } else {
516 varC, T;
517 var i;
518
519//console.log(">>> binaryField.finiteField.(improved)module");
520 C = aValue._value.slice(0);
521 for (i=17; i>=9; i--) {
522 T = C[i];
523 C[i-9] = (((C[i-9] ^ (T<<5) ^ (T<<10) ^ (T<<12) ^ (T<<17)) & 0xffffffff) >>> 0);
524 C[i-8] = ((C[i-8] ^ (T>>>27) ^ (T>>>22) ^ (T>>>20) ^ (T>>>15)) >>> 0);
525 }
526 T = (C[8] >>> 27);
527 C[0] = ((C[0] ^ T ^ ((T<<5) ^ (T<<7) ^ (T<<12)) & 0xffffffff) >>> 0);
528 C[8] = (C[8] & 0x07ffffff);
529
530 for(i=9; i<=17; i++) {
531 C[i] = 0;
532 }
533
534 result = new Clipperz.Crypto.ECC.BinaryField.Value(C);
535//console.log("<<< binaryField.finiteField.(improved)module");
536 }
537
538 return result;
539 };
540 }
541
542 return Clipperz.Crypto.ECC.StandardCurves._B283;
543 },
544
545 //-----------------------------------------------------------------------------
546 __syntaxFix__: "syntax fix"
547});
548
549//#############################################################################
550
diff --git a/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js b/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js
new file mode 100644
index 0000000..a649c9f
--- a/dev/null
+++ b/frontend/gamma/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
29//try { 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/gamma/js/Clipperz/Crypto/ECC/BinaryField/Point.js b/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Point.js
new file mode 100644
index 0000000..b7a5537
--- a/dev/null
+++ b/frontend/gamma/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
29//try { 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/gamma/js/Clipperz/Crypto/ECC/BinaryField/Value.js b/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Value.js
new file mode 100644
index 0000000..5a430d1
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Value.js
@@ -0,0 +1,386 @@
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//try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
30 //throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!";
31//}
32if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
33if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
34if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; }
35if (typeof(Clipperz.Crypto.ECC.BinaryField) == 'undefined') { Clipperz.Crypto.ECC.BinaryField = {}; }
36
37Clipperz.Crypto.ECC.BinaryField.Value = function(aValue, aBase, aBitSize) {
38 if (aValue.constructor == String) {
39 varvalue;
40 varstringLength;
41 var numberOfWords;
42 vari,c;
43
44 if (aBase != 16) {
45 throw Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedBase;
46 }
47
48 value = aValue.replace(/ /g, '');
49 stringLength = value.length;
50 numberOfWords = Math.ceil(stringLength / 8);
51 this._value = new Array(numberOfWords);
52
53 c = numberOfWords;
54 for (i=0; i<c; i++) {
55 varword;
56
57 if (i < (c-1)) {
58 word = parseInt(value.substr(stringLength-((i+1)*8), 8), 16);
59 } else {
60 word = parseInt(value.substr(0, stringLength-(i*8)), 16);
61 }
62
63 this._value[i] = word;
64 }
65 } else if (aValue.constructor == Array) {
66 var itemsToCopy;
67
68 itemsToCopy = aValue.length;
69 while (aValue[itemsToCopy - 1] == 0) {
70 itemsToCopy --;
71 }
72
73 this._value = aValue.slice(0, itemsToCopy);
74 } else if (aValue.constructor == Number) {
75 this._value = [aValue];
76 } else {
77 // throw Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedConstructorValueType;
78 }
79
80 this._bitSize == aBitSize || null;
81
82 return this;
83}
84
85Clipperz.Crypto.ECC.BinaryField.Value.prototype = MochiKit.Base.update(null, {
86
87 'value': function() {
88 return this._value;
89 },
90
91 //-----------------------------------------------------------------------------
92
93 'wordSize': function() {
94 return this._value.length
95 },
96
97 //-----------------------------------------------------------------------------
98
99 'clone': function() {
100 return new Clipperz.Crypto.ECC.BinaryField.Value(this._value.slice(0), null, this._bitSize);
101 },
102
103 //-----------------------------------------------------------------------------
104
105 'isZero': function() {
106 return (this.compare(Clipperz.Crypto.ECC.BinaryField.Value.O) == 0);
107 },
108
109 //-----------------------------------------------------------------------------
110
111 'asString': function(aBase) {
112 varresult;
113 var i,c;
114
115 if (aBase != 16) {
116 throw Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedBase;
117 }
118
119 result = "";
120 c = this.wordSize();
121 for (i=0; i<c; i++) {
122 varwordAsString;
123
124 // wordAsString = ("00000000" + this.value()[i].toString(16));
125 wordAsString = ("00000000" + this._value[i].toString(16));
126 wordAsString = wordAsString.substring(wordAsString.length - 8);
127 result = wordAsString + result;
128 }
129
130 result = result.replace(/^(00)*/, "");
131
132 if (result == "") {
133 result = "0";
134 }
135
136 return result;
137 },
138
139 //-----------------------------------------------------------------------------
140
141 'shiftLeft': function(aNumberOfBitsToShift) {
142 //this method seems like it is never called. :-(
143 return new Clipperz.Crypto.ECC.BinaryField.Value(Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(this._value, aNumberOfBitsToShift));
144 },
145
146 //-----------------------------------------------------------------------------
147
148 'bitSize': function() {
149 if (this._bitSize == null) {
150 this._bitSize = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(this._value);
151 }
152
153 return this._bitSize;
154 },
155
156 //-----------------------------------------------------------------------------
157
158 'isBitSet': function(aBitPosition) {
159 return Clipperz.Crypto.ECC.BinaryField.Value._isBitSet(this._value, aBitPosition);
160 },
161
162 //-----------------------------------------------------------------------------
163
164 'xor': function(aValue) {
165 return new Clipperz.Crypto.ECC.BinaryField.Value(Clipperz.Crypto.ECC.BinaryField.Value._xor(this._value, aValue._value));
166 },
167
168 //-----------------------------------------------------------------------------
169
170 'compare': function(aValue) {
171 return Clipperz.Crypto.ECC.BinaryField.Value._compare(this._value, aValue._value);
172 },
173
174 //-----------------------------------------------------------------------------
175 __syntaxFix__: "syntax fix"
176});
177
178Clipperz.Crypto.ECC.BinaryField.Value.O = new Clipperz.Crypto.ECC.BinaryField.Value('0', 16);
179Clipperz.Crypto.ECC.BinaryField.Value.I = new Clipperz.Crypto.ECC.BinaryField.Value('1', 16);
180
181Clipperz.Crypto.ECC.BinaryField.Value._xor = function(a, b, aFirstItemOffset) {
182 var result;
183 var resultSize;
184 var i,c;
185 var firstItemOffset;
186
187 firstItemOffset = aFirstItemOffset || 0;
188 resultSize = Math.max((a.length - firstItemOffset), b.length) + firstItemOffset;
189
190 result = new Array(resultSize);
191
192 c = firstItemOffset;
193 for (i=0; i<c; i++) {
194 result[i] = a[i];
195 }
196
197 c = resultSize;
198 for (i=firstItemOffset; i<c; i++) {
199 result[i] = (((a[i] || 0) ^ (b[i - firstItemOffset] || 0)) >>> 0);
200 }
201
202 return result;
203};
204
205Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor = function(a, b, aFirstItemOffset) {
206 var i,c;
207 var firstItemOffset;
208
209 firstItemOffset = aFirstItemOffset || 0;
210
211 c = Math.max((a.length - firstItemOffset), b.length) + firstItemOffset;
212 for (i=firstItemOffset; i<c; i++) {
213 a[i] = (((a[i] || 0) ^ (b[i - firstItemOffset] || 0)) >>> 0);
214 }
215};
216
217Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft = function(aWordArray, aNumberOfBitsToShift) {
218 var numberOfWordsToShift;
219 varnumberOfBitsToShift;
220 var result;
221 varoverflowValue;
222 var nextOverflowValue;
223 vari,c;
224
225 numberOfWordsToShift = Math.floor(aNumberOfBitsToShift / 32);
226 numberOfBitsToShift = aNumberOfBitsToShift % 32;
227
228 result = new Array(aWordArray.length + numberOfWordsToShift);
229
230 c = numberOfWordsToShift;
231 for (i=0; i<c; i++) {
232 result[i] = 0;
233 }
234
235 overflowValue = 0;
236 nextOverflowValue = 0;
237
238 c = aWordArray.length;
239 for (i=0; i<c; i++) {
240 varvalue;
241 varresultWord;
242
243 // value = this.value()[i];
244 value = aWordArray[i];
245
246 if (numberOfBitsToShift > 0) {
247 nextOverflowValue = (value >>> (32 - numberOfBitsToShift));
248 value = value & (0xffffffff >>> numberOfBitsToShift);
249 resultWord = (((value << numberOfBitsToShift) | overflowValue) >>> 0);
250 } else {
251 resultWord = value;
252 }
253
254 result[i+numberOfWordsToShift] = resultWord;
255 overflowValue = nextOverflowValue;
256 }
257
258 if (overflowValue != 0) {
259 result[aWordArray.length + numberOfWordsToShift] = overflowValue;
260 }
261
262 return result;
263};
264
265Clipperz.Crypto.ECC.BinaryField.Value._overwriteShiftLeft = function(aWordArray, aNumberOfBitsToShift) {
266 var numberOfWordsToShift;
267 varnumberOfBitsToShift;
268 var result;
269 varoverflowValue;
270 vari,c;
271
272 numberOfWordsToShift = Math.floor(aNumberOfBitsToShift / 32);
273 numberOfBitsToShift = aNumberOfBitsToShift % 32;
274
275 result = new Array(aWordArray.length + numberOfWordsToShift);
276
277 c = numberOfWordsToShift;
278 for (i=0; i<c; i++) {
279 result[i] = 0;
280 }
281
282 overflowValue = 0;
283 nextOverflowValue = 0;
284
285 c = aWordArray.length;
286 for (i=0; i<c; i++) {
287 varvalue;
288 varresultWord;
289
290 // value = this.value()[i];
291 value = aWordArray[i];
292
293 if (numberOfBitsToShift > 0) {
294 var nextOverflowValue;
295
296 nextOverflowValue = (value >>> (32 - numberOfBitsToShift));
297 value = value & (0xffffffff >>> numberOfBitsToShift);
298 resultWord = (((value << numberOfBitsToShift) | overflowValue) >>> 0);
299 } else {
300 resultWord = value;
301 }
302
303 result[i+numberOfWordsToShift] = resultWord;
304 overflowValue = nextOverflowValue;
305 }
306
307 if (overflowValue != 0) {
308 result[aWordArray.length + numberOfWordsToShift] = overflowValue;
309 }
310
311 return result;
312};
313
314Clipperz.Crypto.ECC.BinaryField.Value._bitSize = function(aWordArray) {
315 varresult;
316 varnotNullElements;
317 var mostValuableWord;
318 var matchingBitsInMostImportantWord;
319 var mask;
320 var i,c;
321
322 notNullElements = aWordArray.length;
323
324 if ((aWordArray.length == 1) && (aWordArray[0] == 0)) {
325 result = 0;
326 } else {
327 notNullElements --;
328 while((notNullElements > 0) && (aWordArray[notNullElements] == 0)) {
329 notNullElements --;
330 }
331
332 result = notNullElements * 32;
333 mostValuableWord = aWordArray[notNullElements];
334
335 matchingBits = 32;
336 mask = 0x80000000;
337
338 while ((matchingBits > 0) && ((mostValuableWord & mask) == 0)) {
339 matchingBits --;
340 mask >>>= 1;
341 }
342
343 result += matchingBits;
344 }
345
346 return result;
347};
348
349Clipperz.Crypto.ECC.BinaryField.Value._isBitSet = function(aWordArray, aBitPosition) {
350 var result;
351 varbyteIndex;
352 var bitIndexInSelectedByte;
353
354 byteIndex = Math.floor(aBitPosition / 32);
355 bitIndexInSelectedByte = aBitPosition % 32;
356
357 if (byteIndex <= aWordArray.length) {
358 result = ((aWordArray[byteIndex] & (1 << bitIndexInSelectedByte)) != 0);
359 } else {
360 result = false;
361 }
362
363 return result;
364};
365
366Clipperz.Crypto.ECC.BinaryField.Value._compare = function(a,b) {
367 varresult;
368 var i,c;
369
370 result = MochiKit.Base.compare(a.length, b.length);
371
372 c = a.length;
373 for (i=0; (i<c) && (result==0); i++) {
374//console.log("compare[" + c + " - " + i + " - 1] " + this.value()[c-i-1] + ", " + aValue.value()[c-i-1]);
375 // result = MochiKit.Base.compare(this.value()[c-i-1], aValue.value()[c-i-1]);
376 result = MochiKit.Base.compare(a[c-i-1], b[c-i-1]);
377 }
378
379 return result;
380};
381
382
383Clipperz.Crypto.ECC.BinaryField.Value['exception']= {
384 'UnsupportedBase': new MochiKit.Base.NamedError("Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedBase"),
385 'UnsupportedConstructorValueType':new MochiKit.Base.NamedError("Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedConstructorValueType")
386};
diff --git a/frontend/gamma/js/Clipperz/Crypto/ECC/StandardCurves.js b/frontend/gamma/js/Clipperz/Crypto/ECC/StandardCurves.js
new file mode 100644
index 0000000..ae2b8fb
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/ECC/StandardCurves.js
@@ -0,0 +1,239 @@
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//try { if (typeof(Clipperz.Crypto.ECC.BinaryField.Curve) == 'undefined') { throw ""; }} catch (e) {
30 //throw "Clipperz.Crypto.ECC depends on Clipperz.Crypto.ECC.BinaryField.Curve!";
31//}
32//try { if (typeof(Clipperz.Crypto.ECC.Koblitz.Curve) == 'undefined') { throw ""; }} catch (e) {
33 //throw "Clipperz.Crypto.ECC depends on Clipperz.Crypto.ECC.Koblitz.Curve!";
34//}
35
36Clipperz.Crypto.ECC.StandardCurves = {};
37
38MochiKit.Base.update(Clipperz.Crypto.ECC.StandardCurves, {
39
40 //==============================================================================
41
42 '_K571': null,
43 'K571': function() { //f(z) = z^571 + z^10 + z^5 + z^2 + 1
44 if ((Clipperz.Crypto.ECC.StandardCurves._K571 == null) && (typeof(Clipperz.Crypto.ECC.Koblitz.Curve) != 'undefined')) {
45 Clipperz.Crypto.ECC.StandardCurves._K571 = new Clipperz.Crypto.ECC.Koblitz.Curve({
46 modulus: new Clipperz.Crypto.ECC.Koblitz.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000425', 16),
47 a: new Clipperz.Crypto.ECC.Koblitz.Value('0', 16),
48 b: new Clipperz.Crypto.ECC.Koblitz.Value('1', 16),
49 G: new Clipperz.Crypto.ECC.Koblitz.Point({
50 x: new Clipperz.Crypto.ECC.Koblitz.Value('026eb7a8 59923fbc 82189631 f8103fe4 ac9ca297 0012d5d4 60248048 01841ca4 43709584 93b205e6 47da304d b4ceb08c bbd1ba39 494776fb 988b4717 4dca88c7 e2945283 a01c8972', 16),
51 y: new Clipperz.Crypto.ECC.Koblitz.Value('0349dc80 7f4fbf37 4f4aeade 3bca9531 4dd58cec 9f307a54 ffc61efc 006d8a2c 9d4979c0 ac44aea7 4fbebbb9 f772aedc b620b01a 7ba7af1b 320430c8 591984f6 01cd4c14 3ef1c7a3', 16)
52 }),
53 r: new Clipperz.Crypto.ECC.Koblitz.Value('02000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 131850e1 f19a63e4 b391a8db 917f4138 b630d84b e5d63938 1e91deb4 5cfe778f 637c1001', 16),
54 h: new Clipperz.Crypto.ECC.Koblitz.Value('4', 16),
55 primeFactor: new Clipperz.Crypto.ECC.Koblitz.Value('02000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 131850e1 f19a63e4 b391a8db 917f4138 b630d84b e5d63938 1e91deb4 5cfe778f 637c1001', 16)
56 });
57 }
58
59 return Clipperz.Crypto.ECC.StandardCurves._K571;
60 },
61
62 //-----------------------------------------------------------------------------
63
64 '_K283': null,
65 'K283': function() { //f(z) = z^283 + z^12 + z^7 + z^5 + 1
66 if ((Clipperz.Crypto.ECC.StandardCurves._K283 == null) && (typeof(Clipperz.Crypto.ECC.Koblitz.Curve) != 'undefined')) {
67 Clipperz.Crypto.ECC.StandardCurves._K283 = new Clipperz.Crypto.ECC.Koblitz.Curve({
68 modulus: new Clipperz.Crypto.ECC.Koblitz.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
69 a: new Clipperz.Crypto.ECC.Koblitz.Value('0', 16),
70 b: new Clipperz.Crypto.ECC.Koblitz.Value('1', 16),
71 G: new Clipperz.Crypto.ECC.Koblitz.Point({
72 x: new Clipperz.Crypto.ECC.Koblitz.Value('0503213f 78ca4488 3f1a3b81 62f188e5 53cd265f 23c1567a 16876913 b0c2ac24 58492836', 16),
73 y: new Clipperz.Crypto.ECC.Koblitz.Value('01ccda38 0f1c9e31 8d90f95d 07e5426f e87e45c0 e8184698 e4596236 4e341161 77dd2259', 16)
74 }),
75 r: new Clipperz.Crypto.ECC.Koblitz.Value('01ffffff ffffffff ffffffff ffffffff ffffe9ae 2ed07577 265dff7f 94451e06 1e163c61', 16),
76 h: new Clipperz.Crypto.ECC.Koblitz.Value('4', 16),
77 primeFactor: new Clipperz.Crypto.ECC.Koblitz.Value('01ffffff ffffffff ffffffff ffffffff ffffe9ae 2ed07577 265dff7f 94451e06 1e163c61', 16)
78 });
79 }
80
81 return Clipperz.Crypto.ECC.StandardCurves._K283;
82 },
83
84 //==============================================================================
85
86 '_B571': null,
87 'B571': function() { //f(z) = z^571 + z^10 + z^5 + z^2 + 1
88 if ((Clipperz.Crypto.ECC.StandardCurves._B571 == null) && (typeof(Clipperz.Crypto.ECC.BinaryField.Curve) != 'undefined')) {
89 Clipperz.Crypto.ECC.StandardCurves._B571 = new Clipperz.Crypto.ECC.BinaryField.Curve({
90 modulus: new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000425', 16),
91 a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
92 b: new Clipperz.Crypto.ECC.BinaryField.Value('02f40e7e 2221f295 de297117 b7f3d62f 5c6a97ff cb8ceff1 cd6ba8ce 4a9a18ad 84ffabbd 8efa5933 2be7ad67 56a66e29 4afd185a 78ff12aa 520e4de7 39baca0c 7ffeff7f 2955727a', 16),
93 G: new Clipperz.Crypto.ECC.BinaryField.Point({
94 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),
95 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)
96 }),
97 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),
98 h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
99
100 // S: new Clipperz.Crypto.ECC.BinaryField.Value('2aa058f73a0e33ab486b0f610410c53a7f132310', 10),
101 // n: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16)
102 });
103
104 //-----------------------------------------------------------------------------
105 //
106 //Guide to Elliptic Curve Cryptography
107 //Darrel Hankerson, Alfred Menezes, Scott Vanstone
108 //- Pag: 56, Alorithm 2.45 (with a typo!!!)
109 //
110 //-----------------------------------------------------------------------------
111 //
112 // http://www.milw0rm.com/papers/136
113 //
114 // -------------------------------------------------------------------------
115 // Polynomial Reduction Algorithm Modulo f571
116 // -------------------------------------------------------------------------
117 //
118 // Input: Polynomial p(x) of degree 1140 or less, stored as
119 // an array of 2T machinewords.
120 // Output: p(x) mod f571(x)
121 //
122 // FOR i = T-1, ..., 0 DO
123 // SET X := P[i+T]
124 // P[i] := P[i] ^ (X<<5) ^ (X<<7) ^ (X<<10) ^ (X<<15)
125 // P[i+1] := P[i+1] ^ (X>>17) ^ (X>>22) ^ (X>>25) ^ (X>>27)
126 //
127 // SET X := P[T-1] >> 27
128 // P[0] := P[0] ^ X ^ (X<<2) ^ (X<<5) ^ (X<<10)
129 // P[T-1] := P[T-1] & 0x07ffffff
130 //
131 // RETURN P[T-1],...,P[0]
132 //
133 // -------------------------------------------------------------------------
134 //
135 Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().slowModule = Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module;
136 Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module = function(aValue) {
137 varresult;
138
139 if (aValue.bitSize() > 1140) {
140 MochiKit.Logging.logWarning("ECC.StandarCurves.B571.finiteField().module: falling back to default implementation");
141 result = Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().slowModule(aValue);
142 } else {
143 varC, T;
144 var i;
145
146//console.log(">>> binaryField.finiteField.(improved)module");
147 // C = aValue.value().slice(0);
148 C = aValue._value.slice(0);
149 for (i=35; i>=18; i--) {
150 T = C[i];
151 C[i-18] = (((C[i-18] ^ (T<<5) ^ (T<<7) ^ (T<<10) ^ (T<<15)) & 0xffffffff) >>> 0);
152 C[i-17] = ((C[i-17] ^ (T>>>27) ^ (T>>>25) ^ (T>>>22) ^ (T>>>17)) >>> 0);
153 }
154 T = (C[17] >>> 27);
155 C[0] = ((C[0] ^ T ^ ((T<<2) ^ (T<<5) ^ (T<<10)) & 0xffffffff) >>> 0);
156 C[17] = (C[17] & 0x07ffffff);
157
158 for(i=18; i<=35; i++) {
159 C[i] = 0;
160 }
161
162 result = new Clipperz.Crypto.ECC.BinaryField.Value(C);
163//console.log("<<< binaryField.finiteField.(improved)module");
164 }
165
166 return result;
167 };
168 }
169
170 return Clipperz.Crypto.ECC.StandardCurves._B571;
171 },
172
173 //-----------------------------------------------------------------------------
174
175 '_B283': null,
176 'B283': function() { //f(z) = z^283 + z^12 + z^7 + z^5 + 1
177 if ((Clipperz.Crypto.ECC.StandardCurves._B283 == null) && (typeof(Clipperz.Crypto.ECC.BinaryField.Curve) != 'undefined')) {
178 Clipperz.Crypto.ECC.StandardCurves._B283 = new Clipperz.Crypto.ECC.BinaryField.Curve({
179 modulus: new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
180 a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
181 b: new Clipperz.Crypto.ECC.BinaryField.Value('027b680a c8b8596d a5a4af8a 19a0303f ca97fd76 45309fa2 a581485a f6263e31 3b79a2f5', 16),
182 G: new Clipperz.Crypto.ECC.BinaryField.Point({
183 x: new Clipperz.Crypto.ECC.BinaryField.Value('05f93925 8db7dd90 e1934f8c 70b0dfec 2eed25b8 557eac9c 80e2e198 f8cdbecd 86b12053', 16),
184 y: new Clipperz.Crypto.ECC.BinaryField.Value('03676854 fe24141c b98fe6d4 b20d02b4 516ff702 350eddb0 826779c8 13f0df45 be8112f4', 16)
185 }),
186 r: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffff ffffffff ffffffff ffffffff ffffef90 399660fc 938a9016 5b042a7c efadb307', 16),
187 h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
188 });
189
190 //-----------------------------------------------------------------------------
191 //
192 //Guide to Elliptic Curve Cryptography
193 //Darrel Hankerson, Alfred Menezes, Scott Vanstone
194 //- Pag: 56, Alorithm 2.43
195 //
196 //-----------------------------------------------------------------------------
197 Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().slowModule = Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().module;
198 Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().module = function(aValue) {
199 varresult;
200
201 if (aValue.bitSize() > 564) {
202 MochiKit.Logging.logWarning("ECC.StandarCurves.B283.finiteField().module: falling back to default implementation");
203 result = Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().slowModule(aValue);
204 } else {
205 varC, T;
206 var i;
207
208//console.log(">>> binaryField.finiteField.(improved)module");
209 C = aValue._value.slice(0);
210 for (i=17; i>=9; i--) {
211 T = C[i];
212 C[i-9] = (((C[i-9] ^ (T<<5) ^ (T<<10) ^ (T<<12) ^ (T<<17)) & 0xffffffff) >>> 0);
213 C[i-8] = ((C[i-8] ^ (T>>>27) ^ (T>>>22) ^ (T>>>20) ^ (T>>>15)) >>> 0);
214 }
215 T = (C[8] >>> 27);
216 C[0] = ((C[0] ^ T ^ ((T<<5) ^ (T<<7) ^ (T<<12)) & 0xffffffff) >>> 0);
217 C[8] = (C[8] & 0x07ffffff);
218
219 for(i=9; i<=17; i++) {
220 C[i] = 0;
221 }
222
223 result = new Clipperz.Crypto.ECC.BinaryField.Value(C);
224//console.log("<<< binaryField.finiteField.(improved)module");
225 }
226
227 return result;
228 };
229 }
230
231 return Clipperz.Crypto.ECC.StandardCurves._B283;
232 },
233
234 //==============================================================================
235 __syntaxFix__: "syntax fix"
236});
237
238
239
diff --git a/frontend/gamma/js/Clipperz/Crypto/PRNG.js b/frontend/gamma/js/Clipperz/Crypto/PRNG.js
new file mode 100644
index 0000000..266b909
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/PRNG.js
@@ -0,0 +1,855 @@
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) {
495//MochiKit.Logging.logDebug("### PRNG.readyToGenerateRandomBytes");
496Clipperz.log("### PRNG.readyToGenerateRandomBytes");
497 MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes');
498 }
499 MochiKit.Signal.signal(this, 'reseeded');
500 },
501
502 //-------------------------------------------------------------------------
503
504 'isReadyToGenerateRandomValues': function() {
505 return this.reseedCounter() != 0;
506 },
507
508 //-------------------------------------------------------------------------
509
510 'entropyLevel': function() {
511 return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel());
512 },
513
514 //-------------------------------------------------------------------------
515
516 'counter': function() {
517 return this._counter;
518 },
519
520 'incrementCounter': function() {
521 this._counter += 1;
522 },
523
524 'counterBlock': function() {
525 var result;
526
527 result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0);
528
529 return result;
530 },
531
532 //-------------------------------------------------------------------------
533
534 'getRandomBlock': function() {
535 var result;
536
537 result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues()));
538 this.incrementCounter();
539
540 return result;
541 },
542
543 //-------------------------------------------------------------------------
544
545 'getRandomBytes': function(aSize) {
546 var result;
547
548 if (this.isReadyToGenerateRandomValues()) {
549 var i,c;
550 var newKey;
551
552 result = new Clipperz.ByteArray();
553
554 c = Math.ceil(aSize / (128 / 8));
555 for (i=0; i<c; i++) {
556 result.appendBlock(this.getRandomBlock());
557 }
558
559 if (result.length() != aSize) {
560 result = result.split(0, aSize);
561 }
562
563 newKey = this.getRandomBlock().appendBlock(this.getRandomBlock());
564 this.setKey(newKey);
565 } else {
566MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
567 throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy;
568 }
569
570 return result;
571 },
572
573 //-------------------------------------------------------------------------
574
575 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) {
576 varselectedAccumulator;
577
578 selectedAccumulator = this.accumulators()[aPoolId];
579 selectedAccumulator.addRandomByte(aRandomValue);
580
581 if (aPoolId == 0) {
582 MochiKit.Signal.signal(this, 'addedRandomByte')
583 if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) {
584 this.reseed();
585 }
586 }
587 },
588
589 //-------------------------------------------------------------------------
590
591 'numberOfEntropyAccumulators': function() {
592 return this._numberOfEntropyAccumulators;
593 },
594
595 //-------------------------------------------------------------------------
596
597 'randomnessSources': function() {
598 return this._randomnessSources;
599 },
600
601 'addRandomnessSource': function(aRandomnessSource) {
602 aRandomnessSource.setGenerator(this);
603 aRandomnessSource.setSourceId(this.randomnessSources().length);
604 this.randomnessSources().push(aRandomnessSource);
605
606 if (this.isReadyToGenerateRandomValues() == false) {
607 aRandomnessSource.setBoostMode(true);
608 }
609 },
610
611 //-------------------------------------------------------------------------
612
613 'deferredEntropyCollection': function(aValue) {
614 var result;
615
616//MochiKit.Logging.logDebug(">>> PRNG.deferredEntropyCollection");
617
618 if (this.isReadyToGenerateRandomValues()) {
619//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 1");
620 result = aValue;
621 } else {
622//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 2");
623 var deferredResult;
624
625 // Clipperz.NotificationCenter.notify(this, 'updatedProgressState', 'collectingEntropy', true);
626
627 deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection");
628 // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.1 - PRNG.deferredEntropyCollection - 1: " + res); return res;});
629 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue));
630 // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.2 - PRNG.deferredEntropyCollection - 2: " + res); return res;});
631 MochiKit.Signal.connect(this,
632 'readyToGenerateRandomBytes',
633 deferredResult,
634 'callback');
635
636 result = deferredResult;
637 }
638//MochiKit.Logging.logDebug("<<< PRNG.deferredEntropyCollection - result: " + result);
639
640 return result;
641 },
642
643 //-------------------------------------------------------------------------
644
645 'fastEntropyAccumulationForTestingPurpose': function() {
646 while (! this.isReadyToGenerateRandomValues()) {
647 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256));
648 }
649 },
650
651 //-------------------------------------------------------------------------
652
653 'dump': function(appendToDoc) {
654 var tbl;
655 var i,c;
656
657 tbl = document.createElement("table");
658 tbl.border = 0;
659 with (tbl.style) {
660 border = "1px solid lightgrey";
661 fontFamily = 'Helvetica, Arial, sans-serif';
662 fontSize = '8pt';
663 //borderCollapse = "collapse";
664 }
665 var hdr = tbl.createTHead();
666 var hdrtr = hdr.insertRow(0);
667 // document.createElement("tr");
668 {
669 var ntd;
670
671 ntd = hdrtr.insertCell(0);
672 ntd.style.borderBottom = "1px solid lightgrey";
673 ntd.style.borderRight = "1px solid lightgrey";
674 ntd.appendChild(document.createTextNode("#"));
675
676 ntd = hdrtr.insertCell(1);
677 ntd.style.borderBottom = "1px solid lightgrey";
678 ntd.style.borderRight = "1px solid lightgrey";
679 ntd.appendChild(document.createTextNode("s"));
680
681 ntd = hdrtr.insertCell(2);
682 ntd.colSpan = this.firstPoolReseedLevel();
683 ntd.style.borderBottom = "1px solid lightgrey";
684 ntd.style.borderRight = "1px solid lightgrey";
685 ntd.appendChild(document.createTextNode("base values"));
686
687 ntd = hdrtr.insertCell(3);
688 ntd.colSpan = 20;
689 ntd.style.borderBottom = "1px solid lightgrey";
690 ntd.appendChild(document.createTextNode("extra values"));
691
692 }
693
694 c = this.accumulators().length;
695 for (i=0; i<c ; i++) {
696 varcurrentAccumulator;
697 var bdytr;
698 var bdytd;
699 var ii, cc;
700
701 currentAccumulator = this.accumulators()[i]
702
703 bdytr = tbl.insertRow(true);
704
705 bdytd = bdytr.insertCell(0);
706 bdytd.style.borderRight = "1px solid lightgrey";
707 bdytd.style.color = "lightgrey";
708 bdytd.appendChild(document.createTextNode("" + i));
709
710 bdytd = bdytr.insertCell(1);
711 bdytd.style.borderRight = "1px solid lightgrey";
712 bdytd.style.color = "gray";
713 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length()));
714
715
716 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel());
717 for (ii=0; ii<cc; ii++) {
718 var cellText;
719
720 bdytd = bdytr.insertCell(ii + 2);
721
722 if (ii < currentAccumulator.stack().length()) {
723 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii));
724 } else {
725 cellText = "_";
726 }
727
728 if (ii == (this.firstPoolReseedLevel() - 1)) {
729 bdytd.style.borderRight = "1px solid lightgrey";
730 }
731
732 bdytd.appendChild(document.createTextNode(cellText));
733 }
734
735 }
736
737
738 if (appendToDoc) {
739 var ne = document.createElement("div");
740 ne.id = "entropyGeneratorStatus";
741 with (ne.style) {
742 fontFamily = "Courier New, monospace";
743 fontSize = "12px";
744 lineHeight = "16px";
745 borderTop = "1px solid black";
746 padding = "10px";
747 }
748 if (document.getElementById(ne.id)) {
749 MochiKit.DOM.swapDOM(ne.id, ne);
750 } else {
751 document.body.appendChild(ne);
752 }
753 ne.appendChild(tbl);
754 }
755
756 return tbl;
757 },
758
759 //-----------------------------------------------------------------------------
760 __syntaxFix__: "syntax fix"
761});
762
763//#############################################################################
764
765Clipperz.Crypto.PRNG.Random = function(args) {
766 args = args || {};
767 //MochiKit.Base.bindMethods(this);
768
769 return this;
770}
771
772Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
773
774 'toString': function() {
775 return "Clipperz.Crypto.PRNG.Random";
776 },
777
778 //-------------------------------------------------------------------------
779
780 'getRandomBytes': function(aSize) {
781//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes");
782 varresult;
783 var i,c;
784
785 result = new Clipperz.ByteArray()
786 c = aSize || 1;
787 for (i=0; i<c; i++) {
788 result.appendByte((Math.random()*255) & 0xff);
789 }
790
791//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes");
792 return result;
793 },
794
795 //-------------------------------------------------------------------------
796 __syntaxFix__: "syntax fix"
797});
798
799//#############################################################################
800
801_clipperz_crypt_prng_defaultPRNG = null;
802
803Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
804 if (_clipperz_crypt_prng_defaultPRNG == null) {
805 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna();
806
807 //.............................................................
808 //
809 // TimeRandomnessSource
810 //
811 //.............................................................
812 {
813 var newRandomnessSource;
814
815 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111});
816 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
817 }
818
819 //.............................................................
820 //
821 // MouseRandomnessSource
822 //
823 //.............................................................
824 {
825 varnewRandomnessSource;
826
827 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource();
828 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
829 }
830
831 //.............................................................
832 //
833 // KeyboardRandomnessSource
834 //
835 //.............................................................
836 {
837 varnewRandomnessSource;
838
839 newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource();
840 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
841 }
842
843 }
844
845 return _clipperz_crypt_prng_defaultPRNG;
846};
847
848//#############################################################################
849
850Clipperz.Crypto.PRNG.exception = {
851 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy")
852};
853
854
855MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator);
diff --git a/frontend/gamma/js/Clipperz/Crypto/RSA.js b/frontend/gamma/js/Clipperz/Crypto/RSA.js
new file mode 100644
index 0000000..4dad8f7
--- a/dev/null
+++ b/frontend/gamma/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/gamma/js/Clipperz/Crypto/SHA.js b/frontend/gamma/js/Clipperz/Crypto/SHA.js
new file mode 100644
index 0000000..3cf8559
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/SHA.js
@@ -0,0 +1,301 @@
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 if (_c < 0) {
142 _c = _c + (512 / charBits);
143 }
144
145 for (_i=0; _i<_c; _i++) {
146 message.push(0x00); //append "0" bits until message length ≡ 448 ≡ -64 (mod 512)
147 }
148
149 messageLengthInBits = messageLength * charBits;
150 message.push(0x00); //the 4 most high byte are alway 0 as message length is represented with a 32bit value;
151 message.push(0x00);
152 message.push(0x00);
153 message.push(0x00);
154 message.push((messageLengthInBits >> 24)& 0xff);
155 message.push((messageLengthInBits >> 16)& 0xff);
156 message.push((messageLengthInBits >> 8) & 0xff);
157 message.push( messageLengthInBits & 0xff);
158
159 currentMessageIndex = 0;
160 while(currentMessageIndex < message.length) {
161 varw;
162 vara, b, c, d, e, f, g, h;
163
164 w = Array(64);
165
166 _c = 16;
167 for (_i=0; _i<_c; _i++) {
168 var _j;
169
170 _j = currentMessageIndex + _i*4;
171 w[_i] = (message[_j] << 24) | (message[_j + 1] << 16) | (message[_j + 2] << 8) | (message[_j + 3] << 0);
172 }
173
174 _c = 64;
175 for (_i=16; _i<_c; _i++) {
176 vars0, s1;
177
178 s0 = (rotateRight(w[_i-15], 7)) ^ (rotateRight(w[_i-15], 18)) ^ (shiftRight(w[_i-15], 3));
179 s1 = (rotateRight(w[_i-2], 17)) ^ (rotateRight(w[_i-2], 19)) ^ (shiftRight(w[_i-2], 10));
180 w[_i] = safeAdd(w[_i-16], s0, w[_i-7], s1);
181 }
182
183 a=h0; b=h1; c=h2; d=h3; e=h4; f=h5; g=h6; h=h7;
184
185 _c = 64;
186 for (_i=0; _i<_c; _i++) {
187 var s0, s1, ch, maj, t1, t2;
188
189 s0 = (rotateRight(a, 2)) ^ (rotateRight(a, 13)) ^ (rotateRight(a, 22));
190 maj = (a & b) ^ (a & c) ^ (b & c);
191 t2 = safeAdd(s0, maj);
192 s1 = (rotateRight(e, 6)) ^ (rotateRight(e, 11)) ^ (rotateRight(e, 25));
193 ch = (e & f) ^ ((~e) & g);
194 t1 = safeAdd(h, s1, ch, k[_i], w[_i]);
195
196 h = g;
197 g = f;
198 f = e;
199 e = safeAdd(d, t1);
200 d = c;
201 c = b;
202 b = a;
203 a = safeAdd(t1, t2);
204 }
205
206 h0 = safeAdd(h0, a);
207 h1 = safeAdd(h1, b);
208 h2 = safeAdd(h2, c);
209 h3 = safeAdd(h3, d);
210 h4 = safeAdd(h4, e);
211 h5 = safeAdd(h5, f);
212 h6 = safeAdd(h6, g);
213 h7 = safeAdd(h7, h);
214
215 currentMessageIndex += bytesPerBlock;
216 }
217
218 result = new Array(256/8);
219 result[0] = (h0 >> 24)& 0xff;
220 result[1] = (h0 >> 16)& 0xff;
221 result[2] = (h0 >> 8)& 0xff;
222 result[3] = h0 & 0xff;
223
224 result[4] = (h1 >> 24)& 0xff;
225 result[5] = (h1 >> 16)& 0xff;
226 result[6] = (h1 >> 8)& 0xff;
227 result[7] = h1 & 0xff;
228
229 result[8] = (h2 >> 24)& 0xff;
230 result[9] = (h2 >> 16)& 0xff;
231 result[10] = (h2 >> 8)& 0xff;
232 result[11] = h2 & 0xff;
233
234 result[12] = (h3 >> 24)& 0xff;
235 result[13] = (h3 >> 16)& 0xff;
236 result[14] = (h3 >> 8)& 0xff;
237 result[15] = h3 & 0xff;
238
239 result[16] = (h4 >> 24)& 0xff;
240 result[17] = (h4 >> 16)& 0xff;
241 result[18] = (h4 >> 8)& 0xff;
242 result[19] = h4 & 0xff;
243
244 result[20] = (h5 >> 24)& 0xff;
245 result[21] = (h5 >> 16)& 0xff;
246 result[22] = (h5 >> 8)& 0xff;
247 result[23] = h5 & 0xff;
248
249 result[24] = (h6 >> 24)& 0xff;
250 result[25] = (h6 >> 16)& 0xff;
251 result[26] = (h6 >> 8)& 0xff;
252 result[27] = h6 & 0xff;
253
254 result[28] = (h7 >> 24)& 0xff;
255 result[29] = (h7 >> 16)& 0xff;
256 result[30] = (h7 >> 8)& 0xff;
257 result[31] = h7 & 0xff;
258
259//Clipperz.Profile.stop("Clipperz.Crypto.SHA.sha256_array");
260 return result;
261 },
262
263 //-----------------------------------------------------------------------------
264
265 'sha256': function(aValue) {
266//Clipperz.Profile.start("Clipperz.Crypto.SHA.sha256");
267 var result;
268 var resultArray;
269 varvalueArray;
270
271 valueArray = aValue.arrayValues();
272 resultArray = Clipperz.Crypto.SHA.sha256_array(valueArray);
273
274 result = new Clipperz.ByteArray(resultArray);
275
276//Clipperz.Profile.stop("Clipperz.Crypto.SHA.sha256");
277 return result;
278 },
279
280 //-----------------------------------------------------------------------------
281
282 'sha_d256': function(aValue) {
283//Clipperz.Profile.start("Clipperz.Crypto.SHA.sha_d256");
284 var result;
285 var resultArray;
286 varvalueArray;
287
288 valueArray = aValue.arrayValues();
289 resultArray = Clipperz.Crypto.SHA.sha256_array(valueArray);
290 resultArray = Clipperz.Crypto.SHA.sha256_array(resultArray);
291
292 result = new Clipperz.ByteArray(resultArray);
293
294//Clipperz.Profile.stop("Clipperz.Crypto.SHA.sha256");
295 return result;
296 },
297
298 //-----------------------------------------------------------------------------
299 __syntaxFix__: "syntax fix"
300
301});
diff --git a/frontend/gamma/js/Clipperz/Crypto/SRP.js b/frontend/gamma/js/Clipperz/Crypto/SRP.js
new file mode 100644
index 0000000..0eef6ec
--- a/dev/null
+++ b/frontend/gamma/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//#############################################################################